| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/disassembler.h" | 5 #include "vm/disassembler.h" |
| 6 | 6 |
| 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 8 #if defined(TARGET_ARCH_ARM) | 8 #if defined(TARGET_ARCH_ARM) |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 void InstructionDecode(uword pc); | 26 void InstructionDecode(uword pc); |
| 27 | 27 |
| 28 private: | 28 private: |
| 29 // Bottleneck functions to print into the out_buffer. | 29 // Bottleneck functions to print into the out_buffer. |
| 30 void Print(const char* str); | 30 void Print(const char* str); |
| 31 | 31 |
| 32 // Printing of common values. | 32 // Printing of common values. |
| 33 void PrintRegister(int reg); | 33 void PrintRegister(int reg); |
| 34 void PrintSRegister(int reg); | 34 void PrintSRegister(int reg); |
| 35 void PrintDRegister(int reg); | 35 void PrintDRegister(int reg); |
| 36 void PrintDRegisterList(int start, int reg_count); |
| 36 void PrintQRegister(int reg); | 37 void PrintQRegister(int reg); |
| 37 void PrintCondition(Instr* instr); | 38 void PrintCondition(Instr* instr); |
| 38 void PrintShiftRm(Instr* instr); | 39 void PrintShiftRm(Instr* instr); |
| 39 void PrintShiftImm(Instr* instr); | 40 void PrintShiftImm(Instr* instr); |
| 40 void PrintPU(Instr* instr); | 41 void PrintPU(Instr* instr); |
| 41 | 42 |
| 42 // Handle formatting of instructions and their options. | 43 // Handle formatting of instructions and their options. |
| 43 int FormatRegister(Instr* instr, const char* option); | 44 int FormatRegister(Instr* instr, const char* option); |
| 44 int FormatSRegister(Instr* instr, const char* option); | 45 int FormatSRegister(Instr* instr, const char* option); |
| 45 int FormatDRegister(Instr* instr, const char* option); | 46 int FormatDRegister(Instr* instr, const char* option); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 Print("}"); | 326 Print("}"); |
| 326 return 5; | 327 return 5; |
| 327 } | 328 } |
| 328 UNREACHABLE(); | 329 UNREACHABLE(); |
| 329 return -1; | 330 return -1; |
| 330 } | 331 } |
| 331 | 332 |
| 332 | 333 |
| 334 void ARMDecoder::PrintDRegisterList(int start, int reg_count) { |
| 335 Print("{"); |
| 336 for (int i = start; i < start + reg_count; i++) { |
| 337 PrintDRegister(i); |
| 338 if (i != start + reg_count - 1) { |
| 339 Print(", "); |
| 340 } |
| 341 } |
| 342 Print("}"); |
| 343 } |
| 344 |
| 345 |
| 333 int ARMDecoder::FormatDRegister(Instr* instr, const char* format) { | 346 int ARMDecoder::FormatDRegister(Instr* instr, const char* format) { |
| 334 ASSERT(format[0] == 'd'); | 347 ASSERT(format[0] == 'd'); |
| 335 if (format[1] == 'n') { // 'dn: Dn register | 348 if (format[1] == 'n') { // 'dn: Dn register |
| 336 int reg = instr->DnField(); | 349 int reg = instr->DnField(); |
| 337 PrintDRegister(reg); | 350 PrintDRegister(reg); |
| 338 return 2; | 351 return 2; |
| 339 } else if (format[1] == 'd') { // 'dd: Dd register | 352 } else if (format[1] == 'd') { // 'dd: Dd register |
| 340 int reg = instr->DdField(); | 353 int reg = instr->DdField(); |
| 341 PrintDRegister(reg); | 354 PrintDRegister(reg); |
| 342 return 2; | 355 return 2; |
| 343 } else if (format[1] == 'm') { // 'dm: Dm register | 356 } else if (format[1] == 'm') { // 'dm: Dm register |
| 344 int reg = instr->DmField(); | 357 int reg = instr->DmField(); |
| 345 PrintDRegister(reg); | 358 PrintDRegister(reg); |
| 346 return 2; | 359 return 2; |
| 347 } else if (format[1] == 'l') { | 360 } else if (format[1] == 'l') { |
| 348 ASSERT(STRING_STARTS_WITH(format, "dlist")); | 361 ASSERT(STRING_STARTS_WITH(format, "dlist")); |
| 349 int reg_count = instr->Bits(0, 8) >> 1; | 362 int reg_count = instr->Bits(0, 8) >> 1; |
| 350 int start = (instr->Bit(22) << 4) | instr->Bits(12, 4); | 363 int start = (instr->Bit(22) << 4) | instr->Bits(12, 4); |
| 351 Print("{"); | 364 PrintDRegisterList(start, reg_count); |
| 352 for (int i = start; i < start + reg_count; i++) { | |
| 353 PrintDRegister(i); | |
| 354 if (i != start + reg_count - 1) { | |
| 355 Print(", "); | |
| 356 } | |
| 357 } | |
| 358 Print("}"); | |
| 359 return 5; | 365 return 5; |
| 366 } else if (format[1] == 't') { |
| 367 ASSERT(STRING_STARTS_WITH(format, "dtbllist")); |
| 368 int reg_count = instr->Bits(8, 2) + 1; |
| 369 int start = (instr->Bit(7) << 4) | instr->Bits(16, 4); |
| 370 PrintDRegisterList(start, reg_count); |
| 371 return 8; |
| 360 } | 372 } |
| 361 UNREACHABLE(); | 373 UNREACHABLE(); |
| 362 return -1; | 374 return -1; |
| 363 } | 375 } |
| 364 | 376 |
| 365 | 377 |
| 366 int ARMDecoder::FormatQRegister(Instr* instr, const char* format) { | 378 int ARMDecoder::FormatQRegister(Instr* instr, const char* format) { |
| 367 ASSERT(format[0] == 'q'); | 379 ASSERT(format[0] == 'q'); |
| 368 if (format[1] == 'n') { // 'qn: Qn register | 380 if (format[1] == 'n') { // 'qn: Qn register |
| 369 int reg = instr->QnField(); | 381 int reg = instr->QnField(); |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1292 } else if ((instr->Bits(8, 4) == 9) && (instr->Bit(4) == 1) && | 1304 } else if ((instr->Bits(8, 4) == 9) && (instr->Bit(4) == 1) && |
| 1293 (instr->Bits(23, 2) == 0)) { | 1305 (instr->Bits(23, 2) == 0)) { |
| 1294 Format(instr, "vmulq'sz 'qd, 'qn, 'qm"); | 1306 Format(instr, "vmulq'sz 'qd, 'qn, 'qm"); |
| 1295 } else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 1) && | 1307 } else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 1) && |
| 1296 (instr->Bits(23, 2) == 2) && (instr->Bit(21) == 0)) { | 1308 (instr->Bits(23, 2) == 2) && (instr->Bit(21) == 0)) { |
| 1297 Format(instr, "vmulqs 'qd, 'qn, 'qm"); | 1309 Format(instr, "vmulqs 'qd, 'qn, 'qm"); |
| 1298 } else { | 1310 } else { |
| 1299 Unknown(instr); | 1311 Unknown(instr); |
| 1300 } | 1312 } |
| 1301 } else { | 1313 } else { |
| 1302 Unknown(instr); | 1314 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) && |
| 1315 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) { |
| 1316 Format(instr, "vtbl 'dd, 'dtbllist, 'dm"); |
| 1317 } else { |
| 1318 Unknown(instr); |
| 1319 } |
| 1303 } | 1320 } |
| 1304 } | 1321 } |
| 1305 | 1322 |
| 1306 | 1323 |
| 1307 void ARMDecoder::InstructionDecode(uword pc) { | 1324 void ARMDecoder::InstructionDecode(uword pc) { |
| 1308 Instr* instr = Instr::At(pc); | 1325 Instr* instr = Instr::At(pc); |
| 1309 | 1326 |
| 1310 if (instr->ConditionField() == kSpecialCondition) { | 1327 if (instr->ConditionField() == kSpecialCondition) { |
| 1311 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) { | 1328 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) { |
| 1312 Format(instr, "clrex"); | 1329 Format(instr, "clrex"); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 human_buffer, | 1416 human_buffer, |
| 1400 sizeof(human_buffer), | 1417 sizeof(human_buffer), |
| 1401 pc); | 1418 pc); |
| 1402 pc += instruction_length; | 1419 pc += instruction_length; |
| 1403 } | 1420 } |
| 1404 } | 1421 } |
| 1405 | 1422 |
| 1406 } // namespace dart | 1423 } // namespace dart |
| 1407 | 1424 |
| 1408 #endif // defined TARGET_ARCH_ARM | 1425 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |