Alien-LibJIT

 view release on metacpan or  search on metacpan

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

 * Structure that is used to help with parameter passing.
 */
typedef struct
{
	jit_nint		offset;
	unsigned int	index;
	unsigned int	max_regs;
	const int	   *word_regs;
	jit_value_t		word_values[JIT_MAX_WORD_REG_PARAMS];

} jit_param_passing_t;

/*
 * Round a size up to a multiple of the stack word size.
 */
#define	ROUND_STACK(size)	\
		(((size) + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
#define	STACK_WORDS(size)	\
		(((size) + (sizeof(void *) - 1)) / sizeof(void *))

/*
 * Allocate a word register or incoming frame position to a value.
 */
static int alloc_incoming_word
	(jit_function_t func, jit_param_passing_t *passing,
	 jit_value_t value, int extra_offset)
{
	int reg;
	reg = passing->word_regs[passing->index];
	if(reg != -1 && passing->word_values[passing->index] != 0)
	{
		/* The value was already forced out previously, so just copy it */
		if(!jit_insn_store(func, value, passing->word_values[passing->index]))
		{
			return 0;
		}
		++(passing->index);
	}
	else if(reg != -1)
	{
		if(!jit_insn_incoming_reg(func, value, reg))
		{
			return 0;
		}
		++(passing->index);
	}
	else
	{
		if(!jit_insn_incoming_frame_posn
				(func, value, passing->offset + extra_offset))
		{
			return 0;
		}
		passing->offset += sizeof(void *);
	}
	return 1;
}

/*
 * Force the remaining word registers out into temporary values,
 * to protect them from being accidentally overwritten by the code
 * that deals with multi-word parameters.
 */
static int force_remaining_out
	(jit_function_t func, jit_param_passing_t *passing)
{
	unsigned int index = passing->index;
	jit_value_t value;
	while(index < passing->max_regs && passing->word_regs[index] != -1)
	{
		if(passing->word_values[index] != 0)
		{
			/* We've already done this before */
			return 1;
		}
		value = jit_value_create(func, jit_type_void_ptr);
		if(!value)
		{
			return 0;
		}
		if(!jit_insn_incoming_reg(func, value, passing->word_regs[index]))
		{
			return 0;
		}
		passing->word_values[index] = value;
		++index;
	}
	return 1;
}

int _jit_create_entry_insns(jit_function_t func)
{
	jit_type_t signature = func->signature;
	jit_type_t type;
	jit_value_t value;
	jit_value_t temp;
	jit_value_t addr_of;
	unsigned int num_params;
	unsigned int param;
	unsigned int size;
	jit_param_passing_t passing;
	jit_nint partial_offset;

	/* Reset the local variable frame size for this function */
	func->builder->frame_size = JIT_INITIAL_FRAME_SIZE;

	/* Initialize the parameter passing information block */
	passing.offset = JIT_INITIAL_STACK_OFFSET;
	passing.index = 0;
#ifdef JIT_FASTCALL_WORD_REG_PARAMS
	if(jit_type_get_abi(signature) == jit_abi_fastcall)
	{
		passing.word_regs = fastcall_word_regs;
	}
	else
#endif
	{
		passing.word_regs = cdecl_word_regs;
	}
	for(size = 0; size < JIT_MAX_WORD_REG_PARAMS; ++size)
	{



( run in 0.601 second using v1.01-cache-2.11-cpan-524268b4103 )