59 #if defined(V8_TARGET_ARCH_MIPS)
78 : converter_(converter),
79 out_buffer_(out_buffer),
81 out_buffer_[out_buffer_pos_] =
'\0';
88 int InstructionDecode(
byte* instruction);
92 void PrintChar(
const char ch);
93 void Print(
const char* str);
96 void PrintRegister(
int reg);
97 void PrintFPURegister(
int freg);
98 void PrintRs(Instruction* instr);
99 void PrintRt(Instruction* instr);
100 void PrintRd(Instruction* instr);
101 void PrintFs(Instruction* instr);
102 void PrintFt(Instruction* instr);
103 void PrintFd(Instruction* instr);
104 void PrintSa(Instruction* instr);
105 void PrintSd(Instruction* instr);
106 void PrintSs1(Instruction* instr);
107 void PrintSs2(Instruction* instr);
108 void PrintBc(Instruction* instr);
109 void PrintCc(Instruction* instr);
110 void PrintFunction(Instruction* instr);
111 void PrintSecondaryField(Instruction* instr);
112 void PrintUImm16(Instruction* instr);
113 void PrintSImm16(Instruction* instr);
114 void PrintXImm16(Instruction* instr);
115 void PrintXImm26(Instruction* instr);
116 void PrintCode(Instruction* instr);
118 void PrintInstructionName(Instruction* instr);
121 int FormatRegister(Instruction* instr,
const char* option);
122 int FormatFPURegister(Instruction* instr,
const char* option);
123 int FormatOption(Instruction* instr,
const char* option);
124 void Format(Instruction* instr,
const char* format);
125 void Unknown(Instruction* instr);
128 void DecodeTypeRegister(Instruction* instr);
129 void DecodeTypeImmediate(Instruction* instr);
130 void DecodeTypeJump(Instruction* instr);
141 #define STRING_STARTS_WITH(string, compare_string) \
142 (strncmp(string, compare_string, strlen(compare_string)) == 0)
146 void Decoder::PrintChar(
const char ch) {
147 out_buffer_[out_buffer_pos_++] = ch;
154 while (cur !=
'\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
158 out_buffer_[out_buffer_pos_] = 0;
163 void Decoder::PrintRegister(
int reg) {
164 Print(converter_.NameOfCPURegister(reg));
168 void Decoder::PrintRs(Instruction* instr) {
169 int reg = instr->RsValue();
174 void Decoder::PrintRt(Instruction* instr) {
175 int reg = instr->RtValue();
180 void Decoder::PrintRd(Instruction* instr) {
181 int reg = instr->RdValue();
187 void Decoder::PrintFPURegister(
int freg) {
188 Print(converter_.NameOfXMMRegister(freg));
192 void Decoder::PrintFs(Instruction* instr) {
193 int freg = instr->RsValue();
194 PrintFPURegister(freg);
198 void Decoder::PrintFt(Instruction* instr) {
199 int freg = instr->RtValue();
200 PrintFPURegister(freg);
204 void Decoder::PrintFd(Instruction* instr) {
205 int freg = instr->RdValue();
206 PrintFPURegister(freg);
211 void Decoder::PrintSa(Instruction* instr) {
212 int sa = instr->SaValue();
213 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", sa);
218 void Decoder::PrintSd(Instruction* instr) {
219 int sd = instr->RdValue();
220 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", sd);
225 void Decoder::PrintSs1(Instruction* instr) {
226 int ss = instr->RdValue();
227 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", ss + 1);
232 void Decoder::PrintSs2(Instruction* instr) {
233 int ss = instr->RdValue();
234 int pos = instr->SaValue();
236 OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", ss - pos + 1);
241 void Decoder::PrintBc(Instruction* instr) {
242 int cc = instr->FBccValue();
243 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", cc);
248 void Decoder::PrintCc(Instruction* instr) {
249 int cc = instr->FCccValue();
250 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"cc(%d)", cc);
255 void Decoder::PrintUImm16(Instruction* instr) {
256 int32_t imm = instr->Imm16Value();
257 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%u", imm);
262 void Decoder::PrintSImm16(Instruction* instr) {
263 int32_t imm = ((instr->Imm16Value()) << 16) >> 16;
264 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", imm);
269 void Decoder::PrintXImm16(Instruction* instr) {
270 int32_t imm = instr->Imm16Value();
271 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%x", imm);
276 void Decoder::PrintXImm26(Instruction* instr) {
278 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%x", imm);
283 void Decoder::PrintCode(Instruction* instr) {
284 if (instr->OpcodeFieldRaw() !=
SPECIAL)
286 switch (instr->FunctionFieldRaw()) {
289 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
290 "0x%05x (%d)", code, code);
299 int32_t code = instr->Bits(15, 6);
301 OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%03x", code);
311 void Decoder::PrintInstructionName(Instruction* instr) {
317 int Decoder::FormatRegister(Instruction* instr,
const char* format) {
319 if (format[1] ==
's') {
320 int reg = instr->RsValue();
323 }
else if (format[1] ==
't') {
324 int reg = instr->RtValue();
327 }
else if (format[1] ==
'd') {
328 int reg = instr->RdValue();
339 int Decoder::FormatFPURegister(Instruction* instr,
const char* format) {
341 if (format[1] ==
's') {
342 int reg = instr->FsValue();
343 PrintFPURegister(reg);
345 }
else if (format[1] ==
't') {
346 int reg = instr->FtValue();
347 PrintFPURegister(reg);
349 }
else if (format[1] ==
'd') {
350 int reg = instr->FdValue();
351 PrintFPURegister(reg);
364 int Decoder::FormatOption(Instruction* instr,
const char* format) {
367 ASSERT(STRING_STARTS_WITH(format,
"code"));
372 if (format[3] ==
'1') {
373 ASSERT(STRING_STARTS_WITH(format,
"imm16"));
374 if (format[5] ==
's') {
375 ASSERT(STRING_STARTS_WITH(format,
"imm16s"));
377 }
else if (format[5] ==
'u') {
378 ASSERT(STRING_STARTS_WITH(format,
"imm16u"));
381 ASSERT(STRING_STARTS_WITH(format,
"imm16x"));
386 ASSERT(STRING_STARTS_WITH(format,
"imm26x"));
392 return FormatRegister(instr, format);
395 return FormatFPURegister(instr, format);
400 ASSERT(STRING_STARTS_WITH(format,
"sa"));
405 ASSERT(STRING_STARTS_WITH(format,
"sd"));
410 if (format[2] ==
'1') {
411 ASSERT(STRING_STARTS_WITH(format,
"ss1"));
415 ASSERT(STRING_STARTS_WITH(format,
"ss2"));
423 ASSERT(STRING_STARTS_WITH(format,
"bc"));
428 ASSERT(STRING_STARTS_WITH(format,
"Cc"));
441 void Decoder::Format(Instruction* instr,
const char* format) {
442 char cur = *format++;
443 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
445 format += FormatOption(instr, format);
447 out_buffer_[out_buffer_pos_++] = cur;
451 out_buffer_[out_buffer_pos_] =
'\0';
457 void Decoder::Unknown(Instruction* instr) {
458 Format(instr,
"unknown");
462 void Decoder::DecodeTypeRegister(Instruction* instr) {
463 switch (instr->OpcodeFieldRaw()) {
465 switch (instr->RsFieldRaw()) {
470 Format(instr,
"mfc1 'rt, 'fs");
473 Format(instr,
"mfhc1 'rt, 'fs");
476 Format(instr,
"mtc1 'rt, 'fs");
480 Format(instr,
"ctc1 'rt, 'fs");
483 Format(instr,
"cfc1 'rt, 'fs");
486 Format(instr,
"mthc1 'rt, 'fs");
489 switch (instr->FunctionFieldRaw()) {
491 Format(instr,
"add.d 'fd, 'fs, 'ft");
494 Format(instr,
"sub.d 'fd, 'fs, 'ft");
497 Format(instr,
"mul.d 'fd, 'fs, 'ft");
500 Format(instr,
"div.d 'fd, 'fs, 'ft");
503 Format(instr,
"abs.d 'fd, 'fs");
506 Format(instr,
"mov.d 'fd, 'fs");
509 Format(instr,
"neg.d 'fd, 'fs");
512 Format(instr,
"sqrt.d 'fd, 'fs");
515 Format(instr,
"cvt.w.d 'fd, 'fs");
519 Format(instr,
"cvt.l.d 'fd, 'fs");
526 Format(instr,
"trunc.w.d 'fd, 'fs");
530 Format(instr,
"trunc.l.d 'fd, 'fs");
537 Format(instr,
"round.w.d 'fd, 'fs");
540 Format(instr,
"floor.w.d 'fd, 'fs");
543 Format(instr,
"ceil.w.d 'fd, 'fs");
546 Format(instr,
"cvt.s.d 'fd, 'fs");
549 Format(instr,
"c.f.d 'fs, 'ft, 'Cc");
552 Format(instr,
"c.un.d 'fs, 'ft, 'Cc");
555 Format(instr,
"c.eq.d 'fs, 'ft, 'Cc");
558 Format(instr,
"c.ueq.d 'fs, 'ft, 'Cc");
561 Format(instr,
"c.olt.d 'fs, 'ft, 'Cc");
564 Format(instr,
"c.ult.d 'fs, 'ft, 'Cc");
567 Format(instr,
"c.ole.d 'fs, 'ft, 'Cc");
570 Format(instr,
"c.ule.d 'fs, 'ft, 'Cc");
573 Format(instr,
"unknown.cop1.d");
581 switch (instr->FunctionFieldRaw()) {
583 Format(instr,
"cvt.s.w 'fd, 'fs");
586 Format(instr,
"cvt.d.w 'fd, 'fs");
593 switch (instr->FunctionFieldRaw()) {
596 Format(instr,
"cvt.d.l 'fd, 'fs");
604 Format(instr,
"cvt.s.l 'fd, 'fs");
622 switch (instr->FunctionFieldRaw()) {
624 Format(instr,
"jr 'rs");
627 Format(instr,
"jalr 'rs");
630 if ( 0x0 == static_cast<int>(instr->InstructionBits()))
631 Format(instr,
"nop");
633 Format(instr,
"sll 'rd, 'rt, 'sa");
636 if (instr->RsValue() == 0) {
637 Format(instr,
"srl 'rd, 'rt, 'sa");
640 Format(instr,
"rotr 'rd, 'rt, 'sa");
647 Format(instr,
"sra 'rd, 'rt, 'sa");
650 Format(instr,
"sllv 'rd, 'rt, 'rs");
653 if (instr->SaValue() == 0) {
654 Format(instr,
"srlv 'rd, 'rt, 'rs");
657 Format(instr,
"rotrv 'rd, 'rt, 'rs");
664 Format(instr,
"srav 'rd, 'rt, 'rs");
667 Format(instr,
"mfhi 'rd");
670 Format(instr,
"mflo 'rd");
673 Format(instr,
"mult 'rs, 'rt");
676 Format(instr,
"multu 'rs, 'rt");
679 Format(instr,
"div 'rs, 'rt");
682 Format(instr,
"divu 'rs, 'rt");
685 Format(instr,
"add 'rd, 'rs, 'rt");
688 Format(instr,
"addu 'rd, 'rs, 'rt");
691 Format(instr,
"sub 'rd, 'rs, 'rt");
694 Format(instr,
"subu 'rd, 'rs, 'rt");
697 Format(instr,
"and 'rd, 'rs, 'rt");
700 if (0 == instr->RsValue()) {
701 Format(instr,
"mov 'rd, 'rt");
702 }
else if (0 == instr->RtValue()) {
703 Format(instr,
"mov 'rd, 'rs");
705 Format(instr,
"or 'rd, 'rs, 'rt");
709 Format(instr,
"xor 'rd, 'rs, 'rt");
712 Format(instr,
"nor 'rd, 'rs, 'rt");
715 Format(instr,
"slt 'rd, 'rs, 'rt");
718 Format(instr,
"sltu 'rd, 'rs, 'rt");
721 Format(instr,
"break, code: 'code");
724 Format(instr,
"tge 'rs, 'rt, code: 'code");
727 Format(instr,
"tgeu 'rs, 'rt, code: 'code");
730 Format(instr,
"tlt 'rs, 'rt, code: 'code");
733 Format(instr,
"tltu 'rs, 'rt, code: 'code");
736 Format(instr,
"teq 'rs, 'rt, code: 'code");
739 Format(instr,
"tne 'rs, 'rt, code: 'code");
742 Format(instr,
"movz 'rd, 'rs, 'rt");
745 Format(instr,
"movn 'rd, 'rs, 'rt");
748 if (instr->Bit(16)) {
749 Format(instr,
"movt 'rd, 'rs, 'bc");
751 Format(instr,
"movf 'rd, 'rs, 'bc");
759 switch (instr->FunctionFieldRaw()) {
761 Format(instr,
"mul 'rd, 'rs, 'rt");
764 Format(instr,
"clz 'rd, 'rs");
771 switch (instr->FunctionFieldRaw()) {
774 Format(instr,
"ins 'rt, 'rs, 'sa, 'ss2");
782 Format(instr,
"ext 'rt, 'rs, 'sa, 'ss1");
798 void Decoder::DecodeTypeImmediate(Instruction* instr) {
799 switch (instr->OpcodeFieldRaw()) {
802 switch (instr->RsFieldRaw()) {
804 if (instr->FBtrueValue()) {
805 Format(instr,
"bc1t 'bc, 'imm16u");
807 Format(instr,
"bc1f 'bc, 'imm16u");
815 switch (instr->RtFieldRaw()) {
817 Format(instr,
"bltz 'rs, 'imm16u");
820 Format(instr,
"bltzal 'rs, 'imm16u");
823 Format(instr,
"bgez 'rs, 'imm16u");
826 Format(instr,
"bgezal 'rs, 'imm16u");
834 Format(instr,
"beq 'rs, 'rt, 'imm16u");
837 Format(instr,
"bne 'rs, 'rt, 'imm16u");
840 Format(instr,
"blez 'rs, 'imm16u");
843 Format(instr,
"bgtz 'rs, 'imm16u");
847 Format(instr,
"addi 'rt, 'rs, 'imm16s");
850 Format(instr,
"addiu 'rt, 'rs, 'imm16s");
853 Format(instr,
"slti 'rt, 'rs, 'imm16s");
856 Format(instr,
"sltiu 'rt, 'rs, 'imm16u");
859 Format(instr,
"andi 'rt, 'rs, 'imm16x");
862 Format(instr,
"ori 'rt, 'rs, 'imm16x");
865 Format(instr,
"xori 'rt, 'rs, 'imm16x");
868 Format(instr,
"lui 'rt, 'imm16x");
872 Format(instr,
"lb 'rt, 'imm16s('rs)");
875 Format(instr,
"lh 'rt, 'imm16s('rs)");
878 Format(instr,
"lwl 'rt, 'imm16s('rs)");
881 Format(instr,
"lw 'rt, 'imm16s('rs)");
884 Format(instr,
"lbu 'rt, 'imm16s('rs)");
887 Format(instr,
"lhu 'rt, 'imm16s('rs)");
890 Format(instr,
"lwr 'rt, 'imm16s('rs)");
893 Format(instr,
"sb 'rt, 'imm16s('rs)");
896 Format(instr,
"sh 'rt, 'imm16s('rs)");
899 Format(instr,
"swl 'rt, 'imm16s('rs)");
902 Format(instr,
"sw 'rt, 'imm16s('rs)");
905 Format(instr,
"swr 'rt, 'imm16s('rs)");
908 Format(instr,
"lwc1 'ft, 'imm16s('rs)");
911 Format(instr,
"ldc1 'ft, 'imm16s('rs)");
914 Format(instr,
"swc1 'ft, 'imm16s('rs)");
917 Format(instr,
"sdc1 'ft, 'imm16s('rs)");
926 void Decoder::DecodeTypeJump(Instruction* instr) {
927 switch (instr->OpcodeFieldRaw()) {
929 Format(instr,
"j 'imm26x");
932 Format(instr,
"jal 'imm26x");
941 int Decoder::InstructionDecode(
byte* instr_ptr) {
944 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
946 instr->InstructionBits());
947 switch (instr->InstructionType()) {
949 DecodeTypeRegister(instr);
953 DecodeTypeImmediate(instr);
957 DecodeTypeJump(instr);
961 Format(instr,
"UNSUPPORTED");
1014 : converter_(converter) {}
1017 Disassembler::~Disassembler() {}
1021 byte* instruction) {
1022 v8::internal::Decoder d(converter_, buffer);
1023 return d.InstructionDecode(instruction);
1028 int Disassembler::ConstantPoolSizeAt(
byte* instruction) {
1033 void Disassembler::Disassemble(FILE* f,
byte* begin,
byte* end) {
1034 NameConverter converter;
1035 Disassembler d(converter);
1036 for (
byte*
pc = begin;
pc < end;) {
1040 pc += d.InstructionDecode(buffer,
pc);
1041 fprintf(f,
"%p %08x %s\n",
1042 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.
start());
1051 #endif // V8_TARGET_ARCH_MIPS
Disassembler(const NameConverter &converter)
virtual const char * NameOfXMMRegister(int reg) const
v8::internal::EmbeddedVector< char, 128 > tmp_buffer_
virtual const char * NameOfConstant(byte *addr) const
#define ASSERT(condition)
v8::Handle< v8::Value > Print(const v8::Arguments &args)
virtual const char * NameInCode(byte *addr) const
static const char * Name(int reg)
virtual const char * NameOfByteCPURegister(int reg) const
static Instruction * At(byte *pc)
virtual const char * NameOfCPURegister(int reg) const
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
virtual const char * NameOfAddress(byte *addr) const
#define UNIMPLEMENTED_MIPS()
static const char * Name(int reg)
static int SNPrintF(Vector< char > str, const char *format,...)
#define UNSUPPORTED_MIPS()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments