Search in sources :

Example 6 with ConditionOperand

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

the class BranchOptimizations method generateCondMove.

/**
 * Attempt to generate a straight-line sequence using conditional move
 * instructions, to replace a diamond control flow structure.
 *
 * <p>Suppose we have the following code, where e{n} is an expression:
 * <pre>
 * if (a op b) {
 *   x = e2;
 *   y = e3;
 * } else {
 *   z = e4;
 *   x = e5;
 * }
 * </pre>
 * We would transform this to:
 * <pre>
 * t1 = a;
 * t2 = b;
 * t3 = e2;
 * t4 = e3;
 * t5 = e4;
 * t6 = e5;
 * COND MOVE [if (t1 op t2) x := t3 else x := t6 ];
 * COND MOVE [if (t1 op t2) y := t4 else y := y];
 * COND MOVE [if (t1 op t2) z := z  else z := t5];
 * </pre>
 *
 * <p>Note that we rely on other optimizations (eg. copy propagation) to
 * clean up some of this unnecessary mess.
 *
 * <p>Note that in this example, we've increased the shortest path by 2
 * expression evaluations, 2 moves, and 3 cond moves, but eliminated one
 * conditional branch.
 *
 * <p>We apply a cost heuristic to guide this transformation:
 * We will eliminate a conditional branch iff it increases the shortest
 * path by no more than 'k' operations.  Currently, we count each
 * instruction (alu, move, or cond move) as 1 evaluation.
 * The parameter k is specified by OPT\_Options.COND_MOVE_CUTOFF.
 *
 * <p> In the example above, since we've increased the shortest path by
 * 6 instructions, we will only perform the transformation if {@code k >= 7}.
 *
 * <p> TODO items
 * <ul>
 * <li> consider smarter cost heuristics
 * <li> enhance downstream code generation to avoid redundant evaluation
 * of condition codes.
 * </ul>
 *
 * @param ir governing IR
 * @param bb basic block of cb
 * @param cb conditional branch instruction
 * @return true if the transformation succeeds, false otherwise
 */
private boolean generateCondMove(IR ir, BasicBlock bb, Instruction cb) {
    final boolean VERBOSE = false;
    if (!VM.BuildForIA32)
        return false;
    if (!IfCmp.conforms(cb))
        return false;
    if (VERBOSE)
        System.out.println("CondMove: Looking to optimize " + cb);
    // Don't generate CMOVs for branches that can be folded.
    if (IfCmp.getVal1(cb).isConstant() && IfCmp.getVal2(cb).isConstant()) {
        if (VERBOSE)
            System.out.println("CondMove: fail - could be folded");
        return false;
    }
    // see if bb is the root of an if-then-else.
    Diamond diamond = Diamond.buildDiamond(bb);
    if (diamond == null) {
        if (VERBOSE)
            System.out.println("CondMove: fail - no diamond");
        return false;
    }
    BasicBlock taken = diamond.getTaken();
    BasicBlock notTaken = diamond.getNotTaken();
    // has a taboo instruction (eg., a PEI, store or divide).
    if (taken != null && hasCMTaboo(taken)) {
        if (VERBOSE)
            System.out.println("CondMove: fail - taken branch has taboo instruction");
        return false;
    }
    if (notTaken != null && hasCMTaboo(notTaken)) {
        if (VERBOSE)
            System.out.println("CondMove: fail - not taken branch has taboo instruction");
        return false;
    }
    ConditionOperand cond = IfCmp.getCond(cb);
    // Do not generate when we don't know the branch probability or
    // when branch probability is high. CMOVs reduce performance of
    // the out-of-order engine (Intel Optimization Guide -
    // Assembly/Compiler Coding Rule 2).
    // Ignore in the case of an abs() method as we can create tighter
    // instructions.
    BranchProfileOperand profile = IfCmp.getBranchProfile(cb);
    if ((Math.abs(profile.takenProbability - 0.5) >= ir.options.CONTROL_WELL_PREDICTED_CUTOFF) && !(cb.position() != null && cb.position().method.getName() == ABS && cond.isFLOATINGPOINT())) {
        if (VERBOSE)
            System.out.println("CondMove: fail - branch could be well predicted by branch predictor: " + profile.takenProbability);
        return false;
    }
    // if we must generate FCMP, make sure the condition code is OK
    if (cond.isFLOATINGPOINT()) {
        if (!fpConditionOK(cond)) {
            // Condition not OK, but maybe if we flip the operands
            if (!fpConditionOK(cond.flipOperands())) {
                // still not ok so flip operands back
                cond.flipOperands();
                // controlling just floating point moves
                if (!VM.BuildForSSE2Full || hasFloatingPointDef(taken, true) || hasFloatingPointDef(notTaken, true)) {
                    if (VERBOSE)
                        System.out.println("CondMove: fail - fp condition not OK: " + cond);
                    return false;
                }
            } else {
                // flip operands
                Operand val1 = IfCmp.getVal1(cb);
                Operand val2 = IfCmp.getVal2(cb);
                IfCmp.setVal1(cb, val2);
                IfCmp.setVal2(cb, val1);
            }
        }
    }
    if (!cond.isFLOATINGPOINT()) {
        // compares or for unsigned compares in x87
        if (VM.BuildForSSE2Full || !cond.isUNSIGNED()) {
            if (hasFloatingPointDef(taken, false) || hasFloatingPointDef(notTaken, false)) {
                if (VERBOSE)
                    System.out.println("CondMove: fail - not allowed integer condition controlling floating conditional move");
                return false;
            }
        }
    }
    // For now, do not generate CMOVs for longs.
    if (hasLongDef(taken) || hasLongDef(notTaken)) {
        return false;
    }
    // count the number of expression evaluations in each side of the
    // diamond
    int takenCost = 0;
    int notTakenCost = 0;
    if (taken != null)
        takenCost = evaluateCost(taken);
    if (notTaken != null)
        notTakenCost = evaluateCost(notTaken);
    // evaluate whether it's profitable.
    int shortestCost = Math.min(takenCost, notTakenCost);
    int xformCost = 2 * (takenCost + notTakenCost);
    int k = ir.options.CONTROL_COND_MOVE_CUTOFF;
    if (xformCost - shortestCost > k) {
        if (VERBOSE)
            System.out.println("CondMove: fail - cost too high");
        return false;
    }
    // Perform the transformation!
    doCondMove(ir, diamond, cb);
    return true;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)

