public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed
@ 2023-08-07  7:31 Lehua Ding
  0 siblings, 0 replies; 3+ messages in thread
From: Lehua Ding @ 2023-08-07  7:31 UTC (permalink / raw)
  To: Kito Cheng; +Cc: gcc-patches, juzhe.zhong, rdapp.gcc, palmer, jeffreyalaw

[-- Attachment #1: Type: text/plain, Size: 1109 bytes --]

Hi Kito,

> > +machine_mode m1_mode = TARGET_VECTOR_ELEN_64
> > +? (TARGET_MIN_VLEN >= 128 ? VNx2DImode : VNx1DImode) 
> > +: VNx1SImode;

> This should update since JuZhe has update the mode system :P

Yes, thanks reminder.

> > @@ -5907,7 +6057,7 @@ riscv_expand_epilogue (int style) 
> > Start off by assuming that no registers need to be restored.*/ 
> >struct riscv_frame_info *frame = &cfun->machine->frame; 
> >unsigned mask = frame->mask; 
> > -HOST_WIDE_INT step2 = 0; 
> > +poly_int64 step2 = 0; 

> I saw we check `step2.to_constant () 
> 0` later, does it mean step2 is 
> always a scalar rather than a poly number? 
> If so, I would suggest keeping HOST_WIDE_INT if possible.
step2 will be reduced by `riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);`
before `step2.to_constant () > 0`. After `riscv_for_each_saved_v_reg`,
the step2 must be a constant. So step2 may be a poly number if there are any
length agnostic vector registers that need to be saved.

Best,
Lehua

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed
  2023-07-20  9:01 ` [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed Lehua Ding
@ 2023-08-07  6:53   ` Kito Cheng
  0 siblings, 0 replies; 3+ messages in thread
From: Kito Cheng @ 2023-08-07  6:53 UTC (permalink / raw)
  To: Lehua Ding; +Cc: gcc-patches, juzhe.zhong, rdapp.gcc, palmer, jeffreyalaw

> +  machine_mode m1_mode = TARGET_VECTOR_ELEN_64
> +                          ? (TARGET_MIN_VLEN >= 128 ? VNx2DImode : VNx1DImode)
> +                          : VNx1SImode;

This should update since JuZhe has update the mode system :P

> @@ -5907,7 +6057,7 @@ riscv_expand_epilogue (int style)
>       Start off by assuming that no registers need to be restored.  */
>    struct riscv_frame_info *frame = &cfun->machine->frame;
>    unsigned mask = frame->mask;
> -  HOST_WIDE_INT step2 = 0;
> +  poly_int64 step2 = 0;

I saw we check `step2.to_constant () > 0` later, does it mean step2 is
always a scalar rather than a poly number?
If so, I would suggest keeping HOST_WIDE_INT if possible.


> @@ -6058,10 +6218,10 @@ riscv_expand_epilogue (int style)
>      riscv_emit_stack_tie ();
>
>    /* Deallocate the final bit of the frame.  */
> -  if (step2 > 0)
> +  if (step2.to_constant () > 0)
>      {
>        insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
> -                                      GEN_INT (step2)));
> +                                      GEN_INT (step2.to_constant ())));
>
>        rtx dwarf = NULL_RTX;
>        rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed
  2023-07-20  9:01 [PATCH 0/3] RISC-V: Add an experimental vector calling convention Lehua Ding
@ 2023-07-20  9:01 ` Lehua Ding
  2023-08-07  6:53   ` Kito Cheng
  0 siblings, 1 reply; 3+ messages in thread
From: Lehua Ding @ 2023-07-20  9:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, rdapp.gcc, kito.cheng, palmer, jeffreyalaw

Because functions which follow vector calling convention variant has
callee-saved vector reigsters but functions which follow standard calling
convention don't have. We need to distinguish which function callee is so that
we can tell GCC exactly which vector registers callee will clobber. So I encode
the callee's calling convention information into the calls rtx pattern like
AArch64. The old operand 2 and 3 of call pattern which copy from MIPS target are
useless and removed according to my analysis.

