/*
 * 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*, CallInfo*, 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.
 *
 * argLocs is an array of location records describing the incoming arguments
 * with one location record per word of argument.
 */
void flushIns(CompilationUnit* cUnit, RegLocation* argLocs, RegLocation rlMethod)
{
  /*
   * 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 = rlMethod;
  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 = &argLocs[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, CallInfo* info,
                   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,
        AbstractMethod::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, AbstractMethod::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, CallInfo* info,
                  int state, uint32_t dexIdx, uint32_t methodIdx,
                  uintptr_t unused, uintptr_t unused2, InvokeType unused3)
{
  /*
   * 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]
      RegLocation  rlArg = info->args[0];
      loadValueDirectFixed(cUnit, rlArg, rARG1);
      break;
    }
    case 1: // Is "this" null? [use rARG1]
      genNullCheck(cUnit, info->args[0].sRegLow, rARG1, info->optFlags);
      // 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, AbstractMethod::GetCodeOffset().Int32Value(),
                   rINVOKE_TGT);
      break;
#endif
    default:
      return -1;
  }
  return state + 1;
}

/*
 * 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, CallInfo* info, int state,
                          uint32_t dexIdx, uint32_t unused, uintptr_t unused2,
                          uintptr_t directMethod, InvokeType unused4)
{
#if !defined(TARGET_ARM)
  directMethod = 0;
#endif
#if !defined(TARGET_X86)
  int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline);
#endif

  if (directMethod != 0) {
    switch (state) {
      case 0:  // Load the trampoline target [sets rINVOKE_TGT].
#if !defined(TARGET_X86)
        loadWordDisp(cUnit, rSELF, trampoline, rINVOKE_TGT);
#endif
        // Get the interface Method* [sets rARG0]
        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] = kInterface;
          }
#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: remove copy of method if it is promoted.
        loadCurrMethodDirect(cUnit, rARG0);
        // Load the trampoline target [sets rINVOKE_TGT].
#if !defined(TARGET_X86)
        loadWordDisp(cUnit, rSELF, trampoline, rINVOKE_TGT);
#endif
        break;
    case 1:  // Get method->dex_cache_resolved_methods_ [set/use rARG0]
      loadWordDisp(cUnit, rARG0,
                   AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(),
                   rARG0);
      break;
    case 2:  // Grab target method* [set/use rARG0]
      loadWordDisp(cUnit, rARG0,
                   Array::DataOffset(sizeof(Object*)).Int32Value() + dexIdx * 4,
                   rARG0);
      break;
    default:
      return -1;
    }
  }
  return state + 1;
}

int nextInvokeInsnSP(CompilationUnit* cUnit, CallInfo* info, 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, CallInfo* info,
                         int state, uint32_t dexIdx, uint32_t methodIdx,
                         uintptr_t unused, uintptr_t unused2,
                         InvokeType unused3)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
  return nextInvokeInsnSP(cUnit, info, trampoline, state, dexIdx, 0);
}

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

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

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

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

int loadArgRegs(CompilationUnit* cUnit, CallInfo* info, 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 < info->numArgWords); nextReg++) {
    RegLocation rlArg = info->args[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, info, 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, CallInfo* info,
                         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 (info->numArgWords == 0)
    return callState;

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

  DCHECK_LE(info->numArgWords, 5);
  if (info->numArgWords > 3) {
    int32_t nextUse = 3;
    //Detect special case of wide arg spanning arg3/arg4
    RegLocation rlUse0 = info->args[0];
    RegLocation rlUse1 = info->args[1];
    RegLocation rlUse2 = info->args[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, info, 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, info, callState, dexIdx, methodIdx,
                               directCode, directMethod, type);
      nextUse++;
    }
    // Loop through the rest
    while (nextUse < info->numArgWords) {
      int lowReg;
      int highReg = -1;
      rlArg = info->args[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, info, 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, info, callState, dexIdx, methodIdx,
                               directCode, directMethod, type);
    }
  }

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

  if (pcrLabel) {
    *pcrLabel = genNullCheck(cUnit, info->args[0].sRegLow, rARG1,
                             info->optFlags);
  }
  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, CallInfo* info, int callState,
                       LIR** pcrLabel, NextCallInsn nextCallInsn,
                       uint32_t dexIdx, uint32_t methodIdx,
                       uintptr_t directCode, uintptr_t directMethod,
                       InvokeType type, bool skipThis)
{

  // If we can treat it as non-range (Jumbo ops will use range form)
  if (info->numArgWords <= 5)
    return genDalvikArgsNoRange(cUnit, info, callState, pcrLabel,
                                nextCallInsn, dexIdx, methodIdx,
                                directCode, directMethod, type, skipThis);
  /*
   * 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 < info->numArgWords;) {
    RegLocation loc = info->args[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, info->args[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, (info->numArgWords - 3) * 4, false);
#else
  if (info->numArgWords >= 20) {
    // Generate memcpy
    opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
    opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
    callRuntimeHelperRegRegImm(cUnit, ENTRYPOINT_OFFSET(pMemcpy),
                               rARG0, rARG1, (info->numArgWords - 3) * 4, false);
  } else {
    // Use vldm/vstm pair using rARG3 as a temp
    int regsLeft = std::min(info->numArgWords - 3, 16);
    callState = nextCallInsn(cUnit, info, 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, info, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);
    opRegRegImm(cUnit, kOpAdd, rARG3, rSP, 4 /* Method* */ + (3 * 4));
    callState = nextCallInsn(cUnit, info, 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, info, callState, dexIdx, methodIdx,
                             directCode, directMethod, type);

  }
#endif

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

  callState = nextCallInsn(cUnit, info, callState, dexIdx, methodIdx,
                           directCode, directMethod, type);
  if (pcrLabel) {
    *pcrLabel = genNullCheck(cUnit, info->args[0].sRegLow, rARG1,
                             info->optFlags);
  }
  return callState;
}

RegLocation inlineTarget(CompilationUnit* cUnit, CallInfo* info)
{
  RegLocation res;
  if (info->result.location == kLocInvalid) {
    res = oatGetReturn(cUnit, false);
  } else {
    res = info->result;
  }
  return res;
}

RegLocation inlineTargetWide(CompilationUnit* cUnit, CallInfo* info)
{
  RegLocation res;
  if (info->result.location == kLocInvalid) {
    res = oatGetReturnWide(cUnit, false);
  } else {
    res = info->result;
  }
  return res;
}

bool genInlinedCharAt(CompilationUnit* cUnit, CallInfo* info)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  // 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 = info->args[0];
  RegLocation rlIdx = info->args[1];
  rlObj = loadValue(cUnit, rlObj, kCoreReg);
  rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
  int regMax;
  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, info->optFlags);
  bool rangeCheck = (!(info->optFlags & MIR_IGNORE_RANGE_CHECK));
  LIR* launchPad = NULL;
#if !defined(TARGET_X86)
  int regOff = oatAllocTemp(cUnit);
  int regPtr = oatAllocTemp(cUnit);
  if (rangeCheck) {
    regMax = oatAllocTemp(cUnit);
    loadWordDisp(cUnit, rlObj.lowReg, countOffset, regMax);
  }
  loadWordDisp(cUnit, rlObj.lowReg, offsetOffset, regOff);
  loadWordDisp(cUnit, rlObj.lowReg, valueOffset, regPtr);
  if (rangeCheck) {
    // Set up a launch pad to allow retry in case of bounds violation */
    launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
    oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
                          (intptr_t)launchPad);
    opRegReg(cUnit, kOpCmp, rlIdx.lowReg, regMax);
    oatFreeTemp(cUnit, regMax);
    opCondBranch(cUnit, kCondCs, launchPad);
  }
#else
  if (rangeCheck) {
    regMax = oatAllocTemp(cUnit);
    loadWordDisp(cUnit, rlObj.lowReg, countOffset, regMax);
    // Set up a launch pad to allow retry in case of bounds violation */
    launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
    oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
                          (intptr_t)launchPad);
    opRegReg(cUnit, kOpCmp, rlIdx.lowReg, regMax);
    oatFreeTemp(cUnit, regMax);
    opCondBranch(cUnit, kCondCc, launchPad);
  }
  int regOff = oatAllocTemp(cUnit);
  int regPtr = oatAllocTemp(cUnit);
  loadWordDisp(cUnit, rlObj.lowReg, offsetOffset, regOff);
  loadWordDisp(cUnit, rlObj.lowReg, valueOffset, regPtr);
#endif
  opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
  opRegReg(cUnit, kOpAdd, regOff, rlIdx.lowReg);
  oatFreeTemp(cUnit, rlObj.lowReg);
  oatFreeTemp(cUnit, rlIdx.lowReg);
  RegLocation rlDest = inlineTarget(cUnit, info);
  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] = 0;  // no resumption
  }
  // Record that we've already inlined & null checked
  info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  return true;
#else
  return false;
#endif
}

bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  RegLocation rlSrc1 = info->args[0];
  RegLocation rlSrc2 = info->args[1];
  rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
  rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, info);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
#if defined(TARGET_ARM)
  opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
  genBarrier(cUnit);
