• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // A Disassembler object is used to disassemble a block of code instruction by
6 // instruction. The default implementation of the NameConverter object can be
7 // overriden to modify register names or to do symbol lookup on addresses.
8 //
9 // The example below will disassemble a block of code and print it to stdout.
10 //
11 //   NameConverter converter;
12 //   Disassembler d(converter);
13 //   for (byte* pc = begin; pc < end;) {
14 //     v8::base::EmbeddedVector<char, 256> buffer;
15 //     byte* prev_pc = pc;
16 //     pc += d.InstructionDecode(buffer, pc);
17 //     printf("%p    %08x      %s\n",
18 //            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
19 //   }
20 //
21 // The Disassembler class also has a convenience method to disassemble a block
22 // of code into a FILE*, meaning that the above functionality could also be
23 // achieved by just calling Disassembler::Disassemble(stdout, begin, end);
24 
25 #include <assert.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 #if V8_TARGET_ARCH_RISCV64
31 
32 #include "src/base/platform/platform.h"
33 #include "src/base/strings.h"
34 #include "src/base/vector.h"
35 #include "src/codegen/macro-assembler.h"
36 #include "src/codegen/riscv64/constants-riscv64.h"
37 #include "src/diagnostics/disasm.h"
38 
39 namespace v8 {
40 namespace internal {
41 
42 //------------------------------------------------------------------------------
43 
44 // Decoder decodes and disassembles instructions into an output buffer.
45 // It uses the converter to convert register names and call destinations into
46 // more informative description.
47 class Decoder {
48  public:
Decoder(const disasm::NameConverter & converter,v8::base::Vector<char> out_buffer)49   Decoder(const disasm::NameConverter& converter,
50           v8::base::Vector<char> out_buffer)
51       : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
52     out_buffer_[out_buffer_pos_] = '\0';
53   }
54 
~Decoder()55   ~Decoder() {}
56   Decoder(const Decoder&) = delete;
57   Decoder& operator=(const Decoder&) = delete;
58 
59   // Writes one disassembled instruction into 'buffer' (0-terminated).
60   // Returns the length of the disassembled machine instruction in bytes.
61   int InstructionDecode(byte* instruction);
62 
63  private:
64   // Bottleneck functions to print into the out_buffer.
65   void PrintChar(const char ch);
66   void Print(const char* str);
67 
68   // Printing of common values.
69   void PrintRegister(int reg);
70   void PrintFPURegister(int freg);
71   void PrintVRegister(int reg);
72   void PrintFPUStatusRegister(int freg);
73   void PrintRs1(Instruction* instr);
74   void PrintRs2(Instruction* instr);
75   void PrintRd(Instruction* instr);
76   void PrintUimm(Instruction* instr);
77   void PrintVs1(Instruction* instr);
78   void PrintVs2(Instruction* instr);
79   void PrintVd(Instruction* instr);
80   void PrintFRs1(Instruction* instr);
81   void PrintFRs2(Instruction* instr);
82   void PrintFRs3(Instruction* instr);
83   void PrintFRd(Instruction* instr);
84   void PrintImm12(Instruction* instr);
85   void PrintImm12X(Instruction* instr);
86   void PrintImm20U(Instruction* instr);
87   void PrintImm20J(Instruction* instr);
88   void PrintShamt(Instruction* instr);
89   void PrintShamt32(Instruction* instr);
90   void PrintRvcImm6(Instruction* instr);
91   void PrintRvcImm6U(Instruction* instr);
92   void PrintRvcImm6Addi16sp(Instruction* instr);
93   void PrintRvcShamt(Instruction* instr);
94   void PrintRvcImm6Ldsp(Instruction* instr);
95   void PrintRvcImm6Lwsp(Instruction* instr);
96   void PrintRvcImm6Sdsp(Instruction* instr);
97   void PrintRvcImm6Swsp(Instruction* instr);
98   void PrintRvcImm5W(Instruction* instr);
99   void PrintRvcImm5D(Instruction* instr);
100   void PrintRvcImm8Addi4spn(Instruction* instr);
101   void PrintRvcImm11CJ(Instruction* instr);
102   void PrintRvcImm8B(Instruction* instr);
103   void PrintRvvVm(Instruction* instr);
104   void PrintAcquireRelease(Instruction* instr);
105   void PrintBranchOffset(Instruction* instr);
106   void PrintStoreOffset(Instruction* instr);
107   void PrintCSRReg(Instruction* instr);
108   void PrintRvvSEW(Instruction* instr);
109   void PrintRvvLMUL(Instruction* instr);
110   void PrintRvvSimm5(Instruction* instr);
111   void PrintRvvUimm5(Instruction* instr);
112   void PrintRoundingMode(Instruction* instr);
113   void PrintMemoryOrder(Instruction* instr, bool is_pred);
114 
115   // Each of these functions decodes one particular instruction type.
116   void DecodeRType(Instruction* instr);
117   void DecodeR4Type(Instruction* instr);
118   void DecodeRAType(Instruction* instr);
119   void DecodeRFPType(Instruction* instr);
120   void DecodeIType(Instruction* instr);
121   void DecodeSType(Instruction* instr);
122   void DecodeBType(Instruction* instr);
123   void DecodeUType(Instruction* instr);
124   void DecodeJType(Instruction* instr);
125   void DecodeCRType(Instruction* instr);
126   void DecodeCAType(Instruction* instr);
127   void DecodeCIType(Instruction* instr);
128   void DecodeCIWType(Instruction* instr);
129   void DecodeCSSType(Instruction* instr);
130   void DecodeCLType(Instruction* instr);
131   void DecodeCSType(Instruction* instr);
132   void DecodeCJType(Instruction* instr);
133   void DecodeCBType(Instruction* instr);
134 
135   void DecodeVType(Instruction* instr);
136   void DecodeRvvIVV(Instruction* instr);
137   void DecodeRvvFVV(Instruction* instr);
138   void DecodeRvvFVF(Instruction* instr);
139   void DecodeRvvIVI(Instruction* instr);
140   void DecodeRvvIVX(Instruction* instr);
141   void DecodeRvvVL(Instruction* instr);
142   void DecodeRvvVS(Instruction* instr);
143   void DecodeRvvMVV(Instruction* instr);
144   void DecodeRvvMVX(Instruction* instr);
145   // Printing of instruction name.
146   void PrintInstructionName(Instruction* instr);
147 
148   void PrintTarget(Instruction* instr);
149 
150   // Handle formatting of instructions and their options.
151   int FormatRegister(Instruction* instr, const char* option);
152   int FormatFPURegisterOrRoundMode(Instruction* instr, const char* option);
153   int FormatRvcRegister(Instruction* instr, const char* option);
154   int FormatRvcImm(Instruction* instr, const char* option);
155   int FormatOption(Instruction* instr, const char* option);
156   void Format(Instruction* instr, const char* format);
157   void Unknown(Instruction* instr);
158 
159   int switch_sew(Instruction* instr);
160   int switch_nf(Instruction* instr);
161   const disasm::NameConverter& converter_;
162   v8::base::Vector<char> out_buffer_;
163   int out_buffer_pos_;
164 };
165 
166 // Support for assertions in the Decoder formatting functions.
167 #define STRING_STARTS_WITH(string, compare_string) \
168   (strncmp(string, compare_string, strlen(compare_string)) == 0)
169 
170 // Append the ch to the output buffer.
PrintChar(const char ch)171 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
172 
173 // Append the str to the output buffer.
Print(const char * str)174 void Decoder::Print(const char* str) {
175   char cur = *str++;
176   while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
177     PrintChar(cur);
178     cur = *str++;
179   }
180   out_buffer_[out_buffer_pos_] = 0;
181 }
182 
183 // Print the register name according to the active name converter.
PrintRegister(int reg)184 void Decoder::PrintRegister(int reg) {
185   Print(converter_.NameOfCPURegister(reg));
186 }
187 
PrintVRegister(int reg)188 void Decoder::PrintVRegister(int reg) {
189   Print(v8::internal::VRegisters::Name(reg));
190 }
191 
PrintRs1(Instruction * instr)192 void Decoder::PrintRs1(Instruction* instr) {
193   int reg = instr->Rs1Value();
194   PrintRegister(reg);
195 }
196 
PrintRs2(Instruction * instr)197 void Decoder::PrintRs2(Instruction* instr) {
198   int reg = instr->Rs2Value();
199   PrintRegister(reg);
200 }
201 
PrintRd(Instruction * instr)202 void Decoder::PrintRd(Instruction* instr) {
203   int reg = instr->RdValue();
204   PrintRegister(reg);
205 }
206 
PrintUimm(Instruction * instr)207 void Decoder::PrintUimm(Instruction* instr) {
208   int val = instr->Rs1Value();
209   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", val);
210 }
211 
PrintVs1(Instruction * instr)212 void Decoder::PrintVs1(Instruction* instr) {
213   int reg = instr->Vs1Value();
214   PrintVRegister(reg);
215 }
216 
PrintVs2(Instruction * instr)217 void Decoder::PrintVs2(Instruction* instr) {
218   int reg = instr->Vs2Value();
219   PrintVRegister(reg);
220 }
221 
PrintVd(Instruction * instr)222 void Decoder::PrintVd(Instruction* instr) {
223   int reg = instr->VdValue();
224   PrintVRegister(reg);
225 }
226 
227 // Print the FPUregister name according to the active name converter.
PrintFPURegister(int freg)228 void Decoder::PrintFPURegister(int freg) {
229   Print(converter_.NameOfXMMRegister(freg));
230 }
231 
PrintFRs1(Instruction * instr)232 void Decoder::PrintFRs1(Instruction* instr) {
233   int reg = instr->Rs1Value();
234   PrintFPURegister(reg);
235 }
236 
PrintFRs2(Instruction * instr)237 void Decoder::PrintFRs2(Instruction* instr) {
238   int reg = instr->Rs2Value();
239   PrintFPURegister(reg);
240 }
241 
PrintFRs3(Instruction * instr)242 void Decoder::PrintFRs3(Instruction* instr) {
243   int reg = instr->Rs3Value();
244   PrintFPURegister(reg);
245 }
246 
PrintFRd(Instruction * instr)247 void Decoder::PrintFRd(Instruction* instr) {
248   int reg = instr->RdValue();
249   PrintFPURegister(reg);
250 }
251 
PrintImm12X(Instruction * instr)252 void Decoder::PrintImm12X(Instruction* instr) {
253   int32_t imm = instr->Imm12Value();
254   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
255 }
256 
PrintImm12(Instruction * instr)257 void Decoder::PrintImm12(Instruction* instr) {
258   int32_t imm = instr->Imm12Value();
259   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
260 }
261 
PrintTarget(Instruction * instr)262 void Decoder::PrintTarget(Instruction* instr) {
263   if (Assembler::IsJalr(instr->InstructionBits())) {
264     if (Assembler::IsAuipc((instr - 4)->InstructionBits()) &&
265         (instr - 4)->RdValue() == instr->Rs1Value()) {
266       int32_t imm = Assembler::BrachlongOffset((instr - 4)->InstructionBits(),
267                                                instr->InstructionBits());
268       const char* target =
269           converter_.NameOfAddress(reinterpret_cast<byte*>(instr - 4) + imm);
270       out_buffer_pos_ +=
271           base::SNPrintF(out_buffer_ + out_buffer_pos_, " -> %s", target);
272       return;
273     }
274   }
275 }
276 
PrintBranchOffset(Instruction * instr)277 void Decoder::PrintBranchOffset(Instruction* instr) {
278   int32_t imm = instr->BranchOffset();
279   const char* target =
280       converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + imm);
281   out_buffer_pos_ +=
282       base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d -> %s", imm, target);
283 }
284 
PrintStoreOffset(Instruction * instr)285 void Decoder::PrintStoreOffset(Instruction* instr) {
286   int32_t imm = instr->StoreOffset();
287   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
288 }
289 
PrintRvvSEW(Instruction * instr)290 void Decoder::PrintRvvSEW(Instruction* instr) {
291   const char* sew = instr->RvvSEW();
292   out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", sew);
293 }
294 
PrintRvvLMUL(Instruction * instr)295 void Decoder::PrintRvvLMUL(Instruction* instr) {
296   const char* lmul = instr->RvvLMUL();
297   out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", lmul);
298 }
299 
PrintRvvSimm5(Instruction * instr)300 void Decoder::PrintRvvSimm5(Instruction* instr) {
301   const int simm5 = instr->RvvSimm5();
302   out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", simm5);
303 }
304 
PrintRvvUimm5(Instruction * instr)305 void Decoder::PrintRvvUimm5(Instruction* instr) {
306   const uint32_t uimm5 = instr->RvvUimm5();
307   out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", uimm5);
308 }
309 
PrintImm20U(Instruction * instr)310 void Decoder::PrintImm20U(Instruction* instr) {
311   int32_t imm = instr->Imm20UValue();
312   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
313 }
314 
PrintImm20J(Instruction * instr)315 void Decoder::PrintImm20J(Instruction* instr) {
316   int32_t imm = instr->Imm20JValue();
317   const char* target =
318       converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + imm);
319   out_buffer_pos_ +=
320       base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d -> %s", imm, target);
321 }
322 
PrintShamt(Instruction * instr)323 void Decoder::PrintShamt(Instruction* instr) {
324   int32_t imm = instr->Shamt();
325   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
326 }
327 
PrintShamt32(Instruction * instr)328 void Decoder::PrintShamt32(Instruction* instr) {
329   int32_t imm = instr->Shamt32();
330   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
331 }
332 
PrintRvcImm6(Instruction * instr)333 void Decoder::PrintRvcImm6(Instruction* instr) {
334   int32_t imm = instr->RvcImm6Value();
335   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
336 }
337 
PrintRvcImm6U(Instruction * instr)338 void Decoder::PrintRvcImm6U(Instruction* instr) {
339   int32_t imm = instr->RvcImm6Value() & 0xFFFFF;
340   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
341 }
342 
PrintRvcImm6Addi16sp(Instruction * instr)343 void Decoder::PrintRvcImm6Addi16sp(Instruction* instr) {
344   int32_t imm = instr->RvcImm6Addi16spValue();
345   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
346 }
347 
PrintRvcShamt(Instruction * instr)348 void Decoder::PrintRvcShamt(Instruction* instr) {
349   int32_t imm = instr->RvcShamt6();
350   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
351 }
352 
PrintRvcImm6Ldsp(Instruction * instr)353 void Decoder::PrintRvcImm6Ldsp(Instruction* instr) {
354   int32_t imm = instr->RvcImm6LdspValue();
355   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
356 }
357 
PrintRvcImm6Lwsp(Instruction * instr)358 void Decoder::PrintRvcImm6Lwsp(Instruction* instr) {
359   int32_t imm = instr->RvcImm6LwspValue();
360   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
361 }
362 
PrintRvcImm6Swsp(Instruction * instr)363 void Decoder::PrintRvcImm6Swsp(Instruction* instr) {
364   int32_t imm = instr->RvcImm6SwspValue();
365   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
366 }
367 
PrintRvcImm6Sdsp(Instruction * instr)368 void Decoder::PrintRvcImm6Sdsp(Instruction* instr) {
369   int32_t imm = instr->RvcImm6SdspValue();
370   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
371 }
372 
PrintRvcImm5W(Instruction * instr)373 void Decoder::PrintRvcImm5W(Instruction* instr) {
374   int32_t imm = instr->RvcImm5WValue();
375   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
376 }
377 
PrintRvcImm5D(Instruction * instr)378 void Decoder::PrintRvcImm5D(Instruction* instr) {
379   int32_t imm = instr->RvcImm5DValue();
380   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
381 }
382 
PrintRvcImm8Addi4spn(Instruction * instr)383 void Decoder::PrintRvcImm8Addi4spn(Instruction* instr) {
384   int32_t imm = instr->RvcImm8Addi4spnValue();
385   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
386 }
387 
PrintRvcImm11CJ(Instruction * instr)388 void Decoder::PrintRvcImm11CJ(Instruction* instr) {
389   int32_t imm = instr->RvcImm11CJValue();
390   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
391 }
392 
PrintRvcImm8B(Instruction * instr)393 void Decoder::PrintRvcImm8B(Instruction* instr) {
394   int32_t imm = instr->RvcImm8BValue();
395   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
396 }
397 
PrintRvvVm(Instruction * instr)398 void Decoder::PrintRvvVm(Instruction* instr) {
399   uint8_t imm = instr->RvvVM();
400   if (imm == 0) {
401     out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "  v0.t");
402   }
403 }
404 
PrintAcquireRelease(Instruction * instr)405 void Decoder::PrintAcquireRelease(Instruction* instr) {
406   bool aq = instr->AqValue();
407   bool rl = instr->RlValue();
408   if (aq || rl) {
409     out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, ".");
410   }
411   if (aq) {
412     out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "aq");
413   }
414   if (rl) {
415     out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "rl");
416   }
417 }
418 
PrintCSRReg(Instruction * instr)419 void Decoder::PrintCSRReg(Instruction* instr) {
420   int32_t csr_reg = instr->CsrValue();
421   std::string s;
422   switch (csr_reg) {
423     case csr_fflags:  // Floating-Point Accrued Exceptions (RW)
424       s = "csr_fflags";
425       break;
426     case csr_frm:  // Floating-Point Dynamic Rounding Mode (RW)
427       s = "csr_frm";
428       break;
429     case csr_fcsr:  // Floating-Point Control and Status Register (RW)
430       s = "csr_fcsr";
431       break;
432     case csr_cycle:
433       s = "csr_cycle";
434       break;
435     case csr_time:
436       s = "csr_time";
437       break;
438     case csr_instret:
439       s = "csr_instret";
440       break;
441     case csr_cycleh:
442       s = "csr_cycleh";
443       break;
444     case csr_timeh:
445       s = "csr_timeh";
446       break;
447     case csr_instreth:
448       s = "csr_instreth";
449       break;
450     default:
451       UNREACHABLE();
452   }
453   out_buffer_pos_ +=
454       base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s.c_str());
455 }
456 
PrintRoundingMode(Instruction * instr)457 void Decoder::PrintRoundingMode(Instruction* instr) {
458   int frm = instr->RoundMode();
459   std::string s;
460   switch (frm) {
461     case RNE:
462       s = "RNE";
463       break;
464     case RTZ:
465       s = "RTZ";
466       break;
467     case RDN:
468       s = "RDN";
469       break;
470     case RUP:
471       s = "RUP";
472       break;
473     case RMM:
474       s = "RMM";
475       break;
476     case DYN:
477       s = "DYN";
478       break;
479     default:
480       UNREACHABLE();
481   }
482   out_buffer_pos_ +=
483       base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s.c_str());
484 }
485 
PrintMemoryOrder(Instruction * instr,bool is_pred)486 void Decoder::PrintMemoryOrder(Instruction* instr, bool is_pred) {
487   int memOrder = instr->MemoryOrder(is_pred);
488   std::string s;
489   if ((memOrder & PSI) == PSI) {
490     s += "i";
491   }
492   if ((memOrder & PSO) == PSO) {
493     s += "o";
494   }
495   if ((memOrder & PSR) == PSR) {
496     s += "r";
497   }
498   if ((memOrder & PSW) == PSW) {
499     s += "w";
500   }
501   out_buffer_pos_ +=
502       base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s.c_str());
503 }
504 
505 // Printing of instruction name.
PrintInstructionName(Instruction * instr)506 void Decoder::PrintInstructionName(Instruction* instr) {}
507 
508 // Handle all register based formatting in this function to reduce the
509 // complexity of FormatOption.
FormatRegister(Instruction * instr,const char * format)510 int Decoder::FormatRegister(Instruction* instr, const char* format) {
511   DCHECK_EQ(format[0], 'r');
512   if (format[1] == 's') {  // 'rs[12]: Rs register.
513     if (format[2] == '1') {
514       int reg = instr->Rs1Value();
515       PrintRegister(reg);
516       return 3;
517     } else if (format[2] == '2') {
518       int reg = instr->Rs2Value();
519       PrintRegister(reg);
520       return 3;
521     }
522     UNREACHABLE();
523   } else if (format[1] == 'd') {  // 'rd: rd register.
524     int reg = instr->RdValue();
525     PrintRegister(reg);
526     return 2;
527   }
528   UNREACHABLE();
529 }
530 
531 // Handle all FPUregister based formatting in this function to reduce the
532 // complexity of FormatOption.
FormatFPURegisterOrRoundMode(Instruction * instr,const char * format)533 int Decoder::FormatFPURegisterOrRoundMode(Instruction* instr,
534                                           const char* format) {
535   DCHECK_EQ(format[0], 'f');
536   if (format[1] == 's') {  // 'fs[1-3]: Rs register.
537     if (format[2] == '1') {
538       int reg = instr->Rs1Value();
539       PrintFPURegister(reg);
540       return 3;
541     } else if (format[2] == '2') {
542       int reg = instr->Rs2Value();
543       PrintFPURegister(reg);
544       return 3;
545     } else if (format[2] == '3') {
546       int reg = instr->Rs3Value();
547       PrintFPURegister(reg);
548       return 3;
549     }
550     UNREACHABLE();
551   } else if (format[1] == 'd') {  // 'fd: fd register.
552     int reg = instr->RdValue();
553     PrintFPURegister(reg);
554     return 2;
555   } else if (format[1] == 'r') {  // 'frm
556     DCHECK(STRING_STARTS_WITH(format, "frm"));
557     PrintRoundingMode(instr);
558     return 3;
559   }
560   UNREACHABLE();
561 }
562 
563 // Handle all C extension register based formatting in this function to reduce
564 // the complexity of FormatOption.
FormatRvcRegister(Instruction * instr,const char * format)565 int Decoder::FormatRvcRegister(Instruction* instr, const char* format) {
566   DCHECK_EQ(format[0], 'C');
567   DCHECK(format[1] == 'r' || format[1] == 'f');
568   if (format[2] == 's') {  // 'Crs[12]: Rs register.
569     if (format[3] == '1') {
570       if (format[4] == 's') {  // 'Crs1s: 3-bits register
571         int reg = instr->RvcRs1sValue();
572         if (format[1] == 'r') {
573           PrintRegister(reg);
574         } else if (format[1] == 'f') {
575           PrintFPURegister(reg);
576         }
577         return 5;
578       }
579       int reg = instr->RvcRs1Value();
580       if (format[1] == 'r') {
581         PrintRegister(reg);
582       } else if (format[1] == 'f') {
583         PrintFPURegister(reg);
584       }
585       return 4;
586     } else if (format[3] == '2') {
587       if (format[4] == 's') {  // 'Crs2s: 3-bits register
588         int reg = instr->RvcRs2sValue();
589         if (format[1] == 'r') {
590           PrintRegister(reg);
591         } else if (format[1] == 'f') {
592           PrintFPURegister(reg);
593         }
594         return 5;
595       }
596       int reg = instr->RvcRs2Value();
597       if (format[1] == 'r') {
598         PrintRegister(reg);
599       } else if (format[1] == 'f') {
600         PrintFPURegister(reg);
601       }
602       return 4;
603     }
604     UNREACHABLE();
605   } else if (format[2] == 'd') {  // 'Crd: rd register.
606     int reg = instr->RvcRdValue();
607     if (format[1] == 'r') {
608       PrintRegister(reg);
609     } else if (format[1] == 'f') {
610       PrintFPURegister(reg);
611     }
612     return 3;
613   }
614   UNREACHABLE();
615 }
616 
617 // Handle all C extension immediates based formatting in this function to reduce
618 // the complexity of FormatOption.
FormatRvcImm(Instruction * instr,const char * format)619 int Decoder::FormatRvcImm(Instruction* instr, const char* format) {
620   // TODO(riscv): add other rvc imm format
621   DCHECK(STRING_STARTS_WITH(format, "Cimm"));
622   if (format[4] == '6') {
623     if (format[5] == 'U') {
624       DCHECK(STRING_STARTS_WITH(format, "Cimm6U"));
625       PrintRvcImm6U(instr);
626       return 6;
627     } else if (format[5] == 'A') {
628       if (format[9] == '1' && format[10] == '6') {
629         DCHECK(STRING_STARTS_WITH(format, "Cimm6Addi16sp"));
630         PrintRvcImm6Addi16sp(instr);
631         return 13;
632       }
633       UNREACHABLE();
634     } else if (format[5] == 'L') {
635       if (format[6] == 'd') {
636         if (format[7] == 's') {
637           DCHECK(STRING_STARTS_WITH(format, "Cimm6Ldsp"));
638           PrintRvcImm6Ldsp(instr);
639           return 9;
640         }
641       } else if (format[6] == 'w') {
642         if (format[7] == 's') {
643           DCHECK(STRING_STARTS_WITH(format, "Cimm6Lwsp"));
644           PrintRvcImm6Lwsp(instr);
645           return 9;
646         }
647       }
648       UNREACHABLE();
649     } else if (format[5] == 'S') {
650       if (format[6] == 'w') {
651         DCHECK(STRING_STARTS_WITH(format, "Cimm6Swsp"));
652         PrintRvcImm6Swsp(instr);
653         return 9;
654       } else if (format[6] == 'd') {
655         DCHECK(STRING_STARTS_WITH(format, "Cimm6Sdsp"));
656         PrintRvcImm6Sdsp(instr);
657         return 9;
658       }
659       UNREACHABLE();
660     }
661     PrintRvcImm6(instr);
662     return 5;
663   } else if (format[4] == '5') {
664     DCHECK(STRING_STARTS_WITH(format, "Cimm5"));
665     if (format[5] == 'W') {
666       DCHECK(STRING_STARTS_WITH(format, "Cimm5W"));
667       PrintRvcImm5W(instr);
668       return 6;
669     } else if (format[5] == 'D') {
670       DCHECK(STRING_STARTS_WITH(format, "Cimm5D"));
671       PrintRvcImm5D(instr);
672       return 6;
673     }
674     UNREACHABLE();
675   } else if (format[4] == '8') {
676     DCHECK(STRING_STARTS_WITH(format, "Cimm8"));
677     if (format[5] == 'A') {
678       DCHECK(STRING_STARTS_WITH(format, "Cimm8Addi4spn"));
679       PrintRvcImm8Addi4spn(instr);
680       return 13;
681     } else if (format[5] == 'B') {
682       DCHECK(STRING_STARTS_WITH(format, "Cimm8B"));
683       PrintRvcImm8B(instr);
684       return 6;
685     }
686     UNREACHABLE();
687   } else if (format[4] == '1') {
688     DCHECK(STRING_STARTS_WITH(format, "Cimm1"));
689     if (format[5] == '1') {
690       DCHECK(STRING_STARTS_WITH(format, "Cimm11CJ"));
691       PrintRvcImm11CJ(instr);
692       return 8;
693     }
694     UNREACHABLE();
695   }
696   UNREACHABLE();
697 }
698 
699 // FormatOption takes a formatting string and interprets it based on
700 // the current instructions. The format string points to the first
701 // character of the option string (the option escape has already been
702 // consumed by the caller.)  FormatOption returns the number of
703 // characters that were consumed from the formatting string.
FormatOption(Instruction * instr,const char * format)704 int Decoder::FormatOption(Instruction* instr, const char* format) {
705   switch (format[0]) {
706     case 'C': {  // `C extension
707       if (format[1] == 'r' || format[1] == 'f') {
708         return FormatRvcRegister(instr, format);
709       } else if (format[1] == 'i') {
710         return FormatRvcImm(instr, format);
711       } else if (format[1] == 's') {
712         DCHECK(STRING_STARTS_WITH(format, "Cshamt"));
713         PrintRvcShamt(instr);
714         return 6;
715       }
716       UNREACHABLE();
717     }
718     case 'c': {  // `csr: CSR registers
719       if (format[1] == 's') {
720         if (format[2] == 'r') {
721           PrintCSRReg(instr);
722           return 3;
723         }
724       }
725       UNREACHABLE();
726     }
727     case 'i': {  // 'imm12, 'imm12x, 'imm20U, or 'imm20J: Immediates.
728       if (format[3] == '1') {
729         if (format[4] == '2') {
730           DCHECK(STRING_STARTS_WITH(format, "imm12"));
731           if (format[5] == 'x') {
732             PrintImm12X(instr);
733             return 6;
734           }
735           PrintImm12(instr);
736           return 5;
737         }
738       } else if (format[3] == '2' && format[4] == '0') {
739         DCHECK(STRING_STARTS_WITH(format, "imm20"));
740         switch (format[5]) {
741           case 'U':
742             DCHECK(STRING_STARTS_WITH(format, "imm20U"));
743             PrintImm20U(instr);
744             break;
745           case 'J':
746             DCHECK(STRING_STARTS_WITH(format, "imm20J"));
747             PrintImm20J(instr);
748             break;
749         }
750         return 6;
751       }
752       UNREACHABLE();
753     }
754     case 'o': {  // 'offB or 'offS: Offsets.
755       if (format[3] == 'B') {
756         DCHECK(STRING_STARTS_WITH(format, "offB"));
757         PrintBranchOffset(instr);
758         return 4;
759       } else if (format[3] == 'S') {
760         DCHECK(STRING_STARTS_WITH(format, "offS"));
761         PrintStoreOffset(instr);
762         return 4;
763       }
764       UNREACHABLE();
765     }
766     case 'r': {  // 'r: registers.
767       return FormatRegister(instr, format);
768     }
769     case 'f': {  // 'f: FPUregisters or `frm
770       return FormatFPURegisterOrRoundMode(instr, format);
771     }
772     case 'a': {  // 'a: Atomic acquire and release.
773       PrintAcquireRelease(instr);
774       return 1;
775     }
776     case 'p': {  // `pre
777       DCHECK(STRING_STARTS_WITH(format, "pre"));
778       PrintMemoryOrder(instr, true);
779       return 3;
780     }
781     case 's': {  // 's32 or 's64: Shift amount.
782       if (format[1] == '3') {
783         DCHECK(STRING_STARTS_WITH(format, "s32"));
784         PrintShamt32(instr);
785         return 3;
786       } else if (format[1] == '6') {
787         DCHECK(STRING_STARTS_WITH(format, "s64"));
788         PrintShamt(instr);
789         return 3;
790       } else if (format[1] == 'u') {
791         DCHECK(STRING_STARTS_WITH(format, "suc"));
792         PrintMemoryOrder(instr, false);
793         return 3;
794       } else if (format[1] == 'e') {
795         DCHECK(STRING_STARTS_WITH(format, "sew"));
796         PrintRvvSEW(instr);
797         return 3;
798       } else if (format[1] == 'i') {
799         DCHECK(STRING_STARTS_WITH(format, "simm5"));
800         PrintRvvSimm5(instr);
801         return 5;
802       }
803       UNREACHABLE();
804     }
805     case 'v': {
806       if (format[1] == 'd') {
807         DCHECK(STRING_STARTS_WITH(format, "vd"));
808         PrintVd(instr);
809         return 2;
810       } else if (format[2] == '1') {
811         DCHECK(STRING_STARTS_WITH(format, "vs1"));
812         PrintVs1(instr);
813         return 3;
814       } else if (format[2] == '2') {
815         DCHECK(STRING_STARTS_WITH(format, "vs2"));
816         PrintVs2(instr);
817         return 3;
818       } else {
819         DCHECK(STRING_STARTS_WITH(format, "vm"));
820         PrintRvvVm(instr);
821         return 2;
822       }
823     }
824     case 'l': {
825       DCHECK(STRING_STARTS_WITH(format, "lmul"));
826       PrintRvvLMUL(instr);
827       return 4;
828     }
829     case 'u': {
830       if (STRING_STARTS_WITH(format, "uimm5")) {
831         PrintRvvUimm5(instr);
832         return 5;
833       } else {
834         DCHECK(STRING_STARTS_WITH(format, "uimm"));
835         PrintUimm(instr);
836         return 4;
837       }
838     }
839     case 't': {  // 'target: target of branch instructions'
840       DCHECK(STRING_STARTS_WITH(format, "target"));
841       PrintTarget(instr);
842       return 6;
843     }
844   }
845   UNREACHABLE();
846 }
847 
848 // Format takes a formatting string for a whole instruction and prints it into
849 // the output buffer. All escaped options are handed to FormatOption to be
850 // parsed further.
Format(Instruction * instr,const char * format)851 void Decoder::Format(Instruction* instr, const char* format) {
852   char cur = *format++;
853   while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
854     if (cur == '\'') {  // Single quote is used as the formatting escape.
855       format += FormatOption(instr, format);
856     } else {
857       out_buffer_[out_buffer_pos_++] = cur;
858     }
859     cur = *format++;
860   }
861   out_buffer_[out_buffer_pos_] = '\0';
862 }
863 
864 // For currently unimplemented decodings the disassembler calls Unknown(instr)
865 // which will just print "unknown" of the instruction bits.
Unknown(Instruction * instr)866 void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
867 
868 // RISCV Instruction Decode Routine
DecodeRType(Instruction * instr)869 void Decoder::DecodeRType(Instruction* instr) {
870   switch (instr->InstructionBits() & kRTypeMask) {
871     case RO_ADD:
872       Format(instr, "add       'rd, 'rs1, 'rs2");
873       break;
874     case RO_SUB:
875       if (instr->Rs1Value() == zero_reg.code())
876         Format(instr, "neg       'rd, 'rs2");
877       else
878         Format(instr, "sub       'rd, 'rs1, 'rs2");
879       break;
880     case RO_SLL:
881       Format(instr, "sll       'rd, 'rs1, 'rs2");
882       break;
883     case RO_SLT:
884       if (instr->Rs2Value() == zero_reg.code())
885         Format(instr, "sltz      'rd, 'rs1");
886       else if (instr->Rs1Value() == zero_reg.code())
887         Format(instr, "sgtz      'rd, 'rs2");
888       else
889         Format(instr, "slt       'rd, 'rs1, 'rs2");
890       break;
891     case RO_SLTU:
892       if (instr->Rs1Value() == zero_reg.code())
893         Format(instr, "snez      'rd, 'rs2");
894       else
895         Format(instr, "sltu      'rd, 'rs1, 'rs2");
896       break;
897     case RO_XOR:
898       Format(instr, "xor       'rd, 'rs1, 'rs2");
899       break;
900     case RO_SRL:
901       Format(instr, "srl       'rd, 'rs1, 'rs2");
902       break;
903     case RO_SRA:
904       Format(instr, "sra       'rd, 'rs1, 'rs2");
905       break;
906     case RO_OR:
907       Format(instr, "or        'rd, 'rs1, 'rs2");
908       break;
909     case RO_AND:
910       Format(instr, "and       'rd, 'rs1, 'rs2");
911       break;
912 #ifdef V8_TARGET_ARCH_64_BIT
913     case RO_ADDW:
914       Format(instr, "addw      'rd, 'rs1, 'rs2");
915       break;
916     case RO_SUBW:
917       if (instr->Rs1Value() == zero_reg.code())
918         Format(instr, "negw      'rd, 'rs2");
919       else
920         Format(instr, "subw      'rd, 'rs1, 'rs2");
921       break;
922     case RO_SLLW:
923       Format(instr, "sllw      'rd, 'rs1, 'rs2");
924       break;
925     case RO_SRLW:
926       Format(instr, "srlw      'rd, 'rs1, 'rs2");
927       break;
928     case RO_SRAW:
929       Format(instr, "sraw      'rd, 'rs1, 'rs2");
930       break;
931 #endif /* V8_TARGET_ARCH_64_BIT */
932     // TODO(riscv): Add RISCV M extension macro
933     case RO_MUL:
934       Format(instr, "mul       'rd, 'rs1, 'rs2");
935       break;
936     case RO_MULH:
937       Format(instr, "mulh      'rd, 'rs1, 'rs2");
938       break;
939     case RO_MULHSU:
940       Format(instr, "mulhsu    'rd, 'rs1, 'rs2");
941       break;
942     case RO_MULHU:
943       Format(instr, "mulhu     'rd, 'rs1, 'rs2");
944       break;
945     case RO_DIV:
946       Format(instr, "div       'rd, 'rs1, 'rs2");
947       break;
948     case RO_DIVU:
949       Format(instr, "divu      'rd, 'rs1, 'rs2");
950       break;
951     case RO_REM:
952       Format(instr, "rem       'rd, 'rs1, 'rs2");
953       break;
954     case RO_REMU:
955       Format(instr, "remu      'rd, 'rs1, 'rs2");
956       break;
957 #ifdef V8_TARGET_ARCH_64_BIT
958     case RO_MULW:
959       Format(instr, "mulw      'rd, 'rs1, 'rs2");
960       break;
961     case RO_DIVW:
962       Format(instr, "divw      'rd, 'rs1, 'rs2");
963       break;
964     case RO_DIVUW:
965       Format(instr, "divuw     'rd, 'rs1, 'rs2");
966       break;
967     case RO_REMW:
968       Format(instr, "remw      'rd, 'rs1, 'rs2");
969       break;
970     case RO_REMUW:
971       Format(instr, "remuw     'rd, 'rs1, 'rs2");
972       break;
973 #endif /*V8_TARGET_ARCH_64_BIT*/
974     // TODO(riscv): End Add RISCV M extension macro
975     default: {
976       switch (instr->BaseOpcode()) {
977         case AMO:
978           DecodeRAType(instr);
979           break;
980         case OP_FP:
981           DecodeRFPType(instr);
982           break;
983         default:
984           UNSUPPORTED_RISCV();
985       }
986     }
987   }
988 }
989 
DecodeRAType(Instruction * instr)990 void Decoder::DecodeRAType(Instruction* instr) {
991   // TODO(riscv): Add macro for RISCV A extension
992   // Special handling for A extension instructions because it uses func5
993   // For all A extension instruction, V8 simulator is pure sequential. No
994   // Memory address lock or other synchronizaiton behaviors.
995   switch (instr->InstructionBits() & kRATypeMask) {
996     case RO_LR_W:
997       Format(instr, "lr.w'a    'rd, ('rs1)");
998       break;
999     case RO_SC_W:
1000       Format(instr, "sc.w'a    'rd, 'rs2, ('rs1)");
1001       break;
1002     case RO_AMOSWAP_W:
1003       Format(instr, "amoswap.w'a 'rd, 'rs2, ('rs1)");
1004       break;
1005     case RO_AMOADD_W:
1006       Format(instr, "amoadd.w'a 'rd, 'rs2, ('rs1)");
1007       break;
1008     case RO_AMOXOR_W:
1009       Format(instr, "amoxor.w'a 'rd, 'rs2, ('rs1)");
1010       break;
1011     case RO_AMOAND_W:
1012       Format(instr, "amoand.w'a 'rd, 'rs2, ('rs1)");
1013       break;
1014     case RO_AMOOR_W:
1015       Format(instr, "amoor.w'a 'rd, 'rs2, ('rs1)");
1016       break;
1017     case RO_AMOMIN_W:
1018       Format(instr, "amomin.w'a 'rd, 'rs2, ('rs1)");
1019       break;
1020     case RO_AMOMAX_W:
1021       Format(instr, "amomax.w'a 'rd, 'rs2, ('rs1)");
1022       break;
1023     case RO_AMOMINU_W:
1024       Format(instr, "amominu.w'a 'rd, 'rs2, ('rs1)");
1025       break;
1026     case RO_AMOMAXU_W:
1027       Format(instr, "amomaxu.w'a 'rd, 'rs2, ('rs1)");
1028       break;
1029 #ifdef V8_TARGET_ARCH_64_BIT
1030     case RO_LR_D:
1031       Format(instr, "lr.d'a 'rd, ('rs1)");
1032       break;
1033     case RO_SC_D:
1034       Format(instr, "sc.d'a 'rd, 'rs2, ('rs1)");
1035       break;
1036     case RO_AMOSWAP_D:
1037       Format(instr, "amoswap.d'a 'rd, 'rs2, ('rs1)");
1038       break;
1039     case RO_AMOADD_D:
1040       Format(instr, "amoadd.d'a 'rd, 'rs2, ('rs1)");
1041       break;
1042     case RO_AMOXOR_D:
1043       Format(instr, "amoxor.d'a 'rd, 'rs2, ('rs1)");
1044       break;
1045     case RO_AMOAND_D:
1046       Format(instr, "amoand.d'a 'rd, 'rs2, ('rs1)");
1047       break;
1048     case RO_AMOOR_D:
1049       Format(instr, "amoor.d'a 'rd, 'rs2, ('rs1)");
1050       break;
1051     case RO_AMOMIN_D:
1052       Format(instr, "amomin.d'a 'rd, 'rs2, ('rs1)");
1053       break;
1054     case RO_AMOMAX_D:
1055       Format(instr, "amoswap.d'a 'rd, 'rs2, ('rs1)");
1056       break;
1057     case RO_AMOMINU_D:
1058       Format(instr, "amominu.d'a 'rd, 'rs2, ('rs1)");
1059       break;
1060     case RO_AMOMAXU_D:
1061       Format(instr, "amomaxu.d'a 'rd, 'rs2, ('rs1)");
1062       break;
1063 #endif /*V8_TARGET_ARCH_64_BIT*/
1064     // TODO(riscv): End Add macro for RISCV A extension
1065     default: {
1066       UNSUPPORTED_RISCV();
1067     }
1068   }
1069 }
1070 
DecodeRFPType(Instruction * instr)1071 void Decoder::DecodeRFPType(Instruction* instr) {
1072   // OP_FP instructions (F/D) uses func7 first. Some further uses fun3 and rs2()
1073 
1074   // kRATypeMask is only for func7
1075   switch (instr->InstructionBits() & kRFPTypeMask) {
1076     // TODO(riscv): Add macro for RISCV F extension
1077     case RO_FADD_S:
1078       Format(instr, "fadd.s    'fd, 'fs1, 'fs2");
1079       break;
1080     case RO_FSUB_S:
1081       Format(instr, "fsub.s    'fd, 'fs1, 'fs2");
1082       break;
1083     case RO_FMUL_S:
1084       Format(instr, "fmul.s    'fd, 'fs1, 'fs2");
1085       break;
1086     case RO_FDIV_S:
1087       Format(instr, "fdiv.s    'fd, 'fs1, 'fs2");
1088       break;
1089     case RO_FSQRT_S:
1090       Format(instr, "fsqrt.s   'fd, 'fs1");
1091       break;
1092     case RO_FSGNJ_S: {  // RO_FSGNJN_S  RO_FSGNJX_S
1093       switch (instr->Funct3Value()) {
1094         case 0b000:  // RO_FSGNJ_S
1095           if (instr->Rs1Value() == instr->Rs2Value())
1096             Format(instr, "fmv.s     'fd, 'fs1");
1097           else
1098             Format(instr, "fsgnj.s   'fd, 'fs1, 'fs2");
1099           break;
1100         case 0b001:  // RO_FSGNJN_S
1101           if (instr->Rs1Value() == instr->Rs2Value())
1102             Format(instr, "fneg.s    'fd, 'fs1");
1103           else
1104             Format(instr, "fsgnjn.s  'fd, 'fs1, 'fs2");
1105           break;
1106         case 0b010:  // RO_FSGNJX_S
1107           if (instr->Rs1Value() == instr->Rs2Value())
1108             Format(instr, "fabs.s    'fd, 'fs1");
1109           else
1110             Format(instr, "fsgnjx.s  'fd, 'fs1, 'fs2");
1111           break;
1112         default:
1113           UNSUPPORTED_RISCV();
1114       }
1115       break;
1116     }
1117     case RO_FMIN_S: {  // RO_FMAX_S
1118       switch (instr->Funct3Value()) {
1119         case 0b000:  // RO_FMIN_S
1120           Format(instr, "fmin.s    'fd, 'fs1, 'fs2");
1121           break;
1122         case 0b001:  // RO_FMAX_S
1123           Format(instr, "fmax.s    'fd, 'fs1, 'fs2");
1124           break;
1125         default:
1126           UNSUPPORTED_RISCV();
1127       }
1128       break;
1129     }
1130     case RO_FCVT_W_S: {  // RO_FCVT_WU_S , 64F RO_FCVT_L_S RO_FCVT_LU_S
1131       switch (instr->Rs2Value()) {
1132         case 0b00000:  // RO_FCVT_W_S
1133           Format(instr, "fcvt.w.s  ['frm] 'rd, 'fs1");
1134           break;
1135         case 0b00001:  // RO_FCVT_WU_S
1136           Format(instr, "fcvt.wu.s ['frm] 'rd, 'fs1");
1137           break;
1138 #ifdef V8_TARGET_ARCH_64_BIT
1139         case 0b00010:  // RO_FCVT_L_S
1140           Format(instr, "fcvt.l.s  ['frm] 'rd, 'fs1");
1141           break;
1142         case 0b00011:  // RO_FCVT_LU_S
1143           Format(instr, "fcvt.lu.s ['frm] 'rd, 'fs1");
1144           break;
1145 #endif /* V8_TARGET_ARCH_64_BIT */
1146         default:
1147           UNSUPPORTED_RISCV();
1148       }
1149       break;
1150     }
1151     case RO_FMV: {  // RO_FCLASS_S
1152       if (instr->Rs2Value() != 0b00000) {
1153         UNSUPPORTED_RISCV();
1154       }
1155       switch (instr->Funct3Value()) {
1156         case 0b000:  // RO_FMV_X_W
1157           Format(instr, "fmv.x.w   'rd, 'fs1");
1158           break;
1159         case 0b001:  // RO_FCLASS_S
1160           Format(instr, "fclass.s  'rd, 'fs1");
1161           break;
1162         default:
1163           UNSUPPORTED_RISCV();
1164       }
1165       break;
1166     }
1167     case RO_FLE_S: {  // RO_FEQ_S RO_FLT_S RO_FLE_S
1168       switch (instr->Funct3Value()) {
1169         case 0b010:  // RO_FEQ_S
1170           Format(instr, "feq.s     'rd, 'fs1, 'fs2");
1171           break;
1172         case 0b001:  // RO_FLT_S
1173           Format(instr, "flt.s     'rd, 'fs1, 'fs2");
1174           break;
1175         case 0b000:  // RO_FLE_S
1176           Format(instr, "fle.s     'rd, 'fs1, 'fs2");
1177           break;
1178         default:
1179           UNSUPPORTED_RISCV();
1180       }
1181       break;
1182     }
1183     case RO_FCVT_S_W: {  // RO_FCVT_S_WU , 64F RO_FCVT_S_L RO_FCVT_S_LU
1184       switch (instr->Rs2Value()) {
1185         case 0b00000:  // RO_FCVT_S_W
1186           Format(instr, "fcvt.s.w  'fd, 'rs1");
1187           break;
1188         case 0b00001:  // RO_FCVT_S_WU
1189           Format(instr, "fcvt.s.wu 'fd, 'rs1");
1190           break;
1191 #ifdef V8_TARGET_ARCH_64_BIT
1192         case 0b00010:  // RO_FCVT_S_L
1193           Format(instr, "fcvt.s.l  'fd, 'rs1");
1194           break;
1195         case 0b00011:  // RO_FCVT_S_LU
1196           Format(instr, "fcvt.s.lu 'fd, 'rs1");
1197           break;
1198 #endif /* V8_TARGET_ARCH_64_BIT */
1199         default: {
1200           UNSUPPORTED_RISCV();
1201         }
1202       }
1203       break;
1204     }
1205     case RO_FMV_W_X: {
1206       if (instr->Funct3Value() == 0b000) {
1207         Format(instr, "fmv.w.x   'fd, 'rs1");
1208       } else {
1209         UNSUPPORTED_RISCV();
1210       }
1211       break;
1212     }
1213     // TODO(riscv): Add macro for RISCV D extension
1214     case RO_FADD_D:
1215       Format(instr, "fadd.d    'fd, 'fs1, 'fs2");
1216       break;
1217     case RO_FSUB_D:
1218       Format(instr, "fsub.d    'fd, 'fs1, 'fs2");
1219       break;
1220     case RO_FMUL_D:
1221       Format(instr, "fmul.d    'fd, 'fs1, 'fs2");
1222       break;
1223     case RO_FDIV_D:
1224       Format(instr, "fdiv.d    'fd, 'fs1, 'fs2");
1225       break;
1226     case RO_FSQRT_D: {
1227       if (instr->Rs2Value() == 0b00000) {
1228         Format(instr, "fsqrt.d   'fd, 'fs1");
1229       } else {
1230         UNSUPPORTED_RISCV();
1231       }
1232       break;
1233     }
1234     case RO_FSGNJ_D: {  // RO_FSGNJN_D RO_FSGNJX_D
1235       switch (instr->Funct3Value()) {
1236         case 0b000:  // RO_FSGNJ_D
1237           if (instr->Rs1Value() == instr->Rs2Value())
1238             Format(instr, "fmv.d     'fd, 'fs1");
1239           else
1240             Format(instr, "fsgnj.d   'fd, 'fs1, 'fs2");
1241           break;
1242         case 0b001:  // RO_FSGNJN_D
1243           if (instr->Rs1Value() == instr->Rs2Value())
1244             Format(instr, "fneg.d    'fd, 'fs1");
1245           else
1246             Format(instr, "fsgnjn.d  'fd, 'fs1, 'fs2");
1247           break;
1248         case 0b010:  // RO_FSGNJX_D
1249           if (instr->Rs1Value() == instr->Rs2Value())
1250             Format(instr, "fabs.d    'fd, 'fs1");
1251           else
1252             Format(instr, "fsgnjx.d  'fd, 'fs1, 'fs2");
1253           break;
1254         default:
1255           UNSUPPORTED_RISCV();
1256       }
1257       break;
1258     }
1259     case RO_FMIN_D: {  // RO_FMAX_D
1260       switch (instr->Funct3Value()) {
1261         case 0b000:  // RO_FMIN_D
1262           Format(instr, "fmin.d    'fd, 'fs1, 'fs2");
1263           break;
1264         case 0b001:  // RO_FMAX_D
1265           Format(instr, "fmax.d    'fd, 'fs1, 'fs2");
1266           break;
1267         default:
1268           UNSUPPORTED_RISCV();
1269       }
1270       break;
1271     }
1272     case (RO_FCVT_S_D & kRFPTypeMask): {
1273       if (instr->Rs2Value() == 0b00001) {
1274         Format(instr, "fcvt.s.d  ['frm] 'fd, 'rs1");
1275       } else {
1276         UNSUPPORTED_RISCV();
1277       }
1278       break;
1279     }
1280     case RO_FCVT_D_S: {
1281       if (instr->Rs2Value() == 0b00000) {
1282         Format(instr, "fcvt.d.s  'fd, 'fs1");
1283       } else {
1284         UNSUPPORTED_RISCV();
1285       }
1286       break;
1287     }
1288     case RO_FLE_D: {  // RO_FEQ_D RO_FLT_D RO_FLE_D
1289       switch (instr->Funct3Value()) {
1290         case 0b010:  // RO_FEQ_S
1291           Format(instr, "feq.d     'rd, 'fs1, 'fs2");
1292           break;
1293         case 0b001:  // RO_FLT_D
1294           Format(instr, "flt.d     'rd, 'fs1, 'fs2");
1295           break;
1296         case 0b000:  // RO_FLE_D
1297           Format(instr, "fle.d     'rd, 'fs1, 'fs2");
1298           break;
1299         default:
1300           UNSUPPORTED_RISCV();
1301       }
1302       break;
1303     }
1304     case (RO_FCLASS_D & kRFPTypeMask): {  // RO_FCLASS_D , 64D RO_FMV_X_D
1305       if (instr->Rs2Value() != 0b00000) {
1306         UNSUPPORTED_RISCV();
1307         break;
1308       }
1309       switch (instr->Funct3Value()) {
1310         case 0b001:  // RO_FCLASS_D
1311           Format(instr, "fclass.d  'rd, 'fs1");
1312           break;
1313 #ifdef V8_TARGET_ARCH_64_BIT
1314         case 0b000:  // RO_FMV_X_D
1315           Format(instr, "fmv.x.d   'rd, 'fs1");
1316           break;
1317 #endif /* V8_TARGET_ARCH_64_BIT */
1318         default:
1319           UNSUPPORTED_RISCV();
1320       }
1321       break;
1322     }
1323     case RO_FCVT_W_D: {  // RO_FCVT_WU_D , 64F RO_FCVT_L_D RO_FCVT_LU_D
1324       switch (instr->Rs2Value()) {
1325         case 0b00000:  // RO_FCVT_W_D
1326           Format(instr, "fcvt.w.d  ['frm] 'rd, 'fs1");
1327           break;
1328         case 0b00001:  // RO_FCVT_WU_D
1329           Format(instr, "fcvt.wu.d ['frm] 'rd, 'fs1");
1330           break;
1331 #ifdef V8_TARGET_ARCH_64_BIT
1332         case 0b00010:  // RO_FCVT_L_D
1333           Format(instr, "fcvt.l.d  ['frm] 'rd, 'fs1");
1334           break;
1335         case 0b00011:  // RO_FCVT_LU_D
1336           Format(instr, "fcvt.lu.d ['frm] 'rd, 'fs1");
1337           break;
1338 #endif /* V8_TARGET_ARCH_64_BIT */
1339         default:
1340           UNSUPPORTED_RISCV();
1341       }
1342       break;
1343     }
1344     case RO_FCVT_D_W: {  // RO_FCVT_D_WU , 64F RO_FCVT_D_L RO_FCVT_D_LU
1345       switch (instr->Rs2Value()) {
1346         case 0b00000:  // RO_FCVT_D_W
1347           Format(instr, "fcvt.d.w  'fd, 'rs1");
1348           break;
1349         case 0b00001:  // RO_FCVT_D_WU
1350           Format(instr, "fcvt.d.wu 'fd, 'rs1");
1351           break;
1352 #ifdef V8_TARGET_ARCH_64_BIT
1353         case 0b00010:  // RO_FCVT_D_L
1354           Format(instr, "fcvt.d.l  'fd, 'rs1");
1355           break;
1356         case 0b00011:  // RO_FCVT_D_LU
1357           Format(instr, "fcvt.d.lu 'fd, 'rs1");
1358           break;
1359 #endif /* V8_TARGET_ARCH_64_BIT */
1360         default:
1361           UNSUPPORTED_RISCV();
1362       }
1363       break;
1364     }
1365 #ifdef V8_TARGET_ARCH_64_BIT
1366     case RO_FMV_D_X: {
1367       if (instr->Funct3Value() == 0b000 && instr->Rs2Value() == 0b00000) {
1368         Format(instr, "fmv.d.x   'fd, 'rs1");
1369       } else {
1370         UNSUPPORTED_RISCV();
1371       }
1372       break;
1373     }
1374 #endif /* V8_TARGET_ARCH_64_BIT */
1375     default: {
1376       UNSUPPORTED_RISCV();
1377     }
1378   }
1379 }
1380 
DecodeR4Type(Instruction * instr)1381 void Decoder::DecodeR4Type(Instruction* instr) {
1382   switch (instr->InstructionBits() & kR4TypeMask) {
1383     // TODO(riscv): use F Extension macro block
1384     case RO_FMADD_S:
1385       Format(instr, "fmadd.s   'fd, 'fs1, 'fs2, 'fs3");
1386       break;
1387     case RO_FMSUB_S:
1388       Format(instr, "fmsub.s   'fd, 'fs1, 'fs2, 'fs3");
1389       break;
1390     case RO_FNMSUB_S:
1391       Format(instr, "fnmsub.s   'fd, 'fs1, 'fs2, 'fs3");
1392       break;
1393     case RO_FNMADD_S:
1394       Format(instr, "fnmadd.s   'fd, 'fs1, 'fs2, 'fs3");
1395       break;
1396     // TODO(riscv): use F Extension macro block
1397     case RO_FMADD_D:
1398       Format(instr, "fmadd.d   'fd, 'fs1, 'fs2, 'fs3");
1399       break;
1400     case RO_FMSUB_D:
1401       Format(instr, "fmsub.d   'fd, 'fs1, 'fs2, 'fs3");
1402       break;
1403     case RO_FNMSUB_D:
1404       Format(instr, "fnmsub.d  'fd, 'fs1, 'fs2, 'fs3");
1405       break;
1406     case RO_FNMADD_D:
1407       Format(instr, "fnmadd.d  'fd, 'fs1, 'fs2, 'fs3");
1408       break;
1409     default:
1410       UNSUPPORTED_RISCV();
1411   }
1412 }
1413 
DecodeIType(Instruction * instr)1414 void Decoder::DecodeIType(Instruction* instr) {
1415   if (instr->vl_vs_width() != -1) {
1416     DecodeRvvVL(instr);
1417   } else {
1418     switch (instr->InstructionBits() & kITypeMask) {
1419       case RO_JALR:
1420         if (instr->RdValue() == zero_reg.code() &&
1421             instr->Rs1Value() == ra.code() && instr->Imm12Value() == 0)
1422           Format(instr, "ret");
1423         else if (instr->RdValue() == zero_reg.code() &&
1424                  instr->Imm12Value() == 0)
1425           Format(instr, "jr        'rs1");
1426         else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
1427           Format(instr, "jalr      'rs1");
1428         else
1429           Format(instr, "jalr      'rd, 'imm12('rs1)");
1430         break;
1431       case RO_LB:
1432         Format(instr, "lb        'rd, 'imm12('rs1)");
1433         break;
1434       case RO_LH:
1435         Format(instr, "lh        'rd, 'imm12('rs1)");
1436         break;
1437       case RO_LW:
1438         Format(instr, "lw        'rd, 'imm12('rs1)");
1439         break;
1440       case RO_LBU:
1441         Format(instr, "lbu       'rd, 'imm12('rs1)");
1442         break;
1443       case RO_LHU:
1444         Format(instr, "lhu       'rd, 'imm12('rs1)");
1445         break;
1446 #ifdef V8_TARGET_ARCH_64_BIT
1447       case RO_LWU:
1448         Format(instr, "lwu       'rd, 'imm12('rs1)");
1449         break;
1450       case RO_LD:
1451         Format(instr, "ld        'rd, 'imm12('rs1)");
1452         break;
1453 #endif /*V8_TARGET_ARCH_64_BIT*/
1454       case RO_ADDI:
1455         if (instr->Imm12Value() == 0) {
1456           if (instr->RdValue() == zero_reg.code() &&
1457               instr->Rs1Value() == zero_reg.code())
1458             Format(instr, "nop");
1459           else
1460             Format(instr, "mv        'rd, 'rs1");
1461         } else if (instr->Rs1Value() == zero_reg.code()) {
1462           Format(instr, "li        'rd, 'imm12");
1463         } else {
1464           Format(instr, "addi      'rd, 'rs1, 'imm12");
1465         }
1466         break;
1467       case RO_SLTI:
1468         Format(instr, "slti      'rd, 'rs1, 'imm12");
1469         break;
1470       case RO_SLTIU:
1471         if (instr->Imm12Value() == 1)
1472           Format(instr, "seqz      'rd, 'rs1");
1473         else
1474           Format(instr, "sltiu     'rd, 'rs1, 'imm12");
1475         break;
1476       case RO_XORI:
1477         if (instr->Imm12Value() == -1)
1478           Format(instr, "not       'rd, 'rs1");
1479         else
1480           Format(instr, "xori      'rd, 'rs1, 'imm12x");
1481         break;
1482       case RO_ORI:
1483         Format(instr, "ori       'rd, 'rs1, 'imm12x");
1484         break;
1485       case RO_ANDI:
1486         Format(instr, "andi      'rd, 'rs1, 'imm12x");
1487         break;
1488       case RO_SLLI:
1489         Format(instr, "slli      'rd, 'rs1, 's64");
1490         break;
1491       case RO_SRLI: {  //  RO_SRAI
1492         if (!instr->IsArithShift()) {
1493           Format(instr, "srli      'rd, 'rs1, 's64");
1494         } else {
1495           Format(instr, "srai      'rd, 'rs1, 's64");
1496         }
1497         break;
1498       }
1499 #ifdef V8_TARGET_ARCH_64_BIT
1500       case RO_ADDIW:
1501         if (instr->Imm12Value() == 0)
1502           Format(instr, "sext.w    'rd, 'rs1");
1503         else
1504           Format(instr, "addiw     'rd, 'rs1, 'imm12");
1505         break;
1506       case RO_SLLIW:
1507         Format(instr, "slliw     'rd, 'rs1, 's32");
1508         break;
1509       case RO_SRLIW: {  //  RO_SRAIW
1510         if (!instr->IsArithShift()) {
1511           Format(instr, "srliw     'rd, 'rs1, 's32");
1512         } else {
1513           Format(instr, "sraiw     'rd, 'rs1, 's32");
1514         }
1515         break;
1516       }
1517 #endif /*V8_TARGET_ARCH_64_BIT*/
1518       case RO_FENCE:
1519         if (instr->MemoryOrder(true) == PSIORW &&
1520             instr->MemoryOrder(false) == PSIORW)
1521           Format(instr, "fence");
1522         else
1523           Format(instr, "fence 'pre, 'suc");
1524         break;
1525       case RO_ECALL: {                   // RO_EBREAK
1526         if (instr->Imm12Value() == 0) {  // ECALL
1527           Format(instr, "ecall");
1528         } else if (instr->Imm12Value() == 1) {  // EBREAK
1529           Format(instr, "ebreak");
1530         } else {
1531           UNSUPPORTED_RISCV();
1532         }
1533         break;
1534       }
1535       // TODO(riscv): use Zifencei Standard Extension macro block
1536       case RO_FENCE_I:
1537         Format(instr, "fence.i");
1538         break;
1539       // TODO(riscv): use Zicsr Standard Extension macro block
1540       // FIXME(RISC-V): Add special formatting for CSR registers
1541       case RO_CSRRW:
1542         if (instr->CsrValue() == csr_fcsr) {
1543           if (instr->RdValue() == zero_reg.code())
1544             Format(instr, "fscsr     'rs1");
1545           else
1546             Format(instr, "fscsr     'rd, 'rs1");
1547         } else if (instr->CsrValue() == csr_frm) {
1548           if (instr->RdValue() == zero_reg.code())
1549             Format(instr, "fsrm      'rs1");
1550           else
1551             Format(instr, "fsrm      'rd, 'rs1");
1552         } else if (instr->CsrValue() == csr_fflags) {
1553           if (instr->RdValue() == zero_reg.code())
1554             Format(instr, "fsflags   'rs1");
1555           else
1556             Format(instr, "fsflags   'rd, 'rs1");
1557         } else if (instr->RdValue() == zero_reg.code()) {
1558           Format(instr, "csrw      'csr, 'rs1");
1559         } else {
1560           Format(instr, "csrrw     'rd, 'csr, 'rs1");
1561         }
1562         break;
1563       case RO_CSRRS:
1564         if (instr->Rs1Value() == zero_reg.code()) {
1565           switch (instr->CsrValue()) {
1566             case csr_instret:
1567               Format(instr, "rdinstret 'rd");
1568               break;
1569             case csr_instreth:
1570               Format(instr, "rdinstreth 'rd");
1571               break;
1572             case csr_time:
1573               Format(instr, "rdtime    'rd");
1574               break;
1575             case csr_timeh:
1576               Format(instr, "rdtimeh   'rd");
1577               break;
1578             case csr_cycle:
1579               Format(instr, "rdcycle   'rd");
1580               break;
1581             case csr_cycleh:
1582               Format(instr, "rdcycleh  'rd");
1583               break;
1584             case csr_fflags:
1585               Format(instr, "frflags   'rd");
1586               break;
1587             case csr_frm:
1588               Format(instr, "frrm      'rd");
1589               break;
1590             case csr_fcsr:
1591               Format(instr, "frcsr     'rd");
1592               break;
1593             default:
1594               UNREACHABLE();
1595           }
1596         } else if (instr->Rs1Value() == zero_reg.code()) {
1597           Format(instr, "csrr      'rd, 'csr");
1598         } else if (instr->RdValue() == zero_reg.code()) {
1599           Format(instr, "csrs      'csr, 'rs1");
1600         } else {
1601           Format(instr, "csrrs     'rd, 'csr, 'rs1");
1602         }
1603         break;
1604       case RO_CSRRC:
1605         if (instr->RdValue() == zero_reg.code())
1606           Format(instr, "csrc      'csr, 'rs1");
1607         else
1608           Format(instr, "csrrc     'rd, 'csr, 'rs1");
1609         break;
1610       case RO_CSRRWI:
1611         if (instr->RdValue() == zero_reg.code())
1612           Format(instr, "csrwi     'csr, 'uimm");
1613         else
1614           Format(instr, "csrrwi    'rd, 'csr, 'uimm");
1615         break;
1616       case RO_CSRRSI:
1617         if (instr->RdValue() == zero_reg.code())
1618           Format(instr, "csrsi     'csr, 'uimm");
1619         else
1620           Format(instr, "csrrsi    'rd, 'csr, 'uimm");
1621         break;
1622       case RO_CSRRCI:
1623         if (instr->RdValue() == zero_reg.code())
1624           Format(instr, "csrci     'csr, 'uimm");
1625         else
1626           Format(instr, "csrrci    'rd, 'csr, 'uimm");
1627         break;
1628       // TODO(riscv): use F Extension macro block
1629       case RO_FLW:
1630         Format(instr, "flw       'fd, 'imm12('rs1)");
1631         break;
1632       // TODO(riscv): use D Extension macro block
1633       case RO_FLD:
1634         Format(instr, "fld       'fd, 'imm12('rs1)");
1635         break;
1636       default:
1637         UNSUPPORTED_RISCV();
1638     }
1639   }
1640 }
1641 
DecodeSType(Instruction * instr)1642 void Decoder::DecodeSType(Instruction* instr) {
1643   if (instr->vl_vs_width() != -1) {
1644     DecodeRvvVS(instr);
1645   } else {
1646     switch (instr->InstructionBits() & kSTypeMask) {
1647       case RO_SB:
1648         Format(instr, "sb        'rs2, 'offS('rs1)");
1649         break;
1650       case RO_SH:
1651         Format(instr, "sh        'rs2, 'offS('rs1)");
1652         break;
1653       case RO_SW:
1654         Format(instr, "sw        'rs2, 'offS('rs1)");
1655         break;
1656 #ifdef V8_TARGET_ARCH_64_BIT
1657       case RO_SD:
1658         Format(instr, "sd        'rs2, 'offS('rs1)");
1659         break;
1660 #endif /*V8_TARGET_ARCH_64_BIT*/
1661       // TODO(riscv): use F Extension macro block
1662       case RO_FSW:
1663         Format(instr, "fsw       'fs2, 'offS('rs1)");
1664         break;
1665       // TODO(riscv): use D Extension macro block
1666       case RO_FSD:
1667         Format(instr, "fsd       'fs2, 'offS('rs1)");
1668         break;
1669       default:
1670         UNSUPPORTED_RISCV();
1671     }
1672   }
1673 }
DecodeBType(Instruction * instr)1674 void Decoder::DecodeBType(Instruction* instr) {
1675   switch (instr->InstructionBits() & kBTypeMask) {
1676     case RO_BEQ:
1677       Format(instr, "beq       'rs1, 'rs2, 'offB");
1678       break;
1679     case RO_BNE:
1680       Format(instr, "bne       'rs1, 'rs2, 'offB");
1681       break;
1682     case RO_BLT:
1683       Format(instr, "blt       'rs1, 'rs2, 'offB");
1684       break;
1685     case RO_BGE:
1686       Format(instr, "bge       'rs1, 'rs2, 'offB");
1687       break;
1688     case RO_BLTU:
1689       Format(instr, "bltu      'rs1, 'rs2, 'offB");
1690       break;
1691     case RO_BGEU:
1692       Format(instr, "bgeu      'rs1, 'rs2, 'offB");
1693       break;
1694     default:
1695       UNSUPPORTED_RISCV();
1696   }
1697 }
DecodeUType(Instruction * instr)1698 void Decoder::DecodeUType(Instruction* instr) {
1699   // U Type doesn't have additional mask
1700   switch (instr->BaseOpcodeFieldRaw()) {
1701     case RO_LUI:
1702       Format(instr, "lui       'rd, 'imm20U");
1703       break;
1704     case RO_AUIPC:
1705       Format(instr, "auipc     'rd, 'imm20U");
1706       break;
1707     default:
1708       UNSUPPORTED_RISCV();
1709   }
1710 }
1711 // namespace internal
DecodeJType(Instruction * instr)1712 void Decoder::DecodeJType(Instruction* instr) {
1713   // J Type doesn't have additional mask
1714   switch (instr->BaseOpcodeValue()) {
1715     case RO_JAL:
1716       if (instr->RdValue() == zero_reg.code())
1717         Format(instr, "j         'imm20J");
1718       else if (instr->RdValue() == ra.code())
1719         Format(instr, "jal       'imm20J");
1720       else
1721         Format(instr, "jal       'rd, 'imm20J");
1722       break;
1723     default:
1724       UNSUPPORTED_RISCV();
1725   }
1726 }
1727 
DecodeCRType(Instruction * instr)1728 void Decoder::DecodeCRType(Instruction* instr) {
1729   switch (instr->RvcFunct4Value()) {
1730     case 0b1000:
1731       if (instr->RvcRs1Value() != 0 && instr->RvcRs2Value() == 0)
1732         Format(instr, "jr        'Crs1");
1733       else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() != 0)
1734         Format(instr, "mv        'Crd, 'Crs2");
1735       else
1736         UNSUPPORTED_RISCV();
1737       break;
1738     case 0b1001:
1739       if (instr->RvcRs1Value() == 0 && instr->RvcRs2Value() == 0)
1740         Format(instr, "ebreak");
1741       else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() == 0)
1742         Format(instr, "jalr      'Crs1");
1743       else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() != 0)
1744         Format(instr, "add       'Crd, 'Crd, 'Crs2");
1745       else
1746         UNSUPPORTED_RISCV();
1747       break;
1748     default:
1749       UNSUPPORTED_RISCV();
1750   }
1751 }
1752 
DecodeCAType(Instruction * instr)1753 void Decoder::DecodeCAType(Instruction* instr) {
1754   switch (instr->InstructionBits() & kCATypeMask) {
1755     case RO_C_SUB:
1756       Format(instr, "sub       'Crs1s, 'Crs1s, 'Crs2s");
1757       break;
1758     case RO_C_XOR:
1759       Format(instr, "xor       'Crs1s, 'Crs1s, 'Crs2s");
1760       break;
1761     case RO_C_OR:
1762       Format(instr, "or       'Crs1s, 'Crs1s, 'Crs2s");
1763       break;
1764     case RO_C_AND:
1765       Format(instr, "and       'Crs1s, 'Crs1s, 'Crs2s");
1766       break;
1767     case RO_C_SUBW:
1768       Format(instr, "subw       'Crs1s, 'Crs1s, 'Crs2s");
1769       break;
1770     case RO_C_ADDW:
1771       Format(instr, "addw       'Crs1s, 'Crs1s, 'Crs2s");
1772       break;
1773     default:
1774       UNSUPPORTED_RISCV();
1775   }
1776 }
1777 
DecodeCIType(Instruction * instr)1778 void Decoder::DecodeCIType(Instruction* instr) {
1779   switch (instr->RvcOpcode()) {
1780     case RO_C_NOP_ADDI:
1781       if (instr->RvcRdValue() == 0)
1782         Format(instr, "nop");
1783       else
1784         Format(instr, "addi      'Crd, 'Crd, 'Cimm6");
1785       break;
1786     case RO_C_ADDIW:
1787       Format(instr, "addiw     'Crd, 'Crd, 'Cimm6");
1788       break;
1789     case RO_C_LI:
1790       Format(instr, "li        'Crd, 'Cimm6");
1791       break;
1792     case RO_C_LUI_ADD:
1793       if (instr->RvcRdValue() == 2)
1794         Format(instr, "addi      sp, sp, 'Cimm6Addi16sp");
1795       else if (instr->RvcRdValue() != 0 && instr->RvcRdValue() != 2)
1796         Format(instr, "lui       'Crd, 'Cimm6U");
1797       else
1798         UNSUPPORTED_RISCV();
1799       break;
1800     case RO_C_SLLI:
1801       Format(instr, "slli      'Crd, 'Crd, 'Cshamt");
1802       break;
1803     case RO_C_FLDSP:
1804       Format(instr, "fld       'Cfd, 'Cimm6Ldsp(sp)");
1805       break;
1806     case RO_C_LWSP:
1807       Format(instr, "lw        'Crd, 'Cimm6Lwsp(sp)");
1808       break;
1809     case RO_C_LDSP:
1810       Format(instr, "ld        'Crd, 'Cimm6Ldsp(sp)");
1811       break;
1812     default:
1813       UNSUPPORTED_RISCV();
1814   }
1815 }
1816 
DecodeCIWType(Instruction * instr)1817 void Decoder::DecodeCIWType(Instruction* instr) {
1818   switch (instr->RvcOpcode()) {
1819     case RO_C_ADDI4SPN:
1820       Format(instr, "addi       'Crs2s, sp, 'Cimm8Addi4spn");
1821       break;
1822     default:
1823       UNSUPPORTED_RISCV();
1824   }
1825 }
1826 
DecodeCSSType(Instruction * instr)1827 void Decoder::DecodeCSSType(Instruction* instr) {
1828   switch (instr->RvcOpcode()) {
1829     case RO_C_SWSP:
1830       Format(instr, "sw        'Crs2, 'Cimm6Swsp(sp)");
1831       break;
1832     case RO_C_SDSP:
1833       Format(instr, "sd        'Crs2, 'Cimm6Sdsp(sp)");
1834       break;
1835     case RO_C_FSDSP:
1836       Format(instr, "fsd       'Cfs2, 'Cimm6Sdsp(sp)");
1837       break;
1838     default:
1839       UNSUPPORTED_RISCV();
1840   }
1841 }
1842 
DecodeCLType(Instruction * instr)1843 void Decoder::DecodeCLType(Instruction* instr) {
1844   switch (instr->RvcOpcode()) {
1845     case RO_C_FLD:
1846       Format(instr, "fld       'Cfs2s, 'Cimm5D('Crs1s)");
1847       break;
1848     case RO_C_LW:
1849       Format(instr, "lw       'Crs2s, 'Cimm5W('Crs1s)");
1850       break;
1851     case RO_C_LD:
1852       Format(instr, "ld       'Crs2s, 'Cimm5D('Crs1s)");
1853       break;
1854     default:
1855       UNSUPPORTED_RISCV();
1856   }
1857 }
1858 
DecodeCSType(Instruction * instr)1859 void Decoder::DecodeCSType(Instruction* instr) {
1860   switch (instr->RvcOpcode()) {
1861     case RO_C_FSD:
1862       Format(instr, "fsd       'Cfs2s, 'Cimm5D('Crs1s)");
1863       break;
1864     case RO_C_SW:
1865       Format(instr, "sw       'Crs2s, 'Cimm5W('Crs1s)");
1866       break;
1867     case RO_C_SD:
1868       Format(instr, "sd       'Crs2s, 'Cimm5D('Crs1s)");
1869       break;
1870     default:
1871       UNSUPPORTED_RISCV();
1872   }
1873 }
1874 
DecodeCJType(Instruction * instr)1875 void Decoder::DecodeCJType(Instruction* instr) {
1876   switch (instr->RvcOpcode()) {
1877     case RO_C_J:
1878       Format(instr, "j       'Cimm11CJ");
1879       break;
1880     default:
1881       UNSUPPORTED_RISCV();
1882   }
1883 }
1884 
DecodeCBType(Instruction * instr)1885 void Decoder::DecodeCBType(Instruction* instr) {
1886   switch (instr->RvcOpcode()) {
1887     case RO_C_BNEZ:
1888       Format(instr, "bnez       'Crs1s, x0, 'Cimm8B");
1889       break;
1890     case RO_C_BEQZ:
1891       Format(instr, "beqz       'Crs1s, x0, 'Cimm8B");
1892       break;
1893     case RO_C_MISC_ALU:
1894       if (instr->RvcFunct2BValue() == 0b00)
1895         Format(instr, "srli       'Crs1s, 'Crs1s, 'Cshamt");
1896       else if (instr->RvcFunct2BValue() == 0b01)
1897         Format(instr, "srai       'Crs1s, 'Crs1s, 'Cshamt");
1898       else if (instr->RvcFunct2BValue() == 0b10)
1899         Format(instr, "andi       'Crs1s, 'Crs1s, 'Cimm6");
1900       else
1901         UNSUPPORTED_RISCV();
1902       break;
1903     default:
1904       UNSUPPORTED_RISCV();
1905   }
1906 }
1907 
DecodeRvvIVV(Instruction * instr)1908 void Decoder::DecodeRvvIVV(Instruction* instr) {
1909   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVV);
1910   switch (instr->InstructionBits() & kVTypeMask) {
1911     case RO_V_VADD_VV:
1912       Format(instr, "vadd.vv   'vd, 'vs2, 'vs1'vm");
1913       break;
1914     case RO_V_VSADD_VV:
1915       Format(instr, "vsadd.vv  'vd, 'vs2, 'vs1'vm");
1916       break;
1917     case RO_V_VSADDU_VV:
1918       Format(instr, "vsaddu.vv 'vd, 'vs2, 'vs1'vm");
1919       break;
1920     case RO_V_VSUB_VV:
1921       Format(instr, "vsub.vv   'vd, 'vs2, 'vs1'vm");
1922       break;
1923     case RO_V_VSSUB_VV:
1924       Format(instr, "vssub.vv  'vd, 'vs2, 'vs1'vm");
1925       break;
1926     case RO_V_VSSUBU_VV:
1927       Format(instr, "vssubu.vv  'vd, 'vs2, 'vs1'vm");
1928       break;
1929     case RO_V_VMIN_VV:
1930       Format(instr, "vmin.vv   'vd, 'vs2, 'vs1'vm");
1931       break;
1932     case RO_V_VMINU_VV:
1933       Format(instr, "vminu.vv  'vd, 'vs2, 'vs1'vm");
1934       break;
1935     case RO_V_VMAX_VV:
1936       Format(instr, "vmax.vv   'vd, 'vs2, 'vs1'vm");
1937       break;
1938     case RO_V_VMAXU_VV:
1939       Format(instr, "vmaxu.vv  'vd, 'vs2, 'vs1'vm");
1940       break;
1941     case RO_V_VAND_VV:
1942       Format(instr, "vand.vv   'vd, 'vs2, 'vs1'vm");
1943       break;
1944     case RO_V_VOR_VV:
1945       Format(instr, "vor.vv    'vd, 'vs2, 'vs1'vm");
1946       break;
1947     case RO_V_VXOR_VV:
1948       Format(instr, "vxor.vv   'vd, 'vs2, 'vs1'vm");
1949       break;
1950     case RO_V_VRGATHER_VV:
1951       Format(instr, "vrgather.vv 'vd, 'vs2, 'vs1'vm");
1952       break;
1953     case RO_V_VMSEQ_VV:
1954       Format(instr, "vmseq.vv  'vd, 'vs2, 'vs1'vm");
1955       break;
1956     case RO_V_VMSNE_VV:
1957       Format(instr, "vmsne.vv  'vd, 'vs2, 'vs1'vm");
1958       break;
1959     case RO_V_VMSLT_VV:
1960       Format(instr, "vmslt.vv  'vd, 'vs2, 'vs1'vm");
1961       break;
1962     case RO_V_VMSLTU_VV:
1963       Format(instr, "vmsltu.vv 'vd, 'vs2, 'vs1'vm");
1964       break;
1965     case RO_V_VMSLE_VV:
1966       Format(instr, "vmsle.vv  'vd, 'vs2, 'vs1'vm");
1967       break;
1968     case RO_V_VMSLEU_VV:
1969       Format(instr, "vmsleu.vv 'vd, 'vs2, 'vs1'vm");
1970       break;
1971     case RO_V_VMV_VV:
1972       if (instr->RvvVM()) {
1973         Format(instr, "vmv.vv    'vd, 'vs1");
1974       } else {
1975         Format(instr, "vmerge.vvm 'vd, 'vs2, 'vs1, v0");
1976       }
1977       break;
1978     case RO_V_VADC_VV:
1979       if (!instr->RvvVM()) {
1980         Format(instr, "vadc.vvm  'vd, 'vs2, 'vs1");
1981       } else {
1982         UNREACHABLE();
1983       }
1984       break;
1985     case RO_V_VMADC_VV:
1986       if (!instr->RvvVM()) {
1987         Format(instr, "vmadc.vvm 'vd, 'vs2, 'vs1");
1988       } else {
1989         UNREACHABLE();
1990       }
1991       break;
1992     case RO_V_VNCLIP_WV:
1993       Format(instr, "vnclip.wv 'vd, 'vs2, 'vs1");
1994       break;
1995     case RO_V_VNCLIPU_WV:
1996       Format(instr, "vnclipu.wv 'vd, 'vs2, 'vs1");
1997       break;
1998     case RO_V_VSLL_VV:
1999       Format(instr, "vsll.vv   'vd, 'vs2, 'vs1");
2000       break;
2001     case RO_V_VSRL_VV:
2002       Format(instr, "vsrl.vv   'vd, 'vs2, 'vs1");
2003       break;
2004     case RO_V_VSRA_VV:
2005       Format(instr, "vsra.vv   'vd, 'vs2, 'vs1");
2006       break;
2007     case RO_V_VSMUL_VV:
2008       Format(instr, "vsmul.vv  'vd, 'vs2, 'vs1");
2009       break;
2010     default:
2011       UNSUPPORTED_RISCV();
2012       break;
2013   }
2014 }
2015 
DecodeRvvIVI(Instruction * instr)2016 void Decoder::DecodeRvvIVI(Instruction* instr) {
2017   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVI);
2018   switch (instr->InstructionBits() & kVTypeMask) {
2019     case RO_V_VADD_VI:
2020       Format(instr, "vadd.vi   'vd, 'vs2, 'simm5'vm");
2021       break;
2022     case RO_V_VSADD_VI:
2023       Format(instr, "vsadd.vi  'vd, 'vs2, 'simm5'vm");
2024       break;
2025     case RO_V_VSADDU_VI:
2026       Format(instr, "vsaddu.vi 'vd, 'vs2, 'simm5'vm");
2027       break;
2028     case RO_V_VRSUB_VI:
2029       Format(instr, "vrsub.vi  'vd, 'vs2, 'simm5'vm");
2030       break;
2031     case RO_V_VAND_VI:
2032       Format(instr, "vand.vi   'vd, 'vs2, 'simm5'vm");
2033       break;
2034     case RO_V_VOR_VI:
2035       Format(instr, "vor.vi    'vd, 'vs2, 'simm5'vm");
2036       break;
2037     case RO_V_VXOR_VI:
2038       Format(instr, "vxor.vi   'vd, 'vs2, 'simm5'vm");
2039       break;
2040     case RO_V_VRGATHER_VI:
2041       Format(instr, "vrgather.vi  'vd, 'vs2, 'simm5'vm");
2042       break;
2043     case RO_V_VMV_VI:
2044       if (instr->RvvVM()) {
2045         Format(instr, "vmv.vi    'vd, 'simm5");
2046       } else {
2047         Format(instr, "vmerge.vim 'vd, 'vs2, 'simm5, v0");
2048       }
2049       break;
2050     case RO_V_VMSEQ_VI:
2051       Format(instr, "vmseq.vi  'vd, 'vs2, 'simm5'vm");
2052       break;
2053     case RO_V_VMSNE_VI:
2054       Format(instr, "vmsne.vi  'vd, 'vs2, 'simm5'vm");
2055       break;
2056     case RO_V_VMSLEU_VI:
2057       Format(instr, "vmsleu.vi 'vd, 'vs2, 'simm5'vm");
2058       break;
2059     case RO_V_VMSLE_VI:
2060       Format(instr, "vmsle.vi  'vd, 'vs2, 'simm5'vm");
2061       break;
2062     case RO_V_VMSGTU_VI:
2063       Format(instr, "vmsgtu.vi 'vd, 'vs2, 'simm5'vm");
2064       break;
2065     case RO_V_VMSGT_VI:
2066       Format(instr, "vmsgt.vi  'vd, 'vs2, 'simm5'vm");
2067       break;
2068     case RO_V_VSLIDEDOWN_VI:
2069       Format(instr, "vslidedown.vi 'vd, 'vs2, 'uimm5'vm");
2070       break;
2071     case RO_V_VSLIDEUP_VI:
2072       Format(instr, "vslideup.vi   'vd, 'vs2, 'uimm5'vm");
2073       break;
2074     case RO_V_VSRL_VI:
2075       Format(instr, "vsrl.vi   'vd, 'vs2, 'uimm5'vm");
2076       break;
2077     case RO_V_VSRA_VI:
2078       Format(instr, "vsra.vi   'vd, 'vs2, 'uimm5'vm");
2079       break;
2080     case RO_V_VSLL_VI:
2081       Format(instr, "vsll.vi   'vd, 'vs2, 'uimm5'vm");
2082       break;
2083     case RO_V_VADC_VI:
2084       if (!instr->RvvVM()) {
2085         Format(instr, "vadc.vim  'vd, 'vs2, 'uimm5");
2086       } else {
2087         UNREACHABLE();
2088       }
2089       break;
2090     case RO_V_VMADC_VI:
2091       if (!instr->RvvVM()) {
2092         Format(instr, "vmadc.vim 'vd, 'vs2, 'uimm5");
2093       } else {
2094         UNREACHABLE();
2095       }
2096       break;
2097     case RO_V_VNCLIP_WI:
2098       Format(instr, "vnclip.wi 'vd, 'vs2, 'uimm5");
2099       break;
2100     case RO_V_VNCLIPU_WI:
2101       Format(instr, "vnclipu.wi 'vd, 'vs2, 'uimm5");
2102       break;
2103     default:
2104       UNSUPPORTED_RISCV();
2105       break;
2106   }
2107 }
2108 
DecodeRvvIVX(Instruction * instr)2109 void Decoder::DecodeRvvIVX(Instruction* instr) {
2110   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_IVX);
2111   switch (instr->InstructionBits() & kVTypeMask) {
2112     case RO_V_VADD_VX:
2113       Format(instr, "vadd.vx   'vd, 'vs2, 'rs1'vm");
2114       break;
2115     case RO_V_VSADD_VX:
2116       Format(instr, "vsadd.vx  'vd, 'vs2, 'rs1'vm");
2117       break;
2118     case RO_V_VSADDU_VX:
2119       Format(instr, "vsaddu.vx 'vd, 'vs2, 'rs1'vm");
2120       break;
2121     case RO_V_VSUB_VX:
2122       Format(instr, "vsub.vx   'vd, 'vs2, 'rs1'vm");
2123       break;
2124     case RO_V_VSSUB_VX:
2125       Format(instr, "vssub.vx  'vd, 'vs2, 'rs1'vm");
2126       break;
2127     case RO_V_VRSUB_VX:
2128       Format(instr, "vrsub.vx  'vd, 'vs2, 'rs1'vm");
2129       break;
2130     case RO_V_VMIN_VX:
2131       Format(instr, "vmin.vx   'vd, 'vs2, 'rs1'vm");
2132       break;
2133     case RO_V_VMINU_VX:
2134       Format(instr, "vminu.vx  'vd, 'vs2, 'rs1'vm");
2135       break;
2136     case RO_V_VMAX_VX:
2137       Format(instr, "vmax.vx   'vd, 'vs2, 'rs1'vm");
2138       break;
2139     case RO_V_VMAXU_VX:
2140       Format(instr, "vmaxu.vx  'vd, 'vs2, 'rs1'vm");
2141       break;
2142     case RO_V_VAND_VX:
2143       Format(instr, "vand.vx   'vd, 'vs2, 'rs1'vm");
2144       break;
2145     case RO_V_VOR_VX:
2146       Format(instr, "vor.vx    'vd, 'vs2, 'rs1'vm");
2147       break;
2148     case RO_V_VXOR_VX:
2149       Format(instr, "vxor.vx   'vd, 'vs2, 'rs1'vm");
2150       break;
2151     case RO_V_VRGATHER_VX:
2152       Format(instr, "vrgather.vx   'vd, 'vs2, 'rs1'vm");
2153       break;
2154     case RO_V_VMV_VX:
2155       if (instr->RvvVM()) {
2156         Format(instr, "vmv.vx    'vd, 'rs1");
2157       } else {
2158         Format(instr, "vmerge.vxm 'vd, 'vs2, 'rs1, v0");
2159       }
2160       break;
2161     case RO_V_VMSEQ_VX:
2162       Format(instr, "vmseq.vx  'vd, 'vs2, 'rs1'vm");
2163       break;
2164     case RO_V_VMSNE_VX:
2165       Format(instr, "vmsne.vx  'vd, 'vs2, 'rs1'vm");
2166       break;
2167     case RO_V_VMSLT_VX:
2168       Format(instr, "vmslt.vx  'vd, 'vs2, 'rs1'vm");
2169       break;
2170     case RO_V_VMSLTU_VX:
2171       Format(instr, "vmsltu.vx 'vd, 'vs2, 'rs1'vm");
2172       break;
2173     case RO_V_VMSLE_VX:
2174       Format(instr, "vmsle.vx  'vd, 'vs2, 'rs1'vm");
2175       break;
2176     case RO_V_VMSLEU_VX:
2177       Format(instr, "vmsleu.vx 'vd, 'vs2, 'rs1'vm");
2178       break;
2179     case RO_V_VMSGT_VX:
2180       Format(instr, "vmsgt.vx  'vd, 'vs2, 'rs1'vm");
2181       break;
2182     case RO_V_VMSGTU_VX:
2183       Format(instr, "vmsgtu.vx 'vd, 'vs2, 'rs1'vm");
2184       break;
2185     case RO_V_VSLIDEDOWN_VX:
2186       Format(instr, "vslidedown.vx 'vd, 'vs2, 'rs1'vm");
2187       break;
2188     case RO_V_VADC_VX:
2189       if (!instr->RvvVM()) {
2190         Format(instr, "vadc.vxm  'vd, 'vs2, 'rs1");
2191       } else {
2192         UNREACHABLE();
2193       }
2194       break;
2195     case RO_V_VMADC_VX:
2196       if (!instr->RvvVM()) {
2197         Format(instr, "vmadc.vxm 'vd, 'vs2, 'rs1");
2198       } else {
2199         UNREACHABLE();
2200       }
2201       break;
2202     case RO_V_VSLL_VX:
2203       Format(instr, "vsll.vx  'vd, 'vs2, 'rs1");
2204       break;
2205     case RO_V_VSRL_VX:
2206       Format(instr, "vsrl.vx  'vd, 'vs2, 'rs1");
2207       break;
2208     case RO_V_VSRA_VX:
2209       Format(instr, "vsra.vx  'vd, 'vs2, 'rs1");
2210       break;
2211     case RO_V_VNCLIP_WX:
2212       Format(instr, "vnclip.wx 'vd, 'vs2, 'rs1");
2213       break;
2214     case RO_V_VNCLIPU_WX:
2215       Format(instr, "vnclipu.wx 'vd, 'vs2, 'rs1");
2216       break;
2217     case RO_V_VSMUL_VX:
2218       Format(instr, "vsmul.vx  'vd, 'vs2, 'vs1");
2219       break;
2220     default:
2221       UNSUPPORTED_RISCV();
2222       break;
2223   }
2224 }
2225 
DecodeRvvMVV(Instruction * instr)2226 void Decoder::DecodeRvvMVV(Instruction* instr) {
2227   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_MVV);
2228   switch (instr->InstructionBits() & kVTypeMask) {
2229     case RO_V_VMUNARY0: {
2230       if (instr->Vs1Value() == VID_V) {
2231         Format(instr, "vid.v   'rd, 'vs2'vm");
2232       } else {
2233         UNSUPPORTED_RISCV();
2234       }
2235       break;
2236     }
2237     case RO_V_VWXUNARY0:
2238       if (instr->Vs1Value() == 0x0) {
2239         Format(instr, "vmv.x.s   'rd, 'vs2");
2240       } else if (instr->Vs1Value() == 0b10001) {
2241         Format(instr, "vfirst.m  'rd, 'vs2");
2242       } else if (instr->Vs1Value() == 0b10000) {
2243         Format(instr, "vcpop.m   'rd, 'vs2");
2244       } else {
2245         UNSUPPORTED_RISCV();
2246       }
2247       break;
2248     case RO_V_VREDMAXU:
2249       Format(instr, "vredmaxu.vs  'vd, 'vs2, 'vs1'vm");
2250       break;
2251     case RO_V_VREDMAX:
2252       Format(instr, "vredmax.vs  'vd, 'vs2, 'vs1'vm");
2253       break;
2254     case RO_V_VREDMIN:
2255       Format(instr, "vredmin.vs  'vd, 'vs2, 'vs1'vm");
2256       break;
2257     case RO_V_VREDMINU:
2258       Format(instr, "vredminu.vs  'vd, 'vs2, 'vs1'vm");
2259       break;
2260     case RO_V_VXUNARY0:
2261       if (instr->Vs1Value() == 0b00010) {
2262         Format(instr, "vzext.vf8 'vd, 'vs2'vm");
2263       } else if (instr->Vs1Value() == 0b00011) {
2264         Format(instr, "vsext.vf8 'vd, 'vs2'vm");
2265       } else if (instr->Vs1Value() == 0b00100) {
2266         Format(instr, "vzext.vf4 'vd, 'vs2'vm");
2267       } else if (instr->Vs1Value() == 0b00101) {
2268         Format(instr, "vsext.vf4 'vd, 'vs2'vm");
2269       } else if (instr->Vs1Value() == 0b00110) {
2270         Format(instr, "vzext.vf2 'vd, 'vs2'vm");
2271       } else if (instr->Vs1Value() == 0b00111) {
2272         Format(instr, "vsext.vf2 'vd, 'vs2'vm");
2273       } else {
2274         UNSUPPORTED_RISCV();
2275       }
2276       break;
2277     case RO_V_VWMUL_VV:
2278       Format(instr, "vwmul.vv   'vd, 'vs2, 'vs1'vm");
2279       break;
2280     case RO_V_VWMULU_VV:
2281       Format(instr, "vwmulu.vv   'vd, 'vs2, 'vs1'vm");
2282       break;
2283     case RO_V_VMUL_VV:
2284       Format(instr, "vmul.vv   'vd, 'vs2, 'vs1'vm");
2285       break;
2286     case RO_V_VMULHU_VV:
2287       Format(instr, "vmulhu.vv   'vd, 'vs2, 'vs1'vm");
2288       break;
2289     case RO_V_VDIV_VV:
2290       Format(instr, "vdiv.vv   'vd, 'vs2, 'vs1'vm");
2291       break;
2292     case RO_V_VDIVU_VV:
2293       Format(instr, "vdivu.vv   'vd, 'vs2, 'vs1'vm");
2294       break;
2295     case RO_V_VWADDU_VV:
2296       Format(instr, "vwaddu.vv  'vd, 'vs2, 'vs1'vm");
2297       break;
2298     case RO_V_VWADD_VV:
2299       Format(instr, "vwadd.vv  'vd, 'vs2, 'vs1'vm");
2300       break;
2301     case RO_V_VCOMPRESS_VV:
2302       Format(instr, "vcompress.vm 'vd, 'vs2, 'vs1'vm");
2303       break;
2304     default:
2305       UNSUPPORTED_RISCV();
2306       break;
2307   }
2308 }
2309 
DecodeRvvMVX(Instruction * instr)2310 void Decoder::DecodeRvvMVX(Instruction* instr) {
2311   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_MVX);
2312   switch (instr->InstructionBits() & kVTypeMask) {
2313     case RO_V_VRXUNARY0:
2314       if (instr->Vs2Value() == 0x0) {
2315         Format(instr, "vmv.s.x   'vd, 'rs1");
2316       } else {
2317         UNSUPPORTED_RISCV();
2318       }
2319       break;
2320     case RO_V_VWMUL_VX:
2321       Format(instr, "vwmul.vx   'vd, 'vs2, 'rs1'vm");
2322       break;
2323     case RO_V_VWMULU_VX:
2324       Format(instr, "vwmulu.vx   'vd, 'vs2, 'rs1'vm");
2325       break;
2326     case RO_V_VMUL_VX:
2327       Format(instr, "vmul.vx   'vd, 'vs2, 'rs1'vm");
2328       break;
2329     case RO_V_VMULHU_VX:
2330       Format(instr, "vmulhu.vx 'vd, 'vs2, 'rs1'vm");
2331       break;
2332     case RO_V_VDIV_VX:
2333       Format(instr, "vdiv.vx   'vd, 'vs2, 'rs1'vm");
2334       break;
2335     case RO_V_VDIVU_VX:
2336       Format(instr, "vdivu.vx  'vd, 'vs2, 'rs1'vm");
2337       break;
2338     case RO_V_VWADDUW_VX:
2339       Format(instr, "vwaddu.wx 'vd, 'vs2, 'rs1'vm");
2340       break;
2341     case RO_V_VWADDU_VX:
2342       Format(instr, "vwaddu.vx 'vd, 'vs2, 'rs1'vm");
2343       break;
2344     case RO_V_VWADD_VX:
2345       Format(instr, "vwadd.vx 'vd, 'vs2, 'rs1'vm");
2346       break;
2347     default:
2348       UNSUPPORTED_RISCV();
2349       break;
2350   }
2351 }
2352 
DecodeRvvFVV(Instruction * instr)2353 void Decoder::DecodeRvvFVV(Instruction* instr) {
2354   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_FVV);
2355   switch (instr->InstructionBits() & kVTypeMask) {
2356     case RO_V_VFUNARY0:
2357       switch (instr->Vs1Value()) {
2358         case VFCVT_XU_F_V:
2359           Format(instr, "vfcvt.xu.f.v  'vd, 'vs2'vm");
2360           break;
2361         case VFCVT_X_F_V:
2362           Format(instr, "vfcvt.x.f.v   'vd, 'vs2'vm");
2363           break;
2364         case VFNCVT_F_F_W:
2365           Format(instr, "vfncvt.f.f.w  'vd, 'vs2'vm");
2366           break;
2367         case VFNCVT_X_F_W:
2368           Format(instr, "vfncvt.x.f.w  'vd, 'vs2'vm");
2369           break;
2370         case VFNCVT_XU_F_W:
2371           Format(instr, "vfncvt.xu.f.w  'vd, 'vs2'vm");
2372           break;
2373         case VFCVT_F_X_V:
2374           Format(instr, "vfcvt.f.x.v   'vd, 'vs2'vm");
2375           break;
2376         case VFCVT_F_XU_V:
2377           Format(instr, "vfcvt.f.xu.v  'vd, 'vs2'vm");
2378           break;
2379         case VFWCVT_XU_F_V:
2380           Format(instr, "vfwcvt.xu.f.v  'vd, 'vs2'vm");
2381           break;
2382         case VFWCVT_X_F_V:
2383           Format(instr, "vfwcvt.x.f.v   'vd, 'vs2'vm");
2384           break;
2385         case VFWCVT_F_X_V:
2386           Format(instr, "vfwcvt.f.x.v   'vd, 'vs2'vm");
2387           break;
2388         case VFWCVT_F_XU_V:
2389           Format(instr, "vfwcvt.f.xu.v  'vd, 'vs2'vm");
2390           break;
2391         case VFWCVT_F_F_V:
2392           Format(instr, "vfwcvt.f.f.v  'vd, 'vs2'vm");
2393           break;
2394         default:
2395           UNSUPPORTED_RISCV();
2396           break;
2397       }
2398       break;
2399     case RO_V_VFUNARY1:
2400       switch (instr->Vs1Value()) {
2401         case VFCLASS_V:
2402           Format(instr, "vfclass.v  'vd, 'vs2'vm");
2403           break;
2404         case VFSQRT_V:
2405           Format(instr, "vfsqrt.v  'vd, 'vs2'vm");
2406           break;
2407         case VFRSQRT7_V:
2408           Format(instr, "vfrsqrt7.v 'vd, 'vs2'vm");
2409           break;
2410         case VFREC7_V:
2411           Format(instr, "vfrec7.v  'vd, 'vs2'vm");
2412           break;
2413         default:
2414           break;
2415       }
2416       break;
2417     case RO_V_VMFEQ_VV:
2418       Format(instr, "vmfeq.vv  'vd, 'vs2, 'vs1'vm");
2419       break;
2420     case RO_V_VMFNE_VV:
2421       Format(instr, "vmfne.vv  'vd, 'vs2, 'vs1'vm");
2422       break;
2423     case RO_V_VMFLT_VV:
2424       Format(instr, "vmflt.vv  'vd, 'vs2, 'vs1'vm");
2425       break;
2426     case RO_V_VMFLE_VV:
2427       Format(instr, "vmfle.vv  'vd, 'vs2, 'vs1'vm");
2428       break;
2429     case RO_V_VFMAX_VV:
2430       Format(instr, "vfmax.vv  'vd, 'vs2, 'vs1'vm");
2431       break;
2432     case RO_V_VFREDMAX_VV:
2433       Format(instr, "vfredmax.vs 'vd, 'vs2, 'vs1'vm");
2434       break;
2435     case RO_V_VFMIN_VV:
2436       Format(instr, "vfmin.vv  'vd, 'vs2, 'vs1'vm");
2437       break;
2438     case RO_V_VFSGNJ_VV:
2439       Format(instr, "vfsgnj.vv   'vd, 'vs2, 'vs1'vm");
2440       break;
2441     case RO_V_VFSGNJN_VV:
2442       if (instr->Vs1Value() == instr->Vs2Value()) {
2443         Format(instr, "vneg.vv   'vd, 'vs1'vm");
2444       } else {
2445         Format(instr, "vfsgnjn.vv   'vd, 'vs2, 'vs1'vm");
2446       }
2447       break;
2448     case RO_V_VFSGNJX_VV:
2449       if (instr->Vs1Value() == instr->Vs2Value()) {
2450         Format(instr, "vabs.vv   'vd, 'vs1'vm");
2451       } else {
2452         Format(instr, "vfsgnjn.vv   'vd, 'vs2, 'vs1'vm");
2453       }
2454       break;
2455     case RO_V_VFADD_VV:
2456       Format(instr, "vfadd.vv  'vd, 'vs2, 'vs1'vm");
2457       break;
2458     case RO_V_VFSUB_VV:
2459       Format(instr, "vfsub.vv  'vd, 'vs2, 'vs1'vm");
2460       break;
2461     case RO_V_VFDIV_VV:
2462       Format(instr, "vfdiv.vv  'vd, 'vs2, 'vs1'vm");
2463       break;
2464     case RO_V_VFMUL_VV:
2465       Format(instr, "vfmul.vv  'vd, 'vs2, 'vs1'vm");
2466       break;
2467     case RO_V_VFMADD_VV:
2468       Format(instr, "vfmadd.vv 'vd, 'vs1, 'vs2'vm");
2469       break;
2470     case RO_V_VFNMADD_VV:
2471       Format(instr, "vfnmadd.vv 'vd, 'vs1, 'vs2'vm");
2472       break;
2473     case RO_V_VFMSUB_VV:
2474       Format(instr, "vfmsub.vv 'vd, 'vs1, 'vs2'vm");
2475       break;
2476     case RO_V_VFNMSUB_VV:
2477       Format(instr, "vfnmsub.vv 'vd, 'vs1, 'vs2'vm");
2478       break;
2479     case RO_V_VFMACC_VV:
2480       Format(instr, "vfmacc.vv 'vd, 'vs1, 'vs2'vm");
2481       break;
2482     case RO_V_VFNMACC_VV:
2483       Format(instr, "vfnmacc.vv 'vd, 'vs1, 'vs2'vm");
2484       break;
2485     case RO_V_VFMSAC_VV:
2486       Format(instr, "vfmsac.vv 'vd, 'vs1, 'vs2'vm");
2487       break;
2488     case RO_V_VFNMSAC_VV:
2489       Format(instr, "vfnmsac.vv 'vd, 'vs1, 'vs2'vm");
2490       break;
2491     case RO_V_VFMV_FS:
2492       if (instr->Vs1Value() == 0x0) {
2493         Format(instr, "vfmv.f.s  'fd, 'vs2");
2494       } else {
2495         UNSUPPORTED_RISCV();
2496       }
2497       break;
2498     case RO_V_VFWADD_VV:
2499       Format(instr, "vfwadd.vv 'vd, 'vs2, 'vs1'vm");
2500       break;
2501     case RO_V_VFWSUB_VV:
2502       Format(instr, "vfwsub.vv 'vd, 'vs2, 'vs1'vm");
2503       break;
2504     case RO_V_VFWADD_W_VV:
2505       Format(instr, "vfwadd.wv 'vd, 'vs2, 'vs1'vm");
2506       break;
2507     case RO_V_VFWSUB_W_VV:
2508       Format(instr, "vfwsub.wv 'vd, 'vs2, 'vs1'vm");
2509       break;
2510     case RO_V_VFWREDUSUM_VV:
2511       Format(instr, "vfwredusum.vs 'vd, 'vs2, 'vs1'vm");
2512       break;
2513     case RO_V_VFWREDOSUM_VV:
2514       Format(instr, "vfwredosum.vs 'vd, 'vs2, 'vs1'vm");
2515       break;
2516     case RO_V_VFWMUL_VV:
2517       Format(instr, "vfwmul.vv 'vd, 'vs2, 'vs1'vm");
2518       break;
2519     case RO_V_VFWMACC_VV:
2520       Format(instr, "vfwmacc.vv 'vd, 'vs1, 'vs2'vm");
2521       break;
2522     case RO_V_VFWNMACC_VV:
2523       Format(instr, "vfwnmacc.vv 'vd, 'vs1, 'vs2'vm");
2524       break;
2525     case RO_V_VFWMSAC_VV:
2526       Format(instr, "vfwmsac.vv 'vd, 'vs1, 'vs2'vm");
2527       break;
2528     case RO_V_VFWNMSAC_VV:
2529       Format(instr, "vfwnmsac.vv 'vd, 'vs1, 'vs2'vm");
2530       break;
2531     default:
2532       UNSUPPORTED_RISCV();
2533       break;
2534   }
2535 }
2536 
DecodeRvvFVF(Instruction * instr)2537 void Decoder::DecodeRvvFVF(Instruction* instr) {
2538   DCHECK_EQ(instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask), OP_FVF);
2539   switch (instr->InstructionBits() & kVTypeMask) {
2540     case RO_V_VFSGNJ_VF:
2541       Format(instr, "vfsgnj.vf   'vd, 'vs2, 'fs1'vm");
2542       break;
2543     case RO_V_VFSGNJN_VF:
2544       Format(instr, "vfsgnjn.vf   'vd, 'vs2, 'fs1'vm");
2545       break;
2546     case RO_V_VFSGNJX_VF:
2547       Format(instr, "vfsgnjn.vf   'vd, 'vs2, 'fs1'vm");
2548       break;
2549     case RO_V_VFMV_VF:
2550       Format(instr, "vfmv.v.f  'vd, 'fs1");
2551       break;
2552     case RO_V_VFMADD_VF:
2553       Format(instr, "vfmadd.vf 'vd, 'fs1, 'vs2'vm");
2554       break;
2555     case RO_V_VFNMADD_VF:
2556       Format(instr, "vfnmadd.vf 'vd, 'fs1, 'vs2'vm");
2557       break;
2558     case RO_V_VFMSUB_VF:
2559       Format(instr, "vfmsub.vf 'vd, 'fs1, 'vs2'vm");
2560       break;
2561     case RO_V_VFNMSUB_VF:
2562       Format(instr, "vfnmsub.vf 'vd, 'fs1, 'vs2'vm");
2563       break;
2564     case RO_V_VFMACC_VF:
2565       Format(instr, "vfmacc.vf 'vd, 'fs1, 'vs2'vm");
2566       break;
2567     case RO_V_VFNMACC_VF:
2568       Format(instr, "vfnmacc.vf 'vd, 'fs1, 'vs2'vm");
2569       break;
2570     case RO_V_VFMSAC_VF:
2571       Format(instr, "vfmsac.vf 'vd, 'fs1, 'vs2'vm");
2572       break;
2573     case RO_V_VFNMSAC_VF:
2574       Format(instr, "vfnmsac.vf 'vd, 'fs1, 'vs2'vm");
2575       break;
2576     case RO_V_VFWADD_VF:
2577       Format(instr, "vfwadd.vf 'vd, 'vs2, 'fs1'vm");
2578       break;
2579     case RO_V_VFWSUB_VF:
2580       Format(instr, "vfwsub.vf 'vd, 'vs2, 'fs1'vm");
2581       break;
2582     case RO_V_VFWADD_W_VF:
2583       Format(instr, "vfwadd.wf 'vd, 'vs2, 'fs1'vm");
2584       break;
2585     case RO_V_VFWSUB_W_VF:
2586       Format(instr, "vfwsub.wf 'vd, 'vs2, 'fs1'vm");
2587       break;
2588     case RO_V_VFWMUL_VF:
2589       Format(instr, "vfwmul.vf 'vd, 'vs2, 'fs1'vm");
2590       break;
2591     case RO_V_VFWMACC_VF:
2592       Format(instr, "vfwmacc.vf 'vd, 'fs1, 'vs2'vm");
2593       break;
2594     case RO_V_VFWNMACC_VF:
2595       Format(instr, "vfwnmacc.vf 'vd, 'fs1, 'vs2'vm");
2596       break;
2597     case RO_V_VFWMSAC_VF:
2598       Format(instr, "vfwmsac.vf 'vd, 'fs1, 'vs2'vm");
2599       break;
2600     case RO_V_VFWNMSAC_VF:
2601       Format(instr, "vfwnmsac.vf 'vd, 'fs1, 'vs2'vm");
2602       break;
2603     default:
2604       UNSUPPORTED_RISCV();
2605       break;
2606   }
2607 }
2608 
DecodeVType(Instruction * instr)2609 void Decoder::DecodeVType(Instruction* instr) {
2610   switch (instr->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask)) {
2611     case OP_IVV:
2612       DecodeRvvIVV(instr);
2613       return;
2614     case OP_FVV:
2615       DecodeRvvFVV(instr);
2616       return;
2617     case OP_MVV:
2618       DecodeRvvMVV(instr);
2619       return;
2620     case OP_IVI:
2621       DecodeRvvIVI(instr);
2622       return;
2623     case OP_IVX:
2624       DecodeRvvIVX(instr);
2625       return;
2626     case OP_FVF:
2627       DecodeRvvFVF(instr);
2628       return;
2629     case OP_MVX:
2630       DecodeRvvMVX(instr);
2631       return;
2632   }
2633   switch (instr->InstructionBits() &
2634           (kBaseOpcodeMask | kFunct3Mask | 0x80000000)) {
2635     case RO_V_VSETVLI:
2636       Format(instr, "vsetvli   'rd, 'rs1, 'sew, 'lmul");
2637       break;
2638     case RO_V_VSETVL:
2639       if (!(instr->InstructionBits() & 0x40000000)) {
2640         Format(instr, "vsetvl    'rd, 'rs1,  'rs2");
2641       } else {
2642         Format(instr, "vsetivli  'rd, 'uimm, 'sew, 'lmul");
2643       }
2644       break;
2645     default:
2646       UNSUPPORTED_RISCV();
2647       break;
2648   }
2649 }
switch_nf(Instruction * instr)2650 int Decoder::switch_nf(Instruction* instr) {
2651   int nf = 0;
2652   switch (instr->InstructionBits() & kRvvNfMask) {
2653     case 0x20000000:
2654       nf = 2;
2655       break;
2656     case 0x40000000:
2657       nf = 3;
2658       break;
2659     case 0x60000000:
2660       nf = 4;
2661       break;
2662     case 0x80000000:
2663       nf = 5;
2664       break;
2665     case 0xa0000000:
2666       nf = 6;
2667       break;
2668     case 0xc0000000:
2669       nf = 7;
2670       break;
2671     case 0xe0000000:
2672       nf = 8;
2673       break;
2674   }
2675   return nf;
2676 }
DecodeRvvVL(Instruction * instr)2677 void Decoder::DecodeRvvVL(Instruction* instr) {
2678   char str[50];
2679   uint32_t instr_temp =
2680       instr->InstructionBits() & (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask);
2681   // switch (instr->InstructionBits() &
2682   //      (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask)) {
2683   if (RO_V_VL == instr_temp) {
2684     if (!(instr->InstructionBits() & (kRvvRs2Mask))) {
2685       snprintf(str, sizeof(str), "vle%d.v       'vd, ('rs1)'vm",
2686                instr->vl_vs_width());
2687       Format(instr, str);
2688     } else {
2689       snprintf(str, sizeof(str), "vle%dff.v       'vd, ('rs1)'vm",
2690                instr->vl_vs_width());
2691       Format(instr, str);
2692     }
2693   } else if (RO_V_VLS == instr_temp) {
2694     snprintf(str, sizeof(str), "vlse%d.v       'vd, ('rs1), 'rs2'vm",
2695              instr->vl_vs_width());
2696     Format(instr, str);
2697 
2698   } else if (RO_V_VLX == instr_temp) {
2699     snprintf(str, sizeof(str), "vlxei%d.v       'vd, ('rs1), 'vs2'vm",
2700              instr->vl_vs_width());
2701     Format(instr, str);
2702   } else if (RO_V_VLSEG2 == instr_temp || RO_V_VLSEG3 == instr_temp ||
2703              RO_V_VLSEG4 == instr_temp || RO_V_VLSEG5 == instr_temp ||
2704              RO_V_VLSEG6 == instr_temp || RO_V_VLSEG7 == instr_temp ||
2705              RO_V_VLSEG8 == instr_temp) {
2706     if (!(instr->InstructionBits() & (kRvvRs2Mask))) {
2707       snprintf(str, sizeof(str), "vlseg%de%d.v       'vd, ('rs1)'vm",
2708                switch_nf(instr), instr->vl_vs_width());
2709     } else {
2710       snprintf(str, sizeof(str), "vlseg%de%dff.v       'vd, ('rs1)'vm",
2711                switch_nf(instr), instr->vl_vs_width());
2712     }
2713     Format(instr, str);
2714   } else if (RO_V_VLSSEG2 == instr_temp || RO_V_VLSSEG3 == instr_temp ||
2715              RO_V_VLSSEG4 == instr_temp || RO_V_VLSSEG5 == instr_temp ||
2716              RO_V_VLSSEG6 == instr_temp || RO_V_VLSSEG7 == instr_temp ||
2717              RO_V_VLSSEG8 == instr_temp) {
2718     snprintf(str, sizeof(str), "vlsseg%de%d.v       'vd, ('rs1), 'rs2'vm",
2719              switch_nf(instr), instr->vl_vs_width());
2720     Format(instr, str);
2721   } else if (RO_V_VLXSEG2 == instr_temp || RO_V_VLXSEG3 == instr_temp ||
2722              RO_V_VLXSEG4 == instr_temp || RO_V_VLXSEG5 == instr_temp ||
2723              RO_V_VLXSEG6 == instr_temp || RO_V_VLXSEG7 == instr_temp ||
2724              RO_V_VLXSEG8 == instr_temp) {
2725     snprintf(str, sizeof(str), "vlxseg%dei%d.v       'vd, ('rs1), 'vs2'vm",
2726              switch_nf(instr), instr->vl_vs_width());
2727     Format(instr, str);
2728   }
2729 }
2730 
switch_sew(Instruction * instr)2731 int Decoder::switch_sew(Instruction* instr) {
2732   int width = 0;
2733   if ((instr->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
2734       (instr->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
2735     return -1;
2736   switch (instr->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
2737     case 0x0:
2738       width = 8;
2739       break;
2740     case 0x00005000:
2741       width = 16;
2742       break;
2743     case 0x00006000:
2744       width = 32;
2745       break;
2746     case 0x00007000:
2747       width = 64;
2748       break;
2749     case 0x10000000:
2750       width = 128;
2751       break;
2752     case 0x10005000:
2753       width = 256;
2754       break;
2755     case 0x10006000:
2756       width = 512;
2757       break;
2758     case 0x10007000:
2759       width = 1024;
2760       break;
2761     default:
2762       width = -1;
2763       break;
2764   }
2765   return width;
2766 }
2767 
DecodeRvvVS(Instruction * instr)2768 void Decoder::DecodeRvvVS(Instruction* instr) {
2769   char str[50];
2770   uint32_t instr_temp =
2771       instr->InstructionBits() & (kRvvMopMask | kRvvNfMask | kBaseOpcodeMask);
2772   if (RO_V_VS == instr_temp) {
2773     snprintf(str, sizeof(str), "vse%d.v    'vd, ('rs1)'vm",
2774              instr->vl_vs_width());
2775     Format(instr, str);
2776   } else if (RO_V_VSS == instr_temp) {
2777     snprintf(str, sizeof(str), "vsse%d.v      'vd, ('rs1), 'rs2'vm",
2778              instr->vl_vs_width());
2779     Format(instr, str);
2780   } else if (RO_V_VSX == instr_temp) {
2781     snprintf(str, sizeof(str), "vsxei%d.v      'vd, ('rs1), 'vs2'vm",
2782              instr->vl_vs_width());
2783     Format(instr, str);
2784   } else if (RO_V_VSU == instr_temp) {
2785     snprintf(str, sizeof(str), "vsuxei%d.v      'vd, ('rs1), 'vs2'vm",
2786              instr->vl_vs_width());
2787     Format(instr, str);
2788   } else if (RO_V_VSSEG2 == instr_temp || RO_V_VSSEG3 == instr_temp ||
2789              RO_V_VSSEG4 == instr_temp || RO_V_VSSEG5 == instr_temp ||
2790              RO_V_VSSEG6 == instr_temp || RO_V_VSSEG7 == instr_temp ||
2791              RO_V_VSSEG8 == instr_temp) {
2792     snprintf(str, sizeof(str), "vsseg%de%d.v      'vd, ('rs1)'vm",
2793              switch_nf(instr), instr->vl_vs_width());
2794     Format(instr, str);
2795   } else if (RO_V_VSSSEG2 == instr_temp || RO_V_VSSSEG3 == instr_temp ||
2796              RO_V_VSSSEG4 == instr_temp || RO_V_VSSSEG5 == instr_temp ||
2797              RO_V_VSSSEG6 == instr_temp || RO_V_VSSSEG7 == instr_temp ||
2798              RO_V_VSSSEG8 == instr_temp) {
2799     snprintf(str, sizeof(str), "vssseg%de%d.v      'vd, ('rs1), 'rs2'vm",
2800              switch_nf(instr), instr->vl_vs_width());
2801     Format(instr, str);
2802   } else if (RO_V_VSXSEG2 == instr_temp || RO_V_VSXSEG3 == instr_temp ||
2803              RO_V_VSXSEG4 == instr_temp || RO_V_VSXSEG5 == instr_temp ||
2804              RO_V_VSXSEG6 == instr_temp || RO_V_VSXSEG7 == instr_temp ||
2805              RO_V_VSXSEG8 == instr_temp) {
2806     snprintf(str, sizeof(str), "vsxseg%dei%d.v      'vd, ('rs1), 'vs2'vm",
2807              switch_nf(instr), instr->vl_vs_width());
2808     Format(instr, str);
2809   }
2810 }
2811 
2812 // Disassemble the instruction at *instr_ptr into the output buffer.
2813 // All instructions are one word long, except for the simulator
2814 // pseudo-instruction stop(msg). For that one special case, we return
2815 // size larger than one kInstrSize.
InstructionDecode(byte * instr_ptr)2816 int Decoder::InstructionDecode(byte* instr_ptr) {
2817   Instruction* instr = Instruction::At(instr_ptr);
2818   // Print raw instruction bytes.
2819   out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_,
2820                                     "%08x       ", instr->InstructionBits());
2821   switch (instr->InstructionType()) {
2822     case Instruction::kRType:
2823       DecodeRType(instr);
2824       break;
2825     case Instruction::kR4Type:
2826       DecodeR4Type(instr);
2827       break;
2828     case Instruction::kIType:
2829       DecodeIType(instr);
2830       break;
2831     case Instruction::kSType:
2832       DecodeSType(instr);
2833       break;
2834     case Instruction::kBType:
2835       DecodeBType(instr);
2836       break;
2837     case Instruction::kUType:
2838       DecodeUType(instr);
2839       break;
2840     case Instruction::kJType:
2841       DecodeJType(instr);
2842       break;
2843     case Instruction::kCRType:
2844       DecodeCRType(instr);
2845       break;
2846     case Instruction::kCAType:
2847       DecodeCAType(instr);
2848       break;
2849     case Instruction::kCJType:
2850       DecodeCJType(instr);
2851       break;
2852     case Instruction::kCIType:
2853       DecodeCIType(instr);
2854       break;
2855     case Instruction::kCIWType:
2856       DecodeCIWType(instr);
2857       break;
2858     case Instruction::kCSSType:
2859       DecodeCSSType(instr);
2860       break;
2861     case Instruction::kCLType:
2862       DecodeCLType(instr);
2863       break;
2864     case Instruction::kCSType:
2865       DecodeCSType(instr);
2866       break;
2867     case Instruction::kCBType:
2868       DecodeCBType(instr);
2869       break;
2870     case Instruction::kVType:
2871       DecodeVType(instr);
2872       break;
2873     default:
2874       Format(instr, "UNSUPPORTED");
2875       UNSUPPORTED_RISCV();
2876   }
2877   return instr->InstructionSize();
2878 }
2879 
2880 }  // namespace internal
2881 }  // namespace v8
2882 
2883 //------------------------------------------------------------------------------
2884 
2885 namespace disasm {
2886 
NameOfAddress(byte * addr) const2887 const char* NameConverter::NameOfAddress(byte* addr) const {
2888   v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
2889   return tmp_buffer_.begin();
2890 }
2891 
NameOfConstant(byte * addr) const2892 const char* NameConverter::NameOfConstant(byte* addr) const {
2893   return NameOfAddress(addr);
2894 }
2895 
NameOfCPURegister(int reg) const2896 const char* NameConverter::NameOfCPURegister(int reg) const {
2897   return v8::internal::Registers::Name(reg);
2898 }
2899 
NameOfXMMRegister(int reg) const2900 const char* NameConverter::NameOfXMMRegister(int reg) const {
2901   return v8::internal::FPURegisters::Name(reg);
2902 }
2903 
NameOfByteCPURegister(int reg) const2904 const char* NameConverter::NameOfByteCPURegister(int reg) const {
2905   UNREACHABLE();  // RISC-V does not have the concept of a byte register.
2906   // return "nobytereg";
2907 }
2908 
NameInCode(byte * addr) const2909 const char* NameConverter::NameInCode(byte* addr) const {
2910   // The default name converter is called for unknown code. So we will not try
2911   // to access any memory.
2912   return "";
2913 }
2914 
2915 //------------------------------------------------------------------------------
2916 
InstructionDecode(v8::base::Vector<char> buffer,byte * instruction)2917 int Disassembler::InstructionDecode(v8::base::Vector<char> buffer,
2918                                     byte* instruction) {
2919   v8::internal::Decoder d(converter_, buffer);
2920   return d.InstructionDecode(instruction);
2921 }
2922 
ConstantPoolSizeAt(byte * instruction)2923 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
2924   return v8::internal::Assembler::ConstantPoolSizeAt(
2925       reinterpret_cast<v8::internal::Instruction*>(instruction));
2926 }
2927 
Disassemble(FILE * f,byte * begin,byte * end,UnimplementedOpcodeAction unimplemented_action)2928 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
2929                                UnimplementedOpcodeAction unimplemented_action) {
2930   NameConverter converter;
2931   Disassembler d(converter, unimplemented_action);
2932   for (byte* pc = begin; pc < end;) {
2933     v8::base::EmbeddedVector<char, 128> buffer;
2934     buffer[0] = '\0';
2935     byte* prev_pc = pc;
2936     pc += d.InstructionDecode(buffer, pc);
2937     v8::internal::PrintF(f, "%p    %08x      %s\n", static_cast<void*>(prev_pc),
2938                          *reinterpret_cast<uint32_t*>(prev_pc), buffer.begin());
2939   }
2940 }
2941 
2942 #undef STRING_STARTS_WITH
2943 
2944 }  // namespace disasm
2945 
2946 #endif  // V8_TARGET_ARCH_RISCV64
2947