gcc/ChangeLog:

	* config/riscv/riscv-sr.cc (riscv_remove_unneeded_save_restore_calls): Pass riscv_cc.
	* config/riscv/riscv.cc (struct riscv_frame_info): Add new fileds.
	(riscv_frame_info::reset): Reset new fileds.
	(riscv_call_tls_get_addr): Pass riscv_cc.
	(riscv_function_arg): Return riscv_cc for call patterm.
	(riscv_insn_callee_abi): Implement TARGET_INSN_CALLEE_ABI.
	(riscv_save_reg_p): Add vector callee-saved check.
	(riscv_save_libcall_count): Add vector save area.
	(riscv_compute_frame_info): Ditto.
	(riscv_restore_reg): Update for type change.
	(riscv_for_each_saved_v_reg): New function save vector registers.
	(riscv_first_stack_step): Handle funciton with vector callee-saved registers.
	(riscv_expand_prologue): Ditto.
	(riscv_expand_epilogue): Ditto.
	(riscv_output_mi_thunk): Pass riscv_cc.
	(TARGET_INSN_CALLEE_ABI): Implement TARGET_INSN_CALLEE_ABI.
	* config/riscv/riscv.md: Add CALLEE_CC operand for call pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c: New test.
	* gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c: New test.
	* gcc.target/riscv/rvv/base/abi-callee-saved-1.c: New test.
	* gcc.target/riscv/rvv/base/abi-callee-saved-2.c: New test.

---
 gcc/config/riscv/riscv-sr.cc                  |  12 +-
 gcc/config/riscv/riscv.cc                     | 222 +++++++++++++++---
 gcc/config/riscv/riscv.md                     |  43 +++-
 .../rvv/base/abi-callee-saved-1-fixed-1.c     |  85 +++++++
 .../rvv/base/abi-callee-saved-1-fixed-2.c     |  85 +++++++
 .../riscv/rvv/base/abi-callee-saved-1.c       |  87 +++++++
 .../riscv/rvv/base/abi-callee-saved-2.c       | 117 +++++++++
 7 files changed, 606 insertions(+), 45 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c

diff --git a/gcc/config/riscv/riscv-sr.cc b/gcc/config/riscv/riscv-sr.cc
index 7248f04d68f..e6e17685df5 100644
--- a/gcc/config/riscv/riscv-sr.cc
+++ b/gcc/config/riscv/riscv-sr.cc
@@ -447,12 +447,18 @@ riscv_remove_unneeded_save_restore_calls (void)
       && !SIBCALL_REG_P (REGNO (target)))
     return;
 
+  /* Extract RISCV CC from the UNSPEC rtx.  */
+  rtx unspec = XVECEXP (callpat, 0, 1);
+  gcc_assert (GET_CODE (unspec) == UNSPEC
+	      && XINT (unspec, 1) == UNSPEC_CALLEE_CC);
+  riscv_cc cc = (riscv_cc) INTVAL (XVECEXP (unspec, 0, 0));
   rtx sibcall = NULL;
   if (set_target != NULL)
-    sibcall
-      = gen_sibcall_value_internal (set_target, target, const0_rtx);
+    sibcall = gen_sibcall_value_internal (set_target, target, const0_rtx,
+					  gen_int_mode (cc, SImode));
   else
