* i686 pic & DCmode
@ 2013-08-07 15:52 Nathan Sidwell
2013-08-07 17:09 ` Eric Botcazou
2013-08-07 17:35 ` Nathan Sidwell
0 siblings, 2 replies; 4+ messages in thread
From: Nathan Sidwell @ 2013-08-07 15:52 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 2064 bytes --]
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
[-- Attachment #2: pic.diff --]
[-- Type: text/plain, Size: 593 bytes --]
2013-08-07 Nathan Sidwell <nathan@codesourcery.com>
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;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: i686 pic & DCmode
2013-08-07 15:52 i686 pic & DCmode Nathan Sidwell
@ 2013-08-07 17:09 ` Eric Botcazou
2013-08-07 17:35 ` Nathan Sidwell
1 sibling, 0 replies; 4+ messages in thread
From: Eric Botcazou @ 2013-08-07 17:09 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: gcc-patches
> The usual x86 ports avoid this, because their must_return_in_mem hooks DTRT
> already and we never fall into the default case.
So why not do the same for i686-elf?
> 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.
IMO that's not sufficient, you ought to go through all the back-ends and check
that you aren't breaking anything with such a bold change. This code is more
than 2 decades old and can affect every single port in a major way.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: i686 pic & DCmode
2013-08-07 15:52 i686 pic & DCmode Nathan Sidwell
2013-08-07 17:09 ` Eric Botcazou
@ 2013-08-07 17:35 ` Nathan Sidwell
2013-08-07 18:36 ` Ian Lance Taylor
1 sibling, 1 reply; 4+ messages in thread
From: Nathan Sidwell @ 2013-08-07 17:35 UTC (permalink / raw)
To: GCC Patches
Having poked further, I find this in the testsuite:
pr11001-strlen-2.c
--begin
register int regvar asm("%eax");
char *
do_copy (char *str)
{
return malloc (strlen (str) + 1);
}
--end
Is that even meaningful? The doc's for a global reg var say:
'Choose a register that is normally saved and restored by function calls on your
machine, so that library routines will not clobber it.'
If one never made calls to a library unaware of the reg's global use, things
would be ok. Except if one chose a register that is used by the ABI to return
things, or by the pro/epilogue code as a scratch register.
Should attempts to use a call_used reg as a global reg var generate an error?
Should it stop it being marked as a fixed_reg?
nathan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: i686 pic & DCmode
2013-08-07 17:35 ` Nathan Sidwell
@ 2013-08-07 18:36 ` Ian Lance Taylor
0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2013-08-07 18:36 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: GCC Patches
On Wed, Aug 7, 2013 at 10:34 AM, Nathan Sidwell <nathan@acm.org> wrote:
> Having poked further, I find this in the testsuite:
>
> pr11001-strlen-2.c
> --begin
> register int regvar asm("%eax");
>
> char *
> do_copy (char *str)
> {
> return malloc (strlen (str) + 1);
> }
> --end
>
> Is that even meaningful? The doc's for a global reg var say:
> 'Choose a register that is normally saved and restored by function calls on
> your
> machine, so that library routines will not clobber it.'
This is risky but meaningful, and potentially useful with asm
instructions.
> If one never made calls to a library unaware of the reg's global use, things
> would be ok. Except if one chose a register that is used by the ABI to
> return things, or by the pro/epilogue code as a scratch register.
>
> Should attempts to use a call_used reg as a global reg var generate an
> error?
No. Perhaps a warning.
> Should it stop it being marked as a fixed_reg?
Definitely not.
Ian
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-08-07 18:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-07 15:52 i686 pic & DCmode Nathan Sidwell
2013-08-07 17:09 ` Eric Botcazou
2013-08-07 17:35 ` Nathan Sidwell
2013-08-07 18:36 ` Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).