/*
 * Copyright (C) 2014 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 "assembler_arm32.h"

#include <functional>
#include <type_traits>

#include "base/macros.h"
#include "base/stl_util.h"
#include "utils/arm/assembler_arm_test.h"

namespace art {

using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;
using std::placeholders::_5;

// To speed up tests, don't use all register combinations.
static constexpr bool kUseSparseRegisterList = true;

// To speed up tests, don't use all condition codes.
static constexpr bool kUseSparseConditionList = true;

// To speed up tests, don't use all shift immediates.
static constexpr bool kUseSparseShiftImmediates = true;

class AssemblerArm32Test : public AssemblerArmTest<arm::Arm32Assembler,
                                                   arm::Register, arm::SRegister,
                                                   uint32_t, arm::ShifterOperand, arm::Condition,
                                                   arm::SetCc> {
 protected:
  std::string GetArchitectureString() OVERRIDE {
    return "arm";
  }

  std::string GetAssemblerParameters() OVERRIDE {
    // Arm-v7a, cortex-a15 (means we have sdiv).
    return " -march=armv7-a -mcpu=cortex-a15 -mfpu=neon";
  }

  const char* GetAssemblyHeader() OVERRIDE {
    return kArm32AssemblyHeader;
  }

  std::string GetDisassembleParameters() OVERRIDE {
    return " -D -bbinary -marm --no-show-raw-insn";
  }

  void SetUpHelpers() OVERRIDE {
    if (registers_.size() == 0) {
      if (kUseSparseRegisterList) {
        registers_.insert(end(registers_),
                          {  // NOLINT(whitespace/braces)
                              new arm::Register(arm::R0),
                              new arm::Register(arm::R1),
                              new arm::Register(arm::R4),
                              new arm::Register(arm::R8),
                              new arm::Register(arm::R11),
                              new arm::Register(arm::R12),
                              new arm::Register(arm::R13),
                              new arm::Register(arm::R14),
                              new arm::Register(arm::R15)
                          });
      } else {
        registers_.insert(end(registers_),
                          {  // NOLINT(whitespace/braces)
                              new arm::Register(arm::R0),
                              new arm::Register(arm::R1),
                              new arm::Register(arm::R2),
                              new arm::Register(arm::R3),
                              new arm::Register(arm::R4),
                              new arm::Register(arm::R5),
                              new arm::Register(arm::R6),
                              new arm::Register(arm::R7),
                              new arm::Register(arm::R8),
                              new arm::Register(arm::R9),
                              new arm::Register(arm::R10),
                              new arm::Register(arm::R11),
                              new arm::Register(arm::R12),
                              new arm::Register(arm::R13),
                              new arm::Register(arm::R14),
                              new arm::Register(arm::R15)
                          });
      }
    }

    if (!kUseSparseConditionList) {
      conditions_.push_back(arm::Condition::EQ);
      conditions_.push_back(arm::Condition::NE);
      conditions_.push_back(arm::Condition::CS);
      conditions_.push_back(arm::Condition::CC);
      conditions_.push_back(arm::Condition::MI);
      conditions_.push_back(arm::Condition::PL);
      conditions_.push_back(arm::Condition::VS);
      conditions_.push_back(arm::Condition::VC);
      conditions_.push_back(arm::Condition::HI);
      conditions_.push_back(arm::Condition::LS);
      conditions_.push_back(arm::Condition::GE);
      conditions_.push_back(arm::Condition::LT);
      conditions_.push_back(arm::Condition::GT);
      conditions_.push_back(arm::Condition::LE);
      conditions_.push_back(arm::Condition::AL);
    } else {
      conditions_.push_back(arm::Condition::EQ);
      conditions_.push_back(arm::Condition::NE);
      conditions_.push_back(arm::Condition::CC);
      conditions_.push_back(arm::Condition::VC);
      conditions_.push_back(arm::Condition::HI);
      conditions_.push_back(arm::Condition::LT);
      conditions_.push_back(arm::Condition::AL);
    }

    set_ccs_.push_back(arm::kCcDontCare);
    set_ccs_.push_back(arm::kCcSet);
    set_ccs_.push_back(arm::kCcKeep);

    shifter_operands_.push_back(arm::ShifterOperand(0));
    shifter_operands_.push_back(arm::ShifterOperand(1));
    shifter_operands_.push_back(arm::ShifterOperand(2));
    shifter_operands_.push_back(arm::ShifterOperand(3));
    shifter_operands_.push_back(arm::ShifterOperand(4));
    shifter_operands_.push_back(arm::ShifterOperand(5));
    shifter_operands_.push_back(arm::ShifterOperand(127));
    shifter_operands_.push_back(arm::ShifterOperand(128));
    shifter_operands_.push_back(arm::ShifterOperand(254));
    shifter_operands_.push_back(arm::ShifterOperand(255));

    if (!kUseSparseRegisterList) {
      shifter_operands_.push_back(arm::ShifterOperand(arm::R0));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R1));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R2));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R3));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R4));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R5));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R6));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R7));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R8));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R9));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R10));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R11));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R12));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R13));
    } else {
      shifter_operands_.push_back(arm::ShifterOperand(arm::R0));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R1));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R4));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R8));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R11));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R12));
      shifter_operands_.push_back(arm::ShifterOperand(arm::R13));
    }

    std::vector<arm::Shift> shifts {
      arm::Shift::LSL, arm::Shift::LSR, arm::Shift::ASR, arm::Shift::ROR, arm::Shift::RRX
    };

    // ShifterOperands of form "reg shift-type imm."
    for (arm::Shift shift : shifts) {
      for (arm::Register* reg : registers_) {  // Note: this will pick up the sparse set.
        if (*reg == arm::R15) {  // Skip PC.
          continue;
        }
        if (shift != arm::Shift::RRX) {
          if (!kUseSparseShiftImmediates) {
            for (uint32_t imm = 1; imm < 32; ++imm) {
              shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, imm));
            }
          } else {
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 1));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 2));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 3));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 7));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 15));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 16));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 30));
            shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 31));
          }
        } else {
          // RRX doesn't have an immediate.
          shifter_operands_.push_back(arm::ShifterOperand(*reg, shift, 0));
        }
      }
    }
  }

  std::vector<arm::ShifterOperand> CreateRegisterShifts(std::vector<arm::Register*>& base_regs,
                                                        int32_t shift_min, int32_t shift_max) {
    std::vector<arm::ShifterOperand> res;
    static constexpr arm::Shift kShifts[] = { arm::Shift::LSL, arm::Shift::LSR, arm::Shift::ASR,
                                              arm::Shift::ROR };

    for (arm::Shift shift : kShifts) {
      for (arm::Register* reg : base_regs) {
        // Take the min, the max, and three values in between.
        res.push_back(arm::ShifterOperand(*reg, shift, shift_min));
        if (shift_min != shift_max) {
          res.push_back(arm::ShifterOperand(*reg, shift, shift_max));
          int32_t middle = (shift_min + shift_max) / 2;
          res.push_back(arm::ShifterOperand(*reg, shift, middle));
          res.push_back(arm::ShifterOperand(*reg, shift, middle - 1));
          res.push_back(arm::ShifterOperand(*reg, shift, middle + 1));
        }
      }
    }

    return res;
  }

  void TearDown() OVERRIDE {
    AssemblerArmTest::TearDown();
    STLDeleteElements(&registers_);
  }

  std::vector<arm::Register*> GetRegisters() OVERRIDE {
    return registers_;
  }

  uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
    return imm_value;
  }

  std::vector<arm::Condition>& GetConditions() OVERRIDE {
    return conditions_;
  }

  std::string GetConditionString(arm::Condition c) OVERRIDE {
    std::ostringstream oss;
    oss << c;
    return oss.str();
  }

  std::vector<arm::SetCc>& GetSetCcs() OVERRIDE {
    return set_ccs_;
  }

  std::string GetSetCcString(arm::SetCc s) OVERRIDE {
    // For arm32, kCcDontCare defaults to not setting condition codes.
    return s == arm::kCcSet ? "s" : "";
  }

  arm::Register GetPCRegister() OVERRIDE {
    return arm::R15;
  }

  std::vector<arm::ShifterOperand>& GetShiftOperands() OVERRIDE {
    return shifter_operands_;
  }

  std::string GetShiftString(arm::ShifterOperand sop) OVERRIDE {
    std::ostringstream oss;
    if (sop.IsShift()) {
      // Not a rotate...
      if (sop.GetShift() == arm::Shift::RRX) {
        oss << sop.GetRegister() << ", " << sop.GetShift();
      } else {
        oss << sop.GetRegister() << ", " << sop.GetShift() << " #" << sop.GetImmediate();
      }
    } else if (sop.IsRegister()) {
      oss << sop.GetRegister();
    } else {
      CHECK(sop.IsImmediate());
      oss << "#" << sop.GetImmediate();
    }
    return oss.str();
  }

  static const char* GetRegTokenFromDepth(int depth) {
    switch (depth) {
      case 0:
        return Base::REG1_TOKEN;
      case 1:
        return Base::REG2_TOKEN;
      case 2:
        return Base::REG3_TOKEN;
      case 3:
        return REG4_TOKEN;
      default:
        LOG(FATAL) << "Depth problem.";
        UNREACHABLE();
    }
  }

  void ExecuteAndPrint(std::function<void()> f, std::string fmt, std::ostringstream& oss) {
    if (first_) {
      first_ = false;
    } else {
      oss << "\n";
    }
    oss << fmt;

    f();
  }

  // NOTE: Only support simple test like "aaa=bbb"
  bool EvalFilterString(std::string filter) {
    if (filter.compare("") == 0) {
      return false;
    }

    size_t equal_sign_index = filter.find('=');
    if (equal_sign_index == std::string::npos) {
      EXPECT_TRUE(false) << "Unsupported filter string.";
    }

    std::string lhs = filter.substr(0, equal_sign_index);
    std::string rhs = filter.substr(equal_sign_index + 1, std::string::npos);
    return lhs.compare(rhs) == 0;
  }

  void TemplateHelper(std::function<void(arm::Register)> f, int depth ATTRIBUTE_UNUSED,
                      bool without_pc, std::string fmt, std::string filter,
                      std::ostringstream& oss) {
    std::vector<arm::Register*> registers = without_pc ? GetRegistersWithoutPC() : GetRegisters();
    for (auto reg : registers) {
      std::string after_reg = fmt;
      std::string after_reg_filter = filter;

      std::string reg_string = GetRegName<RegisterView::kUsePrimaryName>(*reg);
      size_t reg_index;
      const char* reg_token = GetRegTokenFromDepth(depth);

      while ((reg_index = after_reg.find(reg_token)) != std::string::npos) {
        after_reg.replace(reg_index, strlen(reg_token), reg_string);
      }

      while ((reg_index = after_reg_filter.find(reg_token)) != std::string::npos) {
        after_reg_filter.replace(reg_index, strlen(reg_token), reg_string);
      }
      if (EvalFilterString(after_reg_filter)) {
        continue;
      }

      ExecuteAndPrint([&] () { f(*reg); }, after_reg, oss);
    }
  }

  void TemplateHelper(std::function<void(const arm::ShifterOperand&)> f, int depth ATTRIBUTE_UNUSED,
                      bool without_pc ATTRIBUTE_UNUSED, std::string fmt, std::string filter,
                      std::ostringstream& oss) {
    for (const arm::ShifterOperand& shift : GetShiftOperands()) {
      std::string after_shift = fmt;
      std::string after_shift_filter = filter;

      std::string shift_string = GetShiftString(shift);
      size_t shift_index;
      while ((shift_index = after_shift.find(SHIFT_TOKEN)) != std::string::npos) {
        after_shift.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string);
      }

      while ((shift_index = after_shift_filter.find(SHIFT_TOKEN)) != std::string::npos) {
        after_shift_filter.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string);
      }
      if (EvalFilterString(after_shift_filter)) {
        continue;
      }

      ExecuteAndPrint([&] () { f(shift); }, after_shift, oss);
    }
  }

  void TemplateHelper(std::function<void(arm::Condition)> f, int depth ATTRIBUTE_UNUSED,
                      bool without_pc ATTRIBUTE_UNUSED, std::string fmt, std::string filter,
                      std::ostringstream& oss) {
    for (arm::Condition c : GetConditions()) {
      std::string after_cond = fmt;
      std::string after_cond_filter = filter;

      size_t cond_index = after_cond.find(COND_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c));
      }

      cond_index = after_cond_filter.find(COND_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond_filter.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c));
      }
      if (EvalFilterString(after_cond_filter)) {
        continue;
      }

      ExecuteAndPrint([&] () { f(c); }, after_cond, oss);
    }
  }

  void TemplateHelper(std::function<void(arm::SetCc)> f, int depth ATTRIBUTE_UNUSED,
                      bool without_pc ATTRIBUTE_UNUSED, std::string fmt, std::string filter,
                      std::ostringstream& oss) {
    for (arm::SetCc s : GetSetCcs()) {
      std::string after_cond = fmt;
      std::string after_cond_filter = filter;

      size_t cond_index = after_cond.find(SET_CC_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond.replace(cond_index, ConstexprStrLen(SET_CC_TOKEN), GetSetCcString(s));
      }

      cond_index = after_cond_filter.find(SET_CC_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond_filter.replace(cond_index, ConstexprStrLen(SET_CC_TOKEN), GetSetCcString(s));
      }
      if (EvalFilterString(after_cond_filter)) {
        continue;
      }

      ExecuteAndPrint([&] () { f(s); }, after_cond, oss);
    }
  }

  template <typename... Args>
  void TemplateHelper(std::function<void(arm::Register, Args...)> f, int depth, bool without_pc,
                      std::string fmt, std::string filter, std::ostringstream& oss) {
    std::vector<arm::Register*> registers = without_pc ? GetRegistersWithoutPC() : GetRegisters();
    for (auto reg : registers) {
      std::string after_reg = fmt;
      std::string after_reg_filter = filter;

      std::string reg_string = GetRegName<RegisterView::kUsePrimaryName>(*reg);
      size_t reg_index;
      const char* reg_token = GetRegTokenFromDepth(depth);

      while ((reg_index = after_reg.find(reg_token)) != std::string::npos) {
        after_reg.replace(reg_index, strlen(reg_token), reg_string);
      }

      while ((reg_index = after_reg_filter.find(reg_token)) != std::string::npos) {
        after_reg_filter.replace(reg_index, strlen(reg_token), reg_string);
      }
      if (EvalFilterString(after_reg_filter)) {
        continue;
      }

      auto lambda = [&] (Args... args) { f(*reg, args...); };  // NOLINT [readability/braces] [4]
      TemplateHelper(std::function<void(Args...)>(lambda), depth + 1, without_pc,
          after_reg, after_reg_filter, oss);
    }
  }

  template <typename... Args>
  void TemplateHelper(std::function<void(const arm::ShifterOperand&, Args...)> f, int depth,
                      bool without_pc, std::string fmt, std::string filter,
                      std::ostringstream& oss) {
    for (const arm::ShifterOperand& shift : GetShiftOperands()) {
      std::string after_shift = fmt;
      std::string after_shift_filter = filter;

      std::string shift_string = GetShiftString(shift);
      size_t shift_index;
      while ((shift_index = after_shift.find(SHIFT_TOKEN)) != std::string::npos) {
        after_shift.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string);
      }

      while ((shift_index = after_shift_filter.find(SHIFT_TOKEN)) != std::string::npos) {
        after_shift_filter.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string);
      }
      if (EvalFilterString(after_shift_filter)) {
        continue;
      }

      auto lambda = [&] (Args... args) { f(shift, args...); };  // NOLINT [readability/braces] [4]
      TemplateHelper(std::function<void(Args...)>(lambda), depth, without_pc,
          after_shift, after_shift_filter, oss);
    }
  }

  template <typename... Args>
  void TemplateHelper(std::function<void(arm::Condition, Args...)> f, int depth, bool without_pc,
                      std::string fmt, std::string filter, std::ostringstream& oss) {
    for (arm::Condition c : GetConditions()) {
      std::string after_cond = fmt;
      std::string after_cond_filter = filter;

      size_t cond_index = after_cond.find(COND_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c));
      }

      cond_index = after_cond_filter.find(COND_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond_filter.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c));
      }
      if (EvalFilterString(after_cond_filter)) {
        continue;
      }

      auto lambda = [&] (Args... args) { f(c, args...); };  // NOLINT [readability/braces] [4]
      TemplateHelper(std::function<void(Args...)>(lambda), depth, without_pc,
          after_cond, after_cond_filter, oss);
    }
  }

  template <typename... Args>
  void TemplateHelper(std::function<void(arm::SetCc, Args...)> f, int depth, bool without_pc,
                      std::string fmt, std::string filter, std::ostringstream& oss) {
    for (arm::SetCc s : GetSetCcs()) {
      std::string after_cond = fmt;
      std::string after_cond_filter = filter;

      size_t cond_index = after_cond.find(SET_CC_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond.replace(cond_index, ConstexprStrLen(SET_CC_TOKEN), GetSetCcString(s));
      }

      cond_index = after_cond_filter.find(SET_CC_TOKEN);
      if (cond_index != std::string::npos) {
        after_cond_filter.replace(cond_index, ConstexprStrLen(SET_CC_TOKEN), GetSetCcString(s));
      }
      if (EvalFilterString(after_cond_filter)) {
        continue;
      }

      auto lambda = [&] (Args... args) { f(s, args...); };  // NOLINT [readability/braces] [4]
      TemplateHelper(std::function<void(Args...)>(lambda), depth, without_pc,
          after_cond, after_cond_filter, oss);
    }
  }

  template <typename Assembler, typename T1, typename T2>
  std::function<void(T1, T2)> GetBoundFunction2(void (Assembler::*f)(T1, T2)) {
    return std::bind(f, GetAssembler(), _1, _2);
  }

  template <typename Assembler, typename T1, typename T2, typename T3>
  std::function<void(T1, T2, T3)> GetBoundFunction3(void (Assembler::*f)(T1, T2, T3)) {
    return std::bind(f, GetAssembler(), _1, _2, _3);
  }

  template <typename Assembler, typename T1, typename T2, typename T3, typename T4>
  std::function<void(T1, T2, T3, T4)> GetBoundFunction4(
      void (Assembler::*f)(T1, T2, T3, T4)) {
    return std::bind(f, GetAssembler(), _1, _2, _3, _4);
  }

  template <typename Assembler, typename T1, typename T2, typename T3, typename T4, typename T5>
  std::function<void(T1, T2, T3, T4, T5)> GetBoundFunction5(
      void (Assembler::*f)(T1, T2, T3, T4, T5)) {
    return std::bind(f, GetAssembler(), _1, _2, _3, _4, _5);
  }

  template <typename... Args>
  void GenericTemplateHelper(std::function<void(Args...)> f, bool without_pc,
                             std::string fmt, std::string test_name, std::string filter) {
    first_ = false;
    WarnOnCombinations(CountHelper<Args...>(without_pc));

    std::ostringstream oss;

    TemplateHelper(f, 0, without_pc, fmt, filter, oss);

    oss << "\n";  // Trailing newline.

    DriverStr(oss.str(), test_name);
  }

  template <typename Assembler, typename... Args>
  void T2Helper(void (Assembler::*f)(Args...), bool without_pc, std::string fmt,
                std::string test_name, std::string filter = "") {
    GenericTemplateHelper(GetBoundFunction2(f), without_pc, fmt, test_name, filter);
  }

  template <typename Assembler, typename... Args>
  void T3Helper(void (Assembler::*f)(Args...), bool without_pc, std::string fmt,
      std::string test_name, std::string filter = "") {
    GenericTemplateHelper(GetBoundFunction3(f), without_pc, fmt, test_name, filter);
  }

  template <typename Assembler, typename... Args>
  void T4Helper(void (Assembler::*f)(Args...), bool without_pc, std::string fmt,
      std::string test_name, std::string filter = "") {
    GenericTemplateHelper(GetBoundFunction4(f), without_pc, fmt, test_name, filter);
  }

  template <typename Assembler, typename... Args>
  void T5Helper(void (Assembler::*f)(Args...), bool without_pc, std::string fmt,
      std::string test_name, std::string filter = "") {
    GenericTemplateHelper(GetBoundFunction5(f), without_pc, fmt, test_name, filter);
  }

 private:
  template <typename T>
  size_t CountHelper(bool without_pc) {
    size_t tmp;
    if (std::is_same<T, arm::Register>::value) {
      tmp = GetRegisters().size();
      if (without_pc) {
        tmp--;;  // Approximation...
      }
      return tmp;
    } else if (std::is_same<T, const arm::ShifterOperand&>::value) {
      return GetShiftOperands().size();
    } else if (std::is_same<T, arm::Condition>::value) {
      return GetConditions().size();
    } else {
      LOG(WARNING) << "Unknown type while counting.";
      return 1;
    }
  }

  template <typename T1, typename T2, typename... Args>
  size_t CountHelper(bool without_pc) {
    size_t tmp;
    if (std::is_same<T1, arm::Register>::value) {
      tmp = GetRegisters().size();
      if (without_pc) {
        tmp--;;  // Approximation...
      }
    } else if (std::is_same<T1, const arm::ShifterOperand&>::value) {
      tmp =  GetShiftOperands().size();
    } else if (std::is_same<T1, arm::Condition>::value) {
      tmp = GetConditions().size();
    } else {
      LOG(WARNING) << "Unknown type while counting.";
      tmp = 1;
    }
    size_t rec = CountHelper<T2, Args...>(without_pc);
    return rec * tmp;
  }

  bool first_;

  static constexpr const char* kArm32AssemblyHeader = ".arm\n";

  std::vector<arm::Register*> registers_;
  std::vector<arm::Condition> conditions_;
  std::vector<arm::SetCc> set_ccs_;
  std::vector<arm::ShifterOperand> shifter_operands_;
};


TEST_F(AssemblerArm32Test, Toolchain) {
  EXPECT_TRUE(CheckTools());
}

TEST_F(AssemblerArm32Test, Sbfx) {
  std::vector<std::pair<uint32_t, uint32_t>> immediates;
  immediates.push_back({0, 1});
  immediates.push_back({0, 8});
  immediates.push_back({0, 15});
  immediates.push_back({0, 16});
  immediates.push_back({0, 31});
  immediates.push_back({0, 32});

  immediates.push_back({1, 1});
  immediates.push_back({1, 15});
  immediates.push_back({1, 31});

  immediates.push_back({8, 1});
  immediates.push_back({8, 15});
  immediates.push_back({8, 16});
  immediates.push_back({8, 24});

  immediates.push_back({31, 1});

  DriverStr(RepeatRRiiC(&arm::Arm32Assembler::sbfx, immediates,
                        "sbfx{cond} {reg1}, {reg2}, #{imm1}, #{imm2}"), "sbfx");
}

TEST_F(AssemblerArm32Test, Ubfx) {
  std::vector<std::pair<uint32_t, uint32_t>> immediates;
  immediates.push_back({0, 1});
  immediates.push_back({0, 8});
  immediates.push_back({0, 15});
  immediates.push_back({0, 16});
  immediates.push_back({0, 31});
  immediates.push_back({0, 32});

  immediates.push_back({1, 1});
  immediates.push_back({1, 15});
  immediates.push_back({1, 31});

  immediates.push_back({8, 1});
  immediates.push_back({8, 15});
  immediates.push_back({8, 16});
  immediates.push_back({8, 24});

  immediates.push_back({31, 1});

  DriverStr(RepeatRRiiC(&arm::Arm32Assembler::ubfx, immediates,
                        "ubfx{cond} {reg1}, {reg2}, #{imm1}, #{imm2}"), "ubfx");
}

TEST_F(AssemblerArm32Test, Mul) {
  T4Helper(&arm::Arm32Assembler::mul, true, "mul{cond} {reg1}, {reg2}, {reg3}", "mul");
}

TEST_F(AssemblerArm32Test, Mla) {
  T5Helper(&arm::Arm32Assembler::mla, true, "mla{cond} {reg1}, {reg2}, {reg3}, {reg4}", "mla");
}

TEST_F(AssemblerArm32Test, Umull) {
  T5Helper(&arm::Arm32Assembler::umull, true, "umull{cond} {reg1}, {reg2}, {reg3}, {reg4}",
           "umull", "{reg1}={reg2}");  // Skip the cases where reg1 == reg2.
}

TEST_F(AssemblerArm32Test, Smull) {
  T5Helper(&arm::Arm32Assembler::smull, true, "smull{cond} {reg1}, {reg2}, {reg3}, {reg4}",
           "smull", "{reg1}={reg2}");  // Skip the cases where reg1 == reg2.
}

TEST_F(AssemblerArm32Test, Sdiv) {
  T4Helper(&arm::Arm32Assembler::sdiv, true, "sdiv{cond} {reg1}, {reg2}, {reg3}", "sdiv");
}

TEST_F(AssemblerArm32Test, Udiv) {
  T4Helper(&arm::Arm32Assembler::udiv, true, "udiv{cond} {reg1}, {reg2}, {reg3}", "udiv");
}

TEST_F(AssemblerArm32Test, And) {
  T5Helper(&arm::Arm32Assembler::and_, true, "and{cond}{s} {reg1}, {reg2}, {shift}", "and");
}

TEST_F(AssemblerArm32Test, Ands) {
  T4Helper(&arm::Arm32Assembler::ands, true, "and{cond}s {reg1}, {reg2}, {shift}", "ands");
}

TEST_F(AssemblerArm32Test, Eor) {
  T5Helper(&arm::Arm32Assembler::eor, true, "eor{cond}{s} {reg1}, {reg2}, {shift}", "eor");
}

TEST_F(AssemblerArm32Test, Eors) {
  T4Helper(&arm::Arm32Assembler::eors, true, "eor{cond}s {reg1}, {reg2}, {shift}", "eors");
}

TEST_F(AssemblerArm32Test, Orr) {
  T5Helper(&arm::Arm32Assembler::orr, true, "orr{cond}{s} {reg1}, {reg2}, {shift}", "orr");
}

TEST_F(AssemblerArm32Test, Orrs) {
  T4Helper(&arm::Arm32Assembler::orrs, true, "orr{cond}s {reg1}, {reg2}, {shift}", "orrs");
}

TEST_F(AssemblerArm32Test, Bic) {
  T5Helper(&arm::Arm32Assembler::bic, true, "bic{cond}{s} {reg1}, {reg2}, {shift}", "bic");
}

TEST_F(AssemblerArm32Test, Bics) {
  T4Helper(&arm::Arm32Assembler::bics, true, "bic{cond}s {reg1}, {reg2}, {shift}", "bics");
}

TEST_F(AssemblerArm32Test, Mov) {
  T4Helper(&arm::Arm32Assembler::mov, true, "mov{cond}{s} {reg1}, {shift}", "mov");
}

TEST_F(AssemblerArm32Test, Movs) {
  T3Helper(&arm::Arm32Assembler::movs, true, "mov{cond}s {reg1}, {shift}", "movs");
}

TEST_F(AssemblerArm32Test, Mvn) {
  T4Helper(&arm::Arm32Assembler::mvn, true, "mvn{cond}{s} {reg1}, {shift}", "mvn");
}

TEST_F(AssemblerArm32Test, Mvns) {
  T3Helper(&arm::Arm32Assembler::mvns, true, "mvn{cond}s {reg1}, {shift}", "mvns");
}

TEST_F(AssemblerArm32Test, Add) {
  T5Helper(&arm::Arm32Assembler::add, false, "add{cond}{s} {reg1}, {reg2}, {shift}", "add");
}

TEST_F(AssemblerArm32Test, Adds) {
  T4Helper(&arm::Arm32Assembler::adds, false, "add{cond}s {reg1}, {reg2}, {shift}", "adds");
}

TEST_F(AssemblerArm32Test, Adc) {
  T5Helper(&arm::Arm32Assembler::adc, false, "adc{cond}{s} {reg1}, {reg2}, {shift}", "adc");
}

TEST_F(AssemblerArm32Test, Adcs) {
  T4Helper(&arm::Arm32Assembler::adcs, false, "adc{cond}s {reg1}, {reg2}, {shift}", "adcs");
}

TEST_F(AssemblerArm32Test, Sub) {
  T5Helper(&arm::Arm32Assembler::sub, false, "sub{cond}{s} {reg1}, {reg2}, {shift}", "sub");
}

TEST_F(AssemblerArm32Test, Subs) {
  T4Helper(&arm::Arm32Assembler::subs, false, "sub{cond}s {reg1}, {reg2}, {shift}", "subs");
}

TEST_F(AssemblerArm32Test, Sbc) {
  T5Helper(&arm::Arm32Assembler::sbc, false, "sbc{cond}{s} {reg1}, {reg2}, {shift}", "sbc");
}

TEST_F(AssemblerArm32Test, Sbcs) {
  T4Helper(&arm::Arm32Assembler::sbcs, false, "sbc{cond}s {reg1}, {reg2}, {shift}", "sbcs");
}

TEST_F(AssemblerArm32Test, Rsb) {
  T5Helper(&arm::Arm32Assembler::rsb, true, "rsb{cond}{s} {reg1}, {reg2}, {shift}", "rsb");
}

TEST_F(AssemblerArm32Test, Rsbs) {
  T4Helper(&arm::Arm32Assembler::rsbs, true, "rsb{cond}s {reg1}, {reg2}, {shift}", "rsbs");
}

TEST_F(AssemblerArm32Test, Rsc) {
  T5Helper(&arm::Arm32Assembler::rsc, true, "rsc{cond}{s} {reg1}, {reg2}, {shift}", "rsc");
}

TEST_F(AssemblerArm32Test, Rscs) {
  T4Helper(&arm::Arm32Assembler::rscs, false, "rsc{cond}s {reg1}, {reg2}, {shift}", "rscs");
}

/* TODO: Need better filter support.
TEST_F(AssemblerArm32Test, Strex) {
  T4Helper(&arm::Arm32Assembler::strex, "strex{cond} {reg1}, {reg2}, [{reg3}]", "strex",
           "{reg1}={reg2}||{reg1}={reg3}");  // Skip the cases where reg1 == reg2 || reg1 == reg3.
}
*/

