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

jiawei@iscas.ac.cn jiawei@iscas.ac.cn
Thu Jul 27 04:52:13 GMT 2023


> -----原始邮件-----
> 发件人: "Tsukasa OI" <research_trasio@irq.a4lg.com>
> 发送时间: 2023-07-27 09:31:26 (星期四)
> 收件人: jiawei@iscas.ac.cn
> 抄送: binutils@sourceware.org
> 主题: Re: [PATCH 2/2] RISC-V: Support Zcmp cm.mv instructions
> 
> So, two patches make full 'Zcmp' extension support, right?

Yes, I still waiting more comment and adjusting the first one.

> 
> I think following patch (inline) is required too because 'Zcmp' is
> incompatible with 'Zcd' (since current Binutils [without my recent patch
> set] does not infer 'Zcd' from 'C' plus 'D', we need to check 'C' + 'D'
> as well).

Thanks!The Zcmp and Zcd has enconding space conflict, 
I will add this in next version patch.

> 
> Thanks,
> Tsukasa
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index e68de65fac15..b42814b6ed3d 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1970,6 +1970,15 @@ riscv_parse_check_conflicts (riscv_parse_subset_t
> *rps)
>  	(_("rv%d does not support the `zcf' extension"), xlen);
>        no_conflict = false;
>      }
> +  if (riscv_lookup_subset (rps->subset_list, "zcmp", &subset)
> +      && ((riscv_lookup_subset (rps->subset_list, "c", &subset)
> +	   && riscv_lookup_subset (rps->subset_list, "d", &subset))
> +	  || riscv_lookup_subset (rps->subset_list, "zcd", &subset)))
> +    {
> +      rps->error_handler (
> +	  _ ("`zcmp' is conflict with the `c+d' / `zcd' extension"));
> +      no_conflict = false;
> +    }
>    if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
>        && riscv_lookup_subset (rps->subset_list, "f", &subset))
>      {
> -- 
> 
> 
> On 2023/07/26 18:06, Jiawei 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_get_sregno):
> >         (print_insn_args):
> >         * riscv-opc.c (match_sreg1_not_eq_sreg2):
> > 
> > ---
> >  gas/config/tc-riscv.c             | 17 +++++++++++++++++
> >  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               |  8 ++++++++
> >  7 files changed, 109 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 266a91451b7..c5be308aa08 100644
> > --- a/gas/config/tc-riscv.c
> > +++ b/gas/config/tc-riscv.c
> > @@ -1578,6 +1578,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.  */
> > @@ -3785,6 +3788,20 @@ 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, ®no)
> > +			  || !RISCV_SREG_0_7 (regno))
> > +			break;
> > +		      INSERT_OPERAND (SREG1, *ip, regno % 8);
> > +		      continue;
> > +
> > +			case '2':
> > +		      if (!reg_lookup (&asarg, RCLASS_GPR, ®no)
> > +			  || !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 f8054f54f15..11e9c0b99d0 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
> > @@ -3419,6 +3423,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 f9bfb19bd5e..44576fa9241 100644
> > --- a/include/opcode/riscv.h
> > +++ b/include/opcode/riscv.h
> > @@ -326,6 +326,10 @@ static inline unsigned int riscv_insn_length (insn_t insn)
> >  /* Zc fields.  */
> >  #define OP_MASK_RLIST		0xf
> >  #define OP_SH_RLIST		4
> > +#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
> > @@ -341,7 +345,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
> > @@ -389,6 +396,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 d938c9cb2ed..058698c0c0a 100644
> > --- a/opcodes/riscv-dis.c
> > +++ b/opcodes/riscv-dis.c
> > @@ -263,6 +263,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_get_sregno (0) equals 8. */
> > +
> > +static unsigned
> > +riscv_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
> > @@ -667,6 +678,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_get_sregno (EXTRACT_OPERAND (SREG1, l))]);
> > +		    break;
> > +		  case '2':
> > +		    print (info->stream, dis_style_register, "%s",
> > +		      riscv_gpr_names[riscv_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 7d2f92e736b..b0a69efed49 100644
> > --- a/opcodes/riscv-opc.c
> > +++ b/opcodes/riscv-opc.c
> > @@ -329,6 +329,12 @@ match_th_load_pair(const struct riscv_opcode *op,
> >    return rd1 != rd2 && rd1 != rs && rd2 != rs && match_opcode (op, insn);
> >  }
> >  
> > +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));
> > +}
> > +
> >  const struct riscv_opcode riscv_opcodes[] =
> >  {
> >  /* name, xlen, isa, operands, match, mask, match_func, pinfo.  */
> > @@ -1972,6 +1978,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 },
</target></yulong@iscas.ac.cn></shihua@iscas.ac.cn></simon.cook@embecosm.com></sinan.lin@linux.alibaba.com></nandni.jamnadas@embecosm.com></mary.bennett@embecosm.com></charlie.keaney@embecosm.com></research_trasio@irq.a4lg.com>


More information about the Binutils mailing list