| 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: mnem = "test"; break; |
| 538 case 2: mnem = "not"; break; | 538 case 2: mnem = "not"; break; |
| 539 case 3: mnem = "neg"; break; | 539 case 3: mnem = "neg"; break; |
| 540 case 4: mnem = "mul"; break; | 540 case 4: mnem = "mul"; break; |
| 541 case 5: mnem = "imul"; break; | 541 case 5: mnem = "imul"; break; |
| 542 case 7: mnem = "idiv"; break; | 542 case 6: mnem = "div"; break; |
| 543 default: UnimplementedInstruction(); | 543 case 7: mnem = "idiv"; break; |
| 544 } | 544 default: UnimplementedInstruction(); |
| 545 AppendToBuffer("%s %s", mnem, NameOfCPURegister(rm)); | |
| 546 return 2; | |
| 547 } else if (mod == 3 && regop == eax) { | |
| 548 int32_t imm = *reinterpret_cast<int32_t*>(data+2); | |
| 549 AppendToBuffer("test %s,0x%x", NameOfCPURegister(rm), imm); | |
| 550 return 6; | |
| 551 } else if (regop == eax) { | |
| 552 AppendToBuffer("test "); | |
| 553 int count = PrintRightOperand(data+1); | |
| 554 int32_t imm = *reinterpret_cast<int32_t*>(data+1+count); | |
| 555 AppendToBuffer(",0x%x", imm); | |
| 556 return 1+count+4 /*int32_t*/; | |
| 557 } else { | |
| 558 UnimplementedInstruction(); | |
| 559 return 2; | |
| 560 } | 545 } |
| 546 AppendToBuffer("%s ", mnem); |
| 547 int count = PrintRightOperand(data); |
| 548 if (regop == 0) { |
| 549 AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count)); |
| 550 count += 4; |
| 551 } |
| 552 return 1 + count; |
| 561 } | 553 } |
| 562 | 554 |
| 563 | 555 |
| 564 int DisassemblerIA32::D1D3C1Instruction(byte* data) { | 556 int DisassemblerIA32::D1D3C1Instruction(byte* data) { |
| 565 byte op = *data; | 557 byte op = *data; |
| 566 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); | 558 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); |
| 567 byte modrm = *(data+1); | 559 byte modrm = *++data; |
| 568 int mod, regop, rm; | 560 int mod, regop, rm; |
| 569 get_modrm(modrm, &mod, ®op, &rm); | 561 get_modrm(modrm, &mod, ®op, &rm); |
| 570 int imm8 = -1; | 562 int imm8 = -1; |
| 571 int num_bytes = 2; | 563 const char* mnem = NULL; |
| 572 if (mod == 3) { | 564 switch (regop) { |
| 573 const char* mnem = NULL; | 565 case kROL: mnem = "rol"; break; |
| 574 switch (regop) { | 566 case kROR: mnem = "ror"; break; |
| 575 case kROL: mnem = "rol"; break; | 567 case kRCL: mnem = "rcl"; break; |
| 576 case kROR: mnem = "ror"; break; | 568 case kRCR: mnem = "rcr"; break; |
| 577 case kRCL: mnem = "rcl"; break; | 569 case kSHL: mnem = "shl"; break; |
| 578 case kRCR: mnem = "rcr"; break; | 570 case KSHR: mnem = "shr"; break; |
| 579 case kSHL: mnem = "shl"; break; | 571 case kSAR: mnem = "sar"; break; |
| 580 case KSHR: mnem = "shr"; break; | 572 default: UnimplementedInstruction(); |
| 581 case kSAR: mnem = "sar"; break; | 573 } |
| 582 default: UnimplementedInstruction(); | 574 AppendToBuffer("%s ", mnem); |
| 583 } | 575 int count = PrintRightOperand(data); |
| 584 if (op == 0xD1) { | 576 if (op == 0xD1) { |
| 585 imm8 = 1; | 577 imm8 = 1; |
| 586 } else if (op == 0xC1) { | 578 } else if (op == 0xC1) { |
| 587 imm8 = *(data+2); | 579 imm8 = *(data+2); |
| 588 num_bytes = 3; | 580 count++; |
| 589 } else if (op == 0xD3) { | 581 } else if (op == 0xD3) { |
| 590 // Shift/rotate by cl. | 582 // Shift/rotate by cl. |
| 591 } | 583 } |
| 592 ASSERT_NE(NULL, mnem); | 584 if (imm8 >= 0) { |
| 593 AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm)); | 585 AppendToBuffer(",%d", imm8); |
| 594 if (imm8 >= 0) { | |
| 595 AppendToBuffer("%d", imm8); | |
| 596 } else { | |
| 597 AppendToBuffer("cl"); | |
| 598 } | |
| 599 } else { | 586 } else { |
| 600 UnimplementedInstruction(); | 587 AppendToBuffer(",cl"); |
| 601 } | 588 } |
| 602 return num_bytes; | 589 return 1 + count; |
| 603 } | 590 } |
| 604 | 591 |
| 605 | 592 |
| 606 // Returns number of bytes used, including *data. | 593 // Returns number of bytes used, including *data. |
| 607 int DisassemblerIA32::JumpShort(byte* data) { | 594 int DisassemblerIA32::JumpShort(byte* data) { |
| 608 ASSERT_EQ(0xEB, *data); | 595 ASSERT_EQ(0xEB, *data); |
| 609 byte b = *(data+1); | 596 byte b = *(data+1); |
| 610 byte* dest = data + static_cast<int8_t>(b) + 2; | 597 byte* dest = data + static_cast<int8_t>(b) + 2; |
| 611 AppendToBuffer("jmp %s", NameOfAddress(dest)); | 598 AppendToBuffer("jmp %s", NameOfAddress(dest)); |
| 612 return 2; | 599 return 2; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 UNIMPLEMENTED(); // This type is not implemented. | 934 UNIMPLEMENTED(); // This type is not implemented. |
| 948 } | 935 } |
| 949 //---------------------------- | 936 //---------------------------- |
| 950 if (!processed) { | 937 if (!processed) { |
| 951 switch (*data) { | 938 switch (*data) { |
| 952 case 0xC2: | 939 case 0xC2: |
| 953 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); | 940 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); |
| 954 data += 3; | 941 data += 3; |
| 955 break; | 942 break; |
| 956 | 943 |
| 957 case 0x69: // fall through | |
| 958 case 0x6B: | 944 case 0x6B: |
| 959 { int mod, regop, rm; | 945 { |
| 960 get_modrm(*(data+1), &mod, ®op, &rm); | 946 data++; |
| 961 int32_t imm = | 947 data += PrintOperands("imul", REG_OPER_OP_ORDER, data); |
| 962 *data == 0x6B ? *(data+2) : *reinterpret_cast<int32_t*>(data+2); | 948 AppendToBuffer(",%d", *data); |
| 963 AppendToBuffer("imul %s,%s,0x%x", | 949 data++; |
| 964 NameOfCPURegister(regop), | |
| 965 NameOfCPURegister(rm), | |
| 966 imm); | |
| 967 data += 2 + (*data == 0x6B ? 1 : 4); | |
| 968 } | 950 } |
| 969 break; | 951 break; |
| 970 | 952 |
| 953 case 0x69: |
| 954 { |
| 955 data++; |
| 956 data += PrintOperands("imul", REG_OPER_OP_ORDER, data); |
| 957 AppendToBuffer(",%d", *reinterpret_cast<int32_t*>(data)); |
| 958 data += 4; |
| 959 } |
| 960 break; |
| 961 |
| 971 case 0xF6: | 962 case 0xF6: |
| 972 { data++; | 963 { data++; |
| 973 int mod, regop, rm; | 964 int mod, regop, rm; |
| 974 get_modrm(*data, &mod, ®op, &rm); | 965 get_modrm(*data, &mod, ®op, &rm); |
| 975 if (regop == eax) { | 966 if (regop == eax) { |
| 976 AppendToBuffer("test_b "); | 967 AppendToBuffer("test_b "); |
| 977 data += PrintRightByteOperand(data); | 968 data += PrintRightByteOperand(data); |
| 978 int32_t imm = *data; | 969 int32_t imm = *data; |
| 979 AppendToBuffer(",0x%x", imm); | 970 AppendToBuffer(",0x%x", imm); |
| 980 data++; | 971 data++; |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 fprintf(f, " "); | 1743 fprintf(f, " "); |
| 1753 } | 1744 } |
| 1754 fprintf(f, " %s\n", buffer.start()); | 1745 fprintf(f, " %s\n", buffer.start()); |
| 1755 } | 1746 } |
| 1756 } | 1747 } |
| 1757 | 1748 |
| 1758 | 1749 |
| 1759 } // namespace disasm | 1750 } // namespace disasm |
| 1760 | 1751 |
| 1761 #endif // V8_TARGET_ARCH_IA32 | 1752 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |