From patchwork Wed Sep 28 01:11:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 675900 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3skKS31NMFz9sBr for ; Wed, 28 Sep 2016 11:12:14 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=wJaqW1x/; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=EP9gRHkbZTKmkS3nLyzLIewF6a3q1eeipQCb3bT3xy1WdvMl3s okM2yhNtxj7+yhL0+K8kTuiKMtZAVnmZ0Tbl/ZZV5sm5iLgH3wnRIcw8V0avfWZd BMFs1XBqp61pobPrXufCoxLJ38Zv3C+TXyHodEjNVBb8ykufZWmg0kmsI= 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:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=5d1m2JBWCMgciUhear6TZqucpNg=; b=wJaqW1x/Gq/qsmaXIdYU WimGngWwbx/qwlNgD+BndtZvuNpVIPU/bKSpHtSjkObuYEcFSgrLvMya6sztrRYX Cp2lrMXa3DTnJIq7o216l3HI6tUZdUyK0J9bJHEJtTOGvEqXWpIUl7meeNn3HunI VqnzUdYX+j0S91GgEkesG9E= Received: (qmail 41387 invoked by alias); 28 Sep 2016 01:12: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 41339 invoked by uid 89); 28 Sep 2016 01:12:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=corrects, 1553 X-HELO: mail-pf0-f195.google.com Received: from mail-pf0-f195.google.com (HELO mail-pf0-f195.google.com) (209.85.192.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 28 Sep 2016 01:11:52 +0000 Received: by mail-pf0-f195.google.com with SMTP id q2so1398986pfj.0 for ; Tue, 27 Sep 2016 18:11:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=4BHZOMsLjb03QREglj6uzH/RcgHYXnknAsMGY8QRMvI=; b=OrumTmv+1gRFIVNJZ6AFITweTGWQda0TLy6XIuU5VnwmCF3sTh0KRluKxKglhrttf8 WOTTQxWtwmFUGceW67ulY8AoPSBcJ03OO6zbSIUVrQ1lUkXFLyJUn4yrFZBYcfEhZaLV oOxZGiIidDOevteIrmCFKGfZwb/nxmROmWujjzajmv00mdqEYCezREt1wTTIaX/rLMUk 1ZSEKXT421KU1wGyAhoY4f/INwbxkJ2TWvYTMWRLLq2qCmR9dS490I5CQk+SsLDVKJsF WIq53+vti4pY2HHLE9cPKjeR40FQSDDfbIWpqCcD9tV1hMaxaL//Zxi5yeWEZMJRUhni etdQ== X-Gm-Message-State: AE9vXwMYVN64y/i3BqdVK2il9e50byr8V+q1yo0Oay1szXhWMLwaTY8I8iIgwCSX6XeRgg== X-Received: by 10.98.217.199 with SMTP id b68mr53411597pfl.74.1475025110710; Tue, 27 Sep 2016 18:11:50 -0700 (PDT) Received: from bubble.grove.modra.org (CPE-58-160-146-233.sa.bigpond.net.au. [58.160.146.233]) by smtp.gmail.com with ESMTPSA id s12sm7527684pfj.73.2016.09.27.18.11.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Sep 2016 18:11:50 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 8DF9FC03C4; Wed, 28 Sep 2016 10:41:45 +0930 (ACST) Date: Wed, 28 Sep 2016 10:41:45 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org Cc: Segher Boessenkool Subject: [PATCH 1/2][RS6000] .gnu.attribute Tag_GNU_Power_ABI_FP Message-ID: <20160928011145.GF3336@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-IsSubscribed: yes Extend this attribute to cover long double ABIs, for 64-bit too. The idea is that the linker should warn if you are linking object files with incompatible ABIs, for example IEEE128 long double with IBM long double. It's only a warning, and doesn't catch everything. In particular, global data mismatches. ie. initialised global variables in one format can be used by code that expects a different format without warning. Also, a function returning "sizeof (long double)" or similar won't cause an object file to be tagged. Oh, and you need a new linker to see long double warnings. The patch also corrects an error that crept in to code setting rs6000_passes_float. See the added comment. Passing IEEE128 values in vsx regs ought to set both Tag_GNU_Power_ABI_FP and Tag_GNU_Power_ABI_Vector. I've also added a new option, default on, that disables output of .gnu_attribute tags. That's needed because this patch alone introduces libstdc++ testsuite regressions, fixed by the next patch. Bootstrapped and regression tested powerpc64le-linux and powerpc64-linux biarch. OK to apply? * config/rs6000/sysv4.opt (mgnu-attr): New option. * config/rs6000/rs6000.c (HAVE_LD_PPC_GNU_ATTR): Define. (rs6000_passes_float): Comment. (rs6000_passes_long_double): New static var. (call_ABI_of_interest): Return false unless rs6000_gnu_attr is set. (init_cumulative_args): Set up to emit fp .gnu.attribute for ELF 64-bit ABIs as well as 32-bit ELF. Correct rs6000_passes_float to include fp values returned in vectors. Set rs6000_passes_long_double. (rs6000_function_arg_advance_1): Likewise for function args. (rs6000_elf_file_end): Emit fp .gnu.attribute for ELF 64-bit ABIs, and SPE. Emit long double tag value too. (rs6000_opt_vars): Add gnu-attr. * configure.ac (HAVE_LD_PPC_GNU_ATTR): New ppc32 test. * configure: Regenerate. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4d3706c..49f662a 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -183,8 +183,16 @@ unsigned rs6000_pmode; unsigned rs6000_pointer_size; #ifdef HAVE_AS_GNU_ATTRIBUTE -/* Flag whether floating point values have been passed/returned. */ +# ifndef HAVE_LD_PPC_GNU_ATTR +# define HAVE_LD_PPC_GNU_ATTR 0 +# endif +/* Flag whether floating point values have been passed/returned. + Note that this doesn't say whether fprs are used, since the + Tag_GNU_Power_ABI_FP .gnu.attributes value this flag controls + should be set for soft-float values passed in gprs and ieee128 + values passed in vsx registers. */ static bool rs6000_passes_float; +static bool rs6000_passes_long_double; /* Flag whether vector values have been passed/returned. */ static bool rs6000_passes_vector; /* Flag whether small (<= 8 byte) structures have been returned. */ @@ -10920,7 +10928,7 @@ rs6000_return_in_msb (const_tree valtype) static bool call_ABI_of_interest (tree fndecl) { - if (symtab->state == EXPANSION) + if (rs6000_gnu_attr && symtab->state == EXPANSION) { struct cgraph_node *c_node; @@ -10997,7 +11005,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, } #ifdef HAVE_AS_GNU_ATTRIBUTE - if (DEFAULT_ABI == ABI_V4) + if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4)) { cum->escapes = call_ABI_of_interest (fndecl); if (cum->escapes) @@ -11025,10 +11033,19 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, <= 8)) rs6000_returns_struct = true; } - if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (return_mode)) - rs6000_passes_float = true; - else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode) - || SPE_VECTOR_MODE (return_mode)) + if (SCALAR_FLOAT_MODE_P (return_mode)) + { + rs6000_passes_float = true; + if ((HAVE_LD_PPC_GNU_ATTR || TARGET_64BIT) + && (FLOAT128_IBM_P (return_mode) + || FLOAT128_IEEE_P (return_mode) + || (return_type != NULL + && (TYPE_MAIN_VARIANT (return_type) + == long_double_type_node)))) + rs6000_passes_long_double = true; + } + if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode) + || SPE_VECTOR_MODE (return_mode)) rs6000_passes_vector = true; } } @@ -11475,16 +11492,23 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode, cum->nargs_prototype--; #ifdef HAVE_AS_GNU_ATTRIBUTE - if (DEFAULT_ABI == ABI_V4 + if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4) && cum->escapes) { - if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode)) - rs6000_passes_float = true; - else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) - rs6000_passes_vector = true; - else if (SPE_VECTOR_MODE (mode) - && !cum->stdarg - && cum->sysv_gregno <= GP_ARG_MAX_REG) + if (SCALAR_FLOAT_MODE_P (mode)) + { + rs6000_passes_float = true; + if ((HAVE_LD_PPC_GNU_ATTR || TARGET_64BIT) + && (FLOAT128_IBM_P (mode) + || FLOAT128_IEEE_P (mode) + || (type != NULL + && TYPE_MAIN_VARIANT (type) == long_double_type_node))) + rs6000_passes_long_double = true; + } + if ((named && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) + || (SPE_VECTOR_MODE (mode) + && !cum->stdarg + && cum->sysv_gregno <= GP_ARG_MAX_REG)) rs6000_passes_vector = true; } #endif @@ -34292,13 +34316,21 @@ static void rs6000_elf_file_end (void) { #ifdef HAVE_AS_GNU_ATTRIBUTE + /* ??? The value emitted depends on options active at file end. + Assume anyone using #pragma or attributes that might change + options knows what they are doing. */ + if ((TARGET_64BIT || DEFAULT_ABI == ABI_V4) + && rs6000_passes_float) + fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", + ((TARGET_DF_FPR | TARGET_DF_SPE ? 1 + : TARGET_SF_FPR | TARGET_SF_SPE ? 3 + : 2) + | (!rs6000_passes_long_double ? 0 + : !TARGET_LONG_DOUBLE_128 ? 2 * 4 + : TARGET_IEEEQUAD ? 3 * 4 + : 1 * 4))); if (TARGET_32BIT && DEFAULT_ABI == ABI_V4) { - if (rs6000_passes_float) - fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", - ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 - : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 - : 2)); if (rs6000_passes_vector) fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n", (TARGET_ALTIVEC_ABI ? 2 @@ -37085,6 +37117,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] = { "warn-cell-microcode", offsetof (struct gcc_options, x_rs6000_warn_cell_microcode), offsetof (struct cl_target_option, x_rs6000_warn_cell_microcode), }, + { "gnu-attr", + offsetof (struct gcc_options, x_rs6000_gnu_attr), + offsetof (struct cl_target_option, x_rs6000_gnu_attr), }, }; /* Inner function to handle attribute((target("..."))) and #pragma GCC target diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt index 581fcde..d5b27cc 100644 --- a/gcc/config/rs6000/sysv4.opt +++ b/gcc/config/rs6000/sysv4.opt @@ -155,3 +155,7 @@ Generate code to use a non-exec PLT and GOT. mbss-plt Target Report RejectNegative Var(secure_plt, 0) Save Generate code for old exec BSS PLT. + +mgnu-attr +Target Report Var(rs6000_gnu_attr) Init(-1) Save +Emit .gnu_attribute tags. diff --git a/gcc/configure.ac b/gcc/configure.ac index 534f22e..94912a0 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -5322,6 +5322,49 @@ if test "x$gcc_cv_ld_clearcap" = xyes; then fi AC_MSG_RESULT($gcc_cv_ld_clearcap) +case "$target" in + powerpc*-*-*) + case "$target" in + *le-*-linux*) + emul_name="-melf32lppc" + ;; + *) + emul_name="-melf32ppc" + ;; + esac + AC_CACHE_CHECK(linker .gnu_attribute long double support, + gcc_cv_ld_ppc_attr, + [gcc_cv_ld_ppc_attr=no + if test x"$ld_is_gold" = xyes; then + gcc_cv_ld_ppc_attr=yes + elif test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 28 -o "$gcc_cv_gld_major_version" -gt 2; then + gcc_cv_ld_ppc_attr=yes + fi + elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then + # check that merging the long double .gnu_attribute doesn't warn + cat > conftest1.s < conftest2.s < /dev/null 2>&1 \ + && $gcc_cv_as -a32 -o conftest2.o conftest2.s > /dev/null 2>&1 \ + && $gcc_cv_ld $emul_name -r -o conftest.o conftest1.o conftest2.o > /dev/null 2> conftest.err \ + && test ! -s conftest.err; then + gcc_cv_ld_ppc_attr=yes + fi + rm -f conftest.err conftest.o conftest1.o conftest2.o conftest1.s conftest2.s + fi + ]) + if test x$gcc_cv_ld_ppc_attr = xyes; then + AC_DEFINE(HAVE_LD_PPC_GNU_ATTR, 1, + [Define if your PowerPC linker has .gnu_attribute long double support.]) + fi + ;; +esac + case "$target:$tm_file" in powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*) case "$target" in