use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method float_2long.
private static Instruction float_2long(Instruction s, IR ir) {
Instruction nextInstr = s.nextInstructionInCodeOrder();
while (Label.conforms(nextInstr) || BBend.conforms(nextInstr)) {
nextInstr = nextInstr.nextInstructionInCodeOrder();
}
if (VM.BuildFor32Addr) {
// we need 6 basic blocks (in code order)
// 1: the current block that does a test to see if this is a regular f2l or
// branches to the maxint/NaN case
// 2: a block to perform a regular f2l
// 3: a block to test for NaN
// 4: a block to perform give maxint
// 5: a block to perform NaN
// 6: the next basic block
BasicBlock testBB = s.getBasicBlock();
BasicBlock nextBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, nextBB);
BasicBlock nanBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, nanBB);
BasicBlock maxintBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, maxintBB);
BasicBlock nanTestBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, nanTestBB);
BasicBlock f2lBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, f2lBB);
// Move the maxlongFloat value and the value into x87 registers and compare and
// branch if they are <= or unordered.
RegisterOperand resultHi = Unary.getResult(s).copyRO();
resultHi.setType(TypeReference.Int);
RegisterOperand resultLo = new RegisterOperand(ir.regpool.getSecondReg(resultHi.getRegister()), TypeReference.Int);
RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
RegisterOperand cw = ir.regpool.makeTempInt();
MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongFloatField.getOffset(), (byte) 4);
RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Float);
RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Float);
int offset = -ir.stackManager.allocateSpaceForConversion();
StackLocationOperand slLo = new StackLocationOperand(true, offset, 4);
StackLocationOperand slHi = new StackLocationOperand(true, offset + 4, 4);
StackLocationOperand sl = new StackLocationOperand(true, offset, 8);
MemoryOperand scratchLo = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset(), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
MemoryOperand scratchHi = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset().plus(4), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
s.insertBefore(CPOS(s, MIR_Move.create(IA32_MOVSS, slLo, value)));
s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, slLo.copy())));
s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0.copyRO(), maxlong)));
MIR_Compare.mutate(s, IA32_FUCOMIP, st0.copyRO(), st1);
testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.LLE(), nanTestBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
testBB.insertOut(f2lBB);
testBB.insertOut(nanTestBB);
// Convert float to long knowing that if the value is < min long the Intel
// unspecified result is min long
// TODO: this would be a lot simpler and faster with SSE3's FISTTP instruction
f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl, st0.copyRO())));
f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo, slLo.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi, slHi)));
f2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
f2lBB.insertOut(nextBB);
// Did the compare find a NaN or a maximum integer?
nanTestBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FSTP, st0.copyRO(), st0.copyRO())));
nanTestBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
nanTestBB.insertOut(nanBB);
nanTestBB.insertOut(maxintBB);
// Value was >= max long
maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC((int) Long.MAX_VALUE))));
maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC((int) (Long.MAX_VALUE >>> 32)))));
maxintBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
maxintBB.insertOut(nextBB);
// In case of NaN result is 0
nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC(0))));
nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC(0))));
nanBB.insertOut(nextBB);
} else {
// we need 4 basic blocks (in code order)
// 1: the current block which includes a test for NaN
// 2: a block to perform regular f2l
// 3: a block to handle NaN (which gives a result of 0)
// 4: the next basic block
BasicBlock testBB = s.getBasicBlock();
BasicBlock nextBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, nextBB);
BasicBlock nanBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, nanBB);
BasicBlock f2lBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, f2lBB);
RegisterOperand result = Unary.getResult(s).copyRO();
RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
RegisterOperand adjustment = ir.regpool.makeTempInt();
testBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, adjustment.copy(), IC(0))));
MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongFloatField.getOffset(), (byte) 4);
MIR_Compare.mutate(s, IA32_UCOMISS, value.copy(), maxlong);
testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
testBB.insertOut(f2lBB);
testBB.insertOut(nanBB);
f2lBB.appendInstruction(CPOS(s, MIR_Set.create(IA32_SET__B, adjustment.copy(), IA32ConditionOperand.LGE())));
f2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_CVTTSS2SI, result.copy(), value.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, result.copy(), adjustment.copy())));
f2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
f2lBB.insertOut(nextBB);
// In case of NaN result is 0.
nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result.copyRO(), LC(0))));
nanBB.insertOut(nextBB);
}
return nextInstr;
}
use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method SET_EXCEPTION_OBJECT.
/**
* Emit code to move a value in a register to the stack location where a
* caught exception object is expected to be.
*
* @param s the instruction to expand
*/
protected final void SET_EXCEPTION_OBJECT(Instruction s) {
int offset = -burs.ir.stackManager.allocateSpaceForCaughtException();
StackLocationOperand sl = new StackLocationOperand(true, offset, DW);
Operand val = CacheOp.getClearRef(s);
if (val.isRegister()) {
EMIT(MIR_Move.mutate(s, IA32_MOV, sl, val));
} else if (val.isConstant()) {
RegisterOperand temp;
if (val.isIntConstant()) {
if (VM.VerifyAssertions)
opt_assert(VM.BuildFor32Addr);
temp = regpool.makeTempInt();
} else if (val.isLongConstant()) {
if (VM.VerifyAssertions)
opt_assert(VM.BuildFor64Addr);
temp = regpool.makeTempLong();
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val)));
// for opt compiler var usage info?
val = temp.copyRO();
EMIT(MIR_Move.mutate(s, IA32_MOV, sl, temp.copy()));
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
}
}
use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method FPR2GPR_64.
/**
* Emits code to move 64 bits from FPRs to GPRs
*
* @param s instruction to modify for the move
*/
protected final void FPR2GPR_64(Instruction s) {
int offset = -burs.ir.stackManager.allocateSpaceForConversion();
StackLocationOperand sl = new StackLocationOperand(true, offset, QW);
StackLocationOperand sl1 = new StackLocationOperand(true, offset + 4, DW);
StackLocationOperand sl2 = new StackLocationOperand(true, offset, DW);
EMIT(CPOS(s, MIR_Move.create(IA32_FMOV, sl, Unary.getClearVal(s))));
RegisterOperand i1 = Unary.getClearResult(s);
RegisterOperand i2 = new RegisterOperand(regpool.getSecondReg(i1.getRegister()), TypeReference.Int);
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, i1, sl1)));
EMIT(MIR_Move.mutate(s, IA32_MOV, i2, sl2));
}
Aggregations