################################################################################ ## ## LSU EE 4720 Spring 2022 Homework 1 ## ## ## Due Midnight 4 February 2022 # Assignment https://www.ece.lsu.edu/ee4720/2022/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 problems in this file and solve them. # # A procedure shell has been provided for each problem. Place # your solution there. # # Assembler code following the problem runs your solution. # 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: # 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/2022/hw01.pdf # # Complete strlen_p1 so that the main loop uses a lw instruction. strlen_p1: ## Register Usage # # CALL VALUE # $a0: Address of first character of string. # This address will be a multiple of 4. # # RETURN # $v0: The length of the string (not including the null). # # Note: # Can modify registers $t0-$t9, $a0-$a3, $v0, $v1. # DO NOT modify other registers. # # [ ] The testbench should show 0 errors. # [ ] Try to reduce the number of executed instructions. # [ ] Do not use pseudoinstructions except for nop. # Do not use: li, la, mov, bgt, blt, etc. # # [ ] Code should be efficient. # [ ] The code should be clearly written. # [ ] Comments should be written for an experienced programmer. addi $v0, $a0, 0 LOOP_P1: lhu $t0, 0($a0) andi $t1, $t0, 0xff00 beq $t1, $0, DONE0 andi $t1, $t0, 0xff bne $t1, $0, LOOP_P1 addi $a0, $a0, 2 sub $v0, $a0, $v0 jr $ra addi $v0, $v0, -1 DONE0: jr $ra sub $v0, $a0, $v0 ################################################################################ ## Problem 2 # # Complete strlen_p2 so that it makes good use of the orc.b instruction. strlen_p2: # CALL VALUE # $a0: Address of first character of string. # This address will be a multiple of 4. # # RETURN # $v0: The length of the string (not including the null). # # Note: # Can modify registers $t0-$t9, $a0-$a3, $v0, $v1. # DO NOT modify other registers. # # [ ] Use lw to load from string. (Replace the lbu) # [ ] Make use of orc.b insn. Consider using clz, clo. # [ ] The testbench should show 0 errors. # [ ] Try to reduce the number of executed instructions. # [ ] Do not use pseudoinstructions except for nop. # Do not use: li, la, mov, bgt, blt, etc. # # [ ] Code should be efficient. # [ ] The code should be clearly written. # [ ] Comments should be written for an experienced programmer. addi $v0, $a0, 1 LOOP_P2: lbu $t0, 0($a0) orc.b $t1, $t0 # Modify code so that $t1 is used! bne $t0, $0, LOOP_P2 addi $a0, $a0, 1 jr $ra sub $v0, $a0, $v0 ############################################################################## # strlen_ref: ## Register Usage # # $a0: Address of first character of string. # $v0: Return value, the length of the string. addi $v0, $a0, 1 # Set aside a copy of the string start + 1. REF_LOOP: lbu $t0, 0($a0) # Load next character in string into $t0 bne $t0, $0, REF_LOOP # If it's not zero, continue addi $a0, $a0, 1 # Increment address. (Note: Delay slot insn.) jr $ra sub $v0, $a0, $v0 ############################################################################## # ## Test Code # # The code below calls the strlen routines. .data str: .align 2 .asciiz "1" .align 2, -1 .asciiz "12" .align 2, -1 .asciiz "123" .align 2, -1 .asciiz "1234" .align 2, -1 .asciiz "12345" .align 2, -1 .asciiz "" .align 2, -1 .asciiz "\"Per aspera, ad astra!\"" .align 2, -1 .ascii "eighteen quintillion, four hundred forty six quadrillion, " .ascii "seven hundred forty four trillion, seventy three billion, " .ascii "seven hundred nine million, five hundred fifty one thousand, " .asciiz "six hundred sixteen" msg: .asciiz "String %/s2/2d: Length %/v1/3d is " msg_good: .asciiz "correct. Took %/s4/3d insn or %/f6/.3f char/insn\n" msg_bad: .asciiz "wrong. Should be %/s7/3d.\n" mut_strlen_p1: .word strlen_p1 .asciiz "strlen_p1 (Problem 1 - Bit Ops)" mut_strlen_p2: .word strlen_p2 .asciiz "strlen_p2 (Problem 2 - RISC V orc insn)" mut_strlen_ref: .word strlen_ref .asciiz "strlen_ref (Simple strlen routine.)" muts: .word mut_strlen_p1 .word mut_strlen_p2 .word mut_strlen_ref .word 0 mut_msg: .asciiz "\n** Starting Test of Routine \"%/t0/s\" **\n" .text .globl __start __start: mtc0 $0, $22 # Pause tracing. addi $s1, $0, 0 TBOUTER: la $t0, muts sll $t1, $s1, 2 add $t1, $t1, $t0 lw $s0, 0($t1) bne $s0, $0, TB_MORE nop addi $v0, $0, 10 # System call code for exit. syscall TB_MORE: la $a0, mut_msg addi $t0, $s0, 4 addi $v0, $0, 11 syscall la $a0, str addi $s6, $a0, 0 # Save copy of string starting address. addi $s2, $0, 0 TBLOOP: addi $a0, $s6, 0 jal strlen_ref addi $s2, $s2, 1 addi $s7, $v0, 0 addi $a0, $s6, 0 addi $v0, $0, -1 lw $t0, 0($s0) mtc0 $v0, $22 # Resume tracing. (No effect if not stepping.) jalr $t0 mfc0 $s5, $9 # Copy current instruction count. (Before.) mfc0 $s4, $9 # Copy current instruction count. (After.) mtc0 $0, $22 # Pause tracing. addi $s4, $s4, -1 sub $s4, $s4, $s5 mtc1 $s4, $f4 cvt.d.w $f4, $f4 mtc1 $v0, $f0 cvt.d.w $f0, $f0 div.d $f6, $f0, $f4 addi $v1, $v0, 0 # Move length of string to $v1 addi $v0, $0, 11 # System call code for message. la $a0, msg # Address of message. syscall la $a0, msg_good beq $v1, $s7 TB_CONTINUE nop la $a0, msg_bad TB_CONTINUE: syscall add $s6, $s6, $s7 ori $s6, $s6, 0x3 addi $s6, $s6, 1 la $a0, msg slt $t0, $s6, $a0 bne $t0, $0, TBLOOP nop j TBOUTER addi $s1, $s1, 1