/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This file contains codegen for the Thumb ISA and is intended to be
 * includes by:
 *
 *        Codegen-$(TARGET_ARCH_VARIANT).c
 *
 */

static int coreTemps[] = {r0, r1, r2, r3, r4PC, r7, r8, r9, r10, r11, r12};
static int corePreserved[] = {};
static int fpTemps[] = {fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
                        fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31};
static int fpPreserved[] = {};

static int encodeImmSingle(int value)
{
    int res;
    int bitA =    (value & 0x80000000) >> 31;
    int notBitB = (value & 0x40000000) >> 30;
    int bitB =    (value & 0x20000000) >> 29;
    int bSmear =  (value & 0x3e000000) >> 25;
    int slice =   (value & 0x01f80000) >> 19;
    int zeroes =  (value & 0x0007ffff);
    if (zeroes != 0)
        return -1;
    if (bitB) {
        if ((notBitB != 0) || (bSmear != 0x1f))
            return -1;
    } else {
        if ((notBitB != 1) || (bSmear != 0x0))
            return -1;
    }
    res = (bitA << 7) | (bitB << 6) | slice;
    return res;
}

static ArmLIR *loadFPConstantValue(CompilationUnit *cUnit, int rDest,
                                   int value)
{
    int encodedImm = encodeImmSingle(value);
    assert(SINGLEREG(rDest));
    if (encodedImm >= 0) {
        return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm);
    }
    ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0);
    if (dataTarget == NULL) {
        dataTarget = addWordData(cUnit, value, false);
    }
    ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true);
    loadPcRel->opCode = kThumb2Vldrs;
    loadPcRel->generic.target = (LIR *) dataTarget;
    loadPcRel->operands[0] = rDest;
    loadPcRel->operands[1] = rpc;
    setupResourceMasks(loadPcRel);
    // Self-cosim workaround.
    if (rDest != rlr)
        setMemRefType(loadPcRel, true, kLiteral);
    loadPcRel->aliasInfo = dataTarget->operands[0];
    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);
    return loadPcRel;
}

static int leadingZeros(u4 val)
{
    u4 alt;
    int n;
    int count;

    count = 16;
    n = 32;
    do {
        alt = val >> count;
        if (alt != 0) {
            n = n - count;
            val = alt;
        }
        count >>= 1;
    } while (count);
    return n - val;
}

/*
 * Determine whether value can be encoded as a Thumb2 modified
 * immediate.  If not, return -1.  If so, return i:imm3:a:bcdefgh form.
 */
static int modifiedImmediate(u4 value)
{
   int zLeading;
   int zTrailing;
   u4 b0 = value & 0xff;

   /* Note: case of value==0 must use 0:000:0:0000000 encoding */
   if (value <= 0xFF)
       return b0;  // 0:000:a:bcdefgh
   if (value == ((b0 << 16) | b0))
       return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */
   if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0))
       return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */
   b0 = (value >> 8) & 0xff;
   if (value == ((b0 << 24) | (b0 << 8)))
       return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */
   /* Can we do it with rotation? */
   zLeading = leadingZeros(value);
   zTrailing = 32 - leadingZeros(~value & (value - 1));
   /* A run of eight or fewer active bits? */
   if ((zLeading + zTrailing) < 24)
       return -1;  /* No - bail */
   /* left-justify the constant, discarding msb (known to be 1) */
   value <<= zLeading + 1;
   /* Create bcdefgh */
   value >>= 25;
   /* Put it all together */
   return value | ((0x8 + zLeading) << 7); /* [01000..11111]:bcdefgh */
}

/*
 * Load a immediate using a shortcut if possible; otherwise
 * grab from the per-translation literal pool.
 *
 * No additional register clobbering operation performed. Use this version when
 * 1) rDest is freshly returned from dvmCompilerAllocTemp or
 * 2) The codegen is under fixed register usage
 */
static ArmLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
                                     int value)
{
    ArmLIR *res;
    int modImm;

    if (FPREG(rDest)) {
        return loadFPConstantValue(cUnit, rDest, value);
    }

    /* See if the value can be constructed cheaply */
    if (LOWREG(rDest) && (value >= 0) && (value <= 255)) {
        return newLIR2(cUnit, kThumbMovImm, rDest, value);
    }
    /* Check Modified immediate special cases */
    modImm = modifiedImmediate(value);
    if (modImm >= 0) {
        res = newLIR2(cUnit, kThumb2MovImmShift, rDest, modImm);
        return res;
    }
    modImm = modifiedImmediate(~value);
    if (modImm >= 0) {
        res = newLIR2(cUnit, kThumb2MvnImmShift, rDest, modImm);
        return res;
    }
    /* 16-bit immediate? */
    if ((value & 0xffff) == value) {
        res = newLIR2(cUnit, kThumb2MovImm16, rDest, value);
        return res;
    }
    /* No shortcut - go ahead and use literal pool */
    ArmLIR *dataTarget = scanLiteralPool(cUnit, value, 0);
    if (dataTarget == NULL) {
        dataTarget = addWordData(cUnit, value, false);
    }
    ArmLIR *loadPcRel = dvmCompilerNew(sizeof(ArmLIR), true);
    loadPcRel->opCode = LOWREG(rDest) ? kThumbLdrPcRel : kThumb2LdrPcRel12;
    loadPcRel->generic.target = (LIR *) dataTarget;
    loadPcRel->operands[0] = rDest;
    setupResourceMasks(loadPcRel);
    /*
     * Special case for literal loads with a link register target.
     * Self-cosim mode will insert calls prior to heap references
     * after optimization, and those will destroy r14.  The easy
     * workaround is to treat literal loads into r14 as heap references
     * to prevent them from being hoisted.  Use of r14 in this manner
     * is currently rare.  Revisit if that changes.
     */
    if (rDest != rlr)
        setMemRefType(loadPcRel, true, kLiteral);
    loadPcRel->aliasInfo = dataTarget->operands[0];
    res = loadPcRel;
    dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel);

    /*
     * To save space in the constant pool, we use the ADD_RRI8 instruction to
     * add up to 255 to an existing constant value.
     */
    if (dataTarget->operands[0] != value) {
        opRegImm(cUnit, kOpAdd, rDest, value - dataTarget->operands[0]);
    }
    return res;
}

/*
 * Load an immediate value into a fixed or temp register.  Target
 * register is clobbered, and marked inUse.
 */
static ArmLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
{
    if (dvmCompilerIsTemp(cUnit, rDest)) {
        dvmCompilerClobber(cUnit, rDest);
        dvmCompilerMarkInUse(cUnit, rDest);
    }
    return loadConstantNoClobber(cUnit, rDest, value);
}

static ArmLIR *opNone(CompilationUnit *cUnit, OpKind op)
{
    ArmOpCode opCode = kThumbBkpt;
    switch (op) {
        case kOpUncondBr:
            opCode = kThumbBUncond;
            break;
        default:
            assert(0);
    }
    return newLIR0(cUnit, opCode);
}

static ArmLIR *opCondBranch(CompilationUnit *cUnit, ArmConditionCode cc)
{
    return newLIR2(cUnit, kThumbBCond, 0 /* offset to be patched */, cc);
}

static ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value)
{
    ArmOpCode opCode = kThumbBkpt;
    switch (op) {
        case kOpPush:
            opCode = ((value & 0xff00) != 0) ? kThumb2Push : kThumbPush;
            break;
        case kOpPop:
            opCode = ((value & 0xff00) != 0) ? kThumb2Pop : kThumbPop;
            break;
        default:
            assert(0);
    }
    return newLIR1(cUnit, opCode, value);
}

static ArmLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
{
    ArmOpCode opCode = kThumbBkpt;
    switch (op) {
        case kOpBlx:
            opCode = kThumbBlxR;
            break;
        default:
            assert(0);
    }
    return newLIR1(cUnit, opCode, rDestSrc);
}

