A jump table
Four addresses in memory, an index that picks one of them, and a jr through a register instead of a chain of comparisons.
A number picks which of four pieces of code runs. t2 holds 2, the program reads the third address
out of a table in memory and jumps to it, and the multiplication is what happens. Changing t2
changes the answer without changing a comparison anywhere.
The bigger of two numbers chose between two paths with a blt. A chain of those works for three or
four cases and gets slower with every one you add, since a value at the bottom of the chain is
compared against everything above it first. A table is looked up once whatever the value is.
You need to know: the "Branch on compare" lecture and the "Loads, stores and immediates"
lecture. What is new here is a jump to an address the program worked out, jr t5 goes to whatever
t5 holds, which nothing in the source names.
.word add_op, sub_op, mul_op, div_op writes four words, and each one is the address the assembler
gave that label. Put the memory panel on 10010000 and they read 00400024, 0040002C, 00400034
and 0040003C, which are four addresses inside your own code. A label is nothing but an address, and
this is what that sentence is for.
The three instructions before the jr are C's table[op]: multiply the index by the size of an
element with a shift, add it to the base, and read the word there. What comes out is an address, and
jr is the same instruction that returns from a subroutine, since ret is jalr zero, ra, 0 and
jr t5 is jalr zero, t5, 0. Writing jalr t5 instead would make this four calls rather than a
switch, because that form writes the return address into ra on the way.
t6 comes out at 00000012, which is 18, and t5 at 00400034, the address of mul_op. Each arm
ends with j done for the same reason the two halves of an if do: the arms are laid out one after
another and nothing stops the program running into the next one.
All four arms are one real instruction each. mul and div are the M extension, which this
simulator has, and they behave like any other instruction here; MIPS spells its three operand div
as a pseudo-instruction that expands to four, a bne and a break checking the divisor before the
real division.
Try changing li t2, 2 to li t2, 3 and t6 comes out at 2, which is 6 divided by 3. With 0 it
comes out at 9 and with 1 at 3. Nothing else in the program moves, and there is no comparison
anywhere in it to change.