FW: RE: x86_64 port
Kurt Roeckx
kurt at roeckx.be
Mon Mar 7 13:01:16 EST 2005
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
I get the same with both gcc-3.3 and gcc-3.4. They generate
identical code.
> 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.
It looks to me like it's using eax/rax instead of r13 to me.
It's probably doing some optimizing it shouldn't, but on the
other hand isn't "wrong".
Also, it should be a "movq $g, %rax" instead of movl.
Without -O I get:
f:
pushq %rbp
movq %rsp, %rbp
movl $g, %r13d
movq %r13, %rax
jmp *%rax
(Note that the first 2 instructions are now a stack frame,
disabled with -O)
It still is using an movl instead of a movq, which is wrong.
esi (or rsi) give the following warning:
bug.c:1: warning: call-clobbered register used for global register variable
And doesn't change a thing. It's still the same code.
Using %ebp or %rbp with -O gives:
movl $g, %ebp
jmp *%rbp
Which gives the same movl/movq problem, but now got the right
register.
Doing the same on i386 generates this:
f:
pushl %ebp
movl %esp, %ebp
movl $g, %eax
jmp *%eax
Using -fomit-frame-pointer you get:
f:
movl $g, %eax
jmp *%eax
Which seems to be exactly the same thing, except it got the size
right now.
The weird thing is that r13 doesn't exist on i386, and it didn't
complain about it.
Anyway, as summary:
- It's using a movl where it should use a movq
- It's probably doing some optimizations it shouldn't, but
they're not "wrong" in this testcase and probably can't be
avoided because of the way gcc works.
Those happen on both i386 and amd64.
Kurt
More information about the Glasgow-haskell-users
mailing list