ISA
32-bit architecture, based on MIPS
Registers
- 32 x 32-bit GPR name R0-R31, R0 always contains ‘0’, even if other value is stored in it.
- PC – Program Counter, inaccessible directly from assembler
- IF/ID, ID/EX, EX/MEM, MEM/WB – for pipeline, inaccessible from assembler (IF - instruction fetch, ID - instruction decode, EX - execute, MEM - memory access, WB - write back)
- AOL, AOH - registers that store 64-bit result of ALU operation (for 64-bit operands and 32- bit operands multiplication/division). AOL (states for Alu-Out-Low) contains lower 32 bits of result, AOH (Alu - Out - High) - higher 32 bits. (equivalent of LO and HI in MIPS!)
General structure of instructions
ALU
32-bit (ALU operands)
- Rd = Rs (fuction) Rt
| Opcode (6) | Rs (5) | Rt (5) | Rd (5) | shift (5) | Function (6) | 
64-bit (ALU operands)
- AOH AOL = (([Rs+1]<<32)+Rs) (function) (([Rt+1]<<32)+Rt)
Or, more formally:
- AOL = ((([Rs+1]<<32)+Rs) (function) (([Rt+1]<<32)+Rt)) AND (232 -1)
- AOH = ((([Rs+1]<<32)+Rs) (function) (([Rt+1]<<32)+Rt)) >> 32
Note: (Rs or Rt = 31 will be coupled with R0! It gives us simple way to add 64- and 32-bit numbers by putting 32-bit one in R31)
(It is some kind of Little Endian that simplifies implementation)
| Opcode(6) | Rs (5) | Rt (5) | Shift (10) | Function(6) | 
Immediate
- Rd = Rs (function) Value
| Opcode (6) | Rs (5) | Rd (5) | Value (16) | 
MEMORY
| Opcode (6) | Rs (5) | Rd (5) | Offset (16) | 
CONTROL
Jump
| Opcode (6) | Address (26) | 
Jump to address stored in register
| Opcode (6) | Rs (5) | Empty(21) | 
Branch
| Opcode (6) | Rs (5) | Rt (5) | Value (16) | 
Value is signed
SPECIAL REGISTERS
| Opcode (6) | Empty(5) | Rd(5) | Empty(16) | 
Instruction Set
| 
Category | 
Name | 
Syntax | 
Meaning | 
Encoding | 
| 
ALU, 32-bit, Arithmetic | Add | add Rs,Rt,Rd | Rd = Rs + Rt | 000001ssssstttttddddd-----000000 | 
| Add Unsigned | addu Rs,Rt,Rd | Rd = Rs + Rt | 000001ssssstttttddddd-----000001 | |
| Subtract | sub Rs,Rt,Rd | Rd = Rs - Rt | 000001ssssstttttddddd-----000010 | |
| Subtract Unsigned | subu Rs,Rt,Rd | Rd = Rs - Rt | 000001ssssstttttddddd-----000011 | |
| Multiply | mul Rs,Rt,Rd | Rd = Rs * Rt | 000001ssssstttttddddd-----000100 | |
| Multiply Unsigned | mulu Rs,Rt,Rd | Rd = Rs * Rt | 000001ssssstttttddddd-----000101 | |
| Divide | div Rs,Rt,Rd | Rd = Rs / Rt | 000001ssssstttttddddd-----000110 | |
| Divide Unsigned | divu Rs,Rt,Rd | Rd = Rs / Rt | 000001ssssstttttddddd-----000111 | |
| Add Immediate | addi Rs,Rd,C | Rd = Rs + C | 000011sssssdddddcccccccccccccccc | |
| Add Immediate Unsigned | addiu Rs,Rd,C | Rd = Rs + C | 000101sssssdddddcccccccccccccccc | |
| Multiply to Long | mull Rs,Rt | AOL = ((Rs * Rt) << 32) >> 32 AOH = (Rs * Rt) >> 32 | 000001sssssttttt----------010000 | |
| Multiply to Long Unsigned | mullu Rs,Rt | AOL = ((Rs * Rt) << 32) >> 32 AOH = (Rs * Rt) >> 32 | 000001sssssttttt----------010001 | |
| Divide to Long | divl Rs,Rt | AOL = Rs / Rt AOH = Rs % Rt | 000001sssssttttt----------010010 | |
| Divide to Long Unsigned | divlu Rs,Rt | AOL = Rs / Rt AOH = Rs % Rt | 000001sssssttttt----------010011 | |
| 
ALU, 32-bit, Logic | And | and Rs,Rt,Rd | Rd = Rs & Rt | 000001ssssstttttddddd-----001000 | 
| And Immediate | andi Rs,Rd,C | Rd = Rs & C | 000111sssssdddddcccccccccccccccc | |
| Or | or Rs,Rt,Rd | Rd = Rs | Rt | 000001ssssstttttddddd-----001001 | |
| Or Immediate | ori Rs,Rd,C | Rd = Rs | C | 001001sssssdddddcccccccccccccccc | |
| Nand | nand Rs,Rt,Rd | Rd = ~( Rs & Rt ) | 000001ssssstttttddddd-----001010 | |
| Nand Immediate | nandi Rs,Rd,C | Rd = ~( Rs & C ) | 001011sssssdddddcccccccccccccccc | |
| Nor | nor Rs,Rt,Rd | Rd = ~( Rs & Rt ) | 000001ssssstttttddddd-----001011 | |
| Nor Immediate | nori Rs,Rd,C | Rd = ~( Rs & C ) | 001101sssssdddddcccccccccccccccc | |
| Xor | xor Rs,Rt,Rd | Rd = Rs ^ Rt | 000001ssssstttttddddd-----001100 | |
| Xor Immediate | xori Rs,Rd,C | Rd = Rs ^ C | 001111sssssdddddcccccccccccccccc | |
| Xnor | Xnor Rs,Rd,C | Rd = ~( Rs ^ Rt ) | 000001ssssstttttddddd-----001101 | |
| Xnor Immediate | Xnori Rs, Rt,Rd | Rd = ~( Rs ^ C ) | 010001sssssdddddcccccccccccccccc | |
| 
ALU, 32-bit, Bitwise Shift | Shift left logical | sll Rs, Rd, shift | Rd = Rs << shift | 000001sssssddddd-----shift011000 | 
| Shift right logical | srl Rs, Rd, shift | Rd = Rs >> shift | 000001sssssddddd-----shift011001 | |
| Shift right arithmetic | sra Rs, Rd, shift | Rd = Rs >> shift (arithmetic – difficult formula) | 000001sssssddddd-----shift011010 | |
| 
ALU, 64-bit, Arithmetic | Add | ladd Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)+ (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)+ (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000000 | 
| Add Unsigned | laddu Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)+ (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)+ (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000001 | |
| Subtract | lsub Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)- (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)-(((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000010 | |
| Subtract Unsigned | lsubu Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)- (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)- (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000011 | |
| Multiply | lmul Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)* (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)* (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000100 | |
| Multiply Unsigned | lmulu Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)* (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)* (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000101 | |
| Divide | ldiv Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)/ (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)/ (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000110 | |
| Divide Unsigned | ldivu Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)/ (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)/ (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------000111 | |
| 
ALU, 64-bit, Logic | And | land Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)& (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)& (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------001000 | 
| Or | lor Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)| (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)| (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------001001 | |
| Nand | lnand Rs,Rt | AOL =~(((((Rs+1)<<32)+Rs)& (((Rt+1)<<32)+Rt))) AND (232 -1) AOH =~(((((Rs+1)<<32)+Rs)& (((Rt+1)<<32)+Rt))) >>32 | 000010sssssttttt----------001010 | |
| Nor | lnor Rs,Rt | AOL =~(((((Rs+1)<<32)+Rs)| (((Rt+1)<<32)+Rt))) AND (232 -1) AOH =~(((((Rs+1)<<32)+Rs)|(((Rt+1)<<32)+Rt))) >>32 | 000010sssssttttt----------001011 | |
| Xor | lxor Rs,Rt | AOL = ((((Rs+1)<<32)+Rs)^ (((Rt+1)<<32)+Rt)) AND (232 -1) AOH =((((Rs+1)<<32)+Rs)^ (((Rt+1)<<32)+Rt)) >>32 | 000010sssssttttt----------001100 | |
| Xnor | lxnor Rs,Rt | AOL =~(((((Rs+1)<<32)+Rs)^ (((Rt+1)<<32)+Rt))) AND (232 -1) AOH =~(((((Rs+1)<<32)+Rs)^ (((Rt+1)<<32)+Rt))) >>32 | 000010sssssttttt----------001101 | |
| 
ALU, 64-bit, Bitwise Shift | Shift left logical | lsll Rs, shift | AOL = ((((Rs+1)<<32)+Rs) << shift) AND (232 -1) AOH= ((((Rs+1)<<32)+Rs) << shift) >> 32 | 000010sssss-----shiftshift011000 | 
| Shift right logical | lsrl Rs, shift | AOL = ((((Rs+1)<<32)+Rs) >> shift) AND (232 -1) AOH= ((((Rs+1)<<32)+Rs) >> shift) >> 32 | 000010sssss-----shiftshift011001 | |
| Shift right arithmetic | lsra Rs, shift | AOL = ((((Rs+1)<<32)+Rs) >> shift) AND (232 -1) AOH= ((((Rs+1)<<32)+Rs) >> shift) >> 32 (arithmetic shift!! – difficult formula) | 000010sssss-----shiftshift011010 | |
| 
MEMORY | Load word | lw Rd,Rs(C) | Rd = MEMORY[Rs + C] | 000100sssssdddddcccccccccccccccc | 
| Load half | lh Rd,Rs(C) | Rd = MEMORY[Rs + C] (signed) | 000110sssssdddddcccccccccccccccc | |
| Load half unsigned | lhu Rd,Rs(C) | Rd = MEMORY[Rs + C] (unsigned - without sign ext.) | 001000sssssdddddcccccccccccccccc | |
| Load byte | lb Rd,Rs(C) | Rd = MEMORY[Rs + C] (signed) | 001010sssssdddddcccccccccccccccc | |
| Load byte unsigned | lbu Rd,Rs(C) | Rd = MEMORY[Rs + C] (unsigned - without sign ext.)) | 001100sssssdddddcccccccccccccccc | |
| Store word | sw Rd,Rs(C) | MEMORY[Rs + C] = Rd | 001110sssssdddddcccccccccccccccc | |
| Store half | sh Rd,Rs(C) | MEMORY[Rs + C] = Rd | 010000sssssdddddcccccccccccccccc | |
| Store byte | sb Rd,Rs(C) | MEMORY[Rs + C] = Rd | 010010sssssdddddcccccccccccccccc | |
| 
SPECIAL REGISTERS | Move From AOL | maol Rd | Rd = AOL | 010100-----ddddd-------------------- | 
| Move From AOH | maoh Rd | Rd = AOH | 010110-----ddddd-------------------- | |
| 
CONTROL 32-bit | Jump | j A | PC = (PC+4)[31:28] . A*4 | 010011aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 
| Jump register | jr Rs | PC = Rs | 010101sssss------------------------- | |
| Branch if equal | beq Rs,Rt,C | If (Rs == Rt) PC = PC+4+4*C | 010111ssssstttttcccccccccccccccc | |
| Branch if not equal | bne Rs,Rt,C | If (Rs != Rt) PC = PC+4+4*C | 011001ssssstttttcccccccccccccccc | |
| Branch if greater than | bgt Rs,Rt,C | If (Rs > Rt) PC = PC+4+4*C | 011011ssssstttttcccccccccccccccc | |
| Unsigned branch if greater than | bgtu Rs,Rt,C | If (Rs > Rt) PC = PC+4+4*C | 011101ssssstttttcccccccccccccccc | |
| Branch if greater or equal to | bge Rs,Rt,C | If (Rs >= Rt) PC = PC+4+4*C | 011111ssssstttttcccccccccccccccc | |
| Unsigned branch if greater or equal to | bgeu Rs,Rt,C | If (Rs >= Rt) PC = PC+4+4*C | 100001ssssstttttcccccccccccccccc | |
| Branch if less than | blt Rs,Rt,C | If (Rs < Rt) PC = PC+4+4*C | 100011ssssstttttcccccccccccccccc | |
| Unsigned branch if less than | bltu Rs,Rt,C | If (Rs < Rt) PC = PC+4+4*C | 100101ssssstttttcccccccccccccccc | |
| Branch if less or equal to | ble Rs,Rt,C | If (Rs <= Rt) PC = PC+4+4*C | 100111ssssstttttcccccccccccccccc | |
| Unsigned branch if less or equal to | bleu Rs,Rt,C | If (Rs <= Rt) PC = PC+4+4*C | 101001ssssstttttcccccccccccccccc | |
| 
CONTROL 64-bit | Branch if equal | lbeq Rs,Rt,C | If (((Rs+1)<<32+Rs) ==((Rt+1)<<32+Rt)) PC = PC+4+4*C | 101000ssssstttttcccccccccccccccc | 
| Branch if not equal | lbne Rs,Rt,C | If (((Rs+1)<<32+Rs) !=((Rt+1)<<32+Rt)) PC = PC+4+4*C | 101010ssssstttttcccccccccccccccc | |
| Branch if greater than | lbgt Rs,Rt,C | If (((Rs+1)<<32+Rs) >((Rt+1)<<32+Rt)) PC = PC+4+4*C | 101100ssssstttttcccccccccccccccc | |
| Unsigned branch if greater than | lbgtu Rs,Rt,C | If (((Rs+1)<<32+Rs) >((Rt+1)<<32+Rt)) PC = PC+4+4*C | 101110ssssstttttcccccccccccccccc | |
| Branch if greater or equal to | lbge Rs,Rt,C | If (((Rs+1)<<32+Rs) >=((Rt+1)<<32+Rt)) PC = PC+4+4*C | 110000ssssstttttcccccccccccccccc | |
| Unsigned branch if greater or equal to | lbgeu Rs,Rt,C | If (((Rs+1)<<32+Rs) >=((Rt+1)<<32+Rt)) PC = PC+4+4*C | 110010ssssstttttcccccccccccccccc | |
| Branch if less than | lblt Rs,Rt,C | If (((Rs+1)<<32+Rs) <((Rt+1)<<32+Rt)) PC = PC+4+4*C | 110100ssssstttttcccccccccccccccc | |
| Unsigned branch if less than | lbltu Rs,Rt,C | If (((Rs+1)<<32+Rs) <((Rt+1)<<32+Rt)) PC = PC+4+4*C | 110110ssssstttttcccccccccccccccc | |
| Branch if less or equal to | lble Rs,Rt,C | If (((Rs+1)<<32+Rs) <=((Rt+1)<<32+Rt)) PC = PC+4+4*C | 111000ssssstttttcccccccccccccccc | |
| Unsigned branch if less or equal to | lbleu Rs,Rt,C | If (((Rs+1)<<32+Rs) <=((Rt+1)<<32+Rt)) PC = PC+4+4*C | 111010ssssstttttcccccccccccccccc | 
Note 1: Constant in all branches is signed!
Note 2: In MIPS only branches ‘equal’ and ‘not equal’ are implemented, but we can implement other using multiple ALU flags to determine if statement is true or not (e.g. A is greater than B if A-B results in flags Negative and Zero both equal to 0).
Changes
List of changes in comparison with word doc (too much to put in the summary):
- 64-bit ALU operations use only 2 registers instead of 4 (Rs+1 and Rt+1 replace Ru and Rv)
- 64-bit CONTROL instructions were added (thanks previous change).
There is some free opcodes that can be used to implement functions like 'multiply immediate' or '64-bit something immediate', but they are not neccesery and I would prefer to have some free opcodes ;).