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