PowerPC for Dummies
By Jimmy Kaz
Instructions:
li
lis
lwz
lwzu
lwzx
lmw
addi
addis
b
bl
blr
beq
bne
bgt
blt
ble
bge
bng
bnl
bso
bns
bun
bnu
bctr
bctrl
bdnz
bdnzt
bdnzf
bdz
cmp
cmpwi
cmplwi
cntlzw
eieio
mr
mflr
mtlr
mtctr
mtspr
mulli
NOT
ori
rlwinm
slw
slwi
sraw
stwu
xoris
V
BIT
0
BYTE
00
HALFWORD
0000
WORD
00000000
Register:
Something that can hold a value, or an adddress.
Count Register:
Something that holds the number for the amount of times something will happen.
Floating Point Register:
Something that holds a floating point value. (ex: 1.1)
Link Register:
Something that holds an address that can be returned to.
*See "bl" and "mflr" instruction*
Stack Frame:
Something that when created, allows you to free up registers that couldn't normally be used for operations and store data in them temportarily
The following operations convert the values in registers to binary.
The "check" is done by checking each bit to see if the number is 1 or 0
In this context, "true" is the value "1" and "false" is the value "0"
If the conditions are not met to make the resulting value "true", it will return "false".
AND
If both values are true, the result is true.
OR
If at least value 1 is true, the result is true.
NOR
If at least value 1 is false, the result is true.
XOR
Only 1 of the values can be true. If both are true, or if none are true, The result is false.
XNOR
The result will be true if both values are true or if both values are false.
NAND
Both values must be false for the result to be true.
XAND
Same thing as XNOR.
"With Update"
An address will be placed into a register after execution of an instruction.
"Algebric"
The user specified value in an instruction will be treated as a 32 bit value.
"Indexed"
Calculates an address after execution of an instruction.
Instruction List:
If any of this is wrong, contact me on discord "JimmyK#2848"
Yes, I know that the order of registers is usually "rD, rA" etc.
For simplicity, I'm listing it in "order of instance" for each instruction.
EXAMPLE:
or r1, r2, r3
r1 = Register A
r2 = Register B
r3 = Register C
li
Load Immediate
Loads a value into a register.
EXAMPLE :
li r0, 5
r0 | 00000000 | 00000005 |
r0 = 0x00000005
lis
Load Immediate Shifted
Loads a value into the upper 16 bits of a register.
EXAMPLE :
lis r0, 0xFFFF
r0 | 00000000 | FFFF0000 |
r0 = 0xFFFF0000
Load Word Zero
The value stored at the address in Register B is Loaded into Register A. The middle value is a pointer that adds onto the address
EXAMPLE :
lwz r0, 0x0(r1)
r0 | 00000000 | 00000000 |
r1 | 8055FFAA | 3333FFFF |
* Once this line of code gets executed, Any and all values that are at memory address 0x8055FFAA will be loaded into Register 0. So now, it looks like this
r0 | 00000000 | 3333FFFF |
r1 | 8055FFAA | 00000000 |
Load Word Zero Update
The value in Register A will be loaded into whatever Address is in Register B.
After the instruction is executed, The address in Register B is updated by the value you specify
EXAMPLE :
lwzu r1, 4(r2)
BEOFRE EXECUTION OF INSTRUCTION:
r1 | 00000000 | 00000008 |
r2 | 80000004 | 00000000 |
AFTER EXECUTION OF INSTRUCTION:
r1 | 00000000 | 00000000 |
r2 | 80000008 | 00000008 |
* Notice how the address in Register 2 is 0x80000008. It changed because it was
updated by the pointer, which was 0x4.
Load Word Zero Indexed
The value in Register A will be loaded into whatever Address is in Register C.
After the instruction is executed, The address in Register C is updated by the value in Register A.
The new address is stored in Register B
EXAMPLE :
lwzx r1, r2, r3
Load Multiple Words
Whatever value is in Register A up until Register 31 is loaded into Register B, the data will then be put into all Registers starting at Register B up until Register 31, for each register, 0x4 is added to the value being loaded. The value in the middle is an optional pointer.
addi
Add Immediate
The value that you specify will be added to whatever is currently in a register.
EXAMPLE :
addi r0, r0, 4
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000004 |
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000008 |
addis
Add Immediate Shifted
The value that you specify will be added to the upper half of whatever is currently in a register.
EXAMPLE :
addis r0, r0, 4
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00040000 |
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00080000 |
Branch
Your code will jump (branch) to a specific place in memory.
Branch And Link
Your code will jump to the start of a function, the instructions of said function will be executed until a blr statement is reached, once it's reached, the code will jump back to the bl instruction and execute every instruction below it.
Branch To Link Register
Your code will jump to whatever address is held in the link register.
beq
Branch If Equal
If the value specified in a Compare Statement is equal to the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 holds the value 0x00000005, the following instruction will be executed
beq test
# The code will now jump to a function named "test" since the value in register 0 was equal to the value in the compare instruction.
bne
Branch If Not Equal
If the value specified in a Compare Statement is not equal to the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 does not hold the value 0x00000005, the following instruction will be executed
bne test
# The code will now jump to a function named "test" since the value in register 0 was not equal to the value in the compare instruction.
bgt
Branch If Greater Than
If the value specified in a Compare Statement is Greater than the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 holds a value greater than 0x00000005 the following instruction will be executed
bgt test
# The code will now jump to a function named "test" since the value in register 0 was greater than the value in the compare instruction.
blt
Branch If Less Than
If the value specified in a Compare Statement is Less than the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 holds a value less than 0x00000005 the following instruction will be executed
blt test
# The code will now jump to a function named "test" since the value in register 0 was less than the value in the compare instruction.
ble
Branch If Less Than Or Equal To
If the value specified in a Compare Statement is Less than or equal to the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 holds a value less than or equal to 0x00000005 the following instruction will be executed
ble test
# The code will now jump to a function named "test" since the value in register 0 was either 5 or less than 5
bge
Branch If Greater Than Or Equal To
If the value specified in a Compare Statement is Greater than or equal to the value in a register. A branch is taken.
EXAMPLE :
cmpwi r0, 5
# If register 0 holds a value less than or equal to 0x00000005 the following instruction will be executed
bge test
# The code will now jump to a function named "test" since the value in register 0 was either 5 or greater than 5
bng
Branch If Not Greater Than
Use ble instead.
bnl
Branch If Not Less Than
Use bge instead.
bso
Branch If Summary Overflow
Currently Unknown. To be added
bns
Branch If Not Summary Overflow
Currently Unknown. To be added
bun
Branch If Unordered
Currently Unknown. To be added
bnu
Branch If Not Unordered
Currently Unknown. To be added
Branch To Count Register
Your code will jump to the address that you stored in the count register.
EXAMPLE :
# Assume r10 = 0x80004508
mtctr r10
bctr
# The code would now jump to the address 0x80004508
Branch To Count Register And Link
Your code will jump to the address that you stored in the count register. The code will jump back to it's original function when a blr instruction is reached. Once it's reached, the very next instruction is executed
EXAMPLE :
# Assume r10 = 0x80004508
function:
mtctr r10
bctrl
function_at_address_80004508:
blr
# When the blr is reached, the code will jump back to "function" and move on to the "li" instruction
Branch if Decremented Count Register Not Zero
A function in your code will loop over and over again until The Count Register reaches 0.
Example:
The loop amount depends on the length set in the Count Register beforehand.
If you set the length in the count register to be "4" for instance, the function would be ran 4 times
li r5, 4 # 4 = Amount of times for function to be ran
mtctr r5 # Register 5 is moved to the count register
function_2:
subi r6, r6, 2 # This will subtract 2 from the value in Register 6 every time it gets executed, in this case, it will happen 4 times.
bdnz function_2 # This will make "function_2" run 4 times, this instruction subtracts 1 from the count register every time it's ran, so after 4 times, it will stop as it will then equal 0.
Branch if Decremented Count Register Not Zero And If Condition True
Same as bdnz, except the loop will stop if a compare statment returns true (equal)
Branch if Decremented Count Register Not Zero And If Condition False
Same as bdnz, except the loop will stop if a compare statment returns false (not equal)
Branch if Decremented Count Register Zero
A function in your code will loop as long as The Count Register holds the value "0"
Compare
Checks to see if 2 registers are equal to the same value, or 0.
Compare Word Immediate
Checks to see if a register holds a specific HALFWORD.
(Any value between -0x8000 and 0x7FFF)
EXAMPLE :
cmpwi r0, 0x1
r0 | 00000000 | 00000001 |
The result would be TRUE.
Compare Logical Word Immediate
Checks to see if a register holds a value up to "65535".
This instruction can't check for a negative value since it only deals with unsigned integers
EXAMPLE :
cmplwi r0, 0x0009
r0 | 00000000 | 00000009 |
The result would be TRUE.
(I can't show a higher value because it would be in hex and make things confusing)
Count Leading Zeros Word
Unofficial Definition:
Converts the value in a register to binary and checks how zeros come before the first instance of the number 1 in the value.
Example to be added.
Enforce In-Order Execution of I/O
Unofficial Definition:
None of the instructions that store values will be executed until the instructions that load values that were apart of the functions that were running when this instruction was executed finish loading values.... I think....
Move Register
Moves whatever is in Register B to Register A
EXAMPLE :
mr r0, r1
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000000 |
r1 | 00000000 | 0000000F |
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | 0000000F |
r1 | 00000000 | 0000000F |
r0 = 0x0000000F
Move From Link Register
This pretty much just allows you to use the "bl" instruction and other "link" instruction types. The register can be pretty much anything.
It backs up whatever address is in the register you specify
Move To Link Register
If your code has a branch + link instruction of any kind, this is needed before the blr instruction in the exit function.
This restores whatever value was in the register before the execution of the mflr instruction.
Move To Count Register
A value is loaded from a specified register, The value tells the code how many times you want something to happen. It is stored in a "Count Register". Usually used alongside bdnz and stbu/stwu
SYNTAX :
# Assume r0 = 0x00000004
mtctr r0
# The amount of times a certain thing will happen in a code is now "4"
Move To Special Purpose Register
Stores whatever address is in the register you specify in a Link Register called "SPR" (Special Purpose Register)
EXAMPLE :
mtspr r10
# r10 is now stored in the SPR
Multiply Low Immediate
Multiplies whatever is in Register B by a specific HALFWORD and places the result in Register A
EXAMPLE :
mulli r1, r0, 0x2
* The value in r0 is multiplied by 2 and the result is stored in register 1.
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000004 |
r1 | 00000000 | 00000000 |
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000004 |
r1 | 00000000 | 00000008 |
r1 = 0x00000008
Other Information
- To multiply a value in a register and have the value stored in the same register, make both register values the same.
(ie. mulli r0, r0, 0x2)
NOT Operation
Makes the value in a register negative
EXAMPLE :
not r0, r0
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000001 |
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | FFFFFFFE |
ori
OR Immediate
Loads a value into the lower 16 bits of a register.
EXAMPLE :
ori r0, r0, 0xFFFF
r0 | 00000000 | 0000FFFF |
r0 = 0x0000FFFF
rlwinm
Rotate Left Word Immediate Then AND With Mask
I don't even know how I could explain this.
To put it simply, this is an instruction that has the functions of slwi, srwi, clrlwi, and clrrwi.
Shift Left Word
The value in Register B will be doubled however many times the value in Register C specifies, the result is stored in Register A.
EXAMPLE :
* For the sake of simplicty, I will be using a different syntax
32 << 1
The result would be "64"
32 << 2
Shift Left Word Immediate
This can do many different things depending on what the value you specify is.
If the value is "8"
- The Code will move a byte to the the upper half of a halfword in the lower half of a register (0xFFFFFF01 -> 0xFFFF0100)
If the value is "16"
- The Code will move a halfword from the lower half of a register to the upper half. (0xFFFF1111 -> 0x11110000)
If the value is "32"
- The code will clear the value in the register. (0x11111111 -> 0x00000000)
The value is taken from Register B and Stored in Register A
Shift Right Algebraic Word
The value in Register B will be halved however many times the value in Register C specifies, the result is stored in Register A.
EXAMPLE :
* For the sake of simplicty, I will be using a different syntax
32 >> 1
The result would be "16"
32 >> 2
Store Word And Update
Unofficial Definition:
Pushes Data into a Stack frame to allow the use of Registers that normally can't be used for operations.
XOR Immediate Shift
Definition will be added as soon as I figure out what the actual use for this instruction is.
Unofficial Definition:
"Copy Register". This can be used to copy the contents of a register
into another.
EXAMPLE :
xoris r0, r5, 0
BEOFRE EXECUTION OF INSTRUCTION:
r0 | 00000000 | 00000000 |
r5 | 00000000 | A55553F4 |
r0 = 0x00000000
r5 = 0xA55553F4
AFTER EXECUTION OF INSTRUCTION:
r0 | 00000000 | A55553F4 |
r5 | 00000000 | A55553F4 |
r0 = 0xA55553F4
r5 = 0xA55553F4
Dot Operand
This is not an instruction, but rather an operand. It can be added to the end of certain instructions.
It checks to see if the very first register specified in the instruction is equal to 0.
This is why you will often see branch statements with no matching compare statement.
I'll try not to go into too much technical detail with these. I had a very hard time understanding these at first.
OR
OR Operation
This checks to see if at least one register is equal to a value you specify, The specified value is placed in Register A.
A compare statement below checks to see if at least one register is equal to the value you specified.
EXAMPLE :
# Assume that Register 0 = 0x1
# Assume that Register 1 = 0x3
or r2, r0, r1 # To put it simply, this places the value you're checking the registers for in Register 2
cmpwi r2, 3 # This checks to see if at least one of the Registers is equal to your specified value, which in this case is "3" (the cmpwi instruction can't compare 2 registers, this is just comparing the value in r2 to the value of the result of the OR operation, which is the value you're checking the registers for)
beq function2 # Since the result returned true and one of the registers was equal to 3, the code will branch to "function2"
AND
AND Operation
This checks to see if both registers are equal to a value you specify, The specified value is placed in Register A.
A compare statement below checks to see if both registers are equal to the value you specified
EXAMPLE :
# Assume that Register 0 = 0x3
# Assume that Register 1 = 0x3
and r2, r0, r1 # To put it simply, this places the value you're checking the registers for in Register 2
cmpwi r2, 3 # This checks to see if both Register 0 and Register 1 are equal to your specified value, which in this case is "3" (the cmpwi instruction can't compare 2 registers, this is just comparing the value in r2 to the value of the result of the AND operation, which is the value you're checking the registers for)
beq function2 # Since the result returned true and both registers were equal to "3" the code will jump to "function2"
Instructions that affect floating point registers and preform opperations. With some instructions being unique to the Wii.
psq_add
Paired Single Quantized Add
The floats in Floating Point Register B and Floating Point Register C are added together. The resulting value is added to whatever is in Floating Point Register A
psq_sub
Paired Single Quantized Subtract
The float in Floating Point Register B is subtracted by the float in Floating Point Register C. The resulting value is subtracted from Whatever is in Floating Point Register A.
psq_mul
Paired Single Quantized Multiply
The floats in Floating Point Register B and Floating Point Register C are multiplied together and stored in Floating Point Register A
psq_div
Paired Single Quantized Divide
The float in Floating Point Register A is divided by the amount of times the floats in Floating Point Register B and Floating Point Register C divided together equal.
Floating Select
If Floating Point Register A is 0, or greater than 0, The value in Floating Point Register D is copied to Floating Point Register C. If Floating Point A is less than 0, The value in Floating Point Register B is copied to Floating Point Register D.
Guide:
Load Address into Register
Example : The address 0x800035FF will be loaded in Register 0
# This will load the address into register 0
lis r0, 0x8000
ori r0, r0, 0x35FF
# This instruction isn't always needed, but you can add it. This will load the value stored at address 0x800035FF into register 0
lwz r0, 0(r0)
Guide:
Check if a register holds a 32-Bit value
Example : Register 0 will be checked to see if it holds the value 0xFFFE5645
# For explaining/example purposes, I will put an instruction that loads a 32 bit value into another register, you'll most likely just be comparing though.
# This instruction requires the use of 2 different registers, one for the value, and one for comparing
# This will put the value 0xFFFE5645 into Register 1
lis r1, 0xFFFE
ori r1, r1, 0x5645
# This will check if Register 0 is equal to the value in Register 1 (If r0 = 0xFFFE5645)
cmpw r0, r1
Special Thanks
Kiwi515
GibHaltmannKill
Paniaal
Adamcrossing
TheLordScruffy
JoshuaMK
Vega