Browse Source

Added Firefox 105.0 source and patches

Clement 1 year ago
parent
commit
49ec4f1a6d

+ 34 - 0
firefox/README.md

@@ -0,0 +1,34 @@
+Firefox RISC-V Build Guide
+
+1. Download Rust 1.63
+
+    $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+    $ rustup default 1.63.0
+
+(1.64.0 rust currently have some problems with riscv64)
+
+2. Download the dependencies needed for build:
+    $ apt-get install libnspr4 libgtk-3-dev
+
+3. You can either use the source code or git clone:
+    $ cd firefox
+
+    OR
+
+    $ git clone https://salsa.debian.org/mozilla-team/firefox.git -b debian/105.0-1 --depth=1
+
+
+4. Apply the following patches:
+
+    $ patch -Np1 -i 0001-Bug-1786638-Return-early-if-we-can-t-fetch-an-intern.patch
+    $ patch -Np1 -i firefox-riscv64-hack.patch
+    $ patch -Np1 -i makotokato-riscv64-support-and-zenithal-backported.patch
+
+5. Move the mozconfig file into the base directory of the source code:
+
+6. Build firefox by running:
+
+    $ ./mach vendor rust --ignore-modified
+    $ ./mach build
+
+7. The output binaries and libraries can be found in ./obj-riscv64-unknown-linux-gnu/dist/bin/

+ 1 - 0
firefox/firefox

@@ -0,0 +1 @@
+Subproject commit 69f82f5ccff0469c982e6524789af7e7581f91bf

+ 37 - 0
firefox/mozconfig

@@ -0,0 +1,37 @@
+# Please don't use this mozconfig unless you are planning to build
+# packages for Debian or a derivative.
+ac_add_options --with-app-name=firefox
+ac_add_options --disable-release
+ 
+#added extra
+ac_add_options --enable-hardening
+ac_add_options --enable-rust-simd
+ac_add_options --enable-linker=bfd
+ac_add_options --disable-bootstrap
+ 
+# Branding
+ac_add_options --enable-official-branding
+ac_add_options --with-branding=browser/branding/official
+ac_add_options --enable-update-channel=release
+ac_add_options --with-unsigned-addon-scopes=app,system
+ac_add_options --allow-addon-sideload
+ 
+#ac_add_options --enable-default-toolkit=cairo-gtk3-wayland
+ac_add_options --with-google-location-service-api-keyfile=$topsrcdir/debian/google.key
+ac_add_options --with-google-safebrowsing-api-keyfile=$topsrcdir/debian/google.key
+ac_add_options --with-mozilla-api-keyfile=$topsrcdir/debian/mls.key
+ 
+ac_add_options --with-system-zlib # MOZ_SYSTEM_ZLIB=1
+ac_add_options --disable-strip
+ac_add_options --disable-install-strip
+ac_add_options --enable-system-ffi # MOZ_SYSTEM_FFI=1
+ac_add_options --with-system-libevent # MOZ_SYSTEM_LIBEVENT=1
+ac_add_options --with-system-nspr # MOZ_SYSTEM_NSPR=1
+#ac_add_options --with-system-nss # MOZ_SYSTEM_NSS=1
+ 
+ac_add_options --disable-updater
+ac_add_options --disable-tests
+ac_add_options --with-unsigned-addon-scopes=app,system
+ac_add_options --allow-addon-sideload
+ac_add_options --enable-alsa
+ac_add_options --without-wasm-sandboxed-libraries

+ 26 - 0
firefox/patch/0001-Bug-1786638-Return-early-if-we-can-t-fetch-an-intern.patch

