/*
 * Copyright (C) 2012 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.
 */

#include "oat/runtime/oat_support_entrypoints.h"

namespace art {

/*
 * This source files contains "gen" codegen routines that should
 * be applicable to most targets.  Only mid-level support utilities
 * and "op" calls may be used here.
 */

typedef int (*NextCallInsn)(CompilationUnit*, MIR*, int, uint32_t dexIdx,
                            uint32_t methodIdx, uintptr_t directCode,
                            uintptr_t directMethod, InvokeType type);
LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target);

/*
 * If there are any ins passed in registers that have not been promoted
 * to a callee-save register, flush them to the frame.  Perform intial
 * assignment of promoted arguments.
 */
void flushIns(CompilationUnit* cUnit)
{
  /*
   * Dummy up a RegLocation for the incoming Method*
   * It will attempt to keep rARG0 live (or copy it to home location
   * if promoted).
   */
  RegLocation rlSrc = cUnit->regLocation[cUnit->methodSReg];
  RegLocation rlMethod = cUnit->regLocation[cUnit->methodSReg];
  rlSrc.location = kLocPhysReg;
  rlSrc.lowReg = rARG0;
  rlSrc.home = false;
  oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow);
  storeValue(cUnit, rlMethod, rlSrc);
  // If Method* has been promoted, explicitly flush
  if (rlMethod.location == kLocPhysReg) {
    storeWordDisp(cUnit, rSP, 0, rARG0);
  }

  if (cUnit->numIns == 0)
    return;
  const int numArgRegs = 3;
  static int argRegs[] = {rARG1, rARG2, rARG3};
  int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
  /*
   * Copy incoming arguments to their proper home locations.
   * NOTE: an older version of dx had an issue in which
   * it would reuse static method argument registers.
   * This could result in the same Dalvik virtual register
   * being promoted to both core and fp regs. To account for this,
   * we only copy to the corresponding promoted physical register
   * if it matches the type of the SSA name for the incoming
   * argument.  It is also possible that long and double arguments
   * end up half-promoted.  In those cases, we must flush the promoted
   * half to memory as well.
   */
  for (int i = 0; i < cUnit->numIns; i++) {
    PromotionMap* vMap = &cUnit->promotionMap[startVReg + i];
    if (i < numArgRegs) {
      // If arriving in register
      bool needFlush = true;
      RegLocation* tLoc = &cUnit->regLocation[startVReg + i];
      if ((vMap->coreLocation == kLocPhysReg) && !tLoc->fp) {
        opRegCopy(cUnit, vMap->coreReg, argRegs[i]);
        needFlush = false;
      } else if ((vMap->fpLocation == kLocPhysReg) && tLoc->fp) {
        opRegCopy(cUnit, vMap->fpReg, argRegs[i]);
        needFlush = false;
      } else {
        needFlush = true;
      }

      // For wide args, force flush if only half is promoted
      if (tLoc->wide) {
        PromotionMap* pMap = vMap + (tLoc->highWord ? -1 : +1);
        needFlush |= (pMap->coreLocation != vMap->coreLocation) ||
            (pMap->fpLocation != vMap->fpLocation);
      }
      if (needFlush) {
        storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                      argRegs[i], kWord);
      }
    } else {
      // If arriving in frame & promoted
      if (vMap->coreLocation == kLocPhysReg) {
        loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                     vMap->coreReg);
      }
      if (vMap->fpLocation == kLocPhysReg) {
        loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
                     vMap->fpReg);
      }
    }
  }
}

