use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.
the class AssemblerBase method doLOWTABLESWITCH.
/**
* Emit the given instruction, assuming that
* it is a MIR_LowTableSwitch instruction
* and has a MIR_LOWTABLESWITCH operator
*
* @param inst the instruction to assemble
*/
protected void doLOWTABLESWITCH(Instruction inst) {
// n = number of normal cases (0..n-1)
int n = MIR_LowTableSwitch.getNumberOfTargets(inst);
GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number);
GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number);
emitTableswitchCode(ms, idx);
// loaded for the cases
for (int i = 0; i < n; i++) {
Operand target = MIR_LowTableSwitch.getTarget(inst, i);
emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target));
}
}
use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genParameterCopy.
/**
* Stores parameters into local space of the callee's stackframe.
* <p>
* Assumption: although some parameters may be passed in registers,
* space for all parameters is laid out in order on the caller's stackframe.
*
* @param srcOffset offset from frame pointer of first parameter in caller's stackframe.
*/
private void genParameterCopy(Offset srcOffset) {
// number of general purpose registers unloaded
int gpr = 0;
// number of floating point registers unloaded
int fpr = 0;
// next GPR to get a parameter
GPR T = T0;
// offset from the bottom of the locals for the current parameter
int dstOffset = 0;
if (!method.isStatic()) {
// handle "this" parameter
if (gpr < NUM_PARAMETER_GPRS) {
asm.emitPUSH_Reg(T);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
} else {
// no parameters passed in registers
asm.emitPUSH_RegDisp(SP, srcOffset);
}
dstOffset -= WORDSIZE;
}
// to handle floating point parameters in registers
int[] fprOffset = new int[NUM_PARAMETER_FPRS];
// to handle floating point parameters in registers
boolean[] is32bit = new boolean[NUM_PARAMETER_FPRS];
// in the case of doubles and floats SP may drift from the expected value as we don't use push/pop
int spIsOffBy = 0;
for (TypeReference t : method.getParameterTypes()) {
if (t.isLongType()) {
if (spIsOffBy != 0) {
// fix up SP if it drifted
adjustStack(-spIsOffBy, true);
spIsOffBy = 0;
}
if (gpr < NUM_PARAMETER_GPRS) {
if (VM.BuildFor32Addr) {
// hi mem := lo register (== hi order word)
asm.emitPUSH_Reg(T);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
if (gpr < NUM_PARAMETER_GPRS) {
// lo mem := hi register (== lo order word)
asm.emitPUSH_Reg(T);
gpr++;
} else {
// lo mem from caller's stackframe
asm.emitPUSH_RegDisp(SP, srcOffset);
}
} else {
// create empty slot
adjustStack(-WORDSIZE, true);
// push long
asm.emitPUSH_Reg(T);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
}
} else {
if (VM.BuildFor32Addr) {
// hi mem from caller's stackframe
asm.emitPUSH_RegDisp(SP, srcOffset);
// lo mem from caller's stackframe
asm.emitPUSH_RegDisp(SP, srcOffset);
} else {
// create empty slot
adjustStack(-WORDSIZE, true);
// push long
asm.emitPUSH_RegDisp(SP, srcOffset);
}
}
dstOffset -= 2 * WORDSIZE;
} else if (t.isFloatType()) {
if (fpr < NUM_PARAMETER_FPRS) {
spIsOffBy += WORDSIZE;
fprOffset[fpr] = dstOffset;
is32bit[fpr] = true;
fpr++;
} else {
if (spIsOffBy != 0) {
// fix up SP if it drifted
adjustStack(-spIsOffBy, true);
spIsOffBy = 0;
}
asm.emitPUSH_RegDisp(SP, srcOffset);
}
dstOffset -= WORDSIZE;
} else if (t.isDoubleType()) {
if (fpr < NUM_PARAMETER_FPRS) {
spIsOffBy += 2 * WORDSIZE;
dstOffset -= WORDSIZE;
fprOffset[fpr] = dstOffset;
dstOffset -= WORDSIZE;
is32bit[fpr] = false;
fpr++;
} else {
if (spIsOffBy != 0) {
// fix up SP if it drifted
adjustStack(-spIsOffBy, true);
spIsOffBy = 0;
}
if (VM.BuildFor32Addr) {
// hi mem from caller's stackframe
asm.emitPUSH_RegDisp(SP, srcOffset);
// lo mem from caller's stackframe
asm.emitPUSH_RegDisp(SP, srcOffset);
} else {
// create empty slot
adjustStack(-WORDSIZE, true);
// push double
asm.emitPUSH_RegDisp(SP, srcOffset);
}
dstOffset -= 2 * WORDSIZE;
}
} else {
// t is object, int, short, char, byte, or boolean
if (spIsOffBy != 0) {
// fix up SP if it drifted
adjustStack(-spIsOffBy, true);
spIsOffBy = 0;
}
if (gpr < NUM_PARAMETER_GPRS) {
asm.emitPUSH_Reg(T);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
} else {
asm.emitPUSH_RegDisp(SP, srcOffset);
}
dstOffset -= WORDSIZE;
}
}
if (spIsOffBy != 0) {
// fix up SP if it drifted
adjustStack(-spIsOffBy, true);
}
for (int i = fpr - 1; 0 <= i; i--) {
// unload the floating point register stack (backwards)
if (is32bit[i]) {
if (SSE2_BASE) {
asm.emitMOVSS_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), XMM.lookup(i));
} else {
asm.emitFSTP_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), FP0);
}
} else {
if (SSE2_BASE) {
asm.emitMOVSD_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), XMM.lookup(i));
} else {
asm.emitFSTP_RegDisp_Reg_Quad(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), FP0);
}
}
}
}
use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genParameterRegisterLoad.
/**
* Copy parameters from operand stack into registers.
* Assumption: parameters are layed out on the stack in order
* with SP pointing to the last parameter.
* Also, this method is called before the generation of an explicit method call.
* @param method is the method to be called.
* @param hasThisParam is the method virtual?
*/
protected void genParameterRegisterLoad(MethodReference method, boolean hasThisParam) {
int max = NUM_PARAMETER_GPRS + NUM_PARAMETER_FPRS;
// quit looking when all registers are full
if (max == 0)
return;
// number of general purpose registers filled
int gpr = 0;
// number of floating point registers filled
int fpr = 0;
// next GPR to get a parameter
GPR T = T0;
int params = method.getParameterWords() + (hasThisParam ? 1 : 0);
// stack offset of first parameter word
Offset offset = Offset.fromIntSignExtend((params - 1) << LG_WORDSIZE);
if (hasThisParam) {
if (gpr < NUM_PARAMETER_GPRS) {
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
}
for (TypeReference type : method.getParameterTypes()) {
// quit looking when all registers are full
if (max == 0)
return;
TypeReference t = type;
if (t.isLongType()) {
if (gpr < NUM_PARAMETER_GPRS) {
if (WORDSIZE == 4) {
// lo register := hi mem (== hi order word)
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
if (gpr < NUM_PARAMETER_GPRS) {
// hi register := lo mem (== lo order word)
stackMoveHelper(T, offset.minus(WORDSIZE));
gpr++;
max--;
}
} else {
// initially offset will point at junk word, move down and over
stackMoveHelper(T, offset.minus(WORDSIZE));
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
}
offset = offset.minus(2 * WORDSIZE);
} else if (t.isFloatType()) {
if (fpr < NUM_PARAMETER_FPRS) {
if (SSE2_FULL) {
asm.emitMOVSS_Reg_RegDisp(XMM.lookup(fpr), SP, offset);
} else {
asm.emitFLD_Reg_RegDisp(FP0, SP, offset);
}
fpr++;
max--;
}
offset = offset.minus(WORDSIZE);
} else if (t.isDoubleType()) {
if (fpr < NUM_PARAMETER_FPRS) {
if (SSE2_FULL) {
asm.emitMOVSD_Reg_RegDisp(XMM.lookup(fpr), SP, offset.minus(WORDSIZE));
} else {
asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, offset.minus(WORDSIZE));
}
fpr++;
max--;
}
offset = offset.minus(2 * WORDSIZE);
} else if (t.isReferenceType() || t.isWordLikeType()) {
if (gpr < NUM_PARAMETER_GPRS) {
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
} else {
// t is object, int, short, char, byte, or boolean
if (gpr < NUM_PARAMETER_GPRS) {
if (offset.isZero()) {
asm.emitMOV_Reg_RegInd(T, SP);
} else {
asm.emitMOV_Reg_RegDisp(T, SP, offset);
}
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
}
}
if (VM.VerifyAssertions)
VM._assert(offset.EQ(Offset.fromIntSignExtend(-WORDSIZE)));
}
use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
Address fp = registers.getInnermostFramePointer();
RVMThread myThread = RVMThread.getCurrentThread();
if (TRACE) {
VM.sysWrite("Frame size of ");
VM.sysWrite(optMethod.getMethod());
VM.sysWrite(" is ");
VM.sysWrite(optMethod.getFrameFixedSize());
VM.sysWriteln();
}
// reset sp to "empty params" state (ie same as it was after prologue)
Address sp = fp.minus(optMethod.getFrameFixedSize());
registers.getGPRs().set(STACK_POINTER.value(), sp.toWord());
// store exception object for later retrieval by catch block
int offset = optMethod.getUnsignedExceptionOffset();
if (offset != 0) {
// only put the exception object in the stackframe if the catch block is expecting it.
// (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
// drop the exceptionObject on the floor).
Magic.setObjectAtOffset(Magic.addressAsObject(fp), Offset.fromIntSignExtend(-offset), exceptionObject);
if (TRACE) {
VM.sysWrite("Storing exception object ");
VM.sysWrite(Magic.objectAsAddress(exceptionObject));
VM.sysWrite(" at offset ");
VM.sysWrite(offset);
VM.sysWrite(" from framepoint ");
VM.sysWrite(fp);
VM.sysWriteln();
}
}
if (TRACE) {
VM.sysWrite("Registers before delivering exception in ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
if (TRACE) {
VM.sysWrite("Set ip to ");
VM.sysWrite(registers.getIP());
VM.sysWriteln();
}
// disabled right before RuntimeEntrypoints.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// 'give back' the portion of the stack we borrowed to run
// exception delivery code when invoked for a hardware trap.
// If this was a straight software trap (athrow) then setting
// the stacklimit should be harmless, since the stacklimit should already have exactly
// the value we are setting it too.
myThread.stackLimit = Magic.objectAsAddress(myThread.getStack()).plus(STACK_SIZE_GUARD);
// "branches" to catchBlockInstructionAddress
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method unwindStackFrame.
/**
* Unwind a stackframe.
*/
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
Address fp = registers.getInnermostFramePointer();
OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
if (TRACE) {
VM.sysWrite("Registers before unwinding frame for ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
// restore non-volatile registers
int frameOffset = optMethod.getUnsignedNonVolatileOffset();
for (int i = optMethod.getFirstNonVolatileGPR(); i < NUM_NONVOLATILE_GPRS; i++, frameOffset += BYTES_IN_ADDRESS) {
registers.getGPRs().set(NONVOLATILE_GPRS[i].value(), fp.minus(frameOffset).loadWord());
}
if (VM.VerifyAssertions)
VM._assert(NUM_NONVOLATILE_FPRS == 0);
registers.unwindStackFrame();
if (TRACE) {
VM.sysWrite("Registers after unwinding frame for ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
}
Aggregations