-    sibcall = gen_sibcall_internal (target, const0_rtx);
+    sibcall
+      = gen_sibcall_internal (target, const0_rtx, gen_int_mode (cc, SImode));
 
   rtx_insn *before_call = PREV_INSN (call);
   remove_insn (call);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 73e9f2001e6..1ca3ed42d40 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -101,6 +101,9 @@ struct GTY(())  riscv_frame_info {
   /* Likewise FPR X.  */
   unsigned int fmask;
 
+  /* Likewise for vector registers.  */
+  unsigned int vmask;
+
   /* How much the GPR save/restore routines adjust sp (or 0 if unused).  */
   unsigned save_libcall_adjustment;
 
@@ -108,6 +111,10 @@ struct GTY(())  riscv_frame_info {
   poly_int64 gp_sp_offset;
   poly_int64 fp_sp_offset;
 
+  /* Top and bottom offsets of vector save areas from frame bottom.  */
+  poly_int64 v_sp_offset_top;
+  poly_int64 v_sp_offset_bottom;
+
   /* Offset of virtual frame pointer from stack pointer/frame bottom */
   poly_int64 frame_pointer_offset;
 
@@ -243,7 +250,7 @@ unsigned riscv_stack_boundary;
 /* If non-zero, this is an offset to be added to SP to redefine the CFA
    when restoring the FP register from the stack.  Only valid when generating
    the epilogue.  */
-static int epilogue_cfa_sp_offset;
+static poly_int64 epilogue_cfa_sp_offset;
 
 /* Which tuning parameters to use.  */
 static const struct riscv_tune_param *tune_param;
@@ -399,10 +406,13 @@ void riscv_frame_info::reset(void)
   total_size = 0;
   mask = 0;
   fmask = 0;
+  vmask = 0;
   save_libcall_adjustment = 0;
 
   gp_sp_offset = 0;
   fp_sp_offset = 0;
+  v_sp_offset_top = 0;
+  v_sp_offset_bottom = 0;
 
   frame_pointer_offset = 0;
 
@@ -1682,7 +1692,8 @@ riscv_call_tls_get_addr (rtx sym, rtx result)
   start_sequence ();
 
   emit_insn (riscv_got_load_tls_gd (a0, sym));
-  insn = emit_call_insn (gen_call_value (result, func, const0_rtx, NULL));
+  insn = emit_call_insn (gen_call_value (result, func, const0_rtx,
+					 gen_int_mode (RISCV_CC_BASE, SImode)));
   RTL_CONST_CALL_P (insn) = 1;
   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
   insn = get_insns ();
@@ -4145,7 +4156,8 @@ riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   struct riscv_arg_info info;
 
   if (arg.end_marker_p ())
-    return NULL;
+    /* Return the calling convention that used by the current function. */
+    return gen_int_mode (cum->variant_cc, SImode);
 
   return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
 }
@@ -4379,6 +4391,21 @@ riscv_fntype_abi (const_tree fntype)
   return default_function_abi;
 }
 
+/* Implement TARGET_INSN_CALLEE_ABI.  */
+
+const predefined_function_abi &
+riscv_insn_callee_abi (const rtx_insn *insn)
+{
+  rtx pat = PATTERN (insn);
+  gcc_assert (GET_CODE (pat) == PARALLEL);
+  rtx unspec = XVECEXP (pat, 0, 1);
+  gcc_assert (GET_CODE (unspec) == UNSPEC
+	      && XINT (unspec, 1) == UNSPEC_CALLEE_CC);
+  riscv_cc cc = (riscv_cc) INTVAL (XVECEXP (unspec, 0, 0));
+  gcc_assert (cc < RISCV_CC_UNKNOWN);
+  return function_abis[cc];
+}
+
 /* Handle an attribute requiring a FUNCTION_DECL;
    arguments as in struct attribute_spec.handler.  */
 static tree
@@ -5179,6 +5206,11 @@ riscv_save_reg_p (unsigned int regno)
   if (call_saved && might_clobber)
     return true;
 
+  /* Save callee-saved V registers.  */
+  if (V_REG_P (regno) && !crtl->abi->clobbers_full_reg_p (regno)
+      && might_clobber)
+    return true;
+
   if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
     return true;
 
@@ -5275,6 +5307,12 @@ riscv_save_libcall_count (unsigned mask)
 	|                               |       + UNITS_PER_HWVALUE
 	|  FPR save area                |
 	|                               |
+	+-------------------------------+ <-- stack_pointer_rtx
+	|                               |       + v_sp_offset_top
+	|  Vector Registers save area   |
+	|                               |
+	| ----------------------------- | <-- stack_pointer_rtx
+	|  area padding                 |       + v_sp_offset_bottom
 	+-------------------------------+ <-- frame_pointer_rtx (virtual)
 	|                               |
 	|  local variables              |
@@ -5311,6 +5349,7 @@ riscv_compute_frame_info (void)
   poly_int64 offset;
   bool interrupt_save_prologue_temp = false;
   unsigned int regno, i, num_x_saved = 0, num_f_saved = 0, x_save_size = 0;
+  unsigned int num_v_saved = 0;
 
   frame = &cfun->machine->frame;
 
@@ -5349,6 +5388,15 @@ riscv_compute_frame_info (void)
 	for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
 	  if (riscv_save_reg_p (regno))
 	    frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
