Skip to content

Commit

Permalink
ABI for _BitInt
Browse files Browse the repository at this point in the history
`_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
  • Loading branch information
kito-cheng committed Jan 5, 2024
1 parent 52a6631 commit 9e2e1d9
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions riscv-cc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ sign-extended to XLEN bits.
When passed in registers or on the stack, floating-point types narrower than
XLEN bits are widened to XLEN bits, with the upper bits undefined.

When passed in registers or on the stack, `__BitInt(N)`, unused bits are
undefined, types narrower than XLEN bits are widened to XLEN bits, with the
upper bits undefined.

Scalars that are 2×XLEN bits wide are passed in a pair of argument registers,
with the low-order XLEN bits in the lower-numbered register and the high-order
XLEN bits in the higher-numbered register. If no argument registers are
Expand Down Expand Up @@ -457,6 +461,12 @@ alignments (based on the ILP32 convention):
| float _Complex | 8 | 4
| double _Complex | 16 | 8
| long double _Complex | 32 | 16
| _BitInt(1 ≤ N ≤ 8) | 1 | 1
| _BitInt(9 ≤ N ≤ 16) | 2 | 2
| _BitInt(17 ≤ N ≤ 32) | 4 | 4
| _BitInt(33 ≤ N ≤ 64) | 8 | 8
| _BitInt(65 ≤ N ≤ 128)| 16 | 16
| _BitInt(N > 128) | RoundUp(N / 128) * 16 | 16
|===

LP64, LP64F, LP64D, and LP64Q:: Use the following type sizes and
Expand Down Expand Up @@ -484,6 +494,12 @@ alignments (based on the LP64 convention):
| float _Complex | 8 | 4
| double _Complex | 16 | 8
| long double _Complex | 32 | 16
| _BitInt(1 ≤ N ≤ 8) | 1 | 1
| _BitInt(9 ≤ N ≤ 16) | 2 | 2
| _BitInt(17 ≤ N ≤ 32) | 4 | 4
| _BitInt(33 ≤ N ≤ 64) | 8 | 8
| _BitInt(65 ≤ N ≤ 128)| 16 | 16
| _BitInt(N > 128) | RoundUp(N / 128) * 16 | 16
|===

The alignment of `max_align_t` is 16.
Expand All @@ -493,6 +509,17 @@ The alignment of `max_align_t` is 16.
Structs and unions are aligned to the alignment of their most strictly aligned
member. The size of any object is a multiple of its alignment.

==== _BitInt (N)

`_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.

`_BitInt(N)` types are stored in little-endian order in memory. Bits in each
byte are allocated from low to high.

Unused bits of the `_BitInt (N)` are unspecified when stored in memory or
register.

=== C/{Cpp} type representations

`char` is unsigned.
Expand Down

0 comments on commit 9e2e1d9

Please sign in to comment.