use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_putstatic.
@Override
protected void emit_resolved_putstatic(FieldReference fieldRef) {
RVMField field = fieldRef.peekResolvedField();
Offset fieldOffset = field.getOffset();
if (NEEDS_OBJECT_PUTSTATIC_BARRIER && field.isReferenceType() && !field.isUntraced()) {
Barriers.compilePutstaticBarrierImm(asm, fieldOffset, fieldRef.getId());
} else {
if (field.getSize() <= BYTES_IN_INT) {
// field is one word
if (VM.BuildFor32Addr) {
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset));
} else {
asm.emitPOP_Reg(T1);
asm.generateJTOCstoreInt(fieldOffset, T1);
}
} else {
// field is two words (double or long)
if (VM.VerifyAssertions)
VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
if (VM.BuildFor32Addr) {
// JMM: we need to guarantee atomic access for volatile fields
if (field.isVolatile()) {
if (SSE2_BASE) {
asm.emitMOVQ_Reg_RegInd(XMM0, SP);
asm.emitMOVQ_Abs_Reg(Magic.getTocPointer().plus(fieldOffset), XMM0);
} else {
asm.emitFLD_Reg_RegInd_Quad(FP0, SP);
asm.emitFSTP_Abs_Reg_Quad(Magic.getTocPointer().plus(fieldOffset), FP0);
}
adjustStack(2 * WORDSIZE, false);
} else {
// store low part
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset));
// store high part
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset).plus(WORDSIZE));
}
} else {
asm.generateJTOCpop(fieldOffset);
if (fieldRef.getNumberOfStackSlots() != 1) {
adjustStack(WORDSIZE, true);
}
}
}
}
if (field.isVolatile()) {
asm.emitMFENCE();
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_new.
/*
* other object model functions
*/
@Override
protected void emit_resolved_new(RVMClass typeRef) {
int instanceSize = typeRef.getInstanceSize();
Offset tibOffset = typeRef.getTibOffset();
int whichAllocator = MemoryManager.pickAllocator(typeRef, method);
int align = ObjectModel.getAlignment(typeRef);
int offset = ObjectModel.getOffsetForAlignment(typeRef, false);
int site = MemoryManager.getAllocationSite(true);
asm.emitPUSH_Imm(instanceSize);
// put tib on stack
asm.generateJTOCpush(tibOffset);
// does the class have a finalizer?
asm.emitPUSH_Imm(typeRef.hasFinalizer() ? 1 : 0);
asm.emitPUSH_Imm(whichAllocator);
asm.emitPUSH_Imm(align);
asm.emitPUSH_Imm(offset);
asm.emitPUSH_Imm(site);
// pass 7 parameter words
genParameterRegisterLoad(asm, 7);
asm.generateJTOCcall(Entrypoints.resolvedNewScalarMethod.getOffset());
asm.emitPUSH_Reg(T0);
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genParameterRegisterLoad.
/**
* Copy parameters from operand stack into registers.
* Assumption: parameters are layed out on the stack in order
* with SP pointing to the last parameter.
* Also, this method is called before the generation of an explicit method call.
* @param method is the method to be called.
* @param hasThisParam is the method virtual?
*/
protected void genParameterRegisterLoad(MethodReference method, boolean hasThisParam) {
int max = NUM_PARAMETER_GPRS + NUM_PARAMETER_FPRS;
// quit looking when all registers are full
if (max == 0)
return;
// number of general purpose registers filled
int gpr = 0;
// number of floating point registers filled
int fpr = 0;
// next GPR to get a parameter
GPR T = T0;
int params = method.getParameterWords() + (hasThisParam ? 1 : 0);
// stack offset of first parameter word
Offset offset = Offset.fromIntSignExtend((params - 1) << LG_WORDSIZE);
if (hasThisParam) {
if (gpr < NUM_PARAMETER_GPRS) {
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
}
for (TypeReference type : method.getParameterTypes()) {
// quit looking when all registers are full
if (max == 0)
return;
TypeReference t = type;
if (t.isLongType()) {
if (gpr < NUM_PARAMETER_GPRS) {
if (WORDSIZE == 4) {
// lo register := hi mem (== hi order word)
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
if (gpr < NUM_PARAMETER_GPRS) {
// hi register := lo mem (== lo order word)
stackMoveHelper(T, offset.minus(WORDSIZE));
gpr++;
max--;
}
} else {
// initially offset will point at junk word, move down and over
stackMoveHelper(T, offset.minus(WORDSIZE));
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
}
offset = offset.minus(2 * WORDSIZE);
} else if (t.isFloatType()) {
if (fpr < NUM_PARAMETER_FPRS) {
if (SSE2_FULL) {
asm.emitMOVSS_Reg_RegDisp(XMM.lookup(fpr), SP, offset);
} else {
asm.emitFLD_Reg_RegDisp(FP0, SP, offset);
}
fpr++;
max--;
}
offset = offset.minus(WORDSIZE);
} else if (t.isDoubleType()) {
if (fpr < NUM_PARAMETER_FPRS) {
if (SSE2_FULL) {
asm.emitMOVSD_Reg_RegDisp(XMM.lookup(fpr), SP, offset.minus(WORDSIZE));
} else {
asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, offset.minus(WORDSIZE));
}
fpr++;
max--;
}
offset = offset.minus(2 * WORDSIZE);
} else if (t.isReferenceType() || t.isWordLikeType()) {
if (gpr < NUM_PARAMETER_GPRS) {
stackMoveHelper(T, offset);
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
} else {
// t is object, int, short, char, byte, or boolean
if (gpr < NUM_PARAMETER_GPRS) {
if (offset.isZero()) {
asm.emitMOV_Reg_RegInd(T, SP);
} else {
asm.emitMOV_Reg_RegDisp(T, SP, offset);
}
// at most 2 parameters can be passed in general purpose registers
T = T1;
gpr++;
max--;
}
offset = offset.minus(WORDSIZE);
}
}
if (VM.VerifyAssertions)
VM._assert(offset.EQ(Offset.fromIntSignExtend(-WORDSIZE)));
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_d2i.
@Override
protected void emit_d2i() {
if (SSE2_BASE) {
// Set up value in XMM0
asm.emitMOVSD_Reg_RegInd(XMM0, SP);
// throw away slots
adjustStack(2 * WORDSIZE, true);
// adjust = 0
asm.emitXOR_Reg_Reg(T1, T1);
// result = 0
asm.emitXOR_Reg_Reg(T0, T0);
// value cmp maxint
asm.generateJTOCcmpDouble(XMM0, Entrypoints.maxintField.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.emitCVTTSD2SI_Reg_Reg(T0, XMM0);
// T0 = T0 - T1, ie fix max int case
asm.emitSUB_Reg_Reg(T0, T1);
fr1.resolve(asm);
// push result
asm.emitPUSH_Reg(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 args to C function (reversed)
asm.emitPUSH_RegDisp(SP, off.plus(4));
asm.emitPUSH_RegDisp(SP, off.plus(4));
// (3) invoke C function through bootrecord
asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
asm.emitCALL_RegDisp(S0, Entrypoints.sysDoubleToIntIPField.getOffset());
// (4) pop arguments
asm.emitPOP_Reg(S0);
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
// throw away slot
adjustStack(WORDSIZE, true);
asm.emitMOV_RegInd_Reg(SP, T0);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_getfield.
@Override
protected void emit_resolved_getfield(FieldReference fieldRef) {
TypeReference fieldType = fieldRef.getFieldContentsType();
RVMField field = fieldRef.peekResolvedField();
Offset fieldOffset = field.getOffset();
if (field.isReferenceType()) {
// 32/64bit reference load
if (NEEDS_OBJECT_GETFIELD_BARRIER && !field.isUntraced()) {
Barriers.compileGetfieldBarrierImm(asm, fieldOffset, fieldRef.getId());
} else {
// T0 is object reference
asm.emitPOP_Reg(T0);
// place field value on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
}
} else if (fieldType.isBooleanType()) {
// 8bit unsigned load
// S0 is object reference
asm.emitPOP_Reg(S0);
// T0 is field value
asm.emitMOVZX_Reg_RegDisp_Byte(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isByteType()) {
// 8bit signed load
// S0 is object reference
asm.emitPOP_Reg(S0);
// T0 is field value
asm.emitMOVSX_Reg_RegDisp_Byte(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isShortType()) {
// 16bit signed load
// S0 is object reference
asm.emitPOP_Reg(S0);
// T0 is field value
asm.emitMOVSX_Reg_RegDisp_Word(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isCharType()) {
// 16bit unsigned load
// S0 is object reference
asm.emitPOP_Reg(S0);
// T0 is field value
asm.emitMOVZX_Reg_RegDisp_Word(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isIntType() || fieldType.isFloatType() || (VM.BuildFor32Addr && fieldType.isWordLikeType())) {
// 32bit load
// S0 is object reference
asm.emitPOP_Reg(S0);
if (VM.BuildFor32Addr) {
// place value on stack
asm.emitPUSH_RegDisp(S0, fieldOffset);
} else {
// T0 is field value
asm.emitMOV_Reg_RegDisp(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
}
} else {
// 64bit load
if (VM.VerifyAssertions) {
VM._assert(fieldType.isLongType() || fieldType.isDoubleType() || (VM.BuildFor64Addr && fieldType.isWordLikeType()));
}
// T0 is object reference
asm.emitPOP_Reg(T0);
if (VM.BuildFor32Addr && field.isVolatile()) {
// as a slightly optimized Intel memory copy using the FPU
if (SSE2_BASE) {
// XMM0 is field value
asm.emitMOVQ_Reg_RegDisp(XMM0, T0, fieldOffset);
// adjust stack down to hold 64bit value
adjustStack(-2 * WORDSIZE, true);
// replace reference with value on stack
asm.emitMOVQ_RegInd_Reg(SP, XMM0);
} else {
// FP0 is field value
asm.emitFLD_Reg_RegDisp_Quad(FP0, T0, fieldOffset);
// adjust stack down to hold 64bit value
adjustStack(-2 * WORDSIZE, true);
// replace reference with value on stack
asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);
}
} else if (VM.BuildFor32Addr && !field.isVolatile()) {
// place high half on stack
asm.emitPUSH_RegDisp(T0, fieldOffset.plus(ONE_SLOT));
// place low half on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
} else {
if (!fieldType.isWordLikeType()) {
// add empty slot
adjustStack(-WORDSIZE, true);
}
// place value on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
}
}
}
Aggregations