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