Calling C functions with variable arguments on x64

Everything else that doesn't fall into one of the other PB categories.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Calling C functions with variable arguments on x64

Post by wilbert »

There are some problems calling C functions with variable arguments on x64 if they contain floating point arguments.

When it comes to functions with variable arguments on x64, the calling conventions mention ...
Windows wrote:For floating-point values only, both the integer and the floating-point register will contain the float value in case the callee expects the value in the integer registers.
Linux/Mac wrote:When a function taking variable-arguments is called, %rax must be set to the total number of floating point parameters passed to the function in vector registers.
For example the c function sprintf.

Code: Select all

ImportC ""
  sprintf(*buffer, format.p-utf8, arg.d)
EndImport

Global Dim buf.c(128)

sprintf(@buf(), "%e", 3.14)
Debug PeekS(@buf(), -1, #PB_UTF8)
On Windows, the third argument (arg.d) is passed in register xmm2 which would be fine for a function without variable arguments.
Since sprintf is a function using variable arguments, a copy of this value should also be passed in register r8 which PB doesn't do.

On Linux/Mac, PB doesn't pass the correct value in the rax register as this isn't required for a function with a fixed amount of arguments.

A workaround would be setting up the call yourself using asm instructions if you need this functionality but it's not very convenient.

I wanted to explain the problem.
It's not a bug since PB just doesn't support functions with variable arguments.
Windows (x64)
Raspberry Pi OS (Arm64)