/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "codegen_arm.h"

#include <inttypes.h>

#include <string>
#include <sstream>

#include "backend_arm.h"
#include "base/logging.h"
#include "dex/mir_graph.h"
#include "dex/quick/mir_to_lir-inl.h"

namespace art {

#ifdef ARM_R4_SUSPEND_FLAG
static constexpr RegStorage core_regs_arr[] =
    {rs_r0, rs_r1, rs_r2, rs_r3, rs_rARM_SUSPEND, rs_r5, rs_r6, rs_r7, rs_r8, rs_rARM_SELF,
     rs_r10, rs_r11, rs_r12, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
#else
static constexpr RegStorage core_regs_arr[] =
    {rs_r0, rs_r1, rs_r2, rs_r3, rs_r4, rs_r5, rs_r6, rs_r7, rs_r8, rs_rARM_SELF,
     rs_r10, rs_r11, rs_r12, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
#endif
static constexpr RegStorage sp_regs_arr[] =
    {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10,
     rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15, rs_fr16, rs_fr17, rs_fr18, rs_fr19, rs_fr20,
     rs_fr21, rs_fr22, rs_fr23, rs_fr24, rs_fr25, rs_fr26, rs_fr27, rs_fr28, rs_fr29, rs_fr30,
     rs_fr31};
static constexpr RegStorage dp_regs_arr[] =
    {rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, rs_dr8, rs_dr9, rs_dr10,
     rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15};
#ifdef ARM_R4_SUSPEND_FLAG
static constexpr RegStorage reserved_regs_arr[] =
    {rs_rARM_SUSPEND, rs_rARM_SELF, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
static constexpr RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r12};
#else
static constexpr RegStorage reserved_regs_arr[] =
    {rs_rARM_SELF, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC};
static constexpr RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r4, rs_r12};
#endif
static constexpr RegStorage sp_temps_arr[] =
    {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10,
     rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15};
static constexpr RegStorage dp_temps_arr[] =
    {rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7};

static constexpr ArrayRef<const RegStorage> empty_pool;
static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr);
static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr);
static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr);
static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr);
static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr);
static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr);
static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr);

RegLocation ArmMir2Lir::LocCReturn() {
  return arm_loc_c_return;
}

RegLocation ArmMir2Lir::LocCReturnRef() {
  return arm_loc_c_return;
}

RegLocation ArmMir2Lir::LocCReturnWide() {
  return arm_loc_c_return_wide;
}

RegLocation ArmMir2Lir::LocCReturnFloat() {
  return arm_loc_c_return_float;
}

RegLocation ArmMir2Lir::LocCReturnDouble() {
  return arm_loc_c_return_double;
}

// Return a target-dependent special register.
RegStorage ArmMir2Lir::TargetReg(SpecialTargetRegister reg) {
  RegStorage res_reg;
  switch (reg) {
    case kSelf: res_reg = rs_rARM_SELF; break;
#ifdef ARM_R4_SUSPEND_FLAG
    case kSuspend: res_reg =  rs_rARM_SUSPEND; break;
#else
    case kSuspend: res_reg = RegStorage::InvalidReg(); break;
#endif
    case kLr: res_reg =  rs_rARM_LR; break;
    case kPc: res_reg =  rs_rARM_PC; break;
    case kSp: res_reg =  rs_rARM_SP; break;
    case kArg0: res_reg = rs_r0; break;
    case kArg1: res_reg = rs_r1; break;
    case kArg2: res_reg = rs_r2; break;
    case kArg3: res_reg = rs_r3; break;
    case kFArg0: res_reg = kArm32QuickCodeUseSoftFloat ? rs_r0 : rs_fr0; break;
    case kFArg1: res_reg = kArm32QuickCodeUseSoftFloat ? rs_r1 : rs_fr1; break;
    case kFArg2: res_reg = kArm32QuickCodeUseSoftFloat ? rs_r2 : rs_fr2; break;
    case kFArg3: res_reg = kArm32QuickCodeUseSoftFloat ? rs_r3 : rs_fr3; break;
    case kFArg4: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr4; break;
    case kFArg5: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr5; break;
    case kFArg6: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr6; break;
    case kFArg7: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr7; break;
    case kFArg8: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr8; break;
    case kFArg9: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr9; break;
    case kFArg10: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr10; break;
    case kFArg11: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr11; break;
    case kFArg12: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr12; break;
    case kFArg13: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr13; break;
    case kFArg14: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr14; break;
    case kFArg15: res_reg = kArm32QuickCodeUseSoftFloat ? RegStorage::InvalidReg() : rs_fr15; break;
    case kRet0: res_reg = rs_r0; break;
    case kRet1: res_reg = rs_r1; break;
    case kInvokeTgt: res_reg = rs_rARM_LR; break;
    case kHiddenArg: res_reg = rs_r12; break;
    case kHiddenFpArg: res_reg = RegStorage::InvalidReg(); break;
    case kCount: res_reg = RegStorage::InvalidReg(); break;
    default: res_reg = RegStorage::InvalidReg();
  }
  return res_reg;
}

