/*
 * Copyright (C) 2011 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 Thumb2 ISA and is intended to be
 * includes by:
 *
 *        Codegen-$(TARGET_ARCH_VARIANT).c
 *
 */

#include "oat_compilation_unit.h"

namespace art {


/* Return the position of an ssa name within the argument list */
int inPosition(CompilationUnit* cUnit, int sReg)
{
    int vReg = SRegToVReg(cUnit, sReg);
    return vReg - cUnit->numRegs;
}

/*
 * Describe an argument.  If it's already in an arg register, just leave it
 * there.  NOTE: all live arg registers must be locked prior to this call
 * to avoid having them allocated as a temp by downstream utilities.
 */
RegLocation argLoc(CompilationUnit* cUnit, RegLocation loc)
{
    int argNum = inPosition(cUnit, loc.sRegLow);
    if (loc.wide) {
        if (argNum == 2) {
            // Bad case - half in register, half in frame.  Just punt
            loc.location = kLocInvalid;
        } else if (argNum < 2) {
            loc.lowReg = rARG1 + argNum;
            loc.highReg = loc.lowReg + 1;
            loc.location = kLocPhysReg;
        } else {
            loc.location = kLocDalvikFrame;
        }
    } else {
        if (argNum < 3) {
            loc.lowReg = rARG1 + argNum;
            loc.location = kLocPhysReg;
        } else {
            loc.location = kLocDalvikFrame;
        }
    }
    return loc;
}

/*
 * Load an argument.  If already in a register, just return.  If in
 * the frame, we can't use the normal loadValue() because it assumed
 * a proper frame - and we're frameless.
 */
RegLocation loadArg(CompilationUnit* cUnit, RegLocation loc)
{
    if (loc.location == kLocDalvikFrame) {
        int start = (inPosition(cUnit, loc.sRegLow) + 1) * sizeof(uint32_t);
        loc.lowReg = oatAllocTemp(cUnit);
        loadWordDisp(cUnit, rSP, start, loc.lowReg);
        if (loc.wide) {
            loc.highReg = oatAllocTemp(cUnit);
            loadWordDisp(cUnit, rSP, start + sizeof(uint32_t), loc.highReg);
        }
        loc.location = kLocPhysReg;
    }
    return loc;
}

/* Lock any referenced arguments that arrive in registers */
void lockLiveArgs(CompilationUnit* cUnit, MIR* mir)
{
    int firstIn = cUnit->numRegs;
    const int numArgRegs = 3;  // TODO: generalize & move to RegUtil.cc
    for (int i = 0; i < mir->ssaRep->numUses; i++) {
        int vReg = SRegToVReg(cUnit, mir->ssaRep->uses[i]);
        int inPosition = vReg - firstIn;
        if (inPosition < numArgRegs) {
            oatLockTemp(cUnit, rARG1 + inPosition);
        }
    }
}

/* Find the next MIR, which may be in a following basic block */
MIR* getNextMir(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir)
{
    BasicBlock* bb = *pBb;
    MIR* origMir = mir;
    while (bb != NULL) {
        if (mir != NULL) {
            mir = mir->next;
        }
        if (mir != NULL) {
            return mir;
        } else {
            bb = bb->fallThrough;
            *pBb = bb;
            if (bb) {
               mir = bb->firstMIRInsn;
               if (mir != NULL) {
                   return mir;
               }
            }
        }
    }
    return origMir;
}

/* Used for the "printMe" listing */
void genPrintLabel(CompilationUnit *cUnit, MIR* mir)
{
    LIR* boundaryLIR;
    /* Mark the beginning of a Dalvik instruction for line tracking */
    char* instStr = cUnit->printMe ?
       oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
    boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
                          (intptr_t) instStr);
    cUnit->boundaryMap.insert(std::make_pair(mir->offset,
                             (LIR*)boundaryLIR));
    /* Don't generate the SSA annotation unless verbose mode is on */
    if (cUnit->printMe && mir->ssaRep) {
        char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
        newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
    }
}

