public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Fei Gao <gaofei@eswincomputing.com>
To: gcc-patches@gcc.gnu.org
Cc: kito.cheng@gmail.com, palmer@dabbelt.com, jeffreyalaw@gmail.com,
	sinan.lin@linux.alibaba.com, jiawei@iscas.ac.cn,
	Fei Gao <gaofei@eswincomputing.com>
Subject: [PATCH 2/4] [RISC-V] support cm.popretz in zcmp
Date: Wed,  7 Jun 2023 05:52:13 +0000	[thread overview]
Message-ID: <20230607055215.29332-3-gaofei@eswincomputing.com> (raw)
In-Reply-To: <20230607055215.29332-1-gaofei@eswincomputing.com>

Generate cm.popretz instead of cm.popret if return value is 0.

Signed-off-by: Fei Gao <gaofei@eswincomputing.com>

gcc/ChangeLog:

        * config/riscv/riscv.cc
        (riscv_zcmp_can_use_popretz): true if popretz can be used
        (riscv_gen_multi_pop_insn): interface to generate cm.pop[ret][z]
        (riscv_expand_epilogue): expand cm.pop[ret][z] in epilogue
        * config/riscv/riscv.md:
        * config/riscv/zc.md
        (@gpr_multi_popretz_up_to_ra_<mode>): md for popretz ra
        (@gpr_multi_popretz_up_to_s0_<mode>): md for popretz ra, s0
        (@gpr_multi_popretz_up_to_s1_<mode>): likewise
        (@gpr_multi_popretz_up_to_s2_<mode>): likewise
        (@gpr_multi_popretz_up_to_s3_<mode>): likewise
        (@gpr_multi_popretz_up_to_s4_<mode>): likewise
        (@gpr_multi_popretz_up_to_s5_<mode>): likewise
        (@gpr_multi_popretz_up_to_s6_<mode>): likewise
        (@gpr_multi_popretz_up_to_s7_<mode>): likewise
        (@gpr_multi_popretz_up_to_s8_<mode>): likewise
        (@gpr_multi_popretz_up_to_s9_<mode>): likewise
        (@gpr_multi_popretz_up_to_s11_<mode>): likewise

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rv32e_zcmp.c: add testcase for cm.popretz in rv32e
        * gcc.target/riscv/rv32i_zcmp.c: add testcase for cm.popretz in rv32i
---
 gcc/config/riscv/riscv.cc                   | 114 ++++--
 gcc/config/riscv/riscv.md                   |   1 +
 gcc/config/riscv/zc.md                      | 393 ++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c |  12 +
 gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c |  12 +
 5 files changed, 508 insertions(+), 24 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index c476c699f4c..f60c241a526 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -435,6 +435,7 @@ typedef enum
   PUSH_IDX = 0,
   POP_IDX,
   POPRET_IDX,
+  POPRETZ_IDX,
   ZCMP_OP_NUM
 } riscv_zcmp_op_t;
 
