/* These are macros to manage storing signatures, selecting what to save */ /* keeping track of the hidden offset, and ensuring it doesn't overflow */ /* They're useful across many tests, but generally for specific classes of ops */ /* This function set up the Page table entry for Sv32 Translation scheme Arguments: _PAR: Register containing Physical Address _PR: Register containing Permissions for Leaf PTE. (Note: No-leaf PTE (if-any) has only valid permssion (pte.v) set) _TR0, _TR1, _TR2: Temporary registers used and modified by function VA: Virtual address level: Level at which PTE would be setup 0: Two level translation 1: Superpage */ #define LEVEL0 0x00 #define LEVEL1 0x01 #define LEVEL2 0x02 #define LEVEL3 0x03 #define LEVEL4 0x04 #define sv39 0x00 #define sv48 0x01 #define sv57 0x02 #define CODE code_bgn_off #define DATA data_bgn_off #define SIG sig_bgn_off #define VMEM vmem_bgn_off #define ALL_MEM_PMP ;\ li t2, -1 ;\ csrw pmpaddr0, t2 ;\ li t2, 0x0F ;\ csrw pmpcfg0, t2 ;\ sfence.vma ; #define SIGNATURE_AREA(TYPE,ARG1,ARG2, ...) ;\ LI (t0, ARG1) ;\ .if(TYPE == CODE) ;\ LI (t1, ARG2) ;\ sub t0, t0, t1 ;\ csrr sp, mscratch ;\ add t1,sp,t0 ;\ csrw sscratch, t1 ;\ .else ;\ LA (t1, ARG2) ;\ sub t0, t0, t1 ;\ .endif ;\ LREG t1, TYPE+0*sv_area_sz(sp) ;\ add t2, t1, t0 ;\ SREG t2, TYPE+1*sv_area_sz(sp) ; //****NOTE: label `rvtest_Sroot_pg_tbl` must be declared after RVTEST_DATA_END // in the test aligned at 4kiB (use .align 12) #define PTE_SETUP_RV32(_PAR, _PR, _TR0, _TR1, VA, level) ;\ srli _PAR, _PAR, 12 ;\ slli _PAR, _PAR, 10 ;\ or _PAR, _PAR, _PR ;\ .if (level==1) ;\ LA(_TR1, rvtest_Sroot_pg_tbl) ;\ .set vpn, ((VA>>22)&0x3FF)<<2 ;\ .endif ;\ .if (level==0) ;\ LA(_TR1, rvtest_slvl1_pg_tbl) ;\ .set vpn, ((VA>>12)&0x3FF)<<2 ;\ .endif ;\ LI(_TR0, vpn) ;\ add _TR1, _TR1, _TR0 ;\ SREG _PAR, 0(_TR1); #define PTE_SETUP_RV64(_PAR, _PR, _TR0, _TR1, VA, level, mode) ;\ srli _PAR, _PAR, 12 ;\ slli _PAR, _PAR, 10 ;\ or _PAR, _PAR, _PR ;\ .if (mode == sv39) ;\ .if (level == 2) ;\ LA(_TR1, rvtest_Sroot_pg_tbl) ;\ .set vpn, ((VA >> 30) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 1) ;\ LA(_TR1, rvtest_slvl1_pg_tbl) ;\ .set vpn, ((VA >> 21) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 0) ;\ LA(_TR1, rvtest_slvl2_pg_tbl) ;\ .set vpn, ((VA >> 12) & 0x1FF) << 3 ;\ .endif ;\ .endif ;\ .if (mode == sv48) ;\ .if (level == 3) ;\ LA(_TR1, rvtest_Sroot_pg_tbl) ;\ .set vpn, ((VA >> 39) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 2) ;\ LA(_TR1, rvtest_slvl1_pg_tbl) ;\ .set vpn, ((VA >> 30) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 1) ;\ LA(_TR1, rvtest_slvl2_pg_tbl) ;\ .set vpn, ((VA >> 21) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 0) ;\ LA(_TR1, rvtest_slvl3_pg_tbl) ;\ .set vpn, ((VA >> 12) & 0x1FF) << 3 ;\ .endif ;\ .endif ;\ .if (mode == sv57) ;\ .if (level == 4) ;\ LA(_TR1, rvtest_Sroot_pg_tbl) ;\ .set vpn, ((VA >> 48) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 3) ;\ LA(_TR1, rvtest_slvl1_pg_tbl) ;\ .set vpn, ((VA >> 39) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 2) ;\ LA(_TR1, rvtest_slvl2_pg_tbl) ;\ .set vpn, ((VA >> 30) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 1) ;\ LA(_TR1, rvtest_slvl3_pg_tbl) ;\ .set vpn, ((VA >> 21) & 0x1FF) << 3 ;\ .endif ;\ .if (level == 0) ;\ LA(_TR1, rvtest_slvl3_pg_tbl) ;\ .set vpn, ((VA >> 12) & 0x1FF) << 3 ;\ .endif ;\ .endif ;\ LI(_TR0, vpn) ;\ add _TR1, _TR1, _TR0 ;\ SREG _PAR, 0(_TR1) ; #define PTE_PERMUPD_RV32(_PR, _TR0, _TR1, VA, level) ;\ .if (level==1) ;\ LA(_TR1, rvtest_Sroot_pg_tbl) ;\ .set vpn, ((VA>>22)&0x3FF)<<2 ;\ .endif ;\ .if (level==0) ;\ LA(_TR1, rvtest_slvl1_pg_tbl) ;\ .set vpn, ((VA>>12)&0x3FF)<<2 ;\ .endif ;\ LI(_TR0, vpn) ;\ add _TR1, _TR1, _TR0 ;\ LREG _TR0, 0(_TR1) ;\ srli _TR0, _TR0, 10 ;\ slli _TR0, _TR0, 10 ;\ or _TR0, _TR0, _PR ;\ SREG _TR0, 0(_TR1) ; #define SATP_SETUP_SV32 ;\ LA(t6, rvtest_Sroot_pg_tbl) ;\ LI(t5, SATP32_MODE) ;\ srli t6, t6, 12 ;\ or t6, t6, t5 ;\ csrw satp, t6 ; #define SATP_SETUP_RV64(MODE) ;\ LA(t6, rvtest_Sroot_pg_tbl) ;\ .if (MODE == sv39) ;\ LI(t5, (SATP64_MODE) & (SATP_MODE_SV39 << 60)) ;\ .endif ;\ .if (MODE == sv48) ;\ LI(t5, (SATP64_MODE) & (SATP_MODE_SV48 << 60)) ;\ .endif ;\ .if (MODE == sv57) ;\ LI(t5, (SATP64_MODE) & (SATP_MODE_SV57 << 60)) ;\ .endif ;\ .if (MODE == sv64) ;\ LI(t5, (SATP64_MODE) & (SATP_MODE_SV64 << 60)) ;\ .endif ;\ srli t6, t6, 12 ;\ or t6, t6, t5 ;\ csrw satp, t6 ; //Tests for atomic memory operation(AMO) instructions #define TEST_AMO_OP(inst, destreg, origptr, reg2, origval, updval, sigptr, ...) ;\ .if NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ LI(reg2, MASK_XLEN(origval)) ;\ RVTEST_SIGUPD(sigptr, reg2) /*Write original AMO src */ ;\ LI(reg2, MASK_XLEN(updval)) ;\ addi origptr, sigptr, offset-REGWIDTH /* Calculate where orig AMO src is stored */ ;\ inst destreg, reg2, (origptr) /*origval -> destreg; updated val -> (origptr) */ ;\ RVTEST_SIGUPD(sigptr, destreg) /* write original AMO val */ #define NAN_BOXED(__val__,__width__,__max__) ;\ .if __width__ == 32 ;\ .word __val__ ;\ .else ;\ .dword __val__ ;\ .endif ;\ .if __max__ > __width__ ;\ .set pref_bytes,(__max__-__width__)/32 ;\ .else ;\ .set pref_bytes, 0 ;\ .endif ;\ .rept pref_bytes ;\ .word 0xffffffff ;\ .endr ; #define ZERO_EXTEND(__val__,__width__,__max__) ;\ .if __max__ > __width__ ;\ .set pref_bytes,(__max__-__width__)/32 ;\ .else ;\ .set pref_bytes, 0 ;\ .endif ;\ .rept pref_bytes ;\ .word 0 ;\ .endr ;\ .if __width__ == 32 ;\ .word __val__ ;\ .else ;\ .dword __val__ ;\ .endif; #define RVTEST_FP_ENABLE() ;\ LI(a0, (MSTATUS_FS & (MSTATUS_FS >> 1))) ;\ csrs mstatus, a0 ;\ csrwi fcsr, 0 // This macro is for vector #define RVTEST_VXSAT_ENABLE() ;\ LI(a0, (MSTATUS_VS & (MSTATUS_VS >> 1))) ;\ csrs mstatus, a0 ;\ clrov /* RVTEST_SIGBASE(reg, label) initializes to label and clears offset */ #define RVTEST_SIGBASE(_R,_TAG) ;\ LA(_R,_TAG) ;\ .set offset,0 // This macro is loading data from memory with any offset value // This macro is loading data from memory with any offset value #define LOAD_MEM_VAL(_LINST, _AREG, _RD, _OFF, _TREG) ;\ .if (((_OFF & ~0x07FF)== 0) |((_OFF | 0x07FF)== -1)) ;\ _LINST _RD, _OFF(_AREG) /* yes, it fits */ ;\ .else /* no, needs base adj */ ;\ .set _off, SEXT_IMM(_OFF) /* strip off hi bits */ ;\ .set cry, BIT(_off,11)<<12 ;\ LI( _TREG, (_OFF & ~0x0FFF)+cry) /* strip off hi bits*/ ;\ add _AREG, _AREG, _TREG /* modified temp base*/ ;\ _LINST _RD, _off(_AREG) ;\ sub _AREG, _AREG, _TREG /* undo modification */ ;\ .endif /* this function ensures individual sig stores don't exceed offset limits */ /* if they would, update the base and reduce offset by 2048 - _SZ */ /* an option is to pre-incr offset if there was a previous signature store */ #define CHK_OFFSET(_BREG, _SZ, _PRE_INC) ;\ .if (_PRE_INC!=0) ;\ .set offset, offset+_SZ ;\ .endif ;\ .if offset >= 2048 ;\ addi _BREG, _BREG, (2048 - _SZ) ;\ .set offset, offset - (2048 - _SZ) ;\ .endif /* automatically adjust base and offset if offset gets too big, resetting offset */ /* 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 NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ CHK_OFFSET(_BR, REGWIDTH,0) ;\ SREG _R,offset(_BR) ;\ .set offset,offset+REGWIDTH /* RVTEST_SIGUPD_F(basereg, sigreg,flagreg,newoff) */ /* This macro is used to store the signature values of (32 & 64) F and D */ /* teats which use TEST_(FPSR_OP, FPIO_OP, FPRR_OP, FPR4_OP) opcodes */ /* It stores both an Xreg and an Freg, first adjusting base & offset to */ /* to keep offset < 2048. SIGALIGN is set to the max(FREGWIDTH, REGWIDTH)*/ /* _BR - Base Reg, _R - FReg, _F - Fstatus Xreg */ #define RVTEST_SIGUPD_F(_BR,_R,_F,...) ;\ .if NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ .if (offset&(SIGALIGN-1))!=0 ;\ /* Throw warnings then modify offset to target */ ;\ .warning "Incorrect signature Offset Alignment." ;\ .set offset, offset&(SIGALIGN-1)+SIGALIGN ;\ .endif ;\ CHK_OFFSET(_BR, SIGALIGN, 0) ;\ FSREG _R,offset(_BR) ;\ CHK_OFFSET(_BR, SIGALIGN, 1) ;\ SREG _F,offset(_BR) ;\ .set offset,offset+SIGALIGN /* RVTEST_SIGUPD_FID(basereg, sigreg,flagreg,newoff) */ /* This macro stores the signature values of (32 & 64) F & D insts */ /* which uses TEST_(FPID_OP, FCMP_OP) ops */ /* It stores two integer registers. SigReg is stored @offset[BaseReg], */ /* FlagReg at offset+Regwidth[BaseReg]. It updates offset by 2*regwidth */ /* and post increments so repeated uses store sig values sequentially */ /* _BR - Base Reg, _R - Signature reg, _F - Flag reg */ #define RVTEST_SIGUPD_FID(_BR,_R,_F,...) ;\ .if NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ .if (offset&(SIGALIGN-1))!=0 ;\ /* Throw warnings then modify offset to target */ ;\ .warning "Signature Incorrect Offset Alignment." ;\ .set offset, offset&(SIGALIGN-1)+SIGALIGN ;\ .endif ;\ CHK_OFFSET(_BR, REGWIDTH, 0) ;\ SREG _R,offset(_BR) ;\ CHK_OFFSET(_BR, REGWIDTH, 1) ;\ SREG _F,offset(_BR) ;\ .set offset,offset+REGWIDTH // for updating signatures that include flagreg for P-ext saturation instructions (RV32/RV64). #define RVTEST_SIGUPD_PK(_BR,_R,_F,...) ;\ .if NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ .if (offset & (REGWIDTH-1)) != 0 ;\ .warning "Signature Incorrect Offset Alignment." ;\ .set offset, offset&(SIGALIGN-1)+SIGALIGN ;\ .endif ;\ CHK_OFFSET(_BR,REGWIDTH,0) ;\ SREG _R,offset(_BR) ;\ CHK_OFFSET(_BR,REGWIDTH,1) ;\ SREG _F,offset(_BR) ;\ .set offset,offset+(REGWIDTH) // for updating signatures when 'rd' is a paired register (64-bit) // in Zpsfoperand extension in RV32; this reuses RVTEST_SIGUPD_PK() #define RVTEST_SIGUPD_P64(_BR,_R,_R_HI,...) ;\ .if NARG(__VA_ARGS__) == 0 ;\ RVTEST_SIGUPD_PK(_BR,_R,_R_HI) ;\ .else ;\ RVTEST_SIGUPD_PK(_BR,_R,_R_HI,_ARG1(__VA_OPT__(__VA_ARGS__,0))) ;\ .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,...) ;\ rdov _F ;\ .if NARG(__VA_ARGS__) == 1 ;\ .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0)) ;\ .endif ;\ .if (offset & (REGWIDTH-1)) != 0 ;\ .warning "Incorrect Offset Alignment for Signature." ;\ .set offset, offset&(SIGALIGN-1)+SIGALIGN ;\ .endif ;\ CHK_OFFSET(_BR,REGWIDTH,0) ;\ SREG _R,offset(_BR) ;\ CHK_OFFSET(_BR,REGWIDTH,1) ;\ SREG _R_HI,offset(_BR) ;\ CHK_OFFSET(_BR,REGWIDTH,1) ;\ SREG _F,offset(_BR) ;\ .set offset,offset+(REGWIDTH) /* DEPRECATE this is redundant with RVTEST_BASEUPD(BR,_NR), */ /* except it doesn't correct for offset overflow while moving */ #define RVTEST_VALBASEMOV(_NR,_BR) ;\ add _NR, _BR, x0; #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 /* * 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,...) ;\ /* deal with case where offset>=2047 */ ;\ .set corr 2048-REGWIDTH ;\ .if offset <2048 ;\ .set corr offset ;\ .endif ;\ .set offset, offset-corr ;\ ;\ .if NARG(__VA_ARGS__) == 0 ;\ addi _BR, _BR, corr ;\ .else ;\ addi _ARG1(__VA_ARGS__,x0) ,_BR, corr ;\ .endif //============================================================================== // This section borrows from Andrew's from Andrew Waterman's risc-v test macros // They are used to generate tests; some are op specific, some format specific //============================================================================== #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) #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 ;\ .ifc label, 1b ;\ .fill 2,1,0x00 ;\ .endif ;\ .endif ;\ xori rd,rd, 0x1 ;\ beq x0,x0,6b ;\ .if adj & 2 == 2 ;\ .ifc label, 1b ;\ .fill 2,1,0x00 ;\ .endif ;\ .endif ;\ .if (imm/2) - 2 >= 0 ;\ .set num,(imm/2)-2 ;\ .else ;\ .set num,0 ;\ .endif ;\ .ifc 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 ;\ .ifc label, 1b ;\ .set num,0 ;\ .endif ;\ .rept num ;\ nop ;\ .endr ;\ 3: .if adj & 2 == 2 ;\ .ifc label, 3f ;\ .fill 2,1,0x00 ;\ .endif ;\ .endif ;\ xori rd,rd, 0x3 ;\ LA(tempreg, 4f) ;\ jalr x0,0(tempreg) ;\ .if adj & 2 == 2 ;\ .ifc label, 3f ;\ .fill 2,1,0x00 ;\ .endif ;\ .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 ;\ .ifc 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 ;\ .ifc 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) #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) #define TEST_STORE_F(swreg,testreg,fcsr_val,rs1,rs2,imm_val,offset,inst,adj,flagreg,valaddr_reg, val_offset);\ LOAD_MEM_VAL(FLREG, valaddr_reg, rs2, val_offset, testreg);\ addi rs1,swreg,offset+adj ;\ LI(testreg,imm_val) ;\ sub rs1,rs1,testreg ;\ inst rs2, imm_val(rs1) ;\ nop ;\ nop ;\ csrr flagreg, fcsr ;\ RVTEST_SIGUPD(swreg,flagreg,offset+SIGALIGN) #define TEST_LOAD_F(swreg,testreg,fcsr_val,rs1,destreg,imm_val,inst,adj,flagreg) ;\ LA(rs1,rvtest_data+adj-imm_val) ;\ LI(testreg, fcsr_val) ;\ csrw fcsr, testreg ;\ inst destreg, imm_val(rs1) ;\ nop ;\ nop ;\ csrr flagreg, fcsr ;\ RVTEST_SIGUPD_F(swreg,destreg,flagreg) #define TEST_CBO_ZERO(swreg,rs1,inst,imm_val) ;\ LI(rs1,imm_val&(RVMODEL_CBZ_BLOCKSIZE-1)) ;\ add rs1,rs1,swreg ;\ inst (rs1) ;\ nop ;\ nop ;\ ADDI(swreg, swreg, RVMODEL_CBZ_BLOCKSIZE) #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, code... ) ;\ code ;\ RVTEST_SIGUPD_F(swreg,destreg,flagreg) ;\ RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) #define TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, code... ) ;\ code; \ RVTEST_SIGUPD_FID(swreg,destreg,flagreg) ;\ 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, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg, val_offset, testreg); \ LI(testreg, fcsr_val) ;\ csrw fcsr, testreg ;\ inst destreg, freg, rm ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with a single register operand //This variant does not take the rm field and set it while writing the instruction #define TEST_FPSR_OP_NRM( inst, destreg, freg, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg, val_offset, testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with a single register operand and integer destination register #define TEST_FPID_OP( inst, destreg, freg, rm, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg,load_instr) \ TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(load_instr, valaddr_reg, freg, val_offset, testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg, rm ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with a single register operand and integer operand register #define TEST_FPIO_OP( inst, destreg, freg, rm, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg, load_instr) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(load_instr, valaddr_reg, freg, val_offset, testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg, rm ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with a single register operand and integer destination register //This variant does not take the rm field and set it while writing the instruction #define TEST_FPID_OP_NRM( inst, destreg, freg, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg, val_offset, testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with a single register operand and integer operand register //This variant does not take the rm field and set it while writing the instruction #define TEST_FPIO_OP_NRM( inst, destreg, freg, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg, load_instr) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(load_instr, valaddr_reg, freg, val_offset, testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg ;\ csrr flagreg, fcsr ;\ ) //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 //This variant does not take the rm field and set it while writing the instruction #define TEST_FPRR_OP_NRM(inst, destreg, freg1, freg2, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg1, val_offset, testreg) ;\ LOAD_MEM_VAL(FLREG, valaddr_reg, freg2, (val_offset+FREGWIDTH), testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg1, freg2 ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point instructions with register-register operand #define TEST_FPRR_OP(inst, destreg, freg1, freg2, rm, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg1, val_offset, testreg) ;\ LOAD_MEM_VAL(FLREG, valaddr_reg, freg2, (val_offset+FREGWIDTH), testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg1, freg2, rm ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point CMP instructions with register-register operand #define TEST_FCMP_OP(inst, destreg, freg1, freg2, fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_FID(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg1, val_offset, testreg) ;\ LOAD_MEM_VAL(FLREG, valaddr_reg, freg2, (val_offset+FREGWIDTH), testreg) ;\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg1, freg2 ;\ csrr flagreg, fcsr ;\ ) //Tests for floating-point R4 type instructions #define TEST_FPR4_OP(inst, destreg, freg1, freg2, freg3, rm , fcsr_val, correctval, valaddr_reg, val_offset, flagreg, swreg, testreg) \ TEST_CASE_F(testreg, destreg, correctval, swreg, flagreg, \ LOAD_MEM_VAL(FLREG, valaddr_reg, freg1, val_offset, testreg) ;\ LOAD_MEM_VAL(FLREG, valaddr_reg, freg2, (val_offset+FREGWIDTH), testreg) ;\ LOAD_MEM_VAL(FLREG, valaddr_reg, freg3, (val_offset+2*FREGWIDTH), testreg);\ li testreg, fcsr_val; csrw fcsr, testreg ;\ inst destreg, freg1, freg2, freg3, rm ;\ csrr flagreg, fcsr ;\ ) #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 ;\ rdov flagreg ;\ 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) \ LI(reg, MASK_XLEN(val)) ;\ inst destreg, reg ;\ rdov flagreg ;\ RVTEST_SIGUPD_PK(swreg,destreg,flagreg,offset) ;\ RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) #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 single (rd/rs1) register operand. #define TEST_CRD_OP(inst, destreg, correctval, val1, swreg, offset, testreg) \ TEST_CASE(testreg, destreg, correctval, swreg, offset, \ LI(destreg, MASK_XLEN(val1)) ;\ inst destreg ;\ ) //Tests for instructions with a destination and single source 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 ;\ .ifc 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 ;\ .ifc label, 1b ;\ .set num,0 ;\ .endif ;\ .rept num ;\ c.nop ;\ .endr ;\ ;\ 3: addi tempreg, tempreg ,0x3 ;\ ;\ 4: RVTEST_SIGUPD(swreg,tempreg,offset) #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 ;\ .ifc 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 ;\ .ifc label, 1b ;\ .set num,0 ;\ .endif ;\ .rept num ;\ c.nop ;\ .endr ;\ ;\ 3: addi tempreg, tempreg, 0x3 ;\ ;\ 4: RVTEST_SIGUPD(swreg,tempreg,offset) #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 ;\ .ifc 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 ;\ .ifc 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) #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) #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) //--------------------------------- 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