Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-rules-arm.ins  view on Meta::CPAN

	[reg, imm] -> {
		arm_shift_reg_imm8(inst, ARM_SHL, $1, $1, ($2 & 0x1F));
	}
	[reg, reg] -> {
		arm_alu_reg_imm8(inst, ARM_AND, ARM_WORK, $2, 0x1F);
		arm_shift_reg_reg(inst, ARM_SHL, $1, $1, ARM_WORK);
	}

JIT_OP_ISHR: 
	[reg, imm] -> {
		arm_shift_reg_imm8(inst, ARM_SAR, $1, $1, ($2 & 0x1F));
	}
	[reg, reg] -> {
		arm_alu_reg_imm8(inst, ARM_AND, ARM_WORK, $2, 0x1F);
		arm_shift_reg_reg(inst, ARM_SAR, $1, $1, ARM_WORK);
	}

JIT_OP_ISHR_UN: 
	[reg, imm] -> {
		arm_shift_reg_imm8(inst, ARM_SHR, $1, $1, ($2 & 0x1F));
	}
	[reg, reg] -> {
		arm_alu_reg_imm8(inst, ARM_AND, ARM_WORK, $2, 0x1F);
		arm_shift_reg_reg(inst, ARM_SHR, $1, $1, ARM_WORK);
	}

JIT_OP_LAND: 
	[lreg, lreg] -> {
		arm_alu_reg_reg(inst, ARM_AND, $1, $1, $2);
		arm_alu_reg_reg(inst, ARM_AND, %1, %1, %2);
	}

JIT_OP_LOR: 
	[lreg, lreg] -> {
		arm_alu_reg_reg(inst, ARM_ORR, $1, $1, $2);
		arm_alu_reg_reg(inst, ARM_ORR, %1, %1, %2);
	}

JIT_OP_LXOR: 
	[lreg, lreg] -> {
		arm_alu_reg_reg(inst, ARM_EOR, $1, $1, $2);
		arm_alu_reg_reg(inst, ARM_EOR, %1, %1, %2);
	}

JIT_OP_LNOT: 
	[lreg] -> {
		arm_alu_reg(inst, ARM_MVN, $1, $1);
		arm_alu_reg(inst, ARM_MVN, %1, %1);
	}

/*
 * Branch opcodes.
 */

JIT_OP_BR: branch /*spill_before*/
	[] -> {
		/* ARM_CC_AL == "always branch" */
		output_branch(func, &inst, ARM_CC_AL, insn);

		/* Flush the constant pool now, to minimize the probability that
		   it is accidentally flushed in the middle of a loop body */
		jit_gen_save_inst_ptr(gen, inst);
		flush_constants(gen, 1);
		jit_gen_load_inst_ptr(gen, inst);
	}

JIT_OP_BR_IFALSE: branch 
	[reg] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, 0);
		output_branch(func, &inst, ARM_CC_EQ, insn);
	}

JIT_OP_BR_ITRUE: branch 
	[reg] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, 0);
		output_branch(func, &inst, ARM_CC_NE, insn);
	}

JIT_OP_BR_IEQ: branch 
	[reg, immu8] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_EQ, insn);
	}
	[reg, reg] -> {
		arm_test_reg_reg(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_EQ, insn);
	}

JIT_OP_BR_INE: branch 
	[reg, immu8] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_NE, insn);
	}
	[reg, reg] -> {
		arm_test_reg_reg(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_NE, insn);
	}

JIT_OP_BR_ILT: branch 
	[reg, immu8] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_LT, insn);
	}
	[reg, reg] -> {
		arm_test_reg_reg(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_LT, insn);
	}

JIT_OP_BR_ILT_UN: branch 
	[reg, immu8] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_LT_UN, insn);
	}
	[reg, reg] -> {
		arm_test_reg_reg(inst, ARM_CMP, $1, $2);
		output_branch(func, &inst, ARM_CC_LT_UN, insn);
	}

JIT_OP_BR_ILE: branch 
	[reg, immu8] -> {
		arm_test_reg_imm8(inst, ARM_CMP, $1, $2);

libjit/jit/jit-rules-arm.ins  view on Meta::CPAN

		_jit_regs_spill_all(gen);
		_jit_gen_fix_value(insn->value1);
		jit_gen_load_inst_ptr(gen, inst);
		if(insn->value1->is_constant)
		{
			mov_reg_imm
				(gen, &inst, ARM_R0, ((int *)(insn->value1->address))[0]);
		}
		else
		{
			arm_load_membase(inst, ARM_R0, ARM_FP, insn->value1->frame_offset);
		}
		jump_to_epilog(gen, &inst, block);
		jit_gen_save_inst_ptr(gen, inst);
	}

JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT
		(JIT_ARM_HAS_VFP): branch 
	[freg64, clobber("r0", "r1")] -> {
		arm_mov_reg_reg_double(inst,ARM_R0,ARM_R1, $1);
		jump_to_epilog(gen, &inst, block);
	}

JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT (JIT_ARM_HAS_FPA): branch
	[freg] -> {
		if($1 != 0)
		{
			arm_alu_freg(inst, ARM_MVF, ARM_F0, $1);
		}
		jump_to_epilog(gen, &inst, block);
	}

JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
	[] -> {
		arm_inst_buf inst;
		_jit_regs_spill_all(gen);
		_jit_gen_fix_value(insn->value1);
		jit_gen_load_inst_ptr(gen, inst);
		if(insn->value1->is_constant)
		{
			mov_reg_imm
				(gen, &inst, ARM_R0, ((int *)(insn->value1->address))[0]);
			mov_reg_imm
				(gen, &inst, ARM_R1, ((int *)(insn->value1->address))[1]);
		}
		else
		{
			arm_load_membase(inst, ARM_R0, ARM_FP, insn->value1->frame_offset);
			arm_load_membase(inst, ARM_R1, ARM_FP,
							 insn->value1->frame_offset + 4);
		}
		jump_to_epilog(gen, &inst, block);
		jit_gen_save_inst_ptr(gen, inst);
	}

JIT_OP_RETURN_SMALL_STRUCT: note
	[reg, imm, clobber("r0", "r1")] -> {
		//$1: address of the struct to be returned
		//$2: size of the struct to be returned
		
		//Prevent the accidental overwriting of the address
		int temp_reg = $1;
		if(temp_reg < 3)
		{
			arm_mov_reg_reg(inst, ARM_WORK, temp_reg);
			temp_reg = ARM_WORK;
		}
		
		//Copy the struct to the return register in a way that's appropriate to its size
		switch($2)
		{
		case 1:
			arm_load_membase_byte(inst, ARM_R0, temp_reg, 0);
			break;

		case 2:
			arm_load_membase_ushort(inst, ARM_R0, temp_reg, 0);
			break;

		case 3:
			arm_load_membase_ushort(inst, ARM_R0, temp_reg, 0);
			arm_load_membase_byte(inst, ARM_R1, temp_reg, 2);
			arm_shift_reg_imm8(inst, ARM_SHL, ARM_R1, ARM_R1, 16);
			arm_alu_reg_reg(inst, ARM_ORR, ARM_R0, ARM_R0, ARM_R1);
			break;

		case 4:
			arm_load_membase(inst, ARM_R0, temp_reg, 0);
			break;

		/*TODO: is this the right way to return a struct > 4 bytes?
		* Or should it be returned by address? Look at the Procedure Call Standard!
		*/
		
		case 5:
			arm_load_membase(inst, ARM_R0, temp_reg, 0);
			arm_load_membase_byte(inst, ARM_R1, temp_reg, 4);
			break;

		case 6:
			arm_load_membase(inst, ARM_R0, temp_reg, 0);
			arm_load_membase_ushort(inst, ARM_R1, temp_reg, 4);
			break;

		case 7:
			arm_load_membase(inst, ARM_R0, temp_reg, 0);
			arm_load_membase_ushort(inst, ARM_R1, temp_reg, 4);
			arm_load_membase_byte(inst, ARM_R2, temp_reg, 6);
			arm_shift_reg_imm8(inst, ARM_SHL, ARM_R2, ARM_R2, 16);
			arm_alu_reg_reg(inst, ARM_ORR, ARM_R1, ARM_R1, ARM_R2);
			break;

		case 8:
			arm_load_membase(inst, ARM_R0, temp_reg, 0);
			arm_load_membase(inst, ARM_R1, temp_reg, 4);
			break;
		}

		jump_to_epilog(gen, &inst, block);
	}



( run in 0.789 second using v1.01-cache-2.11-cpan-524268b4103 )