static ArmLIR *opRegRegShift(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                        int rSrc2, int shift)
{
    bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2));
    ArmOpCode opCode = kThumbBkpt;
    switch (op) {
        case kOpAdc:
            opCode = (thumbForm) ? kThumbAdcRR : kThumb2AdcRRR;
            break;
        case kOpAnd:
            opCode = (thumbForm) ? kThumbAndRR : kThumb2AndRRR;
            break;
        case kOpBic:
            opCode = (thumbForm) ? kThumbBicRR : kThumb2BicRRR;
            break;
        case kOpCmn:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbCmnRR : kThumb2CmnRR;
            break;
        case kOpCmp:
            if (thumbForm)
                opCode = kThumbCmpRR;
            else if ((shift == 0) && !LOWREG(rDestSrc1) && !LOWREG(rSrc2))
                opCode = kThumbCmpHH;
            else if ((shift == 0) && LOWREG(rDestSrc1))
                opCode = kThumbCmpLH;
            else if (shift == 0)
                opCode = kThumbCmpHL;
            else
                opCode = kThumb2CmpRR;
            break;
        case kOpXor:
            opCode = (thumbForm) ? kThumbEorRR : kThumb2EorRRR;
            break;
        case kOpMov:
            assert(shift == 0);
            if (LOWREG(rDestSrc1) && LOWREG(rSrc2))
                opCode = kThumbMovRR;
            else if (!LOWREG(rDestSrc1) && !LOWREG(rSrc2))
                opCode = kThumbMovRR_H2H;
            else if (LOWREG(rDestSrc1))
                opCode = kThumbMovRR_H2L;
            else
                opCode = kThumbMovRR_L2H;
            break;
        case kOpMul:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbMul : kThumb2MulRRR;
            break;
        case kOpMvn:
            opCode = (thumbForm) ? kThumbMvn : kThumb2MnvRR;
            break;
        case kOpNeg:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbNeg : kThumb2NegRR;
            break;
        case kOpOr:
            opCode = (thumbForm) ? kThumbOrr : kThumb2OrrRRR;
            break;
        case kOpSbc:
            opCode = (thumbForm) ? kThumbSbc : kThumb2SbcRRR;
            break;
        case kOpTst:
            opCode = (thumbForm) ? kThumbTst : kThumb2TstRR;
            break;
        case kOpLsl:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbLslRR : kThumb2LslRRR;
            break;
        case kOpLsr:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbLsrRR : kThumb2LsrRRR;
            break;
        case kOpAsr:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbAsrRR : kThumb2AsrRRR;
            break;
        case kOpRor:
            assert(shift == 0);
            opCode = (thumbForm) ? kThumbRorRR : kThumb2RorRRR;
            break;
        case kOpAdd:
            opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
            break;
        case kOpSub:
            opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
            break;
        case kOp2Byte:
            assert(shift == 0);
            return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 8);
        case kOp2Short:
            assert(shift == 0);
            return newLIR4(cUnit, kThumb2Sbfx, rDestSrc1, rSrc2, 0, 16);
        case kOp2Char:
            assert(shift == 0);
            return newLIR4(cUnit, kThumb2Ubfx, rDestSrc1, rSrc2, 0, 16);
        default:
            assert(0);
            break;
    }
    assert(opCode >= 0);
    if (EncodingMap[opCode].flags & IS_BINARY_OP)
        return newLIR2(cUnit, opCode, rDestSrc1, rSrc2);
    else if (EncodingMap[opCode].flags & IS_TERTIARY_OP) {
        if (EncodingMap[opCode].fieldLoc[2].kind == kFmtShift)
            return newLIR3(cUnit, opCode, rDestSrc1, rSrc2, shift);
        else
            return newLIR3(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2);
    } else if (EncodingMap[opCode].flags & IS_QUAD_OP)
        return newLIR4(cUnit, opCode, rDestSrc1, rDestSrc1, rSrc2, shift);
    else {
        assert(0);
        return NULL;
    }
}

static ArmLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                        int rSrc2)
{
    return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0);
}

static ArmLIR *opRegRegRegShift(CompilationUnit *cUnit, OpKind op,
                                int rDest, int rSrc1, int rSrc2, int shift)
{
    ArmOpCode opCode = kThumbBkpt;
    bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) &&
                      LOWREG(rSrc2);
    switch (op) {
        case kOpAdd:
            opCode = (thumbForm) ? kThumbAddRRR : kThumb2AddRRR;
            break;
        case kOpSub:
            opCode = (thumbForm) ? kThumbSubRRR : kThumb2SubRRR;
            break;
        case kOpAdc:
            opCode = kThumb2AdcRRR;
            break;
        case kOpAnd:
            opCode = kThumb2AndRRR;
            break;
        case kOpBic:
            opCode = kThumb2BicRRR;
            break;
        case kOpXor:
            opCode = kThumb2EorRRR;
            break;
        case kOpMul:
            assert(shift == 0);
            opCode = kThumb2MulRRR;
            break;
        case kOpOr:
            opCode = kThumb2OrrRRR;
            break;
        case kOpSbc:
            opCode = kThumb2SbcRRR;
            break;
        case kOpLsl:
            assert(shift == 0);
            opCode = kThumb2LslRRR;
            break;
        case kOpLsr:
            assert(shift == 0);
            opCode = kThumb2LsrRRR;
            break;
        case kOpAsr:
            assert(shift == 0);
            opCode = kThumb2AsrRRR;
            break;
        case kOpRor:
            assert(shift == 0);
            opCode = kThumb2RorRRR;
            break;
        default:
            assert(0);
            break;
    }
    assert(opCode >= 0);
    if (EncodingMap[opCode].flags & IS_QUAD_OP)
        return newLIR4(cUnit, opCode, rDest, rSrc1, rSrc2, shift);
    else {
        assert(EncodingMap[opCode].flags & IS_TERTIARY_OP);
        return newLIR3(cUnit, opCode, rDest, rSrc1, rSrc2);
    }
}

static ArmLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
                           int rSrc1, int rSrc2)
{
    return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0);
}

static ArmLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
                           int rSrc1, int value)
{
    ArmLIR *res;
    bool neg = (value < 0);
    int absValue = (neg) ? -value : value;
    ArmOpCode opCode = kThumbBkpt;
    ArmOpCode altOpCode = kThumbBkpt;
    bool allLowRegs = (LOWREG(rDest) && LOWREG(rSrc1));
    int modImm = modifiedImmediate(value);
    int modImmNeg = modifiedImmediate(-value);

    switch(op) {
        case kOpLsl:
            if (allLowRegs)
                return newLIR3(cUnit, kThumbLslRRI5, rDest, rSrc1, value);
            else
                return newLIR3(cUnit, kThumb2LslRRI5, rDest, rSrc1, value);
        case kOpLsr:
            if (allLowRegs)
                return newLIR3(cUnit, kThumbLsrRRI5, rDest, rSrc1, value);
            else
                return newLIR3(cUnit, kThumb2LsrRRI5, rDest, rSrc1, value);
        case kOpAsr:
            if (allLowRegs)
                return newLIR3(cUnit, kThumbAsrRRI5, rDest, rSrc1, value);
            else
                return newLIR3(cUnit, kThumb2AsrRRI5, rDest, rSrc1, value);
        case kOpRor:
            return newLIR3(cUnit, kThumb2RorRRI5, rDest, rSrc1, value);
        case kOpAdd:
            if (LOWREG(rDest) && (rSrc1 == 13) &&
                (value <= 1020) && ((value & 0x3)==0)) {
                return newLIR3(cUnit, kThumbAddSpRel, rDest, rSrc1,
                               value >> 2);
            } else if (LOWREG(rDest) && (rSrc1 == rpc) &&
                       (value <= 1020) && ((value & 0x3)==0)) {
                return newLIR3(cUnit, kThumbAddPcRel, rDest, rSrc1,
                               value >> 2);
            }
            opCode = kThumb2AddRRI8;
            altOpCode = kThumb2AddRRR;
            // Note: intentional fallthrough
        case kOpSub:
            if (allLowRegs && ((absValue & 0x7) == absValue)) {
                if (op == kOpAdd)
                    opCode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3;
                else
                    opCode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3;
                return newLIR3(cUnit, opCode, rDest, rSrc1, absValue);
            } else if ((absValue & 0xff) == absValue) {
                if (op == kOpAdd)
                    opCode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12;
                else
                    opCode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12;
                return newLIR3(cUnit, opCode, rDest, rSrc1, absValue);
            }
            if (modImmNeg >= 0) {
                op = (op == kOpAdd) ? kOpSub : kOpAdd;
                modImm = modImmNeg;
            }
            if (op == kOpSub) {
                opCode = kThumb2SubRRI8;
                altOpCode = kThumb2SubRRR;
            }
            break;
        case kOpAdc:
            opCode = kThumb2AdcRRI8;
            altOpCode = kThumb2AdcRRR;
            break;
        case kOpSbc:
            opCode = kThumb2SbcRRI8;
            altOpCode = kThumb2SbcRRR;
            break;
        case kOpOr:
            opCode = kThumb2OrrRRI8;
            altOpCode = kThumb2OrrRRR;
            break;
        case kOpAnd:
            opCode = kThumb2AndRRI8;
            altOpCode = kThumb2AndRRR;
            break;
        case kOpXor:
            opCode = kThumb2EorRRI8;
            altOpCode = kThumb2EorRRR;
            break;
        case kOpMul:
            //TUNING: power of 2, shift & add
            modImm = -1;
            altOpCode = kThumb2MulRRR;
            break;
        case kOpCmp: {
            int modImm = modifiedImmediate(value);
            ArmLIR *res;
            if (modImm >= 0) {
                res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm);
            } else {
                int rTmp = dvmCompilerAllocTemp(cUnit);
                res = loadConstant(cUnit, rTmp, value);
                opRegReg(cUnit, kOpCmp, rSrc1, rTmp);
                dvmCompilerFreeTemp(cUnit, rTmp);
            }
            return res;
        }
        default:
            assert(0);
    }

    if (modImm >= 0) {
        return newLIR3(cUnit, opCode, rDest, rSrc1, modImm);
    } else {
        int rScratch = dvmCompilerAllocTemp(cUnit);
        loadConstant(cUnit, rScratch, value);
        if (EncodingMap[altOpCode].flags & IS_QUAD_OP)
            res = newLIR4(cUnit, altOpCode, rDest, rSrc1, rScratch, 0);
        else
            res = newLIR3(cUnit, altOpCode, rDest, rSrc1, rScratch);
        dvmCompilerFreeTemp(cUnit, rScratch);
        return res;
    }
}