void scanMethodLiteralPool(CompilationUnit* cUnit, LIR** methodTarget, LIR** codeTarget, const DexFile* dexFile, uint32_t dexMethodIdx)
{
  LIR* curTarget = cUnit->methodLiteralList;
  LIR* nextTarget = curTarget != NULL ? curTarget->next : NULL;
  while (curTarget != NULL && nextTarget != NULL) {
    if (curTarget->operands[0] == (int)dexFile &&
      nextTarget->operands[0] == (int)dexMethodIdx) {
    *codeTarget = curTarget;
    *methodTarget = nextTarget;
    DCHECK((*codeTarget)->next == *methodTarget);
    DCHECK_EQ((*codeTarget)->operands[0], (int)dexFile);
    DCHECK_EQ((*methodTarget)->operands[0], (int)dexMethodIdx);
    break;
    }
    curTarget = nextTarget->next;
    nextTarget = curTarget != NULL ? curTarget->next : NULL;
  }
}

/*
 * Bit of a hack here - in the absence of a real scheduling pass,
 * emit the next instruction in static & direct invoke sequences.
 */
int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
                   int state, uint32_t dexIdx, uint32_t unused,
                   uintptr_t directCode, uintptr_t directMethod,
                   InvokeType type)
{
#if !defined(TARGET_ARM)
  directCode = 0;
  directMethod = 0;
#endif
  if (directCode != 0 && directMethod != 0) {
    switch (state) {
    case 0:  // Get the current Method* [sets rARG0]
      if (directCode != (uintptr_t)-1) {
        loadConstant(cUnit, rINVOKE_TGT, directCode);
      } else {
        LIR* dataTarget = scanLiteralPool(cUnit->codeLiteralList, dexIdx, 0);
        if (dataTarget == NULL) {
          dataTarget = addWordData(cUnit, &cUnit->codeLiteralList, dexIdx);
          dataTarget->operands[1] = type;
        }
#if defined(TARGET_ARM)
        LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
                                kThumb2LdrPcRel12, rINVOKE_TGT, 0, 0, 0, 0,
                                dataTarget);
        oatAppendLIR(cUnit, loadPcRel);
#else
        UNIMPLEMENTED(FATAL) << (void*)dataTarget;
#endif
      }
      if (directMethod != (uintptr_t)-1) {
        loadConstant(cUnit, rARG0, directMethod);
      } else {
        LIR* dataTarget = scanLiteralPool(cUnit->methodLiteralList, dexIdx, 0);
        if (dataTarget == NULL) {
          dataTarget = addWordData(cUnit, &cUnit->methodLiteralList, dexIdx);
          dataTarget->operands[1] = type;
        }
#if defined(TARGET_ARM)
        LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
                                kThumb2LdrPcRel12, rARG0, 0, 0, 0, 0,
                                dataTarget);
        oatAppendLIR(cUnit, loadPcRel);
#else
        UNIMPLEMENTED(FATAL) << (void*)dataTarget;
#endif
      }
      break;
    default:
      return -1;
    }
  } else {
    switch (state) {
    case 0:  // Get the current Method* [sets rARG0]
      // TUNING: we can save a reg copy if Method* has been promoted
      loadCurrMethodDirect(cUnit, rARG0);
      break;
    case 1:  // Get method->dex_cache_resolved_methods_
      loadWordDisp(cUnit, rARG0,
        Method::DexCacheResolvedMethodsOffset().Int32Value(),
        rARG0);
      // Set up direct code if known.
      if (directCode != 0) {
        if (directCode != (uintptr_t)-1) {
          loadConstant(cUnit, rINVOKE_TGT, directCode);
        } else {
          LIR* dataTarget = scanLiteralPool(cUnit->codeLiteralList, dexIdx, 0);
          if (dataTarget == NULL) {
            dataTarget = addWordData(cUnit, &cUnit->codeLiteralList, dexIdx);
            dataTarget->operands[1] = type;
          }
#if defined(TARGET_ARM)
          LIR* loadPcRel = rawLIR(cUnit, cUnit->currentDalvikOffset,
                                  kThumb2LdrPcRel12, rINVOKE_TGT, 0, 0, 0, 0,
                                  dataTarget);
          oatAppendLIR(cUnit, loadPcRel);
#else
          UNIMPLEMENTED(FATAL) << (void*)dataTarget;
#endif
        }
      }
      break;
    case 2:  // Grab target method*
      loadWordDisp(cUnit, rARG0,
                   Array::DataOffset(sizeof(Object*)).Int32Value() + dexIdx * 4,
                   rARG0);
      break;
#if !defined(TARGET_X86)
    case 3:  // Grab the code from the method*
      if (directCode == 0) {
        loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
                     rINVOKE_TGT);
      }
      break;
#endif
    default:
      return -1;
    }
  }
  return state + 1;
}

