resources: Added Asmtests to the resources

Change-Id: If19d67e1807819ae1bb3c6e4593de47d95967570
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5-resources/+/29007
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: Jason Lowe-Power <power.jg@gmail.com>
diff --git a/Makefile b/Makefile
index d7b57e9..aaee287 100644
--- a/Makefile
+++ b/Makefile
@@ -51,6 +51,11 @@
 square-bench		:= $(square-bin)/square.o
 square-out			:= $(output-dir)/test-progs/square
 
+# Asmtest Parameters
+asmtest-src         := $(source-dir)/asmtest
+asmtest-bin         := $(asmtest-src)/bin
+asmtest-dist-dir    := $(output-dir)/test-progs/asmtest/bin
+
 # RISCV-Tests
 .PHONY: riscv-tests
 riscv-tests: $(riscv-benchmarks)
@@ -166,10 +171,27 @@
 	-rm -r $(square-out)
 	-make -C $(square-dir) clean
 
+# Asmtest
+.PHONY: asmtests
+asmtests: $(asmtest-dist-dir)
+
+$(asmtest-dist-dir): $(asmtest-bin)
+	-mkdir -p $(asmtest-dist-dir)
+	cp $(asmtest-bin)/* $(asmtest-dist-dir)/
+
+$(asmtest-bin): $(asmtest-src)/Makefile
+	make -C $(asmtest-src)
+
+.PHONY: clean-asmtests
+clean-asmtests:
+	-make -C $(asmtest-src) clean
+	-rm -rf $(asmtest-dist-dir)
+
 # Global
 .PHONY: all
-all: riscv-tests insttests pthreads square
+all: riscv-tests insttests pthreads square asmtests
 
 .PHONY: clean
-clean: clean-riscv-tests clean-insttests clean-pthreads clean-square
+clean: clean-riscv-tests clean-insttests clean-pthreads clean-square \
+	   clean-asmtests
 	-rm -r $(output-dir)
diff --git a/src/asmtest/.gitignore b/src/asmtest/.gitignore
new file mode 100644
index 0000000..84ff6ec
--- /dev/null
+++ b/src/asmtest/.gitignore
@@ -0,0 +1,2 @@
+bin/*
+dump/*
diff --git a/src/asmtest/LICENSE b/src/asmtest/LICENSE
new file mode 100644
index 0000000..e0f0cba
--- /dev/null
+++ b/src/asmtest/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2012-2020, The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the Regents nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/src/asmtest/Makefile b/src/asmtest/Makefile
new file mode 100644
index 0000000..44b97b1
--- /dev/null
+++ b/src/asmtest/Makefile
@@ -0,0 +1,105 @@
+#=======================================================================
+# Makefile for riscv-tests/isa
+#-----------------------------------------------------------------------
+
+XLEN ?= 64
+
+src_dir 	:= ./isa
+bin_dir 	:= ./bin
+dump_dir 	:= ./dump
+
+include $(src_dir)/rv64ui/Makefrag
+include $(src_dir)/rv64uc/Makefrag
+include $(src_dir)/rv64um/Makefrag
+include $(src_dir)/rv64ua/Makefrag
+include $(src_dir)/rv64uf/Makefrag
+include $(src_dir)/rv64ud/Makefrag
+include $(src_dir)/rv64si/Makefrag
+include $(src_dir)/rv64mi/Makefrag
+include $(src_dir)/rv64uamt/Makefrag
+include $(src_dir)/rv64samt/Makefrag
+
+default: all
+
+#--------------------------------------------------------------------
+# Build rules
+#--------------------------------------------------------------------
+
+RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
+RISCV_GCC ?= $(RISCV_PREFIX)gcc
+RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
+RISCV_SIM ?= spike
+
+vpath %.S $(src_dir)
+
+#------------------------------------------------------------
+# Build assembly tests
+
+%.dump: %
+	mkdir -p $(dump_dir)
+	$(RISCV_OBJDUMP) $(bin_dir)/$< > $(dump_dir)/$@
+
+%.out: %
+	$(RISCV_SIM) --isa=rv64gc $< 2> $@
+
+define compile_template
+
+$$($(1)_p_tests): $(1)-p-%: $(1)/%.S
+	mkdir -p $(bin_dir)
+	$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(src_dir)/../env/p -I$(src_dir)/macros/scalar -T$(src_dir)/../env/p/link.ld $$< -o $(bin_dir)/$$@
+$(1)_p_env_tests += $$($(1)_p_tests)
+
+$$($(1)_ps_tests): $(1)-ps-%: $(1)/%.S
+	mkdir -p $(bin_dir)
+	$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(src_dir)/../env/ps -I$(src_dir)/macros/scalar -I$(src_dir)/macros/mt -T$(src_dir)/../env/ps/link.ld $$< -o $(bin_dir)/$$@
+$(1)_ps_env_tests += $$($(1)_ps_tests)
+
+$$($(1)_v_tests): $(1)-v-%: $(1)/%.S
+	mkdir -p $(bin_dir)
+	$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -DENTROPY=0x$$(shell echo \$$@ | md5sum | cut -c 1-7) -std=gnu99 -O2 -I$(src_dir)/../env/v -I$(src_dir)/macros/scalar -T$(src_dir)/../env/v/link.ld $(src_dir)/../env/v/entry.S $(src_dir)/../env/v/*.c $$< -o $(bin_dir)/$$@
+$(1)_v_env_tests += $$($(1)_v_tests)
+
+$(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests))
+
+$(1): $$($(1)_tests_dump)
+
+.PHONY: $(1)
+
+p_env_tests 	+= $$($(1)_p_env_tests)
+v_env_tests 	+= $$($(1)_v_env_tests)
+ps_env_tests 	+= $$($(1)_ps_env_tests)
+
+endef
+
+$(eval $(call compile_template,rv64ui,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64uc,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64um,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64ua,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64uf,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64ud,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64uamt,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,rv64samt,-march=rv64g -mabi=lp64))
+
+p_env_tests_dump = $(addsuffix .dump, $(p_env_tests))
+ps_env_tests_dump = $(addsuffix .dump, $(ps_env_tests))
+v_env_tests_dump = $(addsuffix .dump, $(v_env_tests))
+
+#------------------------------------------------------------
+# Targets
+
+all: 	p ps v
+# build tests with p environment
+p:		$(p_env_tests_dump)
+# build tests with ps environment
+ps: 	$(ps_env_tests_dump)
+# build tests with v environment
+v:		$(v_env_tests_dump)
+
+#------------------------------------------------------------
+# Clean up
+
+clean:
+	-rm -rf $(bin_dir) $(dump_dir)
diff --git a/src/asmtest/README.md b/src/asmtest/README.md
new file mode 100644
index 0000000..bf516e3
--- /dev/null
+++ b/src/asmtest/README.md
@@ -0,0 +1,84 @@
+gem5 Specifc RISC-V tests
+=========================
+
+About
+-----
+
+This work provides assembly testing infrastructure including single-threaded
+and multi-threaded tests for RISC-V ISA in gem5. Each test targets an
+individual RISC-V instruction or a Linux system call. This work targets
+system call emulation (SE) mode in gem5.
+
+This work is based on the riscv-tests project.
+
+Link to the orignal riscv-tests projects can be found here:
+  https://github.com/riscv/riscv-tests
+
+Link to the original riscv-tests project's LICENSE and README can be found
+here:
+  https://github.com/riscv/riscv-tests/blob/master/LICENSE
+  https://github.com/riscv/riscv-tests/blob/master/README.md
+
+Specific commit ID that this work is based off:
+  68cad7baf3ed0a4553fffd14726d24519ee1296a
+
+Changes from the orignal riscv-tests project
+--------------------------------------------
+
+1. Only rv64 tests are imported into this work
+
+The original project offers both rv64 and rv32 tests. Since the current
+implementation of RISC-V in gem5 is focused on its 64-bit version, only
+64-bit tests (rv64) are imported from the original project. Future work
+on 32-bit can easily integrate all 32-bit tests into gem5.
+
+2. New testing environment for gem5
+
+Since the original riscv-tests project is designed for bare-metal system (i.e.,
+without OS support), it offers several environments to control how a test
+interacts with a host machine (to-host communication). However, in gem5 SE
+mode, gem5 emulates an OS, and there is no host machine. Therefore, we
+developed a new testing environment called `ps` for gem5.
+
+This testing environment uses system call `exit` to return test results as an
+exit code of a particular test instead of writing them to a host machine. This
+environment requires the testing platform to implement/emulate at least `exit`
+system call.
+
+3. Minimal threading library written in assembly (`isa/macros/mt`)
+
+To simplify debugging multi-threading systems, we developed a minimal threading
+library that supports very basic threading functionality including creating a
+thread, exiting a thread, waiting for some thread(s) on a condition, and waking
+up some thread(s).
+
+Multi-threaded tests can rely on this library to manage multiple threads.
+
+4. RISC-V AMO, LR, and SC instruction tests (`isa/rv64uamt`)
+
+This is a set of assembly tests that target multi-core systems and test AMO
+instructions. This test set uses a minimal number of system calls (i.e., clone,
+mmap, munmap and exit) to create and manage threads.  It does not use any
+complex sleep/wakeup mechanism to manage and synchronize threads to avoid
+adding extra unnecessary complexity. The major goal of this test set is to
+stress AMO instructions. Threads only synchronize at the end of their
+execution. The master thread does a spin-wait to wait for all threads to
+complete before it checks final results.
+
+5. Thread-related system call tests (`isa/rv64samt`)
+
+This is a set of assembly tests that target thread-related system calls and
+thread wait/wakeup behaviors. This set reuses some of the tests in
+`isa/rv64uamt` but uses more advanced futex system call operations to make
+threads wait and wake up in certain cases. This test set also checks functional
+behaviors of threads after a wait/wakeup operation.
+
+How to compile this test suite
+------------------------------
+
+1. Install RISC-V GNU toolchain. Source code and instruction on how to install
+it can be found here: https://github.com/riscv/riscv-gnu-toolchain
+
+2. Run `make`
+
+3. Test binaries are in `bin`
diff --git a/src/asmtest/env/LICENSE b/src/asmtest/env/LICENSE
new file mode 100644
index 0000000..48fe522
--- /dev/null
+++ b/src/asmtest/env/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2012-2015, The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the Regents nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/src/asmtest/env/encoding.h b/src/asmtest/env/encoding.h
new file mode 100644
index 0000000..769b0d0
--- /dev/null
+++ b/src/asmtest/env/encoding.h
@@ -0,0 +1,2702 @@
+/* See LICENSE for license details. */
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE         0x00000001
+#define MSTATUS_SIE         0x00000002
+#define MSTATUS_HIE         0x00000004
+#define MSTATUS_MIE         0x00000008
+#define MSTATUS_UPIE        0x00000010
+#define MSTATUS_SPIE        0x00000020
+#define MSTATUS_HPIE        0x00000040
+#define MSTATUS_MPIE        0x00000080
+#define MSTATUS_SPP         0x00000100
+#define MSTATUS_VS          0x00000600
+#define MSTATUS_MPP         0x00001800
+#define MSTATUS_FS          0x00006000
+#define MSTATUS_XS          0x00018000
+#define MSTATUS_MPRV        0x00020000
+#define MSTATUS_SUM         0x00040000
+#define MSTATUS_MXR         0x00080000
+#define MSTATUS_TVM         0x00100000
+#define MSTATUS_TW          0x00200000
+#define MSTATUS_TSR         0x00400000
+#define MSTATUS32_SD        0x80000000
+#define MSTATUS_UXL         0x0000000300000000
+#define MSTATUS_SXL         0x0000000C00000000
+#define MSTATUS64_SD        0x8000000000000000
+
+#define SSTATUS_UIE         0x00000001
+#define SSTATUS_SIE         0x00000002
+#define SSTATUS_UPIE        0x00000010
+#define SSTATUS_SPIE        0x00000020
+#define SSTATUS_SPP         0x00000100
+#define SSTATUS_VS          0x00000600
+#define SSTATUS_FS          0x00006000
+#define SSTATUS_XS          0x00018000
+#define SSTATUS_SUM         0x00040000
+#define SSTATUS_MXR         0x00080000
+#define SSTATUS32_SD        0x80000000
+#define SSTATUS_UXL         0x0000000300000000
+#define SSTATUS64_SD        0x8000000000000000
+
+#define USTATUS_UIE         0x00000001
+#define USTATUS_UPIE        0x00000010
+
+#define DCSR_XDEBUGVER      (3U<<30)
+#define DCSR_NDRESET        (1<<29)
+#define DCSR_FULLRESET      (1<<28)
+#define DCSR_EBREAKM        (1<<15)
+#define DCSR_EBREAKH        (1<<14)
+#define DCSR_EBREAKS        (1<<13)
+#define DCSR_EBREAKU        (1<<12)
+#define DCSR_STOPCYCLE      (1<<10)
+#define DCSR_STOPTIME       (1<<9)
+#define DCSR_CAUSE          (7<<6)
+#define DCSR_DEBUGINT       (1<<5)
+#define DCSR_HALT           (1<<3)
+#define DCSR_STEP           (1<<2)
+#define DCSR_PRV            (3<<0)
+
+#define DCSR_CAUSE_NONE     0
+#define DCSR_CAUSE_SWBP     1
+#define DCSR_CAUSE_HWBP     2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP     4
+#define DCSR_CAUSE_HALT     5
+
+#define MCONTROL_TYPE(xlen)    (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen)   (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT     (1<<19)
+#define MCONTROL_TIMING     (1<<18)
+#define MCONTROL_ACTION     (0x3f<<12)
+#define MCONTROL_CHAIN      (1<<11)
+#define MCONTROL_MATCH      (0xf<<7)
+#define MCONTROL_M          (1<<6)
+#define MCONTROL_H          (1<<5)
+#define MCONTROL_S          (1<<4)
+#define MCONTROL_U          (1<<3)
+#define MCONTROL_EXECUTE    (1<<2)
+#define MCONTROL_STORE      (1<<1)
+#define MCONTROL_LOAD       (1<<0)
+
+#define MCONTROL_TYPE_NONE      0
+#define MCONTROL_TYPE_MATCH     2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION   0
+#define MCONTROL_ACTION_DEBUG_MODE        1
+#define MCONTROL_ACTION_TRACE_START       2
+#define MCONTROL_ACTION_TRACE_STOP        3
+#define MCONTROL_ACTION_TRACE_EMIT        4
+
+#define MCONTROL_MATCH_EQUAL     0
+#define MCONTROL_MATCH_NAPOT     1
+#define MCONTROL_MATCH_GE        2
+#define MCONTROL_MATCH_LT        3
+#define MCONTROL_MATCH_MASK_LOW  4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_USIP            (1 << IRQ_U_SOFT)
+#define MIP_SSIP            (1 << IRQ_S_SOFT)
+#define MIP_HSIP            (1 << IRQ_H_SOFT)
+#define MIP_MSIP            (1 << IRQ_M_SOFT)
+#define MIP_UTIP            (1 << IRQ_U_TIMER)
+#define MIP_STIP            (1 << IRQ_S_TIMER)
+#define MIP_HTIP            (1 << IRQ_H_TIMER)
+#define MIP_MTIP            (1 << IRQ_M_TIMER)
+#define MIP_UEIP            (1 << IRQ_U_EXT)
+#define MIP_SEIP            (1 << IRQ_S_EXT)
+#define MIP_HEIP            (1 << IRQ_H_EXT)
+#define MIP_MEIP            (1 << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7FC00000
+#define SATP32_PPN  0x003FFFFF
+#define SATP64_MODE 0xF000000000000000
+#define SATP64_ASID 0x0FFFF00000000000
+#define SATP64_PPN  0x00000FFFFFFFFFFF
+
+#define SATP_MODE_OFF  0
+#define SATP_MODE_SV32 1
+#define SATP_MODE_SV39 8
+#define SATP_MODE_SV48 9
+#define SATP_MODE_SV57 10
+#define SATP_MODE_SV64 11
+
+#define PMP_R     0x01
+#define PMP_W     0x02
+#define PMP_X     0x04
+#define PMP_A     0x18
+#define PMP_L     0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR   0x08
+#define PMP_NA4   0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_U_SOFT   0
+#define IRQ_S_SOFT   1
+#define IRQ_H_SOFT   2
+#define IRQ_M_SOFT   3
+#define IRQ_U_TIMER  4
+#define IRQ_S_TIMER  5
+#define IRQ_H_TIMER  6
+#define IRQ_M_TIMER  7
+#define IRQ_U_EXT    8
+#define IRQ_S_EXT    9
+#define IRQ_H_EXT    10
+#define IRQ_M_EXT    11
+#define IRQ_COP      12
+#define IRQ_HOST     13
+
+#define DEFAULT_RSTVEC     0x00001000
+#define CLINT_BASE         0x02000000
+#define CLINT_SIZE         0x000c0000
+#define EXT_IO_BASE        0x40000000
+#define DRAM_BASE          0x80000000
+
+/* page table entry (PTE) fields */
+#define PTE_V     0x001 /* Valid */
+#define PTE_R     0x002 /* Read */
+#define PTE_W     0x004 /* Write */
+#define PTE_X     0x008 /* Execute */
+#define PTE_U     0x010 /* User */
+#define PTE_G     0x020 /* Global */
+#define PTE_A     0x040 /* Accessed */
+#define PTE_D     0x080 /* Dirty */
+#define PTE_SOFT  0x300 /* Reserved for Software */
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SATP_MODE SATP64_MODE
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SATP_MODE SATP32_MODE
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_csr(reg) ({ unsigned long __tmp; \
+  asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+  __tmp; })
+
+#define write_csr(reg, val) ({ \
+  asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+  asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+  __tmp; })
+
+#define set_csr(reg, bit) ({ unsigned long __tmp; \
+  asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+  __tmp; })
+
+#define clear_csr(reg, bit) ({ unsigned long __tmp; \
+  asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+  __tmp; })
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse_opcodes.  */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_BEQ 0x63
+#define MASK_BEQ  0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE  0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT  0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE  0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU  0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU  0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR  0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL  0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI  0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC  0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI  0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI  0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI  0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU  0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI  0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI  0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI  0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI  0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI  0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD  0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB  0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL  0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT  0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU  0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR  0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL  0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA  0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR  0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND  0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW  0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW  0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW  0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW  0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW  0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW  0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW  0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW  0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW  0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB  0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH  0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW  0x707f
+#define MATCH_LD 0x3003
+#define MASK_LD  0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU  0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU  0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU  0x707f
+#define MATCH_SB 0x23
+#define MASK_SB  0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH  0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW  0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD  0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE  0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I  0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL  0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH  0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU  0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU  0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV  0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU  0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM  0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU  0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW  0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW  0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW  0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW  0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW  0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W  0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W  0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W  0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W  0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W  0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W  0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W  0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W  0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W  0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W  0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W  0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D  0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D  0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D  0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D  0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D  0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D  0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D  0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D  0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D  0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D  0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D  0xf800707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL  0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK  0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET  0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET  0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET  0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET  0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA  0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI  0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW  0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS  0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC  0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI  0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI  0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI  0x707f
+#define MATCH_HFENCE_VVMA 0x22000073
+#define MASK_HFENCE_VVMA  0xfe007fff
+#define MATCH_HFENCE_GVMA 0x62000073
+#define MASK_HFENCE_GVMA  0xfe007fff
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S  0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S  0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S  0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S  0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S  0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S  0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S  0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S  0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S  0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S  0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D  0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D  0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D  0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D  0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D  0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D  0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D  0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D  0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D  0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D  0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S  0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D  0xfff0007f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q  0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q  0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q  0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q  0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q  0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q  0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q  0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q  0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q  0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q  0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S  0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q  0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D  0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q  0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S  0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S  0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S  0xfe00707f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D  0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D  0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D  0xfe00707f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q  0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q  0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q  0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S  0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S  0xfff0007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S  0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S  0xfff0007f
+#define MATCH_FMV_X_W 0xe0000053
+#define MASK_FMV_X_W  0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S  0xfff0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D  0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D  0xfff0007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D  0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D  0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D  0xfff0707f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D  0xfff0707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q  0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q  0xfff0007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q  0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q  0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q  0xfff0707f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q  0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W  0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU  0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L  0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU  0xfff0007f
+#define MATCH_FMV_W_X 0xf0000053
+#define MASK_FMV_W_X  0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W  0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU  0xfff0007f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L  0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU  0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X  0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W  0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU  0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L  0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU  0xfff0007f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X  0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW  0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD  0x707f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ  0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW  0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD  0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ  0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S  0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S  0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S  0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S  0x600007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D  0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D  0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D  0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D  0x600007f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q  0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q  0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q  0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q  0x600007f
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP  0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP  0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR  0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR  0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK  0xffff
+#define MATCH_C_SRLI_RV32 0x8001
+#define MASK_C_SRLI_RV32  0xfc03
+#define MATCH_C_SRAI_RV32 0x8401
+#define MASK_C_SRAI_RV32  0xfc03
+#define MATCH_C_SLLI_RV32 0x2
+#define MASK_C_SLLI_RV32  0xf003
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD  0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD  0xe003
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW  0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP  0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP  0xe003
+#define MATCH_C_LQ 0x2000
+#define MASK_C_LQ  0xe003
+#define MATCH_C_SQ 0xa000
+#define MASK_C_SQ  0xe003
+#define MATCH_C_LQSP 0x2002
+#define MASK_C_LQSP  0xe003
+#define MATCH_C_SQSP 0xa002
+#define MASK_C_SQSP  0xe003
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN  0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD  0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW  0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW  0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD  0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW  0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW  0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI  0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL  0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI  0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI  0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI  0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI  0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI  0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB  0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR  0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR  0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND  0xfc63
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW  0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW  0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J  0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ  0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ  0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI  0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP  0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP  0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP  0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV  0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD  0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP  0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP  0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP  0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0  0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1  0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2  0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD  0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1  0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2  0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1  0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1  0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2  0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD  0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1  0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2  0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2  0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1  0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2  0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD  0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1  0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2  0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3  0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1  0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2  0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD  0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1  0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2  0x707f
+#define MATCH_VSETVLI 0x7057
+#define MASK_VSETVLI  0x8000707f
+#define MATCH_VSETVL 0x80007057
+#define MASK_VSETVL  0xfe00707f
+#define MATCH_VLB_V 0x10000007
+#define MASK_VLB_V  0x1df0707f
+#define MATCH_VLH_V 0x10005007
+#define MASK_VLH_V  0x1df0707f
+#define MATCH_VLW_V 0x10006007
+#define MASK_VLW_V  0x1df0707f
+#define MATCH_VLE_V 0x7007
+#define MASK_VLE_V  0x1df0707f
+#define MATCH_VLBU_V 0x7
+#define MASK_VLBU_V  0x1df0707f
+#define MATCH_VLHU_V 0x5007
+#define MASK_VLHU_V  0x1df0707f
+#define MATCH_VLWU_V 0x6007
+#define MASK_VLWU_V  0x1df0707f
+#define MATCH_VSB_V 0x27
+#define MASK_VSB_V  0x1df0707f
+#define MATCH_VSH_V 0x5027
+#define MASK_VSH_V  0x1df0707f
+#define MATCH_VSW_V 0x6027
+#define MASK_VSW_V  0x1df0707f
+#define MATCH_VSE_V 0x7027
+#define MASK_VSE_V  0x1df0707f
+#define MATCH_VLSB_V 0x18000007
+#define MASK_VLSB_V  0x1c00707f
+#define MATCH_VLSH_V 0x18005007
+#define MASK_VLSH_V  0x1c00707f
+#define MATCH_VLSW_V 0x18006007
+#define MASK_VLSW_V  0x1c00707f
+#define MATCH_VLSE_V 0x8007007
+#define MASK_VLSE_V  0x1c00707f
+#define MATCH_VLSBU_V 0x8000007
+#define MASK_VLSBU_V  0x1c00707f
+#define MATCH_VLSHU_V 0x8005007
+#define MASK_VLSHU_V  0x1c00707f
+#define MATCH_VLSWU_V 0x8006007
+#define MASK_VLSWU_V  0x1c00707f
+#define MATCH_VSSB_V 0x8000027
+#define MASK_VSSB_V  0x1c00707f
+#define MATCH_VSSH_V 0x8005027
+#define MASK_VSSH_V  0x1c00707f
+#define MATCH_VSSW_V 0x8006027
+#define MASK_VSSW_V  0x1c00707f
+#define MATCH_VSSE_V 0x8007027
+#define MASK_VSSE_V  0x1c00707f
+#define MATCH_VLXB_V 0x1c000007
+#define MASK_VLXB_V  0x1c00707f
+#define MATCH_VLXH_V 0x1c005007
+#define MASK_VLXH_V  0x1c00707f
+#define MATCH_VLXW_V 0x1c006007
+#define MASK_VLXW_V  0x1c00707f
+#define MATCH_VLXE_V 0xc007007
+#define MASK_VLXE_V  0x1c00707f
+#define MATCH_VLXBU_V 0xc000007
+#define MASK_VLXBU_V  0x1c00707f
+#define MATCH_VLXHU_V 0xc005007
+#define MASK_VLXHU_V  0x1c00707f
+#define MATCH_VLXWU_V 0xc006007
+#define MASK_VLXWU_V  0x1c00707f
+#define MATCH_VSXB_V 0xc000027
+#define MASK_VSXB_V  0x1c00707f
+#define MATCH_VSXH_V 0xc005027
+#define MASK_VSXH_V  0x1c00707f
+#define MATCH_VSXW_V 0xc006027
+#define MASK_VSXW_V  0x1c00707f
+#define MATCH_VSXE_V 0xc007027
+#define MASK_VSXE_V  0x1c00707f
+#define MATCH_VSUXB_V 0x1c000027
+#define MASK_VSUXB_V  0xfc00707f
+#define MATCH_VSUXH_V 0x1c005027
+#define MASK_VSUXH_V  0xfc00707f
+#define MATCH_VSUXW_V 0x1c006027
+#define MASK_VSUXW_V  0xfc00707f
+#define MATCH_VSUXE_V 0x1c007027
+#define MASK_VSUXE_V  0xfc00707f
+#define MATCH_VLBFF_V 0x11000007
+#define MASK_VLBFF_V  0x1df0707f
+#define MATCH_VLHFF_V 0x11005007
+#define MASK_VLHFF_V  0x1df0707f
+#define MATCH_VLWFF_V 0x11006007
+#define MASK_VLWFF_V  0x1df0707f
+#define MATCH_VLEFF_V 0x1007007
+#define MASK_VLEFF_V  0x1df0707f
+#define MATCH_VLBUFF_V 0x1000007
+#define MASK_VLBUFF_V  0x1df0707f
+#define MATCH_VLHUFF_V 0x1005007
+#define MASK_VLHUFF_V  0x1df0707f
+#define MATCH_VLWUFF_V 0x1006007
+#define MASK_VLWUFF_V  0x1df0707f
+#define MATCH_VL1R_V 0x2807007
+#define MASK_VL1R_V  0xfff0707f
+#define MATCH_VS1R_V 0x2807027
+#define MASK_VS1R_V  0xfff0707f
+#define MATCH_VFADD_VF 0x5057
+#define MASK_VFADD_VF  0xfc00707f
+#define MATCH_VFSUB_VF 0x8005057
+#define MASK_VFSUB_VF  0xfc00707f
+#define MATCH_VFMIN_VF 0x10005057
+#define MASK_VFMIN_VF  0xfc00707f
+#define MATCH_VFMAX_VF 0x18005057
+#define MASK_VFMAX_VF  0xfc00707f
+#define MATCH_VFSGNJ_VF 0x20005057
+#define MASK_VFSGNJ_VF  0xfc00707f
+#define MATCH_VFSGNJN_VF 0x24005057
+#define MASK_VFSGNJN_VF  0xfc00707f
+#define MATCH_VFSGNJX_VF 0x28005057
+#define MASK_VFSGNJX_VF  0xfc00707f
+#define MATCH_VFMV_S_F 0x42005057
+#define MASK_VFMV_S_F  0xfff0707f
+#define MATCH_VFMERGE_VFM 0x5c005057
+#define MASK_VFMERGE_VFM  0xfe00707f
+#define MATCH_VFMV_V_F 0x5e005057
+#define MASK_VFMV_V_F  0xfff0707f
+#define MATCH_VMFEQ_VF 0x60005057
+#define MASK_VMFEQ_VF  0xfc00707f
+#define MATCH_VMFLE_VF 0x64005057
+#define MASK_VMFLE_VF  0xfc00707f
+#define MATCH_VMFLT_VF 0x6c005057
+#define MASK_VMFLT_VF  0xfc00707f
+#define MATCH_VMFNE_VF 0x70005057
+#define MASK_VMFNE_VF  0xfc00707f
+#define MATCH_VMFGT_VF 0x74005057
+#define MASK_VMFGT_VF  0xfc00707f
+#define MATCH_VMFGE_VF 0x7c005057
+#define MASK_VMFGE_VF  0xfc00707f
+#define MATCH_VFDIV_VF 0x80005057
+#define MASK_VFDIV_VF  0xfc00707f
+#define MATCH_VFRDIV_VF 0x84005057
+#define MASK_VFRDIV_VF  0xfc00707f
+#define MATCH_VFMUL_VF 0x90005057
+#define MASK_VFMUL_VF  0xfc00707f
+#define MATCH_VFRSUB_VF 0x9c005057
+#define MASK_VFRSUB_VF  0xfc00707f
+#define MATCH_VFMADD_VF 0xa0005057
+#define MASK_VFMADD_VF  0xfc00707f
+#define MATCH_VFNMADD_VF 0xa4005057
+#define MASK_VFNMADD_VF  0xfc00707f
+#define MATCH_VFMSUB_VF 0xa8005057
+#define MASK_VFMSUB_VF  0xfc00707f
+#define MATCH_VFNMSUB_VF 0xac005057
+#define MASK_VFNMSUB_VF  0xfc00707f
+#define MATCH_VFMACC_VF 0xb0005057
+#define MASK_VFMACC_VF  0xfc00707f
+#define MATCH_VFNMACC_VF 0xb4005057
+#define MASK_VFNMACC_VF  0xfc00707f
+#define MATCH_VFMSAC_VF 0xb8005057
+#define MASK_VFMSAC_VF  0xfc00707f
+#define MATCH_VFNMSAC_VF 0xbc005057
+#define MASK_VFNMSAC_VF  0xfc00707f
+#define MATCH_VFWADD_VF 0xc0005057
+#define MASK_VFWADD_VF  0xfc00707f
+#define MATCH_VFWSUB_VF 0xc8005057
+#define MASK_VFWSUB_VF  0xfc00707f
+#define MATCH_VFWADD_WF 0xd0005057
+#define MASK_VFWADD_WF  0xfc00707f
+#define MATCH_VFWSUB_WF 0xd8005057
+#define MASK_VFWSUB_WF  0xfc00707f
+#define MATCH_VFWMUL_VF 0xe0005057
+#define MASK_VFWMUL_VF  0xfc00707f
+#define MATCH_VFWMACC_VF 0xf0005057
+#define MASK_VFWMACC_VF  0xfc00707f
+#define MATCH_VFWNMACC_VF 0xf4005057
+#define MASK_VFWNMACC_VF  0xfc00707f
+#define MATCH_VFWMSAC_VF 0xf8005057
+#define MASK_VFWMSAC_VF  0xfc00707f
+#define MATCH_VFWNMSAC_VF 0xfc005057
+#define MASK_VFWNMSAC_VF  0xfc00707f
+#define MATCH_VFADD_VV 0x1057
+#define MASK_VFADD_VV  0xfc00707f
+#define MATCH_VFREDSUM_VS 0x4001057
+#define MASK_VFREDSUM_VS  0xfc00707f
+#define MATCH_VFSUB_VV 0x8001057
+#define MASK_VFSUB_VV  0xfc00707f
+#define MATCH_VFREDOSUM_VS 0xc001057
+#define MASK_VFREDOSUM_VS  0xfc00707f
+#define MATCH_VFMIN_VV 0x10001057
+#define MASK_VFMIN_VV  0xfc00707f
+#define MATCH_VFREDMIN_VS 0x14001057
+#define MASK_VFREDMIN_VS  0xfc00707f
+#define MATCH_VFMAX_VV 0x18001057
+#define MASK_VFMAX_VV  0xfc00707f
+#define MATCH_VFREDMAX_VS 0x1c001057
+#define MASK_VFREDMAX_VS  0xfc00707f
+#define MATCH_VFSGNJ_VV 0x20001057
+#define MASK_VFSGNJ_VV  0xfc00707f
+#define MATCH_VFSGNJN_VV 0x24001057
+#define MASK_VFSGNJN_VV  0xfc00707f
+#define MATCH_VFSGNJX_VV 0x28001057
+#define MASK_VFSGNJX_VV  0xfc00707f
+#define MATCH_VFMV_F_S 0x42001057
+#define MASK_VFMV_F_S  0xfe0ff07f
+#define MATCH_VMFEQ_VV 0x60001057
+#define MASK_VMFEQ_VV  0xfc00707f
+#define MATCH_VMFLE_VV 0x64001057
+#define MASK_VMFLE_VV  0xfc00707f
+#define MATCH_VMFLT_VV 0x6c001057
+#define MASK_VMFLT_VV  0xfc00707f
+#define MATCH_VMFNE_VV 0x70001057
+#define MASK_VMFNE_VV  0xfc00707f
+#define MATCH_VFDIV_VV 0x80001057
+#define MASK_VFDIV_VV  0xfc00707f
+#define MATCH_VFMUL_VV 0x90001057
+#define MASK_VFMUL_VV  0xfc00707f
+#define MATCH_VFMADD_VV 0xa0001057
+#define MASK_VFMADD_VV  0xfc00707f
+#define MATCH_VFNMADD_VV 0xa4001057
+#define MASK_VFNMADD_VV  0xfc00707f
+#define MATCH_VFMSUB_VV 0xa8001057
+#define MASK_VFMSUB_VV  0xfc00707f
+#define MATCH_VFNMSUB_VV 0xac001057
+#define MASK_VFNMSUB_VV  0xfc00707f
+#define MATCH_VFMACC_VV 0xb0001057
+#define MASK_VFMACC_VV  0xfc00707f
+#define MATCH_VFNMACC_VV 0xb4001057
+#define MASK_VFNMACC_VV  0xfc00707f
+#define MATCH_VFMSAC_VV 0xb8001057
+#define MASK_VFMSAC_VV  0xfc00707f
+#define MATCH_VFNMSAC_VV 0xbc001057
+#define MASK_VFNMSAC_VV  0xfc00707f
+#define MATCH_VFCVT_XU_F_V 0x88001057
+#define MASK_VFCVT_XU_F_V  0xfc0ff07f
+#define MATCH_VFCVT_X_F_V 0x88009057
+#define MASK_VFCVT_X_F_V  0xfc0ff07f
+#define MATCH_VFCVT_F_XU_V 0x88011057
+#define MASK_VFCVT_F_XU_V  0xfc0ff07f
+#define MATCH_VFCVT_F_X_V 0x88019057
+#define MASK_VFCVT_F_X_V  0xfc0ff07f
+#define MATCH_VFWCVT_XU_F_V 0x88041057
+#define MASK_VFWCVT_XU_F_V  0xfc0ff07f
+#define MATCH_VFWCVT_X_F_V 0x88049057
+#define MASK_VFWCVT_X_F_V  0xfc0ff07f
+#define MATCH_VFWCVT_F_XU_V 0x88051057
+#define MASK_VFWCVT_F_XU_V  0xfc0ff07f
+#define MATCH_VFWCVT_F_X_V 0x88059057
+#define MASK_VFWCVT_F_X_V  0xfc0ff07f
+#define MATCH_VFWCVT_F_F_V 0x88061057
+#define MASK_VFWCVT_F_F_V  0xfc0ff07f
+#define MATCH_VFNCVT_XU_F_W 0x88081057
+#define MASK_VFNCVT_XU_F_W  0xfc0ff07f
+#define MATCH_VFNCVT_X_F_W 0x88089057
+#define MASK_VFNCVT_X_F_W  0xfc0ff07f
+#define MATCH_VFNCVT_F_XU_W 0x88091057
+#define MASK_VFNCVT_F_XU_W  0xfc0ff07f
+#define MATCH_VFNCVT_F_X_W 0x88099057
+#define MASK_VFNCVT_F_X_W  0xfc0ff07f
+#define MATCH_VFNCVT_F_F_W 0x880a1057
+#define MASK_VFNCVT_F_F_W  0xfc0ff07f
+#define MATCH_VFNCVT_ROD_F_F_W 0x880a9057
+#define MASK_VFNCVT_ROD_F_F_W  0xfc0ff07f
+#define MATCH_VFSQRT_V 0x8c001057
+#define MASK_VFSQRT_V  0xfc0ff07f
+#define MATCH_VFCLASS_V 0x8c081057
+#define MASK_VFCLASS_V  0xfc0ff07f
+#define MATCH_VFWADD_VV 0xc0001057
+#define MASK_VFWADD_VV  0xfc00707f
+#define MATCH_VFWREDSUM_VS 0xc4001057
+#define MASK_VFWREDSUM_VS  0xfc00707f
+#define MATCH_VFWSUB_VV 0xc8001057
+#define MASK_VFWSUB_VV  0xfc00707f
+#define MATCH_VFWREDOSUM_VS 0xcc001057
+#define MASK_VFWREDOSUM_VS  0xfc00707f
+#define MATCH_VFWADD_WV 0xd0001057
+#define MASK_VFWADD_WV  0xfc00707f
+#define MATCH_VFWSUB_WV 0xd8001057
+#define MASK_VFWSUB_WV  0xfc00707f
+#define MATCH_VFWMUL_VV 0xe0001057
+#define MASK_VFWMUL_VV  0xfc00707f
+#define MATCH_VFDOT_VV 0xe4001057
+#define MASK_VFDOT_VV  0xfc00707f
+#define MATCH_VFWMACC_VV 0xf0001057
+#define MASK_VFWMACC_VV  0xfc00707f
+#define MATCH_VFWNMACC_VV 0xf4001057
+#define MASK_VFWNMACC_VV  0xfc00707f
+#define MATCH_VFWMSAC_VV 0xf8001057
+#define MASK_VFWMSAC_VV  0xfc00707f
+#define MATCH_VFWNMSAC_VV 0xfc001057
+#define MASK_VFWNMSAC_VV  0xfc00707f
+#define MATCH_VADD_VX 0x4057
+#define MASK_VADD_VX  0xfc00707f
+#define MATCH_VSUB_VX 0x8004057
+#define MASK_VSUB_VX  0xfc00707f
+#define MATCH_VRSUB_VX 0xc004057
+#define MASK_VRSUB_VX  0xfc00707f
+#define MATCH_VMINU_VX 0x10004057
+#define MASK_VMINU_VX  0xfc00707f
+#define MATCH_VMIN_VX 0x14004057
+#define MASK_VMIN_VX  0xfc00707f
+#define MATCH_VMAXU_VX 0x18004057
+#define MASK_VMAXU_VX  0xfc00707f
+#define MATCH_VMAX_VX 0x1c004057
+#define MASK_VMAX_VX  0xfc00707f
+#define MATCH_VAND_VX 0x24004057
+#define MASK_VAND_VX  0xfc00707f
+#define MATCH_VOR_VX 0x28004057
+#define MASK_VOR_VX  0xfc00707f
+#define MATCH_VXOR_VX 0x2c004057
+#define MASK_VXOR_VX  0xfc00707f
+#define MATCH_VRGATHER_VX 0x30004057
+#define MASK_VRGATHER_VX  0xfc00707f
+#define MATCH_VSLIDEUP_VX 0x38004057
+#define MASK_VSLIDEUP_VX  0xfc00707f
+#define MATCH_VSLIDEDOWN_VX 0x3c004057
+#define MASK_VSLIDEDOWN_VX  0xfc00707f
+#define MATCH_VADC_VXM 0x40004057
+#define MASK_VADC_VXM  0xfe00707f
+#define MATCH_VMADC_VXM 0x44004057
+#define MASK_VMADC_VXM  0xfc00707f
+#define MATCH_VSBC_VXM 0x48004057
+#define MASK_VSBC_VXM  0xfe00707f
+#define MATCH_VMSBC_VXM 0x4c004057
+#define MASK_VMSBC_VXM  0xfc00707f
+#define MATCH_VMERGE_VXM 0x5c004057
+#define MASK_VMERGE_VXM  0xfe00707f
+#define MATCH_VMV_V_X 0x5e004057
+#define MASK_VMV_V_X  0xfff0707f
+#define MATCH_VMSEQ_VX 0x60004057
+#define MASK_VMSEQ_VX  0xfc00707f
+#define MATCH_VMSNE_VX 0x64004057
+#define MASK_VMSNE_VX  0xfc00707f
+#define MATCH_VMSLTU_VX 0x68004057
+#define MASK_VMSLTU_VX  0xfc00707f
+#define MATCH_VMSLT_VX 0x6c004057
+#define MASK_VMSLT_VX  0xfc00707f
+#define MATCH_VMSLEU_VX 0x70004057
+#define MASK_VMSLEU_VX  0xfc00707f
+#define MATCH_VMSLE_VX 0x74004057
+#define MASK_VMSLE_VX  0xfc00707f
+#define MATCH_VMSGTU_VX 0x78004057
+#define MASK_VMSGTU_VX  0xfc00707f
+#define MATCH_VMSGT_VX 0x7c004057
+#define MASK_VMSGT_VX  0xfc00707f
+#define MATCH_VSADDU_VX 0x80004057
+#define MASK_VSADDU_VX  0xfc00707f
+#define MATCH_VSADD_VX 0x84004057
+#define MASK_VSADD_VX  0xfc00707f
+#define MATCH_VSSUBU_VX 0x88004057
+#define MASK_VSSUBU_VX  0xfc00707f
+#define MATCH_VSSUB_VX 0x8c004057
+#define MASK_VSSUB_VX  0xfc00707f
+#define MATCH_VSLL_VX 0x94004057
+#define MASK_VSLL_VX  0xfc00707f
+#define MATCH_VSMUL_VX 0x9c004057
+#define MASK_VSMUL_VX  0xfc00707f
+#define MATCH_VSRL_VX 0xa0004057
+#define MASK_VSRL_VX  0xfc00707f
+#define MATCH_VSRA_VX 0xa4004057
+#define MASK_VSRA_VX  0xfc00707f
+#define MATCH_VSSRL_VX 0xa8004057
+#define MASK_VSSRL_VX  0xfc00707f
+#define MATCH_VSSRA_VX 0xac004057
+#define MASK_VSSRA_VX  0xfc00707f
+#define MATCH_VNSRL_WX 0xb0004057
+#define MASK_VNSRL_WX  0xfc00707f
+#define MATCH_VNSRA_WX 0xb4004057
+#define MASK_VNSRA_WX  0xfc00707f
+#define MATCH_VNCLIPU_WX 0xb8004057
+#define MASK_VNCLIPU_WX  0xfc00707f
+#define MATCH_VNCLIP_WX 0xbc004057
+#define MASK_VNCLIP_WX  0xfc00707f
+#define MATCH_VQMACCU_VX 0xf0004057
+#define MASK_VQMACCU_VX  0xfc00707f
+#define MATCH_VQMACC_VX 0xf4004057
+#define MASK_VQMACC_VX  0xfc00707f
+#define MATCH_VQMACCUS_VX 0xf8004057
+#define MASK_VQMACCUS_VX  0xfc00707f
+#define MATCH_VQMACCSU_VX 0xfc004057
+#define MASK_VQMACCSU_VX  0xfc00707f
+#define MATCH_VADD_VV 0x57
+#define MASK_VADD_VV  0xfc00707f
+#define MATCH_VSUB_VV 0x8000057
+#define MASK_VSUB_VV  0xfc00707f
+#define MATCH_VMINU_VV 0x10000057
+#define MASK_VMINU_VV  0xfc00707f
+#define MATCH_VMIN_VV 0x14000057
+#define MASK_VMIN_VV  0xfc00707f
+#define MATCH_VMAXU_VV 0x18000057
+#define MASK_VMAXU_VV  0xfc00707f
+#define MATCH_VMAX_VV 0x1c000057
+#define MASK_VMAX_VV  0xfc00707f
+#define MATCH_VAND_VV 0x24000057
+#define MASK_VAND_VV  0xfc00707f
+#define MATCH_VOR_VV 0x28000057
+#define MASK_VOR_VV  0xfc00707f
+#define MATCH_VXOR_VV 0x2c000057
+#define MASK_VXOR_VV  0xfc00707f
+#define MATCH_VRGATHER_VV 0x30000057
+#define MASK_VRGATHER_VV  0xfc00707f
+#define MATCH_VADC_VVM 0x40000057
+#define MASK_VADC_VVM  0xfe00707f
+#define MATCH_VMADC_VVM 0x44000057
+#define MASK_VMADC_VVM  0xfc00707f
+#define MATCH_VSBC_VVM 0x48000057
+#define MASK_VSBC_VVM  0xfe00707f
+#define MATCH_VMSBC_VVM 0x4c000057
+#define MASK_VMSBC_VVM  0xfc00707f
+#define MATCH_VMERGE_VVM 0x5c000057
+#define MASK_VMERGE_VVM  0xfe00707f
+#define MATCH_VMV_V_V 0x5e000057
+#define MASK_VMV_V_V  0xfff0707f
+#define MATCH_VMSEQ_VV 0x60000057
+#define MASK_VMSEQ_VV  0xfc00707f
+#define MATCH_VMSNE_VV 0x64000057
+#define MASK_VMSNE_VV  0xfc00707f
+#define MATCH_VMSLTU_VV 0x68000057
+#define MASK_VMSLTU_VV  0xfc00707f
+#define MATCH_VMSLT_VV 0x6c000057
+#define MASK_VMSLT_VV  0xfc00707f
+#define MATCH_VMSLEU_VV 0x70000057
+#define MASK_VMSLEU_VV  0xfc00707f
+#define MATCH_VMSLE_VV 0x74000057
+#define MASK_VMSLE_VV  0xfc00707f
+#define MATCH_VSADDU_VV 0x80000057
+#define MASK_VSADDU_VV  0xfc00707f
+#define MATCH_VSADD_VV 0x84000057
+#define MASK_VSADD_VV  0xfc00707f
+#define MATCH_VSSUBU_VV 0x88000057
+#define MASK_VSSUBU_VV  0xfc00707f
+#define MATCH_VSSUB_VV 0x8c000057
+#define MASK_VSSUB_VV  0xfc00707f
+#define MATCH_VSLL_VV 0x94000057
+#define MASK_VSLL_VV  0xfc00707f
+#define MATCH_VSMUL_VV 0x9c000057
+#define MASK_VSMUL_VV  0xfc00707f
+#define MATCH_VSRL_VV 0xa0000057
+#define MASK_VSRL_VV  0xfc00707f
+#define MATCH_VSRA_VV 0xa4000057
+#define MASK_VSRA_VV  0xfc00707f
+#define MATCH_VSSRL_VV 0xa8000057
+#define MASK_VSSRL_VV  0xfc00707f
+#define MATCH_VSSRA_VV 0xac000057
+#define MASK_VSSRA_VV  0xfc00707f
+#define MATCH_VNSRL_WV 0xb0000057
+#define MASK_VNSRL_WV  0xfc00707f
+#define MATCH_VNSRA_WV 0xb4000057
+#define MASK_VNSRA_WV  0xfc00707f
+#define MATCH_VNCLIPU_WV 0xb8000057
+#define MASK_VNCLIPU_WV  0xfc00707f
+#define MATCH_VNCLIP_WV 0xbc000057
+#define MASK_VNCLIP_WV  0xfc00707f
+#define MATCH_VWREDSUMU_VS 0xc0000057
+#define MASK_VWREDSUMU_VS  0xfc00707f
+#define MATCH_VWREDSUM_VS 0xc4000057
+#define MASK_VWREDSUM_VS  0xfc00707f
+#define MATCH_VDOTU_VV 0xe0000057
+#define MASK_VDOTU_VV  0xfc00707f
+#define MATCH_VDOT_VV 0xe4000057
+#define MASK_VDOT_VV  0xfc00707f
+#define MATCH_VQMACCU_VV 0xf0000057
+#define MASK_VQMACCU_VV  0xfc00707f
+#define MATCH_VQMACC_VV 0xf4000057
+#define MASK_VQMACC_VV  0xfc00707f
+#define MATCH_VQMACCSU_VV 0xfc000057
+#define MASK_VQMACCSU_VV  0xfc00707f
+#define MATCH_VADD_VI 0x3057
+#define MASK_VADD_VI  0xfc00707f
+#define MATCH_VRSUB_VI 0xc003057
+#define MASK_VRSUB_VI  0xfc00707f
+#define MATCH_VAND_VI 0x24003057
+#define MASK_VAND_VI  0xfc00707f
+#define MATCH_VOR_VI 0x28003057
+#define MASK_VOR_VI  0xfc00707f
+#define MATCH_VXOR_VI 0x2c003057
+#define MASK_VXOR_VI  0xfc00707f
+#define MATCH_VRGATHER_VI 0x30003057
+#define MASK_VRGATHER_VI  0xfc00707f
+#define MATCH_VSLIDEUP_VI 0x38003057
+#define MASK_VSLIDEUP_VI  0xfc00707f
+#define MATCH_VSLIDEDOWN_VI 0x3c003057
+#define MASK_VSLIDEDOWN_VI  0xfc00707f
+#define MATCH_VADC_VIM 0x40003057
+#define MASK_VADC_VIM  0xfe00707f
+#define MATCH_VMADC_VIM 0x44003057
+#define MASK_VMADC_VIM  0xfc00707f
+#define MATCH_VMERGE_VIM 0x5c003057
+#define MASK_VMERGE_VIM  0xfe00707f
+#define MATCH_VMV_V_I 0x5e003057
+#define MASK_VMV_V_I  0xfff0707f
+#define MATCH_VMSEQ_VI 0x60003057
+#define MASK_VMSEQ_VI  0xfc00707f
+#define MATCH_VMSNE_VI 0x64003057
+#define MASK_VMSNE_VI  0xfc00707f
+#define MATCH_VMSLEU_VI 0x70003057
+#define MASK_VMSLEU_VI  0xfc00707f
+#define MATCH_VMSLE_VI 0x74003057
+#define MASK_VMSLE_VI  0xfc00707f
+#define MATCH_VMSGTU_VI 0x78003057
+#define MASK_VMSGTU_VI  0xfc00707f
+#define MATCH_VMSGT_VI 0x7c003057
+#define MASK_VMSGT_VI  0xfc00707f
+#define MATCH_VSADDU_VI 0x80003057
+#define MASK_VSADDU_VI  0xfc00707f
+#define MATCH_VSADD_VI 0x84003057
+#define MASK_VSADD_VI  0xfc00707f
+#define MATCH_VSLL_VI 0x94003057
+#define MASK_VSLL_VI  0xfc00707f
+#define MATCH_VMV1R_V 0x9e003057
+#define MASK_VMV1R_V  0xfe0ff07f
+#define MATCH_VMV2R_V 0x9e00b057
+#define MASK_VMV2R_V  0xfe0ff07f
+#define MATCH_VMV4R_V 0x9e01b057
+#define MASK_VMV4R_V  0xfe0ff07f
+#define MATCH_VMV8R_V 0x9e03b057
+#define MASK_VMV8R_V  0xfe0ff07f
+#define MATCH_VSRL_VI 0xa0003057
+#define MASK_VSRL_VI  0xfc00707f
+#define MATCH_VSRA_VI 0xa4003057
+#define MASK_VSRA_VI  0xfc00707f
+#define MATCH_VSSRL_VI 0xa8003057
+#define MASK_VSSRL_VI  0xfc00707f
+#define MATCH_VSSRA_VI 0xac003057
+#define MASK_VSSRA_VI  0xfc00707f
+#define MATCH_VNSRL_WI 0xb0003057
+#define MASK_VNSRL_WI  0xfc00707f
+#define MATCH_VNSRA_WI 0xb4003057
+#define MASK_VNSRA_WI  0xfc00707f
+#define MATCH_VNCLIPU_WI 0xb8003057
+#define MASK_VNCLIPU_WI  0xfc00707f
+#define MATCH_VNCLIP_WI 0xbc003057
+#define MASK_VNCLIP_WI  0xfc00707f
+#define MATCH_VREDSUM_VS 0x2057
+#define MASK_VREDSUM_VS  0xfc00707f
+#define MATCH_VREDAND_VS 0x4002057
+#define MASK_VREDAND_VS  0xfc00707f
+#define MATCH_VREDOR_VS 0x8002057
+#define MASK_VREDOR_VS  0xfc00707f
+#define MATCH_VREDXOR_VS 0xc002057
+#define MASK_VREDXOR_VS  0xfc00707f
+#define MATCH_VREDMINU_VS 0x10002057
+#define MASK_VREDMINU_VS  0xfc00707f
+#define MATCH_VREDMIN_VS 0x14002057
+#define MASK_VREDMIN_VS  0xfc00707f
+#define MATCH_VREDMAXU_VS 0x18002057
+#define MASK_VREDMAXU_VS  0xfc00707f
+#define MATCH_VREDMAX_VS 0x1c002057
+#define MASK_VREDMAX_VS  0xfc00707f
+#define MATCH_VAADDU_VV 0x20002057
+#define MASK_VAADDU_VV  0xfc00707f
+#define MATCH_VAADD_VV 0x24002057
+#define MASK_VAADD_VV  0xfc00707f
+#define MATCH_VASUBU_VV 0x28002057
+#define MASK_VASUBU_VV  0xfc00707f
+#define MATCH_VASUB_VV 0x2c002057
+#define MASK_VASUB_VV  0xfc00707f
+#define MATCH_VMV_X_S 0x42002057
+#define MASK_VMV_X_S  0xfe0ff07f
+#define MATCH_VCOMPRESS_VM 0x5e002057
+#define MASK_VCOMPRESS_VM  0xfe00707f
+#define MATCH_VMANDNOT_MM 0x60002057
+#define MASK_VMANDNOT_MM  0xfc00707f
+#define MATCH_VMAND_MM 0x64002057
+#define MASK_VMAND_MM  0xfc00707f
+#define MATCH_VMOR_MM 0x68002057
+#define MASK_VMOR_MM  0xfc00707f
+#define MATCH_VMXOR_MM 0x6c002057
+#define MASK_VMXOR_MM  0xfc00707f
+#define MATCH_VMORNOT_MM 0x70002057
+#define MASK_VMORNOT_MM  0xfc00707f
+#define MATCH_VMNAND_MM 0x74002057
+#define MASK_VMNAND_MM  0xfc00707f
+#define MATCH_VMNOR_MM 0x78002057
+#define MASK_VMNOR_MM  0xfc00707f
+#define MATCH_VMXNOR_MM 0x7c002057
+#define MASK_VMXNOR_MM  0xfc00707f
+#define MATCH_VMSBF_M 0x5000a057
+#define MASK_VMSBF_M  0xfc0ff07f
+#define MATCH_VMSOF_M 0x50012057
+#define MASK_VMSOF_M  0xfc0ff07f
+#define MATCH_VMSIF_M 0x5001a057
+#define MASK_VMSIF_M  0xfc0ff07f
+#define MATCH_VIOTA_M 0x50082057
+#define MASK_VIOTA_M  0xfc0ff07f
+#define MATCH_VID_V 0x5008a057
+#define MASK_VID_V  0xfdfff07f
+#define MATCH_VPOPC_M 0x40082057
+#define MASK_VPOPC_M  0xfc0ff07f
+#define MATCH_VFIRST_M 0x4008a057
+#define MASK_VFIRST_M  0xfc0ff07f
+#define MATCH_VDIVU_VV 0x80002057
+#define MASK_VDIVU_VV  0xfc00707f
+#define MATCH_VDIV_VV 0x84002057
+#define MASK_VDIV_VV  0xfc00707f
+#define MATCH_VREMU_VV 0x88002057
+#define MASK_VREMU_VV  0xfc00707f
+#define MATCH_VREM_VV 0x8c002057
+#define MASK_VREM_VV  0xfc00707f
+#define MATCH_VMULHU_VV 0x90002057
+#define MASK_VMULHU_VV  0xfc00707f
+#define MATCH_VMUL_VV 0x94002057
+#define MASK_VMUL_VV  0xfc00707f
+#define MATCH_VMULHSU_VV 0x98002057
+#define MASK_VMULHSU_VV  0xfc00707f
+#define MATCH_VMULH_VV 0x9c002057
+#define MASK_VMULH_VV  0xfc00707f
+#define MATCH_VMADD_VV 0xa4002057
+#define MASK_VMADD_VV  0xfc00707f
+#define MATCH_VNMSUB_VV 0xac002057
+#define MASK_VNMSUB_VV  0xfc00707f
+#define MATCH_VMACC_VV 0xb4002057
+#define MASK_VMACC_VV  0xfc00707f
+#define MATCH_VNMSAC_VV 0xbc002057
+#define MASK_VNMSAC_VV  0xfc00707f
+#define MATCH_VWADDU_VV 0xc0002057
+#define MASK_VWADDU_VV  0xfc00707f
+#define MATCH_VWADD_VV 0xc4002057
+#define MASK_VWADD_VV  0xfc00707f
+#define MATCH_VWSUBU_VV 0xc8002057
+#define MASK_VWSUBU_VV  0xfc00707f
+#define MATCH_VWSUB_VV 0xcc002057
+#define MASK_VWSUB_VV  0xfc00707f
+#define MATCH_VWADDU_WV 0xd0002057
+#define MASK_VWADDU_WV  0xfc00707f
+#define MATCH_VWADD_WV 0xd4002057
+#define MASK_VWADD_WV  0xfc00707f
+#define MATCH_VWSUBU_WV 0xd8002057
+#define MASK_VWSUBU_WV  0xfc00707f
+#define MATCH_VWSUB_WV 0xdc002057
+#define MASK_VWSUB_WV  0xfc00707f
+#define MATCH_VWMULU_VV 0xe0002057
+#define MASK_VWMULU_VV  0xfc00707f
+#define MATCH_VWMULSU_VV 0xe8002057
+#define MASK_VWMULSU_VV  0xfc00707f
+#define MATCH_VWMUL_VV 0xec002057
+#define MASK_VWMUL_VV  0xfc00707f
+#define MATCH_VWMACCU_VV 0xf0002057
+#define MASK_VWMACCU_VV  0xfc00707f
+#define MATCH_VWMACC_VV 0xf4002057
+#define MASK_VWMACC_VV  0xfc00707f
+#define MATCH_VWMACCSU_VV 0xfc002057
+#define MASK_VWMACCSU_VV  0xfc00707f
+#define MATCH_VAADDU_VX 0x20006057
+#define MASK_VAADDU_VX  0xfc00707f
+#define MATCH_VAADD_VX 0x24006057
+#define MASK_VAADD_VX  0xfc00707f
+#define MATCH_VASUBU_VX 0x28006057
+#define MASK_VASUBU_VX  0xfc00707f
+#define MATCH_VASUB_VX 0x2c006057
+#define MASK_VASUB_VX  0xfc00707f
+#define MATCH_VMV_S_X 0x42006057
+#define MASK_VMV_S_X  0xfff0707f
+#define MATCH_VSLIDE1UP_VX 0x38006057
+#define MASK_VSLIDE1UP_VX  0xfc00707f
+#define MATCH_VSLIDE1DOWN_VX 0x3c006057
+#define MASK_VSLIDE1DOWN_VX  0xfc00707f
+#define MATCH_VDIVU_VX 0x80006057
+#define MASK_VDIVU_VX  0xfc00707f
+#define MATCH_VDIV_VX 0x84006057
+#define MASK_VDIV_VX  0xfc00707f
+#define MATCH_VREMU_VX 0x88006057
+#define MASK_VREMU_VX  0xfc00707f
+#define MATCH_VREM_VX 0x8c006057
+#define MASK_VREM_VX  0xfc00707f
+#define MATCH_VMULHU_VX 0x90006057
+#define MASK_VMULHU_VX  0xfc00707f
+#define MATCH_VMUL_VX 0x94006057
+#define MASK_VMUL_VX  0xfc00707f
+#define MATCH_VMULHSU_VX 0x98006057
+#define MASK_VMULHSU_VX  0xfc00707f
+#define MATCH_VMULH_VX 0x9c006057
+#define MASK_VMULH_VX  0xfc00707f
+#define MATCH_VMADD_VX 0xa4006057
+#define MASK_VMADD_VX  0xfc00707f
+#define MATCH_VNMSUB_VX 0xac006057
+#define MASK_VNMSUB_VX  0xfc00707f
+#define MATCH_VMACC_VX 0xb4006057
+#define MASK_VMACC_VX  0xfc00707f
+#define MATCH_VNMSAC_VX 0xbc006057
+#define MASK_VNMSAC_VX  0xfc00707f
+#define MATCH_VWADDU_VX 0xc0006057
+#define MASK_VWADDU_VX  0xfc00707f
+#define MATCH_VWADD_VX 0xc4006057
+#define MASK_VWADD_VX  0xfc00707f
+#define MATCH_VWSUBU_VX 0xc8006057
+#define MASK_VWSUBU_VX  0xfc00707f
+#define MATCH_VWSUB_VX 0xcc006057
+#define MASK_VWSUB_VX  0xfc00707f
+#define MATCH_VWADDU_WX 0xd0006057
+#define MASK_VWADDU_WX  0xfc00707f
+#define MATCH_VWADD_WX 0xd4006057
+#define MASK_VWADD_WX  0xfc00707f
+#define MATCH_VWSUBU_WX 0xd8006057
+#define MASK_VWSUBU_WX  0xfc00707f
+#define MATCH_VWSUB_WX 0xdc006057
+#define MASK_VWSUB_WX  0xfc00707f
+#define MATCH_VWMULU_VX 0xe0006057
+#define MASK_VWMULU_VX  0xfc00707f
+#define MATCH_VWMULSU_VX 0xe8006057
+#define MASK_VWMULSU_VX  0xfc00707f
+#define MATCH_VWMUL_VX 0xec006057
+#define MASK_VWMUL_VX  0xfc00707f
+#define MATCH_VWMACCU_VX 0xf0006057
+#define MASK_VWMACCU_VX  0xfc00707f
+#define MATCH_VWMACC_VX 0xf4006057
+#define MASK_VWMACC_VX  0xfc00707f
+#define MATCH_VWMACCUS_VX 0xf8006057
+#define MASK_VWMACCUS_VX  0xfc00707f
+#define MATCH_VWMACCSU_VX 0xfc006057
+#define MASK_VWMACCSU_VX  0xfc00707f
+#define MATCH_VAMOSWAPW_V 0x800602f
+#define MASK_VAMOSWAPW_V  0xf800707f
+#define MATCH_VAMOADDW_V 0x602f
+#define MASK_VAMOADDW_V  0xf800707f
+#define MATCH_VAMOXORW_V 0x2000602f
+#define MASK_VAMOXORW_V  0xf800707f
+#define MATCH_VAMOANDW_V 0x6000602f
+#define MASK_VAMOANDW_V  0xf800707f
+#define MATCH_VAMOORW_V 0x4000602f
+#define MASK_VAMOORW_V  0xf800707f
+#define MATCH_VAMOMINW_V 0x8000602f
+#define MASK_VAMOMINW_V  0xf800707f
+#define MATCH_VAMOMAXW_V 0xa000602f
+#define MASK_VAMOMAXW_V  0xf800707f
+#define MATCH_VAMOMINUW_V 0xc000602f
+#define MASK_VAMOMINUW_V  0xf800707f
+#define MATCH_VAMOMAXUW_V 0xe000602f
+#define MASK_VAMOMAXUW_V  0xf800707f
+#define MATCH_VAMOSWAPE_V 0x800702f
+#define MASK_VAMOSWAPE_V  0xf800707f
+#define MATCH_VAMOADDE_V 0x702f
+#define MASK_VAMOADDE_V  0xf800707f
+#define MATCH_VAMOXORE_V 0x2000702f
+#define MASK_VAMOXORE_V  0xf800707f
+#define MATCH_VAMOANDE_V 0x6000702f
+#define MASK_VAMOANDE_V  0xf800707f
+#define MATCH_VAMOORE_V 0x4000702f
+#define MASK_VAMOORE_V  0xf800707f
+#define MATCH_VAMOMINE_V 0x8000702f
+#define MASK_VAMOMINE_V  0xf800707f
+#define MATCH_VAMOMAXE_V 0xa000702f
+#define MASK_VAMOMAXE_V  0xf800707f
+#define MATCH_VAMOMINUE_V 0xc000702f
+#define MASK_VAMOMINUE_V  0xf800707f
+#define MATCH_VAMOMAXUE_V 0xe000702f
+#define MASK_VAMOMAXUE_V  0xf800707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_USTATUS 0x0
+#define CSR_UIE 0x4
+#define CSR_UTVEC 0x5
+#define CSR_VSTART 0x8
+#define CSR_VXSAT 0x9
+#define CSR_VXRM 0xa
+#define CSR_USCRATCH 0x40
+#define CSR_UEPC 0x41
+#define CSR_UCAUSE 0x42
+#define CSR_UTVAL 0x43
+#define CSR_UIP 0x44
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_VL 0xc20
+#define CSR_VTYPE 0xc21
+#define CSR_VLENB 0xc22
+#define CSR_SSTATUS 0x100
+#define CSR_SEDELEG 0x102
+#define CSR_SIDELEG 0x103
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_STVAL 0x143
+#define CSR_SIP 0x144
+#define CSR_SATP 0x180
+#define CSR_VSSTATUS 0x200
+#define CSR_VSIE 0x204
+#define CSR_VSTVEC 0x205
+#define CSR_VSSCRATCH 0x240
+#define CSR_VSEPC 0x241
+#define CSR_VSCAUSE 0x242
+#define CSR_VSTVAL 0x243
+#define CSR_VSIP 0x244
+#define CSR_VSATP 0x280
+#define CSR_HSTATUS 0x600
+#define CSR_HEDELEG 0x602
+#define CSR_HIDELEG 0x603
+#define CSR_HCOUNTEREN 0x606
+#define CSR_HGATP 0x680
+#define CSR_UTVT 0x7
+#define CSR_UNXTI 0x45
+#define CSR_UINTSTATUS 0x46
+#define CSR_USCRATCHCSW 0x48
+#define CSR_USCRATCHCSWL 0x49
+#define CSR_STVT 0x107
+#define CSR_SNXTI 0x145
+#define CSR_SINTSTATUS 0x146
+#define CSR_SSCRATCHCSW 0x148
+#define CSR_SSCRATCHCSWL 0x149
+#define CSR_MTVT 0x307
+#define CSR_MNXTI 0x345
+#define CSR_MINTSTATUS 0x346
+#define CSR_MSCRATCHCSW 0x348
+#define CSR_MSCRATCHCSWL 0x349
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MTVAL 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA)
+DECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_srli_rv32, MATCH_C_SRLI_RV32, MASK_C_SRLI_RV32)
+DECLARE_INSN(c_srai_rv32, MATCH_C_SRAI_RV32, MASK_C_SRAI_RV32)
+DECLARE_INSN(c_slli_rv32, MATCH_C_SLLI_RV32, MASK_C_SLLI_RV32)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_lq, MATCH_C_LQ, MASK_C_LQ)
+DECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ)
+DECLARE_INSN(c_lqsp, MATCH_C_LQSP, MASK_C_LQSP)
+DECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI)
+DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL)
+DECLARE_INSN(vlb_v, MATCH_VLB_V, MASK_VLB_V)
+DECLARE_INSN(vlh_v, MATCH_VLH_V, MASK_VLH_V)
+DECLARE_INSN(vlw_v, MATCH_VLW_V, MASK_VLW_V)
+DECLARE_INSN(vle_v, MATCH_VLE_V, MASK_VLE_V)
+DECLARE_INSN(vlbu_v, MATCH_VLBU_V, MASK_VLBU_V)
+DECLARE_INSN(vlhu_v, MATCH_VLHU_V, MASK_VLHU_V)
+DECLARE_INSN(vlwu_v, MATCH_VLWU_V, MASK_VLWU_V)
+DECLARE_INSN(vsb_v, MATCH_VSB_V, MASK_VSB_V)
+DECLARE_INSN(vsh_v, MATCH_VSH_V, MASK_VSH_V)
+DECLARE_INSN(vsw_v, MATCH_VSW_V, MASK_VSW_V)
+DECLARE_INSN(vse_v, MATCH_VSE_V, MASK_VSE_V)
+DECLARE_INSN(vlsb_v, MATCH_VLSB_V, MASK_VLSB_V)
+DECLARE_INSN(vlsh_v, MATCH_VLSH_V, MASK_VLSH_V)
+DECLARE_INSN(vlsw_v, MATCH_VLSW_V, MASK_VLSW_V)
+DECLARE_INSN(vlse_v, MATCH_VLSE_V, MASK_VLSE_V)
+DECLARE_INSN(vlsbu_v, MATCH_VLSBU_V, MASK_VLSBU_V)
+DECLARE_INSN(vlshu_v, MATCH_VLSHU_V, MASK_VLSHU_V)
+DECLARE_INSN(vlswu_v, MATCH_VLSWU_V, MASK_VLSWU_V)
+DECLARE_INSN(vssb_v, MATCH_VSSB_V, MASK_VSSB_V)
+DECLARE_INSN(vssh_v, MATCH_VSSH_V, MASK_VSSH_V)
+DECLARE_INSN(vssw_v, MATCH_VSSW_V, MASK_VSSW_V)
+DECLARE_INSN(vsse_v, MATCH_VSSE_V, MASK_VSSE_V)
+DECLARE_INSN(vlxb_v, MATCH_VLXB_V, MASK_VLXB_V)
+DECLARE_INSN(vlxh_v, MATCH_VLXH_V, MASK_VLXH_V)
+DECLARE_INSN(vlxw_v, MATCH_VLXW_V, MASK_VLXW_V)
+DECLARE_INSN(vlxe_v, MATCH_VLXE_V, MASK_VLXE_V)
+DECLARE_INSN(vlxbu_v, MATCH_VLXBU_V, MASK_VLXBU_V)
+DECLARE_INSN(vlxhu_v, MATCH_VLXHU_V, MASK_VLXHU_V)
+DECLARE_INSN(vlxwu_v, MATCH_VLXWU_V, MASK_VLXWU_V)
+DECLARE_INSN(vsxb_v, MATCH_VSXB_V, MASK_VSXB_V)
+DECLARE_INSN(vsxh_v, MATCH_VSXH_V, MASK_VSXH_V)
+DECLARE_INSN(vsxw_v, MATCH_VSXW_V, MASK_VSXW_V)
+DECLARE_INSN(vsxe_v, MATCH_VSXE_V, MASK_VSXE_V)
+DECLARE_INSN(vsuxb_v, MATCH_VSUXB_V, MASK_VSUXB_V)
+DECLARE_INSN(vsuxh_v, MATCH_VSUXH_V, MASK_VSUXH_V)
+DECLARE_INSN(vsuxw_v, MATCH_VSUXW_V, MASK_VSUXW_V)
+DECLARE_INSN(vsuxe_v, MATCH_VSUXE_V, MASK_VSUXE_V)
+DECLARE_INSN(vlbff_v, MATCH_VLBFF_V, MASK_VLBFF_V)
+DECLARE_INSN(vlhff_v, MATCH_VLHFF_V, MASK_VLHFF_V)
+DECLARE_INSN(vlwff_v, MATCH_VLWFF_V, MASK_VLWFF_V)
+DECLARE_INSN(vleff_v, MATCH_VLEFF_V, MASK_VLEFF_V)
+DECLARE_INSN(vlbuff_v, MATCH_VLBUFF_V, MASK_VLBUFF_V)
+DECLARE_INSN(vlhuff_v, MATCH_VLHUFF_V, MASK_VLHUFF_V)
+DECLARE_INSN(vlwuff_v, MATCH_VLWUFF_V, MASK_VLWUFF_V)
+DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
+DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)
+DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF)
+DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF)
+DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF)
+DECLARE_INSN(vfmax_vf, MATCH_VFMAX_VF, MASK_VFMAX_VF)
+DECLARE_INSN(vfsgnj_vf, MATCH_VFSGNJ_VF, MASK_VFSGNJ_VF)
+DECLARE_INSN(vfsgnjn_vf, MATCH_VFSGNJN_VF, MASK_VFSGNJN_VF)
+DECLARE_INSN(vfsgnjx_vf, MATCH_VFSGNJX_VF, MASK_VFSGNJX_VF)
+DECLARE_INSN(vfmv_s_f, MATCH_VFMV_S_F, MASK_VFMV_S_F)
+DECLARE_INSN(vfmerge_vfm, MATCH_VFMERGE_VFM, MASK_VFMERGE_VFM)
+DECLARE_INSN(vfmv_v_f, MATCH_VFMV_V_F, MASK_VFMV_V_F)
+DECLARE_INSN(vmfeq_vf, MATCH_VMFEQ_VF, MASK_VMFEQ_VF)
+DECLARE_INSN(vmfle_vf, MATCH_VMFLE_VF, MASK_VMFLE_VF)
+DECLARE_INSN(vmflt_vf, MATCH_VMFLT_VF, MASK_VMFLT_VF)
+DECLARE_INSN(vmfne_vf, MATCH_VMFNE_VF, MASK_VMFNE_VF)
+DECLARE_INSN(vmfgt_vf, MATCH_VMFGT_VF, MASK_VMFGT_VF)
+DECLARE_INSN(vmfge_vf, MATCH_VMFGE_VF, MASK_VMFGE_VF)
+DECLARE_INSN(vfdiv_vf, MATCH_VFDIV_VF, MASK_VFDIV_VF)
+DECLARE_INSN(vfrdiv_vf, MATCH_VFRDIV_VF, MASK_VFRDIV_VF)
+DECLARE_INSN(vfmul_vf, MATCH_VFMUL_VF, MASK_VFMUL_VF)
+DECLARE_INSN(vfrsub_vf, MATCH_VFRSUB_VF, MASK_VFRSUB_VF)
+DECLARE_INSN(vfmadd_vf, MATCH_VFMADD_VF, MASK_VFMADD_VF)
+DECLARE_INSN(vfnmadd_vf, MATCH_VFNMADD_VF, MASK_VFNMADD_VF)
+DECLARE_INSN(vfmsub_vf, MATCH_VFMSUB_VF, MASK_VFMSUB_VF)
+DECLARE_INSN(vfnmsub_vf, MATCH_VFNMSUB_VF, MASK_VFNMSUB_VF)
+DECLARE_INSN(vfmacc_vf, MATCH_VFMACC_VF, MASK_VFMACC_VF)
+DECLARE_INSN(vfnmacc_vf, MATCH_VFNMACC_VF, MASK_VFNMACC_VF)
+DECLARE_INSN(vfmsac_vf, MATCH_VFMSAC_VF, MASK_VFMSAC_VF)
+DECLARE_INSN(vfnmsac_vf, MATCH_VFNMSAC_VF, MASK_VFNMSAC_VF)
+DECLARE_INSN(vfwadd_vf, MATCH_VFWADD_VF, MASK_VFWADD_VF)
+DECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF)
+DECLARE_INSN(vfwadd_wf, MATCH_VFWADD_WF, MASK_VFWADD_WF)
+DECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF)
+DECLARE_INSN(vfwmul_vf, MATCH_VFWMUL_VF, MASK_VFWMUL_VF)
+DECLARE_INSN(vfwmacc_vf, MATCH_VFWMACC_VF, MASK_VFWMACC_VF)
+DECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF)
+DECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF)
+DECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF)
+DECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV)
+DECLARE_INSN(vfredsum_vs, MATCH_VFREDSUM_VS, MASK_VFREDSUM_VS)
+DECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV)
+DECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS)
+DECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV)
+DECLARE_INSN(vfredmin_vs, MATCH_VFREDMIN_VS, MASK_VFREDMIN_VS)
+DECLARE_INSN(vfmax_vv, MATCH_VFMAX_VV, MASK_VFMAX_VV)
+DECLARE_INSN(vfredmax_vs, MATCH_VFREDMAX_VS, MASK_VFREDMAX_VS)
+DECLARE_INSN(vfsgnj_vv, MATCH_VFSGNJ_VV, MASK_VFSGNJ_VV)
+DECLARE_INSN(vfsgnjn_vv, MATCH_VFSGNJN_VV, MASK_VFSGNJN_VV)
+DECLARE_INSN(vfsgnjx_vv, MATCH_VFSGNJX_VV, MASK_VFSGNJX_VV)
+DECLARE_INSN(vfmv_f_s, MATCH_VFMV_F_S, MASK_VFMV_F_S)
+DECLARE_INSN(vmfeq_vv, MATCH_VMFEQ_VV, MASK_VMFEQ_VV)
+DECLARE_INSN(vmfle_vv, MATCH_VMFLE_VV, MASK_VMFLE_VV)
+DECLARE_INSN(vmflt_vv, MATCH_VMFLT_VV, MASK_VMFLT_VV)
+DECLARE_INSN(vmfne_vv, MATCH_VMFNE_VV, MASK_VMFNE_VV)
+DECLARE_INSN(vfdiv_vv, MATCH_VFDIV_VV, MASK_VFDIV_VV)
+DECLARE_INSN(vfmul_vv, MATCH_VFMUL_VV, MASK_VFMUL_VV)
+DECLARE_INSN(vfmadd_vv, MATCH_VFMADD_VV, MASK_VFMADD_VV)
+DECLARE_INSN(vfnmadd_vv, MATCH_VFNMADD_VV, MASK_VFNMADD_VV)
+DECLARE_INSN(vfmsub_vv, MATCH_VFMSUB_VV, MASK_VFMSUB_VV)
+DECLARE_INSN(vfnmsub_vv, MATCH_VFNMSUB_VV, MASK_VFNMSUB_VV)
+DECLARE_INSN(vfmacc_vv, MATCH_VFMACC_VV, MASK_VFMACC_VV)
+DECLARE_INSN(vfnmacc_vv, MATCH_VFNMACC_VV, MASK_VFNMACC_VV)
+DECLARE_INSN(vfmsac_vv, MATCH_VFMSAC_VV, MASK_VFMSAC_VV)
+DECLARE_INSN(vfnmsac_vv, MATCH_VFNMSAC_VV, MASK_VFNMSAC_VV)
+DECLARE_INSN(vfcvt_xu_f_v, MATCH_VFCVT_XU_F_V, MASK_VFCVT_XU_F_V)
+DECLARE_INSN(vfcvt_x_f_v, MATCH_VFCVT_X_F_V, MASK_VFCVT_X_F_V)
+DECLARE_INSN(vfcvt_f_xu_v, MATCH_VFCVT_F_XU_V, MASK_VFCVT_F_XU_V)
+DECLARE_INSN(vfcvt_f_x_v, MATCH_VFCVT_F_X_V, MASK_VFCVT_F_X_V)
+DECLARE_INSN(vfwcvt_xu_f_v, MATCH_VFWCVT_XU_F_V, MASK_VFWCVT_XU_F_V)
+DECLARE_INSN(vfwcvt_x_f_v, MATCH_VFWCVT_X_F_V, MASK_VFWCVT_X_F_V)
+DECLARE_INSN(vfwcvt_f_xu_v, MATCH_VFWCVT_F_XU_V, MASK_VFWCVT_F_XU_V)
+DECLARE_INSN(vfwcvt_f_x_v, MATCH_VFWCVT_F_X_V, MASK_VFWCVT_F_X_V)
+DECLARE_INSN(vfwcvt_f_f_v, MATCH_VFWCVT_F_F_V, MASK_VFWCVT_F_F_V)
+DECLARE_INSN(vfncvt_xu_f_w, MATCH_VFNCVT_XU_F_W, MASK_VFNCVT_XU_F_W)
+DECLARE_INSN(vfncvt_x_f_w, MATCH_VFNCVT_X_F_W, MASK_VFNCVT_X_F_W)
+DECLARE_INSN(vfncvt_f_xu_w, MATCH_VFNCVT_F_XU_W, MASK_VFNCVT_F_XU_W)
+DECLARE_INSN(vfncvt_f_x_w, MATCH_VFNCVT_F_X_W, MASK_VFNCVT_F_X_W)
+DECLARE_INSN(vfncvt_f_f_w, MATCH_VFNCVT_F_F_W, MASK_VFNCVT_F_F_W)
+DECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W)
+DECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V)
+DECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V)
+DECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV)
+DECLARE_INSN(vfwredsum_vs, MATCH_VFWREDSUM_VS, MASK_VFWREDSUM_VS)
+DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV)
+DECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS)
+DECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV)
+DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV)
+DECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV)
+DECLARE_INSN(vfdot_vv, MATCH_VFDOT_VV, MASK_VFDOT_VV)
+DECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV)
+DECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV)
+DECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV)
+DECLARE_INSN(vfwnmsac_vv, MATCH_VFWNMSAC_VV, MASK_VFWNMSAC_VV)
+DECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX)
+DECLARE_INSN(vsub_vx, MATCH_VSUB_VX, MASK_VSUB_VX)
+DECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX)
+DECLARE_INSN(vminu_vx, MATCH_VMINU_VX, MASK_VMINU_VX)
+DECLARE_INSN(vmin_vx, MATCH_VMIN_VX, MASK_VMIN_VX)
+DECLARE_INSN(vmaxu_vx, MATCH_VMAXU_VX, MASK_VMAXU_VX)
+DECLARE_INSN(vmax_vx, MATCH_VMAX_VX, MASK_VMAX_VX)
+DECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX)
+DECLARE_INSN(vor_vx, MATCH_VOR_VX, MASK_VOR_VX)
+DECLARE_INSN(vxor_vx, MATCH_VXOR_VX, MASK_VXOR_VX)
+DECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX)
+DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX)
+DECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX)
+DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM)
+DECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM)
+DECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM)
+DECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM)
+DECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM)
+DECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X)
+DECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX)
+DECLARE_INSN(vmsne_vx, MATCH_VMSNE_VX, MASK_VMSNE_VX)
+DECLARE_INSN(vmsltu_vx, MATCH_VMSLTU_VX, MASK_VMSLTU_VX)
+DECLARE_INSN(vmslt_vx, MATCH_VMSLT_VX, MASK_VMSLT_VX)
+DECLARE_INSN(vmsleu_vx, MATCH_VMSLEU_VX, MASK_VMSLEU_VX)
+DECLARE_INSN(vmsle_vx, MATCH_VMSLE_VX, MASK_VMSLE_VX)
+DECLARE_INSN(vmsgtu_vx, MATCH_VMSGTU_VX, MASK_VMSGTU_VX)
+DECLARE_INSN(vmsgt_vx, MATCH_VMSGT_VX, MASK_VMSGT_VX)
+DECLARE_INSN(vsaddu_vx, MATCH_VSADDU_VX, MASK_VSADDU_VX)
+DECLARE_INSN(vsadd_vx, MATCH_VSADD_VX, MASK_VSADD_VX)
+DECLARE_INSN(vssubu_vx, MATCH_VSSUBU_VX, MASK_VSSUBU_VX)
+DECLARE_INSN(vssub_vx, MATCH_VSSUB_VX, MASK_VSSUB_VX)
+DECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX)
+DECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX)
+DECLARE_INSN(vsrl_vx, MATCH_VSRL_VX, MASK_VSRL_VX)
+DECLARE_INSN(vsra_vx, MATCH_VSRA_VX, MASK_VSRA_VX)
+DECLARE_INSN(vssrl_vx, MATCH_VSSRL_VX, MASK_VSSRL_VX)
+DECLARE_INSN(vssra_vx, MATCH_VSSRA_VX, MASK_VSSRA_VX)
+DECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX)
+DECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX)
+DECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX)
+DECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX)
+DECLARE_INSN(vqmaccu_vx, MATCH_VQMACCU_VX, MASK_VQMACCU_VX)
+DECLARE_INSN(vqmacc_vx, MATCH_VQMACC_VX, MASK_VQMACC_VX)
+DECLARE_INSN(vqmaccus_vx, MATCH_VQMACCUS_VX, MASK_VQMACCUS_VX)
+DECLARE_INSN(vqmaccsu_vx, MATCH_VQMACCSU_VX, MASK_VQMACCSU_VX)
+DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV)
+DECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV)
+DECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV)
+DECLARE_INSN(vmin_vv, MATCH_VMIN_VV, MASK_VMIN_VV)
+DECLARE_INSN(vmaxu_vv, MATCH_VMAXU_VV, MASK_VMAXU_VV)
+DECLARE_INSN(vmax_vv, MATCH_VMAX_VV, MASK_VMAX_VV)
+DECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV)
+DECLARE_INSN(vor_vv, MATCH_VOR_VV, MASK_VOR_VV)
+DECLARE_INSN(vxor_vv, MATCH_VXOR_VV, MASK_VXOR_VV)
+DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV)
+DECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM)
+DECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM)
+DECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM)
+DECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM)
+DECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM)
+DECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V)
+DECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV)
+DECLARE_INSN(vmsne_vv, MATCH_VMSNE_VV, MASK_VMSNE_VV)
+DECLARE_INSN(vmsltu_vv, MATCH_VMSLTU_VV, MASK_VMSLTU_VV)
+DECLARE_INSN(vmslt_vv, MATCH_VMSLT_VV, MASK_VMSLT_VV)
+DECLARE_INSN(vmsleu_vv, MATCH_VMSLEU_VV, MASK_VMSLEU_VV)
+DECLARE_INSN(vmsle_vv, MATCH_VMSLE_VV, MASK_VMSLE_VV)
+DECLARE_INSN(vsaddu_vv, MATCH_VSADDU_VV, MASK_VSADDU_VV)
+DECLARE_INSN(vsadd_vv, MATCH_VSADD_VV, MASK_VSADD_VV)
+DECLARE_INSN(vssubu_vv, MATCH_VSSUBU_VV, MASK_VSSUBU_VV)
+DECLARE_INSN(vssub_vv, MATCH_VSSUB_VV, MASK_VSSUB_VV)
+DECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV)
+DECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV)
+DECLARE_INSN(vsrl_vv, MATCH_VSRL_VV, MASK_VSRL_VV)
+DECLARE_INSN(vsra_vv, MATCH_VSRA_VV, MASK_VSRA_VV)
+DECLARE_INSN(vssrl_vv, MATCH_VSSRL_VV, MASK_VSSRL_VV)
+DECLARE_INSN(vssra_vv, MATCH_VSSRA_VV, MASK_VSSRA_VV)
+DECLARE_INSN(vnsrl_wv, MATCH_VNSRL_WV, MASK_VNSRL_WV)
+DECLARE_INSN(vnsra_wv, MATCH_VNSRA_WV, MASK_VNSRA_WV)
+DECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV)
+DECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV)
+DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS)
+DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS)
+DECLARE_INSN(vdotu_vv, MATCH_VDOTU_VV, MASK_VDOTU_VV)
+DECLARE_INSN(vdot_vv, MATCH_VDOT_VV, MASK_VDOT_VV)
+DECLARE_INSN(vqmaccu_vv, MATCH_VQMACCU_VV, MASK_VQMACCU_VV)
+DECLARE_INSN(vqmacc_vv, MATCH_VQMACC_VV, MASK_VQMACC_VV)
+DECLARE_INSN(vqmaccsu_vv, MATCH_VQMACCSU_VV, MASK_VQMACCSU_VV)
+DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI)
+DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI)
+DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI)
+DECLARE_INSN(vor_vi, MATCH_VOR_VI, MASK_VOR_VI)
+DECLARE_INSN(vxor_vi, MATCH_VXOR_VI, MASK_VXOR_VI)
+DECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI)
+DECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI)
+DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI)
+DECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM)
+DECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM)
+DECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM)
+DECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I)
+DECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI)
+DECLARE_INSN(vmsne_vi, MATCH_VMSNE_VI, MASK_VMSNE_VI)
+DECLARE_INSN(vmsleu_vi, MATCH_VMSLEU_VI, MASK_VMSLEU_VI)
+DECLARE_INSN(vmsle_vi, MATCH_VMSLE_VI, MASK_VMSLE_VI)
+DECLARE_INSN(vmsgtu_vi, MATCH_VMSGTU_VI, MASK_VMSGTU_VI)
+DECLARE_INSN(vmsgt_vi, MATCH_VMSGT_VI, MASK_VMSGT_VI)
+DECLARE_INSN(vsaddu_vi, MATCH_VSADDU_VI, MASK_VSADDU_VI)
+DECLARE_INSN(vsadd_vi, MATCH_VSADD_VI, MASK_VSADD_VI)
+DECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI)
+DECLARE_INSN(vmv1r_v, MATCH_VMV1R_V, MASK_VMV1R_V)
+DECLARE_INSN(vmv2r_v, MATCH_VMV2R_V, MASK_VMV2R_V)
+DECLARE_INSN(vmv4r_v, MATCH_VMV4R_V, MASK_VMV4R_V)
+DECLARE_INSN(vmv8r_v, MATCH_VMV8R_V, MASK_VMV8R_V)
+DECLARE_INSN(vsrl_vi, MATCH_VSRL_VI, MASK_VSRL_VI)
+DECLARE_INSN(vsra_vi, MATCH_VSRA_VI, MASK_VSRA_VI)
+DECLARE_INSN(vssrl_vi, MATCH_VSSRL_VI, MASK_VSSRL_VI)
+DECLARE_INSN(vssra_vi, MATCH_VSSRA_VI, MASK_VSSRA_VI)
+DECLARE_INSN(vnsrl_wi, MATCH_VNSRL_WI, MASK_VNSRL_WI)
+DECLARE_INSN(vnsra_wi, MATCH_VNSRA_WI, MASK_VNSRA_WI)
+DECLARE_INSN(vnclipu_wi, MATCH_VNCLIPU_WI, MASK_VNCLIPU_WI)
+DECLARE_INSN(vnclip_wi, MATCH_VNCLIP_WI, MASK_VNCLIP_WI)
+DECLARE_INSN(vredsum_vs, MATCH_VREDSUM_VS, MASK_VREDSUM_VS)
+DECLARE_INSN(vredand_vs, MATCH_VREDAND_VS, MASK_VREDAND_VS)
+DECLARE_INSN(vredor_vs, MATCH_VREDOR_VS, MASK_VREDOR_VS)
+DECLARE_INSN(vredxor_vs, MATCH_VREDXOR_VS, MASK_VREDXOR_VS)
+DECLARE_INSN(vredminu_vs, MATCH_VREDMINU_VS, MASK_VREDMINU_VS)
+DECLARE_INSN(vredmin_vs, MATCH_VREDMIN_VS, MASK_VREDMIN_VS)
+DECLARE_INSN(vredmaxu_vs, MATCH_VREDMAXU_VS, MASK_VREDMAXU_VS)
+DECLARE_INSN(vredmax_vs, MATCH_VREDMAX_VS, MASK_VREDMAX_VS)
+DECLARE_INSN(vaaddu_vv, MATCH_VAADDU_VV, MASK_VAADDU_VV)
+DECLARE_INSN(vaadd_vv, MATCH_VAADD_VV, MASK_VAADD_VV)
+DECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV)
+DECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV)
+DECLARE_INSN(vmv_x_s, MATCH_VMV_X_S, MASK_VMV_X_S)
+DECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM)
+DECLARE_INSN(vmandnot_mm, MATCH_VMANDNOT_MM, MASK_VMANDNOT_MM)
+DECLARE_INSN(vmand_mm, MATCH_VMAND_MM, MASK_VMAND_MM)
+DECLARE_INSN(vmor_mm, MATCH_VMOR_MM, MASK_VMOR_MM)
+DECLARE_INSN(vmxor_mm, MATCH_VMXOR_MM, MASK_VMXOR_MM)
+DECLARE_INSN(vmornot_mm, MATCH_VMORNOT_MM, MASK_VMORNOT_MM)
+DECLARE_INSN(vmnand_mm, MATCH_VMNAND_MM, MASK_VMNAND_MM)
+DECLARE_INSN(vmnor_mm, MATCH_VMNOR_MM, MASK_VMNOR_MM)
+DECLARE_INSN(vmxnor_mm, MATCH_VMXNOR_MM, MASK_VMXNOR_MM)
+DECLARE_INSN(vmsbf_m, MATCH_VMSBF_M, MASK_VMSBF_M)
+DECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M)
+DECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M)
+DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M)
+DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V)
+DECLARE_INSN(vpopc_m, MATCH_VPOPC_M, MASK_VPOPC_M)
+DECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M)
+DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV)
+DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV)
+DECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV)
+DECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV)
+DECLARE_INSN(vmulhu_vv, MATCH_VMULHU_VV, MASK_VMULHU_VV)
+DECLARE_INSN(vmul_vv, MATCH_VMUL_VV, MASK_VMUL_VV)
+DECLARE_INSN(vmulhsu_vv, MATCH_VMULHSU_VV, MASK_VMULHSU_VV)
+DECLARE_INSN(vmulh_vv, MATCH_VMULH_VV, MASK_VMULH_VV)
+DECLARE_INSN(vmadd_vv, MATCH_VMADD_VV, MASK_VMADD_VV)
+DECLARE_INSN(vnmsub_vv, MATCH_VNMSUB_VV, MASK_VNMSUB_VV)
+DECLARE_INSN(vmacc_vv, MATCH_VMACC_VV, MASK_VMACC_VV)
+DECLARE_INSN(vnmsac_vv, MATCH_VNMSAC_VV, MASK_VNMSAC_VV)
+DECLARE_INSN(vwaddu_vv, MATCH_VWADDU_VV, MASK_VWADDU_VV)
+DECLARE_INSN(vwadd_vv, MATCH_VWADD_VV, MASK_VWADD_VV)
+DECLARE_INSN(vwsubu_vv, MATCH_VWSUBU_VV, MASK_VWSUBU_VV)
+DECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV)
+DECLARE_INSN(vwaddu_wv, MATCH_VWADDU_WV, MASK_VWADDU_WV)
+DECLARE_INSN(vwadd_wv, MATCH_VWADD_WV, MASK_VWADD_WV)
+DECLARE_INSN(vwsubu_wv, MATCH_VWSUBU_WV, MASK_VWSUBU_WV)
+DECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV)
+DECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV)
+DECLARE_INSN(vwmulsu_vv, MATCH_VWMULSU_VV, MASK_VWMULSU_VV)
+DECLARE_INSN(vwmul_vv, MATCH_VWMUL_VV, MASK_VWMUL_VV)
+DECLARE_INSN(vwmaccu_vv, MATCH_VWMACCU_VV, MASK_VWMACCU_VV)
+DECLARE_INSN(vwmacc_vv, MATCH_VWMACC_VV, MASK_VWMACC_VV)
+DECLARE_INSN(vwmaccsu_vv, MATCH_VWMACCSU_VV, MASK_VWMACCSU_VV)
+DECLARE_INSN(vaaddu_vx, MATCH_VAADDU_VX, MASK_VAADDU_VX)
+DECLARE_INSN(vaadd_vx, MATCH_VAADD_VX, MASK_VAADD_VX)
+DECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX)
+DECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX)
+DECLARE_INSN(vmv_s_x, MATCH_VMV_S_X, MASK_VMV_S_X)
+DECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX)
+DECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX)
+DECLARE_INSN(vdivu_vx, MATCH_VDIVU_VX, MASK_VDIVU_VX)
+DECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX)
+DECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX)
+DECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX)
+DECLARE_INSN(vmulhu_vx, MATCH_VMULHU_VX, MASK_VMULHU_VX)
+DECLARE_INSN(vmul_vx, MATCH_VMUL_VX, MASK_VMUL_VX)
+DECLARE_INSN(vmulhsu_vx, MATCH_VMULHSU_VX, MASK_VMULHSU_VX)
+DECLARE_INSN(vmulh_vx, MATCH_VMULH_VX, MASK_VMULH_VX)
+DECLARE_INSN(vmadd_vx, MATCH_VMADD_VX, MASK_VMADD_VX)
+DECLARE_INSN(vnmsub_vx, MATCH_VNMSUB_VX, MASK_VNMSUB_VX)
+DECLARE_INSN(vmacc_vx, MATCH_VMACC_VX, MASK_VMACC_VX)
+DECLARE_INSN(vnmsac_vx, MATCH_VNMSAC_VX, MASK_VNMSAC_VX)
+DECLARE_INSN(vwaddu_vx, MATCH_VWADDU_VX, MASK_VWADDU_VX)
+DECLARE_INSN(vwadd_vx, MATCH_VWADD_VX, MASK_VWADD_VX)
+DECLARE_INSN(vwsubu_vx, MATCH_VWSUBU_VX, MASK_VWSUBU_VX)
+DECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX)
+DECLARE_INSN(vwaddu_wx, MATCH_VWADDU_WX, MASK_VWADDU_WX)
+DECLARE_INSN(vwadd_wx, MATCH_VWADD_WX, MASK_VWADD_WX)
+DECLARE_INSN(vwsubu_wx, MATCH_VWSUBU_WX, MASK_VWSUBU_WX)
+DECLARE_INSN(vwsub_wx, MATCH_VWSUB_WX, MASK_VWSUB_WX)
+DECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX)
+DECLARE_INSN(vwmulsu_vx, MATCH_VWMULSU_VX, MASK_VWMULSU_VX)
+DECLARE_INSN(vwmul_vx, MATCH_VWMUL_VX, MASK_VWMUL_VX)
+DECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX)
+DECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX)
+DECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX)
+DECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX)
+DECLARE_INSN(vamoswapw_v, MATCH_VAMOSWAPW_V, MASK_VAMOSWAPW_V)
+DECLARE_INSN(vamoaddw_v, MATCH_VAMOADDW_V, MASK_VAMOADDW_V)
+DECLARE_INSN(vamoxorw_v, MATCH_VAMOXORW_V, MASK_VAMOXORW_V)
+DECLARE_INSN(vamoandw_v, MATCH_VAMOANDW_V, MASK_VAMOANDW_V)
+DECLARE_INSN(vamoorw_v, MATCH_VAMOORW_V, MASK_VAMOORW_V)
+DECLARE_INSN(vamominw_v, MATCH_VAMOMINW_V, MASK_VAMOMINW_V)
+DECLARE_INSN(vamomaxw_v, MATCH_VAMOMAXW_V, MASK_VAMOMAXW_V)
+DECLARE_INSN(vamominuw_v, MATCH_VAMOMINUW_V, MASK_VAMOMINUW_V)
+DECLARE_INSN(vamomaxuw_v, MATCH_VAMOMAXUW_V, MASK_VAMOMAXUW_V)
+DECLARE_INSN(vamoswape_v, MATCH_VAMOSWAPE_V, MASK_VAMOSWAPE_V)
+DECLARE_INSN(vamoadde_v, MATCH_VAMOADDE_V, MASK_VAMOADDE_V)
+DECLARE_INSN(vamoxore_v, MATCH_VAMOXORE_V, MASK_VAMOXORE_V)
+DECLARE_INSN(vamoande_v, MATCH_VAMOANDE_V, MASK_VAMOANDE_V)
+DECLARE_INSN(vamoore_v, MATCH_VAMOORE_V, MASK_VAMOORE_V)
+DECLARE_INSN(vamomine_v, MATCH_VAMOMINE_V, MASK_VAMOMINE_V)
+DECLARE_INSN(vamomaxe_v, MATCH_VAMOMAXE_V, MASK_VAMOMAXE_V)
+DECLARE_INSN(vamominue_v, MATCH_VAMOMINUE_V, MASK_VAMOMINUE_V)
+DECLARE_INSN(vamomaxue_v, MATCH_VAMOMAXUE_V, MASK_VAMOMAXUE_V)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(ustatus, CSR_USTATUS)
+DECLARE_CSR(uie, CSR_UIE)
+DECLARE_CSR(utvec, CSR_UTVEC)
+DECLARE_CSR(vstart, CSR_VSTART)
+DECLARE_CSR(vxsat, CSR_VXSAT)
+DECLARE_CSR(vxrm, CSR_VXRM)
+DECLARE_CSR(uscratch, CSR_USCRATCH)
+DECLARE_CSR(uepc, CSR_UEPC)
+DECLARE_CSR(ucause, CSR_UCAUSE)
+DECLARE_CSR(utval, CSR_UTVAL)
+DECLARE_CSR(uip, CSR_UIP)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(vl, CSR_VL)
+DECLARE_CSR(vtype, CSR_VTYPE)
+DECLARE_CSR(vlenb, CSR_VLENB)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sedeleg, CSR_SEDELEG)
+DECLARE_CSR(sideleg, CSR_SIDELEG)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(stval, CSR_STVAL)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(satp, CSR_SATP)
+DECLARE_CSR(vsstatus, CSR_VSSTATUS)
+DECLARE_CSR(vsie, CSR_VSIE)
+DECLARE_CSR(vstvec, CSR_VSTVEC)
+DECLARE_CSR(vsscratch, CSR_VSSCRATCH)
+DECLARE_CSR(vsepc, CSR_VSEPC)
+DECLARE_CSR(vscause, CSR_VSCAUSE)
+DECLARE_CSR(vstval, CSR_VSTVAL)
+DECLARE_CSR(vsip, CSR_VSIP)
+DECLARE_CSR(vsatp, CSR_VSATP)
+DECLARE_CSR(hstatus, CSR_HSTATUS)
+DECLARE_CSR(hedeleg, CSR_HEDELEG)
+DECLARE_CSR(hideleg, CSR_HIDELEG)
+DECLARE_CSR(hcounteren, CSR_HCOUNTEREN)
+DECLARE_CSR(hgatp, CSR_HGATP)
+DECLARE_CSR(utvt, CSR_UTVT)
+DECLARE_CSR(unxti, CSR_UNXTI)
+DECLARE_CSR(uintstatus, CSR_UINTSTATUS)
+DECLARE_CSR(uscratchcsw, CSR_USCRATCHCSW)
+DECLARE_CSR(uscratchcswl, CSR_USCRATCHCSWL)
+DECLARE_CSR(stvt, CSR_STVT)
+DECLARE_CSR(snxti, CSR_SNXTI)
+DECLARE_CSR(sintstatus, CSR_SINTSTATUS)
+DECLARE_CSR(sscratchcsw, CSR_SSCRATCHCSW)
+DECLARE_CSR(sscratchcswl, CSR_SSCRATCHCSWL)
+DECLARE_CSR(mtvt, CSR_MTVT)
+DECLARE_CSR(mnxti, CSR_MNXTI)
+DECLARE_CSR(mintstatus, CSR_MINTSTATUS)
+DECLARE_CSR(mscratchcsw, CSR_MSCRATCHCSW)
+DECLARE_CSR(mscratchcswl, CSR_MSCRATCHCSWL)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mtval, CSR_MTVAL)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch, CSR_DSCRATCH)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
diff --git a/src/asmtest/env/p/link.ld b/src/asmtest/env/p/link.ld
new file mode 100644
index 0000000..b3e315e
--- /dev/null
+++ b/src/asmtest/env/p/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+  . = 0x80000000;
+  .text.init : { *(.text.init) }
+  . = ALIGN(0x1000);
+  .tohost : { *(.tohost) }
+  . = ALIGN(0x1000);
+  .text : { *(.text) }
+  . = ALIGN(0x1000);
+  .data : { *(.data) }
+  .bss : { *(.bss) }
+  _end = .;
+}
+
diff --git a/src/asmtest/env/p/riscv_test.h b/src/asmtest/env/p/riscv_test.h
new file mode 100644
index 0000000..661b2c5
--- /dev/null
+++ b/src/asmtest/env/p/riscv_test.h
@@ -0,0 +1,284 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
+#define _ENV_PHYSICAL_SINGLE_CORE_H
+
+#include "../encoding.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_RV64U                                                    \
+  .macro init;                                                          \
+  .endm
+
+#define RVTEST_RV64UF                                                   \
+  .macro init;                                                          \
+  RVTEST_FP_ENABLE;                                                     \
+  .endm
+
+#define RVTEST_RV64UV                                                   \
+  .macro init;                                                          \
+  RVTEST_VECTOR_ENABLE;                                                 \
+  .endm
+
+#define RVTEST_RV32U                                                    \
+  .macro init;                                                          \
+  .endm
+
+#define RVTEST_RV32UF                                                   \
+  .macro init;                                                          \
+  RVTEST_FP_ENABLE;                                                     \
+  .endm
+
+#define RVTEST_RV32UV                                                   \
+  .macro init;                                                          \
+  RVTEST_VECTOR_ENABLE;                                                 \
+  .endm
+
+#define RVTEST_RV64M                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_MACHINE;                                                \
+  .endm
+
+#define RVTEST_RV64S                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_SUPERVISOR;                                             \
+  .endm
+
+#define RVTEST_RV32M                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_MACHINE;                                                \
+  .endm
+
+#define RVTEST_RV32S                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_SUPERVISOR;                                             \
+  .endm
+
+#if __riscv_xlen == 64
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
+#else
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
+#endif
+
+#define INIT_XREG                                                       \
+  li x1, 0;                                                             \
+  li x2, 0;                                                             \
+  li x3, 0;                                                             \
+  li x4, 0;                                                             \
+  li x5, 0;                                                             \
+  li x6, 0;                                                             \
+  li x7, 0;                                                             \
+  li x8, 0;                                                             \
+  li x9, 0;                                                             \
+  li x10, 0;                                                            \
+  li x11, 0;                                                            \
+  li x12, 0;                                                            \
+  li x13, 0;                                                            \
+  li x14, 0;                                                            \
+  li x15, 0;                                                            \
+  li x16, 0;                                                            \
+  li x17, 0;                                                            \
+  li x18, 0;                                                            \
+  li x19, 0;                                                            \
+  li x20, 0;                                                            \
+  li x21, 0;                                                            \
+  li x22, 0;                                                            \
+  li x23, 0;                                                            \
+  li x24, 0;                                                            \
+  li x25, 0;                                                            \
+  li x26, 0;                                                            \
+  li x27, 0;                                                            \
+  li x28, 0;                                                            \
+  li x29, 0;                                                            \
+  li x30, 0;                                                            \
+  li x31, 0;
+
+#define INIT_PMP                                                        \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  /* Set up a PMP to permit all accesses */                             \
+  li t0, (1 << (31 + (__riscv_xlen / 64) * (53 - 31))) - 1;             \
+  csrw pmpaddr0, t0;                                                    \
+  li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X;                             \
+  csrw pmpcfg0, t0;                                                     \
+  .align 2;                                                             \
+1:
+
+#define INIT_SATP                                                      \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  csrwi sptbr, 0;                                                       \
+  .align 2;                                                             \
+1:
+
+#define DELEGATE_NO_TRAPS                                               \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  csrwi medeleg, 0;                                                     \
+  csrwi mideleg, 0;                                                     \
+  csrwi mie, 0;                                                         \
+  .align 2;                                                             \
+1:
+
+#define RVTEST_ENABLE_SUPERVISOR                                        \
+  li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1);                              \
+  csrs mstatus, a0;                                                     \
+  li a0, SIP_SSIP | SIP_STIP;                                           \
+  csrs mideleg, a0;                                                     \
+
+#define RVTEST_ENABLE_MACHINE                                           \
+  li a0, MSTATUS_MPP;                                                   \
+  csrs mstatus, a0;                                                     \
+
+#define RVTEST_FP_ENABLE                                                \
+  li a0, MSTATUS_FS & (MSTATUS_FS >> 1);                                \
+  csrs mstatus, a0;                                                     \
+  csrwi fcsr, 0
+
+#define RVTEST_VECTOR_ENABLE                                            \
+  li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)) |                             \
+         (MSTATUS_FS & (MSTATUS_FS >> 1));                              \
+  csrs mstatus, a0;                                                     \
+  csrwi fcsr, 0
+
+#define RISCV_MULTICORE_DISABLE                                         \
+  csrr a0, mhartid;                                                     \
+  1: bnez a0, 1b
+
+#define EXTRA_TVEC_USER
+#define EXTRA_TVEC_MACHINE
+#define EXTRA_INIT
+#define EXTRA_INIT_TIMER
+
+#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
+
+#define RVTEST_CODE_BEGIN                                               \
+        .section .text.init;                                            \
+        .align  6;                                                      \
+        .weak stvec_handler;                                            \
+        .weak mtvec_handler;                                            \
+        .globl _start;                                                  \
+_start:                                                                 \
+        /* reset vector */                                              \
+        j reset_vector;                                                 \
+        .align 2;                                                       \
+trap_vector:                                                            \
+        /* test whether the test came from pass/fail */                 \
+        csrr t5, mcause;                                                \
+        li t6, CAUSE_USER_ECALL;                                        \
+        beq t5, t6, write_tohost;                                       \
+        li t6, CAUSE_SUPERVISOR_ECALL;                                  \
+        beq t5, t6, write_tohost;                                       \
+        li t6, CAUSE_MACHINE_ECALL;                                     \
+        beq t5, t6, write_tohost;                                       \
+        /* if an mtvec_handler is defined, jump to it */                \
+        la t5, mtvec_handler;                                           \
+        beqz t5, 1f;                                                    \
+        jr t5;                                                          \
+        /* was it an interrupt or an exception? */                      \
+  1:    csrr t5, mcause;                                                \
+        bgez t5, handle_exception;                                      \
+        INTERRUPT_HANDLER;                                              \
+handle_exception:                                                       \
+        /* we don't know how to handle whatever the exception was */    \
+  other_exception:                                                      \
+        /* some unhandlable exception occurred */                       \
+  1:    ori TESTNUM, TESTNUM, 1337;                                     \
+  write_tohost:                                                         \
+        mv a1, TESTNUM;                                                 \
+        /* 1 = success; otherwise (a0 >> 1) is the failed test */       \
+        srl a1, a1, 1;                                                  \
+        la a0, tohost_data;                                             \
+        sb a1, 0(a0);                                                   \
+        /* write exit code (binary) to file */                          \
+        li a1, 1;                                                       \
+        li a2, 0;                                                       \
+        la a3, tohost_file;                                             \
+        .long 0x9E00007B;                                               \
+        /* shutdown gem5 */                                             \
+        li a0, 0;                                                       \
+        .long 0x4200007B;                                               \
+        j write_tohost;                                                 \
+reset_vector:                                                           \
+        INIT_XREG;                                                      \
+        RISCV_MULTICORE_DISABLE;                                        \
+        INIT_SATP;                                                      \
+        INIT_PMP;                                                       \
+        DELEGATE_NO_TRAPS;                                              \
+        li TESTNUM, 0;                                                  \
+        la t0, trap_vector;                                             \
+        csrw mtvec, t0;                                                 \
+        CHECK_XLEN;                                                     \
+        /* if an stvec_handler is defined, delegate exceptions to it */ \
+        la t0, stvec_handler;                                           \
+        beqz t0, 1f;                                                    \
+        csrw stvec, t0;                                                 \
+        li t0, (1 << CAUSE_LOAD_PAGE_FAULT) |                           \
+               (1 << CAUSE_STORE_PAGE_FAULT) |                          \
+               (1 << CAUSE_FETCH_PAGE_FAULT) |                          \
+               (1 << CAUSE_MISALIGNED_FETCH) |                          \
+               (1 << CAUSE_USER_ECALL) |                                \
+               (1 << CAUSE_BREAKPOINT);                                 \
+        csrw medeleg, t0;                                               \
+1:      csrwi mstatus, 0;                                               \
+        init;                                                           \
+        EXTRA_INIT;                                                     \
+        EXTRA_INIT_TIMER;                                               \
+        la t0, 1f;                                                      \
+        csrw mepc, t0;                                                  \
+        csrr a0, mhartid;                                               \
+        mret;                                                           \
+1:
+
+//-----------------------------------------------------------------------
+// End Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_CODE_END                                                 \
+        unimp
+
+//-----------------------------------------------------------------------
+// Pass/Fail Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_PASS                                                     \
+        fence;                                                          \
+        li TESTNUM, 1;                                                  \
+        li a7, 93;                                                      \
+        li a0, 0;                                                       \
+        ecall
+
+#define TESTNUM gp
+#define RVTEST_FAIL                                                     \
+        fence;                                                          \
+1:      beqz TESTNUM, 1b;                                               \
+        sll TESTNUM, TESTNUM, 1;                                        \
+        or TESTNUM, TESTNUM, 1;                                         \
+        li a7, 93;                                                      \
+        addi a0, TESTNUM, 0;                                            \
+        ecall
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#define EXTRA_DATA                                                      \
+tohost_file:                                                            \
+        .asciz "exitcode";                                              \
+tohost_data:                                                            \
+        .byte 0;
+
+#define RVTEST_DATA_BEGIN                                               \
+        EXTRA_DATA                                                      \
+        .pushsection .tohost,"aw",@progbits;                            \
+        .align 6; .global tohost; tohost: .dword 0;                     \
+        .align 6; .global fromhost; fromhost: .dword 0;                 \
+        .popsection;                                                    \
+        .align 4; .global begin_signature; begin_signature:
+
+#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
+
+#endif
diff --git a/src/asmtest/env/pm/link.ld b/src/asmtest/env/pm/link.ld
new file mode 120000
index 0000000..86b45f9
--- /dev/null
+++ b/src/asmtest/env/pm/link.ld
@@ -0,0 +1 @@
+../p/link.ld
\ No newline at end of file
diff --git a/src/asmtest/env/pm/riscv_test.h b/src/asmtest/env/pm/riscv_test.h
new file mode 100644
index 0000000..38a0e86
--- /dev/null
+++ b/src/asmtest/env/pm/riscv_test.h
@@ -0,0 +1,11 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_MULTI_CORE_H
+#define _ENV_PHYSICAL_MULTI_CORE_H
+
+#include "../p/riscv_test.h"
+
+#undef RISCV_MULTICORE_DISABLE
+#define RISCV_MULTICORE_DISABLE
+
+#endif
diff --git a/src/asmtest/env/ps/link.ld b/src/asmtest/env/ps/link.ld
new file mode 100644
index 0000000..b3e315e
--- /dev/null
+++ b/src/asmtest/env/ps/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+  . = 0x80000000;
+  .text.init : { *(.text.init) }
+  . = ALIGN(0x1000);
+  .tohost : { *(.tohost) }
+  . = ALIGN(0x1000);
+  .text : { *(.text) }
+  . = ALIGN(0x1000);
+  .data : { *(.data) }
+  .bss : { *(.bss) }
+  _end = .;
+}
+
diff --git a/src/asmtest/env/ps/riscv_test.h b/src/asmtest/env/ps/riscv_test.h
new file mode 100644
index 0000000..8fcb7ab
--- /dev/null
+++ b/src/asmtest/env/ps/riscv_test.h
@@ -0,0 +1,170 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
+#define _ENV_PHYSICAL_SINGLE_CORE_H
+
+#include "../encoding.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_RV64U                                                    \
+  .macro init;                                                          \
+  .endm
+
+#define RVTEST_RV64UF                                                   \
+  .macro init;                                                          \
+  RVTEST_FP_ENABLE;                                                     \
+  .endm
+
+#define RVTEST_RV32U                                                    \
+  .macro init;                                                          \
+  .endm
+
+#define RVTEST_RV32UF                                                   \
+  .macro init;                                                          \
+  RVTEST_FP_ENABLE;                                                     \
+  .endm
+
+#define RVTEST_RV64M                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_MACHINE;                                                \
+  .endm
+
+#define RVTEST_RV64S                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_SUPERVISOR;                                             \
+  .endm
+
+#define RVTEST_RV32M                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_MACHINE;                                                \
+  .endm
+
+#define RVTEST_RV32S                                                    \
+  .macro init;                                                          \
+  RVTEST_ENABLE_SUPERVISOR;                                             \
+  .endm
+
+#if __riscv_xlen == 64
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
+#else
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
+#endif
+
+#define INIT_PMP                                                        \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  li t0, -1;        /* Set up a PMP to permit all accesses */           \
+  csrw pmpaddr0, t0;                                                    \
+  li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X;                             \
+  csrw pmpcfg0, t0;                                                     \
+  .align 2;                                                             \
+1:
+
+#define INIT_SATP                                                      \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  csrwi sptbr, 0;                                                       \
+  .align 2;                                                             \
+1:
+
+#define DELEGATE_NO_TRAPS                                               \
+  la t0, 1f;                                                            \
+  csrw mtvec, t0;                                                       \
+  csrwi medeleg, 0;                                                     \
+  csrwi mideleg, 0;                                                     \
+  csrwi mie, 0;                                                         \
+  .align 2;                                                             \
+1:
+
+#define RVTEST_ENABLE_SUPERVISOR                                        \
+  li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1);                              \
+  csrs mstatus, a0;                                                     \
+  li a0, SIP_SSIP | SIP_STIP;                                           \
+  csrs mideleg, a0;                                                     \
+
+#define RVTEST_ENABLE_MACHINE                                           \
+  li a0, MSTATUS_MPP;                                                   \
+  csrs mstatus, a0;                                                     \
+
+#define RVTEST_FP_ENABLE                                                \
+  li a0, MSTATUS_FS & (MSTATUS_FS >> 1);                                \
+  csrs mstatus, a0;                                                     \
+  csrwi fcsr, 0
+
+#define RISCV_MULTICORE_DISABLE                                         \
+  csrr a0, mhartid;                                                     \
+  1: bnez a0, 1b
+
+#define EXTRA_TVEC_USER
+#define EXTRA_TVEC_MACHINE
+#define EXTRA_INIT
+#define EXTRA_INIT_TIMER
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//    Jump to the first test case
+//-----------------------------------------------------------------------
+
+#define RVTEST_CODE_BEGIN                                               \
+        .section .text.init;                                            \
+        .align  6;                                                      \
+        .weak stvec_handler;                                            \
+        .weak mtvec_handler;                                            \
+        .globl _start;                                                  \
+_start:                                                                 \
+        la t0, 1f;                                                      \
+        jr t0;                                                          \
+        .align 2;                                                       \
+1:
+
+//-----------------------------------------------------------------------
+// RVTEST_CODE_END Macro
+//    Call exit syscall to terminate the simulation
+//-----------------------------------------------------------------------
+
+#define EXIT_SYSCALL 93
+#define RVTEST_CODE_END                                                 \
+        li a7, EXIT_SYSCALL;                                            \
+        ecall
+
+//-----------------------------------------------------------------------
+// RVTEST_PASS Macro
+//    Pass 0 as a return code to an EXIT ecall
+//-----------------------------------------------------------------------
+
+#define TESTNUM gp
+#define RVTEST_PASS                                                     \
+        fence;                                                          \
+        li a0, 0;
+
+//-----------------------------------------------------------------------
+// RVTEST_FAIL Macro
+//    Pass test case number as a return code to an EXIT ecall
+//-----------------------------------------------------------------------
+
+#define TESTNUM gp
+#define RVTEST_FAIL                                                     \
+        fence;                                                          \
+        mv a0, TESTNUM;                                                 \
+        RVTEST_CODE_END
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#define EXTRA_DATA
+
+#define RVTEST_DATA_BEGIN                                               \
+        EXTRA_DATA                                                      \
+        .pushsection .tohost,"aw",@progbits;                            \
+        .align 6; .global tohost; tohost: .dword 0;                     \
+        .align 6; .global fromhost; fromhost: .dword 0;                 \
+        .popsection;                                                    \
+        .align 4; .global begin_signature; begin_signature:
+
+#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
+
+#endif
diff --git a/src/asmtest/env/pt/link.ld b/src/asmtest/env/pt/link.ld
new file mode 120000
index 0000000..86b45f9
--- /dev/null
+++ b/src/asmtest/env/pt/link.ld
@@ -0,0 +1 @@
+../p/link.ld
\ No newline at end of file
diff --git a/src/asmtest/env/pt/riscv_test.h b/src/asmtest/env/pt/riscv_test.h
new file mode 100644
index 0000000..34c2a33
--- /dev/null
+++ b/src/asmtest/env/pt/riscv_test.h
@@ -0,0 +1,69 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
+#define _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
+
+#include "../p/riscv_test.h"
+
+#define TIMER_INTERVAL 2
+
+#undef EXTRA_INIT_TIMER
+#define EXTRA_INIT_TIMER                                                \
+        li a0, MIP_MTIP;                                                \
+        csrs mie, a0;                                                   \
+        csrr a0, mtime;                                                 \
+        addi a0, a0, TIMER_INTERVAL;                                    \
+        csrw mtimecmp, a0;                                              \
+
+#if SSTATUS_XS != 0x18000
+# error
+#endif
+#define XS_SHIFT 15
+
+#undef INTERRUPT_HANDLER
+#define INTERRUPT_HANDLER                                               \
+        slli t5, t5, 1;                                                 \
+        srli t5, t5, 1;                                                 \
+        add t5, t5, -IRQ_M_TIMER;                                       \
+        bnez t5, other_exception; /* other interrups shouldn't happen */\
+        csrr t5, mtime;                                                 \
+        addi t5, t5, TIMER_INTERVAL;                                    \
+        csrw mtimecmp, t5;                                              \
+        mret;                                                           \
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#undef EXTRA_DATA
+#define EXTRA_DATA                                                      \
+        .align 3;                                                       \
+regspill:                                                               \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+        .dword 0xdeadbeefcafebabe;                                      \
+evac:                                                                   \
+        .skip 32768;                                                    \
+
+#endif
diff --git a/src/asmtest/env/v/entry.S b/src/asmtest/env/v/entry.S
new file mode 100644
index 0000000..fa492e6
--- /dev/null
+++ b/src/asmtest/env/v/entry.S
@@ -0,0 +1,162 @@
+#include "riscv_test.h"
+
+#if __riscv_xlen == 64
+# define STORE    sd
+# define LOAD     ld
+# define REGBYTES 8
+#else
+# define STORE    sw
+# define LOAD     lw
+# define REGBYTES 4
+#endif
+
+#define STACK_TOP (_end + 4096)
+
+  .section ".text.init","ax",@progbits
+  .globl _start
+  .align 2
+_start:
+  j handle_reset
+
+  /* NMI vector */
+  .align 2
+nmi_vector:
+  j wtf
+
+  .align 2
+trap_vector:
+  j wtf
+
+handle_reset:
+  li x1, 0
+  li x2, 0
+  li x3, 0
+  li x4, 0
+  li x5, 0
+  li x6, 0
+  li x7, 0
+  li x8, 0
+  li x9, 0
+  li x10, 0
+  li x11, 0
+  li x12, 0
+  li x13, 0
+  li x14, 0
+  li x15, 0
+  li x16, 0
+  li x17, 0
+  li x18, 0
+  li x19, 0
+  li x20, 0
+  li x21, 0
+  li x22, 0
+  li x23, 0
+  li x24, 0
+  li x25, 0
+  li x26, 0
+  li x27, 0
+  li x28, 0
+  li x29, 0
+  li x30, 0
+  li x31, 0
+
+  la t0, trap_vector
+  csrw mtvec, t0
+  la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
+  csrr t0, mhartid
+  slli t0, t0, 12
+  add sp, sp, t0
+  csrw mscratch, sp
+  call extra_boot
+  la a0, userstart
+  j vm_boot
+
+  .globl  pop_tf
+pop_tf:
+  LOAD  t0,33*REGBYTES(a0)
+  csrw  sepc,t0
+  LOAD  x1,1*REGBYTES(a0)
+  LOAD  x2,2*REGBYTES(a0)
+  LOAD  x3,3*REGBYTES(a0)
+  LOAD  x4,4*REGBYTES(a0)
+  LOAD  x5,5*REGBYTES(a0)
+  LOAD  x6,6*REGBYTES(a0)
+  LOAD  x7,7*REGBYTES(a0)
+  LOAD  x8,8*REGBYTES(a0)
+  LOAD  x9,9*REGBYTES(a0)
+  LOAD  x11,11*REGBYTES(a0)
+  LOAD  x12,12*REGBYTES(a0)
+  LOAD  x13,13*REGBYTES(a0)
+  LOAD  x14,14*REGBYTES(a0)
+  LOAD  x15,15*REGBYTES(a0)
+  LOAD  x16,16*REGBYTES(a0)
+  LOAD  x17,17*REGBYTES(a0)
+  LOAD  x18,18*REGBYTES(a0)
+  LOAD  x19,19*REGBYTES(a0)
+  LOAD  x20,20*REGBYTES(a0)
+  LOAD  x21,21*REGBYTES(a0)
+  LOAD  x22,22*REGBYTES(a0)
+  LOAD  x23,23*REGBYTES(a0)
+  LOAD  x24,24*REGBYTES(a0)
+  LOAD  x25,25*REGBYTES(a0)
+  LOAD  x26,26*REGBYTES(a0)
+  LOAD  x27,27*REGBYTES(a0)
+  LOAD  x28,28*REGBYTES(a0)
+  LOAD  x29,29*REGBYTES(a0)
+  LOAD  x30,30*REGBYTES(a0)
+  LOAD  x31,31*REGBYTES(a0)
+  LOAD  a0,10*REGBYTES(a0)
+  sret
+
+  .global  trap_entry
+  .align 2
+trap_entry:
+  csrrw sp, sscratch, sp
+
+  # save gprs
+  STORE  x1,1*REGBYTES(sp)
+  STORE  x3,3*REGBYTES(sp)
+  STORE  x4,4*REGBYTES(sp)
+  STORE  x5,5*REGBYTES(sp)
+  STORE  x6,6*REGBYTES(sp)
+  STORE  x7,7*REGBYTES(sp)
+  STORE  x8,8*REGBYTES(sp)
+  STORE  x9,9*REGBYTES(sp)
+  STORE  x10,10*REGBYTES(sp)
+  STORE  x11,11*REGBYTES(sp)
+  STORE  x12,12*REGBYTES(sp)
+  STORE  x13,13*REGBYTES(sp)
+  STORE  x14,14*REGBYTES(sp)
+  STORE  x15,15*REGBYTES(sp)
+  STORE  x16,16*REGBYTES(sp)
+  STORE  x17,17*REGBYTES(sp)
+  STORE  x18,18*REGBYTES(sp)
+  STORE  x19,19*REGBYTES(sp)
+  STORE  x20,20*REGBYTES(sp)
+  STORE  x21,21*REGBYTES(sp)
+  STORE  x22,22*REGBYTES(sp)
+  STORE  x23,23*REGBYTES(sp)
+  STORE  x24,24*REGBYTES(sp)
+  STORE  x25,25*REGBYTES(sp)
+  STORE  x26,26*REGBYTES(sp)
+  STORE  x27,27*REGBYTES(sp)
+  STORE  x28,28*REGBYTES(sp)
+  STORE  x29,29*REGBYTES(sp)
+  STORE  x30,30*REGBYTES(sp)
+  STORE  x31,31*REGBYTES(sp)
+
+  csrrw  t0,sscratch,sp
+  STORE  t0,2*REGBYTES(sp)
+
+  # get sr, epc, badvaddr, cause
+  csrr   t0,sstatus
+  STORE  t0,32*REGBYTES(sp)
+  csrr   t0,sepc
+  STORE  t0,33*REGBYTES(sp)
+  csrr   t0,sbadaddr
+  STORE  t0,34*REGBYTES(sp)
+  csrr   t0,scause
+  STORE  t0,35*REGBYTES(sp)
+
+  move  a0, sp
+  j handle_trap
diff --git a/src/asmtest/env/v/link.ld b/src/asmtest/env/v/link.ld
new file mode 120000
index 0000000..86b45f9
--- /dev/null
+++ b/src/asmtest/env/v/link.ld
@@ -0,0 +1 @@
+../p/link.ld
\ No newline at end of file
diff --git a/src/asmtest/env/v/riscv_test.h b/src/asmtest/env/v/riscv_test.h
new file mode 100644
index 0000000..751e037
--- /dev/null
+++ b/src/asmtest/env/v/riscv_test.h
@@ -0,0 +1,75 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_VIRTUAL_SINGLE_CORE_H
+#define _ENV_VIRTUAL_SINGLE_CORE_H
+
+#include "../p/riscv_test.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_FP_ENABLE
+#define RVTEST_FP_ENABLE fssr x0
+
+#undef RVTEST_CODE_BEGIN
+#define RVTEST_CODE_BEGIN                                               \
+        .text;                                                          \
+        .global extra_boot;                                             \
+extra_boot:                                                             \
+        EXTRA_INIT                                                      \
+        ret;                                                            \
+        .global userstart;                                              \
+userstart:                                                              \
+        init
+
+//-----------------------------------------------------------------------
+// Pass/Fail Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_PASS
+#define RVTEST_PASS li a0, 1; scall
+
+#undef RVTEST_FAIL
+#define RVTEST_FAIL sll a0, TESTNUM, 1; 1:beqz a0, 1b; or a0, a0, 1; scall;
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_DATA_END
+#define RVTEST_DATA_END
+
+//-----------------------------------------------------------------------
+// Supervisor mode definitions and macros
+//-----------------------------------------------------------------------
+
+#define MAX_TEST_PAGES 63 // this must be the period of the LFSR below
+#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << 5) | ((x) >> 1))
+
+#define PGSHIFT 12
+#define PGSIZE (1UL << PGSHIFT)
+
+#define SIZEOF_TRAPFRAME_T ((__riscv_xlen / 8) * 36)
+
+#ifndef __ASSEMBLER__
+
+typedef unsigned long pte_t;
+#define LEVELS (sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2)
+#define PTIDXBITS (PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2))
+#define VPN_BITS (PTIDXBITS * LEVELS)
+#define VA_BITS (VPN_BITS + PGSHIFT)
+#define PTES_PER_PT (1UL << RISCV_PGLEVEL_BITS)
+#define MEGAPAGE_SIZE (PTES_PER_PT * PGSIZE)
+
+typedef struct
+{
+  long gpr[32];
+  long sr;
+  long epc;
+  long badvaddr;
+  long cause;
+} trapframe_t;
+#endif
+
+#endif
diff --git a/src/asmtest/env/v/string.c b/src/asmtest/env/v/string.c
new file mode 100644
index 0000000..4ffedc0
--- /dev/null
+++ b/src/asmtest/env/v/string.c
@@ -0,0 +1,114 @@
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+
+void* memcpy(void* dest, const void* src, size_t len)
+{
+  if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
+    const uintptr_t* s = src;
+    uintptr_t *d = dest;
+    while (d < (uintptr_t*)(dest + len))
+      *d++ = *s++;
+  } else {
+    const char* s = src;
+    char *d = dest;
+    while (d < (char*)(dest + len))
+      *d++ = *s++;
+  }
+  return dest;
+}
+
+void* memset(void* dest, int byte, size_t len)
+{
+  if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
+    uintptr_t word = byte & 0xFF;
+    word |= word << 8;
+    word |= word << 16;
+    word |= word << 16 << 16;
+
+    uintptr_t *d = dest;
+    while (d < (uintptr_t*)(dest + len))
+      *d++ = word;
+  } else {
+    char *d = dest;
+    while (d < (char*)(dest + len))
+      *d++ = byte;
+  }
+  return dest;
+}
+
+size_t strlen(const char *s)
+{
+  const char *p = s;
+  while (*p)
+    p++;
+  return p - s;
+}
+
+int strcmp(const char* s1, const char* s2)
+{
+  unsigned char c1, c2;
+
+  do {
+    c1 = *s1++;
+    c2 = *s2++;
+  } while (c1 != 0 && c1 == c2);
+
+  return c1 - c2;
+}
+
+int memcmp(const void* s1, const void* s2, size_t n)
+{
+  if ((((uintptr_t)s1 | (uintptr_t)s2) & (sizeof(uintptr_t)-1)) == 0) {
+    const uintptr_t* u1 = s1;
+    const uintptr_t* u2 = s2;
+    const uintptr_t* end = u1 + (n / sizeof(uintptr_t));
+    while (u1 < end) {
+      if (*u1 != *u2)
+        break;
+      u1++;
+      u2++;
+    }
+    n -= (const void*)u1 - s1;
+    s1 = u1;
+    s2 = u2;
+  }
+
+  while (n--) {
+    unsigned char c1 = *(const unsigned char*)s1++;
+    unsigned char c2 = *(const unsigned char*)s2++;
+    if (c1 != c2)
+      return c1 - c2;
+  }
+
+  return 0;
+}
+
+char* strcpy(char* dest, const char* src)
+{
+  char* d = dest;
+  while ((*d++ = *src++))
+    ;
+  return dest;
+}
+
+long atol(const char* str)
+{
+  long res = 0;
+  int sign = 0;
+
+  while (*str == ' ')
+    str++;
+
+  if (*str == '-' || *str == '+') {
+    sign = *str == '-';
+    str++;
+  }
+
+  while (*str) {
+    res *= 10;
+    res += *str++ - '0';
+  }
+
+  return sign ? -res : res;
+}
diff --git a/src/asmtest/env/v/vm.c b/src/asmtest/env/v/vm.c
new file mode 100644
index 0000000..3172f93
--- /dev/null
+++ b/src/asmtest/env/v/vm.c
@@ -0,0 +1,300 @@
+// See LICENSE for license details.
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "riscv_test.h"
+
+#if __riscv_xlen == 32
+# define SATP_MODE_CHOICE SATP_MODE_SV32
+#elif defined(Sv48)
+# define SATP_MODE_CHOICE SATP_MODE_SV48
+#else
+# define SATP_MODE_CHOICE SATP_MODE_SV39
+#endif
+
+void trap_entry();
+void pop_tf(trapframe_t*);
+
+#define pa2kva(pa) ((void*)(pa) - DRAM_BASE - MEGAPAGE_SIZE)
+#define uva2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
+
+#define flush_page(addr) asm volatile ("sfence.vma %0" : : "r" (addr) : "memory")
+
+static const char *stdoutFile = "stdout";
+static const char *exitcodeFile = "exitcode";
+
+static uint64_t lfsr63(uint64_t x)
+{
+  uint64_t bit = (x ^ (x >> 1)) & 1;
+  return (x >> 1) | (bit << 62);
+}
+
+static void cputchar(const char *file, int x)
+{
+  volatile char c = x;
+  register size_t a0 asm("a0") = (uintptr_t)(&c);
+  register size_t a1 asm("a1") = 1;
+  register size_t a2 asm("a2") = 0;
+  register size_t a3 asm("a3") = (uintptr_t)file;
+  asm volatile (".long 0x9E00007B" : : "r"(a0), "r"(a1), "r"(a2), "r"(a3));
+}
+
+static void cputstring(const char* s)
+{
+  while (*s)
+    cputchar(stdoutFile, *s++);
+}
+
+static void terminate(int code)
+{
+  cputchar(exitcodeFile, code >> 1);
+  register size_t a0 asm("a0") = 0;
+  asm volatile (".long 0x4200007B" : : "r"(a0));
+  while (1);
+}
+
+void wtf()
+{
+  terminate(255 << 1);
+}
+
+#define stringify1(x) #x
+#define stringify(x) stringify1(x)
+#define assert(x) do { \
+  if (x) break; \
+  cputstring("Assertion failed: " stringify(x) "\n"); \
+  terminate(3); \
+} while(0)
+
+#define l1pt pt[0]
+#define user_l2pt pt[1]
+#if SATP_MODE_CHOICE == SATP_MODE_SV48
+# define NPT 6
+# define kernel_l2pt pt[2]
+# define kernel_l3pt pt[3]
+# define user_l3pt pt[4]
+# define user_llpt pt[5]
+#elif SATP_MODE_CHOICE == SATP_MODE_SV39
+# define NPT 4
+# define kernel_l2pt pt[2]
+# define user_llpt pt[3]
+#elif SATP_MODE_CHOICE == SATP_MODE_SV32
+# define NPT 2
+# define user_llpt user_l2pt
+#else
+# error Unknown SATP_MODE_CHOICE
+#endif
+pte_t pt[NPT][PTES_PER_PT] __attribute__((aligned(PGSIZE)));
+
+typedef struct { pte_t addr; void* next; } freelist_t;
+
+freelist_t user_mapping[MAX_TEST_PAGES];
+freelist_t freelist_nodes[MAX_TEST_PAGES];
+freelist_t *freelist_head, *freelist_tail;
+
+void printhex(uint64_t x)
+{
+  char str[17];
+  for (int i = 0; i < 16; i++)
+  {
+    str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
+    x >>= 4;
+  }
+  str[16] = 0;
+
+  cputstring(str);
+}
+
+static void evict(unsigned long addr)
+{
+  assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
+  addr = addr/PGSIZE*PGSIZE;
+
+  freelist_t* node = &user_mapping[addr/PGSIZE];
+  if (node->addr)
+  {
+    // check accessed and dirty bits
+    assert(user_llpt[addr/PGSIZE] & PTE_A);
+    uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
+    if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
+      assert(user_llpt[addr/PGSIZE] & PTE_D);
+      memcpy((void*)addr, uva2kva(addr), PGSIZE);
+    }
+    write_csr(sstatus, sstatus);
+
+    user_mapping[addr/PGSIZE].addr = 0;
+
+    if (freelist_tail == 0)
+      freelist_head = freelist_tail = node;
+    else
+    {
+      freelist_tail->next = node;
+      freelist_tail = node;
+    }
+  }
+}
+
+void handle_fault(uintptr_t addr, uintptr_t cause)
+{
+  assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
+  addr = addr/PGSIZE*PGSIZE;
+
+  if (user_llpt[addr/PGSIZE]) {
+    if (!(user_llpt[addr/PGSIZE] & PTE_A)) {
+      user_llpt[addr/PGSIZE] |= PTE_A;
+    } else {
+      assert(!(user_llpt[addr/PGSIZE] & PTE_D) && cause == CAUSE_STORE_PAGE_FAULT);
+      user_llpt[addr/PGSIZE] |= PTE_D;
+    }
+    flush_page(addr);
+    return;
+  }
+
+  freelist_t* node = freelist_head;
+  assert(node);
+  freelist_head = node->next;
+  if (freelist_head == freelist_tail)
+    freelist_tail = 0;
+
+  uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
+  user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
+  flush_page(addr);
+
+  assert(user_mapping[addr/PGSIZE].addr == 0);
+  user_mapping[addr/PGSIZE] = *node;
+
+  uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
+  memcpy((void*)addr, uva2kva(addr), PGSIZE);
+  write_csr(sstatus, sstatus);
+
+  user_llpt[addr/PGSIZE] = new_pte;
+  flush_page(addr);
+
+  __builtin___clear_cache(0,0);
+}
+
+void handle_trap(trapframe_t* tf)
+{
+  if (tf->cause == CAUSE_USER_ECALL)
+  {
+    int n = tf->gpr[10];
+
+    for (long i = 1; i < MAX_TEST_PAGES; i++)
+      evict(i*PGSIZE);
+
+    terminate(n);
+  }
+  else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION)
+  {
+    assert(tf->epc % 4 == 0);
+
+    int* fssr;
+    asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr));
+
+    if (*(int*)tf->epc == *fssr)
+      terminate(1); // FP test on non-FP hardware.  "succeed."
+    else
+      assert(!"illegal instruction");
+    tf->epc += 4;
+  }
+  else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT)
+    handle_fault(tf->badvaddr, tf->cause);
+  else
+    assert(!"unexpected exception");
+
+  pop_tf(tf);
+}
+
+static void coherence_torture()
+{
+  // cause coherence misses without affecting program semantics
+  uint64_t random = ENTROPY;
+  while (1) {
+    uintptr_t paddr = DRAM_BASE + ((random % (2 * (MAX_TEST_PAGES + 1) * PGSIZE)) & -4);
+#ifdef __riscv_atomic
+    if (random & 1) // perform a no-op write
+      asm volatile ("amoadd.w zero, zero, (%0)" :: "r"(paddr));
+    else // perform a read
+#endif
+      asm volatile ("lw zero, (%0)" :: "r"(paddr));
+    random = lfsr63(random);
+  }
+}
+
+void vm_boot(uintptr_t test_addr)
+{
+  uint64_t random = ENTROPY;
+  if (read_csr(mhartid) > 0)
+    coherence_torture();
+
+  _Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
+
+#if (MAX_TEST_PAGES > PTES_PER_PT) || (DRAM_BASE % MEGAPAGE_SIZE) != 0
+# error
+#endif
+  // map user to lowermost megapage
+  l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+  // map kernel to uppermost megapage
+#if SATP_MODE_CHOICE == SATP_MODE_SV48
+  l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+  kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+  kernel_l3pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+  user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+  user_l3pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+#elif SATP_MODE_CHOICE == SATP_MODE_SV39
+  l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+  kernel_l2pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+  user_l2pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+#elif SATP_MODE_CHOICE == SATP_MODE_SV32
+  l1pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+#else
+# error
+#endif
+  uintptr_t vm_choice = SATP_MODE_CHOICE;
+  uintptr_t sptbr_value = ((uintptr_t)l1pt >> PGSHIFT)
+                        | (vm_choice * (SATP_MODE & ~(SATP_MODE<<1)));
+  write_csr(sptbr, sptbr_value);
+  if (read_csr(sptbr) != sptbr_value)
+    assert(!"unsupported satp mode");
+
+  // Set up PMPs if present, ignoring illegal instruction trap if not.
+  uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
+  uintptr_t pmpa = ((uintptr_t)1 << (__riscv_xlen == 32 ? 31 : 53)) - 1;
+  asm volatile ("la t0, 1f\n\t"
+                "csrrw t0, mtvec, t0\n\t"
+                "csrw pmpaddr0, %1\n\t"
+                "csrw pmpcfg0, %0\n\t"
+                ".align 2\n\t"
+                "1: csrw mtvec, t0"
+                : : "r" (pmpc), "r" (pmpa) : "t0");
+
+  // set up supervisor trap handling
+  write_csr(stvec, pa2kva(trap_entry));
+  write_csr(sscratch, pa2kva(read_csr(mscratch)));
+  write_csr(medeleg,
+    (1 << CAUSE_USER_ECALL) |
+    (1 << CAUSE_FETCH_PAGE_FAULT) |
+    (1 << CAUSE_LOAD_PAGE_FAULT) |
+    (1 << CAUSE_STORE_PAGE_FAULT));
+  // FPU on; accelerator on; vector unit on
+  write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS);
+  write_csr(mie, 0);
+
+  random = 1 + (random % MAX_TEST_PAGES);
+  freelist_head = pa2kva((void*)&freelist_nodes[0]);
+  freelist_tail = pa2kva(&freelist_nodes[MAX_TEST_PAGES-1]);
+  for (long i = 0; i < MAX_TEST_PAGES; i++)
+  {
+    freelist_nodes[i].addr = DRAM_BASE + (MAX_TEST_PAGES + random)*PGSIZE;
+    freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
+    random = LFSR_NEXT(random);
+  }
+  freelist_nodes[MAX_TEST_PAGES-1].next = 0;
+
+  trapframe_t tf;
+  memset(&tf, 0, sizeof(tf));
+  tf.epc = test_addr - DRAM_BASE;
+  pop_tf(&tf);
+}
diff --git a/src/asmtest/isa/.gitignore b/src/asmtest/isa/.gitignore
new file mode 100644
index 0000000..c93c5ff
--- /dev/null
+++ b/src/asmtest/isa/.gitignore
@@ -0,0 +1 @@
+rv*-*
diff --git a/src/asmtest/isa/macros/mt/test_macros_mt.h b/src/asmtest/isa/macros/mt/test_macros_mt.h
new file mode 100644
index 0000000..ae21fa5
--- /dev/null
+++ b/src/asmtest/isa/macros/mt/test_macros_mt.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This test_macros includes necessary functions and macros to create
+// and exit threads. They're used in multi-threaded assembly tests.
+// This assumes the target system can concurrently support 4 different
+// threads (i.e., 1 master thread and 3 child threads)
+//------------------------------------------------------------------------
+
+#ifndef __TEST_MACROS_MT_H
+#define __TEST_MACROS_MT_H
+
+#define SYSCALL_MMAP    222
+#define SYSCALL_MUNMAP  215
+#define SYSCALL_CLONE   220
+
+#define STACK_SIZE      (4096 * 1024)
+
+#define PROT_READ	      0x1
+#define PROT_WRITE	    0x2
+#define MMAP_PROT_FLAGS (PROT_READ | PROT_WRITE)
+
+#define MAP_PRIVATE	    0x02
+#define MAP_ANONYMOUS	  0x20
+#define MAP_STACK	      0x20000
+#define MMAP_MAP_FLAGS  (MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK)
+
+#define CLONE_VM	      0x00000100
+#define CLONE_FS	      0x00000200
+#define CLONE_FILES	    0x00000400
+#define CLONE_SIGHAND	  0x00000800
+#define CLONE_PARENT	  0x00008000
+#define CLONE_THREAD	  0x00010000
+#define CLONE_IO		    0x80000000
+#define CLONE_FLAGS     (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND\
+                         | CLONE_PARENT | CLONE_THREAD | CLONE_IO)
+
+#define NUM_THREADS     3
+
+#define FAILURE         1
+#define SUCCESS         0
+
+#define HARTID          0xF14
+
+//------------------------------------------------------------------------
+// create NUM_THREADS child threads
+//------------------------------------------------------------------------
+_create_threads:
+  li      t0, NUM_THREADS
+  mv      s0, ra                  // save return register
+1:
+  jal     ra, _alloc_stack
+  addi    sp, sp, -8
+  sd      a0, (sp)                // save pointer to the new stack
+  jal     ra, _clone_thread       // clone a new thread
+  addi    t0, t0, -1
+  bnez    t0, 1b
+  mv      ra, s0                  // restore return register
+  ret
+
+_alloc_stack:
+  li      a0, 0
+  li      a1, STACK_SIZE
+  li      a2, MMAP_PROT_FLAGS
+  li      a3, MMAP_MAP_FLAGS
+  li      a4, -1
+  li      a5, 0
+  li      a7, SYSCALL_MMAP
+  ecall
+  ret
+
+_clone_thread:
+  li      a1, STACK_SIZE
+  add     a1, a1, a0
+  li      a0, CLONE_FLAGS
+  li      a7, SYSCALL_CLONE
+  ecall
+  beqz    a0, _mt_test
+  ret
+
+//------------------------------------------------------------------------
+// wait for all child threads to exit
+//------------------------------------------------------------------------
+_join:
+  la      t0, barrier
+  li      t1, NUM_THREADS
+1:
+  ld      t2, (t0)
+  bne     t1, t2, 1b
+  ret
+
+//------------------------------------------------------------------------
+// deallocate NUM_THREADS child threads
+//------------------------------------------------------------------------
+_delete_threads:
+  li      t0, NUM_THREADS
+  mv      s0, ra                  // save return register
+1:
+  ld      a0, (sp)                // pop the new stack's pointer
+  addi    sp, sp, 8
+  jal     ra, _dealloc_stack
+  addi    t0, t0, -1
+  bnez    t0, 1b
+  mv      ra, s0                  // restore return register
+  ret
+
+_dealloc_stack:
+  li      a1, STACK_SIZE
+  li      a7, SYSCALL_MUNMAP
+  ecall
+  ret
+
+#define MT_DATA                                                           \
+  shared_var:   .dword    0;                                              \
+  barrier:      .dword    0;                                              \
+  array:        .dword    0x00000000deadbeef,                             \
+                          0xdeadbeefdeadbeef,                             \
+                          0x12343eeaaf423451;                             \
+
+#endif
diff --git a/src/asmtest/isa/macros/mt/test_macros_mt_ecall.h b/src/asmtest/isa/macros/mt/test_macros_mt_ecall.h
new file mode 100644
index 0000000..c5cae0f
--- /dev/null
+++ b/src/asmtest/isa/macros/mt/test_macros_mt_ecall.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This test_macros includes necessary functions and macros to create
+// and exit threads. They're used in multi-threaded assembly tests.
+// This assumes the target system can concurrently support 4 different
+// threads (i.e., 1 master thread and 3 child threads).
+//
+// Threads are synchronized through futex system call (i.e., wait and
+// wakeup operations).
+//------------------------------------------------------------------------
+
+#ifndef __TEST_MACROS_MT_FUTEX_H
+#define __TEST_MACROS_MT_FUTEX_H
+
+#define SYSCALL_FUTEX         98
+#define SYSCALL_GETTID        178
+#define SYSCALL_MUNMAP        215
+#define SYSCALL_CLONE         220
+#define SYSCALL_MMAP          222
+
+#define MEM_SIZE              (4096 * 1024)
+
+#define PROT_READ             0x1
+#define PROT_WRITE            0x2
+#define MMAP_PROT_FLAGS       (PROT_READ | PROT_WRITE)
+
+#define MAP_PRIVATE           0x02
+#define MAP_ANONYMOUS         0x20
+#define MAP_STACK             0x20000
+#define MMAP_MAP_FLAGS        (MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK)
+
+#define CLONE_VM              0x00000100
+#define CLONE_FS              0x00000200
+#define CLONE_FILES           0x00000400
+#define CLONE_SIGHAND         0x00000800
+#define CLONE_PARENT          0x00008000
+#define CLONE_THREAD          0x00010000
+#define CLONE_IO              0x80000000
+#define CLONE_PARENT_SETTID   0x00100000	/* set the TID in the parent */
+#define CLONE_CHILD_CLEARTID  0x00200000	/* clear the TID in the child */
+#define CLONE_SETTLS          0x00080000
+#define CLONE_FLAGS           (CLONE_VM | CLONE_FS | CLONE_FILES \
+                              | CLONE_SIGHAND | CLONE_PARENT \
+                              | CLONE_THREAD | CLONE_IO \
+                              | CLONE_PARENT_SETTID \
+                              | CLONE_CHILD_CLEARTID \
+                              | CLONE_SETTLS)
+
+#define FUTEX_WAIT            0
+#define FUTEX_WAKE            1
+#define FUTEX_CMP_REQUEUE     4
+#define FUTEX_WAKE_OP         5
+#define FUTEX_WAIT_BITSET     9
+#define FUTEX_WAKE_BITSET     10
+#define FUTEX_PRIVATE_FLAG    128
+#define FUTEX_CLOCK_REALTIME  256
+#define FUTEX_CMD_MASK        ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
+
+#define FUTEX_OP_SET          0  /* uaddr2 = oparg; */
+#define FUTEX_OP_ADD          1  /* uaddr2 += oparg; */
+#define FUTEX_OP_OR           2  /* uaddr2 |= oparg; */
+#define FUTEX_OP_ANDN         3  /* uaddr2 &= ~oparg; */
+#define FUTEX_OP_XOR          4  /* uaddr2 ^= oparg; */
+#define FUTEX_OP_ARG_SHIFT    8  /* Use (1 << oparg) as operand */
+
+#define FUTEX_OP_CMP_EQ       0  /* if (oldval == cmparg) wake */
+#define FUTEX_OP_CMP_NE       1  /* if (oldval != cmparg) wake */
+#define FUTEX_OP_CMP_LT       2  /* if (oldval < cmparg) wake */
+#define FUTEX_OP_CMP_LE       3  /* if (oldval <= cmparg) wake */
+#define FUTEX_OP_CMP_GT       4  /* if (oldval > cmparg) wake */
+#define FUTEX_OP_CMP_GE       5  /* if (oldval >= cmparg) wake */
+
+#define FUTEX_OP(op, oparg, cmp, cmparg)                    \
+                (((op & 0xf) << 28) |                       \
+                 ((cmp & 0xf) << 24) |                      \
+                 ((oparg & 0xfff) << 12) |                  \
+                 (cmparg & 0xfff))
+
+#define FUTEX_WAIT_PRIVATE        (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_PRIVATE        (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
+
+#define FAILURE               1
+#define SUCCESS               0
+
+//------------------------------------------------------------------------
+// _create_threads: create a given number of threads
+//
+//    The calling thread (a.k.a, master thread) saves information about its
+//    child threads in its stack in the following structure:
+//
+//    | child_stack_ptr_0       |  << fp: frame pointer
+//    | child_tls_ptr_0         |
+//    | child_thread_id_0       |
+//    | saved_child_thread_id_0 |
+//    | child_stack_ptr_1       |
+//    | child_tls_ptr_1         |
+//    | child_thread_id_1       |
+//    | saved_child_thread_id_1 |
+//    | ...                     |  << sp: stack pointer
+//
+//    For each child thread, we need to save the following information
+//    in the parent thread's stack frame:
+//
+//    - child_stack_ptr stores the lower address of the child thread's
+//      stack space
+//
+//    - child_tls_ptr stores the lower address of the child thread's
+//      thread local storage (TLS)
+//
+//    - child_thread_id stores the thread ID of the child thread. This
+//      variable will be cleared by the child thread when it exits.
+//
+//    - saved_child_thread_id also stores the thread ID of the child
+//      thread, but this variable is used only by the parent thread.
+//
+//    This function takes the number of threads to create in a0. It
+//    updates n_child_threads variable to the number of successfully
+//    created threads.
+//------------------------------------------------------------------------
+
+_create_threads:
+  mv      t0, a0                // get the number of threads
+  mv      s0, ra                // save return register
+  la      t3, n_worker_threads
+1:
+  // allocate a new stack space and save its pointer in the caller's stack
+  jal     ra, _alloc_mem
+  addi    sp, sp, -8
+  sd      a0, (sp)
+  mv      t1, a0
+
+  // allocate a new thread local storage (TLS) and save its pointer in the
+  // caller's stack
+  jal     ra, _alloc_mem
+  addi    sp, sp, -8
+  sd      a0, (sp)
+  mv      t2, a0
+
+  // allocate space in the caller's stack to store new thread ID
+  addi    sp, sp, -8
+
+  // clone a new thread
+  li      a0, CLONE_FLAGS
+  li      s2, MEM_SIZE
+  add     a1, t1, s2        // pointer to the high address of the new stack
+  mv      a2, sp            // ptid
+  mv      a3, t2            // pointer to the low address of the new TLS,
+                            // assuming TLS grows upward
+  mv      a4, sp            // ctid
+  li      a7, SYSCALL_CLONE // clone syscall number
+  ecall                     // call clone syscall
+  bltz    a0, 2f            // syscall error
+  beqz    a0, _mt_test      // only the new thread jumps to _mt_test
+
+  // save child thread ID in the caller's stack
+  addi      sp, sp, -8
+  sd        a0, (sp)
+
+  // decrement the number of threads to create
+  addi      t0, t0, -1
+
+  // increment the number of successfully created threads sofar
+  addi      t4, zero, 1
+  amoadd.d  zero, t4, (t3)
+
+  // check if we still need to spawn more threads
+  bnez      t0, 1b
+  j         3f
+2:
+  // handle clone syscall error by deleting the last memory frame created
+  // for the unsuccessfully spawned thread.
+  addi      sp, sp, 8       // skip child_thread_id
+
+  // deallocate last allocated tls
+  ld        a0, (sp)
+  jal       ra, _dealloc_mem
+  addi      sp, sp, 8
+
+  // deallocate last allocated stack
+  ld        a0, (sp)
+  jal       ra, _dealloc_mem
+  addi      sp, sp, 8
+3:
+  // finish creating threads
+  mv        ra, s0
+  ret
+
+//------------------------------------------------------------------------
+// _alloc_mem: allocate a memory space with size MEM_SIZE
+//
+//    This function returns the pointer to the newly allocated memory
+//    space in a0
+//------------------------------------------------------------------------
+
+_alloc_mem:
+  li      a0, 0
+  li      a1, MEM_SIZE
+  li      a2, MMAP_PROT_FLAGS
+  li      a3, MMAP_MAP_FLAGS
+  li      a4, -1
+  li      a5, 0
+  li      a7, SYSCALL_MMAP
+  ecall
+  ret
+
+//------------------------------------------------------------------------
+// _delete_threads: deallocate all child threads
+//
+//    This function assumes the following structure in the calling thread's
+//    stack frame
+//
+//    | child_stack_ptr_0       |  << fp: frame pointer
+//    | child_tls_ptr_0         |
+//    | child_thread_id_0       |
+//    | saved_child_thread_id_0 |
+//    | child_stack_ptr_1       |
+//    | child_tls_ptr_1         |
+//    | child_thread_id_1       |
+//    | saved_child_thread_id_1 |
+//    | ...                     |  << sp: stack pointer
+//
+//    This function takes the number of threads to delete in a0
+//------------------------------------------------------------------------
+
+_delete_threads:
+  mv      t0, a0                  // get the number of threads to delete
+  mv      s0, ra                  // save return register
+1:
+  addi    sp, sp, 8               // skip saved_child_thread_id
+  addi    sp, sp, 8               // skip child_thread_id
+
+  // deallocate thread's tls
+  ld      a0, (sp)
+  jal     ra, _dealloc_mem
+  addi    sp, sp, 8
+
+  // deallocate thread's stack
+  ld      a0, (sp)
+  jal     ra, _dealloc_mem
+  addi    sp, sp, 8
+
+  // decrement the number of threads to delete
+  addi    t0, t0, -1
+  bnez    t0, 1b
+
+  // finish deleting all threads
+  mv      ra, s0                  // restore return register
+  ret
+
+//------------------------------------------------------------------------
+// _dealloc_mem: deallocate memory space of size MEM_SIZE
+//
+//    This function takes the pointer to the memory space in a0
+//------------------------------------------------------------------------
+
+_dealloc_mem:
+  li      a1, MEM_SIZE
+  li      a7, SYSCALL_MUNMAP
+  ecall
+  ret
+
+//------------------------------------------------------------------------
+// _join: wait for all child threads to exit
+//
+//    Child threads are created with CLONE_CHILD_CLEARTID flag, so when
+//    they exit, they will clear the ctid/ptid variable and wake up their
+//    parent thread.
+//
+//    This function assumes the following structure in the calling thread's
+//    stack frame
+//
+//    | child_stack_ptr_0       |  << fp: frame pointer
+//    | child_tls_ptr_0         |
+//    | child_thread_id_0       |
+//    | saved_child_thread_id_0 |
+//    | child_stack_ptr_1       |
+//    | child_tls_ptr_1         |
+//    | child_thread_id_1       |
+//    | saved_child_thread_id_1 |
+//    | ...                     |  << sp: stack pointer
+//
+//    This function takes a number of threads to wait in a0
+//------------------------------------------------------------------------
+
+_join:
+  mv      t0, a0          // get the number of threads
+  mv      s0, ra          // save return register
+  mv      s1, sp          // save stack pointer
+1:
+  // Calling futex_wait on ctidptr
+  ld      a2, (sp)                // get child thread ID from
+                                  // saved_child_thread_id
+  addi    sp, sp, 8
+  mv      a0, sp                  // futex address (child_thread_id)
+  li      a1, FUTEX_WAIT_PRIVATE
+  li      a7, SYSCALL_FUTEX
+  ecall
+
+  addi    sp, sp, 8              // skip child_tls_ptr
+  addi    sp, sp, 8              // skip child_stack_ptr
+
+  // decrement the number of threads to wait for
+  addi    t0, t0, -1
+  bnez    t0, 1b
+
+  // finish waiting for all threads
+  mv      ra, s0                  // restore return register
+  mv      sp, s1                  // restore stack pointer
+  ret
+
+#define MT_DATA                                                           \
+  n_worker_threads:     .dword    0;                                      \
+  shared_var:           .dword    0;                                      \
+  barrier:              .dword    0;                                      \
+  array:                .dword    0x00000000deadbeef,                     \
+                                  0xdeadbeefdeadbeef,                     \
+                                  0x12343eeaaf423451;                     \
+
+#endif
diff --git a/src/asmtest/isa/macros/scalar/test_macros.h b/src/asmtest/isa/macros/scalar/test_macros.h
new file mode 100644
index 0000000..ed4cab0
--- /dev/null
+++ b/src/asmtest/isa/macros/scalar/test_macros.h
@@ -0,0 +1,649 @@
+// See LICENSE for license details.
+
+#ifndef __TEST_MACROS_SCALAR_H
+#define __TEST_MACROS_SCALAR_H
+
+
+#-----------------------------------------------------------------------
+# Helper macros
+#-----------------------------------------------------------------------
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define TEST_CASE( testnum, testreg, correctval, code... ) \
+test_ ## testnum: \
+    code; \
+    li  x7, MASK_XLEN(correctval); \
+    li  TESTNUM, testnum; \
+    bne testreg, x7, fail;
+
+# We use a macro hack to simpify code generation for various numbers
+# of bubble cycles.
+
+#define TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_1  nop; TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_2  nop; TEST_INSERT_NOPS_1
+#define TEST_INSERT_NOPS_3  nop; TEST_INSERT_NOPS_2
+#define TEST_INSERT_NOPS_4  nop; TEST_INSERT_NOPS_3
+#define TEST_INSERT_NOPS_5  nop; TEST_INSERT_NOPS_4
+#define TEST_INSERT_NOPS_6  nop; TEST_INSERT_NOPS_5
+#define TEST_INSERT_NOPS_7  nop; TEST_INSERT_NOPS_6
+#define TEST_INSERT_NOPS_8  nop; TEST_INSERT_NOPS_7
+#define TEST_INSERT_NOPS_9  nop; TEST_INSERT_NOPS_8
+#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
+
+
+#-----------------------------------------------------------------------
+# RV64UI MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests for instructions with immediate operand
+#-----------------------------------------------------------------------
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x14, x1, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x1, x1, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      inst x14, x1, SEXT_IMM(imm); \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x14, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      inst x14, x1, SEXT_IMM(imm); \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \
+    TEST_CASE( testnum, x1, result, \
+      inst x1, x0, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \
+    TEST_CASE( testnum, x0, 0, \
+      li  x1, MASK_XLEN(val1); \
+      inst x0, x1, SEXT_IMM(imm); \
+    )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register operands
+#-----------------------------------------------------------------------
+
+#define TEST_R_OP( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x1, val1; \
+      inst x14, x1; \
+    )
+
+#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, val1; \
+      inst x1, x1; \
+    )
+
+#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, val1; \
+      inst x14, x1; \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x14, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register-register operands
+#-----------------------------------------------------------------------
+
+#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x14, x1, x2; \
+    )
+
+#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x1, x1, x2; \
+    )
+
+#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x2, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x2, x1, x2; \
+    )
+
+#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x1, x1, x1; \
+    )
+
+#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x14, x1, x2; \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x14, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## src1_nops \
+      li  x2, MASK_XLEN(val2); \
+      TEST_INSERT_NOPS_ ## src2_nops \
+      inst x14, x1, x2; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x14, result, \
+      li  x4, 0; \
+1:    li  x2, MASK_XLEN(val2); \
+      TEST_INSERT_NOPS_ ## src1_nops \
+      li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## src2_nops \
+      inst x14, x1, x2; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
+    TEST_CASE( testnum, x2, result, \
+      li x1, MASK_XLEN(val); \
+      inst x2, x0, x1; \
+    )
+
+#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
+    TEST_CASE( testnum, x2, result, \
+      li x1, MASK_XLEN(val); \
+      inst x2, x1, x0; \
+    )
+
+#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
+    TEST_CASE( testnum, x1, result, \
+      inst x1, x0, x0; \
+    )
+
+#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
+    TEST_CASE( testnum, x0, 0, \
+      li x1, MASK_XLEN(val1); \
+      li x2, MASK_XLEN(val2); \
+      inst x0, x1, x2; \
+    )
+
+#-----------------------------------------------------------------------
+# Test memory instructions
+#-----------------------------------------------------------------------
+
+#define TEST_LD_OP( testnum, inst, result, offset, base ) \
+    TEST_CASE( testnum, x14, result, \
+      la  x1, base; \
+      inst x14, offset(x1); \
+    )
+
+#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
+    TEST_CASE( testnum, x14, result, \
+      la  x1, base; \
+      li  x2, result; \
+      store_inst x2, offset(x1); \
+      load_inst x14, offset(x1); \
+    )
+
+#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  la  x1, base; \
+    inst x14, offset(x1); \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    addi  x6, x14, 0; \
+    li  x7, result; \
+    bne x6, x7, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b; \
+
+#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  la  x1, base; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x14, offset(x1); \
+    li  x7, result; \
+    bne x14, x7, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  li  x1, result; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    la  x2, base; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    store_inst x1, offset(x2); \
+    load_inst x14, offset(x2); \
+    li  x7, result; \
+    bne x14, x7, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  la  x2, base; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x1, result; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    store_inst x1, offset(x2); \
+    load_inst x14, offset(x2); \
+    li  x7, result; \
+    bne x14, x7, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x1, val1; \
+    li  x2, val2; \
+    inst x1, x2, 2f; \
+    bne x0, TESTNUM, fail; \
+1:  bne x0, TESTNUM, 3f; \
+2:  inst x1, x2, 1b; \
+    bne x0, TESTNUM, fail; \
+3:
+
+#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x1, val1; \
+    li  x2, val2; \
+    inst x1, x2, 1f; \
+    bne x0, TESTNUM, 2f; \
+1:  bne x0, TESTNUM, fail; \
+2:  inst x1, x2, 1b; \
+3:
+
+#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  li  x1, val1; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x2, val2; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    inst x1, x2, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  li  x2, val2; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x1, val1; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    inst x1, x2, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#-----------------------------------------------------------------------
+# Test jump instructions
+#-----------------------------------------------------------------------
+
+#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  la  x6, 2f; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x6; \
+    bne x0, TESTNUM, fail; \
+2:  addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+    li  x4, 0; \
+1:  la  x6, 2f; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x13, x6, 0; \
+    bne x0, TESTNUM, fail; \
+2:  addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+
+#-----------------------------------------------------------------------
+# RV64UF MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests floating-point instructions
+#-----------------------------------------------------------------------
+
+#define qNaNf 0f:7fc00000
+#define sNaNf 0f:7f800001
+#define qNaN 0d:7ff8000000000000
+#define sNaN 0d:7ff0000000000001
+
+#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  flw f0, 0(a0); \
+  flw f1, 4(a0); \
+  flw f2, 8(a0); \
+  lw  a3, 12(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 2; \
+  test_ ## testnum ## _data: \
+  .float val1; \
+  .float val2; \
+  .float val3; \
+  .result; \
+  .popsection
+
+#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  fld f0, 0(a0); \
+  fld f1, 8(a0); \
+  fld f2, 16(a0); \
+  ld  a3, 24(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double val1; \
+  .double val2; \
+  .double val3; \
+  .result; \
+  .popsection
+
+// TODO: assign a separate mem location for the comparison address?
+#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  fld f0, 0(a0); \
+  fld f1, 8(a0); \
+  fld f2, 16(a0); \
+  lw  a3, 24(a0); \
+  lw  t1, 28(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne t1, t2, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double val1; \
+  .double val2; \
+  .double val3; \
+  .result; \
+  .popsection
+
+#define TEST_FCVT_S_D32( testnum, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+                    fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FCVT_S_D( testnum, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+                    fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3)
+
+#define TEST_FCVT_D_S( testnum, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
+                    fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fmv.x.s a0, f3)
+
+#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fmv.x.d a0, f3)
+
+#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fmv.x.s a0, f3)
+
+#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fmv.x.d a0, f3)
+
+#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
+                    inst a0, f0, rm)
+
+#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst a0, f0, rm)
+
+#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \
+                    inst a0, f0, f1)
+
+#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+                    inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+                    inst a0, f0, f1)
+
+#define TEST_FCLASS_S(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \
+                    fclass.s a0, fa0)
+
+#define TEST_FCLASS_D32(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, \
+            la a0, test_ ## testnum ## _data ;\
+            fld fa0, 0(a0); \
+            fclass.d a0, fa0) \
+    .pushsection .data; \
+    .align 3; \
+    test_ ## testnum ## _data: \
+    .dword input; \
+    .popsection
+
+#define TEST_FCLASS_D(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \
+                    fclass.d a0, fa0)
+
+#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  lw  a3, 0(a0); \
+  li  a0, val1; \
+  inst f0, a0; \
+  fsflags x0; \
+  fmv.x.s a0, f0; \
+  bne a0, a3, fail; \
+  .pushsection .data; \
+  .align 2; \
+  test_ ## testnum ## _data: \
+  .float result; \
+  .popsection
+
+#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  lw  a3, 0(a0); \
+  lw  a4, 4(a0); \
+  li  a1, val1; \
+  inst f0, a1; \
+  \
+  fsd f0, 0(a0); \
+  lw a1, 4(a0); \
+  lw a0, 0(a0); \
+  \
+  fsflags x0; \
+  bne a0, a3, fail; \
+  bne a1, a4, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double result; \
+  .popsection
+
+#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  ld  a3, 0(a0); \
+  li  a0, val1; \
+  inst f0, a0; \
+  fsflags x0; \
+  fmv.x.d a0, f0; \
+  bne a0, a3, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double result; \
+  .popsection
+
+// We need some special handling here to allow 64-bit comparison in 32-bit arch
+// TODO: find a better name and clean up when intended for general usage?
+#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
+test_ ## testnum: \
+    code; \
+    la  x15, test_ ## testnum ## _data ; \
+    lw  x7, 0(x15); \
+    lw  x15, 4(x15); \
+    li  TESTNUM, testnum; \
+    bne testreg1, x7, fail;\
+    bne testreg2, x15, fail;\
+    .pushsection .data; \
+    .align 3; \
+    test_ ## testnum ## _data: \
+    .dword correctval; \
+    .popsection
+
+// ^ x14 is used in some other macros, to avoid issues we use x15 for upper word
+
+#-----------------------------------------------------------------------
+# Pass and fail code (assumes test num is in TESTNUM)
+#-----------------------------------------------------------------------
+
+#define TEST_PASSFAIL \
+        bne x0, TESTNUM, pass; \
+fail: \
+        RVTEST_FAIL; \
+pass: \
+        RVTEST_PASS \
+
+
+#-----------------------------------------------------------------------
+# Test data section
+#-----------------------------------------------------------------------
+
+#define TEST_DATA
+
+#endif
diff --git a/src/asmtest/isa/rv64mi/Makefrag b/src/asmtest/isa/rv64mi/Makefrag
new file mode 100644
index 0000000..c81c24e
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/Makefrag
@@ -0,0 +1,18 @@
+#=======================================================================
+# Makefrag for rv64mi tests
+#-----------------------------------------------------------------------
+
+rv64mi_sc_tests = \
+	access \
+	breakpoint \
+	csr \
+	mcsr \
+	illegal \
+	ma_fetch \
+	ma_addr \
+	scall \
+	sbreak \
+
+rv64mi_p_tests = $(addprefix rv64mi-p-, $(rv64mi_sc_tests))
+
+spike_tests += $(rv64mi_p_tests)
diff --git a/src/asmtest/isa/rv64mi/access.S b/src/asmtest/isa/rv64mi/access.S
new file mode 100644
index 0000000..40a28d3
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/access.S
@@ -0,0 +1,70 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# access.S
+#-----------------------------------------------------------------------------
+#
+# Test access-exception behavior.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  .align 2
+
+  # Flipping just the MSB should result in an illegal address for RV64.
+  la t2, fail
+  li t0, 1 << (__riscv_xlen - 1)
+  xor t0, t0, t2
+
+  # jalr to an illegal address should commit (hence should write rd).
+  # after the pc is set to rs1, an access exception should be raised.
+  li TESTNUM, 2
+  li t1, CAUSE_FETCH_ACCESS
+  la s1, 1f
+  li t2, 0
+  jalr t2, t0
+1:
+
+  # A load to an illegal address should not commit.
+  li TESTNUM, 3
+  li t1, CAUSE_LOAD_ACCESS
+  la s1, 1f
+  mv t2, s1
+  lb t2, (t0)
+  j fail
+1:
+
+  j pass
+
+  TEST_PASSFAIL
+
+  .align 2
+  .global mtvec_handler
+mtvec_handler:
+  li a0, 2
+  beq TESTNUM, a0, 2f
+  li a0, 3
+  beq TESTNUM, a0, 2f
+  j fail
+
+2:
+  bne t2, s1, fail
+
+  csrr t2, mcause
+  bne t2, t1, fail
+
+  csrw mepc, s1
+  mret
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64mi/breakpoint.S b/src/asmtest/isa/rv64mi/breakpoint.S
new file mode 100644
index 0000000..252a696
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/breakpoint.S
@@ -0,0 +1,129 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# breakpoint.S
+#-----------------------------------------------------------------------------
+#
+# Test breakpoints, if they are implemented.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  # Set up breakpoint to trap on M-mode fetches.
+  li TESTNUM, 2
+
+  # Skip tselect if hard-wired.
+  csrw tselect, x0
+  csrr a1, tselect
+  bne x0, a1, pass
+
+  la a2, 1f
+  csrw tdata2, a2
+  li a0, (2 << (__riscv_xlen - 4)) | MCONTROL_M | MCONTROL_EXECUTE
+  csrw tdata1, a0
+  # Skip if breakpoint type is unsupported.
+  csrr a1, tdata1
+  bne a0, a1, 2f
+  .align 2
+1:
+  # Trap handler should skip this instruction.
+  beqz x0, fail
+
+  # Make sure reads don't trap.
+  li TESTNUM, 3
+  lw a0, (a2)
+
+2:
+  # Set up breakpoint to trap on M-mode reads.
+  li TESTNUM, 4
+  li a0, (2 << (__riscv_xlen - 4)) | MCONTROL_M | MCONTROL_LOAD
+  csrw tdata1, a0
+  # Skip if breakpoint type is unsupported.
+  csrr a1, tdata1
+  bne a0, a1, 2f
+  la a2, data1
+  csrw tdata2, a2
+
+  # Trap handler should skip this instruction.
+  lw a2, (a2)
+  beqz a2, fail
+
+  # Make sure writes don't trap.
+  li TESTNUM, 5
+  sw x0, (a2)
+
+2:
+  # Set up breakpoint to trap on M-mode stores.
+  li TESTNUM, 6
+  li a0, (2 << (__riscv_xlen - 4)) |  MCONTROL_M | MCONTROL_STORE
+  csrw tdata1, a0
+  # Skip if breakpoint type is unsupported.
+  csrr a1, tdata1
+  bne a0, a1, 2f
+
+  # Trap handler should skip this instruction.
+  sw a2, (a2)
+
+  # Make sure store didn't succeed.
+  li TESTNUM, 7
+  lw a2, (a2)
+  bnez a2, fail
+
+  # Try to set up a second breakpoint.
+  li a0, 1
+  csrw tselect, a0
+  csrr a1, tselect
+  bne a0, a1, pass
+
+  li a0, (2 << (__riscv_xlen - 4)) | MCONTROL_M | MCONTROL_LOAD
+  csrw tdata1, a0
+  la a3, data2
+  csrw tdata2, a3
+
+  # Make sure the second breakpoint triggers.
+  li TESTNUM, 8
+  lw a3, (a3)
+  beqz a3, fail
+
+  # Make sure the first breakpoint still triggers.
+  li TESTNUM, 10
+  la a2, data1
+  sw a2, (a2)
+  li TESTNUM, 11
+  lw a2, (a2)
+  bnez a2, fail
+
+2:
+  TEST_PASSFAIL
+
+  .align 2
+  .global mtvec_handler
+mtvec_handler:
+  # Only even-numbered tests should trap.
+  andi t0, TESTNUM, 1
+  bnez t0, fail
+
+  li t0, CAUSE_BREAKPOINT
+  csrr t1, mcause
+  bne t0, t1, fail
+
+  csrr t0, mepc
+  addi t0, t0, 4
+  csrw mepc, t0
+  mret
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+data1: .word 0
+data2: .word 0
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64mi/csr.S b/src/asmtest/isa/rv64mi/csr.S
new file mode 100644
index 0000000..77e7619
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/csr.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64S
+#define RVTEST_RV64S RVTEST_RV64M
+#define __MACHINE_MODE
+
+#include "../rv64si/csr.S"
diff --git a/src/asmtest/isa/rv64mi/illegal.S b/src/asmtest/isa/rv64mi/illegal.S
new file mode 100644
index 0000000..41097f5
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/illegal.S
@@ -0,0 +1,196 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# illegal.S
+#-----------------------------------------------------------------------------
+#
+# Test illegal instruction trap.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  .align 2
+  .option norvc
+
+  li TESTNUM, 2
+bad2:
+  .word 0
+  j fail
+
+  # Skip the rest of the test if S-mode is not present.
+  li t0, MSTATUS_MPP
+  csrc mstatus, t0
+  li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S
+  csrs mstatus, t1
+  csrr t2, mstatus
+  and t2, t2, t0
+  bne t1, t2, pass
+
+  # Test vectored interrupts if they are supported.
+test_vectored_interrupts:
+  csrwi mip, MIP_SSIP
+  csrwi mie, MIP_SSIP
+  la t0, mtvec_handler + 1
+  csrrw s0, mtvec, t0
+  csrr t0, mtvec
+  andi t0, t0, 1
+  beqz t0, msip
+  csrsi mstatus, MSTATUS_MIE
+# TODO we don't have a timer yet, so just skip the test
+# 1:
+#   j 1b
+msip:
+  csrw mtvec, s0
+
+  # Delegate supervisor software interrupts so WFI won't stall.
+  csrwi mideleg, MIP_SSIP
+  # Enter supervisor mode.
+  la t0, 1f
+  csrw mepc, t0
+  li t0, MSTATUS_MPP
+  csrc mstatus, t0
+  li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S
+  csrs mstatus, t1
+  mret
+
+1:
+  # Make sure WFI doesn't trap when TW=0.
+  wfi
+bad3:
+  .word 0
+  j fail
+
+bad4:
+  # Make sure WFI does trap when TW=1.
+  wfi
+  j fail
+
+  # Make sure SFENCE.VMA and sptbr don't trap when TVM=0.
+  sfence.vma
+  csrr t0, sptbr
+bad5:
+  .word 0
+  j fail
+
+bad6:
+  # Make sure SFENCE.VMA and sptbr do trap when TVM=1.
+  sfence.vma
+  j fail
+bad7:
+  csrr t0, sptbr
+  j fail
+
+  # Make sure SRET doesn't trap when TSR=0.
+  la t0, bad8
+  csrw sepc, t0
+  li t0, SSTATUS_SPP
+  csrs sstatus, t0
+  li t0, SSTATUS_SPIE
+  csrc sstatus, t0
+  sret
+bad8:
+  .word 0
+  j fail
+
+  # Make sure SRET does trap when TSR=1.
+  la t0, 1f
+  csrw sepc, t0
+bad9:
+  sret
+1:
+  j fail
+
+  TEST_PASSFAIL
+
+  .align 8
+  .global mtvec_handler
+mtvec_handler:
+  j synchronous_exception
+  j msip
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+  j fail
+
+synchronous_exception:
+  li t1, CAUSE_ILLEGAL_INSTRUCTION
+  csrr t0, mcause
+  bne t0, t1, fail
+  csrr t0, mepc
+
+  # Make sure mtval contains either 0 or the instruction word.
+  csrr t2, mbadaddr
+  beqz t2, 1f
+  lhu t1, 0(t0)
+  xor t2, t2, t1
+  lhu t1, 2(t0)
+  slli t1, t1, 16
+  xor t2, t2, t1
+  bnez t2, fail
+1:
+
+  la t1, bad2
+  beq t0, t1, 2f
+  la t1, bad3
+  beq t0, t1, 3f
+  la t1, bad4
+  beq t0, t1, 4f
+  la t1, bad5
+  beq t0, t1, 5f
+  la t1, bad6
+  beq t0, t1, 6f
+  la t1, bad7
+  beq t0, t1, 7f
+  la t1, bad8
+  beq t0, t1, 8f
+  la t1, bad9
+  beq t0, t1, 9f
+  j fail
+2:
+4:
+6:
+7:
+  addi t0, t0, 8
+  csrw mepc, t0
+  mret
+
+3:
+  li t1, MSTATUS_TW
+  csrs mstatus, t1
+  j 2b
+
+5:
+  li t1, MSTATUS_TVM
+  csrs mstatus, t1
+  j 2b
+
+8:
+  li t1, MSTATUS_TSR
+  csrs mstatus, t1
+  j 2b
+
+9:
+  j 2b
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64mi/ma_addr.S b/src/asmtest/isa/rv64mi/ma_addr.S
new file mode 100644
index 0000000..721ac6a
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/ma_addr.S
@@ -0,0 +1,126 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ma_addr.S
+#-----------------------------------------------------------------------------
+#
+# Test misaligned ld/st trap.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  .align 2
+  .option norvc
+
+  la s0, data
+
+  # indicate it's a load test
+  li s1, CAUSE_MISALIGNED_LOAD
+
+#define SEXT(x, n) ((-((x) >> ((n)-1)) << (n)) | ((x) & ((1 << (n))-1)))
+
+/* Check that a misaligned load either writes the correct value, or
+   takes an exception and performs no writeback.  */
+#define MISALIGNED_LOAD_TEST(testnum, insn, base, offset, res) \
+  li TESTNUM, testnum; \
+  la t2, 1f; \
+  addi t1, base, offset; \
+  insn t1, offset(base); \
+  li t2, res; \
+  bne t1, t2, fail; \
+1:
+
+  MISALIGNED_LOAD_TEST(2,  lh,  s0, 1, SEXT(0xbbcc, 16))
+  MISALIGNED_LOAD_TEST(3,  lhu, s0, 1, 0xbbcc)
+  MISALIGNED_LOAD_TEST(4,  lw,  s0, 1, SEXT(0x99aabbcc, 32))
+  MISALIGNED_LOAD_TEST(5,  lw,  s0, 2, SEXT(0x8899aabb, 32))
+  MISALIGNED_LOAD_TEST(6,  lw,  s0, 3, SEXT(0x778899aa, 32))
+
+#if __riscv_xlen == 64
+  MISALIGNED_LOAD_TEST(7,  lwu, s0, 1, 0x99aabbcc)
+  MISALIGNED_LOAD_TEST(8,  lwu, s0, 2, 0x8899aabb)
+  MISALIGNED_LOAD_TEST(9,  lwu, s0, 3, 0x778899aa)
+
+  MISALIGNED_LOAD_TEST(10, ld, s0, 1, 0x5566778899aabbcc)
+  MISALIGNED_LOAD_TEST(11, ld, s0, 2, 0x445566778899aabb)
+  MISALIGNED_LOAD_TEST(12, ld, s0, 3, 0x33445566778899aa)
+  MISALIGNED_LOAD_TEST(13, ld, s0, 4, 0x2233445566778899)
+  MISALIGNED_LOAD_TEST(14, ld, s0, 5, 0x1122334455667788)
+  MISALIGNED_LOAD_TEST(15, ld, s0, 6, 0xee11223344556677)
+  MISALIGNED_LOAD_TEST(16, ld, s0, 7, 0xffee112233445566)
+#endif
+
+  # indicate it's a store test
+  li s1, CAUSE_MISALIGNED_STORE
+
+/* Check that a misaligned store has some effect and takes no exception,
+   or takes no effect and generates an exception.  This is not very
+   thorough.  */
+#define MISALIGNED_STORE_TEST(testnum, insn, base, offset, size) \
+  li TESTNUM, testnum; \
+  la t2, 1f; \
+  addi t1, base, offset; \
+  insn x0, offset(base); \
+  lb t1, (offset - 1)(base); \
+  beqz t1, fail; \
+  lb t1, (offset + size)(base); \
+  beqz t1, fail; \
+  lb t1, (offset + 0)(base); \
+  bnez t1, fail; \
+  lb t1, (offset + size - 1)(base); \
+  bnez t1, fail; \
+1:
+
+  MISALIGNED_STORE_TEST(22,  sh,  s0, 1, 2)
+  MISALIGNED_STORE_TEST(23,  sw,  s0, 5, 4)
+  MISALIGNED_STORE_TEST(24,  sw,  s0, 10, 4)
+  MISALIGNED_STORE_TEST(25,  sw,  s0, 15, 4)
+
+#if __riscv_xlen == 64
+  MISALIGNED_STORE_TEST(26, sd, s0, 25, 8)
+  MISALIGNED_STORE_TEST(27, sd, s0, 34, 8)
+  MISALIGNED_STORE_TEST(28, sd, s0, 43, 8)
+  MISALIGNED_STORE_TEST(29, sd, s0, 52, 8)
+  MISALIGNED_STORE_TEST(30, sd, s0, 61, 8)
+  MISALIGNED_STORE_TEST(31, sd, s0, 70, 8)
+  MISALIGNED_STORE_TEST(32, sd, s0, 79, 8)
+#endif
+
+  TEST_PASSFAIL
+
+  .align 3
+  .global mtvec_handler
+mtvec_handler:
+  csrr t0, mcause
+  bne t0, s1, fail
+
+  csrr t0, mbadaddr
+  bne t0, t1, fail
+
+  lb t0, (t0)
+  beqz t0, fail
+
+  csrw mepc, t2
+  mret
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+data:
+  .align 3
+.word 0xaabbccdd
+.word 0x66778899
+.word 0x22334455
+.word 0xeeffee11
+.fill 0xff, 1, 80
+
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64mi/ma_fetch.S b/src/asmtest/isa/rv64mi/ma_fetch.S
new file mode 100644
index 0000000..cfcb90c
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/ma_fetch.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64S
+#define RVTEST_RV64S RVTEST_RV64M
+#define __MACHINE_MODE
+
+#include "../rv64si/ma_fetch.S"
diff --git a/src/asmtest/isa/rv64mi/mcsr.S b/src/asmtest/isa/rv64mi/mcsr.S
new file mode 100644
index 0000000..e0256e7
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/mcsr.S
@@ -0,0 +1,45 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mcsr.S
+#-----------------------------------------------------------------------------
+#
+# Test various M-mode CSRs.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  # Check that mcpuid reports the correct XLEN
+#if __riscv_xlen == 64
+  TEST_CASE(2, a0, 0x2, csrr a0, misa; srl a0, a0, 62)
+#else
+  TEST_CASE(2, a0, 0x1, csrr a0, misa; srl a0, a0, 30)
+#endif
+
+  # Check that mhartid reports 0
+  TEST_CASE(3, a0, 0x0, csrr a0, mhartid)
+
+  # Check that reading the following CSRs doesn't cause an exception
+  csrr a0, mimpid
+  csrr a0, marchid
+  csrr a0, mvendorid
+
+  # Check that writing hte following CSRs doesn't cause an exception
+  li t0, 0
+  csrs mtvec, t0
+  csrs mepc, t0
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64mi/sbreak.S b/src/asmtest/isa/rv64mi/sbreak.S
new file mode 100644
index 0000000..f36a9f8
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/sbreak.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64S
+#define RVTEST_RV64S RVTEST_RV64M
+#define __MACHINE_MODE
+
+#include "../rv64si/sbreak.S"
diff --git a/src/asmtest/isa/rv64mi/scall.S b/src/asmtest/isa/rv64mi/scall.S
new file mode 100644
index 0000000..22e9eb5
--- /dev/null
+++ b/src/asmtest/isa/rv64mi/scall.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64S
+#define RVTEST_RV64S RVTEST_RV64M
+#define __MACHINE_MODE
+
+#include "../rv64si/scall.S"
diff --git a/src/asmtest/isa/rv64samt/Makefrag b/src/asmtest/isa/rv64samt/Makefrag
new file mode 100644
index 0000000..5fb3710
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/Makefrag
@@ -0,0 +1,13 @@
+#=========================================================================
+# Makefrag for rv64samt tests
+#=========================================================================
+
+rv64sa_mt_tests = sysclone_d \
+                  sysfutex_d \
+                  sysfutex1_d \
+                  sysfutex2_d \
+                  sysfutex3_d \
+
+rv64samt_ps_tests = $(addprefix rv64samt-ps-, $(rv64sa_mt_tests))
+
+spike_tests += $(rv64samt_ps_tests)
diff --git a/src/asmtest/isa/rv64samt/sysclone_d.S b/src/asmtest/isa/rv64samt/sysclone_d.S
new file mode 100644
index 0000000..882751e
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/sysclone_d.S
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// sysclone_d tests basic functionalities of clone system call:
+//    - create a new thread
+//    - assign a new per-thread stack frame to the child thread
+//    - assign a new per-thread TLS to the child thread
+//
+// In addition to testing clone(), sysclone_d partially checks
+// functionalities of futex and exit system calls that are used to
+// facilitate thread exit and synchronization.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt_ecall.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define MAX_NUM_THREADS 20
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  li      a0, MAX_NUM_THREADS
+  call    _create_threads
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  beqz    a0, _fail                   // exit if there's no worker thread
+  call    _join
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _check
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _delete_threads
+
+  li      a0, SUCCESS
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed by child threads
+//------------------------------------------------------------------------
+_mt_test:
+  // get this thread's TID
+  li      a7, SYSCALL_GETTID
+  ecall
+
+  // store the TID to both stack and TLS of this thread
+  addi    sp, sp, -8
+  sd      a0, (sp)
+  sd      a0, (tp)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// _check:
+//    The master thread looks into the stack and TLS of each child thread
+//    and check if the child thread's TID was written in both places.
+//
+//    This function assumes the following structure in the calling thread's
+//    stack frame
+//
+//    | child_stack_ptr_0       |  << fp: frame pointer
+//    | child_tls_ptr_0         |
+//    | child_thread_id_0       |
+//    | saved_child_thread_id_0 |
+//    | child_stack_ptr_1       |
+//    | child_tls_ptr_1         |
+//    | child_thread_id_1       |
+//    | saved_child_thread_id_1 |
+//    | ...                     |  << sp: stack pointer
+//
+//    This function takes a number of threads to check in a0
+//------------------------------------------------------------------------
+
+_check:
+  mv      t0, a0          // get the number of threads
+  mv      s0, ra          // save return register
+  mv      s1, sp          // save stack pointer
+1:
+  ld      t1, (sp)        // get child_thread_saved_id
+
+  addi    sp, sp, 8
+  ld      t2, (sp)        // get child_thread_id
+  bnez    t2, _fail       // this child_thread_id should have been cleared
+
+  addi    sp, sp, 8
+  ld      t3, (sp)        // get child_tls_ptr
+  ld      t3, (t3)        // get the first value stored in child's TLS
+  bne     t1, t3, _fail   // child_tid should have been saved in the TLS
+
+  addi    sp, sp, 8
+  ld      t4, (sp)        // get child_stack_ptr
+  li      t5, MEM_SIZE
+  add     t4, t4, t5      // get the high address of child's stack
+  ld      t4, -8(t4)      // get the first value stored in child's stack
+  bne     t1, t4, _fail   // child_tid should have been saved in the stack
+
+  addi    sp, sp, 8
+
+  // decrement the number of threads to wait for
+  addi    t0, t0, -1
+  bnez    t0, 1b
+
+  // finish checking all threads
+  mv      ra, s0                  // restore return register
+  mv      sp, s1                  // restore stack pointer
+  ret
+
+_fail:
+  li        a0, FAILURE
+  RVTEST_CODE_END
+
+  .data
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64samt/sysfutex1_d.S b/src/asmtest/isa/rv64samt/sysfutex1_d.S
new file mode 100644
index 0000000..fa495c7
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/sysfutex1_d.S
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// sysfutex1_d tests basic functionalities of futex system call:
+//    - make some threads wait on a variable
+//    - wake up all threads waiting on a variable
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt_ecall.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define MAX_NUM_THREADS 20
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, call _master function, waits for all
+// threads to complete, deallocates threads and checks result
+//------------------------------------------------------------------------
+  li      a0, MAX_NUM_THREADS
+  call    _create_threads
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  beqz    a0, _fail                   // exit if there's no worker thread
+
+  call    _master_work
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _join
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _check
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _delete_threads
+
+  li      a0, SUCCESS
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// master_work function executed by the parent/master thread
+//
+//    - wake up all threads waiting on futex_X
+//------------------------------------------------------------------------
+_master_work:
+  mv    s0, ra                  // save return address
+  li    t0, 0                   // number of threads that have been waken
+  la    t1, n_worker_threads
+  ld    t1, (t1)
+
+1:
+  // futex(futex_X, FUTEX_WAKE_PRIVATE, n_worker_threads)
+  la    a0, futex_X
+  li    a1, FUTEX_WAKE_PRIVATE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  add   t0, t0, a0              // track the number of waken threads so far
+
+  // keep waking up until all threads are waken up
+  blt   t0, t1, 1b
+
+  // restore return address and return
+  mv    ra, s0
+  ret
+
+//------------------------------------------------------------------------
+// mt_test function executed by child threads
+//
+//    Wait on futex_X
+//------------------------------------------------------------------------
+_mt_test:
+  // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
+  la    a0, futex_X
+  li    a1, FUTEX_WAIT_PRIVATE
+  li    a2, 0                   // expected val of futex_X
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// _check:
+//    Each thread should do LOOP_COUNT iterations
+//------------------------------------------------------------------------
+
+_check:
+  ret
+
+_fail:
+  li        a0, FAILURE
+  RVTEST_CODE_END
+
+  .data
+
+futex_X:  .dword  0
+futex_Y:  .dword  0
+
+count_master:   .dword  0
+count_child:    .dword  0
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64samt/sysfutex2_d.S b/src/asmtest/isa/rv64samt/sysfutex2_d.S
new file mode 100644
index 0000000..1a12d42
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/sysfutex2_d.S
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// sysfutex_d tests FUTEX_WAKE_OP functionalities of futex system call:
+//    - make a thread wait on a variable
+//    - atomically wake up a thread waiting on a variable and perform
+//      a operation on a value
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt_ecall.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define NUM_THREADS 1
+#define LOOP_COUNT  1000
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, call _master function, waits for all
+// threads to complete, deallocates threads and checks result
+//------------------------------------------------------------------------
+  li      a0, NUM_THREADS
+  call    _create_threads
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  beqz    a0, _fail        // exit if there's no worker thread
+
+  call    _master_work
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _join
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _check
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _delete_threads
+
+  li      a0, SUCCESS
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// master_work function executed by the parent/master thread
+//
+//    Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
+//    loop. Also atomically modify futex_Z during the wake-up.
+//------------------------------------------------------------------------
+_master_work:
+  mv    s0, ra                  // save return address
+  li    t0, LOOP_COUNT
+  la    t1, count_master
+  la    t3, count_Z
+
+1:
+  // futex(futex_X, FUTEX_WAKE_OP, 1, val2, futex_Z, val3 )
+  la    a0, futex_X
+  li    a1, FUTEX_WAKE_OP
+  li    a2, 1                   // wake up at most 1 thread
+  li    a3, 0                   // should not perform the second wake up
+  la    a4, futex_Z             // add 1 to futex_Z each time
+  li    a5, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_LT, 0)
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // increment count_Z (should equals to futex_Z)
+  ld    t4, (t3)
+  addi  t4, t4, 1
+  sd    t4, (t3)
+
+  // keep waking up until at least one thread is waken up
+  beqz  a0, 1b
+
+  // increment count_master
+  ld    t2, (t1)
+  addi  t2, t2, 1
+  sd    t2, (t1)
+
+  // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
+  la    a0, futex_Y
+  li    a1, FUTEX_WAIT_PRIVATE
+  li    a2, 0                   // expected val of futex_Y
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // decrement t0
+  addi  t0, t0, -1
+  bnez  t0, 1b
+
+  // restore return address and return
+  mv    ra, s0
+  ret
+
+//------------------------------------------------------------------------
+// mt_test function executed by child threads
+//
+//    Wait on futex_X and then wake up threads waiting on futex_Y in a loop
+//------------------------------------------------------------------------
+_mt_test:
+  li    t0, LOOP_COUNT
+  la    t1, count_child
+
+1:
+  // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
+  la    a0, futex_X
+  li    a1, FUTEX_WAIT_PRIVATE
+  li    a2, 0                   // expected val of futex_X
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // increment count_child
+  ld    t2, (t1)
+  addi  t2, t2, 1
+  sd    t2, (t1)
+
+2:
+  // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
+  la    a0, futex_Y
+  li    a1, FUTEX_WAKE_PRIVATE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // keep waking up until at least one thread is waken up
+  beqz  a0, 2b
+
+  // decrement t0
+  addi  t0, t0, -1
+  bnez  t0, 1b
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// _check:
+//    Each thread should do LOOP_COUNT iterations
+//------------------------------------------------------------------------
+
+_check:
+  la    t0, count_master
+  la    t1, count_child
+  li    t2, LOOP_COUNT
+  la    t3, count_Z
+  la    t4, futex_Z
+
+  ld    t0, (t0)
+  bne   t0, t2, _fail
+
+  ld    t1, (t1)
+  bne   t1, t2, _fail
+
+  ld    t3, (t3)
+  ld    t4, (t4)
+  bne   t3, t4, _fail
+
+  ret
+
+_fail:
+  li        a0, FAILURE
+  RVTEST_CODE_END
+
+  .data
+
+futex_X:  .dword  0
+futex_Y:  .dword  0
+futex_Z:  .dword  0
+
+count_master:   .dword  0
+count_child:    .dword  0
+count_Z:        .dword  0
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64samt/sysfutex3_d.S b/src/asmtest/isa/rv64samt/sysfutex3_d.S
new file mode 100644
index 0000000..2797426
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/sysfutex3_d.S
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// sysfutex3_d tests FUTEX_CMP_REQUEUE functionalities of futex system
+// call:
+//    - make worker threads waiting on futex 1
+//    - wake up 1 thread, requeue the rest of the threads to futex 2
+//    - wake all threads waiting on futex 1 and futex 2
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt_ecall.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define NUM_THREADS 20
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, call _master function, waits for all
+// threads to complete, deallocates threads and checks result
+//------------------------------------------------------------------------
+  li      a0, NUM_THREADS
+  call    _create_threads
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  beqz    a0, _fail        // exit if there's no worker thread
+
+  call    _master_work
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _join
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _check
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _delete_threads
+
+  li      a0, SUCCESS
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// master_work function executed by the parent/master thread
+//------------------------------------------------------------------------
+_master_work:
+  mv    s0, ra                  // save return address
+  li    t0, 0                   // number of threads that have been waken
+  la    t1, n_worker_threads
+  ld    t1, (t1)
+
+1:
+  // futex(futex_X, FUTEX_CMP_REQUEUE, 1, INT_MAX, futex_Y, *futex_X)
+  la    a0, futex_X
+  li    a1, FUTEX_CMP_REQUEUE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a3, 1000                // practically is INT_MAX
+  la    a4, futex_Y             // move all other waiter to futex_Y
+  li    a5, 0
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // loop until wake up one thread, all other waiter are requeued to
+  // futex_Y
+  beqz  a0, 1b
+
+  addi  t0, t0, 1
+
+2:
+  // alternating between futex_X and futex_Y
+  // because there could be new threads added to futex_X's queue
+  // after our futex_requeue
+
+  // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
+  la    a0, futex_Y
+  li    a1, FUTEX_WAKE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  add   t0, t0, a0              // track the number of waken threads so far
+
+  // futex(futex_X, FUTEX_WAKE_PRIVATE, 0)
+  la    a0, futex_X
+  li    a1, FUTEX_WAKE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  add   t0, t0, a0              // track the number of waken threads so far
+
+  // keep waking up until all threads are waken up
+  blt   t0, t1, 2b
+
+  // restore return address and return
+  mv    ra, s0
+  ret
+
+//------------------------------------------------------------------------
+// mt_test function executed by child threads
+//
+//    Wait on futex_X
+//------------------------------------------------------------------------
+_mt_test:
+  // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
+  la    a0, futex_X
+  li    a1, FUTEX_WAIT
+  li    a2, 0                   // expected val of futex_X
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// _check:
+//    counter should equals to number of child threads
+//------------------------------------------------------------------------
+
+_check:
+  ret
+
+_fail:
+  li        a0, FAILURE
+  RVTEST_CODE_END
+
+  .data
+
+futex_X:  .dword  0
+futex_Y:  .dword  0
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64samt/sysfutex_d.S b/src/asmtest/isa/rv64samt/sysfutex_d.S
new file mode 100644
index 0000000..e684e60
--- /dev/null
+++ b/src/asmtest/isa/rv64samt/sysfutex_d.S
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// sysfutex_d tests basic functionalities of futex system call:
+//    - make a thread wait on a variable
+//    - wake up a thread waiting on a variable
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt_ecall.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define NUM_THREADS 1
+#define LOOP_COUNT  1000
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, call _master function, waits for all
+// threads to complete, deallocates threads and checks result
+//------------------------------------------------------------------------
+  li      a0, NUM_THREADS
+  call    _create_threads
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  beqz    a0, _fail        // exit if there's no worker thread
+  call    _master_work
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _join
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _check
+
+  la      t6, n_worker_threads
+  ld      a0, (t6)
+  call    _delete_threads
+
+  li      a0, SUCCESS
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// master_work function executed by the parent/master thread
+//
+//    Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
+//    loop.
+//------------------------------------------------------------------------
+_master_work:
+  mv    s0, ra                  // save return address
+  li    t0, LOOP_COUNT
+  la    t1, count_master
+
+1:
+  // futex(futex_X, FUTEX_WAKE_PRIVATE, 1)
+  la    a0, futex_X
+  li    a1, FUTEX_WAKE_PRIVATE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // keep waking up until at least one thread is waken up
+  beqz  a0, 1b
+
+  // increment count_master
+  ld    t2, (t1)
+  addi  t2, t2, 1
+  sd    t2, (t1)
+
+  // futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
+  la    a0, futex_Y
+  li    a1, FUTEX_WAIT_PRIVATE
+  li    a2, 0                   // expected val of futex_Y
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // decrement t0
+  addi  t0, t0, -1
+  bnez  t0, 1b
+
+  // restore return address and return
+  mv    ra, s0
+  ret
+
+//------------------------------------------------------------------------
+// mt_test function executed by child threads
+//
+//    Wait on futex_X and then wake up threads waiting on futex_Y in a loop
+//------------------------------------------------------------------------
+_mt_test:
+  li    t0, LOOP_COUNT
+  la    t1, count_child
+
+1:
+  // futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
+  la    a0, futex_X
+  li    a1, FUTEX_WAIT_PRIVATE
+  li    a2, 0                   // expected val of futex_X
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // increment count_child
+  ld    t2, (t1)
+  addi  t2, t2, 1
+  sd    t2, (t1)
+
+2:
+  // futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
+  la    a0, futex_Y
+  li    a1, FUTEX_WAKE_PRIVATE
+  li    a2, 1                   // wake up at most 1 thread
+  li    a7, SYSCALL_FUTEX
+  ecall
+
+  // keep waking up until at least one thread is waken up
+  beqz  a0, 2b
+
+  // decrement t0
+  addi  t0, t0, -1
+  bnez  t0, 1b
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// _check:
+//    Each thread should do LOOP_COUNT iterations
+//------------------------------------------------------------------------
+
+_check:
+  la    t0, count_master
+  la    t1, count_child
+  li    t2, LOOP_COUNT
+
+  ld    t0, (t0)
+  bne   t0, t2, _fail
+
+  ld    t1, (t1)
+  bne   t1, t2, _fail
+
+  ret
+
+_fail:
+  li        a0, FAILURE
+  RVTEST_CODE_END
+
+  .data
+
+futex_X:  .dword  0
+futex_Y:  .dword  0
+
+count_master:   .dword  0
+count_child:    .dword  0
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64si/Makefrag b/src/asmtest/isa/rv64si/Makefrag
new file mode 100644
index 0000000..f01a332
--- /dev/null
+++ b/src/asmtest/isa/rv64si/Makefrag
@@ -0,0 +1,16 @@
+#=======================================================================
+# Makefrag for rv64si tests
+#-----------------------------------------------------------------------
+
+rv64si_sc_tests = \
+	csr \
+	dirty \
+	icache-alias \
+	ma_fetch \
+	scall \
+	wfi \
+	sbreak \
+
+rv64si_p_tests = $(addprefix rv64si-p-, $(rv64si_sc_tests))
+
+spike_tests += $(rv64si_p_tests)
diff --git a/src/asmtest/isa/rv64si/csr.S b/src/asmtest/isa/rv64si/csr.S
new file mode 100644
index 0000000..09494ef
--- /dev/null
+++ b/src/asmtest/isa/rv64si/csr.S
@@ -0,0 +1,154 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# csr.S
+#-----------------------------------------------------------------------------
+#
+# Test CSRRx and CSRRxI instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64S
+RVTEST_CODE_BEGIN
+
+#ifdef __MACHINE_MODE
+  #define sscratch mscratch
+  #define sstatus mstatus
+  #define scause mcause
+  #define sepc mepc
+  #define sret mret
+  #define stvec_handler mtvec_handler
+  #undef SSTATUS_SPP
+  #define SSTATUS_SPP MSTATUS_MPP
+#endif
+
+  # For RV64, make sure UXL encodes RV64.  (UXL does not exist for RV32.)
+#if __riscv_xlen == 64
+  # If running in M mode, use mstatus.MPP to check existence of U mode.
+  # Otherwise, if in S mode, then U mode must exist and we don't need to check.
+#ifdef __MACHINE_MODE
+  li t0, MSTATUS_MPP
+  csrc mstatus, t0
+  csrr t1, mstatus
+  and t0, t0, t1
+  bnez t0, 1f
+#endif
+  # If U mode is present, UXL should be 2 (XLEN = 64-bit)
+  TEST_CASE(18, a0, SSTATUS_UXL & (SSTATUS_UXL << 1), csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
+#ifdef __MACHINE_MODE
+  j 2f
+1:
+  # If U mode is not present, UXL should be 0
+  TEST_CASE(19, a0, 0, csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
+2:
+#endif
+#endif
+
+  TEST_CASE(20, a0,         0, csrw sscratch, zero; csrr a0, sscratch);
+  TEST_CASE(21, a0,         0, csrrwi a0, sscratch, 0; csrrwi a0, sscratch, 0xF);
+
+  csrwi sscratch, 3
+  TEST_CASE( 2, a0,         3, csrr a0, sscratch);
+  TEST_CASE( 3, a1,         3, csrrci a1, sscratch, 1);
+  TEST_CASE( 4, a2,         2, csrrsi a2, sscratch, 4);
+  TEST_CASE( 5, a3,         6, csrrwi a3, sscratch, 2);
+  TEST_CASE( 6, a1,         2, li a0, 0xbad1dea; csrrw a1, sscratch, a0);
+  TEST_CASE( 7, a1, 0xbad1dea, li a0, 0x0001dea; csrrc a1, sscratch, a0);
+  TEST_CASE( 8, a1, 0xbad0000, li a0, 0x000beef; csrrs a1, sscratch, a0);
+  TEST_CASE( 9, a0, 0xbadbeef, li a0, 0xbad1dea; csrrw a0, sscratch, a0);
+  TEST_CASE(10, a0, 0xbad1dea, li a0, 0x0001dea; csrrc a0, sscratch, a0);
+  TEST_CASE(11, a0, 0xbad0000, li a0, 0x000beef; csrrs a0, sscratch, a0);
+  TEST_CASE(12, a0, 0xbadbeef, csrr a0, sscratch);
+
+#ifdef __MACHINE_MODE
+  # Is F extension present?
+  csrr a0, misa
+  andi a0, a0, (1 << ('F' - 'A'))
+  beqz a0, 1f
+  # If so, make sure FP stores have no effect when mstatus.FS is off.
+  li a1, MSTATUS_FS
+  csrs mstatus, a1
+#ifdef __riscv_flen
+  fmv.s.x f0, x0
+  csrc mstatus, a1
+  la a1, fsw_data
+  TEST_CASE(13, a0, 1, fsw f0, (a1); lw a0, (a1));
+#else
+  # Fail if this test is compiled without F but executed on a core with F.
+  TEST_CASE(13, zero, 1)
+#endif
+1:
+
+  # Figure out if 'U' is set in misa
+  csrr a0, misa   # a0 = csr(misa)
+  srli a0, a0, 20 # a0 = a0 >> 20
+  andi a0, a0, 1  # a0 = a0 & 1
+  beqz a0, finish # if no user mode, skip the rest of these checks
+#endif /* __MACHINE_MODE */
+
+  # jump to user land
+  li t0, SSTATUS_SPP
+  csrc sstatus, t0
+  la t0, 1f
+  csrw sepc, t0
+  sret
+  1:
+
+  # Make sure writing the cycle counter causes an exception.
+  # Don't run in supervisor, as we don't delegate illegal instruction traps.
+#ifdef __MACHINE_MODE
+  TEST_CASE(14, a0, 255, li a0, 255; csrrw a0, cycle, x0);
+#endif
+
+  # Make sure reading status in user mode causes an exception.
+  # Don't run in supervisor, as we don't delegate illegal instruction traps.
+#ifdef __MACHINE_MODE
+  TEST_CASE(15, a0, 255, li a0, 255; csrr a0, sstatus)
+#else
+  TEST_CASE(15, x0, 0, nop)
+#endif
+
+finish:
+  RVTEST_PASS
+
+  # We should only fall through to this if scall failed.
+  TEST_PASSFAIL
+
+  .align 2
+  .global stvec_handler
+stvec_handler:
+  # Trapping on tests 13-15 is good news.
+  # Note that since the test didn't complete, TESTNUM is smaller by 1.
+  li t0, 12
+  bltu TESTNUM, t0, 1f
+  li t0, 14
+  bleu TESTNUM, t0, privileged
+1:
+
+  # catch RVTEST_PASS and kick it up to M-mode
+  csrr t0, scause
+  li t1, CAUSE_USER_ECALL
+  bne t0, t1, fail
+  RVTEST_PASS
+
+privileged:
+  # Make sure scause indicates a lack of privilege.
+  csrr t0, scause
+  li t1, CAUSE_ILLEGAL_INSTRUCTION
+  bne t0, t1, fail
+  # Return to user mode, but skip the trapping instruction.
+  csrr t0, sepc
+  addi t0, t0, 4
+  csrw sepc, t0
+  sret
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+fsw_data: .word 1
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/dirty.S b/src/asmtest/isa/rv64si/dirty.S
new file mode 100644
index 0000000..15f3163
--- /dev/null
+++ b/src/asmtest/isa/rv64si/dirty.S
@@ -0,0 +1,133 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# dirty.S
+#-----------------------------------------------------------------------------
+#
+# Test VM referenced and dirty bits.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+#if (DRAM_BASE >> 30 << 30) != DRAM_BASE
+# error This test requires DRAM_BASE be SV39 superpage-aligned
+#endif 
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  # Turn on VM
+  li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+  la a1, page_table_1
+  srl a1, a1, RISCV_PGSHIFT
+  or a1, a1, a0
+  csrw sptbr, a1
+  sfence.vma
+
+  # Set up MPRV with MPP=S, so loads and stores use S-mode
+  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV
+  csrs mstatus, a1
+
+  # Try a faulting store to make sure dirty bit is not set
+  li TESTNUM, 2
+  li t2, 1
+  sw t2, dummy - DRAM_BASE, a0
+
+  # Set SUM=1 so user memory access is permitted
+  li TESTNUM, 3
+  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_SUM
+  csrs mstatus, a1
+
+  # Make sure SUM=1 works
+  lw t0, dummy - DRAM_BASE
+  bnez t0, die
+
+  # Try a non-faulting store to make sure dirty bit is set
+  sw t2, dummy - DRAM_BASE, a0
+
+  # Make sure it succeeded
+  lw t0, dummy - DRAM_BASE
+  bne t0, t2, die
+
+  # Leave MPRV
+  li t0, MSTATUS_MPRV
+  csrc mstatus, t0
+
+  # Make sure D bit is set
+  lw t0, page_table_1
+  li a0, PTE_A | PTE_D
+  and t0, t0, a0
+  bne t0, a0, die
+
+  # Enter MPRV again
+  li t0, MSTATUS_MPRV
+  csrs mstatus, t0
+
+  # Make sure that superpage entries trap when PPN LSBs are set.
+  li TESTNUM, 4
+  lw a0, page_table_1 - DRAM_BASE
+  or a0, a0, 1 << PTE_PPN_SHIFT
+  sw a0, page_table_1 - DRAM_BASE, t0
+  sfence.vma
+  sw a0, page_table_1 - DRAM_BASE, t0
+  j die
+  
+  RVTEST_PASS
+
+  TEST_PASSFAIL
+
+  .align 2
+  .global mtvec_handler
+mtvec_handler:
+  csrr t0, mcause
+  add t0, t0, -CAUSE_STORE_PAGE_FAULT
+  bnez t0, die
+
+  li t1, 2
+  bne TESTNUM, t1, 1f
+  # Make sure D bit is clear
+  lw t0, page_table_1
+  and t1, t0, PTE_D
+  bnez t1, die
+skip:
+  csrr t0, mepc
+  add t0, t0, 4
+  csrw mepc, t0
+  mret
+
+1:
+  li t1, 3
+  bne TESTNUM, t1, 1f
+  # The implementation doesn't appear to set D bits in HW.
+  # Make sure the D bit really is clear.
+  lw t0, page_table_1
+  and t1, t0, PTE_D
+  bnez t1, die
+  # Set the D bit.
+  or t0, t0, PTE_D
+  sw t0, page_table_1, t1
+  sfence.vma
+  mret
+
+1:
+  li t1, 4
+  bne TESTNUM, t1, 1f
+  j pass
+
+1:
+die:
+  RVTEST_FAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+.align 12
+page_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A
+dummy: .dword 0
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/icache-alias.S b/src/asmtest/isa/rv64si/icache-alias.S
new file mode 100644
index 0000000..dbc934e
--- /dev/null
+++ b/src/asmtest/isa/rv64si/icache-alias.S
@@ -0,0 +1,141 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# icache-alias.S
+#-----------------------------------------------------------------------------
+#
+# Test that instruction memory appears to be physically addressed, i.e.,
+# that disagreements in the low-order VPN and PPN bits don't cause the
+# wrong instruction to be fetched.  It also tests that changing a page
+# mapping takes effect without executing FENCE.I.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+  li TESTNUM, 2
+
+  # Set up intermediate page tables
+
+  la t0, page_table_3
+  srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+  ori t0, t0, PTE_V
+  sd t0, page_table_2, t1
+
+  la t0, page_table_2
+  srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+  ori t0, t0, PTE_V
+  sd t0, page_table_1, t1
+
+  # Set up leaf mappings where va[12] != pa[12]
+
+  la t0, code_page_1
+  srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+  ori t0, t0, PTE_V | PTE_X | PTE_A
+  sd t0, page_table_3 + 8, t1
+
+  la t0, code_page_2
+  srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+  ori t0, t0, PTE_V | PTE_X | PTE_A
+  sd t0, page_table_3 + 0, t1
+
+  # Turn on VM
+
+  li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+  la a1, page_table_1
+  srl a1, a1, RISCV_PGSHIFT
+  or a1, a1, a0
+  csrw sptbr, a1
+  sfence.vma
+
+  # Enter supervisor mode and make sure correct page is accessed
+
+  la a2, 1f
+  csrwi mepc, 0
+  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S)
+  csrs mstatus, a1
+  mret
+
+1:
+  li TESTNUM, 2
+  addi a0, a0, -321
+  bnez a0, fail
+
+  li TESTNUM, 3
+  la a2, 1f
+  li t0, RISCV_PGSIZE
+  csrw mepc, t0
+  mret
+
+1:
+  addi a0, a0, -123
+  bnez a0, fail
+
+  li TESTNUM, 4
+  la a2, 1f
+  csrwi mepc, 0
+  mret
+
+  .align 2
+1:
+  addi a0, a0, -321
+  bnez a0, fail
+
+  li TESTNUM, 5
+
+  # Change mapping and try again
+
+  la t0, code_page_1
+  srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+  ori t0, t0, PTE_V | PTE_X | PTE_A
+  sd t0, page_table_3 + 0, t1
+  sfence.vma
+
+  la a2, 1f
+  csrwi mepc, 0
+  mret
+
+  .align 2
+1:
+  addi a0, a0, -123
+  bnez a0, fail
+  
+  RVTEST_PASS
+
+  TEST_PASSFAIL
+
+  .align 2
+  .global mtvec_handler
+mtvec_handler:
+  csrr t0, mcause
+  add t0, t0, -CAUSE_STORE_PAGE_FAULT
+  bnez t0, fail
+
+  jr a2
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+.align 12
+page_table_1: .dword 0
+.align 12
+page_table_2: .dword 0
+.align 12
+page_table_3: .dword 0
+.align 13
+code_page_1:
+  li a0, 123
+  sw x0, (x0)
+.align 12
+code_page_2:
+  li a0, 321
+  sw x0, (x0)
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/ma_fetch.S b/src/asmtest/isa/rv64si/ma_fetch.S
new file mode 100644
index 0000000..7d2adec
--- /dev/null
+++ b/src/asmtest/isa/rv64si/ma_fetch.S
@@ -0,0 +1,204 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ma_fetch.S
+#-----------------------------------------------------------------------------
+#
+# Test misaligned fetch trap.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64S
+RVTEST_CODE_BEGIN
+
+#ifdef __MACHINE_MODE
+  #define sscratch mscratch
+  #define sstatus mstatus
+  #define scause mcause
+  #define sbadaddr mbadaddr
+  #define sepc mepc
+  #define sret mret
+  #define stvec_handler mtvec_handler
+#endif
+
+  .align 2
+  .option norvc
+
+  # Without RVC, the jalr should trap, and the handler will skip ahead.
+  # With RVC, the jalr should not trap, and "j fail" should get skipped.
+  li TESTNUM, 2
+  li t1, 0
+  la t0, 1f
+  jalr t1, t0, 2
+1:
+  .option rvc
+  c.j 1f
+  c.j 2f
+  .option norvc
+1:
+  j fail
+2:
+
+  // This test should pass, since JALR ignores the target LSB
+  li TESTNUM, 3
+  la t0, 1f
+  jalr t1, t0, 1
+1:
+  j 1f
+  j fail
+1:
+
+  li TESTNUM, 4
+  li t1, 0
+  la t0, 1f
+  jalr t1, t0, 3
+1:
+  .option rvc
+  c.j 1f
+  c.j 2f
+  .option norvc
+1:
+  j fail
+2:
+
+  # Like test 2, but with jal instead of jalr.
+  li TESTNUM, 5
+  li t1, 0
+  la t0, 1f
+  jal t1, 2f
+1:
+  .option rvc
+  c.j 1f
+2:
+  c.j 2f
+  .option norvc
+1:
+  j fail
+2:
+
+  # Like test 2, but with a taken branch instead of jalr.
+  li TESTNUM, 6
+  li t1, 0
+  la t0, 1f
+  beqz x0, 2f
+1:
+  .option rvc
+  c.j 1f
+2:
+  c.j 2f
+  .option norvc
+1:
+  j fail
+2:
+
+  # Not-taken branches should not trap, even without RVC.
+  li TESTNUM, 7
+  bnez x0, 1f
+  j 2f
+  .option rvc
+  c.j 1f
+1:
+  c.j 1f
+  .option norvc
+1:
+  j fail
+2:
+
+#ifdef __MACHINE_MODE
+  # RVC cannot be disabled if doing so would cause a misaligned instruction
+  # exception on the next instruction fetch. (This test assumes no other
+  # extensions that support misalignment are present.)
+  li TESTNUM, 8
+  csrr t2, misa
+  andi t2, t2, 1 << ('c' - 'a')
+  beqz t2, 2f
+
+  .option rvc
+  c.nop
+  csrci misa, 1 << ('c' - 'a')
+1:
+  c.nop
+  .option norvc
+
+  csrr t2, misa
+  andi t2, t2, 1 << ('c' - 'a')
+  beqz t2, fail
+
+  # When RVC is disabled, mret to a misaligned mepc should succeed,
+  # masking off mepc[1].
+  la t0, 1f
+  addi t0, t0, -2
+  csrw mepc, t0
+
+  # Try to disable RVC; if it can't be disabled, skip the test.
+  csrci misa, 1 << ('c' - 'a')
+  csrr t2, misa
+  andi t2, t2, 1 << ('c' - 'a')
+  bnez t2, 2f
+
+  li t2, MSTATUS_MPP
+  csrs mstatus, t2
+  mret
+
+  # mret should transfer control to this branch.  Otherwise, it will
+  # transfer control two bytes into the branch, which happens to be the
+  # illegal instruction c.unimp.
+  beqz x0, 1f
+1:
+  csrsi misa, 1 << ('c' - 'a')
+2:
+#endif
+
+  j pass
+
+  TEST_PASSFAIL
+
+  .align 2
+  .global stvec_handler
+stvec_handler:
+  # tests 2, 4, 5, 6, and 8 should trap
+  li a0, 2
+  beq TESTNUM, a0, 1f
+  li a0, 4
+  beq TESTNUM, a0, 1f
+  li a0, 5
+  beq TESTNUM, a0, 1f
+  li a0, 6
+  beq TESTNUM, a0, 1f
+  j fail
+1:
+
+  # verify that return address was not written
+  bnez t1, fail
+
+  # verify trap cause
+  li a1, CAUSE_MISALIGNED_FETCH
+  csrr a0, scause
+  bne a0, a1, fail
+
+  # verify that epc == &jalr (== t0 - 4)
+  csrr a1, sepc
+  addi a1, a1, 4
+  bne t0, a1, fail
+
+  # verify that badaddr == 0 or badaddr == t0+2.
+  csrr a0, sbadaddr
+  beqz a0, 1f
+  addi a0, a0, -2
+  bne a0, t0, fail
+1:
+
+  addi a1, a1, 12
+  csrw sepc, a1
+  sret
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/sbreak.S b/src/asmtest/isa/rv64si/sbreak.S
new file mode 100644
index 0000000..31efff8
--- /dev/null
+++ b/src/asmtest/isa/rv64si/sbreak.S
@@ -0,0 +1,51 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# scall.S
+#-----------------------------------------------------------------------------
+#
+# Test syscall trap.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64S
+RVTEST_CODE_BEGIN
+
+#ifdef __MACHINE_MODE
+  #define sscratch mscratch
+  #define sstatus mstatus
+  #define scause mcause
+  #define sepc mepc
+  #define sret mret
+  #define stvec_handler mtvec_handler
+#endif
+
+  li TESTNUM, 2
+
+do_break:
+  sbreak
+  j fail
+
+  TEST_PASSFAIL
+
+  .align 2
+  .global stvec_handler
+stvec_handler:
+  li t1, CAUSE_BREAKPOINT
+  csrr t0, scause
+  bne t0, t1, fail
+  la t1, do_break
+  csrr t0, sepc
+  bne t0, t1, fail
+  j pass
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/scall.S b/src/asmtest/isa/rv64si/scall.S
new file mode 100644
index 0000000..9956e03
--- /dev/null
+++ b/src/asmtest/isa/rv64si/scall.S
@@ -0,0 +1,83 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# scall.S
+#-----------------------------------------------------------------------------
+#
+# Test syscall trap.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64S
+RVTEST_CODE_BEGIN
+
+#ifdef __MACHINE_MODE
+  #define sscratch mscratch
+  #define sstatus mstatus
+  #define scause mcause
+  #define sepc mepc
+  #define sret mret
+  #define stvec_handler mtvec_handler
+  #undef SSTATUS_SPP
+  #define SSTATUS_SPP MSTATUS_MPP
+#endif
+
+  li TESTNUM, 2
+
+  # This is the expected trap code.
+  li t1, CAUSE_USER_ECALL
+
+#ifdef __MACHINE_MODE
+  # If running in M mode, use mstatus.MPP to check existence of U mode.
+  # Otherwise, if in S mode, then U mode must exist and we don't need to check.
+  li t0, MSTATUS_MPP
+  csrc mstatus, t0
+  csrr t2, mstatus
+  and t0, t0, t2
+  beqz t0, 1f
+
+  # If U mode doesn't exist, mcause should indicate ECALL from M mode.
+  li t1, CAUSE_MACHINE_ECALL
+#endif
+
+1:
+  li t0, SSTATUS_SPP
+  csrc sstatus, t0
+  la t0, 1f
+  csrw sepc, t0
+  sret
+1:
+
+  li TESTNUM, 1
+do_scall:
+  scall
+  j fail
+
+  TEST_PASSFAIL
+
+# Depending on the test environment, the M-mode version of this test might
+# not actually invoke the following handler.  Instead, the usual ECALL
+# handler in the test environment might detect the CAUSE_USER_ECALL or
+# CAUSE_MACHINE_ECALL exception and mark the test as having passed.
+# Either way, we'll get the coverage we desire: such a handler must check
+# both mcause and TESTNUM, just like the following handler.
+  .align 2
+  .global stvec_handler
+stvec_handler:
+  csrr t0, scause
+  bne t0, t1, fail
+  la t2, do_scall
+  csrr t0, sepc
+  bne t0, t2, fail
+  j pass
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64si/wfi.S b/src/asmtest/isa/rv64si/wfi.S
new file mode 100644
index 0000000..0302034
--- /dev/null
+++ b/src/asmtest/isa/rv64si/wfi.S
@@ -0,0 +1,33 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# wfi.S
+#-----------------------------------------------------------------------------
+#
+# Test wait-for-interrupt instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64S
+RVTEST_CODE_BEGIN
+
+  # Make sure wfi doesn't halt the hart, even if interrupts are disabled
+  csrc sstatus, SSTATUS_SIE
+  csrs sie, SIP_SSIP
+  csrs sip, SIP_SSIP
+  wfi
+
+  RVTEST_PASS
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ua/Makefrag b/src/asmtest/isa/rv64ua/Makefrag
new file mode 100644
index 0000000..5019226
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/Makefrag
@@ -0,0 +1,14 @@
+#=======================================================================
+# Makefrag for rv64ua tests
+#-----------------------------------------------------------------------
+
+rv64ua_sc_tests = \
+	amoadd_d amoand_d amomax_d amomaxu_d amomin_d amominu_d amoor_d amoxor_d amoswap_d \
+	amoadd_w amoand_w amomax_w amomaxu_w amomin_w amominu_w amoor_w amoxor_w amoswap_w \
+	lrsc \
+
+rv64ua_p_tests = $(addprefix rv64ua-p-, $(rv64ua_sc_tests))
+rv64ua_v_tests = $(addprefix rv64ua-v-, $(rv64ua_sc_tests))
+rv64ua_ps_tests = $(addprefix rv64ua-ps-, $(rv64ua_sc_tests))
+
+spike_tests += $(rv64ua_p_tests) $(rv64ua_v_tests)
diff --git a/src/asmtest/isa/rv64ua/amoadd_d.S b/src/asmtest/isa/rv64ua/amoadd_d.S
new file mode 100644
index 0000000..05b2f38
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoadd_d.S
@@ -0,0 +1,47 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoadd_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoadd.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amoadd.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff7ffff800, ld a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xffffffff7ffff800, \
+    amoadd.d a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffff7ffff000, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoadd_w.S b/src/asmtest/isa/rv64ua/amoadd_w.S
new file mode 100644
index 0000000..d076d45
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoadd_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoadd_w.S
+#-----------------------------------------------------------------------------
+#
+# Test amoadd.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amoadd.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0x000000007ffff800, lw a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0x000000007ffff800, \
+    li  a1, 0xffffffff80000000; \
+    amoadd.w a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xfffffffffffff800, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+    .bss
+    .align 3
+amo_operand:
+    .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoand_d.S b/src/asmtest/isa/rv64ua/amoand_d.S
new file mode 100644
index 0000000..c1148c0
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoand_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoand_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoand.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amoand.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xffffffff80000000, \
+    li  a1, 0x0000000080000000; \
+    amoand.d a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0x0000000080000000, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoand_w.S b/src/asmtest/isa/rv64ua/amoand_w.S
new file mode 100644
index 0000000..7fe3bd0
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoand_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoand.w.S
+#-----------------------------------------------------------------------------
+#
+# Test amoand.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amoand.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xffffffff80000000, \
+    li  a1, 0x0000000080000000; \
+    amoand.w a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomax_d.S b/src/asmtest/isa/rv64ua/amomax_d.S
new file mode 100644
index 0000000..b7f8703
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomax_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomax_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomax.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amomax.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 1; \
+    sd x0, 0(a3); \
+    amomax.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 1, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomax_w.S b/src/asmtest/isa/rv64ua/amomax_w.S
new file mode 100644
index 0000000..f986205
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomax_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomax_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomax.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amomax.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 1; \
+    sw x0, 0(a3); \
+    amomax.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 1, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomaxu_d.S b/src/asmtest/isa/rv64ua/amomaxu_d.S
new file mode 100644
index 0000000..227ac4c
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomaxu_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomaxu_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomaxu.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amomaxu.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sd x0, 0(a3); \
+    amomaxu.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffffffffffff, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomaxu_w.S b/src/asmtest/isa/rv64ua/amomaxu_w.S
new file mode 100644
index 0000000..eb27d07
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomaxu_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomaxu_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomaxu.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amomaxu.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sw x0, 0(a3); \
+    amomaxu.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomin_d.S b/src/asmtest/isa/rv64ua/amomin_d.S
new file mode 100644
index 0000000..ee6bbf3
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomin_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomin_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomin.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amomin.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sd x0, 0(a3); \
+    amomin.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffffffffffff, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amomin_w.S b/src/asmtest/isa/rv64ua/amomin_w.S
new file mode 100644
index 0000000..1337d2c
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amomin_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amomin_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amomin.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amomin.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sw x0, 0(a3); \
+    amomin.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amominu_d.S b/src/asmtest/isa/rv64ua/amominu_d.S
new file mode 100644
index 0000000..08bfb5b
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amominu_d.S
@@ -0,0 +1,49 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amominu_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amominu.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amominu.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sd x0, 0(a3); \
+    amominu.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
+  
diff --git a/src/asmtest/isa/rv64ua/amominu_w.S b/src/asmtest/isa/rv64ua/amominu_w.S
new file mode 100644
index 0000000..f45f856
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amominu_w.S
@@ -0,0 +1,49 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amominu_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amominu.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amominu.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
+
+  TEST_CASE(4, a4, 0, \
+    li a1, 0xffffffffffffffff; \
+    sw x0, 0(a3); \
+    amominu.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
+  
diff --git a/src/asmtest/isa/rv64ua/amoor_d.S b/src/asmtest/isa/rv64ua/amoor_d.S
new file mode 100644
index 0000000..6f71495
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoor_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoor_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoor.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amoor.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xfffffffffffff800, \
+    li  a1, 1; \
+    amoor.d a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xfffffffffffff801, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoor_w.S b/src/asmtest/isa/rv64ua/amoor_w.S
new file mode 100644
index 0000000..e64b8c2
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoor_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoor.w.S
+#-----------------------------------------------------------------------------
+#
+# Test amoor.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amoor.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xfffffffffffff800, \
+    li  a1, 1; \
+    amoor.w a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xfffffffffffff801, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoswap_d.S b/src/asmtest/isa/rv64ua/amoswap_d.S
new file mode 100644
index 0000000..6b07d74
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoswap_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoswap.d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoswap.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amoswap.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xfffffffffffff800, \
+    li  a1, 0x0000000080000000; \
+    amoswap.d a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0x0000000080000000, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoswap_w.S b/src/asmtest/isa/rv64ua/amoswap_w.S
new file mode 100644
index 0000000..c4276dc
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoswap_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoswap_w.S
+#-----------------------------------------------------------------------------
+#
+# Test amoswap.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amoswap.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0xfffffffffffff800, \
+    li  a1, 0x0000000080000000; \
+    amoswap.w a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoxor_d.S b/src/asmtest/isa/rv64ua/amoxor_d.S
new file mode 100644
index 0000000..8305434
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoxor_d.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoxor_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoxor.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sd a0, 0(a3); \
+    amoxor.d	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0x000000007ffff800, ld a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0x000000007ffff800, \
+    li  a1, 1; \
+    amoxor.d a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0x000000007ffff801, ld a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/amoxor_w.S b/src/asmtest/isa/rv64ua/amoxor_w.S
new file mode 100644
index 0000000..1b6fc48
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/amoxor_w.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoxor_w.S
+#-----------------------------------------------------------------------------
+#
+# Test amoxor.w instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a4, 0xffffffff80000000, \
+    li a0, 0xffffffff80000000; \
+    li a1, 0xfffffffffffff800; \
+    la a3, amo_operand; \
+    sw a0, 0(a3); \
+    amoxor.w	a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(3, a5, 0x7ffff800, lw a5, 0(a3))
+
+  # try again after a cache miss
+  TEST_CASE(4, a4, 0x7ffff800, \
+    li  a1, 0xc0000001; \
+    amoxor.w a4, a1, 0(a3); \
+  )
+
+  TEST_CASE(5, a5, 0xffffffffbffff801, lw a5, 0(a3))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
+
+  .bss
+  .align 3
+amo_operand:
+  .dword 0
diff --git a/src/asmtest/isa/rv64ua/lrsc.S b/src/asmtest/isa/rv64ua/lrsc.S
new file mode 100644
index 0000000..c7589d7
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/lrsc.S
@@ -0,0 +1,102 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lrsr.S
+#-----------------------------------------------------------------------------
+#
+# Test LR/SC instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+# get a unique core id
+la a0, coreid
+li a1, 1
+amoadd.w a2, a1, (a0)
+
+# for now, only run this on core 0
+1:li a3, 1
+bgeu a2, a3, 1b
+
+1: lw a1, (a0)
+bltu a1, a3, 1b
+
+# make sure that sc without a reservation fails.
+TEST_CASE( 2, a4, 1, \
+  la a0, foo; \
+  li a5, 0xdeadbeef; \
+  sc.w a4, a5, (a0); \
+)
+
+# make sure the failing sc did not commit into memory
+TEST_CASE( 3, a4, 0, \
+  lw a4, foo; \
+)
+
+# make sure that sc with the wrong reservation fails.
+# TODO is this actually mandatory behavior?
+TEST_CASE( 4, a4, 1, \
+  la a0, foo; \
+  la a1, fooTest3; \
+  lr.w a1, (a1); \
+  sc.w a4, a1, (a0); \
+)
+
+#define LOG_ITERATIONS 10
+
+# have each core add its coreid+1 to foo 1024 times
+la a0, foo
+li a1, 1<<LOG_ITERATIONS
+addi a2, a2, 1
+1: lr.w a4, (a0)
+add a4, a4, a2
+sc.w a4, a4, (a0)
+bnez a4, 1b
+add a1, a1, -1
+bnez a1, 1b
+
+# wait for all cores to finish
+la a0, barrier
+li a1, 1
+amoadd.w x0, a1, (a0)
+1: lw a1, (a0)
+blt a1, a3, 1b
+fence
+
+# expected result is 512*ncores*(ncores+1)
+TEST_CASE( 5, a0, 0, \
+  lw a0, foo; \
+  slli a1, a3, LOG_ITERATIONS-1; \
+1:sub a0, a0, a1; \
+  addi a3, a3, -1; \
+  bgez a3, 1b
+)
+
+# make sure that sc-after-successful-sc fails.
+TEST_CASE( 6, a1, 1, \
+  la a0, foo; \
+1:lr.w a1, (a0); \
+  sc.w a1, x0, (a0); \
+  bnez a1, 1b; \
+  sc.w a1, x0, (a0)
+)
+
+TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+coreid: .word 0
+barrier: .word 0
+foo: .word 0
+.skip 1024
+fooTest3: .word 0
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ua/test.S b/src/asmtest/isa/rv64ua/test.S
new file mode 100644
index 0000000..9e6ab68
--- /dev/null
+++ b/src/asmtest/isa/rv64ua/test.S
@@ -0,0 +1,25 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# amoadd_d.S
+#-----------------------------------------------------------------------------
+#
+# Test amoadd.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+la        a0, shared_var
+amoadd.w  t0, t1, 0(a0)
+lr.w      t2, 0(a0)
+//sc.w      t0, t1, 0(a0)
+
+RVTEST_CODE_END
+
+  .data
+shared_var:     .dword    0
+non_shared_var: .dword    0
diff --git a/src/asmtest/isa/rv64uamt/Makefrag b/src/asmtest/isa/rv64uamt/Makefrag
new file mode 100644
index 0000000..56a189f
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/Makefrag
@@ -0,0 +1,10 @@
+#=======================================================================
+# Makefrag for rv64ua_mt tests
+#-----------------------------------------------------------------------
+
+rv64ua_mt_tests = amoadd_d amoswap_d amoxor_d amoand_d \
+                  amoor_d amomin_d amomax_d amominu_d amomaxu_d lrsc_d \
+
+rv64uamt_ps_tests = $(addprefix rv64uamt-ps-, $(rv64ua_mt_tests))
+
+spike_tests += $(rv64uamt_ps_tests)
diff --git a/src/asmtest/isa/rv64uamt/amoadd_d.S b/src/asmtest/isa/rv64uamt/amoadd_d.S
new file mode 100644
index 0000000..1efb139
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amoadd_d.S
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amoadd_d instruction in multi-threading system.
+// Each thread increments a globally shared variable LOOP_COUNT times.
+// Once a thread completes, it signals its completition by atomically
+// incrementing a barrier variable.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define LOOP_COUNT  1000
+#define RESULT      LOOP_COUNT * NUM_THREADS
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  li        t0, 1               // one operand of amoadd_w
+  li        t1, LOOP_COUNT      // loop count
+  la        a0, shared_var
+1:
+  amoadd.d  zero, t0, (a0)
+  addi      t1, t1, -1
+  bnez      t1, 1b
+
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
diff --git a/src/asmtest/isa/rv64uamt/amoand_d.S b/src/asmtest/isa/rv64uamt/amoand_d.S
new file mode 100644
index 0000000..74bc316
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amoand_d.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amoand_w instruction in multi-threading system.
+// All threads execute an amoxor_w instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0x000000008E003441
+
+//------------------------------------------------------------------------
+// Reinitialize shared_var to 0xffffffffffffffff
+//------------------------------------------------------------------------
+  la  a0, shared_var
+  li  t0, 0xffffffffffffffff
+  sd  t0, (a0)
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amoand.d  zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amomax_d.S b/src/asmtest/isa/rv64uamt/amomax_d.S
new file mode 100644
index 0000000..4d74959
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amomax_d.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amomax_d instruction in multi-threading system.
+// All threads execute an amomax_w instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0x12343eeaaf423451
+
+//------------------------------------------------------------------------
+// Reinitialize shared_var to 0x8000000000000000
+//------------------------------------------------------------------------
+  la  a0, shared_var
+  li  t0, 0x8000000000000000
+  sd  t0, (a0)
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amomax.d  zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amomaxu_d.S b/src/asmtest/isa/rv64uamt/amomaxu_d.S
new file mode 100644
index 0000000..488f422
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amomaxu_d.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amomax_d instruction in multi-threading system.
+// All threads execute an amomax_w instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0xdeadbeefdeadbeef
+
+//------------------------------------------------------------------------
+// Reinitialize shared_var to 0x0000000000000000
+//------------------------------------------------------------------------
+  la  a0, shared_var
+  li  t0, 0x0000000000000000
+  sd  t0, (a0)
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amomaxu.d zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amomin_d.S b/src/asmtest/isa/rv64uamt/amomin_d.S
new file mode 100644
index 0000000..2d57a7c
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amomin_d.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amomin_d instruction in multi-threading system.
+// All threads execute an amomin_d instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0xDEADBEEFDEADBEEF
+
+//------------------------------------------------------------------------
+// Reinitialize shared_var to 0x7fffffffffffffff
+//------------------------------------------------------------------------
+  la  a0, shared_var
+  li  t0, 0x7fffffffffffffff
+  sd  t0, (a0)
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amomin.d  zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amominu_d.S b/src/asmtest/isa/rv64uamt/amominu_d.S
new file mode 100644
index 0000000..34e1e2f
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amominu_d.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amominu_d instruction in multi-threading system.
+// All threads execute an amominu_d instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0x00000000deadbeef
+
+//------------------------------------------------------------------------
+// Reinitialize shared_var to 0xffffffffffffffff
+//------------------------------------------------------------------------
+  la  a0, shared_var
+  li  t0, 0xffffffffffffffff
+  sd  t0, (a0)
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amominu.d zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amoor_d.S b/src/asmtest/isa/rv64uamt/amoor_d.S
new file mode 100644
index 0000000..14ba63c
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amoor_d.S
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amoor_d instruction in multi-threading system.
+// All threads execute an amoor_w instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0xDEBDBEEFFFEFBEFF
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amoor.d   zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/amoswap_d.S b/src/asmtest/isa/rv64uamt/amoswap_d.S
new file mode 100644
index 0000000..48d3aa3
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amoswap_d.S
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amoswap.d instruction in multi-threading system.
+// All threads execute a critical section LOOP_COUNT times. A thread
+// gets into a critical section by acquiring a lock variable (i.e.,
+// shared_var) and checking return value.
+// 0 means the lock is not being locked. Each thread increments
+// a variable (i.e., var) inside the critical section and releases the
+// lock by swapping back 0 to the lock variable.
+// The master thread (i.e., thread 0) waits for all threads to complete
+// and compare the var's value to the expected result.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define LOOP_COUNT  1000
+#define RESULT      NUM_THREADS * LOOP_COUNT
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  li        t0, 1               // initialize the swap value (1-locked)
+  li        t1, LOOP_COUNT
+  la        t2, var             // load the var's address
+  la        a0, shared_var
+
+1:
+  amoswap.d.aq  s2, t0, (a0)    // try to swap t0 with the lock
+  bnez          s2, 1b          // retry if the lock is being held
+
+  lw            t3, (t2)        // load the var's value
+  addi          t3, t3, 1       // add 1 to the value
+  sw            t3, (t2)        // store the new value to var
+
+  amoswap.d.rl  zero, zero, (a0)// release the lock by swapping back 0
+
+  addi          t1, t1, -1      // decrement the loop_count
+  bnez          t1, 1b          // repeat if not done yet
+
+  la            a0, barrier
+  amoadd.d      zero, t0, (a0)  // signal this thread's completion
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+var: .dword   0
diff --git a/src/asmtest/isa/rv64uamt/amoxor_d.S b/src/asmtest/isa/rv64uamt/amoxor_d.S
new file mode 100644
index 0000000..3b975c9
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/amoxor_d.S
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests amoxor_d instruction in multi-threading system.
+// All threads execute an amoxor_w instruction.
+// Master thread (i.e., thread 0) waits for all threads to complete by
+// spinning on the barrier variable until all threads update the variable.
+// Then, the master thread checks the shared variable's value.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define RESULT      0xCC998005AF423451
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  la        a0, shared_var
+  la        t0, array_index
+  li        t1, 8
+  amoadd.d  t1, t1, (t0)        // get my array_index
+
+  la        t0, array
+  add       t0, t0, t1
+  ld        t0, (t0)            // get array[array_index]
+
+  amoxor.d  zero, t0, (a0)
+
+  li        t0, 1
+  la        a0, barrier
+  amoadd.d  zero, t0, (a0)
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, shared_var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+array_index:    .dword    0;
diff --git a/src/asmtest/isa/rv64uamt/lrsc_d.S b/src/asmtest/isa/rv64uamt/lrsc_d.S
new file mode 100644
index 0000000..ff8d387
--- /dev/null
+++ b/src/asmtest/isa/rv64uamt/lrsc_d.S
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018, Cornell University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of Cornell University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//------------------------------------------------------------------------
+// This code tests lr.d and sc.d instructions in multi-threading system.
+// All threads execute a critical section LOOP_COUNT times. A thread
+// gets into a critical section by acquiring a lock variable (i.e.,
+// shared_var) and checking return value.
+// 0 means the lock is not being locked. Each thread increments
+// a variable (i.e., var) inside the critical section and releases the
+// lock by swapping back 0 to the lock variable.
+// The master thread (i.e., thread 0) waits for all threads to complete
+// and compare the var's value to the expected result.
+//------------------------------------------------------------------------
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "test_macros_mt.h"
+
+  RVTEST_RV64U
+  RVTEST_CODE_BEGIN
+
+#define LOOP_COUNT  1000
+#define RESULT      NUM_THREADS * LOOP_COUNT
+
+//------------------------------------------------------------------------
+// Master thread creates new threads, waits for all threads to complete,
+// deallocates threads and checks result
+//------------------------------------------------------------------------
+  call _create_threads
+  call _join
+  call _delete_threads
+  call _check
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// mt_test function executed in child threads
+// A child thread signals its completion by atomicaly adding 1 to barrier
+//------------------------------------------------------------------------
+_mt_test:
+  li        t0, 1               // initialize the swap value (1-locked)
+  li        t1, LOOP_COUNT
+  la        t2, var             // load the var's address
+  la        a0, shared_var
+
+1:
+  lr.d.aq       s2, (a0)        // load and reserve a0
+  bnez          s2, 1b          // retry lr if the lock is being held
+  sc.d.rl       s2, t0, (a0)    // try to lock a0
+  bnez          s2, 1b          // retry if sc failed
+
+  lw            t3, (t2)        // load the var's value
+  addi          t3, t3, 1       // add 1 to the value
+  sw            t3, (t2)        // store the new value to var
+
+  sd            zero, (a0)      // release the lock by storing 0 to a0
+
+  addi          t1, t1, -1      // decrement the loop_count
+  bnez          t1, 1b          // repeat if not done yet
+
+  la            a0, barrier
+  amoadd.d      zero, t0, (a0)  // signal this thread's completion
+
+  RVTEST_CODE_END
+
+//------------------------------------------------------------------------
+// Master thread checks result
+//------------------------------------------------------------------------
+_check:
+  la        a0, var
+  li        a1, RESULT
+  ld        a0, (a0)
+  bne       a0, a1, _fail
+  li        a0, SUCCESS
+  ret
+
+_fail:
+  li        a0, FAILURE
+  ret
+
+  .data
+
+MT_DATA
+var: .dword   0
diff --git a/src/asmtest/isa/rv64uc/Makefrag b/src/asmtest/isa/rv64uc/Makefrag
new file mode 100644
index 0000000..a1fec6f
--- /dev/null
+++ b/src/asmtest/isa/rv64uc/Makefrag
@@ -0,0 +1,12 @@
+#=======================================================================
+# Makefrag for rv64uc tests
+#-----------------------------------------------------------------------
+
+rv64uc_sc_tests = \
+	rvc \
+
+rv64uc_p_tests = $(addprefix rv64uc-p-, $(rv64uc_sc_tests))
+rv64uc_v_tests = $(addprefix rv64uc-v-, $(rv64uc_sc_tests))
+rv64ua_ps_tests = $(addprefix rv64ua-ps-, $(rv64ua_sc_tests))
+
+spike_tests += $(rv64uc_p_tests) $(rv64uc_v_tests)
diff --git a/src/asmtest/isa/rv64uc/rvc.S b/src/asmtest/isa/rv64uc/rvc.S
new file mode 100644
index 0000000..3629d1d
--- /dev/null
+++ b/src/asmtest/isa/rv64uc/rvc.S
@@ -0,0 +1,154 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# rvc.S
+#-----------------------------------------------------------------------------
+#
+# Test RVC corner cases.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  .align 2
+  .option push
+  .option norvc
+
+  #define RVC_TEST_CASE(n, r, v, code...) \
+    TEST_CASE (n, r, v, .option push; .option rvc; code; .align 2; .option pop)
+
+  // Make sure fetching a 4-byte instruction across a page boundary works.
+  li TESTNUM, 2
+  li a1, 666
+  TEST_CASE (2, a1, 667, \
+        j 1f; \
+        .align 3; \
+        data: \
+          .dword 0xfedcba9876543210; \
+          .dword 0xfedcba9876543210; \
+        .align 12; \
+        .skip 4094; \
+      1: addi a1, a1, 1)
+
+  li sp, 0x1234
+  RVC_TEST_CASE (3, a0, 0x1234 + 1020, c.addi4spn a0, sp, 1020)
+  RVC_TEST_CASE (4, sp, 0x1234 + 496, c.addi16sp sp, 496)
+  RVC_TEST_CASE (5, sp, 0x1234 + 496 - 512, c.addi16sp sp, -512)
+
+  la a1, data
+  RVC_TEST_CASE (6, a2, 0xfffffffffedcba99, c.lw a0, 4(a1); addi a0, a0, 1; c.sw a0, 4(a1); c.lw a2, 4(a1))
+#if __riscv_xlen == 64
+  RVC_TEST_CASE (7, a2, 0xfedcba9976543211, c.ld a0, 0(a1); addi a0, a0, 1; c.sd a0, 0(a1); c.ld a2, 0(a1))
+#endif
+
+  RVC_TEST_CASE (8, a0, -15, ori a0, x0, 1; c.addi a0, -16)
+  RVC_TEST_CASE (9, a5, -16, ori a5, x0, 1; c.li a5, -16)
+#if __riscv_xlen == 64
+  RVC_TEST_CASE (10, a0, 0x76543210, ld a0, (a1); c.addiw a0, -1)
+#endif
+
+  RVC_TEST_CASE (11, s0, 0xffffffffffffffe1, c.lui s0, 0xfffe1; c.srai s0, 12)
+#if __riscv_xlen == 64
+  RVC_TEST_CASE (12, s0, 0x000fffffffffffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
+#else
+  RVC_TEST_CASE (12, s0, 0x000fffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
+#endif
+  RVC_TEST_CASE (14, s0, ~0x11, c.li s0, -2; c.andi s0, ~0x10)
+  RVC_TEST_CASE (15, s1, 14, li s1, 20; li a0, 6; c.sub s1, a0)
+  RVC_TEST_CASE (16, s1, 18, li s1, 20; li a0, 6; c.xor s1, a0)
+  RVC_TEST_CASE (17, s1, 22, li s1, 20; li a0, 6; c.or s1, a0)
+  RVC_TEST_CASE (18, s1,  4, li s1, 20; li a0, 6; c.and s1, a0)
+#if __riscv_xlen == 64
+  RVC_TEST_CASE (19, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, -1; c.subw s1, a0)
+  RVC_TEST_CASE (20, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, 1; c.addw s1, a0)
+#endif
+  RVC_TEST_CASE (21, s0, 0x12340, li s0, 0x1234; c.slli s0, 4)
+
+  RVC_TEST_CASE (30, ra, 0, \
+        li ra, 0; \
+        c.j 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (31, x0, 0, \
+        li a0, 0; \
+        c.beqz a0, 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (32, x0, 0, \
+        li a0, 1; \
+        c.bnez a0, 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (33, x0, 0, \
+        li a0, 1; \
+        c.beqz a0, 1f; \
+        c.j 2f; \
+      1:c.j fail; \
+      2:)
+
+  RVC_TEST_CASE (34, x0, 0, \
+        li a0, 0; \
+        c.bnez a0, 1f; \
+        c.j 2f; \
+      1:c.j fail; \
+      2:)
+
+  RVC_TEST_CASE (35, ra, 0, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jr t0; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (36, ra, -2, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jalr t0; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:sub ra, ra, t0)
+
+#if __riscv_xlen == 32
+  RVC_TEST_CASE (37, ra, -2, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jal 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:sub ra, ra, t0)
+#endif
+
+  la sp, data
+  RVC_TEST_CASE (40, a2, 0xfffffffffedcba99, c.lwsp a0, 12(sp); addi a0, a0, 1; c.swsp a0, 12(sp); c.lwsp a2, 12(sp))
+#if __riscv_xlen == 64
+  RVC_TEST_CASE (41, a2, 0xfedcba9976543211, c.ldsp a0, 8(sp); addi a0, a0, 1; c.sdsp a0, 8(sp); c.ldsp a2, 8(sp))
+#endif
+
+  RVC_TEST_CASE (42, t0, 0x246, li a0, 0x123; c.mv t0, a0; c.add t0, a0)
+
+  .option pop
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/Makefrag b/src/asmtest/isa/rv64ud/Makefrag
new file mode 100644
index 0000000..7828481
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/Makefrag
@@ -0,0 +1,13 @@
+#=======================================================================
+# Makefrag for rv64ud tests
+#-----------------------------------------------------------------------
+
+rv64ud_sc_tests = \
+	fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \
+	ldst move structural recoding \
+
+rv64ud_p_tests = $(addprefix rv64ud-p-, $(rv64ud_sc_tests))
+rv64ud_v_tests = $(addprefix rv64ud-v-, $(rv64ud_sc_tests))
+rv64ud_ps_tests = $(addprefix rv64ud-ps-, $(rv64ud_sc_tests))
+
+spike_tests += $(rv64ud_p_tests) $(rv64ud_v_tests)
diff --git a/src/asmtest/isa/rv64ud/fadd.S b/src/asmtest/isa/rv64ud/fadd.S
new file mode 100644
index 0000000..51ca82d
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fadd.S
@@ -0,0 +1,50 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fadd.S
+#-----------------------------------------------------------------------------
+#
+# Test f{add|sub|mul}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_FP_OP2_D
+    #define TEST_FP_OP2_D TEST_FP_OP2_D32
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_D( 2,  fadd.d, 0,                3.5,        2.5,        1.0 );
+  TEST_FP_OP2_D( 3,  fadd.d, 1,              -1234,    -1235.1,        1.1 );
+  TEST_FP_OP2_D( 4,  fadd.d, 1,         3.14159266, 3.14159265, 0.00000001 );
+
+  TEST_FP_OP2_D( 5,  fsub.d, 0,                1.5,        2.5,        1.0 );
+  TEST_FP_OP2_D( 6,  fsub.d, 1,              -1234,    -1235.1,       -1.1 );
+  TEST_FP_OP2_D( 7,  fsub.d, 1, 3.1415926400000001, 3.14159265, 0.00000001 );
+
+  TEST_FP_OP2_D( 8,  fmul.d, 0,                2.5,        2.5,        1.0 );
+  TEST_FP_OP2_D( 9,  fmul.d, 1,            1358.61,    -1235.1,       -1.1 );
+  TEST_FP_OP2_D(10,  fmul.d, 1,      3.14159265e-8, 3.14159265, 0.00000001 );
+
+  # Is the canonical NaN generated for Inf - Inf?
+  TEST_FP_OP2_D(11,  fsub.d, 0x10, qNaN, Inf, Inf);
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fclass.S b/src/asmtest/isa/rv64ud/fclass.S
new file mode 100644
index 0000000..04a8947
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fclass.S
@@ -0,0 +1,46 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fclass.S
+#-----------------------------------------------------------------------------
+#
+# Test fclass.d instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_FCLASS_D
+    #define TEST_FCLASS_D TEST_FCLASS_D32
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FCLASS_D( 2, 1 << 0, 0xfff0000000000000 )
+  TEST_FCLASS_D( 3, 1 << 1, 0xbff0000000000000 )
+  TEST_FCLASS_D( 4, 1 << 2, 0x800fffffffffffff )
+  TEST_FCLASS_D( 5, 1 << 3, 0x8000000000000000 )
+  TEST_FCLASS_D( 6, 1 << 4, 0x0000000000000000 )
+  TEST_FCLASS_D( 7, 1 << 5, 0x000fffffffffffff )
+  TEST_FCLASS_D( 8, 1 << 6, 0x3ff0000000000000 )
+  TEST_FCLASS_D( 9, 1 << 7, 0x7ff0000000000000 )
+  TEST_FCLASS_D(10, 1 << 8, 0x7ff0000000000001 )
+  TEST_FCLASS_D(11, 1 << 9, 0x7ff8000000000000 )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fcmp.S b/src/asmtest/isa/rv64ud/fcmp.S
new file mode 100644
index 0000000..7727a28
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fcmp.S
@@ -0,0 +1,56 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcmp.S
+#-----------------------------------------------------------------------------
+#
+# Test f{eq|lt|le}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_FP_CMP_OP_D
+    #define TEST_FP_CMP_OP_D TEST_FP_CMP_OP_D32
+#endif
+
+  TEST_FP_CMP_OP_D( 2, feq.d, 0x00, 1, -1.36, -1.36)
+  TEST_FP_CMP_OP_D( 3, fle.d, 0x00, 1, -1.36, -1.36)
+  TEST_FP_CMP_OP_D( 4, flt.d, 0x00, 0, -1.36, -1.36)
+
+  TEST_FP_CMP_OP_D( 5, feq.d, 0x00, 0, -1.37, -1.36)
+  TEST_FP_CMP_OP_D( 6, fle.d, 0x00, 1, -1.37, -1.36)
+  TEST_FP_CMP_OP_D( 7, flt.d, 0x00, 1, -1.37, -1.36)
+
+  # Only sNaN should signal invalid for feq.
+  TEST_FP_CMP_OP_D( 8, feq.d, 0x00, 0, NaN, 0)
+  TEST_FP_CMP_OP_D( 9, feq.d, 0x00, 0, NaN, NaN)
+  TEST_FP_CMP_OP_D(10, feq.d, 0x10, 0, sNaN, 0)
+
+  # qNaN should signal invalid for fle/flt.
+  TEST_FP_CMP_OP_D(11, flt.d, 0x10, 0, NaN, 0)
+  TEST_FP_CMP_OP_D(12, flt.d, 0x10, 0, NaN, NaN)
+  TEST_FP_CMP_OP_D(13, flt.d, 0x10, 0, sNaN, 0)
+  TEST_FP_CMP_OP_D(14, fle.d, 0x10, 0, NaN, 0)
+  TEST_FP_CMP_OP_D(15, fle.d, 0x10, 0, NaN, NaN)
+  TEST_FP_CMP_OP_D(16, fle.d, 0x10, 0, sNaN, 0)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fcvt.S b/src/asmtest/isa/rv64ud/fcvt.S
new file mode 100644
index 0000000..98916b1
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fcvt.S
@@ -0,0 +1,79 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcvt.S
+#-----------------------------------------------------------------------------
+#
+# Test fcvt.d.{wu|w|lu|l}, fcvt.s.d, and fcvt.d.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_INT_FP_OP_D
+    #define TEST_INT_FP_OP_D TEST_INT_FP_OP_D32
+
+    #undef TEST_FCVT_S_D
+    #define TEST_FCVT_S_D TEST_FCVT_S_D32
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_INT_FP_OP_D(2,  fcvt.d.w,                   2.0,  2);
+  TEST_INT_FP_OP_D(3,  fcvt.d.w,                  -2.0, -2);
+
+  TEST_INT_FP_OP_D(4, fcvt.d.wu,                   2.0,  2);
+  TEST_INT_FP_OP_D(5, fcvt.d.wu,            4294967294, -2);
+
+#if __riscv_xlen >= 64
+  TEST_INT_FP_OP_D(6,  fcvt.d.l,                   2.0,  2);
+  TEST_INT_FP_OP_D(7,  fcvt.d.l,                  -2.0, -2);
+
+  TEST_INT_FP_OP_D(8, fcvt.d.lu,                   2.0,  2);
+  TEST_INT_FP_OP_D(9, fcvt.d.lu, 1.8446744073709552e19, -2);
+#endif
+
+  TEST_FCVT_S_D(10, -1.5, -1.5)
+  TEST_FCVT_D_S(11, -1.5, -1.5)
+
+#if __riscv_xlen >= 64
+  TEST_CASE(12, a0, 0x7ff8000000000000,
+    la a1, test_data_22;
+    ld a2, 0(a1);
+    fmv.d.x f2, a2;
+    fcvt.s.d f2, f2;
+    fcvt.d.s f2, f2;
+    fmv.x.d a0, f2;
+  )
+#else
+  TEST_CASE_D32(12, a0, a1, 0x7ff8000000000000,
+    la a1, test_data_22;
+    fld f2, 0(a1);
+    fcvt.s.d f2, f2;
+    fcvt.d.s f2, f2;
+    fsd f2, 0(a1);
+    lw a0, 0(a1);
+    lw a1, 4(a1)
+  )
+#endif
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+test_data_22:
+  .dword 0x7ffcffffffff8004
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fcvt_w.S b/src/asmtest/isa/rv64ud/fcvt_w.S
new file mode 100644
index 0000000..56cc29d
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fcvt_w.S
@@ -0,0 +1,114 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcvt_w.S
+#-----------------------------------------------------------------------------
+#
+# Test fcvt{wu|w|lu|l}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_INT_OP_D( 2,  fcvt.w.d, 0x01,         -1, -1.1, rtz);
+  TEST_FP_INT_OP_D( 3,  fcvt.w.d, 0x00,         -1, -1.0, rtz);
+  TEST_FP_INT_OP_D( 4,  fcvt.w.d, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_D( 5,  fcvt.w.d, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_D( 6,  fcvt.w.d, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_D( 7,  fcvt.w.d, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_D( 8,  fcvt.w.d, 0x10,     -1<<31, -3e9, rtz);
+  TEST_FP_INT_OP_D( 9,  fcvt.w.d, 0x10,  (1<<31)-1,  3e9, rtz);
+
+  TEST_FP_INT_OP_D(12, fcvt.wu.d, 0x10,          0, -3.0, rtz);
+  TEST_FP_INT_OP_D(13, fcvt.wu.d, 0x10,          0, -1.0, rtz);
+  TEST_FP_INT_OP_D(14, fcvt.wu.d, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_D(15, fcvt.wu.d, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_D(16, fcvt.wu.d, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_D(17, fcvt.wu.d, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_D(18, fcvt.wu.d, 0x10,          0, -3e9, rtz);
+  TEST_FP_INT_OP_D(19, fcvt.wu.d, 0x00, 0xffffffffb2d05e00, 3e9, rtz);
+
+#if __riscv_xlen >= 64
+  TEST_FP_INT_OP_D(22,  fcvt.l.d, 0x01,         -1, -1.1, rtz);
+  TEST_FP_INT_OP_D(23,  fcvt.l.d, 0x00,         -1, -1.0, rtz);
+  TEST_FP_INT_OP_D(24,  fcvt.l.d, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_D(25,  fcvt.l.d, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_D(26,  fcvt.l.d, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_D(27,  fcvt.l.d, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_D(28,  fcvt.l.d, 0x00,-3000000000, -3e9, rtz);
+  TEST_FP_INT_OP_D(29,  fcvt.l.d, 0x00, 3000000000,  3e9, rtz);
+  TEST_FP_INT_OP_D(20,  fcvt.l.d, 0x10,     -1<<63,-3e19, rtz);
+  TEST_FP_INT_OP_D(21,  fcvt.l.d, 0x10,  (1<<63)-1, 3e19, rtz);
+
+  TEST_FP_INT_OP_D(32, fcvt.lu.d, 0x10,          0, -3.0, rtz);
+  TEST_FP_INT_OP_D(33, fcvt.lu.d, 0x10,          0, -1.0, rtz);
+  TEST_FP_INT_OP_D(34, fcvt.lu.d, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_D(35, fcvt.lu.d, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_D(36, fcvt.lu.d, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_D(37, fcvt.lu.d, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_D(38, fcvt.lu.d, 0x10,          0, -3e9, rtz);
+  TEST_FP_INT_OP_D(39, fcvt.lu.d, 0x00, 3000000000,  3e9, rtz);
+#endif
+
+  # test negative NaN, negative infinity conversion
+  TEST_CASE(42, x1, 0x000000007fffffff, la x1, tdat_d; fld f1,  0(x1); fcvt.w.d x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE(43, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1,  0(x1); fcvt.l.d x1, f1)
+#endif
+  TEST_CASE(44, x1, 0xffffffff80000000, la x1, tdat_d; fld f1, 16(x1); fcvt.w.d x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE(45, x1, 0x8000000000000000, la x1, tdat_d; fld f1, 16(x1); fcvt.l.d x1, f1)
+#endif
+
+  # test positive NaN, positive infinity conversion
+  TEST_CASE(52, x1, 0x000000007fffffff, la x1, tdat_d; fld f1,  8(x1); fcvt.w.d x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE(53, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1,  8(x1); fcvt.l.d x1, f1)
+#endif
+  TEST_CASE(54, x1, 0x000000007fffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.w.d x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE(55, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.l.d x1, f1)
+#endif
+
+  # test NaN, infinity conversions to unsigned integer
+  TEST_CASE(62, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1,  0(x1); fcvt.wu.d x1, f1)
+  TEST_CASE(63, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1,  8(x1); fcvt.wu.d x1, f1)
+  TEST_CASE(64, x1,                  0, la x1, tdat_d; fld f1, 16(x1); fcvt.wu.d x1, f1)
+  TEST_CASE(65, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.wu.d x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE(66, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1,  0(x1); fcvt.lu.d x1, f1)
+  TEST_CASE(67, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1,  8(x1); fcvt.lu.d x1, f1)
+  TEST_CASE(68, x1,                  0, la x1, tdat_d; fld f1, 16(x1); fcvt.lu.d x1, f1)
+  TEST_CASE(69, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.lu.d x1, f1)
+#endif
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+# -NaN, NaN, -inf, +inf
+tdat:
+.word 0xffffffff
+.word 0x7fffffff
+.word 0xff800000
+.word 0x7f800000
+
+tdat_d:
+.dword 0xffffffffffffffff
+.dword 0x7fffffffffffffff
+.dword 0xfff0000000000000
+.dword 0x7ff0000000000000
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fdiv.S b/src/asmtest/isa/rv64ud/fdiv.S
new file mode 100644
index 0000000..f985fa1
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fdiv.S
@@ -0,0 +1,54 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fdiv.S
+#-----------------------------------------------------------------------------
+#
+# Test f{div|sqrt}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the functions with the 32-bit variants defined in test_macros.h
+    #undef TEST_FP_OP2_D
+    #define TEST_FP_OP2_D TEST_FP_OP2_D32
+
+    #undef TEST_FP_OP1_D
+    #define TEST_FP_OP1_D TEST_FP_OP1_D32
+
+    #undef TEST_FP_OP1_D_DWORD_RESULT
+    #define TEST_FP_OP1_D_DWORD_RESULT TEST_FP_OP1_D32_DWORD_RESULT
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_D( 2,  fdiv.d, 1, 1.1557273520668288, 3.14159265, 2.71828182 );
+  TEST_FP_OP2_D( 3,  fdiv.d, 1,-0.9991093838555584,      -1234,     1235.1 );
+  TEST_FP_OP2_D( 4,  fdiv.d, 0,         3.14159265, 3.14159265,        1.0 );
+
+  TEST_FP_OP1_D( 5,  fsqrt.d, 1, 1.7724538498928541, 3.14159265 );
+  TEST_FP_OP1_D( 6,  fsqrt.d, 0,                100,      10000 );
+
+  TEST_FP_OP1_D_DWORD_RESULT(16,  fsqrt.d, 0x10,      0x7FF8000000000000,      -1.0 );
+
+  TEST_FP_OP1_D( 7,  fsqrt.d, 1, 13.076696830622021, 171.0);
+
+  TEST_FP_OP1_D( 8,  fsqrt.d, 1,0.00040099251863345283320230749702, 1.60795e-7);
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fmadd.S b/src/asmtest/isa/rv64ud/fmadd.S
new file mode 100644
index 0000000..1e3ba66
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fmadd.S
@@ -0,0 +1,51 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fmadd.S
+#-----------------------------------------------------------------------------
+#
+# Test f[n]m{add|sub}.s and f[n]m{add|sub}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_FP_OP3_D
+    #define TEST_FP_OP3_D TEST_FP_OP3_D32
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP3_D( 2,  fmadd.d, 0,                 3.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_D( 3,  fmadd.d, 1,  1236.1999999999999, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_D( 4,  fmadd.d, 0,               -12.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_D( 5, fnmadd.d, 0,                -3.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_D( 6, fnmadd.d, 1, -1236.1999999999999, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_D( 7, fnmadd.d, 0,                12.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_D( 8,  fmsub.d, 0,                 1.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_D( 9,  fmsub.d, 1,                1234, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_D(10,  fmsub.d, 0,                -8.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_D(11, fnmsub.d, 0,                -1.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_D(12, fnmsub.d, 1,               -1234, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_D(13, fnmsub.d, 0,                 8.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/fmin.S b/src/asmtest/isa/rv64ud/fmin.S
new file mode 100644
index 0000000..8f270a5
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/fmin.S
@@ -0,0 +1,60 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fmin.S
+#-----------------------------------------------------------------------------
+#
+# Test f{min|max}.d instructinos.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#if __riscv_xlen == 32
+    # Replace the function with the 32-bit variant defined in test_macros.h
+    #undef TEST_FP_OP2_D
+    #define TEST_FP_OP2_D TEST_FP_OP2_D32
+#endif
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_D( 2,  fmin.d, 0,        1.0,        2.5,        1.0 );
+  TEST_FP_OP2_D( 3,  fmin.d, 0,    -1235.1,    -1235.1,        1.1 );
+  TEST_FP_OP2_D( 4,  fmin.d, 0,    -1235.1,        1.1,    -1235.1 );
+  TEST_FP_OP2_D( 5,  fmin.d, 0,    -1235.1,        NaN,    -1235.1 );
+  TEST_FP_OP2_D( 6,  fmin.d, 0, 0.00000001, 3.14159265, 0.00000001 );
+  TEST_FP_OP2_D( 7,  fmin.d, 0,       -2.0,       -1.0,       -2.0 );
+
+  TEST_FP_OP2_D(12,  fmax.d, 0,        2.5,        2.5,        1.0 );
+  TEST_FP_OP2_D(13,  fmax.d, 0,        1.1,    -1235.1,        1.1 );
+  TEST_FP_OP2_D(14,  fmax.d, 0,        1.1,        1.1,    -1235.1 );
+  TEST_FP_OP2_D(15,  fmax.d, 0,    -1235.1,        NaN,    -1235.1 );
+  TEST_FP_OP2_D(16,  fmax.d, 0, 3.14159265, 3.14159265, 0.00000001 );
+  TEST_FP_OP2_D(17,  fmax.d, 0,       -1.0,       -1.0,       -2.0 );
+
+  # FMAX(sNaN, x) = x
+  TEST_FP_OP2_D(20,  fmax.d, 0x10, 1.0, sNaN, 1.0);
+  # FMAX(qNaN, qNaN) = canonical NaN
+  TEST_FP_OP2_D(21,  fmax.d, 0x00, qNaN, NaN, NaN);
+
+  # -0.0 < +0.0
+  TEST_FP_OP2_D(30,  fmin.d, 0,       -0.0,       -0.0,        0.0 );
+  TEST_FP_OP2_D(31,  fmin.d, 0,       -0.0,        0.0,       -0.0 );
+  TEST_FP_OP2_D(32,  fmax.d, 0,        0.0,       -0.0,        0.0 );
+  TEST_FP_OP2_D(33,  fmax.d, 0,        0.0,        0.0,       -0.0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/ldst.S b/src/asmtest/isa/rv64ud/ldst.S
new file mode 100644
index 0000000..9629341
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/ldst.S
@@ -0,0 +1,42 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ldst.S
+#-----------------------------------------------------------------------------
+#
+# This test verifies that flw, fld, fsw, and fsd work properly.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  la s0, tdat
+  TEST_CASE(2, a0, 0x40000000bf800000, fld f2, 0(s0); fsd f2, 16(s0); ld a0, 16(s0))
+  TEST_CASE(3, a0, 0x40000000bf800000, fld f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0))
+  TEST_CASE(4, a0, 0x40000000bf800000, flw f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0))
+  TEST_CASE(5, a0, 0xc080000040400000, fld f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0))
+  TEST_CASE(6, a0, 0xffffffff40400000, flw f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+.word 0xbf800000
+.word 0x40000000
+.word 0x40400000
+.word 0xc0800000
+.word 0xdeadbeef
+.word 0xcafebabe
+.word 0xabad1dea
+.word 0x1337d00d
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/move.S b/src/asmtest/isa/rv64ud/move.S
new file mode 100644
index 0000000..8911d95
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/move.S
@@ -0,0 +1,113 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# move.S
+#-----------------------------------------------------------------------------
+#
+# This test verifies that fmv.d.x, fmv.x.d, and fsgnj[x|n].d work properly.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+#TODO: make 32-bit compatible version
+#define TEST_FSGNJD(n, insn, new_sign, rs1_sign, rs2_sign) \
+  TEST_CASE(n, a0, 0x123456789abcdef0 | (-(new_sign) << 63), \
+    li a1, ((rs1_sign) << 63) | 0x123456789abcdef0; \
+    li a2, -(rs2_sign); \
+    fmv.d.x f1, a1; \
+    fmv.d.x f2, a2; \
+    insn f0, f1, f2; \
+    fmv.x.d a0, f0)
+
+  TEST_FSGNJD(10, fsgnj.d, 0, 0, 0)
+  TEST_FSGNJD(11, fsgnj.d, 1, 0, 1)
+  TEST_FSGNJD(12, fsgnj.d, 0, 1, 0)
+  TEST_FSGNJD(13, fsgnj.d, 1, 1, 1)
+
+  TEST_FSGNJD(20, fsgnjn.d, 1, 0, 0)
+  TEST_FSGNJD(21, fsgnjn.d, 0, 0, 1)
+  TEST_FSGNJD(22, fsgnjn.d, 1, 1, 0)
+  TEST_FSGNJD(23, fsgnjn.d, 0, 1, 1)
+
+  TEST_FSGNJD(30, fsgnjx.d, 0, 0, 0)
+  TEST_FSGNJD(31, fsgnjx.d, 1, 0, 1)
+  TEST_FSGNJD(32, fsgnjx.d, 1, 1, 0)
+  TEST_FSGNJD(33, fsgnjx.d, 0, 1, 1)
+
+// Test fsgnj.s in conjunction with double-precision moves
+#define TEST_FSGNJS(n, rd, rs1, rs2) \
+  TEST_CASE(n, a0, (rd) | (-((rd) >> 31) << 32), \
+    li a1, rs1; \
+    li a2, rs2; \
+    fmv.d.x f1, a1; \
+    fmv.d.x f2, a2; \
+    fsgnj.s f0, f1, f2; \
+    fmv.x.s a0, f0); \
+  TEST_CASE(1##n, a0, (rd) | 0xffffffff00000000, \
+    li a1, rs1; \
+    li a2, rs2; \
+    fmv.d.x f1, a1; \
+    fmv.d.x f2, a2; \
+    fsgnj.s f0, f1, f2; \
+    fmv.x.d a0, f0)
+
+  TEST_FSGNJS(40, 0x7fc00000, 0x7ffffffe12345678, 0)
+  TEST_FSGNJS(41, 0x7fc00000, 0xfffffffe12345678, 0)
+  TEST_FSGNJS(42, 0x7fc00000, 0x7fffffff12345678, 0)
+  TEST_FSGNJS(43, 0x12345678, 0xffffffff12345678, 0)
+
+  TEST_FSGNJS(50, 0x7fc00000, 0x7ffffffe12345678, 0x80000000)
+  TEST_FSGNJS(51, 0x7fc00000, 0xfffffffe12345678, 0x80000000)
+  TEST_FSGNJS(52, 0x7fc00000, 0x7fffffff12345678, 0x80000000)
+  TEST_FSGNJS(53, 0x12345678, 0xffffffff12345678, 0x80000000)
+
+  TEST_FSGNJS(60, 0xffc00000, 0x7ffffffe12345678, 0xffffffff80000000)
+  TEST_FSGNJS(61, 0xffc00000, 0xfffffffe12345678, 0xffffffff80000000)
+  TEST_FSGNJS(62, 0x92345678, 0xffffffff12345678, 0xffffffff80000000)
+  TEST_FSGNJS(63, 0x12345678, 0xffffffff12345678, 0x7fffffff80000000)
+
+// Test fsgnj.d in conjunction with single-precision moves
+#define TEST_FSGNJD_SP(n, isnan, rd, rs1, rs2) \
+  TEST_CASE(n, a0, ((rd) & 0xffffffff) | (-(((rd) >> 31) & 1) << 32), \
+    li a1, rs1; \
+    li a2, rs2; \
+    fmv.d.x f1, a1; \
+    fmv.d.x f2, a2; \
+    fsgnj.d f0, f1, f2; \
+    feq.s a0, f0, f0; \
+    addi a0, a0, -!(isnan); \
+    bnez a0, 1f; \
+    fmv.x.s a0, f0; \
+    1:); \
+  TEST_CASE(1##n, a0, rd, \
+    li a1, rs1; \
+    li a2, rs2; \
+    fmv.d.x f1, a1; \
+    fmv.d.x f2, a2; \
+    fsgnj.d f0, f1, f2; \
+    fmv.x.d a0, f0; \
+    1:)
+
+  TEST_FSGNJD_SP(70, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff11111111)
+  TEST_FSGNJD_SP(71, 1, 0x7fffffff11111111, 0xffffffff11111111, 0x7fffffff11111111)
+  TEST_FSGNJD_SP(72, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff91111111)
+  TEST_FSGNJD_SP(73, 0, 0xffffffff11111111, 0xffffffff11111111, 0x8000000000000000)
+  TEST_FSGNJD_SP(74, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff11111111)
+  TEST_FSGNJD_SP(75, 1, 0x7fffffff11111111, 0x7fffffff11111111, 0x7fffffff11111111)
+  TEST_FSGNJD_SP(76, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff91111111)
+  TEST_FSGNJD_SP(77, 0, 0xffffffff11111111, 0x7fffffff11111111, 0x8000000000000000)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/recoding.S b/src/asmtest/isa/rv64ud/recoding.S
new file mode 100644
index 0000000..69ad665
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/recoding.S
@@ -0,0 +1,67 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# recoding.S
+#-----------------------------------------------------------------------------
+#
+# Test corner cases of John Hauser's microarchitectural recoding scheme.
+# There are twice as many recoded values as IEEE-754 values; some of these
+# extras are redundant (e.g. Inf) and others are illegal (subnormals with
+# too many bits set).
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  # Make sure infinities with different mantissas compare as equal.
+  fld f0, minf, a0
+  fld f1, three, a0
+  fmul.d f1, f1, f0
+  TEST_CASE( 2, a0, 1, feq.d a0, f0, f1)
+  TEST_CASE( 3, a0, 1, fle.d a0, f0, f1)
+  TEST_CASE( 4, a0, 0, flt.d a0, f0, f1)
+
+  # Likewise, but for zeroes.
+  fcvt.d.w f0, x0
+  li a0, 1
+  fcvt.d.w f1, a0
+  fmul.d f1, f1, f0
+  TEST_CASE(5, a0, 1, feq.d a0, f0, f1)
+  TEST_CASE(6, a0, 1, fle.d a0, f0, f1)
+  TEST_CASE(7, a0, 0, flt.d a0, f0, f1)
+
+  # When converting small doubles to single-precision subnormals,
+  # ensure that the extra precision is discarded.
+  flw f0, big, a0
+  fld f1, tiny, a0
+  fcvt.s.d f1, f1
+  fmul.s f0, f0, f1
+  fmv.x.s a0, f0
+  lw a1, small
+  TEST_CASE(10, a0, 0, sub a0, a0, a1)
+
+  # Make sure FSD+FLD correctly saves and restores a single-precision value.
+  flw f0, three, a0
+  fadd.s f1, f0, f0
+  fadd.s f0, f0, f0
+  fsd f0, tiny, a0
+  fld f0, tiny, a0
+  TEST_CASE(20, a0, 1, feq.s a0, f0, f1)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+minf: .double -Inf
+three: .double 3.0
+big: .float 1221
+small: .float 2.9133121e-37
+tiny: .double 2.3860049081905093e-40
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ud/structural.S b/src/asmtest/isa/rv64ud/structural.S
new file mode 100644
index 0000000..3cf87aa
--- /dev/null
+++ b/src/asmtest/isa/rv64ud/structural.S
@@ -0,0 +1,58 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# structural.S
+#-----------------------------------------------------------------------------
+#
+# This test verifies that the FPU correctly obviates structural hazards on its
+# writeback port (e.g. fadd followed by fsgnj)
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+li x12, 1
+
+li x2, 0x3FF0000000000000
+li x1, 0x3F800000
+
+#define TEST(nops, errcode)     \
+  fmv.d.x  f4, x0    ;\
+  fmv.s.x  f3, x0    ;\
+  fmv.d.x  f2, x2    ;\
+  fmv.s.x  f1, x1    ;\
+  j 1f ;\
+  .align 5        ;\
+1:fmul.d  f4, f2, f2  ;\
+  nops          ;\
+  fsgnj.s f3, f1, f1 ;\
+  fmv.x.d  x4, f4    ;\
+  fmv.x.s  x5, f3    ;\
+  beq     x1, x5, 2f  ;\
+  RVTEST_FAIL ;\
+2:beq     x2, x4, 2f  ;\
+  RVTEST_FAIL; \
+2:fmv.d.x  f2, zero    ;\
+  fmv.s.x  f1, zero    ;\
+
+TEST(;,2)
+TEST(nop,4)
+TEST(nop;nop,6)
+TEST(nop;nop;nop,8)
+TEST(nop;nop;nop;nop,10)
+TEST(nop;nop;nop;nop;nop,12)
+TEST(nop;nop;nop;nop;nop;nop,14)
+
+RVTEST_PASS
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/Makefrag b/src/asmtest/isa/rv64uf/Makefrag
new file mode 100644
index 0000000..26c63af
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/Makefrag
@@ -0,0 +1,13 @@
+#=======================================================================
+# Makefrag for rv64uf tests
+#-----------------------------------------------------------------------
+
+rv64uf_sc_tests = \
+	fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \
+	ldst move recoding \
+
+rv64uf_p_tests = $(addprefix rv64uf-p-, $(rv64uf_sc_tests))
+rv64uf_v_tests = $(addprefix rv64uf-v-, $(rv64uf_sc_tests))
+rv64uf_ps_tests = $(addprefix rv64uf-ps-, $(rv64uf_sc_tests))
+
+spike_tests += $(rv64uf_p_tests) $(rv64uf_v_tests)
diff --git a/src/asmtest/isa/rv64uf/fadd.S b/src/asmtest/isa/rv64uf/fadd.S
new file mode 100644
index 0000000..b6259df
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fadd.S
@@ -0,0 +1,44 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fadd.S
+#-----------------------------------------------------------------------------
+#
+# Test f{add|sub|mul}.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_S( 2,  fadd.s, 0,                3.5,        2.5,        1.0 );
+  TEST_FP_OP2_S( 3,  fadd.s, 1,              -1234,    -1235.1,        1.1 );
+  TEST_FP_OP2_S( 4,  fadd.s, 1,         3.14159265, 3.14159265, 0.00000001 );
+
+  TEST_FP_OP2_S( 5,  fsub.s, 0,                1.5,        2.5,        1.0 );
+  TEST_FP_OP2_S( 6,  fsub.s, 1,              -1234,    -1235.1,       -1.1 );
+  TEST_FP_OP2_S( 7,  fsub.s, 1,         3.14159265, 3.14159265, 0.00000001 );
+
+  TEST_FP_OP2_S( 8,  fmul.s, 0,                2.5,        2.5,        1.0 );
+  TEST_FP_OP2_S( 9,  fmul.s, 1,            1358.61,    -1235.1,       -1.1 );
+  TEST_FP_OP2_S(10,  fmul.s, 1,      3.14159265e-8, 3.14159265, 0.00000001 );
+
+  # Is the canonical NaN generated for Inf - Inf?
+  TEST_FP_OP2_S(11,  fsub.s, 0x10, qNaNf, Inf, Inf);
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fclass.S b/src/asmtest/isa/rv64uf/fclass.S
new file mode 100644
index 0000000..9bb86b1
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fclass.S
@@ -0,0 +1,40 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fclass.S
+#-----------------------------------------------------------------------------
+#
+# Test fclass.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FCLASS_S( 2, 1 << 0, 0xff800000 )
+  TEST_FCLASS_S( 3, 1 << 1, 0xbf800000 )
+  TEST_FCLASS_S( 4, 1 << 2, 0x807fffff )
+  TEST_FCLASS_S( 5, 1 << 3, 0x80000000 )
+  TEST_FCLASS_S( 6, 1 << 4, 0x00000000 )
+  TEST_FCLASS_S( 7, 1 << 5, 0x007fffff )
+  TEST_FCLASS_S( 8, 1 << 6, 0x3f800000 )
+  TEST_FCLASS_S( 9, 1 << 7, 0x7f800000 )
+  TEST_FCLASS_S(10, 1 << 8, 0x7f800001 )
+  TEST_FCLASS_S(11, 1 << 9, 0x7fc00000 )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fcmp.S b/src/asmtest/isa/rv64uf/fcmp.S
new file mode 100644
index 0000000..2d7fcc2
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fcmp.S
@@ -0,0 +1,50 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcmp.S
+#-----------------------------------------------------------------------------
+#
+# Test f{eq|lt|le}.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_CMP_OP_S( 2, feq.s, 0x00, 1, -1.36, -1.36)
+  TEST_FP_CMP_OP_S( 3, fle.s, 0x00, 1, -1.36, -1.36)
+  TEST_FP_CMP_OP_S( 4, flt.s, 0x00, 0, -1.36, -1.36)
+
+  TEST_FP_CMP_OP_S( 5, feq.s, 0x00, 0, -1.37, -1.36)
+  TEST_FP_CMP_OP_S( 6, fle.s, 0x00, 1, -1.37, -1.36)
+  TEST_FP_CMP_OP_S( 7, flt.s, 0x00, 1, -1.37, -1.36)
+
+  # Only sNaN should signal invalid for feq.
+  TEST_FP_CMP_OP_S( 8, feq.s, 0x00, 0, NaN, 0)
+  TEST_FP_CMP_OP_S( 9, feq.s, 0x00, 0, NaN, NaN)
+  TEST_FP_CMP_OP_S(10, feq.s, 0x10, 0, sNaNf, 0)
+
+  # qNaN should signal invalid for fle/flt.
+  TEST_FP_CMP_OP_S(11, flt.s, 0x10, 0, NaN, 0)
+  TEST_FP_CMP_OP_S(12, flt.s, 0x10, 0, NaN, NaN)
+  TEST_FP_CMP_OP_S(13, flt.s, 0x10, 0, sNaNf, 0)
+  TEST_FP_CMP_OP_S(14, fle.s, 0x10, 0, NaN, 0)
+  TEST_FP_CMP_OP_S(15, fle.s, 0x10, 0, NaN, NaN)
+  TEST_FP_CMP_OP_S(16, fle.s, 0x10, 0, sNaNf, 0)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fcvt.S b/src/asmtest/isa/rv64uf/fcvt.S
new file mode 100644
index 0000000..a41686e
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fcvt.S
@@ -0,0 +1,43 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcvt.S
+#-----------------------------------------------------------------------------
+#
+# Test fcvt.s.{wu|w|lu|l}, fcvt.s.d, and fcvt.d.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_INT_FP_OP_S( 2,  fcvt.s.w,                   2.0,  2);
+  TEST_INT_FP_OP_S( 3,  fcvt.s.w,                  -2.0, -2);
+
+  TEST_INT_FP_OP_S( 4, fcvt.s.wu,                   2.0,  2);
+  TEST_INT_FP_OP_S( 5, fcvt.s.wu,           4.2949673e9, -2);
+
+#if __riscv_xlen >= 64
+  TEST_INT_FP_OP_S( 6,  fcvt.s.l,                   2.0,  2);
+  TEST_INT_FP_OP_S( 7,  fcvt.s.l,                  -2.0, -2);
+
+  TEST_INT_FP_OP_S( 8, fcvt.s.lu,                   2.0,  2);
+  TEST_INT_FP_OP_S( 9, fcvt.s.lu,          1.8446744e19, -2);
+#endif
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fcvt_w.S b/src/asmtest/isa/rv64uf/fcvt_w.S
new file mode 100644
index 0000000..cad5cba
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fcvt_w.S
@@ -0,0 +1,105 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fcvt_w.S
+#-----------------------------------------------------------------------------
+#
+# Test fcvt{wu|w|lu|l}.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_INT_OP_S( 2,  fcvt.w.s, 0x01,         -1, -1.1, rtz);
+  TEST_FP_INT_OP_S( 3,  fcvt.w.s, 0x00,         -1, -1.0, rtz);
+  TEST_FP_INT_OP_S( 4,  fcvt.w.s, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_S( 5,  fcvt.w.s, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_S( 6,  fcvt.w.s, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_S( 7,  fcvt.w.s, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_S( 8,  fcvt.w.s, 0x10,     -1<<31, -3e9, rtz);
+  TEST_FP_INT_OP_S( 9,  fcvt.w.s, 0x10,  (1<<31)-1,  3e9, rtz);
+
+  TEST_FP_INT_OP_S(12, fcvt.wu.s, 0x10,          0, -3.0, rtz);
+  TEST_FP_INT_OP_S(13, fcvt.wu.s, 0x10,          0, -1.0, rtz);
+  TEST_FP_INT_OP_S(14, fcvt.wu.s, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_S(15, fcvt.wu.s, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_S(16, fcvt.wu.s, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_S(17, fcvt.wu.s, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_S(18, fcvt.wu.s, 0x10,          0, -3e9, rtz);
+  TEST_FP_INT_OP_S(19, fcvt.wu.s, 0x00, 3000000000,  3e9, rtz);
+
+#if __riscv_xlen >= 64
+  TEST_FP_INT_OP_S(22,  fcvt.l.s, 0x01,         -1, -1.1, rtz);
+  TEST_FP_INT_OP_S(23,  fcvt.l.s, 0x00,         -1, -1.0, rtz);
+  TEST_FP_INT_OP_S(24,  fcvt.l.s, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_S(25,  fcvt.l.s, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_S(26,  fcvt.l.s, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_S(27,  fcvt.l.s, 0x01,          1,  1.1, rtz);
+
+  TEST_FP_INT_OP_S(32, fcvt.lu.s, 0x10,          0, -3.0, rtz);
+  TEST_FP_INT_OP_S(33, fcvt.lu.s, 0x10,          0, -1.0, rtz);
+  TEST_FP_INT_OP_S(34, fcvt.lu.s, 0x01,          0, -0.9, rtz);
+  TEST_FP_INT_OP_S(35, fcvt.lu.s, 0x01,          0,  0.9, rtz);
+  TEST_FP_INT_OP_S(36, fcvt.lu.s, 0x00,          1,  1.0, rtz);
+  TEST_FP_INT_OP_S(37, fcvt.lu.s, 0x01,          1,  1.1, rtz);
+  TEST_FP_INT_OP_S(38, fcvt.lu.s, 0x10,          0, -3e9, rtz);
+#endif
+
+  # test negative NaN, negative infinity conversion
+  TEST_CASE( 42, x1, 0x000000007fffffff, la x1, tdat  ; flw f1,  0(x1); fcvt.w.s x1, f1)
+  TEST_CASE( 44, x1, 0xffffffff80000000, la x1, tdat  ; flw f1,  8(x1); fcvt.w.s x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE( 43, x1, 0x7fffffffffffffff, la x1, tdat  ; flw f1,  0(x1); fcvt.l.s x1, f1)
+  TEST_CASE( 45, x1, 0x8000000000000000, la x1, tdat  ; flw f1,  8(x1); fcvt.l.s x1, f1)
+#endif
+
+  # test positive NaN, positive infinity conversion
+  TEST_CASE( 52, x1, 0x000000007fffffff, la x1, tdat  ; flw f1,  4(x1); fcvt.w.s x1, f1)
+  TEST_CASE( 54, x1, 0x000000007fffffff, la x1, tdat  ; flw f1, 12(x1); fcvt.w.s x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE( 53, x1, 0x7fffffffffffffff, la x1, tdat  ; flw f1,  4(x1); fcvt.l.s x1, f1)
+  TEST_CASE( 55, x1, 0x7fffffffffffffff, la x1, tdat  ; flw f1, 12(x1); fcvt.l.s x1, f1)
+#endif
+
+  # test NaN, infinity conversions to unsigned integer
+  TEST_CASE( 62, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1,  0(x1); fcvt.wu.s x1, f1)
+  TEST_CASE( 63, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1,  4(x1); fcvt.wu.s x1, f1)
+  TEST_CASE( 64, x1,                  0, la x1, tdat  ; flw f1,  8(x1); fcvt.wu.s x1, f1)
+  TEST_CASE( 65, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1, 12(x1); fcvt.wu.s x1, f1)
+#if __riscv_xlen >= 64
+  TEST_CASE( 66, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1,  0(x1); fcvt.lu.s x1, f1)
+  TEST_CASE( 67, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1,  4(x1); fcvt.lu.s x1, f1)
+  TEST_CASE( 68, x1,                  0, la x1, tdat  ; flw f1,  8(x1); fcvt.lu.s x1, f1)
+  TEST_CASE( 69, x1, 0xffffffffffffffff, la x1, tdat  ; flw f1, 12(x1); fcvt.lu.s x1, f1)
+#endif
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+# -NaN, NaN, -inf, +inf
+tdat:
+.word 0xffffffff
+.word 0x7fffffff
+.word 0xff800000
+.word 0x7f800000
+
+tdat_d:
+.dword 0xffffffffffffffff
+.dword 0x7fffffffffffffff
+.dword 0xfff0000000000000
+.dword 0x7ff0000000000000
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fdiv.S b/src/asmtest/isa/rv64uf/fdiv.S
new file mode 100644
index 0000000..a75a23d
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fdiv.S
@@ -0,0 +1,40 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fdiv.S
+#-----------------------------------------------------------------------------
+#
+# Test f{div|sqrt}.s instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_S(2,  fdiv.s, 1, 1.1557273520668288, 3.14159265, 2.71828182 );
+  TEST_FP_OP2_S(3,  fdiv.s, 1,-0.9991093838555584,      -1234,     1235.1 );
+  TEST_FP_OP2_S(4,  fdiv.s, 0,         3.14159265, 3.14159265,        1.0 );
+
+  TEST_FP_OP1_S(5,  fsqrt.s, 1, 1.7724538498928541, 3.14159265 );
+  TEST_FP_OP1_S(6,  fsqrt.s, 0,                100,      10000 );
+
+  TEST_FP_OP1_S_DWORD_RESULT(7,  fsqrt.s, 0x10, 0x7FC00000, -1.0 );
+
+  TEST_FP_OP1_S(8,  fsqrt.s, 1, 13.076696, 171.0);
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fmadd.S b/src/asmtest/isa/rv64uf/fmadd.S
new file mode 100644
index 0000000..241bead
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fmadd.S
@@ -0,0 +1,45 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fmadd.S
+#-----------------------------------------------------------------------------
+#
+# Test f[n]m{add|sub}.s and f[n]m{add|sub}.d instructions.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP3_S( 2,  fmadd.s, 0,                 3.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_S( 3,  fmadd.s, 1,              1236.2, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_S( 4,  fmadd.s, 0,               -12.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_S( 5, fnmadd.s, 0,                -3.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_S( 6, fnmadd.s, 1,             -1236.2, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_S( 7, fnmadd.s, 0,                12.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_S( 8,  fmsub.s, 0,                 1.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_S( 9,  fmsub.s, 1,                1234, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_S(10,  fmsub.s, 0,                -8.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_FP_OP3_S(11, fnmsub.s, 0,                -1.5,  1.0,        2.5,        1.0 );
+  TEST_FP_OP3_S(12, fnmsub.s, 1,               -1234, -1.0,    -1235.1,        1.1 );
+  TEST_FP_OP3_S(13, fnmsub.s, 0,                 8.0,  2.0,       -5.0,       -2.0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/fmin.S b/src/asmtest/isa/rv64uf/fmin.S
new file mode 100644
index 0000000..1f97533
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/fmin.S
@@ -0,0 +1,54 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fmin.S
+#-----------------------------------------------------------------------------
+#
+# Test f{min|max}.s instructinos.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_FP_OP2_S( 2,  fmin.s, 0,        1.0,        2.5,        1.0 );
+  TEST_FP_OP2_S( 3,  fmin.s, 0,    -1235.1,    -1235.1,        1.1 );
+  TEST_FP_OP2_S( 4,  fmin.s, 0,    -1235.1,        1.1,    -1235.1 );
+  TEST_FP_OP2_S( 5,  fmin.s, 0,    -1235.1,        NaN,    -1235.1 );
+  TEST_FP_OP2_S( 6,  fmin.s, 0, 0.00000001, 3.14159265, 0.00000001 );
+  TEST_FP_OP2_S( 7,  fmin.s, 0,       -2.0,       -1.0,       -2.0 );
+
+  TEST_FP_OP2_S(12,  fmax.s, 0,        2.5,        2.5,        1.0 );
+  TEST_FP_OP2_S(13,  fmax.s, 0,        1.1,    -1235.1,        1.1 );
+  TEST_FP_OP2_S(14,  fmax.s, 0,        1.1,        1.1,    -1235.1 );
+  TEST_FP_OP2_S(15,  fmax.s, 0,    -1235.1,        NaN,    -1235.1 );
+  TEST_FP_OP2_S(16,  fmax.s, 0, 3.14159265, 3.14159265, 0.00000001 );
+  TEST_FP_OP2_S(17,  fmax.s, 0,       -1.0,       -1.0,       -2.0 );
+
+  # FMAX(sNaN, x) = x
+  TEST_FP_OP2_S(20,  fmax.s, 0x10, 1.0, sNaNf, 1.0);
+  # FMAX(qNaN, qNaN) = canonical NaN
+  TEST_FP_OP2_S(21,  fmax.s, 0x00, qNaNf, NaN, NaN);
+
+  # -0.0 < +0.0
+  TEST_FP_OP2_S(30,  fmin.s, 0,       -0.0,       -0.0,        0.0 );
+  TEST_FP_OP2_S(31,  fmin.s, 0,       -0.0,        0.0,       -0.0 );
+  TEST_FP_OP2_S(32,  fmax.s, 0,        0.0,       -0.0,        0.0 );
+  TEST_FP_OP2_S(33,  fmax.s, 0,        0.0,        0.0,       -0.0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/ldst.S b/src/asmtest/isa/rv64uf/ldst.S
new file mode 100644
index 0000000..c35dd8d
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/ldst.S
@@ -0,0 +1,38 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ldst.S
+#-----------------------------------------------------------------------------
+#
+# This test verifies that flw, fld, fsw, and fsd work properly.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a0, 0x40000000deadbeef, la a1, tdat; flw f1, 4(a1); fsw f1, 20(a1); ld a0, 16(a1))
+  TEST_CASE(3, a0, 0x1337d00dbf800000, la a1, tdat; flw f1, 0(a1); fsw f1, 24(a1); ld a0, 24(a1))
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+.word 0xbf800000
+.word 0x40000000
+.word 0x40400000
+.word 0xc0800000
+.word 0xdeadbeef
+.word 0xcafebabe
+.word 0xabad1dea
+.word 0x1337d00d
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/move.S b/src/asmtest/isa/rv64uf/move.S
new file mode 100644
index 0000000..60f7cf3
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/move.S
@@ -0,0 +1,58 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# move.S
+#-----------------------------------------------------------------------------
+#
+# This test verifies that the fmv.s.x, fmv.x.s, and fsgnj[x|n].d instructions
+# and the fcsr work properly.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a1, 1, csrwi fcsr, 1; li a0, 0x1234; fssr a1, a0)
+  TEST_CASE(3, a0, 0x34, frsr a0)
+  TEST_CASE(4, a0, 0x14, frflags a0)
+  TEST_CASE(5, a0, 0x01, csrrwi a0, frm, 2)
+  TEST_CASE(6, a0, 0x54, frsr a0)
+  TEST_CASE(7, a0, 0x14, csrrci a0, fflags, 4)
+  TEST_CASE(8, a0, 0x50, frsr a0)
+
+#define TEST_FSGNJS(n, insn, new_sign, rs1_sign, rs2_sign) \
+  TEST_CASE(n, a0, 0x12345678 | (-(new_sign) << 31), \
+    li a1, ((rs1_sign) << 31) | 0x12345678; \
+    li a2, -(rs2_sign); \
+    fmv.s.x f1, a1; \
+    fmv.s.x f2, a2; \
+    insn f0, f1, f2; \
+    fmv.x.s a0, f0)
+
+  TEST_FSGNJS(10, fsgnj.s, 0, 0, 0)
+  TEST_FSGNJS(11, fsgnj.s, 1, 0, 1)
+  TEST_FSGNJS(12, fsgnj.s, 0, 1, 0)
+  TEST_FSGNJS(13, fsgnj.s, 1, 1, 1)
+
+  TEST_FSGNJS(20, fsgnjn.s, 1, 0, 0)
+  TEST_FSGNJS(21, fsgnjn.s, 0, 0, 1)
+  TEST_FSGNJS(22, fsgnjn.s, 1, 1, 0)
+  TEST_FSGNJS(23, fsgnjn.s, 0, 1, 1)
+
+  TEST_FSGNJS(30, fsgnjx.s, 0, 0, 0)
+  TEST_FSGNJS(31, fsgnjx.s, 1, 0, 1)
+  TEST_FSGNJS(32, fsgnjx.s, 1, 1, 0)
+  TEST_FSGNJS(33, fsgnjx.s, 0, 1, 1)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64uf/recoding.S b/src/asmtest/isa/rv64uf/recoding.S
new file mode 100644
index 0000000..802be66
--- /dev/null
+++ b/src/asmtest/isa/rv64uf/recoding.S
@@ -0,0 +1,46 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# recoding.S
+#-----------------------------------------------------------------------------
+#
+# Test corner cases of John Hauser's microarchitectural recoding scheme.
+# There are twice as many recoded values as IEEE-754 values; some of these
+# extras are redundant (e.g. Inf) and others are illegal (subnormals with
+# too many bits set).
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+  # Make sure infinities with different mantissas compare as equal.
+  flw f0, minf, a0
+  flw f1, three, a0
+  fmul.s f1, f1, f0
+  TEST_CASE( 2, a0, 1, feq.s a0, f0, f1)
+  TEST_CASE( 3, a0, 1, fle.s a0, f0, f1)
+  TEST_CASE( 4, a0, 0, flt.s a0, f0, f1)
+
+  # Likewise, but for zeroes.
+  fcvt.s.w f0, x0
+  li a0, 1
+  fcvt.s.w f1, a0
+  fmul.s f1, f1, f0
+  TEST_CASE(5, a0, 1, feq.s a0, f0, f1)
+  TEST_CASE(6, a0, 1, fle.s a0, f0, f1)
+  TEST_CASE(7, a0, 0, flt.s a0, f0, f1)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+minf: .float -Inf
+three: .float 3.0
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/Makefrag b/src/asmtest/isa/rv64ui/Makefrag
new file mode 100644
index 0000000..24ba30c
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/Makefrag
@@ -0,0 +1,28 @@
+#=======================================================================
+# Makefrag for rv64ui tests
+#-----------------------------------------------------------------------
+
+rv64ui_sc_tests = \
+	add addi addiw addw \
+	and andi \
+	auipc \
+	beq bge bgeu blt bltu bne \
+	simple \
+	fence_i \
+	jal jalr \
+	lb lbu lh lhu lw lwu ld \
+	lui \
+	or ori \
+	sb sh sw sd \
+	sll slli slliw sllw \
+	slt slti sltiu sltu \
+	sra srai sraiw sraw \
+	srl srli srliw srlw \
+	sub subw \
+	xor xori \
+
+rv64ui_p_tests = $(addprefix rv64ui-p-, $(rv64ui_sc_tests))
+rv64ui_v_tests = $(addprefix rv64ui-v-, $(rv64ui_sc_tests))
+rv64ui_ps_tests = $(addprefix rv64ui-ps-, $(rv64ui_sc_tests))
+
+spike_tests += $(rv64ui_p_tests) $(rv64ui_v_tests)
diff --git a/src/asmtest/isa/rv64ui/add.S b/src/asmtest/isa/rv64ui/add.S
new file mode 100644
index 0000000..0696428
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/add.S
@@ -0,0 +1,85 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# add.S
+#-----------------------------------------------------------------------------
+#
+# Test add instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  add, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  add, 0x00000002, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  add, 0x0000000a, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  add, 0xffffffffffff8000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  add, 0xffffffff80000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  add, 0xffffffff7fff8000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 8,  add, 0x0000000000007fff, 0x0000000000000000, 0x0000000000007fff );
+  TEST_RR_OP( 9,  add, 0x000000007fffffff, 0x000000007fffffff, 0x0000000000000000 );
+  TEST_RR_OP( 10, add, 0x0000000080007ffe, 0x000000007fffffff, 0x0000000000007fff );
+
+  TEST_RR_OP( 11, add, 0xffffffff80007fff, 0xffffffff80000000, 0x0000000000007fff );
+  TEST_RR_OP( 12, add, 0x000000007fff7fff, 0x000000007fffffff, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 13, add, 0xffffffffffffffff, 0x0000000000000000, 0xffffffffffffffff );
+  TEST_RR_OP( 14, add, 0x0000000000000000, 0xffffffffffffffff, 0x0000000000000001 );
+  TEST_RR_OP( 15, add, 0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff );
+
+  TEST_RR_OP( 16, add, 0x0000000080000000, 0x0000000000000001, 0x000000007fffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 17, add, 24, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 18, add, 25, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 19, add, 26, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 20, 0, add, 24, 13, 11 );
+  TEST_RR_DEST_BYPASS( 21, 1, add, 25, 14, 11 );
+  TEST_RR_DEST_BYPASS( 22, 2, add, 26, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 23, 0, 0, add, 24, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 1, add, 25, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 25, 0, 2, add, 26, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 0, add, 24, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 27, 1, 1, add, 25, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 28, 2, 0, add, 26, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 29, 0, 0, add, 24, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 1, add, 25, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 31, 0, 2, add, 26, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 0, add, 24, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 33, 1, 1, add, 25, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 34, 2, 0, add, 26, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 35, add, 15, 15 );
+  TEST_RR_ZEROSRC2( 36, add, 32, 32 );
+  TEST_RR_ZEROSRC12( 37, add, 0 );
+  TEST_RR_ZERODEST( 38, add, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/addi.S b/src/asmtest/isa/rv64ui/addi.S
new file mode 100644
index 0000000..e6b67ca
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/addi.S
@@ -0,0 +1,71 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# addi.S
+#-----------------------------------------------------------------------------
+#
+# Test addi instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  addi, 0x00000000, 0x00000000, 0x000 );
+  TEST_IMM_OP( 3,  addi, 0x00000002, 0x00000001, 0x001 );
+  TEST_IMM_OP( 4,  addi, 0x0000000a, 0x00000003, 0x007 );
+
+  TEST_IMM_OP( 5,  addi, 0xfffffffffffff800, 0x0000000000000000, 0x800 );
+  TEST_IMM_OP( 6,  addi, 0xffffffff80000000, 0xffffffff80000000, 0x000 );
+  TEST_IMM_OP( 7,  addi, 0xffffffff7ffff800, 0xffffffff80000000, 0x800 );
+
+  TEST_IMM_OP( 8,  addi, 0x00000000000007ff, 0x00000000, 0x7ff );
+  TEST_IMM_OP( 9,  addi, 0x000000007fffffff, 0x7fffffff, 0x000 );
+  TEST_IMM_OP( 10, addi, 0x00000000800007fe, 0x7fffffff, 0x7ff );
+
+  TEST_IMM_OP( 11, addi, 0xffffffff800007ff, 0xffffffff80000000, 0x7ff );
+  TEST_IMM_OP( 12, addi, 0x000000007ffff7ff, 0x000000007fffffff, 0x800 );
+
+  TEST_IMM_OP( 13, addi, 0xffffffffffffffff, 0x0000000000000000, 0xfff );
+  TEST_IMM_OP( 14, addi, 0x0000000000000000, 0xffffffffffffffff, 0x001 );
+  TEST_IMM_OP( 15, addi, 0xfffffffffffffffe, 0xffffffffffffffff, 0xfff );
+
+  TEST_IMM_OP( 16, addi, 0x0000000080000000, 0x7fffffff, 0x001 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, addi, 24, 13, 11 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, addi, 24, 13, 11 );
+  TEST_IMM_DEST_BYPASS( 19, 1, addi, 23, 13, 10 );
+  TEST_IMM_DEST_BYPASS( 20, 2, addi, 22, 13,  9 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, addi, 24, 13, 11 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, addi, 23, 13, 10 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, addi, 22, 13,  9 );
+
+  TEST_IMM_ZEROSRC1( 24, addi, 32, 32 );
+  TEST_IMM_ZERODEST( 25, addi, 33, 50 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/addiw.S b/src/asmtest/isa/rv64ui/addiw.S
new file mode 100644
index 0000000..c0f9a61
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/addiw.S
@@ -0,0 +1,71 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# addiw.S
+#-----------------------------------------------------------------------------
+#
+# Test addiw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  addiw, 0x00000000, 0x00000000, 0x000 );
+  TEST_IMM_OP( 3,  addiw, 0x00000002, 0x00000001, 0x001 );
+  TEST_IMM_OP( 4,  addiw, 0x0000000a, 0x00000003, 0x007 );
+
+  TEST_IMM_OP( 5,  addiw, 0xfffffffffffff800, 0x0000000000000000, 0x800 );
+  TEST_IMM_OP( 6,  addiw, 0xffffffff80000000, 0xffffffff80000000, 0x000 );
+  TEST_IMM_OP( 7,  addiw, 0x000000007ffff800, 0xffffffff80000000, 0x800 );
+
+  TEST_IMM_OP( 8,  addiw, 0x00000000000007ff, 0x00000000, 0x7ff );
+  TEST_IMM_OP( 9,  addiw, 0x000000007fffffff, 0x7fffffff, 0x000 );
+  TEST_IMM_OP( 10, addiw, 0xffffffff800007fe, 0x7fffffff, 0x7ff );
+
+  TEST_IMM_OP( 11, addiw, 0xffffffff800007ff, 0xffffffff80000000, 0x7ff );
+  TEST_IMM_OP( 12, addiw, 0x000000007ffff7ff, 0x000000007fffffff, 0x800 );
+
+  TEST_IMM_OP( 13, addiw, 0xffffffffffffffff, 0x0000000000000000, 0xfff );
+  TEST_IMM_OP( 14, addiw, 0x0000000000000000, 0xffffffffffffffff, 0x001 );
+  TEST_IMM_OP( 15, addiw, 0xfffffffffffffffe, 0xffffffffffffffff, 0xfff );
+
+  TEST_IMM_OP( 16, addiw, 0xffffffff80000000, 0x7fffffff, 0x001 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, addiw, 24, 13, 11 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, addiw, 24, 13, 11 );
+  TEST_IMM_DEST_BYPASS( 19, 1, addiw, 23, 13, 10 );
+  TEST_IMM_DEST_BYPASS( 20, 2, addiw, 22, 13,  9 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, addiw, 24, 13, 11 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, addiw, 23, 13, 10 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, addiw, 22, 13,  9 );
+
+  TEST_IMM_ZEROSRC1( 24, addiw, 32, 32 );
+  TEST_IMM_ZERODEST( 25, addiw, 33, 50 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/addw.S b/src/asmtest/isa/rv64ui/addw.S
new file mode 100644
index 0000000..ad7fe0b
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/addw.S
@@ -0,0 +1,85 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# addw.S
+#-----------------------------------------------------------------------------
+#
+# Test addw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  addw, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  addw, 0x00000002, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  addw, 0x0000000a, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  addw, 0xffffffffffff8000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  addw, 0xffffffff80000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  addw, 0x000000007fff8000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 8,  addw, 0x0000000000007fff, 0x0000000000000000, 0x0000000000007fff );
+  TEST_RR_OP( 9,  addw, 0x000000007fffffff, 0x000000007fffffff, 0x0000000000000000 );
+  TEST_RR_OP( 10, addw, 0xffffffff80007ffe, 0x000000007fffffff, 0x0000000000007fff );
+
+  TEST_RR_OP( 11, addw, 0xffffffff80007fff, 0xffffffff80000000, 0x0000000000007fff );
+  TEST_RR_OP( 12, addw, 0x000000007fff7fff, 0x000000007fffffff, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 13, addw, 0xffffffffffffffff, 0x0000000000000000, 0xffffffffffffffff );
+  TEST_RR_OP( 14, addw, 0x0000000000000000, 0xffffffffffffffff, 0x0000000000000001 );
+  TEST_RR_OP( 15, addw, 0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff );
+
+  TEST_RR_OP( 16, addw, 0xffffffff80000000, 0x0000000000000001, 0x000000007fffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 17, addw, 24, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 18, addw, 25, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 19, addw, 26, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 20, 0, addw, 24, 13, 11 );
+  TEST_RR_DEST_BYPASS( 21, 1, addw, 25, 14, 11 );
+  TEST_RR_DEST_BYPASS( 22, 2, addw, 26, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 23, 0, 0, addw, 24, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 1, addw, 25, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 25, 0, 2, addw, 26, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 0, addw, 24, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 27, 1, 1, addw, 25, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 28, 2, 0, addw, 26, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 29, 0, 0, addw, 24, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 1, addw, 25, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 31, 0, 2, addw, 26, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 0, addw, 24, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 33, 1, 1, addw, 25, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 34, 2, 0, addw, 26, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 35, addw, 15, 15 );
+  TEST_RR_ZEROSRC2( 36, addw, 32, 32 );
+  TEST_RR_ZEROSRC12( 37, addw, 0 );
+  TEST_RR_ZERODEST( 38, addw, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/and.S b/src/asmtest/isa/rv64ui/and.S
new file mode 100644
index 0000000..3f63790
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/and.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# and.S
+#-----------------------------------------------------------------------------
+#
+# Test and instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_OP( 3, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_OP( 4, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_OP( 5, and, 0xf000f000, 0xf00ff00f, 0xf0f0f0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 6, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC2_EQ_DEST( 7, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_EQ_DEST( 8, and, 0xff00ff00, 0xff00ff00 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 9,  0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_DEST_BYPASS( 10, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_DEST_BYPASS( 11, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC12_BYPASS( 12, 0, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 13, 0, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 14, 0, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 15, 1, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 16, 1, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 17, 2, 0, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC21_BYPASS( 18, 0, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 19, 0, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 20, 0, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 21, 1, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 22, 1, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 23, 2, 0, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_ZEROSRC1( 24, and, 0, 0xff00ff00 );
+  TEST_RR_ZEROSRC2( 25, and, 0, 0x00ff00ff );
+  TEST_RR_ZEROSRC12( 26, and, 0 );
+  TEST_RR_ZERODEST( 27, and, 0x11111111, 0x22222222 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/andi.S b/src/asmtest/isa/rv64ui/andi.S
new file mode 100644
index 0000000..913af9d
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/andi.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# andi.S
+#-----------------------------------------------------------------------------
+#
+# Test andi instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2, andi, 0xff00ff00, 0xff00ff00, 0xf0f );
+  TEST_IMM_OP( 3, andi, 0x000000f0, 0x0ff00ff0, 0x0f0 );
+  TEST_IMM_OP( 4, andi, 0x0000000f, 0x00ff00ff, 0x70f );
+  TEST_IMM_OP( 5, andi, 0x00000000, 0xf00ff00f, 0x0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 6, andi, 0x00000000, 0xff00ff00, 0x0f0 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 7,  0, andi, 0x00000700, 0x0ff00ff0, 0x70f );
+  TEST_IMM_DEST_BYPASS( 8,  1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 );
+  TEST_IMM_DEST_BYPASS( 9,  2, andi, 0xf00ff00f, 0xf00ff00f, 0xf0f );
+
+  TEST_IMM_SRC1_BYPASS( 10, 0, andi, 0x00000700, 0x0ff00ff0, 0x70f );
+  TEST_IMM_SRC1_BYPASS( 11, 1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 );
+  TEST_IMM_SRC1_BYPASS( 12, 2, andi, 0x0000000f, 0xf00ff00f, 0x70f );
+
+  TEST_IMM_ZEROSRC1( 13, andi, 0, 0x0f0 );
+  TEST_IMM_ZERODEST( 14, andi, 0x00ff00ff, 0x70f );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/auipc.S b/src/asmtest/isa/rv64ui/auipc.S
new file mode 100644
index 0000000..6fe5962
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/auipc.S
@@ -0,0 +1,39 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# auipc.S
+#-----------------------------------------------------------------------------
+#
+# Test auipc instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  TEST_CASE(2, a0, 10000, \
+    .align 3; \
+    lla a0, 1f + 10000; \
+    jal a1, 1f; \
+    1: sub a0, a0, a1; \
+  )
+
+  TEST_CASE(3, a0, -10000, \
+    .align 3; \
+    lla a0, 1f - 10000; \
+    jal a1, 1f; \
+    1: sub a0, a0, a1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/beq.S b/src/asmtest/isa/rv64ui/beq.S
new file mode 100644
index 0000000..436db8c
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/beq.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# beq.S
+#-----------------------------------------------------------------------------
+#
+# Test beq instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, beq,  0,  0 );
+  TEST_BR2_OP_TAKEN( 3, beq,  1,  1 );
+  TEST_BR2_OP_TAKEN( 4, beq, -1, -1 );
+
+  TEST_BR2_OP_NOTTAKEN( 5, beq,  0,  1 );
+  TEST_BR2_OP_NOTTAKEN( 6, beq,  1,  0 );
+  TEST_BR2_OP_NOTTAKEN( 7, beq, -1,  1 );
+  TEST_BR2_OP_NOTTAKEN( 8, beq,  1, -1 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 9,  0, 0, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 10, 0, 1, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 11, 0, 2, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 12, 1, 0, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 13, 1, 1, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 14, 2, 0, beq, 0, -1 );
+
+  TEST_BR2_SRC12_BYPASS( 15, 0, 0, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 16, 0, 1, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 17, 0, 2, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 18, 1, 0, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 19, 1, 1, beq, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 20, 2, 0, beq, 0, -1 );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 21, x1, 3, \
+    li  x1, 1; \
+    beq x0, x0, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/bge.S b/src/asmtest/isa/rv64ui/bge.S
new file mode 100644
index 0000000..04aebbc
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/bge.S
@@ -0,0 +1,76 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bge.S
+#-----------------------------------------------------------------------------
+#
+# Test bge instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, bge,  0,  0 );
+  TEST_BR2_OP_TAKEN( 3, bge,  1,  1 );
+  TEST_BR2_OP_TAKEN( 4, bge, -1, -1 );
+  TEST_BR2_OP_TAKEN( 5, bge,  1,  0 );
+  TEST_BR2_OP_TAKEN( 6, bge,  1, -1 );
+  TEST_BR2_OP_TAKEN( 7, bge, -1, -2 );
+
+  TEST_BR2_OP_NOTTAKEN(  8, bge,  0,  1 );
+  TEST_BR2_OP_NOTTAKEN(  9, bge, -1,  1 );
+  TEST_BR2_OP_NOTTAKEN( 10, bge, -2, -1 );
+  TEST_BR2_OP_NOTTAKEN( 11, bge, -2,  1 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 12, 0, 0, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 13, 0, 1, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 14, 0, 2, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 15, 1, 0, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 16, 1, 1, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 17, 2, 0, bge, -1, 0 );
+
+  TEST_BR2_SRC12_BYPASS( 18, 0, 0, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 19, 0, 1, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 20, 0, 2, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 21, 1, 0, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 22, 1, 1, bge, -1, 0 );
+  TEST_BR2_SRC12_BYPASS( 23, 2, 0, bge, -1, 0 );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 24, x1, 3, \
+    li  x1, 1; \
+    bge x1, x0, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/bgeu.S b/src/asmtest/isa/rv64ui/bgeu.S
new file mode 100644
index 0000000..36b6b3a
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/bgeu.S
@@ -0,0 +1,76 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bgeu.S
+#-----------------------------------------------------------------------------
+#
+# Test bgeu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, bgeu, 0x00000000, 0x00000000 );
+  TEST_BR2_OP_TAKEN( 3, bgeu, 0x00000001, 0x00000001 );
+  TEST_BR2_OP_TAKEN( 4, bgeu, 0xffffffff, 0xffffffff );
+  TEST_BR2_OP_TAKEN( 5, bgeu, 0x00000001, 0x00000000 );
+  TEST_BR2_OP_TAKEN( 6, bgeu, 0xffffffff, 0xfffffffe );
+  TEST_BR2_OP_TAKEN( 7, bgeu, 0xffffffff, 0x00000000 );
+
+  TEST_BR2_OP_NOTTAKEN(  8, bgeu, 0x00000000, 0x00000001 );
+  TEST_BR2_OP_NOTTAKEN(  9, bgeu, 0xfffffffe, 0xffffffff );
+  TEST_BR2_OP_NOTTAKEN( 10, bgeu, 0x00000000, 0xffffffff );
+  TEST_BR2_OP_NOTTAKEN( 11, bgeu, 0x7fffffff, 0x80000000 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 12, 0, 0, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 13, 0, 1, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 14, 0, 2, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 15, 1, 0, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 16, 1, 1, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 17, 2, 0, bgeu, 0xefffffff, 0xf0000000 );
+
+  TEST_BR2_SRC12_BYPASS( 18, 0, 0, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 19, 0, 1, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 20, 0, 2, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 21, 1, 0, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 22, 1, 1, bgeu, 0xefffffff, 0xf0000000 );
+  TEST_BR2_SRC12_BYPASS( 23, 2, 0, bgeu, 0xefffffff, 0xf0000000 );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 24, x1, 3, \
+    li  x1, 1; \
+    bgeu x1, x0, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/blt.S b/src/asmtest/isa/rv64ui/blt.S
new file mode 100644
index 0000000..1c0ca69
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/blt.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# blt.S
+#-----------------------------------------------------------------------------
+#
+# Test blt instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, blt,  0,  1 );
+  TEST_BR2_OP_TAKEN( 3, blt, -1,  1 );
+  TEST_BR2_OP_TAKEN( 4, blt, -2, -1 );
+
+  TEST_BR2_OP_NOTTAKEN( 5, blt,  1,  0 );
+  TEST_BR2_OP_NOTTAKEN( 6, blt,  1, -1 );
+  TEST_BR2_OP_NOTTAKEN( 7, blt, -1, -2 );
+  TEST_BR2_OP_NOTTAKEN( 8, blt,  1, -2 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 9,  0, 0, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 10, 0, 1, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 11, 0, 2, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 12, 1, 0, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 13, 1, 1, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 14, 2, 0, blt, 0, -1 );
+
+  TEST_BR2_SRC12_BYPASS( 15, 0, 0, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 16, 0, 1, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 17, 0, 2, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 18, 1, 0, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 19, 1, 1, blt, 0, -1 );
+  TEST_BR2_SRC12_BYPASS( 20, 2, 0, blt, 0, -1 );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 21, x1, 3, \
+    li  x1, 1; \
+    blt x0, x1, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/bltu.S b/src/asmtest/isa/rv64ui/bltu.S
new file mode 100644
index 0000000..4e880d6
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/bltu.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bltu.S
+#-----------------------------------------------------------------------------
+#
+# Test bltu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, bltu, 0x00000000, 0x00000001 );
+  TEST_BR2_OP_TAKEN( 3, bltu, 0xfffffffe, 0xffffffff );
+  TEST_BR2_OP_TAKEN( 4, bltu, 0x00000000, 0xffffffff );
+
+  TEST_BR2_OP_NOTTAKEN( 5, bltu, 0x00000001, 0x00000000 );
+  TEST_BR2_OP_NOTTAKEN( 6, bltu, 0xffffffff, 0xfffffffe );
+  TEST_BR2_OP_NOTTAKEN( 7, bltu, 0xffffffff, 0x00000000 );
+  TEST_BR2_OP_NOTTAKEN( 8, bltu, 0x80000000, 0x7fffffff );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 9,  0, 0, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 10, 0, 1, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 11, 0, 2, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 12, 1, 0, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 13, 1, 1, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 14, 2, 0, bltu, 0xf0000000, 0xefffffff );
+
+  TEST_BR2_SRC12_BYPASS( 15, 0, 0, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 16, 0, 1, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 17, 0, 2, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 18, 1, 0, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 19, 1, 1, bltu, 0xf0000000, 0xefffffff );
+  TEST_BR2_SRC12_BYPASS( 20, 2, 0, bltu, 0xf0000000, 0xefffffff );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 21, x1, 3, \
+    li  x1, 1; \
+    bltu x0, x1, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/bne.S b/src/asmtest/isa/rv64ui/bne.S
new file mode 100644
index 0000000..3ca4e6c
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/bne.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bne.S
+#-----------------------------------------------------------------------------
+#
+# Test bne instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Branch tests
+  #-------------------------------------------------------------
+
+  # Each test checks both forward and backward branches
+
+  TEST_BR2_OP_TAKEN( 2, bne,  0,  1 );
+  TEST_BR2_OP_TAKEN( 3, bne,  1,  0 );
+  TEST_BR2_OP_TAKEN( 4, bne, -1,  1 );
+  TEST_BR2_OP_TAKEN( 5, bne,  1, -1 );
+
+  TEST_BR2_OP_NOTTAKEN( 6, bne,  0,  0 );
+  TEST_BR2_OP_NOTTAKEN( 7, bne,  1,  1 );
+  TEST_BR2_OP_NOTTAKEN( 8, bne, -1, -1 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_BR2_SRC12_BYPASS( 9,  0, 0, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 10, 0, 1, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 11, 0, 2, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 12, 1, 0, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 13, 1, 1, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 14, 2, 0, bne, 0, 0 );
+
+  TEST_BR2_SRC12_BYPASS( 15, 0, 0, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 16, 0, 1, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 17, 0, 2, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 18, 1, 0, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 19, 1, 1, bne, 0, 0 );
+  TEST_BR2_SRC12_BYPASS( 20, 2, 0, bne, 0, 0 );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 21, x1, 3, \
+    li  x1, 1; \
+    bne x1, x0, 1f; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+    addi x1, x1, 1; \
+1:  addi x1, x1, 1; \
+    addi x1, x1, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/fence_i.S b/src/asmtest/isa/rv64ui/fence_i.S
new file mode 100644
index 0000000..cd0fe56
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/fence_i.S
@@ -0,0 +1,54 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fence_i.S
+#-----------------------------------------------------------------------------
+#
+# Test self-modifying code and the fence.i instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+li a3, 111
+lh a0, insn
+lh a1, insn+2
+
+# test I$ hit
+.align 6
+sh a0, 1f, t0
+sh a1, 1f+2, t0
+fence.i
+
+1: addi a3, a3, 222
+TEST_CASE( 2, a3, 444, nop )
+
+# test prefetcher hit
+li a4, 100
+1: addi a4, a4, -1
+bnez a4, 1b
+
+sh a0, 1f, t0
+sh a1, 1f+2, t0
+fence.i
+
+.align 6
+1: addi a3, a3, 555
+TEST_CASE( 3, a3, 777, nop )
+
+TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+insn:
+  addi a3, a3, 333
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/jal.S b/src/asmtest/isa/rv64ui/jal.S
new file mode 100644
index 0000000..00c65d8
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/jal.S
@@ -0,0 +1,59 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# jal.S
+#-----------------------------------------------------------------------------
+#
+# Test jal instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Test 2: Basic test
+  #-------------------------------------------------------------
+
+test_2:
+  li  TESTNUM, 2
+  li  ra, 0
+
+  jal x4, target_2
+linkaddr_2:
+  nop
+  nop
+
+  j fail
+
+target_2:
+  la  x2, linkaddr_2
+  bne x2, x4, fail
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  TEST_CASE( 3, ra, 3, \
+    li  ra, 1; \
+    jal x0, 1f; \
+    addi ra, ra, 1; \
+    addi ra, ra, 1; \
+    addi ra, ra, 1; \
+    addi ra, ra, 1; \
+1:  addi ra, ra, 1; \
+    addi ra, ra, 1; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/jalr.S b/src/asmtest/isa/rv64ui/jalr.S
new file mode 100644
index 0000000..c922b11
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/jalr.S
@@ -0,0 +1,86 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# jalr.S
+#-----------------------------------------------------------------------------
+#
+# Test jalr instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Test 2: Basic test
+  #-------------------------------------------------------------
+
+test_2:
+  li  TESTNUM, 2
+  li  t0, 0
+  la  t1, target_2
+
+  jalr t0, t1, 0
+linkaddr_2:
+  j fail
+
+target_2:
+  la  t1, linkaddr_2
+  bne t0, t1, fail
+
+  #-------------------------------------------------------------
+  # Test 3: Basic test2, rs = rd
+  #-------------------------------------------------------------
+
+test_3:
+  li  TESTNUM, 3
+  la  t0, target_3
+
+  jalr t0, t0, 0
+linkaddr_3:
+  j fail
+
+target_3:
+  la  t1, linkaddr_3
+  bne t0, t1, fail
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_JALR_SRC1_BYPASS( 4, 0, jalr );
+  TEST_JALR_SRC1_BYPASS( 5, 1, jalr );
+  TEST_JALR_SRC1_BYPASS( 6, 2, jalr );
+
+  #-------------------------------------------------------------
+  # Test delay slot instructions not executed nor bypassed
+  #-------------------------------------------------------------
+
+  .option push
+  .align 2
+  .option norvc
+  TEST_CASE( 7, t0, 4, \
+    li  t0, 1; \
+    la  t1, 1f; \
+    jr  t1, -4; \
+    addi t0, t0, 1; \
+    addi t0, t0, 1; \
+    addi t0, t0, 1; \
+    addi t0, t0, 1; \
+1:  addi t0, t0, 1; \
+    addi t0, t0, 1; \
+  )
+  .option pop
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lb.S b/src/asmtest/isa/rv64ui/lb.S
new file mode 100644
index 0000000..856dfe9
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lb.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lb.S
+#-----------------------------------------------------------------------------
+#
+# Test lb instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lb, 0xffffffffffffffff, 0,  tdat );
+  TEST_LD_OP( 3, lb, 0x0000000000000000, 1,  tdat );
+  TEST_LD_OP( 4, lb, 0xfffffffffffffff0, 2,  tdat );
+  TEST_LD_OP( 5, lb, 0x000000000000000f, 3, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lb, 0xffffffffffffffff, -3, tdat4 );
+  TEST_LD_OP( 7, lb, 0x0000000000000000, -2,  tdat4 );
+  TEST_LD_OP( 8, lb, 0xfffffffffffffff0, -1,  tdat4 );
+  TEST_LD_OP( 9, lb, 0x000000000000000f, 0,   tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0xffffffffffffffff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lb x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x0000000000000000, \
+    la  x1, tdat; \
+    addi x1, x1, -6; \
+    lb x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lb, 0xfffffffffffffff0, 1, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lb, 0x000000000000000f, 1, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lb, 0x0000000000000000, 1, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lb, 0xfffffffffffffff0, 1, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lb, 0x000000000000000f, 1, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lb, 0x0000000000000000, 1, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lb  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lb  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .byte 0xff
+tdat2:  .byte 0x00
+tdat3:  .byte 0xf0
+tdat4:  .byte 0x0f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lbu.S b/src/asmtest/isa/rv64ui/lbu.S
new file mode 100644
index 0000000..adc3a05
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lbu.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lbu.S
+#-----------------------------------------------------------------------------
+#
+# Test lbu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lbu, 0x00000000000000ff, 0,  tdat );
+  TEST_LD_OP( 3, lbu, 0x0000000000000000, 1,  tdat );
+  TEST_LD_OP( 4, lbu, 0x00000000000000f0, 2,  tdat );
+  TEST_LD_OP( 5, lbu, 0x000000000000000f, 3, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lbu, 0x00000000000000ff, -3, tdat4 );
+  TEST_LD_OP( 7, lbu, 0x0000000000000000, -2,  tdat4 );
+  TEST_LD_OP( 8, lbu, 0x00000000000000f0, -1,  tdat4 );
+  TEST_LD_OP( 9, lbu, 0x000000000000000f, 0,   tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x00000000000000ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lbu x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x0000000000000000, \
+    la  x1, tdat; \
+    addi x1, x1, -6; \
+    lbu x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lbu, 0x00000000000000f0, 1, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lbu, 0x000000000000000f, 1, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lbu, 0x0000000000000000, 1, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lbu, 0x00000000000000f0, 1, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lbu, 0x000000000000000f, 1, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lbu, 0x0000000000000000, 1, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lbu  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lbu  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .byte 0xff
+tdat2:  .byte 0x00
+tdat3:  .byte 0xf0
+tdat4:  .byte 0x0f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/ld.S b/src/asmtest/isa/rv64ui/ld.S
new file mode 100644
index 0000000..948c34b
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/ld.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ld.S
+#-----------------------------------------------------------------------------
+#
+# Test ld instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, ld, 0x00ff00ff00ff00ff, 0,  tdat );
+  TEST_LD_OP( 3, ld, 0xff00ff00ff00ff00, 8,  tdat );
+  TEST_LD_OP( 4, ld, 0x0ff00ff00ff00ff0, 16, tdat );
+  TEST_LD_OP( 5, ld, 0xf00ff00ff00ff00f, 24, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, ld, 0x00ff00ff00ff00ff, -24, tdat4 );
+  TEST_LD_OP( 7, ld, 0xff00ff00ff00ff00, -16, tdat4 );
+  TEST_LD_OP( 8, ld, 0x0ff00ff00ff00ff0, -8,  tdat4 );
+  TEST_LD_OP( 9, ld, 0xf00ff00ff00ff00f, 0,   tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x00ff00ff00ff00ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    ld x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0xff00ff00ff00ff00, \
+    la  x1, tdat; \
+    addi x1, x1, -3; \
+    ld x5, 11(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, ld, 0x0ff00ff00ff00ff0, 8, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, ld, 0xf00ff00ff00ff00f, 8, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, ld, 0xff00ff00ff00ff00, 8, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, ld, 0x0ff00ff00ff00ff0, 8, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, ld, 0xf00ff00ff00ff00f, 8, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, ld, 0xff00ff00ff00ff00, 8, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    ld  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    ld  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .dword 0x00ff00ff00ff00ff
+tdat2:  .dword 0xff00ff00ff00ff00
+tdat3:  .dword 0x0ff00ff00ff00ff0
+tdat4:  .dword 0xf00ff00ff00ff00f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lh.S b/src/asmtest/isa/rv64ui/lh.S
new file mode 100644
index 0000000..338ed69
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lh.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lh.S
+#-----------------------------------------------------------------------------
+#
+# Test lh instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lh, 0x00000000000000ff, 0,  tdat );
+  TEST_LD_OP( 3, lh, 0xffffffffffffff00, 2,  tdat );
+  TEST_LD_OP( 4, lh, 0x0000000000000ff0, 4,  tdat );
+  TEST_LD_OP( 5, lh, 0xfffffffffffff00f, 6, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lh, 0x00000000000000ff, -6,  tdat4 );
+  TEST_LD_OP( 7, lh, 0xffffffffffffff00, -4,  tdat4 );
+  TEST_LD_OP( 8, lh, 0x0000000000000ff0, -2,  tdat4 );
+  TEST_LD_OP( 9, lh, 0xfffffffffffff00f,  0, tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x00000000000000ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lh x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0xffffffffffffff00, \
+    la  x1, tdat; \
+    addi x1, x1, -5; \
+    lh x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lh, 0x0000000000000ff0, 2, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lh, 0xfffffffffffff00f, 2, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lh, 0xffffffffffffff00, 2, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lh, 0x0000000000000ff0, 2, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lh, 0xfffffffffffff00f, 2, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lh, 0xffffffffffffff00, 2, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lh  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lh  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .half 0x00ff
+tdat2:  .half 0xff00
+tdat3:  .half 0x0ff0
+tdat4:  .half 0xf00f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lhu.S b/src/asmtest/isa/rv64ui/lhu.S
new file mode 100644
index 0000000..a4cc49b
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lhu.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lhu.S
+#-----------------------------------------------------------------------------
+#
+# Test lhu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lhu, 0x00000000000000ff, 0,  tdat );
+  TEST_LD_OP( 3, lhu, 0x000000000000ff00, 2,  tdat );
+  TEST_LD_OP( 4, lhu, 0x0000000000000ff0, 4,  tdat );
+  TEST_LD_OP( 5, lhu, 0x000000000000f00f, 6, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lhu, 0x00000000000000ff, -6,  tdat4 );
+  TEST_LD_OP( 7, lhu, 0x000000000000ff00, -4,  tdat4 );
+  TEST_LD_OP( 8, lhu, 0x0000000000000ff0, -2,  tdat4 );
+  TEST_LD_OP( 9, lhu, 0x000000000000f00f,  0, tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x00000000000000ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lhu x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x000000000000ff00, \
+    la  x1, tdat; \
+    addi x1, x1, -5; \
+    lhu x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lhu, 0x0000000000000ff0, 2, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lhu, 0x000000000000f00f, 2, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lhu, 0x000000000000ff00, 2, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lhu, 0x0000000000000ff0, 2, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lhu, 0x000000000000f00f, 2, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lhu, 0x000000000000ff00, 2, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lhu  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lhu  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .half 0x00ff
+tdat2:  .half 0xff00
+tdat3:  .half 0x0ff0
+tdat4:  .half 0xf00f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lui.S b/src/asmtest/isa/rv64ui/lui.S
new file mode 100644
index 0000000..8a4e70c
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lui.S
@@ -0,0 +1,36 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lui.S
+#-----------------------------------------------------------------------------
+#
+# Test lui instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_CASE( 2, x1, 0x0000000000000000, lui x1, 0x00000 );
+  TEST_CASE( 3, x1, 0xfffffffffffff800, lui x1, 0xfffff;sra x1,x1,1);
+  TEST_CASE( 4, x1, 0x00000000000007ff, lui x1, 0x7ffff;sra x1,x1,20);
+  TEST_CASE( 5, x1, 0xfffffffffffff800, lui x1, 0x80000;sra x1,x1,20);
+
+  TEST_CASE( 6, x0, 0, lui x0, 0x80000 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lw.S b/src/asmtest/isa/rv64ui/lw.S
new file mode 100644
index 0000000..40a73f1
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lw.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lw.S
+#-----------------------------------------------------------------------------
+#
+# Test lw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lw, 0x0000000000ff00ff, 0,  tdat );
+  TEST_LD_OP( 3, lw, 0xffffffffff00ff00, 4,  tdat );
+  TEST_LD_OP( 4, lw, 0x000000000ff00ff0, 8,  tdat );
+  TEST_LD_OP( 5, lw, 0xfffffffff00ff00f, 12, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lw, 0x0000000000ff00ff, -12, tdat4 );
+  TEST_LD_OP( 7, lw, 0xffffffffff00ff00, -8,  tdat4 );
+  TEST_LD_OP( 8, lw, 0x000000000ff00ff0, -4,  tdat4 );
+  TEST_LD_OP( 9, lw, 0xfffffffff00ff00f, 0,   tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x0000000000ff00ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lw x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0xffffffffff00ff00, \
+    la  x1, tdat; \
+    addi x1, x1, -3; \
+    lw x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lw, 0x000000000ff00ff0, 4, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lw, 0xfffffffff00ff00f, 4, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lw, 0xffffffffff00ff00, 4, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lw, 0x000000000ff00ff0, 4, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lw, 0xfffffffff00ff00f, 4, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lw, 0xffffffffff00ff00, 4, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lw  x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lw  x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .word 0x00ff00ff
+tdat2:  .word 0xff00ff00
+tdat3:  .word 0x0ff00ff0
+tdat4:  .word 0xf00ff00f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/lwu.S b/src/asmtest/isa/rv64ui/lwu.S
new file mode 100644
index 0000000..9f7cf67
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/lwu.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lwu.S
+#-----------------------------------------------------------------------------
+#
+# Test lwu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_LD_OP( 2, lwu, 0x0000000000ff00ff, 0,  tdat );
+  TEST_LD_OP( 3, lwu, 0x00000000ff00ff00, 4,  tdat );
+  TEST_LD_OP( 4, lwu, 0x000000000ff00ff0, 8,  tdat );
+  TEST_LD_OP( 5, lwu, 0x00000000f00ff00f, 12, tdat );
+
+  # Test with negative offset
+
+  TEST_LD_OP( 6, lwu, 0x0000000000ff00ff, -12, tdat4 );
+  TEST_LD_OP( 7, lwu, 0x00000000ff00ff00, -8,  tdat4 );
+  TEST_LD_OP( 8, lwu, 0x000000000ff00ff0, -4,  tdat4 );
+  TEST_LD_OP( 9, lwu, 0x00000000f00ff00f, 0,   tdat4 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x0000000000ff00ff, \
+    la  x1, tdat; \
+    addi x1, x1, -32; \
+    lwu x5, 32(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x00000000ff00ff00, \
+    la  x1, tdat; \
+    addi x1, x1, -3; \
+    lwu x5, 7(x1); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_LD_DEST_BYPASS( 12, 0, lwu, 0x000000000ff00ff0, 4, tdat2 );
+  TEST_LD_DEST_BYPASS( 13, 1, lwu, 0x00000000f00ff00f, 4, tdat3 );
+  TEST_LD_DEST_BYPASS( 14, 2, lwu, 0x00000000ff00ff00, 4, tdat1 );
+
+  TEST_LD_SRC1_BYPASS( 15, 0, lwu, 0x000000000ff00ff0, 4, tdat2 );
+  TEST_LD_SRC1_BYPASS( 16, 1, lwu, 0x00000000f00ff00f, 4, tdat3 );
+  TEST_LD_SRC1_BYPASS( 17, 2, lwu, 0x00000000ff00ff00, 4, tdat1 );
+
+  #-------------------------------------------------------------
+  # Test write-after-write hazard
+  #-------------------------------------------------------------
+
+  TEST_CASE( 18, x2, 2, \
+    la  x5, tdat; \
+    lwu x2, 0(x5); \
+    li  x2, 2; \
+  )
+
+  TEST_CASE( 19, x2, 2, \
+    la  x5, tdat; \
+    lwu x2, 0(x5); \
+    nop; \
+    li  x2, 2; \
+  )
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .word 0x00ff00ff
+tdat2:  .word 0xff00ff00
+tdat3:  .word 0x0ff00ff0
+tdat4:  .word 0xf00ff00f
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/or.S b/src/asmtest/isa/rv64ui/or.S
new file mode 100644
index 0000000..6d84f53
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/or.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# or.S
+#-----------------------------------------------------------------------------
+#
+# Test or instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_OP( 3, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_OP( 4, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_OP( 5, or, 0xf0fff0ff, 0xf00ff00f, 0xf0f0f0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 6, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC2_EQ_DEST( 7, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_EQ_DEST( 8, or, 0xff00ff00, 0xff00ff00 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 9,  0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_DEST_BYPASS( 10, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_DEST_BYPASS( 11, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC12_BYPASS( 12, 0, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 13, 0, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 14, 0, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 15, 1, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 16, 1, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 17, 2, 0, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC21_BYPASS( 18, 0, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 19, 0, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 20, 0, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 21, 1, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 22, 1, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 23, 2, 0, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_ZEROSRC1( 24, or, 0xff00ff00, 0xff00ff00 );
+  TEST_RR_ZEROSRC2( 25, or, 0x00ff00ff, 0x00ff00ff );
+  TEST_RR_ZEROSRC12( 26, or, 0 );
+  TEST_RR_ZERODEST( 27, or, 0x11111111, 0x22222222 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/ori.S b/src/asmtest/isa/rv64ui/ori.S
new file mode 100644
index 0000000..437c00a
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/ori.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ori.S
+#-----------------------------------------------------------------------------
+#
+# Test ori instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2, ori, 0xffffffffffffff0f, 0xffffffffff00ff00, 0xf0f );
+  TEST_IMM_OP( 3, ori, 0x000000000ff00ff0, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_OP( 4, ori, 0x0000000000ff07ff, 0x0000000000ff00ff, 0x70f );
+  TEST_IMM_OP( 5, ori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 6, ori, 0xff00fff0, 0xff00ff00, 0x0f0 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 7,  0, ori, 0x000000000ff00ff0, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_DEST_BYPASS( 8,  1, ori, 0x0000000000ff07ff, 0x0000000000ff00ff, 0x70f );
+  TEST_IMM_DEST_BYPASS( 9,  2, ori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  TEST_IMM_SRC1_BYPASS( 10, 0, ori, 0x000000000ff00ff0, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_SRC1_BYPASS( 11, 1, ori, 0xffffffffffffffff, 0x0000000000ff00ff, 0xf0f );
+  TEST_IMM_SRC1_BYPASS( 12, 2, ori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  TEST_IMM_ZEROSRC1( 13, ori, 0x0f0, 0x0f0 );
+  TEST_IMM_ZERODEST( 14, ori, 0x00ff00ff, 0x70f );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sb.S b/src/asmtest/isa/rv64ui/sb.S
new file mode 100644
index 0000000..19e32d6
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sb.S
@@ -0,0 +1,96 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sb.S
+#-----------------------------------------------------------------------------
+#
+# Test sb instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_ST_OP( 2, lb, sb, 0xffffffffffffffaa, 0, tdat );
+  TEST_ST_OP( 3, lb, sb, 0x0000000000000000, 1, tdat );
+  TEST_ST_OP( 4, lh, sb, 0xffffffffffffefa0, 2, tdat );
+  TEST_ST_OP( 5, lb, sb, 0x000000000000000a, 3, tdat );
+
+  # Test with negative offset
+
+  TEST_ST_OP( 6, lb, sb, 0xffffffffffffffaa, -3, tdat8 );
+  TEST_ST_OP( 7, lb, sb, 0x0000000000000000, -2, tdat8 );
+  TEST_ST_OP( 8, lb, sb, 0xffffffffffffffa0, -1, tdat8 );
+  TEST_ST_OP( 9, lb, sb, 0x000000000000000a, 0,  tdat8 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x78, \
+    la  x1, tdat9; \
+    li  x2, 0x12345678; \
+    addi x4, x1, -32; \
+    sb x2, 32(x4); \
+    lb x5, 0(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0xffffffffffffff98, \
+    la  x1, tdat9; \
+    li  x2, 0x00003098; \
+    addi x1, x1, -6; \
+    sb x2, 7(x1); \
+    la  x4, tdat10; \
+    lb x5, 0(x4); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_ST_SRC12_BYPASS( 12, 0, 0, lb, sb, 0xffffffffffffffdd, 0, tdat );
+  TEST_ST_SRC12_BYPASS( 13, 0, 1, lb, sb, 0xffffffffffffffcd, 1, tdat );
+  TEST_ST_SRC12_BYPASS( 14, 0, 2, lb, sb, 0xffffffffffffffcc, 2, tdat );
+  TEST_ST_SRC12_BYPASS( 15, 1, 0, lb, sb, 0xffffffffffffffbc, 3, tdat );
+  TEST_ST_SRC12_BYPASS( 16, 1, 1, lb, sb, 0xffffffffffffffbb, 4, tdat );
+  TEST_ST_SRC12_BYPASS( 17, 2, 0, lb, sb, 0xffffffffffffffab, 5, tdat );
+
+  TEST_ST_SRC21_BYPASS( 18, 0, 0, lb, sb, 0x33, 0, tdat );
+  TEST_ST_SRC21_BYPASS( 19, 0, 1, lb, sb, 0x23, 1, tdat );
+  TEST_ST_SRC21_BYPASS( 20, 0, 2, lb, sb, 0x22, 2, tdat );
+  TEST_ST_SRC21_BYPASS( 21, 1, 0, lb, sb, 0x12, 3, tdat );
+  TEST_ST_SRC21_BYPASS( 22, 1, 1, lb, sb, 0x11, 4, tdat );
+  TEST_ST_SRC21_BYPASS( 23, 2, 0, lb, sb, 0x01, 5, tdat );
+
+  li a0, 0xef
+  la a1, tdat
+  sb a0, 3(a1)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .byte 0xef
+tdat2:  .byte 0xef
+tdat3:  .byte 0xef
+tdat4:  .byte 0xef
+tdat5:  .byte 0xef
+tdat6:  .byte 0xef
+tdat7:  .byte 0xef
+tdat8:  .byte 0xef
+tdat9:  .byte 0xef
+tdat10: .byte 0xef
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sd.S b/src/asmtest/isa/rv64ui/sd.S
new file mode 100644
index 0000000..b6fd66d
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sd.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sd.S
+#-----------------------------------------------------------------------------
+#
+# Test sd instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_ST_OP( 2, ld, sd, 0x00aa00aa00aa00aa, 0,  tdat );
+  TEST_ST_OP( 3, ld, sd, 0xaa00aa00aa00aa00, 8,  tdat );
+  TEST_ST_OP( 4, ld, sd, 0x0aa00aa00aa00aa0, 16,  tdat );
+  TEST_ST_OP( 5, ld, sd, 0xa00aa00aa00aa00a, 24, tdat );
+
+  # Test with negative offset
+
+  TEST_ST_OP( 6, ld, sd, 0x00aa00aa00aa00aa, -24, tdat8 );
+  TEST_ST_OP( 7, ld, sd, 0xaa00aa00aa00aa00, -16, tdat8 );
+  TEST_ST_OP( 8, ld, sd, 0x0aa00aa00aa00aa0, -8,  tdat8 );
+  TEST_ST_OP( 9, ld, sd, 0xa00aa00aa00aa00a, 0,   tdat8 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x1234567812345678, \
+    la  x1, tdat9; \
+    li  x2, 0x1234567812345678; \
+    addi x4, x1, -32; \
+    sd x2, 32(x4); \
+    ld x5, 0(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x5821309858213098, \
+    la  x1, tdat9; \
+    li  x2, 0x5821309858213098; \
+    addi x1, x1, -3; \
+    sd x2, 11(x1); \
+    la  x4, tdat10; \
+    ld x5, 0(x4); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_ST_SRC12_BYPASS( 12, 0, 0, ld, sd, 0xabbccdd, 0,  tdat );
+  TEST_ST_SRC12_BYPASS( 13, 0, 1, ld, sd, 0xaabbccd, 8,  tdat );
+  TEST_ST_SRC12_BYPASS( 14, 0, 2, ld, sd, 0xdaabbcc, 16, tdat );
+  TEST_ST_SRC12_BYPASS( 15, 1, 0, ld, sd, 0xddaabbc, 24, tdat );
+  TEST_ST_SRC12_BYPASS( 16, 1, 1, ld, sd, 0xcddaabb, 32, tdat );
+  TEST_ST_SRC12_BYPASS( 17, 2, 0, ld, sd, 0xccddaab, 40, tdat );
+
+  TEST_ST_SRC21_BYPASS( 18, 0, 0, ld, sd, 0x00112233, 0,  tdat );
+  TEST_ST_SRC21_BYPASS( 19, 0, 1, ld, sd, 0x30011223, 8,  tdat );
+  TEST_ST_SRC21_BYPASS( 20, 0, 2, ld, sd, 0x33001122, 16, tdat );
+  TEST_ST_SRC21_BYPASS( 21, 1, 0, ld, sd, 0x23300112, 24, tdat );
+  TEST_ST_SRC21_BYPASS( 22, 1, 1, ld, sd, 0x22330011, 32, tdat );
+  TEST_ST_SRC21_BYPASS( 23, 2, 0, ld, sd, 0x12233001, 40, tdat );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .dword 0xdeadbeefdeadbeef
+tdat2:  .dword 0xdeadbeefdeadbeef
+tdat3:  .dword 0xdeadbeefdeadbeef
+tdat4:  .dword 0xdeadbeefdeadbeef
+tdat5:  .dword 0xdeadbeefdeadbeef
+tdat6:  .dword 0xdeadbeefdeadbeef
+tdat7:  .dword 0xdeadbeefdeadbeef
+tdat8:  .dword 0xdeadbeefdeadbeef
+tdat9:  .dword 0xdeadbeefdeadbeef
+tdat10: .dword 0xdeadbeefdeadbeef
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sh.S b/src/asmtest/isa/rv64ui/sh.S
new file mode 100644
index 0000000..ea9eb23
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sh.S
@@ -0,0 +1,96 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sh.S
+#-----------------------------------------------------------------------------
+#
+# Test sh instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_ST_OP( 2, lh, sh, 0x00000000000000aa, 0, tdat );
+  TEST_ST_OP( 3, lh, sh, 0xffffffffffffaa00, 2, tdat );
+  TEST_ST_OP( 4, lw, sh, 0xffffffffbeef0aa0, 4, tdat );
+  TEST_ST_OP( 5, lh, sh, 0xffffffffffffa00a, 6, tdat );
+
+  # Test with negative offset
+
+  TEST_ST_OP( 6, lh, sh, 0x00000000000000aa, -6, tdat8 );
+  TEST_ST_OP( 7, lh, sh, 0xffffffffffffaa00, -4, tdat8 );
+  TEST_ST_OP( 8, lh, sh, 0x0000000000000aa0, -2, tdat8 );
+  TEST_ST_OP( 9, lh, sh, 0xffffffffffffa00a, 0,  tdat8 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x5678, \
+    la  x1, tdat9; \
+    li  x2, 0x12345678; \
+    addi x4, x1, -32; \
+    sh x2, 32(x4); \
+    lh x5, 0(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x3098, \
+    la  x1, tdat9; \
+    li  x2, 0x00003098; \
+    addi x1, x1, -5; \
+    sh x2, 7(x1); \
+    la  x4, tdat10; \
+    lh x5, 0(x4); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_ST_SRC12_BYPASS( 12, 0, 0, lh, sh, 0xffffffffffffccdd, 0,  tdat );
+  TEST_ST_SRC12_BYPASS( 13, 0, 1, lh, sh, 0xffffffffffffbccd, 2,  tdat );
+  TEST_ST_SRC12_BYPASS( 14, 0, 2, lh, sh, 0xffffffffffffbbcc, 4,  tdat );
+  TEST_ST_SRC12_BYPASS( 15, 1, 0, lh, sh, 0xffffffffffffabbc, 6, tdat );
+  TEST_ST_SRC12_BYPASS( 16, 1, 1, lh, sh, 0xffffffffffffaabb, 8, tdat );
+  TEST_ST_SRC12_BYPASS( 17, 2, 0, lh, sh, 0xffffffffffffdaab, 10, tdat );
+
+  TEST_ST_SRC21_BYPASS( 18, 0, 0, lh, sh, 0x2233, 0,  tdat );
+  TEST_ST_SRC21_BYPASS( 19, 0, 1, lh, sh, 0x1223, 2,  tdat );
+  TEST_ST_SRC21_BYPASS( 20, 0, 2, lh, sh, 0x1122, 4,  tdat );
+  TEST_ST_SRC21_BYPASS( 21, 1, 0, lh, sh, 0x0112, 6, tdat );
+  TEST_ST_SRC21_BYPASS( 22, 1, 1, lh, sh, 0x0011, 8, tdat );
+  TEST_ST_SRC21_BYPASS( 23, 2, 0, lh, sh, 0x3001, 10, tdat );
+
+  li a0, 0xbeef
+  la a1, tdat
+  sh a0, 6(a1)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .half 0xbeef
+tdat2:  .half 0xbeef
+tdat3:  .half 0xbeef
+tdat4:  .half 0xbeef
+tdat5:  .half 0xbeef
+tdat6:  .half 0xbeef
+tdat7:  .half 0xbeef
+tdat8:  .half 0xbeef
+tdat9:  .half 0xbeef
+tdat10: .half 0xbeef
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/simple.S b/src/asmtest/isa/rv64ui/simple.S
new file mode 100644
index 0000000..6c45fbd
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/simple.S
@@ -0,0 +1,27 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# simple.S
+#-----------------------------------------------------------------------------
+#
+# This is the most basic self checking test. If your simulator does not
+# pass thiss then there is little chance that it will pass any of the
+# more complicated self checking tests.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+RVTEST_PASS
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sll.S b/src/asmtest/isa/rv64ui/sll.S
new file mode 100644
index 0000000..8682743
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sll.S
@@ -0,0 +1,96 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sll.S
+#-----------------------------------------------------------------------------
+#
+# Test sll instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sll, 0x0000000000000001, 0x0000000000000001, 0  );
+  TEST_RR_OP( 3,  sll, 0x0000000000000002, 0x0000000000000001, 1  );
+  TEST_RR_OP( 4,  sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_OP( 5,  sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_OP( 6,  sll, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_RR_OP( 7,  sll, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_RR_OP( 8,  sll, 0xfffffffffffffffe, 0xffffffffffffffff, 1  );
+  TEST_RR_OP( 9,  sll, 0xffffffffffffff80, 0xffffffffffffffff, 7  );
+  TEST_RR_OP( 10, sll, 0xffffffffffffc000, 0xffffffffffffffff, 14 );
+  TEST_RR_OP( 11, sll, 0xffffffff80000000, 0xffffffffffffffff, 31 );
+
+  TEST_RR_OP( 12, sll, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_RR_OP( 13, sll, 0x0000000042424242, 0x0000000021212121, 1  );
+  TEST_RR_OP( 14, sll, 0x0000001090909080, 0x0000000021212121, 7  );
+  TEST_RR_OP( 15, sll, 0x0000084848484000, 0x0000000021212121, 14 );
+  TEST_RR_OP( 16, sll, 0x1090909080000000, 0x0000000021212121, 31 );
+
+  # Verify that shifts only use bottom six(rv64) or five(rv32) bits
+
+  TEST_RR_OP( 17, sll, 0x0000000021212121, 0x0000000021212121, 0xffffffffffffffc0 );
+  TEST_RR_OP( 18, sll, 0x0000000042424242, 0x0000000021212121, 0xffffffffffffffc1 );
+  TEST_RR_OP( 19, sll, 0x0000001090909080, 0x0000000021212121, 0xffffffffffffffc7 );
+  TEST_RR_OP( 20, sll, 0x0000084848484000, 0x0000000021212121, 0xffffffffffffffce );
+
+#if __riscv_xlen == 64
+  TEST_RR_OP( 21, sll, 0x8000000000000000, 0x0000000021212121, 0xffffffffffffffff );
+  TEST_RR_OP( 50, sll, 0x8000000000000000, 0x0000000000000001, 63 );
+  TEST_RR_OP( 51, sll, 0xffffff8000000000, 0xffffffffffffffff, 39 );
+  TEST_RR_OP( 52, sll, 0x0909080000000000, 0x0000000021212121, 43 );
+#endif
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, sll, 0x00000080, 0x00000001, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, sll, 0x00004000, 0x00000001, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, sll, 24, 3 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, sll, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, sll, 0x0000000080000000, 0x0000000000000001, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, sll, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, sll, 0x0000000080000000, 0x0000000000000001, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, sll, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, sll, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, sll, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_RR_ZEROSRC1( 40, sll, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, sll, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, sll, 0 );
+  TEST_RR_ZERODEST( 43, sll, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/slli.S b/src/asmtest/isa/rv64ui/slli.S
new file mode 100644
index 0000000..b5341ad
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/slli.S
@@ -0,0 +1,74 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slli.S
+#-----------------------------------------------------------------------------
+#
+# Test slli instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  slli, 0x0000000000000001, 0x0000000000000001, 0  );
+  TEST_IMM_OP( 3,  slli, 0x0000000000000002, 0x0000000000000001, 1  );
+  TEST_IMM_OP( 4,  slli, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_OP( 5,  slli, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_OP( 6,  slli, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_OP( 7,  slli, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_IMM_OP( 8,  slli, 0xfffffffffffffffe, 0xffffffffffffffff, 1  );
+  TEST_IMM_OP( 9,  slli, 0xffffffffffffff80, 0xffffffffffffffff, 7  );
+  TEST_IMM_OP( 10, slli, 0xffffffffffffc000, 0xffffffffffffffff, 14 );
+  TEST_IMM_OP( 11, slli, 0xffffffff80000000, 0xffffffffffffffff, 31 );
+
+  TEST_IMM_OP( 12, slli, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_IMM_OP( 13, slli, 0x0000000042424242, 0x0000000021212121, 1  );
+  TEST_IMM_OP( 14, slli, 0x0000001090909080, 0x0000000021212121, 7  );
+  TEST_IMM_OP( 15, slli, 0x0000084848484000, 0x0000000021212121, 14 );
+  TEST_IMM_OP( 16, slli, 0x1090909080000000, 0x0000000021212121, 31 );
+
+#if __riscv_xlen == 64
+  TEST_IMM_OP( 50, slli, 0x8000000000000000, 0x0000000000000001, 63 );
+  TEST_IMM_OP( 51, slli, 0xffffff8000000000, 0xffffffffffffffff, 39 );
+  TEST_IMM_OP( 52, slli, 0x0909080000000000, 0x0000000021212121, 43 );
+#endif
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, slli, 0x00000080, 0x00000001, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, slli, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, slli, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, slli, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, slli, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_SRC1_BYPASS( 22, 1, slli, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, slli, 0x0000000080000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, slli, 0, 31 );
+  TEST_IMM_ZERODEST( 25, slli, 33, 20 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/slliw.S b/src/asmtest/isa/rv64ui/slliw.S
new file mode 100644
index 0000000..0ed888b
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/slliw.S
@@ -0,0 +1,75 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slliw.S
+#-----------------------------------------------------------------------------
+#
+# Test slliw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  slliw, 0x0000000000000001, 0x0000000000000001, 0  );
+  TEST_IMM_OP( 3,  slliw, 0x0000000000000002, 0x0000000000000001, 1  );
+  TEST_IMM_OP( 4,  slliw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_OP( 5,  slliw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_OP( 6,  slliw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_OP( 7,  slliw, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_IMM_OP( 8,  slliw, 0xfffffffffffffffe, 0xffffffffffffffff, 1  );
+  TEST_IMM_OP( 9,  slliw, 0xffffffffffffff80, 0xffffffffffffffff, 7  );
+  TEST_IMM_OP( 10, slliw, 0xffffffffffffc000, 0xffffffffffffffff, 14 );
+  TEST_IMM_OP( 11, slliw, 0xffffffff80000000, 0xffffffffffffffff, 31 );
+
+  TEST_IMM_OP( 12, slliw, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_IMM_OP( 13, slliw, 0x0000000042424242, 0x0000000021212121, 1  );
+  TEST_IMM_OP( 14, slliw, 0xffffffff90909080, 0x0000000021212121, 7  );
+  TEST_IMM_OP( 15, slliw, 0x0000000048484000, 0x0000000021212121, 14 );
+  TEST_IMM_OP( 16, slliw, 0xffffffff80000000, 0x0000000021212121, 31 );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_IMM_OP( 44, slliw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_IMM_OP( 45, slliw, 0x0000000023456780, 0xffffffff12345678, 4 );
+  TEST_IMM_OP( 46, slliw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_IMM_OP( 47, slliw, 0xffffffff93456780, 0x0000000099345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, slliw, 0x00000080, 0x00000001, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, slliw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, slliw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, slliw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, slliw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_IMM_SRC1_BYPASS( 22, 1, slliw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, slliw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, slliw, 0, 31 );
+  TEST_IMM_ZERODEST( 25, slliw, 31, 28 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sllw.S b/src/asmtest/isa/rv64ui/sllw.S
new file mode 100644
index 0000000..62b4db6
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sllw.S
@@ -0,0 +1,97 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sllw.S
+#-----------------------------------------------------------------------------
+#
+# Test sllw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sllw, 0x0000000000000001, 0x0000000000000001, 0  );
+  TEST_RR_OP( 3,  sllw, 0x0000000000000002, 0x0000000000000001, 1  );
+  TEST_RR_OP( 4,  sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_OP( 5,  sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_OP( 6,  sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_RR_OP( 7,  sllw, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_RR_OP( 8,  sllw, 0xfffffffffffffffe, 0xffffffffffffffff, 1  );
+  TEST_RR_OP( 9,  sllw, 0xffffffffffffff80, 0xffffffffffffffff, 7  );
+  TEST_RR_OP( 10, sllw, 0xffffffffffffc000, 0xffffffffffffffff, 14 );
+  TEST_RR_OP( 11, sllw, 0xffffffff80000000, 0xffffffffffffffff, 31 );
+
+  TEST_RR_OP( 12, sllw, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_RR_OP( 13, sllw, 0x0000000042424242, 0x0000000021212121, 1  );
+  TEST_RR_OP( 14, sllw, 0xffffffff90909080, 0x0000000021212121, 7  );
+  TEST_RR_OP( 15, sllw, 0x0000000048484000, 0x0000000021212121, 14 );
+  TEST_RR_OP( 16, sllw, 0xffffffff80000000, 0x0000000021212121, 31 );
+
+  # Verify that shifts only use bottom five bits
+
+  TEST_RR_OP( 17, sllw, 0x0000000021212121, 0x0000000021212121, 0xffffffffffffffe0 );
+  TEST_RR_OP( 18, sllw, 0x0000000042424242, 0x0000000021212121, 0xffffffffffffffe1 );
+  TEST_RR_OP( 19, sllw, 0xffffffff90909080, 0x0000000021212121, 0xffffffffffffffe7 );
+  TEST_RR_OP( 20, sllw, 0x0000000048484000, 0x0000000021212121, 0xffffffffffffffee );
+  TEST_RR_OP( 21, sllw, 0xffffffff80000000, 0x0000000021212121, 0xffffffffffffffff );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_RR_OP( 44, sllw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_RR_OP( 45, sllw, 0x0000000023456780, 0xffffffff12345678, 4 );
+  TEST_RR_OP( 46, sllw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_RR_OP( 47, sllw, 0xffffffff93456780, 0x0000000099345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, sllw, 0x00000080, 0x00000001, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, sllw, 0x00004000, 0x00000001, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, sllw, 24, 3 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, sllw, 0x0000000000000080, 0x0000000000000001, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, sllw, 0x0000000000004000, 0x0000000000000001, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, sllw, 0xffffffff80000000, 0x0000000000000001, 31 );
+
+  TEST_RR_ZEROSRC1( 40, sllw, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, sllw, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, sllw, 0 );
+  TEST_RR_ZERODEST( 43, sllw, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/slt.S b/src/asmtest/isa/rv64ui/slt.S
new file mode 100644
index 0000000..644a51a
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/slt.S
@@ -0,0 +1,84 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slt.S
+#-----------------------------------------------------------------------------
+#
+# Test slt instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  slt, 0, 0x0000000000000000, 0x0000000000000000 );
+  TEST_RR_OP( 3,  slt, 0, 0x0000000000000001, 0x0000000000000001 );
+  TEST_RR_OP( 4,  slt, 1, 0x0000000000000003, 0x0000000000000007 );
+  TEST_RR_OP( 5,  slt, 0, 0x0000000000000007, 0x0000000000000003 );
+
+  TEST_RR_OP( 6,  slt, 0, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 7,  slt, 1, 0xffffffff80000000, 0x0000000000000000 );
+  TEST_RR_OP( 8,  slt, 1, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 9,  slt, 1, 0x0000000000000000, 0x0000000000007fff );
+  TEST_RR_OP( 10, slt, 0, 0x000000007fffffff, 0x0000000000000000 );
+  TEST_RR_OP( 11, slt, 0, 0x000000007fffffff, 0x0000000000007fff );
+
+  TEST_RR_OP( 12, slt, 1, 0xffffffff80000000, 0x0000000000007fff );
+  TEST_RR_OP( 13, slt, 0, 0x000000007fffffff, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 14, slt, 0, 0x0000000000000000, 0xffffffffffffffff );
+  TEST_RR_OP( 15, slt, 1, 0xffffffffffffffff, 0x0000000000000001 );
+  TEST_RR_OP( 16, slt, 0, 0xffffffffffffffff, 0xffffffffffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 17, slt, 0, 14, 13 );
+  TEST_RR_SRC2_EQ_DEST( 18, slt, 1, 11, 13 );
+  TEST_RR_SRC12_EQ_DEST( 19, slt, 0, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 20, 0, slt, 1, 11, 13 );
+  TEST_RR_DEST_BYPASS( 21, 1, slt, 0, 14, 13 );
+  TEST_RR_DEST_BYPASS( 22, 2, slt, 1, 12, 13 );
+
+  TEST_RR_SRC12_BYPASS( 23, 0, 0, slt, 0, 14, 13 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 1, slt, 1, 11, 13 );
+  TEST_RR_SRC12_BYPASS( 25, 0, 2, slt, 0, 15, 13 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 0, slt, 1, 10, 13 );
+  TEST_RR_SRC12_BYPASS( 27, 1, 1, slt, 0, 16, 13 );
+  TEST_RR_SRC12_BYPASS( 28, 2, 0, slt, 1,  9, 13 );
+
+  TEST_RR_SRC21_BYPASS( 29, 0, 0, slt, 0, 17, 13 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 1, slt, 1,  8, 13 );
+  TEST_RR_SRC21_BYPASS( 31, 0, 2, slt, 0, 18, 13 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 0, slt, 1,  7, 13 );
+  TEST_RR_SRC21_BYPASS( 33, 1, 1, slt, 0, 19, 13 );
+  TEST_RR_SRC21_BYPASS( 34, 2, 0, slt, 1,  6, 13 );
+
+  TEST_RR_ZEROSRC1( 35, slt, 0, -1 );
+  TEST_RR_ZEROSRC2( 36, slt, 1, -1 );
+  TEST_RR_ZEROSRC12( 37, slt, 0 );
+  TEST_RR_ZERODEST( 38, slt, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/slti.S b/src/asmtest/isa/rv64ui/slti.S
new file mode 100644
index 0000000..9222fa4
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/slti.S
@@ -0,0 +1,70 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slti.S
+#-----------------------------------------------------------------------------
+#
+# Test slti instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  slti, 0, 0x0000000000000000, 0x000 );
+  TEST_IMM_OP( 3,  slti, 0, 0x0000000000000001, 0x001 );
+  TEST_IMM_OP( 4,  slti, 1, 0x0000000000000003, 0x007 );
+  TEST_IMM_OP( 5,  slti, 0, 0x0000000000000007, 0x003 );
+
+  TEST_IMM_OP( 6,  slti, 0, 0x0000000000000000, 0x800 );
+  TEST_IMM_OP( 7,  slti, 1, 0xffffffff80000000, 0x000 );
+  TEST_IMM_OP( 8,  slti, 1, 0xffffffff80000000, 0x800 );
+
+  TEST_IMM_OP( 9,  slti, 1, 0x0000000000000000, 0x7ff );
+  TEST_IMM_OP( 10, slti, 0, 0x000000007fffffff, 0x000 );
+  TEST_IMM_OP( 11, slti, 0, 0x000000007fffffff, 0x7ff );
+
+  TEST_IMM_OP( 12, slti, 1, 0xffffffff80000000, 0x7ff );
+  TEST_IMM_OP( 13, slti, 0, 0x000000007fffffff, 0x800 );
+
+  TEST_IMM_OP( 14, slti, 0, 0x0000000000000000, 0xfff );
+  TEST_IMM_OP( 15, slti, 1, 0xffffffffffffffff, 0x001 );
+  TEST_IMM_OP( 16, slti, 0, 0xffffffffffffffff, 0xfff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, slti, 1, 11, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, slti, 0, 15, 10 );
+  TEST_IMM_DEST_BYPASS( 19, 1, slti, 1, 10, 16 );
+  TEST_IMM_DEST_BYPASS( 20, 2, slti, 0, 16,  9 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, slti, 1, 11, 15 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, slti, 0, 17,  8 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, slti, 1, 12, 14 );
+
+  TEST_IMM_ZEROSRC1( 24, slti, 0, 0xfff );
+  TEST_IMM_ZERODEST( 25, slti, 0x00ff00ff, 0xfff );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sltiu.S b/src/asmtest/isa/rv64ui/sltiu.S
new file mode 100644
index 0000000..f6a719b
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sltiu.S
@@ -0,0 +1,70 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sltiu.S
+#-----------------------------------------------------------------------------
+#
+# Test sltiu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  sltiu, 0, 0x0000000000000000, 0x000 );
+  TEST_IMM_OP( 3,  sltiu, 0, 0x0000000000000001, 0x001 );
+  TEST_IMM_OP( 4,  sltiu, 1, 0x0000000000000003, 0x007 );
+  TEST_IMM_OP( 5,  sltiu, 0, 0x0000000000000007, 0x003 );
+
+  TEST_IMM_OP( 6,  sltiu, 1, 0x0000000000000000, 0x800 );
+  TEST_IMM_OP( 7,  sltiu, 0, 0xffffffff80000000, 0x000 );
+  TEST_IMM_OP( 8,  sltiu, 1, 0xffffffff80000000, 0x800 );
+
+  TEST_IMM_OP( 9,  sltiu, 1, 0x0000000000000000, 0x7ff );
+  TEST_IMM_OP( 10, sltiu, 0, 0x000000007fffffff, 0x000 );
+  TEST_IMM_OP( 11, sltiu, 0, 0x000000007fffffff, 0x7ff );
+
+  TEST_IMM_OP( 12, sltiu, 0, 0xffffffff80000000, 0x7ff );
+  TEST_IMM_OP( 13, sltiu, 1, 0x000000007fffffff, 0x800 );
+
+  TEST_IMM_OP( 14, sltiu, 1, 0x0000000000000000, 0xfff );
+  TEST_IMM_OP( 15, sltiu, 0, 0xffffffffffffffff, 0x001 );
+  TEST_IMM_OP( 16, sltiu, 0, 0xffffffffffffffff, 0xfff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, sltiu, 1, 11, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, sltiu, 0, 15, 10 );
+  TEST_IMM_DEST_BYPASS( 19, 1, sltiu, 1, 10, 16 );
+  TEST_IMM_DEST_BYPASS( 20, 2, sltiu, 0, 16,  9 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, sltiu, 1, 11, 15 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, sltiu, 0, 17,  8 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, sltiu, 1, 12, 14 );
+
+  TEST_IMM_ZEROSRC1( 24, sltiu, 1, 0xfff );
+  TEST_IMM_ZERODEST( 25, sltiu, 0x00ff00ff, 0xfff );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sltu.S b/src/asmtest/isa/rv64ui/sltu.S
new file mode 100644
index 0000000..52ff685
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sltu.S
@@ -0,0 +1,84 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sltu.S
+#-----------------------------------------------------------------------------
+#
+# Test sltu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sltu, 0, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  sltu, 0, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  sltu, 1, 0x00000003, 0x00000007 );
+  TEST_RR_OP( 5,  sltu, 0, 0x00000007, 0x00000003 );
+
+  TEST_RR_OP( 6,  sltu, 1, 0x00000000, 0xffff8000 );
+  TEST_RR_OP( 7,  sltu, 0, 0x80000000, 0x00000000 );
+  TEST_RR_OP( 8,  sltu, 1, 0x80000000, 0xffff8000 );
+
+  TEST_RR_OP( 9,  sltu, 1, 0x00000000, 0x00007fff );
+  TEST_RR_OP( 10, sltu, 0, 0x7fffffff, 0x00000000 );
+  TEST_RR_OP( 11, sltu, 0, 0x7fffffff, 0x00007fff );
+
+  TEST_RR_OP( 12, sltu, 0, 0x80000000, 0x00007fff );
+  TEST_RR_OP( 13, sltu, 1, 0x7fffffff, 0xffff8000 );
+
+  TEST_RR_OP( 14, sltu, 1, 0x00000000, 0xffffffff );
+  TEST_RR_OP( 15, sltu, 0, 0xffffffff, 0x00000001 );
+  TEST_RR_OP( 16, sltu, 0, 0xffffffff, 0xffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 17, sltu, 0, 14, 13 );
+  TEST_RR_SRC2_EQ_DEST( 18, sltu, 1, 11, 13 );
+  TEST_RR_SRC12_EQ_DEST( 19, sltu, 0, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 20, 0, sltu, 1, 11, 13 );
+  TEST_RR_DEST_BYPASS( 21, 1, sltu, 0, 14, 13 );
+  TEST_RR_DEST_BYPASS( 22, 2, sltu, 1, 12, 13 );
+
+  TEST_RR_SRC12_BYPASS( 23, 0, 0, sltu, 0, 14, 13 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 1, sltu, 1, 11, 13 );
+  TEST_RR_SRC12_BYPASS( 25, 0, 2, sltu, 0, 15, 13 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 0, sltu, 1, 10, 13 );
+  TEST_RR_SRC12_BYPASS( 27, 1, 1, sltu, 0, 16, 13 );
+  TEST_RR_SRC12_BYPASS( 28, 2, 0, sltu, 1,  9, 13 );
+
+  TEST_RR_SRC21_BYPASS( 29, 0, 0, sltu, 0, 17, 13 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 1, sltu, 1,  8, 13 );
+  TEST_RR_SRC21_BYPASS( 31, 0, 2, sltu, 0, 18, 13 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 0, sltu, 1,  7, 13 );
+  TEST_RR_SRC21_BYPASS( 33, 1, 1, sltu, 0, 19, 13 );
+  TEST_RR_SRC21_BYPASS( 34, 2, 0, sltu, 1,  6, 13 );
+
+  TEST_RR_ZEROSRC1( 35, sltu, 1, -1 );
+  TEST_RR_ZEROSRC2( 36, sltu, 0, -1 );
+  TEST_RR_ZEROSRC12( 37, sltu, 0 );
+  TEST_RR_ZERODEST( 38, sltu, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sra.S b/src/asmtest/isa/rv64ui/sra.S
new file mode 100644
index 0000000..580ae89
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sra.S
@@ -0,0 +1,90 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sra.S
+#-----------------------------------------------------------------------------
+#
+# Test sra instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sra, 0xffffffff80000000, 0xffffffff80000000, 0  );
+  TEST_RR_OP( 3,  sra, 0xffffffffc0000000, 0xffffffff80000000, 1  );
+  TEST_RR_OP( 4,  sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_OP( 5,  sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_OP( 6,  sra, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_RR_OP( 7,  sra, 0x000000007fffffff, 0x000000007fffffff, 0  );
+  TEST_RR_OP( 8,  sra, 0x000000003fffffff, 0x000000007fffffff, 1  );
+  TEST_RR_OP( 9,  sra, 0x0000000000ffffff, 0x000000007fffffff, 7  );
+  TEST_RR_OP( 10, sra, 0x000000000001ffff, 0x000000007fffffff, 14 );
+  TEST_RR_OP( 11, sra, 0x0000000000000000, 0x000000007fffffff, 31 );
+
+  TEST_RR_OP( 12, sra, 0xffffffff81818181, 0xffffffff81818181, 0  );
+  TEST_RR_OP( 13, sra, 0xffffffffc0c0c0c0, 0xffffffff81818181, 1  );
+  TEST_RR_OP( 14, sra, 0xffffffffff030303, 0xffffffff81818181, 7  );
+  TEST_RR_OP( 15, sra, 0xfffffffffffe0606, 0xffffffff81818181, 14 );
+  TEST_RR_OP( 16, sra, 0xffffffffffffffff, 0xffffffff81818181, 31 );
+
+  # Verify that shifts only use bottom six(rv64) or five(rv32) bits
+
+  TEST_RR_OP( 17, sra, 0xffffffff81818181, 0xffffffff81818181, 0xffffffffffffffc0 );
+  TEST_RR_OP( 18, sra, 0xffffffffc0c0c0c0, 0xffffffff81818181, 0xffffffffffffffc1 );
+  TEST_RR_OP( 19, sra, 0xffffffffff030303, 0xffffffff81818181, 0xffffffffffffffc7 );
+  TEST_RR_OP( 20, sra, 0xfffffffffffe0606, 0xffffffff81818181, 0xffffffffffffffce );
+  TEST_RR_OP( 21, sra, 0xffffffffffffffff, 0xffffffff81818181, 0xffffffffffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, sra, 0, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, sra, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, sra, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, sra, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, sra, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, sra, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, sra, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, sra, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_ZEROSRC1( 40, sra, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, sra, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, sra, 0 );
+  TEST_RR_ZERODEST( 43, sra, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/srai.S b/src/asmtest/isa/rv64ui/srai.S
new file mode 100644
index 0000000..8d05213
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/srai.S
@@ -0,0 +1,68 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srai.S
+#-----------------------------------------------------------------------------
+#
+# Test srai instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  srai, 0xffffff8000000000, 0xffffff8000000000, 0  );
+  TEST_IMM_OP( 3,  srai, 0xffffffffc0000000, 0xffffffff80000000, 1  );
+  TEST_IMM_OP( 4,  srai, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_IMM_OP( 5,  srai, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_OP( 6,  srai, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_OP( 7,  srai, 0x000000007fffffff, 0x000000007fffffff, 0  );
+  TEST_IMM_OP( 8,  srai, 0x000000003fffffff, 0x000000007fffffff, 1  );
+  TEST_IMM_OP( 9,  srai, 0x0000000000ffffff, 0x000000007fffffff, 7  );
+  TEST_IMM_OP( 10, srai, 0x000000000001ffff, 0x000000007fffffff, 14 );
+  TEST_IMM_OP( 11, srai, 0x0000000000000000, 0x000000007fffffff, 31 );
+
+  TEST_IMM_OP( 12, srai, 0xffffffff81818181, 0xffffffff81818181, 0  );
+  TEST_IMM_OP( 13, srai, 0xffffffffc0c0c0c0, 0xffffffff81818181, 1  );
+  TEST_IMM_OP( 14, srai, 0xffffffffff030303, 0xffffffff81818181, 7  );
+  TEST_IMM_OP( 15, srai, 0xfffffffffffe0606, 0xffffffff81818181, 14 );
+  TEST_IMM_OP( 16, srai, 0xffffffffffffffff, 0xffffffff81818181, 31 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, srai, 0xffffffffff000000, 0xffffffff80000000, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, srai, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, srai, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, srai, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, srai, 0xffffffffff000000, 0xffffffff80000000, 7 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, srai, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, srai, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, srai, 0, 4 );
+  TEST_IMM_ZERODEST( 25, srai, 33, 10 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sraiw.S b/src/asmtest/isa/rv64ui/sraiw.S
new file mode 100644
index 0000000..a435e59
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sraiw.S
@@ -0,0 +1,78 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sraiw.S
+#-----------------------------------------------------------------------------
+#
+# Test sraiw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  sraiw, 0xffffffff80000000, 0xffffffff80000000, 0  );
+  TEST_IMM_OP( 3,  sraiw, 0xffffffffc0000000, 0xffffffff80000000, 1  );
+  TEST_IMM_OP( 4,  sraiw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_IMM_OP( 5,  sraiw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_OP( 6,  sraiw, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_OP( 7,  sraiw, 0x000000007fffffff, 0x000000007fffffff, 0  );
+  TEST_IMM_OP( 8,  sraiw, 0x000000003fffffff, 0x000000007fffffff, 1  );
+  TEST_IMM_OP( 9,  sraiw, 0x0000000000ffffff, 0x000000007fffffff, 7  );
+  TEST_IMM_OP( 10, sraiw, 0x000000000001ffff, 0x000000007fffffff, 14 );
+  TEST_IMM_OP( 11, sraiw, 0x0000000000000000, 0x000000007fffffff, 31 );
+
+  TEST_IMM_OP( 12, sraiw, 0xffffffff81818181, 0xffffffff81818181, 0  );
+  TEST_IMM_OP( 13, sraiw, 0xffffffffc0c0c0c0, 0xffffffff81818181, 1  );
+  TEST_IMM_OP( 14, sraiw, 0xffffffffff030303, 0xffffffff81818181, 7  );
+  TEST_IMM_OP( 15, sraiw, 0xfffffffffffe0606, 0xffffffff81818181, 14 );
+  TEST_IMM_OP( 16, sraiw, 0xffffffffffffffff, 0xffffffff81818181, 31 );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_IMM_OP( 44, sraiw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_IMM_OP( 45, sraiw, 0x0000000001234567, 0xffffffff12345678, 4 );
+  TEST_IMM_OP( 46, sraiw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_IMM_OP( 47, sraiw, 0xfffffffff9234567, 0x0000000092345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, sraiw, 0xffffffffff000000, 0xffffffff80000000, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, sraiw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, sraiw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, sraiw, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, sraiw, 0xffffffffff000000, 0xffffffff80000000, 7 );
+  TEST_IMM_SRC1_BYPASS( 22, 1, sraiw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, sraiw, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, sraiw, 0, 31 );
+  TEST_IMM_ZERODEST( 25, sraiw, 31, 28 );
+
+  TEST_IMM_OP( 26, sraiw, 0x0000000000000000, 0x00e0000000000000, 28)
+  TEST_IMM_OP( 27, sraiw, 0xffffffffff000000, 0x00000000f0000000, 4)
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sraw.S b/src/asmtest/isa/rv64ui/sraw.S
new file mode 100644
index 0000000..68d913e
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sraw.S
@@ -0,0 +1,97 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sraw.S
+#-----------------------------------------------------------------------------
+#
+# Test sraw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sraw, 0xffffffff80000000, 0xffffffff80000000, 0  );
+  TEST_RR_OP( 3,  sraw, 0xffffffffc0000000, 0xffffffff80000000, 1  );
+  TEST_RR_OP( 4,  sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_OP( 5,  sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_OP( 6,  sraw, 0xffffffffffffffff, 0xffffffff80000001, 31 );
+
+  TEST_RR_OP( 7,  sraw, 0x000000007fffffff, 0x000000007fffffff, 0  );
+  TEST_RR_OP( 8,  sraw, 0x000000003fffffff, 0x000000007fffffff, 1  );
+  TEST_RR_OP( 9,  sraw, 0x0000000000ffffff, 0x000000007fffffff, 7  );
+  TEST_RR_OP( 10, sraw, 0x000000000001ffff, 0x000000007fffffff, 14 );
+  TEST_RR_OP( 11, sraw, 0x0000000000000000, 0x000000007fffffff, 31 );
+
+  TEST_RR_OP( 12, sraw, 0xffffffff81818181, 0xffffffff81818181, 0  );
+  TEST_RR_OP( 13, sraw, 0xffffffffc0c0c0c0, 0xffffffff81818181, 1  );
+  TEST_RR_OP( 14, sraw, 0xffffffffff030303, 0xffffffff81818181, 7  );
+  TEST_RR_OP( 15, sraw, 0xfffffffffffe0606, 0xffffffff81818181, 14 );
+  TEST_RR_OP( 16, sraw, 0xffffffffffffffff, 0xffffffff81818181, 31 );
+
+  # Verify that shifts only use bottom five bits
+
+  TEST_RR_OP( 17, sraw, 0xffffffff81818181, 0xffffffff81818181, 0xffffffffffffffe0 );
+  TEST_RR_OP( 18, sraw, 0xffffffffc0c0c0c0, 0xffffffff81818181, 0xffffffffffffffe1 );
+  TEST_RR_OP( 19, sraw, 0xffffffffff030303, 0xffffffff81818181, 0xffffffffffffffe7 );
+  TEST_RR_OP( 20, sraw, 0xfffffffffffe0606, 0xffffffff81818181, 0xffffffffffffffee );
+  TEST_RR_OP( 21, sraw, 0xffffffffffffffff, 0xffffffff81818181, 0xffffffffffffffff );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_RR_OP( 44, sraw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_RR_OP( 45, sraw, 0x0000000001234567, 0xffffffff12345678, 4 );
+  TEST_RR_OP( 46, sraw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_RR_OP( 47, sraw, 0xfffffffff9234567, 0x0000000092345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, sraw, 0, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, sraw, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, sraw, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, sraw, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, sraw, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, sraw, 0xffffffffff000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, sraw, 0xfffffffffffe0000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, sraw, 0xffffffffffffffff, 0xffffffff80000000, 31 );
+
+  TEST_RR_ZEROSRC1( 40, sraw, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, sraw, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, sraw, 0 );
+  TEST_RR_ZERODEST( 43, sraw, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/srl.S b/src/asmtest/isa/rv64ui/srl.S
new file mode 100644
index 0000000..5ee223f
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/srl.S
@@ -0,0 +1,93 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srl.S
+#-----------------------------------------------------------------------------
+#
+# Test srl instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+#define TEST_SRL(n, v, a) \
+  TEST_RR_OP(n, srl, ((v) & ((1 << (__riscv_xlen-1) << 1) - 1)) >> (a), v, a)
+
+  TEST_SRL( 2,  0xffffffff80000000, 0  );
+  TEST_SRL( 3,  0xffffffff80000000, 1  );
+  TEST_SRL( 4,  0xffffffff80000000, 7  );
+  TEST_SRL( 5,  0xffffffff80000000, 14 );
+  TEST_SRL( 6,  0xffffffff80000001, 31 );
+
+  TEST_SRL( 7,  0xffffffffffffffff, 0  );
+  TEST_SRL( 8,  0xffffffffffffffff, 1  );
+  TEST_SRL( 9,  0xffffffffffffffff, 7  );
+  TEST_SRL( 10, 0xffffffffffffffff, 14 );
+  TEST_SRL( 11, 0xffffffffffffffff, 31 );
+
+  TEST_SRL( 12, 0x0000000021212121, 0  );
+  TEST_SRL( 13, 0x0000000021212121, 1  );
+  TEST_SRL( 14, 0x0000000021212121, 7  );
+  TEST_SRL( 15, 0x0000000021212121, 14 );
+  TEST_SRL( 16, 0x0000000021212121, 31 );
+
+  # Verify that shifts only use bottom six(rv64) or five(rv32) bits
+
+  TEST_RR_OP( 17, srl, 0x0000000021212121, 0x0000000021212121, 0xffffffffffffffc0 );
+  TEST_RR_OP( 18, srl, 0x0000000010909090, 0x0000000021212121, 0xffffffffffffffc1 );
+  TEST_RR_OP( 19, srl, 0x0000000000424242, 0x0000000021212121, 0xffffffffffffffc7 );
+  TEST_RR_OP( 20, srl, 0x0000000000008484, 0x0000000021212121, 0xffffffffffffffce );
+  TEST_RR_OP( 21, srl, 0x0000000000000000, 0x0000000021212121, 0xffffffffffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, srl, 0, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, srl, 0x00000001, 0x80000000, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, srl, 0x00000001, 0x80000000, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, srl, 0x00000001, 0x80000000, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, srl, 0x00000001, 0x80000000, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, srl, 0x01000000, 0x80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, srl, 0x00020000, 0x80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, srl, 0x00000001, 0x80000000, 31 );
+
+  TEST_RR_ZEROSRC1( 40, srl, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, srl, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, srl, 0 );
+  TEST_RR_ZERODEST( 43, srl, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/srli.S b/src/asmtest/isa/rv64ui/srli.S
new file mode 100644
index 0000000..3522957
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/srli.S
@@ -0,0 +1,71 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srli.S
+#-----------------------------------------------------------------------------
+#
+# Test srli instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+#define TEST_SRLI(n, v, a) \
+  TEST_IMM_OP(n, srli, ((v) & ((1 << (__riscv_xlen-1) << 1) - 1)) >> (a), v, a)
+
+  TEST_SRLI( 2,  0xffffffff80000000, 0  );
+  TEST_SRLI( 3,  0xffffffff80000000, 1  );
+  TEST_SRLI( 4,  0xffffffff80000000, 7  );
+  TEST_SRLI( 5,  0xffffffff80000000, 14 );
+  TEST_SRLI( 6,  0xffffffff80000001, 31 );
+
+  TEST_SRLI( 7,  0xffffffffffffffff, 0  );
+  TEST_SRLI( 8,  0xffffffffffffffff, 1  );
+  TEST_SRLI( 9,  0xffffffffffffffff, 7  );
+  TEST_SRLI( 10, 0xffffffffffffffff, 14 );
+  TEST_SRLI( 11, 0xffffffffffffffff, 31 );
+
+  TEST_SRLI( 12, 0x0000000021212121, 0  );
+  TEST_SRLI( 13, 0x0000000021212121, 1  );
+  TEST_SRLI( 14, 0x0000000021212121, 7  );
+  TEST_SRLI( 15, 0x0000000021212121, 14 );
+  TEST_SRLI( 16, 0x0000000021212121, 31 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, srli, 0x01000000, 0x80000000, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, srli, 0x01000000, 0x80000000, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, srli, 0x00020000, 0x80000000, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, srli, 0x00000001, 0x80000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, srli, 0x01000000, 0x80000000, 7  );
+  TEST_IMM_SRC1_BYPASS( 22, 1, srli, 0x00020000, 0x80000000, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, srli, 0x00000001, 0x80000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, srli, 0, 4 );
+  TEST_IMM_ZERODEST( 25, srli, 33, 10 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/srliw.S b/src/asmtest/isa/rv64ui/srliw.S
new file mode 100644
index 0000000..471042f
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/srliw.S
@@ -0,0 +1,75 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srliw.S
+#-----------------------------------------------------------------------------
+#
+# Test srliw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2,  srliw, 0xffffffff80000000, 0xffffffff80000000, 0  );
+  TEST_IMM_OP( 3,  srliw, 0x0000000040000000, 0xffffffff80000000, 1  );
+  TEST_IMM_OP( 4,  srliw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_IMM_OP( 5,  srliw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_IMM_OP( 6,  srliw, 0x0000000000000001, 0xffffffff80000001, 31 );
+
+  TEST_IMM_OP( 7,  srliw, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_IMM_OP( 8,  srliw, 0x000000007fffffff, 0xffffffffffffffff, 1  );
+  TEST_IMM_OP( 9,  srliw, 0x0000000001ffffff, 0xffffffffffffffff, 7  );
+  TEST_IMM_OP( 10, srliw, 0x000000000003ffff, 0xffffffffffffffff, 14 );
+  TEST_IMM_OP( 11, srliw, 0x0000000000000001, 0xffffffffffffffff, 31 );
+
+  TEST_IMM_OP( 12, srliw, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_IMM_OP( 13, srliw, 0x0000000010909090, 0x0000000021212121, 1  );
+  TEST_IMM_OP( 14, srliw, 0x0000000000424242, 0x0000000021212121, 7  );
+  TEST_IMM_OP( 15, srliw, 0x0000000000008484, 0x0000000021212121, 14 );
+  TEST_IMM_OP( 16, srliw, 0x0000000000000000, 0x0000000021212121, 31 );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_IMM_OP( 44, srliw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_IMM_OP( 45, srliw, 0x0000000001234567, 0xffffffff12345678, 4 );
+  TEST_IMM_OP( 46, srliw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_IMM_OP( 47, srliw, 0x0000000009234567, 0x0000000092345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 17, srliw, 0x0000000001000000, 0xffffffff80000000, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 18, 0, srliw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_IMM_DEST_BYPASS( 19, 1, srliw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_IMM_DEST_BYPASS( 20, 2, srliw, 0x0000000000000001, 0xffffffff80000001, 31 );
+
+  TEST_IMM_SRC1_BYPASS( 21, 0, srliw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_IMM_SRC1_BYPASS( 22, 1, srliw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_IMM_SRC1_BYPASS( 23, 2, srliw, 0x0000000000000001, 0xffffffff80000001, 31 );
+
+  TEST_IMM_ZEROSRC1( 24, srliw, 0, 31 );
+  TEST_IMM_ZERODEST( 25, srliw, 31, 28 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/srlw.S b/src/asmtest/isa/rv64ui/srlw.S
new file mode 100644
index 0000000..f0d1dae
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/srlw.S
@@ -0,0 +1,97 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srlw.S
+#-----------------------------------------------------------------------------
+#
+# Test srlw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  srlw, 0xffffffff80000000, 0xffffffff80000000, 0  );
+  TEST_RR_OP( 3,  srlw, 0x0000000040000000, 0xffffffff80000000, 1  );
+  TEST_RR_OP( 4,  srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_OP( 5,  srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_OP( 6,  srlw, 0x0000000000000001, 0xffffffff80000001, 31 );
+
+  TEST_RR_OP( 7,  srlw, 0xffffffffffffffff, 0xffffffffffffffff, 0  );
+  TEST_RR_OP( 8,  srlw, 0x000000007fffffff, 0xffffffffffffffff, 1  );
+  TEST_RR_OP( 9,  srlw, 0x0000000001ffffff, 0xffffffffffffffff, 7  );
+  TEST_RR_OP( 10, srlw, 0x000000000003ffff, 0xffffffffffffffff, 14 );
+  TEST_RR_OP( 11, srlw, 0x0000000000000001, 0xffffffffffffffff, 31 );
+
+  TEST_RR_OP( 12, srlw, 0x0000000021212121, 0x0000000021212121, 0  );
+  TEST_RR_OP( 13, srlw, 0x0000000010909090, 0x0000000021212121, 1  );
+  TEST_RR_OP( 14, srlw, 0x0000000000424242, 0x0000000021212121, 7  );
+  TEST_RR_OP( 15, srlw, 0x0000000000008484, 0x0000000021212121, 14 );
+  TEST_RR_OP( 16, srlw, 0x0000000000000000, 0x0000000021212121, 31 );
+
+  # Verify that shifts only use bottom five bits
+
+  TEST_RR_OP( 17, srlw, 0x0000000021212121, 0x0000000021212121, 0xffffffffffffffe0 );
+  TEST_RR_OP( 18, srlw, 0x0000000010909090, 0x0000000021212121, 0xffffffffffffffe1 );
+  TEST_RR_OP( 19, srlw, 0x0000000000424242, 0x0000000021212121, 0xffffffffffffffe7 );
+  TEST_RR_OP( 20, srlw, 0x0000000000008484, 0x0000000021212121, 0xffffffffffffffee );
+  TEST_RR_OP( 21, srlw, 0x0000000000000000, 0x0000000021212121, 0xffffffffffffffff );
+
+  # Verify that shifts ignore top 32 (using true 64-bit values)
+
+  TEST_RR_OP( 44, srlw, 0x0000000012345678, 0xffffffff12345678, 0 );
+  TEST_RR_OP( 45, srlw, 0x0000000001234567, 0xffffffff12345678, 4 );
+  TEST_RR_OP( 46, srlw, 0xffffffff92345678, 0x0000000092345678, 0 );
+  TEST_RR_OP( 47, srlw, 0x0000000009234567, 0x0000000092345678, 4 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 22, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC2_EQ_DEST( 23, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_EQ_DEST( 24, srlw, 0, 7 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 25, 0, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_DEST_BYPASS( 26, 1, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_DEST_BYPASS( 27, 2, srlw, 0x0000000000000001, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC12_BYPASS( 28, 0, 0, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 29, 0, 1, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 30, 0, 2, srlw, 0x0000000000000001, 0xffffffff80000000, 31 );
+  TEST_RR_SRC12_BYPASS( 31, 1, 0, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC12_BYPASS( 32, 1, 1, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC12_BYPASS( 33, 2, 0, srlw, 0x0000000000000001, 0xffffffff80000000, 31 );
+
+  TEST_RR_SRC21_BYPASS( 34, 0, 0, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 35, 0, 1, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 36, 0, 2, srlw, 0x0000000000000001, 0xffffffff80000000, 31 );
+  TEST_RR_SRC21_BYPASS( 37, 1, 0, srlw, 0x0000000001000000, 0xffffffff80000000, 7  );
+  TEST_RR_SRC21_BYPASS( 38, 1, 1, srlw, 0x0000000000020000, 0xffffffff80000000, 14 );
+  TEST_RR_SRC21_BYPASS( 39, 2, 0, srlw, 0x0000000000000001, 0xffffffff80000000, 31 );
+
+  TEST_RR_ZEROSRC1( 40, srlw, 0, 15 );
+  TEST_RR_ZEROSRC2( 41, srlw, 32, 32 );
+  TEST_RR_ZEROSRC12( 42, srlw, 0 );
+  TEST_RR_ZERODEST( 43, srlw, 1024, 2048 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sub.S b/src/asmtest/isa/rv64ui/sub.S
new file mode 100644
index 0000000..005bdea
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sub.S
@@ -0,0 +1,83 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sub.S
+#-----------------------------------------------------------------------------
+#
+# Test sub instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  sub, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 );
+  TEST_RR_OP( 3,  sub, 0x0000000000000000, 0x0000000000000001, 0x0000000000000001 );
+  TEST_RR_OP( 4,  sub, 0xfffffffffffffffc, 0x0000000000000003, 0x0000000000000007 );
+
+  TEST_RR_OP( 5,  sub, 0x0000000000008000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  sub, 0xffffffff80000000, 0xffffffff80000000, 0x0000000000000000 );
+  TEST_RR_OP( 7,  sub, 0xffffffff80008000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 8,  sub, 0xffffffffffff8001, 0x0000000000000000, 0x0000000000007fff );
+  TEST_RR_OP( 9,  sub, 0x000000007fffffff, 0x000000007fffffff, 0x0000000000000000 );
+  TEST_RR_OP( 10, sub, 0x000000007fff8000, 0x000000007fffffff, 0x0000000000007fff );
+
+  TEST_RR_OP( 11, sub, 0xffffffff7fff8001, 0xffffffff80000000, 0x0000000000007fff );
+  TEST_RR_OP( 12, sub, 0x0000000080007fff, 0x000000007fffffff, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 13, sub, 0x0000000000000001, 0x0000000000000000, 0xffffffffffffffff );
+  TEST_RR_OP( 14, sub, 0xfffffffffffffffe, 0xffffffffffffffff, 0x0000000000000001 );
+  TEST_RR_OP( 15, sub, 0x0000000000000000, 0xffffffffffffffff, 0xffffffffffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 16, sub, 2, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 17, sub, 3, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 18, sub, 0, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 19, 0, sub, 2, 13, 11 );
+  TEST_RR_DEST_BYPASS( 20, 1, sub, 3, 14, 11 );
+  TEST_RR_DEST_BYPASS( 21, 2, sub, 4, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 22, 0, 0, sub, 2, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 23, 0, 1, sub, 3, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 2, sub, 4, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 25, 1, 0, sub, 2, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 1, sub, 3, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 27, 2, 0, sub, 4, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 28, 0, 0, sub, 2, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 29, 0, 1, sub, 3, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 2, sub, 4, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 31, 1, 0, sub, 2, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 1, sub, 3, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 33, 2, 0, sub, 4, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 34, sub, 15, -15 );
+  TEST_RR_ZEROSRC2( 35, sub, 32, 32 );
+  TEST_RR_ZEROSRC12( 36, sub, 0 );
+  TEST_RR_ZERODEST( 37, sub, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/subw.S b/src/asmtest/isa/rv64ui/subw.S
new file mode 100644
index 0000000..9940d8c
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/subw.S
@@ -0,0 +1,83 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# subw.S
+#-----------------------------------------------------------------------------
+#
+# Test subw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  subw, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 );
+  TEST_RR_OP( 3,  subw, 0x0000000000000000, 0x0000000000000001, 0x0000000000000001 );
+  TEST_RR_OP( 4,  subw, 0xfffffffffffffffc, 0x0000000000000003, 0x0000000000000007 );
+
+  TEST_RR_OP( 5,  subw, 0x0000000000008000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  subw, 0xffffffff80000000, 0xffffffff80000000, 0x0000000000000000 );
+  TEST_RR_OP( 7,  subw, 0xffffffff80008000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 8,  subw, 0xffffffffffff8001, 0x0000000000000000, 0x0000000000007fff );
+  TEST_RR_OP( 9,  subw, 0x000000007fffffff, 0x000000007fffffff, 0x0000000000000000 );
+  TEST_RR_OP( 10, subw, 0x000000007fff8000, 0x000000007fffffff, 0x0000000000007fff );
+
+  TEST_RR_OP( 11, subw, 0x000000007fff8001, 0xffffffff80000000, 0x0000000000007fff );
+  TEST_RR_OP( 12, subw, 0xffffffff80007fff, 0x000000007fffffff, 0xffffffffffff8000 );
+
+  TEST_RR_OP( 13, subw, 0x0000000000000001, 0x0000000000000000, 0xffffffffffffffff );
+  TEST_RR_OP( 14, subw, 0xfffffffffffffffe, 0xffffffffffffffff, 0x0000000000000001 );
+  TEST_RR_OP( 15, subw, 0x0000000000000000, 0xffffffffffffffff, 0xffffffffffffffff );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 16, subw, 2, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 17, subw, 3, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 18, subw, 0, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 19, 0, subw, 2, 13, 11 );
+  TEST_RR_DEST_BYPASS( 20, 1, subw, 3, 14, 11 );
+  TEST_RR_DEST_BYPASS( 21, 2, subw, 4, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 22, 0, 0, subw, 2, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 23, 0, 1, subw, 3, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 24, 0, 2, subw, 4, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 25, 1, 0, subw, 2, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 26, 1, 1, subw, 3, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 27, 2, 0, subw, 4, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 28, 0, 0, subw, 2, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 29, 0, 1, subw, 3, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 30, 0, 2, subw, 4, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 31, 1, 0, subw, 2, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 32, 1, 1, subw, 3, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 33, 2, 0, subw, 4, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 34, subw, 15, -15 );
+  TEST_RR_ZEROSRC2( 35, subw, 32, 32 );
+  TEST_RR_ZEROSRC12( 36, subw, 0 );
+  TEST_RR_ZERODEST( 37, subw, 16, 30 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/sw.S b/src/asmtest/isa/rv64ui/sw.S
new file mode 100644
index 0000000..ab094b3
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/sw.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sw.S
+#-----------------------------------------------------------------------------
+#
+# Test sw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Basic tests
+  #-------------------------------------------------------------
+
+  TEST_ST_OP( 2, lw, sw, 0x0000000000aa00aa, 0,  tdat );
+  TEST_ST_OP( 3, lw, sw, 0xffffffffaa00aa00, 4,  tdat );
+  TEST_ST_OP( 4, lw, sw, 0x000000000aa00aa0, 8,  tdat );
+  TEST_ST_OP( 5, lw, sw, 0xffffffffa00aa00a, 12, tdat );
+
+  # Test with negative offset
+
+  TEST_ST_OP( 6, lw, sw, 0x0000000000aa00aa, -12, tdat8 );
+  TEST_ST_OP( 7, lw, sw, 0xffffffffaa00aa00, -8,  tdat8 );
+  TEST_ST_OP( 8, lw, sw, 0x000000000aa00aa0, -4,  tdat8 );
+  TEST_ST_OP( 9, lw, sw, 0xffffffffa00aa00a, 0,   tdat8 );
+
+  # Test with a negative base
+
+  TEST_CASE( 10, x5, 0x12345678, \
+    la  x1, tdat9; \
+    li  x2, 0x12345678; \
+    addi x4, x1, -32; \
+    sw x2, 32(x4); \
+    lw x5, 0(x1); \
+  )
+
+  # Test with unaligned base
+
+  TEST_CASE( 11, x5, 0x58213098, \
+    la  x1, tdat9; \
+    li  x2, 0x58213098; \
+    addi x1, x1, -3; \
+    sw x2, 7(x1); \
+    la  x4, tdat10; \
+    lw x5, 0(x4); \
+  )
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_ST_SRC12_BYPASS( 12, 0, 0, lw, sw, 0xffffffffaabbccdd, 0,  tdat );
+  TEST_ST_SRC12_BYPASS( 13, 0, 1, lw, sw, 0xffffffffdaabbccd, 4,  tdat );
+  TEST_ST_SRC12_BYPASS( 14, 0, 2, lw, sw, 0xffffffffddaabbcc, 8,  tdat );
+  TEST_ST_SRC12_BYPASS( 15, 1, 0, lw, sw, 0xffffffffcddaabbc, 12, tdat );
+  TEST_ST_SRC12_BYPASS( 16, 1, 1, lw, sw, 0xffffffffccddaabb, 16, tdat );
+  TEST_ST_SRC12_BYPASS( 17, 2, 0, lw, sw, 0xffffffffbccddaab, 20, tdat );
+
+  TEST_ST_SRC21_BYPASS( 18, 0, 0, lw, sw, 0x00112233, 0,  tdat );
+  TEST_ST_SRC21_BYPASS( 19, 0, 1, lw, sw, 0x30011223, 4,  tdat );
+  TEST_ST_SRC21_BYPASS( 20, 0, 2, lw, sw, 0x33001122, 8,  tdat );
+  TEST_ST_SRC21_BYPASS( 21, 1, 0, lw, sw, 0x23300112, 12, tdat );
+  TEST_ST_SRC21_BYPASS( 22, 1, 1, lw, sw, 0x22330011, 16, tdat );
+  TEST_ST_SRC21_BYPASS( 23, 2, 0, lw, sw, 0x12233001, 20, tdat );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+tdat:
+tdat1:  .word 0xdeadbeef
+tdat2:  .word 0xdeadbeef
+tdat3:  .word 0xdeadbeef
+tdat4:  .word 0xdeadbeef
+tdat5:  .word 0xdeadbeef
+tdat6:  .word 0xdeadbeef
+tdat7:  .word 0xdeadbeef
+tdat8:  .word 0xdeadbeef
+tdat9:  .word 0xdeadbeef
+tdat10: .word 0xdeadbeef
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/test.S b/src/asmtest/isa/rv64ui/test.S
new file mode 100644
index 0000000..2bd3306
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/test.S
@@ -0,0 +1,88 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# addi.S
+#-----------------------------------------------------------------------------
+#
+# Test addi instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  li    a2, 100
+  li    a0, 0
+  li    a0, 0
+  li    a0, 0
+  li    a0, 0
+
+loop:
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+  addi  a2, a2, -1
+  bnez  a2, loop
+
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  mul   a1, a2, a3
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+#  addi  a1, a0, 1
+
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/xor.S b/src/asmtest/isa/rv64ui/xor.S
new file mode 100644
index 0000000..c4e9552
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/xor.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# xor.S
+#-----------------------------------------------------------------------------
+#
+# Test xor instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_OP( 3, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_OP( 4, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_OP( 5, xor, 0x00ff00ff, 0xf00ff00f, 0xf0f0f0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 6, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC2_EQ_DEST( 7, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_EQ_DEST( 8, xor, 0x00000000, 0xff00ff00 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 9,  0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_DEST_BYPASS( 10, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_DEST_BYPASS( 11, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC12_BYPASS( 12, 0, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 13, 0, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 14, 0, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 15, 1, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC12_BYPASS( 16, 1, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC12_BYPASS( 17, 2, 0, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_SRC21_BYPASS( 18, 0, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 19, 0, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 20, 0, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 21, 1, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+  TEST_RR_SRC21_BYPASS( 22, 1, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+  TEST_RR_SRC21_BYPASS( 23, 2, 0, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+  TEST_RR_ZEROSRC1( 24, xor, 0xff00ff00, 0xff00ff00 );
+  TEST_RR_ZEROSRC2( 25, xor, 0x00ff00ff, 0x00ff00ff );
+  TEST_RR_ZEROSRC12( 26, xor, 0 );
+  TEST_RR_ZERODEST( 27, xor, 0x11111111, 0x22222222 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64ui/xori.S b/src/asmtest/isa/rv64ui/xori.S
new file mode 100644
index 0000000..eb59d12
--- /dev/null
+++ b/src/asmtest/isa/rv64ui/xori.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# xori.S
+#-----------------------------------------------------------------------------
+#
+# Test xori instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Logical tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_OP( 2, xori, 0xffffffffff00f00f, 0x0000000000ff0f00, 0xf0f );
+  TEST_IMM_OP( 3, xori, 0x000000000ff00f00, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_OP( 4, xori, 0x0000000000ff0ff0, 0x0000000000ff08ff, 0x70f );
+  TEST_IMM_OP( 5, xori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_SRC1_EQ_DEST( 6, xori, 0xffffffffff00f00f, 0xffffffffff00f700, 0x70f );
+
+   #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_IMM_DEST_BYPASS( 7,  0, xori, 0x000000000ff00f00, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_DEST_BYPASS( 8,  1, xori, 0x0000000000ff0ff0, 0x0000000000ff08ff, 0x70f );
+  TEST_IMM_DEST_BYPASS( 9,  2, xori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  TEST_IMM_SRC1_BYPASS( 10, 0, xori, 0x000000000ff00f00, 0x000000000ff00ff0, 0x0f0 );
+  TEST_IMM_SRC1_BYPASS( 11, 1, xori, 0x0000000000ff0ff0, 0x0000000000ff0fff, 0x00f );
+  TEST_IMM_SRC1_BYPASS( 12, 2, xori, 0xfffffffff00ff0ff, 0xfffffffff00ff00f, 0x0f0 );
+
+  TEST_IMM_ZEROSRC1( 13, xori, 0x0f0, 0x0f0 );
+  TEST_IMM_ZERODEST( 14, xori, 0x00ff00ff, 0x70f );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/Makefrag b/src/asmtest/isa/rv64um/Makefrag
new file mode 100644
index 0000000..64ae738
--- /dev/null
+++ b/src/asmtest/isa/rv64um/Makefrag
@@ -0,0 +1,14 @@
+#=======================================================================
+# Makefrag for rv64um tests
+#-----------------------------------------------------------------------
+
+rv64um_sc_tests = \
+	div divu divuw divw \
+	mul mulh mulhsu mulhu mulw \
+	rem remu remuw remw \
+
+rv64um_p_tests = $(addprefix rv64um-p-, $(rv64um_sc_tests))
+rv64um_v_tests = $(addprefix rv64um-v-, $(rv64um_sc_tests))
+rv64um_ps_tests = $(addprefix rv64um-ps-, $(rv64um_sc_tests))
+
+spike_tests += $(rv64um_p_tests) $(rv64um_v_tests)
diff --git a/src/asmtest/isa/rv64um/div.S b/src/asmtest/isa/rv64um/div.S
new file mode 100644
index 0000000..ee21f0c
--- /dev/null
+++ b/src/asmtest/isa/rv64um/div.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# div.S
+#-----------------------------------------------------------------------------
+#
+# Test div instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, div,  3,  20,   6 );
+  TEST_RR_OP( 3, div, -3, -20,   6 );
+  TEST_RR_OP( 4, div, -3,  20,  -6 );
+  TEST_RR_OP( 5, div,  3, -20,  -6 );
+
+  TEST_RR_OP( 6, div, -1<<63, -1<<63,  1 );
+  TEST_RR_OP( 7, div, -1<<63, -1<<63, -1 );
+
+  TEST_RR_OP( 8, div, -1, -1<<63, 0 );
+  TEST_RR_OP( 9, div, -1,      1, 0 );
+  TEST_RR_OP(10, div, -1,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/divu.S b/src/asmtest/isa/rv64um/divu.S
new file mode 100644
index 0000000..e63fd65
--- /dev/null
+++ b/src/asmtest/isa/rv64um/divu.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# divu.S
+#-----------------------------------------------------------------------------
+#
+# Test divu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, divu,                   3,  20,   6 );
+  TEST_RR_OP( 3, divu, 3074457345618258599, -20,   6 );
+  TEST_RR_OP( 4, divu,                   0,  20,  -6 );
+  TEST_RR_OP( 5, divu,                   0, -20,  -6 );
+
+  TEST_RR_OP( 6, divu, -1<<63, -1<<63,  1 );
+  TEST_RR_OP( 7, divu,     0,  -1<<63, -1 );
+
+  TEST_RR_OP( 8, divu, -1, -1<<63, 0 );
+  TEST_RR_OP( 9, divu, -1,      1, 0 );
+  TEST_RR_OP(10, divu, -1,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/divuw.S b/src/asmtest/isa/rv64um/divuw.S
new file mode 100644
index 0000000..4c9eee7
--- /dev/null
+++ b/src/asmtest/isa/rv64um/divuw.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# divuw.S
+#-----------------------------------------------------------------------------
+#
+# Test divuw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, divuw,         3,  20,   6 );
+  TEST_RR_OP( 3, divuw, 715827879, -20 << 32 >> 32,   6 );
+  TEST_RR_OP( 4, divuw,         0,  20,  -6 );
+  TEST_RR_OP( 5, divuw,         0, -20,  -6 );
+
+  TEST_RR_OP( 6, divuw, -1<<31, -1<<31,  1 );
+  TEST_RR_OP( 7, divuw, 0,      -1<<31, -1 );
+
+  TEST_RR_OP( 8, divuw, -1, -1<<31, 0 );
+  TEST_RR_OP( 9, divuw, -1,      1, 0 );
+  TEST_RR_OP(10, divuw, -1,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/divw.S b/src/asmtest/isa/rv64um/divw.S
new file mode 100644
index 0000000..4cffa1a
--- /dev/null
+++ b/src/asmtest/isa/rv64um/divw.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# divw.S
+#-----------------------------------------------------------------------------
+#
+# Test divw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, divw,  3,  20,   6 );
+  TEST_RR_OP( 3, divw, -3, -20,   6 );
+  TEST_RR_OP( 4, divw, -3,  20,  -6 );
+  TEST_RR_OP( 5, divw,  3, -20,  -6 );
+
+  TEST_RR_OP( 6, divw, -1<<31, -1<<31,  1 );
+  TEST_RR_OP( 7, divw, -1<<31, -1<<31, -1 );
+
+  TEST_RR_OP( 8, divw, -1, -1<<31, 0 );
+  TEST_RR_OP( 9, divw, -1,      1, 0 );
+  TEST_RR_OP(10, divw, -1,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/mul.S b/src/asmtest/isa/rv64um/mul.S
new file mode 100644
index 0000000..c647e97
--- /dev/null
+++ b/src/asmtest/isa/rv64um/mul.S
@@ -0,0 +1,78 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mul.S
+#-----------------------------------------------------------------------------
+#
+# Test mul instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP(32,  mul, 0x0000000000001200, 0x0000000000007e00, 0x6db6db6db6db6db7 );
+  TEST_RR_OP(33,  mul, 0x0000000000001240, 0x0000000000007fc0, 0x6db6db6db6db6db7 );
+
+  TEST_RR_OP( 2,  mul, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  mul, 0x00000001, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  mul, 0x00000015, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  mul, 0x0000000000000000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  mul, 0x0000000000000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  mul, 0x0000400000000000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP(30,  mul, 0x000000000000ff7f, 0xaaaaaaaaaaaaaaab, 0x000000000002fe7d );
+  TEST_RR_OP(31,  mul, 0x000000000000ff7f, 0x000000000002fe7d, 0xaaaaaaaaaaaaaaab );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 8, mul, 143, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 9, mul, 154, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 10, mul, 169, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 11, 0, mul, 143, 13, 11 );
+  TEST_RR_DEST_BYPASS( 12, 1, mul, 154, 14, 11 );
+  TEST_RR_DEST_BYPASS( 13, 2, mul, 165, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 14, 0, 0, mul, 143, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 15, 0, 1, mul, 154, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 16, 0, 2, mul, 165, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 17, 1, 0, mul, 143, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 18, 1, 1, mul, 154, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 19, 2, 0, mul, 165, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 20, 0, 0, mul, 143, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 21, 0, 1, mul, 154, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 22, 0, 2, mul, 165, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 23, 1, 0, mul, 143, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 24, 1, 1, mul, 154, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 25, 2, 0, mul, 165, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 26, mul, 0, 31 );
+  TEST_RR_ZEROSRC2( 27, mul, 0, 32 );
+  TEST_RR_ZEROSRC12( 28, mul, 0 );
+  TEST_RR_ZERODEST( 29, mul, 33, 34 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/mulh.S b/src/asmtest/isa/rv64um/mulh.S
new file mode 100644
index 0000000..1fd12a1
--- /dev/null
+++ b/src/asmtest/isa/rv64um/mulh.S
@@ -0,0 +1,72 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mulh.S
+#-----------------------------------------------------------------------------
+#
+# Test mulh instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  mulh, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  mulh, 0x00000000, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  mulh, 0x00000000, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  mulh, 0x0000000000000000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  mulh, 0x0000000000000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  mulh, 0x0000000000000000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 8, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC2_EQ_DEST( 9, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_EQ_DEST( 10, mulh, 169, 13<<32 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 11, 0, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 12, 1, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 13, 2, mulh, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC12_BYPASS( 14, 0, 0, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 15, 0, 1, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 16, 0, 2, mulh, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 17, 1, 0, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 18, 1, 1, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 19, 2, 0, mulh, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC21_BYPASS( 20, 0, 0, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 21, 0, 1, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 22, 0, 2, mulh, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 23, 1, 0, mulh, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 24, 1, 1, mulh, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 25, 2, 0, mulh, 165, 15<<32, 11<<32 );
+
+  TEST_RR_ZEROSRC1( 26, mulh, 0, 31<<32 );
+  TEST_RR_ZEROSRC2( 27, mulh, 0, 32<<32 );
+  TEST_RR_ZEROSRC12( 28, mulh, 0 );
+  TEST_RR_ZERODEST( 29, mulh, 33<<32, 34<<32 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/mulhsu.S b/src/asmtest/isa/rv64um/mulhsu.S
new file mode 100644
index 0000000..c037db2
--- /dev/null
+++ b/src/asmtest/isa/rv64um/mulhsu.S
@@ -0,0 +1,72 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mulhsu.S
+#-----------------------------------------------------------------------------
+#
+# Test mulhsu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  mulhsu, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  mulhsu, 0x00000000, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  mulhsu, 0x00000000, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  mulhsu, 0x0000000000000000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  mulhsu, 0x0000000000000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  mulhsu, 0xffffffff80000000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 8, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC2_EQ_DEST( 9, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_EQ_DEST( 10, mulhsu, 169, 13<<32 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 11, 0, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 12, 1, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 13, 2, mulhsu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC12_BYPASS( 14, 0, 0, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 15, 0, 1, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 16, 0, 2, mulhsu, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 17, 1, 0, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 18, 1, 1, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 19, 2, 0, mulhsu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC21_BYPASS( 20, 0, 0, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 21, 0, 1, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 22, 0, 2, mulhsu, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 23, 1, 0, mulhsu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 24, 1, 1, mulhsu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 25, 2, 0, mulhsu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_ZEROSRC1( 26, mulhsu, 0, 31<<32 );
+  TEST_RR_ZEROSRC2( 27, mulhsu, 0, 32<<32 );
+  TEST_RR_ZEROSRC12( 28, mulhsu, 0 );
+  TEST_RR_ZERODEST( 29, mulhsu, 33<<32, 34<<32 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/mulhu.S b/src/asmtest/isa/rv64um/mulhu.S
new file mode 100644
index 0000000..aa7b762
--- /dev/null
+++ b/src/asmtest/isa/rv64um/mulhu.S
@@ -0,0 +1,75 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mulhu.S
+#-----------------------------------------------------------------------------
+#
+# Test mulhu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  mulhu, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  mulhu, 0x00000000, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  mulhu, 0x00000000, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  mulhu, 0x0000000000000000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  mulhu, 0x0000000000000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  mulhu, 0xffffffff7fff8000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  TEST_RR_OP(30,  mulhu, 0x000000000001fefe, 0xaaaaaaaaaaaaaaab, 0x000000000002fe7d );
+  TEST_RR_OP(31,  mulhu, 0x000000000001fefe, 0x000000000002fe7d, 0xaaaaaaaaaaaaaaab );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 8, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC2_EQ_DEST( 9, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_EQ_DEST( 10, mulhu, 169, 13<<32 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 11, 0, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 12, 1, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_DEST_BYPASS( 13, 2, mulhu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC12_BYPASS( 14, 0, 0, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 15, 0, 1, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 16, 0, 2, mulhu, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 17, 1, 0, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 18, 1, 1, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC12_BYPASS( 19, 2, 0, mulhu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_SRC21_BYPASS( 20, 0, 0, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 21, 0, 1, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 22, 0, 2, mulhu, 165, 15<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 23, 1, 0, mulhu, 143, 13<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 24, 1, 1, mulhu, 154, 14<<32, 11<<32 );
+  TEST_RR_SRC21_BYPASS( 25, 2, 0, mulhu, 165, 15<<32, 11<<32 );
+
+  TEST_RR_ZEROSRC1( 26, mulhu, 0, 31<<32 );
+  TEST_RR_ZEROSRC2( 27, mulhu, 0, 32<<32 );
+  TEST_RR_ZEROSRC12( 28, mulhu, 0 );
+  TEST_RR_ZERODEST( 29, mulhu, 33<<32, 34<<32 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/mulw.S b/src/asmtest/isa/rv64um/mulw.S
new file mode 100644
index 0000000..379c3f2
--- /dev/null
+++ b/src/asmtest/isa/rv64um/mulw.S
@@ -0,0 +1,72 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# mulw.S
+#-----------------------------------------------------------------------------
+#
+# Test mulw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2,  mulw, 0x00000000, 0x00000000, 0x00000000 );
+  TEST_RR_OP( 3,  mulw, 0x00000001, 0x00000001, 0x00000001 );
+  TEST_RR_OP( 4,  mulw, 0x00000015, 0x00000003, 0x00000007 );
+
+  TEST_RR_OP( 5,  mulw, 0x0000000000000000, 0x0000000000000000, 0xffffffffffff8000 );
+  TEST_RR_OP( 6,  mulw, 0x0000000000000000, 0xffffffff80000000, 0x00000000 );
+  TEST_RR_OP( 7,  mulw, 0x0000000000000000, 0xffffffff80000000, 0xffffffffffff8000 );
+
+  #-------------------------------------------------------------
+  # Source/Destination tests
+  #-------------------------------------------------------------
+
+  TEST_RR_SRC1_EQ_DEST( 8, mulw, 143, 13, 11 );
+  TEST_RR_SRC2_EQ_DEST( 9, mulw, 154, 14, 11 );
+  TEST_RR_SRC12_EQ_DEST( 10, mulw, 169, 13 );
+
+  #-------------------------------------------------------------
+  # Bypassing tests
+  #-------------------------------------------------------------
+
+  TEST_RR_DEST_BYPASS( 11, 0, mulw, 143, 13, 11 );
+  TEST_RR_DEST_BYPASS( 12, 1, mulw, 154, 14, 11 );
+  TEST_RR_DEST_BYPASS( 13, 2, mulw, 165, 15, 11 );
+
+  TEST_RR_SRC12_BYPASS( 14, 0, 0, mulw, 143, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 15, 0, 1, mulw, 154, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 16, 0, 2, mulw, 165, 15, 11 );
+  TEST_RR_SRC12_BYPASS( 17, 1, 0, mulw, 143, 13, 11 );
+  TEST_RR_SRC12_BYPASS( 18, 1, 1, mulw, 154, 14, 11 );
+  TEST_RR_SRC12_BYPASS( 19, 2, 0, mulw, 165, 15, 11 );
+
+  TEST_RR_SRC21_BYPASS( 20, 0, 0, mulw, 143, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 21, 0, 1, mulw, 154, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 22, 0, 2, mulw, 165, 15, 11 );
+  TEST_RR_SRC21_BYPASS( 23, 1, 0, mulw, 143, 13, 11 );
+  TEST_RR_SRC21_BYPASS( 24, 1, 1, mulw, 154, 14, 11 );
+  TEST_RR_SRC21_BYPASS( 25, 2, 0, mulw, 165, 15, 11 );
+
+  TEST_RR_ZEROSRC1( 26, mulw, 0, 31 );
+  TEST_RR_ZEROSRC2( 27, mulw, 0, 32 );
+  TEST_RR_ZEROSRC12( 28, mulw, 0 );
+  TEST_RR_ZERODEST( 29, mulw, 33, 34 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/rem.S b/src/asmtest/isa/rv64um/rem.S
new file mode 100644
index 0000000..e3248ff
--- /dev/null
+++ b/src/asmtest/isa/rv64um/rem.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# rem.S
+#-----------------------------------------------------------------------------
+#
+# Test rem instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, rem,  2,  20,   6 );
+  TEST_RR_OP( 3, rem, -2, -20,   6 );
+  TEST_RR_OP( 4, rem,  2,  20,  -6 );
+  TEST_RR_OP( 5, rem, -2, -20,  -6 );
+
+  TEST_RR_OP( 6, rem,  0, -1<<63,  1 );
+  TEST_RR_OP( 7, rem,  0, -1<<63, -1 );
+
+  TEST_RR_OP( 8, rem, -1<<63, -1<<63, 0 );
+  TEST_RR_OP( 9, rem,      1,      1, 0 );
+  TEST_RR_OP(10, rem,      0,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/remu.S b/src/asmtest/isa/rv64um/remu.S
new file mode 100644
index 0000000..6946d0d
--- /dev/null
+++ b/src/asmtest/isa/rv64um/remu.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# remu.S
+#-----------------------------------------------------------------------------
+#
+# Test remu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, remu,   2,  20,   6 );
+  TEST_RR_OP( 3, remu,   2, -20,   6 );
+  TEST_RR_OP( 4, remu,  20,  20,  -6 );
+  TEST_RR_OP( 5, remu, -20, -20,  -6 );
+
+  TEST_RR_OP( 6, remu,      0, -1<<63,  1 );
+  TEST_RR_OP( 7, remu, -1<<63, -1<<63, -1 );
+
+  TEST_RR_OP( 8, remu, -1<<63, -1<<63, 0 );
+  TEST_RR_OP( 9, remu,      1,      1, 0 );
+  TEST_RR_OP(10, remu,      0,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/remuw.S b/src/asmtest/isa/rv64um/remuw.S
new file mode 100644
index 0000000..334b5c5
--- /dev/null
+++ b/src/asmtest/isa/rv64um/remuw.S
@@ -0,0 +1,41 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# remuw.S
+#-----------------------------------------------------------------------------
+#
+# Test remuw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, remuw,   2,  20,   6 );
+  TEST_RR_OP( 3, remuw,   2, -20,   6 );
+  TEST_RR_OP( 4, remuw,  20,  20,  -6 );
+  TEST_RR_OP( 5, remuw, -20, -20,  -6 );
+
+  TEST_RR_OP( 6, remuw,      0, -1<<31,  1 );
+  TEST_RR_OP( 7, remuw, -1<<31, -1<<31, -1 );
+
+  TEST_RR_OP( 8, remuw, -1<<31, -1<<31, 0 );
+  TEST_RR_OP( 9, remuw,      1,      1, 0 );
+  TEST_RR_OP(10, remuw,      0,      0, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END
diff --git a/src/asmtest/isa/rv64um/remw.S b/src/asmtest/isa/rv64um/remw.S
new file mode 100644
index 0000000..3ae8e3d
--- /dev/null
+++ b/src/asmtest/isa/rv64um/remw.S
@@ -0,0 +1,42 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# remw.S
+#-----------------------------------------------------------------------------
+#
+# Test remw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  #-------------------------------------------------------------
+  # Arithmetic tests
+  #-------------------------------------------------------------
+
+  TEST_RR_OP( 2, remw,  2,  20,   6 );
+  TEST_RR_OP( 3, remw, -2, -20,   6 );
+  TEST_RR_OP( 4, remw,  2,  20,  -6 );
+  TEST_RR_OP( 5, remw, -2, -20,  -6 );
+
+  TEST_RR_OP( 6, remw,  0, -1<<31,  1 );
+  TEST_RR_OP( 7, remw,  0, -1<<31, -1 );
+
+  TEST_RR_OP( 8, remw, -1<<31, -1<<31, 0 );
+  TEST_RR_OP( 9, remw,      1,      1, 0 );
+  TEST_RR_OP(10, remw,      0,      0, 0 );
+  TEST_RR_OP(11, remw, 0xfffffffffffff897,0xfffffffffffff897, 0 );
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+RVTEST_DATA_END