ARMv8 is the machine architecture that the Nintendo Switch uses to process compiled code. It has a very large instruction set and register components.
The architecture includes a variety of registers.
The GPRs have two varieties, 64-bit GPRs and 32-bit GPRs.
|X0-X7||64-bit||Used to pass parameters to a function and to return a result. Can be used as scratch.|
|X8||64-bit||Indirect result register. Passes the address of an indirect result.|
|X9-X15||64-bit||Caller-saved temporary registers.|
|X16||64-bit||IP0 (Intra-Procedure Call) temporary register. Can be used for call veneers and as a caller-saved temporary register.|
|X17||64-bit||IP1 (Intra-Procedure Call) temporary register. Can be used for call veneers and as a caller-saved temporary register.|
|X18||64-bit||Platform register, reserved by the platform ABI. For platforms that do not utilize the register, it can be used as a temporary register.|
|X19-X29||64-bit||Callee-saved temporary registers.|
|X30||64-bit||Link register (LR).|
The 32-bit registers use the exact same register types, where it starts with W rather than X.
The architecture has multiple types of registers for floating point.
|S0-S7||32-bit||Used to pass parameters to a function and to return a result. Can be used as scratch.|
|S16-S31||32-bit||These registers do not need to be preserved by the caller, nor the callee.|
The following types of floating point registers exist (only the prefixes):
|D or V||64-bit|
|WZR||32-bit||Zero register. Always contains a 32-bit 0x0 value.|
|XZR||64-bit||Zero register. Always contains a 64-bit 0x0 value.|
|WSP||32-bit||Current stack pointer.|
|SP||64-bit||Current stack pointer.|
|ELR||64-bit||Exception link register.|
|SPSR||64-bit||Saved processor state register.|
Conditional instructions are a simplified way to check for conditions on the same line as an instruction.
|NE||Not equal to.|
|HS||Greater than, equal to. (unsigned)|
|LO||Less than. (unsigned)|
|MI||Minus or negative.|
|PL||Positive or zero.|
|VC||No signed overflow.|
|HI||Greater than. (unsigned)|
|LS||Less than or equal to. (unsigned)|
|GE||Greater than or equal to. (signed)|
|LT||Less than. (signed)|
|GT||Greater than. (signed)|
|LE||Less than or equal to. (signed)|
|AL||Always executed by default.|
As with any other architecture, certain registers are set to be parameter registers, which are registers used to pass a value / reference to another method. As stated above, the first 8 registers (X0-X7 / W0-W7) are used. The order of types can be any pattern, as long as it properly increments the register number. For example:
X0, X1, X2, W3, X4, W5 would be (assuming X is long and W is of type int): long, long, long, int, long, int.
W0, X1, W2 would be: int, long, int.