diff options
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 Binary files differdeleted file mode 100755 index 9b72737..0000000 --- a/debug/test +++ /dev/null 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 |