################################################################################
##
## LSU EE 4720 Spring 2019 Homework 1
##
##
 ## Due Midnight  23 January 2019

 # Assignment https://www.ece.lsu.edu/ee4720/2019/hw01.pdf

 ## Instructions:
  #
  # (0) Read and follow account setup instructions at
  #     https://www.ece.lsu.edu/ee4720/proc.html
  #
  # (1) Use this file for your
  #     solution.  The TA-bot will look first for a file named ~/hw01/hw01.s.
  #     If you have multiple versions make sure the one you want graded
  #     is in ~/hw01/hw01.s.
  #
  # (2) Find the problem in this file and solve it.
  #
  #     A procedure shell has been provided for the each problem.  Place
  #     your solution there.
  #
  #     Assembler code following the problems runs your solutions.
  #     That code can be modified.
  #
  #     Your entire solution should be in this file.
  #
  #     Do not rename the line labels in this file and be sure to use the
  #     directory and filename given above.  (Line labels may be added.)
  #
  # (3) Your solution will automatically be copied from your account by
  #     the TA-bot.  Late submissions can be E-mailed.
  #

 ## Additional Resources
  #
  # MIPS Architecture Manual Volume 2 (Contains a list of instructions.)
  #      https://www.ece.lsu.edu/ee4720/mips32v2.pdf
  #      Note: SPIM implements MIPS-I instructions.
  #
  # SPIM Documentation:
  #      Appendix A of Patterson and Hennessey.
  #      https://www.ece.lsu.edu/3755/spim.pdf
  #
  # Account Setup and Emacs (Text Editor) Instructions
  #      https://www.ece.lsu.edu/ee4720/proc.html
  #      To learn Emacs look for and follow instructions for the Emacs tutorial.
  #
  # Unix Help (Outdated, need a better link.)
  #      https://www.ece.lsu.edu/v/4ltrwrd/


################################################################################
## Problem 1
#
#  Instructions: https://www.ece.lsu.edu/ee4720/2019/hw01.pdf

        .text

get_index:
        ## Register Usage
        #
        # CALL VALUES:
        #  $a0: Address of word to look up. Word will be at least 3 chars.
        #  $a1: Address of start of word table.
        #  $a2: Address of end of word table.
        #  $a3: Address of storage for hash table.
        #
        # RETURN:
        #  $v0: If found, word position (first is 1, second is 2, etc.);
        #       if not found, 0;
        #  $v1: If not in hash table, hash index;
        #       if in hash table, 0x100 + hash index.
        #
        # Note:
        #  Can modify $t0-$t9, $a0-$a3
        #
        # See code in hw01-equiv.cc App::lookup.

        # [ ] Code should be correct.
        # [ ] Code should be reasonably efficient.
        # [ ] Do not use pseudoinstructions except for nop and la.


        jr $ra
        nop



################################################################################
## Testbench Routine
#
# 

.data
word_list_start:
	.asciiz "aardvark"
	.asciiz "ark"
	.asciiz "bark"
	.asciiz "barkeeper"
	.asciiz "persevere"
	.asciiz "bird"
	.asciiz "box"
	.asciiz "sox"
	.asciiz "lox"
	.asciiz "soy"
	.asciiz "sax"
	.asciiz "brain"
word_list_end:
test_words_start:
	.asciiz "ark"
	.asciiz "box"
	.asciiz "sox"
	.asciiz "soy"
	.asciiz "sax"
	.asciiz "sod"
	.asciiz "barkeeper"
	.asciiz "bark"
	.asciiz "woof"
	.asciiz "bar"
	.asciiz "ark"
	.asciiz "bar"
	.asciiz "bark"
	.asciiz "barkeeper"
	.asciiz "arkansas"
	.asciiz "lox"
	.asciiz "box"
	.asciiz "sox"
	.asciiz "sax"
	.asciiz "soy"
	.asciiz "aardvark"
	.asciiz "persevere"
test_words_end:
        .byte 0 0 0 0
        .align 4
results_start:
	.word   2  0x4b  # ark
	.word   7  0x3e  # box
	.word   8  0x2f  # sox
	.word  10  0x3f  # soy
	.word  11  0xac  # sax
	.word   0  0xee  # sod
	.word   4  0x1d  # barkeeper
	.word   3  0x1d  # bark
	.word   0  0x5a  # woof
	.word   0  0x1d  # bar
	.word   2 0x14b  # ark
	.word   0  0x1d  # bar
	.word   3 0x11d  # bark
	.word   4  0x1d  # barkeeper
	.word   0  0x4b  # arkansas
	.word   9  0x30  # lox
	.word   7 0x13e  # box
	.word   8 0x12f  # sox
	.word  11 0x1ac  # sax
	.word  10 0x13f  # soy
	.word   1  0x1e  # aardvark
	.word   5   0xe  # persevere

hash_table:
        .space 1024

msg:
        .asciiz "Pos: %/s1/3d %/t5/1c  Hash 0x%/v1/3x %/t3/1c%/t4/1c  Word: %/s0/s\n"

msg_at_end:
        .asciiz "Done with tests: Errors: %/s3/d pos, %/s5/d hash found, %/s4/d hash idx\n"

        .text
        .globl __start

__start:

        la $s0, test_words_start
        la $s2, test_words_end
        addi $s3, $0, 0  # Word position error count.
        addi $s4, $0, 0  # Hash index error count.
        addi $s5, $0, 0  # Hash found error count.
        la $s6, results_start

TB_WORD_LOOP:
        addi $a0, $s0, 0
        la $a1, word_list_start
        la $a2, word_list_end
        la $a3, hash_table
        jal get_index
        addi $v0, $0, -2

        lw $t0, 0($s6) # Word Position
        beq $t0, $v0, TB_DONE_POS_CHECK
        addi $t5, $0, 95  # '_'
        addi $t5, $0, 88  # 'X'
        addi $s3, $s3, 1
TB_DONE_POS_CHECK:
        lw $t0, 4($s6) # Hash
        andi $t1, $t0, 0x100
        andi $t2, $v1, 0x100
        beq $t1, $t2, TB_DONE_HASH_FOUND_CHECK
        addi $t3, $0, 95  # '_' 
        addi $t3, $0, 88  # 'X' 
        addi $s5, $s5, 1
TB_DONE_HASH_FOUND_CHECK:
        andi $t1, $t0, 0xff
        andi $t2, $v1, 0xff
        beq $t1, $t2, TB_DONE_HASH_IDX_CHECK
        addi $t4, $0, 95  # '_' 
        addi $t4, $0, 88  # 'X' 
        addi $s4, $s4, 1
TB_DONE_HASH_IDX_CHECK:
        addi $s6, $s6, 8
        
        addi $s1, $v0, 0
        la $a0, msg
        addi $v0, $0, 11
        syscall

TB_CHAR_LOOP:
        lbu $t0, 0($s0)
        bne $t0, $0, TB_CHAR_LOOP
        addi $s0, $s0, 1

        slt $t0, $s0, $s2
        bne $t0, $0, TB_WORD_LOOP
        nop

        la $a0, msg_at_end
        addi $v0, $0, 11
        syscall

        addi $v0, $0, 10
        syscall
        nop