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())));
}
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);
}
}
}
Aggregations