/*
 * Decode the register id.
 */
ResourceMask ArmMir2Lir::GetRegMaskCommon(const RegStorage& reg) const {
  return GetRegMaskArm(reg);
}

constexpr ResourceMask ArmMir2Lir::GetRegMaskArm(RegStorage reg) {
  return reg.IsDouble()
      /* Each double register is equal to a pair of single-precision FP registers */
      ? ResourceMask::TwoBits(reg.GetRegNum() * 2 + kArmFPReg0)
      : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kArmFPReg0 : reg.GetRegNum());
}

constexpr ResourceMask ArmMir2Lir::EncodeArmRegList(int reg_list) {
  return ResourceMask::RawMask(static_cast<uint64_t >(reg_list), 0u);
}

constexpr ResourceMask ArmMir2Lir::EncodeArmRegFpcsList(int reg_list) {
  return ResourceMask::RawMask(static_cast<uint64_t >(reg_list) << kArmFPReg16, 0u);
}

ResourceMask ArmMir2Lir::GetPCUseDefEncoding() const {
  return ResourceMask::Bit(kArmRegPC);
}

// Thumb2 specific setup.  TODO: inline?:
void ArmMir2Lir::SetupTargetResourceMasks(LIR* lir, uint64_t flags,
                                          ResourceMask* use_mask, ResourceMask* def_mask) {
  DCHECK_EQ(cu_->instruction_set, kThumb2);
  DCHECK(!lir->flags.use_def_invalid);

  int opcode = lir->opcode;

  // These flags are somewhat uncommon - bypass if we can.
  if ((flags & (REG_DEF_SP | REG_USE_SP | REG_DEF_LIST0 | REG_DEF_LIST1 |
                REG_DEF_FPCS_LIST0 | REG_DEF_FPCS_LIST2 | REG_USE_PC | IS_IT | REG_USE_LIST0 |
                REG_USE_LIST1 | REG_USE_FPCS_LIST0 | REG_USE_FPCS_LIST2 | REG_DEF_LR)) != 0) {
    if (flags & REG_DEF_SP) {
      def_mask->SetBit(kArmRegSP);
    }

    if (flags & REG_USE_SP) {
      use_mask->SetBit(kArmRegSP);
    }

    if (flags & REG_DEF_LIST0) {
      def_mask->SetBits(EncodeArmRegList(lir->operands[0]));
    }

    if (flags & REG_DEF_LIST1) {
      def_mask->SetBits(EncodeArmRegList(lir->operands[1]));
    }

    if (flags & REG_DEF_FPCS_LIST0) {
      def_mask->SetBits(EncodeArmRegList(lir->operands[0]));
    }

    if (flags & REG_DEF_FPCS_LIST2) {
      for (int i = 0; i < lir->operands[2]; i++) {
        SetupRegMask(def_mask, lir->operands[1] + i);
      }
    }

    if (flags & REG_USE_PC) {
      use_mask->SetBit(kArmRegPC);
    }

    /* Conservatively treat the IT block */
    if (flags & IS_IT) {
      *def_mask = kEncodeAll;
    }

    if (flags & REG_USE_LIST0) {
      use_mask->SetBits(EncodeArmRegList(lir->operands[0]));
    }

    if (flags & REG_USE_LIST1) {
      use_mask->SetBits(EncodeArmRegList(lir->operands[1]));
    }

    if (flags & REG_USE_FPCS_LIST0) {
      use_mask->SetBits(EncodeArmRegList(lir->operands[0]));
    }

    if (flags & REG_USE_FPCS_LIST2) {
      for (int i = 0; i < lir->operands[2]; i++) {
        SetupRegMask(use_mask, lir->operands[1] + i);
      }
    }
    /* Fixup for kThumbPush/lr and kThumbPop/pc */
    if (opcode == kThumbPush || opcode == kThumbPop) {
      constexpr ResourceMask r8Mask = GetRegMaskArm(rs_r8);
      if ((opcode == kThumbPush) && (use_mask->Intersects(r8Mask))) {
        use_mask->ClearBits(r8Mask);
        use_mask->SetBit(kArmRegLR);
      } else if ((opcode == kThumbPop) && (def_mask->Intersects(r8Mask))) {
        def_mask->ClearBits(r8Mask);
        def_mask->SetBit(kArmRegPC);;
      }
    }
    if (flags & REG_DEF_LR) {
      def_mask->SetBit(kArmRegLR);
    }
  }
}

ArmConditionCode ArmMir2Lir::ArmConditionEncoding(ConditionCode ccode) {
  ArmConditionCode res;
  switch (ccode) {
    case kCondEq: res = kArmCondEq; break;
    case kCondNe: res = kArmCondNe; break;
    case kCondCs: res = kArmCondCs; break;
    case kCondCc: res = kArmCondCc; break;
    case kCondUlt: res = kArmCondCc; break;
    case kCondUge: res = kArmCondCs; break;
    case kCondMi: res = kArmCondMi; break;
    case kCondPl: res = kArmCondPl; break;
    case kCondVs: res = kArmCondVs; break;
    case kCondVc: res = kArmCondVc; break;
    case kCondHi: res = kArmCondHi; break;
    case kCondLs: res = kArmCondLs; break;
    case kCondGe: res = kArmCondGe; break;
    case kCondLt: res = kArmCondLt; break;
    case kCondGt: res = kArmCondGt; break;
    case kCondLe: res = kArmCondLe; break;
    case kCondAl: res = kArmCondAl; break;
    case kCondNv: res = kArmCondNv; break;
    default:
      LOG(FATAL) << "Bad condition code " << ccode;
      res = static_cast<ArmConditionCode>(0);  // Quiet gcc
  }
  return res;
}

static const char* core_reg_names[16] = {
  "r0",
  "r1",
  "r2",
  "r3",
  "r4",
  "r5",
  "r6",
  "r7",
  "r8",
  "rSELF",
  "r10",
  "r11",
  "r12",
  "sp",
  "lr",
  "pc",
};


static const char* shift_names[4] = {
  "lsl",
  "lsr",
  "asr",
  "ror"};

/* Decode and print a ARM register name */
static char* DecodeRegList(int opcode, int vector, char* buf, size_t buf_size) {
  int i;
  bool printed = false;
  buf[0] = 0;
  for (i = 0; i < 16; i++, vector >>= 1) {
    if (vector & 0x1) {
      int reg_id = i;
      if (opcode == kThumbPush && i == 8) {
        reg_id = rs_rARM_LR.GetRegNum();
      } else if (opcode == kThumbPop && i == 8) {
        reg_id = rs_rARM_PC.GetRegNum();
      }
      if (printed) {
        snprintf(buf + strlen(buf), buf_size - strlen(buf), ", r%d", reg_id);
      } else {
        printed = true;
        snprintf(buf, buf_size, "r%d", reg_id);
      }
    }
  }
  return buf;
}

static char*  DecodeFPCSRegList(int count, int base, char* buf, size_t buf_size) {
  snprintf(buf, buf_size, "s%d", base);
  for (int i = 1; i < count; i++) {
    snprintf(buf + strlen(buf), buf_size - strlen(buf), ", s%d", base + i);
  }
  return buf;
}

static int32_t ExpandImmediate(int value) {
  int32_t mode = (value & 0xf00) >> 8;
  uint32_t bits = value & 0xff;
  switch (mode) {
    case 0:
      return bits;
     case 1:
      return (bits << 16) | bits;
     case 2:
      return (bits << 24) | (bits << 8);
     case 3:
      return (bits << 24) | (bits << 16) | (bits << 8) | bits;
    default:
      break;
  }
  bits = (bits | 0x80) << 24;
  return bits >> (((value & 0xf80) >> 7) - 8);
}

const char* cc_names[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
                         "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"};
/*
 * Interpret a format string and build a string no longer than size
 * See format key in Assemble.c.
 */
std::string ArmMir2Lir::BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr) {
  std::string buf;
  int i;
  const char* fmt_end = &fmt[strlen(fmt)];
  char tbuf[256];
  const char* name;
  char nc;
  while (fmt < fmt_end) {
    int operand;
    if (*fmt == '!') {
      fmt++;
      DCHECK_LT(fmt, fmt_end);
      nc = *fmt++;
      if (nc == '!') {
        strcpy(tbuf, "!");
      } else {
         DCHECK_LT(fmt, fmt_end);
         DCHECK_LT(static_cast<unsigned>(nc-'0'), 4U);
         operand = lir->operands[nc-'0'];
         switch (*fmt++) {
           case 'H':
             if (operand != 0) {
               snprintf(tbuf, arraysize(tbuf), ", %s %d", shift_names[operand & 0x3], operand >> 2);
             } else {
               strcpy(tbuf, "");
             }
             break;
           case 'B':
             switch (operand) {
               case kSY:
                 name = "sy";
                 break;
               case kST:
                 name = "st";
                 break;
               case kISH:
                 name = "ish";
                 break;
               case kISHST:
                 name = "ishst";
                 break;
               case kNSH:
                 name = "nsh";
                 break;
               case kNSHST:
                 name = "shst";
                 break;
               default:
                 name = "DecodeError2";
                 break;
             }
             strcpy(tbuf, name);
             break;
           case 'b':
             strcpy(tbuf, "0000");
             for (i = 3; i >= 0; i--) {
               tbuf[i] += operand & 1;
               operand >>= 1;
             }
             break;
           case 'n':
             operand = ~ExpandImmediate(operand);
             snprintf(tbuf, arraysize(tbuf), "%d [%#x]", operand, operand);
             break;
           case 'm':
             operand = ExpandImmediate(operand);
             snprintf(tbuf, arraysize(tbuf), "%d [%#x]", operand, operand);
             break;
           case 's':
             snprintf(tbuf, arraysize(tbuf), "s%d", RegStorage::RegNum(operand));
             break;
           case 'S':
             snprintf(tbuf, arraysize(tbuf), "d%d", RegStorage::RegNum(operand));
             break;
           case 'h':
             snprintf(tbuf, arraysize(tbuf), "%04x", operand);
             break;
           case 'M':
           case 'd':
             snprintf(tbuf, arraysize(tbuf), "%d", operand);
             break;
           case 'C':
             operand = RegStorage::RegNum(operand);
             DCHECK_LT(operand, static_cast<int>(
                 sizeof(core_reg_names)/sizeof(core_reg_names[0])));
             snprintf(tbuf, arraysize(tbuf), "%s", core_reg_names[operand]);
             break;
           case 'E':
             snprintf(tbuf, arraysize(tbuf), "%d", operand*4);
             break;
           case 'F':
             snprintf(tbuf, arraysize(tbuf), "%d", operand*2);
             break;
           case 'c':
             strcpy(tbuf, cc_names[operand]);
             break;
           case 't':
             snprintf(tbuf, arraysize(tbuf), "0x%08" PRIxPTR " (L%p)",
                 reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4 + (operand << 1),
                 lir->target);
             break;
           case 'T':
             snprintf(tbuf, arraysize(tbuf), "%s", PrettyMethod(
                 static_cast<uint32_t>(lir->operands[1]),
                 *UnwrapPointer<DexFile>(lir->operands[2])).c_str());
             break;
           case 'u': {
             int offset_1 = lir->operands[0];
             int offset_2 = NEXT_LIR(lir)->operands[0];
             uintptr_t target =
                 (((reinterpret_cast<uintptr_t>(base_addr) + lir->offset + 4) &
                 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
                 0xfffffffc;
             snprintf(tbuf, arraysize(tbuf), "%p", reinterpret_cast<void *>(target));
             break;
          }

           /* Nothing to print for BLX_2 */
           case 'v':
             strcpy(tbuf, "see above");
             break;
           case 'R':
             DecodeRegList(lir->opcode, operand, tbuf, arraysize(tbuf));
             break;
           case 'P':
             DecodeFPCSRegList(operand, 16, tbuf, arraysize(tbuf));
             break;
           case 'Q':
             DecodeFPCSRegList(operand, 0, tbuf, arraysize(tbuf));
             break;
           default:
             strcpy(tbuf, "DecodeError1");
             break;
        }
        buf += tbuf;
      }
    } else {
       buf += *fmt++;
    }
  }
  // Dump thread offset.
  std::string fmt_str = GetTargetInstFmt(lir->opcode);
  if (std::string::npos != fmt_str.find(", [!1C, #!2") && rARM_SELF == lir->operands[1] &&
      std::string::npos != buf.find(", [")) {
    int offset = lir->operands[2];
    if (std::string::npos != fmt_str.find("#!2d")) {
    } else if (std::string::npos != fmt_str.find("#!2E")) {
      offset *= 4;
    } else if (std::string::npos != fmt_str.find("#!2F")) {
      offset *= 2;
    } else {
      LOG(FATAL) << "Should not reach here";
    }
    std::ostringstream tmp_stream;
    Thread::DumpThreadOffset<4>(tmp_stream, offset);
    buf += "  ; ";
    buf += tmp_stream.str();
  }
  return buf;
}

void ArmMir2Lir::DumpResourceMask(LIR* arm_lir, const ResourceMask& mask, const char* prefix) {
  char buf[256];
  buf[0] = 0;

  if (mask.Equals(kEncodeAll)) {
    strcpy(buf, "all");
  } else {
    char num[8];
    int i;

    for (i = 0; i < kArmRegEnd; i++) {
      if (mask.HasBit(i)) {
        snprintf(num, arraysize(num), "%d ", i);
        strcat(buf, num);
      }
    }

    if (mask.HasBit(ResourceMask::kCCode)) {
      strcat(buf, "cc ");
    }
    if (mask.HasBit(ResourceMask::kFPStatus)) {
      strcat(buf, "fpcc ");
    }

    /* Memory bits */
    if (arm_lir && (mask.HasBit(ResourceMask::kDalvikReg))) {
      snprintf(buf + strlen(buf), arraysize(buf) - strlen(buf), "dr%d%s",
               DECODE_ALIAS_INFO_REG(arm_lir->flags.alias_info),
               DECODE_ALIAS_INFO_WIDE(arm_lir->flags.alias_info) ? "(+1)" : "");
    }
    if (mask.HasBit(ResourceMask::kLiteral)) {
      strcat(buf, "lit ");
    }

    if (mask.HasBit(ResourceMask::kHeapRef)) {
      strcat(buf, "heap ");
    }
    if (mask.HasBit(ResourceMask::kMustNotAlias)) {
      strcat(buf, "noalias ");
    }
  }
  if (buf[0]) {
    LOG(INFO) << prefix << ": " << buf;
  }
}

bool ArmMir2Lir::IsUnconditionalBranch(LIR* lir) {
  return ((lir->opcode == kThumbBUncond) || (lir->opcode == kThumb2BUncond));
}

RegisterClass ArmMir2Lir::RegClassForFieldLoadStore(OpSize size, bool is_volatile) {
  if (UNLIKELY(is_volatile)) {
    // On arm, atomic 64-bit load/store requires a core register pair.
    // Smaller aligned load/store is atomic for both core and fp registers.
    if (size == k64 || size == kDouble) {
      return kCoreReg;
    }
  }
  return RegClassBySize(size);
}

ArmMir2Lir::ArmMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
    : Mir2Lir(cu, mir_graph, arena),
      call_method_insns_(arena->Adapter()),
      dex_cache_access_insns_(arena->Adapter()),
      dex_cache_arrays_base_reg_(RegStorage::InvalidReg()) {
  call_method_insns_.reserve(100);
  // Sanity check - make sure encoding map lines up.
  for (int i = 0; i < kArmLast; i++) {
    DCHECK_EQ(ArmMir2Lir::EncodingMap[i].opcode, i)
        << "Encoding order for " << ArmMir2Lir::EncodingMap[i].name
        << " is wrong: expecting " << i << ", seeing "
        << static_cast<int>(ArmMir2Lir::EncodingMap[i].opcode);
  }
}

Mir2Lir* ArmCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
                          ArenaAllocator* const arena) {
  return new ArmMir2Lir(cu, mir_graph, arena);
}

void ArmMir2Lir::CompilerInitializeRegAlloc() {
  reg_pool_.reset(new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */,
                                            sp_regs, dp_regs,
                                            reserved_regs, empty_pool /* reserved64 */,
                                            core_temps, empty_pool /* core64_temps */,
                                            sp_temps, dp_temps));

  // Target-specific adjustments.

  // Alias single precision floats to appropriate half of overlapping double.
  for (RegisterInfo* info : reg_pool_->sp_regs_) {
    int sp_reg_num = info->GetReg().GetRegNum();
    int dp_reg_num = sp_reg_num >> 1;
    RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num);
    RegisterInfo* dp_reg_info = GetRegInfo(dp_reg);
    // Double precision register's master storage should refer to itself.
    DCHECK_EQ(dp_reg_info, dp_reg_info->Master());
    // Redirect single precision's master storage to master.
    info->SetMaster(dp_reg_info);
    // Singles should show a single 32-bit mask bit, at first referring to the low half.
    DCHECK_EQ(info->StorageMask(), RegisterInfo::kLowSingleStorageMask);
    if (sp_reg_num & 1) {
      // For odd singles, change to use the high word of the backing double.
      info->SetStorageMask(RegisterInfo::kHighSingleStorageMask);
    }
  }

#ifdef ARM_R4_SUSPEND_FLAG
  // TODO: re-enable this when we can safely save r4 over the suspension code path.
  bool no_suspend = NO_SUSPEND;  // || !Runtime::Current()->ExplicitSuspendChecks();
  if (no_suspend) {
    GetRegInfo(rs_rARM_SUSPEND)->MarkFree();
  }
#endif

  // Don't start allocating temps at r0/s0/d0 or you may clobber return regs in early-exit methods.
  // TODO: adjust when we roll to hard float calling convention.
  reg_pool_->next_core_reg_ = 2;
  reg_pool_->next_sp_reg_ = 0;
  reg_pool_->next_dp_reg_ = 0;
}

/*
 * TUNING: is true leaf?  Can't just use METHOD_IS_LEAF to determine as some
 * instructions might call out to C/assembly helper functions.  Until
 * machinery is in place, always spill lr.
 */

void ArmMir2Lir::AdjustSpillMask() {
  core_spill_mask_ |= (1 << rs_rARM_LR.GetRegNum());
  num_core_spills_++;
}

/*
 * Mark a callee-save fp register as promoted.  Note that
 * vpush/vpop uses contiguous register lists so we must
 * include any holes in the mask.  Associate holes with
 * Dalvik register INVALID_VREG (0xFFFFU).
 */
void ArmMir2Lir::MarkPreservedSingle(int v_reg, RegStorage reg) {
  DCHECK_GE(reg.GetRegNum(), ARM_FP_CALLEE_SAVE_BASE);
  int adjusted_reg_num = reg.GetRegNum() - ARM_FP_CALLEE_SAVE_BASE;
  // Ensure fp_vmap_table is large enough
  int table_size = fp_vmap_table_.size();
  for (int i = table_size; i < (adjusted_reg_num + 1); i++) {
    fp_vmap_table_.push_back(INVALID_VREG);
  }
  // Add the current mapping
  fp_vmap_table_[adjusted_reg_num] = v_reg;
  // Size of fp_vmap_table is high-water mark, use to set mask
  num_fp_spills_ = fp_vmap_table_.size();
  fp_spill_mask_ = ((1 << num_fp_spills_) - 1) << ARM_FP_CALLEE_SAVE_BASE;
}

