
Ivan Matek wrote:
On Tue, Jan 21, 2025 at 4:20 PM Peter Dimov
mailto:pdimov@gmail.com > wrote: Only decimal128_fast doesn't fit in two registers.
Also not all functions take 1 argument, in PDF I explicitly used copysign as example.
x86-64 uses up to 6 registers for parameter passing (RDI, RSI, RDX, RCX, R8, R9), which means that up to three 128 bit trivially copyable types can be passed in registers when pass by value is used.
I got a bit confused to be honest with all this I should have not gone and wrote reply before trying this out on godbolt, my apologies for noise.
But here are 2 things I believe are not correct in your response. Passing up to three 128 bit trivial types in registers is not property of X86-64, but of Linux ABI, Windows ABI is different.
Yes, that's why I said "non-Windows x86-64". :-)
On my machine decimal64_fast is not 128 bit because typedef unsigned long int uint_fast16_t; static_assert(sizeof(decimal64_fast) == 24); if you do not believe me here is godbolt: https://godbolt.org/z/xPzYTP6cM
That's true, and it's actually not passed in registers for this reason. https://godbolt.org/z/qs5z6Th9e Interesting. Looks like this is caused by the use of uint_fast16_t, which is actually uint64_t. Maybe not the best choice. https://godbolt.org/z/8fczrzbEY is better. Although as I said in my other e-mail, maybe the exponent and the significand should just be packed into a single uint64_t.