@@ -5535,30 +5536,30 @@ riscv_emit_stack_tie (void)
 /*zcmp multi push and pop code_for_push_pop function ptr array  */
 const code_for_push_pop_t code_for_push_pop [ZCMP_MAX_GRP_SLOTS][ZCMP_OP_NUM] = {
   {code_for_gpr_multi_push_up_to_ra,    code_for_gpr_multi_pop_up_to_ra,
-   code_for_gpr_multi_popret_up_to_ra},
+   code_for_gpr_multi_popret_up_to_ra,  code_for_gpr_multi_popretz_up_to_ra},
   {code_for_gpr_multi_push_up_to_s0,    code_for_gpr_multi_pop_up_to_s0,
-   code_for_gpr_multi_popret_up_to_s0},
+   code_for_gpr_multi_popret_up_to_s0,  code_for_gpr_multi_popretz_up_to_s0},
   {code_for_gpr_multi_push_up_to_s1,    code_for_gpr_multi_pop_up_to_s1,
-   code_for_gpr_multi_popret_up_to_s1},
+   code_for_gpr_multi_popret_up_to_s1,  code_for_gpr_multi_popretz_up_to_s1},
   {code_for_gpr_multi_push_up_to_s2,    code_for_gpr_multi_pop_up_to_s2,
-   code_for_gpr_multi_popret_up_to_s2},
+   code_for_gpr_multi_popret_up_to_s2,  code_for_gpr_multi_popretz_up_to_s2},
   {code_for_gpr_multi_push_up_to_s3,    code_for_gpr_multi_pop_up_to_s3,
-   code_for_gpr_multi_popret_up_to_s3},
+   code_for_gpr_multi_popret_up_to_s3,  code_for_gpr_multi_popretz_up_to_s3},
   {code_for_gpr_multi_push_up_to_s4,    code_for_gpr_multi_pop_up_to_s4,
-   code_for_gpr_multi_popret_up_to_s4},
+   code_for_gpr_multi_popret_up_to_s4,  code_for_gpr_multi_popretz_up_to_s4},
   {code_for_gpr_multi_push_up_to_s5,    code_for_gpr_multi_pop_up_to_s5,
-   code_for_gpr_multi_popret_up_to_s5},
+   code_for_gpr_multi_popret_up_to_s5,  code_for_gpr_multi_popretz_up_to_s5},
   {code_for_gpr_multi_push_up_to_s6,    code_for_gpr_multi_pop_up_to_s6,
-   code_for_gpr_multi_popret_up_to_s6},
+   code_for_gpr_multi_popret_up_to_s6,  code_for_gpr_multi_popretz_up_to_s6},
   {code_for_gpr_multi_push_up_to_s7,    code_for_gpr_multi_pop_up_to_s7,
-   code_for_gpr_multi_popret_up_to_s7},
+   code_for_gpr_multi_popret_up_to_s7,  code_for_gpr_multi_popretz_up_to_s7},
   {code_for_gpr_multi_push_up_to_s8,    code_for_gpr_multi_pop_up_to_s8,
-   code_for_gpr_multi_popret_up_to_s8},
+   code_for_gpr_multi_popret_up_to_s8,  code_for_gpr_multi_popretz_up_to_s8},
   {code_for_gpr_multi_push_up_to_s9,    code_for_gpr_multi_pop_up_to_s9,
-   code_for_gpr_multi_popret_up_to_s9},
-  {nullptr, nullptr, nullptr},
+   code_for_gpr_multi_popret_up_to_s9,  code_for_gpr_multi_popretz_up_to_s9},
+  {nullptr, nullptr, nullptr, nullptr},
   {code_for_gpr_multi_push_up_to_s11,   code_for_gpr_multi_pop_up_to_s11,
-   code_for_gpr_multi_popret_up_to_s11}};
+   code_for_gpr_multi_popret_up_to_s11, code_for_gpr_multi_popretz_up_to_s11}};
 
 static rtx
 riscv_gen_multi_push_pop_insn (riscv_zcmp_op_t op, HOST_WIDE_INT adj_size,
@@ -5747,6 +5748,80 @@ riscv_adjust_libcall_cfi_epilogue ()
   return dwarf;
 }
 
