Custom Code/PowerPC Assembly Cheatsheet: Difference between revisions
Jhmaster2000 (talk | contribs) m (add res) |
Jhmaster2000 (talk | contribs) (add paired shangles instructions) |
||
(46 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{DISPLAYTITLE:PowerPC Assembly Cheatsheet}} |
|||
= '''// WIP''' = |
|||
Instructions, registers and general info cheatsheet for PowerPC 32-bit Big Endian Assembly architecture used by the Wii U. |
|||
<nowiki>#</nowiki> = placeholder |
|||
== How to read this cheatsheet == |
|||
r# = register |
|||
* 64-bit only instructions and behaviors are entirely ignored and removed from this cheatsheet. |
|||
i# = immediate (the subscript numbers next to it is it's size in bits) |
|||
* If a right shift operation does not specify it is sign-fill, it is implicitly zero-fill by default |
|||
* If a value is referred to simply as "value" without specifying bit-count, it is implicitly 32 bits (aka a WORD, integer or float depending on context) |
|||
* multiplications and divisions implicitly result in a 64-bit value |
|||
* C-style casts are used due to being shorter to fit in the small table cells code snippets, but treat them as '''static_cast<T>''' |
|||
* the pseudocode examples are a C++ code representation to visualize the logic of an instruction, it is NOT code that compiles down to that instruction! |
|||
* In most cases where "float" is mentioned in a sentence (not a code snippet where it refers to the type), it usually means "a floating point value" which can be either float or double, not only float. |
|||
* <nowiki>#</nowiki> = placeholder (either a number or a letter, a letter is a labelled placeholder for a number so it may be referenced to by other text) |
|||
* r# = register (shorthand for GPR#) |
|||
* f# = floating point register (shorthand for FPR#) |
|||
* i# = immediate (the subscript numbers next to it is it's size in bits) |
|||
* ui# = unsigned immediate (above is signed) |
|||
* Instruction parameters wrapped in [ ] are optional and can be omitted. |
|||
* <nowiki>*</nowiki> = unsure of exact functionality |
|||
* "Assembly-only" instructions do NOT mean they cannot be generated from C++ compilation but rather they have no direct C++ snippet equivalent and instead are "glue" required to make the processor work. |
|||
{| class="mw-collapsible mw-collapsed" style="min-width: 250px" |
|||
|+'''Pseudocode Typedefs''' |
|||
!<syntaxhighlight lang="c++"> |
|||
typedef unsigned int uint; // 32 bit integer value |
|||
typedef signed int sint; // 32 bit integer value |
|||
typedef unsigned short ushort; // 16 bit integer value |
|||
typedef signed short sshort; // 16 bit integer value |
|||
typedef unsigned char ubyte; // 8 bit integer value |
|||
typedef signed char sbyte; // 8 bit integer value |
|||
float; // 32 bit floating point value |
|||
double; // 64 bit floating point value |
|||
</syntaxhighlight> |
|||
|} |
|||
== == |
|||
ui# = unsigned immediate (above is signed) |
|||
{| class="wikitable mw-collapsible mw-collapsed" style="min-width: 200px" |
|||
<nowiki>*</nowiki> = unsure of functionality |
|||
|+Registers |
|||
!Register |
|||
resources: |
|||
!Name |
|||
!Attributes |
|||
!Bits |
|||
!Purpose |
|||
|- |
|||
! colspan="5" style="text-align: center;" |'''General Purpose Registers (GPRs)''' |
|||
|- |
|||
|r0 |
|||
|GPR0 |
|||
|Volatile + Cross-Module |
|||
|32 |
|||
|General purpose, may be used by function linkage |
|||
|- |
|||
|r1 |
|||
|GPR1 |
|||
|Saved + Reserved |
|||
|32 |
|||
|Reserved for storing the stack frame pointer |
|||
|- |
|||
|r2 |
|||
|GPR2 |
|||
|Reserved |
|||
|32 |
|||
|Reserved for usage by the system |
|||
|- |
|||
|r3 |
|||
|GPR3 |
|||
|Volatile |
|||
|32 |
|||
|Stores 1st argument passed to function calls and their return value |
|||
|- |
|||
|r4 - r10 |
|||
|GPR4 - GPR10 |
|||
|Volatile |
|||
|32 |
|||
|Store from 2nd to 8th argument passed to function calls |
|||
|- |
|||
|r11 - r12 |
|||
|GPR11 - GPR12 |
|||
|Volatile + Cross-Module |
|||
|32 |
|||
|General purpose, may be used by function linkage |
|||
|- |
|||
|r13 |
|||
|GPR13 |
|||
|Reserved |
|||
|32 |
|||
|Reserved for storing the small data area (SDA) pointer |
|||
|- |
|||
|r14 - r31 |
|||
|GPR14 - GPR31 |
|||
|Saved |
|||
|32 |
|||
|General purpose, store generic integer values and pointers |
|||
|- |
|||
! colspan="5" style="text-align: center;" |'''Floating Point Registers (FPRs)''' |
|||
|- |
|||
|f0 |
|||
|FPR0 |
|||
|Volatile |
|||
|64 |
|||
|Store generic floating point numbers |
|||
|- |
|||
|f1 |
|||
|FPR1 |
|||
|Volatile |
|||
|64 |
|||
|Stores 1st float argument passed to function calls and their float return value |
|||
|- |
|||
|f2 - f8 |
|||
|FPR2 - FPR8 |
|||
|Volatile |
|||
|64 |
|||
|Store from 2nd to 8th float argument passed to function calls |
|||
|- |
|||
|f9 - f13 |
|||
|FPR9 - FPR13 |
|||
|Volatile |
|||
|64 |
|||
|Store generic floating point numbers |
|||
|- |
|||
|f14 - f30 |
|||
|FPR14 - FPR30 |
|||
|Saved |
|||
|64 |
|||
|Store generic floating point numbers |
|||
|- |
|||
|f31 |
|||
|FPR31 |
|||
|Saved |
|||
|64 |
|||
|General purpose, used for static chain if needed |
|||
|- |
|||
! colspan="5" style="text-align: center;" |'''Special Purpose Registers (SPRs)''' |
|||
|- |
|||
|PC / IAR |
|||
|Program Counter / Instruction Address Register |
|||
|Internal |
|||
|32 |
|||
|Stores the address of the current instruction (Controlled by the CPU) |
|||
|- |
|||
|LR |
|||
|Link Register |
|||
|Volatile |
|||
|32 |
|||
|Stores the return address for some of the branching instructions |
|||
|- |
|||
|CTR |
|||
|CounT Register |
|||
|Volatile |
|||
|32 |
|||
|Stores the counter of loop iterations for most instructions that perform loops. Also used for virtual function calls as it can contain an address which can be branched to |
|||
|- |
|||
|MSR |
|||
|Machine State Register |
|||
|Special |
|||
|32 |
|||
|Stores bits with information about the CPU and its current state |
|||
|- |
|||
|SRR0 |
|||
|machine status Save/Restore Register 0 |
|||
|Interrupt-only |
|||
|32 |
|||
|When an exception occurs, holds the address where instruction processing should resume when the exception handler returns control to the interrupted process |
|||
|- |
|||
|SRR1 |
|||
|machine status Save/Restore Register 1 |
|||
|Interrupt-only |
|||
|32 |
|||
|Stores machine status (select MSR bits and possibly other status bits as well) on exceptions, in order to restore those values when an <code>rfi</code> instruction is executed |
|||
|- |
|||
|[[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#CR|CR]] |
|||
|Condition Register |
|||
|Volatile / Saved |
|||
|32 |
|||
|Divided in 8 bitfields of 4 bits each to hold different kinds of conditions |
|||
|- |
|||
|[[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]] |
|||
|fiXed point Exception Register |
|||
|Volatile |
|||
|32 |
|||
|Indicates overflows and carry conditions for integer operations and the number of bytes to be transferred by the load/store string indexed instructions |
|||
|- |
|||
|[[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#FPSCR|FPSCR]] |
|||
|Floating Point Status and Control Register |
|||
|Volatile |
|||
|32 |
|||
|Contains all floating point exception signal bits, exception summary bits, exception enable bits, and rounding control bits needed for compliance with the [https://en.wikipedia.org/wiki/IEEE_754 IEEE754] floating point arithmetic standard |
|||
|- |
|||
|[[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#TB|TB]] |
|||
|Time Base |
|||
|Special |
|||
|64 |
|||
|Maintains the time of day and operates interval timers. The '''TB is not a register itself''' but the combined value of the two 32-bit registers [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#TB|TBU]] and [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#TB|TBL]]. |
|||
|- |
|||
|<small>''...''</small> |
|||
|<small>''There are way more but less common SPRs which won't be listed here''</small> |
|||
|<small>''-''</small> |
|||
|<small>''-''</small> |
|||
|<small>''For a full but undescriptive list of all SPRs, visit [https://wiiubrew.org/wiki/Hardware/Espresso wiiubrew.org/Hardware/Espresso]''</small> |
|||
|} |
|||
{| class="wikitable mw-collapsible mw-collapsed" style="min-width: 200px" |
|||
* https://jimkatz.github.io/powerpc_for_dummies (very incomplete, has mistakes) |
|||
|+Instructions |
|||
* http://wiibrew.org/wiki/Assembler_Tutorial#Load_and_Store_Instructions (also has missing instructions but way more accurate and better worded) |
|||
* http://math-atlas.sourceforge.net/devel/assembly/ppc_isa.pdf (official instruction set docs, hard to navigate/search) |
|||
{| class="wikitable" |
|||
|- |
|- |
||
!Instruction |
!Instruction |
||
!Name |
!Name |
||
!Parameters |
!Parameters |
||
Line 23: | Line 209: | ||
!Additional Info |
!Additional Info |
||
|- |
|- |
||
! colspan="5" |Integer Arithmetic Instructions |
|||
|li |
|||
|Load Immediate |
|||
|rA, iX₁₆ |
|||
|<code>rA = iX</code> |
|||
|Loads iX into rA |
|||
|- |
|- |
||
|<code>add</code><ref name=":0">This instruction has a variant with the <code>.</code> suffix, which indicates the instruction will update the [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#CR|CR]] special register based on the result of its operation, otherwise it behaves identically to the normal variant described on the table.</ref><ref name=":1">This instruction has a variant with the <code>o</code> suffix, which indicates the instruction will enable the overflow bit [OV] in the [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]] special register, otherwise it behaves identically to the normal variant described on the table aside from different behavior caused by the overflow bit. This suffix can be combined with the <code>.</code> suffix if the base instruction supports it. (Resulting in an <code>o.</code> suffix)</ref> |
|||
|lis |
|||
|ADD operation |
|||
|Load Immediate Shifted |
|||
|rA, |
|<code>rA, rB, rC</code> |
||
|<code>rA = rB + rC</code> |
|||
|Adds the values of rB and rC together and stores the result in rA |
|||
|Loads iX into the upper 16 bits of rA |
|||
|- |
|- |
||
|<code>addc</code><ref name=":0" /><ref name=":1" /> |
|||
|lwz |
|||
|ADD Carrying |
|||
|Load Word Zero |
|||
|rA, |
|<code>rA, rB, rC</code> |
||
|<code>rA = |
|<code>rA = rB + rC</code> |
||
| |
|Adds the values of rB and rC together and stores the result in rA |
||
|- |
|- |
||
|<code>addi</code> |
|||
|lwzu |
|||
|ADD Immediate |
|||
|Load Word Zero Update |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|rA, iX₁₆(rB) |
|||
|<code>rA |
|<code>rA = rB + iX</code> |
||
| |
|Adds the values of rB and iX together and stores the result in rA |
||
|- |
|- |
||
|<code>addic</code><ref name=":0" /> |
|||
|lwzx |
|||
|ADD Immediate Carrying |
|||
|Load Word Zero Indexed |
|||
|rA, rB, |
|<code>rA, rB, iX₅</code> |
||
|<code>rA = |
|<code>rA = rB + iX</code> |
||
| |
|Adds the values of rB and iX together and stores the result in rA |
||
|- |
|- |
||
|<code>addis</code> |
|||
|lmw * |
|||
|ADD Immediate Shifted |
|||
|Load Multiple Words |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|rA, iX₁₆(rB) |
|||
|<code>rA = rB + (iX << 16)</code> |
|||
|<syntaxhighlight lang="c++"> |
|||
|Adds the values of rB and (iX << 16) together and stores the result in rA |
|||
int EA = rB + iX; |
|||
int N = rA; |
|||
do { |
|||
GPR[N] = *(EA); |
|||
EA = EA + 4; |
|||
N = N + 1; |
|||
} while (N <= 31); |
|||
</syntaxhighlight> |
|||
|Loads GPR[rA] to r31 with the value at the<br />address (rB + iX + N), where N starts at 0 and<br />increments by 4 for each register loaded.<br /><br />Example: (r0 = 29, r1 = 0x20000000)<br /><code>lmw r0, 0x20(r1)</code><br />This will load the following registers like so:<br /><code>r29 = *(0x20000020)</code><br /><code>r30 = *(0x20000024)</code><br /><code>r31 = *(0x20000028)</code> |
|||
|- |
|- |
||
|<code>adde</code><ref name=":0" /><ref name=":1" /> |
|||
|add |
|||
|ADD Extended |
|||
|Addition |
|||
|rA, rB, rC |
|<code>rA, rB, rC</code> |
||
|<code>rA = rB + rC</code> |
|<code>rA = rB + rC + XER[CA]</code> |
||
|Adds the values of rB, rC and [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA] together and stores the result in rA |
|||
| |
|||
|- |
|- |
||
|<code>addme</code><ref name=":0" /><ref name=":1" /> |
|||
|addi |
|||
|ADD to Minus one Extended |
|||
|Add Immediate |
|||
|rA, rB |
|<code>rA, rB</code> |
||
|<code>rA = rB + |
|<code>rA = rB + XER[CA] + 0xFFFFFFFF</code> |
||
|Adds the values of rB, [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA] and 0xFFFFFFFF together and stores the result in rA |
|||
| |
|||
|- |
|- |
||
|<code>addze</code><ref name=":0" /><ref name=":1" /> |
|||
|addis |
|||
|ADD to Zero Extended |
|||
|Add Immediate Shifted |
|||
|rA, rB |
|<code>rA, rB</code> |
||
|<code>rA = rB + |
|<code>rA = rB + XER[CA]</code> |
||
|Adds the values of rB and [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA] together and stores the result in rA |
|||
|- |
|||
|<code>subf</code><ref name=":0" /><ref name=":1" /> |
|||
|SUBtract From |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rC - rB</code> |
|||
|Subtracts the value of rB from rC and stores the result in rA. |
|||
|- |
|||
|<code>subfc</code><ref name=":0" /><ref name=":1" /> |
|||
|SUBtract From, Carrying |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rC - rB</code> |
|||
|Subtracts the value of rB from rC and stores the result in rA. |
|||
|- |
|||
|<code>subfic</code> |
|||
|SUBtract From Immediate Carrying |
|||
|<code>rA, rB, iX₅</code> |
|||
|<code>rA = iX - rB</code> |
|||
|Subtracts the value of iX from rC and stores the result in rA. (CRO is modified) |
|||
|- |
|||
|<code>subfe</code><ref name=":0" /><ref name=":1" /> |
|||
|SUBtract From, Extended |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (rC - rB) + XER[CA]</code> |
|||
|Subtracts the value of rB from rC and adds the value of [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA] to the result, then stores the final result in rA |
|||
|- |
|||
|<code>subfme</code><ref name=":0" /><ref name=":1" /> |
|||
|SUBtract From Minus one Extended |
|||
|<code>rA, rB</code> |
|||
|<code>rA = (XER[CA] - rB) + 0xFFFFFFFF</code> |
|||
|Subtracts the value of rB from [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA], adds 0xFFFFFFFF to the result, then stores the final result in rA |
|||
|- |
|||
|<code>subfze</code><ref name=":0" /><ref name=":1" /> |
|||
|SUBtract From Zero Extended |
|||
|<code>rA, rB</code> |
|||
|<code>rA = XER[CA] - rB</code> |
|||
|Subtracts the value of rB from [[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#XER|XER]][CA] and stores the result in rA |
|||
|- |
|||
|<code>neg</code><ref name=":0" /><ref name=":1" /> |
|||
|NEGate |
|||
|<code>rA, rB</code> |
|||
|<code>rA = 1 - rB</code> |
|||
|Subtracts the value of rB from 1 and stores the result in rA |
|||
|- |
|||
|<code>mulli</code> |
|||
|MULtiply Low Immediate |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|<code>rA = (rB * iX) & 0xFFFFFFFF</code> |
|||
|Multiplies the value of rB by iX and stores the lower 32 bits of the result in rA |
|||
|- |
|||
|<code>mullw</code><ref name=":0" /><ref name=":1" /> |
|||
|MULtiply Low Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (rB * rC) & 0xFFFFFFFF</code> |
|||
|Multiplies the value of rB by the value of rC and stores the lower 32 bits of the result in rA |
|||
|- |
|||
|<code>mulhw</code><ref name=":0" /> |
|||
|MULtiply High Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (rB * rC) >> 32</code> |
|||
|Multiplies the value of rB by the value of rC and stores the upper 32 bits of the result in rA |
|||
|- |
|||
|<code>mulhwu</code><ref name=":0" /> |
|||
|MULtiply High Word Unsigned |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = ((uint)rB * (uint)rC) >> 32</code> |
|||
|Multiplies the unsigned value of rB by the unsigned value of rC and stores the upper 32 bits of the result in rA |
|||
|- |
|||
|<code>divw</code><ref name=":0" /><ref name=":1" /> |
|||
|DIVide Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB / rC</code> |
|||
|Divides the value of rB by the value of rC and stores the result in rA. The remainder is lost. |
|||
|- |
|||
|<code>divwu</code><ref name=":0" /><ref name=":1" /> |
|||
|DIVide Word Unsigned |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (uint)rB / (uint)rC</code> |
|||
|Divides the unsigned value of rB by the unsigned value of rC and stores the result in rA. The remainder is lost. |
|||
|- |
|||
! colspan="5" |Integer Comparison Instructions |
|||
|- |
|||
| colspan="5" | |
|||
* If the optional parameter <code>cr#</code> is omitted, <code>cr0</code> is used. |
|||
* The constant parameter <code>0</code> can only be set to 1 in 64-bit CPUs, so in the case of the Wii U it will always be zero and does effectively nothing. |
|||
|- |
|||
|<code>cmp</code> |
|||
|CoMPare |
|||
|<code>[cr#,] 0, rA, rB</code> |
|||
|''N/A'' |
|||
|The value of rA is compared to the value of rB, the results of the comparison are stored in cr# |
|||
|- |
|||
|<code>cmpi</code> |
|||
|CoMPare Immediate |
|||
|<code>[cr#,] 0, rA, iX</code> |
|||
|''N/A'' |
|||
|The value of rA is compared to iX, the results of the comparison are stored in cr# |
|||
|- |
|||
|<code>cmpl</code> |
|||
|CoMPare Logical |
|||
|<code>[cr#,] 0, rA, rB</code> |
|||
|''N/A'' |
|||
|The unsigned value of rA is compared to the unsigned value of rB, the results of the comparison are stored in cr# |
|||
|- |
|||
|<code>cmpli</code> |
|||
|CoMPare Logical Immediate |
|||
|<code>[cr#,] 0, rA, uiX</code> |
|||
|''N/A'' |
|||
|The unsigned value of rA is compared to uiX, the results of the comparison are stored in cr# |
|||
|- |
|||
|<code>cmpw</code> |
|||
|CoMPare Word |
|||
|<code>rA, rB</code> |
|||
|''N/A'' |
|||
| |
| |
||
|- |
|- |
||
|<code>cmpwi</code> |
|||
|and |
|||
|CoMPare Word Immediate |
|||
|AND Operation |
|||
|<code>rA, iX₁₆</code> |
|||
|rA, rB, rC |
|||
|''N/A'' |
|||
|<code>rA = rB & rC</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>cmplwi</code> |
|||
|andc |
|||
|CoMPare Logical Word Immediate |
|||
|AND Complement |
|||
|rA, rB, rC |
|||
|<code>rA = rB & ~rC</code> |
|||
| |
| |
||
|''N/A'' |
|||
| |
|||
|- |
|||
! colspan="5" |Integer Logical Instructions |
|||
|- |
|- |
||
|andi. |
|<code>andi.</code> |
||
|AND Immediate |
|AND Immediate |
||
|rA, rB, uiX₁₆ |
|<code>rA, rB, uiX₁₆</code> |
||
|<code>rA = rB & uiX</code> |
|<code>rA = rB & uiX</code> |
||
|Performs an AND operation on rB and uiX then stores the result in rA |
|||
| |
|||
|- |
|- |
||
|andis. |
|<code>andis.</code> |
||
|AND Immediate Shifted |
|AND Immediate Shifted |
||
|rA, rB, uiX₁₆ |
|<code>rA, rB, uiX₁₆</code> |
||
|<code>rA = rB & (uiX << 16)</code> |
|||
|Performs an AND operation on rB and (uiX << 16) then stores the result in rA |
|||
|- |
|||
|<code>ori</code> |
|||
|OR Immediate |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|<code><nowiki>rA = rB | iX</nowiki></code> |
|||
|<nowiki>Stores in rA the result of (rB | iX)</nowiki> |
|||
|- |
|||
|<code>oris</code> |
|||
|OR Immediate Shifted |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|<code><nowiki>rA = rB | (iX << 16)</nowiki></code> |
|||
|<nowiki>Stores in rA the result of (rB | (iX << 16))</nowiki> |
|||
|- |
|||
|<code>xori</code> |
|||
|XOR Immediate |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|<code>rA = rB ^ iX</code> |
|||
|Performs an XOR operation on rB and iX then stores the result in rA |
|||
|- |
|||
|<code>xoris</code> |
|||
|XOR Immediate Shifted |
|||
|<code>rA, rB, iX₁₆</code> |
|||
|<code>rA = rB ^ (iX << 16)</code> |
|||
|Performs an XOR operation on rB and (iX << 16) then stores the result in rA |
|||
|- |
|||
|<code>and</code><ref name=":0" /> |
|||
| AND Operation |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB & rC</code> |
|||
|Performs an AND operation on rB and rC then stores the result in rA |
|||
|- |
|||
|<code>or</code><ref name=":0" /> |
|||
|OR operation |
|||
|<code>rA, rB, rC</code> |
|||
|<code><nowiki>rA = rB | rC</nowiki></code> |
|||
|<nowiki>Stores in rA the result of (rB | rC)</nowiki> |
|||
|- |
|||
|<code>xor</code><ref name=":0" /> |
|||
|XOR operation |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB ^ rC</code> |
|||
|Performs an XOR operation on rB and rC then stores the result in rA |
|||
|- |
|||
|<code>nand</code><ref name=":0" /> |
|||
|NAND operation |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = ~(rB & rC)</code> |
|||
|Stores in rA the negated result of (rB & rC) |
|||
|- |
|||
|<code>nor</code><ref name=":0" /> |
|||
|NOR operation |
|||
|<code>rA, rB, rC</code> |
|||
|<code><nowiki>rA = ~(rB | rC)</nowiki></code> |
|||
|<nowiki>Stores in rA the negated result of (rB | rC)</nowiki> |
|||
|- |
|||
|<code>eqv</code> *<ref name=":0" /> |
|||
|EQuiValent |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB == rC</code> |
|||
|Compares if the values of rB and rC are equal and stores the result in rA (?) |
|||
|- |
|||
|<code>andc</code><ref name=":0" /> |
|||
|AND Complement |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB & ~rC</code> |
|||
|Performs an AND operation on rB and negated rC then stores the result in rA |
|||
|- |
|||
|<code>orc</code><ref name=":0" /> |
|||
|OR Complement |
|||
|<code>rA, rB, rC</code> |
|||
|<code><nowiki>rA = rB | ~rC</nowiki></code> |
|||
|<nowiki>Stores in rA the result of (rB | ~rC)</nowiki> |
|||
|- |
|||
|<code>extsb</code><ref name=":0" /> |
|||
|EXTend Sign Byte |
|||
|<code>rA, rB</code> |
|||
|<code>rA = (int8_t)rB</code> |
|||
|Fills the upper 24 bits of rB's value with the sign bit of the stored 8 bit value |
|||
|- |
|||
|<code>extsh</code><ref name=":0" /> |
|||
|EXTend Sign Halfword |
|||
|<code>rA, rB</code> |
|||
|<code>rA = (int16_t)rB</code> |
|||
|Fills the upper 16 bits of rB's value with the sign bit of the stored 16 bit value |
|||
|- |
|||
|<code>cntlzw</code><ref name=":0" /> |
|||
|CouNT Leading Zeros Word |
|||
|<code>rA, rB</code> |
|||
|''N/A'' |
|||
|Stores into rA the number of consecutive leading zero bits in the value of rB |
|||
|- |
|||
! colspan="5" |Integer Rotate Instructions |
|||
|- |
|||
|<code>rlwinm</code><ref name=":0" /> |
|||
|Rotate Left Word Immediate, aNd with Mask |
|||
|<code>rA,{{nbsp}}rB,{{nbsp}}iX₅,{{nbsp}}iY₅,{{nbsp}}iZ₅</code> |
|||
|<syntaxhighlight lang="c++"> |
|<syntaxhighlight lang="c++"> |
||
uint mask = ((uint)-1) << (31 - iZ + iY) >> iY; |
|||
rA = rB & (uiX << 16) |
|||
rA = (rB << iX) | (rB >> (32 - iX)) & mask; |
|||
</syntaxhighlight> |
</syntaxhighlight> |
||
|Rotates the value in rB by iX bits to the left |
|||
The result of the above is AND'ed with the mask specified by iY and iZ |
|||
iY specifies the starting bit of the 1-bits in the mask (0-indexed) |
|||
iZ specifies the end bit of the 1-bits in the mask (0-indexed) |
|||
The final result is stored in rA |
|||
|- |
|||
|<code>rlwnm</code><ref name=":0" /> |
|||
|Rotate Left Word, aNd with Mask |
|||
| |
|||
| |
|||
| |
| |
||
|- |
|- |
||
|<code>rlwimi</code><ref name=":0" /> |
|||
|b |
|||
|Rotate Left Word Immediate, Mask Insert |
|||
|Branch |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
! colspan="5" |Integer Shift Instructions |
|||
|bl |
|||
|- |
|||
|Branch And Link |
|||
|<code>slw</code><ref name=":0" /> |
|||
|Shift Left Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = rB << rC</code> |
|||
|Shifts the value in rB by the value in rC to the left and stores the result in rA |
|||
|- |
|||
|<code>srw</code><ref name=":0" /> |
|||
|Shift Right Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (unsigned)rB >> rC</code> |
|||
|Shifts the value in rB by the value in rC to the right and stores the result in rA |
|||
|- |
|||
|<code>srawi</code><ref name=":0" /> |
|||
|Shift Right Algebraic Word Immediate |
|||
|<code>rA, rB, iX₅</code> |
|||
|<code>rA = (signed)rB >> iX</code> |
|||
|Shifts the value in rB by iX to the right and stores the result in rA |
|||
Unlike regular zero-fill right shift operations, this one sign-fills the vacant bits |
|||
|- |
|||
|<code>sraw</code><ref name=":0" /> |
|||
|Shift Right Algebraic Word |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = (signed)rB >> rC</code> |
|||
|Shifts the value in rB by the value in rC to the right and stores the result in rA |
|||
Unlike regular zero-fill right shift operations, this one sign-fills the vacant bits |
|||
|- |
|||
|<code>slwi</code> |
|||
|Shift Left Word Immediate |
|||
|<code>rA, rB, iX₅</code> |
|||
|<code>rA = rB << iX</code> |
|||
|Shifts the value in rB by iX to the left and stores the result in rA |
|||
|- |
|||
|<code>srwi</code> |
|||
|Shift Right Word Immediate |
|||
|<code>rA, rB, iX₅</code> |
|||
|<code>rA = (unsigned)rB >> iX</code> |
|||
|Shifts the value in rB by iX to the right and stores the result in rA |
|||
|- |
|||
! colspan="5" |Floating Point Arithmetic Instructions |
|||
|- |
|||
! colspan="5" |Floating Point Multiply-Add Instructions |
|||
|- |
|||
! colspan="5" |Floating Point Rounding & Conversion Instructions |
|||
|- |
|||
! colspan="5" |Floating Point Comparison Instructions |
|||
|- |
|||
! colspan="5" |[[Custom Code/PowerPC ASM Cheatsheet/Special Purpose Registers#FPSCR|Floating Point Status and Control Register]] Instructions |
|||
|- |
|||
! colspan="5" |Floating Point Move Instructions |
|||
|- |
|||
|<code>fmr</code><ref name=":0" /> |
|||
|Float Move Register |
|||
|<code>fA, fB</code> |
|||
|<code>fA = fB</code> |
|||
|Copies the value of fB into fA (Despite the instruction name, fB is preserved) |
|||
|- |
|||
|<code>fneg</code><ref name=":0" /> |
|||
|Float Negate |
|||
|<code>fA, fB</code> |
|||
|<code>fA = -fB</code> |
|||
|Negates the value of fB and stores the result in fA |
|||
|- |
|||
|<code>fabs</code><ref name=":0" /> |
|||
|Float Absolute |
|||
|<code>fA, fB</code> |
|||
|<code>fA = abs(fB)</code> |
|||
|The absolute value of fB is stored into rA |
|||
|- |
|||
|<code>fnabs</code><ref name=":0" /> |
|||
|Float Negative Absolute |
|||
|<code>fA, fB</code> |
|||
|<code>fA = -abs(fB)</code> |
|||
|The negative absolute value of fB is stored into rA |
|||
|- |
|||
! colspan="5" |Floating Point Load Instructions |
|||
|- |
|||
|<code>lfs</code> |
|||
|Load Float Single |
|||
|<code>fA, iX₁₆(rA)</code> |
|||
|<code>fA = (float)(*(rA + iX))</code> |
|||
|Loads the value at the address (rA + iX) casted to float into fA. |
|||
|- |
|||
|<code>lfsx</code> |
|||
|Load Float Single indeXed |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>lfsu</code> |
|||
|blr |
|||
|Load Float Single Update |
|||
|Branch To Link Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>lfsux</code> |
|||
|beq |
|||
|Load Float Single Update indeXed |
|||
|Branch If Equal |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>lfd</code> |
|||
|bne |
|||
|Load Float Double |
|||
|Branch If Not Equal |
|||
|<code>fA, iX₁₆(rA)</code> |
|||
|<code>fA = (double)(*(rA + iX))</code> |
|||
|Loads the 64 bit value at the address (rA + iX) casted to double into fA. |
|||
|- |
|||
|<code>lfdx</code> |
|||
|Load Float Double indeXed |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>lfdu</code> |
|||
|bgt |
|||
|Load Float Double Update |
|||
|Branch If Greater Than |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>lfdux</code> |
|||
|blt |
|||
|Load Float Double Update indeXed |
|||
|Branch If Less Than |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
! colspan="5" |Floating Point Store Instructions |
|||
|ble |
|||
|- |
|||
|Branch If Less Than Or Equal To |
|||
|<code>stfs</code> |
|||
|STore Float Single |
|||
|<code>fA, iX₁₆(rA)</code> |
|||
|<code>*(rA + iX) = (float)fA</code> |
|||
|Stores the value of fA casted to float at the memory address (rA + iX) |
|||
|- |
|||
|<code>stfsx</code> |
|||
|STore Float Single indeXed |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfsu</code> |
|||
|bge |
|||
|STore Float Single Update |
|||
|Branch If Greater Than Or Equal To |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfsux</code> |
|||
|bng |
|||
|STore Float Single Update indeXed |
|||
|Branch If Not Greater Than |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfd</code> |
|||
|bnl |
|||
|STore Float Double |
|||
|Branch If Not Less Than |
|||
|<code>fA, iX₁₆(rA)</code> |
|||
|<code>*(rA + iX) = fA</code> |
|||
|Stores the 64 bit value of fA at the memory address (rA + iX) |
|||
|- |
|||
|<code>stfdx</code> |
|||
|STore Float Double indeXed |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfdu</code> |
|||
|bso |
|||
|STore Float Double Update |
|||
|Branch If Summary Overflow |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfdux</code> |
|||
|bns |
|||
|STore Float Double Update indeXed |
|||
|Branch If Not Summary Overflow |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>stfiwx</code> |
|||
|bun |
|||
|STore Float as Integer Word indeXed |
|||
|Branch If Unordered |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
! colspan="5" |Paired Singles Instructions (WIP)<ref>These instructions are exclusive to the '''Broadway''' (Wii) and '''Espresso''' (Wii U) processors, they are not part of standard PowerPC Assembly and never existed outside the Wii and Wii U.</ref> |
|||
|bnu |
|||
|- |
|||
|Branch If Not Unordered |
|||
|<code>psq_l</code> |
|||
|<small>Paired Single</small> Quantized Load |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_lx</code> |
|||
|bctr |
|||
|<small>Paired Single</small> Quantized Load indeXed |
|||
|Branch To Count Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_lu</code> |
|||
|bctrl |
|||
|<small>Paired Single</small> Quantized Load Update |
|||
|Branch To Count Register And Link |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_lux</code> |
|||
|bdnz |
|||
|<small>Paired Single</small> Quantized Load Update indeXed |
|||
|Branch If Decremented Count Register Not Zero |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_st</code> |
|||
|bdnzt |
|||
|<small>Paired Single</small> Quantized Store |
|||
|Branch If Decremented Count Register Not Zero And If Condition True |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_stx</code> |
|||
|bdnzf |
|||
|<small>Paired Single</small> Quantized Store indeXed |
|||
|Branch If Decremented Count Register Not Zero And If Condition False |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_stu</code> |
|||
|bdz |
|||
|<small>Paired Single</small> Quantized Store Update |
|||
|Branch if Decremented Count Register Zero |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>psq_stux</code> |
|||
|cmp |
|||
|<small>Paired Single</small> Quantized Store Update indeXed |
|||
|Compare |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_abs</code> |
|||
|cmpwi |
|||
|<small>Paired Single</small> ABSolute |
|||
|Compare Word Immediate |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_add</code> |
|||
|cmplwi |
|||
|<small>Paired Single</small> ADD |
|||
|Compare Logical Word Immediate |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_cmpo0</code> |
|||
|cntlzw |
|||
|<small>Paired Single</small> CoMPare Ordered high(0) |
|||
|Count Leading Zeros Word |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_cmpo1</code> |
|||
|eieio |
|||
|<small>Paired Single</small> CoMPare Ordered low(1) |
|||
|Enforce In-Order Execution of I/O |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_cmpu0</code> |
|||
|eqv |
|||
|<small>Paired Single</small> CoMPare Unordered high(0) |
|||
|Equivalent |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
|<code>rA = rB == rC</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_cmpu1</code> |
|||
|extsb |
|||
|<small>Paired Single</small> CoMPare Unordered low(1) |
|||
|Extend Sign Byte |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = (int8_t)rB</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_div</code> |
|||
|extsh |
|||
|<small>Paired Single</small> DIVide |
|||
|Extend Sign Halfword |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = (int16_t)rB</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_madd</code> |
|||
|extsw |
|||
|<small>Paired Single</small> Multiply & ADD |
|||
|Extend Sign Word |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = (int32_t)rB</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_madds0</code> |
|||
|mr |
|||
|<small>Paired Single</small> Multiply & ADD Scalar high(0) |
|||
|Move Register |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = rB</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_madds1</code> |
|||
|mflr |
|||
|<small>Paired Single</small> Multiply & ADD Scalar low(1) |
|||
|Move From Link Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_merge00</code> |
|||
|mtlr |
|||
|<small>Paired Single</small> MERGE high(00) |
|||
|Move To Link Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_merge01</code> |
|||
|mtctr |
|||
|<small>Paired Single</small> MERGE direct(01) |
|||
|Move To Count Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_merge10</code> |
|||
|mtspr |
|||
|<small>Paired Single</small> MERGE swapped(10) |
|||
|Move To Special Purpose Register |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_merge11</code> |
|||
|mulli |
|||
|<small>Paired Single</small> MERGE low(11) |
|||
|Multiply Low Immediate |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_mr</code> |
|||
|nand |
|||
|<small>Paired Single</small> Move Register |
|||
|NAND Operation |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
|<code>rA = ~(rB & rC)</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_msub</code> |
|||
|neg |
|||
|<small>Paired Single</small> Multiply & SUBtract |
|||
|Negate |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = ~rB + 1</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_mul</code> |
|||
|nor |
|||
|<small>Paired Single</small> MULtiply |
|||
|NOR Operation |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
| `rA="~(rB" |<code><nowiki>rA = ~(rB | rC)</nowiki></code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_muls0</code> |
|||
|not |
|||
|<small>Paired Single</small> MULtiply Scalar high(0) |
|||
|NOT Operation |
|||
| |
|||
|rA, rB |
|||
| |
|||
|<code>rA = ~rB</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_muls1</code> |
|||
|or |
|||
|<small>Paired Single</small> MULtiply Scalar low(1) |
|||
|OR Operation |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
| `rA="rB" |<code><nowiki>rA = rB | rC</nowiki></code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_nabs</code> |
|||
|orc |
|||
|<small>Paired Single</small> Negative ABSolute |
|||
|OR Complement |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
| `rA="rB" |<code><nowiki>rA = rB | ~rC</nowiki></code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_neg</code> |
|||
|ori |
|||
|<small>Paired Single</small> NEGate |
|||
|OR Immediate |
|||
| |
|||
|rA, rB, iX₁₆ |
|||
| |
|||
| `rA="rB" |<code><nowiki>rA = rB | iX</nowiki></code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_nmadd</code> |
|||
|oris |
|||
|<small>Paired Single</small> Negative Multiply & ADD |
|||
|OR Immediate Shifted |
|||
| |
|||
|rA, rB, iX₁₆ |
|||
| |
|||
| `rA="rB" |<code><nowiki>rA = rB | (iX << 16)</nowiki></code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_nmsub</code> |
|||
|rlwinm |
|||
|<small>Paired Single</small> Negative Multiply & SUBtract |
|||
|Rotate Left Word Immediate Then AND With Mask |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_res</code> |
|||
|slw |
|||
|<small>Paired Single</small> Reciprocal EStimate |
|||
|Shift Left Word |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_rsqrte</code> |
|||
|slwi |
|||
|<small>Paired Single</small> Reciprocal SQuareRooT Estimate |
|||
|Shift Left Word Immediate |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_sel</code> |
|||
|sraw |
|||
|<small>Paired Single</small> SELect |
|||
|Shift Right Algebraic Word |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_sub</code> |
|||
|stwu |
|||
|<small>Paired Single</small> SUBtract |
|||
|Store Word And Update |
|||
| |
| |
||
| |
| |
||
| |
| |
||
|- |
|- |
||
|<code>ps_sum0</code> |
|||
|xor |
|||
|<small>Paired Single</small> vector SUM high(0) |
|||
|XOR Operation |
|||
| |
|||
|rA, rB, rC |
|||
| |
|||
|<code>rA = rB ^ rC</code> |
|||
| |
| |
||
|- |
|- |
||
|<code>ps_sum1</code> |
|||
|xori |
|||
|<small>Paired Single</small> vector SUM low(1) |
|||
|XOR Immediate |
|||
| |
|||
|rA, rB, iX₁₆ |
|||
| |
|||
|<code>rA = rB ^ iX</code> |
|||
| |
| |
||
|- |
|- |
||
! colspan="5" |Integer Load Instructions |
|||
|xoris |
|||
|- |
|||
|XOR Immediate Shifted |
|||
|<code>lbz</code> |
|||
|rA, rB, iX₁₆ |
|||
|Load Byte Zero-fill |
|||
|<code>rA = rB ^ (iX << 16)</code> |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>rA = (ubyte)(*(rB + iX))</code> |
|||
|Loads the 8 bit value at the address (rB + iX) into rA |
|||
|- |
|||
|<code>lbzx</code> |
|||
|Load Byte Zero-fill indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lbzu</code> |
|||
|Load Byte Zero-fill Update |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lbzux</code> |
|||
|Load Byte Zero-fill Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhz</code> |
|||
|Load Halfword Zero-fill |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>rA = (ushort)(*(rB + iX))</code> |
|||
|Loads the 16 bit value at the address (rB + iX) into rA |
|||
|- |
|||
|<code>lhzx</code> |
|||
|Load Halfword Zero-fill indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhzu</code> |
|||
|Load Halfword Zero-fill Update |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhzux</code> |
|||
|Load Halfword Zero-fill Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lha</code> |
|||
|Load Halfword Algebraic |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhax</code> |
|||
|Load Halfword Algebraic indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhau</code> |
|||
|Load Halfword Algebraic Update |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lhaux</code> |
|||
|Load Halfword Algebraic Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lwz</code> |
|||
|Load Word Zero-fill |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>rA = *(rB + iX)</code> |
|||
|Loads the value at the address (rB + iX) into rA |
|||
|- |
|||
|<code>lwzx</code> |
|||
|Load Word Zero-fill indeXed |
|||
|<code>rA, rB, rC</code> |
|||
|<code>rA = *(rB + rC)</code> |
|||
|Loads the value at the address (rB + rC) into rA |
|||
|- |
|||
|<code>lwzu</code> |
|||
|Load Word Zero-fill Update |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<syntaxhighlight lang="c++"> |
|||
rA = *(rB + iX); |
|||
rB = rB + iX; |
|||
</syntaxhighlight> |
|||
|Loads the value at the address (rB + iX) into rA<br />Then loads rB with the address (rB + iX) |
|||
|- |
|||
|<code>lwzux</code> |
|||
|Load Word Zero-fill Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>lmw</code> * |
|||
|Load Multiple Words |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<syntaxhighlight lang="c++">int EA = rB + iX; |
|||
int N = rA; |
|||
do { |
|||
GPR[N] = *(EA); |
|||
EA = EA + 4; |
|||
N = N + 1; |
|||
} while (N <= 31);</syntaxhighlight> |
|||
|Loads GPR[rA] to r31 with the value at the address (rB + iX + N), |
|||
where N starts at 0 and increments by 4 for each register loaded. |
|||
<u>Example</u>: Assume '''r0 = 29''' and '''r1 = 0x20000000'''<br /><code>lmw r0, 0x20(r1)</code><br />This will load the following registers like so:<br /><code>r29 = *(0x20000020)</code><br /><code>r30 = *(0x20000024)</code><br /><code>r31 = *(0x20000028)</code> |
|||
|- |
|||
! colspan="5" |Integer Store Instructions |
|||
|- |
|||
|<code>stb</code> |
|||
|STore Byte |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>*(rB + iX) = (ubyte)rA</code> |
|||
|Stores the 8 bit value of rA at the memory address (rB + iX) |
|||
|- |
|||
|<code>stbx</code> |
|||
|STore Byte indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>stbu</code> |
|||
|STore Byte Update |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>stbux</code> |
|||
|STore Byte Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>sth</code> |
|||
|STore Halfword |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>*(rB + iX) = (ushort)rA</code> |
|||
|Stores the 16 bit value of rA at the memory address (rB + iX) |
|||
|- |
|||
|<code>sthx</code> |
|||
|STore Halfword indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>sthu</code> |
|||
|STore Halfword Update |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>sthux</code> |
|||
|STore Halfword Update indeXed |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>stw</code> |
|||
|STore Word |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>*(rB + iX) = rA</code> |
|||
|Stores the value of rA at the memory address (rB + iX) |
|||
|- |
|||
|<code>stwx</code> |
|||
|STore Word indeXed |
|||
|<code>rA, rB, rC</code> |
|||
|<code>*(rB + rC) = rA</code> |
|||
|Stores the value of rA at the memory address (rB + rC) |
|||
|- |
|||
|<code>stwu</code> |
|||
|STore Word And Update |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>*(rB + iX) = rA</code> |
|||
<code>rB = rB + iX</code> |
|||
|Stores the value of rA at the memory address (rB + iX) |
|||
Stores the computed address (rB + iX) into rB |
|||
|- |
|||
|<code>stwux</code> |
|||
|STore Word And Update indeXed |
|||
|<code>rA, rB, rC</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>stmw</code> * |
|||
|STore Multiple Words |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
! colspan="5" |Little Endian Integer Load & Store Instructions |
|||
|- |
|||
! colspan="5" |Integer Load and Store Strings Instructions |
|||
|- |
|||
| |
|||
| |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
| |
|||
| |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
| |
|||
| |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
! colspan="5" |Branch Instructions |
|||
|- |
|||
|<code>b</code> |
|||
|Branch |
|||
|<code>iX₂₄</code> |
|||
|<code>goto LABEL</code> |
|||
|Jumps from the current address to IAR + iX, either up or down |
|||
|- |
|||
|<code>ba</code> |
|||
|Branch Absolute |
|||
|<code>iX₂₄</code> |
|||
|<code>goto LABEL</code> |
|||
|Jumps from the current address to the address iX, either up or down |
|||
|- |
|||
|<code>bl</code> |
|||
|Branch & Link |
|||
|<code>iX₂₄</code> |
|||
|<code>((void (*)())IAR + iX)()</code> |
|||
|Jumps from the current address to IAR + iX, either up or down |
|||
Also stores the address of the instruction directly below itself in LR |
|||
''This is the most common instruction used for calling a function'' |
|||
|- |
|||
|<code>bla</code> |
|||
|Branch & Link Absolute |
|||
|<code>iX₂₄</code> |
|||
|<code>((void (*)())IAR + iX)()</code> |
|||
|Jumps from the current address to the address iX, either up or down |
|||
Also stores the address of the instruction directly below itself in LR |
|||
|- |
|||
|<code>bc</code> |
|||
|Branch Conditional |
|||
|<code>BO, BI, iX</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bca</code> |
|||
|Branch Conditional Absolute |
|||
|<code>BO, BI, iX</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bcl</code> |
|||
|Branch Conditional & Link |
|||
|<code>BO, BI, iX</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bcla</code> |
|||
|Branch Conditional & Link Absolute |
|||
|<code>BO, BI, iX</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bclr</code> |
|||
|Branch Conditional to Link Register |
|||
|<code>BO, BI, BH</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bclrl</code> |
|||
|Branch Conditional to Link Register & Link |
|||
|<code>BO, BI, BH</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bcctr</code> |
|||
|Branch Conditional to CounT Register |
|||
|<code>BO, BI, BH</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>bcctrl</code> |
|||
|Branch Conditional to CounT Register & Link |
|||
|<code>BO, BI, BH</code> |
|||
| |
|||
| |
|||
|- |
|||
| |
|||
| |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>blr</code> |
|||
|Branch to Link Register |
|||
|''N/A'' |
|||
|<code>return <r3 / f1></code> |
|||
|Jumps from the current address to the address stored in LR |
|||
This is essentially the '''return''' statement of a function, with the value currently loaded into either r3 or f1 holding the returned value, depending on if the return type is a fixed or floating point value |
|||
|- |
|||
|<code>beq</code> |
|||
|Branch if EQual |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x == y) goto LABEL</code> |
|||
|If the EQ bit in CR0 is 1, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>bne</code> |
|||
|Branch if Not Equal |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x != y) goto LABEL</code> |
|||
|If the EQ bit in CR0 is 0, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>bgt</code> |
|||
|Branch if Greater Than |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x > y) goto LABEL</code> |
|||
|If the GT bit in CR0 is 1, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>blt</code> |
|||
|Branch if Less Than |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x < y) goto LABEL</code> |
|||
|If the LT bit in CR0 is 1, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>bge</code> |
|||
|Branch if Greater than or Equal |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x >= y) goto LABEL</code> |
|||
|If either the GT bit or EQ bit in CR0 is 1, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>ble</code> |
|||
|Branch if Less than or Equal |
|||
|<code>iX₂₄</code> |
|||
|<code>if (x <= y) goto LABEL</code> |
|||
|If either the LT bit or EQ bit in CR0 is 1, jumps from the current address to IAR + iX |
|||
Otherwise, does nothing |
|||
|- |
|||
|<code>bng</code> |
|||
|Branch if Not Greater than |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bnl</code> |
|||
| Branch if Not Less than |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bso</code> |
|||
|Branch if Summary Overflow |
|||
|??? |
|||
|??? |
|||
|??? |
|||
|- |
|||
|<code>bns</code> |
|||
|Branch if Not Summary overflow |
|||
|??? |
|||
|??? |
|||
|??? |
|||
|- |
|||
|<code>bun</code> |
|||
|Branch if UNordered |
|||
|??? |
|||
|??? |
|||
|??? |
|||
|- |
|||
|<code>bnu</code> |
|||
|Branch if Not Unordered |
|||
| ??? |
|||
|??? |
|||
|??? |
|||
|- |
|||
|<code>bctr</code> |
|||
|Branch to CounT Register |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bctrl</code> |
|||
|Branch to CounT Register and Link |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bdnz</code> |
|||
|Branch if Decremented count register Not Zero |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bdnzt</code> |
|||
|Branch if Decremented count register Not Zero and if condition True |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bdnzf</code> |
|||
|Branch if Decremented count register Not Zero and if condition False |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>bdz</code> |
|||
|Branch if Decremented count register Zero |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
! colspan="5" |Condition Register Logical Instructions |
|||
|- |
|||
! colspan="5" |Move to/from Special Purpose Registers Instructions |
|||
|- |
|||
|<code>mflr</code> |
|||
|Move From Link Register |
|||
|<code>rA</code> |
|||
|<code>rA = LR</code> |
|||
|Copies the value of LR into rA |
|||
|- |
|||
|<code>mtlr</code> |
|||
|Move To Link Register |
|||
|<code>rA</code> |
|||
|<code>LR = rA</code> |
|||
|Copies the value of rA into the LR |
|||
|- |
|||
|<code>mtctr</code> |
|||
|Move To CounT Register |
|||
|<code>rA</code> |
|||
|<code>CTR = rA</code> |
|||
|Copies the value of rA into the CTR |
|||
|- |
|||
|<code>mtfsf</code> * |
|||
|Move To FpScr Fields |
|||
|<code>UNK1, fA</code> |
|||
|??? |
|||
|Copies the value of fA into the FPSCR under the control of the field mask in UNK1 |
|||
|- |
|||
|<code>mtfsb1</code> |
|||
|Move To FpScr Bit 1 |
|||
|<code>iX<sub>?</sub></code> |
|||
|<code><nowiki>FPSCR = FPSCR | 0b1 << iX - 1</nowiki></code> |
|||
|Sets bit iX of the FPSCR register to 1 |
|||
|- |
|||
| |
|||
| |
|||
| |
|||
| |
|||
| |
|||
|- |
|||
|<code>mtspr</code> |
|||
|Move To Special Purpose Register |
|||
|<code>SPR, rA</code> |
|||
|<code>SPRs[SPR] = rA</code> |
|||
|Copies the value of rA into the special purpose register SPR |
|||
|- |
|||
|<code>mfspr</code> |
|||
|Move From Special Purpose Register |
|||
|<code>rA, SPR</code> |
|||
|<code>rA = SPRs[SPR]</code> |
|||
|Copies the value of special purpose register SPR into rA |
|||
|- |
|||
|<code>mfmsr</code> |
|||
|Move From Machine State Register |
|||
|<code>rA</code> |
|||
|<code>rA = MSR</code> |
|||
|Copies the value of MSR into rA |
|||
|- |
|||
|<code>mftb</code> |
|||
|Move From Time Base |
|||
|<code>rA [, TBR]</code> |
|||
|''N/A'' |
|||
|If TBR == 268, the value of TBL (Time Base Lower) is copied into rA |
|||
If TBR == 269, the value of TBU (Time Base Upper) is copied into rA |
|||
If TBR is omitted, 268 is used as default value |
|||
|- |
|||
|<code>mftbu</code> |
|||
|Move From Time Base Upper |
|||
|<code>rA</code> |
|||
|''N/A'' |
|||
|Copies the value of TBU (Time Base Upper) into rA |
|||
|- |
|||
! colspan="5" |Trap Instructions |
|||
|- |
|||
|<code>twi</code> |
|||
|Trap Word Immediate |
|||
|<code>TO, rA, iX</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>tw</code> |
|||
|Trap Word |
|||
|<code>TO, rA, rB</code> |
|||
| |
|||
| |
|||
|- |
|||
! colspan="5" |Memory Synchronization Instructions |
|||
|- |
|||
|<code>lwarx</code> |
|||
|Load Word And Reserve indeXed |
|||
|<code>rA, rB, rC</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>stwcx.</code> |
|||
|STore Word Conditional indeXed |
|||
|<code>rA, rB, rC</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>sync</code> |
|||
|SYNChronize |
|||
|<code>L</code> |
|||
|''<small>Assembly-only instruction</small>'' |
|||
|Delays all following instructions until all previous instructions required for context are complete. |
|||
|- |
|||
|<code>eieio</code> |
|||
|Enforce In-order Execution of I/O |
|||
|''N/A'' |
|||
|''<small>Assembly-only instruction</small>'' |
|||
|''"Provides an ordering function for the effects of loads and stores executed by the processor."'' |
|||
|- |
|||
|<code>isync</code> |
|||
|Instruction SYNChronize |
|||
|''N/A'' |
|||
|''<small>Assembly-only instruction</small>'' |
|||
|Delays all following instructions until all previous instructions required for context are complete. |
|||
Additionally discards all prefetched instructions for a context reset. |
|||
|- |
|||
! colspan="5" |Cache Control Instructions |
|||
|- |
|||
|<code>dcbz_l</code> |
|||
|Data Cache Block Zero and Lock |
|||
|<code>rA, rB</code> |
|||
|''<small>Assembly-only instruction</small>'' |
|||
|''Too complex.''<ref name=":2">This instruction is too complex to be explained in brief terms on a cheatsheet. Most instructions of this kind are extremely rare and you are unlikely to ever encounter them, and even if you do, even less likely that you will need to know its behavior to understand the surrounding code. If you really need to learn this instruction refer to the processor manuals.</ref>All you might need to know about this instruction is rA+rB form an address input, and it does not modify any registers. |
|||
|- |
|||
|<code>dcbi</code> |
|||
|Data Cache Block Invalidate |
|||
|<code>rA, rB</code> |
|||
|''<small>Assembly-only instruction</small>'' |
|||
|''Too complex.''<ref name=":2" /> |
|||
|- |
|||
! colspan="5" |External Control Instructions |
|||
|- |
|||
|<code>eciwx</code> |
|||
|External Control In Word indeXed |
|||
|<code>rA, rB, rC</code> |
|||
| |
|||
| |
|||
|- |
|||
|<code>ecowx</code> |
|||
|External Control Out Word indeXed |
|||
|<code>rA, rB, rC</code> |
|||
| |
|||
| |
|||
|- |
|||
! colspan="5" |Uncategorized instructions (categories WIP) |
|||
|- |
|||
|<code>li</code> |
|||
|Load Immediate |
|||
|<code>rA, iX₁₆</code> |
|||
|<code>rA = iX</code> |
|||
|Loads iX into rA |
|||
|- |
|||
|<code>lis</code> |
|||
|Load Immediate Shifted |
|||
|<code>rA, iX₁₆</code> |
|||
| `rA="rA" |<code><nowiki>rA = rA | (iX << 16)</nowiki></code> |
|||
|Loads iX into the upper 16 bits of rA |
|||
|- |
|||
|<code>la</code> |
|||
|Load Address |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>rA = rB + iX</code> |
|||
|Adds iX to the address stored in rB and loads the result into rA. |
|||
|- |
|||
|<code>mr</code> |
|||
|Move Register |
|||
|<code>rA, rB</code> |
|||
|<code>rA = rB</code> |
|||
|Copies the value of rB into rA (Despite the instruction name, rB is preserved) |
|||
|- |
|||
|<code>not</code> |
|||
|NOT operation |
|||
|<code>rA, rB</code> |
|||
|<code>rA = ~rB</code> |
|||
|Stores in rA the result of negated rB |
|||
|- |
|||
! colspan="5" |Misc. Instructions |
|||
|- |
|||
|<code>nop</code> |
|||
|No OPeration |
|||
|''N/A'' |
|||
|<code>;</code> |
|||
|Does nothing |
|||
|- |
|||
|<code>sc</code> |
|||
|System Call |
|||
|<code>[iX₇]</code> |
|||
|''N/A'' |
|||
|Calls upon the system to perform a service identified by iX |
|||
If iX is not provided, triggers a system call exception. |
|||
|- |
|||
|<code>rfi</code> |
|||
|Return From Interrupt |
|||
| |
|||
| |
|||
| |
| |
||
|} |
|} |
||
[[Category:Documentation]] |
|||
== == |
|||
==== External Resources ==== |
|||
*http://class.ece.iastate.edu/arun/CprE281_F05/lab/labw10a/Labw10a_Files/PowerPC%20Assembly%20Quick%20Reference.htm (few but nicely explained instructions with some examples and explains a little about assembly source files) |
|||
*https://jimkatz.github.io/powerpc_for_dummies (very incomplete, has mistakes) |
|||
*http://wiibrew.org/wiki/Assembler_Tutorial (also has missing instructions but way more accurate and better worded) |
|||
*https://fail0verflow.com/media/files/ppc_750cl.pdf (official instruction set docs, hard to navigate/search) |
|||
*http://personal.denison.edu/~bressoud/cs281-s07/ppc_instructions.pdf (similar to the above but stripped of all pages not documenting instructions, easier to search, missing instructions and references) |
|||
*[https://web.archive.org/web/20221024185252/https://wiki.alcf.anl.gov/images/f/fb/PowerPC_-_Assembly_-_IBM_Programming_Environment_2.3.pdf @archive:https://wiki.alcf.anl.gov/images/f/fb/PowerPC_-_Assembly_-_IBM_Programming_Environment_2.3.pdf] (additional instructions not included in the official instruction set docs, instead it points to this document) |
|||
*https://www.nxp.com/docs/en/application-note/AN2491.pdf (similar to the above but stripped of all pages not related to instructions, easier to search, also specific to 32 bit unlike the main document) |
|||
*http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf (the PowerPC ELF specification, contains some advanced in-depth information about the processor and thus its assembly mechanics) |
|||
*http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Motorola_PowerPC/PowerPc/GenInfo/pemch2.pdf (general PowerPC architecture information spec, good advanced registers reference) |
|||
*https://smashboards.com/threads/guide-using-paired-singles-and-gqrs.456834/ (paired singles tutorial, has some nice visual instruction graphs) |
|||
*https://mariokartwii.com/showthread.php?tid=1870 (another paired singles tutorial, very Wii-oriented but much of the same still applies in Wii U) |
|||
<br> |
|||
<hr> |
|||
<br> |
|||
__NOTOC__ |
__NOTOC__ |
||
__NOEDITSECTION__ |
__NOEDITSECTION__ |
||
[[Category:Documentation]] |
Latest revision as of 03:26, 12 August 2023
Instructions, registers and general info cheatsheet for PowerPC 32-bit Big Endian Assembly architecture used by the Wii U.
How to read this cheatsheet
- 64-bit only instructions and behaviors are entirely ignored and removed from this cheatsheet.
- If a right shift operation does not specify it is sign-fill, it is implicitly zero-fill by default
- If a value is referred to simply as "value" without specifying bit-count, it is implicitly 32 bits (aka a WORD, integer or float depending on context)
- multiplications and divisions implicitly result in a 64-bit value
- C-style casts are used due to being shorter to fit in the small table cells code snippets, but treat them as static_cast<T>
- the pseudocode examples are a C++ code representation to visualize the logic of an instruction, it is NOT code that compiles down to that instruction!
- In most cases where "float" is mentioned in a sentence (not a code snippet where it refers to the type), it usually means "a floating point value" which can be either float or double, not only float.
- # = placeholder (either a number or a letter, a letter is a labelled placeholder for a number so it may be referenced to by other text)
- r# = register (shorthand for GPR#)
- f# = floating point register (shorthand for FPR#)
- i# = immediate (the subscript numbers next to it is it's size in bits)
- ui# = unsigned immediate (above is signed)
- Instruction parameters wrapped in [ ] are optional and can be omitted.
- * = unsure of exact functionality
- "Assembly-only" instructions do NOT mean they cannot be generated from C++ compilation but rather they have no direct C++ snippet equivalent and instead are "glue" required to make the processor work.
typedef unsigned int uint; // 32 bit integer value
typedef signed int sint; // 32 bit integer value
typedef unsigned short ushort; // 16 bit integer value
typedef signed short sshort; // 16 bit integer value
typedef unsigned char ubyte; // 8 bit integer value
typedef signed char sbyte; // 8 bit integer value
float; // 32 bit floating point value
double; // 64 bit floating point value
|
---|
Register | Name | Attributes | Bits | Purpose |
---|---|---|---|---|
General Purpose Registers (GPRs) | ||||
r0 | GPR0 | Volatile + Cross-Module | 32 | General purpose, may be used by function linkage |
r1 | GPR1 | Saved + Reserved | 32 | Reserved for storing the stack frame pointer |
r2 | GPR2 | Reserved | 32 | Reserved for usage by the system |
r3 | GPR3 | Volatile | 32 | Stores 1st argument passed to function calls and their return value |
r4 - r10 | GPR4 - GPR10 | Volatile | 32 | Store from 2nd to 8th argument passed to function calls |
r11 - r12 | GPR11 - GPR12 | Volatile + Cross-Module | 32 | General purpose, may be used by function linkage |
r13 | GPR13 | Reserved | 32 | Reserved for storing the small data area (SDA) pointer |
r14 - r31 | GPR14 - GPR31 | Saved | 32 | General purpose, store generic integer values and pointers |
Floating Point Registers (FPRs) | ||||
f0 | FPR0 | Volatile | 64 | Store generic floating point numbers |
f1 | FPR1 | Volatile | 64 | Stores 1st float argument passed to function calls and their float return value |
f2 - f8 | FPR2 - FPR8 | Volatile | 64 | Store from 2nd to 8th float argument passed to function calls |
f9 - f13 | FPR9 - FPR13 | Volatile | 64 | Store generic floating point numbers |
f14 - f30 | FPR14 - FPR30 | Saved | 64 | Store generic floating point numbers |
f31 | FPR31 | Saved | 64 | General purpose, used for static chain if needed |
Special Purpose Registers (SPRs) | ||||
PC / IAR | Program Counter / Instruction Address Register | Internal | 32 | Stores the address of the current instruction (Controlled by the CPU) |
LR | Link Register | Volatile | 32 | Stores the return address for some of the branching instructions |
CTR | CounT Register | Volatile | 32 | Stores the counter of loop iterations for most instructions that perform loops. Also used for virtual function calls as it can contain an address which can be branched to |
MSR | Machine State Register | Special | 32 | Stores bits with information about the CPU and its current state |
SRR0 | machine status Save/Restore Register 0 | Interrupt-only | 32 | When an exception occurs, holds the address where instruction processing should resume when the exception handler returns control to the interrupted process |
SRR1 | machine status Save/Restore Register 1 | Interrupt-only | 32 | Stores machine status (select MSR bits and possibly other status bits as well) on exceptions, in order to restore those values when an rfi instruction is executed
|
CR | Condition Register | Volatile / Saved | 32 | Divided in 8 bitfields of 4 bits each to hold different kinds of conditions |
XER | fiXed point Exception Register | Volatile | 32 | Indicates overflows and carry conditions for integer operations and the number of bytes to be transferred by the load/store string indexed instructions |
FPSCR | Floating Point Status and Control Register | Volatile | 32 | Contains all floating point exception signal bits, exception summary bits, exception enable bits, and rounding control bits needed for compliance with the IEEE754 floating point arithmetic standard |
TB | Time Base | Special | 64 | Maintains the time of day and operates interval timers. The TB is not a register itself but the combined value of the two 32-bit registers TBU and TBL. |
... | There are way more but less common SPRs which won't be listed here | - | - | For a full but undescriptive list of all SPRs, visit wiiubrew.org/Hardware/Espresso |
Instruction | Name | Parameters | Pseudocode Equivalent | Additional Info |
---|---|---|---|---|
Integer Arithmetic Instructions | ||||
add [1][2]
|
ADD operation | rA, rB, rC
|
rA = rB + rC
|
Adds the values of rB and rC together and stores the result in rA |
addc [1][2]
|
ADD Carrying | rA, rB, rC
|
rA = rB + rC
|
Adds the values of rB and rC together and stores the result in rA |
addi
|
ADD Immediate | rA, rB, iX₁₆
|
rA = rB + iX
|
Adds the values of rB and iX together and stores the result in rA |
addic [1]
|
ADD Immediate Carrying | rA, rB, iX₅
|
rA = rB + iX
|
Adds the values of rB and iX together and stores the result in rA |
addis
|
ADD Immediate Shifted | rA, rB, iX₁₆
|
rA = rB + (iX << 16)
|
Adds the values of rB and (iX << 16) together and stores the result in rA |
adde [1][2]
|
ADD Extended | rA, rB, rC
|
rA = rB + rC + XER[CA]
|
Adds the values of rB, rC and XER[CA] together and stores the result in rA |
addme [1][2]
|
ADD to Minus one Extended | rA, rB
|
rA = rB + XER[CA] + 0xFFFFFFFF
|
Adds the values of rB, XER[CA] and 0xFFFFFFFF together and stores the result in rA |
addze [1][2]
|
ADD to Zero Extended | rA, rB
|
rA = rB + XER[CA]
|
Adds the values of rB and XER[CA] together and stores the result in rA |
subf [1][2]
|
SUBtract From | rA, rB, rC
|
rA = rC - rB
|
Subtracts the value of rB from rC and stores the result in rA. |
subfc [1][2]
|
SUBtract From, Carrying | rA, rB, rC
|
rA = rC - rB
|
Subtracts the value of rB from rC and stores the result in rA. |
subfic
|
SUBtract From Immediate Carrying | rA, rB, iX₅
|
rA = iX - rB
|
Subtracts the value of iX from rC and stores the result in rA. (CRO is modified) |
subfe [1][2]
|
SUBtract From, Extended | rA, rB, rC
|
rA = (rC - rB) + XER[CA]
|
Subtracts the value of rB from rC and adds the value of XER[CA] to the result, then stores the final result in rA |
subfme [1][2]
|
SUBtract From Minus one Extended | rA, rB
|
rA = (XER[CA] - rB) + 0xFFFFFFFF
|
Subtracts the value of rB from XER[CA], adds 0xFFFFFFFF to the result, then stores the final result in rA |
subfze [1][2]
|
SUBtract From Zero Extended | rA, rB
|
rA = XER[CA] - rB
|
Subtracts the value of rB from XER[CA] and stores the result in rA |
neg [1][2]
|
NEGate | rA, rB
|
rA = 1 - rB
|
Subtracts the value of rB from 1 and stores the result in rA |
mulli
|
MULtiply Low Immediate | rA, rB, iX₁₆
|
rA = (rB * iX) & 0xFFFFFFFF
|
Multiplies the value of rB by iX and stores the lower 32 bits of the result in rA |
mullw [1][2]
|
MULtiply Low Word | rA, rB, rC
|
rA = (rB * rC) & 0xFFFFFFFF
|
Multiplies the value of rB by the value of rC and stores the lower 32 bits of the result in rA |
mulhw [1]
|
MULtiply High Word | rA, rB, rC
|
rA = (rB * rC) >> 32
|
Multiplies the value of rB by the value of rC and stores the upper 32 bits of the result in rA |
mulhwu [1]
|
MULtiply High Word Unsigned | rA, rB, rC
|
rA = ((uint)rB * (uint)rC) >> 32
|
Multiplies the unsigned value of rB by the unsigned value of rC and stores the upper 32 bits of the result in rA |
divw [1][2]
|
DIVide Word | rA, rB, rC
|
rA = rB / rC
|
Divides the value of rB by the value of rC and stores the result in rA. The remainder is lost. |
divwu [1][2]
|
DIVide Word Unsigned | rA, rB, rC
|
rA = (uint)rB / (uint)rC
|
Divides the unsigned value of rB by the unsigned value of rC and stores the result in rA. The remainder is lost. |
Integer Comparison Instructions | ||||
| ||||
cmp
|
CoMPare | [cr#,] 0, rA, rB
|
N/A | The value of rA is compared to the value of rB, the results of the comparison are stored in cr# |
cmpi
|
CoMPare Immediate | [cr#,] 0, rA, iX
|
N/A | The value of rA is compared to iX, the results of the comparison are stored in cr# |
cmpl
|
CoMPare Logical | [cr#,] 0, rA, rB
|
N/A | The unsigned value of rA is compared to the unsigned value of rB, the results of the comparison are stored in cr# |
cmpli
|
CoMPare Logical Immediate | [cr#,] 0, rA, uiX
|
N/A | The unsigned value of rA is compared to uiX, the results of the comparison are stored in cr# |
cmpw
|
CoMPare Word | rA, rB
|
N/A | |
cmpwi
|
CoMPare Word Immediate | rA, iX₁₆
|
N/A | |
cmplwi
|
CoMPare Logical Word Immediate | N/A | ||
Integer Logical Instructions | ||||
andi.
|
AND Immediate | rA, rB, uiX₁₆
|
rA = rB & uiX
|
Performs an AND operation on rB and uiX then stores the result in rA |
andis.
|
AND Immediate Shifted | rA, rB, uiX₁₆
|
rA = rB & (uiX << 16)
|
Performs an AND operation on rB and (uiX << 16) then stores the result in rA |
ori
|
OR Immediate | rA, rB, iX₁₆
|
rA = rB | iX
|
Stores in rA the result of (rB | iX) |
oris
|
OR Immediate Shifted | rA, rB, iX₁₆
|
rA = rB | (iX << 16)
|
Stores in rA the result of (rB | (iX << 16)) |
xori
|
XOR Immediate | rA, rB, iX₁₆
|
rA = rB ^ iX
|
Performs an XOR operation on rB and iX then stores the result in rA |
xoris
|
XOR Immediate Shifted | rA, rB, iX₁₆
|
rA = rB ^ (iX << 16)
|
Performs an XOR operation on rB and (iX << 16) then stores the result in rA |
and [1]
|
AND Operation | rA, rB, rC
|
rA = rB & rC
|
Performs an AND operation on rB and rC then stores the result in rA |
or [1]
|
OR operation | rA, rB, rC
|
rA = rB | rC
|
Stores in rA the result of (rB | rC) |
xor [1]
|
XOR operation | rA, rB, rC
|
rA = rB ^ rC
|
Performs an XOR operation on rB and rC then stores the result in rA |
nand [1]
|
NAND operation | rA, rB, rC
|
rA = ~(rB & rC)
|
Stores in rA the negated result of (rB & rC) |
nor [1]
|
NOR operation | rA, rB, rC
|
rA = ~(rB | rC)
|
Stores in rA the negated result of (rB | rC) |
eqv *[1]
|
EQuiValent | rA, rB, rC
|
rA = rB == rC
|
Compares if the values of rB and rC are equal and stores the result in rA (?) |
andc [1]
|
AND Complement | rA, rB, rC
|
rA = rB & ~rC
|
Performs an AND operation on rB and negated rC then stores the result in rA |
orc [1]
|
OR Complement | rA, rB, rC
|
rA = rB | ~rC
|
Stores in rA the result of (rB | ~rC) |
extsb [1]
|
EXTend Sign Byte | rA, rB
|
rA = (int8_t)rB
|
Fills the upper 24 bits of rB's value with the sign bit of the stored 8 bit value |
extsh [1]
|
EXTend Sign Halfword | rA, rB
|
rA = (int16_t)rB
|
Fills the upper 16 bits of rB's value with the sign bit of the stored 16 bit value |
cntlzw [1]
|
CouNT Leading Zeros Word | rA, rB
|
N/A | Stores into rA the number of consecutive leading zero bits in the value of rB |
Integer Rotate Instructions | ||||
rlwinm [1]
|
Rotate Left Word Immediate, aNd with Mask | rA, rB, iX₅, iY₅, iZ₅
|
uint mask = ((uint)-1) << (31 - iZ + iY) >> iY;
rA = (rB << iX) | (rB >> (32 - iX)) & mask;
|
Rotates the value in rB by iX bits to the left
The result of the above is AND'ed with the mask specified by iY and iZ iY specifies the starting bit of the 1-bits in the mask (0-indexed) iZ specifies the end bit of the 1-bits in the mask (0-indexed) The final result is stored in rA |
rlwnm [1]
|
Rotate Left Word, aNd with Mask | |||
rlwimi [1]
|
Rotate Left Word Immediate, Mask Insert | |||
Integer Shift Instructions | ||||
slw [1]
|
Shift Left Word | rA, rB, rC
|
rA = rB << rC
|
Shifts the value in rB by the value in rC to the left and stores the result in rA |
srw [1]
|
Shift Right Word | rA, rB, rC
|
rA = (unsigned)rB >> rC
|
Shifts the value in rB by the value in rC to the right and stores the result in rA |
srawi [1]
|
Shift Right Algebraic Word Immediate | rA, rB, iX₅
|
rA = (signed)rB >> iX
|
Shifts the value in rB by iX to the right and stores the result in rA
Unlike regular zero-fill right shift operations, this one sign-fills the vacant bits |
sraw [1]
|
Shift Right Algebraic Word | rA, rB, rC
|
rA = (signed)rB >> rC
|
Shifts the value in rB by the value in rC to the right and stores the result in rA
Unlike regular zero-fill right shift operations, this one sign-fills the vacant bits |
slwi
|
Shift Left Word Immediate | rA, rB, iX₅
|
rA = rB << iX
|
Shifts the value in rB by iX to the left and stores the result in rA |
srwi
|
Shift Right Word Immediate | rA, rB, iX₅
|
rA = (unsigned)rB >> iX
|
Shifts the value in rB by iX to the right and stores the result in rA |
Floating Point Arithmetic Instructions | ||||
Floating Point Multiply-Add Instructions | ||||
Floating Point Rounding & Conversion Instructions | ||||
Floating Point Comparison Instructions | ||||
Floating Point Status and Control Register Instructions | ||||
Floating Point Move Instructions | ||||
fmr [1]
|
Float Move Register | fA, fB
|
fA = fB
|
Copies the value of fB into fA (Despite the instruction name, fB is preserved) |
fneg [1]
|
Float Negate | fA, fB
|
fA = -fB
|
Negates the value of fB and stores the result in fA |
fabs [1]
|
Float Absolute | fA, fB
|
fA = abs(fB)
|
The absolute value of fB is stored into rA |
fnabs [1]
|
Float Negative Absolute | fA, fB
|
fA = -abs(fB)
|
The negative absolute value of fB is stored into rA |
Floating Point Load Instructions | ||||
lfs
|
Load Float Single | fA, iX₁₆(rA)
|
fA = (float)(*(rA + iX))
|
Loads the value at the address (rA + iX) casted to float into fA. |
lfsx
|
Load Float Single indeXed | |||
lfsu
|
Load Float Single Update | |||
lfsux
|
Load Float Single Update indeXed | |||
lfd
|
Load Float Double | fA, iX₁₆(rA)
|
fA = (double)(*(rA + iX))
|
Loads the 64 bit value at the address (rA + iX) casted to double into fA. |
lfdx
|
Load Float Double indeXed | |||
lfdu
|
Load Float Double Update | |||
lfdux
|
Load Float Double Update indeXed | |||
Floating Point Store Instructions | ||||
stfs
|
STore Float Single | fA, iX₁₆(rA)
|
*(rA + iX) = (float)fA
|
Stores the value of fA casted to float at the memory address (rA + iX) |
stfsx
|
STore Float Single indeXed | |||
stfsu
|
STore Float Single Update | |||
stfsux
|
STore Float Single Update indeXed | |||
stfd
|
STore Float Double | fA, iX₁₆(rA)
|
*(rA + iX) = fA
|
Stores the 64 bit value of fA at the memory address (rA + iX) |
stfdx
|
STore Float Double indeXed | |||
stfdu
|
STore Float Double Update | |||
stfdux
|
STore Float Double Update indeXed | |||
stfiwx
|
STore Float as Integer Word indeXed | |||
Paired Singles Instructions (WIP)[3] | ||||
psq_l
|
Paired Single Quantized Load | |||
psq_lx
|
Paired Single Quantized Load indeXed | |||
psq_lu
|
Paired Single Quantized Load Update | |||
psq_lux
|
Paired Single Quantized Load Update indeXed | |||
psq_st
|
Paired Single Quantized Store | |||
psq_stx
|
Paired Single Quantized Store indeXed | |||
psq_stu
|
Paired Single Quantized Store Update | |||
psq_stux
|
Paired Single Quantized Store Update indeXed | |||
ps_abs
|
Paired Single ABSolute | |||
ps_add
|
Paired Single ADD | |||
ps_cmpo0
|
Paired Single CoMPare Ordered high(0) | |||
ps_cmpo1
|
Paired Single CoMPare Ordered low(1) | |||
ps_cmpu0
|
Paired Single CoMPare Unordered high(0) | |||
ps_cmpu1
|
Paired Single CoMPare Unordered low(1) | |||
ps_div
|
Paired Single DIVide | |||
ps_madd
|
Paired Single Multiply & ADD | |||
ps_madds0
|
Paired Single Multiply & ADD Scalar high(0) | |||
ps_madds1
|
Paired Single Multiply & ADD Scalar low(1) | |||
ps_merge00
|
Paired Single MERGE high(00) | |||
ps_merge01
|
Paired Single MERGE direct(01) | |||
ps_merge10
|
Paired Single MERGE swapped(10) | |||
ps_merge11
|
Paired Single MERGE low(11) | |||
ps_mr
|
Paired Single Move Register | |||
ps_msub
|
Paired Single Multiply & SUBtract | |||
ps_mul
|
Paired Single MULtiply | |||
ps_muls0
|
Paired Single MULtiply Scalar high(0) | |||
ps_muls1
|
Paired Single MULtiply Scalar low(1) | |||
ps_nabs
|
Paired Single Negative ABSolute | |||
ps_neg
|
Paired Single NEGate | |||
ps_nmadd
|
Paired Single Negative Multiply & ADD | |||
ps_nmsub
|
Paired Single Negative Multiply & SUBtract | |||
ps_res
|
Paired Single Reciprocal EStimate | |||
ps_rsqrte
|
Paired Single Reciprocal SQuareRooT Estimate | |||
ps_sel
|
Paired Single SELect | |||
ps_sub
|
Paired Single SUBtract | |||
ps_sum0
|
Paired Single vector SUM high(0) | |||
ps_sum1
|
Paired Single vector SUM low(1) | |||
Integer Load Instructions | ||||
lbz
|
Load Byte Zero-fill | rA, iX₁₆(rB)
|
rA = (ubyte)(*(rB + iX))
|
Loads the 8 bit value at the address (rB + iX) into rA |
lbzx
|
Load Byte Zero-fill indeXed | |||
lbzu
|
Load Byte Zero-fill Update | |||
lbzux
|
Load Byte Zero-fill Update indeXed | |||
lhz
|
Load Halfword Zero-fill | rA, iX₁₆(rB)
|
rA = (ushort)(*(rB + iX))
|
Loads the 16 bit value at the address (rB + iX) into rA |
lhzx
|
Load Halfword Zero-fill indeXed | |||
lhzu
|
Load Halfword Zero-fill Update | |||
lhzux
|
Load Halfword Zero-fill Update indeXed | |||
lha
|
Load Halfword Algebraic | rA, iX₁₆(rB)
|
||
lhax
|
Load Halfword Algebraic indeXed | |||
lhau
|
Load Halfword Algebraic Update | |||
lhaux
|
Load Halfword Algebraic Update indeXed | |||
lwz
|
Load Word Zero-fill | rA, iX₁₆(rB)
|
rA = *(rB + iX)
|
Loads the value at the address (rB + iX) into rA |
lwzx
|
Load Word Zero-fill indeXed | rA, rB, rC
|
rA = *(rB + rC)
|
Loads the value at the address (rB + rC) into rA |
lwzu
|
Load Word Zero-fill Update | rA, iX₁₆(rB)
|
rA = *(rB + iX);
rB = rB + iX;
|
Loads the value at the address (rB + iX) into rA Then loads rB with the address (rB + iX) |
lwzux
|
Load Word Zero-fill Update indeXed | |||
lmw *
|
Load Multiple Words | rA, iX₁₆(rB)
|
int EA = rB + iX;
int N = rA;
do {
GPR[N] = *(EA);
EA = EA + 4;
N = N + 1;
} while (N <= 31);
|
Loads GPR[rA] to r31 with the value at the address (rB + iX + N),
where N starts at 0 and increments by 4 for each register loaded.
|
Integer Store Instructions | ||||
stb
|
STore Byte | rA, iX₁₆(rB)
|
*(rB + iX) = (ubyte)rA
|
Stores the 8 bit value of rA at the memory address (rB + iX) |
stbx
|
STore Byte indeXed | |||
stbu
|
STore Byte Update | |||
stbux
|
STore Byte Update indeXed | |||
sth
|
STore Halfword | rA, iX₁₆(rB)
|
*(rB + iX) = (ushort)rA
|
Stores the 16 bit value of rA at the memory address (rB + iX) |
sthx
|
STore Halfword indeXed | |||
sthu
|
STore Halfword Update | |||
sthux
|
STore Halfword Update indeXed | |||
stw
|
STore Word | rA, iX₁₆(rB)
|
*(rB + iX) = rA
|
Stores the value of rA at the memory address (rB + iX) |
stwx
|
STore Word indeXed | rA, rB, rC
|
*(rB + rC) = rA
|
Stores the value of rA at the memory address (rB + rC) |
stwu
|
STore Word And Update | rA, iX₁₆(rB)
|
*(rB + iX) = rA
|
Stores the value of rA at the memory address (rB + iX)
Stores the computed address (rB + iX) into rB |
stwux
|
STore Word And Update indeXed | rA, rB, rC
|
||
stmw *
|
STore Multiple Words | |||
Little Endian Integer Load & Store Instructions | ||||
Integer Load and Store Strings Instructions | ||||
Branch Instructions | ||||
b
|
Branch | iX₂₄
|
goto LABEL
|
Jumps from the current address to IAR + iX, either up or down |
ba
|
Branch Absolute | iX₂₄
|
goto LABEL
|
Jumps from the current address to the address iX, either up or down |
bl
|
Branch & Link | iX₂₄
|
((void (*)())IAR + iX)()
|
Jumps from the current address to IAR + iX, either up or down
Also stores the address of the instruction directly below itself in LR This is the most common instruction used for calling a function |
bla
|
Branch & Link Absolute | iX₂₄
|
((void (*)())IAR + iX)()
|
Jumps from the current address to the address iX, either up or down
Also stores the address of the instruction directly below itself in LR |
bc
|
Branch Conditional | BO, BI, iX
|
||
bca
|
Branch Conditional Absolute | BO, BI, iX
|
||
bcl
|
Branch Conditional & Link | BO, BI, iX
|
||
bcla
|
Branch Conditional & Link Absolute | BO, BI, iX
|
||
bclr
|
Branch Conditional to Link Register | BO, BI, BH
|
||
bclrl
|
Branch Conditional to Link Register & Link | BO, BI, BH
|
||
bcctr
|
Branch Conditional to CounT Register | BO, BI, BH
|
||
bcctrl
|
Branch Conditional to CounT Register & Link | BO, BI, BH
|
||
blr
|
Branch to Link Register | N/A | return <r3 / f1>
|
Jumps from the current address to the address stored in LR
This is essentially the return statement of a function, with the value currently loaded into either r3 or f1 holding the returned value, depending on if the return type is a fixed or floating point value |
beq
|
Branch if EQual | iX₂₄
|
if (x == y) goto LABEL
|
If the EQ bit in CR0 is 1, jumps from the current address to IAR + iX
Otherwise, does nothing |
bne
|
Branch if Not Equal | iX₂₄
|
if (x != y) goto LABEL
|
If the EQ bit in CR0 is 0, jumps from the current address to IAR + iX
Otherwise, does nothing |
bgt
|
Branch if Greater Than | iX₂₄
|
if (x > y) goto LABEL
|
If the GT bit in CR0 is 1, jumps from the current address to IAR + iX
Otherwise, does nothing |
blt
|
Branch if Less Than | iX₂₄
|
if (x < y) goto LABEL
|
If the LT bit in CR0 is 1, jumps from the current address to IAR + iX
Otherwise, does nothing |
bge
|
Branch if Greater than or Equal | iX₂₄
|
if (x >= y) goto LABEL
|
If either the GT bit or EQ bit in CR0 is 1, jumps from the current address to IAR + iX
Otherwise, does nothing |
ble
|
Branch if Less than or Equal | iX₂₄
|
if (x <= y) goto LABEL
|
If either the LT bit or EQ bit in CR0 is 1, jumps from the current address to IAR + iX
Otherwise, does nothing |
bng
|
Branch if Not Greater than | |||
bnl
|
Branch if Not Less than | |||
bso
|
Branch if Summary Overflow | ??? | ??? | ??? |
bns
|
Branch if Not Summary overflow | ??? | ??? | ??? |
bun
|
Branch if UNordered | ??? | ??? | ??? |
bnu
|
Branch if Not Unordered | ??? | ??? | ??? |
bctr
|
Branch to CounT Register | |||
bctrl
|
Branch to CounT Register and Link | |||
bdnz
|
Branch if Decremented count register Not Zero | |||
bdnzt
|
Branch if Decremented count register Not Zero and if condition True | |||
bdnzf
|
Branch if Decremented count register Not Zero and if condition False | |||
bdz
|
Branch if Decremented count register Zero | |||
Condition Register Logical Instructions | ||||
Move to/from Special Purpose Registers Instructions | ||||
mflr
|
Move From Link Register | rA
|
rA = LR
|
Copies the value of LR into rA |
mtlr
|
Move To Link Register | rA
|
LR = rA
|
Copies the value of rA into the LR |
mtctr
|
Move To CounT Register | rA
|
CTR = rA
|
Copies the value of rA into the CTR |
mtfsf *
|
Move To FpScr Fields | UNK1, fA
|
??? | Copies the value of fA into the FPSCR under the control of the field mask in UNK1 |
mtfsb1
|
Move To FpScr Bit 1 | iX?
|
FPSCR = FPSCR | 0b1 << iX - 1
|
Sets bit iX of the FPSCR register to 1 |
mtspr
|
Move To Special Purpose Register | SPR, rA
|
SPRs[SPR] = rA
|
Copies the value of rA into the special purpose register SPR |
mfspr
|
Move From Special Purpose Register | rA, SPR
|
rA = SPRs[SPR]
|
Copies the value of special purpose register SPR into rA |
mfmsr
|
Move From Machine State Register | rA
|
rA = MSR
|
Copies the value of MSR into rA |
mftb
|
Move From Time Base | rA [, TBR]
|
N/A | If TBR == 268, the value of TBL (Time Base Lower) is copied into rA
If TBR == 269, the value of TBU (Time Base Upper) is copied into rA If TBR is omitted, 268 is used as default value |
mftbu
|
Move From Time Base Upper | rA
|
N/A | Copies the value of TBU (Time Base Upper) into rA |
Trap Instructions | ||||
twi
|
Trap Word Immediate | TO, rA, iX
|
||
tw
|
Trap Word | TO, rA, rB
|
||
Memory Synchronization Instructions | ||||
lwarx
|
Load Word And Reserve indeXed | rA, rB, rC
|
||
stwcx.
|
STore Word Conditional indeXed | rA, rB, rC
|
||
sync
|
SYNChronize | L
|
Assembly-only instruction | Delays all following instructions until all previous instructions required for context are complete. |
eieio
|
Enforce In-order Execution of I/O | N/A | Assembly-only instruction | "Provides an ordering function for the effects of loads and stores executed by the processor." |
isync
|
Instruction SYNChronize | N/A | Assembly-only instruction | Delays all following instructions until all previous instructions required for context are complete.
Additionally discards all prefetched instructions for a context reset. |
Cache Control Instructions | ||||
dcbz_l
|
Data Cache Block Zero and Lock | rA, rB
|
Assembly-only instruction | Too complex.[4]All you might need to know about this instruction is rA+rB form an address input, and it does not modify any registers. |
dcbi
|
Data Cache Block Invalidate | rA, rB
|
Assembly-only instruction | Too complex.[4] |
External Control Instructions | ||||
eciwx
|
External Control In Word indeXed | rA, rB, rC
|
||
ecowx
|
External Control Out Word indeXed | rA, rB, rC
|
||
Uncategorized instructions (categories WIP) | ||||
li
|
Load Immediate | rA, iX₁₆
|
rA = iX
|
Loads iX into rA |
lis
|
Load Immediate Shifted | rA, iX₁₆
|
rA = rA | (iX << 16)
|
Loads iX into the upper 16 bits of rA |
la
|
Load Address | rA, iX₁₆(rB)
|
rA = rB + iX
|
Adds iX to the address stored in rB and loads the result into rA. |
mr
|
Move Register | rA, rB
|
rA = rB
|
Copies the value of rB into rA (Despite the instruction name, rB is preserved) |
not
|
NOT operation | rA, rB
|
rA = ~rB
|
Stores in rA the result of negated rB |
Misc. Instructions | ||||
nop
|
No OPeration | N/A | ;
|
Does nothing |
sc
|
System Call | [iX₇]
|
N/A | Calls upon the system to perform a service identified by iX
If iX is not provided, triggers a system call exception. |
rfi
|
Return From Interrupt |
External Resources
- http://class.ece.iastate.edu/arun/CprE281_F05/lab/labw10a/Labw10a_Files/PowerPC%20Assembly%20Quick%20Reference.htm (few but nicely explained instructions with some examples and explains a little about assembly source files)
- https://jimkatz.github.io/powerpc_for_dummies (very incomplete, has mistakes)
- http://wiibrew.org/wiki/Assembler_Tutorial (also has missing instructions but way more accurate and better worded)
- https://fail0verflow.com/media/files/ppc_750cl.pdf (official instruction set docs, hard to navigate/search)
- http://personal.denison.edu/~bressoud/cs281-s07/ppc_instructions.pdf (similar to the above but stripped of all pages not documenting instructions, easier to search, missing instructions and references)
- @archive:https://wiki.alcf.anl.gov/images/f/fb/PowerPC_-_Assembly_-_IBM_Programming_Environment_2.3.pdf (additional instructions not included in the official instruction set docs, instead it points to this document)
- https://www.nxp.com/docs/en/application-note/AN2491.pdf (similar to the above but stripped of all pages not related to instructions, easier to search, also specific to 32 bit unlike the main document)
- http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf (the PowerPC ELF specification, contains some advanced in-depth information about the processor and thus its assembly mechanics)
- http://www.csit-sun.pub.ro/~cpop/Documentatie_SMP/Motorola_PowerPC/PowerPc/GenInfo/pemch2.pdf (general PowerPC architecture information spec, good advanced registers reference)
- https://smashboards.com/threads/guide-using-paired-singles-and-gqrs.456834/ (paired singles tutorial, has some nice visual instruction graphs)
- https://mariokartwii.com/showthread.php?tid=1870 (another paired singles tutorial, very Wii-oriented but much of the same still applies in Wii U)
- ↑ 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 1.25 1.26 1.27 1.28 1.29 1.30 1.31 1.32 1.33 1.34 1.35 1.36 1.37 1.38 This instruction has a variant with the
.
suffix, which indicates the instruction will update the CR special register based on the result of its operation, otherwise it behaves identically to the normal variant described on the table. - ↑ 2.00 2.01 2.02 2.03 2.04 2.05 2.06 2.07 2.08 2.09 2.10 2.11 2.12 2.13 This instruction has a variant with the
o
suffix, which indicates the instruction will enable the overflow bit [OV] in the XER special register, otherwise it behaves identically to the normal variant described on the table aside from different behavior caused by the overflow bit. This suffix can be combined with the.
suffix if the base instruction supports it. (Resulting in ano.
suffix) - ↑ These instructions are exclusive to the Broadway (Wii) and Espresso (Wii U) processors, they are not part of standard PowerPC Assembly and never existed outside the Wii and Wii U.
- ↑ 4.0 4.1 This instruction is too complex to be explained in brief terms on a cheatsheet. Most instructions of this kind are extremely rare and you are unlikely to ever encounter them, and even if you do, even less likely that you will need to know its behavior to understand the surrounding code. If you really need to learn this instruction refer to the processor manuals.