Alien-LibJIT

 view release on metacpan or  search on metacpan

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

/*
 * jit-rules-x86.ins - Instruction selector for x86.
 *
 * Copyright (C) 2004  Southern Storm Software, Pty Ltd.
 *
 * This file is part of the libjit library.
 *
 * The libjit library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * The libjit library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the libjit library.  If not, see
 * <http://www.gnu.org/licenses/>.
 */
 
%regclass reg x86_reg
%regclass breg x86_breg
%regclass freg x86_freg
%lregclass lreg x86_lreg

/*
 * Conversion opcodes.
 */

JIT_OP_TRUNC_SBYTE:
	[=reg, breg] -> {
		x86_widen_reg(inst, $1, $2, 1, 0);
	}

JIT_OP_TRUNC_UBYTE:
	[=reg, breg] -> {
		x86_widen_reg(inst, $1, $2, 0, 0);
	}

JIT_OP_TRUNC_SHORT:
	[=reg, reg] -> {
		x86_widen_reg(inst, $1, $2, 1, 1);
	}

JIT_OP_TRUNC_USHORT:
	[=reg, reg] -> {
		x86_widen_reg(inst, $1, $2, 0, 1);
	}

JIT_OP_CHECK_SBYTE: more_space
	[reg] -> {
		unsigned char *patch1;
		unsigned char *patch2;
		x86_alu_reg_imm(inst, X86_CMP, $1, -128);
		patch1 = inst;
		x86_branch8(inst, X86_CC_LE, 0, 1);
		x86_alu_reg_imm(inst, X86_CMP, $1, 127);
		patch2 = inst;
		x86_branch8(inst, X86_CC_LE, 0, 1);
		x86_patch(patch1, inst);

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

			x86_alu_reg_imm(inst, X86_ADD, $1, value1);
			x86_alu_reg_imm(inst, X86_ADC, %1, value2);
		}
		else
		{
			x86_alu_reg_imm(inst, X86_ADD, %1, value2);
		}
	}
	[lreg, local] -> {
		x86_alu_reg_membase(inst, X86_ADD, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_ADC, %1, X86_EBP, $2 + 4);
	}
	[lreg, lreg] -> {
		x86_alu_reg_reg(inst, X86_ADD, $1, $2);
		x86_alu_reg_reg(inst, X86_ADC, %1, %2);
	}

JIT_OP_LSUB:
	[lreg, imm] -> {
		jit_int value1 = ((jit_int *)($2))[0];
		jit_int value2 = ((jit_int *)($2))[1];
		if(value1 != 0)
		{
			x86_alu_reg_imm(inst, X86_SUB, $1, value1);
			x86_alu_reg_imm(inst, X86_SBB, %1, value2);
		}
		else
		{
			x86_alu_reg_imm(inst, X86_SUB, %1, value2);
		}
	}
	[lreg, local] -> {
		x86_alu_reg_membase(inst, X86_SUB, $1, X86_EBP, $2);
		x86_alu_reg_membase(inst, X86_SBB, %1, X86_EBP, $2 + 4);
	}
	[lreg, lreg] -> {
		x86_alu_reg_reg(inst, X86_SUB, $1, $2);
		x86_alu_reg_reg(inst, X86_SBB, %1, %2);
	}

JIT_OP_LNEG:
	[lreg] -> {
		/* TODO: gcc generates the first variant while
		   AoA suggests the second. Figure out if one
		   is better than other. */
#if 1
		x86_neg_reg(inst, $1);
		x86_alu_reg_imm(inst, X86_ADC, %1, 0);
		x86_neg_reg(inst, %1);
#else
		x86_neg_reg(inst, %1);
		x86_neg_reg(inst, $1);
		x86_alu_reg_imm(inst, X86_SBB, %1, 0);
#endif
	}