+
+      /* Find out which V registers we need to save. */
+      if (TARGET_VECTOR)
+	for (regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
+	  if (riscv_save_reg_p (regno))
+	    {
+	      frame->vmask |= 1 << (regno - V_REG_FIRST);
+	      num_v_saved++;
+	    }
     }
 
   if (frame->mask)
@@ -5386,6 +5434,12 @@ riscv_compute_frame_info (void)
   offset += riscv_stack_align (get_frame_size ());
   /* The virtual frame pointer points above the local variables. */
   frame->frame_pointer_offset = offset;
+  /* Next are the callee-saved VRs.  */
+  if (frame->vmask)
+    offset += riscv_stack_align (num_v_saved * UNITS_PER_V_REG);
+  frame->v_sp_offset_top = offset;
+  frame->v_sp_offset_bottom
+    = frame->v_sp_offset_top - num_v_saved * UNITS_PER_V_REG;
   /* Next are the callee-saved FPRs. */
   if (frame->fmask)
     offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG);
@@ -5490,10 +5544,12 @@ riscv_restore_reg (rtx reg, rtx mem)
   rtx dwarf = NULL_RTX;
   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
 
-  if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
+  if (known_gt (epilogue_cfa_sp_offset, 0)
+      && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
     {
-      rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-					 GEN_INT (epilogue_cfa_sp_offset));
+      rtx cfa_adjust_rtx
+	= gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+			gen_int_mode (epilogue_cfa_sp_offset, Pmode));
       dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
     }
 
@@ -5671,6 +5727,79 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
       }
 }
 
+/* Call FN for each V register that is saved by the current function.  */
+
+static void
+riscv_for_each_saved_v_reg (poly_int64 &remaining_size,
+			    riscv_save_restore_fn fn, bool prologue)
+{
+  rtx vlen = NULL_RTX;
+  if (cfun->machine->frame.vmask != 0)
+    {
+      if (UNITS_PER_V_REG.is_constant ()
+	  && SMALL_OPERAND (UNITS_PER_V_REG.to_constant ()))
+	vlen = GEN_INT (UNITS_PER_V_REG.to_constant ());
+      else
+	{
+	  vlen = RISCV_PROLOGUE_TEMP (Pmode);
+	  rtx insn
+	    = emit_move_insn (vlen, gen_int_mode (UNITS_PER_V_REG, Pmode));
+	  RTX_FRAME_RELATED_P (insn) = 1;
+	}
+    }
+
+  machine_mode m1_mode = TARGET_VECTOR_ELEN_64
+			   ? (TARGET_MIN_VLEN >= 128 ? VNx2DImode : VNx1DImode)
+			   : VNx1SImode;
+  if (prologue)
+    {
+      /* This loop must iterate over the same space as its companion in
+	 riscv_compute_frame_info.  */
+      for (unsigned int regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
+	if (BITSET_P (cfun->machine->frame.vmask, regno - V_REG_FIRST))
+	  {
+	    bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
+	    if (handle_reg)
+	      {
+		rtx insn = NULL_RTX;
+		if (CONST_INT_P (vlen))
+		  {
+		    gcc_assert (SMALL_OPERAND (-INTVAL (vlen)));
+		    insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
+						     stack_pointer_rtx,
+						     GEN_INT (-INTVAL (vlen))));
+		  }
+		else
+		  insn = emit_insn (
+		    gen_sub3_insn (stack_pointer_rtx, stack_pointer_rtx, vlen));
+		gcc_assert (insn != NULL_RTX);
+		RTX_FRAME_RELATED_P (insn) = 1;
+		riscv_save_restore_reg (m1_mode, regno, 0, fn);
+		remaining_size -= UNITS_PER_V_REG;
+	      }
+	  }
+    }
+  else
+    {
+      /* This loop must iterate over the same space as its companion in
+	 riscv_compute_frame_info.  */
+      for (unsigned int regno = V_REG_LAST; regno >= V_REG_FIRST; regno--)
+	if (BITSET_P (cfun->machine->frame.vmask, regno - V_REG_FIRST))
+	  {
+	    bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
+	    if (handle_reg)
+	      {
+		riscv_save_restore_reg (m1_mode, regno, 0, fn);
+		rtx insn = emit_insn (
+		  gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, vlen));
+		gcc_assert (insn != NULL_RTX);
+		RTX_FRAME_RELATED_P (insn) = 1;
+		remaining_size -= UNITS_PER_V_REG;
+	      }
+	  }
+    }
+}
+
 /* For stack frames that can't be allocated with a single ADDI instruction,
    compute the best value to initially allocate.  It must at a minimum
    allocate enough space to spill the callee-saved registers.  If TARGET_RVC,
@@ -5688,6 +5817,11 @@ riscv_first_stack_step (struct riscv_frame_info *frame, poly_int64 remaining_siz
   else
     remaining_const_size = remaining_size.to_constant ();
 
+  /* First step must be set to the top of vector registers save area if any
+     vector registers need be preversed.  */
+  if (frame->vmask != 0)
+    return (remaining_size - frame->v_sp_offset_top).to_constant ();
+
   if (SMALL_OPERAND (remaining_const_size))
     return remaining_const_size;
 
