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

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

Issue 14206002: Adds some floating point instructions to MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
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 10
(...skipping 13 matching lines...) Expand all
24 // Writes one disassembled instruction into 'buffer' (0-terminated). 24 // Writes one disassembled instruction into 'buffer' (0-terminated).
25 // Returns true if the instruction was successfully decoded, false otherwise. 25 // Returns true if the instruction was successfully decoded, false otherwise.
26 void InstructionDecode(Instr* instr); 26 void InstructionDecode(Instr* instr);
27 27
28 private: 28 private:
29 // Bottleneck functions to print into the out_buffer. 29 // Bottleneck functions to print into the out_buffer.
30 void Print(const char* str); 30 void Print(const char* str);
31 31
32 // Printing of common values. 32 // Printing of common values.
33 void PrintRegister(Register reg); 33 void PrintRegister(Register reg);
34 void PrintFRegister(FRegister reg);
35 void PrintFormat(Instr* instr);
34 36
35 int FormatRegister(Instr* instr, const char* format); 37 int FormatRegister(Instr* instr, const char* format);
38 int FormatFRegister(Instr* instr, const char* format);
36 int FormatOption(Instr* instr, const char* format); 39 int FormatOption(Instr* instr, const char* format);
37 void Format(Instr* instr, const char* format); 40 void Format(Instr* instr, const char* format);
38 void Unknown(Instr* instr); 41 void Unknown(Instr* instr);
39 42
40 void DecodeSpecial(Instr* instr); 43 void DecodeSpecial(Instr* instr);
41 void DecodeSpecial2(Instr* instr); 44 void DecodeSpecial2(Instr* instr);
42 void DecodeRegImm(Instr* instr); 45 void DecodeRegImm(Instr* instr);
46 void DecodeCop1(Instr* instr);
43 47
44 // Convenience functions. 48 // Convenience functions.
45 char* get_buffer() const { return buffer_; } 49 char* get_buffer() const { return buffer_; }
46 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 50 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
47 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 51 size_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
48 52
49 char* buffer_; // Decode instructions into this buffer. 53 char* buffer_; // Decode instructions into this buffer.
50 size_t buffer_size_; // The size of the character buffer. 54 size_t buffer_size_; // The size of the character buffer.
51 size_t buffer_pos_; // Current character position in buffer. 55 size_t buffer_pos_; // Current character position in buffer.
52 56
(...skipping 19 matching lines...) Expand all
72 76
73 77
74 static const char* reg_names[kNumberOfCpuRegisters] = { 78 static const char* reg_names[kNumberOfCpuRegisters] = {
75 "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" , 79 "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" ,
76 "r8" , "r9" , "r10", "r11", "r12", "r13", "r14", "r15", 80 "r8" , "r9" , "r10", "r11", "r12", "r13", "r14", "r15",
77 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 81 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
78 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 82 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
79 }; 83 };
80 84
81 85
86 static const char* freg_names[kNumberOfFRegisters] = {
87 "f0" , "f1" , "f2" , "f3" , "f4" , "f5" , "f6" , "f7" ,
88 "f8" , "f9" , "f10", "f11", "f12", "f13", "f14", "f15",
89 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
90 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
91 };
92
93
82 void MIPSDecoder::PrintRegister(Register reg) { 94 void MIPSDecoder::PrintRegister(Register reg) {
83 ASSERT(0 <= reg); 95 ASSERT(0 <= reg);
84 ASSERT(reg < kNumberOfCpuRegisters); 96 ASSERT(reg < kNumberOfCpuRegisters);
85 Print(reg_names[reg]); 97 Print(reg_names[reg]);
86 } 98 }
87 99
88 100
101 void MIPSDecoder::PrintFRegister(FRegister reg) {
102 ASSERT(0 <= reg);
103 ASSERT(reg < kNumberOfFRegisters);
104 Print(freg_names[reg]);
105 }
106
107
89 // Handle all register based formatting in these functions to reduce the 108 // Handle all register based formatting in these functions to reduce the
90 // complexity of FormatOption. 109 // complexity of FormatOption.
91 int MIPSDecoder::FormatRegister(Instr* instr, const char* format) { 110 int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
92 ASSERT(format[0] == 'r'); 111 ASSERT(format[0] == 'r');
93 switch (format[1]) { 112 switch (format[1]) {
94 case 's': { // 'rs: Rs register 113 case 's': { // 'rs: Rs register
95 PrintRegister(instr->RsField()); 114 PrintRegister(instr->RsField());
96 return 2; 115 return 2;
97 } 116 }
98 case 't': { // 'rt: Rt register 117 case 't': { // 'rt: Rt register
99 PrintRegister(instr->RtField()); 118 PrintRegister(instr->RtField());
100 return 2; 119 return 2;
101 } 120 }
102 case 'd': { // 'rd: Rd register 121 case 'd': { // 'rd: Rd register
103 PrintRegister(instr->RdField()); 122 PrintRegister(instr->RdField());
104 return 2; 123 return 2;
105 } 124 }
106 } 125 }
107 UNREACHABLE(); 126 UNREACHABLE();
108 return -1; 127 return -1;
109 } 128 }
110 129
111 130
131 int MIPSDecoder::FormatFRegister(Instr* instr, const char* format) {
132 ASSERT(format[0] == 'f');
133 switch (format[1]) {
134 case 's': { // 'fs: Fs register
135 PrintFRegister(instr->FsField());
136 return 2;
137 }
138 case 't': { // 'ft: Ft register
139 PrintFRegister(instr->FtField());
140 return 2;
141 }
142 case 'd': { // 'fd: Fd register
143 PrintFRegister(instr->FdField());
144 return 2;
145 }
146 }
147 UNREACHABLE();
148 return -1;
149 }
150
151
152 void MIPSDecoder::PrintFormat(Instr *instr) {
153 switch (instr->FormatField()) {
154 case FMT_S: {
155 Print("s");
156 break;
157 }
158 case FMT_D: {
159 Print("d");
160 break;
161 }
162 case FMT_W: {
163 Print("w");
164 break;
165 }
166 case FMT_L: {
167 Print("l");
168 break;
169 }
170 case FMT_PS: {
171 Print("ps");
172 break;
173 }
174 default: {
175 Print("unknown");
176 break;
177 }
178 }
179 }
180
181
112 // FormatOption takes a formatting string and interprets it based on 182 // FormatOption takes a formatting string and interprets it based on
113 // the current instructions. The format string points to the first 183 // the current instructions. The format string points to the first
114 // character of the option string (the option escape has already been 184 // character of the option string (the option escape has already been
115 // consumed by the caller.) FormatOption returns the number of 185 // consumed by the caller.) FormatOption returns the number of
116 // characters that were consumed from the formatting string. 186 // characters that were consumed from the formatting string.
117 int MIPSDecoder::FormatOption(Instr* instr, const char* format) { 187 int MIPSDecoder::FormatOption(Instr* instr, const char* format) {
118 switch (format[0]) { 188 switch (format[0]) {
119 case 'c': { 189 case 'c': {
120 ASSERT(STRING_STARTS_WITH(format, "code")); 190 ASSERT(STRING_STARTS_WITH(format, "code"));
121 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 191 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 233 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
164 remaining_size_in_buffer(), 234 remaining_size_in_buffer(),
165 "%d", 235 "%d",
166 imm); 236 imm);
167 } 237 }
168 return 4; 238 return 4;
169 } 239 }
170 case 'r': { 240 case 'r': {
171 return FormatRegister(instr, format); 241 return FormatRegister(instr, format);
172 } 242 }
243 case 'f': {
244 if (format[1] == 'm') {
245 ASSERT(STRING_STARTS_WITH(format, "fmt"));
246 PrintFormat(instr);
247 return 3;
248 } else {
249 return FormatFRegister(instr, format);
250 }
251 }
173 case 's': { 252 case 's': {
174 ASSERT(STRING_STARTS_WITH(format, "sa")); 253 ASSERT(STRING_STARTS_WITH(format, "sa"));
175 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 254 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
176 remaining_size_in_buffer(), 255 remaining_size_in_buffer(),
177 "%d", 256 "%d",
178 instr->SaField()); 257 instr->SaField());
179 return 2; 258 return 2;
180 } 259 }
181 default: { 260 default: {
182 UNREACHABLE(); 261 UNREACHABLE();
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 Format(instr, "bltzl 'rs, 'dest"); 469 Format(instr, "bltzl 'rs, 'dest");
391 break; 470 break;
392 } 471 }
393 default: { 472 default: {
394 Unknown(instr); 473 Unknown(instr);
395 break; 474 break;
396 } 475 }
397 } 476 }
398 } 477 }
399 478
479 void MIPSDecoder::DecodeCop1(Instr* instr) {
480 ASSERT(instr->OpcodeField() == COP1);
481 if (instr->HasFormat()) {
482 // If the rs field is a valid format, then the function field identifies
483 // the instruction.
484 switch (instr->Cop1FunctionField()) {
485 case COP1_ADD: {
486 Format(instr, "add.'fmt 'fd, 'fs, 'ft");
487 break;
488 }
489 case COP1_MOV: {
490 Format(instr, "mov.'fmt 'fd, 'fs");
491 break;
492 }
493 default: {
494 Unknown(instr);
495 break;
496 }
497 }
498 } else {
499 // If the rs field isn't a valid format, then it must be a sub-opcode.
500 switch (instr->Cop1SubField()) {
501 case COP1_MF: {
502 if (instr->Bits(0, 11) != 0) {
503 Unknown(instr);
504 } else {
505 Format(instr, "mfc1 'rt, 'fs");
506 }
507 break;
508 }
509 case COP1_MT: {
510 if (instr->Bits(0, 11) != 0) {
511 Unknown(instr);
512 } else {
513 Format(instr, "mtc1 'rt, 'fs");
514 }
515 break;
516 }
517 default: {
518 Unknown(instr);
519 break;
520 }
521 }
522 }
523 }
400 524
401 void MIPSDecoder::InstructionDecode(Instr* instr) { 525 void MIPSDecoder::InstructionDecode(Instr* instr) {
402 switch (instr->OpcodeField()) { 526 switch (instr->OpcodeField()) {
403 case SPECIAL: { 527 case SPECIAL: {
404 DecodeSpecial(instr); 528 DecodeSpecial(instr);
405 break; 529 break;
406 } 530 }
407 case SPECIAL2: { 531 case SPECIAL2: {
408 DecodeSpecial2(instr); 532 DecodeSpecial2(instr);
409 break; 533 break;
410 } 534 }
411 case REGIMM: { 535 case REGIMM: {
412 DecodeRegImm(instr); 536 DecodeRegImm(instr);
413 break; 537 break;
414 } 538 }
539 case COP1: {
540 DecodeCop1(instr);
541 break;
542 }
415 case ADDIU: { 543 case ADDIU: {
416 Format(instr, "addiu 'rt, 'rs, 'imms"); 544 Format(instr, "addiu 'rt, 'rs, 'imms");
417 break; 545 break;
418 } 546 }
419 case ANDI: { 547 case ANDI: {
420 Format(instr, "andi 'rt, 'rs, 'immu"); 548 Format(instr, "andi 'rt, 'rs, 'immu");
421 break; 549 break;
422 } 550 }
423 case BEQ: { 551 case BEQ: {
424 Format(instr, "beq 'rs, 'rt, 'dest"); 552 Format(instr, "beq 'rs, 'rt, 'dest");
(...skipping 28 matching lines...) Expand all
453 break; 581 break;
454 } 582 }
455 case LB: { 583 case LB: {
456 Format(instr, "lb 'rt, 'imms('rs)"); 584 Format(instr, "lb 'rt, 'imms('rs)");
457 break; 585 break;
458 } 586 }
459 case LBU: { 587 case LBU: {
460 Format(instr, "lbu 'rt, 'imms('rs)"); 588 Format(instr, "lbu 'rt, 'imms('rs)");
461 break; 589 break;
462 } 590 }
591 case LDC1: {
592 Format(instr, "ldc1 'ft, 'imms('rs)");
593 break;
594 }
463 case LH: { 595 case LH: {
464 Format(instr, "lh 'rt, 'imms('rs)"); 596 Format(instr, "lh 'rt, 'imms('rs)");
465 break; 597 break;
466 } 598 }
467 case LUI: { 599 case LUI: {
468 Format(instr, "lui 'rt, 'immu"); 600 Format(instr, "lui 'rt, 'immu");
469 break; 601 break;
470 } 602 }
471 case LW: { 603 case LW: {
472 Format(instr, "lw 'rt, 'imms('rs)"); 604 Format(instr, "lw 'rt, 'imms('rs)");
473 break; 605 break;
474 } 606 }
607 case LWC1: {
608 Format(instr, "lwc1 'ft, 'imms('rs)");
609 break;
610 }
475 case ORI: { 611 case ORI: {
476 Format(instr, "ori 'rt, 'rs, 'immu"); 612 Format(instr, "ori 'rt, 'rs, 'immu");
477 break; 613 break;
478 } 614 }
479 case SB: { 615 case SB: {
480 Format(instr, "sb 'rt, 'imms('rs)"); 616 Format(instr, "sb 'rt, 'imms('rs)");
481 break; 617 break;
482 } 618 }
483 case SH: { 619 case SH: {
484 Format(instr, "sh 'rt, 'imms('rs)"); 620 Format(instr, "sh 'rt, 'imms('rs)");
485 break; 621 break;
486 } 622 }
623 case SDC1: {
624 Format(instr, "sdc1 'ft, 'imms('rs)");
625 break;
626 }
487 case SW: { 627 case SW: {
488 Format(instr, "sw 'rt, 'imms('rs)"); 628 Format(instr, "sw 'rt, 'imms('rs)");
489 break; 629 break;
490 } 630 }
631 case SWC1: {
632 Format(instr, "swc1 'ft, 'imms('rs)");
633 break;
634 }
491 default: { 635 default: {
492 Unknown(instr); 636 Unknown(instr);
493 break; 637 break;
494 } 638 }
495 } 639 }
496 } 640 }
497 641
498 642
499 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 643 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
500 char* human_buffer, intptr_t human_size, 644 char* human_buffer, intptr_t human_size,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 pc); 683 pc);
540 pc += instruction_length; 684 pc += instruction_length;
541 } 685 }
542 686
543 return; 687 return;
544 } 688 }
545 689
546 } // namespace dart 690 } // namespace dart
547 691
548 #endif // defined TARGET_ARCH_MIPS 692 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698