#elif defined(TARGET_X86)
  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, isMin ? kX86CondG : kX86CondL);
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
  LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
  branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
#endif
  storeValue(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

// Generates an inlined String.isEmpty or String.length.
bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, CallInfo* info,
                                     bool isEmpty)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  // dst = src.length();
  RegLocation rlObj = info->args[0];
  rlObj = loadValue(cUnit, rlObj, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, info);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, info->optFlags);
  loadWordDisp(cUnit, rlObj.lowReg, String::CountOffset().Int32Value(),
               rlResult.lowReg);
  if (isEmpty) {
    // dst = (dst == 0);
#if defined(TARGET_ARM)
    int tReg = oatAllocTemp(cUnit);
    opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg);
    opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg);
#elif defined(TARGET_X86)
    opRegImm(cUnit, kOpSub, rlResult.lowReg, 1);
    opRegImm(cUnit, kOpLsr, rlResult.lowReg, 31);
#endif
  }
  storeValue(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

bool genInlinedAbsInt(CompilationUnit *cUnit, CallInfo* info)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  RegLocation rlSrc = info->args[0];
  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
  RegLocation rlDest = inlineTarget(cUnit, info);
  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, CallInfo* info)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = info->args[0];
  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
  RegLocation rlDest = inlineTargetWide(cUnit, info);
  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;
#elif defined(TARGET_X86)
  // Reuse source registers to avoid running out of temps
  RegLocation rlSrc = info->args[0];
  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
  RegLocation rlDest = inlineTargetWide(cUnit, info);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  opRegCopyWide(cUnit, rlResult.lowReg, rlResult.highReg, rlSrc.lowReg, rlSrc.highReg);
  oatFreeTemp(cUnit, rlSrc.lowReg);
  oatFreeTemp(cUnit, rlSrc.highReg);
  int signReg = oatAllocTemp(cUnit);
  // abs(x) = y<=x>>31, (x+y)^y.
  opRegRegImm(cUnit, kOpAsr, signReg, rlResult.highReg, 31);
  opRegReg(cUnit, kOpAdd, rlResult.lowReg, signReg);
  opRegReg(cUnit, kOpAdc, rlResult.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, CallInfo* info)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  RegLocation rlSrc = info->args[0];
  RegLocation rlDest = inlineTarget(cUnit, info);
  storeValue(cUnit, rlDest, rlSrc);
  return true;
#else
  return false;
#endif
}

bool genInlinedDoubleCvt(CompilationUnit *cUnit, CallInfo* info)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  RegLocation rlSrc = info->args[0];
  RegLocation rlDest = inlineTargetWide(cUnit, info);
  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, CallInfo* info,
                       bool zeroBased)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  oatClobberCalleeSave(cUnit);
  oatLockCallTemps(cUnit);  // Using fixed registers
  int regPtr = rARG0;
  int regChar = rARG1;
  int regStart = rARG2;

  RegLocation rlObj = info->args[0];
  RegLocation rlChar = info->args[1];
  RegLocation rlStart = info->args[2];
  loadValueDirectFixed(cUnit, rlObj, regPtr);
  loadValueDirectFixed(cUnit, rlChar, regChar);
  if (zeroBased) {
    loadConstant(cUnit, regStart, 0);
  } else {
    loadValueDirectFixed(cUnit, rlStart, regStart);
  }
#if !defined(TARGET_X86)
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pIndexOf));
#endif
  genNullCheck(cUnit, rlObj.sRegLow, regPtr, info->optFlags);
  LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
  oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
              (intptr_t)launchPad);
  opCmpImmBranch(cUnit, kCondGt, regChar, 0xFFFF, launchPad);
  // NOTE: not a safepoint
#if !defined(TARGET_X86)
  opReg(cUnit, kOpBlx, rTgt);
#else
  opThreadMem(cUnit, kOpBlx, ENTRYPOINT_OFFSET(pIndexOf));
#endif
  LIR* resumeTgt = newLIR0(cUnit, kPseudoTargetLabel);
  launchPad->operands[2] = (uintptr_t)resumeTgt;
  // Record that we've already inlined & null checked
  info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  RegLocation rlReturn = oatGetReturn(cUnit, false);
  RegLocation rlDest = inlineTarget(cUnit, info);
  storeValue(cUnit, rlDest, rlReturn);
  return true;
#else
  return false;
#endif
}