@@ -5803,31 +5937,47 @@ riscv_expand_prologue (void)
       REG_NOTES (insn) = dwarf;
     }
 
-  /* Save the registers.  */
-  if ((frame->mask | frame->fmask) != 0)
+  /* Save the GP, FP, and V registers.  */
+  if ((frame->mask | frame->fmask | frame->vmask) != 0)
     {
       HOST_WIDE_INT step1 = riscv_first_stack_step (frame, remaining_size);
-
-      insn = gen_add3_insn (stack_pointer_rtx,
-			    stack_pointer_rtx,
-			    GEN_INT (-step1));
-      RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
-      remaining_size -= step1;
+      if (step1 != 0)
+	{
+	  insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
+				GEN_INT (-step1));
+	  RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
+	  remaining_size -= step1;
+	}
       riscv_for_each_saved_reg (remaining_size, riscv_save_reg, false, false);
-    }
 
-  frame->mask = mask; /* Undo the above fib.  */
+      /* Set up the frame pointer, if we're using one.  */
+      if (frame_pointer_needed)
+	{
+	  insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
+				GEN_INT ((frame->hard_frame_pointer_offset
+					  - remaining_size)
+					   .to_constant ()));
+	  RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
+
+	  riscv_emit_stack_tie ();
+	}
 
+      riscv_for_each_saved_v_reg (remaining_size, riscv_save_reg, true);
+    }
   /* Set up the frame pointer, if we're using one.  */
-  if (frame_pointer_needed)
+  else if (frame_pointer_needed)
     {
-      insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
-			    GEN_INT ((frame->hard_frame_pointer_offset - remaining_size).to_constant ()));
+      insn = gen_add3_insn (
+	hard_frame_pointer_rtx, stack_pointer_rtx,
+	GEN_INT (
+	  (frame->hard_frame_pointer_offset - remaining_size).to_constant ()));
       RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
 
       riscv_emit_stack_tie ();
     }
 
+  frame->mask = mask; /* Undo the above fib.  */
+
   /* Allocate the rest of the frame.  */
   if (known_gt (remaining_size, 0))
     {
@@ -5907,7 +6057,7 @@ riscv_expand_epilogue (int style)
      Start off by assuming that no registers need to be restored.  */
   struct riscv_frame_info *frame = &cfun->machine->frame;
   unsigned mask = frame->mask;
-  HOST_WIDE_INT step2 = 0;
+  poly_int64 step2 = 0;
   bool use_restore_libcall = ((style == NORMAL_RETURN)
 			      && riscv_use_save_libcall (frame));
   unsigned libcall_size = (use_restore_libcall
@@ -5987,13 +6137,22 @@ riscv_expand_epilogue (int style)
 
   /* If we need to restore registers, deallocate as much stack as
      possible in the second step without going out of range.  */
-  if ((frame->mask | frame->fmask) != 0)
+  if ((frame->mask | frame->fmask | frame->vmask) != 0)
     step2 = riscv_first_stack_step (frame, frame->total_size - libcall_size);
 
   if (use_restore_libcall)
     frame->mask = mask; /* Undo the above fib.  */
 
-  poly_int64 step1 = frame->total_size - step2 - libcall_size;
+  poly_int64 step1;
+  /* STEP1 must be set to the bottom of vector registers save area if any
+     vector registers need be preversed.  */
+  if (frame->vmask != 0)
+    {
+      step1 = frame->v_sp_offset_bottom;
+      step2 = frame->total_size - step1 - libcall_size;
+    }
+  else
+    step1 = frame->total_size - step2 - libcall_size;
 
   /* Set TARGET to BASE + STEP1.  */
   if (known_gt (step1, 0))
@@ -6027,8 +6186,9 @@ riscv_expand_epilogue (int style)
 					   stack_pointer_rtx,
 					   adjust));
 	  rtx dwarf = NULL_RTX;
