From patchwork Mon Nov 11 14:43:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 290337 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BC7732C009F for ; Tue, 12 Nov 2013 01:51:32 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:subject:to:date:from:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=xO8xS1l0br61sfak uUCMKsIXrdQsmmV5w2f14dnP+He1tLIXdZiPpRCNo38/ANZPVmLZnpWzuxFP9Rat neFhoCThnCHVuihjTOlEMwCS7beAozyC42HfXR95WUPNW4r42NbEo9t5i1kW674n eJu50YmKuuIYGPNZfqI40GRP9Bs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:subject:to:date:from:mime-version:content-type :content-transfer-encoding; s=default; bh=MG4zekMkPFpX620fLubUoJ 8bMVI=; b=eifusf00unfLvBBdGL71phNfIufTprzWAwIM2pSlQeEOFrtcnfMic0 O2rlMUZ28SD/GHXHxTL+dr3lOLlOX/YOC+tgdX4+QaVZcTTHs1Goi9Sb5dHuAYKz x+UIdMlgUWsJ8hezFo8KbfXa8NPaFGfEVy7SDZfox79/3UOJV1f0Y= Received: (qmail 12246 invoked by alias); 11 Nov 2013 14:45:03 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 12211 invoked by uid 89); 11 Nov 2013 14:45:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL, BAYES_50, MSGID_FROM_MTA_HEADER, RDNS_NONE, SPF_PASS autolearn=no version=3.3.2 X-HELO: e06smtp10.uk.ibm.com Received: from Unknown (HELO e06smtp10.uk.ibm.com) (195.75.94.106) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 11 Nov 2013 14:43:21 +0000 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 11 Nov 2013 14:43:12 -0000 Received: from d06dlp02.portsmouth.uk.ibm.com (9.149.20.14) by e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 11 Nov 2013 14:43:10 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id 0AB09219005C for ; Mon, 11 Nov 2013 14:43:10 +0000 (GMT) Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by b06cxnps3074.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id rABEgvFR54394884 for ; Mon, 11 Nov 2013 14:42:57 GMT Received: from d06av02.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id rABEh9t8011003 for ; Mon, 11 Nov 2013 07:43:09 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with SMTP id rABEh8Xq010955 for ; Mon, 11 Nov 2013 07:43:08 -0700 Message-Id: <201311111443.rABEh8Xq010955@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Mon, 11 Nov 2013 15:43:08 +0100 Subject: [PATCH, rs6000] ELFv2 ABI 5/8: Struct return calling convention changes To: gcc-patches@gcc.gnu.org Date: Mon, 11 Nov 2013 15:43:08 +0100 (CET) From: "Ulrich Weigand" MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13111114-4966-0000-0000-00000777003A Hello, analogously to the previous patch handling homogeneous aggregates as arguments, this patch handles such aggregates as return values. In addition, the ELFv2 ABI returns any aggregate of up to 16 bytes in size (that is not otherwise handled) in up to two GPRs. In either case, the return value is returned formatted exactly as if it were being passed as first argument. In order to get this correct in the big-endian ELFv2 case, we need to provide a non-default implementation of TARGET_RETURN_IN_MSB. Bye, Ulrich ChangeLog: 2013-11-11 Ulrich Weigand Michael Gschwind * config/rs6000/rs6000.h (FP_ARG_MAX_RETURN): New macro. (ALTIVEC_ARG_MAX_RETURN): Likewise. (FUNCTION_VALUE_REGNO_P): Use them. * config/rs6000/rs6000.c (TARGET_RETURN_IN_MSB): Define. (rs6000_return_in_msb): New function. (rs6000_return_in_memory): Handle ELFv2 homogeneous aggregates. Handle aggregates of up to 16 bytes for ELFv2. (rs6000_function_value): Handle ELFv2 homogeneous aggregates. Index: gcc/gcc/config/rs6000/rs6000.h =================================================================== --- gcc.orig/gcc/config/rs6000/rs6000.h +++ gcc/gcc/config/rs6000/rs6000.h @@ -1648,6 +1648,10 @@ extern enum reg_class rs6000_constraints #define GP_ARG_RETURN GP_ARG_MIN_REG #define FP_ARG_RETURN FP_ARG_MIN_REG #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2) +#define FP_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? FP_ARG_RETURN \ + : (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1)) +#define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? ALTIVEC_ARG_RETURN \ + : (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1)) /* Flags for the call/call_value rtl operations set up by function_arg */ #define CALL_NORMAL 0x00000000 /* no special processing */ @@ -1667,8 +1671,10 @@ extern enum reg_class rs6000_constraints On RS/6000, this is r3, fp1, and v2 (for AltiVec). */ #define FUNCTION_VALUE_REGNO_P(N) \ ((N) == GP_ARG_RETURN \ - || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT && TARGET_FPRS) \ - || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)) + || ((N) >= FP_ARG_RETURN && (N) <= FP_ARG_MAX_RETURN \ + && TARGET_HARD_FLOAT && TARGET_FPRS) \ + || ((N) >= ALTIVEC_ARG_RETURN && (N) <= ALTIVEC_ARG_MAX_RETURN \ + && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)) /* 1 if N is a possible register number for function argument passing. On RS/6000, these are r3-r10 and fp1-fp13. Index: gcc/gcc/config/rs6000/rs6000.c =================================================================== --- gcc.orig/gcc/config/rs6000/rs6000.c +++ gcc/gcc/config/rs6000/rs6000.c @@ -1449,6 +1449,9 @@ static const struct attribute_spec rs600 #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory +#undef TARGET_RETURN_IN_MSB +#define TARGET_RETURN_IN_MSB rs6000_return_in_msb + #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs @@ -8725,6 +8728,16 @@ rs6000_return_in_memory (const_tree type /* Otherwise fall through to more conventional ABI rules. */ } + /* The ELFv2 ABI returns homogeneous VFP aggregates in registers */ + if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type, + NULL, NULL)) + return false; + + /* The ELFv2 ABI returns aggregates up to 16B in registers */ + if (DEFAULT_ABI == ABI_ELFv2 && AGGREGATE_TYPE_P (type) + && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) <= 16) + return false; + if (AGGREGATE_TYPE_P (type) && (aix_struct_return || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8)) @@ -8756,6 +8769,19 @@ rs6000_return_in_memory (const_tree type return false; } +/* Specify whether values returned in registers should be at the most + significant end of a register. We want aggregates returned by + value to match the way aggregates are passed to functions. */ + +static bool +rs6000_return_in_msb (const_tree valtype) +{ + return (DEFAULT_ABI == ABI_ELFv2 + && BYTES_BIG_ENDIAN + && AGGREGATE_TYPE_P (valtype) + && FUNCTION_ARG_PADDING (TYPE_MODE (valtype), valtype) == upward); +} + #ifdef HAVE_AS_GNU_ATTRIBUTE /* Return TRUE if a call to function FNDECL may be one that potentially affects the function calling ABI of the object file. */ @@ -29897,6 +29923,8 @@ rs6000_function_value (const_tree valtyp { enum machine_mode mode; unsigned int regno; + enum machine_mode elt_mode; + int n_elts; /* Special handling for structs in darwin64. */ if (TARGET_MACHO @@ -29916,6 +29944,36 @@ rs6000_function_value (const_tree valtyp /* Otherwise fall through to standard ABI rules. */ } + /* The ELFv2 ABI returns homogeneous VFP aggregates in registers. */ + if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (valtype), valtype, + &elt_mode, &n_elts)) + { + int first_reg, n_regs, i; + rtx par; + + if (SCALAR_FLOAT_MODE_P (elt_mode)) + { + /* _Decimal128 must use even/odd register pairs. */ + first_reg = (elt_mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; + n_regs = (GET_MODE_SIZE (elt_mode) + 7) >> 3; + } + else + { + first_reg = ALTIVEC_ARG_RETURN; + n_regs = 1; + } + + par = gen_rtx_PARALLEL (TYPE_MODE (valtype), rtvec_alloc (n_elts)); + for (i = 0; i < n_elts; i++) + { + rtx r = gen_rtx_REG (elt_mode, first_reg + i * n_regs); + rtx off = GEN_INT (i * GET_MODE_SIZE (elt_mode)); + XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, r, off); + } + + return par; + } + if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode) { /* Long long return value need be split in -mpowerpc64, 32bit ABI. */