CS 281 Midterm Exam Solutions -- Fall 2017 Problem #1 ========== Here's the mystery routine again, with some comments: mystery: addi $sp, $sp, -8 ### Stack code sw $s0, 0($sp) ### Stack code sw $s1, 4($sp) ### Stack code li $s0, 1 # Keep a 1 around for later here: slt $s1, $a0, $s0 # Is $a0 less than 1? beq $s1, $s0, there # If so, jump out of loop sub $a0, $a0, $a1 # else subtract off $a1 from $a0 j here # jump back up to top of loop there: li $v0, 1 # Assume we'll "return" a 1 beq $a0, $zero, gone # If $a0 is 0, jump to end (1 is right) li $v0, 0 # Else, right answer is 0; load into $v0 gone: lw $s0, 0($sp) ### Stack code lw $s1, 4($sp) ### Stack code addi $sp, $sp, 8 ### Stack code jr $ra # Go back to caller In English, it determines whether or not its first input is evenly divisible by its second. It subtracts $a1 off of $a0 repeatedly until it hits zero or goes negative, then stops and returns a 1 (if we hit zero) or a 0 (if we went past zero before stopping). Problem #2 ========== The routine uses $s0 and $s1, and must therefore store their contents to memory before proceeding, and restore those values before returning. The stack code has been added to the version shown above. We don't need to store $a0, $a1, or $ra since we don't call any other routines or otherwise mess up those registers. Problem #3 ========== a) 10111101 --> 189 01100111 --> 103 b) 10111101 --> -67 01100111 --> 103 c) 1111111 10111101 01100111 -------- 00100100 --> 36, regardless of whether inputs are signed or unsigned d) Yes, whether we consider it unsigned or signed. You only have to look at the left-most column. If the inputs are unsigned, a bit "falls off the end" so overflow has occurred. If inputs are signed, a carry bit falls into the left-most column, so overflow has occurred (the sign of the result has been affected). Problem #4 ========== 750x10^9 instructions, divided into three classes: 40% take 2 cycles, 30% take 3, and 30% take 5. a) We can do it the "long" way and actually calculate the number of instructions in each category: (750x10^9 x 40% x 2) + (750x10^9 x 30% x 3) + (750x10^9 x 30% x 5) ------------------------------------------------------------------ 750 x 10^9 Or we can leave the 750x10^9 out of things and just use the percentages to weight the cycle counts in each category: 40% x 2 + 30% x 3 + 30% x 5 = 3.2 cycles/instruction b) 750x10^9 inst * 3.2 cycles/inst Time = ------------------------------- = 960 seconds 2.5x10^9 cycles/sec c) We can recycle the formula above to get: 750x10^9 inst * 3.2 cycles/inst Time = ------------------------------- = 800 seconds X cycles/sec Solving for X, we get a clock rate of 3x10^9 or 3 GHz. d) One way to solve this is to see how long the program would take WITHOUT removing any Class C instructions, then figure out how many would need to be removed to hit the target. Without any optimization, we know it would take 960 seconds, as found in part b). We're trying to get down to 800 seconds so we need to shave 160 seconds. How many Class C instructions is that? 160 sec x 2.5x10^9 cycles/sec N = ----------------------------- = 80 x 10^9 = 80 billion 5 cycles/instruction We'd have to cut 80 billion Class C instructions. Problem #6 ========== a) 0 1010 010 --> +1.1010 x 2^2 = 110.10 x 2^0 That's 6.5 in base 10. b) The best we could do is 1.1111 x 2^3. That uses the largest possible exponent, and packs in as many 1's as possible in the significand. That turns into 1111.1 x 2^0 or 15.5 in base 10. c) It would increase the maximum exponent size from 3 to 7, allowing a maximum possible BradFloat value of 248. But it also means we can't have negative exponents, so it becomes impossible to represent things like 1/2.