Search in sources :

Example 41 with Offset

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();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) Offset(org.vmmagic.unboxed.Offset)

Example 42 with Offset

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);
}
Also used : Offset(org.vmmagic.unboxed.Offset)

Example 43 with Offset

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)));
}
Also used : GPR(org.jikesrvm.ia32.RegisterConstants.GPR) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 44 with Offset

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);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Offset(org.vmmagic.unboxed.Offset)

Example 45 with Offset

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);
        }
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Aggregations

Offset (org.vmmagic.unboxed.Offset)215 Address (org.vmmagic.unboxed.Address)48 Inline (org.vmmagic.pragma.Inline)38 Entrypoint (org.vmmagic.pragma.Entrypoint)32 ObjectReference (org.vmmagic.unboxed.ObjectReference)21 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)20 TypeReference (org.jikesrvm.classloader.TypeReference)17 RVMField (org.jikesrvm.classloader.RVMField)14 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)13 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)13 NoInline (org.vmmagic.pragma.NoInline)13 RVMMethod (org.jikesrvm.classloader.RVMMethod)11 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)10 Word (org.vmmagic.unboxed.Word)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)9 RVMType (org.jikesrvm.classloader.RVMType)8 Register (org.jikesrvm.compilers.opt.ir.Register)8 RVMClass (org.jikesrvm.classloader.RVMClass)7 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7