diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index 591d461..9c84bc1 100644
--- a/compiler/utils/arm/assembler_arm.cc
+++ b/compiler/utils/arm/assembler_arm.cc
@@ -92,16 +92,29 @@
       break;
     case kRegister:
       if (is_shift_) {
+        uint32_t shift_type;
+        switch (shift_) {
+          case arm::Shift::ROR:
+            shift_type = static_cast<uint32_t>(shift_);
+            CHECK_NE(immed_, 0U);
+            break;
+          case arm::Shift::RRX:
+            shift_type = static_cast<uint32_t>(arm::Shift::ROR);  // Same encoding as ROR.
+            CHECK_EQ(immed_, 0U);
+            break;
+          default:
+            shift_type = static_cast<uint32_t>(shift_);
+        }
         // Shifted immediate or register.
         if (rs_ == kNoRegister) {
           // Immediate shift.
           return immed_ << kShiftImmShift |
-                          static_cast<uint32_t>(shift_) << kShiftShift |
+                          shift_type << kShiftShift |
                           static_cast<uint32_t>(rm_);
         } else {
           // Register shift.
           return static_cast<uint32_t>(rs_) << kShiftRegisterShift |
-              static_cast<uint32_t>(shift_) << kShiftShift | (1 << 4) |
+              shift_type << kShiftShift | (1 << 4) |
               static_cast<uint32_t>(rm_);
         }
       } else {
diff --git a/compiler/utils/arm/assembler_arm32_test.cc b/compiler/utils/arm/assembler_arm32_test.cc
index 277a9eb..fe12a22 100644
--- a/compiler/utils/arm/assembler_arm32_test.cc
+++ b/compiler/utils/arm/assembler_arm32_test.cc
@@ -16,49 +16,208 @@
 
 #include "assembler_arm32.h"
 
+#include <functional>
+#include <type_traits>
+
+#include "base/macros.h"
 #include "base/stl_util.h"
-#include "utils/assembler_test.h"
+#include "utils/arm/assembler_arm_test.h"
 
 namespace art {
 
-class AssemblerArm32Test : public AssemblerTest<arm::Arm32Assembler,
-                                                arm::Register, arm::SRegister,
-                                                uint32_t> {
+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> {
  protected:
   std::string GetArchitectureString() OVERRIDE {
     return "arm";
   }
 
+  std::string GetAssemblerParameters() OVERRIDE {
+    return " -march=armv7ve";  // Arm-v7a with virtualization extension (means we have sdiv).
+  }
+
+  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) {
-      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 (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);
+    }
+
+    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 {
-    AssemblerTest::TearDown();
+    AssemblerArmTest::TearDown();
     STLDeleteElements(&registers_);
   }
 
@@ -70,8 +229,280 @@
     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();
+  }
+
+  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 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();
+  }
+
+  void TemplateHelper(std::function<void(arm::Register)> f, int depth ATTRIBUTE_UNUSED,
+                      bool without_pc,
+                      std::string fmt, std::ostringstream& oss) {
+    std::vector<arm::Register*> registers = without_pc ? GetRegistersWithoutPC() : GetRegisters();
+    for (auto reg : registers) {
+      std::string after_reg = fmt;
+
+      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);
+      }
+
+      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::ostringstream& oss) {
+    for (const arm::ShifterOperand& shift : GetShiftOperands()) {
+      std::string after_shift = fmt;
+
+      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);
+      }
+
+      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::ostringstream& oss) {
+    for (arm::Condition c : GetConditions()) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      ExecuteAndPrint([&] () { f(c); }, after_cond, oss);
+    }
+  }
+
+  template <typename... Args>
+  void TemplateHelper(std::function<void(arm::Register, Args...)> f, int depth, bool without_pc,
+                      std::string fmt, std::ostringstream& oss) {
+    std::vector<arm::Register*> registers = without_pc ? GetRegistersWithoutPC() : GetRegisters();
+    for (auto reg : registers) {
+      std::string after_reg = fmt;
+
+      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);
+      }
+
+      auto lambda = [&] (Args... args) { f(*reg, args...); };  // NOLINT [readability/braces] [4]
+      TemplateHelper(std::function<void(Args...)>(lambda), depth + 1, without_pc,
+          after_reg, oss);
+    }
+  }
+
+  template <typename... Args>
+  void TemplateHelper(std::function<void(const arm::ShifterOperand&, Args...)> f, int depth,
+                      bool without_pc, std::string fmt, std::ostringstream& oss) {
+    for (const arm::ShifterOperand& shift : GetShiftOperands()) {
+      std::string after_shift = fmt;
+
+      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);
+      }
+
+      auto lambda = [&] (Args... args) { f(shift, args...); };  // NOLINT [readability/braces] [4]
+      TemplateHelper(std::function<void(Args...)>(lambda), depth, without_pc,
+          after_shift, oss);
+    }
+  }
+
+  template <typename... Args>
+  void TemplateHelper(std::function<void(arm::Condition, Args...)> f, int depth, bool without_pc,
+                      std::string fmt, std::ostringstream& oss) {
+    for (arm::Condition c : GetConditions()) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      auto lambda = [&] (Args... args) { f(c, args...); };  // NOLINT [readability/braces] [4]
+      TemplateHelper(std::function<void(Args...)>(lambda), depth, without_pc,
+          after_cond, oss);
+    }
+  }
+
+  template <typename T1, typename T2>
+  std::function<void(T1, T2)> GetBoundFunction2(void (arm::Arm32Assembler::*f)(T1, T2)) {
+    return std::bind(f, GetAssembler(), _1, _2);
+  }
+
+  template <typename T1, typename T2, typename T3>
+  std::function<void(T1, T2, T3)> GetBoundFunction3(void (arm::Arm32Assembler::*f)(T1, T2, T3)) {
+    return std::bind(f, GetAssembler(), _1, _2, _3);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4>
+  std::function<void(T1, T2, T3, T4)> GetBoundFunction4(
+      void (arm::Arm32Assembler::*f)(T1, T2, T3, T4)) {
+    return std::bind(f, GetAssembler(), _1, _2, _3, _4);
+  }
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  std::function<void(T1, T2, T3, T4, T5)> GetBoundFunction5(
+      void (arm::Arm32Assembler::*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) {
+    WarnOnCombinations(CountHelper<Args...>(without_pc));
+
+    std::ostringstream oss;
+
+    TemplateHelper(f, 0, without_pc, fmt, oss);
+
+    oss << "\n";  // Trailing newline.
+
+    DriverStr(oss.str(), test_name);
+  }
+
+  template <typename... Args>
+  void T2Helper(void (arm::Arm32Assembler::*f)(Args...), bool without_pc, std::string fmt,
+                std::string test_name) {
+    GenericTemplateHelper(GetBoundFunction2(f), without_pc, fmt, test_name);
+  }
+
+  template <typename... Args>
+  void T3Helper(void (arm::Arm32Assembler::*f)(Args...), bool without_pc, std::string fmt,
+      std::string test_name) {
+    GenericTemplateHelper(GetBoundFunction3(f), without_pc, fmt, test_name);
+  }
+
+  template <typename... Args>
+  void T4Helper(void (arm::Arm32Assembler::*f)(Args...), bool without_pc, std::string fmt,
+      std::string test_name) {
+    GenericTemplateHelper(GetBoundFunction4(f), without_pc, fmt, test_name);
+  }
+
+  template <typename... Args>
+  void T5Helper(void (arm::Arm32Assembler::*f)(Args...), bool without_pc, std::string fmt,
+      std::string test_name) {
+    GenericTemplateHelper(GetBoundFunction5(f), without_pc, fmt, test_name);
+  }
+
  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::ShifterOperand> shifter_operands_;
 };
 
 
@@ -79,77 +510,181 @@
   EXPECT_TRUE(CheckTools());
 }
 
