#   Histogram example
##  Register usage:

        .data
list:   .word   19, 13, 2, 7, 11, 5, 23, 29, 17, 3, 47, 21, 84, 77, 14, 92, 36, 41, 32, 9
size:   .word   20

        .text
########################################################### main
main:
        la      $a0, list
        lw      $a1, size
        jal     mod5_histogram
	
done:
        li	    $v0, 10
        syscall


########################################################### mod5_histogram
# Creates and prints a histogram counting the non-negative integers
# in a list according their mod5 equivalence classes.
#
# Arguments:  $a0:  address of array of integers
#             $a1:  number of values in array
#
mod5_histogram:

        bltz    $a1, exit           # quit on invalid list

        addi    $sp, $sp, -20       # space for histogram on stack
        sw      $zero, 16($sp)
        sw      $zero, 12($sp)
        sw      $zero,  8($sp)
        sw      $zero,  4($sp)
        sw      $zero,  0($sp)
	
make:   or      $a2, $sp, $zero     # pass address of histogram
        addi    $sp, $sp, -4
        sw      $ra, ($sp)
        jal     make_histogram
        lw      $ra, ($sp)
        addi    $sp, $sp, 4
	
print:  or      $a1, $sp, $zero
        li      $a0, 5
        addi    $sp, $sp, -4
        sw      $ra, ($sp)
        jal     prnt_histogram
        lw      $ra, ($sp)
        addi    $sp, $sp, 4
	
        addi    $sp, $sp, 20
	
exit:   jr      $ra

########################################################### make_histogram
make_histogram:

        ori     $t0, $a2, 0         # get handle on histogram
        li      $t1, 0              # set loop counter
	
build:  bge     $t1, $a1, quit      # finished with list analysis?
        lw      $t2, ($a0)          # get next list elem
        li      $t5, 5
        rem     $t2, $t2, $t5       # get elem mod 5
        sll     $t2, $t2, 2         # compute offset
        add     $t3, $t0, $t2       # compute array address
        lw      $t4, ($t3)          # retrieve histogram value
        addi    $t4, $t4, 1         # increment counter
        sw      $t4, ($t3)          # put counter back
	
        addi    $t1, $t1, 1         # count this pass
        addi    $a0, $a0, 4         # step to next list elem
        j       build               # continue with next list elem

quit:   jr      $ra


prnt_histogram:
########################################################### prnt_histogram
#  $a0 = size of list
#  $a1 = address of list
#
        .data
sep:    .asciiz ":  "
nl:     .asciiz "\n"

        .text
	
        move     $t1, $a1      # put address of list in temp register
        li       $t2, 0        # initialize loop counter
        move     $t3, $a0      # put size of list in temp register
print_loop:
        beq      $t2, $t3, print_loop_end    # stop after last elem is printed
	
        or	     $a0, $t2, 0                 # print the loop counter
        li	     $v0, 1
        syscall
	
        la	     $a0, sep                 # print a separator value
        li	     $v0, 4
        syscall
	
        lw	     $a0, ($t1)               # print the value at the array pointer
        li	     $v0, 1
        syscall
	
        la	     $a0, nl                  # print a newline
        li	     $v0, 4
        syscall
	
        addi     $t2, $t2, 1              # increment the loop counter
        addi     $t1, $t1, 4              # step to the next array elem
        j        print_loop               # repeat the loop
print_loop_end:
        jr       $ra

