# NOTES: 
# This is RISC-V version; 2020
# Use simulator RARS: https://github.com/TheThirdOne/rars/releases (Download only: rars1_4.jar)
# If unsure about an instruction or system-call (i.e., environment-call), always check:
# [instructions]  https://github.com/TheThirdOne/rars/wiki/Supported-Instructions 
# [system calls]  https://github.com/TheThirdOne/rars/wiki/Environment-Calls 

# Program to compute all Fibonacci numbers up to a specified value
# Forward recursive - starts computing the first two numbers, then passes
# those along with the upper limit and count of how many back to itself
# to compute the next one  (really more like iterative than recursive)

# This version uses save registers, which is not entirely necessary
# because the variable values are not needed after the internal subroutine
# call.  Useful to illustrate bookeeping in a recursive program.

.data
m1:  .asciz "Enter limit of Fibonacci series: "
m2:  .asciz "f1\t=\t1\nf2\t=\t1\n"
m3:  .asciz "f"
m4:  .asciz "\t=\t"
t:  .asciz "\t"
n:  .asciz "\n"

.text
.globl main

main:  
  addi  sp, sp, -8#make room on stack
  sw  s0, 4(sp)
  sw  ra, 0(sp)   #push return address 

  li a7, 4        #syscall 4 (print string)
  la a0, m1       #Enter limit of Fibonacci...
  ecall

  li a7, 5        #read limit (s0); user's int will be placed into register a0
  ecall    
  mv s0, a0
  
  li a7, 4        #print f1 and f2
  la a0, m2
  ecall  
  
  li a0 1         #fibonacci(1,1,3,limit);
  li a1 1
  li a2 3
  mv a3 s0
  jal fibonacci
  
  lw s0, 4(sp)
  lw ra, 0(sp)    #pop return address 
  addi sp,sp,8   #reduce the stack
  
  li a7, 10       #terminate the program
  ecall
  
fibonacci:
  addi  sp,sp,-20#make room on stack
  sw  ra, 16(sp)  #push return address 
  sw  s1, 12(sp)  
  sw  s2, 8(sp)  
  sw  s3, 4(sp)  
  sw  s4, 0(sp)  
  mv t0, a0       #copy all of the parameters
  mv s1, a1  
  mv s2, a2  
  mv s3, a3  
  add s4 t0 s1    #int f3 = f1 + f2;
  bgt s4 s3 endif #if (f3 <= limit) {
  
  li a7, 4        #printf("F%d\t=\t%d\n",count,f3);
  la a0, m3
  ecall    
  li a7, 1        #print count
  mv a0 s2
  ecall  
  li a7, 4        #print "\t=\t"
  la a0, m4
  ecall
  li a7, 1        #print f3
  mv a0 s4
  ecall    
  li a7, 4        #print "\n"
  la a0, n
  ecall
  
  mv a0 s1        #fibonacci(f2,f3,++count,limit);
  mv a1 s4
  addi a2 s2 1    #++count
  mv a3 s3
  jal fibonacci
  
endif:  
  lw  ra, 16(sp)  #pop stack stuff 
  lw  s1, 12(sp)  
  lw  s2, 8(sp)  
  lw  s3, 4(sp)  
  lw  s4, 0(sp)  
  addi sp,sp,20   #reduce the stack
  jalr ra         #return
