The pattern of "load address to register" followed by "load value from
address in register" generally results in three instructions: two to
load the address and one to load the value.
This can be reduced to two instructions by allowing the assembler to
incorporate the low bits of the address within the load (or store)
instruction itself. In the case of a store, this requires specifying
a second register that can be temporarily used to hold the high bits
of the address. (In the case of a load, the destination register is
reused for this purpose.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
la a2, _edata
/* Calculate relocation addend */
- la t0, prefix_virt
- LOADN a0, (t0)
+ LOADN a0, prefix_virt
sub a0, a1, a0
/* Skip applying relocations if addend is zero */
li a1, SATP_MODE_SV57
/* Calculate virtual address offset */
- la t0, prefix_virt
- LOADN t0, (t0)
+ LOADN t0, prefix_virt
la t1, _prefix
sub a0, t1, t0
STOREN t0, -PTE_SIZE(a4)
/* Calculate PTE[x] address for iPXE virtual address map */
- la t0, prefix_virt
- LOADN t0, (t0)
+ LOADN t0, prefix_virt
srli t0, t0, VPN1_LSB
andi t0, t0, ( PTE_COUNT - 1 )
slli t0, t0, PTE_SIZE_LOG2
mv a2, a0
/* Calculate virtual address offset */
- la t0, prefix_virt
- LOADN t0, (t0)
+ LOADN t0, prefix_virt
la t1, _prefix
sub a0, t1, t0
progress " .stack"
/* Store boot hart */
- la t0, boot_hart
- STOREN s0, (t0)
+ STOREN s0, boot_hart, t0
/* Register device tree */
la a0, sysfdt