This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/52792] this pointer and return pointer are passed in wrong order when ms_abi is used (x86_64)


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52792

--- Comment #5 from Kai Tietz <ktietz at gcc dot gnu.org> ---
For the c++ sample:
typedef struct agg { long a; long b; long c; } agg;

class abc {
   long m;
public:
   agg foo(long a, long b, long c);
   agg boo(void);
};


agg abc::foo(long a, long b, long c)
{
  agg r = { a, b, c};
  m = a + b +c;
  return r;
}

MS' compiler produces for foo() method:
?foo@abc@@QAE?AUagg@@JJJ@Z:
                     push    ebp
                     mov     ebp, esp
                     mov     eax, [ebp+8]
                     mov     edx, [ebp+10h]
                     push    esi
                     mov     esi, [ebp+14h]
                     push    edi
                     mov     edi, [ebp+0Ch]
                     mov     [eax+4], edx
                     add     edx, edi
                     mov     [eax], edi
                     add     edx, esi
                     pop     edi
                     mov     [eax+8], esi
                     mov     [ecx], edx
                     pop     esi
                     pop     ebp
                     retn    10h

g++ produces on x86 (with -O2 -fno-omit-frame-pointer):
__ZN3abc3fooElll:
        pushl   %ebp
        movl    %ecx, %eax
        movl    %esp, %ebp
        pushl   %ebx
        movl    16(%ebp), %ecx
        movl    12(%ebp), %ebx
        movl    20(%ebp), %edx
        movl    %ecx, 4(%eax)
        addl    %ebx, %ecx
        movl    %ebx, (%eax)
        movl    %edx, 8(%eax)
        addl    %ecx, %edx
        movl    8(%ebp), %ecx
        movl    %edx, (%ecx)
        popl    %ebx
        popl    %ebp
        ret     $16

As we can see are for the ms compiler the argument 'this' passed in ecx, and
the aggregate pointer as first stack argument.  For g++ 'this' is passed on
stack, and the aggregate uses the 'ecx' register.

For x64 ms' compiler produces for foo() member:
?foo@abc@@QEAA?AUagg@@JJJ@Z:            ; DATA XREF: .rdata:off_140002748↓o
                     mov     r10d, [rsp+28h]
                     lea     eax, [r8+r9]
                     add     eax, r10d
                     mov     [rdx], r8d
                     mov     [rcx], eax
                     mov     rax, rdx
                     mov     [rdx+4], r9d
                     mov     [rdx+8], r10d
                     retn

g++ (with -O2) produces for x86_64 msabi:
_ZN3abc3fooElll:
.LFB0:
        .seh_endprologue
        movq    %rcx, %rax
        movl    40(%rsp), %ecx
        movl    %r9d, 4(%rax)
        addl    %r8d, %r9d
        movl    %r8d, (%rax)
        movl    %ecx, 8(%rax)
        addl    %r9d, %ecx
        movl    %ecx, (%rdx)
        ret

For ms' compiler it passes 'this' in rcx, and the aggregate pointer in 'rdx'.
For g++ it passes 'this' in rdx, and the aggregate pointer in 'rcx'.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]