/*
 * 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*, InvokeInfo*, 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, InvokeInfo* 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,
        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, InvokeInfo* info,
                  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 = 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, Method::GetCodeOffset().Int32Value(),
                   rINVOKE_TGT);
      break;
#endif
    default:
      return -1;
  }
  return state + 1;
}

int nextInvokeInsnSP(CompilationUnit* cUnit, InvokeInfo* 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, InvokeInfo* 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, InvokeInfo* 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, InvokeInfo* 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, InvokeInfo* 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);
}

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

int nextInterfaceCallInsnWithAccessCheck(CompilationUnit* cUnit,
                                         InvokeInfo* 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, InvokeInfo* 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, InvokeInfo* 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, InvokeInfo* 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);
#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);
  } 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, InvokeInfo* info)
{
  RegLocation res;
  if (info->result.location == kLocInvalid) {
    res = oatGetReturn(cUnit, false);
  } else {
    res = info->result;
  }
  return res;
}

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

bool genInlinedCharAt(CompilationUnit* cUnit, InvokeInfo* info)
{
#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 = info->args[0];
  RegLocation rlIdx = info->args[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, info->optFlags);
  bool rangeCheck = (!(info->optFlags & 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, (uintptr_t)info);
    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, 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, InvokeInfo* info, bool isMin)
{
#if defined(TARGET_ARM)
  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);
  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, InvokeInfo* info,
                                     bool isEmpty)
{
#if defined(TARGET_ARM)
  // 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);
    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, InvokeInfo* info)
{
#if defined(TARGET_ARM)
  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, InvokeInfo* 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;
#else
  return false;
#endif
}

bool genInlinedFloatCvt(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
  RegLocation rlSrc = info->args[0];
  RegLocation rlDest = inlineTarget(cUnit, info);
  storeValue(cUnit, rlDest, rlSrc);
  return true;
#else
  return false;
#endif
}

bool genInlinedDoubleCvt(CompilationUnit *cUnit, InvokeInfo* info)
{
#if defined(TARGET_ARM)
  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, InvokeInfo* info,
                       bool zeroBased)
{
#if defined(TARGET_ARM)

  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);
  }
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pIndexOf));
  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);
  opReg(cUnit, kOpBlx, rTgt);
  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, InvokeInfo* info)
{
#if defined(TARGET_ARM)
  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);
  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pStringCompareTo));
  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);
  opReg(cUnit, kOpBlx, rTgt);
  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 genIntrinsic(CompilationUnit* cUnit, InvokeInfo* info)
{
  if ((info->optFlags & MIR_INLINED) || info->isRange ||
      (info->result.location == kLocInvalid))  {
    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->methodIdx, *cUnit->dex_file));
  if (tgtMethod.compare("char java.lang.String.charAt(int)") == 0) {
    return genInlinedCharAt(cUnit, info);
  }
  if (tgtMethod.compare("int java.lang.Math.min(int, int)") == 0) {
    return genInlinedMinMaxInt(cUnit, info, true /* isMin */);
  }
  if (tgtMethod.compare("int java.lang.Math.max(int, int)") == 0) {
    return genInlinedMinMaxInt(cUnit, info, false /* isMin */);
  }
  if (tgtMethod.compare("int java.lang.String.length()") == 0) {
    return genInlinedStringIsEmptyOrLength(cUnit, info, false /* isEmpty */);
  }
  if (tgtMethod.compare("boolean java.lang.String.isEmpty()") == 0) {
    return genInlinedStringIsEmptyOrLength(cUnit, info, true /* isEmpty */);
  }
  if (tgtMethod.compare("int java.lang.Math.abs(int)") == 0) {
    return genInlinedAbsInt(cUnit, info);
  }
  if (tgtMethod.compare("long java.lang.Math.abs(long)") == 0) {
    return genInlinedAbsLong(cUnit, info);
  }
  if (tgtMethod.compare("int java.lang.Float.floatToRawIntBits(float)") == 0) {
    return genInlinedFloatCvt(cUnit, info);
  }
  if (tgtMethod.compare("float java.lang.Float.intBitsToFloat(int)") == 0) {
    return genInlinedFloatCvt(cUnit, info);
  }
  if (tgtMethod.compare("long java.lang.Double.doubleToRawLongBits(double)") == 0) {
    return genInlinedDoubleCvt(cUnit, info);
  }
  if (tgtMethod.compare("double java.lang.Double.longBitsToDouble(long)") == 0) {
    return genInlinedDoubleCvt(cUnit, info);
  }
  if (tgtMethod.compare("int java.lang.String.indexOf(int, int)") == 0) {
    return genInlinedIndexOf(cUnit, info, false /* base 0 */);
  }
  if (tgtMethod.compare("int java.lang.String.indexOf(int)") == 0) {
    return genInlinedIndexOf(cUnit, info, true /* base 0 */);
  }
  if (tgtMethod.compare("int java.lang.String.compareTo(java.lang.String)") == 0) {
    return genInlinedStringCompareTo(cUnit, info);
  }
  return false;
}


}  // namespace art