void ArmMir2Lir::MarkPreservedDouble(int v_reg, RegStorage reg) {
  // TEMP: perform as 2 singles.
  int reg_num = reg.GetRegNum() << 1;
  RegStorage lo = RegStorage::Solo32(RegStorage::kFloatingPoint | reg_num);
  RegStorage hi = RegStorage::Solo32(RegStorage::kFloatingPoint | reg_num | 1);
  MarkPreservedSingle(v_reg, lo);
  MarkPreservedSingle(v_reg + 1, hi);
}

/* Clobber all regs that might be used by an external C call */
void ArmMir2Lir::ClobberCallerSave() {
  // TODO: rework this - it's gotten even more ugly.
  Clobber(rs_r0);
  Clobber(rs_r1);
  Clobber(rs_r2);
  Clobber(rs_r3);
  Clobber(rs_r12);
  Clobber(rs_r14lr);
  Clobber(rs_fr0);
  Clobber(rs_fr1);
  Clobber(rs_fr2);
  Clobber(rs_fr3);
  Clobber(rs_fr4);
  Clobber(rs_fr5);
  Clobber(rs_fr6);
  Clobber(rs_fr7);
  Clobber(rs_fr8);
  Clobber(rs_fr9);
  Clobber(rs_fr10);
  Clobber(rs_fr11);
  Clobber(rs_fr12);
  Clobber(rs_fr13);
  Clobber(rs_fr14);
  Clobber(rs_fr15);
  Clobber(rs_dr0);
  Clobber(rs_dr1);
  Clobber(rs_dr2);
  Clobber(rs_dr3);
  Clobber(rs_dr4);
  Clobber(rs_dr5);
  Clobber(rs_dr6);
  Clobber(rs_dr7);
}

RegLocation ArmMir2Lir::GetReturnWideAlt() {
  RegLocation res = LocCReturnWide();
  res.reg.SetLowReg(rs_r2.GetReg());
  res.reg.SetHighReg(rs_r3.GetReg());
  Clobber(rs_r2);
  Clobber(rs_r3);
  MarkInUse(rs_r2);
  MarkInUse(rs_r3);
  MarkWide(res.reg);
  return res;
}

RegLocation ArmMir2Lir::GetReturnAlt() {
  RegLocation res = LocCReturn();
  res.reg.SetReg(rs_r1.GetReg());
  Clobber(rs_r1);
  MarkInUse(rs_r1);
  return res;
}

/* To be used when explicitly managing register use */
void ArmMir2Lir::LockCallTemps() {
  LockTemp(rs_r0);
  LockTemp(rs_r1);
  LockTemp(rs_r2);
  LockTemp(rs_r3);
  if (!kArm32QuickCodeUseSoftFloat) {
    LockTemp(rs_fr0);
    LockTemp(rs_fr1);
    LockTemp(rs_fr2);
    LockTemp(rs_fr3);
    LockTemp(rs_fr4);
    LockTemp(rs_fr5);
    LockTemp(rs_fr6);
    LockTemp(rs_fr7);
    LockTemp(rs_fr8);
    LockTemp(rs_fr9);
    LockTemp(rs_fr10);
    LockTemp(rs_fr11);
    LockTemp(rs_fr12);
    LockTemp(rs_fr13);
    LockTemp(rs_fr14);
    LockTemp(rs_fr15);
    LockTemp(rs_dr0);
    LockTemp(rs_dr1);
    LockTemp(rs_dr2);
    LockTemp(rs_dr3);
    LockTemp(rs_dr4);
    LockTemp(rs_dr5);
    LockTemp(rs_dr6);
    LockTemp(rs_dr7);
  }
}

/* To be used when explicitly managing register use */
void ArmMir2Lir::FreeCallTemps() {
  FreeTemp(rs_r0);
  FreeTemp(rs_r1);
  FreeTemp(rs_r2);
  FreeTemp(rs_r3);
  FreeTemp(TargetReg(kHiddenArg));
  if (!kArm32QuickCodeUseSoftFloat) {
    FreeTemp(rs_fr0);
    FreeTemp(rs_fr1);
    FreeTemp(rs_fr2);
    FreeTemp(rs_fr3);
    FreeTemp(rs_fr4);
    FreeTemp(rs_fr5);
    FreeTemp(rs_fr6);
    FreeTemp(rs_fr7);
    FreeTemp(rs_fr8);
    FreeTemp(rs_fr9);
    FreeTemp(rs_fr10);
    FreeTemp(rs_fr11);
    FreeTemp(rs_fr12);
    FreeTemp(rs_fr13);
    FreeTemp(rs_fr14);
    FreeTemp(rs_fr15);
    FreeTemp(rs_dr0);
    FreeTemp(rs_dr1);
    FreeTemp(rs_dr2);
    FreeTemp(rs_dr3);
    FreeTemp(rs_dr4);
    FreeTemp(rs_dr5);
    FreeTemp(rs_dr6);
    FreeTemp(rs_dr7);
  }
}

