/*
 * 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,
        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, CallInfo* 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, 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);
}

/*
 * 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 unused3, InvokeType unused4)
{
  int trampoline = ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline);
  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);
#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, 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);
#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);
#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 genIntrinsic(CompilationUnit* cUnit, CallInfo* info)
{
  if ((info->optFlags & MIR_INLINED) || info->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(info->index, *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
