From 946f4ba0c4e8b9252dc5f420ceb09964754a096f Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Tue, 8 Feb 2022 23:36:30 +0800 Subject: [PATCH 01/14] add MSTATUS_VS to encoding.h --- riscv-test-suite/env/encoding.h | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv-test-suite/env/encoding.h b/riscv-test-suite/env/encoding.h index 88b2ac8fb..9d6d8f180 100644 --- a/riscv-test-suite/env/encoding.h +++ b/riscv-test-suite/env/encoding.h @@ -37,6 +37,7 @@ #define MSTATUS_HPP 0x00000600 #define MSTATUS_MPP 0x00001800 #define MSTATUS_FS 0x00006000 +#define MSTATUS_VS 0x00000600 #define MSTATUS_XS 0x00018000 #define MSTATUS_MPRV 0x00020000 #define MSTATUS_SUM 0x00040000 From f130e0ae9d729c117ed247632861de72324a9a27 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Tue, 8 Feb 2022 23:42:56 +0800 Subject: [PATCH 02/14] add support for RV64F (riscv-ctg 82ed4f0) --- riscv-test-suite/env/arch_test.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index ab255fca1..5ed021590 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -95,6 +95,15 @@ #endif #endif +#if XLEN==64 + #if FLEN==32 + #define SREG sw + #define LREG lW + #define REGWIDTH 4 + #define MASK 0xFFFFFFFF + #endif +#endif + #define MMODE_SIG 3 #define RLENG (REGWIDTH<<3) From b32fc3e92021eacc86d9116d9e64a8c859ca36a8 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Tue, 8 Feb 2022 23:51:24 +0800 Subject: [PATCH 03/14] correct comments for TEST_IMM_OP and TEST_RRI_OP and remove trailing spaces --- riscv-test-suite/env/arch_test.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 5ed021590..47dfac37e 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -344,7 +344,7 @@ bltz t4, sv_mtval /* correct adjustment is code_begin in t3 */ LA( t3, mtrap_sigptr) /* adjustment assuming access is to signature region */ - LI(t4, DATA_REL_TVAL_MSK) /* trap#s not 14, 11..8, 2 adjust w/ data_begin */ + LI(t4, DATA_REL_TVAL_MSK) /* trap#s not 14, 11..8, 2 adjust w/ data_begin */ sll t4, t4, t2 /* put bit# in MSB */ bgez t4, no_adj /* correct adjustment is data_begin in t3 */ sigbound_chk: @@ -555,7 +555,7 @@ .endm -#define RVTEST_CASE(_PNAME,_DSTR,...) +#define RVTEST_CASE(_PNAME,_DSTR,...) #define RVTEST_FP_ENABLE() \ li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \ @@ -852,7 +852,7 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) sub destreg, destreg, testreg; \ ) -//Tests for a instructions with register-immediate operand +//Tests for instructions with register-immediate operand #define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset, testreg) \ TEST_CASE(testreg, destreg, correctval, swreg, offset, \ LI(reg, MASK_XLEN(val)); \ @@ -885,7 +885,8 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) inst destreg, freg; \ csrrs flagreg, fflags, x0; \ ) -//Tests for a instructions with register-register operand + +//Tests for instructions with register-register-immediate operands #define TEST_RRI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ TEST_CASE(testreg, destreg, correctval, swreg, offset, \ LI(reg1, MASK_XLEN(val1)); \ From 5ab4852a5585c1f523d52777278cf38fad0e99e3 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Wed, 9 Feb 2022 16:47:38 +0800 Subject: [PATCH 04/14] add TEST_RD_OP(): test instructions with a single register operand -- from RISCV-CTG 6aa62192 --- riscv-test-suite/env/arch_test.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 47dfac37e..8ee9026af 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -969,6 +969,13 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) inst destreg, x2,imm; \ ) +//Tests for instructions with a single register operand +#define TEST_RD_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg1, MASK_XLEN(val1)); \ + inst destreg, reg1; \ + ) + #define TEST_CBRANCH_OP(inst, tempreg, reg2, val2, imm, label, swreg, offset) \ LI(reg2, MASK_XLEN(val2)) ;\ j 2f ;\ From 3f447ce79f244a6f012fd13f807387bffd5636c7 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Wed, 9 Feb 2022 16:49:29 +0800 Subject: [PATCH 05/14] add arch_test.h macros for P-ext --- riscv-test-suite/env/arch_test.h | 179 +++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 8ee9026af..fc167d6ad 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -562,6 +562,15 @@ csrs mstatus, a0; \ csrwi fcsr, 0 +#ifdef pext_check_vxsat_ov +#define RVTEST_VXSAT_ENABLE()\ + li a0, MSTATUS_VS & (MSTATUS_VS >> 1); \ + csrs mstatus, a0; \ + clrov +#else +#define RVTEST_VXSAT_ENABLE() +#endif + #define RVTEST_SIGBASE(_R,_TAG) \ LA(_R,_TAG);\ .set offset,0; @@ -607,6 +616,46 @@ .set offset,offset+(2*REGWIDTH);\ .endif; +// for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. +#define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...)\ + .if NARG(__VA_ARGS__) == 1;\ + SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ + SREG _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+REGWIDTH+REGWIDTH;\ + .endif;\ + .if NARG(__VA_ARGS__) == 0;\ + SREG _R,offset(_BR);\ + SREG _R_HI,(offset+REGWIDTH)(_BR);\ + .set offset,offset+REGWIDTH+REGWIDTH;\ + .endif; + + +// only reads the vxsat.OV flag when Zicsr extension is present +#ifdef pext_check_vxsat_ov +#define RDOV(_F)\ + rdov _F +#else +#define RDOV(_F)\ + nop +#endif + +// for updating signatures that include flagreg when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. +#define RVTEST_SIGUPD_PK64(_BR,_R,_R_HI,_F,...)\ + .if NARG(__VA_ARGS__) == 1;\ + SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ + SREG _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ + RDOV(_F);\ + SREG _F,(_ARG1(__VA_ARGS__,0)+8)(_BR);\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+REGWIDTH+REGWIDTH+REGWIDTH;\ + .endif;\ + .if NARG(__VA_ARGS__) == 0;\ + SREG _R,offset(_BR);\ + SREG _R_HI,(offset+REGWIDTH)(_BR);\ + RDOV(_F);\ + SREG _F,(offset+REGWIDTH+REGWIDTH)(_BR);\ + .set offset,offset+REGWIDTH+REGWIDTH+REGWIDTH;\ + .endif; + #define RVTEST_VALBASEUPD(_BR,...)\ .if NARG(__VA_ARGS__) == 0;\ addi _BR,_BR,2040;\ @@ -944,6 +993,136 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) inst imm_val; \ ) +//Tests for instructions with register-immediate operand and update the saturation flag +#define TEST_PKIMM_OP( inst, destreg, reg, correctval, val, imm, flagreg, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val)); \ + inst destreg, reg, SEXT_IMM(imm); \ + rdov flagreg; \ + ) +//Tests for instructions with register-register operand and update the saturation flag +#define TEST_PKRR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, flagreg, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + rdov flagreg; \ + ) + +//Tests for instructions with a single register operand and update the saturation flag +#define TEST_PKR_OP( inst, destreg, reg, correctval, val, flagreg, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val)); \ + inst destreg, reg; \ + rdov flagreg; \ + ) + + +#if __riscv_xlen == 32 +//Tests for a instruction with register pair operands for all its three operands +#define TEST_P64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + LI(reg2_hi, MASK_XLEN(val2_hi)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg,destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_PK64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, flagreg, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + LI(reg2_hi, MASK_XLEN(val2_hi)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK64(swreg,destreg, destreg_hi, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_PPN_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, correctval, correctval_hi, val1, val1_hi, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_PK64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, flagreg, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK64(swreg, destreg, destreg_hi, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_NPN_OP_32(inst, destreg, reg1, reg1_hi, reg2, correctval, val1, val1_hi, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD(swreg,destreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); + +#define TEST_P64_NP_OP_32(inst, destreg, reg1, reg1_hi, correctval, val1, val1_hi, imm_val, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + inst destreg, reg1, imm_val; \ + RVTEST_SIGUPD(swreg,destreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); + +//Tests for a instruction with pair register rd, pair register rs1 and pair register rs2 +#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ + TEST_P64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) +#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ + TEST_PK64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) +//Tests for a instruction with pair register rd, pair register rs1 and normal register rs2 +#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_P64_PPN_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) +//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 +#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ + TEST_P64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) +//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 +#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ + TEST_PK64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +//Tests for a instruction with normal register rd, pair register rs1 and normal register rs2 +#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_P64_NPN_OP_32(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) +//Tests for a instruction with normal register rd, pair register rs1 +#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ + TEST_P64_NP_OP_32(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) + +#else +// When in rv64, there are no instructions with pair operand, so Macro is redefined to normal TEST_RR_OP +#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ + TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ + TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ + TEST_IMM_OP(inst, rd, rs1, correctval, rs1_val, imm_val, swreg, offset, testreg) + +#endif + + + + #define TEST_CMV_OP( inst, destreg, reg, correctval, val2, swreg, offset, testreg) \ TEST_CASE(testreg, destreg, correctval, swreg, offset, \ LI(reg, MASK_XLEN(val2)); \ From 5765d61a0dc54e92735cf225db9dd9b41588d420 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Mon, 21 Feb 2022 23:48:02 +0800 Subject: [PATCH 06/14] TEST_RD_OP() duplicates TEST_CMV_OP() so make it an alias of TEST_CMV_OP() --- riscv-test-suite/env/arch_test.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index fc167d6ad..9f46daf28 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -1150,10 +1150,7 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) //Tests for instructions with a single register operand #define TEST_RD_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)); \ - inst destreg, reg1; \ - ) + TEST_CMV_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) #define TEST_CBRANCH_OP(inst, tempreg, reg2, val2, imm, label, swreg, offset) \ LI(reg2, MASK_XLEN(val2)) ;\ From e015eaaeb3d321ff6f36ddf1e6db02e9bc7936b5 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Mon, 21 Feb 2022 23:48:44 +0800 Subject: [PATCH 07/14] Remove SREG/LREG/REGWIDTH/MASK definition for XLEN==64 && FLEN==32: FLEN value should not affect their value --- riscv-test-suite/env/arch_test.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 9f46daf28..f0bbbe5b9 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -95,15 +95,6 @@ #endif #endif -#if XLEN==64 - #if FLEN==32 - #define SREG sw - #define LREG lW - #define REGWIDTH 4 - #define MASK 0xFFFFFFFF - #endif -#endif - #define MMODE_SIG 3 #define RLENG (REGWIDTH<<3) From ab71c016cf2691a05dd1bd9e2006d635d4237a92 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Mon, 21 Feb 2022 23:50:55 +0800 Subject: [PATCH 08/14] Expand SREG/REGWIDTH macros for RVTEST_SIGUPD_P64 and RVTEST_SIGUPD_PK64: they are valid in RV32 only --- riscv-test-suite/env/arch_test.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index f0bbbe5b9..63b60e143 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -610,14 +610,14 @@ // for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. #define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...)\ .if NARG(__VA_ARGS__) == 1;\ - SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ - SREG _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+REGWIDTH+REGWIDTH;\ + sw _R,_ARG1(__VA_ARGS__,0)(_BR);\ + sw _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+8;\ .endif;\ .if NARG(__VA_ARGS__) == 0;\ - SREG _R,offset(_BR);\ - SREG _R_HI,(offset+REGWIDTH)(_BR);\ - .set offset,offset+REGWIDTH+REGWIDTH;\ + sw _R,offset(_BR);\ + sw _R_HI,(offset+4)(_BR);\ + .set offset,offset+8;\ .endif; @@ -633,18 +633,18 @@ // for updating signatures that include flagreg when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. #define RVTEST_SIGUPD_PK64(_BR,_R,_R_HI,_F,...)\ .if NARG(__VA_ARGS__) == 1;\ - SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ - SREG _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ + sw _R,_ARG1(__VA_ARGS__,0)(_BR);\ + sw _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ RDOV(_F);\ - SREG _F,(_ARG1(__VA_ARGS__,0)+8)(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+REGWIDTH+REGWIDTH+REGWIDTH;\ + sw _F,(_ARG1(__VA_ARGS__,0)+8)(_BR);\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+12;\ .endif;\ .if NARG(__VA_ARGS__) == 0;\ - SREG _R,offset(_BR);\ - SREG _R_HI,(offset+REGWIDTH)(_BR);\ + sw _R,offset(_BR);\ + sw _R_HI,(offset+4)(_BR);\ RDOV(_F);\ - SREG _F,(offset+REGWIDTH+REGWIDTH)(_BR);\ - .set offset,offset+REGWIDTH+REGWIDTH+REGWIDTH;\ + sw _F,(offset+8)(_BR);\ + .set offset,offset+12;\ .endif; #define RVTEST_VALBASEUPD(_BR,...)\ From 717da1a6216b5ef7576e0aa359edaa355c0a79fe Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Mon, 21 Feb 2022 23:53:31 +0800 Subject: [PATCH 09/14] Save flagreg to signatures for TEST_PKRR_OP() and TEST_PKR_OP --- riscv-test-suite/env/arch_test.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 63b60e143..af54767fe 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -647,6 +647,10 @@ .set offset,offset+12;\ .endif; +// for updating signatures that include flagreg for P-ext saturation instructions (RV32/RV64). +#define RVTEST_SIGUPD_PK(_BR,_R,_F,OFFSET)\ + RVTEST_SIGUPD_FID(_BR,_R,_F,OFFSET) + #define RVTEST_VALBASEUPD(_BR,...)\ .if NARG(__VA_ARGS__) == 0;\ addi _BR,_BR,2040;\ @@ -991,24 +995,23 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) inst destreg, reg, SEXT_IMM(imm); \ rdov flagreg; \ ) + //Tests for instructions with register-register operand and update the saturation flag #define TEST_PKRR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, flagreg, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - rdov flagreg; \ - ) + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK(swreg, destreg, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) //Tests for instructions with a single register operand and update the saturation flag #define TEST_PKR_OP( inst, destreg, reg, correctval, val, flagreg, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ LI(reg, MASK_XLEN(val)); \ inst destreg, reg; \ rdov flagreg; \ ) - #if __riscv_xlen == 32 //Tests for a instruction with register pair operands for all its three operands #define TEST_P64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, swreg, offset, testreg) \ @@ -1093,6 +1096,7 @@ RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) TEST_P64_NP_OP_32(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) #else + // When in rv64, there are no instructions with pair operand, so Macro is redefined to normal TEST_RR_OP #define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) From 5e5f975d7f5029ac27ca3f8334ebd2560b955db7 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Thu, 3 Mar 2022 18:44:09 +0800 Subject: [PATCH 10/14] Implement RVTEST_SIGUPD_P64 by reusing RVTEST_SIGUPD_FID --- riscv-test-suite/env/arch_test.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index af54767fe..b69231c29 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -609,18 +609,12 @@ // for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. #define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...)\ - .if NARG(__VA_ARGS__) == 1;\ - sw _R,_ARG1(__VA_ARGS__,0)(_BR);\ - sw _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+8;\ - .endif;\ - .if NARG(__VA_ARGS__) == 0;\ - sw _R,offset(_BR);\ - sw _R_HI,(offset+4)(_BR);\ - .set offset,offset+8;\ + .if NARG(VA_ARGS) == 0;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI);\ + .else;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0)));\ .endif; - // only reads the vxsat.OV flag when Zicsr extension is present #ifdef pext_check_vxsat_ov #define RDOV(_F)\ From 49e3e0b2efcbf3cda315d5faf6d3dfb82fc0f505 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Fri, 4 Mar 2022 21:37:28 +0800 Subject: [PATCH 11/14] Automatically adjust base and offset if offset gets too big --- riscv-test-suite/env/arch_test.h | 110 ++++++++++++++++--------------- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index b69231c29..5f7ca9493 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -573,49 +573,55 @@ #define _ARG2(_1ST,_2ND, ...) _2ND #define _ARG1(_1ST,...) _1ST #define NARG(...) _ARG5(__VA_OPT__(__VA_ARGS__,)4,3,2,1,0) -#define RVTEST_SIGUPD(_BR,_R,...)\ - .if NARG(__VA_ARGS__) == 1;\ - SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+REGWIDTH;\ - .endif;\ - .if NARG(__VA_ARGS__) == 0;\ - SREG _R,offset(_BR);\ - .set offset,offset+REGWIDTH;\ - .endif; -#define RVTEST_SIGUPD_F(_BR,_R,_F,...)\ - .if NARG(__VA_ARGS__) == 1;\ - FSREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ - SREG _F,_ARG1(__VA_ARGS__,0)+REGWIDTH(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+(REGWIDTH+REGWIDTH);\ - .endif;\ - .if NARG(__VA_ARGS__) == 0;\ - FSREG _R,offset(_BR);\ - SREG _F,offset+REGWIDTH(_BR);\ - .set offset,offset+(REGWIDTH+REGWIDTH);\ - .endif; + /* automatically adjust base and offset if offset gets too big */ + /* RVTEST_SIGUPD(basereg, sigreg) stores sigreg at offset(basereg) and updates offset by regwidth */ + /* RVTEST_SIGUPD(basereg, sigreg,newoff) stores sigreg at newoff(basereg) and updates offset to regwidth+newoff */ +#define RVTEST_SIGUPD(_BR,_R,...) \ + .if offset+REGWIDTH>=2048 ;\ + addi _BR, _BR, offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + .set offset,offset+REGWIDTH + +#define RVTEST_SIGUPD_F(_BR,_R,_F,...) \ + .if offset+2*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + FSREG _R,offset(_BR) ;\ + SREG _F,offset+REGWIDTH(_BR) ;\ + .set offset,offset+(2*REGWIDTH) + -#define RVTEST_SIGUPD_FID(_BR,_R,_F,...)\ - .if NARG(__VA_ARGS__) == 1;\ - SREG _R,_ARG1(__VA_ARGS__,0)(_BR);\ - SREG _F,_ARG1(__VA_ARGS__,0)+REGWIDTH(_BR);\ - .set offset,_ARG1(__VA_ARGS__,0)+(2*REGWIDTH);\ - .endif;\ - .if NARG(__VA_ARGS__) == 0;\ - SREG _R,offset(_BR);\ - SREG _F,offset+REGWIDTH(_BR);\ - .set offset,offset+(2*REGWIDTH);\ - .endif; +#define RVTEST_SIGUPD_FID(_BR,_R,_F,...) \ + .if offset+2*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + SREG _F,offset+REGWIDTH(_BR) ;\ + .set offset,offset+(2*REGWIDTH) // for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. -#define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...)\ - .if NARG(VA_ARGS) == 0;\ - RVTEST_SIGUPD_FID(_BR,_R,_R_HI);\ - .else;\ - RVTEST_SIGUPD_FID(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0)));\ - .endif; - -// only reads the vxsat.OV flag when Zicsr extension is present +#define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...) \ + .if NARG(__VA_ARGS__) == 0 ;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI) ;\ + .else ;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0)));\ + .endif + +// for reading vxsat.OV flag in P-ext; and only reads the flag when Zicsr extension is present #ifdef pext_check_vxsat_ov #define RDOV(_F)\ rdov _F @@ -626,20 +632,18 @@ // for updating signatures that include flagreg when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. #define RVTEST_SIGUPD_PK64(_BR,_R,_R_HI,_F,...)\ - .if NARG(__VA_ARGS__) == 1;\ - sw _R,_ARG1(__VA_ARGS__,0)(_BR);\ - sw _R_HI,(_ARG1(__VA_ARGS__,0)+4)(_BR);\ - RDOV(_F);\ - sw _F,(_ARG1(__VA_ARGS__,0)+8)(_BR);\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,)0)+12;\ - .endif;\ - .if NARG(__VA_ARGS__) == 0;\ - sw _R,offset(_BR);\ - sw _R_HI,(offset+4)(_BR);\ - RDOV(_F);\ - sw _F,(offset+8)(_BR);\ - .set offset,offset+12;\ - .endif; + .if offset+3*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + SREG _R_HI,offset+REGWIDTH(_BR) ;\ + RDOV(_F) ;\ + SREG _F,offset+2*REGWIDTH(_BR) ;\ + .set offset,offset+(3*REGWIDTH) // for updating signatures that include flagreg for P-ext saturation instructions (RV32/RV64). #define RVTEST_SIGUPD_PK(_BR,_R,_F,OFFSET)\ From cbd640e1575b2b47e0ec7c42fb16563a7b376233 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Fri, 4 Mar 2022 21:45:20 +0800 Subject: [PATCH 12/14] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0439014f7..ea86faeb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## [2.6.3] - 2022-03-04 + - import and synchronize P-ext changes in arch_test.h from riscv-ctg + - automatically adjust base and offset if offset gets too big + ## [2.6.2] - 2022-02-24 - modified verify.sh to ignore comments in reference signature during diff operation [#230] - udpated test-format spec to include the order of lines in the signature file [#214] From 69b3fa0c36283b12ff30851dd0a1083c8b8c3d21 Mon Sep 17 00:00:00 2001 From: Yung-Ching Hsiao Date: Tue, 8 Mar 2022 11:31:13 +0800 Subject: [PATCH 13/14] convert arch_test.h to Unix file format --- riscv-test-suite/env/arch_test.h | 2720 +++++++++++++++--------------- 1 file changed, 1360 insertions(+), 1360 deletions(-) diff --git a/riscv-test-suite/env/arch_test.h b/riscv-test-suite/env/arch_test.h index 5f7ca9493..5c7f0ed57 100644 --- a/riscv-test-suite/env/arch_test.h +++ b/riscv-test-suite/env/arch_test.h @@ -1,1360 +1,1360 @@ -#include "encoding.h" -// TODO the following should come from the YAML. -#ifndef NUM_SPECD_INTCAUSES - #define NUM_SPECD_INTCAUSES 16 -#endif -//#define RVTEST_FIXED_LEN -#ifndef UNROLLSZ - #define UNROLLSZ 5 -#endif -// #ifndef rvtest_gpr_save -// #define rvtest_gpr_save -// #endif - -#define TEST_CASE_1 - -//----------------------------------------------------------------------- -// RV Arch Test Macros -//----------------------------------------------------------------------- -#ifndef RVMODEL_SET_MSW_INT - #warning "RVMODEL_SET_MSW_INT is not defined by target. Declaring as empty macro" - #define RVMODEL_SET_MSW_INT -#endif - -#ifndef RVMODEL_CLEAR_MSW_INT - #warning "RVMODEL_CLEAR_MSW_INT is not defined by target. Declaring as empty macro" - #define RVMODEL_CLEAR_MSW_INT -#endif - -#ifndef RVMODEL_CLEAR_MTIMER_INT - #warning "RVMODEL_CLEAR_MTIMER_INT is not defined by target. Declaring as empty macro" - #define RVMODEL_CLEAR_MTIMER_INT -#endif - -#ifndef RVMODEL_CLEAR_MEXT_INT - #warning "RVMODEL_CLEAR_MEXT_INT is not defined by target. Declaring as empty macro" - #define RVMODEL_CLEAR_MEXT_INT -#endif - -#ifdef RVTEST_FIXED_LEN - #define LI(reg, val)\ - .option push;\ - .option norvc;\ - .align UNROLLSZ;\ - li reg,val;\ - .align UNROLLSZ;\ - .option pop; - - #define LA(reg, val)\ - .option push;\ - .option norvc;\ - .align UNROLLSZ;\ - la reg,val;\ - .align UNROLLSZ;\ - .option pop; - -#else - #define LI(reg,val);\ - .option push;\ - .option norvc;\ - li reg,val;\ - .option pop; - - #define LA(reg,val);\ - .option push;\ - .option norvc;\ - la reg,val;\ - .option pop; -#endif -#if XLEN==64 - #define SREG sd - #define LREG ld - #define REGWIDTH 8 - #define MASK 0xFFFFFFFFFFFFFFFF - -#else - #if XLEN==32 - #define SREG sw - #define LREG lw - #define REGWIDTH 4 - #define MASK 0xFFFFFFFF - - #endif -#endif - -#if FLEN==64 - #define FLREG fld - #define FSREG fsd - #define FREGWIDTH 8 - -#else - #if FLEN==32 - #define FLREG flw - #define FSREG fsw - #define FREGWIDTH 4 - #endif -#endif - -#define MMODE_SIG 3 -#define RLENG (REGWIDTH<<3) - -#define RVTEST_ISA(_STR) - -#ifndef DATA_REL_TVAL_MSK - #define DATA_REL_TVAL_MSK 0x0F05 << (REGWIDTH*8-16) -#endif - -#ifndef CODE_REL_TVAL_MSK - #define CODE_REL_TVAL_MSK 0xD008 << (REGWIDTH*8-16) -#endif - - -// ----------------------------------- CODE BEGIN w/ TRAP HANDLER START ------------------------ // - -.macro RVTEST_CODE_BEGIN - .align UNROLLSZ - .section .text.init; - .globl rvtest_init; \ - rvtest_init: -#ifdef rvtest_mtrap_routine - LA(x1, rvtest_trap_prolog ); - jalr ra, x1 - rvtest_prolog_done: -#endif - LI (x1, (0xFEEDBEADFEEDBEAD & MASK)); - LI (x2, (0xFF76DF56FF76DF56 & MASK)); - LI (x3, (0x7FBB6FAB7FBB6FAB & MASK)); - LI (x4, (0xBFDDB7D5BFDDB7D5 & MASK)); - LA (x5, rvtest_code_begin); - LA (x6, rvtest_data_begin); - LI (x7, (0xB7FBB6FAB7FBB6FA & MASK)); - LI (x8, (0x5BFDDB7D5BFDDB7D & MASK)); - LI (x9, (0xADFEEDBEADFEEDBE & MASK)); - LI (x10, (0x56FF76DF56FF76DF & MASK)); - LI (x11, (0xAB7FBB6FAB7FBB6F & MASK)); - LI (x12, (0xD5BFDDB7D5BFDDB7 & MASK)); - LI (x13, (0xEADFEEDBEADFEEDB & MASK)); - LI (x14, (0xF56FF76DF56FF76D & MASK)); - LI (x15, (0xFAB7FBB6FAB7FBB6 & MASK)); - #ifndef RVTEST_E - LI (x16, (0x7D5BFDDB7D5BFDDB & MASK)); - LI (x17, (0xBEADFEEDBEADFEED & MASK)); - LI (x18, (0xDF56FF76DF56FF76 & MASK)); - LI (x19, (0x6FAB7FBB6FAB7FBB & MASK)); - LI (x20, (0xB7D5BFDDB7D5BFDD & MASK)); - LI (x21, (0xDBEADFEEDBEADFEE & MASK)); - LI (x22, (0x6DF56FF76DF56FF7 & MASK)); - LI (x23, (0xB6FAB7FBB6FAB7FB & MASK)); - LI (x24, (0xDB7D5BFDDB7D5BFD & MASK)); - LI (x25, (0xEDBEADFEEDBEADFE & MASK)); - LI (x26, (0x76DF56FF76DF56FF & MASK)); - LI (x27, (0xBB6FAB7FBB6FAB7F & MASK)); - LI (x28, (0xDDB7D5BFDDB7D5BF & MASK)); - LI (x29, (0xEEDBEADFEEDBEADF & MASK)); - LI (x30, (0xF76DF56FF76DF56F & MASK)); - LI (x31, (0xFBB6FAB7FBB6FAB7 & MASK)); - #endif - .globl rvtest_code_begin - rvtest_code_begin: -.endm - -// --------------------------------- CODE BEGIN w/ TRAP HANDLER END -----------------------------// - -.macro RVTEST_CODE_END - .align 4; - .global rvtest_code_end - rvtest_code_end: -#ifdef rvtest_mtrap_routine - .option push - .option norvc - j exit_cleanup - - rvtest_trap_prolog: - /******************************************************************************/ - /**** Prolog, to be run before any tests ****/ - /**** #include 1 copy of this per mode in rvmodel_boot code? ****/ - /**** ------------------------------------------------------------------- ****/ - /**** if xTVEC isn't completely RW, then we need to change the code at its ****/ - /**** target. The entire trap trampoline and mtrap handler replaces the ****/ - /**** area pointed to by mtvec, after saving its original contents first. ****/ - /**** If it isn't possible to fully write that area, restore and fail. ****/ - /******************************************************************************/ - - //trap_handler_prolog; enter with t1..t6 available - - init_mscratch: - la t1, trapreg_sv - csrrw t1, CSR_MSCRATCH, t1 // swap old mscratch. mscratch not points to trapreg_sv - la t2, mscratch_save - SREG t1, 0(t2) // save old mscratch in mscratch_save region - csrr t1, CSR_MSCRATCH // read the trapreg_sv address - LA( t2, mtrap_sigptr ) // locate the start of the trap signature - SREG t2, 0(t1) // save mtrap_sigptr at first location of trapreg_sv - init_mtvec: - la t1, mtrampoline - la t4, mtvec_save - csrrw t2, CSR_MTVEC, t1 // swap mtvec and trap_trampoline - SREG t2, 0(t4) // save orig mtvec - csrr t3, CSR_MTVEC // now read new_mtval back - beq t3, t1, rvtest_prolog_done // if mtvec==trap_trampoline, mtvec is writable, continue - - /****************************************************************/ - /**** fixed mtvec, can't move it so move trampoline instead ****/ - /**** t1=trampoline, t2=oldmtvec, t3=save area, t4=save end ****/ - /****************************************************************/ - - // t2 = dut's original mtvec setting - // t1 = mtrampoline address - init_tramp: /**** copy trampoline at mtvec tgt ****/ - - csrw CSR_MTVEC, t2 // restore orig mtvec, will now attemp to copy trampoline to it - la t3, tramptbl_sv // addr of save area - addi t4, t3, NUM_SPECD_INTCAUSES*4 // end of save area - - overwrite_tt: // now build new trampoline table with offsets base from curr mtvec - lw t6, 0(t2) // get original mtvec target - sw t6, 0(t3) // save it - lw t5, 0(t1) // get trampoline src - sw t5, 0(t2) // overwrite mtvec target - lw t6, 0(t2) // rd it back to make sure it was written - bne t6, t5, resto_tramp // table isn't fully writable, restore and give up - addi t1, t1, 4 // next src index - addi t2, t2, 4 // next tgt index - addi t3, t3, 4 // next save index - bne t3, t4, overwrite_tt // not done, loop - j rvtest_prolog_done - - resto_tramp: // vector table not writeable, restore - LREG t1, 16(t4) // load mscratch_SAVE at fixed offset from table end - csrw CSR_MSCRATCH, t1 // restore mscratch - LREG t4, 8(t4) // load mtvec_SAVE (used as end of loop marker) - - - resto_loop: // goes backwards, t2= dest vec tbl ptr, t3=src save area ptr, t4=vec tbl begin - lw t6, 0(t3) // read saved tgt entry - sw t6, 0(t2) // restore original tgt - addi t2, t2, -4 // prev tgt index - addi t3, t3, -4 // prev save index - bne t2, t4, resto_loop // didn't restore to begining yet, loop - - j rvtest_end // failure to replace trampoline - - - #define mhandler \ - csrrw sp, CSR_MSCRATCH, sp; \ - SREG t6, 6*REGWIDTH(sp); \ - jal t6, common_prolog; - - /**********************************************************************/ - /**** This is the entry point for all m-modetraps, vectored or not.****/ - /**** At entry, mscratch will contain a pointer to a scratch area. ****/ - /**** This is an array of branches at 4B intevals that spreads out ****/ - /**** to an array of 32B mhandler macros for specd int causes, and ****/ - /**** to a return for anything above that (which causes a mismatch)****/ - /**********************************************************************/ - mtrampoline: // 64 or 32 entry table - value = 0 - .rept NUM_SPECD_INTCAUSES // located at each possible int vectors - j mtrap_handler + 12*(value) //offset < +/- 1MB - value = value + 1 - .endr - .rept RLENG-NUM_SPECD_INTCAUSES // fill at each impossible entry - mret - .endr - - mtrap_handler: /* after executing, sp points to temp save area, t4 is PC */ - .rept NUM_SPECD_INTCAUSES - mhandler - .endr - - common_prolog: - la t5, common_mhandler - jr t5 - /*********************************************************************/ - /**** common code for all ints & exceptions, will fork to handle ****/ - /**** each separately. The common handler first stores trap mode+ ****/ - /**** vector, and mcause signatures. All traps have 4wd sigs, but ****/ - /**** sw and timer ints only store 3 of the 4. ****/ - /**** sig offset Exception ExtInt SWInt TimerInt ****/ - /**** 0: tval IntID -1 -1 ****/ - /**** 4: mepc mip mip mip ****/ - /**** 8: <---------------------- mcause -------------> ****/ - /**** 12: <--------------------- Vect+mode ----------> ****/ - /*********************************************************************/ - /* in general, CSRs loaded in t2, addresses into t3 */ - - common_mhandler: /* enter with link in t6 */ - SREG t5, 5*REGWIDTH(sp) - SREG t4, 4*REGWIDTH(sp) - SREG t3, 3*REGWIDTH(sp) - SREG t2, 2*REGWIDTH(sp) - SREG t1, 1*REGWIDTH(sp) /* save other temporaries */ - - LREG t1, 0(sp) /* load trap sig pointer (runs backwards from DATA_END) */ - - LA( t3, mtrampoline) - sub t2, t6, t3 /* reloc “link” to 0..63 to show which int vector was taken */ - addi t2, t2, MMODE_SIG /* insert mode# into 1:0 */ - SREG t2, 0*REGWIDTH(t1) /* save 1st sig value, (vect, trapmode) */ - sv_mcause: - csrr t2, CSR_MCAUSE - SREG t2, 1*REGWIDTH(t1) /* save 2nd sig value, (mcause) */ - - bltz t2, common_mint_handler /* this is a interrupt, not a trap */ - - /********************************************************************/ - /**** This is the exceptions specific code, storing relative mepc****/ - /**** & relative tval signatures. tval is relocated by code or ****/ - /**** data start, or 0 depending on mcause. mepc signature value ****/ - /**** is relocated by code start, and restored adjusted depending****/ - /**** on op alignment so trapped op isn't re-executed. ****/ - /********************************************************************/ - common_mexcpt_handler: - csrr t2, CSR_MEPC - sv_mepc: - LA( t3, rvtest_prolog_done) /* offset to compensate for different loader offsets */ - sub t4, t2, t3 /* convert mepc to rel offset of beginning of test*/ - SREG t4, 2*REGWIDTH(t1) /* save 3rd sig value, (rel mepc) into trap signature area */ - adj_mepc: //adj mepc so there is padding after op, and its 8B aligned - andi t4, t2, 0x2 /* set to 2 if mepc was misaligned */ - sub t2, t2, t4 /* adjust mepc to prev 4B alignment */ - addi t2, t2, 0x8 /* adjust mepc, so it skips past the op, has padding & is 4B aligned */ - csrw CSR_MEPC, t2 /* restore adjusted value, has 1,2, or 3 bytes of padding */ - - - /* calculate relative mtval if it’s an address (by code_begin or data_begin amt) */ - /* note that masks that determine this are implementation specific from YAML */ - - /* masks are bit reversed, so mcause==0 bit is in MSB (so different for RV32 and RV64) */ - - adj_mtval: - csrr t2, CSR_MCAUSE /* code begin adjustment amount already in t3 */ - - LI(t4, CODE_REL_TVAL_MSK) /* trap#s 12, 3,1,0, -- adjust w/ code_begin */ - sll t4, t4, t2 /* put bit# in MSB */ - bltz t4, sv_mtval /* correct adjustment is code_begin in t3 */ - - LA( t3, mtrap_sigptr) /* adjustment assuming access is to signature region */ - LI(t4, DATA_REL_TVAL_MSK) /* trap#s not 14, 11..8, 2 adjust w/ data_begin */ - sll t4, t4, t2 /* put bit# in MSB */ - bgez t4, no_adj /* correct adjustment is data_begin in t3 */ - sigbound_chk: - csrr t4, CSR_MTVAL /* do a bounds check on mtval */ - bge t3, t4, sv_mtval /* if mtval is greater than the rvmodel_data_begin then use that as anchor */ - LA( t3, rvtest_data_begin) /* else change anchor to rvtest_data_begin */ - blt t3, t4, sv_mtval /* before the signature, use data_begin adj */ - mv t4, t3 /* use sig relative adjust */ - no_adj: - LI(t3, 0) /* else zero adjustment amt */ - - // For Illegal op handling - addi t2, t2, -2 /* check if mcause==2 (illegal op) */ - bnez t2, sv_mtval /* not illegal op, no special treatment */ - csrr t2, CSR_MTVAL - bnez t2, sv_mtval /* mtval isn’t zero, no special treatment */ - illop: - LI(t5, 0x20000) /* get mprv mask */ - csrrs t5, CSR_MSTATUS, t5 /* set mprv while saving the old value */ - csrr t3, CSR_MEPC - lhu t2, 0(t3) /* load 1st 16b of opc w/ old priv, endianess*/ - andi t4, t2, 0x3 - addi t4, t4, -0x3 /* does opcode[1:0]==0b11? (Meaning >16b op) */ - bnez t4, sv_mtval /* entire mtval is in tt2, adj amt will be set to zero */ - lhu t4, 2(t3) - sll t4, t4, 16 - or t3, t2, t4 /* get 2nd hwd, align it & insert it into opcode */ - csrw CSR_MSTATUS, t5 /* restore mstatus */ - -/*******FIXME: this will not handle 48 or 64b opcodes in an RV64) ********/ - - sv_mtval: - csrr t2, CSR_MTVAL - sub t2, t2, t3 /* perform mtval adjust by either code or data position or zero*/ - SREG t2, 3*REGWIDTH(t1) /* save 4th sig value, (rel mtval) into trap signature area */ - - resto_rtn: /* restore and return */ - addi t1, t1,4*REGWIDTH /* adjust trap signature ptr (traps always save 4 words) */ - SREG t1, 0*REGWIDTH(sp) /* save updated trap sig pointer (pts to trap_sigptr */ - - LREG t1, 1*REGWIDTH(sp) - LREG t2, 2*REGWIDTH(sp) - LREG t3, 3*REGWIDTH(sp) - LREG t4, 4*REGWIDTH(sp) - LREG t5, 5*REGWIDTH(sp) - LREG t6, 6*REGWIDTH(sp) /* restore temporaries */ - - csrrw sp, CSR_MSCRATCH, sp /* restore sp from scratch */ - mret - - common_mint_handler: /* t1 has sig ptr, t2 has mcause */ - - LI(t3, 1) - sll t3, t3, t2 /* create mask 1<> 1); \ - csrs mstatus, a0; \ - csrwi fcsr, 0 - -#ifdef pext_check_vxsat_ov -#define RVTEST_VXSAT_ENABLE()\ - li a0, MSTATUS_VS & (MSTATUS_VS >> 1); \ - csrs mstatus, a0; \ - clrov -#else -#define RVTEST_VXSAT_ENABLE() -#endif - -#define RVTEST_SIGBASE(_R,_TAG) \ - LA(_R,_TAG);\ - .set offset,0; - -.set offset,0; -#define _ARG5(_1ST,_2ND, _3RD,_4TH,_5TH,...) _5TH -#define _ARG4(_1ST,_2ND, _3RD,_4TH,...) _4TH -#define _ARG3(_1ST,_2ND, _3RD, ...) _3RD -#define _ARG2(_1ST,_2ND, ...) _2ND -#define _ARG1(_1ST,...) _1ST -#define NARG(...) _ARG5(__VA_OPT__(__VA_ARGS__,)4,3,2,1,0) - - /* automatically adjust base and offset if offset gets too big */ - /* RVTEST_SIGUPD(basereg, sigreg) stores sigreg at offset(basereg) and updates offset by regwidth */ - /* RVTEST_SIGUPD(basereg, sigreg,newoff) stores sigreg at newoff(basereg) and updates offset to regwidth+newoff */ -#define RVTEST_SIGUPD(_BR,_R,...) \ - .if offset+REGWIDTH>=2048 ;\ - addi _BR, _BR, offset ;\ - .set offset, 0 ;\ - .endif ;\ - .if NARG(__VA_ARGS__) == 1 ;\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ - .endif ;\ - SREG _R,offset(_BR) ;\ - .set offset,offset+REGWIDTH - -#define RVTEST_SIGUPD_F(_BR,_R,_F,...) \ - .if offset+2*REGWIDTH>=2048 ;\ - addi _BR, _BR,offset ;\ - .set offset, 0 ;\ - .endif ;\ - .if NARG(__VA_ARGS__) == 1 ;\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ - .endif ;\ - FSREG _R,offset(_BR) ;\ - SREG _F,offset+REGWIDTH(_BR) ;\ - .set offset,offset+(2*REGWIDTH) - - -#define RVTEST_SIGUPD_FID(_BR,_R,_F,...) \ - .if offset+2*REGWIDTH>=2048 ;\ - addi _BR, _BR,offset ;\ - .set offset, 0 ;\ - .endif ;\ - .if NARG(__VA_ARGS__) == 1 ;\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ - .endif ;\ - SREG _R,offset(_BR) ;\ - SREG _F,offset+REGWIDTH(_BR) ;\ - .set offset,offset+(2*REGWIDTH) - -// for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. -#define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...) \ - .if NARG(__VA_ARGS__) == 0 ;\ - RVTEST_SIGUPD_FID(_BR,_R,_R_HI) ;\ - .else ;\ - RVTEST_SIGUPD_FID(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0)));\ - .endif - -// for reading vxsat.OV flag in P-ext; and only reads the flag when Zicsr extension is present -#ifdef pext_check_vxsat_ov -#define RDOV(_F)\ - rdov _F -#else -#define RDOV(_F)\ - nop -#endif - -// for updating signatures that include flagreg when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. -#define RVTEST_SIGUPD_PK64(_BR,_R,_R_HI,_F,...)\ - .if offset+3*REGWIDTH>=2048 ;\ - addi _BR, _BR,offset ;\ - .set offset, 0 ;\ - .endif ;\ - .if NARG(__VA_ARGS__) == 1 ;\ - .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ - .endif ;\ - SREG _R,offset(_BR) ;\ - SREG _R_HI,offset+REGWIDTH(_BR) ;\ - RDOV(_F) ;\ - SREG _F,offset+2*REGWIDTH(_BR) ;\ - .set offset,offset+(3*REGWIDTH) - -// for updating signatures that include flagreg for P-ext saturation instructions (RV32/RV64). -#define RVTEST_SIGUPD_PK(_BR,_R,_F,OFFSET)\ - RVTEST_SIGUPD_FID(_BR,_R,_F,OFFSET) - -#define RVTEST_VALBASEUPD(_BR,...)\ - .if NARG(__VA_ARGS__) == 0;\ - addi _BR,_BR,2040;\ - .endif;\ - .if NARG(__VA_ARGS__) == 1;\ - LA(_BR,_ARG1(__VA_ARGS__,x0));\ - .endif; - -#define RVTEST_VALBASEMOV(_NR,_BR)\ - add _NR, _BR, x0; -/* - * RVTEST_BASEUPD(base reg) - updates the base register the last signature address + REGWIDTH - * RVTEST_BASEUPD(base reg, new reg) - moves value of the next signature region to update into new reg - * The hidden variable offset is reset always -*/ - -#define RVTEST_BASEUPD(_BR,...)\ - .if NARG(__VA_ARGS__) == 0;\ - addi _BR,_BR,offset;\ - .endif;\ - .if NARG(__VA_ARGS__) == 1;\ - addi _ARG1(__VA_ARGS__,x0),_BR,offset;\ - .endif;\ - .set offset,0; - - - -//------------------------------ BORROWED FROM ANDREW's RISC-V TEST MACROS -----------------------// -#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1)) - -#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11)) - -#define TEST_JALR_OP(tempreg, rd, rs1, imm, swreg, offset,adj) \ -5: ;\ - LA(rd,5b ) ;\ - .if adj & 1 == 1 ;\ - LA(rs1, 3f-imm+adj-1 ) ;\ - jalr rd, imm+1(rs1) ;\ - .else ;\ - LA(rs1, 3f-imm+adj) ;\ - jalr rd, imm(rs1) ;\ - .endif ;\ - nop ;\ - nop ;\ - xori rd,rd, 0x2 ;\ - j 4f ;\ - ;\ -3: .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - xori rd,rd, 0x3 ;\ - j 4f ;\ - .if adj&2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - ;\ -4: LA(tempreg, 5b ) ;\ - andi tempreg,tempreg,~(3) ;\ - sub rd,rd,tempreg ;\ - RVTEST_SIGUPD(swreg,rd,offset) -//SREG rd, offset(swreg); - -#define TEST_JAL_OP(tempreg, rd, imm, label, swreg, offset, adj)\ -5: ;\ - LA(tempreg, 2f ) ;\ - jalr x0,0(tempreg) ;\ -6: LA(tempreg, 4f ) ;\ - jalr x0,0(tempreg) ;\ -1: .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - xori rd,rd, 0x1 ;\ - beq x0,x0,6b ;\ - .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - .if (imm/2) - 2 >= 0 ;\ - .set num,(imm/2)-2 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 3f ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - nop ;\ - .endr ;\ - ;\ -2: jal rd, label+(adj) ;\ - .if adj & 2 == 2 ;\ - nop ;\ - nop ;\ - .endif ;\ - xori rd,rd, 0x2 ;\ - j 4f ;\ - .if (imm/2) - 3 >= 0 ;\ - .set num,(imm/2)-3 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 1b ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - nop ;\ - .endr ;\ -3: .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - xori rd,rd, 0x3 ;\ - LA(tempreg, 4f ) ;\ - jalr x0,0(tempreg) ;\ - .if adj&2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ -4: LA(tempreg, 5b ) ;\ - andi tempreg,tempreg,~(3) ;\ - sub rd,rd,tempreg ;\ - RVTEST_SIGUPD(swreg,rd,offset) -//SREG rd, offset(swreg); - -#define TEST_BRANCH_OP(inst, tempreg, reg1, reg2, val1, val2, imm, label, swreg, offset,adj) \ - LI(reg1, MASK_XLEN(val1)) ;\ - LI(reg2, MASK_XLEN(val2)) ;\ - addi tempreg,x0,0 ;\ - j 2f ;\ - ;\ -1: .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - addi tempreg,tempreg, 0x1 ;\ - j 4f ;\ - .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - .if (imm/2) - 2 >= 0 ;\ - .set num,(imm/2)-2 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 3f ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - nop ;\ - .endr ;\ - ;\ -2: inst reg1, reg2, label+adj ;\ - addi tempreg, tempreg,0x2 ;\ - j 4f ;\ - .if (imm/4) - 3 >= 0 ;\ - .set num,(imm/4)-3 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 1b ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - nop ;\ - .endr ;\ - ;\ -3: .if adj & 2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - addi tempreg, tempreg,0x3 ;\ - j 4f ;\ - .if adj&2 == 2 ;\ - .fill 2,1,0x00 ;\ - .endif ;\ - ;\ -4: RVTEST_SIGUPD(swreg,tempreg,offset) -//SREG tempreg, offset(swreg); - -#define TEST_STORE(swreg,testreg,index,rs1,rs2,rs2_val,imm_val,offset,inst,adj) ;\ -LI(rs2,rs2_val) ;\ -addi rs1,swreg,offset+adj ;\ -LI(testreg,imm_val) ;\ -sub rs1,rs1,testreg ;\ -inst rs2, imm_val(rs1) ;\ -nop ;\ -nop - -#define TEST_LOAD(swreg,testreg,index,rs1,destreg,imm_val,offset,inst,adj) ;\ -LA(rs1,rvtest_data+(index*4)+adj-imm_val) ;\ -inst destreg, imm_val(rs1) ;\ -nop ;\ -nop ;\ -RVTEST_SIGUPD(swreg,destreg,offset) -//SREG destreg, offset(swreg); - -#define TEST_STORE_F(swreg,testreg,index,rs1,rs2,rs2_val,imm_val,offset,inst,adj,flagreg) ;\ -LI(flagreg,rs2_val) ;\ -fmv.w.x rs2, flagreg ;\ -addi rs1,swreg,offset+adj ;\ -LI(testreg,imm_val) ;\ -sub rs1,rs1,testreg ;\ -inst rs2, imm_val(rs1) ;\ -nop ;\ -nop ;\ -csrrs flagreg, fflags, x0 ;\ -RVTEST_SIGUPD(swreg,flagreg,offset) - -#define TEST_LOAD_F(swreg,testreg,index,rs1,destreg,imm_val,offset,inst,adj,flagreg) ;\ -LA(rs1,rvtest_data+(index*4)+adj-imm_val) ;\ -inst destreg, imm_val(rs1) ;\ -nop ;\ -nop ;\ -csrrs flagreg, fflags, x0 ;\ -RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) - -#define TEST_CSR_FIELD(ADDRESS,TEMP_REG,MASK_REG,NEG_MASK_REG,VAL,DEST_REG,OFFSET,BASE_REG) \ - LI(TEMP_REG,VAL);\ - and TEMP_REG,TEMP_REG,MASK_REG;\ - csrr DEST_REG,ADDRESS;\ - and DEST_REG,DEST_REG,NEG_MASK_REG;\ - or TEMP_REG,TEMP_REG,DEST_REG;\ - csrw ADDRESS,TEMP_REG;\ - csrr DEST_REG,ADDRESS;\ - RVTEST_SIGUPD(BASE_REG,DEST_REG,OFFSET) - - -#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... ) \ - code; \ - RVTEST_SIGUPD(swreg,destreg,offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) - -#define TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, code... ) \ - code; \ - RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) - -#define TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, code... ) \ - code; \ - RVTEST_SIGUPD_FID(swreg,destreg,flagreg,offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) - -#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LA testreg, 1f; \ - 1: \ - inst destreg, imm; \ - sub destreg, destreg, testreg; \ - ) - -//Tests for instructions with register-immediate operand -#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg, MASK_XLEN(val)); \ - inst destreg, reg, SEXT_IMM(imm); \ - ) - -//Tests for floating-point instructions with a single register operand -#define TEST_FPSR_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ - FLREG freg, val_offset(valaddr_reg); \ - csrrwi x0, frm, rm; \ - inst destreg, freg; \ - csrrs flagreg, fflags, x0; \ - ) - -//Tests for floating-point instructions with a single register operand and integer destination register -#define TEST_FPID_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ - FLREG freg, val_offset(valaddr_reg); \ - csrrwi x0, frm, rm; \ - inst destreg, freg; \ - csrrs flagreg, fflags, x0; \ - ) - -//Tests for floating-point instructions with a single register operand and integer operand register -#define TEST_FPIO_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ - LREG freg, val_offset(valaddr_reg); \ - csrrwi x0, frm, rm; \ - inst destreg, freg; \ - csrrs flagreg, fflags, x0; \ - ) - -//Tests for instructions with register-register-immediate operands -#define TEST_RRI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2, imm; \ - ) - -//Tests for a instructions with register-register operand -#define TEST_RI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2, imm; \ - ) - -//Tests for a instructions with register-register operand -#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - ) -//Tests for floating-point instructions with register-register operand -#define TEST_FPRR_OP(inst, destreg, freg1, freg2, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ - FLREG freg1, val_offset(valaddr_reg); \ - FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ - csrrwi x0, frm, rm; \ - inst destreg, freg1, freg2; \ - csrrs flagreg, fflags, x0; \ - ) - -//Tests for floating-point CMP instructions with register-register operand -#define TEST_FCMP_OP(inst, destreg, freg1, freg2, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ - FLREG freg1, val_offset(valaddr_reg); \ - FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ - inst destreg, freg1, freg2; \ - csrrs flagreg, fflags, x0; \ - ) - -//Tests for floating-point R4 type instructions -#define TEST_FPR4_OP(inst, destreg, freg1, freg2, freg3, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ - TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ - FLREG freg1, val_offset(valaddr_reg); \ - FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ - FLREG freg3, val_offset+2*FREGWIDTH(valaddr_reg); \ - csrrwi x0, frm, rm; \ - inst destreg, freg1, freg2, freg3; \ - csrrs flagreg, fflags, x0; \ - ) - -#define TEST_CNOP_OP( inst, testreg, imm_val, swreg, offset) \ - TEST_CASE(testreg, x0, 0, swreg, offset, \ - inst imm_val; \ - ) - -//Tests for instructions with register-immediate operand and update the saturation flag -#define TEST_PKIMM_OP( inst, destreg, reg, correctval, val, imm, flagreg, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg, MASK_XLEN(val)); \ - inst destreg, reg, SEXT_IMM(imm); \ - rdov flagreg; \ - ) - -//Tests for instructions with register-register operand and update the saturation flag -#define TEST_PKRR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, flagreg, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_PK(swreg, destreg, flagreg, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) - -//Tests for instructions with a single register operand and update the saturation flag -#define TEST_PKR_OP( inst, destreg, reg, correctval, val, flagreg, swreg, offset, testreg) \ - TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ - LI(reg, MASK_XLEN(val)); \ - inst destreg, reg; \ - rdov flagreg; \ - ) - -#if __riscv_xlen == 32 -//Tests for a instruction with register pair operands for all its three operands -#define TEST_P64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg1_hi, MASK_XLEN(val1_hi)); \ - LI(reg2, MASK_XLEN(val2)); \ - LI(reg2_hi, MASK_XLEN(val2_hi)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_P64(swreg,destreg, destreg_hi, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) - -#define TEST_PK64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, flagreg, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg1_hi, MASK_XLEN(val1_hi)); \ - LI(reg2, MASK_XLEN(val2)); \ - LI(reg2_hi, MASK_XLEN(val2_hi)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_PK64(swreg,destreg, destreg_hi, flagreg, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) - -#define TEST_P64_PPN_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, correctval, correctval_hi, val1, val1_hi, val2, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg1_hi, MASK_XLEN(val1_hi)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) - -#define TEST_P64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) - -#define TEST_PK64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, flagreg, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD_PK64(swreg, destreg, destreg_hi, flagreg, offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) - -#define TEST_P64_NPN_OP_32(inst, destreg, reg1, reg1_hi, reg2, correctval, val1, val1_hi, val2, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg1_hi, MASK_XLEN(val1_hi)); \ - LI(reg2, MASK_XLEN(val2)); \ - inst destreg, reg1, reg2; \ - RVTEST_SIGUPD(swreg,destreg,offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); - -#define TEST_P64_NP_OP_32(inst, destreg, reg1, reg1_hi, correctval, val1, val1_hi, imm_val, swreg, offset, testreg) \ - LI(reg1, MASK_XLEN(val1)); \ - LI(reg1_hi, MASK_XLEN(val1_hi)); \ - inst destreg, reg1, imm_val; \ - RVTEST_SIGUPD(swreg,destreg,offset); \ - RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); - -//Tests for a instruction with pair register rd, pair register rs1 and pair register rs2 -#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ - TEST_P64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) -#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ - TEST_PK64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) -//Tests for a instruction with pair register rd, pair register rs1 and normal register rs2 -#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ - TEST_P64_PPN_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) -//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 -#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ - TEST_P64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) -//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 -#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ - TEST_PK64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) -//Tests for a instruction with normal register rd, pair register rs1 and normal register rs2 -#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ - TEST_P64_NPN_OP_32(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) -//Tests for a instruction with normal register rd, pair register rs1 -#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ - TEST_P64_NP_OP_32(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) - -#else - -// When in rv64, there are no instructions with pair operand, so Macro is redefined to normal TEST_RR_OP -#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ - TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) -#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ - TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) -#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ - TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) -#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ - TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) -#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ - TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) -#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ - TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) -#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ - TEST_IMM_OP(inst, rd, rs1, correctval, rs1_val, imm_val, swreg, offset, testreg) - -#endif - - - - -#define TEST_CMV_OP( inst, destreg, reg, correctval, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg, MASK_XLEN(val2)); \ - inst destreg, reg; \ - ) - -#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg, MASK_XLEN(val2)); \ - LI(destreg, MASK_XLEN(val1)); \ - inst destreg, reg; \ - ) - -#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(destreg, MASK_XLEN(val)); \ - inst destreg, imm; \ - ) - -#define TEST_CADDI4SPN_OP( inst, destreg, correctval, imm, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(x2, 0); \ - inst destreg, x2,imm; \ - ) - -//Tests for instructions with a single register operand -#define TEST_RD_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) \ - TEST_CMV_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) - -#define TEST_CBRANCH_OP(inst, tempreg, reg2, val2, imm, label, swreg, offset) \ - LI(reg2, MASK_XLEN(val2)) ;\ - j 2f ;\ - addi tempreg, x0,0 ;\ - .option push ;\ - .option norvc ;\ -1: addi tempreg, tempreg,0x1 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 4 >= 0 ;\ - .set num,(imm/2)-4 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 3f ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ -2: inst reg2, label ;\ - .option push ;\ - .option norvc ;\ - addi tempreg, tempreg, 0x2 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 5 >= 0 ;\ - .set num,(imm/2)-5 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 1b ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ - ;\ -3: addi tempreg, tempreg ,0x3 ;\ - ;\ -4: RVTEST_SIGUPD(swreg,tempreg,offset) -//SREG tempreg, offset(swreg); - - -#define TEST_CJ_OP(inst, tempreg, imm, label, swreg, offset) \ - .option push ;\ - .option norvc ;\ - j 2f ;\ - addi tempreg,x0,0 ;\ -1: addi tempreg, tempreg,0x1 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 4 >= 0 ;\ - .set num,(imm/2)-4 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 3f ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ -2: inst label ;\ - .option push ;\ - .option norvc ;\ - addi tempreg, tempreg, 0x2 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 5 >= 0 ;\ - .set num,(imm/2)-5 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 1b ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ - ;\ -3: addi tempreg, tempreg, 0x3 ;\ - ;\ -4: RVTEST_SIGUPD(swreg,tempreg,offset) -//SREG tempreg, offset(swreg); - -#define TEST_CJAL_OP(inst, tempreg, imm, label, swreg, offset) \ -5: ;\ - j 2f ;\ - ;\ - .option push ;\ - .option norvc ;\ -1: xori x1,x1, 0x1 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 4 >= 0 ;\ - .set num,(imm/2)-4 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 3f ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ -2: inst label ;\ - .option push ;\ - .option norvc ;\ - xori x1,x1, 0x2 ;\ - j 4f ;\ - .option pop ;\ - .if (imm/2) - 5 >= 0 ;\ - .set num,(imm/2)-5 ;\ - .else ;\ - .set num,0 ;\ - .endif ;\ - .if label == 1b ;\ - .set num,0 ;\ - .endif ;\ - .rept num ;\ - c.nop ;\ - .endr ;\ - ;\ -3: xori x1,x1, 0x3 ;\ - ;\ -4: LA(tempreg, 5b) ;\ - andi tempreg,tempreg,~(3) ;\ - sub x1,x1,tempreg ;\ - RVTEST_SIGUPD(swreg,x1,offset) -//SREG x1, offset(swreg); - -#define TEST_CJR_OP(tempreg, rs1, swreg, offset) \ -5: ;\ - LA(rs1, 3f) ;\ - ;\ -2: c.jr rs1 ;\ - xori rs1,rs1, 0x2 ;\ - j 4f ;\ - ;\ -3: xori rs1,rs1, 0x3 ;\ - ;\ -4: LA(tempreg, 5b) ;\ - andi tempreg,tempreg,~(3) ;\ - sub rs1,rs1,tempreg ;\ - RVTEST_SIGUPD(swreg,rs1,offset) -//SREG rs1, offset(swreg); - -#define TEST_CJALR_OP(tempreg, rs1, swreg, offset) \ -5: ;\ - LA(rs1, 3f ) ;\ - ;\ -2: c.jalr rs1 ;\ - xori x1,x1, 0x2 ;\ - j 4f ;\ - ;\ -3: xori x1,x1, 0x3 ;\ - ;\ -4: LA(tempreg, 5b ) ;\ - andi tempreg,tempreg,~(3) ;\ - sub x1,x1,tempreg ;\ - RVTEST_SIGUPD(swreg,x1,offset) -//SREG x1, offset(swreg); - - -//--------------------------------- Migration aliases ------------------------------------------ -#ifdef RV_COMPLIANCE_RV32M - #warning "RV_COMPLIANCE_RV32M macro will be deprecated." - #define RVMODEL_BOOT \ - RVTEST_IO_INIT; \ - RV_COMPLIANCE_RV32M ; \ - RV_COMPLIANCE_CODE_BEGIN -#endif - -#define SWSIG(a, b) - -#ifdef RV_COMPLIANCE_DATA_BEGIN - #warning "RV_COMPLIANCE_DATA_BEGIN macro deprecated in v0.2. Please use RVMODEL_DATA_BEGIN instead" - #define RVMODEL_DATA_BEGIN \ - RV_COMPLIANCE_DATA_BEGIN -#endif - -#ifdef RV_COMPLIANCE_DATA_END - #warning "RV_COMPLIANCE_DATA_END macro deprecated in v0.2. Please use RVMODEL_DATA_END instead" - #define RVMODEL_DATA_END \ - RV_COMPLIANCE_DATA_END -#endif - -#ifdef RV_COMPLIANCE_HALT - #warning "RV_COMPLIANCE_HALT macro deprecated in v0.2. Please use RVMODEL_HALT instead" - #define RVMODEL_HALT \ - RV_COMPLIANCE_HALT -#endif - -#ifdef RVTEST_IO_ASSERT_GPR_EQ - #warning "RVTEST_IO_ASSERT_GPR_EQ macro deprecated in v0.2. Please use RVMODEL_IO_ASSERT_GPR_EQ instead" - #define RVMODEL_IO_ASSERT_GPR_EQ(_SP, _R, _I) \ - RVTEST_IO_ASSERT_GPR_EQ(_SP,_R, _I) -#endif - -#ifdef RVTEST_IO_WRITE_STR - #warning "RVTEST_IO_WRITE_STR macro deprecated in v0.2. Please use RVMODEL_IO_WRITE_STR instead" - #define RVMODEL_IO_WRITE_STR(_SP, _STR) \ - RVTEST_IO_WRITE_STR(_SP, _STR) -#endif - -#ifdef RVTEST_IO_INIT - #warning "RVTEST_IO_INIT is deprecated in v0.2. Please use RVMODEL_BOOT for initialization" -#endif - -#ifdef RVTEST_IO_CHECK - #warning "RVTEST_IO_CHECK is deprecated in v0.2. -#endif +#include "encoding.h" +// TODO the following should come from the YAML. +#ifndef NUM_SPECD_INTCAUSES + #define NUM_SPECD_INTCAUSES 16 +#endif +//#define RVTEST_FIXED_LEN +#ifndef UNROLLSZ + #define UNROLLSZ 5 +#endif +// #ifndef rvtest_gpr_save +// #define rvtest_gpr_save +// #endif + +#define TEST_CASE_1 + +//----------------------------------------------------------------------- +// RV Arch Test Macros +//----------------------------------------------------------------------- +#ifndef RVMODEL_SET_MSW_INT + #warning "RVMODEL_SET_MSW_INT is not defined by target. Declaring as empty macro" + #define RVMODEL_SET_MSW_INT +#endif + +#ifndef RVMODEL_CLEAR_MSW_INT + #warning "RVMODEL_CLEAR_MSW_INT is not defined by target. Declaring as empty macro" + #define RVMODEL_CLEAR_MSW_INT +#endif + +#ifndef RVMODEL_CLEAR_MTIMER_INT + #warning "RVMODEL_CLEAR_MTIMER_INT is not defined by target. Declaring as empty macro" + #define RVMODEL_CLEAR_MTIMER_INT +#endif + +#ifndef RVMODEL_CLEAR_MEXT_INT + #warning "RVMODEL_CLEAR_MEXT_INT is not defined by target. Declaring as empty macro" + #define RVMODEL_CLEAR_MEXT_INT +#endif + +#ifdef RVTEST_FIXED_LEN + #define LI(reg, val)\ + .option push;\ + .option norvc;\ + .align UNROLLSZ;\ + li reg,val;\ + .align UNROLLSZ;\ + .option pop; + + #define LA(reg, val)\ + .option push;\ + .option norvc;\ + .align UNROLLSZ;\ + la reg,val;\ + .align UNROLLSZ;\ + .option pop; + +#else + #define LI(reg,val);\ + .option push;\ + .option norvc;\ + li reg,val;\ + .option pop; + + #define LA(reg,val);\ + .option push;\ + .option norvc;\ + la reg,val;\ + .option pop; +#endif +#if XLEN==64 + #define SREG sd + #define LREG ld + #define REGWIDTH 8 + #define MASK 0xFFFFFFFFFFFFFFFF + +#else + #if XLEN==32 + #define SREG sw + #define LREG lw + #define REGWIDTH 4 + #define MASK 0xFFFFFFFF + + #endif +#endif + +#if FLEN==64 + #define FLREG fld + #define FSREG fsd + #define FREGWIDTH 8 + +#else + #if FLEN==32 + #define FLREG flw + #define FSREG fsw + #define FREGWIDTH 4 + #endif +#endif + +#define MMODE_SIG 3 +#define RLENG (REGWIDTH<<3) + +#define RVTEST_ISA(_STR) + +#ifndef DATA_REL_TVAL_MSK + #define DATA_REL_TVAL_MSK 0x0F05 << (REGWIDTH*8-16) +#endif + +#ifndef CODE_REL_TVAL_MSK + #define CODE_REL_TVAL_MSK 0xD008 << (REGWIDTH*8-16) +#endif + + +// ----------------------------------- CODE BEGIN w/ TRAP HANDLER START ------------------------ // + +.macro RVTEST_CODE_BEGIN + .align UNROLLSZ + .section .text.init; + .globl rvtest_init; \ + rvtest_init: +#ifdef rvtest_mtrap_routine + LA(x1, rvtest_trap_prolog ); + jalr ra, x1 + rvtest_prolog_done: +#endif + LI (x1, (0xFEEDBEADFEEDBEAD & MASK)); + LI (x2, (0xFF76DF56FF76DF56 & MASK)); + LI (x3, (0x7FBB6FAB7FBB6FAB & MASK)); + LI (x4, (0xBFDDB7D5BFDDB7D5 & MASK)); + LA (x5, rvtest_code_begin); + LA (x6, rvtest_data_begin); + LI (x7, (0xB7FBB6FAB7FBB6FA & MASK)); + LI (x8, (0x5BFDDB7D5BFDDB7D & MASK)); + LI (x9, (0xADFEEDBEADFEEDBE & MASK)); + LI (x10, (0x56FF76DF56FF76DF & MASK)); + LI (x11, (0xAB7FBB6FAB7FBB6F & MASK)); + LI (x12, (0xD5BFDDB7D5BFDDB7 & MASK)); + LI (x13, (0xEADFEEDBEADFEEDB & MASK)); + LI (x14, (0xF56FF76DF56FF76D & MASK)); + LI (x15, (0xFAB7FBB6FAB7FBB6 & MASK)); + #ifndef RVTEST_E + LI (x16, (0x7D5BFDDB7D5BFDDB & MASK)); + LI (x17, (0xBEADFEEDBEADFEED & MASK)); + LI (x18, (0xDF56FF76DF56FF76 & MASK)); + LI (x19, (0x6FAB7FBB6FAB7FBB & MASK)); + LI (x20, (0xB7D5BFDDB7D5BFDD & MASK)); + LI (x21, (0xDBEADFEEDBEADFEE & MASK)); + LI (x22, (0x6DF56FF76DF56FF7 & MASK)); + LI (x23, (0xB6FAB7FBB6FAB7FB & MASK)); + LI (x24, (0xDB7D5BFDDB7D5BFD & MASK)); + LI (x25, (0xEDBEADFEEDBEADFE & MASK)); + LI (x26, (0x76DF56FF76DF56FF & MASK)); + LI (x27, (0xBB6FAB7FBB6FAB7F & MASK)); + LI (x28, (0xDDB7D5BFDDB7D5BF & MASK)); + LI (x29, (0xEEDBEADFEEDBEADF & MASK)); + LI (x30, (0xF76DF56FF76DF56F & MASK)); + LI (x31, (0xFBB6FAB7FBB6FAB7 & MASK)); + #endif + .globl rvtest_code_begin + rvtest_code_begin: +.endm + +// --------------------------------- CODE BEGIN w/ TRAP HANDLER END -----------------------------// + +.macro RVTEST_CODE_END + .align 4; + .global rvtest_code_end + rvtest_code_end: +#ifdef rvtest_mtrap_routine + .option push + .option norvc + j exit_cleanup + + rvtest_trap_prolog: + /******************************************************************************/ + /**** Prolog, to be run before any tests ****/ + /**** #include 1 copy of this per mode in rvmodel_boot code? ****/ + /**** ------------------------------------------------------------------- ****/ + /**** if xTVEC isn't completely RW, then we need to change the code at its ****/ + /**** target. The entire trap trampoline and mtrap handler replaces the ****/ + /**** area pointed to by mtvec, after saving its original contents first. ****/ + /**** If it isn't possible to fully write that area, restore and fail. ****/ + /******************************************************************************/ + + //trap_handler_prolog; enter with t1..t6 available + + init_mscratch: + la t1, trapreg_sv + csrrw t1, CSR_MSCRATCH, t1 // swap old mscratch. mscratch not points to trapreg_sv + la t2, mscratch_save + SREG t1, 0(t2) // save old mscratch in mscratch_save region + csrr t1, CSR_MSCRATCH // read the trapreg_sv address + LA( t2, mtrap_sigptr ) // locate the start of the trap signature + SREG t2, 0(t1) // save mtrap_sigptr at first location of trapreg_sv + init_mtvec: + la t1, mtrampoline + la t4, mtvec_save + csrrw t2, CSR_MTVEC, t1 // swap mtvec and trap_trampoline + SREG t2, 0(t4) // save orig mtvec + csrr t3, CSR_MTVEC // now read new_mtval back + beq t3, t1, rvtest_prolog_done // if mtvec==trap_trampoline, mtvec is writable, continue + + /****************************************************************/ + /**** fixed mtvec, can't move it so move trampoline instead ****/ + /**** t1=trampoline, t2=oldmtvec, t3=save area, t4=save end ****/ + /****************************************************************/ + + // t2 = dut's original mtvec setting + // t1 = mtrampoline address + init_tramp: /**** copy trampoline at mtvec tgt ****/ + + csrw CSR_MTVEC, t2 // restore orig mtvec, will now attemp to copy trampoline to it + la t3, tramptbl_sv // addr of save area + addi t4, t3, NUM_SPECD_INTCAUSES*4 // end of save area + + overwrite_tt: // now build new trampoline table with offsets base from curr mtvec + lw t6, 0(t2) // get original mtvec target + sw t6, 0(t3) // save it + lw t5, 0(t1) // get trampoline src + sw t5, 0(t2) // overwrite mtvec target + lw t6, 0(t2) // rd it back to make sure it was written + bne t6, t5, resto_tramp // table isn't fully writable, restore and give up + addi t1, t1, 4 // next src index + addi t2, t2, 4 // next tgt index + addi t3, t3, 4 // next save index + bne t3, t4, overwrite_tt // not done, loop + j rvtest_prolog_done + + resto_tramp: // vector table not writeable, restore + LREG t1, 16(t4) // load mscratch_SAVE at fixed offset from table end + csrw CSR_MSCRATCH, t1 // restore mscratch + LREG t4, 8(t4) // load mtvec_SAVE (used as end of loop marker) + + + resto_loop: // goes backwards, t2= dest vec tbl ptr, t3=src save area ptr, t4=vec tbl begin + lw t6, 0(t3) // read saved tgt entry + sw t6, 0(t2) // restore original tgt + addi t2, t2, -4 // prev tgt index + addi t3, t3, -4 // prev save index + bne t2, t4, resto_loop // didn't restore to begining yet, loop + + j rvtest_end // failure to replace trampoline + + + #define mhandler \ + csrrw sp, CSR_MSCRATCH, sp; \ + SREG t6, 6*REGWIDTH(sp); \ + jal t6, common_prolog; + + /**********************************************************************/ + /**** This is the entry point for all m-modetraps, vectored or not.****/ + /**** At entry, mscratch will contain a pointer to a scratch area. ****/ + /**** This is an array of branches at 4B intevals that spreads out ****/ + /**** to an array of 32B mhandler macros for specd int causes, and ****/ + /**** to a return for anything above that (which causes a mismatch)****/ + /**********************************************************************/ + mtrampoline: // 64 or 32 entry table + value = 0 + .rept NUM_SPECD_INTCAUSES // located at each possible int vectors + j mtrap_handler + 12*(value) //offset < +/- 1MB + value = value + 1 + .endr + .rept RLENG-NUM_SPECD_INTCAUSES // fill at each impossible entry + mret + .endr + + mtrap_handler: /* after executing, sp points to temp save area, t4 is PC */ + .rept NUM_SPECD_INTCAUSES + mhandler + .endr + + common_prolog: + la t5, common_mhandler + jr t5 + /*********************************************************************/ + /**** common code for all ints & exceptions, will fork to handle ****/ + /**** each separately. The common handler first stores trap mode+ ****/ + /**** vector, and mcause signatures. All traps have 4wd sigs, but ****/ + /**** sw and timer ints only store 3 of the 4. ****/ + /**** sig offset Exception ExtInt SWInt TimerInt ****/ + /**** 0: tval IntID -1 -1 ****/ + /**** 4: mepc mip mip mip ****/ + /**** 8: <---------------------- mcause -------------> ****/ + /**** 12: <--------------------- Vect+mode ----------> ****/ + /*********************************************************************/ + /* in general, CSRs loaded in t2, addresses into t3 */ + + common_mhandler: /* enter with link in t6 */ + SREG t5, 5*REGWIDTH(sp) + SREG t4, 4*REGWIDTH(sp) + SREG t3, 3*REGWIDTH(sp) + SREG t2, 2*REGWIDTH(sp) + SREG t1, 1*REGWIDTH(sp) /* save other temporaries */ + + LREG t1, 0(sp) /* load trap sig pointer (runs backwards from DATA_END) */ + + LA( t3, mtrampoline) + sub t2, t6, t3 /* reloc “link” to 0..63 to show which int vector was taken */ + addi t2, t2, MMODE_SIG /* insert mode# into 1:0 */ + SREG t2, 0*REGWIDTH(t1) /* save 1st sig value, (vect, trapmode) */ + sv_mcause: + csrr t2, CSR_MCAUSE + SREG t2, 1*REGWIDTH(t1) /* save 2nd sig value, (mcause) */ + + bltz t2, common_mint_handler /* this is a interrupt, not a trap */ + + /********************************************************************/ + /**** This is the exceptions specific code, storing relative mepc****/ + /**** & relative tval signatures. tval is relocated by code or ****/ + /**** data start, or 0 depending on mcause. mepc signature value ****/ + /**** is relocated by code start, and restored adjusted depending****/ + /**** on op alignment so trapped op isn't re-executed. ****/ + /********************************************************************/ + common_mexcpt_handler: + csrr t2, CSR_MEPC + sv_mepc: + LA( t3, rvtest_prolog_done) /* offset to compensate for different loader offsets */ + sub t4, t2, t3 /* convert mepc to rel offset of beginning of test*/ + SREG t4, 2*REGWIDTH(t1) /* save 3rd sig value, (rel mepc) into trap signature area */ + adj_mepc: //adj mepc so there is padding after op, and its 8B aligned + andi t4, t2, 0x2 /* set to 2 if mepc was misaligned */ + sub t2, t2, t4 /* adjust mepc to prev 4B alignment */ + addi t2, t2, 0x8 /* adjust mepc, so it skips past the op, has padding & is 4B aligned */ + csrw CSR_MEPC, t2 /* restore adjusted value, has 1,2, or 3 bytes of padding */ + + + /* calculate relative mtval if it’s an address (by code_begin or data_begin amt) */ + /* note that masks that determine this are implementation specific from YAML */ + + /* masks are bit reversed, so mcause==0 bit is in MSB (so different for RV32 and RV64) */ + + adj_mtval: + csrr t2, CSR_MCAUSE /* code begin adjustment amount already in t3 */ + + LI(t4, CODE_REL_TVAL_MSK) /* trap#s 12, 3,1,0, -- adjust w/ code_begin */ + sll t4, t4, t2 /* put bit# in MSB */ + bltz t4, sv_mtval /* correct adjustment is code_begin in t3 */ + + LA( t3, mtrap_sigptr) /* adjustment assuming access is to signature region */ + LI(t4, DATA_REL_TVAL_MSK) /* trap#s not 14, 11..8, 2 adjust w/ data_begin */ + sll t4, t4, t2 /* put bit# in MSB */ + bgez t4, no_adj /* correct adjustment is data_begin in t3 */ + sigbound_chk: + csrr t4, CSR_MTVAL /* do a bounds check on mtval */ + bge t3, t4, sv_mtval /* if mtval is greater than the rvmodel_data_begin then use that as anchor */ + LA( t3, rvtest_data_begin) /* else change anchor to rvtest_data_begin */ + blt t3, t4, sv_mtval /* before the signature, use data_begin adj */ + mv t4, t3 /* use sig relative adjust */ + no_adj: + LI(t3, 0) /* else zero adjustment amt */ + + // For Illegal op handling + addi t2, t2, -2 /* check if mcause==2 (illegal op) */ + bnez t2, sv_mtval /* not illegal op, no special treatment */ + csrr t2, CSR_MTVAL + bnez t2, sv_mtval /* mtval isn’t zero, no special treatment */ + illop: + LI(t5, 0x20000) /* get mprv mask */ + csrrs t5, CSR_MSTATUS, t5 /* set mprv while saving the old value */ + csrr t3, CSR_MEPC + lhu t2, 0(t3) /* load 1st 16b of opc w/ old priv, endianess*/ + andi t4, t2, 0x3 + addi t4, t4, -0x3 /* does opcode[1:0]==0b11? (Meaning >16b op) */ + bnez t4, sv_mtval /* entire mtval is in tt2, adj amt will be set to zero */ + lhu t4, 2(t3) + sll t4, t4, 16 + or t3, t2, t4 /* get 2nd hwd, align it & insert it into opcode */ + csrw CSR_MSTATUS, t5 /* restore mstatus */ + +/*******FIXME: this will not handle 48 or 64b opcodes in an RV64) ********/ + + sv_mtval: + csrr t2, CSR_MTVAL + sub t2, t2, t3 /* perform mtval adjust by either code or data position or zero*/ + SREG t2, 3*REGWIDTH(t1) /* save 4th sig value, (rel mtval) into trap signature area */ + + resto_rtn: /* restore and return */ + addi t1, t1,4*REGWIDTH /* adjust trap signature ptr (traps always save 4 words) */ + SREG t1, 0*REGWIDTH(sp) /* save updated trap sig pointer (pts to trap_sigptr */ + + LREG t1, 1*REGWIDTH(sp) + LREG t2, 2*REGWIDTH(sp) + LREG t3, 3*REGWIDTH(sp) + LREG t4, 4*REGWIDTH(sp) + LREG t5, 5*REGWIDTH(sp) + LREG t6, 6*REGWIDTH(sp) /* restore temporaries */ + + csrrw sp, CSR_MSCRATCH, sp /* restore sp from scratch */ + mret + + common_mint_handler: /* t1 has sig ptr, t2 has mcause */ + + LI(t3, 1) + sll t3, t3, t2 /* create mask 1<> 1); \ + csrs mstatus, a0; \ + csrwi fcsr, 0 + +#ifdef pext_check_vxsat_ov +#define RVTEST_VXSAT_ENABLE()\ + li a0, MSTATUS_VS & (MSTATUS_VS >> 1); \ + csrs mstatus, a0; \ + clrov +#else +#define RVTEST_VXSAT_ENABLE() +#endif + +#define RVTEST_SIGBASE(_R,_TAG) \ + LA(_R,_TAG);\ + .set offset,0; + +.set offset,0; +#define _ARG5(_1ST,_2ND, _3RD,_4TH,_5TH,...) _5TH +#define _ARG4(_1ST,_2ND, _3RD,_4TH,...) _4TH +#define _ARG3(_1ST,_2ND, _3RD, ...) _3RD +#define _ARG2(_1ST,_2ND, ...) _2ND +#define _ARG1(_1ST,...) _1ST +#define NARG(...) _ARG5(__VA_OPT__(__VA_ARGS__,)4,3,2,1,0) + + /* automatically adjust base and offset if offset gets too big */ + /* RVTEST_SIGUPD(basereg, sigreg) stores sigreg at offset(basereg) and updates offset by regwidth */ + /* RVTEST_SIGUPD(basereg, sigreg,newoff) stores sigreg at newoff(basereg) and updates offset to regwidth+newoff */ +#define RVTEST_SIGUPD(_BR,_R,...) \ + .if offset+REGWIDTH>=2048 ;\ + addi _BR, _BR, offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + .set offset,offset+REGWIDTH + +#define RVTEST_SIGUPD_F(_BR,_R,_F,...) \ + .if offset+2*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + FSREG _R,offset(_BR) ;\ + SREG _F,offset+REGWIDTH(_BR) ;\ + .set offset,offset+(2*REGWIDTH) + + +#define RVTEST_SIGUPD_FID(_BR,_R,_F,...) \ + .if offset+2*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + SREG _F,offset+REGWIDTH(_BR) ;\ + .set offset,offset+(2*REGWIDTH) + +// for updating signatures when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. +#define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...) \ + .if NARG(__VA_ARGS__) == 0 ;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI) ;\ + .else ;\ + RVTEST_SIGUPD_FID(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0)));\ + .endif + +// for reading vxsat.OV flag in P-ext; and only reads the flag when Zicsr extension is present +#ifdef pext_check_vxsat_ov +#define RDOV(_F)\ + rdov _F +#else +#define RDOV(_F)\ + nop +#endif + +// for updating signatures that include flagreg when 'rd' is a paired register (64-bit) in Zpsfoperand extension in RV32. +#define RVTEST_SIGUPD_PK64(_BR,_R,_R_HI,_F,...)\ + .if offset+3*REGWIDTH>=2048 ;\ + addi _BR, _BR,offset ;\ + .set offset, 0 ;\ + .endif ;\ + .if NARG(__VA_ARGS__) == 1 ;\ + .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ + .endif ;\ + SREG _R,offset(_BR) ;\ + SREG _R_HI,offset+REGWIDTH(_BR) ;\ + RDOV(_F) ;\ + SREG _F,offset+2*REGWIDTH(_BR) ;\ + .set offset,offset+(3*REGWIDTH) + +// for updating signatures that include flagreg for P-ext saturation instructions (RV32/RV64). +#define RVTEST_SIGUPD_PK(_BR,_R,_F,OFFSET)\ + RVTEST_SIGUPD_FID(_BR,_R,_F,OFFSET) + +#define RVTEST_VALBASEUPD(_BR,...)\ + .if NARG(__VA_ARGS__) == 0;\ + addi _BR,_BR,2040;\ + .endif;\ + .if NARG(__VA_ARGS__) == 1;\ + LA(_BR,_ARG1(__VA_ARGS__,x0));\ + .endif; + +#define RVTEST_VALBASEMOV(_NR,_BR)\ + add _NR, _BR, x0; +/* + * RVTEST_BASEUPD(base reg) - updates the base register the last signature address + REGWIDTH + * RVTEST_BASEUPD(base reg, new reg) - moves value of the next signature region to update into new reg + * The hidden variable offset is reset always +*/ + +#define RVTEST_BASEUPD(_BR,...)\ + .if NARG(__VA_ARGS__) == 0;\ + addi _BR,_BR,offset;\ + .endif;\ + .if NARG(__VA_ARGS__) == 1;\ + addi _ARG1(__VA_ARGS__,x0),_BR,offset;\ + .endif;\ + .set offset,0; + + + +//------------------------------ BORROWED FROM ANDREW's RISC-V TEST MACROS -----------------------// +#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1)) + +#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11)) + +#define TEST_JALR_OP(tempreg, rd, rs1, imm, swreg, offset,adj) \ +5: ;\ + LA(rd,5b ) ;\ + .if adj & 1 == 1 ;\ + LA(rs1, 3f-imm+adj-1 ) ;\ + jalr rd, imm+1(rs1) ;\ + .else ;\ + LA(rs1, 3f-imm+adj) ;\ + jalr rd, imm(rs1) ;\ + .endif ;\ + nop ;\ + nop ;\ + xori rd,rd, 0x2 ;\ + j 4f ;\ + ;\ +3: .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + xori rd,rd, 0x3 ;\ + j 4f ;\ + .if adj&2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + ;\ +4: LA(tempreg, 5b ) ;\ + andi tempreg,tempreg,~(3) ;\ + sub rd,rd,tempreg ;\ + RVTEST_SIGUPD(swreg,rd,offset) +//SREG rd, offset(swreg); + +#define TEST_JAL_OP(tempreg, rd, imm, label, swreg, offset, adj)\ +5: ;\ + LA(tempreg, 2f ) ;\ + jalr x0,0(tempreg) ;\ +6: LA(tempreg, 4f ) ;\ + jalr x0,0(tempreg) ;\ +1: .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + xori rd,rd, 0x1 ;\ + beq x0,x0,6b ;\ + .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + .if (imm/2) - 2 >= 0 ;\ + .set num,(imm/2)-2 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 3f ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + nop ;\ + .endr ;\ + ;\ +2: jal rd, label+(adj) ;\ + .if adj & 2 == 2 ;\ + nop ;\ + nop ;\ + .endif ;\ + xori rd,rd, 0x2 ;\ + j 4f ;\ + .if (imm/2) - 3 >= 0 ;\ + .set num,(imm/2)-3 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 1b ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + nop ;\ + .endr ;\ +3: .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + xori rd,rd, 0x3 ;\ + LA(tempreg, 4f ) ;\ + jalr x0,0(tempreg) ;\ + .if adj&2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ +4: LA(tempreg, 5b ) ;\ + andi tempreg,tempreg,~(3) ;\ + sub rd,rd,tempreg ;\ + RVTEST_SIGUPD(swreg,rd,offset) +//SREG rd, offset(swreg); + +#define TEST_BRANCH_OP(inst, tempreg, reg1, reg2, val1, val2, imm, label, swreg, offset,adj) \ + LI(reg1, MASK_XLEN(val1)) ;\ + LI(reg2, MASK_XLEN(val2)) ;\ + addi tempreg,x0,0 ;\ + j 2f ;\ + ;\ +1: .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + addi tempreg,tempreg, 0x1 ;\ + j 4f ;\ + .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + .if (imm/2) - 2 >= 0 ;\ + .set num,(imm/2)-2 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 3f ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + nop ;\ + .endr ;\ + ;\ +2: inst reg1, reg2, label+adj ;\ + addi tempreg, tempreg,0x2 ;\ + j 4f ;\ + .if (imm/4) - 3 >= 0 ;\ + .set num,(imm/4)-3 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 1b ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + nop ;\ + .endr ;\ + ;\ +3: .if adj & 2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + addi tempreg, tempreg,0x3 ;\ + j 4f ;\ + .if adj&2 == 2 ;\ + .fill 2,1,0x00 ;\ + .endif ;\ + ;\ +4: RVTEST_SIGUPD(swreg,tempreg,offset) +//SREG tempreg, offset(swreg); + +#define TEST_STORE(swreg,testreg,index,rs1,rs2,rs2_val,imm_val,offset,inst,adj) ;\ +LI(rs2,rs2_val) ;\ +addi rs1,swreg,offset+adj ;\ +LI(testreg,imm_val) ;\ +sub rs1,rs1,testreg ;\ +inst rs2, imm_val(rs1) ;\ +nop ;\ +nop + +#define TEST_LOAD(swreg,testreg,index,rs1,destreg,imm_val,offset,inst,adj) ;\ +LA(rs1,rvtest_data+(index*4)+adj-imm_val) ;\ +inst destreg, imm_val(rs1) ;\ +nop ;\ +nop ;\ +RVTEST_SIGUPD(swreg,destreg,offset) +//SREG destreg, offset(swreg); + +#define TEST_STORE_F(swreg,testreg,index,rs1,rs2,rs2_val,imm_val,offset,inst,adj,flagreg) ;\ +LI(flagreg,rs2_val) ;\ +fmv.w.x rs2, flagreg ;\ +addi rs1,swreg,offset+adj ;\ +LI(testreg,imm_val) ;\ +sub rs1,rs1,testreg ;\ +inst rs2, imm_val(rs1) ;\ +nop ;\ +nop ;\ +csrrs flagreg, fflags, x0 ;\ +RVTEST_SIGUPD(swreg,flagreg,offset) + +#define TEST_LOAD_F(swreg,testreg,index,rs1,destreg,imm_val,offset,inst,adj,flagreg) ;\ +LA(rs1,rvtest_data+(index*4)+adj-imm_val) ;\ +inst destreg, imm_val(rs1) ;\ +nop ;\ +nop ;\ +csrrs flagreg, fflags, x0 ;\ +RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset) + +#define TEST_CSR_FIELD(ADDRESS,TEMP_REG,MASK_REG,NEG_MASK_REG,VAL,DEST_REG,OFFSET,BASE_REG) \ + LI(TEMP_REG,VAL);\ + and TEMP_REG,TEMP_REG,MASK_REG;\ + csrr DEST_REG,ADDRESS;\ + and DEST_REG,DEST_REG,NEG_MASK_REG;\ + or TEMP_REG,TEMP_REG,DEST_REG;\ + csrw ADDRESS,TEMP_REG;\ + csrr DEST_REG,ADDRESS;\ + RVTEST_SIGUPD(BASE_REG,DEST_REG,OFFSET) + + +#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... ) \ + code; \ + RVTEST_SIGUPD(swreg,destreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) + +#define TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, code... ) \ + code; \ + RVTEST_SIGUPD_F(swreg,destreg,flagreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) + +#define TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, code... ) \ + code; \ + RVTEST_SIGUPD_FID(swreg,destreg,flagreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) + +#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LA testreg, 1f; \ + 1: \ + inst destreg, imm; \ + sub destreg, destreg, testreg; \ + ) + +//Tests for instructions with register-immediate operand +#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val)); \ + inst destreg, reg, SEXT_IMM(imm); \ + ) + +//Tests for floating-point instructions with a single register operand +#define TEST_FPSR_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ + FLREG freg, val_offset(valaddr_reg); \ + csrrwi x0, frm, rm; \ + inst destreg, freg; \ + csrrs flagreg, fflags, x0; \ + ) + +//Tests for floating-point instructions with a single register operand and integer destination register +#define TEST_FPID_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ + FLREG freg, val_offset(valaddr_reg); \ + csrrwi x0, frm, rm; \ + inst destreg, freg; \ + csrrs flagreg, fflags, x0; \ + ) + +//Tests for floating-point instructions with a single register operand and integer operand register +#define TEST_FPIO_OP( inst, destreg, freg, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ + LREG freg, val_offset(valaddr_reg); \ + csrrwi x0, frm, rm; \ + inst destreg, freg; \ + csrrs flagreg, fflags, x0; \ + ) + +//Tests for instructions with register-register-immediate operands +#define TEST_RRI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2, imm; \ + ) + +//Tests for a instructions with register-register operand +#define TEST_RI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2, imm; \ + ) + +//Tests for a instructions with register-register operand +#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + ) +//Tests for floating-point instructions with register-register operand +#define TEST_FPRR_OP(inst, destreg, freg1, freg2, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ + FLREG freg1, val_offset(valaddr_reg); \ + FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ + csrrwi x0, frm, rm; \ + inst destreg, freg1, freg2; \ + csrrs flagreg, fflags, x0; \ + ) + +//Tests for floating-point CMP instructions with register-register operand +#define TEST_FCMP_OP(inst, destreg, freg1, freg2, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ + FLREG freg1, val_offset(valaddr_reg); \ + FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ + inst destreg, freg1, freg2; \ + csrrs flagreg, fflags, x0; \ + ) + +//Tests for floating-point R4 type instructions +#define TEST_FPR4_OP(inst, destreg, freg1, freg2, freg3, rm, correctval, valaddr_reg, val_offset, flagreg, swreg, offset, testreg) \ + TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, offset, \ + FLREG freg1, val_offset(valaddr_reg); \ + FLREG freg2, val_offset+FREGWIDTH(valaddr_reg); \ + FLREG freg3, val_offset+2*FREGWIDTH(valaddr_reg); \ + csrrwi x0, frm, rm; \ + inst destreg, freg1, freg2, freg3; \ + csrrs flagreg, fflags, x0; \ + ) + +#define TEST_CNOP_OP( inst, testreg, imm_val, swreg, offset) \ + TEST_CASE(testreg, x0, 0, swreg, offset, \ + inst imm_val; \ + ) + +//Tests for instructions with register-immediate operand and update the saturation flag +#define TEST_PKIMM_OP( inst, destreg, reg, correctval, val, imm, flagreg, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val)); \ + inst destreg, reg, SEXT_IMM(imm); \ + rdov flagreg; \ + ) + +//Tests for instructions with register-register operand and update the saturation flag +#define TEST_PKRR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, flagreg, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK(swreg, destreg, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) + +//Tests for instructions with a single register operand and update the saturation flag +#define TEST_PKR_OP( inst, destreg, reg, correctval, val, flagreg, swreg, offset, testreg) \ + TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, offset, \ + LI(reg, MASK_XLEN(val)); \ + inst destreg, reg; \ + rdov flagreg; \ + ) + +#if __riscv_xlen == 32 +//Tests for a instruction with register pair operands for all its three operands +#define TEST_P64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + LI(reg2_hi, MASK_XLEN(val2_hi)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg,destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_PK64_PPP_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, reg2_hi, correctval, correctval_hi, val1, val1_hi, val2, val2_hi, flagreg, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + LI(reg2_hi, MASK_XLEN(val2_hi)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK64(swreg,destreg, destreg_hi, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_PPN_OP_32(inst, destreg, destreg_hi, reg1, reg1_hi, reg2, correctval, correctval_hi, val1, val1_hi, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_P64(swreg, destreg, destreg_hi, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_PK64_PNN_OP_32(inst, destreg, destreg_hi, reg1, reg2, correctval, correctval_hi, val1, val2, flagreg, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD_PK64(swreg, destreg, destreg_hi, flagreg, offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg_hi, correctval_hi) + +#define TEST_P64_NPN_OP_32(inst, destreg, reg1, reg1_hi, reg2, correctval, val1, val1_hi, val2, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + LI(reg2, MASK_XLEN(val2)); \ + inst destreg, reg1, reg2; \ + RVTEST_SIGUPD(swreg,destreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); + +#define TEST_P64_NP_OP_32(inst, destreg, reg1, reg1_hi, correctval, val1, val1_hi, imm_val, swreg, offset, testreg) \ + LI(reg1, MASK_XLEN(val1)); \ + LI(reg1_hi, MASK_XLEN(val1_hi)); \ + inst destreg, reg1, imm_val; \ + RVTEST_SIGUPD(swreg,destreg,offset); \ + RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval); + +//Tests for a instruction with pair register rd, pair register rs1 and pair register rs2 +#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ + TEST_P64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) +#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ + TEST_PK64_PPP_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) +//Tests for a instruction with pair register rd, pair register rs1 and normal register rs2 +#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_P64_PPN_OP_32(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) +//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 +#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ + TEST_P64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) +//Tests for a instruction with pair register rd, normal register rs1 and normal register rs2 +#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ + TEST_PK64_PNN_OP_32(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +//Tests for a instruction with normal register rd, pair register rs1 and normal register rs2 +#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_P64_NPN_OP_32(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) +//Tests for a instruction with normal register rd, pair register rs1 +#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ + TEST_P64_NP_OP_32(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) + +#else + +// When in rv64, there are no instructions with pair operand, so Macro is redefined to normal TEST_RR_OP +#define TEST_P64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_PK64_PPP_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, rs2_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, rs2_val_hi, flagreg, swreg, offset, testreg) \ + TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +#define TEST_P64_PPN_OP(inst, rd, rd_hi, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_P64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_PK64_PNN_OP(inst, rd, rd_hi, rs1, rs2, correctval, correctval_hi, rs1_val, rs2_val, flagreg, swreg, offset, testreg) \ + TEST_PKRR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, flagreg, swreg, offset, testreg) +#define TEST_P64_NPN_OP(inst, rd, rs1, rs1_hi, rs2, correctval, correctval_hi, rs1_val, rs1_val_hi, rs2_val, swreg, offset, testreg) \ + TEST_RR_OP(inst, rd, rs1, rs2, correctval, rs1_val, rs2_val, swreg, offset, testreg) +#define TEST_P64_NP_OP(inst, rd, rs1, rs1_hi, correctval, correctval_hi, rs1_val, rs1_val_hi, imm_val, swreg, offset, testreg) \ + TEST_IMM_OP(inst, rd, rs1, correctval, rs1_val, imm_val, swreg, offset, testreg) + +#endif + + + + +#define TEST_CMV_OP( inst, destreg, reg, correctval, val2, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val2)); \ + inst destreg, reg; \ + ) + +#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(reg, MASK_XLEN(val2)); \ + LI(destreg, MASK_XLEN(val1)); \ + inst destreg, reg; \ + ) + +#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(destreg, MASK_XLEN(val)); \ + inst destreg, imm; \ + ) + +#define TEST_CADDI4SPN_OP( inst, destreg, correctval, imm, swreg, offset, testreg) \ + TEST_CASE(testreg, destreg, correctval, swreg, offset, \ + LI(x2, 0); \ + inst destreg, x2,imm; \ + ) + +//Tests for instructions with a single register operand +#define TEST_RD_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) \ + TEST_CMV_OP(inst, destreg, reg1, correctval, val1, swreg, offset, testreg) + +#define TEST_CBRANCH_OP(inst, tempreg, reg2, val2, imm, label, swreg, offset) \ + LI(reg2, MASK_XLEN(val2)) ;\ + j 2f ;\ + addi tempreg, x0,0 ;\ + .option push ;\ + .option norvc ;\ +1: addi tempreg, tempreg,0x1 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 4 >= 0 ;\ + .set num,(imm/2)-4 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 3f ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ +2: inst reg2, label ;\ + .option push ;\ + .option norvc ;\ + addi tempreg, tempreg, 0x2 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 5 >= 0 ;\ + .set num,(imm/2)-5 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 1b ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ + ;\ +3: addi tempreg, tempreg ,0x3 ;\ + ;\ +4: RVTEST_SIGUPD(swreg,tempreg,offset) +//SREG tempreg, offset(swreg); + + +#define TEST_CJ_OP(inst, tempreg, imm, label, swreg, offset) \ + .option push ;\ + .option norvc ;\ + j 2f ;\ + addi tempreg,x0,0 ;\ +1: addi tempreg, tempreg,0x1 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 4 >= 0 ;\ + .set num,(imm/2)-4 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 3f ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ +2: inst label ;\ + .option push ;\ + .option norvc ;\ + addi tempreg, tempreg, 0x2 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 5 >= 0 ;\ + .set num,(imm/2)-5 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 1b ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ + ;\ +3: addi tempreg, tempreg, 0x3 ;\ + ;\ +4: RVTEST_SIGUPD(swreg,tempreg,offset) +//SREG tempreg, offset(swreg); + +#define TEST_CJAL_OP(inst, tempreg, imm, label, swreg, offset) \ +5: ;\ + j 2f ;\ + ;\ + .option push ;\ + .option norvc ;\ +1: xori x1,x1, 0x1 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 4 >= 0 ;\ + .set num,(imm/2)-4 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 3f ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ +2: inst label ;\ + .option push ;\ + .option norvc ;\ + xori x1,x1, 0x2 ;\ + j 4f ;\ + .option pop ;\ + .if (imm/2) - 5 >= 0 ;\ + .set num,(imm/2)-5 ;\ + .else ;\ + .set num,0 ;\ + .endif ;\ + .if label == 1b ;\ + .set num,0 ;\ + .endif ;\ + .rept num ;\ + c.nop ;\ + .endr ;\ + ;\ +3: xori x1,x1, 0x3 ;\ + ;\ +4: LA(tempreg, 5b) ;\ + andi tempreg,tempreg,~(3) ;\ + sub x1,x1,tempreg ;\ + RVTEST_SIGUPD(swreg,x1,offset) +//SREG x1, offset(swreg); + +#define TEST_CJR_OP(tempreg, rs1, swreg, offset) \ +5: ;\ + LA(rs1, 3f) ;\ + ;\ +2: c.jr rs1 ;\ + xori rs1,rs1, 0x2 ;\ + j 4f ;\ + ;\ +3: xori rs1,rs1, 0x3 ;\ + ;\ +4: LA(tempreg, 5b) ;\ + andi tempreg,tempreg,~(3) ;\ + sub rs1,rs1,tempreg ;\ + RVTEST_SIGUPD(swreg,rs1,offset) +//SREG rs1, offset(swreg); + +#define TEST_CJALR_OP(tempreg, rs1, swreg, offset) \ +5: ;\ + LA(rs1, 3f ) ;\ + ;\ +2: c.jalr rs1 ;\ + xori x1,x1, 0x2 ;\ + j 4f ;\ + ;\ +3: xori x1,x1, 0x3 ;\ + ;\ +4: LA(tempreg, 5b ) ;\ + andi tempreg,tempreg,~(3) ;\ + sub x1,x1,tempreg ;\ + RVTEST_SIGUPD(swreg,x1,offset) +//SREG x1, offset(swreg); + + +//--------------------------------- Migration aliases ------------------------------------------ +#ifdef RV_COMPLIANCE_RV32M + #warning "RV_COMPLIANCE_RV32M macro will be deprecated." + #define RVMODEL_BOOT \ + RVTEST_IO_INIT; \ + RV_COMPLIANCE_RV32M ; \ + RV_COMPLIANCE_CODE_BEGIN +#endif + +#define SWSIG(a, b) + +#ifdef RV_COMPLIANCE_DATA_BEGIN + #warning "RV_COMPLIANCE_DATA_BEGIN macro deprecated in v0.2. Please use RVMODEL_DATA_BEGIN instead" + #define RVMODEL_DATA_BEGIN \ + RV_COMPLIANCE_DATA_BEGIN +#endif + +#ifdef RV_COMPLIANCE_DATA_END + #warning "RV_COMPLIANCE_DATA_END macro deprecated in v0.2. Please use RVMODEL_DATA_END instead" + #define RVMODEL_DATA_END \ + RV_COMPLIANCE_DATA_END +#endif + +#ifdef RV_COMPLIANCE_HALT + #warning "RV_COMPLIANCE_HALT macro deprecated in v0.2. Please use RVMODEL_HALT instead" + #define RVMODEL_HALT \ + RV_COMPLIANCE_HALT +#endif + +#ifdef RVTEST_IO_ASSERT_GPR_EQ + #warning "RVTEST_IO_ASSERT_GPR_EQ macro deprecated in v0.2. Please use RVMODEL_IO_ASSERT_GPR_EQ instead" + #define RVMODEL_IO_ASSERT_GPR_EQ(_SP, _R, _I) \ + RVTEST_IO_ASSERT_GPR_EQ(_SP,_R, _I) +#endif + +#ifdef RVTEST_IO_WRITE_STR + #warning "RVTEST_IO_WRITE_STR macro deprecated in v0.2. Please use RVMODEL_IO_WRITE_STR instead" + #define RVMODEL_IO_WRITE_STR(_SP, _STR) \ + RVTEST_IO_WRITE_STR(_SP, _STR) +#endif + +#ifdef RVTEST_IO_INIT + #warning "RVTEST_IO_INIT is deprecated in v0.2. Please use RVMODEL_BOOT for initialization" +#endif + +#ifdef RVTEST_IO_CHECK + #warning "RVTEST_IO_CHECK is deprecated in v0.2. +#endif From bbaa7b66bacc62b6d8b3a29c148cc90fb5ca5e6f Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 9 Mar 2022 08:43:38 +0530 Subject: [PATCH 14/14] Update README.md Remove `misalign1` test from the list of failed tests in disclaimer. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ba81bbb1..fdc2fc4e2 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ when reporting the status of pass/fail on the execution of the architectural sui have compressed extension support enabled by default. Targets without the compressed extension support will fail the following tests: 1. rv[32/64]i_m/privilege/src/misalign-b[ge[u],lt[u],eq,ne]-01.S - 2. rv[32/64]i_m/privilege/src/misalign[1,2]-jalr-01.S + 2. rv[32/64]i_m/privilege/src/misalign2-jalr-01.S 3. The machine mode trap handler used in the privilege tests assumes one of the following conditions. Targets not satisfying any of the following conditions are bound to fail the entire