-
 TEST_F(AssemblerArm32Test, Sbfx) {
-  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 1);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 8);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 16);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 32);
+  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});
 
-  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 1);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 8);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 16);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 24);
+  immediates.push_back({1, 1});
+  immediates.push_back({1, 15});
+  immediates.push_back({1, 31});
 
-  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 1);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 8);
-  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 16);
+  immediates.push_back({8, 1});
+  immediates.push_back({8, 15});
+  immediates.push_back({8, 16});
+  immediates.push_back({8, 24});
 
-  GetAssembler()->sbfx(arm::R0, arm::R1, 31, 1);
+  immediates.push_back({31, 1});
 
-  const char* expected =
-      "sbfx r0, r1, #0, #1\n"
-      "sbfx r0, r1, #0, #8\n"
-      "sbfx r0, r1, #0, #16\n"
-      "sbfx r0, r1, #0, #32\n"
-
-      "sbfx r0, r1, #8, #1\n"
-      "sbfx r0, r1, #8, #8\n"
-      "sbfx r0, r1, #8, #16\n"
-      "sbfx r0, r1, #8, #24\n"
-
-      "sbfx r0, r1, #16, #1\n"
-      "sbfx r0, r1, #16, #8\n"
-      "sbfx r0, r1, #16, #16\n"
-
-      "sbfx r0, r1, #31, #1\n";
-  DriverStr(expected, "sbfx");
+  DriverStr(RepeatRRiiC(&arm::Arm32Assembler::sbfx, immediates,
+                        "sbfx{cond} {reg1}, {reg2}, #{imm1}, #{imm2}"), "sbfx");
 }
 
 TEST_F(AssemblerArm32Test, Ubfx) {
-  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 1);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 8);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 16);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 32);
+  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});
 
-  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 1);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 8);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 16);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 24);
+  immediates.push_back({1, 1});
+  immediates.push_back({1, 15});
+  immediates.push_back({1, 31});
 
