* The instruction set:: The RISC instruction set used in GNU lightning
* GNU lightning examples:: GNU lightning's examples
* Reentrancy:: Re-entrant usage of GNU lightning
+* Registers:: Accessing the whole register file
* Customizations:: Advanced code generation customizations
* Acknowledgements:: Acknowledgements for GNU lightning
@end menu
dynamic code generation.
@end iftex
-Dynamic code generation is the generation of machine code
-at runtime. It is typically used to strip a layer of interpretation
+Dynamic code generation is the generation of machine code
+at runtime. It is typically used to strip a layer of interpretation
by allowing compilation to occur at runtime. One of the most
well-known applications of dynamic code generation is perhaps that
of interpreters that compile source code to an intermediate bytecode
representations with the speed of machine code. Another common
application of dynamic code generation is in the field of hardware
simulators and binary emulators, which can use the same techniques
-to translate simulated instructions to the instructions of the
+to translate simulated instructions to the instructions of the
underlying machine.
Yet other applications come to mind: for example, windowing
generator is a tedious and error-prone task more than a difficult one.
@lightning{} provides a portable, fast and easily retargetable dynamic
-code generation system.
+code generation system.
To be portable, @lightning{} abstracts over current architectures'
quirks and unorthogonalities. The interface that it exposes to is that
ret @rem{! Return to caller}
@end example
+@item Register liveness
+
+During code generation, @lightning{} occasionally needs scratch registers
+or needs to use architecture-defined registers. For that, @lightning{}
+internally maintains register liveness information.
+
+In the following example, @code{qdivr} will need special registers like
+@code{R0} on some architectures. As @lightning{} understands that
+@code{R0} is used in the subsequent instruction, it will create
+save/restore code for @code{R0} in case.
+
+@example
+...
+qdivr V0, V1, V2, V3
+movr V3, R0
+...
+@end example
+
+The same is not true in the example that follows. Here, @code{R0} is
+not alive after the division operation because @code{R0} is neither an
+argument register nor a callee-save register. Thus, no save/restore
+code for @code{R0} will be created in case.
+
+@example
+...
+qdivr V0, V1, V2, V3
+jmpr R1
+...
+@end example
+
+The @code{live} instruction can be used to mark a register as live after
+it as in the following example. Here, @code{R0} will be preserved
+across the division.
+
+@example
+...
+qdivr V0, V1, V2, V3
+live R0
+jmpr R1
+...
+@end example
+
+The @code{live} instruction is useful at code entry and exit points,
+like after and before a @code{callr} instruction.
+
@item Trampolines, continuations and tail call optimization
Frequently it is required to generate jit code that must jump to
mov %i0, %g2 retl
inc %g2 inc %o0
mov %g2, %i0
- restore
- retl
- nop
+ restore
+ retl
+ nop
@end example
In this case, @lightning{} introduces overhead to create a register
window (not knowing that the procedure is a leaf procedure) and to
argument to every call, as multiple jit states generating code in
paralell should be very uncommon.
-@section Registers
+@node Registers
@chapter Accessing the whole register file
As mentioned earlier in this chapter, all @lightning{} back-ends are
@code{JIT_R(0)} denote the same register, and likewise for
integer callee-saved, or floating-point, registers.
+@section Scratch registers
+
+For operations, @lightning{} does not support directly, like storing
+a literal in memory, @code{jit_get_reg} and @code{jit_unget_reg} can be used to
+acquire and release a scratch register as in the following pattern:
+
+@example
+ 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);
+@end example
+
+As @code{jit_get_reg} and @code{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.
+
+@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);
+@end example
+
@node Customizations
@chapter Customizations