This week we transition from Chapter 2 (Instructions) directly into Chapter 3 of our textbook (Computer Organization and Design). Until now, we have exclusively designed hardware and processed data using the Integer Data Type (both signed and unsigned formats).
However, real-world engineering requires processing fractional decimal values. In these notes, we explore how computer architecture mathematically structures decimals, the limitations of Fixed-Point logic, the globally standardized IEEE 754 Protocol, and how MIPS manages these complex numbers using an external Floating-Point Unit (FPU) known as Coprocessor 1.
Our fundamental architectural issue is that physical memory arrays and CPU registers (like $t0) are rigidly built using 32 physical bits. How do we represent a decimal point . using only binary 0s and 1s?
The most intuitive approach is to statically define an arbitrary dividing line within our 32-bit constraint. For example, we could say the first 16 bits represent the whole integer number, and the remaining 16 bits represent the fractional decimal.
add) works natively.To solve this, the Institute of Electrical and Electronics Engineers ratified the IEEE 754 Standard in 1985. Instead of fixing the decimal in place, the hardware dynamically “floats” the decimal point based on scientific notation, maximizing both range and granular precision within the exact same 32 bits!
Standard Scientific Notation: $-1.234 \times 10^{5}$ Binary Floating Point Notation: $(-1)^{s} \times (1 + \text{Fraction}) \times 2^{(\text{Exponent} - \text{Bias})}$