-  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 1);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 8);
-  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 16);
+  immediates.push_back({8, 1});
+  immediates.push_back({8, 15});
+  immediates.push_back({8, 16});
+  immediates.push_back({8, 24});
 
-  GetAssembler()->ubfx(arm::R0, arm::R1, 31, 1);
+  immediates.push_back({31, 1});
 
-  const char* expected =
-      "ubfx r0, r1, #0, #1\n"
-      "ubfx r0, r1, #0, #8\n"
-      "ubfx r0, r1, #0, #16\n"
-      "ubfx r0, r1, #0, #32\n"
+  DriverStr(RepeatRRiiC(&arm::Arm32Assembler::ubfx, immediates,
+                        "ubfx{cond} {reg1}, {reg2}, #{imm1}, #{imm2}"), "ubfx");
+}
 
-      "ubfx r0, r1, #8, #1\n"
-      "ubfx r0, r1, #8, #8\n"
-      "ubfx r0, r1, #8, #16\n"
-      "ubfx r0, r1, #8, #24\n"
+TEST_F(AssemblerArm32Test, Mul) {
+  T4Helper(&arm::Arm32Assembler::mul, true, "mul{cond} {reg1}, {reg2}, {reg3}", "mul");
+}
 
-      "ubfx r0, r1, #16, #1\n"
-      "ubfx r0, r1, #16, #8\n"
-      "ubfx r0, r1, #16, #16\n"
+TEST_F(AssemblerArm32Test, Mla) {
+  T5Helper(&arm::Arm32Assembler::mla, true, "mla{cond} {reg1}, {reg2}, {reg3}, {reg4}", "mul");
+}
 
-      "ubfx r0, r1, #31, #1\n";
-  DriverStr(expected, "ubfx");
+/* TODO: Needs support to filter out register combinations, as rdhi must not be equal to rdlo.
+TEST_F(AssemblerArm32Test, Umull) {
+  T5Helper(&arm::Arm32Assembler::umull, true, "umull{cond} {reg1}, {reg2}, {reg3}, {reg4}",
+           "umull");
+}
+*/
+
+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) {
+  T4Helper(&arm::Arm32Assembler::and_, true, "and{cond} {reg1}, {reg2}, {shift}", "and");
+}
+
+TEST_F(AssemblerArm32Test, Eor) {
+  T4Helper(&arm::Arm32Assembler::eor, true, "eor{cond} {reg1}, {reg2}, {shift}", "eor");
+}
+
+TEST_F(AssemblerArm32Test, Orr) {
+  T4Helper(&arm::Arm32Assembler::orr, true, "orr{cond} {reg1}, {reg2}, {shift}", "orr");
+}
+
+TEST_F(AssemblerArm32Test, Orrs) {
+  T4Helper(&arm::Arm32Assembler::orrs, true, "orr{cond}s {reg1}, {reg2}, {shift}", "orrs");
+}
+
+TEST_F(AssemblerArm32Test, Bic) {
+  T4Helper(&arm::Arm32Assembler::bic, true, "bic{cond} {reg1}, {reg2}, {shift}", "bic");
+}
+
+TEST_F(AssemblerArm32Test, Mov) {
+  T3Helper(&arm::Arm32Assembler::mov, true, "mov{cond} {reg1}, {shift}", "mov");
+}
+
+TEST_F(AssemblerArm32Test, Movs) {
+  T3Helper(&arm::Arm32Assembler::movs, true, "mov{cond}s {reg1}, {shift}", "movs");
+}
+
+TEST_F(AssemblerArm32Test, Mvn) {
+  T3Helper(&arm::Arm32Assembler::mvn, true, "mvn{cond} {reg1}, {shift}", "mvn");
+}
+
+TEST_F(AssemblerArm32Test, Mvns) {
+  T3Helper(&arm::Arm32Assembler::mvns, true, "mvn{cond}s {reg1}, {shift}", "mvns");
+}
+
+TEST_F(AssemblerArm32Test, Add) {
+  T4Helper(&arm::Arm32Assembler::add, false, "add{cond} {reg1}, {reg2}, {shift}", "add");
+}
+
+TEST_F(AssemblerArm32Test, Adds) {
+  T4Helper(&arm::Arm32Assembler::adds, false, "add{cond}s {reg1}, {reg2}, {shift}", "adds");
+}
+
+TEST_F(AssemblerArm32Test, Adc) {
+  T4Helper(&arm::Arm32Assembler::adc, false, "adc{cond} {reg1}, {reg2}, {shift}", "adc");
+}
+
+TEST_F(AssemblerArm32Test, Sub) {
+  T4Helper(&arm::Arm32Assembler::sub, false, "sub{cond} {reg1}, {reg2}, {shift}", "sub");
+}
+
+TEST_F(AssemblerArm32Test, Subs) {
+  T4Helper(&arm::Arm32Assembler::subs, false, "sub{cond}s {reg1}, {reg2}, {shift}", "subs");
+}
+
+TEST_F(AssemblerArm32Test, Sbc) {
+  T4Helper(&arm::Arm32Assembler::sbc, false, "sbc{cond} {reg1}, {reg2}, {shift}", "sbc");
+}
+
+TEST_F(AssemblerArm32Test, Rsb) {
+  T4Helper(&arm::Arm32Assembler::rsb, true, "rsb{cond} {reg1}, {reg2}, {shift}", "rsb");
+}
+
+TEST_F(AssemblerArm32Test, Rsbs) {
+  T4Helper(&arm::Arm32Assembler::rsbs, true, "rsb{cond}s {reg1}, {reg2}, {shift}", "rsbs");
+}
+
+TEST_F(AssemblerArm32Test, Rsc) {
+  T4Helper(&arm::Arm32Assembler::rsc, true, "rsc{cond} {reg1}, {reg2}, {shift}", "rsc");
+}
+
+/* TODO: Needs support to filter out register combinations, as reg1 must not be equal to reg3.
+TEST_F(AssemblerArm32Test, Strex) {
+  RRRCWithoutPCHelper(&arm::Arm32Assembler::strex, "strex{cond} {reg1}, {reg2}, [{reg3}]", "strex");
+}
+*/
+
+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");
 }
 
 }  // namespace art
