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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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"
11 #include "vm/instructions.h" 11 #include "vm/instructions.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 #ifndef PRODUCT 15 #ifndef PRODUCT
16 16
17 class ARMDecoder : public ValueObject { 17 class ARMDecoder : public ValueObject {
18 public: 18 public:
19 ARMDecoder(char* buffer, size_t buffer_size) 19 ARMDecoder(char* buffer, size_t buffer_size)
20 : buffer_(buffer), 20 : buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) {
21 buffer_size_(buffer_size),
22 buffer_pos_(0) {
23 buffer_[buffer_pos_] = '\0'; 21 buffer_[buffer_pos_] = '\0';
24 } 22 }
25 23
26 ~ARMDecoder() {} 24 ~ARMDecoder() {}
27 25
28 // Writes one disassembled instruction into 'buffer' (0-terminated). 26 // Writes one disassembled instruction into 'buffer' (0-terminated).
29 // Returns true if the instruction was successfully decoded, false otherwise. 27 // Returns true if the instruction was successfully decoded, false otherwise.
30 void InstructionDecode(uword pc); 28 void InstructionDecode(uword pc);
31 29
32 private: 30 private:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 void DecodeType5(Instr* instr); 62 void DecodeType5(Instr* instr);
65 void DecodeType6(Instr* instr); 63 void DecodeType6(Instr* instr);
66 void DecodeType7(Instr* instr); 64 void DecodeType7(Instr* instr);
67 void DecodeSIMDDataProcessing(Instr* instr); 65 void DecodeSIMDDataProcessing(Instr* instr);
68 66
69 // Convenience functions. 67 // Convenience functions.
70 char* get_buffer() const { return buffer_; } 68 char* get_buffer() const { return buffer_; }
71 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 69 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
72 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 70 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
73 71
74 char* buffer_; // Decode instructions into this buffer. 72 char* buffer_; // Decode instructions into this buffer.
75 size_t buffer_size_; // The size of the character buffer. 73 size_t buffer_size_; // The size of the character buffer.
76 size_t buffer_pos_; // Current character position in buffer. 74 size_t buffer_pos_; // Current character position in buffer.
77 75
78 DISALLOW_ALLOCATION(); 76 DISALLOW_ALLOCATION();
79 DISALLOW_COPY_AND_ASSIGN(ARMDecoder); 77 DISALLOW_COPY_AND_ASSIGN(ARMDecoder);
80 }; 78 };
81 79
82 80
83 // Support for assertions in the ARMDecoder formatting functions. 81 // Support for assertions in the ARMDecoder formatting functions.
84 #define STRING_STARTS_WITH(string, compare_string) \ 82 #define STRING_STARTS_WITH(string, compare_string) \
85 (strncmp(string, compare_string, strlen(compare_string)) == 0) 83 (strncmp(string, compare_string, strlen(compare_string)) == 0)
86 84
87 85
88 // Append the str to the output buffer. 86 // Append the str to the output buffer.
89 void ARMDecoder::Print(const char* str) { 87 void ARMDecoder::Print(const char* str) {
90 char cur = *str++; 88 char cur = *str++;
91 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { 89 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
92 buffer_[buffer_pos_++] = cur; 90 buffer_[buffer_pos_++] = cur;
93 cur = *str++; 91 cur = *str++;
94 } 92 }
95 buffer_[buffer_pos_] = '\0'; 93 buffer_[buffer_pos_] = '\0';
96 } 94 }
97 95
98 96
99 // These condition names are defined in a way to match the native disassembler 97 // These condition names are defined in a way to match the native disassembler
100 // formatting. See for example the command "objdump -d <binary file>". 98 // formatting. See for example the command "objdump -d <binary file>".
101 static const char* cond_names[kMaxCondition] = { 99 static const char* cond_names[kMaxCondition] = {
102 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" , 100 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
103 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", 101 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
104 }; 102 };
105 103
106 104
107 // Print the condition guarding the instruction. 105 // Print the condition guarding the instruction.
108 void ARMDecoder::PrintCondition(Instr* instr) { 106 void ARMDecoder::PrintCondition(Instr* instr) {
109 Print(cond_names[instr->ConditionField()]); 107 Print(cond_names[instr->ConditionField()]);
110 } 108 }
111 109
112 110
113 // These register names are defined in a way to match the native disassembler 111 // These register names are defined in a way to match the native disassembler
114 // formatting, except for register alias pp (r5). 112 // formatting, except for register alias pp (r5).
115 // See for example the command "objdump -d <binary file>". 113 // See for example the command "objdump -d <binary file>".
116 static const char* reg_names[kNumberOfCpuRegisters] = { 114 static const char* reg_names[kNumberOfCpuRegisters] = {
117 #if defined(TARGET_ABI_IOS) 115 #if defined(TARGET_ABI_IOS)
118 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp", 116 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp",
119 "r8", "r9", "thr", "r11", "ip", "sp", "lr", "pc", 117 "r8", "r9", "thr", "r11", "ip", "sp", "lr", "pc",
120 #elif defined(TARGET_ABI_EABI) 118 #elif defined(TARGET_ABI_EABI)
121 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7", 119 "r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7",
122 "r8", "r9", "thr", "fp", "ip", "sp", "lr", "pc", 120 "r8", "r9", "thr", "fp", "ip", "sp", "lr", "pc",
123 #else 121 #else
124 #error Unknown ABI 122 #error Unknown ABI
125 #endif 123 #endif
126 }; 124 };
127 125
128 126
129 // Print the register name according to the active name converter. 127 // Print the register name according to the active name converter.
130 void ARMDecoder::PrintRegister(int reg) { 128 void ARMDecoder::PrintRegister(int reg) {
131 ASSERT(0 <= reg); 129 ASSERT(0 <= reg);
132 ASSERT(reg < kNumberOfCpuRegisters); 130 ASSERT(reg < kNumberOfCpuRegisters);
133 Print(reg_names[reg]); 131 Print(reg_names[reg]);
134 } 132 }
135 133
136 134
137 void ARMDecoder::PrintSRegister(int reg) { 135 void ARMDecoder::PrintSRegister(int reg) {
138 ASSERT(0 <= reg); 136 ASSERT(0 <= reg);
139 ASSERT(reg < kNumberOfSRegisters); 137 ASSERT(reg < kNumberOfSRegisters);
140 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 138 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
141 remaining_size_in_buffer(), 139 remaining_size_in_buffer(), "s%d", reg);
142 "s%d", reg);
143 } 140 }
144 141
145 142
146 void ARMDecoder::PrintDRegister(int reg) { 143 void ARMDecoder::PrintDRegister(int reg) {
147 ASSERT(0 <= reg); 144 ASSERT(0 <= reg);
148 ASSERT(reg < kNumberOfDRegisters); 145 ASSERT(reg < kNumberOfDRegisters);
149 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 146 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
150 remaining_size_in_buffer(), 147 remaining_size_in_buffer(), "d%d", reg);
151 "d%d", reg);
152 } 148 }
153 149
154 150
155 void ARMDecoder::PrintQRegister(int reg) { 151 void ARMDecoder::PrintQRegister(int reg) {
156 ASSERT(0 <= reg); 152 ASSERT(0 <= reg);
157 ASSERT(reg < kNumberOfQRegisters); 153 ASSERT(reg < kNumberOfQRegisters);
158 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 154 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
159 remaining_size_in_buffer(), 155 remaining_size_in_buffer(), "q%d", reg);
160 "q%d", reg);
161 } 156 }
162 157
163 158
164 // These shift names are defined in a way to match the native disassembler 159 // These shift names are defined in a way to match the native disassembler
165 // formatting. See for example the command "objdump -d <binary file>". 160 // formatting. See for example the command "objdump -d <binary file>".
166 static const char* shift_names[kMaxShift] = { 161 static const char* shift_names[kMaxShift] = {"lsl", "lsr", "asr", "ror"};
167 "lsl", "lsr", "asr", "ror"
168 };
169 162
170 163
171 // Print the register shift operands for the instruction. Generally used for 164 // Print the register shift operands for the instruction. Generally used for
172 // data processing instructions. 165 // data processing instructions.
173 void ARMDecoder::PrintShiftRm(Instr* instr) { 166 void ARMDecoder::PrintShiftRm(Instr* instr) {
174 Shift shift = instr->ShiftField(); 167 Shift shift = instr->ShiftField();
175 int shift_amount = instr->ShiftAmountField(); 168 int shift_amount = instr->ShiftAmountField();
176 int rm = instr->RmField(); 169 int rm = instr->RmField();
177 170
178 PrintRegister(rm); 171 PrintRegister(rm);
179 172
180 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) { 173 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) {
181 // Special case for using rm only. 174 // Special case for using rm only.
182 return; 175 return;
183 } 176 }
184 if (instr->RegShiftField() == 0) { 177 if (instr->RegShiftField() == 0) {
185 // by immediate 178 // by immediate
186 if ((shift == ROR) && (shift_amount == 0)) { 179 if ((shift == ROR) && (shift_amount == 0)) {
187 Print(", RRX"); 180 Print(", RRX");
188 return; 181 return;
189 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { 182 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
190 shift_amount = 32; 183 shift_amount = 32;
191 } 184 }
192 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 185 buffer_pos_ +=
193 remaining_size_in_buffer(), 186 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
194 ", %s #%d", 187 ", %s #%d", shift_names[shift], shift_amount);
195 shift_names[shift],
196 shift_amount);
197 } else { 188 } else {
198 // by register 189 // by register
199 int rs = instr->RsField(); 190 int rs = instr->RsField();
200 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 191 buffer_pos_ +=
201 remaining_size_in_buffer(), 192 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
202 ", %s ", 193 ", %s ", shift_names[shift]);
203 shift_names[shift]);
204 PrintRegister(rs); 194 PrintRegister(rs);
205 } 195 }
206 } 196 }
207 197
208 198
209 // Print the immediate operand for the instruction. Generally used for data 199 // Print the immediate operand for the instruction. Generally used for data
210 // processing instructions. 200 // processing instructions.
211 void ARMDecoder::PrintShiftImm(Instr* instr) { 201 void ARMDecoder::PrintShiftImm(Instr* instr) {
212 int rotate = instr->RotateField() * 2; 202 int rotate = instr->RotateField() * 2;
213 int immed8 = instr->Immed8Field(); 203 int immed8 = instr->Immed8Field();
214 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 204 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
215 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 205 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
216 remaining_size_in_buffer(), 206 remaining_size_in_buffer(), "#%d", imm);
217 "#%d",
218 imm);
219 } 207 }
220 208
221 209
222 // Print PU formatting to reduce complexity of FormatOption. 210 // Print PU formatting to reduce complexity of FormatOption.
223 void ARMDecoder::PrintPU(Instr* instr) { 211 void ARMDecoder::PrintPU(Instr* instr) {
224 switch (instr->PUField()) { 212 switch (instr->PUField()) {
225 case 0: { 213 case 0: {
226 Print("da"); 214 Print("da");
227 break; 215 break;
228 } 216 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 case 'c': { // 'cond: conditional execution 418 case 'c': { // 'cond: conditional execution
431 ASSERT(STRING_STARTS_WITH(format, "cond")); 419 ASSERT(STRING_STARTS_WITH(format, "cond"));
432 PrintCondition(instr); 420 PrintCondition(instr);
433 return 4; 421 return 4;
434 } 422 }
435 case 'd': { 423 case 'd': {
436 if (format[1] == 'e') { // 'dest: branch destination 424 if (format[1] == 'e') { // 'dest: branch destination
437 ASSERT(STRING_STARTS_WITH(format, "dest")); 425 ASSERT(STRING_STARTS_WITH(format, "dest"));
438 int off = (instr->SImmed24Field() << 2) + 8; 426 int off = (instr->SImmed24Field() << 2) + 8;
439 uword destination = reinterpret_cast<uword>(instr) + off; 427 uword destination = reinterpret_cast<uword>(instr) + off;
440 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 428 buffer_pos_ +=
441 remaining_size_in_buffer(), 429 OS::SNPrint(current_position_in_buffer(),
442 "%#" Px "", 430 remaining_size_in_buffer(), "%#" Px "", destination);
443 destination);
444 return 4; 431 return 4;
445 } else { 432 } else {
446 return FormatDRegister(instr, format); 433 return FormatDRegister(instr, format);
447 } 434 }
448 } 435 }
449 case 'q': { 436 case 'q': {
450 return FormatQRegister(instr, format); 437 return FormatQRegister(instr, format);
451 } 438 }
452 case 'i': { // 'imm12_4, imm4_12, immf, or immd 439 case 'i': { // 'imm12_4, imm4_12, immf, or immd
453 uint16_t immed16; 440 uint16_t immed16;
454 if (format[3] == 'f') { 441 if (format[3] == 'f') {
455 ASSERT(STRING_STARTS_WITH(format, "immf")); 442 ASSERT(STRING_STARTS_WITH(format, "immf"));
456 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 443 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
457 remaining_size_in_buffer(), 444 remaining_size_in_buffer(), "%f",
458 "%f",
459 instr->ImmFloatField()); 445 instr->ImmFloatField());
460 return 4; 446 return 4;
461 } else if (format[3] == 'd') { 447 } else if (format[3] == 'd') {
462 ASSERT(STRING_STARTS_WITH(format, "immd")); 448 ASSERT(STRING_STARTS_WITH(format, "immd"));
463 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 449 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
464 remaining_size_in_buffer(), 450 remaining_size_in_buffer(), "%g",
465 "%g",
466 instr->ImmDoubleField()); 451 instr->ImmDoubleField());
467 return 4; 452 return 4;
468 } else if (format[3] == '1') { 453 } else if (format[3] == '1') {
469 ASSERT(STRING_STARTS_WITH(format, "imm12_4")); 454 ASSERT(STRING_STARTS_WITH(format, "imm12_4"));
470 immed16 = instr->BkptField(); 455 immed16 = instr->BkptField();
471 } else { 456 } else {
472 ASSERT(format[3] == '4'); 457 ASSERT(format[3] == '4');
473 if (format[5] == 'v') { 458 if (format[5] == 'v') {
474 ASSERT(STRING_STARTS_WITH(format, "imm4_vdup")); 459 ASSERT(STRING_STARTS_WITH(format, "imm4_vdup"));
475 int32_t idx = -1; 460 int32_t idx = -1;
476 int32_t imm4 = instr->Bits(16, 4); 461 int32_t imm4 = instr->Bits(16, 4);
477 if ((imm4 & 1) != 0) idx = imm4 >> 1; 462 if ((imm4 & 1) != 0)
478 else if ((imm4 & 2) != 0) idx = imm4 >> 2; 463 idx = imm4 >> 1;
479 else if ((imm4 & 4) != 0) idx = imm4 >> 3; 464 else if ((imm4 & 2) != 0)
465 idx = imm4 >> 2;
466 else if ((imm4 & 4) != 0)
467 idx = imm4 >> 3;
480 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 468 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
481 remaining_size_in_buffer(), 469 remaining_size_in_buffer(), "%d", idx);
482 "%d",
483 idx);
484 return 9; 470 return 9;
485 } else { 471 } else {
486 ASSERT(STRING_STARTS_WITH(format, "imm4_12")); 472 ASSERT(STRING_STARTS_WITH(format, "imm4_12"));
487 immed16 = instr->MovwField(); 473 immed16 = instr->MovwField();
488 } 474 }
489 } 475 }
490 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 476 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
491 remaining_size_in_buffer(), 477 remaining_size_in_buffer(), "0x%x", immed16);
492 "0x%x",
493 immed16);
494 return 7; 478 return 7;
495 } 479 }
496 case 'l': { // 'l: branch and link 480 case 'l': { // 'l: branch and link
497 if (instr->HasLink()) { 481 if (instr->HasLink()) {
498 Print("l"); 482 Print("l");
499 } 483 }
500 return 1; 484 return 1;
501 } 485 }
502 case 'm': { // 'memop: load/store instructions 486 case 'm': { // 'memop: load/store instructions
503 ASSERT(STRING_STARTS_WITH(format, "memop")); 487 ASSERT(STRING_STARTS_WITH(format, "memop"));
504 if (instr->HasL() || 488 if (instr->HasL() ||
505 // Extra load/store instructions. 489 // Extra load/store instructions.
506 ((instr->TypeField() == 0) && instr->HasSign() && !instr->HasH())) { 490 ((instr->TypeField() == 0) && instr->HasSign() && !instr->HasH())) {
507 Print("ldr"); 491 Print("ldr");
508 } else { 492 } else {
509 Print("str"); 493 Print("str");
510 } 494 }
511 return 5; 495 return 5;
512 } 496 }
513 case 'o': { 497 case 'o': {
514 if (format[3] == '1') { 498 if (format[3] == '1') {
515 if (format[4] == '0') { 499 if (format[4] == '0') {
516 // 'off10: 10-bit offset for VFP load and store instructions 500 // 'off10: 10-bit offset for VFP load and store instructions
517 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 501 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
518 remaining_size_in_buffer(), 502 remaining_size_in_buffer(), "%d",
519 "%d",
520 instr->Bits(0, 8) << 2); 503 instr->Bits(0, 8) << 2);
521 } else { 504 } else {
522 // 'off12: 12-bit offset for load and store instructions. 505 // 'off12: 12-bit offset for load and store instructions.
523 ASSERT(STRING_STARTS_WITH(format, "off12")); 506 ASSERT(STRING_STARTS_WITH(format, "off12"));
524 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 507 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
525 remaining_size_in_buffer(), 508 remaining_size_in_buffer(), "%d",
526 "%d",
527 instr->Offset12Field()); 509 instr->Offset12Field());
528 } 510 }
529 return 5; 511 return 5;
530 } 512 }
531 // 'off8: 8-bit offset for extra load and store instructions. 513 // 'off8: 8-bit offset for extra load and store instructions.
532 ASSERT(STRING_STARTS_WITH(format, "off8")); 514 ASSERT(STRING_STARTS_WITH(format, "off8"));
533 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField(); 515 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
534 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 516 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
535 remaining_size_in_buffer(), 517 remaining_size_in_buffer(), "%d", offs8);
536 "%d",
537 offs8);
538 return 4; 518 return 4;
539 } 519 }
540 case 'p': { // 'pu: P and U bits for load and store instructions. 520 case 'p': { // 'pu: P and U bits for load and store instructions.
541 ASSERT(STRING_STARTS_WITH(format, "pu")); 521 ASSERT(STRING_STARTS_WITH(format, "pu"));
542 PrintPU(instr); 522 PrintPU(instr);
543 return 2; 523 return 2;
544 } 524 }
545 case 'r': { 525 case 'r': {
546 return FormatRegister(instr, format); 526 return FormatRegister(instr, format);
547 } 527 }
548 case 's': { 528 case 's': {
549 if (format[1] == 'h') { // 'shift_op or 'shift_rm 529 if (format[1] == 'h') { // 'shift_op or 'shift_rm
550 if (format[6] == 'o') { // 'shift_op 530 if (format[6] == 'o') { // 'shift_op
551 ASSERT(STRING_STARTS_WITH(format, "shift_op")); 531 ASSERT(STRING_STARTS_WITH(format, "shift_op"));
552 if (instr->TypeField() == 0) { 532 if (instr->TypeField() == 0) {
553 PrintShiftRm(instr); 533 PrintShiftRm(instr);
554 } else { 534 } else {
555 ASSERT(instr->TypeField() == 1); 535 ASSERT(instr->TypeField() == 1);
556 PrintShiftImm(instr); 536 PrintShiftImm(instr);
557 } 537 }
558 return 8; 538 return 8;
559 } else { // 'shift_rm 539 } else { // 'shift_rm
560 ASSERT(STRING_STARTS_WITH(format, "shift_rm")); 540 ASSERT(STRING_STARTS_WITH(format, "shift_rm"));
561 PrintShiftRm(instr); 541 PrintShiftRm(instr);
562 return 8; 542 return 8;
563 } 543 }
564 } else if (format[1] == 'v') { // 'svc 544 } else if (format[1] == 'v') { // 'svc
565 ASSERT(STRING_STARTS_WITH(format, "svc")); 545 ASSERT(STRING_STARTS_WITH(format, "svc"));
566 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 546 buffer_pos_ +=
567 remaining_size_in_buffer(), 547 OS::SNPrint(current_position_in_buffer(),
568 "0x%x", 548 remaining_size_in_buffer(), "0x%x", instr->SvcField());
569 instr->SvcField());
570 return 3; 549 return 3;
571 } else if (format[1] == 'z') { 550 } else if (format[1] == 'z') {
572 // 'sz: Size field of SIMD instructions. 551 // 'sz: Size field of SIMD instructions.
573 int sz = instr->Bits(20, 2); 552 int sz = instr->Bits(20, 2);
574 char const* sz_str; 553 char const* sz_str;
575 switch (sz) { 554 switch (sz) {
576 case 0: sz_str = "b"; break; 555 case 0:
577 case 1: sz_str = "h"; break; 556 sz_str = "b";
578 case 2: sz_str = "w"; break; 557 break;
579 case 3: sz_str = "l"; break; 558 case 1:
580 default: sz_str = "?"; break; 559 sz_str = "h";
560 break;
561 case 2:
562 sz_str = "w";
563 break;
564 case 3:
565 sz_str = "l";
566 break;
567 default:
568 sz_str = "?";
569 break;
581 } 570 }
582 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 571 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
583 remaining_size_in_buffer(), 572 remaining_size_in_buffer(), "%s", sz_str);
584 "%s",
585 sz_str);
586 return 2; 573 return 2;
587 } else if (format[1] == ' ') { 574 } else if (format[1] == ' ') {
588 // 's: S field of data processing instructions. 575 // 's: S field of data processing instructions.
589 if (instr->HasS()) { 576 if (instr->HasS()) {
590 Print("s"); 577 Print("s");
591 } 578 }
592 return 1; 579 return 1;
593 } else { 580 } else {
594 return FormatSRegister(instr, format); 581 return FormatSRegister(instr, format);
595 } 582 }
596 } 583 }
597 case 't': { // 'target: target of branch instructions. 584 case 't': { // 'target: target of branch instructions.
598 ASSERT(STRING_STARTS_WITH(format, "target")); 585 ASSERT(STRING_STARTS_WITH(format, "target"));
599 int off = (instr->SImmed24Field() << 2) + 8; 586 int off = (instr->SImmed24Field() << 2) + 8;
600 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 587 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
601 remaining_size_in_buffer(), 588 remaining_size_in_buffer(), "%+d", off);
602 "%+d",
603 off);
604 return 6; 589 return 6;
605 } 590 }
606 case 'u': { // 'u: signed or unsigned multiplies. 591 case 'u': { // 'u: signed or unsigned multiplies.
607 if (instr->Bit(22) == 0) { 592 if (instr->Bit(22) == 0) {
608 Print("u"); 593 Print("u");
609 } else { 594 } else {
610 Print("s"); 595 Print("s");
611 } 596 }
612 return 1; 597 return 1;
613 } 598 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 void ARMDecoder::Format(Instr* instr, const char* format) { 632 void ARMDecoder::Format(Instr* instr, const char* format) {
648 char cur = *format++; 633 char cur = *format++;
649 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) { 634 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
650 if (cur == '\'') { // Single quote is used as the formatting escape. 635 if (cur == '\'') { // Single quote is used as the formatting escape.
651 format += FormatOption(instr, format); 636 format += FormatOption(instr, format);
652 } else { 637 } else {
653 buffer_[buffer_pos_++] = cur; 638 buffer_[buffer_pos_++] = cur;
654 } 639 }
655 cur = *format++; 640 cur = *format++;
656 } 641 }
657 buffer_[buffer_pos_] = '\0'; 642 buffer_[buffer_pos_] = '\0';
658 } 643 }
659 644
660 645
661 // For currently unimplemented decodings the disassembler calls Unknown(instr) 646 // For currently unimplemented decodings the disassembler calls Unknown(instr)
662 // which will just print "unknown" of the instruction bits. 647 // which will just print "unknown" of the instruction bits.
663 void ARMDecoder::Unknown(Instr* instr) { 648 void ARMDecoder::Unknown(Instr* instr) {
664 Format(instr, "unknown"); 649 Format(instr, "unknown");
665 } 650 }
666 651
667 652
(...skipping 20 matching lines...) Expand all
688 Unknown(instr); 673 Unknown(instr);
689 } 674 }
690 break; 675 break;
691 } 676 }
692 case 7: { 677 case 7: {
693 if ((instr->Bits(21, 2) == 0x1) && (instr->ConditionField() == AL)) { 678 if ((instr->Bits(21, 2) == 0x1) && (instr->ConditionField() == AL)) {
694 Format(instr, "bkpt #'imm12_4"); 679 Format(instr, "bkpt #'imm12_4");
695 if (instr->BkptField() == Instr::kStopMessageCode) { 680 if (instr->BkptField() == Instr::kStopMessageCode) {
696 const char* message = *reinterpret_cast<const char**>( 681 const char* message = *reinterpret_cast<const char**>(
697 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 682 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
698 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 683 buffer_pos_ +=
699 remaining_size_in_buffer(), 684 OS::SNPrint(current_position_in_buffer(),
700 " ; \"%s\"", 685 remaining_size_in_buffer(), " ; \"%s\"", message);
701 message);
702 } 686 }
703 } else { 687 } else {
704 // Format(instr, "smc'cond"); 688 // Format(instr, "smc'cond");
705 Unknown(instr); // Not used. 689 Unknown(instr); // Not used.
706 } 690 }
707 break; 691 break;
708 } 692 }
709 default: { 693 default: {
710 Unknown(instr); // Not used. 694 Unknown(instr); // Not used.
711 break; 695 break;
712 } 696 }
713 } 697 }
714 } else if (instr->IsMultiplyOrSyncPrimitive()) { 698 } else if (instr->IsMultiplyOrSyncPrimitive()) {
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 } else { 1041 } else {
1058 Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd, 'rn"); 1042 Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd, 'rn");
1059 } 1043 }
1060 } else { 1044 } else {
1061 if (instr->Bit(20) == 1) { 1045 if (instr->Bit(20) == 1) {
1062 Format(instr, "vmovrrd'cond 'rd, 'rn, 'dm"); 1046 Format(instr, "vmovrrd'cond 'rd, 'rn, 'dm");
1063 } else { 1047 } else {
1064 Format(instr, "vmovdrr'cond 'dm, 'rd, 'rn"); 1048 Format(instr, "vmovdrr'cond 'dm, 'rd, 'rn");
1065 } 1049 }
1066 } 1050 }
1067 } else if (instr-> IsVFPLoadStore()) { 1051 } else if (instr->IsVFPLoadStore()) {
1068 if (instr->Bit(8) == 0) { 1052 if (instr->Bit(8) == 0) {
1069 if (instr->Bit(20) == 1) { // vldrs 1053 if (instr->Bit(20) == 1) { // vldrs
1070 if (instr->Bit(23) == 1) { 1054 if (instr->Bit(23) == 1) {
1071 Format(instr, "vldrs'cond 'sd, ['rn, #+'off10]"); 1055 Format(instr, "vldrs'cond 'sd, ['rn, #+'off10]");
1072 } else { 1056 } else {
1073 Format(instr, "vldrs'cond 'sd, ['rn, #-'off10]"); 1057 Format(instr, "vldrs'cond 'sd, ['rn, #-'off10]");
1074 } 1058 }
1075 } else { // vstrs 1059 } else { // vstrs
1076 if (instr->Bit(23) == 1) { 1060 if (instr->Bit(23) == 1) {
1077 Format(instr, "vstrs'cond 'sd, ['rn, #+'off10]"); 1061 Format(instr, "vstrs'cond 'sd, ['rn, #+'off10]");
(...skipping 10 matching lines...) Expand all
1088 } 1072 }
1089 } else { // vstrd 1073 } else { // vstrd
1090 if (instr->Bit(23) == 1) { 1074 if (instr->Bit(23) == 1) {
1091 Format(instr, "vstrd'cond 'dd, ['rn, #+'off10]"); 1075 Format(instr, "vstrd'cond 'dd, ['rn, #+'off10]");
1092 } else { 1076 } else {
1093 Format(instr, "vstrd'cond 'dd, ['rn, #-'off10]"); 1077 Format(instr, "vstrd'cond 'dd, ['rn, #-'off10]");
1094 } 1078 }
1095 } 1079 }
1096 } 1080 }
1097 } else if (instr->IsVFPMultipleLoadStore()) { 1081 } else if (instr->IsVFPMultipleLoadStore()) {
1098 if (instr->HasL()) { // vldm 1082 if (instr->HasL()) { // vldm
1099 if (instr->Bit(8)) { // vldmd 1083 if (instr->Bit(8)) { // vldmd
1100 Format(instr, "vldmd'cond'pu 'rn'w, 'dlist"); 1084 Format(instr, "vldmd'cond'pu 'rn'w, 'dlist");
1101 } else { // vldms 1085 } else { // vldms
1102 Format(instr, "vldms'cond'pu 'rn'w, 'slist"); 1086 Format(instr, "vldms'cond'pu 'rn'w, 'slist");
1103 } 1087 }
1104 } else { // vstm 1088 } else { // vstm
1105 if (instr->Bit(8)) { // vstmd 1089 if (instr->Bit(8)) { // vstmd
1106 Format(instr, "vstmd'cond'pu 'rn'w, 'dlist"); 1090 Format(instr, "vstmd'cond'pu 'rn'w, 'dlist");
1107 } else { // vstms 1091 } else { // vstms
1108 Format(instr, "vstms'cond'pu 'rn'w, 'slist"); 1092 Format(instr, "vstms'cond'pu 'rn'w, 'slist");
1109 } 1093 }
1110 } 1094 }
1111 } else { 1095 } else {
1112 Unknown(instr); 1096 Unknown(instr);
1113 } 1097 }
1114 } 1098 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 } 1151 }
1168 } else { 1152 } else {
1169 if (instr->Bit(6) == 0) { 1153 if (instr->Bit(6) == 0) {
1170 Format(instr, "vaddd'cond 'dd, 'dn, 'dm"); 1154 Format(instr, "vaddd'cond 'dd, 'dn, 'dm");
1171 } else { 1155 } else {
1172 Format(instr, "vsubd'cond 'dd, 'dn, 'dm"); 1156 Format(instr, "vsubd'cond 'dd, 'dn, 'dm");
1173 } 1157 }
1174 } 1158 }
1175 break; 1159 break;
1176 } 1160 }
1177 case 0xb: { // Other VFP data-processing instructions 1161 case 0xb: { // Other VFP data-processing instructions
1178 if (instr->Bit(6) == 0) { // vmov immediate 1162 if (instr->Bit(6) == 0) { // vmov immediate
1179 if (instr->Bit(8) == 0) { 1163 if (instr->Bit(8) == 0) {
1180 Format(instr, "vmovs'cond 'sd, #'immf"); 1164 Format(instr, "vmovs'cond 'sd, #'immf");
1181 } else { 1165 } else {
1182 Format(instr, "vmovd'cond 'dd, #'immd"); 1166 Format(instr, "vmovd'cond 'dd, #'immd");
1183 } 1167 }
1184 break; 1168 break;
1185 } 1169 }
1186 switch (instr->Bits(16, 4)) { 1170 switch (instr->Bits(16, 4)) {
1187 case 0: { // vmov register, vabs 1171 case 0: { // vmov register, vabs
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1211 }
1228 break; 1212 break;
1229 } 1213 }
1230 default: { 1214 default: {
1231 Unknown(instr); 1215 Unknown(instr);
1232 break; 1216 break;
1233 } 1217 }
1234 } 1218 }
1235 break; 1219 break;
1236 } 1220 }
1237 case 4: // vcmp, vcmpe 1221 case 4: // vcmp, vcmpe
1238 case 5: { // vcmp #0.0, vcmpe #0.0 1222 case 5: { // vcmp #0.0, vcmpe #0.0
1239 if (instr->Bit(7) == 1) { // vcmpe 1223 if (instr->Bit(7) == 1) { // vcmpe
1240 Unknown(instr); 1224 Unknown(instr);
1241 } else { 1225 } else {
1242 if (instr->Bit(8) == 0) { // vcmps 1226 if (instr->Bit(8) == 0) { // vcmps
1243 if (instr->Bit(16) == 0) { 1227 if (instr->Bit(16) == 0) {
1244 Format(instr, "vcmps'cond 'sd, 'sm"); 1228 Format(instr, "vcmps'cond 'sd, 'sm");
1245 } else { 1229 } else {
1246 Format(instr, "vcmps'cond 'sd, #0.0"); 1230 Format(instr, "vcmps'cond 'sd, #0.0");
1247 } 1231 }
1248 } else { // vcmpd 1232 } else { // vcmpd
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 } 1278 }
1295 } else { 1279 } else {
1296 if (instr->Bit(16) == 0) { 1280 if (instr->Bit(16) == 0) {
1297 Format(instr, "vcvtud'cond 'sd, 'dm"); 1281 Format(instr, "vcvtud'cond 'sd, 'dm");
1298 } else { 1282 } else {
1299 Format(instr, "vcvtid'cond 'sd, 'dm"); 1283 Format(instr, "vcvtid'cond 'sd, 'dm");
1300 } 1284 }
1301 } 1285 }
1302 break; 1286 break;
1303 } 1287 }
1304 case 2: // vcvtb, vcvtt 1288 case 2: // vcvtb, vcvtt
1305 case 3: // vcvtb, vcvtt 1289 case 3: // vcvtb, vcvtt
1306 case 9: // undefined 1290 case 9: // undefined
1307 case 10: // vcvt between floating-point and fixed-point 1291 case 10: // vcvt between floating-point and fixed-point
1308 case 11: // vcvt between floating-point and fixed-point 1292 case 11: // vcvt between floating-point and fixed-point
1309 case 14: // vcvt between floating-point and fixed-point 1293 case 14: // vcvt between floating-point and fixed-point
1310 case 15: // vcvt between floating-point and fixed-point 1294 case 15: // vcvt between floating-point and fixed-point
1311 default: { 1295 default: {
1312 Unknown(instr); 1296 Unknown(instr);
1313 break; 1297 break;
1314 } 1298 }
1315 } 1299 }
1316 } 1300 } break;
1317 break;
1318 } 1301 }
1319 } else { 1302 } else {
1320 // 8, 16, or 32-bit Transfer between ARM Core and VFP 1303 // 8, 16, or 32-bit Transfer between ARM Core and VFP
1321 if ((instr->Bits(21, 3) == 0) && (instr->Bit(8) == 0)) { 1304 if ((instr->Bits(21, 3) == 0) && (instr->Bit(8) == 0)) {
1322 if (instr->Bit(20) == 0) { 1305 if (instr->Bit(20) == 0) {
1323 Format(instr, "vmovs'cond 'sn, 'rd"); 1306 Format(instr, "vmovs'cond 'sn, 'rd");
1324 } else { 1307 } else {
1325 Format(instr, "vmovr'cond 'rd, 'sn"); 1308 Format(instr, "vmovr'cond 'rd, 'sn");
1326 } 1309 }
1327 } else if ((instr->Bits(22, 3) == 0) && (instr->Bit(20) == 0) && 1310 } else if ((instr->Bits(22, 3) == 0) && (instr->Bit(20) == 0) &&
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 default: { 1508 default: {
1526 // The type field is 3-bits in the ARM encoding. 1509 // The type field is 3-bits in the ARM encoding.
1527 UNREACHABLE(); 1510 UNREACHABLE();
1528 break; 1511 break;
1529 } 1512 }
1530 } 1513 }
1531 } 1514 }
1532 } 1515 }
1533 1516
1534 1517
1535 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 1518 void Disassembler::DecodeInstruction(char* hex_buffer,
1536 char* human_buffer, intptr_t human_size, 1519 intptr_t hex_size,
1537 int* out_instr_size, const Code& code, 1520 char* human_buffer,
1538 Object** object, uword pc) { 1521 intptr_t human_size,
1522 int* out_instr_size,
1523 const Code& code,
1524 Object** object,
1525 uword pc) {
1539 ARMDecoder decoder(human_buffer, human_size); 1526 ARMDecoder decoder(human_buffer, human_size);
1540 decoder.InstructionDecode(pc); 1527 decoder.InstructionDecode(pc);
1541 int32_t instruction_bits = Instr::At(pc)->InstructionBits(); 1528 int32_t instruction_bits = Instr::At(pc)->InstructionBits();
1542 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits); 1529 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits);
1543 if (out_instr_size) { 1530 if (out_instr_size) {
1544 *out_instr_size = Instr::kInstrSize; 1531 *out_instr_size = Instr::kInstrSize;
1545 } 1532 }
1546 1533
1547 *object = NULL; 1534 *object = NULL;
1548 if (!code.IsNull()) { 1535 if (!code.IsNull()) {
1549 *object = &Object::Handle(); 1536 *object = &Object::Handle();
1550 if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) { 1537 if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
1551 *object = NULL; 1538 *object = NULL;
1552 } 1539 }
1553 } 1540 }
1554 } 1541 }
1555 1542
1556 #endif // !PRODUCT 1543 #endif // !PRODUCT
1557 1544
1558 } // namespace dart 1545 } // namespace dart
1559 1546
1560 #endif // defined TARGET_ARCH_ARM 1547 #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