/* Handle Thumb-only variants here - otherwise punt to opRegRegImm */
static ArmLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                        int value)
{
    ArmLIR *res;
    bool neg = (value < 0);
    int absValue = (neg) ? -value : value;
    bool shortForm = (((absValue & 0xff) == absValue) && LOWREG(rDestSrc1));
    ArmOpCode opCode = kThumbBkpt;
    switch (op) {
        case kOpAdd:
            if ( !neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */
                assert((value & 0x3) == 0);
                return newLIR1(cUnit, kThumbAddSpI7, value >> 2);
            } else if (shortForm) {
                opCode = (neg) ? kThumbSubRI8 : kThumbAddRI8;
            }
            break;
        case kOpSub:
            if (!neg && (rDestSrc1 == 13) && (value <= 508)) { /* sp */
                assert((value & 0x3) == 0);
                return newLIR1(cUnit, kThumbSubSpI7, value >> 2);
            } else if (shortForm) {
                opCode = (neg) ? kThumbAddRI8 : kThumbSubRI8;
            }
            break;
        case kOpCmp:
            if (LOWREG(rDestSrc1) && shortForm)
                opCode = (shortForm) ?  kThumbCmpRI8 : kThumbCmpRR;
            else if (LOWREG(rDestSrc1))
                opCode = kThumbCmpRR;
            else {
                shortForm = false;
                opCode = kThumbCmpHL;
            }
            break;
        default:
            /* Punt to opRegRegImm - if bad case catch it there */
            shortForm = false;
            break;
    }
    if (shortForm)
        return newLIR2(cUnit, opCode, rDestSrc1, absValue);
    else {
        return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
    }
}

/*
 * Determine whether value can be encoded as a Thumb2 floating point
 * immediate.  If not, return -1.  If so return encoded 8-bit value.
 */
static int encodeImmDoubleHigh(int value)
{
    int res;
    int bitA =    (value & 0x80000000) >> 31;
    int notBitB = (value & 0x40000000) >> 30;
    int bitB =    (value & 0x20000000) >> 29;
    int bSmear =  (value & 0x3fc00000) >> 22;
    int slice =   (value & 0x003f0000) >> 16;
    int zeroes =  (value & 0x0000ffff);
    if (zeroes != 0)
        return -1;
    if (bitB) {
        if ((notBitB != 0) || (bSmear != 0x1f))
            return -1;
    } else {
        if ((notBitB != 1) || (bSmear != 0x0))
            return -1;
    }
    res = (bitA << 7) | (bitB << 6) | slice;
    return res;
}

static int encodeImmDouble(int valLo, int valHi)
{
    int res = -1;
    if (valLo == 0)
        res = encodeImmDoubleHigh(valHi);
    return res;
}

static ArmLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
                                     int rDestHi, int valLo, int valHi)
{
    int encodedImm = encodeImmDouble(valLo, valHi);
    ArmLIR *res;
    if (FPREG(rDestLo) && (encodedImm >= 0)) {
        res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi),
                      encodedImm);
    } else {
        res = loadConstantNoClobber(cUnit, rDestLo, valLo);
        loadConstantNoClobber(cUnit, rDestHi, valHi);
    }
    return res;
}

static int encodeShift(int code, int amount) {
    return ((amount & 0x1f) << 2) | code;
}

static ArmLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
                               int rIndex, int rDest, int scale, OpSize size)
{
    bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest);
    ArmLIR *load;
    ArmOpCode opCode = kThumbBkpt;
    bool thumbForm = (allLowRegs && (scale == 0));
    int regPtr;

    if (FPREG(rDest)) {
        assert(SINGLEREG(rDest));
        assert((size == kWord) || (size == kSingle));
        opCode = kThumb2Vldrs;
        size = kSingle;
    } else {
        if (size == kSingle)
            size = kWord;
    }

    switch (size) {
        case kSingle:
            regPtr = dvmCompilerAllocTemp(cUnit);
            if (scale) {
                newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
                        encodeShift(kArmLsl, scale));
            } else {
                opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
            }
            load = newLIR3(cUnit, opCode, rDest, regPtr, 0);
#if defined(WITH_SELF_VERIFICATION)
            if (cUnit->heapMemOp)
                load->branchInsertSV = true;
#endif
            return load;
        case kWord:
            opCode = (thumbForm) ? kThumbLdrRRR : kThumb2LdrRRR;
            break;
        case kUnsignedHalf:
            opCode = (thumbForm) ? kThumbLdrhRRR : kThumb2LdrhRRR;
            break;
        case kSignedHalf:
            opCode = (thumbForm) ? kThumbLdrshRRR : kThumb2LdrshRRR;
            break;
        case kUnsignedByte:
            opCode = (thumbForm) ? kThumbLdrbRRR : kThumb2LdrbRRR;
            break;
        case kSignedByte:
            opCode = (thumbForm) ? kThumbLdrsbRRR : kThumb2LdrsbRRR;
            break;
        default:
            assert(0);
    }
    if (thumbForm)
        load = newLIR3(cUnit, opCode, rDest, rBase, rIndex);
    else
        load = newLIR4(cUnit, opCode, rDest, rBase, rIndex, scale);

