From patchwork Mon Aug 20 09:29:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 28969 Received: (qmail 16464 invoked by alias); 20 Aug 2018 09:30:01 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 16179 invoked by uid 89); 20 Aug 2018 09:30:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=pcs, spare, candidates, partially X-HELO: EUR03-AM5-obe.outbound.protection.outlook.com Received: from mail-eopbgr30043.outbound.protection.outlook.com (HELO EUR03-AM5-obe.outbound.protection.outlook.com) (40.107.3.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 20 Aug 2018 09:29:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=iOJS1QwO7k3OdnCK9EqKsy11UhRyy7GQ7fvK0WD8YWA=; b=eQnoiKcHSqUE86XZ85w5n59yAjUQy2PFV6ZIRPpz94kxB3LrhASNMfSztAd6hdp1SxdJ4v2LIBv5bpSQwkUBjCznR9W/jCs772x4MUs3F1efPQE4JCRPt0XFnbtqi7kCryiSDK6vVGyPhq6uUz+85jTYkhNothRmfnxMoCXrbiQ= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; Received: from C02TF0U7HF1T.manchester.arm.com (217.140.106.32) by AM4PR0802MB2131.eurprd08.prod.outlook.com (2603:10a6:200:5c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1059.21; Mon, 20 Aug 2018 09:29:47 +0000 From: Alan Hayward To: gdb-patches@sourceware.org Cc: nd@arm.com, Alan Hayward Subject: [PATCH 2/4] Aarch64: Float register detection for _push_dummy_call Date: Mon, 20 Aug 2018 10:29:31 +0100 Message-Id: <20180820092933.83224-3-alan.hayward@arm.com> In-Reply-To: <20180820092933.83224-1-alan.hayward@arm.com> References: <20180820092933.83224-1-alan.hayward@arm.com> MIME-Version: 1.0 Return-Path: alan.hayward@arm.com Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-IsSubscribed: yes Use aapcs_is_vfp_call_or_return_candidate to detect float register args, then pass in registers if there is room. pass_in_v_or_stack is no longer used. Remove it. 2018-08-20 Alan Hayward * aarch64-tdep.c (aapcs_is_vfp_call_or_return_candidate): Make static (pass_in_v_or_stack): Remove function. (pass_in_v_vfp_candidate): New function. (aarch64_push_dummy_call): Check for float register candidates. --- gdb/aarch64-tdep.c | 149 +++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index d3ea13f6f6..45dde8a37e 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1329,7 +1329,7 @@ aapcs_is_vfp_call_or_return_candidate_1 (struct type *type, Note that HFAs and HVAs can include nested structures and arrays. */ -bool +static bool aapcs_is_vfp_call_or_return_candidate (struct type *type, int *count, struct type **fundamental_type) { @@ -1522,19 +1522,57 @@ pass_in_x_or_stack (struct gdbarch *gdbarch, struct regcache *regcache, } } -/* Pass a value in a V register, or on the stack if insufficient are - available. */ - -static void -pass_in_v_or_stack (struct gdbarch *gdbarch, - struct regcache *regcache, - struct aarch64_call_info *info, - struct type *type, - struct value *arg) +/* Pass a value, which is of type arg_type, in a V register. Assumes value is a + aapcs_is_vfp_call_or_return_candidate and there are enough spare V + registers. A return value of false is an error state as the value will have + been partially passed to the stack. */ +static bool +pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache, + struct aarch64_call_info *info, struct type *arg_type, + struct value *arg) { - if (!pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (type), - value_contents (arg))) - pass_on_stack (info, type, arg); + switch (TYPE_CODE (arg_type)) + { + case TYPE_CODE_FLT: + return pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (arg_type), + value_contents (arg)); + break; + + case TYPE_CODE_COMPLEX: + { + const bfd_byte *buf = value_contents (arg); + struct type *target_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); + + if (!pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (target_type), + buf)) + return false; + + return pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (target_type), + buf + TYPE_LENGTH (target_type)); + } + + case TYPE_CODE_ARRAY: + if (TYPE_VECTOR (arg_type)) + return pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (arg_type), + value_contents (arg)); + /* fall through. */ + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + for (int i = 0; i < TYPE_NFIELDS (arg_type); i++) + { + struct value *field = value_primitive_field (arg, 0, i, arg_type); + struct type *field_type = check_typedef (value_type (field)); + + if (!pass_in_v_vfp_candidate (gdbarch, regcache, info, field_type, + field)) + return false; + } + return true; + + default: + return false; + } } /* Implement the "push_dummy_call" gdbarch method. */ @@ -1623,12 +1661,33 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (argnum = 0; argnum < nargs; argnum++) { struct value *arg = args[argnum]; - struct type *arg_type; - int len; + struct type *arg_type, *fundamental_type; + int len, elements; arg_type = check_typedef (value_type (arg)); len = TYPE_LENGTH (arg_type); + /* If arg can be passed in v registers as per the AAPCS64, then do so if + if there are enough spare registers. */ + if (aapcs_is_vfp_call_or_return_candidate (arg_type, &elements, + &fundamental_type)) + { + if (info.nsrn + elements <= 8) + { + /* We know that we have sufficient registers available therefore + this will never need to fallback to the stack. */ + if (!pass_in_v_vfp_candidate (gdbarch, regcache, &info, arg_type, + arg)) + error (_("Failed to push args")); + } + else + { + info.nsrn = 8; + pass_on_stack (&info, arg_type, arg); + } + continue; + } + switch (TYPE_CODE (arg_type)) { case TYPE_CODE_INT: @@ -1648,68 +1707,10 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, pass_in_x_or_stack (gdbarch, regcache, &info, arg_type, arg); break; - case TYPE_CODE_COMPLEX: - if (info.nsrn <= 6) - { - const bfd_byte *buf = value_contents (arg); - struct type *target_type = - check_typedef (TYPE_TARGET_TYPE (arg_type)); - - pass_in_v (gdbarch, regcache, &info, - TYPE_LENGTH (target_type), buf); - pass_in_v (gdbarch, regcache, &info, - TYPE_LENGTH (target_type), - buf + TYPE_LENGTH (target_type)); - } - else - { - info.nsrn = 8; - pass_on_stack (&info, arg_type, arg); - } - break; - case TYPE_CODE_FLT: - pass_in_v_or_stack (gdbarch, regcache, &info, arg_type, arg); - break; - case TYPE_CODE_STRUCT: case TYPE_CODE_ARRAY: case TYPE_CODE_UNION: - if (is_hfa_or_hva (arg_type)) - { - int elements = TYPE_NFIELDS (arg_type); - - /* Homogeneous Aggregates */ - if (info.nsrn + elements < 8) - { - int i; - - for (i = 0; i < elements; i++) - { - /* We know that we have sufficient registers - available therefore this will never fallback - to the stack. */ - struct value *field = - value_primitive_field (arg, 0, i, arg_type); - struct type *field_type = - check_typedef (value_type (field)); - - pass_in_v_or_stack (gdbarch, regcache, &info, - field_type, field); - } - } - else - { - info.nsrn = 8; - pass_on_stack (&info, arg_type, arg); - } - } - else if (TYPE_CODE (arg_type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (arg_type) && (len == 16 || len == 8)) - { - /* Short vector types are passed in V registers. */ - pass_in_v_or_stack (gdbarch, regcache, &info, arg_type, arg); - } - else if (len > 16) + if (len > 16) { /* PCS B.7 Aggregates larger than 16 bytes are passed by invisible reference. */