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 )