From 2ab801bbc95cc663399b97d52b47000638e2e53f Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Wed, 16 Dec 2015 13:21:16 -0800 Subject: [PATCH] 8087 information --- pubs/pc/reference/intel/8087/README.md | 347 +++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 pubs/pc/reference/intel/8087/README.md diff --git a/pubs/pc/reference/intel/8087/README.md b/pubs/pc/reference/intel/8087/README.md new file mode 100644 index 000000000..46b3c856a --- /dev/null +++ b/pubs/pc/reference/intel/8087/README.md @@ -0,0 +1,347 @@ +--- +layout: page +title: Intel 8087 FPU Information +permalink: /pubs/pc/reference/intel/8087/ +--- + +Intel 8087 FPU Information +--- + +From the [iAPX 86 [8086], 88 [8088] USER'S MANUAL, AUGUST 1981](/pubs/pc/reference/intel/), p.S-1, +"THE 8087 NUMERIC DATA PROCESSOR": + +> **S.1 Processor Overview** + +> The 8087 Numeric Data Processor is a coprocessor that performs arithmetic and comparison operations on a +variety of numeric data types; it also executes numerous built-in transcendental functions (e.g., tangent and +log functions). As a coprocessor to a maximum mode 8086 or 8088, the NDP effectively extends the register and +instruction sets of the host CPU and adds several new data types as well. The programmer generally does not +perceive the 8087 as a separate device; instead, the computational capabilities of the CPU appear greatly expanded. + +> ***Evolution*** + +> In the mid-1970's, Intel made the commitment to expand the computational capabilities of microprocessors +from addition and subtraction of integers to an array of widely useful operations on real numbers. (Real numbers +encompass integers, fractions, and irrational numbers such as π and √2.) In 1977, the corporation adopted a +standard for representing real numbers in a "floating point" format. Intel's Floating Point Arithmetic Library +(FPAL) was the first product to utilize this standard format. FPAL is a set of subroutines for the 8080/8085 +microprocessors. These routines perform arithmetic and limited standard functions on single precision (32-bit) +real numbers; an FPAL multiply executes in about 1.5 ms (1.6 MHz 8080A CPU). The next product, the iSBC 31O™ +High Speed Math Unit, essentially implements FPAL in a single iSBC™ card, reducing a single-precision multiply +to about 100 µs. The Intel® 8232 is a single-chip arithmetic processor for the 8080/8085 family. The 8232 accepts +double precision (64-bit) operands as well as single precision numbers. It performs a single precision multiply in +about 100 µs and multiplies double precision numbers in about 875 µs (2 MHz version). + +> In 1979, a working committee of the Institute for Electrical and Electronic Engineers (IEEE) proposed an +industry standard for minicomputer and microcomputer floating point arithmetic*. The intent of the standard is +to promote portability of numeric programs between computers and to provide a uniform programming environment that +encourages the development of accurate, reliable software. The proposed standard specifies requirements and options +for number formats as well as the results of computations on these numbers. The floating point number formats are +identical to those previously adopted by Intel and used in the products described in this section. + +> *J. Coonen, W. Kahan, J. Palmer, T. Pittman, D. Stevenson, "A Proposed Standard for Binary Floating Point Arithmetic," +ACM SIGNUM Newsletter, October 1979. + +> The 8087 Numeric Data Processor is the most advanced development in Intel's continuing effort to provide improved +tools for numerically-oriented microprocessor applications. It is a single-chip hardware implementation of the +proposed IEEE standard, including all its options for single and double precision numbers. As such, it is compatible +with previous Intel numerics products; programs written for the 8087 will be transportable to future products that +conform to the proposed IEEE standard. The NDP also provides many additional functions that are extensions to the +proposed standard. + +> ***Performance*** + +> The 8087 multiplies 32-bit and 64-bit real numbers in about 19 µs and 27 µs, respectively. Of course, the actual +performance of the NDP in a given system depends on numerous application-specific factors. + +> Table S-1 compares the execution times of several 8087 instructions with the equivalent operations executed in +software on a 5 MHz 8086. The software equivalents are highly optimized assembly language procedures from the 8087 +emulator, an NDP development tool discussed later in this section. + +> The performance figures quoted in this section are for operations on real (floating point) numbers. The 8087 +also has instructions that enable it to utilize fixed point binary and decimal integers of up to 64 bits and 18 digits, +respectively. Using an 8087, rather than multiple precision software algorithms for integer operations, can provide +speed improvements of 10-100 times. + + Table S-1. 8087 Emulator Speed Comparison + (Approximate Execution Time in µs, 5 MHz Clock) + + Instruction 8087 8086 Emulation + + Multiply (single precision) 19 1,600 + Multiply (double precision) 27 2,100 + Add 17 1,600 + Divide (single precision) 39 3,200 + Compare 9 1,300 + Load (single precision) 9 1,700 + Store (single precision) 18 1,200 + Square root 36 19,600 + Tangent 90 13,000 + Exponentiation 100 17,100 + +> The 8087's unique coprocessor interface to the CPU can yield an additional performance increment beyond that +of simple instruction speed. No overhead is incurred in setting up the device for a computation; the 8087 decodes +its own instructions automatically in parallel with the CPU. Moreover, built-in coordination facilities allow the +CPU to proceed with other instructions while the 8087 is simultaneously executing its numeric instruction. +Programs can exploit this processor parallelism to increase total system throughput. + +> ***Usability*** + +> Viewed strictly from the standpoint of raw speed, the 8087 enables serious computation-intensive tasks to be +performed by microprocessors for the first time. The 8087 offers more than just high performance, however. +By synthesizing advances made by numerical analysts in the past several years, the NDP provides a level of usability +that surpasses existing minicomputer and mainframe arithmetic units. In fact, the charter of the 8087 design team was +first to achieve exceptional functionality and then to obtain high performance. + +> The 8087 is explicitly designed to deliver stable, accurate results when programmed using straightforward "pencil +and paper" algorithms. While this statement may seem trivial, experienced users of "floating point processors" will +recognize its fundamental importance. For example, most computers can overflow when two single precision floating +point numbers are multiplied together and then divided by a third, even if the final result is a perfectly valid +32-bit number. The 8087 delivers the correctly rounded result. Other typical examples of undesirable machine behavior +in straightforward calculations occur when solving for the roots of a quadratic equation: + + -b ± √b^2 - 4ac + --------------- + 2a + +> or computing financial rate of return, which involves the expression: (1+i)^n. Straightforward algorithms will not +deliver consistently correct results (and will not indicate when they are incorrect) on most machines. To obtain +correct results on traditional machines under all conditions usually requires sophisticated numerical techniques that +are foreign to most programmers. General application programmers using straight-forward algorithms will produce much +more reliable programs on the 8087. This simple fact greatly reduces the software investment required to develop safe, +accurate computation-based products. + +> Beyond traditional numerics support for "scien-tific" applications, the 8087 has built-in facilities for "commerical" +computing. It can process decimal numbers of up to 18 digits without round-off errors, and it performs exact arithmetic +on integers as large as 2^64. Exact arithmetic is vital in accounting applications where rounding errors may introduce +money losses that cannot be reconciled. + +> The NDP contains a number of facilities that can optionally be invoked by sophisticated users. Examples of these +advanced features include two models of infinity, directed rounding, gradual underflow, and traps to user-written +exception handling software. + +> ***Programming Interface*** + +> The combination of an 8086 or 8088 CPU and an 8087 generally appears to the programmer as a single machine. The 8087, +in effect, adds new data types, registers, and instructions to the CPU. The programming languages and the coprocessor +architecture take care of most interprocessor coordination automatically. + +> Table S-2 lists the seven 8087 data types. Internally, the 8087 holds all numbers in the temporary real format; the +extended range and precision of this format are key contributors to the NDP's ability to consistently deliver stable, +expected results. The 8087's load and store instructions convert operands between the other formats and temporary real. +The fact that these conversions are made, and that calculations may be performed on converted numbers, is transparent +to the programmer. Integer operands, whether binary or decimal, yield correct integer results, just as real operands +yield correct real results. Moreover, a rounding error does not occur when a number in an external format is converted +to temporary real. + + Table S-2. Data Types + + Data Type Bits Significant Digits Approximate Range + (Decimal) (Decimal) + + Word Integer 16 4 -32,768 <= X <= +32,767 + Short Integer 32 9 -2x10^9 <= X <= +2x10^9 + Long Integer 64 18 -9x10^18 <= X <= +9x10^18 + Packed Decimal 80 18 -99...99 <= X <= +99...99 + Short Real* 32 6-7 8.43x10^-37 <= |X| <= +3.37x10^38 + Long Real* 64 15-16 4.19x10^-307 <= |X| <= +1.67x10^308 + Temporary Real 80 19 3.4x10^-4932 <= |X| <= +1.2x10^4932 + + *The short and long real data types correspond to the single and double precision data types + defined in other Intel numerics products. + +> Computations in the 8087 center on the processor's register stack. These eight 80-bit registers provide the +equivalent capacity of 40 of the 16-bit registers found in typical CPUs. This generous register space allows more +constants and intermediate results to be held in registers during calculations, reducing memory access and consequently +improving execution speed as well as bus availability. The 8087 register set is unique in that it can be accessed both +as a stack, with instructions operating implicitly on the top one or two stack elements, and as a fixed register set, +with instructions operating on explicitly designated registers. + +> Table S-3 lists the 8087's major instructions by class. Assembly language programs are written in A8M-86, the +8086/8088/8087 common assembly language. A8M-86 provides directives for defining all 8087 data types and mnemonics +for all instructions. The fact that some instructions in a program are executed by the 8087 and others by the CPU is +usually of no concern to the programmer. All 8086/8088 addressing modes may be used to access memory-based 8087 +operands, enabling convenient processing of numeric arrays, structures, based variables, etc. + + Table S-3. Principal Instructions + + Class Instructions + + Data Transfer Load (all data types), Store (all data types), Exchange + + Arithmetic Add, Subtract, Multiply, Divide, Subtract Reversed, Divide Reversed, + Square Root, Scale, Remainder, Integer Part, Change Sign, + Absolute Value, Extract + + Comparison Compare, Examine, Test + + Transcendental Tangent, Arctangent, 2^x-1, Y*Log2(X + 1), Y*Log2(X) + + Constants 0, 1, π, Log10(2), Loge(2), Log2(10), Log2(e) + + Processor Control Load Control Word, Store Control Word, Store Status Word, + Load Environment, Store Environment, Save, Restore, Enable Interrupts, + Disable Interrupts, Clear Exceptions, Initialize + +> NDP routines may also be written in PL/M-86, Intel's high-level language for the 8086 and 8088 CPUs. PL/M-86 +provides the programmer with access to many 8087 facilities while reducing the programmer's need to understand the +architecture of the chip. + +> Two features of the 8087 hardware further simplify numeric application programming. First, the 8087 is invoked +directly by the programmer's instructions. There is no need to write instructions that "address" the NDP as an "I/O +device", or to incur the overhead of setting up a DMA operation to perform data transfers. Second, the NDP +automatically detects exception conditions that can potentially damage a calculation at run-time. On-chip exception +handlers are automatically invoked by default to field these exceptions so that a reasonable result is produced and +execution may proceed without program intervention. Alternatively, the 8087 can interrupt the CPU and thus trap +to a user procedure when an exception is detected. + +> Besides the assembler and compiler, Intel provides a software emulator for the 8087. The 8087 emulator (E8087) +is a software package that provides the functional equivalent of an 8087; it executes entirely on an 8086 or 8088 CPU. +The emulator allows 8087 routines to be developed and checked out on an 8086/8088 execution vehicle before prototype +8087 hardware is operational. At the source code level, there is no difference between a routine that will ultimately +run on an 8087 or on a CPU emulation of an 8087. At link time, the decision is made whether to use the NDP or the +software emulator; no re-compilation or re-assembly is necessary. Source programs are independent of the numeric +execution vehicle: except for timing, the operation of the emulated NDP is the same as for "real hardware". The +emulator also makes it simple fora product to offer the NDP as a "plug-in" performance option without the necessity +of maintaining two sets of source code. + +> ***Hardware Interface*** + +> As a coprocessor to an 8086 or 8088, the 8087 is wired directly to the CPU. The CPU's queue status lines (QSO and QS1) +enable the NDP to obtain and decode instructions in synchronization with the CPU. The NDP's BUSY signal informs the +CPU that the NDP is executing; the CPU WAIT instruction tests this signal to ensure that the NDP is ready to execute +a subsequent instruction. The NDP can interrupt the CPU when it detects an exception. The NDP's interrupt request line +is typically routed to the CPU through an 8259A Programmable Interrupt Controller. + +> The NDP uses one of its host CPU's request/grant lines to obtain control of the local bus for data transfers (loads +and stores). The other CPU request/grant line is available for general system use, for example, by a local 8089 +Input/Output Processor. A local 8089 may also be connected to the 8087's RQ/GT1 line. In this configuration, the 8087 +passes the request/grant handshake signals between the CPU and the IOP when the 8087 is not in control of the local bus. +When it is in control of the bus, the 8087 relinquishes the bus (at the end of the current bus cycle) upon a request +from the connected IOP, giving the IOP higher priority than itself. In this way, two local 8089's can be configured in +a module that also includes a CPU and an 8087. + +> All processors utilize the same clock generator and system bus interface components (bus controller, latches, +transceivers, and bus arbiter). Thus, no additional hardware beyond the 8087 is required to add powerful computational +capabilities to an 8086- or 8088-based system. + +> **S.2 Processor Architecture** + +> The NDP is internally divided into two processing elements, the control unit (CU) and the numeric execution unit +(NEU). In essence, the NEU executes all numeric instructions, while the CU fetches instructions, reads and writes memory +operands, and executes the processor control class of instructions. The two elements are able to operate independently +of one another, allowing the CU to maintain synchronization with the CPU while the NEU executes numeric instructions. + +> ***Control Unit*** + +> The CU keeps the 8087 operating in synchronization with its host CPU. 8087 instructions are intermixed with CPU +instructions in a single instruction stream fetched by the CPU. By monitoring the status signals emitted by the CPU, +the NDP control unit can determine when an instruction is being fetched. When the instruction byte or word becomes +available on the local bus, the CU taps the bus in parallel with the CPU and obtains that portion of the instruction. + +> The CU maintains an instruction queue that is identical to the queue in the host CPU. By monitoring the CPU's queue +status lines, the CU is able to obtain and decode instructions from the queue in synchronization with the CPU. In effect, +both processors fetch and decode the instruction stream in parallel. + +> The two processors execute the instruction stream differently, however. The first five bits of all 8087 machine +instructions are identical; these bits designate the coprocessor escape (ESC) class of instructions. The control unit +ignores all instructions that do not match these bits, since these instructions are directed to the CPU only. When the +CU decodes an instruction containing the escape code, it either executes the instruction itself, or passes it to the +NEU, depending on the type of instruction. + +> The CPU distinguishes between ESC instructions that reference memory and those that do not. If the instruction refers +to a memory operand, the CPU calculates the operand's address and then performs a "dummy read" of the word at that +location. This is a normal read cycle, except that the CPU ignores the data it receives. If the ESC instruction does +not contain a memory reference, the CPU simply proceeds to the next instruction. + +> A given 8087 instruction (an ESC to the CPU) will either require loading an operand from memory into the 8087, +or will require storing an operand from the 8087 into memory, or will not reference memory at all. In the first two +cases, the CU makes use of the "dummy read" cycle initiated by the CPU. The CU captures and saves the operand address +that the CPU places on the bus early in the "dummy read". If the instruction is an 8087 load, the CU additionally +captures the first (and possibly only) word of the operand when it becomes available on the bus. If the operand to +be loaded is longer than one word, the CU immediately obtains the bus from the CPU and reads the rest of the operand +in consecutive bus cycles. In a store operation, the CU captures and saves the operand address as in a load, and +ignores the data word that follows in the "dummy read" cycle. When the 8087 is ready to perform the store, the CU +obtains the bus from the CPU and writes the operand at the saved address using as many consecutive bus cycles as are +necessary to store the operand. + +> ***Numeric Execution Unit*** + +> The NEU executes all instructions that involve the register stack; these include arithmetic, comparison, transcendental, +constant, and data transfer instructions. The data path in the NEU is 68 bits wide and allows internal operand transfers +to be performed at very high speeds. + +> ***Register Stack*** + +> Each of the eight registers in the 8087's register stack is 80 bits wide, and each is divided into the "fields" +shown in figure S-5. This format corresponds to the NDP's temporary real data type that is used for all calculations. +Section S.3 describes in detail how numbers are represented in the temporary real format. + +> At a given point in time, the ST field in the status word (described shortly) identifies the current top-of-stack +register. A load ("push") operation decrements ST by 1 and loads a value into the new top register. A store-and-pop +operation stores the value from the current top register and then increments ST by 1. Thus, like 8086/8088 stacks in +memory, the 8087 register stack grows "down" toward lower-addressed registers. + +> Instructions may address registers either implicitly or explicitly. Many instructions operate on the register at +the top of the stack. These instructions implicitly address the register pointed to by ST. + +> For example, the ASM-86 instruction FSQRT replaces the number at the top of the stack with its square root; this +instruction takes no operands because the top-of-stack register is implied as the operand. Other instructions allow +the programmer to explicitly specify the register that is to be used. Explicit register addressing is "top-relative" +where the ASM-86 expression ST denotes the current stack top and ST(i) refers to the ith register from ST in the stack +(0 <= i <= 7). For example, if ST contains O11B (register 3 is the top of the stack), the following instruction would +add registers 3 and 5: + + FADD ST, ST(2) + +> In typical use, the programmer may conceptually "divide" the registers into a fixed group and an adjustable group. +The fixed registers are used like the conventional registers in a CPU, to hold constants, accumulations, etc. +The adjustable group is used like a stack, with operands pushed on and results popped off. After loading, the registers +in the fixed group are addressed explicitly, while those in the adjustable group are addressed implicitly. Of course, +all registers may be addressed using either mode, and the "definition" of the fixed versus the adjustable areas may be +altered at any time. Section S.8 contains a programming example that illustrates typical register stack use. + +> The stack organization and top-relative addressing of the registers simplify subroutine programming. Passing +subroutine parameters on the register stack eliminates the need for the subroutine to "know" which registers actually +contain the parameters and allows different routines to call the same subroutine without having to observe a convention +for passing parameters in dedicated registers. So long as the stack is not full, each routine simply loads the parameters +on the stack and calls the subroutine. The subroutine addresses the parameters as ST, ST(l), etc., even though ST may, +for example, refer to register 3 in one invocation and register 5 in another. + +> ***Status Word*** + +> The status word reflects the overall condition of the 8087; it may be examined by storing it into memory with an +NDP instruction and then inspecting it with CPU code. The status word is divided into the fields shown in figure S-6. +The busy field (bit 15) indicates whether the NDP is executing an instruction (B=1) or is idle (B=O). + +> Several 8087 instructions (for example, the comparison instructions) post their results to the condition code (bits +14 and 10-8 of the status word). The principal use of the condition code is for conditional branching. This may be +accomplished by executing an instruction that sets the condition code, storing the status word in memory and then +examining the condition code with CPU instructions. + +> Bits 13-11 of the status word point to the 8087 register that is the current stack top (ST). Note that if ST=000B, +a "push" operation, which decrements ST, produces ST=111B; similarly, popping the stack with ST=111B yields ST=000B. + +> Bit 7 is the interrupt request field. The NDP sets this field to record a pending interrupt to the CPU. + +> Bits 5-0 are set to indicate that the NEU has detected an exception while executing an instruction. Section S.3 +explains these exceptions. + +> ***Control Word*** + +> To satisfy a broad range of application requirements, the NDP provides several processing options which are selected +by loading a word from memory into the control word. Figure S-7 shows the format and encoding of the fields in the +control word; it is provided here for reference. Section S.3 explains the use of each of these 8087 facilities except +the interrupt-enable control field, which is covered in section S.6. + +> ***Tag Word*** + +> The tag word marks the content of each register as shown in figure S-8. The principal function of the tag word is to +optimize the NDP's performance under certain circumstances and programmers ordinarily need not be concerned with it. + +> ***Exception Pointers*** + +> The exception pointers (see figure S-9) are provided for user-written exception handlers. Whenever the 8087 executes +an instruction, the CU saves the instruction address and the instruc- tion opcode in the exception pointers. In addition, +if the instruction references a memory operand, the address of the operand is retained also. An exception handler can +store these pointers in memory and thus obtain information concerning the instruction that caused the exception.