Search in sources :

Example 6 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emitDynamicLinkingSequence.

/**
 * Emit dynamic linking sequence placing the offset of the given member in reg
 * @param asm assembler to generate code into
 * @param reg register to hold offset to method
 * @param ref method reference to be resolved
 * @param couldBeZero could the value in the offsets table require resolving
 */
static void emitDynamicLinkingSequence(Assembler asm, GPR reg, MemberReference ref, boolean couldBeZero) {
    int memberId = ref.getId();
    Offset memberOffset = Offset.fromIntZeroExtend(memberId << 2);
    Offset tableOffset = Entrypoints.memberOffsetsField.getOffset();
    if (couldBeZero) {
        // branch here after dynamic class loading
        int retryLabel = asm.getMachineCodeIndex();
        // reg is offsets table
        asm.generateJTOCloadWord(reg, tableOffset);
        if (VM.BuildFor32Addr) {
            // reg is offset of member, or 0 if member's class isn't loaded
            asm.emitMOV_Reg_RegDisp(reg, reg, memberOffset);
        } else {
            // reg is offset of member, or 0 if member's class isn't loaded
            asm.emitMOVSXDQ_Reg_RegDisp(reg, reg, memberOffset);
        }
        if (NEEDS_DYNAMIC_LINK == 0) {
            // reg ?= NEEDS_DYNAMIC_LINK, is field's class loaded?
            asm.emitTEST_Reg_Reg(reg, reg);
        } else {
            // reg ?= NEEDS_DYNAMIC_LINK, is field's class loaded?
            asm.emitCMP_Reg_Imm(reg, NEEDS_DYNAMIC_LINK);
        }
        // if so, skip call instructions
        ForwardReference fr = asm.forwardJcc(NE);
        // pass member's dictId
        asm.emitPUSH_Imm(memberId);
        // pass 1 parameter word
        genParameterRegisterLoad(asm, 1);
        Offset resolverOffset = Entrypoints.resolveMemberMethod.getOffset();
        // does class loading as sideffect
        asm.generateJTOCcall(resolverOffset);
        // reload reg with valid value
        asm.emitJMP_Imm(retryLabel);
        // come from Jcc above.
        fr.resolve(asm);
    } else {
        // reg is offsets table
        asm.generateJTOCloadWord(reg, tableOffset);
        if (VM.BuildFor32Addr) {
            // reg is offset of member
            asm.emitMOV_Reg_RegDisp(reg, reg, memberOffset);
        } else {
            // reg is offset of member
            asm.emitMOVSXDQ_Reg_RegDisp(reg, reg, memberOffset);
        }
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Offset(org.vmmagic.unboxed.Offset)

Example 7 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_f2l.

@Override
protected void emit_f2l() {
    if (VM.BuildFor32Addr) {
        // TODO: SSE3 has a FISTTP instruction that stores the value with truncation
        // meaning the FPSCW can be left alone
        // Setup value into FP1
        asm.emitFLD_Reg_RegInd(FP0, SP);
        // Setup maxlong into FP0
        asm.emitFLD_Reg_Abs(FP0, Magic.getTocPointer().plus(Entrypoints.maxlongFloatField.getOffset()));
        // if value > maxlong or NaN goto fr1; FP0 = value
        asm.emitFUCOMIP_Reg_Reg(FP0, FP1);
        ForwardReference fr1 = asm.forwardJcc(LLE);
        // Normally the status and control word rounds numbers, but for conversion
        // to an integer/long value we want truncation. We therefore save the FPSCW,
        // set it to truncation perform operation then restore
        // Grow the stack
        adjustStack(-WORDSIZE, true);
        // [SP-4] = fpscw
        asm.emitFNSTCW_RegDisp(SP, MINUS_ONE_SLOT);
        // EAX = fpscw
        asm.emitMOVZX_Reg_RegDisp_Word(T0, SP, MINUS_ONE_SLOT);
        // EAX = FPSCW in truncate mode
        asm.emitOR_Reg_Imm(T0, 0xC00);
        // [SP] = new fpscw value
        asm.emitMOV_RegInd_Reg(SP, T0);
        // Set FPSCW
        asm.emitFLDCW_RegInd(SP);
        // Store 64bit long
        asm.emitFISTP_RegInd_Reg_Quad(SP, FP0);
        // Restore FPSCW
        asm.emitFLDCW_RegDisp(SP, MINUS_ONE_SLOT);
        ForwardReference fr2 = asm.forwardJMP();
        fr1.resolve(asm);
        // pop FPU*1
        asm.emitFSTP_Reg_Reg(FP0, FP0);
        // if value == NaN goto fr3
        ForwardReference fr3 = asm.forwardJcc(PE);
        asm.emitMOV_RegInd_Imm(SP, 0x7FFFFFFF);
        asm.emitPUSH_Imm(-1);
        ForwardReference fr4 = asm.forwardJMP();
        fr3.resolve(asm);
        asm.emitMOV_RegInd_Imm(SP, 0);
        asm.emitPUSH_Imm(0);
        fr2.resolve(asm);
        fr4.resolve(asm);
    } else {
        // 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 maxlong
        asm.generateJTOCcmpFloat(XMM0, Entrypoints.maxlongFloatField.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_Quad(T0, XMM0);
        // T0 = T0 - T1, ie fix max long case
        asm.emitSUB_Reg_Reg_Quad(T0, T1);
        fr1.resolve(asm);
        // push result
        asm.emitPUSH_Reg(T0);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 8 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_checkcast_final.

@Override
protected void emit_checkcast_final(RVMType type) {
    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();
    // TIB of object
    asm.baselineEmitLoadTIB(S0, ECX);
    asm.generateJTOCcmpWord(S0, type.getTibOffset());
    asm.emitBranchLikelyNextInstruction();
    ForwardReference fr = asm.forwardJcc(EQ);
    asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
    fr.resolve(asm);
    isNull.resolve(asm);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 9 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference 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 10 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference 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)

Aggregations

ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)71 Offset (org.vmmagic.unboxed.Offset)13 TypeReference (org.jikesrvm.classloader.TypeReference)5 RVMClass (org.jikesrvm.classloader.RVMClass)4 Assembler (org.jikesrvm.compilers.common.assembler.ppc.Assembler)4 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 GPR (org.jikesrvm.ia32.RegisterConstants.GPR)3 XMM (org.jikesrvm.ia32.RegisterConstants.XMM)3 InterfaceMethodSignature (org.jikesrvm.classloader.InterfaceMethodSignature)2 RVMArray (org.jikesrvm.classloader.RVMArray)2 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)2 FloatingPointMachineRegister (org.jikesrvm.ia32.RegisterConstants.FloatingPointMachineRegister)2 JNICompiledMethod (org.jikesrvm.jni.JNICompiledMethod)2 Entrypoint (org.vmmagic.pragma.Entrypoint)2 Inline (org.vmmagic.pragma.Inline)2 Address (org.vmmagic.unboxed.Address)2 Atom (org.jikesrvm.classloader.Atom)1 FieldReference (org.jikesrvm.classloader.FieldReference)1 MethodReference (org.jikesrvm.classloader.MethodReference)1 RVMType (org.jikesrvm.classloader.RVMType)1