Next: , Previous: Delay slots, Up: Standard macros


3.4.4 Supporting arbitrarily sized immediate values

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.