Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for Vector Calling Convention #389

Merged
merged 21 commits into from
Jan 8, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
address some comments by sorear
  • Loading branch information
lhtin committed Dec 22, 2023
commit 78c9230fa274069db072dacff7a200bb7d75840d
8 changes: 4 additions & 4 deletions riscv-cc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ the high-order XLEN bits are passed on the stack.
Scalars wider than 2×XLEN bits are passed by reference and are replaced in the
argument list with the address.

The size of scalars with vector type is considered to be unknown, so these scalars always is passed by reference.

NOTE: The vector type mentioned here refers to the type defined https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/master/rvv-intrinsic-rfc.md#type-system[here]

Aggregates whose total size is no more than XLEN bits are passed in
Expand All @@ -175,7 +173,7 @@ of registers; if only one register is available, the first XLEN bits are passed
in a register and the remaining bits are passed on the stack. If no registers are
available, the aggregate is passed on the stack. Bits unused due to
padding, and bits past the end of an aggregate whose size in bits is not
divisible by XLEN, are undefined. If the aggregate contains a field of vector type, it always is passed by reference.
divisible by XLEN, are undefined.

Aggregates or scalars passed on the stack are aligned to the greater of the
type alignment and XLEN bits, but never more than the stack alignment.
Expand Down Expand Up @@ -334,14 +332,16 @@ provided they hold values no more than ABI_FLEN bits wide.

This section applies only to named arguments. Variadic arguments of vector type are passed by reference.

The hardware vector calling convention adds 1 argument register for vector mask type argument and 31 argument registers for vector data and tuple type argument which are v0 and v1-v31, respectively. v0 is used for the first vector mask type argument and the vector mask type return value, the rest of the mask type arguments are treated as vector data type arguments. v1-v31 are also used for the vector data and tuple type return value.
The hardware vector calling convention adds 1 argument register for argument of vector mask type and 31 argument registers for arguments of vector data type and vector tuple type which are v0 and v1-v31, respectively. v0 is used for the first argument of vector mask type and return values of vector mask type, the rest of the arguments of mask type are treated as arguments of vector data type. v1-v31 are also used for return values of vector data type and vector tuple type.
lhtin marked this conversation as resolved.
Show resolved Hide resolved

Vector data type arguments have properties LMUL and NREGS, the current LMUL can be 1/8, 1/4, 1/2, 1, 2, 4, 8, the current NREGS can be 1, 2, 4, 8. For arguments with LMUL less than 1, their LMUL is treated as 1. The LMUL of the vector mask type argument is treated as 1. The NREGS property means the number of registers needed for this argument. For vector data type, NREGS is 1 when LMUL is less than 1, otherwise NREGS is equal to LMUL. If it is possible to find NREGS unused continuous vector register set starting from v1 and its first register is LMUL-aligned, use these registers to pass the argument. Otherwise, the argument is passed by reference.
lhtin marked this conversation as resolved.
Show resolved Hide resolved

vector tuple type arguments have the same LMUL and NREGS properties as the vector data type, but also have the NF property. NREGS equals NF multiplied by LMUL, but cannot exceed 8. The process of finding the argument registers is the same as for the vector data type.

NOTE: The vector mask type, data type and tuple type are defined https://github.com/riscv-non-isa/rvv-intrinsic-doc/blob/master/rvv-intrinsic-rfc.md#type-system[here].

lhtin marked this conversation as resolved.
Show resolved Hide resolved
Vector type are not allowed in struct or union.

Values are returned in the same manner as the first named argument of the same type would be passed.

If a function uses standard vector calling convention variant, the function needs to be annotated with `STO_RISCV_VARIANT_CC`. See xref:riscv-elf.adoc#dynamic-linking[Dynamic Linking] for more details.
Expand Down