Search in sources :

Example 21 with LongConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.

the class NormalizeConstants method asImmediateOrRegLong.

static Operand asImmediateOrRegLong(Operand addr, Instruction s, IR ir, boolean signed) {
    if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
        if (!canBeImmediate(((LongConstantOperand) addr).value, signed)) {
            RegisterOperand rop = ir.regpool.makeTempLong();
            s.insertBefore(Move.create(REF_MOVE, rop, addr));
            return rop.copyD2U();
        } else {
            // can be immediate --> convert to int
            return new IntConstantOperand((int) ((LongConstantOperand) addr).value);
        }
    } else if (addr instanceof ConstantOperand) {
        // must not happen
        if (VM.VerifyAssertions)
            VM._assert(VM.NOT_REACHED);
    }
    // Operand was OK as is.
    return addr;
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)

Example 22 with LongConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.

the class NormalizeConstants method asRegLong.

static Operand asRegLong(Operand addr, Instruction s, IR ir) {
    if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
        RegisterOperand rop = ir.regpool.makeTempLong();
        s.insertBefore(Move.create(REF_MOVE, rop, addr));
        return rop.copyD2U();
    } else if (addr instanceof ConstantOperand) {
        // must not happen
        if (VM.VerifyAssertions)
            VM._assert(VM.NOT_REACHED);
    }
    // Operand was OK as is.
    return addr;
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)

Example 23 with LongConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.

the class NormalizeConstants method asImmediateOrRegPolymorphic.

static Operand asImmediateOrRegPolymorphic(Operand addr, Instruction s, IR ir, boolean signed) {
    if (addr instanceof IntConstantOperand) {
        if (!canBeImmediate(((IntConstantOperand) addr).value, signed)) {
            RegisterOperand rop = ir.regpool.makeTempInt();
            s.insertBefore(Move.create(REF_MOVE, rop, addr));
            return rop.copyD2U();
        }
    } else if (addr instanceof AddressConstantOperand) {
        if (!canBeImmediate(((AddressConstantOperand) addr).value, signed)) {
            RegisterOperand rop = ir.regpool.makeTempAddress();
            s.insertBefore(Move.create(REF_MOVE, rop, addr));
            return rop.copyD2U();
        } else {
            // can be immediate --> convert to int
            return new IntConstantOperand(((AddressConstantOperand) addr).value.toInt());
        }
    } else if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
        if (!canBeImmediate(((LongConstantOperand) addr).value, signed)) {
            RegisterOperand rop = ir.regpool.makeTempLong();
            s.insertBefore(Move.create(REF_MOVE, rop, addr));
            return rop.copyD2U();
        } else {
            // can be immediate --> convert to int
            return new IntConstantOperand((int) ((LongConstantOperand) addr).value);
        }
    }
    // Operand was OK as is.
    return addr;
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)

Example 24 with LongConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method BOOLEAN_CMP_LONG.

/**
 * Expansion of BOOLEAN_CMP_LONG
 *
 * @param s the instruction to copy position info from
 * @param res the result operand
 * @param val1 the first value
 * @param val2 the second value
 * @param cond the condition operand
 */
protected final void BOOLEAN_CMP_LONG(Instruction s, RegisterOperand res, Operand val1, Operand val2, ConditionOperand cond) {
    // Can we simplify to a shift?
    if (cond.isLESS() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
        // Put the most significant bit of val1 into res
        Register val1_reg = val1.asRegister().getRegister();
        EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
        EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
    } else if (cond.isGREATER_EQUAL() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
        // Put the most significant bit of val1 into res and invert
        Register val1_reg = val1.asRegister().getRegister();
        EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
        EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
        EMIT(MIR_BinaryAcc.create(IA32_XOR, res.copyRO(), IC(1)));
    } else {
        // ==/!= : do subtract then OR 2 32-bit quantities test for zero/non-zero
        if (cond.isGREATER() || cond.isLESS_EQUAL()) {
            Operand swap_temp;
            cond.flipOperands();
            swap_temp = val1;
            val1 = val2;
            val2 = swap_temp;
        }
        if (VM.VerifyAssertions) {
            opt_assert(cond.isEQUAL() || cond.isNOT_EQUAL() || cond.isLESS() || cond.isGREATER_EQUAL());
        }
        RegisterOperand one = regpool.makeTempInt();
        RegisterOperand lone = regpool.makeTempInt();
        Operand two, ltwo;
        if (val1 instanceof RegisterOperand) {
            Register val1_reg = val1.asRegister().getRegister();
            EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, new RegisterOperand(val1_reg, TypeReference.Int))));
            EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, new RegisterOperand(regpool.getSecondReg(val1_reg), TypeReference.Int))));
        } else {
            LongConstantOperand tmp = (LongConstantOperand) val1;
            EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, IC(tmp.upper32()))));
            EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, IC(tmp.lower32()))));
        }
        if (val2 instanceof RegisterOperand) {
            two = val2;
            ((RegisterOperand) two).setType(TypeReference.Int);
            ltwo = new RegisterOperand(burs.ir.regpool.getSecondReg(val2.asRegister().getRegister()), TypeReference.Int);
        } else {
            LongConstantOperand tmp = (LongConstantOperand) val2;
            two = IC(tmp.upper32());
            ltwo = IC(tmp.lower32());
        }
        if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, lone.copyRO(), ltwo)));
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, one.copyRO(), lone.copyRO())));
        } else {
            EMIT(CPOS(s, MIR_Compare.create(IA32_CMP, lone.copyRO(), ltwo)));
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
        }
        RegisterOperand temp = regpool.makeTemp(TypeReference.Boolean);
        EMIT(CPOS(s, MIR_Set.create(IA32_SET__B, temp, COND(cond))));
        EMIT(MIR_Unary.mutate(s, IA32_MOVZX__B, res, temp.copyRO()));
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)

