Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-rules-x86-64.c view on Meta::CPAN
/* and load the integer to the destination register */
x86_64_mov_reg_regp_size(inst, dreg, X86_64_RSP, size);
/* restore the stack pointer */
x86_64_add_reg_imm_size(inst, X86_64_RSP, 16, 8);
#endif
#endif
return inst;
}
/*
* Call a function
*/
static unsigned char *
x86_64_call_code(unsigned char *inst, jit_nint func)
{
jit_nint offset;
x86_64_mov_reg_imm_size(inst, X86_64_RAX, 8, 4);
offset = func - ((jit_nint)inst + 5);
if(offset >= jit_min_int && offset <= jit_max_int)
{
/* We can use the immediate call */
x86_64_call_imm(inst, offset);
}
else
{
/* We have to do a call via register */
x86_64_mov_reg_imm_size(inst, X86_64_SCRATCH, func, 8);
x86_64_call_reg(inst, X86_64_SCRATCH);
}
return inst;
}
/*
* Jump to a function
*/
static unsigned char *
x86_64_jump_to_code(unsigned char *inst, jit_nint func)
{
jit_nint offset;
offset = func - ((jit_nint)inst + 5);
if(offset >= jit_min_int && offset <= jit_max_int)
{
/* We can use the immediate call */
x86_64_jmp_imm(inst, offset);
}
else
{
/* We have to do a call via register */
x86_64_mov_reg_imm_size(inst, X86_64_SCRATCH, func, 8);
x86_64_jmp_reg(inst, X86_64_SCRATCH);
}
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);
x86_64_lea_membase_size(inst, X86_64_RDI, X86_64_RIP, 0, 8);
x86_64_mov_membase_reg_size(inst, X86_64_RBP,
func->builder->setjmp_value->frame_offset
+ jit_jmp_catch_pc_offset, X86_64_RDI, 8);
}
/* Push the exception type onto the stack */
x86_64_mov_reg_imm_size(inst, X86_64_RDI, type, 4);
/* Call the "jit_exception_builtin" function, which will never return */
return x86_64_call_code(inst, (jit_nint)jit_exception_builtin);
}
/*
* spill a register to it's place in the current stack frame.
* The argument type must be in it's normalized form.
*/
static void
_spill_reg(unsigned char **inst_ptr, jit_type_t type,
jit_int reg, jit_int offset)
{
unsigned char *inst = *inst_ptr;
if(IS_GENERAL_REG(reg))
{
switch(type->kind)
{
#if 0
case JIT_TYPE_SBYTE:
case JIT_TYPE_UBYTE:
{
x86_64_mov_membase_reg_size(inst, X86_64_RBP, offset,
_jit_reg_info[reg].cpu_reg, 1);
}
break;
case JIT_TYPE_SHORT:
case JIT_TYPE_USHORT:
{
x86_64_mov_membase_reg_size(inst, X86_64_RBP, offset,
_jit_reg_info[reg].cpu_reg, 2);
}
break;
#else
case JIT_TYPE_SBYTE:
case JIT_TYPE_UBYTE:
case JIT_TYPE_SHORT:
case JIT_TYPE_USHORT:
#endif
case JIT_TYPE_INT:
case JIT_TYPE_UINT:
case JIT_TYPE_FLOAT32:
{
x86_64_mov_membase_reg_size(inst, X86_64_RBP, offset,
( run in 0.375 second using v1.01-cache-2.11-cpan-1edf4fed603 )