@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Morgan Rae Reschenberg <mreschenberg@mozilla.com>
+Date: Wed, 24 Aug 2022 04:44:38 +0000
+Subject: [PATCH] Bug 1786638: Return early if we can't fetch an internal obj
+ when computing ATK relations r=Jamie
+
+Differential Revision: https://phabricator.services.mozilla.com/D155426
+---
+ accessible/atk/AccessibleWrap.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/accessible/atk/AccessibleWrap.cpp b/accessible/atk/AccessibleWrap.cpp
+index 85281ba2cc20..2bdb40ddcb15 100644
+--- a/accessible/atk/AccessibleWrap.cpp
++++ b/accessible/atk/AccessibleWrap.cpp
+@@ -836,6 +836,10 @@ AtkRelationSet* refRelationSetCB(AtkObject* aAtkObj) {
+       ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
+ 
+   Accessible* acc = GetInternalObj(aAtkObj);
++  if (!acc) {
++    return relation_set;
++  }
++
+   if (!StaticPrefs::accessibility_cache_enabled_AtStartup() &&
+       acc->IsRemote()) {
+     RemoteAccessible* proxy = acc->AsRemote();

+ 102 - 0
firefox/patch/firefox-riscv64-hack.patch

@@ -0,0 +1,102 @@
+Temporary hack to allow us to directly apply diff of matoko's branch.  Disable
+rust-vet to skip auditing third party libs in order to download/vendor rust
+deps on non-git firefox src.  Skip some style checks, as
+macroassembler support in js/src/jit/ is not complete yet
+
+diff --git a/python/mozbuild/mozbuild/vendor/vendor_rust.py b/python/mozbuild/mozbuild/vendor/vendor_rust.py
+index 7394ccaf40..491bd7fbdb 100644
+--- a/python/mozbuild/mozbuild/vendor/vendor_rust.py
++++ b/python/mozbuild/mozbuild/vendor/vendor_rust.py
+@@ -740,38 +740,40 @@ license file's hash.
+                     failed = True
+ 
+         # Only emit warnings for cargo-vet for now.
+-        env = os.environ.copy()
+-        env["PATH"] = os.pathsep.join(
+-            (
+-                str(Path(cargo).parent),
+-                os.environ["PATH"],
+-            )
+-        )
+-        flags = ["--output-format=json"]
+-        if "MOZ_AUTOMATION" in os.environ:
+-            flags.append("--locked")
+-            flags.append("--frozen")
+-        res = cargo_vet(
+-            self,
+-            flags,
+-            stdout=subprocess.PIPE,
+-            env=env,
+-        )
+-        if res.returncode:
+-            vet = json.loads(res.stdout)
+-            for failure in vet.get("failures", []):
+-                failure["crate"] = failure.pop("name")
+-                self.log(
+-                    logging.ERROR,
+-                    "cargo_vet_failed",
+-                    failure,
+-                    "Missing audit for {crate}:{version} (requires {missing_criteria})."
+-                    " Run `./mach cargo vet` for more information.",
+-                )
+-                failed = True
+-
+-        if failed:
+-            return False
++        #env = os.environ.copy()
++        #env["PATH"] = os.pathsep.join(
++        #    (
++        #        str(Path(cargo).parent),
++        #        os.environ["PATH"],
++        #    )
++        #)
++        #print(env["PATH"])
++        #print(self.topsrcdir)
++        #flags = ["--output-format=json"]
++        #if "MOZ_AUTOMATION" in os.environ:
++        #    flags.append("--locked")
++        #    flags.append("--frozen")
++        #res = cargo_vet(
++        #    self,
++        #    flags,
++        #    stdout=subprocess.PIPE,
++        #    env=env,
++        #)
++        #if res.returncode:
++        #    vet = json.loads(res.stdout)
++        #    for failure in vet.get("failures", []):
++        #        failure["crate"] = failure.pop("name")
++        #        self.log(
++        #            logging.ERROR,
++        #            "cargo_vet_failed",
++        #            failure,
++        #            "Missing audit for {crate}:{version} (requires {missing_criteria})."
++        #            " Run `./mach cargo vet` for more information.",
++        #        )
++        #        failed = True
++
++        #if failed:
++        #    return False
+ 
+         res = subprocess.run(
+             [cargo, "vendor", vendor_dir], cwd=self.topsrcdir, stdout=subprocess.PIPE
+@@ -848,6 +848,7 @@ license file's hash.
+                     directory=replace["directory"],
+                 )
+             )
++        return True
+ 
+         if not self._check_licenses(vendor_dir):
+             self.log(
+diff --git a/js/src/build/moz.build b/js/src/build/moz.build
+index 4c48a5c4ff..e68d79447e 100644
+--- a/js/src/build/moz.build
++++ b/js/src/build/moz.build
+@@ -101,7 +101,5 @@ GeneratedFile(
+     inputs=[
+         "!%sjs_static.%s" % (CONFIG["LIB_PREFIX"], CONFIG["LIB_SUFFIX"]),
+-        "/config/check_spidermonkey_style.py",
+-        "/config/check_macroassembler_style.py",
+         "/config/check_js_opcode.py",
+     ],
+ )

+ 4079 - 0
firefox/patch/makotokato-riscv64-support-and-zenithal-backported.patch

@@ -0,0 +1,4079 @@
+diff --unified --recursive --text a/.cargo/config.in b/.cargo/config.in
+--- a/.cargo/config.in
++++ b/.cargo/config.in
+@@ -22,11 +22,6 @@
+ replace-with = "vendored-sources"
+ rev = "3bfc47d9a571d0842676043ba60716318e946c06"
+ 
+-[source."https://github.com/mozilla/midir.git"]
+-git = "https://github.com/mozilla/midir.git"
+-replace-with = "vendored-sources"
+-rev = "e1b4dcb767f9e69afe95a860374aaa9635d81e3d"
+-
+ [source."https://github.com/mozilla/cubeb-pulse-rs"]
+ git = "https://github.com/mozilla/cubeb-pulse-rs"
+ replace-with = "vendored-sources"
+@@ -37,6 +32,11 @@
+ replace-with = "vendored-sources"
+ rev = "44eca95823bb57e964cf7b6d9791ed2ccb4b2108"
+ 
++[source."https://github.com/mozilla/authenticator-rs"]
++git = "https://github.com/mozilla/authenticator-rs"
++replace-with = "vendored-sources"
++rev = "b85bccf0527e42c877573029e8d35ff13ef06f9d"
++
+ [source."https://github.com/mozilla/audioipc"]
+ git = "https://github.com/mozilla/audioipc"
+ replace-with = "vendored-sources"
+
+From a418c651c88cd2682c4cfe61e9f57b5389078c09 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Thu, 17 Jun 2021 21:50:49 +0900
+Subject: [PATCH] signal handler
+
+---
+ js/src/wasm/WasmSignalHandlers.cpp | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+--- a/js/src/wasm/WasmSignalHandlers.cpp        2022-02-12 19:29:33.566924464 +0800
++++ b/js/src/wasm/WasmSignalHandlers.cpp        2022-02-12 19:50:29.499985612 +0800
+@@ -163,6 +163,11 @@
+ #      define R01_sig(p) ((p)->uc_mcontext.gp_regs[1])
+ #      define R32_sig(p) ((p)->uc_mcontext.gp_regs[32])
+ #    endif
++#  if defined(__linux__) && defined(__riscv) && __riscv_xlen == 64
++#    define EPC_sig(p) ((p)->uc_mcontext.__gregs[0])
++#    define X02_sig(p) ((p)->uc_mcontext.__gregs[2])
++#    define X08_sig(p) ((p)->uc_mcontext.__gregs[8])
++#  endif
+ #  elif defined(__NetBSD__)
+ #    define EIP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EIP])
+ #    define EBP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EBP])
+@@ -405,6 +410,10 @@
+ #    define FP_sig(p) RFP_sig(p)
+ #    define SP_sig(p) RSP_sig(p)
+ #    define LR_sig(p) RRA_sig(p)
++#elif defined(__riscv) && __riscv_xlen == 64
++#  define PC_sig(p) EPC_sig(p)
++#  define SP_sig(p) X02_sig(p)
++#  define FP_sig(p) X08_sig(p)
+ #  endif
+
+ static void SetContextPC(CONTEXT* context, uint8_t* pc) {
+
+diff --git a/Cargo.lock b/Cargo.lock
+index edc5ef5ff2d98..f6240163e1440 100644
+--- a/Cargo.lock	2022-08-29 14:41:23.089464305 +0800
++++ b/Cargo.lock	2022-08-29 14:48:22.707351349 +0800
+@@ -30,14 +30,14 @@
+ 
+ [[package]]
+ name = "alsa"
+-version = "0.4.3"
++version = "0.6.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "eb213f6b3e4b1480a60931ca2035794aa67b73103d254715b1db7b70dcb3c934"
++checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b"
+ dependencies = [
+  "alsa-sys",
+  "bitflags",
+  "libc",
+- "nix",
++ "nix 0.23.1",
+ ]
+ 
+ [[package]]
+@@ -368,9 +368,8 @@
+
+ [[package]]
+ name = "authenticator"
+-version = "0.3.1"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "08cee7a0952628fde958e149507c2bb321ab4fccfafd225da0b20adc956ef88a"
++version = "0.3.2"
++source = "git+https://github.com/mozilla/authenticator-rs?rev=b85bccf0527e42c877573029e8d35ff13ef06f9d#b85bccf0527e42c877573029e8d35ff13ef06f9d"
+ dependencies = [
+  "bitflags",
+  "core-foundation",
+@@ -378,7 +377,7 @@
+  "libc",
+  "libudev",
+  "log",
+- "rand 0.7.999",
++ "rand 0.8.5",
+  "runloop",
+  "winapi",
+ ]
+@@ -2220,6 +2219,7 @@
+  "log",
+  "mapped_hyph",
+  "mdns_service",
++ "midir",
+  "midir_impl",
+  "mio 0.8.0",
+  "moz_asserts",
+@@ -3290,8 +3290,9 @@
+ 
+ [[package]]
+ name = "midir"
+-version = "0.7.0"
+-source = "git+https://github.com/mozilla/midir.git?rev=e1b4dcb767f9e69afe95a860374aaa9635d81e3d#e1b4dcb767f9e69afe95a860374aaa9635d81e3d"
++version = "0.8.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2c1c68e2b589cce71b14a10d7d1599a845673f9decde80fa9e8500fdccd50dca"
+ dependencies = [
+  "alsa",
+  "bitflags",
+@@ -3299,10 +3300,9 @@
+  "js-sys",
+  "libc",
+  "memalloc",
+- "nix",
+  "wasm-bindgen",
+  "web-sys",
+- "winapi",
++ "windows",
+ ]
+
+ [[package]]
+@@ -3341,7 +3341,7 @@
+  "libc",
+  "memmap2 0.2.999",
+  "memoffset 0.5.6",
+- "nix",
++ "nix 0.15.0",
+  "tempfile",
+  "thiserror",
+ ]
+@@ -3752,6 +3752,19 @@
+ ]
+
+ [[package]]
++name = "nix"
++version = "0.23.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
++dependencies = [
++ "bitflags",
++ "cc",
++ "cfg-if 1.0.0",
++ "libc",
++ "memoffset 0.6.5",
++]
++
++[[package]]
+ name = "nom"
+ version = "6.1.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+@@ -6238,6 +6251,49 @@
+ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+ [[package]]
++name = "windows"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
++dependencies = [
++ "windows_aarch64_msvc",
++ "windows_i686_gnu",
++ "windows_i686_msvc",
++ "windows_x86_64_gnu",
++ "windows_x86_64_msvc",
++]
++
++[[package]]
++name = "windows_aarch64_msvc"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
++
++[[package]]
++name = "windows_i686_gnu"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
++
++[[package]]
++name = "windows_i686_msvc"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
++
++[[package]]
++name = "windows_x86_64_gnu"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
++
++[[package]]
++name = "windows_x86_64_msvc"
++version = "0.32.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
++
++[[package]]
+ name = "wineventlog"
+ version = "0.1.0"
+ dependencies = [
+
+diff --git a/Cargo.toml b/Cargo.toml
+index 1c2437f1f5675..2923c7e5ea9bf 100644
+--- a/Cargo.toml        2022-05-31 11:15:47.681941501 +0800
++++ b/Cargo.toml        2022-05-31 11:26:35.076132533 +0800
+@@ -149,7 +149,6 @@
+ fog = { path = "toolkit/components/glean/api" }
+ libudev-sys = { path = "dom/webauthn/libudev-sys" }
+ packed_simd = { package = "packed_simd_2", git = "https://github.com/hsivonen/packed_simd", rev="412f9a0aa556611de021bde89dee8fefe6e0fbbd" }
+-midir = { git = "https://github.com/mozilla/midir.git", rev = "e1b4dcb767f9e69afe95a860374aaa9635d81e3d" }
+ minidump_writer_linux = { git = "https://github.com/rust-minidump/minidump-writer.git", rev = "75ada456c92a429704691a85e1cb42fef8cafc0d" }
+
+ # application-services overrides to make updating them all simpler.
+
+diff --git a/python/mozbuild/mozbuild/vendor/vendor_rust.py b/python/mozbuild/mozbuild/vendor/vendor_rust.py
+index 31baea4290..7394ccaf40 100644
+--- a/python/mozbuild/mozbuild/vendor/vendor_rust.py
++++ b/python/mozbuild/mozbuild/vendor/vendor_rust.py
+@@ -98,6 +98,7 @@ TOLERATED_DUPES = {
+     "libloading": 2,
+     "memoffset": 2,
+     "mio": 2,
++    "nix": 2,
+     # Transition from time 0.1 to 0.3 underway, but chrono is stuck on 0.1
+     # and hasn't been updated in 1.5 years (an hypothetical update is
+     # expected to remove the dependency on time altogether).
+--- a/dom/midi/midir_impl/Cargo.toml	2022-08-30 01:32:46.905420566 +0800
++++ b/dom/midi/midir_impl/Cargo.toml	2022-08-30 01:33:08.125466847 +0800
+@@ -7,7 +7,7 @@
+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+ 
+ [dependencies]
+-midir = "0.7.0"
++midir = "0.8.0"
+ nsstring = { path = "../../../xpcom/rust/nsstring/" }
+ uuid = { version = "0.8", features = ["v4"] }
+ thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
+--- a/toolkit/library/rust/shared/Cargo.toml	2022-08-30 01:32:51.372097505 +0800
++++ b/toolkit/library/rust/shared/Cargo.toml	2022-08-30 01:33:57.192217018 +0800
+@@ -39,7 +39,7 @@
+ # audioipc2-client and audioipc2-server.
+ tokio-threadpool = { version = "=0.1.17", optional = true }
+ encoding_glue = { path = "../../../../intl/encoding_glue" }
+-authenticator = "0.3.1"
++authenticator = { git = "https://github.com/mozilla/authenticator-rs", rev = "b85bccf0527e42c877573029e8d35ff13ef06f9d" }
+ gkrust_utils = { path = "../../../../xpcom/rust/gkrust_utils" }
+ gecko_logger = { path = "../../../../xpcom/rust/gecko_logger" }
+ rsdparsa_capi = { path = "../../../../dom/media/webrtc/sdp/rsdparsa_capi" }
+@@ -75,6 +75,7 @@
+ jog = { path = "../../../components/glean/bindings/jog" }
+ dap_ffi = { path = "../../../components/telemetry/dap/ffi" }
+ data-encoding-ffi = { path = "../../../../dom/fs/parent/rust/data-encoding-ffi" }
++midir = { version = "0.8.0" }
+ uniffi-example-arithmetic = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bb2039f077a29dba0879372a67e764e6ace8e33f", optional = true }
+ uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bb2039f077a29dba0879372a67e764e6ace8e33f", optional = true }
+ uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "bb2039f077a29dba0879372a67e764e6ace8e33f", optional = true }
+
+ # Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
+ # version less than or equal to what we link to. This isn't a problem because we
+
+From 0475f4a69df2437d4809ae7419b221f54b554f71 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Wed, 16 Feb 2022 23:41:23 +0900
+Subject: [PATCH] Add JIT skelton
+
+---
+ js/moz.configure                              |   2 +
+ js/src/jit/Assembler.h                        |   2 +
+ js/src/jit/CodeGenerator.h                    |   2 +
+ js/src/jit/LIR.h                              |   2 +
+ js/src/jit/Lowering.h                         |   2 +
+ js/src/jit/MacroAssembler.h                   |   2 +
+ js/src/jit/MoveEmitter.h                      |   2 +
+ js/src/jit/Registers.h                        |   2 +
+ js/src/jit/SharedICHelpers-inl.h              |   2 +
+ js/src/jit/SharedICHelpers.h                  |   2 +
+ js/src/jit/SharedICRegisters.h                |   2 +
+ js/src/jit/moz.build                          |   2 +
+ js/src/jit/riscv64/Architecture-riscv64.h     | 171 +++++++
+ js/src/jit/riscv64/Assembler-riscv64.h        | 200 ++++++++
+ js/src/jit/riscv64/CodeGenerator-riscv64.h    |  78 +++
+ js/src/jit/riscv64/LIR-riscv64.h              | 111 +++++
+ js/src/jit/riscv64/Lowering-riscv64.h         | 130 +++++
+ js/src/jit/riscv64/MacroAssembler-riscv64.h   | 458 ++++++++++++++++++
+ js/src/jit/riscv64/MoveEmitter-riscv64.h      |  32 ++
+ .../jit/riscv64/SharedICHelpers-riscv64-inl.h |  34 ++
+ js/src/jit/riscv64/SharedICHelpers-riscv64.h  |  32 ++
+ .../jit/riscv64/SharedICRegisters-riscv64.h   |  38 ++
+ js/src/jit/riscv64/Trampoline-riscv64.cpp     |  67 +++
+ 23 files changed, 1375 insertions(+)
+ create mode 100644 js/src/jit/riscv64/Architecture-riscv64.h
+ create mode 100644 js/src/jit/riscv64/Assembler-riscv64.h
+ create mode 100644 js/src/jit/riscv64/CodeGenerator-riscv64.h
+ create mode 100644 js/src/jit/riscv64/LIR-riscv64.h
+ create mode 100644 js/src/jit/riscv64/Lowering-riscv64.h
+ create mode 100644 js/src/jit/riscv64/MacroAssembler-riscv64.h
+ create mode 100644 js/src/jit/riscv64/MoveEmitter-riscv64.h
+ create mode 100644 js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h
+ create mode 100644 js/src/jit/riscv64/SharedICHelpers-riscv64.h
+ create mode 100644 js/src/jit/riscv64/SharedICRegisters-riscv64.h
+ create mode 100644 js/src/jit/riscv64/Trampoline-riscv64.cpp
+
+diff --git a/js/moz.configure b/js/moz.configure
+index 0213f0b4b2718..42184e9358f38 100644
+--- a/js/moz.configure	2022-09-19 14:47:19.124047241 +0800
++++ b/js/moz.configure	2022-09-19 15:03:42.545608473 +0800
+@@ -262,6 +262,7 @@
+ set_config("JS_CODEGEN_MIPS32", jit_codegen.mips32)
+ set_config("JS_CODEGEN_MIPS64", jit_codegen.mips64)
+ set_config("JS_CODEGEN_LOONG64", jit_codegen.loong64)
++set_config("JS_CODEGEN_RISCV64", jit_codegen.riscv64)
+ set_config("JS_CODEGEN_X86", jit_codegen.x86)
+ set_config("JS_CODEGEN_X64", jit_codegen.x64)
+ set_config("JS_CODEGEN_WASM32", jit_codegen.wasm32)
+@@ -271,6 +272,7 @@
+ set_define("JS_CODEGEN_MIPS32", jit_codegen.mips32)
+ set_define("JS_CODEGEN_MIPS64", jit_codegen.mips64)
+ set_define("JS_CODEGEN_LOONG64", jit_codegen.loong64)
++set_define("JS_CODEGEN_RISCV64", jit_codegen.riscv64)
+ set_define("JS_CODEGEN_X86", jit_codegen.x86)
+ set_define("JS_CODEGEN_X64", jit_codegen.x64)
+ set_define("JS_CODEGEN_WASM32", jit_codegen.wasm32)
+
+diff --git a/js/src/jit/Assembler.h b/js/src/jit/Assembler.h
+index 5f80e658f923e..65c0eb48bd393 100644
+--- a/js/src/jit/Assembler.h
++++ b/js/src/jit/Assembler.h
+@@ -21,6 +21,8 @@
+ #  include "jit/mips64/Assembler-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/Assembler-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/Assembler-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/Assembler-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
+index a1c58acd0a174..8338f5fc1f95d 100644
+--- a/js/src/jit/CodeGenerator.h
++++ b/js/src/jit/CodeGenerator.h
+@@ -26,6 +26,8 @@
+ #  include "jit/mips64/CodeGenerator-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/CodeGenerator-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/CodeGenerator-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/CodeGenerator-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h
+index c7946d6bef4ae..33baec8cb685f 100644
+--- a/js/src/jit/LIR.h
++++ b/js/src/jit/LIR.h
+@@ -1933,6 +1933,8 @@
+ #    include "jit/mips64/LIR-mips64.h"
+ #  endif
+ #  include "jit/mips-shared/LIR-mips-shared.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/LIR-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/LIR-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
+index 079f57d97db06..a13805e648d87 100644
+--- a/js/src/jit/Lowering.h
++++ b/js/src/jit/Lowering.h
+@@ -25,6 +25,8 @@
+ #  include "jit/mips64/Lowering-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/Lowering-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/Lowering-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/Lowering-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
+index d6953919a8c19..b7f1947430eae 100644
+--- a/js/src/jit/MacroAssembler.h
++++ b/js/src/jit/MacroAssembler.h
+@@ -27,6 +27,8 @@
+ #  include "jit/mips64/MacroAssembler-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/MacroAssembler-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/MacroAssembler-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/MacroAssembler-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/MoveEmitter.h b/js/src/jit/MoveEmitter.h
+index 6c62c0561a5b1..256ec8a15ac2b 100644
+--- a/js/src/jit/MoveEmitter.h
++++ b/js/src/jit/MoveEmitter.h
+@@ -19,6 +19,8 @@
+ #  include "jit/mips64/MoveEmitter-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/MoveEmitter-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/MoveEmitter-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/MoveEmitter-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/Registers.h b/js/src/jit/Registers.h
+index 67c8661004d4e..70b73ecb556b0 100644
+--- a/js/src/jit/Registers.h
++++ b/js/src/jit/Registers.h
+@@ -22,6 +22,8 @@
+ #  include "jit/mips64/Architecture-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/Architecture-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/Architecture-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/Architecture-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/SharedICHelpers-inl.h b/js/src/jit/SharedICHelpers-inl.h
+index 901c80cdd8591..d62c17bc2a9d4 100644
+--- a/js/src/jit/SharedICHelpers-inl.h
++++ b/js/src/jit/SharedICHelpers-inl.h
+@@ -20,6 +20,8 @@
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/SharedICHelpers-loong64-inl.h"
+ #elif defined(JS_CODEGEN_WASM32)
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/SharedICHelpers-riscv64-inl.h"
+ #  include "jit/wasm32/SharedICHelpers-wasm32-inl.h"
+ #elif defined(JS_CODEGEN_NONE)
+ #  include "jit/none/SharedICHelpers-none-inl.h"
+diff --git a/js/src/jit/SharedICHelpers.h b/js/src/jit/SharedICHelpers.h
+index 563cae3ccfe4e..0d95439a10d96 100644
+--- a/js/src/jit/SharedICHelpers.h
++++ b/js/src/jit/SharedICHelpers.h
+@@ -19,6 +19,8 @@
+ #  include "jit/mips-shared/SharedICHelpers-mips-shared.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/SharedICHelpers-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/SharedICHelpers-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/SharedICHelpers-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/SharedICRegisters.h b/js/src/jit/SharedICRegisters.h
+index c87e5f8408959..aee2f54602285 100644
+--- a/js/src/jit/SharedICRegisters.h
++++ b/js/src/jit/SharedICRegisters.h
+@@ -21,6 +21,8 @@
+ #  include "jit/mips64/SharedICRegisters-mips64.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/SharedICRegisters-loong64.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/SharedICRegisters-riscv64.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/SharedICRegisters-wasm32.h"
+ #elif defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/moz.build b/js/src/jit/moz.build
+index 60f6a4674ab92..ebb8f18b50d26 100644
+--- a/js/src/jit/moz.build
++++ b/js/src/jit/moz.build
+@@ -212,6 +212,13 @@
+         ]
+         if CONFIG["JS_SIMULATOR_MIPS64"]:
+             UNIFIED_SOURCES += ["mips64/Simulator-mips64.cpp"]
++elif CONFIG["JS_CODEGEN_RISCV64"]:
++    UNIFIED_SOURCES += [
++        "riscv64/Assembler-riscv64.cpp",
++        "riscv64/Trampoline-riscv64.cpp",
++    ]
++    if CONFIG["JS_SIMULATOR_RISC64"]:
++        UNIFIED_SOURCES += ["riscv64/Simulator-riscv64.cpp"]
+ elif CONFIG["JS_CODEGEN_LOONG64"]:
+     UNIFIED_SOURCES += [
+         "loong64/Architecture-loong64.cpp",
+
+diff --git a/js/src/jit/riscv64/Architecture-riscv64.h b/js/src/jit/riscv64/Architecture-riscv64.h
+new file mode 100644
+index 0000000000000..3a4a25205bcd1
+--- /dev/null
++++ b/js/src/jit/riscv64/Architecture-riscv64.h
+@@ -0,0 +1,171 @@
++/* -*- 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_Architecture_riscv64_h
++#define jit_riscv64_Architecture_riscv64_h
++
++// JitSpewer.h is included through MacroAssembler implementations for other
++// platforms, so include it here to avoid inadvertent build bustage.
++#include "jit/JitSpewer.h"
++
++#include "jit/shared/Architecture-shared.h"
++
++namespace js {
++namespace jit {
++
++static const uint32_t SimdMemoryAlignment =
++    4;  // Make it 4 to avoid a bunch of div-by-zero warnings
++static const uint32_t WasmStackAlignment = 8;
++static const uint32_t WasmTrapInstructionLength = 0;
++
++// See comments in wasm::GenerateFunctionPrologue.
++static constexpr uint32_t WasmCheckedCallEntryOffset = 0u;
++static constexpr uint32_t WasmCheckedTailEntryOffset = 1u;
++
++class Registers {
++ public:
++  enum RegisterID {
++    r0 = 0,
++    invalid_reg,
++    invalid_reg2,  // To avoid silly static_assert failures.
++  };
++  typedef uint8_t Code;
++  typedef RegisterID Encoding;
++  union RegisterContent {
++    uintptr_t r;
++  };
++
++  typedef uint8_t SetType;
++
++  static uint32_t SetSize(SetType) { MOZ_CRASH(); }
++  static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
++  static uint32_t LastBit(SetType) { MOZ_CRASH(); }
++  static const char* GetName(Code) { MOZ_CRASH(); }
++  static Code FromName(const char*) { MOZ_CRASH(); }
++
++  static const Encoding StackPointer = invalid_reg;
++  static const Encoding Invalid = invalid_reg;
++  static const uint32_t Total = 1;
++  static const uint32_t TotalPhys = 0;
++  static const uint32_t Allocatable = 0;
++  static const SetType AllMask = 0;
++  static const SetType ArgRegMask = 0;
++  static const SetType VolatileMask = 0;
++  static const SetType NonVolatileMask = 0;
++  static const SetType NonAllocatableMask = 0;
++  static const SetType AllocatableMask = 0;
++  static const SetType JSCallMask = 0;
++  static const SetType CallMask = 0;
++};
++
++typedef uint8_t PackedRegisterMask;
++
++class FloatRegisters {
++ public:
++  enum FPRegisterID { f0 = 0, invalid_reg };
++  typedef FPRegisterID Code;
++  typedef FPRegisterID Encoding;
++  union RegisterContent {
++    double d;
++  };
++
++  typedef uint32_t SetType;
++
++  static const char* GetName(Code) { MOZ_CRASH(); }
++  static Code FromName(const char*) { MOZ_CRASH(); }
++
++  static const Code Invalid = invalid_reg;
++  static const uint32_t Total = 0;
++  static const uint32_t TotalPhys = 0;
++  static const uint32_t Allocatable = 0;
++  static const SetType AllMask = 0;
++  static const SetType AllDoubleMask = 0;
++  static const SetType AllSingleMask = 0;
++  static const SetType VolatileMask = 0;
++  static const SetType NonVolatileMask = 0;
++  static const SetType NonAllocatableMask = 0;
++  static const SetType AllocatableMask = 0;
++};
++
++template <typename T>
++class TypedRegisterSet;
++
++struct FloatRegister {
++  typedef FloatRegisters Codes;
++  typedef Codes::Code Code;
++  typedef Codes::Encoding Encoding;
++  typedef Codes::SetType SetType;
++
++  Code _;
++
++  static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
++  static uint32_t LastBit(SetType) { MOZ_CRASH(); }
++  static FloatRegister FromCode(uint32_t) { MOZ_CRASH(); }
++  bool isSingle() const { MOZ_CRASH(); }
++  bool isDouble() const { MOZ_CRASH(); }
++  bool isSimd128() const { MOZ_CRASH(); }
++  bool isInvalid() const { MOZ_CRASH(); }
++  FloatRegister asSingle() const { MOZ_CRASH(); }
++  FloatRegister asDouble() const { MOZ_CRASH(); }
++  FloatRegister asSimd128() const { MOZ_CRASH(); }
++  Code code() const { MOZ_CRASH(); }
++  Encoding encoding() const { MOZ_CRASH(); }
++  const char* name() const { MOZ_CRASH(); }
++  bool volatile_() const { MOZ_CRASH(); }
++  bool operator!=(FloatRegister) const { MOZ_CRASH(); }
++  bool operator==(FloatRegister) const { MOZ_CRASH(); }
++  bool aliases(FloatRegister) const { MOZ_CRASH(); }
++  uint32_t numAliased() const { MOZ_CRASH(); }
++  FloatRegister aliased(uint32_t) { MOZ_CRASH(); }
++  bool equiv(FloatRegister) const { MOZ_CRASH(); }
++  uint32_t size() const { MOZ_CRASH(); }
++  uint32_t numAlignedAliased() const { MOZ_CRASH(); }
++  FloatRegister alignedAliased(uint32_t) { MOZ_CRASH(); }
++  SetType alignedOrDominatedAliasedSet() const { MOZ_CRASH(); }
++
++  static constexpr RegTypeName DefaultType = RegTypeName::Float64;
++
++  template <RegTypeName = DefaultType>
++  static SetType LiveAsIndexableSet(SetType s) {
++    return SetType(0);
++  }
++
++  template <RegTypeName Name = DefaultType>
++  static SetType AllocatableAsIndexableSet(SetType s) {
++    static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
++    return SetType(0);
++  }
++
++  template <typename T>
++  static T ReduceSetForPush(T) {
++    MOZ_CRASH();
++  }
++  uint32_t getRegisterDumpOffsetInBytes() { MOZ_CRASH(); }
++  static uint32_t SetSize(SetType x) { MOZ_CRASH(); }
++  static Code FromName(const char* name) { MOZ_CRASH(); }
++
++  // This is used in static initializers, so produce a bogus value instead of
++  // crashing.
++  static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister>&) {
++    return 0;
++  }
++};
++
++inline bool hasUnaliasedDouble() { MOZ_CRASH(); }
++inline bool hasMultiAlias() { MOZ_CRASH(); }
++
++static const uint32_t ShadowStackSpace = 0;
++static const uint32_t JumpImmediateRange = INT32_MAX;
++
++#ifdef JS_NUNBOX32
++static const int32_t NUNBOX32_TYPE_OFFSET = 4;
++static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0;
++#endif
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_Architecture_riscv64_h */
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
+new file mode 100644
+index 0000000000000..55b0d3436b3d6
+--- /dev/null
++++ b/js/src/jit/riscv64/Assembler-riscv64.h
+@@ -0,0 +1,200 @@
++/* -*- 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_Assembler_riscv64_h
++#define jit_riscv64_Assembler_riscv64_h
++
++#include "mozilla/Assertions.h"
++
++#include <stdint.h>
++
++#include "jit/riscv64/Architecture-riscv64.h"
++#include "jit/Registers.h"
++#include "jit/RegisterSets.h"
++#include "jit/shared/Assembler-shared.h"
++
++namespace js {
++namespace jit {
++
++class MacroAssembler;
++
++static constexpr Register StackPointer{Registers::invalid_reg};
++static constexpr Register FramePointer{Registers::invalid_reg};
++static constexpr Register ReturnReg{Registers::invalid_reg2};
++static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister ReturnSimd128Reg = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister ScratchSimd128Reg = {
++    FloatRegisters::invalid_reg};
++static constexpr FloatRegister InvalidFloatReg = {FloatRegisters::invalid_reg};
++
++struct ScratchFloat32Scope : FloatRegister {
++  explicit ScratchFloat32Scope(MacroAssembler& masm) {}
++};
++
++struct ScratchDoubleScope : FloatRegister {
++  explicit ScratchDoubleScope(MacroAssembler& masm) {}
++};
++
++static constexpr Register OsrFrameReg{Registers::invalid_reg};
++static constexpr Register PreBarrierReg{Registers::invalid_reg};
++static constexpr Register InterpreterPCReg{Registers::invalid_reg};
++static constexpr Register CallTempReg0{Registers::invalid_reg};
++static constexpr Register CallTempReg1{Registers::invalid_reg};
++static constexpr Register CallTempReg2{Registers::invalid_reg};
++static constexpr Register CallTempReg3{Registers::invalid_reg};
++static constexpr Register CallTempReg4{Registers::invalid_reg};
++static constexpr Register CallTempReg5{Registers::invalid_reg};
++static constexpr Register InvalidReg{Registers::invalid_reg};
++static constexpr Register CallTempNonArgRegs[] = {InvalidReg, InvalidReg};
++static const uint32_t NumCallTempNonArgRegs = std::size(CallTempNonArgRegs);
++
++static constexpr Register IntArgReg0{Registers::invalid_reg};
++static constexpr Register IntArgReg1{Registers::invalid_reg};
++static constexpr Register IntArgReg2{Registers::invalid_reg};
++static constexpr Register IntArgReg3{Registers::invalid_reg};
++static constexpr Register HeapReg{Registers::invalid_reg};
++
++static constexpr Register RegExpTesterRegExpReg{Registers::invalid_reg};
++static constexpr Register RegExpTesterStringReg{Registers::invalid_reg};
++static constexpr Register RegExpTesterLastIndexReg{Registers::invalid_reg};
++static constexpr Register RegExpTesterStickyReg{Registers::invalid_reg};
++
++static constexpr Register RegExpMatcherRegExpReg{Registers::invalid_reg};
++static constexpr Register RegExpMatcherStringReg{Registers::invalid_reg};
++static constexpr Register RegExpMatcherLastIndexReg{Registers::invalid_reg};
++static constexpr Register RegExpMatcherStickyReg{Registers::invalid_reg};
++
++// Uses |invalid_reg2| to avoid static_assert failures.
++static constexpr Register JSReturnReg_Type{Registers::invalid_reg2};
++static constexpr Register JSReturnReg_Data{Registers::invalid_reg2};
++static constexpr Register JSReturnReg{Registers::invalid_reg2};
++
++static constexpr ValueOperand JSReturnOperand(InvalidReg);
++static constexpr Register64 ReturnReg64(InvalidReg);
++
++static constexpr Register ABINonArgReg0{Registers::invalid_reg};
++static constexpr Register ABINonArgReg1{Registers::invalid_reg};
++static constexpr Register ABINonArgReg2{Registers::invalid_reg};
++static constexpr Register ABINonArgReg3{Registers::invalid_reg};
++static constexpr Register ABINonArgReturnReg0{Registers::invalid_reg};
++static constexpr Register ABINonArgReturnReg1{Registers::invalid_reg};
++static constexpr Register ABINonVolatileReg{Registers::invalid_reg};
++static constexpr Register ABINonArgReturnVolatileReg{Registers::invalid_reg};
++
++static constexpr FloatRegister ABINonArgDoubleReg = {
++    FloatRegisters::invalid_reg};
++
++static constexpr Register WasmTableCallScratchReg0{Registers::invalid_reg};
++static constexpr Register WasmTableCallScratchReg1{Registers::invalid_reg};
++static constexpr Register WasmTableCallSigReg{Registers::invalid_reg};
++static constexpr Register WasmTableCallIndexReg{Registers::invalid_reg};
++static constexpr Register WasmTlsReg{Registers::invalid_reg};
++static constexpr Register WasmJitEntryReturnScratch{Registers::invalid_reg};
++
++static constexpr uint32_t ABIStackAlignment = 4;
++static constexpr uint32_t CodeAlignment = 16;
++static constexpr uint32_t JitStackAlignment = 8;
++static constexpr uint32_t JitStackValueAlignment =
++    JitStackAlignment / sizeof(Value);
++
++static const Scale ScalePointer = TimesOne;
++
++class Assembler : public AssemblerShared {
++ public:
++  enum Condition {
++    Equal,
++    NotEqual,
++    Above,
++    AboveOrEqual,
++    Below,
++    BelowOrEqual,
++    GreaterThan,
++    GreaterThanOrEqual,
++    LessThan,
++    LessThanOrEqual,
++    Overflow,
++    CarrySet,
++    CarryClear,
++    Signed,
++    NotSigned,
++    Zero,
++    NonZero,
++    Always,
++  };
++
++  enum DoubleCondition {
++    DoubleOrdered,
++    DoubleEqual,
++    DoubleNotEqual,
++    DoubleGreaterThan,
++    DoubleGreaterThanOrEqual,
++    DoubleLessThan,
++    DoubleLessThanOrEqual,
++    DoubleUnordered,
++    DoubleEqualOrUnordered,
++    DoubleNotEqualOrUnordered,
++    DoubleGreaterThanOrUnordered,
++    DoubleGreaterThanOrEqualOrUnordered,
++    DoubleLessThanOrUnordered,
++    DoubleLessThanOrEqualOrUnordered
++  };
++
++  static Condition InvertCondition(Condition) { MOZ_CRASH(); }
++
++  static DoubleCondition InvertCondition(DoubleCondition) { MOZ_CRASH(); }
++
++  template <typename T, typename S>
++  static void PatchDataWithValueCheck(CodeLocationLabel, T, S) {
++    MOZ_CRASH();
++  }
++  static void PatchWrite_Imm32(CodeLocationLabel, Imm32) { MOZ_CRASH(); }
++
++  static void PatchWrite_NearCall(CodeLocationLabel, CodeLocationLabel) {
++    MOZ_CRASH();
++  }
++  static uint32_t PatchWrite_NearCallSize() { MOZ_CRASH(); }
++
++  static void ToggleToJmp(CodeLocationLabel) { MOZ_CRASH(); }
++  static void ToggleToCmp(CodeLocationLabel) { MOZ_CRASH(); }
++  static void ToggleCall(CodeLocationLabel, bool) { MOZ_CRASH(); }
++
++  static void Bind(uint8_t*, const CodeLabel&) { MOZ_CRASH(); }
++
++  static uintptr_t GetPointer(uint8_t*) { MOZ_CRASH(); }
++
++  static bool HasRoundInstruction(RoundingMode) { return false; }
++
++  void verifyHeapAccessDisassembly(uint32_t begin, uint32_t end,
++                                   const Disassembler::HeapAccess& heapAccess) {
++    MOZ_CRASH();
++  }
++
++  void setUnlimitedBuffer() { MOZ_CRASH(); }
++};
++
++class Operand {
++ public:
++  explicit Operand(const Address&) { MOZ_CRASH(); }
++  explicit Operand(const Register) { MOZ_CRASH(); }
++  explicit Operand(const FloatRegister) { MOZ_CRASH(); }
++  explicit Operand(Register, Imm32) { MOZ_CRASH(); }
++  explicit Operand(Register, int32_t) { MOZ_CRASH(); }
++};
++
++class ABIArgGenerator {
++ public:
++  ABIArgGenerator() { MOZ_CRASH(); }
++  ABIArg next(MIRType) { MOZ_CRASH(); }
++  ABIArg& current() { MOZ_CRASH(); }
++  uint32_t stackBytesConsumedSoFar() const { MOZ_CRASH(); }
++  void increaseStackOffset(uint32_t) { MOZ_CRASH(); }
++};
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_Assembler_riscv64_h */
+diff --git a/js/src/jit/riscv64/CodeGenerator-riscv64.h b/js/src/jit/riscv64/CodeGenerator-riscv64.h
+new file mode 100644
+index 0000000000000..db30b32283e42
+--- /dev/null
++++ b/js/src/jit/riscv64/CodeGenerator-riscv64.h
+@@ -0,0 +1,78 @@
++/* -*- 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_CodeGenerator_riscv64_h
++#define jit_riscv64_CodeGenerator_riscv64_h
++
++#include "jit/shared/CodeGenerator-shared.h"
++
++namespace js {
++namespace jit {
++
++class CodeGeneratorRiscv64 : public CodeGeneratorShared {
++ protected:
++  CodeGeneratorRiscv64(MIRGenerator* gen, LIRGraph* graph, MacroAssembler* masm)
++      : CodeGeneratorShared(gen, graph, masm) {
++    MOZ_CRASH();
++  }
++
++  MoveOperand toMoveOperand(LAllocation) const { MOZ_CRASH(); }
++  template <typename T1, typename T2>
++  void bailoutCmp32(Assembler::Condition, T1, T2, LSnapshot*) {
++    MOZ_CRASH();
++  }
++  template <typename T1, typename T2>
++  void bailoutTest32(Assembler::Condition, T1, T2, LSnapshot*) {
++    MOZ_CRASH();
++  }
++  template <typename T1, typename T2>
++  void bailoutCmpPtr(Assembler::Condition, T1, T2, LSnapshot*) {
++    MOZ_CRASH();
++  }
++  void bailoutTestPtr(Assembler::Condition, Register, Register, LSnapshot*) {
++    MOZ_CRASH();
++  }
++  void bailoutIfFalseBool(Register, LSnapshot*) { MOZ_CRASH(); }
++  void bailoutFrom(Label*, LSnapshot*) { MOZ_CRASH(); }
++  void bailout(LSnapshot*) { MOZ_CRASH(); }
++  void bailoutIf(Assembler::Condition, LSnapshot*) { MOZ_CRASH(); }
++  bool generateOutOfLineCode() { MOZ_CRASH(); }
++  void testNullEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
++                          MBasicBlock*) {
++    MOZ_CRASH();
++  }
++  void testUndefinedEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
++                               MBasicBlock*) {
++    MOZ_CRASH();
++  }
++  void testObjectEmitBranch(Assembler::Condition, ValueOperand, MBasicBlock*,
++                            MBasicBlock*) {
++    MOZ_CRASH();
++  }
++  void testZeroEmitBranch(Assembler::Condition, Register, MBasicBlock*,
++                          MBasicBlock*) {
++    MOZ_CRASH();
++  }
++  void emitTableSwitchDispatch(MTableSwitch*, Register, Register) {
++    MOZ_CRASH();
++  }
++  void emitBigIntDiv(LBigIntDiv*, Register, Register, Register, Label*) {
++    MOZ_CRASH();
++  }
++  void emitBigIntMod(LBigIntMod*, Register, Register, Register, Label*) {
++    MOZ_CRASH();
++  }
++  ValueOperand ToValue(LInstruction*, size_t) { MOZ_CRASH(); }
++  ValueOperand ToTempValue(LInstruction*, size_t) { MOZ_CRASH(); }
++  void generateInvalidateEpilogue() { MOZ_CRASH(); }
++};
++
++typedef CodeGeneratorRiscv64 CodeGeneratorSpecific;
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_CodeGenerator_riscv64_h */
+diff --git a/js/src/jit/riscv64/LIR-riscv64.h b/js/src/jit/riscv64/LIR-riscv64.h
+new file mode 100644
+index 0000000000000..59d42c6c75094
+--- /dev/null
++++ b/js/src/jit/riscv64/LIR-riscv64.h
+@@ -0,0 +1,111 @@
++/* -*- 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_LIR_riscv64_h
++#define jit_riscv64_LIR_riscv64_h
++
++namespace js {
++namespace jit {
++
++class LUnboxFloatingPoint : public LInstruction {
++ public:
++  LIR_HEADER(UnboxFloatingPoint)
++  static const size_t Input = 0;
++
++  MUnbox* mir() const { MOZ_CRASH(); }
++
++  const LDefinition* output() const { MOZ_CRASH(); }
++  MIRType type() const { MOZ_CRASH(); }
++};
++
++class LTableSwitch : public LInstruction {
++ public:
++  LIR_HEADER(TableSwitch)
++  MTableSwitch* mir() { MOZ_CRASH(); }
++
++  const LAllocation* index() { MOZ_CRASH(); }
++  const LDefinition* tempInt() { MOZ_CRASH(); }
++  const LDefinition* tempPointer() { MOZ_CRASH(); }
++};
++
++class LTableSwitchV : public LInstruction {
++ public:
++  LIR_HEADER(TableSwitchV)
++  MTableSwitch* mir() { MOZ_CRASH(); }
++
++  const LDefinition* tempInt() { MOZ_CRASH(); }
++  const LDefinition* tempFloat() { MOZ_CRASH(); }
++  const LDefinition* tempPointer() { MOZ_CRASH(); }
++
++  static const size_t InputValue = 0;
++};
++
++class LWasmUint32ToFloat32 : public LInstructionHelper<1, 1, 0> {
++ public:
++  explicit LWasmUint32ToFloat32(const LAllocation&)
++      : LInstructionHelper(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++};
++
++class LUnbox : public LInstructionHelper<1, 2, 0> {
++ public:
++  MUnbox* mir() const { MOZ_CRASH(); }
++  const LAllocation* payload() { MOZ_CRASH(); }
++  const LAllocation* type() { MOZ_CRASH(); }
++  const char* extraName() const { MOZ_CRASH(); }
++};
++class LDivI : public LBinaryMath<1> {
++ public:
++  LDivI(const LAllocation&, const LAllocation&, const LDefinition&)
++      : LBinaryMath(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++  MDiv* mir() const { MOZ_CRASH(); }
++};
++class LDivPowTwoI : public LInstructionHelper<1, 1, 0> {
++ public:
++  LDivPowTwoI(const LAllocation&, int32_t)
++      : LInstructionHelper(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++  const LAllocation* numerator() { MOZ_CRASH(); }
++  int32_t shift() { MOZ_CRASH(); }
++  MDiv* mir() const { MOZ_CRASH(); }
++};
++class LModI : public LBinaryMath<1> {
++ public:
++  LModI(const LAllocation&, const LAllocation&, const LDefinition&)
++      : LBinaryMath(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++
++  const LDefinition* callTemp() { MOZ_CRASH(); }
++  MMod* mir() const { MOZ_CRASH(); }
++};
++class LWasmUint32ToDouble : public LInstructionHelper<1, 1, 0> {
++ public:
++  explicit LWasmUint32ToDouble(const LAllocation&)
++      : LInstructionHelper(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++};
++class LModPowTwoI : public LInstructionHelper<1, 1, 0> {
++ public:
++  int32_t shift() { MOZ_CRASH(); }
++  LModPowTwoI(const LAllocation& lhs, int32_t shift)
++      : LInstructionHelper(Opcode::Invalid) {
++    MOZ_CRASH();
++  }
++  MMod* mir() const { MOZ_CRASH(); }
++};
++
++class LMulI : public LInstruction {};
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_LIR_riscv64_h */
+diff --git a/js/src/jit/riscv64/Lowering-riscv64.h b/js/src/jit/riscv64/Lowering-riscv64.h
+new file mode 100644
+index 0000000000000..a68e52b87243f
+--- /dev/null
++++ b/js/src/jit/riscv64/Lowering-riscv64.h
+@@ -0,0 +1,130 @@
++/* -*- 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_Lowering_riscv64_h
++#define jit_riscv64_Lowering_riscv64_h
++
++#include "jit/shared/Lowering-shared.h"
++
++namespace js {
++namespace jit {
++
++class LIRGeneratorRiscv64 : public LIRGeneratorShared {
++ protected:
++  LIRGeneratorRiscv64(MIRGenerator* gen, MIRGraph& graph, LIRGraph& lirGraph)
++      : LIRGeneratorShared(gen, graph, lirGraph) {
++    MOZ_CRASH();
++  }
++
++  LBoxAllocation useBoxFixed(MDefinition*, Register, Register,
++                             bool useAtStart = false) {
++    MOZ_CRASH();
++  }
++
++  LAllocation useByteOpRegister(MDefinition*) { MOZ_CRASH(); }
++  LAllocation useByteOpRegisterAtStart(MDefinition*) { MOZ_CRASH(); }
++  LAllocation useByteOpRegisterOrNonDoubleConstant(MDefinition*) {
++    MOZ_CRASH();
++  }
++  LDefinition tempByteOpRegister() { MOZ_CRASH(); }
++  LDefinition tempToUnbox() { MOZ_CRASH(); }
++  bool needTempForPostBarrier() { MOZ_CRASH(); }
++  void lowerUntypedPhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); }
++  void lowerInt64PhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); }
++  void defineInt64Phi(MPhi*, size_t) { MOZ_CRASH(); }
++  void lowerForShift(LInstructionHelper<1, 2, 0>*, MDefinition*, MDefinition*,
++                     MDefinition*) {
++    MOZ_CRASH();
++  }
++  void lowerUrshD(MUrsh*) { MOZ_CRASH(); }
++  void lowerPowOfTwoI(MPow*) { MOZ_CRASH(); }
++  template <typename T>
++  void lowerForALU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void lowerForFPU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void lowerForALUInt64(T, MDefinition*, MDefinition*,
++                        MDefinition* v = nullptr) {
++    MOZ_CRASH();
++  }
++  void lowerForMulInt64(LMulI64*, MMul*, MDefinition*,
++                        MDefinition* v = nullptr) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void lowerForShiftInt64(T, MDefinition*, MDefinition*,
++                          MDefinition* v = nullptr) {
++    MOZ_CRASH();
++  }
++  void lowerForBitAndAndBranch(LBitAndAndBranch*, MInstruction*, MDefinition*,
++                               MDefinition*) {
++    MOZ_CRASH();
++  }
++  void lowerForCompareI64AndBranch(MTest*, MCompare*, JSOp, MDefinition*,
++                                   MDefinition*, MBasicBlock*, MBasicBlock*) {
++    MOZ_CRASH();
++  }
++
++  void lowerConstantDouble(double, MInstruction*) { MOZ_CRASH(); }
++  void lowerConstantFloat32(float, MInstruction*) { MOZ_CRASH(); }
++  void lowerTruncateDToInt32(MTruncateToInt32*) { MOZ_CRASH(); }
++  void lowerTruncateFToInt32(MTruncateToInt32*) { MOZ_CRASH(); }
++  void lowerBuiltinInt64ToFloatingPoint(MBuiltinInt64ToFloatingPoint* ins) {
++    MOZ_CRASH();
++  }
++  void lowerWasmBuiltinTruncateToInt64(MWasmBuiltinTruncateToInt64* ins) {
++    MOZ_CRASH();
++  }
++  void lowerWasmBuiltinTruncateToInt32(MWasmBuiltinTruncateToInt32* ins) {
++    MOZ_CRASH();
++  }
++  void lowerDivI(MDiv*) { MOZ_CRASH(); }
++  void lowerModI(MMod*) { MOZ_CRASH(); }
++  void lowerDivI64(MDiv*) { MOZ_CRASH(); }
++  void lowerWasmBuiltinDivI64(MWasmBuiltinDivI64* div) { MOZ_CRASH(); }
++  void lowerModI64(MMod*) { MOZ_CRASH(); }
++  void lowerWasmBuiltinModI64(MWasmBuiltinModI64* mod) { MOZ_CRASH(); }
++  void lowerNegI(MInstruction*, MDefinition*) { MOZ_CRASH(); }
++  void lowerNegI64(MInstruction*, MDefinition*) { MOZ_CRASH(); }
++  void lowerMulI(MMul*, MDefinition*, MDefinition*) { MOZ_CRASH(); }
++  void lowerUDiv(MDiv*) { MOZ_CRASH(); }
++  void lowerUMod(MMod*) { MOZ_CRASH(); }
++  void lowerWasmSelectI(MWasmSelect* select) { MOZ_CRASH(); }
++  void lowerWasmSelectI64(MWasmSelect* select) { MOZ_CRASH(); }
++  void lowerWasmCompareAndSelect(MWasmSelect* ins, MDefinition* lhs,
++                                 MDefinition* rhs, MCompare::CompareType compTy,
++                                 JSOp jsop) {
++    MOZ_CRASH();
++  }
++  bool canSpecializeWasmCompareAndSelect(MCompare::CompareType compTy,
++                                         MIRType insTy) {
++    MOZ_CRASH();
++  }
++
++  void lowerBigIntLsh(MBigIntLsh*) { MOZ_CRASH(); }
++  void lowerBigIntRsh(MBigIntRsh*) { MOZ_CRASH(); }
++  void lowerBigIntDiv(MBigIntDiv*) { MOZ_CRASH(); }
++  void lowerBigIntMod(MBigIntMod*) { MOZ_CRASH(); }
++
++  void lowerAtomicLoad64(MLoadUnboxedScalar*) { MOZ_CRASH(); }
++  void lowerAtomicStore64(MStoreUnboxedScalar*) { MOZ_CRASH(); }
++
++  LTableSwitch* newLTableSwitch(LAllocation, LDefinition, MTableSwitch*) {
++    MOZ_CRASH();
++  }
++  LTableSwitchV* newLTableSwitchV(MTableSwitch*) { MOZ_CRASH(); }
++};
++
++typedef LIRGeneratorRiscv64 LIRGeneratorSpecific;
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_Lowering_riscv64_h */
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+new file mode 100644
+index 0000000000000..a9265bb7bd44b
+--- /dev/null
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+@@ -0,0 +1,458 @@
++/* -*- 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_MacroAssembler_riscv64_h
++#define jit_riscv64_MacroAssembler_riscv64_h
++
++#include <iterator>
++
++#include "jit/MoveResolver.h"
++#include "jit/riscv64/Assembler-riscv64.h"
++#include "wasm/WasmTypeDecls.h"
++
++namespace js {
++namespace jit {
++
++class CompactBufferReader;
++
++class ScratchTagScope {
++ public:
++  ScratchTagScope(MacroAssembler&, const ValueOperand) {}
++  operator Register() { MOZ_CRASH(); }
++  void release() { MOZ_CRASH(); }
++  void reacquire() { MOZ_CRASH(); }
++};
++
++class ScratchTagScopeRelease {
++ public:
++  explicit ScratchTagScopeRelease(ScratchTagScope*) {}
++};
++
++class MacroAssemblerRiscv64 : public Assembler {
++ public:
++  MacroAssemblerRiscv64() { MOZ_CRASH(); }
++
++  MoveResolver moveResolver_;
++
++  size_t size() const { MOZ_CRASH(); }
++  size_t bytesNeeded() const { MOZ_CRASH(); }
++  size_t jumpRelocationTableBytes() const { MOZ_CRASH(); }
++  size_t dataRelocationTableBytes() const { MOZ_CRASH(); }
++  size_t preBarrierTableBytes() const { MOZ_CRASH(); }
++
++  size_t numCodeLabels() const { MOZ_CRASH(); }
++  CodeLabel codeLabel(size_t) { MOZ_CRASH(); }
++
++  bool reserve(size_t size) { MOZ_CRASH(); }
++  bool appendRawCode(const uint8_t* code, size_t numBytes) { MOZ_CRASH(); }
++  bool swapBuffer(wasm::Bytes& bytes) { MOZ_CRASH(); }
++
++  void assertNoGCThings() const { MOZ_CRASH(); }
++
++  static void TraceJumpRelocations(JSTracer*, JitCode*, CompactBufferReader&) {
++    MOZ_CRASH();
++  }
++  static void TraceDataRelocations(JSTracer*, JitCode*, CompactBufferReader&) {
++    MOZ_CRASH();
++  }
++
++  static bool SupportsFloatingPoint() { return false; }
++  static bool SupportsUnalignedAccesses() { return false; }
++  static bool SupportsFastUnalignedFPAccesses() { return false; }
++
++  void executableCopy(void*, bool = true) { MOZ_CRASH(); }
++  void copyJumpRelocationTable(uint8_t*) { MOZ_CRASH(); }
++  void copyDataRelocationTable(uint8_t*) { MOZ_CRASH(); }
++  void copyPreBarrierTable(uint8_t*) { MOZ_CRASH(); }
++  void processCodeLabels(uint8_t*) { MOZ_CRASH(); }
++
++  void flushBuffer() { MOZ_CRASH(); }
++
++  template <typename T>
++  void bind(T) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void j(Condition, T) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void jump(T) {
++    MOZ_CRASH();
++  }
++  void writeCodePointer(CodeLabel* label) { MOZ_CRASH(); }
++  void haltingAlign(size_t) { MOZ_CRASH(); }
++  void nopAlign(size_t) { MOZ_CRASH(); }
++  void checkStackAlignment() { MOZ_CRASH(); }
++  uint32_t currentOffset() { MOZ_CRASH(); }
++
++  void nop() { MOZ_CRASH(); }
++  void breakpoint() { MOZ_CRASH(); }
++  void abiret() { MOZ_CRASH(); }
++  void ret() { MOZ_CRASH(); }
++
++  CodeOffset toggledJump(Label*) { MOZ_CRASH(); }
++  CodeOffset toggledCall(JitCode*, bool) { MOZ_CRASH(); }
++  static size_t ToggledCallSize(uint8_t*) { MOZ_CRASH(); }
++
++  void finish() { MOZ_CRASH(); }
++
++  template <typename T, typename S>
++  void moveValue(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S, typename U>
++  void moveValue(T, S, U) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void storeValue(const T&, const S&) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S, typename U>
++  void storeValue(T, S, U) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void storePrivateValue(const T&, const S&) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void loadValue(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void loadUnalignedValue(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void pushValue(const T&) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void pushValue(T, S) {
++    MOZ_CRASH();
++  }
++  void popValue(ValueOperand) { MOZ_CRASH(); }
++  void tagValue(JSValueType, Register, ValueOperand) { MOZ_CRASH(); }
++  void retn(Imm32 n) { MOZ_CRASH(); }
++  template <typename T>
++  void push(const T&) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void Push(T) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void pop(T) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void Pop(T) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  CodeOffset pushWithPatch(T) {
++    MOZ_CRASH();
++  }
++
++  void testNullSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
++  void testObjectSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
++  void testUndefinedSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
++
++  template <typename T, typename S>
++  void cmpPtrSet(Condition, T, S, Register) {
++    MOZ_CRASH();
++  }
++  void cmp8Set(Condition, Address, Imm32, Register) { MOZ_CRASH(); }
++  void cmp16Set(Condition, Address, Imm32, Register) { MOZ_CRASH(); }
++  template <typename T, typename S>
++  void cmp32Set(Condition, T, S, Register) {
++    MOZ_CRASH();
++  }
++  void cmp64Set(Condition, Address, Imm64, Register) { MOZ_CRASH(); }
++
++  template <typename T>
++  void mov(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void movePtr(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void move32(const T&, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void movq(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void moveFloat32(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void moveDouble(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void move64(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  CodeOffset movWithPatch(T, Register) {
++    MOZ_CRASH();
++  }
++
++  template <typename T>
++  void loadPtr(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load32(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load32Unaligned(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void loadFloat32(T, FloatRegister) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void loadDouble(T, FloatRegister) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void loadPrivate(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load8SignExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load8ZeroExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load16SignExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load16UnalignedSignExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load16ZeroExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load16UnalignedZeroExtend(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load64(T, Register64) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void load64Unaligned(T, Register64) {
++    MOZ_CRASH();
++  }
++
++  template <typename T, typename S>
++  void storePtr(const T&, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store32(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store32_NoSecondScratch(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store32Unaligned(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void storeFloat32(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void storeDouble(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store8(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store16(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store16Unaligned(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store64(T, S) {
++    MOZ_CRASH();
++  }
++  template <typename T, typename S>
++  void store64Unaligned(T, S) {
++    MOZ_CRASH();
++  }
++
++  template <typename T>
++  void computeEffectiveAddress(T, Register) {
++    MOZ_CRASH();
++  }
++
++  void splitTagForTest(ValueOperand, ScratchTagScope&) { MOZ_CRASH(); }
++
++  void boxDouble(FloatRegister, ValueOperand, FloatRegister) { MOZ_CRASH(); }
++  void boxNonDouble(JSValueType, Register, ValueOperand) { MOZ_CRASH(); }
++  template <typename T>
++  void boxDouble(FloatRegister src, const T& dest) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxInt32(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxBoolean(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxString(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxSymbol(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxBigInt(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxObject(T, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxDouble(T, FloatRegister) {
++    MOZ_CRASH();
++  }
++  void unboxValue(const ValueOperand&, AnyRegister, JSValueType) {
++    MOZ_CRASH();
++  }
++  void unboxNonDouble(const ValueOperand&, Register, JSValueType) {
++    MOZ_CRASH();
++  }
++  void unboxNonDouble(const Address&, Register, JSValueType) { MOZ_CRASH(); }
++  template <typename T>
++  void unboxGCThingForGCBarrier(const T&, Register) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void unboxObjectOrNull(const T& src, Register dest) {
++    MOZ_CRASH();
++  }
++  void notBoolean(ValueOperand) { MOZ_CRASH(); }
++  [[nodiscard]] Register extractObject(Address, Register) { MOZ_CRASH(); }
++  [[nodiscard]] Register extractObject(ValueOperand, Register) { MOZ_CRASH(); }
++  [[nodiscard]] Register extractSymbol(ValueOperand, Register) { MOZ_CRASH(); }
++  [[nodiscard]] Register extractInt32(ValueOperand, Register) { MOZ_CRASH(); }
++  [[nodiscard]] Register extractBoolean(ValueOperand, Register) { MOZ_CRASH(); }
++  template <typename T>
++  [[nodiscard]] Register extractTag(T, Register) {
++    MOZ_CRASH();
++  }
++
++  void convertFloat32ToInt32(FloatRegister, Register, Label*, bool v = true) {
++    MOZ_CRASH();
++  }
++  void convertDoubleToInt32(FloatRegister, Register, Label*, bool v = true) {
++    MOZ_CRASH();
++  }
++  void convertDoubleToPtr(FloatRegister, Register, Label*, bool v = true) {
++    MOZ_CRASH();
++  }
++  void convertBoolToInt32(Register, Register) { MOZ_CRASH(); }
++
++  void convertDoubleToFloat32(FloatRegister, FloatRegister) { MOZ_CRASH(); }
++  void convertInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); }
++
++  template <typename T>
++  void convertInt32ToDouble(T, FloatRegister) {
++    MOZ_CRASH();
++  }
++  void convertFloat32ToDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); }
++
++  void boolValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
++  void boolValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
++  void int32ValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
++  void int32ValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
++
++  void loadConstantDouble(double, FloatRegister) { MOZ_CRASH(); }
++  void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
++  Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
++  Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
++  Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
++
++  template <typename T>
++  void loadUnboxedValue(T, MIRType, AnyRegister) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) {
++    MOZ_CRASH();
++  }
++  template <typename T>
++  void storeUnboxedPayload(ValueOperand value, T, size_t, JSValueType) {
++    MOZ_CRASH();
++  }
++
++  void convertUInt32ToDouble(Register, FloatRegister) { MOZ_CRASH(); }
++  void convertUInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); }
++  void incrementInt32Value(Address) { MOZ_CRASH(); }
++  void ensureDouble(ValueOperand, FloatRegister, Label*) { MOZ_CRASH(); }
++  void handleFailureWithHandlerTail(Label*) { MOZ_CRASH(); }
++
++  void buildFakeExitFrame(Register, uint32_t*) { MOZ_CRASH(); }
++  bool buildOOLFakeExitFrame(void*) { MOZ_CRASH(); }
++
++  void setPrinter(Sprinter*) { MOZ_CRASH(); }
++  Operand ToPayload(Operand base) { MOZ_CRASH(); }
++  Address ToPayload(Address) { MOZ_CRASH(); }
++
++  Register getStackPointer() const { MOZ_CRASH(); }
++
++  // Instrumentation for entering and leaving the profiler.
++  void profilerEnterFrame(Register, Register) { MOZ_CRASH(); }
++  void profilerExitFrame() { MOZ_CRASH(); }
++
++#ifdef JS_NUNBOX32
++  Address ToType(Address) { MOZ_CRASH(); }
++#endif
++};
++
++typedef MacroAssemblerRiscv64 MacroAssemblerSpecific;
++
++static inline bool GetTempRegForIntArg(uint32_t, uint32_t, Register*) {
++  MOZ_CRASH();
++}
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_MacroAssembler_riscv64_h */
+diff --git a/js/src/jit/riscv64/MoveEmitter-riscv64.h b/js/src/jit/riscv64/MoveEmitter-riscv64.h
+new file mode 100644
+index 0000000000000..24ca3aebb26a4
+--- /dev/null
++++ b/js/src/jit/riscv64/MoveEmitter-riscv64.h
+@@ -0,0 +1,32 @@
++/* -*- 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_MoveEmitter_riscv64_h
++#define jit_riscv64_MoveEmitter_riscv64_h
++
++#include "mozilla/Assertions.h"
++
++namespace js {
++namespace jit {
++
++class MacroAssemblerRiscv64;
++class MoveResolver;
++struct Register;
++
++class MoveEmitterRiscv64 {
++ public:
++  explicit MoveEmitterRiscv64(MacroAssemblerRiscv64&) { MOZ_CRASH(); }
++  void emit(const MoveResolver&) { MOZ_CRASH(); }
++  void finish() { MOZ_CRASH(); }
++  void setScratchRegister(Register) { MOZ_CRASH(); }
++};
++
++typedef MoveEmitterRiscv64 MoveEmitter;
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_MoveEmitter_riscv64_h */
+diff --git a/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h b/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h
+new file mode 100644
+index 0000000000000..7c6f7b7c20d7b
+--- /dev/null
++++ b/js/src/jit/riscv64/SharedICHelpers-riscv64-inl.h
+@@ -0,0 +1,34 @@
++/* -*- 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_SharedICHelpers_riscv64_inl_h
++#define jit_riscv64_SharedICHelpers_riscv64_inl_h
++
++#include "jit/SharedICHelpers.h"
++
++namespace js {
++namespace jit {
++
++inline void EmitBaselineTailCallVM(TrampolinePtr, MacroAssembler&, uint32_t) {
++  MOZ_CRASH();
++}
++inline void EmitBaselineCreateStubFrameDescriptor(MacroAssembler&, Register,
++                                                  uint32_t) {
++  MOZ_CRASH();
++}
++inline void EmitBaselineCallVM(TrampolinePtr, MacroAssembler&) { MOZ_CRASH(); }
++
++static const uint32_t STUB_FRAME_SIZE = 0;
++static const uint32_t STUB_FRAME_SAVED_STUB_OFFSET = 0;
++
++inline void EmitBaselineEnterStubFrame(MacroAssembler&, Register) {
++  MOZ_CRASH();
++}
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_SharedICHelpers_riscv64_inl_h */
+diff --git a/js/src/jit/riscv64/SharedICHelpers-riscv64.h b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
+new file mode 100644
+index 0000000000000..15734c11f5738
+--- /dev/null
++++ b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
+@@ -0,0 +1,32 @@
++/* -*- 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_SharedICHelpers_riscv64_h
++#define jit_riscv64_SharedICHelpers_riscv64_h
++
++namespace js {
++namespace jit {
++
++static const size_t ICStackValueOffset = 0;
++
++inline void EmitRestoreTailCallReg(MacroAssembler&) { MOZ_CRASH(); }
++inline void EmitRepushTailCallReg(MacroAssembler&) { MOZ_CRASH(); }
++inline void EmitCallIC(MacroAssembler&, CodeOffset*) { MOZ_CRASH(); }
++inline void EmitReturnFromIC(MacroAssembler&) { MOZ_CRASH(); }
++inline void EmitBaselineLeaveStubFrame(MacroAssembler&, bool v = false) {
++  MOZ_CRASH();
++}
++inline void EmitStubGuardFailure(MacroAssembler&) { MOZ_CRASH(); }
++
++template <typename T>
++inline void EmitPreBarrier(MacroAssembler&, T, MIRType) {
++  MOZ_CRASH();
++}
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_SharedICHelpers_riscv64_h */
+diff --git a/js/src/jit/riscv64/SharedICRegisters-riscv64.h b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+new file mode 100644
+index 0000000000000..72183cb02c2c0
+--- /dev/null
++++ b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+@@ -0,0 +1,38 @@
++/* -*- 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_SharedICRegisters_riscv64_h
++#define jit_riscv64_SharedICRegisters_riscv64_h
++
++#include "jit/riscv64/MacroAssembler-riscv64.h"
++#include "jit/Registers.h"
++#include "jit/RegisterSets.h"
++
++namespace js {
++namespace jit {
++
++static constexpr Register BaselineFrameReg{Registers::invalid_reg};
++static constexpr Register BaselineStackReg{Registers::invalid_reg};
++
++static constexpr ValueOperand R0 = JSReturnOperand;
++static constexpr ValueOperand R1 = JSReturnOperand;
++static constexpr ValueOperand R2 = JSReturnOperand;
++
++static constexpr Register ICTailCallReg{Registers::invalid_reg};
++static constexpr Register ICStubReg{Registers::invalid_reg};
++
++static constexpr Register ExtractTemp0{Registers::invalid_reg};
++static constexpr Register ExtractTemp1{Registers::invalid_reg};
++
++static constexpr FloatRegister FloatReg0 = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister FloatReg1 = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister FloatReg2 = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister FloatReg3 = {FloatRegisters::invalid_reg};
++
++}  // namespace jit
++}  // namespace js
++
++#endif /* jit_riscv64_SharedICRegisters_riscv64_h */
+diff --git a/js/src/jit/riscv64/Trampoline-riscv64.cpp b/js/src/jit/riscv64/Trampoline-riscv64.cpp
+new file mode 100644
+index 0000000000000..0774254cf4cf5
+--- /dev/null
++++ b/js/src/jit/riscv64/Trampoline-riscv64.cpp
+@@ -0,0 +1,67 @@
++/* -*- 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/. */
++
++#include "jit/Bailouts.h"
++#include "jit/BaselineIC.h"
++#include "jit/JitRuntime.h"
++#include "vm/Realm.h"
++
++using namespace js;
++using namespace js::jit;
++
++// This file includes stubs for generating the JIT trampolines when there is no
++// JIT backend, and also includes implementations for assorted random things
++// which can't be implemented in headers.
++
++void JitRuntime::generateEnterJIT(JSContext*, MacroAssembler&) { MOZ_CRASH(); }
++// static
++mozilla::Maybe<::JS::ProfilingFrameIterator::RegisterState>
++JitRuntime::getCppEntryRegisters(JitFrameLayout* frameStackAddress) {
++  return mozilla::Nothing{};
++}
++void JitRuntime::generateInvalidator(MacroAssembler&, Label*) { MOZ_CRASH(); }
++void JitRuntime::generateArgumentsRectifier(MacroAssembler&,
++                                            ArgumentsRectifierKind kind) {
++  MOZ_CRASH();
++}
++JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler&,
++                                                          Label*, uint32_t) {
++  MOZ_CRASH();
++}
++void JitRuntime::generateBailoutHandler(MacroAssembler&, Label*) {
++  MOZ_CRASH();
++}
++uint32_t JitRuntime::generatePreBarrier(JSContext*, MacroAssembler&, MIRType) {
++  MOZ_CRASH();
++}
++void JitRuntime::generateExceptionTailStub(MacroAssembler&, Label*) {
++  MOZ_CRASH();
++}
++void JitRuntime::generateBailoutTailStub(MacroAssembler&, Label*) {
++  MOZ_CRASH();
++}
++void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler&, Label*) {
++  MOZ_CRASH();
++}
++
++bool JitRuntime::generateVMWrapper(JSContext*, MacroAssembler&,
++                                   const VMFunctionData&, DynFn, uint32_t*) {
++  MOZ_CRASH();
++}
++
++FrameSizeClass FrameSizeClass::FromDepth(uint32_t) { MOZ_CRASH(); }
++FrameSizeClass FrameSizeClass::ClassLimit() { MOZ_CRASH(); }
++uint32_t FrameSizeClass::frameSize() const { MOZ_CRASH(); }
++
++BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter,
++                                   BailoutStack* bailout) {
++  MOZ_CRASH();
++}
++
++BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter,
++                                   InvalidationBailoutStack* bailout) {
++  MOZ_CRASH();
++}
+
+From ef48b82e6e70ae569d2f401b54148c2c9535f0cf Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Thu, 17 Feb 2022 00:05:54 +0900
+Subject: [PATCH] Add registers.
+
+---
+ js/src/jit/riscv64/Architecture-riscv64.h   | 291 +++++++++++++++++---
+ js/src/jit/riscv64/Assembler-riscv64.cpp    |  42 +++
+ js/src/jit/riscv64/Assembler-riscv64.h      | 186 +++++++++----
+ js/src/jit/riscv64/MacroAssembler-riscv64.h |  15 +-
+ 5 files changed, 433 insertions(+), 107 deletions(-)
+ create mode 100644 js/src/jit/riscv64/Assembler-riscv64.cpp
+
+diff --git a/js/src/jit/riscv64/Architecture-riscv64.h b/js/src/jit/riscv64/Architecture-riscv64.h
+index 3a4a25205bcd1..2b5495ce5f3d8 100644
+--- a/js/src/jit/riscv64/Architecture-riscv64.h
++++ b/js/src/jit/riscv64/Architecture-riscv64.h
+@@ -28,9 +28,72 @@ static constexpr uint32_t WasmCheckedTailEntryOffset = 1u;
+ class Registers {
+  public:
+   enum RegisterID {
+-    r0 = 0,
+-    invalid_reg,
+-    invalid_reg2,  // To avoid silly static_assert failures.
++    x0 = 0,
++    zero = 0,
++    x1 = 1,
++    ra = 1,
++    x2 = 2,
++    sp = 2,
++    x3 = 3,
++    gp = 3,
++    x4 = 4,
++    tp = 4,
++    x5 = 5,
++    t0 = 5,
++    x6 = 6,
++    t1 = 6,
++    x7 = 7,
++    t2 = 7,
++    x8 = 8,
++    fp = 8,
++    s0 = 8,
++    x9 = 9,
++    s1 = 9,
++    x10 = 10,
++    a0 = 10,
++    x11 = 11,
++    a1 = 11,
++    x12 = 12,
++    a2 = 12,
++    x13 = 13,
++    a3 = 13,
++    x14 = 14,
++    a4 = 14,
++    x15 = 15,
++    a5 = 15,
++    x16 = 16,
++    a6 = 16,
++    x17 = 17,
++    a7 = 17,
++    x18 = 18,
++    s2 = 18,
++    x19 = 19,
++    s3 = 19,
++    x20 = 20,
++    s4 = 20,
++    x21 = 21,
++    s5 = 21,
++    x22 = 22,
++    s6 = 22,
++    x23 = 23,
++    s7 = 23,
++    x24 = 24,
++    s8 = 24,
++    x25 = 25,
++    s9 = 25,
++    x26 = 26,
++    s10 = 26,
++    x27 = 27,
++    s11 = 27,
++    x28 = 28,
++    t3 = 28,
++    x29 = 29,
++    t4 = 29,
++    x30 = 30,
++    t5 = 30,
++    x31 = 31,
++    t6 = 31,
++    invalid_reg
+   };
+   typedef uint8_t Code;
+   typedef RegisterID Encoding;
+@@ -38,25 +101,69 @@ class Registers {
+     uintptr_t r;
+   };
+ 
+-  typedef uint8_t SetType;
++  typedef uint32_t SetType;
+ 
+-  static uint32_t SetSize(SetType) { MOZ_CRASH(); }
+-  static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
+-  static uint32_t LastBit(SetType) { MOZ_CRASH(); }
+-  static const char* GetName(Code) { MOZ_CRASH(); }
+-  static Code FromName(const char*) { MOZ_CRASH(); }
++  static uint32_t SetSize(SetType x) {
++    static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
++    return mozilla::CountPopulation32(x);
++  }
++  static uint32_t FirstBit(SetType) {
++    return mozilla::CountTrailingZeroes32(x);
++  }
++  static uint32_t LastBit(SetType) {
++    return 31 - mozilla::CountLeadingZeroes32(x);
++  }
++
++  static const char* GetName(uint32_t code) {
++    // clang-format off
++    static const char* const Names[] = {
++        "zero", "ra", "sp",  "gp",  "tp", "t0", "t1", "t2",
++        "fp",   "s1", "a0",  "a1",  "a2", "a3", "a4", "a5",
++        "a6",   "a7", "s2",  "s3",  "s4", "s5", "s6", "s7",
++        "s8",   "s9", "s10", "s11", "t3", "t4", "t5", "t6"};
++    // clang-format on
++    static_assert(Total == sizeof(Names) / sizeof(Names[0]),
++                  "Table is the correct size");
++    if (code >= Total) {
++      return "invalid";
++    }
++    return Names[code];
++  }
+ 
+-  static const Encoding StackPointer = invalid_reg;
++  static Code FromName(const char* name) {
++    for (size_t i = 0; i < Total; i++) {
++      if (strcmp(GetName(Code(i)), name) == 0) {
++        return Code(i);
++      }
++    }
++    return Invalid;
++  }
++
++  static const Encoding StackPointer = sp;
+   static const Encoding Invalid = invalid_reg;
+-  static const uint32_t Total = 1;
+-  static const uint32_t TotalPhys = 0;
+-  static const uint32_t Allocatable = 0;
+-  static const SetType AllMask = 0;
+-  static const SetType ArgRegMask = 0;
+-  static const SetType VolatileMask = 0;
+-  static const SetType NonVolatileMask = 0;
+-  static const SetType NonAllocatableMask = 0;
+-  static const SetType AllocatableMask = 0;
++  static const uint32_t Total = 32;
++  static const uint32_t TotalPhys = 32;
++  static const uint32_t Allocatable = 28;
++  static const SetType AllMask = 0xffffffff;
++  static const SetType ArgRegMask =
++      (1 << Registers::a0) | (1 << Registers::a1) | (1 << Registers::a2) |
++      (1 << Registers::a3) | (1 << Registers::a4) | (1 << Registers::a5) |
++      (1 << Registers::a6) | (1 << Registers::a7);
++  static const SetType VolatileMask =
++      (1 << Registers::a0) | (1 << Registers::a1) | (1 << Registers::a2) |
++      (1 << Registers::a3) | (1 << Registers::a4) | (1 << Registers::a5) |
++      (1 << Registers::a6) | (1 << Registers::a7) | (1 << Registers::t0) |
++      (1 << Registers::t1) | (1 << Registers::t2) | (1 << Registers::t3) |
++      (1 << Registers::t4) | (1 << Registers::t5) | (1 << Registers::t6);
++  static const SetType NonVolatileMask =
++      (1 << Registers::s0) | (1 << Registers::s1) | (1 << Registers::s2) |
++      (1 << Registers::s3) | (1 << Registers::s4) | (1 << Registers::s5) |
++      (1 << Registers::s6) | (1 << Registers::s7) | (1 << Registers::s8) |
++      (1 << Registers::s9) | (1 << Registers::s10) | (1 << Registers::s11);
++  static const SetType NonAllocatableMask =
++      (1 << Registers::zero) | (1 << Registers::sp) | (1 << Registers::tp) |
++      (1 << Registers::gp);
++  static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
+   static const SetType JSCallMask = 0;
+   static const SetType CallMask = 0;
+ };
+@@ -65,29 +172,134 @@ typedef uint8_t PackedRegisterMask;
+ 
+ class FloatRegisters {
+  public:
+-  enum FPRegisterID { f0 = 0, invalid_reg };
++  enum FPRegisterID {
++    f0 = 0,
++    ft0 = 0,
++    f1 = 1,
++    ft1 = 1,
++    f2 = 2,
++    ft2 = 2,
++    f3 = 3,
++    ft3 = 3,
++    f4 = 4,
++    ft4 = 4,
++    f5 = 5,
++    ft5 = 5,
++    f6 = 6,
++    ft6 = 6,
++    f7 = 7,
++    ft7 = 7,
++    f8 = 8,
++    fs0 = 8,
++    f9 = 9,
++    fs1 = 9,
++    f10 = 10,
++    fa0 = 10,
++    f11 = 11,
++    fa1 = 11,
++    f12 = 12,
++    fa2 = 12,
++    f13 = 13,
++    fa3 = 13,
++    f14 = 14,
++    fa4 = 14,
++    f15 = 15,
++    fa5 = 15,
++    f16 = 16,
++    fa6 = 16,
++    f17 = 17,
++    fa7 = 17,
++    f18 = 18,
++    fs2 = 18,
++    f19 = 19,
++    fs3 = 19,
++    f20 = 20,
++    fs4 = 20,
++    f21 = 21,
++    fs5 = 21,
++    f22 = 22,
++    fs6 = 22,
++    f23 = 23,
++    fs7 = 23,
++    f24 = 24,
++    fs8 = 24,
++    f25 = 25,
++    fs9 = 25,
++    f26 = 26,
++    fs10 = 26,
++    f27 = 27,
++    fs11 = 27,
++    f28 = 28,
++    ft8 = 28,
++    f29 = 29,
++    ft9 = 29,
++    f30 = 30,
++    ft10 = 30,
++    f31 = 31,
++    ft11 = 31,
++    invalid_reg
++  };
+   typedef FPRegisterID Code;
+   typedef FPRegisterID Encoding;
+   union RegisterContent {
++    float s;
+     double d;
+   };
+ 
+   typedef uint32_t SetType;
+ 
+-  static const char* GetName(Code) { MOZ_CRASH(); }
+-  static Code FromName(const char*) { MOZ_CRASH(); }
++  static const char* GetName(uint32_t code) {
++    // clang-format off
++    static const char* const Names[] = {
++        "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
++        "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
++        "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
++        "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
++    };
++    // clang-format on
++    static_assert(Total == sizeof(Names) / sizeof(Names[0]),
++                  "Table is the correct size");
++    if (code >= Total) {
++      return "invalid";
++    }
++    return Names[code];
++  }
++  static Code FromName(const char*) {
++    for (size_t i = 0; i < Total; i++) {
++      if (strcmp(GetName(Code(i)), name) == 0) {
++        return Code(i);
++      }
++    }
++    return Invalid;
++  }
+ 
+   static const Code Invalid = invalid_reg;
+-  static const uint32_t Total = 0;
+-  static const uint32_t TotalPhys = 0;
+-  static const uint32_t Allocatable = 0;
+-  static const SetType AllMask = 0;
++  static const uint32_t Total = 32;
++  static const uint32_t TotalPhys = 32;
++  static const uint32_t Allocatable = 32;
++  static const SetType AllMask = 0xffffffff;
+   static const SetType AllDoubleMask = 0;
+   static const SetType AllSingleMask = 0;
+-  static const SetType VolatileMask = 0;
+-  static const SetType NonVolatileMask = 0;
++  static const SetType VolatileMask =
++      (1 << FloatRegisters::ft0) | (1 << FloatRegisters::ft1) |
++      (1 << FloatRegisters::ft2) | (1 << FloatRegisters::ft3) |
++      (1 << FloastRegisters::ft4) | (1 << FloatRegisters::ft5) |
++      (1 << FloatRegisters::ft6) | (1 << FloatRegisters::ft7) |
++      (1 << FloatRegisters::ft8) | (1 << FloatRegisters::ft9) |
++      (1 << FloatRegisters::ft10) | (1 << FloatRegisters::ft11) |
++      (1 << FloatRegisters::fa0) | (1 << FloatRegisters::fa1) |
++      (1 << FloatRegisters::fa2) | (1 << FloatRegisters::fa3) |
++      (1 << FloatRegisters::fa4) | (1 << FloatRegisters::fa5) |
++      (1 << FloatRegisters::fa6) | (1 << FloatRegisters::fa7);
++  static const SetType NonVolatileMask =
++      (1 << FloatRegisters::fs0) | (1 << FloatRegisters::fs1) |
++      (1 << FloatRegisters::fs2) | (1 << FloatRegisters::fs3) |
++      (1 << FloatRegisters::fs4) | (1 << FloatRegisters::fs5) |
++      (1 << FloatRegisters::fs6) | (1 << FloatRegisters::fs7) |
++      (1 << FloatRegisters::fs8) | (1 << FloatRegisters::fs9) |
++      (1 << FloatRegisters::fs10) | (1 << FloatRegisters::fs11);
+   static const SetType NonAllocatableMask = 0;
+-  static const SetType AllocatableMask = 0;
++  static const SetType AllocatableMask = AllMask & ~NonAllocatableMask;
+ };
+ 
+ template <typename T>
+@@ -99,19 +311,25 @@ struct FloatRegister {
+   typedef Codes::Encoding Encoding;
+   typedef Codes::SetType SetType;
+ 
+-  Code _;
++  enum RegType { Single, Double };
++
++  Code code_ : 5;
++  uint32_t kind_ : 2;
++
++  FloatRegister(uint32_t r) : code_(r), kind_(Double) {}
++  FloatRegister(uint32_t r, RegType k) : code_(r), kind_(k) {}
+ 
+   static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
+   static uint32_t LastBit(SetType) { MOZ_CRASH(); }
+   static FloatRegister FromCode(uint32_t) { MOZ_CRASH(); }
+-  bool isSingle() const { MOZ_CRASH(); }
+-  bool isDouble() const { MOZ_CRASH(); }
+-  bool isSimd128() const { MOZ_CRASH(); }
++  bool isSingle() const { return kind_ == Single; }
++  bool isDouble() const { return kind_ == Double; }
++  bool isSimd128() const { return false; }
+   bool isInvalid() const { MOZ_CRASH(); }
+   FloatRegister asSingle() const { MOZ_CRASH(); }
+   FloatRegister asDouble() const { MOZ_CRASH(); }
+   FloatRegister asSimd128() const { MOZ_CRASH(); }
+-  Code code() const { MOZ_CRASH(); }
++  Code code() const { return code_; }
+   Encoding encoding() const { MOZ_CRASH(); }
+   const char* name() const { MOZ_CRASH(); }
+   bool volatile_() const { MOZ_CRASH(); }
+@@ -160,11 +378,6 @@ inline bool hasMultiAlias() { MOZ_CRASH(); }
+ static const uint32_t ShadowStackSpace = 0;
+ static const uint32_t JumpImmediateRange = INT32_MAX;
+ 
+-#ifdef JS_NUNBOX32
+-static const int32_t NUNBOX32_TYPE_OFFSET = 4;
+-static const int32_t NUNBOX32_PAYLOAD_OFFSET = 0;
+-#endif
+-
+ }  // namespace jit
+ }  // namespace js
+ 
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.cpp b/js/src/jit/riscv64/Assembler-riscv64.cpp
+new file mode 100644
+index 0000000000000..0e9cf05fcc111
+--- /dev/null
++++ b/js/src/jit/riscv64/Assembler-riscv64.cpp
+@@ -0,0 +1,42 @@
++/* -*- 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/. */
++
++#include "jit/riscv64/Assembler-riscv64.h"
++
++using namespace js;
++using namespace js::jit;
++
++ABIArg ABIArgGenerator::next(MIRType type) {
++  switch (type) {
++    case MIRType::Int32:
++    case MIRType::Int64:
++    case MIRType::Pointer:
++    case MIRType::RefOrNull:
++    case MIRType::StackResults:
++      if (intRegIndex_ == NumIntArgRegs) {
++        current_ = ABIArg(stackOffset_);
++        stackOffset_ += sizeof(uintptr_t);
++        break;
++      }
++      current_ = ABIArg(IntArgRegs[intRegIndex_++]);
++      break;
++
++    case MIRType::Double:
++      if (floatRegIndex_ == NumFloatArgRegs) {
++        current_ = ABIArg(stackOffset_);
++        stackOffset_ += sizeof(double);
++        break;
++      }
++      current_ = ABIArg(FloatArgReg[floatRegIndex_++]);
++      break;
++
++    case MIRType::Float32:
++    case MIRType::Simd128:
++    default:
++      MOZ_CRASH("Unexpected argument type");
++  }
++  return current_;
++}
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
+index 55b0d3436b3d6..e1a4e0f3c7790 100644
+--- a/js/src/jit/riscv64/Assembler-riscv64.h
++++ b/js/src/jit/riscv64/Assembler-riscv64.h
+@@ -21,72 +21,82 @@ namespace jit {
+ 
+ class MacroAssembler;
+ 
+-static constexpr Register StackPointer{Registers::invalid_reg};
+-static constexpr Register FramePointer{Registers::invalid_reg};
+-static constexpr Register ReturnReg{Registers::invalid_reg2};
+-static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister ReturnSimd128Reg = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister ScratchSimd128Reg = {
+-    FloatRegisters::invalid_reg};
++static constexpr Register StackPointer{Registers::sp};
++static constexpr Register FramePointer{Registers::fp};
++static constexpr Register ReturnReg{Registers::a0};
+ static constexpr FloatRegister InvalidFloatReg = {FloatRegisters::invalid_reg};
+-
+-struct ScratchFloat32Scope : FloatRegister {
+-  explicit ScratchFloat32Scope(MacroAssembler& masm) {}
++static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::fa0, Single};
++static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::fa0, Double};
++static constexpr FloatRegister ReturnSimd128Reg = InvalidFloatReg;
++static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
++static constexpr FloatRegister ScratchFloat32Reg_ =
++    FloatRegister(FloatRegisters::ft0, FloatRegisters::Single);
++static constexpr FloatRegister ScratchDoubleReg_ = {FloatResgisters::ft0,
++                                                    FloatRegisters::Double};
++
++struct ScratchFloat32Scope : AutoFloatRegisterScope {
++  explicit ScratchFloat32Scope(MacroAssembler& masm)
++      : AutoFloatRegisterScope(masm, ScratchFloat32Reg_) {}
+ };
+ 
+-struct ScratchDoubleScope : FloatRegister {
+-  explicit ScratchDoubleScope(MacroAssembler& masm) {}
++struct ScratchDoubleScope : AutoFloatRegisterScope {
++  explicit ScratchDoubleScope(MacroAssembler& masm)
++      : AutoFloatRegisterScope(masm, ScratchDoubleReg_) {}
+ };
+ 
+ static constexpr Register OsrFrameReg{Registers::invalid_reg};
+ static constexpr Register PreBarrierReg{Registers::invalid_reg};
+ static constexpr Register InterpreterPCReg{Registers::invalid_reg};
+-static constexpr Register CallTempReg0{Registers::invalid_reg};
+-static constexpr Register CallTempReg1{Registers::invalid_reg};
+-static constexpr Register CallTempReg2{Registers::invalid_reg};
+-static constexpr Register CallTempReg3{Registers::invalid_reg};
+-static constexpr Register CallTempReg4{Registers::invalid_reg};
+-static constexpr Register CallTempReg5{Registers::invalid_reg};
++static constexpr Register CallTempReg0{Registers::t0};
++static constexpr Register CallTempReg1{Registers::t1};
++static constexpr Register CallTempReg2{Registers::t2};
++static constexpr Register CallTempReg3{Registers::t3};
++static constexpr Register CallTempReg4{Registers::t4};
++static constexpr Register CallTempReg5{Registers::t5};
++static constexpr Register CallTempReg6{Registers::t6};
+ static constexpr Register InvalidReg{Registers::invalid_reg};
+-static constexpr Register CallTempNonArgRegs[] = {InvalidReg, InvalidReg};
++static constexpr Register CallTempNonArgRegs[] = {
++    Registers::t0, Registers::t1, Registers::t2, Registers::t3,
++    Registers::t4, Registers::t5, Registers::t6};
+ static const uint32_t NumCallTempNonArgRegs = std::size(CallTempNonArgRegs);
+ 
+-static constexpr Register IntArgReg0{Registers::invalid_reg};
+-static constexpr Register IntArgReg1{Registers::invalid_reg};
+-static constexpr Register IntArgReg2{Registers::invalid_reg};
+-static constexpr Register IntArgReg3{Registers::invalid_reg};
++static constexpr Register IntArgReg0{Registers::a0};
++static constexpr Register IntArgReg1{Registers::a1};
++static constexpr Register IntArgReg2{Registers::a2};
++static constexpr Register IntArgReg3{Registers::a3};
++static constexpr Register IntArgReg4{Registers::a4};
++static constexpr Register IntArgReg5{Registers::a5};
++static constexpr Register IntArgReg6{Registers::a6};
++static constexpr Register IntArgReg7{Registers::a7};
+ static constexpr Register HeapReg{Registers::invalid_reg};
+ 
+-static constexpr Register RegExpTesterRegExpReg{Registers::invalid_reg};
+-static constexpr Register RegExpTesterStringReg{Registers::invalid_reg};
+-static constexpr Register RegExpTesterLastIndexReg{Registers::invalid_reg};
+-static constexpr Register RegExpTesterStickyReg{Registers::invalid_reg};
++// Registerd used in RegExpTester instruction (do not use ReturnReg).
++static constexpr Register RegExpTesterRegExpReg = CallTempReg0;
++static constexpr Register RegExpTesterStringReg = CallTempReg1;
++static constexpr Register RegExpTesterLastIndexReg = CallTempReg2;
+ 
+-static constexpr Register RegExpMatcherRegExpReg{Registers::invalid_reg};
+-static constexpr Register RegExpMatcherStringReg{Registers::invalid_reg};
+-static constexpr Register RegExpMatcherLastIndexReg{Registers::invalid_reg};
+-static constexpr Register RegExpMatcherStickyReg{Registers::invalid_reg};
++// Registerd used in RegExpMatcher instruction (do not use JSReturnOperand).
++static constexpr Register RegExpMatcherRegExpReg = CallTempReg0;
++static constexpr Register RegExpMatcherStringReg = CallTempReg1;
++static constexpr Register RegExpMatcherLastIndexReg = CallTempReg2;
+ 
+-// Uses |invalid_reg2| to avoid static_assert failures.
+-static constexpr Register JSReturnReg_Type{Registers::invalid_reg2};
+-static constexpr Register JSReturnReg_Data{Registers::invalid_reg2};
+-static constexpr Register JSReturnReg{Registers::invalid_reg2};
++static constexpr Register JSReturnReg_Type{Registers::a3};
++static constexpr Register JSReturnReg_Data{Registers::a2};
++static constexpr Register JSReturnReg{Registers::a2};
+ 
+-static constexpr ValueOperand JSReturnOperand(InvalidReg);
+-static constexpr Register64 ReturnReg64(InvalidReg);
++static constexpr ValueOperand ValueOperand(JSReturnReg);
++static constexpr Register64 ReturnReg64(a0);
+ 
+-static constexpr Register ABINonArgReg0{Registers::invalid_reg};
+-static constexpr Register ABINonArgReg1{Registers::invalid_reg};
+-static constexpr Register ABINonArgReg2{Registers::invalid_reg};
+-static constexpr Register ABINonArgReg3{Registers::invalid_reg};
+-static constexpr Register ABINonArgReturnReg0{Registers::invalid_reg};
+-static constexpr Register ABINonArgReturnReg1{Registers::invalid_reg};
+-static constexpr Register ABINonVolatileReg{Registers::invalid_reg};
+-static constexpr Register ABINonArgReturnVolatileReg{Registers::invalid_reg};
++static constexpr Register ABINonArgReg0{Registers::s0};
++static constexpr Register ABINonArgReg1{Registers::s1};
++static constexpr Register ABINonArgReg2{Registers::s2};
++static constexpr Register ABINonArgReg3{Registers::s3};
++static constexpr Register ABINonArgReturnReg0{Registers::s0};
++static constexpr Register ABINonArgReturnReg1{Registers::s1};
++static constexpr Register ABINonVolatileReg{Registers::fp};
++static constexpr Register ABINonArgReturnVolatileReg{Registers::ra};
+ 
+-static constexpr FloatRegister ABINonArgDoubleReg = {
+-    FloatRegisters::invalid_reg};
++static constexpr FloatRegister ABINonArgDoubleReg = {FloatRegisters::fs0, Double};
+ 
+ static constexpr Register WasmTableCallScratchReg0{Registers::invalid_reg};
+ static constexpr Register WasmTableCallScratchReg1{Registers::invalid_reg};
+@@ -95,7 +105,7 @@ static constexpr Register WasmTableCallIndexReg{Registers::invalid_reg};
+ static constexpr Register WasmTlsReg{Registers::invalid_reg};
+ static constexpr Register WasmJitEntryReturnScratch{Registers::invalid_reg};
+ 
+-static constexpr uint32_t ABIStackAlignment = 4;
++static constexpr uint32_t ABIStackAlignment = 16;
+ static constexpr uint32_t CodeAlignment = 16;
+ static constexpr uint32_t JitStackAlignment = 8;
+ static constexpr uint32_t JitStackValueAlignment =
+@@ -103,8 +113,20 @@ static constexpr uint32_t JitStackValueAlignment =
+ 
+ static const Scale ScalePointer = TimesOne;
+ 
++class Instruction;
++typedef js::jit::AssemblerBuffer<1024, Instruction> RISCVBuffer;
++
+ class Assembler : public AssemblerShared {
+  public:
++  enum RISCVCondition : uint32_t {
++    EQ = 0b000,
++    NE = 0b001,
++    LT = 0b100,
++    GE = 0b101,
++    LTU = 0b110,
++    GEU = 0b111,
++  };
++
+   enum Condition {
+     Equal,
+     NotEqual,
+@@ -143,6 +165,10 @@ class Assembler : public AssemblerShared {
+     DoubleLessThanOrEqualOrUnordered
+   };
+ 
++  RISCVBuffer m_buffer;
++
++  BufferOffset nextOffset() { return m_buffer.nextOffset(); }
++
+   static Condition InvertCondition(Condition) { MOZ_CRASH(); }
+ 
+   static DoubleCondition InvertCondition(DoubleCondition) { MOZ_CRASH(); }
+@@ -162,7 +188,7 @@ class Assembler : public AssemblerShared {
+   static void ToggleToCmp(CodeLocationLabel) { MOZ_CRASH(); }
+   static void ToggleCall(CodeLocationLabel, bool) { MOZ_CRASH(); }
+ 
+-  static void Bind(uint8_t*, const CodeLabel&) { MOZ_CRASH(); }
++  static void Bind(uint8_t* rawCode, const CodeLabel& label) { MOZ_CRASH(); }
+ 
+   static uintptr_t GetPointer(uint8_t*) { MOZ_CRASH(); }
+ 
+@@ -174,24 +200,66 @@ class Assembler : public AssemblerShared {
+   }
+ 
+   void setUnlimitedBuffer() { MOZ_CRASH(); }
++
++  MOZ_ALWAYS_INLINE BufferOffset writeInst(uint32_t x) {
++    MOZ_ASSERT(hasCreator());
++    return m_buffer.putInt(x);
++  }
++};
++
++class Instruction {
++ protected:
++  uint32_t data;
++
++  // Standard constructor
++  Instruction(uint32_t data_) : data(data_) {}
++
++ public:
++  uint32_t encode() const { return data; }
++
++  void setData(uint32_t data) { this->data = data; }
++  Instruction* next();
++  const uint32_t* raw() const { return &data; }
++  uint32_t size() const { return sizeof(data); }
+ };
+ 
+ class Operand {
+  public:
+-  explicit Operand(const Address&) { MOZ_CRASH(); }
+-  explicit Operand(const Register) { MOZ_CRASH(); }
++  enum Kind { REG };
++
++ private
++  Kind kind_ : 4;
++  uint32_t reg_ : 5;
++  int32_t offset_;
++
++ public:
++  explicit Operand(const Register reg)
++      : kind_(REG), reg_(reg.code()), offset_(0) {}
+   explicit Operand(const FloatRegister) { MOZ_CRASH(); }
+-  explicit Operand(Register, Imm32) { MOZ_CRASH(); }
+-  explicit Operand(Register, int32_t) { MOZ_CRASH(); }
++  explicit Operand(const Address& adress) { MOZ_CRASH(); }
++  explicit Operand(Register reg, Imm32 offset)
++      : kind_(REG), reg_(reg.code()), offset_(offset.value) {}
++  explicit Operand(Register reg, int32_t offset)
++      : kind_(REG), reg_(reg.code()), offset_(offset) {}
++
++  Kind kind() const { return kind_; }
+ };
+ 
+ class ABIArgGenerator {
+  public:
+-  ABIArgGenerator() { MOZ_CRASH(); }
+-  ABIArg next(MIRType) { MOZ_CRASH(); }
+-  ABIArg& current() { MOZ_CRASH(); }
+-  uint32_t stackBytesConsumedSoFar() const { MOZ_CRASH(); }
+-  void increaseStackOffset(uint32_t) { MOZ_CRASH(); }
++  ABIArgGenerator()
++      : intRegIndex_(0), floatRegIndex_(0), stackOffset_(0), current_() {}
++
++  ABIArg next(MIRType);
++  ABIArg& current() { return current_; }
++  uint32_t stackBytesConsumedSoFar() const { return stackOffset_; }
++  void increaseStackOffset(uint32_t bytes) { stackOffset_ += bytes; }
++
++ private:
++  unsigned intRegIndex_;
++  unsigned floatRegIndex_;
++  uint32_t stackOffset_;
++  ABIArg current_;
+ };
+ 
+ }  // namespace jit
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+index a9265bb7bd44b..94c9fe75a438a 100644
+--- a/js/src/jit/riscv64/MacroAssembler-riscv64.h
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+@@ -69,7 +69,7 @@ class MacroAssemblerRiscv64 : public Assembler {
+   void copyPreBarrierTable(uint8_t*) { MOZ_CRASH(); }
+   void processCodeLabels(uint8_t*) { MOZ_CRASH(); }
+ 
+-  void flushBuffer() { MOZ_CRASH(); }
++  void flushBuffer() { m_buffer.flushPool(); }
+ 
+   template <typename T>
+   void bind(T) {
+@@ -83,11 +83,16 @@ class MacroAssemblerRiscv64 : public Assembler {
+   void jump(T) {
+     MOZ_CRASH();
+   }
+-  void writeCodePointer(CodeLabel* label) { MOZ_CRASH(); }
++  void writeCodePointer(CodeLabel* label) {
++    MOZ_ASSERT(hasCreator());
++    m_buffer.ensureSpace(sizeof(uintptr_t));
++    BufferOffset off = m_buffer.putInt64Unchecked(-1);
++    label->patchAt()->bind(off.getOffset());
++  }
+   void haltingAlign(size_t) { MOZ_CRASH(); }
+   void nopAlign(size_t) { MOZ_CRASH(); }
+   void checkStackAlignment() { MOZ_CRASH(); }
+-  uint32_t currentOffset() { MOZ_CRASH(); }
++  uint32_t currentOffset() { return nextOffset().getOffset(); }
+ 
+   void nop() { MOZ_CRASH(); }
+   void breakpoint() { MOZ_CRASH(); }
+@@ -440,10 +445,6 @@ class MacroAssemblerRiscv64 : public Assembler {
+   // Instrumentation for entering and leaving the profiler.
+   void profilerEnterFrame(Register, Register) { MOZ_CRASH(); }
+   void profilerExitFrame() { MOZ_CRASH(); }
+-
+-#ifdef JS_NUNBOX32
+-  Address ToType(Address) { MOZ_CRASH(); }
+-#endif
+ };
+ 
+ typedef MacroAssemblerRiscv64 MacroAssemblerSpecific;
+From 5c74e6bed2ed7f68c8ef30c0967aaea41b169476 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Fri, 10 Jun 2022 12:52:42 +0900
+Subject: [PATCH] Fix spidermonkey
+
+---
+ js/src/jit/riscv64/Assembler-riscv64.h          |  2 +-
+ js/src/jit/riscv64/MacroAssembler-riscv64-inl.h | 12 ++++++++++++
+ js/src/jit/riscv64/SharedICHelpers-riscv64.h    |  3 +++
+ js/src/jit/riscv64/SharedICRegisters-riscv64.h  |  2 +-
+ 4 files changed, 17 insertions(+), 2 deletions(-)
+ create mode 100644 js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
+
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
+index e1a4e0f3c7790..2cea8373d2246 100644
+--- a/js/src/jit/riscv64/Assembler-riscv64.h
++++ b/js/src/jit/riscv64/Assembler-riscv64.h
+@@ -11,9 +11,9 @@
+ 
+ #include <stdint.h>
+ 
+-#include "jit/riscv64/Architecture-riscv64.h"
+ #include "jit/Registers.h"
+ #include "jit/RegisterSets.h"
++#include "jit/riscv64/Architecture-riscv64.h"
+ #include "jit/shared/Assembler-shared.h"
+ 
+ namespace js {
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
+new file mode 100644
+index 0000000000000..fa5ef6e87d0a9
+--- /dev/null
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
+@@ -0,0 +1,12 @@
++/* -*- 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_MacroAssembler_riscv64_inl_h
++#define jit_riscv64_MacroAssembler_riscv64_inl_h
++
++#include "jit/riscv64/MacroAssembler-riscv64.h"
++
++#endif
+diff --git a/js/src/jit/riscv64/SharedICHelpers-riscv64.h b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
+index 15734c11f5738..205b6615dad5f 100644
+--- a/js/src/jit/riscv64/SharedICHelpers-riscv64.h
++++ b/js/src/jit/riscv64/SharedICHelpers-riscv64.h
+@@ -7,6 +7,9 @@
+ #ifndef jit_riscv64_SharedICHelpers_riscv64_h
+ #define jit_riscv64_SharedICHelpers_riscv64_h
+ 
++#include "jit/MacroAssembler.h"
++#include "jit/SharedICRegisters.h"
++
+ namespace js {
+ namespace jit {
+ 
+diff --git a/js/src/jit/riscv64/SharedICRegisters-riscv64.h b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+index 72183cb02c2c0..29b8c71fa3386 100644
+--- a/js/src/jit/riscv64/SharedICRegisters-riscv64.h
++++ b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+@@ -7,9 +7,9 @@
+ #ifndef jit_riscv64_SharedICRegisters_riscv64_h
+ #define jit_riscv64_SharedICRegisters_riscv64_h
+ 
+-#include "jit/riscv64/MacroAssembler-riscv64.h"
+ #include "jit/Registers.h"
+ #include "jit/RegisterSets.h"
++#include "jit/riscv64/MacroAssembler-riscv64.h"
+ 
+ namespace js {
+ namespace jit {
+From b33c1094612da3623ae23f9ddbe23976fdcbe1f0 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Sun, 26 Jun 2022 11:32:25 +0900
+Subject: [PATCH] ...
+
+---
+ js/src/jit/MacroAssembler-inl.h               |  2 +
+ js/src/jit/MacroAssembler.h                   |  8 ++-
+ js/src/jit/moz.build                          |  2 +-
+ js/src/jit/riscv64/Architecture-riscv64.h     | 72 ++++++++++++-------
+ js/src/jit/riscv64/Assembler-riscv64.h        | 56 +++++++++------
+ js/src/jit/riscv64/MacroAssembler-riscv64.h   | 38 +++++-----
+ .../jit/riscv64/SharedICRegisters-riscv64.h   |  8 +--
+ js/src/util/Poison.h                          |  2 +
+ js/src/wasm/WasmCompile.cpp                   |  2 +
+ js/src/wasm/WasmFrameIter.cpp                 |  6 ++
+ 10 files changed, 120 insertions(+), 76 deletions(-)
+
+diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h
+index 5ed4ac74589e3..1c208e676de57 100644
+--- a/js/src/jit/MacroAssembler-inl.h
++++ b/js/src/jit/MacroAssembler-inl.h
+@@ -39,6 +39,8 @@
+ #  include "jit/mips64/MacroAssembler-mips64-inl.h"
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  include "jit/loong64/MacroAssembler-loong64-inl.h"
++#elif defined(JS_CODEGEN_RISCV64)
++#  include "jit/riscv64/MacroAssembler-riscv64-inl.h"
+ #elif defined(JS_CODEGEN_WASM32)
+ #  include "jit/wasm32/MacroAssembler-wasm32-inl.h"
+ #elif !defined(JS_CODEGEN_NONE)
+diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
+index a7d4800328690..0737468991181 100644
+--- a/js/src/jit/MacroAssembler.h
++++ b/js/src/jit/MacroAssembler.h
+@@ -96,8 +98,8 @@
+ //   }
+ //   ////}}} check_macroassembler_style
+
+-#define ALL_ARCH mips32, mips64, arm, arm64, x86, x64, loong64, wasm32
+-#define ALL_SHARED_ARCH arm, arm64, loong64, x86_shared, mips_shared, wasm32
++#define ALL_ARCH mips32, mips64, arm, arm64, x86, x64, loong64, riscv64, wasm32
++#define ALL_SHARED_ARCH arm, arm64, loong64, riscv64, x86_shared, mips_shared, wasm32
+
+ // * How this macro works:
+ //
+@@ -144,6 +146,7 @@
+ #define DEFINED_ON_mips64
+ #define DEFINED_ON_mips_shared
+ #define DEFINED_ON_loong64
++#define DEFINED_ON_riscv64
+ #define DEFINED_ON_wasm32
+ #define DEFINED_ON_none
+
+@@ -177,6 +180,9 @@
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  undef DEFINED_ON_loong64
+ #  define DEFINED_ON_loong64 define
++#elif defined(JS_CODEGEN_RISCV64)
++#  undef DEFINED_ON_riscv64
++#  define DEFINED_ON_riscv64 define
+ #elif defined(JS_CODEGEN_WASM32)
+ #  undef DEFINED_ON_wasm32
+ #  define DEFINED_ON_wasm32 define
+diff --git a/js/src/jit/riscv64/Architecture-riscv64.h b/js/src/jit/riscv64/Architecture-riscv64.h
+index 2b5495ce5f3d8..a676dc142ec7e 100644
+--- a/js/src/jit/riscv64/Architecture-riscv64.h
++++ b/js/src/jit/riscv64/Architecture-riscv64.h
+@@ -107,10 +107,10 @@ class Registers {
+     static_assert(sizeof(SetType) == 4, "SetType must be 32 bits");
+     return mozilla::CountPopulation32(x);
+   }
+-  static uint32_t FirstBit(SetType) {
++  static uint32_t FirstBit(SetType x) {
+     return mozilla::CountTrailingZeroes32(x);
+   }
+-  static uint32_t LastBit(SetType) {
++  static uint32_t LastBit(SetType x) {
+     return 31 - mozilla::CountLeadingZeroes32(x);
+   }
+
+@@ -239,15 +239,18 @@ class FloatRegisters {
+     ft11 = 31,
+     invalid_reg
+   };
+-  typedef FPRegisterID Code;
++
++  typedef uint8_t Code;
+   typedef FPRegisterID Encoding;
++  typedef uint32_t SetType;
++
++  enum Kind : uint8_t { Double, Single };
++
+   union RegisterContent {
+     float s;
+     double d;
+   };
+ 
+-  typedef uint32_t SetType;
+-
+   static const char* GetName(uint32_t code) {
+     // clang-format off
+     static const char* const Names[] = {
+@@ -264,16 +267,19 @@ class FloatRegisters {
+     }
+     return Names[code];
+   }
+-  static Code FromName(const char*) {
++  static Code FromName(const char* name) {
+     for (size_t i = 0; i < Total; i++) {
+-      if (strcmp(GetName(Code(i)), name) == 0) {
++      if (strcmp(GetName(i), name) == 0) {
+         return Code(i);
+       }
+     }
++
+     return Invalid;
+   }
+ 
+-  static const Code Invalid = invalid_reg;
++  static constexpr Encoding encoding(Code c) { return Encoding(c & 31); }
++
++  static const Encoding Invalid = invalid_reg;
+   static const uint32_t Total = 32;
+   static const uint32_t TotalPhys = 32;
+   static const uint32_t Allocatable = 32;
+@@ -283,7 +289,7 @@ class FloatRegisters {
+   static const SetType VolatileMask =
+       (1 << FloatRegisters::ft0) | (1 << FloatRegisters::ft1) |
+       (1 << FloatRegisters::ft2) | (1 << FloatRegisters::ft3) |
+-      (1 << FloastRegisters::ft4) | (1 << FloatRegisters::ft5) |
++      (1 << FloatRegisters::ft4) | (1 << FloatRegisters::ft5) |
+       (1 << FloatRegisters::ft6) | (1 << FloatRegisters::ft7) |
+       (1 << FloatRegisters::ft8) | (1 << FloatRegisters::ft9) |
+       (1 << FloatRegisters::ft10) | (1 << FloatRegisters::ft11) |
+@@ -307,31 +313,39 @@ class TypedRegisterSet;
+ 
+ struct FloatRegister {
+   typedef FloatRegisters Codes;
+-  typedef Codes::Code Code;
++  typedef size_t Code;
+   typedef Codes::Encoding Encoding;
+   typedef Codes::SetType SetType;
++  typedef Codes::Kind Kind;
+ 
+-  enum RegType { Single, Double };
+-
+-  Code code_ : 5;
+-  uint32_t kind_ : 2;
++ private:
++  uint8_t encoding_;
++  uint8_t kind_;
++  bool invalid_;
+ 
+-  FloatRegister(uint32_t r) : code_(r), kind_(Double) {}
+-  FloatRegister(uint32_t r, RegType k) : code_(r), kind_(k) {}
++ public:
++  constexpr FloatRegister(Encoding encoding)
++      : encoding_(encoding), kind_(FloatRegisters::Double), invalid_(false) {}
++  constexpr FloatRegister(Encoding encoding, Kind kind)
++      : encoding_(encoding), kind_(kind), invalid_(false) {}
++  constexpr FloatRegister()
++      : encoding_(0), kind_(FloatRegisters::Double), invalid_(true) {}
+ 
+   static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
+   static uint32_t LastBit(SetType) { MOZ_CRASH(); }
+-  static FloatRegister FromCode(uint32_t) { MOZ_CRASH(); }
+-  bool isSingle() const { return kind_ == Single; }
+-  bool isDouble() const { return kind_ == Double; }
++  static FloatRegister FromCode(uint32_t i) {
++    return FloatRegister(FloatRegisters::encoding(i), FloatRegisters::Double);
++  }
++  bool isSingle() const { return kind_ == FloatRegisters::Single; }
++  bool isDouble() const { return kind_ == FloatRegisters::Double; }
+   bool isSimd128() const { return false; }
+-  bool isInvalid() const { MOZ_CRASH(); }
++  bool isInvalid() const { return invalid_; }
+   FloatRegister asSingle() const { MOZ_CRASH(); }
+   FloatRegister asDouble() const { MOZ_CRASH(); }
+   FloatRegister asSimd128() const { MOZ_CRASH(); }
+-  Code code() const { return code_; }
+-  Encoding encoding() const { MOZ_CRASH(); }
+-  const char* name() const { MOZ_CRASH(); }
++  Code code() const { MOZ_CRASH(); }
++  Encoding encoding() const { return Encoding(encoding_); }
++  const char* name() const { return FloatRegisters::GetName(code()); }
+   bool volatile_() const { MOZ_CRASH(); }
+   bool operator!=(FloatRegister) const { MOZ_CRASH(); }
+   bool operator==(FloatRegister) const { MOZ_CRASH(); }
+@@ -361,9 +375,15 @@ struct FloatRegister {
+   static T ReduceSetForPush(T) {
+     MOZ_CRASH();
+   }
+-  uint32_t getRegisterDumpOffsetInBytes() { MOZ_CRASH(); }
+-  static uint32_t SetSize(SetType x) { MOZ_CRASH(); }
+-  static Code FromName(const char* name) { MOZ_CRASH(); }
++  uint32_t getRegisterDumpOffsetInBytes() {
++    MOZ_CRASH();
++    return 0;
++  }
++  static uint32_t SetSize(SetType x) {
++    MOZ_CRASH();
++    return 0;
++  }
++  static Code FromName(const char* name) { return 0; }
+ 
+   // This is used in static initializers, so produce a bogus value instead of
+   // crashing.
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
+index 2cea8373d2246..e695662be5cba 100644
+--- a/js/src/jit/riscv64/Assembler-riscv64.h
++++ b/js/src/jit/riscv64/Assembler-riscv64.h
+@@ -7,32 +7,45 @@
+ #ifndef jit_riscv64_Assembler_riscv64_h
+ #define jit_riscv64_Assembler_riscv64_h
+ 
+-#include "mozilla/Assertions.h"
+-
+-#include <stdint.h>
++#include "mozilla/Sprintf.h"
++#include <iterator>
+ 
++#include "jit/CompactBuffer.h"
++#include "jit/JitCode.h"
++#include "jit/JitSpewer.h"
+ #include "jit/Registers.h"
+ #include "jit/RegisterSets.h"
+ #include "jit/riscv64/Architecture-riscv64.h"
+ #include "jit/shared/Assembler-shared.h"
++#include "jit/shared/Disassembler-shared.h"
++#include "jit/shared/IonAssemblerBuffer.h"
++#include "wasm/WasmTypeDecls.h"
+ 
+ namespace js {
+ namespace jit {
+ 
+ class MacroAssembler;
+ 
++static constexpr Register t0{Registers::t0};
++static constexpr Register t1{Registers::t1};
++static constexpr Register t2{Registers::t2};
++static constexpr Register t3{Registers::t3};
++static constexpr Register t4{Registers::t4};
++static constexpr Register t5{Registers::t5};
++static constexpr Register t6{Registers::t6};
++
+ static constexpr Register StackPointer{Registers::sp};
+ static constexpr Register FramePointer{Registers::fp};
+ static constexpr Register ReturnReg{Registers::a0};
+-static constexpr FloatRegister InvalidFloatReg = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister ReturnFloat32Reg = {FloatRegisters::fa0, Single};
+-static constexpr FloatRegister ReturnDoubleReg = {FloatRegisters::fa0, Double};
++static constexpr FloatRegister InvalidFloatReg;
++static constexpr FloatRegister ReturnFloat32Reg{FloatRegisters::fa0,
++                                                FloatRegisters::Single};
++static constexpr FloatRegister ReturnDoubleReg{FloatRegisters::fa0,
++                                               FloatRegisters::Double};
+ static constexpr FloatRegister ReturnSimd128Reg = InvalidFloatReg;
+ static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
+-static constexpr FloatRegister ScratchFloat32Reg_ =
+-    FloatRegister(FloatRegisters::ft0, FloatRegisters::Single);
+-static constexpr FloatRegister ScratchDoubleReg_ = {FloatResgisters::ft0,
+-                                                    FloatRegisters::Double};
++static constexpr FloatRegister ScratchFloat32Reg_ = InvalidFloatReg;
++static constexpr FloatRegister ScratchDoubleReg_ = InvalidFloatReg;
+ 
+ struct ScratchFloat32Scope : AutoFloatRegisterScope {
+   explicit ScratchFloat32Scope(MacroAssembler& masm)
+@@ -47,17 +60,14 @@ struct ScratchDoubleScope : AutoFloatRegisterScope {
+ static constexpr Register OsrFrameReg{Registers::invalid_reg};
+ static constexpr Register PreBarrierReg{Registers::invalid_reg};
+ static constexpr Register InterpreterPCReg{Registers::invalid_reg};
+-static constexpr Register CallTempReg0{Registers::t0};
+-static constexpr Register CallTempReg1{Registers::t1};
+-static constexpr Register CallTempReg2{Registers::t2};
+-static constexpr Register CallTempReg3{Registers::t3};
+-static constexpr Register CallTempReg4{Registers::t4};
+-static constexpr Register CallTempReg5{Registers::t5};
+-static constexpr Register CallTempReg6{Registers::t6};
++static constexpr Register CallTempReg0 = t0;
++static constexpr Register CallTempReg1 = t1;
++static constexpr Register CallTempReg2 = t2;
++static constexpr Register CallTempReg3 = t3;
++static constexpr Register CallTempReg4 = t4;
++static constexpr Register CallTempReg5 = t5;
+ static constexpr Register InvalidReg{Registers::invalid_reg};
+-static constexpr Register CallTempNonArgRegs[] = {
+-    Registers::t0, Registers::t1, Registers::t2, Registers::t3,
+-    Registers::t4, Registers::t5, Registers::t6};
++static constexpr Register CallTempNonArgRegs[] = {t0, t1, t2, t3, t4, t5, t6};
+ static const uint32_t NumCallTempNonArgRegs = std::size(CallTempNonArgRegs);
+ 
+ static constexpr Register IntArgReg0{Registers::a0};
+@@ -85,7 +95,7 @@ static constexpr Register JSReturnReg_Data{Registers::a2};
+ static constexpr Register JSReturnReg{Registers::a2};
+ 
+ static constexpr ValueOperand ValueOperand(JSReturnReg);
+-static constexpr Register64 ReturnReg64(a0);
++static constexpr Register64 ReturnReg64(ReturnReg);
+ 
+ static constexpr Register ABINonArgReg0{Registers::s0};
+ static constexpr Register ABINonArgReg1{Registers::s1};
+@@ -96,7 +106,7 @@ static constexpr Register ABINonArgReturnReg1{Registers::s1};
+ static constexpr Register ABINonVolatileReg{Registers::fp};
+ static constexpr Register ABINonArgReturnVolatileReg{Registers::ra};
+ 
+-static constexpr FloatRegister ABINonArgDoubleReg = {FloatRegisters::fs0, Double};
++static constexpr FloatRegister ABINonArgDoubleReg = InvalidFloatReg;
+ 
+ static constexpr Register WasmTableCallScratchReg0{Registers::invalid_reg};
+ static constexpr Register WasmTableCallScratchReg1{Registers::invalid_reg};
+@@ -227,7 +237,7 @@ class Operand {
+  public:
+   enum Kind { REG };
+ 
+- private
++ private:
+   Kind kind_ : 4;
+   uint32_t reg_ : 5;
+   int32_t offset_;
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+index 94c9fe75a438a..6466946454e4f 100644
+--- a/js/src/jit/riscv64/MacroAssembler-riscv64.h
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+@@ -7,31 +7,36 @@
+ #ifndef jit_riscv64_MacroAssembler_riscv64_h
+ #define jit_riscv64_MacroAssembler_riscv64_h
+ 
+-#include <iterator>
+-
+-#include "jit/MoveResolver.h"
+ #include "jit/riscv64/Assembler-riscv64.h"
+-#include "wasm/WasmTypeDecls.h"
++#include "jit/MoveResolver.h"
++#include "wasm/WasmBuiltins.h"
+ 
+ namespace js {
+ namespace jit {
+ 
+-class CompactBufferReader;
+-
+-class ScratchTagScope {
++class ScratchTagScope : public SecondScratchRegisterScope {
+  public:
+-  ScratchTagScope(MacroAssembler&, const ValueOperand) {}
+-  operator Register() { MOZ_CRASH(); }
+-  void release() { MOZ_CRASH(); }
+-  void reacquire() { MOZ_CRASH(); }
++  ScratchTagScope(MacroAssembler& masm, const ValueOperand&)
++      : SecondScratchRegisterScope(masm) {}
+ };
+ 
+ class ScratchTagScopeRelease {
++  ScratchTagScope* ts_;
++
+  public:
+-  explicit ScratchTagScopeRelease(ScratchTagScope*) {}
++  explicit ScratchTagScopeRelease(ScratchTagScope* ts) : ts_(ts) {
++    ts_->release();
++  }
++
++  ~ScratchTagScopeRelease() { ts_->reacquire(); }
+ };
+ 
+ class MacroAssemblerRiscv64 : public Assembler {
++ protected:
++  // Perform a downcast. Should be removed by Bug 996602.
++  MacroAssembler& asMasm();
++  const MacroAssembler& asMasm() const;
++
+  public:
+   MacroAssemblerRiscv64() { MOZ_CRASH(); }
+ 
+@@ -52,13 +57,6 @@ class MacroAssemblerRiscv64 : public Assembler {
+ 
+   void assertNoGCThings() const { MOZ_CRASH(); }
+ 
+-  static void TraceJumpRelocations(JSTracer*, JitCode*, CompactBufferReader&) {
+-    MOZ_CRASH();
+-  }
+-  static void TraceDataRelocations(JSTracer*, JitCode*, CompactBufferReader&) {
+-    MOZ_CRASH();
+-  }
+-
+   static bool SupportsFloatingPoint() { return false; }
+   static bool SupportsUnalignedAccesses() { return false; }
+   static bool SupportsFastUnalignedFPAccesses() { return false; }
+@@ -69,7 +67,7 @@ class MacroAssemblerRiscv64 : public Assembler {
+   void copyPreBarrierTable(uint8_t*) { MOZ_CRASH(); }
+   void processCodeLabels(uint8_t*) { MOZ_CRASH(); }
+ 
+-  void flushBuffer() { m_buffer.flushPool(); }
++  void flushBuffer() {}
+ 
+   template <typename T>
+   void bind(T) {
+diff --git a/js/src/jit/riscv64/SharedICRegisters-riscv64.h b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+index 29b8c71fa3386..87e14461f65ba 100644
+--- a/js/src/jit/riscv64/SharedICRegisters-riscv64.h
++++ b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+@@ -27,10 +27,10 @@ static constexpr Register ICStubReg{Registers::invalid_reg};
+ static constexpr Register ExtractTemp0{Registers::invalid_reg};
+ static constexpr Register ExtractTemp1{Registers::invalid_reg};
+ 
+-static constexpr FloatRegister FloatReg0 = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister FloatReg1 = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister FloatReg2 = {FloatRegisters::invalid_reg};
+-static constexpr FloatRegister FloatReg3 = {FloatRegisters::invalid_reg};
++static constexpr FloatRegister FloatReg0;
++static constexpr FloatRegister FloatReg1;
++static constexpr FloatRegister FloatReg2;
++static constexpr FloatRegister FloatReg3;
+ 
+ }  // namespace jit
+ }  // namespace js
+diff --git a/js/src/util/Poison.h b/js/src/util/Poison.h
+index cb8e1abc64b12..a6a2d2f12b80f 100644
+--- a/js/src/util/Poison.h
++++ b/js/src/util/Poison.h
+@@ -95,6 +95,8 @@ const uint8_t JS_SCOPE_DATA_TRAILING_NAMES_PATTERN = 0xCC;
+ #  define JS_SWEPT_CODE_PATTERN 0x01  // undefined instruction
+ #elif defined(JS_CODEGEN_LOONG64)
+ #  define JS_SWEPT_CODE_PATTERN 0x01  // undefined instruction
++#elif defined(JS_CODEGEN_RISCV64)
++#  define JS_SWEPT_CODE_PATTERN 0x01  // undefined instruction
+ #else
+ #  error "JS_SWEPT_CODE_PATTERN not defined for this platform"
+ #endif
+diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp
+index 26534bca4ea47..403e26414bbf1 100644
+--- a/js/src/wasm/WasmCompile.cpp
++++ b/js/src/wasm/WasmCompile.cpp
+@@ -74,6 +74,8 @@
+ #elif defined(JS_CODEGEN_LOONG64)
+   MOZ_ASSERT(jit::GetLOONG64Flags() <= (UINT32_MAX >> ARCH_BITS));
+   return LOONG64 | (jit::GetLOONG64Flags() << ARCH_BITS);
++#elif defined(JS_CODEGEN_RISCV64)
++  return 0;
+ #elif defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_WASM32)
+   return 0;
+ #else
+diff --git a/js/src/wasm/WasmFrameIter.cpp b/js/src/wasm/WasmFrameIter.cpp
+index e612e057049c0..0ce345328713a 100644
+--- a/js/src/wasm/WasmFrameIter.cpp
++++ b/js/src/wasm/WasmFrameIter.cpp
+@@ -397,6 +397,12 @@
+ static const unsigned SetFP = 20;
+ static const unsigned PoppedFP = 4;
+ static const unsigned PoppedFPJitEntry = 0;
++#elif defined(JS_CODEGEN_RISCV64)
++static const unsigned PushedRetAddr = 0;
++static const unsigned PushedFP = 1;
++static const unsigned SetFP = 2;
++static const unsigned PoppedFP = 3;
++static const unsigned PoppedFPJitEntry = 4;
+ #elif defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_WASM32)
+ // Synthetic values to satisfy asserts and avoid compiler warnings.
+ static const unsigned PushedRetAddr = 0;
+From 8356d013017edc7c71e95bba73a054e6d2e44e28 Mon Sep 17 00:00:00 2001
+From: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+Date: Mon, 27 Jun 2022 21:33:34 +0900
+Subject: [PATCH] ...
+
+---
+ js/src/jit/FlushICache.h                      |   2 +-
+ js/src/jit/MacroAssembler.cpp                 |   2 +
+ js/src/jit/MacroAssembler.h                   | 174 +++++++++---------
+ js/src/jit/riscv64/Assembler-riscv64.cpp      |  11 +-
+ js/src/jit/riscv64/Assembler-riscv64.h        |  31 +++-
+ .../jit/riscv64/MacroAssembler-riscv64-inl.h  |   6 +
+ js/src/jit/riscv64/MacroAssembler-riscv64.h   |  13 +-
+ .../jit/riscv64/SharedICRegisters-riscv64.h   |   2 +-
+ js/src/jit/shared/Assembler-shared.h          |   5 +-
+ js/src/wasm/WasmBCMemory.cpp                  |  27 +++
+ js/src/wasm/WasmSignalHandlers.cpp            |  11 +-
+ 11 files changed, 175 insertions(+), 109 deletions(-)
+
+diff --git a/js/src/jit/FlushICache.h b/js/src/jit/FlushICache.h
+index 42b1fb045ce6d..feeae3c793c23 100644
+--- a/js/src/jit/FlushICache.h
++++ b/js/src/jit/FlushICache.h
+@@ -25,7 +25,7 @@ inline void FlushICache(void* code, size_t size,
+ 
+ #elif (defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)) ||   \
+     (defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)) || \
+-    defined(JS_CODEGEN_LOONG64)
++    defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
+ 
+ extern void FlushICache(void* code, size_t size, bool codeIsThreadLocal = true);
+ 
+diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
+index 3abc601bec090..066560150924b 100644
+--- a/js/src/jit/MacroAssembler.cpp
++++ b/js/src/jit/MacroAssembler.cpp
+@@ -4068,6 +4068,8 @@
+   ma_dsll(temp1, temp1, temp3);
+ #elif JS_CODEGEN_LOONG64
+   as_sll_d(temp1, temp1, temp3);
++#elif JS_CODEGEN_RISCV64
++  MOZ_CRASH();
+ #elif JS_CODEGEN_WASM32
+   MOZ_CRASH();
+ #elif JS_CODEGEN_NONE
+diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
+index 0737468991181..3395a139d36c7 100644
+--- a/js/src/jit/MacroAssembler.h
++++ b/js/src/jit/MacroAssembler.h
+
+@@ -497,10 +503,10 @@
+
+   // The size of the area used by PushRegsInMask.
+   size_t PushRegsInMaskSizeInBytes(LiveRegisterSet set)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared, riscv64);
+
+   void PushRegsInMask(LiveRegisterSet set)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared, riscv64);
+   void PushRegsInMask(LiveGeneralRegisterSet set);
+
+   // Like PushRegsInMask, but instead of pushing the registers, store them to
+@@ -511,12 +517,12 @@
+   // must point to either the lowest address in the save area, or some address
+   // below that.
+   void storeRegsInMask(LiveRegisterSet set, Address dest, Register scratch)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared, riscv64);
+
+   void PopRegsInMask(LiveRegisterSet set);
+   void PopRegsInMask(LiveGeneralRegisterSet set);
+   void PopRegsInMaskIgnore(LiveRegisterSet set, LiveRegisterSet ignore)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared, riscv64);
+
+   // ===============================================================
+   // Stack manipulation functions -- single registers/values.
+@@ -549,7 +555,7 @@
+   void Pop(FloatRegister t) PER_SHARED_ARCH;
+   void Pop(const ValueOperand& val) PER_SHARED_ARCH;
+   void PopFlags() DEFINED_ON(x86_shared);
+-  void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared, loong64, wasm32);
++  void PopStackPtr() DEFINED_ON(arm, mips_shared, x86_shared, loong64, riscv64, wasm32);
+   void popRooted(VMFunctionData::RootType rootType, Register cellReg,
+                  const ValueOperand& valueReg);
+
+@@ -607,8 +613,8 @@
+   void callAndPushReturnAddress(Label* label) DEFINED_ON(x86_shared);
+
+   // These do not adjust framePushed().
+-  void pushReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64, wasm32);
+-  void popReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64, wasm32);
++  void pushReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64, wasm32);
++  void popReturnAddress() DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64, wasm32);
+
+   // Useful for dealing with two-valued returns.
+   void moveRegPair(Register src0, Register src1, Register dst0, Register dst1,
+@@ -639,10 +645,10 @@
+   // Note: "Near" applies to ARM64 where the target must be within 1 MB (this is
+   // release-asserted).
+   CodeOffset moveNearAddressWithPatch(Register dest)
+-      DEFINED_ON(x86, x64, arm, arm64, loong64, wasm32, mips_shared);
++      DEFINED_ON(x86, x64, arm, arm64, loong64, riscv64, wasm32, mips_shared);
+   static void patchNearAddressMove(CodeLocationLabel loc,
+                                    CodeLocationLabel target)
+-      DEFINED_ON(x86, x64, arm, arm64, loong64, wasm32, mips_shared);
++      DEFINED_ON(x86, x64, arm, arm64, loong64, riscv64, wasm32, mips_shared);
+
+  public:
+   // ===============================================================
+@@ -1051,17 +1057,17 @@
+   inline void addPtr(ImmWord imm, Register dest) PER_ARCH;
+   inline void addPtr(ImmPtr imm, Register dest);
+   inline void addPtr(Imm32 imm, const Address& dest)
+-      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64, wasm32);
+   inline void addPtr(Imm32 imm, const AbsoluteAddress& dest)
+       DEFINED_ON(x86, x64);
+   inline void addPtr(const Address& src, Register dest)
+-      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64, wasm32);
+ 
+   inline void add64(Register64 src, Register64 dest) PER_ARCH;
+   inline void add64(Imm32 imm, Register64 dest) PER_ARCH;
+   inline void add64(Imm64 imm, Register64 dest) PER_ARCH;
+   inline void add64(const Operand& src, Register64 dest)
+-      DEFINED_ON(x64, mips64, loong64);
++      DEFINED_ON(x64, mips64, loong64, riscv64);
+
+   inline void addFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
+ 
+@@ -1080,16 +1086,16 @@
+
+   inline void subPtr(Register src, Register dest) PER_ARCH;
+   inline void subPtr(Register src, const Address& dest)
+-      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64, wasm32);
+   inline void subPtr(Imm32 imm, Register dest) PER_ARCH;
+   inline void subPtr(ImmWord imm, Register dest) DEFINED_ON(x64);
+   inline void subPtr(const Address& addr, Register dest)
+-      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64, wasm32);
+
+   inline void sub64(Register64 src, Register64 dest) PER_ARCH;
+   inline void sub64(Imm64 imm, Register64 dest) PER_ARCH;
+   inline void sub64(const Operand& src, Register64 dest)
+-      DEFINED_ON(x64, mips64, loong64);
++      DEFINED_ON(x64, mips64, loong64, riscv64);
+ 
+   inline void subFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
+
+@@ -1105,10 +1111,11 @@
+
+   inline void mul64(const Operand& src, const Register64& dest) DEFINED_ON(x64);
+   inline void mul64(const Operand& src, const Register64& dest,
+-                    const Register temp) DEFINED_ON(x64, mips64, loong64);
++                    const Register temp)
++      DEFINED_ON(x64, mips64, loong64, riscv64);
+   inline void mul64(Imm64 imm, const Register64& dest) PER_ARCH;
+   inline void mul64(Imm64 imm, const Register64& dest, const Register temp)
+-      DEFINED_ON(x86, x64, arm, mips32, mips64, loong64);
++      DEFINED_ON(x86, x64, arm, mips32, mips64, loong64, riscv64);
+   inline void mul64(const Register64& src, const Register64& dest,
+                     const Register temp) PER_ARCH;
+   inline void mul64(const Register64& src1, const Register64& src2,
+@@ -1122,14 +1129,14 @@
+   inline void mulDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
+
+   inline void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest)
+-      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86, x64, loong64, riscv64, wasm32);
+ 
+   // Perform an integer division, returning the integer part rounded toward
+   // zero. rhs must not be zero, and the division must not overflow.
+   //
+   // On ARM, the chip must have hardware division instructions.
+   inline void quotient32(Register rhs, Register srcDest, bool isUnsigned)
+-      DEFINED_ON(mips_shared, arm, arm64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64, wasm32);
+
+   // As above, but srcDest must be eax and tempEdx must be edx.
+   inline void quotient32(Register rhs, Register srcDest, Register tempEdx,
+@@ -1140,7 +1147,7 @@
+   //
+   // On ARM, the chip must have hardware division instructions.
+   inline void remainder32(Register rhs, Register srcDest, bool isUnsigned)
+-      DEFINED_ON(mips_shared, arm, arm64, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, loong64, riscv64, wasm32);
+
+   // As above, but srcDest must be eax and tempEdx must be edx.
+   inline void remainder32(Register rhs, Register srcDest, Register tempEdx,
+@@ -1155,7 +1162,7 @@
+   // rhs is preserved, srdDest is clobbered.
+   void flexibleRemainder32(Register rhs, Register srcDest, bool isUnsigned,
+                            const LiveRegisterSet& volatileLiveRegs)
+-      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64, wasm32);
+
+   // Perform an integer division, returning the integer part rounded toward
+   // zero. rhs must not be zero, and the division must not overflow.
+@@ -1166,7 +1173,7 @@
+   // rhs is preserved, srdDest is clobbered.
+   void flexibleQuotient32(Register rhs, Register srcDest, bool isUnsigned,
+                           const LiveRegisterSet& volatileLiveRegs)
+-      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64);
++      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64);
+
+   // Perform an integer division, returning the integer part rounded toward
+   // zero. rhs must not be zero, and the division must not overflow. The
+@@ -1179,7 +1186,7 @@
+   void flexibleDivMod32(Register rhs, Register srcDest, Register remOutput,
+                         bool isUnsigned,
+                         const LiveRegisterSet& volatileLiveRegs)
+-      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, wasm32);
++      DEFINED_ON(mips_shared, arm, arm64, x86_shared, loong64, riscv64, wasm32);
+
+   inline void divFloat32(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
+   inline void divDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH;
+@@ -1386,7 +1393,7 @@
+ 
+   template <typename T1, typename T2>
+   inline void cmp32Set(Condition cond, T1 lhs, T2 rhs, Register dest)
+-      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, wasm32);
++      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64, wasm32);
+
+   // Only the NotEqual and Equal conditions are allowed.
+   inline void cmp64Set(Condition cond, Address lhs, Imm64 rhs,
+@@ -1421,10 +1428,10 @@
+ 
+   inline void branch32(Condition cond, const AbsoluteAddress& lhs, Register rhs,
+                        Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void branch32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs,
+                        Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   inline void branch32(Condition cond, const BaseIndex& lhs, Register rhs,
+                        Label* label) DEFINED_ON(arm, x86_shared);
+@@ -1438,7 +1445,7 @@
+ 
+   inline void branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs,
+                        Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+ 
+   // The supported condition are Equal, NotEqual, LessThan(orEqual),
+   // GreaterThan(orEqual), Below(orEqual) and Above(orEqual). When a fail label
+@@ -1489,14 +1496,14 @@
+
+   inline void branchPtr(Condition cond, const AbsoluteAddress& lhs,
+                         Register rhs, Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void branchPtr(Condition cond, const AbsoluteAddress& lhs, ImmWord rhs,
+                         Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   inline void branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs,
+                         Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   // Given a pointer to a GC Cell, retrieve the StoreBuffer pointer from its
+   // chunk header, or nullptr if it is in the tenured heap.
+@@ -1504,7 +1511,7 @@
+ 
+   void branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   void branchPtrInNurseryChunk(Condition cond, const Address& address,
+                                Register temp, Label* label) DEFINED_ON(x86);
+   void branchValueIsNurseryCell(Condition cond, const Address& address,
+@@ -1526,10 +1533,10 @@
+   // x64 variants will do this only in the int64_t range.
+   inline void branchTruncateFloat32MaybeModUint32(FloatRegister src,
+                                                   Register dest, Label* fail)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void branchTruncateDoubleMaybeModUint32(FloatRegister src,
+                                                  Register dest, Label* fail)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+ 
+   // Truncate a double/float32 to intptr and when it doesn't fit jump to the
+   // failure label.
+@@ -1542,10 +1549,10 @@
+   // failure label.
+   inline void branchTruncateFloat32ToInt32(FloatRegister src, Register dest,
+                                            Label* fail)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void branchTruncateDoubleToInt32(FloatRegister src, Register dest,
+                                           Label* fail)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   inline void branchDouble(DoubleCondition cond, FloatRegister lhs,
+                            FloatRegister rhs, Label* label) PER_SHARED_ARCH;
+@@ -1602,7 +1609,7 @@
+                            Label* label) PER_SHARED_ARCH;
+   inline void branchTest32(Condition cond, const AbsoluteAddress& lhs,
+                            Imm32 rhs, Label* label)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   template <class L>
+   inline void branchTestPtr(Condition cond, Register lhs, Register rhs,
+@@ -1763,7 +1770,7 @@
+   inline void branchTestInt32(Condition cond, Register tag,
+                               Label* label) PER_SHARED_ARCH;
+   inline void branchTestDouble(Condition cond, Register tag, Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+   inline void branchTestNumber(Condition cond, Register tag,
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestBoolean(Condition cond, Register tag,
+@@ -1795,7 +1802,7 @@
+                                   Label* label) PER_SHARED_ARCH;
+   inline void branchTestUndefined(Condition cond, const ValueOperand& value,
+                                   Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestInt32(Condition cond, const Address& address,
+                               Label* label) PER_SHARED_ARCH;
+@@ -1803,7 +1810,7 @@
+                               Label* label) PER_SHARED_ARCH;
+   inline void branchTestInt32(Condition cond, const ValueOperand& value,
+                               Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestDouble(Condition cond, const Address& address,
+                                Label* label) PER_SHARED_ARCH;
+@@ -1811,11 +1818,11 @@
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestDouble(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestNumber(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestBoolean(Condition cond, const Address& address,
+                                 Label* label) PER_SHARED_ARCH;
+@@ -1823,7 +1830,7 @@
+                                 Label* label) PER_SHARED_ARCH;
+   inline void branchTestBoolean(Condition cond, const ValueOperand& value,
+                                 Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+ 
+   inline void branchTestString(Condition cond, const Address& address,
+                                Label* label) PER_SHARED_ARCH;
+@@ -1831,7 +1838,7 @@
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestString(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestSymbol(Condition cond, const Address& address,
+                                Label* label) PER_SHARED_ARCH;
+@@ -1839,7 +1846,7 @@
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestSymbol(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+ 
+   inline void branchTestBigInt(Condition cond, const Address& address,
+                                Label* label) PER_SHARED_ARCH;
+@@ -1847,7 +1854,7 @@
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestBigInt(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestNull(Condition cond, const Address& address,
+                              Label* label) PER_SHARED_ARCH;
+@@ -1855,7 +1862,7 @@
+                              Label* label) PER_SHARED_ARCH;
+   inline void branchTestNull(Condition cond, const ValueOperand& value,
+                              Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   // Clobbers the ScratchReg on x64.
+   inline void branchTestObject(Condition cond, const Address& address,
+@@ -1864,7 +1871,7 @@
+                                Label* label) PER_SHARED_ARCH;
+   inline void branchTestObject(Condition cond, const ValueOperand& value,
+                                Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+ 
+   inline void branchTestGCThing(Condition cond, const Address& address,
+                                 Label* label) PER_SHARED_ARCH;
+@@ -1875,7 +1882,7 @@
+
+   inline void branchTestPrimitive(Condition cond, const ValueOperand& value,
+                                   Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestMagic(Condition cond, const Address& address,
+                               Label* label) PER_SHARED_ARCH;
+@@ -1884,7 +1891,7 @@
+   template <class L>
+   inline void branchTestMagic(Condition cond, const ValueOperand& value,
+                               L label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   inline void branchTestMagic(Condition cond, const Address& valaddr,
+                               JSWhyMagic why, Label* label) PER_ARCH;
+@@ -1902,17 +1909,17 @@
+   // The type of the value should match the type of the method.
+   inline void branchTestInt32Truthy(bool truthy, const ValueOperand& value,
+                                     Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, wasm32);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, x86_shared, riscv64, wasm32);
+   inline void branchTestDoubleTruthy(bool truthy, FloatRegister reg,
+                                      Label* label) PER_SHARED_ARCH;
+   inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value,
+                                       Label* label) PER_ARCH;
+   inline void branchTestStringTruthy(bool truthy, const ValueOperand& value,
+                                      Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+   inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value,
+                                      Label* label)
+-      DEFINED_ON(arm, arm64, mips32, mips64, loong64, wasm32, x86_shared);
++      DEFINED_ON(arm, arm64, mips32, mips64, loong64, riscv64, wasm32, x86_shared);
+
+   // Create an unconditional branch to the address given as argument.
+   inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;
+@@ -2014,11 +2021,11 @@
+
+   inline void cmp32Move32(Condition cond, Register lhs, Register rhs,
+                           Register src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86_shared);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86_shared);
+
+   inline void cmp32Move32(Condition cond, Register lhs, const Address& rhs,
+                           Register src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86_shared);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86_shared);
+
+   inline void cmpPtrMovePtr(Condition cond, Register lhs, Register rhs,
+                             Register src, Register dest) PER_ARCH;
+@@ -2028,36 +2035,36 @@
+ 
+   inline void cmp32Load32(Condition cond, Register lhs, const Address& rhs,
+                           const Address& src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
++      DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
+
+   inline void cmp32Load32(Condition cond, Register lhs, Register rhs,
+                           const Address& src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared);
++      DEFINED_ON(arm, arm64, loong64, mips_shared, x86_shared, riscv64);
+
+   inline void cmp32LoadPtr(Condition cond, const Address& lhs, Imm32 rhs,
+                            const Address& src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86, x64);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86, x64);
+
+   inline void cmp32MovePtr(Condition cond, Register lhs, Imm32 rhs,
+                            Register src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86, x64);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86, x64);
+
+   inline void test32LoadPtr(Condition cond, const Address& addr, Imm32 mask,
+                             const Address& src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86, x64);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86, x64);
+ 
+   inline void test32MovePtr(Condition cond, const Address& addr, Imm32 mask,
+                             Register src, Register dest)
+-      DEFINED_ON(arm, arm64, loong64, wasm32, mips_shared, x86, x64);
++      DEFINED_ON(arm, arm64, loong64, riscv64, wasm32, mips_shared, x86, x64);
+
+   // Conditional move for Spectre mitigations.
+   inline void spectreMovePtr(Condition cond, Register src, Register dest)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+ 
+   // Zeroes dest if the condition is true.
+   inline void spectreZeroRegister(Condition cond, Register scratch,
+                                   Register dest)
+-      DEFINED_ON(arm, arm64, mips_shared, x86_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86_shared, loong64, riscv64, wasm32);
+
+   // Performs a bounds check and zeroes the index register if out-of-bounds
+   // (to mitigate Spectre).
+@@ -2069,17 +2076,17 @@
+  public:
+   inline void spectreBoundsCheck32(Register index, Register length,
+                                    Register maybeScratch, Label* failure)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void spectreBoundsCheck32(Register index, const Address& length,
+                                    Register maybeScratch, Label* failure)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+ 
+   inline void spectreBoundsCheckPtr(Register index, Register length,
+                                     Register maybeScratch, Label* failure)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+   inline void spectreBoundsCheckPtr(Register index, const Address& length,
+                                     Register maybeScratch, Label* failure)
+-      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips_shared, x86, x64, loong64, riscv64, wasm32);
+
+   // ========================================================================
+   // Canonicalization primitives.
+@@ -2093,10 +2100,10 @@
+   // ========================================================================
+   // Memory access primitives.
+   inline void storeUncanonicalizedDouble(FloatRegister src, const Address& dest)
+-      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, wasm32);
++      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64, wasm32);
+   inline void storeUncanonicalizedDouble(FloatRegister src,
+                                          const BaseIndex& dest)
+-      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, wasm32);
++      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64, wasm32);
+   inline void storeUncanonicalizedDouble(FloatRegister src, const Operand& dest)
+       DEFINED_ON(x86_shared);
+ 
+@@ -2110,10 +2117,10 @@
+ 
+   inline void storeUncanonicalizedFloat32(FloatRegister src,
+                                           const Address& dest)
+-      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, wasm32);
++      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64, wasm32);
+   inline void storeUncanonicalizedFloat32(FloatRegister src,
+                                           const BaseIndex& dest)
+-      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, wasm32);
++      DEFINED_ON(x86_shared, arm, arm64, mips32, mips64, loong64, riscv64, wasm32);
+   inline void storeUncanonicalizedFloat32(FloatRegister src,
+                                           const Operand& dest)
+       DEFINED_ON(x86_shared);
+@@ -3514,10 +3521,10 @@
+
+   // temp required on x86 and x64; must be undefined on mips64 and loong64.
+   void convertUInt64ToFloat32(Register64 src, FloatRegister dest, Register temp)
+-      DEFINED_ON(arm64, mips64, loong64, wasm32, x64, x86);
++      DEFINED_ON(arm64, mips64, loong64, riscv64, wasm32, x64, x86);
+ 
+   void convertInt64ToFloat32(Register64 src, FloatRegister dest)
+-      DEFINED_ON(arm64, mips64, loong64, wasm32, x64, x86);
++      DEFINED_ON(arm64, mips64, loong64, riscv64, wasm32, x64, x86);
+
+   bool convertUInt64ToDoubleNeedsTemp() PER_ARCH;
+ 
+@@ -3569,19 +3576,19 @@
+
+   void wasmBoundsCheck32(Condition cond, Register index,
+                          Register boundsCheckLimit, Label* ok)
+-      DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, riscv64, wasm32);
+
+   void wasmBoundsCheck32(Condition cond, Register index,
+                          Address boundsCheckLimit, Label* ok)
+-      DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, mips32, mips64, x86_shared, loong64, riscv64, wasm32);
+
+   void wasmBoundsCheck64(Condition cond, Register64 index,
+                          Register64 boundsCheckLimit, Label* ok)
+-      DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, wasm32);
++      DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, riscv64, wasm32);
+
+   void wasmBoundsCheck64(Condition cond, Register64 index,
+                          Address boundsCheckLimit, Label* ok)
+-      DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, wasm32);
++      DEFINED_ON(arm64, mips64, x64, x86, arm, loong64, riscv64, wasm32);
+ 
+   // Each wasm load/store instruction appends its own wasm::Trap::OutOfBounds.
+   void wasmLoad(const wasm::MemoryAccessDesc& access, Operand srcAddr,
+@@ -3674,7 +3681,7 @@
+   void oolWasmTruncateCheckF64ToI32(FloatRegister input, Register output,
+                                     TruncFlags flags, wasm::BytecodeOffset off,
+                                     Label* rejoin)
+-      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64, wasm32);
+
+   void wasmTruncateFloat32ToUInt32(FloatRegister input, Register output,
+                                    bool isSaturating, Label* oolEntry) PER_ARCH;
+@@ -3684,35 +3691,35 @@
+   void oolWasmTruncateCheckF32ToI32(FloatRegister input, Register output,
+                                     TruncFlags flags, wasm::BytecodeOffset off,
+                                     Label* rejoin)
+-      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64, wasm32);
+
+   // The truncate-to-int64 methods will always bind the `oolRejoin` label
+   // after the last emitted instruction.
+   void wasmTruncateDoubleToInt64(FloatRegister input, Register64 output,
+                                  bool isSaturating, Label* oolEntry,
+                                  Label* oolRejoin, FloatRegister tempDouble)
+-      DEFINED_ON(arm64, x86, x64, mips64, loong64, wasm32);
++      DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
+   void wasmTruncateDoubleToUInt64(FloatRegister input, Register64 output,
+                                   bool isSaturating, Label* oolEntry,
+                                   Label* oolRejoin, FloatRegister tempDouble)
+-      DEFINED_ON(arm64, x86, x64, mips64, loong64, wasm32);
++      DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
+   void oolWasmTruncateCheckF64ToI64(FloatRegister input, Register64 output,
+                                     TruncFlags flags, wasm::BytecodeOffset off,
+                                     Label* rejoin)
+-      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64, wasm32);
+
+   void wasmTruncateFloat32ToInt64(FloatRegister input, Register64 output,
+                                   bool isSaturating, Label* oolEntry,
+                                   Label* oolRejoin, FloatRegister tempDouble)
+-      DEFINED_ON(arm64, x86, x64, mips64, loong64, wasm32);
++      DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
+   void wasmTruncateFloat32ToUInt64(FloatRegister input, Register64 output,
+                                    bool isSaturating, Label* oolEntry,
+                                    Label* oolRejoin, FloatRegister tempDouble)
+-      DEFINED_ON(arm64, x86, x64, mips64, loong64, wasm32);
++      DEFINED_ON(arm64, x86, x64, mips64, loong64, riscv64, wasm32);
+   void oolWasmTruncateCheckF32ToI64(FloatRegister input, Register64 output,
+                                     TruncFlags flags, wasm::BytecodeOffset off,
+                                     Label* rejoin)
+-      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, wasm32);
++      DEFINED_ON(arm, arm64, x86_shared, mips_shared, loong64, riscv64, wasm32);
+
+   void loadWasmGlobalPtr(uint32_t globalDataOffset, Register dest);
+
+@@ -3775,7 +3782,7 @@
+   // convention, which requires predictable high bits.  In practice, this means
+   // that the 32-bit value will be zero-extended or sign-extended to 64 bits as
+   // appropriate for the platform.
+-  void widenInt32(Register r) DEFINED_ON(arm64, x64, mips64, loong64);
++  void widenInt32(Register r) DEFINED_ON(arm64, x64, mips64, loong64, riscv64);
+
+   // As enterFakeExitFrame(), but using register conventions appropriate for
+   // wasm stubs.
+@@ -5017,7 +5024,7 @@
+   inline void addStackPtrTo(T t);
+
+   void subFromStackPtr(Imm32 imm32)
+-      DEFINED_ON(mips32, mips64, loong64, wasm32, arm, x86, x64);
++      DEFINED_ON(mips32, mips64, loong64, riscv64, wasm32, arm, x86, x64);
+   void subFromStackPtr(Register reg);
+
+   template <typename T>
+
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.cpp b/js/src/jit/riscv64/Assembler-riscv64.cpp
+index 0e9cf05fcc111..90fa6d87a83d4 100644
+--- a/js/src/jit/riscv64/Assembler-riscv64.cpp
++++ b/js/src/jit/riscv64/Assembler-riscv64.cpp
+@@ -21,19 +21,24 @@ ABIArg ABIArgGenerator::next(MIRType type) {
+         stackOffset_ += sizeof(uintptr_t);
+         break;
+       }
+-      current_ = ABIArg(IntArgRegs[intRegIndex_++]);
++      current_ = ABIArg(Register::FromCode(intRegIndex_));
++      intRegIndex_++;
+       break;
+
++    case MIRType::Float32:
+     case MIRType::Double:
+       if (floatRegIndex_ == NumFloatArgRegs) {
+         current_ = ABIArg(stackOffset_);
+         stackOffset_ += sizeof(double);
+         break;
+       }
+-      current_ = ABIArg(FloatArgReg[floatRegIndex_++]);
++      current_ = ABIArg(FloatRegister(FloatRegisters::Encoding(floatRegIndex_),
++                                      type == MIRType::Double
++                                          ? FloatRegisters::Double
++                                          : FloatRegisters::Single));
++      floatRegIndex_++;
+       break;
+ 
+-    case MIRType::Float32:
+     case MIRType::Simd128:
+     default:
+       MOZ_CRASH("Unexpected argument type");
+diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h
+index e695662be5cba..a58e6c4aff222 100644
+--- a/js/src/jit/riscv64/Assembler-riscv64.h
++++ b/js/src/jit/riscv64/Assembler-riscv64.h
+@@ -13,8 +13,6 @@
+ #include "jit/CompactBuffer.h"
+ #include "jit/JitCode.h"
+ #include "jit/JitSpewer.h"
+-#include "jit/Registers.h"
+-#include "jit/RegisterSets.h"
+ #include "jit/riscv64/Architecture-riscv64.h"
+ #include "jit/shared/Assembler-shared.h"
+ #include "jit/shared/Disassembler-shared.h"
+@@ -33,6 +31,8 @@ static constexpr Register t3{Registers::t3};
+ static constexpr Register t4{Registers::t4};
+ static constexpr Register t5{Registers::t5};
+ static constexpr Register t6{Registers::t6};
++static constexpr Register s0{Registers::s0};
++static constexpr Register s4{Registers::s4};
+ 
+ static constexpr Register StackPointer{Registers::sp};
+ static constexpr Register FramePointer{Registers::fp};
+@@ -47,6 +47,19 @@ static constexpr FloatRegister ScratchSimd128Reg = InvalidFloatReg;
+ static constexpr FloatRegister ScratchFloat32Reg_ = InvalidFloatReg;
+ static constexpr FloatRegister ScratchDoubleReg_ = InvalidFloatReg;
+ 
++static constexpr Register ScratchRegister = t6;
++
++// Helper class for ScratchRegister usage. Asserts that only one piece
++// of code thinks it has exclusive ownership of the scratch register.
++struct ScratchRegisterScope : public AutoRegisterScope {
++  explicit ScratchRegisterScope(MacroAssembler& masm)
++      : AutoRegisterScope(masm, ScratchRegister) {}
++};
++
++struct SecondScratchRegisterScope : public AutoRegisterScope {
++  explicit SecondScratchRegisterScope(MacroAssembler& masm);
++};
++
+ struct ScratchFloat32Scope : AutoFloatRegisterScope {
+   explicit ScratchFloat32Scope(MacroAssembler& masm)
+       : AutoFloatRegisterScope(masm, ScratchFloat32Reg_) {}
+@@ -94,7 +107,6 @@ static constexpr Register JSReturnReg_Type{Registers::a3};
+ static constexpr Register JSReturnReg_Data{Registers::a2};
+ static constexpr Register JSReturnReg{Registers::a2};
+ 
+-static constexpr ValueOperand ValueOperand(JSReturnReg);
+ static constexpr Register64 ReturnReg64(ReturnReg);
+ 
+ static constexpr Register ABINonArgReg0{Registers::s0};
+@@ -108,6 +120,11 @@ static constexpr Register ABINonArgReturnVolatileReg{Registers::ra};
+ 
+ static constexpr FloatRegister ABINonArgDoubleReg = InvalidFloatReg;
+ 
++// Instance pointer argument register for WebAssembly functions. This must not
++// alias any other register used for passing function arguments or return
++// values. Preserved by WebAssembly functions.
++static constexpr Register InstanceReg = s4;
++
+ static constexpr Register WasmTableCallScratchReg0{Registers::invalid_reg};
+ static constexpr Register WasmTableCallScratchReg1{Registers::invalid_reg};
+ static constexpr Register WasmTableCallSigReg{Registers::invalid_reg};
+@@ -183,6 +200,11 @@ class Assembler : public AssemblerShared {
+ 
+   static DoubleCondition InvertCondition(DoubleCondition) { MOZ_CRASH(); }
+ 
++  static void TraceJumpRelocations(JSTracer* trc, JitCode* code,
++                                   CompactBufferReader& reader);
++  static void TraceDataRelocations(JSTracer* trc, JitCode* code,
++                                   CompactBufferReader& reader);
++
+   template <typename T, typename S>
+   static void PatchDataWithValueCheck(CodeLocationLabel, T, S) {
+     MOZ_CRASH();
+@@ -255,6 +277,9 @@ class Operand {
+   Kind kind() const { return kind_; }
+ };
+ 
++static const uint32_t NumIntArgRegs = 8;
++static const uint32_t NumFloatArgRegs = 8;
++
+ class ABIArgGenerator {
+  public:
+   ABIArgGenerator()
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
+index fa5ef6e87d0a9..3dd6273d0f01b 100644
+--- a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
+@@ -9,4 +9,10 @@
+ 
+ #include "jit/riscv64/MacroAssembler-riscv64.h"
+ 
++namespace js {
++namespace jit {
++
++}  // namespace jit
++}  // namespace js
++
+ #endif
+diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+index 6466946454e4f..30ca17d359d4d 100644
+--- a/js/src/jit/riscv64/MacroAssembler-riscv64.h
++++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h
+@@ -14,9 +14,11 @@
+ namespace js {
+ namespace jit {
+ 
++static constexpr ValueOperand JSReturnOperand{JSReturnReg};
++
+ class ScratchTagScope : public SecondScratchRegisterScope {
+  public:
+-  ScratchTagScope(MacroAssembler& masm, const ValueOperand&)
++  ScratchTagScope(MacroAssembler& masm, const js::jit::ValueOperand&)
+       : SecondScratchRegisterScope(masm) {}
+ };
+ 
+@@ -82,10 +84,7 @@ class MacroAssemblerRiscv64 : public Assembler {
+     MOZ_CRASH();
+   }
+   void writeCodePointer(CodeLabel* label) {
+-    MOZ_ASSERT(hasCreator());
+-    m_buffer.ensureSpace(sizeof(uintptr_t));
+-    BufferOffset off = m_buffer.putInt64Unchecked(-1);
+-    label->patchAt()->bind(off.getOffset());
++    MOZ_CRASH();
+   }
+   void haltingAlign(size_t) { MOZ_CRASH(); }
+   void nopAlign(size_t) { MOZ_CRASH(); }
+@@ -429,7 +428,6 @@ class MacroAssemblerRiscv64 : public Assembler {
+   void convertUInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); }
+   void incrementInt32Value(Address) { MOZ_CRASH(); }
+   void ensureDouble(ValueOperand, FloatRegister, Label*) { MOZ_CRASH(); }
+-  void handleFailureWithHandlerTail(Label*) { MOZ_CRASH(); }
+ 
+   void buildFakeExitFrame(Register, uint32_t*) { MOZ_CRASH(); }
+   bool buildOOLFakeExitFrame(void*) { MOZ_CRASH(); }
+@@ -440,6 +438,9 @@ class MacroAssemblerRiscv64 : public Assembler {
+ 
+   Register getStackPointer() const { MOZ_CRASH(); }
+ 
++  void handleFailureWithHandlerTail(Label* profilerExitTail,
++                                    Label* bailoutTail) { MOZ_CRASH(); }
++
+   // Instrumentation for entering and leaving the profiler.
+   void profilerEnterFrame(Register, Register) { MOZ_CRASH(); }
+   void profilerExitFrame() { MOZ_CRASH(); }
+diff --git a/js/src/jit/riscv64/SharedICRegisters-riscv64.h b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+index 87e14461f65ba..f1d5f165d8adb 100644
+--- a/js/src/jit/riscv64/SharedICRegisters-riscv64.h
++++ b/js/src/jit/riscv64/SharedICRegisters-riscv64.h
+@@ -7,9 +7,9 @@
+ #ifndef jit_riscv64_SharedICRegisters_riscv64_h
+ #define jit_riscv64_SharedICRegisters_riscv64_h
+ 
++#include "jit/riscv64/Assembler-riscv64.h"
+ #include "jit/Registers.h"
+ #include "jit/RegisterSets.h"
+-#include "jit/riscv64/MacroAssembler-riscv64.h"
+ 
+ namespace js {
+ namespace jit {
+diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h
+index fcabddd98b611..19cf397df1473 100644
+--- a/js/src/jit/shared/Assembler-shared.h
++++ b/js/src/jit/shared/Assembler-shared.h
+@@ -26,13 +26,15 @@
+
+ #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) ||     \
+     defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
+-    defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_WASM32)
++    defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_WASM32) || \
++    defined(JS_CODEGEN_RISCV64)
+ // Push return addresses callee-side.
+ #  define JS_USE_LINK_REGISTER
+ #endif
+
+ #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
+-    defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_LOONG64)
++    defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_LOONG64) || \
++    defined(JS_CODEGEN_RISCV64)
+ // JS_CODELABEL_LINKMODE gives labels additional metadata
+ // describing how Bind() should patch them.
+ #  define JS_CODELABEL_LINKMODE
+diff --git a/js/src/wasm/WasmBCMemory.cpp b/js/src/wasm/WasmBCMemory.cpp
+index 94e739090b130..2c226dadd5f2d 100644
+--- a/js/src/wasm/WasmBCMemory.cpp
++++ b/js/src/wasm/WasmBCMemory.cpp
+@@ -1214,6 +1214,22 @@
+   bc->maybeFree(temps.t2);
+ }
+
++#elif defined(JS_CODEGEN_RISCV64)
++
++struct Temps {
++  RegI32 t0;
++};
++
++static void PopAndAllocate(BaseCompiler* bc, ValType type,
++                           Scalar::Type viewType, AtomicOp op, RegI32* rd,
++                           RegI32* rv, Temps* temps) {}
++
++static void Perform(BaseCompiler* bc, const MemoryAccessDesc& access,
++                    BaseIndex srcAddr, AtomicOp op, RegI32 rv, RegI32 rd,
++                    const Temps& temps) {}
++
++static void Deallocate(BaseCompiler*, RegI32, const Temps&) {}
++
+ #elif defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_WASM32)
+
+ using Temps = Nothing;
+@@ -1375,6 +1391,17 @@
+   bc->freeI64(temp);
+ }
+
++#elif defined(JS_CODEGEN_RISCV64)
++
++static void PopAndAllocate(BaseCompiler* bc, AtomicOp op, RegI64* rd,
++                           RegI64* rv, RegI64* temp) {}
++
++static void Perform(BaseCompiler* bc, const MemoryAccessDesc& access,
++                    BaseIndex srcAddr, AtomicOp op, RegI64 rv, RegI64 temp,
++                    RegI64 rd) {}
++
++static void Deallocate(BaseCompiler* bc, AtomicOp op, RegI64 rv, RegI64 temp) {}
++
+ #elif defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_WASM32)
+
+ static void PopAndAllocate(BaseCompiler*, AtomicOp, RegI64*, RegI64*, RegI64*) {