use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_i2f.
@Override
protected void emit_i2f() {
if (VM.BuildFor64Addr) {
// TO is X (an int)
popInt(T0);
pushLong(T0, T0);
// load long
popDouble(F0);
// convert it
asm.emitFCFID(F0, F0);
// store the float
pushFloat(F0);
} else {
// TO is X (an int)
popInt(T0);
// F0 is MAGIC
asm.emitLFDtoc(F0, Entrypoints.IEEEmagicField.getOffset(), T1);
asm.emitSTFDoffset(F0, THREAD_REGISTER, Entrypoints.scratchStorageField.getOffset());
asm.emitSTWoffset(T0, THREAD_REGISTER, Entrypoints.scratchStorageField.getOffset().plus(4));
// is X < 0
asm.emitCMPI(T0, 0);
ForwardReference fr = asm.emitForwardBC(GE);
asm.emitLIntOffset(T0, THREAD_REGISTER, Entrypoints.scratchStorageField.getOffset());
// decrement top of MAGIC
asm.emitADDI(T0, -1, T0);
asm.emitSTWoffset(T0, THREAD_REGISTER, // MAGIC + X in scratch field
Entrypoints.scratchStorageField.getOffset());
fr.resolve(asm);
// F1 is MAGIC + X
asm.emitLFDoffset(F1, THREAD_REGISTER, Entrypoints.scratchStorageField.getOffset());
// F1 is X
asm.emitFSUB(F1, F1, F0);
// float(X) is on stack
pushFloat(F1);
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_tableswitch.
@Override
protected void emit_tableswitch(int defaultval, int low, int high) {
int bTarget = biStart + defaultval;
int mTarget = bytecodeMap[bTarget];
// n = number of normal cases (0..n-1)
int n = high - low + 1;
// only used if options.PROFILE_EDGE_COUNTERS;
int firstCounter = edgeCounterIdx;
if (options.PROFILE_EDGE_COUNTERS) {
// allocate n+1 counters
edgeCounterIdx += n + 1;
// Load counter array for this method
loadCounterArray(T2);
}
// T0 is index
popInt(T0);
if (Assembler.fits(-low, 16)) {
asm.emitADDI(T0, -low, T0);
} else {
asm.emitLVAL(T1, low);
asm.emitSUBFC(T0, T1, T0);
}
asm.emitLVAL(T3, n);
asm.emitCMPL(T0, T3);
if (options.PROFILE_EDGE_COUNTERS) {
// jump around jump to default target
ForwardReference fr = asm.emitForwardBC(LT);
incEdgeCounter(T2, S0, T3, firstCounter + n);
asm.emitB(mTarget, bTarget);
fr.resolve(asm);
} else {
// conditionally jump to default target
if (bTarget - SHORT_FORWARD_LIMIT < biStart) {
asm.emitShortBC(GE, mTarget, bTarget);
} else {
asm.emitBC(GE, mTarget, bTarget);
}
}
ForwardReference fr1 = asm.emitForwardBL();
for (int i = 0; i < n; i++) {
int offset = bcodes.getTableSwitchOffset(i);
bTarget = biStart + offset;
mTarget = bytecodeMap[bTarget];
asm.emitSwitchCase(i, mTarget, bTarget);
}
bcodes.skipTableSwitchOffsets(n);
fr1.resolve(asm);
// T1 is base of table
asm.emitMFLR(T1);
// convert to bytes
asm.emitSLWI(T0, T0, LOG_BYTES_IN_INT);
if (options.PROFILE_EDGE_COUNTERS) {
incEdgeCounterIdx(T2, S0, T3, firstCounter, T0);
}
// T0 is relative offset of desired case
asm.emitLIntX(T0, T0, T1);
// T1 is absolute address of desired case
asm.emitADD(T1, T1, T0);
asm.emitMTCTR(T1);
asm.emitBCCTR();
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lookupswitch.
@Override
protected void emit_lookupswitch(int defaultval, int npairs) {
if (options.PROFILE_EDGE_COUNTERS) {
// Load counter array for this method
loadCounterArray(T2);
}
// T0 is key
popInt(T0);
for (int i = 0; i < npairs; i++) {
int match = bcodes.getLookupSwitchValue(i);
if (Assembler.fits(match, 16)) {
asm.emitCMPI(T0, match);
} else {
asm.emitLVAL(T1, match);
asm.emitCMP(T0, T1);
}
int offset = bcodes.getLookupSwitchOffset(i);
int bTarget = biStart + offset;
int mTarget = bytecodeMap[bTarget];
if (options.PROFILE_EDGE_COUNTERS) {
// Flip conditions so we can jump over the increment of the taken counter.
ForwardReference fr = asm.emitForwardBC(NE);
// Increment counter & jump to target
incEdgeCounter(T2, S0, T3, edgeCounterIdx++);
asm.emitB(mTarget, bTarget);
fr.resolve(asm);
} else {
if (bTarget - SHORT_FORWARD_LIMIT < biStart) {
asm.emitShortBC(EQ, mTarget, bTarget);
} else {
asm.emitBC(EQ, mTarget, bTarget);
}
}
}
bcodes.skipLookupSwitchPairs(npairs);
int bTarget = biStart + defaultval;
int mTarget = bytecodeMap[bTarget];
if (options.PROFILE_EDGE_COUNTERS) {
incEdgeCounter(T2, S0, T3, edgeCounterIdx++);
}
asm.emitB(mTarget, bTarget);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genThreadSwitchTest.
/**
* @param whereFrom is this thread switch from a PROLOGUE, BACKEDGE, or EPILOGUE?
*/
private void genThreadSwitchTest(int whereFrom) {
if (isInterruptible) {
ForwardReference fr;
// yield if takeYieldpoint is non-zero.
asm.emitLIntOffset(S0, THREAD_REGISTER, Entrypoints.takeYieldpointField.getOffset());
asm.emitCMPI(S0, 0);
if (whereFrom == RVMThread.PROLOGUE) {
// Take yieldpoint if yieldpoint flag is non-zero (either 1 or -1)
fr = asm.emitForwardBC(EQ);
asm.emitLAddrToc(S0, Entrypoints.yieldpointFromPrologueMethod.getOffset());
} else if (whereFrom == RVMThread.BACKEDGE) {
// Take yieldpoint if yieldpoint flag is >0
fr = asm.emitForwardBC(LE);
asm.emitLAddrToc(S0, Entrypoints.yieldpointFromBackedgeMethod.getOffset());
} else {
// EPILOGUE
// Take yieldpoint if yieldpoint flag is non-zero (either 1 or -1)
fr = asm.emitForwardBC(EQ);
asm.emitLAddrToc(S0, Entrypoints.yieldpointFromEpilogueMethod.getOffset());
}
asm.emitMTCTR(S0);
asm.emitBCCTRL();
fr.resolve(asm);
if (VM.BuildForAdaptiveSystem && options.INVOCATION_COUNTERS) {
int id = compiledMethod.getId();
InvocationCounts.allocateCounter(id);
asm.emitLAddrToc(T0, AosEntrypoints.invocationCountsField.getOffset());
asm.emitLVAL(T1, compiledMethod.getId() << LOG_BYTES_IN_INT);
asm.emitLIntX(T2, T0, T1);
asm.emitADDICr(T2, T2, -1);
asm.emitSTWX(T2, T0, T1);
ForwardReference fr2 = asm.emitForwardBC(GT);
asm.emitLAddrToc(T0, AosEntrypoints.invocationCounterTrippedMethod.getOffset());
asm.emitMTCTR(T0);
asm.emitLVAL(T0, id);
asm.emitBCCTRL();
fr2.resolve(asm);
}
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class Assembler method reserveForwardCase.
/* call before emiting data for the case branch */
void reserveForwardCase(int where) {
ForwardReference fr = new ForwardReference.SwitchCase(mIP, where);
forwardRefs = ForwardReference.enqueue(forwardRefs, fr);
}
Aggregations