#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        load->branchInsertSV = true;
#endif
    return load;
}

static ArmLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
                                int rIndex, int rSrc, int scale, OpSize size)
{
    bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc);
    ArmLIR *store;
    ArmOpCode opCode = kThumbBkpt;
    bool thumbForm = (allLowRegs && (scale == 0));
    int regPtr;

    if (FPREG(rSrc)) {
        assert(SINGLEREG(rSrc));
        if ((size != kWord) && (size != kSingle)) {
           /* Move float value into core register */
           int tReg = dvmCompilerAllocTemp(cUnit);
           dvmCompilerRegCopy(cUnit, tReg, rSrc);
           rSrc = tReg;
        } else {
            opCode = kThumb2Vstrs;
            size = kSingle;
        }
    } else {
        if (size == kSingle)
            size = kWord;
    }

    switch (size) {
        case kSingle:
            regPtr = dvmCompilerAllocTemp(cUnit);
            if (scale) {
                newLIR4(cUnit, kThumb2AddRRR, regPtr, rBase, rIndex,
                        encodeShift(kArmLsl, scale));
            } else {
                opRegRegReg(cUnit, kOpAdd, regPtr, rBase, rIndex);
            }
            store = newLIR3(cUnit, opCode, rSrc, regPtr, 0);
#if defined(WITH_SELF_VERIFICATION)
            if (cUnit->heapMemOp)
                store->branchInsertSV = true;
#endif
            return store;
        case kWord:
            opCode = (thumbForm) ? kThumbStrRRR : kThumb2StrRRR;
            break;
        case kUnsignedHalf:
        case kSignedHalf:
            opCode = (thumbForm) ? kThumbStrhRRR : kThumb2StrhRRR;
            break;
        case kUnsignedByte:
        case kSignedByte:
            opCode = (thumbForm) ? kThumbStrbRRR : kThumb2StrbRRR;
            break;
        default:
            assert(0);
    }
    if (thumbForm)
        store = newLIR3(cUnit, opCode, rSrc, rBase, rIndex);
    else
        store = newLIR4(cUnit, opCode, rSrc, rBase, rIndex, scale);

#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        store->branchInsertSV = true;
#endif
    return store;
}

/*
 * Load value from base + displacement.  Optionally perform null check
 * on base (which must have an associated sReg and MIR).  If not
 * performing null check, incoming MIR can be null.
 */
static ArmLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
                                int displacement, int rDest, int rDestHi,
                                OpSize size, int sReg)
{
    ArmLIR *res, *load;
    ArmOpCode opCode = kThumbBkpt;
    bool shortForm = false;
    bool thumb2Form = (displacement < 4092 && displacement >= 0);
    int shortMax = 128;
    bool allLowRegs = (LOWREG(rBase) && LOWREG(rDest));
    int encodedDisp = displacement;

    switch (size) {
        case kDouble:
        case kLong:
            if (FPREG(rDest)) {
                if (SINGLEREG(rDest)) {
                    assert(FPREG(rDestHi));
                    rDest = S2D(rDest, rDestHi);
                }
                opCode = kThumb2Vldrd;
                if (displacement <= 1020) {
                    shortForm = true;
                    encodedDisp >>= 2;
                }
                break;
            } else {
                res = loadBaseDispBody(cUnit, mir, rBase, displacement, rDest,
                                       -1, kWord, sReg);
                loadBaseDispBody(cUnit, NULL, rBase, displacement + 4, rDestHi,
                                 -1, kWord, INVALID_SREG);
                return res;
            }
        case kSingle:
        case kWord:
            if (FPREG(rDest)) {
                opCode = kThumb2Vldrs;
                if (displacement <= 1020) {
                    shortForm = true;
                    encodedDisp >>= 2;
                }
                break;
            }
            if (LOWREG(rDest) && (rBase == rpc) &&
                (displacement <= 1020) && (displacement >= 0)) {
                shortForm = true;
                encodedDisp >>= 2;
                opCode = kThumbLdrPcRel;
            } else if (LOWREG(rDest) && (rBase == r13) &&
                      (displacement <= 1020) && (displacement >= 0)) {
                shortForm = true;
                encodedDisp >>= 2;
                opCode = kThumbLdrSpRel;
            } else if (allLowRegs && displacement < 128 && displacement >= 0) {
                assert((displacement & 0x3) == 0);
                shortForm = true;
                encodedDisp >>= 2;
                opCode = kThumbLdrRRI5;
            } else if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2LdrRRI12;
            }
            break;
        case kUnsignedHalf:
            if (allLowRegs && displacement < 64 && displacement >= 0) {
                assert((displacement & 0x1) == 0);
                shortForm = true;
                encodedDisp >>= 1;
                opCode = kThumbLdrhRRI5;
            } else if (displacement < 4092 && displacement >= 0) {
                shortForm = true;
                opCode = kThumb2LdrhRRI12;
            }
            break;
        case kSignedHalf:
            if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2LdrshRRI12;
            }
            break;
        case kUnsignedByte:
            if (allLowRegs && displacement < 32 && displacement >= 0) {
                shortForm = true;
                opCode = kThumbLdrbRRI5;
            } else if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2LdrbRRI12;
            }
            break;
        case kSignedByte:
            if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2LdrsbRRI12;
            }
            break;
        default:
            assert(0);
    }

    if (shortForm) {
        load = res = newLIR3(cUnit, opCode, rDest, rBase, encodedDisp);
    } else {
        int regOffset = dvmCompilerAllocTemp(cUnit);
        res = loadConstant(cUnit, regOffset, encodedDisp);
        load = loadBaseIndexed(cUnit, rBase, regOffset, rDest, 0, size);
        dvmCompilerFreeTemp(cUnit, regOffset);
    }

    if (rBase == rFP) {
        annotateDalvikRegAccess(load, displacement >> 2, true /* isLoad */);
    }
#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        load->branchInsertSV = true;
#endif
    return res;
}

static ArmLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
                            int displacement, int rDest, OpSize size,
                            int sReg)
{
    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
                            size, sReg);
}

static  ArmLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
                                 int displacement, int rDestLo, int rDestHi,
                                 int sReg)
{
    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
                            kLong, sReg);
}


static ArmLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
                                 int displacement, int rSrc, int rSrcHi,
                                 OpSize size)
{
    ArmLIR *res, *store;
    ArmOpCode opCode = kThumbBkpt;
    bool shortForm = false;
    bool thumb2Form = (displacement < 4092 && displacement >= 0);
    int shortMax = 128;
    bool allLowRegs = (LOWREG(rBase) && LOWREG(rSrc));
    int encodedDisp = displacement;

    switch (size) {
        case kLong:
        case kDouble:
            if (!FPREG(rSrc)) {
                res = storeBaseDispBody(cUnit, rBase, displacement, rSrc,
                                        -1, kWord);
                storeBaseDispBody(cUnit, rBase, displacement + 4, rSrcHi,
                                  -1, kWord);
                return res;
            }
            if (SINGLEREG(rSrc)) {
                assert(FPREG(rSrcHi));
                rSrc = S2D(rSrc, rSrcHi);
            }
            opCode = kThumb2Vstrd;
            if (displacement <= 1020) {
                shortForm = true;
                encodedDisp >>= 2;
            }
            break;
        case kSingle:
        case kWord:
            if (FPREG(rSrc)) {
                assert(SINGLEREG(rSrc));
                opCode = kThumb2Vstrs;
                if (displacement <= 1020) {
                    shortForm = true;
                    encodedDisp >>= 2;
                }
            break;
            }
            if (allLowRegs && displacement < 128 && displacement >= 0) {
                assert((displacement & 0x3) == 0);
                shortForm = true;
                encodedDisp >>= 2;
                opCode = kThumbStrRRI5;
            } else if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2StrRRI12;
            }
            break;
        case kUnsignedHalf:
        case kSignedHalf:
            if (allLowRegs && displacement < 64 && displacement >= 0) {
                assert((displacement & 0x1) == 0);
                shortForm = true;
                encodedDisp >>= 1;
                opCode = kThumbStrhRRI5;
            } else if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2StrhRRI12;
            }
            break;
        case kUnsignedByte:
        case kSignedByte:
            if (allLowRegs && displacement < 32 && displacement >= 0) {
                shortForm = true;
                opCode = kThumbStrbRRI5;
            } else if (thumb2Form) {
                shortForm = true;
                opCode = kThumb2StrbRRI12;
            }
            break;
        default:
            assert(0);
    }
    if (shortForm) {
        store = res = newLIR3(cUnit, opCode, rSrc, rBase, encodedDisp);
    } else {
        int rScratch = dvmCompilerAllocTemp(cUnit);
        res = loadConstant(cUnit, rScratch, encodedDisp);
        store = storeBaseIndexed(cUnit, rBase, rScratch, rSrc, 0, size);
        dvmCompilerFreeTemp(cUnit, rScratch);
    }

    if (rBase == rFP) {
        annotateDalvikRegAccess(store, displacement >> 2, false /* isLoad */);
    }
#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        store->branchInsertSV = true;
#endif
    return res;
}

static ArmLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
                             int displacement, int rSrc, OpSize size)
{
    return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
}

static ArmLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
                                 int displacement, int rSrcLo, int rSrcHi)
{
    return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
}

static ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
{
    ArmLIR *res;
    genBarrier(cUnit);
    if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) {
        res = newLIR2(cUnit, kThumbLdmia, rBase, rMask);
    } else {
        res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask);
    }
#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        res->branchInsertSV = true;
#endif
    genBarrier(cUnit);
    return res;
}

static ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
{
    ArmLIR *res;
    genBarrier(cUnit);
    if (LOWREG(rBase) && ((rMask & 0xff)==rMask)) {
        res = newLIR2(cUnit, kThumbStmia, rBase, rMask);
    } else {
        res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask);
    }
#if defined(WITH_SELF_VERIFICATION)
    if (cUnit->heapMemOp)
        res->branchInsertSV = true;
#endif
    genBarrier(cUnit);
    return res;
}

static void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
{
    storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
}

static void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
{
    loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
}


/*
 * Perform a "reg cmp imm" operation and jump to the PCR region if condition
 * satisfies.
 */
static ArmLIR *genRegImmCheck(CompilationUnit *cUnit,
                              ArmConditionCode cond, int reg,
                              int checkValue, int dOffset,
                              ArmLIR *pcrLabel)
{
    ArmLIR *branch;
    int modImm;
    /*
     * TODO: re-enable usage of kThumb2Cbz & kThumb2Cbnz once assembler is
     * enhanced to allow us to replace code patterns when instructions don't
     * reach.  Currently, CB[N]Z is causing too many assembler aborts.
     * What we want to do is emit the short forms, and then replace them with
     * longer versions when needed.
     */

    if (0 && (LOWREG(reg)) && (checkValue == 0) &&
       ((cond == kArmCondEq) || (cond == kArmCondNe))) {
        branch = newLIR2(cUnit,
                         (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
                         reg, 0);
    } else {
        modImm = modifiedImmediate(checkValue);
        if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
            newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
        } else if (modImm >= 0) {
            newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
        } else {
            int tReg = dvmCompilerAllocTemp(cUnit);
            loadConstant(cUnit, tReg, checkValue);
            opRegReg(cUnit, kOpCmp, reg, tReg);
        }
        branch = newLIR2(cUnit, kThumbBCond, 0, cond);
    }
    return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
}

static ArmLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
{
    ArmLIR* res = dvmCompilerNew(sizeof(ArmLIR), true);
    res->operands[0] = rDest;
    res->operands[1] = rSrc;
    if (rDest == rSrc) {
        res->isNop = true;
    } else {
        assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc));
        if (DOUBLEREG(rDest)) {
            res->opCode = kThumb2Vmovd;
        } else {
            if (SINGLEREG(rDest)) {
                res->opCode = SINGLEREG(rSrc) ? kThumb2Vmovs : kThumb2Fmsr;
            } else {
                assert(SINGLEREG(rSrc));
                res->opCode = kThumb2Fmrs;
            }
        }
        res->operands[0] = rDest;
        res->operands[1] = rSrc;
    }
    setupResourceMasks(res);
    return res;
}

static ArmLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
{
    ArmLIR* res;
    ArmOpCode opCode;
    if (FPREG(rDest) || FPREG(rSrc))
        return fpRegCopy(cUnit, rDest, rSrc);
    res = dvmCompilerNew(sizeof(ArmLIR), true);
    if (LOWREG(rDest) && LOWREG(rSrc))
        opCode = kThumbMovRR;
    else if (!LOWREG(rDest) && !LOWREG(rSrc))
         opCode = kThumbMovRR_H2H;
    else if (LOWREG(rDest))
         opCode = kThumbMovRR_H2L;
    else
         opCode = kThumbMovRR_L2H;

    res->operands[0] = rDest;
    res->operands[1] = rSrc;
    res->opCode = opCode;
    setupResourceMasks(res);
    if (rDest == rSrc) {
        res->isNop = true;
    }
    return res;
}

static ArmLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
{
    ArmLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
    dvmCompilerAppendLIR(cUnit, (LIR*)res);
    return res;
}

static void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
                           int srcLo, int srcHi)
{
    bool destFP = FPREG(destLo) && FPREG(destHi);
    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
    assert(FPREG(srcLo) == FPREG(srcHi));
    assert(FPREG(destLo) == FPREG(destHi));
    if (destFP) {
        if (srcFP) {
            genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
        } else {
            newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
        }
    } else {
        if (srcFP) {
            newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
        } else {
            // Handle overlap
            if (srcHi == destLo) {
                genRegCopy(cUnit, destHi, srcHi);
                genRegCopy(cUnit, destLo, srcLo);
            } else {
                genRegCopy(cUnit, destLo, srcLo);
                genRegCopy(cUnit, destHi, srcHi);
            }
        }
    }
}
