use of org.jikesrvm.compilers.opt.ir.Register 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.Register 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.Register 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.Register in project JikesRVM by JikesRVM.
the class CallingConvention method prologueExpand.
// ///////////////////
// Implementation
// ///////////////////
/**
* Expand the prologue instruction to make calling convention explicit.
*/
private static void prologueExpand(IR ir) {
// set up register lists for dead code elimination.
boolean useDU = ir.options.getOptLevel() >= 1;
if (useDU) {
DefUse.computeDU(ir);
}
Instruction prologueInstr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
if (VM.VerifyAssertions)
VM._assert(prologueInstr.operator() == IR_PROLOGUE);
Instruction start = prologueInstr.nextInstructionInCodeOrder();
int int_index = 0;
int double_index = 0;
int spilledArgumentCounter = (-256 - STACKFRAME_HEADER_SIZE) >> LOG_BYTES_IN_ADDRESS;
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
Register FP = phys.getFP();
for (Enumeration<Operand> symParams = prologueInstr.getDefs(); symParams.hasMoreElements(); ) {
RegisterOperand symParamOp = (RegisterOperand) symParams.nextElement();
Register symParam = symParamOp.getRegister();
TypeReference t = symParamOp.getType();
if (t.isFloatType()) {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (double_index < NUMBER_DOUBLE_PARAM) {
Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
start.insertBefore(MIR_Move.create(PPC_FMR, F(symParam), F(param)));
} else {
// spilled parameter
start.insertBefore(MIR_Load.create(PPC_LFS, F(symParam), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_FLOAT)));
spilledArgumentCounter--;
}
}
double_index++;
} else if (t.isDoubleType()) {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (double_index < NUMBER_DOUBLE_PARAM) {
Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
start.insertBefore(MIR_Move.create(PPC_FMR, D(symParam), D(param)));
} else {
// spilled parameter
start.insertBefore(MIR_Load.create(PPC_LFD, D(symParam), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
spilledArgumentCounter -= BYTES_IN_DOUBLE / BYTES_IN_ADDRESS;
}
}
double_index++;
} else {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (int_index < NUMBER_INT_PARAM) {
Register param = phys.get(FIRST_INT_PARAM + (int_index));
start.insertBefore(MIR_Move.create(PPC_MOVE, new RegisterOperand(symParam, t), A(param)));
} else {
// spilled parameter
if (VM.BuildFor64Addr && (t.isIntType() || t.isShortType() || t.isByteType() || t.isCharType() || t.isBooleanType())) {
start.insertBefore(MIR_Load.create(PPC_LInt, new RegisterOperand(symParam, t), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_INT)));
} else {
// same size as addr (ie, either we're in 32 bit mode or we're in 64 bit mode and it's a reference or long)
start.insertBefore(MIR_Load.create(PPC_LAddr, new RegisterOperand(symParam, t), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
}
spilledArgumentCounter--;
}
}
int_index++;
}
}
removeDefsFromPrologue(prologueInstr);
}
use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class RegisterPreferences method initialize.
/**
* Set up register preferences based on instructions in an IR.
*/
@Override
public void initialize(IR ir) {
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
switch(s.getOpcode()) {
case PPC_MOVE_opcode:
// add affinities produced by MOVE instructions
Operand result = MIR_Move.getResult(s);
Operand value = MIR_Move.getValue(s);
if (result.isRegister() && value.isRegister()) {
Register r1 = result.asRegister().getRegister();
Register r2 = value.asRegister().getRegister();
addAffinity(1, r2, r1);
// above.
if (SYMBOLIC_SYMBOLIC_HEURISTIC && r1.isSymbolic() && r2.isSymbolic()) {
addAffinity(1, r2, r1);
}
}
break;
default:
break;
}
}
}
Aggregations