@@ -166,9 +166,10 @@ the calling convention are unspecified upon exit, the contents of all
166166callee-saved registers must be restored to what was set on entry, and the
167167contents of any fixed registers like `gp` and `tp` never change.
168168
169-
170- NOTE: Calling convention for big-endian is *NOT* included in this specification
171- yet, we intend to define that in future version of this specification.
169+ NOTE: Big-endian calling conventions follow the same rules as little-endian
170+ calling conventions. The only difference is in the byte ordering of multi-byte
171+ values in memory and registers. Register usage, argument passing, and return
172+ value conventions remain the same.
172173
173174[#integer-cc]
174175=== Integer Calling Convention
@@ -191,14 +192,27 @@ available, the scalar is passed on the stack by value. If exactly one
191192register is available, the low-order XLEN bits are passed in the register and
192193the high-order XLEN bits are passed on the stack.
193194
195+ This register-pair ordering is defined in terms of value significance and is
196+ independent of endianness. For example, on RV32BE a 64-bit scalar returned
197+ in a0/a1 places bits [31:0] (the least-significant XLEN bits) in a0 and
198+ bits [63:32] in a1; memory layout remains big-endian.
199+
200+ NOTE: Defining the register-pair ordering independent of endianness allows
201+ RV32_Zdinx and Zilsd paired load/store paths to be used directly for argument
202+ passing and return without extra swaps. Memory layout remains governed by the
203+ target endianness.
204+
194205Scalars wider than 2×XLEN bits are passed by reference and are replaced in the
195206argument list with the address.
196207
197208Aggregates whose total size is no more than XLEN bits are passed in
198209a register, with the fields laid out as though they were passed in memory. If
199210no register is available, the aggregate is passed on the stack.
200211Aggregates whose total size is no more than 2×XLEN bits are passed in a pair
201- of registers; if only one register is available, the first XLEN bits are passed
212+ of registers with the fields laid out as though they were passed in memory:
213+ the lower-numbered register holds the lower-addressed XLEN-sized chunk of
214+ the aggregate and the higher-numbered register holds the next chunk;
215+ if only one register is available, the first XLEN bits are passed
202216in a register and the remaining bits are passed on the stack. If no registers are
203217available, the aggregate is passed on the stack. Bits unused due to
204218padding, and bits past the end of an aggregate whose size in bits is not
@@ -231,7 +245,10 @@ same manner as named arguments, with one exception. Variadic arguments with
231245even-numbered), or on the stack by value if none is available. After a
232246variadic argument has been passed on the stack, all future arguments will also
233247be passed on the stack (i.e. the last argument register may be left unused due
234- to the aligned register pair rule).
248+ to the aligned register pair rule). For 2×XLEN scalars placed in an aligned
249+ register pair, the lower-numbered register holds the least-significant XLEN bits
250+ and the higher-numbered register holds the most-significant XLEN bits,
251+ regardless of endianness.
235252
236253Values are returned in the same manner as a first named argument of the same
237254type would be passed. If such an argument would have been passed by
0 commit comments