Crunching Numbers Topics we need to explore Representing numbers on a computer Negatives, too 4.1...
-
Upload
violet-mcdonald -
Category
Documents
-
view
221 -
download
0
Transcript of Crunching Numbers Topics we need to explore Representing numbers on a computer Negatives, too 4.1...
Crunching Numbers
• Topics we need to explore
• Representing numbers on a computer• Negatives, too
4.1
Hardware Alert!Hardware Alert!
• Building hardware to work with Floating Point numbers
• Building hardware to do logic and math• And, Or• Addition, Subtraction• Comparisons• Multiplication and Division
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...
4.2
Sign bit: 0-->positive, 1-->negativeSign bit: 0-->positive, 1-->negative 31 remaining bits for magnitude31 remaining bits for magnitude
First method: use an extra bit for the sign0 000 0000 0000 0000 0000 0000 0000 01011 000 0000 0000 0000 0000 0000 0000 0101
+5
-5
Sign and Magnitude Representation
• Two different representations for 0!
0000
0111
0011
1011
11111110
1101
1100
1010
1001
1000
0110
0101
0100
0010
0001
+0+1
+2
+3
+4
+5
+6
+7-0
-1
-2
-3
-4
-5
-6
-7
4.2
Note: Example is shown for 4-bit numbers
Note: Example is shown for 4-bit numbers
Inner numbers:Binary
representationSeven Positive Numbers and “Positive” Zero
Seven Negative Numbers and
“Negative” Zero
• Number range for n bits = +/- 2n-1 -1
• Three low order bits represent the magnitude: 0 (000) through 7 (111)
• Two discontinuities
• High order bit is sign: 0 = positive (or zero), 1 = negative
Two’s Complement Representation
• Only one discontinuity now
0000
0111
0011
1011
11111110
1101
1100
1010
1001
1000
0110
0101
0100
0010
0001
+0+1
+2
+3
+4
+5
+6
+7-8
-7
-6
-5
-4
-3
-2
-1
4.2
Note: Example is shown for 4-bit numbers
Note: Example is shown for 4-bit numbers
Inner numbers:Binary
representationEight Positive
Numbers
Re-order Negative
Numbers to Eliminate
Discontinuities
• Only one zero
• One extra negative number
Note: Negative numbersstill have 1 for MSB
Note: Negative numbersstill have 1 for MSB
2’s Complement Negation Method #1To calculate the negative of a 2’s complement number:
1. Complement the entire number
2. Add one
Examples:
n = 0110= 6
complement n = 01000100 = 68n = 10010000= -1121001
add 1
-n =1010 = -6
complement
10111011add 1
-n =10111100 = -68
complement
01101111add 1
-n =01110000 = 112
WARNING: This is for calculating the negative of a number. There is no such thing as “taking the 2’s complement of a number”.
2’s Complement Negation Method #2To 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
Examples:
n = 0110= 6
-n = 1010 = -6
copycomplement
n = 01000100 = 68
-n = 10010111 = -68
copycomplement
n = 10010000= -112
-n = 10000011 = 112
copycomplement
3. Complement the remaining bits
Adding Two’s Complement Numbers
4
+ 3
7
0100
0011
0111
-4
+ 3
-1
1100
0011
1111
-4
+ (-3)
-7
1100
1101
11001
4
- 3
1
0100
1101
10001
Just add the completenumbers together.Just add the completenumbers together.
Sign taken care of automatically.Sign taken care of automatically.
Ignore carry-out (for now)Ignore carry-out (for now)
4.3
A carry out from sign bit does not necessarily mean overflow!A carry out from sign bit does not necessarily mean overflow!
OverflowAdd two positive numbers to get a negative numberor two negative numbers to get a positive numberAdd two positive numbers to get a negative numberor two negative numbers to get a positive number
5 + 3 = -85 + 3 = -8
-7 - 2 = +7-7 - 2 = +7
4.3
Overflow cannot occur when adding a positive and negative number together
0000
0111
0011
1011
11111110
1101
1100
1010
1001
1000
0110
0101
0100
0010
0001
+0+1
+2
+3
+4
+5
+6
+7-8
-7
-6
-5
-4
-3
-2
-1
Overflow occurs when crossing discontinuity
Not a discontinuity - No Overflow
A carryout from the MSB could mean crossing at either of these places – One is OK, one is Overflow
Detecting OverflowOverflow occurs when:
We add two positive numbers and obtain a negative
Looking at the sign bit (MSB):
0+ 0
0Cin
0Cout
+
++
0+ 0
1Cin
0Cout
+
+-
No overflow Overflow
We add two negative numbers and obtain a positive
1+ 1
0Cin
1Cout
-
-+
1+ 1
1Cin
1Cout
-
--
Overflow No Overflow
Overflow when carry in to sign bit does not equal carry outOverflow when carry in to sign bit does not equal carry out
Cin
Cout
Overflow
0 110
4.3
1+ 0
0Cin
0Cout
-
+-
No Overflow
1
1+ 0
1Cin
1Cout
-
++
No Overflow
0
Signed and Unsigned operationsConsider 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 5 and $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!
Copy MSB of original number into all remaining bits
0111
1010
710710
(32-bit 2’s comp.)
-610-610 (32-bit 2’s comp.)
Sign ExtensionSign Extension
4.2
0000 0000 0000 0000 0000 0000 0000 0111
1111 1111 1111 1111 1111 1111 1111 1010
4-bit2’s comp.
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.
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)
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
0x prefix means Hex
There is logic to itand Rd, Rs, Rt Rd <-- Rs • Rtor Rd, Rs, Rt Rd <-- Rs Rt
AND, OR are bitwise logic operations
0010 0011 0111 0110 1010 1111 0000 1101 OR 1001 1010 1000 0101 0001 1011 1010 0011
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
Note: Bit numberingstarts at zero.
Note: Bit numberingstarts at zero.
1011 1011 1111 0111 1011 1111 1010 1111
Shift Instructions
sll $s3, $t2, 1 # $s3 <-- $t2 shifted left 1 bit
0010 0011 0111 0110 1010 1111 0000 1101$t2
0100 0110 1110 1101 0101 1110 0001 101 $s3
Old MSB: Bit-bucketedOld MSB: Bit-bucketed
New LSB: ZeroNew LSB: Zero
srl $t3, $s4, 5 # $t3 <-- $s4 right shifted 5 bits
4.4
0
Opcode RS RT RD ShAmt Function R-Type InstructionR-Type Instruction
0
Using Shifts1. You need only the 2nd byte of a 4-byte word
srl $t1, $t1, 8
0010 0011 0111 0110 1010 1111 0000 1101$t1
0000 0000 0010 0011 0111 0110 1010 1111$t1
andi $t1, $t1, 0x00FF
0000 0000 0000 0000 0000 0000 1010 1111$t1
2. You want to multiply $t3 by 8 (note: 8 equals 23)
0000 0000 0000 0000 0000 0000 0000 0101$t3
sll $t3, $t3, 3 # move 3 places to the left
0000 0000 0000 0000 0000 0000 0010 1000$t3
(equals 5)
(equals 40)
4.4
To access only part of a word, we need the bits on the RHS
8
0000 0000 0000 0000 0000 0000 1111 1111Note - extended with 16 0’s
Must isolate only the 8 bits on RHS
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
Constructing an ALU - Logic Operations
0
1
A
B
Operation
Result
2-to-1 Mux
If Operation = 0, Result = A • BIf Operation = 1, Result = A B
4.5
Start out by supporting AND and OR operations
AB
A+B
Two operands, two results.We need only one result...
The Operation input comes from logic that looks at the opcode
Half Adder
Ai 0 0 1 1
Sum 0 1 1 0
CarryOut0 0 0 1
1
Bi 0
0 1
Sum = Ai Bi Ai Bi
= Ai Bi
CarryOut = Ai Bi
CarryOut
Sum A i
B i
+
4.5
A half adder adds two bits, A and Band produces a Sum and CarryOut
Sum
CarryOut
A i
B i
Problem: We often need to add two bits and a CarryIn...
Full Adder
B
AB00 01 11 10
0
1
A
Cin
Cout
0
0
0
1
1
1
0
1
B
AB00 01 11 10
0
1
A
Cin
Sum
0
1
1
0
0
1
1
0
Cout = Sum = A B Cin
4.5
+B1
A1
Sum
CarryOut
CarryIn
A full adder adds two bits, A and B, and a CarryIn and produces a Sum and CarryOut
A B Cin Cout Sum
0 0 0 0 00 0 1 0 10 1 0 0 10 1 1 1 01 0 0 0 11 0 1 1 01 1 0 1 01 1 1 1 1
BCin ACinAB
Adding to our ALU
CarryIn
CarryOut
4.5
ALUA
B
Cout
Cin
ResultCin
Cout
Op (2 bits)
Operation Function00 A • B01 A B10 A + B
Operation Function00 A • B01 A B10 A + B
+
(Op is now 2 bits)
Add an Adder
Connect CarryIn (from previous bit) and CarryOut (to next bit)
Expand Mux to 3-to-1 (Op is now 2 bits)
0
1
Operation
Result
A
B2
0
1
Putting it all together Cin
A0
B0
Result0ALU0
Cin
Cout
Operation
A1
B1
Result1ALU1
Cin
Cout
A2
B2
Result2ALU2
Cin
Cout
A31
B31
Result31ALU31
Cin
Cout
4.5Cout
• Connect to common Operation controls
• Now we can do 32-bit AND and OR operations
• Stack 32 of our 1-bit ALU’s together
• Each one gets one bit from A and one from B
• 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
Subtracting
4.5
0
1B
0
1
A
Operation
Result
+ 2
CarryIn
CarryOut
BInvert
For subtraction: Set CarryIn of LSB to 1,
Set BInvert to 1
For subtraction: Set CarryIn of LSB to 1,
Set BInvert to 1
• Add an inverter, and a signal BInvert to get 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
B
• 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
Set to 1 for LSB
Support for SLT
4.5
• 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)
Result
0
1
A
Operation
+ 2B
CarryIn
CarryOut
0
1
BInvert
Less
We’re going to have to do something differentfor the MSB and the LSB
We’re going to have to do something differentfor the MSB and the LSB
• We need to support the SLT operation
• Set Result to 0000 0000 0000 0000 0000 0000 0000 0001 if A <B
0
1
2
3
Less will be ‘0’ for bits 1-31, special for bit 0
That tricky MSB
4.5
• To properly execute the SLT, we need to Set the LSB if the MSB is ‘1’
• (After a subtraction)
OverFlow
Set
0
1
A
Operation
Result
+ 2B
CarryIn
CarryOut
0
1
BInvert
3Less
MSB OnlyMSB Only
• Can’t use the ‘Result’ of the MSB
• Op will set the Mux to the ‘Less’ Field
• Bring out the adder output directly: ‘Set’
• Also, we need to check for overflow
• Overflow if Cin to MSB is different from Cout of MSB
Cin Operation
4.5
Cout
• Our new and improved 32-bit ALU
The Whole Thing BInvert
0ALU31
Result31CinA31B31
Cout
LessOverFlow
Set
• Add the BInvert control to each bit
• Connect ‘Set’ output of MSB to ‘Less’ Input of LSB
• Set the LSB during SLT when negative
• Output OverFlow from MSB
ALU0
A0B0 Result0
Cin
LessCout
0B2 ALU2
Result2
CinA2
LessCout
0ALU1
Result1
A1B1
Cout
Less
Cin
• Connect ‘0’ to all the Less inputs except LSB
4.5
One LastChange
Zero
A
B
ZeroResultOverFlow
Operation
Cout
Result2
Result1
Cin Operation
Cout
BInvert
0OverFlow
Set
0
0
ALU31
Result31Cin
A31B31
Cout
Less
ALU0
A0B0
Result0Cin
LessCout
B2 ALU2
CinA2
LessCout
ALU1
A1B1
Cout
Less
Cin
We need to add a checkto see if the result is zero
ALU FunctionsFunction BInv Op Carryin Result
And 0 00 0 R = A • BOr 0 01 0 R = A BAdd 0 10 0 R = A + BSubtract 1 10 1 R = A - BSLT 1 11 1 R = 1 if A < B
0 if A B
Function BInv Op Carryin Result
And 0 00 0 R = A • BOr 0 01 0 R = A BAdd 0 10 0 R = A + BSubtract 1 10 1 R = A - BSLT 1 11 1 R = 1 if A < B
0 if A B
4.5
0
1
A
Operation
Result
+ 2B
CarryIn
CarryOut
0
1
BInvert
3Less
We also have zero-detect for BEQ,BNE (use subtract).
We also have zero-detect for BEQ,BNE (use subtract).
Skipping over Shift operations...Skipping over Shift operations...
Note: Adding would be a lot faster if we didn’t use a ripple-carry adder...
Note: Adding would be a lot faster if we didn’t use a ripple-carry adder...
Since Binvert and Carryin are always the same, we can combine them in to a single signal subtract
Since Binvert and Carryin are always the same, we can combine them in to a single signal subtract
Multiplication
4.6
Multiplying two numbers A and BMultiplying two numbers A and B
n partial products, where B is n digits longn partial products, where B is n digits long
n additionsn additions
6 x 56 x 5
Equals 30Equals 30
Each partial product is either: 110 (A*1) or 000 (A*0)
Each partial product is either: 110 (A*1) or 000 (A*0)
Note: Product may take as manyas two times the number of bits!
Note: Product may take as manyas two times the number of bits!
In Binary...
4 2 1
x 1 2 31 2 6 38 4 2
+ 4 2 15 1 7 8 3
1 1 0
x 1 0 1
1 1 00 0 0
+ 1 1 0 1 1 1 1 0
1 1 01 1 0 01 1 0 0 0
1 0 1 1 0 1
Multiplication Steps
4.6
1 1 00 0 0 0
+
Step1: LSB of multiplier is 1 --> Add a copy of multiplicand
x
0 0 1 1 01 1 1 1 0
1 1 0 0 0
Step2: Shift multiplier right to reveal new LSBShift multiplicand left to multiply by 2
Step 3: LSB of multiplier is 0 --> Add zero
Step 4: Shift multiplier right, multiplicand left
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)
4. Add the multiplicand to the current result
3. Hold product (result) (64 bits)
Multiplication
4.6
Control
64-bit
Product
64 bit
Write
Multiplicand
64 bitShLeft
Multiplier
32 bit
ShRight
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)
4. Add the multiplicand to the current result
3. Hold product (result) (64 bits)
5. Control the whole process Algorithm:
initialize registers;
for (i=0; i<32; i++) {
if LSB(multiplier)==1{
product += multiplicand;
}
left shift multiplicand 1;
right shift multiplier 1;
}
Multiplication example: 1101 x 0101
4.6
Multiplicand Multiplier Product
xxxx1101 0101 00000000Initial Values
•1-->Add Multiplicand to Product•Shift M’cand left, M’plier right
•0-->Do nothing•Shift M’cand left, M’plier right
•1-->Add Multiplicand to Product•Shift M’cand left, M’plier right
•0-->Do nothing•Shift M’cand left, M’plier right
Note: Using 4/8 bit values forexample.Assume unsigned integers.
Note: Using 4/8 bit values forexample.Assume unsigned integers.Control
8-bit
000000000
8 bit
Write
xxxx11018 bit
ShLeft
0101
4 bit
ShRight
xxx11010 0010 00001101+
xx110100 0001 00001101
x1101000 0000 01000001+
11010000 0000 01000001
1101 x 0101 = 0100000113 x 5 = 65
Improved Multiplier
4.6
Control
64-bit
Product
64 bit
Write
Multiplicand
64 bitShLeft
Multiplier
32 bit
ShRight
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
initialize registers;
for (i=0; i<32; i++) {
if LSB(multiplier)==1{
LH product += multiplicand;
}
right shift product 1;
right shift multiplier 1;
}
Algorithm:
32-bit
32 bit 32 bit
Control
RH Product64 bit
Write
Multiplicand MultiplierShRight
LH Product ShRight
Extra bit for carryout
1101 xx01 0011 01xx
1101 xx01 10000 01xx
1101 x010 0110 1xxx
Improved Multiplier: 1101 x 0101
4.6
Multiplicand Multiplier Product
1101 0101 0000 xxxxInitial Values
•1-->Add Multiplicand to LH Product•Shift Product right, M’plier right
•0-->Do nothing•Shift Product right, M’plier right
•1-->Add Multiplicand to Product•Shift Product right, M’plier right
•0-->Do nothing•Shift Product right, M’plier right
1101 0101 1101 xxxx+
1101 xxx0 1000 001x
+
1101 xxxx 0100 0001
1101 x 0101 = 0100000113 x 5 = 65
32-bit
32 bit 32 bit
Control
RH Product64 bit
Write
Multiplicand MultiplierShRight
LH Product ShRight
0011+ 1101
10000
Improved Improved Multiplier
4.6
Note that we’re shifting bits out of the multiplier and into the product
Why not put these together into the same register
32-bit
32 bit 32 bit
Control
RH Product64 bit
Write
Multiplicand MultiplierShRight
LH Product ShRight
As space opens up in the multiplier, overwrite it with the product bits
32-bit
32 bit
Control
Multiplier64 bit
Write
Multiplicand
LH Product ShRight
initialize registers (multiplier in RH product);
for (i=0; i<32; i++) {
if LSB(multiplier)==1{
LH product += multiplicand;
}
right shift product-multiplier 1;}
Algorithm:
Multiplicand Product-Multiplier
1101 0000 0101
1101 1101 0101
1101 0011 0101
1101 1000 0010
1101 0100 0001
1101 10000 0101
1101 0110 1010
Improved Multiplier: 1101 x 0101
4.6
Initial Values
•1-->Add Multiplicand to LH Product•Shift Product-M’plier right
•0-->Do nothing•Shift Product-M’plier right
•1-->Add Multiplicand to Product•Shift Product-M’plier right
•0-->Do nothing•Shift Product-M’plier right
+
+
1101 x 0101 = 0100000113 x 5 = 65
0011+ 1101
10000
32-bit
32 bit
Control
Multiplier64 bit
Write
Multiplicand
LH Product ShRight
MIPS MultiplyingMIPS hardware does32-bit multiplies32-bit x 32-bit --> 64 bit
MIPS hardware does32-bit multiplies32-bit x 32-bit --> 64 bit
4.6
The 64-bit product register is divided into two parts: Hi: Holds upper 32 bits of product Lo: Holds lower 32 bits
mfhi $t5 # move Hi to register $t5mflo $t6 # move Lo to register $t6
mul Rd, Rs, Rt --> mult Rs, Rt mflo Rd
mul Rd, Rs, Rt --> mult Rs, Rt mflo Rd
mult Rs, Rt -->Upper 32-bits of result in HiLower 32-bits of result in Lo
mult Rs, Rt -->Upper 32-bits of result in HiLower 32-bits of result in Lo
32-bit
32 bit
Control
Lo64 bit
Write
Rs
Hi ShRight
Dividing
4.7
dividend
quotientdivisor
remainder
4832315-45
33-30
32-30
23-15
8
3221
73
145
3
1001001101-0001001-1011000-101
110-101
1
0111
1-000
0
11
Dividend = Divisor * Quotient + RemainderDividend = Divisor * Quotient + Remainder
Idea: Repeatedly subtract divisor. Shift as appropriate.
Idea: Repeatedly subtract divisor. Shift as appropriate.
Division
4.6
We need hardware to:1. Hold divisor (32 bits) and shift it right (requires 64 bits)
2. Hold remainder (64 bits)
4. Subtract the divisor from the current result
3. Hold quotient (result) (32 bits) and shift it left
5. Control the whole processAlgorithm:
initialize registers (divisor in LHS);for (i=0; i<33; i++) {
remainder -= divisor;
Control
64-bit
Remainder
64 bit
Write
Divisor
64 bitShRight
Quotient
32 bit
ShLeftif (remainder < 0) {
remainder+=divisor;left shift quotient 1, LSB=0
} else {left shift quotient 1, LSB=1
}
}right shift divisor 1
Division Example: 1001001/0101
4.7
Control
64-bit
Remainder64 bitWrite
Divisor64 bitShRight
Quotient
32 bit
ShLeft
Quotient Divisor Remainder
xxxx 01010000 01001001
xxxx 01010000 11111001-
xxx0 00101000 01001001
Initial Values (Divisor in LHS)•1a. Rem. <-- Rem-Divisor
xxx0 00101000 00100001
•2a. Rem. <-- Rem-Divisor
-
xx01 00010100 00100001
xx01 00010100 00001101
•3a. Rem. <-- Rem-Divisor
-
x011 00001010 00001101
x011 00001010 00000011
0111 00000101 00000011
•4a. Rem. <-- Rem-Divisor
0111 00000101 11111110
1110 00000010 00000011
•5a. Rem. <-- Rem-Divisor-
-
•1b. Rem.<0, Add Div., LSh Q, Q0=0; RSh Div.
•2b. Rem>=0, LSh Q, Q0=1; RSh Div.
•3b. Rem>=0, LSh Q, Q0=1; RSh Div.
•4b. Rem>=0, LSh Q, Q0=1; RSh Div.
•5b. Rem<0, Add Div., LSh Q, Q0=0; RSh Div.
1001001/0101 = 1110 rem 001173/5 = 14 rem 3
1
2
3
4
5
N+1 Steps, but first step cannot produce a 1.
Improved Divider
4.6
Control
64-bit
Remainder
64 bit
Write
Divisor
64 bitShRight
Quotient
32 bit
ShLeft
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!)
Control
32-bit
LH Rem.64 bit
Write
Divisor
32 bit
Quotient
32 bit
ShLeft
ShLeftRH Rem.
Algorithm:initialize registers
if (remainder < 0) {
LH remainder+=divisor;left shift quotient 1, LSB=0;
} else {left shift quotient 1, LSB=1;
}}
for (i=0; i<32; i++) {
LH remainder -= divisor;left shift remainder 1;
xxxx 0101 0100001x
Improved Divider: 1001001/0101
4.7
Quotient Divisor Remainder
xxxx 0101 01001001
-
xxx1 0101 100001xx
Initial Values•0. LSh Rem
xxx1 0101 001101xx
•1a. Rem. <-- Rem-Divisor
-
xx11 0101 01101xxx
xx11 0101 00011xxx
•2a. Rem. <-- Rem-Divisor
-
x111 0101 0011xxxx
x111 0101 1110xxxx
1110 0101 0011xxxx
•3a. Rem. <-- Rem-Divisor
•4a. Rem. <-- Rem-Divisor
-
•1b. Rem>=0, LSh Q, Q0=1; LSh Rem.
•2b. Rem>=0, LSh Q, Q0=1; LSh Rem.
•3b. Rem>=0, LSh Q, Q0=1; LSh Rem.
•4b. Rem<0, Add Div., LSh Q, Q0=0
1001001/0101 = 1110 rem 001173/5 = 14 rem 3
1
2
3
4
xxxx 0101 1001001x
Control
32-bit
LH Rem.64 bit
Write
Divisor32 bit
Quotient
32 bit
ShLeft
ShLeftRH Rem.
Improved Improved Divider
4.6
Note that the remainder is emptying at the same rate that the quotient is filling.
Combine the two!
Control
32-bit
LH Rem.64 bit
Write
Divisor
32 bit
Quotient
32 bit
ShLeft
ShLeftRH Rem. Control
32-bit
LH Rem.64 bit
Write
Divisor
32 bit
ShLeftRem-Quot.
Algorithm:initialize registers
if (remainder < 0) {
LH remainder+=divisor;left shift rem-quotient 1, LSB=0;
} else {left shift rem-quotient 1, LSB=1;
}}
for (i=0; i<32; i++) {LH remainder -= divisor;
left shift rem-quotient 1;
right shift LH remainder-quotient 1
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
0101 00110111
0101 01000010
0101 100001010101 001101010101 01101011
Improved Improved Divider: 1001001/0101
4.7
Divisor Remainder-Quotient
0101 01001001
-
Initial Values•0. LSh Rem-Quo.
•1a. Rem <-- Rem-Divisor
-
0101 00011011
•2a. Rem. <-- Rem-Divisor
-
0101 11100111
0101 01101110
•3a. Rem. <-- Rem-Divisor
•4a. Rem. <-- Rem-Divisor
-
•1b. Rem>=0, LSh Rem-Quo, Q0=1
•2b. Rem>=0, LSh Rem-Quo, Q0=1
•3b. Rem>=0, LSh Rem-Quo, Q0=1
•4b. Rem<0, Add Div., LSh Rem-Quo, Q0=0
1001001/0101 = 1110 rem 001173/5 = 14 rem 3
1
2
3
4
0101 10010010
Control
32-bit
LH Rem.64 bit
Write
Divisor32 bit
ShLeftRem-Quot.
0101 00111110•Final: RSh Rem 1
MIPS Dividing MIPS hardware does64-bit / 32-bit division
MIPS hardware does64-bit / 32-bit division
4.6
Control
32-bit
Hi64 bit
Write
Divisor
32 bit
ShLeftLo
Result has two parts: Quotient in Lo Remainder in Hi
Result has two parts: Quotient in Lo Remainder in Hi
div $t1,$t2Lo = $t1/$t2 (integer)Hi = $t1 % $t2
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
pseudoinstructions:div $t0, $t1, $t2 $t0 = $t1/$t2 (integer)rem $t3, $t1, $t2 $t3 = $t1 % $t2
Floating Point Numbers
• Floating point is used to represent “real” numbers
• 1.23233, 0.0003002, 3323443898.3325358903
• Real means “not imaginary”
4.8
• Computer floating-point numbers are a subset of real numbers
• Limit on the largest/smallest number represented• Depends on number of bits used
• Limit on the precision• 12345678901234567890 --> 12345678900000000000• Floating Point numbers are approximate, while integers
are exact representation
Scientific Notation
+ 34.383 x 102 = 3438.3
SignSign SignificandSignificand ExponentExponent
+ 3.4383 x 103 = 3438.3 Normalized form: Only onedigit before the decimal point
Normalized form: Only onedigit before the decimal point
+3.4383000E+03 = 3438.3 Floating point notationFloating point notation
8 digit significand can only represent 8 significant digits8 digit significand can only represent 8 significant digits
4.8
Binary Floating Point Numbers
+ 101.1101+ 101.1101
= 1 x 22 + 0 x 21
+ 1 x 20 + 1 x 2-1
+ 1 x 2-2 + 0 x 2-3
+ 1 x 2-4
+1.011101 E+2+1.011101 E+2 Normalized so that the binary point immediately follows the leading digit
Note: First digit is always non-zero --> First digit is always one.
Note: First digit is always non-zero --> First digit is always one.
4.8
= 4 + 0 + 1 + 1/2 + 1/4 + 0 + 1/16= 5.8125
IEEE Floating Point Format
SignSign ExponentExponent SignificandSignificand
31 30 23 22 0
8 bits 23 bits
0: Positive1: Negative
Biased by 127. Leading ‘1’ is implied, but notrepresented
Number = -1S * (1 + Sig) x 2E-127
• Allows representation of numbers in range 2-127 to 2+128 (10±38)
4.8
• Since the significand always starts with ‘1’, we don’t have to represent it explicitly
• Significand is effectively 24 bits• Zero is represented by Sign=Significand=Exp=0
IEEE Double Precision FormatSignSign
SignificandSignificandBias:1023
Number = -1S * (1 + Sig) x 2E-1023
• Allows representation of numbers in range 2-1023 to 2+1024(10± 308)
• Larger significand means more precision
• Takes two registers to hold one number
4.8
31 0
32 bits
63 62 52 51 32
11 bits 20 bits
ExponentExponent
ConversionConvert 5.75 to Single-Precision IEEE Floating Point
2. Normalize ---> 1.0111 x 22
SignificandSignificand ExponentExponent
3. Sign = 0 (positive).
4.8
1. Convert 5.7510 to Binary ---> 101.112
7. Put in proper bit fields Number = 0 10000001 01110000000000000000000 = 0x40B80000
5. Express significand as 24 bits Sig = 1.01110000000000000000000
4. Add 127 (bias) to exponent. Exponent = 12910 = 100000012
6. Remove leading one from significand, leaving 23 bits Sig = .01110000000000000000000
Adding Floating Point Numbers
1.2232E+3 + 4.211E+51.2232E+3 + 4.211E+5
1. Normalize to higher exponenta. Find the difference between exponents (= 2)b. Shift smaller number right by that amount 1.2232E+3 == 0.012232E+5
Note: If carry out of MSD, re-normalizeNote: If carry out of MSD, re-normalize
5.0 E+2+ 7.0 E+2 12.0 E+2 = 1.2 E+3
4.8
2. Now that exponents are the same, add significands together4.211 E+5
+ 0.012232 E+5 4.223232 E+5
Adding IEEE Floating Point Numbers S E Sig. 0x45B8CD8D --> 0 8B 38CD8D = 5913.69410
+ 0x46FC8672 --> 0 8D 7C8672 = 32323.2210
S E Sig. 0x45B8CD8D --> 0 8B 38CD8D = 5913.69410
+ 0x46FC8672 --> 0 8D 7C8672 = 32323.2210
1. Check for Sign=Exp=Significand=0 --> If so, treat as a special case
4.8
2. Put the ‘1’ back in bit 23 of significands 38CD8D = 011 1000 1100 1101 1000 1101 ---> 1011 1000 1100 1101 1000 1101 = B8CD8D
7C8672 = 111 1100 1000 0110 0111 0010 ---> 1111 1100 1000 0110 0111 0010 = FC8672 0 8B B8CD8D + 0 8D FC8672
Adding IEEE Floating Point Numbers 0 8B B8CD8D+ 0 8D FC8672
0 8B B8CD8D+ 0 8D FC8672
3. Normalize to higher exponent: a. Find difference in exponents: 8D - 8B = 2
4.8
b. Shift significand of number with smaller exponent right by the difference B8CD8D = 1011 1000 1100 1101 1000 1101 right shift by 2 --> 0010 1110 0011 0011 0110 0011 = 2E3363
c. Set lower-valued exponent to higher one 0 8D 2E3363 (re-normalized form of 0 8B B8CD8D) + 0 8D FC8672
Adding IEEE Floating Point Numbers
4. Add significands: (note: carry produced one too many bits) 0010 1110 0011 0011 0110 0011+ 1111 1100 1000 0110 0111 00101 0010 1010 1011 1001 1101 0101 = 12AB9D5
0 8D 2E3363+ 0 8D FC8672
0 8D 2E3363+ 0 8D FC8672
Bit 24Bit 24
Result is: 0 8E 155CEAor 0x47155CEA= 38236.9110
Result is: 0 8E 155CEAor 0x47155CEA= 38236.9110
4.8
5. Since bit 24 is ‘1’, we must re-normalize by shifting significand right 1 and incrementing exponent by one. 1 0010 1010 1011 1001 1101 0101SRL --> 1001 0101 0101 1100 1110 1010 = 955CEA (significand) exp: 8D --> 8E
6. Get rid of bit 23 in significand (for IEEE standard) 1001 0101 0101 1100 1110 1010 --> 001 0101 0101 1100 1110 1010 = 155CEA
Multiplying Floating Point Numbers
4.8
34.233 E +09 * 212.32 E +0334.233 E +09 * 212.32 E +03
5. Truncate extra bits... --> 7.26835 E +15
1. Add exponents: --> 9 + 3 = 12
2. Multiply significands --> 34.233 * 212.32 = 7268.35056
3. Result is 7268.35056 E +12
4. Normalize: 7.26835056 E +15
Multiplying IEEE Floating Point Numbers
4.8
0 8B 38CD8D = 5913.69410
x 0 8D 7C8672 = 32323.2210
0 8B 38CD8D = 5913.69410
x 0 8D 7C8672 = 32323.2210
1. Check for zero.
Multiplying two 24-bit numbers with 23 bits to the right of the binary point – result has 48 bits, with 46 bits to the right of the point
Multiplying two 24-bit numbers with 23 bits to the right of the binary point – result has 48 bits, with 46 bits to the right of the point
2. Add exponents. (Note: both have the bias of 127 already. Only want to bias once, so subtract 127 (7F) .) 8B + 8D - 7F = 99 3. Put ‘1’ back onto bit 23, multiply significands. 38CD8D --> B8CD8D 7C8672 --> FC8672 B8CD8D * FC8672 = 10.11 0110 0100 1011 0110 0100 1010 1111 0101 0110 1100 1010
Multiplying IEEE Floating Point Numbers
4.8
0 8B 38CD8D = 5913.69410
x 0 8D 7C8672 = 32323.2210
0 8B 38CD8D = 5913.69410
x 0 8D 7C8672 = 32323.2210
10.11 0110 0100 1011 0110 0100 1010 1111 0101 0110 1100 1010
5. Re-normalize so one place to left of binary point.1.011 0110 0100 1011 0110 0100 1010 1111 0101 0110 1100 1010(Add one to exponent) --> 99 + 1 = 9A
6. Remove extra bits so only 24 bits remain1.011 0110 0100 1011 0110 0100
7. Remove implied one (bit 23) 011 0110 0100 1011 0110 0100
Result is: 0 9A 364B64 = 191149632.174710
Instruction R5 R6 R7 Addr:Data
1 add $6, $0, $0 (ARRAY) 6000: 0xBA
2 addi $7, $0, 8 6004: 0x0B
3 lb $5, ARRAY($7) 6008: 0xAC
4 srl $5, $5, 28 600C
5 lbu $6, ARRAY($0) 6010
6 andi $5, $6, 0x5 6014
7 bne $5, $0, EXIT 6018
8 addi $5, $0, 0x1234 601C
9 li $7, 0x1000 6020
10 mult $7, $5
11 mfhi $7
12 mflo $5
13 sw $5, ARRAY($0)
14 addi $sp, $sp, -4
15 sw $7, 0($sp)
16 lw $5, 0($sp)
17 addi $sp, $sp, 4
18 EXIT:
Instruction R5 R6 R7 Addr:Data
1 add $6, $0, $0 (ARRAY) 6000: 0x0A
2 addi $7, $0, 8 6004: 0x0B
3 lb $5, ARRAY($7) 6008: 0x0C
4 srl $5, $5, 28 600C
5 lbu $6, ARRAY($0) 6010
6 ori $5, $6, 0x5 6014
7 beq $5, $0, EXIT 6018
8 addi $5, $0, 0x1234 601C
9 li $7, 0x1000 6020
10 div $7, $5
11 mfhi $7
12 mflo $5
13 sw $5, ARRAY($0)
14 addi $sp, $sp, -4
15 sw $7, 0($sp)
16 lw $5, 0($sp)
17 addi $sp, $sp, 4
18 EXIT:
Example
• Write a program that reads a 4-element row and column vectors from memory and• Multiplies both by a scalar also found in memory• Calculates the scalar product of the two vectors• Assume no partial product may exceed 32 bits• Use v1= [1 2 3 4], v2= [0 1 2 3]T, s=5 as test inputs
.dataV1: .word 1, 2, 3, 4 #vector1V2T: .word 0, 1, 2, 3 #transpose vector2S: .word 5SV1: .space 16SV2T: .space 16V1V2: .space 4
Example 2
• Write a program that finds the greatest common divisor of two integers found in memory by repeatedly dividing and incrementing.
.data
NUM1: .word 5 #for test
NUM2: .word 7 #for test
MSG1: .asciiz “the common divisor is:”
MSG2: .asciiz “No common divisor except 1!”
gcd=1;count=2;while (count < a && count < b){if (a%gcd=0 && b%gcd=0)gcd++
count++}
.textmain: addi $t0, $0, 2 #initialize GCD
addi $t3, $0, 0 #current GCDlw $t1, NUM1($0) #num1 in t1lw $t2, NUM2($0) #num2 in t2
WHILE: div $t1,$t0mfhi $t4 #remainder in $t4bne $t4, $0, SKIP #if remainder not zero,
#no point dividing the other div $t2, $t0
mfhi $t4bne $t4,$0, SKIP #NOT a CDmove $t3, $t0 #t3 has current GCD
SKIP: bgt $t0, $t1, CHECK #equal to num1, exit
bgt $t0, $t2, CHECK #equal to num2, exit
addi $t0, $t0, 1 #try next integerj WHILE
CHECK: bne $t3, $0, PRINT #print GCDla $a0, MSG2li $v0, 4syscall
j exitPRINT: la $a0, MSG1 #printing MSG1
li $v0, 4syscallmove $a0, $t3 #printing GCDli $v0,1syscall
exit: li $v0, 10syscall