Closed sebhub closed 6 years ago
s0 is the frame pointer (fp) register. This is documented in the ISA manual, chapter 20, RISC-V Asssembly Programmer's Handbook. The function FP is important enough that it is reasonable for gdb to prefer that name over s0. The lack of mention in the psABI looks like an oversight. I'd suggest a bug report or patch against that document.
Interesting that the assembler doesn't accept it. Maybe it should.
I am not sure if the role of s0 as a frame point is of practical relevance. The following code
void g(void);
int f(int i)
{
g();
return i;
}
compiles to using -Og or -O2 with GCC
f:
addi sp,sp,-16
sw ra,12(sp)
sw s0,8(sp)
mv s0,a0
call g
mv a0,s0
lw ra,12(sp)
lw s0,8(sp)
addi sp,sp,16
jr ra
So, s0 is just the first callee-saved register picked up by GCC. Do you see s0 as a frame pointer in real code? I think the use of the more specific name "fp" instead of the general "s0" is just confusing in GDB.
The GCC default is to omit the frame pointer. If you use -fno-omit-frame-pointer
you'll see s0
used as such.
Just looking at MIPS toolchain sources for comparison, the assembler supports $30, $s8, and $fp as names for the same register. The compiler supports only $30, and $fp. And gdb apparently only supports s8. So the RISC-V port isn't any more confused than the MIPS port.
I think dropping fp from gdb is wrong, as some people will expect "print $fp" to work, and that should work. But we could perhaps put s0 before fp which presumably makes that the preferred reg for gdb disassembly.
Note that gdb is upstream, and the upstream gdb port is not the same as the one in riscv-binutils-gdb, so adding patches here isn't very useful. Patches added here may be lost when we switch to upstream gdb.
@jim-wilson I agree dropping fp seems wrong, but that it would make sense to disassemble it as s0 instead. That would make it consistent with gas/objdump.
I sent a patch to the GDB patches list:
The psABI doesn't mention an "fp" register.
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
It is also not understood by the assembler:
This results in: test.s: Assembler messages: test.s:2: Error: illegal operands `mv fp,fp'
GDB prints register s0 as fp:
Maybe this patch should be applied to GDB: