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
 

 

GUIDES AND
EXAMPLES PAGE

 

V


 

BIT

0

 

BYTE

00

 

HALFWORD

0000

 

WORD

00000000

 


Terms:


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 


 

Operation Terms:

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 falsethe 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.

 

 


 
Other Terms:
 

 

"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

 

 


lwz

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



 


lwzu

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. 

 

 


lwzx

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

 

 


lmw

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

 

 


b

Branch

Your code will jump (branch) to a specific place in memory.

 

 


bl

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.

 

 


blr

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

 


bctr

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

 

 


bctrl

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

 


bdnz

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.

 


bdnzt

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)

 


bdnzf

Branch if Decremented Count Register Not Zero And If Condition False

Same as bdnzexcept the loop will stop if a compare statment returns false (not equal)

 


bdz

Branch if Decremented Count Register Zero

A function in your code will loop as long as The Count Register holds the value "0"

 


cmp

Compare

Checks to see if 2 registers are equal to the same value, or 0.

 


cmpwi

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.

 

 


cmplwi

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)

 

 


cntlzw

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.

 


eieio

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....

 

 


mr

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

 


mflr

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

 


 

mtlr

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.

 

 

 


mtctr

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"

 


 

mtspr

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

 

 


mulli

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

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.

 

 

 

 


slw

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

 


slwi

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 

 

 


sraw

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


stwu

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.

 


xoris

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.

 

 


Operation Instructions

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"

 

 


 

Floating Point Instructions

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.

 

 


fsel

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