| 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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 int64_t off = instr->SImm19Field() << 2; | 380 int64_t off = instr->SImm19Field() << 2; |
| 381 uword destination = reinterpret_cast<uword>(instr) + off; | 381 uword destination = reinterpret_cast<uword>(instr) + off; |
| 382 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 382 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 383 remaining_size_in_buffer(), | 383 remaining_size_in_buffer(), |
| 384 "%#" Px "", | 384 "%#" Px "", |
| 385 destination); | 385 destination); |
| 386 } | 386 } |
| 387 } | 387 } |
| 388 return 6; | 388 return 6; |
| 389 } | 389 } |
| 390 case 'f': { |
| 391 ASSERT(STRING_STARTS_WITH(format, "fsz")); |
| 392 const int sz = instr->SzField(); |
| 393 char const* sz_str; |
| 394 switch (sz) { |
| 395 case 0: |
| 396 if (instr->Bit(23) == 1) { |
| 397 sz_str = "q"; |
| 398 } else { |
| 399 sz_str = "b"; |
| 400 } |
| 401 break; |
| 402 case 1: sz_str = "h"; break; |
| 403 case 2: sz_str = "s"; break; |
| 404 case 3: sz_str = "d"; break; |
| 405 default: sz_str = "?"; break; |
| 406 } |
| 407 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 408 remaining_size_in_buffer(), |
| 409 "%s", |
| 410 sz_str); |
| 411 return 3; |
| 412 } |
| 390 case 'h': { | 413 case 'h': { |
| 391 ASSERT(STRING_STARTS_WITH(format, "hw")); | 414 ASSERT(STRING_STARTS_WITH(format, "hw")); |
| 392 const int shift = instr->HWField() << 4; | 415 const int shift = instr->HWField() << 4; |
| 393 if (shift != 0) { | 416 if (shift != 0) { |
| 394 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 417 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 395 remaining_size_in_buffer(), | 418 remaining_size_in_buffer(), |
| 396 "lsl %d", | 419 "lsl %d", |
| 397 shift); | 420 shift); |
| 398 } | 421 } |
| 399 return 2; | 422 return 2; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 Format(instr, "movk'sf 'rd, 'imm16 'hw"); | 578 Format(instr, "movk'sf 'rd, 'imm16 'hw"); |
| 556 break; | 579 break; |
| 557 default: | 580 default: |
| 558 Unknown(instr); | 581 Unknown(instr); |
| 559 break; | 582 break; |
| 560 } | 583 } |
| 561 } | 584 } |
| 562 | 585 |
| 563 | 586 |
| 564 void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) { | 587 void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) { |
| 565 if (instr->Bit(23) != 0) { | |
| 566 // 128-bit ldr/str. | |
| 567 Unknown(instr); | |
| 568 } | |
| 569 if (instr->Bit(26) == 1) { | 588 if (instr->Bit(26) == 1) { |
| 570 if (instr->Bits(30, 2) != 3) { | |
| 571 // Only 64-bit double variant supported. | |
| 572 Unknown(instr); | |
| 573 } | |
| 574 // SIMD or FP src/dst. | 589 // SIMD or FP src/dst. |
| 575 if (instr->Bit(22) == 1) { | 590 if (instr->Bit(22) == 1) { |
| 576 Format(instr, "fldrd 'vt, 'memop"); | 591 Format(instr, "fldr'fsz 'vt, 'memop"); |
| 577 } else { | 592 } else { |
| 578 Format(instr, "fstrd 'vt, 'memop"); | 593 Format(instr, "fstr'fsz 'vt, 'memop"); |
| 579 } | 594 } |
| 580 } else { | 595 } else { |
| 581 // Integer src/dst. | 596 // Integer src/dst. |
| 582 if (instr->Bit(22) == 1) { | 597 if (instr->Bits(22, 2) == 0) { |
| 598 Format(instr, "str'sz 'rt, 'memop"); |
| 599 } else { |
| 583 Format(instr, "ldr'sz 'rt, 'memop"); | 600 Format(instr, "ldr'sz 'rt, 'memop"); |
| 584 } else { | |
| 585 Format(instr, "str'sz 'rt, 'memop"); | |
| 586 } | 601 } |
| 587 } | 602 } |
| 588 } | 603 } |
| 589 | 604 |
| 590 | 605 |
| 591 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { | 606 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { |
| 592 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || | 607 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || |
| 593 (instr->Bits(24, 3) != 0)) { | 608 (instr->Bits(24, 3) != 0)) { |
| 594 Unknown(instr); | 609 Unknown(instr); |
| 595 } | 610 } |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 Format(instr, "fmovdr 'vd, 'rn"); | 995 Format(instr, "fmovdr 'vd, 'rn"); |
| 981 } else if (instr->Bits(16, 5) == 24) { | 996 } else if (instr->Bits(16, 5) == 24) { |
| 982 Format(instr, "fcvtzds 'rd, 'vn"); | 997 Format(instr, "fcvtzds 'rd, 'vn"); |
| 983 } else { | 998 } else { |
| 984 Unknown(instr); | 999 Unknown(instr); |
| 985 } | 1000 } |
| 986 } | 1001 } |
| 987 | 1002 |
| 988 | 1003 |
| 989 void ARM64Decoder::DecodeFPOneSource(Instr* instr) { | 1004 void ARM64Decoder::DecodeFPOneSource(Instr* instr) { |
| 990 const int opc = instr->Bits(15, 2); | 1005 const int opc = instr->Bits(15, 6); |
| 1006 |
| 1007 if ((opc != 5) && (instr->Bit(22) != 1)) { |
| 1008 // Source is interpreted as single-precision only if we're doing a |
| 1009 // conversion from single -> double. |
| 1010 Unknown(instr); |
| 1011 return; |
| 1012 } |
| 991 | 1013 |
| 992 switch (opc) { | 1014 switch (opc) { |
| 993 case 0: | 1015 case 0: |
| 994 Format(instr, "fmovdd 'vd, 'vn"); | 1016 Format(instr, "fmovdd 'vd, 'vn"); |
| 995 break; | 1017 break; |
| 996 case 1: | 1018 case 1: |
| 997 Format(instr, "fabsd 'vd, 'vn"); | 1019 Format(instr, "fabsd 'vd, 'vn"); |
| 998 break; | 1020 break; |
| 999 case 2: | 1021 case 2: |
| 1000 Format(instr, "fnegd 'vd, 'vn"); | 1022 Format(instr, "fnegd 'vd, 'vn"); |
| 1001 break; | 1023 break; |
| 1002 case 3: | 1024 case 3: |
| 1003 Format(instr, "fsqrtd 'vd, 'vn"); | 1025 Format(instr, "fsqrtd 'vd, 'vn"); |
| 1004 break; | 1026 break; |
| 1027 case 4: |
| 1028 Format(instr, "fcvtsd 'vd, 'vn"); |
| 1029 break; |
| 1030 case 5: |
| 1031 Format(instr, "fcvtds 'vd, 'vn"); |
| 1032 break; |
| 1005 default: | 1033 default: |
| 1006 UNREACHABLE(); | 1034 Unknown(instr); |
| 1007 break; | 1035 break; |
| 1008 } | 1036 } |
| 1009 } | 1037 } |
| 1010 | 1038 |
| 1011 | 1039 |
| 1012 void ARM64Decoder::DecodeFPTwoSource(Instr* instr) { | 1040 void ARM64Decoder::DecodeFPTwoSource(Instr* instr) { |
| 1013 if (instr->Bits(22, 2) != 1) { | 1041 if (instr->Bits(22, 2) != 1) { |
| 1014 Unknown(instr); | 1042 Unknown(instr); |
| 1015 return; | 1043 return; |
| 1016 } | 1044 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 human_buffer, | 1167 human_buffer, |
| 1140 sizeof(human_buffer), | 1168 sizeof(human_buffer), |
| 1141 pc); | 1169 pc); |
| 1142 pc += instruction_length; | 1170 pc += instruction_length; |
| 1143 } | 1171 } |
| 1144 } | 1172 } |
| 1145 | 1173 |
| 1146 } // namespace dart | 1174 } // namespace dart |
| 1147 | 1175 |
| 1148 #endif // defined TARGET_ARCH_ARM | 1176 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |