Reputation: 1
I'm really having a difficult time figuring out how to approach this problem. I get that I want to take the binary representation of both the integer and fraction, combine them for the mantissa, and assign the sign bit to the beginning, but I don't know how to actually implement it in MIPS.
Can anyone help me at least get started?
Assume that your MIPS hardware does not have floating-point registers and floating-point ALU. If you want to perform floating point addition, you will have to use MIPS integer instructions that use the integer registers ($0 - $31) and the integer ALU to get the job done. In this assignment question, you will write MIPS code, using integer instructions and integer registers only, to implement a procedure to add two float-point numbers and to write a main function to call the procedure.
Write a MIPS procedure toFloat to put a floating-point number into IEEE single-precision format. The procedure takes three integers as input: $a0, $a1, $a2, which represents a floating-point number in this way: If $a0 contains 0, the floating-point number is positive, else if $a0 contains 1, the floating-point number is negative. The number stored in register $a1 is the integer part of the floating-point number, and the number stored in register $a2 is the fraction part of the floating-point number. For example, to present the floating-point number -5.25, the three input registers should contain these numbers: $a0 = 1, $a1 = 5, and $a2 = 25. For the fraction part, you can use the div rs rt instruction to divide 25 by 100. The fraction will be stored in the HI register, and you can use the mfhi instruction to retrieve the fraction. The procedure will return v0, which contains the IEEE single-precision pattern corresponding to the floating-point number represented by the three input numbers. Once you have this procedure, you can use it to convert the input numbers 2.5 and 7.5 into their IEEE single-precision format.
Write a MIPS procedure printFloat to print a number that is in the IEEE single-precision format. The input of the procedure is in $a0, which is a number in the IEEE single-precision format. The procedure will simply print the bit pattern stored in $a0. You can use a loop to print each bit. Once you have this procedure, you can use it to print the input number 2.5 and 7.5 in their floating-point format.
Write a MIPS program to implement the main function to call your procedures. In this program, you will call
toFloat(0, 2, 5) to generate the float-point format for 2.5;
toFloat(0, 7, 5) to generate the float-point format for 7.5;
printFloat to print 2.5
printFloat to print 7.5
Here's the code that I have so far:
http://s7.postimg.org/v39ufikaj/code.png
Upvotes: 0
Views: 7524
Reputation: 1076
Ok, the first step (as noted in comments) is to spend some quality time with a converter that show the bits, like the one here: binaryconvert.com floating point converter.
Then, the easy part is to take $a0 and dump bit 0 into bit 1 of our result. Something like:
add $v0, $zero, $zero # initialize our result
sll $t0, $a0, 31 # shift the lsb to the msb
or $v0, $v0, $t0 # set the sign bit in the result
But now we've got to do math. I was hoping that $a1 would be a whole number portion, and $a2 would be a binary fractional portion. But it's not like that... they say $a1 is the whole number (still a whole number in binary), but $a2 is, in effect, cents. (If 25/100 = 0.25 decimal, then $a2 contains cents.)
Here's where I'm getting confused, myself. The instructions say "use the div rs rt instruction to divide 25 by 100. The fraction will be stored in the HI register". But when I read what div
does (MIPS Instruction Reference), it says it puts the quotient in $LO and the remainder in $HI. So dividing 25 by 100 would give you... 25. That's a good way to discard an amount greater than 100, but it doesn't get us to a binary fractional representation of the number.
In fact, I just spent a whole class plus lunch trying to figure out an elegant way to take a number between 0 and 99, divide it by 100, and convert the result to binary without using the FPU. I'm coming up short. So I'll let you ask the prof about that part.
But once we have the whole number portion in $a1, and a string of 1's and 0's representing the fractional part (lets put that in $s2), we just need to normalize it. We have a number in $a1
.$s2
, and we need it to be in this format:
1.nnnnnnn
... where we start with a 1, and then the fractional part is however many binary digits.
Here's some pseudocode that might work.
or
it so that it fills in the least significant bits of $a1Let's see if that works in an example. $a1 has the integer portion of 0x0000C000, and $s2 has somehow been loaded with 0.75 (1 x 2^-1 + 1 x 2^-2)
$a1: 0000 0000 0000 0000 1100 0000 0000 0000
$s2: 1100 0000 0000 0000 0000 0000 0000 0000
I have to shift $a1 16 times:
$a1: 1100 0000 0000 0000 0000 0000 0000 0000
That should give me an exponent of 31 - 16 = 15. Add bias of 127 and I get 142 (0x8E). That goes in the exponent section.
I need to shift $s2 right by the same amount (16):
$s2: 0000 0000 0000 0000 1100 0000 0000 0000
or
those together:
$a1: 1100 0000 0000 0000 1100 0000 0000 0000
Visualize that with a decimal point:
original: 1100 0000 0000 0000.1100 0000 0000 0000
normaliz: 1.100 0000 0000 0000 1100 0000 0000 0000
Because we omit the implied '1' to the left of the decimal point, shift it out and we have:
$a1: 100 0000 0000 0000 1100 0000 0000 0000 0
Take 23 bits of that. So if I've got this right, that converter above should say that 49152.75 stores in an IEEE FP as:
01000111 01000000 00000000 11000000
Sign = 0
Exponent = 10001110 (0x8E)
Mantissa = 1000 0000 0000 0001 1000 000
(Now, try to imagine my surprise that this actually worked!)
Upvotes: 1