I'm porting some AArch64/ARM64/Apple Silicon assembly code from Linux to macOS.
This code uses all 31 available registers (stack pointer doesn't count) to avoid almost all cases of spilling; the Linux calling conventions allow me to use that many registers.
If pressed, I would admit that spilling one extra register (thus bringing it down to 30 registers used) is feasible as performance would be minimally affected, but if restricted to 29 or less available registers, performance would suffer considerably more. Thus, I'd really like to have at least 30 registers available, and ideally 31.
I just learned from this official Apple document that two extra registers are reserved, beyond what the Linux calling conventions require:
Respect the Purpose of Specific CPU Registers
The ARM standard delegates certain decisions to platform designers. Apple platforms adhere to the following choices:
- The platforms reserve register x18. Don’t use this register.
- The frame pointer register (x29) must always address a valid frame record. Some functions — such as leaf functions or tail calls — may opt not to create an entry in this list As a result, stack traces are always meaningful, even without debug information.
Despite these claims, my code appears to run fine without it.
Now, I fully understand that ignoring such ABI requirements is a Very Bad Thing (TM). However, I'd like to understand exactly how the code may break due to the use of each of x18 and x29.
For instance, from reading the above documentation, my understanding is that x29 is there to support debugging or crash dumps. Suppose I didn't care about debugging this function in particular (which I actually don't), or whether any generated crash dumps are meaningful. In that case, is there any harm to using x29?
As for x18, any idea what is it used for? I'd hypothesize (with zero supporting evidence) that if an interrupt or context switch executes while this code is running, x18 is not saved, and thus corrupts the results of my function once it returns. That would be a more serious condition, and I'd heed the advice to not use x18 in that case.
Also note that the code in question is a leaf function, so there is no issue with breaking any functions called from within it.