/*
 * Bit of a hack here - in the absence of a real scheduling pass,
 * emit the next instruction in a virtual invoke sequence.
 * We can use rLR as a temp prior to target address loading
 * Note also that we'll load the first argument ("this") into
 * rARG1 here rather than the standard loadArgRegs.
 */
int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
                  int state, uint32_t dexIdx, uint32_t methodIdx,
                  uintptr_t unused, uintptr_t unused2, InvokeType unused3)
{
  RegLocation rlArg;
  /*
   * This is the fast path in which the target virtual method is
   * fully resolved at compile time.
   */
  switch (state) {
    case 0:  // Get "this" [set rARG1]
      rlArg = oatGetSrc(cUnit, mir, 0);
      loadValueDirectFixed(cUnit, rlArg, rARG1);
      break;
    case 1: // Is "this" null? [use rARG1]
      genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
      // get this->klass_ [use rARG1, set rINVOKE_TGT]
      loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(),
                   rINVOKE_TGT);
      break;
    case 2: // Get this->klass_->vtable [usr rINVOKE_TGT, set rINVOKE_TGT]
      loadWordDisp(cUnit, rINVOKE_TGT, Class::VTableOffset().Int32Value(),
                   rINVOKE_TGT);
      break;
    case 3: // Get target method [use rINVOKE_TGT, set rARG0]
      loadWordDisp(cUnit, rINVOKE_TGT, (methodIdx * 4) +
                   Array::DataOffset(sizeof(Object*)).Int32Value(), rARG0);
      break;
#if !defined(TARGET_X86)
    case 4: // Get the compiled code address [uses rARG0, sets rINVOKE_TGT]
      loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
                   rINVOKE_TGT);
      break;
#endif
    default:
      return -1;
  }
  return state + 1;
}

int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
                     int state, uint32_t dexIdx, uint32_t methodIdx)
{
  /*
   * This handles the case in which the base method is not fully
   * resolved at compile time, we bail to a runtime helper.
   */
  if (state == 0) {
#if !defined(TARGET_X86)
    // Load trampoline target
    loadWordDisp(cUnit, rSELF, trampoline, rINVOKE_TGT);
#endif
    // Load rARG0 with method index
    loadConstant(cUnit, rARG0, dexIdx);
    return 1;
  }
  return -1;
}

int nextStaticCallInsnSP(CompilationUnit* cUnit, MIR* mir,
                         int state, uint32_t dexIdx, uint32_t methodIdx,
                         uintptr_t unused, uintptr_t unused2,
                         InvokeType unused3)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

int nextDirectCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
                         uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
                         uintptr_t unused2, InvokeType unused3)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
                        uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
                        uintptr_t unused2, InvokeType unused3)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir, int state,
                    uint32_t dexIdx, uint32_t methodIdx, uintptr_t unused,
                    uintptr_t unused2, InvokeType unused3)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

/*
 * All invoke-interface calls bounce off of art_invoke_interface_trampoline,
 * which will locate the target and continue on via a tail call.
 */
int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir, int state,
                          uint32_t dexIdx, uint32_t unused, uintptr_t unused2,
                          uintptr_t unused3, InvokeType unused4)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

int nextInterfaceCallInsnWithAccessCheck(CompilationUnit* cUnit, MIR* mir,
                                         int state, uint32_t dexIdx,
                                         uint32_t unused, uintptr_t unused2,
                                         uintptr_t unused3, InvokeType unused4)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
}

