From 5f8a4918c6482e65c67a2b7decd5c2af3e3fe0e5 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao <48193236+chihminchao@users.noreply.github.com> Date: Wed, 11 Nov 2020 17:09:15 +0800 Subject: add zfh (float16) test case and related macros (#301) * ext: add zfh extension test case and related macro Signed-off-by: Chih-Min Chao * build: add zfh to target Signed-off-by: Chih-Min Chao --- isa/Makefile | 4 ++ isa/macros/scalar/test_macros.h | 73 ++++++++++++++++++++++++++++ isa/rv32uzfh/Makefrag | 12 +++++ isa/rv32uzfh/fadd.S | 7 +++ isa/rv32uzfh/fclass.S | 7 +++ isa/rv32uzfh/fcmp.S | 7 +++ isa/rv32uzfh/fcvt.S | 7 +++ isa/rv32uzfh/fcvt_w.S | 7 +++ isa/rv32uzfh/fdiv.S | 7 +++ isa/rv32uzfh/fmadd.S | 7 +++ isa/rv32uzfh/fmin.S | 7 +++ isa/rv32uzfh/ldst.S | 38 +++++++++++++++ isa/rv32uzfh/move.S | 7 +++ isa/rv32uzfh/recoding.S | 7 +++ isa/rv64uzfh/Makefrag | 12 +++++ isa/rv64uzfh/fadd.S | 44 +++++++++++++++++ isa/rv64uzfh/fclass.S | 44 +++++++++++++++++ isa/rv64uzfh/fcmp.S | 37 ++++++++++++++ isa/rv64uzfh/fcvt.S | 49 +++++++++++++++++++ isa/rv64uzfh/fcvt_w.S | 104 ++++++++++++++++++++++++++++++++++++++++ isa/rv64uzfh/fdiv.S | 41 ++++++++++++++++ isa/rv64uzfh/fmadd.S | 45 +++++++++++++++++ isa/rv64uzfh/fmin.S | 54 +++++++++++++++++++++ isa/rv64uzfh/ldst.S | 38 +++++++++++++++ isa/rv64uzfh/move.S | 58 ++++++++++++++++++++++ isa/rv64uzfh/recoding.S | 46 ++++++++++++++++++ 26 files changed, 769 insertions(+) create mode 100644 isa/rv32uzfh/Makefrag create mode 100644 isa/rv32uzfh/fadd.S create mode 100644 isa/rv32uzfh/fclass.S create mode 100644 isa/rv32uzfh/fcmp.S create mode 100644 isa/rv32uzfh/fcvt.S create mode 100644 isa/rv32uzfh/fcvt_w.S create mode 100644 isa/rv32uzfh/fdiv.S create mode 100644 isa/rv32uzfh/fmadd.S create mode 100644 isa/rv32uzfh/fmin.S create mode 100644 isa/rv32uzfh/ldst.S create mode 100644 isa/rv32uzfh/move.S create mode 100644 isa/rv32uzfh/recoding.S create mode 100644 isa/rv64uzfh/Makefrag create mode 100644 isa/rv64uzfh/fadd.S create mode 100644 isa/rv64uzfh/fclass.S create mode 100644 isa/rv64uzfh/fcmp.S create mode 100644 isa/rv64uzfh/fcvt.S create mode 100644 isa/rv64uzfh/fcvt_w.S create mode 100644 isa/rv64uzfh/fdiv.S create mode 100644 isa/rv64uzfh/fmadd.S create mode 100644 isa/rv64uzfh/fmin.S create mode 100644 isa/rv64uzfh/ldst.S create mode 100644 isa/rv64uzfh/move.S create mode 100644 isa/rv64uzfh/recoding.S diff --git a/isa/Makefile b/isa/Makefile index 4e1ba20..ca49960 100644 --- a/isa/Makefile +++ b/isa/Makefile @@ -13,6 +13,7 @@ include $(src_dir)/rv64um/Makefrag include $(src_dir)/rv64ua/Makefrag include $(src_dir)/rv64uf/Makefrag include $(src_dir)/rv64ud/Makefrag +include $(src_dir)/rv64uzfh/Makefrag include $(src_dir)/rv64si/Makefrag include $(src_dir)/rv64mi/Makefrag endif @@ -22,6 +23,7 @@ include $(src_dir)/rv32um/Makefrag include $(src_dir)/rv32ua/Makefrag include $(src_dir)/rv32uf/Makefrag include $(src_dir)/rv32ud/Makefrag +include $(src_dir)/rv32uzfh/Makefrag include $(src_dir)/rv32si/Makefrag include $(src_dir)/rv32mi/Makefrag @@ -77,6 +79,7 @@ $(eval $(call compile_template,rv32um,-march=rv32g -mabi=ilp32)) $(eval $(call compile_template,rv32ua,-march=rv32g -mabi=ilp32)) $(eval $(call compile_template,rv32uf,-march=rv32g -mabi=ilp32)) $(eval $(call compile_template,rv32ud,-march=rv32g -mabi=ilp32)) +$(eval $(call compile_template,rv32uzfh,-march=rv32g_zfh -mabi=ilp32)) $(eval $(call compile_template,rv32si,-march=rv32g -mabi=ilp32)) $(eval $(call compile_template,rv32mi,-march=rv32g -mabi=ilp32)) ifeq ($(XLEN),64) @@ -86,6 +89,7 @@ $(eval $(call compile_template,rv64um,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64ua,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64uf,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64ud,-march=rv64g -mabi=lp64)) +$(eval $(call compile_template,rv64uzfh,-march=rv64g_zfh -mabi=lp64)) $(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64)) endif diff --git a/isa/macros/scalar/test_macros.h b/isa/macros/scalar/test_macros.h index ed4cab0..a8a78a7 100644 --- a/isa/macros/scalar/test_macros.h +++ b/isa/macros/scalar/test_macros.h @@ -374,11 +374,35 @@ test_ ## testnum: \ # Tests floating-point instructions #----------------------------------------------------------------------- +#define qNaNh 0h:7e00 +#define sNaNh 0h:7c01 #define qNaNf 0f:7fc00000 #define sNaNf 0f:7f800001 #define qNaN 0d:7ff8000000000000 #define sNaN 0d:7ff0000000000001 +#define TEST_FP_OP_H_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ +test_ ## testnum: \ + li TESTNUM, testnum; \ + la a0, test_ ## testnum ## _data ;\ + flh f0, 0(a0); \ + flh f1, 2(a0); \ + flh f2, 4(a0); \ + lh a3, 6(a0); \ + code; \ + fsflags a1, x0; \ + li a2, flags; \ + bne a0, a3, fail; \ + bne a1, a2, fail; \ + .pushsection .data; \ + .align 1; \ + test_ ## testnum ## _data: \ + .float16 val1; \ + .float16 val2; \ + .float16 val3; \ + .result; \ + .popsection + #define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ test_ ## testnum: \ li TESTNUM, testnum; \ @@ -460,6 +484,19 @@ test_ ## testnum: \ 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_FCVT_H_S( testnum, result, val1 ) \ + TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \ + fcvt.s.h f3, f0; fcvt.h.s f3, f3; fmv.x.h a0, f3) + +#define TEST_FCVT_H_D( testnum, result, val1 ) \ + TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \ + fcvt.d.h f3, f0; fcvt.h.d f3, f3; fmv.x.h a0, f3) + + +#define TEST_FP_OP1_H( testnum, inst, flags, result, val1 ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, 0.0, 0.0, \ + inst f3, f0; fmv.x.h 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) @@ -477,6 +514,10 @@ test_ ## testnum: \ TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ inst f3, f0; fmv.x.s a0, f3) +#define TEST_FP_OP1_H_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \ + inst f3, f0; fmv.x.h a0, f3) + #define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) @@ -490,6 +531,10 @@ test_ ## testnum: \ 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_H( testnum, inst, flags, result, val1, val2 ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, 0.0, \ + inst f3, f0, f1; fmv.x.h a0, f3) + #define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \ inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) @@ -503,6 +548,10 @@ test_ ## testnum: \ 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_H( testnum, inst, flags, result, val1, val2, val3 ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, val3, \ + inst f3, f0, f1, f2; fmv.x.h a0, f3) + #define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \ inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) @@ -516,6 +565,10 @@ test_ ## testnum: \ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \ inst a0, f0, rm) +#define TEST_FP_INT_OP_H( testnum, inst, flags, result, val1, rm ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \ + inst a0, f0, rm) + #define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ inst a0, f0, f1; li t2, 0) @@ -528,6 +581,10 @@ test_ ## testnum: \ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \ inst a0, f0, f1) +#define TEST_FP_CMP_OP_H( testnum, inst, flags, result, val1, val2 ) \ + TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, val1, val2, 0.0, \ + inst a0, f0, f1) + #define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \ inst a0, f0, f1; li t2, 0) @@ -571,6 +628,22 @@ test_ ## testnum: \ .float result; \ .popsection +#define TEST_INT_FP_OP_H( testnum, inst, result, val1 ) \ +test_ ## testnum: \ + li TESTNUM, testnum; \ + la a0, test_ ## testnum ## _data ;\ + lh a3, 0(a0); \ + li a0, val1; \ + inst f0, a0; \ + fsflags x0; \ + fmv.x.h a0, f0; \ + bne a0, a3, fail; \ + .pushsection .data; \ + .align 1; \ + test_ ## testnum ## _data: \ + .float16 result; \ + .popsection + #define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \ test_ ## testnum: \ li TESTNUM, testnum; \ diff --git a/isa/rv32uzfh/Makefrag b/isa/rv32uzfh/Makefrag new file mode 100644 index 0000000..5d9869d --- /dev/null +++ b/isa/rv32uzfh/Makefrag @@ -0,0 +1,12 @@ +#======================================================================= +# Makefrag for rv32uzfh tests +#----------------------------------------------------------------------- + +rv32uzfh_sc_tests = \ + fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \ + ldst move recoding \ + +rv32uzfh_p_tests = $(addprefix rv32uzfh-p-, $(rv32uzfh_sc_tests)) +rv32uzfh_v_tests = $(addprefix rv32uzfh-v-, $(rv32uzfh_sc_tests)) + +spike32_tests += $(rv32uzfh_p_tests) $(rv32uzfh_v_tests) diff --git a/isa/rv32uzfh/fadd.S b/isa/rv32uzfh/fadd.S new file mode 100644 index 0000000..11dba9d --- /dev/null +++ b/isa/rv32uzfh/fadd.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fadd.S" diff --git a/isa/rv32uzfh/fclass.S b/isa/rv32uzfh/fclass.S new file mode 100644 index 0000000..b1fcf24 --- /dev/null +++ b/isa/rv32uzfh/fclass.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fclass.S" diff --git a/isa/rv32uzfh/fcmp.S b/isa/rv32uzfh/fcmp.S new file mode 100644 index 0000000..9793dea --- /dev/null +++ b/isa/rv32uzfh/fcmp.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fcmp.S" diff --git a/isa/rv32uzfh/fcvt.S b/isa/rv32uzfh/fcvt.S new file mode 100644 index 0000000..2b5bf5a --- /dev/null +++ b/isa/rv32uzfh/fcvt.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UF +#define RVTEST_RV64UF RVTEST_RV32UF + +#include "../rv64uzfh/fcvt.S" diff --git a/isa/rv32uzfh/fcvt_w.S b/isa/rv32uzfh/fcvt_w.S new file mode 100644 index 0000000..d532b35 --- /dev/null +++ b/isa/rv32uzfh/fcvt_w.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UF +#define RVTEST_RV64UF RVTEST_RV32UF + +#include "../rv64uzfh/fcvt_w.S" diff --git a/isa/rv32uzfh/fdiv.S b/isa/rv32uzfh/fdiv.S new file mode 100644 index 0000000..2bf43a7 --- /dev/null +++ b/isa/rv32uzfh/fdiv.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fdiv.S" diff --git a/isa/rv32uzfh/fmadd.S b/isa/rv32uzfh/fmadd.S new file mode 100644 index 0000000..2a5ea91 --- /dev/null +++ b/isa/rv32uzfh/fmadd.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fmadd.S" diff --git a/isa/rv32uzfh/fmin.S b/isa/rv32uzfh/fmin.S new file mode 100644 index 0000000..360e02f --- /dev/null +++ b/isa/rv32uzfh/fmin.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/fmin.S" diff --git a/isa/rv32uzfh/ldst.S b/isa/rv32uzfh/ldst.S new file mode 100644 index 0000000..7f09872 --- /dev/null +++ b/isa/rv32uzfh/ldst.S @@ -0,0 +1,38 @@ +# See LICENSE for license details. + +#***************************************************************************** +# ldst.S +#----------------------------------------------------------------------------- +# +# This test verifies that flw, fld, fsw, and fsd work properly. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV32UF +RVTEST_CODE_BEGIN + + TEST_CASE(2, a0, 0xcafe4000, la a1, tdat; flh f1, 4(a1); fsh f1, 20(a1); lw a0, 20(a1)) + TEST_CASE(3, a0, 0xabadbf80, la a1, tdat; flh f1, 0(a1); fsh f1, 24(a1); lw a0, 24(a1)) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +tdat: +.word 0xbf80bf80 +.word 0x40004000 +.word 0x40404040 +.word 0xc080c080 +.word 0xdeadbeef +.word 0xcafebabe +.word 0xabad1dea +.word 0x1337d00d + +RVTEST_DATA_END diff --git a/isa/rv32uzfh/move.S b/isa/rv32uzfh/move.S new file mode 100644 index 0000000..b399a76 --- /dev/null +++ b/isa/rv32uzfh/move.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/move.S" diff --git a/isa/rv32uzfh/recoding.S b/isa/rv32uzfh/recoding.S new file mode 100644 index 0000000..271a5cb --- /dev/null +++ b/isa/rv32uzfh/recoding.S @@ -0,0 +1,7 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64UH +#define RVTEST_RV64UH RVTEST_RV32UH + +#include "../rv64uzfh/recoding.S" diff --git a/isa/rv64uzfh/Makefrag b/isa/rv64uzfh/Makefrag new file mode 100644 index 0000000..94e8c31 --- /dev/null +++ b/isa/rv64uzfh/Makefrag @@ -0,0 +1,12 @@ +#======================================================================= +# Makefrag for rv64uzfh tests +#----------------------------------------------------------------------- + +rv64uzfh_sc_tests = \ + fadd fdiv fclass fcmp fcvt fcvt_w fmadd fmin \ + ldst move recoding \ + +rv64uzfh_p_tests = $(addprefix rv64uzfh-p-, $(rv64uzfh_sc_tests)) +rv64uzfh_v_tests = $(addprefix rv64uzfh-v-, $(rv64uzfh_sc_tests)) + +spike_tests += $(rv64uzfh_p_tests) $(rv64uzfh_v_tests) diff --git a/isa/rv64uzfh/fadd.S b/isa/rv64uzfh/fadd.S new file mode 100644 index 0000000..6ca7f33 --- /dev/null +++ b/isa/rv64uzfh/fadd.S @@ -0,0 +1,44 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fadd.S +#----------------------------------------------------------------------------- +# +# Test f{add|sub|mul}.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_OP2_H( 2, fadd.h, 0, 3.5, 2.5, 1.0 ); + TEST_FP_OP2_H( 3, fadd.h, 1, -1234, -1235.1, 1.1 ); + TEST_FP_OP2_H( 4, fadd.h, 1, 3.14, 3.13, 0.01 ); + + TEST_FP_OP2_H( 5, fsub.h, 0, 1.5, 2.5, 1.0 ); + TEST_FP_OP2_H( 6, fsub.h, 1, -1234, -1235.1, -1.1 ); + TEST_FP_OP2_H( 7, fsub.h, 1, 3.14, 3.15, 0.01 ); + + TEST_FP_OP2_H( 8, fmul.h, 0, 2.5, 2.5, 1.0 ); + TEST_FP_OP2_H( 9, fmul.h, 0, 1235.1, -1235.1, -1.0 ); + TEST_FP_OP2_H(10, fmul.h, 1, 1.1, 11.0, 0.1 ); + + # Is the canonical NaN generated for Inf - Inf? + TEST_FP_OP2_H(11, fsub.h, 0x10, qNaNh, Inf, Inf); + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fclass.S b/isa/rv64uzfh/fclass.S new file mode 100644 index 0000000..86af7e5 --- /dev/null +++ b/isa/rv64uzfh/fclass.S @@ -0,0 +1,44 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fclass.S +#----------------------------------------------------------------------------- +# +# Test fclass.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + #define TEST_FCLASS_H(testnum, correct, input) \ + TEST_CASE(testnum, a0, correct, li a0, input; fmv.h.x fa0, a0; \ + fclass.h a0, fa0) + + TEST_FCLASS_H( 2, 1 << 0, 0xfc00 ) + TEST_FCLASS_H( 3, 1 << 1, 0xbc00 ) + TEST_FCLASS_H( 4, 1 << 2, 0x83ff ) + TEST_FCLASS_H( 5, 1 << 3, 0x8000 ) + TEST_FCLASS_H( 6, 1 << 4, 0x0000 ) + TEST_FCLASS_H( 7, 1 << 5, 0x03ff ) + TEST_FCLASS_H( 8, 1 << 6, 0x3c00 ) + TEST_FCLASS_H( 9, 1 << 7, 0x7c00 ) + TEST_FCLASS_H(10, 1 << 8, 0x7c01 ) + TEST_FCLASS_H(11, 1 << 9, 0x7e00 ) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fcmp.S b/isa/rv64uzfh/fcmp.S new file mode 100644 index 0000000..9f8a4e3 --- /dev/null +++ b/isa/rv64uzfh/fcmp.S @@ -0,0 +1,37 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fcmp.S +#----------------------------------------------------------------------------- +# +# Test f{eq|lt|le}.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_CMP_OP_H( 2, feq.h, 0x00, 1, -1.36, -1.36) + TEST_FP_CMP_OP_H( 3, fle.h, 0x00, 1, -1.36, -1.36) + TEST_FP_CMP_OP_H( 4, flt.h, 0x00, 0, -1.36, -1.36) + + TEST_FP_CMP_OP_H( 5, feq.h, 0x00, 0, -1.37, -1.36) + TEST_FP_CMP_OP_H( 6, fle.h, 0x00, 1, -1.37, -1.36) + TEST_FP_CMP_OP_H( 7, flt.h, 0x00, 1, -1.37, -1.36) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fcvt.S b/isa/rv64uzfh/fcvt.S new file mode 100644 index 0000000..5f130e1 --- /dev/null +++ b/isa/rv64uzfh/fcvt.S @@ -0,0 +1,49 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fcvt.S +#----------------------------------------------------------------------------- +# +# Test fcvt.h.{wu|w|lu|l}, fcvt.h.d, and fcvt.d.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_INT_FP_OP_H( 2, fcvt.h.w, 2.0, 2); + TEST_INT_FP_OP_H( 3, fcvt.h.w, -2.0, -2); + + TEST_INT_FP_OP_H( 4, fcvt.h.wu, 2.0, 2); + TEST_INT_FP_OP_H( 5, fcvt.h.wu, 0h:7c00, -2); + +#if __riscv_xlen >= 64 + TEST_INT_FP_OP_H( 6, fcvt.h.l, 2.0, 2); + TEST_INT_FP_OP_H( 7, fcvt.h.l, -2.0, -2); + + TEST_INT_FP_OP_H( 8, fcvt.h.lu, 2.0, 2); + TEST_INT_FP_OP_H( 9, fcvt.h.lu, 0h:7c00, -2); +#endif + + TEST_FCVT_H_S( 10, -1.5, -1.5) + +#if __riscv_xlen >= 64 + TEST_FCVT_H_D( 11, -1.5, -1.5) +#endif + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fcvt_w.S b/isa/rv64uzfh/fcvt_w.S new file mode 100644 index 0000000..013ecac --- /dev/null +++ b/isa/rv64uzfh/fcvt_w.S @@ -0,0 +1,104 @@ +# See LICENSE for license details. +#***************************************************************************** +# fcvt_w.S +#----------------------------------------------------------------------------- +# +# Test fcvt{wu|w|lu|l}.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_INT_OP_H( 2, fcvt.w.h, 0x01, -1, -1.1, rtz); + TEST_FP_INT_OP_H( 3, fcvt.w.h, 0x00, -1, -1.0, rtz); + TEST_FP_INT_OP_H( 4, fcvt.w.h, 0x01, 0, -0.9, rtz); + TEST_FP_INT_OP_H( 5, fcvt.w.h, 0x01, 0, 0.9, rtz); + TEST_FP_INT_OP_H( 6, fcvt.w.h, 0x00, 1, 1.0, rtz); + TEST_FP_INT_OP_H( 7, fcvt.w.h, 0x01, 1, 1.1, rtz); + TEST_FP_INT_OP_H( 8, fcvt.w.h, 0x00, -2054, 0h:e803, rtz); + TEST_FP_INT_OP_H( 9, fcvt.w.h, 0x00, 2054, 0h:6803, rtz); + + TEST_FP_INT_OP_H(12, fcvt.wu.h, 0x10, 0, -3.0, rtz); + TEST_FP_INT_OP_H(13, fcvt.wu.h, 0x10, 0, -1.0, rtz); + TEST_FP_INT_OP_H(14, fcvt.wu.h, 0x01, 0, -0.9, rtz); + TEST_FP_INT_OP_H(15, fcvt.wu.h, 0x01, 0, 0.9, rtz); + TEST_FP_INT_OP_H(16, fcvt.wu.h, 0x00, 1, 1.0, rtz); + TEST_FP_INT_OP_H(17, fcvt.wu.h, 0x01, 1, 1.1, rtz); + TEST_FP_INT_OP_H(18, fcvt.wu.h, 0x10, 0, 0h:e803, rtz); + TEST_FP_INT_OP_H(19, fcvt.wu.h, 0x00, 2054, 0h:6803, rtz); + +#if __riscv_xlen >= 64 + TEST_FP_INT_OP_H(22, fcvt.l.h, 0x01, -1, -1.1, rtz); + TEST_FP_INT_OP_H(23, fcvt.l.h, 0x00, -1, -1.0, rtz); + TEST_FP_INT_OP_H(24, fcvt.l.h, 0x01, 0, -0.9, rtz); + TEST_FP_INT_OP_H(25, fcvt.l.h, 0x01, 0, 0.9, rtz); + TEST_FP_INT_OP_H(26, fcvt.l.h, 0x00, 1, 1.0, rtz); + TEST_FP_INT_OP_H(27, fcvt.l.h, 0x01, 1, 1.1, rtz); + + TEST_FP_INT_OP_H(32, fcvt.lu.h, 0x10, 0, -3.0, rtz); + TEST_FP_INT_OP_H(33, fcvt.lu.h, 0x10, 0, -1.0, rtz); + TEST_FP_INT_OP_H(34, fcvt.lu.h, 0x01, 0, -0.9, rtz); + TEST_FP_INT_OP_H(35, fcvt.lu.h, 0x01, 0, 0.9, rtz); + TEST_FP_INT_OP_H(36, fcvt.lu.h, 0x00, 1, 1.0, rtz); + TEST_FP_INT_OP_H(37, fcvt.lu.h, 0x01, 1, 1.1, rtz); + TEST_FP_INT_OP_H(38, fcvt.lu.h, 0x10, 0, 0h:e483, rtz); +#endif + + # test negative NaN, negative infinity conversion + TEST_CASE( 42, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 0(x1); fcvt.w.h x1, f1) + TEST_CASE( 43, x1, 0xffffffff80000000, la x1, tdat ; flw f1, 8(x1); fcvt.w.h x1, f1) +#if __riscv_xlen >= 64 + TEST_CASE( 44, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.l.h x1, f1) + TEST_CASE( 45, x1, 0x8000000000000000, la x1, tdat ; flw f1, 8(x1); fcvt.l.h x1, f1) +#endif + + # test positive NaN, positive infinity conversion + TEST_CASE( 52, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 4(x1); fcvt.w.h x1, f1) + TEST_CASE( 53, x1, 0x000000007fffffff, la x1, tdat ; flw f1, 12(x1); fcvt.w.h x1, f1) +#if __riscv_xlen >= 64 + TEST_CASE( 54, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.l.h x1, f1) + TEST_CASE( 55, x1, 0x7fffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.l.h x1, f1) +#endif + + # test NaN, infinity conversions to unsigned integer + TEST_CASE( 62, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.wu.h x1, f1) + TEST_CASE( 63, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.wu.h x1, f1) + TEST_CASE( 64, x1, 0, la x1, tdat ; flw f1, 8(x1); fcvt.wu.h x1, f1) + TEST_CASE( 65, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.wu.h x1, f1) +#if __riscv_xlen >= 64 + TEST_CASE( 66, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 0(x1); fcvt.lu.h x1, f1) + TEST_CASE( 67, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 4(x1); fcvt.lu.h x1, f1) + TEST_CASE( 68, x1, 0, la x1, tdat ; flw f1, 8(x1); fcvt.lu.h x1, f1) + TEST_CASE( 69, x1, 0xffffffffffffffff, la x1, tdat ; flw f1, 12(x1); fcvt.lu.h x1, f1) +#endif + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +# -NaN, NaN, -inf, +inf +#tdat: +#.word 0xffffffff +#.word 0x7fffffff +#.word 0xff800000 +#.word 0x7f800000 + +tdat: +.word 0xffffffff +.word 0xffff7fff +.word 0xfffffc00 +.word 0xffff7c00 + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fdiv.S b/isa/rv64uzfh/fdiv.S new file mode 100644 index 0000000..894ebfc --- /dev/null +++ b/isa/rv64uzfh/fdiv.S @@ -0,0 +1,41 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fdiv.S +#----------------------------------------------------------------------------- +# +# Test f{div|sqrt}.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_OP2_H(2, fdiv.h, 1, 1.1557273520668288, 3.14159265, 2.71828182 ); + TEST_FP_OP2_H(3, fdiv.h, 1,-0.9991093838555584, -1234, 1235.1 ); + TEST_FP_OP2_H(4, fdiv.h, 0, 3.14159265, 3.14159265, 1.0 ); + + TEST_FP_OP1_H(5, fsqrt.h, 1, 1.7724538498928541, 3.14159265 ); + TEST_FP_OP1_H(6, fsqrt.h, 0, 100, 10000 ); + + TEST_FP_OP1_H_DWORD_RESULT(7, fsqrt.h, 0x10, 0x00007e00, -1.0 ); + + TEST_FP_OP1_H(8, fsqrt.h, 1, 13.076696, 171.0); + + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fmadd.S b/isa/rv64uzfh/fmadd.S new file mode 100644 index 0000000..2b49763 --- /dev/null +++ b/isa/rv64uzfh/fmadd.S @@ -0,0 +1,45 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fmadd.S +#----------------------------------------------------------------------------- +# +# Test f[n]m{add|sub}.h and f[n]m{add|sub}.h instructions. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_OP3_H( 2, fmadd.h, 0, 3.5, 1.0, 2.5, 1.0 ); + TEST_FP_OP3_H( 3, fmadd.h, 1, 13.2, -1.0, -12.1, 1.1 ); + TEST_FP_OP3_H( 4, fmadd.h, 0, -12.0, 2.0, -5.0, -2.0 ); + + TEST_FP_OP3_H( 5, fnmadd.h, 0, -3.5, 1.0, 2.5, 1.0 ); + TEST_FP_OP3_H( 6, fnmadd.h, 1, -13.2, -1.0, -12.1, 1.1 ); + TEST_FP_OP3_H( 7, fnmadd.h, 0, 12.0, 2.0, -5.0, -2.0 ); + + TEST_FP_OP3_H( 8, fmsub.h, 0, 1.5, 1.0, 2.5, 1.0 ); + TEST_FP_OP3_H( 9, fmsub.h, 1, 11, -1.0, -12.1, 1.1 ); + TEST_FP_OP3_H(10, fmsub.h, 0, -8.0, 2.0, -5.0, -2.0 ); + + TEST_FP_OP3_H(11, fnmsub.h, 0, -1.5, 1.0, 2.5, 1.0 ); + TEST_FP_OP3_H(12, fnmsub.h, 1, -11, -1.0, -12.1, 1.1 ); + TEST_FP_OP3_H(13, fnmsub.h, 0, 8.0, 2.0, -5.0, -2.0 ); + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/fmin.S b/isa/rv64uzfh/fmin.S new file mode 100644 index 0000000..3feec99 --- /dev/null +++ b/isa/rv64uzfh/fmin.S @@ -0,0 +1,54 @@ +# See LICENSE for license details. + +#***************************************************************************** +# fmin.S +#----------------------------------------------------------------------------- +# +# Test f{min|max}.h instructinos. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + #------------------------------------------------------------- + # Arithmetic tests + #------------------------------------------------------------- + + TEST_FP_OP2_H( 2, fmin.h, 0, 1.0, 2.5, 1.0 ); + TEST_FP_OP2_H( 3, fmin.h, 0, -1235.1, -1235.1, 1.1 ); + TEST_FP_OP2_H( 4, fmin.h, 0, -1235.1, 1.1, -1235.1 ); + TEST_FP_OP2_H( 5, fmin.h, 0, -1235.1, NaN, -1235.1 ); + TEST_FP_OP2_H( 6, fmin.h, 0, 0.00000001, 3.14159265, 0.00000001 ); + TEST_FP_OP2_H( 7, fmin.h, 0, -2.0, -1.0, -2.0 ); + + TEST_FP_OP2_H(12, fmax.h, 0, 2.5, 2.5, 1.0 ); + TEST_FP_OP2_H(13, fmax.h, 0, 1.1, -1235.1, 1.1 ); + TEST_FP_OP2_H(14, fmax.h, 0, 1.1, 1.1, -1235.1 ); + TEST_FP_OP2_H(15, fmax.h, 0, -1235.1, NaN, -1235.1 ); + TEST_FP_OP2_H(16, fmax.h, 0, 3.14159265, 3.14159265, 0.00000001 ); + TEST_FP_OP2_H(17, fmax.h, 0, -1.0, -1.0, -2.0 ); + + # FMIN(hNaN, x) = x + TEST_FP_OP2_H(20, fmax.h, 0x10, 1.0, sNaNh, 1.0); + # FMIN(hNaN, hNaN) = canonical NaN + TEST_FP_OP2_H(21, fmax.h, 0x00, qNaNh, NaN, NaN); + + # -0.0 < +0.0 + TEST_FP_OP2_H(30, fmin.h, 0, -0.0, -0.0, 0.0 ); + TEST_FP_OP2_H(31, fmin.h, 0, -0.0, 0.0, -0.0 ); + TEST_FP_OP2_H(32, fmax.h, 0, 0.0, -0.0, 0.0 ); + TEST_FP_OP2_H(33, fmax.h, 0, 0.0, 0.0, -0.0 ); + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/ldst.S b/isa/rv64uzfh/ldst.S new file mode 100644 index 0000000..ff1cdab --- /dev/null +++ b/isa/rv64uzfh/ldst.S @@ -0,0 +1,38 @@ +# See LICENSE for license details. + +#***************************************************************************** +# ldst.S +#----------------------------------------------------------------------------- +# +# This test verifies that flw, fld, fsw, and fsd work properly. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + TEST_CASE(2, a0, 0xcafe1000deadbeef, la a1, tdat; flh f1, 4(a1); fsh f1, 20(a1); ld a0, 16(a1)) + TEST_CASE(3, a0, 0x1337d00dabad0001, la a1, tdat; flh f1, 0(a1); fsh f1, 24(a1); ld a0, 24(a1)) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +tdat: +.word 0xbf800001 +.word 0x40001000 +.word 0x40400000 +.word 0xc0800000 +.word 0xdeadbeef +.word 0xcafebabe +.word 0xabad1dea +.word 0x1337d00d + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/move.S b/isa/rv64uzfh/move.S new file mode 100644 index 0000000..20021df --- /dev/null +++ b/isa/rv64uzfh/move.S @@ -0,0 +1,58 @@ +# See LICENSE for license details. + +#***************************************************************************** +# move.S +#----------------------------------------------------------------------------- +# +# This test verifies that the fmv.h.x, fmv.x.h, and fsgnj[x|n].d instructions +# and the fcsr work properly. +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + TEST_CASE(2, a1, 1, csrwi fcsr, 1; li a0, 0x1234; fssr a1, a0) + TEST_CASE(3, a0, 0x34, frsr a0) + TEST_CASE(4, a0, 0x14, frflags a0) + TEST_CASE(5, a0, 0x01, csrrwi a0, frm, 2) + TEST_CASE(6, a0, 0x54, frsr a0) + TEST_CASE(7, a0, 0x14, csrrci a0, fflags, 4) + TEST_CASE(8, a0, 0x50, frsr a0) + +#define TEST_FSGNJS(n, insn, new_sign, rs1_sign, rs2_sign) \ + TEST_CASE(n, a0, 0x1234 | (-(new_sign) << 15), \ + li a1, ((rs1_sign) << 15) | 0x1234; \ + li a2, -(rs2_sign); \ + fmv.h.x f1, a1; \ + fmv.h.x f2, a2; \ + insn f0, f1, f2; \ + fmv.x.h a0, f0) + + TEST_FSGNJS(10, fsgnj.h, 0, 0, 0) + TEST_FSGNJS(11, fsgnj.h, 1, 0, 1) + TEST_FSGNJS(12, fsgnj.h, 0, 1, 0) + TEST_FSGNJS(13, fsgnj.h, 1, 1, 1) + + TEST_FSGNJS(20, fsgnjn.h, 1, 0, 0) + TEST_FSGNJS(21, fsgnjn.h, 0, 0, 1) + TEST_FSGNJS(22, fsgnjn.h, 1, 1, 0) + TEST_FSGNJS(23, fsgnjn.h, 0, 1, 1) + + TEST_FSGNJS(30, fsgnjx.h, 0, 0, 0) + TEST_FSGNJS(31, fsgnjx.h, 1, 0, 1) + TEST_FSGNJS(32, fsgnjx.h, 1, 1, 0) + TEST_FSGNJS(33, fsgnjx.h, 0, 1, 1) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +RVTEST_DATA_END diff --git a/isa/rv64uzfh/recoding.S b/isa/rv64uzfh/recoding.S new file mode 100644 index 0000000..802be66 --- /dev/null +++ b/isa/rv64uzfh/recoding.S @@ -0,0 +1,46 @@ +# See LICENSE for license details. + +#***************************************************************************** +# recoding.S +#----------------------------------------------------------------------------- +# +# Test corner cases of John Hauser's microarchitectural recoding scheme. +# There are twice as many recoded values as IEEE-754 values; some of these +# extras are redundant (e.g. Inf) and others are illegal (subnormals with +# too many bits set). +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64UF +RVTEST_CODE_BEGIN + + # Make sure infinities with different mantissas compare as equal. + flw f0, minf, a0 + flw f1, three, a0 + fmul.s f1, f1, f0 + TEST_CASE( 2, a0, 1, feq.s a0, f0, f1) + TEST_CASE( 3, a0, 1, fle.s a0, f0, f1) + TEST_CASE( 4, a0, 0, flt.s a0, f0, f1) + + # Likewise, but for zeroes. + fcvt.s.w f0, x0 + li a0, 1 + fcvt.s.w f1, a0 + fmul.s f1, f1, f0 + TEST_CASE(5, a0, 1, feq.s a0, f0, f1) + TEST_CASE(6, a0, 1, fle.s a0, f0, f1) + TEST_CASE(7, a0, 0, flt.s a0, f0, f1) + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + +minf: .float -Inf +three: .float 3.0 + +RVTEST_DATA_END -- cgit v1.1