Search in sources :

Example 1 with LongConstantOperand

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

the class BURS_Helpers method TRAP_IF_IMM.

/**
 * Take the generic LIR trap_if and coerce into the limited
 * vocabulary understood by the C trap handler on PPC.  See
 * TrapConstants.java.  Also see ConvertToLowLevelIR.java
 * which generates most of these TRAP_IFs.
 *
 * @param s the instruction to expand
 * @param longConstant is the argument a long constant?
 */
protected final void TRAP_IF_IMM(Instruction s, boolean longConstant) {
    RegisterOperand gRes = TrapIf.getClearGuardResult(s);
    RegisterOperand v1 = (RegisterOperand) TrapIf.getClearVal1(s);
    ConditionOperand cond = TrapIf.getClearCond(s);
    TrapCodeOperand tc = TrapIf.getClearTCode(s);
    switch(tc.getTrapCode()) {
        case RuntimeEntrypoints.TRAP_ARRAY_BOUNDS:
            {
                IntConstantOperand v2 = (IntConstantOperand) TrapIf.getClearVal2(s);
                if (cond.isLOWER_EQUAL()) {
                    EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, new PowerPCTrapOperand(cond), v1, v2, tc));
                } else if (cond.isHIGHER_EQUAL()) {
                    // have flip the operands and use non-immediate so trap handler can recognize.
                    RegisterOperand tmp = regpool.makeTempInt();
                    IntConstant(tmp.getRegister(), v2.value);
                    EMIT(MIR_Trap.mutate(s, PPC_TW, gRes, new PowerPCTrapOperand(cond.flipOperands()), tmp, v1, tc));
                } else {
                    throw new OptimizingCompilerException("Unexpected case of trap_if" + s);
                }
            }
            break;
        case RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO:
            {
                ConstantOperand v2 = (ConstantOperand) TrapIf.getClearVal2(s);
                if (VM.VerifyAssertions) {
                    if (longConstant) {
                        long val = ((LongConstantOperand) v2).value;
                        boolean caseMatchesExpected = val == 0L && cond.isEQUAL();
                        if (!caseMatchesExpected) {
                            String msg = "Unexpected case of trap_if" + s;
                            VM._assert(VM.NOT_REACHED, msg);
                        }
                    } else {
                        int val = ((IntConstantOperand) v2).value;
                        boolean caseMatchesExpected = val == 0L && cond.isEQUAL();
                        if (!caseMatchesExpected) {
                            String msg = "Unexpected case of trap_if" + s;
                            VM._assert(VM.NOT_REACHED, msg);
                        }
                    }
                }
                if (longConstant) {
                    if (VM.BuildFor32Addr) {
                        // A slightly ugly matter, but we need to deal with combining
                        // the two pieces of a long register from a LONG_ZERO_CHECK.
                        // A little awkward, but probably the easiest workaround...
                        RegisterOperand rr = regpool.makeTempInt();
                        EMIT(MIR_Binary.create(PPC_OR, rr, v1, I(regpool.getSecondReg(v1.getRegister()))));
                        v1 = rr.copyD2U();
                        v2 = IC(0);
                        EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, new PowerPCTrapOperand(cond), v1, v2, tc));
                    } else {
                        EMIT(MIR_Trap.mutate(s, PPC64_TDI, gRes, new PowerPCTrapOperand(cond), v1, v2, tc));
                    }
                } else {
                    EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, new PowerPCTrapOperand(cond), v1, v2, tc));
                }
            }
            break;
        default:
            throw new OptimizingCompilerException("Unexpected case of trap_if" + s);
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) PowerPCTrapOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCTrapOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 2 with LongConstantOperand

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

the class NormalizeConstants method perform.

/**
 * Doit.
 *
 * @param ir IR to normalize
 */
