tor-browser

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

Base-constant-riscv.h (35482B)


      1 // Copyright 2022 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 #ifndef jit_riscv64_constant_Base_constant_riscv__h_
      5 #define jit_riscv64_constant_Base_constant_riscv__h_
      6 
      7 #include "mozilla/Assertions.h"
      8 
      9 namespace js {
     10 namespace jit {
     11 
     12 // On RISC-V Simulator breakpoints can have different codes:
     13 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
     14 //   the simulator will run through them and print the registers.
     15 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
     16 //   instructions (see Assembler::stop()).
     17 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
     18 //   debugger.
     19 const uint32_t kMaxTracepointCode = 63;
     20 const uint32_t kMaxWatchpointCode = 31;
     21 const uint32_t kMaxStopCode = 127;
     22 const uint32_t kWasmTrapCode = 6;
     23 static_assert(kMaxWatchpointCode < kMaxStopCode);
     24 static_assert(kMaxTracepointCode < kMaxStopCode);
     25 
     26 // Debug parameters.
     27 //
     28 // For example:
     29 //
     30 // __ Debug(TRACE_ENABLE | LOG_TRACE);
     31 // starts tracing: set v8_flags.trace-sim is true.
     32 // __ Debug(TRACE_ENABLE | LOG_REGS);
     33 // PrintAllregs.
     34 // __ Debug(TRACE_DISABLE | LOG_TRACE);
     35 // stops tracing: set v8_flags.trace-sim is false.
     36 const uint32_t kDebuggerTracingDirectivesMask = 0b111 << 3;
     37 enum DebugParameters : uint32_t {
     38  NO_PARAM = 1 << 5,
     39  BREAK = 1 << 0,
     40  LOG_TRACE = 1 << 1,
     41  LOG_REGS = 1 << 2,
     42  LOG_ALL = LOG_TRACE,
     43  // Trace control.
     44  TRACE_ENABLE = 1 << 3 | NO_PARAM,
     45  TRACE_DISABLE = 1 << 4 | NO_PARAM,
     46 };
     47 // On RISCV all instructions are 32 bits, except for RVC.
     48 using Instr = int32_t;
     49 using ShortInstr = int16_t;
     50 typedef unsigned char byte;
     51 // ----- Fields offset and length.
     52 // RISCV constants
     53 const int kBaseOpcodeShift = 0;
     54 const int kBaseOpcodeBits = 7;
     55 const int kFunct6Shift = 26;
     56 const int kFunct6Bits = 6;
     57 const int kFunct7Shift = 25;
     58 const int kFunct7Bits = 7;
     59 const int kFunct5Shift = 27;
     60 const int kFunct5Bits = 5;
     61 const int kFunct3Shift = 12;
     62 const int kFunct3Bits = 3;
     63 const int kFunct2Shift = 25;
     64 const int kFunct2Bits = 2;
     65 const int kRs1Shift = 15;
     66 const int kRs1Bits = 5;
     67 const int kVs1Shift = 15;
     68 const int kVs1Bits = 5;
     69 const int kVs2Shift = 20;
     70 const int kVs2Bits = 5;
     71 const int kVdShift = 7;
     72 const int kVdBits = 5;
     73 const int kRs2Shift = 20;
     74 const int kRs2Bits = 5;
     75 const int kRs3Shift = 27;
     76 const int kRs3Bits = 5;
     77 const int kRdShift = 7;
     78 const int kRdBits = 5;
     79 const int kRlShift = 25;
     80 const int kAqShift = 26;
     81 const int kImm12Shift = 20;
     82 const int kImm12Bits = 12;
     83 const int kImm11Shift = 2;
     84 const int kImm11Bits = 11;
     85 const int kShamtShift = 20;
     86 const int kShamtBits = 5;
     87 const uint32_t kShamtMask = (((1 << kShamtBits) - 1) << kShamtShift);
     88 const int kShamtWShift = 20;
     89 // FIXME: remove this once we have a proper way to handle the wide shift amount
     90 const int kShamtWBits = 6;
     91 const int kArithShiftShift = 30;
     92 const int kImm20Shift = 12;
     93 const int kImm20Bits = 20;
     94 const int kCsrShift = 20;
     95 const int kCsrBits = 12;
     96 const int kMemOrderBits = 4;
     97 const int kPredOrderShift = 24;
     98 const int kSuccOrderShift = 20;
     99 
    100 // for C extension
    101 const int kRvcFunct4Shift = 12;
    102 const int kRvcFunct4Bits = 4;
    103 const int kRvcFunct3Shift = 13;
    104 const int kRvcFunct3Bits = 3;
    105 const int kRvcRs1Shift = 7;
    106 const int kRvcRs1Bits = 5;
    107 const int kRvcRs2Shift = 2;
    108 const int kRvcRs2Bits = 5;
    109 const int kRvcRdShift = 7;
    110 const int kRvcRdBits = 5;
    111 const int kRvcRs1sShift = 7;
    112 const int kRvcRs1sBits = 3;
    113 const int kRvcRs2sShift = 2;
    114 const int kRvcRs2sBits = 3;
    115 const int kRvcFunct2Shift = 5;
    116 const int kRvcFunct2BShift = 10;
    117 const int kRvcFunct2Bits = 2;
    118 const int kRvcFunct6Shift = 10;
    119 const int kRvcFunct6Bits = 6;
    120 
    121 const uint32_t kRvcOpcodeMask =
    122    0b11 | (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
    123 const uint32_t kRvcFunct3Mask =
    124    (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
    125 const uint32_t kRvcFunct4Mask =
    126    (((1 << kRvcFunct4Bits) - 1) << kRvcFunct4Shift);
    127 const uint32_t kRvcFunct6Mask =
    128    (((1 << kRvcFunct6Bits) - 1) << kRvcFunct6Shift);
    129 const uint32_t kRvcFunct2Mask =
    130    (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2Shift);
    131 const uint32_t kRvcFunct2BMask =
    132    (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2BShift);
    133 const uint32_t kCRTypeMask = kRvcOpcodeMask | kRvcFunct4Mask;
    134 const uint32_t kCSTypeMask = kRvcOpcodeMask | kRvcFunct6Mask;
    135 const uint32_t kCATypeMask = kRvcOpcodeMask | kRvcFunct6Mask | kRvcFunct2Mask;
    136 const uint32_t kRvcBImm8Mask = (((1 << 5) - 1) << 2) | (((1 << 3) - 1) << 10);
    137 
    138 // RISCV Instruction bit masks
    139 const uint32_t kBaseOpcodeMask = ((1 << kBaseOpcodeBits) - 1)
    140                                 << kBaseOpcodeShift;
    141 const uint32_t kFunct3Mask = ((1 << kFunct3Bits) - 1) << kFunct3Shift;
    142 const uint32_t kFunct5Mask = ((1 << kFunct5Bits) - 1) << kFunct5Shift;
    143 const uint32_t kFunct6Mask = ((1 << kFunct6Bits) - 1) << kFunct6Shift;
    144 const uint32_t kFunct7Mask = ((1 << kFunct7Bits) - 1) << kFunct7Shift;
    145 const uint32_t kFunct2Mask = 0b11 << kFunct7Shift;
    146 const uint32_t kRTypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct7Mask;
    147 const uint32_t kRATypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct5Mask;
    148 const uint32_t kRFPTypeMask = kBaseOpcodeMask | kFunct7Mask;
    149 const uint32_t kR4TypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct2Mask;
    150 const uint32_t kITypeMask = kBaseOpcodeMask | kFunct3Mask;
    151 const uint32_t kSTypeMask = kBaseOpcodeMask | kFunct3Mask;
    152 const uint32_t kBTypeMask = kBaseOpcodeMask | kFunct3Mask;
    153 const uint32_t kUTypeMask = kBaseOpcodeMask;
    154 const uint32_t kJTypeMask = kBaseOpcodeMask;
    155 const uint32_t kRs1FieldMask = ((1 << kRs1Bits) - 1) << kRs1Shift;
    156 const uint32_t kRs2FieldMask = ((1 << kRs2Bits) - 1) << kRs2Shift;
    157 const uint32_t kRs3FieldMask = ((1 << kRs3Bits) - 1) << kRs3Shift;
    158 const uint32_t kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
    159 const uint32_t kBImm12Mask = kFunct7Mask | kRdFieldMask;
    160 const uint32_t kImm20Mask = ((1 << kImm20Bits) - 1) << kImm20Shift;
    161 const uint32_t kImm12Mask = ((1 << kImm12Bits) - 1) << kImm12Shift;
    162 const uint32_t kImm11Mask = ((1 << kImm11Bits) - 1) << kImm11Shift;
    163 const uint32_t kImm31_12Mask = ((1 << 20) - 1) << 12;
    164 const uint32_t kImm19_0Mask = ((1 << 20) - 1);
    165 
    166 // for RVV extension
    167 #define RVV_LMUL(V) \
    168  V(m1)             \
    169  V(m2)             \
    170  V(m4)             \
    171  V(m8)             \
    172  V(RESERVERD)      \
    173  V(mf8)            \
    174  V(mf4)            \
    175  V(mf2)
    176 
    177 enum Vlmul {
    178 #define DEFINE_FLAG(name) name,
    179  RVV_LMUL(DEFINE_FLAG)
    180 #undef DEFINE_FLAG
    181 };
    182 
    183 #define RVV_SEW(V) \
    184  V(E8)            \
    185  V(E16)           \
    186  V(E32)           \
    187  V(E64)
    188 
    189 #define DEFINE_FLAG(name) name,
    190 enum VSew {
    191  RVV_SEW(DEFINE_FLAG)
    192 #undef DEFINE_FLAG
    193 };
    194 
    195 constexpr int kRvvELEN = 64;
    196 constexpr int kRvvVLEN = 128;
    197 constexpr int kRvvSLEN = kRvvVLEN;
    198 const int kRvvFunct6Shift = 26;
    199 const int kRvvFunct6Bits = 6;
    200 const uint32_t kRvvFunct6Mask =
    201    (((1 << kRvvFunct6Bits) - 1) << kRvvFunct6Shift);
    202 
    203 const int kRvvVmBits = 1;
    204 const int kRvvVmShift = 25;
    205 const uint32_t kRvvVmMask = (((1 << kRvvVmBits) - 1) << kRvvVmShift);
    206 
    207 const int kRvvVs2Bits = 5;
    208 const int kRvvVs2Shift = 20;
    209 const uint32_t kRvvVs2Mask = (((1 << kRvvVs2Bits) - 1) << kRvvVs2Shift);
    210 
    211 const int kRvvVs1Bits = 5;
    212 const int kRvvVs1Shift = 15;
    213 const uint32_t kRvvVs1Mask = (((1 << kRvvVs1Bits) - 1) << kRvvVs1Shift);
    214 
    215 const int kRvvRs1Bits = kRvvVs1Bits;
    216 const int kRvvRs1Shift = kRvvVs1Shift;
    217 const uint32_t kRvvRs1Mask = (((1 << kRvvRs1Bits) - 1) << kRvvRs1Shift);
    218 
    219 const int kRvvRs2Bits = 5;
    220 const int kRvvRs2Shift = 20;
    221 const uint32_t kRvvRs2Mask = (((1 << kRvvRs2Bits) - 1) << kRvvRs2Shift);
    222 
    223 const int kRvvImm5Bits = kRvvVs1Bits;
    224 const int kRvvImm5Shift = kRvvVs1Shift;
    225 const uint32_t kRvvImm5Mask = (((1 << kRvvImm5Bits) - 1) << kRvvImm5Shift);
    226 
    227 const int kRvvVdBits = 5;
    228 const int kRvvVdShift = 7;
    229 const uint32_t kRvvVdMask = (((1 << kRvvVdBits) - 1) << kRvvVdShift);
    230 
    231 const int kRvvRdBits = kRvvVdBits;
    232 const int kRvvRdShift = kRvvVdShift;
    233 const uint32_t kRvvRdMask = (((1 << kRvvRdBits) - 1) << kRvvRdShift);
    234 
    235 const int kRvvZimmBits = 11;
    236 const int kRvvZimmShift = 20;
    237 const uint32_t kRvvZimmMask = (((1 << kRvvZimmBits) - 1) << kRvvZimmShift);
    238 
    239 const int kRvvUimmShift = kRvvRs1Shift;
    240 const int kRvvUimmBits = kRvvRs1Bits;
    241 const uint32_t kRvvUimmMask = (((1 << kRvvUimmBits) - 1) << kRvvUimmShift);
    242 
    243 const int kRvvWidthBits = 3;
    244 const int kRvvWidthShift = 12;
    245 const uint32_t kRvvWidthMask = (((1 << kRvvWidthBits) - 1) << kRvvWidthShift);
    246 
    247 const int kRvvMopBits = 2;
    248 const int kRvvMopShift = 26;
    249 const uint32_t kRvvMopMask = (((1 << kRvvMopBits) - 1) << kRvvMopShift);
    250 
    251 const int kRvvMewBits = 1;
    252 const int kRvvMewShift = 28;
    253 const uint32_t kRvvMewMask = (((1 << kRvvMewBits) - 1) << kRvvMewShift);
    254 
    255 const int kRvvNfBits = 3;
    256 const int kRvvNfShift = 29;
    257 const uint32_t kRvvNfMask = (((1 << kRvvNfBits) - 1) << kRvvNfShift);
    258 
    259 const int kNopByte = 0x00000013;
    260 
    261 enum BaseOpcode : uint32_t {
    262  LOAD = 0b0000011,       // I form: LB LH LW LBU LHU
    263  LOAD_FP = 0b0000111,    // I form: FLW FLD FLQ
    264  MISC_MEM = 0b0001111,   // I special form: FENCE FENCE.I
    265  OP_IMM = 0b0010011,     // I form: ADDI SLTI SLTIU XORI ORI ANDI
    266  AUIPC = 0b0010111,      // U form: AUIPC
    267  OP_IMM_32 = 0b0011011,  // I form: ADDIW SLLIW SRLIW SRAIW
    268  // Note:  SRLIW SRAIW I form first, then func3 101 special shift encoding
    269  STORE = 0b0100011,     // S form: SB SH SW SD
    270  STORE_FP = 0b0100111,  // S form: FSW FSD FSQ
    271  AMO = 0b0101111,       // R form: All A instructions
    272  OP = 0b0110011,      // R: ADD SUB SLL SLT SLTU XOR SRL SRA OR AND and 32M set
    273  LUI = 0b0110111,     // U form: LUI
    274  OP_32 = 0b0111011,   // R: ADDW SUBW SLLW SRLW SRAW MULW DIVW DIVUW REMW REMUW
    275  MADD = 0b1000011,    // R4 type: FMADD.S FMADD.D FMADD.Q
    276  MSUB = 0b1000111,    // R4 type: FMSUB.S FMSUB.D FMSUB.Q
    277  NMSUB = 0b1001011,   // R4 type: FNMSUB.S FNMSUB.D FNMSUB.Q
    278  NMADD = 0b1001111,   // R4 type: FNMADD.S FNMADD.D FNMADD.Q
    279  OP_FP = 0b1010011,   // R type: Q ext
    280  BRANCH = 0b1100011,  // B form: BEQ BNE, BLT, BGE, BLTU BGEU
    281  JALR = 0b1100111,    // I form: JALR
    282  JAL = 0b1101111,     // J form: JAL
    283  SYSTEM = 0b1110011,  // I form: ECALL EBREAK Zicsr ext
    284  OP_V = 0b1010111,    // V form: RVV
    285 
    286  // C extension
    287  C0 = 0b00,
    288  C1 = 0b01,
    289  C2 = 0b10,
    290  FUNCT2_0 = 0b00,
    291  FUNCT2_1 = 0b01,
    292  FUNCT2_2 = 0b10,
    293  FUNCT2_3 = 0b11,
    294 };
    295 
    296 // ----- Emulated conditions.
    297 // On RISC-V we use this enum to abstract from conditional branch instructions.
    298 // The 'U' prefix is used to specify unsigned comparisons.
    299 // Opposite conditions must be paired as odd/even numbers
    300 // because 'NegateCondition' function flips LSB to negate condition.
    301 enum RiscvCondition {  // Any value < 0 is considered no_condition.
    302  overflow = 0,
    303  no_overflow = 1,
    304  Uless = 2,
    305  Ugreater_equal = 3,
    306  Uless_equal = 4,
    307  Ugreater = 5,
    308  equal = 6,
    309  not_equal = 7,  // Unordered or Not Equal.
    310  less = 8,
    311  greater_equal = 9,
    312  less_equal = 10,
    313  greater = 11,
    314  cc_always = 12,
    315 
    316  // Aliases.
    317  eq = equal,
    318  ne = not_equal,
    319  ge = greater_equal,
    320  lt = less,
    321  gt = greater,
    322  le = less_equal,
    323  al = cc_always,
    324  ult = Uless,
    325  uge = Ugreater_equal,
    326  ule = Uless_equal,
    327  ugt = Ugreater,
    328 };
    329 
    330 // ----- Coprocessor conditions.
    331 enum FPUCondition {
    332  kNoFPUCondition = -1,
    333  EQ = 0x02,  // Ordered and Equal
    334  NE = 0x03,  // Unordered or Not Equal
    335  LT = 0x04,  // Ordered and Less Than
    336  GE = 0x05,  // Ordered and Greater Than or Equal
    337  LE = 0x06,  // Ordered and Less Than or Equal
    338  GT = 0x07,  // Ordered and Greater Than
    339 };
    340 
    341 enum CheckForInexactConversion {
    342  kCheckForInexactConversion,
    343  kDontCheckForInexactConversion
    344 };
    345 
    346 enum class MaxMinKind : int { kMin = 0, kMax = 1 };
    347 
    348 // ----------------------------------------------------------------------------
    349 // RISCV flags
    350 
    351 enum ControlStatusReg {
    352  csr_fflags = 0x001,   // Floating-Point Accrued Exceptions (RW)
    353  csr_frm = 0x002,      // Floating-Point Dynamic Rounding Mode (RW)
    354  csr_fcsr = 0x003,     // Floating-Point Control and Status Register (RW)
    355  csr_cycle = 0xc00,    // Cycle counter for RDCYCLE instruction (RO)
    356  csr_time = 0xc01,     // Timer for RDTIME instruction (RO)
    357  csr_instret = 0xc02,  // Insns-retired counter for RDINSTRET instruction (RO)
    358  csr_cycleh = 0xc80,   // Upper 32 bits of cycle, RV32I only (RO)
    359  csr_timeh = 0xc81,    // Upper 32 bits of time, RV32I only (RO)
    360  csr_instreth = 0xc82  // Upper 32 bits of instret, RV32I only (RO)
    361 };
    362 
    363 enum FFlagsMask {
    364  kInvalidOperation = 0b10000,  // NV: Invalid
    365  kDivideByZero = 0b1000,       // DZ:  Divide by Zero
    366  kOverflow = 0b100,            // OF: Overflow
    367  kUnderflow = 0b10,            // UF: Underflow
    368  kInexact = 0b1                // NX:  Inexact
    369 };
    370 
    371 enum FPURoundingMode {
    372  RNE = 0b000,  // Round to Nearest, ties to Even
    373  RTZ = 0b001,  // Round towards Zero
    374  RDN = 0b010,  // Round Down (towards -infinity)
    375  RUP = 0b011,  // Round Up (towards +infinity)
    376  RMM = 0b100,  // Round to Nearest, tiest to Max Magnitude
    377  DYN = 0b111   // In instruction's rm field, selects dynamic rounding mode;
    378                // In Rounding Mode register, Invalid
    379 };
    380 
    381 enum MemoryOdering {
    382  PSI = 0b1000,  // PI or SI
    383  PSO = 0b0100,  // PO or SO
    384  PSR = 0b0010,  // PR or SR
    385  PSW = 0b0001,  // PW or SW
    386  PSIORW = PSI | PSO | PSR | PSW
    387 };
    388 
    389 const int kFloat32ExponentBias = 127;
    390 const int kFloat32MantissaBits = 23;
    391 const int kFloat32ExponentBits = 8;
    392 const int kFloat64ExponentBias = 1023;
    393 const int kFloat64MantissaBits = 52;
    394 const int kFloat64ExponentBits = 11;
    395 
    396 enum FClassFlag {
    397  kNegativeInfinity = 1,
    398  kNegativeNormalNumber = 1 << 1,
    399  kNegativeSubnormalNumber = 1 << 2,
    400  kNegativeZero = 1 << 3,
    401  kPositiveZero = 1 << 4,
    402  kPositiveSubnormalNumber = 1 << 5,
    403  kPositiveNormalNumber = 1 << 6,
    404  kPositiveInfinity = 1 << 7,
    405  kSignalingNaN = 1 << 8,
    406  kQuietNaN = 1 << 9
    407 };
    408 
    409 enum OffsetSize : uint32_t {
    410  kOffset21 = 21,  // RISCV jal
    411  kOffset12 = 12,  // RISCV imm12
    412  kOffset20 = 20,  // RISCV imm20
    413  kOffset13 = 13,  // RISCV branch
    414  kOffset32 = 32,  // RISCV auipc + instr_I
    415  kOffset11 = 11,  // RISCV C_J
    416  kOffset9 = 9,    // RISCV compressed branch
    417 };
    418 
    419 // The classes of immediate branch ranges, in order of increasing range.
    420 // Note that CondBranchType and CompareBranchType have the same range.
    421 enum ImmBranchRangeType {
    422  CondBranchRangeType,    //
    423  UncondBranchRangeType,  //
    424  UnknownBranchRangeType,
    425 
    426  // Number of 'short-range' branch range types.
    427  // We don't consider unconditional branches 'short-range'.
    428  NumShortBranchRangeTypes = UnknownBranchRangeType
    429 };
    430 
    431 inline ImmBranchRangeType OffsetSizeToImmBranchRangeType(OffsetSize bits) {
    432  switch (bits) {
    433    case kOffset21:
    434      return UncondBranchRangeType;
    435    case kOffset13:
    436      return CondBranchRangeType;
    437    default:
    438      MOZ_CRASH("Unimplement");
    439  }
    440 }
    441 
    442 inline OffsetSize ImmBranchRangeTypeToOffsetSize(ImmBranchRangeType type) {
    443  switch (type) {
    444    case CondBranchRangeType:
    445      return kOffset13;
    446    case UncondBranchRangeType:
    447      return kOffset21;
    448    default:
    449      MOZ_CRASH("Unimplement");
    450  }
    451 }
    452 
    453 int32_t ImmBranchMaxForwardOffset(OffsetSize bits);
    454 
    455 inline int32_t ImmBranchMaxForwardOffset(ImmBranchRangeType type) {
    456  return ImmBranchMaxForwardOffset(ImmBranchRangeTypeToOffsetSize(type));
    457 }
    458 // -----------------------------------------------------------------------------
    459 // Specific instructions, constants, and masks.
    460 // These constants are declared in assembler-riscv64.cc, as they use named
    461 // registers and other constants.
    462 
    463 // An Illegal instruction
    464 const Instr kIllegalInstr = 0;  // All other bits are 0s (i.e., ecall)
    465 // An ECALL instruction, used for redirected real time call
    466 const Instr rtCallRedirInstr = SYSTEM;  // All other bits are 0s (i.e., ecall)
    467 // An EBreak instruction, used for debugging and semi-hosting
    468 const Instr kBreakInstr = SYSTEM | 1 << kImm12Shift;  // ebreak
    469 
    470 constexpr uint8_t kInstrSize = 4;
    471 constexpr uint8_t kShortInstrSize = 2;
    472 constexpr uint8_t kInstrSizeLog2 = 2;
    473 
    474 class InstructionBase {
    475 public:
    476  enum {
    477    // On RISC-V, PC cannot actually be directly accessed. We behave as if PC
    478    // was always the value of the current instruction being executed.
    479    kPCReadOffset = 0
    480  };
    481 
    482  // Instruction type.
    483  enum Type {
    484    kRType,
    485    kR4Type,  // Special R4 for Q extension
    486    kIType,
    487    kSType,
    488    kBType,
    489    kUType,
    490    kJType,
    491    // C extension
    492    kCRType,
    493    kCIType,
    494    kCSSType,
    495    kCIWType,
    496    kCLType,
    497    kCSType,
    498    kCAType,
    499    kCBType,
    500    kCJType,
    501    // V extension
    502    kVType,
    503    kVLType,
    504    kVSType,
    505    kVAMOType,
    506    kVIVVType,
    507    kVFVVType,
    508    kVMVVType,
    509    kVIVIType,
    510    kVIVXType,
    511    kVFVFType,
    512    kVMVXType,
    513    kVSETType,
    514    kUnsupported = -1
    515  };
    516 
    517  inline bool IsIllegalInstruction() const {
    518    uint16_t FirstHalfWord = *reinterpret_cast<const uint16_t*>(this);
    519    return FirstHalfWord == 0;
    520  }
    521 
    522  bool IsShortInstruction() const;
    523 
    524  inline uint8_t InstructionSize() const {
    525    return (this->IsShortInstruction()) ? kShortInstrSize : kInstrSize;
    526  }
    527 
    528  // Get the raw instruction bits.
    529  inline Instr InstructionBits() const {
    530    if (this->IsShortInstruction()) {
    531      return 0x0000FFFF & (*reinterpret_cast<const ShortInstr*>(this));
    532    }
    533    return *reinterpret_cast<const Instr*>(this);
    534  }
    535 
    536  // Set the raw instruction bits to value.
    537  inline void SetInstructionBits(Instr value) {
    538    *reinterpret_cast<Instr*>(this) = value;
    539  }
    540 
    541  // Read one particular bit out of the instruction bits.
    542  inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
    543 
    544  // Read a bit field out of the instruction bits.
    545  inline int Bits(int hi, int lo) const {
    546    return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
    547  }
    548 
    549  // Accessors for the different named fields used in the RISC-V encoding.
    550  inline BaseOpcode BaseOpcodeValue() const {
    551    return static_cast<BaseOpcode>(
    552        Bits(kBaseOpcodeShift + kBaseOpcodeBits - 1, kBaseOpcodeShift));
    553  }
    554 
    555  // Return the fields at their original place in the instruction encoding.
    556  inline BaseOpcode BaseOpcodeFieldRaw() const {
    557    return static_cast<BaseOpcode>(InstructionBits() & kBaseOpcodeMask);
    558  }
    559 
    560  // Safe to call within R-type instructions
    561  inline int Funct7FieldRaw() const { return InstructionBits() & kFunct7Mask; }
    562 
    563  // Safe to call within R-type instructions
    564  inline int Funct6FieldRaw() const { return InstructionBits() & kFunct6Mask; }
    565 
    566  // Safe to call within R-, I-, S-, or B-type instructions
    567  inline int Funct3FieldRaw() const { return InstructionBits() & kFunct3Mask; }
    568 
    569  // Safe to call within R-, I-, S-, or B-type instructions
    570  inline int Rs1FieldRawNoAssert() const {
    571    return InstructionBits() & kRs1FieldMask;
    572  }
    573 
    574  // Safe to call within R-, S-, or B-type instructions
    575  inline int Rs2FieldRawNoAssert() const {
    576    return InstructionBits() & kRs2FieldMask;
    577  }
    578 
    579  // Safe to call within R4-type instructions
    580  inline int Rs3FieldRawNoAssert() const {
    581    return InstructionBits() & kRs3FieldMask;
    582  }
    583 
    584  inline int32_t ITypeBits() const { return InstructionBits() & kITypeMask; }
    585 
    586  inline int32_t InstructionOpcodeType() const {
    587    if (IsShortInstruction()) {
    588      return InstructionBits() & kRvcOpcodeMask;
    589    } else {
    590      return InstructionBits() & kBaseOpcodeMask;
    591    }
    592  }
    593 
    594  // Get the encoding type of the instruction.
    595  Type InstructionType() const;
    596  OffsetSize GetOffsetSize() const;
    597  inline ImmBranchRangeType GetImmBranchRangeType() const {
    598    return OffsetSizeToImmBranchRangeType(GetOffsetSize());
    599  }
    600 
    601 protected:
    602  InstructionBase() {}
    603 };
    604 
    605 template <class T>
    606 class InstructionGetters : public T {
    607 public:
    608  // Say if the instruction is a break or a trap.
    609  bool IsTrap() const;
    610 
    611  inline int BaseOpcode() const {
    612    return this->InstructionBits() & kBaseOpcodeMask;
    613  }
    614 
    615  inline int RvcOpcode() const {
    616    MOZ_ASSERT(this->IsShortInstruction());
    617    return this->InstructionBits() & kRvcOpcodeMask;
    618  }
    619 
    620  inline int Rs1Value() const {
    621    MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
    622               this->InstructionType() == InstructionBase::kR4Type ||
    623               this->InstructionType() == InstructionBase::kIType ||
    624               this->InstructionType() == InstructionBase::kSType ||
    625               this->InstructionType() == InstructionBase::kBType ||
    626               this->InstructionType() == InstructionBase::kIType ||
    627               this->InstructionType() == InstructionBase::kVType);
    628    return this->Bits(kRs1Shift + kRs1Bits - 1, kRs1Shift);
    629  }
    630 
    631  inline int Rs2Value() const {
    632    MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
    633               this->InstructionType() == InstructionBase::kR4Type ||
    634               this->InstructionType() == InstructionBase::kSType ||
    635               this->InstructionType() == InstructionBase::kBType ||
    636               this->InstructionType() == InstructionBase::kIType ||
    637               this->InstructionType() == InstructionBase::kVType);
    638    return this->Bits(kRs2Shift + kRs2Bits - 1, kRs2Shift);
    639  }
    640 
    641  inline int Rs3Value() const {
    642    MOZ_ASSERT(this->InstructionType() == InstructionBase::kR4Type);
    643    return this->Bits(kRs3Shift + kRs3Bits - 1, kRs3Shift);
    644  }
    645 
    646  inline int Vs1Value() const {
    647    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
    648               this->InstructionType() == InstructionBase::kIType ||
    649               this->InstructionType() == InstructionBase::kSType);
    650    return this->Bits(kVs1Shift + kVs1Bits - 1, kVs1Shift);
    651  }
    652 
    653  inline int Vs2Value() const {
    654    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
    655               this->InstructionType() == InstructionBase::kIType ||
    656               this->InstructionType() == InstructionBase::kSType);
    657    return this->Bits(kVs2Shift + kVs2Bits - 1, kVs2Shift);
    658  }
    659 
    660  inline int VdValue() const {
    661    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
    662               this->InstructionType() == InstructionBase::kIType ||
    663               this->InstructionType() == InstructionBase::kSType);
    664    return this->Bits(kVdShift + kVdBits - 1, kVdShift);
    665  }
    666 
    667  inline int RdValue() const {
    668    MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
    669               this->InstructionType() == InstructionBase::kR4Type ||
    670               this->InstructionType() == InstructionBase::kIType ||
    671               this->InstructionType() == InstructionBase::kSType ||
    672               this->InstructionType() == InstructionBase::kUType ||
    673               this->InstructionType() == InstructionBase::kJType ||
    674               this->InstructionType() == InstructionBase::kVType);
    675    return this->Bits(kRdShift + kRdBits - 1, kRdShift);
    676  }
    677 
    678  inline int RvcRs1Value() const { return this->RvcRdValue(); }
    679 
    680  int RvcRdValue() const;
    681 
    682  int RvcRs2Value() const;
    683 
    684  int RvcRs1sValue() const;
    685 
    686  int RvcRs2sValue() const;
    687 
    688  int Funct7Value() const;
    689 
    690  inline int Funct3Value() const {
    691    MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
    692               this->InstructionType() == InstructionBase::kIType ||
    693               this->InstructionType() == InstructionBase::kSType ||
    694               this->InstructionType() == InstructionBase::kBType);
    695    return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
    696  }
    697 
    698  inline int Funct5Value() const {
    699    MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType &&
    700               this->BaseOpcode() == OP_FP);
    701    return this->Bits(kFunct5Shift + kFunct5Bits - 1, kFunct5Shift);
    702  }
    703 
    704  int RvcFunct6Value() const;
    705 
    706  int RvcFunct4Value() const;
    707 
    708  int RvcFunct3Value() const;
    709 
    710  int RvcFunct2Value() const;
    711 
    712  int RvcFunct2BValue() const;
    713 
    714  inline int CsrValue() const {
    715    MOZ_ASSERT(this->InstructionType() == InstructionBase::kIType &&
    716               this->BaseOpcode() == SYSTEM);
    717    return (this->Bits(kCsrShift + kCsrBits - 1, kCsrShift));
    718  }
    719 
    720  inline int RoundMode() const {
    721    MOZ_ASSERT((this->InstructionType() == InstructionBase::kRType ||
    722                this->InstructionType() == InstructionBase::kR4Type) &&
    723               this->BaseOpcode() == OP_FP);
    724    return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
    725  }
    726 
    727  inline int MemoryOrder(bool is_pred) const {
    728    MOZ_ASSERT((this->InstructionType() == InstructionBase::kIType &&
    729                this->BaseOpcode() == MISC_MEM));
    730    if (is_pred) {
    731      return this->Bits(kPredOrderShift + kMemOrderBits - 1, kPredOrderShift);
    732    } else {
    733      return this->Bits(kSuccOrderShift + kMemOrderBits - 1, kSuccOrderShift);
    734    }
    735  }
    736 
    737  inline int Imm12Value() const {
    738    MOZ_ASSERT(this->InstructionType() == InstructionBase::kIType);
    739    int Value = this->Bits(kImm12Shift + kImm12Bits - 1, kImm12Shift);
    740    return Value << 20 >> 20;
    741  }
    742 
    743  inline int32_t Imm12SExtValue() const {
    744    int32_t Value = this->Imm12Value() << 20 >> 20;
    745    return Value;
    746  }
    747 
    748  inline int BranchOffset() const {
    749    MOZ_ASSERT(this->InstructionType() == InstructionBase::kBType);
    750    // | imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode |
    751    //  31          25                      11          7
    752    uint32_t Bits = this->InstructionBits();
    753    int16_t imm13 = ((Bits & 0xf00) >> 7) | ((Bits & 0x7e000000) >> 20) |
    754                    ((Bits & 0x80) << 4) | ((Bits & 0x80000000) >> 19);
    755    return imm13 << 19 >> 19;
    756  }
    757 
    758  inline int StoreOffset() const {
    759    MOZ_ASSERT(this->InstructionType() == InstructionBase::kSType);
    760    // | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
    761    //  31       25                      11       7
    762    uint32_t Bits = this->InstructionBits();
    763    int16_t imm12 = ((Bits & 0xf80) >> 7) | ((Bits & 0xfe000000) >> 20);
    764    return imm12 << 20 >> 20;
    765  }
    766 
    767  inline int Imm20UValue() const {
    768    MOZ_ASSERT(this->InstructionType() == InstructionBase::kUType);
    769    // | imm[31:12] | rd | opcode |
    770    //  31        12
    771    int32_t Bits = this->InstructionBits();
    772    return Bits >> 12;
    773  }
    774 
    775  inline int Imm20JValue() const {
    776    MOZ_ASSERT(this->InstructionType() == InstructionBase::kJType);
    777    // | imm[20|10:1|11|19:12] | rd | opcode |
    778    //  31                   12
    779    uint32_t Bits = this->InstructionBits();
    780    int32_t imm20 = ((Bits & 0x7fe00000) >> 20) | ((Bits & 0x100000) >> 9) |
    781                    (Bits & 0xff000) | ((Bits & 0x80000000) >> 11);
    782    return imm20 << 11 >> 11;
    783  }
    784 
    785  inline bool IsArithShift() const {
    786    // Valid only for right shift operations
    787    MOZ_ASSERT((this->BaseOpcode() == OP || this->BaseOpcode() == OP_32 ||
    788                this->BaseOpcode() == OP_IMM ||
    789                this->BaseOpcode() == OP_IMM_32) &&
    790               this->Funct3Value() == 0b101);
    791    return this->InstructionBits() & 0x40000000;
    792  }
    793 
    794  inline int Shamt() const {
    795    // Valid only for shift instructions (SLLI, SRLI, SRAI)
    796    MOZ_ASSERT(((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM ||
    797                (this->InstructionBits() & kBaseOpcodeMask) == OP_IMM_32) &&
    798               (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
    799    // | 0A0000 | shamt | rs1 | funct3 | rd | opcode |
    800    //  31       25    20
    801    return this->Bits(kImm12Shift + 5, kImm12Shift);
    802  }
    803 
    804  inline int Shamt32() const {
    805    // Valid only for shift instructions (SLLIW, SRLIW, SRAIW)
    806    MOZ_ASSERT((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM_32 &&
    807               (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
    808    // | 0A00000 | shamt | rs1 | funct3 | rd | opcode |
    809    //  31        24   20
    810    return this->Bits(kImm12Shift + 4, kImm12Shift);
    811  }
    812 
    813  inline int RvcImm6Value() const {
    814    MOZ_ASSERT(this->IsShortInstruction());
    815    // | funct3 | imm[5] | rs1/rd | imm[4:0] | opcode |
    816    //  15         12              6        2
    817    uint32_t Bits = this->InstructionBits();
    818    int32_t imm6 = ((Bits & 0x1000) >> 7) | ((Bits & 0x7c) >> 2);
    819    return imm6 << 26 >> 26;
    820  }
    821 
    822  inline int RvcImm6Addi16spValue() const {
    823    MOZ_ASSERT(this->IsShortInstruction());
    824    // | funct3 | nzimm[9] | 2 | nzimm[4|6|8:7|5] | opcode |
    825    //  15         12           6                2
    826    uint32_t Bits = this->InstructionBits();
    827    int32_t imm10 = ((Bits & 0x1000) >> 3) | ((Bits & 0x40) >> 2) |
    828                    ((Bits & 0x20) << 1) | ((Bits & 0x18) << 4) |
    829                    ((Bits & 0x4) << 3);
    830    MOZ_ASSERT(imm10 != 0);
    831    return imm10 << 22 >> 22;
    832  }
    833 
    834  inline int RvcImm8Addi4spnValue() const {
    835    MOZ_ASSERT(this->IsShortInstruction());
    836    // | funct3 | nzimm[11]  | rd' | opcode |
    837    //  15      13           5     2
    838    uint32_t Bits = this->InstructionBits();
    839    int32_t uimm10 = ((Bits & 0x20) >> 2) | ((Bits & 0x40) >> 4) |
    840                     ((Bits & 0x780) >> 1) | ((Bits & 0x1800) >> 7);
    841    MOZ_ASSERT(uimm10 != 0);
    842    return uimm10;
    843  }
    844 
    845  inline int RvcShamt6() const {
    846    MOZ_ASSERT(this->IsShortInstruction());
    847    // | funct3 | nzuimm[5] | rs1/rd | nzuimm[4:0] | opcode |
    848    //  15         12                 6           2
    849    int32_t imm6 = this->RvcImm6Value();
    850    return imm6 & 0x3f;
    851  }
    852 
    853  inline int RvcImm6LwspValue() const {
    854    MOZ_ASSERT(this->IsShortInstruction());
    855    // | funct3 | uimm[5] | rs1 | uimm[4:2|7:6] | opcode |
    856    //  15         12            6             2
    857    uint32_t Bits = this->InstructionBits();
    858    int32_t imm8 =
    859        ((Bits & 0x1000) >> 7) | ((Bits & 0x70) >> 2) | ((Bits & 0xc) << 4);
    860    return imm8;
    861  }
    862 
    863  inline int RvcImm6LdspValue() const {
    864    MOZ_ASSERT(this->IsShortInstruction());
    865    // | funct3 | uimm[5] | rs1 | uimm[4:3|8:6] | opcode |
    866    //  15         12            6             2
    867    uint32_t Bits = this->InstructionBits();
    868    int32_t imm9 =
    869        ((Bits & 0x1000) >> 7) | ((Bits & 0x60) >> 2) | ((Bits & 0x1c) << 4);
    870    return imm9;
    871  }
    872 
    873  inline int RvcImm6SwspValue() const {
    874    MOZ_ASSERT(this->IsShortInstruction());
    875    // | funct3 | uimm[5:2|7:6] | rs2 | opcode |
    876    //  15       12            7
    877    uint32_t Bits = this->InstructionBits();
    878    int32_t imm8 = ((Bits & 0x1e00) >> 7) | ((Bits & 0x180) >> 1);
    879    return imm8;
    880  }
    881 
    882  inline int RvcImm6SdspValue() const {
    883    MOZ_ASSERT(this->IsShortInstruction());
    884    // | funct3 | uimm[5:3|8:6] | rs2 | opcode |
    885    //  15       12            7
    886    uint32_t Bits = this->InstructionBits();
    887    int32_t imm9 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x380) >> 1);
    888    return imm9;
    889  }
    890 
    891  inline int RvcImm5WValue() const {
    892    MOZ_ASSERT(this->IsShortInstruction());
    893    // | funct3 | imm[5:3] | rs1 | imm[2|6] | rd | opcode |
    894    //  15       12       10     6          4     2
    895    uint32_t Bits = this->InstructionBits();
    896    int32_t imm7 =
    897        ((Bits & 0x1c00) >> 7) | ((Bits & 0x40) >> 4) | ((Bits & 0x20) << 1);
    898    return imm7;
    899  }
    900 
    901  inline int RvcImm5DValue() const {
    902    MOZ_ASSERT(this->IsShortInstruction());
    903    // | funct3 | imm[5:3] | rs1 | imm[7:6] | rd | opcode |
    904    //  15       12        10    6          4     2
    905    uint32_t Bits = this->InstructionBits();
    906    int32_t imm8 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x60) << 1);
    907    return imm8;
    908  }
    909 
    910  inline int RvcImm11CJValue() const {
    911    MOZ_ASSERT(this->IsShortInstruction());
    912    // | funct3 | [11|4|9:8|10|6|7|3:1|5] | opcode |
    913    //  15      12                        2
    914    uint32_t Bits = this->InstructionBits();
    915    int32_t imm12 = ((Bits & 0x4) << 3) | ((Bits & 0x38) >> 2) |
    916                    ((Bits & 0x40) << 1) | ((Bits & 0x80) >> 1) |
    917                    ((Bits & 0x100) << 2) | ((Bits & 0x600) >> 1) |
    918                    ((Bits & 0x800) >> 7) | ((Bits & 0x1000) >> 1);
    919    return imm12 << 20 >> 20;
    920  }
    921 
    922  inline int RvcImm8BValue() const {
    923    MOZ_ASSERT(this->IsShortInstruction());
    924    // | funct3 | imm[8|4:3] | rs1` | imm[7:6|2:1|5]  | opcode |
    925    //  15       12        10       7                 2
    926    uint32_t Bits = this->InstructionBits();
    927    int32_t imm9 = ((Bits & 0x4) << 3) | ((Bits & 0x18) >> 2) |
    928                   ((Bits & 0x60) << 1) | ((Bits & 0xc00) >> 7) |
    929                   ((Bits & 0x1000) >> 4);
    930    return imm9 << 23 >> 23;
    931  }
    932 
    933  inline int vl_vs_width() {
    934    int width = 0;
    935    if ((this->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
    936        (this->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
    937      return -1;
    938    switch (this->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
    939      case 0x0:
    940        width = 8;
    941        break;
    942      case 0x00005000:
    943        width = 16;
    944        break;
    945      case 0x00006000:
    946        width = 32;
    947        break;
    948      case 0x00007000:
    949        width = 64;
    950        break;
    951      case 0x10000000:
    952        width = 128;
    953        break;
    954      case 0x10005000:
    955        width = 256;
    956        break;
    957      case 0x10006000:
    958        width = 512;
    959        break;
    960      case 0x10007000:
    961        width = 1024;
    962        break;
    963      default:
    964        width = -1;
    965        break;
    966    }
    967    return width;
    968  }
    969 
    970  uint32_t Rvvzimm() const;
    971 
    972  uint32_t Rvvuimm() const;
    973 
    974  inline uint32_t RvvVsew() const {
    975    uint32_t zimm = this->Rvvzimm();
    976    uint32_t vsew = (zimm >> 3) & 0x7;
    977    return vsew;
    978  }
    979 
    980  inline uint32_t RvvVlmul() const {
    981    uint32_t zimm = this->Rvvzimm();
    982    uint32_t vlmul = zimm & 0x7;
    983    return vlmul;
    984  }
    985 
    986  inline uint8_t RvvVM() const {
    987    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
    988               this->InstructionType() == InstructionBase::kIType ||
    989               this->InstructionType() == InstructionBase::kSType);
    990    return this->Bits(kRvvVmShift + kRvvVmBits - 1, kRvvVmShift);
    991  }
    992 
    993  inline const char* RvvSEW() const {
    994    uint32_t vsew = this->RvvVsew();
    995    switch (vsew) {
    996 #define CAST_VSEW(name) \
    997  case name:            \
    998    return #name;
    999      RVV_SEW(CAST_VSEW)
   1000      default:
   1001        return "unknown";
   1002 #undef CAST_VSEW
   1003    }
   1004  }
   1005 
   1006  inline const char* RvvLMUL() const {
   1007    uint32_t vlmul = this->RvvVlmul();
   1008    switch (vlmul) {
   1009 #define CAST_VLMUL(name) \
   1010  case name:             \
   1011    return #name;
   1012      RVV_LMUL(CAST_VLMUL)
   1013      default:
   1014        return "unknown";
   1015 #undef CAST_VLMUL
   1016    }
   1017  }
   1018 
   1019 #define sext(x, len) (((int32_t)(x) << (32 - len)) >> (32 - len))
   1020 #define zext(x, len) (((uint32_t)(x) << (32 - len)) >> (32 - len))
   1021 
   1022  inline int32_t RvvSimm5() const {
   1023    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType);
   1024    return sext(this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift),
   1025                kRvvImm5Bits);
   1026  }
   1027 
   1028  inline uint32_t RvvUimm5() const {
   1029    MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType);
   1030    uint32_t imm = this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift);
   1031    return zext(imm, kRvvImm5Bits);
   1032  }
   1033 #undef sext
   1034 #undef zext
   1035  inline bool AqValue() const { return this->Bits(kAqShift, kAqShift); }
   1036 
   1037  inline bool RlValue() const { return this->Bits(kRlShift, kRlShift); }
   1038 };
   1039 
   1040 class Instruction : public InstructionGetters<InstructionBase> {
   1041 public:
   1042  // Instructions are read of out a code stream. The only way to get a
   1043  // reference to an instruction is to convert a pointer. There is no way
   1044  // to allocate or create instances of class Instruction.
   1045  // Use the At(pc) function to create references to Instruction.
   1046  static Instruction* At(byte* pc) {
   1047    return reinterpret_cast<Instruction*>(pc);
   1048  }
   1049 
   1050 private:
   1051  // We need to prevent the creation of instances of class Instruction.
   1052  Instruction() = delete;
   1053  Instruction(const Instruction&) = delete;
   1054  Instruction& operator=(const Instruction&) = delete;
   1055 };
   1056 
   1057 // -----------------------------------------------------------------------------
   1058 // Instructions.
   1059 
   1060 template <class P>
   1061 bool InstructionGetters<P>::IsTrap() const {
   1062  return (this->InstructionBits() == kBreakInstr);
   1063 }
   1064 
   1065 }  // namespace jit
   1066 }  // namespace js
   1067 #endif  //  jit_riscv64_constant_Base_constant_riscv__h_