OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 // A Disassembler object is used to disassemble a block of code instruction by | 5 // A Disassembler object is used to disassemble a block of code instruction by |
6 // instruction. The default implementation of the NameConverter object can be | 6 // instruction. The default implementation of the NameConverter object can be |
7 // overriden to modify register names or to do symbol lookup on addresses. | 7 // overriden to modify register names or to do symbol lookup on addresses. |
8 // | 8 // |
9 // The example below will disassemble a block of code and print it to stdout. | 9 // The example below will disassemble a block of code and print it to stdout. |
10 // | 10 // |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 // UnknownFormat(instr) which will just print opcode name of the | 364 // UnknownFormat(instr) which will just print opcode name of the |
365 // instruction bits. | 365 // instruction bits. |
366 void Decoder::UnknownFormat(Instruction* instr, const char* name) { | 366 void Decoder::UnknownFormat(Instruction* instr, const char* name) { |
367 char buffer[100]; | 367 char buffer[100]; |
368 snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name); | 368 snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name); |
369 Format(instr, buffer); | 369 Format(instr, buffer); |
370 } | 370 } |
371 | 371 |
372 | 372 |
373 void Decoder::DecodeExt1(Instruction* instr) { | 373 void Decoder::DecodeExt1(Instruction* instr) { |
374 switch (instr->Bits(10, 1) << 1) { | 374 switch (EXT1 | (instr->BitField(10, 1))) { |
375 case MCRF: { | 375 case MCRF: { |
376 UnknownFormat(instr, "mcrf"); // not used by V8 | 376 UnknownFormat(instr, "mcrf"); // not used by V8 |
377 break; | 377 break; |
378 } | 378 } |
379 case BCLRX: { | 379 case BCLRX: { |
380 int bo = instr->Bits(25, 21) << 21; | 380 int bo = instr->BitField(25, 21); |
381 int bi = instr->Bits(20, 16); | 381 int bi = instr->Bits(20, 16); |
382 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1)); | 382 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1)); |
383 switch (bo) { | 383 switch (bo) { |
384 case DCBNZF: { | 384 case DCBNZF: { |
385 UnknownFormat(instr, "bclrx-dcbnzf"); | 385 UnknownFormat(instr, "bclrx-dcbnzf"); |
386 break; | 386 break; |
387 } | 387 } |
388 case DCBEZF: { | 388 case DCBEZF: { |
389 UnknownFormat(instr, "bclrx-dcbezf"); | 389 UnknownFormat(instr, "bclrx-dcbezf"); |
390 break; | 390 break; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 break; | 440 break; |
441 } | 441 } |
442 case BA: { | 442 case BA: { |
443 Format(instr, "blr'l"); | 443 Format(instr, "blr'l"); |
444 break; | 444 break; |
445 } | 445 } |
446 } | 446 } |
447 break; | 447 break; |
448 } | 448 } |
449 case BCCTRX: { | 449 case BCCTRX: { |
450 switch (instr->Bits(25, 21) << 21) { | 450 switch (instr->BitField(25, 21)) { |
451 case DCBNZF: { | 451 case DCBNZF: { |
452 UnknownFormat(instr, "bcctrx-dcbnzf"); | 452 UnknownFormat(instr, "bcctrx-dcbnzf"); |
453 break; | 453 break; |
454 } | 454 } |
455 case DCBEZF: { | 455 case DCBEZF: { |
456 UnknownFormat(instr, "bcctrx-dcbezf"); | 456 UnknownFormat(instr, "bcctrx-dcbezf"); |
457 break; | 457 break; |
458 } | 458 } |
459 case BF: { | 459 case BF: { |
460 UnknownFormat(instr, "bcctrx-bf"); | 460 UnknownFormat(instr, "bcctrx-bf"); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 } | 534 } |
535 default: { | 535 default: { |
536 Unknown(instr); // not used by V8 | 536 Unknown(instr); // not used by V8 |
537 } | 537 } |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 | 541 |
542 void Decoder::DecodeExt2(Instruction* instr) { | 542 void Decoder::DecodeExt2(Instruction* instr) { |
543 // Some encodings are 10-1 bits, handle those first | 543 // Some encodings are 10-1 bits, handle those first |
544 switch (instr->Bits(10, 1) << 1) { | 544 switch (EXT2 | (instr->BitField(10, 1))) { |
545 case SRWX: { | 545 case SRWX: { |
546 Format(instr, "srw'. 'ra, 'rs, 'rb"); | 546 Format(instr, "srw'. 'ra, 'rs, 'rb"); |
547 return; | 547 return; |
548 } | 548 } |
549 #if V8_TARGET_ARCH_PPC64 | 549 #if V8_TARGET_ARCH_PPC64 |
550 case SRDX: { | 550 case SRDX: { |
551 Format(instr, "srd'. 'ra, 'rs, 'rb"); | 551 Format(instr, "srd'. 'ra, 'rs, 'rb"); |
552 return; | 552 return; |
553 } | 553 } |
554 #endif | 554 #endif |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 return; | 635 return; |
636 } | 636 } |
637 #if V8_TARGET_ARCH_PPC64 | 637 #if V8_TARGET_ARCH_PPC64 |
638 case POPCNTD: { | 638 case POPCNTD: { |
639 Format(instr, "popcntd 'ra, 'rs"); | 639 Format(instr, "popcntd 'ra, 'rs"); |
640 return; | 640 return; |
641 } | 641 } |
642 #endif | 642 #endif |
643 } | 643 } |
644 | 644 |
645 switch (instr->Bits(10, 2) << 2) { | 645 switch (EXT2 | (instr->BitField(10, 2))) { |
646 case SRADIX: { | 646 case SRADIX: { |
647 Format(instr, "sradi'. 'ra,'rs,'sh"); | 647 Format(instr, "sradi'. 'ra,'rs,'sh"); |
648 return; | 648 return; |
649 } | 649 } |
650 } | 650 } |
651 | 651 |
652 // ?? are all of these xo_form? | 652 // ?? are all of these xo_form? |
653 switch (instr->Bits(9, 1) << 1) { | 653 switch (EXT2 | (instr->BitField(9, 1))) { |
654 case CMP: { | 654 case CMP: { |
655 #if V8_TARGET_ARCH_PPC64 | 655 #if V8_TARGET_ARCH_PPC64 |
656 if (instr->Bit(21)) { | 656 if (instr->Bit(21)) { |
657 #endif | 657 #endif |
658 Format(instr, "cmp 'ra, 'rb"); | 658 Format(instr, "cmp 'ra, 'rb"); |
659 #if V8_TARGET_ARCH_PPC64 | 659 #if V8_TARGET_ARCH_PPC64 |
660 } else { | 660 } else { |
661 Format(instr, "cmpw 'ra, 'rb"); | 661 Format(instr, "cmpw 'ra, 'rb"); |
662 } | 662 } |
663 #endif | 663 #endif |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 Format(instr, "mtfprwa 'Dt, 'ra"); | 892 Format(instr, "mtfprwa 'Dt, 'ra"); |
893 return; | 893 return; |
894 } | 894 } |
895 case MTVSRWZ: { | 895 case MTVSRWZ: { |
896 Format(instr, "mtfprwz 'Dt, 'ra"); | 896 Format(instr, "mtfprwz 'Dt, 'ra"); |
897 return; | 897 return; |
898 } | 898 } |
899 #endif | 899 #endif |
900 } | 900 } |
901 | 901 |
902 switch (instr->Bits(5, 1) << 1) { | 902 switch (EXT2 | (instr->BitField(5, 1))) { |
903 case ISEL: { | 903 case ISEL: { |
904 Format(instr, "isel 'rt, 'ra, 'rb"); | 904 Format(instr, "isel 'rt, 'ra, 'rb"); |
905 return; | 905 return; |
906 } | 906 } |
907 default: { | 907 default: { |
908 Unknown(instr); // not used by V8 | 908 Unknown(instr); // not used by V8 |
909 } | 909 } |
910 } | 910 } |
911 } | 911 } |
912 | 912 |
913 | 913 |
914 void Decoder::DecodeExt3(Instruction* instr) { | 914 void Decoder::DecodeExt3(Instruction* instr) { |
915 switch (instr->Bits(10, 1) << 1) { | 915 switch (EXT3 | (instr->BitField(10, 1))) { |
916 case FCFID: { | 916 case FCFID: { |
917 Format(instr, "fcfids'. 'Dt, 'Db"); | 917 Format(instr, "fcfids'. 'Dt, 'Db"); |
918 break; | 918 break; |
919 } | 919 } |
920 case FCFIDU: { | 920 case FCFIDU: { |
921 Format(instr, "fcfidus'.'Dt, 'Db"); | 921 Format(instr, "fcfidus'.'Dt, 'Db"); |
922 break; | 922 break; |
923 } | 923 } |
924 default: { | 924 default: { |
925 Unknown(instr); // not used by V8 | 925 Unknown(instr); // not used by V8 |
926 } | 926 } |
927 } | 927 } |
928 } | 928 } |
929 | 929 |
930 | 930 |
931 void Decoder::DecodeExt4(Instruction* instr) { | 931 void Decoder::DecodeExt4(Instruction* instr) { |
932 switch (instr->Bits(5, 1) << 1) { | 932 switch (EXT4 | (instr->BitField(5, 1))) { |
933 case FDIV: { | 933 case FDIV: { |
934 Format(instr, "fdiv'. 'Dt, 'Da, 'Db"); | 934 Format(instr, "fdiv'. 'Dt, 'Da, 'Db"); |
935 return; | 935 return; |
936 } | 936 } |
937 case FSUB: { | 937 case FSUB: { |
938 Format(instr, "fsub'. 'Dt, 'Da, 'Db"); | 938 Format(instr, "fsub'. 'Dt, 'Da, 'Db"); |
939 return; | 939 return; |
940 } | 940 } |
941 case FADD: { | 941 case FADD: { |
942 Format(instr, "fadd'. 'Dt, 'Da, 'Db"); | 942 Format(instr, "fadd'. 'Dt, 'Da, 'Db"); |
(...skipping 14 matching lines...) Expand all Loading... |
957 case FMSUB: { | 957 case FMSUB: { |
958 Format(instr, "fmsub'. 'Dt, 'Da, 'Dc, 'Db"); | 958 Format(instr, "fmsub'. 'Dt, 'Da, 'Dc, 'Db"); |
959 return; | 959 return; |
960 } | 960 } |
961 case FMADD: { | 961 case FMADD: { |
962 Format(instr, "fmadd'. 'Dt, 'Da, 'Dc, 'Db"); | 962 Format(instr, "fmadd'. 'Dt, 'Da, 'Dc, 'Db"); |
963 return; | 963 return; |
964 } | 964 } |
965 } | 965 } |
966 | 966 |
967 switch (instr->Bits(10, 1) << 1) { | 967 switch (EXT4 | (instr->BitField(10, 1))) { |
968 case FCMPU: { | 968 case FCMPU: { |
969 Format(instr, "fcmpu 'Da, 'Db"); | 969 Format(instr, "fcmpu 'Da, 'Db"); |
970 break; | 970 break; |
971 } | 971 } |
972 case FRSP: { | 972 case FRSP: { |
973 Format(instr, "frsp'. 'Dt, 'Db"); | 973 Format(instr, "frsp'. 'Dt, 'Db"); |
974 break; | 974 break; |
975 } | 975 } |
976 case FCFID: { | 976 case FCFID: { |
977 Format(instr, "fcfid'. 'Dt, 'Db"); | 977 Format(instr, "fcfid'. 'Dt, 'Db"); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 break; | 1058 break; |
1059 } | 1059 } |
1060 default: { | 1060 default: { |
1061 Unknown(instr); // not used by V8 | 1061 Unknown(instr); // not used by V8 |
1062 } | 1062 } |
1063 } | 1063 } |
1064 } | 1064 } |
1065 | 1065 |
1066 | 1066 |
1067 void Decoder::DecodeExt5(Instruction* instr) { | 1067 void Decoder::DecodeExt5(Instruction* instr) { |
1068 switch (instr->Bits(4, 2) << 2) { | 1068 switch (EXT5 | (instr->BitField(4, 2))) { |
1069 case RLDICL: { | 1069 case RLDICL: { |
1070 Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb"); | 1070 Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb"); |
1071 return; | 1071 return; |
1072 } | 1072 } |
1073 case RLDICR: { | 1073 case RLDICR: { |
1074 Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me"); | 1074 Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me"); |
1075 return; | 1075 return; |
1076 } | 1076 } |
1077 case RLDIC: { | 1077 case RLDIC: { |
1078 Format(instr, "rldic'. 'ra, 'rs, 'sh, 'mb"); | 1078 Format(instr, "rldic'. 'ra, 'rs, 'sh, 'mb"); |
1079 return; | 1079 return; |
1080 } | 1080 } |
1081 case RLDIMI: { | 1081 case RLDIMI: { |
1082 Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb"); | 1082 Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb"); |
1083 return; | 1083 return; |
1084 } | 1084 } |
1085 } | 1085 } |
1086 switch (instr->Bits(4, 1) << 1) { | 1086 switch (EXT5 | (instr->BitField(4, 1))) { |
1087 case RLDCL: { | 1087 case RLDCL: { |
1088 Format(instr, "rldcl'. 'ra, 'rs, 'sb, 'mb"); | 1088 Format(instr, "rldcl'. 'ra, 'rs, 'sb, 'mb"); |
1089 return; | 1089 return; |
1090 } | 1090 } |
1091 } | 1091 } |
1092 Unknown(instr); // not used by V8 | 1092 Unknown(instr); // not used by V8 |
1093 } | 1093 } |
1094 | 1094 |
1095 void Decoder::DecodeExt6(Instruction* instr) { | 1095 void Decoder::DecodeExt6(Instruction* instr) { |
1096 switch (instr->Bits(10, 3) << 3) { | 1096 switch (EXT6 | (instr->BitField(10, 3))) { |
1097 #define DECODE_XX3_INSTRUCTIONS(name, opcode_name, opcode_value) \ | 1097 #define DECODE_XX3_INSTRUCTIONS(name, opcode_name, opcode_value) \ |
1098 case opcode_name: { \ | 1098 case opcode_name: { \ |
1099 Format(instr, #name" 'Dt, 'Da, 'Db"); \ | 1099 Format(instr, #name" 'Dt, 'Da, 'Db"); \ |
1100 return; \ | 1100 return; \ |
1101 } | 1101 } |
1102 XX3_OPCODE_LIST(DECODE_XX3_INSTRUCTIONS) | 1102 PPC_XX3_OPCODE_LIST(DECODE_XX3_INSTRUCTIONS) |
1103 #undef DECODE_XX3_INSTRUCTIONS | 1103 #undef DECODE_XX3_INSTRUCTIONS |
1104 } | 1104 } |
1105 switch (instr->Bits(10, 2) << 2) { | 1105 switch (EXT6 | (instr->BitField(10, 2))) { |
1106 #define DECODE_XX2_INSTRUCTIONS(name, opcode_name, opcode_value) \ | 1106 #define DECODE_XX2_INSTRUCTIONS(name, opcode_name, opcode_value) \ |
1107 case opcode_name: { \ | 1107 case opcode_name: { \ |
1108 Format(instr, #name" 'Dt, 'Db"); \ | 1108 Format(instr, #name" 'Dt, 'Db"); \ |
1109 return; \ | 1109 return; \ |
1110 } | 1110 } |
1111 XX2_OPCODE_LIST(DECODE_XX2_INSTRUCTIONS) | 1111 PPC_XX2_OPCODE_LIST(DECODE_XX2_INSTRUCTIONS) |
1112 } | 1112 } |
1113 #undef DECODE_XX3_INSTRUCTIONS | 1113 #undef DECODE_XX3_INSTRUCTIONS |
1114 Unknown(instr); // not used by V8 | 1114 Unknown(instr); // not used by V8 |
1115 } | 1115 } |
1116 | 1116 |
1117 #undef VERIFIY | 1117 #undef VERIFIY |
1118 | 1118 |
1119 // Disassemble the instruction at *instr_ptr into the output buffer. | 1119 // Disassemble the instruction at *instr_ptr into the output buffer. |
1120 int Decoder::InstructionDecode(byte* instr_ptr) { | 1120 int Decoder::InstructionDecode(byte* instr_ptr) { |
1121 Instruction* instr = Instruction::At(instr_ptr); | 1121 Instruction* instr = Instruction::At(instr_ptr); |
1122 // Print raw instruction bytes. | 1122 // Print raw instruction bytes. |
1123 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x ", | 1123 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x ", |
1124 instr->InstructionBits()); | 1124 instr->InstructionBits()); |
1125 | 1125 |
1126 if (ABI_USES_FUNCTION_DESCRIPTORS && instr->InstructionBits() == 0) { | 1126 if (ABI_USES_FUNCTION_DESCRIPTORS && instr->InstructionBits() == 0) { |
1127 // The first field will be identified as a jump table entry. We | 1127 // The first field will be identified as a jump table entry. We |
1128 // emit the rest of the structure as zero, so just skip past them. | 1128 // emit the rest of the structure as zero, so just skip past them. |
1129 Format(instr, "constant"); | 1129 Format(instr, "constant"); |
1130 return Instruction::kInstrSize; | 1130 return Instruction::kInstrSize; |
1131 } | 1131 } |
1132 | 1132 |
1133 switch (instr->OpcodeValue() << 26) { | 1133 uint32_t opcode = instr->OpcodeValue() << 26; |
| 1134 switch (opcode) { |
1134 case TWI: { | 1135 case TWI: { |
1135 PrintSoftwareInterrupt(instr->SvcValue()); | 1136 PrintSoftwareInterrupt(instr->SvcValue()); |
1136 break; | 1137 break; |
1137 } | 1138 } |
1138 case MULLI: { | 1139 case MULLI: { |
1139 UnknownFormat(instr, "mulli"); | 1140 UnknownFormat(instr, "mulli"); |
1140 break; | 1141 break; |
1141 } | 1142 } |
1142 case SUBFIC: { | 1143 case SUBFIC: { |
1143 Format(instr, "subfic 'rt, 'ra, 'int16"); | 1144 Format(instr, "subfic 'rt, 'ra, 'int16"); |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1509 pc += d.InstructionDecode(buffer, pc); | 1510 pc += d.InstructionDecode(buffer, pc); |
1510 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), | 1511 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), |
1511 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1512 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1512 } | 1513 } |
1513 } | 1514 } |
1514 | 1515 |
1515 | 1516 |
1516 } // namespace disasm | 1517 } // namespace disasm |
1517 | 1518 |
1518 #endif // V8_TARGET_ARCH_PPC | 1519 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |