# x87 trigonometric instructions

The 8087 has instructions FPTAN and FPATAN, which are Partial Tangent and Partial Arctangent. The "partial" is presumably is to do with the range of the operands. For FPTAN the operand must be less than pi / 4 in absolute value.

Why was there this restriction, so why is it not pi / 2?

With the 80387, the FPTAN has to have an absolute value less than 2^63, but what is the reason for this number?

Finally, was there a reason that the 8087 did not include FCOS and FSIN?

• Guess: The restriction is there because whatever approximation is used isn't good enough outside of pi/4, and they don't have enough gates to reduce the pi/2 range to pi/4 in hardware, so they leave that to software. So to answer the question, one must find out what approximation is used in the 8087... – dirkt Mar 28 '20 at 15:30
• Your guess is borne out by this paper -- see for example the FSIN error graph on page 5. – another-dave Mar 28 '20 at 16:06
• It is a range of pi/2 that just happens to go from -pi/4 to pi/4 which covers the full period of the function. – Brian Mar 28 '20 at 16:37
• … and the improved algorithm produces results which may surprise people, for example FSIN(MATH_PI) is not exactly zero because the floating point constant MATH_PI is not exactly equal to pi! – alephzero Mar 28 '20 at 18:08
• @another-dave good reference. In the 1990s Intel replaced the 8087’s CORDIC-based approximations with polynomial-based approximations, which have greater overall accuracy and speed. So the 80387 FSIN would have had even larger errors! It also says “FPTAN(x) should not be relied on as an accurate approximation of tan(𝑥) near multiples of π/2, odd or even”. – Single Malt Mar 29 '20 at 10:48

The tan(x) function has a period of π radians, with asymptotes at ±π/2; it effectively calculates sin(x)/cos(x), and the latter goes to zero at those points. So a function which evaluates properly over that interval can be used for any angle, by first reducing the angle to the range supported.

However, accurately calculating the tangent function near the asymptotes is more difficult than near the origin. It can still be done by further reducing the input angle to the ±π/4 range and taking the reciprocal of the result. This works because sin(x) == cos(x - π/2) and both functions are periodic, which you can substitute into the identity above.

The 8087 FPTAN instruction was evidently designed to cover only the half-period immediately surrounding the origin, making the assumption that the programmer would reduce angles to that range before executing it. This is common with polynomial approximations, which are much easier to implement in an FPU than a fully accurate calculation.

The 80387 runs into a different limitation, as it clearly implements a reduction step to permit an extended range of inputs. But the double-extended format has a 63-bit significand, so reducing a value larger than 2^63 would leave no significant precision behind. Even as you approach that limit, the available precision reduces substantially in absolute terms.

While the 8087 did not include sine and cosine calculations, it is possible to derive them using the following identities:

1+Tan^2(a) = 1/Cos^2(a)
1+Cot^2(a) = 1/Sin^2(a)

Hence something like the following sequence would apply:

``````FPTAN
FMUL ST(0)  ; square the tangent
FLD1
FSQRT       ; square root
FLD1
FDIVP       ; reciprocal
``````

The above would produce the cosine, but not necessarily with the correct sign. This would have to be inferred from the quadrant of the original input (before reduction).

Obviously, obtaining the correct result from a single instruction is much faster and more convenient, which is why it was added to the 80387. In the earlier 8087, the space for microcode was decidedly limited, so functions that weren't strictly necessary were simply left out.

Full implementations of trigonometric functions usually start with a reduction step anyway, to improve the precision of the result by avoiding large values internal to the computation. These can still be implemented on the 8087 using the five elementary operations - addition, subtraction, multiplication, division, and square root.

• The tangent function has a period of π, with poles at ±π/2. The OP is specifically asking why the tangent function on the 8087 only covers the interval [-π/4, π/4], rather than the full interval between the poles. The Taylor series around 0 converges for the whole interval. – Sven Marnach Mar 28 '20 at 20:57
• @SvenMarnach Good point, and I've expanded the answer to explain why that's still usable. – Chromatix Mar 28 '20 at 21:36
• Double-extended has 64-bit significand, not 63. Moreover, the most significant bit is even explicitly stored in the format, unlike single and double precision formats. – Ruslan Mar 29 '20 at 8:36
• @Ruslan I excluded that most-significant bit because, for the range of numbers in question, it is fixed at 1 and thus not significant. – Chromatix Mar 29 '20 at 9:50
• Erm... I don't quite get why being fixed at 1 makes it not significant. Its value changes with exponent, so it's not like a useless constant digit. Besides, for denormals (which are inside the range (-2⁶³,2⁶³)) it's zero. – Ruslan Mar 29 '20 at 10:17

