[PATCH v6 2/2] RISC-V: Support Zcmp cm.mv instructions.

Kito Cheng kito.cheng@gmail.com
Thu Feb 1 12:58:01 GMT 2024


LGTM

On Wed, Jan 31, 2024 at 10:12 PM Jiawei <jiawei@iscas.ac.cn> wrote:
>
> This patch supports Zcmp instruction 'cm.mva01s' and 'cm.mvsa01'.
> All disassemble instructions use the sreg format.
>
> Co-Authored by: Charlie Keaney <charlie.keaney@embecosm.com>
> Co-Authored by: Mary Bennett <mary.bennett@embecosm.com>
> Co-Authored by: Nandni Jamnadas <nandni.jamnadas@embecosm.com>
> Co-Authored by: Sinan Lin <sinan.lin@linux.alibaba.com>
> Co-Authored by: Simon Cook <simon.cook@embecosm.com>
> Co-Authored by: Shihua Liao <shihua@iscas.ac.cn>
> Co-Authored by: Yulong Shi <yulong@iscas.ac.cn>
>
> gas/ChangeLog:
>
>         * config/tc-riscv.c (validate_riscv_insn): New operators.
>         (riscv_ip): Ditto.
>         * testsuite/gas/riscv/zcmp-mv.d: New test.
>         * testsuite/gas/riscv/zcmp-mv.s: New test.
>
> include/ChangeLog:
>
>         * opcode/riscv-opc.h (MATCH_CM_MVA01S): New opcode.
>         (MASK_CM_MVA01S): New mask.
>         (MATCH_CM_MVSA01): New opcode.
>         (MASK_CM_MVSA01): New mask.
>         (DECLARE_INSN): New declarations.
>         * opcode/riscv.h (OP_MASK_SREG1): New mask.
>         (OP_SH_SREG1): New operand code.
>         (OP_MASK_SREG2): New mask.
>         (OP_SH_SREG2): New operand code.
>         (X_A0): New reg number.
>         (X_A1): Ditto.
>         (X_S7): Ditto.
>         (RISCV_SREG_0_7): New macro function.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (riscv_zcmp_get_sregno): New function.
>         (print_insn_args): New operators.
>         * riscv-opc.c (match_sreg1_not_eq_sreg2): New match function.
> ---
>  gas/config/tc-riscv.c             | 15 +++++++++++++++
>  gas/testsuite/gas/riscv/zcmp-mv.d | 26 ++++++++++++++++++++++++++
>  gas/testsuite/gas/riscv/zcmp-mv.s | 21 +++++++++++++++++++++
>  include/opcode/riscv-opc.h        |  6 ++++++
>  include/opcode/riscv.h            | 12 ++++++++++++
>  opcodes/riscv-dis.c               | 19 +++++++++++++++++++
>  opcodes/riscv-opc.c               |  9 +++++++++
>  7 files changed, 108 insertions(+)
>  create mode 100644 gas/testsuite/gas/riscv/zcmp-mv.d
>  create mode 100644 gas/testsuite/gas/riscv/zcmp-mv.s
>
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index edb8087463a..c705fd57eaa 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1571,6 +1571,9 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
>             case 'c':
>               switch (*++oparg)
>                 {
> +               /* sreg operators in cm.mvsa01 and cm.mva01s. */
> +               case '1': USE_BITS (OP_MASK_SREG1, OP_SH_SREG1); break;
> +               case '2': USE_BITS (OP_MASK_SREG2, OP_SH_SREG2); break;
>                 /* byte immediate operators, load/store byte insns.  */
>                 case 'h': used_bits |= ENCODE_ZCB_HALFWORD_UIMM (-1U); break;
>                 /* halfword immediate operators, load/store halfword insns.  */
> @@ -3819,6 +3822,18 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>                       asarg = expr_parse_end;
>                       imm_expr->X_op = O_absent;
>                       continue;
> +                   case '1':
> +                     if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
> +                         || !RISCV_SREG_0_7 (regno))
> +                       break;
> +                     INSERT_OPERAND (SREG1, *ip, regno % 8);
> +                     continue;
> +                   case '2':
> +                     if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
> +                         || !RISCV_SREG_0_7 (regno))
> +                       break;
> +                     INSERT_OPERAND (SREG2, *ip, regno % 8);
> +                     continue;
>                     default:
>                       goto unknown_riscv_ip_operand;
>                     }
> diff --git a/gas/testsuite/gas/riscv/zcmp-mv.d b/gas/testsuite/gas/riscv/zcmp-mv.d
> new file mode 100644
> index 00000000000..351d301dd3f
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zcmp-mv.d
> @@ -0,0 +1,26 @@
> +#as: -march=rv64i_zcmp
> +#source: zcmp-mv.s
> +#objdump: -dr -Mno-aliases
> +
> +.*:[    ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[       ]*[0-9a-f]+:[   ]+ac7e[         ]+cm.mva01s[    ]+s0,s7
> +[       ]*[0-9a-f]+:[   ]+ac7a[         ]+cm.mva01s[    ]+s0,s6
> +[       ]*[0-9a-f]+:[   ]+acfe[         ]+cm.mva01s[    ]+s1,s7
> +[       ]*[0-9a-f]+:[   ]+acfa[         ]+cm.mva01s[    ]+s1,s6
> +[       ]*[0-9a-f]+:[   ]+afee[         ]+cm.mva01s[    ]+s7,s3
> +[       ]*[0-9a-f]+:[   ]+ade2[         ]+cm.mva01s[    ]+s3,s0
> +[       ]*[0-9a-f]+:[   ]+aef2[         ]+cm.mva01s[    ]+s5,s4
> +[       ]*[0-9a-f]+:[   ]+aefa[         ]+cm.mva01s[    ]+s5,s6
> +[       ]*[0-9a-f]+:[   ]+afa2[         ]+cm.mvsa01[    ]+s7,s0
> +[       ]*[0-9a-f]+:[   ]+af22[         ]+cm.mvsa01[    ]+s6,s0
> +[       ]*[0-9a-f]+:[   ]+afa6[         ]+cm.mvsa01[    ]+s7,s1
> +[       ]*[0-9a-f]+:[   ]+af26[         ]+cm.mvsa01[    ]+s6,s1
> +[       ]*[0-9a-f]+:[   ]+adbe[         ]+cm.mvsa01[    ]+s3,s7
> +[       ]*[0-9a-f]+:[   ]+ada2[         ]+cm.mvsa01[    ]+s3,s0
> +[       ]*[0-9a-f]+:[   ]+aeb2[         ]+cm.mvsa01[    ]+s5,s4
> +[       ]*[0-9a-f]+:[   ]+aeba[         ]+cm.mvsa01[    ]+s5,s6
> diff --git a/gas/testsuite/gas/riscv/zcmp-mv.s b/gas/testsuite/gas/riscv/zcmp-mv.s
> new file mode 100644
> index 00000000000..0bcf2a6cd98
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zcmp-mv.s
> @@ -0,0 +1,21 @@
> +target:
> +
> +       # cm.mva01s
> +       cm.mva01s s0,s7
> +       cm.mva01s s0,s6
> +       cm.mva01s s1,s7
> +       cm.mva01s s1,s6
> +       cm.mva01s s7,s3
> +       cm.mva01s x19,s0
> +       cm.mva01s s5,x20
> +       cm.mva01s x21,x22
> +
> +       # cm.mvsa01
> +       cm.mvsa01 s7,s0
> +       cm.mvsa01 s6,s0
> +       cm.mvsa01 s7,s1
> +       cm.mvsa01 s6,s1
> +       cm.mvsa01 s3,s7
> +       cm.mvsa01 x19,s0
> +       cm.mvsa01 s5,x20
> +       cm.mvsa01 x21,x22
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index d0f93b11f01..606982d7bb7 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -2244,6 +2244,10 @@
>  #define MASK_CM_POPRET 0xff03
>  #define MATCH_CM_POPRETZ 0xbc02
>  #define MASK_CM_POPRETZ 0xff03
> +#define MATCH_CM_MVA01S 0xac62
> +#define MASK_CM_MVA01S 0xfc63
> +#define MATCH_CM_MVSA01 0xac22
> +#define MASK_CM_MVSA01 0xfc63
>  /* Svinval instruction.  */
>  #define MATCH_SINVAL_VMA 0x16000073
>  #define MASK_SINVAL_VMA 0xfe007fff
> @@ -3930,6 +3934,8 @@ 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)
> +DECLARE_INSN(cm_mvsa01, MATCH_CM_MVSA01, MASK_CM_MVSA01)
> +DECLARE_INSN(cm_mva01s, MATCH_CM_MVA01S, MASK_CM_MVA01S)
>  /* 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 40cc2494eac..ae63029db6a 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -346,6 +346,10 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>  #define OP_MASK_REG_LIST               0xf
>  #define OP_SH_REG_LIST         4
>  #define ZCMP_SP_ALIGNMENT 16
> +#define OP_MASK_SREG1          0x7
> +#define OP_SH_SREG1            7
> +#define OP_MASK_SREG2          0x7
> +#define OP_SH_SREG2            2
>
>  #define NVECR 32
>  #define NVECM 1
> @@ -367,7 +371,10 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>  #define X_T2 7
>  #define X_S0 8
>  #define X_S1 9
> +#define X_A0 10
> +#define X_A1 11
>  #define X_S2 18
> +#define X_S7 23
>  #define X_S10 26
>  #define X_S11 27
>  #define X_T3 28
> @@ -415,6 +422,11 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>  /* The maximal number of subset can be required.  */
>  #define MAX_SUBSET_NUM 4
>
> +/* The range of sregs.  */
> +#define RISCV_SREG_0_7(REGNO) \
> +       ((REGNO == X_S0 || REGNO == X_S1) \
> +        || (REGNO >= X_S2 && REGNO <= X_S7))
> +
>  /* All RISC-V instructions belong to at least one of these classes.  */
>  enum riscv_insn_class
>  {
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 8de03f7d399..dd1eb80275e 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -259,6 +259,17 @@ riscv_get_spimm (insn_t l)
>    return spimm;
>  }
>
> +/* Get s-register regno by using sreg number.
> +   e.g. the regno of s0 is 8, so
> +   riscv_zcmp_get_sregno (0) equals 8. */
> +
> +static unsigned
> +riscv_zcmp_get_sregno (unsigned sreg_idx)
> +{
> +  return sreg_idx > 1 ?
> +      sreg_idx + 16 : sreg_idx + 8;
> +}
> +
>  /* Print insn arguments for 32/64-bit code.  */
>
>  static void
> @@ -672,6 +683,14 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>             case 'c': /* Zcb extension 16 bits length instruction fields. */
>               switch (*++oparg)
>                 {
> +               case '1':
> +                   print (info->stream, dis_style_register, "%s",
> +                     riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG1, l))]);
> +                   break;
> +               case '2':
> +                   print (info->stream, dis_style_register, "%s",
> +                     riscv_gpr_names[riscv_zcmp_get_sregno (EXTRACT_OPERAND (SREG2, l))]);
> +                   break;
>                 case 'b':
>                   print (info->stream, dis_style_immediate, "%d",
>                          (int)EXTRACT_ZCB_BYTE_UIMM (l));
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 3da75db6db1..9d61ce95433 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -333,6 +333,13 @@ match_th_load_pair(const struct riscv_opcode *op,
>    return rd1 != rd2 && rd1 != rs && rd2 != rs && match_opcode (op, insn);
>  }
>
> +static int
> +match_sreg1_not_eq_sreg2 (const struct riscv_opcode *op, insn_t insn)
> +{
> +  return match_opcode (op, insn)
> +      && (EXTRACT_OPERAND (SREG1, insn) != EXTRACT_OPERAND (SREG2, insn));
> +}
> +
>  /* The order of overloaded instructions matters.  Label arguments and
>     register arguments look the same. Instructions that can have either
>     for arguments must apear in the correct order in this table for the
> @@ -1998,6 +2005,8 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"cm.pop",     0,  INSN_CLASS_ZCMP, "{Wcr},Wcp",  MATCH_CM_POP, MASK_CM_POP, match_opcode, 0 },
>  {"cm.popret",  0,  INSN_CLASS_ZCMP, "{Wcr},Wcp",  MATCH_CM_POPRET, MASK_CM_POPRET, match_opcode, 0 },
>  {"cm.popretz", 0,  INSN_CLASS_ZCMP, "{Wcr},Wcp",  MATCH_CM_POPRETZ, MASK_CM_POPRETZ, match_opcode, 0 },
> +{"cm.mva01s",  0,  INSN_CLASS_ZCMP, "Wc1,Wc2",    MATCH_CM_MVA01S, MASK_CM_MVA01S, match_opcode, 0 },
> +{"cm.mvsa01",  0,  INSN_CLASS_ZCMP, "Wc1,Wc2",    MATCH_CM_MVSA01, MASK_CM_MVSA01, match_sreg1_not_eq_sreg2, 0 },
>
>  /* Supervisor instructions.  */
>  {"csrr",       0, INSN_CLASS_ZICSR, "d,E",   MATCH_CSRRS, MASK_CSRRS|MASK_RS1, match_opcode, INSN_ALIAS },
> --
> 2.25.1
>


More information about the Binutils mailing list