diff --git a/compiler/utils/arm/assembler_arm_test.h b/compiler/utils/arm/assembler_arm_test.h
new file mode 100644
index 0000000..34475b2
--- /dev/null
+++ b/compiler/utils/arm/assembler_arm_test.h
@@ -0,0 +1,545 @@
+/*
+ * 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.
+ */
+
+#ifndef ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_
+#define ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_
+
+#include "utils/assembler_test.h"
+
+namespace art {
+
+template<typename Ass, typename Reg, typename FPReg, typename Imm, typename SOp, typename Cond>
+class AssemblerArmTest : public AssemblerTest<Ass, Reg, FPReg, Imm> {
+ public:
+  typedef AssemblerTest<Ass, Reg, FPReg, Imm> Base;
+
+  using Base::GetRegisters;
+  using Base::GetRegName;
+  using Base::CreateImmediate;
+  using Base::WarnOnCombinations;
+
+  static constexpr int64_t kFullImmRangeThreshold = 32;
+
+  virtual void FillImmediates(std::vector<Imm>& immediates, int64_t imm_min, int64_t imm_max) {
+    // Small range: do completely.
+    if (imm_max - imm_min <= kFullImmRangeThreshold) {
+      for (int64_t i = imm_min; i <= imm_max; ++i) {
+        immediates.push_back(CreateImmediate(i));
+      }
+    } else {
+      immediates.push_back(CreateImmediate(imm_min));
+      immediates.push_back(CreateImmediate(imm_max));
+      if (imm_min < imm_max - 1) {
+        immediates.push_back(CreateImmediate(imm_min + 1));
+      }
+      if (imm_min < imm_max - 2) {
+        immediates.push_back(CreateImmediate(imm_min + 2));
+      }
+      if (imm_min < imm_max - 3) {
+        immediates.push_back(CreateImmediate(imm_max - 1));
+      }
+      if (imm_min < imm_max - 4) {
+        immediates.push_back(CreateImmediate((imm_min + imm_max) / 2));
+      }
+    }
+  }
+
+  std::string RepeatRRIIC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond),
+                          int64_t imm1_min, int64_t imm1_max,
+                          int64_t imm2_min, int64_t imm2_max,
+                          std::string fmt) {
+    return RepeatTemplatedRRIIC(f, GetRegisters(), GetRegisters(),
+                                &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+                                &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+                                imm1_min, imm1_max, imm2_min, imm2_max,
+                                fmt);
+  }
+
+  template <typename Reg1, typename Reg2>
+  std::string RepeatTemplatedRRIIC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond),
+                                   const std::vector<Reg1*> reg1_registers,
+                                   const std::vector<Reg2*> reg2_registers,
+                                   std::string (AssemblerArmTest::*GetName1)(const Reg1&),
+                                   std::string (AssemblerArmTest::*GetName2)(const Reg2&),
+                                   int64_t imm1_min, int64_t imm1_max,
+                                   int64_t imm2_min, int64_t imm2_max,
+                                   std::string fmt) {
+    std::vector<Imm> immediates1;
+    FillImmediates(immediates1, imm1_min, imm1_max);
+    std::vector<Imm> immediates2;
+    FillImmediates(immediates2, imm2_min, imm2_max);
+
+    std::vector<Cond>& cond = GetConditions();
+
+    WarnOnCombinations(cond.size() * immediates1.size() * immediates2.size() *
+                       reg1_registers.size() * reg2_registers.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (Imm i : immediates1) {
+        std::string base = after_cond;
+
+        size_t imm1_index = base.find(IMM1_TOKEN);
+        if (imm1_index != std::string::npos) {
+          std::ostringstream sreg;
+          sreg << i;
+          std::string imm_string = sreg.str();
+          base.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string);
+        }
+
+        for (Imm j : immediates2) {
+          std::string base2 = base;
+
+          size_t imm2_index = base2.find(IMM2_TOKEN);
+          if (imm2_index != std::string::npos) {
+            std::ostringstream sreg;
+            sreg << j;
+            std::string imm_string = sreg.str();
+            base2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string);
+          }
+
+          for (auto reg1 : reg1_registers) {
+            std::string base3 = base2;
+
+            std::string reg1_string = (this->*GetName1)(*reg1);
+            size_t reg1_index;
+            while ((reg1_index = base3.find(Base::REG1_TOKEN)) != std::string::npos) {
+              base3.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string);
+            }
+
+            for (auto reg2 : reg2_registers) {
+              std::string base4 = base3;
+
+              std::string reg2_string = (this->*GetName2)(*reg2);
+              size_t reg2_index;
+              while ((reg2_index = base4.find(Base::REG2_TOKEN)) != std::string::npos) {
+                base4.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string);
+              }
+
+              if (first) {
+                first = false;
+              } else {
+                oss << "\n";
+              }
+              oss << base4;
+
+              (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c);
+            }
+          }
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+  std::string RepeatRRiiC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond),
+                          std::vector<std::pair<Imm, Imm>>& immediates,
+                          std::string fmt) {
+    return RepeatTemplatedRRiiC(f, GetRegisters(), GetRegisters(),
+        &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+        &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+        immediates, fmt);
+  }
+
+  template <typename Reg1, typename Reg2>
+  std::string RepeatTemplatedRRiiC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond),
+        const std::vector<Reg1*> reg1_registers,
+        const std::vector<Reg2*> reg2_registers,
+        std::string (AssemblerArmTest::*GetName1)(const Reg1&),
+        std::string (AssemblerArmTest::*GetName2)(const Reg2&),
+        std::vector<std::pair<Imm, Imm>>& immediates,
+        std::string fmt) {
+    std::vector<Cond>& cond = GetConditions();
+
+    WarnOnCombinations(cond.size() * immediates.size() * reg1_registers.size() *
+                       reg2_registers.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (std::pair<Imm, Imm>& pair : immediates) {
+        Imm i = pair.first;
+        Imm j = pair.second;
+        std::string after_imm1 = after_cond;
+
+        size_t imm1_index = after_imm1.find(IMM1_TOKEN);
+        if (imm1_index != std::string::npos) {
+          std::ostringstream sreg;
+          sreg << i;
+          std::string imm_string = sreg.str();
+          after_imm1.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string);
+        }
+
+        std::string after_imm2 = after_imm1;
+
+        size_t imm2_index = after_imm2.find(IMM2_TOKEN);
+        if (imm2_index != std::string::npos) {
+          std::ostringstream sreg;
+          sreg << j;
+          std::string imm_string = sreg.str();
+          after_imm2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string);
+        }
+
+        for (auto reg1 : reg1_registers) {
+          std::string after_reg1 = after_imm2;
+
+          std::string reg1_string = (this->*GetName1)(*reg1);
+          size_t reg1_index;
+          while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) {
+            after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string);
+          }
+
+          for (auto reg2 : reg2_registers) {
+            std::string after_reg2 = after_reg1;
+
+            std::string reg2_string = (this->*GetName2)(*reg2);
+            size_t reg2_index;
+            while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) {
+              after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string);
+            }
+
+            if (first) {
+              first = false;
+            } else {
+              oss << "\n";
+            }
+            oss << after_reg2;
+
+            (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c);
+          }
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+  std::string RepeatRRC(void (Ass::*f)(Reg, Reg, Cond), std::string fmt) {
+    return RepeatTemplatedRRC(f, GetRegisters(), GetRegisters(), GetConditions(),
+        &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+        &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+        fmt);
+  }
+
+  template <typename Reg1, typename Reg2>
+  std::string RepeatTemplatedRRC(void (Ass::*f)(Reg1, Reg2, Cond),
+                                 const std::vector<Reg1*>& reg1_registers,
+                                 const std::vector<Reg2*>& reg2_registers,
+                                 const std::vector<Cond>& cond,
+                                 std::string (AssemblerArmTest::*GetName1)(const Reg1&),
+                                 std::string (AssemblerArmTest::*GetName2)(const Reg2&),
+                                 std::string fmt) {
+    WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (const Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (auto reg1 : reg1_registers) {
+        std::string after_reg1 = after_cond;
+
+        std::string reg1_string = (this->*GetName1)(*reg1);
+        size_t reg1_index;
+        while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) {
+          after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string);
+        }
+
+        for (auto reg2 : reg2_registers) {
+          std::string after_reg2 = after_reg1;
+
+          std::string reg2_string = (this->*GetName2)(*reg2);
+          size_t reg2_index;
+          while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) {
+            after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string);
+          }
+
+          if (first) {
+            first = false;
+          } else {
+            oss << "\n";
+          }
+          oss << after_reg2;
+
+          (Base::GetAssembler()->*f)(*reg1, *reg2, c);
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+  std::string RepeatRRRC(void (Ass::*f)(Reg, Reg, Reg, Cond), std::string fmt) {
+    return RepeatTemplatedRRRC(f, GetRegisters(), GetRegisters(), GetRegisters(), GetConditions(),
+                               &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+                               &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+                               &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>,
+                               fmt);
+  }
+
+  template <typename Reg1, typename Reg2, typename Reg3>
+  std::string RepeatTemplatedRRRC(void (Ass::*f)(Reg1, Reg2, Reg3, Cond),
+                                  const std::vector<Reg1*>& reg1_registers,
+                                  const std::vector<Reg2*>& reg2_registers,
+                                  const std::vector<Reg3*>& reg3_registers,
+                                  const std::vector<Cond>& cond,
+                                  std::string (AssemblerArmTest::*GetName1)(const Reg1&),
+                                  std::string (AssemblerArmTest::*GetName2)(const Reg2&),
+                                  std::string (AssemblerArmTest::*GetName3)(const Reg3&),
+                                  std::string fmt) {
+    WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() *
+                       reg3_registers.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (const Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (auto reg1 : reg1_registers) {
+        std::string after_reg1 = after_cond;
+
+        std::string reg1_string = (this->*GetName1)(*reg1);
+        size_t reg1_index;
+        while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) {
+          after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string);
+        }
+
+        for (auto reg2 : reg2_registers) {
+          std::string after_reg2 = after_reg1;
+
+          std::string reg2_string = (this->*GetName2)(*reg2);
+          size_t reg2_index;
+          while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) {
+            after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string);
+          }
+
+          for (auto reg3 : reg3_registers) {
+            std::string after_reg3 = after_reg2;
+
+            std::string reg3_string = (this->*GetName3)(*reg3);
+            size_t reg3_index;
+            while ((reg3_index = after_reg3.find(REG3_TOKEN)) != std::string::npos) {
+              after_reg3.replace(reg3_index, ConstexprStrLen(REG3_TOKEN), reg3_string);
+            }
+
+            if (first) {
+              first = false;
+            } else {
+              oss << "\n";
+            }
+            oss << after_reg3;
+
+            (Base::GetAssembler()->*f)(*reg1, *reg2, *reg3, c);
+          }
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+  template <typename RegT>
+  std::string RepeatTemplatedRSC(void (Ass::*f)(RegT, SOp, Cond),
+                                 const std::vector<RegT*>& registers,
+                                 const std::vector<SOp>& shifts,
+                                 const std::vector<Cond>& cond,
+                                 std::string (AssemblerArmTest::*GetName)(const RegT&),
+                                 std::string fmt) {
+    WarnOnCombinations(cond.size() * registers.size() * shifts.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (const Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (const SOp& shift : shifts) {
+        std::string after_shift = after_cond;
+
+        std::string shift_string = GetShiftString(shift);
+        size_t shift_index;
+        while ((shift_index = after_shift.find(Base::SHIFT_TOKEN)) != std::string::npos) {
+          after_shift.replace(shift_index, ConstexprStrLen(Base::SHIFT_TOKEN), shift_string);
+        }
+
+        for (auto reg : registers) {
+          std::string after_reg = after_shift;
+
+          std::string reg_string = (this->*GetName)(*reg);
+          size_t reg_index;
+          while ((reg_index = after_reg.find(Base::REG_TOKEN)) != std::string::npos) {
+            after_reg.replace(reg_index, ConstexprStrLen(Base::REG_TOKEN), reg_string);
+          }
+
+          if (first) {
+            first = false;
+          } else {
+            oss << "\n";
+          }
+          oss << after_reg;
+
+          (Base::GetAssembler()->*f)(*reg, shift, c);
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+  template <typename Reg1, typename Reg2>
+  std::string RepeatTemplatedRRSC(void (Ass::*f)(Reg1, Reg2, const SOp&, Cond),
+                                  const std::vector<Reg1*>& reg1_registers,
+                                  const std::vector<Reg2*>& reg2_registers,
+                                  const std::vector<SOp>& shifts,
+                                  const std::vector<Cond>& cond,
+                                  std::string (AssemblerArmTest::*GetName1)(const Reg1&),
+                                  std::string (AssemblerArmTest::*GetName2)(const Reg2&),
+                                  std::string fmt) {
+    WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() * shifts.size());
+
+    std::ostringstream oss;
+    bool first = true;
+    for (const Cond& c : cond) {
+      std::string after_cond = fmt;
+
+      size_t cond_index = after_cond.find(COND_TOKEN);
+      if (cond_index != std::string::npos) {
+        after_cond.replace(cond_index, ConstexprStrLen(IMM1_TOKEN), GetConditionString(c));
+      }
+
+      for (const SOp& shift : shifts) {
+        std::string after_shift = after_cond;
+
+        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);
+        }
+
+        for (auto reg1 : reg1_registers) {
+          std::string after_reg1 = after_shift;
+
+          std::string reg1_string = (this->*GetName1)(*reg1);
+          size_t reg1_index;
+          while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) {
+            after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string);
+          }
+
+          for (auto reg2 : reg2_registers) {
+            std::string after_reg2 = after_reg1;
+
+            std::string reg2_string = (this->*GetName2)(*reg2);
+            size_t reg2_index;
+            while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) {
+              after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string);
+            }
+
+            if (first) {
+              first = false;
+            } else {
+              oss << "\n";
+            }
+            oss << after_reg2;
+
+            (Base::GetAssembler()->*f)(*reg1, *reg2, shift, c);
+          }
+        }
+      }
+    }
+    // Add a newline at the end.
+    oss << "\n";
+
+    return oss.str();
+  }
+
+ protected:
+  explicit AssemblerArmTest() {}
+
+  virtual std::vector<Cond>& GetConditions() = 0;
+  virtual std::string GetConditionString(Cond c) = 0;
+
+  virtual std::vector<SOp>& GetShiftOperands() = 0;
+  virtual std::string GetShiftString(SOp sop) = 0;
+
+  virtual Reg GetPCRegister() = 0;
+  virtual std::vector<Reg*> GetRegistersWithoutPC() {
+    std::vector<Reg*> without_pc = GetRegisters();
+    Reg pc_reg = GetPCRegister();
+
+    for (auto it = without_pc.begin(); it != without_pc.end(); ++it) {
+      if (**it == pc_reg) {
+        without_pc.erase(it);
+        break;
+      }
+    }
+
+    return without_pc;
+  }
+
+  static constexpr const char* IMM1_TOKEN = "{imm1}";
+  static constexpr const char* IMM2_TOKEN = "{imm2}";
+  static constexpr const char* REG3_TOKEN = "{reg3}";
+  static constexpr const char* REG4_TOKEN = "{reg4}";
+  static constexpr const char* COND_TOKEN = "{cond}";
+  static constexpr const char* SHIFT_TOKEN = "{shift}";
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AssemblerArmTest);
+};
+
+}  // namespace art
+
+#endif  // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_
diff --git a/compiler/utils/assembler_test.h b/compiler/utils/assembler_test.h
index 9d3fa01..1fadb91 100644
--- a/compiler/utils/assembler_test.h
+++ b/compiler/utils/assembler_test.h
@@ -38,14 +38,14 @@
 // temp directory.
 static std::string tmpnam_;
 
