During his continuing analysis of the architecture and microcode of Intel’s highly influential 8087 floating point unit (FPU) co-processor, [Ken Shirriff] has now arrived at the point where he can put together how the 8087’s microcode implements various x87 instructions. One of these, the FSCALE instruction turned out to be far more complicated than assumed, with one might assume to be a straightforward powers-of-two scaling turning out to entail over 140 micro-instructions and three levels of sub-routine calls just to handle all cases.
The annotated die shot in the heading image shows the functional blocks that are used by this one x87 instruction, to give some kind of idea of what amount of hardware even ‘just’ scaling a floating point number involves.
Much like with the x86’s CISC-style ISA, these 8087 instructions break down into individual steps that involve everything from loading values into registers, performing operations, checking for and handling error conditions as well as stack management. As can be seen in [Ken]’s breakdown of the FSCALE implementation in the 8087 it’s all very logical, taking a high-level instruction and doing all that’s needed for a robust implementation, without bothering the developer with the details.
Of note is that the 8087’s implementations led to the IEEE 754 floating point standard, providing what definitely at the time was one of the most mathematically accurate FPUs that somehow still was financially responsible enough to make it into a relatively affordable PC.

I’m amazed at how many options and different formats for this and that that were supported in 1980, it seems to have complicated things enormously at a time when on-chip RAM and ROM were hugely expensive. Thank you [Ken Sherriff], as fascinating as usual.
Whoever wrote that microcode was surely not expecting it to ever see it publicly analysed!
Oh, the memories. Implementing this on an 8080, as well as PDP8 format, and the translation between the two. Old lab machine and hardware interfaces from DEC, the banging’ new IBM-PC with two– count them! TWO!– floppy drives and an 8087, with a SOL-20 between them to handle buffering and format translation for data. SOmething with a Z80 would have been better, but the SOL was there and the S-100 bus space was there and multi-serial s-100 card was there and CPM was there and… It was a weird time. Later, had to write a basic 8087 compatible library for a class. For the 8085. Hammered it out in a couple hours, passed all test vectors. Only one or two other people passed in a 300 level course with maybe 300 students between all sections. Evaluator asked me how and I just told him I’d written most of it before.
One thing that is key in the IEEE 754 spec is that it is NOT actually 8087 format. Similar, and many people working on the committee had been involved in the 8087 (both Intel people and hired guns like Bill Kahan, who was also instrumental in improving the HP calculator operations in the late 1970’s. IIRC, he was responsible for the first keypress zero solver, as well as improving the least significant end for several transcendental functions)
I did an implementation of IEEE754 in assembler on a 6502 at university shortly after the specs were published. The code was way less than the 16kB the 8086 emulator code did inasmuch my computer only had 4kB of RAM; but then again, I didn’t have to implement the 8087 specification and the interfacing to a 8086/8088 processor (like capturing the illegal instruction interrupt to do the calculations).
If I remember correctly, one key difference between the 8087 and IEEE754 was the the former had the leading, almost-always-one bit explicitly included in the representation whereas it was implicit in IEEE754 to gain an extra bit’s worth of precision for the same size of a number — and caused higher complexity in the implementation. Sigh!
Fun times then and a top grade earned — I have to cherish the little victories, eh?
IEEE754 on a 6502? There is a Hack A Day story ;)
I wish I still had the source code as I had to use all the clever tricks the little one could handle. After I finished this, a friend of mine created a 1024-point fast fourier transformation (FFT) program using my FP routines. It required SIN and COS functions, which I implemented with Chebyshev recurrence as the FFT routine only uses multiples of a given base angle, v (2π/1024 for a 1024-point FFT if I remember correctly), basically using four constants (cos(0)=1; sin(0)=0; cos(π/512); sin(π/512)) and looping through with
cos(n×v)=2cos(v)cos((n-1)v)-cos((n-2)v)
and
sin(n×v)=2cos(v)sin((n-1)v)-sin((n-2)v)
This way of calculating it requires the four constants and two temporary values of storage and then looping — not very fast but rather efficient in a memory-strapped computer.
Ah, those were the times.
According to Ken’s article, the internal representation has a leading 1, but the external format (i.e. what the programmer would see) has not.