MIR* specialIGet(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
                 OpSize size, bool longOrDouble, bool isObject)
{
    int fieldOffset;
    bool isVolatile;
    uint32_t fieldIdx = mir->dalvikInsn.vC;
    bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
                                 false);
    if (!fastPath) {
        return NULL;
    }
    RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
    lockLiveArgs(cUnit, mir);
    rlObj = argLoc(cUnit, rlObj);
    // Reject if object reference is not "this"
    if ((rlObj.location == kLocInvalid) ||
        (inPosition(cUnit, rlObj.sRegLow) != 0)) {
        oatResetRegPool(cUnit);
        return NULL;
    }
    RegLocation rlDest;
    if (longOrDouble) {
        rlDest = oatGetReturnWide(cUnit, false);
    } else {
        rlDest = oatGetReturn(cUnit, false);
    }
    // Point of no return - no aborts after this
    mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
    genPrintLabel(cUnit, mir);
    rlObj = loadArg(cUnit, rlObj);
    genIGet(cUnit, mir, size, rlDest, rlObj, longOrDouble, isObject);
    return getNextMir(cUnit, bb, mir);
}

MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
                 OpSize size, bool longOrDouble, bool isObject)
{
    int fieldOffset;
    bool isVolatile;
    uint32_t fieldIdx = mir->dalvikInsn.vC;
    bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile,
                                 false);
    if (!fastPath) {
        return NULL;
    }
    RegLocation rlSrc;
    RegLocation rlObj;
    lockLiveArgs(cUnit, mir);
    if (longOrDouble) {
        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
        rlObj = oatGetSrc(cUnit, mir, 2);
    } else {
        rlSrc = oatGetSrc(cUnit, mir, 0);
        rlObj = oatGetSrc(cUnit, mir, 1);
    }
    rlSrc = argLoc(cUnit, rlSrc);
    rlObj = argLoc(cUnit, rlObj);
    // Reject if object reference is not "this"
    if ((rlObj.location == kLocInvalid) ||
        (inPosition(cUnit, rlObj.sRegLow) != 0) ||
        (rlSrc.location == kLocInvalid)) {
        oatResetRegPool(cUnit);
        return NULL;
    }
    // Point of no return - no aborts after this
    mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
    genPrintLabel(cUnit, mir);
    rlObj = loadArg(cUnit, rlObj);
    rlSrc = loadArg(cUnit, rlSrc);
    genIPut(cUnit, mir, size, rlSrc, rlObj, longOrDouble, isObject);
    return getNextMir(cUnit, bb, mir);
}

MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir)
{
    RegLocation rlSrc;
    RegLocation rlDest;
    bool wide = (mir->ssaRep->numUses == 2);
    if (wide) {
        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
        rlDest = oatGetReturnWide(cUnit, false);
    } else {
        rlSrc = oatGetSrc(cUnit, mir, 0);
        rlDest = oatGetReturn(cUnit, false);
    }
    lockLiveArgs(cUnit, mir);
    rlSrc = argLoc(cUnit, rlSrc);
    if (rlSrc.location == kLocInvalid) {
        oatResetRegPool(cUnit);
        return NULL;
    }
    // Point of no return - no aborts after this
    genPrintLabel(cUnit, mir);
    rlSrc = loadArg(cUnit, rlSrc);
    if (wide) {
        storeValueWide(cUnit, rlDest, rlSrc);
    } else {
        storeValue(cUnit, rlDest, rlSrc);
    }
    return mir;
}

/*
 * Special-case code genration for simple non-throwing leaf methods.
 */
