Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-rules-x86.c view on Meta::CPAN
{
/* We need to output a long-form backwards branch */
offset -= 3;
opcode = long_form_branch(opcode);
if(opcode < 256)
{
*inst++ = (unsigned char)opcode;
}
else
{
*inst++ = (unsigned char)(opcode >> 8);
*inst++ = (unsigned char)opcode;
--offset;
}
x86_imm_emit32(inst, offset);
}
}
else
{
/* Output a placeholder and record on the block's fixup list */
opcode = long_form_branch(opcode);
if(opcode < 256)
{
*inst++ = (unsigned char)opcode;
}
else
{
*inst++ = (unsigned char)(opcode >> 8);
*inst++ = (unsigned char)opcode;
}
x86_imm_emit32(inst, (int)(block->fixup_list));
block->fixup_list = (void *)(inst - 4);
}
return inst;
}
/*
* Jump to the current function's epilog.
*/
static unsigned char *
jump_to_epilog(jit_gencode_t gen, unsigned char *inst, jit_block_t block)
{
/* 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 inst;
}
/* Output a placeholder for the jump and add it to the fixup list */
*inst++ = (unsigned char)0xE9;
x86_imm_emit32(inst, (int)(gen->epilog_fixup));
gen->epilog_fixup = (void *)(inst - 4);
return inst;
}
/*
* Throw a builtin exception.
*/
static unsigned char *
throw_builtin(unsigned char *inst, jit_function_t func, int type)
{
/* 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);
if(func->builder->position_independent)
{
x86_call_imm(inst, 0);
x86_pop_membase(inst, X86_EBP,
func->builder->setjmp_value->frame_offset
+ jit_jmp_catch_pc_offset);
}
else
{
int pc = (int) inst;
x86_mov_membase_imm(inst, X86_EBP,
func->builder->setjmp_value->frame_offset
+ jit_jmp_catch_pc_offset, pc, 4);
}
}
/* Push the exception type onto the stack */
x86_push_imm(inst, type);
/* Call the "jit_exception_builtin" function, which will never return */
x86_call_code(inst, jit_exception_builtin);
return inst;
}
/*
* Copy a block of memory that has a specific size. Other than
* the parameter pointers, all registers must be unused at this point.
*/
static unsigned char *memory_copy
(jit_gencode_t gen, unsigned char *inst, int dreg, jit_nint doffset,
int sreg, jit_nint soffset, jit_nuint size)
{
int temp_reg = get_temp_reg(dreg, sreg, -1);
if(size <= 4 * sizeof(void *))
{
/* Use direct copies to copy the memory */
int offset = 0;
while(size >= sizeof(void *))
{
x86_mov_reg_membase(inst, temp_reg, sreg,
soffset + offset, sizeof(void *));
x86_mov_membase_reg(inst, dreg, doffset + offset,
temp_reg, sizeof(void *));
size -= sizeof(void *);
offset += sizeof(void *);
}
#ifdef JIT_NATIVE_INT64
if(size >= 4)
{
x86_mov_reg_membase(inst, temp_reg, sreg, soffset + offset, 4);
x86_mov_membase_reg(inst, dreg, doffset + offset, temp_reg, 4);
size -= 4;
offset += 4;
}
#endif
( run in 0.369 second using v1.01-cache-2.11-cpan-385001e3568 )