# Computer Architecture

Start Lecture #10

### I-type (Immediate)

The I is for immediate.

• These instructions have an immediate third operand, i.e., the third operand is contained in the instruction itself.
• This means the operand itself, and not just its address or register number, is contained in the instruction.
• The format of an I-type instruction is
op rs rt operand
6 5 5 16
• The instruction specifies two registers and one immediate operand.
• rs is a source register.
• rt is sometimes a source and sometimes a destination register.
• Compare I and R types: Since there is no shamt and no funct, the immediate field can be larger than the field for a register.

#### Load Word and Store Word

Examples: lw/sw \$1,1000(\$2)

• The constant 1000 is the immediate operand.
• The effect of the lw example is that register \$1 is loaded with the contents of Mem[\$2+1000].
• The effect of the sw example is that the value in register \$1 is stored in Mem[\$2+1000].
• These instructions transfer a word (32 bits) to/from memory.
• But the machine is byte addressable!
• Then how come the machine has load/store word instead of load/store byte?
Ans: It has load/store byte as well, but we don't cover it (it is not hard; if you are interested read section 2.8).
• What if the memory address is not a multiple of 4?
Ans: An error (MIPS requires aligned accesses).
• The machine representation is: 35/43 2 1 1000

RISC-like properties of the MIPS architecture.

• All instructions are the same length (32 bits).
• Field sizes of R-type and I-type correspond.
• The type (R-type, I-type, etc.) is determined by the opcode.
• rs is the register used in determining the reference to memory for both load and store.
• These properties will prove helpful when we construct a MIPS processor.

• The effect of the instruction is
\$1 = \$2 + 100
• Why is there no subi?
Ans: The immediate operand in addi can be negative.

## 2.5: Logical Operations

#### Shifts: sll and srl (shift left/right) logical

Examples sll/srl \$8,\$12,7

• These examples set register 2 to the value obtained by shifting the contents of register 12 left/right 7 bits and setting the 7 rightmost/leftmost bits to 0. Register 12 is not changed.
• Naturally the two register numbers can be the same.
• This is an R-type instruction, with shamt used and rs not used.
• Why do we need both sll and srl, i.e, why not just have one of them and use a negative shift amt for the other?
Ans: The shamt is only 5 bits and need shifts from 0 to 31 bits.
Hence not enough bits for negative shifts.
• But why do we need shifts up to 31 bits? Isn't a left shift by 26 bits the same as a right shift by 32-26=6 bits?
Ans: NO!, these are shifts not rotates.
• Op is 0.
• funct is 0/2 for sll/srl.

#### Bitwise AND and OR: and, or, andi, ori

No surprises.

• and \$1,\$2,\$3
or \$1,\$2,\$3
• Standard R-type instructions.
• andi \$1,\$2,100
ori \$1,\$2,100
• Standard I-type instructions.

#### Bitwise NOR (includes NOT): nor

MIPS includes a bitwise NOR (our ALU implemented it) implemented as an R-type instruction.

• Example: nor \$5,\$7,\$6 sets register 5 to the bitwise NOR of registers 7 and 6.
• An important special case occurs when one of the source operands is register 0 (which is always 0).
• Remember that A NOR 0 = NOT(A OR 0) = NOT(A). So we get NOT for free by using register 0.
• Example: nor \$7,\$0,\$3 sets register 7 to the complement (technically the one's complement) of register 3.

## 2.6: Instructions for Making Decisions

#### beq and bne (branch (not) equal)

Examples: beq/bne \$1,\$2,123

• I-type
• if reg1=reg2 then go to the 124rd instruction after this one.
• if reg1!=reg2 then go to the 124rd instruction after this one.
• Why 124 not 123?
Ans: We will see that the CPU adds 4 to the program counter (for the no branch case) and then adds (times 4) the third operand. More significantly perhaps is that going to the 0th word after this one is not especially useful.
• Normally one writes a label for the third operand and the assembler calculates the offset needed.

#### slt (set less-then)

Example: slt \$3,\$8,\$2

• An R-type instruction.
• Set register 3 to (if register8 < register2 then 1 else 0)
• Similar to other R-type instructions: slt reads the 2nd and 3rd registers specified and writes the first.

#### slti (set less-then immediate)

Example: slt \$3,\$8,20

• An I-type instruction.
• Set register 3 to (if register 8 < 20 then 1 else 0).
• Similar to many other I-type instructions: slt reads the 2nd register specified and writes the first.

#### blt (branch if less than)

Example: blt \$5,\$8,123

• I-type
• if reg5 < reg8 then go to the 124rd instruction after this one.
• *** WRONG ***
• There is no blt instruction.
stl \$1,\$5,\$8
bne \$1,\$0,123

#### ble (branch if less than or equal)

Example: ble \$5,\$8,L (L a label to be calculated by the assembler.)

• Wrong!
• There is no ble \$5,\$8,L instruction.
• There is also no sle \$1,\$5,\$8, set \$1 if \$5 less or equal \$8.
• Note that \$5 ≤ \$8 is the same as NOT (\$8 < \$5).
• Hence we test for \$8 < \$5 and branch if false.
stl \$1,\$8,\$5
beq \$1,\$0,L

#### bgt (branch if greater than)

Example bgt \$5,\$8,L

• Wrong!
• There is no bgt \$5,\$8,L instruction.
• There is also no sgt \$1,\$5,\$8, set \$1 if \$5 greater than \$8.
• Note that \$5 > \$8 is the same as \$8 < \$5.
• Hence we test for \$8 < \$5 and branch if true.
stl \$1,\$8,\$5
bne \$1,\$0,L

#### bge (branch if greater than or equal)

Example: bge \$5,\$8,L

• Wrong!
• There is no bge \$5,\$8,L instruction.
• There is also no sge \$1,\$5,\$8, set \$1 if \$5 greater or equal \$8l
• Note that \$5 ≥ \$8 is the same as NOT (\$5 < \$8)l
• Hence we test for \$5 < \$8 and branch if false.
stl \$1,\$5,\$8
beq \$1,\$0,L

Note: Please do not make the mistake of thinking that
stl \$1,\$5,\$8
beq \$1,\$0,L
is the same as
stl \$1,\$8,\$5
bne \$1,\$0,L

It is not the case that the negation of X < Y is Y > X.
End of Note

### J-type instructions (J for jump)

These have a different format, but again the opcode is the first 6 bits.
6   26

The effect is to jump to the specified (immediate) address. Note that there are no registers specified in this instruction and that the target address is not relative to (i.e. added to) the address of the current instruction as was done with branches.

#### j (jump)

Example: j 10000

• Jump to instruction (not byte) 10000.
• Branches are PC relative, jumps are absolute.
• A J-type instruction.
• Range is 2^26 words = 2^28 bytes = 1/4 GB

But MIPS is a 32-bit machine with 32-bit address and we have specified only 26 bits. What about the other 6 bits?

In detail the address of the next instruction is calculated via a multi-step process.

1. The 26 bit address field is extracted from the instruction.
2. This address is left shifted two bits. The result is a 28-bit address (call it A) that is always a multiple of 4, which makes sense since all instructions must begin on a multiple of 4 bytes.
3. The high order 4 bits are extracted from the address of the current instruction (not the address in the current instruction). Call this 4-bit quantity B.
4. The address of the next instruction is formed by concatenating B with A.

## 2.7: Supporting Procedures in Computer Hardware

#### jal (jump and link)

Example: jal 10000

• Jump to instruction 10000 and store the return address (the address of the instruction after the jal).
• J type.
• Used for subroutine calls.
• The return address is stored in register 31. By using a fixed register, jal avoids the need for a second register field and hence can have 26 bits for the instruction address (i.e., can be a J type).

#### jr (jump register)

Important example: jr \$31

• Jump to the location in register 31.
• This is how to return from a subroutine called via a jal.
• R type, but uses only one register.
• Will it use one of the source registers or the destination register?
Ans: This will be clear when we construct the processor.

Homework: 2.38

Skipped.

## MIPS Addressing for 32-bit Immediates and Addresses

How can we put a 32-bit value (say 2 billion) into register 6?

1. Zero and add.
• Zero register 6 with sub \$6,\$6,\$6
• then add 2 billion with addi \$6,\$6,2000000000.
• WRONG: 2 billion doesn't fit in the 16-bit immediate field of an addi.
2. Load the word
• Have the constant placed in the program text (via some assembler directive).
• Issue lw to load the register.
• But memory accesses are slow and this uses a cache entry.
• Load immediate the high order 16 bits (into the low order bits of register 6)
• Shift register 6 left 16 bits (filling the low order with zero)
• Add immediate the low order 16 bits to register 6.
• Watch out! The add immediate might actually subtract!
4. Load shift OR
• Load immediate the high order 16 bits (into the low order bits of register 6)
• Shift register 6 left 16 bits (filling the low order with zero)
• OR immediate the low order 16 bits to register 6.
• This works.
• But it uses three instructions and three words of memory. We wish to improve this

#### lui (load upper immediate)

Example: lui \$4,123

• Loads 123 into the upper 16 bits of register 4 and clears the lower 16 bits of the register.
• An I-type instruction; rs is not used.
• This does the load and shift of the solution above.
• The combination lui followed by ori (OR immediate) solves our problem.

Homework: 2.29 (assume b≥0), 2.7, 2.32, 2.33.