Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(831)

Side by Side Diff: runtime/vm/disassembler_arm.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/disassembler.cc ('k') | runtime/vm/disassembler_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/disassembler.h" 5 #include "vm/disassembler.h"
6 6
7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
8 #if defined(TARGET_ARCH_ARM) 8 #if defined(TARGET_ARCH_ARM)
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 70 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
71 71
72 char* buffer_; // Decode instructions into this buffer. 72 char* buffer_; // Decode instructions into this buffer.
73 size_t buffer_size_; // The size of the character buffer. 73 size_t buffer_size_; // The size of the character buffer.
74 size_t buffer_pos_; // Current character position in buffer. 74 size_t buffer_pos_; // Current character position in buffer.
75 75
76 DISALLOW_ALLOCATION(); 76 DISALLOW_ALLOCATION();
77 DISALLOW_COPY_AND_ASSIGN(ARMDecoder); 77 DISALLOW_COPY_AND_ASSIGN(ARMDecoder);
78 }; 78 };
79 79
80
81 // Support for assertions in the ARMDecoder formatting functions. 80 // Support for assertions in the ARMDecoder formatting functions.
82 #define STRING_STARTS_WITH(string, compare_string) \ 81 #define STRING_STARTS_WITH(string, compare_string) \
83 (strncmp(string, compare_string, strlen(compare_string)) == 0) 82 (strncmp(string, compare_string, strlen(compare_string)) == 0)
84 83
85
86 // Append the str to the output buffer. 84 // Append the str to the output buffer.
87 void ARMDecoder::Print(const char* str) { 85 void ARMDecoder::Print(const char* str) {
88 char cur = *str++; 86 char cur = *str++;
89 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { 87 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
90 buffer_[buffer_pos_++] = cur; 88 buffer_[buffer_pos_++] = cur;
91 cur = *str++; 89 cur = *str++;
92 } 90 }
93 buffer_[buffer_pos_] = '\0'; 91 buffer_[buffer_pos_] = '\0';
94 } 92 }
95 93
96
97 // These condition names are defined in a way to match the native disassembler 94 // These condition names are defined in a way to match the native disassembler
98 // formatting. See for example the command "objdump -d <binary file>". 95 // formatting. See for example the command "objdump -d <binary file>".
99 static const char* cond_names[kNumberOfConditions] = { 96 static const char* cond_names[kNumberOfConditions] = {
100 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 97 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
101 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", 98 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
102 }; 99 };
103 100
104
105 // Print the condition guarding the instruction. 101 // Print the condition guarding the instruction.
106 void ARMDecoder::PrintCondition(Instr* instr) { 102 void ARMDecoder::PrintCondition(Instr* instr) {
107 Print(cond_names[instr->ConditionField()]); 103 Print(cond_names[instr->ConditionField()]);
108 } 104 }
109 105
110
111 // These register names are defined in a way to match the native disassembler 106 // These register names are defined in a way to match the native disassembler
112 // formatting, except for register alias pp (r5). 107 // formatting, except for register alias pp (r5).
113 // See for example the command "objdump -d <binary file>". 108 // See for example the command "objdump -d <binary file>".
114 static const char* reg_names[kNumberOfCpuRegisters] = { 109 static const char* reg_names[kNumberOfCpuRegisters] = {
115 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS) 110 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
116 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp", 111 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp",
117 "r8", "r9", "thr", "r11", "ip", "sp", "lr", "pc", 112 "r8", "r9", "thr", "r11", "ip", "sp", "lr", "pc",
118 #else 113 #else
119 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7", 114 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7",
120 "r8", "r9", "thr", "fp", "ip", "sp", "lr", "pc", 115 "r8", "r9", "thr", "fp", "ip", "sp", "lr", "pc",
121 #endif 116 #endif
122 }; 117 };
123 118
124
125 // Print the register name according to the active name converter. 119 // Print the register name according to the active name converter.
126 void ARMDecoder::PrintRegister(int reg) { 120 void ARMDecoder::PrintRegister(int reg) {
127 ASSERT(0 <= reg); 121 ASSERT(0 <= reg);
128 ASSERT(reg < kNumberOfCpuRegisters); 122 ASSERT(reg < kNumberOfCpuRegisters);
129 Print(reg_names[reg]); 123 Print(reg_names[reg]);
130 } 124 }
131 125
132
133 void ARMDecoder::PrintSRegister(int reg) { 126 void ARMDecoder::PrintSRegister(int reg) {
134 ASSERT(0 <= reg); 127 ASSERT(0 <= reg);
135 ASSERT(reg < kNumberOfSRegisters); 128 ASSERT(reg < kNumberOfSRegisters);
136 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 129 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
137 remaining_size_in_buffer(), "s%d", reg); 130 remaining_size_in_buffer(), "s%d", reg);
138 } 131 }
139 132
140
141 void ARMDecoder::PrintDRegister(int reg) { 133 void ARMDecoder::PrintDRegister(int reg) {
142 ASSERT(0 <= reg); 134 ASSERT(0 <= reg);
143 ASSERT(reg < kNumberOfDRegisters); 135 ASSERT(reg < kNumberOfDRegisters);
144 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 136 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
145 remaining_size_in_buffer(), "d%d", reg); 137 remaining_size_in_buffer(), "d%d", reg);
146 } 138 }
147 139
148
149 void ARMDecoder::PrintQRegister(int reg) { 140 void ARMDecoder::PrintQRegister(int reg) {
150 ASSERT(0 <= reg); 141 ASSERT(0 <= reg);
151 ASSERT(reg < kNumberOfQRegisters); 142 ASSERT(reg < kNumberOfQRegisters);
152 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 143 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
153 remaining_size_in_buffer(), "q%d", reg); 144 remaining_size_in_buffer(), "q%d", reg);
154 } 145 }
155 146
156
157 // These shift names are defined in a way to match the native disassembler 147 // These shift names are defined in a way to match the native disassembler
158 // formatting. See for example the command "objdump -d <binary file>". 148 // formatting. See for example the command "objdump -d <binary file>".
159 static const char* shift_names[kMaxShift] = {"lsl", "lsr", "asr", "ror"}; 149 static const char* shift_names[kMaxShift] = {"lsl", "lsr", "asr", "ror"};
160 150
161
162 // Print the register shift operands for the instruction. Generally used for 151 // Print the register shift operands for the instruction. Generally used for
163 // data processing instructions. 152 // data processing instructions.
164 void ARMDecoder::PrintShiftRm(Instr* instr) { 153 void ARMDecoder::PrintShiftRm(Instr* instr) {
165 Shift shift = instr->ShiftField(); 154 Shift shift = instr->ShiftField();
166 int shift_amount = instr->ShiftAmountField(); 155 int shift_amount = instr->ShiftAmountField();
167 int rm = instr->RmField(); 156 int rm = instr->RmField();
168 157
169 PrintRegister(rm); 158 PrintRegister(rm);
170 159
171 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) { 160 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) {
(...skipping 14 matching lines...) Expand all
186 } else { 175 } else {
187 // by register 176 // by register
188 int rs = instr->RsField(); 177 int rs = instr->RsField();
189 buffer_pos_ += 178 buffer_pos_ +=
190 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(), 179 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
191 ", %s ", shift_names[shift]); 180 ", %s ", shift_names[shift]);
192 PrintRegister(rs); 181 PrintRegister(rs);
193 } 182 }
194 } 183 }
195 184
196
197 // Print the immediate operand for the instruction. Generally used for data 185 // Print the immediate operand for the instruction. Generally used for data
198 // processing instructions. 186 // processing instructions.
199 void ARMDecoder::PrintShiftImm(Instr* instr) { 187 void ARMDecoder::PrintShiftImm(Instr* instr) {
200 int rotate = instr->RotateField() * 2; 188 int rotate = instr->RotateField() * 2;
201 int immed8 = instr->Immed8Field(); 189 int immed8 = instr->Immed8Field();
202 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 190 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
203 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 191 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
204 remaining_size_in_buffer(), "#%d", imm); 192 remaining_size_in_buffer(), "#%d", imm);
205 } 193 }
206 194
207
208 // Print PU formatting to reduce complexity of FormatOption. 195 // Print PU formatting to reduce complexity of FormatOption.
209 void ARMDecoder::PrintPU(Instr* instr) { 196 void ARMDecoder::PrintPU(Instr* instr) {
210 switch (instr->PUField()) { 197 switch (instr->PUField()) {
211 case 0: { 198 case 0: {
212 Print("da"); 199 Print("da");
213 break; 200 break;
214 } 201 }
215 case 1: { 202 case 1: {
216 Print("ia"); 203 Print("ia");
217 break; 204 break;
218 } 205 }
219 case 2: { 206 case 2: {
220 Print("db"); 207 Print("db");
221 break; 208 break;
222 } 209 }
223 case 3: { 210 case 3: {
224 Print("ib"); 211 Print("ib");
225 break; 212 break;
226 } 213 }
227 default: { 214 default: {
228 UNREACHABLE(); 215 UNREACHABLE();
229 break; 216 break;
230 } 217 }
231 } 218 }
232 } 219 }
233 220
234
235 // Handle all register based formatting in these functions to reduce the 221 // Handle all register based formatting in these functions to reduce the
236 // complexity of FormatOption. 222 // complexity of FormatOption.
237 int ARMDecoder::FormatRegister(Instr* instr, const char* format) { 223 int ARMDecoder::FormatRegister(Instr* instr, const char* format) {
238 ASSERT(format[0] == 'r'); 224 ASSERT(format[0] == 'r');
239 if (format[1] == 'n') { // 'rn: Rn register 225 if (format[1] == 'n') { // 'rn: Rn register
240 int reg = instr->RnField(); 226 int reg = instr->RnField();
241 PrintRegister(reg); 227 PrintRegister(reg);
242 return 2; 228 return 2;
243 } else if (format[1] == 'd') { // 'rd: Rd register 229 } else if (format[1] == 'd') { // 'rd: Rd register
244 int reg = instr->RdField(); 230 int reg = instr->RdField();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 reg++; 266 reg++;
281 rlist >>= 1; 267 rlist >>= 1;
282 } 268 }
283 Print("}"); 269 Print("}");
284 return 5; 270 return 5;
285 } 271 }
286 UNREACHABLE(); 272 UNREACHABLE();
287 return -1; 273 return -1;
288 } 274 }
289 275
290
291 int ARMDecoder::FormatSRegister(Instr* instr, const char* format) { 276 int ARMDecoder::FormatSRegister(Instr* instr, const char* format) {
292 ASSERT(format[0] == 's'); 277 ASSERT(format[0] == 's');
293 if (format[1] == 'n') { // 'sn: Sn register 278 if (format[1] == 'n') { // 'sn: Sn register
294 int reg = instr->SnField(); 279 int reg = instr->SnField();
295 PrintSRegister(reg); 280 PrintSRegister(reg);
296 return 2; 281 return 2;
297 } else if (format[1] == 'd') { // 'sd: Sd register 282 } else if (format[1] == 'd') { // 'sd: Sd register
298 int reg = instr->SdField(); 283 int reg = instr->SdField();
299 PrintSRegister(reg); 284 PrintSRegister(reg);
300 return 2; 285 return 2;
(...skipping 19 matching lines...) Expand all
320 Print(", "); 305 Print(", ");
321 } 306 }
322 } 307 }
323 Print("}"); 308 Print("}");
324 return 5; 309 return 5;
325 } 310 }
326 UNREACHABLE(); 311 UNREACHABLE();
327 return -1; 312 return -1;
328 } 313 }
329 314
330
331 void ARMDecoder::PrintDRegisterList(int start, int reg_count) { 315 void ARMDecoder::PrintDRegisterList(int start, int reg_count) {
332 Print("{"); 316 Print("{");
333 for (int i = start; i < start + reg_count; i++) { 317 for (int i = start; i < start + reg_count; i++) {
334 PrintDRegister(i); 318 PrintDRegister(i);
335 if (i != start + reg_count - 1) { 319 if (i != start + reg_count - 1) {
336 Print(", "); 320 Print(", ");
337 } 321 }
338 } 322 }
339 Print("}"); 323 Print("}");
340 } 324 }
341 325
342
343 int ARMDecoder::FormatDRegister(Instr* instr, const char* format) { 326 int ARMDecoder::FormatDRegister(Instr* instr, const char* format) {
344 ASSERT(format[0] == 'd'); 327 ASSERT(format[0] == 'd');
345 if (format[1] == 'n') { // 'dn: Dn register 328 if (format[1] == 'n') { // 'dn: Dn register
346 int reg = instr->DnField(); 329 int reg = instr->DnField();
347 PrintDRegister(reg); 330 PrintDRegister(reg);
348 return 2; 331 return 2;
349 } else if (format[1] == 'd') { // 'dd: Dd register 332 } else if (format[1] == 'd') { // 'dd: Dd register
350 int reg = instr->DdField(); 333 int reg = instr->DdField();
351 PrintDRegister(reg); 334 PrintDRegister(reg);
352 return 2; 335 return 2;
(...skipping 11 matching lines...) Expand all
364 ASSERT(STRING_STARTS_WITH(format, "dtbllist")); 347 ASSERT(STRING_STARTS_WITH(format, "dtbllist"));
365 int reg_count = instr->Bits(8, 2) + 1; 348 int reg_count = instr->Bits(8, 2) + 1;
366 int start = (instr->Bit(7) << 4) | instr->Bits(16, 4); 349 int start = (instr->Bit(7) << 4) | instr->Bits(16, 4);
367 PrintDRegisterList(start, reg_count); 350 PrintDRegisterList(start, reg_count);
368 return 8; 351 return 8;
369 } 352 }
370 UNREACHABLE(); 353 UNREACHABLE();
371 return -1; 354 return -1;
372 } 355 }
373 356
374
375 int ARMDecoder::FormatQRegister(Instr* instr, const char* format) { 357 int ARMDecoder::FormatQRegister(Instr* instr, const char* format) {
376 ASSERT(format[0] == 'q'); 358 ASSERT(format[0] == 'q');
377 if (format[1] == 'n') { // 'qn: Qn register 359 if (format[1] == 'n') { // 'qn: Qn register
378 int reg = instr->QnField(); 360 int reg = instr->QnField();
379 PrintQRegister(reg); 361 PrintQRegister(reg);
380 return 2; 362 return 2;
381 } else if (format[1] == 'd') { // 'qd: Qd register 363 } else if (format[1] == 'd') { // 'qd: Qd register
382 int reg = instr->QdField(); 364 int reg = instr->QdField();
383 PrintQRegister(reg); 365 PrintQRegister(reg);
384 return 2; 366 return 2;
385 } else if (format[1] == 'm') { // 'qm: Qm register 367 } else if (format[1] == 'm') { // 'qm: Qm register
386 int reg = instr->QmField(); 368 int reg = instr->QmField();
387 PrintQRegister(reg); 369 PrintQRegister(reg);
388 return 2; 370 return 2;
389 } 371 }
390 UNREACHABLE(); 372 UNREACHABLE();
391 return -1; 373 return -1;
392 } 374 }
393 375
394
395 // FormatOption takes a formatting string and interprets it based on 376 // FormatOption takes a formatting string and interprets it based on
396 // the current instructions. The format string points to the first 377 // the current instructions. The format string points to the first
397 // character of the option string (the option escape has already been 378 // character of the option string (the option escape has already been
398 // consumed by the caller.) FormatOption returns the number of 379 // consumed by the caller.) FormatOption returns the number of
399 // characters that were consumed from the formatting string. 380 // characters that were consumed from the formatting string.
400 int ARMDecoder::FormatOption(Instr* instr, const char* format) { 381 int ARMDecoder::FormatOption(Instr* instr, const char* format) {
401 switch (format[0]) { 382 switch (format[0]) {
402 case 'a': { // 'a: accumulate multiplies 383 case 'a': { // 'a: accumulate multiplies
403 if (instr->Bit(21) == 0) { 384 if (instr->Bit(21) == 0) {
404 Print("ul"); 385 Print("ul");
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 } 597 }
617 default: { 598 default: {
618 UNREACHABLE(); 599 UNREACHABLE();
619 break; 600 break;
620 } 601 }
621 } 602 }
622 UNREACHABLE(); 603 UNREACHABLE();
623 return -1; 604 return -1;
624 } 605 }
625 606
626
627 // Format takes a formatting string for a whole instruction and prints it into 607 // Format takes a formatting string for a whole instruction and prints it into
628 // the output buffer. All escaped options are handed to FormatOption to be 608 // the output buffer. All escaped options are handed to FormatOption to be
629 // parsed further. 609 // parsed further.
630 void ARMDecoder::Format(Instr* instr, const char* format) { 610 void ARMDecoder::Format(Instr* instr, const char* format) {
631 char cur = *format++; 611 char cur = *format++;
632 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) { 612 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
633 if (cur == '\'') { // Single quote is used as the formatting escape. 613 if (cur == '\'') { // Single quote is used as the formatting escape.
634 format += FormatOption(instr, format); 614 format += FormatOption(instr, format);
635 } else { 615 } else {
636 buffer_[buffer_pos_++] = cur; 616 buffer_[buffer_pos_++] = cur;
637 } 617 }
638 cur = *format++; 618 cur = *format++;
639 } 619 }
640 buffer_[buffer_pos_] = '\0'; 620 buffer_[buffer_pos_] = '\0';
641 } 621 }
642 622
643
644 // For currently unimplemented decodings the disassembler calls Unknown(instr) 623 // For currently unimplemented decodings the disassembler calls Unknown(instr)
645 // which will just print "unknown" of the instruction bits. 624 // which will just print "unknown" of the instruction bits.
646 void ARMDecoder::Unknown(Instr* instr) { 625 void ARMDecoder::Unknown(Instr* instr) {
647 Format(instr, "unknown"); 626 Format(instr, "unknown");
648 } 627 }
649 628
650
651 void ARMDecoder::DecodeType01(Instr* instr) { 629 void ARMDecoder::DecodeType01(Instr* instr) {
652 if (!instr->IsDataProcessing()) { 630 if (!instr->IsDataProcessing()) {
653 // miscellaneous, multiply, sync primitives, extra loads and stores. 631 // miscellaneous, multiply, sync primitives, extra loads and stores.
654 if (instr->IsMiscellaneous()) { 632 if (instr->IsMiscellaneous()) {
655 switch (instr->Bits(4, 3)) { 633 switch (instr->Bits(4, 3)) {
656 case 1: { 634 case 1: {
657 if (instr->Bits(21, 2) == 0x3) { 635 if (instr->Bits(21, 2) == 0x3) {
658 Format(instr, "clz'cond 'rd, 'rm"); 636 Format(instr, "clz'cond 'rd, 'rm");
659 } else if (instr->Bits(21, 2) == 0x1) { 637 } else if (instr->Bits(21, 2) == 0x1) {
660 Format(instr, "bx'cond 'rm"); 638 Format(instr, "bx'cond 'rm");
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 } 903 }
926 default: { 904 default: {
927 // The Opcode field is a 4-bit field. 905 // The Opcode field is a 4-bit field.
928 UNREACHABLE(); 906 UNREACHABLE();
929 break; 907 break;
930 } 908 }
931 } 909 }
932 } 910 }
933 } 911 }
934 912
935
936 void ARMDecoder::DecodeType2(Instr* instr) { 913 void ARMDecoder::DecodeType2(Instr* instr) {
937 switch (instr->PUField()) { 914 switch (instr->PUField()) {
938 case 0: { 915 case 0: {
939 if (instr->HasW()) { 916 if (instr->HasW()) {
940 Unknown(instr); // Not used. 917 Unknown(instr); // Not used.
941 } else { 918 } else {
942 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); 919 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
943 } 920 }
944 break; 921 break;
945 } 922 }
(...skipping 14 matching lines...) Expand all
960 break; 937 break;
961 } 938 }
962 default: { 939 default: {
963 // The PU field is a 2-bit field. 940 // The PU field is a 2-bit field.
964 UNREACHABLE(); 941 UNREACHABLE();
965 break; 942 break;
966 } 943 }
967 } 944 }
968 } 945 }
969 946
970
971 void ARMDecoder::DecodeType3(Instr* instr) { 947 void ARMDecoder::DecodeType3(Instr* instr) {
972 if (instr->IsDivision()) { 948 if (instr->IsDivision()) {
973 if (!TargetCPUFeatures::integer_division_supported()) { 949 if (!TargetCPUFeatures::integer_division_supported()) {
974 Unknown(instr); 950 Unknown(instr);
975 return; 951 return;
976 } 952 }
977 if (instr->Bit(21)) { 953 if (instr->Bit(21)) {
978 Format(instr, "udiv'cond 'rn, 'rs, 'rm"); 954 Format(instr, "udiv'cond 'rn, 'rs, 'rm");
979 } else { 955 } else {
980 Format(instr, "sdiv'cond 'rn, 'rs, 'rm"); 956 Format(instr, "sdiv'cond 'rn, 'rs, 'rm");
(...skipping 26 matching lines...) Expand all
1007 break; 983 break;
1008 } 984 }
1009 default: { 985 default: {
1010 // The PU field is a 2-bit field. 986 // The PU field is a 2-bit field.
1011 UNREACHABLE(); 987 UNREACHABLE();
1012 break; 988 break;
1013 } 989 }
1014 } 990 }
1015 } 991 }
1016 992
1017
1018 void ARMDecoder::DecodeType4(Instr* instr) { 993 void ARMDecoder::DecodeType4(Instr* instr) {
1019 if (instr->Bit(22) == 1) { 994 if (instr->Bit(22) == 1) {
1020 Unknown(instr); // Privileged mode currently not supported. 995 Unknown(instr); // Privileged mode currently not supported.
1021 } else if (instr->HasL()) { 996 } else if (instr->HasL()) {
1022 Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); 997 Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
1023 } else { 998 } else {
1024 Format(instr, "stm'cond'pu 'rn'w, 'rlist"); 999 Format(instr, "stm'cond'pu 'rn'w, 'rlist");
1025 } 1000 }
1026 } 1001 }
1027 1002
1028
1029 void ARMDecoder::DecodeType5(Instr* instr) { 1003 void ARMDecoder::DecodeType5(Instr* instr) {
1030 Format(instr, "b'l'cond 'target ; 'dest"); 1004 Format(instr, "b'l'cond 'target ; 'dest");
1031 } 1005 }
1032 1006
1033
1034 void ARMDecoder::DecodeType6(Instr* instr) { 1007 void ARMDecoder::DecodeType6(Instr* instr) {
1035 if (instr->IsVFPDoubleTransfer()) { 1008 if (instr->IsVFPDoubleTransfer()) {
1036 if (instr->Bit(8) == 0) { 1009 if (instr->Bit(8) == 0) {
1037 if (instr->Bit(20) == 1) { 1010 if (instr->Bit(20) == 1) {
1038 Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm, 'sm1}"); 1011 Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm, 'sm1}");
1039 } else { 1012 } else {
1040 Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd, 'rn"); 1013 Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd, 'rn");
1041 } 1014 }
1042 } else { 1015 } else {
1043 if (instr->Bit(20) == 1) { 1016 if (instr->Bit(20) == 1) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 Format(instr, "vstmd'cond'pu 'rn'w, 'dlist"); 1061 Format(instr, "vstmd'cond'pu 'rn'w, 'dlist");
1089 } else { // vstms 1062 } else { // vstms
1090 Format(instr, "vstms'cond'pu 'rn'w, 'slist"); 1063 Format(instr, "vstms'cond'pu 'rn'w, 'slist");
1091 } 1064 }
1092 } 1065 }
1093 } else { 1066 } else {
1094 Unknown(instr); 1067 Unknown(instr);
1095 } 1068 }
1096 } 1069 }
1097 1070
1098
1099 void ARMDecoder::DecodeType7(Instr* instr) { 1071 void ARMDecoder::DecodeType7(Instr* instr) {
1100 if (instr->Bit(24) == 1) { 1072 if (instr->Bit(24) == 1) {
1101 Format(instr, "svc'cond #'svc"); 1073 Format(instr, "svc'cond #'svc");
1102 } else if (instr->IsVFPDataProcessingOrSingleTransfer()) { 1074 } else if (instr->IsVFPDataProcessingOrSingleTransfer()) {
1103 if (instr->Bit(4) == 0) { 1075 if (instr->Bit(4) == 0) {
1104 // VFP Data Processing 1076 // VFP Data Processing
1105 switch (instr->Bits(20, 4) & 0xb) { 1077 switch (instr->Bits(20, 4) & 0xb) {
1106 case 0: { // vmla, vmls floating-point 1078 case 0: { // vmla, vmls floating-point
1107 if (instr->Bit(8) == 0) { 1079 if (instr->Bit(8) == 0) {
1108 if (instr->Bit(6) == 0) { 1080 if (instr->Bit(6) == 0) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 } 1292 }
1321 } else { 1293 } else {
1322 Unknown(instr); 1294 Unknown(instr);
1323 } 1295 }
1324 } 1296 }
1325 } else { 1297 } else {
1326 Unknown(instr); 1298 Unknown(instr);
1327 } 1299 }
1328 } 1300 }
1329 1301
1330
1331 void ARMDecoder::DecodeSIMDDataProcessing(Instr* instr) { 1302 void ARMDecoder::DecodeSIMDDataProcessing(Instr* instr) {
1332 ASSERT(instr->ConditionField() == kSpecialCondition); 1303 ASSERT(instr->ConditionField() == kSpecialCondition);
1333 if (instr->Bit(6) == 1) { 1304 if (instr->Bit(6) == 1) {
1334 if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) && 1305 if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) &&
1335 (instr->Bits(23, 2) == 0)) { 1306 (instr->Bits(23, 2) == 0)) {
1336 Format(instr, "vaddq'sz 'qd, 'qn, 'qm"); 1307 Format(instr, "vaddq'sz 'qd, 'qn, 'qm");
1337 } else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 0) && 1308 } else if ((instr->Bits(8, 4) == 13) && (instr->Bit(4) == 0) &&
1338 (instr->Bits(23, 2) == 0) && (instr->Bit(21) == 0)) { 1309 (instr->Bits(23, 2) == 0) && (instr->Bit(21) == 0)) {
1339 Format(instr, "vaddqs 'qd, 'qn, 'qm"); 1310 Format(instr, "vaddqs 'qd, 'qn, 'qm");
1340 } else if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) && 1311 } else if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) &&
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } else { 1421 } else {
1451 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) && 1422 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) &&
1452 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) { 1423 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) {
1453 Format(instr, "vtbl 'dd, 'dtbllist, 'dm"); 1424 Format(instr, "vtbl 'dd, 'dtbllist, 'dm");
1454 } else { 1425 } else {
1455 Unknown(instr); 1426 Unknown(instr);
1456 } 1427 }
1457 } 1428 }
1458 } 1429 }
1459 1430
1460
1461 void ARMDecoder::InstructionDecode(uword pc) { 1431 void ARMDecoder::InstructionDecode(uword pc) {
1462 Instr* instr = Instr::At(pc); 1432 Instr* instr = Instr::At(pc);
1463 1433
1464 if (instr->ConditionField() == kSpecialCondition) { 1434 if (instr->ConditionField() == kSpecialCondition) {
1465 if ((instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) && 1435 if ((instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) &&
1466 (TargetCPUFeatures::arm_version() != ARMv5TE)) { 1436 (TargetCPUFeatures::arm_version() != ARMv5TE)) {
1467 Format(instr, "clrex"); 1437 Format(instr, "clrex");
1468 } else { 1438 } else {
1469 if (instr->IsSIMDDataProcessing()) { 1439 if (instr->IsSIMDDataProcessing()) {
1470 DecodeSIMDDataProcessing(instr); 1440 DecodeSIMDDataProcessing(instr);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 } 1475 }
1506 default: { 1476 default: {
1507 // The type field is 3-bits in the ARM encoding. 1477 // The type field is 3-bits in the ARM encoding.
1508 UNREACHABLE(); 1478 UNREACHABLE();
1509 break; 1479 break;
1510 } 1480 }
1511 } 1481 }
1512 } 1482 }
1513 } 1483 }
1514 1484
1515
1516 void Disassembler::DecodeInstruction(char* hex_buffer, 1485 void Disassembler::DecodeInstruction(char* hex_buffer,
1517 intptr_t hex_size, 1486 intptr_t hex_size,
1518 char* human_buffer, 1487 char* human_buffer,
1519 intptr_t human_size, 1488 intptr_t human_size,
1520 int* out_instr_size, 1489 int* out_instr_size,
1521 const Code& code, 1490 const Code& code,
1522 Object** object, 1491 Object** object,
1523 uword pc) { 1492 uword pc) {
1524 ARMDecoder decoder(human_buffer, human_size); 1493 ARMDecoder decoder(human_buffer, human_size);
1525 decoder.InstructionDecode(pc); 1494 decoder.InstructionDecode(pc);
(...skipping 10 matching lines...) Expand all
1536 *object = NULL; 1505 *object = NULL;
1537 } 1506 }
1538 } 1507 }
1539 } 1508 }
1540 1509
1541 #endif // !PRODUCT 1510 #endif // !PRODUCT
1542 1511
1543 } // namespace dart 1512 } // namespace dart
1544 1513
1545 #endif // defined TARGET_ARCH_ARM 1514 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/disassembler.cc ('k') | runtime/vm/disassembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698