1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <assert.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <string.h>
9 
10 #if V8_TARGET_ARCH_LOONG64
11 
12 #include "src/base/platform/platform.h"
13 #include "src/base/strings.h"
14 #include "src/base/vector.h"
15 #include "src/codegen/loong64/constants-loong64.h"
16 #include "src/codegen/macro-assembler.h"
17 #include "src/diagnostics/disasm.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 //------------------------------------------------------------------------------
23 
24 // Decoder decodes and disassembles instructions into an output buffer.
25 // It uses the converter to convert register names and call destinations into
26 // more informative description.
27 class Decoder {
28  public:
Decoder(const disasm::NameConverter& converter, v8::base::Vector<char> out_buffer)29   Decoder(const disasm::NameConverter& converter,
30           v8::base::Vector<char> out_buffer)
31       : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
32     out_buffer_[out_buffer_pos_] = '\0';
33   }
34 
~Decoder()35   ~Decoder() {}
36 
37   Decoder(const Decoder&) = delete;
38   Decoder& operator=(const Decoder&) = delete;
39 
40   // Writes one disassembled instruction into 'buffer' (0-terminated).
41   // Returns the length of the disassembled machine instruction in bytes.
42   int InstructionDecode(byte* instruction);
43 
44  private:
45   // Bottleneck functions to print into the out_buffer.
46   void PrintChar(const char ch);
47   void Print(const char* str);
48 
49   // Printing of common values.
50   void PrintRegister(int reg);
51   void PrintFPURegister(int freg);
52   void PrintFPUStatusRegister(int freg);
53   void PrintRj(Instruction* instr);
54   void PrintRk(Instruction* instr);
55   void PrintRd(Instruction* instr);
56   void PrintFj(Instruction* instr);
57   void PrintFk(Instruction* instr);
58   void PrintFd(Instruction* instr);
59   void PrintFa(Instruction* instr);
60   void PrintSa2(Instruction* instr);
61   void PrintSa3(Instruction* instr);
62   void PrintUi5(Instruction* instr);
63   void PrintUi6(Instruction* instr);
64   void PrintUi12(Instruction* instr);
65   void PrintMsbw(Instruction* instr);
66   void PrintLsbw(Instruction* instr);
67   void PrintMsbd(Instruction* instr);
68   void PrintLsbd(Instruction* instr);
69   //  void PrintCond(Instruction* instr);
70   void PrintSi12(Instruction* instr);
71   void PrintSi14(Instruction* instr);
72   void PrintSi16(Instruction* instr);
73   void PrintSi20(Instruction* instr);
74   void PrintXi12(Instruction* instr);
75   void PrintXi20(Instruction* instr);
76   void PrintCj(Instruction* instr);
77   void PrintCd(Instruction* instr);
78   void PrintCa(Instruction* instr);
79   void PrintCode(Instruction* instr);
80   void PrintHint5(Instruction* instr);
81   void PrintHint15(Instruction* instr);
82   void PrintPCOffs16(Instruction* instr);
83   void PrintPCOffs21(Instruction* instr);
84   void PrintPCOffs26(Instruction* instr);
85   void PrintOffs16(Instruction* instr);
86   void PrintOffs21(Instruction* instr);
87   void PrintOffs26(Instruction* instr);
88 
89   // Handle formatting of instructions and their options.
90   int FormatRegister(Instruction* instr, const char* option);
91   int FormatFPURegister(Instruction* instr, const char* option);
92   int FormatOption(Instruction* instr, const char* option);
93   void Format(Instruction* instr, const char* format);
94   void Unknown(Instruction* instr);
95   int DecodeBreakInstr(Instruction* instr);
96 
97   // Each of these functions decodes one particular instruction type.
98   int InstructionDecode(Instruction* instr);
99   void DecodeTypekOp6(Instruction* instr);
100   void DecodeTypekOp7(Instruction* instr);
101   void DecodeTypekOp8(Instruction* instr);
102   void DecodeTypekOp10(Instruction* instr);
103   void DecodeTypekOp12(Instruction* instr);
104   void DecodeTypekOp14(Instruction* instr);
105   int DecodeTypekOp17(Instruction* instr);
106   void DecodeTypekOp22(Instruction* instr);
107 
108   const disasm::NameConverter& converter_;
109   v8::base::Vector<char> out_buffer_;
110   int out_buffer_pos_;
111 };
112 
113 // Support for assertions in the Decoder formatting functions.
114 #define STRING_STARTS_WITH(string, compare_string) \
115   (strncmp(string, compare_string, strlen(compare_string)) == 0)
116 
117 // Append the ch to the output buffer.
PrintChar(const char ch)118 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
119 
120 // Append the str to the output buffer.
Print(const char* str)121 void Decoder::Print(const char* str) {
122   char cur = *str++;
123   while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
124     PrintChar(cur);
125     cur = *str++;
126   }
127   out_buffer_[out_buffer_pos_] = 0;
128 }
129 
130 // Print the register name according to the active name converter.
PrintRegister(int reg)131 void Decoder::PrintRegister(int reg) {
132   Print(converter_.NameOfCPURegister(reg));
133 }
134 
PrintRj(Instruction* instr)135 void Decoder::PrintRj(Instruction* instr) {
136   int reg = instr->RjValue();
137   PrintRegister(reg);
138 }
139 
PrintRk(Instruction* instr)140 void Decoder::PrintRk(Instruction* instr) {
141   int reg = instr->RkValue();
142   PrintRegister(reg);
143 }
144 
PrintRd(Instruction* instr)145 void Decoder::PrintRd(Instruction* instr) {
146   int reg = instr->RdValue();
147   PrintRegister(reg);
148 }
149 
150 // Print the FPUregister name according to the active name converter.
PrintFPURegister(int freg)151 void Decoder::PrintFPURegister(int freg) {
152   Print(converter_.NameOfXMMRegister(freg));
153 }
154 
PrintFj(Instruction* instr)155 void Decoder::PrintFj(Instruction* instr) {
156   int freg = instr->FjValue();
157   PrintFPURegister(freg);
158 }
159 
PrintFk(Instruction* instr)160 void Decoder::PrintFk(Instruction* instr) {
161   int freg = instr->FkValue();
162   PrintFPURegister(freg);
163 }
164 
PrintFd(Instruction* instr)165 void Decoder::PrintFd(Instruction* instr) {
166   int freg = instr->FdValue();
167   PrintFPURegister(freg);
168 }
169 
PrintFa(Instruction* instr)170 void Decoder::PrintFa(Instruction* instr) {
171   int freg = instr->FaValue();
172   PrintFPURegister(freg);
173 }
174 
175 // Print the integer value of the sa field.
PrintSa2(Instruction* instr)176 void Decoder::PrintSa2(Instruction* instr) {
177   int sa = instr->Sa2Value();
178   uint32_t opcode = (instr->InstructionBits() >> 18) << 18;
179   if (opcode == ALSL || opcode == ALSL_D) {
180     sa += 1;
181   }
182   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
183 }
184 
PrintSa3(Instruction* instr)185 void Decoder::PrintSa3(Instruction* instr) {
186   int sa = instr->Sa3Value();
187   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
188 }
189 
PrintUi5(Instruction* instr)190 void Decoder::PrintUi5(Instruction* instr) {
191   int ui = instr->Ui5Value();
192   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
193 }
194 
PrintUi6(Instruction* instr)195 void Decoder::PrintUi6(Instruction* instr) {
196   int ui = instr->Ui6Value();
197   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
198 }
199 
PrintUi12(Instruction* instr)200 void Decoder::PrintUi12(Instruction* instr) {
201   int ui = instr->Ui12Value();
202   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ui);
203 }
204 
PrintXi12(Instruction* instr)205 void Decoder::PrintXi12(Instruction* instr) {
206   int xi = instr->Ui12Value();
207   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", xi);
208 }
209 
PrintXi20(Instruction* instr)210 void Decoder::PrintXi20(Instruction* instr) {
211   int xi = instr->Si20Value();
212   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", xi);
213 }
214 
PrintMsbd(Instruction* instr)215 void Decoder::PrintMsbd(Instruction* instr) {
216   int msbd = instr->MsbdValue();
217   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", msbd);
218 }
219 
PrintLsbd(Instruction* instr)220 void Decoder::PrintLsbd(Instruction* instr) {
221   int lsbd = instr->LsbdValue();
222   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", lsbd);
223 }
224 
PrintMsbw(Instruction* instr)225 void Decoder::PrintMsbw(Instruction* instr) {
226   int msbw = instr->MsbwValue();
227   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", msbw);
228 }
229 
PrintLsbw(Instruction* instr)230 void Decoder::PrintLsbw(Instruction* instr) {
231   int lsbw = instr->LsbwValue();
232   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", lsbw);
233 }
234 
PrintSi12(Instruction* instr)235 void Decoder::PrintSi12(Instruction* instr) {
236   int si = ((instr->Si12Value()) << (32 - kSi12Bits)) >> (32 - kSi12Bits);
237   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
238                                     si, instr->Si12Value());
239 }
240 
PrintSi14(Instruction* instr)241 void Decoder::PrintSi14(Instruction* instr) {
242   int si = ((instr->Si14Value()) << (32 - kSi14Bits)) >> (32 - kSi14Bits);
243   si <<= 2;
244   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
245                                     si, instr->Si14Value() << 2);
246 }
247 
PrintSi16(Instruction* instr)248 void Decoder::PrintSi16(Instruction* instr) {
249   int si = ((instr->Si16Value()) << (32 - kSi16Bits)) >> (32 - kSi16Bits);
250   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
251                                     si, instr->Si16Value());
252 }
253 
PrintSi20(Instruction* instr)254 void Decoder::PrintSi20(Instruction* instr) {
255   int si = ((instr->Si20Value()) << (32 - kSi20Bits)) >> (32 - kSi20Bits);
256   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d(0x%x)",
257                                     si, instr->Si20Value());
258 }
259 
PrintCj(Instruction* instr)260 void Decoder::PrintCj(Instruction* instr) {
261   int cj = instr->CjValue();
262   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", cj);
263 }
264 
PrintCd(Instruction* instr)265 void Decoder::PrintCd(Instruction* instr) {
266   int cd = instr->CdValue();
267   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", cd);
268 }
269 
PrintCa(Instruction* instr)270 void Decoder::PrintCa(Instruction* instr) {
271   int ca = instr->CaValue();
272   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", ca);
273 }
274 
PrintCode(Instruction* instr)275 void Decoder::PrintCode(Instruction* instr) {
276   int code = instr->CodeValue();
277   out_buffer_pos_ +=
278       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", code, code);
279 }
280 
PrintHint5(Instruction* instr)281 void Decoder::PrintHint5(Instruction* instr) {
282   int hint = instr->Hint5Value();
283   out_buffer_pos_ +=
284       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
285 }
286 
PrintHint15(Instruction* instr)287 void Decoder::PrintHint15(Instruction* instr) {
288   int hint = instr->Hint15Value();
289   out_buffer_pos_ +=
290       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
291 }
292 
PrintPCOffs16(Instruction* instr)293 void Decoder::PrintPCOffs16(Instruction* instr) {
294   int n_bits = 2;
295   int offs = instr->Offs16Value();
296   int target = ((offs << n_bits) << (32 - kOffsLowBits - n_bits)) >>
297                (32 - kOffsLowBits - n_bits);
298   out_buffer_pos_ += base::SNPrintF(
299       out_buffer_ + out_buffer_pos_, "%s",
300       converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
301 }
302 
PrintPCOffs21(Instruction* instr)303 void Decoder::PrintPCOffs21(Instruction* instr) {
304   int n_bits = 2;
305   int offs = instr->Offs21Value();
306   int target =
307       ((offs << n_bits) << (32 - kOffsLowBits - kOffs21HighBits - n_bits)) >>
308       (32 - kOffsLowBits - kOffs21HighBits - n_bits);
309   out_buffer_pos_ += base::SNPrintF(
310       out_buffer_ + out_buffer_pos_, "%s",
311       converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
312 }
313 
PrintPCOffs26(Instruction* instr)314 void Decoder::PrintPCOffs26(Instruction* instr) {
315   int n_bits = 2;
316   int offs = instr->Offs26Value();
317   int target =
318       ((offs << n_bits) << (32 - kOffsLowBits - kOffs26HighBits - n_bits)) >>
319       (32 - kOffsLowBits - kOffs26HighBits - n_bits);
320   out_buffer_pos_ += base::SNPrintF(
321       out_buffer_ + out_buffer_pos_, "%s",
322       converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + target));
323 }
324 
PrintOffs16(Instruction* instr)325 void Decoder::PrintOffs16(Instruction* instr) {
326   int offs = instr->Offs16Value();
327   out_buffer_pos_ +=
328       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
329 }
330 
PrintOffs21(Instruction* instr)331 void Decoder::PrintOffs21(Instruction* instr) {
332   int offs = instr->Offs21Value();
333   out_buffer_pos_ +=
334       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
335 }
336 
PrintOffs26(Instruction* instr)337 void Decoder::PrintOffs26(Instruction* instr) {
338   int offs = instr->Offs26Value();
339   out_buffer_pos_ +=
340       base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
341 }
342 
343 // Handle all register based formatting in this function to reduce the
344 // complexity of FormatOption.
FormatRegister(Instruction* instr, const char* format)345 int Decoder::FormatRegister(Instruction* instr, const char* format) {
346   DCHECK_EQ(format[0], 'r');
347   if (format[1] == 'j') {  // 'rj: Rj register.
348     int reg = instr->RjValue();
349     PrintRegister(reg);
350     return 2;
351   } else if (format[1] == 'k') {  // 'rk: rk register.
352     int reg = instr->RkValue();
353     PrintRegister(reg);
354     return 2;
355   } else if (format[1] == 'd') {  // 'rd: rd register.
356     int reg = instr->RdValue();
357     PrintRegister(reg);
358     return 2;
359   }
360   UNREACHABLE();
361 }
362 
363 // Handle all FPUregister based formatting in this function to reduce the
364 // complexity of FormatOption.
FormatFPURegister(Instruction* instr, const char* format)365 int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
366   DCHECK_EQ(format[0], 'f');
367   if (format[1] == 'j') {  // 'fj: fj register.
368     int reg = instr->FjValue();
369     PrintFPURegister(reg);
370     return 2;
371   } else if (format[1] == 'k') {  // 'fk: fk register.
372     int reg = instr->FkValue();
373     PrintFPURegister(reg);
374     return 2;
375   } else if (format[1] == 'd') {  // 'fd: fd register.
376     int reg = instr->FdValue();
377     PrintFPURegister(reg);
378     return 2;
379   } else if (format[1] == 'a') {  // 'fa: fa register.
380     int reg = instr->FaValue();
381     PrintFPURegister(reg);
382     return 2;
383   }
384   UNREACHABLE();
385 }
386 
387 // FormatOption takes a formatting string and interprets it based on
388 // the current instructions. The format string points to the first
389 // character of the option string (the option escape has already been
390 // consumed by the caller.)  FormatOption returns the number of
391 // characters that were consumed from the formatting string.
FormatOption(Instruction* instr, const char* format)392 int Decoder::FormatOption(Instruction* instr, const char* format) {
393   switch (format[0]) {
394     case 'c': {
395       switch (format[1]) {
396         case 'a':
397           DCHECK(STRING_STARTS_WITH(format, "ca"));
398           PrintCa(instr);
399           return 2;
400         case 'd':
401           DCHECK(STRING_STARTS_WITH(format, "cd"));
402           PrintCd(instr);
403           return 2;
404         case 'j':
405           DCHECK(STRING_STARTS_WITH(format, "cj"));
406           PrintCj(instr);
407           return 2;
408         case 'o':
409           DCHECK(STRING_STARTS_WITH(format, "code"));
410           PrintCode(instr);
411           return 4;
412       }
413     }
414     case 'f': {
415       return FormatFPURegister(instr, format);
416     }
417     case 'h': {
418       if (format[4] == '5') {
419         DCHECK(STRING_STARTS_WITH(format, "hint5"));
420         PrintHint5(instr);
421         return 5;
422       } else if (format[4] == '1') {
423         DCHECK(STRING_STARTS_WITH(format, "hint15"));
424         PrintHint15(instr);
425         return 6;
426       }
427       break;
428     }
429     case 'l': {
430       switch (format[3]) {
431         case 'w':
432           DCHECK(STRING_STARTS_WITH(format, "lsbw"));
433           PrintLsbw(instr);
434           return 4;
435         case 'd':
436           DCHECK(STRING_STARTS_WITH(format, "lsbd"));
437           PrintLsbd(instr);
438           return 4;
439         default:
440           return 0;
441       }
442     }
443     case 'm': {
444       if (format[3] == 'w') {
445         DCHECK(STRING_STARTS_WITH(format, "msbw"));
446         PrintMsbw(instr);
447       } else if (format[3] == 'd') {
448         DCHECK(STRING_STARTS_WITH(format, "msbd"));
449         PrintMsbd(instr);
450       }
451       return 4;
452     }
453     case 'o': {
454       if (format[1] == 'f') {
455         if (format[4] == '1') {
456           DCHECK(STRING_STARTS_WITH(format, "offs16"));
457           PrintOffs16(instr);
458           return 6;
459         } else if (format[4] == '2') {
460           if (format[5] == '1') {
461             DCHECK(STRING_STARTS_WITH(format, "offs21"));
462             PrintOffs21(instr);
463             return 6;
464           } else if (format[5] == '6') {
465             DCHECK(STRING_STARTS_WITH(format, "offs26"));
466             PrintOffs26(instr);
467             return 6;
468           }
469         }
470       }
471       break;
472     }
473     case 'p': {
474       if (format[6] == '1') {
475         DCHECK(STRING_STARTS_WITH(format, "pcoffs16"));
476         PrintPCOffs16(instr);
477         return 8;
478       } else if (format[6] == '2') {
479         if (format[7] == '1') {
480           DCHECK(STRING_STARTS_WITH(format, "pcoffs21"));
481           PrintPCOffs21(instr);
482           return 8;
483         } else if (format[7] == '6') {
484           DCHECK(STRING_STARTS_WITH(format, "pcoffs26"));
485           PrintPCOffs26(instr);
486           return 8;
487         }
488       }
489       break;
490     }
491     case 'r': {
492       return FormatRegister(instr, format);
493     }
494     case 's': {
495       switch (format[1]) {
496         case 'a':
497           if (format[2] == '2') {
498             DCHECK(STRING_STARTS_WITH(format, "sa2"));
499             PrintSa2(instr);
500           } else if (format[2] == '3') {
501             DCHECK(STRING_STARTS_WITH(format, "sa3"));
502             PrintSa3(instr);
503           }
504           return 3;
505         case 'i':
506           if (format[2] == '2') {
507             DCHECK(STRING_STARTS_WITH(format, "si20"));
508             PrintSi20(instr);
509             return 4;
510           } else if (format[2] == '1') {
511             switch (format[3]) {
512               case '2':
513                 DCHECK(STRING_STARTS_WITH(format, "si12"));
514                 PrintSi12(instr);
515                 return 4;
516               case '4':
517                 DCHECK(STRING_STARTS_WITH(format, "si14"));
518                 PrintSi14(instr);
519                 return 4;
520               case '6':
521                 DCHECK(STRING_STARTS_WITH(format, "si16"));
522                 PrintSi16(instr);
523                 return 4;
524               default:
525                 break;
526             }
527           }
528           break;
529         default:
530           break;
531       }
532       break;
533     }
534     case 'u': {
535       if (format[2] == '5') {
536         DCHECK(STRING_STARTS_WITH(format, "ui5"));
537         PrintUi5(instr);
538         return 3;
539       } else if (format[2] == '6') {
540         DCHECK(STRING_STARTS_WITH(format, "ui6"));
541         PrintUi6(instr);
542         return 3;
543       } else if (format[2] == '1') {
544         DCHECK(STRING_STARTS_WITH(format, "ui12"));
545         PrintUi12(instr);
546         return 4;
547       }
548       break;
549     }
550     case 'x': {
551       if (format[2] == '2') {
552         DCHECK(STRING_STARTS_WITH(format, "xi20"));
553         PrintXi20(instr);
554         return 4;
555       } else if (format[3] == '2') {
556         DCHECK(STRING_STARTS_WITH(format, "xi12"));
557         PrintXi12(instr);
558         return 4;
559       }
560       break;
561     }
562     default:
563       UNREACHABLE();
564   }
565   return 0;
566 }
567 
568 // Format takes a formatting string for a whole instruction and prints it into
569 // the output buffer. All escaped options are handed to FormatOption to be
570 // parsed further.
Format(Instruction* instr, const char* format)571 void Decoder::Format(Instruction* instr, const char* format) {
572   char cur = *format++;
573   while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
574     if (cur == '\'') {  // Single quote is used as the formatting escape.
575       format += FormatOption(instr, format);
576     } else {
577       out_buffer_[out_buffer_pos_++] = cur;
578     }
579     cur = *format++;
580   }
581   out_buffer_[out_buffer_pos_] = '\0';
582 }
583 
584 // For currently unimplemented decodings the disassembler calls Unknown(instr)
585 // which will just print "unknown" of the instruction bits.
Unknown(Instruction* instr)586 void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
587 
DecodeBreakInstr(Instruction* instr)588 int Decoder::DecodeBreakInstr(Instruction* instr) {
589   // This is already known to be BREAK instr, just extract the code.
590   /*if (instr->Bits(14, 0) == static_cast<int>(kMaxStopCode)) {
591     // This is stop(msg).
592     Format(instr, "break, code: 'code");
593     out_buffer_pos_ += SNPrintF(
594         out_buffer_ + out_buffer_pos_, "\n%p       %08" PRIx64,
595         static_cast<void*>(reinterpret_cast<int32_t*>(instr + kInstrSize)),
596         reinterpret_cast<uint64_t>(
597             *reinterpret_cast<char**>(instr + kInstrSize)));
598     // Size 3: the break_ instr, plus embedded 64-bit char pointer.
599     return 3 * kInstrSize;
600   } else {
601     Format(instr, "break, code: 'code");
602     return kInstrSize;
603   }*/
604   Format(instr, "break        code: 'code");
605   return kInstrSize;
606 }  //===================================================
607 
DecodeTypekOp6(Instruction* instr)608 void Decoder::DecodeTypekOp6(Instruction* instr) {
609   switch (instr->Bits(31, 26) << 26) {
610     case ADDU16I_D:
611       Format(instr, "addu16i.d    'rd, 'rj, 'si16");
612       break;
613     case BEQZ:
614       Format(instr, "beqz         'rj, 'offs21 -> 'pcoffs21");
615       break;
616     case BNEZ:
617       Format(instr, "bnez         'rj, 'offs21 -> 'pcoffs21");
618       break;
619     case BCZ:
620       if (instr->Bit(8))
621         Format(instr, "bcnez        fcc'cj, 'offs21 -> 'pcoffs21");
622       else
623         Format(instr, "bceqz        fcc'cj, 'offs21 -> 'pcoffs21");
624       break;
625     case JIRL:
626       Format(instr, "jirl         'rd, 'rj, 'offs16");
627       break;
628     case B:
629       Format(instr, "b            'offs26 -> 'pcoffs26");
630       break;
631     case BL:
632       Format(instr, "bl           'offs26 -> 'pcoffs26");
633       break;
634     case BEQ:
635       Format(instr, "beq          'rj, 'rd, 'offs16 -> 'pcoffs16");
636       break;
637     case BNE:
638       Format(instr, "bne          'rj, 'rd, 'offs16 -> 'pcoffs16");
639       break;
640     case BLT:
641       Format(instr, "blt          'rj, 'rd, 'offs16 -> 'pcoffs16");
642       break;
643     case BGE:
644       Format(instr, "bge          'rj, 'rd, 'offs16 -> 'pcoffs16");
645       break;
646     case BLTU:
647       Format(instr, "bltu         'rj, 'rd, 'offs16 -> 'pcoffs16");
648       break;
649     case BGEU:
650       Format(instr, "bgeu         'rj, 'rd, 'offs16 -> 'pcoffs16");
651       break;
652     default:
653       UNREACHABLE();
654   }
655 }
656 
DecodeTypekOp7(Instruction* instr)657 void Decoder::DecodeTypekOp7(Instruction* instr) {
658   switch (instr->Bits(31, 25) << 25) {
659     case LU12I_W:
660       Format(instr, "lu12i.w      'rd, 'xi20");
661       break;
662     case LU32I_D:
663       Format(instr, "lu32i.d      'rd, 'xi20");
664       break;
665     case PCADDI:
666       Format(instr, "pcaddi       'rd, 'xi20");
667       break;
668     case PCALAU12I:
669       Format(instr, "pcalau12i    'rd, 'xi20");
670       break;
671     case PCADDU12I:
672       Format(instr, "pcaddu12i    'rd, 'xi20");
673       break;
674     case PCADDU18I:
675       Format(instr, "pcaddu18i    'rd, 'xi20");
676       break;
677     default:
678       UNREACHABLE();
679   }
680 }
681 
DecodeTypekOp8(Instruction* instr)682 void Decoder::DecodeTypekOp8(Instruction* instr) {
683   switch (instr->Bits(31, 24) << 24) {
684     case LDPTR_W:
685       Format(instr, "ldptr.w      'rd, 'rj, 'si14");
686       break;
687     case STPTR_W:
688       Format(instr, "stptr.w      'rd, 'rj, 'si14");
689       break;
690     case LDPTR_D:
691       Format(instr, "ldptr.d      'rd, 'rj, 'si14");
692       break;
693     case STPTR_D:
694       Format(instr, "stptr.d      'rd, 'rj, 'si14");
695       break;
696     case LL_W:
697       Format(instr, "ll.w         'rd, 'rj, 'si14");
698       break;
699     case SC_W:
700       Format(instr, "sc.w         'rd, 'rj, 'si14");
701       break;
702     case LL_D:
703       Format(instr, "ll.d         'rd, 'rj, 'si14");
704       break;
705     case SC_D:
706       Format(instr, "sc.d         'rd, 'rj, 'si14");
707       break;
708     default:
709       UNREACHABLE();
710   }
711 }
712 
DecodeTypekOp10(Instruction* instr)713 void Decoder::DecodeTypekOp10(Instruction* instr) {
714   switch (instr->Bits(31, 22) << 22) {
715     case BSTR_W: {
716       if (instr->Bit(21) != 0) {
717         if (instr->Bit(15) == 0) {
718           Format(instr, "bstrins.w    'rd, 'rj, 'msbw, 'lsbw");
719         } else {
720           Format(instr, "bstrpick.w   'rd, 'rj, 'msbw, 'lsbw");
721         }
722       }
723       break;
724     }
725     case BSTRINS_D:
726       Format(instr, "bstrins.d    'rd, 'rj, 'msbd, 'lsbd");
727       break;
728     case BSTRPICK_D:
729       Format(instr, "bstrpick.d   'rd, 'rj, 'msbd, 'lsbd");
730       break;
731     case SLTI:
732       Format(instr, "slti         'rd, 'rj, 'si12");
733       break;
734     case SLTUI:
735       Format(instr, "sltui        'rd, 'rj, 'si12");
736       break;
737     case ADDI_W:
738       Format(instr, "addi.w       'rd, 'rj, 'si12");
739       break;
740     case ADDI_D:
741       Format(instr, "addi.d       'rd, 'rj, 'si12");
742       break;
743     case LU52I_D:
744       Format(instr, "lu52i.d      'rd, 'rj, 'xi12");
745       break;
746     case ANDI:
747       Format(instr, "andi         'rd, 'rj, 'xi12");
748       break;
749     case ORI:
750       Format(instr, "ori          'rd, 'rj, 'xi12");
751       break;
752     case XORI:
753       Format(instr, "xori         'rd, 'rj, 'xi12");
754       break;
755     case LD_B:
756       Format(instr, "ld.b         'rd, 'rj, 'si12");
757       break;
758     case LD_H:
759       Format(instr, "ld.h         'rd, 'rj, 'si12");
760       break;
761     case LD_W:
762       Format(instr, "ld.w         'rd, 'rj, 'si12");
763       break;
764     case LD_D:
765       Format(instr, "ld.d         'rd, 'rj, 'si12");
766       break;
767     case ST_B:
768       Format(instr, "st.b         'rd, 'rj, 'si12");
769       break;
770     case ST_H:
771       Format(instr, "st.h         'rd, 'rj, 'si12");
772       break;
773     case ST_W:
774       Format(instr, "st.w         'rd, 'rj, 'si12");
775       break;
776     case ST_D:
777       Format(instr, "st.d         'rd, 'rj, 'si12");
778       break;
779     case LD_BU:
780       Format(instr, "ld.bu        'rd, 'rj, 'si12");
781       break;
782     case LD_HU:
783       Format(instr, "ld.hu        'rd, 'rj, 'si12");
784       break;
785     case LD_WU:
786       Format(instr, "ld.wu        'rd, 'rj, 'si12");
787       break;
788     case FLD_S:
789       Format(instr, "fld.s        'fd, 'rj, 'si12");
790       break;
791     case FST_S:
792       Format(instr, "fst.s        'fd, 'rj, 'si12");
793       break;
794     case FLD_D:
795       Format(instr, "fld.d        'fd, 'rj, 'si12");
796       break;
797     case FST_D:
798       Format(instr, "fst.d        'fd, 'rj, 'si12");
799       break;
800     default:
801       UNREACHABLE();
802   }
803 }
804 
DecodeTypekOp12(Instruction* instr)805 void Decoder::DecodeTypekOp12(Instruction* instr) {
806   switch (instr->Bits(31, 20) << 20) {
807     case FMADD_S:
808       Format(instr, "fmadd.s      'fd, 'fj, 'fk, 'fa");
809       break;
810     case FMADD_D:
811       Format(instr, "fmadd.d      'fd, 'fj, 'fk, 'fa");
812       break;
813     case FMSUB_S:
814       Format(instr, "fmsub.s      'fd, 'fj, 'fk, 'fa");
815       break;
816     case FMSUB_D:
817       Format(instr, "fmsub.d      'fd, 'fj, 'fk, 'fa");
818       break;
819     case FNMADD_S:
820       Format(instr, "fnmadd.s     'fd, 'fj, 'fk, 'fa");
821       break;
822     case FNMADD_D:
823       Format(instr, "fnmadd.d     'fd, 'fj, 'fk, 'fa");
824       break;
825     case FNMSUB_S:
826       Format(instr, "fnmsub.s     'fd, 'fj, 'fk, 'fa");
827       break;
828     case FNMSUB_D:
829       Format(instr, "fnmsub.d     'fd, 'fj, 'fk, 'fa");
830       break;
831     case FCMP_COND_S:
832       switch (instr->Bits(19, 15)) {
833         case CAF:
834           Format(instr, "fcmp.caf.s   fcc'cd, 'fj, 'fk");
835           break;
836         case SAF:
837           Format(instr, "fcmp.saf.s   fcc'cd, 'fj, 'fk");
838           break;
839         case CLT:
840           Format(instr, "fcmp.clt.s   fcc'cd, 'fj, 'fk");
841           break;
842         case CEQ:
843           Format(instr, "fcmp.ceq.s   fcc'cd, 'fj, 'fk");
844           break;
845         case SEQ:
846           Format(instr, "fcmp.seq.s   fcc'cd, 'fj, 'fk");
847           break;
848         case CLE:
849           Format(instr, "fcmp.cle.s   fcc'cd, 'fj, 'fk");
850           break;
851         case SLE:
852           Format(instr, "fcmp.sle.s   fcc'cd, 'fj, 'fk");
853           break;
854         case CUN:
855           Format(instr, "fcmp.cun.s   fcc'cd, 'fj, 'fk");
856           break;
857         case SUN:
858           Format(instr, "fcmp.sun.s   fcc'cd, 'fj, 'fk");
859           break;
860         case CULT:
861           Format(instr, "fcmp.cult.s  fcc'cd, 'fj, 'fk");
862           break;
863         case SULT:
864           Format(instr, "fcmp.sult.s  fcc'cd, 'fj, 'fk");
865           break;
866         case CUEQ:
867           Format(instr, "fcmp.cueq.s  fcc'cd, 'fj, 'fk");
868           break;
869         case SUEQ:
870           Format(instr, "fcmp.sueq.s  fcc'cd, 'fj, 'fk");
871           break;
872         case CULE:
873           Format(instr, "fcmp.cule.s  fcc'cd, 'fj, 'fk");
874           break;
875         case SULE:
876           Format(instr, "fcmp.sule.s  fcc'cd, 'fj, 'fk");
877           break;
878         case CNE:
879           Format(instr, "fcmp.cne.s   fcc'cd, 'fj, 'fk");
880           break;
881         case SNE:
882           Format(instr, "fcmp.sne.s   fcc'cd, 'fj, 'fk");
883           break;
884         case COR:
885           Format(instr, "fcmp.cor.s   fcc'cd, 'fj, 'fk");
886           break;
887         case SOR:
888           Format(instr, "fcmp.sor.s   fcc'cd, 'fj, 'fk");
889           break;
890         case CUNE:
891           Format(instr, "fcmp.cune.s  fcc'cd, 'fj, 'fk");
892           break;
893         case SUNE:
894           Format(instr, "fcmp.sune.s  fcc'cd, 'fj, 'fk");
895           break;
896         default:
897           UNREACHABLE();
898       }
899       break;
900     case FCMP_COND_D:
901       switch (instr->Bits(19, 15)) {
902         case CAF:
903           Format(instr, "fcmp.caf.d   fcc'cd, 'fj, 'fk");
904           break;
905         case SAF:
906           Format(instr, "fcmp.saf.d   fcc'cd, 'fj, 'fk");
907           break;
908         case CLT:
909           Format(instr, "fcmp.clt.d   fcc'cd, 'fj, 'fk");
910           break;
911         case CEQ:
912           Format(instr, "fcmp.ceq.d   fcc'cd, 'fj, 'fk");
913           break;
914         case SEQ:
915           Format(instr, "fcmp.seq.d   fcc'cd, 'fj, 'fk");
916           break;
917         case CLE:
918           Format(instr, "fcmp.cle.d   fcc'cd, 'fj, 'fk");
919           break;
920         case SLE:
921           Format(instr, "fcmp.sle.d   fcc'cd, 'fj, 'fk");
922           break;
923         case CUN:
924           Format(instr, "fcmp.cun.d   fcc'cd, 'fj, 'fk");
925           break;
926         case SUN:
927           Format(instr, "fcmp.sun.d   fcc'cd, 'fj, 'fk");
928           break;
929         case CULT:
930           Format(instr, "fcmp.cult.d  fcc'cd, 'fj, 'fk");
931           break;
932         case SULT:
933           Format(instr, "fcmp.sult.d  fcc'cd, 'fj, 'fk");
934           break;
935         case CUEQ:
936           Format(instr, "fcmp.cueq.d  fcc'cd, 'fj, 'fk");
937           break;
938         case SUEQ:
939           Format(instr, "fcmp.sueq.d  fcc'cd, 'fj, 'fk");
940           break;
941         case CULE:
942           Format(instr, "fcmp.cule.d  fcc'cd, 'fj, 'fk");
943           break;
944         case SULE:
945           Format(instr, "fcmp.sule.d  fcc'cd, 'fj, 'fk");
946           break;
947         case CNE:
948           Format(instr, "fcmp.cne.d   fcc'cd, 'fj, 'fk");
949           break;
950         case SNE:
951           Format(instr, "fcmp.sne.d   fcc'cd, 'fj, 'fk");
952           break;
953         case COR:
954           Format(instr, "fcmp.cor.d   fcc'cd, 'fj, 'fk");
955           break;
956         case SOR:
957           Format(instr, "fcmp.sor.d   fcc'cd, 'fj, 'fk");
958           break;
959         case CUNE:
960           Format(instr, "fcmp.cune.d  fcc'cd, 'fj, 'fk");
961           break;
962         case SUNE:
963           Format(instr, "fcmp.sune.d  fcc'cd, 'fj, 'fk");
964           break;
965         default:
966           UNREACHABLE();
967       }
968       break;
969     case FSEL:
970       Format(instr, "fsel         'fd, 'fj, 'fk, fcc'ca");
971       break;
972     default:
973       UNREACHABLE();
974   }
975 }
976 
DecodeTypekOp14(Instruction* instr)977 void Decoder::DecodeTypekOp14(Instruction* instr) {
978   switch (instr->Bits(31, 18) << 18) {
979     case ALSL:
980       if (instr->Bit(17))
981         Format(instr, "alsl.wu      'rd, 'rj, 'rk, 'sa2");
982       else
983         Format(instr, "alsl.w       'rd, 'rj, 'rk, 'sa2");
984       break;
985     case BYTEPICK_W:
986       Format(instr, "bytepick.w   'rd, 'rj, 'rk, 'sa2");
987       break;
988     case BYTEPICK_D:
989       Format(instr, "bytepick.d   'rd, 'rj, 'rk, 'sa3");
990       break;
991     case ALSL_D:
992       Format(instr, "alsl.d       'rd, 'rj, 'rk, 'sa2");
993       break;
994     case SLLI:
995       if (instr->Bit(16))
996         Format(instr, "slli.d       'rd, 'rj, 'ui6");
997       else
998         Format(instr, "slli.w       'rd, 'rj, 'ui5");
999       break;
1000     case SRLI:
1001       if (instr->Bit(16))
1002         Format(instr, "srli.d       'rd, 'rj, 'ui6");
1003       else
1004         Format(instr, "srli.w       'rd, 'rj, 'ui5");
1005       break;
1006     case SRAI:
1007       if (instr->Bit(16))
1008         Format(instr, "srai.d       'rd, 'rj, 'ui6");
1009       else
1010         Format(instr, "srai.w       'rd, 'rj, 'ui5");
1011       break;
1012     case ROTRI:
1013       if (instr->Bit(16))
1014         Format(instr, "rotri.d      'rd, 'rj, 'ui6");
1015       else
1016         Format(instr, "rotri.w      'rd, 'rj, 'ui5");
1017       break;
1018     default:
1019       UNREACHABLE();
1020   }
1021 }
1022 
DecodeTypekOp17(Instruction* instr)1023 int Decoder::DecodeTypekOp17(Instruction* instr) {
1024   switch (instr->Bits(31, 15) << 15) {
1025     case ADD_W:
1026       Format(instr, "add.w        'rd, 'rj, 'rk");
1027       break;
1028     case ADD_D:
1029       Format(instr, "add.d        'rd, 'rj, 'rk");
1030       break;
1031     case SUB_W:
1032       Format(instr, "sub.w        'rd, 'rj, 'rk");
1033       break;
1034     case SUB_D:
1035       Format(instr, "sub.d        'rd, 'rj, 'rk");
1036       break;
1037     case SLT:
1038       Format(instr, "slt          'rd, 'rj, 'rk");
1039       break;
1040     case SLTU:
1041       Format(instr, "sltu         'rd, 'rj, 'rk");
1042       break;
1043     case MASKEQZ:
1044       Format(instr, "maskeqz      'rd, 'rj, 'rk");
1045       break;
1046     case MASKNEZ:
1047       Format(instr, "masknez      'rd, 'rj, 'rk");
1048       break;
1049     case NOR:
1050       Format(instr, "nor          'rd, 'rj, 'rk");
1051       break;
1052     case AND:
1053       Format(instr, "and          'rd, 'rj, 'rk");
1054       break;
1055     case OR:
1056       Format(instr, "or           'rd, 'rj, 'rk");
1057       break;
1058     case XOR:
1059       Format(instr, "xor          'rd, 'rj, 'rk");
1060       break;
1061     case ORN:
1062       Format(instr, "orn          'rd, 'rj, 'rk");
1063       break;
1064     case ANDN:
1065       Format(instr, "andn         'rd, 'rj, 'rk");
1066       break;
1067     case SLL_W:
1068       Format(instr, "sll.w        'rd, 'rj, 'rk");
1069       break;
1070     case SRL_W:
1071       Format(instr, "srl.w        'rd, 'rj, 'rk");
1072       break;
1073     case SRA_W:
1074       Format(instr, "sra.w        'rd, 'rj, 'rk");
1075       break;
1076     case SLL_D:
1077       Format(instr, "sll.d        'rd, 'rj, 'rk");
1078       break;
1079     case SRL_D:
1080       Format(instr, "srl.d        'rd, 'rj, 'rk");
1081       break;
1082     case SRA_D:
1083       Format(instr, "sra.d        'rd, 'rj, 'rk");
1084       break;
1085     case ROTR_D:
1086       Format(instr, "rotr.d       'rd, 'rj, 'rk");
1087       break;
1088     case ROTR_W:
1089       Format(instr, "rotr.w       'rd, 'rj, 'rk");
1090       break;
1091     case MUL_W:
1092       Format(instr, "mul.w        'rd, 'rj, 'rk");
1093       break;
1094     case MULH_W:
1095       Format(instr, "mulh.w       'rd, 'rj, 'rk");
1096       break;
1097     case MULH_WU:
1098       Format(instr, "mulh.wu      'rd, 'rj, 'rk");
1099       break;
1100     case MUL_D:
1101       Format(instr, "mul.d        'rd, 'rj, 'rk");
1102       break;
1103     case MULH_D:
1104       Format(instr, "mulh.d       'rd, 'rj, 'rk");
1105       break;
1106     case MULH_DU:
1107       Format(instr, "mulh.du      'rd, 'rj, 'rk");
1108       break;
1109     case MULW_D_W:
1110       Format(instr, "mulw.d.w     'rd, 'rj, 'rk");
1111       break;
1112     case MULW_D_WU:
1113       Format(instr, "mulw.d.wu    'rd, 'rj, 'rk");
1114       break;
1115     case DIV_W:
1116       Format(instr, "div.w        'rd, 'rj, 'rk");
1117       break;
1118     case MOD_W:
1119       Format(instr, "mod.w        'rd, 'rj, 'rk");
1120       break;
1121     case DIV_WU:
1122       Format(instr, "div.wu       'rd, 'rj, 'rk");
1123       break;
1124     case MOD_WU:
1125       Format(instr, "mod.wu       'rd, 'rj, 'rk");
1126       break;
1127     case DIV_D:
1128       Format(instr, "div.d        'rd, 'rj, 'rk");
1129       break;
1130     case MOD_D:
1131       Format(instr, "mod.d        'rd, 'rj, 'rk");
1132       break;
1133     case DIV_DU:
1134       Format(instr, "div.du       'rd, 'rj, 'rk");
1135       break;
1136     case MOD_DU:
1137       Format(instr, "mod.du       'rd, 'rj, 'rk");
1138       break;
1139     case BREAK:
1140       return DecodeBreakInstr(instr);
1141     case FADD_S:
1142       Format(instr, "fadd.s       'fd, 'fj, 'fk");
1143       break;
1144     case FADD_D:
1145       Format(instr, "fadd.d       'fd, 'fj, 'fk");
1146       break;
1147     case FSUB_S:
1148       Format(instr, "fsub.s       'fd, 'fj, 'fk");
1149       break;
1150     case FSUB_D:
1151       Format(instr, "fsub.d       'fd, 'fj, 'fk");
1152       break;
1153     case FMUL_S:
1154       Format(instr, "fmul.s       'fd, 'fj, 'fk");
1155       break;
1156     case FMUL_D:
1157       Format(instr, "fmul.d       'fd, 'fj, 'fk");
1158       break;
1159     case FDIV_S:
1160       Format(instr, "fdiv.s       'fd, 'fj, 'fk");
1161       break;
1162     case FDIV_D:
1163       Format(instr, "fdiv.d       'fd, 'fj, 'fk");
1164       break;
1165     case FMAX_S:
1166       Format(instr, "fmax.s       'fd, 'fj, 'fk");
1167       break;
1168     case FMAX_D:
1169       Format(instr, "fmax.d       'fd, 'fj, 'fk");
1170       break;
1171     case FMIN_S:
1172       Format(instr, "fmin.s       'fd, 'fj, 'fk");
1173       break;
1174     case FMIN_D:
1175       Format(instr, "fmin.d       'fd, 'fj, 'fk");
1176       break;
1177     case FMAXA_S:
1178       Format(instr, "fmaxa.s      'fd, 'fj, 'fk");
1179       break;
1180     case FMAXA_D:
1181       Format(instr, "fmaxa.d      'fd, 'fj, 'fk");
1182       break;
1183     case FMINA_S:
1184       Format(instr, "fmina.s      'fd, 'fj, 'fk");
1185       break;
1186     case FMINA_D:
1187       Format(instr, "fmina.d      'fd, 'fj, 'fk");
1188       break;
1189     case LDX_B:
1190       Format(instr, "ldx.b        'rd, 'rj, 'rk");
1191       break;
1192     case LDX_H:
1193       Format(instr, "ldx.h        'rd, 'rj, 'rk");
1194       break;
1195     case LDX_W:
1196       Format(instr, "ldx.w        'rd, 'rj, 'rk");
1197       break;
1198     case LDX_D:
1199       Format(instr, "ldx.d        'rd, 'rj, 'rk");
1200       break;
1201     case STX_B:
1202       Format(instr, "stx.b        'rd, 'rj, 'rk");
1203       break;
1204     case STX_H:
1205       Format(instr, "stx.h        'rd, 'rj, 'rk");
1206       break;
1207     case STX_W:
1208       Format(instr, "stx.w        'rd, 'rj, 'rk");
1209       break;
1210     case STX_D:
1211       Format(instr, "stx.d        'rd, 'rj, 'rk");
1212       break;
1213     case LDX_BU:
1214       Format(instr, "ldx.bu       'rd, 'rj, 'rk");
1215       break;
1216     case LDX_HU:
1217       Format(instr, "ldx.hu       'rd, 'rj, 'rk");
1218       break;
1219     case LDX_WU:
1220       Format(instr, "ldx.wu       'rd, 'rj, 'rk");
1221       break;
1222     case FLDX_S:
1223       Format(instr, "fldx.s       'fd, 'rj, 'rk");
1224       break;
1225     case FLDX_D:
1226       Format(instr, "fldx.d       'fd, 'rj, 'rk");
1227       break;
1228     case FSTX_S:
1229       Format(instr, "fstx.s       'fd, 'rj, 'rk");
1230       break;
1231     case FSTX_D:
1232       Format(instr, "fstx.d       'fd, 'rj, 'rk");
1233       break;
1234     case AMSWAP_W:
1235       Format(instr, "amswap.w     'rd, 'rk, 'rj");
1236       break;
1237     case AMSWAP_D:
1238       Format(instr, "amswap.d     'rd, 'rk, 'rj");
1239       break;
1240     case AMADD_W:
1241       Format(instr, "amadd.w      'rd, 'rk, 'rj");
1242       break;
1243     case AMADD_D:
1244       Format(instr, "amadd.d      'rd, 'rk, 'rj");
1245       break;
1246     case AMAND_W:
1247       Format(instr, "amand.w      'rd, 'rk, 'rj");
1248       break;
1249     case AMAND_D:
1250       Format(instr, "amand.d      'rd, 'rk, 'rj");
1251       break;
1252     case AMOR_W:
1253       Format(instr, "amor.w       'rd, 'rk, 'rj");
1254       break;
1255     case AMOR_D:
1256       Format(instr, "amor.d       'rd, 'rk, 'rj");
1257       break;
1258     case AMXOR_W:
1259       Format(instr, "amxor.w      'rd, 'rk, 'rj");
1260       break;
1261     case AMXOR_D:
1262       Format(instr, "amxor.d      'rd, 'rk, 'rj");
1263       break;
1264     case AMMAX_W:
1265       Format(instr, "ammax.w      'rd, 'rk, 'rj");
1266       break;
1267     case AMMAX_D:
1268       Format(instr, "ammax.d      'rd, 'rk, 'rj");
1269       break;
1270     case AMMIN_W:
1271       Format(instr, "ammin.w      'rd, 'rk, 'rj");
1272       break;
1273     case AMMIN_D:
1274       Format(instr, "ammin.d      'rd, 'rk, 'rj");
1275       break;
1276     case AMMAX_WU:
1277       Format(instr, "ammax.wu     'rd, 'rk, 'rj");
1278       break;
1279     case AMMAX_DU:
1280       Format(instr, "ammax.du     'rd, 'rk, 'rj");
1281       break;
1282     case AMMIN_WU:
1283       Format(instr, "ammin.wu     'rd, 'rk, 'rj");
1284       break;
1285     case AMMIN_DU:
1286       Format(instr, "ammin.du     'rd, 'rk, 'rj");
1287       break;
1288     case AMSWAP_DB_W:
1289       Format(instr, "amswap_db.w  'rd, 'rk, 'rj");
1290       break;
1291     case AMSWAP_DB_D:
1292       Format(instr, "amswap_db.d  'rd, 'rk, 'rj");
1293       break;
1294     case AMADD_DB_W:
1295       Format(instr, "amadd_db.w   'rd, 'rk, 'rj");
1296       break;
1297     case AMADD_DB_D:
1298       Format(instr, "amadd_db.d   'rd, 'rk, 'rj");
1299       break;
1300     case AMAND_DB_W:
1301       Format(instr, "amand_db.w   'rd, 'rk, 'rj");
1302       break;
1303     case AMAND_DB_D:
1304       Format(instr, "amand_db.d   'rd, 'rk, 'rj");
1305       break;
1306     case AMOR_DB_W:
1307       Format(instr, "amor_db.w    'rd, 'rk, 'rj");
1308       break;
1309     case AMOR_DB_D:
1310       Format(instr, "amor_db.d    'rd, 'rk, 'rj");
1311       break;
1312     case AMXOR_DB_W:
1313       Format(instr, "amxor_db.w   'rd, 'rk, 'rj");
1314       break;
1315     case AMXOR_DB_D:
1316       Format(instr, "amxor_db.d   'rd, 'rk, 'rj");
1317       break;
1318     case AMMAX_DB_W:
1319       Format(instr, "ammax_db.w   'rd, 'rk, 'rj");
1320       break;
1321     case AMMAX_DB_D:
1322       Format(instr, "ammax_db.d   'rd, 'rk, 'rj");
1323       break;
1324     case AMMIN_DB_W:
1325       Format(instr, "ammin_db.w   'rd, 'rk, 'rj");
1326       break;
1327     case AMMIN_DB_D:
1328       Format(instr, "ammin_db.d   'rd, 'rk, 'rj");
1329       break;
1330     case AMMAX_DB_WU:
1331       Format(instr, "ammax_db.wu  'rd, 'rk, 'rj");
1332       break;
1333     case AMMAX_DB_DU:
1334       Format(instr, "ammax_db.du  'rd, 'rk, 'rj");
1335       break;
1336     case AMMIN_DB_WU:
1337       Format(instr, "ammin_db.wu  'rd, 'rk, 'rj");
1338       break;
1339     case AMMIN_DB_DU:
1340       Format(instr, "ammin_db.du  'rd, 'rk, 'rj");
1341       break;
1342     case DBAR:
1343       Format(instr, "dbar         'hint15");
1344       break;
1345     case IBAR:
1346       Format(instr, "ibar         'hint15");
1347       break;
1348     case FSCALEB_S:
1349       Format(instr, "fscaleb.s    'fd, 'fj, 'fk");
1350       break;
1351     case FSCALEB_D:
1352       Format(instr, "fscaleb.d    'fd, 'fj, 'fk");
1353       break;
1354     case FCOPYSIGN_S:
1355       Format(instr, "fcopysign.s  'fd, 'fj, 'fk");
1356       break;
1357     case FCOPYSIGN_D:
1358       Format(instr, "fcopysign.d  'fd, 'fj, 'fk");
1359       break;
1360     default:
1361       UNREACHABLE();
1362   }
1363   return kInstrSize;
1364 }
1365 
DecodeTypekOp22(Instruction* instr)1366 void Decoder::DecodeTypekOp22(Instruction* instr) {
1367   switch (instr->Bits(31, 10) << 10) {
1368     case CLZ_W:
1369       Format(instr, "clz.w        'rd, 'rj");
1370       break;
1371     case CTZ_W:
1372       Format(instr, "ctz.w        'rd, 'rj");
1373       break;
1374     case CLZ_D:
1375       Format(instr, "clz.d        'rd, 'rj");
1376       break;
1377     case CTZ_D:
1378       Format(instr, "ctz.d        'rd, 'rj");
1379       break;
1380     case REVB_2H:
1381       Format(instr, "revb.2h      'rd, 'rj");
1382       break;
1383     case REVB_4H:
1384       Format(instr, "revb.4h      'rd, 'rj");
1385       break;
1386     case REVB_2W:
1387       Format(instr, "revb.2w      'rd, 'rj");
1388       break;
1389     case REVB_D:
1390       Format(instr, "revb.d       'rd, 'rj");
1391       break;
1392     case REVH_2W:
1393       Format(instr, "revh.2w      'rd, 'rj");
1394       break;
1395     case REVH_D:
1396       Format(instr, "revh.d       'rd, 'rj");
1397       break;
1398     case BITREV_4B:
1399       Format(instr, "bitrev.4b    'rd, 'rj");
1400       break;
1401     case BITREV_8B:
1402       Format(instr, "bitrev.8b    'rd, 'rj");
1403       break;
1404     case BITREV_W:
1405       Format(instr, "bitrev.w     'rd, 'rj");
1406       break;
1407     case BITREV_D:
1408       Format(instr, "bitrev.d     'rd, 'rj");
1409       break;
1410     case EXT_W_B:
1411       Format(instr, "ext.w.b      'rd, 'rj");
1412       break;
1413     case EXT_W_H:
1414       Format(instr, "ext.w.h      'rd, 'rj");
1415       break;
1416     case FABS_S:
1417       Format(instr, "fabs.s       'fd, 'fj");
1418       break;
1419     case FABS_D:
1420       Format(instr, "fabs.d       'fd, 'fj");
1421       break;
1422     case FNEG_S:
1423       Format(instr, "fneg.s       'fd, 'fj");
1424       break;
1425     case FNEG_D:
1426       Format(instr, "fneg.d       'fd, 'fj");
1427       break;
1428     case FSQRT_S:
1429       Format(instr, "fsqrt.s      'fd, 'fj");
1430       break;
1431     case FSQRT_D:
1432       Format(instr, "fsqrt.d      'fd, 'fj");
1433       break;
1434     case FMOV_S:
1435       Format(instr, "fmov.s       'fd, 'fj");
1436       break;
1437     case FMOV_D:
1438       Format(instr, "fmov.d       'fd, 'fj");
1439       break;
1440     case MOVGR2FR_W:
1441       Format(instr, "movgr2fr.w   'fd, 'rj");
1442       break;
1443     case MOVGR2FR_D:
1444       Format(instr, "movgr2fr.d   'fd, 'rj");
1445       break;
1446     case MOVGR2FRH_W:
1447       Format(instr, "movgr2frh.w  'fd, 'rj");
1448       break;
1449     case MOVFR2GR_S:
1450       Format(instr, "movfr2gr.s   'rd, 'fj");
1451       break;
1452     case MOVFR2GR_D:
1453       Format(instr, "movfr2gr.d   'rd, 'fj");
1454       break;
1455     case MOVFRH2GR_S:
1456       Format(instr, "movfrh2gr.s  'rd, 'fj");
1457       break;
1458     case MOVGR2FCSR:
1459       Format(instr, "movgr2fcsr   fcsr, 'rj");
1460       break;
1461     case MOVFCSR2GR:
1462       Format(instr, "movfcsr2gr   'rd, fcsr");
1463       break;
1464     case FCVT_S_D:
1465       Format(instr, "fcvt.s.d     'fd, 'fj");
1466       break;
1467     case FCVT_D_S:
1468       Format(instr, "fcvt.d.s     'fd, 'fj");
1469       break;
1470     case FTINTRM_W_S:
1471       Format(instr, "ftintrm.w.s  'fd, 'fj");
1472       break;
1473     case FTINTRM_W_D:
1474       Format(instr, "ftintrm.w.d  'fd, 'fj");
1475       break;
1476     case FTINTRM_L_S:
1477       Format(instr, "ftintrm.l.s  'fd, 'fj");
1478       break;
1479     case FTINTRM_L_D:
1480       Format(instr, "ftintrm.l.d  'fd, 'fj");
1481       break;
1482     case FTINTRP_W_S:
1483       Format(instr, "ftintrp.w.s  'fd, 'fj");
1484       break;
1485     case FTINTRP_W_D:
1486       Format(instr, "ftintrp.w.d  'fd, 'fj");
1487       break;
1488     case FTINTRP_L_S:
1489       Format(instr, "ftintrp.l.s  'fd, 'fj");
1490       break;
1491     case FTINTRP_L_D:
1492       Format(instr, "ftintrp.l.d  'fd, 'fj");
1493       break;
1494     case FTINTRZ_W_S:
1495       Format(instr, "ftintrz.w.s  'fd, 'fj");
1496       break;
1497     case FTINTRZ_W_D:
1498       Format(instr, "ftintrz.w.d  'fd, 'fj");
1499       break;
1500     case FTINTRZ_L_S:
1501       Format(instr, "ftintrz.l.s  'fd, 'fj");
1502       break;
1503     case FTINTRZ_L_D:
1504       Format(instr, "ftintrz.l.d  'fd, 'fj");
1505       break;
1506     case FTINTRNE_W_S:
1507       Format(instr, "ftintrne.w.s 'fd, 'fj");
1508       break;
1509     case FTINTRNE_W_D:
1510       Format(instr, "ftintrne.w.d 'fd, 'fj");
1511       break;
1512     case FTINTRNE_L_S:
1513       Format(instr, "ftintrne.l.s 'fd, 'fj");
1514       break;
1515     case FTINTRNE_L_D:
1516       Format(instr, "ftintrne.l.d 'fd, 'fj");
1517       break;
1518     case FTINT_W_S:
1519       Format(instr, "ftint.w.s    'fd, 'fj");
1520       break;
1521     case FTINT_W_D:
1522       Format(instr, "ftint.w.d    'fd, 'fj");
1523       break;
1524     case FTINT_L_S:
1525       Format(instr, "ftint.l.s    'fd, 'fj");
1526       break;
1527     case FTINT_L_D:
1528       Format(instr, "ftint.l.d    'fd, 'fj");
1529       break;
1530     case FFINT_S_W:
1531       Format(instr, "ffint.s.w    'fd, 'fj");
1532       break;
1533     case FFINT_S_L:
1534       Format(instr, "ffint.s.l    'fd, 'fj");
1535       break;
1536     case FFINT_D_W:
1537       Format(instr, "ffint.d.w    'fd, 'fj");
1538       break;
1539     case FFINT_D_L:
1540       Format(instr, "ffint.d.l    'fd, 'fj");
1541       break;
1542     case FRINT_S:
1543       Format(instr, "frint.s      'fd, 'fj");
1544       break;
1545     case FRINT_D:
1546       Format(instr, "frint.d      'fd, 'fj");
1547       break;
1548     case MOVFR2CF:
1549       Format(instr, "movfr2cf     fcc'cd, 'fj");
1550       break;
1551     case MOVCF2FR:
1552       Format(instr, "movcf2fr     'fd, fcc'cj");
1553       break;
1554     case MOVGR2CF:
1555       Format(instr, "movgr2cf     fcc'cd, 'rj");
1556       break;
1557     case MOVCF2GR:
1558       Format(instr, "movcf2gr     'rd, fcc'cj");
1559       break;
1560     case FRECIP_S:
1561       Format(instr, "frecip.s     'fd, 'fj");
1562       break;
1563     case FRECIP_D:
1564       Format(instr, "frecip.d     'fd, 'fj");
1565       break;
1566     case FRSQRT_S:
1567       Format(instr, "frsqrt.s     'fd, 'fj");
1568       break;
1569     case FRSQRT_D:
1570       Format(instr, "frsqrt.d     'fd, 'fj");
1571       break;
1572     case FCLASS_S:
1573       Format(instr, "fclass.s     'fd, 'fj");
1574       break;
1575     case FCLASS_D:
1576       Format(instr, "fclass.d     'fd, 'fj");
1577       break;
1578     case FLOGB_S:
1579       Format(instr, "flogb.s      'fd, 'fj");
1580       break;
1581     case FLOGB_D:
1582       Format(instr, "flogb.d      'fd, 'fj");
1583       break;
1584     case CLO_W:
1585       Format(instr, "clo.w        'rd, 'rj");
1586       break;
1587     case CTO_W:
1588       Format(instr, "cto.w        'rd, 'rj");
1589       break;
1590     case CLO_D:
1591       Format(instr, "clo.d        'rd, 'rj");
1592       break;
1593     case CTO_D:
1594       Format(instr, "cto.d        'rd, 'rj");
1595       break;
1596     default:
1597       UNREACHABLE();
1598   }
1599 }
1600 
InstructionDecode(byte* instr_ptr)1601 int Decoder::InstructionDecode(byte* instr_ptr) {
1602   Instruction* instr = Instruction::At(instr_ptr);
1603   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_,
1604                                     "%08x       ", instr->InstructionBits());
1605   switch (instr->InstructionType()) {
1606     case Instruction::kOp6Type: {
1607       DecodeTypekOp6(instr);
1608       break;
1609     }
1610     case Instruction::kOp7Type: {
1611       DecodeTypekOp7(instr);
1612       break;
1613     }
1614     case Instruction::kOp8Type: {
1615       DecodeTypekOp8(instr);
1616       break;
1617     }
1618     case Instruction::kOp10Type: {
1619       DecodeTypekOp10(instr);
1620       break;
1621     }
1622     case Instruction::kOp12Type: {
1623       DecodeTypekOp12(instr);
1624       break;
1625     }
1626     case Instruction::kOp14Type: {
1627       DecodeTypekOp14(instr);
1628       break;
1629     }
1630     case Instruction::kOp17Type: {
1631       return DecodeTypekOp17(instr);
1632     }
1633     case Instruction::kOp22Type: {
1634       DecodeTypekOp22(instr);
1635       break;
1636     }
1637     case Instruction::kUnsupported: {
1638       Format(instr, "UNSUPPORTED");
1639       break;
1640     }
1641     default: {
1642       Format(instr, "UNSUPPORTED");
1643       break;
1644     }
1645   }
1646   return kInstrSize;
1647 }
1648 
1649 }  // namespace internal
1650 }  // namespace v8
1651 
1652 //------------------------------------------------------------------------------
1653 
1654 namespace disasm {
1655 
NameOfAddress(byte* addr) const1656 const char* NameConverter::NameOfAddress(byte* addr) const {
1657   v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1658   return tmp_buffer_.begin();
1659 }
1660 
NameOfConstant(byte* addr) const1661 const char* NameConverter::NameOfConstant(byte* addr) const {
1662   return NameOfAddress(addr);
1663 }
1664 
NameOfCPURegister(int reg) const1665 const char* NameConverter::NameOfCPURegister(int reg) const {
1666   return v8::internal::Registers::Name(reg);
1667 }
1668 
NameOfXMMRegister(int reg) const1669 const char* NameConverter::NameOfXMMRegister(int reg) const {
1670   return v8::internal::FPURegisters::Name(reg);
1671 }
1672 
NameOfByteCPURegister(int reg) const1673 const char* NameConverter::NameOfByteCPURegister(int reg) const {
1674   UNREACHABLE();
1675 }
1676 
NameInCode(byte* addr) const1677 const char* NameConverter::NameInCode(byte* addr) const {
1678   // The default name converter is called for unknown code. So we will not try
1679   // to access any memory.
1680   return "";
1681 }
1682 
1683 //------------------------------------------------------------------------------
1684 
InstructionDecode(v8::base::Vector<char> buffer, byte* instruction)1685 int Disassembler::InstructionDecode(v8::base::Vector<char> buffer,
1686                                     byte* instruction) {
1687   v8::internal::Decoder d(converter_, buffer);
1688   return d.InstructionDecode(instruction);
1689 }
1690 
ConstantPoolSizeAt(byte* instruction)1691 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1692 
Disassemble(FILE* f, byte* begin, byte* end, UnimplementedOpcodeAction unimplemented_action)1693 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
1694                                UnimplementedOpcodeAction unimplemented_action) {
1695   NameConverter converter;
1696   Disassembler d(converter, unimplemented_action);
1697   for (byte* pc = begin; pc < end;) {
1698     v8::base::EmbeddedVector<char, 128> buffer;
1699     buffer[0] = '\0';
1700     byte* prev_pc = pc;
1701     pc += d.InstructionDecode(buffer, pc);
1702     v8::internal::PrintF(f, "%p    %08x      %s\n", static_cast<void*>(prev_pc),
1703                          *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
1704   }
1705 }
1706 
1707 #undef STRING_STARTS_WITH
1708 
1709 }  // namespace disasm
1710 
1711 #endif  // V8_TARGET_ARCH_LOONG64
1712