Conversation
|
Plan to putting more table for the code gen among 3 different options, I was too optimistic that I could have time to doing that...:( anyway will put that once I have one. |
|
I just realized I didn't have enough bandwidth on this, so I asked my colleague @BeMg to help on this. We plan to did few more comparison and analysis for moving this forward. |
|
Here is a comparison of three strategies for how to deal with unused bits for bitInt:
This table shows the number of instructions for common operations between different strategies.
And the following table shows the number of instructions for each operation.
Also, here is the doc that includes the detailed assembly and the C source code for reference. cc @kito-cheng |
What if we use sign-extend strategy for signed BitInts and zero-extend strategy for unsigned BitInts as suggested here #419 (comment) This would match what we do for uint16_t/uint8_t/int16_t/uint16_t. That should give the shortest sequence for shift_right, div, mod, and compares. |
|
Updated with more combination code generation results There are four kinds of configurations for BitInt with three different ABI policies: And here is the table summarizing the number of assembly instructions
The details of the sheet can be found here cc @kito-cheng |
Update: Add mix type extend BitInt(65)
And detail instruction count sheet |
|
According to @BeMg's experiments, doing the same kind of extension as the original data type gives the best code gen performance, so I'm prefer that. The only issue is that BitInt(32) on RV64 wouldn’t match the behavior of a normal unsigned/uint32_t. and there are two options:
Let me know if anyone has any preferecne or comment, otherwise we will decide that in next psABI meeting and moving forward :) |
|
Here is an example implementation for four different styles. |
|
It was raised at the psabi tg that special casing N=32 might make the libgcc/compiler-rt implementations more difficult, as they would need to be implemented differently. I asked whether there were separate implementations for different N, or a shared implementation. According to the docs, it seems the answer is there is a shared implementation: https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html#Bit-precise-integer-arithmetic-functions This also does not use the conventional ABI, it uses a buffer+length encoding, which avoids the "does this fit into a register" questions usually present. We probably still need to agree on |
|
Changes:
|
|
Changes:
|
|
Also some survey on GCC implementation:
|
|
Where are you testing _BitInt for s390x? I can't get it to work on godbolt.org, so I'm not sure where you're getting the information that it orders the chunks from most to least significant. Is that only in trunk or something? |
|
As for which makes more sense, least to most significant is the sensible ordering for the chunks, as if you're doing, say, addition, you need to iterate from least to most significant chunk, no? |
|
Am 9. Oktober 2025 19:50:04 MESZ schrieb Jessica Clarke ***@***.***>:
jrtc27 left a comment (riscv-non-isa/riscv-elf-psabi-doc#419)
As for which makes more sense, least to most significant is the sensible ordering for the chunks, as if you're doing, say, addition, you need to iterate from least to most significant chunk, no?
Loops with decrements are trivial.
If you order the bytes in native sequence, you don't have to worry about chunk sizes at all.
Data stored by as 32-bit chunks will be ordered in the same sequence as when using 128-bit chunks. This makes storage to file easy.
Best regards
Heinrich
|
Implement riscv-non-isa/riscv-elf-psabi-doc#419. This patch makes the type extension based on the variable type for BIGINT, rather than using sign extension for all cases.
Implement riscv-non-isa/riscv-elf-psabi-doc#419. This patch makes the type extension based on the variable type for BIGINT, rather than using sign extension for all cases.
Implement riscv-non-isa/riscv-elf-psabi-doc#419. This patch makes the type extension based on the variable type for BIGINT, rather than using sign extension for all cases.
752c944 to
454059c
Compare
|
Changes:
|
|
Gonna merge this since we have both implementation on both GCC and LLVM, although GCC part still not landed yet, but just few minor test fails still fixing, |
Add ABI specification for _BitInt(N), the arbitrary-sized integer type
defined in C23.
Size and Alignment:
- _BitInt(N) size: smallest power-of-two bytes that can hold N bits
- Alignment follows size, capped at 2×XLEN bytes (16 bytes for RV64,
8 bytes for RV32)
Unused Bits:
- Signed _BitInt(N): unused bits are sign-extended
- Unsigned _BitInt(N): unused bits are zero-extended
- Note: _BitInt defaults to signed per C spec
Memory Layout and Endianness:
- N ≤ 2×XLEN: follows standard scalar endianness
- N > 2×XLEN: divided into 2×XLEN-bit chunks
- Little-endian: lower-addressed chunks contain less significant bits
- Big-endian (experimental): lower-addressed chunks contain more
significant bits
Calling Convention:
- _BitInt(N) where N ≤ XLEN: passed in a single register with
sign/zero extension based on signedness
- _BitInt(N) where XLEN < N ≤ 2×XLEN: passed in aligned register pair
- _BitInt(32) on RV64: passed as signed/unsigned 32-bit value
- _BitInt(N) where N > 2×XLEN: passed by reference
References:
- ISO/IEC WG14 N2763:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf
- [AArch64] Rationale Document for ABI related to the C23 _BitInt type:
https://github.com/ARM-software/abi-aa/tree/main/design-documents/bit-precise-types.rst
- AAPCS64 for _BitInt(N):
ARM-software/abi-aa@d621417
- x86-64 ABI for _BitInt(N):
https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/8ca45392570e96920f8a15d903d6122f6d263cd0
Fix #300
_BitInt (N)is the type defined in C23, allow user to define an arbitrary-sized integer type, where N is a postive integer larger than zero.This proposal defined the size and alignment of _BitInt, and define the unused bits as unspecified which is same as x86-64 and AArch64.
For the calling convention part, we keep unused bits as unspecified.
Ref:
ISO/IEC WG14 N2763: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf
[AArch64] Rationale Document for ABI related to the C23 _BitInt type. https://github.com/ARM-software/abi-aa/tree/main/design-documents/bit-precise-types.rst
AAPCS64 for _BitInt(N) ARM-software/abi-aa@d621417
x86-64 ABI for _BitInt(N) https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/8ca45392570e96920f8a15d903d6122f6d263cd0
Fix #300