[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4.2 Common features supported by `core-common.h'

The `core-common.h' file contains hundreds of macro definitions which will spare you defining a lot of things in the files the are specific to your port. Here is a list of the features that `core-common.h' provides.

Support for common synthetic instructions
These are instructions that can be represented as a simple operation, for example a bit-wise AND or a subtraction. `core-common.h' recognizes when the port-specific header file defines these macros and avoids compiler warnings about redefined macros, but there should be no need to define them. They are:
#define jit_extr_c_ui(d, rs)
#define jit_extr_s_ui(d, rs)
#define jit_extr_c_ul(d, rs)
#define jit_extr_s_ul(d, rs)
#define jit_extr_i_ul(d, rs)
#define jit_negr_i(d, rs)
#define jit_negr_l(d, rs)

Support for the ABI
All of jit_prolog, jit_leaf and jit_finish are not mandatory. If not defined, they will be defined respectively as an empty macro, as a synonym for jit_prolog, and as a synonym for jit_calli. Whether to define them or not in the port-specific header file, it depends on the underlying architecture's ABI---in general, however, you'll need to define at least jit_prolog.

Support for uncommon instructions
These are instructions that many widespread architectures lack. `core-common.h' is able to provide default definitions, but they are usually inefficient if the hardware provides a way to do these operations with a single instruction. They are extension with sign and "reverse subtraction" (that is, REG2IMMREG1):
#define jit_extr_c_i(d, rs)
#define jit_extr_s_i(d, rs)
#define jit_extr_c_l(d, rs)
#define jit_extr_s_l(d, rs)
#define jit_extr_i_l(d, rs)
#define jit_rsbi_i(d, rs, is)
#define jit_rsbi_l(d, rs, is)
#define jit_rsbi_p(d, rs, is)

Conversion between network and host byte ordering
These macros are no-ops on big endian systems. Don't define them on such systems; on the other hand, they are mandatory on little endian systems. They are:
#define jit_ntoh_ui(d, rs)
#define jit_ntoh_us(d, rs)

Support for a "zero" register
Many RISC architectures provide a read-only register whose value is hard-coded to be zero; this register is then used implicitly when referring to a memory location using a single register. For example, on the SPARC, an operand like [%l6] is actually assembled as [%l6+%g0]. If this is the case, you should define JIT_RZERO to be the number of this register; `core-common.h' will use it to implement all variations of the ld and st instructions. For example:
#define jit_ldi_c(d, is)         jit_ldxi_c(d, JIT_RZERO, is)
#define jit_ldr_i(d, rs)         jit_ldxr_c(d, JIT_RZERO, rs)

If available, JIT_RZERO is also used to provide more efficient definitions of the neg instruction (see "Support for common synthetic instructions", above).

`core-common.h' provides a lot of trivial definitions which make the instruction set as orthogonal as possible. For example, adding two unsigned integers is exactly the same as adding two signed integers (assuming a two's complement representation of negative numbers); yet, GNU lightning provides both jit_addr_i and jit_addr_ui macros. Similarly, pointers and unsigned long integers behave in the same way, but GNU lightning has separate instruction for the two data types--those that operate on pointers usually include a typecast that makes programs clearer.

These define "synthetic" instructions whose definition is not as trivial as in the case of synonyms, but is anyway standard. This is the case for bitwise NOT (which is implemented by XORing a string of ones), "reverse subtraction" between registers (which is converted to a normal subtraction with the two source operands inverted), and subtraction of an immediate from a register (which is converted to an addition). Unlike neg and ext (see "Support for common synthetic instructions", above), which are simply non-mandatory, you must not define these functions.

Support for longs
On most systems, longs and unsigned longs are the same as, respectively, ints and unsigned ints. In this case, `core-common.h' defines operations on these types to be synonyms.

Last but not least, `core-common.h' defines the jit_state type. Part of this struct is machine-dependent and includes all kinds of state needed by the back-end; this part is always accessible in a re-entrant way as _jitl. _jitl will be of type struct jit_local_state; this struct must be defined even if no state is required.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Alistair Turnbull on April, 12 2005 using texi2html