Parameter passing in Visual Studio. Note how __m128 types are passed. Does it mean that no more than 4 __m128 arguments should be passed by value.
void good_function(__m128, __m128, __m128, __m128, __m128&);
void bad_function(__m128, __m128, __m128, __m128, __m128);
Does the same rule apply to GCC?
Thank you!
EDIT: Is it possible that the fifth argument of bad_function can be misaligned? I read somewhere that only 3 arguments are passed in registers (I guess it is Win32, not x64).
The parameter passing description you linked to is actually a x86_64 Windows ABI (application binary interface) description demonstrating how values will be passed to a function at the assembly level (i.e., how the compiler will translate a C-function call to assembly). That being said, the first four arguments will be passed as pointers to the
__m128types using registers on a x86_64 platform. Since the x86_64 platform has more registers to work with compared to it’s 32-bit couterpart, this type of parameter passing is done in order to speed up functions calls since accessing arguments stored in registers will be faster than accessing argument values stored in memory on the stack like you would normally see with cdecl-style function calls on a 32-bit x86 platform. If you go beyond 4 arguments, then the rest of the pointers to the__m128type are stored on the stack. So there are no “good function” or “bad functions” simply based on the the number of arguments. In your example, both of your functions are good, it’s just with the second example the rest of the arguments must use stack-space, as the number of available registers that can be used to pass values have been used up.That being said, the pointers to the
__m128types will most likely be pointing to addresses allocated on the stack if they are automatic variables. So either way, you’ll most likely be using stack space, either to store the variables being pointed to, or to pass extra arguments to functions when working with larger-than-64-bit values and other aggregate types like classes, unions, arrays, etc.As for GCC, since what you’ve referenced is actually a platform-dependent ABI implementation (in this case x86_64 Windows), what you’ll see on other platforms will differ somewhat, although again, for most x86_64 OS’s, they will use a series of registers to pass the first couple arguments of a function call. So GCC will actually use the same rules as Visual Studio on x86_64 Windows, but on other platforms it will create different assembly based on the x86_64 ABI’s for those platforms.