From patchwork Wed Nov 11 10:53:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 9647 Received: (qmail 123106 invoked by alias); 11 Nov 2015 10:54:07 -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 122819 invoked by uid 89); 11 Nov 2015 10:54:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f49.google.com Received: from mail-pa0-f49.google.com (HELO mail-pa0-f49.google.com) (209.85.220.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 11 Nov 2015 10:54:00 +0000 Received: by pabfh17 with SMTP id fh17so28435017pab.0 for ; Wed, 11 Nov 2015 02:53:58 -0800 (PST) X-Received: by 10.68.132.97 with SMTP id ot1mr13463851pbb.162.1447239238178; Wed, 11 Nov 2015 02:53:58 -0800 (PST) Received: from E107787-LIN.cambridge.arm.com (gcc2-power8.osuosl.org. [140.211.9.43]) by smtp.gmail.com with ESMTPSA id wh10sm8907698pab.2.2015.11.11.02.53.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 Nov 2015 02:53:57 -0800 (PST) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 1/2] Refactor arm_return_in_memory Date: Wed, 11 Nov 2015 10:53:51 +0000 Message-Id: <1447239232-30916-2-git-send-email-yao.qi@linaro.org> In-Reply-To: <1447239232-30916-1-git-send-email-yao.qi@linaro.org> References: <1447239232-30916-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes Current arm_return_in_memory isn't friendly to adding new things in it. Moreover, a lot of stuff are about APCS, which is not used nowadays (AAPCS is being used). This patch is to refactor arm_return_in_memory, so that some code can be shared for both APCS and AAPCS at the beginning of arm_return_in_memory, and then each ABI (APCS and AAPCS) are processed separately. gdb: 2015-11-11 Yao Qi * arm-tdep.c (arm_return_in_memory): Rewrite it. (arm_return_value): Call arm_return_in_memory for TYPE_CODE_COMPLEX. --- gdb/arm-tdep.c | 162 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 4f8c7f2..f52f03a 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -8991,99 +8991,106 @@ arm_extract_return_value (struct type *type, struct regcache *regs, static int arm_return_in_memory (struct gdbarch *gdbarch, struct type *type) { - int nRc; enum type_code code; type = check_typedef (type); - /* In the ARM ABI, "integer" like aggregate types are returned in - registers. For an aggregate type to be integer like, its size - must be less than or equal to INT_REGISTER_SIZE and the - offset of each addressable subfield must be zero. Note that bit - fields are not addressable, and all addressable subfields of - unions always start at offset zero. - - This function is based on the behaviour of GCC 2.95.1. - See: gcc/arm.c: arm_return_in_memory() for details. - - Note: All versions of GCC before GCC 2.95.2 do not set up the - parameters correctly for a function returning the following - structure: struct { float f;}; This should be returned in memory, - not a register. Richard Earnshaw sent me a patch, but I do not - know of any way to detect if a function like the above has been - compiled with the correct calling convention. */ + /* Simple, non-aggregate types (ie not including vectors and + complex) are always returned in a register (or registers). */ + code = TYPE_CODE (type); + if (TYPE_CODE_STRUCT != code && TYPE_CODE_UNION != code + && TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code) + return 0; - /* All aggregate types that won't fit in a register must be returned - in memory. */ - if (TYPE_LENGTH (type) > INT_REGISTER_SIZE) + if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS) { + /* The AAPCS says all aggregates not larger than a word are returned + in a register. */ + if (TYPE_LENGTH (type) <= INT_REGISTER_SIZE) + return 0; + return 1; } + else + { + int nRc; - /* The AAPCS says all aggregates not larger than a word are returned - in a register. */ - if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS) - return 0; + /* All aggregate types that won't fit in a register must be returned + in memory. */ + if (TYPE_LENGTH (type) > INT_REGISTER_SIZE) + return 1; - /* The only aggregate types that can be returned in a register are - structs and unions. Arrays must be returned in memory. */ - code = TYPE_CODE (type); - if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code)) - { - return 1; - } + /* In the ARM ABI, "integer" like aggregate types are returned in + registers. For an aggregate type to be integer like, its size + must be less than or equal to INT_REGISTER_SIZE and the + offset of each addressable subfield must be zero. Note that bit + fields are not addressable, and all addressable subfields of + unions always start at offset zero. - /* Assume all other aggregate types can be returned in a register. - Run a check for structures, unions and arrays. */ - nRc = 0; + This function is based on the behaviour of GCC 2.95.1. + See: gcc/arm.c: arm_return_in_memory() for details. - if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code)) - { - int i; - /* Need to check if this struct/union is "integer" like. For - this to be true, its size must be less than or equal to - INT_REGISTER_SIZE and the offset of each addressable - subfield must be zero. Note that bit fields are not - addressable, and unions always start at offset zero. If any - of the subfields is a floating point type, the struct/union - cannot be an integer type. */ - - /* For each field in the object, check: - 1) Is it FP? --> yes, nRc = 1; - 2) Is it addressable (bitpos != 0) and - not packed (bitsize == 0)? - --> yes, nRc = 1 - */ - - for (i = 0; i < TYPE_NFIELDS (type); i++) - { - enum type_code field_type_code; - field_type_code = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, - i))); - - /* Is it a floating point type field? */ - if (field_type_code == TYPE_CODE_FLT) - { - nRc = 1; - break; - } + Note: All versions of GCC before GCC 2.95.2 do not set up the + parameters correctly for a function returning the following + structure: struct { float f;}; This should be returned in memory, + not a register. Richard Earnshaw sent me a patch, but I do not + know of any way to detect if a function like the above has been + compiled with the correct calling convention. */ + + /* Assume all other aggregate types can be returned in a register. + Run a check for structures, unions and arrays. */ + nRc = 0; - /* If bitpos != 0, then we have to care about it. */ - if (TYPE_FIELD_BITPOS (type, i) != 0) + if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code)) + { + int i; + /* Need to check if this struct/union is "integer" like. For + this to be true, its size must be less than or equal to + INT_REGISTER_SIZE and the offset of each addressable + subfield must be zero. Note that bit fields are not + addressable, and unions always start at offset zero. If any + of the subfields is a floating point type, the struct/union + cannot be an integer type. */ + + /* For each field in the object, check: + 1) Is it FP? --> yes, nRc = 1; + 2) Is it addressable (bitpos != 0) and + not packed (bitsize == 0)? + --> yes, nRc = 1 + */ + + for (i = 0; i < TYPE_NFIELDS (type); i++) { - /* Bitfields are not addressable. If the field bitsize is - zero, then the field is not packed. Hence it cannot be - a bitfield or any other packed type. */ - if (TYPE_FIELD_BITSIZE (type, i) == 0) + enum type_code field_type_code; + + field_type_code + = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, + i))); + + /* Is it a floating point type field? */ + if (field_type_code == TYPE_CODE_FLT) { nRc = 1; break; } + + /* If bitpos != 0, then we have to care about it. */ + if (TYPE_FIELD_BITPOS (type, i) != 0) + { + /* Bitfields are not addressable. If the field bitsize is + zero, then the field is not packed. Hence it cannot be + a bitfield or any other packed type. */ + if (TYPE_FIELD_BITSIZE (type, i) == 0) + { + nRc = 1; + break; + } + } } } - } - return nRc; + return nRc; + } } /* Write into appropriate registers a function return value of type @@ -9238,12 +9245,11 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function, || arm_return_in_memory (gdbarch, valtype)) return RETURN_VALUE_STRUCT_CONVENTION; } - - /* AAPCS returns complex types longer than a register in memory. */ - if (tdep->arm_abi != ARM_ABI_APCS - && TYPE_CODE (valtype) == TYPE_CODE_COMPLEX - && TYPE_LENGTH (valtype) > INT_REGISTER_SIZE) - return RETURN_VALUE_STRUCT_CONVENTION; + else if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX) + { + if (arm_return_in_memory (gdbarch, valtype)) + return RETURN_VALUE_STRUCT_CONVENTION; + } if (writebuf) arm_store_return_value (valtype, regcache, writebuf);