Search in sources :

Example 36 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_lstore.

@Override
protected void emit_lstore(int index) {
    try {
        if (VM.BuildFor32Addr) {
            // pop computes EA after ESP has moved by 4!
            Offset offset = localOffset(index + 1).minus(WORDSIZE);
            // high part
            asm.emitPOP_RegDisp(ESP, offset);
            // low part (ESP has moved by 4!!)
            asm.emitPOP_RegDisp(ESP, offset);
        } else {
            Offset offset = localOffset(index + 1).minus(WORDSIZE);
            asm.emitPOP_RegDisp(ESP, offset);
            // throw away top word
            adjustStack(WORDSIZE, true);
        }
    } catch (UnreachableBytecodeException e) {
        asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
    }
}
Also used : Offset(org.vmmagic.unboxed.Offset)

Example 37 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genPrologue.

// ----------------//
// implementation //
// ----------------//
private void genPrologue() {
    if (shouldPrint)
        asm.comment("prologue for " + method);
    if (klass.hasBridgeFromNativeAnnotation()) {
        // replace the normal prologue with a special prolog
        JNICompiler.generateGlueCodeForJNIMethod(asm, method, compiledMethod.getId());
        // set some constants for the code generation of the rest of the method
        // firstLocalOffset is shifted down because more registers are saved
        firstLocalOffset = STACKFRAME_BODY_OFFSET.minus(JNICompiler.SAVED_GPRS_FOR_JNI << LG_WORDSIZE);
    } else {
        genStackOverflowCheck();
        /* paramaters are on the stack and/or in registers;  There is space
       * on the stack for all the paramaters;  Parameter slots in the
       * stack are such that the first paramater has the higher address,
       * i.e., it pushed below all the other paramaters;  The return
       * address is the topmost entry on the stack.  The frame pointer
       * still addresses the previous frame.
       * The first word of the header, currently addressed by the stack
       * pointer, contains the return address.
       */
        /* establish a new frame:
       * push the caller's frame pointer in the stack, and
       * reset the frame pointer to the current stack top,
       * ie, the frame pointer addresses directly the word
       * that contains the previous frame pointer.
       * The second word of the header contains the frame
       * point of the caller.
       * The third word of the header contains the compiled method id of the called method.
       */
        // store caller's frame pointer
        asm.emitPUSH_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
        // establish new frame
        if (VM.BuildFor32Addr) {
            asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), SP);
        } else {
            asm.emitMOV_RegDisp_Reg_Quad(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), SP);
        }
        /*
       * NOTE: until the end of the prologue SP holds the framepointer.
       */
        if (VM.VerifyAssertions)
            VM._assert(STACKFRAME_METHOD_ID_OFFSET.toInt() == -WORDSIZE);
        asm.emitPUSH_Imm(compiledMethod.getId());
        /*
       * save registers
       */
        if (VM.VerifyAssertions)
            VM._assert(EDI_SAVE_OFFSET.toInt() == -2 * WORDSIZE);
        // save nonvolatile EDI register
        asm.emitPUSH_Reg(EDI);
        if (VM.VerifyAssertions)
            VM._assert(EBX_SAVE_OFFSET.toInt() == -3 * WORDSIZE);
        // save nonvolatile EBX register
        asm.emitPUSH_Reg(EBX);
        int savedRegistersSize;
        if (method.hasBaselineSaveLSRegistersAnnotation()) {
            if (VM.VerifyAssertions)
                VM._assert(EBP_SAVE_OFFSET.toInt() == -4 * WORDSIZE);
            asm.emitPUSH_Reg(EBP);
            savedRegistersSize = SAVED_GPRS_FOR_SAVE_LS_REGISTERS << LG_WORDSIZE;
        } else {
            // default
            savedRegistersSize = SAVED_GPRS << LG_WORDSIZE;
        }
        // TODO: (SJF): When I try to reclaim ESI, I may have to save it here?
        if (klass.hasDynamicBridgeAnnotation()) {
            savedRegistersSize += 2 << LG_WORDSIZE;
            if (VM.VerifyAssertions)
                VM._assert(T0_SAVE_OFFSET.toInt() == -4 * WORDSIZE);
            asm.emitPUSH_Reg(T0);
            if (VM.VerifyAssertions)
                VM._assert(T1_SAVE_OFFSET.toInt() == -5 * WORDSIZE);
            asm.emitPUSH_Reg(T1);
            if (SSE2_FULL) {
                // TODO: Store SSE2 Control word?
                // adjust stack to bottom of saved area
                adjustStack(-BASELINE_XMM_STATE_SIZE, true);
                if (VM.VerifyAssertions)
                    VM._assert(XMM_SAVE_OFFSET.toInt() == (-5 * WORDSIZE) - BASELINE_XMM_STATE_SIZE);
                asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(24), XMM3);
                asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(16), XMM2);
                asm.emitMOVQ_RegDisp_Reg(SP, Offset.fromIntSignExtend(8), XMM1);
                asm.emitMOVQ_RegInd_Reg(SP, XMM0);
                savedRegistersSize += BASELINE_XMM_STATE_SIZE;
            } else {
                if (VM.VerifyAssertions)
                    VM._assert(FPU_SAVE_OFFSET.toInt() == (-5 * WORDSIZE) - X87_FPU_STATE_SIZE);
                // adjust stack to bottom of saved area
                adjustStack(-X87_FPU_STATE_SIZE, true);
                asm.emitFNSAVE_RegInd(SP);
                savedRegistersSize += X87_FPU_STATE_SIZE;
            }
        }
        // copy registers to callee's stackframe
        firstLocalOffset = STACKFRAME_BODY_OFFSET.minus(savedRegistersSize);
        Offset firstParameterOffset = Offset.fromIntSignExtend(savedRegistersSize + STACKFRAME_HEADER_SIZE + (parameterWords << LG_WORDSIZE) - WORDSIZE);
        genParameterCopy(firstParameterOffset);
        int emptyStackOffset = (method.getLocalWords() << LG_WORDSIZE) - (parameterWords << LG_WORDSIZE);
        if (emptyStackOffset != 0) {
            // set aside room for non parameter locals
            adjustStack(-emptyStackOffset, true);
        }
        /* defer generating code which may cause GC until
       * locals were initialized. see emit_deferred_prologue
       */
        if (method.isForOsrSpecialization()) {
            return;
        }
        if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
            // use (nonvolatile) EBX to hold base of this method's counter array
            if (NEEDS_OBJECT_ALOAD_BARRIER) {
                asm.generateJTOCpush(Entrypoints.edgeCountersField.getOffset());
                asm.emitPUSH_Imm(getEdgeCounterIndex());
                Barriers.compileArrayLoadBarrier(asm, false);
                if (VM.BuildFor32Addr) {
                    asm.emitMOV_Reg_Reg(EBX, T0);
                } else {
                    asm.emitMOV_Reg_Reg_Quad(EBX, T0);
                }
            } else {
                if (VM.BuildFor32Addr) {
                    asm.emitMOV_Reg_Abs(EBX, Magic.getTocPointer().plus(Entrypoints.edgeCountersField.getOffset()));
                    asm.emitMOV_Reg_RegDisp(EBX, EBX, getEdgeCounterOffset());
                } else {
                    asm.generateJTOCpush(Entrypoints.edgeCountersField.getOffset());
                    asm.emitPOP_Reg(EBX);
                    asm.emitMOV_Reg_RegDisp_Quad(EBX, EBX, getEdgeCounterOffset());
                }
            }
        }
        if (method.isSynchronized())
            genMonitorEnter();
        genThreadSwitchTest(RVMThread.PROLOGUE);
    }
}
Also used : Offset(org.vmmagic.unboxed.Offset)