void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
                    SpecialCaseHandler specialCase)
{
   cUnit->currentDalvikOffset = mir->offset;
   MIR* nextMir = NULL;
   switch(specialCase) {
       case kNullMethod:
           DCHECK(mir->dalvikInsn.opcode == Instruction::RETURN_VOID);
           nextMir = mir;
           break;
       case kConstFunction:
           genPrintLabel(cUnit, mir);
           loadConstant(cUnit, rRET0, mir->dalvikInsn.vB);
           nextMir = getNextMir(cUnit, &bb, mir);
           break;
       case kIGet:
           nextMir = specialIGet(cUnit, &bb, mir, kWord, false, false);
           break;
       case kIGetBoolean:
       case kIGetByte:
           nextMir = specialIGet(cUnit, &bb, mir, kUnsignedByte, false, false);
           break;
       case kIGetObject:
           nextMir = specialIGet(cUnit, &bb, mir, kWord, false, true);
           break;
       case kIGetChar:
           nextMir = specialIGet(cUnit, &bb, mir, kUnsignedHalf, false, false);
           break;
       case kIGetShort:
           nextMir = specialIGet(cUnit, &bb, mir, kSignedHalf, false, false);
           break;
       case kIGetWide:
           nextMir = specialIGet(cUnit, &bb, mir, kLong, true, false);
           break;
       case kIPut:
           nextMir = specialIPut(cUnit, &bb, mir, kWord, false, false);
           break;
       case kIPutBoolean:
       case kIPutByte:
           nextMir = specialIPut(cUnit, &bb, mir, kUnsignedByte, false, false);
           break;
       case kIPutObject:
           nextMir = specialIPut(cUnit, &bb, mir, kWord, false, true);
           break;
       case kIPutChar:
           nextMir = specialIPut(cUnit, &bb, mir, kUnsignedHalf, false, false);
           break;
       case kIPutShort:
           nextMir = specialIPut(cUnit, &bb, mir, kSignedHalf, false, false);
           break;
       case kIPutWide:
           nextMir = specialIPut(cUnit, &bb, mir, kLong, true, false);
           break;
       case kIdentity:
           nextMir = specialIdentity(cUnit, mir);
           break;
       default:
           return;
   }
   if (nextMir != NULL) {
        cUnit->currentDalvikOffset = nextMir->offset;
        if (specialCase != kIdentity) {
            genPrintLabel(cUnit, nextMir);
        }
        newLIR1(cUnit, kThumbBx, rLR);
        cUnit->coreSpillMask = 0;
        cUnit->numCoreSpills = 0;
        cUnit->fpSpillMask = 0;
        cUnit->numFPSpills = 0;
        cUnit->frameSize = 0;
        cUnit->coreVmapTable.clear();
        cUnit->fpVmapTable.clear();
    }
}

/*
 * Generate a Thumb2 IT instruction, which can nullify up to
 * four subsequent instructions based on a condition and its
 * inverse.  The condition applies to the first instruction, which
 * is executed if the condition is met.  The string "guide" consists
 * of 0 to 3 chars, and applies to the 2nd through 4th instruction.
 * A "T" means the instruction is executed if the condition is
 * met, and an "E" means the instruction is executed if the condition
 * is not met.
 */
LIR* opIT(CompilationUnit* cUnit, ArmConditionCode code, const char* guide)
{
    int mask;
    int condBit = code & 1;
    int altBit = condBit ^ 1;
    int mask3 = 0;
    int mask2 = 0;
    int mask1 = 0;

    //Note: case fallthroughs intentional
    switch(strlen(guide)) {
        case 3:
            mask1 = (guide[2] == 'T') ? condBit : altBit;
        case 2:
            mask2 = (guide[1] == 'T') ? condBit : altBit;
        case 1:
            mask3 = (guide[0] == 'T') ? condBit : altBit;
            break;
        case 0:
            break;
        default:
            LOG(FATAL) << "OAT: bad case in opIT";
    }
    mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
           (1 << (3 - strlen(guide)));
    return newLIR2(cUnit, kThumb2It, code, mask);
}

