use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class CallingConvention method expandSysCall.
/**
* Calling convention to implement calls to native (C) routines
* using the Linux linkage conventions.<p>
*
* @param s the call instruction
* @param ir the IR that contains the call
*/
public static void expandSysCall(Instruction s, IR ir) {
Operand ip = Call.getClearAddress(s);
// Allocate space to save non-volatiles.
allocateSpaceForSysCall(ir);
// Make sure we allocate enough space for the parameters to this call.
int numberParams = Call.getNumberOfParams(s);
int parameterWords = 0;
for (int i = 0; i < numberParams; i++) {
parameterWords++;
Operand op = Call.getParam(s, i);
parameterWords += op.getType().getStackWords();
}
// allocate space for each parameter,
// plus one word on the stack to hold the address of the callee,
// plus one word on stack for alignment of x64 syscalls
int alignWords = VM.BuildFor64Addr ? 1 : 0;
int neededWords = parameterWords + alignWords + 1;
ir.stackManager.allocateParameterSpace(neededWords * WORDSIZE);
// Convert to a SYSCALL instruction with a null method operand.
Call.mutate0(s, SYSCALL, Call.getClearResult(s), ip, null);
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class RewriteMemoryOperandsWithOversizedDisplacements method perform.
@Override
public void perform(IR ir) {
for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = inst.nextInstructionInCodeOrder()) {
for (int i = 0; i < inst.getNumberOfOperands(); i++) {
Operand op = inst.getOperand(i);
if (op instanceof MemoryOperand) {
MemoryOperand mo = (MemoryOperand) op;
disp64MemOperandConversion(ir, inst, mo);
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class StackManager method saveFloatingPointState.
/**
* Insert code into the prologue to save the floating point state.
*
* @param inst the first instruction after the prologue.
*/
private void saveFloatingPointState(Instruction inst) {
if (SSE2_FULL) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
for (int i = 0; i < 8; i++) {
inst.insertBefore(MIR_Move.create(IA32_MOVQ, new StackLocationOperand(true, -fsaveLocation + (i * BYTES_IN_DOUBLE), BYTES_IN_DOUBLE), new RegisterOperand(phys.getFPR(i), TypeReference.Double)));
}
} else {
Operand M = new StackLocationOperand(true, -fsaveLocation, 4);
inst.insertBefore(MIR_FSave.create(IA32_FNSAVE, M));
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand 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.Operand 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