+/* return true if popretz pattern can be matched.
+   set (reg 10 a0) (const_int 0)
+   use (reg 10 a0)
+   NOTE_INSN_EPILOGUE_BEG  */
+static rtx_insn *
+riscv_zcmp_can_use_popretz(void)
+{
+  rtx_insn *insn = NULL, *use = NULL, *clear = NULL;
+
+  /* sequence stack for NOTE_INSN_EPILOGUE_BEG*/
+  struct sequence_stack * outer_seq = get_current_sequence ()->next;
+  if (!outer_seq)
+    return NULL;
+  insn = outer_seq->first;
+  if(!insn || !NOTE_P (insn) || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG)
+    return NULL;
+
+  /* sequence stack for the insn before NOTE_INSN_EPILOGUE_BEG*/
+  outer_seq = outer_seq->next;
+  if (outer_seq)
+    insn = outer_seq->last;
+
+  /* skip notes  */
+  while (insn && NOTE_P (insn))
+    {
+      insn = PREV_INSN (insn);
+    }
+  use = insn;
+
+  /* match use (reg 10 a0)  */
+  if (use == NULL || !INSN_P (use)
+      || GET_CODE (PATTERN (use)) != USE
+      || !REG_P(XEXP(PATTERN (use), 0))
+      || REGNO(XEXP(PATTERN (use), 0)) != A0_REGNUM)
+    return NULL;
+
+  /* match set (reg 10 a0) (const_int 0 [0])  */
+  clear = PREV_INSN (use);
+  if (clear != NULL && INSN_P (clear)
+      && GET_CODE (PATTERN (clear)) == SET
+      && REG_P (SET_DEST (PATTERN (clear)))
+      && REGNO (SET_DEST (PATTERN (clear))) == A0_REGNUM
+      && SET_SRC (PATTERN (clear)) == const0_rtx)
+    return clear;
+
+  return NULL;
+}
+
+static void
+riscv_gen_multi_pop_insn(bool use_multi_pop_normal, unsigned mask,
+                         unsigned multipop_size)
+{
+  rtx insn;
+  unsigned regs_count = riscv_multi_push_regs_count (mask);
+
+  if (!use_multi_pop_normal)
+    insn= emit_insn (
+      riscv_gen_multi_push_pop_insn(POP_IDX, multipop_size, regs_count));
+  else if(rtx_insn * clear_a0_insn = riscv_zcmp_can_use_popretz())
+    {
+      delete_insn (NEXT_INSN (clear_a0_insn));
+      delete_insn (clear_a0_insn);
+      insn = emit_jump_insn (
+        riscv_gen_multi_push_pop_insn (POPRETZ_IDX, multipop_size, regs_count));
+    }
+  else
+    insn = emit_jump_insn (
+      riscv_gen_multi_push_pop_insn (POPRET_IDX, multipop_size, regs_count));
+
+  rtx dwarf = riscv_adjust_multi_pop_cfi_epilogue (multipop_size);
+  RTX_FRAME_RELATED_P (insn) = 1;
+  REG_NOTES (insn) = dwarf;
+}
+
 /* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
    style says which.  */
 
@@ -5943,17 +6018,8 @@ riscv_expand_epilogue (int style)
 
   if (use_multi_pop)
     {
-      unsigned regs_count = riscv_multi_push_regs_count (frame->mask);
-      if (use_multi_pop_normal)
-        insn = emit_jump_insn (
-          riscv_gen_multi_push_pop_insn (POPRET_IDX, multipop_size, regs_count));
-      else
-        insn= emit_insn (
-          riscv_gen_multi_push_pop_insn(POP_IDX, multipop_size, regs_count));
-
-      rtx dwarf = riscv_adjust_multi_pop_cfi_epilogue (multipop_size);
-      RTX_FRAME_RELATED_P (insn) = 1;
-      REG_NOTES (insn) = dwarf;
+      riscv_gen_multi_pop_insn(use_multi_pop_normal,
+                               frame->mask, multipop_size);
       if (use_multi_pop_normal)
         return;
     }
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index c858b3bc9ef..b2e1f82f627 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -120,6 +120,7 @@
    (T1_REGNUM			6)
    (S0_REGNUM			8)
    (S1_REGNUM			9)
+   (A0_REGNUM			10)
    (S2_REGNUM			18)
    (S3_REGNUM			19)
    (S4_REGNUM			20)
diff --git a/gcc/config/riscv/zc.md b/gcc/config/riscv/zc.md
index 5c1bf031b8d..8d7de97daad 100644
--- a/gcc/config/riscv/zc.md
+++ b/gcc/config/riscv/zc.md
@@ -708,6 +708,399 @@
   "cm.popret	{ra, s0-s11}, %0"
 )
 