MIPS implements the Single Precision (32-bit) format utilizing three distinct, mathematically packed fields:
1 is negative, 0 is positive.When packed together, the CPU can dynamically reallocate its bit-budget: if the exponent is incredibly large, the number represents cosmic distances. If the exponent is incredibly negative, the exact same 32 bits represent microscopic fractions.
Floating-point arithmetic (specifically multiplication and division) requires drastically different physical silicon gates to execute than standard integer math. Combining floating-point logic and integer logic into a single monolithic ALU would create massive, slow bottlenecks in the processor datapath.
Therefore, the MIPS architecture formally delegates all decimal math to a mathematically dedicated secondary chip known as Coprocessor 1 (CP1), universally referred to as the Floating Point Unit (FPU).
The FPU maintains its own separate, physically distinct memory array containing 32 independent registers ($f0 through $f31).
$f0 and $f1) to create massive 64-bit mathematical structures.Standard MIPS instructions like add and lw cannot physically access the FPU. You must explicitly command the CPU to execute FPU-specific hardware commands. Notice they append .s (Single-Precision) or .d (Double-Precision) to the instruction.
lwc1 $f0, 0($a0) (Load Word to Coprocessor 1)add.s $f0, $f1, $f2 (Floating-Point Addition)mfc1 $t0, $f12 (Move From Coprocessor 1 into Integer CPU)F-Type (Floating-Point) Instruction Format:
opcode (6 bits) |
fmt (5 bits) |
ft (5 bits) |
fs (5 bits) |
fd (5 bits) |
funct (6 bits) |
|---|---|---|---|---|---|
| Instruction Class | Precision (.s=16, .d=17) |
Target Reg | Source Reg 1 | Dest Reg | Specific Math Operation |
$\Rightarrow$ For a complete execution list, refer to the “Floating-Point Instruction Formats” section on the back of your MIPS Green Sheet.
(Synthesized from Patterson & Hennessy’s COaD and Hamacher’s Embedded Systems)
While the basic fields of IEEE 754 provide range and precision, the standard dictates several critical architectural details for reliable hardware evaluation:
1 in the fractional component is always assumed (1.xxxxx). This “hidden bit” buys us one extra bit of free precision, granting 24 bits of effective accuracy in a 23-bit field.
00000000, Fraction = 011111111, Fraction = 0 (Used for divide-by-zero).11111111, Fraction $\neq 0$ (Used for illegal math, like taking the square root of a negative without complex logic).Example 1: Easy (Decimal to IEEE 754 Single Precision) Problem: Convert $-0.75_ {10}$ to IEEE 754 Single Precision binary. (Source: COaD) Solution:
1.01111110.1 (hidden bit). The fractional remainder is just 1. Pad with zeros: Mantissa = 100 0000 0000 0000 0000 0000.
Final 32-bit Code: 1 01111110 10000000000000000000000 (0xBF400000)Example 2: Medium/Hard (Floating-Point Decimal Arithmetic) Problem: Convert $12.375_ {10}$ to IEEE 754 Single Precision. Solution:
0.10000010.10001100000000000000000.
Final 32-bit Code: 0 10000010 10001100000000000000000 (0x41460000)(Synthesized from Harris & Harris’ Digital Design and COaD)
A critical aspect of Instruction Set Architecture (ISA) design is how to handle Literals/Immediates—hardcoded numbers directly embedded into the code (e.g., addi $t0, $t0, 4 or li $v0, 10).
0, 1, 4) account for over 50% of arithmetic and branching operands. Instead of storing these constants in memory and executing an expensive lw (Load Word) operation every time, MIPS dedicates the I-Type Instruction Format to embed a 16-bit literal directly inside the 32-bit instruction.li):
lui $t0, 0x1234 (Load Upper Immediate into the top 16 bits).ori $t0, $t0, 0xABCD (Bitwise OR the lower 16 bits).Example 1: Easy (Base I-Type Arithmetic)
Problem: Compile the C-code A = B - 50 into a MIPS native instruction assuming A = $s0 and B = $s1. (Source: Harris & Harris)
Solution:
There is no subi instruction in MIPS. The architecture handles negative constants using standard addi.
Assembly: addi $s0, $s1, -50
Machine Encoding:
addi): 8 $\rightarrow$ 001000rs ($s1): 17 $\rightarrow$ 10001rt ($s0): 16 $\rightarrow$ 10000imm ($-50_ {10}$ in Two’s Complement): 1111 1111 1100 1110Example 2: Medium/Hard (Loading a 32-bit Literal)
Problem: Load the enormous 32-bit hex address 0x003D0900 into integer register $s0. (Source: COaD)
Solution:
Because I-Type formats strictly limit immediate values to 16 bits, we cannot accomplish this in one clock cycle. We must use a two-instruction macro.
lui $s0, 0x003D (Loads 0000 0000 0011 1101 into the upper 16 bits, clears lower bits).ori $s0, $s0, 0x0900 (ORs 0000 1001 0000 0000 into the lower 16 bits).
(Note: Attempting to use addi instead of ori can fail here because addi sign-extends its 16-bit argument, potentially corrupting the explicit upper bit-pattern).(Synthesized from Harris & Harris and Cavanagh’s HDL Fundamentals)
How does the processor actually physically evaluate these instructions in SystemVerilog hardware?
add) usually resolves in a single clock cycle utilizing a standard ripple-carry or carry-lookahead adder. Floating-point operations, however, require massive gate depth. The physical implementation of an FPU instruction mathematically requires distinct sequential processing states:
1.xxxx leading format and adjust the exponent accordingly.add may finish in 1 cycle, an add.s might require 4 to 6 discrete clock cycles, and a div.s could halt the pipeline for 20+ cycles. This constraint highlights precisely why Coprocessor 1 must be logically segregated from the main integer datapath—if they shared the exact same clock phase logic, the floating-point latency would catastrophically cripple the entire central processing unit’s throughput.Example 1: Easy (Tracing an Integer Datapath)
Problem: Trace the specific microarchitectural hardware units utilized during a complete clock cycle of the instruction add $t0, $t1, $t2. (Source: Hamacher / Harris)
Solution:
The integer addition requires precisely defined functional units in sequence:
$t1 and $t2.$t1 + $t2 via its combinational gate datapath.$t0 using the Write Data port.
(Data Memory is entirely bypassed during an R-Type ALU operation).Example 2: Medium/Hard (Tracing a Coprocessor 1 FPU Pipeline)
Problem: Detail the sequential hardware logic utilized by the FPU to execute add.s $f0, $f1, $f2, highlighting why it cannot execute in a single basic clock cycle. (Source: Cavanagh HDL / COaD)
Solution:
Attempting $0.5 + (-0.4375)$ requires the FPU to perform multi-stage calculations that drastically exceed integer ALU latency.
$f1’s exponent is $2^{-1}$ and $f2 is $2^{-4}$. The smaller number ($-0.4375$) must be shifted dynamically to the right by 3 places so both numbers share the $2^{-1}$ power frame.1. The hardware must shift the solution left/right until the leading 1 is perfectly normalized (1.xxxx), while simultaneously decrementing/incrementing the resulting Exponent field.(For an explicit binary step-by-step logic trace of this execution pipeline, analyzing the alignment and addition of $7.875_{10} + 0.1875_{10}$, see Figure 5.29 below):

