# This program implements three silly functions.  
# In math notation, they are:
#
#  f(x,y) = g(y-1,x+1)-2
#
#  g(x,y) = h(2-y,x*2)+1
#
#  h(x,y) = x+y
#
# The main program calls f with arguments 1 and 7, then prints the results.
# Written by Scott D. Anderson, February 15, 1999

	.data
	.align 2
ans:	.asciiz "The answer is: "
nl:	.asciiz "\n"
	.text
	.globl main
main:	nop
	subu $sp $sp 4		# make room on stack for one word
	sw $ra 0($sp)		# save return address on stack

	li $a0 1		# load args
	li $a1 7
	jal f
	move $t0 $v0		# save result
	li $v0 4		# code to print string
	la $a0 ans
	syscall
	li $v0 1		# code to print integer
	move $a0 $t0		# retrieve result
	syscall
	li $v0 4		# code to print string (final newline)
	la $a0 nl
	syscall

	lw $ra 0($sp)		# re-load return address
	addu $sp $sp 4		# pop stack
	jr $ra			# done

### ################################################################
	
f:	subu $sp $sp 12		# space for 3 words on stack
	sw $a0 0($sp)		# put A0 in first elt of stack frame
	sw $a1 4($sp)		# put A1 in second elt of stack frame
	sw $ra 8($sp)		# put RA in third elt of stack frame
	addi $t0 $a1 -1		# t0 = y-1
	addi $a1 $a0 1		# second arg is x+1
	move $a0 $t0		# first arg is t0 = y-1
	jal g			# call g
	addi $v0 $v0 -2		# result is g(y-1,x+1)-2
	lw $a0 0($sp)		# retrieve A0
	lw $a1 4($sp)		# retrieve A1
	lw $ra 8($sp)		# retrieve return address
	addu $sp $sp 12		# restore stack pointer
	jr $ra			# return from subroutine

### ################################################################
	
g:	subu $sp $sp 12		# space for 3 words on stack
	sw $a0 0($sp)		# put A0 in first elt of stack frame
	sw $a1 4($sp)		# put A1 in second elt of stack frame
	sw $ra 8($sp)		# put RA in third elt of stack frame
	add $t0 $a0 $a0		# t0 = x*2
	li $t1 2		# need this temporary for the subtraction
	sub $a0 $t1 $a1		# first arg is 2-y
	move $a1 $t0		# second arg is t0 = x*2
	jal h			# call h
	addi $v0 $v0 1		# result is h(y/2,x*2)+1
	lw $a0 0($sp)		# get A0 from first elt of stack frame
	lw $a1 4($sp)		# get A1 from second elt of stack frame
	lw $ra 8($sp)		# get RA from third elt of stack frame
	addu $sp $sp 12		# remove 3 words from stack
	jr $ra			# return from subroutine

### ################################################################
	
h:	add $v0 $a0 $a1		# value is x+y
	jr $ra			# return from subroutine

