FW: RE: x86_64 port
Simon Marlow
simonmar at microsoft.com
Mon Mar 7 11:59:38 EST 2005
On 07 March 2005 16:40, Simon Marlow wrote:
> On 07 March 2005 16:18, David Brown wrote:
>
>> On Mon, Mar 07, 2005 at 11:47:31AM -0000, Simon Marlow wrote:
>>
>>> $ cat bug.c
>>> register void * R1 __asm__("%r13");
>>>
>>> extern void g(void);
>>> static void f(void) {
>>> R1 = g;
>>> goto *R1;
>>> }
>>> $ gcc -S -O bug.c
>>> $
>>>
>>> And take a look at the generated assembly for the function f:
>>>
>>> f:
>>> .LFB2:
>>> movl $g, %eax
>>> jmp *%rax
>>>
>>> Note that the assignment to the global variable R1 has been lost.
>>> It works fine on x86 though: change the register variable to %esi
>>> and try it.
>>
>> Hmm. On gcc 3.3.5 that I have, it discards the assignment on x86 as
>> well.
>
> Yes, looks like it fails with 3.4.1 and 3.4.3 I have here, but 3.2.2
> works.
>
> Now I'm quite surpised that this hasn't affected us on x86. Very
> strange.
The mystery as to why this doesn't affect us on x86 is solved: on x86 we
generate slightly different C code, including a dummy function call:
extern void g(void);
static void f(void) {
R1 = g;
dummy();
goto *R1;
}
the call to dummy() (which we filter out from the assembly later) is
enough to force gcc to emit the assignment to R1. That dummy function
call has been there for ever, and the original reason for it has been
lost in the mists of time... comments in the source code seemed to
indicate that it was probably not necessary any more, so for x86_64 I
removed it. It looks like I'll have to reinstate it to work around this
bug, though.
Cheers,
Simon
More information about the Glasgow-haskell-users
mailing list