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