################################################################################
##
## Solution to LSU EE 3755 Fall 2001 Homework 4
##
## Name:
## Instructions:
#
# Copy this to a file named hw04sol.s to directory ~/hw in your
# class account. (~ is your home directory.) Use this file for your
# solution.
#
# Procedure shells have been provided for each problem. Place
# your solution within the respective shells.
#
# The code at the top runs a test on each problem. That code
# code can be modified, for example, only calling the test
# for the problem currently being worked on.
#
# Your entire solution should be in this file. The solution to
# Problem 0 is not being collected.
#
# 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.)
# Assignment: http://www.ece.lsu.edu/ee3755/2001f/hw04.pdf
################################################################################
## Main Routine
.text
.globl __start
__start:
jal test_countlz # Comment out this line to skip this test.
nop
jal test_itos # Comment out this line to skip this test.
nop
DONE:
addi $v0, $0, 10 # Code for the exit system call.
syscall
nop
################################################################################
## Solution to Problem 1
.globl countlz
countlz:
## Register Usage
#
# $a0: Input value. (Modified by this routine.)
# $v0: Return value.
addi $v0, $0, 33
CLZ_LOOP:
addi $v0, $v0, -1
bne $a0, $0, CLZ_LOOP
srl $a0, $a0, 1
jr $ra
nop
################################################################################
## Solution to Problem 2
.globl itos
itos:
## Register Usage
#
# $a0: i: Input value, the integer to convert.
# $v0: Return value, $a0 value in IEEE 754 format.
# Holds return value while "under construction."
# $t0: Sign bit.
# $t1: Number of leading zeros in absolute value of i.
# $t2: Exponent.
bne $a0, $0, ITOS_NONZERO
nop
jr $ra # Return zero if integer is zero.
add $v0, $0, $0
ITOS_NONZERO:
bgez $a0, ITOS_ABS
slt $t0, $a0, $0 # t0 -> sign of integer.
sub $a0, $0, $a0
ITOS_ABS:
clz $t1, $a0 # t1 -> number of leading zeros.
sllv $v0, $a0, $t1
sll $v0, $v0, 1
srl $v0, $v0, 9 # v0 -> significand
addi $t2, $0, 158
sub $t2, $t2, $t1 # t2 -> Biased exponent in bits 7:0
sll $t2, $t2, 23 # t2 -> Biased exponent in bits 30:23
or $v0, $v0, $t2 # v0 -> biased exponent, significand
sll $t0, $t0, 31 # t0 -> Sign bit at bit 31
jr $ra
or $v0, $v0, $t0 # v0 -> sign bit, biased exponent, significand
################################################################################
## Test Code for countlz
.data
clzt_data:
# Test numbers for countlz. Additional tests can be added.
# Zero can only appear as the last number.
.word 0x1, 0xf, 0xfab, 0x72345678, 0x8fffffff
.word 0
clzt_pass_msg:
.asciiz "All countlz tests passed.\n"
clzt_fail_msg:
.ascii "Test countlz failed. "
.asciiz "Number in $a1, $t1 (correct) != $t2 (wrong)\n"
clzt_fail_fmt:
.ascii "Test countlz failed. "
.asciiz "Number 0x%/s1/x: lz %/t1/d (correct) != %/t2/d (wrong)\n"
.text
.globl test_countlz
test_countlz:
addi $sp, $sp, -16
sw $ra, 12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)
la $s0, clzt_data
add $s2, $0, $0
CLZT_LOOP:
lw $a0, 0($s0)
jal countlz
add $s1, $a0, $0
clz $t1, $s1
bne $t1, $v0 CLZT_FAIL
addi $s0, $s0, 4
bne $s1, $0, CLZT_LOOP
nop
la $a0, clzt_pass_msg
j CLZT_MSG
nop
CLZT_FAIL:
la $a0, clzt_fail_fmt
add $t2, $v0, $0
CLZT_MSG:
li $v0, 11
syscall
lw $ra, 12($sp)
lw $s2, 8($sp)
lw $s1, 4($sp)
lw $s0, 0($sp)
jr $ra
addi $sp, $sp, 16
################################################################################
## Test Code for itos
.data
itost_data:
# Test numbers for countlz. Additional tests can be added.
# Zero can only appear as the last number.
.word 1, -1, 2, -2, 5, -5, 3755, -3755
.word 2123456789, -2123456789
.word 0x100fffff, 0x1fffffff, 0x1abcdef
.word 0
itost_pass_msg:
.asciiz "All itos tests passed.\n"
itost_fail_msg:
.ascii "Test itos failed. "
.asciiz "Integer in $t3, $t1 (correct) != $t2 (wrong)\n"
itost_fail_fmt:
.ascii "Test itos failed. "
.ascii "Integer %/t3/d, 0x%/t1/08x (correct) != 0x%/t2/08x (wrong)\n"
.asciiz " FP: %/f0/.f (correct) != %/f2/.f (wrong)\n"
.text
.globl test_itos
test_itos:
addi $sp, $sp, -16
sw $ra, 12($sp)
sw $s2, 8($sp)
sw $s1, 4($sp)
sw $s0, 0($sp)
la $s0, itost_data
add $s2, $0, $0
ITOST_LOOP:
lw $a0, 0($s0)
jal itos
add $s1, $a0, $0
bgez $s1, ITOST_POS_1
add $s2, $0, $s1
sub $s2, $0, $s1
ITOST_POS_1:
clz $t0, $s2
sllv $s2, $s2, $t0
srl $s2, $s2, 8
sll $s2, $s2, 8
bgez $s1, ITOST_POS_2
srlv $s2, $s2, $t0
sub $s2, $0, $s2
ITOST_POS_2:
mtc1 $s2, $f0
cvt.s.w $f0, $f0
mfc1 $t1, $f0
bne $t1, $v0 ITOST_FAIL
addi $s0, $s0, 4
bne $s1, $0, ITOST_LOOP
nop
la $a0, itost_pass_msg
j ITOST_MSG
nop
ITOST_FAIL:
la $a0, itost_fail_fmt
add $t2, $v0, $0
add $t3, $s1, $0
mtc1 $v0, $f2
cvt.d.s $f2, $f2
cvt.d.s $f0, $f0
ITOST_MSG:
li $v0, 11
syscall
lw $ra, 12($sp)
lw $s2, 8($sp)
lw $s1, 4($sp)
lw $s0, 0($sp)
jr $ra
addi $sp, $sp, 16