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