I have been tossing around the idea of implementing a MIPS1 chip similar to the R3000 (I have a lot of nostalgia for a certian grey box from the 90s). Additionally, it seems like the right complexity level to challenge me without becoming unmanagable.
Unfortunately I haven't worked much with the MIPS_1 architecture directly so I wanted to try to create an assembler to familiarize myself with the ISA before diving into a larger project using it.
NOTE: This project is still in progress. I am still working on some aspects and have more work to do to validate the outputs. I would recommend verifying any outputs against a proven simulator like MARS or SPIM.
At this time the assembler can be called by calling ./main.rb followed by the filename (omitting .asm). Additionally an H or B can be added as a second argument to denote Hex or Binary output, this option defaults to HEX
./main.rb ascii H
Currently the assembler pulls the file from the samples folder. This is to simplify testing but will eventually change allowing you to give the full path of the file you would like to use.
Currently the assembler outputs a full memory dump called <filename>.txt, a dump of the instructions called <filename>_inst.txt and a dump of the data called <filename>_data.txt. Additionally if a sample output is available as I've created in the MARS_output folder a diff will be created for the instructions called <filename>_diff.txt. This is another testing feature and eventually will only be provided if requested by an arg.
- Create remaining unit tests
- Expand unit tests to randomize inputs and/or explore all potential cases
- Create additional sample code and validate its outputs
- Add logger to control verbosity, replace debugger print statements with log calls
- Add support for missing directives
- Add support for coprocessors
- Add support for additional sections (rdata, sdata, lit4/8 ect.)
- 32 32-bit General Purpose Registers
- $0 - hardwired to zero
- HI/LO - 32-bit registers used for asynchronous int mul/div
- PC
- R type : Opcode[0:5], rs[6:10], rt[11:15], rd[16:20], shamt[21:25], funct[26:31]
- I type : Opcode[0:5], rs[6:10], rt[11:15], immediate[16:31]
- J type : Opcode[0:5], Address[6:31]
- Load/Store
- 8-bit, 16-bit and 32-bit
- Add/Sub
- Source operands from RS and RT
- Output into RD
- Mul/Div
- Signed or Unsigned
- Output to HI/LOW
- Control Flow
- Followed by branch delay slot
- Compare RS against zero or RT
-System Call, Breakpoint
- call exceptions
ADD rd, rs, rt : Addition (with overflow)
ADDI rd, rs, Imm : Addition immediate (with overflow)
ADDU rd, rs, rt : Addition (without overflow)
ADDIU rd, rs, Imm : Addition immediate (without overflow)
AND rd, rs, rt : AND
ANDI rd, rs, Imm : AND Immediate
DIV rs, rt : Divide(with overflow)
DIVU rs, rt : Divide(without overflow)
MULT rs, rt : Multiply
MULTU rs, rt : Unsigned Multiply
NOR rd, rs, rt : NOR
OR rd, rs, rt : OR
ORI rd, rs, tr : OR Immediate
SLL rd, rs, rt : Shift Left Logical
SLLV rd, rs, rt : Shift Left Logical Variable
SRA rd, rs, rt : Shift Right Arithmetic
SRAV rd, rs, rt : Shift Right Arithmetic Variable
SR1 rd, rs, rt : Shift Right Logical
SR1V rd, rs, rt : Shift Right Logical Variable
SUB rd, rs, rt : Subtract (with overflow)
SUBU rd, rs, rt : Subtract (without overflow)
XOR rd, rs, rt : XOR
XORI rd, rs, Imm : XOR Immediate
LUI rd, Imm : Load Upper Immediate
SLT rd, rs, rt : Set Less Than
SLTI rd, rt, Imm : Set Less Than Immediate
SLTU rd, rs, rt : Set Less Than Unsigned
SLTIU rd, rs, Imm : Set Less Than Unsigned Immediate
BEQ rs, rt, offset : Branch on Equal
BGEZ rs, offset : Branch on Greater Than Equal Zero
BGEZAL rs, offset : Branch on Greater Than Equal Zero And Link
BGTZ rs, offset : Branch on Greater Than Zero
BLEZ rs, offset : Branch on Less Than Equal Zero
BGEZAL rs, offset : Branch on Greater Than Equal Zero And Link
BLTZAL rs, offset : Branch on Less Than And Link
BLTZ rs, offset : Branch on Less Than Zero
BNE rs, rt, offset : Branch on Not Equal
J label : Jump
JAL label : Jump and Link
JALR rs : Jump and Link Register
JR rs : Jump Register
LB rd, imm(rs) : Load Byte
LBU rd, imm(rs) : Load Unsigned Byte
LH rd, imm(rs) : Load Halfword
LHU rd, imm(rs) : Load Unsigned Halfword
LW rd, imm(rs) : Load Word
LWL rd, imm(rs) : Load Word Left
LWR rd, imm(rs) : Load Word Right
SB rs, imm(rt) : Store Byte
SH rs, imm(rt) : Store Halfword
SW rs, imm(rt) : Store Word
SWL rs, imm(rt) : Store Word Left
SWR rs, imm(rt) : Store Word Right
MFHI rd : Move From hi
MFLO rd : Move From lo
MTHI rd : Move To hi
MTLO rd : Move To low
LWCZ rd, imm(rs) : Load Word Coprocessor
SWCZ rs, imm(rt) : Store Word Coprocessor
BCZT label : Branch Coprocessor z True
BCZF label : Branch Coprocessor z False
https://user.eng.umd.edu/~manoj/759M/MIPSALM.html
https://shawnzhong.github.io/JsSpim/
https://uweb.engr.arizona.edu/~ece369/Resources/spim/MIPSReference.pdf
https://bh-cookbook.github.io/mips-asm/mips-instruction-set-part-5.html
https://computerscience.missouristate.edu/mars-mips-simulator.html
https://www.udemy.com/course/the-complete-mips-programming-course/learn/lecture/37060212#content