tests: Removed test-progs/asmtest

The insttests source is now found in gem5-resources:
https://gem5.googlesource.com/public/gem5-resources/+/refs/heads/master/src/asmtest

The pre-compiled binaries are pulled from dist.gem5.org.

There is no reason to keep these here. They are therefore being
removed.

Change-Id: Ic7869677278248f77b2703497ae7fc808d8f767a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33142
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Bobby R. Bruce
2020-08-20 13:46:54 -07:00
parent 29409425e9
commit 89f078fc79
172 changed files with 0 additions and 14555 deletions

View File

@@ -1,24 +0,0 @@
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Regents nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

View File

@@ -1,89 +0,0 @@
#=======================================================================
# Makefile for riscv-tests/isa
#-----------------------------------------------------------------------
XLEN ?= 64
src_dir := ./isa
bin_dir := ../../bin/riscv
dump_dir := ../../dump/riscv
include $(src_dir)/rv64ui/Makefrag
include $(src_dir)/rv64uc/Makefrag
include $(src_dir)/rv64um/Makefrag
include $(src_dir)/rv64ua/Makefrag
include $(src_dir)/rv64uf/Makefrag
include $(src_dir)/rv64ud/Makefrag
include $(src_dir)/rv64si/Makefrag
include $(src_dir)/rv64mi/Makefrag
include $(src_dir)/rv64uamt/Makefrag
include $(src_dir)/rv64samt/Makefrag
default: all
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM ?= spike
vpath %.S $(src_dir)
#------------------------------------------------------------
# Build assembly tests
%.dump: %
mkdir -p $(dump_dir)
$(RISCV_OBJDUMP) $(bin_dir)/$< > $(dump_dir)/$@
%.out: %
$(RISCV_SIM) --isa=rv64gc $< 2> $@
define compile_template
$$($(1)_ps_tests): $(1)-ps-%: $(1)/%.S
mkdir -p $(bin_dir)
$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(src_dir)/../env/ps -I$(src_dir)/macros/scalar -I$(src_dir)/macros/mt -T$(src_dir)/../env/ps/link.ld $$< -o $(bin_dir)/$$@
$(1)_ps_env_tests += $$($(1)_ps_tests)
$(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests))
$(1): $$($(1)_tests_dump)
.PHONY: $(1)
p_env_tests += $$($(1)_p_env_tests)
v_env_tests += $$($(1)_v_env_tests)
ps_env_tests += $$($(1)_ps_env_tests)
endef
$(eval $(call compile_template,rv64ui,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uc,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64um,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ua,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uf,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ud,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64uamt,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64samt,-march=rv64g -mabi=lp64))
ps_env_tests_dump = $(addsuffix .dump, $(ps_env_tests))
#------------------------------------------------------------
# Targets
all: ps
# build tests with ps environment
ps: $(ps_env_tests_dump)
#------------------------------------------------------------
# Clean up
clean:
rm -rf $(bin_dir) $(dump_dir)

View File

@@ -1,92 +0,0 @@
gem5 Specifc RISC-V tests
=========================
About
-----
This work provides assembly testing infrastructure including single-threaded
and multi-threaded tests for RISC-V ISA in gem5. Each test targets an
individual RISC-V instruction or a Linux system call. This work targets
system call emulation (SE) mode in gem5.
This work is based on the riscv-tests project.
Link to the orignal riscv-tests projects can be found here:
https://github.com/riscv/riscv-tests
Link to the original riscv-tests project's LICENSE and README can be found
here:
https://github.com/riscv/riscv-tests/blob/master/LICENSE
https://github.com/riscv/riscv-tests/blob/master/README.md
Specific commit ID that this work is based off:
68cad7baf3ed0a4553fffd14726d24519ee1296a
Changes from the orignal riscv-tests project
--------------------------------------------
1. Only rv64 tests are imported into this work
The original project offers both rv64 and rv32 tests. Since the current
implementation of RISC-V in gem5 is focused on its 64-bit version, only
64-bit tests (rv64) are imported from the original project. Future work
on 32-bit can easily integrate all 32-bit tests into gem5.
2. New testing environment for gem5
Since the original riscv-tests project is designed for bare-metal system (i.e.,
without OS support), it offers several environments to control how a test
interacts with a host machine (to-host communication). However, in gem5 SE
mode, gem5 emulates an OS, and there is no host machine. Therefore, we
developed a new testing environment called `ps` for gem5.
This testing environment uses system call `exit` to return test results as an
exit code of a particular test instead of writing them to a host machine. This
environment requires the testing platform to implement/emulate at least `exit`
system call.
3. Minimal threading library written in assembly (`isa/macros/mt`)
To simplify debugging multi-threading systems, we developed a minimal threading
library that supports very basic threading functionality including creating a
thread, exiting a thread, waiting for some thread(s) on a condition, and waking
up some thread(s).
Multi-threaded tests can rely on this library to manage multiple threads.
4. RISC-V AMO, LR, and SC instruction tests (`isa/rv64uamt`)
This is a set of assembly tests that target multi-core systems and test AMO
instructions. This test set uses a minimal number of system calls (i.e., clone,
mmap, munmap and exit) to create and manage threads. It does not use any
complex sleep/wakeup mechanism to manage and synchronize threads to avoid
adding extra unnecessary complexity. The major goal of this test set is to
stress AMO instructions. Threads only synchronize at the end of their
execution. The master thread does a spin-wait to wait for all threads to
complete before it checks final results.
5. Thread-related system call tests (`isa/rv64samt`)
This is a set of assembly tests that target thread-related system calls and
thread wait/wakeup behaviors. This set reuses some of the tests in
`isa/rv64uamt` but uses more advanced futex system call operations to make
threads wait and wake up in certain cases. This test set also checks functional
behaviors of threads after a wait/wakeup operation.
How to compile this test suite
------------------------------
1. Install RISC-V GNU toolchain. Source code and instruction on how to install
it can be found here: https://github.com/riscv/riscv-gnu-toolchain
2. Run `make`
3. Test binaries are in `$GEM5/tests/test-progs/asmtest/bin/riscv/` ($GEM5 is
your gem5 directory)
How to run all tests
--------------------
1. Run `./run-tests.py`
2. Test outputs are in ./test-summary.out

View File

@@ -1,24 +0,0 @@
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Regents nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +0,0 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
SECTIONS
{
. = 0x80000000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);
.tohost : { *(.tohost) }
. = ALIGN(0x1000);
.text : { *(.text) }
. = ALIGN(0x1000);
.data : { *(.data) }
.bss : { *(.bss) }
_end = .;
}

View File

@@ -1,215 +0,0 @@
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
#define _ENV_PHYSICAL_SINGLE_CORE_H
#include "../encoding.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
#define RVTEST_RV64U \
.macro init; \
.endm
#define RVTEST_RV64UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV32U \
.macro init; \
.endm
#define RVTEST_RV32UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV64M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV64S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#define RVTEST_RV32M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV32S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#if __riscv_xlen == 64
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
#else
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
#endif
#define INIT_PMP \
la t0, 1f; \
csrw mtvec, t0; \
li t0, -1; /* Set up a PMP to permit all accesses */ \
csrw pmpaddr0, t0; \
li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
csrw pmpcfg0, t0; \
.align 2; \
1:
#define INIT_SATP \
la t0, 1f; \
csrw mtvec, t0; \
csrwi sptbr, 0; \
.align 2; \
1:
#define DELEGATE_NO_TRAPS \
la t0, 1f; \
csrw mtvec, t0; \
csrwi medeleg, 0; \
csrwi mideleg, 0; \
csrwi mie, 0; \
.align 2; \
1:
#define RVTEST_ENABLE_SUPERVISOR \
li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
csrs mstatus, a0; \
li a0, SIP_SSIP | SIP_STIP; \
csrs mideleg, a0; \
#define RVTEST_ENABLE_MACHINE \
li a0, MSTATUS_MPP; \
csrs mstatus, a0; \
#define RVTEST_FP_ENABLE \
li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
csrs mstatus, a0; \
csrwi fcsr, 0
#define RISCV_MULTICORE_DISABLE \
csrr a0, mhartid; \
1: bnez a0, 1b
#define EXTRA_TVEC_USER
#define EXTRA_TVEC_MACHINE
#define EXTRA_INIT
#define EXTRA_INIT_TIMER
#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
#define RVTEST_CODE_BEGIN \
.section .text.init; \
.align 6; \
.weak stvec_handler; \
.weak mtvec_handler; \
.globl _start; \
_start: \
/* reset vector */ \
j reset_vector; \
.align 2; \
trap_vector: \
/* test whether the test came from pass/fail */ \
csrr t5, mcause; \
li t6, CAUSE_USER_ECALL; \
beq t5, t6, write_tohost; \
li t6, CAUSE_SUPERVISOR_ECALL; \
beq t5, t6, write_tohost; \
li t6, CAUSE_MACHINE_ECALL; \
beq t5, t6, write_tohost; \
/* if an mtvec_handler is defined, jump to it */ \
la t5, mtvec_handler; \
beqz t5, 1f; \
jr t5; \
/* was it an interrupt or an exception? */ \
1: csrr t5, mcause; \
bgez t5, handle_exception; \
INTERRUPT_HANDLER; \
handle_exception: \
/* we don't know how to handle whatever the exception was */ \
other_exception: \
/* some unhandlable exception occurred */ \
1: ori TESTNUM, TESTNUM, 1337; \
write_tohost: \
sw TESTNUM, tohost, t5; \
j write_tohost; \
reset_vector: \
RISCV_MULTICORE_DISABLE; \
INIT_SATP; \
INIT_PMP; \
DELEGATE_NO_TRAPS; \
li TESTNUM, 0; \
la t0, trap_vector; \
csrw mtvec, t0; \
CHECK_XLEN; \
/* if an stvec_handler is defined, delegate exceptions to it */ \
la t0, stvec_handler; \
beqz t0, 1f; \
csrw stvec, t0; \
li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \
(1 << CAUSE_STORE_PAGE_FAULT) | \
(1 << CAUSE_FETCH_PAGE_FAULT) | \
(1 << CAUSE_MISALIGNED_FETCH) | \
(1 << CAUSE_USER_ECALL) | \
(1 << CAUSE_BREAKPOINT); \
csrw medeleg, t0; \
csrr t1, medeleg; \
bne t0, t1, other_exception; \
1: csrwi mstatus, 0; \
init; \
EXTRA_INIT; \
EXTRA_INIT_TIMER; \
la t0, 1f; \
csrw mepc, t0; \
csrr a0, mhartid; \
mret; \
1:
//-----------------------------------------------------------------------
// End Macro
//-----------------------------------------------------------------------
#define RVTEST_CODE_END \
unimp
//-----------------------------------------------------------------------
// Pass/Fail Macro
//-----------------------------------------------------------------------
#define RVTEST_PASS \
fence; \
li TESTNUM, 1; \
ecall
#define TESTNUM gp
#define RVTEST_FAIL \
fence; \
1: beqz TESTNUM, 1b; \
sll TESTNUM, TESTNUM, 1; \
or TESTNUM, TESTNUM, 1; \
ecall
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#define EXTRA_DATA
#define RVTEST_DATA_BEGIN \
EXTRA_DATA \
.pushsection .tohost,"aw",@progbits; \
.align 6; .global tohost; tohost: .dword 0; \
.align 6; .global fromhost; fromhost: .dword 0; \
.popsection; \
.align 4; .global begin_signature; begin_signature:
#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
#endif

View File

@@ -1 +0,0 @@
../p/link.ld

View File

@@ -1,11 +0,0 @@
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_MULTI_CORE_H
#define _ENV_PHYSICAL_MULTI_CORE_H
#include "../p/riscv_test.h"
#undef RISCV_MULTICORE_DISABLE
#define RISCV_MULTICORE_DISABLE
#endif

View File

@@ -1,17 +0,0 @@
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
SECTIONS
{
. = 0x80000000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);
.tohost : { *(.tohost) }
. = ALIGN(0x1000);
.text : { *(.text) }
. = ALIGN(0x1000);
.data : { *(.data) }
.bss : { *(.bss) }
_end = .;
}

View File

@@ -1,170 +0,0 @@
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
#define _ENV_PHYSICAL_SINGLE_CORE_H
#include "../encoding.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
#define RVTEST_RV64U \
.macro init; \
.endm
#define RVTEST_RV64UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV32U \
.macro init; \
.endm
#define RVTEST_RV32UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV64M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV64S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#define RVTEST_RV32M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV32S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#if __riscv_xlen == 64
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
#else
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
#endif
#define INIT_PMP \
la t0, 1f; \
csrw mtvec, t0; \
li t0, -1; /* Set up a PMP to permit all accesses */ \
csrw pmpaddr0, t0; \
li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
csrw pmpcfg0, t0; \
.align 2; \
1:
#define INIT_SATP \
la t0, 1f; \
csrw mtvec, t0; \
csrwi sptbr, 0; \
.align 2; \
1:
#define DELEGATE_NO_TRAPS \
la t0, 1f; \
csrw mtvec, t0; \
csrwi medeleg, 0; \
csrwi mideleg, 0; \
csrwi mie, 0; \
.align 2; \
1:
#define RVTEST_ENABLE_SUPERVISOR \
li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
csrs mstatus, a0; \
li a0, SIP_SSIP | SIP_STIP; \
csrs mideleg, a0; \
#define RVTEST_ENABLE_MACHINE \
li a0, MSTATUS_MPP; \
csrs mstatus, a0; \
#define RVTEST_FP_ENABLE \
li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
csrs mstatus, a0; \
csrwi fcsr, 0
#define RISCV_MULTICORE_DISABLE \
csrr a0, mhartid; \
1: bnez a0, 1b
#define EXTRA_TVEC_USER
#define EXTRA_TVEC_MACHINE
#define EXTRA_INIT
#define EXTRA_INIT_TIMER
//-----------------------------------------------------------------------
// Begin Macro
// Jump to the first test case
//-----------------------------------------------------------------------
#define RVTEST_CODE_BEGIN \
.section .text.init; \
.align 6; \
.weak stvec_handler; \
.weak mtvec_handler; \
.globl _start; \
_start: \
la t0, 1f; \
jr t0; \
.align 2; \
1:
//-----------------------------------------------------------------------
// RVTEST_CODE_END Macro
// Call exit syscall to terminate the simulation
//-----------------------------------------------------------------------
#define EXIT_SYSCALL 93
#define RVTEST_CODE_END \
li a7, EXIT_SYSCALL; \
ecall
//-----------------------------------------------------------------------
// RVTEST_PASS Macro
// Pass 0 as a return code to an EXIT ecall
//-----------------------------------------------------------------------
#define TESTNUM gp
#define RVTEST_PASS \
fence; \
li a0, 0;
//-----------------------------------------------------------------------
// RVTEST_FAIL Macro
// Pass test case number as a return code to an EXIT ecall
//-----------------------------------------------------------------------
#define TESTNUM gp
#define RVTEST_FAIL \
fence; \
mv a0, TESTNUM; \
RVTEST_CODE_END
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#define EXTRA_DATA
#define RVTEST_DATA_BEGIN \
EXTRA_DATA \
.pushsection .tohost,"aw",@progbits; \
.align 6; .global tohost; tohost: .dword 0; \
.align 6; .global fromhost; fromhost: .dword 0; \
.popsection; \
.align 4; .global begin_signature; begin_signature:
#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
#endif

View File

@@ -1 +0,0 @@
../p/link.ld

View File

@@ -1,69 +0,0 @@
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
#define _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
#include "../p/riscv_test.h"
#define TIMER_INTERVAL 2
#undef EXTRA_INIT_TIMER
#define EXTRA_INIT_TIMER \
li a0, MIP_MTIP; \
csrs mie, a0; \
csrr a0, mtime; \
addi a0, a0, TIMER_INTERVAL; \
csrw mtimecmp, a0; \
#if SSTATUS_XS != 0x18000
# error
#endif
#define XS_SHIFT 15
#undef INTERRUPT_HANDLER
#define INTERRUPT_HANDLER \
slli t5, t5, 1; \
srli t5, t5, 1; \
add t5, t5, -IRQ_M_TIMER; \
bnez t5, other_exception; /* other interrups shouldn't happen */\
csrr t5, mtime; \
addi t5, t5, TIMER_INTERVAL; \
csrw mtimecmp, t5; \
mret; \
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#undef EXTRA_DATA
#define EXTRA_DATA \
.align 3; \
regspill: \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
evac: \
.skip 32768; \
#endif

View File

@@ -1,125 +0,0 @@
#include "riscv_test.h"
#if __riscv_xlen == 64
# define STORE sd
# define LOAD ld
# define REGBYTES 8
#else
# define STORE sw
# define LOAD lw
# define REGBYTES 4
#endif
#define STACK_TOP (_end + 4096)
.section ".text.init","ax",@progbits
.globl _start
_start:
j handle_reset
/* NMI vector */
nmi_vector:
j wtf
trap_vector:
j wtf
handle_reset:
la t0, trap_vector
csrw mtvec, t0
la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
csrr t0, mhartid
slli t0, t0, 12
add sp, sp, t0
csrw mscratch, sp
la a0, userstart
j vm_boot
.globl pop_tf
pop_tf:
LOAD t0,33*REGBYTES(a0)
csrw sepc,t0
LOAD x1,1*REGBYTES(a0)
LOAD x2,2*REGBYTES(a0)
LOAD x3,3*REGBYTES(a0)
LOAD x4,4*REGBYTES(a0)
LOAD x5,5*REGBYTES(a0)
LOAD x6,6*REGBYTES(a0)
LOAD x7,7*REGBYTES(a0)
LOAD x8,8*REGBYTES(a0)
LOAD x9,9*REGBYTES(a0)
LOAD x11,11*REGBYTES(a0)
LOAD x12,12*REGBYTES(a0)
LOAD x13,13*REGBYTES(a0)
LOAD x14,14*REGBYTES(a0)
LOAD x15,15*REGBYTES(a0)
LOAD x16,16*REGBYTES(a0)
LOAD x17,17*REGBYTES(a0)
LOAD x18,18*REGBYTES(a0)
LOAD x19,19*REGBYTES(a0)
LOAD x20,20*REGBYTES(a0)
LOAD x21,21*REGBYTES(a0)
LOAD x22,22*REGBYTES(a0)
LOAD x23,23*REGBYTES(a0)
LOAD x24,24*REGBYTES(a0)
LOAD x25,25*REGBYTES(a0)
LOAD x26,26*REGBYTES(a0)
LOAD x27,27*REGBYTES(a0)
LOAD x28,28*REGBYTES(a0)
LOAD x29,29*REGBYTES(a0)
LOAD x30,30*REGBYTES(a0)
LOAD x31,31*REGBYTES(a0)
LOAD a0,10*REGBYTES(a0)
sret
.global trap_entry
trap_entry:
csrrw sp, sscratch, sp
# save gprs
STORE x1,1*REGBYTES(sp)
STORE x3,3*REGBYTES(sp)
STORE x4,4*REGBYTES(sp)
STORE x5,5*REGBYTES(sp)
STORE x6,6*REGBYTES(sp)
STORE x7,7*REGBYTES(sp)
STORE x8,8*REGBYTES(sp)
STORE x9,9*REGBYTES(sp)
STORE x10,10*REGBYTES(sp)
STORE x11,11*REGBYTES(sp)
STORE x12,12*REGBYTES(sp)
STORE x13,13*REGBYTES(sp)
STORE x14,14*REGBYTES(sp)
STORE x15,15*REGBYTES(sp)
STORE x16,16*REGBYTES(sp)
STORE x17,17*REGBYTES(sp)
STORE x18,18*REGBYTES(sp)
STORE x19,19*REGBYTES(sp)
STORE x20,20*REGBYTES(sp)
STORE x21,21*REGBYTES(sp)
STORE x22,22*REGBYTES(sp)
STORE x23,23*REGBYTES(sp)
STORE x24,24*REGBYTES(sp)
STORE x25,25*REGBYTES(sp)
STORE x26,26*REGBYTES(sp)
STORE x27,27*REGBYTES(sp)
STORE x28,28*REGBYTES(sp)
STORE x29,29*REGBYTES(sp)
STORE x30,30*REGBYTES(sp)
STORE x31,31*REGBYTES(sp)
csrrw t0,sscratch,sp
STORE t0,2*REGBYTES(sp)
# get sr, epc, badvaddr, cause
csrr t0,sstatus
STORE t0,32*REGBYTES(sp)
csrr t0,sepc
STORE t0,33*REGBYTES(sp)
csrr t0,sbadaddr
STORE t0,34*REGBYTES(sp)
csrr t0,scause
STORE t0,35*REGBYTES(sp)
move a0, sp
j handle_trap

