On Mon, 3 Feb 2025 22:24:11 +0000, BGB wrote:
On 2/3/2025 3:35 PM, MitchAlsup1 wrote:
On Mon, 3 Feb 2025 20:58:50 +0000, BGB wrote:
-------------------
I had used 16 arguments in the XG2 ABI, but this was with 64 registers,
and mostly because this basically entirely eliminated the existence of non-register arguments.
In the ABI variant originally, it was intended as the 128-bit ABI, and
was expanded to 16 argument registers initially mostly because, in the 128-bit mode, each 128-bit argument took 2 registers (as an even pair);
so one was far more likely to eat up all the argument registers.
I had this problem in Mc 88100 ABI.
This ABI variant ended up being used as the base ABI for XG2 rather than
the original (8 argument register) ABI variant (albeit, dropping back to 64-bit pointers). But, it was still sorta relevant for functions
accepting 128-bit SIMD vectors (which were also passed as even register pairs).
Another reason NOT to have SIMD...instructions--it is perfectly fine
to have multi-lane calculations (and memory references) and perform
them without SIDM instructions.
Of course, I was also using spill space, and the added cost of 128 bytes
of spill space to nearly every stack frame was enough to be noticed.
Ended up special casing it to only require 128 bytes if either:
Functions with more than 8 argument registers were called;
A vararg function was called (such as "printf()");
Other cases using 64 bytes.
This greatly reduced the number of cases where 128 bytes were reserved,
and most of these were due to printf's or similar.
Brian's LLVM compiler reserves nothing on the stack except locations
that can be accessed within the subroutine--even when varargs is
present. In fact: caller does not need to know the called subroutine
is varargs.
The RISC-V ABI doesn't use spill-space though, but could also be faked callee-side by adjusting the SP-adjustments for the stack-frame if
needed (namely, adding an extra 64 bytes to the stack-size adjustment).
By the time one reaches 16 arguments, they (usually) reach 100%
coverage.
I have had managers refuse to accept subroutines with more than 8
arguments, telling that the arguments should be related in some
way and I should build some kind of structure representing how
they are related, and pass it instead.
I am mostly just going by "in the wild" code here...
But, yeah, I guess one can argue how much the different 8 or 16
arguments makes when it is less than 1% of functions.
But, yeah, statistical coverage in this case:
2 arguments: 36.8%
4 arguments: 79.2%
6 arguments: 96.2%
8 arguments: 99.3%
10 arguments: 99.9%
12 arguments: 100%
16 arguments: 100%
---------------------
Yeah, a case could be made that, practically, 8 is probably sufficient.
In HW one always shoots at "more than sufficient" {knee of the curve}
rather than "near optimal".
Only practical merit of 16 being that one can then (almost) ignore the possibility of non-register arguments, if they make the compiler refuse
to accept more than 16 arguments.
Yes, but then you arrive at the subroutine without any free registers
to perform a "few" calculations to know if you really want to enter
the subroutine or take a quick exit.
---------------
IIRC Android has a feature like this, albeit generally with a lower
limit (say, if you try to "malloc()" a 1GB array, the process is
terminated on the spot).
Acceptable only when there is a means to actually allow malloc() of
that 1GB array. I suspect said system is happy to allow you to
mmap() a 1TB file.
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)