Is t3 / x28 preserved across calls?
No. t0-t6 are temporary registers and are not preserved across calls.
Temporary register 3 (x28). The psABI classifies t3 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.
t3 / x28 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.
t3 is a caller-saved temporary register, so callees may overwrite it.
If the caller still needs the t3 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 t3, a0, 1
# If t3 is needed after the call, the caller must save it to an ABI-valid location first
call foo
# restore t3 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.