#pragma qtrvsim show terminal
#pragma qtrvsim show registers
#pragma qtrvsim show memory

.globl _start
.globl __start
    
.org 0x00000200

.text
_start:
	addi	sp,sp,-32   #set stack for main (32 bytes)
	sw	ra,24(sp)   #store return adress in stack
	sw	s0,16(sp)   #store s0 in stack
	addi	s0,sp,32    #set frame pointer to old stack pointer
	mv	a5,a0       
	sw	a1,-32(s0)  #store a1 in stack (caller save)
	sw	a5,-20(s0)  #store a5 in stack (caller save)
	li	a0,2        #set a0 to 2 (argument of fib)
	call	fib         #call fib 
	mv	a5,a0       #get result of fib in r5
	mv	a1,a5       #[...] printf part removed
	jr	ra          #exit from main
fib:
	addi	sp,sp,-48  #set stack for fib (48 Bytes = 6x8bytes (6 words))
	sw	ra,40(sp)  #store return adress in stack
	sw	s0,32(sp)  #store s0 in stack (callee saved) 
	sw	s1,24(sp)  #store s1 in stack (callee saved)
	addi	s0,sp,48   #set frame pointer to old SP
	mv	a5,a0      #get function argument
	sw	a5,-36(s0) #store argument (i) in stack 
	lw	a5,-36(s0) #? it seems that prev. instr. set a5 to 0
	sext.w	a4,a5      #a4 <- i 
	li	a5,1       #a5 <- 1
	bgt	a4,a5,L2   # branch to L1 if i > 1
	li	a5,1       # (else branch) set R5 to 1 (result)
	j	L3         # branch L3
L2:
	lw	a5,-36(s0) #get i (argument of fib) 
	addiw	a5,a5,-1   #compute i-1
	sext.w	a5,a5      #useless ?
	mv	a0,a5      #set i-1 in argument register (s0)
	call	fib        #recursive call to fib(i-1)
	mv	a5,a0      #get result from recursive call fib(i-1)
	mv	s1,a5      #put result in s1
	lw	a5,-36(s0) #get i (argument of fib) 
	addiw	a5,a5,-2   #compute i-2
	sext.w	a5,a5      #useless ?
	mv	a0,a5      #set i-2 in argument register (s0)
	call	fib        #recursive call to fib(i-2)
	mv	a5,a0      #get result from recursive call fib(i-2)
	addw	a5,s1,a5   #a5 <- fib(i-1) + fib(i-2)
	sext.w	a5,a5      #useless? 
L3:
	mv	a0,a5      #put result (1) in a0
	lw	ra,40(sp)  #restore return adresse
	lw	s0,32(sp)  #restore frame pointer
	lw	s1,24(sp)  #restore s1
	addi	sp,sp,48   #remove fib stack 
	jr	ra         #return to caller code


#pragma qtrvsim tab core
