use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_checkcast_resolvedClass.
@Override
protected void emit_checkcast_resolvedClass(RVMClass type) {
int LHSDepth = type.getTypeDepth();
int LHSId = type.getId();
if (VM.BuildFor32Addr) {
// load object from stack
asm.emitMOV_Reg_RegInd(ECX, SP);
} else {
// load object from stack
asm.emitMOV_Reg_RegInd_Quad(ECX, SP);
}
// jump forward if ECX == 0
ForwardReference isNull = asm.forwardJECXZ();
// S0 = TIB of object
asm.baselineEmitLoadTIB(S0, ECX);
// S0 = superclass IDs
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));
}
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);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(LGT);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
fr.resolve(asm);
}
// Load id from display at required depth and compare against target id.
asm.emitMOVZX_Reg_RegDisp_Word(S0, S0, Offset.fromIntZeroExtend(LHSDepth << LOG_BYTES_IN_SHORT));
asm.emitCMP_Reg_Imm(S0, LHSId);
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(EQ);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
fr.resolve(asm);
isNull.resolve(asm);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_f2i.
@Override
protected void emit_f2i() {
if (SSE2_BASE) {
// Set up value in XMM0
asm.emitMOVSS_Reg_RegInd(XMM0, SP);
// adjust = 0
asm.emitXOR_Reg_Reg(T1, T1);
// result = 0
asm.emitXOR_Reg_Reg(T0, T0);
// value cmp maxint
asm.generateJTOCcmpFloat(XMM0, Entrypoints.maxintFloatField.getOffset());
// if NaN goto fr1
ForwardReference fr1 = asm.forwardJcc(PE);
// T1 = (value >= maxint) ? 1 : 0;
asm.emitSET_Cond_Reg_Byte(LGE, T1);
// T0 = (int)value, or 0x80000000 if value > maxint
asm.emitCVTTSS2SI_Reg_Reg(T0, XMM0);
// T0 = T0 - T1, ie fix max int case
asm.emitSUB_Reg_Reg(T0, T1);
fr1.resolve(asm);
// push result
asm.emitMOV_RegInd_Reg(SP, T0);
} else {
// TODO: use x87 operations to do this conversion inline taking care of
// the boundary cases that differ between x87 and Java
// (1) 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]);
}
// (2) Push arg to C function
asm.emitPUSH_RegDisp(SP, off);
// (3) invoke C function through bootrecord
asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
asm.emitCALL_RegDisp(S0, Entrypoints.sysFloatToIntIPField.getOffset());
// (4) pop argument;
asm.emitPOP_Reg(S0);
// (5) restore RVM nonvolatiles
for (int i = numNonVols - 1; i >= 0; i--) {
asm.emitPOP_Reg(NONVOLATILE_GPRS[i]);
}
// (6) put result on expression stack
asm.emitMOV_RegInd_Reg(SP, T0);
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lmul.
@Override
protected void emit_lmul() {
if (VM.BuildFor64Addr) {
// the long value
asm.emitPOP_Reg(T0);
// throw away slot
asm.emitPOP_Reg(S0);
asm.emitIMUL2_Reg_RegInd_Quad(T0, SP);
asm.emitMOV_RegInd_Reg_Quad(SP, T0);
} else {
// value2.low <-- ESP
if (VM.VerifyAssertions)
VM._assert(S0 != EAX);
if (VM.VerifyAssertions)
VM._assert(S0 != EDX);
// EAX = multiplicand low; SP changed!
asm.emitPOP_Reg(EAX);
// EDX = multiplicand high
asm.emitPOP_Reg(EDX);
// stack: value1.high = mulitplier
// value1.low <-- ESP
// value2.high = multiplicand
// value2.low
// S0 = multiplier high
asm.emitMOV_Reg_RegDisp(S0, SP, ONE_SLOT);
// is one operand > 2^32 ?
asm.emitOR_Reg_Reg(EDX, S0);
// EDX = multiplier low
asm.emitMOV_Reg_RegInd(EDX, SP);
// Jump if we need a 64bit multiply
ForwardReference fr1 = asm.forwardJcc(NE);
// EDX:EAX = 32bit multiply of multiplier and multiplicand low
asm.emitMUL_Reg_Reg(EAX, EDX);
// Jump over 64bit multiply
ForwardReference fr2 = asm.forwardJMP();
// Start of 64bit multiply
fr1.resolve(asm);
// EDX = multiplicand high * multiplier low
asm.emitIMUL2_Reg_RegDisp(EDX, SP, MINUS_ONE_SLOT);
// S0 = multiplier high * multiplicand low
asm.emitIMUL2_Reg_Reg(S0, EAX);
// S0 = S0 + EDX
asm.emitADD_Reg_Reg(S0, EDX);
// EDX:EAX = 32bit multiply of multiplier and multiplicand low
asm.emitMUL_Reg_RegInd(EAX, SP);
// EDX = EDX + S0
asm.emitADD_Reg_Reg(EDX, S0);
// Finish up
fr2.resolve(asm);
// store EDX:EAX to stack
asm.emitMOV_RegDisp_Reg(SP, ONE_SLOT, EDX);
asm.emitMOV_RegInd_Reg(SP, EAX);
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_instanceof_resolvedInterface.
@Override
protected void emit_instanceof_resolvedInterface(RVMClass type) {
int interfaceIndex = type.getDoesImplementIndex();
int interfaceMask = type.getDoesImplementBitMask();
// load object from stack
asm.emitPOP_Reg(ECX);
// test for null
ForwardReference isNull = asm.forwardJECXZ();
// S0 = TIB of object
asm.baselineEmitLoadTIB(S0, ECX);
// S0 = implements bit vector
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
} else {
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
}
ForwardReference outOfBounds = null;
if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
// must do arraybounds check of implements bit vector
if (ARRAY_LENGTH_BYTES == 4) {
asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
} else {
asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
}
outOfBounds = asm.forwardJcc(LLE);
}
// Test the implements bit and push true if it is set
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
ForwardReference notMatched = asm.forwardJcc(EQ);
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_lshr.
@Override
protected void emit_lshr() {
if (VM.BuildFor32Addr) {
// ECX is constrained to be the shift count
if (VM.VerifyAssertions)
VM._assert(ECX != T0);
if (VM.VerifyAssertions)
VM._assert(ECX != T1);
// shift amount (6 bits)
asm.emitPOP_Reg(ECX);
// pop low half
asm.emitPOP_Reg(T0);
// pop high half
asm.emitPOP_Reg(T1);
asm.emitAND_Reg_Imm(ECX, 0x3F);
asm.emitCMP_Reg_Imm(ECX, 32);
ForwardReference fr1 = asm.forwardJcc(LT);
// low half = high half
asm.emitMOV_Reg_Reg(T0, T1);
// high half = sign extension of low half
asm.emitSAR_Reg_Imm(T1, 31);
fr1.resolve(asm);
// shift low half, filling from high
asm.emitSHRD_Reg_Reg_Reg(T0, T1, ECX);
// shift high half
asm.emitSAR_Reg_Reg(T1, ECX);
// push high half
asm.emitPUSH_Reg(T1);
// push low half
asm.emitPUSH_Reg(T0);
} else {
asm.emitPOP_Reg(ECX);
asm.emitSAR_RegInd_Reg_Quad(SP, ECX);
}
}
Aggregations