As mentioned earlier in this chapter, all GNU lightning back-ends are guaranteed to have at least six general-purpose integer registers and six floating-point registers, but many back-ends will have more.
To access the entire register files, you can use the
JIT_R, JIT_V and JIT_F macros. They
accept a parameter that identifies the register number, which
must be strictly less than JIT_R_NUM, JIT_V_NUM
and JIT_F_NUM respectively; the number need not be
constant. Of course, expressions like JIT_R0 and
JIT_R(0) denote the same register, and likewise for
integer callee-saved, or floating-point, registers.
For operations, GNU lightning does not support directly, like storing
a literal in memory, jit_get_reg and jit_unget_reg can be used to
acquire and release a scratch register as in the following pattern:
jit_int32_t reg = jit_get_reg (jit_class_gpr);
jit_movi (reg, immediate);
jit_stxi (offsetof (some_struct, some_field), JIT_V0, reg);
jit_unget_reg (reg);
As jit_get_reg and jit_unget_reg may generate spills and
reloads but don’t follow branches, the code between both must be in
the same basic block and must not contain any branches as in the
following (bad) example.
jit_int32_t reg = jit_get_reg (jit_class_gpr);
jit_ldxi (reg, JIT_V0, offset);
jump = jit_bnei (reg, V0);
jit_movr (JIT_V1, reg);
jit_patch (jump);
jit_unget_reg (reg);