Fixes for x86 compiler optimizations.

x86 works with all but a few optimizations turned on, and the broken
ones are still disabled for now. This change includes:

- Flagging of opcodes to incidate register use and def. Also, made
  flagging more complete for loads/stores and set/use ccodes.

- Fixes to load store elimination, though it still doesn't work yet.

- Prevent double values that are loaded or stored from losing their
  FP_DOUBLE flag. Later optimizations use this sizing.

- Renumbering of DOUBLE registers so they alias with FP regs when
  masked.

- Add support in the disassembler to recognize shifts.

Change-Id: I758cdce418409fdd84206ce295005d5c9ab635f8
diff --git a/src/disassembler_x86.cc b/src/disassembler_x86.cc
index dc12ef7..4aff822 100644
--- a/src/disassembler_x86.cc
+++ b/src/disassembler_x86.cc
@@ -145,6 +145,7 @@
   bool load = false;  // loads from memory (ie rm is on the right)
   bool byte_operand = false;
   bool ax = false;  // implicit use of ax
+  bool cx = false;  // implicit use of cx
   bool reg_in_opcode = false;  // low 3-bits of opcode encode register parameter
   RegFile src_reg_file = GPR;
   RegFile dst_reg_file = GPR;
@@ -383,7 +384,7 @@
     reg_in_opcode = true;
     break;
   case 0xC0: case 0xC1:
-  case 0xD0: case 0xD1:
+  case 0xD0: case 0xD1: case 0xD2: case 0xD3:
     static const char* shift_opcodes[] =
         {"rol", "ror", "rcl", "rcr", "shl", "shr", "unknown-shift", "sar"};
     modrm_opcodes = shift_opcodes;
@@ -391,7 +392,8 @@
     reg_is_opcode = true;
     store = true;
     immediate_bytes = ((*instr & 0xf0) == 0xc0) ? 1 : 0;
-    byte_operand = *instr == 0xC0;
+    cx = (*instr == 0xD2) || (*instr == 0xD3);
+    byte_operand = (*instr == 0xC0);
     break;
   case 0xC3: opcode << "ret"; break;
   case 0xC7:
@@ -508,10 +510,15 @@
     }
   }
   if (ax) {
+    args << ", ";
     DumpReg(args, rex, 0 /* EAX */, byte_operand, prefix[2], GPR);
   }
+  if (cx) {
+    args << ", ";
+    DumpReg(args, rex, 1 /* ECX */, true, prefix[2], GPR);
+  }
   if (immediate_bytes > 0) {
-    if (has_modrm || reg_in_opcode || ax) {
+    if (has_modrm || reg_in_opcode || ax || cx) {
       args << ", ";
     }
     if (immediate_bytes == 1) {