Exercise 1: Easy (Decimal to Single & Double Precision) Problem: Convert $8.5_ {10}$ to IEEE 754 Single-Precision (32-bit) and Double-Precision (64-bit) binary formats. Solution:
0.10000010.1. The fractional remainder is 0001. Pad with zeros to 23 bits $\rightarrow$ 0001 0000 0000 0000 0000 000.0 10000010 00010000000000000000000 (0x41080000)100 0000 0010.1. The fractional remainder is 0001. Pad with zeros to 52 bits $\rightarrow$ 0001 followed by 48 zeros.0 10000000010 0001000000000000000000000000000000000000000000000000 (Upper: 0x40210000, Lower: 0x00000000)Exercise 2: Medium (Negative Fractional Decimal) Problem: Convert $-0.15625_ {10}$ to IEEE 754 Single and Double Precision. Solution:
1.01111100.1 $\rightarrow$ 0100 0000 0000 0000 0000 000.1 01111100 01000000000000000000000 (0xBE200000)011 1111 1100.1 $\rightarrow$ 0100 followed by 48 zeros.1 01111111100 0100000000000000000000000000000000000000000000000000 (Upper: 0xBFC40000, Lower: 0x00000000)Exercise 3: Hard (Repeating Fraction & Rounding) Problem: Convert $0.1_ {10}$ to IEEE 754 Single and Double Precision. Solution:
0.01111011.1. We need the first 23 bits: 1001 1001 1001 1001 1001 100. The incredibly strict IEEE 754 “Round to Nearest, Ties to Even” requires us to look at the 24th bit (which is a 1). Since it’s a 1, we must round up our 23-bit mantissa $\rightarrow$ 1001 1001 1001 1001 1001 101.0 01111011 10011001100110011001101 (0x3DCCCCCD)011 1111 1011.1001100110011001100110011001100110011001100110011010.0 01111111011 1001100110011001100110011001100110011001100110011010 (Upper: 0x3FB99999, Lower: 0x9999999A)Exercise 4: Easy (IEEE 754 Binary to Decimal)
Problem: Convert the following 32-bit Single-Precision binary value (0x40D00000) into a base-10 decimal:
0 10000001 10100000000000000000000
Solution:
0 $\rightarrow$ The number is Positive $+$.10000001 in decimal is $128 + 1 = 129$. Subtract the Single-Precision bias (127): $129 - 127 = 2$. Exponent is $2^{2}$.101000.... Append the hidden leading 1.: The scientific fraction is $1.101_ {2}$.Exercise 5: Medium (IEEE 754 Hexadecimal to Decimal)
Problem: In a debugger, register $f0 contains the hex value 0xC1480000. What base-10 decimal value does this represent?
Solution:
C is 1100, 1 is 0001, 4 is 0100, 8 is 1000.
$\rightarrow$ 1100 0001 0100 1000 0000 0000 0000 00001 | 10000010 | 100100000000000000000001 $\rightarrow$ Negative $-$.10000010 is $128 + 2 = 130$. Minus bias: $130 - 127 = 3$. Exponent is $2^{3}$.1001: $1.1001_ {2}$.Exercise 6: Hard (IEEE 754 Hexadecimal to Micro-Decimal)
Problem: MIPS memory contains 0xBED00000. Calculate its exact base-10 value.
Solution:
B = 1011, E = 1110, D = 1101, 0 = 0000.
$\rightarrow$ 1011 1110 1101 0000 0000 0000 0000 00001 | 01111101 | 101000000000000000000001 $\rightarrow$ Negative $-$.01111101 in decimal is $64 + 32 + 16 + 8 + 4 + 1 = 125$. Minus bias: $125 - 127 = -2$. Exponent is $2^{-2}$.101: $1.101_ {2}$.During Weeks 06 and 07, we observed the famous Quake III Arena Fast Inverse Square Root algorithm implemented in MIPS (quake_calc.s). Without understanding Chapter 3 and the IEEE 754 standard, the core logic appears to be pure sorcery.
Let us review the exact MIPS core logic utilized to approximate $\frac{1}{\sqrt{x}}$:
# Move float bits from FPU ($f12) into CPU Integer Register ($t0)
mfc1 $t0, $f12
# i = 0x5f3759df - ( i >> 1 );
srl $t1, $t0, 1 # Bit-shift right by 1
lw $t2, magic # Load magic number (0x5f3759df)
sub $t0, $t2, $t1 # Integer subtraction
# Move integer bits ($t0) back to FPU ($f0)
mtc1 $t0, $f0
Why does moving a floating-point number into an integer register, shifting its bits, and subtracting it from 0x5f3759df yield a phenomenally accurate first-pass approximation for $\frac{1}{\sqrt{x}}$?
The brilliance lies fundamentally in the IEEE 754 Exponent Bias and the Mantissa (Fraction) Normalization we just studied!
i >> 1): In the raw integer representation, shifting bits right by one position is exactly calculating the division by 2 (the $0.5$ in $-0.5$).0x5f3759df): Because we must negate the exponent ($-0.5$) and correctly subtract the IEEE 754 bias offset (+127), we cannot simply subtract from zero. Mathematical derivation of the optimal bias error offset ($\mu$) combined with the bit-shifted IEEE 754 exponent bias geometrically yields the hex constant 0x5f3759df.By exploiting the physical 32-bit structure of IEEE 754, the programmer bypassed the massive latency of FPU division and square-root operations—performing a complex non-linear curve approximation using a single sub-nanosecond integer bit-shift (srl) and an integer subtract (sub)!