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

Side by Side Diff: runtime/vm/disassembler_mips.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_ia32.cc ('k') | runtime/vm/disassembler_x64.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_MIPS. 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
8 #if defined(TARGET_ARCH_MIPS) 8 #if defined(TARGET_ARCH_MIPS)
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "vm/instructions.h" 10 #include "vm/instructions.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 #ifndef PRODUCT 14 #ifndef PRODUCT
15 15
16 class MIPSDecoder : public ValueObject { 16 class MIPSDecoder : public ValueObject {
17 public: 17 public:
18 MIPSDecoder(char* buffer, size_t buffer_size) 18 MIPSDecoder(char* buffer, size_t buffer_size)
19 : buffer_(buffer), 19 : buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) {
20 buffer_size_(buffer_size),
21 buffer_pos_(0) {
22 buffer_[buffer_pos_] = '\0'; 20 buffer_[buffer_pos_] = '\0';
23 } 21 }
24 22
25 ~MIPSDecoder() {} 23 ~MIPSDecoder() {}
26 24
27 // Writes one disassembled instruction into 'buffer' (0-terminated). 25 // Writes one disassembled instruction into 'buffer' (0-terminated).
28 // Returns true if the instruction was successfully decoded, false otherwise. 26 // Returns true if the instruction was successfully decoded, false otherwise.
29 void InstructionDecode(Instr* instr); 27 void InstructionDecode(Instr* instr);
30 28
31 private: 29 private:
(...skipping 14 matching lines...) Expand all
46 void DecodeSpecial(Instr* instr); 44 void DecodeSpecial(Instr* instr);
47 void DecodeSpecial2(Instr* instr); 45 void DecodeSpecial2(Instr* instr);
48 void DecodeRegImm(Instr* instr); 46 void DecodeRegImm(Instr* instr);
49 void DecodeCop1(Instr* instr); 47 void DecodeCop1(Instr* instr);
50 48
51 // Convenience functions. 49 // Convenience functions.
52 char* get_buffer() const { return buffer_; } 50 char* get_buffer() const { return buffer_; }
53 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 51 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
54 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 52 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
55 53
56 char* buffer_; // Decode instructions into this buffer. 54 char* buffer_; // Decode instructions into this buffer.
57 size_t buffer_size_; // The size of the character buffer. 55 size_t buffer_size_; // The size of the character buffer.
58 size_t buffer_pos_; // Current character position in buffer. 56 size_t buffer_pos_; // Current character position in buffer.
59 57
60 DISALLOW_ALLOCATION(); 58 DISALLOW_ALLOCATION();
61 DISALLOW_COPY_AND_ASSIGN(MIPSDecoder); 59 DISALLOW_COPY_AND_ASSIGN(MIPSDecoder);
62 }; 60 };
63 61
64 62
65 // Support for assertions in the MIPSDecoder formatting functions. 63 // Support for assertions in the MIPSDecoder formatting functions.
66 #define STRING_STARTS_WITH(string, compare_string) \ 64 #define STRING_STARTS_WITH(string, compare_string) \
67 (strncmp(string, compare_string, strlen(compare_string)) == 0) 65 (strncmp(string, compare_string, strlen(compare_string)) == 0)
68 66
69 67
70 // Append the str to the output buffer. 68 // Append the str to the output buffer.
71 void MIPSDecoder::Print(const char* str) { 69 void MIPSDecoder::Print(const char* str) {
72 char cur = *str++; 70 char cur = *str++;
73 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { 71 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
74 buffer_[buffer_pos_++] = cur; 72 buffer_[buffer_pos_++] = cur;
75 cur = *str++; 73 cur = *str++;
76 } 74 }
77 buffer_[buffer_pos_] = '\0'; 75 buffer_[buffer_pos_] = '\0';
78 } 76 }
79 77
80 78
81 static const char* reg_names[kNumberOfCpuRegisters] = { 79 static const char* reg_names[kNumberOfCpuRegisters] = {
82 "zr", "at", "v0", "v1" , "a0", "a1", "a2", "a3", 80 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2",
83 "t0", "t1", "t2", "t3" , "t4", "t5", "t6", "t7", 81 "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "thr", "s4", "s5",
84 "s0", "s1", "s2", "thr", "s4", "s5", "s6", "pp", 82 "s6", "pp", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
85 "t8", "t9", "k0", "k1" , "gp", "sp", "fp", "ra",
86 }; 83 };
87 84
88 85
89 static const char* freg_names[kNumberOfFRegisters] = { 86 static const char* freg_names[kNumberOfFRegisters] = {
90 "f0" , "f1" , "f2" , "f3" , "f4" , "f5" , "f6" , "f7" , 87 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
91 "f8" , "f9" , "f10", "f11", "f12", "f13", "f14", "f15", 88 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
92 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 89 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
93 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
94 }; 90 };
95 91
96 92
97 void MIPSDecoder::PrintRegister(Register reg) { 93 void MIPSDecoder::PrintRegister(Register reg) {
98 ASSERT(0 <= reg); 94 ASSERT(0 <= reg);
99 ASSERT(reg < kNumberOfCpuRegisters); 95 ASSERT(reg < kNumberOfCpuRegisters);
100 Print(reg_names[reg]); 96 Print(reg_names[reg]);
101 } 97 }
102 98
103 99
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 case 'd': { // 'fd: Fd register 141 case 'd': { // 'fd: Fd register
146 PrintFRegister(instr->FdField()); 142 PrintFRegister(instr->FdField());
147 return 2; 143 return 2;
148 } 144 }
149 } 145 }
150 UNREACHABLE(); 146 UNREACHABLE();
151 return -1; 147 return -1;
152 } 148 }
153 149
154 150
155 void MIPSDecoder::PrintFormat(Instr *instr) { 151 void MIPSDecoder::PrintFormat(Instr* instr) {
156 switch (instr->FormatField()) { 152 switch (instr->FormatField()) {
157 case FMT_S: { 153 case FMT_S: {
158 Print("s"); 154 Print("s");
159 break; 155 break;
160 } 156 }
161 case FMT_D: { 157 case FMT_D: {
162 Print("d"); 158 Print("d");
163 break; 159 break;
164 } 160 }
165 case FMT_W: { 161 case FMT_W: {
(...skipping 18 matching lines...) Expand all
184 180
185 // FormatOption takes a formatting string and interprets it based on 181 // FormatOption takes a formatting string and interprets it based on
186 // the current instructions. The format string points to the first 182 // the current instructions. The format string points to the first
187 // character of the option string (the option escape has already been 183 // character of the option string (the option escape has already been
188 // consumed by the caller.) FormatOption returns the number of 184 // consumed by the caller.) FormatOption returns the number of
189 // characters that were consumed from the formatting string. 185 // characters that were consumed from the formatting string.
190 int MIPSDecoder::FormatOption(Instr* instr, const char* format) { 186 int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
191 switch (format[0]) { 187 switch (format[0]) {
192 case 'c': { 188 case 'c': {
193 ASSERT(STRING_STARTS_WITH(format, "code")); 189 ASSERT(STRING_STARTS_WITH(format, "code"));
194 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 190 buffer_pos_ +=
195 remaining_size_in_buffer(), 191 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
196 "0x%x", 192 "0x%x", instr->BreakCodeField());
197 instr->BreakCodeField());
198 return 4; 193 return 4;
199 } 194 }
200 case 'h': { 195 case 'h': {
201 ASSERT(STRING_STARTS_WITH(format, "hint")); 196 ASSERT(STRING_STARTS_WITH(format, "hint"));
202 if (instr->SaField() == 0x10) { 197 if (instr->SaField() == 0x10) {
203 // The high bit of the SA field is the only one that means something for 198 // The high bit of the SA field is the only one that means something for
204 // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed. 199 // JALR and JR. TODO(zra): Fill in the other cases for PREF if needed.
205 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 200 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
206 remaining_size_in_buffer(), 201 remaining_size_in_buffer(), ".hb");
207 ".hb");
208 } else if (instr->SaField() != 0) { 202 } else if (instr->SaField() != 0) {
209 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 203 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
210 remaining_size_in_buffer(), 204 remaining_size_in_buffer(), ".unknown");
211 ".unknown");
212 } 205 }
213 return 4; 206 return 4;
214 } 207 }
215 case 'd': { 208 case 'd': {
216 ASSERT(STRING_STARTS_WITH(format, "dest")); 209 ASSERT(STRING_STARTS_WITH(format, "dest"));
217 int off = instr->SImmField() << 2; 210 int off = instr->SImmField() << 2;
218 uword destination = 211 uword destination =
219 reinterpret_cast<uword>(instr) + off + Instr::kInstrSize; 212 reinterpret_cast<uword>(instr) + off + Instr::kInstrSize;
220 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 213 buffer_pos_ +=
221 remaining_size_in_buffer(), 214 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
222 "%#" Px "", 215 "%#" Px "", destination);
223 destination);
224 return 4; 216 return 4;
225 } 217 }
226 case 'i': { 218 case 'i': {
227 ASSERT(STRING_STARTS_WITH(format, "imm")); 219 ASSERT(STRING_STARTS_WITH(format, "imm"));
228 if (format[3] == 'u') { 220 if (format[3] == 'u') {
229 int32_t imm = instr->UImmField(); 221 int32_t imm = instr->UImmField();
230 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 222 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
231 remaining_size_in_buffer(), 223 remaining_size_in_buffer(), "0x%x", imm);
232 "0x%x",
233 imm);
234 } else { 224 } else {
235 ASSERT(STRING_STARTS_WITH(format, "imms")); 225 ASSERT(STRING_STARTS_WITH(format, "imms"));
236 int32_t imm = instr->SImmField(); 226 int32_t imm = instr->SImmField();
237 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 227 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
238 remaining_size_in_buffer(), 228 remaining_size_in_buffer(), "%d", imm);
239 "%d",
240 imm);
241 } 229 }
242 return 4; 230 return 4;
243 } 231 }
244 case 'r': { 232 case 'r': {
245 return FormatRegister(instr, format); 233 return FormatRegister(instr, format);
246 } 234 }
247 case 'f': { 235 case 'f': {
248 if (format[1] == 'm') { 236 if (format[1] == 'm') {
249 ASSERT(STRING_STARTS_WITH(format, "fmt")); 237 ASSERT(STRING_STARTS_WITH(format, "fmt"));
250 PrintFormat(instr); 238 PrintFormat(instr);
251 return 3; 239 return 3;
252 } else { 240 } else {
253 return FormatFRegister(instr, format); 241 return FormatFRegister(instr, format);
254 } 242 }
255 } 243 }
256 case 's': { 244 case 's': {
257 ASSERT(STRING_STARTS_WITH(format, "sa")); 245 ASSERT(STRING_STARTS_WITH(format, "sa"));
258 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 246 buffer_pos_ +=
259 remaining_size_in_buffer(), 247 OS::SNPrint(current_position_in_buffer(), remaining_size_in_buffer(),
260 "%d", 248 "%d", instr->SaField());
261 instr->SaField());
262 return 2; 249 return 2;
263 } 250 }
264 default: { 251 default: { UNREACHABLE(); }
265 UNREACHABLE();
266 }
267 } 252 }
268 UNREACHABLE(); 253 UNREACHABLE();
269 return -1; 254 return -1;
270 } 255 }
271 256
272 257
273 // Format takes a formatting string for a whole instruction and prints it into 258 // Format takes a formatting string for a whole instruction and prints it into
274 // the output buffer. All escaped options are handed to FormatOption to be 259 // the output buffer. All escaped options are handed to FormatOption to be
275 // parsed further. 260 // parsed further.
276 void MIPSDecoder::Format(Instr* instr, const char* format) { 261 void MIPSDecoder::Format(Instr* instr, const char* format) {
277 char cur = *format++; 262 char cur = *format++;
278 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) { 263 while ((cur != 0) && (buffer_pos_ < (buffer_size_ - 1))) {
279 if (cur == '\'') { // Single quote is used as the formatting escape. 264 if (cur == '\'') { // Single quote is used as the formatting escape.
280 format += FormatOption(instr, format); 265 format += FormatOption(instr, format);
281 } else { 266 } else {
282 buffer_[buffer_pos_++] = cur; 267 buffer_[buffer_pos_++] = cur;
283 } 268 }
284 cur = *format++; 269 cur = *format++;
285 } 270 }
286 buffer_[buffer_pos_] = '\0'; 271 buffer_[buffer_pos_] = '\0';
287 } 272 }
288 273
289 274
290 // For currently unimplemented decodings the disassembler calls Unknown(instr) 275 // For currently unimplemented decodings the disassembler calls Unknown(instr)
291 // which will just print "unknown" of the instruction bits. 276 // which will just print "unknown" of the instruction bits.
292 void MIPSDecoder::Unknown(Instr* instr) { 277 void MIPSDecoder::Unknown(Instr* instr) {
293 Format(instr, "unknown"); 278 Format(instr, "unknown");
294 } 279 }
295 280
296 281
297 void MIPSDecoder::DecodeSpecial(Instr* instr) { 282 void MIPSDecoder::DecodeSpecial(Instr* instr) {
298 ASSERT(instr->OpcodeField() == SPECIAL); 283 ASSERT(instr->OpcodeField() == SPECIAL);
299 switch (instr->FunctionField()) { 284 switch (instr->FunctionField()) {
300 case ADDU: { 285 case ADDU: {
301 Format(instr, "addu 'rd, 'rs, 'rt"); 286 Format(instr, "addu 'rd, 'rs, 'rt");
302 break; 287 break;
303 } 288 }
304 case AND: { 289 case AND: {
305 Format(instr, "and 'rd, 'rs, 'rt"); 290 Format(instr, "and 'rd, 'rs, 'rt");
306 break; 291 break;
307 } 292 }
308 case BREAK: { 293 case BREAK: {
309 Format(instr, "break 'code"); 294 Format(instr, "break 'code");
310 if (instr->BreakCodeField() == Instr::kStopMessageCode) { 295 if (instr->BreakCodeField() == Instr::kStopMessageCode) {
311 const char* message = *reinterpret_cast<const char**>( 296 const char* message = *reinterpret_cast<const char**>(
312 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 297 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
313 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 298 buffer_pos_ +=
314 remaining_size_in_buffer(), 299 OS::SNPrint(current_position_in_buffer(),
315 " ; \"%s\"", 300 remaining_size_in_buffer(), " ; \"%s\"", message);
316 message);
317 } 301 }
318 break; 302 break;
319 } 303 }
320 case DIV: { 304 case DIV: {
321 Format(instr, "div 'rs, 'rt"); 305 Format(instr, "div 'rs, 'rt");
322 break; 306 break;
323 } 307 }
324 case DIVU: { 308 case DIVU: {
325 Format(instr, "divu 'rs, 'rt"); 309 Format(instr, "divu 'rs, 'rt");
326 break; 310 break;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } else if (instr->RsField() == R0) { 367 } else if (instr->RsField() == R0) {
384 Format(instr, "mov 'rd, 'rt"); 368 Format(instr, "mov 'rd, 'rt");
385 } else if (instr->RtField() == R0) { 369 } else if (instr->RtField() == R0) {
386 Format(instr, "mov 'rd, 'rs"); 370 Format(instr, "mov 'rd, 'rs");
387 } else { 371 } else {
388 Format(instr, "or 'rd, 'rs, 'rt"); 372 Format(instr, "or 'rd, 'rs, 'rt");
389 } 373 }
390 break; 374 break;
391 } 375 }
392 case SLL: { 376 case SLL: {
393 if ((instr->RdField() == R0) && 377 if ((instr->RdField() == R0) && (instr->RtField() == R0) &&
394 (instr->RtField() == R0) &&
395 (instr->SaField() == 0)) { 378 (instr->SaField() == 0)) {
396 Format(instr, "nop"); 379 Format(instr, "nop");
397 } else { 380 } else {
398 Format(instr, "sll 'rd, 'rt, 'sa"); 381 Format(instr, "sll 'rd, 'rt, 'sa");
399 } 382 }
400 break; 383 break;
401 } 384 }
402 case SLLV: { 385 case SLLV: {
403 Format(instr, "sllv 'rd, 'rt, 'rs"); 386 Format(instr, "sllv 'rd, 'rt, 'rs");
404 break; 387 break;
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 break; 753 break;
771 } 754 }
772 default: { 755 default: {
773 Unknown(instr); 756 Unknown(instr);
774 break; 757 break;
775 } 758 }
776 } 759 }
777 } 760 }
778 761
779 762
780 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 763 void Disassembler::DecodeInstruction(char* hex_buffer,
781 char* human_buffer, intptr_t human_size, 764 intptr_t hex_size,
782 int* out_instr_len, const Code& code, 765 char* human_buffer,
783 Object** object, uword pc) { 766 intptr_t human_size,
767 int* out_instr_len,
768 const Code& code,
769 Object** object,
770 uword pc) {
784 MIPSDecoder decoder(human_buffer, human_size); 771 MIPSDecoder decoder(human_buffer, human_size);
785 Instr* instr = Instr::At(pc); 772 Instr* instr = Instr::At(pc);
786 decoder.InstructionDecode(instr); 773 decoder.InstructionDecode(instr);
787 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits()); 774 OS::SNPrint(hex_buffer, hex_size, "%08x", instr->InstructionBits());
788 if (out_instr_len) { 775 if (out_instr_len) {
789 *out_instr_len = Instr::kInstrSize; 776 *out_instr_len = Instr::kInstrSize;
790 } 777 }
791 778
792 *object = NULL; 779 *object = NULL;
793 if (!code.IsNull()) { 780 if (!code.IsNull()) {
794 *object = &Object::Handle(); 781 *object = &Object::Handle();
795 if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) { 782 if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
796 *object = NULL; 783 *object = NULL;
797 } 784 }
798 } 785 }
799 } 786 }
800 787
801 #endif // !PRODUCT 788 #endif // !PRODUCT
802 789
803 } // namespace dart 790 } // namespace dart
804 791
805 #endif // defined TARGET_ARCH_MIPS 792 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_ia32.cc ('k') | runtime/vm/disassembler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698