JIT_OP_FADD, JIT_OP_DADD, JIT_OP_NFADD: stack, x87_arith, commutative
	[freg, freg] -> {
		int flags;

		flags = _jit_regs_select(&regs);

		if((flags & _JIT_REGS_NO_POP) == 0)
		{
			x86_fp_op_reg(inst, X86_FADD,
				fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1);
		}
		else if((flags & _JIT_REGS_FLIP_ARGS) != 0)
		{
			x86_fp_op_reg(inst, X86_FADD,
				fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0);
		}
		else
		{
			x86_fp_op(inst, X86_FADD,
				fp_stack_index(gen, $2 + JIT_REG_STACK_START));
		}
	}

JIT_OP_FSUB, JIT_OP_DSUB, JIT_OP_NFSUB: stack, x87_arith_reversible
	[freg, freg] -> {
		int flags;

		flags = _jit_regs_select(&regs);

		if((flags & _JIT_REGS_NO_POP) == 0)
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op_reg(inst, X86_FSUB,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1);
			}
			else
			{
				x86_fp_op_reg(inst, X86_FSUBR,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START), 1);
			}
		}
		else if((flags & _JIT_REGS_FLIP_ARGS) != 0)
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op_reg(inst, X86_FSUB,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0);
			}
			else
			{
				x86_fp_op(inst, X86_FSUBR,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START));
			}
		}
		else
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op(inst, X86_FSUB,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START));
			}
			else
			{
				x86_fp_op_reg(inst, X86_FSUBR,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START), 0);
			}
		}
	}

JIT_OP_FMUL, JIT_OP_DMUL, JIT_OP_NFMUL: stack, x87_arith, commutative
	[freg, freg] -> {
		int flags;

		flags = _jit_regs_select(&regs);

		if((flags & _JIT_REGS_NO_POP) == 0)
		{
			x86_fp_op_reg(inst, X86_FMUL, fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1);
		}
		else if((flags & _JIT_REGS_FLIP_ARGS) != 0)
		{
			x86_fp_op_reg(inst, X86_FMUL, fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0);
		}
		else
		{
			x86_fp_op(inst, X86_FMUL, fp_stack_index(gen, $2 + JIT_REG_STACK_START));
		}
	}

JIT_OP_FDIV, JIT_OP_DDIV, JIT_OP_NFDIV: stack, x87_arith_reversible
	[freg, freg] -> {
		int flags;

		flags = _jit_regs_select(&regs);

		if((flags & _JIT_REGS_NO_POP) == 0)
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op_reg(inst, X86_FDIV,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START), 1);
			}
			else
			{
				x86_fp_op_reg(inst, X86_FDIVR,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START), 1);
			}
		}
		else if((flags & _JIT_REGS_FLIP_ARGS) != 0)
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op_reg(inst, X86_FDIV,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START), 0);
			}
			else
			{
				x86_fp_op(inst, X86_FDIVR,
					fp_stack_index(gen, $1 + JIT_REG_STACK_START));
			}
		}
		else
		{
			if((flags & _JIT_REGS_REVERSE) == 0)
			{
				x86_fp_op(inst, X86_FDIV,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START));
			}
			else
			{
				x86_fp_op_reg(inst, X86_FDIVR,
					fp_stack_index(gen, $2 + JIT_REG_STACK_START), 0);
			}
		}
	}

JIT_OP_FREM, JIT_OP_DREM, JIT_OP_NFREM: stack
	[freg, freg, scratch reg("eax")] -> {
		unsigned char *label;
		label = inst;
		x86_fprem(inst);
		x86_fnstsw(inst);
		x86_alu_reg_imm(inst, X86_AND, X86_EAX, 0x0400);
		x86_branch(inst, X86_CC_NZ, label, 0);
		x86_fstp(inst, 1);
	}

JIT_OP_FNEG, JIT_OP_DNEG, JIT_OP_NFNEG: stack
	[freg] -> {
		x86_fchs(inst);
	}

/*
 * Bitwise opcodes.



( run in 0.745 second using v1.01-cache-2.11-cpan-d0baa829c65 )