use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method insertEpilogue.
/**
* Insert the epilogue before a particular return instruction.
*
* @param ret the return instruction.
*/
private void insertEpilogue(Instruction ret) {
// 1. Restore any saved registers
if (ir.compiledMethod.isSaveVolatile()) {
restoreVolatileRegisters(ret);
restoreFloatingPointState(ret);
}
restoreNonVolatiles(ret);
// 2. Restore caller's stackpointer and framepointer
int frameSize = getFrameFixedSize();
ret.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(frameSize)));
MemoryOperand fpHome = MemoryOperand.BD(ir.regpool.makeTROp(), ArchEntrypoints.framePointerField.getOffset(), (byte) WORDSIZE, null, null);
ret.insertBefore(MIR_Nullary.create(IA32_POP, fpHome));
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method isScratchFreeMove.
/**
* @param s the instruction to check
* @return {@code true} if and only if the instruction is a MOVE instruction
* that can be generated without resorting to scratch registers
*/
private boolean isScratchFreeMove(Instruction s) {
if (s.operator() != IA32_MOV)
return false;
// registers in these move instructions.
if (!FLOAT_ESP)
return false;
Operand result = MIR_Move.getResult(s);
Operand value = MIR_Move.getValue(s);
// memory operands.
if (result.isMemory()) {
MemoryOperand M = result.asMemory();
if (hasSymbolicRegister(M))
return false;
// disable these too. What's left? WORDSIZE only.
if (M.size != WORDSIZE)
return false;
}
if (value.isMemory()) {
MemoryOperand M = value.asMemory();
if (hasSymbolicRegister(M))
return false;
// disable these too. What's left? WORDSIZE only.
if (M.size != WORDSIZE)
return false;
}
// If we get here, all is kosher.
return true;
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method moveESPBefore.
/**
* Before instruction s, insert code to adjust ESP so that it lies at a
* particular offset from its usual location.
*
* @param s the instruction before which ESP must have the desired offset
* @param desiredOffset the desired offset
*/
private void moveESPBefore(Instruction s, int desiredOffset) {
PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
Register ESP = phys.getESP();
int delta = desiredOffset - ESPOffset;
if (delta != 0) {
if (canModifyEFLAGS(s)) {
s.insertBefore(MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), VM.BuildFor32Addr ? IC(delta) : LC(delta)));
} else {
MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(delta), (byte) WORDSIZE, null, null);
s.insertBefore(MIR_Lea.create(IA32_LEA, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), M));
}
ESPOffset = desiredOffset;
}
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method insertNormalStackOverflowCheck.
/**
* Insert an explicit stack overflow check in the prologue <em>after</em>
* buying the stack frame.<p>
*
* SIDE EFFECT: mutates the plg into a trap instruction. We need to
* mutate so that the trap instruction is in the GC map data structures.
*
* @param plg the prologue instruction
*/
private void insertNormalStackOverflowCheck(Instruction plg) {
if (!ir.method.isInterruptible()) {
plg.remove();
return;
}
if (ir.compiledMethod.isSaveVolatile()) {
return;
}
PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
Register ESP = phys.getESP();
MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), Entrypoints.stackLimitField.getOffset(), (byte) WORDSIZE, null, null);
// Trap if ESP <= active Thread Stack Limit
MIR_TrapIf.mutate(plg, IA32_TRAPIF, null, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), M, IA32ConditionOperand.LE(), TrapCodeOperand.StackOverflow());
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand 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;
}
}
}
Aggregations