Skip to content

Commit aa4698a

Browse files
committed
Improve bit-field description
Move bit-field description out of the calling convention since bit-fields representation is also relevant in memory. Prefer bit-field over bitfield for consistency with C and C++. Tidy wording for overlength bit-fields (fixes #410) and align with the Itanium C++ ABI. Add descriptions for zero-length and unnamed bit-fields, mirroring x86-64 language and matching gcc and clang behavior. Signed-off-by: Stefan O'Rear <[email protected]>
1 parent 5ffe5b5 commit aa4698a

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

riscv-cc.adoc

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,21 +216,6 @@ Empty structs or union arguments or return values are ignored by C compilers
216216
which support them as a non-standard extension. This is not the case for {Cpp},
217217
which requires them to be sized types.
218218

219-
Bitfields are packed in little-endian fashion. A bitfield that would span the
220-
alignment boundary of its integer type is padded to begin at the next
221-
alignment boundary. For example, `struct { int x : 10; int y : 12; }` is
222-
a 32-bit type with `x` in bits 9-0, `y` in bits 21-10, and bits 31-22
223-
undefined. By contrast, `struct { short x : 10; short y : 12; }` is a 32-bit
224-
type with `x` in bits 9-0, `y` in bits 27-16, and bits 31-28 and bits 15-10
225-
undefined.
226-
227-
Bitfields may larger than its integer type, bits excess than its integer
228-
type will treat as padding bits, then padding to begin at the next alignment
229-
boundary. For example `struct { char x : 9; char y; }` is a 24 byte type with
230-
`x` in bits 7-0, `y` in bit 23-16, and bits 15-8 undefined,
231-
`struct { char x : 9; char y : 2 }` is a 16-bit type with `x` in bits 7-0, `y`
232-
in bit 10-9, and bit 8, bits 15-11 is undefined.
233-
234219
Arguments passed by reference may be modified by the callee.
235220

236221
Floating-point reals are passed the same way as aggregates of the same size;
@@ -639,6 +624,35 @@ The type `size_t` is defined as `unsigned int` for RV32 and `unsigned long` for
639624

640625
The type `ptrdiff_t` is defined as `int` for RV32 and `long` for RV64.
641626

627+
=== Bit-fields
628+
629+
Bit-fields are packed in little-endian fashion. A bit-field that would span the
630+
alignment boundary of its integer type is padded to begin at the next
631+
alignment boundary. For example, `struct { int x : 10; int y : 12; }` is
632+
a 32-bit type with `x` in bits 9-0, `y` in bits 21-10, and bits 31-22
633+
undefined. By contrast, `struct { short x : 10; short y : 12; }` is a 32-bit
634+
type with `x` in bits 9-0, `y` in bits 27-16, and bits 31-28 and bits 15-10
635+
undefined.
636+
637+
Bit-fields which are larger than their integer types are only present in {Cpp}
638+
and are defined by the _Itanium {Cpp} ABI_ <<itanium-cxx-abi>>. The bit-field
639+
and containing struct are aligned on a boundary corresponding to the largest
640+
integral type smaller than the bit-field, up to 64-bit alignment on RV32 or
641+
128-bit alignment on RV64. Any bits in excess of the size of the declared type
642+
are treated as padding. For example `struct { char x : 9; char y; }` is a
643+
24-bit type with `x` in bits 7-0, `y` in bit 23-16, and bits 15-8 undefined;
644+
`struct { char x : 9; char y : 2 }` is a 16-bit type with `x` in bits 7-0, `y`
645+
in bit 10-9, and bits 8 and 15-11 undefined.
646+
647+
Unnamed nonzero length bit-fields allocate space in the same fashion as named
648+
bitfields but do not affect the alignment of the containing struct.
649+
650+
Zero length bit-fields are aligned relative to the start of the containing
651+
struct according to their declared type and, since they must be unnamed, do not
652+
affect the struct alignment. C requies bit-fields on opposite sides of a
653+
zero-length bitfield to be treated as separate memory locations for the
654+
purposes of data races.
655+
642656
=== va_list, va_start, and va_arg
643657

644658
The `va_list` type is `void*`. A callee with variadic arguments is responsible

0 commit comments

Comments
 (0)