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 DisassemblerX87::F7Instruction(byte* data) { | 530 int DisassemblerX87::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 DisassemblerX87::D1D3C1Instruction(byte* data) { | 571 int DisassemblerX87::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 DisassemblerX87::JumpShort(byte* data) { | 624 int DisassemblerX87::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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 fprintf(f, " "); | 1766 fprintf(f, " "); |
1749 } | 1767 } |
1750 fprintf(f, " %s\n", buffer.start()); | 1768 fprintf(f, " %s\n", buffer.start()); |
1751 } | 1769 } |
1752 } | 1770 } |
1753 | 1771 |
1754 | 1772 |
1755 } // namespace disasm | 1773 } // namespace disasm |
1756 | 1774 |
1757 #endif // V8_TARGET_ARCH_X87 | 1775 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |