ECE 15B Computer Organization Spring 2011 Dmitri Strukov Partially adapted from Computer Organization and Design, 4 th edition, Patterson and Hennessy,
Fibonacci numbers F(n) = F(n-1)+F(n-2) F(1) = 1 F(2) = 1 n = … F(n) = … /* 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 c */ int fib(int n) { If (n==1) return 1; If (n==2) return 1; return fib(n-1)+fib(n-2); } # Recursive function in MIPS assembler #prolog FIB: addi $sp, $sp, -12 sw $a0, 0($sp) sw $s0, 4($sp) sw $ra, 8($ra) # body addi $v0, $zero, 1 addi $t0, $zero, 1 beq $a0, $t0, EPILOG#check for n==1 addi $t0, $zero, 2 beq $a0, $t0, EPILOG#check for n==2 addi $a0, $a0, -1 jal FIB#calculate fib(n-1) addi $s0, $zero, $v0# save fib(n-1) to $s0 addi $a0, $a0, -1 #calculate fib(n-2) jal FIB addi $v0, $v0, $s0 #epilog EPILOG: lw $a0, 0($sp) lw $s0, 4,($sp) lw $ra, 8,($sp) addi $sp, $sp, 12 jr $ra /* Recursive function in c */ int fib(int n) { v0 = 1; If (n==1) goto EXIT; If (n==2) goto EXIT; n = n – 1; s0 = fib(n); n = n – 1; v0 = fib(n); v0 = v0 +s0; EXIT: return v0; }
ECE 15B Spring 2011 /* 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); } # Recursive function in MIPS assembler #prolog FIB: addi $sp, $sp, -12 sw $a0, 0($sp) sw $s0, 4($sp) sw $ra, 8($ra) # body addi $v0, $zero, 1 addi $t0, $zero, 1 beq $a0, $t0, EPILOG#check for n==1 addi $t0, $zero, 2 beq $a0, $t0, EPILOG#check for n==2 addi $a0, $a0, -1 jal FIB#calculate fib(n-1) addi $s0, $zero, $v0# save fib(n-1) to $s0 addi $a0, $a0, -1 #calculate fib(n-2) jal FIB addi $v0, $v0, $s0 #epilog EPILOG: lw $a0, 0($sp) lw $s0, 4,($sp) lw $ra, 8,($sp) addi $sp, $sp, 12 jr $ra /* Recursive function in c */ int fib(int n) { v0 = 1; If (n==1) goto EXIT; If (n==2) goto EXIT; n = n – 1; s0 = fib(n); n = n – 1; v0 = fib(n); v0 = v0 +s0; EXIT: return v0; }
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 ECE 15B Spring 2011 stack instructions
Where is the code stored? ECE 15B Spring 2011 stack Code (????) static data dynamic data (heap) RF[$sp] 0 ANS: In main memory
Instruction memory ECE 15B Spring 2011 stack code static data dynamic data (heap) IM: Physically different memory Logically mapped to main memory
Direct mapped cache implementation of instruction memory ECE 15B Spring 2011 Main Main memory Instruction memory At any point in time IM has a copy of a portion of main memory Separate memory (tag) to store which location is currently mapped Tag (28 bit) If upper portion of PC (28 bit) matches tag then IM has right values (hit), otherwise stop execution and load right portion
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v00 $a03 $t00 $s00 $sp0xFFFF0000 $ra0x0108 indexvalue 0xFFFF00000x xFFFF00FC 0xFFFF00F8 0xFFFF00F4 RF (right after execution of initial jal FIB at 0x0104) MM (initial values in stack)
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a02 $t02 $s00 $sp0xFFFF00F4 $ra0x102C indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 RF (after execution jal FIB at 0x1028) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a02 $t02 $s00 $sp0xFFFF00E8 $ra0x102C indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x102C 0xFFFF00EC0 0xFFFF00E82 RF (after execution beq at 0x1020) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a02 $t02 $s00 $sp0xFFFF00F4 $ra0x102C indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x102C 0xFFFF00EC0 0xFFFF00E82 RF (after execution jr at 0x104C) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a01 $t02 $s01 $sp0xFFFF00F4 $ra0x1038 indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x102C 0xFFFF00EC0 0xFFFF00E82 RF (after execution jal at 0x1034) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a01 $t01 $s01 $sp0xFFFF00E8 $ra0x1038 indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x1038 0xFFFF00EC1 0xFFFF00E81 RF (after execution beq at 0x1018) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v01 $a01 $t01 $s01 $sp0xFFFF00F4 $ra0x1038 indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x1038 0xFFFF00EC1 0xFFFF00E81 RF (after execution jr at 0x104C) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v02 $a03 $t01 $s00 $sp0xFFFF00F4 $ra0x0108 indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x1038 0xFFFF00EC1 0xFFFF00E81 RF (after execution jr at 0x104C) MM - stack
Recursive function execution: step by step ECE 15B Spring x0100addi $a0, $zero, 3 0x0104 jal FIB 0x0108 next instruction XXXXXXXXXXXXXXXXXXXXXX FIB: 0x1000addi $sp, $sp, -12 0x1004sw $a0, 0($sp) 0x1008sw $s0, 4($sp) 0x100Csw $ra, 8($ra) 0x1010addi $v0, $zero, 1 0x1014addi $t0, $zero, 1 0x1018beq $a0, $t0, EPILOG 0x101Caddi $t0, $zero, 2 0x1020beq $a0, $t0, EPILOG 0x1024addi $a0, $a0, -1 0x1028jal FIB 0x102Caddi $s0, $zero, $v0 0x1030addi $a0, $a0, -1 0x1034 jal FIB 0x1038addi $v0, $v0, $s0 EPILOG: 0x103Clw $a0, 0($sp) 0x1040lw $s0, 4,($sp) 0x1044lw $ra, 8,($sp) 0x1048addi $sp, $sp, 12 0x104Cjr $ra indexvalue $v0 2 $a03 $t01 $s00 $sp0xFFFF00F4 $ra0x0108 indexvalue 0xFFFF01000x xFFFF00FC0x0108 0xFFFF00F80 0xFFFF00F43 0xFFFF00F00x1038 0xFFFF00EC1 0xFFFF00E81 RF (at the end of program) MM - stack
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