tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Disasm-riscv64.cpp (67788B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 */
      4 // Copyright 2011 the V8 project authors. All rights reserved.
      5 // Use of this source code is governed by a BSD-style license that can be
      6 // found in the LICENSE file.
      7 
      8 // A Disassembler object is used to disassemble a block of code instruction by
      9 // instruction. The default implementation of the NameConverter object can be
     10 // overriden to modify register names or to do symbol lookup on addresses.
     11 //
     12 // The example below will disassemble a block of code and print it to stdout.
     13 //
     14 //   disasm::NameConverter converter;
     15 //   disasm::Disassembler d(converter);
     16 //   for (uint8_t* pc = begin; pc < end;) {
     17 //     disasm::EmbeddedVector<char, disasm::ReasonableBufferSize> buffer;
     18 //     uint8_t* prev_pc = pc;
     19 //     pc += d.InstructionDecode(buffer, pc);
     20 //     printf("%p    %08x      %s\n",
     21 //            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
     22 //   }
     23 //
     24 // The Disassembler class also has a convenience method to disassemble a block
     25 // of code into a FILE*, meaning that the above functionality could also be
     26 // achieved by just calling Disassembler::Disassemble(stdout, begin, end);
     27 
     28 #include "jit/riscv64/disasm/Disasm-riscv64.h"
     29 
     30 #include <stdio.h>
     31 #include <string.h>
     32 #include <string_view>
     33 
     34 #include "jit/riscv64/Assembler-riscv64.h"
     35 
     36 namespace js {
     37 namespace jit {
     38 namespace disasm {
     39 
     40 #define UNSUPPORTED_RISCV() printf("Unsupported instruction %d.\n", __LINE__)
     41 //------------------------------------------------------------------------------
     42 
     43 // Decoder decodes and disassembles instructions into an output buffer.
     44 // It uses the converter to convert register names and call destinations into
     45 // more informative description.
     46 class Decoder {
     47 public:
     48  Decoder(const disasm::NameConverter& converter, V8Vector<char> out_buffer)
     49      : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
     50    out_buffer_[out_buffer_pos_] = '\0';
     51  }
     52 
     53  ~Decoder() {}
     54 
     55  // Writes one disassembled instruction into 'buffer' (0-terminated).
     56  // Returns the length of the disassembled machine instruction in bytes.
     57  int InstructionDecode(uint8_t* instruction);
     58 
     59  static bool IsConstantPoolAt(uint8_t* instr_ptr);
     60  static int ConstantPoolSizeAt(uint8_t* instr_ptr);
     61 
     62 private:
     63  // Bottleneck functions to print into the out_buffer.
     64  void PrintChar(const char ch);
     65  void Print(const char* str);
     66 
     67  // Printing of common values.
     68  void PrintRegister(int reg);
     69  void PrintFPURegister(int freg);
     70  void PrintVRegister(int reg);
     71  void PrintFPUStatusRegister(int freg);
     72  void PrintRs1(Instruction* instr);
     73  void PrintRs2(Instruction* instr);
     74  void PrintRd(Instruction* instr);
     75  void PrintUimm(Instruction* instr);
     76  void PrintVs1(Instruction* instr);
     77  void PrintVs2(Instruction* instr);
     78  void PrintVd(Instruction* instr);
     79  void PrintFRs1(Instruction* instr);
     80  void PrintFRs2(Instruction* instr);
     81  void PrintFRs3(Instruction* instr);
     82  void PrintFRd(Instruction* instr);
     83  void PrintImm12(Instruction* instr);
     84  void PrintImm12X(Instruction* instr);
     85  void PrintImm20U(Instruction* instr);
     86  void PrintImm20J(Instruction* instr);
     87  void PrintShamt(Instruction* instr);
     88  void PrintShamt32(Instruction* instr);
     89  void PrintRvcImm6(Instruction* instr);
     90  void PrintRvcImm6U(Instruction* instr);
     91  void PrintRvcImm6Addi16sp(Instruction* instr);
     92  void PrintRvcShamt(Instruction* instr);
     93  void PrintRvcImm6Ldsp(Instruction* instr);
     94  void PrintRvcImm6Lwsp(Instruction* instr);
     95  void PrintRvcImm6Sdsp(Instruction* instr);
     96  void PrintRvcImm6Swsp(Instruction* instr);
     97  void PrintRvcImm5W(Instruction* instr);
     98  void PrintRvcImm5D(Instruction* instr);
     99  void PrintRvcImm8Addi4spn(Instruction* instr);
    100  void PrintRvcImm11CJ(Instruction* instr);
    101  void PrintRvcImm8B(Instruction* instr);
    102  void PrintRvvVm(Instruction* instr);
    103  void PrintAcquireRelease(Instruction* instr);
    104  void PrintBranchOffset(Instruction* instr);
    105  void PrintStoreOffset(Instruction* instr);
    106  void PrintCSRReg(Instruction* instr);
    107  void PrintRvvSEW(Instruction* instr);
    108  void PrintRvvLMUL(Instruction* instr);
    109  void PrintRvvSimm5(Instruction* instr);
    110  void PrintRvvUimm5(Instruction* instr);
    111  void PrintRoundingMode(Instruction* instr);
    112  void PrintMemoryOrder(Instruction* instr, bool is_pred);
    113 
    114  // Each of these functions decodes one particular instruction type.
    115  void DecodeRType(Instruction* instr);
    116  void DecodeR4Type(Instruction* instr);
    117  void DecodeRAType(Instruction* instr);
    118  void DecodeRFPType(Instruction* instr);
    119  void DecodeIType(Instruction* instr);
    120  void DecodeSType(Instruction* instr);
    121  void DecodeBType(Instruction* instr);
    122  void DecodeUType(Instruction* instr);
    123  void DecodeJType(Instruction* instr);
    124  void DecodeCRType(Instruction* instr);
    125  void DecodeCAType(Instruction* instr);
    126  void DecodeCIType(Instruction* instr);
    127  void DecodeCIWType(Instruction* instr);
    128  void DecodeCSSType(Instruction* instr);
    129  void DecodeCLType(Instruction* instr);
    130  void DecodeCSType(Instruction* instr);
    131  void DecodeCJType(Instruction* instr);
    132  void DecodeCBType(Instruction* instr);
    133 
    134  // Printing of instruction name.
    135  void PrintInstructionName(Instruction* instr);
    136  void PrintTarget(Instruction* instr);
    137 
    138  // Handle formatting of instructions and their options.
    139  int FormatRegister(Instruction* instr, const char* option);
    140  int FormatFPURegisterOrRoundMode(Instruction* instr, const char* option);
    141  int FormatRvcRegister(Instruction* instr, const char* option);
    142  int FormatRvcImm(Instruction* instr, const char* option);
    143  int FormatOption(Instruction* instr, const char* option);
    144  void Format(Instruction* instr, const char* format);
    145  void Unknown(Instruction* instr);
    146 
    147  int switch_sew(Instruction* instr);
    148  int switch_nf(Instruction* instr);
    149 
    150  const disasm::NameConverter& converter_;
    151  V8Vector<char> out_buffer_;
    152  int out_buffer_pos_;
    153 
    154  // Disallow copy and assign.
    155  Decoder(const Decoder&) = delete;
    156  void operator=(const Decoder&) = delete;
    157 };
    158 
    159 // Support for assertions in the Decoder formatting functions.
    160 #define STRING_STARTS_WITH(string, compare_string) \
    161  (strncmp(string, compare_string, strlen(compare_string)) == 0)
    162 
    163 // Append the ch to the output buffer.
    164 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
    165 
    166 // Append the str to the output buffer.
    167 void Decoder::Print(const char* str) {
    168  char cur = *str++;
    169  while (cur != '\0' && (out_buffer_pos_ < int(out_buffer_.length() - 1))) {
    170    PrintChar(cur);
    171    cur = *str++;
    172  }
    173  out_buffer_[out_buffer_pos_] = 0;
    174 }
    175 
    176 int Decoder::switch_nf(Instruction* instr) {
    177  int nf = 0;
    178  switch (instr->InstructionBits() & kRvvNfMask) {
    179    case 0x20000000:
    180      nf = 2;
    181      break;
    182    case 0x40000000:
    183      nf = 3;
    184      break;
    185    case 0x60000000:
    186      nf = 4;
    187      break;
    188    case 0x80000000:
    189      nf = 5;
    190      break;
    191    case 0xa0000000:
    192      nf = 6;
    193      break;
    194    case 0xc0000000:
    195      nf = 7;
    196      break;
    197    case 0xe0000000:
    198      nf = 8;
    199      break;
    200  }
    201  return nf;
    202 }
    203 
    204 int Decoder::switch_sew(Instruction* instr) {
    205  int width = 0;
    206  if ((instr->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
    207      (instr->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
    208    return -1;
    209  switch (instr->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
    210    case 0x0:
    211      width = 8;
    212      break;
    213    case 0x00005000:
    214      width = 16;
    215      break;
    216    case 0x00006000:
    217      width = 32;
    218      break;
    219    case 0x00007000:
    220      width = 64;
    221      break;
    222    case 0x10000000:
    223      width = 128;
    224      break;
    225    case 0x10005000:
    226      width = 256;
    227      break;
    228    case 0x10006000:
    229      width = 512;
    230      break;
    231    case 0x10007000:
    232      width = 1024;
    233      break;
    234    default:
    235      width = -1;
    236      break;
    237  }
    238  return width;
    239 }
    240 
    241 // Handle all register based formatting in this function to reduce the
    242 // complexity of FormatOption.
    243 int Decoder::FormatRegister(Instruction* instr, const char* format) {
    244  MOZ_ASSERT(format[0] == 'r');
    245  if (format[1] == 's') {  // 'rs[12]: Rs register.
    246    if (format[2] == '1') {
    247      int reg = instr->Rs1Value();
    248      PrintRegister(reg);
    249      return 3;
    250    } else if (format[2] == '2') {
    251      int reg = instr->Rs2Value();
    252      PrintRegister(reg);
    253      return 3;
    254    }
    255    MOZ_CRASH();
    256  } else if (format[1] == 'd') {  // 'rd: rd register.
    257    int reg = instr->RdValue();
    258    PrintRegister(reg);
    259    return 2;
    260  }
    261  MOZ_CRASH();
    262 }
    263 
    264 // Handle all FPUregister based formatting in this function to reduce the
    265 // complexity of FormatOption.
    266 int Decoder::FormatFPURegisterOrRoundMode(Instruction* instr,
    267                                          const char* format) {
    268  MOZ_ASSERT(format[0] == 'f');
    269  if (format[1] == 's') {  // 'fs[1-3]: Rs register.
    270    if (format[2] == '1') {
    271      int reg = instr->Rs1Value();
    272      PrintFPURegister(reg);
    273      return 3;
    274    } else if (format[2] == '2') {
    275      int reg = instr->Rs2Value();
    276      PrintFPURegister(reg);
    277      return 3;
    278    } else if (format[2] == '3') {
    279      int reg = instr->Rs3Value();
    280      PrintFPURegister(reg);
    281      return 3;
    282    }
    283    MOZ_CRASH();
    284  } else if (format[1] == 'd') {  // 'fd: fd register.
    285    int reg = instr->RdValue();
    286    PrintFPURegister(reg);
    287    return 2;
    288  } else if (format[1] == 'r') {  // 'frm
    289    MOZ_ASSERT(STRING_STARTS_WITH(format, "frm"));
    290    PrintRoundingMode(instr);
    291    return 3;
    292  }
    293  MOZ_CRASH();
    294 }
    295 
    296 // Handle all C extension register based formatting in this function to reduce
    297 // the complexity of FormatOption.
    298 int Decoder::FormatRvcRegister(Instruction* instr, const char* format) {
    299  MOZ_ASSERT(format[0] == 'C');
    300  MOZ_ASSERT(format[1] == 'r' || format[1] == 'f');
    301  if (format[2] == 's') {  // 'Crs[12]: Rs register.
    302    if (format[3] == '1') {
    303      if (format[4] == 's') {  // 'Crs1s: 3-bits register
    304        int reg = instr->RvcRs1sValue();
    305        if (format[1] == 'r') {
    306          PrintRegister(reg);
    307        } else if (format[1] == 'f') {
    308          PrintFPURegister(reg);
    309        }
    310        return 5;
    311      }
    312      int reg = instr->RvcRs1Value();
    313      if (format[1] == 'r') {
    314        PrintRegister(reg);
    315      } else if (format[1] == 'f') {
    316        PrintFPURegister(reg);
    317      }
    318      return 4;
    319    } else if (format[3] == '2') {
    320      if (format[4] == 's') {  // 'Crs2s: 3-bits register
    321        int reg = instr->RvcRs2sValue();
    322        if (format[1] == 'r') {
    323          PrintRegister(reg);
    324        } else if (format[1] == 'f') {
    325          PrintFPURegister(reg);
    326        }
    327        return 5;
    328      }
    329      int reg = instr->RvcRs2Value();
    330      if (format[1] == 'r') {
    331        PrintRegister(reg);
    332      } else if (format[1] == 'f') {
    333        PrintFPURegister(reg);
    334      }
    335      return 4;
    336    }
    337    MOZ_CRASH();
    338  } else if (format[2] == 'd') {  // 'Crd: rd register.
    339    int reg = instr->RvcRdValue();
    340    if (format[1] == 'r') {
    341      PrintRegister(reg);
    342    } else if (format[1] == 'f') {
    343      PrintFPURegister(reg);
    344    }
    345    return 3;
    346  }
    347  MOZ_CRASH();
    348 }
    349 
    350 // Handle all C extension immediates based formatting in this function to reduce
    351 // the complexity of FormatOption.
    352 int Decoder::FormatRvcImm(Instruction* instr, const char* format) {
    353  // TODO(riscv): add other rvc imm format
    354  MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm"));
    355  if (format[4] == '6') {
    356    if (format[5] == 'U') {
    357      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6U"));
    358      PrintRvcImm6U(instr);
    359      return 6;
    360    } else if (format[5] == 'A') {
    361      if (format[9] == '1' && format[10] == '6') {
    362        MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6Addi16sp"));
    363        PrintRvcImm6Addi16sp(instr);
    364        return 13;
    365      }
    366      MOZ_CRASH();
    367    } else if (format[5] == 'L') {
    368      if (format[6] == 'd') {
    369        if (format[7] == 's') {
    370          MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6Ldsp"));
    371          PrintRvcImm6Ldsp(instr);
    372          return 9;
    373        }
    374      } else if (format[6] == 'w') {
    375        if (format[7] == 's') {
    376          MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6Lwsp"));
    377          PrintRvcImm6Lwsp(instr);
    378          return 9;
    379        }
    380      }
    381      MOZ_CRASH();
    382    } else if (format[5] == 'S') {
    383      if (format[6] == 'w') {
    384        MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6Swsp"));
    385        PrintRvcImm6Swsp(instr);
    386        return 9;
    387      } else if (format[6] == 'd') {
    388        MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm6Sdsp"));
    389        PrintRvcImm6Sdsp(instr);
    390        return 9;
    391      }
    392      MOZ_CRASH();
    393    }
    394    PrintRvcImm6(instr);
    395    return 5;
    396  } else if (format[4] == '5') {
    397    MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm5"));
    398    if (format[5] == 'W') {
    399      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm5W"));
    400      PrintRvcImm5W(instr);
    401      return 6;
    402    } else if (format[5] == 'D') {
    403      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm5D"));
    404      PrintRvcImm5D(instr);
    405      return 6;
    406    }
    407    MOZ_CRASH();
    408  } else if (format[4] == '8') {
    409    MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm8"));
    410    if (format[5] == 'A') {
    411      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm8Addi4spn"));
    412      PrintRvcImm8Addi4spn(instr);
    413      return 13;
    414    } else if (format[5] == 'B') {
    415      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm8B"));
    416      PrintRvcImm8B(instr);
    417      return 6;
    418    }
    419    MOZ_CRASH();
    420  } else if (format[4] == '1') {
    421    MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm1"));
    422    if (format[5] == '1') {
    423      MOZ_ASSERT(STRING_STARTS_WITH(format, "Cimm11CJ"));
    424      PrintRvcImm11CJ(instr);
    425      return 8;
    426    }
    427    MOZ_CRASH();
    428  }
    429  MOZ_CRASH();
    430 }
    431 
    432 // FormatOption takes a formatting string and interprets it based on
    433 // the current instructions. The format string points to the first
    434 // character of the option string (the option escape has already been
    435 // consumed by the caller.)  FormatOption returns the number of
    436 // characters that were consumed from the formatting string.
    437 int Decoder::FormatOption(Instruction* instr, const char* format) {
    438  switch (format[0]) {
    439    case 'C': {  // `C extension
    440      if (format[1] == 'r' || format[1] == 'f') {
    441        return FormatRvcRegister(instr, format);
    442      } else if (format[1] == 'i') {
    443        return FormatRvcImm(instr, format);
    444      } else if (format[1] == 's') {
    445        MOZ_ASSERT(STRING_STARTS_WITH(format, "Cshamt"));
    446        PrintRvcShamt(instr);
    447        return 6;
    448      }
    449      MOZ_CRASH();
    450    }
    451    case 'c': {  // `csr: CSR registers
    452      if (format[1] == 's') {
    453        if (format[2] == 'r') {
    454          PrintCSRReg(instr);
    455          return 3;
    456        }
    457      }
    458      MOZ_CRASH();
    459    }
    460    case 'i': {  // 'imm12, 'imm12x, 'imm20U, or 'imm20J: Immediates.
    461      if (format[3] == '1') {
    462        if (format[4] == '2') {
    463          MOZ_ASSERT(STRING_STARTS_WITH(format, "imm12"));
    464          if (format[5] == 'x') {
    465            PrintImm12X(instr);
    466            return 6;
    467          }
    468          PrintImm12(instr);
    469          return 5;
    470        }
    471      } else if (format[3] == '2' && format[4] == '0') {
    472        MOZ_ASSERT(STRING_STARTS_WITH(format, "imm20"));
    473        switch (format[5]) {
    474          case 'U':
    475            MOZ_ASSERT(STRING_STARTS_WITH(format, "imm20U"));
    476            PrintImm20U(instr);
    477            break;
    478          case 'J':
    479            MOZ_ASSERT(STRING_STARTS_WITH(format, "imm20J"));
    480            PrintImm20J(instr);
    481            break;
    482        }
    483        return 6;
    484      }
    485      MOZ_CRASH();
    486    }
    487    case 'o': {  // 'offB or 'offS: Offsets.
    488      if (format[3] == 'B') {
    489        MOZ_ASSERT(STRING_STARTS_WITH(format, "offB"));
    490        PrintBranchOffset(instr);
    491        return 4;
    492      } else if (format[3] == 'S') {
    493        MOZ_ASSERT(STRING_STARTS_WITH(format, "offS"));
    494        PrintStoreOffset(instr);
    495        return 4;
    496      }
    497      MOZ_CRASH();
    498    }
    499    case 'r': {  // 'r: registers.
    500      return FormatRegister(instr, format);
    501    }
    502    case 'f': {  // 'f: FPUregisters or `frm
    503      return FormatFPURegisterOrRoundMode(instr, format);
    504    }
    505    case 'a': {  // 'a: Atomic acquire and release.
    506      PrintAcquireRelease(instr);
    507      return 1;
    508    }
    509    case 'p': {  // `pre
    510      MOZ_ASSERT(STRING_STARTS_WITH(format, "pre"));
    511      PrintMemoryOrder(instr, true);
    512      return 3;
    513    }
    514    case 's': {  // 's32 or 's64: Shift amount.
    515      if (format[1] == '3') {
    516        MOZ_ASSERT(STRING_STARTS_WITH(format, "s32"));
    517        PrintShamt32(instr);
    518        return 3;
    519      } else if (format[1] == '6') {
    520        MOZ_ASSERT(STRING_STARTS_WITH(format, "s64"));
    521        PrintShamt(instr);
    522        return 3;
    523      } else if (format[1] == 'u') {
    524        MOZ_ASSERT(STRING_STARTS_WITH(format, "suc"));
    525        PrintMemoryOrder(instr, false);
    526        return 3;
    527      } else if (format[1] == 'e') {
    528        MOZ_ASSERT(STRING_STARTS_WITH(format, "sew"));
    529        PrintRvvSEW(instr);
    530        return 3;
    531      } else if (format[1] == 'i') {
    532        MOZ_ASSERT(STRING_STARTS_WITH(format, "simm5"));
    533        PrintRvvSimm5(instr);
    534        return 5;
    535      }
    536      MOZ_CRASH();
    537    }
    538    case 'v': {
    539      if (format[1] == 'd') {
    540        MOZ_ASSERT(STRING_STARTS_WITH(format, "vd"));
    541        PrintVd(instr);
    542        return 2;
    543      } else if (format[2] == '1') {
    544        MOZ_ASSERT(STRING_STARTS_WITH(format, "vs1"));
    545        PrintVs1(instr);
    546        return 3;
    547      } else if (format[2] == '2') {
    548        MOZ_ASSERT(STRING_STARTS_WITH(format, "vs2"));
    549        PrintVs2(instr);
    550        return 3;
    551      } else {
    552        MOZ_ASSERT(STRING_STARTS_WITH(format, "vm"));
    553        PrintRvvVm(instr);
    554        return 2;
    555      }
    556    }
    557    case 'l': {
    558      MOZ_ASSERT(STRING_STARTS_WITH(format, "lmul"));
    559      PrintRvvLMUL(instr);
    560      return 4;
    561    }
    562    case 'u': {
    563      if (STRING_STARTS_WITH(format, "uimm5")) {
    564        PrintRvvUimm5(instr);
    565        return 5;
    566      } else {
    567        MOZ_ASSERT(STRING_STARTS_WITH(format, "uimm"));
    568        PrintUimm(instr);
    569        return 4;
    570      }
    571    }
    572    case 't': {  // 'target: target of branch instructions'
    573      MOZ_ASSERT(STRING_STARTS_WITH(format, "target"));
    574      PrintTarget(instr);
    575      return 6;
    576    }
    577  }
    578  MOZ_CRASH();
    579 }
    580 
    581 // Format takes a formatting string for a whole instruction and prints it into
    582 // the output buffer. All escaped options are handed to FormatOption to be
    583 // parsed further.
    584 void Decoder::Format(Instruction* instr, const char* format) {
    585  char cur = *format++;
    586  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
    587    if (cur == '\'') {  // Single quote is used as the formatting escape.
    588      format += FormatOption(instr, format);
    589    } else {
    590      out_buffer_[out_buffer_pos_++] = cur;
    591    }
    592    cur = *format++;
    593  }
    594  out_buffer_[out_buffer_pos_] = '\0';
    595 }
    596 
    597 // The disassembler may end up decoding data inlined in the code. We do not want
    598 // it to crash if the data does not ressemble any known instruction.
    599 #define VERIFY(condition) \
    600  if (!(condition)) {     \
    601    Unknown(instr);       \
    602    return;               \
    603  }
    604 
    605 // For currently unimplemented decodings the disassembler calls Unknown(instr)
    606 // which will just print "unknown" of the instruction bits.
    607 void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
    608 
    609 // Print the register name according to the active name converter.
    610 void Decoder::PrintRegister(int reg) {
    611  Print(converter_.NameOfCPURegister(reg));
    612 }
    613 
    614 void Decoder::PrintVRegister(int reg) { UNSUPPORTED_RISCV(); }
    615 
    616 void Decoder::PrintRs1(Instruction* instr) {
    617  int reg = instr->Rs1Value();
    618  PrintRegister(reg);
    619 }
    620 
    621 void Decoder::PrintRs2(Instruction* instr) {
    622  int reg = instr->Rs2Value();
    623  PrintRegister(reg);
    624 }
    625 
    626 void Decoder::PrintRd(Instruction* instr) {
    627  int reg = instr->RdValue();
    628  PrintRegister(reg);
    629 }
    630 
    631 void Decoder::PrintUimm(Instruction* instr) {
    632  int val = instr->Rs1Value();
    633  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", val);
    634 }
    635 
    636 void Decoder::PrintVs1(Instruction* instr) {
    637  int reg = instr->Vs1Value();
    638  PrintVRegister(reg);
    639 }
    640 
    641 void Decoder::PrintVs2(Instruction* instr) {
    642  int reg = instr->Vs2Value();
    643  PrintVRegister(reg);
    644 }
    645 
    646 void Decoder::PrintVd(Instruction* instr) {
    647  int reg = instr->VdValue();
    648  PrintVRegister(reg);
    649 }
    650 
    651 // Print the FPUregister name according to the active name converter.
    652 void Decoder::PrintFPURegister(int freg) {
    653  Print(converter_.NameOfXMMRegister(freg));
    654 }
    655 
    656 void Decoder::PrintFRs1(Instruction* instr) {
    657  int reg = instr->Rs1Value();
    658  PrintFPURegister(reg);
    659 }
    660 
    661 void Decoder::PrintFRs2(Instruction* instr) {
    662  int reg = instr->Rs2Value();
    663  PrintFPURegister(reg);
    664 }
    665 
    666 void Decoder::PrintFRs3(Instruction* instr) {
    667  int reg = instr->Rs3Value();
    668  PrintFPURegister(reg);
    669 }
    670 
    671 void Decoder::PrintFRd(Instruction* instr) {
    672  int reg = instr->RdValue();
    673  PrintFPURegister(reg);
    674 }
    675 
    676 void Decoder::PrintImm12X(Instruction* instr) {
    677  int32_t imm = instr->Imm12Value();
    678  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
    679 }
    680 
    681 void Decoder::PrintImm12(Instruction* instr) {
    682  int32_t imm = instr->Imm12Value();
    683  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    684 }
    685 
    686 void Decoder::PrintTarget(Instruction* instr) {
    687  // if (Assembler::IsJalr(instr->InstructionBits())) {
    688  //   if (Assembler::IsAuipc((instr - 4)->InstructionBits()) &&
    689  //       (instr - 4)->RdValue() == instr->Rs1Value()) {
    690  //     int32_t imm = Assembler::BrachlongOffset((instr -
    691  //     4)->InstructionBits(),
    692  //                                              instr->InstructionBits());
    693  //     const char* target =
    694  //         converter_.NameOfAddress(reinterpret_cast<byte*>(instr - 4) + imm);
    695  //     out_buffer_pos_ +=
    696  //         SNPrintF(out_buffer_ + out_buffer_pos_, " -> %s", target);
    697  //     return;
    698  //   }
    699  // }
    700 }
    701 
    702 void Decoder::PrintBranchOffset(Instruction* instr) {
    703  int32_t imm = instr->BranchOffset();
    704  const char* target =
    705      converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + imm);
    706  out_buffer_pos_ +=
    707      SNPrintF(out_buffer_ + out_buffer_pos_, "%d -> %s", imm, target);
    708 }
    709 
    710 void Decoder::PrintStoreOffset(Instruction* instr) {
    711  int32_t imm = instr->StoreOffset();
    712  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    713 }
    714 
    715 void Decoder::PrintRvvSEW(Instruction* instr) {
    716  const char* sew = instr->RvvSEW();
    717  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", sew);
    718 }
    719 
    720 void Decoder::PrintRvvLMUL(Instruction* instr) {
    721  const char* lmul = instr->RvvLMUL();
    722  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", lmul);
    723 }
    724 
    725 void Decoder::PrintRvvSimm5(Instruction* instr) {
    726  const int simm5 = instr->RvvSimm5();
    727  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", simm5);
    728 }
    729 
    730 void Decoder::PrintRvvUimm5(Instruction* instr) {
    731  const uint32_t uimm5 = instr->RvvUimm5();
    732  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", uimm5);
    733 }
    734 
    735 void Decoder::PrintImm20U(Instruction* instr) {
    736  int32_t imm = instr->Imm20UValue();
    737  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
    738 }
    739 
    740 void Decoder::PrintImm20J(Instruction* instr) {
    741  int32_t imm = instr->Imm20JValue();
    742  const char* target =
    743      converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + imm);
    744  out_buffer_pos_ +=
    745      SNPrintF(out_buffer_ + out_buffer_pos_, "%d -> %s", imm, target);
    746 }
    747 
    748 void Decoder::PrintShamt(Instruction* instr) {
    749  int32_t imm = instr->Shamt();
    750  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    751 }
    752 
    753 void Decoder::PrintShamt32(Instruction* instr) {
    754  int32_t imm = instr->Shamt32();
    755  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    756 }
    757 
    758 void Decoder::PrintRvcImm6(Instruction* instr) {
    759  int32_t imm = instr->RvcImm6Value();
    760  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    761 }
    762 
    763 void Decoder::PrintRvcImm6U(Instruction* instr) {
    764  int32_t imm = instr->RvcImm6Value() & 0xFFFFF;
    765  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
    766 }
    767 
    768 void Decoder::PrintRvcImm6Addi16sp(Instruction* instr) {
    769  int32_t imm = instr->RvcImm6Addi16spValue();
    770  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    771 }
    772 
    773 void Decoder::PrintRvcShamt(Instruction* instr) {
    774  int32_t imm = instr->RvcShamt6();
    775  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    776 }
    777 
    778 void Decoder::PrintRvcImm6Ldsp(Instruction* instr) {
    779  int32_t imm = instr->RvcImm6LdspValue();
    780  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    781 }
    782 
    783 void Decoder::PrintRvcImm6Lwsp(Instruction* instr) {
    784  int32_t imm = instr->RvcImm6LwspValue();
    785  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    786 }
    787 
    788 void Decoder::PrintRvcImm6Swsp(Instruction* instr) {
    789  int32_t imm = instr->RvcImm6SwspValue();
    790  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    791 }
    792 
    793 void Decoder::PrintRvcImm6Sdsp(Instruction* instr) {
    794  int32_t imm = instr->RvcImm6SdspValue();
    795  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    796 }
    797 
    798 void Decoder::PrintRvcImm5W(Instruction* instr) {
    799  int32_t imm = instr->RvcImm5WValue();
    800  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    801 }
    802 
    803 void Decoder::PrintRvcImm5D(Instruction* instr) {
    804  int32_t imm = instr->RvcImm5DValue();
    805  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    806 }
    807 
    808 void Decoder::PrintRvcImm8Addi4spn(Instruction* instr) {
    809  int32_t imm = instr->RvcImm8Addi4spnValue();
    810  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    811 }
    812 
    813 void Decoder::PrintRvcImm11CJ(Instruction* instr) {
    814  int32_t imm = instr->RvcImm11CJValue();
    815  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    816 }
    817 
    818 void Decoder::PrintRvcImm8B(Instruction* instr) {
    819  int32_t imm = instr->RvcImm8BValue();
    820  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
    821 }
    822 
    823 void Decoder::PrintRvvVm(Instruction* instr) {
    824  uint8_t imm = instr->RvvVM();
    825  if (imm == 0) {
    826    out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "  v0.t");
    827  }
    828 }
    829 
    830 void Decoder::PrintAcquireRelease(Instruction* instr) {
    831  bool aq = instr->AqValue();
    832  bool rl = instr->RlValue();
    833  if (aq || rl) {
    834    out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, ".");
    835  }
    836  if (aq) {
    837    out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "aq");
    838  }
    839  if (rl) {
    840    out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "rl");
    841  }
    842 }
    843 
    844 void Decoder::PrintCSRReg(Instruction* instr) {
    845  int32_t csr_reg = instr->CsrValue();
    846  std::string_view s;
    847  switch (csr_reg) {
    848    case csr_fflags:  // Floating-Point Accrued Exceptions (RW)
    849      s = "csr_fflags";
    850      break;
    851    case csr_frm:  // Floating-Point Dynamic Rounding Mode (RW)
    852      s = "csr_frm";
    853      break;
    854    case csr_fcsr:  // Floating-Point Control and Status Register (RW)
    855      s = "csr_fcsr";
    856      break;
    857    case csr_cycle:
    858      s = "csr_cycle";
    859      break;
    860    case csr_time:
    861      s = "csr_time";
    862      break;
    863    case csr_instret:
    864      s = "csr_instret";
    865      break;
    866    case csr_cycleh:
    867      s = "csr_cycleh";
    868      break;
    869    case csr_timeh:
    870      s = "csr_timeh";
    871      break;
    872    case csr_instreth:
    873      s = "csr_instreth";
    874      break;
    875    default:
    876      MOZ_CRASH();
    877  }
    878  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s.data());
    879 }
    880 
    881 void Decoder::PrintRoundingMode(Instruction* instr) {
    882  int frm = instr->RoundMode();
    883  std::string_view s;
    884  switch (frm) {
    885    case RNE:
    886      s = "RNE";
    887      break;
    888    case RTZ:
    889      s = "RTZ";
    890      break;
    891    case RDN:
    892      s = "RDN";
    893      break;
    894    case RUP:
    895      s = "RUP";
    896      break;
    897    case RMM:
    898      s = "RMM";
    899      break;
    900    case DYN:
    901      s = "DYN";
    902      break;
    903    default:
    904      MOZ_CRASH();
    905  }
    906  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s.data());
    907 }
    908 
    909 void Decoder::PrintMemoryOrder(Instruction* instr, bool is_pred) {
    910  int memOrder = instr->MemoryOrder(is_pred);
    911  char s[5] = {};
    912  char* ps = s;
    913  if ((memOrder & PSI) == PSI) {
    914    *ps++ = 'i';
    915  }
    916  if ((memOrder & PSO) == PSO) {
    917    *ps++ = 'o';
    918  }
    919  if ((memOrder & PSR) == PSR) {
    920    *ps++ = 'r';
    921  }
    922  if ((memOrder & PSW) == PSW) {
    923    *ps++ = 'w';
    924  }
    925  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s", s);
    926 }
    927 
    928 // Printing of instruction name.
    929 void Decoder::PrintInstructionName(Instruction* instr) {}
    930 
    931 // RISCV Instruction Decode Routine
    932 void Decoder::DecodeRType(Instruction* instr) {
    933  switch (instr->InstructionBits() & kRTypeMask) {
    934    case RO_ADD:
    935      Format(instr, "add       'rd, 'rs1, 'rs2");
    936      break;
    937    case RO_SUB:
    938      if (instr->Rs1Value() == zero.code())
    939        Format(instr, "neg       'rd, 'rs2");
    940      else
    941        Format(instr, "sub       'rd, 'rs1, 'rs2");
    942      break;
    943    case RO_SLL:
    944      Format(instr, "sll       'rd, 'rs1, 'rs2");
    945      break;
    946    case RO_SLT:
    947      if (instr->Rs2Value() == zero.code())
    948        Format(instr, "sltz      'rd, 'rs1");
    949      else if (instr->Rs1Value() == zero.code())
    950        Format(instr, "sgtz      'rd, 'rs2");
    951      else
    952        Format(instr, "slt       'rd, 'rs1, 'rs2");
    953      break;
    954    case RO_SLTU:
    955      if (instr->Rs1Value() == zero.code())
    956        Format(instr, "snez      'rd, 'rs2");
    957      else
    958        Format(instr, "sltu      'rd, 'rs1, 'rs2");
    959      break;
    960    case RO_XOR:
    961      Format(instr, "xor       'rd, 'rs1, 'rs2");
    962      break;
    963    case RO_SRL:
    964      Format(instr, "srl       'rd, 'rs1, 'rs2");
    965      break;
    966    case RO_SRA:
    967      Format(instr, "sra       'rd, 'rs1, 'rs2");
    968      break;
    969    case RO_OR:
    970      Format(instr, "or        'rd, 'rs1, 'rs2");
    971      break;
    972    case RO_AND:
    973      Format(instr, "and       'rd, 'rs1, 'rs2");
    974      break;
    975    case RO_ANDN:
    976      Format(instr, "andn      'rd, 'rs1, 'rs2");
    977      break;
    978    case RO_ORN:
    979      Format(instr, "orn       'rd, 'rs1, 'rs2");
    980      break;
    981    case RO_XNOR:
    982      Format(instr, "xnor      'rd, 'rs1, 'rs2");
    983      break;
    984 #ifdef JS_CODEGEN_RISCV64
    985    case RO_ADDW:
    986      Format(instr, "addw      'rd, 'rs1, 'rs2");
    987      break;
    988    case RO_ADDUW:
    989      if (instr->Rs2Value() == zero_reg.code()) {
    990        Format(instr, "zext.w    'rd, 'rs1");
    991      } else {
    992        Format(instr, "add.uw    'rd, 'rs1, 'rs2");
    993      }
    994      break;
    995    case RO_SUBW:
    996      if (instr->Rs1Value() == zero.code())
    997        Format(instr, "negw      'rd, 'rs2");
    998      else
    999        Format(instr, "subw      'rd, 'rs1, 'rs2");
   1000      break;
   1001    case RO_SLLW:
   1002      Format(instr, "sllw      'rd, 'rs1, 'rs2");
   1003      break;
   1004    case RO_SRLW:
   1005      Format(instr, "srlw      'rd, 'rs1, 'rs2");
   1006      break;
   1007    case RO_SRAW:
   1008      Format(instr, "sraw      'rd, 'rs1, 'rs2");
   1009      break;
   1010 #endif /* JS_CODEGEN_RISCV64 */
   1011    // TODO(riscv): Add RISCV M extension macro
   1012    case RO_MUL:
   1013      Format(instr, "mul       'rd, 'rs1, 'rs2");
   1014      break;
   1015    case RO_MULH:
   1016      Format(instr, "mulh      'rd, 'rs1, 'rs2");
   1017      break;
   1018    case RO_MULHSU:
   1019      Format(instr, "mulhsu    'rd, 'rs1, 'rs2");
   1020      break;
   1021    case RO_MULHU:
   1022      Format(instr, "mulhu     'rd, 'rs1, 'rs2");
   1023      break;
   1024    case RO_DIV:
   1025      Format(instr, "div       'rd, 'rs1, 'rs2");
   1026      break;
   1027    case RO_DIVU:
   1028      Format(instr, "divu      'rd, 'rs1, 'rs2");
   1029      break;
   1030    case RO_REM:
   1031      Format(instr, "rem       'rd, 'rs1, 'rs2");
   1032      break;
   1033    case RO_REMU:
   1034      Format(instr, "remu      'rd, 'rs1, 'rs2");
   1035      break;
   1036 #ifdef JS_CODEGEN_RISCV64
   1037    case RO_MULW:
   1038      Format(instr, "mulw      'rd, 'rs1, 'rs2");
   1039      break;
   1040    case RO_DIVW:
   1041      Format(instr, "divw      'rd, 'rs1, 'rs2");
   1042      break;
   1043    case RO_DIVUW:
   1044      Format(instr, "divuw     'rd, 'rs1, 'rs2");
   1045      break;
   1046    case RO_REMW:
   1047      Format(instr, "remw      'rd, 'rs1, 'rs2");
   1048      break;
   1049    case RO_REMUW:
   1050      Format(instr, "remuw     'rd, 'rs1, 'rs2");
   1051      break;
   1052    case RO_SH1ADDUW:
   1053      Format(instr, "sh1add.uw 'rd, 'rs1, 'rs2");
   1054      break;
   1055    case RO_SH2ADDUW:
   1056      Format(instr, "sh2add.uw 'rd, 'rs1, 'rs2");
   1057      break;
   1058    case RO_SH3ADDUW:
   1059      Format(instr, "sh3add.uw 'rd, 'rs1, 'rs2");
   1060      break;
   1061    case RO_ROLW:
   1062      Format(instr, "rolw     'rd, 'rs1, 'rs2");
   1063      break;
   1064    case RO_RORW:
   1065      Format(instr, "rorw     'rd, 'rs1, 'rs2");
   1066      break;
   1067 #endif /*JS_CODEGEN_RISCV64*/
   1068    case RO_SH1ADD:
   1069      Format(instr, "sh1add    'rd, 'rs1, 'rs2");
   1070      break;
   1071    case RO_SH2ADD:
   1072      Format(instr, "sh2add    'rd, 'rs1, 'rs2");
   1073      break;
   1074    case RO_SH3ADD:
   1075      Format(instr, "sh3add    'rd, 'rs1, 'rs2");
   1076      break;
   1077    case RO_MAX:
   1078      Format(instr, "max       'rd, 'rs1, 'rs2");
   1079      break;
   1080    case RO_MAXU:
   1081      Format(instr, "maxu      'rd, 'rs1, 'rs2");
   1082      break;
   1083    case RO_MIN:
   1084      Format(instr, "min       'rd, 'rs1, 'rs2");
   1085      break;
   1086    case RO_MINU:
   1087      Format(instr, "minu      'rd, 'rs1, 'rs2");
   1088      break;
   1089    case RO_ZEXTH:
   1090      Format(instr, "zext.h    'rd, 'rs1");
   1091      break;
   1092    case RO_ROL:
   1093      Format(instr, "rol      'rd, 'rs1, 'rs2");
   1094      break;
   1095    case RO_ROR:
   1096      Format(instr, "ror      'rd, 'rs1, 'rs2");
   1097      break;
   1098    case RO_BCLR:
   1099      Format(instr, "bclr      'rd, 'rs1, 'rs2");
   1100      break;
   1101    case RO_BEXT:
   1102      Format(instr, "bext      'rd, 'rs1, 'rs2");
   1103      break;
   1104    case RO_BINV:
   1105      Format(instr, "binv      'rd, 'rs1, 'rs2");
   1106      break;
   1107    case RO_BSET:
   1108      Format(instr, "bset      'rd, 'rs1, 'rs2");
   1109      break;
   1110    // TODO(riscv): End Add RISCV M extension macro
   1111    default: {
   1112      switch (instr->BaseOpcode()) {
   1113        case AMO:
   1114          DecodeRAType(instr);
   1115          break;
   1116        case OP_FP:
   1117          DecodeRFPType(instr);
   1118          break;
   1119        default:
   1120          UNSUPPORTED_RISCV();
   1121      }
   1122    }
   1123  }
   1124 }
   1125 
   1126 void Decoder::DecodeRAType(Instruction* instr) {
   1127  // TODO(riscv): Add macro for RISCV A extension
   1128  // Special handling for A extension instructions because it uses func5
   1129  // For all A extension instruction, V8 simulator is pure sequential. No
   1130  // Memory address lock or other synchronizaiton behaviors.
   1131  switch (instr->InstructionBits() & kRATypeMask) {
   1132    case RO_LR_W:
   1133      Format(instr, "lr.w'a    'rd, ('rs1)");
   1134      break;
   1135    case RO_SC_W:
   1136      Format(instr, "sc.w'a    'rd, 'rs2, ('rs1)");
   1137      break;
   1138    case RO_AMOSWAP_W:
   1139      Format(instr, "amoswap.w'a 'rd, 'rs2, ('rs1)");
   1140      break;
   1141    case RO_AMOADD_W:
   1142      Format(instr, "amoadd.w'a 'rd, 'rs2, ('rs1)");
   1143      break;
   1144    case RO_AMOXOR_W:
   1145      Format(instr, "amoxor.w'a 'rd, 'rs2, ('rs1)");
   1146      break;
   1147    case RO_AMOAND_W:
   1148      Format(instr, "amoand.w'a 'rd, 'rs2, ('rs1)");
   1149      break;
   1150    case RO_AMOOR_W:
   1151      Format(instr, "amoor.w'a 'rd, 'rs2, ('rs1)");
   1152      break;
   1153    case RO_AMOMIN_W:
   1154      Format(instr, "amomin.w'a 'rd, 'rs2, ('rs1)");
   1155      break;
   1156    case RO_AMOMAX_W:
   1157      Format(instr, "amomax.w'a 'rd, 'rs2, ('rs1)");
   1158      break;
   1159    case RO_AMOMINU_W:
   1160      Format(instr, "amominu.w'a 'rd, 'rs2, ('rs1)");
   1161      break;
   1162    case RO_AMOMAXU_W:
   1163      Format(instr, "amomaxu.w'a 'rd, 'rs2, ('rs1)");
   1164      break;
   1165 #ifdef JS_CODEGEN_RISCV64
   1166    case RO_LR_D:
   1167      Format(instr, "lr.d'a 'rd, ('rs1)");
   1168      break;
   1169    case RO_SC_D:
   1170      Format(instr, "sc.d'a 'rd, 'rs2, ('rs1)");
   1171      break;
   1172    case RO_AMOSWAP_D:
   1173      Format(instr, "amoswap.d'a 'rd, 'rs2, ('rs1)");
   1174      break;
   1175    case RO_AMOADD_D:
   1176      Format(instr, "amoadd.d'a 'rd, 'rs2, ('rs1)");
   1177      break;
   1178    case RO_AMOXOR_D:
   1179      Format(instr, "amoxor.d'a 'rd, 'rs2, ('rs1)");
   1180      break;
   1181    case RO_AMOAND_D:
   1182      Format(instr, "amoand.d'a 'rd, 'rs2, ('rs1)");
   1183      break;
   1184    case RO_AMOOR_D:
   1185      Format(instr, "amoor.d'a 'rd, 'rs2, ('rs1)");
   1186      break;
   1187    case RO_AMOMIN_D:
   1188      Format(instr, "amomin.d'a 'rd, 'rs2, ('rs1)");
   1189      break;
   1190    case RO_AMOMAX_D:
   1191      Format(instr, "amoswap.d'a 'rd, 'rs2, ('rs1)");
   1192      break;
   1193    case RO_AMOMINU_D:
   1194      Format(instr, "amominu.d'a 'rd, 'rs2, ('rs1)");
   1195      break;
   1196    case RO_AMOMAXU_D:
   1197      Format(instr, "amomaxu.d'a 'rd, 'rs2, ('rs1)");
   1198      break;
   1199 #endif /*JS_CODEGEN_RISCV64*/
   1200    // TODO(riscv): End Add macro for RISCV A extension
   1201    default: {
   1202      UNSUPPORTED_RISCV();
   1203    }
   1204  }
   1205 }
   1206 
   1207 void Decoder::DecodeRFPType(Instruction* instr) {
   1208  // OP_FP instructions (F/D) uses func7 first. Some further uses fun3 and rs2()
   1209 
   1210  // kRATypeMask is only for func7
   1211  switch (instr->InstructionBits() & kRFPTypeMask) {
   1212    // TODO(riscv): Add macro for RISCV F extension
   1213    case RO_FADD_S:
   1214      Format(instr, "fadd.s    'fd, 'fs1, 'fs2");
   1215      break;
   1216    case RO_FSUB_S:
   1217      Format(instr, "fsub.s    'fd, 'fs1, 'fs2");
   1218      break;
   1219    case RO_FMUL_S:
   1220      Format(instr, "fmul.s    'fd, 'fs1, 'fs2");
   1221      break;
   1222    case RO_FDIV_S:
   1223      Format(instr, "fdiv.s    'fd, 'fs1, 'fs2");
   1224      break;
   1225    case RO_FSQRT_S:
   1226      Format(instr, "fsqrt.s   'fd, 'fs1");
   1227      break;
   1228    case RO_FSGNJ_S: {  // RO_FSGNJN_S  RO_FSGNJX_S
   1229      switch (instr->Funct3Value()) {
   1230        case 0b000:  // RO_FSGNJ_S
   1231          if (instr->Rs1Value() == instr->Rs2Value())
   1232            Format(instr, "fmv.s     'fd, 'fs1");
   1233          else
   1234            Format(instr, "fsgnj.s   'fd, 'fs1, 'fs2");
   1235          break;
   1236        case 0b001:  // RO_FSGNJN_S
   1237          if (instr->Rs1Value() == instr->Rs2Value())
   1238            Format(instr, "fneg.s    'fd, 'fs1");
   1239          else
   1240            Format(instr, "fsgnjn.s  'fd, 'fs1, 'fs2");
   1241          break;
   1242        case 0b010:  // RO_FSGNJX_S
   1243          if (instr->Rs1Value() == instr->Rs2Value())
   1244            Format(instr, "fabs.s    'fd, 'fs1");
   1245          else
   1246            Format(instr, "fsgnjx.s  'fd, 'fs1, 'fs2");
   1247          break;
   1248        default:
   1249          UNSUPPORTED_RISCV();
   1250      }
   1251      break;
   1252    }
   1253    case RO_FMIN_S: {  // RO_FMAX_S
   1254      switch (instr->Funct3Value()) {
   1255        case 0b000:  // RO_FMIN_S
   1256          Format(instr, "fmin.s    'fd, 'fs1, 'fs2");
   1257          break;
   1258        case 0b001:  // RO_FMAX_S
   1259          Format(instr, "fmax.s    'fd, 'fs1, 'fs2");
   1260          break;
   1261        default:
   1262          UNSUPPORTED_RISCV();
   1263      }
   1264      break;
   1265    }
   1266    case RO_FCVT_W_S: {  // RO_FCVT_WU_S , 64F RO_FCVT_L_S RO_FCVT_LU_S
   1267      switch (instr->Rs2Value()) {
   1268        case 0b00000:  // RO_FCVT_W_S
   1269          Format(instr, "fcvt.w.s  ['frm] 'rd, 'fs1");
   1270          break;
   1271        case 0b00001:  // RO_FCVT_WU_S
   1272          Format(instr, "fcvt.wu.s ['frm] 'rd, 'fs1");
   1273          break;
   1274 #ifdef JS_CODEGEN_RISCV64
   1275        case 0b00010:  // RO_FCVT_L_S
   1276          Format(instr, "fcvt.l.s  ['frm] 'rd, 'fs1");
   1277          break;
   1278        case 0b00011:  // RO_FCVT_LU_S
   1279          Format(instr, "fcvt.lu.s ['frm] 'rd, 'fs1");
   1280          break;
   1281 #endif /* JS_CODEGEN_RISCV64 */
   1282        default:
   1283          UNSUPPORTED_RISCV();
   1284      }
   1285      break;
   1286    }
   1287    case RO_FMV: {  // RO_FCLASS_S
   1288      if (instr->Rs2Value() != 0b00000) {
   1289        UNSUPPORTED_RISCV();
   1290      }
   1291      switch (instr->Funct3Value()) {
   1292        case 0b000:  // RO_FMV_X_W
   1293          Format(instr, "fmv.x.w   'rd, 'fs1");
   1294          break;
   1295        case 0b001:  // RO_FCLASS_S
   1296          Format(instr, "fclass.s  'rd, 'fs1");
   1297          break;
   1298        default:
   1299          UNSUPPORTED_RISCV();
   1300      }
   1301      break;
   1302    }
   1303    case RO_FLE_S: {  // RO_FEQ_S RO_FLT_S RO_FLE_S
   1304      switch (instr->Funct3Value()) {
   1305        case 0b010:  // RO_FEQ_S
   1306          Format(instr, "feq.s     'rd, 'fs1, 'fs2");
   1307          break;
   1308        case 0b001:  // RO_FLT_S
   1309          Format(instr, "flt.s     'rd, 'fs1, 'fs2");
   1310          break;
   1311        case 0b000:  // RO_FLE_S
   1312          Format(instr, "fle.s     'rd, 'fs1, 'fs2");
   1313          break;
   1314        default:
   1315          UNSUPPORTED_RISCV();
   1316      }
   1317      break;
   1318    }
   1319    case RO_FCVT_S_W: {  // RO_FCVT_S_WU , 64F RO_FCVT_S_L RO_FCVT_S_LU
   1320      switch (instr->Rs2Value()) {
   1321        case 0b00000:  // RO_FCVT_S_W
   1322          Format(instr, "fcvt.s.w  'fd, 'rs1");
   1323          break;
   1324        case 0b00001:  // RO_FCVT_S_WU
   1325          Format(instr, "fcvt.s.wu 'fd, 'rs1");
   1326          break;
   1327 #ifdef JS_CODEGEN_RISCV64
   1328        case 0b00010:  // RO_FCVT_S_L
   1329          Format(instr, "fcvt.s.l  'fd, 'rs1");
   1330          break;
   1331        case 0b00011:  // RO_FCVT_S_LU
   1332          Format(instr, "fcvt.s.lu 'fd, 'rs1");
   1333          break;
   1334 #endif /* JS_CODEGEN_RISCV64 */
   1335        default: {
   1336          UNSUPPORTED_RISCV();
   1337        }
   1338      }
   1339      break;
   1340    }
   1341    case RO_FMV_W_X: {
   1342      if (instr->Funct3Value() == 0b000) {
   1343        Format(instr, "fmv.w.x   'fd, 'rs1");
   1344      } else {
   1345        UNSUPPORTED_RISCV();
   1346      }
   1347      break;
   1348    }
   1349    // TODO(riscv): Add macro for RISCV D extension
   1350    case RO_FADD_D:
   1351      Format(instr, "fadd.d    'fd, 'fs1, 'fs2");
   1352      break;
   1353    case RO_FSUB_D:
   1354      Format(instr, "fsub.d    'fd, 'fs1, 'fs2");
   1355      break;
   1356    case RO_FMUL_D:
   1357      Format(instr, "fmul.d    'fd, 'fs1, 'fs2");
   1358      break;
   1359    case RO_FDIV_D:
   1360      Format(instr, "fdiv.d    'fd, 'fs1, 'fs2");
   1361      break;
   1362    case RO_FSQRT_D: {
   1363      if (instr->Rs2Value() == 0b00000) {
   1364        Format(instr, "fsqrt.d   'fd, 'fs1");
   1365      } else {
   1366        UNSUPPORTED_RISCV();
   1367      }
   1368      break;
   1369    }
   1370    case RO_FSGNJ_D: {  // RO_FSGNJN_D RO_FSGNJX_D
   1371      switch (instr->Funct3Value()) {
   1372        case 0b000:  // RO_FSGNJ_D
   1373          if (instr->Rs1Value() == instr->Rs2Value())
   1374            Format(instr, "fmv.d     'fd, 'fs1");
   1375          else
   1376            Format(instr, "fsgnj.d   'fd, 'fs1, 'fs2");
   1377          break;
   1378        case 0b001:  // RO_FSGNJN_D
   1379          if (instr->Rs1Value() == instr->Rs2Value())
   1380            Format(instr, "fneg.d    'fd, 'fs1");
   1381          else
   1382            Format(instr, "fsgnjn.d  'fd, 'fs1, 'fs2");
   1383          break;
   1384        case 0b010:  // RO_FSGNJX_D
   1385          if (instr->Rs1Value() == instr->Rs2Value())
   1386            Format(instr, "fabs.d    'fd, 'fs1");
   1387          else
   1388            Format(instr, "fsgnjx.d  'fd, 'fs1, 'fs2");
   1389          break;
   1390        default:
   1391          UNSUPPORTED_RISCV();
   1392      }
   1393      break;
   1394    }
   1395    case RO_FMIN_D: {  // RO_FMAX_D
   1396      switch (instr->Funct3Value()) {
   1397        case 0b000:  // RO_FMIN_D
   1398          Format(instr, "fmin.d    'fd, 'fs1, 'fs2");
   1399          break;
   1400        case 0b001:  // RO_FMAX_D
   1401          Format(instr, "fmax.d    'fd, 'fs1, 'fs2");
   1402          break;
   1403        default:
   1404          UNSUPPORTED_RISCV();
   1405      }
   1406      break;
   1407    }
   1408    case (RO_FCVT_S_D & kRFPTypeMask): {
   1409      if (instr->Rs2Value() == 0b00001) {
   1410        Format(instr, "fcvt.s.d  ['frm] 'fd, 'fs1");
   1411      } else {
   1412        UNSUPPORTED_RISCV();
   1413      }
   1414      break;
   1415    }
   1416    case RO_FCVT_D_S: {
   1417      if (instr->Rs2Value() == 0b00000) {
   1418        Format(instr, "fcvt.d.s  'fd, 'fs1");
   1419      } else {
   1420        UNSUPPORTED_RISCV();
   1421      }
   1422      break;
   1423    }
   1424    case RO_FLE_D: {  // RO_FEQ_D RO_FLT_D RO_FLE_D
   1425      switch (instr->Funct3Value()) {
   1426        case 0b010:  // RO_FEQ_S
   1427          Format(instr, "feq.d     'rd, 'fs1, 'fs2");
   1428          break;
   1429        case 0b001:  // RO_FLT_D
   1430          Format(instr, "flt.d     'rd, 'fs1, 'fs2");
   1431          break;
   1432        case 0b000:  // RO_FLE_D
   1433          Format(instr, "fle.d     'rd, 'fs1, 'fs2");
   1434          break;
   1435        default:
   1436          UNSUPPORTED_RISCV();
   1437      }
   1438      break;
   1439    }
   1440    case (RO_FCLASS_D & kRFPTypeMask): {  // RO_FCLASS_D , 64D RO_FMV_X_D
   1441      if (instr->Rs2Value() != 0b00000) {
   1442        UNSUPPORTED_RISCV();
   1443        break;
   1444      }
   1445      switch (instr->Funct3Value()) {
   1446        case 0b001:  // RO_FCLASS_D
   1447          Format(instr, "fclass.d  'rd, 'fs1");
   1448          break;
   1449 #ifdef JS_CODEGEN_RISCV64
   1450        case 0b000:  // RO_FMV_X_D
   1451          Format(instr, "fmv.x.d   'rd, 'fs1");
   1452          break;
   1453 #endif /* JS_CODEGEN_RISCV64 */
   1454        default:
   1455          UNSUPPORTED_RISCV();
   1456      }
   1457      break;
   1458    }
   1459    case RO_FCVT_W_D: {  // RO_FCVT_WU_D , 64F RO_FCVT_L_D RO_FCVT_LU_D
   1460      switch (instr->Rs2Value()) {
   1461        case 0b00000:  // RO_FCVT_W_D
   1462          Format(instr, "fcvt.w.d  ['frm] 'rd, 'fs1");
   1463          break;
   1464        case 0b00001:  // RO_FCVT_WU_D
   1465          Format(instr, "fcvt.wu.d ['frm] 'rd, 'fs1");
   1466          break;
   1467 #ifdef JS_CODEGEN_RISCV64
   1468        case 0b00010:  // RO_FCVT_L_D
   1469          Format(instr, "fcvt.l.d  ['frm] 'rd, 'fs1");
   1470          break;
   1471        case 0b00011:  // RO_FCVT_LU_D
   1472          Format(instr, "fcvt.lu.d ['frm] 'rd, 'fs1");
   1473          break;
   1474 #endif /* JS_CODEGEN_RISCV64 */
   1475        default:
   1476          UNSUPPORTED_RISCV();
   1477      }
   1478      break;
   1479    }
   1480    case RO_FCVT_D_W: {  // RO_FCVT_D_WU , 64F RO_FCVT_D_L RO_FCVT_D_LU
   1481      switch (instr->Rs2Value()) {
   1482        case 0b00000:  // RO_FCVT_D_W
   1483          Format(instr, "fcvt.d.w  'fd, 'rs1");
   1484          break;
   1485        case 0b00001:  // RO_FCVT_D_WU
   1486          Format(instr, "fcvt.d.wu 'fd, 'rs1");
   1487          break;
   1488 #ifdef JS_CODEGEN_RISCV64
   1489        case 0b00010:  // RO_FCVT_D_L
   1490          Format(instr, "fcvt.d.l  'fd, 'rs1");
   1491          break;
   1492        case 0b00011:  // RO_FCVT_D_LU
   1493          Format(instr, "fcvt.d.lu 'fd, 'rs1");
   1494          break;
   1495 #endif /* JS_CODEGEN_RISCV64 */
   1496        default:
   1497          UNSUPPORTED_RISCV();
   1498      }
   1499      break;
   1500    }
   1501 #ifdef JS_CODEGEN_RISCV64
   1502    case RO_FMV_D_X: {
   1503      if (instr->Funct3Value() == 0b000 && instr->Rs2Value() == 0b00000) {
   1504        Format(instr, "fmv.d.x   'fd, 'rs1");
   1505      } else {
   1506        UNSUPPORTED_RISCV();
   1507      }
   1508      break;
   1509    }
   1510 #endif /* JS_CODEGEN_RISCV64 */
   1511    default: {
   1512      UNSUPPORTED_RISCV();
   1513    }
   1514  }
   1515 }
   1516 
   1517 void Decoder::DecodeR4Type(Instruction* instr) {
   1518  switch (instr->InstructionBits() & kR4TypeMask) {
   1519    // TODO(riscv): use F Extension macro block
   1520    case RO_FMADD_S:
   1521      Format(instr, "fmadd.s   'fd, 'fs1, 'fs2, 'fs3");
   1522      break;
   1523    case RO_FMSUB_S:
   1524      Format(instr, "fmsub.s   'fd, 'fs1, 'fs2, 'fs3");
   1525      break;
   1526    case RO_FNMSUB_S:
   1527      Format(instr, "fnmsub.s   'fd, 'fs1, 'fs2, 'fs3");
   1528      break;
   1529    case RO_FNMADD_S:
   1530      Format(instr, "fnmadd.s   'fd, 'fs1, 'fs2, 'fs3");
   1531      break;
   1532    // TODO(riscv): use F Extension macro block
   1533    case RO_FMADD_D:
   1534      Format(instr, "fmadd.d   'fd, 'fs1, 'fs2, 'fs3");
   1535      break;
   1536    case RO_FMSUB_D:
   1537      Format(instr, "fmsub.d   'fd, 'fs1, 'fs2, 'fs3");
   1538      break;
   1539    case RO_FNMSUB_D:
   1540      Format(instr, "fnmsub.d  'fd, 'fs1, 'fs2, 'fs3");
   1541      break;
   1542    case RO_FNMADD_D:
   1543      Format(instr, "fnmadd.d  'fd, 'fs1, 'fs2, 'fs3");
   1544      break;
   1545    default:
   1546      UNSUPPORTED_RISCV();
   1547  }
   1548 }
   1549 
   1550 void Decoder::DecodeIType(Instruction* instr) {
   1551  switch (instr->InstructionBits() & kITypeMask) {
   1552    case RO_JALR:
   1553      if (instr->RdValue() == zero.code() && instr->Rs1Value() == ra.code() &&
   1554          instr->Imm12Value() == 0)
   1555        Format(instr, "ret");
   1556      else if (instr->RdValue() == zero.code() && instr->Imm12Value() == 0)
   1557        Format(instr, "jr        'rs1");
   1558      else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
   1559        Format(instr, "jalr      'rs1");
   1560      else
   1561        Format(instr, "jalr      'rd, 'imm12('rs1)");
   1562      break;
   1563    case RO_LB:
   1564      Format(instr, "lb        'rd, 'imm12('rs1)");
   1565      break;
   1566    case RO_LH:
   1567      Format(instr, "lh        'rd, 'imm12('rs1)");
   1568      break;
   1569    case RO_LW:
   1570      Format(instr, "lw        'rd, 'imm12('rs1)");
   1571      break;
   1572    case RO_LBU:
   1573      Format(instr, "lbu       'rd, 'imm12('rs1)");
   1574      break;
   1575    case RO_LHU:
   1576      Format(instr, "lhu       'rd, 'imm12('rs1)");
   1577      break;
   1578 #ifdef JS_CODEGEN_RISCV64
   1579    case RO_LWU:
   1580      Format(instr, "lwu       'rd, 'imm12('rs1)");
   1581      break;
   1582    case RO_LD:
   1583      Format(instr, "ld        'rd, 'imm12('rs1)");
   1584      break;
   1585 #endif /*JS_CODEGEN_RISCV64*/
   1586    case RO_ADDI:
   1587      if (instr->Imm12Value() == 0) {
   1588        if (instr->RdValue() == zero.code() && instr->Rs1Value() == zero.code())
   1589          Format(instr, "nop");
   1590        else
   1591          Format(instr, "mv        'rd, 'rs1");
   1592      } else if (instr->Rs1Value() == zero.code()) {
   1593        Format(instr, "li        'rd, 'imm12");
   1594      } else {
   1595        Format(instr, "addi      'rd, 'rs1, 'imm12");
   1596      }
   1597      break;
   1598    case RO_SLTI:
   1599      Format(instr, "slti      'rd, 'rs1, 'imm12");
   1600      break;
   1601    case RO_SLTIU:
   1602      if (instr->Imm12Value() == 1)
   1603        Format(instr, "seqz      'rd, 'rs1");
   1604      else
   1605        Format(instr, "sltiu     'rd, 'rs1, 'imm12");
   1606      break;
   1607    case RO_XORI:
   1608      if (instr->Imm12Value() == -1)
   1609        Format(instr, "not       'rd, 'rs1");
   1610      else
   1611        Format(instr, "xori      'rd, 'rs1, 'imm12x");
   1612      break;
   1613    case RO_ORI:
   1614      Format(instr, "ori       'rd, 'rs1, 'imm12x");
   1615      break;
   1616    case RO_ANDI:
   1617      Format(instr, "andi      'rd, 'rs1, 'imm12x");
   1618      break;
   1619    case OP_SHL:
   1620      switch (instr->Funct6FieldRaw() | OP_SHL) {
   1621        case RO_SLLI:
   1622          Format(instr, "slli      'rd, 'rs1, 's64");
   1623          break;
   1624        case RO_BCLRI:
   1625          Format(instr, "bclri     'rd, 'rs1, 's64");
   1626          break;
   1627        case RO_BINVI:
   1628          Format(instr, "binvi     'rd, 'rs1, 's64");
   1629          break;
   1630        case RO_BSETI:
   1631          Format(instr, "bseti     'rd, 'rs1, 's64");
   1632          break;
   1633        case OP_COUNT:
   1634          switch (instr->Shamt()) {
   1635            case 0:
   1636              Format(instr, "clz       'rd, 'rs1");
   1637              break;
   1638            case 1:
   1639              Format(instr, "ctz       'rd, 'rs1");
   1640              break;
   1641            case 2:
   1642              Format(instr, "cpop      'rd, 'rs1");
   1643              break;
   1644            case 4:
   1645              Format(instr, "sext.b    'rd, 'rs1");
   1646              break;
   1647            case 5:
   1648              Format(instr, "sext.h    'rd, 'rs1");
   1649              break;
   1650            default:
   1651              UNSUPPORTED_RISCV();
   1652          }
   1653          break;
   1654        default:
   1655          UNSUPPORTED_RISCV();
   1656      }
   1657      break;
   1658    case OP_SHR: {  //  RO_SRAI
   1659      switch (instr->Funct6FieldRaw() | OP_SHR) {
   1660        case RO_SRLI:
   1661          Format(instr, "srli      'rd, 'rs1, 's64");
   1662          break;
   1663        case RO_SRAI:
   1664          Format(instr, "srai      'rd, 'rs1, 's64");
   1665          break;
   1666        case RO_BEXTI:
   1667          Format(instr, "bexti     'rd, 'rs1, 's64");
   1668          break;
   1669        case RO_ORCB&(kFunct6Mask | OP_SHR):
   1670          Format(instr, "orc.b     'rd, 'rs1");
   1671          break;
   1672        case RO_RORI:
   1673 #ifdef JS_CODEGEN_RISCV64
   1674          Format(instr, "rori      'rd, 'rs1, 's64");
   1675          break;
   1676 #else
   1677          Format(instr, "rori      'rd, 'rs1, 's32");
   1678          break;
   1679 #endif
   1680        case RO_REV8: {
   1681          if (instr->Imm12Value() == RO_REV8_IMM12) {
   1682            Format(instr, "rev8      'rd, 'rs1");
   1683            break;
   1684          }
   1685          UNSUPPORTED_RISCV();
   1686          break;
   1687        }
   1688        default:
   1689          UNSUPPORTED_RISCV();
   1690      }
   1691      break;
   1692    }
   1693 #ifdef JS_CODEGEN_RISCV64
   1694    case RO_ADDIW:
   1695      if (instr->Imm12Value() == 0)
   1696        Format(instr, "sext.w    'rd, 'rs1");
   1697      else
   1698        Format(instr, "addiw     'rd, 'rs1, 'imm12");
   1699      break;
   1700    case OP_SHLW:
   1701      switch (instr->Funct7FieldRaw() | OP_SHLW) {
   1702        case RO_SLLIW:
   1703          Format(instr, "slliw     'rd, 'rs1, 's32");
   1704          break;
   1705        case RO_SLLIUW:
   1706          Format(instr, "slli.uw   'rd, 'rs1, 's32");
   1707          break;
   1708        case OP_COUNTW: {
   1709          switch (instr->Shamt()) {
   1710            case 0:
   1711              Format(instr, "clzw      'rd, 'rs1");
   1712              break;
   1713            case 1:
   1714              Format(instr, "ctzw      'rd, 'rs1");
   1715              break;
   1716            case 2:
   1717              Format(instr, "cpopw     'rd, 'rs1");
   1718              break;
   1719            default:
   1720              UNSUPPORTED_RISCV();
   1721          }
   1722          break;
   1723        }
   1724        default:
   1725          UNSUPPORTED_RISCV();
   1726      }
   1727      break;
   1728    case OP_SHRW: {  //  RO_SRAI
   1729      switch (instr->Funct7FieldRaw() | OP_SHRW) {
   1730        case RO_SRLIW:
   1731          Format(instr, "srliw     'rd, 'rs1, 's32");
   1732          break;
   1733        case RO_SRAIW:
   1734          Format(instr, "sraiw     'rd, 'rs1, 's32");
   1735          break;
   1736        case RO_RORIW:
   1737          Format(instr, "roriw     'rd, 'rs1, 's32");
   1738          break;
   1739        default:
   1740          UNSUPPORTED_RISCV();
   1741      }
   1742      break;
   1743    }
   1744 #endif /*JS_CODEGEN_RISCV64*/
   1745    case RO_FENCE:
   1746      if (instr->MemoryOrder(true) == PSIORW &&
   1747          instr->MemoryOrder(false) == PSIORW)
   1748        Format(instr, "fence");
   1749      else
   1750        Format(instr, "fence 'pre, 'suc");
   1751      break;
   1752    case RO_ECALL: {                   // RO_EBREAK
   1753      if (instr->Imm12Value() == 0) {  // ECALL
   1754        Format(instr, "ecall");
   1755      } else if (instr->Imm12Value() == 1) {  // EBREAK
   1756        Format(instr, "ebreak");
   1757      } else {
   1758        UNSUPPORTED_RISCV();
   1759      }
   1760      break;
   1761    }
   1762    // TODO(riscv): use Zifencei Standard Extension macro block
   1763    case RO_FENCE_I:
   1764      Format(instr, "fence.i");
   1765      break;
   1766    // TODO(riscv): use Zicsr Standard Extension macro block
   1767    // FIXME(RISC-V): Add special formatting for CSR registers
   1768    case RO_CSRRW:
   1769      if (instr->CsrValue() == csr_fcsr) {
   1770        if (instr->RdValue() == zero.code())
   1771          Format(instr, "fscsr     'rs1");
   1772        else
   1773          Format(instr, "fscsr     'rd, 'rs1");
   1774      } else if (instr->CsrValue() == csr_frm) {
   1775        if (instr->RdValue() == zero.code())
   1776          Format(instr, "fsrm      'rs1");
   1777        else
   1778          Format(instr, "fsrm      'rd, 'rs1");
   1779      } else if (instr->CsrValue() == csr_fflags) {
   1780        if (instr->RdValue() == zero.code())
   1781          Format(instr, "fsflags   'rs1");
   1782        else
   1783          Format(instr, "fsflags   'rd, 'rs1");
   1784      } else if (instr->RdValue() == zero.code()) {
   1785        Format(instr, "csrw      'csr, 'rs1");
   1786      } else {
   1787        Format(instr, "csrrw     'rd, 'csr, 'rs1");
   1788      }
   1789      break;
   1790    case RO_CSRRS:
   1791      if (instr->Rs1Value() == zero.code()) {
   1792        switch (instr->CsrValue()) {
   1793          case csr_instret:
   1794            Format(instr, "rdinstret 'rd");
   1795            break;
   1796          case csr_instreth:
   1797            Format(instr, "rdinstreth 'rd");
   1798            break;
   1799          case csr_time:
   1800            Format(instr, "rdtime    'rd");
   1801            break;
   1802          case csr_timeh:
   1803            Format(instr, "rdtimeh   'rd");
   1804            break;
   1805          case csr_cycle:
   1806            Format(instr, "rdcycle   'rd");
   1807            break;
   1808          case csr_cycleh:
   1809            Format(instr, "rdcycleh  'rd");
   1810            break;
   1811          case csr_fflags:
   1812            Format(instr, "frflags   'rd");
   1813            break;
   1814          case csr_frm:
   1815            Format(instr, "frrm      'rd");
   1816            break;
   1817          case csr_fcsr:
   1818            Format(instr, "frcsr     'rd");
   1819            break;
   1820          default:
   1821            MOZ_CRASH();
   1822        }
   1823      } else if (instr->Rs1Value() == zero.code()) {
   1824        Format(instr, "csrr      'rd, 'csr");
   1825      } else if (instr->RdValue() == zero.code()) {
   1826        Format(instr, "csrs      'csr, 'rs1");
   1827      } else {
   1828        Format(instr, "csrrs     'rd, 'csr, 'rs1");
   1829      }
   1830      break;
   1831    case RO_CSRRC:
   1832      if (instr->RdValue() == zero.code())
   1833        Format(instr, "csrc      'csr, 'rs1");
   1834      else
   1835        Format(instr, "csrrc     'rd, 'csr, 'rs1");
   1836      break;
   1837    case RO_CSRRWI:
   1838      if (instr->RdValue() == zero.code())
   1839        Format(instr, "csrwi     'csr, 'uimm");
   1840      else
   1841        Format(instr, "csrrwi    'rd, 'csr, 'uimm");
   1842      break;
   1843    case RO_CSRRSI:
   1844      if (instr->RdValue() == zero.code())
   1845        Format(instr, "csrsi     'csr, 'uimm");
   1846      else
   1847        Format(instr, "csrrsi    'rd, 'csr, 'uimm");
   1848      break;
   1849    case RO_CSRRCI:
   1850      if (instr->RdValue() == zero.code())
   1851        Format(instr, "csrci     'csr, 'uimm");
   1852      else
   1853        Format(instr, "csrrci    'rd, 'csr, 'uimm");
   1854      break;
   1855    // TODO(riscv): use F Extension macro block
   1856    case RO_FLW:
   1857      Format(instr, "flw       'fd, 'imm12('rs1)");
   1858      break;
   1859    // TODO(riscv): use D Extension macro block
   1860    case RO_FLD:
   1861      Format(instr, "fld       'fd, 'imm12('rs1)");
   1862      break;
   1863    default:
   1864 #ifdef CAN_USE_RVV_INSTRUCTIONS
   1865      if (instr->vl_vs_width() != -1) {
   1866        DecodeRvvVL(instr);
   1867      } else {
   1868        UNSUPPORTED_RISCV();
   1869      }
   1870      break;
   1871 #else
   1872      UNSUPPORTED_RISCV();
   1873 #endif
   1874  }
   1875 }
   1876 
   1877 void Decoder::DecodeSType(Instruction* instr) {
   1878  switch (instr->InstructionBits() & kSTypeMask) {
   1879    case RO_SB:
   1880      Format(instr, "sb        'rs2, 'offS('rs1)");
   1881      break;
   1882    case RO_SH:
   1883      Format(instr, "sh        'rs2, 'offS('rs1)");
   1884      break;
   1885    case RO_SW:
   1886      Format(instr, "sw        'rs2, 'offS('rs1)");
   1887      break;
   1888 #ifdef JS_CODEGEN_RISCV64
   1889    case RO_SD:
   1890      Format(instr, "sd        'rs2, 'offS('rs1)");
   1891      break;
   1892 #endif /*JS_CODEGEN_RISCV64*/
   1893    // TODO(riscv): use F Extension macro block
   1894    case RO_FSW:
   1895      Format(instr, "fsw       'fs2, 'offS('rs1)");
   1896      break;
   1897    // TODO(riscv): use D Extension macro block
   1898    case RO_FSD:
   1899      Format(instr, "fsd       'fs2, 'offS('rs1)");
   1900      break;
   1901    default:
   1902 #ifdef CAN_USE_RVV_INSTRUCTIONS
   1903      if (instr->vl_vs_width() != -1) {
   1904        DecodeRvvVS(instr);
   1905      } else {
   1906        UNSUPPORTED_RISCV();
   1907      }
   1908      break;
   1909 #else
   1910      UNSUPPORTED_RISCV();
   1911 #endif
   1912  }
   1913 }
   1914 
   1915 void Decoder::DecodeBType(Instruction* instr) {
   1916  switch (instr->InstructionBits() & kBTypeMask) {
   1917    case RO_BEQ:
   1918      Format(instr, "beq       'rs1, 'rs2, 'offB");
   1919      break;
   1920    case RO_BNE:
   1921      Format(instr, "bne       'rs1, 'rs2, 'offB");
   1922      break;
   1923    case RO_BLT:
   1924      Format(instr, "blt       'rs1, 'rs2, 'offB");
   1925      break;
   1926    case RO_BGE:
   1927      Format(instr, "bge       'rs1, 'rs2, 'offB");
   1928      break;
   1929    case RO_BLTU:
   1930      Format(instr, "bltu      'rs1, 'rs2, 'offB");
   1931      break;
   1932    case RO_BGEU:
   1933      Format(instr, "bgeu      'rs1, 'rs2, 'offB");
   1934      break;
   1935    default:
   1936      UNSUPPORTED_RISCV();
   1937  }
   1938 }
   1939 void Decoder::DecodeUType(Instruction* instr) {
   1940  // U Type doesn't have additional mask
   1941  switch (instr->BaseOpcodeFieldRaw()) {
   1942    case LUI:
   1943      Format(instr, "lui       'rd, 'imm20U");
   1944      break;
   1945    case AUIPC:
   1946      Format(instr, "auipc     'rd, 'imm20U");
   1947      break;
   1948    default:
   1949      UNSUPPORTED_RISCV();
   1950  }
   1951 }
   1952 // namespace jit
   1953 void Decoder::DecodeJType(Instruction* instr) {
   1954  // J Type doesn't have additional mask
   1955  switch (instr->BaseOpcodeValue()) {
   1956    case JAL:
   1957      if (instr->RdValue() == zero.code())
   1958        Format(instr, "j         'imm20J");
   1959      else if (instr->RdValue() == ra.code())
   1960        Format(instr, "jal       'imm20J");
   1961      else
   1962        Format(instr, "jal       'rd, 'imm20J");
   1963      break;
   1964    default:
   1965      UNSUPPORTED_RISCV();
   1966  }
   1967 }
   1968 
   1969 void Decoder::DecodeCRType(Instruction* instr) {
   1970  switch (instr->RvcFunct4Value()) {
   1971    case 0b1000:
   1972      if (instr->RvcRs1Value() != 0 && instr->RvcRs2Value() == 0)
   1973        Format(instr, "jr        'Crs1");
   1974      else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() != 0)
   1975        Format(instr, "mv        'Crd, 'Crs2");
   1976      else
   1977        UNSUPPORTED_RISCV();
   1978      break;
   1979    case 0b1001:
   1980      if (instr->RvcRs1Value() == 0 && instr->RvcRs2Value() == 0)
   1981        Format(instr, "ebreak");
   1982      else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() == 0)
   1983        Format(instr, "jalr      'Crs1");
   1984      else if (instr->RvcRdValue() != 0 && instr->RvcRs2Value() != 0)
   1985        Format(instr, "add       'Crd, 'Crd, 'Crs2");
   1986      else
   1987        UNSUPPORTED_RISCV();
   1988      break;
   1989    default:
   1990      UNSUPPORTED_RISCV();
   1991  }
   1992 }
   1993 
   1994 void Decoder::DecodeCAType(Instruction* instr) {
   1995  switch (instr->InstructionBits() & kCATypeMask) {
   1996    case RO_C_SUB:
   1997      Format(instr, "sub       'Crs1s, 'Crs1s, 'Crs2s");
   1998      break;
   1999    case RO_C_XOR:
   2000      Format(instr, "xor       'Crs1s, 'Crs1s, 'Crs2s");
   2001      break;
   2002    case RO_C_OR:
   2003      Format(instr, "or       'Crs1s, 'Crs1s, 'Crs2s");
   2004      break;
   2005    case RO_C_AND:
   2006      Format(instr, "and       'Crs1s, 'Crs1s, 'Crs2s");
   2007      break;
   2008 #ifdef JS_CODEGEN_RISCV64
   2009    case RO_C_SUBW:
   2010      Format(instr, "subw       'Crs1s, 'Crs1s, 'Crs2s");
   2011      break;
   2012    case RO_C_ADDW:
   2013      Format(instr, "addw       'Crs1s, 'Crs1s, 'Crs2s");
   2014      break;
   2015 #endif
   2016    default:
   2017      UNSUPPORTED_RISCV();
   2018  }
   2019 }
   2020 
   2021 void Decoder::DecodeCIType(Instruction* instr) {
   2022  switch (instr->RvcOpcode()) {
   2023    case RO_C_NOP_ADDI:
   2024      if (instr->RvcRdValue() == 0)
   2025        Format(instr, "nop");
   2026      else
   2027        Format(instr, "addi      'Crd, 'Crd, 'Cimm6");
   2028      break;
   2029 #ifdef JS_CODEGEN_RISCV64
   2030    case RO_C_ADDIW:
   2031      Format(instr, "addiw     'Crd, 'Crd, 'Cimm6");
   2032      break;
   2033 #endif
   2034    case RO_C_LI:
   2035      Format(instr, "li        'Crd, 'Cimm6");
   2036      break;
   2037    case RO_C_LUI_ADD:
   2038      if (instr->RvcRdValue() == 2)
   2039        Format(instr, "addi      sp, sp, 'Cimm6Addi16sp");
   2040      else if (instr->RvcRdValue() != 0 && instr->RvcRdValue() != 2)
   2041        Format(instr, "lui       'Crd, 'Cimm6U");
   2042      else
   2043        UNSUPPORTED_RISCV();
   2044      break;
   2045    case RO_C_SLLI:
   2046      Format(instr, "slli      'Crd, 'Crd, 'Cshamt");
   2047      break;
   2048    case RO_C_FLDSP:
   2049      Format(instr, "fld       'Cfd, 'Cimm6Ldsp(sp)");
   2050      break;
   2051    case RO_C_LWSP:
   2052      Format(instr, "lw        'Crd, 'Cimm6Lwsp(sp)");
   2053      break;
   2054 #ifdef JS_CODEGEN_RISCV64
   2055    case RO_C_LDSP:
   2056      Format(instr, "ld        'Crd, 'Cimm6Ldsp(sp)");
   2057      break;
   2058 #elif defined(JS_CODEGEN_RISCV32)
   2059    case RO_C_FLWSP:
   2060      Format(instr, "flw       'Cfd, 'Cimm6Ldsp(sp)");
   2061      break;
   2062 #endif
   2063    default:
   2064      UNSUPPORTED_RISCV();
   2065  }
   2066 }
   2067 
   2068 void Decoder::DecodeCIWType(Instruction* instr) {
   2069  switch (instr->RvcOpcode()) {
   2070    case RO_C_ADDI4SPN:
   2071      Format(instr, "addi       'Crs2s, sp, 'Cimm8Addi4spn");
   2072      break;
   2073    default:
   2074      UNSUPPORTED_RISCV();
   2075  }
   2076 }
   2077 
   2078 void Decoder::DecodeCSSType(Instruction* instr) {
   2079  switch (instr->RvcOpcode()) {
   2080    case RO_C_SWSP:
   2081      Format(instr, "sw        'Crs2, 'Cimm6Swsp(sp)");
   2082      break;
   2083 #ifdef JS_CODEGEN_RISCV64
   2084    case RO_C_SDSP:
   2085      Format(instr, "sd        'Crs2, 'Cimm6Sdsp(sp)");
   2086      break;
   2087 #elif defined(JS_CODEGEN_RISCV32)
   2088    case RO_C_FSWSP:
   2089      Format(instr, "fsw       'Cfs2, 'Cimm6Sdsp(sp)");
   2090      break;
   2091 #endif
   2092    case RO_C_FSDSP:
   2093      Format(instr, "fsd       'Cfs2, 'Cimm6Sdsp(sp)");
   2094      break;
   2095    default:
   2096      UNSUPPORTED_RISCV();
   2097  }
   2098 }
   2099 
   2100 void Decoder::DecodeCLType(Instruction* instr) {
   2101  switch (instr->RvcOpcode()) {
   2102    case RO_C_FLD:
   2103      Format(instr, "fld       'Cfs2s, 'Cimm5D('Crs1s)");
   2104      break;
   2105    case RO_C_LW:
   2106      Format(instr, "lw       'Crs2s, 'Cimm5W('Crs1s)");
   2107      break;
   2108 #ifdef JS_CODEGEN_RISCV64
   2109    case RO_C_LD:
   2110      Format(instr, "ld       'Crs2s, 'Cimm5D('Crs1s)");
   2111      break;
   2112 #elif defined(JS_CODEGEN_RISCV32)
   2113    case RO_C_FLW:
   2114      Format(instr, "fld       'Cfs2s, 'Cimm5D('Crs1s)");
   2115      break;
   2116 #endif
   2117 
   2118    default:
   2119      UNSUPPORTED_RISCV();
   2120  }
   2121 }
   2122 
   2123 void Decoder::DecodeCSType(Instruction* instr) {
   2124  switch (instr->RvcOpcode()) {
   2125    case RO_C_FSD:
   2126      Format(instr, "fsd       'Cfs2s, 'Cimm5D('Crs1s)");
   2127      break;
   2128    case RO_C_SW:
   2129      Format(instr, "sw       'Crs2s, 'Cimm5W('Crs1s)");
   2130      break;
   2131 #ifdef JS_CODEGEN_RISCV64
   2132    case RO_C_SD:
   2133      Format(instr, "sd       'Crs2s, 'Cimm5D('Crs1s)");
   2134      break;
   2135 #elif defined(JS_CODEGEN_RISCV32)
   2136    case RO_C_FSW:
   2137      Format(instr, "fsw       'Cfs2s, 'Cimm5D('Crs1s)");
   2138      break;
   2139 #endif
   2140    default:
   2141      UNSUPPORTED_RISCV();
   2142  }
   2143 }
   2144 
   2145 void Decoder::DecodeCJType(Instruction* instr) {
   2146  switch (instr->RvcOpcode()) {
   2147    case RO_C_J:
   2148      Format(instr, "j       'Cimm11CJ");
   2149      break;
   2150    default:
   2151      UNSUPPORTED_RISCV();
   2152  }
   2153 }
   2154 
   2155 void Decoder::DecodeCBType(Instruction* instr) {
   2156  switch (instr->RvcOpcode()) {
   2157    case RO_C_BNEZ:
   2158      Format(instr, "bnez       'Crs1s, x0, 'Cimm8B");
   2159      break;
   2160    case RO_C_BEQZ:
   2161      Format(instr, "beqz       'Crs1s, x0, 'Cimm8B");
   2162      break;
   2163    case RO_C_MISC_ALU:
   2164      if (instr->RvcFunct2BValue() == 0b00)
   2165        Format(instr, "srli       'Crs1s, 'Crs1s, 'Cshamt");
   2166      else if (instr->RvcFunct2BValue() == 0b01)
   2167        Format(instr, "srai       'Crs1s, 'Crs1s, 'Cshamt");
   2168      else if (instr->RvcFunct2BValue() == 0b10)
   2169        Format(instr, "andi       'Crs1s, 'Crs1s, 'Cimm6");
   2170      else
   2171        UNSUPPORTED_RISCV();
   2172      break;
   2173    default:
   2174      UNSUPPORTED_RISCV();
   2175  }
   2176 }
   2177 
   2178 #undef VERIFIY
   2179 
   2180 bool Decoder::IsConstantPoolAt(uint8_t* instr_ptr) {
   2181  UNSUPPORTED_RISCV();
   2182  MOZ_CRASH();
   2183 }
   2184 
   2185 int Decoder::ConstantPoolSizeAt(uint8_t* instr_ptr) {
   2186  UNSUPPORTED_RISCV();
   2187  MOZ_CRASH();
   2188 }
   2189 
   2190 // Disassemble the instruction at *instr_ptr into the output buffer.
   2191 int Decoder::InstructionDecode(byte* instr_ptr) {
   2192  Instruction* instr = Instruction::At(instr_ptr);
   2193  // Print raw instruction bytes.
   2194  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x       ",
   2195                              instr->InstructionBits());
   2196  switch (instr->InstructionType()) {
   2197    case Instruction::kRType:
   2198      DecodeRType(instr);
   2199      break;
   2200    case Instruction::kR4Type:
   2201      DecodeR4Type(instr);
   2202      break;
   2203    case Instruction::kIType:
   2204      DecodeIType(instr);
   2205      break;
   2206    case Instruction::kSType:
   2207      DecodeSType(instr);
   2208      break;
   2209    case Instruction::kBType:
   2210      DecodeBType(instr);
   2211      break;
   2212    case Instruction::kUType:
   2213      DecodeUType(instr);
   2214      break;
   2215    case Instruction::kJType:
   2216      DecodeJType(instr);
   2217      break;
   2218    case Instruction::kCRType:
   2219      DecodeCRType(instr);
   2220      break;
   2221    case Instruction::kCAType:
   2222      DecodeCAType(instr);
   2223      break;
   2224    case Instruction::kCJType:
   2225      DecodeCJType(instr);
   2226      break;
   2227    case Instruction::kCIType:
   2228      DecodeCIType(instr);
   2229      break;
   2230    case Instruction::kCIWType:
   2231      DecodeCIWType(instr);
   2232      break;
   2233    case Instruction::kCSSType:
   2234      DecodeCSSType(instr);
   2235      break;
   2236    case Instruction::kCLType:
   2237      DecodeCLType(instr);
   2238      break;
   2239    case Instruction::kCSType:
   2240      DecodeCSType(instr);
   2241      break;
   2242    case Instruction::kCBType:
   2243      DecodeCBType(instr);
   2244      break;
   2245 #ifdef CAN_USE_RVV_INSTRUCTIONS
   2246    case Instruction::kVType:
   2247      DecodeVType(instr);
   2248      break;
   2249 #endif
   2250    default:
   2251      Format(instr, "UNSUPPORTED");
   2252      UNSUPPORTED_RISCV();
   2253  }
   2254  return instr->InstructionSize();
   2255 }
   2256 
   2257 }  // namespace disasm
   2258 
   2259 #undef STRING_STARTS_WITH
   2260 #undef VERIFY
   2261 
   2262 //------------------------------------------------------------------------------
   2263 
   2264 namespace disasm {
   2265 
   2266 const char* NameConverter::NameOfAddress(uint8_t* addr) const {
   2267  SNPrintF(tmp_buffer_, "%p", addr);
   2268  return tmp_buffer_.start();
   2269 }
   2270 
   2271 const char* NameConverter::NameOfConstant(uint8_t* addr) const {
   2272  return NameOfAddress(addr);
   2273 }
   2274 
   2275 const char* NameConverter::NameOfCPURegister(int reg) const {
   2276  return Registers::GetName(reg);
   2277 }
   2278 
   2279 const char* NameConverter::NameOfByteCPURegister(int reg) const {
   2280  MOZ_CRASH(" RISC-V does not have the concept of a byte register.");
   2281 }
   2282 
   2283 const char* NameConverter::NameOfXMMRegister(int reg) const {
   2284  return FloatRegisters::GetName(reg);
   2285 }
   2286 
   2287 const char* NameConverter::NameInCode(uint8_t* addr) const {
   2288  // The default name converter is called for unknown code. So we will not try
   2289  // to access any memory.
   2290  return "";
   2291 }
   2292 
   2293 //------------------------------------------------------------------------------
   2294 
   2295 Disassembler::Disassembler(const NameConverter& converter)
   2296    : converter_(converter) {}
   2297 
   2298 Disassembler::~Disassembler() {}
   2299 
   2300 int Disassembler::InstructionDecode(V8Vector<char> buffer,
   2301                                    uint8_t* instruction) {
   2302  Decoder d(converter_, buffer);
   2303  return d.InstructionDecode(instruction);
   2304 }
   2305 
   2306 int Disassembler::ConstantPoolSizeAt(uint8_t* instruction) {
   2307  return Decoder::ConstantPoolSizeAt(instruction);
   2308 }
   2309 
   2310 void Disassembler::Disassemble(FILE* f, uint8_t* begin, uint8_t* end) {
   2311  NameConverter converter;
   2312  Disassembler d(converter);
   2313  for (uint8_t* pc = begin; pc < end;) {
   2314    EmbeddedVector<char, ReasonableBufferSize> buffer;
   2315    buffer[0] = '\0';
   2316    uint8_t* prev_pc = pc;
   2317    pc += d.InstructionDecode(buffer, pc);
   2318    fprintf(f, "%p    %08x      %s\n", prev_pc,
   2319            *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
   2320  }
   2321 }
   2322 
   2323 }  // namespace disasm
   2324 }  // namespace jit
   2325 }  // namespace js