The restrictions on the range of arguments the transcendental instructions are able to handle is a direct result of hardware resource limitations in these early floating-point units. The primary source for the implementation details of the transcendental instructions in the 8087 is:

Rafi Nave, "Implementation of transcendental functions on a numerics processor". Microprocessing and Microprogramming, Vol. 11, No. 3-4, March-April 1983, pp. 221-225

It states that the microcode size was limited to about 500 lines for all of the transcendentals combined. Because of limited hardware, the algorithms used are based on CORDIC for the initial steps, followed by rational approximation once the partial remainder has become sufficiently small.

To fit the ~30kbit microcode ROM into the chip at all with the transistor densities and die sizes available at the time (the 8087 contained more transistors than the 8086), Intel had to resort to a special four-state ROM, as described in

Rafi Nave and John Palmer, "A Numeric Data Processor". In 1980 IEEE International Solid-State Circuits Conference, Philadelphia, PA, USA, February 13-15, 1980, pp. 108-109

A second source, that pertains to the 80387 which relaxed several range restrictions on the transcendental instructions describes the same combination of CORDIC and rational approximation as was used in the 8087:

Alan K. Yuen, "Intel's Floating-Point Processors". Electro/88 Conference Record, Boston, MA, USA, May 10-12, 1988, pp. 48/5/1-7.

Palmer and Morse, who were architects of the 8086/8087, published a book on the math coprocessor:

John F. Palmer and Stephen P. Morse, "The 8087 Primer", John Wiley & Sons, 1984

In the chapter on the transcendental functions, they likewise cite the severe restrictions on microcode size as the reason for the range limitations of the built-in transcendental instructions of the 8087. The fundamental design idea was to support only the most time-consuming part of these computations in hardware and let programmers handle the argument reduction in software.

All trigonometric functions can be computed via `FPTAN`and all inverse trigonometric functions can be computed via `FPATAN`, as shown in "The 8087 Primer", alleviating the need for direct hardware support given the severe hardware resource limitations in the 8087. For the 80387, more hardware resources were available, which allowed support for the `FSINCOS` instruction.

• From the Software Developer's Manual: "An important use of the FPREM instruction is to reduce the arguments of periodic functions. When reduction is complete, the instruction stores the three least-significant bits of the quotient in the C3, C1, and C0 flags of the FPU status word. This information is important in argument reduction for the tangent function (using a modulus of π/4), because it locates the original angle in the correct one of eight sectors of the unit circle". Is this step done first, then FPTAN? – Single Malt Mar 30 '20 at 20:04
• @SingleMalt `FPREM` (better even `FPREM1` introduced with the 80387) can be used for argument reduction. However, this means that the value of π/2 used in the process is only accurate to extended precision, which causes accuracy issues in the trig functions for arguments that are large in magnitude, or close to integer multiples of π/2. A numerically superior alternative would be to use the argument reduction algorithm by Payne and Hanek published in 1983. – njuffa Mar 30 '20 at 20:51
• Had not heard of the Payne and Hanek algorithm. Interesting, and great answer with the C code so can step through. The quantification above of ~30kbit microcode limit with 500 lines for all of the transcendentals similarly excellent. – Single Malt Mar 31 '20 at 17:17
• @Single Malt: The literature reference is: M. Payne and R. Hanek. “Radian reduction for trigonometric functions,” SIGNUM Newsletter, 18:19–24, 1983. Most people, including me, find that article very hard to understand. That's why I pointed you at my C implementation instead. The Nave/Palmer paper says "microcode (including constants) utilizes over 30,000 bits of ROM". Based on a high-resolution die photo, Ken Shirriff counted 26368 bits for the microcode alone. – njuffa Mar 31 '20 at 19:38

I remember that FPTAN didn't give the actual tg(x), but two results and you had to divide one by another in order to get tg(x) (and they were not sin(x) and cos(x) as one would hope).

Probably that's why it was "Partial".