int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
                int callState, NextCallInsn nextCallInsn, uint32_t dexIdx,
                uint32_t methodIdx, uintptr_t directCode,
                uintptr_t directMethod, InvokeType type, bool skipThis)
{
  int lastArgReg = rARG3;
  int nextReg = rARG1;
  int nextArg = 0;
  if (skipThis) {
    nextReg++;
    nextArg++;
  }
  for (; (nextReg <= lastArgReg) && (nextArg < mir->ssaRep->numUses); nextReg++) {
    RegLocation rlArg = oatGetRawSrc(cUnit, mir, nextArg++);
    rlArg = oatUpdateRawLoc(cUnit, rlArg);
    if (rlArg.wide && (nextReg <= rARG2)) {
      loadValueDirectWideFixed(cUnit, rlArg, nextReg, nextReg + 1);
      nextReg++;
      nextArg++;
    } else {
      rlArg.wide = false;
      loadValueDirectFixed(cUnit, rlArg, nextReg);
    }
    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                 directCode, directMethod, type);
  }
  return callState;
}

/*
 * Load up to 5 arguments, the first three of which will be in
 * rARG1 .. rARG3.  On entry rARG0 contains the current method pointer,
 * and as part of the load sequence, it must be replaced with
 * the target method pointer.  Note, this may also be called
 * for "range" variants if the number of arguments is 5 or fewer.
 */
int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
                         DecodedInstruction* dInsn, int callState,
                         LIR** pcrLabel, NextCallInsn nextCallInsn,
                         uint32_t dexIdx, uint32_t methodIdx,
                         uintptr_t directCode, uintptr_t directMethod,
                         InvokeType type, bool skipThis)
{
  RegLocation rlArg;

  /* If no arguments, just return */
  if (dInsn->vA == 0)
    return callState;

  callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                           directCode, directMethod, type);

  DCHECK_LE(dInsn->vA, 5U);
  if (dInsn->vA > 3) {
    uint32_t nextUse = 3;
    //Detect special case of wide arg spanning arg3/arg4
    RegLocation rlUse0 = oatGetRawSrc(cUnit, mir, 0);
    RegLocation rlUse1 = oatGetRawSrc(cUnit, mir, 1);
    RegLocation rlUse2 = oatGetRawSrc(cUnit, mir, 2);
    if (((!rlUse0.wide && !rlUse1.wide) || rlUse0.wide) &&
      rlUse2.wide) {
      int reg = -1;
      // Wide spans, we need the 2nd half of uses[2].
      rlArg = oatUpdateLocWide(cUnit, rlUse2);
      if (rlArg.location == kLocPhysReg) {
        reg = rlArg.highReg;
      } else {
        // rARG2 & rARG3 can safely be used here
        reg = rARG3;
        loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg);
        callState = nextCallInsn(cUnit, mir, callState, dexIdx,
                                 methodIdx, directCode, directMethod, type);
      }
      storeBaseDisp(cUnit, rSP, (nextUse + 1) * 4, reg, kWord);
      storeBaseDisp(cUnit, rSP, 16 /* (3+1)*4 */, reg, kWord);
      callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                               directCode, directMethod, type);
      nextUse++;
    }
    // Loop through the rest
    while (nextUse < dInsn->vA) {
      int lowReg;
      int highReg = -1;
      rlArg = oatGetRawSrc(cUnit, mir, nextUse);
      rlArg = oatUpdateRawLoc(cUnit, rlArg);
      if (rlArg.location == kLocPhysReg) {
        lowReg = rlArg.lowReg;
        highReg = rlArg.highReg;
      } else {
        lowReg = rARG2;
        if (rlArg.wide) {
          highReg = rARG3;
          loadValueDirectWideFixed(cUnit, rlArg, lowReg, highReg);
        } else {
          loadValueDirectFixed(cUnit, rlArg, lowReg);
        }
        callState = nextCallInsn(cUnit, mir, callState, dexIdx,
                                 methodIdx, directCode, directMethod, type);
      }
      int outsOffset = (nextUse + 1) * 4;
      if (rlArg.wide) {
        storeBaseDispWide(cUnit, rSP, outsOffset, lowReg, highReg);
        nextUse += 2;
      } else {
        storeWordDisp(cUnit, rSP, outsOffset, lowReg);
        nextUse++;
      }
      callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                               directCode, directMethod, type);
    }
  }

  callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
                          dexIdx, methodIdx, directCode, directMethod,
                          type, skipThis);

  if (pcrLabel) {
    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
  }
  return callState;
}

