From: Megan Wachs Date: Mon, 17 Apr 2017 18:33:46 +0000 (-0700) Subject: Merge remote-tracking branch 'origin/priv-1.10' into HEAD X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d76b30df333659baf81b8411c7144378b735062a;hp=a5f84eecc4f7ffc698d57724f49d6aa8ce996e5c;p=riscv-tests.git Merge remote-tracking branch 'origin/priv-1.10' into HEAD --- diff --git a/benchmarks/Makefile b/benchmarks/Makefile index 531d981..d1c2362 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -29,41 +29,29 @@ bmarks = \ spmv \ mt-vvadd \ mt-matmul \ - -bmarks_host = \ - median \ - qsort \ - towers \ - vvadd \ - multiply \ - spmv \ - vec-vvadd \ - vec-cmplxmult \ - vec-matmul \ + pmp \ #-------------------------------------------------------------------- # Build rules #-------------------------------------------------------------------- -HOST_OPTS = -std=gnu99 -DPREALLOCATE=0 -DHOST_DEBUG=1 -HOST_COMP = gcc $(HOST_OPTS) - RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf- RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_GCC_OPTS ?= -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf +RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs) -RISCV_LINK_MT ?= $(RISCV_GCC) -T $(src_dir)/common/test-mt.ld -RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lgcc +RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lgcc -T $(src_dir)/common/test.ld RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.data RISCV_SIM ?= spike --isa=rv$(XLEN)gc -VPATH += $(addprefix $(src_dir)/, $(bmarks)) -VPATH += $(src_dir)/common - incs += -I$(src_dir)/../env -I$(src_dir)/common $(addprefix -I$(src_dir)/, $(bmarks)) objs := -include $(patsubst %, $(src_dir)/%/bmark.mk, $(bmarks)) +define compile_template +$(1).riscv: $(wildcard $(src_dir)/$(1)/*) $(wildcard $(src_dir)/common/*) + $$(RISCV_GCC) $$(incs) $$(RISCV_GCC_OPTS) $$(RISCV_LINK_OPTS) -o $$@ $(wildcard $(src_dir)/$(1)/*.c) $(wildcard $(src_dir)/common/*.c) $(wildcard $(src_dir)/common/*.S) +endef + +$(foreach bmark,$(bmarks),$(eval $(call compile_template,$(bmark)))) #------------------------------------------------------------ # Build and run benchmarks on riscv simulator @@ -72,46 +60,17 @@ bmarks_riscv_bin = $(addsuffix .riscv, $(bmarks)) bmarks_riscv_dump = $(addsuffix .riscv.dump, $(bmarks)) bmarks_riscv_out = $(addsuffix .riscv.out, $(bmarks)) -bmarks_defs = -DPREALLOCATE=1 -DHOST_DEBUG=0 -bmarks_cycles = 80000 - $(bmarks_riscv_dump): %.riscv.dump: %.riscv $(RISCV_OBJDUMP) $< > $@ $(bmarks_riscv_out): %.riscv.out: %.riscv $(RISCV_SIM) $< > $@ -%.o: %.c - $(RISCV_GCC) $(RISCV_GCC_OPTS) $(bmarks_defs) \ - -c $(incs) $< -o $@ - -%.o: %.S - $(RISCV_GCC) $(RISCV_GCC_OPTS) $(bmarks_defs) -D__ASSEMBLY__=1 \ - -c $(incs) $< -o $@ - riscv: $(bmarks_riscv_dump) -run-riscv: $(bmarks_riscv_out) - echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ - $(bmarks_riscv_out); echo; +run: $(bmarks_riscv_out) junk += $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(bmarks_riscv_hex) $(bmarks_riscv_out) -#------------------------------------------------------------ -# Build and run benchmarks on host machine - -bmarks_host_bin = $(addsuffix .host, $(bmarks_host)) -bmarks_host_out = $(addsuffix .host.out, $(bmarks_host)) - -$(bmarks_host_out): %.host.out: %.host - ./$< > $@ - -host: $(bmarks_host_bin) -run-host: $(bmarks_host_out) - echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ - $(bmarks_host_out); echo; - -junk += $(bmarks_host_bin) $(bmarks_host_out) - #------------------------------------------------------------ # Default diff --git a/benchmarks/common/crt.S b/benchmarks/common/crt.S index a821769..d75e81e 100644 --- a/benchmarks/common/crt.S +++ b/benchmarks/common/crt.S @@ -12,12 +12,9 @@ # define REGBYTES 4 #endif - .text + .section ".text.init" .globl _start _start: - la t0, trap_entry - csrw mtvec, t0 - li x1, 0 li x2, 0 li x3, 0 @@ -55,20 +52,23 @@ _start: csrs mstatus, t0 # make sure XLEN agrees with compilation choice - csrr t0, misa + li t0, 1 + slli t0, t0, 31 #if __riscv_xlen == 64 - bltz t0, 1f -#else bgez t0, 1f +#else + bltz t0, 1f #endif - li a0, 1234 - j tohost_exit +2: + li a0, 1 + sw a0, tohost, t0 + j 2b 1: #ifdef __riscv_flen # initialize FPU if we have one - andi t0, t0, 1 << ('f' - 'a') - beqz t0, 1f + la t0, 1f + csrw mtvec, t0 fssr x0 fmv.s.x f0, x0 @@ -103,12 +103,18 @@ _start: fmv.s.x f29,x0 fmv.s.x f30,x0 fmv.s.x f31,x0 +1: #endif -1: + # initialize trap vector + la t0, trap_entry + csrw mtvec, t0 # initialize global pointer - la gp, _gp +.option push +.option norelax + la gp, __global_pointer$ +.option pop la tp, _end + 63 and tp, tp, -64 diff --git a/benchmarks/common/syscalls.c b/benchmarks/common/syscalls.c index 3f15aac..4940aa2 100644 --- a/benchmarks/common/syscalls.c +++ b/benchmarks/common/syscalls.c @@ -8,15 +8,13 @@ #include "util.h" #define SYS_write 64 -#define SYS_exit 93 -#define SYS_stats 1234 #undef strcmp extern volatile uint64_t tohost; extern volatile uint64_t fromhost; -static uintptr_t handle_frontend_syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2) +static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2) { volatile uint64_t magic_mem[8] __attribute__((aligned(64))); magic_mem[0] = which; @@ -38,7 +36,7 @@ static uintptr_t handle_frontend_syscall(uintptr_t which, uint64_t arg0, uint64_ static uintptr_t counters[NUM_COUNTERS]; static char* counter_names[NUM_COUNTERS]; -static int handle_stats(int enable) +void setStats(int enable) { int i = 0; #define READ_CTR(name) do { \ @@ -52,7 +50,6 @@ static int handle_stats(int enable) READ_CTR(minstret); #undef READ_CTR - return 0; } void __attribute__((noreturn)) tohost_exit(uintptr_t code) @@ -61,39 +58,14 @@ void __attribute__((noreturn)) tohost_exit(uintptr_t code) while (1); } -uintptr_t handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) -{ - if (cause != CAUSE_MACHINE_ECALL) - tohost_exit(1337); - else if (regs[17] == SYS_exit) - tohost_exit(regs[10]); - else if (regs[17] == SYS_stats) - regs[10] = handle_stats(regs[10]); - else - regs[10] = handle_frontend_syscall(regs[17], regs[10], regs[11], regs[12]); - - return epc + ((*(unsigned short*)epc & 3) == 3 ? 4 : 2); -} - -static uintptr_t syscall(uintptr_t num, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2) +uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) { - register uintptr_t a7 asm("a7") = num; - register uintptr_t a0 asm("a0") = arg0; - register uintptr_t a1 asm("a1") = arg1; - register uintptr_t a2 asm("a2") = arg2; - asm volatile ("scall" : "+r"(a0) : "r"(a1), "r"(a2), "r"(a7)); - return a0; + tohost_exit(1337); } void exit(int code) { - syscall(SYS_exit, code, 0, 0); - while (1); -} - -void setStats(int enable) -{ - syscall(SYS_stats, enable, 0, 0); + tohost_exit(code); } void printstr(const char* s) diff --git a/benchmarks/common/test.ld b/benchmarks/common/test.ld index dd32bb1..a08d71d 100644 --- a/benchmarks/common/test.ld +++ b/benchmarks/common/test.ld @@ -22,7 +22,7 @@ SECTIONS /* text: test code section */ . = 0x80000000; - .text.init : { crt.o(.text) } + .text.init : { *(.text.init) } .tohost ALIGN(0x1000) : { *(.tohost) } @@ -32,7 +32,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) } @@ -48,14 +48,14 @@ SECTIONS .tdata : { _tls_data = .; - crt.o(.tdata.begin) + *(.tdata.begin) *(.tdata) - crt.o(.tdata.end) + *(.tdata.end) } .tbss : { *(.tbss) - crt.o(.tbss.end) + *(.tbss.end) } /* End of uninitalized data segement */ diff --git a/benchmarks/common/util.h b/benchmarks/common/util.h index 22f81cf..081cfd6 100644 --- a/benchmarks/common/util.h +++ b/benchmarks/common/util.h @@ -3,62 +3,12 @@ #ifndef __UTIL_H #define __UTIL_H -//-------------------------------------------------------------------------- -// Macros - -// Set HOST_DEBUG to 1 if you are going to compile this for a host -// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG -// to 0 if you are compiling with the smips-gcc toolchain. - -#ifndef HOST_DEBUG -#define HOST_DEBUG 0 -#endif - -// Set PREALLOCATE to 1 if you want to preallocate the benchmark -// function before starting stats. If you have instruction/data -// caches and you don't want to count the overhead of misses, then -// you will need to use preallocation. - -#ifndef PREALLOCATE -#define PREALLOCATE 0 -#endif - -// Set SET_STATS to 1 if you want to carve out the piece that actually -// does the computation. - -#if HOST_DEBUG -#include -static void setStats(int enable) {} -#else extern void setStats(int enable); -#endif #include #define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; } -static void printArray(const char name[], int n, const int arr[]) -{ -#if HOST_DEBUG - int i; - printf( " %10s :", name ); - for ( i = 0; i < n; i++ ) - printf( " %3d ", arr[i] ); - printf( "\n" ); -#endif -} - -static void printDoubleArray(const char name[], int n, const double arr[]) -{ -#if HOST_DEBUG - int i; - printf( " %10s :", name ); - for ( i = 0; i < n; i++ ) - printf( " %g ", arr[i] ); - printf( "\n" ); -#endif -} - static int verify(int n, const volatile int* test, const int* verify) { int i; @@ -117,6 +67,11 @@ static uint64_t lfsr(uint64_t x) return (x >> 1) | (bit << 62); } +static uintptr_t insn_len(uintptr_t pc) +{ + return (*(unsigned short*)pc & 3) ? 4 : 2; +} + #ifdef __riscv #include "encoding.h" #endif diff --git a/benchmarks/dhrystone/bmark.mk b/benchmarks/dhrystone/bmark.mk deleted file mode 100644 index 06b4ab8..0000000 --- a/benchmarks/dhrystone/bmark.mk +++ /dev/null @@ -1,32 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -dhrystone_c_src = \ - dhrystone_main.c \ - dhrystone.c \ - syscalls.c \ - -dhrystone_riscv_src = \ - crt.S \ - -dhrystone_c_objs = $(patsubst %.c, %.o, $(dhrystone_c_src)) -dhrystone_riscv_objs = $(patsubst %.S, %.o, $(dhrystone_riscv_src)) - -dhrystone_host_bin = dhrystone.host -$(dhrystone_host_bin): $(dhrystone_c_src) - $(HOST_COMP) $^ -o $(dhrystone_host_bin) - -dhrystone_riscv_bin = dhrystone.riscv -$(dhrystone_riscv_bin): $(dhrystone_c_objs) $(dhrystone_riscv_objs) - $(RISCV_LINK) $(dhrystone_c_objs) $(dhrystone_riscv_objs) \ - -o $(dhrystone_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(dhrystone_c_objs) $(dhrystone_riscv_objs) \ - $(dhrystone_host_bin) $(dhrystone_riscv_bin) diff --git a/benchmarks/dhrystone/dhrystone_main.c b/benchmarks/dhrystone/dhrystone_main.c index 492270a..9c7bcf5 100644 --- a/benchmarks/dhrystone/dhrystone_main.c +++ b/benchmarks/dhrystone/dhrystone_main.c @@ -5,45 +5,13 @@ //-------------------------------------------------------------------------- // // This is the classic Dhrystone synthetic integer benchmark. -// You should not change anything except the HOST_DEBUG and -// PREALLOCATE macros for your timing run. +// #pragma GCC optimize ("no-inline") #include "dhrystone.h" -//-------------------------------------------------------------------------- -// Macros - -// Set HOST_DEBUG to 1 if you are going to compile this for a host -// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG -// to 0 if you are compiling with the smips-gcc toolchain. - -#ifndef HOST_DEBUG -#define HOST_DEBUG 0 -#endif - -// Set PREALLOCATE to 1 if you want to preallocate the benchmark -// function before starting stats. If you have instruction/data -// caches and you don't want to count the overhead of misses, then -// you will need to use preallocation. - -#ifndef PREALLOCATE -#define PREALLOCATE 0 -#endif - -// Set SET_STATS to 1 if you want to carve out the piece that actually -// does the computation. - -#ifndef SET_STATS -#define SET_STATS 0 -#endif - -#if HOST_DEBUG -# define debug_printf printf -#else void debug_printf(const char* str, ...); -#endif #include "util.h" @@ -101,21 +69,7 @@ int main (int argc, char** argv) REG int Number_Of_Runs; /* Arguments */ -#if HOST_DEBUG - if (argc > 2) - { - printf("Usage: %s [number of loops]\n", argv[0]); - exit (1); - } - if (argc == 2) - { - Number_Of_Runs = atoi (argv[1]); - } - else if (Number_Of_Runs <= 0) -#endif - { - Number_Of_Runs = NUMBER_OF_RUNS; - } + Number_Of_Runs = NUMBER_OF_RUNS; /* Initializations */ diff --git a/benchmarks/median/bmark.mk b/benchmarks/median/bmark.mk deleted file mode 100644 index b489a67..0000000 --- a/benchmarks/median/bmark.mk +++ /dev/null @@ -1,31 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -median_c_src = \ - median_main.c \ - median.c \ - syscalls.c \ - -median_riscv_src = \ - crt.S \ - -median_c_objs = $(patsubst %.c, %.o, $(median_c_src)) -median_riscv_objs = $(patsubst %.S, %.o, $(median_riscv_src)) - -median_host_bin = median.host -$(median_host_bin): $(median_c_src) - $(HOST_COMP) $^ -o $(median_host_bin) - -median_riscv_bin = median.riscv -$(median_riscv_bin): $(median_c_objs) $(median_riscv_objs) - $(RISCV_LINK) $(median_c_objs) $(median_riscv_objs) -o $(median_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(median_c_objs) $(median_riscv_objs) \ - $(median_host_bin) $(median_riscv_bin) diff --git a/benchmarks/median/median_main.c b/benchmarks/median/median_main.c index c7fd6a6..b62ecd1 100644 --- a/benchmarks/median/median_main.c +++ b/benchmarks/median/median_main.c @@ -7,8 +7,7 @@ // This benchmark performs a 1D three element median filter. The // input data (and reference data) should be generated using the // median_gendata.pl perl script and dumped to a file named -// dataset1.h You should not change anything except the -// HOST_DEBUG and PREALLOCATE macros for your timing run. +// dataset1.h. #include "util.h" @@ -26,10 +25,6 @@ int main( int argc, char* argv[] ) { int results_data[DATA_SIZE]; - // Output the input array - printArray( "input", DATA_SIZE, input_data ); - printArray( "verify", DATA_SIZE, verify_data ); - #if PREALLOCATE // If needed we preallocate everything in the caches median( DATA_SIZE, input_data, results_data ); @@ -40,9 +35,6 @@ int main( int argc, char* argv[] ) median( DATA_SIZE, input_data, results_data ); setStats(0); - // Print out the results - printArray( "results", DATA_SIZE, results_data ); - // Check the results return verify( DATA_SIZE, results_data, verify_data ); } diff --git a/benchmarks/mm/bmark.mk b/benchmarks/mm/bmark.mk deleted file mode 100644 index ec8fd16..0000000 --- a/benchmarks/mm/bmark.mk +++ /dev/null @@ -1,31 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -mm_c_src = \ - mm_main.c \ - mm.c \ - syscalls.c \ - -mm_riscv_src = \ - crt.S \ - -mm_c_objs = $(patsubst %.c, %.o, $(mm_c_src)) -mm_riscv_objs = $(patsubst %.S, %.o, $(mm_riscv_src)) - -mm_host_bin = mm.host -$(mm_host_bin) : $(mm_c_src) - $(HOST_COMP) $^ -o $(mm_host_bin) - -mm_riscv_bin = mm.riscv -$(mm_riscv_bin) : $(mm_c_objs) $(mm_riscv_objs) - $(RISCV_LINK) $(mm_c_objs) $(mm_riscv_objs) -o $(mm_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(mm_c_objs) $(mm_riscv_objs) \ - $(mm_host_bin) $(mm_riscv_bin) diff --git a/benchmarks/mt-matmul/bmark.mk b/benchmarks/mt-matmul/bmark.mk deleted file mode 100644 index 6a7140f..0000000 --- a/benchmarks/mt-matmul/bmark.mk +++ /dev/null @@ -1,31 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -mt_matmul_c_src = \ - mt-matmul.c \ - matmul.c \ - syscalls.c \ - -mt_matmul_riscv_src = \ - crt.S \ - -mt_matmul_c_objs = $(patsubst %.c, %.o, $(mt_matmul_c_src)) -mt_matmul_riscv_objs = $(patsubst %.S, %.o, $(mt_matmul_riscv_src)) - -mt_matmul_host_bin = mt-matmul.host -$(mt_matmul_host_bin) : $(mt_matmul_c_src) - $(HOST_COMP) $^ -o $(mt_matmul_host_bin) - -mt_matmul_riscv_bin = mt-matmul.riscv -$(mt_matmul_riscv_bin) : $(mt_matmul_c_objs) $(mt_matmul_riscv_objs) - $(RISCV_LINK) $(mt_matmul_c_objs) $(mt_matmul_riscv_objs) $(RISCV_LINK_OPTS) -o $(mt_matmul_riscv_bin) - -junk += $(mt_matmul_c_objs) $(mt_matmul_riscv_objs) \ - $(mt_matmul_host_bin) $(mt_matmul_riscv_bin) diff --git a/benchmarks/mt-matmul/mt-matmul.c b/benchmarks/mt-matmul/mt-matmul.c index 9c68ada..dbb7562 100644 --- a/benchmarks/mt-matmul/mt-matmul.c +++ b/benchmarks/mt-matmul/mt-matmul.c @@ -12,10 +12,6 @@ // using the matmul_gendata.pl perl script and dumped to a file named // dataset.h. - -// print out arrays, etc. -//#define DEBUG - //-------------------------------------------------------------------------- // Includes @@ -57,10 +53,5 @@ void thread_entry(int cid, int nc) int res = verify(ARRAY_SIZE, results_data, verify_data); -#ifdef DEBUG - printArray("results:", ARRAY_SIZE, results_data); - printArray("verify :", ARRAY_SIZE, verify_data); -#endif - exit(res); } diff --git a/benchmarks/mt-vvadd/bmark.mk b/benchmarks/mt-vvadd/bmark.mk deleted file mode 100644 index ff969c1..0000000 --- a/benchmarks/mt-vvadd/bmark.mk +++ /dev/null @@ -1,31 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -mt_vvadd_c_src = \ - mt-vvadd.c \ - vvadd.c \ - syscalls.c \ - -mt_vvadd_riscv_src = \ - crt.S \ - -mt_vvadd_c_objs = $(patsubst %.c, %.o, $(mt_vvadd_c_src)) -mt_vvadd_riscv_objs = $(patsubst %.S, %.o, $(mt_vvadd_riscv_src)) - -mt_vvadd_host_bin = mt-vvadd.host -$(mt_vvadd_host_bin) : $(mt_vvadd_c_src) - $(HOST_COMP) $^ -o $(mt_vvadd_host_bin) - -mt_vvadd_riscv_bin = mt-vvadd.riscv -$(mt_vvadd_riscv_bin) : $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs) - $(RISCV_LINK) $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs) $(RISCV_LINK_OPTS) -o $(mt_vvadd_riscv_bin) - -junk += $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs) \ - $(mt_vvadd_host_bin) $(mt_vvadd_riscv_bin) diff --git a/benchmarks/mt-vvadd/mt-vvadd.c b/benchmarks/mt-vvadd/mt-vvadd.c index 8709166..54c9602 100644 --- a/benchmarks/mt-vvadd/mt-vvadd.c +++ b/benchmarks/mt-vvadd/mt-vvadd.c @@ -12,9 +12,6 @@ // generated using the vvadd_gendata.pl perl script and dumped // to a file named dataset.h -// to print out arrays, etc. -//#define DEBUG - //-------------------------------------------------------------------------- // Includes @@ -57,10 +54,6 @@ void thread_entry(int cid, int nc) stats(vvadd(cid, nc, DATA_SIZE, input1_data, input2_data, results_data); barrier(nc), DATA_SIZE); if(cid == 0) { -#ifdef DEBUG - printDoubleArray("out-of-place results: ", DATA_SIZE, results_data); - printDoubleArray("out-of-place verify : ", DATA_SIZE, verify_data); -#endif int res = verifyDouble(DATA_SIZE, results_data, verify_data); if(res) exit(res); } @@ -76,10 +69,6 @@ void thread_entry(int cid, int nc) stats(vvadd(cid, nc, DATA_SIZE, results_data, input2_data, results_data); barrier(nc), DATA_SIZE); if(cid == 0) { -#ifdef DEBUG - printDoubleArray("in-place results: ", DATA_SIZE, results_data); - printDoubleArray("in-place verify : ", DATA_SIZE, verify_data); -#endif int res = verifyDouble(DATA_SIZE, results_data, verify_data); if(res) exit(res); } diff --git a/benchmarks/multiply/bmark.mk b/benchmarks/multiply/bmark.mk deleted file mode 100644 index 93ba67f..0000000 --- a/benchmarks/multiply/bmark.mk +++ /dev/null @@ -1,31 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -multiply_c_src = \ - multiply_main.c \ - multiply.c \ - syscalls.c \ - -multiply_riscv_src = \ - crt.S \ - -multiply_c_objs = $(patsubst %.c, %.o, $(multiply_c_src)) -multiply_riscv_objs = $(patsubst %.S, %.o, $(multiply_riscv_src)) - -multiply_host_bin = multiply.host -$(multiply_host_bin): $(multiply_c_src) - $(HOST_COMP) $^ -o $(multiply_host_bin) - -multiply_riscv_bin = multiply.riscv -$(multiply_riscv_bin): $(multiply_c_objs) $(multiply_riscv_objs) - $(RISCV_LINK) $(multiply_c_objs) $(multiply_riscv_objs) -o $(multiply_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(multiply_c_objs) $(multiply_riscv_objs) \ - $(multiply_host_bin) $(multiply_riscv_bin) diff --git a/benchmarks/multiply/multiply_main.c b/benchmarks/multiply/multiply_main.c index aed3e0d..ea225eb 100644 --- a/benchmarks/multiply/multiply_main.c +++ b/benchmarks/multiply/multiply_main.c @@ -7,8 +7,7 @@ // This benchmark tests the software multiply implemenation. The // input data (and reference data) should be generated using the // multiply_gendata.pl perl script and dumped to a file named -// dataset1.h You should not change anything except the -// HOST_DEBUG and VERIFY macros for your timing run. +// dataset1.h #include "util.h" @@ -27,11 +26,6 @@ int main( int argc, char* argv[] ) int i; int results_data[DATA_SIZE]; - // Output the input arrays - printArray( "input1", DATA_SIZE, input_data1 ); - printArray( "input2", DATA_SIZE, input_data2 ); - printArray( "verify", DATA_SIZE, verify_data ); - #if PREALLOCATE for (i = 0; i < DATA_SIZE; i++) { @@ -45,9 +39,6 @@ int main( int argc, char* argv[] ) results_data[i] = multiply( input_data1[i], input_data2[i] ); } setStats(0); - - // Print out the results - printArray( "results", DATA_SIZE, results_data ); // Check the results return verify( DATA_SIZE, results_data, verify_data ); diff --git a/benchmarks/pmp/pmp.c b/benchmarks/pmp/pmp.c new file mode 100644 index 0000000..9d07ed8 --- /dev/null +++ b/benchmarks/pmp/pmp.c @@ -0,0 +1,198 @@ +// See LICENSE for license details. + +// Test of PMP functionality. + +#include +#include +#include +#include "util.h" + +volatile int trap_expected; + +#define INLINE inline __attribute__((always_inline)) + +uintptr_t handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) +{ + if (cause == CAUSE_ILLEGAL_INSTRUCTION) + exit(0); // no PMP support + + if (!trap_expected || cause != CAUSE_LOAD_ACCESS) + exit(1); + trap_expected = 0; + return epc + insn_len(epc); +} + +#define SCRATCH RISCV_PGSIZE +uintptr_t scratch[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE))); +uintptr_t l1pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE))); +uintptr_t l2pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE))); +#if __riscv_xlen == 64 +uintptr_t l3pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE))); +#else +#define l3pt l2pt +#endif + +static void init_pt() +{ + l1pt[0] = ((uintptr_t)l2pt >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_V; + l3pt[SCRATCH / RISCV_PGSIZE] = ((uintptr_t)scratch >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_A | PTE_D | PTE_V | PTE_R | PTE_W; +#if __riscv_xlen == 64 + l2pt[0] = ((uintptr_t)l3pt >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_V; + uintptr_t vm_choice = SPTBR_MODE_SV39; +#else + uintptr_t vm_choice = SPTBR_MODE_SV32; +#endif + write_csr(sptbr, ((uintptr_t)l1pt >> RISCV_PGSHIFT) | + (vm_choice * (SPTBR_MODE & ~(SPTBR_MODE<<1)))); + write_csr(pmpcfg0, (PMP_NAPOT | PMP_R) << 16); + write_csr(pmpaddr2, -1); +} + +INLINE uintptr_t va2pa(uintptr_t va) +{ + if (va < SCRATCH || va >= SCRATCH + RISCV_PGSIZE) + exit(3); + return va - SCRATCH + (uintptr_t)scratch; +} + +#define GRANULE (1UL << PMP_SHIFT) + +typedef struct { + uintptr_t cfg; + uintptr_t a0; + uintptr_t a1; +} pmpcfg_t; + +INLINE int pmp_ok(pmpcfg_t p, uintptr_t addr, uintptr_t size) +{ + if ((p.cfg & PMP_A) == 0) + return 1; + + if ((p.cfg & PMP_A) != PMP_TOR) { + uintptr_t range = 1; + + if ((p.cfg & PMP_A) == PMP_NAPOT) { + range <<= 1; + for (uintptr_t i = 1; i; i <<= 1) { + if ((p.a1 & i) == 0) + break; + p.a1 &= ~i; + range <<= 1; + } + } + + p.a0 = p.a1; + p.a1 = p.a0 + range; + } + + p.a0 *= GRANULE; + p.a1 *= GRANULE; + addr = va2pa(addr); + + uintptr_t hits = 0; + for (uintptr_t i = 0; i < size; i += GRANULE) { + if (p.a0 <= addr + i && addr + i < p.a1) + hits += GRANULE; + } + + return hits == 0 || hits >= size; +} + +INLINE void test_one(uintptr_t addr, uintptr_t size) +{ + uintptr_t new_mstatus = (read_csr(mstatus) & ~MSTATUS_MPP) | (MSTATUS_MPP & (MSTATUS_MPP >> 1)) | MSTATUS_MPRV; + switch (size) { + case 1: asm volatile ("csrrw %0, mstatus, %0; lb x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break; + case 2: asm volatile ("csrrw %0, mstatus, %0; lh x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break; + case 4: asm volatile ("csrrw %0, mstatus, %0; lw x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break; +#if __riscv_xlen >= 64 + case 8: asm volatile ("csrrw %0, mstatus, %0; ld x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break; +#endif + default: __builtin_unreachable(); + } +} + +INLINE void test_all_sizes(pmpcfg_t p, uintptr_t addr) +{ + for (size_t size = 1; size <= sizeof(uintptr_t); size *= 2) { + if (addr & (size - 1)) + continue; + trap_expected = !pmp_ok(p, addr, size); + test_one(addr, size); + if (trap_expected) + exit(2); + } +} + +INLINE void test_range_once(pmpcfg_t p, uintptr_t base, uintptr_t range) +{ + for (uintptr_t addr = base; addr < base + range; addr += GRANULE) + test_all_sizes(p, addr); +} + +INLINE pmpcfg_t set_pmp(pmpcfg_t p) +{ + uintptr_t cfg0 = read_csr(pmpcfg0); + write_csr(pmpcfg0, cfg0 & ~0xff00); + write_csr(pmpaddr0, p.a0); + write_csr(pmpaddr1, p.a1); + write_csr(pmpcfg0, ((p.cfg << 8) & 0xff00) | (cfg0 & ~0xff00)); + asm volatile ("sfence.vma"); + return p; +} + +INLINE pmpcfg_t set_pmp_range(uintptr_t base, uintptr_t range) +{ + pmpcfg_t p; + p.cfg = PMP_TOR | PMP_R; + p.a0 = base >> PMP_SHIFT; + p.a1 = (base + range) >> PMP_SHIFT; + return set_pmp(p); +} + +INLINE pmpcfg_t set_pmp_napot(uintptr_t base, uintptr_t range) +{ + pmpcfg_t p; + p.cfg = PMP_R | (range > GRANULE ? PMP_NAPOT : PMP_NA4); + p.a0 = 0; + p.a1 = (base + (range/2 - 1)) >> PMP_SHIFT; + return set_pmp(p); +} + +static void test_range(uintptr_t addr, uintptr_t range) +{ + pmpcfg_t p = set_pmp_range(va2pa(addr), range); + test_range_once(p, addr, range); + + if ((range & (range - 1)) == 0 && (addr & (range - 1)) == 0) { + p = set_pmp_napot(va2pa(addr), range); + test_range_once(p, addr, range); + } +} + +static void test_ranges(uintptr_t addr, uintptr_t size) +{ + for (uintptr_t range = GRANULE; range <= size; range += GRANULE) + test_range(addr, range); +} + +static void exhaustive_test(uintptr_t addr, uintptr_t size) +{ + for (uintptr_t base = addr; base < addr + size; base += GRANULE) + test_ranges(base, size - (base - addr)); +} + +int main() +{ + init_pt(); + + const int max_exhaustive = 32; + exhaustive_test(SCRATCH, max_exhaustive); + exhaustive_test(SCRATCH + RISCV_PGSIZE - max_exhaustive, max_exhaustive); + + test_range(SCRATCH, RISCV_PGSIZE); + test_range(SCRATCH, RISCV_PGSIZE / 2); + test_range(SCRATCH + RISCV_PGSIZE / 2, RISCV_PGSIZE / 2); + + return 0; +} diff --git a/benchmarks/qsort/bmark.mk b/benchmarks/qsort/bmark.mk deleted file mode 100644 index 4b39d96..0000000 --- a/benchmarks/qsort/bmark.mk +++ /dev/null @@ -1,30 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -qsort_c_src = \ - qsort_main.c \ - syscalls.c \ - -qsort_riscv_src = \ - crt.S \ - -qsort_c_objs = $(patsubst %.c, %.o, $(qsort_c_src)) -qsort_riscv_objs = $(patsubst %.S, %.o, $(qsort_riscv_src)) - -qsort_host_bin = qsort.host -$(qsort_host_bin) : $(qsort_c_src) - $(HOST_COMP) $^ -o $(qsort_host_bin) - -qsort_riscv_bin = qsort.riscv -$(qsort_riscv_bin) : $(qsort_c_objs) $(qsort_riscv_objs) - $(RISCV_LINK) $(qsort_c_objs) $(qsort_riscv_objs) -o $(qsort_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(qsort_c_objs) $(qsort_riscv_objs) \ - $(qsort_host_bin) $(qsort_riscv_bin) diff --git a/benchmarks/qsort/qsort_main.c b/benchmarks/qsort/qsort_main.c index e962e82..18adc25 100644 --- a/benchmarks/qsort/qsort_main.c +++ b/benchmarks/qsort/qsort_main.c @@ -8,10 +8,7 @@ // implementation is largely adapted from Numerical Recipes for C. The // input data (and reference data) should be generated using the // qsort_gendata.pl perl script and dumped to a file named -// dataset1.h The smips-gcc toolchain does not support system calls -// so printf's can only be used on a host system, not on the smips -// processor simulator itself. You should not change anything except -// the HOST_DEBUG and PREALLOCATE macros for your timing run. +// dataset1.h. #include "util.h" #include @@ -76,10 +73,6 @@ void sort(size_t n, type arr[]) for (;;) { -#if HOST_DEBUG - printArray( "", n, arr ); -#endif - // Insertion sort when subarray small enough. if ( ir-l < INSERTION_THRESHOLD ) { @@ -122,10 +115,6 @@ void sort(size_t n, type arr[]) // Push pointers to larger subarray on stack, // process smaller subarray immediately. -#if HOST_DEBUG - assert(stackp < stack+NSTACK); -#endif - if ( ir-i+1 >= j-l ) { stackp[0] = ir; @@ -147,10 +136,6 @@ void sort(size_t n, type arr[]) int main( int argc, char* argv[] ) { - // Output the input array - printArray( "input", DATA_SIZE, input_data ); - printArray( "verify", DATA_SIZE, verify_data ); - #if PREALLOCATE // If needed we preallocate everything in the caches sort(DATA_SIZE, verify_data); @@ -163,9 +148,6 @@ int main( int argc, char* argv[] ) sort( DATA_SIZE, input_data ); setStats(0); - // Print out the results - printArray( "test", DATA_SIZE, input_data ); - // Check the results return verify( DATA_SIZE, input_data, verify_data ); } diff --git a/benchmarks/readme.txt b/benchmarks/readme.txt index a14780f..d90fe2d 100644 --- a/benchmarks/readme.txt +++ b/benchmarks/readme.txt @@ -37,13 +37,6 @@ points to make about the toolchain. about how to write assembly in C here: http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html - + If you look at the example benchmarks you will see that I have two - important macros HOST_DEBUG and VERIFY. Use HOST_DEBUG to compile the - benchmark on your host workstation (ie use standard gcc on Athena/Linux - box) and then debug the benchmark. Since you are using standard gcc you - can use printf's to make sure that your benchmark actually works before - trying it out on your RISCV processor. - + Debugging C compiled code on the RISCV processor is a real pain. It is hard to associate the assembly with the C code and there is no debugger. So if you encounter a bug in your processor when running a C diff --git a/benchmarks/rsort/bmark.mk b/benchmarks/rsort/bmark.mk deleted file mode 100644 index 0fa713c..0000000 --- a/benchmarks/rsort/bmark.mk +++ /dev/null @@ -1,30 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -rsort_c_src = \ - rsort.c \ - syscalls.c \ - -rsort_riscv_src = \ - crt.S \ - -rsort_c_objs = $(patsubst %.c, %.o, $(rsort_c_src)) -rsort_riscv_objs = $(patsubst %.S, %.o, $(rsort_riscv_src)) - -rsort_host_bin = rsort.host -$(rsort_host_bin) : $(rsort_c_src) - $(HOST_COMP) $^ -o $(rsort_host_bin) - -rsort_riscv_bin = rsort.riscv -$(rsort_riscv_bin) : $(rsort_c_objs) $(rsort_riscv_objs) - $(RISCV_LINK) $(rsort_c_objs) $(rsort_riscv_objs) -o $(rsort_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(rsort_c_objs) $(rsort_riscv_objs) \ - $(rsort_host_bin) $(rsort_riscv_bin) diff --git a/benchmarks/rsort/rsort.c b/benchmarks/rsort/rsort.c index dc53642..7ffc12a 100644 --- a/benchmarks/rsort/rsort.c +++ b/benchmarks/rsort/rsort.c @@ -8,10 +8,7 @@ // implementation is largely adapted from Numerical Recipes for C. The // input data (and reference data) should be generated using the // qsort_gendata.pl perl script and dumped to a file named -// dataset1.h The smips-gcc toolchain does not support system calls -// so printf's can only be used on a host system, not on the smips -// processor simulator itself. You should not change anything except -// the HOST_DEBUG and PREALLOCATE macros for your timing run. +// dataset1.h #include "util.h" #include @@ -107,9 +104,6 @@ void sort(size_t n, type* arrIn, type* scratchIn) int main( int argc, char* argv[] ) { static type scratch[DATA_SIZE]; - // Output the input array - printArray( "input", DATA_SIZE, input_data ); - printArray( "verify", DATA_SIZE, verify_data ); #if PREALLOCATE // If needed we preallocate everything in the caches @@ -123,9 +117,6 @@ int main( int argc, char* argv[] ) sort(DATA_SIZE, input_data, scratch); setStats(0); - // Print out the results - printArray( "test", DATA_SIZE, input_data ); - // Check the results return verify( DATA_SIZE, input_data, verify_data ); } diff --git a/benchmarks/spmv/bmark.mk b/benchmarks/spmv/bmark.mk deleted file mode 100644 index dcfdb19..0000000 --- a/benchmarks/spmv/bmark.mk +++ /dev/null @@ -1,30 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -spmv_c_src = \ - spmv_main.c \ - syscalls.c \ - -spmv_riscv_src = \ - crt.S \ - -spmv_c_objs = $(patsubst %.c, %.o, $(spmv_c_src)) -spmv_riscv_objs = $(patsubst %.S, %.o, $(spmv_riscv_src)) - -spmv_host_bin = spmv.host -$(spmv_host_bin) : $(spmv_c_src) - $(HOST_COMP) $^ -o $(spmv_host_bin) - -spmv_riscv_bin = spmv.riscv -$(spmv_riscv_bin) : $(spmv_c_objs) $(spmv_riscv_objs) - $(RISCV_LINK) $(spmv_c_objs) $(spmv_riscv_objs) -o $(spmv_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(spmv_c_objs) $(spmv_riscv_objs) \ - $(spmv_host_bin) $(spmv_riscv_bin) diff --git a/benchmarks/towers/bmark.mk b/benchmarks/towers/bmark.mk deleted file mode 100644 index b16bf04..0000000 --- a/benchmarks/towers/bmark.mk +++ /dev/null @@ -1,30 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -towers_c_src = \ - towers_main.c \ - syscalls.c \ - -towers_riscv_src = \ - crt.S \ - -towers_c_objs = $(patsubst %.c, %.o, $(towers_c_src)) -towers_riscv_objs = $(patsubst %.S, %.o, $(towers_riscv_src)) - -towers_host_bin = towers.host -$(towers_host_bin) : $(towers_c_src) - $(HOST_COMP) $^ -o $(towers_host_bin) - -towers_riscv_bin = towers.riscv -$(towers_riscv_bin) : $(towers_c_objs) $(towers_riscv_objs) - $(RISCV_LINK) $(towers_c_objs) $(towers_riscv_objs) -o $(towers_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(towers_c_objs) $(towers_riscv_objs) \ - $(towers_host_bin) $(towers_riscv_bin) diff --git a/benchmarks/towers/towers_main.c b/benchmarks/towers/towers_main.c index 03de47d..8c2355a 100644 --- a/benchmarks/towers/towers_main.c +++ b/benchmarks/towers/towers_main.c @@ -13,10 +13,7 @@ // disc on top of a smaller disc. // // This implementation starts with NUM_DISC discs and uses a recursive -// algorithm to sovel the puzzle. The smips-gcc toolchain does not support -// system calls so printf's can only be used on a host system, not on the -// smips processor simulator itself. You should not change anything except -// the HOST_DEBUG and PREALLOCATE macros for your timing run. +// algorithm to sovel the puzzle. #include "util.h" @@ -140,34 +137,6 @@ void towers_clear( struct Towers* this ) } -#if HOST_DEBUG -void towers_print( struct Towers* this ) -{ - struct Node* ptr; - int i, numElements; - - printf( " pegA: " ); - for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegA))); i++ ) - printf( ". " ); - for ( ptr = this->pegA.head; ptr != 0; ptr = ptr->next ) - printf( "%d ", ptr->val ); - - printf( " pegB: " ); - for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegB))); i++ ) - printf( ". " ); - for ( ptr = this->pegB.head; ptr != 0; ptr = ptr->next ) - printf( "%d ", ptr->val ); - - printf( " pegC: " ); - for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegC))); i++ ) - printf( ". " ); - for ( ptr = this->pegC.head; ptr != 0; ptr = ptr->next ) - printf( "%d ", ptr->val ); - - printf( "\n" ); -} -#endif - void towers_solve_h( struct Towers* this, int n, struct List* startPeg, struct List* tempPeg, @@ -176,9 +145,6 @@ void towers_solve_h( struct Towers* this, int n, int val; if ( n == 1 ) { -#if HOST_DEBUG - towers_print(this); -#endif val = list_pop(startPeg); list_push(destPeg,val); this->numMoves++; @@ -202,43 +168,25 @@ int towers_verify( struct Towers* this ) int numDiscs = 0; if ( list_getSize(&this->pegA) != 0 ) { -#if HOST_DEBUG - printf( "ERROR: Peg A is not empty!\n" ); -#endif return 2; } if ( list_getSize(&this->pegB) != 0 ) { -#if HOST_DEBUG - printf( "ERROR: Peg B is not empty!\n" ); -#endif return 3; } if ( list_getSize(&this->pegC) != this->numDiscs ) { -#if HOST_DEBUG - printf( " ERROR: Expected %d discs but found only %d discs!\n", \ - this->numDiscs, list_getSize(&this->pegC) ); -#endif return 4; } for ( ptr = this->pegC.head; ptr != 0; ptr = ptr->next ) { numDiscs++; if ( ptr->val != numDiscs ) { -#if HOST_DEBUG - printf( " ERROR: Expecting disc %d on peg C but found disc %d instead!\n", \ - numDiscs, ptr->val ); -#endif return 5; } } if ( this->numMoves != ((1 << this->numDiscs) - 1) ) { -#if HOST_DEBUG - printf( " ERROR: Expecting %d num moves but found %d instead!\n", \ - ((1 << this->numDiscs) - 1), this->numMoves ); -#endif return 6; } @@ -280,12 +228,6 @@ int main( int argc, char* argv[] ) towers_solve( &towers ); setStats(0); - // Print out the results - -#if HOST_DEBUG - towers_print( &towers ); -#endif - // Check the results return towers_verify( &towers ); } diff --git a/benchmarks/vvadd/bmark.mk b/benchmarks/vvadd/bmark.mk deleted file mode 100644 index 5ab99de..0000000 --- a/benchmarks/vvadd/bmark.mk +++ /dev/null @@ -1,30 +0,0 @@ -#======================================================================= -# UCB CS250 Makefile fragment for benchmarks -#----------------------------------------------------------------------- -# -# Each benchmark directory should have its own fragment which -# essentially lists what the source files are and how to link them -# into an riscv and/or host executable. All variables should include -# the benchmark name as a prefix so that they are unique. -# - -vvadd_c_src = \ - vvadd_main.c \ - syscalls.c \ - -vvadd_riscv_src = \ - crt.S \ - -vvadd_c_objs = $(patsubst %.c, %.o, $(vvadd_c_src)) -vvadd_riscv_objs = $(patsubst %.S, %.o, $(vvadd_riscv_src)) - -vvadd_host_bin = vvadd.host -$(vvadd_host_bin) : $(vvadd_c_src) - $(HOST_COMP) $^ -o $(vvadd_host_bin) - -vvadd_riscv_bin = vvadd.riscv -$(vvadd_riscv_bin) : $(vvadd_c_objs) $(vvadd_riscv_objs) - $(RISCV_LINK) $(vvadd_c_objs) $(vvadd_riscv_objs) -o $(vvadd_riscv_bin) $(RISCV_LINK_OPTS) - -junk += $(vvadd_c_objs) $(vvadd_riscv_objs) \ - $(vvadd_host_bin) $(vvadd_riscv_bin) diff --git a/benchmarks/vvadd/vvadd_main.c b/benchmarks/vvadd/vvadd_main.c index 00e1593..d8ff01c 100644 --- a/benchmarks/vvadd/vvadd_main.c +++ b/benchmarks/vvadd/vvadd_main.c @@ -7,11 +7,7 @@ // This benchmark uses adds to vectors and writes the results to a // third vector. The input data (and reference data) should be // generated using the vvadd_gendata.pl perl script and dumped -// to a file named dataset1.h The smips-gcc toolchain does not -// support system calls so printf's can only be used on a host system, -// not on the smips processor simulator itself. You should not change -// anything except the HOST_DEBUG and PREALLOCATE macros for your timing -// runs. +// to a file named dataset1.h. #include "util.h" @@ -37,11 +33,6 @@ int main( int argc, char* argv[] ) { int results_data[DATA_SIZE]; - // Output the input array - printArray( "input1", DATA_SIZE, input1_data ); - printArray( "input2", DATA_SIZE, input2_data ); - printArray( "verify", DATA_SIZE, verify_data ); - #if PREALLOCATE // If needed we preallocate everything in the caches vvadd( DATA_SIZE, input1_data, input2_data, results_data ); @@ -52,9 +43,6 @@ int main( int argc, char* argv[] ) vvadd( DATA_SIZE, input1_data, input2_data, results_data ); setStats(0); - // Print out the results - printArray( "results", DATA_SIZE, results_data ); - // Check the results return verify( DATA_SIZE, results_data, verify_data ); } diff --git a/debug/programs/entry.S b/debug/programs/entry.S index a5e745d..e021860 100755 --- a/debug/programs/entry.S +++ b/debug/programs/entry.S @@ -35,7 +35,10 @@ handle_reset: csrwi mie, 0 # initialize global pointer - la gp, _gp +.option push +.option norelax + la gp, __global_pointer$ +.option pop # initialize stack pointer la sp, stack_top diff --git a/debug/targets/freedom-e300-sim/link.lds b/debug/targets/freedom-e300-sim/link.lds index 1dbb99c..1e0645a 100755 --- a/debug/targets/freedom-e300-sim/link.lds +++ b/debug/targets/freedom-e300-sim/link.lds @@ -13,7 +13,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) diff --git a/debug/targets/freedom-e300/link.lds b/debug/targets/freedom-e300/link.lds index 1dbb99c..1e0645a 100755 --- a/debug/targets/freedom-e300/link.lds +++ b/debug/targets/freedom-e300/link.lds @@ -13,7 +13,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) diff --git a/debug/targets/freedom-u500-sim/link.lds b/debug/targets/freedom-u500-sim/link.lds index 1dbb99c..1e0645a 100755 --- a/debug/targets/freedom-u500-sim/link.lds +++ b/debug/targets/freedom-u500-sim/link.lds @@ -13,7 +13,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) diff --git a/debug/targets/freedom-u500/link.lds b/debug/targets/freedom-u500/link.lds index 1dbb99c..1e0645a 100755 --- a/debug/targets/freedom-u500/link.lds +++ b/debug/targets/freedom-u500/link.lds @@ -13,7 +13,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) diff --git a/debug/targets/spike/link.lds b/debug/targets/spike/link.lds index 52e4472..b86b2b7 100755 --- a/debug/targets/spike/link.lds +++ b/debug/targets/spike/link.lds @@ -15,7 +15,7 @@ SECTIONS .data : { *(.data) } .sdata : { - _gp = . + 0x800; + __global_pointer$ = . + 0x800; *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) *(.sdata .sdata.* .gnu.linkonce.s.*) diff --git a/env b/env index 9e219c9..3f1d04a 160000 --- a/env +++ b/env @@ -1 +1 @@ -Subproject commit 9e219c9ca70459bfda9067d637bb8bf52c5f0326 +Subproject commit 3f1d04a2e8f849c306bdca7c7115462c3a60a6e0 diff --git a/isa/Makefile b/isa/Makefile index 3ed1b60..7f22c53 100644 --- a/isa/Makefile +++ b/isa/Makefile @@ -55,7 +55,7 @@ $$($(1)_p_tests): $(1)-p-%: $(1)/%.S $(1)_tests += $$($(1)_p_tests) $$($(1)_v_tests): $(1)-v-%: $(1)/%.S - $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -DENTROPY=0x$$(shell echo \$$@ | md5sum | cut -c 1-7) -std=gnu99 -O2 -I$(src_dir)/../env/v -I$(src_dir)/macros/scalar -T$(src_dir)/../env/v/link.ld $(src_dir)/../env/v/entry.S $(src_dir)/../env/v/*.c $$< -lc -o $$@ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -DENTROPY=0x$$(shell echo \$$@ | md5sum | cut -c 1-7) -std=gnu99 -O2 -I$(src_dir)/../env/v -I$(src_dir)/macros/scalar -T$(src_dir)/../env/v/link.ld $(src_dir)/../env/v/entry.S $(src_dir)/../env/v/*.c $$< -o $$@ $(1)_tests += $$($(1)_v_tests) $(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests)) @@ -92,8 +92,6 @@ tests_out = $(addsuffix .out, $(spike_tests)) tests32_out = $(addsuffix .out32, $(spike32_tests)) run: $(tests_out) $(tests32_out) - echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ - $(tests_out) $(tests32_out); echo; junk += $(tests) $(tests_dump) $(tests_hex) $(tests_out) $(tests32_out) diff --git a/isa/macros/scalar/test_macros.h b/isa/macros/scalar/test_macros.h index 006f419..6650fa8 100644 --- a/isa/macros/scalar/test_macros.h +++ b/isa/macros/scalar/test_macros.h @@ -44,9 +44,9 @@ test_ ## testnum: \ #define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11)) #define TEST_IMM_OP( testnum, inst, result, val1, imm ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x1, MASK_XLEN(val1); \ - inst x3, x1, SEXT_IMM(imm); \ + inst x30, x1, SEXT_IMM(imm); \ ) #define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \ @@ -59,20 +59,20 @@ test_ ## testnum: \ TEST_CASE( testnum, x6, result, \ li x4, 0; \ 1: li x1, MASK_XLEN(val1); \ - inst x3, x1, SEXT_IMM(imm); \ + inst x30, x1, SEXT_IMM(imm); \ TEST_INSERT_NOPS_ ## nop_cycles \ - addi x6, x3, 0; \ + addi x6, x30, 0; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ ) #define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x4, 0; \ 1: li x1, MASK_XLEN(val1); \ TEST_INSERT_NOPS_ ## nop_cycles \ - inst x3, x1, SEXT_IMM(imm); \ + inst x30, x1, SEXT_IMM(imm); \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ @@ -94,9 +94,9 @@ test_ ## testnum: \ #----------------------------------------------------------------------- #define TEST_R_OP( testnum, inst, result, val1 ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x1, val1; \ - inst x3, x1; \ + inst x30, x1; \ ) #define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \ @@ -109,9 +109,9 @@ test_ ## testnum: \ TEST_CASE( testnum, x6, result, \ li x4, 0; \ 1: li x1, val1; \ - inst x3, x1; \ + inst x30, x1; \ TEST_INSERT_NOPS_ ## nop_cycles \ - addi x6, x3, 0; \ + addi x6, x30, 0; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ @@ -122,10 +122,10 @@ test_ ## testnum: \ #----------------------------------------------------------------------- #define TEST_RR_OP( testnum, inst, result, val1, val2 ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x1, MASK_XLEN(val1); \ li x2, MASK_XLEN(val2); \ - inst x3, x1, x2; \ + inst x30, x1, x2; \ ) #define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \ @@ -153,35 +153,35 @@ test_ ## testnum: \ li x4, 0; \ 1: li x1, MASK_XLEN(val1); \ li x2, MASK_XLEN(val2); \ - inst x3, x1, x2; \ + inst x30, x1, x2; \ TEST_INSERT_NOPS_ ## nop_cycles \ - addi x6, x3, 0; \ + addi x6, x30, 0; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ ) #define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x4, 0; \ 1: li x1, MASK_XLEN(val1); \ TEST_INSERT_NOPS_ ## src1_nops \ li x2, MASK_XLEN(val2); \ TEST_INSERT_NOPS_ ## src2_nops \ - inst x3, x1, x2; \ + inst x30, x1, x2; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ ) #define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ li x4, 0; \ 1: li x2, MASK_XLEN(val2); \ TEST_INSERT_NOPS_ ## src1_nops \ li x1, MASK_XLEN(val1); \ TEST_INSERT_NOPS_ ## src2_nops \ - inst x3, x1, x2; \ + inst x30, x1, x2; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ @@ -216,17 +216,17 @@ test_ ## testnum: \ #----------------------------------------------------------------------- #define TEST_LD_OP( testnum, inst, result, offset, base ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ la x1, base; \ - inst x3, offset(x1); \ + inst x30, offset(x1); \ ) #define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \ - TEST_CASE( testnum, x3, result, \ + TEST_CASE( testnum, x30, result, \ la x1, base; \ li x2, result; \ store_inst x2, offset(x1); \ - load_inst x3, offset(x1); \ + load_inst x30, offset(x1); \ ) #define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \ @@ -234,9 +234,9 @@ test_ ## testnum: \ li TESTNUM, testnum; \ li x4, 0; \ 1: la x1, base; \ - inst x3, offset(x1); \ + inst x30, offset(x1); \ TEST_INSERT_NOPS_ ## nop_cycles \ - addi x6, x3, 0; \ + addi x6, x30, 0; \ li x29, result; \ bne x6, x29, fail; \ addi x4, x4, 1; \ @@ -249,9 +249,9 @@ test_ ## testnum: \ li x4, 0; \ 1: la x1, base; \ TEST_INSERT_NOPS_ ## nop_cycles \ - inst x3, offset(x1); \ + inst x30, offset(x1); \ li x29, result; \ - bne x3, x29, fail; \ + bne x30, x29, fail; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ @@ -265,9 +265,9 @@ test_ ## testnum: \ la x2, base; \ TEST_INSERT_NOPS_ ## src2_nops \ store_inst x1, offset(x2); \ - load_inst x3, offset(x2); \ + load_inst x30, offset(x2); \ li x29, result; \ - bne x3, x29, fail; \ + bne x30, x29, fail; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ @@ -281,9 +281,9 @@ test_ ## testnum: \ li x1, result; \ TEST_INSERT_NOPS_ ## src2_nops \ store_inst x1, offset(x2); \ - load_inst x3, offset(x2); \ + load_inst x30, offset(x2); \ li x29, result; \ - bne x3, x29, fail; \ + bne x30, x29, fail; \ addi x4, x4, 1; \ li x5, 2; \ bne x4, x5, 1b \ diff --git a/isa/rv32mi/Makefrag b/isa/rv32mi/Makefrag index a726244..5ee7edc 100644 --- a/isa/rv32mi/Makefrag +++ b/isa/rv32mi/Makefrag @@ -13,9 +13,6 @@ rv32mi_sc_tests = \ sbreak \ shamt \ -rv32mi_mc_tests = \ - ipi \ - rv32mi_p_tests = $(addprefix rv32mi-p-, $(rv32mi_sc_tests)) spike32_tests += $(rv32mi_p_tests) diff --git a/isa/rv32mi/ipi.S b/isa/rv32mi/ipi.S deleted file mode 100644 index c39fc29..0000000 --- a/isa/rv32mi/ipi.S +++ /dev/null @@ -1,7 +0,0 @@ -# See LICENSE for license details. - -#include "riscv_test.h" -#undef RVTEST_RV64M -#define RVTEST_RV64M RVTEST_RV32M - -#include "../rv64mi/ipi.S" diff --git a/isa/rv32si/dirty.S b/isa/rv32si/dirty.S index 7692b28..9340a85 100644 --- a/isa/rv32si/dirty.S +++ b/isa/rv32si/dirty.S @@ -4,7 +4,7 @@ #undef RVTEST_RV64M #define RVTEST_RV64M RVTEST_RV32M -#undef VM_SV39 -#define VM_SV39 VM_SV32 +#undef SPTBR_MODE_SV39 +#define SPTBR_MODE_SV39 SPTBR_MODE_SV32 #include "../rv64si/dirty.S" diff --git a/isa/rv32uf/Makefrag b/isa/rv32uf/Makefrag index bc958a7..7dde664 100644 --- a/isa/rv32uf/Makefrag +++ b/isa/rv32uf/Makefrag @@ -3,7 +3,7 @@ #----------------------------------------------------------------------- rv32uf_sc_tests = \ - fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin fsgnj \ + fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \ ldst move recoding \ rv32uf_p_tests = $(addprefix rv32uf-p-, $(rv32uf_sc_tests)) diff --git a/isa/rv32uf/fsgnj.S b/isa/rv32uf/fsgnj.S deleted file mode 100644 index 6d05a23..0000000 --- a/isa/rv32uf/fsgnj.S +++ /dev/null @@ -1,7 +0,0 @@ -# See LICENSE for license details. - -#include "riscv_test.h" -#undef RVTEST_RV64UF -#define RVTEST_RV64UF RVTEST_RV32UF - -#include "../rv64uf/fsgnj.S" diff --git a/isa/rv64mi/Makefrag b/isa/rv64mi/Makefrag index e4fa426..fb38e5f 100644 --- a/isa/rv64mi/Makefrag +++ b/isa/rv64mi/Makefrag @@ -12,9 +12,6 @@ rv64mi_sc_tests = \ scall \ sbreak \ -rv64mi_mc_tests = \ - ipi \ - rv64mi_p_tests = $(addprefix rv64mi-p-, $(rv64mi_sc_tests)) spike_tests += $(rv64mi_p_tests) diff --git a/isa/rv64mi/illegal.S b/isa/rv64mi/illegal.S index 30c22b2..a1b445f 100644 --- a/isa/rv64mi/illegal.S +++ b/isa/rv64mi/illegal.S @@ -13,23 +13,165 @@ RVTEST_RV64M RVTEST_CODE_BEGIN + .align 2 + .option norvc + li TESTNUM, 2 +bad2: .word 0 j fail - j pass + # Skip the rest of the test if S-mode is not present. + li t0, MSTATUS_MPP + csrc mstatus, t0 + li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S + csrs mstatus, t1 + csrr t2, mstatus + and t2, t2, t0 + bne t1, t2, pass + + # Test vectored interrupts if they are supported. +test_vectored_interrupts: + csrwi mip, MIP_SSIP + csrwi mie, MIP_SSIP + la t0, mtvec_handler + 1 + csrrw s0, mtvec, t0 + csrr t0, mtvec + andi t0, t0, 1 + beqz t0, msip + csrsi mstatus, MSTATUS_MIE +1: + j 1b +msip: + csrw mtvec, s0 + + # Delegate supervisor software interrupts so WFI won't stall. + csrwi mideleg, MIP_SSIP + # Enter supervisor mode. + la t0, 1f + csrw mepc, t0 + li t0, MSTATUS_MPP + csrc mstatus, t0 + li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S + csrs mstatus, t1 + mret + +1: + # Make sure WFI doesn't trap when TW=0. + wfi +bad3: + .word 0 + j fail + +bad4: + # Make sure WFI does trap when TW=1. + wfi + j fail + + # Make sure SFENCE.VMA and sptbr don't trap when TVM=0. + sfence.vma + csrr t0, sptbr +bad5: + .word 0 + j fail + +bad6: + # Make sure SFENCE.VMA and sptbr do trap when TVM=1. + sfence.vma + j fail +bad7: + csrr t0, sptbr + j fail + + # Make sure SRET doesn't trap when TSR=0. + la t0, bad8 + csrw sepc, t0 + li t0, SSTATUS_SPP + csrs sstatus, t0 + li t0, SSTATUS_SPIE + csrc sstatus, t0 + sret +bad8: + .word 0 + j fail + + # Make sure SRET does trap when TSR=1. + la t0, 1f + csrw sepc, t0 +bad9: + sret +1: + j fail TEST_PASSFAIL + .align 8 mtvec_handler: + j synchronous_exception + j msip + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + j fail + +synchronous_exception: li t1, CAUSE_ILLEGAL_INSTRUCTION csrr t0, mcause bne t0, t1, fail csrr t0, mepc + la t1, bad2 + beq t0, t1, 2f + la t1, bad3 + beq t0, t1, 3f + la t1, bad4 + beq t0, t1, 4f + la t1, bad5 + beq t0, t1, 5f + la t1, bad6 + beq t0, t1, 6f + la t1, bad7 + beq t0, t1, 7f + la t1, bad8 + beq t0, t1, 8f + la t1, bad9 + beq t0, t1, 9f + j fail +2: +4: +6: +7: addi t0, t0, 8 csrw mepc, t0 mret +3: + li t1, MSTATUS_TW + csrs mstatus, t1 + j 2b + +5: + li t1, MSTATUS_TVM + csrs mstatus, t1 + j 2b + +8: + li t1, MSTATUS_TSR + csrs mstatus, t1 + j 2b + +9: + j 2b + RVTEST_CODE_END .data diff --git a/isa/rv64mi/ipi.S b/isa/rv64mi/ipi.S deleted file mode 100644 index 7178310..0000000 --- a/isa/rv64mi/ipi.S +++ /dev/null @@ -1,49 +0,0 @@ -# See LICENSE for license details. - -#***************************************************************************** -# ipi.S -#----------------------------------------------------------------------------- -# -# Test interprocessor interrupts. -# - -#include "riscv_test.h" -#include "test_macros.h" - -RVTEST_RV64M -RVTEST_CODE_BEGIN - - # enable interrupts - csrs mstatus, MSTATUS_MIE - csrs mie, MIP_MSIP - - # get a unique core id - la a0, coreid - li a1, 1 - amoadd.w a2, a1, (a0) - - # for now, only run this on core 0 - 1:li a3, 1 - bgeu a2, a3, 1b - - # send a self-IPI - csrwi mipi, 1 - 1: j 1b - -mtvec_handler: - bnez a2, fail - RVTEST_PASS - - TEST_PASSFAIL - -RVTEST_CODE_END - - .data -RVTEST_DATA_BEGIN - - TEST_DATA - -coreid: .word 0 -foo: .word 0 - -RVTEST_DATA_END diff --git a/isa/rv64mi/ma_addr.S b/isa/rv64mi/ma_addr.S index be3572f..1e5ab68 100644 --- a/isa/rv64mi/ma_addr.S +++ b/isa/rv64mi/ma_addr.S @@ -20,47 +20,73 @@ RVTEST_CODE_BEGIN # indicate it's a load test li s1, CAUSE_MISALIGNED_LOAD -#define MISALIGNED_LDST_TEST(testnum, insn, base, offset) \ - li TESTNUM, testnum; \ - insn x0, offset(base); \ - j fail \ +#define SEXT(x, n) ((-((x) >> ((n)-1)) << (n)) | ((x) & ((1 << (n))-1))) - MISALIGNED_LDST_TEST(2, lh, s0, 1) - MISALIGNED_LDST_TEST(3, lhu, s0, 1) - MISALIGNED_LDST_TEST(4, lw, s0, 1) - MISALIGNED_LDST_TEST(5, lw, s0, 2) - MISALIGNED_LDST_TEST(6, lw, s0, 3) +/* Check that a misaligned load either writes the correct value, or + takes an exception and performs no writeback. */ +#define MISALIGNED_LOAD_TEST(testnum, insn, base, offset, res) \ + li TESTNUM, testnum; \ + la t2, 1f; \ + addi t1, base, offset; \ + insn t1, offset(base); \ + li t2, res; \ + bne t1, t2, fail; \ +1: + + MISALIGNED_LOAD_TEST(2, lh, s0, 1, SEXT(0xbbcc, 16)) + MISALIGNED_LOAD_TEST(3, lhu, s0, 1, 0xbbcc) + MISALIGNED_LOAD_TEST(4, lw, s0, 1, SEXT(0x99aabbcc, 32)) + MISALIGNED_LOAD_TEST(5, lw, s0, 2, SEXT(0x8899aabb, 32)) + MISALIGNED_LOAD_TEST(6, lw, s0, 3, SEXT(0x778899aa, 32)) #if __riscv_xlen == 64 - MISALIGNED_LDST_TEST(7, lwu, s0, 1) - MISALIGNED_LDST_TEST(8, lwu, s0, 2) - MISALIGNED_LDST_TEST(9, lwu, s0, 3) - - MISALIGNED_LDST_TEST(10, ld, s0, 1) - MISALIGNED_LDST_TEST(11, ld, s0, 2) - MISALIGNED_LDST_TEST(12, ld, s0, 3) - MISALIGNED_LDST_TEST(13, ld, s0, 4) - MISALIGNED_LDST_TEST(14, ld, s0, 5) - MISALIGNED_LDST_TEST(15, ld, s0, 6) - MISALIGNED_LDST_TEST(16, ld, s0, 7) + MISALIGNED_LOAD_TEST(7, lwu, s0, 1, 0x99aabbcc) + MISALIGNED_LOAD_TEST(8, lwu, s0, 2, 0x8899aabb) + MISALIGNED_LOAD_TEST(9, lwu, s0, 3, 0x778899aa) + + MISALIGNED_LOAD_TEST(10, ld, s0, 1, 0x5566778899aabbcc) + MISALIGNED_LOAD_TEST(11, ld, s0, 2, 0x445566778899aabb) + MISALIGNED_LOAD_TEST(12, ld, s0, 3, 0x33445566778899aa) + MISALIGNED_LOAD_TEST(13, ld, s0, 4, 0x2233445566778899) + MISALIGNED_LOAD_TEST(14, ld, s0, 5, 0x1122334455667788) + MISALIGNED_LOAD_TEST(15, ld, s0, 6, 0xee11223344556677) + MISALIGNED_LOAD_TEST(16, ld, s0, 7, 0xffee112233445566) #endif # indicate it's a store test li s1, CAUSE_MISALIGNED_STORE - MISALIGNED_LDST_TEST(22, sh, s0, 1) - MISALIGNED_LDST_TEST(23, sw, s0, 1) - MISALIGNED_LDST_TEST(24, sw, s0, 2) - MISALIGNED_LDST_TEST(25, sw, s0, 3) +/* Check that a misaligned store has some effect and takes no exception, + or takes no effect and generates an exception. This is not very + thorough. */ +#define MISALIGNED_STORE_TEST(testnum, insn, base, offset, size) \ + li TESTNUM, testnum; \ + la t2, 1f; \ + addi t1, base, offset; \ + insn x0, offset(base); \ + lb t1, (offset - 1)(base); \ + beqz t1, fail; \ + lb t1, (offset + size)(base); \ + beqz t1, fail; \ + lb t1, (offset + 0)(base); \ + bnez t1, fail; \ + lb t1, (offset + size - 1)(base); \ + bnez t1, fail; \ +1: + + MISALIGNED_STORE_TEST(22, sh, s0, 1, 2) + MISALIGNED_STORE_TEST(23, sw, s0, 5, 4) + MISALIGNED_STORE_TEST(24, sw, s0, 10, 4) + MISALIGNED_STORE_TEST(25, sw, s0, 15, 4) #if __riscv_xlen == 64 - MISALIGNED_LDST_TEST(26, sd, s0, 1) - MISALIGNED_LDST_TEST(27, sd, s0, 2) - MISALIGNED_LDST_TEST(28, sd, s0, 3) - MISALIGNED_LDST_TEST(29, sd, s0, 4) - MISALIGNED_LDST_TEST(30, sd, s0, 5) - MISALIGNED_LDST_TEST(31, sd, s0, 6) - MISALIGNED_LDST_TEST(32, sd, s0, 7) + MISALIGNED_STORE_TEST(26, sd, s0, 25, 8) + MISALIGNED_STORE_TEST(27, sd, s0, 34, 8) + MISALIGNED_STORE_TEST(28, sd, s0, 43, 8) + MISALIGNED_STORE_TEST(29, sd, s0, 52, 8) + MISALIGNED_STORE_TEST(30, sd, s0, 61, 8) + MISALIGNED_STORE_TEST(31, sd, s0, 70, 8) + MISALIGNED_STORE_TEST(32, sd, s0, 79, 8) #endif TEST_PASSFAIL @@ -70,9 +96,13 @@ mtvec_handler: csrr t0, mcause bne t0, s1, fail - csrr t0, mepc - addi t0, t0, 8 - csrw mepc, t0 + csrr t0, mbadaddr + bne t0, t1, fail + + lb t0, (t0) + beqz t0, fail + + csrw mepc, t2 mret RVTEST_CODE_END @@ -81,7 +111,13 @@ RVTEST_CODE_END RVTEST_DATA_BEGIN data: - .dword 0 + .align 3 +.word 0xaabbccdd +.word 0x66778899 +.word 0x22334455 +.word 0xeeffee11 +.fill 0xff, 1, 80 + TEST_DATA diff --git a/isa/rv64si/dirty.S b/isa/rv64si/dirty.S index 0314cf5..17aa57f 100644 --- a/isa/rv64si/dirty.S +++ b/isa/rv64si/dirty.S @@ -13,37 +13,45 @@ RVTEST_RV64M RVTEST_CODE_BEGIN - # Turn on VM with superpage identity mapping + # Turn on VM + li a0, (SPTBR_MODE & ~(SPTBR_MODE<<1)) * SPTBR_MODE_SV39 la a1, page_table_1 srl a1, a1, RISCV_PGSHIFT - la a2, page_table_2 - srl a2, a2, RISCV_PGSHIFT + or a1, a1, a0 csrw sptbr, a1 - sfence.vm - li a1, ((MSTATUS_VM & ~(MSTATUS_VM<<1)) * VM_SV39) | ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) + sfence.vma + + # Set up MPRV with MPP=S, so loads and stores use S-mode + li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV csrs mstatus, a1 - la a1, 1f - DRAM_BASE - csrw mepc, a1 - la a1, stvec_handler - DRAM_BASE - csrw stvec, a1 - mret -1: # Try a faulting store to make sure dirty bit is not set li TESTNUM, 2 - li t0, 1 - sw t0, dummy, t1 + li t2, 1 + sw t2, dummy - DRAM_BASE, t1 - # Load new page table + # Set SUM=1 so user memory access is permitted li TESTNUM, 3 - csrw sptbr, a2 - sfence.vm + li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_SUM + csrs mstatus, a1 + + # Make sure SUM=1 works + lw t0, dummy - DRAM_BASE + bnez t0, die # Try a non-faulting store to make sure dirty bit is set - sw t0, dummy, t1 + sw t2, dummy - DRAM_BASE, t1 + + # Make sure it succeeded + lw t0, dummy - DRAM_BASE + bne t0, t2, die - # Make sure R and D bits are set - lw t0, page_table_2 + # Leave MPRV + li t0, MSTATUS_MPRV + csrc mstatus, t0 + + # Make sure D bit is set + lw t0, page_table_1 li t1, PTE_A | PTE_D and t0, t0, t1 bne t0, t1, die @@ -53,27 +61,34 @@ RVTEST_CODE_BEGIN TEST_PASSFAIL .align 2 -stvec_handler: - csrr t0, scause +mtvec_handler: + csrr t0, mcause + add t0, t0, -CAUSE_STORE_PAGE_FAULT + bnez t0, die + li t1, 2 bne TESTNUM, t1, 1f - # Make sure R bit is set - lw t0, page_table_1 - li t1, PTE_A - and t0, t0, t1 - bne t0, t1, die - # Make sure D bit is clear lw t0, page_table_1 - li t1, PTE_D - and t0, t0, t1 - beq t0, t1, die - - csrr t0, sepc + and t1, t0, PTE_D + bnez t1, die +skip: + csrr t0, mepc add t0, t0, 4 - csrw sepc, t0 - sret + csrw mepc, t0 + mret +1: + li t1, 3 + bne TESTNUM, t1, 1f + # The implementation doesn't appear to set D bits in HW. Skip the test, + # after making sure the D bit is clear. + lw t0, page_table_1 + and t1, t0, PTE_D + bnez t1, die + j pass + +1: die: RVTEST_FAIL @@ -85,9 +100,7 @@ RVTEST_DATA_BEGIN TEST_DATA .align 12 -page_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_X +page_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A dummy: .dword 0 -.align 12 -page_table_2: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_X | PTE_W RVTEST_DATA_END diff --git a/isa/rv64ud/Makefrag b/isa/rv64ud/Makefrag index 6e8be9c..9cffb5d 100644 --- a/isa/rv64ud/Makefrag +++ b/isa/rv64ud/Makefrag @@ -3,7 +3,7 @@ #----------------------------------------------------------------------- rv64ud_sc_tests = \ - fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin fsgnj \ + fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \ ldst move structural recoding \ rv64ud_p_tests = $(addprefix rv64ud-p-, $(rv64ud_sc_tests)) diff --git a/isa/rv64ud/fsgnj.S b/isa/rv64ud/fsgnj.S deleted file mode 100644 index e914777..0000000 --- a/isa/rv64ud/fsgnj.S +++ /dev/null @@ -1,44 +0,0 @@ -# See LICENSE for license details. - -#***************************************************************************** -# fsgnj.S -#----------------------------------------------------------------------------- -# -# Test fsgn{j|jn|x}.d instructions. -# - -#include "riscv_test.h" -#include "test_macros.h" - -RVTEST_RV64UF -RVTEST_CODE_BEGIN - - #------------------------------------------------------------- - # Arithmetic tests - #------------------------------------------------------------- - - TEST_FP_OP2_D( 2, fsgnj.d, 0, -6.3, 6.3, -1.0 ); - TEST_FP_OP2_D( 3, fsgnj.d, 0, 7.3, 7.3, 2.0 ); - TEST_FP_OP2_D( 4, fsgnj.d, 0, -8.3, -8.3, -3.0 ); - TEST_FP_OP2_D( 5, fsgnj.d, 0, 9.3, -9.3, 4.0 ); - - TEST_FP_OP2_D(12, fsgnjn.d, 0, 6.3, 6.3, -1.0 ); - TEST_FP_OP2_D(13, fsgnjn.d, 0, -7.3, 7.3, 2.0 ); - TEST_FP_OP2_D(14, fsgnjn.d, 0, 8.3, -8.3, -3.0 ); - TEST_FP_OP2_D(15, fsgnjn.d, 0, -9.3, -9.3, 4.0 ); - - TEST_FP_OP2_D(22, fsgnjx.d, 0, -6.3, 6.3, -1.0 ); - TEST_FP_OP2_D(23, fsgnjx.d, 0, 7.3, 7.3, 2.0 ); - TEST_FP_OP2_D(24, fsgnjx.d, 0, 8.3, -8.3, -3.0 ); - TEST_FP_OP2_D(25, fsgnjx.d, 0, -9.3, -9.3, 4.0 ); - - TEST_PASSFAIL - -RVTEST_CODE_END - - .data -RVTEST_DATA_BEGIN - - TEST_DATA - -RVTEST_DATA_END diff --git a/isa/rv64ud/ldst.S b/isa/rv64ud/ldst.S index 59084e3..9629341 100644 --- a/isa/rv64ud/ldst.S +++ b/isa/rv64ud/ldst.S @@ -13,8 +13,12 @@ RVTEST_RV64UF RVTEST_CODE_BEGIN - TEST_CASE(2, a0, 0x40000000bf800000, la a1, tdat; fld f2, 0(a1); fsd f2, 16(a1); ld a0, 16(a1)) - TEST_CASE(3, a0, 0xc080000040400000, la a1, tdat; fld f2, 8(a1); fsd f2, 16(a1); ld a0, 16(a1)) + la s0, tdat + TEST_CASE(2, a0, 0x40000000bf800000, fld f2, 0(s0); fsd f2, 16(s0); ld a0, 16(s0)) + TEST_CASE(3, a0, 0x40000000bf800000, fld f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0)) + TEST_CASE(4, a0, 0x40000000bf800000, flw f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0)) + TEST_CASE(5, a0, 0xc080000040400000, fld f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0)) + TEST_CASE(6, a0, 0xffffffff40400000, flw f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0)) TEST_PASSFAIL diff --git a/isa/rv64ud/move.S b/isa/rv64ud/move.S index 806d4de..ccc41b5 100644 --- a/isa/rv64ud/move.S +++ b/isa/rv64ud/move.S @@ -4,8 +4,7 @@ # move.S #----------------------------------------------------------------------------- # -# This test verifies that mxtf.[s,d], mftx.[s,d], fssr, frsr, -# and fsgnj[x|n].d work properly. +# This test verifies that fmv.d.x, fmv.x.d, and fsgnj[x|n].d work properly. # #include "riscv_test.h" @@ -14,15 +13,92 @@ RVTEST_RV64UF RVTEST_CODE_BEGIN -li a0, 1 -fssr a0 +#define TEST_FSGNJD(n, insn, new_sign, rs1_sign, rs2_sign) \ + TEST_CASE(n, a0, 0x123456789abcdef0 | (-(new_sign) << 63), \ + li a1, ((rs1_sign) << 63) | 0x123456789abcdef0; \ + li a2, -(rs2_sign); \ + fmv.d.x f1, a1; \ + fmv.d.x f2, a2; \ + insn f0, f1, f2; \ + fmv.x.d a0, f0) - TEST_CASE(2, a1, 1, li a0, 0x1234; fssr a1, a0) - TEST_CASE(3, a0, 0x34, frsr a0) - TEST_CASE(4, a0, 0x34, frsr a0) + TEST_FSGNJD(10, fsgnj.d, 0, 0, 0) + TEST_FSGNJD(11, fsgnj.d, 1, 0, 1) + TEST_FSGNJD(12, fsgnj.d, 0, 1, 0) + TEST_FSGNJD(13, fsgnj.d, 1, 1, 1) - TEST_CASE(5, a0, 0x3FF02468A0000000, li a1, 0x3FF02468A0000000; fmv.d.x f1, a1; fmv.x.d a0, f1) - TEST_CASE(6, a0, 0xBFF02468A0001000, li a1, 0x3FF02468A0001000; li a2, -1; fmv.d.x f1, a1; fmv.d.x f2, a2; fsgnj.d f0, f1, f2; fmv.x.d a0, f0) + TEST_FSGNJD(20, fsgnjn.d, 1, 0, 0) + TEST_FSGNJD(21, fsgnjn.d, 0, 0, 1) + TEST_FSGNJD(22, fsgnjn.d, 1, 1, 0) + TEST_FSGNJD(23, fsgnjn.d, 0, 1, 1) + + TEST_FSGNJD(30, fsgnjx.d, 0, 0, 0) + TEST_FSGNJD(31, fsgnjx.d, 1, 0, 1) + TEST_FSGNJD(32, fsgnjx.d, 1, 1, 0) + TEST_FSGNJD(33, fsgnjx.d, 0, 1, 1) + +// Test fsgnj.s in conjunction with double-precision moves +#define TEST_FSGNJS(n, rd, rs1, rs2) \ + TEST_CASE(n, a0, (rd) | (-((rd) >> 31) << 32), \ + li a1, rs1; \ + li a2, rs2; \ + fmv.d.x f1, a1; \ + fmv.d.x f2, a2; \ + fsgnj.s f0, f1, f2; \ + fmv.x.s a0, f0); \ + TEST_CASE(1##n, a0, (rd) | 0xffffffff00000000, \ + li a1, rs1; \ + li a2, rs2; \ + fmv.d.x f1, a1; \ + fmv.d.x f2, a2; \ + fsgnj.s f0, f1, f2; \ + fmv.x.d a0, f0) + + TEST_FSGNJS(40, 0x7fc00000, 0x7ffffffe12345678, 0) + TEST_FSGNJS(41, 0x7fc00000, 0xfffffffe12345678, 0) + TEST_FSGNJS(42, 0x7fc00000, 0x7fffffff12345678, 0) + TEST_FSGNJS(43, 0x12345678, 0xffffffff12345678, 0) + + TEST_FSGNJS(50, 0x7fc00000, 0x7ffffffe12345678, 0x80000000) + TEST_FSGNJS(51, 0x7fc00000, 0xfffffffe12345678, 0x80000000) + TEST_FSGNJS(52, 0x7fc00000, 0x7fffffff12345678, 0x80000000) + TEST_FSGNJS(53, 0x12345678, 0xffffffff12345678, 0x80000000) + + TEST_FSGNJS(60, 0xffc00000, 0x7ffffffe12345678, 0xffffffff80000000) + TEST_FSGNJS(61, 0xffc00000, 0xfffffffe12345678, 0xffffffff80000000) + TEST_FSGNJS(62, 0x92345678, 0xffffffff12345678, 0xffffffff80000000) + TEST_FSGNJS(63, 0x12345678, 0xffffffff12345678, 0x7fffffff80000000) + +// Test fsgnj.d in conjunction with single-precision moves +#define TEST_FSGNJD_SP(n, isnan, rd, rs1, rs2) \ + TEST_CASE(n, a0, ((rd) & 0xffffffff) | (-(((rd) >> 31) & 1) << 32), \ + li a1, rs1; \ + li a2, rs2; \ + fmv.d.x f1, a1; \ + fmv.d.x f2, a2; \ + fsgnj.d f0, f1, f2; \ + feq.s a0, f0, f0; \ + addi a0, a0, -!(isnan); \ + bnez a0, 1f; \ + fmv.x.s a0, f0; \ + 1:); \ + TEST_CASE(1##n, a0, rd, \ + li a1, rs1; \ + li a2, rs2; \ + fmv.d.x f1, a1; \ + fmv.d.x f2, a2; \ + fsgnj.d f0, f1, f2; \ + fmv.x.d a0, f0; \ + 1:) + + TEST_FSGNJD_SP(70, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff11111111) + TEST_FSGNJD_SP(71, 1, 0x7fffffff11111111, 0xffffffff11111111, 0x7fffffff11111111) + TEST_FSGNJD_SP(72, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff91111111) + TEST_FSGNJD_SP(73, 0, 0xffffffff11111111, 0xffffffff11111111, 0x8000000000000000) + TEST_FSGNJD_SP(74, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff11111111) + TEST_FSGNJD_SP(75, 1, 0x7fffffff11111111, 0x7fffffff11111111, 0x7fffffff11111111) + TEST_FSGNJD_SP(76, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff91111111) + TEST_FSGNJD_SP(77, 0, 0xffffffff11111111, 0x7fffffff11111111, 0x8000000000000000) TEST_PASSFAIL diff --git a/isa/rv64ud/structural.S b/isa/rv64ud/structural.S index 76c6691..5ecbb96 100644 --- a/isa/rv64ud/structural.S +++ b/isa/rv64ud/structural.S @@ -30,8 +30,8 @@ li x1, 0x3F800000 nops ;\ fsgnj.s f3, f1, f1 ;\ fmv.x.d x4, f4 ;\ - fmv.x.s x3, f3 ;\ - beq x1, x3, 2f ;\ + fmv.x.s x5, f3 ;\ + beq x1, x5, 2f ;\ RVTEST_FAIL ;\ 2:beq x2, x4, 2f ;\ RVTEST_FAIL; \ diff --git a/isa/rv64uf/Makefrag b/isa/rv64uf/Makefrag index d3c3f23..33c11db 100644 --- a/isa/rv64uf/Makefrag +++ b/isa/rv64uf/Makefrag @@ -3,7 +3,7 @@ #----------------------------------------------------------------------- rv64uf_sc_tests = \ - fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin fsgnj \ + fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \ ldst move recoding \ rv64uf_p_tests = $(addprefix rv64uf-p-, $(rv64uf_sc_tests)) diff --git a/isa/rv64uf/fsgnj.S b/isa/rv64uf/fsgnj.S deleted file mode 100644 index 6d4bdb4..0000000 --- a/isa/rv64uf/fsgnj.S +++ /dev/null @@ -1,44 +0,0 @@ -# See LICENSE for license details. - -#***************************************************************************** -# fsgnj.S -#----------------------------------------------------------------------------- -# -# Test fsgn{j|jn|x}.s instructions. -# - -#include "riscv_test.h" -#include "test_macros.h" - -RVTEST_RV64UF -RVTEST_CODE_BEGIN - - #------------------------------------------------------------- - # Arithmetic tests - #------------------------------------------------------------- - - TEST_FP_OP2_S( 2, fsgnj.s, 0, -6.3, 6.3, -1.0 ); - TEST_FP_OP2_S( 3, fsgnj.s, 0, 7.3, 7.3, 2.0 ); - TEST_FP_OP2_S( 4, fsgnj.s, 0, -8.3, -8.3, -3.0 ); - TEST_FP_OP2_S( 5, fsgnj.s, 0, 9.3, -9.3, 4.0 ); - - TEST_FP_OP2_S(12, fsgnjn.s, 0, 6.3, 6.3, -1.0 ); - TEST_FP_OP2_S(13, fsgnjn.s, 0, -7.3, 7.3, 2.0 ); - TEST_FP_OP2_S(14, fsgnjn.s, 0, 8.3, -8.3, -3.0 ); - TEST_FP_OP2_S(15, fsgnjn.s, 0, -9.3, -9.3, 4.0 ); - - TEST_FP_OP2_S(22, fsgnjx.s, 0, -6.3, 6.3, -1.0 ); - TEST_FP_OP2_S(23, fsgnjx.s, 0, 7.3, 7.3, 2.0 ); - TEST_FP_OP2_S(24, fsgnjx.s, 0, 8.3, -8.3, -3.0 ); - TEST_FP_OP2_S(25, fsgnjx.s, 0, -9.3, -9.3, 4.0 ); - - TEST_PASSFAIL - -RVTEST_CODE_END - - .data -RVTEST_DATA_BEGIN - - TEST_DATA - -RVTEST_DATA_END diff --git a/isa/rv64uf/move.S b/isa/rv64uf/move.S index a94af55..60f7cf3 100644 --- a/isa/rv64uf/move.S +++ b/isa/rv64uf/move.S @@ -4,8 +4,8 @@ # move.S #----------------------------------------------------------------------------- # -# This test verifies that mxtf.[s,d], mftx.[s,d], fssr, frsr, -# and fsgnj[x|n].s work properly. +# This test verifies that the fmv.s.x, fmv.x.s, and fsgnj[x|n].d instructions +# and the fcsr work properly. # #include "riscv_test.h" @@ -14,18 +14,37 @@ RVTEST_RV64UF RVTEST_CODE_BEGIN -li a0, 1 -fssr a0 - - TEST_CASE(2, a1, 1, li a0, 0x1234; fssr a1, a0) + TEST_CASE(2, a1, 1, csrwi fcsr, 1; li a0, 0x1234; fssr a1, a0) TEST_CASE(3, a0, 0x34, frsr a0) - TEST_CASE(4, a0, 0x34, frsr a0) - - TEST_CASE(5, a0, 0xFFFFFFFFBF812345, li a1, 0xFFFFFFFFBF812345; fmv.s.x f0, a1; fmv.x.s a0, f0) - - TEST_CASE(6, a0, 0xFFFFFFFFBF812345, li a1, 0xFFFFFFFFBF812345; fmv.s.x f0, a1; fsgnj.s f1, f0, f0; fmv.x.s a0, f1) - TEST_CASE(7, a0, 0x000000004BA98765, li a1, 0xFFFFFFFFCBA98765; fmv.s.x f0, a1; fsgnjx.s f1, f0, f0; fmv.x.s a0, f1) - TEST_CASE(8, a0, 0x000000005EADBEEF, li a1, 0xFFFFFFFFDEADBEEF; fmv.s.x f0, a1; fsgnjn.s f1, f0, f0; fmv.x.s a0, f1) + TEST_CASE(4, a0, 0x14, frflags a0) + TEST_CASE(5, a0, 0x01, csrrwi a0, frm, 2) + TEST_CASE(6, a0, 0x54, frsr a0) + TEST_CASE(7, a0, 0x14, csrrci a0, fflags, 4) + TEST_CASE(8, a0, 0x50, frsr a0) + +#define TEST_FSGNJS(n, insn, new_sign, rs1_sign, rs2_sign) \ + TEST_CASE(n, a0, 0x12345678 | (-(new_sign) << 31), \ + li a1, ((rs1_sign) << 31) | 0x12345678; \ + li a2, -(rs2_sign); \ + fmv.s.x f1, a1; \ + fmv.s.x f2, a2; \ + insn f0, f1, f2; \ + fmv.x.s a0, f0) + + TEST_FSGNJS(10, fsgnj.s, 0, 0, 0) + TEST_FSGNJS(11, fsgnj.s, 1, 0, 1) + TEST_FSGNJS(12, fsgnj.s, 0, 1, 0) + TEST_FSGNJS(13, fsgnj.s, 1, 1, 1) + + TEST_FSGNJS(20, fsgnjn.s, 1, 0, 0) + TEST_FSGNJS(21, fsgnjn.s, 0, 0, 1) + TEST_FSGNJS(22, fsgnjn.s, 1, 1, 0) + TEST_FSGNJS(23, fsgnjn.s, 0, 1, 1) + + TEST_FSGNJS(30, fsgnjx.s, 0, 0, 0) + TEST_FSGNJS(31, fsgnjx.s, 1, 0, 1) + TEST_FSGNJS(32, fsgnjx.s, 1, 1, 0) + TEST_FSGNJS(33, fsgnjx.s, 0, 1, 1) TEST_PASSFAIL diff --git a/isa/rv64ui/jal.S b/isa/rv64ui/jal.S index f7f299d..00c65d8 100644 --- a/isa/rv64ui/jal.S +++ b/isa/rv64ui/jal.S @@ -21,7 +21,7 @@ test_2: li TESTNUM, 2 li ra, 0 - jal x3, target_2 + jal x4, target_2 linkaddr_2: nop nop @@ -30,7 +30,7 @@ linkaddr_2: target_2: la x2, linkaddr_2 - bne x2, x3, fail + bne x2, x4, fail #------------------------------------------------------------- # Test delay slot instructions not executed nor bypassed diff --git a/isa/rv64ui/lb.S b/isa/rv64ui/lb.S index 277b03e..856dfe9 100644 --- a/isa/rv64ui/lb.S +++ b/isa/rv64ui/lb.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0xffffffffffffffff, \ + TEST_CASE( 10, x5, 0xffffffffffffffff, \ la x1, tdat; \ addi x1, x1, -32; \ - lb x3, 32(x1); \ + lb x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x0000000000000000, \ + TEST_CASE( 11, x5, 0x0000000000000000, \ la x1, tdat; \ addi x1, x1, -6; \ - lb x3, 7(x1); \ + lb x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lb x2, 0(x3); \ + la x5, tdat; \ + lb x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lb x2, 0(x3); \ + la x5, tdat; \ + lb x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/lbu.S b/isa/rv64ui/lbu.S index 5f4c2fe..adc3a05 100644 --- a/isa/rv64ui/lbu.S +++ b/isa/rv64ui/lbu.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x00000000000000ff, \ + TEST_CASE( 10, x5, 0x00000000000000ff, \ la x1, tdat; \ addi x1, x1, -32; \ - lbu x3, 32(x1); \ + lbu x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x0000000000000000, \ + TEST_CASE( 11, x5, 0x0000000000000000, \ la x1, tdat; \ addi x1, x1, -6; \ - lbu x3, 7(x1); \ + lbu x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lbu x2, 0(x3); \ + la x5, tdat; \ + lbu x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lbu x2, 0(x3); \ + la x5, tdat; \ + lbu x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/ld.S b/isa/rv64ui/ld.S index 62fe4e5..948c34b 100644 --- a/isa/rv64ui/ld.S +++ b/isa/rv64ui/ld.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x00ff00ff00ff00ff, \ + TEST_CASE( 10, x5, 0x00ff00ff00ff00ff, \ la x1, tdat; \ addi x1, x1, -32; \ - ld x3, 32(x1); \ + ld x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0xff00ff00ff00ff00, \ + TEST_CASE( 11, x5, 0xff00ff00ff00ff00, \ la x1, tdat; \ addi x1, x1, -3; \ - ld x3, 11(x1); \ + ld x5, 11(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - ld x2, 0(x3); \ + la x5, tdat; \ + ld x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - ld x2, 0(x3); \ + la x5, tdat; \ + ld x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/lh.S b/isa/rv64ui/lh.S index decacda..338ed69 100644 --- a/isa/rv64ui/lh.S +++ b/isa/rv64ui/lh.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x00000000000000ff, \ + TEST_CASE( 10, x5, 0x00000000000000ff, \ la x1, tdat; \ addi x1, x1, -32; \ - lh x3, 32(x1); \ + lh x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0xffffffffffffff00, \ + TEST_CASE( 11, x5, 0xffffffffffffff00, \ la x1, tdat; \ addi x1, x1, -5; \ - lh x3, 7(x1); \ + lh x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lh x2, 0(x3); \ + la x5, tdat; \ + lh x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lh x2, 0(x3); \ + la x5, tdat; \ + lh x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/lhu.S b/isa/rv64ui/lhu.S index 5a55724..a4cc49b 100644 --- a/isa/rv64ui/lhu.S +++ b/isa/rv64ui/lhu.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x00000000000000ff, \ + TEST_CASE( 10, x5, 0x00000000000000ff, \ la x1, tdat; \ addi x1, x1, -32; \ - lhu x3, 32(x1); \ + lhu x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x000000000000ff00, \ + TEST_CASE( 11, x5, 0x000000000000ff00, \ la x1, tdat; \ addi x1, x1, -5; \ - lhu x3, 7(x1); \ + lhu x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lhu x2, 0(x3); \ + la x5, tdat; \ + lhu x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lhu x2, 0(x3); \ + la x5, tdat; \ + lhu x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/lw.S b/isa/rv64ui/lw.S index 02a12c0..40a73f1 100644 --- a/isa/rv64ui/lw.S +++ b/isa/rv64ui/lw.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x0000000000ff00ff, \ + TEST_CASE( 10, x5, 0x0000000000ff00ff, \ la x1, tdat; \ addi x1, x1, -32; \ - lw x3, 32(x1); \ + lw x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0xffffffffff00ff00, \ + TEST_CASE( 11, x5, 0xffffffffff00ff00, \ la x1, tdat; \ addi x1, x1, -3; \ - lw x3, 7(x1); \ + lw x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lw x2, 0(x3); \ + la x5, tdat; \ + lw x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lw x2, 0(x3); \ + la x5, tdat; \ + lw x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/lwu.S b/isa/rv64ui/lwu.S index 1ca17b1..9f7cf67 100644 --- a/isa/rv64ui/lwu.S +++ b/isa/rv64ui/lwu.S @@ -31,18 +31,18 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x0000000000ff00ff, \ + TEST_CASE( 10, x5, 0x0000000000ff00ff, \ la x1, tdat; \ addi x1, x1, -32; \ - lwu x3, 32(x1); \ + lwu x5, 32(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x00000000ff00ff00, \ + TEST_CASE( 11, x5, 0x00000000ff00ff00, \ la x1, tdat; \ addi x1, x1, -3; \ - lwu x3, 7(x1); \ + lwu x5, 7(x1); \ ) #------------------------------------------------------------- @@ -62,14 +62,14 @@ RVTEST_CODE_BEGIN #------------------------------------------------------------- TEST_CASE( 18, x2, 2, \ - la x3, tdat; \ - lwu x2, 0(x3); \ + la x5, tdat; \ + lwu x2, 0(x5); \ li x2, 2; \ ) TEST_CASE( 19, x2, 2, \ - la x3, tdat; \ - lwu x2, 0(x3); \ + la x5, tdat; \ + lwu x2, 0(x5); \ nop; \ li x2, 2; \ ) diff --git a/isa/rv64ui/sb.S b/isa/rv64ui/sb.S index 17ab2e2..19e32d6 100644 --- a/isa/rv64ui/sb.S +++ b/isa/rv64ui/sb.S @@ -31,23 +31,23 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x78, \ + TEST_CASE( 10, x5, 0x78, \ la x1, tdat9; \ li x2, 0x12345678; \ addi x4, x1, -32; \ sb x2, 32(x4); \ - lb x3, 0(x1); \ + lb x5, 0(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0xffffffffffffff98, \ + TEST_CASE( 11, x5, 0xffffffffffffff98, \ la x1, tdat9; \ li x2, 0x00003098; \ addi x1, x1, -6; \ sb x2, 7(x1); \ la x4, tdat10; \ - lb x3, 0(x4); \ + lb x5, 0(x4); \ ) #------------------------------------------------------------- diff --git a/isa/rv64ui/sd.S b/isa/rv64ui/sd.S index f9d83b7..b6fd66d 100644 --- a/isa/rv64ui/sd.S +++ b/isa/rv64ui/sd.S @@ -31,23 +31,23 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x1234567812345678, \ + TEST_CASE( 10, x5, 0x1234567812345678, \ la x1, tdat9; \ li x2, 0x1234567812345678; \ addi x4, x1, -32; \ sd x2, 32(x4); \ - ld x3, 0(x1); \ + ld x5, 0(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x5821309858213098, \ + TEST_CASE( 11, x5, 0x5821309858213098, \ la x1, tdat9; \ li x2, 0x5821309858213098; \ addi x1, x1, -3; \ sd x2, 11(x1); \ la x4, tdat10; \ - ld x3, 0(x4); \ + ld x5, 0(x4); \ ) #------------------------------------------------------------- diff --git a/isa/rv64ui/sh.S b/isa/rv64ui/sh.S index 10897d4..ea9eb23 100644 --- a/isa/rv64ui/sh.S +++ b/isa/rv64ui/sh.S @@ -31,23 +31,23 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x5678, \ + TEST_CASE( 10, x5, 0x5678, \ la x1, tdat9; \ li x2, 0x12345678; \ addi x4, x1, -32; \ sh x2, 32(x4); \ - lh x3, 0(x1); \ + lh x5, 0(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x3098, \ + TEST_CASE( 11, x5, 0x3098, \ la x1, tdat9; \ li x2, 0x00003098; \ addi x1, x1, -5; \ sh x2, 7(x1); \ la x4, tdat10; \ - lh x3, 0(x4); \ + lh x5, 0(x4); \ ) #------------------------------------------------------------- diff --git a/isa/rv64ui/sw.S b/isa/rv64ui/sw.S index 86b62fc..ab094b3 100644 --- a/isa/rv64ui/sw.S +++ b/isa/rv64ui/sw.S @@ -31,23 +31,23 @@ RVTEST_CODE_BEGIN # Test with a negative base - TEST_CASE( 10, x3, 0x12345678, \ + TEST_CASE( 10, x5, 0x12345678, \ la x1, tdat9; \ li x2, 0x12345678; \ addi x4, x1, -32; \ sw x2, 32(x4); \ - lw x3, 0(x1); \ + lw x5, 0(x1); \ ) # Test with unaligned base - TEST_CASE( 11, x3, 0x58213098, \ + TEST_CASE( 11, x5, 0x58213098, \ la x1, tdat9; \ li x2, 0x58213098; \ addi x1, x1, -3; \ sw x2, 7(x1); \ la x4, tdat10; \ - lw x3, 0(x4); \ + lw x5, 0(x4); \ ) #-------------------------------------------------------------