This is the mail archive of the 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]

x86_64 ABI

my understanding of the x86_64 ABI is that the following structure should be passed in registers:

struct data {
	unsigned int x;
	unsigned int y;
	unsigned long z;

but when I compile:

#include <stdio.h>

struct data {
  unsigned int  x       : 32;
  unsigned int  y       : 32;
  unsigned long dummy   : 64;
} ;

#ifdef __cplusplus
extern "C" int foo (data t);
extern int foo (struct data t);

#ifndef __cplusplus
data    d;

main (int argc, char* argv[])
  d.x = 1; d.y = 2;

printf ("an integer %d", foo(d));

  return 0;

I get different results, depending on whether I compile it as C or C+ + code. I'm using gcc 4.1.1 (but the same happens with 3.4.5).

In C I get:
        subq    $8, %rsp
        movl    $1, d+8(%rip)
        movl    $2, d+12(%rip)
        movq    d(%rip), %rdi
        movq    d+8(%rip), %rsi
        call    foo

so the argument gets passed in registers.

But in C++ the result is different and the data structure is passed on the stack.
subq $24, %rsp
movl $1, d+8(%rip)
movq d(%rip), %rdi
movl $2, d+12(%rip)
movq d+8(%rip), %rsi
movq %rdi, (%rsp)
movq %rsi, 8(%rsp)
call foo

My understanding of the ABI is that the data structure should be passed in registers, but in any case the behavior should be the same for C and C++ when data is POD. In the example if foo was a C function the code produced by g++ would be wrong. In this case it would also be very dangerous because the data structure happens to be _also_ in the right registers, but I expect small changes to the code to make it fail.
Unless g++ is actually passing the argument in registers and what's wrong is the spurious pushes onto the stack.

Maurizio Vitale

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