Alien-LibJIT

 view release on metacpan or  search on metacpan

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

 * and then once you have them working you can move on to the floating point
 * operations.
 * @end deftypefun
@*/
int _jit_opcode_is_supported(int opcode)
{
	/* We support all opcodes in the interpreter */
	return 1;
}

/*
 * Calculate the size of the argument area for an interpreted function.
 */
unsigned int _jit_interp_calculate_arg_size
		(jit_function_t func, jit_type_t signature)
{
	unsigned int size = 0;
	jit_type_t type;
	unsigned int num_params;
	unsigned int param;

	/* Determine if we need nested parameter information */
	if(func->nested_parent)
	{
		size += 2 * sizeof(jit_item);
	}

	/* Determine if we need a structure pointer argument */
	type = jit_type_get_return(signature);
	if(jit_type_return_via_pointer(type))
	{
		size += sizeof(jit_item);
	}

	/* Calculate the total size of the regular arguments */
	num_params = jit_type_num_params(signature);
	for(param = 0; param < num_params; ++param)
	{
		type = jit_type_normalize(jit_type_get_param(signature, param));
		if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
		{
			size += JIT_NUM_ITEMS_IN_STRUCT(jit_type_get_size(type)) *
					sizeof(jit_item);
		}
		else
		{
			size += sizeof(jit_item);
		}
	}

	/* Return the final size to the caller */
	return size;
}

/*@
 * @deftypefun {void *} _jit_gen_prolog (jit_gencode_t @var{gen}, jit_function_t @var{func}, void *@var{buf})
 * Generate the prolog for a function into a previously-prepared
 * buffer area of @code{JIT_PROLOG_SIZE} bytes in size.  Returns
 * the start of the prolog, which may be different than @var{buf}.
 *
 * This function is called at the end of the code generation process,
 * not the beginning.  At this point, it is known which callee save
 * registers must be preserved, allowing the back end to output the
 * most compact prolog possible.
 * @end deftypefun
@*/
void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
{
	/* Output the jit_function_interp structure at the beginning */
	jit_function_interp_t interp = (jit_function_interp_t)buf;
	unsigned int max_working_area =
		gen->max_working_area + gen->extra_working_space;
	interp->func = func;
	interp->args_size = _jit_interp_calculate_arg_size(func, func->signature);
	interp->frame_size =
		(func->builder->frame_size + max_working_area) * sizeof(jit_item);
	interp->working_area = max_working_area;
	return buf;
}

/*@
 * @deftypefun void _jit_gen_epilog (jit_gencode_t @var{gen}, jit_function_t @var{func})
 * Generate a function epilog, restoring the registers that
 * were saved on entry to the function, and then returning.
 *
 * Only one epilog is generated per function.  Functions with multiple
 * @code{jit_insn_return} instructions will all jump to the common epilog.
 * This is needed because the code generator may not know which callee
 * save registers need to be restored by the epilog until the full function
 * has been processed.
 * @end deftypefun
@*/
void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
{
	/* The interpreter doesn't use epilogs */
}

/*@
 * @deftypefun {void *} _jit_gen_redirector (jit_gencode_t @var{gen}, jit_function_t @var{func})
 * Generate code for a redirector, which makes an indirect jump
 * to the contents of @code{@var{func}->entry_point}.  Redirectors
 * are used on recompilable functions in place of the regular
 * entry point.  This allows @code{libjit} to redirect existing
 * 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 */
}

/*@



( run in 0.641 second using v1.01-cache-2.11-cpan-5735350b133 )