| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 8 #if defined(TARGET_ARCH_ARM64) | 8 #if defined(TARGET_ARCH_ARM64) |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 | 10 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 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, R31Type r31t); | 33 void PrintRegister(int reg, R31Type r31t); |
| 34 void PrintVRegister(int reg); | 34 void PrintVRegister(int reg); |
| 35 void PrintShiftExtendRm(Instr* instr); | 35 void PrintShiftExtendRm(Instr* instr); |
| 36 void PrintMemOperand(Instr* instr); | 36 void PrintMemOperand(Instr* instr); |
| 37 void PrintPairMemOperand(Instr* instr); |
| 37 void PrintS(Instr* instr); | 38 void PrintS(Instr* instr); |
| 38 void PrintCondition(Instr* instr); | 39 void PrintCondition(Instr* instr); |
| 39 | 40 |
| 40 // Handle formatting of instructions and their options. | 41 // Handle formatting of instructions and their options. |
| 41 int FormatRegister(Instr* instr, const char* option); | 42 int FormatRegister(Instr* instr, const char* option); |
| 42 int FormatVRegister(Instr*instr, const char* option); | 43 int FormatVRegister(Instr*instr, const char* option); |
| 43 int FormatOption(Instr* instr, const char* format); | 44 int FormatOption(Instr* instr, const char* format); |
| 44 void Format(Instr* instr, const char* format); | 45 void Format(Instr* instr, const char* format); |
| 45 void Unknown(Instr* instr); | 46 void Unknown(Instr* instr); |
| 46 | 47 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 210 } |
| 210 Print("]"); | 211 Print("]"); |
| 211 } else { | 212 } else { |
| 212 switch (instr->Bits(10, 2)) { | 213 switch (instr->Bits(10, 2)) { |
| 213 case 0: { | 214 case 0: { |
| 214 // rn + signed 9-bit immediate, pre-index, no writeback. | 215 // rn + signed 9-bit immediate, pre-index, no writeback. |
| 215 const int32_t imm9 = instr->SImm9Field(); | 216 const int32_t imm9 = instr->SImm9Field(); |
| 216 Print("["); | 217 Print("["); |
| 217 PrintRegister(rn, R31IsSP); | 218 PrintRegister(rn, R31IsSP); |
| 218 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 219 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 219 remaining_size_in_buffer(), | 220 remaining_size_in_buffer(), |
| 220 ", #%d", | 221 ", #%d", |
| 221 imm9); | 222 imm9); |
| 222 Print("]"); | 223 Print("]"); |
| 223 break; | 224 break; |
| 224 } | 225 } |
| 225 case 1: { | 226 case 1: { |
| 226 const int32_t imm9 = instr->SImm9Field(); | 227 const int32_t imm9 = instr->SImm9Field(); |
| 227 // rn + signed 9-bit immediate, post-index, writeback. | 228 // rn + signed 9-bit immediate, post-index, writeback. |
| 228 Print("["); | 229 Print("["); |
| 229 PrintRegister(rn, R31IsSP); | 230 PrintRegister(rn, R31IsSP); |
| 230 Print("]"); | 231 Print("]"); |
| 231 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 232 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 break; | 266 break; |
| 266 } | 267 } |
| 267 default: { | 268 default: { |
| 268 Print("???"); | 269 Print("???"); |
| 269 } | 270 } |
| 270 } | 271 } |
| 271 } | 272 } |
| 272 } | 273 } |
| 273 | 274 |
| 274 | 275 |
| 276 void ARM64Decoder::PrintPairMemOperand(Instr* instr) { |
| 277 const Register rn = instr->RnField(); |
| 278 const int32_t simm7 = instr->SImm7Field(); |
| 279 const int32_t offset = simm7 << (2 + instr->Bit(31)); |
| 280 Print("["); |
| 281 PrintRegister(rn, R31IsSP); |
| 282 switch (instr->Bits(23, 3)) { |
| 283 case 1: |
| 284 // rn + (imm7 << (2 + B31)), post-index, writeback. |
| 285 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 286 remaining_size_in_buffer(), |
| 287 "], #%d !", |
| 288 offset); |
| 289 break; |
| 290 case 2: |
| 291 // rn + (imm7 << (2 + B31)), pre-index, no writeback. |
| 292 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 293 remaining_size_in_buffer(), |
| 294 ", #%d ]", |
| 295 offset); |
| 296 break; |
| 297 case 3: |
| 298 // rn + (imm7 << (2 + B31)), pre-index, writeback. |
| 299 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 300 remaining_size_in_buffer(), |
| 301 ", #%d ]!", |
| 302 offset); |
| 303 break; |
| 304 default: |
| 305 Print(", ???]"); |
| 306 break; |
| 307 } |
| 308 } |
| 309 |
| 310 |
| 275 // Handle all register based formatting in these functions to reduce the | 311 // Handle all register based formatting in these functions to reduce the |
| 276 // complexity of FormatOption. | 312 // complexity of FormatOption. |
| 277 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { | 313 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { |
| 278 ASSERT(format[0] == 'r'); | 314 ASSERT(format[0] == 'r'); |
| 279 if (format[1] == 'n') { // 'rn: Rn register | 315 if (format[1] == 'n') { // 'rn: Rn register |
| 280 int reg = instr->RnField(); | 316 int reg = instr->RnField(); |
| 281 PrintRegister(reg, instr->RnMode()); | 317 PrintRegister(reg, instr->RnMode()); |
| 282 return 2; | 318 return 2; |
| 283 } else if (format[1] == 'd') { // 'rd: Rd register | 319 } else if (format[1] == 'd') { // 'rd: Rd register |
| 284 int reg = instr->RdField(); | 320 int reg = instr->RdField(); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 dimm); | 540 dimm); |
| 505 return 4; | 541 return 4; |
| 506 } | 542 } |
| 507 } | 543 } |
| 508 case 'm': { | 544 case 'm': { |
| 509 ASSERT(STRING_STARTS_WITH(format, "memop")); | 545 ASSERT(STRING_STARTS_WITH(format, "memop")); |
| 510 PrintMemOperand(instr); | 546 PrintMemOperand(instr); |
| 511 return 5; | 547 return 5; |
| 512 } | 548 } |
| 513 case 'p': { | 549 case 'p': { |
| 514 if (format[2] == 'a') { | 550 if (format[1] == 'c') { |
| 515 ASSERT(STRING_STARTS_WITH(format, "pcadr")); | 551 if (format[2] == 'a') { |
| 516 const int64_t immhi = instr->SImm19Field(); | 552 ASSERT(STRING_STARTS_WITH(format, "pcadr")); |
| 517 const int64_t immlo = instr->Bits(29, 2); | 553 const int64_t immhi = instr->SImm19Field(); |
| 518 const int64_t off = (immhi << 2) | immlo; | 554 const int64_t immlo = instr->Bits(29, 2); |
| 519 const int64_t pc = reinterpret_cast<int64_t>(instr); | 555 const int64_t off = (immhi << 2) | immlo; |
| 520 const int64_t dest = pc + off; | 556 const int64_t pc = reinterpret_cast<int64_t>(instr); |
| 521 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 557 const int64_t dest = pc + off; |
| 522 remaining_size_in_buffer(), | 558 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 523 "0x%"Px64, | 559 remaining_size_in_buffer(), |
| 524 dest); | 560 "0x%"Px64, |
| 561 dest); |
| 562 } else { |
| 563 ASSERT(STRING_STARTS_WITH(format, "pcldr")); |
| 564 const int64_t off = instr->SImm19Field() << 2; |
| 565 const int64_t pc = reinterpret_cast<int64_t>(instr); |
| 566 const int64_t dest = pc + off; |
| 567 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 568 remaining_size_in_buffer(), |
| 569 "0x%"Px64, |
| 570 dest); |
| 571 } |
| 572 return 5; |
| 525 } else { | 573 } else { |
| 526 ASSERT(STRING_STARTS_WITH(format, "pcldr")); | 574 ASSERT(STRING_STARTS_WITH(format, "pmemop")); |
| 527 const int64_t off = instr->SImm19Field() << 2; | 575 PrintPairMemOperand(instr); |
| 528 const int64_t pc = reinterpret_cast<int64_t>(instr); | 576 return 6; |
| 529 const int64_t dest = pc + off; | |
| 530 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | |
| 531 remaining_size_in_buffer(), | |
| 532 "0x%"Px64, | |
| 533 dest); | |
| 534 } | 577 } |
| 535 return 5; | |
| 536 } | 578 } |
| 537 case 'r': { | 579 case 'r': { |
| 538 return FormatRegister(instr, format); | 580 return FormatRegister(instr, format); |
| 539 } | 581 } |
| 540 case 'v': { | 582 case 'v': { |
| 541 if (format[1] == 's') { | 583 if (format[1] == 's') { |
| 542 ASSERT(STRING_STARTS_WITH(format, "vsz")); | 584 ASSERT(STRING_STARTS_WITH(format, "vsz")); |
| 543 char const* sz_str = NULL; | 585 char const* sz_str = NULL; |
| 544 if (instr->Bits(14, 2) == 3) { | 586 if (instr->Bits(14, 2) == 3) { |
| 545 switch (instr->Bit(22)) { | 587 switch (instr->Bit(22)) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 // Integer src/dst. | 709 // Integer src/dst. |
| 668 if (instr->Bits(22, 2) == 0) { | 710 if (instr->Bits(22, 2) == 0) { |
| 669 Format(instr, "str'sz 'rt, 'memop"); | 711 Format(instr, "str'sz 'rt, 'memop"); |
| 670 } else { | 712 } else { |
| 671 Format(instr, "ldr'sz 'rt, 'memop"); | 713 Format(instr, "ldr'sz 'rt, 'memop"); |
| 672 } | 714 } |
| 673 } | 715 } |
| 674 } | 716 } |
| 675 | 717 |
| 676 | 718 |
| 719 void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) { |
| 720 if (instr->Bit(22) == 1) { |
| 721 // Load. |
| 722 Format(instr, "ldp'sf 'rt, 'ra, 'pmemop"); |
| 723 } else { |
| 724 // Store. |
| 725 Format(instr, "stp'sf 'rt, 'ra, 'pmemop"); |
| 726 } |
| 727 } |
| 728 |
| 729 |
| 677 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { | 730 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { |
| 678 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || | 731 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || |
| 679 (instr->Bits(24, 3) != 0)) { | 732 (instr->Bits(24, 3) != 0)) { |
| 680 Unknown(instr); | 733 Unknown(instr); |
| 681 } | 734 } |
| 682 if (instr->Bit(30)) { | 735 if (instr->Bit(30)) { |
| 683 Format(instr, "ldrx 'rt, 'pcldr"); | 736 Format(instr, "ldrx 'rt, 'pcldr"); |
| 684 } else { | 737 } else { |
| 685 Format(instr, "ldrw 'rt, 'pcldr"); | 738 Format(instr, "ldrw 'rt, 'pcldr"); |
| 686 } | 739 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 DecodeUnconditionalBranch(instr); | 927 DecodeUnconditionalBranch(instr); |
| 875 } else { | 928 } else { |
| 876 Unknown(instr); | 929 Unknown(instr); |
| 877 } | 930 } |
| 878 } | 931 } |
| 879 | 932 |
| 880 | 933 |
| 881 void ARM64Decoder::DecodeLoadStore(Instr* instr) { | 934 void ARM64Decoder::DecodeLoadStore(Instr* instr) { |
| 882 if (instr->IsLoadStoreRegOp()) { | 935 if (instr->IsLoadStoreRegOp()) { |
| 883 DecodeLoadStoreReg(instr); | 936 DecodeLoadStoreReg(instr); |
| 937 } else if (instr->IsLoadStoreRegPairOp()) { |
| 938 DecodeLoadStoreRegPair(instr); |
| 884 } else if (instr->IsLoadRegLiteralOp()) { | 939 } else if (instr->IsLoadRegLiteralOp()) { |
| 885 DecodeLoadRegLiteral(instr); | 940 DecodeLoadRegLiteral(instr); |
| 886 } else { | 941 } else { |
| 887 Unknown(instr); | 942 Unknown(instr); |
| 888 } | 943 } |
| 889 } | 944 } |
| 890 | 945 |
| 891 | 946 |
| 892 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { | 947 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { |
| 893 switch (instr->Bit(30)) { | 948 switch (instr->Bit(30)) { |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 human_buffer, | 1441 human_buffer, |
| 1387 sizeof(human_buffer), | 1442 sizeof(human_buffer), |
| 1388 pc); | 1443 pc); |
| 1389 pc += instruction_length; | 1444 pc += instruction_length; |
| 1390 } | 1445 } |
| 1391 } | 1446 } |
| 1392 | 1447 |
| 1393 } // namespace dart | 1448 } // namespace dart |
| 1394 | 1449 |
| 1395 #endif // defined TARGET_ARCH_ARM | 1450 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |