MIPS32R2: Enable table-based switch in presence of irreducible loops

Test: test-art-host-gtest
Test: booted MIPS32R2 in QEMU
Test: testrunner.py --target --optimizing --32
Test: repeat all of the above with suppressed generation
      of HMipsPackedSwitch

Change-Id: Ic8a27d88cd2d7eebaf5826ce8fd1a5607a024844
diff --git a/compiler/utils/mips/assembler_mips_test.cc b/compiler/utils/mips/assembler_mips_test.cc
index eed83a5..9397be4 100644
--- a/compiler/utils/mips/assembler_mips_test.cc
+++ b/compiler/utils/mips/assembler_mips_test.cc
@@ -2913,6 +2913,46 @@
   DriverStr(expected, "LoadNearestFarLabelAddress");
 }
 
+TEST_F(AssemblerMIPSTest, LoadFarthestNearLabelAddressUsingNal) {
+  mips::MipsLabel label;
+  __ LoadLabelAddress(mips::V0, mips::ZERO, &label);
+  constexpr size_t kAddiuCount = 0x1FDE;
+  for (size_t i = 0; i != kAddiuCount; ++i) {
+    __ Addiu(mips::A0, mips::A1, 0);
+  }
+  __ Bind(&label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bltzal $zero, .+4\n"
+      "addiu $v0, $ra, %lo(2f - 1f)\n"
+      "1:\n" +
+      RepeatInsn(kAddiuCount, "addiu $a0, $a1, %hi(2f - 1b)\n") +
+      "2:\n";
+  DriverStr(expected, "LoadFarthestNearLabelAddressUsingNal");
+}
+
+TEST_F(AssemblerMIPSTest, LoadNearestFarLabelAddressUsingNal) {
+  mips::MipsLabel label;
+  __ LoadLabelAddress(mips::V0, mips::ZERO, &label);
+  constexpr size_t kAdduCount = 0x1FDF;
+  for (size_t i = 0; i != kAdduCount; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+  __ Bind(&label);
+
+  std::string expected =
+      ".set noreorder\n"
+      "bltzal $zero, .+4\n"
+      "lui $at, %hi(2f - 1f)\n"
+      "1:\n"
+      "ori $at, $at, %lo(2f - 1b)\n"
+      "addu $v0, $at, $ra\n" +
+      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
+      "2:\n";
+  DriverStr(expected, "LoadNearestFarLabelAddressUsingNal");
+}
+
 TEST_F(AssemblerMIPSTest, LoadFarthestNearLiteral) {
   mips::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
   __ BindPcRelBaseLabel();
@@ -2951,6 +2991,46 @@
   DriverStr(expected, "LoadNearestFarLiteral");
 }
 
+TEST_F(AssemblerMIPSTest, LoadFarthestNearLiteralUsingNal) {
+  mips::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
+  __ LoadLiteral(mips::V0, mips::ZERO, literal);
+  constexpr size_t kAddiuCount = 0x1FDE;
+  for (size_t i = 0; i != kAddiuCount; ++i) {
+    __ Addiu(mips::A0, mips::A1, 0);
+  }
+
+  std::string expected =
+      ".set noreorder\n"
+      "bltzal $zero, .+4\n"
+      "lw $v0, %lo(2f - 1f)($ra)\n"
+      "1:\n" +
+      RepeatInsn(kAddiuCount, "addiu $a0, $a1, %hi(2f - 1b)\n") +
+      "2:\n"
+      ".word 0x12345678\n";
+  DriverStr(expected, "LoadFarthestNearLiteralUsingNal");
+}
+
+TEST_F(AssemblerMIPSTest, LoadNearestFarLiteralUsingNal) {
+  mips::Literal* literal = __ NewLiteral<uint32_t>(0x12345678);
+  __ LoadLiteral(mips::V0, mips::ZERO, literal);
+  constexpr size_t kAdduCount = 0x1FDF;
+  for (size_t i = 0; i != kAdduCount; ++i) {
+    __ Addu(mips::ZERO, mips::ZERO, mips::ZERO);
+  }
+
+  std::string expected =
+      ".set noreorder\n"
+      "bltzal $zero, .+4\n"
+      "lui $at, %hi(2f - 1f)\n"
+      "1:\n"
+      "addu $at, $at, $ra\n"
+      "lw $v0, %lo(2f - 1b)($at)\n" +
+      RepeatInsn(kAdduCount, "addu $zero, $zero, $zero\n") +
+      "2:\n"
+      ".word 0x12345678\n";
+  DriverStr(expected, "LoadNearestFarLiteralUsingNal");
+}
+
 #undef __
 
 }  // namespace art