This is a description of the MIPS instruction set, their meanings, syntax, semantics, and bit encodings. The syntax given for each instruction refers to the assembly language syntax supported by the MIPS assembler. Hyphens in the encoding indicate "don't care" bits which are not considered when an instruction is being decoded.
General purpose registers (GPRs) are indicated with a dollar sign ($). The words SWORD and UWORD refer to 32-bit signed and 32-bit unsigned data types, respectively.
The manner in which the processor executes an instruction and advances its program counters is as follows:
This behavior is indicated in the instruction specifications below. For brevity, the function advance_pc (int) is used in many of the instruction descriptions. This function is defined as follows:
void advance_pc (SWORD offset)
{
PC = nPC;
nPC += offset;
}
Note: ALL arithmetic immediate values are sign-extended. After that, they are handled as signed or unsigned 32 bit numbers, depending upon the instruction. The only difference between signed and unsigned instructions is that signed instructions can generate an overflow exception and unsigned instructions can not.
The instruction descriptions are given below:
Description: |
Adds two registers and stores the result in a register |
Operation: |
$d = $s + $t; advance_pc (4); |
Syntax: |
add $d, $s, $t |
Encoding: |
|
Description: |
Adds a register and a sign-extended immediate value and stores the result in a register |
Operation: |
$t = $s + imm; advance_pc (4); |
Syntax: |
addi $t, $s, imm |
Encoding: |
|
Description: |
Adds a register and a sign-extended immediate value and stores the result in a register |
Operation: |
$t = $s + imm; advance_pc (4); |
Syntax: |
addiu $t, $s, imm |
Encoding: |
|
Description: |
Adds two registers and stores the result in a register |
Operation: |
$d = $s + $t; advance_pc (4); |
Syntax: |
addu $d, $s, $t |
Encoding: |
|
Description: |
Bitwise ands two registers and stores the result in a register |
Operation: |
$d = $s & $t; advance_pc (4); |
Syntax: |
and $d, $s, $t |
Encoding: |
|
Description: |
Bitwise ands a register and an immediate value and stores the result in a register |
Operation: |
$t = $s & imm; advance_pc (4); |
Syntax: |
andi $t, $s, imm |
Encoding: |
|
Description: |
Branches if the two registers are equal |
Operation: |
if $s == $t advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
beq $s, $t, offset |
Encoding: |
|
Description: |
Branches if the register is greater than or equal to zero |
Operation: |
if $s >= 0 advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bgez $s, offset |
Encoding: |
|
Description: |
Branches if the register is greater than or equal to zero and saves the return address in $31 |
Operation: |
if $s >= 0 $31 = PC + 8 (or nPC + 4); advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bgezal $s, offset |
Encoding: |
|
Description: |
Branches if the register is greater than zero |
Operation: |
if $s > 0 advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bgtz $s, offset |
Encoding: |
|
Description: |
Branches if the register is less than or equal to zero |
Operation: |
if $s <= 0 advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
blez $s, offset |
Encoding: |
|
Description: |
Branches if the register is less than zero |
Operation: |
if $s < 0 advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bltz $s, offset |
Encoding: |
|
Description: |
Branches if the register is less than zero and saves the return address in $31 |
Operation: |
if $s < 0 $31 = PC + 8 (or nPC + 4); advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bltzal $s, offset |
Encoding: |
|
Description: |
Branches if the two registers are not equal |
Operation: |
if $s != $t advance_pc (offset << 2)); else advance_pc (4); |
Syntax: |
bne $s, $t, offset |
Encoding: |
|
Description: |
Divides $s by $t and stores the quotient in $LO and the remainder in $HI |
Operation: |
$LO = $s / $t; $HI = $s % $t; advance_pc (4); |
Syntax: |
div $s, $t |
Encoding: |
|
Description: |
Divides $s by $t and stores the quotient in $LO and the remainder in $HI |
Operation: |
$LO = $s / $t; $HI = $s % $t; advance_pc (4); |
Syntax: |
divu $s, $t |
Encoding: |
|
Description: |
Jumps to the calculated address |
Operation: |
PC = nPC; nPC = (PC & 0xf0000000) | (target << 2); |
Syntax: |
j target |
Encoding: |
|
Description: |
Jumps to the calculated address and stores the return address in $31 |
Operation: |
$31 = PC + 8 (or nPC + 4); PC = nPC; nPC = (PC & 0xf0000000) | (target << 2); |
Syntax: |
jal target |
Encoding: |
|
Description: |
Jump to the address contained in register $s |
Operation: |
PC = nPC; nPC = $s; |
Syntax: |
jr $s |
Encoding: |
|
Description: |
A byte is loaded into a register from the specified address. |
Operation: |
$t = MEM[$s + offset]; advance_pc (4); |
Syntax: |
lb $t, offset($s) |
Encoding: |
|
Description: |
The immediate value is shifted left 16 bits and stored in the register. The lower 16 bits are zeroes. |
Operation: |
$t = (imm << 16); advance_pc (4); |
Syntax: |
lui $t, imm |
Encoding: |
|
Description: |
A word is loaded into a register from the specified address. |
Operation: |
$t = MEM[$s + offset]; advance_pc (4); |
Syntax: |
lw $t, offset($s) |
Encoding: |
|
Description: |
The contents of register HI are moved to the specified register. |
Operation: |
$d = $HI; advance_pc (4); |
Syntax: |
mfhi $d |
Encoding: |
|
Description: |
The contents of register LO are moved to the specified register. |
Operation: |
$d = $LO; advance_pc (4); |
Syntax: |
mflo $d |
Encoding: |
|
Description: |
Multiplies $s by $t and stores the result in $LO. |
Operation: |
$LO = $s * $t; advance_pc (4); |
Syntax: |
mult $s, $t |
Encoding: |
|
Description: |
Multiplies $s by $t and stores the result in $LO. |
Operation: |
$LO = $s * $t; advance_pc (4); |
Syntax: |
multu $s, $t |
Encoding: |
|
Description: |
Performs no operation. |
Operation: |
advance_pc (4); |
Syntax: |
noop |
Encoding: |
|
Note: The encoding for a NOOP represents the instruction SLL $0, $0, 0 which has no side effects. In fact, nearly every instruction that has $0 as its destination register will have no side effect and can thus be considered a NOOP instruction.
Description: |
Bitwise logical ors two registers and stores the result in a register |
Operation: |
$d = $s | $t; advance_pc (4); |
Syntax: |
or $d, $s, $t |
Encoding: |
|
Description: |
Bitwise ors a register and an immediate value and stores the result in a register |
Operation: |
$t = $s | imm; advance_pc (4); |
Syntax: |
ori $t, $s, imm |
Encoding: |
|
Description: |
The least significant byte of $t is stored at the specified address. |
Operation: |
MEM[$s + offset] = (0xff & $t); advance_pc (4); |
Syntax: |
sb $t, offset($s) |
Encoding: |
|
Description: |
Shifts a register value left by the shift amount listed in the instruction and places the result in a third register. Zeroes are shifted in. |
Operation: |
$d = $t << h; advance_pc (4); |
Syntax: |
sll $d, $t, h |
Encoding: |
|
Description: |
Shifts a register value left by the value in a second register and places the result in a third register. Zeroes are shifted in. |
Operation: |
$d = $t << $s; advance_pc (4); |
Syntax: |
sllv $d, $t, $s |
Encoding: |
|
Description: |
If $s is less than $t, $d is set to one. It gets zero otherwise. |
Operation: |
if $s < $t $d = 1; advance_pc (4); else $d = 0; advance_pc (4); |
Syntax: |
slt $d, $s, $t |
Encoding: |
|
Description: |
If $s is less than immediate, $t is set to one. It gets zero otherwise. |
Operation: |
if $s < imm $t = 1; advance_pc (4); else $t = 0; advance_pc (4); |
Syntax: |
slti $t, $s, imm |
Encoding: |
|
Description: |
If $s is less than the unsigned immediate, $t is set to one. It gets zero otherwise. |
Operation: |
if $s < imm $t = 1; advance_pc (4); else $t = 0; advance_pc (4); |
Syntax: |
sltiu $t, $s, imm |
Encoding: |
|
Description: |
If $s is less than $t, $d is set to one. It gets zero otherwise. |
Operation: |
if $s < $t $d = 1; advance_pc (4); else $d = 0; advance_pc (4); |
Syntax: |
sltu $d, $s, $t |
Encoding: |
|
Description: |
Shifts a register value right by the shift amount (shamt) and places the value in the destination register. The sign bit is shifted in. |
Operation: |
$d = $t >> h; advance_pc (4); |
Syntax: |
sra $d, $t, h |
Encoding: |
|
Description: |
Shifts a register value right by the shift amount (shamt) and places the value in the destination register. Zeroes are shifted in. |
Operation: |
$d = $t >> h; advance_pc (4); |
Syntax: |
srl $d, $t, h |
Encoding: |
|
Description: |
Shifts a register value right by the amount specified in $s and places the value in the destination register. Zeroes are shifted in. |
Operation: |
$d = $t >> $s; advance_pc (4); |
Syntax: |
srlv $d, $t, $s |
Encoding: |
|
Description: |
Subtracts two registers and stores the result in a register |
Operation: |
$d = $s - $t; advance_pc (4); |
Syntax: |
sub $d, $s, $t |
Encoding: |
|
Description: |
Subtracts two registers and |