Skip to content

Commit 4129bb3

Browse files
authored
Merge pull request #419 from riscv-non-isa/bigint
ABI for _BitInt
2 parents 1e31ed8 + 062f87e commit 4129bb3

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

riscv-cc.adoc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,28 @@ sign-extended to XLEN bits.
185185
When passed in registers or on the stack, floating-point types narrower than
186186
XLEN bits are widened to XLEN bits, with the upper bits undefined.
187187

188+
When passed in registers or on the stack, `_BitInt(N)` types are handled as
189+
follows:
190+
- For N < XLEN: Types are widened to XLEN bits, with upper bits sign-extended
191+
for signed `_BitInt(N)` or zero-extended for unsigned `_BitInt(N)`.
192+
However, for N = 32 in RV64, both signed and unsigned types are sign-extended.
193+
+
194+
- For N = XLEN: Types are passed using the same rules as scalars that are XLEN
195+
bits wide.
196+
- For XLEN < N ≤ 2×XLEN: Types are passed using the same rules as scalars that
197+
are 2×XLEN bits wide.
198+
Any unused bits in the most significant chunk are sign-extended for signed
199+
types or zero-extended for unsigned types.
200+
- For N > 2×XLEN: Types are passed by reference (replaced in the argument list
201+
with the address). When stored in memory, any unused bits in the most
202+
significant chunk are sign-extended for signed types or zero-extended for
203+
unsigned types.
204+
205+
[NOTE]
206+
====
207+
`_BitInt(32)` on RV64 has a special rule because it behaves consistently with regular `int` types.
208+
====
209+
188210
Scalars that are 2×XLEN bits wide are passed in a pair of argument registers,
189211
with the low-order XLEN bits in the lower-numbered register and the high-order
190212
XLEN bits in the higher-numbered register. If no argument registers are
@@ -589,6 +611,11 @@ alignments (based on the ILP32 convention):
589611
| float _Complex | 8 | 4 |
590612
| double _Complex | 16 | 8 |
591613
| long double _Complex | 32 | 16 |
614+
| _BitInt(1 ≤ N ≤ 8) | 1 | 1 |
615+
| _BitInt(9 ≤ N ≤ 16) | 2 | 2 |
616+
| _BitInt(17 ≤ N ≤ 32) | 4 | 4 |
617+
| _BitInt(33 ≤ N ≤ 64) | 8 | 8 |
618+
| _BitInt(N > 64) | RoundUp(N / 64) * 8 | 8 |
592619
|===
593620

594621
LP64, LP64F, LP64D, and LP64Q:: Use the following type sizes and
@@ -618,6 +645,12 @@ alignments (based on the LP64 convention):
618645
| float _Complex | 8 | 4 |
619646
| double _Complex | 16 | 8 |
620647
| long double _Complex | 32 | 16 |
648+
| _BitInt(1 ≤ N ≤ 8) | 1 | 1 |
649+
| _BitInt(9 ≤ N ≤ 16) | 2 | 2 |
650+
| _BitInt(17 ≤ N ≤ 32) | 4 | 4 |
651+
| _BitInt(33 ≤ N ≤ 64) | 8 | 8 |
652+
| _BitInt(65 ≤ N ≤ 128)| 16 | 16 |
653+
| _BitInt(N > 128) | RoundUp(N / 128) * 16 | 16 |
621654
|===
622655

623656
The alignment of `max_align_t` is 16.
@@ -639,6 +672,31 @@ alignment requirement of its elemental type.
639672
The size of the fixed length vector is determined by multiplying the size of its
640673
elemental type by the total number of elements within the vector.
641674

675+
==== _BitInt (N)
676+
677+
`_BitInt (N)` is the type defined in C23, allow user to define an
678+
arbitrary-sized integer type, where N is a postive integer larger than zero.
679+
680+
`_BitInt(N)` types are stored in memory as follows:
681+
- For N ≤ 2×XLEN: Types follow the standard scalar endianness rules.
682+
- For N > 2×XLEN: Types are divided into 2×XLEN-bit chunks. Each chunk follows
683+
the standard scalar endianness rules. The chunk ordering in memory follows
684+
the system endianness: on little-endian systems, lower-addressed chunks contain
685+
less significant bits; on big-endian systems, lower-addressed chunks contain
686+
more significant bits.
687+
688+
NOTE: The big-endian ABI is still experimental and may change in the future.
689+
690+
Unused bits of the `_BitInt(N)` are extended based on the signedness of the
691+
type when stored in memory or register. For signed `_BitInt(N)`, unused bits
692+
are sign-extended from the most significant bit of the N-bit value. For
693+
unsigned `_BitInt(N)`, unused bits are zero-extended.
694+
695+
NOTE: According to the C language specification, `_BitInt(N)` without an
696+
explicit `unsigned` qualifier is treated as signed. For example, `_BitInt(66)`
697+
is signed and will use sign-extension for unused bits, while
698+
`unsigned _BitInt(66)` will use zero-extension.
699+
642700
=== C/{Cpp} Type Representations
643701

644702
`char` is unsigned.

0 commit comments

Comments
 (0)