// HACKER NEWS — CYBERSECURITY
Microcode in Intel's 8087 floating-point chip: the scale instruction
Computer history, restoring vintage computers, IC reverse engineering, and whatever
In the 1970s, floating-point arithmetic was a mess. Computer manufacturers had a dozen incompatible arithmetic standards.
Moreover, floating-point systems were designed around hardware simplicity rather than mathematical rigor, leading to problems
with numerical stability.
This changed when Intel introduced the 8087 floating-point coprocessor chip in 1980, designed to be as accurate as possible, even in the corner cases.
The 8087 became popular because it could be installed in the IBM PC, making floating-point operations up to 100 times faster in applications ranging from
spreadsheets to CAD.
But more importantly, the 8087 became the floating-point standard used by most computers today.
The 8087 implemented its instructions in complex low-level code called microcode.
I'm part of a group, the Opcode Collective, that is reverse-engineering this microcode, and I've recently made some progress.
In this post, I examine the microcode for one of the 8087's instructions—FSCALE—and describe how this microcode works.
The FSCALE (Floating-point Scale) instruction provides a quick way to scale a number by a power of two, much faster than a multiplication.
I figured that FSCALE was a simple, almost trivial instruction that would be straightforward to understand and explain.
Spoiler: it is not simple. FSCALE uses over 140 micro-instructions and three levels of subroutine calls to handle many special cases.
But the FSCALE microcode illustrates many interesting parts of the 8087, such as the shifter, the adder, and the exponent converter, and also reveals a
hidden feature of the 8087, so hopefully you will find it interesting.
To explore the microcode, I opened up an 8087 chip and created a high-resolution image with a microscope.
The large microcode ROM is in the center, holding the 1648 micro-instructions that control the chip.
The microcode engine on the left steps through the microcode, handling jumps and subroutine calls.
The bottom half of the chip is the "datapath", the circuitry that performs floating-point calculations; it is split into a 16-bit datapath for the
number's exponent and a 64-bit datapath for the number's significand (also known as the fractional part).
Zooming in on the bottom part of the chip shows the datapath circuitry; I've highlighted the relevant parts below.1
The exponent ROM holds various constants.
The exponent converter is a specialized circuit that examines exponents, detects special values, and converts between exponent formats.2
The shifter is a large component; it allows a 64-bit3 value to be shifted left or right by arbitrary amounts. (I wrote about the 8087's shifter circuitry here.)
The adder is the heart of the 8087's calculations; it is used in a loop for multiplication, division, and square roots.
The B register holds one input to the adder, while multiple sources can provide the other input. The sum register holds the adder's output.
The eight stack registers and the temporary registers hold floating-point numbers.
In this section, I'll explain some features of the 8087 that are important for the FSCALE microcode.
To use the 8087, a programmer stores values in its eight internal registers, organized as a stack. Each register holds an 80-bit floating-point number.
To optimize performance,
each value in the register stack has an associated "tag" value, which is mostly invisible to the programmer.4
A tag labels a value as valid, special, zero, or empty.
A "normal" floating-point value is tagged as valid. If the floating-point value is infinity, Not a Number (NaN), or a denormalized value,
then it is tagged as special. A zero value is tagged as zero.
Finally, if a register is empty (e.g., its value has been popped off the stack), the register is tagged as empty.
The 8087 also has temporary registers that it uses internally: tmpA, tmpB, and tmpC.
Like the stack registers, tmpA and tmpB are 80-bit registers, along
wi