tests,style: add RISC-V assembly tests
This patch adds a subset (rv64*) of RISC-V assembly tests. The original riscv-test project can be found here: https://github.com/riscv/riscv-tests. The riscv-test project is under the BSD license (https://github.com/riscv/riscv-tests/blob/master/LICENSE) and is maintained separately from gem5 project. The tests have been slightly modified to work in gem5 SE mode: (1) Removed a trap handler used in riscv-tests for bare-metal systems (2) Instead of throwing an exception, the tests call the exit syscall with the exit code of - '0' if SUCCESS - Failed test case's number (non-zero) if FAILURE The exit code can be captured after a simuation completes. In addition to original RISC-V assembly tests, this patch adds several assembly tests specifically for AMO, LR, SC and system calls. Those tests target a multi-core system. (1) rv64uamt: multi-threaded tests for A-extension instructions (2) rv64samt: multi-threaded tests for clone and futex system calls This patch also makes the style checker ignore RISC-V assembly test directory. The assembly tests are maintained in an external project that does not follow the gem5 coding conventions. Please find more details in the README file included in this patch. Change-Id: Id1015d9a2c6c7d0341fa8b81483289e5f0bfcec0 Reviewed-on: https://gem5-review.googlesource.com/6703 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
24
tests/test-progs/asmtest/src/riscv/LICENSE
Normal file
24
tests/test-progs/asmtest/src/riscv/LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
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.
|
||||
89
tests/test-progs/asmtest/src/riscv/Makefile
Normal file
89
tests/test-progs/asmtest/src/riscv/Makefile
Normal file
@@ -0,0 +1,89 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
92
tests/test-progs/asmtest/src/riscv/README.md
Normal file
92
tests/test-progs/asmtest/src/riscv/README.md
Normal file
@@ -0,0 +1,92 @@
|
||||
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
Normal file
24
tests/test-progs/asmtest/src/riscv/env/LICENSE
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
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
Normal file
1471
tests/test-progs/asmtest/src/riscv/env/encoding.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
tests/test-progs/asmtest/src/riscv/env/p/link.ld
vendored
Normal file
17
tests/test-progs/asmtest/src/riscv/env/p/link.ld
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
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 = .;
|
||||
}
|
||||
|
||||
215
tests/test-progs/asmtest/src/riscv/env/p/riscv_test.h
vendored
Normal file
215
tests/test-progs/asmtest/src/riscv/env/p/riscv_test.h
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
// 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
tests/test-progs/asmtest/src/riscv/env/pm/link.ld
vendored
Symbolic link
1
tests/test-progs/asmtest/src/riscv/env/pm/link.ld
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../p/link.ld
|
||||
11
tests/test-progs/asmtest/src/riscv/env/pm/riscv_test.h
vendored
Normal file
11
tests/test-progs/asmtest/src/riscv/env/pm/riscv_test.h
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// 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
|
||||
17
tests/test-progs/asmtest/src/riscv/env/ps/link.ld
vendored
Normal file
17
tests/test-progs/asmtest/src/riscv/env/ps/link.ld
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
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 = .;
|
||||
}
|
||||
|
||||
170
tests/test-progs/asmtest/src/riscv/env/ps/riscv_test.h
vendored
Normal file
170
tests/test-progs/asmtest/src/riscv/env/ps/riscv_test.h
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// 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
tests/test-progs/asmtest/src/riscv/env/pt/link.ld
vendored
Symbolic link
1
tests/test-progs/asmtest/src/riscv/env/pt/link.ld
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../p/link.ld
|
||||
69
tests/test-progs/asmtest/src/riscv/env/pt/riscv_test.h
vendored
Normal file
69
tests/test-progs/asmtest/src/riscv/env/pt/riscv_test.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// 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
Normal file
125
tests/test-progs/asmtest/src/riscv/env/v/entry.S
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
#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
tests/test-progs/asmtest/src/riscv/env/v/link.ld
vendored
Symbolic link
1
tests/test-progs/asmtest/src/riscv/env/v/link.ld
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../p/link.ld
|
||||
71
tests/test-progs/asmtest/src/riscv/env/v/riscv_test.h
vendored
Normal file
71
tests/test-progs/asmtest/src/riscv/env/v/riscv_test.h
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// 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
Normal file
114
tests/test-progs/asmtest/src/riscv/env/v/string.c
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
#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
Normal file
273
tests/test-progs/asmtest/src/riscv/env/v/vm.c
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
// 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
tests/test-progs/asmtest/src/riscv/isa/.gitignore
vendored
Normal file
1
tests/test-progs/asmtest/src/riscv/isa/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
rv*-*
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
@@ -0,0 +1,649 @@
|
||||
// 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
|
||||
19
tests/test-progs/asmtest/src/riscv/isa/rv64mi/Makefrag
Normal file
19
tests/test-progs/asmtest/src/riscv/isa/rv64mi/Makefrag
Normal file
@@ -0,0 +1,19 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
70
tests/test-progs/asmtest/src/riscv/isa/rv64mi/access.S
Normal file
70
tests/test-progs/asmtest/src/riscv/isa/rv64mi/access.S
Normal file
@@ -0,0 +1,70 @@
|
||||
# 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
|
||||
144
tests/test-progs/asmtest/src/riscv/isa/rv64mi/breakpoint.S
Normal file
144
tests/test-progs/asmtest/src/riscv/isa/rv64mi/breakpoint.S
Normal file
@@ -0,0 +1,144 @@
|
||||
# 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
|
||||
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/csr.S
Normal file
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/csr.S
Normal file
@@ -0,0 +1,8 @@
|
||||
# See LICENSE for license details.
|
||||
|
||||
#include "riscv_test.h"
|
||||
#undef RVTEST_RV64S
|
||||
#define RVTEST_RV64S RVTEST_RV64M
|
||||
#define __MACHINE_MODE
|
||||
|
||||
#include "../rv64si/csr.S"
|
||||
194
tests/test-progs/asmtest/src/riscv/isa/rv64mi/illegal.S
Normal file
194
tests/test-progs/asmtest/src/riscv/isa/rv64mi/illegal.S
Normal file
@@ -0,0 +1,194 @@
|
||||
# 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
|
||||
126
tests/test-progs/asmtest/src/riscv/isa/rv64mi/ma_addr.S
Normal file
126
tests/test-progs/asmtest/src/riscv/isa/rv64mi/ma_addr.S
Normal file
@@ -0,0 +1,126 @@
|
||||
# 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
|
||||
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/ma_fetch.S
Normal file
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/ma_fetch.S
Normal file
@@ -0,0 +1,8 @@
|
||||
# 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"
|
||||
45
tests/test-progs/asmtest/src/riscv/isa/rv64mi/mcsr.S
Normal file
45
tests/test-progs/asmtest/src/riscv/isa/rv64mi/mcsr.S
Normal file
@@ -0,0 +1,45 @@
|
||||
# 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
|
||||
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/sbreak.S
Normal file
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/sbreak.S
Normal file
@@ -0,0 +1,8 @@
|
||||
# See LICENSE for license details.
|
||||
|
||||
#include "riscv_test.h"
|
||||
#undef RVTEST_RV64S
|
||||
#define RVTEST_RV64S RVTEST_RV64M
|
||||
#define __MACHINE_MODE
|
||||
|
||||
#include "../rv64si/sbreak.S"
|
||||
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/scall.S
Normal file
8
tests/test-progs/asmtest/src/riscv/isa/rv64mi/scall.S
Normal file
@@ -0,0 +1,8 @@
|
||||
# See LICENSE for license details.
|
||||
|
||||
#include "riscv_test.h"
|
||||
#undef RVTEST_RV64S
|
||||
#define RVTEST_RV64S RVTEST_RV64M
|
||||
#define __MACHINE_MODE
|
||||
|
||||
#include "../rv64si/scall.S"
|
||||
13
tests/test-progs/asmtest/src/riscv/isa/rv64samt/Makefrag
Normal file
13
tests/test-progs/asmtest/src/riscv/isa/rv64samt/Makefrag
Normal file
@@ -0,0 +1,13 @@
|
||||
#=========================================================================
|
||||
# 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)
|
||||
158
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysclone_d.S
Normal file
158
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysclone_d.S
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
145
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex1_d.S
Normal file
145
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex1_d.S
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
212
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex2_d.S
Normal file
212
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex2_d.S
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta, Moyang
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
172
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex3_d.S
Normal file
172
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex3_d.S
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta, Moyang Wang
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
193
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex_d.S
Normal file
193
tests/test-progs/asmtest/src/riscv/isa/rv64samt/sysfutex_d.S
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
16
tests/test-progs/asmtest/src/riscv/isa/rv64si/Makefrag
Normal file
16
tests/test-progs/asmtest/src/riscv/isa/rv64si/Makefrag
Normal file
@@ -0,0 +1,16 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
148
tests/test-progs/asmtest/src/riscv/isa/rv64si/csr.S
Normal file
148
tests/test-progs/asmtest/src/riscv/isa/rv64si/csr.S
Normal file
@@ -0,0 +1,148 @@
|
||||
# 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
|
||||
129
tests/test-progs/asmtest/src/riscv/isa/rv64si/dirty.S
Normal file
129
tests/test-progs/asmtest/src/riscv/isa/rv64si/dirty.S
Normal file
@@ -0,0 +1,129 @@
|
||||
# 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
|
||||
159
tests/test-progs/asmtest/src/riscv/isa/rv64si/ma_fetch.S
Normal file
159
tests/test-progs/asmtest/src/riscv/isa/rv64si/ma_fetch.S
Normal file
@@ -0,0 +1,159 @@
|
||||
# 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
|
||||
51
tests/test-progs/asmtest/src/riscv/isa/rv64si/sbreak.S
Normal file
51
tests/test-progs/asmtest/src/riscv/isa/rv64si/sbreak.S
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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
|
||||
77
tests/test-progs/asmtest/src/riscv/isa/rv64si/scall.S
Normal file
77
tests/test-progs/asmtest/src/riscv/isa/rv64si/scall.S
Normal file
@@ -0,0 +1,77 @@
|
||||
# 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
|
||||
33
tests/test-progs/asmtest/src/riscv/isa/rv64si/wfi.S
Normal file
33
tests/test-progs/asmtest/src/riscv/isa/rv64si/wfi.S
Normal file
@@ -0,0 +1,33 @@
|
||||
# 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
|
||||
14
tests/test-progs/asmtest/src/riscv/isa/rv64ua/Makefrag
Normal file
14
tests/test-progs/asmtest/src/riscv/isa/rv64ua/Makefrag
Normal file
@@ -0,0 +1,14 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
47
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoadd_d.S
Normal file
47
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoadd_d.S
Normal file
@@ -0,0 +1,47 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoadd_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoadd_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoand_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoand_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoand_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoand_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomax_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomax_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomax_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomax_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomaxu_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomaxu_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomaxu_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomaxu_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomin_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomin_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomin_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amomin_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
49
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amominu_d.S
Normal file
49
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amominu_d.S
Normal file
@@ -0,0 +1,49 @@
|
||||
# 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
|
||||
|
||||
49
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amominu_w.S
Normal file
49
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amominu_w.S
Normal file
@@ -0,0 +1,49 @@
|
||||
# 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
|
||||
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoor_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoor_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoor_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoor_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoswap_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoswap_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoswap_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoswap_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoxor_d.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoxor_d.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoxor_w.S
Normal file
48
tests/test-progs/asmtest/src/riscv/isa/rv64ua/amoxor_w.S
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
85
tests/test-progs/asmtest/src/riscv/isa/rv64ua/lrsc.S
Normal file
85
tests/test-progs/asmtest/src/riscv/isa/rv64ua/lrsc.S
Normal file
@@ -0,0 +1,85 @@
|
||||
# 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
|
||||
25
tests/test-progs/asmtest/src/riscv/isa/rv64ua/test.S
Normal file
25
tests/test-progs/asmtest/src/riscv/isa/rv64ua/test.S
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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
|
||||
10
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/Makefrag
Normal file
10
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/Makefrag
Normal file
@@ -0,0 +1,10 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
104
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoadd_d.S
Normal file
104
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoadd_d.S
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoand_d.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoand_d.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomax_d.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomax_d.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomaxu_d.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomaxu_d.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomin_d.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amomin_d.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amominu_d.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amominu_d.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
106
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoor_d.S
Normal file
106
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoor_d.S
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
117
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoswap_d.S
Normal file
117
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoswap_d.S
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
106
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoxor_d.S
Normal file
106
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/amoxor_d.S
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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;
|
||||
119
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/lrsc_d.S
Normal file
119
tests/test-progs/asmtest/src/riscv/isa/rv64uamt/lrsc_d.S
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Authors: Tuan Ta
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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
|
||||
12
tests/test-progs/asmtest/src/riscv/isa/rv64uc/Makefrag
Normal file
12
tests/test-progs/asmtest/src/riscv/isa/rv64uc/Makefrag
Normal file
@@ -0,0 +1,12 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
154
tests/test-progs/asmtest/src/riscv/isa/rv64uc/rvc.S
Normal file
154
tests/test-progs/asmtest/src/riscv/isa/rv64uc/rvc.S
Normal file
@@ -0,0 +1,154 @@
|
||||
# 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
|
||||
13
tests/test-progs/asmtest/src/riscv/isa/rv64ud/Makefrag
Normal file
13
tests/test-progs/asmtest/src/riscv/isa/rv64ud/Makefrag
Normal file
@@ -0,0 +1,13 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
50
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fadd.S
Normal file
50
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fadd.S
Normal file
@@ -0,0 +1,50 @@
|
||||
# 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
|
||||
46
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fclass.S
Normal file
46
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fclass.S
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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
|
||||
56
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcmp.S
Normal file
56
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcmp.S
Normal file
@@ -0,0 +1,56 @@
|
||||
# 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
|
||||
79
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcvt.S
Normal file
79
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcvt.S
Normal file
@@ -0,0 +1,79 @@
|
||||
# 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
|
||||
114
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcvt_w.S
Normal file
114
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fcvt_w.S
Normal file
@@ -0,0 +1,114 @@
|
||||
# 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
|
||||
54
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fdiv.S
Normal file
54
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fdiv.S
Normal file
@@ -0,0 +1,54 @@
|
||||
# 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
|
||||
51
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fmadd.S
Normal file
51
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fmadd.S
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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
|
||||
60
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fmin.S
Normal file
60
tests/test-progs/asmtest/src/riscv/isa/rv64ud/fmin.S
Normal file
@@ -0,0 +1,60 @@
|
||||
# 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
|
||||
42
tests/test-progs/asmtest/src/riscv/isa/rv64ud/ldst.S
Normal file
42
tests/test-progs/asmtest/src/riscv/isa/rv64ud/ldst.S
Normal file
@@ -0,0 +1,42 @@
|
||||
# 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
|
||||
113
tests/test-progs/asmtest/src/riscv/isa/rv64ud/move.S
Normal file
113
tests/test-progs/asmtest/src/riscv/isa/rv64ud/move.S
Normal file
@@ -0,0 +1,113 @@
|
||||
# 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
|
||||
67
tests/test-progs/asmtest/src/riscv/isa/rv64ud/recoding.S
Normal file
67
tests/test-progs/asmtest/src/riscv/isa/rv64ud/recoding.S
Normal file
@@ -0,0 +1,67 @@
|
||||
# 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
|
||||
58
tests/test-progs/asmtest/src/riscv/isa/rv64ud/structural.S
Normal file
58
tests/test-progs/asmtest/src/riscv/isa/rv64ud/structural.S
Normal file
@@ -0,0 +1,58 @@
|
||||
# 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
|
||||
13
tests/test-progs/asmtest/src/riscv/isa/rv64uf/Makefrag
Normal file
13
tests/test-progs/asmtest/src/riscv/isa/rv64uf/Makefrag
Normal file
@@ -0,0 +1,13 @@
|
||||
#=======================================================================
|
||||
# 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)
|
||||
44
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fadd.S
Normal file
44
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fadd.S
Normal file
@@ -0,0 +1,44 @@
|
||||
# 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
|
||||
40
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fclass.S
Normal file
40
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fclass.S
Normal file
@@ -0,0 +1,40 @@
|
||||
# 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
|
||||
50
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcmp.S
Normal file
50
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcmp.S
Normal file
@@ -0,0 +1,50 @@
|
||||
# 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
|
||||
43
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcvt.S
Normal file
43
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcvt.S
Normal file
@@ -0,0 +1,43 @@
|
||||
# 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
|
||||
105
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcvt_w.S
Normal file
105
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fcvt_w.S
Normal file
@@ -0,0 +1,105 @@
|
||||
# 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
|
||||
40
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fdiv.S
Normal file
40
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fdiv.S
Normal file
@@ -0,0 +1,40 @@
|
||||
# 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
|
||||
45
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fmadd.S
Normal file
45
tests/test-progs/asmtest/src/riscv/isa/rv64uf/fmadd.S
Normal file
@@ -0,0 +1,45 @@
|
||||
# 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