From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9325 invoked by alias); 18 Apr 2011 08:18:40 -0000 Received: (qmail 9258 invoked by uid 22791); 18 Apr 2011 08:18:31 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_FN,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mtagate6.uk.ibm.com (HELO mtagate6.uk.ibm.com) (194.196.100.166) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 18 Apr 2011 08:18:00 +0000 Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate6.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p3I8Hu8U012057 for ; Mon, 18 Apr 2011 08:17:56 GMT Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p3I8Iona1286250 for ; Mon, 18 Apr 2011 09:18:50 +0100 Received: from d06av10.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p3I8HtMf019377 for ; Mon, 18 Apr 2011 02:17:55 -0600 Received: from bart (dyn-9-152-224-47.boeblingen.de.ibm.com [9.152.224.47]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p3I8Hsr8019349; Mon, 18 Apr 2011 02:17:54 -0600 Received: by bart (sSMTP sendmail emulation); Mon, 18 Apr 2011 10:17:54 +0200 From: "Andreas Krebbel" Date: Mon, 18 Apr 2011 09:23:00 -0000 To: Ian Lance Taylor Cc: gcc-patches@gcc.gnu.org Subject: Re: [PING] Fix PR46399 - missing mode promotion for libcall args Message-ID: <20110418081754.GA3385@bart> References: <20110413105432.GA5425@bart> <4DA5AC25.8030209@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-04/txt/msg01357.txt.bz2 Hi, the attached patch uses the existing promote_function_mode hook. For a libcall neither TYPE nor FNTYPE is available so I had to change a few related function in order to deal with that. The patch also fixes the s390 DFP problems. Bye, -Andreas- 2011-04-18 Andreas Krebbel * calls.c (emit_library_call_value_1): Invoke promote_function_mode hook on libcall arguments. * explow.c (promote_function_mode, promote_mode): Handle TYPE argument being NULL. * targhooks.c (default_promote_function_mode): Lisewise. * config/s390/s390.c (s390_promote_function_mode): Likewise. * config/sparc/sparc.c (sparc_promote_function_mode): Likewise. * doc/tm.texi: Document that TYPE argument might be NULL. Index: gcc/calls.c =================================================================== *** gcc/calls.c.orig --- gcc/calls.c *************** emit_library_call_value_1 (int retval, r *** 3484,3489 **** --- 3484,3490 ---- { rtx val = va_arg (p, rtx); enum machine_mode mode = (enum machine_mode) va_arg (p, int); + int unsigned_p = 0; /* We cannot convert the arg value to the mode the library wants here; must do it earlier where we know the signedness of the arg. */ *************** emit_library_call_value_1 (int retval, r *** 3531,3539 **** val = force_operand (XEXP (slot, 0), NULL_RTX); } ! argvec[count].value = val; argvec[count].mode = mode; ! argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true); --- 3532,3540 ---- val = force_operand (XEXP (slot, 0), NULL_RTX); } ! mode = promote_function_mode (NULL_TREE, mode, &unsigned_p, NULL_TREE, 0); argvec[count].mode = mode; ! argvec[count].value = convert_modes (mode, GET_MODE (val), val, 0); argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true); Index: gcc/config/s390/s390.c =================================================================== *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *************** s390_promote_function_mode (const_tree t *** 8742,8748 **** if (INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode) < UNITS_PER_LONG) { ! if (POINTER_TYPE_P (type)) *punsignedp = POINTERS_EXTEND_UNSIGNED; return Pmode; } --- 8742,8748 ---- if (INTEGRAL_MODE_P (mode) && GET_MODE_SIZE (mode) < UNITS_PER_LONG) { ! if (type != NULL_TREE && POINTER_TYPE_P (type)) *punsignedp = POINTERS_EXTEND_UNSIGNED; return Pmode; } Index: gcc/explow.c =================================================================== *** gcc/explow.c.orig --- gcc/explow.c *************** enum machine_mode *** 771,776 **** --- 771,787 ---- promote_function_mode (const_tree type, enum machine_mode mode, int *punsignedp, const_tree funtype, int for_return) { + /* Called without a type node for a libcall. */ + if (type == NULL_TREE) + { + if (INTEGRAL_MODE_P (mode)) + return targetm.calls.promote_function_mode (NULL_TREE, mode, + punsignedp, funtype, + for_return); + else + return mode; + } + switch (TREE_CODE (type)) { case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: *************** enum machine_mode *** 791,796 **** --- 802,813 ---- promote_mode (const_tree type ATTRIBUTE_UNUSED, enum machine_mode mode, int *punsignedp ATTRIBUTE_UNUSED) { + /* For libcalls this is invoked without TYPE from the backends + TARGET_PROMOTE_FUNCTION_MODE hooks. Don't do anything in that + case. */ + if (type == NULL_TREE) + return mode; + /* FIXME: this is the same logic that was there until GCC 4.4, but we probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE is not defined. The affected targets are M32C, S390, SPARC. */ Index: gcc/config/sparc/sparc.c =================================================================== *** gcc/config/sparc/sparc.c.orig --- gcc/config/sparc/sparc.c *************** init_cumulative_args (struct sparc_args *** 4965,4977 **** /* Handle promotion of pointer and integer arguments. */ static enum machine_mode ! sparc_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, enum machine_mode mode, ! int *punsignedp ATTRIBUTE_UNUSED, const_tree fntype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { ! if (POINTER_TYPE_P (type)) { *punsignedp = POINTERS_EXTEND_UNSIGNED; return Pmode; --- 4965,4977 ---- /* Handle promotion of pointer and integer arguments. */ static enum machine_mode ! sparc_promote_function_mode (const_tree type, enum machine_mode mode, ! int *punsignedp, const_tree fntype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { ! if (type != NULL_TREE && POINTER_TYPE_P (type)) { *punsignedp = POINTERS_EXTEND_UNSIGNED; return Pmode; Index: gcc/doc/tm.texi.in =================================================================== *** gcc/doc/tm.texi.in.orig --- gcc/doc/tm.texi.in *************** which an incoming parameter is copied, o *** 952,957 **** --- 952,959 ---- then the hook should return the same mode as @code{promote_mode}, though the signedness may be different. + @var{type} can be omitted when promoting function arguments of libcalls. + The default is to not promote arguments and return values. You can also define the hook to @code{default_promote_function_mode_always_promote} if you would like to apply the same rules given by @code{PROMOTE_MODE}. Index: gcc/doc/tm.texi =================================================================== *** gcc/doc/tm.texi.orig --- gcc/doc/tm.texi *************** which an incoming parameter is copied, o *** 962,967 **** --- 962,969 ---- then the hook should return the same mode as @code{promote_mode}, though the signedness may be different. + @var{type} can be omitted when promoting function arguments of libcalls. + The default is to not promote arguments and return values. You can also define the hook to @code{default_promote_function_mode_always_promote} if you would like to apply the same rules given by @code{PROMOTE_MODE}. Index: gcc/targhooks.c =================================================================== *** gcc/targhooks.c.orig --- gcc/targhooks.c *************** default_promote_function_mode (const_tre *** 124,130 **** const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { ! if (for_return == 2) return promote_mode (type, mode, punsignedp); return mode; } --- 124,130 ---- const_tree funtype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { ! if (type != NULL_TREE && for_return == 2) return promote_mode (type, mode, punsignedp); return mode; }