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 |