use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class BURS_MemOp_Helpers method MO_MC.
protected final MemoryOperand MO_MC(Instruction s) {
// JTOC
Operand base = Binary.getVal1(s);
// float or double value
Operand val = Binary.getVal2(s);
if (val instanceof FloatConstantOperand) {
FloatConstantOperand fc = (FloatConstantOperand) val;
Offset offset = fc.offset;
LocationOperand loc = new LocationOperand(offset);
if (base instanceof IntConstantOperand) {
return MO_D(offset.plus(IV(base)), DW, loc, TG());
} else if (VM.BuildFor64Addr && base instanceof LongConstantOperand) {
return MO_D(offset.plus(Offset.fromLong(LV(base))), DW, loc, TG());
} else {
return MO_BD(base, offset, DW, loc, TG());
}
} else {
DoubleConstantOperand dc = (DoubleConstantOperand) val;
Offset offset = dc.offset;
LocationOperand loc = new LocationOperand(offset);
if (base instanceof IntConstantOperand) {
return MO_D(offset.plus(IV(base)), QW, loc, TG());
} else if (VM.BuildFor64Addr && base instanceof LongConstantOperand) {
return MO_D(offset.plus(Offset.fromLong(LV(base))), QW, loc, TG());
} else {
return MO_BD(Binary.getVal1(s), dc.offset, QW, loc, TG());
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class RewriteMemoryOperandsWithOversizedDisplacements method disp64MemOperandConversion.
private static void disp64MemOperandConversion(IR ir, Instruction inst, MemoryOperand mo) {
if (!mo.disp.isZero() && !Bits.fits(mo.disp, 32)) {
RegisterOperand effectiveAddress = ir.regpool.makeTempLong();
RegisterOperand temp = null;
inst.insertBefore(MIR_Move.create(IMMQ_MOV, effectiveAddress, LC(mo.disp.toLong())));
if (mo.index != null) {
if (mo.scale != 0) {
temp = ir.regpool.makeTempLong();
TypeReference indexType = mo.index.getType();
if (indexType.isLongType() || indexType.isWordLikeType()) {
inst.insertBefore(MIR_Move.create(IA32_MOV, temp, mo.index.copy()));
} else if (indexType.isIntType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
} else if (indexType.isByteType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
} else if (indexType.isShortType() || indexType.isCharType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
} else {
String msg = "Unhandled type: " + indexType;
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED, msg);
}
inst.insertBefore(MIR_BinaryAcc.create(IA32_SHL, temp.copy(), IC(mo.scale)));
inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
} else {
TypeReference indexType = mo.index.getType();
if (indexType.isLongType() || indexType.isWordLikeType()) {
inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.index.copy()));
} else {
temp = ir.regpool.makeTempLong();
if (indexType.isIntType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
} else if (indexType.isByteType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
} else if (indexType.isShortType() || indexType.isCharType()) {
inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
} else {
String msg = "Unhandled type: " + indexType;
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED, msg);
}
inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
}
}
}
if (mo.base != null) {
inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.base.copy()));
}
MemoryOperand newMo = MemoryOperand.I(effectiveAddress.copy().asRegister(), mo.size, null != mo.loc ? (LocationOperand) mo.loc.copy() : null, mo.guard != null ? mo.guard.copy() : null);
inst.replaceOperand(mo, newMo);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method insertNormalPrologue.
/**
* Insert the prologue for a normal method.
*
* Assume we are inserting the prologue for method B called from method
* A.
* <ul>
* <li> Perform a stack overflow check.
* <li> Store a back pointer to A's frame
* <li> Store B's compiled method id
* <li> Adjust frame pointer to point to B's frame
* <li> Save any used non-volatile registers
* </ul>
*/
@Override
public void insertNormalPrologue() {
PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
Register ESP = phys.getESP();
MemoryOperand fpHome = MemoryOperand.BD(ir.regpool.makeTROp(), ArchEntrypoints.framePointerField.getOffset(), (byte) WORDSIZE, null, null);
// the prologue instruction
Instruction plg = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
// inst is the instruction immediately after the IR_PROLOGUE
// instruction
Instruction inst = plg.nextInstructionInCodeOrder();
int frameFixedSize = getFrameFixedSize();
ir.compiledMethod.setFrameFixedSize(frameFixedSize);
// See sysSignal_ia32.c
if (frameFixedSize >= BIG_FRAME_MINIMUM_SIZE) {
// 1. Insert Stack overflow check.
insertBigFrameStackOverflowCheck(plg);
// 2. Save caller's frame pointer
inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, fpHome));
// 3. Set my frame pointer to current value of stackpointer
inst.insertBefore(MIR_Move.create(IA32_MOV, fpHome.copy(), new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD)));
// 4. Store my compiled method id
int cmid = ir.compiledMethod.getId();
inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, VM.BuildFor32Addr ? IC(cmid) : LC(cmid)));
} else {
// 1. Save caller's frame pointer
inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, fpHome));
// 2. Set my frame pointer to current value of stackpointer
inst.insertBefore(MIR_Move.create(IA32_MOV, fpHome.copy(), new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD)));
// 3. Store my compiled method id
int cmid = ir.compiledMethod.getId();
inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, VM.BuildFor32Addr ? IC(cmid) : LC(cmid)));
// 4. Insert Stack overflow check.
insertNormalStackOverflowCheck(plg);
}
// II. Save any used volatile and non-volatile registers
if (ir.compiledMethod.isSaveVolatile()) {
saveVolatiles(inst);
saveFloatingPointState(inst);
}
saveNonVolatiles(inst);
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method insertBigFrameStackOverflowCheck.
/**
* Insert an explicit stack overflow check in the prologue <em>before</em>
* buying the stack frame.
* 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 insertBigFrameStackOverflowCheck(Instruction plg) {
if (!ir.method.isInterruptible()) {
plg.remove();
return;
}
if (ir.compiledMethod.isSaveVolatile()) {
return;
}
PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
Register ESP = phys.getESP();
Register ECX = phys.getECX();
// ECX := active Thread Stack Limit
MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), Entrypoints.stackLimitField.getOffset(), (byte) WORDSIZE, null, null);
plg.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand((ECX), PRIMITIVE_TYPE_FOR_WORD), M));
// ECX += frame Size
int frameSize = getFrameFixedSize();
plg.insertBefore(MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(ECX, PRIMITIVE_TYPE_FOR_WORD), VM.BuildFor32Addr ? IC(frameSize) : LC(frameSize)));
// Trap if ESP <= ECX
MIR_TrapIf.mutate(plg, IA32_TRAPIF, null, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), new RegisterOperand(ECX, PRIMITIVE_TYPE_FOR_WORD), IA32ConditionOperand.LE(), TrapCodeOperand.StackOverflow());
}
use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.
the class StackManager method rewriteMoveInstruction.
/**
* Rewrites a move instruction if it has 2 memory operands.
* One of the 2 memory operands must be a stack location operand. Move
* the SP to the appropriate location and use a push or pop instruction.
*
* @param s the instruction to rewrite
*/
private void rewriteMoveInstruction(Instruction s) {
// first attempt to mutate the move into a noop
if (mutateMoveToNop(s))
return;
Operand result = MIR_Move.getResult(s);
Operand val = MIR_Move.getValue(s);
if (result instanceof StackLocationOperand) {
if (val instanceof MemoryOperand || val instanceof StackLocationOperand) {
int offset = ((StackLocationOperand) result).getOffset();
byte size = ((StackLocationOperand) result).getSize();
offset = FPOffset2SPOffset(offset) + size;
moveESPBefore(s, offset);
MIR_UnaryNoRes.mutate(s, IA32_PUSH, val);
}
} else {
if (result instanceof MemoryOperand) {
if (val instanceof StackLocationOperand) {
int offset = ((StackLocationOperand) val).getOffset();
offset = FPOffset2SPOffset(offset);
moveESPBefore(s, offset);
MIR_Nullary.mutate(s, IA32_POP, result);
}
}
}
}
Aggregations