ART: Enables x86_64 disassembly

This patch
  (a) cuts a REX prefix from the instruction and
  (b) adds missed 32bit disp to instructions with ModR/M and SIB bytes.

Change-Id: I2674678224ca27746b33d4006ed38d497972309f
Signed-off-by: Vladimir Kostyukov <vladimir.kostyukov@intel.com>
diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc
index 1b96a2b..5cc6acf 100644
--- a/disassembler/disassembler_x86.cc
+++ b/disassembler/disassembler_x86.cc
@@ -145,6 +145,9 @@
     }
   } while (have_prefixes);
   uint8_t rex = (supports_rex_ && (*instr >= 0x40) && (*instr <= 0x4F)) ? *instr : 0;
+  if (rex != 0) {
+    instr++;
+  }
   bool has_modrm = false;
   bool reg_is_opcode = false;
   size_t immediate_bytes = 0;
@@ -746,14 +749,18 @@
     uint8_t reg_or_opcode = (modrm >> 3) & 7;
     uint8_t rm = modrm & 7;
     std::ostringstream address;
-    if (mod == 0 && rm == 5) {  // fixed address
-      address_bits = *reinterpret_cast<const uint32_t*>(instr);
-      address << StringPrintf("[0x%x]", address_bits);
+    if (mod == 0 && rm == 5) {
+      if (!supports_rex_) {  // Absolute address.
+        address_bits = *reinterpret_cast<const uint32_t*>(instr);
+        address << StringPrintf("[0x%x]", address_bits);
+      } else {  // 64-bit RIP relative addressing.
+        address << StringPrintf("[RIP + 0x%x]",  *reinterpret_cast<const uint32_t*>(instr));
+      }
       instr += 4;
     } else if (rm == 4 && mod != 3) {  // SIB
       uint8_t sib = *instr;
       instr++;
-      uint8_t ss = (sib >> 6) & 3;
+      uint8_t scale = (sib >> 6) & 3;
       uint8_t index = (sib >> 3) & 7;
       uint8_t base = sib & 7;
       address << "[";
@@ -765,11 +772,22 @@
       }
       if (index != 4) {
         DumpIndexReg(address, rex, index);
-        if (ss != 0) {
-          address << StringPrintf(" * %d", 1 << ss);
+        if (scale != 0) {
+          address << StringPrintf(" * %d", 1 << scale);
         }
       }
-      if (mod == 1) {
+      if (mod == 0) {
+        if (base == 5) {
+          if (index != 4) {
+            address << StringPrintf(" + %d", *reinterpret_cast<const int32_t*>(instr));
+          } else {
+            // 64-bit low 32-bit absolute address, redundant absolute address encoding on 32-bit.
+            address_bits = *reinterpret_cast<const uint32_t*>(instr);
+            address << StringPrintf("%d", address_bits);
+          }
+          instr += 4;
+        }
+      } else if (mod == 1) {
         address << StringPrintf(" + %d", *reinterpret_cast<const int8_t*>(instr));
         instr++;
       } else if (mod == 2) {