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

Side by Side Diff: src/mips/disasm-mips.cc

Issue 561072: MIPS port initial commit (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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
« no previous file with comments | « src/mips/debug-mips.cc ('k') | src/mips/fast-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // A Disassembler object is used to disassemble a block of code instruction by
29 // instruction. The default implementation of the NameConverter object can be
30 // overriden to modify register names or to do symbol lookup on addresses.
31 //
32 // The example below will disassemble a block of code and print it to stdout.
33 //
34 // NameConverter converter;
35 // Disassembler d(converter);
36 // for (byte_* pc = begin; pc < end;) {
37 // char buffer[128];
38 // buffer[0] = '\0';
39 // byte_* prev_pc = pc;
40 // pc += d.InstructionDecode(buffer, sizeof buffer, pc);
41 // printf("%p %08x %s\n",
42 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
43 // }
44 //
45 // The Disassembler class also has a convenience method to disassemble a block
46 // of code into a FILE*, meaning that the above functionality could also be
47 // achieved by just calling Disassembler::Disassemble(stdout, begin, end);
48
49
50 #include <assert.h>
51 #include <stdio.h>
52 #include <stdarg.h>
53 #include <string.h>
54 #ifndef WIN32
55 #include <stdint.h>
56 #endif
57
58 #include "v8.h"
59
60 #include "constants-mips.h"
61 #include "disasm.h"
62 #include "macro-assembler.h"
63 #include "platform.h"
64
65 namespace assembler {
66 namespace mips {
67
68
69 namespace v8i = v8::internal;
70
71
72 //------------------------------------------------------------------------------
73
74 // Decoder decodes and disassembles instructions into an output buffer.
75 // It uses the converter to convert register names and call destinations into
76 // more informative description.
77 class Decoder {
78 public:
79 Decoder(const disasm::NameConverter& converter,
80 v8::internal::Vector<char> out_buffer)
81 : converter_(converter),
82 out_buffer_(out_buffer),
83 out_buffer_pos_(0) {
84 out_buffer_[out_buffer_pos_] = '\0';
85 }
86
87 ~Decoder() {}
88
89 // Writes one disassembled instruction into 'buffer' (0-terminated).
90 // Returns the length of the disassembled machine instruction in bytes.
91 int InstructionDecode(byte_* instruction);
92
93 private:
94 // Bottleneck functions to print into the out_buffer.
95 void PrintChar(const char ch);
96 void Print(const char* str);
97
98 // Printing of common values.
99 void PrintRegister(int reg);
100 void PrintCRegister(int creg);
101 void PrintRs(Instruction* instr);
102 void PrintRt(Instruction* instr);
103 void PrintRd(Instruction* instr);
104 void PrintFs(Instruction* instr);
105 void PrintFt(Instruction* instr);
106 void PrintFd(Instruction* instr);
107 void PrintSa(Instruction* instr);
108 void PrintFunction(Instruction* instr);
109 void PrintSecondaryField(Instruction* instr);
110 void PrintUImm16(Instruction* instr);
111 void PrintSImm16(Instruction* instr);
112 void PrintXImm16(Instruction* instr);
113 void PrintImm26(Instruction* instr);
114 void PrintCode(Instruction* instr); // For break and trap instructions.
115 // Printing of instruction name.
116 void PrintInstructionName(Instruction* instr);
117
118 // Handle formatting of instructions and their options.
119 int FormatRegister(Instruction* instr, const char* option);
120 int FormatCRegister(Instruction* instr, const char* option);
121 int FormatOption(Instruction* instr, const char* option);
122 void Format(Instruction* instr, const char* format);
123 void Unknown(Instruction* instr);
124
125 // Each of these functions decodes one particular instruction type.
126 void DecodeTypeRegister(Instruction* instr);
127 void DecodeTypeImmediate(Instruction* instr);
128 void DecodeTypeJump(Instruction* instr);
129
130 const disasm::NameConverter& converter_;
131 v8::internal::Vector<char> out_buffer_;
132 int out_buffer_pos_;
133
134 DISALLOW_COPY_AND_ASSIGN(Decoder);
135 };
136
137
138 // Support for assertions in the Decoder formatting functions.
139 #define STRING_STARTS_WITH(string, compare_string) \
140 (strncmp(string, compare_string, strlen(compare_string)) == 0)
141
142
143 // Append the ch to the output buffer.
144 void Decoder::PrintChar(const char ch) {
145 out_buffer_[out_buffer_pos_++] = ch;
146 }
147
148
149 // Append the str to the output buffer.
150 void Decoder::Print(const char* str) {
151 char cur = *str++;
152 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
153 PrintChar(cur);
154 cur = *str++;
155 }
156 out_buffer_[out_buffer_pos_] = 0;
157 }
158
159
160 // Print the register name according to the active name converter.
161 void Decoder::PrintRegister(int reg) {
162 Print(converter_.NameOfCPURegister(reg));
163 }
164
165
166 void Decoder::PrintRs(Instruction* instr) {
167 int reg = instr->RsField();
168 PrintRegister(reg);
169 }
170
171
172 void Decoder::PrintRt(Instruction* instr) {
173 int reg = instr->RtField();
174 PrintRegister(reg);
175 }
176
177
178 void Decoder::PrintRd(Instruction* instr) {
179 int reg = instr->RdField();
180 PrintRegister(reg);
181 }
182
183
184 // Print the Cregister name according to the active name converter.
185 void Decoder::PrintCRegister(int creg) {
186 Print(converter_.NameOfXMMRegister(creg));
187 }
188
189
190 void Decoder::PrintFs(Instruction* instr) {
191 int creg = instr->RsField();
192 PrintCRegister(creg);
193 }
194
195
196 void Decoder::PrintFt(Instruction* instr) {
197 int creg = instr->RtField();
198 PrintCRegister(creg);
199 }
200
201
202 void Decoder::PrintFd(Instruction* instr) {
203 int creg = instr->RdField();
204 PrintCRegister(creg);
205 }
206
207
208 // Print the integer value of the sa field.
209 void Decoder::PrintSa(Instruction* instr) {
210 int sa = instr->SaField();
211 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
212 "%d", sa);
213 }
214
215
216 // Print 16-bit unsigned immediate value.
217 void Decoder::PrintUImm16(Instruction* instr) {
218 int32_t imm = instr->Imm16Field();
219 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
220 "%u", imm);
221 }
222
223
224 // Print 16-bit signed immediate value.
225 void Decoder::PrintSImm16(Instruction* instr) {
226 int32_t imm = ((instr->Imm16Field())<<16)>>16;
227 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
228 "%d", imm);
229 }
230
231
232 // Print 16-bit hexa immediate value.
233 void Decoder::PrintXImm16(Instruction* instr) {
234 int32_t imm = instr->Imm16Field();
235 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
236 "0x%x", imm);
237 }
238
239
240 // Print 26-bit immediate value.
241 void Decoder::PrintImm26(Instruction* instr) {
242 int32_t imm = instr->Imm26Field();
243 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
244 "%d", imm);
245 }
246
247
248 // Print 26-bit immediate value.
249 void Decoder::PrintCode(Instruction* instr) {
250 if (instr->OpcodeFieldRaw() != SPECIAL)
251 return; // Not a break or trap instruction.
252 switch (instr->FunctionFieldRaw()) {
253 case BREAK: {
254 int32_t code = instr->Bits(25, 6);
255 out_buffer_pos_ +=
256 v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%05x", code);
257 break;
258 }
259 case TGE:
260 case TGEU:
261 case TLT:
262 case TLTU:
263 case TEQ:
264 case TNE: {
265 int32_t code = instr->Bits(15, 6);
266 out_buffer_pos_ +=
267 v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
268 break;
269 }
270 default: // Not a break or trap instruction.
271 break;
272 };
273 }
274
275
276 // Printing of instruction name.
277 void Decoder::PrintInstructionName(Instruction* instr) {
278 }
279
280
281 // Handle all register based formatting in this function to reduce the
282 // complexity of FormatOption.
283 int Decoder::FormatRegister(Instruction* instr, const char* format) {
284 ASSERT(format[0] == 'r');
285 if (format[1] == 's') { // 'rs: Rs register
286 int reg = instr->RsField();
287 PrintRegister(reg);
288 return 2;
289 } else if (format[1] == 't') { // 'rt: rt register
290 int reg = instr->RtField();
291 PrintRegister(reg);
292 return 2;
293 } else if (format[1] == 'd') { // 'rd: rd register
294 int reg = instr->RdField();
295 PrintRegister(reg);
296 return 2;
297 }
298 UNREACHABLE();
299 return -1;
300 }
301
302
303 // Handle all Cregister based formatting in this function to reduce the
304 // complexity of FormatOption.
305 int Decoder::FormatCRegister(Instruction* instr, const char* format) {
306 ASSERT(format[0] == 'f');
307 if (format[1] == 's') { // 'fs: fs register
308 int reg = instr->RsField();
309 PrintCRegister(reg);
310 return 2;
311 } else if (format[1] == 't') { // 'ft: ft register
312 int reg = instr->RtField();
313 PrintCRegister(reg);
314 return 2;
315 } else if (format[1] == 'd') { // 'fd: fd register
316 int reg = instr->RdField();
317 PrintCRegister(reg);
318 return 2;
319 }
320 UNREACHABLE();
321 return -1;
322 }
323
324
325 // FormatOption takes a formatting string and interprets it based on
326 // the current instructions. The format string points to the first
327 // character of the option string (the option escape has already been
328 // consumed by the caller.) FormatOption returns the number of
329 // characters that were consumed from the formatting string.
330 int Decoder::FormatOption(Instruction* instr, const char* format) {
331 switch (format[0]) {
332 case 'c': { // 'code for break or trap instructions
333 ASSERT(STRING_STARTS_WITH(format, "code"));
334 PrintCode(instr);
335 return 4;
336 }
337 case 'i': { // 'imm16u or 'imm26
338 if (format[3] == '1') {
339 ASSERT(STRING_STARTS_WITH(format, "imm16"));
340 if (format[5] == 's') {
341 ASSERT(STRING_STARTS_WITH(format, "imm16s"));
342 PrintSImm16(instr);
343 } else if (format[5] == 'u') {
344 ASSERT(STRING_STARTS_WITH(format, "imm16u"));
345 PrintSImm16(instr);
346 } else {
347 ASSERT(STRING_STARTS_WITH(format, "imm16x"));
348 PrintXImm16(instr);
349 }
350 return 6;
351 } else {
352 ASSERT(STRING_STARTS_WITH(format, "imm26"));
353 PrintImm26(instr);
354 return 5;
355 }
356 }
357 case 'r': { // 'r: registers
358 return FormatRegister(instr, format);
359 }
360 case 'f': { // 'f: Cregisters
361 return FormatCRegister(instr, format);
362 }
363 case 's': { // 'sa
364 ASSERT(STRING_STARTS_WITH(format, "sa"));
365 PrintSa(instr);
366 return 2;
367 }
368 };
369 UNREACHABLE();
370 return -1;
371 }
372
373
374 // Format takes a formatting string for a whole instruction and prints it into
375 // the output buffer. All escaped options are handed to FormatOption to be
376 // parsed further.
377 void Decoder::Format(Instruction* instr, const char* format) {
378 char cur = *format++;
379 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
380 if (cur == '\'') { // Single quote is used as the formatting escape.
381 format += FormatOption(instr, format);
382 } else {
383 out_buffer_[out_buffer_pos_++] = cur;
384 }
385 cur = *format++;
386 }
387 out_buffer_[out_buffer_pos_] = '\0';
388 }
389
390
391 // For currently unimplemented decodings the disassembler calls Unknown(instr)
392 // which will just print "unknown" of the instruction bits.
393 void Decoder::Unknown(Instruction* instr) {
394 Format(instr, "unknown");
395 }
396
397
398 void Decoder::DecodeTypeRegister(Instruction* instr) {
399 switch (instr->OpcodeFieldRaw()) {
400 case COP1: // Coprocessor instructions
401 switch (instr->RsFieldRaw()) {
402 case BC1: // branch on coprocessor condition
403 UNREACHABLE();
404 break;
405 case MFC1:
406 Format(instr, "mfc1 'rt, 'fs");
407 break;
408 case MFHC1:
409 Format(instr, "mfhc1 rt, 'fs");
410 break;
411 case MTC1:
412 Format(instr, "mtc1 'rt, 'fs");
413 break;
414 case MTHC1:
415 Format(instr, "mthc1 rt, 'fs");
416 break;
417 case S:
418 case D:
419 UNIMPLEMENTED_MIPS();
420 break;
421 case W:
422 switch (instr->FunctionFieldRaw()) {
423 case CVT_S_W:
424 UNIMPLEMENTED_MIPS();
425 break;
426 case CVT_D_W: // Convert word to double.
427 Format(instr, "cvt.d.w 'fd, 'fs");
428 break;
429 default:
430 UNREACHABLE();
431 };
432 break;
433 case L:
434 case PS:
435 UNIMPLEMENTED_MIPS();
436 break;
437 break;
438 default:
439 UNREACHABLE();
440 };
441 break;
442 case SPECIAL:
443 switch (instr->FunctionFieldRaw()) {
444 case JR:
445 Format(instr, "jr 'rs");
446 break;
447 case JALR:
448 Format(instr, "jalr 'rs");
449 break;
450 case SLL:
451 if ( 0x0 == static_cast<int>(instr->InstructionBits()))
452 Format(instr, "nop");
453 else
454 Format(instr, "sll 'rd, 'rt, 'sa");
455 break;
456 case SRL:
457 Format(instr, "srl 'rd, 'rt, 'sa");
458 break;
459 case SRA:
460 Format(instr, "sra 'rd, 'rt, 'sa");
461 break;
462 case SLLV:
463 Format(instr, "sllv 'rd, 'rt, 'rs");
464 break;
465 case SRLV:
466 Format(instr, "srlv 'rd, 'rt, 'rs");
467 break;
468 case SRAV:
469 Format(instr, "srav 'rd, 'rt, 'rs");
470 break;
471 case MFHI:
472 Format(instr, "mfhi 'rd");
473 break;
474 case MFLO:
475 Format(instr, "mflo 'rd");
476 break;
477 case MULT:
478 Format(instr, "mult 'rs, 'rt");
479 break;
480 case MULTU:
481 Format(instr, "multu 'rs, 'rt");
482 break;
483 case DIV:
484 Format(instr, "div 'rs, 'rt");
485 break;
486 case DIVU:
487 Format(instr, "divu 'rs, 'rt");
488 break;
489 case ADD:
490 Format(instr, "add 'rd, 'rs, 'rt");
491 break;
492 case ADDU:
493 Format(instr, "addu 'rd, 'rs, 'rt");
494 break;
495 case SUB:
496 Format(instr, "sub 'rd, 'rs, 'rt");
497 break;
498 case SUBU:
499 Format(instr, "sub 'rd, 'rs, 'rt");
500 break;
501 case AND:
502 Format(instr, "and 'rd, 'rs, 'rt");
503 break;
504 case OR:
505 if (0 == instr->RsField()) {
506 Format(instr, "mov 'rd, 'rt");
507 } else if (0 == instr->RtField()) {
508 Format(instr, "mov 'rd, 'rs");
509 } else {
510 Format(instr, "or 'rd, 'rs, 'rt");
511 }
512 break;
513 case XOR:
514 Format(instr, "xor 'rd, 'rs, 'rt");
515 break;
516 case NOR:
517 Format(instr, "nor 'rd, 'rs, 'rt");
518 break;
519 case SLT:
520 Format(instr, "slt 'rd, 'rs, 'rt");
521 break;
522 case SLTU:
523 Format(instr, "sltu 'rd, 'rs, 'rt");
524 break;
525 case BREAK:
526 Format(instr, "break, code: 'code");
527 break;
528 case TGE:
529 Format(instr, "tge 'rs, 'rt, code: 'code");
530 break;
531 case TGEU:
532 Format(instr, "tgeu 'rs, 'rt, code: 'code");
533 break;
534 case TLT:
535 Format(instr, "tlt 'rs, 'rt, code: 'code");
536 break;
537 case TLTU:
538 Format(instr, "tltu 'rs, 'rt, code: 'code");
539 break;
540 case TEQ:
541 Format(instr, "teq 'rs, 'rt, code: 'code");
542 break;
543 case TNE:
544 Format(instr, "tne 'rs, 'rt, code: 'code");
545 break;
546 default:
547 UNREACHABLE();
548 };
549 break;
550 case SPECIAL2:
551 switch (instr->FunctionFieldRaw()) {
552 case MUL:
553 break;
554 default:
555 UNREACHABLE();
556 };
557 break;
558 default:
559 UNREACHABLE();
560 };
561 }
562
563
564 void Decoder::DecodeTypeImmediate(Instruction* instr) {
565 switch (instr->OpcodeFieldRaw()) {
566 // ------------- REGIMM class.
567 case REGIMM:
568 switch (instr->RtFieldRaw()) {
569 case BLTZ:
570 Format(instr, "bltz 'rs, 'imm16u");
571 break;
572 case BLTZAL:
573 Format(instr, "bltzal 'rs, 'imm16u");
574 break;
575 case BGEZ:
576 Format(instr, "bgez 'rs, 'imm16u");
577 break;
578 case BGEZAL:
579 Format(instr, "bgezal 'rs, 'imm16u");
580 break;
581 default:
582 UNREACHABLE();
583 };
584 break; // case REGIMM
585 // ------------- Branch instructions.
586 case BEQ:
587 Format(instr, "beq 'rs, 'rt, 'imm16u");
588 break;
589 case BNE:
590 Format(instr, "bne 'rs, 'rt, 'imm16u");
591 break;
592 case BLEZ:
593 Format(instr, "blez 'rs, 'imm16u");
594 break;
595 case BGTZ:
596 Format(instr, "bgtz 'rs, 'imm16u");
597 break;
598 // ------------- Arithmetic instructions.
599 case ADDI:
600 Format(instr, "addi 'rt, 'rs, 'imm16s");
601 break;
602 case ADDIU:
603 Format(instr, "addiu 'rt, 'rs, 'imm16s");
604 break;
605 case SLTI:
606 Format(instr, "slti 'rt, 'rs, 'imm16s");
607 break;
608 case SLTIU:
609 Format(instr, "sltiu 'rt, 'rs, 'imm16u");
610 break;
611 case ANDI:
612 Format(instr, "andi 'rt, 'rs, 'imm16x");
613 break;
614 case ORI:
615 Format(instr, "ori 'rt, 'rs, 'imm16x");
616 break;
617 case XORI:
618 Format(instr, "xori 'rt, 'rs, 'imm16x");
619 break;
620 case LUI:
621 Format(instr, "lui 'rt, 'imm16x");
622 break;
623 // ------------- Memory instructions.
624 case LB:
625 Format(instr, "lb 'rt, 'imm16s('rs)");
626 break;
627 case LW:
628 Format(instr, "lw 'rt, 'imm16s('rs)");
629 break;
630 case LBU:
631 Format(instr, "lbu 'rt, 'imm16s('rs)");
632 break;
633 case SB:
634 Format(instr, "sb 'rt, 'imm16s('rs)");
635 break;
636 case SW:
637 Format(instr, "sw 'rt, 'imm16s('rs)");
638 break;
639 case LWC1:
640 Format(instr, "lwc1 'ft, 'imm16s('rs)");
641 break;
642 case LDC1:
643 Format(instr, "ldc1 'ft, 'imm16s('rs)");
644 break;
645 case SWC1:
646 Format(instr, "swc1 'rt, 'imm16s('fs)");
647 break;
648 case SDC1:
649 Format(instr, "sdc1 'rt, 'imm16s('fs)");
650 break;
651 default:
652 UNREACHABLE();
653 break;
654 };
655 }
656
657
658 void Decoder::DecodeTypeJump(Instruction* instr) {
659 switch (instr->OpcodeFieldRaw()) {
660 case J:
661 Format(instr, "j 'imm26");
662 break;
663 case JAL:
664 Format(instr, "jal 'imm26");
665 break;
666 default:
667 UNREACHABLE();
668 }
669 }
670
671
672 // Disassemble the instruction at *instr_ptr into the output buffer.
673 int Decoder::InstructionDecode(byte_* instr_ptr) {
674 Instruction* instr = Instruction::At(instr_ptr);
675 // Print raw instruction bytes.
676 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
677 "%08x ",
678 instr->InstructionBits());
679 switch (instr->InstructionType()) {
680 case Instruction::kRegisterType: {
681 DecodeTypeRegister(instr);
682 break;
683 }
684 case Instruction::kImmediateType: {
685 DecodeTypeImmediate(instr);
686 break;
687 }
688 case Instruction::kJumpType: {
689 DecodeTypeJump(instr);
690 break;
691 }
692 default: {
693 UNSUPPORTED_MIPS();
694 }
695 }
696 return Instruction::kInstructionSize;
697 }
698
699
700 } } // namespace assembler::mips
701
702
703
704 //------------------------------------------------------------------------------
705
706 namespace disasm {
707
708 namespace v8i = v8::internal;
709
710
711 const char* NameConverter::NameOfAddress(byte_* addr) const {
712 static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
713 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
714 return tmp_buffer.start();
715 }
716
717
718 const char* NameConverter::NameOfConstant(byte_* addr) const {
719 return NameOfAddress(addr);
720 }
721
722
723 const char* NameConverter::NameOfCPURegister(int reg) const {
724 return assembler::mips::Registers::Name(reg);
725 }
726
727
728 const char* NameConverter::NameOfXMMRegister(int reg) const {
729 return assembler::mips::FPURegister::Name(reg);
730 }
731
732
733 const char* NameConverter::NameOfByteCPURegister(int reg) const {
734 UNREACHABLE(); // MIPS does not have the concept of a byte register
735 return "nobytereg";
736 }
737
738
739 const char* NameConverter::NameInCode(byte_* addr) const {
740 // The default name converter is called for unknown code. So we will not try
741 // to access any memory.
742 return "";
743 }
744
745
746 //------------------------------------------------------------------------------
747
748 Disassembler::Disassembler(const NameConverter& converter)
749 : converter_(converter) {}
750
751
752 Disassembler::~Disassembler() {}
753
754
755 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
756 byte_* instruction) {
757 assembler::mips::Decoder d(converter_, buffer);
758 return d.InstructionDecode(instruction);
759 }
760
761
762 int Disassembler::ConstantPoolSizeAt(byte_* instruction) {
763 UNIMPLEMENTED_MIPS();
764 return -1;
765 }
766
767
768 void Disassembler::Disassemble(FILE* f, byte_* begin, byte_* end) {
769 NameConverter converter;
770 Disassembler d(converter);
771 for (byte_* pc = begin; pc < end;) {
772 v8::internal::EmbeddedVector<char, 128> buffer;
773 buffer[0] = '\0';
774 byte_* prev_pc = pc;
775 pc += d.InstructionDecode(buffer, pc);
776 fprintf(f, "%p %08x %s\n",
777 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
778 }
779 }
780
781 #undef UNSUPPORTED
782
783 } // namespace disasm
784
OLDNEW
« no previous file with comments | « src/mips/debug-mips.cc ('k') | src/mips/fast-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698