/* Fast string.compareTo(Ljava/lang/string;)I. */
bool genInlinedStringCompareTo(CompilationUnit* cUnit, CallInfo* info)
{
#if defined(TARGET_ARM) || defined(TARGET_X86)
  oatClobberCalleeSave(cUnit);
  oatLockCallTemps(cUnit);  // Using fixed registers
  int regThis = rARG0;
  int regCmp = rARG1;

  RegLocation rlThis = info->args[0];
  RegLocation rlCmp = info->args[1];
  loadValueDirectFixed(cUnit, rlThis, regThis);
  loadValueDirectFixed(cUnit, rlCmp, regCmp);
#if !defined(TARGET_X86)
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pStringCompareTo));
#endif
  genNullCheck(cUnit, rlThis.sRegLow, regThis, info->optFlags);
  //TUNING: check if rlCmp.sRegLow is already null checked
  LIR* launchPad = rawLIR(cUnit, 0, kPseudoIntrinsicRetry, (uintptr_t)info);
  oatInsertGrowableList(cUnit, &cUnit->intrinsicLaunchpads,
                        (intptr_t)launchPad);
  opCmpImmBranch(cUnit, kCondEq, regCmp, 0, launchPad);
  // NOTE: not a safepoint
#if !defined(TARGET_X86)
  opReg(cUnit, kOpBlx, rTgt);
#else
  opThreadMem(cUnit, kOpBlx, ENTRYPOINT_OFFSET(pStringCompareTo));
#endif
  launchPad->operands[2] = 0;  // No return possible
  // Record that we've already inlined & null checked
  info->optFlags |= (MIR_INLINED | MIR_IGNORE_NULL_CHECK);
  RegLocation rlReturn = oatGetReturn(cUnit, false);
  RegLocation rlDest = inlineTarget(cUnit, info);
  storeValue(cUnit, rlDest, rlReturn);
  return true;
#else
  return false;
#endif
}

bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) {
#if defined(TARGET_ARM)
  // Unused - RegLocation rlSrcUnsafe = info->args[0];
  RegLocation rlSrcObj= info->args[1];  // Object - known non-null
  RegLocation rlSrcOffset= info->args[2];  // long low
  rlSrcOffset.wide = 0;  // ignore high half in info->args[3]
  RegLocation rlSrcExpected= info->args[4];  // int or Object
  RegLocation rlSrcNewValue= info->args[5];  // int or Object
  RegLocation rlDest = inlineTarget(cUnit, info);  // boolean place for result


  // Release store semantics, get the barrier out of the way.
  oatGenMemBarrier(cUnit, kSY);

  RegLocation rlObject = loadValue(cUnit, rlSrcObj, kCoreReg);
  RegLocation rlNewValue = loadValue(cUnit, rlSrcNewValue, kCoreReg);

  if (need_write_barrier) {
    // Mark card for object assuming new value is stored.
    markGCCard(cUnit, rlNewValue.lowReg, rlObject.lowReg);
  }

  RegLocation rlOffset = loadValue(cUnit, rlSrcOffset, kCoreReg);

  int rPtr = oatAllocTemp(cUnit);
  opRegRegReg(cUnit, kOpAdd, rPtr, rlObject.lowReg, rlOffset.lowReg);

  // Free now unneeded rlObject and rlOffset to give more temps.
  oatClobberSReg(cUnit, rlObject.sRegLow);
  oatFreeTemp(cUnit, rlObject.lowReg);
  oatClobberSReg(cUnit, rlOffset.sRegLow);
  oatFreeTemp(cUnit, rlOffset.lowReg);

  int rOldValue = oatAllocTemp(cUnit);
  newLIR3(cUnit, kThumb2Ldrex, rOldValue, rPtr, 0);  // rOldValue := [rPtr]

  RegLocation rlExpected = loadValue(cUnit, rlSrcExpected, kCoreReg);

  // if (rOldValue == rExpected) {
  //   [rPtr] <- rNewValue && rResult := success ? 0 : 1
  //   rResult ^= 1
  // } else {
  //   rResult := 0
  // }
  opRegReg(cUnit, kOpCmp, rOldValue, rlExpected.lowReg);
  oatFreeTemp(cUnit, rOldValue);  // Now unneeded.
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
  opIT(cUnit, kArmCondEq, "TE");
  newLIR4(cUnit, kThumb2Strex, rlResult.lowReg, rlNewValue.lowReg, rPtr, 0);
  oatFreeTemp(cUnit, rPtr);  // Now unneeded.
  opRegImm(cUnit, kOpXor, rlResult.lowReg, 1);
  opRegReg(cUnit, kOpXor, rlResult.lowReg, rlResult.lowReg);

  storeValue(cUnit, rlDest, rlResult);

  return true;
#else
  return false;
#endif
}

bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
#if defined(TARGET_ARM)
  LIR *branch;
  RegLocation rlSrc = info->args[0];
  RegLocation rlDest = inlineTargetWide(cUnit, info);  // double place for result
  rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
  newLIR2(cUnit, kThumb2Vsqrtd, S2D(rlResult.lowReg, rlResult.highReg),
          S2D(rlSrc.lowReg, rlSrc.highReg));
  newLIR2(cUnit, kThumb2Vcmpd, S2D(rlResult.lowReg, rlResult.highReg),
          S2D(rlResult.lowReg, rlResult.highReg));
  newLIR0(cUnit, kThumb2Fmstat);
  branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq);
  oatClobberCalleeSave(cUnit);
  oatLockCallTemps(cUnit);  // Using fixed registers
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt));
  newLIR3(cUnit, kThumb2Fmrrd, r0, r1, S2D(rlSrc.lowReg, rlSrc.highReg));
  newLIR1(cUnit, kThumbBlxR, rTgt);
  newLIR3(cUnit, kThumb2Fmdrr, S2D(rlResult.lowReg, rlResult.highReg), r0, r1);
  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
  storeValueWide(cUnit, rlDest, rlResult);
  return true;
#else
  return false;
#endif
}

bool genIntrinsic(CompilationUnit* cUnit, CallInfo* info)
{
  if (info->optFlags & MIR_INLINED) {
    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(info->index, *cUnit->dex_file));
  if (tgtMethod.find(" java.lang") != std::string::npos) {
    if (tgtMethod == "long java.lang.Double.doubleToRawLongBits(double)") {
      return genInlinedDoubleCvt(cUnit, info);
    }
    if (tgtMethod == "double java.lang.Double.longBitsToDouble(long)") {
      return genInlinedDoubleCvt(cUnit, info);
    }
    if (tgtMethod == "int java.lang.Float.floatToRawIntBits(float)") {
      return genInlinedFloatCvt(cUnit, info);
    }
    if (tgtMethod == "float java.lang.Float.intBitsToFloat(int)") {
      return genInlinedFloatCvt(cUnit, info);
    }
    if (tgtMethod == "int java.lang.Math.abs(int)" ||
        tgtMethod == "int java.lang.StrictMath.abs(int)") {
      return genInlinedAbsInt(cUnit, info);
    }
    if (tgtMethod == "long java.lang.Math.abs(long)" ||
        tgtMethod == "long java.lang.StrictMath.abs(long)") {
      return genInlinedAbsLong(cUnit, info);
    }
    if (tgtMethod == "int java.lang.Math.max(int, int)" ||
        tgtMethod == "int java.lang.StrictMath.max(int, int)") {
      return genInlinedMinMaxInt(cUnit, info, false /* isMin */);
    }
    if (tgtMethod == "int java.lang.Math.min(int, int)" ||
        tgtMethod == "int java.lang.StrictMath.min(int, int)") {
      return genInlinedMinMaxInt(cUnit, info, true /* isMin */);
    }
    if (tgtMethod == "double java.lang.Math.sqrt(double)" ||
        tgtMethod == "double java.lang.StrictMath.sqrt(double)") {
      return genInlinedSqrt(cUnit, info);
    }
    if (tgtMethod == "char java.lang.String.charAt(int)") {
      return genInlinedCharAt(cUnit, info);
    }
    if (tgtMethod == "int java.lang.String.compareTo(java.lang.String)") {
      return genInlinedStringCompareTo(cUnit, info);
    }
    if (tgtMethod == "boolean java.lang.String.isEmpty()") {
      return genInlinedStringIsEmptyOrLength(cUnit, info, true /* isEmpty */);
    }
    if (tgtMethod == "int java.lang.String.indexOf(int, int)") {
      return genInlinedIndexOf(cUnit, info, false /* base 0 */);
    }
    if (tgtMethod == "int java.lang.String.indexOf(int)") {
      return genInlinedIndexOf(cUnit, info, true /* base 0 */);
    }
    if (tgtMethod == "int java.lang.String.length()") {
      return genInlinedStringIsEmptyOrLength(cUnit, info, false /* isEmpty */);
    }
  } else if (tgtMethod.find("boolean sun.misc.Unsafe.compareAndSwap") != std::string::npos) {
    if (tgtMethod == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
      return genInlinedCas32(cUnit, info, false);
    }
    if (tgtMethod == "boolean sun.misc.Unsafe.compareAndSwapObject(java.lang.Object, long, java.lang.Object, java.lang.Object)") {
      return genInlinedCas32(cUnit, info, true);
    }
  }
  return false;
}


}  // namespace art
