From: Pan Li
According to the issue as below.
https://hub.fgit.cf/riscv-non-isa/riscv-elf-psabi-doc/pull/416
When the mode size of vls integer mode is less than 2 * XLEN, we will
take the gpr/fpr for both the args and the return values. Instead of
the reference. For example the below code:
typedef short v8hi __attribute__ ((vector_size (16)));
v8hi __attribute__((noinline))
add (v8hi a, v8hi b)
{
v8hi r = a + b;
return r;
}
Before this patch:
add:
vsetivli zero,8,e16,m1,ta,ma
vle16.v v1,0(a1) <== arg by reference
vle16.v v2,0(a2) <== arg by reference
vadd.vv v1,v1,v2
vse16.v v1,0(a0) <== return by reference
ret
After this patch:
add:
addi sp,sp,-32
sd a0,0(sp) <== arg by register a0 - a3
sd a1,8(sp)
sd a2,16(sp)
sd a3,24(sp)
addi a5,sp,16
vsetivli zero,8,e16,m1,ta,ma
vle16.v v2,0(sp)
vle16.v v1,0(a5)
vadd.vv v1,v1,v2
vse16.v v1,0(sp)
ld a0,0(sp) <== return by a0 - a1.
ld a1,8(sp)
addi sp,sp,32
jr ra
For vls floating point, the things get more complicated. We follow
the below rules.
1. Vls element count <= 2 and vls size <= 2 * xlen, go fpr.
2. Vls size <= 2 * xlen, go gpr.
3. Vls size > 2 * xlen, go reference.
One exceptions is V2DF mode, we treat vls mode as aggregated and we will
have TFmode here. Unforturnately, the emit_move_multi_word cannot take
care of TFmode elegantly and we go to gpr for V2DF mode.
The riscv regression passed for this patch.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_v_ext_vector_or_tuple_mode_p):
New predicate function for vector or tuple vector.
(riscv_v_vls_mode_aggregate_reg_count): New function to
calculate the gpr/fpr count required by vls mode.
(riscv_gpr_unit_size): New function to get gpr in bytes.
(riscv_fpr_unit_size): New function to get fpr in bytes.
(riscv_v_vls_to_gpr_mode): New function convert vls mode to gpr mode.
(riscv_v_vls_to_fpr_mode): New function convert vls mode to fpr mode.
(riscv_pass_vls_aggregate_in_gpr_or_fpr): New function to return
the rtx of gpr/fpr for vls mode.
(riscv_mode_pass_by_reference_p): New predicate function to
indicate the mode will be passed by reference or not.
(riscv_get_arg_info): Add vls mode handling.
(riscv_pass_by_reference): Return false if arg info has no zero
gpr count.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/vls/def.h: Add helper marcos.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c: New test.
Signed-off-by: Pan Li
---
gcc/config/riscv/riscv.cc | 185 +-
.../rvv/autovec/vls/calling-convention-1.c| 154 +++
.../rvv/autovec/vls/calling-convention-10.c | 51 +
.../rvv/autovec/vls/calling-convention-2.c| 142 ++
.../rvv/autovec/vls/calling-convention-3.c| 130
.../rvv/autovec/vls/calling-convention-4.c| 118 +++
.../rvv/autovec/vls/calling-convention-5.c| 141 +
.../rvv/autovec/vls/calling-convention-6.c| 129
.../rvv/autovec/vls/calling-convention-7.c| 120
.../rvv/autovec/vls/calling-convention-8.c| 43
.../rvv/autovec/vls/calling-convention-9.c| 51 +
.../autovec/vls/calling-convention-run-1.c| 55 ++
.../autovec/vls/calling-convention-run-2.c| 55 ++
.../autovec/vls/calling-convention-run-3.c| 55 ++
.../autovec/vls/calling-convention-run-4.c| 55 ++
.../autovec/vls/calling-convention-run-5.c| 55 ++
.../autovec/vls/calling-convention-run-6.c| 55 ++
.../gcc.target/riscv/rvv/autovec/vls/def.h| 74 +++
18 files changed, 1665 insertions(+), 3 de