/*
 * The sparse table in the literal pool is an array of <key,displacement>
 * pairs.  For each set, we'll load them as a pair using ldmia.
 * This means that the register number of the temp we use for the key
 * must be lower than the reg for the displacement.
 *
 * The test loop will look something like:
 *
 *   adr   rBase, <table>
 *   ldr   rVal, [rSP, vRegOff]
 *   mov   rIdx, #tableSize
 * lp:
 *   ldmia rBase!, {rKey, rDisp}
 *   sub   rIdx, #1
 *   cmp   rVal, rKey
 *   ifeq
 *   add   rPC, rDisp   ; This is the branch from which we compute displacement
 *   cbnz  rIdx, lp
 */
void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
    if (cUnit->printMe) {
        dumpSparseSwitchTable(table);
    }
    // Add the table to the list - we'll process it later
    SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                         true, kAllocData);
    tabRec->table = table;
    tabRec->vaddr = mir->offset;
    int size = table[1];
    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                                     kAllocLIR);
    oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);

    // Get the switch value
    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
    int rBase = oatAllocTemp(cUnit);
    /* Allocate key and disp temps */
    int rKey = oatAllocTemp(cUnit);
    int rDisp = oatAllocTemp(cUnit);
    // Make sure rKey's register number is less than rDisp's number for ldmia
    if (rKey > rDisp) {
        int tmp = rDisp;
        rDisp = rKey;
        rKey = tmp;
    }
    // Materialize a pointer to the switch table
    newLIR3(cUnit, kThumb2Adr, rBase, 0, (intptr_t)tabRec);
    // Set up rIdx
    int rIdx = oatAllocTemp(cUnit);
    loadConstant(cUnit, rIdx, size);
    // Establish loop branch target
    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
    // Load next key/disp
    newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
    opRegReg(cUnit, kOpCmp, rKey, rlSrc.lowReg);
    // Go if match. NOTE: No instruction set switch here - must stay Thumb2
    opIT(cUnit, kArmCondEq, "");
    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
    tabRec->anchor = switchBranch;
    // Needs to use setflags encoding here
    newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
    opCondBranch(cUnit, kCondNe, target);
}


void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
    if (cUnit->printMe) {
        dumpPackedSwitchTable(table);
    }
    // Add the table to the list - we'll process it later
    SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
                                                true, kAllocData);
    tabRec->table = table;
    tabRec->vaddr = mir->offset;
    int size = table[1];
    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                                        kAllocLIR);
    oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);

    // Get the switch value
    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
    int tableBase = oatAllocTemp(cUnit);
    // Materialize a pointer to the switch table
    newLIR3(cUnit, kThumb2Adr, tableBase, 0, (intptr_t)tabRec);
    int lowKey = s4FromSwitchData(&table[2]);
    int keyReg;
    // Remove the bias, if necessary
    if (lowKey == 0) {
        keyReg = rlSrc.lowReg;
    } else {
        keyReg = oatAllocTemp(cUnit);
        opRegRegImm(cUnit, kOpSub, keyReg, rlSrc.lowReg, lowKey);
    }
    // Bounds check - if < 0 or >= size continue following switch
    opRegImm(cUnit, kOpCmp, keyReg, size-1);
    LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);

    // Load the displacement from the switch table
    int dispReg = oatAllocTemp(cUnit);
    loadBaseIndexed(cUnit, tableBase, keyReg, dispReg, 2, kWord);

    // ..and go! NOTE: No instruction set switch here - must stay Thumb2
    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
    tabRec->anchor = switchBranch;

    /* branchOver target here */
    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
    branchOver->target = (LIR*)target;
}

/*
 * Array data table format:
 *  ushort ident = 0x0300   magic value
 *  ushort width            width of each element in the table
 *  uint   size             number of elements in the table
 *  ubyte  data[size*width] table of data values (may contain a single-byte
 *                          padding at the end)
 *
 * Total size is 4+(width * size + 1)/2 16-bit code units.
 */
