Alien-LibJIT

 view release on metacpan or  search on metacpan

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

	arm_branch_imm(*inst, cond ^ 0x01, 0);

	/* We need to update "catch_pc" if we have a "try" block */
	if(func->builder->setjmp_value != 0)
	{
		_jit_gen_fix_value(func->builder->setjmp_value);
		arm_mov_reg_reg(*inst, ARM_WORK, ARM_PC);
		arm_store_membase(*inst, ARM_WORK, ARM_FP,
				   func->builder->setjmp_value->frame_offset +
						   jit_jmp_catch_pc_offset);
	}

	/* Push the exception type onto the stack */
	arm_mov_reg_imm(*inst, ARM_WORK, type);
	arm_push_reg(*inst, ARM_WORK);

	/* Call the "jit_exception_builtin" function, which will never return */
	arm_call(*inst, jit_exception_builtin);

	/* Back-patch the previous branch instruction */
	arm_patch(*inst, patch, arm_inst_get_posn(*inst));
}

/*
 * Jump to the current function's epilog.
 */
static void jump_to_epilog
		(jit_gencode_t gen, arm_inst_buf *inst, jit_block_t block)
{
	int offset;

	/* If the epilog is the next thing that we will output,
	   then fall through to the epilog directly */
	if(_jit_block_is_final(block))
	{
		return;
	}

	/* Bail out if the instruction buffer has overflowed */
	if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
	{
		return;
	}

	/* Output a placeholder for the jump and add it to the fixup list */
	if(gen->epilog_fixup)
	{
		offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
				((unsigned char *)(gen->epilog_fixup)));
	}
	else
	{
		offset = 0;
	}
	arm_branch_imm(*inst, ARM_CC_AL, offset);
	gen->epilog_fixup = (void *)(arm_inst_get_posn(*inst) - 1);
}

#define	TODO()		\
	do { \
		fprintf(stderr, "TODO at %s, %d\n", __FILE__, (int)__LINE__); \
} while (0)

/*
 * -------------------- End of helper functions ------------------------
 */


/*
 * Initialize the backend.
 */
void _jit_init_backend(void)
{
	/*
	 * Init the various classes of registers
	 */

	/* WORD registers */
	arm_reg = _jit_regclass_create(
		"reg", JIT_REG_WORD, 9,
		ARM_REG_R0, ARM_REG_R1,
		ARM_REG_R2, ARM_REG_R3,
		ARM_REG_R4, ARM_REG_R5,
		ARM_REG_R6, ARM_REG_R7,
		ARM_REG_R8);

#ifdef JIT_ARM_HAS_FPA
	/* float registers */
	arm_freg = _jit_regclass_create(
		"freg64", JIT_REG_ARM_FLOAT, 4,
		ARM_REG_F0, ARM_REG_F1,
		ARM_REG_F2, ARM_REG_F3,
		/*ARM_REG_F4, ARM_REG_F5,
		  ARM_REG_F6, ARM_REG_F7*/);
#endif

#ifdef JIT_ARM_HAS_VFP
	/* 32-bits float registers */
	arm_freg32 = _jit_regclass_create(
		"freg32", JIT_REG_ARM_FLOAT32, 16,
		ARM_REG_S0, ARM_REG_S1,
		ARM_REG_S2, ARM_REG_S3,
		ARM_REG_S4, ARM_REG_S5,
		ARM_REG_S6, ARM_REG_S7,
		ARM_REG_S8, ARM_REG_S9,
		ARM_REG_S10, ARM_REG_S11,
		ARM_REG_S12, ARM_REG_S13,
		ARM_REG_S14, ARM_REG_S15);

	/* 64-bits float registers */
	arm_freg64 = _jit_regclass_create(
		"freg64", JIT_REG_ARM_FLOAT64, 8,
		ARM_REG_D8, ARM_REG_D9,
		ARM_REG_D10, ARM_REG_D11,
		ARM_REG_D12, ARM_REG_D13,
		ARM_REG_D14, ARM_REG_D15);
#endif

	/* Long registers */
	arm_lreg = _jit_regclass_create(
		"lreg", JIT_REG_LONG, 2,

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

			int other_reg = jit_reg_current_other_reg(gen,reg);
			
			_jit_gen_spill_reg(gen, reg, other_reg, value);
			value->in_frame=1;

			/* A new instruction has probably been generated by _jit_gen_spill_reg: reload the inst pointer */
			jit_gen_load_inst_ptr(gen, inst);
		}
		
		assert(jit_type_normalize(value->type)->kind==JIT_TYPE_STRUCT);
		
		arm_load_membase(inst, _jit_reg_info[reg].cpu_reg, ARM_FP, offset);
		if (jit_type_get_size(jit_value_get_type(value)) > 4)
		{
			TODO();
			abort();
		}
		
	}

	/* End the code output process */
	jit_cache_end_output();
}

void _jit_gen_spill_global(jit_gencode_t gen, int reg, jit_value_t value)
{
	/* TODO: Implement if ARM needs it. */
}

void _jit_gen_load_global(jit_gencode_t gen, int reg, jit_value_t value)
{
	jit_cache_setup_output(32);
	arm_load_membase(inst, _jit_reg_info[value->global_reg].cpu_reg,
					 ARM_FP, value->frame_offset);
	jit_cache_end_output();
}

void _jit_gen_fix_value(jit_value_t value)
{
	if(!(value->has_frame_offset) && !(value->is_constant))
	{
		jit_nint size = (jit_nint)(ROUND_STACK(jit_type_get_size(value->type)));
		value->block->func->builder->frame_size += size;
		value->frame_offset = -(value->block->func->builder->frame_size);
		value->has_frame_offset = 1;
	}
}

void _jit_gen_insn(jit_gencode_t gen, jit_function_t func,
				   jit_block_t block, jit_insn_t insn)
{
	flush_if_too_far(gen);
	switch(insn->opcode)
	{
		#define JIT_INCLUDE_RULES
		#include "jit-rules-arm.inc"
		#undef JIT_INCLUDE_RULES

		default:
		{
			fprintf(stderr, "TODO(%x) at %s, %d\n",
					(int)(insn->opcode), __FILE__, (int)__LINE__);
		}
		break;
	}
}

void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block)
{
	void **fixup;
	void **next;
	jit_nint offset;
	arm_inst_buf inst;

	/* 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)
	{
		offset = (((jit_nint)(fixup[0])) & 0x00FFFFFF) << 2;
		if(!offset)
		{
			next = 0;
		}
		else
		{
			next = (void **)(((unsigned char *)fixup) - offset);
		}
		jit_gen_load_inst_ptr(gen, inst);
		arm_patch(inst, fixup, block->address);
		fixup = next;
	}
	block->fixup_list = 0;
}

void _jit_gen_end_block(jit_gencode_t gen, jit_block_t block)
{
	/* Nothing to do here for ARM */
}

int _jit_gen_is_global_candidate(jit_type_t type)
{
	switch(jit_type_remove_tags(type)->kind)
	{
		case JIT_TYPE_INT:
		case JIT_TYPE_UINT:
		case JIT_TYPE_NINT:
		case JIT_TYPE_NUINT:
		case JIT_TYPE_PTR:
		case JIT_TYPE_SIGNATURE:	return 1;
	}
	return 0;
}

int
_jit_reg_get_pair(jit_type_t type, int reg)
{
	type = jit_type_normalize(type);
	if(type)



( run in 0.499 second using v1.01-cache-2.11-cpan-1edf4fed603 )