#
# simple example demonstrating call to recursive procedure
#
# (based on example in Patterson and Hennessy's textbook
#    _Computer Organization and Design_)
#
# Author:  B. Massingill
#
	.text
	.globl	main
#
# opening linkage (save return address)
#
main:
	addi	$sp,$sp,-4
	sw	$ra,0($sp)
#
# register usage:
#	n	$s0
#
	addi	$s0, $zero, 4
	add	$a0, $zero, $s0		# set up parameters for call
	jal	fact			# call fact
	add	$s0, $v0, $zero		# use returned value
# 
# closing linkage (get return address and restore stack pointer)
#
	lw	$ra, 0($sp)		# restore return address
	addi	$sp, $sp, 4
	jr	$ra
#
# recursive factorial function
#
# approximate translation of the following C function:
#
# int fact(int n) {
#     if (n < 1) return 1;
#     else return n * fact(n-1);
# }
#
fact:
# opening linkage (save return address)
	addi	$sp, $sp, -4
	sw	$ra, 0($sp)
# n < 1?
	addi	$t0, $zero, 1		# $t0 has 1
	slt	$t1, $a0, $t0		# $t1 has (n < 1)?
	beq	$t1, $zero, l1
# yes
	addi	$v0, $zero, 1
	j	ret
l1:
# no:
#     save $a0 on stack
	addi	$sp, $sp, -4
	sw	$a0, 0($sp)
#     do recursive call
	addi	$a0, $a0, -1		# $a0 has n - 1
	jal	fact			# $v0 has fact(n-1)
#     restore $a0
	lw	$a0, 0($sp)
	addi	$sp, $sp, 4	
#     finish computation
	mul	$v0, $a0, $v0
# closing linkage (get return address and restore stack pointer)
ret:
	lw	$ra, 0($sp)
	addi	$sp, $sp, 4
	jr	$ra
	.end