Skip to content
Contents

MIPS as a description, and MIPS beside RISC-V

Section 9.4 14 min read

  • the five parts of an ISA description
  • what the engine derives, and what it does not read yet
  • where MIPS32 and RV32IM really differ
  • the seventeen-program sweep

Checked against: carolyne_ref/isa_mips/ (reg.py, uop.py, operand.py, mop.py, imm.py, exec_unit_*.py, mips32.py) Carolyne CLAUDE.md §4, MIPS32 BRING-UP (2026-09-21) Carolyne generated/sim/run/*_mips32_o2 and *_rv32im_o2 result.json The RISC-V Instruction Set Manual, Vol. I (RV32I, M) MIPS32 Vol. II

Before you start

  • the whole book: every chapter contributed one row of the description

By the end, you can

  • Name the five things a description states and what the engine builds from each
  • Point to the ten differences between MIPS32 and RV32IM and say which ones cost instructions
  • Read the sweep table and say what it does and does not show

The description, in one figure

Your core was not written for MIPS. It was written once, against a of what an ISA is. The MIPS package is one instance of that shape:

What a CPU generator needs to know about MIPS: the five parts of the description

Left: what the package states, as data. Right: what the engine builds from it, for any ISA.

carolyne/isa/mips/ — data, 63 µops carolyne/uarch/o3/ — the engine, written once reg.py — register classes r: 32 × 32 bits, $0 = 0 hi: 1 lo: 1 uop.py + operand.py — µops and their slots 63 µops: alu 34 · mem 8 · control 12 · muldiv 9 mop.py — the encoding table 26 opcode rows; funct / rt / sa sub-rules; 3 formats imm.py — immediate rules s16 · lui · br (×4, sign) · j (×4) · bitfield exec_unit_*.py — the four units' bodies alu · mem (2 stages) · control · muldiv features: is_branch · delay_slot · is_store sizes record fields guards wires one pipe each read by rename table + physical file per class r: 64 physical hi: 32 lo: 32 the µop record: uop_idx, 3 srcs, 2 dests the same record shape for RV32IM the decoder: one guard per row a word matches exactly one µop, or none immediate extraction: part-selects, no shifts sign fill is one mux 4 reservation stations, 1 unit each alu out-of-order; mem, control, muldiv in order tags, rollback, store buffer, the slot (phase B)

What to notice

Every left box is something this book taught. Chapter 2 is the first box. Chapters 3 to 8 are the 63 µops and their slots. Chapter 1’s formats and the funct rules are the third box. The %hi/%lo, branch and jump arithmetic of chapters 3 and 5 are the fourth. The right side is what you never had to write for MIPS: the engine derived it.

Read the left column as five decisions.

  1. Register classes. r is 32 registers with $0 constant. hi and lo are two classes of one register each. That is why mult can have two destinations and mfhi reads one without an index (§7.1).
  2. µops and slots. One µop per instruction, 63 in all. They are numbered so that each unit’s µops form one run of ids. Each µop says which slot reads which field. A shift’s value is rt, an add’s is rs (§3.3).
  3. The encoding table. 26 rows keyed on the opcode. Four of them, SPECIAL, REGIMM, SPECIAL2 and SPECIAL3, refine on funct, rt or sa (§1.3, §8.1). A word matches exactly one row or none.
  4. Immediate rules. Five small functions that place bits and fill the sign. s16 and lui (§3.2). The branch offset times four and the jump index times four (§5.1). The ext/ins bit-field pair (§8.2).
  5. Unit bodies. What alu, mem, control and muldiv compute, in hardware code. The delay slot’s link value pc + 8 is written here.

What the engine did with it, and what it does not read yet

The generator read the package and built the machine of §1.1. A decoder with one guard per row. A rename table and a physical file for each of the three classes. Four reservation stations, a store buffer, and the rollback. Then the compile tool built all seventeen C programs for MIPS, and the core ran them. 34 of 34 runs, at -O0 and -O2, matched their host builds on the first try. No engine bug surfaced.

One feature is written but not read. Every branch and jump carries delay_slot, and the engine ignores it. Until it reads it, every slot must hold a nop (§5.4). The compile tool refuses any other word there. The design for reading it exists, and the GoDeeper below sketches it.

The whole table

Here are all 63, grouped as the book met them. Click a group to see only its rows, and a row for its encoding.

Every MIPS32 instruction your core runs

Which chapter taught each group, and which rows share an opcode?

63 of 63
instructionformatcodeoperandsmeaningunittaught in

What to notice

Ten groups, four units. Everything under opcode 0 is one row of the encoding table refined by funct. The release-2 rows, rotr, ext, ins, seb, seh, hide under opcodes 0 and 31. clz and mul hide under opcode 28. Nothing here traps, nothing is privileged, and nothing touches floating point.

MIPS beside RISC-V

The same engine also runs your RV32IM description. So the comparison this book kept promising can now be made on facts, not opinions.

MIPS32 and RV32IM: ten places they differ

MIPS32 Vol. II; the RISC-V manual Vol. I; both descriptions in carolyne/isa

PropertyMIPS32r2RV32IM
one immediate layout?
a zero register?
a delay slot?
multiply into special registers?
a < b in one branch?
a fixed reset vector?
add can trap?
rotates and bit-fields in the base?
conditional moves in the base?
32 registers with ABI names?

Select any cell to read why — and what it costs.

Most rows are choices with a cost each way. The delay slot and the branch forms are the two that change instruction counts on ordinary C.

What to notice

Most rows are trades. A single immediate layout buys MIPS a simpler extractor. RISC-V pays with scrambled B and J forms but keeps the sign bit fixed. HI/LO cost MIPS two register classes; RISC-V pays two instructions for a 64-bit product. Only two rows cost instructions on ordinary C. The delay slot: one nop per taken branch today. And a < b: two words on MIPS against one.

The sweep

Seventeen programs, both ISAs, one engine, -O2, two lanes. Every run matched its host build.

Cycles at -O2 on the same engine: MIPS32 against RV32IM, seventeen programs

generated/sim/run/*_mips32_o2 and *_rv32im_o2, result.json; the sweep of 2026-09-21

riscv_temp34341.00same
hello2642441.08RISC-V
ldst50510.98MIPS
rec45451.00same
m444441.00same
fwd50491.02RISC-V
subword58610.95MIPS
sort_36,1126,2150.98MIPS
stencil4,5654,8960.93MIPS
fib3,3913,1511.08RISC-V
hanoi9,85411,0520.89MIPS
acker24,95020,4141.22RISC-V
combinat52,09853,8060.97MIPS
stirling33,50131,8611.05RISC-V
cprime167,850170,3990.99MIPS
tarai247,744222,5451.11RISC-V
komachi1,709,3131,744,6700.98MIPS

What to notice

The ratio stays between 0.89 and 1.22. MIPS takes fewer cycles on eight programs, more on six, and ties three. hello shows the slot cost plainly: twenty taken branches, twenty nops, twenty more cycles. hanoi and stencil go the other way. Where the programs differ by a thousand times, the ISAs differ by a fifth at most.

Before reading on, decide:

hanoi runs in 9,854 cycles on MIPS and 11,052 on RISC-V, on the same engine. Which claim does that support?

Go deeper: phase B: letting the engine execute the delay slot

The plan is one µop feature, read in four places. Decode marks a lane as a slot when the previous instruction carried delay_slot. The tag generator books the speculation tag on the slot’s lane instead of the branch’s. The branch carries the tag its slot will book. So the slot is older than everything the squash covers and survives by construction. The reorder buffer rolls back by one more entry when the branch has a slot. And the branch station holds a branch until the entry after it is allocated. So the tag it carries exists before it can resolve. About a hundred lines of engine code, no MIPS name in any of them. Then -fno-delayed-branch and the compile tool’s check go, and GCC fills the slots.

Can you now explain it?

An ISA is five kinds of data: register classes, µops with slots, an encoding table, immediate rules and unit bodies. The engine builds the rest. MIPS and RISC-V differ in ten stated places, two of which cost instructions, and run within a fifth of each other on the same core.

If you remember only three things

  1. The description is data. Three classes, 63 µops, 26 encoding rows, five immediate rules, four unit bodies. The chapters of this book are its rows.
  2. The engine adapts. Decoder, rename, stations and rollback came from the description; 34 of 34 runs matched on the first try. The delay slot is the one feature it does not read yet.
  3. The ISAs are close. Ten differences, most of them trades. Cycles at -O2 stay within 0.89 to 1.22 of each other over seventeen programs.

Now try to explain this one yourself: a colleague asks you to bring up a third ISA on this engine. Name the five files you would write first. Then name one thing about that ISA that might force a change in the engine.

Go deeper: a model answer, once you have tried

First reg.py: the register classes and which registers are constant. Then uop.py with operand.py: one µop per instruction and the slot each field feeds. Then mop.py: the opcode rows and their sub-rules. Then imm.py: how each immediate is placed and sign-filled. Then the unit bodies. The thing to watch is anything the µop record cannot say. MIPS found one, the delay slot, which the record can state but the engine does not yet honour. An ISA whose instructions read four sources would find the next one. So would one that cracks an instruction into several µops.

Check your understanding

0/5 answered
  1. 1.A colleague wants to add a third ISA to the same engine. What must they write?

  2. 2.Why does the description declare hi and lo as two one-register classes instead of one 64-bit accumulator?

  3. 3.Today every delay slot must be a nop. What has to change in the engine before the compiler may fill slots?

  4. 4.Which of these is a real difference between MIPS32 and RV32IM, rather than a difference in names?

  5. 5.Across the seventeen programs, MIPS and RISC-V finish within about twenty percent of each other on one engine, most within a few. What does that show?


Next: the glossary: every term of the book, in one place.