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

  • [Bug target/41013] Ne... mikulas at artax dot karlin dot mff dot cuni dot cz

Reply via email to