Search in sources :

Example 11 with ForwardReference

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

the class BaselineCompilerImpl method emit_d2l.

@Override
protected void emit_d2l() {
    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_Quad(FP0, SP);
        // Setup maxlong into FP0
        asm.emitFLD_Reg_Abs_Quad(FP0, Magic.getTocPointer().plus(Entrypoints.maxlongField.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
        // [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_RegDisp_Imm(SP, ONE_SLOT, 0x7FFFFFFF);
        asm.emitMOV_RegInd_Imm(SP, -1);
        ForwardReference fr4 = asm.forwardJMP();
        fr3.resolve(asm);
        asm.emitMOV_RegDisp_Imm(SP, ONE_SLOT, 0);
        asm.emitMOV_RegInd_Imm(SP, 0);
        fr2.resolve(asm);
        fr4.resolve(asm);
    } else {
        // Set up value in XMM0
        asm.emitMOVSD_Reg_RegInd(XMM0, SP);
        // adjust = 0
        asm.emitXOR_Reg_Reg(T1, T1);
        // result = 0
        asm.emitXOR_Reg_Reg(T0, T0);
        // value cmp maxlong
        asm.generateJTOCcmpDouble(XMM0, Entrypoints.maxlongField.getOffset());
        // if NaN goto fr1
        ForwardReference fr1 = asm.forwardJcc(PE);
        // T1 = (value >= maxlong) ? 1 : 0;
        asm.emitSET_Cond_Reg_Byte(LGE, T1);
        // T0 = (int)value, or 0x80...00 if value > maxlong
        asm.emitCVTTSD2SIQ_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.emitMOV_RegInd_Reg_Quad(SP, T0);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 12 with ForwardReference

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

the class BaselineCompilerImpl method genStackOverflowCheck.

private void genStackOverflowCheck() {
    /*
     * Generate stacklimit check.
     *
     * NOTE: The stack overflow check MUST happen before the frame is created.
     * If the check were to happen after frame creation, the stack pointer
     * could already be well below the stack limit. This would be a problem
     * because the IA32 stack overflow handling code imposes a bound on the
     * difference between the stack pointer and the stack limit.
     *
     * NOTE: Frame sizes for the baseline compiler can get very large because
     * each non-parameter local slot and each slot for the operand stack
     * requires one machine word.
     *
     * The Java Virtual Machine Specification has an overview of the limits for
     * the local words and operand words in section 4.11,
     * "Limitations of the Java Virtual Machine".
     */
    if (isInterruptible) {
        int frameSize = calculateRequiredSpaceForFrame(method);
        // S0<-limit
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_Reg(S0, ESP);
            asm.emitSUB_Reg_Imm(S0, frameSize);
            asm.emitCMP_Reg_RegDisp(S0, TR, Entrypoints.stackLimitField.getOffset());
        } else {
            asm.emitMOV_Reg_Reg_Quad(S0, ESP);
            asm.emitSUB_Reg_Imm_Quad(S0, frameSize);
            asm.emitCMP_Reg_RegDisp_Quad(S0, TR, Entrypoints.stackLimitField.getOffset());
        }
        asm.emitBranchLikelyNextInstruction();
        // Jmp around trap if OK
        ForwardReference fr = asm.forwardJcc(LGT);
        // trap
        asm.emitINT_Imm(RuntimeEntrypoints.TRAP_STACK_OVERFLOW + RVM_TRAP_BASE);
        fr.resolve(asm);
    } else {
    // TODO!! make sure stackframe of uninterruptible method doesn't overflow guard page
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 13 with ForwardReference

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

the class BaselineCompilerImpl method emit_lookupswitch.

/**
 * Emit code to implement the lookupswitch bytecode.
 * Uses linear search, one could use a binary search tree instead,
 * but this is the baseline compiler, so don't worry about it.
 *
 * @param defaultval bcIndex of the default target
 * @param npairs number of pairs in the lookup switch
 */
@Override
protected void emit_lookupswitch(int defaultval, int npairs) {
    asm.emitPOP_Reg(T0);
    for (int i = 0; i < npairs; i++) {
        int match = bcodes.getLookupSwitchValue(i);
        asm.emitCMP_Reg_Imm(T0, match);
        int offset = bcodes.getLookupSwitchOffset(i);
        int bTarget = biStart + offset;
        int mTarget = bytecodeMap[bTarget];
        if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
            // Flip conditions so we can jump over the increment of the taken counter.
            ForwardReference fr = asm.forwardJcc(NE);
            incEdgeCounter(S0, null, edgeCounterIdx++);
            asm.emitJMP_ImmOrLabel(mTarget, bTarget);
            fr.resolve(asm);
        } else {
            asm.emitJCC_Cond_ImmOrLabel(EQ, mTarget, bTarget);
        }
    }
    bcodes.skipLookupSwitchPairs(npairs);
    int bTarget = biStart + defaultval;
    int mTarget = bytecodeMap[bTarget];
    if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
        // increment default counter
        incEdgeCounter(S0, null, edgeCounterIdx++);
    }
    asm.emitJMP_ImmOrLabel(mTarget, bTarget);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 14 with ForwardReference

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

the class BaselineCompilerImpl method emit_lshl.

@Override
protected void emit_lshl() {
    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.emitPSLLQ_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);
            // high half = low half
            asm.emitMOV_Reg_Reg(T1, T0);
            // low half = 0
            asm.emitXOR_Reg_Reg(T0, T0);
            fr1.resolve(asm);
            // shift high half, filling from low
            asm.emitSHLD_Reg_Reg_Reg(T1, T0, ECX);
            // shift low half
            asm.emitSHL_Reg_Reg(T0, ECX);
            // push high half
            asm.emitPUSH_Reg(T1);
            // push low half
            asm.emitPUSH_Reg(T0);
        }
    } else {
        asm.emitPOP_Reg(ECX);
        asm.emitSHL_RegInd_Reg_Quad(SP, ECX);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 15 with ForwardReference

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

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