use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_regular_DFcmpGL.
@Override
protected void emit_regular_DFcmpGL(boolean single, boolean unorderedGT) {
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 (unorderedGT) {
// result/T0 = 1 (high bits are 0)
asm.emitMOV_Reg_Imm(T0, 1);
} else {
// clear high bits of result
asm.emitXOR_Reg_Reg(T0, T0);
}
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);
}
ForwardReference fr1 = null;
if (unorderedGT) {
// if unordered goto push result (1)
fr1 = asm.forwardJcc(PE);
}
// T0 = XMM0 > XMM1 ? 1 : 0
asm.emitSET_Cond_Reg_Byte(LGT, T0);
// T0 -= XMM0 < or unordered XMM1 ? 1 : 0
asm.emitSBB_Reg_Imm(T0, 0);
if (unorderedGT) {
fr1.resolve(asm);
}
// push result on stack
asm.emitPUSH_Reg(T0);
if (!SSE2_BASE) {
// pop FPU*1
asm.emitFSTP_Reg_Reg(FP0, FP0);
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_lushr.
@Override
protected void emit_lushr() {
if (VM.BuildFor32Addr) {
if (SSE2_BASE) {
// shift amount (6 bits)
asm.emitPOP_Reg(T0);
// XMM1 <- [SP]
asm.emitMOVQ_Reg_RegInd(XMM1, SP);
// mask to 6bits
asm.emitAND_Reg_Imm(T0, 0x3F);
// XMM0 <- T0
asm.emitMOVD_Reg_Reg(XMM0, T0);
// XMM1 >>>= XMM0
asm.emitPSRLQ_Reg_Reg(XMM1, XMM0);
// [SP] <- XMM1
asm.emitMOVQ_RegInd_Reg(SP, XMM1);
} else {
// 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 = 0
asm.emitXOR_Reg_Reg(T1, T1);
fr1.resolve(asm);
// shift low half, filling from high
asm.emitSHRD_Reg_Reg_Reg(T0, T1, ECX);
// shift high half
asm.emitSHR_Reg_Reg(T1, ECX);
// push high half
asm.emitPUSH_Reg(T1);
// push low half
asm.emitPUSH_Reg(T0);
}
} else {
asm.emitPOP_Reg(ECX);
asm.emitSHR_RegInd_Reg_Quad(SP, ECX);
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genNullCheck.
/**
* Generate an explicit null check (compare to zero).
*
* @param asm the assembler to generate into
* @param objRefReg the register containing the reference
*/
@Inline
private static void genNullCheck(Assembler asm, GPR objRefReg) {
// compare to zero
asm.emitTEST_Reg_Reg(objRefReg, objRefReg);
// Jmp around trap if index is OK
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(NE);
// trap
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_NULL_POINTER + RVM_TRAP_BASE);
fr.resolve(asm);
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_checkcast_resolvedInterface.
@Override
protected void emit_checkcast_resolvedInterface(RVMClass type) {
int interfaceIndex = type.getDoesImplementIndex();
int interfaceMask = type.getDoesImplementBitMask();
if (VM.BuildFor32Addr) {
// load object from stack into ECX
asm.emitMOV_Reg_RegInd(ECX, SP);
} else {
// load object from stack into ECX
asm.emitMOV_Reg_RegInd_Quad(ECX, SP);
}
// forward branch if ECX == 0
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));
}
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);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(LGT);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
fr.resolve(asm);
}
// Test the appropriate bit and if set, branch around another trap imm
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(NE);
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_invokeinterface.
@Override
protected void emit_invokeinterface(MethodReference methodRef) {
// +1 for "this" parameter
final int count = methodRef.getParameterWords() + 1;
RVMMethod resolvedMethod = null;
resolvedMethod = methodRef.peekInterfaceMethod();
// (1) Emit dynamic type checking sequence if required to do so inline.
if (VM.BuildForIMTInterfaceInvocation) {
if (methodRef.isMiranda()) {
// TODO: It's not entirely clear that we can just assume that
// the class actually implements the interface.
// However, we don't know what interface we need to be checking
// so there doesn't appear to be much else we can do here.
} else {
if (resolvedMethod == null) {
// Can't successfully resolve it at compile time.
// Call uncommon case typechecking routine to do the right thing when this code actually executes.
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
// push dict id of target
asm.emitPUSH_Imm(methodRef.getId());
// push "this"
asm.emitPUSH_Reg(T1);
// pass 2 parameter word
genParameterRegisterLoad(asm, 2);
// check that "this" class implements the interface
asm.generateJTOCcall(Entrypoints.unresolvedInvokeinterfaceImplementsTestMethod.getOffset());
} else {
RVMClass interfaceClass = resolvedMethod.getDeclaringClass();
int interfaceIndex = interfaceClass.getDoesImplementIndex();
int interfaceMask = interfaceClass.getDoesImplementBitMask();
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
// S0 = tib of "this" object
asm.baselineEmitLoadTIB(S0, T1);
if (VM.BuildFor32Addr) {
// implements bit vector
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
} else {
// implements bit vector
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
}
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);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(LGT);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
fr.resolve(asm);
}
// Test the appropriate bit and if set, branch around another trap imm
if (interfaceIndex == 0) {
asm.emitTEST_RegInd_Imm(S0, interfaceMask);
} else {
asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
}
asm.emitBranchLikelyNextInstruction();
ForwardReference fr = asm.forwardJcc(NE);
asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
fr.resolve(asm);
}
}
}
// (2) Emit interface invocation sequence.
if (VM.BuildForIMTInterfaceInvocation) {
InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(methodRef);
// squirrel away signature ID
Offset offset = ArchEntrypoints.hiddenSignatureIdField.getOffset();
asm.emitMOV_RegDisp_Imm(THREAD_REGISTER, offset, sig.getId());
// T1 = "this" object
stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
asm.baselineEmitLoadTIB(S0, T1);
// Load the IMT Base into S0
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
} else {
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
}
genParameterRegisterLoad(methodRef, true);
// the interface call
asm.emitCALL_RegDisp(S0, sig.getIMTOffset());
} else {
int itableIndex = -1;
if (VM.BuildForITableInterfaceInvocation && resolvedMethod != null) {
// get the index of the method in the Itable
itableIndex = InterfaceInvocation.getITableIndex(resolvedMethod.getDeclaringClass(), methodRef.getName(), methodRef.getDescriptor());
}
if (itableIndex == -1) {
// itable index is not known at compile-time.
// call "invokeInterface" to resolve object + method id into
// method address
int methodRefId = methodRef.getId();
// "this" parameter is obj
if (count == 1) {
asm.emitPUSH_RegInd(SP);
} else {
asm.emitPUSH_RegDisp(SP, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
}
// id of method to call
asm.emitPUSH_Imm(methodRefId);
// pass 2 parameter words
genParameterRegisterLoad(asm, 2);
// invokeinterface(obj, id) returns address to call
asm.generateJTOCcall(Entrypoints.invokeInterfaceMethod.getOffset());
if (VM.BuildFor32Addr) {
// S0 has address of method
asm.emitMOV_Reg_Reg(S0, T0);
} else {
// S0 has address of method
asm.emitMOV_Reg_Reg_Quad(S0, T0);
}
genParameterRegisterLoad(methodRef, true);
// the interface method (its parameters are on stack)
asm.emitCALL_Reg(S0);
} else {
// itable index is known at compile-time.
// call "findITable" to resolve object + interface id into
// itable address
// T0 = "this" object
stackMoveHelper(T0, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
asm.baselineEmitLoadTIB(S0, T0);
asm.emitPUSH_Reg(S0);
// interface id
asm.emitPUSH_Imm(resolvedMethod.getDeclaringClass().getInterfaceId());
// pass 2 parameter words
genParameterRegisterLoad(asm, 2);
// findItableOffset(tib, id) returns iTable
asm.generateJTOCcall(Entrypoints.findItableMethod.getOffset());
if (VM.BuildFor32Addr) {
// S0 has iTable
asm.emitMOV_Reg_Reg(S0, T0);
} else {
// S0 has iTable
asm.emitMOV_Reg_Reg_Quad(S0, T0);
}
genParameterRegisterLoad(methodRef, true);
// the interface call
asm.emitCALL_RegDisp(S0, Offset.fromIntZeroExtend(itableIndex << LG_WORDSIZE));
}
}
genResultRegisterUnload(methodRef);
}
Aggregations