public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Lehua Ding <lehua.ding@rivai.ai>
To: Kito Cheng <kito.cheng@gmail.com>
Cc: gcc-patches@gcc.gnu.org, juzhe.zhong@rivai.ai
Subject: Re: [PATCH V3 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed
Date: Thu, 31 Aug 2023 20:28:54 +0800	[thread overview]
Message-ID: <96079A3D5F5C00EF+3d846b22-8b02-4234-b74b-5eb1eb0c7cbe@rivai.ai> (raw)
In-Reply-To: <CA+yXCZDNzQ5xvGzMZmZOPqXOu6o8pdjorDy8A6fxqPKi8AZWxQ@mail.gmail.com>

Sorry for that, rebased and send V4 patch, thanks.

On 2023/8/31 17:50, Kito Cheng via Gcc-patches wrote:
> Could you rebase the patch again, it seems got some conflict with zcmt
> which I commit in the past few days...
> 
> On Wed, Aug 30, 2023 at 9:54 AM Lehua Ding <lehua.ding@rivai.ai> wrote:
>>
>> 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 aa6b46d7611..09c9e09e83a 100644
>> --- a/gcc/config/riscv/riscv.cc
>> +++ b/gcc/config/riscv/riscv.cc
>> @@ -108,6 +108,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;
>>
>> @@ -115,6 +118,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;
>>
>> @@ -265,7 +272,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;
>> @@ -425,10 +432,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;
>>
>> @@ -1727,7 +1737,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 ();
>> @@ -4385,7 +4396,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);
>>   }
>> @@ -4625,6 +4637,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
>> @@ -5446,6 +5473,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;
>>
>> @@ -5546,6 +5578,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              |
>> @@ -5582,6 +5620,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;
>>
>> @@ -5620,6 +5659,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)
>> @@ -5657,6 +5705,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);
>> @@ -5761,10 +5815,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);
>>       }
>>
>> @@ -5942,6 +5998,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;
>> +       }
>> +    }
>> +
>> +  /* Select the mode where LMUL is 1 and SEW is largest.  */
>> +  machine_mode m1_mode = TARGET_VECTOR_ELEN_64 ? RVVM1DImode : RVVM1SImode;
>> +
>> +  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,
>> @@ -5959,6 +6088,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;
>>
>> @@ -6074,31 +6208,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))
>>       {
>> @@ -6178,7 +6328,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
>> @@ -6258,13 +6408,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))
>> @@ -6298,8 +6457,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;
>> @@ -6318,9 +6478,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.  */
>> @@ -6329,10 +6489,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,
>> @@ -6951,7 +7111,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
>> @@ -8868,6 +9029,9 @@ riscv_frame_pointer_required (void)
>>   #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 688fd697255..371e9959e61 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" [
>> @@ -2928,18 +2931,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
>> @@ -2951,18 +2956,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
>> @@ -2973,18 +2982,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))]
>>     ""
>>     "@
>> @@ -2997,11 +3008,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;
>>   })
>>
>> @@ -3009,6 +3023,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))]
>>     ""
>>     "@
>> @@ -3028,7 +3043,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
>>

-- 
Best,
Lehua

  reply	other threads:[~2023-08-31 12:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-30  1:54 [PATCH V3 0/3] RISC-V: Add an experimental vector calling convention Lehua Ding
2023-08-30  1:54 ` [PATCH V3 1/3] RISC-V: Part-1: Select suitable vector registers for vector type args and returns Lehua Ding
2023-08-30  1:54 ` [PATCH V3 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed Lehua Ding
2023-08-31  9:50   ` Kito Cheng
2023-08-31 12:28     ` Lehua Ding [this message]
2023-08-30  1:54 ` [PATCH V3 3/3] RISC-V: Part-3: Output .variant_cc directive for vector function Lehua Ding

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=96079A3D5F5C00EF+3d846b22-8b02-4234-b74b-5eb1eb0c7cbe@rivai.ai \
    --to=lehua.ding@rivai.ai \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=juzhe.zhong@rivai.ai \
    --cc=kito.cheng@gmail.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).