CMPE 5 Computer Architecture II Cem Ergün Eastern Mediterranean University Binary Multiplication At each step we multiply the multiplicand by a single digit from the multiplier. In binary, we multiply by either or 0 (much simpler than decimal). Keep a running sum instead of storing and adding all the partial products at the end. Multiplication Longhand multiplication ( 9 = 08) 0 0 = ten (n bit Multiplicand) 0 0 = 9 ten (m bit Multiplier) 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 = 08 ten (n + m bit Product) The result is a number that is n + m bits long Implementing Multiplication Several different ways to implement Things to note about previous method At each step we either copied or set the value to 0 LSBs of the product don t change once computed Can form product by shifting and adding Solution # Shift multiplicand left at each step (same as adding 0 s) Shift multiplier right so we can always consider the 0 th bit Solution # Multiplication without sign ( 9 = 08) 0 0 = ten (n bit Multiplicand) 0 0 = 9 ten (m bit Multiplier) 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 = 08 ten Solution #: Operations Multiplier0 = a. Add multiplicand to product and place the result in Product register Start. Test Multiplier0 Multiplier0 = 0. Shift the Multiplicand register left bit. Shift the Multiplier register right bit Multiplicand 0 0 0 0 0 0 0 0 Multiplier 0 0 Product 0 0 0 0 0 0 0 0 No: < repetitions nd repetition? Yes: repetitions Done 5 6
Solution #: Example Solution #: Hardware Iter Step Multiplier Multiplicand Product 0 Initial Values 00 0000 00 0000 0000 Multiplier[0]= Prod+Mcand 00 0000 00 0000 00 Shift multiplicand left 00 000 000 0000 00 Shift multiplier right 000 000 000 0000 00 Multiplier[0]=0 Do nothing 000 000 000 0000 00 Multiplicand Shift Left Shift multiplicand left 000 00 0000 0000 00 Shift multiplier right 000 00 0000 0000 00 Multiplier[0]=0 Do nothing 000 00 0000 0000 00 6bit ALU Add Multiplier bits Shift multiplicand left 000 00 0000 0000 00 Shift multiplier right 000 00 0000 0000 00 Multiplier[0]= Prod+Mcand 000 00 0000 00 00 Shift multiplicand left 000 00 0000 00 00 Product Shift multiplier right 0000 00 0000 00 00 7 8 Adjustments to Algorithm One big problem with the algorithm/implementation shown: need a 6 bit ALU (adder). Half of the multiplicand bits are always 0 Either high or low bits are 0, even as shifted LSB of product never changes once set Half of the 6 bit adder is therefore wasted We can fix this by: Leaving the multiplicand alone (don t shift). Instead of shifting multiplicand left, shift the product right Add multiplicand to left half of running sum. Adder only needs to be bits wide 9 Solution #: Adjusted Algorithm Revised Addition Shift partial sum instead of multiplicand Multiplier0 = a. Add multiplicand to the left half of the product and place the result in the left half of the Product register Start. Test Multiplier0. Shift the Product register right bit. Shift the Multiplier register right bit nd repetition? Done Multiplier0 = 0 No: < repetitions Yes: repetitions 0 Solution #: Example Solution #: Hardware Iter Step Multiplier Multiplicand Product 0 Initial Values 00 00 0000 0000 Multiplier[0]= Prod+Mcand 00 00 00 0000 Shift product right 00 00 00 0000 Shift multiplier right 000 00 00 0000 Multiplier[0]=0 Do nothing 000 00 00 0000 Multiplicand bits Shift product right 000 00 00 0000 Shift multiplier right 000 00 00 0000 Multiplier[0]=0 Do nothing 000 00 00 0000 Shift product right 000 00 000 000 Shift multiplier right 000 00 000 000 Multiplier[0]= Prod+Mcand 000 00 0 000 Shift product right 000 00 00 00 Shift multiplier right 0000 00 00 00 bit ALU Product Upper bits Add Multiplier bits
Issues and Alternative In the implementation of the adjusted algorithm it is possible to save space by putting the multiplier in the rightmost bits of the product register. If you notice, half of the product register is useless at the beginning At the end, the multiplier register becomes useless Solution # The algorithm is the same, but steps and are done at the same time. Remove the multiplier register Place the multiplier value in the lower half of the product register Solution #: Operations Solution #: Example Solution #: Hardware Iter Step Multiplicand Product 0 Initial Values 00 0000 00 Product[0]= Prod+Mcand 00 00 00 Shift product right 00 00 000 Multiplicand bit ALU bits Add Product[0]=0 Do nothing 00 00 000 Shift product right 00 00 000 Product[0]=0 Do nothing 00 00 000 Shift product right 00 000 00 Product[0]= Prod+Mcand 00 0 00 Shift product right 00 00 00 Product Upper bits Multiplier LSB 5 6 Signed Multiplication Previous algorithms work for unsigned. We could: convert both multiplier and multiplicand to positive before starting, but remember the signs. adjust the product to have the right sign (might need to negate the product). Set the sign bit to make the number negative if the multiplicand and multiplier disagree in sign Positive Positive = Positive Negative Negative = Positive Positive Negative = Negative Negative Positive = Negative Supporting Signed Integers We can adjust the previous algorithm to work with signed integers make sure each shift is an arithmetic shift right shift extend the sign bit (keep the MS bit the same instead of shifting in a 0). Since addition works for signed numbers, the multiply algorithm will now work for signed numbers. 7 8
Step a, a, 0 x 00 ( x ) Multiplicand 0 0 0 0 Product 000000 000 000 0000 0000 0000 multiplier is rightmost bits st partial product in left bits Signed Third Multiplication Algorithm, 0 000 000, 00 Result is s complement 9 0 Improving the speed with Combinational Array Multiplier Combinational Array Multiplier Combinational Array Multiplier bit Example Booth s Algorithm Requires that we can do an addition or a subtraction each iteration (not always an addition). Uses the following property the value of any consecutive string of s in a binary number can be computed with one subtraction.
A different way to compute integer values 00 (8=6) 00000 8 (568 = 8) 8 A little more complex example 00000 8 7 + 5 + 8 7 5 568 + 8 + 5 6 An overview of Booth s Algorithm When doing multiplication, strings of 0s in the multiplier require only shifting (no addition). When doing multiplication, strings of s in the multiplier require operation and shifting. We need to add or subtract only at positions in the multiplier where there is a transition from a 0 to a, or from a to a 0. 7 Booth Explanation Booth also works for negative numbers Booth Algorithm Add additional bit to the right of product Use right two bits of product to determine action Use arithmetic right shift End of string ( ) 0 0 0 0 Middle of string Beginning of string Current Bit Right Bit Explanation Action 0 0 Middle of string of 0s Do nothing 0 End of string of s Add multiplicand 0 Beginning of string of s Subtract multiplicand Middle of string of s Do nothing 8 Shifting The second step of the algorithm is the same as before: shift the product/multiplier right one bit. Arithmetic shift needed for signed arithmetic. The bit shifted off the right is saved and used by the next step (which looks at bits). Booth s Algorithm Booth Example Consider the same example, but think of it as a signed multiplication ( 7=8) Iter Step Multiplicand Product 0 Initial Values 00 0000 00 0 Product=0 ProdMcand 00 000 00 0 Shift product right 00 000 000 Product=0 Prod+Mcand 00 0 000 Shift product right 00 000 0 Product=00 Do nothing 00 000 0 Shift product right 00 00 0 Product=0 ProdMcand 00 00 00 0 Shift product right 00 000 00 9 0 5
Multiply in MIPS Divide Product stored in two bit registers called Hi and Low mult $s0, $s multu $s0, $s Results are moved from Hi/Low mfhi $t0 mflo $t0 # $s0 * $s high/low # $s0 * $s unsigned # $t0 = Hi # $t0 = Low Pseudoinstruction mul $t0, $s0, $s # $t0 = $s0 * $s Longhand division (08 = 9) 0 0 (n bit Quotient) + + 0 0 0 0 0 () (Dividend) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 N + Steps 0 0 0 0 (Remainder) Divide Solution # Solution # Start with quotient = 0, remainder = dividend, and divisor s top bits set On each iteration set remainder to be remainder divisor If large enough (remainder 0), then shift quotient left and set rightmost to If not large enough (remainder < 0), then set remainder to remainder + divisor (restore) Shift divisor right Continue for n+ () iterations rem = rem div if rem < 0 then // divisor too big rem = rem + div quo <<= LSB(quo) = 0 else // can divide quo <<= LSB(quo) = fi div >>= repeat unless done Divide Solution # a. Shift the Quotient register to the left, setting the new rightmost bit to Start. Subtract the register from the Remainder register and place the result in the Remainder register Remainder > 0 Test Remainder. Shift the register right bit rd repetition? Done Remainder < 0 b. Restore the original value by adding the register to the Remainder register and place the sum in the Remainder register. Also shift the Quotient register to the left, setting the new least significant bit to 0 No: < repetitions Yes: repetitions Solution #: Hardware 6bit ALU Quotient bits Shift Left Remainder MSB 5 6 6
Step b b a a a Quotient 0000 0000 0000 0000 000 00 00000 / 000 0000000 0000000 0000000 0000000 0000000 0000000 Remainder 00000 00 00000 0 00000 00000 000000 0000000 final quotient initial values after subtraction after restore shift right final remainder 7 Division Example: 0000/00 Initial Values ( in LHS) Quotient Remainder a. Rem. < Rem xxxx 000000 00000 b. Rem.<0, Add Div., LSh Q, Q 0 =0; RSh Div. xxxx 000000 00 a. Rem. < Rem b. Rem>=0, LSh Q, Q xxx0 000000 00000 0 =; RSh Div. a. Rem. < Rem xxx0 000000 000000 b. Rem>=0, LSh Q, Q 0 =; RSh Div. xx0 000000 000000 a. Rem. < Rem b. Rem>=0, LSh Q, Q xx0 000000 00000 0 =; RSh Div. 5a. Rem. < Rem x0 000000 00000 5b. Rem<0, Add Div., LSh Q, Q 0 =0; RSh Div. x0 000000 000000 ShRight 0 000000 000000 6 bit ShLeft Quotient 0 000000 0 5 6bit bit 0 0000000 000000 Remainder 6 bit 0000/00 = 0 rem 00 7/5 = rem N+ Steps, but first step cannot produce a. 8 Issues and Alternative Solution #: Hardware Just as before Half of the divisor bits are always 0 Either high or low bits are 0, even as shifted Half of the 6 bit adder is therefore wasted Solution # Instead of shifting divisor right, shift the remainder left Adder only needs to be bits wide Can also remove iteration by switching order to shift and then subtract Remainder is in left half of register bits bit ALU Shift Left Remainder MSB Quotient bits Shift Left 9 0 Improved Divider: 0000/00 Initial Values Quotient Remainder 0. LSh Rem xxxx 00 00000 a. Rem. < Rem xxxx 00 0000x b. Rem>=0, LSh Q, Q 0 =; LSh Rem. a. Rem. < Rem xxxx 00 00000x b. Rem>=0, LSh Q, Q 0 =; LSh Rem. xxx 00 0000xx a. Rem. < Rem xxx 00 000xx b. Rem>=0, LSh Q, Q 0 =; LSh Rem. xx 00 00xxx a. Rem. < Rem xx 00 000xxx b. Rem<0, Add Div., LSh Q, Q 0 =0 x 00 00xxxx x 00 0xxxx bit ShLeft Quotient 0 00 00xxxx bit bit 0000/00 = 0 rem 00 LH Rem. RH Rem. ShLeft 7/5 = rem 6 bit Issues and Alternative Just as before, half of the remainder register is useless at the beginning At the end, the quotient register becomes useless Solution # Remove the quotient register Place the quotient in the lower half of the remainder register Need to unshift in the last step to account for offbyone 7
Further Modifications Solution# Same space savings as with multiplication: use right ½ of remainder register to hold the quotient. bit ALU bits Shift right Remainder Shift left quotient test Divide Solution # rem <<= rem = (div >> ) if rem < 0 then rem += (div >> ) rem <<= LSB(rem) = 0 else rem <<= LSB(rem) = fi repeat unless done Correct remainder Start. Shift the Remainder register left bit. Subtract the register from the left half of the Remainder register and place the result in the left half of the Remainder register Remainder > 0 Remainder < 0 Test Remainder a. Shift the Remainder register to the b. Restore the original value by adding left, setting the new rightmost bit to the register to the left half of the Remainder register and place the sum in the left half of the Remainder register. Also shift the Remainder register to the left, setting the new rightmost bit to 0 No: < repetitions nd repetition? Yes: repetitions Done. Shift left half of Remainder right bit Solution #: Example Improved Improved Divider: 0000/00 Initial Values 0. LSh RemQuo. a. Rem < Rem b. Rem>=0, LSh RemQuo, Q 0 = a. Rem. < Rem b. Rem>=0, LSh RemQuo, Q 0 = a. Rem. < Rem b. Rem>=0, LSh RemQuo, Q 0 = a. Rem. < Rem b. Rem<0, Add Div., LSh RemQuo, Q 0 =0 bit bit Final: RSh Rem RemainderQuotient 00 00000 00 00000 00 000000 00 00000 00 0000 00 000 00 0000 00 000 00 00 00 000 00 000 LH Rem. RemQuot. 6 bit ShLeft 0000/00 = 0 rem 00 7/5 = rem 5 6 Signed Division Divide in MIPS Same process as naïve integer multiply Make divisor and dividend positive Negate quotient if signs of divisor and dividend disagree Set sign of remainder Dividend = Quotient + Remainder Sign should match dividend Quotient/Remainder stored in two bit registers called Hi and Low div $s0, $s # $s0 / $s high/low divu $s0, $s # $s0 / $s unsigned Results are moved from Hi/Low mfhi $t0 # $t0 = Hi mflo $t0 # $t0 = Low Pseudoinstructions div $t0, $s0, $s # $t0 = $s0 / $s rem $t0, $s0, $s # $t0 = $s0 % $s div $s0,$s Lo = $s0/$s (integer) Hi Hi = $s0 % $s 7 8 8