5

As far as I know, old x86 CPUs (for example: the 8086 CPU) couldn't do floating point arithmetic, and in order to be able to do floating-point arithmetic, an x87 floating-point coprocessor should be attached to it.

The x87 floating-point coprocessor have instructions like FILD and 8 registers (which are st0 to st7).

Now if an 8086 CPU had an x87 floating-point coprocessor attached to it, can the 8086 CPU in this case execute the x87 floating-point coprocessor instructions and access its registers as if they were part of the 8086 CPU?

user12280
  • 283
  • 2
  • 4
  • 1
    There is nothing stopping an 8086 processor doing floating point without a co-processor (it just takes longer). Microsoft / Borland floating point routines used to put an interrupt instruction before the normal 8087 instruction sequences, when the interrupt was called it checked to see if there was a floating processor installed and emulated the instructions if there was one, otherwise it patched the original interrupt instruction to be a NOP. – PeterI Apr 11 '19 at 13:51
  • It's not strictly true to say that early x86 CPU's could not do floating point arithmetic. They can and did, via software implementations of the necessary algorithms. This was very commonplace, both for floating point data types and others that were not directly supported in hardware. From a user's point of view, the 8087 mainly made things (potentially much) faster through its provision of hardware based algorithms. But of course, the software had to be written to issue instructions to the 8087, so there were often two codepaths - with and without the 8087. – mschaef Apr 11 '19 at 13:52
  • @mschaef: One of the reasons for the 80-bit extended-precision floating-point format was that processors like the 8086 and 68000 could compute with it much more efficiently than with the more compact 64-bit type. – supercat Apr 11 '19 at 15:25
  • @supercat Do you have a reference for that? Would be interested to see details, since it doesn't really match my intuition. (That 80-bits would require both more integer instructions to process and more memory space/bandwidth to move around.) – mschaef Apr 11 '19 at 15:28
  • @mschaef: A 53-bit significant will need to be processed as four 16-bit words (or,on the 68000, two 32-bit words) after the exponent is masked off. A 64-bit significant would need to be processed likewise, but without the masking step. Further, if an implementation keeps a "possibly non-normalized 80-bit value" type for internal use, it could process something like: – supercat Apr 11 '19 at 15:36
  • ...((16777217 - 16777216) + 16777216) without having to shift the first sum left 24 bits and then shift it right 24 bits when adding the last term. An 8-bit processor might take a little longer to process a 64-bit significant than a 56-bit one, but for additions and subtractions the savings on shifting and masking would outweigh the cost of an extra 8 bits of addition. – supercat Apr 11 '19 at 15:40
  • @supercat For whatever it's worth, William Kahan credits the inclusion of 80-bit to round off errors, rather than anything related to performance: "An Extended format as wide as we dared (80 bits) was included to serve the same support role as the 13-decimal internal format serves in Hewlett-Packard’s 10- decimal calculators (their 12-digit calculators use 15 digits). " -- https://people.eecs.berkeley.edu/~wkahan/MathSand.pdf . (Kahan was heavily involved in the design of the 8087, IEEE-754, and HP calculators.) – mschaef Apr 11 '19 at 21:51
  • (Semi-related to this is Java's strictfp keyword that disallows the use of 80-bit intermediate results when working with 64-bit doubles) -- https://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.4 – mschaef Apr 11 '19 at 21:54
  • @mschaef: The 80-bit type offered both advantages, regardless of which was the larger motivation. The designs of the single and double types prioritize storage efficiency over computational efficiency, while the design of the 80-bit type does the opposite. – supercat Apr 11 '19 at 22:21

1 Answers1

11

The 8087 doesn’t add new capabilities to the 8086 itself; it acts purely as a co-processor — a similar model which might be more familiar nowadays is that of a GPU attached to a CPU.

The 8087’s registers aren’t accessible to the 8086, and the 8086 doesn’t execute any 8087 instructions. Both processors read the instruction stream, as the 8086 reads it from memory; both can recognise instructions targeted at the 8087, so the 8087 will know to execute them, and the 8086 will know not to (although it will perform some processing if necessary — e.g. address calculations). When necessary, the 8086 can be told to wait for the 8087 to finish processing an instruction. See How did the 8086 interface with the 8087 FPU coprocessor? for details.

Data is provided to the 8087 either by loading immediate values from the instruction stream, by reading values from memory, or by loading constants. Data is read from the 8087 by asking the 8087 to write values from its registers to memory. Values can’t be copied directly between 8086 and 8087 registers.

Stephen Kitt
  • 121,835
  • 17
  • 505
  • 462