MIPS: Assemblers changes needed for optimizing compiler

Also add assembler tests for MIPS32.

Change-Id: I3ab1fba7f3b06eb3b5058861946d675494a30775
diff --git a/compiler/utils/mips/assembler_mips_test.cc b/compiler/utils/mips/assembler_mips_test.cc
new file mode 100644
index 0000000..063d8bd
--- /dev/null
+++ b/compiler/utils/mips/assembler_mips_test.cc
@@ -0,0 +1,1324 @@
+/*
+ * Copyright (C) 2015 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_mips.h"
+
+#include <map>
+
+#include "base/stl_util.h"
+#include "utils/assembler_test.h"
+
+namespace art {
+
+struct MIPSCpuRegisterCompare {
+  bool operator()(const mips::Register& a, const mips::Register& b) const {
+    return a < b;
+  }
+};
+
+class AssemblerMIPSTest : public AssemblerTest<mips::MipsAssembler,
+                                               mips::Register,
+                                               mips::FRegister,
+                                               uint32_t> {
+ public:
+  typedef AssemblerTest<mips::MipsAssembler, mips::Register, mips::FRegister, uint32_t> Base;
+
+ protected:
+  // Get the typically used name for this architecture, e.g., aarch64, x86-64, ...
+  std::string GetArchitectureString() OVERRIDE {
+    return "mips";
+  }
+
+  std::string GetAssemblerParameters() OVERRIDE {
+    return " --no-warn -32 -march=mips32r2";
+  }
+
+  std::string GetDisassembleParameters() OVERRIDE {
+    return " -D -bbinary -mmips:isa32r2";
+  }
+
+  void SetUpHelpers() OVERRIDE {
+    if (registers_.size() == 0) {
+      registers_.push_back(new mips::Register(mips::ZERO));
+      registers_.push_back(new mips::Register(mips::AT));
+      registers_.push_back(new mips::Register(mips::V0));
+      registers_.push_back(new mips::Register(mips::V1));
+      registers_.push_back(new mips::Register(mips::A0));
+      registers_.push_back(new mips::Register(mips::A1));
+      registers_.push_back(new mips::Register(mips::A2));
+      registers_.push_back(new mips::Register(mips::A3));
+      registers_.push_back(new mips::Register(mips::T0));
+      registers_.push_back(new mips::Register(mips::T1));
+      registers_.push_back(new mips::Register(mips::T2));
+      registers_.push_back(new mips::Register(mips::T3));
+      registers_.push_back(new mips::Register(mips::T4));
+      registers_.push_back(new mips::Register(mips::T5));
+      registers_.push_back(new mips::Register(mips::T6));
+      registers_.push_back(new mips::Register(mips::T7));
+      registers_.push_back(new mips::Register(mips::S0));
+      registers_.push_back(new mips::Register(mips::S1));
+      registers_.push_back(new mips::Register(mips::S2));
+      registers_.push_back(new mips::Register(mips::S3));
+      registers_.push_back(new mips::Register(mips::S4));
+      registers_.push_back(new mips::Register(mips::S5));
+      registers_.push_back(new mips::Register(mips::S6));
+      registers_.push_back(new mips::Register(mips::S7));
+      registers_.push_back(new mips::Register(mips::T8));
+      registers_.push_back(new mips::Register(mips::T9));
+      registers_.push_back(new mips::Register(mips::K0));
+      registers_.push_back(new mips::Register(mips::K1));
+      registers_.push_back(new mips::Register(mips::GP));
+      registers_.push_back(new mips::Register(mips::SP));
+      registers_.push_back(new mips::Register(mips::FP));
+      registers_.push_back(new mips::Register(mips::RA));
+
+      secondary_register_names_.emplace(mips::Register(mips::ZERO), "zero");
+      secondary_register_names_.emplace(mips::Register(mips::AT), "at");
+      secondary_register_names_.emplace(mips::Register(mips::V0), "v0");
+      secondary_register_names_.emplace(mips::Register(mips::V1), "v1");
+      secondary_register_names_.emplace(mips::Register(mips::A0), "a0");
+      secondary_register_names_.emplace(mips::Register(mips::A1), "a1");
+      secondary_register_names_.emplace(mips::Register(mips::A2), "a2");
+      secondary_register_names_.emplace(mips::Register(mips::A3), "a3");
+      secondary_register_names_.emplace(mips::Register(mips::T0), "t0");
+      secondary_register_names_.emplace(mips::Register(mips::T1), "t1");
+      secondary_register_names_.emplace(mips::Register(mips::T2), "t2");
+      secondary_register_names_.emplace(mips::Register(mips::T3), "t3");
+      secondary_register_names_.emplace(mips::Register(mips::T4), "t4");
+      secondary_register_names_.emplace(mips::Register(mips::T5), "t5");
+      secondary_register_names_.emplace(mips::Register(mips::T6), "t6");
+      secondary_register_names_.emplace(mips::Register(mips::T7), "t7");
+      secondary_register_names_.emplace(mips::Register(mips::S0), "s0");
+      secondary_register_names_.emplace(mips::Register(mips::S1), "s1");
+      secondary_register_names_.emplace(mips::Register(mips::S2), "s2");
+      secondary_register_names_.emplace(mips::Register(mips::S3), "s3");
+      secondary_register_names_.emplace(mips::Register(mips::S4), "s4");
+      secondary_register_names_.emplace(mips::Register(mips::S5), "s5");
+      secondary_register_names_.emplace(mips::Register(mips::S6), "s6");
+      secondary_register_names_.emplace(mips::Register(mips::S7), "s7");
+      secondary_register_names_.emplace(mips::Register(mips::T8), "t8");
+      secondary_register_names_.emplace(mips::Register(mips::T9), "t9");
+      secondary_register_names_.emplace(mips::Register(mips::K0), "k0");
+      secondary_register_names_.emplace(mips::Register(mips::K1), "k1");
+      secondary_register_names_.emplace(mips::Register(mips::GP), "gp");
+      secondary_register_names_.emplace(mips::Register(mips::SP), "sp");
+      secondary_register_names_.emplace(mips::Register(mips::FP), "fp");
+      secondary_register_names_.emplace(mips::Register(mips::RA), "ra");
+
+      fp_registers_.push_back(new mips::FRegister(mips::F0));
+      fp_registers_.push_back(new mips::FRegister(mips::F1));
+      fp_registers_.push_back(new mips::FRegister(mips::F2));
+      fp_registers_.push_back(new mips::FRegister(mips::F3));
+      fp_registers_.push_back(new mips::FRegister(mips::F4));
+      fp_registers_.push_back(new mips::FRegister(mips::F5));
+      fp_registers_.push_back(new mips::FRegister(mips::F6));
+      fp_registers_.push_back(new mips::FRegister(mips::F7));
+      fp_registers_.push_back(new mips::FRegister(mips::F8));
+      fp_registers_.push_back(new mips::FRegister(mips::F9));
+      fp_registers_.push_back(new mips::FRegister(mips::F10));
+      fp_registers_.push_back(new mips::FRegister(mips::F11));
+      fp_registers_.push_back(new mips::FRegister(mips::F12));
+      fp_registers_.push_back(new mips::FRegister(mips::F13));
+      fp_registers_.push_back(new mips::FRegister(mips::F14));
+      fp_registers_.push_back(new mips::FRegister(mips::F15));
+      fp_registers_.push_back(new mips::FRegister(mips::F16));
+      fp_registers_.push_back(new mips::FRegister(mips::F17));
+      fp_registers_.push_back(new mips::FRegister(mips::F18));
+      fp_registers_.push_back(new mips::FRegister(mips::F19));
+      fp_registers_.push_back(new mips::FRegister(mips::F20));
+      fp_registers_.push_back(new mips::FRegister(mips::F21));
+      fp_registers_.push_back(new mips::FRegister(mips::F22));
+      fp_registers_.push_back(new mips::FRegister(mips::F23));
+      fp_registers_.push_back(new mips::FRegister(mips::F24));
+      fp_registers_.push_back(new mips::FRegister(mips::F25));
+      fp_registers_.push_back(new mips::FRegister(mips::F26));
+      fp_registers_.push_back(new mips::FRegister(mips::F27));
+      fp_registers_.push_back(new mips::FRegister(mips::F28));
+      fp_registers_.push_back(new mips::FRegister(mips::F29));
+      fp_registers_.push_back(new mips::FRegister(mips::F30));
+      fp_registers_.push_back(new mips::FRegister(mips::F31));
+    }
+  }
+
+  void TearDown() OVERRIDE {
+    AssemblerTest::TearDown();
+    STLDeleteElements(&registers_);
+    STLDeleteElements(&fp_registers_);
+  }
+
+  std::vector<mips::Register*> GetRegisters() OVERRIDE {
+    return registers_;
+  }
+
+  std::vector<mips::FRegister*> GetFPRegisters() OVERRIDE {
+    return fp_registers_;
+  }
+
+  uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
+    return imm_value;
+  }
+
+  std::string GetSecondaryRegisterName(const mips::Register& reg) OVERRIDE {
+    CHECK(secondary_register_names_.find(reg) != secondary_register_names_.end());
+    return secondary_register_names_[reg];
+  }
+
+  std::string RepeatInsn(size_t count, const std::string& insn) {
+    std::string result;
+    for (; count != 0u; --count) {
+      result += insn;
+    }
+    return result;
+  }
+
+ private:
+  std::vector<mips::Register*> registers_;
+  std::map<mips::Register, std::string, MIPSCpuRegisterCompare> secondary_register_names_;
+
+  std::vector<mips::FRegister*> fp_registers_;
+};
+
+
+TEST_F(AssemblerMIPSTest, Toolchain) {
+  EXPECT_TRUE(CheckTools());
+}
+
+#define __ GetAssembler()->
+
+TEST_F(AssemblerMIPSTest, Addu) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Addu, "addu ${reg1}, ${reg2}, ${reg3}"), "Addu");
+}
+
+TEST_F(AssemblerMIPSTest, Addiu) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Addiu, -16, "addiu ${reg1}, ${reg2}, {imm}"), "Addiu");
+}
+
+TEST_F(AssemblerMIPSTest, Subu) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Subu, "subu ${reg1}, ${reg2}, ${reg3}"), "Subu");
+}
+
+TEST_F(AssemblerMIPSTest, MultR2) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::MultR2, "mult ${reg1}, ${reg2}"), "MultR2");
+}
+
+TEST_F(AssemblerMIPSTest, MultuR2) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::MultuR2, "multu ${reg1}, ${reg2}"), "MultuR2");
+}
+
+TEST_F(AssemblerMIPSTest, DivR2Basic) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::DivR2, "div $zero, ${reg1}, ${reg2}"), "DivR2Basic");
+}
+
+TEST_F(AssemblerMIPSTest, DivuR2Basic) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::DivuR2, "divu $zero, ${reg1}, ${reg2}"), "DivuR2Basic");
+}
+
+TEST_F(AssemblerMIPSTest, MulR2) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::MulR2, "mul ${reg1}, ${reg2}, ${reg3}"), "MulR2");
+}
+
+TEST_F(AssemblerMIPSTest, DivR2) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::DivR2, "div $zero, ${reg2}, ${reg3}\nmflo ${reg1}"),
+            "DivR2");
+}
+
+TEST_F(AssemblerMIPSTest, ModR2) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::ModR2, "div $zero, ${reg2}, ${reg3}\nmfhi ${reg1}"),
+            "ModR2");
+}
+
+TEST_F(AssemblerMIPSTest, DivuR2) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::DivuR2, "divu $zero, ${reg2}, ${reg3}\nmflo ${reg1}"),
+            "DivuR2");
+}
+
+TEST_F(AssemblerMIPSTest, ModuR2) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::ModuR2, "divu $zero, ${reg2}, ${reg3}\nmfhi ${reg1}"),
+            "ModuR2");
+}
+
+TEST_F(AssemblerMIPSTest, And) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::And, "and ${reg1}, ${reg2}, ${reg3}"), "And");
+}
+
+TEST_F(AssemblerMIPSTest, Andi) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Andi, 16, "andi ${reg1}, ${reg2}, {imm}"), "Andi");
+}
+
+TEST_F(AssemblerMIPSTest, Or) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Or, "or ${reg1}, ${reg2}, ${reg3}"), "Or");
+}
+
+TEST_F(AssemblerMIPSTest, Ori) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Ori, 16, "ori ${reg1}, ${reg2}, {imm}"), "Ori");
+}
+
+TEST_F(AssemblerMIPSTest, Xor) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Xor, "xor ${reg1}, ${reg2}, ${reg3}"), "Xor");
+}
+
+TEST_F(AssemblerMIPSTest, Xori) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Xori, 16, "xori ${reg1}, ${reg2}, {imm}"), "Xori");
+}
+
+TEST_F(AssemblerMIPSTest, Nor) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Nor, "nor ${reg1}, ${reg2}, ${reg3}"), "Nor");
+}
+
+TEST_F(AssemblerMIPSTest, Seb) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::Seb, "seb ${reg1}, ${reg2}"), "Seb");
+}
+
+TEST_F(AssemblerMIPSTest, Seh) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::Seh, "seh ${reg1}, ${reg2}"), "Seh");
+}
+
+TEST_F(AssemblerMIPSTest, Sll) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sll, 5, "sll ${reg1}, ${reg2}, {imm}"), "Sll");
+}
+
+TEST_F(AssemblerMIPSTest, Srl) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Srl, 5, "srl ${reg1}, ${reg2}, {imm}"), "Srl");
+}
+
+TEST_F(AssemblerMIPSTest, Sra) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sra, 5, "sra ${reg1}, ${reg2}, {imm}"), "Sra");
+}
+
+TEST_F(AssemblerMIPSTest, Sllv) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Sllv, "sllv ${reg1}, ${reg2}, ${reg3}"), "Sllv");
+}
+
+TEST_F(AssemblerMIPSTest, Srlv) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Srlv, "srlv ${reg1}, ${reg2}, ${reg3}"), "Srlv");
+}
+
+TEST_F(AssemblerMIPSTest, Srav) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Srav, "srav ${reg1}, ${reg2}, ${reg3}"), "Srav");
+}
+
+TEST_F(AssemblerMIPSTest, Lb) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lb, -16, "lb ${reg1}, {imm}(${reg2})"), "Lb");
+}
+
+TEST_F(AssemblerMIPSTest, Lh) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lh, -16, "lh ${reg1}, {imm}(${reg2})"), "Lh");
+}
+
+TEST_F(AssemblerMIPSTest, Lw) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lw, -16, "lw ${reg1}, {imm}(${reg2})"), "Lw");
+}
+
+TEST_F(AssemblerMIPSTest, Lbu) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lbu, -16, "lbu ${reg1}, {imm}(${reg2})"), "Lbu");
+}
+
+TEST_F(AssemblerMIPSTest, Lhu) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Lhu, -16, "lhu ${reg1}, {imm}(${reg2})"), "Lhu");
+}
+
+TEST_F(AssemblerMIPSTest, Lui) {
+  DriverStr(RepeatRIb(&mips::MipsAssembler::Lui, 16, "lui ${reg}, {imm}"), "Lui");
+}
+
+TEST_F(AssemblerMIPSTest, Mfhi) {
+  DriverStr(RepeatR(&mips::MipsAssembler::Mfhi, "mfhi ${reg}"), "Mfhi");
+}
+
+TEST_F(AssemblerMIPSTest, Mflo) {
+  DriverStr(RepeatR(&mips::MipsAssembler::Mflo, "mflo ${reg}"), "Mflo");
+}
+
+TEST_F(AssemblerMIPSTest, Sb) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sb, -16, "sb ${reg1}, {imm}(${reg2})"), "Sb");
+}
+
+TEST_F(AssemblerMIPSTest, Sh) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sh, -16, "sh ${reg1}, {imm}(${reg2})"), "Sh");
+}
+
+TEST_F(AssemblerMIPSTest, Sw) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sw, -16, "sw ${reg1}, {imm}(${reg2})"), "Sw");
+}
+
+TEST_F(AssemblerMIPSTest, Slt) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Slt, "slt ${reg1}, ${reg2}, ${reg3}"), "Slt");
+}
+
+TEST_F(AssemblerMIPSTest, Sltu) {
+  DriverStr(RepeatRRR(&mips::MipsAssembler::Sltu, "sltu ${reg1}, ${reg2}, ${reg3}"), "Sltu");
+}
+
+TEST_F(AssemblerMIPSTest, Slti) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Slti, -16, "slti ${reg1}, ${reg2}, {imm}"), "Slti");
+}
+
+TEST_F(AssemblerMIPSTest, Sltiu) {
+  DriverStr(RepeatRRIb(&mips::MipsAssembler::Sltiu, -16, "sltiu ${reg1}, ${reg2}, {imm}"), "Sltiu");
+}
+
+TEST_F(AssemblerMIPSTest, AddS) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::AddS, "add.s ${reg1}, ${reg2}, ${reg3}"), "AddS");
+}
+
+TEST_F(AssemblerMIPSTest, AddD) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::AddD, "add.d ${reg1}, ${reg2}, ${reg3}"), "AddD");
+}
+
+TEST_F(AssemblerMIPSTest, SubS) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::SubS, "sub.s ${reg1}, ${reg2}, ${reg3}"), "SubS");
+}
+
+TEST_F(AssemblerMIPSTest, SubD) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::SubD, "sub.d ${reg1}, ${reg2}, ${reg3}"), "SubD");
+}
+
+TEST_F(AssemblerMIPSTest, MulS) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::MulS, "mul.s ${reg1}, ${reg2}, ${reg3}"), "MulS");
+}
+
+TEST_F(AssemblerMIPSTest, MulD) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::MulD, "mul.d ${reg1}, ${reg2}, ${reg3}"), "MulD");
+}
+
+TEST_F(AssemblerMIPSTest, DivS) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::DivS, "div.s ${reg1}, ${reg2}, ${reg3}"), "DivS");
+}
+
+TEST_F(AssemblerMIPSTest, DivD) {
+  DriverStr(RepeatFFF(&mips::MipsAssembler::DivD, "div.d ${reg1}, ${reg2}, ${reg3}"), "DivD");
+}
+
+TEST_F(AssemblerMIPSTest, MovS) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::MovS, "mov.s ${reg1}, ${reg2}"), "MovS");
+}
+
+TEST_F(AssemblerMIPSTest, MovD) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::MovD, "mov.d ${reg1}, ${reg2}"), "MovD");
+}
+
+TEST_F(AssemblerMIPSTest, NegS) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::NegS, "neg.s ${reg1}, ${reg2}"), "NegS");
+}
+
+TEST_F(AssemblerMIPSTest, NegD) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::NegD, "neg.d ${reg1}, ${reg2}"), "NegD");
+}
+
+TEST_F(AssemblerMIPSTest, CvtSW) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsw, "cvt.s.w ${reg1}, ${reg2}"), "CvtSW");
+}
+
+TEST_F(AssemblerMIPSTest, CvtDW) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtdw, "cvt.d.w ${reg1}, ${reg2}"), "CvtDW");
+}
+
+TEST_F(AssemblerMIPSTest, CvtSD) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtsd, "cvt.s.d ${reg1}, ${reg2}"), "CvtSD");
+}
+
+TEST_F(AssemblerMIPSTest, CvtDS) {
+  DriverStr(RepeatFF(&mips::MipsAssembler::Cvtds, "cvt.d.s ${reg1}, ${reg2}"), "CvtDS");
+}
+
+TEST_F(AssemblerMIPSTest, Mfc1) {
+  DriverStr(RepeatRF(&mips::MipsAssembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1");
+}
+
+TEST_F(AssemblerMIPSTest, Mtc1) {
+  DriverStr(RepeatRF(&mips::MipsAssembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1");
+}
+
+TEST_F(AssemblerMIPSTest, Mfhc1) {
+  DriverStr(RepeatRF(&mips::MipsAssembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1");
+}
+
+TEST_F(AssemblerMIPSTest, Mthc1) {
+  DriverStr(RepeatRF(&mips::MipsAssembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1");
+}
+
+TEST_F(AssemblerMIPSTest, Lwc1) {
+  DriverStr(RepeatFRIb(&mips::MipsAssembler::Lwc1, -16, "lwc1 ${reg1}, {imm}(${reg2})"), "Lwc1");
+}
+
+TEST_F(AssemblerMIPSTest, Ldc1) {
+  DriverStr(RepeatFRIb(&mips::MipsAssembler::Ldc1, -16, "ldc1 ${reg1}, {imm}(${reg2})"), "Ldc1");
+}
+
+TEST_F(AssemblerMIPSTest, Swc1) {
+  DriverStr(RepeatFRIb(&mips::MipsAssembler::Swc1, -16, "swc1 ${reg1}, {imm}(${reg2})"), "Swc1");
+}
+
+TEST_F(AssemblerMIPSTest, Sdc1) {
+  DriverStr(RepeatFRIb(&mips::MipsAssembler::Sdc1, -16, "sdc1 ${reg1}, {imm}(${reg2})"), "Sdc1");
+}
+
+TEST_F(AssemblerMIPSTest, Move) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::Move, "or ${reg1}, ${reg2}, $zero"), "Move");
+}
+
+TEST_F(AssemblerMIPSTest, Clear) {
+  DriverStr(RepeatR(&mips::MipsAssembler::Clear, "or ${reg}, $zero, $zero"), "Clear");
+}
+
+TEST_F(AssemblerMIPSTest, Not) {
+  DriverStr(RepeatRR(&mips::MipsAssembler::Not, "nor ${reg1}, ${reg2}, $zero"), "Not");
+}
+
+TEST_F(AssemblerMIPSTest, LoadFromOffset) {
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 256);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 1000);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x8000);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x10000);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0x12345678);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, -256);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadSignedByte, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 256);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 1000);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x8000);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x10000);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0x12345678);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, -256);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadUnsignedByte, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 256);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 1000);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x8000);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x10000);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0x12345678);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, -256);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadSignedHalfword, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 256);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 1000);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x8000);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x10000);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0x12345678);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, -256);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadUnsignedHalfword, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 256);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 1000);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x8000);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x10000);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0x12345678);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, -256);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadWord, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A1, 0);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A1, mips::A0, 0);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 256);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 1000);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x8000);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x10000);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0x12345678);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, -256);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0xFFFF8000);
+  __ LoadFromOffset(mips::kLoadDoubleword, mips::A0, mips::A2, 0xABCDEF00);
+
+  const char* expected =
+      "lb $a0, 0($a0)\n"
+      "lb $a0, 0($a1)\n"
+      "lb $a0, 256($a1)\n"
+      "lb $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "lb $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "lb $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "lb $a0, 0($at)\n"
+      "lb $a0, -256($a1)\n"
+      "lb $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "lb $a0, 0($at)\n"
+
+      "lbu $a0, 0($a0)\n"
+      "lbu $a0, 0($a1)\n"
+      "lbu $a0, 256($a1)\n"
+      "lbu $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "lbu $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "lbu $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "lbu $a0, 0($at)\n"
+      "lbu $a0, -256($a1)\n"
+      "lbu $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "lbu $a0, 0($at)\n"
+
+      "lh $a0, 0($a0)\n"
+      "lh $a0, 0($a1)\n"
+      "lh $a0, 256($a1)\n"
+      "lh $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "lh $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "lh $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "lh $a0, 0($at)\n"
+      "lh $a0, -256($a1)\n"
+      "lh $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "lh $a0, 0($at)\n"
+
+      "lhu $a0, 0($a0)\n"
+      "lhu $a0, 0($a1)\n"
+      "lhu $a0, 256($a1)\n"
+      "lhu $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "lhu $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "lhu $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "lhu $a0, 0($at)\n"
+      "lhu $a0, -256($a1)\n"
+      "lhu $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "lhu $a0, 0($at)\n"
+
+      "lw $a0, 0($a0)\n"
+      "lw $a0, 0($a1)\n"
+      "lw $a0, 256($a1)\n"
+      "lw $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "lw $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "lw $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "lw $a0, 0($at)\n"
+      "lw $a0, -256($a1)\n"
+      "lw $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "lw $a0, 0($at)\n"
+
+      "lw $a1, 4($a0)\n"
+      "lw $a0, 0($a0)\n"
+      "lw $a0, 0($a1)\n"
+      "lw $a1, 4($a1)\n"
+      "lw $a1, 0($a0)\n"
+      "lw $a2, 4($a0)\n"
+      "lw $a0, 0($a2)\n"
+      "lw $a1, 4($a2)\n"
+      "lw $a0, 256($a2)\n"
+      "lw $a1, 260($a2)\n"
+      "lw $a0, 1000($a2)\n"
+      "lw $a1, 1004($a2)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a2\n"
+      "lw $a0, 0($at)\n"
+      "lw $a1, 4($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a2\n"
+      "lw $a0, 0($at)\n"
+      "lw $a1, 4($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a2\n"
+      "lw $a0, 0($at)\n"
+      "lw $a1, 4($at)\n"
+      "lw $a0, -256($a2)\n"
+      "lw $a1, -252($a2)\n"
+      "lw $a0, 0xFFFF8000($a2)\n"
+      "lw $a1, 0xFFFF8004($a2)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a2\n"
+      "lw $a0, 0($at)\n"
+      "lw $a1, 4($at)\n";
+  DriverStr(expected, "LoadFromOffset");
+}
+
+TEST_F(AssemblerMIPSTest, LoadSFromOffset) {
+  __ LoadSFromOffset(mips::F0, mips::A0, 0);
+  __ LoadSFromOffset(mips::F0, mips::A0, 4);
+  __ LoadSFromOffset(mips::F0, mips::A0, 256);
+  __ LoadSFromOffset(mips::F0, mips::A0, 0x8000);
+  __ LoadSFromOffset(mips::F0, mips::A0, 0x10000);
+  __ LoadSFromOffset(mips::F0, mips::A0, 0x12345678);
+  __ LoadSFromOffset(mips::F0, mips::A0, -256);
+  __ LoadSFromOffset(mips::F0, mips::A0, 0xFFFF8000);
+  __ LoadSFromOffset(mips::F0, mips::A0, 0xABCDEF00);
+
+  const char* expected =
+      "lwc1 $f0, 0($a0)\n"
+      "lwc1 $f0, 4($a0)\n"
+      "lwc1 $f0, 256($a0)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a0\n"
+      "lwc1 $f0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a0\n"
+      "lwc1 $f0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a0\n"
+      "lwc1 $f0, 0($at)\n"
+      "lwc1 $f0, -256($a0)\n"
+      "lwc1 $f0, 0xFFFF8000($a0)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a0\n"
+      "lwc1 $f0, 0($at)\n";
+  DriverStr(expected, "LoadSFromOffset");
+}
+
+
+TEST_F(AssemblerMIPSTest, LoadDFromOffset) {
+  __ LoadDFromOffset(mips::F0, mips::A0, 0);
+  __ LoadDFromOffset(mips::F0, mips::A0, 4);
+  __ LoadDFromOffset(mips::F0, mips::A0, 256);
+  __ LoadDFromOffset(mips::F0, mips::A0, 0x8000);
+  __ LoadDFromOffset(mips::F0, mips::A0, 0x10000);
+  __ LoadDFromOffset(mips::F0, mips::A0, 0x12345678);
+  __ LoadDFromOffset(mips::F0, mips::A0, -256);
+  __ LoadDFromOffset(mips::F0, mips::A0, 0xFFFF8000);
+  __ LoadDFromOffset(mips::F0, mips::A0, 0xABCDEF00);
+
+  const char* expected =
+      "ldc1 $f0, 0($a0)\n"
+      "lwc1 $f0, 4($a0)\n"
+      "lwc1 $f1, 8($a0)\n"
+      "ldc1 $f0, 256($a0)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a0\n"
+      "ldc1 $f0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a0\n"
+      "ldc1 $f0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a0\n"
+      "ldc1 $f0, 0($at)\n"
+      "ldc1 $f0, -256($a0)\n"
+      "ldc1 $f0, 0xFFFF8000($a0)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a0\n"
+      "ldc1 $f0, 0($at)\n";
+  DriverStr(expected, "LoadDFromOffset");
+}
+
+TEST_F(AssemblerMIPSTest, StoreToOffset) {
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A0, 0);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 256);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 1000);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x8000);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x10000);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0x12345678);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, -256);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0xFFFF8000);
+  __ StoreToOffset(mips::kStoreByte, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A0, 0);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 256);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 1000);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x8000);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x10000);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0x12345678);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, -256);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0xFFFF8000);
+  __ StoreToOffset(mips::kStoreHalfword, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A0, 0);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 256);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 1000);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x8000);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x10000);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0x12345678);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, -256);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0xFFFF8000);
+  __ StoreToOffset(mips::kStoreWord, mips::A0, mips::A1, 0xABCDEF00);
+
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 256);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 1000);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x8000);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x10000);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0x12345678);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, -256);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0xFFFF8000);
+  __ StoreToOffset(mips::kStoreDoubleword, mips::A0, mips::A2, 0xABCDEF00);
+
+  const char* expected =
+      "sb $a0, 0($a0)\n"
+      "sb $a0, 0($a1)\n"
+      "sb $a0, 256($a1)\n"
+      "sb $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "sb $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "sb $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "sb $a0, 0($at)\n"
+      "sb $a0, -256($a1)\n"
+      "sb $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "sb $a0, 0($at)\n"
+
+      "sh $a0, 0($a0)\n"
+      "sh $a0, 0($a1)\n"
+      "sh $a0, 256($a1)\n"
+      "sh $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "sh $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "sh $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "sh $a0, 0($at)\n"
+      "sh $a0, -256($a1)\n"
+      "sh $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "sh $a0, 0($at)\n"
+
+      "sw $a0, 0($a0)\n"
+      "sw $a0, 0($a1)\n"
+      "sw $a0, 256($a1)\n"
+      "sw $a0, 1000($a1)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a1\n"
+      "sw $a0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a1\n"
+      "sw $a0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a1\n"
+      "sw $a0, 0($at)\n"
+      "sw $a0, -256($a1)\n"
+      "sw $a0, 0xFFFF8000($a1)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a1\n"
+      "sw $a0, 0($at)\n"
+
+      "sw $a0, 0($a2)\n"
+      "sw $a1, 4($a2)\n"
+      "sw $a0, 256($a2)\n"
+      "sw $a1, 260($a2)\n"
+      "sw $a0, 1000($a2)\n"
+      "sw $a1, 1004($a2)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a2\n"
+      "sw $a0, 0($at)\n"
+      "sw $a1, 4($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a2\n"
+      "sw $a0, 0($at)\n"
+      "sw $a1, 4($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a2\n"
+      "sw $a0, 0($at)\n"
+      "sw $a1, 4($at)\n"
+      "sw $a0, -256($a2)\n"
+      "sw $a1, -252($a2)\n"
+      "sw $a0, 0xFFFF8000($a2)\n"
+      "sw $a1, 0xFFFF8004($a2)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a2\n"
+      "sw $a0, 0($at)\n"
+      "sw $a1, 4($at)\n";
+  DriverStr(expected, "StoreToOffset");
+}
+
+TEST_F(AssemblerMIPSTest, StoreSToOffset) {
+  __ StoreSToOffset(mips::F0, mips::A0, 0);
+  __ StoreSToOffset(mips::F0, mips::A0, 4);
+  __ StoreSToOffset(mips::F0, mips::A0, 256);
+  __ StoreSToOffset(mips::F0, mips::A0, 0x8000);
+  __ StoreSToOffset(mips::F0, mips::A0, 0x10000);
+  __ StoreSToOffset(mips::F0, mips::A0, 0x12345678);
+  __ StoreSToOffset(mips::F0, mips::A0, -256);
+  __ StoreSToOffset(mips::F0, mips::A0, 0xFFFF8000);
+  __ StoreSToOffset(mips::F0, mips::A0, 0xABCDEF00);
+
+  const char* expected =
+      "swc1 $f0, 0($a0)\n"
+      "swc1 $f0, 4($a0)\n"
+      "swc1 $f0, 256($a0)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a0\n"
+      "swc1 $f0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a0\n"
+      "swc1 $f0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a0\n"
+      "swc1 $f0, 0($at)\n"
+      "swc1 $f0, -256($a0)\n"
+      "swc1 $f0, 0xFFFF8000($a0)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a0\n"
+      "swc1 $f0, 0($at)\n";
+  DriverStr(expected, "StoreSToOffset");
+}
+
+TEST_F(AssemblerMIPSTest, StoreDToOffset) {
+  __ StoreDToOffset(mips::F0, mips::A0, 0);
+  __ StoreDToOffset(mips::F0, mips::A0, 4);
+  __ StoreDToOffset(mips::F0, mips::A0, 256);
+  __ StoreDToOffset(mips::F0, mips::A0, 0x8000);
+  __ StoreDToOffset(mips::F0, mips::A0, 0x10000);
+  __ StoreDToOffset(mips::F0, mips::A0, 0x12345678);
+  __ StoreDToOffset(mips::F0, mips::A0, -256);
+  __ StoreDToOffset(mips::F0, mips::A0, 0xFFFF8000);
+  __ StoreDToOffset(mips::F0, mips::A0, 0xABCDEF00);
+
+  const char* expected =
+      "sdc1 $f0, 0($a0)\n"
+      "swc1 $f0, 4($a0)\n"
+      "swc1 $f1, 8($a0)\n"
+      "sdc1 $f0, 256($a0)\n"
+      "ori $at, $zero, 0x8000\n"
+      "addu $at, $at, $a0\n"
+      "sdc1 $f0, 0($at)\n"
+      "lui $at, 1\n"
+      "addu $at, $at, $a0\n"
+      "sdc1 $f0, 0($at)\n"
+      "lui $at, 0x1234\n"
+      "ori $at, 0x5678\n"
+      "addu $at, $at, $a0\n"
+      "sdc1 $f0, 0($at)\n"
+      "sdc1 $f0, -256($a0)\n"
+      "sdc1 $f0, 0xFFFF8000($a0)\n"
+      "lui $at, 0xABCD\n"
+      "ori $at, 0xEF00\n"
+      "addu $at, $at, $a0\n"
+      "sdc1 $f0, 0($at)\n";
+  DriverStr(expected, "StoreDToOffset");
+}
+
+TEST_F(AssemblerMIPSTest, B) {
+  mips::MipsLabel label1, label2;
+  __ B(&label1);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label1);
+  __ B(&label2);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label2);
+  __ B(&label1);
+
+  std::string expected =
+      ".set noreorder\n"
+      "b 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n"
+      "b 2f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "2:\n"
+      "b 1b\n"
+      "nop\n";
+  DriverStr(expected, "B");
+}
+
+TEST_F(AssemblerMIPSTest, Beq) {
+  mips::MipsLabel label;
+  __ Beq(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Beq(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "beq $a0, $a1, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "beq $a2, $a3, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Beq");
+}
+
+TEST_F(AssemblerMIPSTest, Bne) {
+  mips::MipsLabel label;
+  __ Bne(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bne(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bne $a0, $a1, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "bne $a2, $a3, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bne");
+}
+
+TEST_F(AssemblerMIPSTest, Beqz) {
+  mips::MipsLabel label;
+  __ Beqz(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Beqz(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "beq $zero, $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "beq $zero, $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Beqz");
+}
+
+TEST_F(AssemblerMIPSTest, Bnez) {
+  mips::MipsLabel label;
+  __ Bnez(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bnez(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bne $zero, $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "bne $zero, $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bnez");
+}
+
+TEST_F(AssemblerMIPSTest, Bltz) {
+  mips::MipsLabel label;
+  __ Bltz(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bltz(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bltz $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "bltz $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bltz");
+}
+
+TEST_F(AssemblerMIPSTest, Bgez) {
+  mips::MipsLabel label;
+  __ Bgez(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bgez(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bgez $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "bgez $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bgez");
+}
+
+TEST_F(AssemblerMIPSTest, Blez) {
+  mips::MipsLabel label;
+  __ Blez(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Blez(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "blez $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "blez $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Blez");
+}
+
+TEST_F(AssemblerMIPSTest, Bgtz) {
+  mips::MipsLabel label;
+  __ Bgtz(mips::A0, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bgtz(mips::A1, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bgtz $a0, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "bgtz $a1, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bgtz");
+}
+
+TEST_F(AssemblerMIPSTest, Blt) {
+  mips::MipsLabel label;
+  __ Blt(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Blt(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "slt $at, $a0, $a1\n"
+      "bne $zero, $at, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "slt $at, $a2, $a3\n"
+      "bne $zero, $at, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Blt");
+}
+
+TEST_F(AssemblerMIPSTest, Bge) {
+  mips::MipsLabel label;
+  __ Bge(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bge(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "slt $at, $a0, $a1\n"
+      "beq $zero, $at, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "slt $at, $a2, $a3\n"
+      "beq $zero, $at, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bge");
+}
+
+TEST_F(AssemblerMIPSTest, Bltu) {
+  mips::MipsLabel label;
+  __ Bltu(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bltu(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "sltu $at, $a0, $a1\n"
+      "bne $zero, $at, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "sltu $at, $a2, $a3\n"
+      "bne $zero, $at, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bltu");
+}
+
+TEST_F(AssemblerMIPSTest, Bgeu) {
+  mips::MipsLabel label;
+  __ Bgeu(mips::A0, mips::A1, &label);
+  constexpr size_t kAdduCount1 = 63;
+  for (size_t i = 0; i != kAdduCount1; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+  constexpr size_t kAdduCount2 = 64;
+  for (size_t i = 0; i != kAdduCount2; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bgeu(mips::A2, mips::A3, &label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "sltu $at, $a0, $a1\n"
+      "beq $zero, $at, 1f\n"
+      "nop\n" +
+      RepeatInsn(kAdduCount1, "addu $zero, $zero, $zero\n") +
+      "1:\n" +
+      RepeatInsn(kAdduCount2, "addu $zero, $zero, $zero\n") +
+      "sltu $at, $a2, $a3\n"
+      "beq $zero, $at, 1b\n"
+      "nop\n";
+  DriverStr(expected, "Bgeu");
+}
+
+#undef __
+
+}  // namespace art