Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-rules-arm.ins view on Meta::CPAN
*/
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
{
arm_mov_reg_reg((inst), ARM_R1, $2);
}
}
if ($3 != ARM_R2) {
arm_mov_reg_reg((inst), ARM_R2, $3);
}
//Call the function
arm_call(inst, jit_memcpy);
}
JIT_OP_MEMSET: ternary
[any, any, imm, if("$3 <= 0")] -> { }
[reg, imm, imm, if("$3 <= 32"), space("32 + $3 * 4")] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
int disp;
disp = 0;
while($3 >= (disp + 4))
{
//NB: if 0<A<255, then A*0x01010101 = a 32-bit value where each of its four bytes is A.
arm_mov_membase_imm(inst, $1, disp, $2 * 0x01010101, 4, ARM_WORK);
disp += 4;
}
if($3 >= (disp + 2))
{
arm_mov_membase_imm(inst, $1, disp, $2 * 0x0101, 2, ARM_WORK);
disp += 2;
}
if(insn->value2->address > disp)
{
arm_mov_membase_imm(inst, $1, disp, $2, 1, ARM_WORK);
}
}
[reg, reg, imm, if("$3 < 4")] -> {
TODO();
abort();
}
[reg, +reg, imm, scratch reg, if("$3 <= 32 && ($3 % 2) == 0"), space("32 + $3 * 4")] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
// $4 = scratch register
int disp;
arm_mov_reg_reg(inst, $4, $2);
arm_shift_reg_imm8(inst, ARM_SHL, $2, $2, 8);
arm_alu_reg_reg(inst, ARM_ORR, $2, $2, $4);
arm_mov_reg_reg(inst, $4, $2);
arm_shift_reg_imm8(inst, ARM_SHL, $2, $2, 16);
arm_alu_reg_reg(inst, ARM_ORR, $2, $2, $4);
disp = 0;
while($3 >= (disp + 4))
{
arm_mov_membase_reg(inst, $1, disp, $2, 4);
disp += 4;
}
if($3 > disp)
{
arm_mov_membase_reg(inst, $1, disp, $2, 2);
}
}
[reg, +reg, imm, scratch reg,
if("$3 <= 32 && ($3 % 2) != 0"), space("32 + $3 * 4")] -> {
TODO();
abort();
}
[reg, reg, reg, clobber("r0", "r1", "r2"), scratch reg] -> {
// $1 = pointer to the initial memory location
// $2 = value to be written in memory
// $3 = length in bytes
// $4 = scratch register
int pointer=$1;
int value=$2;
int length=$3;
int scratch=$4;
/* Move the outgoing parameters in the right registers (if they are not already where they should be */
if (pointer != ARM_R0) {
if(value == ARM_R0)
{
//Prevent the value from being overwritten
arm_mov_reg_reg((inst), scratch, ARM_R0);
value=scratch;
}
else if(length==ARM_R0)
{
//Prevent the length from being overwritten
arm_mov_reg_reg((inst), scratch, ARM_R0);
length=scratch;
}
arm_mov_reg_reg((inst), ARM_R0, pointer);
//The register that contained the pointer is now free
scratch=pointer;
}
if (value != ARM_R1)
{
if (length == ARM_R1)
{
//The length is stored in R1. Prevent it from being overwritten
arm_mov_reg_reg(inst, scratch, length);
length=scratch;
}
//Set param 2
arm_mov_reg_reg((inst), ARM_R1, value);
//The register that contained the value is now free
scratch=value;
}
if(length != ARM_R1)
{
//Param 3 still isn't in place: move it!
arm_mov_reg_reg(inst, ARM_R2, length);
}
arm_call(inst, jit_memset);
}
( run in 1.429 second using v1.01-cache-2.11-cpan-140bd7fdf52 )