MIPS Forge
MIPS Forge is a self-contained MIPS32 assembler, interpreter/runtime and VS Code front end aimed at the QtSPIM/SPIM programming model. The integrated engine emits real 32-bit MIPS machine words and executes those words in its own virtual CPU; QtSPIM is not required for normal execution.
0.3.0 — QtSPIM compatibility hardening
This release moves from "broad instruction support" to a compatibility-driven implementation.
Integrated engine
The built-in TypeScript engine includes:
- Two-pass MIPS32 assembler with symbols, expressions,
%hi() / %lo(), numeric local labels and multiple memory sections.
- Optional commas in instruction syntax, matching common SPIM source such as
move $k1 $at.
.include, .macro / .end_macro, .repeat / .endr, equates and common data directives.
- User and kernel sections:
.text, .data, .rdata, .sdata, .bss, .ktext, .kdata.
- 32 GPRs, PC, HI/LO, 32 COP1 registers, FCSR/FCC condition state and CP0 state.
- Integer MIPS32 ALU, traps, jumps, ordinary/likely branches, HI/LO multiply/divide, LL/SC, unaligned loads/stores, SPECIAL2 and SPECIAL3.
- Additional MIPS32r2 forms including integer/FPU conditional moves,
recip.s/d, rsqrt.s/d, rdhwr, synci, ehb, pause and ssnop.
- COP1 single/double arithmetic, comparisons, eight FCC condition codes, conversions, rounding modes and control-register access.
- Optional classic delayed branches and delayed loads.
- SPIM memory-mapped receiver/transmitter registers at
0xffff0000 through 0xffff000c.
- CP0 exception routing through
0x80000180, EPC/Cause/BadVAddr/Status state, ERET and a quiet fallback handler when no .ktext handler is supplied.
- SPIM-style syscalls 1–17,
sbrk, basic host file I/O and argc/argv setup.
- SPIM-compatible float display formatting (
%.8f) and double formatting compatible with the normal %.18g behavior.
- Run, Step, Reset, Stop, register/COP0/COP1 explorer, machine-code listing, memory dump and symbol table.
- Standalone command-line runner using exactly the same assembler and CPU.
Differential testing against official SPIM
0.3 adds a first-class compatibility harness instead of guessing whether behavior matches SPIM.
From VS Code run:
MIPS: Compare Current File with Official SPIM
MIPS Forge runs the file once with the integrated engine and once with a configured terminal spim, removes SPIM's startup banner, and opens a report showing the first output difference and both raw outputs.
From a terminal:
npm run diff -- examples\factorial.s
Useful variants:
npm run diff -- --delayed-branches test\corpus\delay_branch.s
npm run diff -- --delayed-loads test\corpus\load_delay.s
npm run diff -- --mapped-io test\corpus\mmio.s
npm run diff -- --spim C:\tools\spim\spim.exe examples\factorial.s
The regression corpus under test/corpus/ currently covers integer ALU/HI-LO, branches and pseudo-instructions, data directives, %hi/%lo, macros/local labels, unaligned access, COP1, delayed loads, branch delay slots and memory-mapped I/O.
Development setup
Requirements:
- Windows 10/11, macOS or Linux
- Node.js 20+ (Node 22 recommended)
- npm
- VS Code
npm install
npm run test:all
Then open the project in VS Code and press F5. A second Extension Development Host window opens with MIPS Forge loaded.
Useful commands:
MIPS: Run Current File
MIPS: Step One Instruction
MIPS: Reset Program
MIPS: Stop Program
MIPS: Assemble / Show Machine Code
MIPS: Show Memory Around Address
MIPS: Show Symbol Table
MIPS: Queue Memory-Mapped Input
MIPS: Run with Official SPIM Backend
MIPS: Compare Current File with Official SPIM
Default shortcuts:
- Run:
Ctrl+Alt+R
- Step:
Ctrl+Alt+S
Run the engine without VS Code
npm run cli -- examples\factorial.s
npm run cli -- examples\bubble_sort.s
npm run cli -- examples\floating_point.s
npm run cli -- examples\include_demo\main.s
Simulator switches are also available:
npm run cli -- --delayed-branches program.s
npm run cli -- --delayed-loads program.s
npm run cli -- --mapped-io program.s
npm run cli -- --mapped-input "abc" --mapped-io program.s
npm run cli -- --exceptions program.s
Official SPIM as a compatibility oracle
The source package does not redistribute SPIM. If you install terminal SPIM separately, configure:
{
"mipsForge.spimPath": "C:\\tools\\spim\\spim.exe",
"mipsForge.spimOptions": [],
"mipsForge.programArguments": [],
"mipsForge.differentialInput": ""
}
You can use SPIM either as the execution backend or only as a differential oracle while continuing to run/debug with the integrated engine.
Testing
npm test # full local suite (core + corpus + differential when SPIM is available)
npm run test:corpus # generated compatibility programs
npm run test:differential
npm run test:all
test:differential skips cleanly when spim is not installed. To require it in CI:
$env:MIPS_FORGE_REQUIRE_SPIM="1"
npm run test:differential
To use a non-PATH SPIM executable:
$env:MIPS_FORGE_SPIM="C:\tools\spim\spim.exe"
npm run test:differential
Build an installable VSIX
Set a real Marketplace publisher ID in package.json, then:
npm install
npm run test:all
npm run package
Install the resulting .vsix using Extensions: Install from VSIX... before publishing it.
See docs/DEVELOPMENT.md, docs/COMPATIBILITY.md, docs/OFFICIAL_SPIM_BACKEND.md, docs/PUBLISHING.md, and docs/ROADMAP.md.
Compatibility claim
The integrated engine is now broad enough for substantial MIPS32/SPIM programs, but this project deliberately does not call the independent engine bit-for-bit QtSPIM-compatible until the differential corpus is run against official SPIM and remaining scheduler/FCSR/TLB edge cases are closed. The official SPIM backend remains the reference path for a source file that depends on behavior we have not yet reproduced.
License
MIPS Forge is MIT licensed. QtSPIM/SPIM binaries are not bundled in this source package.