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 |