56 #if V8_TARGET_ARCH_MIPS
75 : converter_(converter),
76 out_buffer_(out_buffer),
78 out_buffer_[out_buffer_pos_] =
'\0';
85 int InstructionDecode(
byte* instruction);
89 void PrintChar(
const char ch);
90 void Print(
const char* str);
93 void PrintRegister(
int reg);
94 void PrintFPURegister(
int freg);
95 void PrintRs(Instruction* instr);
96 void PrintRt(Instruction* instr);
97 void PrintRd(Instruction* instr);
98 void PrintFs(Instruction* instr);
99 void PrintFt(Instruction* instr);
100 void PrintFd(Instruction* instr);
101 void PrintSa(Instruction* instr);
102 void PrintSd(Instruction* instr);
103 void PrintSs1(Instruction* instr);
104 void PrintSs2(Instruction* instr);
105 void PrintBc(Instruction* instr);
106 void PrintCc(Instruction* instr);
107 void PrintFunction(Instruction* instr);
108 void PrintSecondaryField(Instruction* instr);
109 void PrintUImm16(Instruction* instr);
110 void PrintSImm16(Instruction* instr);
111 void PrintXImm16(Instruction* instr);
112 void PrintXImm26(Instruction* instr);
113 void PrintCode(Instruction* instr);
115 void PrintInstructionName(Instruction* instr);
118 int FormatRegister(Instruction* instr,
const char* option);
119 int FormatFPURegister(Instruction* instr,
const char* option);
120 int FormatOption(Instruction* instr,
const char* option);
121 void Format(Instruction* instr,
const char* format);
122 void Unknown(Instruction* instr);
125 void DecodeTypeRegister(Instruction* instr);
126 void DecodeTypeImmediate(Instruction* instr);
127 void DecodeTypeJump(Instruction* instr);
138 #define STRING_STARTS_WITH(string, compare_string) \
139 (strncmp(string, compare_string, strlen(compare_string)) == 0)
143 void Decoder::PrintChar(
const char ch) {
144 out_buffer_[out_buffer_pos_++] = ch;
151 while (cur !=
'\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
155 out_buffer_[out_buffer_pos_] = 0;
160 void Decoder::PrintRegister(
int reg) {
161 Print(converter_.NameOfCPURegister(reg));
165 void Decoder::PrintRs(Instruction* instr) {
166 int reg = instr->RsValue();
171 void Decoder::PrintRt(Instruction* instr) {
172 int reg = instr->RtValue();
177 void Decoder::PrintRd(Instruction* instr) {
178 int reg = instr->RdValue();
184 void Decoder::PrintFPURegister(
int freg) {
185 Print(converter_.NameOfXMMRegister(freg));
189 void Decoder::PrintFs(Instruction* instr) {
190 int freg = instr->RsValue();
191 PrintFPURegister(freg);
195 void Decoder::PrintFt(Instruction* instr) {
196 int freg = instr->RtValue();
197 PrintFPURegister(freg);
201 void Decoder::PrintFd(Instruction* instr) {
202 int freg = instr->RdValue();
203 PrintFPURegister(freg);
208 void Decoder::PrintSa(Instruction* instr) {
209 int sa = instr->SaValue();
210 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", sa);
215 void Decoder::PrintSd(Instruction* instr) {
216 int sd = instr->RdValue();
217 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", sd);
222 void Decoder::PrintSs1(Instruction* instr) {
223 int ss = instr->RdValue();
224 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", ss + 1);
229 void Decoder::PrintSs2(Instruction* instr) {
230 int ss = instr->RdValue();
231 int pos = instr->SaValue();
233 OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", ss - pos + 1);
238 void Decoder::PrintBc(Instruction* instr) {
239 int cc = instr->FBccValue();
240 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", cc);
245 void Decoder::PrintCc(Instruction* instr) {
246 int cc = instr->FCccValue();
247 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"cc(%d)", cc);
252 void Decoder::PrintUImm16(Instruction* instr) {
253 int32_t imm = instr->Imm16Value();
254 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%u", imm);
259 void Decoder::PrintSImm16(Instruction* instr) {
260 int32_t imm = ((instr->Imm16Value()) << 16) >> 16;
261 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"%d", imm);
266 void Decoder::PrintXImm16(Instruction* instr) {
267 int32_t imm = instr->Imm16Value();
268 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%x", imm);
273 void Decoder::PrintXImm26(Instruction* instr) {
275 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%x", imm);
280 void Decoder::PrintCode(Instruction* instr) {
281 if (instr->OpcodeFieldRaw() !=
SPECIAL)
283 switch (instr->FunctionFieldRaw()) {
286 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
287 "0x%05x (%d)", code, code);
296 int32_t code = instr->Bits(15, 6);
298 OS::SNPrintF(out_buffer_ + out_buffer_pos_,
"0x%03x", code);
308 void Decoder::PrintInstructionName(Instruction* instr) {
314 int Decoder::FormatRegister(Instruction* instr,
const char* format) {
316 if (format[1] ==
's') {
317 int reg = instr->RsValue();
320 }
else if (format[1] ==
't') {
321 int reg = instr->RtValue();
324 }
else if (format[1] ==
'd') {
325 int reg = instr->RdValue();
336 int Decoder::FormatFPURegister(Instruction* instr,
const char* format) {
338 if (format[1] ==
's') {
339 int reg = instr->FsValue();
340 PrintFPURegister(reg);
342 }
else if (format[1] ==
't') {
343 int reg = instr->FtValue();
344 PrintFPURegister(reg);
346 }
else if (format[1] ==
'd') {
347 int reg = instr->FdValue();
348 PrintFPURegister(reg);
350 }
else if (format[1] ==
'r') {
351 int reg = instr->FrValue();
352 PrintFPURegister(reg);
365 int Decoder::FormatOption(Instruction* instr,
const char* format) {
368 ASSERT(STRING_STARTS_WITH(format,
"code"));
373 if (format[3] ==
'1') {
374 ASSERT(STRING_STARTS_WITH(format,
"imm16"));
375 if (format[5] ==
's') {
376 ASSERT(STRING_STARTS_WITH(format,
"imm16s"));
378 }
else if (format[5] ==
'u') {
379 ASSERT(STRING_STARTS_WITH(format,
"imm16u"));
382 ASSERT(STRING_STARTS_WITH(format,
"imm16x"));
387 ASSERT(STRING_STARTS_WITH(format,
"imm26x"));
393 return FormatRegister(instr, format);
396 return FormatFPURegister(instr, format);
401 ASSERT(STRING_STARTS_WITH(format,
"sa"));
406 ASSERT(STRING_STARTS_WITH(format,
"sd"));
411 if (format[2] ==
'1') {
412 ASSERT(STRING_STARTS_WITH(format,
"ss1"));
416 ASSERT(STRING_STARTS_WITH(format,
"ss2"));
424 ASSERT(STRING_STARTS_WITH(format,
"bc"));
429 ASSERT(STRING_STARTS_WITH(format,
"Cc"));
442 void Decoder::Format(Instruction* instr,
const char* format) {
443 char cur = *format++;
444 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
446 format += FormatOption(instr, format);
448 out_buffer_[out_buffer_pos_++] = cur;
452 out_buffer_[out_buffer_pos_] =
'\0';
458 void Decoder::Unknown(Instruction* instr) {
459 Format(instr,
"unknown");
463 void Decoder::DecodeTypeRegister(Instruction* instr) {
464 switch (instr->OpcodeFieldRaw()) {
466 switch (instr->RsFieldRaw()) {
471 Format(instr,
"mfc1 'rt, 'fs");
474 Format(instr,
"mfhc1 'rt, 'fs");
477 Format(instr,
"mtc1 'rt, 'fs");
481 Format(instr,
"ctc1 'rt, 'fs");
484 Format(instr,
"cfc1 'rt, 'fs");
487 Format(instr,
"mthc1 'rt, 'fs");
490 switch (instr->FunctionFieldRaw()) {
492 Format(instr,
"add.d 'fd, 'fs, 'ft");
495 Format(instr,
"sub.d 'fd, 'fs, 'ft");
498 Format(instr,
"mul.d 'fd, 'fs, 'ft");
501 Format(instr,
"div.d 'fd, 'fs, 'ft");
504 Format(instr,
"abs.d 'fd, 'fs");
507 Format(instr,
"mov.d 'fd, 'fs");
510 Format(instr,
"neg.d 'fd, 'fs");
513 Format(instr,
"sqrt.d 'fd, 'fs");
516 Format(instr,
"cvt.w.d 'fd, 'fs");
520 Format(instr,
"cvt.l.d 'fd, 'fs");
527 Format(instr,
"trunc.w.d 'fd, 'fs");
531 Format(instr,
"trunc.l.d 'fd, 'fs");
538 Format(instr,
"round.w.d 'fd, 'fs");
541 Format(instr,
"floor.w.d 'fd, 'fs");
544 Format(instr,
"ceil.w.d 'fd, 'fs");
547 Format(instr,
"cvt.s.d 'fd, 'fs");
550 Format(instr,
"c.f.d 'fs, 'ft, 'Cc");
553 Format(instr,
"c.un.d 'fs, 'ft, 'Cc");
556 Format(instr,
"c.eq.d 'fs, 'ft, 'Cc");
559 Format(instr,
"c.ueq.d 'fs, 'ft, 'Cc");
562 Format(instr,
"c.olt.d 'fs, 'ft, 'Cc");
565 Format(instr,
"c.ult.d 'fs, 'ft, 'Cc");
568 Format(instr,
"c.ole.d 'fs, 'ft, 'Cc");
571 Format(instr,
"c.ule.d 'fs, 'ft, 'Cc");
574 Format(instr,
"unknown.cop1.d");
582 switch (instr->FunctionFieldRaw()) {
584 Format(instr,
"cvt.s.w 'fd, 'fs");
587 Format(instr,
"cvt.d.w 'fd, 'fs");
594 switch (instr->FunctionFieldRaw()) {
597 Format(instr,
"cvt.d.l 'fd, 'fs");
605 Format(instr,
"cvt.s.l 'fd, 'fs");
623 switch (instr->FunctionFieldRaw()) {
625 Format(instr,
"madd.d 'fd, 'fr, 'fs, 'ft");
632 switch (instr->FunctionFieldRaw()) {
634 Format(instr,
"jr 'rs");
637 Format(instr,
"jalr 'rs");
640 if ( 0x0 == static_cast<int>(instr->InstructionBits()))
641 Format(instr,
"nop");
643 Format(instr,
"sll 'rd, 'rt, 'sa");
646 if (instr->RsValue() == 0) {
647 Format(instr,
"srl 'rd, 'rt, 'sa");
650 Format(instr,
"rotr 'rd, 'rt, 'sa");
657 Format(instr,
"sra 'rd, 'rt, 'sa");
660 Format(instr,
"sllv 'rd, 'rt, 'rs");
663 if (instr->SaValue() == 0) {
664 Format(instr,
"srlv 'rd, 'rt, 'rs");
667 Format(instr,
"rotrv 'rd, 'rt, 'rs");
674 Format(instr,
"srav 'rd, 'rt, 'rs");
677 Format(instr,
"mfhi 'rd");
680 Format(instr,
"mflo 'rd");
683 Format(instr,
"mult 'rs, 'rt");
686 Format(instr,
"multu 'rs, 'rt");
689 Format(instr,
"div 'rs, 'rt");
692 Format(instr,
"divu 'rs, 'rt");
695 Format(instr,
"add 'rd, 'rs, 'rt");
698 Format(instr,
"addu 'rd, 'rs, 'rt");
701 Format(instr,
"sub 'rd, 'rs, 'rt");
704 Format(instr,
"subu 'rd, 'rs, 'rt");
707 Format(instr,
"and 'rd, 'rs, 'rt");
710 if (0 == instr->RsValue()) {
711 Format(instr,
"mov 'rd, 'rt");
712 }
else if (0 == instr->RtValue()) {
713 Format(instr,
"mov 'rd, 'rs");
715 Format(instr,
"or 'rd, 'rs, 'rt");
719 Format(instr,
"xor 'rd, 'rs, 'rt");
722 Format(instr,
"nor 'rd, 'rs, 'rt");
725 Format(instr,
"slt 'rd, 'rs, 'rt");
728 Format(instr,
"sltu 'rd, 'rs, 'rt");
731 Format(instr,
"break, code: 'code");
734 Format(instr,
"tge 'rs, 'rt, code: 'code");
737 Format(instr,
"tgeu 'rs, 'rt, code: 'code");
740 Format(instr,
"tlt 'rs, 'rt, code: 'code");
743 Format(instr,
"tltu 'rs, 'rt, code: 'code");
746 Format(instr,
"teq 'rs, 'rt, code: 'code");
749 Format(instr,
"tne 'rs, 'rt, code: 'code");
752 Format(instr,
"movz 'rd, 'rs, 'rt");
755 Format(instr,
"movn 'rd, 'rs, 'rt");
758 if (instr->Bit(16)) {
759 Format(instr,
"movt 'rd, 'rs, 'bc");
761 Format(instr,
"movf 'rd, 'rs, 'bc");
769 switch (instr->FunctionFieldRaw()) {
771 Format(instr,
"mul 'rd, 'rs, 'rt");
774 Format(instr,
"clz 'rd, 'rs");
781 switch (instr->FunctionFieldRaw()) {
784 Format(instr,
"ins 'rt, 'rs, 'sa, 'ss2");
792 Format(instr,
"ext 'rt, 'rs, 'sa, 'ss1");
808 void Decoder::DecodeTypeImmediate(Instruction* instr) {
809 switch (instr->OpcodeFieldRaw()) {
812 switch (instr->RsFieldRaw()) {
814 if (instr->FBtrueValue()) {
815 Format(instr,
"bc1t 'bc, 'imm16u");
817 Format(instr,
"bc1f 'bc, 'imm16u");
825 switch (instr->RtFieldRaw()) {
827 Format(instr,
"bltz 'rs, 'imm16u");
830 Format(instr,
"bltzal 'rs, 'imm16u");
833 Format(instr,
"bgez 'rs, 'imm16u");
836 Format(instr,
"bgezal 'rs, 'imm16u");
844 Format(instr,
"beq 'rs, 'rt, 'imm16u");
847 Format(instr,
"bne 'rs, 'rt, 'imm16u");
850 Format(instr,
"blez 'rs, 'imm16u");
853 Format(instr,
"bgtz 'rs, 'imm16u");
857 Format(instr,
"addi 'rt, 'rs, 'imm16s");
860 Format(instr,
"addiu 'rt, 'rs, 'imm16s");
863 Format(instr,
"slti 'rt, 'rs, 'imm16s");
866 Format(instr,
"sltiu 'rt, 'rs, 'imm16u");
869 Format(instr,
"andi 'rt, 'rs, 'imm16x");
872 Format(instr,
"ori 'rt, 'rs, 'imm16x");
875 Format(instr,
"xori 'rt, 'rs, 'imm16x");
878 Format(instr,
"lui 'rt, 'imm16x");
882 Format(instr,
"lb 'rt, 'imm16s('rs)");
885 Format(instr,
"lh 'rt, 'imm16s('rs)");
888 Format(instr,
"lwl 'rt, 'imm16s('rs)");
891 Format(instr,
"lw 'rt, 'imm16s('rs)");
894 Format(instr,
"lbu 'rt, 'imm16s('rs)");
897 Format(instr,
"lhu 'rt, 'imm16s('rs)");
900 Format(instr,
"lwr 'rt, 'imm16s('rs)");
903 Format(instr,
"pref 'rt, 'imm16s('rs)");
906 Format(instr,
"sb 'rt, 'imm16s('rs)");
909 Format(instr,
"sh 'rt, 'imm16s('rs)");
912 Format(instr,
"swl 'rt, 'imm16s('rs)");
915 Format(instr,
"sw 'rt, 'imm16s('rs)");
918 Format(instr,
"swr 'rt, 'imm16s('rs)");
921 Format(instr,
"lwc1 'ft, 'imm16s('rs)");
924 Format(instr,
"ldc1 'ft, 'imm16s('rs)");
927 Format(instr,
"swc1 'ft, 'imm16s('rs)");
930 Format(instr,
"sdc1 'ft, 'imm16s('rs)");
939 void Decoder::DecodeTypeJump(Instruction* instr) {
940 switch (instr->OpcodeFieldRaw()) {
942 Format(instr,
"j 'imm26x");
945 Format(instr,
"jal 'imm26x");
954 int Decoder::InstructionDecode(
byte* instr_ptr) {
957 out_buffer_pos_ +=
OS::SNPrintF(out_buffer_ + out_buffer_pos_,
959 instr->InstructionBits());
960 switch (instr->InstructionType()) {
962 DecodeTypeRegister(instr);
966 DecodeTypeImmediate(instr);
970 DecodeTypeJump(instr);
974 Format(instr,
"UNSUPPORTED");
1027 : converter_(converter) {}
1030 Disassembler::~Disassembler() {}
1034 byte* instruction) {
1036 return d.InstructionDecode(instruction);
1041 int Disassembler::ConstantPoolSizeAt(
byte* instruction) {
1046 void Disassembler::Disassemble(FILE* f,
byte* begin,
byte* end) {
1047 NameConverter converter;
1048 Disassembler d(converter);
1049 for (
byte*
pc = begin;
pc < end;) {
1053 pc += d.InstructionDecode(buffer,
pc);
1055 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.
start());
1064 #endif // V8_TARGET_ARCH_MIPS
Disassembler(const NameConverter &converter)
void PrintF(const char *format,...)
virtual const char * NameOfXMMRegister(int reg) const
v8::internal::EmbeddedVector< char, 128 > tmp_buffer_
virtual const char * NameOfConstant(byte *addr) const
#define ASSERT(condition)
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
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
#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()
void Print(const v8::FunctionCallbackInfo< v8::Value > &args)