View File

@@ -1 +0,0 @@
../p/link.ld

View File

@@ -1,71 +0,0 @@
// See LICENSE for license details.
#ifndef _ENV_VIRTUAL_SINGLE_CORE_H
#define _ENV_VIRTUAL_SINGLE_CORE_H
#include "../p/riscv_test.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
#undef RVTEST_FP_ENABLE
#define RVTEST_FP_ENABLE fssr x0
#undef RVTEST_CODE_BEGIN
#define RVTEST_CODE_BEGIN \
.text; \
.global userstart; \
userstart: \
init
//-----------------------------------------------------------------------
// Pass/Fail Macro
//-----------------------------------------------------------------------
#undef RVTEST_PASS
#define RVTEST_PASS li a0, 1; scall
#undef RVTEST_FAIL
#define RVTEST_FAIL sll a0, TESTNUM, 1; 1:beqz a0, 1b; or a0, a0, 1; scall;
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#undef RVTEST_DATA_END
#define RVTEST_DATA_END
//-----------------------------------------------------------------------
// Supervisor mode definitions and macros
//-----------------------------------------------------------------------
#define MAX_TEST_PAGES 63 // this must be the period of the LFSR below
#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << 5) | ((x) >> 1))
#define PGSHIFT 12
#define PGSIZE (1UL << PGSHIFT)
#define SIZEOF_TRAPFRAME_T ((__riscv_xlen / 8) * 36)
#ifndef __ASSEMBLER__
typedef unsigned long pte_t;
#define LEVELS (sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2)
#define PTIDXBITS (PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2))
#define VPN_BITS (PTIDXBITS * LEVELS)
#define VA_BITS (VPN_BITS + PGSHIFT)
#define PTES_PER_PT (1UL << RISCV_PGLEVEL_BITS)
#define MEGAPAGE_SIZE (PTES_PER_PT * PGSIZE)
typedef struct
{
long gpr[32];
long sr;
long epc;
long badvaddr;
long cause;
} trapframe_t;
#endif
#endif

View File

@@ -1,114 +0,0 @@
#include <string.h>
#include <stdint.h>
#include <ctype.h>
void* memcpy(void* dest, const void* src, size_t len)
{
if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
const uintptr_t* s = src;
uintptr_t *d = dest;
while (d < (uintptr_t*)(dest + len))
*d++ = *s++;
} else {
const char* s = src;
char *d = dest;
while (d < (char*)(dest + len))
*d++ = *s++;
}
return dest;
}
void* memset(void* dest, int byte, size_t len)
{
if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
uintptr_t word = byte & 0xFF;
word |= word << 8;
word |= word << 16;
word |= word << 16 << 16;
uintptr_t *d = dest;
while (d < (uintptr_t*)(dest + len))
*d++ = word;
} else {
char *d = dest;
while (d < (char*)(dest + len))
*d++ = byte;
}
return dest;
}
size_t strlen(const char *s)
{
const char *p = s;
while (*p)
p++;
return p - s;
}
int strcmp(const char* s1, const char* s2)
{
unsigned char c1, c2;
do {
c1 = *s1++;
c2 = *s2++;
} while (c1 != 0 && c1 == c2);
return c1 - c2;
}
int memcmp(const void* s1, const void* s2, size_t n)
{
if ((((uintptr_t)s1 | (uintptr_t)s2) & (sizeof(uintptr_t)-1)) == 0) {
const uintptr_t* u1 = s1;
const uintptr_t* u2 = s2;
const uintptr_t* end = u1 + (n / sizeof(uintptr_t));
while (u1 < end) {
if (*u1 != *u2)
break;
u1++;
u2++;
}
n -= (const void*)u1 - s1;
s1 = u1;
s2 = u2;
}
while (n--) {
unsigned char c1 = *(const unsigned char*)s1++;
unsigned char c2 = *(const unsigned char*)s2++;
if (c1 != c2)
return c1 - c2;
}
return 0;
}
char* strcpy(char* dest, const char* src)
{
char* d = dest;
while ((*d++ = *src++))
;
return dest;
}
long atol(const char* str)
{
long res = 0;
int sign = 0;
while (*str == ' ')
str++;
if (*str == '-' || *str == '+') {
sign = *str == '-';
str++;
}
while (*str) {
res *= 10;
res += *str++ - '0';
}
return sign ? -res : res;
}

View File

@@ -1,273 +0,0 @@
// See LICENSE for license details.
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "riscv_test.h"
void trap_entry();
void pop_tf(trapframe_t*);
volatile uint64_t tohost;
volatile uint64_t fromhost;
static void do_tohost(uint64_t tohost_value)
{
while (tohost)
fromhost = 0;
tohost = tohost_value;
}
#define pa2kva(pa) ((void*)(pa) - DRAM_BASE - MEGAPAGE_SIZE)
#define uva2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
#define flush_page(addr) asm volatile ("sfence.vma %0" : : "r" (addr) : "memory")
static uint64_t lfsr63(uint64_t x)
{
uint64_t bit = (x ^ (x >> 1)) & 1;
return (x >> 1) | (bit << 62);
}
static void cputchar(int x)
{
do_tohost(0x0101000000000000 | (unsigned char)x);
}
static void cputstring(const char* s)
{
while (*s)
cputchar(*s++);
}
static void terminate(int code)
{
do_tohost(code);
while (1);
}
void wtf()
{
terminate(841);
}
#define stringify1(x) #x
#define stringify(x) stringify1(x)
#define assert(x) do { \
if (x) break; \
cputstring("Assertion failed: " stringify(x) "\n"); \
terminate(3); \
} while(0)
#define l1pt pt[0]
#define user_l2pt pt[1]
#if __riscv_xlen == 64
# define NPT 4
#define kernel_l2pt pt[2]
# define user_l3pt pt[3]
#else
# define NPT 2
# define user_l3pt user_l2pt
#endif
pte_t pt[NPT][PTES_PER_PT] __attribute__((aligned(PGSIZE)));
typedef struct { pte_t addr; void* next; } freelist_t;
freelist_t user_mapping[MAX_TEST_PAGES];
freelist_t freelist_nodes[MAX_TEST_PAGES];
freelist_t *freelist_head, *freelist_tail;
void printhex(uint64_t x)
{
char str[17];
for (int i = 0; i < 16; i++)
{
str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
x >>= 4;
}
str[16] = 0;
cputstring(str);
}
static void evict(unsigned long addr)
{
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
addr = addr/PGSIZE*PGSIZE;
freelist_t* node = &user_mapping[addr/PGSIZE];
if (node->addr)
{
// check accessed and dirty bits
assert(user_l3pt[addr/PGSIZE] & PTE_A);
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
assert(user_l3pt[addr/PGSIZE] & PTE_D);
memcpy((void*)addr, uva2kva(addr), PGSIZE);
}
write_csr(sstatus, sstatus);
user_mapping[addr/PGSIZE].addr = 0;
if (freelist_tail == 0)
freelist_head = freelist_tail = node;
else
{
freelist_tail->next = node;
freelist_tail = node;
}
}
}
void handle_fault(uintptr_t addr, uintptr_t cause)
{
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
addr = addr/PGSIZE*PGSIZE;
if (user_l3pt[addr/PGSIZE]) {
if (!(user_l3pt[addr/PGSIZE] & PTE_A)) {
user_l3pt[addr/PGSIZE] |= PTE_A;
} else {
assert(!(user_l3pt[addr/PGSIZE] & PTE_D) && cause == CAUSE_STORE_PAGE_FAULT);
user_l3pt[addr/PGSIZE] |= PTE_D;
}
flush_page(addr);
return;
}
freelist_t* node = freelist_head;
assert(node);
freelist_head = node->next;
if (freelist_head == freelist_tail)
freelist_tail = 0;
uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
user_l3pt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
flush_page(addr);
assert(user_mapping[addr/PGSIZE].addr == 0);
user_mapping[addr/PGSIZE] = *node;
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
memcpy((void*)addr, uva2kva(addr), PGSIZE);
write_csr(sstatus, sstatus);
user_l3pt[addr/PGSIZE] = new_pte;
flush_page(addr);
__builtin___clear_cache(0,0);
}
void handle_trap(trapframe_t* tf)
{
if (tf->cause == CAUSE_USER_ECALL)
{
int n = tf->gpr[10];
for (long i = 1; i < MAX_TEST_PAGES; i++)
evict(i*PGSIZE);
terminate(n);
}
else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION)
{
assert(tf->epc % 4 == 0);
int* fssr;
asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr));
if (*(int*)tf->epc == *fssr)
terminate(1); // FP test on non-FP hardware. "succeed."
else
assert(!"illegal instruction");
tf->epc += 4;
}
else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT)
handle_fault(tf->badvaddr, tf->cause);
else
assert(!"unexpected exception");
pop_tf(tf);
}
static void coherence_torture()
{
// cause coherence misses without affecting program semantics
unsigned int random = ENTROPY;
while (1) {
uintptr_t paddr = DRAM_BASE + ((random % (2 * (MAX_TEST_PAGES + 1) * PGSIZE)) & -4);
#ifdef __riscv_atomic
if (random & 1) // perform a no-op write
asm volatile ("amoadd.w zero, zero, (%0)" :: "r"(paddr));
else // perform a read
#endif
asm volatile ("lw zero, (%0)" :: "r"(paddr));
random = lfsr63(random);
}
}
void vm_boot(uintptr_t test_addr)
{
unsigned int random = ENTROPY;
if (read_csr(mhartid) > 0)
coherence_torture();
_Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
#if (MAX_TEST_PAGES > PTES_PER_PT) || (DRAM_BASE % MEGAPAGE_SIZE) != 0
# error
#endif
// map user to lowermost megapage
l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
// map kernel to uppermost megapage
#if __riscv_xlen == 64
l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
kernel_l2pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
uintptr_t vm_choice = SATP_MODE_SV39;
#else
l1pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
uintptr_t vm_choice = SATP_MODE_SV32;
#endif
write_csr(sptbr, ((uintptr_t)l1pt >> PGSHIFT) |
(vm_choice * (SATP_MODE & ~(SATP_MODE<<1))));
// Set up PMPs if present, ignoring illegal instruction trap if not.
uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
asm volatile ("la t0, 1f\n\t"
"csrrw t0, mtvec, t0\n\t"
"csrw pmpaddr0, %1\n\t"
"csrw pmpcfg0, %0\n\t"
".align 2\n\t"
"1:"
: : "r" (pmpc), "r" (-1UL) : "t0");
// set up supervisor trap handling
write_csr(stvec, pa2kva(trap_entry));
write_csr(sscratch, pa2kva(read_csr(mscratch)));
write_csr(medeleg,
(1 << CAUSE_USER_ECALL) |
(1 << CAUSE_FETCH_PAGE_FAULT) |
(1 << CAUSE_LOAD_PAGE_FAULT) |
(1 << CAUSE_STORE_PAGE_FAULT));
// FPU on; accelerator on; allow supervisor access to user memory access
write_csr(mstatus, MSTATUS_FS | MSTATUS_XS);
write_csr(mie, 0);
random = 1 + (random % MAX_TEST_PAGES);
freelist_head = pa2kva((void*)&freelist_nodes[0]);
freelist_tail = pa2kva(&freelist_nodes[MAX_TEST_PAGES-1]);
for (long i = 0; i < MAX_TEST_PAGES; i++)
{
freelist_nodes[i].addr = DRAM_BASE + (MAX_TEST_PAGES + random)*PGSIZE;
freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
random = LFSR_NEXT(random);
}
freelist_nodes[MAX_TEST_PAGES-1].next = 0;
trapframe_t tf;
memset(&tf, 0, sizeof(tf));
tf.epc = test_addr - DRAM_BASE;
pop_tf(&tf);
}

View File

@@ -1 +0,0 @@
rv*-*

View File

@@ -1,153 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This test_macros includes necessary functions and macros to create
// and exit threads. They're used in multi-threaded assembly tests.
// This assumes the target system can concurrently support 4 different
// threads (i.e., 1 master thread and 3 child threads)
//------------------------------------------------------------------------
#ifndef __TEST_MACROS_MT_H
#define __TEST_MACROS_MT_H
#define SYSCALL_MMAP 222
#define SYSCALL_MUNMAP 215
#define SYSCALL_CLONE 220
#define STACK_SIZE (4096 * 1024)
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MMAP_PROT_FLAGS (PROT_READ | PROT_WRITE)
#define MAP_PRIVATE 0x02
#define MAP_ANONYMOUS 0x20
#define MAP_STACK 0x20000
#define MMAP_MAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK)
#define CLONE_VM 0x00000100
#define CLONE_FS 0x00000200
#define CLONE_FILES 0x00000400
#define CLONE_SIGHAND 0x00000800
#define CLONE_PARENT 0x00008000
#define CLONE_THREAD 0x00010000
#define CLONE_IO 0x80000000
#define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND\
| CLONE_PARENT | CLONE_THREAD | CLONE_IO)
#define NUM_THREADS 3
#define FAILURE 1
#define SUCCESS 0
#define HARTID 0xF14
//------------------------------------------------------------------------
// create NUM_THREADS child threads
//------------------------------------------------------------------------
_create_threads:
li t0, NUM_THREADS
mv s0, ra // save return register
1:
jal ra, _alloc_stack
addi sp, sp, -8
sd a0, (sp) // save pointer to the new stack
jal ra, _clone_thread // clone a new thread
addi t0, t0, -1
bnez t0, 1b
mv ra, s0 // restore return register
ret
_alloc_stack:
li a0, 0
li a1, STACK_SIZE
li a2, MMAP_PROT_FLAGS
li a3, MMAP_MAP_FLAGS
li a4, -1
li a5, 0
li a7, SYSCALL_MMAP
ecall
ret
_clone_thread:
li a1, STACK_SIZE
add a1, a1, a0
li a0, CLONE_FLAGS
li a7, SYSCALL_CLONE
ecall
beqz a0, _mt_test
ret
//------------------------------------------------------------------------
// wait for all child threads to exit
//------------------------------------------------------------------------
_join:
la t0, barrier
li t1, NUM_THREADS
1:
ld t2, (t0)
bne t1, t2, 1b
ret
//------------------------------------------------------------------------
// deallocate NUM_THREADS child threads
//------------------------------------------------------------------------
_delete_threads:
li t0, NUM_THREADS
mv s0, ra // save return register
1:
ld a0, (sp) // pop the new stack's pointer
addi sp, sp, 8
jal ra, _dealloc_stack
addi t0, t0, -1
bnez t0, 1b
mv ra, s0 // restore return register
ret
_dealloc_stack:
li a1, STACK_SIZE
li a7, SYSCALL_MUNMAP
ecall
ret
#define MT_DATA \
shared_var: .dword 0; \
barrier: .dword 0; \
array: .dword 0x00000000deadbeef, \
0xdeadbeefdeadbeef, \
0x12343eeaaf423451; \
#endif

View File

@@ -1,355 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This test_macros includes necessary functions and macros to create
// and exit threads. They're used in multi-threaded assembly tests.
// This assumes the target system can concurrently support 4 different
// threads (i.e., 1 master thread and 3 child threads).
//
// Threads are synchronized through futex system call (i.e., wait and
// wakeup operations).
//------------------------------------------------------------------------
#ifndef __TEST_MACROS_MT_FUTEX_H
#define __TEST_MACROS_MT_FUTEX_H
#define SYSCALL_FUTEX 98
#define SYSCALL_GETTID 178
#define SYSCALL_MUNMAP 215
#define SYSCALL_CLONE 220
#define SYSCALL_MMAP 222
#define MEM_SIZE (4096 * 1024)
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MMAP_PROT_FLAGS (PROT_READ | PROT_WRITE)
#define MAP_PRIVATE 0x02
#define MAP_ANONYMOUS 0x20
#define MAP_STACK 0x20000
#define MMAP_MAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK)
#define CLONE_VM 0x00000100
#define CLONE_FS 0x00000200
#define CLONE_FILES 0x00000400
#define CLONE_SIGHAND 0x00000800
#define CLONE_PARENT 0x00008000
#define CLONE_THREAD 0x00010000
#define CLONE_IO 0x80000000
#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
#define CLONE_SETTLS 0x00080000
#define CLONE_FLAGS (CLONE_VM | CLONE_FS | CLONE_FILES \
| CLONE_SIGHAND | CLONE_PARENT \
| CLONE_THREAD | CLONE_IO \
| CLONE_PARENT_SETTID \
| CLONE_CHILD_CLEARTID \
| CLONE_SETTLS)
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_CMP_REQUEUE 4
#define FUTEX_WAKE_OP 5
#define FUTEX_WAIT_BITSET 9
#define FUTEX_WAKE_BITSET 10
#define FUTEX_PRIVATE_FLAG 128
#define FUTEX_CLOCK_REALTIME 256
#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
#define FUTEX_OP_SET 0 /* uaddr2 = oparg; */
#define FUTEX_OP_ADD 1 /* uaddr2 += oparg; */
#define FUTEX_OP_OR 2 /* uaddr2 |= oparg; */
#define FUTEX_OP_ANDN 3 /* uaddr2 &= ~oparg; */
#define FUTEX_OP_XOR 4 /* uaddr2 ^= oparg; */
#define FUTEX_OP_ARG_SHIFT 8 /* Use (1 << oparg) as operand */
#define FUTEX_OP_CMP_EQ 0 /* if (oldval == cmparg) wake */
#define FUTEX_OP_CMP_NE 1 /* if (oldval != cmparg) wake */
#define FUTEX_OP_CMP_LT 2 /* if (oldval < cmparg) wake */
#define FUTEX_OP_CMP_LE 3 /* if (oldval <= cmparg) wake */
#define FUTEX_OP_CMP_GT 4 /* if (oldval > cmparg) wake */
#define FUTEX_OP_CMP_GE 5 /* if (oldval >= cmparg) wake */
#define FUTEX_OP(op, oparg, cmp, cmparg) \
(((op & 0xf) << 28) | \
((cmp & 0xf) << 24) | \
((oparg & 0xfff) << 12) | \
(cmparg & 0xfff))
#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
#define FAILURE 1
#define SUCCESS 0
//------------------------------------------------------------------------
// _create_threads: create a given number of threads
//
// The calling thread (a.k.a, master thread) saves information about its
// child threads in its stack in the following structure:
//
// | child_stack_ptr_0 | << fp: frame pointer
// | child_tls_ptr_0 |
// | child_thread_id_0 |
// | saved_child_thread_id_0 |
// | child_stack_ptr_1 |
// | child_tls_ptr_1 |
// | child_thread_id_1 |
// | saved_child_thread_id_1 |
// | ... | << sp: stack pointer
//
// For each child thread, we need to save the following information
// in the parent thread's stack frame:
//
// - child_stack_ptr stores the lower address of the child thread's
// stack space
//
// - child_tls_ptr stores the lower address of the child thread's
// thread local storage (TLS)
//
// - child_thread_id stores the thread ID of the child thread. This
// variable will be cleared by the child thread when it exits.
//
// - saved_child_thread_id also stores the thread ID of the child
// thread, but this variable is used only by the parent thread.
//
// This function takes the number of threads to create in a0. It
// updates n_child_threads variable to the number of successfully
// created threads.
//------------------------------------------------------------------------
_create_threads:
mv t0, a0 // get the number of threads
mv s0, ra // save return register
la t3, n_worker_threads
1:
// allocate a new stack space and save its pointer in the caller's stack
jal ra, _alloc_mem
addi sp, sp, -8
sd a0, (sp)
mv t1, a0
// allocate a new thread local storage (TLS) and save its pointer in the
// caller's stack
jal ra, _alloc_mem
addi sp, sp, -8
sd a0, (sp)
mv t2, a0
// allocate space in the caller's stack to store new thread ID
addi sp, sp, -8
// clone a new thread
li a0, CLONE_FLAGS
li s2, MEM_SIZE
add a1, t1, s2 // pointer to the high address of the new stack
mv a2, sp // ptid
mv a3, t2 // pointer to the low address of the new TLS,
// assuming TLS grows upward
mv a4, sp // ctid
li a7, SYSCALL_CLONE // clone syscall number
ecall // call clone syscall
bltz a0, 2f // syscall error
beqz a0, _mt_test // only the new thread jumps to _mt_test
// save child thread ID in the caller's stack
addi sp, sp, -8
sd a0, (sp)
// decrement the number of threads to create
addi t0, t0, -1
// increment the number of successfully created threads sofar
addi t4, zero, 1
amoadd.d zero, t4, (t3)
// check if we still need to spawn more threads
bnez t0, 1b
j 3f
2:
// handle clone syscall error by deleting the last memory frame created
// for the unsuccessfully spawned thread.
addi sp, sp, 8 // skip child_thread_id
// deallocate last allocated tls
ld a0, (sp)
jal ra, _dealloc_mem
addi sp, sp, 8
// deallocate last allocated stack
ld a0, (sp)
jal ra, _dealloc_mem
addi sp, sp, 8
3:
// finish creating threads
mv ra, s0
ret
//------------------------------------------------------------------------
// _alloc_mem: allocate a memory space with size MEM_SIZE
//
// This function returns the pointer to the newly allocated memory
// space in a0
//------------------------------------------------------------------------
_alloc_mem:
li a0, 0
li a1, MEM_SIZE
li a2, MMAP_PROT_FLAGS
li a3, MMAP_MAP_FLAGS
li a4, -1
li a5, 0
li a7, SYSCALL_MMAP
ecall
ret
//------------------------------------------------------------------------
// _delete_threads: deallocate all child threads
//
// This function assumes the following structure in the calling thread's
// stack frame
//
// | child_stack_ptr_0 | << fp: frame pointer
// | child_tls_ptr_0 |
// | child_thread_id_0 |
// | saved_child_thread_id_0 |
// | child_stack_ptr_1 |
// | child_tls_ptr_1 |
// | child_thread_id_1 |
// | saved_child_thread_id_1 |
// | ... | << sp: stack pointer
//
// This function takes the number of threads to delete in a0
//------------------------------------------------------------------------
_delete_threads:
mv t0, a0 // get the number of threads to delete
mv s0, ra // save return register
1:
addi sp, sp, 8 // skip saved_child_thread_id
addi sp, sp, 8 // skip child_thread_id
// deallocate thread's tls
ld a0, (sp)
jal ra, _dealloc_mem
addi sp, sp, 8
// deallocate thread's stack
ld a0, (sp)
jal ra, _dealloc_mem
addi sp, sp, 8
// decrement the number of threads to delete
addi t0, t0, -1
bnez t0, 1b
// finish deleting all threads
mv ra, s0 // restore return register
ret
//------------------------------------------------------------------------
// _dealloc_mem: deallocate memory space of size MEM_SIZE
//
// This function takes the pointer to the memory space in a0
//------------------------------------------------------------------------
_dealloc_mem:
li a1, MEM_SIZE
li a7, SYSCALL_MUNMAP
ecall
ret
//------------------------------------------------------------------------
// _join: wait for all child threads to exit
//
// Child threads are created with CLONE_CHILD_CLEARTID flag, so when
// they exit, they will clear the ctid/ptid variable and wake up their
// parent thread.
//
// This function assumes the following structure in the calling thread's
// stack frame
//
// | child_stack_ptr_0 | << fp: frame pointer
// | child_tls_ptr_0 |
// | child_thread_id_0 |
// | saved_child_thread_id_0 |
// | child_stack_ptr_1 |
// | child_tls_ptr_1 |
// | child_thread_id_1 |
// | saved_child_thread_id_1 |
// | ... | << sp: stack pointer
//
// This function takes a number of threads to wait in a0
//------------------------------------------------------------------------
_join:
mv t0, a0 // get the number of threads
mv s0, ra // save return register
mv s1, sp // save stack pointer
1:
// Calling futex_wait on ctidptr
ld a2, (sp) // get child thread ID from
// saved_child_thread_id
addi sp, sp, 8
mv a0, sp // futex address (child_thread_id)
li a1, FUTEX_WAIT_PRIVATE
li a7, SYSCALL_FUTEX
ecall
addi sp, sp, 8 // skip child_tls_ptr
addi sp, sp, 8 // skip child_stack_ptr
// decrement the number of threads to wait for
addi t0, t0, -1
bnez t0, 1b
// finish waiting for all threads
mv ra, s0 // restore return register
mv sp, s1 // restore stack pointer
ret
#define MT_DATA \
n_worker_threads: .dword 0; \
shared_var: .dword 0; \
barrier: .dword 0; \
array: .dword 0x00000000deadbeef, \
0xdeadbeefdeadbeef, \
0x12343eeaaf423451; \
#endif

View File

@@ -1,649 +0,0 @@
// See LICENSE for license details.
#ifndef __TEST_MACROS_SCALAR_H
#define __TEST_MACROS_SCALAR_H
#-----------------------------------------------------------------------
# Helper macros
#-----------------------------------------------------------------------
#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
#define TEST_CASE( testnum, testreg, correctval, code... ) \
test_ ## testnum: \
code; \
li x29, MASK_XLEN(correctval); \
li TESTNUM, testnum; \
bne testreg, x29, fail;
# We use a macro hack to simpify code generation for various numbers
# of bubble cycles.
#define TEST_INSERT_NOPS_0
#define TEST_INSERT_NOPS_1 nop; TEST_INSERT_NOPS_0
#define TEST_INSERT_NOPS_2 nop; TEST_INSERT_NOPS_1
#define TEST_INSERT_NOPS_3 nop; TEST_INSERT_NOPS_2
#define TEST_INSERT_NOPS_4 nop; TEST_INSERT_NOPS_3
#define TEST_INSERT_NOPS_5 nop; TEST_INSERT_NOPS_4
#define TEST_INSERT_NOPS_6 nop; TEST_INSERT_NOPS_5
#define TEST_INSERT_NOPS_7 nop; TEST_INSERT_NOPS_6
#define TEST_INSERT_NOPS_8 nop; TEST_INSERT_NOPS_7
#define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8
#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
#-----------------------------------------------------------------------
# RV64UI MACROS
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Tests for instructions with immediate operand
#-----------------------------------------------------------------------
#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \
TEST_CASE( testnum, x30, result, \
li x1, MASK_XLEN(val1); \
inst x30, x1, SEXT_IMM(imm); \
)
#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
TEST_CASE( testnum, x1, result, \
li x1, MASK_XLEN(val1); \
inst x1, x1, SEXT_IMM(imm); \
)
#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
TEST_CASE( testnum, x6, result, \
li x4, 0; \
1: li x1, MASK_XLEN(val1); \
inst x30, x1, SEXT_IMM(imm); \
TEST_INSERT_NOPS_ ## nop_cycles \
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, x30, result, \
li x4, 0; \
1: li x1, MASK_XLEN(val1); \
TEST_INSERT_NOPS_ ## nop_cycles \
inst x30, x1, SEXT_IMM(imm); \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
)
#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \
TEST_CASE( testnum, x1, result, \
inst x1, x0, SEXT_IMM(imm); \
)
#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \
TEST_CASE( testnum, x0, 0, \
li x1, MASK_XLEN(val1); \
inst x0, x1, SEXT_IMM(imm); \
)
#-----------------------------------------------------------------------
# Tests for an instruction with register operands
#-----------------------------------------------------------------------
#define TEST_R_OP( testnum, inst, result, val1 ) \
TEST_CASE( testnum, x30, result, \
li x1, val1; \
inst x30, x1; \
)
#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \
TEST_CASE( testnum, x1, result, \
li x1, val1; \
inst x1, x1; \
)
#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \
TEST_CASE( testnum, x6, result, \
li x4, 0; \
1: li x1, val1; \
inst x30, x1; \
TEST_INSERT_NOPS_ ## nop_cycles \
addi x6, x30, 0; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
)
#-----------------------------------------------------------------------
# Tests for an instruction with register-register operands
#-----------------------------------------------------------------------
#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
TEST_CASE( testnum, x30, result, \
li x1, MASK_XLEN(val1); \
li x2, MASK_XLEN(val2); \
inst x30, x1, x2; \
)
#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
TEST_CASE( testnum, x1, result, \
li x1, MASK_XLEN(val1); \
li x2, MASK_XLEN(val2); \
inst x1, x1, x2; \
)
#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
TEST_CASE( testnum, x2, result, \
li x1, MASK_XLEN(val1); \
li x2, MASK_XLEN(val2); \
inst x2, x1, x2; \
)
#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
TEST_CASE( testnum, x1, result, \
li x1, MASK_XLEN(val1); \
inst x1, x1, x1; \
)
#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
TEST_CASE( testnum, x6, result, \
li x4, 0; \
1: li x1, MASK_XLEN(val1); \
li x2, MASK_XLEN(val2); \
inst x30, x1, x2; \
TEST_INSERT_NOPS_ ## nop_cycles \
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, 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 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, 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 x30, x1, x2; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
)
#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
TEST_CASE( testnum, x2, result, \
li x1, MASK_XLEN(val); \
inst x2, x0, x1; \
)
#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
TEST_CASE( testnum, x2, result, \
li x1, MASK_XLEN(val); \
inst x2, x1, x0; \
)
#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
TEST_CASE( testnum, x1, result, \
inst x1, x0, x0; \
)
#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
TEST_CASE( testnum, x0, 0, \
li x1, MASK_XLEN(val1); \
li x2, MASK_XLEN(val2); \
inst x0, x1, x2; \
)
#-----------------------------------------------------------------------
# Test memory instructions
#-----------------------------------------------------------------------
#define TEST_LD_OP( testnum, inst, result, offset, base ) \
TEST_CASE( testnum, x30, result, \
la x1, base; \
inst x30, offset(x1); \
)
#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
TEST_CASE( testnum, x30, result, \
la x1, base; \
li x2, result; \
store_inst x2, offset(x1); \
load_inst x30, offset(x1); \
)
#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x1, base; \
inst x30, offset(x1); \
TEST_INSERT_NOPS_ ## nop_cycles \
addi x6, x30, 0; \
li x29, result; \
bne x6, x29, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b; \
#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x1, base; \
TEST_INSERT_NOPS_ ## nop_cycles \
inst x30, offset(x1); \
li x29, result; \
bne x30, x29, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: li x1, result; \
TEST_INSERT_NOPS_ ## src1_nops \
la x2, base; \
TEST_INSERT_NOPS_ ## src2_nops \
store_inst x1, offset(x2); \
load_inst x30, offset(x2); \
li x29, result; \
bne x30, x29, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x2, base; \
TEST_INSERT_NOPS_ ## src1_nops \
li x1, result; \
TEST_INSERT_NOPS_ ## src2_nops \
store_inst x1, offset(x2); \
load_inst x30, offset(x2); \
li x29, result; \
bne x30, x29, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x1, val1; \
li x2, val2; \
inst x1, x2, 2f; \
bne x0, TESTNUM, fail; \
1: bne x0, TESTNUM, 3f; \
2: inst x1, x2, 1b; \
bne x0, TESTNUM, fail; \
3:
#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x1, val1; \
li x2, val2; \
inst x1, x2, 1f; \
bne x0, TESTNUM, 2f; \
1: bne x0, TESTNUM, fail; \
2: inst x1, x2, 1b; \
3:
#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: li x1, val1; \
TEST_INSERT_NOPS_ ## src1_nops \
li x2, val2; \
TEST_INSERT_NOPS_ ## src2_nops \
inst x1, x2, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: li x2, val2; \
TEST_INSERT_NOPS_ ## src1_nops \
li x1, val1; \
TEST_INSERT_NOPS_ ## src2_nops \
inst x1, x2, fail; \
addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#-----------------------------------------------------------------------
# Test jump instructions
#-----------------------------------------------------------------------
#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x6, 2f; \
TEST_INSERT_NOPS_ ## nop_cycles \
inst x6; \
bne x0, TESTNUM, fail; \
2: addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x4, 0; \
1: la x6, 2f; \
TEST_INSERT_NOPS_ ## nop_cycles \
inst x19, x6, 0; \
bne x0, TESTNUM, fail; \
2: addi x4, x4, 1; \
li x5, 2; \
bne x4, x5, 1b \
#-----------------------------------------------------------------------
# RV64UF MACROS
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Tests floating-point instructions
#-----------------------------------------------------------------------
#define qNaNf 0f:7fc00000
#define sNaNf 0f:7f800001
#define qNaN 0d:7ff8000000000000
#define sNaN 0d:7ff0000000000001
#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
flw f0, 0(a0); \
flw f1, 4(a0); \
flw f2, 8(a0); \
lw a3, 12(a0); \
code; \
fsflags a1, x0; \
li a2, flags; \
bne a0, a3, fail; \
bne a1, a2, fail; \
.pushsection .data; \
.align 2; \
test_ ## testnum ## _data: \
.float val1; \
.float val2; \
.float val3; \
.result; \
.popsection
#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
fld f0, 0(a0); \
fld f1, 8(a0); \
fld f2, 16(a0); \
ld a3, 24(a0); \
code; \
fsflags a1, x0; \
li a2, flags; \
bne a0, a3, fail; \
bne a1, a2, fail; \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.double val1; \
.double val2; \
.double val3; \
.result; \
.popsection
// TODO: assign a separate mem location for the comparison address?
#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
fld f0, 0(a0); \
fld f1, 8(a0); \
fld f2, 16(a0); \
lw a3, 24(a0); \
lw t1, 28(a0); \
code; \
fsflags a1, x0; \
li a2, flags; \
bne a0, a3, fail; \
bne t1, t2, fail; \
bne a1, a2, fail; \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.double val1; \
.double val2; \
.double val3; \
.result; \
.popsection
#define TEST_FCVT_S_D32( testnum, result, val1 ) \
TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
#define TEST_FCVT_S_D( testnum, result, val1 ) \
TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3)
#define TEST_FCVT_D_S( testnum, result, val1 ) \
TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3)
#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
inst f3, f0; fmv.x.s a0, f3)
#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
// ^: store computation result in address from a0, load high-word into t2
#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
inst f3, f0; fmv.x.d a0, f3)
#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
inst f3, f0; fmv.x.s a0, f3)
#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
// ^: store computation result in address from a0, load high-word into t2
#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
inst f3, f0; fmv.x.d a0, f3)
#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
inst f3, f0, f1; fmv.x.s a0, f3)
#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
// ^: store computation result in address from a0, load high-word into t2
#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
inst f3, f0, f1; fmv.x.d a0, f3)
#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
inst f3, f0, f1, f2; fmv.x.s a0, f3)
#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
// ^: store computation result in address from a0, load high-word into t2
#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \
inst f3, f0, f1, f2; fmv.x.d a0, f3)
#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
inst a0, f0, rm)
#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
inst a0, f0, f1; li t2, 0)
#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
inst a0, f0, rm)
#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \
inst a0, f0, f1)
#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
inst a0, f0, f1; li t2, 0)
#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
inst a0, f0, f1)
#define TEST_FCLASS_S(testnum, correct, input) \
TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \
fclass.s a0, fa0)
#define TEST_FCLASS_D32(testnum, correct, input) \
TEST_CASE(testnum, a0, correct, \
la a0, test_ ## testnum ## _data ;\
fld fa0, 0(a0); \
fclass.d a0, fa0) \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.dword input; \
.popsection
#define TEST_FCLASS_D(testnum, correct, input) \
TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \
fclass.d a0, fa0)
#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
lw a3, 0(a0); \
li a0, val1; \
inst f0, a0; \
fsflags x0; \
fmv.x.s a0, f0; \
bne a0, a3, fail; \
.pushsection .data; \
.align 2; \
test_ ## testnum ## _data: \
.float result; \
.popsection
#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
lw a3, 0(a0); \
lw a4, 4(a0); \
li a1, val1; \
inst f0, a1; \
\
fsd f0, 0(a0); \
lw a1, 4(a0); \
lw a0, 0(a0); \
\
fsflags x0; \
bne a0, a3, fail; \
bne a1, a4, fail; \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.double result; \
.popsection
#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
la a0, test_ ## testnum ## _data ;\
ld a3, 0(a0); \
li a0, val1; \
inst f0, a0; \
fsflags x0; \
fmv.x.d a0, f0; \
bne a0, a3, fail; \
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.double result; \
.popsection
// We need some special handling here to allow 64-bit comparison in 32-bit arch
// TODO: find a better name and clean up when intended for general usage?
#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
test_ ## testnum: \
code; \
la x31, test_ ## testnum ## _data ; \
lw x29, 0(x31); \
lw x31, 4(x31); \
li TESTNUM, testnum; \
bne testreg1, x29, fail;\
bne testreg2, x31, fail;\
.pushsection .data; \
.align 3; \
test_ ## testnum ## _data: \
.dword correctval; \
.popsection
// ^ x30 is used in some other macros, to avoid issues we use x31 for upper word
#-----------------------------------------------------------------------
# Pass and fail code (assumes test num is in TESTNUM)
#-----------------------------------------------------------------------
#define TEST_PASSFAIL \
bne x0, TESTNUM, pass; \
fail: \
RVTEST_FAIL; \
pass: \
RVTEST_PASS \
#-----------------------------------------------------------------------
# Test data section
#-----------------------------------------------------------------------
#define TEST_DATA
#endif

View File

@@ -1,19 +0,0 @@
#=======================================================================
# Makefrag for rv64mi tests
#-----------------------------------------------------------------------
rv64mi_sc_tests = \
access \
breakpoint \
csr \
mcsr \
illegal \
ma_fetch \
ma_addr \
scall \
sbreak \
rv32ud_p_tests = $(addprefix rv32ud-p-, $(rv32ud_sc_tests))
#rv32ud_ps_tests = $(addprefix rv32ud-ps-, $(rv32ud_sc_tests))
spike_tests += $(rv64mi_p_tests)

View File

@@ -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 t3, 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 t3, 1f
mv t2, t3
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, t3, fail
csrr t2, mcause
bne t2, t1, fail
csrw mepc, t3
mret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,144 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# breakpoint.S
#-----------------------------------------------------------------------------
#
# Test breakpoints, if they are implemented.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64M
RVTEST_CODE_BEGIN
# Set up breakpoint to trap on M-mode fetches.
li TESTNUM, 2
# Skip tselect if hard-wired.
csrw tselect, x0
csrr a1, tselect
bne x0, a1, pass
# Make sure there's a breakpoint there.
csrr a0, tdata1
srli a0, a0, __riscv_xlen - 4
li a1, 2
bne a0, a1, pass
la a2, 1f
csrw tdata2, a2
li a0, MCONTROL_M | MCONTROL_EXECUTE
csrw tdata1, a0
# Skip if breakpoint type is unsupported.
csrr a1, tdata1
andi a1, a1, 0x7ff
bne a0, a1, 2f
.align 2
1:
# Trap handler should skip this instruction.
beqz x0, fail
# Make sure reads don't trap.
li TESTNUM, 3
lw a0, (a2)
2:
# Set up breakpoint to trap on M-mode reads.
li TESTNUM, 4
li a0, MCONTROL_M | MCONTROL_LOAD
csrw tdata1, a0
# Skip if breakpoint type is unsupported.
csrr a1, tdata1
andi a1, a1, 0x7ff
bne a0, a1, 2f
la a2, data1
csrw tdata2, a2
# Trap handler should skip this instruction.
lw a2, (a2)
beqz a2, fail
# Make sure writes don't trap.
li TESTNUM, 5
sw x0, (a2)
2:
# Set up breakpoint to trap on M-mode stores.
li TESTNUM, 6
li a0, MCONTROL_M | MCONTROL_STORE
csrw tdata1, a0
# Skip if breakpoint type is unsupported.
csrr a1, tdata1
andi a1, a1, 0x7ff
bne a0, a1, 2f
# Trap handler should skip this instruction.
sw a2, (a2)
# Make sure store didn't succeed.
li TESTNUM, 7
lw a2, (a2)
bnez a2, fail
# Try to set up a second breakpoint.
li a0, 1
csrw tselect, a0
csrr a1, tselect
bne a0, a1, pass
# Make sure there's a breakpoint there.
csrr a0, tdata1
srli a0, a0, __riscv_xlen - 4
li a1, 2
bne a0, a1, pass
li a0, MCONTROL_M | MCONTROL_LOAD
csrw tdata1, a0
la a3, data2
csrw tdata2, a3
# Make sure the second breakpoint triggers.
li TESTNUM, 8
lw a3, (a3)
beqz a3, fail
# Make sure the first breakpoint still triggers.
li TESTNUM, 10
la a2, data1
sw a2, (a2)
li TESTNUM, 11
lw a2, (a2)
bnez a2, fail
2:
TEST_PASSFAIL
.align 2
.global mtvec_handler
mtvec_handler:
# Only even-numbered tests should trap.
andi t0, TESTNUM, 1
bnez t0, fail
li t0, CAUSE_BREAKPOINT
csrr t1, mcause
bne t0, t1, fail
csrr t0, mepc
addi t0, t0, 4
csrw mepc, t0
mret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
data1: .word 0
data2: .word 0
RVTEST_DATA_END

View File

@@ -1,8 +0,0 @@
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV64M
#define __MACHINE_MODE
#include "../rv64si/csr.S"

View File

@@ -1,194 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# illegal.S
#-----------------------------------------------------------------------------
#
# Test illegal instruction trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64M
RVTEST_CODE_BEGIN
.align 2
.option norvc
li TESTNUM, 2
bad2:
.word 0
j fail
# Skip the rest of the test if S-mode is not present.
li t0, MSTATUS_MPP
csrc mstatus, t0
li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S
csrs mstatus, t1
csrr t2, mstatus
and t2, t2, t0
bne t1, t2, pass
# Test vectored interrupts if they are supported.
test_vectored_interrupts:
csrwi mip, MIP_SSIP
csrwi mie, MIP_SSIP
la t0, mtvec_handler + 1
csrrw s0, mtvec, t0
csrr t0, mtvec
andi t0, t0, 1
beqz t0, msip
csrsi mstatus, MSTATUS_MIE
1:
j 1b
msip:
csrw mtvec, s0
# Delegate supervisor software interrupts so WFI won't stall.
csrwi mideleg, MIP_SSIP
# Enter supervisor mode.
la t0, 1f
csrw mepc, t0
li t0, MSTATUS_MPP
csrc mstatus, t0
li t1, (MSTATUS_MPP & -MSTATUS_MPP) * PRV_S
csrs mstatus, t1
mret
1:
# Make sure WFI doesn't trap when TW=0.
wfi
bad3:
.word 0
j fail
bad4:
# Make sure WFI does trap when TW=1.
wfi
j fail
# Make sure SFENCE.VMA and sptbr don't trap when TVM=0.
sfence.vma
csrr t0, sptbr
bad5:
.word 0
j fail
bad6:
# Make sure SFENCE.VMA and sptbr do trap when TVM=1.
sfence.vma
j fail
bad7:
csrr t0, sptbr
j fail
# Make sure SRET doesn't trap when TSR=0.
la t0, bad8
csrw sepc, t0
li t0, SSTATUS_SPP
csrs sstatus, t0
li t0, SSTATUS_SPIE
csrc sstatus, t0
sret
bad8:
.word 0
j fail
# Make sure SRET does trap when TSR=1.
la t0, 1f
csrw sepc, t0
bad9:
sret
1:
j fail
TEST_PASSFAIL
.align 8
.global mtvec_handler
mtvec_handler:
j synchronous_exception
j msip
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
j fail
synchronous_exception:
li t1, CAUSE_ILLEGAL_INSTRUCTION
csrr t0, mcause
bne t0, t1, fail
csrr t0, mepc
# Make sure mtval contains either 0 or the instruction word.
csrr t2, mbadaddr
beqz t2, 1f
lhu t3, 0(t0)
lhu t4, 2(t0)
slli t4, t4, 16
or t3, t3, t4
bne t2, t3, fail
1:
la t1, bad2
beq t0, t1, 2f
la t1, bad3
beq t0, t1, 3f
la t1, bad4
beq t0, t1, 4f
la t1, bad5
beq t0, t1, 5f
la t1, bad6
beq t0, t1, 6f
la t1, bad7
beq t0, t1, 7f
la t1, bad8
beq t0, t1, 8f
la t1, bad9
beq t0, t1, 9f
j fail
2:
4:
6:
7:
addi t0, t0, 8
csrw mepc, t0
mret
3:
li t1, MSTATUS_TW
csrs mstatus, t1
j 2b
5:
li t1, MSTATUS_TVM
csrs mstatus, t1
j 2b
8:
li t1, MSTATUS_TSR
csrs mstatus, t1
j 2b
9:
j 2b
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,126 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# ma_addr.S
#-----------------------------------------------------------------------------
#
# Test misaligned ld/st trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64M
RVTEST_CODE_BEGIN
.align 2
.option norvc
la s0, data
# indicate it's a load test
li s1, CAUSE_MISALIGNED_LOAD
#define SEXT(x, n) ((-((x) >> ((n)-1)) << (n)) | ((x) & ((1 << (n))-1)))
/* Check that a misaligned load either writes the correct value, or
takes an exception and performs no writeback. */
#define MISALIGNED_LOAD_TEST(testnum, insn, base, offset, res) \
li TESTNUM, testnum; \
la t2, 1f; \
addi t1, base, offset; \
insn t1, offset(base); \
li t2, res; \
bne t1, t2, fail; \
1:
MISALIGNED_LOAD_TEST(2, lh, s0, 1, SEXT(0xbbcc, 16))
MISALIGNED_LOAD_TEST(3, lhu, s0, 1, 0xbbcc)
MISALIGNED_LOAD_TEST(4, lw, s0, 1, SEXT(0x99aabbcc, 32))
MISALIGNED_LOAD_TEST(5, lw, s0, 2, SEXT(0x8899aabb, 32))
MISALIGNED_LOAD_TEST(6, lw, s0, 3, SEXT(0x778899aa, 32))
#if __riscv_xlen == 64
MISALIGNED_LOAD_TEST(7, lwu, s0, 1, 0x99aabbcc)
MISALIGNED_LOAD_TEST(8, lwu, s0, 2, 0x8899aabb)
MISALIGNED_LOAD_TEST(9, lwu, s0, 3, 0x778899aa)
MISALIGNED_LOAD_TEST(10, ld, s0, 1, 0x5566778899aabbcc)
MISALIGNED_LOAD_TEST(11, ld, s0, 2, 0x445566778899aabb)
MISALIGNED_LOAD_TEST(12, ld, s0, 3, 0x33445566778899aa)
MISALIGNED_LOAD_TEST(13, ld, s0, 4, 0x2233445566778899)
MISALIGNED_LOAD_TEST(14, ld, s0, 5, 0x1122334455667788)
MISALIGNED_LOAD_TEST(15, ld, s0, 6, 0xee11223344556677)
MISALIGNED_LOAD_TEST(16, ld, s0, 7, 0xffee112233445566)
#endif
# indicate it's a store test
li s1, CAUSE_MISALIGNED_STORE
/* Check that a misaligned store has some effect and takes no exception,
or takes no effect and generates an exception. This is not very
thorough. */
#define MISALIGNED_STORE_TEST(testnum, insn, base, offset, size) \
li TESTNUM, testnum; \
la t2, 1f; \
addi t1, base, offset; \
insn x0, offset(base); \
lb t1, (offset - 1)(base); \
beqz t1, fail; \
lb t1, (offset + size)(base); \
beqz t1, fail; \
lb t1, (offset + 0)(base); \
bnez t1, fail; \
lb t1, (offset + size - 1)(base); \
bnez t1, fail; \
1:
MISALIGNED_STORE_TEST(22, sh, s0, 1, 2)
MISALIGNED_STORE_TEST(23, sw, s0, 5, 4)
MISALIGNED_STORE_TEST(24, sw, s0, 10, 4)
MISALIGNED_STORE_TEST(25, sw, s0, 15, 4)
#if __riscv_xlen == 64
MISALIGNED_STORE_TEST(26, sd, s0, 25, 8)
MISALIGNED_STORE_TEST(27, sd, s0, 34, 8)
MISALIGNED_STORE_TEST(28, sd, s0, 43, 8)
MISALIGNED_STORE_TEST(29, sd, s0, 52, 8)
MISALIGNED_STORE_TEST(30, sd, s0, 61, 8)
MISALIGNED_STORE_TEST(31, sd, s0, 70, 8)
MISALIGNED_STORE_TEST(32, sd, s0, 79, 8)
#endif
TEST_PASSFAIL
.align 3
.global mtvec_handler
mtvec_handler:
csrr t0, mcause
bne t0, s1, fail
csrr t0, mbadaddr
bne t0, t1, fail
lb t0, (t0)
beqz t0, fail
csrw mepc, t2
mret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
data:
.align 3
.word 0xaabbccdd
.word 0x66778899
.word 0x22334455
.word 0xeeffee11
.fill 0xff, 1, 80
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,8 +0,0 @@
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV64M
#define __MACHINE_MODE
#include "../rv64si/ma_fetch.S"

View File

@@ -1,45 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# mcsr.S
#-----------------------------------------------------------------------------
#
# Test various M-mode CSRs.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64M
RVTEST_CODE_BEGIN
# Check that mcpuid reports the correct XLEN
#if __riscv_xlen == 64
TEST_CASE(2, a0, 0x2, csrr a0, misa; srl a0, a0, 62)
#else
TEST_CASE(2, a0, 0x1, csrr a0, misa; srl a0, a0, 30)
#endif
# Check that mhartid reports 0
TEST_CASE(3, a0, 0x0, csrr a0, mhartid)
# Check that reading the following CSRs doesn't cause an exception
csrr a0, mimpid
csrr a0, marchid
csrr a0, mvendorid
# Check that writing hte following CSRs doesn't cause an exception
li t0, 0
csrs mtvec, t0
csrs mepc, t0
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,8 +0,0 @@
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV64M
#define __MACHINE_MODE
#include "../rv64si/sbreak.S"

View File

@@ -1,8 +0,0 @@
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV64M
#define __MACHINE_MODE
#include "../rv64si/scall.S"

View File

@@ -1,13 +0,0 @@
#=========================================================================
# Makefrag for rv64samt tests
#=========================================================================
rv64sa_mt_tests = sysclone_d \
sysfutex_d \
sysfutex1_d \
sysfutex2_d \
sysfutex3_d \
rv64samt_ps_tests = $(addprefix rv64samt-ps-, $(rv64sa_mt_tests))
spike_tests += $(rv64samt_ps_tests)

View File

@@ -1,156 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// sysclone_d tests basic functionalities of clone system call:
// - create a new thread
// - assign a new per-thread stack frame to the child thread
// - assign a new per-thread TLS to the child thread
//
// In addition to testing clone(), sysclone_d partially checks
// functionalities of futex and exit system calls that are used to
// facilitate thread exit and synchronization.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt_ecall.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define MAX_NUM_THREADS 20
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
li a0, MAX_NUM_THREADS
call _create_threads
la t6, n_worker_threads
ld a0, (t6)
beqz a0, _fail // exit if there's no worker thread
call _join
la t6, n_worker_threads
ld a0, (t6)
call _check
la t6, n_worker_threads
ld a0, (t6)
call _delete_threads
li a0, SUCCESS
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed by child threads
//------------------------------------------------------------------------
_mt_test:
// get this thread's TID
li a7, SYSCALL_GETTID
ecall
// store the TID to both stack and TLS of this thread
addi sp, sp, -8
sd a0, (sp)
sd a0, (tp)
RVTEST_CODE_END
//------------------------------------------------------------------------
// _check:
// The master thread looks into the stack and TLS of each child thread
// and check if the child thread's TID was written in both places.
//
// This function assumes the following structure in the calling thread's
// stack frame
//
// | child_stack_ptr_0 | << fp: frame pointer
// | child_tls_ptr_0 |
// | child_thread_id_0 |
// | saved_child_thread_id_0 |
// | child_stack_ptr_1 |
// | child_tls_ptr_1 |
// | child_thread_id_1 |
// | saved_child_thread_id_1 |
// | ... | << sp: stack pointer
//
// This function takes a number of threads to check in a0
//------------------------------------------------------------------------
_check:
mv t0, a0 // get the number of threads
mv s0, ra // save return register
mv s1, sp // save stack pointer
1:
ld t1, (sp) // get child_thread_saved_id
addi sp, sp, 8
ld t2, (sp) // get child_thread_id
bnez t2, _fail // this child_thread_id should have been cleared
addi sp, sp, 8
ld t3, (sp) // get child_tls_ptr
ld t3, (t3) // get the first value stored in child's TLS
bne t1, t3, _fail // child_tid should have been saved in the TLS
addi sp, sp, 8
ld t4, (sp) // get child_stack_ptr
li t5, MEM_SIZE
add t4, t4, t5 // get the high address of child's stack
ld t4, -8(t4) // get the first value stored in child's stack
bne t1, t4, _fail // child_tid should have been saved in the stack
addi sp, sp, 8
// decrement the number of threads to wait for
addi t0, t0, -1
bnez t0, 1b
// finish checking all threads
mv ra, s0 // restore return register
mv sp, s1 // restore stack pointer
ret
_fail:
li a0, FAILURE
RVTEST_CODE_END
.data
MT_DATA

View File

@@ -1,143 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// sysfutex1_d tests basic functionalities of futex system call:
// - make some threads wait on a variable
// - wake up all threads waiting on a variable
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt_ecall.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define MAX_NUM_THREADS 20
//------------------------------------------------------------------------
// Master thread creates new threads, call _master function, waits for all
// threads to complete, deallocates threads and checks result
//------------------------------------------------------------------------
li a0, MAX_NUM_THREADS
call _create_threads
la t6, n_worker_threads
ld a0, (t6)
beqz a0, _fail // exit if there's no worker thread
call _master_work
la t6, n_worker_threads
ld a0, (t6)
call _join
la t6, n_worker_threads
ld a0, (t6)
call _check
la t6, n_worker_threads
ld a0, (t6)
call _delete_threads
li a0, SUCCESS
RVTEST_CODE_END
//------------------------------------------------------------------------
// master_work function executed by the parent/master thread
//
// - wake up all threads waiting on futex_X
//------------------------------------------------------------------------
_master_work:
mv s0, ra // save return address
li t0, 0 // number of threads that have been waken
la t1, n_worker_threads
ld t1, (t1)
1:
// futex(futex_X, FUTEX_WAKE_PRIVATE, n_worker_threads)
la a0, futex_X
li a1, FUTEX_WAKE_PRIVATE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
add t0, t0, a0 // track the number of waken threads so far
// keep waking up until all threads are waken up
blt t0, t1, 1b
// restore return address and return
mv ra, s0
ret
//------------------------------------------------------------------------
// mt_test function executed by child threads
//
// Wait on futex_X
//------------------------------------------------------------------------
_mt_test:
// futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
la a0, futex_X
li a1, FUTEX_WAIT_PRIVATE
li a2, 0 // expected val of futex_X
li a7, SYSCALL_FUTEX
ecall
RVTEST_CODE_END
//------------------------------------------------------------------------
// _check:
// Each thread should do LOOP_COUNT iterations
//------------------------------------------------------------------------
_check:
ret
_fail:
li a0, FAILURE
RVTEST_CODE_END
.data
futex_X: .dword 0
futex_Y: .dword 0
count_master: .dword 0
count_child: .dword 0
MT_DATA

View File

