home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 243,182 of 243,242   
   Bart to Waldek Hebisch   
   Re: printf and time_t   
   07 Feb 26 23:54:18   
   
   From: bc@freeuk.com   
      
   On 07/02/2026 22:48, Waldek Hebisch wrote:   
   > Bart  wrote:   
   >> On 07/02/2026 18:07, Kaz Kylheku wrote:   
      
   >>> The : syntax in the deffi macro call indicates the variadic list.   
   >>> It's not the case that we can make a variadic Lisp function pass its   
   arguments   
   >>> as an arbitrarily long variadic list with arbitrary types to the wrapped   
   FFI   
   >>> function. Fixed parameters must be declared after the colon.   
   >>   
   >> There's another issue with calling variadic functions, unrelated to the   
   >> number of args. I can't tell from the above whether it's convered.   
   >>   
   >> Normally an arg that is passed in a register, will be passed in GPR for   
   >> integer, or a floating point register if not.   
   >>   
   >> But a variadic float argument has to be passed in both, so for Win64   
   >> ABI/x64 it might be in both rcx and xmm1. I think it is similar on SYS V   
   >> for both x64 and arm64 (maybe on the latter both are passed in the GPR;   
   >> I'd have to go and look it up).   
   >   
   > In SYS V convention argument is passed in exactly one place.  It may   
   > be GPR, may be XMM register, may be on the stack.  If you put right   
   > thing in RAX, then your arguments are valid regardless if the function   
   > is a vararg function or not.   
      
   I had to go and check this, and you're right. SYS V does nothing special   
   when calling variadic functions.   
      
   I guess that makes implementing the body of variadic functions harder,   
   since it doesn't know where to look for the n'th variadic argument   
   unless it knows the type.   
      
   And even then, because the int and non-int args are spilled to separate   
   blocks, it has to keep track of where the next arg is in which block.   
      
   I think MS made the better call here; the necessary code is trivial for   
   Win64 ABI.   
      
   >>> A dynamic treatment could be arranged via a heavy weight wrapper mechanism   
   which   
   >>> dynamically analyzes the actual arguments, builds a libffi function   
   descriptor   
   >>> on the fly, then uses it to make the call; it could be wortwhile for   
   someone,   
   >>> but I didn't implement such a thing.  Metaprogramming tricks revolving   
   around   
   >>> dynamically evaluating deffi are also possible.   
   >>   
   >> My LIBFFI approach just uses assembly; it's the simplest way to do it.   
   >> (The LIBFFI 'C' library also uses assembly to do the tricky bits.)   
   >>   
   >> There, for Win64 ABI, I found it easiest to just load all the register   
   >> args to both integer and float registers, whether the called function   
   >> was variadic or not. That's far more efficient than figuring out the   
   >> right register argument by argument.   
   >>   
   >> I haven't implemented that for SYS V; that's more of a nightmare ABI   
   >> where up to 6-12 args   
      
   (Actually, 6-14 args; 6 max in GPRs and 8 in xmm regs)   
      
   > (8-16 on aarch64) can be passed between int and   
   >> float registers depending on the mix of types.   
   >>   
   >> On Win64 ABI, it is 4 args, always.   
   >   
   > My code works fine for SYS V on amd64 and arm32.  I do not think FFI   
   > for aarch64 will be any harder, but ATM I do not have code generator   
   > for aarch64, no need for FFI there.   
   >   
   > I did not bother with Windows, since I do not use it it would be   
   > untested and hence buggy code anyway.   
      
   I started generating code for ARM64, but gave up because it was too hard   
   and not fun (the RISC processor turned out to be a LOT more complex than   
   the CISC x64!).   
      
   The last straw was precisely to do with the SYS V call-conventions, and   
   I hadn't even gotten to variadic arguments yet, nor to structs passed   
   by-value, where the rules are labyrinthine.   
      
   (I understand that neither LLVM or Cranelist backends support them   
   directly; they need to be dealt with earlier on, so the user of those   
   IRs needs to figure it out.)   
      
    >and hence buggy code anyway.   
      
   I think you'd find it much simpler.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca