OLD | NEW |
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 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 // Printing of common values. | 32 // Printing of common values. |
33 void PrintRegister(Register reg); | 33 void PrintRegister(Register reg); |
34 | 34 |
35 int FormatRegister(Instr* instr, const char* format); | 35 int FormatRegister(Instr* instr, const char* format); |
36 int FormatOption(Instr* instr, const char* format); | 36 int FormatOption(Instr* instr, const char* format); |
37 void Format(Instr* instr, const char* format); | 37 void Format(Instr* instr, const char* format); |
38 void Unknown(Instr* instr); | 38 void Unknown(Instr* instr); |
39 | 39 |
40 void DecodeSpecial(Instr* instr); | 40 void DecodeSpecial(Instr* instr); |
41 void DecodeSpecial2(Instr* instr); | 41 void DecodeSpecial2(Instr* instr); |
| 42 void DecodeRegImm(Instr* instr); |
42 | 43 |
43 // Convenience functions. | 44 // Convenience functions. |
44 char* get_buffer() const { return buffer_; } | 45 char* get_buffer() const { return buffer_; } |
45 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } | 46 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } |
46 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } | 47 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } |
47 | 48 |
48 char* buffer_; // Decode instructions into this buffer. | 49 char* buffer_; // Decode instructions into this buffer. |
49 size_t buffer_size_; // The size of the character buffer. | 50 size_t buffer_size_; // The size of the character buffer. |
50 size_t buffer_pos_; // Current character position in buffer. | 51 size_t buffer_pos_; // Current character position in buffer. |
51 | 52 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 131 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
131 remaining_size_in_buffer(), | 132 remaining_size_in_buffer(), |
132 ".hb"); | 133 ".hb"); |
133 } else if (instr->SaField() != 0) { | 134 } else if (instr->SaField() != 0) { |
134 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 135 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
135 remaining_size_in_buffer(), | 136 remaining_size_in_buffer(), |
136 ".unknown"); | 137 ".unknown"); |
137 } | 138 } |
138 return 4; | 139 return 4; |
139 } | 140 } |
| 141 case 'd': { |
| 142 ASSERT(STRING_STARTS_WITH(format, "dest")); |
| 143 int off = instr->SImmField() << 2; |
| 144 uword destination = reinterpret_cast<uword>(instr) + off; |
| 145 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
| 146 remaining_size_in_buffer(), |
| 147 "%#"Px"", |
| 148 destination); |
| 149 return 4; |
| 150 } |
140 case 'i': { | 151 case 'i': { |
141 ASSERT(STRING_STARTS_WITH(format, "imm")); | 152 ASSERT(STRING_STARTS_WITH(format, "imm")); |
142 if (format[3] == 'u') { | 153 if (format[3] == 'u') { |
143 int32_t imm = instr->UImmField(); | 154 int32_t imm = instr->UImmField(); |
144 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), | 155 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), |
145 remaining_size_in_buffer(), | 156 remaining_size_in_buffer(), |
146 "0x%x", | 157 "0x%x", |
147 imm); | 158 imm); |
148 } else { | 159 } else { |
149 ASSERT(STRING_STARTS_WITH(format, "imms")); | 160 ASSERT(STRING_STARTS_WITH(format, "imms")); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 break; | 363 break; |
353 } | 364 } |
354 default: { | 365 default: { |
355 Unknown(instr); | 366 Unknown(instr); |
356 break; | 367 break; |
357 } | 368 } |
358 } | 369 } |
359 } | 370 } |
360 | 371 |
361 | 372 |
| 373 void MIPSDecoder::DecodeRegImm(Instr* instr) { |
| 374 ASSERT(instr->OpcodeField() == REGIMM); |
| 375 switch (instr->RegImmFnField()) { |
| 376 case BGEZ: { |
| 377 Format(instr, "bgez 'rs, 'dest"); |
| 378 break; |
| 379 } |
| 380 case BGEZL: { |
| 381 Format(instr, "bgezl 'rs, 'dest"); |
| 382 break; |
| 383 } |
| 384 case BLTZ: { |
| 385 Format(instr, "bltz 'rs, 'dest"); |
| 386 break; |
| 387 } |
| 388 case BLTZL: { |
| 389 Format(instr, "bltzl 'rs, 'dest"); |
| 390 break; |
| 391 } |
| 392 default: { |
| 393 Unknown(instr); |
| 394 break; |
| 395 } |
| 396 } |
| 397 } |
| 398 |
| 399 |
362 void MIPSDecoder::InstructionDecode(Instr* instr) { | 400 void MIPSDecoder::InstructionDecode(Instr* instr) { |
363 switch (instr->OpcodeField()) { | 401 switch (instr->OpcodeField()) { |
364 case SPECIAL: { | 402 case SPECIAL: { |
365 DecodeSpecial(instr); | 403 DecodeSpecial(instr); |
366 break; | 404 break; |
367 } | 405 } |
368 case SPECIAL2: { | 406 case SPECIAL2: { |
369 DecodeSpecial2(instr); | 407 DecodeSpecial2(instr); |
370 break; | 408 break; |
371 } | 409 } |
| 410 case REGIMM: { |
| 411 DecodeRegImm(instr); |
| 412 break; |
| 413 } |
372 case ADDIU: { | 414 case ADDIU: { |
373 Format(instr, "addiu 'rt, 'rs, 'imms"); | 415 Format(instr, "addiu 'rt, 'rs, 'imms"); |
374 break; | 416 break; |
375 } | 417 } |
376 case ANDI: { | 418 case ANDI: { |
377 Format(instr, "andi 'rt, 'rs, 'immu"); | 419 Format(instr, "andi 'rt, 'rs, 'immu"); |
378 break; | 420 break; |
379 } | 421 } |
| 422 case BEQ: { |
| 423 Format(instr, "beq 'rs, 'rt, 'dest"); |
| 424 break; |
| 425 } |
| 426 case BEQL: { |
| 427 Format(instr, "beql 'rs, 'rt, 'dest"); |
| 428 break; |
| 429 } |
| 430 case BGTZ: { |
| 431 Format(instr, "bgtz 'rs, 'dest"); |
| 432 break; |
| 433 } |
| 434 case BGTZL: { |
| 435 Format(instr, "bgtzl 'rs, 'dest"); |
| 436 break; |
| 437 } |
| 438 case BLEZ: { |
| 439 Format(instr, "blez 'rs, 'dest"); |
| 440 break; |
| 441 } |
| 442 case BLEZL: { |
| 443 Format(instr, "blezl 'rs, 'dest"); |
| 444 break; |
| 445 } |
| 446 case BNE: { |
| 447 Format(instr, "bne 'rs, 'rt, 'dest"); |
| 448 break; |
| 449 } |
| 450 case BNEL: { |
| 451 Format(instr, "bnel 'rs, 'rt, 'dest"); |
| 452 break; |
| 453 } |
380 case LB: { | 454 case LB: { |
381 Format(instr, "lb 'rt, 'imms('rs)"); | 455 Format(instr, "lb 'rt, 'imms('rs)"); |
382 break; | 456 break; |
383 } | 457 } |
384 case LBU: { | 458 case LBU: { |
385 Format(instr, "lbu 'rt, 'imms('rs)"); | 459 Format(instr, "lbu 'rt, 'imms('rs)"); |
386 break; | 460 break; |
387 } | 461 } |
388 case LH: { | 462 case LH: { |
389 Format(instr, "lh 'rt, 'imms('rs)"); | 463 Format(instr, "lh 'rt, 'imms('rs)"); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 pc); | 538 pc); |
465 pc += instruction_length; | 539 pc += instruction_length; |
466 } | 540 } |
467 | 541 |
468 return; | 542 return; |
469 } | 543 } |
470 | 544 |
471 } // namespace dart | 545 } // namespace dart |
472 | 546 |
473 #endif // defined TARGET_ARCH_MIPS | 547 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |