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:
@@ -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.
|
||||
@@ -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)
|
||||
@@ -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
|
||||
24
tests/test-progs/asmtest/src/riscv/env/LICENSE
vendored
24
tests/test-progs/asmtest/src/riscv/env/LICENSE
vendored
@@ -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.
|
||||
1471
tests/test-progs/asmtest/src/riscv/env/encoding.h
vendored
1471
tests/test-progs/asmtest/src/riscv/env/encoding.h
vendored
File diff suppressed because it is too large
Load Diff
17
tests/test-progs/asmtest/src/riscv/env/p/link.ld
vendored
17
tests/test-progs/asmtest/src/riscv/env/p/link.ld
vendored
@@ -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 = .;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
../p/link.ld
|
||||
@@ -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
|
||||
@@ -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 = .;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
../p/link.ld
|
||||
@@ -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
|
||||
125
tests/test-progs/asmtest/src/riscv/env/v/entry.S
vendored
125
tests/test-progs/asmtest/src/riscv/env/v/entry.S
vendored
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
../p/link.ld
|
||||
@@ -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
|
||||
114
tests/test-progs/asmtest/src/riscv/env/v/string.c
vendored
114
tests/test-progs/asmtest/src/riscv/env/v/string.c
vendored
@@ -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;
|
||||
}
|
||||
273
tests/test-progs/asmtest/src/riscv/env/v/vm.c
vendored
273
tests/test-progs/asmtest/src/riscv/env/v/vm.c
vendored
@@ -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);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
rv*-*
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user