Esempio n. 1
0
static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
                     RegLocation rlSrc1, RegLocation rlSrc2)
{
    bool isDouble;
    int defaultResult;
    bool ltNaNBias;
    RegLocation rlResult;

    switch(mir->dalvikInsn.opCode) {
        case OP_CMPL_FLOAT:
            isDouble = false;
            defaultResult = -1;
            break;
        case OP_CMPG_FLOAT:
            isDouble = false;
            defaultResult = 1;
            break;
        case OP_CMPL_DOUBLE:
            isDouble = true;
            defaultResult = -1;
            break;
        case OP_CMPG_DOUBLE:
            isDouble = true;
            defaultResult = 1;
            break;
        default:
            return true;
    }
    if (isDouble) {
        rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
        rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
        dvmCompilerClobberSReg(cUnit, rlDest.sRegLow);
        rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
        loadConstant(cUnit, rlResult.lowReg, defaultResult);
        newLIR2(cUnit, kThumb2Vcmpd, S2D(rlSrc1.lowReg, r1Src2.highReg),
                S2D(rlSrc2.lowReg, rlSrc2.highReg));
    } else {
        rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
        rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
        dvmCompilerClobberSReg(cUnit, rlDest.sRegLow);
        rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
        loadConstant(cUnit, rlResult.lowReg, defaultResult);
        newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg);
    }
    assert(!FPREG(rlResult.lowReg));
    newLIR0(cUnit, kThumb2Fmstat);
    genIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, "");
    newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg,
            modifiedImmediate(-defaultResult)); // Must not alter ccodes
    genIT(cUnit, kArmCondEq, "");
    loadConstant(cUnit, rlResult.lowReg, 0);
    storeValue(cUnit, rlDest, rlResult);
    return false;
}
Esempio n. 2
0
/*
 * Decode the register id.
 */
static inline u8 getRegMaskCommon(int reg)
{
    u8 seed;
    int shift;
    int regId = reg & 0x1f;
    /*
     * Each double register is equal to a pair of single-precision FP registers
     */
    seed = DOUBLEREG(reg) ? 3 : 1;
    /* FP register starts at bit position 16 */
    shift = FPREG(reg) ? kFPReg0 : 0;
    /* Expand the double register id into single offset */
    shift += regId;
    return (seed << shift);
}
Esempio n. 3
0
static void storeValueWide(CompilationUnit *cUnit, RegLocation rlDest,                    
							RegLocation rlSrc)
{
    LIR *defStart;
    LIR *defEnd;
    assert(FPREG(rlSrc.lowReg)==FPREG(rlSrc.highReg));
    assert(rlDest.wide);
    assert(rlSrc.wide);
   // dvmCompilerKillNullCheckedLoc(cUnit, rlDest);
    if (rlSrc.location == kLocPhysReg) {
        if (dvmCompilerIsLive(cUnit, rlSrc.lowReg) ||
            dvmCompilerIsLive(cUnit, rlSrc.highReg) ||
            (rlDest.location == kLocPhysReg)) {
            // Src is live or Dest has assigned reg.
            rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false);
            genRegCopyWide(cUnit, rlDest.lowReg, rlDest.highReg,
                           rlSrc.lowReg, rlSrc.highReg);
        } else {
            // Just re-assign the registers.  Dest gets Src's regs
            rlDest.lowReg = rlSrc.lowReg;
            rlDest.highReg = rlSrc.highReg;
            dvmCompilerClobber(cUnit, rlSrc.lowReg);
            dvmCompilerClobber(cUnit, rlSrc.highReg);
        }
    } else {
        // Load Src either into promoted Dest or temps allocated for Dest
        rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false);
        loadValueDirectWide(cUnit, rlSrc, rlDest.lowReg,
                            rlDest.highReg);
    }

    // Dest is now live and dirty (until/if we flush it to home location)
    dvmCompilerMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow);
    dvmCompilerMarkLive(cUnit, rlDest.highReg,
                        dvmCompilerSRegHi(rlDest.sRegLow));
    dvmCompilerMarkDirty(cUnit, rlDest.lowReg);
    dvmCompilerMarkDirty(cUnit, rlDest.highReg);
    dvmCompilerMarkPair(cUnit, rlDest.lowReg, rlDest.highReg);

    if (rlDest.location == kLocRetval) {
        //storeBaseDispWide(cUnit, rGLUE, offsetof(InterpState, retval),
        //                  rlDest.lowReg, rlDest.highReg);
        storeBaseDispWide(cUnit, rGLUE, 8,
                          rlDest.lowReg, rlDest.highReg);
        dvmCompilerClobber(cUnit, rlDest.lowReg);
        dvmCompilerClobber(cUnit, rlDest.highReg);
    } else {
        dvmCompilerResetDefLocWide(cUnit, rlDest);
        if (dvmCompilerLiveOut(cUnit, rlDest.sRegLow) ||
            dvmCompilerLiveOut(cUnit, dvmCompilerSRegHi(rlDest.sRegLow))) {
            //defStart = (LIR *)cUnit->lastLIRInsn;
            int vReg = dvmCompilerS2VReg(cUnit, rlDest.sRegLow);
            assert((vReg+1) == dvmCompilerS2VReg(cUnit,
                                     dvmCompilerSRegHi(rlDest.sRegLow)));
            storeBaseDispWide(cUnit, rFP, vReg << 2, rlDest.lowReg,
                              rlDest.highReg);
            dvmCompilerMarkClean(cUnit, rlDest.lowReg);
            dvmCompilerMarkClean(cUnit, rlDest.highReg);
            //defEnd = (LIR *)cUnit->lastLIRInsn;
            //dvmCompilerMarkDefWide(cUnit, rlDest, defStart, defEnd);
        }
    }
}