| 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 #include "vm/instructions.h" | 10 #include "vm/instructions.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 int FormatVRegister(Instr* instr, const char* option); | 44 int FormatVRegister(Instr* instr, const char* option); |
| 45 int FormatOption(Instr* instr, const char* format); | 45 int FormatOption(Instr* instr, const char* format); |
| 46 void Format(Instr* instr, const char* format); | 46 void Format(Instr* instr, const char* format); |
| 47 void Unknown(Instr* instr); | 47 void Unknown(Instr* instr); |
| 48 | 48 |
| 49 // Decode instructions. | 49 // Decode instructions. |
| 50 #define DECODE_OP(op) void Decode##op(Instr* instr); | 50 #define DECODE_OP(op) void Decode##op(Instr* instr); |
| 51 APPLY_OP_LIST(DECODE_OP) | 51 APPLY_OP_LIST(DECODE_OP) |
| 52 #undef DECODE_OP | 52 #undef DECODE_OP |
| 53 | 53 |
| 54 | |
| 55 // Convenience functions. | 54 // Convenience functions. |
| 56 char* get_buffer() const { return buffer_; } | 55 char* get_buffer() const { return buffer_; } |
| 57 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } | 56 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } |
| 58 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } | 57 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } |
| 59 | 58 |
| 60 char* buffer_; // Decode instructions into this buffer. | 59 char* buffer_; // Decode instructions into this buffer. |
| 61 size_t buffer_size_; // The size of the character buffer. | 60 size_t buffer_size_; // The size of the character buffer. |
| 62 size_t buffer_pos_; // Current character position in buffer. | 61 size_t buffer_pos_; // Current character position in buffer. |
| 63 | 62 |
| 64 DISALLOW_ALLOCATION(); | 63 DISALLOW_ALLOCATION(); |
| 65 DISALLOW_COPY_AND_ASSIGN(ARM64Decoder); | 64 DISALLOW_COPY_AND_ASSIGN(ARM64Decoder); |
| 66 }; | 65 }; |
| 67 | 66 |
| 68 | |
| 69 // Support for assertions in the ARM64Decoder formatting functions. | 67 // Support for assertions in the ARM64Decoder formatting functions. |
| 70 #define STRING_STARTS_WITH(string, compare_string) \ | 68 #define STRING_STARTS_WITH(string, compare_string) \ |
| 71 (strncmp(string, compare_string, strlen(compare_string)) == 0) | 69 (strncmp(string, compare_string, strlen(compare_string)) == 0) |
| 72 | 70 |
| 73 | |
| 74 // Append the str to the output buffer. | 71 // Append the str to the output buffer. |
| 75 void ARM64Decoder::Print(const char* str) { | 72 void ARM64Decoder::Print(const char* str) { |
| 76 char cur = *str++; | 73 char cur = *str++; |
| 77 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { | 74 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { |
| 78 buffer_[buffer_pos_++] = cur; | 75 buffer_[buffer_pos_++] = cur; |
| 79 cur = *str++; | 76 cur = *str++; |
| 80 } | 77 } |
| 81 buffer_[buffer_pos_] = '\0'; | 78 buffer_[buffer_pos_] = '\0'; |
| 82 } | 79 } |
| 83 | 80 |
| 84 | |
| 85 // These register names are defined in a way to match the native disassembler | 81 // These register names are defined in a way to match the native disassembler |
| 86 // formatting, except for register aliases ctx (r9), pp (r10) and sp (r19). | 82 // formatting, except for register aliases ctx (r9), pp (r10) and sp (r19). |
| 87 // See for example the command "objdump -d <binary file>". | 83 // See for example the command "objdump -d <binary file>". |
| 88 static const char* reg_names[kNumberOfCpuRegisters] = { | 84 static const char* reg_names[kNumberOfCpuRegisters] = { |
| 89 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", | 85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", |
| 90 "r11", "r12", "r13", "r14", "r15", "ip0", "ip1", "r18", "sp", "r20", "r21", | 86 "r11", "r12", "r13", "r14", "r15", "ip0", "ip1", "r18", "sp", "r20", "r21", |
| 91 "r22", "r23", "r24", "r25", "thr", "pp", "ctx", "fp", "lr", "r31", | 87 "r22", "r23", "r24", "r25", "thr", "pp", "ctx", "fp", "lr", "r31", |
| 92 }; | 88 }; |
| 93 | 89 |
| 94 | |
| 95 // Print the register name according to the active name converter. | 90 // Print the register name according to the active name converter. |
| 96 void ARM64Decoder::PrintRegister(int reg, R31Type r31t) { | 91 void ARM64Decoder::PrintRegister(int reg, R31Type r31t) { |
| 97 ASSERT(0 <= reg); | 92 ASSERT(0 <= reg); |
| 98 ASSERT(reg < kNumberOfCpuRegisters); | 93 ASSERT(reg < kNumberOfCpuRegisters); |
| 99 if (reg == 31) { | 94 if (reg == 31) { |
| 100 const char* rstr = (r31t == R31IsZR) ? "zr" : "csp"; | 95 const char* rstr = (r31t == R31IsZR) ? "zr" : "csp"; |
| 101 Print(rstr); | 96 Print(rstr); |
| 102 } else { | 97 } else { |
| 103 Print(reg_names[reg]); | 98 Print(reg_names[reg]); |
| 104 } | 99 } |
| 105 } | 100 } |
| 106 | 101 |
| 107 | |
| 108 void ARM64Decoder::PrintVRegister(int reg) { | 102 void ARM64Decoder::PrintVRegister(int reg) { |
| 109 ASSERT(0 <= reg); | 103 ASSERT(0 <= reg); |
| 110 ASSERT(reg < kNumberOfVRegisters); | 104 ASSERT(reg < kNumberOfVRegisters); |
| 111 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 105 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 112 remaining_size_in_buffer(), "v%d", reg); | 106 remaining_size_in_buffer(), "v%d", reg); |
| 113 } | 107 } |
| 114 | 108 |
| 115 | |
| 116 // These shift names are defined in a way to match the native disassembler | 109 // These shift names are defined in a way to match the native disassembler |
| 117 // formatting. See for example the command "objdump -d <binary file>". | 110 // formatting. See for example the command "objdump -d <binary file>". |
| 118 static const char* shift_names[kMaxShift] = {"lsl", "lsr", "asr", "ror"}; | 111 static const char* shift_names[kMaxShift] = {"lsl", "lsr", "asr", "ror"}; |
| 119 | 112 |
| 120 | |
| 121 static const char* extend_names[kMaxExtend] = { | 113 static const char* extend_names[kMaxExtend] = { |
| 122 "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx", | 114 "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx", |
| 123 }; | 115 }; |
| 124 | 116 |
| 125 | |
| 126 // These condition names are defined in a way to match the native disassembler | 117 // These condition names are defined in a way to match the native disassembler |
| 127 // formatting. See for example the command "objdump -d <binary file>". | 118 // formatting. See for example the command "objdump -d <binary file>". |
| 128 static const char* cond_names[kNumberOfConditions] = { | 119 static const char* cond_names[kNumberOfConditions] = { |
| 129 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", | 120 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", |
| 130 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", | 121 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", |
| 131 }; | 122 }; |
| 132 | 123 |
| 133 | |
| 134 // Print the condition guarding the instruction. | 124 // Print the condition guarding the instruction. |
| 135 void ARM64Decoder::PrintCondition(Instr* instr) { | 125 void ARM64Decoder::PrintCondition(Instr* instr) { |
| 136 if (instr->IsConditionalSelectOp()) { | 126 if (instr->IsConditionalSelectOp()) { |
| 137 Print(cond_names[instr->SelectConditionField()]); | 127 Print(cond_names[instr->SelectConditionField()]); |
| 138 } else { | 128 } else { |
| 139 Print(cond_names[instr->ConditionField()]); | 129 Print(cond_names[instr->ConditionField()]); |
| 140 } | 130 } |
| 141 } | 131 } |
| 142 | 132 |
| 143 | |
| 144 // Print the register shift operands for the instruction. Generally used for | 133 // Print the register shift operands for the instruction. Generally used for |
| 145 // data processing instructions. | 134 // data processing instructions. |
| 146 void ARM64Decoder::PrintShiftExtendRm(Instr* instr) { | 135 void ARM64Decoder::PrintShiftExtendRm(Instr* instr) { |
| 147 int rm = instr->RmField(); | 136 int rm = instr->RmField(); |
| 148 Shift shift = instr->ShiftTypeField(); | 137 Shift shift = instr->ShiftTypeField(); |
| 149 int shift_amount = instr->ShiftAmountField(); | 138 int shift_amount = instr->ShiftAmountField(); |
| 150 Extend extend = instr->ExtendTypeField(); | 139 Extend extend = instr->ExtendTypeField(); |
| 151 int extend_shift_amount = instr->ExtShiftAmountField(); | 140 int extend_shift_amount = instr->ExtShiftAmountField(); |
| 152 | 141 |
| 153 PrintRegister(rm, R31IsZR); | 142 PrintRegister(rm, R31IsZR); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 176 if (((instr->SFField() == 1) && (extend == UXTX)) || | 165 if (((instr->SFField() == 1) && (extend == UXTX)) || |
| 177 ((instr->SFField() == 0) && (extend == UXTW))) { | 166 ((instr->SFField() == 0) && (extend == UXTW))) { |
| 178 // Shift amount. | 167 // Shift amount. |
| 179 buffer_pos_ += | 168 buffer_pos_ += |
| 180 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), | 169 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), |
| 181 " %d", extend_shift_amount); | 170 " %d", extend_shift_amount); |
| 182 } | 171 } |
| 183 } | 172 } |
| 184 } | 173 } |
| 185 | 174 |
| 186 | |
| 187 void ARM64Decoder::PrintMemOperand(Instr* instr) { | 175 void ARM64Decoder::PrintMemOperand(Instr* instr) { |
| 188 const Register rn = instr->RnField(); | 176 const Register rn = instr->RnField(); |
| 189 if (instr->Bit(24) == 1) { | 177 if (instr->Bit(24) == 1) { |
| 190 // rn + scaled unsigned 12-bit immediate offset. | 178 // rn + scaled unsigned 12-bit immediate offset. |
| 191 const uint32_t scale = instr->SzField(); | 179 const uint32_t scale = instr->SzField(); |
| 192 const uint32_t imm12 = instr->Imm12Field(); | 180 const uint32_t imm12 = instr->Imm12Field(); |
| 193 const uint32_t off = imm12 << scale; | 181 const uint32_t off = imm12 << scale; |
| 194 Print("["); | 182 Print("["); |
| 195 PrintRegister(rn, R31IsSP); | 183 PrintRegister(rn, R31IsSP); |
| 196 if (off != 0) { | 184 if (off != 0) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 233 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 246 remaining_size_in_buffer(), ", #%d", imm9); | 234 remaining_size_in_buffer(), ", #%d", imm9); |
| 247 Print("] !"); | 235 Print("] !"); |
| 248 break; | 236 break; |
| 249 } | 237 } |
| 250 default: { Print("???"); } | 238 default: { Print("???"); } |
| 251 } | 239 } |
| 252 } | 240 } |
| 253 } | 241 } |
| 254 | 242 |
| 255 | |
| 256 void ARM64Decoder::PrintPairMemOperand(Instr* instr) { | 243 void ARM64Decoder::PrintPairMemOperand(Instr* instr) { |
| 257 const Register rn = instr->RnField(); | 244 const Register rn = instr->RnField(); |
| 258 const int32_t simm7 = instr->SImm7Field(); | 245 const int32_t simm7 = instr->SImm7Field(); |
| 259 const int32_t offset = simm7 << (2 + instr->Bit(31)); | 246 const int32_t offset = simm7 << (2 + instr->Bit(31)); |
| 260 Print("["); | 247 Print("["); |
| 261 PrintRegister(rn, R31IsSP); | 248 PrintRegister(rn, R31IsSP); |
| 262 switch (instr->Bits(23, 3)) { | 249 switch (instr->Bits(23, 3)) { |
| 263 case 1: | 250 case 1: |
| 264 // rn + (imm7 << (2 + B31)), post-index, writeback. | 251 // rn + (imm7 << (2 + B31)), post-index, writeback. |
| 265 buffer_pos_ += | 252 buffer_pos_ += |
| (...skipping 10 matching lines...) Expand all Loading... |
| 276 buffer_pos_ += | 263 buffer_pos_ += |
| 277 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), | 264 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), |
| 278 ", #%d ]!", offset); | 265 ", #%d ]!", offset); |
| 279 break; | 266 break; |
| 280 default: | 267 default: |
| 281 Print(", ???]"); | 268 Print(", ???]"); |
| 282 break; | 269 break; |
| 283 } | 270 } |
| 284 } | 271 } |
| 285 | 272 |
| 286 | |
| 287 // Handle all register based formatting in these functions to reduce the | 273 // Handle all register based formatting in these functions to reduce the |
| 288 // complexity of FormatOption. | 274 // complexity of FormatOption. |
| 289 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { | 275 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { |
| 290 ASSERT(format[0] == 'r'); | 276 ASSERT(format[0] == 'r'); |
| 291 if (format[1] == 'n') { // 'rn: Rn register | 277 if (format[1] == 'n') { // 'rn: Rn register |
| 292 int reg = instr->RnField(); | 278 int reg = instr->RnField(); |
| 293 PrintRegister(reg, instr->RnMode()); | 279 PrintRegister(reg, instr->RnMode()); |
| 294 return 2; | 280 return 2; |
| 295 } else if (format[1] == 'd') { // 'rd: Rd register | 281 } else if (format[1] == 'd') { // 'rd: Rd register |
| 296 int reg = instr->RdField(); | 282 int reg = instr->RdField(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 310 return 2; | 296 return 2; |
| 311 } else if (format[1] == 's') { // 'rs: Rs register | 297 } else if (format[1] == 's') { // 'rs: Rs register |
| 312 int reg = instr->RsField(); | 298 int reg = instr->RsField(); |
| 313 PrintRegister(reg, R31IsZR); | 299 PrintRegister(reg, R31IsZR); |
| 314 return 2; | 300 return 2; |
| 315 } | 301 } |
| 316 UNREACHABLE(); | 302 UNREACHABLE(); |
| 317 return -1; | 303 return -1; |
| 318 } | 304 } |
| 319 | 305 |
| 320 | |
| 321 int ARM64Decoder::FormatVRegister(Instr* instr, const char* format) { | 306 int ARM64Decoder::FormatVRegister(Instr* instr, const char* format) { |
| 322 ASSERT(format[0] == 'v'); | 307 ASSERT(format[0] == 'v'); |
| 323 if (format[1] == 'd') { | 308 if (format[1] == 'd') { |
| 324 int reg = instr->VdField(); | 309 int reg = instr->VdField(); |
| 325 PrintVRegister(reg); | 310 PrintVRegister(reg); |
| 326 return 2; | 311 return 2; |
| 327 } else if (format[1] == 'n') { | 312 } else if (format[1] == 'n') { |
| 328 int reg = instr->VnField(); | 313 int reg = instr->VnField(); |
| 329 PrintVRegister(reg); | 314 PrintVRegister(reg); |
| 330 return 2; | 315 return 2; |
| 331 } else if (format[1] == 'm') { | 316 } else if (format[1] == 'm') { |
| 332 int reg = instr->VmField(); | 317 int reg = instr->VmField(); |
| 333 PrintVRegister(reg); | 318 PrintVRegister(reg); |
| 334 return 2; | 319 return 2; |
| 335 } else if (format[1] == 't') { | 320 } else if (format[1] == 't') { |
| 336 int reg = instr->VtField(); | 321 int reg = instr->VtField(); |
| 337 PrintVRegister(reg); | 322 PrintVRegister(reg); |
| 338 return 2; | 323 return 2; |
| 339 } | 324 } |
| 340 UNREACHABLE(); | 325 UNREACHABLE(); |
| 341 return -1; | 326 return -1; |
| 342 } | 327 } |
| 343 | 328 |
| 344 | |
| 345 // FormatOption takes a formatting string and interprets it based on | 329 // FormatOption takes a formatting string and interprets it based on |
| 346 // the current instructions. The format string points to the first | 330 // the current instructions. The format string points to the first |
| 347 // character of the option string (the option escape has already been | 331 // character of the option string (the option escape has already been |
| 348 // consumed by the caller.) FormatOption returns the number of | 332 // consumed by the caller.) FormatOption returns the number of |
| 349 // characters that were consumed from the formatting string. | 333 // characters that were consumed from the formatting string. |
| 350 int ARM64Decoder::FormatOption(Instr* instr, const char* format) { | 334 int ARM64Decoder::FormatOption(Instr* instr, const char* format) { |
| 351 switch (format[0]) { | 335 switch (format[0]) { |
| 352 case 'b': { | 336 case 'b': { |
| 353 if (format[3] == 'i') { | 337 if (format[3] == 'i') { |
| 354 ASSERT(STRING_STARTS_WITH(format, "bitimm")); | 338 ASSERT(STRING_STARTS_WITH(format, "bitimm")); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 } | 616 } |
| 633 default: { | 617 default: { |
| 634 UNREACHABLE(); | 618 UNREACHABLE(); |
| 635 break; | 619 break; |
| 636 } | 620 } |
| 637 } | 621 } |
| 638 UNREACHABLE(); | 622 UNREACHABLE(); |
| 639 return -1; | 623 return -1; |
| 640 } | 624 } |
| 641 | 625 |
| 642 | |
| 643 // Format takes a formatting string for a whole instruction and prints it into | 626 // Format takes a formatting string for a whole instruction and prints it into |
| 644 // the output buffer. All escaped options are handed to FormatOption to be | 627 // the output buffer. All escaped options are handed to FormatOption to be |
| 645 // parsed further. | 628 // parsed further. |
| 646 void ARM64Decoder::Format(Instr* instr, const char* format) { | 629 void ARM64Decoder::Format(Instr* instr, const char* format) { |
| 647 char cur = *format++; | 630 char cur = *format++; |
| 648 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) { | 631 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) { |
| 649 if (cur == '\'') { // Single quote is used as the formatting escape. | 632 if (cur == '\'') { // Single quote is used as the formatting escape. |
| 650 format += FormatOption(instr, format); | 633 format += FormatOption(instr, format); |
| 651 } else { | 634 } else { |
| 652 buffer_[buffer_pos_++] = cur; | 635 buffer_[buffer_pos_++] = cur; |
| 653 } | 636 } |
| 654 cur = *format++; | 637 cur = *format++; |
| 655 } | 638 } |
| 656 buffer_[buffer_pos_] = '\0'; | 639 buffer_[buffer_pos_] = '\0'; |
| 657 } | 640 } |
| 658 | 641 |
| 659 | |
| 660 // For currently unimplemented decodings the disassembler calls Unknown(instr) | 642 // For currently unimplemented decodings the disassembler calls Unknown(instr) |
| 661 // which will just print "unknown" of the instruction bits. | 643 // which will just print "unknown" of the instruction bits. |
| 662 void ARM64Decoder::Unknown(Instr* instr) { | 644 void ARM64Decoder::Unknown(Instr* instr) { |
| 663 Format(instr, "unknown"); | 645 Format(instr, "unknown"); |
| 664 } | 646 } |
| 665 | 647 |
| 666 | |
| 667 void ARM64Decoder::DecodeMoveWide(Instr* instr) { | 648 void ARM64Decoder::DecodeMoveWide(Instr* instr) { |
| 668 switch (instr->Bits(29, 2)) { | 649 switch (instr->Bits(29, 2)) { |
| 669 case 0: | 650 case 0: |
| 670 Format(instr, "movn'sf 'rd, 'imm16 'hw"); | 651 Format(instr, "movn'sf 'rd, 'imm16 'hw"); |
| 671 break; | 652 break; |
| 672 case 2: | 653 case 2: |
| 673 Format(instr, "movz'sf 'rd, 'imm16 'hw"); | 654 Format(instr, "movz'sf 'rd, 'imm16 'hw"); |
| 674 break; | 655 break; |
| 675 case 3: | 656 case 3: |
| 676 Format(instr, "movk'sf 'rd, 'imm16 'hw"); | 657 Format(instr, "movk'sf 'rd, 'imm16 'hw"); |
| 677 break; | 658 break; |
| 678 default: | 659 default: |
| 679 Unknown(instr); | 660 Unknown(instr); |
| 680 break; | 661 break; |
| 681 } | 662 } |
| 682 } | 663 } |
| 683 | 664 |
| 684 | |
| 685 void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) { | 665 void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) { |
| 686 if (instr->Bit(26) == 1) { | 666 if (instr->Bit(26) == 1) { |
| 687 // SIMD or FP src/dst. | 667 // SIMD or FP src/dst. |
| 688 if (instr->Bit(22) == 1) { | 668 if (instr->Bit(22) == 1) { |
| 689 Format(instr, "fldr'fsz 'vt, 'memop"); | 669 Format(instr, "fldr'fsz 'vt, 'memop"); |
| 690 } else { | 670 } else { |
| 691 Format(instr, "fstr'fsz 'vt, 'memop"); | 671 Format(instr, "fstr'fsz 'vt, 'memop"); |
| 692 } | 672 } |
| 693 } else { | 673 } else { |
| 694 // Integer src/dst. | 674 // Integer src/dst. |
| 695 if (instr->Bits(22, 2) == 0) { | 675 if (instr->Bits(22, 2) == 0) { |
| 696 Format(instr, "str'sz 'rt, 'memop"); | 676 Format(instr, "str'sz 'rt, 'memop"); |
| 697 } else { | 677 } else { |
| 698 Format(instr, "ldr'sz 'rt, 'memop"); | 678 Format(instr, "ldr'sz 'rt, 'memop"); |
| 699 } | 679 } |
| 700 } | 680 } |
| 701 } | 681 } |
| 702 | 682 |
| 703 | |
| 704 void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) { | 683 void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) { |
| 705 if (instr->Bit(22) == 1) { | 684 if (instr->Bit(22) == 1) { |
| 706 // Load. | 685 // Load. |
| 707 Format(instr, "ldp'sf 'rt, 'ra, 'pmemop"); | 686 Format(instr, "ldp'sf 'rt, 'ra, 'pmemop"); |
| 708 } else { | 687 } else { |
| 709 // Store. | 688 // Store. |
| 710 Format(instr, "stp'sf 'rt, 'ra, 'pmemop"); | 689 Format(instr, "stp'sf 'rt, 'ra, 'pmemop"); |
| 711 } | 690 } |
| 712 } | 691 } |
| 713 | 692 |
| 714 | |
| 715 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { | 693 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { |
| 716 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || | 694 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || |
| 717 (instr->Bits(24, 3) != 0)) { | 695 (instr->Bits(24, 3) != 0)) { |
| 718 Unknown(instr); | 696 Unknown(instr); |
| 719 } | 697 } |
| 720 if (instr->Bit(30)) { | 698 if (instr->Bit(30)) { |
| 721 Format(instr, "ldrx 'rt, 'pcldr"); | 699 Format(instr, "ldrx 'rt, 'pcldr"); |
| 722 } else { | 700 } else { |
| 723 Format(instr, "ldrw 'rt, 'pcldr"); | 701 Format(instr, "ldrw 'rt, 'pcldr"); |
| 724 } | 702 } |
| 725 } | 703 } |
| 726 | 704 |
| 727 | |
| 728 void ARM64Decoder::DecodeLoadStoreExclusive(Instr* instr) { | 705 void ARM64Decoder::DecodeLoadStoreExclusive(Instr* instr) { |
| 729 if ((instr->Bit(23) != 0) || (instr->Bit(21) != 0) || (instr->Bit(15) != 0)) { | 706 if ((instr->Bit(23) != 0) || (instr->Bit(21) != 0) || (instr->Bit(15) != 0)) { |
| 730 Unknown(instr); | 707 Unknown(instr); |
| 731 } | 708 } |
| 732 const int32_t size = instr->Bits(30, 2); | 709 const int32_t size = instr->Bits(30, 2); |
| 733 if (size != 3) { | 710 if (size != 3) { |
| 734 Unknown(instr); | 711 Unknown(instr); |
| 735 } | 712 } |
| 736 | 713 |
| 737 const bool is_load = instr->Bit(22) == 1; | 714 const bool is_load = instr->Bit(22) == 1; |
| 738 if (is_load) { | 715 if (is_load) { |
| 739 Format(instr, "ldxr 'rt, 'rn"); | 716 Format(instr, "ldxr 'rt, 'rn"); |
| 740 } else { | 717 } else { |
| 741 Format(instr, "stxr 'rs, 'rt, 'rn"); | 718 Format(instr, "stxr 'rs, 'rt, 'rn"); |
| 742 } | 719 } |
| 743 } | 720 } |
| 744 | 721 |
| 745 | |
| 746 void ARM64Decoder::DecodeAddSubImm(Instr* instr) { | 722 void ARM64Decoder::DecodeAddSubImm(Instr* instr) { |
| 747 switch (instr->Bit(30)) { | 723 switch (instr->Bit(30)) { |
| 748 case 0: { | 724 case 0: { |
| 749 if ((instr->RdField() == R31) && (instr->SField() == 1)) { | 725 if ((instr->RdField() == R31) && (instr->SField() == 1)) { |
| 750 Format(instr, "cmni'sf 'rn, 'imm12s"); | 726 Format(instr, "cmni'sf 'rn, 'imm12s"); |
| 751 } else { | 727 } else { |
| 752 if (((instr->RdField() == R31) || (instr->RnField() == R31)) && | 728 if (((instr->RdField() == R31) || (instr->RnField() == R31)) && |
| 753 (instr->Imm12Field() == 0) && (instr->Bit(29) == 0)) { | 729 (instr->Imm12Field() == 0) && (instr->Bit(29) == 0)) { |
| 754 Format(instr, "mov'sf 'rd, 'rn"); | 730 Format(instr, "mov'sf 'rd, 'rn"); |
| 755 } else { | 731 } else { |
| 756 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); | 732 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); |
| 757 } | 733 } |
| 758 } | 734 } |
| 759 break; | 735 break; |
| 760 } | 736 } |
| 761 case 1: { | 737 case 1: { |
| 762 if ((instr->RdField() == R31) && (instr->SField() == 1)) { | 738 if ((instr->RdField() == R31) && (instr->SField() == 1)) { |
| 763 Format(instr, "cmpi'sf 'rn, 'imm12s"); | 739 Format(instr, "cmpi'sf 'rn, 'imm12s"); |
| 764 } else { | 740 } else { |
| 765 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); | 741 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); |
| 766 } | 742 } |
| 767 break; | 743 break; |
| 768 } | 744 } |
| 769 default: | 745 default: |
| 770 Unknown(instr); | 746 Unknown(instr); |
| 771 break; | 747 break; |
| 772 } | 748 } |
| 773 } | 749 } |
| 774 | 750 |
| 775 | |
| 776 void ARM64Decoder::DecodeLogicalImm(Instr* instr) { | 751 void ARM64Decoder::DecodeLogicalImm(Instr* instr) { |
| 777 int op = instr->Bits(29, 2); | 752 int op = instr->Bits(29, 2); |
| 778 switch (op) { | 753 switch (op) { |
| 779 case 0: | 754 case 0: |
| 780 Format(instr, "andi'sf 'rd, 'rn, 'bitimm"); | 755 Format(instr, "andi'sf 'rd, 'rn, 'bitimm"); |
| 781 break; | 756 break; |
| 782 case 1: { | 757 case 1: { |
| 783 if (instr->RnField() == R31) { | 758 if (instr->RnField() == R31) { |
| 784 Format(instr, "mov'sf 'rd, 'bitimm"); | 759 Format(instr, "mov'sf 'rd, 'bitimm"); |
| 785 } else { | 760 } else { |
| 786 Format(instr, "orri'sf 'rd, 'rn, 'bitimm"); | 761 Format(instr, "orri'sf 'rd, 'rn, 'bitimm"); |
| 787 } | 762 } |
| 788 break; | 763 break; |
| 789 } | 764 } |
| 790 case 2: | 765 case 2: |
| 791 Format(instr, "eori'sf 'rd, 'rn, 'bitimm"); | 766 Format(instr, "eori'sf 'rd, 'rn, 'bitimm"); |
| 792 break; | 767 break; |
| 793 case 3: | 768 case 3: |
| 794 Format(instr, "andi'sfs 'rd, 'rn, 'bitimm"); | 769 Format(instr, "andi'sfs 'rd, 'rn, 'bitimm"); |
| 795 break; | 770 break; |
| 796 default: | 771 default: |
| 797 Unknown(instr); | 772 Unknown(instr); |
| 798 break; | 773 break; |
| 799 } | 774 } |
| 800 } | 775 } |
| 801 | 776 |
| 802 | |
| 803 void ARM64Decoder::DecodePCRel(Instr* instr) { | 777 void ARM64Decoder::DecodePCRel(Instr* instr) { |
| 804 const int op = instr->Bit(31); | 778 const int op = instr->Bit(31); |
| 805 if (op == 0) { | 779 if (op == 0) { |
| 806 Format(instr, "adr 'rd, 'pcadr"); | 780 Format(instr, "adr 'rd, 'pcadr"); |
| 807 } else { | 781 } else { |
| 808 Unknown(instr); | 782 Unknown(instr); |
| 809 } | 783 } |
| 810 } | 784 } |
| 811 | 785 |
| 812 | |
| 813 void ARM64Decoder::DecodeDPImmediate(Instr* instr) { | 786 void ARM64Decoder::DecodeDPImmediate(Instr* instr) { |
| 814 if (instr->IsMoveWideOp()) { | 787 if (instr->IsMoveWideOp()) { |
| 815 DecodeMoveWide(instr); | 788 DecodeMoveWide(instr); |
| 816 } else if (instr->IsAddSubImmOp()) { | 789 } else if (instr->IsAddSubImmOp()) { |
| 817 DecodeAddSubImm(instr); | 790 DecodeAddSubImm(instr); |
| 818 } else if (instr->IsLogicalImmOp()) { | 791 } else if (instr->IsLogicalImmOp()) { |
| 819 DecodeLogicalImm(instr); | 792 DecodeLogicalImm(instr); |
| 820 } else if (instr->IsPCRelOp()) { | 793 } else if (instr->IsPCRelOp()) { |
| 821 DecodePCRel(instr); | 794 DecodePCRel(instr); |
| 822 } else { | 795 } else { |
| 823 Unknown(instr); | 796 Unknown(instr); |
| 824 } | 797 } |
| 825 } | 798 } |
| 826 | 799 |
| 827 | |
| 828 void ARM64Decoder::DecodeExceptionGen(Instr* instr) { | 800 void ARM64Decoder::DecodeExceptionGen(Instr* instr) { |
| 829 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) && | 801 if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) && |
| 830 (instr->Bits(21, 3) == 0)) { | 802 (instr->Bits(21, 3) == 0)) { |
| 831 Format(instr, "svc 'imm16"); | 803 Format(instr, "svc 'imm16"); |
| 832 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && | 804 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && |
| 833 (instr->Bits(21, 3) == 1)) { | 805 (instr->Bits(21, 3) == 1)) { |
| 834 Format(instr, "brk 'imm16"); | 806 Format(instr, "brk 'imm16"); |
| 835 if (instr->Imm16Field() == Instr::kStopMessageCode) { | 807 if (instr->Imm16Field() == Instr::kStopMessageCode) { |
| 836 const char* message = *reinterpret_cast<const char**>( | 808 const char* message = *reinterpret_cast<const char**>( |
| 837 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); | 809 reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize); |
| 838 buffer_pos_ += | 810 buffer_pos_ += |
| 839 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), | 811 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), |
| 840 " ; \"%s\"", message); | 812 " ; \"%s\"", message); |
| 841 } | 813 } |
| 842 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && | 814 } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) && |
| 843 (instr->Bits(21, 3) == 2)) { | 815 (instr->Bits(21, 3) == 2)) { |
| 844 Format(instr, "hlt 'imm16"); | 816 Format(instr, "hlt 'imm16"); |
| 845 } else { | 817 } else { |
| 846 Unknown(instr); | 818 Unknown(instr); |
| 847 } | 819 } |
| 848 } | 820 } |
| 849 | 821 |
| 850 | |
| 851 void ARM64Decoder::DecodeSystem(Instr* instr) { | 822 void ARM64Decoder::DecodeSystem(Instr* instr) { |
| 852 if (instr->InstructionBits() == CLREX) { | 823 if (instr->InstructionBits() == CLREX) { |
| 853 Format(instr, "clrex"); | 824 Format(instr, "clrex"); |
| 854 return; | 825 return; |
| 855 } | 826 } |
| 856 | 827 |
| 857 if ((instr->Bits(0, 8) == 0x1f) && (instr->Bits(12, 4) == 2) && | 828 if ((instr->Bits(0, 8) == 0x1f) && (instr->Bits(12, 4) == 2) && |
| 858 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && | 829 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && |
| 859 (instr->Bit(21) == 0)) { | 830 (instr->Bit(21) == 0)) { |
| 860 if (instr->Bits(8, 4) == 0) { | 831 if (instr->Bits(8, 4) == 0) { |
| 861 Format(instr, "nop"); | 832 Format(instr, "nop"); |
| 862 } else { | 833 } else { |
| 863 Unknown(instr); | 834 Unknown(instr); |
| 864 } | 835 } |
| 865 } else { | 836 } else { |
| 866 Unknown(instr); | 837 Unknown(instr); |
| 867 } | 838 } |
| 868 } | 839 } |
| 869 | 840 |
| 870 | |
| 871 void ARM64Decoder::DecodeUnconditionalBranchReg(Instr* instr) { | 841 void ARM64Decoder::DecodeUnconditionalBranchReg(Instr* instr) { |
| 872 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 5) == 0) && | 842 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 5) == 0) && |
| 873 (instr->Bits(16, 5) == 0x1f)) { | 843 (instr->Bits(16, 5) == 0x1f)) { |
| 874 switch (instr->Bits(21, 4)) { | 844 switch (instr->Bits(21, 4)) { |
| 875 case 0: | 845 case 0: |
| 876 Format(instr, "br 'rn"); | 846 Format(instr, "br 'rn"); |
| 877 break; | 847 break; |
| 878 case 1: | 848 case 1: |
| 879 Format(instr, "blr 'rn"); | 849 Format(instr, "blr 'rn"); |
| 880 break; | 850 break; |
| 881 case 2: | 851 case 2: |
| 882 Format(instr, "ret 'rn"); | 852 Format(instr, "ret 'rn"); |
| 883 break; | 853 break; |
| 884 default: | 854 default: |
| 885 Unknown(instr); | 855 Unknown(instr); |
| 886 break; | 856 break; |
| 887 } | 857 } |
| 888 } | 858 } |
| 889 } | 859 } |
| 890 | 860 |
| 891 | |
| 892 void ARM64Decoder::DecodeCompareAndBranch(Instr* instr) { | 861 void ARM64Decoder::DecodeCompareAndBranch(Instr* instr) { |
| 893 const int op = instr->Bit(24); | 862 const int op = instr->Bit(24); |
| 894 if (op == 0) { | 863 if (op == 0) { |
| 895 Format(instr, "cbz'sf 'rt, 'dest19"); | 864 Format(instr, "cbz'sf 'rt, 'dest19"); |
| 896 } else { | 865 } else { |
| 897 Format(instr, "cbnz'sf 'rt, 'dest19"); | 866 Format(instr, "cbnz'sf 'rt, 'dest19"); |
| 898 } | 867 } |
| 899 } | 868 } |
| 900 | 869 |
| 901 | |
| 902 void ARM64Decoder::DecodeConditionalBranch(Instr* instr) { | 870 void ARM64Decoder::DecodeConditionalBranch(Instr* instr) { |
| 903 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) { | 871 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) { |
| 904 Unknown(instr); | 872 Unknown(instr); |
| 905 return; | 873 return; |
| 906 } | 874 } |
| 907 Format(instr, "b'cond 'dest19"); | 875 Format(instr, "b'cond 'dest19"); |
| 908 } | 876 } |
| 909 | 877 |
| 910 | |
| 911 void ARM64Decoder::DecodeTestAndBranch(Instr* instr) { | 878 void ARM64Decoder::DecodeTestAndBranch(Instr* instr) { |
| 912 const int op = instr->Bit(24); | 879 const int op = instr->Bit(24); |
| 913 if (op == 0) { | 880 if (op == 0) { |
| 914 Format(instr, "tbz'sf 'rt, 'bitpos, 'dest14"); | 881 Format(instr, "tbz'sf 'rt, 'bitpos, 'dest14"); |
| 915 } else { | 882 } else { |
| 916 Format(instr, "tbnz'sf 'rt, 'bitpos, 'dest14"); | 883 Format(instr, "tbnz'sf 'rt, 'bitpos, 'dest14"); |
| 917 } | 884 } |
| 918 } | 885 } |
| 919 | 886 |
| 920 | |
| 921 void ARM64Decoder::DecodeUnconditionalBranch(Instr* instr) { | 887 void ARM64Decoder::DecodeUnconditionalBranch(Instr* instr) { |
| 922 const int op = instr->Bit(31); | 888 const int op = instr->Bit(31); |
| 923 if (op == 0) { | 889 if (op == 0) { |
| 924 Format(instr, "b 'dest26"); | 890 Format(instr, "b 'dest26"); |
| 925 } else { | 891 } else { |
| 926 Format(instr, "bl 'dest26"); | 892 Format(instr, "bl 'dest26"); |
| 927 } | 893 } |
| 928 } | 894 } |
| 929 | 895 |
| 930 void ARM64Decoder::DecodeCompareBranch(Instr* instr) { | 896 void ARM64Decoder::DecodeCompareBranch(Instr* instr) { |
| 931 if (instr->IsExceptionGenOp()) { | 897 if (instr->IsExceptionGenOp()) { |
| 932 DecodeExceptionGen(instr); | 898 DecodeExceptionGen(instr); |
| 933 } else if (instr->IsSystemOp()) { | 899 } else if (instr->IsSystemOp()) { |
| 934 DecodeSystem(instr); | 900 DecodeSystem(instr); |
| 935 } else if (instr->IsUnconditionalBranchRegOp()) { | 901 } else if (instr->IsUnconditionalBranchRegOp()) { |
| 936 DecodeUnconditionalBranchReg(instr); | 902 DecodeUnconditionalBranchReg(instr); |
| 937 } else if (instr->IsCompareAndBranchOp()) { | 903 } else if (instr->IsCompareAndBranchOp()) { |
| 938 DecodeCompareAndBranch(instr); | 904 DecodeCompareAndBranch(instr); |
| 939 } else if (instr->IsConditionalBranchOp()) { | 905 } else if (instr->IsConditionalBranchOp()) { |
| 940 DecodeConditionalBranch(instr); | 906 DecodeConditionalBranch(instr); |
| 941 } else if (instr->IsTestAndBranchOp()) { | 907 } else if (instr->IsTestAndBranchOp()) { |
| 942 DecodeTestAndBranch(instr); | 908 DecodeTestAndBranch(instr); |
| 943 } else if (instr->IsUnconditionalBranchOp()) { | 909 } else if (instr->IsUnconditionalBranchOp()) { |
| 944 DecodeUnconditionalBranch(instr); | 910 DecodeUnconditionalBranch(instr); |
| 945 } else { | 911 } else { |
| 946 Unknown(instr); | 912 Unknown(instr); |
| 947 } | 913 } |
| 948 } | 914 } |
| 949 | 915 |
| 950 | |
| 951 void ARM64Decoder::DecodeLoadStore(Instr* instr) { | 916 void ARM64Decoder::DecodeLoadStore(Instr* instr) { |
| 952 if (instr->IsLoadStoreRegOp()) { | 917 if (instr->IsLoadStoreRegOp()) { |
| 953 DecodeLoadStoreReg(instr); | 918 DecodeLoadStoreReg(instr); |
| 954 } else if (instr->IsLoadStoreRegPairOp()) { | 919 } else if (instr->IsLoadStoreRegPairOp()) { |
| 955 DecodeLoadStoreRegPair(instr); | 920 DecodeLoadStoreRegPair(instr); |
| 956 } else if (instr->IsLoadRegLiteralOp()) { | 921 } else if (instr->IsLoadRegLiteralOp()) { |
| 957 DecodeLoadRegLiteral(instr); | 922 DecodeLoadRegLiteral(instr); |
| 958 } else if (instr->IsLoadStoreExclusiveOp()) { | 923 } else if (instr->IsLoadStoreExclusiveOp()) { |
| 959 DecodeLoadStoreExclusive(instr); | 924 DecodeLoadStoreExclusive(instr); |
| 960 } else { | 925 } else { |
| 961 Unknown(instr); | 926 Unknown(instr); |
| 962 } | 927 } |
| 963 } | 928 } |
| 964 | 929 |
| 965 | |
| 966 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { | 930 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { |
| 967 switch (instr->Bit(30)) { | 931 switch (instr->Bit(30)) { |
| 968 case 0: { | 932 case 0: { |
| 969 if ((instr->RdField() == R31) && (instr->SFField())) { | 933 if ((instr->RdField() == R31) && (instr->SFField())) { |
| 970 Format(instr, "cmn'sf 'rn, 'shift_op"); | 934 Format(instr, "cmn'sf 'rn, 'shift_op"); |
| 971 } else { | 935 } else { |
| 972 Format(instr, "add'sf's 'rd, 'rn, 'shift_op"); | 936 Format(instr, "add'sf's 'rd, 'rn, 'shift_op"); |
| 973 } | 937 } |
| 974 break; | 938 break; |
| 975 } | 939 } |
| 976 case 1: { | 940 case 1: { |
| 977 if ((instr->RdField() == R31) && (instr->SFField())) { | 941 if ((instr->RdField() == R31) && (instr->SFField())) { |
| 978 Format(instr, "cmp'sf 'rn, 'shift_op"); | 942 Format(instr, "cmp'sf 'rn, 'shift_op"); |
| 979 } else { | 943 } else { |
| 980 Format(instr, "sub'sf's 'rd, 'rn, 'shift_op"); | 944 Format(instr, "sub'sf's 'rd, 'rn, 'shift_op"); |
| 981 } | 945 } |
| 982 break; | 946 break; |
| 983 } | 947 } |
| 984 default: | 948 default: |
| 985 UNREACHABLE(); | 949 UNREACHABLE(); |
| 986 break; | 950 break; |
| 987 } | 951 } |
| 988 } | 952 } |
| 989 | 953 |
| 990 | |
| 991 void ARM64Decoder::DecodeAddSubWithCarry(Instr* instr) { | 954 void ARM64Decoder::DecodeAddSubWithCarry(Instr* instr) { |
| 992 switch (instr->Bit(30)) { | 955 switch (instr->Bit(30)) { |
| 993 case 0: { | 956 case 0: { |
| 994 Format(instr, "adc'sf's 'rd, 'rn, 'rm"); | 957 Format(instr, "adc'sf's 'rd, 'rn, 'rm"); |
| 995 break; | 958 break; |
| 996 } | 959 } |
| 997 case 1: { | 960 case 1: { |
| 998 Format(instr, "sbc'sf's 'rd, 'rn, 'rm"); | 961 Format(instr, "sbc'sf's 'rd, 'rn, 'rm"); |
| 999 break; | 962 break; |
| 1000 } | 963 } |
| 1001 default: | 964 default: |
| 1002 UNREACHABLE(); | 965 UNREACHABLE(); |
| 1003 break; | 966 break; |
| 1004 } | 967 } |
| 1005 } | 968 } |
| 1006 | 969 |
| 1007 | |
| 1008 void ARM64Decoder::DecodeLogicalShift(Instr* instr) { | 970 void ARM64Decoder::DecodeLogicalShift(Instr* instr) { |
| 1009 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); | 971 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); |
| 1010 switch (op) { | 972 switch (op) { |
| 1011 case 0: | 973 case 0: |
| 1012 Format(instr, "and'sf 'rd, 'rn, 'shift_op"); | 974 Format(instr, "and'sf 'rd, 'rn, 'shift_op"); |
| 1013 break; | 975 break; |
| 1014 case 1: | 976 case 1: |
| 1015 Format(instr, "bic'sf 'rd, 'rn, 'shift_op"); | 977 Format(instr, "bic'sf 'rd, 'rn, 'shift_op"); |
| 1016 break; | 978 break; |
| 1017 case 2: { | 979 case 2: { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1037 break; | 999 break; |
| 1038 case 7: | 1000 case 7: |
| 1039 Format(instr, "bic'sfs 'rd, 'rn, 'shift_op"); | 1001 Format(instr, "bic'sfs 'rd, 'rn, 'shift_op"); |
| 1040 break; | 1002 break; |
| 1041 default: | 1003 default: |
| 1042 UNREACHABLE(); | 1004 UNREACHABLE(); |
| 1043 break; | 1005 break; |
| 1044 } | 1006 } |
| 1045 } | 1007 } |
| 1046 | 1008 |
| 1047 | |
| 1048 void ARM64Decoder::DecodeMiscDP1Source(Instr* instr) { | 1009 void ARM64Decoder::DecodeMiscDP1Source(Instr* instr) { |
| 1049 if (instr->Bit(29) != 0) { | 1010 if (instr->Bit(29) != 0) { |
| 1050 Unknown(instr); | 1011 Unknown(instr); |
| 1051 } | 1012 } |
| 1052 | 1013 |
| 1053 const int op = instr->Bits(10, 10); | 1014 const int op = instr->Bits(10, 10); |
| 1054 switch (op) { | 1015 switch (op) { |
| 1055 case 4: | 1016 case 4: |
| 1056 Format(instr, "clz'sf 'rd, 'rn"); | 1017 Format(instr, "clz'sf 'rd, 'rn"); |
| 1057 break; | 1018 break; |
| 1058 default: | 1019 default: |
| 1059 Unknown(instr); | 1020 Unknown(instr); |
| 1060 break; | 1021 break; |
| 1061 } | 1022 } |
| 1062 } | 1023 } |
| 1063 | 1024 |
| 1064 | |
| 1065 void ARM64Decoder::DecodeMiscDP2Source(Instr* instr) { | 1025 void ARM64Decoder::DecodeMiscDP2Source(Instr* instr) { |
| 1066 if (instr->Bit(29) != 0) { | 1026 if (instr->Bit(29) != 0) { |
| 1067 Unknown(instr); | 1027 Unknown(instr); |
| 1068 } | 1028 } |
| 1069 | 1029 |
| 1070 const int op = instr->Bits(10, 5); | 1030 const int op = instr->Bits(10, 5); |
| 1071 switch (op) { | 1031 switch (op) { |
| 1072 case 2: | 1032 case 2: |
| 1073 Format(instr, "udiv'sf 'rd, 'rn, 'rm"); | 1033 Format(instr, "udiv'sf 'rd, 'rn, 'rm"); |
| 1074 break; | 1034 break; |
| 1075 case 3: | 1035 case 3: |
| 1076 Format(instr, "sdiv'sf 'rd, 'rn, 'rm"); | 1036 Format(instr, "sdiv'sf 'rd, 'rn, 'rm"); |
| 1077 break; | 1037 break; |
| 1078 case 8: | 1038 case 8: |
| 1079 Format(instr, "lsl'sf 'rd, 'rn, 'rm"); | 1039 Format(instr, "lsl'sf 'rd, 'rn, 'rm"); |
| 1080 break; | 1040 break; |
| 1081 case 9: | 1041 case 9: |
| 1082 Format(instr, "lsr'sf 'rd, 'rn, 'rm"); | 1042 Format(instr, "lsr'sf 'rd, 'rn, 'rm"); |
| 1083 break; | 1043 break; |
| 1084 case 10: | 1044 case 10: |
| 1085 Format(instr, "asr'sf 'rd, 'rn, 'rm"); | 1045 Format(instr, "asr'sf 'rd, 'rn, 'rm"); |
| 1086 break; | 1046 break; |
| 1087 default: | 1047 default: |
| 1088 Unknown(instr); | 1048 Unknown(instr); |
| 1089 break; | 1049 break; |
| 1090 } | 1050 } |
| 1091 } | 1051 } |
| 1092 | 1052 |
| 1093 | |
| 1094 void ARM64Decoder::DecodeMiscDP3Source(Instr* instr) { | 1053 void ARM64Decoder::DecodeMiscDP3Source(Instr* instr) { |
| 1095 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && | 1054 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && |
| 1096 (instr->Bit(15) == 0)) { | 1055 (instr->Bit(15) == 0)) { |
| 1097 if (instr->RaField() == R31) { | 1056 if (instr->RaField() == R31) { |
| 1098 Format(instr, "mul'sf 'rd, 'rn, 'rm"); | 1057 Format(instr, "mul'sf 'rd, 'rn, 'rm"); |
| 1099 } else { | 1058 } else { |
| 1100 Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra"); | 1059 Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra"); |
| 1101 } | 1060 } |
| 1102 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && | 1061 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && |
| 1103 (instr->Bit(15) == 1)) { | 1062 (instr->Bit(15) == 1)) { |
| 1104 Format(instr, "msub'sf 'rd, 'rn, 'rm, 'ra"); | 1063 Format(instr, "msub'sf 'rd, 'rn, 'rm, 'ra"); |
| 1105 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) && | 1064 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) && |
| 1106 (instr->Bit(15) == 0)) { | 1065 (instr->Bit(15) == 0)) { |
| 1107 Format(instr, "smulh 'rd, 'rn, 'rm"); | 1066 Format(instr, "smulh 'rd, 'rn, 'rm"); |
| 1108 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 6) && | 1067 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 6) && |
| 1109 (instr->Bit(15) == 0)) { | 1068 (instr->Bit(15) == 0)) { |
| 1110 Format(instr, "umulh 'rd, 'rn, 'rm"); | 1069 Format(instr, "umulh 'rd, 'rn, 'rm"); |
| 1111 } else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 5) && | 1070 } else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 5) && |
| 1112 (instr->Bit(15) == 0)) { | 1071 (instr->Bit(15) == 0)) { |
| 1113 Format(instr, "umaddl 'rd, 'rn, 'rm, 'ra"); | 1072 Format(instr, "umaddl 'rd, 'rn, 'rm, 'ra"); |
| 1114 } else { | 1073 } else { |
| 1115 Unknown(instr); | 1074 Unknown(instr); |
| 1116 } | 1075 } |
| 1117 } | 1076 } |
| 1118 | 1077 |
| 1119 | |
| 1120 void ARM64Decoder::DecodeConditionalSelect(Instr* instr) { | 1078 void ARM64Decoder::DecodeConditionalSelect(Instr* instr) { |
| 1121 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { | 1079 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { |
| 1122 Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); | 1080 Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); |
| 1123 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) { | 1081 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) { |
| 1124 Format(instr, "csinc'sf'cond 'rd, 'rn, 'rm"); | 1082 Format(instr, "csinc'sf'cond 'rd, 'rn, 'rm"); |
| 1125 } else if ((instr->Bits(29, 2) == 2) && (instr->Bits(10, 2) == 0)) { | 1083 } else if ((instr->Bits(29, 2) == 2) && (instr->Bits(10, 2) == 0)) { |
| 1126 Format(instr, "csinv'sf'cond 'rd, 'rn, 'rm"); | 1084 Format(instr, "csinv'sf'cond 'rd, 'rn, 'rm"); |
| 1127 } else { | 1085 } else { |
| 1128 Unknown(instr); | 1086 Unknown(instr); |
| 1129 } | 1087 } |
| 1130 } | 1088 } |
| 1131 | 1089 |
| 1132 | |
| 1133 void ARM64Decoder::DecodeDPRegister(Instr* instr) { | 1090 void ARM64Decoder::DecodeDPRegister(Instr* instr) { |
| 1134 if (instr->IsAddSubShiftExtOp()) { | 1091 if (instr->IsAddSubShiftExtOp()) { |
| 1135 DecodeAddSubShiftExt(instr); | 1092 DecodeAddSubShiftExt(instr); |
| 1136 } else if (instr->IsAddSubWithCarryOp()) { | 1093 } else if (instr->IsAddSubWithCarryOp()) { |
| 1137 DecodeAddSubWithCarry(instr); | 1094 DecodeAddSubWithCarry(instr); |
| 1138 } else if (instr->IsLogicalShiftOp()) { | 1095 } else if (instr->IsLogicalShiftOp()) { |
| 1139 DecodeLogicalShift(instr); | 1096 DecodeLogicalShift(instr); |
| 1140 } else if (instr->IsMiscDP1SourceOp()) { | 1097 } else if (instr->IsMiscDP1SourceOp()) { |
| 1141 DecodeMiscDP1Source(instr); | 1098 DecodeMiscDP1Source(instr); |
| 1142 } else if (instr->IsMiscDP2SourceOp()) { | 1099 } else if (instr->IsMiscDP2SourceOp()) { |
| 1143 DecodeMiscDP2Source(instr); | 1100 DecodeMiscDP2Source(instr); |
| 1144 } else if (instr->IsMiscDP3SourceOp()) { | 1101 } else if (instr->IsMiscDP3SourceOp()) { |
| 1145 DecodeMiscDP3Source(instr); | 1102 DecodeMiscDP3Source(instr); |
| 1146 } else if (instr->IsConditionalSelectOp()) { | 1103 } else if (instr->IsConditionalSelectOp()) { |
| 1147 DecodeConditionalSelect(instr); | 1104 DecodeConditionalSelect(instr); |
| 1148 } else { | 1105 } else { |
| 1149 Unknown(instr); | 1106 Unknown(instr); |
| 1150 } | 1107 } |
| 1151 } | 1108 } |
| 1152 | 1109 |
| 1153 | |
| 1154 void ARM64Decoder::DecodeSIMDCopy(Instr* instr) { | 1110 void ARM64Decoder::DecodeSIMDCopy(Instr* instr) { |
| 1155 const int32_t Q = instr->Bit(30); | 1111 const int32_t Q = instr->Bit(30); |
| 1156 const int32_t op = instr->Bit(29); | 1112 const int32_t op = instr->Bit(29); |
| 1157 const int32_t imm4 = instr->Bits(11, 4); | 1113 const int32_t imm4 = instr->Bits(11, 4); |
| 1158 | 1114 |
| 1159 if ((op == 0) && (imm4 == 7)) { | 1115 if ((op == 0) && (imm4 == 7)) { |
| 1160 if (Q == 0) { | 1116 if (Q == 0) { |
| 1161 Format(instr, "vmovrs 'rd, 'vn'idx5"); | 1117 Format(instr, "vmovrs 'rd, 'vn'idx5"); |
| 1162 } else { | 1118 } else { |
| 1163 Format(instr, "vmovrd 'rd, 'vn'idx5"); | 1119 Format(instr, "vmovrd 'rd, 'vn'idx5"); |
| 1164 } | 1120 } |
| 1165 } else if ((Q == 1) && (op == 0) && (imm4 == 0)) { | 1121 } else if ((Q == 1) && (op == 0) && (imm4 == 0)) { |
| 1166 Format(instr, "vdup'csz 'vd, 'vn'idx5"); | 1122 Format(instr, "vdup'csz 'vd, 'vn'idx5"); |
| 1167 } else if ((Q == 1) && (op == 0) && (imm4 == 3)) { | 1123 } else if ((Q == 1) && (op == 0) && (imm4 == 3)) { |
| 1168 Format(instr, "vins'csz 'vd'idx5, 'rn"); | 1124 Format(instr, "vins'csz 'vd'idx5, 'rn"); |
| 1169 } else if ((Q == 1) && (op == 0) && (imm4 == 1)) { | 1125 } else if ((Q == 1) && (op == 0) && (imm4 == 1)) { |
| 1170 Format(instr, "vdup'csz 'vd, 'rn"); | 1126 Format(instr, "vdup'csz 'vd, 'rn"); |
| 1171 } else if ((Q == 1) && (op == 1)) { | 1127 } else if ((Q == 1) && (op == 1)) { |
| 1172 Format(instr, "vins'csz 'vd'idx5, 'vn'idx4"); | 1128 Format(instr, "vins'csz 'vd'idx5, 'vn'idx4"); |
| 1173 } else { | 1129 } else { |
| 1174 Unknown(instr); | 1130 Unknown(instr); |
| 1175 } | 1131 } |
| 1176 } | 1132 } |
| 1177 | 1133 |
| 1178 | |
| 1179 void ARM64Decoder::DecodeSIMDThreeSame(Instr* instr) { | 1134 void ARM64Decoder::DecodeSIMDThreeSame(Instr* instr) { |
| 1180 const int32_t Q = instr->Bit(30); | 1135 const int32_t Q = instr->Bit(30); |
| 1181 const int32_t U = instr->Bit(29); | 1136 const int32_t U = instr->Bit(29); |
| 1182 const int32_t opcode = instr->Bits(11, 5); | 1137 const int32_t opcode = instr->Bits(11, 5); |
| 1183 | 1138 |
| 1184 if (Q == 0) { | 1139 if (Q == 0) { |
| 1185 Unknown(instr); | 1140 Unknown(instr); |
| 1186 return; | 1141 return; |
| 1187 } | 1142 } |
| 1188 | 1143 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 if (instr->Bit(23) == 1) { | 1181 if (instr->Bit(23) == 1) { |
| 1227 Format(instr, "vrsqrt'vsz 'vd, 'vn, 'vm"); | 1182 Format(instr, "vrsqrt'vsz 'vd, 'vn, 'vm"); |
| 1228 } else { | 1183 } else { |
| 1229 Format(instr, "vrecps'vsz 'vd, 'vn, 'vm"); | 1184 Format(instr, "vrecps'vsz 'vd, 'vn, 'vm"); |
| 1230 } | 1185 } |
| 1231 } else { | 1186 } else { |
| 1232 Unknown(instr); | 1187 Unknown(instr); |
| 1233 } | 1188 } |
| 1234 } | 1189 } |
| 1235 | 1190 |
| 1236 | |
| 1237 void ARM64Decoder::DecodeSIMDTwoReg(Instr* instr) { | 1191 void ARM64Decoder::DecodeSIMDTwoReg(Instr* instr) { |
| 1238 const int32_t Q = instr->Bit(30); | 1192 const int32_t Q = instr->Bit(30); |
| 1239 const int32_t U = instr->Bit(29); | 1193 const int32_t U = instr->Bit(29); |
| 1240 const int32_t op = instr->Bits(12, 5); | 1194 const int32_t op = instr->Bits(12, 5); |
| 1241 const int32_t sz = instr->Bits(22, 2); | 1195 const int32_t sz = instr->Bits(22, 2); |
| 1242 | 1196 |
| 1243 if (Q == 0) { | 1197 if (Q == 0) { |
| 1244 Unknown(instr); | 1198 Unknown(instr); |
| 1245 return; | 1199 return; |
| 1246 } | 1200 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 if (sz != 2) { | 1235 if (sz != 2) { |
| 1282 Unknown(instr); | 1236 Unknown(instr); |
| 1283 return; | 1237 return; |
| 1284 } | 1238 } |
| 1285 Format(instr, "vrsqrtes 'vd, 'vn"); | 1239 Format(instr, "vrsqrtes 'vd, 'vn"); |
| 1286 } else { | 1240 } else { |
| 1287 Unknown(instr); | 1241 Unknown(instr); |
| 1288 } | 1242 } |
| 1289 } | 1243 } |
| 1290 | 1244 |
| 1291 | |
| 1292 void ARM64Decoder::DecodeDPSimd1(Instr* instr) { | 1245 void ARM64Decoder::DecodeDPSimd1(Instr* instr) { |
| 1293 if (instr->IsSIMDCopyOp()) { | 1246 if (instr->IsSIMDCopyOp()) { |
| 1294 DecodeSIMDCopy(instr); | 1247 DecodeSIMDCopy(instr); |
| 1295 } else if (instr->IsSIMDThreeSameOp()) { | 1248 } else if (instr->IsSIMDThreeSameOp()) { |
| 1296 DecodeSIMDThreeSame(instr); | 1249 DecodeSIMDThreeSame(instr); |
| 1297 } else if (instr->IsSIMDTwoRegOp()) { | 1250 } else if (instr->IsSIMDTwoRegOp()) { |
| 1298 DecodeSIMDTwoReg(instr); | 1251 DecodeSIMDTwoReg(instr); |
| 1299 } else { | 1252 } else { |
| 1300 Unknown(instr); | 1253 Unknown(instr); |
| 1301 } | 1254 } |
| 1302 } | 1255 } |
| 1303 | 1256 |
| 1304 | |
| 1305 void ARM64Decoder::DecodeFPImm(Instr* instr) { | 1257 void ARM64Decoder::DecodeFPImm(Instr* instr) { |
| 1306 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || | 1258 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || |
| 1307 (instr->Bits(5, 5) != 0)) { | 1259 (instr->Bits(5, 5) != 0)) { |
| 1308 Unknown(instr); | 1260 Unknown(instr); |
| 1309 return; | 1261 return; |
| 1310 } | 1262 } |
| 1311 if (instr->Bit(22) == 1) { | 1263 if (instr->Bit(22) == 1) { |
| 1312 // Double. | 1264 // Double. |
| 1313 Format(instr, "fmovd 'vd, 'immd"); | 1265 Format(instr, "fmovd 'vd, 'immd"); |
| 1314 } else { | 1266 } else { |
| 1315 // Single. | 1267 // Single. |
| 1316 Unknown(instr); | 1268 Unknown(instr); |
| 1317 } | 1269 } |
| 1318 } | 1270 } |
| 1319 | 1271 |
| 1320 | |
| 1321 void ARM64Decoder::DecodeFPIntCvt(Instr* instr) { | 1272 void ARM64Decoder::DecodeFPIntCvt(Instr* instr) { |
| 1322 if ((instr->Bit(29) != 0)) { | 1273 if ((instr->Bit(29) != 0)) { |
| 1323 Unknown(instr); | 1274 Unknown(instr); |
| 1324 return; | 1275 return; |
| 1325 } | 1276 } |
| 1326 | 1277 |
| 1327 if ((instr->SFField() == 0) && (instr->Bits(22, 2) == 0)) { | 1278 if ((instr->SFField() == 0) && (instr->Bits(22, 2) == 0)) { |
| 1328 if (instr->Bits(16, 5) == 6) { | 1279 if (instr->Bits(16, 5) == 6) { |
| 1329 Format(instr, "fmovrs'sf 'rd, 'vn"); | 1280 Format(instr, "fmovrs'sf 'rd, 'vn"); |
| 1330 } else if (instr->Bits(16, 5) == 7) { | 1281 } else if (instr->Bits(16, 5) == 7) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1342 } else if (instr->Bits(16, 5) == 24) { | 1293 } else if (instr->Bits(16, 5) == 24) { |
| 1343 Format(instr, "fcvtzds'sf 'rd, 'vn"); | 1294 Format(instr, "fcvtzds'sf 'rd, 'vn"); |
| 1344 } else { | 1295 } else { |
| 1345 Unknown(instr); | 1296 Unknown(instr); |
| 1346 } | 1297 } |
| 1347 } else { | 1298 } else { |
| 1348 Unknown(instr); | 1299 Unknown(instr); |
| 1349 } | 1300 } |
| 1350 } | 1301 } |
| 1351 | 1302 |
| 1352 | |
| 1353 void ARM64Decoder::DecodeFPOneSource(Instr* instr) { | 1303 void ARM64Decoder::DecodeFPOneSource(Instr* instr) { |
| 1354 const int opc = instr->Bits(15, 6); | 1304 const int opc = instr->Bits(15, 6); |
| 1355 | 1305 |
| 1356 if ((opc != 5) && (instr->Bit(22) != 1)) { | 1306 if ((opc != 5) && (instr->Bit(22) != 1)) { |
| 1357 // Source is interpreted as single-precision only if we're doing a | 1307 // Source is interpreted as single-precision only if we're doing a |
| 1358 // conversion from single -> double. | 1308 // conversion from single -> double. |
| 1359 Unknown(instr); | 1309 Unknown(instr); |
| 1360 return; | 1310 return; |
| 1361 } | 1311 } |
| 1362 | 1312 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1378 break; | 1328 break; |
| 1379 case 5: | 1329 case 5: |
| 1380 Format(instr, "fcvtds 'vd, 'vn"); | 1330 Format(instr, "fcvtds 'vd, 'vn"); |
| 1381 break; | 1331 break; |
| 1382 default: | 1332 default: |
| 1383 Unknown(instr); | 1333 Unknown(instr); |
| 1384 break; | 1334 break; |
| 1385 } | 1335 } |
| 1386 } | 1336 } |
| 1387 | 1337 |
| 1388 | |
| 1389 void ARM64Decoder::DecodeFPTwoSource(Instr* instr) { | 1338 void ARM64Decoder::DecodeFPTwoSource(Instr* instr) { |
| 1390 if (instr->Bits(22, 2) != 1) { | 1339 if (instr->Bits(22, 2) != 1) { |
| 1391 Unknown(instr); | 1340 Unknown(instr); |
| 1392 return; | 1341 return; |
| 1393 } | 1342 } |
| 1394 const int opc = instr->Bits(12, 4); | 1343 const int opc = instr->Bits(12, 4); |
| 1395 | 1344 |
| 1396 switch (opc) { | 1345 switch (opc) { |
| 1397 case 0: | 1346 case 0: |
| 1398 Format(instr, "fmuld 'vd, 'vn, 'vm"); | 1347 Format(instr, "fmuld 'vd, 'vn, 'vm"); |
| 1399 break; | 1348 break; |
| 1400 case 1: | 1349 case 1: |
| 1401 Format(instr, "fdivd 'vd, 'vn, 'vm"); | 1350 Format(instr, "fdivd 'vd, 'vn, 'vm"); |
| 1402 break; | 1351 break; |
| 1403 case 2: | 1352 case 2: |
| 1404 Format(instr, "faddd 'vd, 'vn, 'vm"); | 1353 Format(instr, "faddd 'vd, 'vn, 'vm"); |
| 1405 break; | 1354 break; |
| 1406 case 3: | 1355 case 3: |
| 1407 Format(instr, "fsubd 'vd, 'vn, 'vm"); | 1356 Format(instr, "fsubd 'vd, 'vn, 'vm"); |
| 1408 break; | 1357 break; |
| 1409 default: | 1358 default: |
| 1410 Unknown(instr); | 1359 Unknown(instr); |
| 1411 break; | 1360 break; |
| 1412 } | 1361 } |
| 1413 } | 1362 } |
| 1414 | 1363 |
| 1415 | |
| 1416 void ARM64Decoder::DecodeFPCompare(Instr* instr) { | 1364 void ARM64Decoder::DecodeFPCompare(Instr* instr) { |
| 1417 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { | 1365 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { |
| 1418 Format(instr, "fcmpd 'vn, 'vm"); | 1366 Format(instr, "fcmpd 'vn, 'vm"); |
| 1419 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { | 1367 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { |
| 1420 if (instr->VmField() == V0) { | 1368 if (instr->VmField() == V0) { |
| 1421 Format(instr, "fcmpd 'vn, #0.0"); | 1369 Format(instr, "fcmpd 'vn, #0.0"); |
| 1422 } else { | 1370 } else { |
| 1423 Unknown(instr); | 1371 Unknown(instr); |
| 1424 } | 1372 } |
| 1425 } else { | 1373 } else { |
| 1426 Unknown(instr); | 1374 Unknown(instr); |
| 1427 } | 1375 } |
| 1428 } | 1376 } |
| 1429 | 1377 |
| 1430 | |
| 1431 void ARM64Decoder::DecodeFP(Instr* instr) { | 1378 void ARM64Decoder::DecodeFP(Instr* instr) { |
| 1432 if (instr->IsFPImmOp()) { | 1379 if (instr->IsFPImmOp()) { |
| 1433 DecodeFPImm(instr); | 1380 DecodeFPImm(instr); |
| 1434 } else if (instr->IsFPIntCvtOp()) { | 1381 } else if (instr->IsFPIntCvtOp()) { |
| 1435 DecodeFPIntCvt(instr); | 1382 DecodeFPIntCvt(instr); |
| 1436 } else if (instr->IsFPOneSourceOp()) { | 1383 } else if (instr->IsFPOneSourceOp()) { |
| 1437 DecodeFPOneSource(instr); | 1384 DecodeFPOneSource(instr); |
| 1438 } else if (instr->IsFPTwoSourceOp()) { | 1385 } else if (instr->IsFPTwoSourceOp()) { |
| 1439 DecodeFPTwoSource(instr); | 1386 DecodeFPTwoSource(instr); |
| 1440 } else if (instr->IsFPCompareOp()) { | 1387 } else if (instr->IsFPCompareOp()) { |
| 1441 DecodeFPCompare(instr); | 1388 DecodeFPCompare(instr); |
| 1442 } else { | 1389 } else { |
| 1443 Unknown(instr); | 1390 Unknown(instr); |
| 1444 } | 1391 } |
| 1445 } | 1392 } |
| 1446 | 1393 |
| 1447 | |
| 1448 void ARM64Decoder::DecodeDPSimd2(Instr* instr) { | 1394 void ARM64Decoder::DecodeDPSimd2(Instr* instr) { |
| 1449 if (instr->IsFPOp()) { | 1395 if (instr->IsFPOp()) { |
| 1450 DecodeFP(instr); | 1396 DecodeFP(instr); |
| 1451 } else { | 1397 } else { |
| 1452 Unknown(instr); | 1398 Unknown(instr); |
| 1453 } | 1399 } |
| 1454 } | 1400 } |
| 1455 | 1401 |
| 1456 | |
| 1457 void ARM64Decoder::InstructionDecode(uword pc) { | 1402 void ARM64Decoder::InstructionDecode(uword pc) { |
| 1458 Instr* instr = Instr::At(pc); | 1403 Instr* instr = Instr::At(pc); |
| 1459 | 1404 |
| 1460 if (instr->IsDPImmediateOp()) { | 1405 if (instr->IsDPImmediateOp()) { |
| 1461 DecodeDPImmediate(instr); | 1406 DecodeDPImmediate(instr); |
| 1462 } else if (instr->IsCompareBranchOp()) { | 1407 } else if (instr->IsCompareBranchOp()) { |
| 1463 DecodeCompareBranch(instr); | 1408 DecodeCompareBranch(instr); |
| 1464 } else if (instr->IsLoadStoreOp()) { | 1409 } else if (instr->IsLoadStoreOp()) { |
| 1465 DecodeLoadStore(instr); | 1410 DecodeLoadStore(instr); |
| 1466 } else if (instr->IsDPRegisterOp()) { | 1411 } else if (instr->IsDPRegisterOp()) { |
| 1467 DecodeDPRegister(instr); | 1412 DecodeDPRegister(instr); |
| 1468 } else if (instr->IsDPSimd1Op()) { | 1413 } else if (instr->IsDPSimd1Op()) { |
| 1469 DecodeDPSimd1(instr); | 1414 DecodeDPSimd1(instr); |
| 1470 } else if (instr->IsDPSimd2Op()) { | 1415 } else if (instr->IsDPSimd2Op()) { |
| 1471 DecodeDPSimd2(instr); | 1416 DecodeDPSimd2(instr); |
| 1472 } else { | 1417 } else { |
| 1473 Unknown(instr); | 1418 Unknown(instr); |
| 1474 } | 1419 } |
| 1475 } | 1420 } |
| 1476 | 1421 |
| 1477 | |
| 1478 void Disassembler::DecodeInstruction(char* hex_buffer, | 1422 void Disassembler::DecodeInstruction(char* hex_buffer, |
| 1479 intptr_t hex_size, | 1423 intptr_t hex_size, |
| 1480 char* human_buffer, | 1424 char* human_buffer, |
| 1481 intptr_t human_size, | 1425 intptr_t human_size, |
| 1482 int* out_instr_size, | 1426 int* out_instr_size, |
| 1483 const Code& code, | 1427 const Code& code, |
| 1484 Object** object, | 1428 Object** object, |
| 1485 uword pc) { | 1429 uword pc) { |
| 1486 ARM64Decoder decoder(human_buffer, human_size); | 1430 ARM64Decoder decoder(human_buffer, human_size); |
| 1487 decoder.InstructionDecode(pc); | 1431 decoder.InstructionDecode(pc); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1498 *object = NULL; | 1442 *object = NULL; |
| 1499 } | 1443 } |
| 1500 } | 1444 } |
| 1501 } | 1445 } |
| 1502 | 1446 |
| 1503 #endif // !PRODUCT | 1447 #endif // !PRODUCT |
| 1504 | 1448 |
| 1505 } // namespace dart | 1449 } // namespace dart |
| 1506 | 1450 |
| 1507 #endif // defined TARGET_ARCH_ARM | 1451 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |