ECE 15B Computer Organization Spring 2011 Dmitri Strukov Partially adapted from Computer Organization and Design, 4th edition, Patterson and Hennessy, Agenda • Recursive function (correction to the last lecture) Wrap-up of HW part (except for floating point) • Instruction formats • Addressing modes ECE 15B Spring 2011 Fibonacci numbers F(n) = F(n-1)+F(n-2) F(1) = 1 F(2) = 1 n = 1 2 3 4 F(n) = 1 1 2 3 5 5 6… 8… /* Recursive function in c */ int fib(int n) { If (n==1) return 1; If (n==2) return 1; return fib(n-1)+fib(n-2); } ECE 15B Spring 2011 Procedures Prolog - spill all register to stack used by procedure expect for $t0-$t9 and the one used for returning values - advance stack pointer ($sp) first then write to stack Body code of the procedure Epilog - restore all used registers - adjust stack pointer at the end ($sp) ECE 15B Spring 2011 # Recursive function in MIPS assembler #prolog FIB: addi $sp, $sp, -12 sw $a0, 0($sp) /* Recursive function in c */ sw $s0, 4($sp) int fib(int n) { sw $ra, 8($ra) If (n==1) return 1; # body If (n==2) return 1; addi $v0, $zero, 1 return fib(n-1)+fib(n-2); addi $t0, $zero, 1 } beq $a0, $t0, EPILOG #check for n==1 addi $t0, $zero, 2 /* Recursive function in c */ beq $a0, $t0, EPILOG #check for n==2 int fib(int n) { addi $a0, $a0, -1 v0 = 1; jal FIB #calculate fib(n-1) If (n==1) goto EXIT; addi $s0, $zero, $v0 # save fib(n-1) to $s0 If (n==2) goto EXIT; addi $a0, $a0, -1 #calculate fib(n-2) n = n – 1; jal FIB s0 = fib(n); addi $v0, $v0, $s0 n = n – 1; #epilog v0 = fib(n); EPILOG: lw $a0, 0($sp) v0 = v0 +s0; lw $s0, 4,($sp) EXIT: return v0; lw $ra, 8,($sp) } addi $sp, $sp, 12 ECE 15B jr Spring 2011 $ra # Recursive function in MIPS assembler #prolog FIB: addi $sp, $sp, -12 sw $a0, 0($sp) /* Recursive function in c */ sw $s0, 4($sp) int fib(int n) { sw $ra, 8($ra) If (n==1) return 1; # body If (n==2) return 1; addi $v0, $zero, 1 return fib(n-1)+fib(n-2); addi $t0, $zero, 1 } beq $a0, $t0, EPILOG #check for n==1 addi $t0, $zero, 2 /* Recursive function in c */ beq $a0, $t0, EPILOG #check for n==2 int fib(int n) { addi $a0, $a0, -1 v0 = 1; jal FIB #calculate fib(n-1) If (n==1) goto EXIT; addi $s0, $zero, $v0 # save fib(n-1) to $s0 If (n==2) goto EXIT; addi $a0, $a0, -1 #calculate fib(n-2) n = n – 1; jal FIB s0 = fib(n); addi $v0, $v0, $s0 n = n – 1; #epilog v0 = fib(n); EPILOG: lw $a0, 0($sp) v0 = v0 +s0; lw $s0, 4,($sp) EXIT: return v0; lw $ra, 8,($sp) } addi $sp, $sp, 12 ECE 15B jr Spring 2011 $ra • Now let’s see changes in the memory (stack) and register file as we execute recursive function with n = 3 • First let’s review datapath and where code is stored ECE 15B Spring 2011 Simple datapath review ECE 15B Spring 2011 Simple datapath review stack instructions ECE 15B Spring 2011 Where is the code stored? RF[$sp] stack stack dynamic data (heap) static data 0 Code (????) ANS: In main memory ECE 15B Spring 2011 Instruction memory stack IM: Physically different memory Logically mapped to main memory dynamic data (heap) static data code ECE 15B Spring 2011 Direct mapped cache implementation of instruction memory At any point in time IM has a copy of a portion of main memory Main memory Separate memory (tag) to store which location is currently mapped If upper portion of PC (28 bit) matches tag then IM has right values (hit), otherwise stop execution and load right portion Instruction memory 24 Tag (28 bit) 16 ECE 15B Spring02011 Main Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (right after execution of initial jal MM (initial values in stack) FIB at 0x0104) index value index value $v0 0 0xFFFF0000 0x00000000 $a0 3 0xFFFF00FC $t0 0 0xFFFF00F8 $s0 0 0xFFFF00F4 $sp 0xFFFF0000 $ra 0x0108 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution jal FIB at 0x1028) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 2 0xFFFF00FC 0x0108 $t0 2 0xFFFF00F8 0 $s0 0 0xFFFF00F4 3 $sp 0xFFFF00F4 $ra 0x102C ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution beq at 0x1020) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 2 0xFFFF00FC 0x0108 $t0 2 0xFFFF00F8 0 $s0 0 0xFFFF00F4 3 $sp 0xFFFF00E8 0xFFFF00F0 0x102C $ra 0x102C 0xFFFF00EC 0 0xFFFF00E8 2 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution jr at 0x104C) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 2 0xFFFF00FC 0x0108 $t0 2 0xFFFF00F8 0 $s0 0 0xFFFF00F4 3 $sp 0xFFFF00F4 0xFFFF00F0 0x102C $ra 0x102C 0xFFFF00EC 0 0xFFFF00E8 2 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution jal at 0x1034) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 1 0xFFFF00FC 0x0108 $t0 2 0xFFFF00F8 0 $s0 1 0xFFFF00F4 3 $sp 0xFFFF00F4 0xFFFF00F0 0x102C $ra 0x1038 0xFFFF00EC 0 0xFFFF00E8 2 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution beq at 0x1018) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 1 0xFFFF00FC 0x0108 $t0 1 0xFFFF00F8 0 $s0 1 0xFFFF00F4 3 $sp 0xFFFF00E8 0xFFFF00F0 0x1038 $ra 0x1038 0xFFFF00EC 1 0xFFFF00E8 1 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution jr at 0x104C) MM - stack index value index value $v0 1 0xFFFF0100 0x00000000 $a0 1 0xFFFF00FC 0x0108 $t0 1 0xFFFF00F8 0 $s0 1 0xFFFF00F4 3 $sp 0xFFFF00F4 0xFFFF00F0 0x1038 $ra 0x1038 0xFFFF00EC 1 0xFFFF00E8 1 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (after execution jr at 0x104C) MM - stack index value index value $v0 2 0xFFFF0100 0x00000000 $a0 3 0xFFFF00FC 0x0108 $t0 1 0xFFFF00F8 0 $s0 0 0xFFFF00F4 3 $sp 0xFFFF00F4 0xFFFF00F0 0x1038 $ra 0x0108 0xFFFF00EC 1 0xFFFF00E8 1 ECE 15B Spring 2011 Recursive function execution: step by step 0x0100 0x0104 0x0108 addi $a0, $zero, 3 jal FIB next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: EPILOG: 0x1000 0x1004 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C 0x1020 0x1024 0x1028 0x102C 0x1030 0x1034 0x1038 0x103C 0x1040 0x1044 0x1048 0x104C addi sw sw sw addi addi beq addi beq addi jal addi addi jal addi lw lw lw addi jr $sp, $sp, -12 $a0, 0($sp) $s0, 4($sp) $ra, 8($ra) $v0, $zero, 1 $t0, $zero, 1 $a0, $t0, EPILOG $t0, $zero, 2 $a0, $t0, EPILOG $a0, $a0, -1 FIB $s0, $zero, $v0 $a0, $a0, -1 FIB $v0, $v0, $s0 $a0, 0($sp) $s0, 4,($sp) $ra, 8,($sp) $sp, $sp, 12 $ra RF (at the end of program) MM - stack index value index value $v0 2 0xFFFF0100 0x00000000 $a0 3 0xFFFF00FC 0x0108 $t0 1 0xFFFF00F8 0 $s0 0 0xFFFF00F4 3 $sp 0xFFFF00F4 0xFFFF00F0 0x1038 $ra 0x0108 0xFFFF00EC 1 0xFFFF00E8 1 ECE 15B Spring 2011 Is code optimal? * No need to spill registers when n = 1 and n = 2 * F(n-2) is calculated independently of F(n-1). Better version could be (which is linear in time with n): int fib(int a, int b, int n) { if (n==2) return a; else return fib(a+b, a, n‐1); } …. and use fib(1,1,n) * Even better to use for-loop or do-while ? ECE 15B Spring 2011 Instruction formats ECE 15B Spring 2011 Instruction formats R-format: op rs rt rd shamt funct 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits op rs rt constant or address 6 bits 5 bits 5 bits 16 bits I-format: J-format: op address 6 bits 26 bits ECE 15B Spring 2011 Instruction formats Why stick to fixed formats? rigid and just few formats + fixed instruction size simple decoding faster clock cycle ( hopefully faster execution) note that it is always a tradeoff: too rigid and simple instruction set could be result in the large number of instructions several visual example later… ECE 15B Spring 2011 R-format Example op rs rt rd shamt funct 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits add $t0, $s1, $s2 note the order! (green card) special $s1 $s2 $t0 0 add 0 17 18 8 0 32 000000 10001 10010 01000 00000 100000 00000010001100100100000000100000 2 = 0232402016 ECE 15B Spring 2011 Basic addressing modes Very important aspect of ISA identifying how operands are defined for each operation Typically one (or two) operands is (are) register(s), i.e. general purpose one or PC, while another one is either • Immediate • Register • Memory memory) (may use imm but the actual operand is This how you define basic immediate, register or memory classes of addressing modes ECE 15B Spring 2011 Specific Addressing Mode in MIPS ECE 15B Spring 2011 MIPS PC-relative or branch addressing • Branch instructions specify – Opcode, two registers, target address • Most branch targets are near branch – Forward or backward op rs rt constant or address 6 bits 5 bits 5 bits 16 bits PC-relative addressing Target address = PC + offset × 4 PC already incremented by 4 by this time ECE 15B Spring 2011 Pseudodirect or Jump Addressing • Jump (j and jal) targets could be anywhere in text segment – Encode full address in instruction op address 6 bits 26 bits (Pseudo)Direct jump addressing Target address = PC31…28 : (address × 4) ECE 15B Spring 2011 Target Addressing Example • Loop code from earlier example – Assume Loop at location 80000 Loop: sll $t1, $s3, 2 80000 0 0 19 9 4 0 add $t1, $t1, $s6 80004 0 9 22 9 0 32 lw $t0, 0($t1) 80008 35 9 8 0 bne $t0, $s5, Exit 80012 5 8 21 2 19 19 1 addi $s3, $s3, 1 80016 8 j 80020 2 Exit: … Loop 80024 ECE 15B Spring 2011 20000 Note on the PC incrementing • Technical term for auto-incrementation of PC is “delayed branch” • By default in SPIM “delayed branch” is not checked. To see you SPIM settings look at simulator settings • You can also check it by loading code to SPIM to check main : bne $s0, $s0, main ECE 15B Spring 2011 Branching Far Away • If branch target is too far to encode with 16bit offset, assembler rewrites the code • Example beq $s0,$s1, L1 ↓ bne $s0,$s1, L2 j L1 L2: … ECE 15B Spring 2011 Various specific addressing modes in other ISAs • • • • • • • • • • • • Absolute address Immediate data Inherent address Register direct Register indirect Base register Register indirect with index register Register indirect with index register and displacement Register indirect with index register scaled Absolute address with index register Memory indirect Program counter relative ECE 15B Spring 2011 Example: Basic x86 Addressing Modes • Two operands per instruction Source/dest operand Second source operand Register Register Register Immediate Register Memory Memory Register Memory Immediate Memory addressing modes Address in register Address = Rbase + displacement Address = Rbase + 2scale × Rindex (scale = 0, 1, 2, or 3) Address = Rbase + 2scale × Rindex + displacement ECE 15B Spring 2011 Example of decoding and addressing modes in datapath ECE 15B Spring 2011 Simple datapath picture Let’s add more details on this figure to see why instruction decoding could be simple and to see what is happening with for ECE 15B Spring 2011 different instructions Datapath With Control ECE 15B Spring 2011 R-Type Instruction ECE 15B Spring 2011 Load Instruction ECE 15B Spring 2011 Branch-on-Equal Instruction ECE 15B Spring 2011 Implementing Jumps Jump 2 address 31:26 25:0 • Jump uses word address • Update PC with concatenation of – Top 4 bits of old PC – 26-bit jump address – 00 • Need an extra control signal decoded from opcode ECE 15B Spring 2011 Datapath With Jumps Added ECE 15B Spring 2011 Advanced Topics: Code density examples ECE 15B Spring 2011 Recent study (2009) ECE 15B Spring 2011 Code density examples ECE 15B Spring 2011