regparm=3 passes structures in registers if they fit there. There is
inconsistency in this rule, if structure contains only float or only double
type, it is passed on the stack.

Example:

__attribute__((regparm(3))) void function(struct s s);

now, the argument passing varies wildly depending on the definition of "struct
s".

struct s { float a; float b; } --- passed in registers
struct s { float a; } --- passed on stack
struct s { float a[1]; } --- passed on stack
struct s { float a[2]; } --- passed in registers
struct s { float a; int b; } --- passed in registers
struct s { float a[1]; float b[0]; } --- passed on stack
struct s { double a; } --- passed on stack
struct s { struct { float a; }; } --- passed on stack
union s { float a; } --- passed in registers
struct s { union { float a; }; } --- passed in registers
struct s { struct { float a; } q[1]; } --- passed on stack
struct s { long double a; } --- passed on stack
struct s { union { long double a; } } --- passed in registers

--- actually it seems that if the structure contains only one floating point
entry inside other structures or arrays (not unions), it is passed on stack,
not in registers ... otherwise it is passed in registers.

Hardly anyone deliberately designed it this way. Gcc internals are exposed to
the ABI! If the structure contains just one entry, its mode is different from
BLKmode and it takes different path in function_arg_advance_32 and
function_arg_32.

I'd propose to change it so that structures are always passed in registers, the
current state makes it hard or impossible to do any automatic marshalling of
arguments for regparm functions. I found this bug when trying to extend libffi
to handle regparm=3 calling convention.

(another way to fix this is to pass structures always on the stack, maybe it
would generate faster code, but it would create more ABI-incompatibility pain)


-- 
           Summary: regparm=3 passes structures inconsistently
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mikulas at artax dot karlin dot mff dot cuni dot cz
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41017

Reply via email to