Next: Implementing the ABI, Previous: Delay slots, Up: Standard macros
This is a problem that is endemic to RISC machines. The basic idea is to reserve one or two register to represent large immediate values. Let's see an example from the SPARC:
addi_i R0, V2, 45 | addi_i R0, V2, 10000 ---------------------------+--------------------------- add %l5, 45, %l0 | set 10000, %l6 | add %l5, %l6, %l0
In this case, %l6
is reserved to be used for large immediates.
An elegant solution is to use an internal macro which automatically
decides which version is to be compiled.
Beware of register conflicts on machines with delay slots. This is
the case for the SPARC, where %l7
is used instead for large
immediates in compare-and-branch instructions. So the sequence
jit_delay( jit_addi_i(JIT_R0, JIT_V2, 10000), jit_blei_i(label, JIT_R1, 20000) );
is assembled this way:
set 10000, %l6 ! prepare immediate for add set 20000, %l7 ! prepare immediate for cmp cmp %l1, %l7 ble label add %l5, %l6, %l0 ! delay slot
Note that using %l6
in the branch instruction would have given
an incorrect result—R0
would have been filled with the value of
V2+
20000 rather than V2+
10000.