<<

page 1 of 7

ENCM 369 Winter 2014 Lab 12 for the Week of April 7

Steve Norman Department of Electrical & Engineering University of Calgary April 2014

Lab instructions and other documents for ENCM 369 can be found at http://www.enel.ucalgary.ca/People/Norman/encm369winter2014/

1 This Lab is important, but will not be marked

Solutions will be posted sometime during the week of April 7. Please make a serious effort to solve the Exercises yourself before checking so- lutions! You can expect a significant portion of the marks on the final exam to be related to multiplication and division, and to floating-point number representation and arithmetic.

2 Exercise A: Practice with mult, multu, div, divu 2.1 Read This First mult and multu were the original integer MIPS multiplication instructions, and are the ones explained in lectures and your textbook. Please use these instructions in this exercise, not any other instructions. There is one more real MIPS instruction for integer multiplication: mul. The mul instruction has two GPRs as sources, and writes 31–0 of the product directly to a destination GPR. This is useful for compilers—a compiler can avoid using a mflo instruction when only the low 32 bits of an integer product are needed. MARS also allows a lot of pseudoinstructions for integer division and multiplication, for example, allowing constants instead of GPRs as sources. Please avoid these pseudoinstructions. To keep things as simple as possible, the ENCM 360 final exam in Winter 2014 will test you on the real instructions mult, multu, div, and divu, not any other real instructions or pseudoinstructions for integer multiplication or division. Of course, that implies that you also need to know how to use mflo or mfhi to copy a result out of Lo or Hi into a GPR.

2.2 What to Do Copy the files in encm369w14lab12/exA Read the two files. You should see that ex12A.asm is a nearly complete translation of ex12A.—all the tedious work of translating main has been done. However, code must be added to ex12A.asm for the procedures func1 and func2. ENCM 369 Winter 2014 Lab 12 page 2 of 7

Make a copy of ex12A.asm, and add appropriate instructions to func1 and func2 to properly translate the C versions. If you do this correctly, the output of the MARS program should show you the same numbers as the output of the C program. In doing the translation,

• do not modify main in any way; • handle multiplication as a typical C compiler would—the result of multiplying two 32- should be taken as the low 32 bits of the 64-bit product;

• do not worry about the possibility of —in this exercise, you do not need to write code for special behaviour in the case of a zero divisor.

3 Exercise B: IEEE 754 floating-point formats 3.1 Read This First You should be able to do all parts of this exercise with just pencil and paper—the numbers have been up to make the arithmetic easy to do.

3.2 What to Do Answer the following questions. In each case, take time to write down the steps you take to work toward an answer. 1. If the 32-bit IEEE 754 format is being used, what number does the bit pattern 0xc0a8_0000 represent? 2. If the 32-bit IEEE 754 format is being used, what number does the bit pattern 0x3f20_0000 represent? 3. If the 64-bit IEEE 754 format is being used, what number does the bit pattern 0x4015_0000_0000_0000 represent? 4. If the 64-bit IEEE 754 format is being used, what number does the bit pattern 0xfff0_0000_0000_0000 represent? 5. What is the 32-bit IEEE 754 representation of −3.25? Express your final answer using notation. 6. What is the 64-bit IEEE 754 representation of −3.25? Express your final answer using hexadecimal notation.

4 Exercise C: The minifloat type 4.1 Read This First To understand how floating-point number representation and arithmetic work, it’s useful to consider some pencil-and-paper examples. However, doing pencil-and- paper work with 32-bit patterns (or worse, 64-bit patterns) is tedious, so in this exercise we’ll do it with an 8-bit floating-point type called the minifloat type. The minifloat type is intended to mimic the IEEE 754 32-bit and 64-bit floating-point types. With only 8 bits, the precision and range of magnitudes for minifloat will obviously be severely limited. The layout of a minifloat is as follows: ENCM 369 Winter 2014 Lab 12 page 3 of 7

bit 7: bits 3-0: bit fraction

bits 6-4: biased exponent

Before continuing to describe the minifloat type, I would like to introduce a bit of notation. I will use the ** operator (borrowed from the Fortran and Python pro- gramming languages) for ; this is handy when writing mathematics in Web pages and program comments. (So, for example, 2**4 means 24.) Here is the specification for the minifloat type: • The sign bit of a minifloat is 0 for positive numbers and 1 for negative numbers. • The exponent field of a minifloat is used as follows:

