]> git.ipfire.org Git - thirdparty/gcc.git/commit - gcc/config/riscv/riscv.h
RISC-V: Part-1: Select suitable vector registers for vector type args and returns
authorLehua Ding <lehua.ding@rivai.ai>
Tue, 5 Sep 2023 07:44:50 +0000 (15:44 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Wed, 6 Sep 2023 08:11:11 +0000 (16:11 +0800)
commit94a4b93292f8ab19910c844bb9b63e4a68b55d33
tree51624ec7975c3dfe408421fe3f8661efbd9d3e4c
parent80acabb6dd05090db67805cdd358fe974b45e2ed
RISC-V: Part-1: Select suitable vector registers for vector type args and returns

I post the vector register calling convention rules from in the proposal[1]
directly here:

v0 is used to pass the first vector mask argument to a function, and to return
vector mask result from a function. v8-v23 are used to pass vector data
arguments, vector tuple arguments and the rest vector mask arguments to a
function, and to return vector data and vector tuple results from a function.

Each vector data type and vector tuple type has an LMUL attribute that
indicates a vector register group. The value of LMUL indicates the number of
vector registers in the vector register group and requires the first vector
register number in the vector register group must be a multiple of it. For
example, the LMUL of `vint64m8_t` is 8, so v8-v15 vector register group can be
allocated to this type, but v9-v16 can not because the v9 register number is
not a multiple of 8. If LMUL is less than 1, it is treated as 1. If it is a
vector mask type, its LMUL is 1.

Each vector tuple type also has an NFIELDS attribute that indicates how many
vector register groups the type contains. Thus a vector tuple type needs to
take up LMUL×NFIELDS registers.

The rules for passing vector arguments are as follows:

1. For the first vector mask argument, use v0 to pass it. The argument has now
been allocated.

2. For vector data arguments or rest vector mask arguments, starting from the
v8 register, if a vector register group between v8-v23 that has not been
allocated can be found and the first register number is a multiple of LMUL,
then allocate this vector register group to the argument and mark these
registers as allocated. Otherwise, pass it by reference. The argument has now
been allocated.

3. For vector tuple arguments, starting from the v8 register, if NFIELDS
consecutive vector register groups between v8-v23 that have not been allocated
can be found and the first register number is a multiple of LMUL, then allocate
these vector register groups to the argument and mark these registers as
allocated. Otherwise, pass it by reference. The argument has now been allocated.

NOTE: It should be stressed that the search for the appropriate vector register
groups starts at v8 each time and does not start at the next register after the
registers are allocated for the previous vector argument. Therefore, it is
possible that the vector register number allocated to a vector argument can be
less than the vector register number allocated to previous vector arguments.
For example, for the function
`void foo (vint32m1_t a, vint32m2_t b, vint32m1_t c)`, according to the rules
of allocation, v8 will be allocated to `a`, v10-v11 will be allocated to `b`
and v9 will be allocated to `c`. This approach allows more vector registers to
be allocated to arguments in some cases.

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

[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/389

gcc/ChangeLog:

* config/riscv/riscv-protos.h (builtin_type_p): New function for checking vector type.
* config/riscv/riscv-vector-builtins.cc (builtin_type_p): Ditto.
* config/riscv/riscv.cc (struct riscv_arg_info): New fields.
(riscv_init_cumulative_args): Setup variant_cc field.
(riscv_vector_type_p): New function for checking vector type.
(riscv_hard_regno_nregs): Hoist declare.
(riscv_get_vector_arg): Subroutine of riscv_get_arg_info.
(riscv_get_arg_info): Support vector cc.
(riscv_function_arg_advance): Update cum.
(riscv_pass_by_reference): Handle vector args.
(riscv_v_abi): New function return vector abi.
(riscv_return_value_is_vector_type_p): New function for check vector arguments.
(riscv_arguments_is_vector_type_p): New function for check vector returns.
(riscv_fntype_abi): Implement TARGET_FNTYPE_ABI.
(TARGET_FNTYPE_ABI): Implement TARGET_FNTYPE_ABI.
* config/riscv/riscv.h (GCC_RISCV_H): Define macros for vector abi.
(MAX_ARGS_IN_VECTOR_REGISTERS): Ditto.
(MAX_ARGS_IN_MASK_REGISTERS): Ditto.
(V_ARG_FIRST): Ditto.
(V_ARG_LAST): Ditto.
(enum riscv_cc): Define all RISCV_CC variants.
* config/riscv/riscv.opt: Add --param=riscv-vector-abi.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/abi-call-args-1-run.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-1.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-2-run.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-2.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-3-run.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-3.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-4-run.c: New test.
* gcc.target/riscv/rvv/base/abi-call-args-4.c: New test.
* gcc.target/riscv/rvv/base/abi-call-error-1.c: New test.
* gcc.target/riscv/rvv/base/abi-call-return-run.c: New test.
* gcc.target/riscv/rvv/base/abi-call-return.c: New test.
16 files changed:
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.h
gcc/config/riscv/riscv.opt
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-args-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-error-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-return.c [new file with mode: 0644]