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);