aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/debug.yml2
-rw-r--r--.github/workflows/spike-openocd-tests.yml20
-rw-r--r--benchmarks/Makefile15
-rw-r--r--configure.ac8
-rwxr-xr-xdebug/gdbserver.py122
-rw-r--r--debug/targets.py7
-rwxr-xr-xdebug/targets/RISC-V/spike32.lds9
-rwxr-xr-xdebug/targets/RISC-V/spike64.lds9
-rwxr-xr-xdebug/testbin17704 -> 0 bytes
-rw-r--r--debug/testlib.py26
m---------env0
-rw-r--r--isa/Makefile8
-rw-r--r--isa/hypervisor/2-stage_translation.S136
-rw-r--r--isa/hypervisor/Makefrag8
-rw-r--r--isa/macros/scalar/test_macros.h177
-rw-r--r--isa/rv32mi/Makefrag2
-rw-r--r--isa/rv32mi/instret_overflow.S8
-rw-r--r--isa/rv32mi/pmpaddr.S8
-rw-r--r--isa/rv32ud/fcvt_w.S6
-rw-r--r--isa/rv32ud/recoding.S2
-rw-r--r--isa/rv32ui/Makefrag4
-rw-r--r--isa/rv32ui/ld_st.S7
-rw-r--r--isa/rv32ui/st_ld.S7
-rw-r--r--isa/rv64mi/Makefrag3
-rw-r--r--isa/rv64mi/access.S70
-rw-r--r--isa/rv64mi/illegal.S12
-rw-r--r--isa/rv64mi/instret_overflow.S42
-rw-r--r--isa/rv64mi/ma_addr.S2
-rw-r--r--isa/rv64mi/pmpaddr.S154
-rw-r--r--isa/rv64si/dirty.S2
-rw-r--r--isa/rv64si/icache-alias.S2
-rw-r--r--isa/rv64si/ma_fetch.S6
-rw-r--r--isa/rv64ua/amomaxu_w.S4
-rw-r--r--isa/rv64ua/amominu_w.S4
-rw-r--r--isa/rv64ud/fadd.S4
-rw-r--r--isa/rv64ud/fclass.S8
-rw-r--r--isa/rv64ud/fcmp.S8
-rw-r--r--isa/rv64ud/fcvt.S4
-rw-r--r--isa/rv64ud/fcvt_w.S8
-rw-r--r--isa/rv64ud/fmin.S6
-rw-r--r--isa/rv64ud/move.S12
-rw-r--r--isa/rv64uf/fadd.S2
-rw-r--r--isa/rv64uf/fclass.S8
-rw-r--r--isa/rv64uf/fcmp.S6
-rw-r--r--isa/rv64uf/fcvt_w.S8
-rw-r--r--isa/rv64uf/fmin.S4
-rw-r--r--isa/rv64ui/Makefrag4
-rw-r--r--isa/rv64ui/ld_st.S130
-rw-r--r--isa/rv64ui/st_ld.S130
-rw-r--r--isa/rv64uzfh/fadd.S2
-rw-r--r--isa/rv64uzfh/fclass.S6
-rw-r--r--isa/rv64uzfh/fcvt_w.S4
-rw-r--r--isa/rv64uzfh/fmin.S6
-rw-r--r--isa/rv64uziccid/Makefrag9
-rw-r--r--isa/rv64uziccid/ziccid.S48
55 files changed, 1073 insertions, 236 deletions
diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml
index 7b6beb4..81fe15a 100644
--- a/.github/workflows/debug.yml
+++ b/.github/workflows/debug.yml
@@ -7,7 +7,7 @@ name: Check Debug Code Style (pylint)
jobs:
check:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
steps:
- name: Checkout Code
uses: actions/checkout@v3
diff --git a/.github/workflows/spike-openocd-tests.yml b/.github/workflows/spike-openocd-tests.yml
index 577bd95..e67f2a6 100644
--- a/.github/workflows/spike-openocd-tests.yml
+++ b/.github/workflows/spike-openocd-tests.yml
@@ -34,16 +34,16 @@ on:
jobs:
test:
name: Test debug (Ubuntu)
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: recursive
- name: Install packages
run: |
sudo apt-get update
- sudo apt-get install -y device-tree-compiler build-essential
+ sudo apt-get install -y device-tree-compiler build-essential libjim-dev
- name: Get revisions of dependencies
run: |
@@ -57,7 +57,7 @@ jobs:
- name: Get the toolchain from cache (if available)
id: cache-restore-toolchain
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: /opt/riscv/toolchain
key: "toolchain-${{env.TOOLCHAIN_URL}}"
@@ -74,14 +74,14 @@ jobs:
- name: Save the toolchain to the cache (if necessary)
id: cache-save-toolchain
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: /opt/riscv/toolchain
key: "toolchain-${{env.TOOLCHAIN_URL}}"
- name: Get OpenOCD from cache (if available)
id: cache-restore-openocd
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: /opt/riscv/openocd
key: "openocd-${{env.OPENOCD_COMMIT}}"
@@ -106,14 +106,14 @@ jobs:
- if: ${{ steps.cache-restore-openocd.outputs.cache-hit != 'true' }}
name: Save OpenOCD to cache (if built)
id: cache-save-openocd
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: /opt/riscv/openocd
key: "openocd-${{env.OPENOCD_COMMIT}}"
- name: Get spike from cache (if available)
id: cache-restore-spike
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: /opt/riscv/spike
key: "spike-${{env.SPIKE_COMMIT}}"
@@ -138,7 +138,7 @@ jobs:
- if: ${{ steps.cache-restore-spike.outputs.cache-hit != 'true' }}
name: Save spike to cache (if built)
id: cache-save-spike
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: /opt/riscv/spike
key: "spike-${{env.SPIKE_COMMIT}}"
@@ -166,7 +166,7 @@ jobs:
- name: Archive test logs
# Proceed even if there was a failed test
if: ${{ success() || failure() }}
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: test-logs
path: riscv-tests/debug/logs
diff --git a/benchmarks/Makefile b/benchmarks/Makefile
index d38f8af..acc4573 100644
--- a/benchmarks/Makefile
+++ b/benchmarks/Makefile
@@ -24,7 +24,7 @@ instbasedir = $(UCB_VLSI_HOME)/install
# Sources
#--------------------------------------------------------------------
-bmarks = \
+base_bmarks = \
median \
qsort \
rsort \
@@ -39,21 +39,27 @@ bmarks = \
mt-matmul \
mt-memcpy \
pmp \
+
+vec_bmarks = \
vec-memcpy \
vec-daxpy \
vec-sgemm \
vec-strcmp \
+bmarks = $(base_bmarks) $(vec_bmarks)
+
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
-RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -march=rv$(XLEN)gcv -mabi=$(ABI)
+RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -Wno-implicit-int -Wno-implicit-function-declaration -mabi=$(ABI)
RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs)
RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lm -lgcc -T $(src_dir)/common/test.ld
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
+RISCV_MARCH ?= rv$(XLEN)gc
+RISCV_VMARCH ?= rv$(XLEN)gcv
RISCV_SIM ?= spike --isa=rv$(XLEN)gcv
incs += -I$(src_dir)/../env -I$(src_dir)/common $(addprefix -I$(src_dir)/, $(bmarks))
@@ -61,10 +67,11 @@ objs :=
define compile_template
$(1).riscv: $(wildcard $(src_dir)/$(1)/*) $(wildcard $(src_dir)/common/*)
- $$(RISCV_GCC) $$(incs) $$(RISCV_GCC_OPTS) -o $$@ $(wildcard $(src_dir)/$(1)/*.c) $(wildcard $(src_dir)/$(1)/*.S) $(wildcard $(src_dir)/common/*.c) $(wildcard $(src_dir)/common/*.S) $$(RISCV_LINK_OPTS)
+ $$(RISCV_GCC) $$(incs) $$(RISCV_GCC_OPTS) -march=$(2) -o $$@ $(wildcard $(src_dir)/$(1)/*.c) $(wildcard $(src_dir)/$(1)/*.S) $(wildcard $(src_dir)/common/*.c) $(wildcard $(src_dir)/common/*.S) $$(RISCV_LINK_OPTS)
endef
-$(foreach bmark,$(bmarks),$(eval $(call compile_template,$(bmark))))
+$(foreach bmark,$(base_bmarks),$(eval $(call compile_template,$(bmark),$(RISCV_MARCH))))
+$(foreach bmark,$(vec_bmarks),$(eval $(call compile_template,$(bmark),$(RISCV_VMARCH))))
#------------------------------------------------------------
# Build and run benchmarks on riscv simulator
diff --git a/configure.ac b/configure.ac
index ebfd649..3b8e572 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(riscv-tests, 1.0)
+AC_INIT([riscv-tests],[1.0])
cross_compiling=yes
AC_PROG_CC
@@ -11,6 +11,6 @@ AC_ARG_WITH(xlen,
)
-AC_OUTPUT(
- Makefile
-)
+AC_CONFIG_FILES([Makefile
+])
+AC_OUTPUT
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index 235814a..92f7ce3 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -66,6 +66,20 @@ def srec_parse(line):
if typ == b'S0':
# header
return 0, 0, 0
+ elif typ == b'S1':
+ # data with 16-bit address
+ address = int(line[4:8], 16)
+ for i in range(4, count+1):
+ data += f"{int(line[2 * i:2 * i + 2], 16):c}"
+ # Ignore the checksum.
+ return 1, address, data
+ elif typ == b'S2':
+ # data with 24-bit address
+ address = int(line[4:10], 16)
+ for i in range(5, count+1):
+ data += f"{int(line[2 * i:2 * i + 2], 16):c}"
+ # Ignore the checksum.
+ return 2, address, data
elif typ == b'S3':
# data with 32-bit address
# Any higher bits were chopped off.
@@ -74,9 +88,9 @@ def srec_parse(line):
data += f"{int(line[2 * i:2 * i + 2], 16):c}"
# Ignore the checksum.
return 3, address, data
- elif typ == b'S7':
+ elif typ in (b'S7', b'S8', b'S9'):
# ignore execution start field
- return 7, 0, 0
+ return int(typ[-1]), 0, 0
else:
raise TestFailed(f"Unsupported SREC type {typ!r}.")
@@ -264,6 +278,9 @@ class MemTest64(SimpleMemoryTest):
class MemTestReadInvalid(SimpleMemoryTest):
def test(self):
bad_address = self.hart.bad_address
+ if self.target.support_set_pmp_deny:
+ self.set_pmp_deny(bad_address)
+ self.gdb.command("monitor riscv set_mem_access progbuf abstract")
good_address = self.hart.ram + 0x80
self.write_nop_program(2)
@@ -279,6 +296,10 @@ class MemTestReadInvalid(SimpleMemoryTest):
self.gdb.stepi() # Don't let gdb cache register read
assertEqual(self.gdb.p(f"*((int*)0x{good_address:x})"), 0xabcdef)
assertEqual(self.gdb.p("$s0"), 0x12345678)
+ if self.target.support_set_pmp_deny:
+ self.reset_pmp_deny()
+ self.gdb.command("monitor riscv set_mem_access progbuf sysbus "
+ "abstract")
#class MemTestWriteInvalid(SimpleMemoryTest):
# def test(self):
@@ -389,7 +410,7 @@ class MemTestBlock(GdbTest):
highest_seen = 0
for line in b:
record_type, address, line_data = srec_parse(line)
- if record_type == 3:
+ if record_type in (1, 2, 3):
offset = address - (self.hart.ram & 0xffffffff)
written_data = data[offset:offset+len(line_data)]
highest_seen += len(line_data)
@@ -676,6 +697,47 @@ class HwbpManual(DebugTest):
return self.target.support_manual_hwbp and \
self.hart.instruction_hardware_breakpoint_count >= 1
+ # TODO: This can be removed once
+ # https://github.com/riscv-collab/riscv-openocd/pull/1111
+ # is merged.
+ def check_reserve_trigger_support(self):
+ not_supp_msg = "RESERVE_TRIGGER_NOT_SUPPORTED"
+ if not_supp_msg in self.gdb.command(
+ "monitor if [catch {riscv reserve_trigger 0 on} e] {echo " +
+ not_supp_msg + "}").splitlines():
+ raise TestNotApplicable
+
+ def set_manual_trigger(self, tdata1, tdata2):
+ for tselect in itertools.count(0):
+ self.gdb.p(f"$tselect={tselect}")
+ if self.gdb.p("$tselect") != tselect:
+ raise TestNotApplicable
+
+ self.gdb.command(
+ f"monitor riscv reserve_trigger {tselect} on")
+
+ # Need to disable the trigger before writing tdata2
+ self.gdb.p("$tdata1=0")
+ # Need to write a valid value to tdata2 before writing tdata1
+ self.gdb.p(f"$tdata2=0x{tdata2:x}")
+ self.gdb.p(f"$tdata1=0x{tdata1:x}")
+
+ tdata2_rb = self.gdb.p("$tdata2")
+ tdata1_rb = self.gdb.p("$tdata1")
+ if tdata1_rb == tdata1 and tdata2_rb == tdata2:
+ return tselect
+
+ type_rb = tdata1_rb & MCONTROL_TYPE(self.hart.xlen)
+ type_none = set_field(0, MCONTROL_TYPE(self.hart.xlen),
+ MCONTROL_TYPE_NONE)
+ if type_rb == type_none:
+ raise TestNotApplicable
+
+ self.gdb.p("$tdata1=0")
+ self.gdb.command(
+ f"monitor riscv reserve_trigger {tselect} off")
+ assert False
+
def test(self):
if not self.hart.honors_tdata1_hmode:
# Run to main before setting the breakpoint, because startup code
@@ -684,6 +746,12 @@ class HwbpManual(DebugTest):
self.gdb.c()
self.gdb.command("delete")
+
+ # TODO: This can be removed once
+ # https://github.com/riscv-collab/riscv-openocd/pull/1111
+ # is merged.
+ self.check_reserve_trigger_support()
+
#self.gdb.hbreak("rot13")
tdata1 = MCONTROL_DMODE(self.hart.xlen)
tdata1 = set_field(tdata1, MCONTROL_TYPE(self.hart.xlen),
@@ -692,24 +760,9 @@ class HwbpManual(DebugTest):
tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL)
tdata1 |= MCONTROL_M | MCONTROL_S | MCONTROL_U | MCONTROL_EXECUTE
- tselect = 0
- while True:
- self.gdb.p(f"$tselect={tselect}")
- value = self.gdb.p("$tselect")
- if value != tselect:
- raise TestNotApplicable
- # Need to disable the trigger before writing tdata2
- self.gdb.p("$tdata1=0")
- # Need to write a valid value to tdata2 before writing tdata1
- self.gdb.p("$tdata2=&rot13")
- self.gdb.p(f"$tdata1=0x{tdata1:x}")
- value = self.gdb.p("$tdata1")
- if value == tdata1:
- break
- if value & MCONTROL_TYPE(self.hart.xlen) == MCONTROL_TYPE_NONE:
- raise TestNotApplicable
- self.gdb.p("$tdata1=0")
- tselect += 1
+ tdata2 = self.gdb.p("&rot13")
+
+ tselect = self.set_manual_trigger(tdata1, tdata2)
# The breakpoint should be hit exactly 2 times.
for _ in range(2):
@@ -726,14 +779,22 @@ class HwbpManual(DebugTest):
self.gdb.c()
before = self.gdb.p("$pc")
assertEqual(before, self.gdb.p("&crc32a"))
+
self.gdb.stepi()
- after = self.gdb.p("$pc")
- assertNotEqual(before, after)
+ assertEqual(before, self.gdb.p("$pc"),
+ "OpenOCD shouldn't disable a reserved trigger.")
# Remove the manual HW breakpoint.
assertEqual(tselect, self.gdb.p("$tselect"))
self.gdb.p("$tdata1=0")
+ self.gdb.stepi()
+ assertNotEqual(before, self.gdb.p("$pc"),
+ "OpenOCD should be able to step from a removed BP.")
+
+ self.gdb.command(
+ f"monitor riscv reserve_trigger {tselect} off")
+
self.gdb.b("_exit")
self.exit()
@@ -1056,9 +1117,9 @@ class InterruptTest(GdbSingleHartTest):
self.disable_timer()
return
- self.disable_timer()
assertGreater(interrupt_count, 1000)
assertGreater(local, 1000)
+ self.disable_timer()
def postMortem(self):
GdbSingleHartTest.postMortem(self)
@@ -2125,8 +2186,13 @@ class EtriggerTest(DebugTest):
def test(self):
# Set trigger on Load access fault
self.gdb.command("monitor riscv etrigger set m 0x20")
- # Set fox to a null pointer so we'll get a load access exception later.
- self.gdb.p("fox=(char*)0")
+ # Set fox to a bad pointer so we'll get a load access exception later.
+ # Use NULL if a known-bad address is not provided.
+ bad_address = self.hart.bad_address or 0
+ if self.target.support_set_pmp_deny:
+ self.set_pmp_deny(bad_address)
+ self.gdb.command("monitor riscv set_mem_access progbuf abstract")
+ self.gdb.p(f"fox=(char*)0x{bad_address:08x}")
output = self.gdb.c()
# We should not be at handle_trap
assertNotIn("handle_trap", output)
@@ -2134,6 +2200,10 @@ class EtriggerTest(DebugTest):
# actual exception handler.
assertIn("breakpoint", output)
assertIn("trap_entry", self.gdb.where())
+ if self.target.support_set_pmp_deny:
+ self.reset_pmp_deny()
+ self.gdb.command("monitor riscv set_mem_access progbuf sysbus "
+ "abstract")
class IcountTest(DebugTest):
compile_args = ("programs/infinite_loop.S", )
diff --git a/debug/targets.py b/debug/targets.py
index bb7a5cf..eca0231 100644
--- a/debug/targets.py
+++ b/debug/targets.py
@@ -141,6 +141,13 @@ class Target:
# Instruction count limit
icount_limit = 4
+ # Implements page-based virtual memory. So when PMP changes execute an
+ # SFENCE.VMA
+ implements_page_virtual_memory = True
+
+ # Support set_pmp_deny to create invalid addresses.
+ support_set_pmp_deny = False
+
# Internal variables:
directory = None
temporary_files = []
diff --git a/debug/targets/RISC-V/spike32.lds b/debug/targets/RISC-V/spike32.lds
index 77bb1ba..1e3f34f 100755
--- a/debug/targets/RISC-V/spike32.lds
+++ b/debug/targets/RISC-V/spike32.lds
@@ -5,14 +5,17 @@ SECTIONS
/* Leave some space for pk's data structures, which includes tohost/fromhost
* which are special addresses we ought to leave alone. */
. = 0x10110000;
- .text :
+ .text :
{
*(.text.entry)
*(.text)
+ *(.text.*)
}
/* data segment */
- .data : { *(.data) }
+ .rodata : { *(.rodata .rodata.*) }
+
+ .data : { *(.data .data.*) }
.sdata : {
__global_pointer$ = . + 0x800;
@@ -27,7 +30,7 @@ SECTIONS
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
- .bss : { *(.bss) }
+ .bss : { *(.bss .bss.*) }
__bss_end = .;
__malloc_start = .;
diff --git a/debug/targets/RISC-V/spike64.lds b/debug/targets/RISC-V/spike64.lds
index 2e7d65d..9cbf36f 100755
--- a/debug/targets/RISC-V/spike64.lds
+++ b/debug/targets/RISC-V/spike64.lds
@@ -3,14 +3,17 @@ OUTPUT_ARCH( "riscv" )
SECTIONS
{
. = 0x1212340000;
- .text :
+ .text :
{
*(.text.entry)
*(.text)
+ *(.text.*)
}
/* data segment */
- .data : { *(.data) }
+ .rodata : { *(.rodata .rodata.*) }
+
+ .data : { *(.data .data.*) }
.sdata : {
__global_pointer$ = . + 0x800;
@@ -25,7 +28,7 @@ SECTIONS
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
- .bss : { *(.bss) }
+ .bss : { *(.bss .bss.*) }
__bss_end = .;
__malloc_start = .;
diff --git a/debug/test b/debug/test
deleted file mode 100755
index 9b72737..0000000
--- a/debug/test
+++ /dev/null
Binary files differ
diff --git a/debug/testlib.py b/debug/testlib.py
index 0279b08..82fe3fb 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -65,6 +65,7 @@ def compile(args): # pylint: disable=redefined-builtin
class Spike:
# pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-locals
+ # pylint: disable=too-many-positional-arguments
def __init__(self, target, halted=False, timeout=None, with_jtag_gdb=True,
isa=None, progbufsize=None, dmi_rti=None, abstract_rti=None,
support_hasel=True, support_abstract_csr=True,
@@ -300,6 +301,8 @@ class VcsSim:
class Openocd:
# pylint: disable=too-many-instance-attributes
# pylint: disable-next=consider-using-with
+ # pylint: disable=too-many-positional-arguments
+ # pylint: disable=consider-using-with
logfile = tempfile.NamedTemporaryFile(prefix='openocd', suffix='.log')
logname = logfile.name
@@ -717,6 +720,7 @@ class Gdb:
11, 149, 107, 163, 73, 47, 43, 173, 7, 109, 101, 103, 191, 2, 139,
97, 193, 157, 3, 29, 79, 113, 5, 89, 19, 37, 71, 179, 59, 137, 53)
+ # pylint: disable=too-many-positional-arguments
def __init__(self, target, ports, cmd=None, timeout=60, binaries=None,
logremote=False):
assert ports
@@ -1481,6 +1485,22 @@ class GdbTest(BaseTest):
self.gdb.select_hart(self.hart)
self.gdb.command(f"monitor targets {self.hart.id}")
+ def set_pmp_deny(self, address, size=4 * 1024):
+ # Enable physical memory protection, no permission to access specific
+ # address range (default 4KB).
+ self.gdb.p("$mseccfg=0x4") # RLB
+ self.gdb.p("$pmpcfg0=0x98") # L, NAPOT, !R, !W, !X
+ self.gdb.p("$pmpaddr0="
+ f"0x{((address >> 2) | ((size - 1) >> 3)):x}")
+ # PMP changes require an sfence.vma, 0x12000073 is sfence.vma
+ self.gdb.command("monitor riscv exec_progbuf 0x12000073")
+
+ def reset_pmp_deny(self):
+ self.gdb.p("$pmpcfg0=0")
+ self.gdb.p("$pmpaddr0=0")
+ # PMP changes require an sfence.vma, 0x12000073 is sfence.vma
+ self.gdb.command("monitor riscv exec_progbuf 0x12000073")
+
def disable_pmp(self):
# Disable physical memory protection by allowing U mode access to all
# memory.
@@ -1494,6 +1514,9 @@ class GdbTest(BaseTest):
# pmcfg0 readback matches write, so TOR is supported.
self.gdb.p("$pmpaddr0="
f"0x{(self.hart.ram + self.hart.ram_size) >> 2:x}")
+ if self.target.implements_page_virtual_memory:
+ # PMP changes require an sfence.vma, 0x12000073 is sfence.vma
+ self.gdb.command("monitor riscv exec_progbuf 0x12000073")
except CouldNotFetch:
# PMP registers are optional
pass
@@ -1504,6 +1527,9 @@ class GdbTest(BaseTest):
if interrupt:
self.gdb.interrupt()
self.gdb.p("$mie=$mie & ~0x80")
+ self.gdb.p("$mstatus=$mstatus & ~0x8")
+ self.gdb.p(f"*((long long*) 0x{self.target.clint_addr + 0x4000:x})\
+ =0x" + "f" * (self.hart.xlen // 4))
def exit(self, expected_result=10):
self.gdb.command("delete")
diff --git a/env b/env
-Subproject 4fabfb4e0d3eacc1dc791da70e342e4b68ea7e4
+Subproject 6de71edb142be36319e380ce782c3d1830c65d6
diff --git a/isa/Makefile b/isa/Makefile
index bf85e1f..b1f0c2a 100644
--- a/isa/Makefile
+++ b/isa/Makefile
@@ -13,6 +13,7 @@ include $(src_dir)/rv64um/Makefrag
include $(src_dir)/rv64ua/Makefrag
include $(src_dir)/rv64uf/Makefrag
include $(src_dir)/rv64ud/Makefrag
+include $(src_dir)/rv64uziccid/Makefrag
include $(src_dir)/rv64uzfh/Makefrag
include $(src_dir)/rv64uzba/Makefrag
include $(src_dir)/rv64uzbb/Makefrag
@@ -22,6 +23,7 @@ include $(src_dir)/rv64si/Makefrag
include $(src_dir)/rv64ssvnapot/Makefrag
include $(src_dir)/rv64mi/Makefrag
include $(src_dir)/rv64mzicbo/Makefrag
+include $(src_dir)/hypervisor/Makefrag
endif
include $(src_dir)/rv32ui/Makefrag
include $(src_dir)/rv32uc/Makefrag
@@ -58,10 +60,10 @@ vpath %.S $(src_dir)
$(RISCV_OBJDUMP) $< > $@
%.out: %
- $(RISCV_SIM) --isa=rv64gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
+ $(RISCV_SIM) --isa=rv64gch_ziccid_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
%.out32: %
- $(RISCV_SIM) --isa=rv32gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
+ $(RISCV_SIM) --isa=rv32gc_ziccid_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
define compile_template
@@ -107,6 +109,7 @@ $(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,rv64uziccid,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uzfh,-march=rv64g_zfh -mabi=lp64))
$(eval $(call compile_template,rv64uzba,-march=rv64g_zba -mabi=lp64))
$(eval $(call compile_template,rv64uzbb,-march=rv64g_zbb -mabi=lp64))
@@ -116,6 +119,7 @@ $(eval $(call compile_template,rv64mzicbo,-march=rv64g_zicboz -mabi=lp64))
$(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ssvnapot,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,hypervisor,-march=rv64gh -mabi=lp64))
endif
tests_dump = $(addsuffix .dump, $(tests))
diff --git a/isa/hypervisor/2-stage_translation.S b/isa/hypervisor/2-stage_translation.S
new file mode 100644
index 0000000..93b4340
--- /dev/null
+++ b/isa/hypervisor/2-stage_translation.S
@@ -0,0 +1,136 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# 2-stage_translation.S
+#-----------------------------------------------------------------------------
+#
+# Set 2 stage translation, do a simple load store.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+#define vspt0_gpa 0x0
+#define vspt1_gpa 0x1000
+#define vspt2_gpa 0x2000
+#define GPA 0x200000
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ li TESTNUM, 2
+
+# map GVA 0x0~0xfff to GPA 0x200000~0x200fff
+vs_pt_init:
+ li t0, vspt1_gpa
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, vspt_0, t1
+
+ li t0, vspt2_gpa
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, vspt_1, t1
+
+ li t0, GPA
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_X | PTE_A | PTE_D | PTE_R | PTE_W
+ sd t0, vspt_2, t1
+
+init_vsatp:
+ li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+ la a1, vspt0_gpa
+ srl a1, a1, RISCV_PGSHIFT
+ or a1, a1, a0
+ csrw vsatp, a1
+ hfence.vvma
+
+
+# map GPA 0x200000~0x200fff to data_page
+guest_pt_init:
+ la t0, gpt_1
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_0, t1
+
+ la t0, gpt_2
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_1, t1
+
+ la t0, gpt_3
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_1 + 8, t1
+
+ la t0, vspt_0
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2, t1
+
+ la t0, vspt_1
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2 + 8, t1
+
+ la t0, vspt_2
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2 + 16, t1
+
+ la t0, data_page
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_3, t1
+
+init_hgatp:
+ li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+ la a1, gpt_0
+ srl a1, a1, RISCV_PGSHIFT
+ or a1, a1, a0
+ csrw hgatp, a1
+ hfence.gvma
+
+hstatus_init:
+ li a0, HSTATUS_SPVP
+ csrs hstatus, a0
+
+ la a0, data_page
+ li a1, 0x12345678
+ sw a1, 0(a0)
+
+ li t0, 0x0
+ hlv.w t2, 0(t0) # should be 0x12345678
+ hsv.w t2, 0(t0)
+ bne t2, a1, fail
+
+ RVTEST_PASS
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+.align 12
+vspt_0: .dword 0
+.align 12
+vspt_1: .dword 0
+.align 12
+vspt_2: .dword 0
+
+.align 14
+gpt_0: .dword 0
+.align 14
+gpt_1: .dword 0
+.align 12
+gpt_2: .dword 0
+.align 12
+gpt_3: .dword 0
+.align 12
+data_page: .dword 0
+
+RVTEST_DATA_END
diff --git a/isa/hypervisor/Makefrag b/isa/hypervisor/Makefrag
new file mode 100644
index 0000000..08f711a
--- /dev/null
+++ b/isa/hypervisor/Makefrag
@@ -0,0 +1,8 @@
+#=======================================================================
+# Makefrag for hypervisor tests
+#-----------------------------------------------------------------------
+
+hypervisor_sc_tests = \
+ 2-stage_translation \
+
+hypervisor_p_tests = $(addprefix hypervisor-p-, $(hypervisor_sc_tests))
diff --git a/isa/macros/scalar/test_macros.h b/isa/macros/scalar/test_macros.h
index 518476c..21562d4 100644
--- a/isa/macros/scalar/test_macros.h
+++ b/isa/macros/scalar/test_macros.h
@@ -32,6 +32,13 @@ test_ ## testnum: \
#define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8
#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
+#if __riscv_xlen == 64
+#define LOAD_PTR ld
+#define STORE_PTR sd
+#else
+#define LOAD_PTR lw
+#define STORE_PTR sw
+#endif
#-----------------------------------------------------------------------
# RV64UI MACROS
@@ -295,7 +302,36 @@ test_ ## testnum: \
li x5, 2; \
bne x4, x5, 1b \
-#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
+#define TEST_LD_ST_BYPASS(testnum, load_inst, store_inst, result, offset, base) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la x2, base; \
+ li x1, result; \
+ store_inst x1, offset(x2); \
+ load_inst x14, offset(x2); \
+ store_inst x14, offset(x2); \
+ load_inst x2, offset(x2); \
+ li x7, result; \
+ bne x2, x7, fail; \
+ la x2, base; \
+ STORE_PTR x2,8(x2); \
+ LOAD_PTR x4,8(x2); \
+ store_inst x1, offset(x4); \
+ bne x4, x2, fail; \
+ load_inst x14, offset(x4); \
+ bne x14, x7, fail; \
+
+#define TEST_ST_LD_BYPASS(testnum, load_inst, store_inst, result, offset, base) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la x2, base; \
+ li x1, result; \
+ store_inst x1, offset(x2); \
+ load_inst x14, offset(x2); \
+ li x7, result; \
+ bne x14, x7, fail; \
+
+#define TEST_BR2_OP_TAKEN(testnum, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x1, val1; \
@@ -381,12 +417,23 @@ test_ ## testnum: \
# Tests floating-point instructions
#-----------------------------------------------------------------------
-#define qNaNh 0h:7e00
-#define sNaNh 0h:7c01
-#define qNaNf 0f:7fc00000
-#define sNaNf 0f:7f800001
-#define qNaN 0d:7ff8000000000000
-#define sNaN 0d:7ff0000000000001
+# 16-bit half precision (float16)
+#define qNaNh 0x7e00
+#define sNaNh 0x7c01
+#define Infh 0x7c00
+#define nInfh 0xfc00
+
+# 32-bit single precision (float)
+#define qNaNf 0x7fc00000
+#define sNaNf 0x7f800001
+#define Inff 0x7f800000
+#define nInff 0xff800000
+
+# 64-bit double precision (double)
+#define qNaNd 0x7ff8000000000000
+#define sNaNd 0x7ff0000000000001
+#define Infd 0x7ff0000000000000
+#define nInfd 0xfff0000000000000
#define TEST_FP_OP_H_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
test_ ## testnum: \
@@ -404,9 +451,9 @@ test_ ## testnum: \
.pushsection .data; \
.align 1; \
test_ ## testnum ## _data: \
- .float16 val1; \
- .float16 val2; \
- .float16 val3; \
+ .val1; \
+ .val2; \
+ .val3; \
.result; \
.popsection
@@ -426,9 +473,9 @@ test_ ## testnum: \
.pushsection .data; \
.align 2; \
test_ ## testnum ## _data: \
- .float val1; \
- .float val2; \
- .float val3; \
+ .val1; \
+ .val2; \
+ .val3; \
.result; \
.popsection
@@ -448,9 +495,9 @@ test_ ## testnum: \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
- .double val1; \
- .double val2; \
- .double val3; \
+ .val1; \
+ .val2; \
+ .val3; \
.result; \
.popsection
@@ -473,131 +520,163 @@ test_ ## testnum: \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
- .double val1; \
- .double val2; \
- .double val3; \
+ .val1; \
+ .val2; \
+ .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, \
+ TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, double val1, double 0, double 0, \
fcvt.s.d f13, f10; fcvt.d.s f13, f13; fsd f13, 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, \
+ TEST_FP_OP_D_INTERNAL( testnum, 0, double result, double val1, double 0, double 0, \
fcvt.s.d f13, f10; fcvt.d.s f13, f13; fmv.x.d a0, f13)
#define TEST_FCVT_D_S( testnum, result, val1 ) \
- TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
+ TEST_FP_OP_S_INTERNAL( testnum, 0, float result, float val1, float 0, float 0, \
fcvt.d.s f13, f10; fcvt.s.d f13, f13; fmv.x.s a0, f13)
#define TEST_FCVT_H_S( testnum, result, val1 ) \
- TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, float16 val1, float16 0, float16 0, \
fcvt.s.h f13, f10; fcvt.h.s f13, f13; fmv.x.h a0, f13)
#define TEST_FCVT_H_D( testnum, result, val1 ) \
- TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, float16 val1, float16 0, float16 0, \
fcvt.d.h f13, f10; fcvt.h.d f13, f13; fmv.x.h a0, f13)
#define TEST_FP_OP1_H( testnum, inst, flags, result, val1 ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, 0.0, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 0, float16 0, \
inst f13, f10; fmv.x.h a0, f13;)
#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
- TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float 0, float 0, \
inst f13, f10; fmv.x.s a0, f13)
#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
- TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double 0, double 0, \
inst f13, f10; fsd f13, 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, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double 0, double 0, \
inst f13, f10; fmv.x.d a0, f13)
#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, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, float val1, float 0, float 0, \
inst f13, f10; fmv.x.s a0, f13)
#define TEST_FP_OP1_H_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, word result, float16 val1, float16 0, float16 0, \
inst f13, f10; fmv.x.h a0, f13)
#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, \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \
inst f13, f10; fsd f13, 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, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \
inst f13, f10; fmv.x.d a0, f13)
#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
- TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float val2, float 0, \
+ inst f13, f10, f11; fmv.x.s a0, f13)
+
+#define TEST_FP_OP2_S_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, word val1, word val2, float 0, \
inst f13, f10, f11; fmv.x.s a0, f13)
#define TEST_FP_OP2_H( testnum, inst, flags, result, val1, val2 ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 val2, float16 0, \
+ inst f13, f10, f11; fmv.x.h a0, f13)
+
+#define TEST_FP_OP2_H_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, half result, half val1, half val2, float16 0, \
inst f13, f10, f11; fmv.x.h a0, f13)
#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
- TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double val2, double 0, \
inst f13, f10, f11; fsd f13, 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_D32_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \
+ inst f13, f10, f11; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
- TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double val2, double 0, \
+ inst f13, f10, f11; fmv.x.d a0, f13)
+
+#define TEST_FP_OP2_D_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \
inst f13, f10, f11; fmv.x.d a0, f13)
#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
- TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float val2, float val3, \
inst f13, f10, f11, f12; fmv.x.s a0, f13)
#define TEST_FP_OP3_H( testnum, inst, flags, result, val1, val2, val3 ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, val3, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 val2, float16 val3, \
inst f13, f10, f11, f12; fmv.x.h a0, f13)
#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
- TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double val2, double val3, \
inst f13, f10, f11, f12; fsd f13, 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, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double val2, double val3, \
inst f13, f10, f11, f12; fmv.x.d a0, f13)
#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, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, float val1, float 0, float 0, \
inst a0, f10, rm)
#define TEST_FP_INT_OP_H( testnum, inst, flags, result, val1, rm ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, word result, float16 val1, float16 0, float16 0, \
inst a0, f10, 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, f10, f11; li t2, 0)
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \
+ inst a0, f10, rm; li t2, ((result) << 32 >> 63) * -1)
#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, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \
inst a0, f10, 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, \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, float val1, float val2, float 0, \
+ inst a0, f10, f11)
+
+#define TEST_FP_CMP_OP_S_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, word val1, word val2, float 0, \
inst a0, f10, f11)
#define TEST_FP_CMP_OP_H( testnum, inst, flags, result, val1, val2 ) \
- TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, val1, val2, 0.0, \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, float16 val1, float16 val2, float16 0, \
+ inst a0, f10, f11)
+
+#define TEST_FP_CMP_OP_H_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, half val1, half val2, float16 0, \
inst a0, f10, f11)
#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, \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double val2, double 0, \
+ inst a0, f10, f11; li t2, 0)
+
+#define TEST_FP_CMP_OP_D32_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \
inst a0, f10, f11; 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, \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double val2, double 0, \
+ inst a0, f10, f11)
+
+#define TEST_FP_CMP_OP_D_HEX( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \
inst a0, f10, f11)
#define TEST_FCLASS_S(testnum, correct, input) \
diff --git a/isa/rv32mi/Makefrag b/isa/rv32mi/Makefrag
index d871990..f4b8364 100644
--- a/isa/rv32mi/Makefrag
+++ b/isa/rv32mi/Makefrag
@@ -17,5 +17,7 @@ rv32mi_sc_tests = \
sh-misaligned \
sw-misaligned \
zicntr \
+ instret_overflow \
+ pmpaddr \
rv32mi_p_tests = $(addprefix rv32mi-p-, $(rv32mi_sc_tests))
diff --git a/isa/rv32mi/instret_overflow.S b/isa/rv32mi/instret_overflow.S
new file mode 100644
index 0000000..1808e22
--- /dev/null
+++ b/isa/rv32mi/instret_overflow.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64M
+#define RVTEST_RV64M RVTEST_RV32M
+#define __MACHINE_MODE
+
+#include "../rv64mi/instret_overflow.S"
diff --git a/isa/rv32mi/pmpaddr.S b/isa/rv32mi/pmpaddr.S
new file mode 100644
index 0000000..934af92
--- /dev/null
+++ b/isa/rv32mi/pmpaddr.S
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64M
+#define RVTEST_RV64M RVTEST_RV32M
+#define __MACHINE_MODE
+
+#include "../rv64mi/pmpaddr.S"
diff --git a/isa/rv32ud/fcvt_w.S b/isa/rv32ud/fcvt_w.S
index 3447530..5ae07ad 100644
--- a/isa/rv32ud/fcvt_w.S
+++ b/isa/rv32ud/fcvt_w.S
@@ -4,4 +4,8 @@
#undef RVTEST_RV64UF
#define RVTEST_RV64UF RVTEST_RV32UF
-#include "../rv64uf/fcvt_w.S"
+#include "test_macros.h"
+#undef TEST_FP_INT_OP_D
+#define TEST_FP_INT_OP_D TEST_FP_INT_OP_D32
+
+#include "../rv64ud/fcvt_w.S"
diff --git a/isa/rv32ud/recoding.S b/isa/rv32ud/recoding.S
index 5dc0113..a926f18 100644
--- a/isa/rv32ud/recoding.S
+++ b/isa/rv32ud/recoding.S
@@ -4,4 +4,4 @@
#undef RVTEST_RV64UF
#define RVTEST_RV64UF RVTEST_RV32UF
-#include "../rv64uf/recoding.S"
+#include "../rv64ud/recoding.S"
diff --git a/isa/rv32ui/Makefrag b/isa/rv32ui/Makefrag
index b7d85e1..d797e61 100644
--- a/isa/rv32ui/Makefrag
+++ b/isa/rv32ui/Makefrag
@@ -10,11 +10,11 @@ rv32ui_sc_tests = \
beq bge bgeu blt bltu bne \
fence_i \
jal jalr \
- lb lbu lh lhu lw \
+ lb lbu lh lhu lw ld_st \
lui \
ma_data \
or ori \
- sb sh sw \
+ sb sh sw st_ld \
sll slli \
slt slti sltiu sltu \
sra srai \
diff --git a/isa/rv32ui/ld_st.S b/isa/rv32ui/ld_st.S
new file mode 100644
index 0000000..476b806
--- /dev/null
+++ b/isa/rv32ui/ld_st.S
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64U
+#define RVTEST_RV64U RVTEST_RV32U
+
+#include "../rv64ui/ld_st.S"
diff --git a/isa/rv32ui/st_ld.S b/isa/rv32ui/st_ld.S
new file mode 100644
index 0000000..22b303c
--- /dev/null
+++ b/isa/rv32ui/st_ld.S
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64U
+#define RVTEST_RV64U RVTEST_RV32U
+
+#include "../rv64ui/st_ld.S"
diff --git a/isa/rv64mi/Makefrag b/isa/rv64mi/Makefrag
index a6f23e4..277360f 100644
--- a/isa/rv64mi/Makefrag
+++ b/isa/rv64mi/Makefrag
@@ -3,7 +3,6 @@
#-----------------------------------------------------------------------
rv64mi_sc_tests = \
- access \
breakpoint \
csr \
mcsr \
@@ -19,5 +18,7 @@ rv64mi_sc_tests = \
sw-misaligned \
sd-misaligned \
zicntr \
+ instret_overflow \
+ pmpaddr \
rv64mi_p_tests = $(addprefix rv64mi-p-, $(rv64mi_sc_tests))
diff --git a/isa/rv64mi/access.S b/isa/rv64mi/access.S
deleted file mode 100644
index 40a28d3..0000000
--- a/isa/rv64mi/access.S
+++ /dev/null
@@ -1,70 +0,0 @@
-# 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/isa/rv64mi/illegal.S b/isa/rv64mi/illegal.S
index fb6643b..ca88307 100644
--- a/isa/rv64mi/illegal.S
+++ b/isa/rv64mi/illegal.S
@@ -72,19 +72,19 @@ msip:
beqz t2, bare_s_1
csrc sstatus, t0
- # Make sure SFENCE.VMA and sptbr don't trap when TVM=0.
+ # Make sure SFENCE.VMA and satp don't trap when TVM=0.
sfence.vma
- csrr t0, sptbr
+ csrr t0, satp
bad5:
.word 0
j fail
bad6:
- # Make sure SFENCE.VMA and sptbr do trap when TVM=1.
+ # Make sure SFENCE.VMA and satp do trap when TVM=1.
sfence.vma
j fail
bad7:
- csrr t0, sptbr
+ csrr t0, satp
j fail
test_tsr:
@@ -120,7 +120,7 @@ bare_s_2:
j fail
# And access to satp should not trap
- csrr t0, sptbr
+ csrr t0, satp
bare_s_3:
.word 0
j fail
@@ -156,7 +156,7 @@ synchronous_exception:
csrr t0, mepc
# Make sure mtval contains either 0 or the instruction word.
- csrr t2, mbadaddr
+ csrr t2, mtval
beqz t2, 1f
lhu t1, 0(t0)
xor t2, t2, t1
diff --git a/isa/rv64mi/instret_overflow.S b/isa/rv64mi/instret_overflow.S
new file mode 100644
index 0000000..f026ac0
--- /dev/null
+++ b/isa/rv64mi/instret_overflow.S
@@ -0,0 +1,42 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# minstret_overflow.S
+#-----------------------------------------------------------------------------
+#
+# Test if overflow of instret is handled correctly
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ # The value written to instret will be the value read by the following
+ # instruction (i.e. the increment is suppressed)
+ TEST_CASE(2, a0, 0, csrwi minstret, 0; csrr a0, minstret);
+
+#if __riscv_xlen == 32
+ # Writes to instreth are considered writes to instret and so also
+ # suppress the increment
+ TEST_CASE(3, a0, 0, li t0, 0xffffffff; csrw minstret, t0; csrw minstreth, t0; nop; csrr a0, minstret);
+ TEST_CASE(4, a0, 0, csrr a0, minstreth);
+#endif
+
+2:
+ TEST_PASSFAIL
+
+ .align 2
+ .global mtvec_handler
+mtvec_handler:
+ j fail
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/isa/rv64mi/ma_addr.S b/isa/rv64mi/ma_addr.S
index 8579c01..0f7dc2e 100644
--- a/isa/rv64mi/ma_addr.S
+++ b/isa/rv64mi/ma_addr.S
@@ -103,7 +103,7 @@ mtvec_handler:
j fail
1:
- csrr t0, mbadaddr
+ csrr t0, mtval
beqz t0, 1f
bne t0, t1, fail
diff --git a/isa/rv64mi/pmpaddr.S b/isa/rv64mi/pmpaddr.S
new file mode 100644
index 0000000..29413af
--- /dev/null
+++ b/isa/rv64mi/pmpaddr.S
@@ -0,0 +1,154 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# pmpaddr.S
+#-----------------------------------------------------------------------------
+#
+# Test edge cases around the pmpaddr[G-1] bit which sometimes reads as zero
+# but is always writable and retains its state. Also test CSRC and CSRS
+# modifications to other bits result in a correct read-modify-write.
+#
+# This test auto-detects G but assumes PMP is available. It supports a
+# maximum G of XLEN-1. There's no minimum but if G is 0 then the G-1 bit
+# does not exist and this test trivially passes.
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ li TESTNUM, 1
+
+ # Software may determine the PMP granularity by writing zero to pmpcfg0,
+ # then writing all ones to pmpaddr0, then reading back pmpaddr0.
+ # If G is the index of the least-significant bit set, the PMP granularity
+ # is 2^(G+2) bytes.
+ csrw pmpcfg0, zero
+ li t0, -1
+ csrw pmpaddr0, t0
+ csrr t0, pmpaddr0
+
+ # Isolate the least significant bit.
+
+ neg t1, t0
+ and a7, t0, t1
+
+ # a7 now contains only the lowest 1 that was set in pmpaddr0.
+
+ # If a7 is 0 then G is >=XLEN which this test does not support.
+ beqz a7, fail
+ # Shift so the G-1 bit is set.
+ srl a7, a7, 1
+ # If no bits are set now then G is 0, which trivially passes.
+ beqz a7, pass
+
+#define PMPADDR_Gm1_MASK a7
+#define PMPCFG_A_MASK (0x3 << 3)
+ # Ok now we can begin the main test!
+
+# Set pmpaddr0[G-1] to `value` (1 or 0).
+.macro set_pmpaddr_bit value
+.if \value
+ csrs pmpaddr0, PMPADDR_Gm1_MASK
+.else
+ csrc pmpaddr0, PMPADDR_Gm1_MASK
+.endif
+.endm
+
+# Switch pmpcfg0 to OFF mode so pmpaddr0[G-1] reads as 0.
+.macro set_mode_off
+ csrc pmpcfg0, PMPCFG_A_MASK
+.endm
+
+# Switch pmpcfg0 to NAPOT mode so pmpaddr0[G-1] reads normally.
+.macro set_mode_napot
+ csrs pmpcfg0, PMPCFG_A_MASK
+.endm
+
+# Check that pmpaddr9[G] is set or unset depending on expected_value.
+.macro check_pmpaddr_bit expected_value
+ # Note when gas 2.43 is common we can use \+ instead of \@ which
+ # gives more sensible numbers. \@ still works but it gives 4, 6,
+ # 8, 10, 15... instead of 0, 1, 2, 3.
+ li TESTNUM, (2 + \@)
+ csrr t6, pmpaddr0
+ and t6, t6, PMPADDR_Gm1_MASK
+.if \expected_value
+ beqz t6, fail
+.else
+ bnez t6, fail
+.endif
+.endm
+
+.macro check_pmpaddr_bit_clear
+ csrr t6, pmpaddr0
+ and t6, t6, PMPADDR_Gm1_MASK
+ bnez t6, fail
+.endm
+
+ # Initialise pmpaddr and pmpcfg.
+
+ # M bit is writable in NAPOT mode.
+ set_mode_napot
+ # Clear it, it should read 0.
+ set_pmpaddr_bit 0
+ check_pmpaddr_bit 0
+ # Set it, it shouldn't read 0.
+ set_pmpaddr_bit 1
+ check_pmpaddr_bit 1
+ # M bit is writable but reads as 0 in OFF mode.
+ set_mode_off
+ # Should read as 0.
+ check_pmpaddr_bit 0
+ # Switch back to NAPOT. The 1 should be readable again.
+ set_mode_napot
+ check_pmpaddr_bit 1
+
+ # Test writing the bit while it is read-as-zero.
+ set_pmpaddr_bit 0
+ set_mode_off
+ set_pmpaddr_bit 1
+ set_mode_napot
+ check_pmpaddr_bit 1
+
+ # Test modifying a *different* bit while its underlying
+ # value is 1 but it reads as 0. Since csrs and csrc are
+ # read-modify-write they reads-as value will be written
+ # to the underlying value.
+ set_mode_off
+ # A csrs or csrc from the zero register does not have
+ # any side effects.
+ csrc pmpaddr0, zero
+ csrs pmpaddr0, zero
+ set_mode_napot
+ check_pmpaddr_bit 1
+
+ set_mode_off
+ # Set other bits. This should result in M being cleared
+ # since it currently reads as 0.
+ not t0, PMPADDR_Gm1_MASK
+ csrs pmpaddr0, t0
+ set_mode_napot
+ check_pmpaddr_bit 0
+
+ j pass
+
+ TEST_PASSFAIL
+
+ .align 2
+ .global mtvec_handler
+mtvec_handler:
+ # We aren't expecting any exceptions unless PMP is not supported
+ # in which case this test is also not supported. There's no
+ # way to probe for PMP support so we can't just pass in this case.
+ j fail
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/isa/rv64si/dirty.S b/isa/rv64si/dirty.S
index 15f3163..8a64e25 100644
--- a/isa/rv64si/dirty.S
+++ b/isa/rv64si/dirty.S
@@ -22,7 +22,7 @@ RVTEST_CODE_BEGIN
la a1, page_table_1
srl a1, a1, RISCV_PGSHIFT
or a1, a1, a0
- csrw sptbr, a1
+ csrw satp, a1
sfence.vma
# Set up MPRV with MPP=S, so loads and stores use S-mode
diff --git a/isa/rv64si/icache-alias.S b/isa/rv64si/icache-alias.S
index dbc934e..d2468eb 100644
--- a/isa/rv64si/icache-alias.S
+++ b/isa/rv64si/icache-alias.S
@@ -48,7 +48,7 @@ RVTEST_CODE_BEGIN
la a1, page_table_1
srl a1, a1, RISCV_PGSHIFT
or a1, a1, a0
- csrw sptbr, a1
+ csrw satp, a1
sfence.vma
# Enter supervisor mode and make sure correct page is accessed
diff --git a/isa/rv64si/ma_fetch.S b/isa/rv64si/ma_fetch.S
index b683b6f..31c7a23 100644
--- a/isa/rv64si/ma_fetch.S
+++ b/isa/rv64si/ma_fetch.S
@@ -17,7 +17,7 @@ RVTEST_CODE_BEGIN
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
- #define sbadaddr mbadaddr
+ #define stval mtval
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
@@ -205,8 +205,8 @@ stvec_handler:
addi a1, a1, 4
bne t0, a1, fail
- # verify that badaddr == 0 or badaddr == t0+2.
- csrr a0, sbadaddr
+ # verify that tval == 0 or tval == t0+2.
+ csrr a0, stval
beqz a0, 1f
addi a0, a0, -2
bne a0, t0, fail
diff --git a/isa/rv64ua/amomaxu_w.S b/isa/rv64ua/amomaxu_w.S
index 6eabcd2..9d548f6 100644
--- a/isa/rv64ua/amomaxu_w.S
+++ b/isa/rv64ua/amomaxu_w.S
@@ -31,6 +31,9 @@ RVTEST_CODE_BEGIN
TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3))
+ # The following two cases check that the upper 32 bits are ignored on rv64
+ # implementations. Only enable them for rv64.
+ #if __riscv_xlen == 64
TEST_CASE(6, a4, 1, \
li a0, 0x0000000000000001; \
li a1, 0x8000000000000000; \
@@ -40,6 +43,7 @@ RVTEST_CODE_BEGIN
)
TEST_CASE(7, a5, 1, lw a5, 0(a3))
+ #endif
TEST_PASSFAIL
diff --git a/isa/rv64ua/amominu_w.S b/isa/rv64ua/amominu_w.S
index d04a650..4483e95 100644
--- a/isa/rv64ua/amominu_w.S
+++ b/isa/rv64ua/amominu_w.S
@@ -31,6 +31,9 @@ RVTEST_CODE_BEGIN
TEST_CASE(5, a5, 0, lw a5, 0(a3))
+ # The following two cases check that the upper 32 bits are ignored on rv64
+ # implementations. Only enable them for rv64.
+ #if __riscv_xlen == 64
TEST_CASE(6, a4, 1, \
li a0, 0x0000000000000001; \
li a1, 0x8000000000000000; \
@@ -40,6 +43,7 @@ RVTEST_CODE_BEGIN
)
TEST_CASE(7, a5, 0, lw a5, 0(a3))
+ #endif
TEST_PASSFAIL
diff --git a/isa/rv64ud/fadd.S b/isa/rv64ud/fadd.S
index 51ca82d..1a00df4 100644
--- a/isa/rv64ud/fadd.S
+++ b/isa/rv64ud/fadd.S
@@ -17,6 +17,8 @@ RVTEST_CODE_BEGIN
# 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
+ #undef TEST_FP_OP2_D_HEX
+ #define TEST_FP_OP2_D_HEX TEST_FP_OP2_D32_HEX
#endif
#-------------------------------------------------------------
@@ -36,7 +38,7 @@ RVTEST_CODE_BEGIN
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_FP_OP2_D_HEX(11, fsub.d, 0x10, qNaNd, Infd, Infd);
TEST_PASSFAIL
diff --git a/isa/rv64ud/fclass.S b/isa/rv64ud/fclass.S
index 04a8947..295bb1a 100644
--- a/isa/rv64ud/fclass.S
+++ b/isa/rv64ud/fclass.S
@@ -23,16 +23,16 @@ RVTEST_CODE_BEGIN
# Arithmetic tests
#-------------------------------------------------------------
- TEST_FCLASS_D( 2, 1 << 0, 0xfff0000000000000 )
+ TEST_FCLASS_D( 2, 1 << 0, nInfd )
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_FCLASS_D( 9, 1 << 7, Infd )
+ TEST_FCLASS_D(10, 1 << 8, sNaNd )
+ TEST_FCLASS_D(11, 1 << 9, qNaNd )
TEST_PASSFAIL
diff --git a/isa/rv64ud/fcmp.S b/isa/rv64ud/fcmp.S
index 7727a28..f5d73e4 100644
--- a/isa/rv64ud/fcmp.S
+++ b/isa/rv64ud/fcmp.S
@@ -21,6 +21,8 @@ RVTEST_CODE_BEGIN
# 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
+ #undef TEST_FP_CMP_OP_D_HEX
+ #define TEST_FP_CMP_OP_D_HEX TEST_FP_CMP_OP_D32_HEX
#endif
TEST_FP_CMP_OP_D( 2, feq.d, 0x00, 1, -1.36, -1.36)
@@ -34,15 +36,15 @@ RVTEST_CODE_BEGIN
# 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)
+ TEST_FP_CMP_OP_D_HEX(10, feq.d, 0x10, 0, sNaNd, 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_HEX(13, flt.d, 0x10, 0, sNaNd, 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_FP_CMP_OP_D_HEX(16, fle.d, 0x10, 0, sNaNd, 0)
TEST_PASSFAIL
diff --git a/isa/rv64ud/fcvt.S b/isa/rv64ud/fcvt.S
index 98916b1..75eb121 100644
--- a/isa/rv64ud/fcvt.S
+++ b/isa/rv64ud/fcvt.S
@@ -44,7 +44,7 @@ RVTEST_CODE_BEGIN
TEST_FCVT_D_S(11, -1.5, -1.5)
#if __riscv_xlen >= 64
- TEST_CASE(12, a0, 0x7ff8000000000000,
+ TEST_CASE(12, a0, qNaNd,
la a1, test_data_22;
ld a2, 0(a1);
fmv.d.x f2, a2;
@@ -53,7 +53,7 @@ RVTEST_CODE_BEGIN
fmv.x.d a0, f2;
)
#else
- TEST_CASE_D32(12, a0, a1, 0x7ff8000000000000,
+ TEST_CASE_D32(12, a0, a1, qNaNd,
la a1, test_data_22;
fld f2, 0(a1);
fcvt.s.d f2, f2;
diff --git a/isa/rv64ud/fcvt_w.S b/isa/rv64ud/fcvt_w.S
index 56cc29d..5c65e93 100644
--- a/isa/rv64ud/fcvt_w.S
+++ b/isa/rv64ud/fcvt_w.S
@@ -102,13 +102,13 @@ RVTEST_DATA_BEGIN
tdat:
.word 0xffffffff
.word 0x7fffffff
-.word 0xff800000
-.word 0x7f800000
+.word nInff
+.word Inff
tdat_d:
.dword 0xffffffffffffffff
.dword 0x7fffffffffffffff
-.dword 0xfff0000000000000
-.dword 0x7ff0000000000000
+.dword nInfd
+.dword Infd
RVTEST_DATA_END
diff --git a/isa/rv64ud/fmin.S b/isa/rv64ud/fmin.S
index 8f270a5..150453b 100644
--- a/isa/rv64ud/fmin.S
+++ b/isa/rv64ud/fmin.S
@@ -17,6 +17,8 @@ RVTEST_CODE_BEGIN
# 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
+ #undef TEST_FP_OP2_D_HEX
+ #define TEST_FP_OP2_D_HEX TEST_FP_OP2_D32_HEX
#endif
#-------------------------------------------------------------
@@ -38,9 +40,9 @@ RVTEST_CODE_BEGIN
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);
+ TEST_FP_OP2_D_HEX(20, fmax.d, 0x10, 0x3ff0000000000000, sNaNd, 0x3ff0000000000000);
# FMAX(qNaN, qNaN) = canonical NaN
- TEST_FP_OP2_D(21, fmax.d, 0x00, qNaN, NaN, NaN);
+ TEST_FP_OP2_D_HEX(21, fmax.d, 0x00, qNaNd, 0x7fffffffffffffff, 0x7fffffffffffffff);
# -0.0 < +0.0
TEST_FP_OP2_D(30, fmin.d, 0, -0.0, -0.0, 0.0 );
diff --git a/isa/rv64ud/move.S b/isa/rv64ud/move.S
index 8911d95..60d3cc3 100644
--- a/isa/rv64ud/move.S
+++ b/isa/rv64ud/move.S
@@ -55,14 +55,14 @@ RVTEST_CODE_BEGIN
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(40, qNaNf, 0x7ffffffe12345678, 0)
+ TEST_FSGNJS(41, qNaNf, 0xfffffffe12345678, 0)
+ TEST_FSGNJS(42, qNaNf, 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(50, qNaNf, 0x7ffffffe12345678, 0x80000000)
+ TEST_FSGNJS(51, qNaNf, 0xfffffffe12345678, 0x80000000)
+ TEST_FSGNJS(52, qNaNf, 0x7fffffff12345678, 0x80000000)
TEST_FSGNJS(53, 0x12345678, 0xffffffff12345678, 0x80000000)
TEST_FSGNJS(60, 0xffc00000, 0x7ffffffe12345678, 0xffffffff80000000)
diff --git a/isa/rv64uf/fadd.S b/isa/rv64uf/fadd.S
index b6259df..78edcbf 100644
--- a/isa/rv64uf/fadd.S
+++ b/isa/rv64uf/fadd.S
@@ -30,7 +30,7 @@ RVTEST_CODE_BEGIN
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_FP_OP2_S_HEX(11, fsub.s, 0x10, qNaNf, Inff, Inff);
TEST_PASSFAIL
diff --git a/isa/rv64uf/fclass.S b/isa/rv64uf/fclass.S
index 9bb86b1..f13cfd0 100644
--- a/isa/rv64uf/fclass.S
+++ b/isa/rv64uf/fclass.S
@@ -17,16 +17,16 @@ RVTEST_CODE_BEGIN
# Arithmetic tests
#-------------------------------------------------------------
- TEST_FCLASS_S( 2, 1 << 0, 0xff800000 )
+ TEST_FCLASS_S( 2, 1 << 0, nInff )
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_FCLASS_S( 9, 1 << 7, Inff )
+ TEST_FCLASS_S(10, 1 << 8, sNaNf )
+ TEST_FCLASS_S(11, 1 << 9, qNaNf )
TEST_PASSFAIL
diff --git a/isa/rv64uf/fcmp.S b/isa/rv64uf/fcmp.S
index 2d7fcc2..45642ae 100644
--- a/isa/rv64uf/fcmp.S
+++ b/isa/rv64uf/fcmp.S
@@ -28,15 +28,15 @@ RVTEST_CODE_BEGIN
# 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)
+ TEST_FP_CMP_OP_S_HEX(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_HEX(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_FP_CMP_OP_S_HEX(16, fle.s, 0x10, 0, sNaNf, 0)
TEST_PASSFAIL
diff --git a/isa/rv64uf/fcvt_w.S b/isa/rv64uf/fcvt_w.S
index cad5cba..c5ea603 100644
--- a/isa/rv64uf/fcvt_w.S
+++ b/isa/rv64uf/fcvt_w.S
@@ -93,13 +93,13 @@ RVTEST_DATA_BEGIN
tdat:
.word 0xffffffff
.word 0x7fffffff
-.word 0xff800000
-.word 0x7f800000
+.word nInff
+.word Inff
tdat_d:
.dword 0xffffffffffffffff
.dword 0x7fffffffffffffff
-.dword 0xfff0000000000000
-.dword 0x7ff0000000000000
+.dword nInfd
+.dword Infd
RVTEST_DATA_END
diff --git a/isa/rv64uf/fmin.S b/isa/rv64uf/fmin.S
index 1f97533..2027b0c 100644
--- a/isa/rv64uf/fmin.S
+++ b/isa/rv64uf/fmin.S
@@ -32,9 +32,9 @@ RVTEST_CODE_BEGIN
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);
+ TEST_FP_OP2_S_HEX(20, fmax.s, 0x10, 0x3f800000, sNaNf, 0x3f800000);
# FMAX(qNaN, qNaN) = canonical NaN
- TEST_FP_OP2_S(21, fmax.s, 0x00, qNaNf, NaN, NaN);
+ TEST_FP_OP2_S_HEX(21, fmax.s, 0x00, qNaNf, 0x7fffffff, 0x7fffffff);
# -0.0 < +0.0
TEST_FP_OP2_S(30, fmin.s, 0, -0.0, -0.0, 0.0 );
diff --git a/isa/rv64ui/Makefrag b/isa/rv64ui/Makefrag
index d90347c..59e40cf 100644
--- a/isa/rv64ui/Makefrag
+++ b/isa/rv64ui/Makefrag
@@ -10,11 +10,11 @@ rv64ui_sc_tests = \
simple \
fence_i \
jal jalr \
- lb lbu lh lhu lw lwu ld \
+ lb lbu lh lhu lw lwu ld ld_st \
lui \
ma_data \
or ori \
- sb sh sw sd \
+ sb sh sw sd st_ld \
sll slli slliw sllw \
slt slti sltiu sltu \
sra srai sraiw sraw \
diff --git a/isa/rv64ui/ld_st.S b/isa/rv64ui/ld_st.S
new file mode 100644
index 0000000..d03e132
--- /dev/null
+++ b/isa/rv64ui/ld_st.S
@@ -0,0 +1,130 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ld_st.S
+#-----------------------------------------------------------------------------
+#
+# Test load and store instructions
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Bypassing Tests
+ #-------------------------------------------------------------
+
+ # Test sb and lb (signed byte)
+ TEST_LD_ST_BYPASS(2, lb, sb, 0xffffffffffffffdd, 0, tdat );
+ TEST_LD_ST_BYPASS(3, lb, sb, 0xffffffffffffffcd, 1, tdat );
+ TEST_LD_ST_BYPASS(4, lb, sb, 0xffffffffffffffcc, 2, tdat );
+ TEST_LD_ST_BYPASS(5, lb, sb, 0xffffffffffffffbc, 3, tdat );
+ TEST_LD_ST_BYPASS(6, lb, sb, 0xffffffffffffffbb, 4, tdat );
+ TEST_LD_ST_BYPASS(7, lb, sb, 0xffffffffffffffab, 5, tdat );
+
+ TEST_LD_ST_BYPASS(8, lb, sb, 0x33, 0, tdat );
+ TEST_LD_ST_BYPASS(9, lb, sb, 0x23, 1, tdat );
+ TEST_LD_ST_BYPASS(10, lb, sb, 0x22, 2, tdat );
+ TEST_LD_ST_BYPASS(11, lb, sb, 0x12, 3, tdat );
+ TEST_LD_ST_BYPASS(12, lb, sb, 0x11, 4, tdat );
+ TEST_LD_ST_BYPASS(13, lb, sb, 0x01, 5, tdat );
+
+ # Test sb and lbu (unsigned byte)
+ TEST_LD_ST_BYPASS(14, lbu, sb, 0x33, 0, tdat );
+ TEST_LD_ST_BYPASS(15, lbu, sb, 0x23, 1, tdat );
+ TEST_LD_ST_BYPASS(16, lbu, sb, 0x22, 2, tdat );
+ TEST_LD_ST_BYPASS(17, lbu, sb, 0x12, 3, tdat );
+ TEST_LD_ST_BYPASS(18, lbu, sb, 0x11, 4, tdat );
+ TEST_LD_ST_BYPASS(19, lbu, sb, 0x01, 5, tdat );
+
+ # Test sw and lw (signed word)
+ TEST_LD_ST_BYPASS(20, lw, sw, 0xffffffffaabbccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(21, lw, sw, 0xffffffffdaabbccd, 4, tdat );
+ TEST_LD_ST_BYPASS(22, lw, sw, 0xffffffffddaabbcc, 8, tdat );
+ TEST_LD_ST_BYPASS(23, lw, sw, 0xffffffffcddaabbc, 12, tdat );
+ TEST_LD_ST_BYPASS(24, lw, sw, 0xffffffffccddaabb, 16, tdat );
+ TEST_LD_ST_BYPASS(25, lw, sw, 0xffffffffbccddaab, 20, tdat );
+
+ TEST_LD_ST_BYPASS(26, lw, sw, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(27, lw, sw, 0x30011223, 4, tdat );
+ TEST_LD_ST_BYPASS(28, lw, sw, 0x33001122, 8, tdat );
+ TEST_LD_ST_BYPASS(29, lw, sw, 0x23300112, 12, tdat );
+ TEST_LD_ST_BYPASS(30, lw, sw, 0x22330011, 16, tdat );
+ TEST_LD_ST_BYPASS(31, lw, sw, 0x12233001, 20, tdat );
+
+ # Test sh and lh (signed halfword)
+ TEST_LD_ST_BYPASS(32, lh, sh, 0xffffffffffffccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(33, lh, sh, 0xffffffffffffbccd, 2, tdat );
+ TEST_LD_ST_BYPASS(34, lh, sh, 0xffffffffffffbbcc, 4, tdat );
+ TEST_LD_ST_BYPASS(35, lh, sh, 0xffffffffffffabbc, 6, tdat );
+ TEST_LD_ST_BYPASS(36, lh, sh, 0xffffffffffffaabb, 8, tdat );
+ TEST_LD_ST_BYPASS(37, lh, sh, 0xffffffffffffdaab, 10, tdat );
+
+ TEST_LD_ST_BYPASS(38, lh, sh, 0x2233, 0, tdat );
+ TEST_LD_ST_BYPASS(39, lh, sh, 0x1223, 2, tdat );
+ TEST_LD_ST_BYPASS(40, lh, sh, 0x1122, 4, tdat );
+ TEST_LD_ST_BYPASS(41, lh, sh, 0x0112, 6, tdat );
+ TEST_LD_ST_BYPASS(42, lh, sh, 0x0011, 8, tdat );
+ TEST_LD_ST_BYPASS(43, lh, sh, 0x3001, 10, tdat );
+
+ # Test sh and lhu (unsigned halfword)
+ TEST_LD_ST_BYPASS(44, lhu, sh, 0x2233, 0, tdat );
+ TEST_LD_ST_BYPASS(45, lhu, sh, 0x1223, 2, tdat );
+ TEST_LD_ST_BYPASS(46, lhu, sh, 0x1122, 4, tdat );
+ TEST_LD_ST_BYPASS(47, lhu, sh, 0x0112, 6, tdat );
+ TEST_LD_ST_BYPASS(48, lhu, sh, 0x0011, 8, tdat );
+ TEST_LD_ST_BYPASS(49, lhu, sh, 0x3001, 10, tdat );
+
+ # RV64-specific tests for ld, sd, and lwu
+#if __riscv_xlen == 64
+ # Test sd and ld (doubleword)
+ TEST_LD_ST_BYPASS(50, ld, sd, 0x0011223344556677, 0, tdat );
+ TEST_LD_ST_BYPASS(51, ld, sd, 0x1122334455667788, 8, tdat );
+ TEST_LD_ST_BYPASS(52, ld, sd, 0x2233445566778899, 16, tdat );
+ TEST_LD_ST_BYPASS(53, ld, sd, 0xabbccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(54, ld, sd, 0xaabbccd, 8, tdat );
+ TEST_LD_ST_BYPASS(55, ld, sd, 0xdaabbcc, 16, tdat );
+ TEST_LD_ST_BYPASS(56, ld, sd, 0xddaabbc, 24, tdat );
+ TEST_LD_ST_BYPASS(57, ld, sd, 0xcddaabb, 32, tdat );
+ TEST_LD_ST_BYPASS(58, ld, sd, 0xccddaab, 40, tdat );
+
+ TEST_LD_ST_BYPASS(59, ld, sd, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(60, ld, sd, 0x30011223, 8, tdat );
+ TEST_LD_ST_BYPASS(61, ld, sd, 0x33001122, 16, tdat );
+ TEST_LD_ST_BYPASS(62, ld, sd, 0x23300112, 24, tdat );
+ TEST_LD_ST_BYPASS(63, ld, sd, 0x22330011, 32, tdat );
+ TEST_LD_ST_BYPASS(64, ld, sd, 0x12233001, 40, tdat );
+
+ # Test sw and lwu (unsigned word)
+ TEST_LD_ST_BYPASS(65, lwu, sw, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(66, lwu, sw, 0x33001122, 8, tdat );
+ TEST_LD_ST_BYPASS(67, lwu, sw, 0x30011223, 4, tdat );
+ TEST_LD_ST_BYPASS(68, lwu, sw, 0x23300112, 12, tdat );
+ TEST_LD_ST_BYPASS(69, lwu, sw, 0x22330011, 16, tdat );
+ TEST_LD_ST_BYPASS(70, lwu, sw, 0x12233001, 20, tdat );
+#endif
+
+ li a0, 0xef # Immediate load for manual store test
+ la a1, tdat # Load address of tdat
+ sb a0, 3(a1) # Store byte at offset 3 of tdat
+ lb a2, 3(a1) # Load byte back for verification
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+ .rept 20
+ .word 0xdeadbeef
+ .endr
+
+
+RVTEST_DATA_END
diff --git a/isa/rv64ui/st_ld.S b/isa/rv64ui/st_ld.S
new file mode 100644
index 0000000..89608db
--- /dev/null
+++ b/isa/rv64ui/st_ld.S
@@ -0,0 +1,130 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# st_ld.S
+#-----------------------------------------------------------------------------
+#
+# Test store and load instructions
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Bypassing Tests
+ #-------------------------------------------------------------
+
+ # Test sb and lb (signed byte)
+ TEST_ST_LD_BYPASS(2, lb, sb, 0xffffffffffffffdd, 0, tdat );
+ TEST_ST_LD_BYPASS(3, lb, sb, 0xffffffffffffffcd, 1, tdat );
+ TEST_ST_LD_BYPASS(4, lb, sb, 0xffffffffffffffcc, 2, tdat );
+ TEST_ST_LD_BYPASS(5, lb, sb, 0xffffffffffffffbc, 3, tdat );
+ TEST_ST_LD_BYPASS(6, lb, sb, 0xffffffffffffffbb, 4, tdat );
+ TEST_ST_LD_BYPASS(7, lb, sb, 0xffffffffffffffab, 5, tdat );
+
+ TEST_ST_LD_BYPASS(8, lb, sb, 0x33, 0, tdat );
+ TEST_ST_LD_BYPASS(9, lb, sb, 0x23, 1, tdat );
+ TEST_ST_LD_BYPASS(10, lb, sb, 0x22, 2, tdat );
+ TEST_ST_LD_BYPASS(11, lb, sb, 0x12, 3, tdat );
+ TEST_ST_LD_BYPASS(12, lb, sb, 0x11, 4, tdat );
+ TEST_ST_LD_BYPASS(13, lb, sb, 0x01, 5, tdat );
+
+ # Test sb and lbu (unsigned byte)
+ TEST_ST_LD_BYPASS(14, lbu, sb, 0x33, 0, tdat );
+ TEST_ST_LD_BYPASS(15, lbu, sb, 0x23, 1, tdat );
+ TEST_ST_LD_BYPASS(16, lbu, sb, 0x22, 2, tdat );
+ TEST_ST_LD_BYPASS(17, lbu, sb, 0x12, 3, tdat );
+ TEST_ST_LD_BYPASS(18, lbu, sb, 0x11, 4, tdat );
+ TEST_ST_LD_BYPASS(19, lbu, sb, 0x01, 5, tdat );
+
+ # Test sw and lw (signed word)
+ TEST_ST_LD_BYPASS(20, lw, sw, 0xffffffffaabbccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(21, lw, sw, 0xffffffffdaabbccd, 4, tdat );
+ TEST_ST_LD_BYPASS(22, lw, sw, 0xffffffffddaabbcc, 8, tdat );
+ TEST_ST_LD_BYPASS(23, lw, sw, 0xffffffffcddaabbc, 12, tdat );
+ TEST_ST_LD_BYPASS(24, lw, sw, 0xffffffffccddaabb, 16, tdat );
+ TEST_ST_LD_BYPASS(25, lw, sw, 0xffffffffbccddaab, 20, tdat );
+
+ TEST_ST_LD_BYPASS(26, lw, sw, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(27, lw, sw, 0x30011223, 4, tdat );
+ TEST_ST_LD_BYPASS(28, lw, sw, 0x33001122, 8, tdat );
+ TEST_ST_LD_BYPASS(29, lw, sw, 0x23300112, 12, tdat );
+ TEST_ST_LD_BYPASS(30, lw, sw, 0x22330011, 16, tdat );
+ TEST_ST_LD_BYPASS(31, lw, sw, 0x12233001, 20, tdat );
+
+ # Test sh and lh (signed halfword)
+ TEST_ST_LD_BYPASS(32, lh, sh, 0xffffffffffffccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(33, lh, sh, 0xffffffffffffbccd, 2, tdat );
+ TEST_ST_LD_BYPASS(34, lh, sh, 0xffffffffffffbbcc, 4, tdat );
+ TEST_ST_LD_BYPASS(35, lh, sh, 0xffffffffffffabbc, 6, tdat );
+ TEST_ST_LD_BYPASS(36, lh, sh, 0xffffffffffffaabb, 8, tdat );
+ TEST_ST_LD_BYPASS(37, lh, sh, 0xffffffffffffdaab, 10, tdat );
+
+ TEST_ST_LD_BYPASS(38, lh, sh, 0x2233, 0, tdat );
+ TEST_ST_LD_BYPASS(39, lh, sh, 0x1223, 2, tdat );
+ TEST_ST_LD_BYPASS(40, lh, sh, 0x1122, 4, tdat );
+ TEST_ST_LD_BYPASS(41, lh, sh, 0x0112, 6, tdat );
+ TEST_ST_LD_BYPASS(42, lh, sh, 0x0011, 8, tdat );
+ TEST_ST_LD_BYPASS(43, lh, sh, 0x3001, 10, tdat );
+
+ # Test sh and lhu (unsigned halfword)
+ TEST_ST_LD_BYPASS(44, lhu, sh, 0x2233, 0, tdat );
+ TEST_ST_LD_BYPASS(45, lhu, sh, 0x1223, 2, tdat );
+ TEST_ST_LD_BYPASS(46, lhu, sh, 0x1122, 4, tdat );
+ TEST_ST_LD_BYPASS(47, lhu, sh, 0x0112, 6, tdat );
+ TEST_ST_LD_BYPASS(48, lhu, sh, 0x0011, 8, tdat );
+ TEST_ST_LD_BYPASS(49, lhu, sh, 0x3001, 10, tdat );
+
+ # RV64-specific tests for ld, sd, and lwu
+#if __riscv_xlen == 64
+ # Test sd and ld (doubleword)
+ TEST_ST_LD_BYPASS(50, ld, sd, 0x0011223344556677, 0, tdat );
+ TEST_ST_LD_BYPASS(51, ld, sd, 0x1122334455667788, 8, tdat );
+ TEST_ST_LD_BYPASS(52, ld, sd, 0x2233445566778899, 16, tdat );
+ TEST_ST_LD_BYPASS(53, ld, sd, 0xabbccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(54, ld, sd, 0xaabbccd, 8, tdat );
+ TEST_ST_LD_BYPASS(55, ld, sd, 0xdaabbcc, 16, tdat );
+ TEST_ST_LD_BYPASS(56, ld, sd, 0xddaabbc, 24, tdat );
+ TEST_ST_LD_BYPASS(57, ld, sd, 0xcddaabb, 32, tdat );
+ TEST_ST_LD_BYPASS(58, ld, sd, 0xccddaab, 40, tdat );
+
+ TEST_ST_LD_BYPASS(59, ld, sd, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(60, ld, sd, 0x30011223, 8, tdat );
+ TEST_ST_LD_BYPASS(61, ld, sd, 0x33001122, 16, tdat );
+ TEST_ST_LD_BYPASS(62, ld, sd, 0x23300112, 24, tdat );
+ TEST_ST_LD_BYPASS(63, ld, sd, 0x22330011, 32, tdat );
+ TEST_ST_LD_BYPASS(64, ld, sd, 0x12233001, 40, tdat );
+
+ # Test sw and lwu (unsigned word)
+ TEST_ST_LD_BYPASS(65, lwu, sw, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(66, lwu, sw, 0x33001122, 8, tdat );
+ TEST_ST_LD_BYPASS(67, lwu, sw, 0x30011223, 4, tdat );
+ TEST_ST_LD_BYPASS(68, lwu, sw, 0x23300112, 12, tdat );
+ TEST_ST_LD_BYPASS(69, lwu, sw, 0x22330011, 16, tdat );
+ TEST_ST_LD_BYPASS(70, lwu, sw, 0x12233001, 20, tdat );
+#endif
+
+ li a0, 0xef # Immediate load for manual store test
+ la a1, tdat # Load address of tdat
+ sb a0, 3(a1) # Store byte at offset 3 of tdat
+ lb a2, 3(a1) # Load byte back for verification
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+ .rept 20
+ .word 0xdeadbeef
+ .endr
+
+
+RVTEST_DATA_END
diff --git a/isa/rv64uzfh/fadd.S b/isa/rv64uzfh/fadd.S
index 6ca7f33..973a59c 100644
--- a/isa/rv64uzfh/fadd.S
+++ b/isa/rv64uzfh/fadd.S
@@ -30,7 +30,7 @@ RVTEST_CODE_BEGIN
TEST_FP_OP2_H(10, fmul.h, 1, 1.1, 11.0, 0.1 );
# Is the canonical NaN generated for Inf - Inf?
- TEST_FP_OP2_H(11, fsub.h, 0x10, qNaNh, Inf, Inf);
+ TEST_FP_OP2_H_HEX(11, fsub.h, 0x10, 0x7e00, Infh, Infh);
TEST_PASSFAIL
diff --git a/isa/rv64uzfh/fclass.S b/isa/rv64uzfh/fclass.S
index 86af7e5..a10f241 100644
--- a/isa/rv64uzfh/fclass.S
+++ b/isa/rv64uzfh/fclass.S
@@ -21,15 +21,15 @@ RVTEST_CODE_BEGIN
TEST_CASE(testnum, a0, correct, li a0, input; fmv.h.x fa0, a0; \
fclass.h a0, fa0)
- TEST_FCLASS_H( 2, 1 << 0, 0xfc00 )
+ TEST_FCLASS_H( 2, 1 << 0, nInfh )
TEST_FCLASS_H( 3, 1 << 1, 0xbc00 )
TEST_FCLASS_H( 4, 1 << 2, 0x83ff )
TEST_FCLASS_H( 5, 1 << 3, 0x8000 )
TEST_FCLASS_H( 6, 1 << 4, 0x0000 )
TEST_FCLASS_H( 7, 1 << 5, 0x03ff )
TEST_FCLASS_H( 8, 1 << 6, 0x3c00 )
- TEST_FCLASS_H( 9, 1 << 7, 0x7c00 )
- TEST_FCLASS_H(10, 1 << 8, 0x7c01 )
+ TEST_FCLASS_H( 9, 1 << 7, Infh )
+ TEST_FCLASS_H(10, 1 << 8, sNaNh )
TEST_FCLASS_H(11, 1 << 9, 0x7e00 )
TEST_PASSFAIL
diff --git a/isa/rv64uzfh/fcvt_w.S b/isa/rv64uzfh/fcvt_w.S
index 013ecac..b2ac1bf 100644
--- a/isa/rv64uzfh/fcvt_w.S
+++ b/isa/rv64uzfh/fcvt_w.S
@@ -92,8 +92,8 @@ RVTEST_DATA_BEGIN
#tdat:
#.word 0xffffffff
#.word 0x7fffffff
-#.word 0xff800000
-#.word 0x7f800000
+#.word nInff
+#.word Inff
tdat:
.word 0xffffffff
diff --git a/isa/rv64uzfh/fmin.S b/isa/rv64uzfh/fmin.S
index 3feec99..35d7b5d 100644
--- a/isa/rv64uzfh/fmin.S
+++ b/isa/rv64uzfh/fmin.S
@@ -31,10 +31,10 @@ RVTEST_CODE_BEGIN
TEST_FP_OP2_H(16, fmax.h, 0, 3.14159265, 3.14159265, 0.00000001 );
TEST_FP_OP2_H(17, fmax.h, 0, -1.0, -1.0, -2.0 );
- # FMIN(hNaN, x) = x
- TEST_FP_OP2_H(20, fmax.h, 0x10, 1.0, sNaNh, 1.0);
+ # FMIN(sNaN, x) = x
+ TEST_FP_OP2_H_HEX(20, fmax.h, 0x10, 0x3c00, sNaNh, 0x3c00);
# FMIN(hNaN, hNaN) = canonical NaN
- TEST_FP_OP2_H(21, fmax.h, 0x00, qNaNh, NaN, NaN);
+ TEST_FP_OP2_H_HEX(21, fmax.h, 0x00, 0x7e00, 0x7fff, 0x7fff);
# -0.0 < +0.0
TEST_FP_OP2_H(30, fmin.h, 0, -0.0, -0.0, 0.0 );
diff --git a/isa/rv64uziccid/Makefrag b/isa/rv64uziccid/Makefrag
new file mode 100644
index 0000000..0a16a0f
--- /dev/null
+++ b/isa/rv64uziccid/Makefrag
@@ -0,0 +1,9 @@
+#=======================================================================
+# Makefrag for rv64uziccid tests
+#-----------------------------------------------------------------------
+
+rv64uziccid_sc_tests = \
+ ziccid \
+
+rv64uziccid_p_tests = $(addprefix rv64uziccid-p-, $(rv64uziccid_sc_tests))
+rv64uziccid_v_tests = $(addprefix rv64uziccid-v-, $(rv64uziccid_sc_tests))
diff --git a/isa/rv64uziccid/ziccid.S b/isa/rv64uziccid/ziccid.S
new file mode 100644
index 0000000..1e3256a
--- /dev/null
+++ b/isa/rv64uziccid/ziccid.S
@@ -0,0 +1,48 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ziccid.S
+#-----------------------------------------------------------------------------
+#
+# Test Ziccid eventuality property.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64UF
+RVTEST_CODE_BEGIN
+
+ la t0, insn
+ li t1, 0x00100513 # li a0, 1
+ li t2, 0x00000513 # li a0, 0
+
+ sw t2, (t0)
+ fence.i
+
+ li a1, 100
+loop:
+ .balign 2
+insn:
+ .word 0
+
+ addi a1, a1, -1
+ bnez a1, 1f
+ # modify instruction on 100th iteration
+ sw t1, (t0)
+1:
+ # break out of loop if the modified instruction is executed
+ beqz a0, loop
+
+ TEST_CASE(2, x0, 0, nop)
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END