@@ -170,6 +170,7 @@ contents of any fixed registers like `gp` and `tp` never change,
170170NOTE: Calling convention for big-endian is *NOT* included in this specification
171171yet, we intend to define that in future version of this specification.
172172
173+ [#integer-cc]
173174=== Integer Calling Convention
174175
175176The base integer calling convention provides eight argument registers,
@@ -216,21 +217,6 @@ Empty structs or union arguments or return values are ignored by C compilers
216217which support them as a non-standard extension. This is not the case for {Cpp},
217218which requires them to be sized types.
218219
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-
234220Arguments passed by reference may be modified by the callee.
235221
236222Floating-point reals are passed the same way as aggregates of the same size;
@@ -639,15 +625,66 @@ The type `size_t` is defined as `unsigned int` for RV32 and `unsigned long` for
639625
640626The type `ptrdiff_t` is defined as `int` for RV32 and `long` for RV64.
641627
628+ === Bit-fields
629+
630+ Bit-fields are packed in little-endian fashion. A bit-field that would span the
631+ alignment boundary of its integer type is padded to begin at the next
632+ alignment boundary. For example, `struct { int x : 10; int y : 12; }` is
633+ a 32-bit type with `x` in bits 9-0, `y` in bits 21-10, and bits 31-22
634+ undefined. By contrast, `struct { short x : 10; short y : 12; }` is a 32-bit
635+ type with `x` in bits 9-0, `y` in bits 27-16, and bits 31-28 and bits 15-10
636+ undefined.
637+
638+ Bit-fields which are larger than their integer types are only present in {Cpp}
639+ and are defined by the _Itanium {Cpp} ABI_ <<itanium-cxx-abi>>. The bit-field
640+ and containing struct are aligned on a boundary corresponding to the largest
641+ integral type smaller than the bit-field, up to 64-bit alignment on RV32 or
642+ 128-bit alignment on RV64. Any bits in excess of the size of the declared type
643+ are treated as padding. For example `struct { char x : 9; char y; }` is a
644+ 24-bit type with `x` in bits 7-0, `y` in bit 23-16, and bits 15-8 undefined;
645+ `struct { char x : 9; char y : 2 }` is a 16-bit type with `x` in bits 7-0, `y`
646+ in bit 10-9, and bits 8 and 15-11 undefined.
647+
648+ Unnamed nonzero length bit-fields allocate space in the same fashion as named
649+ bitfields but do not affect the alignment of the containing struct.
650+
651+ Zero length bit-fields are aligned relative to the start of the containing
652+ struct according to their declared type and, since they must be unnamed, do not
653+ affect the struct alignment. C requies bit-fields on opposite sides of a
654+ zero-length bitfield to be treated as separate memory locations for the
655+ purposes of data races.
656+
642657=== va_list, va_start, and va_arg
643658
644- The `va_list` type is `void*`. A callee with variadic arguments is responsible
645- for copying the contents of registers used to pass variadic arguments to the
646- vararg save area, which must be contiguous with arguments passed on the stack.
647- The `va_start` macro initializes its `va_list` argument to point to the start
648- of the vararg save area. The `va_arg` macro will increment its `va_list`
649- argument according to the size of the given type, taking into account the
650- rules about 2×XLEN aligned arguments being passed in "aligned" register pairs.
659+ The `va_list` type has the same representation as `void*` and points to a
660+ sequence of zero or more arguments with preceding padding for alignment,
661+ formatted and aligned as variadic arguments passed on the stack according to
662+ the integer calling convention (<<integer-cc>>). All standard calling conventions use the
663+ same representation for variadic arguments to allow `va_list` types to be
664+ shared between them.
665+
666+ The `va_start` macro in a function initializes its `va_list` argument to point
667+ to the first address at which a variadic argument could be passed to the
668+ function. If all integer argument registers are used for named formal
669+ arguments, the first variadic argument will have been passed on the stack by
670+ the caller, and the `va_list` can point to the address immediately after the
671+ last named argument passed on the stack, or the `sp` value on entry if no named
672+ arguments were passed on the stack. If some integer argument registers were not
673+ used for named formal arguments, then the first variadic argument may have been
674+ passed in a register. The function is then expected to construct a _varargs
675+ save area_ immediately below the entry `sp` and fill it with the entry values
676+ of all integer argument registers not used for named arguments, in sequence.
677+ The `va_list` value can then be initialized to the start of the varargs save
678+ area, and it will iterate through any variadic arguments passed via registers
679+ before continuing to variadic arguments passed on the stack, if any.
680+
681+ The `va_arg` macro will align its `va_list` argument, fetch a value, and
682+ increment the `va_list` according to the alignment and size of a variadic
683+ argument of the given type, which may not be the same as the alignment and size
684+ of the given type in memory. If the type is passed by reference, the size and
685+ alignment used will be those of a pointer, and the fetched pointer will be used
686+ as the address of the actual argument. The `va_copy` macro is a single pointer
687+ copy and the `va_end` macro performs no operation.
651688
652689=== Vector type sizes and alignments
653690
0 commit comments