Custom Code/PowerPC Assembly Cheatsheet: Difference between revisions
Jhmaster2000 (talk | contribs) mNo edit summary |
Jhmaster2000 (talk | contribs) (g) |
||
Line 1: | Line 1: | ||
= '''// WIP Draft''' = |
= '''// WIP Draft''' = |
||
if a right shift operation does not specify it is sign-fill, it is implicitly zero-fill by default |
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) |
|||
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> |
|||
<nowiki>#</nowiki> = placeholder |
<nowiki>#</nowiki> = placeholder |
||
Line 61: | Line 65: | ||
* http://class.ece.iastate.edu/arun/CprE281_F05/lab/labw10a/Labw10a_Files/PowerPC%20Assembly%20Quick%20Reference.htm |
* http://class.ece.iastate.edu/arun/CprE281_F05/lab/labw10a/Labw10a_Files/PowerPC%20Assembly%20Quick%20Reference.htm |
||
*https://jimkatz.github.io/powerpc_for_dummies (very incomplete, has mistakes) |
*https://jimkatz.github.io/powerpc_for_dummies (very incomplete, has mistakes) |
||
* http://wiibrew.org/wiki/Assembler_Tutorial |
* 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) |
*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 though) |
|||
====== Pseudocode Typedefs ====== |
====== Pseudocode Typedefs ====== |
||
<syntaxhighlight lang="c++"> |
<syntaxhighlight lang="c++"> |
||
typedef unsigned int uint; |
typedef unsigned int uint; // 32 bit value |
||
typedef signed int sint; |
typedef signed int sint; // 32 bit value |
||
typedef unsigned short ushort; |
typedef unsigned short ushort; // 16 bit value |
||
typedef signed short sshort; |
typedef signed short sshort; // 16 bit value |
||
typedef unsigned char ubyte; |
typedef unsigned char ubyte; // 8 bit value |
||
typedef signed char sbyte; |
typedef signed char sbyte; // 8 bit value |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
=== Instructions === |
|||
{| class="wikitable" |
{| class="wikitable" |
||
|- |
|- |
||
Line 279: | Line 286: | ||
|<code>eieio</code> |
|<code>eieio</code> |
||
|Enforce In-order Execution of I/O |
|Enforce In-order Execution of I/O |
||
| |
|??? |
||
| |
|??? |
||
|Unknown |
|||
⚫ | |||
|- |
|- |
||
|<code>eqv</code> |
|<code>eqv</code> |
||
Line 287: | Line 294: | ||
|<code>rA, rB, rC</code> |
|<code>rA, rB, rC</code> |
||
|<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>extsb</code> |
|<code>extsb</code> |
||
Line 293: | Line 300: | ||
|<code>rA, rB</code> |
|<code>rA, rB</code> |
||
|<code>rA = (int8_t)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> |
|<code>extsh</code> |
||
Line 299: | Line 306: | ||
|<code>rA, rB</code> |
|<code>rA, rB</code> |
||
|<code>rA = (int16_t)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>lbz</code> |
|||
|Load Byte Zero-fill |
|||
|<code>rA, iX₁₆(rB)</code> |
|||
|<code>rA = (ubyte)(*(rB + iX))</code> |
|||
|Loads the 8 bit value at the address (rB + iX) into rA |
|||
⚫ | |||
|<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>li</code> |
|<code>li</code> |
||
Line 314: | Line 333: | ||
|- |
|- |
||
|<code>lwz</code> |
|<code>lwz</code> |
||
|Load Word Zero |
|Load Word Zero-fill |
||
|<code>rA, iX₁₆(rB)</code> |
|<code>rA, iX₁₆(rB)</code> |
||
|<code>rA = *(rB + iX)</code> |
|<code>rA = *(rB + iX)</code> |
||
Line 358: | Line 377: | ||
|<code>mflr</code> |
|<code>mflr</code> |
||
|Move From Link Register |
|Move From Link Register |
||
|<code>rA</code> |
|||
| |
|||
|<code>rA = LR</code> |
|||
| |
|||
|Copies the value of LR into rA |
|||
| |
|||
|- |
|- |
||
|<code>mtlr</code> |
|<code>mtlr</code> |
||
|Move To Link Register |
|Move To Link Register |
||
|<code>rA</code> |
|||
| |
|||
|<code>LR = rA</code> |
|||
| |
|||
|Copies the value of rA into the LR |
|||
| |
|||
|- |
|- |
||
|<code>mtctr</code> |
|<code>mtctr</code> |
||
|Move To CounT Register |
|Move To CounT Register |
||
|<code>rA</code> |
|||
| |
|||
|<code>CTR = rA</code> |
|||
| |
|||
|Copies the value of rA into the CTR |
|||
| |
|||
|- |
|- |
||
|<code>mtspr</code> |
|<code>mtspr</code> |
||
|Move To Special Purpose Register |
|Move To Special Purpose Register |
||
|<code>SPR, rA</code> |
|||
| |
|||
|<code>SPR[SPR] = rA</code> |
|||
| |
|||
|Copies the value of rA into the special purpose register SPR |
|||
| |
|||
|- |
|- |
||
|<code>mulli</code> |
|<code>mulli</code> |
||
|MULtiply Low Immediate |
|MULtiply Low Immediate |
||
|<code>rA, rB, iX₁₆</code> |
|||
| |
|||
|<code>rA = rB * iX</code> |
|||
| |
|||
|Multiplies the value of rB by iX and stores the result in rA |
|||
| |
|||
|- |
|- |
||
|<code>nand</code> |
|<code>nand</code> |
||
Line 390: | Line 409: | ||
|<code>rA, rB, rC</code> |
|<code>rA, rB, rC</code> |
||
|<code>rA = ~(rB & rC)</code> |
|<code>rA = ~(rB & rC)</code> |
||
|Stores in rA the negated result of (rB & rC) |
|||
| |
|||
|- |
|- |
||
|<code>neg</code> |
|<code>neg</code> |
||
Line 396: | Line 415: | ||
|<code>rA, rB</code> |
|<code>rA, rB</code> |
||
|<code>rA = ~rB + 1</code> |
|<code>rA = ~rB + 1</code> |
||
|Stores in rA the result of negated rB with 1 added to it's value afterwards |
|||
| |
|||
|- |
|- |
||
|<code>nor</code> |
|<code>nor</code> |
||
Line 402: | Line 421: | ||
|<code>rA, rB, rC</code> |
|<code>rA, rB, rC</code> |
||
| `rA="~(rB" |<code><nowiki>rA = ~(rB | rC)</nowiki></code> |
| `rA="~(rB" |<code><nowiki>rA = ~(rB | rC)</nowiki></code> |
||
|<nowiki>Stores in rA the negated result of (rB | rC)</nowiki> |
|||
| |
|||
|- |
|- |
||
|<code>not</code> |
|<code>not</code> |
||
Line 408: | Line 427: | ||
|<code>rA, rB</code> |
|<code>rA, rB</code> |
||
|<code>rA = ~rB</code> |
|<code>rA = ~rB</code> |
||
|Stores in rA the result of negated rB |
|||
| |
|||
|- |
|- |
||
|<code>or</code> |
|<code>or</code> |
||
Line 414: | Line 433: | ||
|<code>rA, rB, rC</code> |
|<code>rA, rB, rC</code> |
||
| `rA="rB" |<code><nowiki>rA = rB | rC</nowiki></code> |
| `rA="rB" |<code><nowiki>rA = rB | rC</nowiki></code> |
||
|<nowiki>Stores in rA the result of (rB | rC)</nowiki> |
|||
| |
|||
|- |
|- |
||
|<code>orc</code> |
|<code>orc</code> |
||
Line 420: | Line 439: | ||
|<code>rA, rB, rC</code> |
|<code>rA, rB, rC</code> |
||
| `rA="rB" |<code><nowiki>rA = rB | ~rC</nowiki></code> |
| `rA="rB" |<code><nowiki>rA = rB | ~rC</nowiki></code> |
||
|<nowiki>Stores in rA the result of (rB | ~rC)</nowiki> |
|||
| |
|||
|- |
|- |
||
|<code>ori</code> |
|<code>ori</code> |
||
Line 426: | Line 445: | ||
|<code>rA, rB, iX₁₆</code> |
|<code>rA, rB, iX₁₆</code> |
||
| `rA="rB" |<code><nowiki>rA = rB | iX</nowiki></code> |
| `rA="rB" |<code><nowiki>rA = rB | iX</nowiki></code> |
||
|<nowiki>Stores in rA the result of (rB | iX)</nowiki> |
|||
| |
|||
|- |
|- |
||
|<code>oris</code> |
|<code>oris</code> |
||
Line 432: | Line 451: | ||
|<code>rA, rB, iX₁₆</code> |
|<code>rA, rB, iX₁₆</code> |
||
| `rA="rB" |<code><nowiki>rA = rB | (iX << 16)</nowiki></code> |
| `rA="rB" |<code><nowiki>rA = rB | (iX << 16)</nowiki></code> |
||
|<nowiki>Stores in rA the result of (rB | (iX << 16))</nowiki> |
|||
| |
|||
|- |
|- |
||
|<code>rlwinm</code> |
|<code>rlwinm</code> |
||
Line 494: | Line 513: | ||
|Shifts the value in rB by iX to the right and stores the result in rA |
|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 |
Unlike regular zero-fill right shift operations, this one sign-fills the vacant bits |
||
⚫ | |||
|<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>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>stw</code> |
|<code>stw</code> |
Revision as of 04:01, 12 June 2022
// WIP Draft
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)
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>
# = placeholder
r# = register
i# = immediate (the subscript numbers next to it is it's size in bits)
ui# = unsigned immediate (above is signed)
* = unsure of functionality
Registers
Register | Name | Purpose | Type |
---|---|---|---|
r0 - r31 | Registers 0 to 31 | Store integer values and addresses | TODO |
f0 - f31 | Floating Point Registers (FPRs) 0 to 31 | Store floating point numbers | TODO |
Register | Name | Purpose | Type |
---|---|---|---|
CR | Condition Register | Stores a condition (todo explain this better + its subregisters crX) | TODO |
CTR | CounT Register | Stores the counter of loop iterations for most instructions that perform loops | TODO |
PC / IAR | Program Counter / Instruction Address Register | Stores the address of the current instruction (Automatically managed by the CPU) | TODO |
LR | Link Register | Stores the return address for some of the branching instructions | TODO |
External Resources
- http://class.ece.iastate.edu/arun/CprE281_F05/lab/labw10a/Labw10a_Files/PowerPC%20Assembly%20Quick%20Reference.htm
- 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 though)
Pseudocode Typedefs
typedef unsigned int uint; // 32 bit value
typedef signed int sint; // 32 bit value
typedef unsigned short ushort; // 16 bit value
typedef signed short sshort; // 16 bit value
typedef unsigned char ubyte; // 8 bit value
typedef signed char sbyte; // 8 bit value
Instructions
Instruction | Name | Parameters | Pseudocode Equivalent | Additional Info |
---|---|---|---|---|
add
|
ADD operation | 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 |
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 |
and
|
AND Operation | rA, rB, rC
|
rA = rB & rC
|
Performs an AND operation on rB and rC then stores the result in rA |
andc
|
AND Complement | rA, rB, rC
|
rA = rB & ~rC
|
Performs an AND operation on rB and negated rC then stores the result in rA |
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 |
b
|
Branch | iX₂₄
|
goto LABEL
|
Jumps from the current address to IAR + iX, either up or down |
bl
|
Branch and 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 it in LR This is the most common instruction to use for calling a function |
blr
|
Branch to Link Register | N/A | return
|
Jumps from the current address to the address stored in LR
This is essentially the return statement of a function |
beq
|
Branch if EQual | |||
bne
|
Branch if Not Equal | |||
bgt
|
Branch if Greater Than | |||
blt
|
Branch if Less Than | |||
ble
|
Branch if Less than or Equal | |||
bge
|
Branch if Greater than or Equal | |||
bng
|
Branch if Not Greater than | |||
bnl
|
Branch if Not Less than | |||
bso
|
Branch if Summary Overflow | ??? | ??? | Unknown |
bns
|
Branch if Not Summary overflow | ??? | ??? | Unknown |
bun
|
Branch if UNordered | ??? | ??? | Unknown |
bnu
|
Branch if Not Unordered | ??? | ??? | Unknown |
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 | |||
cmp
|
CoMPare | |||
cmpwi
|
CoMPare Word Immediate | |||
cmplwi
|
CoMPare Logical Word Immediate | |||
cntlzw
|
CouNT Leading Zeros Word | |||
eieio
|
Enforce In-order Execution of I/O | ??? | ??? | Unknown |
eqv
|
EQuiValent | rA, rB, rC
|
rA = rB == rC
|
Compares if the values of rB and rC are equal and stores the result in rA (?) |
extsb
|
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
|
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 |
lbz
|
Load Byte Zero-fill | rA, iX₁₆(rB)
|
rA = (ubyte)(*(rB + iX))
|
Loads the 8 bit value at the address (rB + iX) into rA |
lhz
|
Load Halfword Zero-fill | rA, iX₁₆(rB)
|
rA = (ushort)(*(rB + iX))
|
Loads the 16 bit value at the address (rB + iX) into rA |
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 |
lwz
|
Load Word Zero-fill | rA, iX₁₆(rB)
|
rA = *(rB + iX)
|
Loads the value at the address (rB + iX) into rA |
lwzu
|
Load Word Zero 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) |
lwzx
|
Load Word Zero indeXed | rA, rB, rC
|
rA = *(rB + rC)
|
Loads the value at the address (rB + rC) into rA |
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.
|
mr
|
Move Register | rA, rB
|
rA = rB
|
Copies the value of rB into rA (Despite the instruction name, rB is preserved) |
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 |
mtspr
|
Move To Special Purpose Register | SPR, rA
|
SPR[SPR] = rA
|
Copies the value of rA into the special purpose register SPR |
mulli
|
MULtiply Low Immediate | rA, rB, iX₁₆
|
rA = rB * iX
|
Multiplies the value of rB by iX and stores the result in rA |
nand
|
NAND operation | rA, rB, rC
|
rA = ~(rB & rC)
|
Stores in rA the negated result of (rB & rC) |
neg
|
NEGate | rA, rB
|
rA = ~rB + 1
|
Stores in rA the result of negated rB with 1 added to it's value afterwards |
nor
|
NOR operation | rA, rB, rC
|
rA = ~(rB | rC)
|
Stores in rA the negated result of (rB | rC) |
not
|
NOT operation | rA, rB
|
rA = ~rB
|
Stores in rA the result of negated rB |
or
|
OR operation | rA, rB, rC
|
rA = rB | rC
|
Stores in rA the result of (rB | rC) |
orc
|
OR Complement | rA, rB, rC
|
rA = rB | ~rC
|
Stores in rA the result of (rB | ~rC) |
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)) |
rlwinm
|
Rotate Left Word Immediate aNd 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 |
sc
|
System Call | iX₇
|
N/A | Calls upon the system to perform a service identified by iX |
slw
|
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 |
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 |
srw
|
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 |
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 |
sraw
|
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 |
srawi
|
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 |
stb
|
STore Byte | rA, iX₁₆(rB)
|
*(rB + iX) = (ubyte)rA
|
Stores the 8 bit value of rA at the memory address (rB + iX) |
sth
|
STore Halfword | rA, iX₁₆(rB)
|
*(rB + iX) = (ushort)rA
|
Stores the 16 bit value of rA at the memory address (rB + iX) |
stw
|
STore Word | rA, iX₁₆(rB)
|
*(rB + iX) = rA
|
Stores the value of rA at the memory address (rB + iX) |
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 |
stwx
|
STore Word indeXed | rA, rB, rC
|
*(rB + rC) = rA
|
Stores the value of rA at the memory address (rB + rC) |
xor
|
XOR operation | rA, rB, rC
|
rA = rB ^ rC
|
Performs an XOR operation on rB and rC then stores the result in rA |
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 |