Hi,
tp
and gp
are two reserved registers in the RISC-V ABI where they both stand for thread pointer and global pointer respectively. The std. mentions that these pointers need to be un-allocatable and user programs should not modify them. They are neither callee saved nor caller saved according to the std ABI.
Calling convention ABI doc: riscv-elf-psabi-doc/riscv-cc.adoc at master · riscv-non-isa/riscv-elf-psabi-doc · GitHub
However, in the clang backend of RISC-V, tp
and gp
are reserved registers but they are also being set as callee saved registers. This is creating some issues for a platform where the tp
register is being used as thread pointer.
For eg, when we modify this register through inline assembly or through a global register variable, clang will emit save-restore code in prolog and epilog of the function effectively undoing the change users want to make.
I find this register to be similar to ARM X18
register which is assigned the role of being a reserved platform register [std. also permits it to being used as a temp. register if the platform does not need this register]. In case of X18
, it is not set as a callee saved register in the default calling convention and there’s another calling convention made available where X18
is a callee saved register.
I’m looking to know if there was any reason for setting tp
and gp
as callee saved or if its a bug in clang.
Reproducible example: Compiler Explorer