public static void perform(IR ir) {
    // This greatly reduces the number of cases we have to worry about below.
    if (VM.VerifyAssertions)
        VM._assert(ir.options.SIMPLIFY_INTEGER_OPS && ir.options.SIMPLIFY_LONG_OPS && ir.options.SIMPLIFY_REF_OPS);
    for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
        // STEP ONE: Get 'large' constants into a form that the PPC BURS rules
        // are prepared to deal with.
        // Constants can't appear as defs, so only scan the uses.
        // 
        int numUses = s.getNumberOfUses();
        if (numUses > 0) {
            int numDefs = s.getNumberOfDefs();
            for (int idx = numDefs; idx < numUses + numDefs; idx++) {
                Operand use = s.getOperand(idx);
                if (use != null) {
                    if (use instanceof ObjectConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(use.getType());
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        ObjectConstantOperand oc = (ObjectConstantOperand) use;
                        Offset offset = oc.offset;
                        if (offset.isZero()) {
                            if (use instanceof StringConstantOperand) {
                                throw new OptimizingCompilerException("String constant w/o valid JTOC offset");
                            } else if (use instanceof ClassConstantOperand) {
                                throw new OptimizingCompilerException("Class constant w/o valid JTOC offset");
                            }
                            offset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(oc.value));
                        }
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof DoubleConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        DoubleConstantOperand dc = (DoubleConstantOperand) use;
                        Offset offset = dc.offset;
                        if (offset.isZero()) {
                            offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
                        }
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(DOUBLE_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof FloatConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        FloatConstantOperand fc = (FloatConstantOperand) use;
                        Offset offset = fc.offset;
                        if (offset.isZero()) {
                            offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
                        }
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(FLOAT_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof LongConstantOperand) {
                        if (!VM.BuildFor64Addr) {
                            if (s.getOpcode() != TRAP_IF_opcode) {
                                RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Long);
                                s.insertBefore(Move.create(LONG_MOVE, rop, use.copy()));
                                s.putOperand(idx, rop.copyD2U());
                            }
                        }
                    } else if (use instanceof NullConstantOperand) {
                        s.putOperand(idx, AC(Address.zero()));
                    } else if (use instanceof TIBConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.JavaLangObjectArray);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof CodeConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.CodeArray);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        Offset offset = ((CodeConstantOperand) use).value.findOrCreateJtocOffset();
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    }
                }
            }
        }
        // Calling Simplifier.simplify ensures that the instruction is
        // in normalized form. This reduces the number of cases we have to
        // worry about (and does last minute constant folding on the off chance
        // we've missed an opportunity...)
        Simplifier.simplify(false, ir.regpool, ir.options, s);
        switch(s.getOpcode()) {
            // ////////
            case REF_STORE_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_STORE : LONG_STORE);
                // On PowerPC, the value being stored must be in a register
                Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case BYTE_STORE_opcode:
            case SHORT_STORE_opcode:
            case INT_STORE_opcode:
            case LONG_STORE_opcode:
                // On PowerPC, the value being stored must be in a register
                Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case FLOAT_STORE_opcode:
            case DOUBLE_STORE_opcode:
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case REF_LOAD_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD);
                // Supported addressing modes are quite limited.
                Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
                Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
                break;
            case BYTE_LOAD_opcode:
            case UBYTE_LOAD_opcode:
            case SHORT_LOAD_opcode:
            case USHORT_LOAD_opcode:
            case INT_LOAD_opcode:
            case LONG_LOAD_opcode:
            case FLOAT_LOAD_opcode:
            case DOUBLE_LOAD_opcode:
                // Supported addressing modes are quite limited.
                Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
                Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
                break;
            case ATTEMPT_INT_opcode:
            case ATTEMPT_LONG_opcode:
            case ATTEMPT_ADDR_opcode:
                // On PowerPC, the value being stored must be in a register
                Attempt.setNewValue(s, asRegPolymorphic(Attempt.getClearNewValue(s), s, ir));
                // not used on powerpc.
                Attempt.setOldValue(s, null);
                // Supported addressing modes are quite limited.
                Attempt.setAddress(s, asRegAddress(Attempt.getClearAddress(s), s, ir));
                Attempt.setOffset(s, asRegOffset(Attempt.getClearOffset(s), s, ir));
                break;
            case PREPARE_INT_opcode:
            case PREPARE_LONG_opcode:
            case PREPARE_ADDR_opcode:
                // Supported addressing modes are quite limited.
                Prepare.setAddress(s, asRegAddress(Prepare.getClearAddress(s), s, ir));
                Prepare.setOffset(s, asRegOffset(Prepare.getClearOffset(s), s, ir));
                break;
            case LONG_MOVE_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_MOVE);
                }
                break;
            case INT_MOVE_opcode:
                s.changeOperatorTo(REF_MOVE);
                break;
            case REF_COND_MOVE_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_COND_MOVE : LONG_COND_MOVE);
                break;
            case REF_IFCMP_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_IFCMP : LONG_IFCMP);
                // val1 can't be a constant, val2 must be small enough.
                IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
            case LONG_IFCMP_opcode:
                if (VM.BuildFor64Addr) {
                    // val1 can't be a constant, val2 must be small enough.
                    IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                    IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
                }
                break;
            case INT_IFCMP_opcode:
                // val1 can't be a constant, val2 must be small enough.
                IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
                break;
            case INT_IFCMP2_opcode:
                // val1 can't be a constant, val2 must be small enough.
                IfCmp2.setVal1(s, asRegInt(IfCmp2.getClearVal1(s), s, ir));
                IfCmp2.setVal2(s, asImmediateOrRegInt(IfCmp2.getClearVal2(s), s, ir, true));
                break;
            case BOOLEAN_CMP_INT_opcode:
            case BOOLEAN_CMP_ADDR_opcode:
                // val2 must be small enough.
                BooleanCmp.setVal2(s, asImmediateOrRegPolymorphic(BooleanCmp.getClearVal2(s), s, ir, !BooleanCmp.getCond(s).isUNSIGNED()));
                break;
            case LONG_CMP_opcode:
                Binary.setVal1(s, asRegPolymorphic(Binary.getVal1(s), s, ir));
                Binary.setVal2(s, asRegPolymorphic(Binary.getVal2(s), s, ir));
                break;
            case LONG_ADD_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_ADD);
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                }
                break;
            case INT_ADD_opcode:
                s.changeOperatorTo(REF_ADD);
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                break;
            case REF_ADD_opcode:
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                break;
            case LONG_SUB_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_SUB);
                    Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // val2 isn't be constant (if it were, Simplifier would have
                // converted this into an ADD of -Val2).
                }
                break;
            case INT_SUB_opcode:
                s.changeOperatorTo(REF_SUB);
                Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // converted this into an ADD of -Val2).
                break;
            case REF_SUB_opcode:
                Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // converted this into an ADD of -Val2).
                break;
            case INT_MUL_opcode:
                Binary.setVal2(s, asImmediateOrRegInt(Binary.getClearVal2(s), s, ir, true));
                break;
            case LONG_MUL_opcode:
                if (VM.BuildFor64Addr) {
                    Binary.setVal2(s, asImmediateOrRegLong(Binary.getClearVal2(s), s, ir, true));
                }
                break;
            // seem to expect constant operands at all.
            case INT_REM_opcode:
            case INT_DIV_opcode:
                GuardedBinary.setVal1(s, asRegInt(GuardedBinary.getClearVal1(s), s, ir));
                GuardedBinary.setVal2(s, asRegInt(GuardedBinary.getClearVal2(s), s, ir));
                break;
            case LONG_REM_opcode:
            case LONG_DIV_opcode:
                if (VM.BuildFor64Addr) {
                    GuardedBinary.setVal1(s, asRegLong(GuardedBinary.getClearVal1(s), s, ir));
                    GuardedBinary.setVal2(s, asRegLong(GuardedBinary.getClearVal2(s), s, ir));
                }
                break;
            case LONG_NEG_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_NEG);
                }
                break;
            case INT_NEG_opcode:
                s.changeOperatorTo(REF_NEG);
                break;
            case LONG_NOT_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_NOT);
                }
                break;
            case INT_NOT_opcode:
                s.changeOperatorTo(REF_NOT);
                break;
            case LONG_AND_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_AND);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_AND_opcode:
                s.changeOperatorTo(REF_AND);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_AND_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case LONG_OR_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_OR);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_OR_opcode:
                s.changeOperatorTo(REF_OR);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_OR_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case LONG_XOR_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_XOR);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_XOR_opcode:
                s.changeOperatorTo(REF_XOR);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_XOR_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_SHL_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHL : LONG_SHL);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_SHL_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_SHL_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case REF_SHR_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHR : LONG_SHR);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_SHR_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_SHR_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case REF_USHR_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_USHR : LONG_USHR);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_USHR_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_USHR_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            // Deal with Simplifier.CF_FLOAT or Simplifier.CF_DOUBLE being false
            case INT_2DOUBLE_opcode:
            case INT_2FLOAT_opcode:
            case INT_BITS_AS_FLOAT_opcode:
                Unary.setVal(s, asRegInt(Unary.getVal(s), s, ir));
                break;
            case ADDR_2INT_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : LONG_2INT);
                break;
            case ADDR_2LONG_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_2LONG : REF_MOVE);
                break;
            case INT_2ADDRSigExt_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : INT_2LONG);
                break;
            case INT_2ADDRZerExt_opcode:
                if (VM.BuildFor32Addr) {
                    s.changeOperatorTo(REF_MOVE);
                }
                break;
            case LONG_2ADDR_opcode:
                s.changeOperatorTo(VM.BuildFor64Addr ? REF_MOVE : LONG_2INT);
                break;
            case NULL_CHECK_opcode:
                NullCheck.setRef(s, asRegAddress(NullCheck.getClearRef(s), s, ir));
                break;
            // Force all call parameters to be in registers
            case SYSCALL_opcode:
            case CALL_opcode:
                {
                    int numArgs = Call.getNumberOfParams(s);
                    for (int i = 0; i < numArgs; i++) {
                        Call.setParam(s, i, asRegPolymorphic(Call.getClearParam(s, i), s, ir));
                    }
                }
                break;
            case RETURN_opcode:
                if (Return.hasVal(s)) {
                    Return.setVal(s, asRegPolymorphic(Return.getClearVal(s), s, ir));
                }
                break;
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Offset(org.vmmagic.unboxed.Offset) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)

Example 3 with LongConstantOperand

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

the class BURS_Helpers method TRAP_IF_IMM.

/**
 * Expansion of TRAP_IF, with an int constant as the second value.
 *
 * @param s the instruction to expand
 * @param longConstant is the argument a long constant?
 */
protected final void TRAP_IF_IMM(Instruction s, boolean longConstant) {
    RegisterOperand gRes = TrapIf.getGuardResult(s);
    RegisterOperand v1 = (RegisterOperand) TrapIf.getVal1(s);
    ConstantOperand v2 = (ConstantOperand) TrapIf.getVal2(s);
    ConditionOperand cond = TrapIf.getCond(s);
    TrapCodeOperand tc = TrapIf.getTCode(s);
    // A little awkward, but probably the easiest workaround...
    if (VM.BuildFor32Addr && longConstant) {
        if (VM.VerifyAssertions) {
            opt_assert((tc.getTrapCode() == RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO) && (((LongConstantOperand) v2).value == 0L));
        }
        RegisterOperand vr = v1.copyRO();
        vr.setType(TypeReference.Int);
        RegisterOperand rr = regpool.makeTempInt();
        EMIT(CPOS(s, MIR_Move.create(IA32_MOV, rr, vr)));
        EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, rr.copy(), new RegisterOperand(regpool.getSecondReg(v1.getRegister()), TypeReference.Int))));
        v1 = rr.copyD2U();
        v2 = IC(0);
    }
    // emit the trap instruction
    EMIT(MIR_TrapIf.mutate(s, IA32_TRAPIF, gRes, v1, v2, COND(cond), tc));
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)

Example 4 with LongConstantOperand

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

the class ComplexLIR2MIRExpansion method process64BitImmediateValues.

public static void process64BitImmediateValues(IR ir) {
    for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
        char opcode = s.getOpcode();
        if (opcode == IMMQ_MOV_opcode)
            continue;
        if (MIR_Move.conforms(s)) {
            Operand moveResult = MIR_Move.getResult(s);
            if (opcode == IA32_MOV_opcode && moveResult.isRegister()) {
                Operand value = MIR_Move.getValue(s);
                if (value.isLongConstant()) {
                    LongConstantOperand lc = (LongConstantOperand) value;
                    if (!Bits.fits(lc.value, 32)) {
                        MIR_Move.mutate(s, IMMQ_MOV, moveResult, value);
                        continue;
                    }
                }
            }
        }
        for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
            Operand op = ops.nextElement();
            if (op.isLongConstant()) {
                LongConstantOperand lc = (LongConstantOperand) op;
                if (!Bits.fits(lc.value, 32)) {
                    RegisterOperand temp = ir.regpool.makeTempLong();
                    if (lc.convertedFromRef()) {
                        temp.flagAsConvertedFromRef();
                    }
                    s.insertBefore(MIR_Move.create(IMMQ_MOV, temp, lc.copy()));
                    s.replaceOperand(lc, temp.copyD2U());
                }
            }
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 5 with LongConstantOperand

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

the class ComplexLIR2MIRExpansion method long_ifcmp_imm.

private static Instruction long_ifcmp_imm(Instruction s, IR ir) {
    Instruction nextInstr = s.nextInstructionInCodeOrder();
    ConditionOperand cond = IfCmp.getCond(s);
    Register xh = ((RegisterOperand) IfCmp.getVal1(s)).getRegister();
    Register xl = ir.regpool.getSecondReg(xh);
    LongConstantOperand rhs = (LongConstantOperand) IfCmp.getVal2(s);
    int low = rhs.lower32();
    int high = rhs.upper32();
    IntConstantOperand yh = IC(high);
    IntConstantOperand yl = IC(low);
    if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
        // tricky... ((xh^yh)|(xl^yl) == 0) <==> (lhll == rhrl)!!
        Register th = ir.regpool.getInteger();
        Register tl = ir.regpool.getInteger();
        if (high == 0) {
            if (low == 0) {
                // 0,0
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
            } else if (low == -1) {
                // 0,-1
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(tl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
            } else {
                // 0,*
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(tl, TypeReference.Int), yl));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
            }
        } else if (high == -1) {
            if (low == 0) {
                // -1,0
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(th, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
            } else if (low == -1) {
                // -1,-1
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(th, TypeReference.Int)));
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(tl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(tl, TypeReference.Int)));
            } else {
                // -1,*
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(th, TypeReference.Int)));
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(tl, TypeReference.Int), yl));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(tl, TypeReference.Int)));
            }
        } else {
            if (low == 0) {
                // *,0
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(th, TypeReference.Int), yh));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
            } else if (low == -1) {
                // *,-1
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(th, TypeReference.Int), yh));
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, new RegisterOperand(tl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(tl, TypeReference.Int)));
            } else {
                // neither high nor low is special
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(xh, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(th, TypeReference.Int), yh));
                s.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(tl, TypeReference.Int), new RegisterOperand(xl, TypeReference.Int)));
                s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new RegisterOperand(tl, TypeReference.Int), yl));
                s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(th, TypeReference.Int), new RegisterOperand(tl, TypeReference.Int)));
            }
        }
        MIR_CondBranch.mutate(s, IA32_JCC, new IA32ConditionOperand(cond), IfCmp.getTarget(s), IfCmp.getBranchProfile(s));
        return nextInstr;
    } else {
        // pick up a few special cases where the sign of xh is sufficient
        if (rhs.value == 0L) {
            if (cond.isLESS()) {
                // xh < 0 implies true
                s.insertBefore(MIR_Compare.create(IA32_CMP, new RegisterOperand(xh, TypeReference.Int), IC(0)));
                MIR_CondBranch.mutate(s, IA32_JCC, IA32ConditionOperand.LT(), IfCmp.getTarget(s), IfCmp.getBranchProfile(s));
                return nextInstr;
            } else if (cond.isGREATER_EQUAL()) {
                s.insertBefore(MIR_Compare.create(IA32_CMP, new RegisterOperand(xh, TypeReference.Int), IC(0)));
                MIR_CondBranch.mutate(s, IA32_JCC, IA32ConditionOperand.GE(), IfCmp.getTarget(s), IfCmp.getBranchProfile(s));
                return nextInstr;
            }
        } else if (rhs.value == -1L) {
            if (cond.isLESS_EQUAL()) {
                s.insertBefore(MIR_Compare.create(IA32_CMP, new RegisterOperand(xh, TypeReference.Int), IC(-1)));
                MIR_CondBranch.mutate(s, IA32_JCC, IA32ConditionOperand.LE(), IfCmp.getTarget(s), IfCmp.getBranchProfile(s));
                return nextInstr;
            } else if (cond.isGREATER()) {
                s.insertBefore(MIR_Compare.create(IA32_CMP, new RegisterOperand(xh, TypeReference.Int), IC(0)));
                MIR_CondBranch.mutate(s, IA32_JCC, IA32ConditionOperand.GE(), IfCmp.getTarget(s), IfCmp.getBranchProfile(s));
                return nextInstr;
            }
        }
        basic_long_ifcmp(s, ir, cond, xh, xl, yh, yl);
        return nextInstr;
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Register(org.jikesrvm.compilers.opt.ir.Register) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)

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