| 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 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 ASSERT_EQ(0xF7, *data); |
| 532 byte modrm = *(data+1); | 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 if (mod == 3 && regop != 0) { | 535 const char* mnem = NULL; |
| 536 const char* mnem = NULL; | 536 switch (regop) { |
| 537 switch (regop) { | 537 case 0: |
| 538 case 2: mnem = "not"; break; | 538 mnem = "test"; |
| 539 case 3: mnem = "neg"; break; | 539 break; |
| 540 case 4: mnem = "mul"; break; | 540 case 2: |
| 541 case 5: mnem = "imul"; break; | 541 mnem = "not"; |
| 542 case 7: mnem = "idiv"; break; | 542 break; |
| 543 default: UnimplementedInstruction(); | 543 case 3: |
| 544 } | 544 mnem = "neg"; |
| 545 AppendToBuffer("%s %s", mnem, NameOfCPURegister(rm)); | 545 break; |
| 546 return 2; | 546 case 4: |
| 547 } else if (mod == 3 && regop == eax) { | 547 mnem = "mul"; |
| 548 int32_t imm = *reinterpret_cast<int32_t*>(data+2); | 548 break; |
| 549 AppendToBuffer("test %s,0x%x", NameOfCPURegister(rm), imm); | 549 case 5: |
| 550 return 6; | 550 mnem = "imul"; |
| 551 } else if (regop == eax) { | 551 break; |
| 552 AppendToBuffer("test "); | 552 case 6: |
| 553 int count = PrintRightOperand(data+1); | 553 mnem = "div"; |
| 554 int32_t imm = *reinterpret_cast<int32_t*>(data+1+count); | 554 break; |
| 555 AppendToBuffer(",0x%x", imm); | 555 case 7: |
| 556 return 1+count+4 /*int32_t*/; | 556 mnem = "idiv"; |
| 557 } else { | 557 break; |
| 558 UnimplementedInstruction(); | 558 default: |
| 559 return 2; | 559 UnimplementedInstruction(); |
| 560 } | 560 } |
| 561 AppendToBuffer("%s ", mnem); |
| 562 int count = PrintRightOperand(data); |
| 563 if (regop == 0) { |
| 564 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count)); |
| 565 count += 4; |
| 566 } |
| 567 return 1 + count; |
| 561 } | 568 } |
| 562 | 569 |
| 563 | 570 |
| 564 int DisassemblerIA32::D1D3C1Instruction(byte* data) { | 571 int DisassemblerIA32::D1D3C1Instruction(byte* data) { |
| 565 byte op = *data; | 572 byte op = *data; |
| 566 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); | 573 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); |
| 567 byte modrm = *(data+1); | 574 byte modrm = *++data; |
| 568 int mod, regop, rm; | 575 int mod, regop, rm; |
| 569 get_modrm(modrm, &mod, ®op, &rm); | 576 get_modrm(modrm, &mod, ®op, &rm); |
| 570 int imm8 = -1; | 577 int imm8 = -1; |
| 571 int num_bytes = 2; | 578 const char* mnem = NULL; |
| 572 if (mod == 3) { | 579 switch (regop) { |
| 573 const char* mnem = NULL; | 580 case kROL: |
| 574 switch (regop) { | 581 mnem = "rol"; |
| 575 case kROL: mnem = "rol"; break; | 582 break; |
| 576 case kROR: mnem = "ror"; break; | 583 case kROR: |
| 577 case kRCL: mnem = "rcl"; break; | 584 mnem = "ror"; |
| 578 case kRCR: mnem = "rcr"; break; | 585 break; |
| 579 case kSHL: mnem = "shl"; break; | 586 case kRCL: |
| 580 case KSHR: mnem = "shr"; break; | 587 mnem = "rcl"; |
| 581 case kSAR: mnem = "sar"; break; | 588 break; |
| 582 default: UnimplementedInstruction(); | 589 case kRCR: |
| 583 } | 590 mnem = "rcr"; |
| 584 if (op == 0xD1) { | 591 break; |
| 585 imm8 = 1; | 592 case kSHL: |
| 586 } else if (op == 0xC1) { | 593 mnem = "shl"; |
| 587 imm8 = *(data+2); | 594 break; |
| 588 num_bytes = 3; | 595 case KSHR: |
| 589 } else if (op == 0xD3) { | 596 mnem = "shr"; |
| 590 // Shift/rotate by cl. | 597 break; |
| 591 } | 598 case kSAR: |
| 592 ASSERT_NE(NULL, mnem); | 599 mnem = "sar"; |
| 593 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm)); | 600 break; |
| 594 if (imm8 >= 0) { | 601 default: |
| 595 AppendToBuffer("%d", imm8); | 602 UnimplementedInstruction(); |
| 596 } else { | 603 } |
| 597 AppendToBuffer("cl"); | 604 AppendToBuffer("%s ", mnem); |
| 598 } | 605 int count = PrintRightOperand(data); |
| 606 if (op == 0xD1) { |
| 607 imm8 = 1; |
| 608 } else if (op == 0xC1) { |
| 609 imm8 = *(data + 2); |
| 610 count++; |
| 611 } else if (op == 0xD3) { |
| 612 // Shift/rotate by cl. |
| 613 } |
| 614 if (imm8 >= 0) { |
| 615 AppendToBuffer(",%d", imm8); |
| 599 } else { | 616 } else { |
| 600 UnimplementedInstruction(); | 617 AppendToBuffer(",cl"); |
| 601 } | 618 } |
| 602 return num_bytes; | 619 return 1 + count; |
| 603 } | 620 } |
| 604 | 621 |
| 605 | 622 |
| 606 // Returns number of bytes used, including *data. | 623 // Returns number of bytes used, including *data. |
| 607 int DisassemblerIA32::JumpShort(byte* data) { | 624 int DisassemblerIA32::JumpShort(byte* data) { |
| 608 ASSERT_EQ(0xEB, *data); | 625 ASSERT_EQ(0xEB, *data); |
| 609 byte b = *(data+1); | 626 byte b = *(data+1); |
| 610 byte* dest = data + static_cast<int8_t>(b) + 2; | 627 byte* dest = data + static_cast<int8_t>(b) + 2; |
| 611 AppendToBuffer("jmp %s", NameOfAddress(dest)); | 628 AppendToBuffer("jmp %s", NameOfAddress(dest)); |
| 612 return 2; | 629 return 2; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 UNIMPLEMENTED(); // This type is not implemented. | 964 UNIMPLEMENTED(); // This type is not implemented. |
| 948 } | 965 } |
| 949 //---------------------------- | 966 //---------------------------- |
| 950 if (!processed) { | 967 if (!processed) { |
| 951 switch (*data) { | 968 switch (*data) { |
| 952 case 0xC2: | 969 case 0xC2: |
| 953 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); | 970 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); |
| 954 data += 3; | 971 data += 3; |
| 955 break; | 972 break; |
| 956 | 973 |
| 957 case 0x69: // fall through | 974 case 0x6B: { |
| 958 case 0x6B: | 975 data++; |
| 959 { int mod, regop, rm; | 976 data += PrintOperands("imul", REG_OPER_OP_ORDER, data); |
| 960 get_modrm(*(data+1), &mod, ®op, &rm); | 977 AppendToBuffer(",%d", *data); |
| 961 int32_t imm = | 978 data++; |
| 962 *data == 0x6B ? *(data+2) : *reinterpret_cast<int32_t*>(data+2); | 979 } break; |
| 963 AppendToBuffer("imul %s,%s,0x%x", | 980 |
| 964 NameOfCPURegister(regop), | 981 case 0x69: { |
| 965 NameOfCPURegister(rm), | 982 data++; |
| 966 imm); | 983 data += PrintOperands("imul", REG_OPER_OP_ORDER, data); |
| 967 data += 2 + (*data == 0x6B ? 1 : 4); | 984 AppendToBuffer(",%d", *reinterpret_cast<int32_t*>(data)); |
| 985 data += 4; |
| 968 } | 986 } |
| 969 break; | 987 break; |
| 970 | 988 |
| 971 case 0xF6: | 989 case 0xF6: |
| 972 { data++; | 990 { data++; |
| 973 int mod, regop, rm; | 991 int mod, regop, rm; |
| 974 get_modrm(*data, &mod, ®op, &rm); | 992 get_modrm(*data, &mod, ®op, &rm); |
| 975 if (regop == eax) { | 993 if (regop == eax) { |
| 976 AppendToBuffer("test_b "); | 994 AppendToBuffer("test_b "); |
| 977 data += PrintRightByteOperand(data); | 995 data += PrintRightByteOperand(data); |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 fprintf(f, " "); | 1770 fprintf(f, " "); |
| 1753 } | 1771 } |
| 1754 fprintf(f, " %s\n", buffer.start()); | 1772 fprintf(f, " %s\n", buffer.start()); |
| 1755 } | 1773 } |
| 1756 } | 1774 } |
| 1757 | 1775 |
| 1758 | 1776 |
| 1759 } // namespace disasm | 1777 } // namespace disasm |
| 1760 | 1778 |
| 1761 #endif // V8_TARGET_ARCH_IA32 | 1779 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |