Floating Point Addition in MIPS - Normalizing the Mantissa

Need help with normalizing the mantissa bits

Page 1 of 1

0 Replies - 5767 Views - Last Post: 25 November 2009 - 11:50 AM

#1 JackKnifeZero  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-September 08

Floating Point Addition in MIPS - Normalizing the Mantissa

Post icon  Posted 25 November 2009 - 11:50 AM

This is for a Lab for my computer architecture class. The lab wants us to implement floating-point addition in MIPS without using the floating point instructions that MIPS provides. I know the overall algorithm of floating point addition but I'm having trouble actually implementing it and right now I'm stuck on how to normalize the mantissa part. I know that it needs to be 24 bits long but I'm not sure about how to check and see if the data in a register like $t0 is 24 bits long. Then if it is not 24 bits long then it needs to be shifted to the right until it is.

Part of the lab instructions say that our addition function needs to only deal with adding positive numbers and doesn't need to detect overflow and underflow. Also, it says that we don't need to do rounding because it is complicated and for this assignment truncation is fine (even if it is less accurate). "Your code will never actually need to perform a left shift for normalization, because of the restriction that it only needs to handle strictly positive numbers." I just noticed this part...is it possible that it is referring to normalizing the mantissa? I don't think so because to normalize the mantissa you wouldn't ever need to shift to the left would you? It should all be to the right....I think.

Anyway the lab has code that will call our function to test it so here is my code so far...also I'm very new to MIPS and assembly language in general if you see anything that is just horribly wrong please tell me :) For instance, I feel like the way I'm using the jal is wrong but I'm not sure. Also the code we write is in the code that the lab provides to test with so the lab's code calls my function using a jal instruction.

# Here is the procedure that performs floating point addition of
# single-precision numbers.  IT SHOULD NOT USE ANY OF THE MIPS
# BUILT-IN FLOATING POINT INSTRUCTIONS.  Also, don't use any of
# the registers $s0-$s7, or any floating point registers (because
# these registers are used by the main program). Finally, don't
# forget to add comments to each line of code that you write.
#
# Remember the single precision format (see page 276):
#		  bit 31 = sign (1 bit)
#	  bits 30-23 = exponent (8 bits)
#	   bits 22-0 = fraction (23 bits)
#

# Describe your register usage here
#	$t0 - used for masking
#	$t1 - first value's exponent
#	$t2 - second value's exponent
#	$t3 - first value's fraction/mantissa
#	$t4 - second value's fraction/mantissa
#	$t5 - used for comparing exponents
#	$t6 - shift amount

# YOUR CODE GOES BELOW

flpadd: 
	#prepare $t0 for masking exponent bits
	lw $t0, emask

	#get first value's exponent and shift it down	
	and $t1, $f1, $t0
	srl $t1, $t1, 23

	#get second value's exponent and shift it down
	and $t2, $f2, $t0
	srl $t2, $t2, 23

	#prepare $t0 for masking fraction bits
	lw $t0, fmask

	#get first value's fraction
	and $t3, $t3, $t0

	#get second value's fraction
	and $t4, $t4, $t0

	#prepare $t0 for appending a 1 to fraction to create mantissa using given ibit
	lw $t0, ibit
	
	#append a leading one to both value's fraction bits to create mantissa
	or $t3, $t3, $t0
	or $t4, $t4, $t0

	#Compare the exponents
	jal compareExp

	#normalize the mantissa
	#I am stuck here...how do I check the length of the data in $t7 to see if it is 24 bits long?

	jr $ra		# return to caller
	
compareExp:
	#if the exponents are equal then branch to adding the Mantissas
	beq $t1, $t2, addMantissas

	#test to see if exponent 1 is less than exponent 2
	#if $t5 == 1, then exponent 1 < exponent 2; if $t5 == 0, then exponent 1 > exponent 2
	slt $t5, $t1, $t2
	
	#if exponent 2 < exponent 1 then branch to expOne
	beq $t5, $0, expOne

	#otherwise exponent 2 > exponent 1 ($t5 = 1) so subtract expontent 1 from expontent 2
	sub $t6, $t2, $t1

	#$t6 is the shift amount so shift the smaller mantissa to the right that amount
	srav $t3, $t3, $t6

	#add the Mantissas
	j addMantissas

expOne:
	#exponent 1 > exponent 2 so subtract exponent 2 from exponent 1
	sub $t6, $t1, $t2

	#$t6 is the shift amount so shift the smaller mantissa to the right that amount
	srav $t4, $t4, $t6
	
	#add the Mantissas
	j addMantissas

addMantissas:
	#add the Mantissas
	add $t7, $t3, $t4

	jr $ra 			#return to caller





And just in case anyone is curious or wants to see the ENTIRE thing...here is my code within the context of the lab's provided code:

# Lab 7: Floating Point Addition
# E85, Harris

# Solutions, David_Harris@hmc.edu and Sarah_Harris@hmc.edu 2007

# The numbers below are loaded into memory (the Data Segment)
# before your program runs.  You can use a lw instruction to
# load these numbers into a register for use by your code.

		.data
atest:  .word 0x40000000 # you can change this to anything you want
btest:  .word 0x40000000 # you can change this to anything you want
fmask:  .word 0x007FFFFF # mask for masking the fraction bits
emask:  .word 0x7F800000 # mask for masking the exponent
ibit:   .word 0x00800000 # mask for the implicit leading one
obit:   .word 0x01000000 # mask for the overflow bit
		.text

# The main program computes e using the infinite series, and
# calls your flpadd procedure (below).
#
# PLEASE DO NOT CHANGE THIS PART OF THE CODE
#
# Here is an explanation of the usage of each register in this code:
#	$s0 - 1 (constant integer)
#	$s1 - i (loop index variable)
#	$s2 - temp
#	$f0 - 1 (constant single precision float)
#	$f1 - e (result accumulator)
#	$f2 - 1/i!
#	$f3 - i!
#	$f4 - temp
		
main:   li $s0,1				# load constant 1
		mtc1 $s0,$f0			# copy 1 into $f0
		cvt.s.w $f0,$f0		 # convert 1 to float
		mov.s $f1,$f0		   # initialize result accumulator
		li $s1,1				# initialize loop index
		mov.s $f3,$f0		   # initialize i! to 1
tloop:  addi $s2,$s1,-11		# determines how many terms are computed
		beq $s2,$0,end		  # terminate loop
fact:   mtc1 $s1,$f4			# copy i into $f4
		cvt.s.w $f4,$f4		 # convert i to float
		mul.s $f3,$f3,$f4	   # update running fact
		div.s $f2,$f0,$f3	   # compute 1/i!
#	   add.s $f1,$f1,$f2	   # we use your flpadd procedure instead!
		mfc1 $a0,$f1			#\  These lines should do the same thing
		mfc1 $a1,$f2			# \ as the commented out line above.
		jal flpadd			  # / This is where we call your procedure.
		mtc1 $v0,$f1			#/
		addi $s1,$s1,1		  # increment i
		j tloop				 #
end:	j end				   #



# If you have trouble getting the right values from the program
# above, you can comment it out and do some simpler tests using
# the following program instead.  It allows you to add two numbers
# (specified as atest and btest, above), leaving the result in $v0.

#main:   lw $a0,atest
#		lw $a1,btest
#		jal flpadd
#end:	j end


# Here is the procedure that performs floating point addition of
# single-precision numbers.  IT SHOULD NOT USE ANY OF THE MIPS
# BUILT-IN FLOATING POINT INSTRUCTIONS.  Also, don't use any of
# the registers $s0-$s7, or any floating point registers (because
# these registers are used by the main program). Finally, don't
# forget to add comments to each line of code that you write.
#
# Remember the single precision format (see page 276):
#		  bit 31 = sign (1 bit)
#	  bits 30-23 = exponent (8 bits)
#	   bits 22-0 = fraction (23 bits)
#

# Describe your register usage here
#	$t0 - used for masking
#	$t1 - first value's exponent
#	$t2 - second value's exponent
#	$t3 - first value's fraction/mantissa
#	$t4 - second value's fraction/mantissa
#	$t5 - used for comparing exponents
#	$t6 - shift amount

# YOUR CODE GOES BELOW

flpadd: 
	#prepare $t0 for masking exponent bits
	lw $t0, emask

	#get first value's exponent and shift it down	
	and $t1, $f1, $t0
	srl $t1, $t1, 23

	#get second value's exponent and shift it down
	and $t2, $f2, $t0
	srl $t2, $t2, 23

	#prepare $t0 for masking fraction bits
	lw $t0, fmask

	#get first value's fraction
	and $t3, $t3, $t0

	#get second value's fraction
	and $t4, $t4, $t0

	#prepare $t0 for appending a 1 to fraction to create mantissa using given ibit
	lw $t0, ibit
	
	#append a leading one to both value's fraction bits to create mantissa
	or $t3, $t3, $t0
	or $t4, $t4, $t0

	#Compare the exponents
	jal compareExp

	#normalize the mantissa
	#I am stuck here...how do I check the length of the data in $t7 to see if it is 24 bits long?

	jr $ra		# return to caller
	
compareExp:
	#if the exponents are equal then branch to adding the Mantissas
	beq $t1, $t2, addMantissas

	#test to see if exponent 1 is less than exponent 2
	#if $t5 == 1, then exponent 1 < exponent 2; if $t5 == 0, then exponent 1 > exponent 2
	slt $t5, $t1, $t2
	
	#if exponent 2 < exponent 1 then branch to expOne
	beq $t5, $0, expOne

	#otherwise exponent 2 > exponent 1 ($t5 = 1) so subtract expontent 1 from expontent 2
	sub $t6, $t2, $t1

	#$t6 is the shift amount so shift the smaller mantissa to the right that amount
	srav $t3, $t3, $t6

	#add the Mantissas
	j addMantissas

expOne:
	#exponent 1 > exponent 2 so subtract exponent 2 from exponent 1
	sub $t6, $t1, $t2

	#$t6 is the shift amount so shift the smaller mantissa to the right that amount
	srav $t4, $t4, $t6
	
	#add the Mantissas
	j addMantissas

addMantissas:
	#add the Mantissas
	add $t7, $t3, $t4

	jr $ra 			#return to caller




Thanks for any input and/or advice!

Is This A Good Question/Topic? 0
  • +

Page 1 of 1