From patchwork Wed Aug 7 15:52:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 265548 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id C93032C008E for ; Thu, 8 Aug 2013 01:53:06 +1000 (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:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=FH2no8xJshL3qGT9OMGf8GLdxLTVem7+ZiHWo11crnK7ZZ EAJJ/W7Shk9gR6EW0+vS4f9BnbLHK9VIVeGO9dO/TiydlJ5qtE6hYiMo7UgEKh0D MrxxjBkN6wWlaru0BAFBMltYusfcTv3dK1NOjulbyr/KwYQYueI8kLCiCOZww= 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:date:from:mime-version:to:subject:content-type; s= default; bh=pz5Kck+E4naSSIc/r3Mn3SY19UM=; b=yMB8vWPq46uCc9+Si77c E996UkyS1Tv/eznvb3tQYklNNTCGeM3HoD4OjnSC3JA0Sjdg0uIs4Hxr7N56+s/s Y0Hj5t1YYNpjNmQ1rkmPI8EQ0tBk5mo/43EbMKU6PTOlKcBII22+iwWyO+SwaB5V esaGrhktvGXTqeX60FWEN0A= Received: (qmail 18943 invoked by alias); 7 Aug 2013 15:52:59 -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 18930 invoked by uid 89); 7 Aug 2013 15:52:59 -0000 X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mail-ve0-f174.google.com) (209.85.128.174) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 07 Aug 2013 15:52:56 +0000 Received: by mail-ve0-f174.google.com with SMTP id d10so2016173vea.33 for ; Wed, 07 Aug 2013 08:52:48 -0700 (PDT) X-Received: by 10.52.168.10 with SMTP id zs10mr675113vdb.21.1375890767907; Wed, 07 Aug 2013 08:52:47 -0700 (PDT) Received: from [192.168.1.15] (pool-71-174-34-5.bstnma.east.verizon.net. [71.174.34.5]) by mx.google.com with ESMTPSA id eu9sm3423501vdb.1.2013.08.07.08.52.46 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 07 Aug 2013 08:52:47 -0700 (PDT) Message-ID: <52026D4D.8020604@acm.org> Date: Wed, 07 Aug 2013 11:52:45 -0400 From: Nathan Sidwell User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: GCC Patches Subject: i686 pic & DCmode X-Virus-Found: No In poking at another set of fails encountered with an i686-elf toolchain (http://gcc.gnu.org/ml/gcc/2013-08/msg00081.html), I find that complex double returns and PIC do not play together. Libgcc's __muldc3 was attempting to return the value in registers, whereas every caller expected it to be returned via pointer-to-aggregate parm. Turned out to be PIC at fault -- libgcc is built as PIC, the callers weren't. To determine if the return value should go in memory, function.c contains aggregate_value_p, which really means 'can't return in registers'. That calls the backend return_in_mem hook, which for i686-elf simply forces BLKmode things to memory (the bundle of fun I refer to in the link). As this is DCmode, we fall through to the default behaviour, which after a few other checks, picks the return register and then looks to see if the span of registers needed for the object are all call clobbered. On x86, the registers are numbered eax, edx, ecx, ebx. The first 3 are call clobbered and ebx is call preserved. Hence (in non PIC), DCmode objects can't be placed there and a pointer-to-result parm is added. In PIC mode, ebx remains call preserved, but becomes a fixed regs. A fixed reg must also set call_used, and hey presto, we suddenly think all 4 are call clobbered. This causes the result to be placed in those 4 registers -- and then the epilogue code restores the incoming ebx value, for extra brokenness. The usual x86 ports avoid this, because their must_return_in_mem hooks DTRT already and we never fall into the default case. I am very surprised this hasn't bitten someone before -- I presume this never worked with i686-elf. It is possible this'll change some other ABI where a fixed reg was permitted to be used in the manner that this now prohibits, but I have a hard time thinking that happens. Shout if you know of one. Anyhow, I've not run a full regression test with this patch, but it does indicate that the i686-elf config's ABI is a bunch of accidents, rather than a coherent design. nathan 2013-08-07 Nathan Sidwell gcc/ * function.c (aggregate_value_p): Don't use a fixed reg either. Index: gcc/function.c =================================================================== --- gcc/function.c (revision 417583) +++ gcc/function.c (working copy) @@ -2031,7 +2031,7 @@ aggregate_value_p (const_tree exp, const regno = REGNO (reg); nregs = hard_regno_nregs[regno][TYPE_MODE (type)]; for (i = 0; i < nregs; i++) - if (! call_used_regs[regno + i]) + if (! call_used_regs[regno + i] || fixed_regs[regno + i]) return 1; return 0;