Example 25 with LongConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method LONG_MUL.

/**
 * Expansion of LONG_MUL
 *
 * @param s the instruction to expand
 * @param result the result operand
 * @param value1 the first operand
 * @param value2 the second operand
 */
protected final void LONG_MUL(Instruction s, RegisterOperand result, Operand value1, Operand value2) {
    if (value2.isRegister()) {
        // a branch
        if (VM.VerifyAssertions)
            opt_assert(Binary.getResult(s).similar(result) && Binary.getVal1(s).similar(value1) && Binary.getVal2(s).similar(value2));
        EMIT(s);
    } else {
        // register in the case of multiplication with a constant
        if ((value2.similar(result)) || value1.isLongConstant()) {
            Operand temp = value1;
            value1 = value2;
            value2 = temp;
        }
        if (VM.VerifyAssertions)
            opt_assert(value1.isRegister() && value2.isLongConstant());
        // In general, (a,b) * (c,d) = (l(a imul d)+l(b imul c)+u(b mul d), l(b mul d))
        Register lhsReg = result.getRegister();
        Register lowlhsReg = regpool.getSecondReg(lhsReg);
        LongConstantOperand rhs2 = (LongConstantOperand) value2;
        // a
        Register rhsReg1 = value1.asRegister().getRegister();
        // b
        Register lowrhsReg1 = regpool.getSecondReg(rhsReg1);
        // c
        int high2 = rhs2.upper32();
        // d
        int low2 = rhs2.lower32();
        // (where * is something other than -1,0,1)
        if (high2 == -1) {
            if (low2 == 0) {
                // CLAIM: (a,b) * (-1,0) = (-b,0)
                if (VM.VerifyAssertions)
                    opt_assert(lhsReg != lowrhsReg1);
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lhsReg, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
            } else if (low2 == 1) {
                // CLAIM: (a,b) * (-1,1) = (a-b,b)
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowlhsReg, TypeReference.Int))));
            } else {
                // CLAIM: (a,b) * (-1, d) = (l(a imul d)-b+u(b mul d), l(b mul d))
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
            }
        } else if (high2 == 0) {
            if (low2 == -1) {
                // 0, -1
                // CLAIM: (a,b) * (0,-1) = (b-(a+(b!=0?1:0)),-b)
                // avoid clobbering a and b by using tmp
                Register tmp = regpool.getInteger();
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
            } else {
                // CLAIM: (a,b) * (0,d) = (l(a imul d)+u(b mul d), l(b mul d))
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
            }
        } else if (high2 == 1) {
            if (low2 == -1) {
                // 1, -1
                // CLAIM: (a,b) * (1,-1) = (2b-(a+(b!=0?1:0)),-b)
                // avoid clobbering a and b by using tmp
                Register tmp = regpool.getInteger();
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
                EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
            } else if (low2 == 0) {
                // 1, 0
                // CLAIM: (x,y) * (1,0) = (y,0)
                // NB we should have simplified this LONG_MUL to a LONG_SHIFT
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
            } else if (low2 == 1) {
                // NB we should have simplified this LONG_MUL to a LONG_SHIFT and LONG_ADDs
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowlhsReg, TypeReference.Int))));
            } else {
                // CLAIM: (a,b) * (1,d) = (l(a imul d)+b+u(b mul d), l(b mul d))
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
            }
        } else {
            if (low2 == -1) {
                // *, -1
                // CLAIM: (a,b) * (c, -1) = ((b+1)*c - (a + b==0?1:0), -b)
                // avoid clobbering a and b by using tmp
                Register tmp = regpool.getInteger();
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(tmp, TypeReference.Int), IC(1))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
                EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
            } else if (low2 == 0) {
                // *, 0
                // CLAIM: (a,b) * (c,0) = (l(b imul c),0)
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(high2))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
            } else if (low2 == 1) {
                // CLAIM: (x,y) * (z,1) = (l(y imul z)+x,y)
                if (lowlhsReg != lowrhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                }
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                Register tmp = regpool.getInteger();
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
                EMIT(CPOS(s, MIR_Move.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
            } else {
                // (a,b) * (c,d) = (l(a imul d)+l(b imul c)+u(b mul d), l(b mul d))
                if (lhsReg != rhsReg1) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
                Register tmp = regpool.getInteger();
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
                EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
            }
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint)

Aggregations

LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)32 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)29 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)27 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)19 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)19 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)18 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)16 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)15 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)14 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)14 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)13 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)13 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)12 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)12 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)12 InlinedOsrTypeInfoOperand (org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand)11 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)11 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)9