/*
 * May have 0+ arguments (also used for jumbo).  Note that
 * source virtual registers may be in physical registers, so may
 * need to be flushed to home location before copying.  This
 * applies to arg3 and above (see below).
 *
 * Two general strategies:
 *    If < 20 arguments
 *       Pass args 3-18 using vldm/vstm block copy
 *       Pass arg0, arg1 & arg2 in rARG1-rARG3
 *    If 20+ arguments
 *       Pass args arg19+ using memcpy block copy
 *       Pass arg0, arg1 & arg2 in rARG1-rARG3
 *
 */
int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
                       DecodedInstruction* dInsn, int callState,
                       LIR** pcrLabel, NextCallInsn nextCallInsn,
                       uint32_t dexIdx, uint32_t methodIdx,
                       uintptr_t directCode, uintptr_t directMethod,
                       InvokeType type, bool skipThis)
{
  int firstArg = dInsn->vC;
  int numArgs = dInsn->vA;

  // If we can treat it as non-range (Jumbo ops will use range form)
  if (numArgs <= 5)
    return genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pcrLabel,
                                nextCallInsn, dexIdx, methodIdx,
                                directCode, directMethod, type, skipThis);
  /*
   * Make sure range list doesn't span the break between in normal
   * Dalvik vRegs and the ins.
   */
  int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow;
  int boundaryReg = cUnit->numDalvikRegisters - cUnit->numIns;
  if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) {
    LOG(FATAL) << "Argument list spanned locals & args";
  }

  /*
   * First load the non-register arguments.  Both forms expect all
   * of the source arguments to be in their home frame location, so
   * scan the sReg names and flush any that have been promoted to
   * frame backing storage.
   */
  // Scan the rest of the args - if in physReg flush to memory
  for (int nextArg = 0; nextArg < numArgs;) {
    RegLocation loc = oatGetRawSrc(cUnit, mir, nextArg);
    if (loc.wide) {
      loc = oatUpdateLocWide(cUnit, loc);
      if ((nextArg >= 2) && (loc.location == kLocPhysReg)) {
        storeBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
                          loc.lowReg, loc.highReg);
      }
      nextArg += 2;
    } else {
      loc = oatUpdateLoc(cUnit, loc);
      if ((nextArg >= 3) && (loc.location == kLocPhysReg)) {
        storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
                      loc.lowReg, kWord);
      }
      nextArg++;
    }
  }

  int startOffset = oatSRegOffset(cUnit,
    cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow);
  int outsOffset = 4 /* Method* */ + (3 * 4);
#if defined(TARGET_MIPS) || defined(TARGET_X86)
  // Generate memcpy
  opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
  opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
  callRuntimeHelperRegRegImm(cUnit, ENTRYPOINT_OFFSET(pMemcpy),
                             rARG0, rARG1, (numArgs - 3) * 4);
#else
  if (numArgs >= 20) {
    // Generate memcpy
    opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
    opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
    callRuntimeHelperRegRegImm(cUnit, ENTRYPOINT_OFFSET(pMemcpy),
                               rARG0, rARG1, (numArgs - 3) * 4);
  } else {
    // Use vldm/vstm pair using rARG3 as a temp
    int regsLeft = std::min(numArgs - 3, 16);
    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);
    opRegRegImm(cUnit, kOpAdd, rARG3, rSP, startOffset);
    LIR* ld = newLIR3(cUnit, kThumb2Vldms, rARG3, fr0, regsLeft);
    //TUNING: loosen barrier
    ld->defMask = ENCODE_ALL;
    setMemRefType(ld, true /* isLoad */, kDalvikReg);
    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);
    opRegRegImm(cUnit, kOpAdd, rARG3, rSP, 4 /* Method* */ + (3 * 4));
    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);
    LIR* st = newLIR3(cUnit, kThumb2Vstms, rARG3, fr0, regsLeft);
    setMemRefType(st, false /* isLoad */, kDalvikReg);
    st->defMask = ENCODE_ALL;
    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);

  }
#endif

  callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
                          dexIdx, methodIdx, directCode, directMethod,
                          type, skipThis);

  callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx,
                           directCode, directMethod, type);
  if (pcrLabel) {
    *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
  }
  return callState;
}

RegLocation inlineTarget(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
{
  RegLocation res;
  mir = oatFindMoveResult(cUnit, bb, mir, false);
  if (mir == NULL) {
    res = oatGetReturn(cUnit, false);
  } else {
    res = oatGetDest(cUnit, mir, 0);
    mir->dalvikInsn.opcode = Instruction::NOP;
  }
  return res;
}

RegLocation inlineTargetWide(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
{
  RegLocation res;
  mir = oatFindMoveResult(cUnit, bb, mir, true);
  if (mir == NULL) {
    res = oatGetReturnWide(cUnit, false);
  } else {
    res = oatGetDestWide(cUnit, mir, 0, 1);
    mir->dalvikInsn.opcode = Instruction::NOP;
  }
  return res;
}

bool genInlinedCharAt(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
            InvokeType type, bool isRange)
{
#if defined(TARGET_ARM)
  // Location of reference to data array
  int valueOffset = String::ValueOffset().Int32Value();
  // Location of count
  int countOffset = String::CountOffset().Int32Value();
  // Starting offset within data array
  int offsetOffset = String::OffsetOffset().Int32Value();
  // Start of char data with array_
  int dataOffset = Array::DataOffset(sizeof(uint16_t)).Int32Value();

  RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
  RegLocation rlIdx = oatGetSrc(cUnit, mir, 1);
  rlObj = loadValue(cUnit, rlObj, kCoreReg);
  rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
  int regMax;
  int regOff = oatAllocTemp(cUnit);
  int regPtr = oatAllocTemp(cUnit);
  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
  bool rangeCheck = (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK));
  if (rangeCheck) {
    regMax = oatAllocTemp(cUnit);
    loadWordDisp(cUnit, rlObj.lowReg, countOffset, regMax);
  }
  loadWordDisp(cUnit, rlObj.lowReg, offsetOffset, regOff);
  loadWordDisp(cUnit, rlObj.lowReg, valueOffset, regPtr);
  LIR* launchPad = NULL;
  if (rangeCheck) {
    // Set up a launch pad to allow retry in case of bounds violation */
    launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
    oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
                          (intptr_t)launchPad);
    opRegReg(cUnit, kOpCmp, rlIdx.lowReg, regMax);
    oatFreeTemp(cUnit, regMax);
    opCondBranch(cUnit, kCondCs, launchPad);
  }
  opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
  opRegReg(cUnit, kOpAdd, regOff, rlIdx.lowReg);
  RegLocation rlDest = inlineTarget(cUnit, bb, mir);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  loadBaseIndexed(cUnit, regPtr, regOff, rlResult.lowReg, 1, kUnsignedHalf);
  oatFreeTemp(cUnit, regOff);
  oatFreeTemp(cUnit, regPtr);
  storeValue(cUnit, rlDest, rlResult);
  if (rangeCheck) {
    launchPad->operands[2] = NULL;  // no resumption
    launchPad->operands[3] = (uintptr_t)bb;
  }
  // Record that we've already inlined & null checked
  mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  return true;
#else
  return false;
#endif
}

