From patchwork Mon Aug 20 09:29:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 28970 Received: (qmail 17114 invoked by alias); 20 Aug 2018 09:30:06 -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 16875 invoked by uid 89); 20 Aug 2018 09:30:04 -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= 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:30:01 +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=wOc86//jGPtT4cvNi5QM3MSl1X5JCSKeSy2qAQaojjk=; b=cCnkWPN2j14OD5LBgHf76a506ZYgFXbMSYUmRhRWrDu1yoszMUnT3JGFDmWAPfF5FPLzn7m4IRk9mzCSBQvJ6WY4ri2lDx+vLNsjFickyPZkqnk2Y5FI9rFia/yEQ4O/4CMtXH/WA91b+hZsiFmJPFE9ecVIEIXSFufaXnB88PM= 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:48 +0000 From: Alan Hayward To: gdb-patches@sourceware.org Cc: nd@arm.com, Alan Hayward Subject: [PATCH 3/4] Aarch64: Float register detection for return values. Date: Mon, 20 Aug 2018 10:29:32 +0100 Message-Id: <20180820092933.83224-4-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. Remove the no longer used is_hfa_or_hva(). 2018-08-20 Alan Hayward PR gdb/22943: * aarch64-tdep.c (is_hfa_or_hva): Remove function. (aarch64_extract_return_value): Use aapcs_is_vfp_call_or_return_candidate. (aarch64_return_in_memory): Likewise. (aarch64_store_return_value): Likewise. --- gdb/aarch64-tdep.c | 200 +++++++++++++---------------------------------------- 1 file changed, 47 insertions(+), 153 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 45dde8a37e..7ff97f9078 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1151,68 +1151,6 @@ aarch64_type_align (struct type *t) } } -/* Return 1 if *TY is a homogeneous floating-point aggregate or - homogeneous short-vector aggregate as defined in the AAPCS64 ABI - document; otherwise return 0. */ - -static int -is_hfa_or_hva (struct type *ty) -{ - switch (TYPE_CODE (ty)) - { - case TYPE_CODE_ARRAY: - { - struct type *target_ty = TYPE_TARGET_TYPE (ty); - - if (TYPE_VECTOR (ty)) - return 0; - - if (TYPE_LENGTH (ty) <= 4 /* HFA or HVA has at most 4 members. */ - && (TYPE_CODE (target_ty) == TYPE_CODE_FLT /* HFA */ - || (TYPE_CODE (target_ty) == TYPE_CODE_ARRAY /* HVA */ - && TYPE_VECTOR (target_ty)))) - return 1; - break; - } - - case TYPE_CODE_UNION: - case TYPE_CODE_STRUCT: - { - /* HFA or HVA has at most four members. */ - if (TYPE_NFIELDS (ty) > 0 && TYPE_NFIELDS (ty) <= 4) - { - struct type *member0_type; - - member0_type = check_typedef (TYPE_FIELD_TYPE (ty, 0)); - if (TYPE_CODE (member0_type) == TYPE_CODE_FLT - || (TYPE_CODE (member0_type) == TYPE_CODE_ARRAY - && TYPE_VECTOR (member0_type))) - { - int i; - - for (i = 0; i < TYPE_NFIELDS (ty); i++) - { - struct type *member1_type; - - member1_type = check_typedef (TYPE_FIELD_TYPE (ty, i)); - if (TYPE_CODE (member0_type) != TYPE_CODE (member1_type) - || (TYPE_LENGTH (member0_type) - != TYPE_LENGTH (member1_type))) - return 0; - } - return 1; - } - } - return 0; - } - - default: - break; - } - - return 0; -} - /* Worker function for aapcs_is_vfp_call_or_return_candidate. Return the number of register required, or -1 on failure. @@ -1988,14 +1926,30 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, { struct gdbarch *gdbarch = regs->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int elements; + struct type *fundamental_type; - if (TYPE_CODE (type) == TYPE_CODE_FLT) + if (aapcs_is_vfp_call_or_return_candidate (type, &elements, + &fundamental_type)) { - bfd_byte buf[V_REGISTER_SIZE]; - int len = TYPE_LENGTH (type); + int len = TYPE_LENGTH (fundamental_type); - regs->cooked_read (AARCH64_V0_REGNUM, buf); - memcpy (valbuf, buf, len); + for (int i = 0; i < elements; i++) + { + int regno = AARCH64_V0_REGNUM + i; + bfd_byte buf[V_REGISTER_SIZE]; + + if (aarch64_debug) + { + debug_printf ("read HFA or HVA return value element %d from %s\n", + i + 1, + gdbarch_register_name (gdbarch, regno)); + } + regs->cooked_read (regno, buf); + + memcpy (valbuf, buf, len); + valbuf += len; + } } else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_CHAR @@ -2023,53 +1977,6 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, valbuf += X_REGISTER_SIZE; } } - else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX) - { - int regno = AARCH64_V0_REGNUM; - bfd_byte buf[V_REGISTER_SIZE]; - struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type)); - int len = TYPE_LENGTH (target_type); - - regs->cooked_read (regno, buf); - memcpy (valbuf, buf, len); - valbuf += len; - regs->cooked_read (regno + 1, buf); - memcpy (valbuf, buf, len); - valbuf += len; - } - else if (is_hfa_or_hva (type)) - { - int elements = TYPE_NFIELDS (type); - struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0)); - int len = TYPE_LENGTH (member_type); - int i; - - for (i = 0; i < elements; i++) - { - int regno = AARCH64_V0_REGNUM + i; - bfd_byte buf[V_REGISTER_SIZE]; - - if (aarch64_debug) - { - debug_printf ("read HFA or HVA return value element %d from %s\n", - i + 1, - gdbarch_register_name (gdbarch, regno)); - } - regs->cooked_read (regno, buf); - - memcpy (valbuf, buf, len); - valbuf += len; - } - } - else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) - && (TYPE_LENGTH (type) == 16 || TYPE_LENGTH (type) == 8)) - { - /* Short vector is returned in V register. */ - gdb_byte buf[V_REGISTER_SIZE]; - - regs->cooked_read (AARCH64_V0_REGNUM, buf); - memcpy (valbuf, buf, TYPE_LENGTH (type)); - } else { /* For a structure or union the behaviour is as if the value had @@ -2098,8 +2005,11 @@ static int aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type) { type = check_typedef (type); + int elements; + struct type *fundamental_type; - if (is_hfa_or_hva (type)) + if (aapcs_is_vfp_call_or_return_candidate (type, &elements, + &fundamental_type)) { /* v0-v7 are used to return values and one register is allocated for one member. However, HFA or HVA has at most four members. */ @@ -2126,14 +2036,31 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, { struct gdbarch *gdbarch = regs->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int elements; + struct type *fundamental_type; - if (TYPE_CODE (type) == TYPE_CODE_FLT) + if (aapcs_is_vfp_call_or_return_candidate (type, &elements, + &fundamental_type)) { - bfd_byte buf[V_REGISTER_SIZE]; - int len = TYPE_LENGTH (type); + int len = TYPE_LENGTH (fundamental_type); + + for (int i = 0; i < elements; i++) + { + int regno = AARCH64_V0_REGNUM + i; + bfd_byte tmpbuf[V_REGISTER_SIZE]; + + if (aarch64_debug) + { + debug_printf ("write HFA or HVA return value element %d to %s\n", + i + 1, + gdbarch_register_name (gdbarch, regno)); + } - memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len); - regs->cooked_write (AARCH64_V0_REGNUM, buf); + memcpy (tmpbuf, valbuf, + len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len); + regs->cooked_write (regno, tmpbuf); + valbuf += len; + } } else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_CHAR @@ -2168,39 +2095,6 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, } } } - else if (is_hfa_or_hva (type)) - { - int elements = TYPE_NFIELDS (type); - struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0)); - int len = TYPE_LENGTH (member_type); - int i; - - for (i = 0; i < elements; i++) - { - int regno = AARCH64_V0_REGNUM + i; - bfd_byte tmpbuf[V_REGISTER_SIZE]; - - if (aarch64_debug) - { - debug_printf ("write HFA or HVA return value element %d to %s\n", - i + 1, - gdbarch_register_name (gdbarch, regno)); - } - - memcpy (tmpbuf, valbuf, len); - regs->cooked_write (regno, tmpbuf); - valbuf += len; - } - } - else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) - && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16)) - { - /* Short vector. */ - gdb_byte buf[V_REGISTER_SIZE]; - - memcpy (buf, valbuf, TYPE_LENGTH (type)); - regs->cooked_write (AARCH64_V0_REGNUM, buf); - } else { /* For a structure or union the behaviour is as if the value had