Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-rules-arm.c view on Meta::CPAN
arm_load_membase_float64(*inst, reg, ARM_PC, 0);
/* Add the constant to the pool, which may cause a flush */
jit_gen_save_inst_ptr(gen, *inst);
add_constant_dword(gen, value1, value2, fixup, 1);
jit_gen_load_inst_ptr(gen, *inst);
}
/*
* Output a branch instruction.
*/
static void output_branch
(jit_function_t func, arm_inst_buf *inst, int cond, jit_insn_t insn)
{
jit_block_t block;
int offset;
//block = jit_block_from_label(func, (jit_label_t)(insn->dest));
if((insn->flags & JIT_INSN_VALUE1_IS_LABEL) != 0)
{
/* "address_of_label" instruction */
block = jit_block_from_label(func, (jit_label_t)(insn->value1));
}
else
{
block = jit_block_from_label(func, (jit_label_t)(insn->dest));
}
if(!block)
{
return;
}
if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
{
/* The buffer has overflowed, so don't worry about fixups */
return;
}
if(block->address)
{
/* We already know the address of the block */
arm_branch(*inst, cond, block->address);
}
else
{
/* Output a placeholder and record on the block's fixup list */
if(block->fixup_list)
{
offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
((unsigned char *)(block->fixup_list)));
}
else
{
offset = 0;
}
arm_branch_imm(*inst, cond, offset);
block->fixup_list = (void *)(arm_inst_get_posn(*inst) - 1);
}
}
/*
* Throw a builtin exception.
*/
static void throw_builtin
(arm_inst_buf *inst, jit_function_t func, int cond, int type)
{
arm_inst_word *patch;
/* Branch past the following code if "cond" is not true */
patch = arm_inst_get_posn(*inst);
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;
}
( run in 0.330 second using v1.01-cache-2.11-cpan-119454b85a5 )