Search in sources :

Example 1 with BURSManagedFPROperand

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

the class BURS_Helpers method FPR_2INT.

/**
 * Expansion of FLOAT_2INT and DOUBLE_2INT, using the FIST instruction. This
 * expansion does some boolean logic and conditional moves in order to avoid
 * changing the floating-point rounding mode or inserting branches. Other
 * expansions are possible, and may be better?
 *
 * @param s the instruction to expand
 * @param result the result operand
 * @param value the second operand
 */
protected final void FPR_2INT(Instruction s, RegisterOperand result, Operand value) {
    MemoryOperand M;
    // and in 'strict' IEEE mode.
    if (value instanceof MemoryOperand) {
        // value is in memory, all we have to do is load it
        EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), value)));
    } else {
        // we must have a store/load sequence to cause IEEE rounding.
        if (value instanceof BURSManagedFPROperand) {
            if (VM.VerifyAssertions) {
                opt_assert(value.similar(myFP0()));
            }
            EMIT(CPOS(s, MIR_Move.create(IA32_FSTP, MO_CONV(DW), value)));
            EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), MO_CONV(DW))));
        } else {
            EMIT(CPOS(s, MIR_Move.create(IA32_FMOV, MO_CONV(DW), value)));
            EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), MO_CONV(DW))));
        }
    }
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_Move.create(IA32_FIST, MO_CONV(DW), myFP0())));
    // MO_CONV now holds myFP0 converted to an integer (round-toward nearest)
    // FP Stack: myFP0 == value
    // isPositive == 1 iff 0.0 < value
    // isNegative == 1 iff 0.0 > value
    Register one = regpool.getInteger();
    Register isPositive = regpool.getInteger();
    Register isNegative = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(one, TypeReference.Int), IC(1))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(isPositive, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(isNegative, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Nullary.create(IA32_FLDZ, myFP0())));
    // FP Stack: myFP0 = 0.0; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(isPositive, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LLT())));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(isNegative, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LGT())));
    EMIT(CPOS(s, MIR_Move.create(IA32_FILD, myFP0(), MO_CONV(DW))));
    // FP Stack: myFP0 = round(value), myFP1 = value
    // addee = 1 iff round(x) < x
    // subtractee = 1 iff round(x) > x
    Register addee = regpool.getInteger();
    Register subtractee = regpool.getInteger();
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(addee, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(subtractee, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(addee, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LLT())));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(subtractee, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LGT())));
    // Now a little tricky part.
    // We will add 1 iff isNegative and x > round(x)
    // We will subtract 1 iff isPositive and x < round(x)
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, new RegisterOperand(addee, TypeReference.Int), new RegisterOperand(isNegative, TypeReference.Int))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, new RegisterOperand(subtractee, TypeReference.Int), new RegisterOperand(isPositive, TypeReference.Int))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, result.copy(), MO_CONV(DW))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, result.copy(), new RegisterOperand(addee, TypeReference.Int))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, result.copy(), new RegisterOperand(subtractee, TypeReference.Int))));
    // Compare myFP0 with (double)Integer.MAX_VALUE
    M = loadFromJTOC(burs.ir, Entrypoints.maxintField.getOffset(), QW);
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), M)));
    // FP Stack: myFP0 = (double)Integer.MAX_VALUE; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    // If MAX_VALUE < value, then result := MAX_INT
    Register maxInt = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(maxInt, TypeReference.Int), IC(Integer.MAX_VALUE))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(maxInt, TypeReference.Int), IA32ConditionOperand.LLT())));
    // Compare myFP0 with (double)Integer.MIN_VALUE
    M = MemoryOperand.D(Magic.getTocPointer().plus(Entrypoints.minintField.getOffset()), QW, null, null);
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), M)));
    // FP Stack: myFP0 = (double)Integer.MIN_VALUE; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    // If MIN_VALUE > value, then result := MIN_INT
    Register minInt = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(minInt, TypeReference.Int), IC(Integer.MIN_VALUE))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(minInt, TypeReference.Int), IA32ConditionOperand.LGT())));
    // Set condition flags: set PE iff myFP0 is a NaN
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP0())));
    // FP Stack: back to original level (all BURS managed slots freed)
    // If FP0 was classified as a NaN, then result := 0
    Register zero = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(zero, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(zero, TypeReference.Int), IA32ConditionOperand.PE())));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand)

Example 2 with BURSManagedFPROperand

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

the class SpillCode method rewriteFPStack.

/**
 *  Rewrites floating point registers to reflect changes in stack
 *  height induced by BURS.
 * <p>
 *  Side effect: update the fpStackHeight in MIRInfo.
 *
 *  @param ir the IR to process
 */
private void rewriteFPStack(IR ir) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    for (Enumeration<BasicBlock> b = ir.getBasicBlocks(); b.hasMoreElements(); ) {
        BasicBlock bb = b.nextElement();
        // The following holds the floating point stack offset from its
        // 'normal' position.
        int fpStackOffset = 0;
        for (Enumeration<Instruction> inst = bb.forwardInstrEnumerator(); inst.hasMoreElements(); ) {
            Instruction s = inst.nextElement();
            for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
                Operand op = ops.nextElement();
                if (op.isRegister()) {
                    RegisterOperand rop = op.asRegister();
                    Register r = rop.getRegister();
                    // Update MIR state for every physical FPR we see
                    if (r.isPhysical() && r.isFloatingPoint() && s.operator() != org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.DUMMY_DEF && s.operator() != org.jikesrvm.compilers.opt.ir.ia32.ArchOperators.DUMMY_USE) {
                        int n = org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet.getFPRIndex(r);
                        if (fpStackOffset != 0) {
                            n += fpStackOffset;
                            rop.setRegister(phys.getFPR(n));
                        }
                        ir.MIRInfo.fpStackHeight = Math.max(ir.MIRInfo.fpStackHeight, n + 1);
                    }
                } else if (op instanceof BURSManagedFPROperand) {
                    int regNum = ((BURSManagedFPROperand) op).regNum;
                    s.replaceOperand(op, new RegisterOperand(phys.getFPR(regNum), TypeReference.Double));
                }
            }
            // position.
            if (s.operator().isFpPop()) {
                fpStackOffset--;
            } else if (s.operator().isFpPush()) {
                fpStackOffset++;
            }
            if (VM.VerifyAssertions)
                VM._assert(fpStackOffset >= 0);
        }
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Register (org.jikesrvm.compilers.opt.ir.Register)2 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)2 BURSManagedFPROperand (org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand)2 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)1 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)1 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)1 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)1 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)1