use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class StackManager method insertSpillBefore.
@Override
public void insertSpillBefore(Instruction s, Register r, Register type, int location) {
Operator move = getMoveOperator(type);
byte size = getSizeOfType(type);
RegisterOperand rOp;
if (type.isFloat()) {
rOp = F(r);
} else if (type.isDouble()) {
rOp = D(r);
} else {
if (VM.BuildFor64Addr && type.isInteger()) {
rOp = new RegisterOperand(r, TypeReference.Int);
} else {
rOp = new RegisterOperand(r, PRIMITIVE_TYPE_FOR_WORD);
}
}
StackLocationOperand spillLoc = new StackLocationOperand(true, -location, size);
Instruction spillOp = MIR_Move.create(move, spillLoc, rOp);
if (VERBOSE_DEBUG) {
System.out.println("INSERT_SPILL_BEFORE: " + "Inserting " + spillOp + " before " + s);
}
s.insertBefore(spillOp);
}
use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class StackManager method replaceOperandWithSpillLocation.
@Override
public void replaceOperandWithSpillLocation(Instruction s, RegisterOperand symb) {
// Get the spill location previously assigned to the symbolic
// register.
int location = regAllocState.getSpill(symb.getRegister());
// Create a memory operand M representing the spill location.
int size;
if (VM.BuildFor32Addr) {
if (SSE2_FULL) {
size = symb.getType().getMemoryBytes();
if (size < WORDSIZE)
size = WORDSIZE;
} else {
int type = PhysicalRegisterSet.getPhysicalRegisterType(symb.getRegister());
size = getSpillSize(type);
}
} else {
if (VM.BuildFor64Addr && symb.getType().getMemoryBytes() <= BYTES_IN_INT) {
// Int-like types and floats need 32-bit locations
size = BYTES_IN_INT;
} else {
size = WORDSIZE;
}
}
StackLocationOperand M = new StackLocationOperand(true, -location, (byte) size);
if (VERBOSE_DEBUG) {
System.out.println("REPLACE_OP_WITH_SPILL_LOC: " + "Instruction before replacement: " + s);
}
// replace the register operand with the memory operand
s.replaceOperand(symb, M);
if (VERBOSE_DEBUG) {
System.out.println("REPLACE_OP_WITH_SPILL_LOC: " + "Instruction after replacement: " + s);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class StackManager method rewriteStackLocations.
/**
* Walks through the IR. For each StackLocationOperand, replace the
* operand with the appropriate MemoryOperand.
*/
private void rewriteStackLocations() {
// ESP is initially WORDSIZE above where the framepointer is going to be.
ESPOffset = getFrameFixedSize() + WORDSIZE;
Register ESP = ((PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet()).getESP();
boolean seenReturn = false;
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (s.isReturn()) {
seenReturn = true;
continue;
}
if (s.isBranch()) {
// restore ESP to home location at end of basic block.
moveESPBefore(s, 0);
continue;
}
if (s.operator() == BBEND) {
if (seenReturn) {
// at a return ESP will be at FrameFixedSize,
seenReturn = false;
ESPOffset = 0;
} else {
moveESPBefore(s, 0);
}
continue;
}
if (s.operator() == ADVISE_ESP) {
ESPOffset = MIR_UnaryNoRes.getVal(s).asIntConstant().value;
continue;
}
if (s.operator() == REQUIRE_ESP) {
// ESP is required to be at the given offset from the bottom of the frame
moveESPBefore(s, MIR_UnaryNoRes.getVal(s).asIntConstant().value);
continue;
}
if (s.operator() == YIELDPOINT_PROLOGUE || s.operator() == YIELDPOINT_BACKEDGE || s.operator() == YIELDPOINT_EPILOGUE) {
moveESPBefore(s, 0);
continue;
}
if (s.operator() == IA32_MOV) {
rewriteMoveInstruction(s);
}
// stacklocation and memory operands.
if (s.operator() == IA32_POP) {
ESPOffset += WORDSIZE;
}
for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
Operand op = ops.nextElement();
if (op instanceof StackLocationOperand) {
StackLocationOperand sop = (StackLocationOperand) op;
int offset = sop.getOffset();
if (sop.isFromTop()) {
offset = FPOffset2SPOffset(offset);
}
offset -= ESPOffset;
byte size = sop.getSize();
MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(offset), size, null, null);
s.replaceOperand(op, M);
} else if (op instanceof MemoryOperand) {
MemoryOperand M = op.asMemory();
if ((M.base != null && M.base.getRegister() == ESP) || (M.index != null && M.index.getRegister() == ESP)) {
M.disp = M.disp.minus(ESPOffset);
}
}
}
// stacklocation and memory operands.
if (s.operator() == IA32_PUSH) {
ESPOffset -= WORDSIZE;
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method double_2long.
private static Instruction double_2long(Instruction s, IR ir) {
Instruction nextInstr = s.nextInstructionInCodeOrder();
while (Label.conforms(nextInstr) || BBend.conforms(nextInstr)) {
nextInstr = nextInstr.nextInstructionInCodeOrder();
}
// 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 d2lBB = testBB.splitNodeAt(s, ir);
ir.cfg.linkInCodeOrder(testBB, d2lBB);
// branch if they are <= or unordered.
if (VM.BuildFor32Addr) {
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.maxlongField.getOffset(), (byte) 8);
RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
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_MOVSD, sl, value)));
s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.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(d2lBB);
testBB.insertOut(nanTestBB);
// Convert double 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
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo, slLo)));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi, slHi)));
d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
d2lBB.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);
return nextInstr;
} else {
RegisterOperand result = Unary.getResult(s).copyRO();
RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
RegisterOperand cw = ir.regpool.makeTempInt();
MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongField.getOffset(), (byte) 8);
RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
int offset = -ir.stackManager.allocateSpaceForConversion();
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_MOVSD, sl, value)));
s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.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(d2lBB);
testBB.insertOut(nanTestBB);
// Convert double 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
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result, sl.copy())));
d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
d2lBB.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, result.copyRO(), LC(Long.MAX_VALUE))));
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, 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 SSE2_FPR2GPR_64.
/**
* Emits code to move 64 bits from SSE2 FPRs to GPRs
*
* @param s instruction to modify for the move
*/
protected final void SSE2_FPR2GPR_64(Instruction s) {
int offset = -burs.ir.stackManager.allocateSpaceForConversion();
StackLocationOperand sl = new StackLocationOperand(true, offset, QW);
Operand val = Unary.getClearVal(s);
if (VM.BuildFor32Addr) {
StackLocationOperand sl1 = new StackLocationOperand(true, offset + 4, DW);
StackLocationOperand sl2 = new StackLocationOperand(true, offset, DW);
EMIT(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, val)));
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));
} else {
EMIT(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, val)));
EMIT(MIR_Move.mutate(s, IA32_MOV, Unary.getResult(s), sl.copy()));
}
}
Aggregations