void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
    // Add the table to the list - we'll process it later
    FillArrayData *tabRec = (FillArrayData *)
         oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
    tabRec->table = table;
    tabRec->vaddr = mir->offset;
    u2 width = tabRec->table[1];
    u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
    tabRec->size = (size * width) + 8;

    oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec);

    // Making a call - use explicit registers
    oatFlushAllRegs(cUnit);   /* Everything to home location */
    loadValueDirectFixed(cUnit, rlSrc, r0);
    loadWordDisp(cUnit, rSELF,
                 OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR);
    // Materialize a pointer to the fill data image
    newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
    oatClobberCalleeSave(cUnit);
    opReg(cUnit, kOpBlx, rLR);
}

void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
    RegLocation rlResult;
    rlSrc = loadValue(cUnit, rlSrc, kFPReg);
    rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
    newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg);
    storeValue(cUnit, rlDest, rlResult);
}

void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
    RegLocation rlResult;
    rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
    rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
    newLIR2(cUnit, kThumb2Vnegd, S2D(rlResult.lowReg, rlResult.highReg),
            S2D(rlSrc.lowReg, rlSrc.highReg));
    storeValueWide(cUnit, rlDest, rlResult);
}

/*
 * Handle simple case (thin lock) inline.  If it's complicated, bail
 * out to the heavyweight lock/unlock routines.  We'll use dedicated
 * registers here in order to be in the right position in case we
 * to bail to dvm[Lock/Unlock]Object(self, object)
 *
 * r0 -> self pointer [arg0 for dvm[Lock/Unlock]Object
 * r1 -> object [arg1 for dvm[Lock/Unlock]Object
 * r2 -> intial contents of object->lock, later result of strex
 * r3 -> self->threadId
 * r12 -> allow to be used by utilities as general temp
 *
 * The result of the strex is 0 if we acquire the lock.
 *
 * See comments in Sync.c for the layout of the lock word.
 * Of particular interest to this code is the test for the
 * simple case - which we handle inline.  For monitor enter, the
 * simple case is thin lock, held by no-one.  For monitor exit,
 * the simple case is thin lock, held by the unlocking thread with
 * a recurse count of 0.
 *
 * A minor complication is that there is a field in the lock word
 * unrelated to locking: the hash state.  This field must be ignored, but
 * preserved.
 *
 */
void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    oatFlushAllRegs(cUnit);
    DCHECK_EQ(LW_SHAPE_THIN, 0);
    loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
    oatLockCallTemps(cUnit);  // Prepare for explicit register usage
    genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
    loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
    newLIR3(cUnit, kThumb2Ldrex, r1, r0,
            Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
    // Align owner
    opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
    // Is lock unheld on lock or held by us (==threadId) on unlock?
    newLIR4(cUnit, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
    newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
    opRegImm(cUnit, kOpCmp, r1, 0);
    opIT(cUnit, kArmCondEq, "");
    newLIR4(cUnit, kThumb2Strex, r1, r2, r0,
            Object::MonitorOffset().Int32Value() >> 2);
    opRegImm(cUnit, kOpCmp, r1, 0);
    opIT(cUnit, kArmCondNe, "T");
    // Go expensive route - artLockObjectFromCode(self, obj);
    loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode),
                 rLR);
    oatClobberCalleeSave(cUnit);
    opReg(cUnit, kOpBlx, rLR);
    oatGenMemBarrier(cUnit, kSY);
}

/*
 * For monitor unlock, we don't have to use ldrex/strex.  Once
 * we've determined that the lock is thin and that we own it with
 * a zero recursion count, it's safe to punch it back to the
 * initial, unlock thin state with a store word.
 */
void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
{
    DCHECK_EQ(LW_SHAPE_THIN, 0);
    oatFlushAllRegs(cUnit);
    loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
    oatLockCallTemps(cUnit);  // Prepare for explicit register usage
    genNullCheck(cUnit, rlSrc.sRegLow, r0, mir);
    loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
    loadWordDisp(cUnit, rSELF, Thread::ThinLockIdOffset().Int32Value(), r2);
    // Is lock unheld on lock or held by us (==threadId) on unlock?
    opRegRegImm(cUnit, kOpAnd, r3, r1, (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
    // Align owner
    opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
    newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
    opRegReg(cUnit, kOpSub, r1, r2);
    opIT(cUnit, kArmCondEq, "EE");
    storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
    // Go expensive route - UnlockObjectFromCode(obj);
    loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode),
                 rLR);
    oatClobberCalleeSave(cUnit);
    opReg(cUnit, kOpBlx, rLR);
    oatGenMemBarrier(cUnit, kSY);
}