RegStorage ArmMir2Lir::LoadHelper(QuickEntrypointEnum trampoline) {
  LoadWordDisp(rs_rARM_SELF, GetThreadOffset<4>(trampoline).Int32Value(), rs_rARM_LR);
  return rs_rARM_LR;
}

LIR* ArmMir2Lir::CheckSuspendUsingLoad() {
  RegStorage tmp = rs_r0;
  Load32Disp(rs_rARM_SELF, Thread::ThreadSuspendTriggerOffset<4>().Int32Value(), tmp);
  LIR* load2 = Load32Disp(tmp, 0, tmp);
  return load2;
}

uint64_t ArmMir2Lir::GetTargetInstFlags(int opcode) {
  DCHECK(!IsPseudoLirOp(opcode));
  return ArmMir2Lir::EncodingMap[opcode].flags;
}

const char* ArmMir2Lir::GetTargetInstName(int opcode) {
  DCHECK(!IsPseudoLirOp(opcode));
  return ArmMir2Lir::EncodingMap[opcode].name;
}

const char* ArmMir2Lir::GetTargetInstFmt(int opcode) {
  DCHECK(!IsPseudoLirOp(opcode));
  return ArmMir2Lir::EncodingMap[opcode].fmt;
}

/*
 * Somewhat messy code here.  We want to allocate a pair of contiguous
 * physical single-precision floating point registers starting with
 * an even numbered reg.  It is possible that the paired s_reg (s_reg+1)
 * has already been allocated - try to fit if possible.  Fail to
 * allocate if we can't meet the requirements for the pair of
 * s_reg<=sX[even] & (s_reg+1)<= sX+1.
 */
// TODO: needs rewrite to support non-backed 64-bit float regs.
RegStorage ArmMir2Lir::AllocPreservedDouble(int s_reg) {
  RegStorage res;
  int v_reg = mir_graph_->SRegToVReg(s_reg);
  int p_map_idx = SRegToPMap(s_reg);
  if (promotion_map_[p_map_idx+1].fp_location == kLocPhysReg) {
    // Upper reg is already allocated.  Can we fit?
    int high_reg = promotion_map_[p_map_idx+1].fp_reg;
    if ((high_reg & 1) == 0) {
      // High reg is even - fail.
      return res;  // Invalid.
    }
    // Is the low reg of the pair free?
    // FIXME: rework.
    RegisterInfo* p = GetRegInfo(RegStorage::FloatSolo32(high_reg - 1));
    if (p->InUse() || p->IsTemp()) {
      // Already allocated or not preserved - fail.
      return res;  // Invalid.
    }
    // OK - good to go.
    res = RegStorage::FloatSolo64(p->GetReg().GetRegNum() >> 1);
    p->MarkInUse();
    MarkPreservedSingle(v_reg, p->GetReg());
  } else {
    /*
     * TODO: until runtime support is in, make sure we avoid promoting the same vreg to
     * different underlying physical registers.
     */
    for (RegisterInfo* info : reg_pool_->dp_regs_) {
      if (!info->IsTemp() && !info->InUse()) {
        res = info->GetReg();
        info->MarkInUse();
        MarkPreservedDouble(v_reg, info->GetReg());
        break;
      }
    }
  }
  if (res.Valid()) {
    RegisterInfo* info = GetRegInfo(res);
    promotion_map_[p_map_idx].fp_location = kLocPhysReg;
    promotion_map_[p_map_idx].fp_reg =
        info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg().GetReg();
    promotion_map_[p_map_idx+1].fp_location = kLocPhysReg;
    promotion_map_[p_map_idx+1].fp_reg =
        info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg().GetReg();
  }
  return res;
}

// Reserve a callee-save sp single register.
RegStorage ArmMir2Lir::AllocPreservedSingle(int s_reg) {
  RegStorage res;
  for (RegisterInfo* info : reg_pool_->sp_regs_) {
    if (!info->IsTemp() && !info->InUse()) {
      res = info->GetReg();
      int p_map_idx = SRegToPMap(s_reg);
      int v_reg = mir_graph_->SRegToVReg(s_reg);
      GetRegInfo(res)->MarkInUse();
      MarkPreservedSingle(v_reg, res);
      promotion_map_[p_map_idx].fp_location = kLocPhysReg;
      promotion_map_[p_map_idx].fp_reg = res.GetReg();
      break;
    }
  }
  return res;
}

