| 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 |