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