| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <assert.h> | 5 #include <assert.h> | 
| 6 #include <stdarg.h> | 6 #include <stdarg.h> | 
| 7 #include <stdio.h> | 7 #include <stdio.h> | 
| 8 | 8 | 
| 9 #include "src/v8.h" | 9 #include "src/v8.h" | 
| 10 | 10 | 
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 204   SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); | 204   SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); | 
| 205 } | 205 } | 
| 206 | 206 | 
| 207 | 207 | 
| 208 void InstructionTable::CopyTable(const ByteMnemonic bm[], | 208 void InstructionTable::CopyTable(const ByteMnemonic bm[], | 
| 209                                  InstructionType type) { | 209                                  InstructionType type) { | 
| 210   for (int i = 0; bm[i].b >= 0; i++) { | 210   for (int i = 0; bm[i].b >= 0; i++) { | 
| 211     InstructionDesc* id = &instructions_[bm[i].b]; | 211     InstructionDesc* id = &instructions_[bm[i].b]; | 
| 212     id->mnem = bm[i].mnem; | 212     id->mnem = bm[i].mnem; | 
| 213     id->op_order_ = bm[i].op_order_; | 213     id->op_order_ = bm[i].op_order_; | 
| 214     ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered. | 214     DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered. | 
| 215     id->type = type; | 215     id->type = type; | 
| 216   } | 216   } | 
| 217 } | 217 } | 
| 218 | 218 | 
| 219 | 219 | 
| 220 void InstructionTable::SetTableRange(InstructionType type, | 220 void InstructionTable::SetTableRange(InstructionType type, | 
| 221                                      byte start, | 221                                      byte start, | 
| 222                                      byte end, | 222                                      byte end, | 
| 223                                      const char* mnem) { | 223                                      const char* mnem) { | 
| 224   for (byte b = start; b <= end; b++) { | 224   for (byte b = start; b <= end; b++) { | 
| 225     InstructionDesc* id = &instructions_[b]; | 225     InstructionDesc* id = &instructions_[b]; | 
| 226     ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered. | 226     DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered. | 
| 227     id->mnem = mnem; | 227     id->mnem = mnem; | 
| 228     id->type = type; | 228     id->type = type; | 
| 229   } | 229   } | 
| 230 } | 230 } | 
| 231 | 231 | 
| 232 | 232 | 
| 233 void InstructionTable::AddJumpConditionalShort() { | 233 void InstructionTable::AddJumpConditionalShort() { | 
| 234   for (byte b = 0x70; b <= 0x7F; b++) { | 234   for (byte b = 0x70; b <= 0x7F; b++) { | 
| 235     InstructionDesc* id = &instructions_[b]; | 235     InstructionDesc* id = &instructions_[b]; | 
| 236     ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered. | 236     DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered. | 
| 237     id->mnem = jump_conditional_mnem[b & 0x0F]; | 237     id->mnem = jump_conditional_mnem[b & 0x0F]; | 
| 238     id->type = JUMP_CONDITIONAL_SHORT_INSTR; | 238     id->type = JUMP_CONDITIONAL_SHORT_INSTR; | 
| 239   } | 239   } | 
| 240 } | 240 } | 
| 241 | 241 | 
| 242 | 242 | 
| 243 // The IA32 disassembler implementation. | 243 // The IA32 disassembler implementation. | 
| 244 class DisassemblerIA32 { | 244 class DisassemblerIA32 { | 
| 245  public: | 245  public: | 
| 246   DisassemblerIA32(const NameConverter& converter, | 246   DisassemblerIA32(const NameConverter& converter, | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 521     return 1 + count + 1 /*int8*/; | 521     return 1 + count + 1 /*int8*/; | 
| 522   } else { | 522   } else { | 
| 523     AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); | 523     AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); | 
| 524     return 1 + count + 4 /*int32_t*/; | 524     return 1 + count + 4 /*int32_t*/; | 
| 525   } | 525   } | 
| 526 } | 526 } | 
| 527 | 527 | 
| 528 | 528 | 
| 529 // Returns number of bytes used, including *data. | 529 // Returns number of bytes used, including *data. | 
| 530 int DisassemblerIA32::F7Instruction(byte* data) { | 530 int DisassemblerIA32::F7Instruction(byte* data) { | 
| 531   ASSERT_EQ(0xF7, *data); | 531   DCHECK_EQ(0xF7, *data); | 
| 532   byte modrm = *++data; | 532   byte modrm = *++data; | 
| 533   int mod, regop, rm; | 533   int mod, regop, rm; | 
| 534   get_modrm(modrm, &mod, ®op, &rm); | 534   get_modrm(modrm, &mod, ®op, &rm); | 
| 535   const char* mnem = NULL; | 535   const char* mnem = NULL; | 
| 536   switch (regop) { | 536   switch (regop) { | 
| 537     case 0: | 537     case 0: | 
| 538       mnem = "test"; | 538       mnem = "test"; | 
| 539       break; | 539       break; | 
| 540     case 2: | 540     case 2: | 
| 541       mnem = "not"; | 541       mnem = "not"; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 563   if (regop == 0) { | 563   if (regop == 0) { | 
| 564     AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count)); | 564     AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count)); | 
| 565     count += 4; | 565     count += 4; | 
| 566   } | 566   } | 
| 567   return 1 + count; | 567   return 1 + count; | 
| 568 } | 568 } | 
| 569 | 569 | 
| 570 | 570 | 
| 571 int DisassemblerIA32::D1D3C1Instruction(byte* data) { | 571 int DisassemblerIA32::D1D3C1Instruction(byte* data) { | 
| 572   byte op = *data; | 572   byte op = *data; | 
| 573   ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); | 573   DCHECK(op == 0xD1 || op == 0xD3 || op == 0xC1); | 
| 574   byte modrm = *++data; | 574   byte modrm = *++data; | 
| 575   int mod, regop, rm; | 575   int mod, regop, rm; | 
| 576   get_modrm(modrm, &mod, ®op, &rm); | 576   get_modrm(modrm, &mod, ®op, &rm); | 
| 577   int imm8 = -1; | 577   int imm8 = -1; | 
| 578   const char* mnem = NULL; | 578   const char* mnem = NULL; | 
| 579   switch (regop) { | 579   switch (regop) { | 
| 580     case kROL: | 580     case kROL: | 
| 581       mnem = "rol"; | 581       mnem = "rol"; | 
| 582       break; | 582       break; | 
| 583     case kROR: | 583     case kROR: | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 615     AppendToBuffer(",%d", imm8); | 615     AppendToBuffer(",%d", imm8); | 
| 616   } else { | 616   } else { | 
| 617     AppendToBuffer(",cl"); | 617     AppendToBuffer(",cl"); | 
| 618   } | 618   } | 
| 619   return 1 + count; | 619   return 1 + count; | 
| 620 } | 620 } | 
| 621 | 621 | 
| 622 | 622 | 
| 623 // Returns number of bytes used, including *data. | 623 // Returns number of bytes used, including *data. | 
| 624 int DisassemblerIA32::JumpShort(byte* data) { | 624 int DisassemblerIA32::JumpShort(byte* data) { | 
| 625   ASSERT_EQ(0xEB, *data); | 625   DCHECK_EQ(0xEB, *data); | 
| 626   byte b = *(data+1); | 626   byte b = *(data+1); | 
| 627   byte* dest = data + static_cast<int8_t>(b) + 2; | 627   byte* dest = data + static_cast<int8_t>(b) + 2; | 
| 628   AppendToBuffer("jmp %s", NameOfAddress(dest)); | 628   AppendToBuffer("jmp %s", NameOfAddress(dest)); | 
| 629   return 2; | 629   return 2; | 
| 630 } | 630 } | 
| 631 | 631 | 
| 632 | 632 | 
| 633 // Returns number of bytes used, including *data. | 633 // Returns number of bytes used, including *data. | 
| 634 int DisassemblerIA32::JumpConditional(byte* data, const char* comment) { | 634 int DisassemblerIA32::JumpConditional(byte* data, const char* comment) { | 
| 635   ASSERT_EQ(0x0F, *data); | 635   DCHECK_EQ(0x0F, *data); | 
| 636   byte cond = *(data+1) & 0x0F; | 636   byte cond = *(data+1) & 0x0F; | 
| 637   byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; | 637   byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; | 
| 638   const char* mnem = jump_conditional_mnem[cond]; | 638   const char* mnem = jump_conditional_mnem[cond]; | 
| 639   AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | 639   AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | 
| 640   if (comment != NULL) { | 640   if (comment != NULL) { | 
| 641     AppendToBuffer(", %s", comment); | 641     AppendToBuffer(", %s", comment); | 
| 642   } | 642   } | 
| 643   return 6;  // includes 0x0F | 643   return 6;  // includes 0x0F | 
| 644 } | 644 } | 
| 645 | 645 | 
| 646 | 646 | 
| 647 // Returns number of bytes used, including *data. | 647 // Returns number of bytes used, including *data. | 
| 648 int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { | 648 int DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { | 
| 649   byte cond = *data & 0x0F; | 649   byte cond = *data & 0x0F; | 
| 650   byte b = *(data+1); | 650   byte b = *(data+1); | 
| 651   byte* dest = data + static_cast<int8_t>(b) + 2; | 651   byte* dest = data + static_cast<int8_t>(b) + 2; | 
| 652   const char* mnem = jump_conditional_mnem[cond]; | 652   const char* mnem = jump_conditional_mnem[cond]; | 
| 653   AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | 653   AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); | 
| 654   if (comment != NULL) { | 654   if (comment != NULL) { | 
| 655     AppendToBuffer(", %s", comment); | 655     AppendToBuffer(", %s", comment); | 
| 656   } | 656   } | 
| 657   return 2; | 657   return 2; | 
| 658 } | 658 } | 
| 659 | 659 | 
| 660 | 660 | 
| 661 // Returns number of bytes used, including *data. | 661 // Returns number of bytes used, including *data. | 
| 662 int DisassemblerIA32::SetCC(byte* data) { | 662 int DisassemblerIA32::SetCC(byte* data) { | 
| 663   ASSERT_EQ(0x0F, *data); | 663   DCHECK_EQ(0x0F, *data); | 
| 664   byte cond = *(data+1) & 0x0F; | 664   byte cond = *(data+1) & 0x0F; | 
| 665   const char* mnem = set_conditional_mnem[cond]; | 665   const char* mnem = set_conditional_mnem[cond]; | 
| 666   AppendToBuffer("%s ", mnem); | 666   AppendToBuffer("%s ", mnem); | 
| 667   PrintRightByteOperand(data+2); | 667   PrintRightByteOperand(data+2); | 
| 668   return 3;  // Includes 0x0F. | 668   return 3;  // Includes 0x0F. | 
| 669 } | 669 } | 
| 670 | 670 | 
| 671 | 671 | 
| 672 // Returns number of bytes used, including *data. | 672 // Returns number of bytes used, including *data. | 
| 673 int DisassemblerIA32::CMov(byte* data) { | 673 int DisassemblerIA32::CMov(byte* data) { | 
| 674   ASSERT_EQ(0x0F, *data); | 674   DCHECK_EQ(0x0F, *data); | 
| 675   byte cond = *(data + 1) & 0x0F; | 675   byte cond = *(data + 1) & 0x0F; | 
| 676   const char* mnem = conditional_move_mnem[cond]; | 676   const char* mnem = conditional_move_mnem[cond]; | 
| 677   int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); | 677   int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); | 
| 678   return 2 + op_size;  // includes 0x0F | 678   return 2 + op_size;  // includes 0x0F | 
| 679 } | 679 } | 
| 680 | 680 | 
| 681 | 681 | 
| 682 // Returns number of bytes used, including *data. | 682 // Returns number of bytes used, including *data. | 
| 683 int DisassemblerIA32::FPUInstruction(byte* data) { | 683 int DisassemblerIA32::FPUInstruction(byte* data) { | 
| 684   byte escape_opcode = *data; | 684   byte escape_opcode = *data; | 
| 685   ASSERT_EQ(0xD8, escape_opcode & 0xF8); | 685   DCHECK_EQ(0xD8, escape_opcode & 0xF8); | 
| 686   byte modrm_byte = *(data+1); | 686   byte modrm_byte = *(data+1); | 
| 687 | 687 | 
| 688   if (modrm_byte >= 0xC0) { | 688   if (modrm_byte >= 0xC0) { | 
| 689     return RegisterFPUInstruction(escape_opcode, modrm_byte); | 689     return RegisterFPUInstruction(escape_opcode, modrm_byte); | 
| 690   } else { | 690   } else { | 
| 691     return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); | 691     return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); | 
| 692   } | 692   } | 
| 693 } | 693 } | 
| 694 | 694 | 
| 695 int DisassemblerIA32::MemoryFPUInstruction(int escape_opcode, | 695 int DisassemblerIA32::MemoryFPUInstruction(int escape_opcode, | 
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1384             get_modrm(*data, &mod, ®op, &rm); | 1384             get_modrm(*data, &mod, ®op, &rm); | 
| 1385             AppendToBuffer("psllq %s,%s", | 1385             AppendToBuffer("psllq %s,%s", | 
| 1386                            NameOfXMMRegister(regop), | 1386                            NameOfXMMRegister(regop), | 
| 1387                            NameOfXMMRegister(rm)); | 1387                            NameOfXMMRegister(rm)); | 
| 1388             data++; | 1388             data++; | 
| 1389           } else if (*data == 0x73) { | 1389           } else if (*data == 0x73) { | 
| 1390             data++; | 1390             data++; | 
| 1391             int mod, regop, rm; | 1391             int mod, regop, rm; | 
| 1392             get_modrm(*data, &mod, ®op, &rm); | 1392             get_modrm(*data, &mod, ®op, &rm); | 
| 1393             int8_t imm8 = static_cast<int8_t>(data[1]); | 1393             int8_t imm8 = static_cast<int8_t>(data[1]); | 
| 1394             ASSERT(regop == esi || regop == edx); | 1394             DCHECK(regop == esi || regop == edx); | 
| 1395             AppendToBuffer("%s %s,%d", | 1395             AppendToBuffer("%s %s,%d", | 
| 1396                            (regop == esi) ? "psllq" : "psrlq", | 1396                            (regop == esi) ? "psllq" : "psrlq", | 
| 1397                            NameOfXMMRegister(rm), | 1397                            NameOfXMMRegister(rm), | 
| 1398                            static_cast<int>(imm8)); | 1398                            static_cast<int>(imm8)); | 
| 1399             data += 2; | 1399             data += 2; | 
| 1400           } else if (*data == 0xD3) { | 1400           } else if (*data == 0xD3) { | 
| 1401             data++; | 1401             data++; | 
| 1402             int mod, regop, rm; | 1402             int mod, regop, rm; | 
| 1403             get_modrm(*data, &mod, ®op, &rm); | 1403             get_modrm(*data, &mod, ®op, &rm); | 
| 1404             AppendToBuffer("psrlq %s,%s", | 1404             AppendToBuffer("psrlq %s,%s", | 
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1651   } | 1651   } | 
| 1652 | 1652 | 
| 1653   if (tmp_buffer_pos_ < sizeof tmp_buffer_) { | 1653   if (tmp_buffer_pos_ < sizeof tmp_buffer_) { | 
| 1654     tmp_buffer_[tmp_buffer_pos_] = '\0'; | 1654     tmp_buffer_[tmp_buffer_pos_] = '\0'; | 
| 1655   } | 1655   } | 
| 1656 | 1656 | 
| 1657   int instr_len = data - instr; | 1657   int instr_len = data - instr; | 
| 1658   if (instr_len == 0) { | 1658   if (instr_len == 0) { | 
| 1659     printf("%02x", *data); | 1659     printf("%02x", *data); | 
| 1660   } | 1660   } | 
| 1661   ASSERT(instr_len > 0);  // Ensure progress. | 1661   DCHECK(instr_len > 0);  // Ensure progress. | 
| 1662 | 1662 | 
| 1663   int outp = 0; | 1663   int outp = 0; | 
| 1664   // Instruction bytes. | 1664   // Instruction bytes. | 
| 1665   for (byte* bp = instr; bp < data; bp++) { | 1665   for (byte* bp = instr; bp < data; bp++) { | 
| 1666     outp += v8::internal::SNPrintF(out_buffer + outp, | 1666     outp += v8::internal::SNPrintF(out_buffer + outp, | 
| 1667                                    "%02x", | 1667                                    "%02x", | 
| 1668                                    *bp); | 1668                                    *bp); | 
| 1669   } | 1669   } | 
| 1670   for (int i = 6 - instr_len; i >= 0; i--) { | 1670   for (int i = 6 - instr_len; i >= 0; i--) { | 
| 1671     outp += v8::internal::SNPrintF(out_buffer + outp, "  "); | 1671     outp += v8::internal::SNPrintF(out_buffer + outp, "  "); | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1770       fprintf(f, "  "); | 1770       fprintf(f, "  "); | 
| 1771     } | 1771     } | 
| 1772     fprintf(f, "  %s\n", buffer.start()); | 1772     fprintf(f, "  %s\n", buffer.start()); | 
| 1773   } | 1773   } | 
| 1774 } | 1774 } | 
| 1775 | 1775 | 
| 1776 | 1776 | 
| 1777 }  // namespace disasm | 1777 }  // namespace disasm | 
| 1778 | 1778 | 
| 1779 #endif  // V8_TARGET_ARCH_IA32 | 1779 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|