/*
 * 64-bit 3way compare function.
 *     mov   rX, #-1
 *     cmp   op1hi, op2hi
 *     blt   done
 *     bgt   flip
 *     sub   rX, op1lo, op2lo (treat as unsigned)
 *     beq   done
 *     ite   hi
 *     mov(hi)   rX, #-1
 *     mov(!hi)  rX, #1
 * flip:
 *     neg   rX
 * done:
 */
void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                RegLocation rlSrc1, RegLocation rlSrc2)
{
    LIR* target1;
    LIR* target2;
    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
    int tReg = oatAllocTemp(cUnit);
    loadConstant(cUnit, tReg, -1);
    opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
    LIR* branch1 = opCondBranch(cUnit, kCondLt, NULL);
    LIR* branch2 = opCondBranch(cUnit, kCondGt, NULL);
    opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
    LIR* branch3 = opCondBranch(cUnit, kCondEq, NULL);

    opIT(cUnit, kArmCondHi, "E");
    newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
    loadConstant(cUnit, tReg, 1);
    genBarrier(cUnit);

    target2 = newLIR0(cUnit, kPseudoTargetLabel);
    opRegReg(cUnit, kOpNeg, tReg, tReg);

    target1 = newLIR0(cUnit, kPseudoTargetLabel);

    RegLocation rlTemp = LOC_C_RETURN; // Just using as template, will change
    rlTemp.lowReg = tReg;
    storeValue(cUnit, rlDest, rlTemp);
    oatFreeTemp(cUnit, tReg);

    branch1->target = (LIR*)target1;
    branch2->target = (LIR*)target2;
    branch3->target = branch1->target;
}

/*
 * Generate a register comparison to an immediate and branch.  Caller
 * is responsible for setting branch target field.
 */
LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
                    int checkValue, LIR* target)
{
    LIR* branch;
    int modImm;
    ArmConditionCode armCond = oatArmConditionEncoding(cond);
    if ((LOWREG(reg)) && (checkValue == 0) &&
       ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
        branch = newLIR2(cUnit,
                         (armCond == 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 = oatAllocTemp(cUnit);
            loadConstant(cUnit, tReg, checkValue);
            opRegReg(cUnit, kOpCmp, reg, tReg);
        }
        branch = newLIR2(cUnit, kThumbBCond, 0, armCond);
    }
    branch->target = target;
    return branch;
}
LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
{
    LIR* res;
    ArmOpcode opcode;
    if (FPREG(rDest) || FPREG(rSrc))
        return fpRegCopy(cUnit, rDest, rSrc);
    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 = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
    if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
        res->flags.isNop = true;
    }
    return res;
}

LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
{
    LIR* res = opRegCopyNoInsert(cUnit, rDest, rSrc);
    oatAppendLIR(cUnit, (LIR*)res);
    return res;
}

void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
                           int srcLo, int srcHi)
{
    bool destFP = FPREG(destLo) && FPREG(destHi);
    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
    DCHECK_EQ(FPREG(srcLo), FPREG(srcHi));
    DCHECK_EQ(FPREG(destLo), FPREG(destHi));
    if (destFP) {
        if (srcFP) {
            opRegCopy(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) {
                opRegCopy(cUnit, destHi, srcHi);
                opRegCopy(cUnit, destLo, srcLo);
            } else {
                opRegCopy(cUnit, destLo, srcLo);
                opRegCopy(cUnit, destHi, srcHi);
            }
        }
    }
}


}  // namespace art
