Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
}
JIT_OP_IMPORT:
[] -> {
/* TODO */
TODO();
}
/*
* Exception handling
*/
JIT_OP_THROW: branch
[reg] -> {
arm_push_reg(inst, $1);
if(func->builder->setjmp_value != 0)
{
/* We have a "setjmp" block in the current function,
so we must record the location of the throw first */
jit_nint pc_offset;
_jit_gen_fix_value(func->builder->setjmp_value);
pc_offset = func->builder->setjmp_value->frame_offset +
jit_jmp_catch_pc_offset;
if(func->builder->position_independent)
{
arm_call_imm(inst, 0);
arm_pop_membase(inst, ARM_FP, pc_offset);
}
else
{
int pc = (int) (unsigned char *) arm_inst_get_posn(inst);
arm_mov_membase_imm(inst, ARM_FP, pc_offset, pc, 4, ARM_WORK);
}
}
arm_call(inst, (void *)jit_exception_throw);
}
JIT_OP_LOAD_PC:
[=reg] -> {
if(func->builder->position_independent)
{
arm_call_imm(inst, 0);
arm_pop_reg(inst, $1);
}
else
{
int pc = inst.current;
mov_reg_imm(gen, &inst, $1, pc);
}
}
JIT_OP_ENTER_FINALLY:
[] -> { /*
* The return address is in the link register
* We must save it on the stack in case it will be overwritten by the content
* of the "finally" block.
* In order to respect the ABI of the ARM architecture, that prescribes an 8-byte
* alignment for the stack at a public interface, we save the value twice,
* in order to move the current SP by 8 bytes
* (we could have just saved the value once and then moved the SP by 4 bytes)
*/
arm_push_reg(inst, ARM_LINK);
arm_push_reg(inst, ARM_LINK);
}
JIT_OP_LEAVE_FINALLY: branch
[] -> {
/* The "finally" return address is on the stack (twice, just for padding)*/
arm_pop_reg(inst, ARM_LINK);
arm_pop_reg(inst, ARM_LINK);
arm_return(inst);
}
JIT_OP_CALL_FINALLY: branch
[] -> {
jit_block_t block;
int offset;
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_call(inst, 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_call_imm(inst, offset);
block->fixup_list = (void *)(arm_inst_get_posn(inst) - 1);
}
}
JIT_OP_ADDRESS_OF_LABEL:
[=reg] -> {
block = jit_block_from_label(func, (jit_label_t)(insn->value1));
if(func->builder->position_independent)
{
/* TODO */
TODO();
}
else
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
else if ($1 == indexreg)
{
//Prevent index reg from being overwritten
arm_mov_reg_reg(inst, $5, indexreg);
indexreg=$5;
}
arm_mov_reg_memindex(inst, $1, basereg, 0, indexreg, 3, 4, $4);
//Write the 2-nd word
arm_mov_reg_memindex(inst, %1, basereg, 4, indexreg, 3, 4, $4);
}
JIT_OP_LOAD_ELEMENT_FLOAT64:
[=freg64, reg, reg, scratch reg] -> {
arm_fld_memindex(inst, $1, $2, 0, $3, 3, 1, $4);
}
JIT_OP_STORE_ELEMENT_BYTE: ternary
[reg, reg, reg, scratch reg] -> {
arm_mov_memindex_reg(inst, $1, 0, $2, 0, $3, 1, $4);
}
JIT_OP_STORE_ELEMENT_SHORT: ternary
[reg, reg, reg, scratch reg] -> {
arm_mov_memindex_reg(inst, $1, 0, $2, 1, $3, 2, $4);
}
JIT_OP_STORE_ELEMENT_INT: ternary
[reg, reg, reg, scratch reg] -> {
arm_mov_memindex_reg(inst, $1, 0, $2, 2, $3, 4, $4);
}
JIT_OP_STORE_ELEMENT_LONG: ternary
[reg, reg, imm] -> {
TODO();
abort();
//x86_mov_memindex_imm(inst, $1, 0, $2, 3, *(int *)($3), 4);
//x86_mov_memindex_imm(inst, $1, 4, $2, 3, *(int *)($3 + 4), 4);
}
[reg, reg, local, scratch reg, scratch reg] -> {
arm_mov_reg_membase(inst, $4, ARM_FP, $3, 4);
arm_mov_memindex_reg(inst, $1, 0, $2, 3, $4, 4, $5);
arm_mov_reg_membase(inst, $4, ARM_FP, $3 + 4, 4);
arm_mov_memindex_reg(inst, $1, 4, $2, 3, $4, 4, $5);
}
[reg, reg, lreg, scratch reg] -> {
arm_mov_memindex_reg(inst, $1, 0, $2, 3, $3, 4, $4);
arm_mov_memindex_reg(inst, $1, 4, $2, 3, %3, 4, $4);
}
JIT_OP_STORE_ELEMENT_FLOAT64: ternary
[reg, reg, freg64, scratch reg] -> {
arm_fst_memindex(inst, $3, $1, 0, $2, 3, 1, $4);
}
/*
* Allocate memory from the stack.
*/
JIT_OP_ALLOCA:
[reg] -> {
//The ARM stack must always be 4-byte aligned and must be 8-byte aligned at a public interface.
//Since we don't know when this function will be called, let's align to 8 bytes.
arm_alu_reg_imm(inst, ARM_ADD, $1, $1, 7);
arm_alu_reg_imm(inst, ARM_AND, $1, $1, ~7);
arm_alu_reg_reg(inst, ARM_SUB, ARM_SP, ARM_SP, $1);
arm_mov_reg_reg(inst, $1, ARM_SP);
gen->stack_changed = 1;
}
/*
* Block operations
*/
JIT_OP_MEMCPY: ternary
[any, any, imm, if("$3 <= 0")] -> { }
[reg, reg, imm, scratch reg, clobber("r0", "r1", "r2")] ->
{
/*
* Call jit_memcpy(dest,src,size).
* $1=dest, $2=src, $3=size
*/
int dest=$1;
int src=$2;
if (dest != ARM_R0) {
if(src==ARM_R0)
{
//Prevent overwriting useful data
arm_mov_reg_reg(inst, $4, src);
src=$4;
}
arm_mov_reg_reg((inst), ARM_R0, dest);
}
if (src != ARM_R1) {
//Move the "src" from wherever it is to where it should be
arm_mov_reg_reg(inst, ARM_R1, src);
}
mov_reg_imm(gen, &(inst), ARM_R2, $3);
//Call the function
arm_call(inst, jit_memcpy);
}
[reg, reg, reg, scratch reg, clobber("r0", "r1", "r2")] -> {
/*
* Call jit_memcpy(dest,src,size).
* $1=dest, $2=src, $3=size
*/
if ($1 != ARM_R0) {
if($2==ARM_R0)
{
//Prevent overwriting useful data
arm_mov_reg_reg(inst, $4, $2);
}
arm_mov_reg_reg((inst), ARM_R0, $1);
}
if ($2 != ARM_R1) {
if ($2==ARM_R0)
{
//Recover previously saved data
arm_mov_reg_reg(inst, ARM_R1, $4);
}
else
( run in 0.458 second using v1.01-cache-2.11-cpan-5623c5533a1 )