Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-rules-interp.c  view on Meta::CPAN


@table @code
@item name
The name of the register.  This is used for debugging purposes.

@item cpu_reg
The raw CPU register number.  Registers in @code{libjit} are
referred to by their pseudo register numbers, corresponding to
their index within @code{JIT_REG_INFO}.  However, these pseudo
register numbers may not necessarily correspond to the register
numbers used by the actual CPU.  This field provides a mapping.

@item other_reg
The second pseudo register in a 64-bit register pair, or -1 if
the current register cannot be used as the first pseudo register
in a 64-bit register pair.  This field only has meaning on 32-bit
platforms, and should always be set to -1 on 64-bit platforms.

@item flags
Flag bits that describe the pseudo register's properties.
@end table

@noindent
The following flags may be present:

@table @code
@item JIT_REG_WORD
This register can hold an integer word value.

@item JIT_REG_LONG
This register can hold a 64-bit long value without needing a
second register.  Normally only used on 64-bit platforms.

@item JIT_REG_FLOAT32
This register can hold a 32-bit floating-point value.

@item JIT_REG_FLOAT64
This register can hold a 64-bit floating-point value.

@item JIT_REG_NFLOAT
This register can hold a native floating-point value.

@item JIT_REG_FRAME
This register holds the frame pointer.  You will almost always supply
@code{JIT_REG_FIXED} for this register.

@item JIT_REG_STACK_PTR
This register holds the stack pointer.  You will almost always supply
@code{JIT_REG_FIXED} for this register.

@item JIT_REG_FIXED
This register has a fixed meaning and cannot be used for general allocation.

@item JIT_REG_CALL_USED
This register will be destroyed by a function call.

@item JIT_REG_IN_STACK
This register is in a stack-like arrangement.

@item JIT_REG_GLOBAL
This register is a candidate for global register allocation.
@end table

A CPU may have some registers arranged into a stack.  In this case
operations can typically only occur at the top of the stack, and
may automatically pop values as a side-effect of the operation.
An example of such architecture is x87 floating point unit.  Such
CPU requires three additional macros.

@table @code

@item JIT_REG_STACK
If defined, this indicates the presence of the register stack.

@item JIT_REG_STACK_START
The index of the first register in the @code{JIT_REG_INFO} array that is used
in a stack-like arrangement.

@item JIT_REG_STACK_END
The index of the last register in the @code{JIT_REG_INFO} array that is used
in a stack-like arrangement.

@end table

The entries in the @code{JIT_REG_INFO} array from @code{JIT_REG_STACK_START}
up to @code{JIT_REG_STACK_END} must also have the @code{JIT_REG_IN_STACK}
flag set.

@subsection Other architecture macros

@noindent
The rule file may also have definitions of the following macros:

@table @code
@item JIT_NUM_GLOBAL_REGS
The number of registers that are used for global register allocation.
Set to zero if global register allocation should not be used.

@item JIT_ALWAYS_REG_REG
Define this to 1 if arithmetic operations must always be performed
on registers.  Define this to 0 if register/memory and memory/register
operations are possible.

@item JIT_PROLOG_SIZE
If defined, this indicates the maximum size of the function prolog.

@item JIT_FUNCTION_ALIGNMENT
This value indicates the alignment required for the start of a function.
e.g. define this to 32 if functions should be aligned on a 32-byte
boundary.

@item JIT_ALIGN_OVERRIDES
Define this to 1 if the platform allows reads and writes on
any byte boundary.  Define to 0 if only properly-aligned
memory accesses are allowed.  Normally only defined to 1 under x86.

@item jit_extra_gen_state
@itemx jit_extra_gen_init
@itemx jit_extra_gen_cleanup
The @code{jit_extra_gen_state} macro can be supplied to add extra fields
to the @code{struct jit_gencode} type in @code{jit-rules.h}, for
extra CPU-specific code generation state information.

The @code{jit_extra_gen_init} macro initializes this extra information,
and the @code{jit_extra_gen_cleanup} macro cleans it up when code
generation is complete.
@end table

@subsection Architecture-dependent functions

@*/

/*
 * Output a native word to the current method.
 */
