Revision: 3141
Author: [email protected]
Date: Tue Oct 27 03:47:01 2009
Log: Add fucomip instruction to disassembler.  Fix some other floating  
point instructions.
Review URL: http://codereview.chromium.org/316010
http://code.google.com/p/v8/source/detail?r=3141

Modified:
  /branches/bleeding_edge/src/ia32/disasm-ia32.cc
  /branches/bleeding_edge/src/x64/disasm-x64.cc

=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Thu Oct  8 06:28:46 2009
+++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Tue Oct 27 03:47:01 2009
@@ -204,7 +204,7 @@
      InstructionDesc* id = &instructions_[bm[i].b];
      id->mnem = bm[i].mnem;
      id->op_order_ = bm[i].op_order_;
-    assert(id->type == NO_INSTR);  // Information already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered.
      id->type = type;
    }
  }
@@ -216,7 +216,7 @@
                                       const char* mnem) {
    for (byte b = start; b <= end; b++) {
      InstructionDesc* id = &instructions_[b];
-    assert(id->type == NO_INSTR);  // Information already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered.
      id->mnem = mnem;
      id->type = type;
    }
@@ -226,7 +226,7 @@
  void InstructionTable::AddJumpConditionalShort() {
    for (byte b = 0x70; b <= 0x7F; b++) {
      InstructionDesc* id = &instructions_[b];
-    assert(id->type == NO_INSTR);  // Information already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered.
      id->mnem = jump_conditional_mnem[b & 0x0F];
      id->type = JUMP_CONDITIONAL_SHORT_INSTR;
    }
@@ -321,6 +321,8 @@
    int SetCC(byte* data);
    int CMov(byte* data);
    int FPUInstruction(byte* data);
+  int MemoryFPUInstruction(int escape_opcode, int regop, byte*  
modrm_start);
+  int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
    void AppendToBuffer(const char* format, ...);


@@ -493,7 +495,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerIA32::F7Instruction(byte* data) {
-  assert(*data == 0xF7);
+  ASSERT_EQ(0xF7, *data);
    byte modrm = *(data+1);
    int mod, regop, rm;
    get_modrm(modrm, &mod, &regop, &rm);
@@ -526,7 +528,7 @@

  int DisassemblerIA32::D1D3C1Instruction(byte* data) {
    byte op = *data;
-  assert(op == 0xD1 || op == 0xD3 || op == 0xC1);
+  ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1);
    byte modrm = *(data+1);
    int mod, regop, rm;
    get_modrm(modrm, &mod, &regop, &rm);
@@ -560,7 +562,7 @@
          default: UnimplementedInstruction();
        }
      }
-    assert(mnem != NULL);
+    ASSERT_NE(NULL, mnem);
      AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm));
      if (imm8 > 0) {
        AppendToBuffer("%d", imm8);
@@ -576,7 +578,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerIA32::JumpShort(byte* data) {
-  assert(*data == 0xEB);
+  ASSERT_EQ(0xEB, *data);
    byte b = *(data+1);
    byte* dest = data + static_cast<int8_t>(b) + 2;
    AppendToBuffer("jmp %s", NameOfAddress(dest));
@@ -586,7 +588,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerIA32::JumpConditional(byte* data, const char* comment) {
-  assert(*data == 0x0F);
+  ASSERT_EQ(0x0F, *data);
    byte cond = *(data+1) & 0x0F;
    byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6;
    const char* mnem = jump_conditional_mnem[cond];
@@ -614,18 +616,18 @@

  // Returns number of bytes used, including *data.
  int DisassemblerIA32::SetCC(byte* data) {
-  assert(*data == 0x0F);
+  ASSERT_EQ(0x0F, *data);
    byte cond = *(data+1) & 0x0F;
    const char* mnem = set_conditional_mnem[cond];
    AppendToBuffer("%s ", mnem);
    PrintRightByteOperand(data+2);
-  return 3;  // includes 0x0F
+  return 3;  // Includes 0x0F.
  }


  // Returns number of bytes used, including *data.
  int DisassemblerIA32::CMov(byte* data) {
-  assert(*data == 0x0F);
+  ASSERT_EQ(0x0F, *data);
    byte cond = *(data + 1) & 0x0F;
    const char* mnem = conditional_move_mnem[cond];
    int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
@@ -635,107 +637,165 @@

  // Returns number of bytes used, including *data.
  int DisassemblerIA32::FPUInstruction(byte* data) {
-  byte b1 = *data;
-  byte b2 = *(data + 1);
-  if (b1 == 0xD9) {
-    const char* mnem = NULL;
-    switch (b2) {
-      case 0xE8: mnem = "fld1"; break;
-      case 0xEE: mnem = "fldz"; break;
-      case 0xE1: mnem = "fabs"; break;
-      case 0xE0: mnem = "fchs"; break;
-      case 0xF8: mnem = "fprem"; break;
-      case 0xF5: mnem = "fprem1"; break;
-      case 0xF7: mnem = "fincstp"; break;
-      case 0xE4: mnem = "ftst"; break;
-    }
-    if (mnem != NULL) {
-      AppendToBuffer("%s", mnem);
-      return 2;
-    } else if ((b2 & 0xF8) == 0xC8) {
-      AppendToBuffer("fxch st%d", b2 & 0x7);
-      return 2;
-    } else {
-      int mod, regop, rm;
-      get_modrm(*(data+1), &mod, &regop, &rm);
-      const char* mnem = "?";
-      switch (regop) {
-        case eax: mnem = "fld_s"; break;
-        case ebx: mnem = "fstp_s"; break;
+  byte escape_opcode = *data;
+  ASSERT_EQ(0xD8, escape_opcode & 0xF8);
+  byte modrm_byte = *(data+1);
+
+  if (modrm_byte >= 0xC0) {
+    return RegisterFPUInstruction(escape_opcode, modrm_byte);
+  } else {
+    return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
+  }
+}
+
+int DisassemblerIA32::MemoryFPUInstruction(int escape_opcode,
+                                           int modrm_byte,
+                                           byte* modrm_start) {
+  const char* mnem = "?";
+  int regop = (modrm_byte >> 3) & 0x7;  // reg/op field of modrm byte.
+  switch (escape_opcode) {
+    case 0xD9: switch (regop) {
+        case 0: mnem = "fld_s"; break;
+        case 3: mnem = "fstp_s"; break;
+        case 7: mnem = "fstcw"; break;
          default: UnimplementedInstruction();
        }
-      AppendToBuffer("%s ", mnem);
-      int count = PrintRightOperand(data + 1);
-      return count + 1;
-    }
-  } else if (b1 == 0xDD) {
-    if ((b2 & 0xF8) == 0xC0) {
-      AppendToBuffer("ffree st%d", b2 & 0x7);
-      return 2;
-    } else {
-      int mod, regop, rm;
-      get_modrm(*(data+1), &mod, &regop, &rm);
-      const char* mnem = "?";
-      switch (regop) {
-        case eax: mnem = "fld_d"; break;
-        case ebx: mnem = "fstp_d"; break;
+      break;
+
+    case 0xDB: switch (regop) {
+        case 0: mnem = "fild_s"; break;
+        case 1: mnem = "fisttp_s"; break;
+        case 2: mnem = "fist_s"; break;
+        case 3: mnem = "fistp_s"; break;
          default: UnimplementedInstruction();
        }
-      AppendToBuffer("%s ", mnem);
-      int count = PrintRightOperand(data + 1);
-      return count + 1;
-    }
-  } else if (b1 == 0xDB) {
-    int mod, regop, rm;
-    get_modrm(*(data+1), &mod, &regop, &rm);
-    const char* mnem = "?";
-    switch (regop) {
-      case eax: mnem = "fild_s"; break;
-      case edx: mnem = "fist_s"; break;
-      case ebx: mnem = "fistp_s"; break;
-      default: UnimplementedInstruction();
-    }
-    AppendToBuffer("%s ", mnem);
-    int count = PrintRightOperand(data + 1);
-    return count + 1;
-  } else if (b1 == 0xDF) {
-    if (b2 == 0xE0) {
-      AppendToBuffer("fnstsw_ax");
-      return 2;
-    }
-    int mod, regop, rm;
-    get_modrm(*(data+1), &mod, &regop, &rm);
-    const char* mnem = "?";
-    switch (regop) {
-      case ebp: mnem = "fild_d"; break;
-      case edi: mnem = "fistp_d"; break;
-      default: UnimplementedInstruction();
-    }
-    AppendToBuffer("%s ", mnem);
-    int count = PrintRightOperand(data + 1);
-    return count + 1;
-  } else if (b1 == 0xDC || b1 == 0xDE) {
-    bool is_pop = (b1 == 0xDE);
-    if (is_pop && b2 == 0xD9) {
-      AppendToBuffer("fcompp");
-      return 2;
-    }
-    const char* mnem = "FP0xDC";
-    switch (b2 & 0xF8) {
-      case 0xC0: mnem = "fadd"; break;
-      case 0xE8: mnem = "fsub"; break;
-      case 0xC8: mnem = "fmul"; break;
-      case 0xF8: mnem = "fdiv"; break;
-      default: UnimplementedInstruction();
-    }
-    AppendToBuffer("%s%s st%d", mnem, is_pop ? "p" : "", b2 & 0x7);
-    return 2;
-  } else if (b1 == 0xDA && b2 == 0xE9) {
-    const char* mnem = "fucompp";
+      break;
+
+    case 0xDD: switch (regop) {
+        case 0: mnem = "fld_d"; break;
+        case 3: mnem = "fstp_d"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDF: switch (regop) {
+        case 5: mnem = "fild_d"; break;
+        case 7: mnem = "fistp_d"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    default: UnimplementedInstruction();
+  }
+  AppendToBuffer("%s ", mnem);
+  int count = PrintRightOperand(modrm_start);
+  return count + 1;
+}
+
+int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
+                                             byte modrm_byte) {
+  bool has_register = false;  // Is the FPU register encoded in modrm_byte?
+  const char* mnem = "?";
+
+  switch (escape_opcode) {
+    case 0xD8:
+      UnimplementedInstruction();
+      break;
+
+    case 0xD9:
+      switch (modrm_byte & 0xF8) {
+        case 0xC8:
+          mnem = "fxch";
+          has_register = true;
+          break;
+        default:
+          switch (modrm_byte) {
+            case 0xE0: mnem = "fchs"; break;
+            case 0xE1: mnem = "fabs"; break;
+            case 0xE4: mnem = "ftst"; break;
+            case 0xE8: mnem = "fld1"; break;
+            case 0xEE: mnem = "fldz"; break;
+            case 0xF5: mnem = "fprem1"; break;
+            case 0xF7: mnem = "fincstp"; break;
+            case 0xF8: mnem = "fprem"; break;
+            case 0xFE: mnem = "fsin"; break;
+            case 0xFF: mnem = "fcos"; break;
+            default: UnimplementedInstruction();
+          }
+      }
+      break;
+
+    case 0xDA:
+      if (modrm_byte == 0xE9) {
+        mnem = "fucompp";
+      } else {
+        UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDB:
+      if ((modrm_byte & 0xF8) == 0xE8) {
+        mnem = "fucomi";
+        has_register = true;
+      } else if (modrm_byte  == 0xE2) {
+        mnem = "fclex";
+      } else {
+        UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDC:
+      has_register = true;
+      switch (modrm_byte & 0xF8) {
+        case 0xC0: mnem = "fadd"; break;
+        case 0xE8: mnem = "fsub"; break;
+        case 0xC8: mnem = "fmul"; break;
+        case 0xF8: mnem = "fdiv"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDD:
+      has_register = true;
+      switch (modrm_byte & 0xF8) {
+        case 0xC0: mnem = "ffree"; break;
+        case 0xD8: mnem = "fstp"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDE:
+      if (modrm_byte  == 0xD9) {
+        mnem = "fcompp";
+      } else {
+        has_register = true;
+        switch (modrm_byte & 0xF8) {
+          case 0xC0: mnem = "faddp"; break;
+          case 0xE8: mnem = "fsubp"; break;
+          case 0xC8: mnem = "fmulp"; break;
+          case 0xF8: mnem = "fdivp"; break;
+          default: UnimplementedInstruction();
+        }
+      }
+      break;
+
+    case 0xDF:
+      if (modrm_byte == 0xE0) {
+        mnem = "fnstsw_ax";
+      } else if ((modrm_byte & 0xF8) == 0xE8) {
+        mnem = "fucomip";
+        has_register = true;
+      }
+      break;
+
+    default: UnimplementedInstruction();
+  }
+
+  if (has_register) {
+    AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
+  } else {
      AppendToBuffer("%s", mnem);
-    return 2;
-  }
-  AppendToBuffer("Unknown FP instruction");
+  }
    return 2;
  }

=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc       Fri Oct 23 02:18:19 2009
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc       Tue Oct 27 03:47:01 2009
@@ -218,7 +218,7 @@
      OperandType op_order = bm[i].op_order_;
      id->op_order_ =
          static_cast<OperandType>(op_order & ~BYTE_SIZE_OPERAND_FLAG);
-    assert(id->type == NO_INSTR);  // Information not already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
      id->type = type;
      id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0);
    }
@@ -232,7 +232,7 @@
                                       const char* mnem) {
    for (byte b = start; b <= end; b++) {
      InstructionDesc* id = &instructions_[b];
-    assert(id->type == NO_INSTR);  // Information already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
      id->mnem = mnem;
      id->type = type;
      id->byte_size_operation = byte_size;
@@ -243,7 +243,7 @@
  void InstructionTable::AddJumpConditionalShort() {
    for (byte b = 0x70; b <= 0x7F; b++) {
      InstructionDesc* id = &instructions_[b];
-    assert(id->type == NO_INSTR);  // Information already entered
+    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
      id->mnem = NULL;  // Computed depending on condition code.
      id->type = JUMP_CONDITIONAL_SHORT_INSTR;
    }
@@ -393,6 +393,7 @@
                                RegisterNameMapping register_name);
    int PrintRightOperand(byte* modrmp);
    int PrintRightByteOperand(byte* modrmp);
+  int PrintRightXMMOperand(byte* modrmp);
    int PrintOperands(const char* mnem,
                      OperandType op_order,
                      byte* data);
@@ -400,13 +401,15 @@
    int PrintImmediateOp(byte* data);
    const char* TwoByteMnemonic(byte opcode);
    int TwoByteOpcodeInstruction(byte* data);
-  int F7Instruction(byte* data);
+  int F6F7Instruction(byte* data);
    int ShiftInstruction(byte* data);
    int JumpShort(byte* data);
    int JumpConditional(byte* data);
    int JumpConditionalShort(byte* data);
    int SetCC(byte* data);
    int FPUInstruction(byte* data);
+  int MemoryFPUInstruction(int escape_opcode, int regop, byte*  
modrm_start);
+  int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
    void AppendToBuffer(const char* format, ...);

    void UnimplementedInstruction() {
@@ -566,6 +569,12 @@
    return PrintRightOperandHelper(modrmp,
                                   &DisassemblerX64::NameOfByteCPURegister);
  }
+
+
+int DisassemblerX64::PrintRightXMMOperand(byte* modrmp) {
+  return PrintRightOperandHelper(modrmp,
+                                 &DisassemblerX64::NameOfXMMRegister);
+}


  // Returns number of bytes used including the current *data.
@@ -648,8 +657,8 @@


  // Returns number of bytes used, including *data.
-int DisassemblerX64::F7Instruction(byte* data) {
-  assert(*data == 0xF7);
+int DisassemblerX64::F6F7Instruction(byte* data) {
+  ASSERT(*data == 0xF7 || *data == 0xF6);
    byte modrm = *(data + 1);
    int mod, regop, rm;
    get_modrm(modrm, &mod, &regop, &rm);
@@ -676,19 +685,12 @@
                     operand_size_code(),
                     NameOfCPURegister(rm));
      return 2;
-  } else if (mod == 3 && regop == 0) {
-    int32_t imm = *reinterpret_cast<int32_t*>(data + 2);
-    AppendToBuffer("test%c %s,0x%x",
-                   operand_size_code(),
-                   NameOfCPURegister(rm),
-                   imm);
-    return 6;
    } else if (regop == 0) {
      AppendToBuffer("test%c ", operand_size_code());
-    int count = PrintRightOperand(data + 1);
-    int32_t imm = *reinterpret_cast<int32_t*>(data + 1 + count);
-    AppendToBuffer(",0x%x", imm);
-    return 1 + count + 4 /*int32_t*/;
+    int count = PrintRightOperand(data + 1);  // Use name of 64-bit  
register.
+    AppendToBuffer(",0x");
+    count += PrintImmediate(data + 1 + count, operand_size());
+    return 1 + count;
    } else {
      UnimplementedInstruction();
      return 2;
@@ -739,7 +741,7 @@
        UnimplementedInstruction();
        return num_bytes;
    }
-  assert(mnem != NULL);
+  ASSERT_NE(NULL, mnem);
    if (op == 0xD0) {
      imm8 = 1;
    } else if (op == 0xC0) {
@@ -762,7 +764,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerX64::JumpShort(byte* data) {
-  assert(*data == 0xEB);
+  ASSERT_EQ(0xEB, *data);
    byte b = *(data + 1);
    byte* dest = data + static_cast<int8_t>(b) + 2;
    AppendToBuffer("jmp %s", NameOfAddress(dest));
@@ -772,7 +774,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerX64::JumpConditional(byte* data) {
-  assert(*data == 0x0F);
+  ASSERT_EQ(0x0F, *data);
    byte cond = *(data + 1) & 0x0F;
    byte* dest = data + *reinterpret_cast<int32_t*>(data + 2) + 6;
    const char* mnem = conditional_code_suffix[cond];
@@ -794,7 +796,7 @@

  // Returns number of bytes used, including *data.
  int DisassemblerX64::SetCC(byte* data) {
-  assert(*data == 0x0F);
+  ASSERT_EQ(0x0F, *data);
    byte cond = *(data + 1) & 0x0F;
    const char* mnem = conditional_code_suffix[cond];
    AppendToBuffer("set%s%c ", mnem, operand_size_code());
@@ -805,166 +807,168 @@

  // Returns number of bytes used, including *data.
  int DisassemblerX64::FPUInstruction(byte* data) {
-  byte b1 = *data;
-  byte b2 = *(data + 1);
-  if (b1 == 0xD9) {
-    const char* mnem = NULL;
-    switch (b2) {
-      case 0xE0:
-        mnem = "fchs";
-        break;
-      case 0xE1:
-        mnem = "fabs";
-        break;
-      case 0xE4:
-        mnem = "ftst";
-        break;
-      case 0xF5:
-        mnem = "fprem1";
-        break;
-      case 0xF7:
-        mnem = "fincstp";
-        break;
-      case 0xE8:
-        mnem = "fld1";
-        break;
-      case 0xEE:
-        mnem = "fldz";
-        break;
-      case 0xF8:
-        mnem = "fprem";
-        break;
-    }
-    if (mnem != NULL) {
-      AppendToBuffer("%s", mnem);
-      return 2;
-    } else if ((b2 & 0xF8) == 0xC8) {
-      AppendToBuffer("fxch st%d", b2 & 0x7);
-      return 2;
-    } else {
-      int mod, regop, rm;
-      get_modrm(*(data + 1), &mod, &regop, &rm);
-      const char* mnem = "?";
-      switch (regop) {
-        case 0:
-          mnem = "fld_s";
-          break;
-        case 3:
-          mnem = "fstp_s";
-          break;
-        default:
-          UnimplementedInstruction();
-      }
-      AppendToBuffer("%s ", mnem);
-      int count = PrintRightOperand(data + 1);
-      return count + 1;
-    }
-  } else if (b1 == 0xDD) {
-    int mod, regop, rm;
-    get_modrm(*(data + 1), &mod, &regop, &rm);
-    if (mod == 3) {
-      switch (regop) {
-        case 0:
-          AppendToBuffer("ffree st%d", rm & 7);
-          break;
-        case 2:
-          AppendToBuffer("fstp st%d", rm & 7);
-          break;
-        default:
-          UnimplementedInstruction();
-          break;
-      }
-      return 2;
-    } else {
-      const char* mnem = "?";
-      switch (regop) {
-        case 0:
-          mnem = "fld_d";
-          break;
-        case 3:
-          mnem = "fstp_d";
+  byte escape_opcode = *data;
+  ASSERT_EQ(0xD8, escape_opcode & 0xF8);
+  byte modrm_byte = *(data+1);
+
+  if (modrm_byte >= 0xC0) {
+    return RegisterFPUInstruction(escape_opcode, modrm_byte);
+  } else {
+    return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
+  }
+}
+
+int DisassemblerX64::MemoryFPUInstruction(int escape_opcode,
+                                           int modrm_byte,
+                                           byte* modrm_start) {
+  const char* mnem = "?";
+  int regop = (modrm_byte >> 3) & 0x7;  // reg/op field of modrm byte.
+  switch (escape_opcode) {
+    case 0xD9: switch (regop) {
+        case 0: mnem = "fld_s"; break;
+        case 3: mnem = "fstp_s"; break;
+        case 7: mnem = "fstcw"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDB: switch (regop) {
+        case 0: mnem = "fild_s"; break;
+        case 1: mnem = "fisttp_s"; break;
+        case 2: mnem = "fist_s"; break;
+        case 3: mnem = "fistp_s"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDD: switch (regop) {
+        case 0: mnem = "fld_d"; break;
+        case 3: mnem = "fstp_d"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDF: switch (regop) {
+        case 5: mnem = "fild_d"; break;
+        case 7: mnem = "fistp_d"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    default: UnimplementedInstruction();
+  }
+  AppendToBuffer("%s ", mnem);
+  int count = PrintRightOperand(modrm_start);
+  return count + 1;
+}
+
+int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
+                                             byte modrm_byte) {
+  bool has_register = false;  // Is the FPU register encoded in modrm_byte?
+  const char* mnem = "?";
+
+  switch (escape_opcode) {
+    case 0xD8:
+      UnimplementedInstruction();
+      break;
+
+    case 0xD9:
+      switch (modrm_byte & 0xF8) {
+        case 0xC8:
+          mnem = "fxch";
+          has_register = true;
            break;
          default:
-          UnimplementedInstruction();
-      }
-      AppendToBuffer("%s ", mnem);
-      int count = PrintRightOperand(data + 1);
-      return count + 1;
-    }
-  } else if (b1 == 0xDB) {
-    int mod, regop, rm;
-    get_modrm(*(data + 1), &mod, &regop, &rm);
-    const char* mnem = "?";
-    switch (regop) {
-      case 0:
-        mnem = "fild_s";
-        break;
-      case 2:
-        mnem = "fist_s";
-        break;
-      case 3:
-        mnem = "fistp_s";
-        break;
-      default:
+          switch (modrm_byte) {
+            case 0xE0: mnem = "fchs"; break;
+            case 0xE1: mnem = "fabs"; break;
+            case 0xE4: mnem = "ftst"; break;
+            case 0xE8: mnem = "fld1"; break;
+            case 0xEE: mnem = "fldz"; break;
+            case 0xF5: mnem = "fprem1"; break;
+            case 0xF7: mnem = "fincstp"; break;
+            case 0xF8: mnem = "fprem"; break;
+            case 0xFE: mnem = "fsin"; break;
+            case 0xFF: mnem = "fcos"; break;
+            default: UnimplementedInstruction();
+          }
+      }
+      break;
+
+    case 0xDA:
+      if (modrm_byte == 0xE9) {
+        mnem = "fucompp";
+      } else {
          UnimplementedInstruction();
-    }
-    AppendToBuffer("%s ", mnem);
-    int count = PrintRightOperand(data + 1);
-    return count + 1;
-  } else if (b1 == 0xDF) {
-    if (b2 == 0xE0) {
-      AppendToBuffer("fnstsw_ax");
-      return 2;
-    }
-    int mod, regop, rm;
-    get_modrm(*(data + 1), &mod, &regop, &rm);
-    const char* mnem = "?";
-    switch (regop) {
-      case 5:
-        mnem = "fild_d";
-        break;
-      case 7:
-        mnem = "fistp_d";
-        break;
-      default:
+      }
+      break;
+
+    case 0xDB:
+      if ((modrm_byte & 0xF8) == 0xE8) {
+        mnem = "fucomi";
+        has_register = true;
+      } else if (modrm_byte  == 0xE2) {
+        mnem = "fclex";
+      } else {
          UnimplementedInstruction();
-    }
-    AppendToBuffer("%s ", mnem);
-    int count = PrintRightOperand(data + 1);
-    return count + 1;
-  } else if (b1 == 0xDC || b1 == 0xDE) {
-    bool is_pop = (b1 == 0xDE);
-    if (is_pop && b2 == 0xD9) {
-      AppendToBuffer("fcompp");
-      return 2;
-    }
-    const char* mnem = "FP0xDC";
-    switch (b2 & 0xF8) {
-      case 0xC0:
-        mnem = "fadd";
-        break;
-      case 0xE8:
-        mnem = "fsub";
-        break;
-      case 0xC8:
-        mnem = "fmul";
-        break;
-      case 0xF8:
-        mnem = "fdiv";
-        break;
-      default:
-        UnimplementedInstruction();
-    }
-    AppendToBuffer("%s%s st%d", mnem, is_pop ? "p" : "", b2 & 0x7);
-    return 2;
-  } else if (b1 == 0xDA && b2 == 0xE9) {
-    const char* mnem = "fucompp";
+      }
+      break;
+
+    case 0xDC:
+      has_register = true;
+      switch (modrm_byte & 0xF8) {
+        case 0xC0: mnem = "fadd"; break;
+        case 0xE8: mnem = "fsub"; break;
+        case 0xC8: mnem = "fmul"; break;
+        case 0xF8: mnem = "fdiv"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDD:
+      has_register = true;
+      switch (modrm_byte & 0xF8) {
+        case 0xC0: mnem = "ffree"; break;
+        case 0xD8: mnem = "fstp"; break;
+        default: UnimplementedInstruction();
+      }
+      break;
+
+    case 0xDE:
+      if (modrm_byte  == 0xD9) {
+        mnem = "fcompp";
+      } else {
+        has_register = true;
+        switch (modrm_byte & 0xF8) {
+          case 0xC0: mnem = "faddp"; break;
+          case 0xE8: mnem = "fsubp"; break;
+          case 0xC8: mnem = "fmulp"; break;
+          case 0xF8: mnem = "fdivp"; break;
+          default: UnimplementedInstruction();
+        }
+      }
+      break;
+
+    case 0xDF:
+      if (modrm_byte == 0xE0) {
+        mnem = "fnstsw_ax";
+      } else if ((modrm_byte & 0xF8) == 0xE8) {
+        mnem = "fucomip";
+        has_register = true;
+      }
+      break;
+
+    default: UnimplementedInstruction();
+  }
+
+  if (has_register) {
+    AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
+  } else {
      AppendToBuffer("%s", mnem);
-    return 2;
-  }
-  AppendToBuffer("Unknown FP instruction");
+  }
    return 2;
  }
+


  // Handle all two-byte opcodes, which start with 0x0F.
@@ -1045,13 +1049,13 @@
        int mod, regop, rm;
        get_modrm(*current, &mod, &regop, &rm);
        AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
-      data += PrintRightOperand(data);
+      current += PrintRightOperand(current);
      } else if ((opcode & 0xF8) == 0x58) {
        // XMM arithmetic. Mnemonic was retrieved at the start of this  
function.
        int mod, regop, rm;
        get_modrm(*current, &mod, &regop, &rm);
-      AppendToBuffer("%s %s,%s", mnemonic, NameOfXMMRegister(regop),
-                     NameOfXMMRegister(rm));
+      AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
+      current += PrintRightXMMOperand(current);
      } else {
        UnimplementedInstruction();
      }
@@ -1060,7 +1064,7 @@

      // CVTTSS2SI: Convert scalar single-precision FP to dword integer.
      // Assert that mod is not 3, so source is memory, not an XMM register.
-    ASSERT((*current & 0xC0) != 0xC0);
+    ASSERT_NE(0xC0, *current & 0xC0);
      current += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, current);
    } else {
      UnimplementedInstruction();
@@ -1235,18 +1239,6 @@
          data += 2 + (*data == 0x6B ? 1 : 4);
          break;
        }
-
-      case 0xF6: {
-        int mod, regop, rm;
-        get_modrm(*(data + 1), &mod, &regop, &rm);
-        if (mod == 3 && regop == 0) {
-          AppendToBuffer("testb %s,%d", NameOfCPURegister(rm), *(data +  
2));
-        } else {
-          UnimplementedInstruction();
-        }
-        data += 3;
-        break;
-      }

        case 0x81:  // fall through
        case 0x83:  // 0x81 with sign extension bit set
@@ -1344,7 +1336,7 @@
        case 0x95:
        case 0x96:
        case 0x97: {
-        int reg = (current & 0x7) | (rex_b() ? 8 : 0);
+        int reg = (*data & 0x7) | (rex_b() ? 8 : 0);
          if (reg == 0) {
            AppendToBuffer("nop");  // Common name for xchg rax,rax.
          } else {
@@ -1352,8 +1344,9 @@
                           operand_size_code(),
                           NameOfCPURegister(reg));
          }
-      }
-
+        data++;
+      }
+        break;

        case 0xFE: {
          data++;
@@ -1465,8 +1458,10 @@
          data += JumpShort(data);
          break;

+      case 0xF6:
+        byte_size_operand_ = true;  // fall through
        case 0xF7:
-        data += F7Instruction(data);
+        data += F6F7Instruction(data);
          break;

        default:

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to