3

So i have a piece of assembly that needs to call a function with the fastcall calling convention on windows, but gcc doesn't (afaict) support it. GCC does provide the regparm attribute but that expects the first 3 parameters to be passed in eax, edx and ecx, whereas fastcall expects the first two parameters to be passed in ecx and edx.

I'm merely trying to avoid effectively duplicating a few code paths, so this isn't exactly critical, but it would be great if it were avoidable.

olliej
  • 35,755
  • 9
  • 58
  • 55
  • 1
    Note that there's really no such thing as "the" fastcall calling convention. What you've described matches what C++ Builder refers to as fastcall. Visual C++ appears to be the odd one out in this case, for what it's worth. – Rob Kennedy Mar 23 '09 at 06:03

3 Answers3

12

GCC does support fastcall, via __attribute__((fastcall)). It appears to have been introduced in GCC 3.4.

jww
  • 97,681
  • 90
  • 411
  • 885
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • Are the first two arguments passed right to left and placed in `edx` and `ecx`, respectively? – jww Mar 10 '17 at 08:26
  • @jww [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#index-fastcall-function-attribute_002c-x86-32) says "the `fastcall` attribute causes the compiler to pass the first argument (if of integral type) in the register ECX and the second argument (if of integral type) in the register EDX." [Microsoft's `__fastcall`](https://msdn.microsoft.com/en-us/library/6xa169sk.aspx) is in the same ECX, EDX order for the first and second arguments, starting from the left. I'm not sure why you'd look at the arguments starting from the right... – ephemient Mar 10 '17 at 08:40
  • *"I'm not sure why you'd look at the arguments starting from the right..."* - I believe that's how the callee passes them - right to left. Consider, if there are four arguments, two are passed on the stack and two are passed in registers. In this case, the "first" argument left-to-right is passed on the stack, not a register. – jww Mar 10 '17 at 08:50
  • @jww Every C calling convention I've see has a fixed mapping from the left-most arguments to registers (maybe none, in the case of cdecl), and it's the right-most arguments that are spilled to the stack. Now, most calling conventions (except Pascal) have the leftward arguments higher up on the stack than the rightward arguments, which can be seen as pushing the right-most argument onto the stack first. But I've never seen a calling convention place right-most argument in a register and spill the left-most to the stack. – ephemient Mar 10 '17 at 09:41
5

I know I'm kind of late to the party on this one but if any of you stumble across this, just remember that you can define a macro to mimic it. For example:

#if defined(__GNUC__)
    #define MSFASTCALL __fastcall
    #define GCCFASTCALL 
#elif defined(_MSC_VER)
    #define MSFASTCALL
    #define GCCFASTCALL __attribute__((fastcall))
#endif

int MSFASTCALL magic() GCCFASTCALL;

Obviously, this looks kind of ugly, so you could just define 2 prototypes (which is what I do) to make it a little easier to read but there are people who prefer the route that requires less typing. I generally don't use calling conventions except for special cases. I just let the compiler optimize the rest away.

Now, there are some quirks to remember. For example, when you're targeting a 64 bit platforms, all functions utilize the fastcall convention in order to take advantage of the extra registers and improve speed and reduce indirection cost. Likewise, fastcall is implemented differently by different platforms as it is not standardized. There are some others but that's all I can pull off the top of my head.

1

If you're calling the function from asm then surely you have complete control over how you call the function. What's stopping you from just loading up the registers and issuing a CALL?

  • 1
    The problem is that the caller is in assembler, the function i'm calling is in C -- and it's the compilers' codegen for the function that i'm calling that is problematic :-( – olliej Oct 03 '08 at 03:10
  • Aaaah...yep, I assumed you were concerned with the caller not the callee. –  Oct 03 '08 at 03:14
  • No worries, i figured that was the confusion :D – olliej Oct 03 '08 at 03:16