summaryrefslogtreecommitdiffstats
path: root/js/src/jit/riscv64/constant
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/riscv64/constant')
-rw-r--r--js/src/jit/riscv64/constant/Base-constant-riscv.cpp247
-rw-r--r--js/src/jit/riscv64/constant/Base-constant-riscv.h1057
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-a.h43
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-c.h61
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-d.h55
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-f.h51
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-i.h73
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-m.h34
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-v.h508
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-zicsr.h30
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv-zifencei.h15
-rw-r--r--js/src/jit/riscv64/constant/Constant-riscv64.h68
-rw-r--r--js/src/jit/riscv64/constant/util-riscv64.h82
13 files changed, 2324 insertions, 0 deletions
diff --git a/js/src/jit/riscv64/constant/Base-constant-riscv.cpp b/js/src/jit/riscv64/constant/Base-constant-riscv.cpp
new file mode 100644
index 0000000000..9658689775
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Base-constant-riscv.cpp
@@ -0,0 +1,247 @@
+// Copyright 2021 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Types.h"
+
+#include <stdio.h>
+
+#include "jit/riscv64/constant/Constant-riscv-c.h"
+#include "jit/riscv64/constant/Constant-riscv-d.h"
+#include "jit/riscv64/constant/Constant-riscv-f.h"
+#include "jit/riscv64/constant/Constant-riscv-i.h"
+#include "jit/riscv64/constant/Constant-riscv-m.h"
+#include "jit/riscv64/constant/Constant-riscv-v.h"
+#include "jit/riscv64/constant/Constant-riscv-zicsr.h"
+#include "jit/riscv64/constant/Constant-riscv-zifencei.h"
+#include "jit/riscv64/Simulator-riscv64.h"
+namespace js {
+namespace jit {
+
+int32_t ImmBranchMaxForwardOffset(OffsetSize bits) {
+ return (1 << (bits - 1)) - 1;
+}
+
+bool InstructionBase::IsShortInstruction() const {
+ uint8_t FirstByte = *reinterpret_cast<const uint8_t*>(this);
+ return (FirstByte & 0x03) <= C2;
+}
+
+template <class T>
+int InstructionGetters<T>::RvcRdValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcRdShift + kRvcRdBits - 1, kRvcRdShift);
+}
+
+template <class T>
+int InstructionGetters<T>::RvcRs2Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcRs2Shift + kRvcRs2Bits - 1, kRvcRs2Shift);
+}
+
+template <class T>
+int InstructionGetters<T>::RvcRs1sValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return 0b1000 + this->Bits(kRvcRs1sShift + kRvcRs1sBits - 1, kRvcRs1sShift);
+}
+
+template <class T>
+int InstructionGetters<T>::RvcRs2sValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return 0b1000 + this->Bits(kRvcRs2sShift + kRvcRs2sBits - 1, kRvcRs2sShift);
+}
+
+template <class T>
+inline int InstructionGetters<T>::RvcFunct6Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcFunct6Shift + kRvcFunct6Bits - 1, kRvcFunct6Shift);
+}
+
+template <class T>
+inline int InstructionGetters<T>::RvcFunct4Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcFunct4Shift + kRvcFunct4Bits - 1, kRvcFunct4Shift);
+}
+
+template <class T>
+inline int InstructionGetters<T>::RvcFunct3Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcFunct3Shift + kRvcFunct3Bits - 1, kRvcFunct3Shift);
+}
+
+template <class T>
+inline int InstructionGetters<T>::RvcFunct2Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcFunct2Shift + kRvcFunct2Bits - 1, kRvcFunct2Shift);
+}
+
+template <class T>
+inline int InstructionGetters<T>::RvcFunct2BValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->Bits(kRvcFunct2BShift + kRvcFunct2Bits - 1, kRvcFunct2BShift);
+}
+
+template <class T>
+uint32_t InstructionGetters<T>::Rvvzimm() const {
+ if ((this->InstructionBits() &
+ (kBaseOpcodeMask | kFunct3Mask | 0x80000000)) == RO_V_VSETVLI) {
+ uint32_t Bits = this->InstructionBits();
+ uint32_t zimm = Bits & kRvvZimmMask;
+ return zimm >> kRvvZimmShift;
+ } else {
+ MOZ_ASSERT((this->InstructionBits() &
+ (kBaseOpcodeMask | kFunct3Mask | 0xC0000000)) == RO_V_VSETIVLI);
+ uint32_t Bits = this->InstructionBits();
+ uint32_t zimm = Bits & kRvvZimmMask;
+ return (zimm >> kRvvZimmShift) & 0x3FF;
+ }
+}
+
+template <class T>
+uint32_t InstructionGetters<T>::Rvvuimm() const {
+ MOZ_ASSERT((this->InstructionBits() &
+ (kBaseOpcodeMask | kFunct3Mask | 0xC0000000)) == RO_V_VSETIVLI);
+ uint32_t Bits = this->InstructionBits();
+ uint32_t uimm = Bits & kRvvUimmMask;
+ return uimm >> kRvvUimmShift;
+}
+
+template class InstructionGetters<InstructionBase>;
+#ifdef JS_SIMULATOR_RISCV64
+template class InstructionGetters<SimInstructionBase>;
+#endif
+
+OffsetSize InstructionBase::GetOffsetSize() const {
+ if (IsIllegalInstruction()) {
+ MOZ_CRASH("IllegalInstruction");
+ }
+ if (IsShortInstruction()) {
+ switch (InstructionBits() & kRvcOpcodeMask) {
+ case RO_C_J:
+ return kOffset11;
+ case RO_C_BEQZ:
+ case RO_C_BNEZ:
+ return kOffset9;
+ default:
+ MOZ_CRASH("IllegalInstruction");
+ }
+ } else {
+ switch (InstructionBits() & kBaseOpcodeMask) {
+ case BRANCH:
+ return kOffset13;
+ case JAL:
+ return kOffset21;
+ default:
+ MOZ_CRASH("IllegalInstruction");
+ }
+ }
+}
+
+InstructionBase::Type InstructionBase::InstructionType() const {
+ if (IsIllegalInstruction()) {
+ return kUnsupported;
+ }
+ // RV64C Instruction
+ if (IsShortInstruction()) {
+ switch (InstructionBits() & kRvcOpcodeMask) {
+ case RO_C_ADDI4SPN:
+ return kCIWType;
+ case RO_C_FLD:
+ case RO_C_LW:
+#ifdef JS_CODEGEN_RISCV64
+ case RO_C_LD:
+#endif
+ return kCLType;
+ case RO_C_FSD:
+ case RO_C_SW:
+#ifdef JS_CODEGEN_RISCV64
+ case RO_C_SD:
+#endif
+ return kCSType;
+ case RO_C_NOP_ADDI:
+ case RO_C_LI:
+#ifdef JS_CODEGEN_RISCV64
+ case RO_C_ADDIW:
+#endif
+ case RO_C_LUI_ADD:
+ return kCIType;
+ case RO_C_MISC_ALU:
+ if (Bits(11, 10) != 0b11)
+ return kCBType;
+ else
+ return kCAType;
+ case RO_C_J:
+ return kCJType;
+ case RO_C_BEQZ:
+ case RO_C_BNEZ:
+ return kCBType;
+ case RO_C_SLLI:
+ case RO_C_FLDSP:
+ case RO_C_LWSP:
+#ifdef JS_CODEGEN_RISCV64
+ case RO_C_LDSP:
+#endif
+ return kCIType;
+ case RO_C_JR_MV_ADD:
+ return kCRType;
+ case RO_C_FSDSP:
+ case RO_C_SWSP:
+#ifdef JS_CODEGEN_RISCV64
+ case RO_C_SDSP:
+#endif
+ return kCSSType;
+ default:
+ break;
+ }
+ } else {
+ // RISCV routine
+ switch (InstructionBits() & kBaseOpcodeMask) {
+ case LOAD:
+ return kIType;
+ case LOAD_FP:
+ return kIType;
+ case MISC_MEM:
+ return kIType;
+ case OP_IMM:
+ return kIType;
+ case AUIPC:
+ return kUType;
+ case OP_IMM_32:
+ return kIType;
+ case STORE:
+ return kSType;
+ case STORE_FP:
+ return kSType;
+ case AMO:
+ return kRType;
+ case OP:
+ return kRType;
+ case LUI:
+ return kUType;
+ case OP_32:
+ return kRType;
+ case MADD:
+ case MSUB:
+ case NMSUB:
+ case NMADD:
+ return kR4Type;
+ case OP_FP:
+ return kRType;
+ case BRANCH:
+ return kBType;
+ case JALR:
+ return kIType;
+ case JAL:
+ return kJType;
+ case SYSTEM:
+ return kIType;
+ case OP_V:
+ return kVType;
+ }
+ }
+ return kUnsupported;
+}
+} // namespace jit
+} // namespace js
diff --git a/js/src/jit/riscv64/constant/Base-constant-riscv.h b/js/src/jit/riscv64/constant/Base-constant-riscv.h
new file mode 100644
index 0000000000..929ccd67b5
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Base-constant-riscv.h
@@ -0,0 +1,1057 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Base_constant_riscv__h_
+#define jit_riscv64_constant_Base_constant_riscv__h_
+namespace js {
+namespace jit {
+
+// On RISC-V Simulator breakpoints can have different codes:
+// - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
+// the simulator will run through them and print the registers.
+// - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
+// instructions (see Assembler::stop()).
+// - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
+// debugger.
+const uint32_t kMaxTracepointCode = 63;
+const uint32_t kMaxWatchpointCode = 31;
+const uint32_t kMaxStopCode = 127;
+const uint32_t kWasmTrapCode = 6;
+static_assert(kMaxWatchpointCode < kMaxStopCode);
+static_assert(kMaxTracepointCode < kMaxStopCode);
+
+// Debug parameters.
+//
+// For example:
+//
+// __ Debug(TRACE_ENABLE | LOG_TRACE);
+// starts tracing: set v8_flags.trace-sim is true.
+// __ Debug(TRACE_ENABLE | LOG_REGS);
+// PrintAllregs.
+// __ Debug(TRACE_DISABLE | LOG_TRACE);
+// stops tracing: set v8_flags.trace-sim is false.
+const uint32_t kDebuggerTracingDirectivesMask = 0b111 << 3;
+enum DebugParameters : uint32_t {
+ NO_PARAM = 1 << 5,
+ BREAK = 1 << 0,
+ LOG_TRACE = 1 << 1,
+ LOG_REGS = 1 << 2,
+ LOG_ALL = LOG_TRACE,
+ // Trace control.
+ TRACE_ENABLE = 1 << 3 | NO_PARAM,
+ TRACE_DISABLE = 1 << 4 | NO_PARAM,
+};
+// On RISCV all instructions are 32 bits, except for RVC.
+using Instr = int32_t;
+using ShortInstr = int16_t;
+typedef unsigned char byte;
+// ----- Fields offset and length.
+// RISCV constants
+const int kBaseOpcodeShift = 0;
+const int kBaseOpcodeBits = 7;
+const int kFunct7Shift = 25;
+const int kFunct7Bits = 7;
+const int kFunct5Shift = 27;
+const int kFunct5Bits = 5;
+const int kFunct3Shift = 12;
+const int kFunct3Bits = 3;
+const int kFunct2Shift = 25;
+const int kFunct2Bits = 2;
+const int kRs1Shift = 15;
+const int kRs1Bits = 5;
+const int kVs1Shift = 15;
+const int kVs1Bits = 5;
+const int kVs2Shift = 20;
+const int kVs2Bits = 5;
+const int kVdShift = 7;
+const int kVdBits = 5;
+const int kRs2Shift = 20;
+const int kRs2Bits = 5;
+const int kRs3Shift = 27;
+const int kRs3Bits = 5;
+const int kRdShift = 7;
+const int kRdBits = 5;
+const int kRlShift = 25;
+const int kAqShift = 26;
+const int kImm12Shift = 20;
+const int kImm12Bits = 12;
+const int kImm11Shift = 2;
+const int kImm11Bits = 11;
+const int kShamtShift = 20;
+const int kShamtBits = 5;
+const int kShamtWShift = 20;
+// FIXME: remove this once we have a proper way to handle the wide shift amount
+const int kShamtWBits = 6;
+const int kArithShiftShift = 30;
+const int kImm20Shift = 12;
+const int kImm20Bits = 20;
+const int kCsrShift = 20;
+const int kCsrBits = 12;
+const int kMemOrderBits = 4;
+const int kPredOrderShift = 24;
+const int kSuccOrderShift = 20;
+
+// for C extension
+const int kRvcFunct4Shift = 12;
+const int kRvcFunct4Bits = 4;
+const int kRvcFunct3Shift = 13;
+const int kRvcFunct3Bits = 3;
+const int kRvcRs1Shift = 7;
+const int kRvcRs1Bits = 5;
+const int kRvcRs2Shift = 2;
+const int kRvcRs2Bits = 5;
+const int kRvcRdShift = 7;
+const int kRvcRdBits = 5;
+const int kRvcRs1sShift = 7;
+const int kRvcRs1sBits = 3;
+const int kRvcRs2sShift = 2;
+const int kRvcRs2sBits = 3;
+const int kRvcFunct2Shift = 5;
+const int kRvcFunct2BShift = 10;
+const int kRvcFunct2Bits = 2;
+const int kRvcFunct6Shift = 10;
+const int kRvcFunct6Bits = 6;
+
+const uint32_t kRvcOpcodeMask =
+ 0b11 | (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
+const uint32_t kRvcFunct3Mask =
+ (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
+const uint32_t kRvcFunct4Mask =
+ (((1 << kRvcFunct4Bits) - 1) << kRvcFunct4Shift);
+const uint32_t kRvcFunct6Mask =
+ (((1 << kRvcFunct6Bits) - 1) << kRvcFunct6Shift);
+const uint32_t kRvcFunct2Mask =
+ (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2Shift);
+const uint32_t kRvcFunct2BMask =
+ (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2BShift);
+const uint32_t kCRTypeMask = kRvcOpcodeMask | kRvcFunct4Mask;
+const uint32_t kCSTypeMask = kRvcOpcodeMask | kRvcFunct6Mask;
+const uint32_t kCATypeMask = kRvcOpcodeMask | kRvcFunct6Mask | kRvcFunct2Mask;
+const uint32_t kRvcBImm8Mask = (((1 << 5) - 1) << 2) | (((1 << 3) - 1) << 10);
+
+// RISCV Instruction bit masks
+const uint32_t kBaseOpcodeMask = ((1 << kBaseOpcodeBits) - 1)
+ << kBaseOpcodeShift;
+const uint32_t kFunct3Mask = ((1 << kFunct3Bits) - 1) << kFunct3Shift;
+const uint32_t kFunct5Mask = ((1 << kFunct5Bits) - 1) << kFunct5Shift;
+const uint32_t kFunct7Mask = ((1 << kFunct7Bits) - 1) << kFunct7Shift;
+const uint32_t kFunct2Mask = 0b11 << kFunct7Shift;
+const uint32_t kRTypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct7Mask;
+const uint32_t kRATypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct5Mask;
+const uint32_t kRFPTypeMask = kBaseOpcodeMask | kFunct7Mask;
+const uint32_t kR4TypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct2Mask;
+const uint32_t kITypeMask = kBaseOpcodeMask | kFunct3Mask;
+const uint32_t kSTypeMask = kBaseOpcodeMask | kFunct3Mask;
+const uint32_t kBTypeMask = kBaseOpcodeMask | kFunct3Mask;
+const uint32_t kUTypeMask = kBaseOpcodeMask;
+const uint32_t kJTypeMask = kBaseOpcodeMask;
+const uint32_t kRs1FieldMask = ((1 << kRs1Bits) - 1) << kRs1Shift;
+const uint32_t kRs2FieldMask = ((1 << kRs2Bits) - 1) << kRs2Shift;
+const uint32_t kRs3FieldMask = ((1 << kRs3Bits) - 1) << kRs3Shift;
+const uint32_t kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
+const uint32_t kBImm12Mask = kFunct7Mask | kRdFieldMask;
+const uint32_t kImm20Mask = ((1 << kImm20Bits) - 1) << kImm20Shift;
+const uint32_t kImm12Mask = ((1 << kImm12Bits) - 1) << kImm12Shift;
+const uint32_t kImm11Mask = ((1 << kImm11Bits) - 1) << kImm11Shift;
+const uint32_t kImm31_12Mask = ((1 << 20) - 1) << 12;
+const uint32_t kImm19_0Mask = ((1 << 20) - 1);
+
+// for RVV extension
+#define RVV_LMUL(V) \
+ V(m1) \
+ V(m2) \
+ V(m4) \
+ V(m8) \
+ V(RESERVERD) \
+ V(mf8) \
+ V(mf4) \
+ V(mf2)
+
+enum Vlmul {
+#define DEFINE_FLAG(name) name,
+ RVV_LMUL(DEFINE_FLAG)
+#undef DEFINE_FLAG
+};
+
+#define RVV_SEW(V) \
+ V(E8) \
+ V(E16) \
+ V(E32) \
+ V(E64)
+
+#define DEFINE_FLAG(name) name,
+enum VSew {
+ RVV_SEW(DEFINE_FLAG)
+#undef DEFINE_FLAG
+};
+
+constexpr int kRvvELEN = 64;
+constexpr int kRvvVLEN = 128;
+constexpr int kRvvSLEN = kRvvVLEN;
+const int kRvvFunct6Shift = 26;
+const int kRvvFunct6Bits = 6;
+const uint32_t kRvvFunct6Mask =
+ (((1 << kRvvFunct6Bits) - 1) << kRvvFunct6Shift);
+
+const int kRvvVmBits = 1;
+const int kRvvVmShift = 25;
+const uint32_t kRvvVmMask = (((1 << kRvvVmBits) - 1) << kRvvVmShift);
+
+const int kRvvVs2Bits = 5;
+const int kRvvVs2Shift = 20;
+const uint32_t kRvvVs2Mask = (((1 << kRvvVs2Bits) - 1) << kRvvVs2Shift);
+
+const int kRvvVs1Bits = 5;
+const int kRvvVs1Shift = 15;
+const uint32_t kRvvVs1Mask = (((1 << kRvvVs1Bits) - 1) << kRvvVs1Shift);
+
+const int kRvvRs1Bits = kRvvVs1Bits;
+const int kRvvRs1Shift = kRvvVs1Shift;
+const uint32_t kRvvRs1Mask = (((1 << kRvvRs1Bits) - 1) << kRvvRs1Shift);
+
+const int kRvvRs2Bits = 5;
+const int kRvvRs2Shift = 20;
+const uint32_t kRvvRs2Mask = (((1 << kRvvRs2Bits) - 1) << kRvvRs2Shift);
+
+const int kRvvImm5Bits = kRvvVs1Bits;
+const int kRvvImm5Shift = kRvvVs1Shift;
+const uint32_t kRvvImm5Mask = (((1 << kRvvImm5Bits) - 1) << kRvvImm5Shift);
+
+const int kRvvVdBits = 5;
+const int kRvvVdShift = 7;
+const uint32_t kRvvVdMask = (((1 << kRvvVdBits) - 1) << kRvvVdShift);
+
+const int kRvvRdBits = kRvvVdBits;
+const int kRvvRdShift = kRvvVdShift;
+const uint32_t kRvvRdMask = (((1 << kRvvRdBits) - 1) << kRvvRdShift);
+
+const int kRvvZimmBits = 11;
+const int kRvvZimmShift = 20;
+const uint32_t kRvvZimmMask = (((1 << kRvvZimmBits) - 1) << kRvvZimmShift);
+
+const int kRvvUimmShift = kRvvRs1Shift;
+const int kRvvUimmBits = kRvvRs1Bits;
+const uint32_t kRvvUimmMask = (((1 << kRvvUimmBits) - 1) << kRvvUimmShift);
+
+const int kRvvWidthBits = 3;
+const int kRvvWidthShift = 12;
+const uint32_t kRvvWidthMask = (((1 << kRvvWidthBits) - 1) << kRvvWidthShift);
+
+const int kRvvMopBits = 2;
+const int kRvvMopShift = 26;
+const uint32_t kRvvMopMask = (((1 << kRvvMopBits) - 1) << kRvvMopShift);
+
+const int kRvvMewBits = 1;
+const int kRvvMewShift = 28;
+const uint32_t kRvvMewMask = (((1 << kRvvMewBits) - 1) << kRvvMewShift);
+
+const int kRvvNfBits = 3;
+const int kRvvNfShift = 29;
+const uint32_t kRvvNfMask = (((1 << kRvvNfBits) - 1) << kRvvNfShift);
+
+const int kNopByte = 0x00000013;
+
+enum BaseOpcode : uint32_t {
+ LOAD = 0b0000011, // I form: LB LH LW LBU LHU
+ LOAD_FP = 0b0000111, // I form: FLW FLD FLQ
+ MISC_MEM = 0b0001111, // I special form: FENCE FENCE.I
+ OP_IMM = 0b0010011, // I form: ADDI SLTI SLTIU XORI ORI ANDI SLLI SRLI SRAI
+ // Note: SLLI/SRLI/SRAI I form first, then func3 001/101 => R type
+ AUIPC = 0b0010111, // U form: AUIPC
+ OP_IMM_32 = 0b0011011, // I form: ADDIW SLLIW SRLIW SRAIW
+ // Note: SRLIW SRAIW I form first, then func3 101 special shift encoding
+ STORE = 0b0100011, // S form: SB SH SW SD
+ STORE_FP = 0b0100111, // S form: FSW FSD FSQ
+ AMO = 0b0101111, // R form: All A instructions
+ OP = 0b0110011, // R: ADD SUB SLL SLT SLTU XOR SRL SRA OR AND and 32M set
+ LUI = 0b0110111, // U form: LUI
+ OP_32 = 0b0111011, // R: ADDW SUBW SLLW SRLW SRAW MULW DIVW DIVUW REMW REMUW
+ MADD = 0b1000011, // R4 type: FMADD.S FMADD.D FMADD.Q
+ MSUB = 0b1000111, // R4 type: FMSUB.S FMSUB.D FMSUB.Q
+ NMSUB = 0b1001011, // R4 type: FNMSUB.S FNMSUB.D FNMSUB.Q
+ NMADD = 0b1001111, // R4 type: FNMADD.S FNMADD.D FNMADD.Q
+ OP_FP = 0b1010011, // R type: Q ext
+ BRANCH = 0b1100011, // B form: BEQ BNE, BLT, BGE, BLTU BGEU
+ JALR = 0b1100111, // I form: JALR
+ JAL = 0b1101111, // J form: JAL
+ SYSTEM = 0b1110011, // I form: ECALL EBREAK Zicsr ext
+ OP_V = 0b1010111, // V form: RVV
+
+ // C extension
+ C0 = 0b00,
+ C1 = 0b01,
+ C2 = 0b10,
+ FUNCT2_0 = 0b00,
+ FUNCT2_1 = 0b01,
+ FUNCT2_2 = 0b10,
+ FUNCT2_3 = 0b11,
+};
+
+// ----- Emulated conditions.
+// On RISC-V we use this enum to abstract from conditional branch instructions.
+// The 'U' prefix is used to specify unsigned comparisons.
+// Opposite conditions must be paired as odd/even numbers
+// because 'NegateCondition' function flips LSB to negate condition.
+enum RiscvCondition { // Any value < 0 is considered no_condition.
+ overflow = 0,
+ no_overflow = 1,
+ Uless = 2,
+ Ugreater_equal = 3,
+ Uless_equal = 4,
+ Ugreater = 5,
+ equal = 6,
+ not_equal = 7, // Unordered or Not Equal.
+ less = 8,
+ greater_equal = 9,
+ less_equal = 10,
+ greater = 11,
+ cc_always = 12,
+
+ // Aliases.
+ eq = equal,
+ ne = not_equal,
+ ge = greater_equal,
+ lt = less,
+ gt = greater,
+ le = less_equal,
+ al = cc_always,
+ ult = Uless,
+ uge = Ugreater_equal,
+ ule = Uless_equal,
+ ugt = Ugreater,
+};
+
+// ----- Coprocessor conditions.
+enum FPUCondition {
+ kNoFPUCondition = -1,
+ EQ = 0x02, // Ordered and Equal
+ NE = 0x03, // Unordered or Not Equal
+ LT = 0x04, // Ordered and Less Than
+ GE = 0x05, // Ordered and Greater Than or Equal
+ LE = 0x06, // Ordered and Less Than or Equal
+ GT = 0x07, // Ordered and Greater Than
+};
+
+enum CheckForInexactConversion {
+ kCheckForInexactConversion,
+ kDontCheckForInexactConversion
+};
+
+enum class MaxMinKind : int { kMin = 0, kMax = 1 };
+
+// ----------------------------------------------------------------------------
+// RISCV flags
+
+enum ControlStatusReg {
+ csr_fflags = 0x001, // Floating-Point Accrued Exceptions (RW)
+ csr_frm = 0x002, // Floating-Point Dynamic Rounding Mode (RW)
+ csr_fcsr = 0x003, // Floating-Point Control and Status Register (RW)
+ csr_cycle = 0xc00, // Cycle counter for RDCYCLE instruction (RO)
+ csr_time = 0xc01, // Timer for RDTIME instruction (RO)
+ csr_instret = 0xc02, // Insns-retired counter for RDINSTRET instruction (RO)
+ csr_cycleh = 0xc80, // Upper 32 bits of cycle, RV32I only (RO)
+ csr_timeh = 0xc81, // Upper 32 bits of time, RV32I only (RO)
+ csr_instreth = 0xc82 // Upper 32 bits of instret, RV32I only (RO)
+};
+
+enum FFlagsMask {
+ kInvalidOperation = 0b10000, // NV: Invalid
+ kDivideByZero = 0b1000, // DZ: Divide by Zero
+ kOverflow = 0b100, // OF: Overflow
+ kUnderflow = 0b10, // UF: Underflow
+ kInexact = 0b1 // NX: Inexact
+};
+
+enum FPURoundingMode {
+ RNE = 0b000, // Round to Nearest, ties to Even
+ RTZ = 0b001, // Round towards Zero
+ RDN = 0b010, // Round Down (towards -infinity)
+ RUP = 0b011, // Round Up (towards +infinity)
+ RMM = 0b100, // Round to Nearest, tiest to Max Magnitude
+ DYN = 0b111 // In instruction's rm field, selects dynamic rounding mode;
+ // In Rounding Mode register, Invalid
+};
+
+enum MemoryOdering {
+ PSI = 0b1000, // PI or SI
+ PSO = 0b0100, // PO or SO
+ PSR = 0b0010, // PR or SR
+ PSW = 0b0001, // PW or SW
+ PSIORW = PSI | PSO | PSR | PSW
+};
+
+const int kFloat32ExponentBias = 127;
+const int kFloat32MantissaBits = 23;
+const int kFloat32ExponentBits = 8;
+const int kFloat64ExponentBias = 1023;
+const int kFloat64MantissaBits = 52;
+const int kFloat64ExponentBits = 11;
+
+enum FClassFlag {
+ kNegativeInfinity = 1,
+ kNegativeNormalNumber = 1 << 1,
+ kNegativeSubnormalNumber = 1 << 2,
+ kNegativeZero = 1 << 3,
+ kPositiveZero = 1 << 4,
+ kPositiveSubnormalNumber = 1 << 5,
+ kPositiveNormalNumber = 1 << 6,
+ kPositiveInfinity = 1 << 7,
+ kSignalingNaN = 1 << 8,
+ kQuietNaN = 1 << 9
+};
+
+enum OffsetSize : uint32_t {
+ kOffset21 = 21, // RISCV jal
+ kOffset12 = 12, // RISCV imm12
+ kOffset20 = 20, // RISCV imm20
+ kOffset13 = 13, // RISCV branch
+ kOffset32 = 32, // RISCV auipc + instr_I
+ kOffset11 = 11, // RISCV C_J
+ kOffset9 = 9, // RISCV compressed branch
+};
+
+// The classes of immediate branch ranges, in order of increasing range.
+// Note that CondBranchType and CompareBranchType have the same range.
+enum ImmBranchRangeType {
+ CondBranchRangeType, //
+ UncondBranchRangeType, //
+ UnknownBranchRangeType,
+
+ // Number of 'short-range' branch range types.
+ // We don't consider unconditional branches 'short-range'.
+ NumShortBranchRangeTypes = UnknownBranchRangeType
+};
+
+inline ImmBranchRangeType OffsetSizeToImmBranchRangeType(OffsetSize bits) {
+ switch (bits) {
+ case kOffset21:
+ return UncondBranchRangeType;
+ case kOffset13:
+ return CondBranchRangeType;
+ default:
+ MOZ_CRASH("Unimplement");
+ }
+}
+
+inline OffsetSize ImmBranchRangeTypeToOffsetSize(ImmBranchRangeType type) {
+ switch (type) {
+ case CondBranchRangeType:
+ return kOffset13;
+ case UncondBranchRangeType:
+ return kOffset21;
+ default:
+ MOZ_CRASH("Unimplement");
+ }
+}
+
+int32_t ImmBranchMaxForwardOffset(OffsetSize bits);
+
+inline int32_t ImmBranchMaxForwardOffset(ImmBranchRangeType type) {
+ return ImmBranchMaxForwardOffset(ImmBranchRangeTypeToOffsetSize(type));
+}
+// -----------------------------------------------------------------------------
+// Specific instructions, constants, and masks.
+// These constants are declared in assembler-riscv64.cc, as they use named
+// registers and other constants.
+
+// An Illegal instruction
+const Instr kIllegalInstr = 0; // All other bits are 0s (i.e., ecall)
+// An ECALL instruction, used for redirected real time call
+const Instr rtCallRedirInstr = SYSTEM; // All other bits are 0s (i.e., ecall)
+// An EBreak instruction, used for debugging and semi-hosting
+const Instr kBreakInstr = SYSTEM | 1 << kImm12Shift; // ebreak
+
+constexpr uint8_t kInstrSize = 4;
+constexpr uint8_t kShortInstrSize = 2;
+constexpr uint8_t kInstrSizeLog2 = 2;
+
+class InstructionBase {
+ public:
+ enum {
+ // On RISC-V, PC cannot actually be directly accessed. We behave as if PC
+ // was always the value of the current instruction being executed.
+ kPCReadOffset = 0
+ };
+
+ // Instruction type.
+ enum Type {
+ kRType,
+ kR4Type, // Special R4 for Q extension
+ kIType,
+ kSType,
+ kBType,
+ kUType,
+ kJType,
+ // C extension
+ kCRType,
+ kCIType,
+ kCSSType,
+ kCIWType,
+ kCLType,
+ kCSType,
+ kCAType,
+ kCBType,
+ kCJType,
+ // V extension
+ kVType,
+ kVLType,
+ kVSType,
+ kVAMOType,
+ kVIVVType,
+ kVFVVType,
+ kVMVVType,
+ kVIVIType,
+ kVIVXType,
+ kVFVFType,
+ kVMVXType,
+ kVSETType,
+ kUnsupported = -1
+ };
+
+ inline bool IsIllegalInstruction() const {
+ uint16_t FirstHalfWord = *reinterpret_cast<const uint16_t*>(this);
+ return FirstHalfWord == 0;
+ }
+
+ bool IsShortInstruction() const;
+
+ inline uint8_t InstructionSize() const {
+ return (this->IsShortInstruction()) ? kShortInstrSize : kInstrSize;
+ }
+
+ // Get the raw instruction bits.
+ inline Instr InstructionBits() const {
+ if (this->IsShortInstruction()) {
+ return 0x0000FFFF & (*reinterpret_cast<const ShortInstr*>(this));
+ }
+ return *reinterpret_cast<const Instr*>(this);
+ }
+
+ // Set the raw instruction bits to value.
+ inline void SetInstructionBits(Instr value) {
+ *reinterpret_cast<Instr*>(this) = value;
+ }
+
+ // Read one particular bit out of the instruction bits.
+ inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
+
+ // Read a bit field out of the instruction bits.
+ inline int Bits(int hi, int lo) const {
+ return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
+ }
+
+ // Accessors for the different named fields used in the RISC-V encoding.
+ inline BaseOpcode BaseOpcodeValue() const {
+ return static_cast<BaseOpcode>(
+ Bits(kBaseOpcodeShift + kBaseOpcodeBits - 1, kBaseOpcodeShift));
+ }
+
+ // Return the fields at their original place in the instruction encoding.
+ inline BaseOpcode BaseOpcodeFieldRaw() const {
+ return static_cast<BaseOpcode>(InstructionBits() & kBaseOpcodeMask);
+ }
+
+ // Safe to call within R-type instructions
+ inline int Funct7FieldRaw() const { return InstructionBits() & kFunct7Mask; }
+
+ // Safe to call within R-, I-, S-, or B-type instructions
+ inline int Funct3FieldRaw() const { return InstructionBits() & kFunct3Mask; }
+
+ // Safe to call within R-, I-, S-, or B-type instructions
+ inline int Rs1FieldRawNoAssert() const {
+ return InstructionBits() & kRs1FieldMask;
+ }
+
+ // Safe to call within R-, S-, or B-type instructions
+ inline int Rs2FieldRawNoAssert() const {
+ return InstructionBits() & kRs2FieldMask;
+ }
+
+ // Safe to call within R4-type instructions
+ inline int Rs3FieldRawNoAssert() const {
+ return InstructionBits() & kRs3FieldMask;
+ }
+
+ inline int32_t ITypeBits() const { return InstructionBits() & kITypeMask; }
+
+ inline int32_t InstructionOpcodeType() const {
+ if (IsShortInstruction()) {
+ return InstructionBits() & kRvcOpcodeMask;
+ } else {
+ return InstructionBits() & kBaseOpcodeMask;
+ }
+ }
+
+ // Get the encoding type of the instruction.
+ Type InstructionType() const;
+ OffsetSize GetOffsetSize() const;
+ inline ImmBranchRangeType GetImmBranchRangeType() const {
+ return OffsetSizeToImmBranchRangeType(GetOffsetSize());
+ }
+
+ protected:
+ InstructionBase() {}
+};
+
+template <class T>
+class InstructionGetters : public T {
+ public:
+ // Say if the instruction is a break or a trap.
+ bool IsTrap() const;
+
+ inline int BaseOpcode() const {
+ return this->InstructionBits() & kBaseOpcodeMask;
+ }
+
+ inline int RvcOpcode() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ return this->InstructionBits() & kRvcOpcodeMask;
+ }
+
+ inline int Rs1Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
+ this->InstructionType() == InstructionBase::kR4Type ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType ||
+ this->InstructionType() == InstructionBase::kBType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kVType);
+ return this->Bits(kRs1Shift + kRs1Bits - 1, kRs1Shift);
+ }
+
+ inline int Rs2Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
+ this->InstructionType() == InstructionBase::kR4Type ||
+ this->InstructionType() == InstructionBase::kSType ||
+ this->InstructionType() == InstructionBase::kBType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kVType);
+ return this->Bits(kRs2Shift + kRs2Bits - 1, kRs2Shift);
+ }
+
+ inline int Rs3Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kR4Type);
+ return this->Bits(kRs3Shift + kRs3Bits - 1, kRs3Shift);
+ }
+
+ inline int Vs1Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType);
+ return this->Bits(kVs1Shift + kVs1Bits - 1, kVs1Shift);
+ }
+
+ inline int Vs2Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType);
+ return this->Bits(kVs2Shift + kVs2Bits - 1, kVs2Shift);
+ }
+
+ inline int VdValue() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType);
+ return this->Bits(kVdShift + kVdBits - 1, kVdShift);
+ }
+
+ inline int RdValue() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
+ this->InstructionType() == InstructionBase::kR4Type ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType ||
+ this->InstructionType() == InstructionBase::kUType ||
+ this->InstructionType() == InstructionBase::kJType ||
+ this->InstructionType() == InstructionBase::kVType);
+ return this->Bits(kRdShift + kRdBits - 1, kRdShift);
+ }
+
+ inline int RvcRs1Value() const { return this->RvcRdValue(); }
+
+ int RvcRdValue() const;
+
+ int RvcRs2Value() const;
+
+ int RvcRs1sValue() const;
+
+ int RvcRs2sValue() const;
+
+ int Funct7Value() const;
+
+ inline int Funct3Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType ||
+ this->InstructionType() == InstructionBase::kBType);
+ return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
+ }
+
+ inline int Funct5Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kRType &&
+ this->BaseOpcode() == OP_FP);
+ return this->Bits(kFunct5Shift + kFunct5Bits - 1, kFunct5Shift);
+ }
+
+ int RvcFunct6Value() const;
+
+ int RvcFunct4Value() const;
+
+ int RvcFunct3Value() const;
+
+ int RvcFunct2Value() const;
+
+ int RvcFunct2BValue() const;
+
+ inline int CsrValue() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kIType &&
+ this->BaseOpcode() == SYSTEM);
+ return (this->Bits(kCsrShift + kCsrBits - 1, kCsrShift));
+ }
+
+ inline int RoundMode() const {
+ MOZ_ASSERT((this->InstructionType() == InstructionBase::kRType ||
+ this->InstructionType() == InstructionBase::kR4Type) &&
+ this->BaseOpcode() == OP_FP);
+ return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
+ }
+
+ inline int MemoryOrder(bool is_pred) const {
+ MOZ_ASSERT((this->InstructionType() == InstructionBase::kIType &&
+ this->BaseOpcode() == MISC_MEM));
+ if (is_pred) {
+ return this->Bits(kPredOrderShift + kMemOrderBits - 1, kPredOrderShift);
+ } else {
+ return this->Bits(kSuccOrderShift + kMemOrderBits - 1, kSuccOrderShift);
+ }
+ }
+
+ inline int Imm12Value() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kIType);
+ int Value = this->Bits(kImm12Shift + kImm12Bits - 1, kImm12Shift);
+ return Value << 20 >> 20;
+ }
+
+ inline int32_t Imm12SExtValue() const {
+ int32_t Value = this->Imm12Value() << 20 >> 20;
+ return Value;
+ }
+
+ inline int BranchOffset() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kBType);
+ // | imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode |
+ // 31 25 11 7
+ uint32_t Bits = this->InstructionBits();
+ int16_t imm13 = ((Bits & 0xf00) >> 7) | ((Bits & 0x7e000000) >> 20) |
+ ((Bits & 0x80) << 4) | ((Bits & 0x80000000) >> 19);
+ return imm13 << 19 >> 19;
+ }
+
+ inline int StoreOffset() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kSType);
+ // | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
+ // 31 25 11 7
+ uint32_t Bits = this->InstructionBits();
+ int16_t imm12 = ((Bits & 0xf80) >> 7) | ((Bits & 0xfe000000) >> 20);
+ return imm12 << 20 >> 20;
+ }
+
+ inline int Imm20UValue() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kUType);
+ // | imm[31:12] | rd | opcode |
+ // 31 12
+ int32_t Bits = this->InstructionBits();
+ return Bits >> 12;
+ }
+
+ inline int Imm20JValue() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kJType);
+ // | imm[20|10:1|11|19:12] | rd | opcode |
+ // 31 12
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm20 = ((Bits & 0x7fe00000) >> 20) | ((Bits & 0x100000) >> 9) |
+ (Bits & 0xff000) | ((Bits & 0x80000000) >> 11);
+ return imm20 << 11 >> 11;
+ }
+
+ inline bool IsArithShift() const {
+ // Valid only for right shift operations
+ MOZ_ASSERT((this->BaseOpcode() == OP || this->BaseOpcode() == OP_32 ||
+ this->BaseOpcode() == OP_IMM ||
+ this->BaseOpcode() == OP_IMM_32) &&
+ this->Funct3Value() == 0b101);
+ return this->InstructionBits() & 0x40000000;
+ }
+
+ inline int Shamt() const {
+ // Valid only for shift instructions (SLLI, SRLI, SRAI)
+ MOZ_ASSERT((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM &&
+ (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
+ // | 0A0000 | shamt | rs1 | funct3 | rd | opcode |
+ // 31 25 20
+ return this->Bits(kImm12Shift + 5, kImm12Shift);
+ }
+
+ inline int Shamt32() const {
+ // Valid only for shift instructions (SLLIW, SRLIW, SRAIW)
+ MOZ_ASSERT((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM_32 &&
+ (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
+ // | 0A00000 | shamt | rs1 | funct3 | rd | opcode |
+ // 31 24 20
+ return this->Bits(kImm12Shift + 4, kImm12Shift);
+ }
+
+ inline int RvcImm6Value() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | imm[5] | rs1/rd | imm[4:0] | opcode |
+ // 15 12 6 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm6 = ((Bits & 0x1000) >> 7) | ((Bits & 0x7c) >> 2);
+ return imm6 << 26 >> 26;
+ }
+
+ inline int RvcImm6Addi16spValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | nzimm[9] | 2 | nzimm[4|6|8:7|5] | opcode |
+ // 15 12 6 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm10 = ((Bits & 0x1000) >> 3) | ((Bits & 0x40) >> 2) |
+ ((Bits & 0x20) << 1) | ((Bits & 0x18) << 4) |
+ ((Bits & 0x4) << 3);
+ MOZ_ASSERT(imm10 != 0);
+ return imm10 << 22 >> 22;
+ }
+
+ inline int RvcImm8Addi4spnValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | nzimm[11] | rd' | opcode |
+ // 15 13 5 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t uimm10 = ((Bits & 0x20) >> 2) | ((Bits & 0x40) >> 4) |
+ ((Bits & 0x780) >> 1) | ((Bits & 0x1800) >> 7);
+ MOZ_ASSERT(uimm10 != 0);
+ return uimm10;
+ }
+
+ inline int RvcShamt6() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | nzuimm[5] | rs1/rd | nzuimm[4:0] | opcode |
+ // 15 12 6 2
+ int32_t imm6 = this->RvcImm6Value();
+ return imm6 & 0x3f;
+ }
+
+ inline int RvcImm6LwspValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | uimm[5] | rs1 | uimm[4:2|7:6] | opcode |
+ // 15 12 6 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm8 =
+ ((Bits & 0x1000) >> 7) | ((Bits & 0x70) >> 2) | ((Bits & 0xc) << 4);
+ return imm8;
+ }
+
+ inline int RvcImm6LdspValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | uimm[5] | rs1 | uimm[4:3|8:6] | opcode |
+ // 15 12 6 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm9 =
+ ((Bits & 0x1000) >> 7) | ((Bits & 0x60) >> 2) | ((Bits & 0x1c) << 4);
+ return imm9;
+ }
+
+ inline int RvcImm6SwspValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | uimm[5:2|7:6] | rs2 | opcode |
+ // 15 12 7
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm8 = ((Bits & 0x1e00) >> 7) | ((Bits & 0x180) >> 1);
+ return imm8;
+ }
+
+ inline int RvcImm6SdspValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | uimm[5:3|8:6] | rs2 | opcode |
+ // 15 12 7
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm9 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x380) >> 1);
+ return imm9;
+ }
+
+ inline int RvcImm5WValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | imm[5:3] | rs1 | imm[2|6] | rd | opcode |
+ // 15 12 10 6 4 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm7 =
+ ((Bits & 0x1c00) >> 7) | ((Bits & 0x40) >> 4) | ((Bits & 0x20) << 1);
+ return imm7;
+ }
+
+ inline int RvcImm5DValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | imm[5:3] | rs1 | imm[7:6] | rd | opcode |
+ // 15 12 10 6 4 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm8 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x60) << 1);
+ return imm8;
+ }
+
+ inline int RvcImm11CJValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | [11|4|9:8|10|6|7|3:1|5] | opcode |
+ // 15 12 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm12 = ((Bits & 0x4) << 3) | ((Bits & 0x38) >> 2) |
+ ((Bits & 0x40) << 1) | ((Bits & 0x80) >> 1) |
+ ((Bits & 0x100) << 2) | ((Bits & 0x600) >> 1) |
+ ((Bits & 0x800) >> 7) | ((Bits & 0x1000) >> 1);
+ return imm12 << 20 >> 20;
+ }
+
+ inline int RvcImm8BValue() const {
+ MOZ_ASSERT(this->IsShortInstruction());
+ // | funct3 | imm[8|4:3] | rs1` | imm[7:6|2:1|5] | opcode |
+ // 15 12 10 7 2
+ uint32_t Bits = this->InstructionBits();
+ int32_t imm9 = ((Bits & 0x4) << 3) | ((Bits & 0x18) >> 2) |
+ ((Bits & 0x60) << 1) | ((Bits & 0xc00) >> 7) |
+ ((Bits & 0x1000) >> 4);
+ return imm9 << 23 >> 23;
+ }
+
+ inline int vl_vs_width() {
+ int width = 0;
+ if ((this->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
+ (this->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
+ return -1;
+ switch (this->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
+ case 0x0:
+ width = 8;
+ break;
+ case 0x00005000:
+ width = 16;
+ break;
+ case 0x00006000:
+ width = 32;
+ break;
+ case 0x00007000:
+ width = 64;
+ break;
+ case 0x10000000:
+ width = 128;
+ break;
+ case 0x10005000:
+ width = 256;
+ break;
+ case 0x10006000:
+ width = 512;
+ break;
+ case 0x10007000:
+ width = 1024;
+ break;
+ default:
+ width = -1;
+ break;
+ }
+ return width;
+ }
+
+ uint32_t Rvvzimm() const;
+
+ uint32_t Rvvuimm() const;
+
+ inline uint32_t RvvVsew() const {
+ uint32_t zimm = this->Rvvzimm();
+ uint32_t vsew = (zimm >> 3) & 0x7;
+ return vsew;
+ }
+
+ inline uint32_t RvvVlmul() const {
+ uint32_t zimm = this->Rvvzimm();
+ uint32_t vlmul = zimm & 0x7;
+ return vlmul;
+ }
+
+ inline uint8_t RvvVM() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType ||
+ this->InstructionType() == InstructionBase::kIType ||
+ this->InstructionType() == InstructionBase::kSType);
+ return this->Bits(kRvvVmShift + kRvvVmBits - 1, kRvvVmShift);
+ }
+
+ inline const char* RvvSEW() const {
+ uint32_t vsew = this->RvvVsew();
+ switch (vsew) {
+#define CAST_VSEW(name) \
+ case name: \
+ return #name;
+ RVV_SEW(CAST_VSEW)
+ default:
+ return "unknown";
+#undef CAST_VSEW
+ }
+ }
+
+ inline const char* RvvLMUL() const {
+ uint32_t vlmul = this->RvvVlmul();
+ switch (vlmul) {
+#define CAST_VLMUL(name) \
+ case name: \
+ return #name;
+ RVV_LMUL(CAST_VLMUL)
+ default:
+ return "unknown";
+#undef CAST_VLMUL
+ }
+ }
+
+#define sext(x, len) (((int32_t)(x) << (32 - len)) >> (32 - len))
+#define zext(x, len) (((uint32_t)(x) << (32 - len)) >> (32 - len))
+
+ inline int32_t RvvSimm5() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType);
+ return sext(this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift),
+ kRvvImm5Bits);
+ }
+
+ inline uint32_t RvvUimm5() const {
+ MOZ_ASSERT(this->InstructionType() == InstructionBase::kVType);
+ uint32_t imm = this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift);
+ return zext(imm, kRvvImm5Bits);
+ }
+#undef sext
+#undef zext
+ inline bool AqValue() const { return this->Bits(kAqShift, kAqShift); }
+
+ inline bool RlValue() const { return this->Bits(kRlShift, kRlShift); }
+};
+
+class Instruction : public InstructionGetters<InstructionBase> {
+ public:
+ // Instructions are read of out a code stream. The only way to get a
+ // reference to an instruction is to convert a pointer. There is no way
+ // to allocate or create instances of class Instruction.
+ // Use the At(pc) function to create references to Instruction.
+ static Instruction* At(byte* pc) {
+ return reinterpret_cast<Instruction*>(pc);
+ }
+
+ private:
+ // We need to prevent the creation of instances of class Instruction.
+ Instruction() = delete;
+ Instruction(const Instruction&) = delete;
+ Instruction& operator=(const Instruction&) = delete;
+};
+
+// -----------------------------------------------------------------------------
+// Instructions.
+
+template <class P>
+bool InstructionGetters<P>::IsTrap() const {
+ return (this->InstructionBits() == kBreakInstr);
+}
+
+} // namespace jit
+} // namespace js
+#endif // jit_riscv64_constant_Base_constant_riscv__h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-a.h b/js/src/jit/riscv64/constant/Constant-riscv-a.h
new file mode 100644
index 0000000000..718e607240
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-a.h
@@ -0,0 +1,43 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_a_h_
+#define jit_riscv64_constant_Constant_riscv64_a_h_
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+enum OpcodeRISCVA : uint32_t {
+ // RV32A Standard Extension
+ RO_LR_W = AMO | (0b010 << kFunct3Shift) | (0b00010 << kFunct5Shift),
+ RO_SC_W = AMO | (0b010 << kFunct3Shift) | (0b00011 << kFunct5Shift),
+ RO_AMOSWAP_W = AMO | (0b010 << kFunct3Shift) | (0b00001 << kFunct5Shift),
+ RO_AMOADD_W = AMO | (0b010 << kFunct3Shift) | (0b00000 << kFunct5Shift),
+ RO_AMOXOR_W = AMO | (0b010 << kFunct3Shift) | (0b00100 << kFunct5Shift),
+ RO_AMOAND_W = AMO | (0b010 << kFunct3Shift) | (0b01100 << kFunct5Shift),
+ RO_AMOOR_W = AMO | (0b010 << kFunct3Shift) | (0b01000 << kFunct5Shift),
+ RO_AMOMIN_W = AMO | (0b010 << kFunct3Shift) | (0b10000 << kFunct5Shift),
+ RO_AMOMAX_W = AMO | (0b010 << kFunct3Shift) | (0b10100 << kFunct5Shift),
+ RO_AMOMINU_W = AMO | (0b010 << kFunct3Shift) | (0b11000 << kFunct5Shift),
+ RO_AMOMAXU_W = AMO | (0b010 << kFunct3Shift) | (0b11100 << kFunct5Shift),
+
+#ifdef JS_CODEGEN_RISCV64
+ // RV64A Standard Extension (in addition to RV32A)
+ RO_LR_D = AMO | (0b011 << kFunct3Shift) | (0b00010 << kFunct5Shift),
+ RO_SC_D = AMO | (0b011 << kFunct3Shift) | (0b00011 << kFunct5Shift),
+ RO_AMOSWAP_D = AMO | (0b011 << kFunct3Shift) | (0b00001 << kFunct5Shift),
+ RO_AMOADD_D = AMO | (0b011 << kFunct3Shift) | (0b00000 << kFunct5Shift),
+ RO_AMOXOR_D = AMO | (0b011 << kFunct3Shift) | (0b00100 << kFunct5Shift),
+ RO_AMOAND_D = AMO | (0b011 << kFunct3Shift) | (0b01100 << kFunct5Shift),
+ RO_AMOOR_D = AMO | (0b011 << kFunct3Shift) | (0b01000 << kFunct5Shift),
+ RO_AMOMIN_D = AMO | (0b011 << kFunct3Shift) | (0b10000 << kFunct5Shift),
+ RO_AMOMAX_D = AMO | (0b011 << kFunct3Shift) | (0b10100 << kFunct5Shift),
+ RO_AMOMINU_D = AMO | (0b011 << kFunct3Shift) | (0b11000 << kFunct5Shift),
+ RO_AMOMAXU_D = AMO | (0b011 << kFunct3Shift) | (0b11100 << kFunct5Shift),
+#endif // JS_CODEGEN_RISCV64
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_a_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-c.h b/js/src/jit/riscv64/constant/Constant-riscv-c.h
new file mode 100644
index 0000000000..a7d4792f5f
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-c.h
@@ -0,0 +1,61 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_c_h_
+#define jit_riscv64_constant_Constant_riscv64_c_h_
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+enum OpcodeRISCVC : uint32_t {
+
+ RO_C_ADDI4SPN = C0 | (0b000 << kRvcFunct3Shift),
+ RO_C_ADDI16SP = C1 | (0b011 << kRvcFunct3Shift),
+ RO_C_LW = C0 | (0b010 << kRvcFunct3Shift),
+ RO_C_SW = C0 | (0b110 << kRvcFunct3Shift),
+ RO_C_NOP_ADDI = C1 | (0b000 << kRvcFunct3Shift),
+ RO_C_LI = C1 | (0b010 << kRvcFunct3Shift),
+ RO_C_SUB = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_0 << kRvcFunct2Shift),
+ RO_C_XOR = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_1 << kRvcFunct2Shift),
+ RO_C_OR = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_2 << kRvcFunct2Shift),
+ RO_C_AND = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_3 << kRvcFunct2Shift),
+ RO_C_LUI_ADD = C1 | (0b011 << kRvcFunct3Shift),
+ RO_C_MISC_ALU = C1 | (0b100 << kRvcFunct3Shift),
+ RO_C_J = C1 | (0b101 << kRvcFunct3Shift),
+ RO_C_BEQZ = C1 | (0b110 << kRvcFunct3Shift),
+ RO_C_BNEZ = C1 | (0b111 << kRvcFunct3Shift),
+ RO_C_SLLI = C2 | (0b000 << kRvcFunct3Shift),
+ RO_C_LWSP = C2 | (0b010 << kRvcFunct3Shift),
+ RO_C_JR_MV_ADD = C2 | (0b100 << kRvcFunct3Shift),
+ RO_C_JR = C2 | (0b1000 << kRvcFunct4Shift),
+ RO_C_MV = C2 | (0b1000 << kRvcFunct4Shift),
+ RO_C_EBREAK = C2 | (0b1001 << kRvcFunct4Shift),
+ RO_C_JALR = C2 | (0b1001 << kRvcFunct4Shift),
+ RO_C_ADD = C2 | (0b1001 << kRvcFunct4Shift),
+ RO_C_SWSP = C2 | (0b110 << kRvcFunct3Shift),
+
+ RO_C_FSD = C0 | (0b101 << kRvcFunct3Shift),
+ RO_C_FLD = C0 | (0b001 << kRvcFunct3Shift),
+ RO_C_FLDSP = C2 | (0b001 << kRvcFunct3Shift),
+ RO_C_FSDSP = C2 | (0b101 << kRvcFunct3Shift),
+#ifdef JS_CODEGEN_RISCV64
+ RO_C_LD = C0 | (0b011 << kRvcFunct3Shift),
+ RO_C_SD = C0 | (0b111 << kRvcFunct3Shift),
+ RO_C_LDSP = C2 | (0b011 << kRvcFunct3Shift),
+ RO_C_SDSP = C2 | (0b111 << kRvcFunct3Shift),
+ RO_C_ADDIW = C1 | (0b001 << kRvcFunct3Shift),
+ RO_C_SUBW =
+ C1 | (0b100111 << kRvcFunct6Shift) | (FUNCT2_0 << kRvcFunct2Shift),
+ RO_C_ADDW =
+ C1 | (0b100111 << kRvcFunct6Shift) | (FUNCT2_1 << kRvcFunct2Shift),
+#endif
+#ifdef JS_CODEGEN_RISCV32
+ RO_C_FLWSP = C2 | (0b011 << kRvcFunct3Shift),
+ RO_C_FSWSP = C2 | (0b111 << kRvcFunct3Shift),
+ RO_C_FLW = C0 | (0b011 << kRvcFunct3Shift),
+ RO_C_FSW = C0 | (0b111 << kRvcFunct3Shift),
+#endif
+};
+} // namespace jit
+} // namespace js
+#endif // jit_riscv64_constant_Constant_riscv64_c_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-d.h b/js/src/jit/riscv64/constant/Constant-riscv-d.h
new file mode 100644
index 0000000000..d97e44ffe5
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-d.h
@@ -0,0 +1,55 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_d_h_
+#define jit_riscv64_constant_Constant_riscv64_d_h_
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+enum OpcodeRISCVD : uint32_t {
+ // RV32D Standard Extension
+ RO_FLD = LOAD_FP | (0b011 << kFunct3Shift),
+ RO_FSD = STORE_FP | (0b011 << kFunct3Shift),
+ RO_FMADD_D = MADD | (0b01 << kFunct2Shift),
+ RO_FMSUB_D = MSUB | (0b01 << kFunct2Shift),
+ RO_FNMSUB_D = NMSUB | (0b01 << kFunct2Shift),
+ RO_FNMADD_D = NMADD | (0b01 << kFunct2Shift),
+ RO_FADD_D = OP_FP | (0b0000001 << kFunct7Shift),
+ RO_FSUB_D = OP_FP | (0b0000101 << kFunct7Shift),
+ RO_FMUL_D = OP_FP | (0b0001001 << kFunct7Shift),
+ RO_FDIV_D = OP_FP | (0b0001101 << kFunct7Shift),
+ RO_FSQRT_D = OP_FP | (0b0101101 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FSGNJ_D = OP_FP | (0b000 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
+ RO_FSGNJN_D = OP_FP | (0b001 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
+ RO_FSQNJX_D = OP_FP | (0b010 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
+ RO_FMIN_D = OP_FP | (0b000 << kFunct3Shift) | (0b0010101 << kFunct7Shift),
+ RO_FMAX_D = OP_FP | (0b001 << kFunct3Shift) | (0b0010101 << kFunct7Shift),
+ RO_FCVT_S_D = OP_FP | (0b0100000 << kFunct7Shift) | (0b00001 << kRs2Shift),
+ RO_FCVT_D_S = OP_FP | (0b0100001 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FEQ_D = OP_FP | (0b010 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
+ RO_FLT_D = OP_FP | (0b001 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
+ RO_FLE_D = OP_FP | (0b000 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
+ RO_FCLASS_D = OP_FP | (0b001 << kFunct3Shift) | (0b1110001 << kFunct7Shift) |
+ (0b00000 << kRs2Shift),
+ RO_FCVT_W_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FCVT_WU_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00001 << kRs2Shift),
+ RO_FCVT_D_W = OP_FP | (0b1101001 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FCVT_D_WU = OP_FP | (0b1101001 << kFunct7Shift) | (0b00001 << kRs2Shift),
+
+#ifdef JS_CODEGEN_RISCV64
+ // RV64D Standard Extension (in addition to RV32D)
+ RO_FCVT_L_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00010 << kRs2Shift),
+ RO_FCVT_LU_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00011 << kRs2Shift),
+ RO_FMV_X_D = OP_FP | (0b000 << kFunct3Shift) | (0b1110001 << kFunct7Shift) |
+ (0b00000 << kRs2Shift),
+ RO_FCVT_D_L = OP_FP | (0b1101001 << kFunct7Shift) | (0b00010 << kRs2Shift),
+ RO_FCVT_D_LU = OP_FP | (0b1101001 << kFunct7Shift) | (0b00011 << kRs2Shift),
+ RO_FMV_D_X = OP_FP | (0b000 << kFunct3Shift) | (0b1111001 << kFunct7Shift) |
+ (0b00000 << kRs2Shift),
+#endif
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_a_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-f.h b/js/src/jit/riscv64/constant/Constant-riscv-f.h
new file mode 100644
index 0000000000..28c96394e2
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-f.h
@@ -0,0 +1,51 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_f_h_
+#define jit_riscv64_constant_Constant_riscv64_f_h_
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+enum OpcodeRISCVF : uint32_t {
+ // RV32F Standard Extension
+ RO_FLW = LOAD_FP | (0b010 << kFunct3Shift),
+ RO_FSW = STORE_FP | (0b010 << kFunct3Shift),
+ RO_FMADD_S = MADD | (0b00 << kFunct2Shift),
+ RO_FMSUB_S = MSUB | (0b00 << kFunct2Shift),
+ RO_FNMSUB_S = NMSUB | (0b00 << kFunct2Shift),
+ RO_FNMADD_S = NMADD | (0b00 << kFunct2Shift),
+ RO_FADD_S = OP_FP | (0b0000000 << kFunct7Shift),
+ RO_FSUB_S = OP_FP | (0b0000100 << kFunct7Shift),
+ RO_FMUL_S = OP_FP | (0b0001000 << kFunct7Shift),
+ RO_FDIV_S = OP_FP | (0b0001100 << kFunct7Shift),
+ RO_FSQRT_S = OP_FP | (0b0101100 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FSGNJ_S = OP_FP | (0b000 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
+ RO_FSGNJN_S = OP_FP | (0b001 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
+ RO_FSQNJX_S = OP_FP | (0b010 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
+ RO_FMIN_S = OP_FP | (0b000 << kFunct3Shift) | (0b0010100 << kFunct7Shift),
+ RO_FMAX_S = OP_FP | (0b001 << kFunct3Shift) | (0b0010100 << kFunct7Shift),
+ RO_FCVT_W_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FCVT_WU_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00001 << kRs2Shift),
+ RO_FMV = OP_FP | (0b1110000 << kFunct7Shift) | (0b000 << kFunct3Shift) |
+ (0b00000 << kRs2Shift),
+ RO_FEQ_S = OP_FP | (0b010 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
+ RO_FLT_S = OP_FP | (0b001 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
+ RO_FLE_S = OP_FP | (0b000 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
+ RO_FCLASS_S = OP_FP | (0b001 << kFunct3Shift) | (0b1110000 << kFunct7Shift),
+ RO_FCVT_S_W = OP_FP | (0b1101000 << kFunct7Shift) | (0b00000 << kRs2Shift),
+ RO_FCVT_S_WU = OP_FP | (0b1101000 << kFunct7Shift) | (0b00001 << kRs2Shift),
+ RO_FMV_W_X = OP_FP | (0b000 << kFunct3Shift) | (0b1111000 << kFunct7Shift),
+
+#ifdef JS_CODEGEN_RISCV64
+ // RV64F Standard Extension (in addition to RV32F)
+ RO_FCVT_L_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00010 << kRs2Shift),
+ RO_FCVT_LU_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00011 << kRs2Shift),
+ RO_FCVT_S_L = OP_FP | (0b1101000 << kFunct7Shift) | (0b00010 << kRs2Shift),
+ RO_FCVT_S_LU = OP_FP | (0b1101000 << kFunct7Shift) | (0b00011 << kRs2Shift),
+#endif // JS_CODEGEN_RISCV64
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_f_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-i.h b/js/src/jit/riscv64/constant/Constant-riscv-i.h
new file mode 100644
index 0000000000..586ffd8a14
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-i.h
@@ -0,0 +1,73 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_i_h_
+#define jit_riscv64_constant_Constant_riscv64_i_h_
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+enum OpcodeRISCV32I : uint32_t {
+ // Note use RO (RiscV Opcode) prefix
+ // RV32I Base Instruction Set
+ RO_LUI = LUI,
+ RO_AUIPC = AUIPC,
+ RO_JAL = JAL,
+ RO_JALR = JALR | (0b000 << kFunct3Shift),
+ RO_BEQ = BRANCH | (0b000 << kFunct3Shift),
+ RO_BNE = BRANCH | (0b001 << kFunct3Shift),
+ RO_BLT = BRANCH | (0b100 << kFunct3Shift),
+ RO_BGE = BRANCH | (0b101 << kFunct3Shift),
+ RO_BLTU = BRANCH | (0b110 << kFunct3Shift),
+ RO_BGEU = BRANCH | (0b111 << kFunct3Shift),
+ RO_LB = LOAD | (0b000 << kFunct3Shift),
+ RO_LH = LOAD | (0b001 << kFunct3Shift),
+ RO_LW = LOAD | (0b010 << kFunct3Shift),
+ RO_LBU = LOAD | (0b100 << kFunct3Shift),
+ RO_LHU = LOAD | (0b101 << kFunct3Shift),
+ RO_SB = STORE | (0b000 << kFunct3Shift),
+ RO_SH = STORE | (0b001 << kFunct3Shift),
+ RO_SW = STORE | (0b010 << kFunct3Shift),
+ RO_ADDI = OP_IMM | (0b000 << kFunct3Shift),
+ RO_SLTI = OP_IMM | (0b010 << kFunct3Shift),
+ RO_SLTIU = OP_IMM | (0b011 << kFunct3Shift),
+ RO_XORI = OP_IMM | (0b100 << kFunct3Shift),
+ RO_ORI = OP_IMM | (0b110 << kFunct3Shift),
+ RO_ANDI = OP_IMM | (0b111 << kFunct3Shift),
+ RO_SLLI = OP_IMM | (0b001 << kFunct3Shift),
+ RO_SRLI = OP_IMM | (0b101 << kFunct3Shift),
+ // RO_SRAI = OP_IMM | (0b101 << kFunct3Shift), // Same as SRLI, use func7
+ RO_ADD = OP | (0b000 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SUB = OP | (0b000 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
+ RO_SLL = OP | (0b001 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SLT = OP | (0b010 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SLTU = OP | (0b011 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_XOR = OP | (0b100 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SRL = OP | (0b101 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SRA = OP | (0b101 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
+ RO_OR = OP | (0b110 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_AND = OP | (0b111 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_FENCE = MISC_MEM | (0b000 << kFunct3Shift),
+ RO_ECALL = SYSTEM | (0b000 << kFunct3Shift),
+// RO_EBREAK = SYSTEM | (0b000 << kFunct3Shift), // Same as ECALL, use imm12
+
+#if JS_CODEGEN_RISCV64
+ // RV64I Base Instruction Set (in addition to RV32I)
+ RO_LWU = LOAD | (0b110 << kFunct3Shift),
+ RO_LD = LOAD | (0b011 << kFunct3Shift),
+ RO_SD = STORE | (0b011 << kFunct3Shift),
+ RO_ADDIW = OP_IMM_32 | (0b000 << kFunct3Shift),
+ RO_SLLIW = OP_IMM_32 | (0b001 << kFunct3Shift),
+ RO_SRLIW = OP_IMM_32 | (0b101 << kFunct3Shift),
+ // RO_SRAIW = OP_IMM_32 | (0b101 << kFunct3Shift), // Same as SRLIW, use func7
+ RO_ADDW = OP_32 | (0b000 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SUBW = OP_32 | (0b000 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
+ RO_SLLW = OP_32 | (0b001 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SRLW = OP_32 | (0b101 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
+ RO_SRAW = OP_32 | (0b101 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
+#endif
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_i_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-m.h b/js/src/jit/riscv64/constant/Constant-riscv-m.h
new file mode 100644
index 0000000000..81a69dab41
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-m.h
@@ -0,0 +1,34 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_m_h_
+#define jit_riscv64_constant_Constant_riscv64_m_h_
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+enum OpcodeRISCVM : uint32_t {
+ // RV32M Standard Extension
+ RO_MUL = OP | (0b000 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_MULH = OP | (0b001 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_MULHSU = OP | (0b010 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_MULHU = OP | (0b011 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_DIV = OP | (0b100 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_DIVU = OP | (0b101 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_REM = OP | (0b110 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_REMU = OP | (0b111 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+
+#ifdef JS_CODEGEN_RISCV64
+ // RV64M Standard Extension (in addition to RV32M)
+ RO_MULW = OP_32 | (0b000 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_DIVW = OP_32 | (0b100 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_DIVUW = OP_32 | (0b101 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_REMW = OP_32 | (0b110 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+ RO_REMUW = OP_32 | (0b111 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
+#endif
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_extension_CONSTANT_RISCV_M_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-v.h b/js/src/jit/riscv64/constant/Constant-riscv-v.h
new file mode 100644
index 0000000000..cca3540efd
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-v.h
@@ -0,0 +1,508 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_v_h_
+#define jit_riscv64_constant_Constant_riscv64_v_h_
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+
+namespace RVV {
+enum TailAgnosticType {
+ ta = 0x1, // Tail agnostic
+ tu = 0x0, // Tail undisturbed
+};
+
+enum MaskAgnosticType {
+ ma = 0x1, // Mask agnostic
+ mu = 0x0, // Mask undisturbed
+};
+enum MaskType {
+ Mask = 0x0, // use the mask
+ NoMask = 0x1,
+};
+} // namespace RVV
+
+enum OpcodeRISCVV : uint32_t {
+ // RVV Extension
+ OP_IVV = OP_V | (0b000 << kFunct3Shift),
+ OP_FVV = OP_V | (0b001 << kFunct3Shift),
+ OP_MVV = OP_V | (0b010 << kFunct3Shift),
+ OP_IVI = OP_V | (0b011 << kFunct3Shift),
+ OP_IVX = OP_V | (0b100 << kFunct3Shift),
+ OP_FVF = OP_V | (0b101 << kFunct3Shift),
+ OP_MVX = OP_V | (0b110 << kFunct3Shift),
+
+ RO_V_VSETVLI = OP_V | (0b111 << kFunct3Shift) | 0b0 << 31,
+ RO_V_VSETIVLI = OP_V | (0b111 << kFunct3Shift) | 0b11 << 30,
+ RO_V_VSETVL = OP_V | (0b111 << kFunct3Shift) | 0b1 << 31,
+
+ // RVV LOAD/STORE
+ RO_V_VL = LOAD_FP | (0b00 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ RO_V_VLS = LOAD_FP | (0b10 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ RO_V_VLX = LOAD_FP | (0b11 << kRvvMopShift) | (0b000 << kRvvNfShift),
+
+ RO_V_VS = STORE_FP | (0b00 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ RO_V_VSS = STORE_FP | (0b10 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ RO_V_VSX = STORE_FP | (0b11 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ RO_V_VSU = STORE_FP | (0b01 << kRvvMopShift) | (0b000 << kRvvNfShift),
+ // THE kFunct6Shift is mop
+ RO_V_VLSEG2 = LOAD_FP | (0b00 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VLSEG3 = LOAD_FP | (0b00 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VLSEG4 = LOAD_FP | (0b00 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VLSEG5 = LOAD_FP | (0b00 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VLSEG6 = LOAD_FP | (0b00 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VLSEG7 = LOAD_FP | (0b00 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VLSEG8 = LOAD_FP | (0b00 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ RO_V_VSSEG2 = STORE_FP | (0b00 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VSSEG3 = STORE_FP | (0b00 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VSSEG4 = STORE_FP | (0b00 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VSSEG5 = STORE_FP | (0b00 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VSSEG6 = STORE_FP | (0b00 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VSSEG7 = STORE_FP | (0b00 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VSSEG8 = STORE_FP | (0b00 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ RO_V_VLSSEG2 = LOAD_FP | (0b10 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VLSSEG3 = LOAD_FP | (0b10 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VLSSEG4 = LOAD_FP | (0b10 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VLSSEG5 = LOAD_FP | (0b10 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VLSSEG6 = LOAD_FP | (0b10 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VLSSEG7 = LOAD_FP | (0b10 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VLSSEG8 = LOAD_FP | (0b10 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ RO_V_VSSSEG2 = STORE_FP | (0b10 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VSSSEG3 = STORE_FP | (0b10 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VSSSEG4 = STORE_FP | (0b10 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VSSSEG5 = STORE_FP | (0b10 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VSSSEG6 = STORE_FP | (0b10 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VSSSEG7 = STORE_FP | (0b10 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VSSSEG8 = STORE_FP | (0b10 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ RO_V_VLXSEG2 = LOAD_FP | (0b11 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VLXSEG3 = LOAD_FP | (0b11 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VLXSEG4 = LOAD_FP | (0b11 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VLXSEG5 = LOAD_FP | (0b11 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VLXSEG6 = LOAD_FP | (0b11 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VLXSEG7 = LOAD_FP | (0b11 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VLXSEG8 = LOAD_FP | (0b11 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ RO_V_VSXSEG2 = STORE_FP | (0b11 << kRvvMopShift) | (0b001 << kRvvNfShift),
+ RO_V_VSXSEG3 = STORE_FP | (0b11 << kRvvMopShift) | (0b010 << kRvvNfShift),
+ RO_V_VSXSEG4 = STORE_FP | (0b11 << kRvvMopShift) | (0b011 << kRvvNfShift),
+ RO_V_VSXSEG5 = STORE_FP | (0b11 << kRvvMopShift) | (0b100 << kRvvNfShift),
+ RO_V_VSXSEG6 = STORE_FP | (0b11 << kRvvMopShift) | (0b101 << kRvvNfShift),
+ RO_V_VSXSEG7 = STORE_FP | (0b11 << kRvvMopShift) | (0b110 << kRvvNfShift),
+ RO_V_VSXSEG8 = STORE_FP | (0b11 << kRvvMopShift) | (0b111 << kRvvNfShift),
+
+ // RVV Vector Arithmetic Instruction
+ VADD_FUNCT6 = 0b000000,
+ RO_V_VADD_VI = OP_IVI | (VADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VADD_VV = OP_IVV | (VADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VADD_VX = OP_IVX | (VADD_FUNCT6 << kRvvFunct6Shift),
+
+ VSUB_FUNCT6 = 0b000010,
+ RO_V_VSUB_VX = OP_IVX | (VSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSUB_VV = OP_IVV | (VSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VDIVU_FUNCT6 = 0b100000,
+ RO_V_VDIVU_VX = OP_MVX | (VDIVU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VDIVU_VV = OP_MVV | (VDIVU_FUNCT6 << kRvvFunct6Shift),
+
+ VDIV_FUNCT6 = 0b100001,
+ RO_V_VDIV_VX = OP_MVX | (VDIV_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VDIV_VV = OP_MVV | (VDIV_FUNCT6 << kRvvFunct6Shift),
+
+ VREMU_FUNCT6 = 0b100010,
+ RO_V_VREMU_VX = OP_MVX | (VREMU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VREMU_VV = OP_MVV | (VREMU_FUNCT6 << kRvvFunct6Shift),
+
+ VREM_FUNCT6 = 0b100011,
+ RO_V_VREM_VX = OP_MVX | (VREM_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VREM_VV = OP_MVV | (VREM_FUNCT6 << kRvvFunct6Shift),
+
+ VMULHU_FUNCT6 = 0b100100,
+ RO_V_VMULHU_VX = OP_MVX | (VMULHU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMULHU_VV = OP_MVV | (VMULHU_FUNCT6 << kRvvFunct6Shift),
+
+ VMUL_FUNCT6 = 0b100101,
+ RO_V_VMUL_VX = OP_MVX | (VMUL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMUL_VV = OP_MVV | (VMUL_FUNCT6 << kRvvFunct6Shift),
+
+ VWMUL_FUNCT6 = 0b111011,
+ RO_V_VWMUL_VX = OP_MVX | (VWMUL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VWMUL_VV = OP_MVV | (VWMUL_FUNCT6 << kRvvFunct6Shift),
+
+ VWMULU_FUNCT6 = 0b111000,
+ RO_V_VWMULU_VX = OP_MVX | (VWMULU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VWMULU_VV = OP_MVV | (VWMULU_FUNCT6 << kRvvFunct6Shift),
+
+ VMULHSU_FUNCT6 = 0b100110,
+ RO_V_VMULHSU_VX = OP_MVX | (VMULHSU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMULHSU_VV = OP_MVV | (VMULHSU_FUNCT6 << kRvvFunct6Shift),
+
+ VMULH_FUNCT6 = 0b100111,
+ RO_V_VMULH_VX = OP_MVX | (VMULH_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMULH_VV = OP_MVV | (VMULH_FUNCT6 << kRvvFunct6Shift),
+
+ VWADD_FUNCT6 = 0b110001,
+ RO_V_VWADD_VV = OP_MVV | (VWADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VWADD_VX = OP_MVX | (VWADD_FUNCT6 << kRvvFunct6Shift),
+
+ VWADDU_FUNCT6 = 0b110000,
+ RO_V_VWADDU_VV = OP_MVV | (VWADDU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VWADDU_VX = OP_MVX | (VWADDU_FUNCT6 << kRvvFunct6Shift),
+
+ VWADDUW_FUNCT6 = 0b110101,
+ RO_V_VWADDUW_VX = OP_MVX | (VWADDUW_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VWADDUW_VV = OP_MVV | (VWADDUW_FUNCT6 << kRvvFunct6Shift),
+
+ VCOMPRESS_FUNCT6 = 0b010111,
+ RO_V_VCOMPRESS_VV = OP_MVV | (VCOMPRESS_FUNCT6 << kRvvFunct6Shift),
+
+ VSADDU_FUNCT6 = 0b100000,
+ RO_V_VSADDU_VI = OP_IVI | (VSADDU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSADDU_VV = OP_IVV | (VSADDU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSADDU_VX = OP_IVX | (VSADDU_FUNCT6 << kRvvFunct6Shift),
+
+ VSADD_FUNCT6 = 0b100001,
+ RO_V_VSADD_VI = OP_IVI | (VSADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSADD_VV = OP_IVV | (VSADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSADD_VX = OP_IVX | (VSADD_FUNCT6 << kRvvFunct6Shift),
+
+ VSSUB_FUNCT6 = 0b100011,
+ RO_V_VSSUB_VV = OP_IVV | (VSSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSSUB_VX = OP_IVX | (VSSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VSSUBU_FUNCT6 = 0b100010,
+ RO_V_VSSUBU_VV = OP_IVV | (VSSUBU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSSUBU_VX = OP_IVX | (VSSUBU_FUNCT6 << kRvvFunct6Shift),
+
+ VRSUB_FUNCT6 = 0b000011,
+ RO_V_VRSUB_VX = OP_IVX | (VRSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VRSUB_VI = OP_IVI | (VRSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VMINU_FUNCT6 = 0b000100,
+ RO_V_VMINU_VX = OP_IVX | (VMINU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMINU_VV = OP_IVV | (VMINU_FUNCT6 << kRvvFunct6Shift),
+
+ VMIN_FUNCT6 = 0b000101,
+ RO_V_VMIN_VX = OP_IVX | (VMIN_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMIN_VV = OP_IVV | (VMIN_FUNCT6 << kRvvFunct6Shift),
+
+ VMAXU_FUNCT6 = 0b000110,
+ RO_V_VMAXU_VX = OP_IVX | (VMAXU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMAXU_VV = OP_IVV | (VMAXU_FUNCT6 << kRvvFunct6Shift),
+
+ VMAX_FUNCT6 = 0b000111,
+ RO_V_VMAX_VX = OP_IVX | (VMAX_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMAX_VV = OP_IVV | (VMAX_FUNCT6 << kRvvFunct6Shift),
+
+ VAND_FUNCT6 = 0b001001,
+ RO_V_VAND_VI = OP_IVI | (VAND_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VAND_VV = OP_IVV | (VAND_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VAND_VX = OP_IVX | (VAND_FUNCT6 << kRvvFunct6Shift),
+
+ VOR_FUNCT6 = 0b001010,
+ RO_V_VOR_VI = OP_IVI | (VOR_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VOR_VV = OP_IVV | (VOR_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VOR_VX = OP_IVX | (VOR_FUNCT6 << kRvvFunct6Shift),
+
+ VXOR_FUNCT6 = 0b001011,
+ RO_V_VXOR_VI = OP_IVI | (VXOR_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VXOR_VV = OP_IVV | (VXOR_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VXOR_VX = OP_IVX | (VXOR_FUNCT6 << kRvvFunct6Shift),
+
+ VRGATHER_FUNCT6 = 0b001100,
+ RO_V_VRGATHER_VI = OP_IVI | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VRGATHER_VV = OP_IVV | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VRGATHER_VX = OP_IVX | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
+
+ VMV_FUNCT6 = 0b010111,
+ RO_V_VMV_VI = OP_IVI | (VMV_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMV_VV = OP_IVV | (VMV_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMV_VX = OP_IVX | (VMV_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMV_VF = OP_FVF | (VMV_FUNCT6 << kRvvFunct6Shift),
+
+ RO_V_VMERGE_VI = RO_V_VMV_VI,
+ RO_V_VMERGE_VV = RO_V_VMV_VV,
+ RO_V_VMERGE_VX = RO_V_VMV_VX,
+
+ VMSEQ_FUNCT6 = 0b011000,
+ RO_V_VMSEQ_VI = OP_IVI | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSEQ_VV = OP_IVV | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSEQ_VX = OP_IVX | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
+
+ VMSNE_FUNCT6 = 0b011001,
+ RO_V_VMSNE_VI = OP_IVI | (VMSNE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSNE_VV = OP_IVV | (VMSNE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSNE_VX = OP_IVX | (VMSNE_FUNCT6 << kRvvFunct6Shift),
+
+ VMSLTU_FUNCT6 = 0b011010,
+ RO_V_VMSLTU_VV = OP_IVV | (VMSLTU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLTU_VX = OP_IVX | (VMSLTU_FUNCT6 << kRvvFunct6Shift),
+
+ VMSLT_FUNCT6 = 0b011011,
+ RO_V_VMSLT_VV = OP_IVV | (VMSLT_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLT_VX = OP_IVX | (VMSLT_FUNCT6 << kRvvFunct6Shift),
+
+ VMSLE_FUNCT6 = 0b011101,
+ RO_V_VMSLE_VI = OP_IVI | (VMSLE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLE_VV = OP_IVV | (VMSLE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLE_VX = OP_IVX | (VMSLE_FUNCT6 << kRvvFunct6Shift),
+
+ VMSLEU_FUNCT6 = 0b011100,
+ RO_V_VMSLEU_VI = OP_IVI | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLEU_VV = OP_IVV | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSLEU_VX = OP_IVX | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
+
+ VMSGTU_FUNCT6 = 0b011110,
+ RO_V_VMSGTU_VI = OP_IVI | (VMSGTU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSGTU_VX = OP_IVX | (VMSGTU_FUNCT6 << kRvvFunct6Shift),
+
+ VMSGT_FUNCT6 = 0b011111,
+ RO_V_VMSGT_VI = OP_IVI | (VMSGT_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMSGT_VX = OP_IVX | (VMSGT_FUNCT6 << kRvvFunct6Shift),
+
+ VSLIDEUP_FUNCT6 = 0b001110,
+ RO_V_VSLIDEUP_VI = OP_IVI | (VSLIDEUP_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSLIDEUP_VX = OP_IVX | (VSLIDEUP_FUNCT6 << kRvvFunct6Shift),
+
+ VSLIDEDOWN_FUNCT6 = 0b001111,
+ RO_V_VSLIDEDOWN_VI = OP_IVI | (VSLIDEDOWN_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSLIDEDOWN_VX = OP_IVX | (VSLIDEDOWN_FUNCT6 << kRvvFunct6Shift),
+
+ VSRL_FUNCT6 = 0b101000,
+ RO_V_VSRL_VI = OP_IVI | (VSRL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSRL_VV = OP_IVV | (VSRL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSRL_VX = OP_IVX | (VSRL_FUNCT6 << kRvvFunct6Shift),
+
+ VSRA_FUNCT6 = 0b101001,
+ RO_V_VSRA_VI = OP_IVI | (VSRA_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSRA_VV = OP_IVV | (VSRA_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSRA_VX = OP_IVX | (VSRA_FUNCT6 << kRvvFunct6Shift),
+
+ VSLL_FUNCT6 = 0b100101,
+ RO_V_VSLL_VI = OP_IVI | (VSLL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSLL_VV = OP_IVV | (VSLL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSLL_VX = OP_IVX | (VSLL_FUNCT6 << kRvvFunct6Shift),
+
+ VSMUL_FUNCT6 = 0b100111,
+ RO_V_VSMUL_VV = OP_IVV | (VSMUL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VSMUL_VX = OP_IVX | (VSMUL_FUNCT6 << kRvvFunct6Shift),
+
+ VADC_FUNCT6 = 0b010000,
+ RO_V_VADC_VI = OP_IVI | (VADC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VADC_VV = OP_IVV | (VADC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VADC_VX = OP_IVX | (VADC_FUNCT6 << kRvvFunct6Shift),
+
+ VMADC_FUNCT6 = 0b010001,
+ RO_V_VMADC_VI = OP_IVI | (VMADC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMADC_VV = OP_IVV | (VMADC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMADC_VX = OP_IVX | (VMADC_FUNCT6 << kRvvFunct6Shift),
+
+ VWXUNARY0_FUNCT6 = 0b010000,
+ VRXUNARY0_FUNCT6 = 0b010000,
+ VMUNARY0_FUNCT6 = 0b010100,
+
+ RO_V_VWXUNARY0 = OP_MVV | (VWXUNARY0_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VRXUNARY0 = OP_MVX | (VRXUNARY0_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMUNARY0 = OP_MVV | (VMUNARY0_FUNCT6 << kRvvFunct6Shift),
+
+ VID_V = 0b10001,
+
+ VXUNARY0_FUNCT6 = 0b010010,
+ RO_V_VXUNARY0 = OP_MVV | (VXUNARY0_FUNCT6 << kRvvFunct6Shift),
+
+ VWFUNARY0_FUNCT6 = 0b010000,
+ RO_V_VFMV_FS = OP_FVV | (VWFUNARY0_FUNCT6 << kRvvFunct6Shift),
+
+ VRFUNARY0_FUNCT6 = 0b010000,
+ RO_V_VFMV_SF = OP_FVF | (VRFUNARY0_FUNCT6 << kRvvFunct6Shift),
+
+ VREDMAXU_FUNCT6 = 0b000110,
+ RO_V_VREDMAXU = OP_MVV | (VREDMAXU_FUNCT6 << kRvvFunct6Shift),
+ VREDMAX_FUNCT6 = 0b000111,
+ RO_V_VREDMAX = OP_MVV | (VREDMAX_FUNCT6 << kRvvFunct6Shift),
+
+ VREDMINU_FUNCT6 = 0b000100,
+ RO_V_VREDMINU = OP_MVV | (VREDMINU_FUNCT6 << kRvvFunct6Shift),
+ VREDMIN_FUNCT6 = 0b000101,
+ RO_V_VREDMIN = OP_MVV | (VREDMIN_FUNCT6 << kRvvFunct6Shift),
+
+ VFUNARY0_FUNCT6 = 0b010010,
+ RO_V_VFUNARY0 = OP_FVV | (VFUNARY0_FUNCT6 << kRvvFunct6Shift),
+ VFUNARY1_FUNCT6 = 0b010011,
+ RO_V_VFUNARY1 = OP_FVV | (VFUNARY1_FUNCT6 << kRvvFunct6Shift),
+
+ VFCVT_XU_F_V = 0b00000,
+ VFCVT_X_F_V = 0b00001,
+ VFCVT_F_XU_V = 0b00010,
+ VFCVT_F_X_V = 0b00011,
+ VFWCVT_XU_F_V = 0b01000,
+ VFWCVT_X_F_V = 0b01001,
+ VFWCVT_F_XU_V = 0b01010,
+ VFWCVT_F_X_V = 0b01011,
+ VFWCVT_F_F_V = 0b01100,
+ VFNCVT_F_F_W = 0b10100,
+ VFNCVT_X_F_W = 0b10001,
+ VFNCVT_XU_F_W = 0b10000,
+
+ VFCLASS_V = 0b10000,
+ VFSQRT_V = 0b00000,
+ VFRSQRT7_V = 0b00100,
+ VFREC7_V = 0b00101,
+
+ VFADD_FUNCT6 = 0b000000,
+ RO_V_VFADD_VV = OP_FVV | (VFADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFADD_VF = OP_FVF | (VFADD_FUNCT6 << kRvvFunct6Shift),
+
+ VFSUB_FUNCT6 = 0b000010,
+ RO_V_VFSUB_VV = OP_FVV | (VFSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFSUB_VF = OP_FVF | (VFSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VFDIV_FUNCT6 = 0b100000,
+ RO_V_VFDIV_VV = OP_FVV | (VFDIV_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFDIV_VF = OP_FVF | (VFDIV_FUNCT6 << kRvvFunct6Shift),
+
+ VFMUL_FUNCT6 = 0b100100,
+ RO_V_VFMUL_VV = OP_FVV | (VFMUL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMUL_VF = OP_FVF | (VFMUL_FUNCT6 << kRvvFunct6Shift),
+
+ // Vector Widening Floating-Point Add/Subtract Instructions
+ VFWADD_FUNCT6 = 0b110000,
+ RO_V_VFWADD_VV = OP_FVV | (VFWADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWADD_VF = OP_FVF | (VFWADD_FUNCT6 << kRvvFunct6Shift),
+
+ VFWSUB_FUNCT6 = 0b110010,
+ RO_V_VFWSUB_VV = OP_FVV | (VFWSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWSUB_VF = OP_FVF | (VFWSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VFWADD_W_FUNCT6 = 0b110100,
+ RO_V_VFWADD_W_VV = OP_FVV | (VFWADD_W_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWADD_W_VF = OP_FVF | (VFWADD_W_FUNCT6 << kRvvFunct6Shift),
+
+ VFWSUB_W_FUNCT6 = 0b110110,
+ RO_V_VFWSUB_W_VV = OP_FVV | (VFWSUB_W_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWSUB_W_VF = OP_FVF | (VFWSUB_W_FUNCT6 << kRvvFunct6Shift),
+
+ // Vector Widening Floating-Point Reduction Instructions
+ VFWREDUSUM_FUNCT6 = 0b110001,
+ RO_V_VFWREDUSUM_VV = OP_FVV | (VFWREDUSUM_FUNCT6 << kRvvFunct6Shift),
+
+ VFWREDOSUM_FUNCT6 = 0b110011,
+ RO_V_VFWREDOSUM_VV = OP_FVV | (VFWREDOSUM_FUNCT6 << kRvvFunct6Shift),
+
+ // Vector Widening Floating-Point Multiply
+ VFWMUL_FUNCT6 = 0b111000,
+ RO_V_VFWMUL_VV = OP_FVV | (VFWMUL_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWMUL_VF = OP_FVF | (VFWMUL_FUNCT6 << kRvvFunct6Shift),
+
+ VMFEQ_FUNCT6 = 0b011000,
+ RO_V_VMFEQ_VV = OP_FVV | (VMFEQ_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMFEQ_VF = OP_FVF | (VMFEQ_FUNCT6 << kRvvFunct6Shift),
+
+ VMFNE_FUNCT6 = 0b011100,
+ RO_V_VMFNE_VV = OP_FVV | (VMFNE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMFNE_VF = OP_FVF | (VMFNE_FUNCT6 << kRvvFunct6Shift),
+
+ VMFLT_FUNCT6 = 0b011011,
+ RO_V_VMFLT_VV = OP_FVV | (VMFLT_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMFLT_VF = OP_FVF | (VMFLT_FUNCT6 << kRvvFunct6Shift),
+
+ VMFLE_FUNCT6 = 0b011001,
+ RO_V_VMFLE_VV = OP_FVV | (VMFLE_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VMFLE_VF = OP_FVF | (VMFLE_FUNCT6 << kRvvFunct6Shift),
+
+ VMFGE_FUNCT6 = 0b011111,
+ RO_V_VMFGE_VF = OP_FVF | (VMFGE_FUNCT6 << kRvvFunct6Shift),
+
+ VMFGT_FUNCT6 = 0b011101,
+ RO_V_VMFGT_VF = OP_FVF | (VMFGT_FUNCT6 << kRvvFunct6Shift),
+
+ VFMAX_FUNCT6 = 0b000110,
+ RO_V_VFMAX_VV = OP_FVV | (VFMAX_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMAX_VF = OP_FVF | (VFMAX_FUNCT6 << kRvvFunct6Shift),
+
+ VFREDMAX_FUNCT6 = 0b0001111,
+ RO_V_VFREDMAX_VV = OP_FVV | (VFREDMAX_FUNCT6 << kRvvFunct6Shift),
+
+ VFMIN_FUNCT6 = 0b000100,
+ RO_V_VFMIN_VV = OP_FVV | (VFMIN_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMIN_VF = OP_FVF | (VFMIN_FUNCT6 << kRvvFunct6Shift),
+
+ VFSGNJ_FUNCT6 = 0b001000,
+ RO_V_VFSGNJ_VV = OP_FVV | (VFSGNJ_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFSGNJ_VF = OP_FVF | (VFSGNJ_FUNCT6 << kRvvFunct6Shift),
+
+ VFSGNJN_FUNCT6 = 0b001001,
+ RO_V_VFSGNJN_VV = OP_FVV | (VFSGNJN_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFSGNJN_VF = OP_FVF | (VFSGNJN_FUNCT6 << kRvvFunct6Shift),
+
+ VFSGNJX_FUNCT6 = 0b001010,
+ RO_V_VFSGNJX_VV = OP_FVV | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFSGNJX_VF = OP_FVF | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
+
+ VFMADD_FUNCT6 = 0b101000,
+ RO_V_VFMADD_VV = OP_FVV | (VFMADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMADD_VF = OP_FVF | (VFMADD_FUNCT6 << kRvvFunct6Shift),
+
+ VFNMADD_FUNCT6 = 0b101001,
+ RO_V_VFNMADD_VV = OP_FVV | (VFNMADD_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFNMADD_VF = OP_FVF | (VFNMADD_FUNCT6 << kRvvFunct6Shift),
+
+ VFMSUB_FUNCT6 = 0b101010,
+ RO_V_VFMSUB_VV = OP_FVV | (VFMSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMSUB_VF = OP_FVF | (VFMSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VFNMSUB_FUNCT6 = 0b101011,
+ RO_V_VFNMSUB_VV = OP_FVV | (VFNMSUB_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFNMSUB_VF = OP_FVF | (VFNMSUB_FUNCT6 << kRvvFunct6Shift),
+
+ VFMACC_FUNCT6 = 0b101100,
+ RO_V_VFMACC_VV = OP_FVV | (VFMACC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMACC_VF = OP_FVF | (VFMACC_FUNCT6 << kRvvFunct6Shift),
+
+ VFNMACC_FUNCT6 = 0b101101,
+ RO_V_VFNMACC_VV = OP_FVV | (VFNMACC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFNMACC_VF = OP_FVF | (VFNMACC_FUNCT6 << kRvvFunct6Shift),
+
+ VFMSAC_FUNCT6 = 0b101110,
+ RO_V_VFMSAC_VV = OP_FVV | (VFMSAC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFMSAC_VF = OP_FVF | (VFMSAC_FUNCT6 << kRvvFunct6Shift),
+
+ VFNMSAC_FUNCT6 = 0b101111,
+ RO_V_VFNMSAC_VV = OP_FVV | (VFNMSAC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFNMSAC_VF = OP_FVF | (VFNMSAC_FUNCT6 << kRvvFunct6Shift),
+
+ // Vector Widening Floating-Point Fused Multiply-Add Instructions
+ VFWMACC_FUNCT6 = 0b111100,
+ RO_V_VFWMACC_VV = OP_FVV | (VFWMACC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWMACC_VF = OP_FVF | (VFWMACC_FUNCT6 << kRvvFunct6Shift),
+
+ VFWNMACC_FUNCT6 = 0b111101,
+ RO_V_VFWNMACC_VV = OP_FVV | (VFWNMACC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWNMACC_VF = OP_FVF | (VFWNMACC_FUNCT6 << kRvvFunct6Shift),
+
+ VFWMSAC_FUNCT6 = 0b111110,
+ RO_V_VFWMSAC_VV = OP_FVV | (VFWMSAC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWMSAC_VF = OP_FVF | (VFWMSAC_FUNCT6 << kRvvFunct6Shift),
+
+ VFWNMSAC_FUNCT6 = 0b111111,
+ RO_V_VFWNMSAC_VV = OP_FVV | (VFWNMSAC_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VFWNMSAC_VF = OP_FVF | (VFWNMSAC_FUNCT6 << kRvvFunct6Shift),
+
+ VNCLIP_FUNCT6 = 0b101111,
+ RO_V_VNCLIP_WV = OP_IVV | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VNCLIP_WX = OP_IVX | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VNCLIP_WI = OP_IVI | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
+
+ VNCLIPU_FUNCT6 = 0b101110,
+ RO_V_VNCLIPU_WV = OP_IVV | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VNCLIPU_WX = OP_IVX | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
+ RO_V_VNCLIPU_WI = OP_IVI | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
+};
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_v_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-zicsr.h b/js/src/jit/riscv64/constant/Constant-riscv-zicsr.h
new file mode 100644
index 0000000000..6fecfa3d92
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-zicsr.h
@@ -0,0 +1,30 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_zicsr_h_
+#define jit_riscv64_constant_Constant_riscv64_zicsr_h_
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+// RISCV CSR related bit mask and shift
+const int kFcsrFlagsBits = 5;
+const uint32_t kFcsrFlagsMask = (1 << kFcsrFlagsBits) - 1;
+const int kFcsrFrmBits = 3;
+const int kFcsrFrmShift = kFcsrFlagsBits;
+const uint32_t kFcsrFrmMask = ((1 << kFcsrFrmBits) - 1) << kFcsrFrmShift;
+const int kFcsrBits = kFcsrFlagsBits + kFcsrFrmBits;
+const uint32_t kFcsrMask = kFcsrFlagsMask | kFcsrFrmMask;
+
+enum OpcodeRISCVZICSR : uint32_t {
+ // RV32/RV64 Zicsr Standard Extension
+ RO_CSRRW = SYSTEM | (0b001 << kFunct3Shift),
+ RO_CSRRS = SYSTEM | (0b010 << kFunct3Shift),
+ RO_CSRRC = SYSTEM | (0b011 << kFunct3Shift),
+ RO_CSRRWI = SYSTEM | (0b101 << kFunct3Shift),
+ RO_CSRRSI = SYSTEM | (0b110 << kFunct3Shift),
+ RO_CSRRCI = SYSTEM | (0b111 << kFunct3Shift),
+};
+} // namespace jit
+} // namespace js
+#endif // jit_riscv64_constant_Constant_riscv64_zicsr_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv-zifencei.h b/js/src/jit/riscv64/constant/Constant-riscv-zifencei.h
new file mode 100644
index 0000000000..be01cd0ae0
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv-zifencei.h
@@ -0,0 +1,15 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_Constant_riscv64_zifencei_h_
+#define jit_riscv64_constant_Constant_riscv64_zifencei_h_
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+namespace js {
+namespace jit {
+enum OpcodeRISCVIFENCEI : uint32_t {
+ RO_FENCE_I = MISC_MEM | (0b001 << kFunct3Shift),
+};
+}
+} // namespace js
+#endif // jit_riscv64_constant_Constant_riscv64_zifencei_h_
diff --git a/js/src/jit/riscv64/constant/Constant-riscv64.h b/js/src/jit/riscv64/constant/Constant-riscv64.h
new file mode 100644
index 0000000000..b9b1f894e7
--- /dev/null
+++ b/js/src/jit/riscv64/constant/Constant-riscv64.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef jit_riscv64_constant_Constant_riscv64_h
+#define jit_riscv64_constant_Constant_riscv64_h
+#include "mozilla/Assertions.h"
+#include "mozilla/Types.h"
+
+#include <stdio.h>
+
+#include "jit/riscv64/constant/Base-constant-riscv.h"
+#include "jit/riscv64/constant/Constant-riscv-a.h"
+#include "jit/riscv64/constant/Constant-riscv-c.h"
+#include "jit/riscv64/constant/Constant-riscv-d.h"
+#include "jit/riscv64/constant/Constant-riscv-f.h"
+#include "jit/riscv64/constant/Constant-riscv-i.h"
+#include "jit/riscv64/constant/Constant-riscv-m.h"
+#include "jit/riscv64/constant/Constant-riscv-v.h"
+#include "jit/riscv64/constant/Constant-riscv-zicsr.h"
+#include "jit/riscv64/constant/Constant-riscv-zifencei.h"
+
+namespace js {
+namespace jit {
+
+// A reasonable (ie, safe) buffer size for the disassembly of a single
+// instruction.
+const int ReasonableBufferSize = 256;
+
+// Difference between address of current opcode and value read from pc
+// register.
+static constexpr int kPcLoadDelta = 4;
+
+// Bits available for offset field in branches
+static constexpr int kBranchOffsetBits = 13;
+
+// Bits available for offset field in jump
+static constexpr int kJumpOffsetBits = 21;
+
+// Bits available for offset field in compresed jump
+static constexpr int kCJalOffsetBits = 12;
+
+// Bits available for offset field in 4 branch
+static constexpr int kCBranchOffsetBits = 9;
+
+// Max offset for b instructions with 12-bit offset field (multiple of 2)
+static constexpr int kMaxBranchOffset = (1 << (kBranchOffsetBits - 1)) - 1;
+
+static constexpr int kCBranchOffset = (1 << (kCBranchOffsetBits - 1)) - 1;
+// Max offset for jal instruction with 20-bit offset field (multiple of 2)
+static constexpr int kMaxJumpOffset = (1 << (kJumpOffsetBits - 1)) - 1;
+
+static constexpr int kCJumpOffset = (1 << (kCJalOffsetBits - 1)) - 1;
+
+static constexpr int kTrampolineSlotsSize = 2 * kInstrSize;
+
+static_assert(kCJalOffsetBits == kOffset12);
+static_assert(kCBranchOffsetBits == kOffset9);
+static_assert(kJumpOffsetBits == kOffset21);
+static_assert(kBranchOffsetBits == kOffset13);
+// Vector as used by the original code to allow for minimal modification.
+// Functions exactly like a character array with helper methods.
+} // namespace jit
+} // namespace js
+
+#endif // jit_riscv64_constant_Constant_riscv64_h
diff --git a/js/src/jit/riscv64/constant/util-riscv64.h b/js/src/jit/riscv64/constant/util-riscv64.h
new file mode 100644
index 0000000000..089e0f3b94
--- /dev/null
+++ b/js/src/jit/riscv64/constant/util-riscv64.h
@@ -0,0 +1,82 @@
+
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#ifndef jit_riscv64_constant_util_riscv64__h_
+#define jit_riscv64_constant_util_riscv64__h_
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+namespace js {
+namespace jit {
+template <typename T>
+class V8Vector {
+ public:
+ V8Vector() : start_(nullptr), length_(0) {}
+ V8Vector(T* data, int length) : start_(data), length_(length) {
+ MOZ_ASSERT(length == 0 || (length > 0 && data != nullptr));
+ }
+
+ // Returns the length of the vector.
+ int length() const { return length_; }
+
+ // Returns the pointer to the start of the data in the vector.
+ T* start() const { return start_; }
+
+ // Access individual vector elements - checks bounds in debug mode.
+ T& operator[](int index) const {
+ MOZ_ASSERT(0 <= index && index < length_);
+ return start_[index];
+ }
+
+ inline V8Vector<T> operator+(int offset) {
+ MOZ_ASSERT(offset < length_);
+ return V8Vector<T>(start_ + offset, length_ - offset);
+ }
+
+ private:
+ T* start_;
+ int length_;
+};
+
+template <typename T, int kSize>
+class EmbeddedVector : public V8Vector<T> {
+ public:
+ EmbeddedVector() : V8Vector<T>(buffer_, kSize) {}
+
+ explicit EmbeddedVector(T initial_value) : V8Vector<T>(buffer_, kSize) {
+ for (int i = 0; i < kSize; ++i) {
+ buffer_[i] = initial_value;
+ }
+ }
+
+ // When copying, make underlying Vector to reference our buffer.
+ EmbeddedVector(const EmbeddedVector& rhs) : V8Vector<T>(rhs) {
+ MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ this->set_start(buffer_);
+ }
+
+ EmbeddedVector& operator=(const EmbeddedVector& rhs) {
+ if (this == &rhs) return *this;
+ V8Vector<T>::operator=(rhs);
+ MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ this->set_start(buffer_);
+ return *this;
+ }
+
+ private:
+ T buffer_[kSize];
+};
+
+// Helper function for printing to a Vector.
+static inline int MOZ_FORMAT_PRINTF(2, 3)
+ SNPrintF(V8Vector<char> str, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ int result = vsnprintf(str.start(), str.length(), format, args);
+ va_end(args);
+ return result;
+}
+} // namespace jit
+} // namespace js
+#endif