Example 7 with ConditionOperand

use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand 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 8 with ConditionOperand

use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand 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)

Example 9 with ConditionOperand

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

the class ComplexLIR2MIRExpansion method fp_ifcmp.

// the fcmoi/fcmoip was generated by burs
// we do the rest of the expansion here because in some
// cases we must remove a trailing goto, and we
// can't do that in burs!
private static Instruction fp_ifcmp(Instruction s) {
    Instruction nextInstr = s.nextInstructionInCodeOrder();
    BranchOperand testFailed;
    BasicBlock bb = s.getBasicBlock();
    Instruction lastInstr = bb.lastRealInstruction();
    if (lastInstr.operator() == IA32_JMP) {
        // We're in trouble if there is another instruction between s and lastInstr!
        if (VM.VerifyAssertions)
            VM._assert(s.nextInstructionInCodeOrder() == lastInstr);
        // Set testFailed to target of GOTO
        testFailed = MIR_Branch.getClearTarget(lastInstr);
        nextInstr = lastInstr.nextInstructionInCodeOrder();
        lastInstr.remove();
    } else {
        // Set testFailed to label of next (fallthrough basic block)
        testFailed = bb.nextBasicBlockInCodeOrder().makeJumpTarget();
    }
    // Translate condition operand respecting IA32 FCOMI/COMISS/COMISD
    Instruction fcomi = s.prevInstructionInCodeOrder();
    Operand val1 = MIR_Compare.getVal1(fcomi);
    Operand val2 = MIR_Compare.getVal2(fcomi);
    ConditionOperand c = IfCmp.getCond(s);
    BranchOperand target = IfCmp.getTarget(s).copy().asBranch();
    BranchProfileOperand branchProfile = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
    // propagate the original probability to the second condition.
    switch(c.value) {
        // (i.e. UNORDERED is a goto to testFailed)
        case ConditionOperand.CMPL_EQUAL:
            if (VM.VerifyAssertions)
                VM._assert(!c.branchIfUnordered());
            // Check whether val1 and val2 operands are the same
            if (!val1.similar(val2)) {
                s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
                testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.EQ(), // ZF == 1
                target, branchProfile));
                s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (testFailed.copy())));
            } else {
                // As val1 == val2 result of compare must be == or UNORDERED
                s.insertBefore(// PF == 0
                MIR_CondBranch.create(// PF == 0
                IA32_JCC, // PF == 0
                IA32ConditionOperand.PO(), target, branchProfile));
                s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            }
            break;
        case ConditionOperand.CMPL_GREATER:
            if (VM.VerifyAssertions)
                VM._assert(!c.branchIfUnordered());
            s.insertBefore(// CF == 0 and ZF == 0
            MIR_CondBranch.create(// CF == 0 and ZF == 0
            IA32_JCC, // CF == 0 and ZF == 0
            IA32ConditionOperand.LGT(), target, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            break;
        case ConditionOperand.CMPG_LESS:
            if (VM.VerifyAssertions)
                VM._assert(!c.branchIfUnordered());
            s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
            testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.LLT(), // CF == 1
            target, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (testFailed.copy())));
            break;
        case ConditionOperand.CMPL_GREATER_EQUAL:
            if (VM.VerifyAssertions)
                VM._assert(!c.branchIfUnordered());
            s.insertBefore(// CF == 0
            MIR_CondBranch.create(// CF == 0
            IA32_JCC, // CF == 0
            IA32ConditionOperand.LGE(), target, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            break;
        case ConditionOperand.CMPG_LESS_EQUAL:
            s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
            testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.LGT(), // ZF == 0 and CF == 0
            (BranchOperand) (testFailed.copy()), branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, target));
            break;
        // (i.e. UNORDERED is a goto to target)
        case ConditionOperand.CMPL_NOT_EQUAL:
            if (VM.VerifyAssertions)
                VM._assert(c.branchIfUnordered());
            // Check whether val1 and val2 operands are the same
            if (!val1.similar(val2)) {
                s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
                target, new BranchProfileOperand(0f), IA32ConditionOperand.NE(), // ZF == 0
                (BranchOperand) (target.copy()), branchProfile));
                s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            } else {
                // As val1 == val2 result of compare must be == or UNORDERED
                s.insertBefore(// PF == 1
                MIR_CondBranch.create(// PF == 1
                IA32_JCC, // PF == 1
                IA32ConditionOperand.PE(), target, branchProfile));
                s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            }
            break;
        case ConditionOperand.CMPL_LESS:
            if (VM.VerifyAssertions)
                VM._assert(c.branchIfUnordered());
            s.insertBefore(// CF == 1
            MIR_CondBranch.create(// CF == 1
            IA32_JCC, // CF == 1
            IA32ConditionOperand.LLT(), target, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            break;
        case ConditionOperand.CMPG_GREATER_EQUAL:
            if (VM.VerifyAssertions)
                VM._assert(c.branchIfUnordered());
            s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
            target, new BranchProfileOperand(0f), IA32ConditionOperand.LLT(), // CF == 1
            testFailed, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (target.copy())));
            break;
        case ConditionOperand.CMPG_GREATER:
            if (VM.VerifyAssertions)
                VM._assert(c.branchIfUnordered());
            s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
            target, new BranchProfileOperand(0f), IA32ConditionOperand.LGT(), // ZF == 0 and CF == 0
            (BranchOperand) (target.copy()), branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            break;
        case ConditionOperand.CMPL_LESS_EQUAL:
            if (VM.VerifyAssertions)
                VM._assert(c.branchIfUnordered());
            s.insertBefore(// CF == 1 or ZF == 1
            MIR_CondBranch.create(// CF == 1 or ZF == 1
            IA32_JCC, // CF == 1 or ZF == 1
            IA32ConditionOperand.LLE(), target, branchProfile));
            s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
            break;
        default:
            OptimizingCompilerException.UNREACHABLE();
    }
    s.remove();
    return nextInstr;
}
Also used : 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) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 10 with ConditionOperand

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

the class ComplexLIR2MIRExpansion method long_ifcmp.

private static Instruction long_ifcmp(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);
    RegisterOperand yh = (RegisterOperand) IfCmp.getClearVal2(s);
    yh.setType(TypeReference.Int);
    RegisterOperand yl = new RegisterOperand(ir.regpool.getSecondReg(yh.getRegister()), TypeReference.Int);
    basic_long_ifcmp(s, ir, cond, xh, xl, yh, yl);
    return nextInstr;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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)

Aggregations

ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)29 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)28 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)21 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)21 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)14 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)14 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)14 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)13 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)13 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)12 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)10 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)10 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)10 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)9 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)8 Register (org.jikesrvm.compilers.opt.ir.Register)7 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)7