void ArmMir2Lir::InstallLiteralPools() {
  patches_.reserve(call_method_insns_.size() + dex_cache_access_insns_.size());

  // PC-relative calls to methods.
  for (LIR* p : call_method_insns_) {
    DCHECK_EQ(p->opcode, kThumb2Bl);
    uint32_t target_method_idx = p->operands[1];
    const DexFile* target_dex_file = UnwrapPointer<DexFile>(p->operands[2]);
    patches_.push_back(LinkerPatch::RelativeCodePatch(p->offset,
                                                      target_dex_file, target_method_idx));
  }

  // PC-relative dex cache array accesses.
  for (LIR* p : dex_cache_access_insns_) {
    DCHECK(p->opcode = kThumb2MovImm16 || p->opcode == kThumb2MovImm16H);
    const LIR* add_pc = UnwrapPointer<LIR>(p->operands[4]);
    DCHECK(add_pc->opcode == kThumbAddRRLH || add_pc->opcode == kThumbAddRRHH);
    const DexFile* dex_file = UnwrapPointer<DexFile>(p->operands[2]);
    uint32_t offset = p->operands[3];
    DCHECK(!p->flags.is_nop);
    DCHECK(!add_pc->flags.is_nop);
    patches_.push_back(LinkerPatch::DexCacheArrayPatch(p->offset,
                                                       dex_file, add_pc->offset, offset));
  }

  // And do the normal processing.
  Mir2Lir::InstallLiteralPools();
}

RegStorage ArmMir2Lir::InToRegStorageArmMapper::GetNextReg(ShortyArg arg) {
  const RegStorage coreArgMappingToPhysicalReg[] =
      {rs_r1, rs_r2, rs_r3};
  const int coreArgMappingToPhysicalRegSize = arraysize(coreArgMappingToPhysicalReg);
  const RegStorage fpArgMappingToPhysicalReg[] =
      {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7,
       rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15};
  constexpr uint32_t fpArgMappingToPhysicalRegSize = arraysize(fpArgMappingToPhysicalReg);
  static_assert(fpArgMappingToPhysicalRegSize % 2 == 0, "Number of FP Arg regs is not even");

  RegStorage result = RegStorage::InvalidReg();
  // Regard double as long, float as int for kArm32QuickCodeUseSoftFloat.
  if (arg.IsFP() && !kArm32QuickCodeUseSoftFloat) {
    if (arg.IsWide()) {
      cur_fp_double_reg_ = std::max(cur_fp_double_reg_, RoundUp(cur_fp_reg_, 2));
      if (cur_fp_double_reg_ < fpArgMappingToPhysicalRegSize) {
        result = RegStorage::MakeRegPair(fpArgMappingToPhysicalReg[cur_fp_double_reg_],
                                         fpArgMappingToPhysicalReg[cur_fp_double_reg_ + 1]);
        result = As64BitFloatReg(result);
        cur_fp_double_reg_ += 2;
      }
    } else {
      if (cur_fp_reg_ % 2 == 0) {
        cur_fp_reg_ = std::max(cur_fp_double_reg_, cur_fp_reg_);
      }
      if (cur_fp_reg_ < fpArgMappingToPhysicalRegSize) {
        result = fpArgMappingToPhysicalReg[cur_fp_reg_];
        cur_fp_reg_++;
      }
    }
  } else {
    if (cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
      if (!kArm32QuickCodeUseSoftFloat && arg.IsWide() && cur_core_reg_ == 0) {
        // Skip r1, and use r2-r3 for the register pair.
        cur_core_reg_++;
      }
      result = coreArgMappingToPhysicalReg[cur_core_reg_++];
      if (arg.IsWide() && cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
        result = RegStorage::MakeRegPair(result, coreArgMappingToPhysicalReg[cur_core_reg_++]);
      }
    }
  }
  return result;
}

int ArmMir2Lir::GenDalvikArgsBulkCopy(CallInfo* info, int first, int count) {
  if (kArm32QuickCodeUseSoftFloat) {
    return Mir2Lir::GenDalvikArgsBulkCopy(info, first, count);
  }
  /*
   * TODO: Improve by adding block copy for large number of arguments.  For now, just
   * copy a Dalvik vreg at a time.
   */
  return count;
}

void ArmMir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) {
  UNUSED(bb);
  DCHECK(MIR::DecodedInstruction::IsPseudoMirOp(mir->dalvikInsn.opcode));
  RegLocation rl_src[3];
  RegLocation rl_dest = mir_graph_->GetBadLoc();
  rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc();
  switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
    case kMirOpMaddInt:
      rl_dest = mir_graph_->GetDest(mir);
      rl_src[0] = mir_graph_->GetSrc(mir, 0);
      rl_src[1] = mir_graph_->GetSrc(mir, 1);
      rl_src[2]= mir_graph_->GetSrc(mir, 2);
      GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], false);
      break;
    case kMirOpMsubInt:
      rl_dest = mir_graph_->GetDest(mir);
      rl_src[0] = mir_graph_->GetSrc(mir, 0);
      rl_src[1] = mir_graph_->GetSrc(mir, 1);
      rl_src[2]= mir_graph_->GetSrc(mir, 2);
      GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], true);
      break;
    default:
      LOG(FATAL) << "Unexpected opcode: " << mir->dalvikInsn.opcode;
  }
}

}  // namespace art