Example 38 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_lrem.

@Override
protected void emit_lrem() {
    if (VM.BuildFor64Addr) {
        // ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements
        asm.emitPOP_Reg(ECX);
        // throw away slot
        asm.emitPOP_Reg(EAX);
        // EAX is dividend
        asm.emitPOP_Reg(EAX);
        // sign extend EAX into EDX
        asm.emitCDO();
        asm.emitIDIV_Reg_Reg_Quad(EAX, ECX);
        // push result
        asm.emitPUSH_Reg(EDX);
    } else {
        // (1) zero check
        asm.emitMOV_Reg_RegInd(T0, SP);
        asm.emitOR_Reg_RegDisp(T0, SP, ONE_SLOT);
        asm.emitBranchLikelyNextInstruction();
        ForwardReference fr1 = asm.forwardJcc(NE);
        // trap if divisor is 0
        asm.emitINT_Imm(RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO + RVM_TRAP_BASE);
        fr1.resolve(asm);
        // (2) 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]);
        }
        // (3) Push args to C function (reversed)
        asm.emitPUSH_RegDisp(SP, off.plus(4));
        asm.emitPUSH_RegDisp(SP, off.plus(4));
        asm.emitPUSH_RegDisp(SP, off.plus(20));
        asm.emitPUSH_RegDisp(SP, off.plus(20));
        // (4) invoke C function through bootrecord
        asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
        asm.emitCALL_RegDisp(S0, Entrypoints.sysLongRemainderIPField.getOffset());
        // (5) pop space for arguments
        adjustStack(4 * WORDSIZE, true);
        // (6) restore RVM nonvolatiles
        for (int i = numNonVols - 1; i >= 0; i--) {
            asm.emitPOP_Reg(NONVOLATILE_GPRS[i]);
        }
        // (7) pop expression stack
        adjustStack(WORDSIZE * 4, true);
        // (8) push results
        asm.emitPUSH_Reg(T1);
        asm.emitPUSH_Reg(T0);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Offset(org.vmmagic.unboxed.Offset)

Example 39 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_ldiv.

@Override
protected void emit_ldiv() {
    if (VM.BuildFor64Addr) {
        // ECX is divisor; NOTE: can't use symbolic registers because of intel hardware requirements
        asm.emitPOP_Reg(ECX);
        // throw away slot
        asm.emitPOP_Reg(EAX);
        // EAX is dividend
        asm.emitPOP_Reg(EAX);
        // sign extend EAX into EDX
        asm.emitCDO();
        asm.emitIDIV_Reg_Reg_Quad(EAX, ECX);
        // push result
        asm.emitPUSH_Reg(EAX);
    } else {
        // (1) zero check
        asm.emitMOV_Reg_RegInd(T0, SP);
        asm.emitOR_Reg_RegDisp(T0, SP, ONE_SLOT);
        asm.emitBranchLikelyNextInstruction();
        ForwardReference fr1 = asm.forwardJcc(NE);
        // trap if divisor is 0
        asm.emitINT_Imm(RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO + RVM_TRAP_BASE);
        fr1.resolve(asm);
        // (2) 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]);
        }
        // (3) Push args to C function (reversed)
        asm.emitPUSH_RegDisp(SP, off.plus(4));
        asm.emitPUSH_RegDisp(SP, off.plus(4));
        asm.emitPUSH_RegDisp(SP, off.plus(20));
        asm.emitPUSH_RegDisp(SP, off.plus(20));
        // (4) invoke C function through bootrecord
        asm.emitMOV_Reg_Abs(S0, Magic.getTocPointer().plus(Entrypoints.the_boot_recordField.getOffset()));
        asm.emitCALL_RegDisp(S0, Entrypoints.sysLongDivideIPField.getOffset());
        // (5) pop space for arguments
        adjustStack(4 * WORDSIZE, true);
        // (6) restore RVM nonvolatiles
        for (int i = numNonVols - 1; i >= 0; i--) {
            asm.emitPOP_Reg(NONVOLATILE_GPRS[i]);
        }
        // (7) pop expression stack
        adjustStack(WORDSIZE * 4, true);
        // (8) push results
        asm.emitPUSH_Reg(T1);
        asm.emitPUSH_Reg(T0);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Offset(org.vmmagic.unboxed.Offset)

Example 40 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_lload.

@Override
protected void emit_lload(int index) {
    try {
        Offset offset = localOffset(index);
        if (VM.BuildFor32Addr) {
            // high part
            asm.emitPUSH_RegDisp(ESP, offset);
            // low part (ESP has moved by 4!!)
            asm.emitPUSH_RegDisp(ESP, offset);
        } else {
            adjustStack(-WORDSIZE, true);
            asm.emitPUSH_RegDisp(ESP, offset);
        }
    } catch (UnreachableBytecodeException e) {
        asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
    }
}
Also used : 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