Instruction Set
MUPS/16 uses a fairly basic RISC instruction set, with 16-bit instructions: 5 bits for the opcode, 3 bits for each of the registers (for a maximum of 8 addressible registers), and four primary instruction types:
Type I, which have two registers and a 5-bit immediate
Type II, which have a single register, and an 8-bit immediate
Type J, which have just an 11-bit immediate
Type R, which have three registers, and a secondary function field in the final two bits allowing four instructions per opcode
All R-type instruction opcodes start with 11 in their top bits, to make decoding simpler. There is currently only one space left for an instruction with an immediate operand (opcode 21), but room for a few more in the R-type opcode space (two entire opcodes, and four slots within partially-used opcodes, for a total of 12 remaining R-type instructions).
I'm not entirely happy with the encoding of the system instructions (30 and 31). All instructions in this block have at least one unused field, so it's possible that with a small increase in the complexity of the instruction decoding we could free up several more R-type slots. This isn't immediately useful (we've got spare), but if we could get the number of R-type instructions down to 16 then we could squeeze them all into the 111xx opcodes, and free up a couple more immediate instructions.
Name | Type | Opcode | Fn | Bits | Asm Example | Summary |
---|---|---|---|---|---|---|
ADDI | I | 0 | 00000 RDD RS1 III II | addi sp, sp, -4 | Add sign-extended 5-bit immediate to RS1, store in RDD | |
ADDIU | I | 1 | 00001 RDD RS1 III II | addiu sp, sp, 18 | Add zero-extended 5-bit immediate to RS1, store in RDD | |
ANDI | I | 2 | 00010 RDD RS1 III II | andi r1, r2, 0x1 | Bitwise AND of zero-extended 5-bit immediate with RS1, store in RDD | |
ORI | I | 3 | 00011 RDD RS1 III II | ori r1, r2, 0x1 | Bitwise OR of zero-extended 5-bit immediate with RS1, store in RDD | |
XORI | I | 4 | 00100 RDD RS1 III II | xori r1, r2, 0x1 | Bitwise XOR of zero-extended 5-bit immediate with RS1, store in RDD | |
NORI | I | 5 | 00101 RDD RS1 III II | nori r1, r2, 0x1 | Bitwise NOR of zero-extended 5-bit immediate with RS1, store in RDD | |
J | J | 6 | 00110 III III III II | j 0x07fe | Unconditional jump to PC + 2 * signed 11-bit immediate | |
JAL | J | 7 | 00111 III III III II | jal 0x07fe | Store PC + 2 into RA and jump to PC + 2 * signed 11-bit immediate | |
JR | II | 8 | 01000 RS1 III III II | jr ra, 0 | Add 8-bit signed immediate to RS1 and jump to result | |
JALR | II | 9 | 01001 RS1 III III II | jalr r1, 0x2 | Store PC + 2 into RA, add signed 8-bit immediate to RS1 and jump to result | |
LB | I | 10 | 01010 RDD RS1 III II | lb r1, [6]sp | Add 5-bit signed immediate to RS1, and load single byte from resulting memory address into RDD, with sign extension of bit 7 | |
LBU | I | 11 | 01011 RDD RS1 III II | lbu r1, [6]sp | Add 5-bit signed immediate to RS1, and load single byte from resulting memory address into RDD, with top 8 bits set to 0 | |
LW | I | 12 | 01100 RDD RS1 III II | lw r1, [6]sp | Add 5-bit signed immediate to RS1, and load two-byte word from resulting memory address into RDD | |
LI | II | 13 | 01101 RDD III III II | li r1, 0x7e | Load 8-bit immediate value into RDD, with sign-extension of bit 7 | |
LIU | II | 14 | 01110 RDD III III II | liu r1, 0xff | Load 8-bit immediate value into RDD, with top 8 bits set to 0 | |
LUI | II | 15 | 01111 RDD III III II | lui r1, 0x01 | Load 8-bit immediate value into upper 8 bits of RDD. Lower 8 bits are unchanged | |
SB | I | 16 | 10000 RS1 RS2 III II | sb [6]sp, r1 | Add 5-bit signed immediate to RS1, and store low byte in RS2 to resulting memory address | |
SW | I | 17 | 10001 RS1 RS2 III II | sw [6]sp, r1 | Add 5-bit signed immediate to RS1, and store two-byte word RS2 to resulting memory address | |
SLLI | I | 18 | 10010 RDD RS1 III II | slli r1, r2, 3 | Shift contents of RS1 left by low four bits of 5-bit immediate, shifting in zero, store in RDD | |
SRLI | I | 19 | 10011 RDD RS1 III II | slli r1, r2, 1 | Shift contents of RS1 right by low four bits of 5-bit immediate, shifting in zero, store in RDD | |
SRAI | I | 20 | 10100 RDD RS1 III II | srai r1, r2, 2 | Shift contents of RS1 right by low four bits of 5-bit immediate, shifting in bit 15 of RS1, store in RDD | |
unused | 21 | 10101 | ||||
BZ | II | 22 | 10110 RS1 III III II | bz r1, -26 | Branch to PC plus 2 * 8-bit signed immediate if RS1 is zero | |
BNZ | II | 23 | 10111 RS1 III III II | bnz r1, -26 | Branch to PC plus 2 * 8-bit signed immediate if RS1 is not zero | |
ADD | R | 24 | 0 | 11000 RDD RS1 RS2 00 | add r1, r2, r3 | Add RS1 to RS2, store result in RDD |
unused | R | 1 | 11000 01 | |||
SUB | R | 24 | 2 | 11000 RDD RS1 RS2 10 | sub r1, r2, r3 | Subtract RS2 from RS1, store result in RDD |
unused | R | 24 | 3 | 11000 RDD RS1 RS2 11 | ||
AND | R | 25 | 0 | 11001 RDD RS1 RS2 00 | and r1, r2, r3 | Bitwise AND of RS1 with RS2, store result in RDD |
OR | R | 25 | 1 | 11001 RDD RS1 RS2 01 | or r1, r2, r3 | Bitwise OR of RS1 with RS2, store result in RDD |
XOR | R | 25 | 2 | 11001 RDD RS1 RS2 10 | xor r1, r2, r3 | Bitwise XOR of RS1 with RS2, store result in RDD |
NOR | R | 25 | 3 | 11001 RDD RS1 RS2 11 | nor r1, r2, r3 | Bitwise NOR of RS1 with RS2, store result in RDD |
SLL | R | 26 | 0 | 11010 RDD RS1 RS2 00 | sll r1, r2, r3 | Shift contents of RS1 left by amount given in bottom four bits of RS2, shifting in zero, store result in RDD |
SRL | R | 26 | 1 | 11010 RDD RS1 RS2 01 | srl r1, r2, r3 | Shift contents of RS1 right by amount given in bottom four bits of RS2, shifting in zero, store result in RDD |
SRA | R | 26 | 2 | 11010 RDD RS1 RS2 10 | sra r1, r2, r3 | Shift contents of RS1 left by amount given in bottom four bits of RS2, shifting in bit 15 of RS1, store result in RDD |
unused | R | 26 | 3 | 11010 11 | ||
SEQ | R | 27 | 0 | 11011 RDD RS1 RS2 00 | seq r1, r2, r3 | Set RDD to 1 if RS1 == RS2, 0 otherwise |
SNE | R | 27 | 1 | 11011 RDD RS1 RS2 01 | sne r1, r2, r3 | Set RDD to 1 if RS1 != RS2, 0 otherwise |
SLT | R | 27 | 2 | 11011 RDD RS1 RS2 10 | slt r1, r2, r3 | Set RDD to 1 if RS1 < RS2, 0 otherwise, signed comparison |
SLTU | R | 27 | 3 | 11011 RDD RS1 RS2 11 | sltu r1, r2, r3 | Set RDD to 1 if RS1 < RS2, 0 otherwise, unsigned comparison |
unused | R | 28 | 11100 | |||
unused | R | 29 | 11101 | |||
RFE | R | 30 | 0 | 11110 000 000 000 00 | rfe | Return from exception. Restore flags from values in S1, set page table index from value in S2, move SPC to PC |
SYSCALL | R | 30 | 1 | 11110 000 000 000 01 | syscall r1 | Invoke system call. Syscall number is passed in r1, args are passed in r2 to r4 |
MFS | R | 30 | 2 | 11110 RDD RS1 000 10 | mfs r1, s1 | Move from system reg. Move contents of RS1 + 8 to register RDD |
MTS | R | 30 | 3 | 11110 RDD RS1 000 11 | mts s1, r1 | Move to system reg. Move contents of register RS1 to RDD + 8 |
PTSI | R | 31 | 0 | 11111 RS1 000 000 00 | ptsi r1 | Set page table index to contents of RS1 |
PTSE | R | 31 | 1 | 11111 RS1 RS2 000 01 | ptse r1, r2 | Set page table entry at index given in RS1 to contents of RS2 |
PTREL | R | 31 | 2 | 11111 RDD RS1 000 10 | ptrel r1, r2 | Set RDD to low word (physical page) of the table entry at table address given in RS1 |
PTREH | R | 31 | 3 | 11111 RDD RS1 000 11 | ptrel r1, r2 | Set low byte of RDD to high byte (permissions) of the table entry at table address given in RS1. Set high byte of RDD to current table index |