#define jit_cache_native(gen,value)					\
	do {								\
		_jit_gen_check_space((gen), sizeof(jit_nuint));		\
		*((jit_nuint *)((gen)->ptr)) = (jit_nuint)(value); 	\
		(gen)->ptr += sizeof(jit_nuint);			\
	} while (0)

/*
 * Write an interpreter opcode to the cache.
 */
#define	jit_cache_opcode(gen,opcode)	\
			jit_cache_native((gen), (jit_nint)(opcode))

/*
 * Write "n" bytes to the cache, rounded up to a multiple of "void *".
 */
#define	jit_cache_add_n(gen,buf,size)					\
		do {							\
			unsigned int __size = 				\
				((size) + sizeof(void *) - 1) & ~(sizeof(void *) - 1); \
			_jit_gen_check_space((gen), __size);		\
			jit_memcpy((gen)->ptr, (buf), (size));		\

libjit/jit/jit-rules-interp.c  view on Meta::CPAN

 * calls to the new version after recompilation.
 * @end deftypefun
@*/
void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
{
	/* The interpreter doesn't need redirectors */
	return 0;
}

/*@
 * @deftypefun void _jit_gen_spill_reg (jit_gencode_t @var{gen}, int @var{reg}, int @var{other_reg}, jit_value_t @var{value})
 * Generate instructions to spill a pseudo register to the local
 * variable frame.  If @var{other_reg} is not -1, then it indicates
 * the second register in a 64-bit register pair.
 *
 * This function will typically call @code{_jit_gen_fix_value} to
 * fix the value's frame position, and will then generate the
 * appropriate spill instructions.
 * @end deftypefun
@*/
void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
						int other_reg, jit_value_t value)
{
	/* Registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_free_reg (jit_gencode_t @var{gen}, int @var{reg}, int @var{other_reg}, int @var{value_used})
 * Generate instructions to free a register without spilling its value.
 * This is called when a register's contents become invalid, or its
 * value is no longer required.  If @var{value_used} is set to a non-zero
 * value, then it indicates that the register's value was just used.
 * Otherwise, there is a value in the register but it was never used.
 *
 * On most platforms, this function won't need to do anything to free
 * the register.  But some do need to take explicit action.  For example,
 * x86 needs an explicit instruction to remove a floating-point value
 * from the FPU's stack if its value has not been used yet.
 * @end deftypefun
@*/
void _jit_gen_free_reg(jit_gencode_t gen, int reg,
					   int other_reg, int value_used)
{
	/* Registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_load_value (jit_gencode_t @var{gen}, int @var{reg}, int @var{other_reg}, jit_value_t @var{value})
 * Generate instructions to load a value into a register.  The value will
 * either be a constant or a slot in the frame.  You should fix frame slots
 * with @code{_jit_gen_fix_value}.
 * @end deftypefun
@*/
void _jit_gen_load_value
	(jit_gencode_t gen, int reg, int other_reg, jit_value_t value)
{
	/* Registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_spill_global (jit_gencode_t @var{gen}, int @var{reg}, jit_value_t @var{value})
 * Spill the contents of @var{value} from its corresponding global register.
 * This is used in rare cases when a machine instruction requires its operand
 * to be in the specific register that happens to be global. In such cases the
 * register is spilled just before the instruction and loaded back immediately
 * after it.
 * @end deftypefun
@*/
void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value)
{
	/* Global registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_load_global (jit_gencode_t @var{gen}, int @var{reg}, jit_value_t @var{value})
 * Load the contents of @var{value} into its corresponding global register.
 * This is used at the head of a function to pull parameters out of stack
 * slots into their global register copies.
 * @end deftypefun
@*/
void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value)
{
	/* Global registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_exch_top (jit_gencode_t @var{gen}, int @var{reg})
 * Generate instructions to exchange the contents of the top stack register
 * with a stack register specified by the @var{reg} argument.
 *
 * It needs to be implemented only by backends that support stack registers.
 * @end deftypefun
@*/
void _jit_gen_exch_top(jit_gencode_t gen, int reg)
{
	/* Stack registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_move_top (jit_gencode_t @var{gen}, int @var{reg})
 * Generate instructions to copy the contents of the top stack register
 * into a stack register specified by the @code{reg} argument and pop
 * the top register after this. If @code{reg} is equal to the top register
 * then the top register is just popped without copying it.
 *
 * It needs to be implemented only by backends that support stack registers.
 * @end deftypefun
@*/
void _jit_gen_move_top(jit_gencode_t gen, int reg)
{
	/* Stack registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_spill_top (jit_gencode_t @var{gen}, int @var{reg}, jit_value_t @var{value}, int @var{pop})
 * Generate instructions to spill the top stack register to the local
 * variable frame. The @var{pop} argument indicates if the top register
 * is popped from the stack.
 *
 * It needs to be implemented only by backends that support stack registers.
 * @end deftypefun
@*/
void _jit_gen_spill_top(jit_gencode_t gen, int reg, jit_value_t value, int pop)
{
	/* Stack registers are not used in the interpreted back end */
}

/*@
 * @deftypefun void _jit_gen_fix_value (jit_value_t @var{value})
 * Fix the position of a value within the local variable frame.
 * If it doesn't already have a position, then assign one for it.
 * @end deftypefun
@*/
void _jit_gen_fix_value(jit_value_t value)
{
	if(!(value->has_frame_offset) && !(value->is_constant))
	{
		jit_nint size = (jit_nint)
			(JIT_NUM_ITEMS_IN_STRUCT(jit_type_get_size(value->type)));
		value->frame_offset = value->block->func->builder->frame_size;
		value->block->func->builder->frame_size += size;

libjit/jit/jit-rules-interp.c  view on Meta::CPAN

		}
		break;
	}
}

/*@
 * @deftypefun void _jit_gen_start_block (jit_gencode_t @var{gen}, jit_block_t @var{block})
 * Called to notify the back end that the start of a basic block
 * has been reached.
 * @end deftypefun
@*/
void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block)
{
	void **fixup;
	void **next;

	/* Set the address of this block */
	block->address = (void *)(gen->ptr);

	/* If this block has pending fixups, then apply them now */
	fixup = (void **)(block->fixup_list);
	while(fixup != 0)
	{
		next = (void **)(fixup[1]);
		fixup[1] = (void *)(jit_nint)(((void **)(block->address)) - fixup);
		fixup = next;
	}
	block->fixup_list = 0;

	fixup = (void **)(block->fixup_absolute_list);
	while(fixup != 0)
	{
		next = (void **)(fixup[0]);
		fixup[0] = (void *)(jit_nint)((void **)(block->address));
		fixup = next;
	}
	block->fixup_absolute_list = 0;

	/* If this is the exception catcher block, then we need to update
	   the exception cookie for the function to point to here */
	if(block->label == block->func->builder->catcher_label &&
	   block->func->has_try)
	{
		block->func->cookie = block->address;
	}
}

/*@
 * @deftypefun void _jit_gen_end_block (jit_gencode_t @var{gen})
 * Called to notify the back end that the end of a basic block
 * has been reached.
 * @end deftypefun
@*/
void _jit_gen_end_block(jit_gencode_t gen, jit_block_t block)
{
	/* Reset the working area size to zero for the next block */
	gen->working_area = 0;
}

/*@
 * @deftypefun int _jit_gen_is_global_candidate (jit_type_t @var{type})
 * Determine if @var{type} is a candidate for allocation within
 * global registers.
 * @end deftypefun
@*/
int _jit_gen_is_global_candidate(jit_type_t type)
{
	/* Global register allocation is not used by the interpreter */
	return 0;
}

/*@
 * @deftypefun int _jit_reg_get_pair (jit_type_t @var{type}, int @var{reg})
 * Determine if a type requires a register pair. If so then for the specified
 * register @var{reg} return the other register of the corresponding pair.
 * Return -1 if no pair is required.
 *
 * This function is used only for native 32-bit backends.
 * @end deftypefun
@*/
int _jit_reg_get_pair(jit_type_t type, int reg)
{
	/* We don't register pairs on 64-bit platforms or the interpreter */
	return -1;
}

#endif /* JIT_BACKEND_INTERP */



( run in 0.839 second using v1.01-cache-2.11-cpan-f0fbb3f571b )