690 likes | 897 Views
Arithmetic and Logic. Crunching Numbers. Topics we need to explore Representing numbers on a computer Negatives, too. Building hardware to do logic and math And, Or Addition, Subtraction Comparisons Multiplication and Division. Hardware Alert!.
E N D
Arithmetic and Logic
Crunching Numbers • Topics we need to explore • Representing numbers on a computer • Negatives, too • Building hardware to do logic and math • And, Or • Addition, Subtraction • Comparisons • Multiplication and Division Hardware Alert! • Building hardware to work with Floating Point numbers 4.1
Representation • All data on a computer is represented in binary • 32 bits of data may be: • 32-bit unsigned integer • 4 ASCII characters • Single-precision IEEE floating point number • Who knows... data: 1000 1001 0100 0110 0000 0101 0010 1000 As 32-bit unsigned integer:2,303,067,432 As 32-bit 2’s complement integer:-1,991,899,864 As 4 ASCII characters: ‘??’, ‘F’, ENQ, ‘(‘ Note: Limited ASCII chart on p. 142 4.2
ASCII Representation of Numbers • Terminal I/O (keyboard, display) only deals with ASCII characters • Typically, strings of characters • “We’re #1” --> 87,101,44,114,101,32,35,49,0 NULL Termination • Note that the number ‘1’ is represented by 49 • Numbers in I/O consist of their ASCII representations • To output 103, use ASCII values 49, 48, 51 (3 bytes) • Outputting 103 (one byte) won’t work ‘1’, ‘0’, ‘3’ code for ‘g’ 4.2
Number Systems- Negative Numbers • What about negative numbers? • We need to represent numbers less than zero as well as zero or higher • In n bits, we get 2n combinations • Make half positive, half negative... • First method: use an extra bit for the sign • 0 000 0000 0000 0000 0000 0000 0000 0101 • 1 000 0000 0000 0000 0000 0000 0000 0101 +5 -5 Sign bit: 0-->positive, 1-->negative 31 remaining bits for magnitude 4.2
Sign and Magnitude Representation -7 +0 Seven Negative Numbers and “Negative” Zero Note: Example is shown for 4-bit numbers +1 -6 0000 1111 0001 1110 -5 +2 1101 0010 -4 +3 Inner numbers:Binary representation 1100 0011 Seven Positive Numbers and “Positive” Zero -3 1011 +4 0100 1010 0101 -2 +5 1001 0110 +6 -1 1000 0111 +7 -0 • High order bit is sign: 0 = positive (or zero), 1 = negative • Three low order bits represent the magnitude: 0 (000) through 7 (111) • Number range for n bits = +/- 2n-1 -1 • Two different representations for 0! • Two discontinuities 4.2
Two’s Complement Representation -1 +0 Note: Example is shown for 4-bit numbers +1 -2 0000 Re-order Negative Numbers to Eliminate Discontinuities 1111 0001 1110 -3 +2 1101 0010 -4 +3 Inner numbers:Binary representation 1100 0011 Eight Positive Numbers -5 1011 +4 0100 1010 0101 -6 +5 1001 0110 +6 -7 1000 0111 +7 -8 Note: Negative numbersstill have 1 for MSB • Only one discontinuity now • Only one zero • One extra negative number 4.2
complement complement complement add 1 add 1 add 1 2’s Complement Negation Method #1 To calculate the negative of a 2’s complement number: WARNING: This is for calculating the negative of a number. There is no such thing as “taking the 2’s complement of a number”. 1. Complement the entire number 2. Add one Examples: n = 0110= 6 n = 01000100 = 68 n = 10010000= -112 1001 10111011 -n =1010 = -6 01101111 -n =10111100 = -68 -n =01110000 = 112
complement complement complement copy copy copy 2’s Complement Negation Method #2 To calculate the negative of a 2’s complement number: 1. Starting at LSB, search to the left for the first one 2. Copy (unchanged) all of the bits to the right of the first one and the first one itself 3. Complement the remaining bits Examples: n = 01000100 = 68 n = 0110= 6 10111 100 -n = = -68 10 10 -n = = -6 n = 10010000= -112 011 10000 -n = = 112
4 + 3 7 0100 0011 0111 -4 + (-3) -7 1100 1101 11001 4 - 3 1 0100 1101 10001 -4 + 3 -1 1100 0011 1111 Adding Two’s Complement Numbers Just add the completenumbers together. Sign taken care of automatically. Ignore carry-out (for now) A carry out from sign bit does not necessarily mean overflow! 4.3
-1 +0 +1 -2 0000 1111 0001 1110 -3 +2 1101 0010 -4 +3 1100 0011 -5 1011 +4 0100 1010 0101 -6 +5 1001 0110 +6 -7 1000 0111 +7 -8 Overflow Add two positive numbers to get a negative number or two negative numbers to get a positive number Not a discontinuity - No Overflow 5 + 3 = -8 -7 - 2 = +7 Overflow occurs when crossing discontinuity A carryout from the MSB could mean crossing at either of these places – One is OK, one is Overflow Overflow cannot occur when adding a positive and negative number together 4.3
Cin Cin Cin Cin Cin Cin Cout Cout Cout Cout Cout Cout 0 1 1 0 0 1 0 0 1 1 1 0 0+ 0 0+ 0 1+ 1 1+ 0 1+ 0 1+ 1 Cin Overflow Cout Detecting Overflow Overflow occurs when: We add two positive numbers and obtain a negative We add two negative numbers and obtain a positive Looking at the sign bit (MSB): + + - - - - + + - - + + + - + - - + 0 1 0 1 1 0 No overflow Overflow Overflow No Overflow No Overflow No Overflow Overflow when carry in to sign bit does not equalcarry out 4.3
Signed and Unsigned operations Consider the following: $t0 = 0000 0000 0000 0000 0000 0000 0000 0101 $t1 = 1111 1111 1111 1111 1111 1111 1111 1001 execute: slt $s0, $t0, $t1 What’s the result? If we mean for $t0 to be 5and $t1 to be 4,294,967,289 (treatas unsigned integers) then $s0 should get 1 If we mean for $t0 to be 5 and $t1 to be -7 (treat as signedintegers) then $s0 should get 0 The default is to treat as signed integers Use sltu for unsigned integers 4.2
Using more bits What’s different between 4-bit 2’s complement and 32-bit? MSB has moved from bit 3 to bit 31! Sign Extension To convert from 4-bit 2’s complement to 32-bit: Copy all 4 bits to 4 Least significant bits of the 32-bit number. Copy MSB of original number into all remaining bits 0000 0000 0000 0000 0000 0000 0000 0111 0111 710 (32-bit 2’s comp.) 710 4-bit2’s comp. 1111 1111 1111 1111 1111 1111 1111 1010 1010 -610 (32-bit 2’s comp.) -610 4.2
Loading a single byte from memory We can read a single 8-bit byte from memory location 3000 by using: lb $t0, 3000($0) # read byte at mem[3000] assuming mem[3000] = 0xF3, we get... $t0: 0xFFFFFFF3 (sign-extension for other 3 bytes) 0x prefix means Hex If we only want the byte at 3000 (without extension), used an unsigned load: lbu$t0, 3000($0) # read byte a mem[3000] $t0: 0x000000F3 (no sign-extension) 4.2
0010 0011 0111 0110 1010 1111 0000 1101 OR 1001 1010 1000 0101 0001 1011 1010 0011 There is logic to it and Rd, Rs, Rt Rd <-- Rs • Rt or Rd, Rs, Rt Rd <-- Rs Ú Rt Note: Bit numberingstarts at zero. AND, OR are bitwise logic operations 1011 1011 1111 0111 1011 1111 1010 1111 Example: Set bit 7 of $s9 to ‘1’ (Don’t mess with the other 31 bits) ori $s9, $s9, 0x0080 0x0080 = 0000 0000 1000 0000 Example: Clear bit 14 of $t3 to ‘0’ andi $t3, $t3, 0xBFFF 0xBFFF = 1011 1111 1111 1111 4.4
0010 0011 0111 0110 1010 1111 0000 1101 $t2 0100 0110 1110 1101 0101 1110 0001 101 $s3 Opcode RS RT RD ShAmt Function Shift Instructions sll $s3, $t2, 1 # $s3 <-- $t2 shifted left 1 bit Old MSB: Bit-bucketed 0 0 New LSB: Zero R-Type Instruction srl $t3, $s4, 5 # $t3 <-- $s4 right shifted 5 bits 4.4
0010 0011 0111 0110 1010 1111 0000 1101 $t1 0000 0000 0010 0011 0111 0110 1010 1111 $t1 $t1 0000 0000 0000 0000 0000 0000 1010 1111 0000 0000 0000 0000 0000 0000 0000 0101 $t3 0000 0000 0000 0000 0000 0000 0010 1000 $t3 To access only part of a word, we need the bits on the RHS Using Shifts 1. You need only the 2nd byte of a 4-byte word srl $t1, $t1, 8 8 Must isolate only the 8 bits on RHS 0000 0000 0000 00000000 0000 1111 1111 Note - extended with 16 0’s andi $t1, $t1, 0x00FF 2. You want to multiply $t3 by 8 (note: 8 equals 23) (equals 5) sll $t3, $t3, 3 # move 3 places to the left (equals 40) 4.4
Arithmetic and Logic Unit • The ALU is at the heart of the CPU • Does math and logic • The ALU is primarily involved in R-type instructions • Perform an operation on two registers and produce a result • Where is the operation specified? • The instruction type specifies the operation • The ALU will have to be controlled by the instruction opcode
0 1 Constructing an ALU - Logic Operations Start out by supporting AND and OR operations Operation 2-to-1 Mux A AB Result A+B B If Operation = 0, Result = A • BIf Operation = 1, Result = A Ú B Two operands, two results.We need only one result... The Operation input comes from logic that looks at the opcode 4.5
Ai Bi Sum CarryOut 0 0 0 0 Sum + 0 1 1 0 1 0 1 0 1 1 0 1 CarryOut Sum = Ai BiÚ Ai Bi = Ai ÅBi A i Sum A i B i B i CarryOut A half adder adds two bits, A and Band produces a Sum and CarryOut Half Adder CarryOut = Ai Bi Problem: We often need to add two bits and a CarryIn... 4.5
CarryIn A1 Sum + B1 CarryOut Sum Cout A A AB AB 00 01 11 10 00 01 11 10 Cin Cin 0 0 1 1 B B A full adder adds two bits, A and B, and a CarryIn and produces a Sum and CarryOut Full Adder A B CinCoutSum 0 0 0 00 0 0 1 01 0 1 0 01 0 1 1 10 1 0 0 01 1 0 1 10 1 1 0 10 1 1 1 11 0 1 0 1 0 0 1 0 1 0 1 0 0 1 1 1 ÚBCin ÚACin Sum =A Å B Å Cin Cout = AB 4.5
Operation A 0 0 Result 1 1 Cin Op (2 bits) + 2 B Cin A Result ALU B Cout Cout Adding to our ALU (Op is now 2 bits) CarryIn Operation Function 00 A • B 01 A Ú B 10 A + B Add an Adder CarryOut Connect CarryIn (from previous bit) and CarryOut (to next bit) Expand Mux to 3-to-1 (Op is now 2 bits) 4.5
Cin A0 Result0 ALU0 B0 Cout Cin A1 Result1 ALU1 B1 Cout Cin A2 Result2 ALU2 B2 Cout Cin A31 Result31 ALU31 B31 Cout Putting it all together Cin Operation • Stack 32 of our 1-bit ALU’s together • Each one gets one bit from A and one from B • Connect to common Operation controls • Now we can do 32-bit AND and OR operations • Connect Cout’s to Cin’s • Now, 32-bit adds will work • Note: Carry will ripple through the stages, one at a time • Ripple-Carry Adder Cout 4.5
Operation CarryIn • Our ALU can add now, but what about subtraction? • To compute A - B, we can instead compute A + (-B) • In 2’s complement, -B = B + 1 A 0 1 Result 0 + 2 • Add an inverter, and a signal BInvert to get B 1 CarryOut Subtracting Set to 1 for LSB BInvert B B • Now, how about that +1? • CarryIn to LSB is unused (always zero) • Set it to 1! • Subtraction just sets BInvert and Cin to 1 For subtraction: Set CarryInof LSB to 1, Set BInvert to 1 4.5
Operation BInvert CarryIn A 0 0 1 1 Result B 0 + 2 2 1 3 CarryOut Support for SLT • We need to support the SLT operation • Set Result to 0000 0000 0000 0000 0000 0000 0000 0001if A <B • A<B is equivalent to(A - B) < 0 • Subtract B from A • If the result is negative, then set LSB of Result to ‘1’, all others to ‘0’ • The result is negative if the MSB after the subtraction is ‘1’ (Two’s complement) Less Less will be ‘0’ for bits 1-31, special for bit 0 We’re going to have to do something differentfor the MSB and the LSB 4.5
Operation BInvert CarryIn A 0 1 Result B 0 + 2 1 Less 3 MSB Only CarryOut That tricky MSB • To properly execute the SLT, we need to Set the LSB if the MSB is ‘1’ • (After a subtraction) • Can’t use the ‘Result’ of the MSB • Op will set the Mux to the ‘Less’ Field • Bring out the adder output directly: ‘Set’ Set • Also, we need to check for overflow • Overflow if Cin to MSB is different from Cout of MSB OverFlow 4.5
A0 Cin B0 Result0 ALU0 Less Cout A1 Cin B1 Result1 ALU1 0 Less Cout A2 Cin B2 Result2 ALU2 0 Less Cout A31 Result31 Cin B31 ALU31 0 Less Cout The Whole Thing BInvert Cin Operation • Our new and improved 32-bit ALU • Add the BInvert control to each bit • Connect ‘0’ to all the Less inputs except LSB • Connect ‘Set’ output of MSB to ‘Less’ Input of LSB • Set the LSB during SLT when negative • Output OverFlow from MSB OverFlow Set Cout 4.5
BInvert Cin Operation A0 Result0 Cin B0 ALU0 Less Cout A1 Result1 Cin B1 ALU1 0 Less Cout Operation A2 Cin B2 ALU2 A Result2 0 Less Cout Zero Result OverFlow Result31 B A31 Cin B31 OverFlow ALU31 Cout 0 Less Set Cout Cout One LastChange We need to add a checkto see if the result is zero Zero 4.5
Operation BInvert CarryIn A 0 1 Result 0 B + 2 1 3 Less CarryOut ALU Functions Function BInv Op Carryin Result And 0 00 0 R = A • B Or 0 01 0 R = A Ú B Add 0 10 0 R = A + B Subtract 1 10 1 R = A - B SLT 1 11 1 R = 1 if A < B 0 if A ³ B Since Binvert and Carryin are always the same, we can combine them in to a single signal subtract Note: Adding would be a lot faster if we didn’t use a ripple-carry adder... We also have zero-detect for BEQ,BNE (use subtract). Skipping over Shift operations... 4.5
Multiplication and Division
Multiplication 4 2 1 Multiplying two numbers A and B x 1 2 3 1 2 6 3 n partial products, where B is n digits long 8 4 2 + 4 2 1 5 1 7 8 3 n additions In Binary... 6 x 5 1 1 0 Each partial product is either: 110 (A*1) or 000 (A*0) x 1 0 1 1 1 0 0 0 0 + 1 1 0 Equals 30 Note: Product may take as manyas two times the number of bits! 1 1 1 1 0 4.6
Multiplication Steps Step1: LSB of multiplier is 1 --> Add a copy of multiplicand 1 1 0 0 1 1 0 1 1 0 0 0 Step2: Shift multiplier right to reveal new LSB Shift multiplicand left to multiply by 2 x 1 0 1 0 1 1 1 1 0 Step 3: LSB of multiplier is 0 --> Add zero 0 0 0 0 1 1 0 0 0 + Step 4: Shift multiplier right, multiplicand left 0 0 1 1 0 1 1 1 1 0 Step5: LSB of multiplier is 1 --> Add a copy of multiplicand Done! Thus, we need hardware to: 1. Hold multiplier (32 bits) and shift it right 2. Hold multiplicand (32 bits) and shift it left (requires 64 bits) 3. Hold product (result) (64 bits) 4. Add the multiplicand to the current result 4.6
initialize registers; Multiplicand ShLeft for (i=0; i<32; i++) { 64 bit if LSB(multiplier)==1{ ShRight Multiplier product += multiplicand; 32 bit } 64-bit left shift multiplicand 1; right shift multiplier 1; Product Write 64 bit } Multiplication We need hardware to: 1. Hold multiplier (32 bits) and shift it right 2. Hold multiplicand (32 bits) and shift it left (requires 64 bits) 3. Hold product (result) (64 bits) 4. Add the multiplicand to the current result 5. Control the whole process Algorithm: Control 4.6
xxxx1101 ShLeft 8 bit ShRight 0101 4 bit 8-bit Control 000000000 Write 8 bit Multiplication example: 1101 x 0101 MultiplicandMultiplierProduct xxxx1101010100000000 Initial Values • 1-->Add Multiplicand to Product • Shift M’cand left, M’plier right + xxx11010001000001101 • 0-->Do nothing • Shift M’cand left, M’plier right xx110100000100001101 + x1101000000001000001 • 1-->Add Multiplicand to Product • Shift M’cand left, M’plier right 11010000000001000001 • 0-->Do nothing • Shift M’cand left, M’plier right 1101 x 0101 = 0100000113 x 5 = 65 Note: Using 4/8 bit values forexample. Assume unsigned integers. 4.6
ShRight Multiplicand Multiplier 32 bit 32 bit Control 32-bit Write 64 bit ShRight LH Product RH Product Algorithm: initialize registers; Multiplicand ShLeft for (i=0; i<32; i++) { 64 bit if LSB(multiplier)==1{ ShRight Multiplier LH product += multiplicand; 32 bit } 64-bit right shift product 1; Control right shift multiplier 1; Product Write 64 bit } Improved Multiplier Even though we’re only adding 32 bits at a time, we need a 64-bit adder Results from shifting multiplicand left over and over again Instead, hold the multiplicand still and shift the product register right! Now we’re only adding 32 bits each time Extra bit for carryout 4.6
ShRight Multiplicand Multiplier 32 bit 32 bit Control 32-bit Write 0011+ 1101 10000 64 bit ShRight LH Product RH Product Improved Multiplier: 1101 x 0101 MultiplicandMultiplierProduct 110101010000 xxxx Initial Values • 1-->Add Multiplicand to LH Product • Shift Productright, M’plier right + 110101011101 xxxx 1101x0100110 1xxx • 0-->Do nothing • Shift Product right, M’plier right 1101xx010011 01xx + • 1-->Add Multiplicand to Product • Shift Product right, M’plier right 1101xx0110000 01xx 1101xxx01000 001x • 0-->Do nothing • Shift Product right, M’plier right 1101xxxx0100 0001 1101 x 0101 = 0100000113 x 5 = 65 4.6
ShRight Multiplicand Multiplier Multiplicand 32 bit 32 bit 32 bit Control 32-bit Control 32-bit Algorithm: Write Write 64 bit ShRight initialize registers (multiplier in RH product); LH Product RH Product ShRight LH Product Multiplier 64 bit for (i=0; i<32; i++) { if LSB(multiplier)==1{ LH product += multiplicand; right shift product-multiplier 1; } } Improved Improved Multiplier Note that we’re shifting bits out of the multiplier and into the product Why not put these together into the same register As space opens up in the multiplier, overwrite it with the product bits 4.6
0011+ 1101 10000 Multiplicand 32 bit Control 32-bit Write ShRight LH Product Multiplier 64 bit Improved Multiplier: 1101 x 0101 MultiplicandProduct-Multiplier 110100000101 Initial Values • 1-->Add Multiplicand to LH Product • Shift Product-M’plier right + 11011101 0101 11010110 1010 • 0-->Do nothing • Shift Product-M’plier right 11010011 0101 + • 1-->Add Multiplicand to Product • Shift Product-M’plier right 1101100000101 110110000010 • 0-->Do nothing • Shift Product-M’plier right 11010100 0001 1101 x 0101 = 0100000113 x 5 = 65 4.6
Rs 32 bit Control 32-bit Write ShRight Hi Lo 64 bit MIPS Multiplying MIPS hardware does32-bit multiplies32-bit x 32-bit --> 64 bit mult Rs, Rt -->Upper 32-bits of result in HiLower 32-bits of result in Lo The 64-bit product register is divided into two parts: Hi: Holds upper 32 bits of product Lo: Holds lower 32 bits mul Rd, Rs, Rt --> mult Rs, Rt mflo Rd mfhi $t5 # move Hi to register $t5 mflo $t6 # move Lo to register $t6 4.6
-45 -000 -30 -101 -30 -101 -15 -101 -000 Dividing quotient Dividend = Divisor * Quotient + Remainder divisor 3 2 2 1 15 48323 dividend 14 5 3 3 0 1 1 1 0 101 1001001 3 2 73 100 1 2 3 remainder 100 0 8 11 0 Idea: Repeatedly subtract divisor. Shift as appropriate. 1 1 3 11 4.7
Divisor ShRight 64 bit if (remainder< 0) { ShLeft Quotient remainder+=divisor;left shift quotient 1, LSB=0 32 bit 64-bit } else { left shift quotient 1, LSB=1 Control } Remainder Write right shift divisor 1 64 bit } Division We need hardware to: 1. Hold divisor (32 bits) and shift it right (requires 64 bits) 2. Hold remainder (64 bits) 3. Hold quotient (result) (32 bits) and shift it left 4. Subtract the divisor from the current result Algorithm: 5. Control the whole process initialize registers (divisor in LHS); for (i=0; i<33; i++) { remainder -= divisor; 4.6
5 4 2 1 3 Divisor ShRight 64 bit ShLeft Quotient 64-bit 32 bit Remainder Write Control 64 bit Division Example: 1001001/0101 QuotientDivisorRemainder xxxx0101000001001001 Initial Values (Divisor in LHS) • 1a.Rem. <-- Rem-Divisor - • 1b.Rem.<0, Add Div., LSh Q, Q0=0; RSh Div. xxxx0101000011111001 • 2a.Rem. <-- Rem-Divisor xxx00010100001001001 • 2b.Rem>=0, LSh Q, Q0=1; RSh Div. - xxx00010100000100001 • 3a.Rem. <-- Rem-Divisor • 3b.Rem>=0, LSh Q, Q0=1; RSh Div. xx010001010000100001 - • 4a.Rem. <-- Rem-Divisor xx010001010000001101 • 4b.Rem>=0, LSh Q, Q0=1; RSh Div. x0110000101000001101 • 5a.Rem. <-- Rem-Divisor - • 5b.Rem<0, Add Div., LSh Q, Q0=0; RSh Div. x0110000101000000011 01110000010100000011 - 01110000010111111110 11100000001000000011 1001001/0101 = 1110 rem 001173/5 = 14 rem 3 N+1 Steps, but first step cannot produce a 1. 4.7
Algorithm: initialize registers for (i=0; i<32; i++) { left shift remainder 1; Divisor Divisor ShRight LH remainder -= divisor; 32 bit 64 bit if (remainder< 0) ShLeft ShLeft { Quotient Quotient LH remainder+=divisor;left shift quotient 1, LSB=0; 32 bit 32 bit 32-bit 64-bit } else { left shift quotient 1, LSB=1; Write Control Control ShLeft LH Rem. RH Rem. } Remainder Write 64 bit } 64 bit Improved Divider As with multiplication, we’re using a 64-bit divisor and a 64-bit ALUwhen there are only 32 useful bits. The 64-bit divisor is needed just to provide the correct alignment. Instead of shifting the divisor right, we shift the remainder left. Also, since we know the first subtraction is useless,don’t do it (still shift the remainder left, though).(Changes from 33 iterations to 32!) 4.6
1 2 3 4 Divisor 32 bit ShLeft Quotient 32 bit 32-bit Write Control ShLeft LH Rem. RH Rem. 64 bit Improved Divider: 1001001/0101 Initial Values QuotientDivisorRemainder xxxx010101001001 • 0. LSh Rem • 1a.Rem. <-- Rem-Divisor xxxx01011001001x - • 1b.Rem>=0, LSh Q, Q0=1; LSh Rem. xxxx01010100001x • 2a.Rem. <-- Rem-Divisor xxx10101100001xx • 2b.Rem>=0, LSh Q, Q0=1; LSh Rem. - xxx10101001101xx • 3a.Rem. <-- Rem-Divisor xx11010101101xxx • 3b.Rem>=0, LSh Q, Q0=1; LSh Rem. - • 4a.Rem. <-- Rem-Divisor xx11010100011xxx • 4b.Rem<0, Add Div., LSh Q, Q0=0 x1110101 0011xxxx - x11101011110xxxx 111001010011xxxx 1001001/0101 = 1110 rem 001173/5 = 14 rem 3 4.7
Algorithm: initialize registers left shift rem-quotient 1; for (i=0; i<32; i++) { Divisor Divisor 32 bit LH remainder -= divisor; 32 bit if (remainder< 0) ShLeft { Quotient LH remainder+=divisor;left shift rem-quotient 1, LSB=0; 32 bit 32-bit 32-bit } else { left shift rem-quotient 1, LSB=1; Write Control Write Control ShLeft LH Rem. Rem-Quot. } ShLeft LH Rem. RH Rem. 64 bit 64 bit } Improved Improved Divider Note that the remainder is emptying at the same rate that the quotient is filling. Combine the two! A problem: We’re shifting the remainder left 33 times, but it should be 32. (Quotient doesn’t exist on first iteration, so it’s shifted only 32 times) Undo the extra shift by shifting the remainder (LH remainder-quotient) right by1 at the end right shift LH remainder-quotient 1 4.6
4 3 2 1 Divisor 32 bit 32-bit Write Control ShLeft LH Rem. Rem-Quot. 64 bit Improved Improved Divider: 1001001/0101 Initial Values DivisorRemainder-Quotient 010101001001 • 0. LSh Rem-Quo. • 1a.Rem <-- Rem-Divisor 010110010010 - • 1b.Rem>=0, LSh Rem-Quo, Q0=1 010101000010 • 2a.Rem. <-- Rem-Divisor 010110000101 • 2b.Rem>=0, LSh Rem-Quo,Q0=1 - 010100110101 • 3a.Rem. <-- Rem-Divisor 010101101011 • 3b.Rem>=0, LSh Rem-Quo, Q0=1 - • 4a.Rem. <-- Rem-Divisor 010100011011 • 4b.Rem<0, Add Div., LSh Rem-Quo, Q0=0 010100110111 - 010111100111 010101101110 • Final: RSh Rem 1 010100111110 1001001/0101 = 1110 rem 001173/5 = 14 rem 3 4.7
Divisor 32 bit 32-bit Write Control ShLeft Hi Lo 64 bit MIPS Dividing MIPS hardware does64-bit / 32-bit division Result has two parts: Quotient in Lo Remainder in Hi div $t1,$t2Lo = $t1/$t2 (integer)Hi = $t1 % $t2 pseudoinstructions: div $t0, $t1, $t2$t0 = $t1/$t2 (integer)rem $t3, $t1, $t2$t3 = $t1 % $t2 4.6