-	  rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-					     GEN_INT (step2 + libcall_size));
+	  rtx cfa_adjust_rtx
+	    = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+			    gen_int_mode (step2 + libcall_size, Pmode));
 
 	  dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
 	  RTX_FRAME_RELATED_P (insn) = 1;
@@ -6047,9 +6207,9 @@ riscv_expand_epilogue (int style)
     frame->mask = 0; /* Temporarily fib that we need not save GPRs.  */
 
   /* Restore the registers.  */
+  riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);
   riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size,
-			    riscv_restore_reg,
-			    true, style == EXCEPTION_RETURN);
+			    riscv_restore_reg, true, style == EXCEPTION_RETURN);
 
   if (use_restore_libcall)
       frame->mask = mask; /* Undo the above fib.  */
@@ -6058,10 +6218,10 @@ riscv_expand_epilogue (int style)
     riscv_emit_stack_tie ();
 
   /* Deallocate the final bit of the frame.  */
-  if (step2 > 0)
+  if (step2.to_constant () > 0)
     {
       insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
-				       GEN_INT (step2)));
+				       GEN_INT (step2.to_constant ())));
 
       rtx dwarf = NULL_RTX;
       rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
@@ -6678,7 +6838,8 @@ riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
     }
 
   /* Jump to the target function.  */
