aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-06-06 14:01:37 +0200
committerClifford Wolf <clifford@clifford.at>2015-06-06 14:14:32 +0200
commit77ba5a18973bd02b461ab96047acfcc3fb62cf7b (patch)
tree573afedb6a3a14c91224e16724fa21ba3a939de2 /tests
downloadpicorv32-77ba5a18973bd02b461ab96047acfcc3fb62cf7b.tar.gz
picorv32-77ba5a18973bd02b461ab96047acfcc3fb62cf7b.zip
Initial import
Diffstat (limited to 'tests')
-rw-r--r--tests/LICENSE24
-rw-r--r--tests/add.S85
-rw-r--r--tests/addi.S71
-rw-r--r--tests/and.S69
-rw-r--r--tests/andi.S55
-rw-r--r--tests/auipc.S39
-rw-r--r--tests/beq.S73
-rw-r--r--tests/bge.S76
-rw-r--r--tests/bgeu.S76
-rw-r--r--tests/blt.S73
-rw-r--r--tests/bltu.S73
-rw-r--r--tests/bne.S73
-rw-r--r--tests/fence_i.S53
-rw-r--r--tests/j.S49
-rw-r--r--tests/jal.S60
-rw-r--r--tests/jalr.S88
-rw-r--r--tests/lb.S92
-rw-r--r--tests/lbu.S92
-rw-r--r--tests/lh.S92
-rw-r--r--tests/lhu.S92
-rw-r--r--tests/lui.S36
-rw-r--r--tests/lw.S92
-rw-r--r--tests/or.S69
-rw-r--r--tests/ori.S55
-rw-r--r--tests/riscv_test.h64
-rw-r--r--tests/sb.S102
-rw-r--r--tests/sh.S102
-rw-r--r--tests/simple.S27
-rw-r--r--tests/sll.S90
-rw-r--r--tests/slli.S68
-rw-r--r--tests/slt.S84
-rw-r--r--tests/slti.S70
-rw-r--r--tests/sra.S90
-rw-r--r--tests/srai.S68
-rw-r--r--tests/srl.S90
-rw-r--r--tests/srli.S69
-rw-r--r--tests/sub.S83
-rw-r--r--tests/sw.S92
-rw-r--r--tests/test_macros.h708
-rw-r--r--tests/xor.S69
-rw-r--r--tests/xori.S55
41 files changed, 3588 insertions, 0 deletions
diff --git a/tests/LICENSE b/tests/LICENSE
new file mode 100644
index 0000000..48fe522
--- /dev/null
+++ b/tests/LICENSE
@@ -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.
diff --git a/tests/add.S b/tests/add.S
new file mode 100644
index 0000000..2eb330e
--- /dev/null
+++ b/tests/add.S
@@ -0,0 +1,85 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# add.S
+#-----------------------------------------------------------------------------
+#
+# Test add instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, add, 0x00000000, 0x00000000, 0x00000000 );
+ TEST_RR_OP( 3, add, 0x00000002, 0x00000001, 0x00000001 );
+ TEST_RR_OP( 4, add, 0x0000000a, 0x00000003, 0x00000007 );
+
+ TEST_RR_OP( 5, add, 0xffff8000, 0x00000000, 0xffff8000 );
+ TEST_RR_OP( 6, add, 0x80000000, 0x80000000, 0x00000000 );
+ TEST_RR_OP( 7, add, 0x7fff8000, 0x80000000, 0xffff8000 );
+
+ TEST_RR_OP( 8, add, 0x00007fff, 0x00000000, 0x00007fff );
+ TEST_RR_OP( 9, add, 0x7fffffff, 0x7fffffff, 0x00000000 );
+ TEST_RR_OP( 10, add, 0x80007ffe, 0x7fffffff, 0x00007fff );
+
+ TEST_RR_OP( 11, add, 0x80007fff, 0x80000000, 0x00007fff );
+ TEST_RR_OP( 12, add, 0x7fff7fff, 0x7fffffff, 0xffff8000 );
+
+ TEST_RR_OP( 13, add, 0xffffffff, 0x00000000, 0xffffffff );
+ TEST_RR_OP( 14, add, 0x00000000, 0xffffffff, 0x00000001 );
+ TEST_RR_OP( 15, add, 0xfffffffe, 0xffffffff, 0xffffffff );
+
+ TEST_RR_OP( 16, add, 0x80000000, 0x00000001, 0x7fffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 17, add, 24, 13, 11 );
+ TEST_RR_SRC2_EQ_DEST( 18, add, 25, 14, 11 );
+ TEST_RR_SRC12_EQ_DEST( 19, add, 26, 13 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 20, 0, add, 24, 13, 11 );
+ TEST_RR_DEST_BYPASS( 21, 1, add, 25, 14, 11 );
+ TEST_RR_DEST_BYPASS( 22, 2, add, 26, 15, 11 );
+
+ TEST_RR_SRC12_BYPASS( 23, 0, 0, add, 24, 13, 11 );
+ TEST_RR_SRC12_BYPASS( 24, 0, 1, add, 25, 14, 11 );
+ TEST_RR_SRC12_BYPASS( 25, 0, 2, add, 26, 15, 11 );
+ TEST_RR_SRC12_BYPASS( 26, 1, 0, add, 24, 13, 11 );
+ TEST_RR_SRC12_BYPASS( 27, 1, 1, add, 25, 14, 11 );
+ TEST_RR_SRC12_BYPASS( 28, 2, 0, add, 26, 15, 11 );
+
+ TEST_RR_SRC21_BYPASS( 29, 0, 0, add, 24, 13, 11 );
+ TEST_RR_SRC21_BYPASS( 30, 0, 1, add, 25, 14, 11 );
+ TEST_RR_SRC21_BYPASS( 31, 0, 2, add, 26, 15, 11 );
+ TEST_RR_SRC21_BYPASS( 32, 1, 0, add, 24, 13, 11 );
+ TEST_RR_SRC21_BYPASS( 33, 1, 1, add, 25, 14, 11 );
+ TEST_RR_SRC21_BYPASS( 34, 2, 0, add, 26, 15, 11 );
+
+ TEST_RR_ZEROSRC1( 35, add, 15, 15 );
+ TEST_RR_ZEROSRC2( 36, add, 32, 32 );
+ TEST_RR_ZEROSRC12( 37, add, 0 );
+ TEST_RR_ZERODEST( 38, add, 16, 30 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/addi.S b/tests/addi.S
new file mode 100644
index 0000000..f7a418b
--- /dev/null
+++ b/tests/addi.S
@@ -0,0 +1,71 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# addi.S
+#-----------------------------------------------------------------------------
+#
+# Test addi instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, addi, 0x00000000, 0x00000000, 0x000 );
+ TEST_IMM_OP( 3, addi, 0x00000002, 0x00000001, 0x001 );
+ TEST_IMM_OP( 4, addi, 0x0000000a, 0x00000003, 0x007 );
+
+ TEST_IMM_OP( 5, addi, 0xfffff800, 0x00000000, 0x800 );
+ TEST_IMM_OP( 6, addi, 0x80000000, 0x80000000, 0x000 );
+ TEST_IMM_OP( 7, addi, 0x7ffff800, 0x80000000, 0x800 );
+
+ TEST_IMM_OP( 8, addi, 0x000007ff, 0x00000000, 0x7ff );
+ TEST_IMM_OP( 9, addi, 0x7fffffff, 0x7fffffff, 0x000 );
+ TEST_IMM_OP( 10, addi, 0x800007fe, 0x7fffffff, 0x7ff );
+
+ TEST_IMM_OP( 11, addi, 0x800007ff, 0x80000000, 0x7ff );
+ TEST_IMM_OP( 12, addi, 0x7ffff7ff, 0x7fffffff, 0x800 );
+
+ TEST_IMM_OP( 13, addi, 0xffffffff, 0x00000000, 0xfff );
+ TEST_IMM_OP( 14, addi, 0x00000000, 0xffffffff, 0x001 );
+ TEST_IMM_OP( 15, addi, 0xfffffffe, 0xffffffff, 0xfff );
+
+ TEST_IMM_OP( 16, addi, 0x80000000, 0x7fffffff, 0x001 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 17, addi, 24, 13, 11 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 18, 0, addi, 24, 13, 11 );
+ TEST_IMM_DEST_BYPASS( 19, 1, addi, 23, 13, 10 );
+ TEST_IMM_DEST_BYPASS( 20, 2, addi, 22, 13, 9 );
+
+ TEST_IMM_SRC1_BYPASS( 21, 0, addi, 24, 13, 11 );
+ TEST_IMM_SRC1_BYPASS( 22, 1, addi, 23, 13, 10 );
+ TEST_IMM_SRC1_BYPASS( 23, 2, addi, 22, 13, 9 );
+
+ TEST_IMM_ZEROSRC1( 24, addi, 32, 32 );
+ TEST_IMM_ZERODEST( 25, addi, 33, 50 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/and.S b/tests/and.S
new file mode 100644
index 0000000..561ae3b
--- /dev/null
+++ b/tests/and.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# and.S
+#-----------------------------------------------------------------------------
+#
+# Test and instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_OP( 3, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_OP( 4, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_OP( 5, and, 0xf000f000, 0xf00ff00f, 0xf0f0f0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 6, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC2_EQ_DEST( 7, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_EQ_DEST( 8, and, 0xff00ff00, 0xff00ff00 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 9, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_DEST_BYPASS( 10, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_DEST_BYPASS( 11, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC12_BYPASS( 12, 0, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 13, 0, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 14, 0, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 15, 1, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 16, 1, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 17, 2, 0, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC21_BYPASS( 18, 0, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 19, 0, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 20, 0, 2, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 21, 1, 0, and, 0x0f000f00, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 22, 1, 1, and, 0x00f000f0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 23, 2, 0, and, 0x000f000f, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_ZEROSRC1( 24, and, 0, 0xff00ff00 );
+ TEST_RR_ZEROSRC2( 25, and, 0, 0x00ff00ff );
+ TEST_RR_ZEROSRC12( 26, and, 0 );
+ TEST_RR_ZERODEST( 27, and, 0x11111111, 0x22222222 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/andi.S b/tests/andi.S
new file mode 100644
index 0000000..c2ae94d
--- /dev/null
+++ b/tests/andi.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# andi.S
+#-----------------------------------------------------------------------------
+#
+# Test andi instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, andi, 0xff00ff00, 0xff00ff00, 0xf0f );
+ TEST_IMM_OP( 3, andi, 0x000000f0, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_OP( 4, andi, 0x0000000f, 0x00ff00ff, 0x70f );
+ TEST_IMM_OP( 5, andi, 0x00000000, 0xf00ff00f, 0x0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 6, andi, 0x00000000, 0xff00ff00, 0x0f0 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 7, 0, andi, 0x00000700, 0x0ff00ff0, 0x70f );
+ TEST_IMM_DEST_BYPASS( 8, 1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 );
+ TEST_IMM_DEST_BYPASS( 9, 2, andi, 0xf00ff00f, 0xf00ff00f, 0xf0f );
+
+ TEST_IMM_SRC1_BYPASS( 10, 0, andi, 0x00000700, 0x0ff00ff0, 0x70f );
+ TEST_IMM_SRC1_BYPASS( 11, 1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 );
+ TEST_IMM_SRC1_BYPASS( 12, 2, andi, 0x0000000f, 0xf00ff00f, 0x70f );
+
+ TEST_IMM_ZEROSRC1( 13, andi, 0, 0x0f0 );
+ TEST_IMM_ZERODEST( 14, andi, 0x00ff00ff, 0x70f );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/auipc.S b/tests/auipc.S
new file mode 100644
index 0000000..c67e3c9
--- /dev/null
+++ b/tests/auipc.S
@@ -0,0 +1,39 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# auipc.S
+#-----------------------------------------------------------------------------
+#
+# Test auipc instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ TEST_CASE(2, a0, 10000, \
+ .align 3; \
+ lla a0, 1f + 10000; \
+ jal a1, 1f; \
+ 1: sub a0, a0, a1; \
+ )
+
+ TEST_CASE(3, a0, -10000, \
+ .align 3; \
+ lla a0, 1f - 10000; \
+ jal a1, 1f; \
+ 1: sub a0, a0, a1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/beq.S b/tests/beq.S
new file mode 100644
index 0000000..c972eff
--- /dev/null
+++ b/tests/beq.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# beq.S
+#-----------------------------------------------------------------------------
+#
+# Test beq instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, beq, 0, 0 );
+ TEST_BR2_OP_TAKEN( 3, beq, 1, 1 );
+ TEST_BR2_OP_TAKEN( 4, beq, -1, -1 );
+
+ TEST_BR2_OP_NOTTAKEN( 5, beq, 0, 1 );
+ TEST_BR2_OP_NOTTAKEN( 6, beq, 1, 0 );
+ TEST_BR2_OP_NOTTAKEN( 7, beq, -1, 1 );
+ TEST_BR2_OP_NOTTAKEN( 8, beq, 1, -1 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 9, 0, 0, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 10, 0, 1, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 11, 0, 2, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 12, 1, 0, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 13, 1, 1, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 14, 2, 0, beq, 0, -1 );
+
+ TEST_BR2_SRC12_BYPASS( 15, 0, 0, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 16, 0, 1, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 17, 0, 2, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 18, 1, 0, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 19, 1, 1, beq, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 20, 2, 0, beq, 0, -1 );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 21, x1, 3, \
+ li x1, 1; \
+ beq x0, x0, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/bge.S b/tests/bge.S
new file mode 100644
index 0000000..d6aea7c
--- /dev/null
+++ b/tests/bge.S
@@ -0,0 +1,76 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bge.S
+#-----------------------------------------------------------------------------
+#
+# Test bge instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, bge, 0, 0 );
+ TEST_BR2_OP_TAKEN( 3, bge, 1, 1 );
+ TEST_BR2_OP_TAKEN( 4, bge, -1, -1 );
+ TEST_BR2_OP_TAKEN( 5, bge, 1, 0 );
+ TEST_BR2_OP_TAKEN( 6, bge, 1, -1 );
+ TEST_BR2_OP_TAKEN( 7, bge, -1, -2 );
+
+ TEST_BR2_OP_NOTTAKEN( 8, bge, 0, 1 );
+ TEST_BR2_OP_NOTTAKEN( 9, bge, -1, 1 );
+ TEST_BR2_OP_NOTTAKEN( 10, bge, -2, -1 );
+ TEST_BR2_OP_NOTTAKEN( 11, bge, -2, 1 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 12, 0, 0, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 13, 0, 1, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 14, 0, 2, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 15, 1, 0, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 16, 1, 1, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 17, 2, 0, bge, -1, 0 );
+
+ TEST_BR2_SRC12_BYPASS( 18, 0, 0, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 19, 0, 1, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 20, 0, 2, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 21, 1, 0, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 22, 1, 1, bge, -1, 0 );
+ TEST_BR2_SRC12_BYPASS( 23, 2, 0, bge, -1, 0 );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 24, x1, 3, \
+ li x1, 1; \
+ bge x1, x0, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/bgeu.S b/tests/bgeu.S
new file mode 100644
index 0000000..114c845
--- /dev/null
+++ b/tests/bgeu.S
@@ -0,0 +1,76 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bgeu.S
+#-----------------------------------------------------------------------------
+#
+# Test bgeu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, bgeu, 0x00000000, 0x00000000 );
+ TEST_BR2_OP_TAKEN( 3, bgeu, 0x00000001, 0x00000001 );
+ TEST_BR2_OP_TAKEN( 4, bgeu, 0xffffffff, 0xffffffff );
+ TEST_BR2_OP_TAKEN( 5, bgeu, 0x00000001, 0x00000000 );
+ TEST_BR2_OP_TAKEN( 6, bgeu, 0xffffffff, 0xfffffffe );
+ TEST_BR2_OP_TAKEN( 7, bgeu, 0xffffffff, 0x00000000 );
+
+ TEST_BR2_OP_NOTTAKEN( 8, bgeu, 0x00000000, 0x00000001 );
+ TEST_BR2_OP_NOTTAKEN( 9, bgeu, 0xfffffffe, 0xffffffff );
+ TEST_BR2_OP_NOTTAKEN( 10, bgeu, 0x00000000, 0xffffffff );
+ TEST_BR2_OP_NOTTAKEN( 11, bgeu, 0x7fffffff, 0x80000000 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 12, 0, 0, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 13, 0, 1, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 14, 0, 2, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 15, 1, 0, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 16, 1, 1, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 17, 2, 0, bgeu, 0xefffffff, 0xf0000000 );
+
+ TEST_BR2_SRC12_BYPASS( 18, 0, 0, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 19, 0, 1, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 20, 0, 2, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 21, 1, 0, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 22, 1, 1, bgeu, 0xefffffff, 0xf0000000 );
+ TEST_BR2_SRC12_BYPASS( 23, 2, 0, bgeu, 0xefffffff, 0xf0000000 );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 24, x1, 3, \
+ li x1, 1; \
+ bgeu x1, x0, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/blt.S b/tests/blt.S
new file mode 100644
index 0000000..12e28c3
--- /dev/null
+++ b/tests/blt.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# blt.S
+#-----------------------------------------------------------------------------
+#
+# Test blt instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, blt, 0, 1 );
+ TEST_BR2_OP_TAKEN( 3, blt, -1, 1 );
+ TEST_BR2_OP_TAKEN( 4, blt, -2, -1 );
+
+ TEST_BR2_OP_NOTTAKEN( 5, blt, 1, 0 );
+ TEST_BR2_OP_NOTTAKEN( 6, blt, 1, -1 );
+ TEST_BR2_OP_NOTTAKEN( 7, blt, -1, -2 );
+ TEST_BR2_OP_NOTTAKEN( 8, blt, 1, -2 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 9, 0, 0, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 10, 0, 1, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 11, 0, 2, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 12, 1, 0, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 13, 1, 1, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 14, 2, 0, blt, 0, -1 );
+
+ TEST_BR2_SRC12_BYPASS( 15, 0, 0, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 16, 0, 1, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 17, 0, 2, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 18, 1, 0, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 19, 1, 1, blt, 0, -1 );
+ TEST_BR2_SRC12_BYPASS( 20, 2, 0, blt, 0, -1 );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 21, x1, 3, \
+ li x1, 1; \
+ blt x0, x1, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/bltu.S b/tests/bltu.S
new file mode 100644
index 0000000..5dcfe7e
--- /dev/null
+++ b/tests/bltu.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bltu.S
+#-----------------------------------------------------------------------------
+#
+# Test bltu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, bltu, 0x00000000, 0x00000001 );
+ TEST_BR2_OP_TAKEN( 3, bltu, 0xfffffffe, 0xffffffff );
+ TEST_BR2_OP_TAKEN( 4, bltu, 0x00000000, 0xffffffff );
+
+ TEST_BR2_OP_NOTTAKEN( 5, bltu, 0x00000001, 0x00000000 );
+ TEST_BR2_OP_NOTTAKEN( 6, bltu, 0xffffffff, 0xfffffffe );
+ TEST_BR2_OP_NOTTAKEN( 7, bltu, 0xffffffff, 0x00000000 );
+ TEST_BR2_OP_NOTTAKEN( 8, bltu, 0x80000000, 0x7fffffff );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 9, 0, 0, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 10, 0, 1, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 11, 0, 2, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 12, 1, 0, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 13, 1, 1, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 14, 2, 0, bltu, 0xf0000000, 0xefffffff );
+
+ TEST_BR2_SRC12_BYPASS( 15, 0, 0, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 16, 0, 1, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 17, 0, 2, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 18, 1, 0, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 19, 1, 1, bltu, 0xf0000000, 0xefffffff );
+ TEST_BR2_SRC12_BYPASS( 20, 2, 0, bltu, 0xf0000000, 0xefffffff );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 21, x1, 3, \
+ li x1, 1; \
+ bltu x0, x1, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/bne.S b/tests/bne.S
new file mode 100644
index 0000000..0b33753
--- /dev/null
+++ b/tests/bne.S
@@ -0,0 +1,73 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# bne.S
+#-----------------------------------------------------------------------------
+#
+# Test bne instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Branch tests
+ #-------------------------------------------------------------
+
+ # Each test checks both forward and backward branches
+
+ TEST_BR2_OP_TAKEN( 2, bne, 0, 1 );
+ TEST_BR2_OP_TAKEN( 3, bne, 1, 0 );
+ TEST_BR2_OP_TAKEN( 4, bne, -1, 1 );
+ TEST_BR2_OP_TAKEN( 5, bne, 1, -1 );
+
+ TEST_BR2_OP_NOTTAKEN( 6, bne, 0, 0 );
+ TEST_BR2_OP_NOTTAKEN( 7, bne, 1, 1 );
+ TEST_BR2_OP_NOTTAKEN( 8, bne, -1, -1 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_BR2_SRC12_BYPASS( 9, 0, 0, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 10, 0, 1, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 11, 0, 2, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 12, 1, 0, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 13, 1, 1, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 14, 2, 0, bne, 0, 0 );
+
+ TEST_BR2_SRC12_BYPASS( 15, 0, 0, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 16, 0, 1, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 17, 0, 2, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 18, 1, 0, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 19, 1, 1, bne, 0, 0 );
+ TEST_BR2_SRC12_BYPASS( 20, 2, 0, bne, 0, 0 );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 21, x1, 3, \
+ li x1, 1; \
+ bne x1, x0, 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/fence_i.S b/tests/fence_i.S
new file mode 100644
index 0000000..8785c1e
--- /dev/null
+++ b/tests/fence_i.S
@@ -0,0 +1,53 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# fence_i.S
+#-----------------------------------------------------------------------------
+#
+# Test self-modifying code and the fence.i instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+li a3, 111
+la a0, 3f
+la a1, 1f
+la a2, 2f
+lw a0, 0(a0)
+
+# test I$ hit
+.align 6
+sw a0, 0(a1)
+fence.i
+
+1: addi a3, a3, 222
+TEST_CASE( 2, a3, 444, nop )
+
+# test prefetcher hit
+li a4, 100
+1: addi a4, a4, -1
+bnez a4, 1b
+
+sw a0, 0(a2)
+fence.i
+
+.align 6
+2: addi a3, a3, 555
+TEST_CASE( 3, a3, 777, nop )
+
+3: addi a3, a3, 333
+
+TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/j.S b/tests/j.S
new file mode 100644
index 0000000..259a236
--- /dev/null
+++ b/tests/j.S
@@ -0,0 +1,49 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# j.S
+#-----------------------------------------------------------------------------
+#
+# Test j instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Test basic
+ #-------------------------------------------------------------
+
+ li TESTNUM, 2;
+ j test_2;
+ j fail;
+test_2:
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 3, x1, 3, \
+ li x1, 1; \
+ j 1f; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/jal.S b/tests/jal.S
new file mode 100644
index 0000000..742abac
--- /dev/null
+++ b/tests/jal.S
@@ -0,0 +1,60 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# jal.S
+#-----------------------------------------------------------------------------
+#
+# Test jal instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Test 2: Basic test
+ #-------------------------------------------------------------
+
+test_2:
+ li TESTNUM, 2
+ li ra, 0
+
+linkaddr_2:
+ jal target_2
+ nop
+ nop
+
+ j fail
+
+target_2:
+ la x2, linkaddr_2
+ addi x2, x2, 4
+ bne x2, ra, fail
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 3, x2, 3, \
+ li x2, 1; \
+ jal 1f; \
+ addi x2, x2, 1; \
+ addi x2, x2, 1; \
+ addi x2, x2, 1; \
+ addi x2, x2, 1; \
+1: addi x2, x2, 1; \
+ addi x2, x2, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/jalr.S b/tests/jalr.S
new file mode 100644
index 0000000..ebe3731
--- /dev/null
+++ b/tests/jalr.S
@@ -0,0 +1,88 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# jalr.S
+#-----------------------------------------------------------------------------
+#
+# Test jalr instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Test 2: Basic test
+ #-------------------------------------------------------------
+
+test_2:
+ li TESTNUM, 2
+ li x31, 0
+ la x2, target_2
+
+linkaddr_2:
+ jalr x19, x2, 0
+ nop
+ nop
+
+ j fail
+
+target_2:
+ la x1, linkaddr_2
+ addi x1, x1, 4
+ bne x1, x19, fail
+
+ #-------------------------------------------------------------
+ # Test 3: Check r0 target and that r31 is not modified
+ #-------------------------------------------------------------
+
+test_3:
+ li TESTNUM, 3
+ li x31, 0
+ la x3, target_3
+
+linkaddr_3:
+ jalr x0, x3, 0
+ nop
+
+ j fail
+
+target_3:
+ bne x31, x0, fail
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_JALR_SRC1_BYPASS( 4, 0, jalr );
+ TEST_JALR_SRC1_BYPASS( 5, 1, jalr );
+ TEST_JALR_SRC1_BYPASS( 6, 2, jalr );
+
+ #-------------------------------------------------------------
+ # Test delay slot instructions not executed nor bypassed
+ #-------------------------------------------------------------
+
+ TEST_CASE( 7, x1, 4, \
+ li x1, 1; \
+ la x2, 1f;
+ jalr x19, x2, -4; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ addi x1, x1, 1; \
+1: addi x1, x1, 1; \
+ addi x1, x1, 1; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/lb.S b/tests/lb.S
new file mode 100644
index 0000000..eaf7902
--- /dev/null
+++ b/tests/lb.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lb.S
+#-----------------------------------------------------------------------------
+#
+# Test lb instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_LD_OP( 2, lb, 0xffffffff, 0, tdat );
+ TEST_LD_OP( 3, lb, 0x00000000, 1, tdat );
+ TEST_LD_OP( 4, lb, 0xfffffff0, 2, tdat );
+ TEST_LD_OP( 5, lb, 0x0000000f, 3, tdat );
+
+ # Test with negative offset
+
+ TEST_LD_OP( 6, lb, 0xffffffff, -3, tdat4 );
+ TEST_LD_OP( 7, lb, 0x00000000, -2, tdat4 );
+ TEST_LD_OP( 8, lb, 0xfffffff0, -1, tdat4 );
+ TEST_LD_OP( 9, lb, 0x0000000f, 0, tdat4 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0xffffffff, \
+ la x1, tdat; \
+ addi x1, x1, -32; \
+ lb x3, 32(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0x00000000, \
+ la x1, tdat; \
+ addi x1, x1, -6; \
+ lb x3, 7(x1); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_LD_DEST_BYPASS( 12, 0, lb, 0xfffffff0, 1, tdat2 );
+ TEST_LD_DEST_BYPASS( 13, 1, lb, 0x0000000f, 1, tdat3 );
+ TEST_LD_DEST_BYPASS( 14, 2, lb, 0x00000000, 1, tdat1 );
+
+ TEST_LD_SRC1_BYPASS( 15, 0, lb, 0xfffffff0, 1, tdat2 );
+ TEST_LD_SRC1_BYPASS( 16, 1, lb, 0x0000000f, 1, tdat3 );
+ TEST_LD_SRC1_BYPASS( 17, 2, lb, 0x00000000, 1, tdat1 );
+
+ #-------------------------------------------------------------
+ # Test write-after-write hazard
+ #-------------------------------------------------------------
+
+ TEST_CASE( 18, x2, 2, \
+ la x3, tdat; \
+ lb x2, 0(x3); \
+ li x2, 2; \
+ )
+
+ TEST_CASE( 19, x2, 2, \
+ la x3, tdat; \
+ lb x2, 0(x3); \
+ nop; \
+ li x2, 2; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .byte 0xff
+tdat2: .byte 0x00
+tdat3: .byte 0xf0
+tdat4: .byte 0x0f
+
+RVTEST_DATA_END
diff --git a/tests/lbu.S b/tests/lbu.S
new file mode 100644
index 0000000..027b643
--- /dev/null
+++ b/tests/lbu.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lbu.S
+#-----------------------------------------------------------------------------
+#
+# Test lbu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_LD_OP( 2, lbu, 0x000000ff, 0, tdat );
+ TEST_LD_OP( 3, lbu, 0x00000000, 1, tdat );
+ TEST_LD_OP( 4, lbu, 0x000000f0, 2, tdat );
+ TEST_LD_OP( 5, lbu, 0x0000000f, 3, tdat );
+
+ # Test with negative offset
+
+ TEST_LD_OP( 6, lbu, 0x000000ff, -3, tdat4 );
+ TEST_LD_OP( 7, lbu, 0x00000000, -2, tdat4 );
+ TEST_LD_OP( 8, lbu, 0x000000f0, -1, tdat4 );
+ TEST_LD_OP( 9, lbu, 0x0000000f, 0, tdat4 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x000000ff, \
+ la x1, tdat; \
+ addi x1, x1, -32; \
+ lbu x3, 32(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0x00000000, \
+ la x1, tdat; \
+ addi x1, x1, -6; \
+ lbu x3, 7(x1); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_LD_DEST_BYPASS( 12, 0, lbu, 0x000000f0, 1, tdat2 );
+ TEST_LD_DEST_BYPASS( 13, 1, lbu, 0x0000000f, 1, tdat3 );
+ TEST_LD_DEST_BYPASS( 14, 2, lbu, 0x00000000, 1, tdat1 );
+
+ TEST_LD_SRC1_BYPASS( 15, 0, lbu, 0x000000f0, 1, tdat2 );
+ TEST_LD_SRC1_BYPASS( 16, 1, lbu, 0x0000000f, 1, tdat3 );
+ TEST_LD_SRC1_BYPASS( 17, 2, lbu, 0x00000000, 1, tdat1 );
+
+ #-------------------------------------------------------------
+ # Test write-after-write hazard
+ #-------------------------------------------------------------
+
+ TEST_CASE( 18, x2, 2, \
+ la x3, tdat; \
+ lbu x2, 0(x3); \
+ li x2, 2; \
+ )
+
+ TEST_CASE( 19, x2, 2, \
+ la x3, tdat; \
+ lbu x2, 0(x3); \
+ nop; \
+ li x2, 2; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .byte 0xff
+tdat2: .byte 0x00
+tdat3: .byte 0xf0
+tdat4: .byte 0x0f
+
+RVTEST_DATA_END
diff --git a/tests/lh.S b/tests/lh.S
new file mode 100644
index 0000000..d8eda91
--- /dev/null
+++ b/tests/lh.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lh.S
+#-----------------------------------------------------------------------------
+#
+# Test lh instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_LD_OP( 2, lh, 0x000000ff, 0, tdat );
+ TEST_LD_OP( 3, lh, 0xffffff00, 2, tdat );
+ TEST_LD_OP( 4, lh, 0x00000ff0, 4, tdat );
+ TEST_LD_OP( 5, lh, 0xfffff00f, 6, tdat );
+
+ # Test with negative offset
+
+ TEST_LD_OP( 6, lh, 0x000000ff, -6, tdat4 );
+ TEST_LD_OP( 7, lh, 0xffffff00, -4, tdat4 );
+ TEST_LD_OP( 8, lh, 0x00000ff0, -2, tdat4 );
+ TEST_LD_OP( 9, lh, 0xfffff00f, 0, tdat4 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x000000ff, \
+ la x1, tdat; \
+ addi x1, x1, -32; \
+ lh x3, 32(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0xffffff00, \
+ la x1, tdat; \
+ addi x1, x1, -5; \
+ lh x3, 7(x1); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_LD_DEST_BYPASS( 12, 0, lh, 0x00000ff0, 2, tdat2 );
+ TEST_LD_DEST_BYPASS( 13, 1, lh, 0xfffff00f, 2, tdat3 );
+ TEST_LD_DEST_BYPASS( 14, 2, lh, 0xffffff00, 2, tdat1 );
+
+ TEST_LD_SRC1_BYPASS( 15, 0, lh, 0x00000ff0, 2, tdat2 );
+ TEST_LD_SRC1_BYPASS( 16, 1, lh, 0xfffff00f, 2, tdat3 );
+ TEST_LD_SRC1_BYPASS( 17, 2, lh, 0xffffff00, 2, tdat1 );
+
+ #-------------------------------------------------------------
+ # Test write-after-write hazard
+ #-------------------------------------------------------------
+
+ TEST_CASE( 18, x2, 2, \
+ la x3, tdat; \
+ lh x2, 0(x3); \
+ li x2, 2; \
+ )
+
+ TEST_CASE( 19, x2, 2, \
+ la x3, tdat; \
+ lh x2, 0(x3); \
+ nop; \
+ li x2, 2; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .half 0x00ff
+tdat2: .half 0xff00
+tdat3: .half 0x0ff0
+tdat4: .half 0xf00f
+
+RVTEST_DATA_END
diff --git a/tests/lhu.S b/tests/lhu.S
new file mode 100644
index 0000000..71daec6
--- /dev/null
+++ b/tests/lhu.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lhu.S
+#-----------------------------------------------------------------------------
+#
+# Test lhu instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_LD_OP( 2, lhu, 0x000000ff, 0, tdat );
+ TEST_LD_OP( 3, lhu, 0x0000ff00, 2, tdat );
+ TEST_LD_OP( 4, lhu, 0x00000ff0, 4, tdat );
+ TEST_LD_OP( 5, lhu, 0x0000f00f, 6, tdat );
+
+ # Test with negative offset
+
+ TEST_LD_OP( 6, lhu, 0x000000ff, -6, tdat4 );
+ TEST_LD_OP( 7, lhu, 0x0000ff00, -4, tdat4 );
+ TEST_LD_OP( 8, lhu, 0x00000ff0, -2, tdat4 );
+ TEST_LD_OP( 9, lhu, 0x0000f00f, 0, tdat4 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x000000ff, \
+ la x1, tdat; \
+ addi x1, x1, -32; \
+ lhu x3, 32(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0x0000ff00, \
+ la x1, tdat; \
+ addi x1, x1, -5; \
+ lhu x3, 7(x1); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_LD_DEST_BYPASS( 12, 0, lhu, 0x00000ff0, 2, tdat2 );
+ TEST_LD_DEST_BYPASS( 13, 1, lhu, 0x0000f00f, 2, tdat3 );
+ TEST_LD_DEST_BYPASS( 14, 2, lhu, 0x0000ff00, 2, tdat1 );
+
+ TEST_LD_SRC1_BYPASS( 15, 0, lhu, 0x00000ff0, 2, tdat2 );
+ TEST_LD_SRC1_BYPASS( 16, 1, lhu, 0x0000f00f, 2, tdat3 );
+ TEST_LD_SRC1_BYPASS( 17, 2, lhu, 0x0000ff00, 2, tdat1 );
+
+ #-------------------------------------------------------------
+ # Test write-after-write hazard
+ #-------------------------------------------------------------
+
+ TEST_CASE( 18, x2, 2, \
+ la x3, tdat; \
+ lhu x2, 0(x3); \
+ li x2, 2; \
+ )
+
+ TEST_CASE( 19, x2, 2, \
+ la x3, tdat; \
+ lhu x2, 0(x3); \
+ nop; \
+ li x2, 2; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .half 0x00ff
+tdat2: .half 0xff00
+tdat3: .half 0x0ff0
+tdat4: .half 0xf00f
+
+RVTEST_DATA_END
diff --git a/tests/lui.S b/tests/lui.S
new file mode 100644
index 0000000..50822d1
--- /dev/null
+++ b/tests/lui.S
@@ -0,0 +1,36 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lui.S
+#-----------------------------------------------------------------------------
+#
+# Test lui instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_CASE( 2, x1, 0x00000000, lui x1, 0x00000 );
+ TEST_CASE( 3, x1, 0xfffff800, lui x1, 0xfffff;sra x1,x1,1);
+ TEST_CASE( 4, x1, 0x000007ff, lui x1, 0x7ffff;sra x1,x1,20);
+ TEST_CASE( 5, x1, 0xfffff800, lui x1, 0x80000;sra x1,x1,20);
+
+ TEST_CASE( 6, x0, 0, lui x0, 0x80000 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/lw.S b/tests/lw.S
new file mode 100644
index 0000000..4a07838
--- /dev/null
+++ b/tests/lw.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# lw.S
+#-----------------------------------------------------------------------------
+#
+# Test lw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_LD_OP( 2, lw, 0x00ff00ff, 0, tdat );
+ TEST_LD_OP( 3, lw, 0xff00ff00, 4, tdat );
+ TEST_LD_OP( 4, lw, 0x0ff00ff0, 8, tdat );
+ TEST_LD_OP( 5, lw, 0xf00ff00f, 12, tdat );
+
+ # Test with negative offset
+
+ TEST_LD_OP( 6, lw, 0x00ff00ff, -12, tdat4 );
+ TEST_LD_OP( 7, lw, 0xff00ff00, -8, tdat4 );
+ TEST_LD_OP( 8, lw, 0x0ff00ff0, -4, tdat4 );
+ TEST_LD_OP( 9, lw, 0xf00ff00f, 0, tdat4 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x00ff00ff, \
+ la x1, tdat; \
+ addi x1, x1, -32; \
+ lw x3, 32(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0xff00ff00, \
+ la x1, tdat; \
+ addi x1, x1, -3; \
+ lw x3, 7(x1); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_LD_DEST_BYPASS( 12, 0, lw, 0x0ff00ff0, 4, tdat2 );
+ TEST_LD_DEST_BYPASS( 13, 1, lw, 0xf00ff00f, 4, tdat3 );
+ TEST_LD_DEST_BYPASS( 14, 2, lw, 0xff00ff00, 4, tdat1 );
+
+ TEST_LD_SRC1_BYPASS( 15, 0, lw, 0x0ff00ff0, 4, tdat2 );
+ TEST_LD_SRC1_BYPASS( 16, 1, lw, 0xf00ff00f, 4, tdat3 );
+ TEST_LD_SRC1_BYPASS( 17, 2, lw, 0xff00ff00, 4, tdat1 );
+
+ #-------------------------------------------------------------
+ # Test write-after-write hazard
+ #-------------------------------------------------------------
+
+ TEST_CASE( 18, x2, 2, \
+ la x3, tdat; \
+ lw x2, 0(x3); \
+ li x2, 2; \
+ )
+
+ TEST_CASE( 19, x2, 2, \
+ la x3, tdat; \
+ lw x2, 0(x3); \
+ nop; \
+ li x2, 2; \
+ )
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .word 0x00ff00ff
+tdat2: .word 0xff00ff00
+tdat3: .word 0x0ff00ff0
+tdat4: .word 0xf00ff00f
+
+RVTEST_DATA_END
diff --git a/tests/or.S b/tests/or.S
new file mode 100644
index 0000000..110bcc4
--- /dev/null
+++ b/tests/or.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# or.S
+#-----------------------------------------------------------------------------
+#
+# Test or instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_OP( 3, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_OP( 4, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_OP( 5, or, 0xf0fff0ff, 0xf00ff00f, 0xf0f0f0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 6, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC2_EQ_DEST( 7, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_EQ_DEST( 8, or, 0xff00ff00, 0xff00ff00 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 9, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_DEST_BYPASS( 10, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_DEST_BYPASS( 11, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC12_BYPASS( 12, 0, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 13, 0, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 14, 0, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 15, 1, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 16, 1, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 17, 2, 0, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC21_BYPASS( 18, 0, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 19, 0, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 20, 0, 2, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 21, 1, 0, or, 0xff0fff0f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 22, 1, 1, or, 0xfff0fff0, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 23, 2, 0, or, 0x0fff0fff, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_ZEROSRC1( 24, or, 0xff00ff00, 0xff00ff00 );
+ TEST_RR_ZEROSRC2( 25, or, 0x00ff00ff, 0x00ff00ff );
+ TEST_RR_ZEROSRC12( 26, or, 0 );
+ TEST_RR_ZERODEST( 27, or, 0x11111111, 0x22222222 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/ori.S b/tests/ori.S
new file mode 100644
index 0000000..a674784
--- /dev/null
+++ b/tests/ori.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ori.S
+#-----------------------------------------------------------------------------
+#
+# Test ori instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, ori, 0xffffff0f, 0xff00ff00, 0xf0f );
+ TEST_IMM_OP( 3, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_OP( 4, ori, 0x00ff07ff, 0x00ff00ff, 0x70f );
+ TEST_IMM_OP( 5, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 6, ori, 0xff00fff0, 0xff00ff00, 0x0f0 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 7, 0, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_DEST_BYPASS( 8, 1, ori, 0x00ff07ff, 0x00ff00ff, 0x70f );
+ TEST_IMM_DEST_BYPASS( 9, 2, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ TEST_IMM_SRC1_BYPASS( 10, 0, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_SRC1_BYPASS( 11, 1, ori, 0xffffffff, 0x00ff00ff, 0xf0f );
+ TEST_IMM_SRC1_BYPASS( 12, 2, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ TEST_IMM_ZEROSRC1( 13, ori, 0x0f0, 0x0f0 );
+ TEST_IMM_ZERODEST( 14, ori, 0x00ff00ff, 0x70f );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/riscv_test.h b/tests/riscv_test.h
new file mode 100644
index 0000000..6c0eb80
--- /dev/null
+++ b/tests/riscv_test.h
@@ -0,0 +1,64 @@
+#ifndef _ENV_PICORV32_TEST_H
+#define _ENV_PICORV32_TEST_H
+
+#ifndef TEST_FUNC_NAME
+# define TEST_FUNC_NAME mytest
+# define TEST_FUNC_TXT "mytest"
+# define TEST_FUNC_RET mytest_ret
+#endif
+
+#define RVTEST_RV32U
+#define TESTNUM x28
+
+#define RVTEST_CODE_BEGIN \
+ .text; \
+ .global TEST_FUNC_NAME; \
+ .global TEST_FUNC_RET; \
+TEST_FUNC_NAME: \
+ lui a0,%hi(.test_name); \
+ addi a0,a0,%lo(.test_name); \
+ lui a2,0x10000000>>12; \
+.prname_next: \
+ lb a1,0(a0); \
+ beq a1,zero,.prname_done; \
+ sw a1,0(a2); \
+ addi a0,a0,1; \
+ jal zero,.prname_next; \
+.test_name: \
+ .ascii TEST_FUNC_TXT; \
+ .byte 0x00; \
+ .balign 4; \
+.prname_done: \
+ addi a1,zero,'.'; \
+ sw a1,0(a2); \
+ sw a1,0(a2);
+
+#define RVTEST_PASS \
+ lui a0,0x10000000>>12; \
+ addi a1,zero,'O'; \
+ addi a2,zero,'K'; \
+ addi a3,zero,'\n'; \
+ sw a1,0(a0); \
+ sw a2,0(a0); \
+ sw a3,0(a0); \
+ jal zero,TEST_FUNC_RET;
+
+#define RVTEST_FAIL \
+ lui a0,0x10000000>>12; \
+ addi a1,zero,'E'; \
+ addi a2,zero,'R'; \
+ addi a3,zero,'O'; \
+ addi a4,zero,'\n'; \
+ sw a1,0(a0); \
+ sw a2,0(a0); \
+ sw a2,0(a0); \
+ sw a3,0(a0); \
+ sw a2,0(a0); \
+ sw a4,0(a0); \
+ sbreak;
+
+#define RVTEST_CODE_END
+#define RVTEST_DATA_BEGIN .balign 4;
+#define RVTEST_DATA_END
+
+#endif
diff --git a/tests/sb.S b/tests/sb.S
new file mode 100644
index 0000000..1a8598c
--- /dev/null
+++ b/tests/sb.S
@@ -0,0 +1,102 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sb.S
+#-----------------------------------------------------------------------------
+#
+# Test sb instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_ST_OP( 2, lb, sb, 0xffffffaa, 0, tdat );
+ TEST_ST_OP( 3, lb, sb, 0x00000000, 1, tdat );
+#ifdef __RISCVEL
+ TEST_ST_OP( 4, lh, sb, 0xffffefa0, 2, tdat );
+#elif defined(__RISCVEB)
+#else
+ TEST_ST_OP( 4, lh, sb, 0xffffa0ef, 2, tdat );
+#error unknown endianness!
+#endif
+ TEST_ST_OP( 5, lb, sb, 0x0000000a, 3, tdat );
+
+ # Test with negative offset
+
+ TEST_ST_OP( 6, lb, sb, 0xffffffaa, -3, tdat8 );
+ TEST_ST_OP( 7, lb, sb, 0x00000000, -2, tdat8 );
+ TEST_ST_OP( 8, lb, sb, 0xffffffa0, -1, tdat8 );
+ TEST_ST_OP( 9, lb, sb, 0x0000000a, 0, tdat8 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x78, \
+ la x1, tdat9; \
+ li x2, 0x12345678; \
+ addi x4, x1, -32; \
+ sb x2, 32(x4); \
+ lb x3, 0(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0xffffff98, \
+ la x1, tdat9; \
+ li x2, 0x00003098; \
+ addi x1, x1, -6; \
+ sb x2, 7(x1); \
+ la x4, tdat10; \
+ lb x3, 0(x4); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_ST_SRC12_BYPASS( 12, 0, 0, lb, sb, 0xffffffdd, 0, tdat );
+ TEST_ST_SRC12_BYPASS( 13, 0, 1, lb, sb, 0xffffffcd, 1, tdat );
+ TEST_ST_SRC12_BYPASS( 14, 0, 2, lb, sb, 0xffffffcc, 2, tdat );
+ TEST_ST_SRC12_BYPASS( 15, 1, 0, lb, sb, 0xffffffbc, 3, tdat );
+ TEST_ST_SRC12_BYPASS( 16, 1, 1, lb, sb, 0xffffffbb, 4, tdat );
+ TEST_ST_SRC12_BYPASS( 17, 2, 0, lb, sb, 0xffffffab, 5, tdat );
+
+ TEST_ST_SRC21_BYPASS( 18, 0, 0, lb, sb, 0x33, 0, tdat );
+ TEST_ST_SRC21_BYPASS( 19, 0, 1, lb, sb, 0x23, 1, tdat );
+ TEST_ST_SRC21_BYPASS( 20, 0, 2, lb, sb, 0x22, 2, tdat );
+ TEST_ST_SRC21_BYPASS( 21, 1, 0, lb, sb, 0x12, 3, tdat );
+ TEST_ST_SRC21_BYPASS( 22, 1, 1, lb, sb, 0x11, 4, tdat );
+ TEST_ST_SRC21_BYPASS( 23, 2, 0, lb, sb, 0x01, 5, tdat );
+
+ li a0, 0xef
+ la a1, tdat
+ sb a0, 3(a1)
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .byte 0xef
+tdat2: .byte 0xef
+tdat3: .byte 0xef
+tdat4: .byte 0xef
+tdat5: .byte 0xef
+tdat6: .byte 0xef
+tdat7: .byte 0xef
+tdat8: .byte 0xef
+tdat9: .byte 0xef
+tdat10: .byte 0xef
+
+RVTEST_DATA_END
diff --git a/tests/sh.S b/tests/sh.S
new file mode 100644
index 0000000..6c464e5
--- /dev/null
+++ b/tests/sh.S
@@ -0,0 +1,102 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sh.S
+#-----------------------------------------------------------------------------
+#
+# Test sh instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_ST_OP( 2, lh, sh, 0x000000aa, 0, tdat );
+ TEST_ST_OP( 3, lh, sh, 0xffffaa00, 2, tdat );
+#ifdef __RISCVEL
+ TEST_ST_OP( 4, lw, sh, 0xbeef0aa0, 4, tdat );
+#elif defined(__RISCVEB)
+#else
+ TEST_ST_OP( 4, lw, sh, 0x0aa0beef, 4, tdat );
+#error unknown endianness!
+#endif
+ TEST_ST_OP( 5, lh, sh, 0xffffa00a, 6, tdat );
+
+ # Test with negative offset
+
+ TEST_ST_OP( 6, lh, sh, 0x000000aa, -6, tdat8 );
+ TEST_ST_OP( 7, lh, sh, 0xffffaa00, -4, tdat8 );
+ TEST_ST_OP( 8, lh, sh, 0x00000aa0, -2, tdat8 );
+ TEST_ST_OP( 9, lh, sh, 0xffffa00a, 0, tdat8 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x5678, \
+ la x1, tdat9; \
+ li x2, 0x12345678; \
+ addi x4, x1, -32; \
+ sh x2, 32(x4); \
+ lh x3, 0(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0x3098, \
+ la x1, tdat9; \
+ li x2, 0x00003098; \
+ addi x1, x1, -5; \
+ sh x2, 7(x1); \
+ la x4, tdat10; \
+ lh x3, 0(x4); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_ST_SRC12_BYPASS( 12, 0, 0, lh, sh, 0xffffccdd, 0, tdat );
+ TEST_ST_SRC12_BYPASS( 13, 0, 1, lh, sh, 0xffffbccd, 2, tdat );
+ TEST_ST_SRC12_BYPASS( 14, 0, 2, lh, sh, 0xffffbbcc, 4, tdat );
+ TEST_ST_SRC12_BYPASS( 15, 1, 0, lh, sh, 0xffffabbc, 6, tdat );
+ TEST_ST_SRC12_BYPASS( 16, 1, 1, lh, sh, 0xffffaabb, 8, tdat );
+ TEST_ST_SRC12_BYPASS( 17, 2, 0, lh, sh, 0xffffdaab, 10, tdat );
+
+ TEST_ST_SRC21_BYPASS( 18, 0, 0, lh, sh, 0x2233, 0, tdat );
+ TEST_ST_SRC21_BYPASS( 19, 0, 1, lh, sh, 0x1223, 2, tdat );
+ TEST_ST_SRC21_BYPASS( 20, 0, 2, lh, sh, 0x1122, 4, tdat );
+ TEST_ST_SRC21_BYPASS( 21, 1, 0, lh, sh, 0x0112, 6, tdat );
+ TEST_ST_SRC21_BYPASS( 22, 1, 1, lh, sh, 0x0011, 8, tdat );
+ TEST_ST_SRC21_BYPASS( 23, 2, 0, lh, sh, 0x3001, 10, tdat );
+
+ li a0, 0xbeef
+ la a1, tdat
+ sh a0, 6(a1)
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .half 0xbeef
+tdat2: .half 0xbeef
+tdat3: .half 0xbeef
+tdat4: .half 0xbeef
+tdat5: .half 0xbeef
+tdat6: .half 0xbeef
+tdat7: .half 0xbeef
+tdat8: .half 0xbeef
+tdat9: .half 0xbeef
+tdat10: .half 0xbeef
+
+RVTEST_DATA_END
diff --git a/tests/simple.S b/tests/simple.S
new file mode 100644
index 0000000..92cf203
--- /dev/null
+++ b/tests/simple.S
@@ -0,0 +1,27 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# simple.S
+#-----------------------------------------------------------------------------
+#
+# This is the most basic self checking test. If your simulator does not
+# pass thiss then there is little chance that it will pass any of the
+# more complicated self checking tests.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+RVTEST_PASS
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/sll.S b/tests/sll.S
new file mode 100644
index 0000000..d297ac5
--- /dev/null
+++ b/tests/sll.S
@@ -0,0 +1,90 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sll.S
+#-----------------------------------------------------------------------------
+#
+# Test sll instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, sll, 0x00000001, 0x00000001, 0 );
+ TEST_RR_OP( 3, sll, 0x00000002, 0x00000001, 1 );
+ TEST_RR_OP( 4, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_OP( 5, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_OP( 6, sll, 0x80000000, 0x00000001, 31 );
+
+ TEST_RR_OP( 7, sll, 0xffffffff, 0xffffffff, 0 );
+ TEST_RR_OP( 8, sll, 0xfffffffe, 0xffffffff, 1 );
+ TEST_RR_OP( 9, sll, 0xffffff80, 0xffffffff, 7 );
+ TEST_RR_OP( 10, sll, 0xffffc000, 0xffffffff, 14 );
+ TEST_RR_OP( 11, sll, 0x80000000, 0xffffffff, 31 );
+
+ TEST_RR_OP( 12, sll, 0x21212121, 0x21212121, 0 );
+ TEST_RR_OP( 13, sll, 0x42424242, 0x21212121, 1 );
+ TEST_RR_OP( 14, sll, 0x90909080, 0x21212121, 7 );
+ TEST_RR_OP( 15, sll, 0x48484000, 0x21212121, 14 );
+ TEST_RR_OP( 16, sll, 0x80000000, 0x21212121, 31 );
+
+ # Verify that shifts only use bottom five bits
+
+ TEST_RR_OP( 17, sll, 0x21212121, 0x21212121, 0xffffffe0 );
+ TEST_RR_OP( 18, sll, 0x42424242, 0x21212121, 0xffffffe1 );
+ TEST_RR_OP( 19, sll, 0x90909080, 0x21212121, 0xffffffe7 );
+ TEST_RR_OP( 20, sll, 0x48484000, 0x21212121, 0xffffffee );
+ TEST_RR_OP( 21, sll, 0x00000000, 0x21212120, 0xffffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 22, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_SRC2_EQ_DEST( 23, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_SRC12_EQ_DEST( 24, sll, 24, 3 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 25, 0, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_DEST_BYPASS( 26, 1, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_DEST_BYPASS( 27, 2, sll, 0x80000000, 0x00000001, 31 );
+
+ TEST_RR_SRC12_BYPASS( 28, 0, 0, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_SRC12_BYPASS( 29, 0, 1, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_SRC12_BYPASS( 30, 0, 2, sll, 0x80000000, 0x00000001, 31 );
+ TEST_RR_SRC12_BYPASS( 31, 1, 0, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_SRC12_BYPASS( 32, 1, 1, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_SRC12_BYPASS( 33, 2, 0, sll, 0x80000000, 0x00000001, 31 );
+
+ TEST_RR_SRC21_BYPASS( 34, 0, 0, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_SRC21_BYPASS( 35, 0, 1, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_SRC21_BYPASS( 36, 0, 2, sll, 0x80000000, 0x00000001, 31 );
+ TEST_RR_SRC21_BYPASS( 37, 1, 0, sll, 0x00000080, 0x00000001, 7 );
+ TEST_RR_SRC21_BYPASS( 38, 1, 1, sll, 0x00004000, 0x00000001, 14 );
+ TEST_RR_SRC21_BYPASS( 39, 2, 0, sll, 0x80000000, 0x00000001, 31 );
+
+ TEST_RR_ZEROSRC1( 40, sll, 0, 15 );
+ TEST_RR_ZEROSRC2( 41, sll, 32, 32 );
+ TEST_RR_ZEROSRC12( 42, sll, 0 );
+ TEST_RR_ZERODEST( 43, sll, 1024, 2048 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/slli.S b/tests/slli.S
new file mode 100644
index 0000000..a51eec9
--- /dev/null
+++ b/tests/slli.S
@@ -0,0 +1,68 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slli.S
+#-----------------------------------------------------------------------------
+#
+# Test slli instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, slli, 0x00000001, 0x00000001, 0 );
+ TEST_IMM_OP( 3, slli, 0x00000002, 0x00000001, 1 );
+ TEST_IMM_OP( 4, slli, 0x00000080, 0x00000001, 7 );
+ TEST_IMM_OP( 5, slli, 0x00004000, 0x00000001, 14 );
+ TEST_IMM_OP( 6, slli, 0x80000000, 0x00000001, 31 );
+
+ TEST_IMM_OP( 7, slli, 0xffffffff, 0xffffffff, 0 );
+ TEST_IMM_OP( 8, slli, 0xfffffffe, 0xffffffff, 1 );
+ TEST_IMM_OP( 9, slli, 0xffffff80, 0xffffffff, 7 );
+ TEST_IMM_OP( 10, slli, 0xffffc000, 0xffffffff, 14 );
+ TEST_IMM_OP( 11, slli, 0x80000000, 0xffffffff, 31 );
+
+ TEST_IMM_OP( 12, slli, 0x21212121, 0x21212121, 0 );
+ TEST_IMM_OP( 13, slli, 0x42424242, 0x21212121, 1 );
+ TEST_IMM_OP( 14, slli, 0x90909080, 0x21212121, 7 );
+ TEST_IMM_OP( 15, slli, 0x48484000, 0x21212121, 14 );
+ TEST_IMM_OP( 16, slli, 0x80000000, 0x21212121, 31 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 17, slli, 0x00000080, 0x00000001, 7 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 18, 0, slli, 0x00000080, 0x00000001, 7 );
+ TEST_IMM_DEST_BYPASS( 19, 1, slli, 0x00004000, 0x00000001, 14 );
+ TEST_IMM_DEST_BYPASS( 20, 2, slli, 0x80000000, 0x00000001, 31 );
+
+ TEST_IMM_SRC1_BYPASS( 21, 0, slli, 0x00000080, 0x00000001, 7 );
+ TEST_IMM_SRC1_BYPASS( 22, 1, slli, 0x00004000, 0x00000001, 14 );
+ TEST_IMM_SRC1_BYPASS( 23, 2, slli, 0x80000000, 0x00000001, 31 );
+
+ TEST_IMM_ZEROSRC1( 24, slli, 0, 31 );
+ TEST_IMM_ZERODEST( 25, slli, 33, 20 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/slt.S b/tests/slt.S
new file mode 100644
index 0000000..3abf82b
--- /dev/null
+++ b/tests/slt.S
@@ -0,0 +1,84 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slt.S
+#-----------------------------------------------------------------------------
+#
+# Test slt instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, slt, 0, 0x00000000, 0x00000000 );
+ TEST_RR_OP( 3, slt, 0, 0x00000001, 0x00000001 );
+ TEST_RR_OP( 4, slt, 1, 0x00000003, 0x00000007 );
+ TEST_RR_OP( 5, slt, 0, 0x00000007, 0x00000003 );
+
+ TEST_RR_OP( 6, slt, 0, 0x00000000, 0xffff8000 );
+ TEST_RR_OP( 7, slt, 1, 0x80000000, 0x00000000 );
+ TEST_RR_OP( 8, slt, 1, 0x80000000, 0xffff8000 );
+
+ TEST_RR_OP( 9, slt, 1, 0x00000000, 0x00007fff );
+ TEST_RR_OP( 10, slt, 0, 0x7fffffff, 0x00000000 );
+ TEST_RR_OP( 11, slt, 0, 0x7fffffff, 0x00007fff );
+
+ TEST_RR_OP( 12, slt, 1, 0x80000000, 0x00007fff );
+ TEST_RR_OP( 13, slt, 0, 0x7fffffff, 0xffff8000 );
+
+ TEST_RR_OP( 14, slt, 0, 0x00000000, 0xffffffff );
+ TEST_RR_OP( 15, slt, 1, 0xffffffff, 0x00000001 );
+ TEST_RR_OP( 16, slt, 0, 0xffffffff, 0xffffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 17, slt, 0, 14, 13 );
+ TEST_RR_SRC2_EQ_DEST( 18, slt, 1, 11, 13 );
+ TEST_RR_SRC12_EQ_DEST( 19, slt, 0, 13 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 20, 0, slt, 1, 11, 13 );
+ TEST_RR_DEST_BYPASS( 21, 1, slt, 0, 14, 13 );
+ TEST_RR_DEST_BYPASS( 22, 2, slt, 1, 12, 13 );
+
+ TEST_RR_SRC12_BYPASS( 23, 0, 0, slt, 0, 14, 13 );
+ TEST_RR_SRC12_BYPASS( 24, 0, 1, slt, 1, 11, 13 );
+ TEST_RR_SRC12_BYPASS( 25, 0, 2, slt, 0, 15, 13 );
+ TEST_RR_SRC12_BYPASS( 26, 1, 0, slt, 1, 10, 13 );
+ TEST_RR_SRC12_BYPASS( 27, 1, 1, slt, 0, 16, 13 );
+ TEST_RR_SRC12_BYPASS( 28, 2, 0, slt, 1, 9, 13 );
+
+ TEST_RR_SRC21_BYPASS( 29, 0, 0, slt, 0, 17, 13 );
+ TEST_RR_SRC21_BYPASS( 30, 0, 1, slt, 1, 8, 13 );
+ TEST_RR_SRC21_BYPASS( 31, 0, 2, slt, 0, 18, 13 );
+ TEST_RR_SRC21_BYPASS( 32, 1, 0, slt, 1, 7, 13 );
+ TEST_RR_SRC21_BYPASS( 33, 1, 1, slt, 0, 19, 13 );
+ TEST_RR_SRC21_BYPASS( 34, 2, 0, slt, 1, 6, 13 );
+
+ TEST_RR_ZEROSRC1( 35, slt, 0, -1 );
+ TEST_RR_ZEROSRC2( 36, slt, 1, -1 );
+ TEST_RR_ZEROSRC12( 37, slt, 0 );
+ TEST_RR_ZERODEST( 38, slt, 16, 30 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/slti.S b/tests/slti.S
new file mode 100644
index 0000000..730cbe2
--- /dev/null
+++ b/tests/slti.S
@@ -0,0 +1,70 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# slti.S
+#-----------------------------------------------------------------------------
+#
+# Test slti instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, slti, 0, 0x00000000, 0x000 );
+ TEST_IMM_OP( 3, slti, 0, 0x00000001, 0x001 );
+ TEST_IMM_OP( 4, slti, 1, 0x00000003, 0x007 );
+ TEST_IMM_OP( 5, slti, 0, 0x00000007, 0x003 );
+
+ TEST_IMM_OP( 6, slti, 0, 0x00000000, 0x800 );
+ TEST_IMM_OP( 7, slti, 1, 0x80000000, 0x000 );
+ TEST_IMM_OP( 8, slti, 1, 0x80000000, 0x800 );
+
+ TEST_IMM_OP( 9, slti, 1, 0x00000000, 0x7ff );
+ TEST_IMM_OP( 10, slti, 0, 0x7fffffff, 0x000 );
+ TEST_IMM_OP( 11, slti, 0, 0x7fffffff, 0x7ff );
+
+ TEST_IMM_OP( 12, slti, 1, 0x80000000, 0x7ff );
+ TEST_IMM_OP( 13, slti, 0, 0x7fffffff, 0x800 );
+
+ TEST_IMM_OP( 14, slti, 0, 0x00000000, 0xfff );
+ TEST_IMM_OP( 15, slti, 1, 0xffffffff, 0x001 );
+ TEST_IMM_OP( 16, slti, 0, 0xffffffff, 0xfff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 17, sltiu, 1, 11, 13 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 18, 0, slti, 0, 15, 10 );
+ TEST_IMM_DEST_BYPASS( 19, 1, slti, 1, 10, 16 );
+ TEST_IMM_DEST_BYPASS( 20, 2, slti, 0, 16, 9 );
+
+ TEST_IMM_SRC1_BYPASS( 21, 0, slti, 1, 11, 15 );
+ TEST_IMM_SRC1_BYPASS( 22, 1, slti, 0, 17, 8 );
+ TEST_IMM_SRC1_BYPASS( 23, 2, slti, 1, 12, 14 );
+
+ TEST_IMM_ZEROSRC1( 24, slti, 0, 0xfff );
+ TEST_IMM_ZERODEST( 25, slti, 0x00ff00ff, 0xfff );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/sra.S b/tests/sra.S
new file mode 100644
index 0000000..8c1de36
--- /dev/null
+++ b/tests/sra.S
@@ -0,0 +1,90 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sra.S
+#-----------------------------------------------------------------------------
+#
+# Test sra instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, sra, 0x80000000, 0x80000000, 0 );
+ TEST_RR_OP( 3, sra, 0xc0000000, 0x80000000, 1 );
+ TEST_RR_OP( 4, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_OP( 5, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_OP( 6, sra, 0xffffffff, 0x80000001, 31 );
+
+ TEST_RR_OP( 7, sra, 0x7fffffff, 0x7fffffff, 0 );
+ TEST_RR_OP( 8, sra, 0x3fffffff, 0x7fffffff, 1 );
+ TEST_RR_OP( 9, sra, 0x00ffffff, 0x7fffffff, 7 );
+ TEST_RR_OP( 10, sra, 0x0001ffff, 0x7fffffff, 14 );
+ TEST_RR_OP( 11, sra, 0x00000000, 0x7fffffff, 31 );
+
+ TEST_RR_OP( 12, sra, 0x81818181, 0x81818181, 0 );
+ TEST_RR_OP( 13, sra, 0xc0c0c0c0, 0x81818181, 1 );
+ TEST_RR_OP( 14, sra, 0xff030303, 0x81818181, 7 );
+ TEST_RR_OP( 15, sra, 0xfffe0606, 0x81818181, 14 );
+ TEST_RR_OP( 16, sra, 0xffffffff, 0x81818181, 31 );
+
+ # Verify that shifts only use bottom five bits
+
+ TEST_RR_OP( 17, sra, 0x81818181, 0x81818181, 0xffffffc0 );
+ TEST_RR_OP( 18, sra, 0xc0c0c0c0, 0x81818181, 0xffffffc1 );
+ TEST_RR_OP( 19, sra, 0xff030303, 0x81818181, 0xffffffc7 );
+ TEST_RR_OP( 20, sra, 0xfffe0606, 0x81818181, 0xffffffce );
+ TEST_RR_OP( 21, sra, 0xffffffff, 0x81818181, 0xffffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 22, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_SRC2_EQ_DEST( 23, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_SRC12_EQ_DEST( 24, sra, 0, 7 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 25, 0, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_DEST_BYPASS( 26, 1, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_DEST_BYPASS( 27, 2, sra, 0xffffffff, 0x80000000, 31 );
+
+ TEST_RR_SRC12_BYPASS( 28, 0, 0, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_SRC12_BYPASS( 29, 0, 1, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_SRC12_BYPASS( 30, 0, 2, sra, 0xffffffff, 0x80000000, 31 );
+ TEST_RR_SRC12_BYPASS( 31, 1, 0, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_SRC12_BYPASS( 32, 1, 1, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_SRC12_BYPASS( 33, 2, 0, sra, 0xffffffff, 0x80000000, 31 );
+
+ TEST_RR_SRC21_BYPASS( 34, 0, 0, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_SRC21_BYPASS( 35, 0, 1, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_SRC21_BYPASS( 36, 0, 2, sra, 0xffffffff, 0x80000000, 31 );
+ TEST_RR_SRC21_BYPASS( 37, 1, 0, sra, 0xff000000, 0x80000000, 7 );
+ TEST_RR_SRC21_BYPASS( 38, 1, 1, sra, 0xfffe0000, 0x80000000, 14 );
+ TEST_RR_SRC21_BYPASS( 39, 2, 0, sra, 0xffffffff, 0x80000000, 31 );
+
+ TEST_RR_ZEROSRC1( 40, sra, 0, 15 );
+ TEST_RR_ZEROSRC2( 41, sra, 32, 32 );
+ TEST_RR_ZEROSRC12( 42, sra, 0 );
+ TEST_RR_ZERODEST( 43, sra, 1024, 2048 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/srai.S b/tests/srai.S
new file mode 100644
index 0000000..4638190
--- /dev/null
+++ b/tests/srai.S
@@ -0,0 +1,68 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srai.S
+#-----------------------------------------------------------------------------
+#
+# Test srai instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, srai, 0x00000000, 0x00000000, 0 );
+ TEST_IMM_OP( 3, srai, 0xc0000000, 0x80000000, 1 );
+ TEST_IMM_OP( 4, srai, 0xff000000, 0x80000000, 7 );
+ TEST_IMM_OP( 5, srai, 0xfffe0000, 0x80000000, 14 );
+ TEST_IMM_OP( 6, srai, 0xffffffff, 0x80000001, 31 );
+
+ TEST_IMM_OP( 7, srai, 0x7fffffff, 0x7fffffff, 0 );
+ TEST_IMM_OP( 8, srai, 0x3fffffff, 0x7fffffff, 1 );
+ TEST_IMM_OP( 9, srai, 0x00ffffff, 0x7fffffff, 7 );
+ TEST_IMM_OP( 10, srai, 0x0001ffff, 0x7fffffff, 14 );
+ TEST_IMM_OP( 11, srai, 0x00000000, 0x7fffffff, 31 );
+
+ TEST_IMM_OP( 12, srai, 0x81818181, 0x81818181, 0 );
+ TEST_IMM_OP( 13, srai, 0xc0c0c0c0, 0x81818181, 1 );
+ TEST_IMM_OP( 14, srai, 0xff030303, 0x81818181, 7 );
+ TEST_IMM_OP( 15, srai, 0xfffe0606, 0x81818181, 14 );
+ TEST_IMM_OP( 16, srai, 0xffffffff, 0x81818181, 31 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 17, srai, 0xff000000, 0x80000000, 7 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 18, 0, srai, 0xff000000, 0x80000000, 7 );
+ TEST_IMM_DEST_BYPASS( 19, 1, srai, 0xfffe0000, 0x80000000, 14 );
+ TEST_IMM_DEST_BYPASS( 20, 2, srai, 0xffffffff, 0x80000001, 31 );
+
+ TEST_IMM_SRC1_BYPASS( 21, 0, srai, 0xff000000, 0x80000000, 7 );
+ TEST_IMM_SRC1_BYPASS( 22, 1, srai, 0xfffe0000, 0x80000000, 14 );
+ TEST_IMM_SRC1_BYPASS( 23, 2, srai, 0xffffffff, 0x80000001, 31 );
+
+ TEST_IMM_ZEROSRC1( 24, srai, 0, 31 );
+ TEST_IMM_ZERODEST( 25, srai, 33, 20 );
+#
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/srl.S b/tests/srl.S
new file mode 100644
index 0000000..35cc4c7
--- /dev/null
+++ b/tests/srl.S
@@ -0,0 +1,90 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srl.S
+#-----------------------------------------------------------------------------
+#
+# Test srl instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, srl, 0xffff8000, 0xffff8000, 0 );
+ TEST_RR_OP( 3, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_OP( 4, srl, 0x01ffff00, 0xffff8000, 7 );
+ TEST_RR_OP( 5, srl, 0x0003fffe, 0xffff8000, 14 );
+ TEST_RR_OP( 6, srl, 0x0001ffff, 0xffff8001, 15 );
+
+ TEST_RR_OP( 7, srl, 0xffffffff, 0xffffffff, 0 );
+ TEST_RR_OP( 8, srl, 0x7fffffff, 0xffffffff, 1 );
+ TEST_RR_OP( 9, srl, 0x01ffffff, 0xffffffff, 7 );
+ TEST_RR_OP( 10, srl, 0x0003ffff, 0xffffffff, 14 );
+ TEST_RR_OP( 11, srl, 0x00000001, 0xffffffff, 31 );
+
+ TEST_RR_OP( 12, srl, 0x21212121, 0x21212121, 0 );
+ TEST_RR_OP( 13, srl, 0x10909090, 0x21212121, 1 );
+ TEST_RR_OP( 14, srl, 0x00424242, 0x21212121, 7 );
+ TEST_RR_OP( 15, srl, 0x00008484, 0x21212121, 14 );
+ TEST_RR_OP( 16, srl, 0x00000000, 0x21212121, 31 );
+
+ # Verify that shifts only use bottom five bits
+
+ TEST_RR_OP( 17, srl, 0x21212121, 0x21212121, 0xffffffe0 );
+ TEST_RR_OP( 18, srl, 0x10909090, 0x21212121, 0xffffffe1 );
+ TEST_RR_OP( 19, srl, 0x00424242, 0x21212121, 0xffffffe7 );
+ TEST_RR_OP( 20, srl, 0x00008484, 0x21212121, 0xffffffee );
+ TEST_RR_OP( 21, srl, 0x00000000, 0x21212121, 0xffffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 22, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_SRC2_EQ_DEST( 23, srl, 0x0003fffe, 0xffff8000, 14 );
+ TEST_RR_SRC12_EQ_DEST( 24, srl, 0, 7 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 25, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_DEST_BYPASS( 26, 1, srl, 0x0003fffe, 0xffff8000, 14 );
+ TEST_RR_DEST_BYPASS( 27, 2, srl, 0x0001ffff, 0xffff8000, 15 );
+
+ TEST_RR_SRC12_BYPASS( 28, 0, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_SRC12_BYPASS( 29, 0, 1, srl, 0x01ffff00, 0xffff8000, 7 );
+ TEST_RR_SRC12_BYPASS( 30, 0, 2, srl, 0x0001ffff, 0xffff8000, 15 );
+ TEST_RR_SRC12_BYPASS( 31, 1, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_SRC12_BYPASS( 32, 1, 1, srl, 0x01ffff00, 0xffff8000, 7 );
+ TEST_RR_SRC12_BYPASS( 33, 2, 0, srl, 0x0001ffff, 0xffff8000, 15 );
+
+ TEST_RR_SRC21_BYPASS( 34, 0, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_SRC21_BYPASS( 35, 0, 1, srl, 0x01ffff00, 0xffff8000, 7 );
+ TEST_RR_SRC21_BYPASS( 36, 0, 2, srl, 0x0001ffff, 0xffff8000, 15 );
+ TEST_RR_SRC21_BYPASS( 37, 1, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_RR_SRC21_BYPASS( 38, 1, 1, srl, 0x01ffff00, 0xffff8000, 7 );
+ TEST_RR_SRC21_BYPASS( 39, 2, 0, srl, 0x0001ffff, 0xffff8000, 15 );
+
+ TEST_RR_ZEROSRC1( 40, srl, 0, 15 );
+ TEST_RR_ZEROSRC2( 41, srl, 32, 32 );
+ TEST_RR_ZEROSRC12( 42, srl, 0 );
+ TEST_RR_ZERODEST( 43, srl, 1024, 2048 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/srli.S b/tests/srli.S
new file mode 100644
index 0000000..c2797cd
--- /dev/null
+++ b/tests/srli.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# srli.S
+#-----------------------------------------------------------------------------
+#
+# Test srli instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, srli, 0xffff8000, 0xffff8000, 0 );
+ TEST_IMM_OP( 3, srli, 0x7fffc000, 0xffff8000, 1 );
+ TEST_IMM_OP( 4, srli, 0x01ffff00, 0xffff8000, 7 );
+ TEST_IMM_OP( 5, srli, 0x0003fffe, 0xffff8000, 14 );
+ TEST_IMM_OP( 6, srli, 0x0001ffff, 0xffff8001, 15 );
+
+ TEST_IMM_OP( 7, srli, 0xffffffff, 0xffffffff, 0 );
+ TEST_IMM_OP( 8, srli, 0x7fffffff, 0xffffffff, 1 );
+ TEST_IMM_OP( 9, srli, 0x01ffffff, 0xffffffff, 7 );
+ TEST_IMM_OP( 10, srli, 0x0003ffff, 0xffffffff, 14 );
+ TEST_IMM_OP( 11, srli, 0x00000001, 0xffffffff, 31 );
+
+ TEST_IMM_OP( 12, srli, 0x21212121, 0x21212121, 0 );
+ TEST_IMM_OP( 13, srli, 0x10909090, 0x21212121, 1 );
+ TEST_IMM_OP( 14, srli, 0x00424242, 0x21212121, 7 );
+ TEST_IMM_OP( 15, srli, 0x00008484, 0x21212121, 14 );
+ TEST_IMM_OP( 16, srli, 0x00000000, 0x21212121, 31 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 21, srli, 0x7fffc000, 0xffff8000, 1 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 22, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_IMM_DEST_BYPASS( 23, 1, srl, 0x0003fffe, 0xffff8000, 14 );
+ TEST_IMM_DEST_BYPASS( 24, 2, srl, 0x0001ffff, 0xffff8000, 15 );
+
+ TEST_IMM_SRC1_BYPASS( 25, 0, srl, 0x7fffc000, 0xffff8000, 1 );
+ TEST_IMM_SRC1_BYPASS( 26, 1, srl, 0x0003fffe, 0xffff8000, 14 );
+ TEST_IMM_SRC1_BYPASS( 27, 2, srl, 0x0001ffff, 0xffff8000, 15 );
+
+
+ TEST_IMM_ZEROSRC1( 28, srli, 0, 31 );
+ TEST_IMM_ZERODEST( 29, srli, 33, 20 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/sub.S b/tests/sub.S
new file mode 100644
index 0000000..ad56e3e
--- /dev/null
+++ b/tests/sub.S
@@ -0,0 +1,83 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sub.S
+#-----------------------------------------------------------------------------
+#
+# Test sub instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Arithmetic tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, sub, 0x00000000, 0x00000000, 0x00000000 );
+ TEST_RR_OP( 3, sub, 0x00000000, 0x00000001, 0x00000001 );
+ TEST_RR_OP( 4, sub, 0xfffffffc, 0x00000003, 0x00000007 );
+
+ TEST_RR_OP( 5, sub, 0x00008000, 0x00000000, 0xffff8000 );
+ TEST_RR_OP( 6, sub, 0x80000000, 0x80000000, 0x00000000 );
+ TEST_RR_OP( 7, sub, 0x80008000, 0x80000000, 0xffff8000 );
+
+ TEST_RR_OP( 8, sub, 0xffff8001, 0x00000000, 0x00007fff );
+ TEST_RR_OP( 9, sub, 0x7fffffff, 0x7fffffff, 0x00000000 );
+ TEST_RR_OP( 10, sub, 0x7fff8000, 0x7fffffff, 0x00007fff );
+
+ TEST_RR_OP( 11, sub, 0x7fff8001, 0x80000000, 0x00007fff );
+ TEST_RR_OP( 12, sub, 0x80007fff, 0x7fffffff, 0xffff8000 );
+
+ TEST_RR_OP( 13, sub, 0x00000001, 0x00000000, 0xffffffff );
+ TEST_RR_OP( 14, sub, 0xfffffffe, 0xffffffff, 0x00000001 );
+ TEST_RR_OP( 15, sub, 0x00000000, 0xffffffff, 0xffffffff );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 16, sub, 2, 13, 11 );
+ TEST_RR_SRC2_EQ_DEST( 17, sub, 3, 14, 11 );
+ TEST_RR_SRC12_EQ_DEST( 18, sub, 0, 13 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 19, 0, sub, 2, 13, 11 );
+ TEST_RR_DEST_BYPASS( 20, 1, sub, 3, 14, 11 );
+ TEST_RR_DEST_BYPASS( 21, 2, sub, 4, 15, 11 );
+
+ TEST_RR_SRC12_BYPASS( 22, 0, 0, sub, 2, 13, 11 );
+ TEST_RR_SRC12_BYPASS( 23, 0, 1, sub, 3, 14, 11 );
+ TEST_RR_SRC12_BYPASS( 24, 0, 2, sub, 4, 15, 11 );
+ TEST_RR_SRC12_BYPASS( 25, 1, 0, sub, 2, 13, 11 );
+ TEST_RR_SRC12_BYPASS( 26, 1, 1, sub, 3, 14, 11 );
+ TEST_RR_SRC12_BYPASS( 27, 2, 0, sub, 4, 15, 11 );
+
+ TEST_RR_SRC21_BYPASS( 28, 0, 0, sub, 2, 13, 11 );
+ TEST_RR_SRC21_BYPASS( 29, 0, 1, sub, 3, 14, 11 );
+ TEST_RR_SRC21_BYPASS( 30, 0, 2, sub, 4, 15, 11 );
+ TEST_RR_SRC21_BYPASS( 31, 1, 0, sub, 2, 13, 11 );
+ TEST_RR_SRC21_BYPASS( 32, 1, 1, sub, 3, 14, 11 );
+ TEST_RR_SRC21_BYPASS( 33, 2, 0, sub, 4, 15, 11 );
+
+ TEST_RR_ZEROSRC1( 34, sub, 15, -15 );
+ TEST_RR_ZEROSRC2( 35, sub, 32, 32 );
+ TEST_RR_ZEROSRC12( 36, sub, 0 );
+ TEST_RR_ZERODEST( 37, sub, 16, 30 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/sw.S b/tests/sw.S
new file mode 100644
index 0000000..fbf76cc
--- /dev/null
+++ b/tests/sw.S
@@ -0,0 +1,92 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# sw.S
+#-----------------------------------------------------------------------------
+#
+# Test sw instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Basic tests
+ #-------------------------------------------------------------
+
+ TEST_ST_OP( 2, lw, sw, 0x00aa00aa, 0, tdat );
+ TEST_ST_OP( 3, lw, sw, 0xaa00aa00, 4, tdat );
+ TEST_ST_OP( 4, lw, sw, 0x0aa00aa0, 8, tdat );
+ TEST_ST_OP( 5, lw, sw, 0xa00aa00a, 12, tdat );
+
+ # Test with negative offset
+
+ TEST_ST_OP( 6, lw, sw, 0x00aa00aa, -12, tdat8 );
+ TEST_ST_OP( 7, lw, sw, 0xaa00aa00, -8, tdat8 );
+ TEST_ST_OP( 8, lw, sw, 0x0aa00aa0, -4, tdat8 );
+ TEST_ST_OP( 9, lw, sw, 0xa00aa00a, 0, tdat8 );
+
+ # Test with a negative base
+
+ TEST_CASE( 10, x3, 0x12345678, \
+ la x1, tdat9; \
+ li x2, 0x12345678; \
+ addi x4, x1, -32; \
+ sw x2, 32(x4); \
+ lw x3, 0(x1); \
+ )
+
+ # Test with unaligned base
+
+ TEST_CASE( 11, x3, 0x58213098, \
+ la x1, tdat9; \
+ li x2, 0x58213098; \
+ addi x1, x1, -3; \
+ sw x2, 7(x1); \
+ la x4, tdat10; \
+ lw x3, 0(x4); \
+ )
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_ST_SRC12_BYPASS( 12, 0, 0, lw, sw, 0xaabbccdd, 0, tdat );
+ TEST_ST_SRC12_BYPASS( 13, 0, 1, lw, sw, 0xdaabbccd, 4, tdat );
+ TEST_ST_SRC12_BYPASS( 14, 0, 2, lw, sw, 0xddaabbcc, 8, tdat );
+ TEST_ST_SRC12_BYPASS( 15, 1, 0, lw, sw, 0xcddaabbc, 12, tdat );
+ TEST_ST_SRC12_BYPASS( 16, 1, 1, lw, sw, 0xccddaabb, 16, tdat );
+ TEST_ST_SRC12_BYPASS( 17, 2, 0, lw, sw, 0xbccddaab, 20, tdat );
+
+ TEST_ST_SRC21_BYPASS( 18, 0, 0, lw, sw, 0x00112233, 0, tdat );
+ TEST_ST_SRC21_BYPASS( 19, 0, 1, lw, sw, 0x30011223, 4, tdat );
+ TEST_ST_SRC21_BYPASS( 20, 0, 2, lw, sw, 0x33001122, 8, tdat );
+ TEST_ST_SRC21_BYPASS( 21, 1, 0, lw, sw, 0x23300112, 12, tdat );
+ TEST_ST_SRC21_BYPASS( 22, 1, 1, lw, sw, 0x22330011, 16, tdat );
+ TEST_ST_SRC21_BYPASS( 23, 2, 0, lw, sw, 0x12233001, 20, tdat );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+tdat1: .word 0xdeadbeef
+tdat2: .word 0xdeadbeef
+tdat3: .word 0xdeadbeef
+tdat4: .word 0xdeadbeef
+tdat5: .word 0xdeadbeef
+tdat6: .word 0xdeadbeef
+tdat7: .word 0xdeadbeef
+tdat8: .word 0xdeadbeef
+tdat9: .word 0xdeadbeef
+tdat10: .word 0xdeadbeef
+
+RVTEST_DATA_END
diff --git a/tests/test_macros.h b/tests/test_macros.h
new file mode 100644
index 0000000..6242f0b
--- /dev/null
+++ b/tests/test_macros.h
@@ -0,0 +1,708 @@
+// See LICENSE for license details.
+
+#ifndef __TEST_MACROS_SCALAR_H
+#define __TEST_MACROS_SCALAR_H
+
+
+#-----------------------------------------------------------------------
+# Helper macros
+#-----------------------------------------------------------------------
+
+#define TEST_CASE( testnum, testreg, correctval, code... ) \
+test_ ## testnum: \
+ code; \
+ li x29, 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, x3, result, \
+ li x1, val1; \
+ inst x3, x1, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, 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, val1; \
+ inst x3, x1, SEXT_IMM(imm); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 0; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x3, result, \
+ li x4, 0; \
+1: li x1, val1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x3, 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, val1; \
+ inst x0, x1, SEXT_IMM(imm); \
+ )
+
+#-----------------------------------------------------------------------
+# Tests for vector config instructions
+#-----------------------------------------------------------------------
+
+#define TEST_VSETCFGIVL( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12); \
+ vsetcfg x1,nxpr,nfpr; \
+ li x1, vl; \
+ vsetvl x1,x1; \
+ )
+
+#define TEST_VVCFG( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12) | (nfpr << 6) | nxpr; \
+ vsetcfg x1; \
+ li x1, vl; \
+ vsetvl x1,x1; \
+ )
+
+#define TEST_VSETVL( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12); \
+ vsetcfg x1,nxpr,nfpr; \
+ li x1, vl; \
+ vsetvl x1, x1; \
+ )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register operands
+#-----------------------------------------------------------------------
+
+#define TEST_R_OP( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x3, result, \
+ li x1, val1; \
+ inst x3, 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 x3, x1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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, x3, result, \
+ li x1, val1; \
+ li x2, val2; \
+ inst x3, x1, x2; \
+ )
+
+#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, val1; \
+ li x2, val2; \
+ inst x1, x1, x2; \
+ )
+
+#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x2, result, \
+ li x1, val1; \
+ li x2, val2; \
+ inst x2, x1, x2; \
+ )
+
+#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, 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, val1; \
+ li x2, val2; \
+ inst x3, x1, x2; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 0; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x3, result, \
+ li x4, 0; \
+1: li x1, val1; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x2, val2; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x3, x1, x2; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x3, result, \
+ li x4, 0; \
+1: li x2, val2; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x1, val1; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x3, 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, val; \
+ inst x2, x0, x1; \
+ )
+
+#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
+ TEST_CASE( testnum, x2, result, \
+ li x1, 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, val1; \
+ li x2, val2; \
+ inst x0, x1, x2; \
+ )
+
+#-----------------------------------------------------------------------
+# Test memory instructions
+#-----------------------------------------------------------------------
+
+#define TEST_LD_OP( testnum, inst, result, offset, base ) \
+ TEST_CASE( testnum, x3, result, \
+ la x1, base; \
+ inst x3, offset(x1); \
+ )
+
+#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
+ TEST_CASE( testnum, x3, result, \
+ la x1, base; \
+ li x2, result; \
+ store_inst x2, offset(x1); \
+ load_inst x3, 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 x3, offset(x1); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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 x3, offset(x1); \
+ li x29, result; \
+ bne x3, 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: la x1, result; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ la x2, base; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ store_inst x1, offset(x2); \
+ load_inst x3, offset(x2); \
+ li x29, result; \
+ bne x3, 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 \
+ la x1, result; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ store_inst x1, offset(x2); \
+ load_inst x3, offset(x2); \
+ li x29, result; \
+ bne x3, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#-----------------------------------------------------------------------
+# Test branch instructions
+#-----------------------------------------------------------------------
+
+#define TEST_BR1_OP_TAKEN( testnum, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x1, val1; \
+ inst x1, 2f; \
+ bne x0, TESTNUM, fail; \
+1: bne x0, TESTNUM, 3f; \
+2: inst x1, 1b; \
+ bne x0, TESTNUM, fail; \
+3:
+
+#define TEST_BR1_OP_NOTTAKEN( testnum, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x1, val1; \
+ inst x1, 1f; \
+ bne x0, TESTNUM, 2f; \
+1: bne x0, TESTNUM, fail; \
+2: inst x1, 1b; \
+3:
+
+#define TEST_BR1_SRC1_BYPASS( testnum, nop_cycles, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x4, 0; \
+1: li x1, val1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x1, 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 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; \
+ j 2f; \
+ .align 2; \
+ .data; \
+ test_ ## testnum ## _data: \
+ .float val1; \
+ .float val2; \
+ .float val3; \
+ .result; \
+ .text; \
+2:
+
+#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; \
+ j 2f; \
+ .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .result; \
+ .text; \
+2:
+
+#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_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_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_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_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_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, result, val1, val2 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, 0, word result, val1, val2, 0.0, \
+ inst a0, f0, f1)
+
+#define TEST_FP_CMP_OP_D( testnum, inst, result, val1, val2 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, 0, dword result, val1, val2, 0.0, \
+ inst a0, f0, f1)
+
+#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; \
+ j 1f; \
+ .align 2; \
+ test_ ## testnum ## _data: \
+ .float result; \
+1:
+
+#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; \
+ j 1f; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double result; \
+1:
+
+
+#-----------------------------------------------------------------------
+# RV64SV MACROS
+#-----------------------------------------------------------------------
+
+#define TEST_ILLEGAL_TVEC_REGID( testnum, nxreg, nfreg, inst, reg1, reg2) \
+ la a0, handler ## testnum; \
+ csrw stvec, a0; \
+ vsetcfg nxreg, nfreg; \
+ li a0, 4; \
+ vsetvl a0, a0; \
+ la a0, src1; \
+ la a1, src2; \
+ vld vx2, a0; \
+ vld vx3, a1; \
+ lui a0,%hi(vtcode1 ## testnum); \
+ vf %lo(vtcode1 ## testnum)(a0); \
+ la reg2, dest; \
+illegal ## testnum: \
+ inst reg1, reg2; \
+ la a3, dest; \
+ vsd vx2, a3; \
+ fence; \
+vtcode1 ## testnum: \
+ add x2, x2, x3; \
+ stop; \
+vtcode2 ## testnum: \
+ add x2, x2, x3; \
+ stop; \
+handler ## testnum: \
+ vxcptkill; \
+ li TESTNUM,2; \
+ csrr a0, scause; \
+ li a1,HWACHA_CAUSE_TVEC_ILLEGAL_REGID; \
+ bne a0,a1,fail; \
+ csrr a0, sbadaddr; \
+ la a1, illegal ## testnum; \
+ lw a2, 0(a1); \
+ bne a0, a2, fail; \
+ vsetcfg 32,0; \
+ li a0,4; \
+ vsetvl a0,a0; \
+ la a0,src1; \
+ la a1,src2; \
+ vld vx2,a0; \
+ vld vx3,a1; \
+ lui a0,%hi(vtcode2 ## testnum); \
+ vf %lo(vtcode2 ## testnum)(a0); \
+ la a3,dest; \
+ vsd vx2,a3; \
+ fence; \
+ ld a1,0(a3); \
+ li a2,5; \
+ li TESTNUM,2; \
+ bne a1,a2,fail; \
+ ld a1,8(a3); \
+ li TESTNUM,3; \
+ bne a1,a2,fail; \
+ ld a1,16(a3); \
+ li TESTNUM,4; \
+ bne a1,a2,fail; \
+ ld a1,24(a3); \
+ li TESTNUM,5; \
+ bne a1,a2,fail; \
+
+#define TEST_ILLEGAL_VT_REGID( testnum, nxreg, nfreg, inst, reg1, reg2, reg3) \
+ la a0, handler ## testnum; \
+ csrw stvec, a0; \
+ vsetcfg nxreg, nfreg; \
+ li a0, 4; \
+ vsetvl a0, a0; \
+ la a0, src1; \
+ la a1, src2; \
+ vld vx2, a0; \
+ vld vx3, a1; \
+ lui a0,%hi(vtcode1 ## testnum); \
+ vf %lo(vtcode1 ## testnum)(a0); \
+ la a3, dest; \
+ vsd vx2, a3; \
+ fence; \
+vtcode1 ## testnum: \
+ add x2, x2, x3; \
+illegal ## testnum: \
+ inst reg1, reg2, reg3; \
+ stop; \
+vtcode2 ## testnum: \
+ add x2, x2, x3; \
+ stop; \
+handler ## testnum: \
+ vxcptkill; \
+ li TESTNUM,2; \
+ csrr a0, scause; \
+ li a1,HWACHA_CAUSE_VF_ILLEGAL_REGID; \
+ bne a0,a1,fail; \
+ csrr a0, sbadaddr; \
+ la a1,illegal ## testnum; \
+ bne a0,a1,fail; \
+ vsetcfg 32,0; \
+ li a0,4; \
+ vsetvl a0,a0; \
+ la a0,src1; \
+ la a1,src2; \
+ vld vx2,a0; \
+ vld vx3,a1; \
+ lui a0,%hi(vtcode2 ## testnum); \
+ vf %lo(vtcode2 ## testnum)(a0); \
+ la a3,dest; \
+ vsd vx2,a3; \
+ fence; \
+ ld a1,0(a3); \
+ li a2,5; \
+ li TESTNUM,2; \
+ bne a1,a2,fail; \
+ ld a1,8(a3); \
+ li TESTNUM,3; \
+ bne a1,a2,fail; \
+ ld a1,16(a3); \
+ li TESTNUM,4; \
+ bne a1,a2,fail; \
+ ld a1,24(a3); \
+ li TESTNUM,5; \
+ bne a1,a2,fail; \
+
+#-----------------------------------------------------------------------
+# 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
diff --git a/tests/xor.S b/tests/xor.S
new file mode 100644
index 0000000..72875fe
--- /dev/null
+++ b/tests/xor.S
@@ -0,0 +1,69 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# xor.S
+#-----------------------------------------------------------------------------
+#
+# Test xor instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_RR_OP( 2, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_OP( 3, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_OP( 4, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_OP( 5, xor, 0x00ff00ff, 0xf00ff00f, 0xf0f0f0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_RR_SRC1_EQ_DEST( 6, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC2_EQ_DEST( 7, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_EQ_DEST( 8, xor, 0x00000000, 0xff00ff00 );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_RR_DEST_BYPASS( 9, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_DEST_BYPASS( 10, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_DEST_BYPASS( 11, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC12_BYPASS( 12, 0, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 13, 0, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 14, 0, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 15, 1, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC12_BYPASS( 16, 1, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC12_BYPASS( 17, 2, 0, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_SRC21_BYPASS( 18, 0, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 19, 0, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 20, 0, 2, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 21, 1, 0, xor, 0xf00ff00f, 0xff00ff00, 0x0f0f0f0f );
+ TEST_RR_SRC21_BYPASS( 22, 1, 1, xor, 0xff00ff00, 0x0ff00ff0, 0xf0f0f0f0 );
+ TEST_RR_SRC21_BYPASS( 23, 2, 0, xor, 0x0ff00ff0, 0x00ff00ff, 0x0f0f0f0f );
+
+ TEST_RR_ZEROSRC1( 24, xor, 0xff00ff00, 0xff00ff00 );
+ TEST_RR_ZEROSRC2( 25, xor, 0x00ff00ff, 0x00ff00ff );
+ TEST_RR_ZEROSRC12( 26, xor, 0 );
+ TEST_RR_ZERODEST( 27, xor, 0x11111111, 0x22222222 );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/tests/xori.S b/tests/xori.S
new file mode 100644
index 0000000..7f2207c
--- /dev/null
+++ b/tests/xori.S
@@ -0,0 +1,55 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# xori.S
+#-----------------------------------------------------------------------------
+#
+# Test xori instruction.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV32U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Logical tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_OP( 2, xori, 0xff00f00f, 0x00ff0f00, 0xf0f );
+ TEST_IMM_OP( 3, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_OP( 4, xori, 0x00ff0ff0, 0x00ff08ff, 0x70f );
+ TEST_IMM_OP( 5, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ #-------------------------------------------------------------
+ # Source/Destination tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_SRC1_EQ_DEST( 6, xori, 0xff00f00f, 0xff00f700, 0x70f );
+
+ #-------------------------------------------------------------
+ # Bypassing tests
+ #-------------------------------------------------------------
+
+ TEST_IMM_DEST_BYPASS( 7, 0, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_DEST_BYPASS( 8, 1, xori, 0x00ff0ff0, 0x00ff08ff, 0x70f );
+ TEST_IMM_DEST_BYPASS( 9, 2, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ TEST_IMM_SRC1_BYPASS( 10, 0, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 );
+ TEST_IMM_SRC1_BYPASS( 11, 1, xori, 0x00ff0ff0, 0x00ff0fff, 0x00f );
+ TEST_IMM_SRC1_BYPASS( 12, 2, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 );
+
+ TEST_IMM_ZEROSRC1( 13, xori, 0x0f0, 0x0f0 );
+ TEST_IMM_ZERODEST( 14, xori, 0x00ff00ff, 0x70f );
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END