use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class StackManager method restoreVolatileRegisters.
/**
* Insert code before a return instruction to restore the volatile
* and volatile registers.
*
* @param inst the return instruction
*/
private void restoreVolatileRegisters(Instruction inst) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
// Restore every GPR
int i = 0;
for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
Register r = e.nextElement();
int location = saveVolatileGPRLocation[i];
Operand M = new StackLocationOperand(true, -location, WORDSIZE);
inst.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand(r, PRIMITIVE_TYPE_FOR_WORD), M));
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class StackManager method restoreFloatingPointState.
/**
* Insert code into the epilogue to restore the floating point state.
*
* @param inst the return instruction after the epilogue.
*/
private void restoreFloatingPointState(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 RegisterOperand(phys.getFPR(i), TypeReference.Double), new StackLocationOperand(true, -fsaveLocation + (i * BYTES_IN_DOUBLE), BYTES_IN_DOUBLE)));
}
} else {
Operand M = new StackLocationOperand(true, -fsaveLocation, 4);
inst.insertBefore(MIR_FSave.create(IA32_FRSTOR, M));
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class StackManager method computeNonVolatileArea.
/**
* Compute the number of stack words needed to hold nonvolatile
* registers.
*
* Side effects:
* <ul>
* <li> updates the OptCompiler structure
* <li> updates the <code>frameSize</code> field of this object
* <li> updates the <code>frameRequired</code> field of this object
* </ul>
*/
@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 * BYTES_IN_ADDRESS;
int numFprNv = PhysicalRegisterSet.getNumberOfNonvolatileFPRs();
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) numFprNv);
frameSize += numFprNv * BYTES_IN_DOUBLE;
// Record that we need a stack frame.
setFrameRequired();
// Map each volatile GPR 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);
}
// Map each non-volatile GPR 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);
}
// Map some special registers to spill locations.
saveXERLocation = allocateNewSpillLocation(INT_REG);
saveCTRLocation = allocateNewSpillLocation(INT_REG);
i = 0;
for (Enumeration<Register> e = phys.enumerateVolatileFPRs(); e.hasMoreElements(); i++) {
e.nextElement();
// Note that as a side effect, the following call bumps up the
// frame size.
saveVolatileFPRLocation[i] = allocateNewSpillLocation(DOUBLE_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++;
}
}
i = 0;
int numFprNv = 0;
for (Enumeration<Register> e = phys.enumerateNonvolatileFPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
if (r.isTouched()) {
// Note that as a side effect, the following call bumps up the
// frame size.
nonVolatileFPRLocation[i++] = allocateNewSpillLocation(DOUBLE_REG);
numFprNv++;
}
}
// Update the OptCompiledMethod object.
ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) numFprNv);
if (numGprNv > 0 || numFprNv > 0) {
int gprOffset = getNonvolatileGPROffset(0);
ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
// record that we need a stack frame
setFrameRequired();
} else {
ir.compiledMethod.setUnsignedNonVolatileOffset(0);
}
}
frameSize = align(frameSize, STACKFRAME_ALIGNMENT);
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class CallingConvention method restoreNonvolatilesAfterSysCall.
/**
* Restore all nonvolatile registers after 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 restoreNonvolatilesAfterSysCall(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();
// restore each non-volatile
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertAfter(MIR_Move.create(IA32_MOV, new RegisterOperand(r, wordType), M));
location += WORDSIZE;
}
// restore the thread register
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertAfter(MIR_Move.create(IA32_MOV, ir.regpool.makeTROp(), M));
// restore the JTOC, if applicable
if (JTOC_REGISTER != null) {
location += WORDSIZE;
Operand jtocSave = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertAfter(MIR_Move.create(IA32_MOV, ir.regpool.makeTocOp(), jtocSave));
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class ActiveSet method allocateToPhysical.
/**
* Checks whether it's ok to allocate an interval to a physical
* register.
*
* @param i the interval to allocate
* @param p the physical register
* @return {@code true} if it's ok to allocate the interval to the
* given physical register, {@code false} otherwise
*/
private boolean allocateToPhysical(CompoundInterval i, Register p) {
GenericRegisterRestrictions restrict = ir.stackManager.getRestrictions();
Register r = i.getRegister();
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
if (p != null && !phys.isAllocatable(p))
return false;
if (LinearScan.VERBOSE_DEBUG && p != null) {
if (!p.isAvailable())
System.out.println("unavailable " + i + p);
if (restrict.isForbidden(r, p))
System.out.println("forbidden" + i + p);
}
if ((p != null) && p.isAvailable() && !restrict.isForbidden(r, p)) {
CompoundInterval pInterval = regAllocState.getInterval(p);
if (pInterval == null) {
// no assignment to p yet
return true;
} else {
if (!i.intersects(pInterval)) {
return true;
}
}
}
return false;
}
Aggregations