From 9132c8152b899a1683bc886f8ba76bedadb48aa1 Mon Sep 17 00:00:00 2001 From: Jiawei Date: Tue, 27 Feb 2024 11:48:11 +0800 Subject: RISC-V: Support Zcmp push/pop instructions. Support zcmp extension push/pop/popret and popret zero instructions. The `reg_list' is a list containing 1 to 13 registers, we can use: "{ra}, {ra, s0}, {ra, s0-s1}, {ra, s0-s2} ... {ra, s0-sN}" to present this feature. Passed gcc/binutils regressions of riscv-gnu-toolchain. Most of work was finished by Sinan Lin. Co-Authored by: Charlie Keaney Co-Authored by: Mary Bennett Co-Authored by: Nandni Jamnadas Co-Authored by: Sinan Lin Co-Authored by: Simon Cook Co-Authored by: Shihua Liao Co-Authored by: Yulong Shi bfd/ChangeLog: * elfxx-riscv.c (riscv_implicit_subset): Imply zca for zcmp. (riscv_supported_std_z_ext): Added zcmp with version 1.0. (riscv_parse_check_conflicts): Zcmp conflicts with d/zcd. (riscv_multi_subset_supports): Handle zcmp. (riscv_multi_subset_supports_ext): Ditto. gas/ChangeLog: * NEWS: Updated. * config/tc-riscv.c (regno_to_reg_list): New function, used to map register to reg_list number. (reglist_lookup): Called reglist_lookup_internal. Return false if reg_list number is zero, which is an invalid value. (reglist_lookup_internal): Parse register list, and return the last register by regno_to_reg_list. (validate_riscv_insn): New operators. (riscv_ip): Ditto. * testsuite/gas/riscv/march-help.l: Updated. * testsuite/gas/riscv/zcmp-push-pop-fail.d: New test. * testsuite/gas/riscv/zcmp-push-pop-fail.l: New test. * testsuite/gas/riscv/zcmp-push-pop-fail.s: New test. * testsuite/gas/riscv/zcmp-push-pop.d: New test. * testsuite/gas/riscv/zcmp-push-pop.s: New test. include/ChangeLog: * opcode/riscv-opc.h (MATCH/MASK_CM_PUSH): New macros for zcmp. (MATCH/MASK_CM_POP): Ditto. (MATCH/MASK_CM_POPRET): Ditto. (MATCH/MASK_CM_POPRETZ): Ditto. (DECLARE_INSN): New declarations for zcmp. * opcode/riscv.h (EXTRACT/ENCODE/VALID_ZCMP_SPIMM): Handle spimm operand for zcmp. (OP_MASK_REG_LIST): Handle operand for zcmp register list. (OP_SH_REG_LIST): Ditto. (ZCMP_SP_ALIGNMENT): New argument, used in riscv_get_sp_base. (X_S0, X_S1, X_S2, X_S10, X_S11): New register numbers. (enum riscv_insn_class): Added INSN_CLASS_ZCMP. (extern riscv_get_sp_base): Added. opcodes/ChangeLog: * riscv-dis.c (print_reg_list): New function, used to get zcmp reg_list field. (riscv_get_spimm): New function, used to get zcmp sp adjustment immediate. (print_insn_args): Handle new operands for zcmp. * riscv-opc.c (riscv_get_sp_base): New function, used by gas and objdump. Get sp base adjustment. (riscv_opcodes): Added zcmp instructions. --- include/opcode/riscv-opc.h | 14 ++++++++++++++ include/opcode/riscv.h | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'include') diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 1459ef2..ae14e14 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2271,6 +2271,15 @@ #define MASK_C_NOT 0xfc7f #define MATCH_C_MUL 0x9c41 #define MASK_C_MUL 0xfc63 +/* Zcmp instructions. */ +#define MATCH_CM_PUSH 0xb802 +#define MASK_CM_PUSH 0xff03 +#define MATCH_CM_POP 0xba02 +#define MASK_CM_POP 0xff03 +#define MATCH_CM_POPRET 0xbe02 +#define MASK_CM_POPRET 0xff03 +#define MATCH_CM_POPRETZ 0xbc02 +#define MASK_CM_POPRETZ 0xff03 /* Svinval instruction. */ #define MATCH_SINVAL_VMA 0x16000073 #define MASK_SINVAL_VMA 0xfe007fff @@ -3964,6 +3973,11 @@ DECLARE_INSN(c_lhu, MATCH_C_LHU, MASK_C_LHU) DECLARE_INSN(c_lh, MATCH_C_LH, MASK_C_LH) DECLARE_INSN(c_sb, MATCH_C_SB, MASK_C_SB) DECLARE_INSN(c_sh, MATCH_C_SH, MASK_C_SH) +/* Zcmp instructions. */ +DECLARE_INSN(cm_push, MATCH_CM_PUSH, MASK_CM_PUSH) +DECLARE_INSN(cm_pop, MATCH_CM_POP, MASK_CM_POP) +DECLARE_INSN(cm_popret, MATCH_CM_POPRET, MASK_CM_POPRET) +DECLARE_INSN(cm_popretz, MATCH_CM_POPRETZ, MASK_CM_POPRETZ) /* Vendor-specific (T-Head) XTheadBa instructions. */ DECLARE_INSN(th_addsl, MATCH_TH_ADDSL, MASK_TH_ADDSL) /* Vendor-specific (T-Head) XTheadBb instructions. */ diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 3245873..d967b78 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -112,6 +112,8 @@ static inline unsigned int riscv_insn_length (insn_t insn) (RV_X(x, 6, 1) | (RV_X(x, 5, 1) << 1)) #define EXTRACT_ZCB_HALFWORD_UIMM(x) \ (RV_X(x, 5, 1) << 1) +#define EXTRACT_ZCMP_SPIMM(x) \ + (RV_X(x, 2, 2) << 4) /* Vendor-specific (CORE-V) extract macros. */ #define EXTRACT_CV_IS2_UIMM5(x) \ (RV_X(x, 20, 5)) @@ -168,6 +170,8 @@ static inline unsigned int riscv_insn_length (insn_t insn) ((RV_X(x, 0, 1) << 6) | (RV_X(x, 1, 1) << 5)) #define ENCODE_ZCB_HALFWORD_UIMM(x) \ (RV_X(x, 1, 1) << 5) +#define ENCODE_ZCMP_SPIMM(x) \ + (RV_X(x, 4, 2) << 2) /* Vendor-specific (CORE-V) encode macros. */ #define ENCODE_CV_IS2_UIMM5(x) \ (RV_X(x, 0, 5) << 20) @@ -200,6 +204,7 @@ static inline unsigned int riscv_insn_length (insn_t insn) #define VALID_RVV_VC_IMM(x) (EXTRACT_RVV_VC_IMM(ENCODE_RVV_VC_IMM(x)) == (x)) #define VALID_ZCB_BYTE_UIMM(x) (EXTRACT_ZCB_BYTE_UIMM(ENCODE_ZCB_BYTE_UIMM(x)) == (x)) #define VALID_ZCB_HALFWORD_UIMM(x) (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x)) +#define VALID_ZCMP_SPIMM(x) (EXTRACT_ZCMP_SPIMM(ENCODE_ZCMP_SPIMM(x)) == (x)) #define RISCV_RTYPE(insn, rd, rs1, rs2) \ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2)) @@ -337,6 +342,11 @@ static inline unsigned int riscv_insn_length (insn_t insn) #define OP_MASK_XTHEADVTYPE_RES 0xf #define OP_SH_XTHEADVTYPE_RES 7 +/* Zc fields. */ +#define OP_MASK_REG_LIST 0xf +#define OP_SH_REG_LIST 4 +#define ZCMP_SP_ALIGNMENT 16 + #define NVECR 32 #define NVECM 1 @@ -355,6 +365,11 @@ static inline unsigned int riscv_insn_length (insn_t insn) #define X_T0 5 #define X_T1 6 #define X_T2 7 +#define X_S0 8 +#define X_S1 9 +#define X_S2 18 +#define X_S10 26 +#define X_S11 27 #define X_T3 28 #define NGPR 32 @@ -464,6 +479,7 @@ enum riscv_insn_class INSN_CLASS_ZCB_AND_ZBA, INSN_CLASS_ZCB_AND_ZBB, INSN_CLASS_ZCB_AND_ZMMUL, + INSN_CLASS_ZCMP, INSN_CLASS_SVINVAL, INSN_CLASS_ZICBOM, INSN_CLASS_ZICBOP, @@ -613,4 +629,6 @@ extern const float riscv_fli_numval[32]; extern const struct riscv_opcode riscv_opcodes[]; extern const struct riscv_opcode riscv_insn_types[]; +extern unsigned int riscv_get_sp_base (insn_t, unsigned int); + #endif /* _RISCV_H_ */ -- cgit v1.1