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 )