use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_deferred_prologue.
/**
* Emit deferred prologue
*/
@Override
protected void emit_deferred_prologue() {
if (VM.VerifyAssertions)
VM._assert(method.isForOsrSpecialization());
if (isInterruptible) {
Offset offset = Entrypoints.stackLimitField.getOffset();
if (VM.BuildFor32Addr) {
// S0<-limit
asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, offset);
asm.emitSUB_Reg_Reg(S0, SP);
asm.emitADD_Reg_Imm(S0, method.getOperandWords() << LG_WORDSIZE);
} else {
// S0<-limit
asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, offset);
asm.emitSUB_Reg_Reg_Quad(S0, SP);
asm.emitADD_Reg_Imm_Quad(S0, method.getOperandWords() << LG_WORDSIZE);
}
asm.emitBranchLikelyNextInstruction();
// Jmp around trap
ForwardReference fr = asm.forwardJcc(LT);
// trap
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_STACK_OVERFLOW + RVM_TRAP_BASE);
fr.resolve(asm);
} else {
// TODO!! make sure stackframe of uninterruptible method doesn't overflow
}
/* never do monitor enter for synced method since the specialized
* code starts after original monitor enter.
*/
genThreadSwitchTest(RVMThread.PROLOGUE);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_instanceof_resolvedClass.
@Override
protected void emit_instanceof_resolvedClass(RVMClass type) {
int LHSDepth = type.getTypeDepth();
int LHSId = type.getId();
// load object from stack
asm.emitPOP_Reg(ECX);
// test for null
ForwardReference isNull = asm.forwardJECXZ();
// get superclass display from object's TIB
asm.baselineEmitLoadTIB(S0, ECX);
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_SUPERCLASS_IDS_INDEX << LG_WORDSIZE));
} else {
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_SUPERCLASS_IDS_INDEX << LG_WORDSIZE));
}
ForwardReference outOfBounds = null;
if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
// must do arraybounds check of superclass display
if (ARRAY_LENGTH_BYTES == 4) {
asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
} else {
asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
}
outOfBounds = asm.forwardJcc(LLE);
}
// Load id from display at required depth and compare against target id; push true if matched
asm.emitMOVZX_Reg_RegDisp_Word(S0, S0, Offset.fromIntZeroExtend(LHSDepth << LOG_BYTES_IN_SHORT));
asm.emitCMP_Reg_Imm(S0, LHSId);
ForwardReference notMatched = asm.forwardJcc(NE);
asm.emitPUSH_Imm(1);
ForwardReference done = asm.forwardJMP();
// push false
isNull.resolve(asm);
if (outOfBounds != null)
outOfBounds.resolve(asm);
notMatched.resolve(asm);
asm.emitPUSH_Imm(0);
done.resolve(asm);
}
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;
// T1 is index of desired case
asm.emitPOP_Reg(T1);
// relativize T1
asm.emitSUB_Reg_Imm(T1, low);
// 0 <= relative index < n
asm.emitCMP_Reg_Imm(T1, n);
if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
int firstCounter = edgeCounterIdx;
edgeCounterIdx += (n + 1);
// Jump around code for default case
ForwardReference fr = asm.forwardJcc(LLT);
incEdgeCounter(S0, null, firstCounter + n);
asm.emitJMP_ImmOrLabel(mTarget, bTarget);
fr.resolve(asm);
// Increment counter for the appropriate case
incEdgeCounter(S0, T1, firstCounter);
} else {
// if not, goto default case
asm.emitJCC_Cond_ImmOrLabel(LGE, mTarget, bTarget);
}
// T0 = EIP at start of method
asm.emitMETHODSTART_Reg(T0);
asm.emitTableswitchCode(T0, T1);
// loaded for the cases
for (int i = 0; i < n; i++) {
int offset = bcodes.getTableSwitchOffset(i);
bTarget = biStart + offset;
mTarget = bytecodeMap[bTarget];
asm.emitOFFSET_Imm_ImmOrLabel(i, mTarget, bTarget);
}
bcodes.skipTableSwitchOffsets(n);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genBoundsCheck.
/**
* Generate an array bounds check trapping if the array bound check fails,
* otherwise falling through.
* @param asm the assembler to generate into
* @param indexReg the register containing the index
* @param arrayRefReg the register containing the array reference
*/
@Inline(value = Inline.When.ArgumentsAreConstant, arguments = { 1, 2 })
static void genBoundsCheck(Assembler asm, GPR indexReg, GPR arrayRefReg) {
// compare index to array length
if (ARRAY_LENGTH_BYTES == 4) {
asm.emitCMP_RegDisp_Reg(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg);
} else {
asm.emitCMP_RegDisp_Reg_Quad(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg);
}
// Jmp around trap if index is OK
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(LGT);
// "pass" index param to C trap handler
asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.arrayIndexTrapParamField.getOffset(), indexReg);
// trap
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_ARRAY_BOUNDS + RVM_TRAP_BASE);
fr.resolve(asm);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_DFcmpGL_if.
@Override
protected void emit_DFcmpGL_if(boolean single, boolean unorderedGT, int bTarget, BranchCondition bc) {
if (SSE2_BASE) {
if (single) {
// XMM0 = value2
asm.emitMOVSS_Reg_RegInd(XMM0, SP);
// XMM1 = value1
asm.emitMOVSS_Reg_RegDisp(XMM1, SP, ONE_SLOT);
// throw away slots
adjustStack(WORDSIZE * 2, true);
} else {
// XMM0 = value2
asm.emitMOVSD_Reg_RegInd(XMM0, SP);
// XMM1 = value1
asm.emitMOVSD_Reg_RegDisp(XMM1, SP, TWO_SLOTS);
// throw away slots
adjustStack(WORDSIZE * 4, true);
}
} else {
if (single) {
// Setup value2 into FP1,
asm.emitFLD_Reg_RegInd(FP0, SP);
// value1 into FP0
asm.emitFLD_Reg_RegDisp(FP0, SP, ONE_SLOT);
// throw away slots
adjustStack(WORDSIZE * 2, true);
} else {
// Setup value2 into FP1,
asm.emitFLD_Reg_RegInd_Quad(FP0, SP);
// value1 into FP0
asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, TWO_SLOTS);
// throw away slots
adjustStack(WORDSIZE * 4, true);
}
}
if (SSE2_BASE) {
if (single) {
// compare value1 and value2
asm.emitUCOMISS_Reg_Reg(XMM1, XMM0);
} else {
// compare value1 and value2
asm.emitUCOMISD_Reg_Reg(XMM1, XMM0);
}
} else {
// compare and pop FPU *1
asm.emitFUCOMIP_Reg_Reg(FP0, FP1);
// pop FPU*1
asm.emitFSTP_Reg_Reg(FP0, FP0);
}
byte asm_bc = -1;
boolean unordered_taken = false;
switch(bc) {
case EQ:
asm_bc = EQ;
unordered_taken = false;
break;
case NE:
asm_bc = NE;
unordered_taken = true;
break;
case LT:
asm_bc = LLT;
unordered_taken = !unorderedGT;
break;
case GE:
asm_bc = LGE;
unordered_taken = unorderedGT;
break;
case GT:
asm_bc = LGT;
unordered_taken = unorderedGT;
break;
case LE:
asm_bc = LLE;
unordered_taken = !unorderedGT;
break;
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
int mTarget = bytecodeMap[bTarget];
if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
// Allocate two counters: taken and not taken
int entry = edgeCounterIdx;
edgeCounterIdx += 2;
if (!unordered_taken) {
ForwardReference notTaken1 = asm.forwardJcc(PE);
ForwardReference notTaken2 = asm.forwardJcc(asm.flipCode(asm_bc));
// Increment taken counter & jump to target
incEdgeCounter(T1, null, entry + EdgeCounts.TAKEN);
asm.emitJMP_ImmOrLabel(mTarget, bTarget);
// Increment not taken counter
notTaken1.resolve(asm);
notTaken2.resolve(asm);
incEdgeCounter(T1, null, entry + EdgeCounts.NOT_TAKEN);
} else {
ForwardReference taken1 = asm.forwardJcc(PE);
ForwardReference taken2 = asm.forwardJcc(asm_bc);
// Increment taken counter & jump to target
incEdgeCounter(T1, null, entry + EdgeCounts.NOT_TAKEN);
ForwardReference notTaken = asm.forwardJMP();
// Increment taken counter
taken1.resolve(asm);
taken2.resolve(asm);
incEdgeCounter(T1, null, entry + EdgeCounts.TAKEN);
asm.emitJMP_ImmOrLabel(mTarget, bTarget);
notTaken.resolve(asm);
}
} else {
if (unordered_taken) {
asm.emitJCC_Cond_ImmOrLabel(PE, mTarget, bTarget);
asm.emitJCC_Cond_ImmOrLabel(asm_bc, mTarget, bTarget);
} else {
ForwardReference notTaken = asm.forwardJcc(PE);
asm.emitJCC_Cond_ImmOrLabel(asm_bc, mTarget, bTarget);
notTaken.resolve(asm);
}
}
}
Aggregations