bool genInlinedMinMaxInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir,
             bool isMin)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc1 = oatGetSrc(cUnit, mir, 0);
  RegLocation rlSrc2 = oatGetSrc(cUnit, mir, 1);
  rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
  rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, bb, mir);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
  opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
  genBarrier(cUnit);
  storeValue(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

// Generates an inlined String.isEmpty or String.length.
bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit,
                                     BasicBlock* bb, MIR* mir, bool isEmpty)
{
#if defined(TARGET_ARM)
  // dst = src.length();
  RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
  rlObj = loadValue(cUnit, rlObj, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, bb, mir);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);
  loadWordDisp(cUnit, rlObj.lowReg, String::CountOffset().Int32Value(),
               rlResult.lowReg);
  if (isEmpty) {
    // dst = (dst == 0);
    int tReg = oatAllocTemp(cUnit);
    opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg);
    opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg);
  }
  storeValue(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

bool genInlinedAbsInt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, bb, mir);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  int signReg = oatAllocTemp(cUnit);
  // abs(x) = y<=x>>31, (x+y)^y.
  opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.lowReg, 31);
  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
  opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
  storeValue(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

bool genInlinedAbsLong(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
  RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  int signReg = oatAllocTemp(cUnit);
  // abs(x) = y<=x>>31, (x+y)^y.
  opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.highReg, 31);
  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
  opRegRegReg(cUnit, kOpAdc, rlResult.highReg, rlSrc.highReg, signReg);
  opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
  opRegReg(cUnit, kOpXor, rlResult.highReg, signReg);
  storeValueWide(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

bool genInlinedFloatCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
  RegLocation rlDest = inlineTarget(cUnit, bb, mir);
  storeValue(cUnit, rlDest, rlSrc);
  return true;
#else
  return false;
#endif
}

bool genInlinedDoubleCvt(CompilationUnit *cUnit, BasicBlock* bb, MIR *mir)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
  RegLocation rlDest = inlineTargetWide(cUnit, bb, mir);
  storeValueWide(cUnit, rlDest, rlSrc);
  return true;
#else
  return false;
#endif
}

/*
 * Fast string.indexOf(I) & (II).  Tests for simple case of char <= 0xffff,
 * otherwise bails to standard library code.
 */
bool genInlinedIndexOf(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
                       InvokeType type, bool zeroBased)
{
#if defined(TARGET_ARM)

  oatClobberCalleeSave(cUnit);
  oatLockCallTemps(cUnit);  // Using fixed registers
  int regPtr = rARG0;
  int regChar = rARG1;
  int regStart = rARG2;

  RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
  RegLocation rlChar = oatGetSrc(cUnit, mir, 1);
  RegLocation rlStart = oatGetSrc(cUnit, mir, 2);
  loadValueDirectFixed(cUnit, rlObj, regPtr);
  loadValueDirectFixed(cUnit, rlChar, regChar);
  if (zeroBased) {
    loadConstant(cUnit, regStart, 0);
  } else {
    loadValueDirectFixed(cUnit, rlStart, regStart);
  }
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pIndexOf));
  genNullCheck(cUnit, rlObj.sRegLow, regPtr, mir);
  LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
  oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
              (intptr_t)launchPad);
  opCmpImmBranch(cUnit, kCondGt, regChar, 0xFFFF, launchPad);
  opReg(cUnit, kOpBlx, rTgt);
  LIR* resumeTgt = newLIR0(cUnit, kPseudoTargetLabel);
  launchPad->operands[2] = (uintptr_t)resumeTgt;
  launchPad->operands[3] = (uintptr_t)bb;
  // Record that we've already inlined & null checked
  mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  return true;
#else
  return false;
#endif
}

