From patchwork Tue Sep 5 07:44:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lehua Ding X-Patchwork-Id: 137480 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ab0a:0:b0:3f2:4152:657d with SMTP id m10csp1522265vqo; Tue, 5 Sep 2023 00:46:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF88vU/jGr+22Oxt9kogWq0ZzRehZzRS8T/Nv83pTtras8gmoIf4gzVah459wJgDP/cDUF1 X-Received: by 2002:a17:906:70d6:b0:9a1:6318:4d39 with SMTP id g22-20020a17090670d600b009a163184d39mr8744501ejk.29.1693899990185; Tue, 05 Sep 2023 00:46:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693899990; cv=none; d=google.com; s=arc-20160816; b=offQQsU6H3uH2Sz2/mUbk/pNT7M+5GYvOEkU1su9sbWSMzDuGpz8fQ4F4tXD9H46OH 2+6wgEi9eT3fA/KNm3ZG8o9bVQViEWlJUK4DoI8chCxsNEepRQ9l6EGbcSrXKpIw2NvJ KIV8Y80r7Cc2xVTNvsd0fw3gAHN+znDOhNI9MZ9d58eQXP3WaBGEJtasRDsVJMtU1R7N WSY2fG/ciYST6lAcJdN9cYxxGxLjVMl1uNSBiO2ldWEWKrEfU7fHD1Wb9FG5nCx2FhJo d5S8ngBKpu4wZMfri+q58qzM8QFLzHDO6wJaRA/Vebzwtd5SpSQS945Q4YaiLwAmUlEf 9tGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:feedback-id :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:dmarc-filter:delivered-to; bh=/xaydx6nJy2vg3YzkRnC43FhnJrjCno60Eu6AHGO3l8=; fh=z1Czm7N8XVhq5qJjafWBUpBTaSinYhfkdyGcUUXhnkM=; b=VUU36KNfHqYPuA/X6WGZ4WODhRz4doIs6cdbmRSRvzwMp5ch5Y/fzFM5USoXZVQlqn Lvo1rTajyC4NOchh4bwz2KqGdeLq3vq+isJs1BlVvnZtQD6yF0FjxyXeCrcqowI4HWfj +cSRfZKldh/ozoYwdywJvpCMbYHVq6PYKdgOfVo8/iuiQeLget9819/+r5fdIkdB1Moa cIY3zxhtaECvOKnpdLAoyAZgWWtYwOhf8Gxp1hIJcPZiOw4GTi8juJOwSLQkuwbGguEs EDairJxyFbqLumlifbs/BoXj8pAydW8Q4ZhfvITbe4+xua/8L9vcz9rW48guPEVArEtV zgLQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id m23-20020a170906235700b009a21af200f7si7184670eja.993.2023.09.05.00.46.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Sep 2023 00:46:30 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AF8B738555A1 for ; Tue, 5 Sep 2023 07:45:41 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbgjp3.qq.com (smtpbgjp3.qq.com [54.92.39.34]) by sourceware.org (Postfix) with ESMTPS id 5018D3858C2A for ; Tue, 5 Sep 2023 07:45:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5018D3858C2A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivai.ai Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rivai.ai X-QQ-mid: bizesmtp69t1693899900tzhevp5x Received: from rios-cad121.hadoop.rioslab.org ( [58.60.1.9]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 05 Sep 2023 15:44:59 +0800 (CST) X-QQ-SSF: 01400000000000C0F000000A0000000 X-QQ-FEAT: wOTYu9h7OeqSg1zi5PPp2PFJfAZ0lXYCjZwMuTsGSvaShiI9DRIwz7UzcfAl1 8EO2QKHbNjyDicipy9ZT72adeiS991ISkt1R0AalUnM167NlXYdZUZydGiEAjHVRmln2xNL COdDYNF+qbVLJ2BJrlpAGXeOdRR5Xu5dk9g1bhPmAUgI2YQ/jXl/xDeUBFkgOkaTtFXY8ip eiSOpcLpY6iPPiwn0RZdas5vgma+n/Wcr8biKgYZZxgCKcvS6EHjC61zTFcIr0Dsc+zswHu Sqq8Bb1s11X2G11ThbtdtHYzXBEz6+Ryry0w+CVw2hEIRNsdXENqL5HfWW5zJ0uQfCsg/qp 9Hpu5SEUrWnBEZ11eiKvkVdg4HTXHMyNdDhOhUthnhydWWXldXU7tdz8IiGJpM2bUBcJ4q3 S++z7MgL/iE= X-QQ-GoodBg: 2 X-BIZMAIL-ID: 5416690252447352928 From: Lehua Ding To: gcc-patches@gcc.gnu.org Subject: [PATCH V5 2/3] RISC-V: Part-2: Save/Restore vector registers which need to be preversed Date: Tue, 5 Sep 2023 15:44:51 +0800 Message-Id: <20230905074452.3714603-3-lehua.ding@rivai.ai> X-Mailer: git-send-email 2.36.3 In-Reply-To: <20230905074452.3714603-1-lehua.ding@rivai.ai> References: <20230905074452.3714603-1-lehua.ding@rivai.ai> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvrgz:qybglogicsvrgz6a-0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lehua.ding@rivai.ai, kito.cheng@gmail.com, juzhe.zhong@rivai.ai Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776182876067705011 X-GMAIL-MSGID: 1776182876067705011 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. (get_riscv_cc): New function return riscv_cc from rtl call_insn. (riscv_insn_callee_abi): Implement TARGET_INSN_CALLEE_ABI. (riscv_save_reg_p): Add vector callee-saved check. (riscv_stack_align): Add vector save area comment. (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.h (get_riscv_cc): Export get_riscv_cc function. * 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-save-restore.c: New test. * gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c: New test. * gcc.target/riscv/rvv/base/abi-callee-saved-1.c: New test. * gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c: New test. * gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c: New test. * gcc.target/riscv/rvv/base/abi-callee-saved-2.c: New test. --- gcc/config/riscv/riscv-sr.cc | 8 +- gcc/config/riscv/riscv.cc | 202 ++++++++++++++++-- gcc/config/riscv/riscv.h | 3 + gcc/config/riscv/riscv.md | 51 +++-- .../rvv/base/abi-callee-saved-1-fixed-1.c | 86 ++++++++ .../rvv/base/abi-callee-saved-1-fixed-2.c | 86 ++++++++ .../base/abi-callee-saved-1-save-restore.c | 85 ++++++++ .../riscv/rvv/base/abi-callee-saved-1-zcmp.c | 85 ++++++++ .../riscv/rvv/base/abi-callee-saved-1.c | 88 ++++++++ .../base/abi-callee-saved-2-save-restore.c | 108 ++++++++++ .../riscv/rvv/base/abi-callee-saved-2-zcmp.c | 107 ++++++++++ .../riscv/rvv/base/abi-callee-saved-2.c | 117 ++++++++++ 12 files changed, 994 insertions(+), 32 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-save-restore.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.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-save-restore.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.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..0f5893f527c 100644 --- a/gcc/config/riscv/riscv-sr.cc +++ b/gcc/config/riscv/riscv-sr.cc @@ -447,12 +447,14 @@ riscv_remove_unneeded_save_restore_calls (void) && !SIBCALL_REG_P (REGNO (target))) return; + riscv_cc cc = get_riscv_cc (XVECEXP (callpat, 0, 1)); 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 acfb8a11fc1..41c9941de65 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -110,6 +110,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; @@ -125,6 +128,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; @@ -278,7 +285,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; @@ -450,10 +457,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; @@ -1893,7 +1903,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 (); @@ -4652,7 +4663,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); } @@ -4892,6 +4904,30 @@ riscv_fntype_abi (const_tree fntype) return default_function_abi; } +/* Return riscv calling convention of call_insn. */ +riscv_cc +get_riscv_cc (const rtx use) +{ + gcc_assert (GET_CODE (use) == USE); + rtx unspec = XEXP (use, 0); + 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 cc; +} + +/* 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); + riscv_cc cc = get_riscv_cc (XVECEXP (pat, 0, 1)); + return function_abis[cc]; +} + /* Handle an attribute requiring a FUNCTION_DECL; arguments as in struct attribute_spec.handler. */ static tree @@ -5747,6 +5783,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; @@ -5919,6 +5960,12 @@ riscv_stack_align (HOST_WIDE_INT value) | | + UNITS_PER_FP_REG | FPR save area | | | + +-------------------------------+ <-- stack_pointer_rtx + | | + v_sp_offset_top + | Vector Registers save area | + | | + | ----------------------------- | <-- stack_pointer_rtx + | padding | + v_sp_offset_bottom +-------------------------------+ <-- frame_pointer_rtx (virtual) | | | local variables | @@ -5942,6 +5989,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; @@ -5980,6 +6028,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) @@ -6026,6 +6083,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); @@ -6138,10 +6201,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); } @@ -6323,6 +6388,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, @@ -6340,6 +6478,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; @@ -6533,11 +6676,20 @@ riscv_expand_prologue (void) if (riscv_use_multi_push (frame)) { remaining_size -= frame->multi_push_adj_base; - if (known_gt (remaining_size, 2 * ZCMP_SP_INC_STEP)) + /* If there are vector registers that need to be saved, then it can only + be reduced to the frame->v_sp_offset_top position at most, since the + vector registers will need to be saved one by one by decreasing the SP + later. */ + poly_int64 remaining_size_above_varea + = frame->vmask != 0 + ? remaining_size - frame->v_sp_offset_top + : remaining_size; + + if (known_gt (remaining_size_above_varea, 2 * ZCMP_SP_INC_STEP)) spimm = 3; - else if (known_gt (remaining_size, ZCMP_SP_INC_STEP)) + else if (known_gt (remaining_size_above_varea, ZCMP_SP_INC_STEP)) spimm = 2; - else if (known_gt (remaining_size, 0)) + else if (known_gt (remaining_size_above_varea, 0)) spimm = 1; else spimm = 0; @@ -6581,7 +6733,7 @@ riscv_expand_prologue (void) REG_NOTES (insn) = dwarf; } - /* Save the registers. */ + /* Save the GP, FP registers. */ if ((frame->mask | frame->fmask) != 0) { if (known_gt (remaining_size, frame->frame_pointer_offset)) @@ -6609,6 +6761,10 @@ riscv_expand_prologue (void) riscv_emit_stack_tie (); } + /* Save the V registers. */ + if (frame->vmask != 0) + riscv_for_each_saved_v_reg (remaining_size, riscv_save_reg, true); + /* Allocate the rest of the frame. */ if (known_gt (remaining_size, 0)) { @@ -6788,7 +6944,7 @@ riscv_expand_epilogue (int style) unsigned mask = frame->mask; unsigned fmask = frame->fmask; unsigned mask_fprs_push = 0; - HOST_WIDE_INT step2 = 0; + poly_int64 step2 = 0; bool use_multi_pop_normal = ((style == NORMAL_RETURN) && riscv_use_multi_push (frame)); bool use_multi_pop_sibcall @@ -6893,7 +7049,16 @@ riscv_expand_epilogue (int style) if (use_restore_libcall || use_multi_pop) frame->mask = mask; /* Undo the above fib. */ - poly_int64 step1 = frame->total_size - step2 - libcall_size - multipop_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 - multipop_size; + } + else + step1 = frame->total_size - step2 - libcall_size - multipop_size; /* Set TARGET to BASE + STEP1. */ if (known_gt (step1, 0)) @@ -6929,7 +7094,8 @@ riscv_expand_epilogue (int style) rtx dwarf = NULL_RTX; rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (step2 + libcall_size + multipop_size)); + gen_int_mode (step2 + libcall_size + multipop_size, + Pmode)); dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf); RTX_FRAME_RELATED_P (insn) = 1; @@ -6958,6 +7124,7 @@ riscv_expand_epilogue (int style) frame->mask = 0; /* Temporarily fib that we need not restore 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 - multipop_size, riscv_restore_reg, true, style == EXCEPTION_RETURN); @@ -6969,10 +7136,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 @@ -7635,7 +7802,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 @@ -9349,6 +9517,8 @@ riscv_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar) #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary #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 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \ diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 222aeec2b24..68be4f37b9d 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -731,6 +731,9 @@ typedef struct { bool used_vrs[MAX_ARGS_IN_VECTOR_REGISTERS]; } CUMULATIVE_ARGS; +/* Return riscv calling convention of call_insn. */ +extern enum riscv_cc get_riscv_cc (const rtx use); + /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 4041875e0e3..f981aeecf80 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -79,6 +79,9 @@ UNSPEC_CLMUL UNSPEC_CLMULH UNSPEC_CLMULR + + ;; the calling convention of callee + UNSPEC_CALLEE_CC ]) (define_c_enum "unspecv" [ @@ -3033,18 +3036,22 @@ (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 + (use (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 "" "")) + (use (unspec:SI [ + (match_operand 2 "const_int_operand") + ] UNSPEC_CALLEE_CC))] "SIBLING_CALL_P (insn)" "@ jr\t%0 @@ -3056,18 +3063,24 @@ [(parallel [(set (match_operand 0 "") (call (match_operand 1 "") (match_operand 2 ""))) - (use (match_operand 3 ""))])] ;; next_arg_reg + (use (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 "" ""))) + (use (unspec:SI [ + (match_operand 3 "const_int_operand") + ] UNSPEC_CALLEE_CC))] "SIBLING_CALL_P (insn)" "@ jr\t%1 @@ -3078,18 +3091,22 @@ (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 + (use (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 "" "")) + (use (unspec:SI [ + (match_operand 2 "const_int_operand") + ] UNSPEC_CALLEE_CC)) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" "@ @@ -3102,11 +3119,14 @@ [(parallel [(set (match_operand 0 "") (call (match_operand 1 "") (match_operand 2 ""))) - (use (match_operand 3 ""))])] ;; next_arg_reg + (use (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; }) @@ -3114,6 +3134,9 @@ [(set (match_operand 0 "" "") (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U")) (match_operand 2 "" ""))) + (use (unspec:SI [ + (match_operand 3 "const_int_operand") + ] UNSPEC_CALLEE_CC)) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" "@ @@ -3133,7 +3156,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..1e6292e84ed --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-1.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gczve32x -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +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..9fdbcd8deb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-fixed-2.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zvl4096b -mabi=lp64d --param=riscv-vector-abi --param=riscv-autovec-preference=fixed-vlmax -Wno-psabi" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +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,-1024 +** mv\ta0,sp +** call\tbar +** addi\tsp,sp,1024 +** vl1re64\.v\tv31,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv30,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv29,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv28,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv27,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv26,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv25,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv24,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv7,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv6,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv5,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv4,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv3,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.v\tv2,0\(sp\) +** addi\tsp,sp,512 +** vl1re64\.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-save-restore.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c new file mode 100644 index 00000000000..007c27498b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-save-restore.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -msave-restore" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +void bar (int8_t *data); + +/* +** foo1: +** call\tt0,__riscv_save_0 +** 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 +** tail\t__riscv_restore_0 +*/ +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-zcmp.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c new file mode 100644 index 00000000000..5f697e7c372 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1-zcmp.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -fno-shrink-wrap-separate" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +void bar (int8_t *data); + +/* +** foo1: +** cm.push\t\{ra\},\s*-16 +** 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 +** cm.popret\t{ra},\s*16 +*/ +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..42d099d39fd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-1.c @@ -0,0 +1,88 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +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-save-restore.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c new file mode 100644 index 00000000000..ce2f68e07d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-save-restore.c @@ -0,0 +1,108 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zfh -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -msave-restore" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +void bar1 (vint8m1_t a); +void bar2 (); + +/* +** foo1: +** tail\tbar1 +*/ +void +foo1 (vint8m1_t a) +{ + bar1 (a); +} + +/* +** foo2: +** call\tt0,__riscv_save_0 +** 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 +** tail\t__riscv_restore_0 + +*/ +void +foo2 (vint8m1_t a) +{ + bar2 (); +} + +/* +** foo3: +** call\tt0,__riscv_save_0 +** vl1re8\.v\tv8,0\(a0\) +** call\tbar1 +** call\tbar2 +** tail\t__riscv_restore_0 +*/ +void +foo3 (vint8m1_t *a) +{ + bar1 (*a); + bar2 (); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c new file mode 100644 index 00000000000..08ca1a102a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/abi-callee-saved-2-zcmp.c @@ -0,0 +1,107 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -march=rv64gcv_zfh_zca_zcmp -mabi=lp64d --param=riscv-vector-abi -Wno-psabi -fno-shrink-wrap-separate" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +void bar1 (vint8m1_t a); +void bar2 (); + +/* +** foo1: +** cm.push\t{ra},\s*-16 +** call\tbar1 +** cm.popret\t{ra},\s*16 +*/ +void +foo1 (vint8m1_t a) +{ + bar1 (a); +} + +/* +** foo2: +** cm.push\t{ra},\s*-16 +** 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 +** cm.popret\t{ra},\s*16 +*/ +void +foo2 (vint8m1_t a) +{ + bar2 (); +} + +/* +** foo3: +** cm.push\t{ra},\s*-16 +** vl1re8\.v\tv8,0\(a0\) +** call\tbar1 +** cm.popret\t{ra},\s*16 +*/ +void +foo3 (vint8m1_t *a) +{ + bar1 (*a); +} 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 + +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); +}