+(define_insn "@gpr_multi_popretz_up_to_ra_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_ra_operand" "I")))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s0_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s0_operand" "I")))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s1_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s1_operand" "I")))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s1}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s2_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s2_operand" "I")))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s2}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s3_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s3_operand" "I")))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s3}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s4_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s4_operand" "I")))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s4}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s5_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s5_operand" "I")))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s5}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s6_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s6_operand" "I")))
+   (set (reg:X S6_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot7_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s6}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s7_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s7_operand" "I")))
+   (set (reg:X S7_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S6_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot7_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot8_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s7}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s8_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s8_operand" "I")))
+   (set (reg:X S8_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S7_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S6_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot7_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot8_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot9_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s8}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s9_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s9_operand" "I")))
+   (set (reg:X S9_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S8_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S7_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S6_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot7_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot8_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot9_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot10_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s9}, %0"
+)
+
+(define_insn "@gpr_multi_popretz_up_to_s11_<mode>"
+  [(set (reg:X SP_REGNUM)
+        (plus:X (reg:X SP_REGNUM)
+                 (match_operand 0 "stack_pop_up_to_s11_operand" "I")))
+   (set (reg:X S11_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot0_offset>))))
+   (set (reg:X S10_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot1_offset>))))
+   (set (reg:X S9_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot2_offset>))))
+   (set (reg:X S8_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot3_offset>))))
+   (set (reg:X S7_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot4_offset>))))
+   (set (reg:X S6_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot5_offset>))))
+   (set (reg:X S5_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot6_offset>))))
+   (set (reg:X S4_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot7_offset>))))
+   (set (reg:X S3_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                      (const_int <slot8_offset>))))
+   (set (reg:X S2_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot9_offset>))))
+   (set (reg:X S1_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot10_offset>))))
+   (set (reg:X S0_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot11_offset>))))
+   (set (reg:X RETURN_ADDR_REGNUM)
+        (mem:X (plus:X (reg:X SP_REGNUM)
+                       (const_int <slot12_offset>))))
+   (set (reg:X A0_REGNUM)
+        (const_int 0))
+   (use (reg:X A0_REGNUM))
+   (return)
+   (use (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_ZCMP"
+  "cm.popretz	{ra, s0-s11}, %0"
+)
+
 (define_insn "@gpr_multi_push_up_to_ra_<mode>"
   [(set (mem:X (plus:X (reg:X SP_REGNUM)
                        (const_int <slot0_offset>)))
diff --git a/gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c b/gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c
index 6dbe489da9b..05e52df99c2 100644
--- a/gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c
+++ b/gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c
@@ -237,3 +237,15 @@ void foo(void)
   f1();
   f2();
 }
+
+/*
+**test_popretz:
+**	cm.push	{ra}, -16
+**	call	f1
+**	cm.popretz	{ra}, 16
+*/
+long test_popretz()
+{
+        f1();
+        return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c b/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
index 924197cb3c4..7d5c1121c35 100644
--- a/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
+++ b/gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
@@ -237,3 +237,15 @@ void foo(void)
   f1();
   f2();
 }
+
+/*
+**test_popretz:
+**	cm.push	{ra}, -16
+**	call	f1
+**	cm.popretz	{ra}, 16
+*/
+long test_popretz()
+{
+        f1();
+        return 0;
+}
-- 
2.17.1


  parent reply	other threads:[~2023-06-07  5:52 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-07  5:52 [PATCH 0/4] [RISC-V] support zcmp extention Fei Gao
2023-06-07  5:52 ` [PATCH 1/4][V4][RISC-V] support cm.push cm.pop cm.popret in zcmp Fei Gao
2023-06-07 10:11   ` jiawei
2023-08-16  8:33   ` Kito Cheng
2023-08-16  8:38     ` Kito Cheng
2023-08-16  9:03       ` Fei Gao
2023-08-20 10:53       ` Fei Gao
2023-08-28  8:04         ` Fei Gao
2023-08-17 11:39     ` Fei Gao
2023-06-07  5:52 ` Fei Gao [this message]
2023-07-13  8:31   ` [PATCH 2/4] [RISC-V] support cm.popretz " Kito Cheng
2023-06-07  5:52 ` [PATCH 3/4] [RISC-V] resolve confilct between zcmp multi push/pop and shrink-wrap-separate Fei Gao
2023-06-12 15:17   ` Kito Cheng
2023-06-12 19:26   ` Jeff Law
2023-06-13  2:35     ` Fei Gao
2023-06-07  5:52 ` [PATCH 4/4] [RISC-V] support cm.mva01s cm.mvsa01 in zcmp Fei Gao
2023-07-13  8:18   ` Kito Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230607055215.29332-3-gaofei@eswincomputing.com \
    --to=gaofei@eswincomputing.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=jiawei@iscas.ac.cn \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=sinan.lin@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).