MIPS: Print register names instead of register numbers in disassembler

Test: ./testrunner.py --optimizing --target on CI20 and in QEMU
Test: mma test-art-host-gtest

Change-Id: I1fc375ae34ee8fd994192705c45d8f30a35dfc56
diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc
index 91203cb..7cb216e 100644
--- a/disassembler/disassembler_mips.cc
+++ b/disassembler/disassembler_mips.cc
@@ -40,6 +40,20 @@
   }
 };
 
+static const char* gO32AbiRegNames[]  = {
+  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+  "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+};
+
+static const char* gN64AbiRegNames[]  = {
+  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+  "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
+  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+  "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
+};
+
 static const uint32_t kOpcodeShift = 26;
 
 static const uint32_t kCop1 = (17 << kOpcodeShift);
@@ -470,6 +484,14 @@
   return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
 }
 
+const char* DisassemblerMips::RegName(uint32_t reg) {
+  if (is_o32_abi_) {
+    return gO32AbiRegNames[reg];
+  } else {
+    return gN64AbiRegNames[reg];
+  }
+}
+
 size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) {
   uint32_t instruction = ReadU32(instr_ptr);
 
@@ -518,7 +540,7 @@
           case 'c':  // Floating-point condition code flag in bc1f/bc1t and movf/movt.
             args << "cc" << (rt >> 2);
             break;
-          case 'D': args << 'r' << rd; break;
+          case 'D': args << RegName(rd); break;
           case 'd': args << 'f' << rd; break;
           case 'a': args << 'f' << sa; break;
           case 'F': args << (sa + 32); break;  // dinsu position.
@@ -553,13 +575,13 @@
           case 'l':  // 9-bit signed offset
             {
               int32_t offset = static_cast<int16_t>(instruction) >> 7;
-              args << StringPrintf("%+d(r%d)", offset, rs);
+              args << StringPrintf("%+d(%s)", offset, RegName(rs));
             }
             break;
           case 'O':  // +x(rs)
             {
               int32_t offset = static_cast<int16_t>(instruction & 0xffff);
-              args << StringPrintf("%+d(r%d)", offset, rs);
+              args << StringPrintf("%+d(%s)", offset, RegName(rs));
               if (rs == 17) {
                 args << "  ; ";
                 GetDisassemblerOptions()->thread_offset_name_function_(args, offset);
@@ -595,13 +617,13 @@
           case 'p':  // 19-bit offset in addiupc.
             {
               int32_t offset = (instruction & 0x7ffff) - ((instruction & 0x40000) << 1);
-              args << offset << "  ; move r" << rs << ", ";
+              args << offset << "  ; move " << RegName(rs) << ", ";
               args << FormatInstructionPointer(instr_ptr + (offset << 2));
             }
             break;
-          case 'S': args << 'r' << rs; break;
+          case 'S': args << RegName(rs); break;
           case 's': args << 'f' << rs; break;
-          case 'T': args << 'r' << rt; break;
+          case 'T': args << RegName(rt); break;
           case 't': args << 'f' << rt; break;
           case 'Z': args << (rd + 1); break;  // sz ([d]ext size).
           case 'z': args << (rd - sa + 1); break;  // sz ([d]ins, dinsu size).
@@ -683,7 +705,7 @@
                 case 2: opcode += ".w"; break;
                 case 3: opcode += ".d"; break;
               }
-              args << StringPrintf("%+d(r%d)", s10 << df, rd);
+              args << StringPrintf("%+d(%s)", s10 << df, RegName(rd));
               break;
             }
           case 'X':  // MSA df/n - ws[x].