Computer Organization CS224 Fall 2012 Lessons 7 and 8 Small constants are used often in typical code Possible approaches? put “typical constants” in memory and load them create hard-wired registers (like $zero) for constants like 1 have special instructions that contain constants ! l l l addi $sp, $sp, 4 #$sp = $sp + 4 slti $t0, $s2, 15 #$t0 = 1 if $s2<15 Machine format (I format): 0x0A 18 8 0x0F The constant is kept inside the instruction itself! l Immediate format limits values to the range +215–1 to -215 §2.5 Representing Instructions in the Computer MIPS Immediate Instructions More than one instruction format? Remember Design Principle #1: Simplicity favors regularity (regularity => simplicity => clean implementation and fast performance) Thus, ISA designers would like to keep just one instruction format But to accommodate reasonable-size constants, field width of more than 5-bits is needed (addi, lw, sw,…) Also, ISA designers would like to keep all instructions the same length The compromise was to add a new instruction format (I-type), with 16-bit constant field Design Principle #4: Good design demands good compromises MIPS (RISC) Design Principles Simplicity favors regularity l l l Smaller is faster l l l limited instruction set limited number of registers in register file limited number of addressing modes Make the common case fast l l fixed size instructions small number of instruction formats opcode always the first 6 bits arithmetic operands from the register file (load-store machine) allow instructions to contain immediate operands Good design demands good compromises l e.g. 3 instruction formats, size of register file Instructions for bitwise manipulation Operation C Java MIPS Shift left << << sll Shift right >> >>> srl Bitwise AND & & and, andi Bitwise OR | | or, ori Bitwise NOT ~ ~ nor Useful for moving, extracting and inserting groups of bits in a word §2.6 Logical Operations Logical Operations Shift Operations op rs rt rd shamt funct 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits shamt: how many positions to shift Shift left logical l Shift left and fill with 0 bits l sll by i bits multiplies by 2i Shift right arithmetical l Shift right and fill with sign bit l sra by i bits divides by 2i (signed numbers) MIPS Shift Operations Need operations to pack and unpack 8-bit characters into 32-bit words, e.g. to isolate bits 23-16 from $s0[31:0], do: Shifts move all the bits in a word left or right sll $t2, $s0, 8 #$t2 = $s0 << 8 bits srl $s0, $t2, 24 #$s0 = $t2 >> 24 bits Instruction Format (R format) 0 16 10 8 0x00 Such shifts are called logical because they fill with zeros l Notice that a 5-bit shamt field is enough to shift a 32-bit value 25 – 1 or 31 bit positions MIPS Logical Operations There are a number of bit-wise logical operations in the MIPS ISA and $t0, $t1, $t2 #$t0 = $t1 & $t2 or $t0, $t1, $t2 #$t0 = $t1 | $t2 nor $t0, $t1, $t2 #$t0 = not($t1 | $t2) Instruction Format (R format) 0 9 10 8 0 0x24 andi $t0, $t1, 0xFF00 #$t0 = $t1 & ff00 ori #$t0 = $t1 | ff00 $t0, $t1, 0xFF00 Instruction Format (I format) 0x0D 9 8 0xFF00 OR Operations Useful to include bits in a word l Set some bits to 1, leave others unchanged or $t0, $t1, $t2 # $t1 is the “OR mask” $t2 0000 0000 0000 0000 0000 1101 1100 0000 $t1 0000 0000 0000 0000 0011 1100 0000 0000 $t0 0000 0000 0000 0000 0011 1101 1100 0000 AND Operations Useful to mask bits in a word l Clear some bits to 0, leave others unchanged and $t0, $t1, $t2 # $t1 is the “AND mask” $t2 0000 0000 0000 0000 0000 1101 1100 0000 $t1 0000 0000 0000 0000 0011 1100 0000 0000 $t0 0000 0000 0000 0000 0000 1100 0000 0000 NOT Operations Useful to invert bits in a word l Change 0 to 1, and 1 to 0 MIPS has NOR 3-operand instruction l a NOR b == NOT ( a OR b ) nor $t0, $t1, $zero Register 0: always read as zero $t1 0000 0000 0000 0000 0011 1100 0000 0000 $t0 1111 1111 1111 1111 1100 0011 1111 1111 Branch to a labeled instruction if a condition is true l beq rs, rt, L1 l if (rs == rt) branch to instruction labeled L1; bne rs, rt, L1 l Otherwise, continue sequentially if (rs != rt) branch to instruction labeled L1; j L1 l unconditional jump to instruction labeled L1 §2.7 Instructions for Making Decisions Conditional Operations MIPS Control Flow Instructions MIPS conditional branch instructions: bne $s0, $s1, Ll beq $s0, $s1, Ll l if (i==j) h = i + j; Ex: L1: bne $s0, $s1, L1 add $s3, $s0, $s1 ... Instruction Format (I format): 0x05 #go to Ll if $s0$s1 #go to Ll if $s0=$s1 16 17 16 bit offset How is the branch destination address specified? Specifying Branch Destinations Use a register (like in lw and sw) added to the 16-bit offset l which register? Instruction Address Register (the PC) - its use is automatically implied by instruction - PC gets updated (PC+4) during the fetch cycle so that it holds the address of the next instruction l limits the branch distance to -215 to +215-1 (word) instructions from the (instruction after the) branch instruction, but most branches are local anyway from the low order 16 bits of the branch instruction 16 offset sign-extend 00 32 32 Add PC 32 32 4 32 Add 32 branch dest address 32 ? Compiling If Else Statements C code: if (i==j) f = g+h; else f = g-h; l f, g, … in $s0, $s1, … Compiled MIPS code: bne add j Else: sub Exit: … $s3, $s4, Else $s0, $s1, $s2 Exit $s0, $s1, $s2 Assembler calculates addresses Compiling Loop Statements C code: while (save[i] == k) i += 1; l i in $s3, k in $s5, address of save in $s6 Hand “compiled” MIPS code: Loop: sll add lw bne addi j Exit: … $t1, $t1, $t0, $t0, $s3, Loop $s3, 2 $t1, $s6 0($t1) $s5, Exit $s3, 1 An optimizing compiler will reduce this loop from 6 instructions to 3 (50% speedup). How? Bottom test_&_branching (back up, or out) saves 1 t1<- t1+4 (instead of sll, add, & addi) saves 2 In Support of Branch Instructions We have beq, bne, but what about other kinds of branches (e.g., branch-if-less-than)? For this, we need yet another instruction, slt Set on less than instruction: slt $t0, $s0, $s1 then else Instruction format (R format): 0 # if $s0 < $s1 # $t0 = 1 # $t0 = 0 16 17 8 0x24 Alternate versions of slt slti $t0, $s0, 25 # if $s0 < 25 then $t0=1 ... sltu $t0, $s0, $s1 # if $s0 < $s1 then $t0=1 ... sltiu $t0, $s0, 25 # if $s0 < 25 then $t0=1 ... 2 Signed vs. Unsigned Signed comparison: slt, slti Unsigned comparison: sltu, sltui Example l l l $s0 = 1111 1111 1111 1111 1111 1111 1111 1111 $s1 = 0000 0000 0000 0000 0000 0000 0000 0001 slt $t0, $s0, $s1 # signed - –1 < +1 $t0 = 1 l sltu $t0, $s0, $s1 # unsigned - +4,294,967,295 > +1 $t0 = 0 More Branch Instructions Can use slt, beq, bne, and the fixed value of 0 in register $zero to create other conditions l slt bne l l l blt $s1, $s2, Label less than $at, $s1, $s2 $at, $zero, Label less than or equal to greater than great than or equal to #$at set to 1 if #$s1 < $s2 ble $s1, $s2, Label bgt $s1, $s2, Label bge $s1, $s2, Label Such branches are included in the instruction set as pseudo-instructions. These are recognized (and expanded) by the assembler l Its why the assembler needs a reserved register ($at) Branch Instruction Design Why not include blt, bge, etc in the actual MIPS ISA? Hardware for <, ≥, … slower than =, ≠ l l Combining with branch involves more work per instruction, requiring a slower clock All instructions would be penalized! beq and bne are the common case (Principle #3) This is a good design compromise (Principle #4)