Ken Shirriff has been reverse-engineering the Intel 8087’s microcode instruction by instruction. This installment covers FPTAN, the tangent instruction, and the answer is neither of the textbook algorithms on its own: the chip uses CORDIC and a polynomial, and the seam between them is the interesting part.

Why 16 CORDIC steps and not 64:

  • CORDIC buys one bit of accuracy per iteration, so 64-bit precision the pure way would need 64 angles and 64 rotations.
  • The 8087 runs 16 steps, leaving a residual angle of about 2⁻¹⁶.
  • That residual goes to a Padé approximant, 3x/(3 − x²). Its error scales with x⁴, so at x < 2⁻¹⁶ the error lands under 2⁻⁶⁴ — the target, met exactly.
  • A ratio of polynomials also fits tan better than a Taylor series, because tan diverges at π/2 and a polynomial can’t.

The instruction is split into three phases, and only the middle one is expensive:

  • Pseudo-division: compare each stored angle against the remaining angle, subtract if smaller, record 1 or 0 into a 16-bit shift register. No rotation happens yet — this phase only decides which rotations are needed.
  • Rational approximation: compute 3x/(3 − x²) on the residual and use it as the starting vector.
  • Pseudo-multiplication: replay the decisions as rotations, smallest first to limit rounding error, shifting bits out until the register empties so small inputs exit early.

What makes it fast is mostly what it refuses to do. FPTAN returns the partial tangent — numerator and denominator as separate stack values — so the division is deferred to the caller. That one decision lets the Padé approximation be a plain pair of polynomials and lets the CORDIC replay consume them directly as (X, Y). Multiplying by 3 is a shift and an add; the constant 3 itself comes from transistors that set the top two significand bits.

The only genuinely expensive step is squaring the angle, done with radix-4 Booth multiplication in hardware, 32 adds per micro-instruction. Typical FPTAN is 450 cycles, split roughly 33% pseudo-division, 47% pseudo-multiplication, 15% polynomial.

Two details worth stealing for any fixed-point routine:

  • The microcode uses 64-bit integer arithmetic with implicit exponents. No exponent bits are stored anywhere, even in the ROM constants, and the implicit exponent changes every loop iteration to keep all 64 bits live instead of accumulating leading zeros.
  • Deciding first and executing later is what allows the rotations to run in reverse order for accuracy, and it’s why the decision shift register could be placed in leftover space on the far right of the die — it only needs two lines.

Intel dropped CORDIC on the Pentium once fast hardware multiplication made polynomials practical, and modern math libraries use SIMD polynomial kernels instead of dedicated circuits. The 8087 is the good case study precisely because it hedged, and you can see the hedge in the silicon.