use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lstore.
@Override
protected void emit_lstore(int index) {
try {
if (VM.BuildFor32Addr) {
// pop computes EA after ESP has moved by 4!
Offset offset = localOffset(index + 1).minus(WORDSIZE);
// high part
asm.emitPOP_RegDisp(ESP, offset);
// low part (ESP has moved by 4!!)
asm.emitPOP_RegDisp(ESP, offset);
} else {
Offset offset = localOffset(index + 1).minus(WORDSIZE);
asm.emitPOP_RegDisp(ESP, offset);
// throw away top word
adjustStack(WORDSIZE, true);
}
} catch (UnreachableBytecodeException e) {
asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genPrologue.
// ----------------//
// implementation //
// ----------------//
private void genPrologue() {
if (shouldPrint)
asm.comment("prologue for " + method);
if (klass.hasBridgeFromNativeAnnotation()) {
// replace the normal prologue with a special prolog
JNICompiler.generateGlueCodeForJNIMethod(asm, method, compiledMethod.getId());
// set some constants for the code generation of the rest of the method
// firstLocalOffset is shifted down because more registers are saved
firstLocalOffset = STACKFRAME_BODY_OFFSET.minus(JNICompiler.SAVED_GPRS_FOR_JNI << LG_WORDSIZE);
} else {
genStackOverflowCheck();
/* paramaters are on the stack and/or in registers; There is space
* on the stack for all the paramaters; Parameter slots in the
* stack are such that the first paramater has the higher address,
* i.e., it pushed below all the other paramaters; The return
* address is the topmost entry on the stack. The frame pointer
* still addresses the previous frame.
* The first word of the header, currently addressed by the stack
* pointer, contains the return address.
*/
/* establish a new frame:
* push the caller's frame pointer in the stack, and
* reset the frame pointer to the current stack top,
* ie, the frame pointer addresses directly the word
* that contains the previous frame pointer.
* The second word of the header contains the frame
* point of the caller.
* The third word of the header contains the compiled method id of the called method.
*/
// store caller's frame pointer
asm.emitPUSH_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
// establish new frame
if (VM.BuildFor32Addr) {
asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), SP);
} else {
asm.emitMOV_RegDisp_Reg_Quad(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), SP);
}
/*
* NOTE: until the end of the prologue SP holds the framepointer.
*/
if (VM.VerifyAssertions)
VM._assert(STACKFRAME_METHOD_ID_OFFSET.toInt() == -WORDSIZE);
asm.emitPUSH_Imm(compiledMethod.getId());
/*
* save registers
*/
if (VM.VerifyAssertions)
VM._assert(EDI_SAVE_OFFSET.toInt() == -2 * WORDSIZE);
// save nonvolatile EDI register
asm.emitPUSH_Reg(EDI);
if (VM.VerifyAssertions)
VM._assert(EBX_SAVE_OFFSET.toInt() == -3 * WORDSIZE);
// save nonvolatile EBX register
asm.emitPUSH_Reg(EBX);
int savedRegistersSize;
if (method.hasBaselineSaveLSRegistersAnnotation()) {
if (VM.VerifyAssertions)
VM._assert(EBP_SAVE_OFFSET.toInt() == -4 * WORDSIZE);
asm.emitPUSH_Reg(EBP);
savedRegistersSize = SAVED_GPRS_FOR_SAVE_LS_REGISTERS << LG_WORDSIZE;
} else {
// default
savedRegistersSize = SAVED_GPRS << LG_WORDSIZE;
}
// TODO: (SJF): When I try to reclaim ESI, I may have to save it here?
if (klass.hasDynamicBridgeAnnotation()) {
savedRegistersSize += 2 << LG_WORDSIZE;
if (VM.VerifyAssertions)
VM._assert(T0_SAVE_OFFSET.toInt() == -4 * WORDSIZE);
asm.emitPUSH_Reg(T0);
if (VM.VerifyAssertions)
VM._assert(T1_SAVE_OFFSET.toInt() == -5 * WORDSIZE);
asm.emitPUSH_Reg(T1);
if (SSE2_FULL) {
// TODO: Store SSE2 Control word?
// adjust stack to bottom of saved area
adjustStack(-BASELINE_XMM_STATE_SIZE, true);
if (VM.VerifyAssertions)
VM._assert(XMM_SAVE_OFFSET.toInt() == (-5 * WORDSIZE) - BASELINE_XMM_STATE_SIZE);
asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(24), XMM3);
asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(16), XMM2);
asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(8), XMM1);
asm.emitMOVQ_RegInd_Reg(SP, XMM0);
savedRegistersSize += BASELINE_XMM_STATE_SIZE;
} else {
if (VM.VerifyAssertions)
VM._assert(FPU_SAVE_OFFSET.toInt() == (-5 * WORDSIZE) - X87_FPU_STATE_SIZE);
// adjust stack to bottom of saved area
adjustStack(-X87_FPU_STATE_SIZE, true);
asm.emitFNSAVE_RegInd(SP);
savedRegistersSize += X87_FPU_STATE_SIZE;
}
}
// copy registers to callee's stackframe
firstLocalOffset = STACKFRAME_BODY_OFFSET.minus(savedRegistersSize);
Offset firstParameterOffset = Offset.fromIntSignExtend(savedRegistersSize + STACKFRAME_HEADER_SIZE + (parameterWords << LG_WORDSIZE) - WORDSIZE);
genParameterCopy(firstParameterOffset);
int emptyStackOffset = (method.getLocalWords() << LG_WORDSIZE) - (parameterWords << LG_WORDSIZE);
if (emptyStackOffset != 0) {
// set aside room for non parameter locals
adjustStack(-emptyStackOffset, true);
}
/* defer generating code which may cause GC until
* locals were initialized. see emit_deferred_prologue
*/
if (method.isForOsrSpecialization()) {
return;
}
if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
// use (nonvolatile) EBX to hold base of this method's counter array
if (NEEDS_OBJECT_ALOAD_BARRIER) {
asm.generateJTOCpush(Entrypoints.edgeCountersField.getOffset());
asm.emitPUSH_Imm(getEdgeCounterIndex());
Barriers.compileArrayLoadBarrier(asm, false);
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_Reg(EBX, T0);
} else {
asm.emitMOV_Reg_Reg_Quad(EBX, T0);
}
} else {
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_Abs(EBX, Magic.getTocPointer().plus(Entrypoints.edgeCountersField.getOffset()));
asm.emitMOV_Reg_RegDisp(EBX, EBX, getEdgeCounterOffset());
} else {
asm.generateJTOCpush(Entrypoints.edgeCountersField.getOffset());
asm.emitPOP_Reg(EBX);
asm.emitMOV_Reg_RegDisp_Quad(EBX, EBX, getEdgeCounterOffset());
}
}
}
if (method.isSynchronized())
genMonitorEnter();
genThreadSwitchTest(RVMThread.PROLOGUE);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lrem.
@Override
protected void emit_lrem() {
if (VM.BuildFor64Addr) {
// ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements
asm.emitPOP_Reg(ECX);
// throw away slot
asm.emitPOP_Reg(EAX);
// EAX is dividend
asm.emitPOP_Reg(EAX);
// sign extend EAX into EDX
asm.emitCDO();
asm.emitIDIV_Reg_Reg_Quad(EAX, ECX);
// push result
asm.emitPUSH_Reg(EDX);
} else {
// (1) zero check
asm.emitMOV_Reg_RegInd(T0, SP);
asm.emitOR_Reg_RegDisp(T0, SP, ONE_SLOT);
asm.emitBranchLikelyNextInstruction();
ForwardReference fr1 = asm.forwardJcc(NE);
// trap if divisor is 0
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO + RVM_TRAP_BASE);
fr1.resolve(asm);
// (2) save RVM nonvolatiles
int numNonVols = NONVOLATILE_GPRS.length;
Offset off = Offset.fromIntSignExtend(numNonVols * WORDSIZE);
for (int i = 0; i < numNonVols; i++) {
asm.emitPUSH_Reg(NONVOLATILE_GPRS[i]);
}
// (3) Push args to C function (reversed)
asm.emitPUSH_RegDisp(SP, off.plus(4));
asm.emitPUSH_RegDisp(SP, off.plus(4));
asm.emitPUSH_RegDisp(SP, off.plus(20));
asm.emitPUSH_RegDisp(SP, off.plus(20));
// (4) invoke C function through bootrecord
asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
asm.emitCALL_RegDisp(S0, Entrypoints.sysLongRemainderIPField.getOffset());
// (5) pop space for arguments
adjustStack(4 * WORDSIZE, true);
// (6) restore RVM nonvolatiles
for (int i = numNonVols - 1; i >= 0; i--) {
asm.emitPOP_Reg(NONVOLATILE_GPRS[i]);
}
// (7) pop expression stack
adjustStack(WORDSIZE * 4, true);
// (8) push results
asm.emitPUSH_Reg(T1);
asm.emitPUSH_Reg(T0);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_ldiv.
@Override
protected void emit_ldiv() {
if (VM.BuildFor64Addr) {
// ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements
asm.emitPOP_Reg(ECX);
// throw away slot
asm.emitPOP_Reg(EAX);
// EAX is dividend
asm.emitPOP_Reg(EAX);
// sign extend EAX into EDX
asm.emitCDO();
asm.emitIDIV_Reg_Reg_Quad(EAX, ECX);
// push result
asm.emitPUSH_Reg(EAX);
} else {
// (1) zero check
asm.emitMOV_Reg_RegInd(T0, SP);
asm.emitOR_Reg_RegDisp(T0, SP, ONE_SLOT);
asm.emitBranchLikelyNextInstruction();
ForwardReference fr1 = asm.forwardJcc(NE);
// trap if divisor is 0
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO + RVM_TRAP_BASE);
fr1.resolve(asm);
// (2) save RVM nonvolatiles
int numNonVols = NONVOLATILE_GPRS.length;
Offset off = Offset.fromIntSignExtend(numNonVols * WORDSIZE);
for (int i = 0; i < numNonVols; i++) {
asm.emitPUSH_Reg(NONVOLATILE_GPRS[i]);
}
// (3) Push args to C function (reversed)
asm.emitPUSH_RegDisp(SP, off.plus(4));
asm.emitPUSH_RegDisp(SP, off.plus(4));
asm.emitPUSH_RegDisp(SP, off.plus(20));
asm.emitPUSH_RegDisp(SP, off.plus(20));
// (4) invoke C function through bootrecord
asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
asm.emitCALL_RegDisp(S0, Entrypoints.sysLongDivideIPField.getOffset());
// (5) pop space for arguments
adjustStack(4 * WORDSIZE, true);
// (6) restore RVM nonvolatiles
for (int i = numNonVols - 1; i >= 0; i--) {
asm.emitPOP_Reg(NONVOLATILE_GPRS[i]);
}
// (7) pop expression stack
adjustStack(WORDSIZE * 4, true);
// (8) push results
asm.emitPUSH_Reg(T1);
asm.emitPUSH_Reg(T0);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lload.
@Override
protected void emit_lload(int index) {
try {
Offset offset = localOffset(index);
if (VM.BuildFor32Addr) {
// high part
asm.emitPUSH_RegDisp(ESP, offset);
// low part (ESP has moved by 4!!)
asm.emitPUSH_RegDisp(ESP, offset);
} else {
adjustStack(-WORDSIZE, true);
asm.emitPUSH_RegDisp(ESP, offset);
}
} catch (UnreachableBytecodeException e) {
asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
}
}
Aggregations