/* Fast string.compareTo(Ljava/lang/string;)I. */
bool genInlinedStringCompareTo(CompilationUnit* cUnit, BasicBlock* bb,
                               MIR* mir, InvokeType type)
{
#if defined(TARGET_ARM)
  oatClobberCalleeSave(cUnit);
  oatLockCallTemps(cUnit);  // Using fixed registers
  int regThis = rARG0;
  int regCmp = rARG1;

  RegLocation rlThis = oatGetSrc(cUnit, mir, 0);
  RegLocation rlCmp = oatGetSrc(cUnit, mir, 1);
  loadValueDirectFixed(cUnit, rlThis, regThis);
  loadValueDirectFixed(cUnit, rlCmp, regCmp);
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pStringCompareTo));
  genNullCheck(cUnit, rlThis.sRegLow, regThis, mir);
  //TUNING: check if rlCmp.sRegLow is already null checked
  LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (int)mir, type);
  oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
              (intptr_t)launchPad);
  opCmpImmBranch(cUnit, kCondEq, regCmp, 0, launchPad);
  opReg(cUnit, kOpBlx, rTgt);
  launchPad->operands[2] = NULL;  // No return possible
  launchPad->operands[3] = (uintptr_t)bb;
  // Record that we've already inlined & null checked
  mir->optimizationFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  return true;
#else
  return false;
#endif
}

bool genIntrinsic(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
                  InvokeType type, bool isRange)
{
  if ((mir->optimizationFlags & MIR_INLINED) || isRange)  {
    return false;
  }
  /*
   * TODO: move these to a target-specific structured constant array
   * and use a generic match function.  The list of intrinsics may be
   * slightly different depending on target.
   * TODO: Fold this into a matching function that runs during
   * basic block building.  This should be part of the action for
   * small method inlining and recognition of the special object init
   * method.  By doing this during basic block construction, we can also
   * take advantage of/generate new useful dataflow info.
   */
  std::string tgtMethod(PrettyMethod(mir->dalvikInsn.vB, *cUnit->dex_file));
  if (tgtMethod.compare("char java.lang.String.charAt(int)") == 0) {
    return genInlinedCharAt(cUnit, bb, mir, type, isRange);
  }
  if (tgtMethod.compare("int java.lang.Math.min(int, int)") == 0) {
    return genInlinedMinMaxInt(cUnit, bb, mir, true /* isMin */);
  }
  if (tgtMethod.compare("int java.lang.Math.max(int, int)") == 0) {
    return genInlinedMinMaxInt(cUnit, bb, mir, false /* isMin */);
  }
  if (tgtMethod.compare("int java.lang.String.length()") == 0) {
    return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, false /* isEmpty */);
  }
  if (tgtMethod.compare("boolean java.lang.String.isEmpty()") == 0) {
    return genInlinedStringIsEmptyOrLength(cUnit, bb, mir, true /* isEmpty */);
  }
  if (tgtMethod.compare("int java.lang.Math.abs(int)") == 0) {
    return genInlinedAbsInt(cUnit, bb, mir);
  }
  if (tgtMethod.compare("long java.lang.Math.abs(long)") == 0) {
    return genInlinedAbsLong(cUnit, bb, mir);
  }
  if (tgtMethod.compare("int java.lang.Float.floatToRawIntBits(float)") == 0) {
    return genInlinedFloatCvt(cUnit, bb, mir);
  }
  if (tgtMethod.compare("float java.lang.Float.intBitsToFloat(int)") == 0) {
    return genInlinedFloatCvt(cUnit, bb, mir);
  }
  if (tgtMethod.compare("long java.lang.Double.doubleToRawLongBits(double)") == 0) {
    return genInlinedDoubleCvt(cUnit, bb, mir);
  }
  if (tgtMethod.compare("double java.lang.Double.longBitsToDouble(long)") == 0) {
    return genInlinedDoubleCvt(cUnit, bb, mir);
  }
  if (tgtMethod.compare("int java.lang.String.indexOf(int, int)") == 0) {
    return genInlinedIndexOf(cUnit, bb, mir, type, false /* base 0 */);
  }
  if (tgtMethod.compare("int java.lang.String.indexOf(int)") == 0) {
    return genInlinedIndexOf(cUnit, bb, mir, type, true /* base 0 */);
  }
  if (tgtMethod.compare("int java.lang.String.compareTo(java.lang.String)") == 0) {
    return genInlinedStringCompareTo(cUnit, bb, mir, type);
  }
  return false;
}


}  // namespace art