– Bit patterns 001, 010, 011, 100, 101 and 110 are used for exponents of normal, nonzero numbers. There is a bias of three in the exponent. – The bit pattern 000 is the exponent field in for representations of zero. (IEEE 754 types use all-0 exponents for zero values and also for very- small-magnitude nonzero values called denormalized numbers; we won’t bother with denormalized numbers in the minifloat type.) – The bit pattern 111 is not used at all. (IEEE 754 types use all-1 expo- nents to indicate special values of Infinity and NaN—“not a number”. We won’t bother with Infinity and NaN in the minifloat type.)

• In a nonzero minifloat, the fraction bits are used to represent the fractional part of the significand. In representations of zero, the fraction bits must all be 0. Now that the uses of the individual fields have been described, it’s possible to determine what (if any) is represented by an 8-bit pattern.

• First of all, both 00000000 and 10000000 represent zero; note that in an IEEE 754 system, there are also two representations of zero. • Next, there are some bit patterns that don’t represent any real number at all. Examples are: 10001010, which has a special exponent of 000 but does not have 0000 in its fraction field; and 01110000, which has the meaningless exponent of 111. • Finally, there are normal, nonzero numbers, such as 01101011. To see what number this is, first split it into fields: the sign bit is 0, the exponent field is 110, and the fraction field is 1011. In base two, then, the number represented is

1.1011 * two ** three Note that the significand is obtained by putting a 1 and a binary point in front of the four-bit fraction field and that the exponent of three is obtained by subtracting the bias of three from the value of six (110). In base ten, the number is

(1 + 1/2 + 1/8 + 1/16) × 23 = 1.6875 × 8 = 13.5. ENCM 369 Winter 2014 Lab 12 page 4 of 7

Let’s consider the problem of determining a minifloat representation of a number given in base 10, say 0.390625. To start with we need to write our number in the form sign * significand * 2 ** exponent where the significand is greater than or equal to 1 and less than 2. This gives us 0.390625 = 1 * 1.5625 * 2 ** (-2) The sign bit should be 0, obviously. The biased exponent should be −2 + 3, or 001 in base two. What is the fractional part of the significand? Here I will cheat a little and just state that 0.5625 is in fact exactly 1/2 + 1/16, so the correct bit pattern is 1001. Putting all the bit fields together, the minifloat representation is 00011001. The fractional part of the significand in a minifloat is bit3 / 2 + bit2 / 4 + bit1 / 8 + bit0 / 16 From this it should be clear that the fractional part of the significand is always an integer multiple of 1/16. Determining the significand bits in the previous example was relatively easy because 0.5625 just happened to be an integer multiple of 1/16. Most base ten fractions are not integer multiples of 1/16, so usually when converting from base ten to minifloat, the fraction will have to be rounded to an integer multiple of 1/16. The following table is useful for doing such rounding: value base two base ten value base two base ten 0/16 0.0000 0.0000 8/16 0.1000 0.5000 1/16 0.0001 0.0625 9/16 0.1001 0.5625 2/16 0.0010 0.1250 10/16 0.1010 0.6250 3/16 0.0011 0.1875 11/16 0.1011 0.6875 4/16 0.0100 0.2500 12/16 0.1100 0.7500 5/16 0.0101 0.3125 13/16 0.1101 0.8125 6/16 0.0110 0.3750 14/16 0.1110 0.8750 7/16 0.0111 0.4375 15/16 0.1111 0.9375 Let’s find a minifloat representation for −3.6, which is −1 × 1.8 × 21. The sign bit is 1 and the exponent field is 100. The fraction bits depend on what rule we choose for rounding. If we use a round-to-nearest rule, the correct choice is 1101, because 0.8 is closer to 0.8125 than it is to 0.7500. With a round-towards-zero rule, the correct choice is 1100. Other rounding rules could be used instead, but in all cases the correct choice will be either 1100 or 1101. So the minifloat representation of −3.6 would be either 11001101 or 11001100; neither representation would be exact.

4.2 What to Do For each of the following minifloat bit patterns, determine the equivalent base ten number, or explain why no such base ten number can be found. 1. 01001100 2. 10101000 3. 11111111 Convert each of the following base ten numbers to a minifloat representation, or explain why the conversion is not possible. If rounding is necessary, use round-to- nearest logic. 4. 0.4 5. −11.0 6. 17.5 ENCM 369 Winter 2014 Lab 12 page 5 of 7

