From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sender-0.a4lg.com (mail-sender-0.a4lg.com [IPv6:2401:2500:203:30b:4000:6bfe:4757:0]) by sourceware.org (Postfix) with ESMTPS id B256A3858CD1 for ; Wed, 26 Jul 2023 06:50:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B256A3858CD1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=irq.a4lg.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=irq.a4lg.com Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id 835A4300089; Wed, 26 Jul 2023 06:50:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=irq.a4lg.com; s=2017s01; t=1690354229; bh=9sJ6tNaXUvpU78bpJFJG53Ut7qrgaSJ+rZCKj2bb6Wk=; h=Message-ID:Date:Mime-Version:Subject:To:References:Cc:From: In-Reply-To:Content-Type:Content-Transfer-Encoding; b=boin8pTTHGqFi6eTJz/p26mIZfv2XVj1M4TcKE7PEHgQJEVrjWVAzpj8XrfgP5uTs vSzTCu+aEU+vNiiWCN5+VeKRH6B5pA+LyloRCsFME5V4lGhpzDR0Ww5s1SefyxKUST hDqXhFDiNGbnLAf4bEEmfrzHXsXhgN+8nRox/VC0= Message-ID: <932f86fc-a17d-3a5d-d38f-f41b27a7eb69@irq.a4lg.com> Date: Wed, 26 Jul 2023 15:50:29 +0900 Mime-Version: 1.0 Subject: Re: [PATCH] RISC-V: Support Zcmp push/pop instructions Content-Language: en-US To: jiawei@iscas.ac.cn References: <20230726032206.494326-1-jiawei@iscas.ac.cn> Cc: binutils@sourceware.org From: Tsukasa OI In-Reply-To: <20230726032206.494326-1-jiawei@iscas.ac.cn> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Magnificent! The register list parser is well written and makes sense. My review comments include very minor formatting issue but functionally, it's almost complete and feels good (in other words, it's almost the time to improve/fix the formatting, too). Thanks, Tsukasa On 2023/07/26 12:22, Jiawei wrote: > Support zcmp extension push/pop/popret and popret zero instructions. > `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. > `stack_adj` is the total size of the stack frame, use > `riscv_get_sp_base` function to calculate it. > Most 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_get_sp_base): New function. > (riscv_multi_subset_supports): New extension. > (riscv_multi_subset_supports_ext): Ditto. > * elfxx-riscv.h (SP_ALIGNMENT): New macro. > (riscv_get_sp_base): New function prototype. > > gas/ChangeLog: > > * config/tc-riscv.c (regno_to_rlist): New regs mapping. > (reglist_lookup): New function. > (validate_riscv_insn): New operators. > (riscv_ip): Ditto. > * 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_CM_PUSH): New opcode. > (MASK_CM_PUSH): New mask. > (MATCH_CM_POP): New opcode. > (MASK_CM_POP): New mask. > (MATCH_CM_POPRET): New opcode. > (MASK_CM_POPRET): New mask. > (MATCH_CM_POPRETZ): New opcode. > (MASK_CM_POPRETZ): New mask. > * opcode/riscv.h (EXTRACT_ZCMP_SPIMM): New inline function. > (ENCODE_ZCMP_SPIMM): Ditto. > (VALID_ZCMP_SPIMM): Ditto. > (OP_MASK_RLIST): New mask. > (OP_SH_RLIST): New operand code. > (X_S0): New reg number. > (X_S1): Ditto. > (X_S2): Ditto. > (X_S10): Ditto. > (X_S11): Ditto. > (enum riscv_insn_class): New extension class. > > opcodes/ChangeLog: > > * riscv-dis.c (set_default_riscv_dis_options): New var. > (parse_riscv_dis_option_without_args): Ditto. > (print_rlist): New print function. > (riscv_get_spimm): New function. > (print_insn_args): New operators. > * riscv-opc.c: New instructions. > --- > bfd/elfxx-riscv.c | 23 ++- > bfd/elfxx-riscv.h | 4 + > gas/config/tc-riscv.c | 180 ++++++++++++++++- > gas/testsuite/gas/riscv/zcmp-push-pop-fail.d | 3 + > gas/testsuite/gas/riscv/zcmp-push-pop-fail.l | 9 + > gas/testsuite/gas/riscv/zcmp-push-pop-fail.s | 13 ++ > gas/testsuite/gas/riscv/zcmp-push-pop.d | 154 +++++++++++++++ > gas/testsuite/gas/riscv/zcmp-push-pop.s | 197 +++++++++++++++++++ > include/opcode/riscv-opc.h | 9 + > include/opcode/riscv.h | 13 ++ > opcodes/riscv-dis.c | 57 ++++++ > opcodes/riscv-opc.c | 6 + > 12 files changed, 665 insertions(+), 3 deletions(-) > create mode 100644 gas/testsuite/gas/riscv/zcmp-push-pop-fail.d > create mode 100644 gas/testsuite/gas/riscv/zcmp-push-pop-fail.l > create mode 100644 gas/testsuite/gas/riscv/zcmp-push-pop-fail.s > create mode 100644 gas/testsuite/gas/riscv/zcmp-push-pop.d > create mode 100644 gas/testsuite/gas/riscv/zcmp-push-pop.s > > diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c > index b43d2cfa0fa..2800edb8206 100644 > --- a/bfd/elfxx-riscv.c > +++ b/bfd/elfxx-riscv.c > @@ -1084,6 +1084,19 @@ check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED, > && subset->minor_version < 1)); > } > > +/* get sp base adjustment */ > + > +int > +riscv_get_sp_base (insn_t opcode, riscv_parse_subset_t *rps) Is this *that* generic (could be used outside?) I will prefer either: 1. riscv_get_sp_base_from_rlist 2. riscv_zcmp_get_sp_base Also, I think the most appropriate position of this function would be in binutils/include/opcode/riscv.h (like the "riscv_insn_length" function). We could accept "unsigned xlen" instead of a complex object "rps". > +{ > + unsigned reg_size = *(rps->xlen) / 8; > + unsigned rlist = EXTRACT_BITS (opcode, OP_MASK_RLIST, OP_SH_RLIST); > + > + unsigned min_sp_adj = (rlist - 3) * reg_size + (rlist == 15 ? reg_size : 0); > + return ((min_sp_adj / SP_ALIGNMENT) + (min_sp_adj % SP_ALIGNMENT != 0)) > + * SP_ALIGNMENT; > +} > + > /* Record all implicit information for the subsets. */ > struct riscv_implicit_subset > { > @@ -1176,6 +1189,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = > {"zcf", "zca", check_implicit_always}, > {"zcd", "zca", check_implicit_always}, > {"zcb", "zca", check_implicit_always}, > + {"zcmp", "zca", check_implicit_always}, > {"smaia", "ssaia", check_implicit_always}, > {"smstateen", "ssstateen", check_implicit_always}, > {"smepmp", "zicsr", check_implicit_always}, > @@ -1313,6 +1327,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = > {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, > {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, > {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, > + {"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, > {NULL, 0, 0, 0, 0} > }; > > @@ -2514,8 +2529,10 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, > return (riscv_subset_supports (rps, "zcb") > && riscv_subset_supports (rps, "zba")); > case INSN_CLASS_ZCB_AND_ZMMUL: > - return (riscv_subset_supports (rps, "zcb") > - && riscv_subset_supports (rps, "zmmul")); > + return riscv_subset_supports (rps, "zcb") > + && riscv_subset_supports (rps, "zmmul"); > + case INSN_CLASS_ZCMP: > + return riscv_subset_supports (rps, "zcmp"); > case INSN_CLASS_SVINVAL: > return riscv_subset_supports (rps, "svinval"); > case INSN_CLASS_H: > @@ -2732,6 +2749,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, > return _("zcb' and `zbb"); > case INSN_CLASS_ZCB_AND_ZMMUL: > return _("zcb' and `zmmul', or `zcb' and `m"); > + case INSN_CLASS_ZCMP: > + return "zcmp"; > case INSN_CLASS_SVINVAL: > return "svinval"; > case INSN_CLASS_H: > diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h > index abcb409bd78..ae144567116 100644 > --- a/bfd/elfxx-riscv.h > +++ b/bfd/elfxx-riscv.h > @@ -26,6 +26,7 @@ > #include "cpu-riscv.h" > > #define RISCV_UNKNOWN_VERSION -1 > +#define SP_ALIGNMENT 16 > > struct riscv_elf_params > { > @@ -123,3 +124,6 @@ extern void > bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *); > extern void > bfd_elf64_riscv_set_data_segment_info (struct bfd_link_info *, int *); > + > +extern int > +riscv_get_sp_base (insn_t, riscv_parse_subset_t *); > \ No newline at end of file No new line at EOF is a problem. Insert a new line after that declaration. If you move the function to binutils/include/opcode/riscv.h, this declaration will be no longer required. > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c > index aaf8b9be64f..266a91451b7 100644 > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -1237,6 +1237,152 @@ flt_lookup (float f, const float *array, size_t size, unsigned *regnop) > return false; > } > > +/* Map ra and s-register to [4,15], so that we can check if the > + reg2 in register list reg1-reg2 or single reg2 is valid or not, > + and obtain the corresponding rlist value. Indentation: 3 spaces before "reg2" and "and". > + > + ra - 4 > + s0 - 5 > + s1 - 6 > + .... > + s10 - 0 (invalid) > + s11 - 15 > +*/ > + > +static int > +regno_to_rlist (unsigned regno) > +{ > + if (regno == X_RA) > + return 4; > + else if (regno == X_S0 || regno == X_S1) > + return 5 + regno - X_S0; > + else if (regno >= X_S2 && regno < X_S10) > + return 7 + regno - X_S2; > + else if (regno == X_S11) > + return 15; > + > + return 0; /* invalid symbol */ > +} > + > +/* Parse register list, and the parsed rlist value is stored in rlist > + argument. > + > + If ABI register names are used (e.g. ra and s0), the register > + list could be "{ra}", "{ra, s0}", "{ra, s0-sN}", where 0 < N < 10 or > + N == 11. > + > + If numeric register names are used (e.g. x1 and x8), the register list > + could be "{x1}", "{x1,x8}", "{x1,x8-x9}", "{x1,x8-x9, x18}" and > + "{x1,x8-x9,x18-xN}", where 19 < N < 25 or N == 27. > + > + It will fail if numeric register names and ABI register names are used > + at the same time. > + */ Formatting: use 3 (instead of 2) spaces before the comment text (line 2 and later on the comment and end of the comment "*/"). > + > +static bool > +reglist_lookup (char **s, unsigned *rlist) > +{ > + unsigned regno; > + /* Use to check if the register format is xreg. */ > + bool use_xreg = **s == 'x'; > + > + /* The first register in register list should be ra. */ > + if (!reg_lookup (s, RCLASS_GPR, ®no) > + || !(*rlist = regno_to_rlist (regno)) /* update rlist */ > + || regno != X_RA) > + return FALSE; Use "false" instead of "FALSE". It applies to the all occurrences of "FALSE" later. > + > + /* Skip "whitespace, whitespace" pattern. */ > + while (ISSPACE (**s)) > + ++ *s; > + if (**s == '}') > + return TRUE; Likewise, use "true" instead of "TRUE". > + else if (**s != ',') > + return FALSE; > + while (ISSPACE (*++*s)) > + ++ *s; > + > + /* Do not use numeric and abi names at the same time. */ > + if (use_xreg && **s != 'x') > + return FALSE; > + > + /* Reg1 should be s0 or its numeric names x8. */ > + if (!reg_lookup (s, RCLASS_GPR, ®no) > + || !(*rlist = regno_to_rlist (regno)) > + || regno != X_S0) > + return FALSE; > + > + /* Skip "whitespace - whitespace" pattern. */ > + while (ISSPACE (**s)) > + ++ *s; > + if (**s == '}') > + return TRUE; > + else if (**s != '-') > + return FALSE; > + while (ISSPACE (*++*s)) > + ++ *s; > + > + if (use_xreg && **s != 'x') > + return FALSE; > + > + /* Reg2 is x9 if the numeric name is used, otherwise, > + it could be any other sN register, where N > 0. */ Indentation: 3 spaces before "it". > + if (!reg_lookup (s, RCLASS_GPR, ®no) > + || !(*rlist = regno_to_rlist (regno)) > + || regno <= X_S0 > + || (use_xreg && regno != X_S1)) > + return FALSE; > + > + /* Skip whitespace */ Indentation: 2 spaces before "/*". > + while (ISSPACE (**s)) > + ++ *s; > + > + /* Check if it is the end of register list. */ > + if (**s == '}') > + return TRUE; > + else if (!use_xreg) > + return FALSE; > + > + /* Here is not reachable if the abi name is used. */ > + gas_assert (use_xreg); > + > + /* If the numeric name is used, we need to parse extra > + register list, reg3 or reg3-reg4. */ Indentation: 3 spaces before "register". > + > + /* Skip ", white space" pattern. */ > + if (**s != ',') > + return FALSE; > + while (ISSPACE (*++*s)) > + ++ *s; > + > + if (use_xreg && **s != 'x') > + return FALSE; > + > + /* Reg3 should be s2. */ > + if (!reg_lookup (s, RCLASS_GPR, ®no) > + || !(*rlist = regno_to_rlist (regno)) > + || regno != X_S2) > + return FALSE; On "if" block, reduce the indentation by 2 (prefixing 1 tab will become 6 spaces after applying this fix). > + > + /* skip "whitespace - whitespace" pattern. */ > + while (ISSPACE (**s)) > + ++ *s; > + if (**s == '}') > + return TRUE; > + else if (**s != '-') > + return FALSE; > + while (ISSPACE (*++*s)) > + ++ *s; > + > + /* Reg4 could be any other sN register, where N > 1. */ > + if (!reg_lookup (s, RCLASS_GPR, ®no) > + || !(*rlist = regno_to_rlist (regno)) > + || regno <= X_S2) > + return FALSE; > + > + return TRUE; > +} > + > #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift))) > #define USE_IMM(n, s) \ > (used_bits |= ((insn_t)((1ull< @@ -1353,6 +1499,9 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) > case ',': break; > case '(': break; > case ')': break; > + case '{': break; > + case '}': break; > + case '!': break; > case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break; > case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break; > case 'A': break; /* Macro operand, must be symbol. */ > @@ -1433,6 +1582,10 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) > case 'h': used_bits |= ENCODE_ZCB_HALFWORD_UIMM (-1U); break; > /* halfword immediate operators, load/store halfword insns. */ > case 'b': used_bits |= ENCODE_ZCB_BYTE_UIMM (-1U); break; > + /* immediate offset operand for cm.push and cm.pop. */ Indentation: 2 tabs before "/*". > + case 'p': used_bits |= ENCODE_ZCMP_SPIMM (-1U); break; > + /* register list operand for cm.push and cm.pop. */ > + case 'r': USE_BITS (OP_MASK_RLIST, OP_SH_RLIST); break; > case 'f': break; > default: > goto unknown_validate_operand; > @@ -3141,6 +3294,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, > case ')': > case '[': > case ']': > + case '{': > + case '}': > if (*asarg++ == *oparg) > continue; > break; > @@ -3597,7 +3752,30 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, > ip->insn_opcode |= ENCODE_ZCB_BYTE_UIMM (imm_expr->X_add_number); > goto rvc_imm_done; > > - case 'f': /* Operand for matching immediate 255. */ > + case 'r': > + /* we use regno to store reglist value here. */ > + if (!reglist_lookup (&asarg, ®no)) > + break; > + INSERT_OPERAND (RLIST, *ip, regno); > + continue; > + > + case 'p': > + if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p) > + || imm_expr->X_op != O_constant) > + break; > + /* convert stack adjust of cm.push to a positive offset. */ > + if (ip->insn_mo->match == MATCH_CM_PUSH) > + imm_expr->X_add_number *= -1; > + /* subtract base stack adjust and get spimm. */ > + imm_expr->X_add_number -= > + riscv_get_sp_base (ip->insn_opcode, &riscv_rps_as); > + if (!VALID_ZCMP_SPIMM (imm_expr->X_add_number)) > + break; > + ip->insn_opcode |= > + ENCODE_ZCMP_SPIMM (imm_expr->X_add_number); > + goto rvc_imm_done; > + > + case 'f': /* operand for matching immediate 255. */ Indentation: 2 tabs and 4 spaces before "case". > if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p) > || imm_expr->X_op != O_constant > || imm_expr->X_add_number != 255) > diff --git a/gas/testsuite/gas/riscv/zcmp-push-pop-fail.d b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.d Tests are very good (except missing new line I comment later). But, I will recommend using the file names beginning with "zcmp-" instead of "zcmp-push-pop-". I think that the push/pop and "move two registers" are being separately developed but splitting the file name feels... too much for the final submission. > new file mode 100644 > index 00000000000..ca1d88e6299 > --- /dev/null > +++ b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.d > @@ -0,0 +1,3 @@ > +#as: -march=rv64i_zcmp > +#source: zcmp-push-pop-fail.s > +#error_output: zcmp-push-pop-fail.l > \ No newline at end of file Place a new line after "-fail.l". > diff --git a/gas/testsuite/gas/riscv/zcmp-push-pop-fail.l b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.l > new file mode 100644 > index 00000000000..955e495d5bb > --- /dev/null > +++ b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.l > @@ -0,0 +1,9 @@ > +.*: Assembler messages: > +.*: Error: illegal operands `cm.push \{a0\},-64' > +.*: Error: illegal operands `cm.pop \{ra,s1\},-64' > +.*: Error: illegal operands `cm.popret \{ra,s2-s3\},-64' > +.*: Error: illegal operands `cm.popretz \{ra,s0-s10\},-112' > +.*: Error: illegal operands `cm.push \{ra\},0' > +.*: Error: illegal operands `cm.pop \{ra,s0\},-80' > +.*: Error: illegal operands `cm.popret \{ra,s0-s1\},-15' > +.*: Error: illegal operands `cm.popretz \{ra,s0-s11\},-165' > diff --git a/gas/testsuite/gas/riscv/zcmp-push-pop-fail.s b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.s > new file mode 100644 > index 00000000000..a82f9399787 > --- /dev/null > +++ b/gas/testsuite/gas/riscv/zcmp-push-pop-fail.s > @@ -0,0 +1,13 @@ > +target: > + > + # rlist > + cm.push {a0}, -64 > + cm.pop {ra, s1}, -64 > + cm.popret {ra, s2-s3}, -64 > + cm.popretz {ra, s0-s10}, -112 > + > + # spimm > + cm.push {ra}, 0 > + cm.pop {ra, s0}, -80 > + cm.popret {ra, s0-s1}, -15 > + cm.popretz {ra, s0-s11}, -165 > diff --git a/gas/testsuite/gas/riscv/zcmp-push-pop.d b/gas/testsuite/gas/riscv/zcmp-push-pop.d > new file mode 100644 > index 00000000000..e21295051ec > --- /dev/null > +++ b/gas/testsuite/gas/riscv/zcmp-push-pop.d > @@ -0,0 +1,154 @@ > +#as: -march=rv64i_zcmp > +#source: zcmp-push-pop.s > +#objdump: -dr -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+000 : > +[ ]*[0-9a-f]+:[ ]+b84e[ ]+cm.push[ ]+\{ra\},-64 > +[ ]*[0-9a-f]+:[ ]+b85e[ ]+cm.push[ ]+\{ra,s0\},-64 > +[ ]*[0-9a-f]+:[ ]+b86a[ ]+cm.push[ ]+\{ra,s0-s1\},-64 > +[ ]*[0-9a-f]+:[ ]+b87a[ ]+cm.push[ ]+\{ra,s0-s2\},-64 > +[ ]*[0-9a-f]+:[ ]+b8da[ ]+cm.push[ ]+\{ra,s0-s8\},-112 > +[ ]*[0-9a-f]+:[ ]+b8e6[ ]+cm.push[ ]+\{ra,s0-s9\},-112 > +[ ]*[0-9a-f]+:[ ]+b8f2[ ]+cm.push[ ]+\{ra,s0-s11\},-112 > +[ ]*[0-9a-f]+:[ ]+b84e[ ]+cm.push[ ]+\{ra\},-64 > +[ ]*[0-9a-f]+:[ ]+b85e[ ]+cm.push[ ]+\{ra,s0\},-64 > +[ ]*[0-9a-f]+:[ ]+b86a[ ]+cm.push[ ]+\{ra,s0-s1\},-64 > +[ ]*[0-9a-f]+:[ ]+b87a[ ]+cm.push[ ]+\{ra,s0-s2\},-64 > +[ ]*[0-9a-f]+:[ ]+b8da[ ]+cm.push[ ]+\{ra,s0-s8\},-112 > +[ ]*[0-9a-f]+:[ ]+b8e6[ ]+cm.push[ ]+\{ra,s0-s9\},-112 > +[ ]*[0-9a-f]+:[ ]+b8f2[ ]+cm.push[ ]+\{ra,s0-s11},-112 > +[ ]*[0-9a-f]+:[ ]+b842[ ]+cm.push[ ]+\{ra\},-16 > +[ ]*[0-9a-f]+:[ ]+b846[ ]+cm.push[ ]+\{ra\},-32 > +[ ]*[0-9a-f]+:[ ]+b84e[ ]+cm.push[ ]+\{ra\},-64 > +[ ]*[0-9a-f]+:[ ]+b872[ ]+cm.push[ ]+\{ra,s0-s2\},-32 > +[ ]*[0-9a-f]+:[ ]+b87a[ ]+cm.push[ ]+\{ra,s0-s2\},-64 > +[ ]*[0-9a-f]+:[ ]+b87e[ ]+cm.push[ ]+\{ra,s0-s2\},-80 > +[ ]*[0-9a-f]+:[ ]+b882[ ]+cm.push[ ]+\{ra,s0-s3\},-48 > +[ ]*[0-9a-f]+:[ ]+b886[ ]+cm.push[ ]+\{ra,s0-s3\},-64 > +[ ]*[0-9a-f]+:[ ]+b88e[ ]+cm.push[ ]+\{ra,s0-s3\},-96 > +[ ]*[0-9a-f]+:[ ]+b8b2[ ]+cm.push[ ]+\{ra,s0-s6\},-64 > +[ ]*[0-9a-f]+:[ ]+b8b6[ ]+cm.push[ ]+\{ra,s0-s6\},-80 > +[ ]*[0-9a-f]+:[ ]+b8be[ ]+cm.push[ ]+\{ra,s0-s6\},-112 > +[ ]*[0-9a-f]+:[ ]+b8c2[ ]+cm.push[ ]+\{ra,s0-s7\},-80 > +[ ]*[0-9a-f]+:[ ]+b8c6[ ]+cm.push[ ]+\{ra,s0-s7\},-96 > +[ ]*[0-9a-f]+:[ ]+b8ce[ ]+cm.push[ ]+\{ra,s0-s7\},-128 > +[ ]*[0-9a-f]+:[ ]+b8e2[ ]+cm.push[ ]+\{ra,s0-s9\},-96 > +[ ]*[0-9a-f]+:[ ]+b8e6[ ]+cm.push[ ]+\{ra,s0-s9\},-112 > +[ ]*[0-9a-f]+:[ ]+b8ee[ ]+cm.push[ ]+\{ra,s0-s9\},-144 > +[ ]*[0-9a-f]+:[ ]+b8f2[ ]+cm.push[ ]+\{ra,s0-s11\},-112 > +[ ]*[0-9a-f]+:[ ]+b8f6[ ]+cm.push[ ]+\{ra,s0-s11\},-128 > +[ ]*[0-9a-f]+:[ ]+b8fa[ ]+cm.push[ ]+\{ra,s0-s11\},-144 > +[ ]*[0-9a-f]+:[ ]+b8fe[ ]+cm.push[ ]+\{ra,s0-s11\},-160 > +[ ]*[0-9a-f]+:[ ]+ba4e[ ]+cm.pop[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+ba5e[ ]+cm.pop[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+ba6a[ ]+cm.pop[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+ba7a[ ]+cm.pop[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+bada[ ]+cm.pop[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bae6[ ]+cm.pop[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+baf2[ ]+cm.pop[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+ba4e[ ]+cm.pop[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+ba5e[ ]+cm.pop[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+ba6a[ ]+cm.pop[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+ba7a[ ]+cm.pop[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+bada[ ]+cm.pop[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bae6[ ]+cm.pop[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+baf2[ ]+cm.pop[ ]+\{ra,s0-s11},112 > +[ ]*[0-9a-f]+:[ ]+ba42[ ]+cm.pop[ ]+\{ra\},16 > +[ ]*[0-9a-f]+:[ ]+ba46[ ]+cm.pop[ ]+\{ra\},32 > +[ ]*[0-9a-f]+:[ ]+ba4e[ ]+cm.pop[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+ba72[ ]+cm.pop[ ]+\{ra,s0-s2\},32 > +[ ]*[0-9a-f]+:[ ]+ba7a[ ]+cm.pop[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+ba7e[ ]+cm.pop[ ]+\{ra,s0-s2\},80 > +[ ]*[0-9a-f]+:[ ]+ba82[ ]+cm.pop[ ]+\{ra,s0-s3\},48 > +[ ]*[0-9a-f]+:[ ]+ba86[ ]+cm.pop[ ]+\{ra,s0-s3\},64 > +[ ]*[0-9a-f]+:[ ]+ba8e[ ]+cm.pop[ ]+\{ra,s0-s3\},96 > +[ ]*[0-9a-f]+:[ ]+bab2[ ]+cm.pop[ ]+\{ra,s0-s6\},64 > +[ ]*[0-9a-f]+:[ ]+bab6[ ]+cm.pop[ ]+\{ra,s0-s6\},80 > +[ ]*[0-9a-f]+:[ ]+babe[ ]+cm.pop[ ]+\{ra,s0-s6\},112 > +[ ]*[0-9a-f]+:[ ]+bac2[ ]+cm.pop[ ]+\{ra,s0-s7\},80 > +[ ]*[0-9a-f]+:[ ]+bac6[ ]+cm.pop[ ]+\{ra,s0-s7\},96 > +[ ]*[0-9a-f]+:[ ]+bace[ ]+cm.pop[ ]+\{ra,s0-s7\},128 > +[ ]*[0-9a-f]+:[ ]+bae2[ ]+cm.pop[ ]+\{ra,s0-s9\},96 > +[ ]*[0-9a-f]+:[ ]+bae6[ ]+cm.pop[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+baee[ ]+cm.pop[ ]+\{ra,s0-s9\},144 > +[ ]*[0-9a-f]+:[ ]+baf2[ ]+cm.pop[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+baf6[ ]+cm.pop[ ]+\{ra,s0-s11\},128 > +[ ]*[0-9a-f]+:[ ]+bafa[ ]+cm.pop[ ]+\{ra,s0-s11\},144 > +[ ]*[0-9a-f]+:[ ]+bafe[ ]+cm.pop[ ]+\{ra,s0-s11\},160 > +[ ]*[0-9a-f]+:[ ]+be4e[ ]+cm.popret[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+be5e[ ]+cm.popret[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+be6a[ ]+cm.popret[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+be7a[ ]+cm.popret[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+beda[ ]+cm.popret[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bee6[ ]+cm.popret[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+bef2[ ]+cm.popret[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+be4e[ ]+cm.popret[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+be5e[ ]+cm.popret[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+be6a[ ]+cm.popret[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+be7a[ ]+cm.popret[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+beda[ ]+cm.popret[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bee6[ ]+cm.popret[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+bef2[ ]+cm.popret[ ]+\{ra,s0-s11},112 > +[ ]*[0-9a-f]+:[ ]+be42[ ]+cm.popret[ ]+\{ra\},16 > +[ ]*[0-9a-f]+:[ ]+be46[ ]+cm.popret[ ]+\{ra\},32 > +[ ]*[0-9a-f]+:[ ]+be4e[ ]+cm.popret[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+be72[ ]+cm.popret[ ]+\{ra,s0-s2\},32 > +[ ]*[0-9a-f]+:[ ]+be7a[ ]+cm.popret[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+be7e[ ]+cm.popret[ ]+\{ra,s0-s2\},80 > +[ ]*[0-9a-f]+:[ ]+be82[ ]+cm.popret[ ]+\{ra,s0-s3\},48 > +[ ]*[0-9a-f]+:[ ]+be86[ ]+cm.popret[ ]+\{ra,s0-s3\},64 > +[ ]*[0-9a-f]+:[ ]+be8e[ ]+cm.popret[ ]+\{ra,s0-s3\},96 > +[ ]*[0-9a-f]+:[ ]+beb2[ ]+cm.popret[ ]+\{ra,s0-s6\},64 > +[ ]*[0-9a-f]+:[ ]+beb6[ ]+cm.popret[ ]+\{ra,s0-s6\},80 > +[ ]*[0-9a-f]+:[ ]+bebe[ ]+cm.popret[ ]+\{ra,s0-s6\},112 > +[ ]*[0-9a-f]+:[ ]+bec2[ ]+cm.popret[ ]+\{ra,s0-s7\},80 > +[ ]*[0-9a-f]+:[ ]+bec6[ ]+cm.popret[ ]+\{ra,s0-s7\},96 > +[ ]*[0-9a-f]+:[ ]+bece[ ]+cm.popret[ ]+\{ra,s0-s7\},128 > +[ ]*[0-9a-f]+:[ ]+bee2[ ]+cm.popret[ ]+\{ra,s0-s9\},96 > +[ ]*[0-9a-f]+:[ ]+bee6[ ]+cm.popret[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+beee[ ]+cm.popret[ ]+\{ra,s0-s9\},144 > +[ ]*[0-9a-f]+:[ ]+bef2[ ]+cm.popret[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+bef6[ ]+cm.popret[ ]+\{ra,s0-s11\},128 > +[ ]*[0-9a-f]+:[ ]+befa[ ]+cm.popret[ ]+\{ra,s0-s11\},144 > +[ ]*[0-9a-f]+:[ ]+befe[ ]+cm.popret[ ]+\{ra,s0-s11\},160 > +[ ]*[0-9a-f]+:[ ]+bc4e[ ]+cm.popretz[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+bc5e[ ]+cm.popretz[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+bc6a[ ]+cm.popretz[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+bc7a[ ]+cm.popretz[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+bcda[ ]+cm.popretz[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bce6[ ]+cm.popretz[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+bcf2[ ]+cm.popretz[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+bc4e[ ]+cm.popretz[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+bc5e[ ]+cm.popretz[ ]+\{ra,s0\},64 > +[ ]*[0-9a-f]+:[ ]+bc6a[ ]+cm.popretz[ ]+\{ra,s0-s1\},64 > +[ ]*[0-9a-f]+:[ ]+bc7a[ ]+cm.popretz[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+bcda[ ]+cm.popretz[ ]+\{ra,s0-s8\},112 > +[ ]*[0-9a-f]+:[ ]+bce6[ ]+cm.popretz[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+bcf2[ ]+cm.popretz[ ]+\{ra,s0-s11},112 > +[ ]*[0-9a-f]+:[ ]+bc42[ ]+cm.popretz[ ]+\{ra\},16 > +[ ]*[0-9a-f]+:[ ]+bc46[ ]+cm.popretz[ ]+\{ra\},32 > +[ ]*[0-9a-f]+:[ ]+bc4e[ ]+cm.popretz[ ]+\{ra\},64 > +[ ]*[0-9a-f]+:[ ]+bc72[ ]+cm.popretz[ ]+\{ra,s0-s2\},32 > +[ ]*[0-9a-f]+:[ ]+bc7a[ ]+cm.popretz[ ]+\{ra,s0-s2\},64 > +[ ]*[0-9a-f]+:[ ]+bc7e[ ]+cm.popretz[ ]+\{ra,s0-s2\},80 > +[ ]*[0-9a-f]+:[ ]+bc82[ ]+cm.popretz[ ]+\{ra,s0-s3\},48 > +[ ]*[0-9a-f]+:[ ]+bc86[ ]+cm.popretz[ ]+\{ra,s0-s3\},64 > +[ ]*[0-9a-f]+:[ ]+bc8e[ ]+cm.popretz[ ]+\{ra,s0-s3\},96 > +[ ]*[0-9a-f]+:[ ]+bcb2[ ]+cm.popretz[ ]+\{ra,s0-s6\},64 > +[ ]*[0-9a-f]+:[ ]+bcb6[ ]+cm.popretz[ ]+\{ra,s0-s6\},80 > +[ ]*[0-9a-f]+:[ ]+bcbe[ ]+cm.popretz[ ]+\{ra,s0-s6\},112 > +[ ]*[0-9a-f]+:[ ]+bcc2[ ]+cm.popretz[ ]+\{ra,s0-s7\},80 > +[ ]*[0-9a-f]+:[ ]+bcc6[ ]+cm.popretz[ ]+\{ra,s0-s7\},96 > +[ ]*[0-9a-f]+:[ ]+bcce[ ]+cm.popretz[ ]+\{ra,s0-s7\},128 > +[ ]*[0-9a-f]+:[ ]+bce2[ ]+cm.popretz[ ]+\{ra,s0-s9\},96 > +[ ]*[0-9a-f]+:[ ]+bce6[ ]+cm.popretz[ ]+\{ra,s0-s9\},112 > +[ ]*[0-9a-f]+:[ ]+bcee[ ]+cm.popretz[ ]+\{ra,s0-s9\},144 > +[ ]*[0-9a-f]+:[ ]+bcf2[ ]+cm.popretz[ ]+\{ra,s0-s11\},112 > +[ ]*[0-9a-f]+:[ ]+bcf6[ ]+cm.popretz[ ]+\{ra,s0-s11\},128 > +[ ]*[0-9a-f]+:[ ]+bcfa[ ]+cm.popretz[ ]+\{ra,s0-s11\},144 > +[ ]*[0-9a-f]+:[ ]+bcfe[ ]+cm.popretz[ ]+\{ra,s0-s11\},160 > diff --git a/gas/testsuite/gas/riscv/zcmp-push-pop.s b/gas/testsuite/gas/riscv/zcmp-push-pop.s > new file mode 100644 > index 00000000000..bec40ebbcbc > --- /dev/null > +++ b/gas/testsuite/gas/riscv/zcmp-push-pop.s > @@ -0,0 +1,197 @@ > +target: > + > + # push > + # abi names > + cm.push {ra}, -64 > + cm.push {ra, s0}, -64 > + cm.push {ra, s0-s1}, -64 > + cm.push {ra, s0-s2}, -64 > + cm.push {ra, s0-s8}, -112 > + cm.push {ra, s0-s9}, -112 > + cm.push {ra, s0-s11}, -112 > + > + # numeric names > + cm.push {x1}, -64 > + cm.push {x1, x8}, -64 > + cm.push {x1, x8-x9}, -64 > + cm.push {x1, x8-x9, x18}, -64 > + cm.push {x1, x8-x9, x18-x24}, -112 > + cm.push {x1, x8-x9, x18-x25}, -112 > + cm.push {x1, x8-x9, x18-x27}, -112 > + > + # spimm > + cm.push {ra}, -16 > + cm.push {ra}, -32 > + cm.push {ra}, -64 > + > + cm.push {ra, s0-s2}, -32 > + cm.push {ra, s0-s2}, -64 > + cm.push {ra, s0-s2}, -80 > + > + cm.push {ra, s0-s3}, -48 > + cm.push {ra, s0-s3}, -64 > + cm.push {ra, s0-s3}, -96 > + > + cm.push {ra, s0-s6}, -64 > + cm.push {ra, s0-s6}, -80 > + cm.push {ra, s0-s6}, -112 > + > + cm.push {ra, s0-s7}, -80 > + cm.push {ra, s0-s7}, -96 > + cm.push {ra, s0-s7}, -128 > + > + cm.push {ra, s0-s9}, -96 > + cm.push {ra, s0-s9}, -112 > + cm.push {ra, s0-s9}, -144 > + > + cm.push {ra, s0-s11}, -112 > + cm.push {ra, s0-s11}, -128 > + cm.push {ra, s0-s11}, -144 > + cm.push {ra, s0-s11}, -160 > + > + # pop > + # abi names > + cm.pop {ra}, 64 > + cm.pop {ra, s0}, 64 > + cm.pop {ra, s0-s1}, 64 > + cm.pop {ra, s0-s2}, 64 > + cm.pop {ra, s0-s8}, 112 > + cm.pop {ra, s0-s9}, 112 > + cm.pop {ra, s0-s11}, 112 > + > + # numeric names > + cm.pop {x1}, 64 > + cm.pop {x1, x8}, 64 > + cm.pop {x1, x8-x9}, 64 > + cm.pop {x1, x8-x9, x18}, 64 > + cm.pop {x1, x8-x9, x18-x24}, 112 > + cm.pop {x1, x8-x9, x18-x25}, 112 > + cm.pop {x1, x8-x9, x18-x27}, 112 > + > + # spimm > + cm.pop {ra}, 16 > + cm.pop {ra}, 32 > + cm.pop {ra}, 64 > + > + cm.pop {ra, s0-s2}, 32 > + cm.pop {ra, s0-s2}, 64 > + cm.pop {ra, s0-s2}, 80 > + > + cm.pop {ra, s0-s3}, 48 > + cm.pop {ra, s0-s3}, 64 > + cm.pop {ra, s0-s3}, 96 > + > + cm.pop {ra, s0-s6}, 64 > + cm.pop {ra, s0-s6}, 80 > + cm.pop {ra, s0-s6}, 112 > + > + cm.pop {ra, s0-s7}, 80 > + cm.pop {ra, s0-s7}, 96 > + cm.pop {ra, s0-s7}, 128 > + > + cm.pop {ra, s0-s9}, 96 > + cm.pop {ra, s0-s9}, 112 > + cm.pop {ra, s0-s9}, 144 > + > + cm.pop {ra, s0-s11}, 112 > + cm.pop {ra, s0-s11}, 128 > + cm.pop {ra, s0-s11}, 144 > + cm.pop {ra, s0-s11}, 160 > + > + # popret > + # abi names > + cm.popret {ra}, 64 > + cm.popret {ra, s0}, 64 > + cm.popret {ra, s0-s1}, 64 > + cm.popret {ra, s0-s2}, 64 > + cm.popret {ra, s0-s8}, 112 > + cm.popret {ra, s0-s9}, 112 > + cm.popret {ra, s0-s11}, 112 > + > + # numeric names > + cm.popret {x1}, 64 > + cm.popret {x1, x8}, 64 > + cm.popret {x1, x8-x9}, 64 > + cm.popret {x1, x8-x9, x18}, 64 > + cm.popret {x1, x8-x9, x18-x24}, 112 > + cm.popret {x1, x8-x9, x18-x25}, 112 > + cm.popret {x1, x8-x9, x18-x27}, 112 > + > + # spimm > + cm.popret {ra}, 16 > + cm.popret {ra}, 32 > + cm.popret {ra}, 64 > + > + cm.popret {ra, s0-s2}, 32 > + cm.popret {ra, s0-s2}, 64 > + cm.popret {ra, s0-s2}, 80 > + > + cm.popret {ra, s0-s3}, 48 > + cm.popret {ra, s0-s3}, 64 > + cm.popret {ra, s0-s3}, 96 > + > + cm.popret {ra, s0-s6}, 64 > + cm.popret {ra, s0-s6}, 80 > + cm.popret {ra, s0-s6}, 112 > + > + cm.popret {ra, s0-s7}, 80 > + cm.popret {ra, s0-s7}, 96 > + cm.popret {ra, s0-s7}, 128 > + > + cm.popret {ra, s0-s9}, 96 > + cm.popret {ra, s0-s9}, 112 > + cm.popret {ra, s0-s9}, 144 > + > + cm.popret {ra, s0-s11}, 112 > + cm.popret {ra, s0-s11}, 128 > + cm.popret {ra, s0-s11}, 144 > + cm.popret {ra, s0-s11}, 160 > + > + # popretz > + # abi names > + cm.popretz {ra}, 64 > + cm.popretz {ra, s0}, 64 > + cm.popretz {ra, s0-s1}, 64 > + cm.popretz {ra, s0-s2}, 64 > + cm.popretz {ra, s0-s8}, 112 > + cm.popretz {ra, s0-s9}, 112 > + cm.popretz {ra, s0-s11}, 112 > + > + # numeric names > + cm.popretz {x1}, 64 > + cm.popretz {x1, x8}, 64 > + cm.popretz {x1, x8-x9}, 64 > + cm.popretz {x1, x8-x9, x18}, 64 > + cm.popretz {x1, x8-x9, x18-x24}, 112 > + cm.popretz {x1, x8-x9, x18-x25}, 112 > + cm.popretz {x1, x8-x9, x18-x27}, 112 > + > + # spimm > + cm.popretz {ra}, 16 > + cm.popretz {ra}, 32 > + cm.popretz {ra}, 64 > + > + cm.popretz {ra, s0-s2}, 32 > + cm.popretz {ra, s0-s2}, 64 > + cm.popretz {ra, s0-s2}, 80 > + > + cm.popretz {ra, s0-s3}, 48 > + cm.popretz {ra, s0-s3}, 64 > + cm.popretz {ra, s0-s3}, 96 > + > + cm.popretz {ra, s0-s6}, 64 > + cm.popretz {ra, s0-s6}, 80 > + cm.popretz {ra, s0-s6}, 112 > + > + cm.popretz {ra, s0-s7}, 80 > + cm.popretz {ra, s0-s7}, 96 > + cm.popretz {ra, s0-s7}, 128 > + > + cm.popretz {ra, s0-s9}, 96 > + cm.popretz {ra, s0-s9}, 112 > + cm.popretz {ra, s0-s9}, 144 > + > + cm.popretz {ra, s0-s11}, 112 > + cm.popretz {ra, s0-s11}, 128 > + cm.popretz {ra, s0-s11}, 144 > + cm.popretz {ra, s0-s11}, 160 > diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h > index 53f5f200508..e2724dde3bf 100644 > --- a/include/opcode/riscv-opc.h > +++ b/include/opcode/riscv-opc.h > @@ -2235,6 +2235,15 @@ > #define MASK_C_NOT 0xfc7f > #define MATCH_C_MUL 0x9c41 > #define MASK_C_MUL 0xfc63 > +/* ZCMP instructions. */ "Zcmp" is preferred. > +#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 > diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h > index 808f3657303..024b1e9f2bc 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) > > #define ENCODE_ITYPE_IMM(x) \ > (RV_X(x, 0, 12) << 20) > @@ -163,6 +165,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) > > #define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x)) > #define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x)) > @@ -190,6 +194,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)) > @@ -254,6 +259,8 @@ static inline unsigned int riscv_insn_length (insn_t insn) > #define OP_SH_AQ 26 > #define OP_MASK_RL 0x1 > #define OP_SH_RL 25 > +#define OP_MASK_RLIST 0xf > +#define OP_SH_RLIST 4 > > #define OP_MASK_CSR 0xfffU > #define OP_SH_CSR 20 > @@ -330,6 +337,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 > @@ -435,6 +447,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, > diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c > index 2826248f8af..d938c9cb2ed 100644 > --- a/opcodes/riscv-dis.c > +++ b/opcodes/riscv-dis.c > @@ -75,6 +75,8 @@ static const char * const *riscv_fpr_names; > /* If set, disassemble as most general instruction. */ > static bool no_aliases = false; > > +/* If set, disassemble numeric register names instead of ABI names. */ > +static int numeric = 0; Use boolean variable and use "true" and "false" instead of "1" and "0". > > /* Set default RISC-V disassembler options. */ > > @@ -84,6 +86,7 @@ set_default_riscv_dis_options (void) > riscv_gpr_names = riscv_gpr_names_abi; > riscv_fpr_names = riscv_fpr_names_abi; > no_aliases = false; > + numeric = 0; > } > > /* Parse RISC-V disassembler option (without arguments). */ > @@ -97,6 +100,7 @@ parse_riscv_dis_option_without_args (const char *option) > { > riscv_gpr_names = riscv_gpr_names_numeric; > riscv_fpr_names = riscv_fpr_names_numeric; > + numeric = 1; > } > else > return false; > @@ -215,6 +219,50 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset, > pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr; > } > > +/* Get ZCMP rlist field. */ "Zcmp" is preferred. > + > +static void > +print_rlist (disassemble_info *info, insn_t l) > +{ > + unsigned rlist = (int)EXTRACT_OPERAND (RLIST, l); > + unsigned r_start = numeric ? X_S2 : X_S0; > + info->fprintf_func (info->stream, "%s", riscv_gpr_names[X_RA]); > + > + if (rlist == 5) > + info->fprintf_func (info->stream, ",%s", riscv_gpr_names[X_S0]); > + else if (rlist == 6 || (numeric && rlist > 6)) > + info->fprintf_func (info->stream, ",%s-%s", > + riscv_gpr_names[X_S0], > + riscv_gpr_names[X_S1]); > + > + if (rlist == 15) > + info->fprintf_func (info->stream, ",%s-%s", > + riscv_gpr_names[r_start], > + riscv_gpr_names[X_S11]); > + else if (rlist == 7 && numeric) > + info->fprintf_func (info->stream, ",%s", > + riscv_gpr_names[X_S2]); > + else if (rlist > 6) > + info->fprintf_func (info->stream, ",%s-%s", > + riscv_gpr_names[r_start], > + riscv_gpr_names[rlist + 11]); > +} > + > +/* Get ZCMP sp adjustment immediate. */ "Zcmp" is preferred. > + > +static int > +riscv_get_spimm (insn_t l) Is this *that* generic? I will prefer riscv_cm_pushpop_get_spimm or some. > +{ > + int spimm = riscv_get_sp_base(l, &riscv_rps_dis); > + > + spimm += EXTRACT_ZCMP_SPIMM (l); > + > + if (((l ^ MATCH_CM_PUSH) & MASK_CM_PUSH) == 0) > + spimm *= -1; > + > + return spimm; > +} > + > /* Print insn arguments for 32/64-bit code. */ > > static void > @@ -420,6 +468,8 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info > case ')': > case '[': > case ']': > + case '{': > + case '}': > print (info->stream, dis_style_text, "%c", *oparg); > break; > > @@ -625,6 +675,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info > print (info->stream, dis_style_immediate, "%d", > (int)EXTRACT_ZCB_HALFWORD_UIMM (l)); > break; > + case 'r': > + print_rlist (info, l); > + break; > + case 'p': > + print (info->stream, dis_style_immediate, "%d", > + riscv_get_spimm (l)); Indentation: 3 tabs and 3 spaces before "riscv_get_spimm". > + break; > default: break; > } > break; > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c > index 6a854736fec..7d2f92e736b 100644 > --- a/opcodes/riscv-opc.c > +++ b/opcodes/riscv-opc.c > @@ -1967,6 +1967,12 @@ const struct riscv_opcode riscv_opcodes[] = > {"c.zext.b", 0, INSN_CLASS_ZCB, "Cs", MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, 0 }, > {"c.sext.w", 64, INSN_CLASS_ZCB, "d", MATCH_C_ADDIW, MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS }, > > +/* Zcmp instructions. */ > +{"cm.push", 0, INSN_CLASS_ZCMP, "{Wcr},Wcp", MATCH_CM_PUSH, MASK_CM_PUSH, match_opcode, 0 }, > +{"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 }, > + > /* Supervisor instructions. */ > {"csrr", 0, INSN_CLASS_ZICSR, "d,E", MATCH_CSRRS, MASK_CSRRS|MASK_RS1, match_opcode, INSN_ALIAS }, > {"csrw", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRW, MASK_CSRRW|MASK_RD, match_opcode, INSN_ALIAS },