In Windows, fastcall calling convention is implemented in the following way: * an argument that has integer type with size less-or-equal than 4 bytes is eligible for fastcall * the first argument that is eligible for fastcall is passed in ECX * the second argument that is eligible for fastcall is passed in EDX
GCC implementes it badly, structures and 64-bit integer arguments are not correctly passed in registers but they incorrectly increase the register number in "function_arg_advance_32" and further arguments eligible for fastcall are not passed in registers. Example: struct s { int a; }; int __attribute__((fastcall,noinline)) f(struct s s, int a1, int a2) { printf("args: %d, %d, %d\n", a1, a2, s.a); return 0; } int main() { struct s s = { 3 }; f(s, 1, 2); return 0; } --- on Windows, s goes on the stack, a1 goes in ECX and a2 goes in EDX. --- in gcc, s goes on the stack (but it incorrectly increased a register number), a1 goes in EDX and a2 goes on the stack too because gcc runs out of fastcall registers. -- Summary: Fastcall calling convention is incompatible with Windows Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: minor 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=41013