TEST_F(AssemblerArm32Test, Clz) {
  T3Helper(&arm::Arm32Assembler::clz, true, "clz{cond} {reg1}, {reg2}", "clz");
}

TEST_F(AssemblerArm32Test, Tst) {
  T3Helper(&arm::Arm32Assembler::tst, true, "tst{cond} {reg1}, {shift}", "tst");
}

TEST_F(AssemblerArm32Test, Teq) {
  T3Helper(&arm::Arm32Assembler::teq, true, "teq{cond} {reg1}, {shift}", "teq");
}

TEST_F(AssemblerArm32Test, Cmp) {
  T3Helper(&arm::Arm32Assembler::cmp, true, "cmp{cond} {reg1}, {shift}", "cmp");
}

TEST_F(AssemblerArm32Test, Cmn) {
  T3Helper(&arm::Arm32Assembler::cmn, true, "cmn{cond} {reg1}, {shift}", "cmn");
}

TEST_F(AssemblerArm32Test, Blx) {
  T2Helper(&arm::Arm32Assembler::blx, true, "blx{cond} {reg1}", "blx");
}

TEST_F(AssemblerArm32Test, Bx) {
  T2Helper(&arm::Arm32Assembler::bx, true, "bx{cond} {reg1}", "bx");
}

TEST_F(AssemblerArm32Test, Vmstat) {
  GetAssembler()->vmstat();

  const char* expected = "vmrs APSR_nzcv, FPSCR\n";

  DriverStr(expected, "vmrs");
}

TEST_F(AssemblerArm32Test, ldrexd) {
  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R0);
  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R1);
  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R2);

  const char* expected =
      "ldrexd r0, r1, [r0]\n"
      "ldrexd r0, r1, [r1]\n"
      "ldrexd r0, r1, [r2]\n";
  DriverStr(expected, "ldrexd");
}

TEST_F(AssemblerArm32Test, strexd) {
  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R0);
  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R1);
  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R2);

  const char* expected =
      "strexd r9, r0, r1, [r0]\n"
      "strexd r9, r0, r1, [r1]\n"
      "strexd r9, r0, r1, [r2]\n";
  DriverStr(expected, "strexd");
}

TEST_F(AssemblerArm32Test, rbit) {
  T3Helper(&arm::Arm32Assembler::rbit, true, "rbit{cond} {reg1}, {reg2}", "rbit");
}

}  // namespace art