@@ -1,210 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// sysfutex_d tests FUTEX_WAKE_OP functionalities of futex system call:
// - make a thread wait on a variable
// - atomically wake up a thread waiting on a variable and perform
// a operation on a value
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt_ecall.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define NUM_THREADS 1
#define LOOP_COUNT 1000
//------------------------------------------------------------------------
// Master thread creates new threads, call _master function, waits for all
// threads to complete, deallocates threads and checks result
//------------------------------------------------------------------------
li a0, NUM_THREADS
call _create_threads
la t6, n_worker_threads
ld a0, (t6)
beqz a0, _fail // exit if there's no worker thread
call _master_work
la t6, n_worker_threads
ld a0, (t6)
call _join
la t6, n_worker_threads
ld a0, (t6)
call _check
la t6, n_worker_threads
ld a0, (t6)
call _delete_threads
li a0, SUCCESS
RVTEST_CODE_END
//------------------------------------------------------------------------
// master_work function executed by the parent/master thread
//
// Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
// loop. Also atomically modify futex_Z during the wake-up.
//------------------------------------------------------------------------
_master_work:
mv s0, ra // save return address
li t0, LOOP_COUNT
la t1, count_master
la t3, count_Z
1:
// futex(futex_X, FUTEX_WAKE_OP, 1, val2, futex_Z, val3 )
la a0, futex_X
li a1, FUTEX_WAKE_OP
li a2, 1 // wake up at most 1 thread
li a3, 0 // should not perform the second wake up
la a4, futex_Z // add 1 to futex_Z each time
li a5, FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_LT, 0)
li a7, SYSCALL_FUTEX
ecall
// increment count_Z (should equals to futex_Z)
ld t4, (t3)
addi t4, t4, 1
sd t4, (t3)
// keep waking up until at least one thread is waken up
beqz a0, 1b
// increment count_master
ld t2, (t1)
addi t2, t2, 1
sd t2, (t1)
// futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
la a0, futex_Y
li a1, FUTEX_WAIT_PRIVATE
li a2, 0 // expected val of futex_Y
li a7, SYSCALL_FUTEX
ecall
// decrement t0
addi t0, t0, -1
bnez t0, 1b
// restore return address and return
mv ra, s0
ret
//------------------------------------------------------------------------
// mt_test function executed by child threads
//
// Wait on futex_X and then wake up threads waiting on futex_Y in a loop
//------------------------------------------------------------------------
_mt_test:
li t0, LOOP_COUNT
la t1, count_child
1:
// futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
la a0, futex_X
li a1, FUTEX_WAIT_PRIVATE
li a2, 0 // expected val of futex_X
li a7, SYSCALL_FUTEX
ecall
// increment count_child
ld t2, (t1)
addi t2, t2, 1
sd t2, (t1)
2:
// futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
la a0, futex_Y
li a1, FUTEX_WAKE_PRIVATE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
// keep waking up until at least one thread is waken up
beqz a0, 2b
// decrement t0
addi t0, t0, -1
bnez t0, 1b
RVTEST_CODE_END
//------------------------------------------------------------------------
// _check:
// Each thread should do LOOP_COUNT iterations
//------------------------------------------------------------------------
_check:
la t0, count_master
la t1, count_child
li t2, LOOP_COUNT
la t3, count_Z
la t4, futex_Z
ld t0, (t0)
bne t0, t2, _fail
ld t1, (t1)
bne t1, t2, _fail
ld t3, (t3)
ld t4, (t4)
bne t3, t4, _fail
ret
_fail:
li a0, FAILURE
RVTEST_CODE_END
.data
futex_X: .dword 0
futex_Y: .dword 0
futex_Z: .dword 0
count_master: .dword 0
count_child: .dword 0
count_Z: .dword 0
MT_DATA

View File

@@ -1,170 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// sysfutex3_d tests FUTEX_CMP_REQUEUE functionalities of futex system
// call:
// - make worker threads waiting on futex 1
// - wake up 1 thread, requeue the rest of the threads to futex 2
// - wake all threads waiting on futex 1 and futex 2
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt_ecall.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define NUM_THREADS 20
//------------------------------------------------------------------------
// Master thread creates new threads, call _master function, waits for all
// threads to complete, deallocates threads and checks result
//------------------------------------------------------------------------
li a0, NUM_THREADS
call _create_threads
la t6, n_worker_threads
ld a0, (t6)
beqz a0, _fail // exit if there's no worker thread
call _master_work
la t6, n_worker_threads
ld a0, (t6)
call _join
la t6, n_worker_threads
ld a0, (t6)
call _check
la t6, n_worker_threads
ld a0, (t6)
call _delete_threads
li a0, SUCCESS
RVTEST_CODE_END
//------------------------------------------------------------------------
// master_work function executed by the parent/master thread
//------------------------------------------------------------------------
_master_work:
mv s0, ra // save return address
li t0, 0 // number of threads that have been waken
la t1, n_worker_threads
ld t1, (t1)
1:
// futex(futex_X, FUTEX_CMP_REQUEUE, 1, INT_MAX, futex_Y, *futex_X)
la a0, futex_X
li a1, FUTEX_CMP_REQUEUE
li a2, 1 // wake up at most 1 thread
li a3, 1000 // practically is INT_MAX
la a4, futex_Y // move all other waiter to futex_Y
li a5, 0
li a7, SYSCALL_FUTEX
ecall
// loop until wake up one thread, all other waiter are requeued to
// futex_Y
beqz a0, 1b
addi t0, t0, 1
2:
// alternating between futex_X and futex_Y
// because there could be new threads added to futex_X's queue
// after our futex_requeue
// futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
la a0, futex_Y
li a1, FUTEX_WAKE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
add t0, t0, a0 // track the number of waken threads so far
// futex(futex_X, FUTEX_WAKE_PRIVATE, 0)
la a0, futex_X
li a1, FUTEX_WAKE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
add t0, t0, a0 // track the number of waken threads so far
// keep waking up until all threads are waken up
blt t0, t1, 2b
// restore return address and return
mv ra, s0
ret
//------------------------------------------------------------------------
// mt_test function executed by child threads
//
// Wait on futex_X
//------------------------------------------------------------------------
_mt_test:
// futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
la a0, futex_X
li a1, FUTEX_WAIT
li a2, 0 // expected val of futex_X
li a7, SYSCALL_FUTEX
ecall
RVTEST_CODE_END
//------------------------------------------------------------------------
// _check:
// counter should equals to number of child threads
//------------------------------------------------------------------------
_check:
ret
_fail:
li a0, FAILURE
RVTEST_CODE_END
.data
futex_X: .dword 0
futex_Y: .dword 0
MT_DATA

View File

@@ -1,191 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// sysfutex_d tests basic functionalities of futex system call:
// - make a thread wait on a variable
// - wake up a thread waiting on a variable
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt_ecall.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define NUM_THREADS 1
#define LOOP_COUNT 1000
//------------------------------------------------------------------------
// Master thread creates new threads, call _master function, waits for all
// threads to complete, deallocates threads and checks result
//------------------------------------------------------------------------
li a0, NUM_THREADS
call _create_threads
la t6, n_worker_threads
ld a0, (t6)
beqz a0, _fail // exit if there's no worker thread
call _master_work
la t6, n_worker_threads
ld a0, (t6)
call _join
la t6, n_worker_threads
ld a0, (t6)
call _check
la t6, n_worker_threads
ld a0, (t6)
call _delete_threads
li a0, SUCCESS
RVTEST_CODE_END
//------------------------------------------------------------------------
// master_work function executed by the parent/master thread
//
// Wake up thread(s) waiting on futex_X and then wait on futex_Y in a
// loop.
//------------------------------------------------------------------------
_master_work:
mv s0, ra // save return address
li t0, LOOP_COUNT
la t1, count_master
1:
// futex(futex_X, FUTEX_WAKE_PRIVATE, 1)
la a0, futex_X
li a1, FUTEX_WAKE_PRIVATE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
// keep waking up until at least one thread is waken up
beqz a0, 1b
// increment count_master
ld t2, (t1)
addi t2, t2, 1
sd t2, (t1)
// futex(futex_Y, FUTEX_WAIT_PRIVATE, 0)
la a0, futex_Y
li a1, FUTEX_WAIT_PRIVATE
li a2, 0 // expected val of futex_Y
li a7, SYSCALL_FUTEX
ecall
// decrement t0
addi t0, t0, -1
bnez t0, 1b
// restore return address and return
mv ra, s0
ret
//------------------------------------------------------------------------
// mt_test function executed by child threads
//
// Wait on futex_X and then wake up threads waiting on futex_Y in a loop
//------------------------------------------------------------------------
_mt_test:
li t0, LOOP_COUNT
la t1, count_child
1:
// futex(futex_X, FUTEX_WAIT_PRIVATE, 1)
la a0, futex_X
li a1, FUTEX_WAIT_PRIVATE
li a2, 0 // expected val of futex_X
li a7, SYSCALL_FUTEX
ecall
// increment count_child
ld t2, (t1)
addi t2, t2, 1
sd t2, (t1)
2:
// futex(futex_Y, FUTEX_WAKE_PRIVATE, 0)
la a0, futex_Y
li a1, FUTEX_WAKE_PRIVATE
li a2, 1 // wake up at most 1 thread
li a7, SYSCALL_FUTEX
ecall
// keep waking up until at least one thread is waken up
beqz a0, 2b
// decrement t0
addi t0, t0, -1
bnez t0, 1b
RVTEST_CODE_END
//------------------------------------------------------------------------
// _check:
// Each thread should do LOOP_COUNT iterations
//------------------------------------------------------------------------
_check:
la t0, count_master
la t1, count_child
li t2, LOOP_COUNT
ld t0, (t0)
bne t0, t2, _fail
ld t1, (t1)
bne t1, t2, _fail
ret
_fail:
li a0, FAILURE
RVTEST_CODE_END
.data
futex_X: .dword 0
futex_Y: .dword 0
count_master: .dword 0
count_child: .dword 0
MT_DATA

View File

@@ -1,16 +0,0 @@
#=======================================================================
# Makefrag for rv64si tests
#-----------------------------------------------------------------------
rv64si_sc_tests = \
csr \
dirty \
ma_fetch \
scall \
wfi \
sbreak \
rv64si_p_tests = $(addprefix rv64si-p-, $(rv64si_sc_tests))
#rv64si_ps_tests = $(addprefix rv64si-ps-, $(rv64si_sc_tests))
spike_tests += $(rv64si_p_tests)

View File