-  insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL, const0_rtx));
+  rtx callee_cc = gen_int_mode (fndecl_abi (function).id (), SImode);
+  insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, callee_cc));
   SIBLING_CALL_P (insn) = 1;
 
   /* Run just enough of rest_of_compilation.  This sequence was
@@ -8485,6 +8646,9 @@ riscv_preferred_else_value (unsigned, tree, unsigned int nops, tree *ops)
 #undef TARGET_FNTYPE_ABI
 #define TARGET_FNTYPE_ABI riscv_fntype_abi
 
+#undef TARGET_INSN_CALLEE_ABI
+#define TARGET_INSN_CALLEE_ABI riscv_insn_callee_abi
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 4615e811947..8fc984fb47d 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -70,6 +70,9 @@
   UNSPEC_CLMUL
   UNSPEC_CLMULH
   UNSPEC_CLMULR
+
+  ;; the calling convention of callee
+  UNSPEC_CALLEE_CC
 ])
 
 (define_c_enum "unspecv" [
@@ -2920,18 +2923,20 @@
 (define_expand "sibcall"
   [(parallel [(call (match_operand 0 "")
 		    (match_operand 1 ""))
-	      (use (match_operand 2 ""))	;; next_arg_reg
-	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
+	      (unspec:SI [
+		(match_operand 2 "const_int_operand")
+	       ] UNSPEC_CALLEE_CC)])]
   ""
 {
   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
-  emit_call_insn (gen_sibcall_internal (target, operands[1]));
+  emit_call_insn (gen_sibcall_internal (target, operands[1], operands[2]));
   DONE;
 })
 
 (define_insn "sibcall_internal"
   [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
-	 (match_operand 1 "" ""))]
+	 (match_operand 1 "" ""))
+   (unspec:SI [(match_operand 2 "const_int_operand")] UNSPEC_CALLEE_CC)]
   "SIBLING_CALL_P (insn)"
   "@
    jr\t%0
@@ -2943,18 +2948,22 @@
   [(parallel [(set (match_operand 0 "")
 		   (call (match_operand 1 "")
 			 (match_operand 2 "")))
-	      (use (match_operand 3 ""))])]		;; next_arg_reg
+	      (unspec:SI [
+		(match_operand 3 "const_int_operand")
+	       ] UNSPEC_CALLEE_CC)])]
   ""
 {
   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
-  emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2]));
+  emit_call_insn (gen_sibcall_value_internal (operands[0], target, operands[2],
+					      operands[3]));
   DONE;
 })
 
 (define_insn "sibcall_value_internal"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
-	      (match_operand 2 "" "")))]
+	      (match_operand 2 "" "")))
+   (unspec:SI [(match_operand 3 "const_int_operand")] UNSPEC_CALLEE_CC)]
   "SIBLING_CALL_P (insn)"
   "@
    jr\t%1
@@ -2965,18 +2974,20 @@
 (define_expand "call"
   [(parallel [(call (match_operand 0 "")
 		    (match_operand 1 ""))
-	      (use (match_operand 2 ""))	;; next_arg_reg
-	      (use (match_operand 3 ""))])]	;; struct_value_size_rtx
+	      (unspec:SI [
+		(match_operand 2 "const_int_operand")
+	       ] UNSPEC_CALLEE_CC)])]
   ""
 {
   rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
-  emit_call_insn (gen_call_internal (target, operands[1]));
+  emit_call_insn (gen_call_internal (target, operands[1], operands[2]));
   DONE;
 })
 
 (define_insn "call_internal"
   [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
 	 (match_operand 1 "" ""))
+   (unspec:SI [(match_operand 2 "const_int_operand")] UNSPEC_CALLEE_CC)
    (clobber (reg:SI RETURN_ADDR_REGNUM))]
   ""
   "@
@@ -2989,11 +3000,14 @@
   [(parallel [(set (match_operand 0 "")
 		   (call (match_operand 1 "")
 			 (match_operand 2 "")))
-	      (use (match_operand 3 ""))])]		;; next_arg_reg
+	      (unspec:SI [
+		(match_operand 3 "const_int_operand")
+	       ] UNSPEC_CALLEE_CC)])]
   ""
 {
   rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
-  emit_call_insn (gen_call_value_internal (operands[0], target, operands[2]));
+  emit_call_insn (gen_call_value_internal (operands[0], target, operands[2],
+					   operands[3]));
   DONE;
 })
 
@@ -3001,6 +3015,7 @@
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
 	      (match_operand 2 "" "")))
+   (unspec:SI [(match_operand 3 "const_int_operand")] UNSPEC_CALLEE_CC)
    (clobber (reg:SI RETURN_ADDR_REGNUM))]
   ""
   "@
@@ -3020,7 +3035,9 @@
 {
   int i;
 
-  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
+  /* Untyped calls always use the RISCV_CC_BASE calling convention.  */
+  emit_call_insn (gen_call (operands[0], const0_rtx,
+			    gen_int_mode (RISCV_CC_BASE, SImode)));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c
new file mode 100644
index 00000000000..d0660588c63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -march=rv64gczve32x -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include <riscv_vector.h>
+
+void bar (int8_t *data);
+
+/*
+** foo1:
+**   addi\tsp,sp,-16
+**   sd\tra,8\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv1,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv2,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv3,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv4,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv5,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv6,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv7,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv24,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv25,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv26,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv27,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv28,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv29,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv30,0\(sp\)
+**   addi\tsp,sp,-4
+**   vs1r\.v\tv31,0\(sp\)
+**   addi\tsp,sp,-1028
+**   mv\ta0,sp
+**   call\tbar
+**   addi\tsp,sp,1028
+**   vl1re32\.v\tv31,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv30,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv29,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv28,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv27,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv26,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv25,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv24,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv7,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv6,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv5,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv4,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv3,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv2,0\(sp\)
+**   addi\tsp,sp,4
+**   vl1re32\.v\tv1,0\(sp\)
+**   addi\tsp,sp,4
+**   ld\tra,8\(sp\)
+**   addi\tsp,sp,16
+**   jr\tra
+*/
+void
+foo1 (vint8m1_t a)
+{
+  int8_t data[1024];
+  bar (data);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c
new file mode 100644
index 00000000000..77c5fee24ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -march=rv64gcv_zvl4096b -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */
+
+#include <riscv_vector.h>
+
+void bar (int8_t *data);
+
+/*
+** foo1:
+**   addi\tsp,sp,-16
+**   sd\tra,8\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv1,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv2,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv3,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv4,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv5,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv6,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv7,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv24,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv25,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv26,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv27,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv28,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv29,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv30,0\(sp\)
+**   addi\tsp,sp,-512
+**   vs1r\.v\tv31,0\(sp\)
+**   addi\tsp,sp,-1028
+**   mv\ta0,sp
+**   call\tbar
+**   addi\tsp,sp,1028
+**   vl1re32\.v\tv31,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv30,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv29,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv28,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv27,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv26,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv25,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv24,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv7,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv6,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv5,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv4,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv3,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv2,0\(sp\)
+**   addi\tsp,sp,512
+**   vl1re32\.v\tv1,0\(sp\)
+**   addi\tsp,sp,512
+**   ld\tra,8\(sp\)
+**   addi\tsp,sp,16
+**   jr\tra
+*/
+void
+foo1 (vint8m1_t a)
+{
+  int8_t data[1024];
+  bar (data);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c
new file mode 100644
index 00000000000..a2a7f78100e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c
@@ -0,0 +1,87 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi" } */
+
+#include <riscv_vector.h>
+
+void bar (int8_t *data);
+
+/*
+** foo1:
+**   addi\tsp,sp,-16
+**   sd\tra,8\(sp\)
+**   csrr\tt0,vlenb
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv1,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv2,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv3,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv4,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv5,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv6,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv7,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv24,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv25,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv26,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv27,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv28,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv29,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv30,0\(sp\)
+**   sub\tsp,sp,t0
+**   vs1r\.v\tv31,0\(sp\)
+**   addi\tsp,sp,-1024
+**   mv\ta0,sp
+**   call\tbar
+**   addi\tsp,sp,1024
+**   csrr\tt0,vlenb
+**   vl1re64\.v\tv31,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv30,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv29,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv28,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv27,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv26,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv25,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv24,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv7,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv6,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv5,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv4,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv3,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv2,0\(sp\)
+**   add\tsp,sp,t0
+**   vl1re64\.v\tv1,0\(sp\)
+**   add\tsp,sp,t0
+**   ld\tra,8\(sp\)
+**   addi\tsp,sp,16
+**   jr\tra
+*/
+void
+foo1 (vint8m1_t a)
+{
+  int8_t data[1024];
+  bar (data);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c
new file mode 100644
index 00000000000..0ea3e247368
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <riscv_vector.h>
+
+void bar1 (vint8m1_t a);
+void bar2 ();
+
+/*
+** foo1:
+**   addi\tsp,sp,-16
+**   sd\tra,8\(sp\)
+**   call\tbar1
+**   ld\tra,8\(sp\)
+**   addi\tsp,sp,16
+**   jr\tra
+*/
+void
+foo1 (vint8m1_t a)
+{
+  bar1 (a);
+}
+
+/*
+**  foo2:
+**    addi\tsp,sp,-16
+**    sd\tra,8\(sp\)
+**    csrr\tt0,vlenb
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv1,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv2,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv3,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv4,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv5,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv6,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv7,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv24,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv25,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv26,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv27,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv28,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv29,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv30,0\(sp\)
+**    sub\tsp,sp,t0
+**    vs1r\.v\tv31,0\(sp\)
+**    call\tbar2
+**    csrr\tt0,vlenb
+**    vl1re64\.v\tv31,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv30,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv29,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv28,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv27,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv26,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv25,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv24,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv7,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv6,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv5,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv4,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv3,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv2,0\(sp\)
+**    add\tsp,sp,t0
+**    vl1re64\.v\tv1,0\(sp\)
+**    add\tsp,sp,t0
+**    ld\tra,8\(sp\)
+**    addi\tsp,sp,16
+**    jr\tra
+
+*/
+void
+foo2 (vint8m1_t a)
+{
+  bar2 ();
+}
+
+/*
+** foo3:
+**   addi\tsp,sp,-16
+**   sd\tra,8\(sp\)
+**   vl1re8\.v\tv8,0\(a0\)
+**   call\tbar1
+**   ld\tra,8\(sp\)
+**   addi\tsp,sp,16
+**   jr\tra
+*/
+void
+foo3 (vint8m1_t *a)
+{
+  bar1 (*a);
+}
-- 
2.36.3


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-08-07  7:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-07  7:31 [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed Lehua Ding
  -- strict thread matches above, loose matches on Subject: below --
2023-07-20  9:01 [PATCH 0/3] RISC-V: Add an experimental vector calling convention Lehua Ding
2023-07-20  9:01 ` [PATCH 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed Lehua Ding
2023-08-07  6:53   ` Kito Cheng

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).