CPS104 Exam 1 Feb 29, 2000 1. Certain error conditions can, and must, be detected by the MYMIPS interpreter. These are conditions which can be generated by some (incorrect) MYMIPS program, and detected during interpretation. For each error message listed below, indicate what C code, if any, the MYMIPS interpreter (NOT the assembler) could use to detect it. (For some messages, the correct answer is that the condition is NOT an error; for others, the condition is not detectable by the interpreter.) Explain your answers briefly, also. a. Address outside memory boundaries Addresses in MYMIPS are taken modulo 2^19. After this operation is applied the result lies in the range 0..(2^19 - 1), and is legal, because MYMIPS memory has size 2^19 bytes. b. Address not aligned LW, STW and values placed in the PC (say, by a branch operation) must be aligned on WORD boundaries, i.e. be a multiple of 4. The fastest check for this is: if ((Addr & 3) != 0) error("Alignment"); c. Branch to data segment This can occur, but cannot be detected. d. Illegal operation code Use a switch to distinguish among all op-codes. Its default case can trigger the fatal error: switch (Op) { case 0: // handle syscall ... case 15: // handle Branch and Link break; default: error("Illegal opcode"); } This can occur, because opcodes 11, 12, and 13 are undefined by MYMIPS. e. Illegal branch condition Branch conditions 0..7 are defined. However, a D field value can be anything in the range 0..15. Use a switch as in d., or if (d>7) error("Illegal branch condition"); // slower than use of a switch f. Illegal SYSCALL SYSCALL operations are defined when eu() has values 0, 1, 4, 5, 6, and 10. All others are illegal. So is 0, actually. Use a switch to handle the defined cases, and have its default execute error("Illegal syscall"); g. Illegal destination register number The destination register field occupies 4 bits of an instruction, and thus can hold a value in the range 0..15. Each of these values represents a legal register number, so this error CANNOT OCCUR. There is some controversy over whether 0 should be legal. The MYMIPS specs states that this register always holds the value 0, and implies that an attempt to change it is legal, by stating that "this should be enforced, by setting R[0]=0; before executing each instruction. h. Illegal source register number Each source register field occupies 4 bits of an instruction, and thus can hold a value in the range 0..15. Each of these values represents a legal register number, so this error CANNOT OCCUR. i. Immediate constant too large The imm field holds 19 bits. If the user WANTED a larger constant, the assembler would have had to catch the error. To the interpreter, any possible value in the imm field is valid. j. Result of addition outside representable range This can occur, and is detectable: Suppose X and Y are the values being added. if (X>=0) { if ((Y>=0) && (X+Y<0)) detect_overflow(); } else ( if ((Y<0) && (X+Y>=0)) detect_overflow(); } 2. Convert each of the following numbers to single precision floating point representation, showing the steps of your work, and ending with hexadecimal representations for each of them: a. 2.75 2.75 = 10.11b = 1.011 * 2^1. M = 0110..., E = 1+127 = 10000000, S=0. 0 100|0000|0 011|000...0 = 40300000 b. -4.00 4.00 = 100.0b = 1.00*2^2. M=0..0, S=1, E=2+127 = 10000001 1 100|0000|1 000|0000| ... = C0800000 3. What value do you get, in hexadecimal and decimal, when you add -8.00 and 8.125 together, as single-precision floating point numbers? -8.00 = 1000.0b = 1.0*2^3. M=00.., E=130=10000010, S=1. 8.125 = 1000.001 = 1.000001*2^3. M=0000010000, E=130=10000010, S=0. Exponents are the same, so no shifting needed to align fraction parts: -1.000000b These numbers have different signs, and must be subtracted +1.000001b ---------- 0.000001b, E=130. This number must be SCALED (shifted left, while adjusting exponent down), until its F is of the form 1.0: .000001b = 1.0*2^-6, giving new E of 130-6 = 124 = 11111100, M=0, S=0 0 111|1110|0 000000... = 7E000000 4. Write an RMI program which, given an integer in variable A, places the field consisting of bits 30..28 of that integer in the low-order 3 bits of variable B. The program should set the other 29 bits of B to zero. Do not use any constants larger than 100 in magnitude in this program. Of course, it should run quickly, as well (less than 20 basic RMI instructions). #define ADD(X,A,B) \ SUB(T,0,B);\ SUB(X,A,T); // Comments below assume A now holds the value "a" ADD(A,A,A); // eliminate bit 31 SUB(B,0,0); // Set B to 0 BNN(A,L1); // go if a<30> == 0 SUB(B,B,-4); // set B<2> to 1 L1: ADD(A,A,A); // shift A left, eliminating bit 30 BNN(A,L2); // go if a<29> == 0 SUB(B,B,-2); L2: ADD(A,A,A); BNN(A,L3); // go if a<28> == 0 SUB(B,B,-1); L3: 5. Write a SPIM program to solve the same problem as in question 4, allocating space for variables A and B in memory properly. Your program should be a complete "main" procedure which returns properly. .data .align 2 A: .word 0 B: .word 0 .text .align 2 .globl main main: lw $t0, A srl $t0, $t0, 28 andi $t0, $t0, 7 sw $t0, B jr $ra 6. Show the 12-bit 2's complement hexadecimal representation of each of the numbers below, and of their sum, again in 12-bit 2's complement: a. 6 b. -8 6 = 006, -8 = ~008+001 = FF7 + 001 = FF8 006 FF8 --- FFE = -2