+enum class RegisterView {  // private
+  kUsePrimaryName,
+  kUseSecondaryName
+};
+
 template<typename Ass, typename Reg, typename FPReg, typename Imm>
 class AssemblerTest : public testing::Test {
  public:
-  enum class RegisterView {  // private
-    kUsePrimaryName,
-    kUseSecondaryName
-  };
-
   Ass* GetAssembler() {
     return assembler_.get();
   }
@@ -159,6 +159,9 @@
                       bool as_uint = false) {
     std::string str;
     std::vector<int64_t> imms = CreateImmediateValues(imm_bytes, as_uint);
+
+    WarnOnCombinations(imms.size());
+
     for (int64_t imm : imms) {
       Imm new_imm = CreateImmediate(imm);
       (assembler_.get()->*f)(new_imm);
@@ -184,12 +187,12 @@
 
   // This is intended to be run as a test.
   bool CheckTools() {
-    if (!FileExists(GetAssemblerCommand())) {
+    if (!FileExists(FindTool(GetAssemblerCmdName()))) {
       return false;
     }
     LOG(INFO) << "Chosen assembler command: " << GetAssemblerCommand();
 
-    if (!FileExists(GetObjdumpCommand())) {
+    if (!FileExists(FindTool(GetObjdumpCmdName()))) {
       return false;
     }
     LOG(INFO) << "Chosen objdump command: " << GetObjdumpCommand();
@@ -197,7 +200,7 @@
     // Disassembly is optional.
     std::string disassembler = GetDisassembleCommand();
     if (disassembler.length() != 0) {
-      if (!FileExists(disassembler)) {
+      if (!FileExists(FindTool(GetDisassembleCmdName()))) {
         return false;
       }
       LOG(INFO) << "Chosen disassemble command: " << GetDisassembleCommand();
@@ -271,7 +274,7 @@
 
     resolved_assembler_cmd_ = line + GetAssemblerParameters();
 
-    return line;
+    return resolved_assembler_cmd_;
   }
 
   // Get the name of the objdump, e.g., "objdump" by default.
@@ -298,7 +301,7 @@
 
     resolved_objdump_cmd_ = line + GetObjdumpParameters();
 
-    return line;
+    return resolved_objdump_cmd_;
   }
 
   // Get the name of the objdump, e.g., "objdump" by default.
@@ -324,7 +327,7 @@
 
     resolved_disassemble_cmd_ = line + GetDisassembleParameters();
 
-    return line;
+    return resolved_disassemble_cmd_;
   }
 
   // Create a couple of immediate values up to the number of bytes given.
@@ -406,6 +409,8 @@
                                        std::string (AssemblerTest::*GetName1)(const Reg1&),
                                        std::string (AssemblerTest::*GetName2)(const Reg2&),
                                        std::string fmt) {
+    WarnOnCombinations(reg1_registers.size() * reg2_registers.size());
+
     std::string str;
     for (auto reg1 : reg1_registers) {
       for (auto reg2 : reg2_registers) {
@@ -435,7 +440,6 @@
     return str;
   }
 
- private:
   template <RegisterView kRegView>
   std::string GetRegName(const Reg& reg) {
     std::ostringstream sreg;
@@ -457,12 +461,32 @@
     return sreg.str();
   }
 
+  // If the assembly file needs a header, return it in a sub-class.
+  virtual const char* GetAssemblyHeader() {
+    return nullptr;
+  }
+
+  void WarnOnCombinations(size_t count) {
+    if (count > kWarnManyCombinationsThreshold) {
+      GTEST_LOG_(WARNING) << "Many combinations (" << count << "), test generation might be slow.";
+    }
+  }
+
+  static constexpr const char* REG_TOKEN = "{reg}";
+  static constexpr const char* REG1_TOKEN = "{reg1}";
+  static constexpr const char* REG2_TOKEN = "{reg2}";
+  static constexpr const char* IMM_TOKEN = "{imm}";
+
+ private:
   template <RegisterView kRegView>
   std::string RepeatRegisterImm(void (Ass::*f)(Reg, const Imm&), size_t imm_bytes,
                                   std::string fmt) {
     const std::vector<Reg*> registers = GetRegisters();
     std::string str;
     std::vector<int64_t> imms = CreateImmediateValues(imm_bytes);
+
+    WarnOnCombinations(registers.size() * imms.size());
+
     for (auto reg : registers) {
       for (int64_t imm : imms) {
         Imm new_imm = CreateImmediate(imm);
@@ -547,7 +571,7 @@
 
   // Compile the assembly file from_file to a binary file to_file. Returns true on success.
   bool Assemble(const char* from_file, const char* to_file, std::string* error_msg) {
-    bool have_assembler = FileExists(GetAssemblerCommand());
+    bool have_assembler = FileExists(FindTool(GetAssemblerCmdName()));
     EXPECT_TRUE(have_assembler) << "Cannot find assembler:" << GetAssemblerCommand();
     if (!have_assembler) {
       return false;
@@ -569,13 +593,20 @@
     args.push_back("-c");
     args.push_back(cmd);
 
-    return Exec(args, error_msg);
+    bool success = Exec(args, error_msg);
+    if (!success) {
+      LOG(INFO) << "Assembler command line:";
+      for (std::string arg : args) {
+        LOG(INFO) << arg;
+      }
+    }
+    return success;
   }
 
   // Runs objdump -h on the binary file and extracts the first line with .text.
   // Returns "" on failure.
   std::string Objdump(std::string file) {
-    bool have_objdump = FileExists(GetObjdumpCommand());
+    bool have_objdump = FileExists(FindTool(GetObjdumpCmdName()));
     EXPECT_TRUE(have_objdump) << "Cannot find objdump: " << GetObjdumpCommand();
     if (!have_objdump) {
       return "";
@@ -652,10 +683,10 @@
 
     // If you want to take a look at the differences between the ART assembler and GCC, comment
     // out the removal code.
-    std::remove(data_name.c_str());
-    std::remove(as_name.c_str());
-    std::remove((data_name + ".dis").c_str());
-    std::remove((as_name + ".dis").c_str());
+//    std::remove(data_name.c_str());
+//    std::remove(as_name.c_str());
+//    std::remove((data_name + ".dis").c_str());
+//    std::remove((as_name + ".dis").c_str());
 
     return result;
   }
@@ -714,6 +745,10 @@
     // TODO: Lots of error checking.
 
     std::ofstream s_out(res->base_name + ".S");
+    const char* header = GetAssemblyHeader();
+    if (header != nullptr) {
+      s_out << header;
+    }
     s_out << assembly_code;
     s_out.close();
 
@@ -862,13 +897,9 @@
     return tmpnam_;
   }
 
+  static constexpr size_t kWarnManyCombinationsThreshold = 500;
   static constexpr size_t OBJDUMP_SECTION_LINE_MIN_TOKENS = 6;
 
-  static constexpr const char* REG_TOKEN = "{reg}";
-  static constexpr const char* REG1_TOKEN = "{reg1}";
-  static constexpr const char* REG2_TOKEN = "{reg2}";
-  static constexpr const char* IMM_TOKEN = "{imm}";
-
   std::unique_ptr<Ass> assembler_;
 
   std::string resolved_assembler_cmd_;
