Is t6 / x31 preserved across calls?
No. t0-t6 are temporary registers and are not preserved across calls.
Temporary register 6 (x31). The psABI classifies t6 as a temporary register for caller-managed short-lived values; its value is not preserved across calls.
The psABI marks t0-t6 as temporary registers. They are not callee-saved; callers must save any value that needs to survive a call.
t6 / x31 belongs to the t0-t6 temporary-register group. The psABI marks it not preserved across calls; callers must save any value that needs to survive a call.
t6 is a caller-saved temporary register, so callees may overwrite it.
If the caller still needs the t6 value after a call, it must save it in advance.
Values that must survive calls should usually live in s* registers or on the stack.
addi t6, a0, 1
# If t6 is needed after the call, the caller must save it to an ABI-valid location first
call foo
# restore t6 from that saved location after the call returnsNo. t0-t6 are temporary registers and are not preserved across calls.
The caller must save it before the call, usually to the stack or another suitable location, and restore it afterward.