The current ABI docs state that the RV32E calling convention (-mabi=ilp32e) may only be used with the RV32E ISA (-march=rv32e). GCC does not produce an error for -march=rv32i -mabi=ilp32e, but it seems that it does ignore the ABI argument and use the ilp32e ABI anyway. I would expect GCC to produce an error instead. $ cat foo.c int foo(int a, int b, int c, int d, int e, int f, int g); int bar() { return foo(1, 2, 3, 4, 5, 6, 7); } $ ./riscv32-unknown-elf-gcc -march=rv32i -mabi=ilp32 foo.c -S -o - .file "foo.c" .option nopic .text .align 2 .globl bar .type bar, @function bar: addi sp,sp,-16 sw ra,12(sp) sw s0,8(sp) addi s0,sp,16 li a6,7 li a5,6 li a4,5 li a3,4 li a2,3 li a1,2 li a0,1 call foo mv a5,a0 mv a0,a5 lw ra,12(sp) lw s0,8(sp) addi sp,sp,16 jr ra .size bar, .-bar .ident "GCC: (GNU) 9.0.0 20180922 (experimental)"
Apologies I pasted the wrong command output in the original report. The invocation demonstrating the bug is below: $ ./riscv32-unknown-elf-gcc -march=rv32i -mabi=ilp32e foo.c -S -o - .file "foo.c" .option nopic .text .align 2 .globl bar .type bar, @function bar: addi sp,sp,-16 sw ra,12(sp) sw s0,8(sp) addi s0,sp,16 li a6,7 li a5,6 li a4,5 li a3,4 li a2,3 li a1,2 li a0,1 call foo mv a5,a0 mv a0,a5 lw ra,12(sp) lw s0,8(sp) addi sp,sp,16 jr ra .size bar, .-bar .ident "GCC: (GNU) 9.0.0 20180922 (experimental)"
One can specify an architecture with FP registers, and an ABI that does not use the FP registers. By the same token, it is reasonable to expect that one should be able to specify an rv32i architecture and use an rv32e ABI with it. In both cases, the unused registers all become call clobbered (aka caller saved). If we go with this interpretation, then the issue here is that we have some architecture checks for TARGET_RVE that should instead be ABI checks for riscv_abi == ABI_ILP32E.
Author: wilson Date: Tue Sep 25 01:27:06 2018 New Revision: 264555 URL: https://gcc.gnu.org/viewcvs?rev=264555&root=gcc&view=rev Log: RISC-V: Fix problems with ilp32e ABI support. gcc/ PR target/87391 * config/riscv/riscv.h (STACK_BOUNDARY): Test riscv_abi == ABI_ILP32E not TARGET_RVE. (ABI_STACK_BOUNDARY, MAX_ARGS_IN_REGISTERS): Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/config/riscv/riscv.h
(In reply to Jim Wilson from comment #2) > One can specify an architecture with FP registers, and an ABI that does not > use the FP registers. By the same token, it is reasonable to expect that > one should be able to specify an rv32i architecture and use an rv32e ABI > with it. In both cases, the unused registers all become call clobbered (aka > caller saved). It's a reasonable expectation, but the ABI docs explicitly state it is an illegal combination. It would make sense to propose a change to the ABI if you want to support -mabi=ilp32e -march=rv32i.
The proposed psABI change is now https://github.com/riscv/riscv-elf-psabi-doc/issues/79
GCC patch applied, riscv-elf-psABI-doc updated, and riscv-c-api-doc updated.