OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 out_buffer_pos_(0) { | 82 out_buffer_pos_(0) { |
83 out_buffer_[out_buffer_pos_] = '\0'; | 83 out_buffer_[out_buffer_pos_] = '\0'; |
84 } | 84 } |
85 | 85 |
86 ~Decoder() {} | 86 ~Decoder() {} |
87 | 87 |
88 // Writes one disassembled instruction into 'buffer' (0-terminated). | 88 // Writes one disassembled instruction into 'buffer' (0-terminated). |
89 // Returns the length of the disassembled machine instruction in bytes. | 89 // Returns the length of the disassembled machine instruction in bytes. |
90 int InstructionDecode(byte* instruction); | 90 int InstructionDecode(byte* instruction); |
91 | 91 |
| 92 static bool IsConstantPoolAt(byte* instr_ptr); |
| 93 static int ConstantPoolSizeAt(byte* instr_ptr); |
| 94 |
92 private: | 95 private: |
93 // Bottleneck functions to print into the out_buffer. | 96 // Bottleneck functions to print into the out_buffer. |
94 void PrintChar(const char ch); | 97 void PrintChar(const char ch); |
95 void Print(const char* str); | 98 void Print(const char* str); |
96 | 99 |
97 // Printing of common values. | 100 // Printing of common values. |
98 void PrintRegister(int reg); | 101 void PrintRegister(int reg); |
99 void PrintSRegister(int reg); | 102 void PrintSRegister(int reg); |
100 void PrintDRegister(int reg); | 103 void PrintDRegister(int reg); |
101 int FormatVFPRegister(Instruction* instr, const char* format); | 104 int FormatVFPRegister(Instruction* instr, const char* format); |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 } | 895 } |
893 } | 896 } |
894 } | 897 } |
895 | 898 |
896 | 899 |
897 void Decoder::DecodeType2(Instruction* instr) { | 900 void Decoder::DecodeType2(Instruction* instr) { |
898 switch (instr->PUField()) { | 901 switch (instr->PUField()) { |
899 case da_x: { | 902 case da_x: { |
900 if (instr->HasW()) { | 903 if (instr->HasW()) { |
901 Unknown(instr); // not used in V8 | 904 Unknown(instr); // not used in V8 |
| 905 return; |
902 } | 906 } |
903 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); | 907 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); |
904 break; | 908 break; |
905 } | 909 } |
906 case ia_x: { | 910 case ia_x: { |
907 if (instr->HasW()) { | 911 if (instr->HasW()) { |
908 Unknown(instr); // not used in V8 | 912 Unknown(instr); // not used in V8 |
| 913 return; |
909 } | 914 } |
910 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); | 915 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); |
911 break; | 916 break; |
912 } | 917 } |
913 case db_x: { | 918 case db_x: { |
914 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); | 919 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); |
915 break; | 920 break; |
916 } | 921 } |
917 case ib_x: { | 922 case ib_x: { |
918 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); | 923 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 default: { | 990 default: { |
986 // The PU field is a 2-bit field. | 991 // The PU field is a 2-bit field. |
987 UNREACHABLE(); | 992 UNREACHABLE(); |
988 break; | 993 break; |
989 } | 994 } |
990 } | 995 } |
991 } | 996 } |
992 | 997 |
993 | 998 |
994 void Decoder::DecodeType4(Instruction* instr) { | 999 void Decoder::DecodeType4(Instruction* instr) { |
995 ASSERT(instr->Bit(22) == 0); // Privileged mode currently not supported. | 1000 if (instr->Bit(22) != 0) { |
996 if (instr->HasL()) { | 1001 // Privileged mode currently not supported. |
997 Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); | 1002 Unknown(instr); |
998 } else { | 1003 } else { |
999 Format(instr, "stm'cond'pu 'rn'w, 'rlist"); | 1004 if (instr->HasL()) { |
| 1005 Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); |
| 1006 } else { |
| 1007 Format(instr, "stm'cond'pu 'rn'w, 'rlist"); |
| 1008 } |
1000 } | 1009 } |
1001 } | 1010 } |
1002 | 1011 |
1003 | 1012 |
1004 void Decoder::DecodeType5(Instruction* instr) { | 1013 void Decoder::DecodeType5(Instruction* instr) { |
1005 Format(instr, "b'l'cond 'target"); | 1014 Format(instr, "b'l'cond 'target"); |
1006 } | 1015 } |
1007 | 1016 |
1008 | 1017 |
1009 void Decoder::DecodeType6(Instruction* instr) { | 1018 void Decoder::DecodeType6(Instruction* instr) { |
(...skipping 25 matching lines...) Expand all Loading... |
1035 } | 1044 } |
1036 return Instruction::kInstrSize; | 1045 return Instruction::kInstrSize; |
1037 } | 1046 } |
1038 | 1047 |
1039 | 1048 |
1040 // void Decoder::DecodeTypeVFP(Instruction* instr) | 1049 // void Decoder::DecodeTypeVFP(Instruction* instr) |
1041 // vmov: Sn = Rt | 1050 // vmov: Sn = Rt |
1042 // vmov: Rt = Sn | 1051 // vmov: Rt = Sn |
1043 // vcvt: Dd = Sm | 1052 // vcvt: Dd = Sm |
1044 // vcvt: Sd = Dm | 1053 // vcvt: Sd = Dm |
| 1054 // Dd = vabs(Dm) |
| 1055 // Dd = vneg(Dm) |
1045 // Dd = vadd(Dn, Dm) | 1056 // Dd = vadd(Dn, Dm) |
1046 // Dd = vsub(Dn, Dm) | 1057 // Dd = vsub(Dn, Dm) |
1047 // Dd = vmul(Dn, Dm) | 1058 // Dd = vmul(Dn, Dm) |
1048 // Dd = vdiv(Dn, Dm) | 1059 // Dd = vdiv(Dn, Dm) |
1049 // vcmp(Dd, Dm) | 1060 // vcmp(Dd, Dm) |
1050 // vmrs | 1061 // vmrs |
1051 // vmsr | 1062 // vmsr |
1052 // Dd = vsqrt(Dm) | 1063 // Dd = vsqrt(Dm) |
1053 void Decoder::DecodeTypeVFP(Instruction* instr) { | 1064 void Decoder::DecodeTypeVFP(Instruction* instr) { |
1054 ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); | 1065 ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 Format(instr, "vldr'cond 'Dd, ['rn + 4*'imm08@00]"); | 1301 Format(instr, "vldr'cond 'Dd, ['rn + 4*'imm08@00]"); |
1291 } else { | 1302 } else { |
1292 Format(instr, "vstr'cond 'Dd, ['rn + 4*'imm08@00]"); | 1303 Format(instr, "vstr'cond 'Dd, ['rn + 4*'imm08@00]"); |
1293 } | 1304 } |
1294 break; | 1305 break; |
1295 default: | 1306 default: |
1296 Unknown(instr); // Not used by V8. | 1307 Unknown(instr); // Not used by V8. |
1297 break; | 1308 break; |
1298 } | 1309 } |
1299 } else { | 1310 } else { |
1300 UNIMPLEMENTED(); // Not used by V8. | 1311 Unknown(instr); // Not used by V8. |
1301 } | 1312 } |
1302 } | 1313 } |
1303 | 1314 |
| 1315 |
| 1316 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { |
| 1317 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
| 1318 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; |
| 1319 } |
| 1320 |
| 1321 |
| 1322 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { |
| 1323 if (IsConstantPoolAt(instr_ptr)) { |
| 1324 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
| 1325 return instruction_bits & kConstantPoolLengthMask; |
| 1326 } else { |
| 1327 return -1; |
| 1328 } |
| 1329 } |
| 1330 |
1304 | 1331 |
1305 // Disassemble the instruction at *instr_ptr into the output buffer. | 1332 // Disassemble the instruction at *instr_ptr into the output buffer. |
1306 int Decoder::InstructionDecode(byte* instr_ptr) { | 1333 int Decoder::InstructionDecode(byte* instr_ptr) { |
1307 Instruction* instr = Instruction::At(instr_ptr); | 1334 Instruction* instr = Instruction::At(instr_ptr); |
1308 // Print raw instruction bytes. | 1335 // Print raw instruction bytes. |
1309 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 1336 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
1310 "%08x ", | 1337 "%08x ", |
1311 instr->InstructionBits()); | 1338 instr->InstructionBits()); |
1312 if (instr->ConditionField() == kSpecialCondition) { | 1339 if (instr->ConditionField() == kSpecialCondition) { |
1313 UNIMPLEMENTED(); | 1340 Unknown(instr); |
| 1341 return Instruction::kInstrSize; |
| 1342 } |
| 1343 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
| 1344 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { |
| 1345 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
| 1346 "constant pool begin (length %d)", |
| 1347 instruction_bits & |
| 1348 kConstantPoolLengthMask); |
1314 return Instruction::kInstrSize; | 1349 return Instruction::kInstrSize; |
1315 } | 1350 } |
1316 switch (instr->TypeValue()) { | 1351 switch (instr->TypeValue()) { |
1317 case 0: | 1352 case 0: |
1318 case 1: { | 1353 case 1: { |
1319 DecodeType01(instr); | 1354 DecodeType01(instr); |
1320 break; | 1355 break; |
1321 } | 1356 } |
1322 case 2: { | 1357 case 2: { |
1323 DecodeType2(instr); | 1358 DecodeType2(instr); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 | 1441 |
1407 | 1442 |
1408 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, | 1443 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, |
1409 byte* instruction) { | 1444 byte* instruction) { |
1410 v8::internal::Decoder d(converter_, buffer); | 1445 v8::internal::Decoder d(converter_, buffer); |
1411 return d.InstructionDecode(instruction); | 1446 return d.InstructionDecode(instruction); |
1412 } | 1447 } |
1413 | 1448 |
1414 | 1449 |
1415 int Disassembler::ConstantPoolSizeAt(byte* instruction) { | 1450 int Disassembler::ConstantPoolSizeAt(byte* instruction) { |
1416 int instruction_bits = *(reinterpret_cast<int*>(instruction)); | 1451 return v8::internal::Decoder::ConstantPoolSizeAt(instruction); |
1417 if ((instruction_bits & 0xfff00000) == 0x03000000) { | |
1418 return instruction_bits & 0x0000ffff; | |
1419 } else { | |
1420 return -1; | |
1421 } | |
1422 } | 1452 } |
1423 | 1453 |
1424 | 1454 |
1425 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { | 1455 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { |
1426 NameConverter converter; | 1456 NameConverter converter; |
1427 Disassembler d(converter); | 1457 Disassembler d(converter); |
1428 for (byte* pc = begin; pc < end;) { | 1458 for (byte* pc = begin; pc < end;) { |
1429 v8::internal::EmbeddedVector<char, 128> buffer; | 1459 v8::internal::EmbeddedVector<char, 128> buffer; |
1430 buffer[0] = '\0'; | 1460 buffer[0] = '\0'; |
1431 byte* prev_pc = pc; | 1461 byte* prev_pc = pc; |
1432 pc += d.InstructionDecode(buffer, pc); | 1462 pc += d.InstructionDecode(buffer, pc); |
1433 fprintf(f, "%p %08x %s\n", | 1463 fprintf(f, "%p %08x %s\n", |
1434 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1464 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1435 } | 1465 } |
1436 } | 1466 } |
1437 | 1467 |
1438 | 1468 |
1439 } // namespace disasm | 1469 } // namespace disasm |
1440 | 1470 |
1441 #endif // V8_TARGET_ARCH_ARM | 1471 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |