use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class CallingConvention method saveNonvolatilesBeforeSysCall.
/**
* Save all nonvolatile registers before a syscall.
* We do this in case the sys call does not respect our
* register conventions.<p>
*
* We save/restore all nonvolatiles and the PR, whether
* or not this routine uses them. This may be a tad inefficient, but if
* you're making a system call, you probably don't care.
*
* @param call the sys call
* @param ir the IR that contains the call
*/
static void saveNonvolatilesBeforeSysCall(Instruction call, IR ir) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
StackManager sm = (StackManager) ir.stackManager;
// get the offset into the stack frame of where to stash the first
// nonvolatile for this case.
int location = sm.getOffsetForSysCall();
// save each non-volatile
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, M, new RegisterOperand(r, wordType)));
location += WORDSIZE;
}
// save the thread register
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, M, ir.regpool.makeTROp()));
// save the JTOC, if present
if (JTOC_REGISTER != null) {
location += WORDSIZE;
Operand jtocSave = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, jtocSave, ir.regpool.makeTocOp()));
}
}
use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class MIRSplitRanges method findOrCreateTemp.
/**
* Finds or creates a temporary register to cache a symbolic register.
*
* @param rOp the symbolic register operand
* @param map a mapping from symbolics to temporaries
* @param ir the governing IR
* @return a register operand to cache the symbolic register
*/
private static RegisterOperand findOrCreateTemp(RegisterOperand rOp, java.util.HashMap<Register, Register> map, IR ir) {
Register tReg = map.get(rOp.getRegister());
if (tReg == null) {
RegisterOperand tOp = ir.regpool.makeTemp(rOp.getType());
map.put(rOp.getRegister(), tOp.getRegister());
return tOp;
} else {
return new RegisterOperand(tReg, rOp.getType());
}
}
use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class MIRSplitRanges method perform.
/**
* The main method.<p>
*
* We split live ranges for registers around PEIs which have catch
* blocks. Suppose we have a
* PEI s which uses a symbolic register r1. We must ensure that after
* register allocation, r1 is NOT assigned to a scratch location in s,
* since this would mess up code in the catch block that uses r1.<p>
*
* So, instead, we introduce a new temporary r2 which holds the value of
* r1. The live range for r2 spans only the instruction s. Later, we
* will ensure that r2 is never spilled.<p>
*
* TODO: This could be implemented more efficiently.
*
* @param ir the governing IR
*/
@Override
public final void perform(IR ir) {
java.util.HashMap<Register, Register> newMap = new java.util.HashMap<Register, Register>(5);
for (Enumeration<BasicBlock> be = ir.getBasicBlocks(); be.hasMoreElements(); ) {
BasicBlock bb = be.nextElement();
for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
Instruction s = ie.nextElement();
;
// clear the cache of register assignments
newMap.clear();
// here and in RegisterRestrictions!
if (s.isPEI() && s.operator() != IR_PROLOGUE) {
if (bb.hasApplicableExceptionalOut(s) || !RegisterRestrictions.SCRATCH_IN_PEI) {
splitAllLiveRanges(s, newMap, ir, false);
}
}
// (1) Some operands must be in registers
switch(s.getOpcode()) {
case MIR_LOWTABLESWITCH_opcode:
{
RegisterOperand rOp = MIR_LowTableSwitch.getIndex(s);
RegisterOperand temp = findOrCreateTemp(rOp, newMap, ir);
// NOTE: Index as marked as a DU because LowTableSwitch is
// going to destroy the value in the register.
// By construction (see ConvertToLowLevelIR), no one will
// ever read the value computed by a LowTableSwitch.
// Therefore, don't insert a move instruction after the
// LowTableSwitch (which would cause IR verification
// problems anyways, since LowTableSwitch is a branch).
// move r into 'temp' before s
insertMoveBefore(temp, rOp.copyRO(), s);
rOp.setRegister(temp.getRegister());
}
break;
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class RegisterRestrictions method restrictTo8Bits.
/**
* Ensures that a particular register is only assigned to AL, BL, CL, or
* DL, since these are the only 8-bit registers we normally address.
*
* @param r the register that needs to be restricted to 8 bits
*/
void restrictTo8Bits(Register r) {
PhysicalRegisterSet phys = (PhysicalRegisterSet) this.phys;
Register ESP = phys.getESP();
Register EBP = phys.getEBP();
Register ESI = phys.getESI();
Register EDI = phys.getEDI();
addRestriction(r, ESP);
addRestriction(r, EBP);
addRestriction(r, ESI);
addRestriction(r, EDI);
}
use of org.jikesrvm.compilers.opt.ir.Register in project JikesRVM by JikesRVM.
the class StackManager method computeNonVolatileArea.
@Override
public void computeNonVolatileArea() {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
if (ir.compiledMethod.isSaveVolatile()) {
// Record that we use every nonvolatile GPR
int numGprNv = PhysicalRegisterSet.getNumberOfNonvolatileGPRs();
ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
// set the frame size
frameSize += numGprNv * WORDSIZE;
frameSize = align(frameSize, STACKFRAME_ALIGNMENT);
// TODO!!
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
// Record that we need a stack frame.
setFrameRequired();
int fpuStateSaveAreaBegin = spillPointer;
// and saveFloatingPointState(..)
if (SSE2_FULL) {
for (int i = 0; i < 8; i++) {
fsaveLocation = allocateNewSpillLocation(DOUBLE_REG);
}
} else {
// frame, as a place to store the floating-point state with FSAVE
for (int i = 0; i < 27; i++) {
fsaveLocation = allocateNewSpillLocation(INT_REG);
}
}
int fpuStateSaveAreaEnd = spillPointer;
int fpuStateSize = fpuStateSaveAreaEnd - fpuStateSaveAreaBegin;
if (VM.VerifyAssertions) {
VM._assert(fpuStateSize == OPT_SAVE_VOLATILE_SPACE_FOR_FPU_STATE);
}
int volatileGPRSaveAreaBegin = spillPointer;
// Map each volatile register to a spill location.
int i = 0;
for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
e.nextElement();
// Note that as a side effect, the following call bumps up the
// frame size.
saveVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
}
int volatileGPRSaveAreaEnd = spillPointer;
int volatileGPRSaveAreaSize = volatileGPRSaveAreaEnd - volatileGPRSaveAreaBegin;
if (VM.VerifyAssertions) {
VM._assert(volatileGPRSaveAreaSize == OPT_SAVE_VOLATILE_SPACE_FOR_VOLATILE_GPRS);
VM._assert((volatileGPRSaveAreaSize + fpuStateSize) == OPT_SAVE_VOLATILE_TOTAL_SIZE);
}
// Map each non-volatile register to a spill location.
i = 0;
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); i++) {
e.nextElement();
// Note that as a side effect, the following call bumps up the
// frame size.
nonVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
}
// Set the offset to find non-volatiles.
int gprOffset = getNonvolatileGPROffset(0);
ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
} else {
// Count the number of nonvolatiles used.
int numGprNv = 0;
int i = 0;
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
if (r.isTouched()) {
// Note that as a side effect, the following call bumps up the
// frame size.
nonVolatileGPRLocation[i++] = allocateNewSpillLocation(INT_REG);
numGprNv++;
}
}
// Update the OptCompiledMethod object.
ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
if (numGprNv > 0) {
int gprOffset = getNonvolatileGPROffset(0);
ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
// record that we need a stack frame
setFrameRequired();
} else {
ir.compiledMethod.setUnsignedNonVolatileOffset(0);
}
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
}
}
Aggregations