@@ -1,148 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# csr.S
#-----------------------------------------------------------------------------
#
# Test CSRRx and CSRRxI instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
#ifdef __MACHINE_MODE
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
#undef SSTATUS_SPP
#define SSTATUS_SPP MSTATUS_MPP
#endif
# For RV64, make sure UXL encodes RV64. (UXL does not exist for RV32.)
#if __riscv_xlen == 64
# If running in M mode, use mstatus.MPP to check existence of U mode.
# Otherwise, if in S mode, then U mode must exist and we don't need to check.
#ifdef __MACHINE_MODE
li t0, MSTATUS_MPP
csrc mstatus, t0
csrr t1, mstatus
and t0, t0, t1
bnez t0, 1f
#endif
# If U mode is present, UXL should be 2 (XLEN = 64-bit)
TEST_CASE(13, a0, SSTATUS_UXL & (SSTATUS_UXL << 1), csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
#ifdef __MACHINE_MODE
j 2f
1:
# If U mode is not present, UXL should be 0
TEST_CASE(14, a0, 0, csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
2:
#endif
#endif
csrwi sscratch, 3
TEST_CASE( 2, a0, 3, csrr a0, sscratch);
TEST_CASE( 3, a1, 3, csrrci a1, sscratch, 1);
TEST_CASE( 4, a2, 2, csrrsi a2, sscratch, 4);
TEST_CASE( 5, a3, 6, csrrwi a3, sscratch, 2);
TEST_CASE( 6, a1, 2, li a0, 0xbad1dea; csrrw a1, sscratch, a0);
TEST_CASE( 7, a0, 0xbad1dea, li a0, 0x0001dea; csrrc a0, sscratch, a0);
TEST_CASE( 8, a0, 0xbad0000, li a0, 0x000beef; csrrs a0, sscratch, a0);
TEST_CASE( 9, a0, 0xbadbeef, csrr a0, sscratch);
#ifdef __MACHINE_MODE
# Is F extension present?
csrr a0, misa
andi a0, a0, (1 << ('F' - 'A'))
beqz a0, 1f
# If so, make sure FP stores have no effect when mstatus.FS is off.
li a1, MSTATUS_FS
csrs mstatus, a1
#ifdef __riscv_flen
fmv.s.x f0, x0
csrc mstatus, a1
la a1, fsw_data
TEST_CASE(10, a0, 1, fsw f0, (a1); lw a0, (a1));
#else
# Fail if this test is compiled without F but executed on a core with F.
TEST_CASE(10, zero, 1)
#endif
1:
# Figure out if 'U' is set in misa
csrr a0, misa # a0 = csr(misa)
srli a0, a0, 20 # a0 = a0 >> 20
andi a0, a0, 1 # a0 = a0 & 1
beqz a0, finish # if no user mode, skip the rest of these checks
#endif /* __MACHINE_MODE */
# jump to user land
li t0, SSTATUS_SPP
csrc sstatus, t0
la t0, 1f
csrw sepc, t0
sret
1:
# Make sure writing the cycle counter causes an exception.
# Don't run in supervisor, as we don't delegate illegal instruction traps.
#ifdef __MACHINE_MODE
TEST_CASE(11, a0, 255, li a0, 255; csrrw a0, cycle, x0);
#endif
# Make sure reading status in user mode causes an exception.
# Don't run in supervisor, as we don't delegate illegal instruction traps.
#ifdef __MACHINE_MODE
TEST_CASE(12, a0, 255, li a0, 255; csrr a0, sstatus)
#else
TEST_CASE(12, x0, 0, nop)
#endif
finish:
RVTEST_PASS
# We should only fall through to this if scall failed.
TEST_PASSFAIL
.align 2
.global stvec_handler
stvec_handler:
# Trapping on tests 10-12 is good news.
# Note that since the test didn't complete, TESTNUM is smaller by 1.
li t0, 9
bltu TESTNUM, t0, 1f
li t0, 11
bleu TESTNUM, t0, privileged
1:
# catch RVTEST_PASS and kick it up to M-mode
csrr t0, scause
li t1, CAUSE_USER_ECALL
bne t0, t1, fail
RVTEST_PASS
privileged:
# Make sure scause indicates a lack of privilege.
csrr t0, scause
li t1, CAUSE_ILLEGAL_INSTRUCTION
bne t0, t1, fail
# Return to user mode, but skip the trapping instruction.
csrr t0, sepc
addi t0, t0, 4
csrw sepc, t0
sret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
fsw_data: .word 1
RVTEST_DATA_END

View File

@@ -1,129 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# dirty.S
#-----------------------------------------------------------------------------
#
# Test VM referenced and dirty bits.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64M
RVTEST_CODE_BEGIN
# Turn on VM
li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
la a1, page_table_1
srl a1, a1, RISCV_PGSHIFT
or a1, a1, a0
csrw sptbr, a1
sfence.vma
# Set up MPRV with MPP=S, so loads and stores use S-mode
li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV
csrs mstatus, a1
# Try a faulting store to make sure dirty bit is not set
li TESTNUM, 2
li t2, 1
sw t2, dummy - DRAM_BASE, a0
# Set SUM=1 so user memory access is permitted
li TESTNUM, 3
li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_SUM
csrs mstatus, a1
# Make sure SUM=1 works
lw t0, dummy - DRAM_BASE
bnez t0, die
# Try a non-faulting store to make sure dirty bit is set
sw t2, dummy - DRAM_BASE, a0
# Make sure it succeeded
lw t0, dummy - DRAM_BASE
bne t0, t2, die
# Leave MPRV
li t0, MSTATUS_MPRV
csrc mstatus, t0
# Make sure D bit is set
lw t0, page_table_1
li a0, PTE_A | PTE_D
and t0, t0, a0
bne t0, a0, die
# Enter MPRV again
li t0, MSTATUS_MPRV
csrs mstatus, t0
# Make sure that superpage entries trap when PPN LSBs are set.
li TESTNUM, 4
lw a0, page_table_1 - DRAM_BASE
or a0, a0, 1 << PTE_PPN_SHIFT
sw a0, page_table_1 - DRAM_BASE, t0
sfence.vma
sw a0, page_table_1 - DRAM_BASE, t0
j die
RVTEST_PASS
TEST_PASSFAIL
.align 2
.global mtvec_handler
mtvec_handler:
csrr t0, mcause
add t0, t0, -CAUSE_STORE_PAGE_FAULT
bnez t0, die
li t1, 2
bne TESTNUM, t1, 1f
# Make sure D bit is clear
lw t0, page_table_1
and t1, t0, PTE_D
bnez t1, die
skip:
csrr t0, mepc
add t0, t0, 4
csrw mepc, t0
mret
1:
li t1, 3
bne TESTNUM, t1, 1f
# The implementation doesn't appear to set D bits in HW.
# Make sure the D bit really is clear.
lw t0, page_table_1
and t1, t0, PTE_D
bnez t1, die
# Set the D bit.
or t0, t0, PTE_D
sw t0, page_table_1, t1
sfence.vma
mret
1:
li t1, 4
bne TESTNUM, t1, 1f
j pass
1:
die:
RVTEST_FAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
.align 12
page_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A
dummy: .dword 0
RVTEST_DATA_END

View File

@@ -1,159 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# ma_fetch.S
#-----------------------------------------------------------------------------
#
# Test misaligned fetch trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
#ifdef __MACHINE_MODE
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
#define sbadaddr mbadaddr
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
#endif
.align 2
.option norvc
# Without RVC, the jalr should trap, and the handler will skip ahead.
# With RVC, the jalr should not trap, and "j fail" should get skipped.
li TESTNUM, 2
li t1, 0
la t0, 1f
jalr t1, t0, 2
1:
.option rvc
c.j 1f
c.j 2f
.option norvc
1:
j fail
2:
// This test should pass, since JALR ignores the target LSB
li TESTNUM, 3
la t0, 1f
jalr t1, t0, 1
1:
j 1f
j fail
1:
li TESTNUM, 4
li t1, 0
la t0, 1f
jalr t1, t0, 3
1:
.option rvc
c.j 1f
c.j 2f
.option norvc
1:
j fail
2:
# Like test 2, but with jal instead of jalr.
li TESTNUM, 5
li t1, 0
la t0, 1f
jal t1, 2f
1:
.option rvc
c.j 1f
2:
c.j 2f
.option norvc
1:
j fail
2:
# Like test 2, but with a taken branch instead of jalr.
li TESTNUM, 6
li t1, 0
la t0, 1f
beqz x0, 2f
1:
.option rvc
c.j 1f
2:
c.j 2f
.option norvc
1:
j fail
2:
# Not-taken branches should not trap, even without RVC.
li TESTNUM, 7
bnez x0, 1f
j 2f
.option rvc
c.j 1f
1:
c.j 1f
.option norvc
1:
j fail
2:
j pass
TEST_PASSFAIL
.align 2
.global stvec_handler
stvec_handler:
# tests 2, 4, 5, and 6 should trap
li a0, 2
beq TESTNUM, a0, 1f
li a0, 4
beq TESTNUM, a0, 1f
li a0, 5
beq TESTNUM, a0, 1f
li a0, 6
beq TESTNUM, a0, 1f
j fail
1:
# verify that return address was not written
bnez t1, fail
# verify trap cause
li a1, CAUSE_MISALIGNED_FETCH
csrr a0, scause
bne a0, a1, fail
# verify that epc == &jalr (== t0 - 4)
csrr a1, sepc
addi a1, a1, 4
bne t0, a1, fail
# verify that badaddr == 0 or badaddr == t0+2.
csrr a0, sbadaddr
beqz a0, 1f
addi a0, a0, -2
bne a0, t0, fail
1:
addi a1, a1, 12
csrw sepc, a1
sret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,51 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# scall.S
#-----------------------------------------------------------------------------
#
# Test syscall trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
#ifdef __MACHINE_MODE
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
#endif
li TESTNUM, 2
do_break:
sbreak
j fail
TEST_PASSFAIL
.align 2
.global stvec_handler
stvec_handler:
li t1, CAUSE_BREAKPOINT
csrr t0, scause
bne t0, t1, fail
la t1, do_break
csrr t0, sepc
bne t0, t1, fail
j pass
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,77 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# scall.S
#-----------------------------------------------------------------------------
#
# Test syscall trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
#ifdef __MACHINE_MODE
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
#undef SSTATUS_SPP
#define SSTATUS_SPP MSTATUS_MPP
#endif
li TESTNUM, 2
# This is the expected trap code.
li t1, CAUSE_USER_ECALL
#ifdef __MACHINE_MODE
# If running in M mode, use mstatus.MPP to check existence of U mode.
# Otherwise, if in S mode, then U mode must exist and we don't need to check.
li t0, MSTATUS_MPP
csrc mstatus, t0
csrr t1, mstatus
and t0, t0, t1
beqz t0, 1f
# If U mode doesn't exist, mcause should indicate ECALL from M mode.
li t1, CAUSE_MACHINE_ECALL
#endif
1:
li t0, SSTATUS_SPP
csrc sstatus, t0
la t0, 1f
csrw sepc, t0
sret
1:
li TESTNUM, 1
do_scall:
scall
j fail
TEST_PASSFAIL
.align 2
.global stvec_handler
stvec_handler:
csrr t0, scause
bne t0, t1, fail
la t2, do_scall
csrr t0, sepc
bne t0, t2, fail
j pass
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,33 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# wfi.S
#-----------------------------------------------------------------------------
#
# Test wait-for-interrupt instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
# Make sure wfi doesn't halt the hart, even if interrupts are disabled
csrc sstatus, SSTATUS_SIE
csrs sie, SIP_SSIP
csrs sip, SIP_SSIP
wfi
RVTEST_PASS
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,14 +0,0 @@
#=======================================================================
# Makefrag for rv64ua tests
#-----------------------------------------------------------------------
rv64ua_sc_tests = \
amoadd_d amoand_d amomax_d amomaxu_d amomin_d amominu_d amoor_d amoxor_d amoswap_d \
amoadd_w amoand_w amomax_w amomaxu_w amomin_w amominu_w amoor_w amoxor_w amoswap_w \
lrsc \
rv64ua_p_tests = $(addprefix rv64ua-p-, $(rv64ua_sc_tests))
rv64ua_v_tests = $(addprefix rv64ua-v-, $(rv64ua_sc_tests))
rv64ua_ps_tests = $(addprefix rv64ua-ps-, $(rv64ua_sc_tests))
spike_tests += $(rv64ua_p_tests) $(rv64ua_v_tests)

View File

@@ -1,47 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoadd_d.S
#-----------------------------------------------------------------------------
#
# Test amoadd.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amoadd.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff7ffff800, ld a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xffffffff7ffff800, \
amoadd.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffff7ffff000, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoadd_w.S
#-----------------------------------------------------------------------------
#
# Test amoadd.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amoadd.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0x000000007ffff800, lw a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0x000000007ffff800, \
li a1, 0xffffffff80000000; \
amoadd.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xfffffffffffff800, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoand_d.S
#-----------------------------------------------------------------------------
#
# Test amoand.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amoand.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xffffffff80000000, \
li a1, 0x0000000080000000; \
amoand.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0x0000000080000000, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoand.w.S
#-----------------------------------------------------------------------------
#
# Test amoand.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amoand.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xffffffff80000000, \
li a1, 0x0000000080000000; \
amoand.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomax_d.S
#-----------------------------------------------------------------------------
#
# Test amomax.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amomax.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 1; \
sd x0, 0(a3); \
amomax.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 1, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomax_d.S
#-----------------------------------------------------------------------------
#
# Test amomax.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amomax.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 1; \
sw x0, 0(a3); \
amomax.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 1, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomaxu_d.S
#-----------------------------------------------------------------------------
#
# Test amomaxu.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amomaxu.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sd x0, 0(a3); \
amomaxu.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffffffffffff, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomaxu_d.S
#-----------------------------------------------------------------------------
#
# Test amomaxu.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amomaxu.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sw x0, 0(a3); \
amomaxu.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomin_d.S
#-----------------------------------------------------------------------------
#
# Test amomin.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amomin.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sd x0, 0(a3); \
amomin.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffffffffffff, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amomin_d.S
#-----------------------------------------------------------------------------
#
# Test amomin.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amomin.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sw x0, 0(a3); \
amomin.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,49 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amominu_d.S
#-----------------------------------------------------------------------------
#
# Test amominu.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amominu.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, ld a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sd x0, 0(a3); \
amominu.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,49 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amominu_d.S
#-----------------------------------------------------------------------------
#
# Test amominu.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amominu.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3))
TEST_CASE(4, a4, 0, \
li a1, 0xffffffffffffffff; \
sw x0, 0(a3); \
amominu.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoor_d.S
#-----------------------------------------------------------------------------
#
# Test amoor.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amoor.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xfffffffffffff800, \
li a1, 1; \
amoor.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xfffffffffffff801, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoor.w.S
#-----------------------------------------------------------------------------
#
# Test amoor.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amoor.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xfffffffffffff800, \
li a1, 1; \
amoor.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xfffffffffffff801, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoswap.d.S
#-----------------------------------------------------------------------------
#
# Test amoswap.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amoswap.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, ld a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xfffffffffffff800, \
li a1, 0x0000000080000000; \
amoswap.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0x0000000080000000, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoswap_w.S
#-----------------------------------------------------------------------------
#
# Test amoswap.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amoswap.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0xfffffffffffff800, \
li a1, 0x0000000080000000; \
amoswap.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoxor_d.S
#-----------------------------------------------------------------------------
#
# Test amoxor.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sd a0, 0(a3); \
amoxor.d a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0x000000007ffff800, ld a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0x000000007ffff800, \
li a1, 1; \
amoxor.d a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0x000000007ffff801, ld a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,48 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoxor_w.S
#-----------------------------------------------------------------------------
#
# Test amoxor.w instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
TEST_CASE(2, a4, 0xffffffff80000000, \
li a0, 0xffffffff80000000; \
li a1, 0xfffffffffffff800; \
la a3, amo_operand; \
sw a0, 0(a3); \
amoxor.w a4, a1, 0(a3); \
)
TEST_CASE(3, a5, 0x7ffff800, lw a5, 0(a3))
# try again after a cache miss
TEST_CASE(4, a4, 0x7ffff800, \
li a1, 0xc0000001; \
amoxor.w a4, a1, 0(a3); \
)
TEST_CASE(5, a5, 0xffffffffbffff801, lw a5, 0(a3))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
.bss
.align 3
amo_operand:
.dword 0

View File

@@ -1,85 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# lrsr.S
#-----------------------------------------------------------------------------
#
# Test LR/SC instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
# get a unique core id
la a0, coreid
li a1, 1
amoadd.w a2, a1, (a0)
# for now, only run this on core 0
1:li a3, 1
bgeu a2, a3, 1b
1: lw a1, (a0)
bltu a1, a3, 1b
# make sure that sc without a reservation fails.
TEST_CASE( 2, a4, 1, \
la a0, foo; \
sc.w a4, x0, (a0); \
)
# make sure that sc with the wrong reservation fails.
# TODO is this actually mandatory behavior?
TEST_CASE( 3, a4, 1, \
la a0, foo; \
add a1, a0, 1024; \
lr.w a1, (a1); \
sc.w a4, a1, (a0); \
)
#define LOG_ITERATIONS 10
# have each core add its coreid+1 to foo 1024 times
la a0, foo
li a1, 1<<LOG_ITERATIONS
addi a2, a2, 1
1: lr.w a4, (a0)
add a4, a4, a2
sc.w a4, a4, (a0)
bnez a4, 1b
add a1, a1, -1
bnez a1, 1b
# wait for all cores to finish
la a0, barrier
li a1, 1
amoadd.w x0, a1, (a0)
1: lw a1, (a0)
blt a1, a3, 1b
fence
# expected result is 512*ncores*(ncores+1)
TEST_CASE( 4, a0, 0, \
lw a0, foo; \
slli a1, a3, LOG_ITERATIONS-1; \
1:sub a0, a0, a1; \
addi a3, a3, -1; \
bgez a3, 1b
)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
coreid: .word 0
barrier: .word 0
foo: .word 0
RVTEST_DATA_END

View File

@@ -1,25 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# amoadd_d.S
#-----------------------------------------------------------------------------
#
# Test amoadd.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
la a0, shared_var
amoadd.w t0, t1, 0(a0)
lr.w t2, 0(a0)
//sc.w t0, t1, 0(a0)
RVTEST_CODE_END
.data
shared_var: .dword 0
non_shared_var: .dword 0

View File

@@ -1,10 +0,0 @@
#=======================================================================
# Makefrag for rv64ua_mt tests
#-----------------------------------------------------------------------
rv64ua_mt_tests = amoadd_d amoswap_d amoxor_d amoand_d \
amoor_d amomin_d amomax_d amominu_d amomaxu_d lrsc_d \
rv64uamt_ps_tests = $(addprefix rv64uamt-ps-, $(rv64ua_mt_tests))
spike_tests += $(rv64uamt_ps_tests)

View File

@@ -1,102 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amoadd_d instruction in multi-threading system.
// Each thread increments a globally shared variable LOOP_COUNT times.
// Once a thread completes, it signals its completition by atomically
// incrementing a barrier variable.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define LOOP_COUNT 1000
#define RESULT LOOP_COUNT * NUM_THREADS
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
li t0, 1 // one operand of amoadd_w
li t1, LOOP_COUNT // loop count
la a0, shared_var
1:
amoadd.d zero, t0, (a0)
addi t1, t1, -1
bnez t1, 1b
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amoand_w instruction in multi-threading system.
// All threads execute an amoxor_w instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0x000000008E003441
//------------------------------------------------------------------------
// Reinitialize shared_var to 0xffffffffffffffff
//------------------------------------------------------------------------
la a0, shared_var
li t0, 0xffffffffffffffff
sd t0, (a0)
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amoand.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amomax_d instruction in multi-threading system.
// All threads execute an amomax_w instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0x12343eeaaf423451
//------------------------------------------------------------------------
// Reinitialize shared_var to 0x8000000000000000
//------------------------------------------------------------------------
la a0, shared_var
li t0, 0x8000000000000000
sd t0, (a0)
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amomax.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amomax_d instruction in multi-threading system.
// All threads execute an amomax_w instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0xdeadbeefdeadbeef
//------------------------------------------------------------------------
// Reinitialize shared_var to 0x0000000000000000
//------------------------------------------------------------------------
la a0, shared_var
li t0, 0x0000000000000000
sd t0, (a0)
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amomaxu.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amomin_d instruction in multi-threading system.
// All threads execute an amomin_d instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0xDEADBEEFDEADBEEF
//------------------------------------------------------------------------
// Reinitialize shared_var to 0x7fffffffffffffff
//------------------------------------------------------------------------
la a0, shared_var
li t0, 0x7fffffffffffffff
sd t0, (a0)
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amomin.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amominu_d instruction in multi-threading system.
// All threads execute an amominu_d instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0x00000000deadbeef
//------------------------------------------------------------------------
// Reinitialize shared_var to 0xffffffffffffffff
//------------------------------------------------------------------------
la a0, shared_var
li t0, 0xffffffffffffffff
sd t0, (a0)
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amominu.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amoor_d instruction in multi-threading system.
// All threads execute an amoor_w instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0xDEBDBEEFFFEFBEFF
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amoor.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,115 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amoswap.d instruction in multi-threading system.
// All threads execute a critical section LOOP_COUNT times. A thread
// gets into a critical section by acquiring a lock variable (i.e.,
// shared_var) and checking return value.
// 0 means the lock is not being locked. Each thread increments
// a variable (i.e., var) inside the critical section and releases the
// lock by swapping back 0 to the lock variable.
// The master thread (i.e., thread 0) waits for all threads to complete
// and compare the var's value to the expected result.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define LOOP_COUNT 1000
#define RESULT NUM_THREADS * LOOP_COUNT
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
li t0, 1 // initialize the swap value (1-locked)
li t1, LOOP_COUNT
la t2, var // load the var's address
la a0, shared_var
1:
amoswap.d.aq s2, t0, (a0) // try to swap t0 with the lock
bnez s2, 1b // retry if the lock is being held
lw t3, (t2) // load the var's value
addi t3, t3, 1 // add 1 to the value
sw t3, (t2) // store the new value to var
amoswap.d.rl zero, zero, (a0)// release the lock by swapping back 0
addi t1, t1, -1 // decrement the loop_count
bnez t1, 1b // repeat if not done yet
la a0, barrier
amoadd.d zero, t0, (a0) // signal this thread's completion
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
var: .dword 0

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests amoxor_d instruction in multi-threading system.
// All threads execute an amoxor_w instruction.
// Master thread (i.e., thread 0) waits for all threads to complete by
// spinning on the barrier variable until all threads update the variable.
// Then, the master thread checks the shared variable's value.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define RESULT 0xCC998005AF423451
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
la a0, shared_var
la t0, array_index
li t1, 8
amoadd.d t1, t1, (t0) // get my array_index
la t0, array
add t0, t0, t1
ld t0, (t0) // get array[array_index]
amoxor.d zero, t0, (a0)
li t0, 1
la a0, barrier
amoadd.d zero, t0, (a0)
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, shared_var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
array_index: .dword 0;

View File

@@ -1,117 +0,0 @@
/*
* Copyright (c) 2018, Cornell University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of Cornell University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//------------------------------------------------------------------------
// This code tests lr.d and sc.d instructions in multi-threading system.
// All threads execute a critical section LOOP_COUNT times. A thread
// gets into a critical section by acquiring a lock variable (i.e.,
// shared_var) and checking return value.
// 0 means the lock is not being locked. Each thread increments
// a variable (i.e., var) inside the critical section and releases the
// lock by swapping back 0 to the lock variable.
// The master thread (i.e., thread 0) waits for all threads to complete
// and compare the var's value to the expected result.
//------------------------------------------------------------------------
#include "riscv_test.h"
#include "test_macros.h"
#include "test_macros_mt.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#define LOOP_COUNT 1000
#define RESULT NUM_THREADS * LOOP_COUNT
//------------------------------------------------------------------------
// Master thread creates new threads, waits for all threads to complete,
// deallocates threads and checks result
//------------------------------------------------------------------------
call _create_threads
call _join
call _delete_threads
call _check
RVTEST_CODE_END
//------------------------------------------------------------------------
// mt_test function executed in child threads
// A child thread signals its completion by atomicaly adding 1 to barrier
//------------------------------------------------------------------------
_mt_test:
li t0, 1 // initialize the swap value (1-locked)
li t1, LOOP_COUNT
la t2, var // load the var's address
la a0, shared_var
1:
lr.d.aq s2, (a0) // load and reserve a0
bnez s2, 1b // retry lr if the lock is being held
sc.d.rl s2, t0, (a0) // try to lock a0
bnez s2, 1b // retry if sc failed
lw t3, (t2) // load the var's value
addi t3, t3, 1 // add 1 to the value
sw t3, (t2) // store the new value to var
sd zero, (a0) // release the lock by storing 0 to a0
addi t1, t1, -1 // decrement the loop_count
bnez t1, 1b // repeat if not done yet
la a0, barrier
amoadd.d zero, t0, (a0) // signal this thread's completion
RVTEST_CODE_END
//------------------------------------------------------------------------
// Master thread checks result
//------------------------------------------------------------------------
_check:
la a0, var
li a1, RESULT
ld a0, (a0)
bne a0, a1, _fail
li a0, SUCCESS
ret
_fail:
li a0, FAILURE
ret
.data
MT_DATA
var: .dword 0

View File

@@ -1,12 +0,0 @@
#=======================================================================
# Makefrag for rv64uc tests
#-----------------------------------------------------------------------
rv64uc_sc_tests = \
rvc \
rv64ua_p_tests = $(addprefix rv64ua-p-, $(rv64ua_sc_tests))
rv64uc_v_tests = $(addprefix rv64uc-v-, $(rv64uc_sc_tests))
rv64ua_ps_tests = $(addprefix rv64ua-ps-, $(rv64ua_sc_tests))
spike_tests += $(rv64uc_p_tests) $(rv64uc_v_tests)

View File

@@ -1,154 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# rvc.S
#-----------------------------------------------------------------------------
#
# Test RVC corner cases.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
.align 2
.option push
.option norvc
#define RVC_TEST_CASE(n, r, v, code...) \
TEST_CASE (n, r, v, .option push; .option rvc; code; .align 2; .option pop)
// Make sure fetching a 4-byte instruction across a page boundary works.
li TESTNUM, 2
li a1, 666
TEST_CASE (2, a1, 667, \
j 1f; \
.align 3; \
data: \
.dword 0xfedcba9876543210; \
.dword 0xfedcba9876543210; \
.align 12; \
.skip 4094; \
1: addi a1, a1, 1)
li sp, 0x1234
RVC_TEST_CASE (3, a0, 0x1234 + 1020, c.addi4spn a0, sp, 1020)
RVC_TEST_CASE (4, sp, 0x1234 + 496, c.addi16sp sp, 496)
RVC_TEST_CASE (5, sp, 0x1234 + 496 - 512, c.addi16sp sp, -512)
la a1, data
RVC_TEST_CASE (6, a2, 0xfffffffffedcba99, c.lw a0, 4(a1); addi a0, a0, 1; c.sw a0, 4(a1); c.lw a2, 4(a1))
#if __riscv_xlen == 64
RVC_TEST_CASE (7, a2, 0xfedcba9976543211, c.ld a0, 0(a1); addi a0, a0, 1; c.sd a0, 0(a1); c.ld a2, 0(a1))
#endif
RVC_TEST_CASE (8, a0, -15, ori a0, x0, 1; c.addi a0, -16)
RVC_TEST_CASE (9, a5, -16, ori a5, x0, 1; c.li a5, -16)
#if __riscv_xlen == 64
RVC_TEST_CASE (10, a0, 0x76543210, ld a0, (a1); c.addiw a0, -1)
#endif
RVC_TEST_CASE (11, s0, 0xffffffffffffffe1, c.lui s0, 0xfffe1; c.srai s0, 12)
#if __riscv_xlen == 64
RVC_TEST_CASE (12, s0, 0x000fffffffffffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
#else
RVC_TEST_CASE (12, s0, 0x000fffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
#endif
RVC_TEST_CASE (14, s0, ~0x11, c.li s0, -2; c.andi s0, ~0x10)
RVC_TEST_CASE (15, s1, 14, li s1, 20; li a0, 6; c.sub s1, a0)
RVC_TEST_CASE (16, s1, 18, li s1, 20; li a0, 6; c.xor s1, a0)
RVC_TEST_CASE (17, s1, 22, li s1, 20; li a0, 6; c.or s1, a0)
RVC_TEST_CASE (18, s1, 4, li s1, 20; li a0, 6; c.and s1, a0)
#if __riscv_xlen == 64
RVC_TEST_CASE (19, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, -1; c.subw s1, a0)
RVC_TEST_CASE (20, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, 1; c.addw s1, a0)
#endif
RVC_TEST_CASE (21, s0, 0x12340, li s0, 0x1234; c.slli s0, 4)
RVC_TEST_CASE (30, ra, 0, \
li ra, 0; \
c.j 1f; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:)
RVC_TEST_CASE (31, x0, 0, \
li a0, 0; \
c.beqz a0, 1f; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:)
RVC_TEST_CASE (32, x0, 0, \
li a0, 1; \
c.bnez a0, 1f; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:)
RVC_TEST_CASE (33, x0, 0, \
li a0, 1; \
c.beqz a0, 1f; \
c.j 2f; \
1:c.j fail; \
2:)
RVC_TEST_CASE (34, x0, 0, \
li a0, 0; \
c.bnez a0, 1f; \
c.j 2f; \
1:c.j fail; \
2:)
RVC_TEST_CASE (35, ra, 0, \
la t0, 1f; \
li ra, 0; \
c.jr t0; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:)
RVC_TEST_CASE (36, ra, -2, \
la t0, 1f; \
li ra, 0; \
c.jalr t0; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:sub ra, ra, t0)
#if __riscv_xlen == 32
RVC_TEST_CASE (37, ra, -2, \
la t0, 1f; \
li ra, 0; \
c.jal 1f; \
c.j 2f; \
1:c.j 1f; \
2:j fail; \
1:sub ra, ra, t0)
#endif
la sp, data
RVC_TEST_CASE (40, a2, 0xfffffffffedcba99, c.lwsp a0, 12(sp); addi a0, a0, 1; c.swsp a0, 12(sp); c.lwsp a2, 12(sp))
#if __riscv_xlen == 64
RVC_TEST_CASE (41, a2, 0xfedcba9976543211, c.ldsp a0, 8(sp); addi a0, a0, 1; c.sdsp a0, 8(sp); c.ldsp a2, 8(sp))
#endif
RVC_TEST_CASE (42, t0, 0x246, li a0, 0x123; c.mv t0, a0; c.add t0, a0)
.option pop
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
RVTEST_DATA_END

View File

@@ -1,13 +0,0 @@
#=======================================================================
# Makefrag for rv64ud tests
#-----------------------------------------------------------------------
rv64ud_sc_tests = \
fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \
ldst move structural recoding \
rv64ud_p_tests = $(addprefix rv64ud-p-, $(rv64ud_sc_tests))
rv64ud_v_tests = $(addprefix rv64ud-v-, $(rv64ud_sc_tests))
rv64ud_ps_tests = $(addprefix rv64ud-ps-, $(rv64ud_sc_tests))
spike_tests += $(rv64ud_p_tests) $(rv64ud_v_tests)

View File

@@ -1,50 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fadd.S
#-----------------------------------------------------------------------------
#
# Test f{add|sub|mul}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_FP_OP2_D
#define TEST_FP_OP2_D TEST_FP_OP2_D32
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP2_D( 2, fadd.d, 0, 3.5, 2.5, 1.0 );
TEST_FP_OP2_D( 3, fadd.d, 1, -1234, -1235.1, 1.1 );
TEST_FP_OP2_D( 4, fadd.d, 1, 3.14159266, 3.14159265, 0.00000001 );
TEST_FP_OP2_D( 5, fsub.d, 0, 1.5, 2.5, 1.0 );
TEST_FP_OP2_D( 6, fsub.d, 1, -1234, -1235.1, -1.1 );
TEST_FP_OP2_D( 7, fsub.d, 1, 3.1415926400000001, 3.14159265, 0.00000001 );
TEST_FP_OP2_D( 8, fmul.d, 0, 2.5, 2.5, 1.0 );
TEST_FP_OP2_D( 9, fmul.d, 1, 1358.61, -1235.1, -1.1 );
TEST_FP_OP2_D(10, fmul.d, 1, 3.14159265e-8, 3.14159265, 0.00000001 );
# Is the canonical NaN generated for Inf - Inf?
TEST_FP_OP2_D(11, fsub.d, 0x10, qNaN, Inf, Inf);
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,46 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fclass.S
#-----------------------------------------------------------------------------
#
# Test fclass.d instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_FCLASS_D
#define TEST_FCLASS_D TEST_FCLASS_D32
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FCLASS_D( 2, 1 << 0, 0xfff0000000000000 )
TEST_FCLASS_D( 3, 1 << 1, 0xbff0000000000000 )
TEST_FCLASS_D( 4, 1 << 2, 0x800fffffffffffff )
TEST_FCLASS_D( 5, 1 << 3, 0x8000000000000000 )
TEST_FCLASS_D( 6, 1 << 4, 0x0000000000000000 )
TEST_FCLASS_D( 7, 1 << 5, 0x000fffffffffffff )
TEST_FCLASS_D( 8, 1 << 6, 0x3ff0000000000000 )
TEST_FCLASS_D( 9, 1 << 7, 0x7ff0000000000000 )
TEST_FCLASS_D(10, 1 << 8, 0x7ff0000000000001 )
TEST_FCLASS_D(11, 1 << 9, 0x7ff8000000000000 )
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,56 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcmp.S
#-----------------------------------------------------------------------------
#
# Test f{eq|lt|le}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_FP_CMP_OP_D
#define TEST_FP_CMP_OP_D TEST_FP_CMP_OP_D32
#endif
TEST_FP_CMP_OP_D( 2, feq.d, 0x00, 1, -1.36, -1.36)
TEST_FP_CMP_OP_D( 3, fle.d, 0x00, 1, -1.36, -1.36)
TEST_FP_CMP_OP_D( 4, flt.d, 0x00, 0, -1.36, -1.36)
TEST_FP_CMP_OP_D( 5, feq.d, 0x00, 0, -1.37, -1.36)
TEST_FP_CMP_OP_D( 6, fle.d, 0x00, 1, -1.37, -1.36)
TEST_FP_CMP_OP_D( 7, flt.d, 0x00, 1, -1.37, -1.36)
# Only sNaN should signal invalid for feq.
TEST_FP_CMP_OP_D( 8, feq.d, 0x00, 0, NaN, 0)
TEST_FP_CMP_OP_D( 9, feq.d, 0x00, 0, NaN, NaN)
TEST_FP_CMP_OP_D(10, feq.d, 0x10, 0, sNaN, 0)
# qNaN should signal invalid for fle/flt.
TEST_FP_CMP_OP_D(11, flt.d, 0x10, 0, NaN, 0)
TEST_FP_CMP_OP_D(12, flt.d, 0x10, 0, NaN, NaN)
TEST_FP_CMP_OP_D(13, flt.d, 0x10, 0, sNaN, 0)
TEST_FP_CMP_OP_D(14, fle.d, 0x10, 0, NaN, 0)
TEST_FP_CMP_OP_D(15, fle.d, 0x10, 0, NaN, NaN)
TEST_FP_CMP_OP_D(16, fle.d, 0x10, 0, sNaN, 0)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,79 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcvt.S
#-----------------------------------------------------------------------------
#
# Test fcvt.d.{wu|w|lu|l}, fcvt.s.d, and fcvt.d.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_INT_FP_OP_D
#define TEST_INT_FP_OP_D TEST_INT_FP_OP_D32
#undef TEST_FCVT_S_D
#define TEST_FCVT_S_D TEST_FCVT_S_D32
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_INT_FP_OP_D(2, fcvt.d.w, 2.0, 2);
TEST_INT_FP_OP_D(3, fcvt.d.w, -2.0, -2);
TEST_INT_FP_OP_D(4, fcvt.d.wu, 2.0, 2);
TEST_INT_FP_OP_D(5, fcvt.d.wu, 4294967294, -2);
#if __riscv_xlen >= 64
TEST_INT_FP_OP_D(6, fcvt.d.l, 2.0, 2);
TEST_INT_FP_OP_D(7, fcvt.d.l, -2.0, -2);
TEST_INT_FP_OP_D(8, fcvt.d.lu, 2.0, 2);
TEST_INT_FP_OP_D(9, fcvt.d.lu, 1.8446744073709552e19, -2);
#endif
TEST_FCVT_S_D(10, -1.5, -1.5)
TEST_FCVT_D_S(11, -1.5, -1.5)
#if __riscv_xlen >= 64
TEST_CASE(12, a0, 0x7ff8000000000000,
la a1, test_data_22;
ld a2, 0(a1);
fmv.d.x f2, a2;
fcvt.s.d f2, f2;
fcvt.d.s f2, f2;
fmv.x.d a0, f2;
)
#else
TEST_CASE_D32(12, a0, a1, 0x7ff8000000000000,
la a1, test_data_22;
fld f2, 0(a1);
fcvt.s.d f2, f2;
fcvt.d.s f2, f2;
fsd f2, 0(a1);
lw a0, 0(a1);
lw a1, 4(a1)
)
#endif
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
test_data_22:
.dword 0x7ffcffffffff8004
RVTEST_DATA_END

View File

@@ -1,114 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcvt_w.S
#-----------------------------------------------------------------------------
#
# Test fcvt{wu|w|lu|l}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_INT_OP_D( 2, fcvt.w.d, 0x01, -1, -1.1, rtz);
TEST_FP_INT_OP_D( 3, fcvt.w.d, 0x00, -1, -1.0, rtz);
TEST_FP_INT_OP_D( 4, fcvt.w.d, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_D( 5, fcvt.w.d, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_D( 6, fcvt.w.d, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_D( 7, fcvt.w.d, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_D( 8, fcvt.w.d, 0x10, -1<<31, -3e9, rtz);
TEST_FP_INT_OP_D( 9, fcvt.w.d, 0x10, (1<<31)-1, 3e9, rtz);
TEST_FP_INT_OP_D(12, fcvt.wu.d, 0x10, 0, -3.0, rtz);
TEST_FP_INT_OP_D(13, fcvt.wu.d, 0x10, 0, -1.0, rtz);
TEST_FP_INT_OP_D(14, fcvt.wu.d, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_D(15, fcvt.wu.d, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_D(16, fcvt.wu.d, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_D(17, fcvt.wu.d, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_D(18, fcvt.wu.d, 0x10, 0, -3e9, rtz);
TEST_FP_INT_OP_D(19, fcvt.wu.d, 0x00, 0xffffffffb2d05e00, 3e9, rtz);
#if __riscv_xlen >= 64
TEST_FP_INT_OP_D(22, fcvt.l.d, 0x01, -1, -1.1, rtz);
TEST_FP_INT_OP_D(23, fcvt.l.d, 0x00, -1, -1.0, rtz);
TEST_FP_INT_OP_D(24, fcvt.l.d, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_D(25, fcvt.l.d, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_D(26, fcvt.l.d, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_D(27, fcvt.l.d, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_D(28, fcvt.l.d, 0x00,-3000000000, -3e9, rtz);
TEST_FP_INT_OP_D(29, fcvt.l.d, 0x00, 3000000000, 3e9, rtz);
TEST_FP_INT_OP_D(20, fcvt.l.d, 0x10, -1<<63,-3e19, rtz);
TEST_FP_INT_OP_D(21, fcvt.l.d, 0x10, (1<<63)-1, 3e19, rtz);
TEST_FP_INT_OP_D(32, fcvt.lu.d, 0x10, 0, -3.0, rtz);
TEST_FP_INT_OP_D(33, fcvt.lu.d, 0x10, 0, -1.0, rtz);
TEST_FP_INT_OP_D(34, fcvt.lu.d, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_D(35, fcvt.lu.d, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_D(36, fcvt.lu.d, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_D(37, fcvt.lu.d, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_D(38, fcvt.lu.d, 0x10, 0, -3e9, rtz);
TEST_FP_INT_OP_D(39, fcvt.lu.d, 0x00, 3000000000, 3e9, rtz);
#endif
# test negative NaN, negative infinity conversion
TEST_CASE(42, x1, 0x000000007fffffff, la x1, tdat_d; fld f1, 0(x1); fcvt.w.d x1, f1)
#if __riscv_xlen >= 64
TEST_CASE(43, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1, 0(x1); fcvt.l.d x1, f1)
#endif
TEST_CASE(44, x1, 0xffffffff80000000, la x1, tdat_d; fld f1, 16(x1); fcvt.w.d x1, f1)
#if __riscv_xlen >= 64
TEST_CASE(45, x1, 0x8000000000000000, la x1, tdat_d; fld f1, 16(x1); fcvt.l.d x1, f1)
#endif
# test positive NaN, positive infinity conversion
TEST_CASE(52, x1, 0x000000007fffffff, la x1, tdat_d; fld f1, 8(x1); fcvt.w.d x1, f1)
#if __riscv_xlen >= 64
TEST_CASE(53, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1, 8(x1); fcvt.l.d x1, f1)
#endif
TEST_CASE(54, x1, 0x000000007fffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.w.d x1, f1)
#if __riscv_xlen >= 64
TEST_CASE(55, x1, 0x7fffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.l.d x1, f1)
#endif
# test NaN, infinity conversions to unsigned integer
TEST_CASE(62, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 0(x1); fcvt.wu.d x1, f1)
TEST_CASE(63, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 8(x1); fcvt.wu.d x1, f1)
TEST_CASE(64, x1, 0, la x1, tdat_d; fld f1, 16(x1); fcvt.wu.d x1, f1)
TEST_CASE(65, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.wu.d x1, f1)
#if __riscv_xlen >= 64
TEST_CASE(66, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 0(x1); fcvt.lu.d x1, f1)
TEST_CASE(67, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 8(x1); fcvt.lu.d x1, f1)
TEST_CASE(68, x1, 0, la x1, tdat_d; fld f1, 16(x1); fcvt.lu.d x1, f1)
TEST_CASE(69, x1, 0xffffffffffffffff, la x1, tdat_d; fld f1, 24(x1); fcvt.lu.d x1, f1)
#endif
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
# -NaN, NaN, -inf, +inf
tdat:
.word 0xffffffff
.word 0x7fffffff
.word 0xff800000
.word 0x7f800000
tdat_d:
.dword 0xffffffffffffffff
.dword 0x7fffffffffffffff
.dword 0xfff0000000000000
.dword 0x7ff0000000000000
RVTEST_DATA_END

View File

@@ -1,54 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fdiv.S
#-----------------------------------------------------------------------------
#
# Test f{div|sqrt}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the functions with the 32-bit variants defined in test_macros.h
#undef TEST_FP_OP2_D
#define TEST_FP_OP2_D TEST_FP_OP2_D32
#undef TEST_FP_OP1_D
#define TEST_FP_OP1_D TEST_FP_OP1_D32
#undef TEST_FP_OP1_D_DWORD_RESULT
#define TEST_FP_OP1_D_DWORD_RESULT TEST_FP_OP1_D32_DWORD_RESULT
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP2_D( 2, fdiv.d, 1, 1.1557273520668288, 3.14159265, 2.71828182 );
TEST_FP_OP2_D( 3, fdiv.d, 1,-0.9991093838555584, -1234, 1235.1 );
TEST_FP_OP2_D( 4, fdiv.d, 0, 3.14159265, 3.14159265, 1.0 );
TEST_FP_OP1_D( 5, fsqrt.d, 1, 1.7724538498928541, 3.14159265 );
TEST_FP_OP1_D( 6, fsqrt.d, 0, 100, 10000 );
TEST_FP_OP1_D_DWORD_RESULT(16, fsqrt.d, 0x10, 0x7FF8000000000000, -1.0 );
TEST_FP_OP1_D( 7, fsqrt.d, 1, 13.076696830622021, 171.0);
TEST_FP_OP1_D( 8, fsqrt.d, 1,0.00040099251863345283320230749702, 1.60795e-7);
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,51 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fmadd.S
#-----------------------------------------------------------------------------
#
# Test f[n]m{add|sub}.s and f[n]m{add|sub}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_FP_OP3_D
#define TEST_FP_OP3_D TEST_FP_OP3_D32
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP3_D( 2, fmadd.d, 0, 3.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_D( 3, fmadd.d, 1, 1236.1999999999999, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_D( 4, fmadd.d, 0, -12.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_D( 5, fnmadd.d, 0, -3.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_D( 6, fnmadd.d, 1, -1236.1999999999999, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_D( 7, fnmadd.d, 0, 12.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_D( 8, fmsub.d, 0, 1.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_D( 9, fmsub.d, 1, 1234, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_D(10, fmsub.d, 0, -8.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_D(11, fnmsub.d, 0, -1.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_D(12, fnmsub.d, 1, -1234, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_D(13, fnmsub.d, 0, 8.0, 2.0, -5.0, -2.0 );
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,60 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fmin.S
#-----------------------------------------------------------------------------
#
# Test f{min|max}.d instructinos.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#if __riscv_xlen == 32
# Replace the function with the 32-bit variant defined in test_macros.h
#undef TEST_FP_OP2_D
#define TEST_FP_OP2_D TEST_FP_OP2_D32
#endif
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP2_D( 2, fmin.d, 0, 1.0, 2.5, 1.0 );
TEST_FP_OP2_D( 3, fmin.d, 0, -1235.1, -1235.1, 1.1 );
TEST_FP_OP2_D( 4, fmin.d, 0, -1235.1, 1.1, -1235.1 );
TEST_FP_OP2_D( 5, fmin.d, 0, -1235.1, NaN, -1235.1 );
TEST_FP_OP2_D( 6, fmin.d, 0, 0.00000001, 3.14159265, 0.00000001 );
TEST_FP_OP2_D( 7, fmin.d, 0, -2.0, -1.0, -2.0 );
TEST_FP_OP2_D(12, fmax.d, 0, 2.5, 2.5, 1.0 );
TEST_FP_OP2_D(13, fmax.d, 0, 1.1, -1235.1, 1.1 );
TEST_FP_OP2_D(14, fmax.d, 0, 1.1, 1.1, -1235.1 );
TEST_FP_OP2_D(15, fmax.d, 0, -1235.1, NaN, -1235.1 );
TEST_FP_OP2_D(16, fmax.d, 0, 3.14159265, 3.14159265, 0.00000001 );
TEST_FP_OP2_D(17, fmax.d, 0, -1.0, -1.0, -2.0 );
# FMIN(sNaN, x) = x
TEST_FP_OP2_D(20, fmax.d, 0x10, 1.0, sNaN, 1.0);
# FMIN(qNaN, qNaN) = canonical NaN
TEST_FP_OP2_D(21, fmax.d, 0x00, qNaN, NaN, NaN);
# -0.0 < +0.0
TEST_FP_OP2_D(30, fmin.d, 0, -0.0, -0.0, 0.0 );
TEST_FP_OP2_D(31, fmin.d, 0, -0.0, 0.0, -0.0 );
TEST_FP_OP2_D(32, fmax.d, 0, 0.0, -0.0, 0.0 );
TEST_FP_OP2_D(33, fmax.d, 0, 0.0, 0.0, -0.0 );
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,42 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# ldst.S
#-----------------------------------------------------------------------------
#
# This test verifies that flw, fld, fsw, and fsd work properly.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
la s0, tdat
TEST_CASE(2, a0, 0x40000000bf800000, fld f2, 0(s0); fsd f2, 16(s0); ld a0, 16(s0))
TEST_CASE(3, a0, 0x40000000bf800000, fld f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0))
TEST_CASE(4, a0, 0x40000000bf800000, flw f2, 0(s0); fsw f2, 16(s0); ld a0, 16(s0))
TEST_CASE(5, a0, 0xc080000040400000, fld f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0))
TEST_CASE(6, a0, 0xffffffff40400000, flw f2, 8(s0); fsd f2, 16(s0); ld a0, 16(s0))
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
tdat:
.word 0xbf800000
.word 0x40000000
.word 0x40400000
.word 0xc0800000
.word 0xdeadbeef
.word 0xcafebabe
.word 0xabad1dea
.word 0x1337d00d
RVTEST_DATA_END

View File

@@ -1,113 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# move.S
#-----------------------------------------------------------------------------
#
# This test verifies that fmv.d.x, fmv.x.d, and fsgnj[x|n].d work properly.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#TODO: make 32-bit compatible version
#define TEST_FSGNJD(n, insn, new_sign, rs1_sign, rs2_sign) \
TEST_CASE(n, a0, 0x123456789abcdef0 | (-(new_sign) << 63), \
li a1, ((rs1_sign) << 63) | 0x123456789abcdef0; \
li a2, -(rs2_sign); \
fmv.d.x f1, a1; \
fmv.d.x f2, a2; \
insn f0, f1, f2; \
fmv.x.d a0, f0)
TEST_FSGNJD(10, fsgnj.d, 0, 0, 0)
TEST_FSGNJD(11, fsgnj.d, 1, 0, 1)
TEST_FSGNJD(12, fsgnj.d, 0, 1, 0)
TEST_FSGNJD(13, fsgnj.d, 1, 1, 1)
TEST_FSGNJD(20, fsgnjn.d, 1, 0, 0)
TEST_FSGNJD(21, fsgnjn.d, 0, 0, 1)
TEST_FSGNJD(22, fsgnjn.d, 1, 1, 0)
TEST_FSGNJD(23, fsgnjn.d, 0, 1, 1)
TEST_FSGNJD(30, fsgnjx.d, 0, 0, 0)
TEST_FSGNJD(31, fsgnjx.d, 1, 0, 1)
TEST_FSGNJD(32, fsgnjx.d, 1, 1, 0)
TEST_FSGNJD(33, fsgnjx.d, 0, 1, 1)
// Test fsgnj.s in conjunction with double-precision moves
#define TEST_FSGNJS(n, rd, rs1, rs2) \
TEST_CASE(n, a0, (rd) | (-((rd) >> 31) << 32), \
li a1, rs1; \
li a2, rs2; \
fmv.d.x f1, a1; \
fmv.d.x f2, a2; \
fsgnj.s f0, f1, f2; \
fmv.x.s a0, f0); \
TEST_CASE(1##n, a0, (rd) | 0xffffffff00000000, \
li a1, rs1; \
li a2, rs2; \
fmv.d.x f1, a1; \
fmv.d.x f2, a2; \
fsgnj.s f0, f1, f2; \
fmv.x.d a0, f0)
TEST_FSGNJS(40, 0x7fc00000, 0x7ffffffe12345678, 0)
TEST_FSGNJS(41, 0x7fc00000, 0xfffffffe12345678, 0)
TEST_FSGNJS(42, 0x7fc00000, 0x7fffffff12345678, 0)
TEST_FSGNJS(43, 0x12345678, 0xffffffff12345678, 0)
TEST_FSGNJS(50, 0x7fc00000, 0x7ffffffe12345678, 0x80000000)
TEST_FSGNJS(51, 0x7fc00000, 0xfffffffe12345678, 0x80000000)
TEST_FSGNJS(52, 0x7fc00000, 0x7fffffff12345678, 0x80000000)
TEST_FSGNJS(53, 0x12345678, 0xffffffff12345678, 0x80000000)
TEST_FSGNJS(60, 0xffc00000, 0x7ffffffe12345678, 0xffffffff80000000)
TEST_FSGNJS(61, 0xffc00000, 0xfffffffe12345678, 0xffffffff80000000)
TEST_FSGNJS(62, 0x92345678, 0xffffffff12345678, 0xffffffff80000000)
TEST_FSGNJS(63, 0x12345678, 0xffffffff12345678, 0x7fffffff80000000)
// Test fsgnj.d in conjunction with single-precision moves
#define TEST_FSGNJD_SP(n, isnan, rd, rs1, rs2) \
TEST_CASE(n, a0, ((rd) & 0xffffffff) | (-(((rd) >> 31) & 1) << 32), \
li a1, rs1; \
li a2, rs2; \
fmv.d.x f1, a1; \
fmv.d.x f2, a2; \
fsgnj.d f0, f1, f2; \
feq.s a0, f0, f0; \
addi a0, a0, -!(isnan); \
bnez a0, 1f; \
fmv.x.s a0, f0; \
1:); \
TEST_CASE(1##n, a0, rd, \
li a1, rs1; \
li a2, rs2; \
fmv.d.x f1, a1; \
fmv.d.x f2, a2; \
fsgnj.d f0, f1, f2; \
fmv.x.d a0, f0; \
1:)
TEST_FSGNJD_SP(70, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff11111111)
TEST_FSGNJD_SP(71, 1, 0x7fffffff11111111, 0xffffffff11111111, 0x7fffffff11111111)
TEST_FSGNJD_SP(72, 0, 0xffffffff11111111, 0xffffffff11111111, 0xffffffff91111111)
TEST_FSGNJD_SP(73, 0, 0xffffffff11111111, 0xffffffff11111111, 0x8000000000000000)
TEST_FSGNJD_SP(74, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff11111111)
TEST_FSGNJD_SP(75, 1, 0x7fffffff11111111, 0x7fffffff11111111, 0x7fffffff11111111)
TEST_FSGNJD_SP(76, 0, 0xffffffff11111111, 0x7fffffff11111111, 0xffffffff91111111)
TEST_FSGNJD_SP(77, 0, 0xffffffff11111111, 0x7fffffff11111111, 0x8000000000000000)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,67 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# recoding.S
#-----------------------------------------------------------------------------
#
# Test corner cases of John Hauser's microarchitectural recoding scheme.
# There are twice as many recoded values as IEEE-754 values; some of these
# extras are redundant (e.g. Inf) and others are illegal (subnormals with
# too many bits set).
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
# Make sure infinities with different mantissas compare as equal.
fld f0, minf, a0
fld f1, three, a0
fmul.d f1, f1, f0
TEST_CASE( 2, a0, 1, feq.d a0, f0, f1)
TEST_CASE( 3, a0, 1, fle.d a0, f0, f1)
TEST_CASE( 4, a0, 0, flt.d a0, f0, f1)
# Likewise, but for zeroes.
fcvt.d.w f0, x0
li a0, 1
fcvt.d.w f1, a0
fmul.d f1, f1, f0
TEST_CASE(5, a0, 1, feq.d a0, f0, f1)
TEST_CASE(6, a0, 1, fle.d a0, f0, f1)
TEST_CASE(7, a0, 0, flt.d a0, f0, f1)
# When converting small doubles to single-precision subnormals,
# ensure that the extra precision is discarded.
flw f0, big, a0
fld f1, tiny, a0
fcvt.s.d f1, f1
fmul.s f0, f0, f1
fmv.x.s a0, f0
lw a1, small
TEST_CASE(10, a0, 0, sub a0, a0, a1)
# Make sure FSD+FLD correctly saves and restores a single-precision value.
flw f0, three, a0
fadd.s f1, f0, f0
fadd.s f0, f0, f0
fsd f0, tiny, a0
fld f0, tiny, a0
TEST_CASE(20, a0, 1, feq.s a0, f0, f1)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
minf: .double -Inf
three: .double 3.0
big: .float 1221
small: .float 2.9133121e-37
tiny: .double 2.3860049081905093e-40
RVTEST_DATA_END

View File

@@ -1,58 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# structural.S
#-----------------------------------------------------------------------------
#
# This test verifies that the FPU correctly obviates structural hazards on its
# writeback port (e.g. fadd followed by fsgnj)
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
li x25, 1
li x2, 0x3FF0000000000000
li x1, 0x3F800000
#define TEST(nops, errcode) \
fmv.d.x f4, x0 ;\
fmv.s.x f3, x0 ;\
fmv.d.x f2, x2 ;\
fmv.s.x f1, x1 ;\
j 1f ;\
.align 5 ;\
1:fmul.d f4, f2, f2 ;\
nops ;\
fsgnj.s f3, f1, f1 ;\
fmv.x.d x4, f4 ;\
fmv.x.s x5, f3 ;\
beq x1, x5, 2f ;\
RVTEST_FAIL ;\
2:beq x2, x4, 2f ;\
RVTEST_FAIL; \
2:fmv.d.x f2, zero ;\
fmv.s.x f1, zero ;\
TEST(;,2)
TEST(nop,4)
TEST(nop;nop,6)
TEST(nop;nop;nop,8)
TEST(nop;nop;nop;nop,10)
TEST(nop;nop;nop;nop;nop,12)
TEST(nop;nop;nop;nop;nop;nop,14)
RVTEST_PASS
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,13 +0,0 @@
#=======================================================================
# Makefrag for rv64uf tests
#-----------------------------------------------------------------------
rv64uf_sc_tests = \
fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \
ldst move recoding \
rv64uf_p_tests = $(addprefix rv64uf-p-, $(rv64uf_sc_tests))
rv64uf_v_tests = $(addprefix rv64uf-v-, $(rv64uf_sc_tests))
rv64uf_ps_tests = $(addprefix rv64uf-ps-, $(rv64uf_sc_tests))
spike_tests += $(rv64uf_p_tests) $(rv64uf_v_tests)

View File

@@ -1,44 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fadd.S
#-----------------------------------------------------------------------------
#
# Test f{add|sub|mul}.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP2_S( 2, fadd.s, 0, 3.5, 2.5, 1.0 );
TEST_FP_OP2_S( 3, fadd.s, 1, -1234, -1235.1, 1.1 );
TEST_FP_OP2_S( 4, fadd.s, 1, 3.14159265, 3.14159265, 0.00000001 );
TEST_FP_OP2_S( 5, fsub.s, 0, 1.5, 2.5, 1.0 );
TEST_FP_OP2_S( 6, fsub.s, 1, -1234, -1235.1, -1.1 );
TEST_FP_OP2_S( 7, fsub.s, 1, 3.14159265, 3.14159265, 0.00000001 );
TEST_FP_OP2_S( 8, fmul.s, 0, 2.5, 2.5, 1.0 );
TEST_FP_OP2_S( 9, fmul.s, 1, 1358.61, -1235.1, -1.1 );
TEST_FP_OP2_S(10, fmul.s, 1, 3.14159265e-8, 3.14159265, 0.00000001 );
# Is the canonical NaN generated for Inf - Inf?
TEST_FP_OP2_S(11, fsub.s, 0x10, qNaNf, Inf, Inf);
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,40 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fclass.S
#-----------------------------------------------------------------------------
#
# Test fclass.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FCLASS_S( 2, 1 << 0, 0xff800000 )
TEST_FCLASS_S( 3, 1 << 1, 0xbf800000 )
TEST_FCLASS_S( 4, 1 << 2, 0x807fffff )
TEST_FCLASS_S( 5, 1 << 3, 0x80000000 )
TEST_FCLASS_S( 6, 1 << 4, 0x00000000 )
TEST_FCLASS_S( 7, 1 << 5, 0x007fffff )
TEST_FCLASS_S( 8, 1 << 6, 0x3f800000 )
TEST_FCLASS_S( 9, 1 << 7, 0x7f800000 )
TEST_FCLASS_S(10, 1 << 8, 0x7f800001 )
TEST_FCLASS_S(11, 1 << 9, 0x7fc00000 )
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,50 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcmp.S
#-----------------------------------------------------------------------------
#
# Test f{eq|lt|le}.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_CMP_OP_S( 2, feq.s, 0x00, 1, -1.36, -1.36)
TEST_FP_CMP_OP_S( 3, fle.s, 0x00, 1, -1.36, -1.36)
TEST_FP_CMP_OP_S( 4, flt.s, 0x00, 0, -1.36, -1.36)
TEST_FP_CMP_OP_S( 5, feq.s, 0x00, 0, -1.37, -1.36)
TEST_FP_CMP_OP_S( 6, fle.s, 0x00, 1, -1.37, -1.36)
TEST_FP_CMP_OP_S( 7, flt.s, 0x00, 1, -1.37, -1.36)
# Only sNaN should signal invalid for feq.
TEST_FP_CMP_OP_S( 8, feq.s, 0x00, 0, NaN, 0)
TEST_FP_CMP_OP_S( 9, feq.s, 0x00, 0, NaN, NaN)
TEST_FP_CMP_OP_S(10, feq.s, 0x10, 0, sNaNf, 0)
# qNaN should signal invalid for fle/flt.
TEST_FP_CMP_OP_S(11, flt.s, 0x10, 0, NaN, 0)
TEST_FP_CMP_OP_S(12, flt.s, 0x10, 0, NaN, NaN)
TEST_FP_CMP_OP_S(13, flt.s, 0x10, 0, sNaNf, 0)
TEST_FP_CMP_OP_S(14, fle.s, 0x10, 0, NaN, 0)
TEST_FP_CMP_OP_S(15, fle.s, 0x10, 0, NaN, NaN)
TEST_FP_CMP_OP_S(16, fle.s, 0x10, 0, sNaNf, 0)
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,43 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcvt.S
#-----------------------------------------------------------------------------
#
# Test fcvt.s.{wu|w|lu|l}, fcvt.s.d, and fcvt.d.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_INT_FP_OP_S( 2, fcvt.s.w, 2.0, 2);
TEST_INT_FP_OP_S( 3, fcvt.s.w, -2.0, -2);
TEST_INT_FP_OP_S( 4, fcvt.s.wu, 2.0, 2);
TEST_INT_FP_OP_S( 5, fcvt.s.wu, 4.2949673e9, -2);
#if __riscv_xlen >= 64
TEST_INT_FP_OP_S( 6, fcvt.s.l, 2.0, 2);
TEST_INT_FP_OP_S( 7, fcvt.s.l, -2.0, -2);
TEST_INT_FP_OP_S( 8, fcvt.s.lu, 2.0, 2);
TEST_INT_FP_OP_S( 9, fcvt.s.lu, 1.8446744e19, -2);
#endif
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,105 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fcvt_w.S
#-----------------------------------------------------------------------------
#
# Test fcvt{wu|w|lu|l}.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_INT_OP_S( 2, fcvt.w.s, 0x01, -1, -1.1, rtz);
TEST_FP_INT_OP_S( 3, fcvt.w.s, 0x00, -1, -1.0, rtz);
TEST_FP_INT_OP_S( 4, fcvt.w.s, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_S( 5, fcvt.w.s, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_S( 6, fcvt.w.s, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_S( 7, fcvt.w.s, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_S( 8, fcvt.w.s, 0x10, -1<<31, -3e9, rtz);
TEST_FP_INT_OP_S( 9, fcvt.w.s, 0x10, (1<<31)-1, 3e9, rtz);
TEST_FP_INT_OP_S(12, fcvt.wu.s, 0x10, 0, -3.0, rtz);
TEST_FP_INT_OP_S(13, fcvt.wu.s, 0x10, 0, -1.0, rtz);
TEST_FP_INT_OP_S(14, fcvt.wu.s, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_S(15, fcvt.wu.s, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_S(16, fcvt.wu.s, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_S(17, fcvt.wu.s, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_S(18, fcvt.wu.s, 0x10, 0, -3e9, rtz);
TEST_FP_INT_OP_S(19, fcvt.wu.s, 0x00, 3000000000, 3e9, rtz);
#if __riscv_xlen >= 64
TEST_FP_INT_OP_S(22, fcvt.l.s, 0x01, -1, -1.1, rtz);
TEST_FP_INT_OP_S(23, fcvt.l.s, 0x00, -1, -1.0, rtz);
TEST_FP_INT_OP_S(24, fcvt.l.s, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_S(25, fcvt.l.s, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_S(26, fcvt.l.s, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_S(27, fcvt.l.s, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_S(32, fcvt.lu.s, 0x10, 0, -3.0, rtz);
TEST_FP_INT_OP_S(33, fcvt.lu.s, 0x10, 0, -1.0, rtz);
TEST_FP_INT_OP_S(34, fcvt.lu.s, 0x01, 0, -0.9, rtz);
TEST_FP_INT_OP_S(35, fcvt.lu.s, 0x01, 0, 0.9, rtz);
TEST_FP_INT_OP_S(36, fcvt.lu.s, 0x00, 1, 1.0, rtz);
TEST_FP_INT_OP_S(37, fcvt.lu.s, 0x01, 1, 1.1, rtz);
TEST_FP_INT_OP_S(38, fcvt.lu.s, 0x10, 0, -3e9, rtz);
#endif
# test negative NaN, negative infinity conversion
TEST_CASE( 42, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 0(x1); fcvt.w.s x1, f1)
TEST_CASE( 44, x1, 0xffffffff80000000, la x1, tdat ; flw f1, 8(x1); fcvt.w.s x1, f1)
#if __riscv_xlen >= 64
TEST_CASE( 43, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.l.s x1, f1)
TEST_CASE( 45, x1, 0x8000000000000000, la x1, tdat ; flw f1, 8(x1); fcvt.l.s x1, f1)
#endif
# test positive NaN, positive infinity conversion
TEST_CASE( 52, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 4(x1); fcvt.w.s x1, f1)
TEST_CASE( 54, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 12(x1); fcvt.w.s x1, f1)
#if __riscv_xlen >= 64
TEST_CASE( 53, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.l.s x1, f1)
TEST_CASE( 55, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.l.s x1, f1)
#endif
# test NaN, infinity conversions to unsigned integer
TEST_CASE( 62, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.wu.s x1, f1)
TEST_CASE( 63, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.wu.s x1, f1)
TEST_CASE( 64, x1, 0, la x1, tdat ; flw f1, 8(x1); fcvt.wu.s x1, f1)
TEST_CASE( 65, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.wu.s x1, f1)
#if __riscv_xlen >= 64
TEST_CASE( 66, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.lu.s x1, f1)
TEST_CASE( 67, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.lu.s x1, f1)
TEST_CASE( 68, x1, 0, la x1, tdat ; flw f1, 8(x1); fcvt.lu.s x1, f1)
TEST_CASE( 69, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.lu.s x1, f1)
#endif
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
# -NaN, NaN, -inf, +inf
tdat:
.word 0xffffffff
.word 0x7fffffff
.word 0xff800000
.word 0x7f800000
tdat_d:
.dword 0xffffffffffffffff
.dword 0x7fffffffffffffff
.dword 0xfff0000000000000
.dword 0x7ff0000000000000
RVTEST_DATA_END

View File

@@ -1,40 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fdiv.S
#-----------------------------------------------------------------------------
#
# Test f{div|sqrt}.s instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP2_S(2, fdiv.s, 1, 1.1557273520668288, 3.14159265, 2.71828182 );
TEST_FP_OP2_S(3, fdiv.s, 1,-0.9991093838555584, -1234, 1235.1 );
TEST_FP_OP2_S(4, fdiv.s, 0, 3.14159265, 3.14159265, 1.0 );
TEST_FP_OP1_S(5, fsqrt.s, 1, 1.7724538498928541, 3.14159265 );
TEST_FP_OP1_S(6, fsqrt.s, 0, 100, 10000 );
TEST_FP_OP1_S_DWORD_RESULT(7, fsqrt.s, 0x10, 0x7FC00000, -1.0 );
TEST_FP_OP1_S(8, fsqrt.s, 1, 13.076696, 171.0);
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

View File

@@ -1,45 +0,0 @@
# See LICENSE for license details.
#*****************************************************************************
# fmadd.S
#-----------------------------------------------------------------------------
#
# Test f[n]m{add|sub}.s and f[n]m{add|sub}.d instructions.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64UF
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_FP_OP3_S( 2, fmadd.s, 0, 3.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_S( 3, fmadd.s, 1, 1236.2, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_S( 4, fmadd.s, 0, -12.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_S( 5, fnmadd.s, 0, -3.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_S( 6, fnmadd.s, 1, -1236.2, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_S( 7, fnmadd.s, 0, 12.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_S( 8, fmsub.s, 0, 1.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_S( 9, fmsub.s, 1, 1234, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_S(10, fmsub.s, 0, -8.0, 2.0, -5.0, -2.0 );
TEST_FP_OP3_S(11, fnmsub.s, 0, -1.5, 1.0, 2.5, 1.0 );
TEST_FP_OP3_S(12, fnmsub.s, 1, -1234, -1.0, -1235.1, 1.1 );
TEST_FP_OP3_S(13, fnmsub.s, 0, 8.0, 2.0, -5.0, -2.0 );
TEST_PASSFAIL
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END

Some files were not shown because too many files have changed in this diff Show More