5 Exercise D: Multiplication of minifloats 5.1 Read This First This exercise is designed to help you understand the steps required to multiply two floating-point numbers. The exercise should also give you a general idea of the kinds of components needed in digital hardware for floating-point multiplication. Suppose you are asked to find the product of two minifloats, and the only tools you have are a pencil and some paper. Here is an algorithm that works on positive minifloats only, illustrated with an example. Let’s suppose you are asked to multiply 01101011 and 00101101. • First, extract the bit patterns for biased exponents: 110 and 010. Because of the bias, the actual exponents are 3 = 6 − 3 and −1 = 2 − 3. The sum of the exponents is 2, so you can tentatively set the exponent bits of the product to be 101 (from 2 + 3 = 5). • Second, find the two significands by putting 1’s in front of the 4-bit fractions from the minifloat bit patterns. For the example, 1.1011 (base two) and 1.1101 (base two) are the significands. • Third, multiply the significands. Because they are both greater than or equal to one and less than two, the result will be greater than or equal to one and less than four. In our example, the multiplication produces 11.00001111 (base two), which is just a little larger than three. • Fourth, determine the significand for the overall result. This needs to be greater than or equal to one and less than two. You can achieve that by di- viding 11.00001111 by two to get 1.100001111 and incrementing the exponent of the result from 101 to 110. (Dividing the result by two and incrementing the exponent would be skipped in a case where the product of significands is less than two.) Rounded to five bits, the significand is 1.1000; therefore the fraction bits will be 1000.

• Combine the sign, exponent, and fraction bits to get an overall result, which for the example would be 01101000.

5.2 What to Do Use the algorithm given in “Read This First” to compute 1. the product of minifloats 00110100 and 01000101. 2. the product of minifloats 11001100 and 00101000.

6 Quick Reference for floating-point programming

In order to help you quickly find you need about instructions you will use in this lab, a two-page document called “MIPS floating-point reference for Lab 12” has been created. You can find a link to it on the Web page for ENCM 369 lab instructions. ENCM 369 Winter 2014 Lab 12 page 6 of 7

7 Exercise E: Introduction to floating point in- structions 7.1 What to Do Copy the files from encm369w14lab12/exE Read the file 12Eprog.c. Build an executable and run it to see what the output is. Now study the file 12Eprog.asm, which is a MARS translation of the C program. This provides examples of many of the key MIPS floating-point instructions. Some key things to look at are: • Note that even though the program is doing some floating-point operations, a lot of work is still done using GPRs. In particular, addresses always go in GPRs—never FPRs—even when memory is being used to hold floating-point numbers.

• Note that a double is eight (two words) in size; this matters when saving a double-precision register on the stack, when allocating an array of doubles, and when the address of an array element of type double. • Note how the constants 1.57079632679489661923 and 0.5 get copied from memory to FPRs.

• Note how the expression i * pi_over_2 is handled. There is NO MIPS in- struction that can multiply an int and a double! Instead, three instructions are needed: mtc1 to copy an integer bit pattern from a GPR to an FPR; cvt.d.w to convert an integer bit pattern in an FPR to a double-precision bit pattern in another FPR; and finally a mul.d instruction to do the multiplica- tion. Use MARS to assembler and run the MARS program. You should notice that the MARS program output is very similar to but not exactly the same as the C program output.

8 Exercise F: Quadratic equation solver 8.1 Read This First To do this exercise you should expect to refer repeatedly to documentation for floating-point instructions: Section 3.5 of your textbook, pages B–70 to B–80 of your textbook, and/or the “MIPS floating-point reference for Lab 12” document.

8.2 What to Do Copy the files from encm369w14lab12/exF Build an executable for the C program you find, and run the executable to see what the output is. Note that you will have to use -lm (with letter l not digit 1) on the command line to build the executable—the linker has to be to told to search the C math library to find the sqrt . Study the C code carefully, then complete the MARS translation in quadratic.asm by writing assembly language code for the quadratic procedure—main and test_q are already complete. For this exercise, use the usual register conventions for GPRs and the following conventions for double-precision FPRs:

• Registers $f2, $f4,..., $f10 should be used as temporaries (like $t0–$t9). ENCM 369 Winter 2014 Lab 12 page 7 of 7

• Registers $f20, $f22,..., $f30 should be used as callee-save registers (like $s0–$s7). • Arguments are passed to quadratic in the following registers: $f12 for a, $f14 for b, $f16 for c, $a0 for roots.

9 Exercise G: Sorting an array of doubles 9.1 Read This First As in Exercise F, you should expect to refer frequently to documentation of floating- point instructions.

9.2 What to Do Copy the files from encm369w14lab12/exG Build an executable using the C code you find, and run the executable to see what the output is. Complete the MARS translation of the C program by a writing a correct definition for sort in sort.asm—the MARS code for main is complete and correct. For this exercise, use the usual register conventions for GPRs and the following conventions for double-precision FPRs:

• Registers $f2, $f4,..., $f10 should be used as temporaries (like $t0–$t9). • Registers $f20, $f22,..., $f30 should be used as callee-save registers (like $s0–$s7).

The arguments should be in a-registers because the arguments are pointers or ints.