home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / intel / 80387.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  437.9 KB  |  9,167 lines

  1.  INTEL 80387 PROGRAMMER'S REFERENCE MANUAL 1987
  2.  
  3.  MARCOM DISCLAIMER -- New word: Intel Certified, iRMK, SupportNET
  4.  May 26, 1987
  5.  
  6.  Intel Corporation makes no warranty for the use of its products and
  7.  assumes no responsibility for any errors which may appear in this document
  8.  nor does it make a commitment to update the information contained herein.
  9.  
  10.  Intel retains the right to make changes to these specifications at any
  11.  time, without notice.
  12.  
  13.  Contact your local sales office to obtain the latest specifications before
  14.  placing your order.
  15.  
  16.  The following are trademarks of Intel Corporation and may only be used to
  17.  identify Intel Products:
  18.  
  19.  Above, BITBUS, COMMputer, CREDIT, Data Pipeline, FASTPATH, Genius, i, î,
  20.  ICE, iCEL, iCS, iDBP, iDIS, I²ICE, iLBX, im, iMDDX, iMMX, Inboard,
  21.  Insite, Intel, intel, intelBOS, Intel Certified, Intelevision,
  22.  inteligent Identifier, inteligent Programming, Intellec, Intellink,
  23.  iOSP, iPDS, iPSC, iRMK, iRMX, iSBC, iSBX, iSDM, iSXM, KEPROM, Library
  24.  Manager, MAPNET, MCS, Megachassis, MICROMAINFRAME, MULTIBUS, MULTICHANNEL,
  25.  MULTIMODULE, MultiSERVER, ONCE, OpenNET, OTP, PC BUBBLE, Plug-A-Bubble,
  26.  PROMPT, Promware, QUEST, QueX, Quick-Pulse Programming, Ripplemode, RMX/80,
  27.  RUPI, Seamless, SLD, SugarCube, SupportNET, UPI, and VLSiCEL, and the
  28.  combination of ICE, iCS, iRMX, iSBC, iSBX, iSXM, MCS, or UPI and a numerical
  29.  suffix, 4-SITE.
  30.  
  31.  MDS is an ordering code only and is not used as a product name or
  32.  trademark. MDS(R) is a registered trademark of Mohawk Data Sciences
  33.  Corporation.
  34.  
  35.  *MULTIBUS is a patented Intel bus.
  36.  Unix is a trademark of AT&T Bell Labs.
  37.  MS-DOS, XENIX, and Multiplan are trademarks of Microsoft Corporation.
  38.  Lotus and 1-2-3 are registered trademarks of Lotus Development Corporation.
  39.  SuperCalc is a registered trademark of Computer Associates International.
  40.  Framework is a trademark of Ashton-Tate.
  41.  System 370 is a trademark of IBM Corporation.
  42.  AT is a registered trademark of IBM Corporation.
  43.  
  44.  Additional copies of this manual or other Intel literature may be obtained
  45.  from:
  46.  
  47.  Intel Corporation
  48.  Literature Distribution
  49.  Mail Stop SC6-59
  50.  3065 Bowers Avenue
  51.  Santa Clara, CA 95051
  52.  
  53.  (c)INTEL CORPORATION 1987    CG-5/26/87
  54.  
  55.  
  56.  Customer Support
  57.  
  58.  ───────────────────────────────────────────────────────────────────────────
  59.  
  60.  Customer Support is Intel's complete support service that provides Intel
  61.  customers with hardware support, software support, customer training, and
  62.  consulting services. For more information contact your local sales offices.
  63.  
  64.  After a customer purchases any system hardware or software product,
  65.  service and support become major factors in determining whether that
  66.  product will continue to meet a customer's expectations. Such support
  67.  requires an international support organization and a breadth of programs
  68.  to meet a variety of customer needs. As you might expect, Intel's customer
  69.  support is quite extensive. It includes factory repair services and
  70.  worldwide field service offices providing hardware repair services,
  71.  software support services, customer training classes, and consulting
  72.  services.
  73.  
  74.  Hardware Support Services
  75.  
  76.  Intel is committed to providing an international service support package
  77.  through a wide variety of service offerings available from Intel Hardware
  78.  Support.
  79.  
  80.  Software Support Services
  81.  
  82.  Intel's software support consists of two levels of contracts. Standard
  83.  support includes TIPS (Technical Information Phone Service), updates and
  84.  subscription service (product-specific troubleshooting guides and COMMENTS
  85.  Magazine). Basic support includes updates and the subscription service.
  86.  Contracts are sold in environments which represent product groupings
  87.  (i.e., iRMX environment).
  88.  
  89.  Consulting Services
  90.  
  91.  Intel provides field systems engineering services for any phase of your
  92.  development or support effort. You can use our systems engineers in a
  93.  variety of ways ranging from assistance in using a new product, developing
  94.  an application, personalizing training, and customizing or tailoring an
  95.  Intel product to providing technical and management consulting. Systems
  96.  Engineers are well versed in technical areas such as microcommunications,
  97.  real-time applications, embedded microcontrollers, and network services.
  98.  You know your application needs; we know our products. Working together we
  99.  can help you get a successful product to market in the least possible time.
  100.  
  101.  Customer Training
  102.  
  103.  Intel offers a wide range of instructional programs covering various
  104.  aspects of system design and implementation. In just three to ten days a
  105.  limited number of individuals learn more in a single workshop than in
  106.  weeks of self-study. For optimum convenience, workshops are scheduled
  107.  regularly at Training Centers woridwide or we can take our workshops to
  108.  you for on-site instruction. Covering a wide variety of topics, Intel's
  109.  major course categories include: architecture and assembly language,
  110.  programming and operating systems, bitbus and LAN applications.
  111.  
  112.  Training Center Locations
  113.  
  114.  To obtain a complete catalog of our workshops, call the nearest Training
  115.  Center in your area.
  116.  
  117.  Boston                    (617) 692-1000
  118.  Chicago                   (312) 310-5700
  119.  San Francisco             (415) 940-7800
  120.  Washington D.C.           (301) 474-2878
  121.  Isreal                    (972) 349-491-099
  122.  Tokyo                     03-437-6611
  123.  Osaka (Call Tokyo)        03-437-6611
  124.  Toronto, Canada           (416) 675-2105
  125.  London                    (0793) 696-000
  126.  Munich                    (089) 5389-1
  127.  Paris                     (01) 687-22-21
  128.  Stockholm                 (468) 734-01-00
  129.  Milan                     39-2-82-44-071
  130.  Benelux (Rotterdam)       (10) 21-23-77
  131.  Copenhagen                (1) 198-033
  132.  Hong Kong                 5-215311-7
  133.  
  134.  
  135.  Preface
  136.  
  137.  ───────────────────────────────────────────────────────────────────────────
  138.  
  139.  This manual describes the 80387 Numeric Processor Extension (NPX) for the
  140.  80386 microprocessor. Understanding the 80387 requires an understanding of
  141.  the 80386; therefore, a brief overview of 80386 concepts is presented first.
  142.  A detailed discussion of the 80386 microprocessor can be found in the 80386
  143.  Programmer's Reference Manual.
  144.  
  145.  The 80386 Microsystem
  146.  
  147.  The 80386 is the basis of a new VLSI microprocessor system with exceptional
  148.  capabilities for supporting large-system applications. This powerful
  149.  microsystem is designed to support multiuser reprogrammable and real-time
  150.  multitasking applications. Its dedicated system support circuits simplify
  151.  system hardware; sophisticated hardware and software tools reduce both the
  152.  time and the cost of product development. The 80386 microsystem offers a
  153.  total-solution approach, enabling you to develop high-speed, interactive,
  154.  multiuser, multitasking──even multiprocessor──systems more rapidly and at
  155.  higher performance than ever before.
  156.  
  157.    ■  Reliability and system up-time are becoming increasingly important in
  158.       all applications. Information must be protected from misuse or
  159.       accidental loss. The 80386 includes a sophisticated and flexible
  160.       four-level protection mechanism that can isolate layers of operating
  161.       system programs from application programs to maintain a high degree of
  162.       system integrity.
  163.  
  164.    ■  The 80386 addresses up to 4 gigabytes of physical memory to support
  165.       today's application requirements. This large physical memory enables
  166.       the 80386 to keep many large programs and data structures
  167.       simultaneously in memory for high-speed access.
  168.  
  169.    ■  For applications with dynamically changing memory requirements, such
  170.       as multiuser business systems, the 80386 CPU provides on-chip memory
  171.       management and virtual memory support. On an 80386-based system, each
  172.       user can have up to 64 terabytes of virtual-address space. This large
  173.       address space virtually eliminates restrictions on the size of programs
  174.       that may be part of the system. The memory management features are
  175.       subject to control of systems software; therefore, systems software
  176.       designers can choose among a variety of memory-organization models.
  177.       Systems designers can choose to view memory in terms of fixed-length
  178.       pages, in terms of variable length segments, or as a combination of
  179.       pages and segments. The sizes of segments can range from one byte to 4
  180.       gigabytes. Virtual memory can be implemented either at the level of
  181.       segments or at the level of pages.
  182.  
  183.    ■  Large multiuser or real-time multitasking systems are easily supported
  184.       by the 80386. High-performance features, such as a very high-speed task
  185.       switch, fast interrupt-response time, intertask protection,
  186.       page-oriented virtual memory, and a quick and direct operating system
  187.       interface, make the 80386 highly suited to multiuser/multitasking
  188.       applications.
  189.  
  190.    ■  The 80386 has two primary operating modes: real-address mode and
  191.       protected mode. In real-address mode, the 80386/80387 is fully upward
  192.       compatible from the 8086, 8088, 80186, and 80188 microprocessors and
  193.       from the 80286 real-address mode; all of the extensive libraries of
  194.       8086 and 8088 software execute 15 to 20 times faster on the 80386,
  195.       without any modification.
  196.  
  197.    ■  In protected-address mode, the advanced memory management
  198.       and protection features of the 80386 become available, without any
  199.       reduction in performance. Upgrading 8086 and 8088 application
  200.       programs to use these new memory management and protection features
  201.       usually requires only reassembly or recompilation (some programs may
  202.       require minor modification). Entire 80286 protected-mode applications
  203.       can run in this mode without modification.
  204.  
  205.    ■  The virtual-8086 mode of the 80386 is available when the primary mode
  206.       is protected mode. Virtual-8086 mode enables direct execution of
  207.       multiple 8086/8088 programs within a protected-mode environment. Most
  208.       8086 and 8088 application programs can be executed in this environment
  209.       without alteration (refer to the 80386 Programmer's Reference Manual
  210.       for differences from 8086). This high degree of compatibility between
  211.       80386 and earlier members of the 8086 processor family reduces both
  212.       the time and the cost of software development.
  213.  
  214.  The Organization of This Manual
  215.  
  216.  This manual describes the 80387 Numeric Processor Extension (NPX) for the
  217.  80386 microprocessor. The material in this manual is presented from the
  218.  perspective of software designers, both at an applications and at a systems
  219.  software level.
  220.  
  221.    ■  Chapter 1, "Introduction to the 80387 Numerics Processor Extension,"
  222.       gives an overview of the 80387 NPX and reviews the concepts of numeric
  223.       computation using the 80387.
  224.  
  225.    ■  Chapter 2, "80387 Numerics Processor Architecture," presents the
  226.       registers and data types of the 80387 to both applications and systems
  227.       programmers.
  228.  
  229.    ■  Chapter 3, "Special Computational Situations," discusses the special
  230.       values that can be represented in the 80387's real formats──denormal
  231.       numbers, zeros, infinities, NaNs (not a number)──as well as numerics
  232.       exceptions. This chapter should be read thoroughly by systems
  233.       programmers, but may be skimmed by applications programmers. Many of
  234.       these special values and exceptions may never occur in applications
  235.       programs.
  236.  
  237.    ■  Chapter 4, "80387 Instruction Set," provides functional information
  238.       for software designers generating applications for systems containing
  239.       an 80386 CPU with an 80387 NPX. The 80386/80387 instruction set
  240.       mnemonics are explained in detail.
  241.  
  242.    ■  Chapter 5, "Programming Numeric Applications," provides a description
  243.       of programming facilities for 80386/80387 systems. A comparative 80387
  244.       programming example is given.
  245.  
  246.    ■  Chapter 6, "System-Level Numeric Programming," provides information of
  247.       interest to systems software writers, including details of the 80387
  248.       architecture and operational characteristics.
  249.  
  250.    ■  Chapter 7, "Numeric Programming Examples," provides several detailed
  251.       programming examples for the 80387, including conditional branching,
  252.       the conversion betweenfloating-point values and their ASCII
  253.       representations, and the use of trigonometric functions. These examples
  254.       illustrate assembly-language programming on the 80387 NPX.
  255.  
  256.    ■  Appendix A, "Machine Instruction Encoding and Decoding," gives
  257.       reference information on the encoding of NPX instructions. This
  258.       information is useful to writers of debuggers, exception handlers, and
  259.       compilers.
  260.  
  261.    ■  Appendix B, "Exception Summary," provides a list of the exceptions
  262.       that each instruction can cause. This list is valuable to both
  263.       applications and systems programmers.
  264.  
  265.    ■  Appendix C, "Compatability between the 80387 and the 80287/8087,"
  266.       describes the differences from the 80387 that are common to the 80287
  267.       and the 8087.
  268.  
  269.    ■  Appendix D, "Compatability between the 80387 and the 8087," describes
  270.       the additional differences between the 80387 and the 8087 that are of
  271.       concern when porting 8086/8087 programs directly to the 80386/80387.
  272.  
  273.    ■  Appendix E, "80387 80-Bit CHMOS III Numeric Processor Extension,"
  274.       reproduces a data sheet of 80387 specifications that is separately
  275.       available. The table of instruction timings in this appendix will be of
  276.       interest to many readers of this manual. (The AC specifications have
  277.       been deliberately left out.) The specifications in data sheets are
  278.       subject to change; consult the most recent data sheet for design-in
  279.       information.
  280.  
  281.    ■  Appendix F, "PC/AT-Compatible 80387 Connection," documents a
  282.       nonstandard method of connecting an 80387 to an 80386 to achieve
  283.       compatibility with the IBM PC/AT.
  284.  
  285.    ■  The Glossary defines 80387 and floating-point terminology. Refer to it
  286.       as needed.
  287.  
  288.  Related Publications
  289.  
  290.  To best use the material in this manual, readers should be familiar with
  291.  the operation and architecture of 80386 systems. The following manuals
  292.  contain information related to the content of this manual and of interest to
  293.  programmers of 80387 systems:
  294.  
  295.    ■  Introduction to the 80386, order number 231252
  296.    ■  80386 Data Sheet, order number 231630
  297.    ■  80386 Hardware Reference Manual, order number 231732
  298.    ■  80386 Programmer's Reference Manual, order number 230985
  299.    ■  80387 Data Sheet, order number 231920
  300.  
  301.  
  302.  Notational Conventions
  303.  
  304.  This manual uses special notation to represent sub and superscript
  305.  characters. Subscript characters are surrounded by {curly brackets}, for
  306.  example 10{2} = 10 base 2. Superscript characters are preceeded by a caret
  307.  and enclosed within (parentheses), for example 10^(3) = 10 to the third
  308.  power.
  309.  
  310.  
  311.  Table of Contents
  312.  
  313.  ────────────────────────────────────────────────────────────────────────────
  314.  
  315.  Chapter 1  Introduction to the 80387 Numerics Processor Extension
  316.  
  317.  1.1  History
  318.  1.2  Performance
  319.  1.3  Ease of Use
  320.  1.4  Applications
  321.  1.5  Upgradability
  322.  1.6  Programming Interface
  323.  
  324.  Chapter 2  80387 Numerics Processor Architecture
  325.  
  326.  2.1  80387 Registers
  327.        2.1.1  The NPX Register Stack
  328.        2.1.2  The NPX Status Word
  329.        2.1.3  Control Word
  330.        2.1.4  The NPX Tag Word
  331.        2.1.5  The NPX Instruction and Data Pointers
  332.  
  333.  2.2  Computation Fundamentals
  334.        2.2.1  Number System
  335.        2.2.2  Data Types and Formats
  336.                2.2.2.1  Binary Integers
  337.                2.2.2.2  Decimal Integers
  338.                2.2.2.3  Real Numbers
  339.  
  340.        2.2.3  Rounding Control
  341.        2.2.4  Precision Control
  342.  
  343.  Chapter 3  Special Computational Situations
  344.  
  345.  3.1  Special Numeric Values
  346.        3.1.1  Denormal Real Numbers
  347.                3.1.1.1  Denormals and Gradual Underflow
  348.  
  349.        3.1.2  Zeros
  350.        3.1.3  Infinity
  351.        3.1.4  NaN (Not-a-Number)
  352.                3.1.4.1  Signaling NaNs
  353.                3.1.4.2  Quiet NaNs
  354.  
  355.        3.1.5  Indefinite
  356.        3.1.6  Encoding of Data Types
  357.        3.1.7  Unsupported Formats
  358.  
  359.  3.2  Numeric Exceptions
  360.        3.2.1  Handling Numeric Exceptions
  361.                3.2.1.1  Automatic Exception Handling
  362.                3.2.1.2  Software Exception Handling
  363.  
  364.        3.2.2  Invalid Operation
  365.                3.2.2.1  Stack Exception
  366.                3.2.2.2  Invalid Arithmetic Operation
  367.  
  368.        3.2.3  Division by Zero
  369.        3.2.4  Denormal Operand
  370.        3.2.5  Numeric Overflow and Underflow
  371.                3.2.5.1  Overflow
  372.                3.2.5.2  Underflow
  373.  
  374.        3.2.6  Inexact (Precision)
  375.        3.2.7  Exception Priority
  376.        3.2.8  Standard Underflow/Overflow Exception Handler
  377.  
  378.  Chapter 4  The 80387 Instruction Set
  379.  
  380.  4.1  Compatibility with the 80287 and 8087
  381.  4.2  Numeric Operands
  382.  4.3  Data Transfer Instructions
  383.        4.3.1  FLD source
  384.        4.3.2  FST destination
  385.        4.3.3  FSTP destination
  386.        4.3.4  FXCH//destination
  387.        4.3.5  FILD source
  388.        4.3.6  FIST destination
  389.        4.3.7  FISTP destination
  390.        4.3.8  FBLD source
  391.        4.3.9  FBSTP destination
  392.  
  393.  4.4  Nontranscendental Instructions
  394.        4.4.1  Addition
  395.        4.4.2  Normal Subtraction
  396.        4.4.3  Reversed Subtraction
  397.        4.4.4  Multiplication
  398.        4.4.5  Normal Division
  399.        4.4.6  Reversed Division
  400.        4.4.7  FSQRT
  401.        4.4.8  FSCALE
  402.        4.4.9  FPREM---Partial Remainder (80287/8087-Compatible)
  403.        4.4.10 FPREM1---Partial Remainder (IEEE Std. 754-Compatible)
  404.        4.4.11 FRNDINT
  405.        4.4.12 FXTRACT
  406.        4.4.13 FABS
  407.        4.4.14 FCHS
  408.  
  409.  4.5  Comparison Instructions
  410.        4.5.1  FCOM//source
  411.        4.5.2  FCOMP//source
  412.        4.5.3  FCOMPP
  413.        4.5.4  FICOM source
  414.        4.5.5  FICOMP source
  415.        4.5.6  FTST
  416.        4.5.7  FUCOM//source
  417.        4.5.8  FUCOMP//source
  418.        4.5.9  FUCOMPP
  419.        4.5.10 FXAM
  420.  
  421.  4.6  Transcendental Instructions
  422.        4.6.1  FCOS
  423.        4.6.2  FSIN
  424.        4.6.3  FSINCOS
  425.        4.6.4  FPTAN
  426.        4.6.5  FPATAN
  427.        4.6.6  F2XM1
  428.        4.6.7  FYL2X
  429.        4.6.8  FYL2XP1
  430.  
  431.  4.7  Constant Instructions
  432.        4.7.1  FLDZ
  433.        4.7.2  FLD1
  434.        4.7.3  FLDPI
  435.        4.7.4  FLDL2T
  436.        4.7.5  FLDL2E
  437.        4.7.6  FLDLG2
  438.        4.7.7  FLDLN2
  439.  
  440.  4.8  Processor Control Instructions
  441.        4.8.1  FINIT/FNINIT
  442.        4.8.2  FLDCW source
  443.        4.8.3  FSTCW/FNSTCW destination
  444.        4.8.4  FSTSW/FNSTSW destination
  445.        4.8.5  FSTSW AX/FNSTSW AX
  446.        4.8.6  FCLEX/FNCLEX
  447.        4.8.7  FSAVE/FNSAVE destination
  448.        4.8.8  FRSTOR source
  449.        4.8.9  FSTENV/FNSTENV destination
  450.        4.8.10 FLDENV source
  451.        4.8.11 FINCSTP
  452.        4.8.12 FDECSTP
  453.        4.8.13 FFREE destination
  454.        4.8.14 FNOP
  455.        4.8.15 FWAIT (CPU Instruction)
  456.  
  457.  Chapter 5  Programming Numeric Applications
  458.  
  459.  5.1  Programming Facilities
  460.        5.1.1  High-Level Languages
  461.        5.1.2  C Programs
  462.        5.1.3  PL/M-386
  463.        5.1.4  ASM386
  464.                5.1.4.1  Defining Data
  465.                5.1.4.2  Records and Structures
  466.                5.1.4.3  Addressing Methods
  467.  
  468.        5.1.5  Comparative Programming Example
  469.        5.1.6  80387 Emulation
  470.  
  471.  5.2  Concurrent Processing with the 80387
  472.        5.2.1  Managing Concurrency
  473.                5.2.1.1  Incorrect Exception Synchronization
  474.                5.2.1.2  Proper Exception Synchronization
  475.  
  476.  Chapter 6  System-Level Numeric Programming
  477.  
  478.  6.1  80386/80387 Architecture
  479.        6.1.1  Instruction and Operand Transfer
  480.        6.1.2  Independent of CPU Addressing Modes
  481.        6.1.3  Dedicated I/O Locations
  482.  
  483.  6.2  Processor Initialization and Control
  484.        6.2.1  System Initialization
  485.        6.2.2  Hardware Recognition of the NPX
  486.        6.2.3  Software Recognition of the NPX
  487.        6.2.4  Configuring the Numerics Environment
  488.        6.2.5  Initializing the 80387
  489.        6.2.6  80387 Emulation
  490.        6.2.7  Handling Numerics Exceptions
  491.        6.2.8  Simultaneous Exception Response
  492.        6.2.9  Exception Recovery Examples
  493.  
  494.  Chapter 7  Numeric Programming Examples
  495.  
  496.  7.1  Conditional Branching Example
  497.  7.2  Exception Handling Examples
  498.  7.3  Floating-Point to ASCII Conversion Examples
  499.        7.3.1  Function Partitioning
  500.        7.3.2  Exception Considerations
  501.        7.3.3  Special Instructions
  502.        7.3.4  Description of Operation
  503.        7.3.5  Scaling the Value
  504.                7.3.5.1  Inaccuracy in Scaling
  505.                7.3.5.2  Avoiding Underflow and Overflow
  506.                7.3.5.3  Final Adjustments
  507.  
  508.        7.3.6  Output Format
  509.  
  510.  7.4  Trigonometric Calculation Examples (Not Tested)
  511.  
  512.  Appendix A  Machine Instruction Encoding and Decoding
  513.  
  514.  Appendix B  Exception Summary
  515.  
  516.  Appendix C  Compatibility Between the 80387 and the 80287/8087
  517.  
  518.  Appendix D  Compatibility Between the 80387 and the 8087
  519.  
  520.  Appendix E  80387 80-Bit CHMOS III Numeric Processor Extension
  521.  
  522.  Appendix F  PC/AT-Compatible 80387 Connection
  523.  
  524.  Glossary of 80387 and Floating-Point Terminology
  525.  
  526.  
  527.  Figures
  528.  
  529.  1-1     Evolution and Performance of Numeric Processors
  530.  
  531.  2-1     80387 Register Set
  532.  2-2     80387 Status Word
  533.  2-3     80387 Control Word Format
  534.  2-4     80387 Tag Word Format
  535.  2-5     Protected Mode 80387 Instruction and Data Pointer Image in Memory,
  536.              32-Bit Format
  537.  2-6     Real Mode 80387 Instruction and Data Pointer Image in Memory,
  538.              32-Bit Format
  539.  2-7     Protected Mode 80387 Instruction and Data Pointer Image in Memory,
  540.              16-Bit Format
  541.  2-8     Real Mode 80387 Instruction and Data Pointer Image in Memory,
  542.              16-Bit Format
  543.  2-9     80387 Double-Precision Number System
  544.  2-10    80387 Data Formats
  545.  
  546.  3-1     Floating-Point System with Denormals
  547.  3-2     Floating-Point System without Denormals
  548.  3-3     Arithmetic Example Using Infinity
  549.  
  550.  4-1     FSAVE/FRSTOR Memory Layout (32-Bit)
  551.  4-2     FSAVE/FRSTOR Memory Layout (16-Bit)
  552.  4-3     Protected Mode 80387 Environment, 32-Bit Format
  553.  4-4     Real Mode 80387 Environment, 32-Bit Format
  554.  4-5     Protected Mode 80387 Environment, 16-Bit Format
  555.  4-6     Real Mode 80387 Environment, 16-Bit Format
  556.  
  557.  5-1     Sample C-386 Program
  558.  5-2     Sample 80387 Constants
  559.  5-3     Status Word Record Definition
  560.  5-4     Structure Definition
  561.  5-5     Sample PL/M-386 Program
  562.  5-6     Sample ASM386 Program
  563.  5-7     Instructions and Register Stack
  564.  5-8     Exception Synchronization Examples
  565.  
  566.  6-1     Software Routine to Recognize the 80287
  567.  
  568.  7-1     Conditional Branching for Compares
  569.  7-2     Conditional Branching for FXAM
  570.  7-3     Full-State Exception Handler
  571.  7-4     Reduced-Latency Exception Handler
  572.  7-5     Reentrant Exception Handler
  573.  7-6     Floating-Point to ASCII Conversion Routine
  574.  7-7     Relationships between Adjacent Joints
  575.  7-8     Robot Arm Kinematics Example
  576.  
  577.  
  578.  Tables
  579.  
  580.  1-1     Numeric Processing Speed Comparisons
  581.  1-2     Numeric Data Types
  582.  1-3     Principal NPX Instructions
  583.  
  584.  2-1     Condition Code Interpretation
  585.  2-2     Correspondence between 80387 and 80386 Flag Bits
  586.  2-3     Summary of Format Parameters
  587.  2-4     Real Number Notation
  588.  2-5     Rounding Modes
  589.  
  590.  3-1     Arithmetic and Nonarithmetic Instructions
  591.  3-2     Denormalization Process
  592.  3-3     Zero Operands and Results
  593.  3-4     Infinity Operands and Results
  594.  3-5     Rules for Generating QNaNs
  595.  3-6     Binary Integer Encodings
  596.  3-7     Packed Decimal Encodings
  597.  3-8     Single and Double Real Encodings
  598.  3-9     Extended Real Encodings
  599.  3-10    Masked Responses to Invalid Operations
  600.  3-11    Masked Overflow Results
  601.  
  602.  4-1     Data Transfer Instructions
  603.  4-2     Nontranscendental Instructions
  604.  4-3     Basic Nontranscendental Instructions and Operands
  605.  4-4     Condition Code Interpretation after FPREM and FPREM
  606.              Instructions
  607.  4-5     Comparison Instructions
  608.  4-6     Condition Code Resulting from Comparisons
  609.  4-7     Condition Code Resulting from FTST
  610.  4-8     Condition Code Defining Operand Class
  611.  4-9     Transcendental Instructions
  612.  4-10    Results of FPATAN
  613.  4-11    Constant Instructions
  614.  4-12    Processor Control Instructions
  615.  
  616.  5-1     PL/M-386 Built-In Procedures
  617.  5-2     ASM386 Storage Allocation Directives
  618.  5-3     Addressing Method Examples
  619.  
  620.  6-1     NPX Processor State Following Initialization
  621.  
  622.  
  623.  Chapter 1  Introduction to the 80387 Numerics Processor Extension
  624.  
  625.  ────────────────────────────────────────────────────────────────────────────
  626.  
  627.  The 80387 NPX is a high-performance numerics processing element that
  628.  extends the 80386 architecture by adding significant numeric capabilities
  629.  and direct support for floating-point, extended-integer, and BCD data types.
  630.  The 80386 CPU with 80387 NPX easily supports powerful and accurate numeric
  631.  applications through its implementation of the IEEE Standard 754 for Binary
  632.  Floating-Point Arithmetic. The 80387 provides floating-point performance
  633.  comparable to that of large minicomputers while offering compatibility with
  634.  object code for 8087 and 80287.
  635.  
  636.  
  637.  1.1  History
  638.  
  639.  The 80387 Numeric Processor Extension (NPX) is compatible with its
  640.  predecessors, the earlier Intel 8087 NPX and 80287 NPX. As the 80386 runs
  641.  8086 programs, so programs designed to use the 8087 and 80287 should run
  642.  unchanged on the 80387.
  643.  
  644.  The 8087 NPX was designed for use in 8086-family systems. The 8086 was the
  645.  first microprocessor family to partition the processing unit to permit
  646.  high-performance numeric capabilities. The 8087 NPX for this processor
  647.  family implemented a complete numeric processing environment in compliance
  648.  with an early proposal for the IEEE 754 Floating-Point Standard.
  649.  
  650.  With the 80287 Numeric Processor Extension, high-speed numeric computations
  651.  were extended to 80286 high-performance multitasking and multiuser systems.
  652.  Multiple tasks using the numeric processor extension were afforded the full
  653.  protection of the 80286 memory management and protection features.
  654.  
  655.  The 80387 Numeric Processor Extension is Intel's third generation numerics
  656.  processor. The 80387 implements the final IEEE standard, adds new
  657.  trigonometric instructions, and uses a new design and CHMOS-III process to
  658.  allow higher clock rates and require fewer clocks per instruction. Together,
  659.  the 80387 with additional instructions and the improved standard bring even
  660.  more convenience and reliability to numerics programming and make this
  661.  convenience and reliability available to applications that need the
  662.  high-speed and large memory capacity of the 32-bit environment of the 80386
  663.  CPU.
  664.  
  665.  Figure 1-1 illustrates the relative performance of 5-MHz 8086/8087,
  666.  8-MHz 80286/80287, and 20-MHz 80386/80387 systems in executing
  667.  numerics-oriented applications.
  668.  
  669.  
  670.  Figure 1-1.  Evolution and Performance of Numeric Processors
  671.  
  672.                    16│                       80386/80387 (20 MHz)
  673.                    15│
  674.                    14│
  675.                    13│
  676.                    12│
  677.                    11│
  678.       RELATIVE     10│
  679.       PERFORMANCE   9│
  680.                     8│
  681.                     7│
  682.                     6│
  683.                     5│
  684.                     4│
  685.                     3│     80286/80287 (8 MHz)
  686.                     2│
  687.                     1│  8086/8087 (5 MHz)
  688.                      └─────────────────────────────────────
  689.                           1980        1983        1987
  690.  
  691.                                   YEAR INTRODUCED
  692.  
  693.  
  694.  1.2  Performance
  695.  
  696.  Table 1-1 compares the execution times of several 80387 instructions with
  697.  the equivalent operations executed on an 8-MHz 80287. As indicated in the
  698.  table, the 16-MHz 80387 NPX provides about 5 to 6 times the performance of
  699.  an 8-MHz 80287 NPX. A 16-MHz 80387 multiplies 32-bit and 64-bit
  700.  floating-point numbers in about 1.9 and 2.8 microseconds, respectively. Of
  701.  course, the actual performance of the NPX in a given system depends on the
  702.  characteristics of the individual application.
  703.  
  704.  Although the performance figures shown in Table 1-1 refer to operations on
  705.  real (floating-point) numbers, the 80387 also manipulates fixed-point
  706.  binary and decimal integers of up to 64 bits or 18 digits, respectively. The
  707.  80387 can improve the speed of multiple-precision software algorithms for
  708.  integer operations by 10 to 100 times.
  709.  
  710.  Because the 80387 NPX is an extension of the 80386 CPU, no software
  711.  overhead is incurred in setting up the NPX for computation. The 80387 and
  712.  80386 processors coordinate their activities in a manner transparent to
  713.  software. Moreover, built-in coordination facilities allow the 80386 CPU to
  714.  proceed with other instructions while the 80387 NPX is simultaneously
  715.  executing numeric instructions. Programs can exploit this concurrency of
  716.  execution to further increase system performance and throughput.
  717.  
  718.  
  719.  Table 1-1.  Numeric Processing Speed Comparisons
  720.  
  721.                                             Approximate Performance Ratios:
  722.         Floating-Point Instruction                16 MHz 80386/80387 ÷
  723.   ┌───────────────────┴─────────────────┐         8 MHz 80286/80287
  724.  
  725.  FADD      ST, ST(i)                Addition             6.2
  726.  FDIV      dword_var                Division             4.7
  727.  FYL2X     stack (0), (1) assumed   Logarithm            6.0
  728.  FPATAX    stack (0) assumed        Arctangent           2.6
  729.  F2XM1     stack (0) assumed        Exponentiation       2.7
  730.  
  731.  
  732.  1.3  East of Use
  733.  
  734.  The 80387 NPX offers more than raw execution speed for
  735.  computation-intensive tasks. The 80387 brings the functionality and power of
  736.  accurate numeric computation into the hands of the general user. These
  737.  features are available in most high-level languages available for the 80386.
  738.  
  739.  Like the 8087 and 80287 that preceded it, the 80387 is explicitly designed
  740.  to deliver stable, accurate results when programmed using straightforward
  741.  "pencil and paper" algorithms. The IEEE standard 754 specifically addresses
  742.  this issue, recognizing the fundamental importance of making numeric
  743.  computations both easy and safe to use.
  744.  
  745.  For example, most computers can overflow when two single-precision
  746.  floating-point numbers are multiplied together and then divided by a third,
  747.  even if the final result is a perfectly valid 32-bit number. The 80387
  748.  delivers the correctly rounded result. Other typical examples of undesirable
  749.  machine behavior in straightforward calculations occur when computing
  750.  financial rate of return, which involves the expression (1 + i)^(n) or when
  751.  solving for roots of a quadratic equation:
  752.  
  753.         -b ± √(b² - 4ac)
  754.         ────────────────
  755.                2a
  756.  
  757.  If a does not equal 0, the formula is numerically unstable when the roots
  758.  are nearly coincident or when their magnitudes are wildly different. The
  759.  formula is also vulnerable to spurious over/underflows when the coefficients
  760.  a, b, and c are all very big or all very tiny. When single-precision
  761.  (4-byte) floating-point coefficients are given as data and the formula is
  762.  evaluated in the 80387's normal way, keeping all intermediate results in
  763.  its stack, the 80387 produces impeccable single-precision roots. This
  764.  happens because, by default and with no effort on the programmer's part, the
  765.  80387 evaluates all those subexpressions with so much extra precision and
  766.  range as to overwhelm any threat to numerical integrity.
  767.  
  768.  If double-precision data and results were at issue, a better formula would
  769.  have to be used, and once again the 80387's default evaluation of that
  770.  formula would provide substantially enhanced numerical integrity over mere
  771.  double-precision evaluation.
  772.  
  773.  On most machines, straightforward algorithms will not deliver consistently
  774.  correct results (and will not indicate when they are incorrect). To obtain
  775.  correct results on traditional machines under all conditions usually
  776.  requires sophisticated numerical techniques that are foreign to most
  777.  programmers. General application programmers using straightforward
  778.  algorithms will produce much more reliable programs using the 80387. This
  779.  simple fact greatly reduces the software investment required to develop
  780.  safe, accurate computation-based products.
  781.  
  782.  Beyond traditional numerics support for scientific applications, the 80387
  783.  has built-in facilities for commercial computing. It can process decimal
  784.  numbers of up to 18 digits without round-off errors, performing exact
  785.  arithmetic on integers as large as 2^(64) or 10^(18). Exact arithmetic is
  786.  vital in accounting applications where rounding errors may introduce
  787.  monetary losses that cannot be reconciled.
  788.  
  789.  The NPX contains a number of optional facilities that can be invoked by
  790.  sophisticated users. These advanced features include directed rounding,
  791.  gradual underflow, and programmed exception-handling facilities.
  792.  
  793.  These automatic exception-handling facilities permit a high degree of
  794.  flexibility in numeric processing software, without burdening the
  795.  programmer. While performing numeric calculations, the NPX automatically
  796.  detects exception conditions that can potentially damage a calculation (for
  797.  example, X ÷ 0 or √X when X < 0). By default, on-chip exception logic
  798.  handles these exceptions so that a reasonable result is produced and
  799.  execution may proceed without program interruption. Alternatively, the NPX
  800.  can signal the CPU, invoking a software exception handler to provide special
  801.  results whenever various types of exceptions are detected.
  802.  
  803.  
  804.  1.4  Applications
  805.  
  806.  The 80386's versatility and performance make it appropriate to a broad
  807.  array of numeric applications. In general, applications that exhibit any of
  808.  the following characteristics can benefit by implementing numeric processing
  809.  on the 80387:
  810.  
  811.    ■  Numeric data vary over a wide range of values, or include nonintegral
  812.       values.
  813.  
  814.    ■  Algorithms produce very large or very small intermediate results.
  815.  
  816.    ■  Computations must be very precise; i.e., a large number of significant
  817.       digits must be maintained.
  818.  
  819.    ■  Performance requirements exceed the capacity of traditional
  820.       microprocessors.
  821.  
  822.    ■  Consistently safe, reliable results must be delivered using a
  823.       programming staff that is not expert in numerical techniques.
  824.  
  825.  Note also that the 80387 can reduce software development costs and improve
  826.  the performance of systems that use not only real numbers, but operate on
  827.  multiprecision binary or decimal integer values as well.
  828.  
  829.  A few examples, which show how the 80387 might be used in specific numerics
  830.  applications, are described below. In many cases, these types of systems
  831.  have been implemented in the past with minicomputers or small mainframe
  832.  computers. The advent of the 80387 brings the size and cost savings of
  833.  microprocessor technology to these applications for the first time.
  834.  
  835.    ■  Business data processing──The NPX's ability to accept decimal operands
  836.       and produce exact decimal results of up to 18 digits greatly simplifies
  837.       accounting programming. Financial calculations that use power functions
  838.       can take advantage of the 80387's exponentiation and logarithmic
  839.       instructions. Many business software packages can benefit from the
  840.       speed and accuracy of the 80387; for example, Lotus* 1-2-3*,
  841.       Multiplan*, SuperCalc*, and Framework*.
  842.  
  843.    ■  Simulation──The large (32-bit) memory space of the 80386 coupled with
  844.       the raw speed of the 80386 and 80387 processors make 80386/80387
  845.       microsystems suitable for attacking large simulation problems, which
  846.       heretofore could only be executed on expensive mini and mainframe
  847.       computers. For example, complex electronic circuit simulations using
  848.       SPICE can now be performed on a microcomputer, the 80386/80387.
  849.       Simulation of mechanical systems using finite element analysis can
  850.       employ more elements, resulting in more detailed analysis or simulation
  851.       of larger systems.
  852.  
  853.    ■  Graphics transformations──The 80387 can be used in graphics terminals
  854.       to locally perform many functions that normally demand the attention of
  855.       a main computer; these include rotation, scaling, and interpolation. By
  856.       also using an 82786 Graphics Display Controller to perform high-speed
  857.       drawing and window management, very powerful and highly self-sufficient
  858.       terminals can be built from a relatively small number of 80386 family
  859.       parts.
  860.  
  861.    ■  Process control──The 80387 solves dynamic range problems
  862.       automatically, and its extended precision allows control functions to
  863.       be fine-tuned for more accurate and efficient performance. Control
  864.       algorithms implemented with the NPX also contribute to improved
  865.       reliability and safety, while the 80387's speed can be exploited in
  866.       real-time operations.
  867.  
  868.    ■  Computer numerical control (CNC)──The 80387 can move and position
  869.       machine tool heads with accuracy in real-time. Axis positioning also
  870.       benefits from the hardware trigonometric support provided by the 80387.
  871.  
  872.    ■  Robotics──Coupling small size and modest power requirements with
  873.       powerful computational abilities, the 80387 is ideal for on-board
  874.       six-axis positioning.
  875.  
  876.    ■  Navigation──Very small, lightweight, and accurate inertial guidance
  877.       systems can be implemented with the 80387. Its built-in trigonometric
  878.       functions can speed and simplify the calculation of position from
  879.       bearing data.
  880.  
  881.    ■  Data acquisition──The 80387 can be used to scan, scale, and reduce
  882.       large quantities of data as it is collected, thereby lowering storage
  883.       requirements and time required to process the data for analysis.
  884.  
  885.  The preceding examples are oriented toward traditional numerics
  886.  applications. There are, in addition, many other types of systems that do
  887.  not appear to the end user as computational, but can employ the 80387 to
  888.  advantage. Indeed, the 80387 presents the imaginative system designer with
  889.  an opportunity similar to that created by the introduction of the
  890.  microprocessor itself. Many applications can be viewed as numerically-based
  891.  if sufficient computational power is available to support this view (e.g.,
  892.  character generation for a laser printer). This is analogous to the
  893.  thousands of successful products that have been built around "buried"
  894.  microprocessors, even though the products themselves bear little
  895.  resemblance to computers.
  896.  
  897.  
  898.  1.5  Upgradability
  899.  
  900.  The architecture of the 80386 CPU is specifically adapted to allow easy
  901.  upgradability to use an 80387, simply by plugging in the 80387 NPX. For this
  902.  reason, designers of 80386 systems may wish to incorporate the 80387 NPX
  903.  into their designs in order to offer two levels of price and performance at
  904.  little additional cost.
  905.  
  906.  Two features of the 80386 CPU make the design and support of upgradable
  907.  80386 systems particularly simple:
  908.  
  909.    ■  The 80386 can be programmed to recognize the presence of an 80387 NPX;
  910.       that is, software can recognize whether it is running on an 80386 with
  911.       or without an 80387 NPX.
  912.  
  913.    ■  After determining whether the 80387 NPX is available, the 80386 CPU
  914.       can be instructed to let the NPX execute all numeric instructions. If
  915.       an 80387 NPX is not available, the 80386 CPU can emulate all 80387
  916.       numeric instructions in software. This emulation is completely
  917.       transparent to the application software──the same object code may be
  918.       used by 80386 systems both with and without an 80387 NPX. No relinking
  919.       or recompiling of application software is necessary; the same code will
  920.       simply execute faster with the 80387 NPX than without.
  921.  
  922.  To facilitate this design of upgradable 80386 systems, Intel provides a
  923.  software emulator for the 80387 that provides the functional equivalent of
  924.  the 80387 hardware, implemented in software on the 80386. Except for timing,
  925.  the operation of this 80387 emulator (EMUL387) is the same as for the 80387
  926.  NPX hardware. When the emulator is combined as part of the systems software,
  927.  the 80386 system with 80387 emulation and the 80386 with 80387 hardware are
  928.  virtually indistinguishable to an application program. This capability
  929.  makes it easy for software developers to maintain a single set of programs
  930.  for both systems. System manufacturers can offer the NPX as a simple plug-in
  931.  performance option without necessitating any changes in the user's software.
  932.  
  933.  
  934.  1.6  Programming Interface
  935.  
  936.  The 80386/80387 pair is programmed as a single processor; all of the 80387
  937.  registers appear to a programmer as extensions of the basic 80386 register
  938.  set. The 80386 has a class of instructions known as ESCAPE instructions, all
  939.  having a common format. These ESC instructions are numeric instructions for
  940.  the 80387 NPX. These numeric instructions for the 80387 are simply encoded
  941.  into the instruction stream along with 80386 instructions.
  942.  
  943.  All of the CPU memory-addressing modes may be used in programming the NPX,
  944.  allowing convenient access to record structures, numeric arrays, and other
  945.  memory-based data structures. All of the memory management and protection
  946.  features of the CPU (both paging and segmentation) are extended to the NPX
  947.  as well.
  948.  
  949.  Numeric processing in the 80387 centers around the NPX register stack.
  950.  Programmers can treat these eight 80-bit registers either as a fixed
  951.  register set, with instructions operating on explicitly-designated
  952.  registers, or as a classical stack, with instructions operating on the top
  953.  one or two stack elements.
  954.  
  955.  Internally, the 80387 holds all numbers in a uniform 80-bit extended
  956.  format. Operands that may be represented in memory as 16-, 32-, or 64-bit
  957.  integers, 32-, 64-, or 80-bit floating-point numbers, or 18-digit packed BCD
  958.  numbers, are automatically converted into extended format as they are loaded
  959.  into the NPX registers. Computation results are subsequently converted back
  960.  into one of these destination data formats when they are stored into memory
  961.  from the NPX registers.
  962.  
  963.  Table 1-2 lists each of the seven data types supported by the 80387,
  964.  showing the data format for each type. All operands are stored in memory
  965.  with the least significant digits starting at the initial (lowest) memory
  966.  address. Numeric instructions access and store memory operands using only
  967.  this initial address. For maximum system performance, all operands should
  968.  start at memory addresses divisible by four.
  969.  
  970.  Table 1-3 lists the 80387 instructions by class. No special programming
  971.  tools are necessary to use the 80387, because all of the NPX instructions
  972.  and data types are directly supported by the ASM386 Assembler, by high-level
  973.  languages from Intel, and by assemblers and compilers produced by many
  974.  independent software vendors. Software routines for the 80387 may be written
  975.  in ASM386 Assembler or any of the following higher-level languages from
  976.  Intel:
  977.  
  978.        PL/M-386
  979.        C-386
  980.  
  981.  In addition, all of the development tools supporting the 8086/8087 and
  982.  80286/80287 can also be used to develop software for the 80386/80387.
  983.  
  984.  All of these high-level languages provide programmers with access to the
  985.  computational power and speed of the 80387 without requiring an
  986.  understanding of the architecture of the 80386 and 80387 chips. Such
  987.  architectural considerations as concurrency and synchronization are handled
  988.  automatically by these high-level languages. For the ASM386 programmer,
  989.  specific rules for handling these issues are discussed in a later section
  990.  of this manual.
  991.  
  992.  The following operating systems are known or expected to support the
  993.  80387: RMX-286/386, MS-DOS, Xenix-286/386, and Unix-286/386. Advanced
  994.  in-circuit debugging support is provided by ICE-386.
  995.  
  996.  
  997.  Table 1-2.  Numeric Data Types
  998.  
  999.  Data Type       Bits  Significant  Approximate Range (Decimal)
  1000.                        Digits
  1001.                        (Decimal)
  1002.  
  1003.  Word integer    16    4            -32,768 ≤ X ≤ +32,767
  1004.  Short integer   32    9            -2*10^(9) ≤ X ≤ +2*10^(9)
  1005.  Long integer    64    18           -9*10^(18) ≤ X ≤ +9*10^(18)
  1006.  Packed decimal  80    18           -99...99 ≤ X ≤ +99...99 (18 digits)
  1007.  Single real     32    6-7          1.18*10^(-38) ≤ │X│ ≤ 3.40*10^(38)
  1008.  Double real     64    15-16        2.23*10^(-308) ≤ │X│ ≤ 1.80*10^(308)
  1009.  Extended real  80    19           3.30*10^(-4932) ≤ │X│ ≤ 1.21*10^(4932)
  1010.  
  1011.  
  1012.  Table 1-3.  Principal NPX Instructions
  1013.  
  1014.  Class                Instruction Types
  1015.  
  1016.  Data Transfer        Load (all data types), Store (all data types), Exchange
  1017.  
  1018.  Arithmetic           Add, Subtract, Multiply, Divide, Subtract Reversed,
  1019.                       Divide Reversed, Square Root, Scale, Remainder, Integer
  1020.                       Part, Change Sign, Absolute Value, Extract
  1021.  
  1022.  Comparison           Compare, Examine, Test
  1023.  
  1024.  Transcendental       Tangent, Arctangent, Sine, Cosine, Sine and Cosine,
  1025.                       2^(x) - 1, Y * Log{2}(X), Y * Log{2}(X+1)
  1026.  
  1027.  Constants            0, 1, π, Log{10}2, Log{e}2, Log{2}10, Log{2}e
  1028.  
  1029.  Processor Control    Load Control Word, Store Control Word, Store Status
  1030.                       Word, Load Environment, Store Environment, Save,
  1031.                       Restore, Clear Exceptions, Initialize
  1032.  
  1033.  
  1034.  
  1035.  Class                Instruction Types
  1036.  
  1037.  Data Transfer        Load (all data types), Store (all data types), Exchange
  1038.  
  1039.  Arithmetic           Add, Subtract, Multiply, Divide, Subtract Reversed,
  1040.                       Divide Reversed, Square Root, Scale, Remainder, Integer
  1041.                       Part, Change Sign, Absolute Value, Extract
  1042.  
  1043.  Comparison           Compare, Examine, Test
  1044.  
  1045.  Transcendental       Tangent, Arctangent, Sine, Cosine, Sine and Cosine,
  1046.                       2^(x) - 1, Y * Log{2}(X), Y * Log{2}(X+1)
  1047.  
  1048.  Constants            0, 1, π, Log{10}2, Log{e}2, Log{2}10, Log{2}e
  1049.  
  1050.  Processor Control    Load Control Word, Store Control Word, Store Status
  1051.                       Word, Load Environment, Store Environment, Save,
  1052.                       Restore, Clear Exceptions, Initialize
  1053.  
  1054.  
  1055.  Chapter 2  80387 Numerics Processor Architecture
  1056.  
  1057.  ────────────────────────────────────────────────────────────────────────────
  1058.  
  1059.  To the programmer, the 80387 NPX appears as a set of additional registers,
  1060.  data types, and instructions──all of which complement those of the 80386.
  1061.  Refer to Chapter 4 for detailed explanations of the 80387 instruction set.
  1062.  This chapter explains the new registers and data types that the 80387 brings
  1063.  to the architecture of the 80386.
  1064.  
  1065.  
  1066.  2.1  80387 Registers
  1067.  
  1068.  The additional registers consist of
  1069.  
  1070.    ■  Eight individually-addressable 80-bit numeric registers, organized as
  1071.       a register stack
  1072.  
  1073.    ■  Three sixteen-bit registers containing:
  1074.  
  1075.       the NPX status word
  1076.       the NPX control word
  1077.       the tag word
  1078.  
  1079.    ■  Two 48-bit registers containing pointers to the current instruction
  1080.       and operand (these registers are actually located in the 80386)
  1081.  
  1082.  All of the NPX numeric instructions focus on the contents of these NPX
  1083.  registers.
  1084.  
  1085.  
  1086.  2.1.1  The NPX Register Stack
  1087.  
  1088.  The 80387 register stack is shown in Figure 2-1. Each of the eight numeric
  1089.  registers in the 80387's register stack is 80 bits wide and is divided into
  1090.  fields corresponding to the NPX's extended real data type.
  1091.  
  1092.  Numeric instructions address the data registers relative to the register on
  1093.  the top of the stack. At any point in time, this top-of-stack register is
  1094.  indicated by the TOP (stack TOP) field in the NPX status word. Load or push
  1095.  operations decrement TOP by one and load a value into the new top register.
  1096.  A store-and-pop operation stores the value from the current TOP register and
  1097.  then increments TOP by one. Like 80386 stacks in memory, the 80387 register
  1098.  stack grows down toward lower-addressed registers.
  1099.  
  1100.  Many numeric instructions have several addressing modes that permit the
  1101.  programmer to implicitly operate on the top of the stack, or to explicitly
  1102.  operate on specific registers relative to the TOP. The ASM386 Assembler
  1103.  supports these register addressing modes, using the expression ST(0), or
  1104.  simply ST, to represent the current Stack Top and ST(i) to specify the ith
  1105.  register from TOP in the stack (0 ≤ i ≤ 7). For example, if TOP contains
  1106.  011B (register 3 is the top of the stack), the following statement would add
  1107.  the contents of two registers in the stack (registers 3 and 5):
  1108.  
  1109.  FADD   ST, ST(2)
  1110.  
  1111.  The stack organization and top-relative addressing of the numeric registers
  1112.  simplify subroutine programming by allowing routines to pass parameters on
  1113.  the register stack. By using the stack to pass parameters rather than using
  1114.  "dedicated" registers, calling routines gain more flexibility in how they
  1115.  use the stack. As long as the stack is not full, each routine simply loads
  1116.  the parameters onto the stack before calling a particular subroutine to
  1117.  perform a numeric calculation. The subroutine then addresses its parameters
  1118.  as ST, ST(1), etc., even though TOP may, for example, refer to physical
  1119.  register 3 in one invocation and physical register 5 in another.
  1120.  
  1121.  
  1122.  Figure 2-1.  80387 Register Set
  1123.  
  1124.                              80387 DATA REGISTERS                 TAG
  1125.                                                                  FIELD
  1126.               79 78    64 63                                 0    1 0
  1127.            ╔════╤════════╤════════════════════════════════════╗  ╔═══╗
  1128.          R0║SIGN│EXPONENT│             SIGNIFICAND            ║  ║   ║
  1129.          R1╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1130.          R2╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1131.          R3╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1132.          R4╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1133.          R5╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1134.          R6╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1135.          R7╟────┼────────┼────────────────────────────────────╢  ╟───╢
  1136.            ╚════╧════════╧════════════════════════════════════╝  ╚═══╝
  1137.  
  1138.             15                0   47                                0
  1139.            ╔═══════════════════╗ ╔═══════════════════════════════════╗
  1140.            ║ CONTROL REGISTER  ║ ║        INSTRUCTION POINTER        ║
  1141.            ╟───────────────────╢ ╟───────────────────────────────────╢
  1142.            ║  STATUS REGISTER  ║ ║            DATA POINTER           ║
  1143.            ╟───────────────────╢ ╚═══════════════════════════════════╝
  1144.            ║     TAG WORD      ║
  1145.            ╚═══════════════════╝
  1146.  
  1147.  
  1148.  2.1.2  The NPX Status Word
  1149.  
  1150.  The 16-bit status word shown in Figure 2-2 reflects the overall state of
  1151.  the 80387. This status word may be stored into memory using the
  1152.  FSTSW/FNSTSW, FSTENV/FNSTENV, and FSAVE/FNSAVE instructions, and can be
  1153.  transferred into the 80386 AX register with the FSTSW AX/FNSTSW AX
  1154.  instructions, allowing the NPX status to be inspected by the CPU.
  1155.  
  1156.  The B-bit (bit 15) is included for 8087 compatibility only. It reflects the
  1157.  contents of the ES bit (bit 7 of the status word), not the status of the
  1158.  BUSY# output of the 80387.
  1159.  
  1160.  The four NPX condition code bits (C{3}-C{0}) are similar to the flags in a
  1161.  CPU: the 80387 updates these bits to reflect the outcome of arithmetic
  1162.  operations. The effect of these instructions on the condition code bits is
  1163.  summarized in Table 2-1. These condition code bits are used principally for
  1164.  conditional branching. The FSTSW AX instruction stores the NPX status word
  1165.  directly into the CPU AX register, allowing these condition codes to be
  1166.  inspected efficiently by 80386 code. The 80386 SAHF instruction can copy
  1167.  C{3}-C{0} directly to 80386 flag bits to simplify conditional branching.
  1168.  Table 2-2 shows the mapping of these bits to the 80386 flag bits.
  1169.  
  1170.  Bits 12-14 of the status word point to the 80387 register that is the
  1171.  current Top of Stack (TOP). The significance of the stack top has been
  1172.  described in the prior section on the register stack.
  1173.  
  1174.  Figure 2-2 shows the six exception flags in bits 0-5 of the status word.
  1175.  Bit 7 is the exception summary status (ES) bit. ES is set if any unmasked
  1176.  exception bits are set, and is cleared otherwise. If this bit is set, the
  1177.  ERROR# signal is asserted. Bits 0-5 indicate whether the NPX has detected
  1178.  one of six possible exception conditions since these status bits were last
  1179.  cleared or reset. They are "sticky" bits, and can only be cleared by the
  1180.  instructions FINIT, FCLEX, FLDENV, FSAVE, and FRSTOR.
  1181.  
  1182.  Bit 6 is the stack fault (SF) bit. This bit distinguishes invalid
  1183.  operations due to stack overflow or underflow from other kinds of invalid
  1184.  operations. When SF is set, bit 9 (C{1}) distinguishes between stack
  1185.  overflow (C{1} = 1) and underflow (C{1} = 0).
  1186.  
  1187.  
  1188.  Figure 2-2.  80387 Status Word
  1189.  
  1190.           ┌─────────────────────────────────────────────────── 80387 BUSY
  1191.           │       ┌───┬───┬───────────────────────── TOP OF STACK POINTER
  1192.           │   ┌───│───│───│───┬───┬───┬─────────────────── CONDITION CODE
  1193.                                
  1194.          15                               7                            0
  1195.         ╔═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╗
  1196.         ║ B │ C │    TOP    │ C │ C │ C │ E │ S │ P │ U │ O │ Z │ D │ I ║
  1197.         ║   │ 3 │   │   │   │ 2 │ 1 │ 0 │ S │ F │ E │ E │ E │ E │ E │ E ║
  1198.         ╚═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
  1199.                                                                
  1200.         ERROR SUMMARY STATUS ─────────────┘   │   │   │   │   │   │   │
  1201.         STACK FAULT ──────────────────────────┘   │   │   │   │   │   │
  1202.         EXCEPTION FLAGS                           │   │   │   │   │   │
  1203.           PRECISION ──────────────────────────────┘   │   │   │   │   │
  1204.           UNDERFLOW ──────────────────────────────────┘   │   │   │   │
  1205.           OVERFLOW ───────────────────────────────────────┘   │   │   │
  1206.           ZERO DIVIDE ────────────────────────────────────────┘   │   │
  1207.           DENORMALIZED OPERAND ───────────────────────────────────┘   │
  1208.           INVALID OPERATION ──────────────────────────────────────────┘
  1209.  
  1210.  ─────────────────────────────────────────────────────────────────────────────
  1211.  NOTE:
  1212.         ES IS SET IF ANY UNMASKED EXCEPTION BIT IS SET; CLEARED OTHERWISE.
  1213.         SEE TABLE 2-1 FOR INTERPRETATION OF CONDITION CODE.
  1214.         TOP VALUES:
  1215.             000 = REGISTER 0 IS TOP OF STACK
  1216.             001 = REGISTER 1 IS TOP OF STACK
  1217.                            .
  1218.                            .
  1219.                            .
  1220.             111 = REGISTER 7 IS TOP OF STACK
  1221.         FOR DEFINITIONS OF EXCEPTIONS, REFER TO CHAPTER 3.
  1222.  ─────────────────────────────────────────────────────────────────────────────
  1223.  
  1224.  
  1225.  Table 2-1.  Condition Code Interpretation
  1226.  
  1227. ╓┌───────────────────┌──────────────────────────────────┌────────────────────╖
  1228.  Instruction         C0 (S)     C3 (Z)      C1 (A)      C2 (C)
  1229.  
  1230.  FPREM, FPREM1       Three least significant bits       Reduction
  1231.                              of quotient
  1232.  
  1233.                      Q2         Q0          Q1          0=complete
  1234.                                             or O/U#     1=incomplete
  1235.  
  1236.  FCOM, FCOMP,
  1237.  FCOMPP, FTST,       Result of comparison   Zero        Operand is not
  1238.  FUCOM, FUCOMP,                             or O/U#     comparable
  1239.  FUCOMPP, FICOM,
  1240.  FICOMP
  1241.  Instruction         C0 (S)     C3 (Z)      C1 (A)      C2 (C)
  1242. FICOMP
  1243.  
  1244.  FXAM                Operand class          Sign        Operand class
  1245.                                             or O/U#
  1246.  
  1247.  FCHS, FABS,
  1248.  FXCH, FINCTOP,
  1249.  FDECTOP, Constant   UNDEFINED              Zero        UNDEFINED
  1250.  loads, FXTRACT,                            or O/U#
  1251.  FLD, FILD, FBLD,
  1252.  FSTP (ext real)
  1253.  
  1254.  FIST, FBSTP,
  1255.  FRNDINT, FST,
  1256.  FSTP, FADD, FMUL,
  1257.  FDIV, FDIVR, FSUB,  UNDEFINED              Roundup     UNDEFINED
  1258.  FSUBR, FSCALE,                             or O/U#
  1259.  FSQRT, FPATAN,
  1260.  F2XM1, FYL2X,
  1261.  FYL2XP1
  1262.  Instruction         C0 (S)     C3 (Z)      C1 (A)      C2 (C)
  1263. FYL2XP1
  1264.  
  1265.  FPTAN, FSIN,        UNDEFINED              Roundup     Reduction
  1266.  FCOS, FSINCOS                              or O/U#     0=complete
  1267.                                             undefined   1=incomplete
  1268.                                             if C2=1
  1269.  
  1270.  FLDENV, FRSTOR      Each bit loaded
  1271.                      from memory
  1272.  
  1273.  
  1274.  FLDCW, FSTENV,
  1275.  FSTCW, FSTSW,       UNDEFINED
  1276.  FCLEX, FINIT,
  1277.  FSAVE
  1278.  
  1279.  
  1280.  ────────────────────────────────────────────────────────────────────────────
  1281.  NOTES
  1282.    O/U#        When both IE and SF bits of status word are set,
  1283.                indicating a stack exception, this bit distinguishes
  1284.                between stack overflow (C1=1) and underflow (C1=0).
  1285.  
  1286.    Reduction   If FPREM and FPREM1 produces a remainder that is less
  1287.                than the modulus, reduction is complete.  When reduction
  1288.                is incomplete the value at the top of the stack is a
  1289.                partial remainder, which can be used as input to further
  1290.                reduction. For FPTAN, FSIN, FCOS, and FSINCOS, the
  1291.                reduction bit is set if the operand at the top of the
  1292.                stack is too large. In this case the original operand
  1293.                remains at the top of the stack.
  1294.  
  1295.    Roundup     When the PE bit of the status word is set, this bit
  1296.                indicates whether the last rounding in the instruction
  1297.                was upward.
  1298.  
  1299.    UNDEFINED   Do not rely on finding any specific value in these bits.
  1300.  ────────────────────────────────────────────────────────────────────────────
  1301.  
  1302.  
  1303.  Table 2-2.  Correspondence between 80387 and 80386 Flag Bits
  1304.  
  1305.  80387 Flag                    80386 Flag
  1306.  
  1307.  C{0}                          CF
  1308.  C{1}                          (none)
  1309.  C{2}                          PF
  1310.  C{3}                          ZF
  1311.  
  1312.  
  1313.  2.1.3  Control Word
  1314.  
  1315.  The NPX provides the programmer with several processing options, which are
  1316.  selected by loading a word from memory into the control word. Figure 2-3
  1317.  shows the format and encoding of the fields in the control word.
  1318.  
  1319.  The low-order byte of this control word configures the 80387 exception
  1320.  masking. Bits 0-5 of the control word contain individual masks for each of
  1321.  the six exception conditions recognized by the 80387. The high-order byte of
  1322.  the control word configures the 80387 processing options, including
  1323.  
  1324.    ■  Precision control
  1325.    ■  Rounding control
  1326.  
  1327.  The precision-control bits (bits 8-9) can be used to set the 80387 internal
  1328.  operating precision at less than the default precision (64-bit significand).
  1329.  These control bits can be used to provide compatibility with the
  1330.  earlier-generation arithmetic processors having less precision than the
  1331.  80387. The precision-control bits affect the results of only the following
  1332.  five arithmetic instructions: ADD, SUB(R), MUL, DIV(R), and SQRT. No other
  1333.  operations are affected by PC.
  1334.  
  1335.  The rounding-control bits (bits 10-11) provide for the common
  1336.  round-to-nearest mode, as well as directed rounding and true chop. Rounding
  1337.  control affects only the arithmetic instructions (refer to Chapter 3 for
  1338.  lists of arithmetic and nonarithmetic instructions).
  1339.  
  1340.  
  1341.  Figure 2-3.  80387 Control Word Format
  1342.  
  1343.           ┌───┬───┬──────────────────────────────────────────────RESERVED
  1344.           │   │   │   ┌────────────────────────────── (INFINITY CONTROL)
  1345.           │   │   │   │   ┌───┬───────────────────────── ROUNDING CONTROL
  1346.           │   │   │   │   │   │   ┌───┬──────────────── PRECISION CONTROL
  1347.                                
  1348.          15                               7                            0
  1349.         ╔═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╗
  1350.         ║ X   X   X │ X │  RC   │  PC   │ X   X │ P │ U │ O │ Z │ D │ I ║
  1351.         ║   │   │   │   │   │   │   │   │   │   │ M │ M │ M │ M │ M │ M ║
  1352.         ╚═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝
  1353.                                                                
  1354.         RESERVED ─────────────────────────┴───┘   │   │   │   │   │   │
  1355.         EXECEPTION MASKS                          │   │   │   │   │   │
  1356.           PRECISION ──────────────────────────────┘   │   │   │   │   │
  1357.           UNDERFLOW ──────────────────────────────────┘   │   │   │   │
  1358.           OVERFLOW ───────────────────────────────────────┘   │   │   │
  1359.           ZERO DIVIDE ────────────────────────────────────────┘   │   │
  1360.           DENORMALIZED OPERAND ───────────────────────────────────┘   │
  1361.           INVALID OPERATION ──────────────────────────────────────────┘
  1362.  
  1363.  ─────────────────────────────────────────────────────────────────────────────
  1364.  NOTE:
  1365.       PRECISION CONTROL                   ROUNDING CONTROL
  1366.         00--24 BITS (SINGLE PRECISION)      00--ROUND TO NEAREST OR EVEN
  1367.         01--(RESERVED)                      01--ROUND DOWN (TOWARD -∞)
  1368.         10--53 BITS (DOUBLE PRECISION)      10--ROUND UP (TOWARD +∞)
  1369.         11--64 BITS (EXTENDED PRECISION)    11--CHOP (TRUNCATE TOWARDS ZERO)
  1370.  ─────────────────────────────────────────────────────────────────────────────
  1371.  
  1372.  
  1373.  2.1.4  The NPX Tag Word
  1374.  
  1375.  The tag word indicates the contents of each register in the register stack,
  1376.  as shown in Figure 2-4. The tag word is used by the NPX itself to
  1377.  distinguish between empty and nonempty register locations. Programmers of
  1378.  exception handlers may use this tag information to check the contents of a
  1379.  numeric register without performing complex decoding of the actual data in
  1380.  the register. The tag values from the tag word correspond to physical
  1381.  registers 0-7. Programmers must use the current top-of-stack (TOP) pointer
  1382.  stored in the NPX status word to associate these tag values with the
  1383.  relative stack registers ST(0) through ST(7).
  1384.  
  1385.  The exact values of the tags are generated during execution of the FSTENV
  1386.  and FSAVE instructions according to the actual contents of the nonempty
  1387.  stack locations. During execution of other instructions, the 80387 updates
  1388.  the TW only to indicate whether a stack location is empty or nonempty.
  1389.  
  1390.  
  1391.  Figure 2-4.  80387 Tag Word Format
  1392.  
  1393.      15                                                                   0
  1394.    ╔════╤═══╤════╤═══╤════╤═══╤════╤═══╤════╤═══╤════╤═══╤════╤═══╤════╤═══╗
  1395.    ║ TAG (7)│ TAG (6)│ TAG (5)│ TAG (4)│ TAG (3)│ TAG (2)│ TAG (1)│ TAG (0)║
  1396.    ╚════╧═══╧════╧═══╧════╧═══╧════╧═══╧════╧═══╧════╧═══╧════╧═══╧════╧═══╝
  1397.                                TAG VALUES:
  1398.                                00 = VALID
  1399.                                01 = ZERO
  1400.                                10 = INVALID OR INFINITY
  1401.                                11 = EMPTY
  1402.  
  1403.  
  1404.  2.1.5  The NPX Instruction and Data Pointers
  1405.  
  1406.  The instruction and data pointers provide support for programmed
  1407.  exception-handlers. These registers are actually located in the 80386, but
  1408.  appear to be located in the 80387 because they are accessed by the ESC
  1409.  instructions FLDENV, FSTENV, FSAVE, and FRSTOR. Whenever the 80386 decodes
  1410.  an ESC instruction, it saves the instruction address, the operand address
  1411.  (if present), and the instruction opcode.
  1412.  
  1413.  When stored in memory, the instruction and data pointers appear in one of
  1414.  four formats, depending on the operating mode of the 80386 (protected mode
  1415.  or real-address mode) and depending on the operand-size attribute in effect
  1416.  (32-bit operand or 16-bit operand). When the 80386 is in virtual-8086 mode,
  1417.  the real-address mode formats are used.
  1418.  
  1419.  Figures 2-5 through 2-8 show these pointers as they are stored following
  1420.  FSTENV instruction.
  1421.  
  1422.  The FSTENV and FSAVE instructions store this data into memory, allowing
  1423.  exception handlers to determine the precise nature of any numeric exceptions
  1424.  that may be encountered.
  1425.  
  1426.  The instruction address saved in the 80386 (as in the 80287) points to any
  1427.  prefixes that preceded the instruction. This is different from the 8087, for
  1428.  which the instruction address points only to the ESC instruction opcode.
  1429.  
  1430.  Note that the processor control instructions FINIT, FLDCW, FSTCW, FSTSW,
  1431.  FCLEX, FSTENV, FLDENV, FSAVE, FRSTOR, and FWAIT do not affect the data
  1432.  pointer. Note also that, except for the instructions just mentioned, the
  1433.  value of the data pointer is undefined if the prior ESC instruction did not
  1434.  have a memory operand.
  1435.  
  1436.  
  1437.  Figure 2-5.  Protected Mode 80387 Instruction and Data Pointer Image in
  1438.               Memory, 32-Bit Format
  1439.  
  1440.                          32-BIT PROTECTED MODE FORMAT
  1441.  
  1442.   31                23                15                7               0
  1443.  ╔═════════════════╪═════════════════╪═════════════════╪═════════════════╗
  1444.  ║             RESERVED              │            CONTROL WORD           ║0H
  1445.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  1446.  ║             RESERVED              │            STATUS WORD            ║4H
  1447.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  1448.  ║             RESERVED              │              TAG WORD             ║8H
  1449.  ╟─────────────────┼─────────────────┴─────────────────┼─────────────────╢
  1450.  ║                               IP OFFSET                               ║CH
  1451.  ╟───────────┬─────┼─────────────────┬─────────────────┼─────────────────╢
  1452.  ║ 0 0 0 0 0 │     OPCODE 10..0      │            CS SELECTOR            ║10H
  1453.  ╟───────────┴─────┼─────────────────┴─────────────────┼─────────────────╢
  1454.  ║                          DATA OPERAND OFFSET                          ║14H
  1455.  ╟─────────────────┼─────────────────┬─────────────────┼─────────────────╢
  1456.  ║             RESERVED              │         OPERAND SELECTOR          ║18H
  1457.  ╚═════════════════╪═════════════════╪═════════════════╪═════════════════╝
  1458.  
  1459.  
  1460.  Figure 2-6.  Real Mode 80387 Instruction and Data Pointer Image in
  1461.               Memory, 32-Bit Format
  1462.  
  1463.                        32-BIT REAL ADDRESS MODE FORMAT
  1464.  
  1465.   31                23                15                7               0
  1466.  ╔═════════════════╪═════════════════╪═════════════════╪═════════════════╗
  1467.  ║             RESERVED              │            CONTROL WORD           ║0H
  1468.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  1469.  ║             RESERVED              │            STATUS WORD            ║4H
  1470.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  1471.  ║             RESERVED              │              TAG WORD             ║8H
  1472.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  1473.  ║             RESERVED              │     INSTRUCTION POINTER 15..0     ║CH
  1474.  ╟─────────┬───────┼─────────────────┼───────────┬─┬───┼─────────────────╢
  1475.  ║ 0 0 0 0 │      INSTRUCTION POINTER 31..16     │0│     OPCODE 10..0    ║10H
  1476.  ╟─────────┴───────┼─────────────────┼───────────┴─┴───┼─────────────────╢
  1477.  ║             RESERVED              │         OPERAND POINTER           ║14H
  1478.  ╟─────────┬───────┼─────────────────┼───────────┬─────┼─────────────────╢
  1479.  ║ 0 0 0 0 │        OPERAND POINTER 31..16       │0 0 0 0 0 0 0 0 0 0 0 0║18H
  1480.  ╚═════════╧═══════╪═════════════════╪═══════════╧═════╪═════════════════╝
  1481.  
  1482.  
  1483.  Figure 2-7.  Protected Mode 80387 Instruction and Data Pointer Image in
  1484.               Memory, 16-Bit Format
  1485.  
  1486.                          16-BIT PROTECTED MODE FORMAT
  1487.  
  1488.                       15                7              0
  1489.                      ╔═════════════════╪════════════════╗
  1490.                      ║           CONTROL WORD           ║ 0H
  1491.                      ╟─────────────────┼────────────────╢
  1492.                      ║            STATUS WORD           ║ 2H
  1493.                      ╟─────────────────┼────────────────╢
  1494.                      ║             TAG WORD             ║ 4H
  1495.                      ╟─────────────────┼────────────────╢
  1496.                      ║             IP OFFSET            ║ 6H
  1497.                      ╟─────────────────┼────────────────╢
  1498.                      ║            CB SELECTOR           ║ 8H
  1499.                      ╟─────────────────┼────────────────╢
  1500.                      ║          OPERAND OFFSET          ║ AH
  1501.                      ╟─────────────────┼────────────────╢
  1502.                      ║         OPERAND SELECTOR         ║ CH
  1503.                      ╚═════════════════╪════════════════╝
  1504.  
  1505.  
  1506.  Figure 2-8.  Real Mode 80387 Instruction and Data Pointer Image in
  1507.               Memory, 16-Bit Format
  1508.  
  1509.                            16-BIT REAL-ADDRESS MODE
  1510.                          AND VIRTUAL-8086 MODE FORMAT
  1511.  
  1512.                       15                7              0
  1513.                      ╔════════════════╪════════════════╗
  1514.                      ║          CONTROL WORD           ║ 0H
  1515.                      ╟────────────────┼────────────────╢
  1516.                      ║           STATUS WORD           ║ 2H
  1517.                      ╟────────────────┼────────────────╢
  1518.                      ║            TAG WORD             ║ 4H
  1519.                      ╟────────────────┼────────────────╢
  1520.                      ║    INSTRUCTION POINTER 15..0    ║ 6H
  1521.                      ╟─────────┬─┬────┼────────────────╢
  1522.                      ║IP 19..16│0│      OPCODE 10..0   ║ 8H
  1523.                      ╟─────────┴─┴────┼────────────────╢
  1524.                      ║      OPERAND POINTER 15..0      ║ AH
  1525.                      ╟─────────┬─┬────┼────────────────╢
  1526.                      ║OP 19..16│0│0 0 0 0 0 0 0 0 0 0 0║ CH
  1527.                      ╚═════════╧═╧════╪════════════════╝
  1528.  
  1529.  
  1530.  2.2  Computation Fundamentals
  1531.  
  1532.  This section covers 80387 programming concepts that are common to all
  1533.  applications. It describes the 80387's internal number system and the
  1534.  various types of numbers that can be employed in NPX programs. The most
  1535.  commonly used options for rounding and precision (selected by fields in the
  1536.  control word) are described, with exhaustive coverage of less frequently
  1537.  used facilities deferred to later sections. Exception conditions that may
  1538.  arise during execution of NPX instructions are also described along with the
  1539.  options that are available for responding to these exceptions.
  1540.  
  1541.  
  1542.  2.2.1  Number System
  1543.  
  1544.  The system of real numbers that people use for pencil and paper
  1545.  calculations is conceptually infinite and continuous. There is no upper or
  1546.  lower limit to the magnitude of the numbers one can employ in a calculation,
  1547.  or to the precision (number of significant digits) that the numbers can
  1548.  represent. When considering any real number, there are always arbitrarily
  1549.  many numbers both larger and smaller. There are also arbitrarily many
  1550.  numbers between (i.e., with more significant digits than) any two real
  1551.  numbers. For example, between 2.5 and 2.6 are 2.51, 2.5897, 2.500001, etc.
  1552.  
  1553.  While ideally it would be desirable for a computer to be able to operate on
  1554.  the entire real number system, in practice this is not possible. Computers,
  1555.  no matter how large, ultimately have fixed-size registers and memories that
  1556.  limit the system of numbers that can be accommodated. These limitations
  1557.  determine both the range and the precision of numbers. The result is a set
  1558.  of numbers that is finite and discrete, rather than infinite and
  1559.  continuous. This sequence is a subset of the real numbers that is designed
  1560.  to form a useful approximation of the real number system.
  1561.  
  1562.  Figure 2-9 superimposes the basic 80387 real number system on a real number
  1563.  line (decimal numbers are shown for clarity, although the 80387 actually
  1564.  represents numbers in binary). The dots indicate the subset of real numbers
  1565.  the 80387 can represent as data and final results of calculations. The
  1566.  80387's range of double-precision, normalized numbers is approximately
  1567.  ±2.23 * 10^(-308) to ±1.80 * 10^(308). Applications that are required to
  1568.  deal with data and final results outside this range are rare. For reference,
  1569.  the range of the IBM System 370* is about ±0.54 * 10^(-78) to
  1570.  ±0.72 * 10^(76).
  1571.  
  1572.  The finite spacing in Figure 2-9 illustrates that the NPX can represent a
  1573.  great many, but not all, of the real numbers in its range. There is always a
  1574.  gap between two adjacent 80387 numbers, and it is possible for the result of
  1575.  a calculation to fall in this space. When this occurs, the NPX rounds the
  1576.  true result to a number that it can represent. Thus, a real number that
  1577.  requires more digits than the 80387 can accommodate (e.g., a 20-digit
  1578.  number) is represented with some loss of accuracy. Notice also that the
  1579.  80387's representable numbers are not distributed evenly along the real
  1580.  number line. In fact, an equal number of representable numbers exists
  1581.  between successive powers of 2 (i.e., as many representable numbers exist
  1582.  between 2 and 4 as between 65,536 and 131,072). Therefore, the gaps between
  1583.  representable numbers are larger as the numbers increase in magnitude. All
  1584.  integers in the range ±2^(64) (approximately ±10^(18)), however, are exactly
  1585.  representable.
  1586.  
  1587.  In its internal operations, the 80387 actually employs a number system that
  1588.  is a substantial superset of that shown in Figure 2-9. The internal format
  1589.  (called extended real) extends the 80387's range to about ±3.30 * 10^(-4932)
  1590.  to ±1.21 * 10^(4932), and its precision to about 19 (equivalent decimal)
  1591.  digits. This format is designed to provide extra range and precision for
  1592.  constants and intermediate results, and is not normally intended for data
  1593.  or final results.
  1594.  
  1595.  From a practical standpoint, the 80387's set of real numbers is
  1596.  sufficiently large and dense so as not to limit the vast majority of
  1597.  microprocessor applications. Compared to most computers, including
  1598.  mainframes, the NPX provides a very good approximation of the real number
  1599.  system. It is important to remember, however, that it is not an exact
  1600.  representation, and that arithmetic on real numbers is inherently
  1601.  approximate.
  1602.  
  1603.  Conversely, and equally important, the 80387 does perform exact arithmetic
  1604.  on integer operands. That is, if an operation on two integers is valid and
  1605.  produces a result that is in range, the result is exact. For example, 4 ÷ 2
  1606.  yields an exact integer, 1 ÷ 3 does not, and 2^(40) * 2^(30) + 1 does not,
  1607.  because the result requires greater than 64 bits of precision.
  1608.  
  1609.  
  1610.  Figure 2-9.  80387 Double-Precision Number System
  1611.  
  1612.   |─── NEGATIVE RANGE (NORMALIZED) ──|
  1613.   |                                    |
  1614.   |               -5  -4  -3  -2  -1   |
  1615.   ┌───┬───┬──┬┐┌───┬───┬───┬───┬───┬───┐
  1616.   │   │   │  │││░░░│░░░│▒▒▒│▒▒▒│▓▓▓│███│
  1617.   └───┴───┴──┴┘└───┴───┴───┴───┴───┴───┘
  1618.                                       
  1619.   │                   -2.23 X 10^(-308)┘
  1620.   └ -1.80 X 10^(308)
  1621.                                           ┌────────────────────────────────┐
  1622.                                           │   ───────┬─────────            │
  1623.                                           │   ▓▓▓▓▓▓▓│▒▒▒▒▒▒▒▒▒            │
  1624.  |── POSITIVE RANGE (NORMALIZED) ───|   │   ▓▓▓▓▓▓▓│▒▒▒▒▒▒▒▒▒            │
  1625.  |                                    |   │   ─∙─────∙─────∙───            │
  1626.  |   1   2   3   4   5                |   │    │─┬─│                     │
  1627.  ┌───┬───┬───┬───┬───┬───┐┌┬──┬───┬───┐   │    │  │  └2.00000000000000000  │
  1628.  │███│▓▓▓│▒▒▒│▒▒▒│░░░│░░░│││  │   │   │   │    │  └ (NOT REPRESENTABLE)    │
  1629.  └───┴───┴───┴───┴───┴───┘└┴──┴───┴───┘   │    └──────1.99999999999999999  │
  1630.       └───┤                             │  PRECISION│─  18 DIGITS  ─│  │
  1631.  │         └────────┐  1.80 X 10^(308)┘   │                                │
  1632.  └ 2.23 X 10^(-308) └─────────────────────┴────────────────────────────────┘
  1633.  
  1634.  
  1635.  2.2.2  Data Types and Formats
  1636.  
  1637.  The 80387 recognizes seven numeric data types for memory-based values,
  1638.  divided into three classes: binary integers, packed decimal integers, and
  1639.  binary reals. A later section describes how these formats are stored in
  1640.  memory (the sign is always located in the highest-addressed byte).
  1641.  
  1642.  Figure 2-10 summarizes the format of each data type. In the figure, the
  1643.  most significant digits of all numbers (and fields within numbers) are the
  1644.  leftmost digits.
  1645.  
  1646.  
  1647.  Figure 2-10.  80387 Data Formats
  1648.  
  1649.   ┌─────────┬─────────┬─────────┬───────────────────────────────────────────┐
  1650.   │         │         │         │MOST                  HIGHEST ADDRESSED    │
  1651.   │DATA     │ RANGE   │PRECISION│SIGNIFICANT BYTE                   BYTE    │
  1652.   │FORMATS  │         │         ├───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐   │
  1653.   │         │         │         │7 0│7 0│7 0│7 0│7 0│7 0│7 0│7 0│7 0│7 0│   │
  1654.   ├─────────┼─────────┼─────────┼───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┤
  1655.   │WORD     │         │         ├──────┐(TWO'S                              │
  1656.   │INTEGER  │ 10^(4)  │ 16 BITS ├──────┘COMPLEMENT)                         │
  1657.   │         │         │         │15   0                                     │
  1658.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1659.   │SHORT    │         │         ├───────────────┐(TWO'S                     │
  1660.   │INTEGER  │ 10^(2)  │ 32 BITS ├───────────────┘COMPLEMENT)                │
  1661.   │         │         │         │31            0                            │
  1662.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1663.   │LONG     │         │         ├───────────────────────────────┐(TWO'S     │
  1664.   │INTEGER  │ 10^(19) │ 64 BITS ├───────────────────────────────┘COMPLEMENT)│
  1665.   │         │         │         │6                             0            │
  1666.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1667.   │         │         │         │                MAGNITUDE                  │
  1668.   │PACKED   │         │         ├─┬───┬─────────────∙∙∙───────────────────┐ │
  1669.   │BCD      │ 10^(18) │18 DIGITS│S│ X │d{17} d{16}        d{2}  d{1}  d{0}│ │
  1670.   │         │         │         ├─┴───┴─────┴─────┴─∙∙∙─┴─────┴─────┴─────┘ │
  1671.   │         │         │         │    72                                  0  │
  1672.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1673.   │         │         │         ├─┬─────┬───────┐                           │
  1674.   │SINGLE   │ 10^(±38)│ 24 BITS │S│ BE  │ SIGN. │                           │
  1675.   │PRECISION│         │         ├─┴─────┴───────┘                           │
  1676.   │         │         │         │31     23     0                            │
  1677.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1678.   │         │         │         ├─┬────────┬────────────────────┐           │
  1679.   │DOUBLE   │10^(±308)│ 53 BITS │S│ BE     │     SIGNIFICAND    │           │
  1680.   │PRECISION│         │         ├─┴────────┴────────────────────┘           │
  1681.   │         │         │         │63       52                   0            │
  1682.   ├─────────┼─────────┼─────────┼───────────────────────────────────────────┤
  1683.   │         │         │         ├─┬────────────┬───────────────────────────┐│
  1684.   │EXTENDED │10^(4932)│ 64 BITS │S│ BE         ├─┐        SIGNIFICAND      ││
  1685.   │PRECISION│         │         ├─┴────────────┴I┴─────────────────────────┘│
  1686.   │         │         │         │79          64 63                       0 │
  1687.   └─────────┴─────────┴─────────┴───────────────────────────────────────────┘
  1688.  
  1689.  ─────────────────────────────────────────────────────────────────────────────
  1690.  NOTE:
  1691.     (1) BE = BIASED EXPONENT
  1692.     (2) S = SIGN BIT (0 = positive, 1 = negative)
  1693.     (3) d{n} = DECIMAL DIGIT (TWO PER TYPE)
  1694.     (4) X = BITS HAVE NO SIGNIFICANCE; 80387 IGNORES WHEN LOADING,
  1695.             ZEROS IN WHEN STORING
  1696.     (5)  = POSITION OF IMPLICIT BINARY POINT
  1697.     (6) I = INTEGER BIT OF SIGNIFICAND; STORED IN TEMPORARY REAL,
  1698.         IMPLICIT IN SINGLE AND DOUBLE PRECISION
  1699.     (7) EXPONENT BIAS (NORMALIZED VALUES):
  1700.         SINGLE: 127 (7FH)
  1701.         DOUBLE: 1023 (3FFH)
  1702.         EXTENDED REAL: 16383 (3FFFH)
  1703.     (8) PACKED BCD: (-1)^(S) (D{17}...D{0})
  1704.     (9) REAL: (-1)^(S) (2^(E-BIAS)) (F{0}F{1}...)
  1705.  ─────────────────────────────────────────────────────────────────────────────
  1706.  
  1707.  
  1708.  2.2.2.1  Binary Integers
  1709.  
  1710.  The three binary integer formats are identical except for length, which
  1711.  governs the range that can be accommodated in each format. The leftmost bit
  1712.  is interpreted as the number's sign: 0 = positive and 1 = negative. Negative
  1713.  numbers are represented in standard two's complement notation (the binary
  1714.  integers are the only 80387 format to use two's complement). The quantity
  1715.  zero is represented with a positive sign (all bits are 0). The 80387 word
  1716.  integer format is identical to the 16-bit signed integer data type of the
  1717.  80386; the 80387 short integer format is identical to the 32-bit signed
  1718.  integer data type of the 80386.
  1719.  
  1720.  The binary integer formats exist in memory only. When used by the 80387,
  1721.  they are automatically converted to the 80-bit extended real format. All
  1722.  binary integers are exactly representable in the extended real format.
  1723.  
  1724.  
  1725.  2.2.2.2  Decimal Integers
  1726.  
  1727.  Decimal integers are stored in packed decimal notation, with two decimal
  1728.  digits "packed" into each byte, except the leftmost byte, which carries the
  1729.  sign bit (0 = positive, 1 = negative). Negative numbers are not stored in
  1730.  two's complement form and are distinguished from positive numbers only by
  1731.  the sign bit. The most significant digit of the number is the leftmost
  1732.  digit. All digits must be in the range 0-9.
  1733.  
  1734.  The decimal integer format exists in memory only. When used by the 80387,
  1735.  it is automatically converted to the 80-bit extended real format. All
  1736.  decimal integers are exactly representable in the extended real format.
  1737.  
  1738.  
  1739.  2.2.2.3  Real Numbers
  1740.  
  1741.  The 80387 represents real numbers of the form:
  1742.  
  1743.    (-1)^(s)2^(E)(b{0}b{1}b{2}b{3}..b{p-1})
  1744.  
  1745.  ...where...
  1746.  
  1747.    s = 0 or 1
  1748.    E = any integer between Emin and Emax, inclusive
  1749.    b{i} = 0 or 1
  1750.    p = number of bits of precision
  1751.  
  1752.  Table 2-3 summarizes the parameters for each of the three real-number
  1753.  formats.
  1754.  
  1755.  The 80387 stores real numbers in a three-field binary format that resembles
  1756.  scientific, or exponential, notation. The format consists of the following
  1757.  fields:
  1758.  
  1759.    ■  The number's significant digits are held in the significand field,
  1760.       b{0} b{1} b{2} b{3}..b{p-1}. (The term "significand" is analogous
  1761.       to the term "mantissa" used to describe floating point numbers on some
  1762.       computers.)
  1763.  
  1764.    ■  The exponent field, e = E+bias, locates the binary point within the
  1765.       significant digits (and therefore determines the number's magnitude).
  1766.       (The term "exponent" is analogous to the term "characteristic" used to
  1767.       describe floating point numbers on somecomputers.)
  1768.  
  1769.    ■  The 1-bit sign field indicates whether the number is positive or
  1770.       negative. Negative numbers differ from positive numbers only in the
  1771.       sign bits of their significands.
  1772.  
  1773.  Table 2-4 shows how the real number 178.125 (decimal) is stored in the
  1774.  80387 single real format. The table lists a progression of equivalent
  1775.  notations that express the same value to show how a number can be converted
  1776.  from one form to another. (The ASM386 and PL/M-386 language translators
  1777.  perform a similar process when they encounter programmer-defined real number
  1778.  constants.) Note that not every decimal fraction has an exact binary
  1779.  equivalent. The decimal number 1/10, for example, cannot be expressed
  1780.  exactly in binary (just as the number 1/3 cannot be expressed exactly in
  1781.  decimal). When a translator encounters such a value, it produces a rounded
  1782.  binary approximation of the decimal value.
  1783.  
  1784.  The NPX usually carries the digits of the significand in normalized form.
  1785.  This means that, except for the value zero, the significand contains an
  1786.  integer bit and fraction bits as follows:
  1787.  
  1788.  1{}fff...ff
  1789.  
  1790.  where {} indicates an assumed binary point. The number of fraction bits
  1791.  varies according to the real format: 23 for single, 52 for double, and 63
  1792.  for extended real. By normalizing real numbers so that their integer bit is
  1793.  always a 1, the 80387 eliminates leading zeros in small values (│X│ < 1).
  1794.  This technique maximizes the number of significant digits that can be
  1795.  accommodated in a significand of a given width. Note that, in the single
  1796.  and double formats, the integer bit is implicit and is not actually stored;
  1797.  the integer bit is physically present in the extended format only.
  1798.  
  1799.  If one were to examine only the significand with its assumed binary point,
  1800.  all normalized real numbers would have values greater than or equal to 1 and
  1801.  less than 2. The exponent field locates the actual binary point in the
  1802.  significant digits. Just as in decimal scientific notation, a positive
  1803.  exponent has the effect of moving the binary point to the right, and a
  1804.  negative exponent effectively moves the binary point to the left, inserting
  1805.  leading zeros as necessary. An unbiased exponent of zero indicates that the
  1806.  position of the assumed binary point is also the position of the actual
  1807.  binary point. The exponent field, then, determines a real number's
  1808.  magnitude.
  1809.  
  1810.  In order to simplify comparing real numbers (e.g., for sorting), the 80387
  1811.  stores exponents in a biased form. This means that a constant is added to
  1812.  the true exponent described above. As Table 2-3 shows, the value of this
  1813.  bias is different for each real format. It has been chosen so as to
  1814.  force the biased exponent to be a positive value. This allows two real
  1815.  numbers (of the same format and sign) to be compared as if they are unsigned
  1816.  binary integers. That is, when comparing them bitwise from left to right
  1817.  (beginning with the leftmost exponent bit), the first bit position that
  1818.  differs orders the numbers; there is no need to proceed further with the
  1819.  comparison. A number's true exponent can be determined simply by
  1820.  subtracting the bias value of its format.
  1821.  
  1822.  The single and double real formats exist in memory only. If a number in one
  1823.  of these formats is loaded into an 80387 register, it is automatically
  1824.  converted to extended format, the format used for all internal operations.
  1825.  Likewise, data in registers can be converted to single or double real for
  1826.  storage in memory. The extended real format may be used in memory also,
  1827.  typically to store intermediate results that cannot be held in registers.
  1828.  
  1829.  Most applications should use the double format to store real-number data
  1830.  and results; it provides sufficient range and precision to return correct
  1831.  results with a minimum of programmer attention. The single real format is
  1832.  appropriate for applications that are constrained by memory, but it should
  1833.  be recognized that this format provides a smaller margin of safety. It is
  1834.  also useful for the debugging of algorithms, because roundoff problems will
  1835.  manifest themselves more quickly in this format. The extended real format
  1836.  should normally be reserved for holding intermediate results, loop
  1837.  accumulations, and constants. Its extra length is designed to shield final
  1838.  results from the effects of rounding and overflow/underflow in intermediate
  1839.  calculations. However, the range and precision of the double format are
  1840.  adequate for most microcomputer applications.
  1841.  
  1842.  
  1843.  Table 2-3.  Summary of Format Parameters
  1844.  
  1845.  Parameter                 ┌──────── Format ────────┐
  1846.                            Single   Double   Extended
  1847.  
  1848.  Format width in bits          32       64         80
  1849.  p (bits of precision)         24       53         64
  1850.  Exponent width in bits         8       11         15
  1851.  Emax                        +127    +1023     +16383
  1852.  Emin                        -126    -1022     -16382
  1853.  Exponent bias               +127    +1023     +16383
  1854.  
  1855.  
  1856.  Table 2-4.  Real Number Notation
  1857.  
  1858.  Notation                Value
  1859.  
  1860.  Ordinary Decimal        178.125
  1861.  Scientific Decimal      1{}78125E2
  1862.  Scientific Binary       1{}0110010001E111
  1863.  Scientific Binary       1{}0110010001E10000110
  1864.  (Biased Exponent)
  1865.  80387 Single Format     Sign    Biased Exponent     Significand
  1866.  (Normalized)            0       10000110            01100100010000000000000
  1867.                                                      1{}(implicit)
  1868.  
  1869.  
  1870.  2.2.3  Rounding Control
  1871.  
  1872.  Internally, the 80387 employs three extra bits (guard, round, and sticky
  1873.  bits) that enable it to round numbers in accord with the infinitely precise
  1874.  true result of a computation; these bits are not accessible to programmers.
  1875.  Whenever the destination can represent the infinitely precise true result,
  1876.  the 80387 delivers it. Rounding occurs in arithmetic and store operations
  1877.  when the format of the destination cannot exactly represent the infinitely
  1878.  precise true result. For example, a real number may be rounded if it is
  1879.  stored in a shorter real format, or in an integer format. Or, the infinitely
  1880.  precise true result may be rounded when it is returned to a register.
  1881.  
  1882.  The NPX has four rounding modes, selectable by the RC field in the control
  1883.  word (see Figure 2-3). Given a true result b that cannot be represented by
  1884.  the target data type, the 80387 determines the two representable numbers a
  1885.  and c that most closely bracket b in value (a < b < c). The processor then
  1886.  rounds (changes) b to a or to c according to the mode selected by the RC
  1887.  field as shown in Table 2-5. Rounding introduces an error in a result that
  1888.  is less than one unit in the last place to which the result is rounded.
  1889.  
  1890.    ■  "Round to nearest" is the default mode and is suitable for most
  1891.       applications; it provides the most accurate and statistically unbiased
  1892.       estimate of the true result.
  1893.  
  1894.    ■  The "chop" or "round toward zero" mode is provided for integer
  1895.       arithmeticapplications.
  1896.  
  1897.    ■  "Round up" and "round down" are termed directed rounding and can be
  1898.       used to implement interval arithmetic. Interval arithmetic generates a
  1899.       certifiable result independent of the occurrence of rounding and other
  1900.       errors. The upper and lower bounds of an interval may be computed by
  1901.       executing an algorithm twice, rounding up in one pass and down in the
  1902.       other.
  1903.  
  1904.  Rounding control affects only the arithmetic instructions (refer to Chapter
  1905.  3 for lists of arithmetic and nonarithmetic instructions).
  1906.  
  1907.  
  1908.  2.2.4  Precision Control
  1909.  
  1910.  The 80387 allows results to be calculated with either 64, 53, or 24 bits of
  1911.  precision in the significand as selected by the precision control (PC) field
  1912.  of the control word. The default setting, and the one that is best suited
  1913.  for most applications, is the full 64 bits of significance provided by the
  1914.  extended real format. The other settings are required by the IEEE standard
  1915.  and are provided to obtain compatibility with the specifications of certain
  1916.  existing programming languages. Specifying less precision nullifies the
  1917.  advantages of the extended format's extended fraction length. When reduced
  1918.  precision is specified, the rounding of the fractional value clears the
  1919.  unused bits on the right to zeros.
  1920.  
  1921.  
  1922.  Table 2-5.  Rounding Modes
  1923.  
  1924.  RC Field    Rounding Mode            Rounding Action
  1925.  
  1926.  00          Round to nearest         Closer to b of a or c; if equally
  1927.                                       close, select even number (the one
  1928.                                       whose least significant bit is zero).
  1929.  01          Round down (toward -∞)   a
  1930.  10          Round up (toward +∞)     c
  1931.  11          Chop (toward 0)          Smaller in magnitude of a or c.
  1932.  
  1933.  ────────────────────────────────────────────────────────────────────────────
  1934.  NOTE
  1935.    a < b < c; a and c are successive representable numbers; b is not
  1936.    representable.
  1937.  ────────────────────────────────────────────────────────────────────────────
  1938.  
  1939.  
  1940.  Chapter 3  Special Computational Situations
  1941.  
  1942.  ───────────────────────────────────────────────────────────────────────────
  1943.  
  1944.  Besides being able to represent positive and negative numbers, the 80387
  1945.  data formats may be used to describe other entities. These special values
  1946.  provide extra flexibility, but most users will not need to understand them
  1947.  in order to use the 80387 successfully. This section describes the special
  1948.  values that may occur in certain cases and the significance of each. The
  1949.  80387 exceptions are also described, for writers of exception handlers and
  1950.  for those interested in probing the limits of computation using the 80387.
  1951.  
  1952.  The material presented in this section is mainly of interest to programmers
  1953.  concerned with writing exception handlers. Many readers will only need to
  1954.  skim this section.
  1955.  
  1956.  When discussing these special computational situations, it is useful to
  1957.  distinguish between arithmetic instructions and nonarithmetic instructions.
  1958.  Nonarithmetic instructions are those that have no operands or transfer their
  1959.  operands without substantial change; arithmetic instructions are those that
  1960.  make significant changes to their operands. Table 3-1 defines these two
  1961.  classes of instructions.
  1962.  
  1963.  
  1964.  Table 3-1.  Arithmetic and Nonarithmetic Instructions
  1965.  
  1966. ╓┌──────────────────────────────────────┌────────────────────────────────────╖
  1967.  Nonarithmetic Instructions             Arithmetic Instructions
  1968.  
  1969.  FABS                                   F2XM1
  1970.  FCHS                                   FADD (P)
  1971.  FCLEX                                  FBLD
  1972.  FDECSTP                                FBSTP
  1973.  FFREE                                  FCOMP(P)(P)
  1974.  FINCSTP                                FCOS
  1975.  FINIT                                  FDIV(R)(P)
  1976.  Nonarithmetic Instructions             Arithmetic Instructions
  1977. FINIT                                  FDIV(R)(P)
  1978.  FLD (register-to-register)             FIADD
  1979.  FLD (extended format from memory)      FICOM(P)
  1980.  FLD constant                           FIDIV(R)
  1981.  FLDCW                                  FILD
  1982.  FLDENV                                 FIMUL
  1983.  FNOP                                   FIST(P)
  1984.  FRSTOR                                 FISUB(R)
  1985.  FSAVE                                  FLD (conversion)
  1986.  FST(P) (register-to-register)          FMUL(P)
  1987.  FSTP (extended format to memory)       FPATAN
  1988.  FSTCW                                  FPREM
  1989.  FSTENV                                 FPREM1
  1990.  FSTSW                                  FPTAN
  1991.  FWAIT                                  FRNDINT
  1992.  FXAM                                   FSCALE
  1993.  FXCH                                   FSIN
  1994.                                         FSINCOS
  1995.                                         FSQRT
  1996.                                         FST(P) (conversion)
  1997.  Nonarithmetic Instructions             Arithmetic Instructions
  1998.                                        FST(P) (conversion)
  1999.                                         FSUB(R)(P)
  2000.                                         FTST
  2001.                                         FUCOM(P)(P)
  2002.                                         FXTRACT
  2003.                                         FYL2X
  2004.                                         FYL2XP1
  2005.  
  2006.  
  2007.  
  2008.  3.1  Special Numeric Values
  2009.  
  2010.  The 80387 data formats encompass encodings for a variety of special values
  2011.  in addition to the typical real or integer data values that result from
  2012.  normal calculations. These special values have significance and can express
  2013.  relevant information about the computations or operations that produced
  2014.  them. The various types of special values are
  2015.  
  2016.    ■  Denormal real numbers
  2017.    ■  Zeros
  2018.    ■  Positive and negative infinity
  2019.    ■  NaN (Not-a-Number)
  2020.    ■  Indefinite
  2021.    ■  Unsupported formats
  2022.  
  2023.  The following sections explain the origins and significance of each of
  2024.  these special values. Tables 3-6 through 3-9 at the end of this section
  2025.  show how each of these special values is encoded for each of the numeric
  2026.  data types.
  2027.  
  2028.  
  2029.  3.1.1  Denormal Real Numbers
  2030.  
  2031.  The 80387 generally stores nonzero real numbers in normalized
  2032.  floating-point form; that is, the integer (leading) bit of the significand
  2033.  is always a one. (Refer to Chapter 2 for a review of operand formats.) This
  2034.  bit is explicitly stored in the extended format, and is implicitly assumed
  2035.  to be a one (1{}) in the single and double formats. Since leading zeros are
  2036.  eliminated, normalized storage allows the maximum number of significant
  2037.  digits to be held in a significand of a given width.
  2038.  
  2039.  When a numeric value becomes very close to zero, normalized floating-point
  2040.  storage cannot be used to express the value accurately. The term tiny is
  2041.  used here to precisely define what values require special handling by the
  2042.  80387. A number R is said to be tiny when -2{Emin} < R < 0 or
  2043.  0 < R < +2{Emin}. (As defined in Chapter 2, Emin is -126 for single format,
  2044.  -1022 for double format, and -16382 for extended format.) In other words, a
  2045.  nonzero number is tiny if its exponent would be too negative to store in the
  2046.  destination format.
  2047.  
  2048.  To accommodate these instances, the 80387 can store and operate on reals
  2049.  that are not normalized, i.e., whose significands contain one or more
  2050.  leading zeros. Denormals typically arise when the result of a calculation
  2051.  yields a value that is tiny.
  2052.  
  2053.  Denormal values have the following properties:
  2054.  
  2055.    ■  The biased floating-point exponent is stored at its smallest value
  2056.       (zero)
  2057.  
  2058.    ■  The integer bit of the significand (whether explicit or implicit) is
  2059.       zero
  2060.  
  2061.  The leading zeros of denormals permit smaller numbers to be represented, at
  2062.  the possible cost of some lost precision (the number of significant bits is
  2063.  reduced by the leading zeros). In typical algorithms, extremely small values
  2064.  are most likely to be generated as intermediate, rather than final, results.
  2065.  By using the NPX's extended real format for holding intermediate values,
  2066.  quantities as small as ±3.4*10{-4932} can be represented; this makes the
  2067.  occurrence of denormal numbers a rare phenomenon in 80387 applications.
  2068.  Nevertheless, the NPX can load, store, and operate on denormalized real
  2069.  numbers when they do occur.
  2070.  
  2071.  Denormals receive special treatment by the 80387 in three respects:
  2072.  
  2073.    ■  The 80387 avoids creating denormals whenever possible. In other words,
  2074.       it always normalizes real numbers except in the case of tiny numbers.
  2075.  
  2076.    ■  The 80387 provides the unmasked underflow exception to permit
  2077.       programmers to detect cases when denormals would be created.
  2078.  
  2079.    ■  The 80387 provides the denormal exception to permit programmers to
  2080.       detect cases when denormals enter into further calculations.
  2081.  
  2082.  Denormalizing means incrementing the true result's exponent and inserting a
  2083.  corresponding leading zero in the significand, shifting the rest of the
  2084.  significand one place to the right. Denormal values may occur in any of the
  2085.  single, double, or extended formats. Table 3-2 illustrates how a result
  2086.  might be denormalized to fit a single format destination.
  2087.  
  2088.  Denormalization produces either a denormal or a zero. Denormals are readily
  2089.  identified by their exponents, which are always the minimum for their
  2090.  formats; in biased form, this is always the bit string: 00..00. This same
  2091.  exponent value is also assigned to the zeros, but a denormal has a nonzero
  2092.  significand. A denormal in a register is tagged special. Tables 3-8 and
  2093.  3-9 show how denormal values are encoded in each of the real data formats.
  2094.  
  2095.  The denormalization process causes loss of significance if low-order
  2096.  one-bits bits are shifted off the right of the significand. In a severe
  2097.  case, all the significand bits of the true result are shifted out and
  2098.  replaced by the leading zeros. In this case, the result of denormalization
  2099.  is a true zero, and, if the value is in a register, it is tagged as a zero.
  2100.  
  2101.  Denormals are rarely encountered in most applications. Typical debugged
  2102.  algorithms generate extremely small results during the evaluation of
  2103.  intermediate subexpressions; the final result is usually of an appropriate
  2104.  magnitude for its single or double format real destination. If intermediate
  2105.  results are held in temporary real, as is recommended, the great range of
  2106.  this format makes underflow very unlikely. Denormals are likely to arise
  2107.  only when an application generates a great many intermediates, so many that
  2108.  they cannot be held on the register stack or in extended format memory
  2109.  variables. If storage limitations force the use of single or double format
  2110.  reals for intermediates, and small values are produced, underflow may occur,
  2111.  and, if masked, may generate denormals.
  2112.  
  2113.  When a denormal number is single or double format is used as a source
  2114.  operand and the denormal exception is masked, the 80387 automatically
  2115.  normalizes the number when it is converted to extended format.
  2116.  
  2117.  
  2118.  Table 3-2.  Denormalization Process
  2119.  
  2120.  Operation          Sign    Exponent    Significand
  2121.  
  2122.  True Result        0       -129        1{}01011100..00
  2123.  Denormalize        0       -128        0{}101011100..00
  2124.  Denormalize        0       -127        0{}0101011100..00
  2125.  Denormalize        0       -126        0{}00101011100..00
  2126.  Denormal Result    0       -126        0{}00101011100..00
  2127.  
  2128.  
  2129.  3.1.1.1  Denormals and Gradual Underflow
  2130.  
  2131.  Floating-point arithmetic cannot carry out all operations exactly for all
  2132.  operands; approximation is unavoidable when the exact result is not
  2133.  representable as a floating-point variable. To keep the approximation
  2134.  mathematically tractable, the hardware is made to conform to accuracy
  2135.  standards that can be modeled by certain inequalities instead of equations.
  2136.  Let the assignment
  2137.  
  2138.    X  Y @ Z    (where @ is some operation)
  2139.  
  2140.  represent a typical operation. In the default rounding mode (round to
  2141.  nearest), each operation is carried out with an absolute error no larger
  2142.  than half the separation between the two floating-point numbers closest to
  2143.  the exact results. Let x be the value stored for the variable whose name in
  2144.  the program is X, and similarly y for Y, and z for Z. Normally y and z will
  2145.  differ by accumulated errors from what is desired and from what would have
  2146.  been obtained in the absence of error. For the calculation of x we assume
  2147.  that y and z are the best approximations available, and we seek to compute x
  2148.  as well as we can. If y@z is representable exactly, then we expect x = y@z,
  2149.  and that is what we get for every algebraic operation on the 80387 (i.e.,
  2150.  when y@z is one of y+z, y-z, y*z, y÷z, sqrt z). But if y@z must be
  2151.  approximated, as is usually the case, then x must differ from y@z by no
  2152.  more than half the difference between the two representable numbers that
  2153.  straddle y@z. That difference depends on two factors:
  2154.  
  2155.    1.  The precision to which the calculation is carried out, as determined
  2156.        either by the precision control bits or by the format used in memory.
  2157.        On the 80387, the precisions are single (24 significant bits), double
  2158.        (53 significant bits), and extended (64 significant bits).
  2159.  
  2160.    2.  How close y@z is to zero. In this respect the presence of denormal
  2161.        numbers on the 80387 provides a distinct advantage over systems that
  2162.        do not admit denormal numbers.
  2163.  
  2164.  In any floating-point number system, the density of representable numbers
  2165.  is greater near zero than near the largest representable magnitudes.
  2166.  However, machines that do not use denormal numbers suffer from an enormous
  2167.  gap between zero and its closest neighbors. Figures 3-1 and 3-2 show what
  2168.  happens near zero in two kinds of floating-point number systems.
  2169.  
  2170.  Figure 3-1 shows a floating-point number system that (like the 80387)
  2171.  admits denormal numbers. For simplicity, only the non-negative numbers
  2172.  appear and the figure illustrates a number system that carries just four
  2173.  significant bits instead of the 24, 53, or 64 significant bits that the
  2174.  80387 offers.
  2175.  
  2176.  Each vertical mark stands for a number representable in four significant
  2177.  bits, and the bolder marks stand for the normal powers of 2. The denormal
  2178.  numbers lie between 0 and the nearest normal power of 2. They are no less
  2179.  dense than the remaining normal nonzero numbers.
  2180.  
  2181.  Figure 3-2 shows a floating-point number system that (unlike the 80387)
  2182.  does not admit denormal numbers. There are two yawning gaps, one on the
  2183.  positive side of zero (as illustrated) and one on the negative side of zero
  2184.  (not illustrated). The gap between zero and the nearest neighbor of zero
  2185.  differs from the gap between that neighbor and the next bigger number by a
  2186.  factor of about 8.4 * 10^(6) for single, 4.5 * 10^(15) for double, and
  2187.  9.2*10^(18) for extended format. Those gaps would horribly complicate error
  2188.  analysis.
  2189.  
  2190.  The advantage of denormal numbers is apparent when one considers what
  2191.  happens in either case when the underflow exception is masked and y@z falls
  2192.  into the space between zero and the smallest normal magnitude. The 80387
  2193.  returns the nearest denormal number. This action might be called "gradual
  2194.  underflow." The effect is no different than the rounding that can occur when
  2195.  y@z falls in the normal range.
  2196.  
  2197.  On the other hand, the system that does not have denormal numbers returns
  2198.  zero as the result, an action that can be much more inaccurate than
  2199.  rounding. This action could be called "abrupt underflow."
  2200.  
  2201.  
  2202.  Figure 3-1.  Floating-Point System with Denormals
  2203.  
  2204.   0+++++++│+++++++│-+-+-+-+-+-+-+-│---+---+---+---+---+---+---+---│------+...
  2205.  
  2206.    └──┬──┘ - - - - - - - - Normal Numbers - - - - - -
  2207.    Denormals
  2208.  
  2209.  
  2210.  Figure 3-2.  Floating-Point System without Denormals
  2211.  
  2212.   0    │+++++++│-+-+-+-+-+-+-+-│---+---+---+---+---+---+---+---│------+---...
  2213.  
  2214.         - - - - - - - - Normal Numbers - - - - - -
  2215.  
  2216.  
  2217.  3.1.2  Zeros
  2218.  
  2219.  The value zero in the real and decimal integer formats may be signed either
  2220.  positive or negative, although the sign of a binary integer zero is always
  2221.  positive. For computational purposes, the value of zero always behaves
  2222.  identically, regardless of sign, and typically the fact that a zero may be
  2223.  signed is transparent to the programmer. If necessary, the FXAM instruction
  2224.  may be used to determine a zero's sign.
  2225.  
  2226.  If a zero is loaded or generated in a register, the register is tagged
  2227.  zero. Table 3-3 lists the results of instructions executed with zero
  2228.  operands and also shows how a zero may be created from nonzero operands.
  2229.  
  2230.  
  2231.  Table 3-3.  Zero Operands and Results
  2232.  
  2233. ╓┌──────────────────┌───────────────────────────┌────────────────────────────╖
  2234.  Key to symbols used in this table
  2235.  
  2236.  Operation          Operands                    Result
  2237.  
  2238.  FLD,FBLD           +0                          +0
  2239.                     -0                          -0
  2240.  FILD               +0                          +0
  2241.  FST,FSTP           +0                          +0
  2242.                     -0                          -0
  2243.                     +X                          +0
  2244.  
  2245.                     -X                          -0
  2246.  
  2247.  FBSTP              +0                          +0
  2248.                     -0                          -0
  2249.  Key to symbols used in this table
  2250.  
  2251.  Operation          Operands                    Result
  2252.                    -0                          -0
  2253.  FIST,FISTP         +0                          +0
  2254.                     -0                          -0
  2255.                     +X                          +0
  2256.  
  2257.                     -X                          -0
  2258.  
  2259.  Addition           +0 plus +0                  +0
  2260.                     -0 plus -0                  -0
  2261.                     +0 plus -0, -0 plus +0      ±0
  2262.  
  2263.                     -X plus +X, +X plus -X      ±0
  2264.  
  2265.                     ±0 plus ±X, ±X plus ±0      #X
  2266.  Subtraction        +0 minus                    -0+0
  2267.                     -0 minus +0                 -0
  2268.                     +0 minus +0, -0 minus -0    ±0
  2269.  
  2270.  Key to symbols used in this table
  2271.  
  2272.  Operation          Operands                    Result
  2273. 
  2274.                     +X minus +X, -X minus -X    ±0
  2275.  
  2276.                     ±0 minus ±X                 -#X
  2277.                     ±X minus ±0                 #X
  2278.  Multiplication     +0 * +0, -0 * -0            +0
  2279.                     +0 * -0, -0 * +0            -0
  2280.                     +0 * +X, +X * +0            +0
  2281.                     +0 * -X, -X * +0            -0
  2282.                     -0 * +X, -X * +0            -0
  2283.  Multiplication     -0 * -X, -X * -0            +0
  2284.                     +X * +Y, -X * -Y            +0
  2285.  
  2286.                     +X * -Y, -X * +Y            -0
  2287.  
  2288.  Division           ±0 ÷ ±0                     Invalid Operation
  2289.                     ±X ÷ ±0                     Φ∞ (Zero Divide)
  2290.                     +0 ÷ +X, -0 ÷ -X            +0
  2291.  Key to symbols used in this table
  2292.  
  2293.  Operation          Operands                    Result
  2294.                    +0 ÷ +X, -0 ÷ -X            +0
  2295.                     +0 ÷ -X, -0 ÷ +X            -0
  2296.                     -X ÷ -Y, +X ÷ +Y            +0
  2297.  
  2298.                     -X ÷ +Y, +X ÷ -Y            -0
  2299.  
  2300.  FPREM, FPREM1      ±0 rem ±0                   Invalid Operation
  2301.                     ±X rem ±0                   Invalid Operation
  2302.                     +0 rem ±X                   +0
  2303.                     -0 rem ±X                   -0
  2304.  FPREM              +X rem ±Y                   +0 Y exactly divides X
  2305.                     -X rem ±Y                   -0 Y exactly divides X
  2306.  FPREM1             +X rem ±Y                   +0 Y exactly divides X
  2307.                     -X rem ±Y                   -0 Y exactly divides X
  2308.  FSQRT              +0                          +0
  2309.                     -0                          -0
  2310.  Compare            ±0 : +X                     ±0 < +X
  2311.                     ±0 : ±0                     ±0 = ±0
  2312.  Key to symbols used in this table
  2313.  
  2314.  Operation          Operands                    Result
  2315.                    ±0 : ±0                     ±0 = ±0
  2316.                     ±0 : -X                     ±0 > -X
  2317.  FTST               ±0                          ±0 = 0
  2318.                     +0                          C{3}=1; C{2}=C{1}=C{0}=0
  2319.                     -0                          C{3}=C{1}=1; C{2}=C{0}=0
  2320.  FCHS               +0                          -0
  2321.                     -0                          +0
  2322.  FABS               ±0                          +0
  2323.  F2XM1              +0                          +0
  2324.                     -0                          -0
  2325.  FRNDINT            +0                          +0
  2326.                     -0                          -0
  2327.  FSCALE             ±0 scaled by -∞             *0
  2328.                     ±0 scaled by +∞             Invalid Operation
  2329.                     ±0 scaled by X              *0
  2330.  FXTRACT            +0                          ST=+0,ST(1)=-∞, Zero divide
  2331.                     -0                          ST=-0,ST(1)=-∞, Zero divide
  2332.  FPTAN±0            *0
  2333.  Key to symbols used in this table
  2334.  
  2335.  Operation          Operands                    Result
  2336. FPTAN±0            *0
  2337.  FSIN (or           ±0                          *0
  2338.  SIN result of
  2339.  FSINCOS)
  2340.  FCOS (or           ±0                          +1
  2341.  COS result of
  2342.  FSINCOS)
  2343.  FPATAN             ±0 ÷ +X                     *0
  2344.                     ±0 ÷ -X                     *π
  2345.                     ±X ÷ ±0                     #π/2
  2346.                     ±0 ÷ +0                     *0
  2347.                     ±0 ÷ -0                     *π
  2348.                     +∞ ÷ ±0                     +π/2
  2349.                     -∞ ÷ ±0                     -π/2
  2350.                     ±0 ÷ +∞                     *0
  2351.                     ±0 ÷ -∞                     *π
  2352.  FYL2X              ±Y * log(±0)                Zero Divide
  2353.                     ±0 * log(±0)                Invalid Operation
  2354.  Key to symbols used in this table
  2355.  
  2356.  Operation          Operands                    Result
  2357.                    ±0 * log(±0)                Invalid Operation
  2358.  FYL2XP1            +Y * log(±0+1)              *0
  2359.                     -Y * log(±0+1)              -0
  2360.  
  2361.  
  2362.  3.1.3  Infinity
  2363.  
  2364.  The real formats support signed representations of infinities. These values
  2365.  are encoded with a biased exponent of all ones and a significand of
  2366.  1{}00..00; if the infinity is in a register, it is tagged special.
  2367.  
  2368.  A programmer may code an infinity, or it may be created by the NPX as its
  2369.  masked response to an overflow or a zero divide exception. Note that
  2370.  depending on rounding mode, the masked response may create the largest valid
  2371.  value representable in the destination rather than infinity.
  2372.  
  2373.  The signs of the infinities are observed, and comparisons are possible.
  2374.  Infinities are always interpreted in the affine sense; that is, -∞ < (any
  2375.  finite number) < +∞. Arithmetic on infinities is always exact and,
  2376.  therefore, signals no exceptions, except for the invalid operations
  2377.  specified in Table 3-4.
  2378.  
  2379.  
  2380.  Table 3-4.  Infinity Operands and Results
  2381.  
  2382. ╓┌───────────────────┌───────────────────┌───────────────────────────────────╖
  2383.  Key to symbols used in this table
  2384.  
  2385.  Operation           Operands            Result
  2386.  
  2387.  Addition            +∞ plus +∞          +∞
  2388.                      -∞ plus -∞          -∞
  2389.                      +∞ plus -∞          Invalid Operation
  2390.                      -∞ plus +∞          Invalid Operation
  2391.                      ±∞ plus ±X          *∞
  2392.                      ±X plus ±∞          *∞
  2393.  Subtraction         +∞ minus -∞         +∞
  2394.                      -∞ minus +∞         -∞
  2395.                      +∞ minus +∞         Invalid Operation
  2396.  Key to symbols used in this table
  2397.  
  2398.  Operation           Operands            Result
  2399.                     +∞ minus +∞         Invalid Operation
  2400.                      -∞ minus -∞         Invalid Operation
  2401.                      ±∞ minus ±X         *∞
  2402.                      ±X minus ±∞         -*∞
  2403.  Multiplication      ±∞ * ±∞             Φ∞
  2404.                      ±∞ * ±Y, ±Y * ±∞    Φ∞
  2405.                      ±0 * ±∞, ±∞ * ±0    Invalid Operation
  2406.  Division            ±∞ ÷ ±∞             Invalid Operation
  2407.                      ±∞ ÷ ±X             Φ∞
  2408.                      ±X ÷ ±∞             Φ0
  2409.                      ±∞ ÷ ±0             Φ∞
  2410.  FSQRT               -∞                  Invalid Operation
  2411.                      +∞                  +∞
  2412.  FPREM, FPREM1       ±∞ rem ±∞           Invalid Operation
  2413.                      ±∞ rem ±X           Invalid Operation
  2414.                      ±X rem ±∞           $X, Q = 0
  2415.  FRNDINT             ±∞                  *∞
  2416.  FSCALE              ±∞ scaled by --∞    Invalid Operation
  2417.  Key to symbols used in this table
  2418.  
  2419.  Operation           Operands            Result
  2420. FSCALE              ±∞ scaled by --∞    Invalid Operation
  2421.                      ±∞ scaled by +∞     *∞
  2422.                      ±∞ scaled by ±X     *∞
  2423.                      ±0 scaled by -∞     ±0
  2424.  
  2425.                      ±0 scaled by ∞I     Invalid Operation
  2426.                      ±Y scaled by +∞     #∞
  2427.                      ±Y scaled by -∞     #0
  2428.  FXTRACT             ±∞                  ST = *∞, ST(1) = +∞
  2429.  Compare             +∞ : +∞             +∞ = +∞
  2430.                      -∞ : -∞             -∞ = -∞
  2431.                      +∞ : -∞             +∞ > -∞
  2432.                      -∞ : +∞             -∞ < +∞
  2433.                      +∞ : ±X             +∞ > X
  2434.                      -∞ : ±X             -∞ < X
  2435.                      ±X : +∞             X < +∞
  2436.                      ±X : -∞             X > +∞
  2437.  FTST                +∞                  +∞ > 0
  2438.  Key to symbols used in this table
  2439.  
  2440.  Operation           Operands            Result
  2441. FTST                +∞                  +∞ > 0
  2442.                      -∞                  -∞ < 0
  2443.  FPATAN              ±∞ ÷ ±X             *π/2
  2444.                      ±Y ÷ +∞             #0
  2445.                      ±Y ÷ -∞             #π
  2446.                      ±∞ ÷ +∞             *π/4
  2447.                      ±∞ ÷ -∞             *3π/4
  2448.                      ±∞ ÷ ±0             *π/2
  2449.                      +0 ÷ +∞             +0
  2450.                      +0 ÷ -∞             +π
  2451.                      -0 ÷ +∞             -0
  2452.                      -0 ÷ -∞             -π
  2453.  F2XM1               +∞                  +∞
  2454.                      -∞                  -1
  2455.  FYL2X, FYL2XP1      ±∞ * log(1)         Invalid Operation
  2456.                      ±∞ * log(Y>1)       *∞
  2457.                      ±∞ * log(0<Y<1)     -*∞
  2458.                      ±Y * log(+∞)        #∞
  2459.  Key to symbols used in this table
  2460.  
  2461.  Operation           Operands            Result
  2462.                     ±Y * log(+∞)        #∞
  2463.                      ±0 * log(+∞)        Invalid Operation
  2464.                      ±Y * log(-∞)        Invalid Operation
  2465.  
  2466.  
  2467.  3.1.4  NaN (Not-a-Number)
  2468.  
  2469.  A NaN (Not a Number) is a member of a class of special values that exists
  2470.  in the real formats only. A NaN has an exponent of 11..11B, may have either
  2471.  sign, and may have any significand except 1{}00..00B, which is assigned to
  2472.  the infinities. A NaN in a register is tagged special.
  2473.  
  2474.  There are two classes of NaNs: signaling (SNaN) and quiet (QNaN). Among the
  2475.  QNaNs, the value real indefinite is of special interest.
  2476.  
  2477.  
  2478.  3.1.4.1  Signaling NaNs
  2479.  
  2480.  A signaling NaN is a NaN that has a zero as the most significant bit of its
  2481.  significand. The rest of the significand may be set to any value. The 80387
  2482.  never generates a signaling NaN as a result; however, it recognizes
  2483.  signaling NaNs when they appear as operands. Arithmetic operations (as
  2484.  defined at the beginning of this chapter) on a signaling NaN cause an
  2485.  invalid-operation exception (except for load operations, FXCH, FCHS, and
  2486.  FABS).
  2487.  
  2488.  By unmasking the invalid operation exception, the programmer can use
  2489.  signaling NaNs to trap to the exception handler. The generality of this
  2490.  approach and the large number of NaN values that are available provide the
  2491.  sophisticated programmer with a tool that can be applied to a variety of
  2492.  special situations.
  2493.  
  2494.  For example, a compiler could use signaling NaNs as references to
  2495.  uninitialized (real) array elements. The compiler could preinitialize each
  2496.  array element with a signaling NaN whose significand contained the index
  2497.  (relative position) of the element. If an application program attempted to
  2498.  access an element that it had not initialized, it would use the NaN placed
  2499.  there by the compiler. If the invalid operation exception were unmasked, an
  2500.  interrupt would occur, and the exception handler would be invoked. The
  2501.  exception handler could determine which element had been accessed, since the
  2502.  operand address field of the exception pointers would point to the NaN, and
  2503.  the NaN would contain the index number of the array element.
  2504.  
  2505.  
  2506.  3.1.4.2  Quiet NaNs
  2507.  
  2508.  A quiet NaN is a NaN that has a one as the most significant bit of its
  2509.  significand. The 80387 creates the quiet NaN real indefinite (defined below)
  2510.  as its default response to certain exceptional conditions. The 80387 may
  2511.  derive other QNaNs by converting an SNaN. The 80387 converts a SNaN by
  2512.  setting the most significant bit of its significand to one, thereby
  2513.  generating an QNaN. The remaining bits of the significand are not changed;
  2514.  therefore, diagnostic information that may be stored in these bits of the
  2515.  SNaN is propagated into the QNaN.
  2516.  
  2517.  The 80387 will generate the special QNaN, real indefinite, as its masked
  2518.  response to an invalid operation exception. This NaN is signed negative; its
  2519.  significand is encoded 1{}100..00. All other NaNs represent values created
  2520.  by programmers or derived from values created by programmers.
  2521.  
  2522.  Both quiet and signaling NaNs are supported in all operations. A QNaN is
  2523.  generated as the masked response for invalid-operation exceptions and as the
  2524.  result of an operation in which at least one of the operands is a QNaN. The
  2525.  80387 applies the rules shown in Table 3-5 when generating a QNaN:
  2526.  
  2527.  Note that handling of a QNaN operand has greater priority than all
  2528.  exceptions except certain invalid-operation exceptions (refer to the section
  2529.  "Exception Priority" in this chapter).
  2530.  
  2531.  Quiet NaNs could be used, for example, to speed up debugging. In its early
  2532.  testing phase, a program often contains multiple errors. An exception
  2533.  handler could be written to save diagnostic information in memory whenever
  2534.  it was invoked. After storing the diagnostic data, it could supply a quiet
  2535.  NaN as the result of the erroneous instruction, and that NaN could point to
  2536.  its associated diagnostic area in memory. The program would then continue,
  2537.  creating a different NaN for each error. When the program ended, the NaN
  2538.  results could be used to access the diagnostic data saved at the time the
  2539.  errors occurred. Many errors could thus be diagnosed and corrected in one
  2540.  test run.
  2541.  
  2542.  
  2543.  Table 3-5.  Rules for Generating QNaNs
  2544.  
  2545.  Operation                          Action
  2546.  
  2547.  Real operation on an SNaN and      Deliver the QNaN operand.
  2548.  a QNaN
  2549.  
  2550.  Real operation on two SNaNs        Deliver the QNaN that results from
  2551.                                     converting the SNaN that has the larger
  2552.                                     significand.
  2553.  
  2554.  Real operation on two QNaNs        Deliver the QNaN that has the larger
  2555.                                     significand.
  2556.  
  2557.  Real operation on an SNaN and      Deliver the QNaN that results from
  2558.  another number                     converting the SNaN.
  2559.  
  2560.  Real operation on a QNaN and       Deliver the QNaN.
  2561.  another number
  2562.  
  2563.  Invalid operation that does not    Deliver the default QNaN real indefinite.
  2564.  involve NaNs
  2565.  
  2566.  
  2567.  3.1.5  Indefinite
  2568.  
  2569.  For every 80387 numeric data type, one unique encoding is reserved for
  2570.  representing the special value indefinite. The 80387 produces this encoding
  2571.  as its response to a masked invalid-operation exception.
  2572.  
  2573.  In the case of reals, the indefinite value is a QNaN as discussed in the
  2574.  prior section.
  2575.  
  2576.  Packed decimal indefinite may be stored by the NPX in a FBSTP instruction;
  2577.  attempting to use this encoding in a FBLD instruction, however, will have an
  2578.  undefined result; thus indefinite cannot be loaded from a packed decimal
  2579.  integer.
  2580.  
  2581.  In the binary integers, the same encoding may represent either indefinite
  2582.  or the largest negative number supported by the format (-2^(15), -2^(31), or
  2583.  -2^(63)). The 80387 will store this encoding as its masked response to
  2584.  an invalid operation, or when the value in a source register represents or
  2585.  rounds to the largest negative integer representable by the destination. In
  2586.  situations where its origin may be ambiguous, the invalid-operation
  2587.  exception flag can be examined to see if the value was produced by an
  2588.  exception response. When this encoding is loaded or used by an integer
  2589.  arithmetic or compare operation, it is always interpreted as a negative
  2590.  number; thus indefinite cannot be loaded from a binary integer.
  2591.  
  2592.  
  2593.  3.1.6  Encoding of Data Types
  2594.  
  2595.  Tables 3-6 through 3-9 show how each of the special values just
  2596.  described is encoded for each of the numeric data types. In these tables,
  2597.  the least-significant bits are shown to the right and are stored in the
  2598.  lowest memory addresses. The sign bit is always the left-most bit of the
  2599.  highest-addressed byte.
  2600.  
  2601.  
  2602.  3.1.7  Unsupported Formats
  2603.  
  2604.  The extended format permits many bit patterns that do not fall into any of
  2605.  the previously mentioned categories. Some of these encodings were supported
  2606.  by the 80287 NPX; however, most of them are not supported by the 80387 NPX.
  2607.  These changes are required due to changes made in the final version of the
  2608.  IEEE 754 standard that eliminated these data types.
  2609.  
  2610.  The categories of encodings formerly known as pseudozeros, pseudo-NaNs,
  2611.  pseudoinfinities, and unnormal numbers are not supported by the 80387. The
  2612.  80387 raises the invalid-operation exception when they are encountered as
  2613.  operands.
  2614.  
  2615.  The encodings formerly known as pseudodenormal numbers are not generated by
  2616.  the 80387; however, they are correctly utilized when encountered in operands
  2617.  to 80387 instructions. The exponent is treated as if it were 00..01 and the
  2618.  mantissa is unchanged. The denormal exception is raised.
  2619.  
  2620.  
  2621.  Table 3-6. Binary Integer Encodings
  2622.  
  2623.                Class                   Sign         Magnitude
  2624.      ┌────────────────────────────────────────────────────────────
  2625.      │         (Largest)                0            11...11
  2626.      │                                  ∙               ∙
  2627.  Positives                              ∙               ∙
  2628.      │                                  ∙               ∙
  2629.      │         (Smallest)               0            00...01
  2630.      └────────────────────────────────────────────────────────────
  2631.                 Zero                    0            00...00
  2632.      ┌────────────────────────────────────────────────────────────
  2633.      │         (Smallest)               1            11...11
  2634.      │                                  ∙               ∙
  2635.  Negatives                              ∙               ∙
  2636.      │                                  ∙               ∙
  2637.      │         (Largest/Indefinite)    1            00...00
  2638.      └────────────────────────────────────────────────────────────
  2639.                                      Word:        ───15 bits───
  2640.                                      Short:       ───31 bits───
  2641.                                      Long:        ───63 bits───
  2642.  
  2643.  
  2644.  Table 3-7. Packed Decimal Encodings
  2645.  
  2646. ╓┌──────────────────────────┌───────────────┌────────────────────────────────
  2647.  
  2648.  
  2649.                                             ┌─────────────────── Magnitude ───
  2650.              Class          Sign             digit      digit      digit
  2651.      ┌────────────────────────────────────────────────────────────────────────
  2652.      │       (Largest)      0       0000000  1 0 0 1    1 0 0 1    1 0 0 1
  2653.      │                      ∙          ∙                              ∙
  2654.      │                      ∙          ∙                              ∙
  2655.  Positives                  ∙          ∙                              ∙
  2656.      │       (Smallest)     0       0000000  0 0 0 0    0 0 0 0    0 0 0 0
  2657.      │
  2658.      │       Zero           0       0000000  0 0 0 0    0 0 0 0    0 0 0 0
  2659.      └────────────────────────────────────────────────────────────────────────
  2660.      ┌────────────────────────────────────────────────────────────────────────
  2661.      │       Zero           1       0000000  0 0 0 0    0 0 0 0    0 0 0 0
  2662.      │
  2663.      │       (Smallest)     1       0000000  0 0 0 0    0 0 0 0    0 0 0 0
  2664.  Negatives                  ∙          ∙                              ∙
  2665.      │                      ∙          ∙                              ∙
  2666.      │                      ∙          ∙                              ∙
  2667.      │       (Largest)      1       0000000  1 0 0 1    1 0 0 1    1 0 0 1
  2668.      └────────────────────────────────────────────────────────────────────────
  2669.  
  2670.                                             ┌─────────────────── Magnitude ───
  2671.              Class          Sign             digit      digit      digit
  2672.     └────────────────────────────────────────────────────────────────────────
  2673.         Indefinite         1       1111111  1 1 1 1    1 1 1 1    U U U U
  2674.                             ──── 1 byte ───  ──────────────────────── 9 bytes
  2675.  
  2676.  
  2677.  Table 3-8. Single and Double Real Encodings
  2678.  
  2679. ╓┌───────────────────────────────┌────────┌───────────┌──────────────────────╖
  2680.                                            Biased      Significand
  2681.              Class                Sign     Exponent    ff--ff
  2682.  
  2683.  
  2684.  
  2685.     ┌──────┬───────────────────────────────────────────────────────
  2686.     │      │           Quiet       0       11...11     11...11
  2687.     │      │                                  ∙           ∙
  2688.     │      │                                  ∙           ∙
  2689.     │      │                                  ∙           ∙
  2690.                                            Biased      Significand
  2691.              Class                Sign     Exponent    ff--ff
  2692.    │      │                                  ∙           ∙
  2693.     │      │                       0       11...11     10...00
  2694.     │    NaNs        ──────────────────────────────────────────────
  2695.     │      │           Signaling   0       11...11     01...11
  2696.     │      │                                  ∙           ∙
  2697.     │      │                                  ∙           ∙
  2698.     │      │                                  ∙           ∙
  2699.     │      │                       0       11...11     00...01
  2700.     │      └───────────────────────────────────────────────────────
  2701.     │                  ∞           0       11...11     00...00
  2702.     │      ┌───────────────────────────────────────────────────────
  2703.     │      │           Normals     0       11...10     11...11
  2704.     │      │                                  ∙           ∙
  2705.  Positives │                                  ∙           ∙
  2706.     │      │                                  ∙           ∙
  2707.     │      │                       0       00...01     00...00
  2708.     │      │         ──────────────────────────────────────────────
  2709.     │    Reals         Denormals   0       00...00     11...11
  2710.     │      │                                  ∙           ∙
  2711.                                            Biased      Significand
  2712.              Class                Sign     Exponent    ff--ff
  2713.    │      │                                  ∙           ∙
  2714.     │      │                                  ∙           ∙
  2715.     │      │                                  ∙           ∙
  2716.     │      │                       0       00...00     00...01
  2717.     │      │         ──────────────────────────────────────────────
  2718.     │      │           Zero        0       00...00     00...00
  2719.     └──────────────────────────────────────────────────────────────
  2720.     ┌──────────────────────────────────────────────────────────────
  2721.     │      │           Zero        1       00...00     00...00
  2722.     │      │         ──────────────────────────────────────────────
  2723.     │      │           Denormals   1       00...00     00...01
  2724.     │      │                                  ∙           ∙
  2725.     │      │                                  ∙           ∙
  2726.     │    Reals                                ∙           ∙
  2727.     │      │                       1       00...00     11...11
  2728.     │      │         ──────────────────────────────────────────────
  2729.     │      │           Normals     1       00...01     00...00
  2730.     │      │                                  ∙           ∙
  2731.     │      │                                  ∙           ∙
  2732.                                            Biased      Significand
  2733.              Class                Sign     Exponent    ff--ff
  2734.    │      │                                  ∙           ∙
  2735.     │      │                                  ∙           ∙
  2736.     │      │                       1       11...10     11...11
  2737.  Negatives └───────────────────────────────────────────────────────
  2738.     │                  ∞           1       11...11     00...00
  2739.     │      ┌─────────┬─────────────────────────────────────────────
  2740.     │      │         │             1       11...11     00...01
  2741.     │      │         │                        ∙           ∙
  2742.     │      │    Signaling                     ∙           ∙
  2743.     │      │         │                        ∙           ∙
  2744.     │      │         │             1       11...11     01...11
  2745.     │    NaNs        ├─────────────────────────────────────────────
  2746.     │      │         │ Indefinite  1       11...11     10...00
  2747.     │      │         │    ─────────────────────────────────────────
  2748.     │      │         │                        ∙           ∙
  2749.     │      │      Quiet                       ∙           ∙
  2750.     │      │         │                        ∙           ∙
  2751.     │      │         │             1       11...11     11...11
  2752.     └──────┴─────────┴─────────────────────────────────────────────
  2753.                                            Biased      Significand
  2754.              Class                Sign     Exponent    ff--ff
  2755.    └──────┴─────────┴─────────────────────────────────────────────
  2756.                               Double:  │ ───8 bits── │ ──23 bits── │
  2757.                               Single:  │ ──11 bits── │ ──52 bits── │
  2758.  
  2759.  
  2760.  Table 3-9. Extended Real Encodings
  2761.  
  2762. ╓┌───────────────────────────────────────┌──────────┌────────────────────────╖
  2763.                                          Biased     Significand
  2764.              Class              Sign     Exponent   1.ff--ff
  2765.      ┌──────┬──────────────────────────────────────────────────
  2766.      │      │                    0       11...11    1 11..11
  2767.      │      │     Quiet          ∙          ∙          ∙
  2768.      │      │                    ∙          ∙          ∙
  2769.      │      │                    0       11...11    1 10..01
  2770.      │    NaNs   ───────────────────────────────────────────────
  2771.      │      │                    0       11...11    1 01..11
  2772.      │      │     Signaling      ∙          ∙          ∙
  2773.      │      │                    ∙          ∙          ∙
  2774.                                          Biased     Significand
  2775.              Class              Sign     Exponent   1.ff--ff
  2776.     │      │                    ∙          ∙          ∙
  2777.      │      │                    0       11...11    1 00..01
  2778.      │      └───────────────────────────────────────────────────
  2779.      │         ∞                 0       11...11    1 00..00
  2780.      │      ┌────────────────────────────────────────────────────
  2781.      │      │                    0       11...10    1 11..11
  2782.      │      │     Normals        ∙          ∙          ∙
  2783.      │      │                    ∙          ∙          ∙
  2784.      │      │                    0       00...01    1 00..00
  2785.      │      │    ───────────────────────────────────────────────
  2786.  Positives  │                    0       11...10    0 11..11
  2787.      │    Reals   Unsupported    ∙          ∙          ∙
  2788.      │      │     8087 Unnormals ∙          ∙          ∙
  2789.      │      │                    0       00...01    0 00..00
  2790.      │      │    ───────────────────────────────────────────────
  2791.      │      │                    0       00...00    1 11..11
  2792.      │      │     Pseudo-        ∙          ∙          ∙
  2793.      │      │       normals      ∙          ∙          ∙
  2794.      │      │                    0       00...00    1 00..00
  2795.                                          Biased     Significand
  2796.              Class              Sign     Exponent   1.ff--ff
  2797.     │      │                    0       00...00    1 00..00
  2798.      │      │    ───────────────────────────────────────────────
  2799.      │      │                    0       00...00    0 11..11
  2800.      │      │     Denormals      ∙          ∙          ∙
  2801.      │      │                    ∙          ∙          ∙
  2802.      │      │                    0       00...00    0 00..01
  2803.      │      ├───────────────────────────────────────────────────
  2804.      │      │     Zero           0       00...00    000...00
  2805.      └──────────────────────────────────────────────────────────
  2806.      ┌──────────────────────────────────────────────────────────
  2807.      │      │     Zero           1       00...00    000...00
  2808.      │      ├───────────────────────────────────────────────────
  2809.      │      │                    1       00...00    0 00..01
  2810.      │      │     Denormals      ∙          ∙          ∙
  2811.      │      │                    ∙          ∙          ∙
  2812.      │      │                    1       00...00    0 11..11
  2813.      │      │    ───────────────────────────────────────────────
  2814.      │      │                    1       00...00    1 00..00s
  2815.      │    Reals   Pseudo-        ∙          ∙          ∙
  2816.                                          Biased     Significand
  2817.              Class              Sign     Exponent   1.ff--ff
  2818.     │    Reals   Pseudo-        ∙          ∙          ∙
  2819.      │      │       normals      ∙          ∙          ∙
  2820.      │      │                    1       00...00    1 11..11
  2821.      │      │    ───────────────────────────────────────────────
  2822.      │      │                    1       00...00    0 00..00
  2823.  Negatives  │     Unsupported    ∙          ∙          ∙
  2824.      │      │     8087 Unnormals ∙          ∙          ∙
  2825.      │      │                    1       11...10    0 11..11
  2826.      │      │    ───────────────────────────────────────────────
  2827.      │      │                    1       00...01    1 00..00
  2828.      │      │     Normals        ∙          ∙          ∙
  2829.      │      │                    ∙          ∙          ∙
  2830.      │      │                    1       11...10    1 11..11
  2831.      │      └────────────────────────────────────────────────────
  2832.      │         ∞                 1       11...11    1 00..00
  2833.      │      ┌───┬───────────────────────────────────────────────
  2834.      │      │   │                1       11...11    1 00..01
  2835.      │      │  Signaling         ∙          ∙          ∙
  2836.      │      │   │                ∙          ∙          ∙
  2837.                                          Biased     Significand
  2838.              Class              Sign     Exponent   1.ff--ff
  2839.     │      │   │                ∙          ∙          ∙
  2840.      │      │   │                1       11...11    1 01..11
  2841.      │      │   ├───────────────────────────────────────────────
  2842.      │     NaNs │    Indefinite  1       11...11    110...00
  2843.      │      │   │     ──────────────────────────────────────────
  2844.      │      │   │                1       11...11    1 10..00
  2845.      │      │  Quiet             ∙          ∙          ∙
  2846.      │      │   │                ∙          ∙          ∙
  2847.      │      │   │                1       11...11    1 11..11
  2848.      └──────┴───┴───────────────────────────────────────────────
  2849.                                       │──15 bits──│──64 bits──│
  2850.  
  2851.  
  2852.  3.2  Numeric Exceptions
  2853.  
  2854.  The 80387 can recognize six classes of numeric exception conditions while
  2855.  executing numeric instructions:
  2856.  
  2857.    1.  I── Invalid operation
  2858.            ■  Stack fault
  2859.            ■  IEEE standard invalid operation
  2860.    2.  Z── Divide-by-zero
  2861.    3.  D── Denormalized operand
  2862.    4.  O── Numeric overflow
  2863.    5.  U── Numeric underflow
  2864.    6.  P── Inexact result (precision)
  2865.  
  2866.  
  2867.  3.2.1  Handling Numeric Exceptions
  2868.  
  2869.  When numeric exceptions occur, the NPX takes one of two possible courses of
  2870.  action:
  2871.  
  2872.    ■  The NPX can itself handle the exception, producing the most reasonable
  2873.       result and allowing numeric program execution to continue undisturbed.
  2874.  
  2875.    ■  A software exception handler can be invoked by the CPU to handle the
  2876.       exception.
  2877.  
  2878.  Each of the six exception conditions described above has a corresponding
  2879.  flag bit in the 80387 status word and a mask bit in the 80387 control word.
  2880.  If an exception is masked (the corresponding mask bit in the control
  2881.  word = 1), the 80387 takes an appropriate default action and continues with
  2882.  the computation. If the exception is unmasked (mask = 0), the 80387 asserts
  2883.  the ERROR# output to the 80386 to signal the exception and invoke a software
  2884.  exception handler.
  2885.  
  2886.  Note that when exceptions are masked, the NPX may detect multiple
  2887.  exceptions in a single instruction, because it continues executing the
  2888.  instruction after performing its masked response. For example, the 80387
  2889.  could detect a denormalized operand, perform its masked response to this
  2890.  exception, and then detect an underflow.
  2891.  
  2892.  
  2893.  3.2.1.1  Automatic Exception Handling
  2894.  
  2895.  The 80387 NPX has a default fix-up activity for every possible exception
  2896.  condition it may encounter. These masked-exception responses are designed to
  2897.  be safe and are generally acceptable for most numeric applications.
  2898.  
  2899.  As an example of how even severe exceptions can be handled safely and
  2900.  automatically using the NPX's default exception responses, consider a
  2901.  calculation of the parallel resistance of several values using only the
  2902.  standard formula (Figure 3-3). If R{1} becomes zero, the circuit resistance
  2903.  becomes zero. With the divide-by-zero and precision exceptions masked, the
  2904.  80387 NPX will produce the correct result.
  2905.  
  2906.  By masking or unmasking specific numeric exceptions in the NPX control
  2907.  word, NPX programmers can delegate responsibility for most exceptions to the
  2908.  NPX, reserving the most severe exceptions for programmed exception handlers.
  2909.  Exception-handling software is often difficult to write, and the NPX's
  2910.  masked responses have been tailored to deliver the most reasonable result
  2911.  for each condition. For the majority of applications, masking all
  2912.  exceptions other than invalid-operation yields satisfactory results with the
  2913.  least programming effort. An invalid-operation exception normally indicates
  2914.  a program error that must be corrected; this exception should not normally
  2915.  be masked.
  2916.  
  2917.  The exception flags in the NPX status word provide a cumulative record of
  2918.  exceptions that have occurred since these flags were last cleared. Once set,
  2919.  these flags can be cleared only by executing the FCLEX (clear exceptions)
  2920.  instruction, by reinitializing the NPX, or by overwriting the flags with an
  2921.  FRSTOR or FLDENV instruction. This allows a programmer to mask all
  2922.  exceptions (except invalid operation), run a calculation, and then inspect
  2923.  the status word to see if any exceptions were detected at any point in the
  2924.  calculation.
  2925.  
  2926.  
  2927.  Figure 3-3.  Arithmetic Example Using Infinity
  2928.  
  2929.                             ───┬──────┬──────┐
  2930.                                │      │      │
  2931.                                │      │      │
  2932.                                │      │      │
  2933.                               R{1}   R{2}   R{3}
  2934.                                │      │      │
  2935.                                │      │      │
  2936.                                │      │      │
  2937.                             ───┴──────┴──────┘
  2938.  
  2939.                                                  1
  2940.            EQUIVALENT RESISTANCE = ──────────────────────────────
  2941.                                     1/R{1}  +  1/R{2}  +  1/R{3}
  2942.  
  2943.  
  2944.  3.2.1.2  Software Exception Handling
  2945.  
  2946.  If the NPX encounters an unmasked exception condition, it signals the
  2947.  exception to the 80386 CPU using the ERROR# status line between the two
  2948.  processors.
  2949.  
  2950.  The next time the 80386 CPU encounters a WAIT or ESC instruction in its
  2951.  instruction stream, the 80386 will detect the active condition of the ERROR#
  2952.  status line and automatically trap to an exception response routine using
  2953.  interrupt #16, the "processor extension error" exception.
  2954.  
  2955.  This exception response routine is normally a part of the systems software.
  2956.  Typical exception responses may include:
  2957.  
  2958.    ■  Incrementing an exception counter for later display or printing
  2959.  
  2960.    ■  Printing or displaying diagnostic information (e.g., the 80387
  2961.       environment andregisters)
  2962.  
  2963.    ■  Aborting further execution
  2964.  
  2965.    ■  Using the exception pointers to build an instruction that will run
  2966.       without exception and executing it
  2967.  
  2968.  For 80386 systems having systems software support for the 80387 NPX,
  2969.  applications programmers should consult the operating system's reference
  2970.  manuals for the appropriate system response to NPX exceptions. For systems
  2971.  programmers, specific details on writing software exception handlers are
  2972.  included in Chapter 6.
  2973.  
  2974.  
  2975.  3.2.2  Invalid Operation
  2976.  
  2977.  This exception may occur in response to two general classes of operations:
  2978.  
  2979.    1.  Stack operations
  2980.    2.  Arithmetic operations
  2981.  
  2982.  The stack flag (SF) of the status word indicates which class of operation
  2983.  caused the exception. When SF is 1 a stack operation has resulted in stack
  2984.  overflow or underflow; when SF is 0, an arithmetic instruction has
  2985.  encountered an invalid operand.
  2986.  
  2987.  
  2988.  3.2.2.1  Stack Exception
  2989.  
  2990.  When SF is 1, indicating a stack operation, the O/U# bit of the condition
  2991.  code (bit C{1}) distinguishes between stack overflow and underflow as
  2992.  follows:
  2993.  
  2994.  O/U# = 1   Stack overflow── an instruction attempted to push down a
  2995.             nonempty stack location.
  2996.  
  2997.  O/U# = 0   Stack underflow── an instruction attempted to read an
  2998.             operand from an empty stack location.
  2999.  
  3000.  When the invalid-operation exception is masked, the 80387 returns the QNaN
  3001.  indefinite. This value overwrites the destination register, destroying
  3002.  its original contents.
  3003.  
  3004.  When the invalid-operation exception is not masked, the 80386 exception
  3005.  "processor extension error" is triggered. TOP is not changed, and the source
  3006.  operands remain unaffected.
  3007.  
  3008.  
  3009.  3.2.2.2  Invalid Arithmetic Operation
  3010.  
  3011.  This class includes the invalid operations defined in IEEE Std 754. The
  3012.  80387 reports an invalid operation in any of the cases shown in Table 3-10.
  3013.  Also shown in this table are the 80387's responses when the invalid
  3014.  exception is masked. When unmasked, the 80386 exception "processor extension
  3015.  error" is triggered, and the operands remain unaltered. An invalid operation
  3016.  generally indicates a program error.
  3017.  
  3018.  
  3019.  Table 3-10.  Masked Responses to Invalid Operations
  3020.  
  3021. ╓┌───────────────────────────────────┌───────────────────────────────────────╖
  3022.  Condition                           Masked Response
  3023.  
  3024.  Any arithmetic operation            Return the QNaN indefinite.
  3025.  on an unsupported format.
  3026.  Condition                           Masked Response
  3027. on an unsupported format.
  3028.  
  3029.  Any arithmetic operation            Return a QNaN (refer to the section
  3030.  on a signaling NaN.                 "Rules for Generating QNaNs").
  3031.  
  3032.  Compare and test operations:        Set condition codes "not comparable."
  3033.  one or both operands is a NaN.
  3034.  
  3035.  Addition of opposite-signed         Return the QNaN indefinite.
  3036.  infinities or subtraction of
  3037.  like-signed infinities.
  3038.  
  3039.  Multiplication: ∞ * 0; or 0 * ∞.    Return the QNaN indefinite.
  3040.  
  3041.  Division: ∞ ÷ ∞; or 0 ÷ 0.          Return the QNaN indefinite.
  3042.  
  3043.  Remainder instructions FPREM,       Return the QNaN indefinite; set C{2}.
  3044.  FPREM1 when modulus (divisor)
  3045.  is zero or dividend is ∞.
  3046.  
  3047.  Condition                           Masked Response
  3048. 
  3049.  Trigonometric instructions FCOS,    Return the QNaN indefinite; set  C{2}.
  3050.  FPTAN, FSIN, FSINCOS when
  3051.  argument is ∞.
  3052.  
  3053.  FSQRT of negative operand (except   Return the QNaN indefinite.
  3054.  FSQRT (-0) = -0), FYL2X of
  3055.  negative operand (except FYL2X
  3056.  (-0) = -∞), FYL2XP1 of operand
  3057.  more negative than -1.
  3058.  
  3059.  FIST(P) instructions when source    Store integer indefinite.
  3060.  register is empty, a NaN, ∞,
  3061.  or exceeds representable range
  3062.  of destination.
  3063.  
  3064.  FBSTP instruction when source       Store packed decimal indefinite.
  3065.  register is empty, a NaN, ∞, or
  3066.  exceeds 18 decimal digits.
  3067.  
  3068.  Condition                           Masked Response
  3069. 
  3070.  FXCH instruction when one or        Change empty registers to the QNaN
  3071.  both registers are tagged empty.    indefinite and then perform exchange.
  3072.  
  3073.  
  3074.  3.2.3  Division by Zero
  3075.  
  3076.  If an instruction attempts to divide a finite nonzero operand by zero, the
  3077.  80387 will report a zero-divide exception. This is possible for
  3078.  F(I)DIV(R)(P) as well as the other instructions that perform division
  3079.  internally: FYL2X and FXTRACT. The masked response for FDIV and FYL2X is to
  3080.  return an infinity signed with the exclusive OR of the signs of the
  3081.  operands. For FXTRACT, ST(1) is set to -∞; ST is set to zero with the same
  3082.  sign as the original operand. If the divide-by-zero exception is unmasked,
  3083.  the 80386 exception "processor extension error" is triggered; the operands
  3084.  remain unaltered.
  3085.  
  3086.  
  3087.  3.2.4  Denormal Operand
  3088.  
  3089.  If an arithmetic instruction attempts to operate on a denormal operand, the
  3090.  NPX reports the denormal-operand exception. Denormal operands may have
  3091.  reduced significance due to lost low-order bits, therefore it may be
  3092.  advisable in certain applications to preclude operations on these operands.
  3093.  This can be accomplished by an exception handler that responds to unmasked
  3094.  denormal exceptions. Most users will mask this exception so that
  3095.  computation may proceed; any loss of accuracy will be analyzed by the user
  3096.  when the final result is delivered.
  3097.  
  3098.  When this exception is masked, the 80387 sets the D-bit in the status word,
  3099.  then proceeds with the instruction. Gradual underflow and denormal numbers
  3100.  as handled on the 80387 will produce results at least as good as, and often
  3101.  better than what could be obtained from a machine that flushes underflows to
  3102.  zero. In fact, a denormal operand in single- or double-precision format will
  3103.  be normalized to the extended-real format when loaded into the 80387.
  3104.  Subsequent operations will benefit from the additional precision of the
  3105.  extended-real format used internally.
  3106.  
  3107.  When this exception is not masked, the D-bit is set and the exception
  3108.  handler is invoked. The operands are not changed by the instruction and are
  3109.  available for inspection by the exception handler.
  3110.  
  3111.  If an 8087/80287 program uses the denormal exception to automatically
  3112.  normalize denormal operands, then that program can run on an 80387 by
  3113.  masking the denormal exception. The 8087/80287 denormal exception handler
  3114.  would not be used by the 80387 in this case. A numerics program runs faster
  3115.  when the 80387 performs normalization of denormal operands. A program can
  3116.  detect at run-time whether it is running on an 80387 or 8087/80287 and
  3117.  disable the denormal exception when an 80387 is used. The following code
  3118.  sequence is recommended to distinguish between an 80387 and an 8087/80287.
  3119.  
  3120.        FINIT              ; Use default infinity mode:
  3121.                           ;  projective for 8087/80287,
  3122.                           ;  affine for 80387
  3123.        FLD1               ; Generate infinty
  3124.        FLDZ
  3125.        FDIV
  3126.        FLD    ST
  3127.                           ; Form negative infinity
  3128.        FCHS
  3129.        FCOMPP             ; Compare +infinity with -infinity
  3130.        FSTSW  temp        ; 8087/80287 will say they are equal
  3131.        MOV    AX, temp
  3132.        SAHF
  3133.        JNZ    Using_80387
  3134.  
  3135.  The denormal-operand exception of the 80387 permits emulation of arithmetic
  3136.  on unnormal operands as provided by the 8087/80287. The standard does not
  3137.  require the denormal exception nor does it recognize the unnormal data type.
  3138.  
  3139.  
  3140.  3.2.5  Numeric Overflow and Underflow
  3141.  
  3142.  If the exponent of a numeric result is too large for the destination real
  3143.  format, the 80387 signals a numeric overflow. Conversely, if the exponent of
  3144.  a result is too small to be represented in the destination format, a numeric
  3145.  underflow is signaled. If either of these exceptions occur, the result of
  3146.  the operation is outside the range of the destination real format.
  3147.  
  3148.  Typical algorithms are most likely to produce extremely large and small
  3149.  numbers in the calculation of intermediate, rather than final, results.
  3150.  Because of the great range of the extended-precision format (recommended as
  3151.  the destination format for intermediates), overflow and underflow are
  3152.  relatively rare events in most 80387 applications.
  3153.  
  3154.  
  3155.  3.2.5.1  Overflow
  3156.  
  3157.  The overflow exception can occur whenever the rounded true result would
  3158.  exceed in magnitude the largest finite number in the destination format. The
  3159.  exception can occur in the execution of most of the arithmetic instructions
  3160.  and in some of the conversion instructions; namely, FST(P), F(I)ADD(P),
  3161.  F(I)SUB(R)(P), F(I)MUL(P), FDIV(R)(P), FSCALE, FYL2X, and FYL2XP1.
  3162.  
  3163.  The response to an overflow condition depends on whether the overflow
  3164.  exception is masked:
  3165.  
  3166.    ■  Overflow exception masked. The value returned depends on the rounding
  3167.       mode as Table 3-11 illustrates.
  3168.  
  3169.    ■  Overflow exception not masked. The unmasked response depends on
  3170.       whether the instruction is supposed to store the result on the stack
  3171.       or in memory:
  3172.  
  3173.       ── Destination is the stack. The true result is divided by 2^(24,576)
  3174.          and rounded. (The bias 24,576 is equal to 3 * 2^(13).) The
  3175.          significand is rounded to the appropriate precision (according to
  3176.          the precision control (PC) bit of the control word, for those
  3177.          instructions controlled by PC, otherwise to extended precision).
  3178.          The roundup bit (C{1}) of the status word is set if the
  3179.          significand was rounded upward.
  3180.  
  3181.          The biasing of the exponent by 24,576 normally translates the
  3182.          number as nearly as possible to the middle of the exponent range
  3183.          so that, if desired, it can be used in subsequent scaled
  3184.          operations with less risk of causing further exceptions. With the
  3185.          instruction FSCALE, however, it can happen that the result is too
  3186.          large and overflows even after biasing. In this case, the unmasked
  3187.          response is exactly the same as the masked round-to-nearest
  3188.          response, namely ± infinity. The intention of this feature is to
  3189.          ensure the trap handler will discover that a translation of the
  3190.          exponent by -24574 would not work correctly without obliging the
  3191.          programmer of Decimal-to-Binary or Exponential functions to
  3192.          determine which trap handler, if any, should be invoked.
  3193.  
  3194.       ── Destination is memory (this can occur only with the store
  3195.          instructions). No result is stored in memory. Instead, the operand
  3196.          is left intact in the stack. Because the data in the stack is in
  3197.          extended-precision format, the exception handler has the option
  3198.          either of reexecuting the store instruction after proper
  3199.          adjustment of the operand or of rounding the significand on the
  3200.          stack to the destination's precision as the standard requires. The
  3201.          exception handler should ultimately store a value into the
  3202.          destination location in memory if the program is to continue.
  3203.  
  3204.  
  3205.  Table 3-11.  Masked Overflow Results
  3206.  
  3207.  Rounding              Sign of
  3208.  Mode                True Result         Result
  3209.  
  3210.  To nearest               +               +∞
  3211.                           -               -∞
  3212.  Toward -∞                +               Largest finite positive number
  3213.                           -               -∞
  3214.  Toward +∞                +               +∞
  3215.                           -               Largest finite negative number
  3216.  Toward zero              +               Largest finite positive number
  3217.                           -               Largest finite negative number
  3218.  
  3219.  
  3220.  3.2.5.2  Underflow
  3221.  
  3222.  Underflow can occur in the execution of the instructions FST(P), FADD(P),
  3223.  FSUB(RP), FMUL(P), F(I)DIV(RP), FSCALE, FPREM(1), FPTAN, FSIN, FCOS,
  3224.  FSINCOS, FPATAN, F2XM1, FYL2X, and FYL2XP1.
  3225.  
  3226.  Two related events contribute to underflow:
  3227.  
  3228.    1.  Creation of a tiny result which, because it is so small, may cause
  3229.        some other exception later (such as overflow upon division).
  3230.  
  3231.    2.  Creation of an inexact result; i.e. the delivered result differs from
  3232.        what would have been computed were both the exponent range and
  3233.        precision unbounded.
  3234.  
  3235.  Which of these events triggers the underflow exception depends on whether
  3236.  the underflow exception is masked:
  3237.  
  3238.    1.  Underflow exception masked. The underflow exception is signaled when
  3239.        the result is both tiny and inexact.
  3240.  
  3241.    2.  Underflow exception not masked. The underflow exception is signaled
  3242.        when the result is tiny, regardless of inexactness.
  3243.  
  3244.  The response to an underflow exception also depends on whether the
  3245.  exception is masked:
  3246.  
  3247.    1.  Masked response. The result is denormal or zero. The precision
  3248.        exception is also triggered.
  3249.  
  3250.    2.  Unmasked response. The unmasked response depends on whether the
  3251.        instruction is supposed to store the result on the stack or in memory:
  3252.  
  3253.        ■  Destination is the stack. The true result is multiplied by
  3254.           2^(24,576) and rounded. (The bias 24,576 is equal to 3 * 2^(13).)
  3255.           The significand is rounded to the appropriate precision (according
  3256.           to the precision control (PC) bit of the control word, for those
  3257.           instructions controlled by PC, otherwise to extended precision).
  3258.           The roundup bit (C{1}) of the status word is set if the significand
  3259.           was rounded upward.
  3260.  
  3261.           The biasing of the exponent by 24,576 normally translates the
  3262.           number as nearly as possible to the middle of the exponent range so
  3263.           that, if desired, it can be used in subsequent scaled operations
  3264.           with less risk of causing further exceptions. With the instruction
  3265.           FSCALE, however, it can happen that the result is too tiny and
  3266.           underflows even after biasing. In this case, the unmasked response
  3267.           is exactly the same as the masked round-to-nearest response, namely
  3268.           ±0. The intention of this feature is to ensure the trap handler
  3269.           will discover that a translation by +24576 would not work correctly
  3270.           without obliging the programmer of Decimal-to-Binary or Exponential
  3271.           functions to determine which trap handler, if any, should be
  3272.           invoked.
  3273.  
  3274.        ■  Destination is memory (this can occur only with the store
  3275.           instructions). No result is stored in memory. Instead, the operand
  3276.           is left intact in the stack. Because the data in the stack is in
  3277.           extended-precision format, the exception handler has the option
  3278.           either of reexecuting the store instruction after proper adjustment
  3279.           of the operand or of rounding the significand on the stack to the
  3280.           destination's precision as the standard requires. The exception
  3281.           handler should ultimately store a value into the destination
  3282.           location in memory if the program is to continue.
  3283.  
  3284.  
  3285.  3.2.6  Inexact (Precision)
  3286.  
  3287.  This exception condition occurs if the result of an operation is not
  3288.  exactly representable in the destination format. For example, the fraction
  3289.  1/3 cannot be precisely represented in binary form. This exception occurs
  3290.  frequently and indicates that some (generally acceptable) accuracy has been
  3291.  lost.
  3292.  
  3293.  All the transcendental instructions are inexact by definition; they always
  3294.  cause the inexact exception.
  3295.  
  3296.  The C{1} (roundup) bit of the status word indicates whether the inexact
  3297.  result was rounded up (C{1} = 1) or chopped (C{1} = 0).
  3298.  
  3299.  The inexact exception accompanies the underflow exception when there is
  3300.  also a loss of accuracy. When underflow is masked, the underflow exception
  3301.  is signaled only when there is a loss of accuracy; therefore the precision
  3302.  flag is always set as well. When underflow is unmasked, there may or may not
  3303.  have been a loss of accuracy; the precision bit indicates which is the case.
  3304.  
  3305.  This exception is provided for applications that need to perform exact
  3306.  arithmetic only. Most applications will mask this exception. The 80387
  3307.  delivers the rounded or over/underflowed result to the destination,
  3308.  regardless of whether a trap occurs.
  3309.  
  3310.  
  3311.  3.2.7  Exception Priority
  3312.  
  3313.  The 80387 deals with exceptions according to a predetermined precedence.
  3314.  Precedence in exception handling means that higher-priority exceptions are
  3315.  flagged and results are delivered according to the requirements of that
  3316.  exception. Lower-priority exceptions may not be flagged even if they occur.
  3317.  For example, dividing an SNaN by zero causes an invalid-operand exception
  3318.  (due to the SNaN) and not a zero-divide exception; the masked result is the
  3319.  QNaN real indefinite, not ∞. A denormal or inexact (precision) exception,
  3320.  however, can accompany a numeric underflow or overflow exception.
  3321.  
  3322.  The exception precedence is as follows:
  3323.  
  3324.    1.  Invalid operation exception, subdivided as follows:
  3325.  
  3326.        a. Stack underflow.
  3327.        b. Stack overflow.
  3328.        c. Operand of unsupported format.
  3329.        d. SNaN operand.
  3330.  
  3331.    2.  QNaN operand. Though this is not an exception, if one operand is a
  3332.        QNaN, dealing with it has precedence over lower-priority exceptions.
  3333.        For example, a QNaN divided by zero results in a QNaN, not a
  3334.        zero-divide exception.
  3335.  
  3336.    3.  Any other invalid-operation exception not mentioned above or zero
  3337.        divide.
  3338.  
  3339.    4.  Denormal operand. If masked, then instruction execution continues,
  3340.        and a lower-priority exception can occur as well.
  3341.  
  3342.    5.  Numeric overflow and underflow. Inexact result (precision) can be
  3343.        flagged as well.
  3344.  
  3345.    6.  Inexact result (precision).
  3346.  
  3347.  
  3348.  3.2.8  Standard Underflow/Overflow Exception Handler
  3349.  
  3350.  As long as the underflow and overflow exceptions are masked, no additional
  3351.  software is required to cause the output of the 80387 to conform to the
  3352.  requirements of IEEE Std 754. When unmasked, these exceptions give the
  3353.  exception handler an additional option in the case of store instructions. No
  3354.  result is stored in memory; instead, the operand is left intact on the
  3355.  stack. The handler may round the significand of the operand on the stack to
  3356.  the destination's precision as the standard requires, or it may adjust the
  3357.  operand and reexecute the faulting instruction.
  3358.  
  3359.  
  3360.  
  3361.  Chapter 4  The 80387 Instruction Set
  3362.  
  3363.  ───────────────────────────────────────────────────────────────────────────
  3364.  
  3365.  This chapter describes the operation of all 80387 instructions. Within this
  3366.  section, the instructions are divided into six functional classes:
  3367.  
  3368.    ■  Data Transfer instructions
  3369.    ■  Nontranscendental instructions
  3370.    ■  Comparison instructions
  3371.    ■  Transcendental instructions
  3372.    ■  Constant instructions
  3373.    ■  Processor Control instructions
  3374.  
  3375.  Throughout this chapter, the instruction set is described as it appears to
  3376.  the ASM386 programmer who is coding a program. Not included in this chapter
  3377.  are details of instruction format, encoding, and execution times. This
  3378.  detailed information may be found in Appendix A. Refer also to Appendix B
  3379.  for a summary of the exceptions caused by each instruction.
  3380.  
  3381.  
  3382.  4.1  Compatibility With the 80287 and 8087
  3383.  
  3384.  The instruction set for the 80387 NPX is largely the same as that for the
  3385.  80287 NPX (used with 80286 systems) and that for the 8087 NPX (used with
  3386.  8086 and 8088 systems). Most object programs generated for the 80287 or 8087
  3387.  will execute without change on the 80387. Several instructions are new to
  3388.  the 80387, and several 80287 and 8087 instructions perform no useful
  3389.  function on the 80387. Appendix C and Appendix D give details of these
  3390.  instruction set differences.
  3391.  
  3392.  
  3393.  4.2  Numeric Operands
  3394.  
  3395.  The typical NPX instruction accepts one or two operands as inputs, operates
  3396.  on these, and produces a result as an output. An operand is most often the
  3397.  contents of a register or of a memory location. The operands of some
  3398.  instructions are predefined; for example, FSQRT always takes the square root
  3399.  of the number in the top NPX stack element. Others allow, or require, the
  3400.  programmer to explicitly code the operand(s) along with the instruction
  3401.  mnemonic. Still others accept one explicit operand and one implicit
  3402.  operand, which is usually the top NPX stack element. All 80387 instructions
  3403.  that have a data operand use ST as one operand or as the only operand.
  3404.  
  3405.  Whether supplied by the programmer or utilized automatically, the two basic
  3406.  types of operands are sources and destinations. A source operand simply
  3407.  supplies one of the inputs to an instruction; it is not altered by the
  3408.  instruction. Even when an instruction converts the source operand from one
  3409.  format to another (e.g., real to integer), the conversion is actually
  3410.  performed in an internal work area to avoid altering the source operand. A
  3411.  destination operand may also provide an input to an instruction. It is
  3412.  distinguished from a source operand, however, because its content may be
  3413.  altered when it receives the result produced by the operation; that is, the
  3414.  destination is replaced by the result.
  3415.  
  3416.  Many instructions allow their operands to be coded in more than one way.
  3417.  For example, FADD (add real) may be written without operands, with only a
  3418.  source or with a destination and a source. The instruction descriptions in
  3419.  this section employ the simple convention of separating alternative operand
  3420.  forms with slashes; the slashes, however, are not coded. Consecutive slashes
  3421.  indicate an option of no explicit operands. The operands for FADD are thus
  3422.  described as
  3423.  
  3424.    //source/destination, source
  3425.  
  3426.  This means that FADD may be written in any of three ways:
  3427.  
  3428.  Written Form               Action
  3429.  
  3430.  FADD                       Add ST to ST(1), put result in ST(1), then pop ST
  3431.  FADD source                Add source to ST(0)
  3432.  FADD destination, source   Add source to destination
  3433.  
  3434.  The assembler can allow the same instruction to be specified in different
  3435.  ways; for example:
  3436.  
  3437.  FADD = FADDP ST(1), ST
  3438.  FADD ST(1) = FADD ST, ST(1)
  3439.  
  3440.  When reading this section, it is important to bear in mind that memory
  3441.  operands may be coded with any of the CPU's memory addressing methods
  3442.  provided by the ModR/M byte. To review these methods (BASE + (INDEX * SCALE)
  3443.  + DISPLACEMENT) refer to the 80386 Programmer's Reference Manual.
  3444.  Chapter 5 also provides several addressing mode examples.
  3445.  
  3446.  
  3447.  4.3  Data Transfer Instructions
  3448.  
  3449.  These instructions (summarized in Table 4-1) move operands among elements
  3450.  of the register stack, and between the stack top and memory. Any of the
  3451.  seven data types can be converted to extended real and loaded (pushed) onto
  3452.  the stack in a single operation; they can be stored to memory in the same
  3453.  manner. The data transfer instructions automatically update the 80387 tag
  3454.  word to reflect whether the register is empty or full following the
  3455.  instruction.
  3456.  
  3457.  Table 4-1.  Data Transfer Instructions
  3458.  
  3459.  Real Transfers
  3460.  FLD          Load Real
  3461.  FST          Store real
  3462.  FSTP         Store real and pop
  3463.  FXCH         Exchange registers
  3464.  Integer Transfers
  3465.  FILD         Integer load
  3466.  FIST         Integer store
  3467.  FISTP        Integer store and pop
  3468.  Packed Decimal Transfers
  3469.  FBLD         Packed decimal (BCD) load
  3470.  FBSTP        Packed decimal (BCD) store and pop
  3471.  
  3472.  
  3473.  4.3.1  FLD source
  3474.  
  3475.  FLD (load real) loads (pushes) the source operand onto the top of the
  3476.  register stack. This is done by decrementing the stack pointer by one and
  3477.  then copying the content of the source to the new stack top. ST(7) must be
  3478.  empty to avoid causing an invalid-operation exception. The new stack top is
  3479.  tagged nonempty. The source may be a register on the stack (ST(i)) or any of
  3480.  the real data types in memory. If the source is a register, the register
  3481.  number used is that before TOP is decremented by the instruction. Coding FLD
  3482.  ST(0) duplicates the stack top. Single and double real source operands are
  3483.  converted to extended real automatically. Loading an extended real operand
  3484.  does not require conversion; therefore, the I and D exceptions do not occur
  3485.  in this case.
  3486.  
  3487.  
  3488.  4.3.2  FST destination
  3489.  
  3490.  FST (store real) copies the NPX stack top to the destination, which
  3491.  may be another register on the stack or a single or double (but not
  3492.  extended-precision) memory operand. If the destination is single or double
  3493.  real, the copy of the significand is rounded to the width of the destination
  3494.  according to the RC field of the control word, and the copy of the exponent
  3495.  is converted to the width and bias of the destination format. The
  3496.  over/underflow condition is checked for as well.
  3497.  
  3498.  If, however, the stack top contains zero, ±∞, or a NaN, then the stack
  3499.  top's significand is not rounded but is chopped (on the right) to fit the
  3500.  destination. Neither is the exponent converted, rather it also is chopped on
  3501.  the right and transferred "as is". This preserves the value's identification
  3502.  as ∞ or a NaN (exponent all ones) so that it can be properly loaded and used
  3503.  later in the program if desired.
  3504.  
  3505.  Note that the 80387 does not signal the invalid-operation exception when
  3506.  the destination is a nonempty stack element.
  3507.  
  3508.  
  3509.  4.3.3  FSTP destination
  3510.  
  3511.  FSTP (store real and pop) operates identically to FST except that the NPX
  3512.  stack is popped following the transfer. This is done by tagging the top
  3513.  stack element empty and then incrementing TOP. FSTP also permits storing to
  3514.  an extended-precision real memory variable, whereas FST does not. If the
  3515.  source operand is a register, the register number used is that before TOP is
  3516.  incremented by the instruction. Coding FSTP ST(0) is equivalent to popping
  3517.  the stack with no data transfer.
  3518.  
  3519.  
  3520.  4.3.4  FXCH //destination
  3521.  
  3522.  FXCH (exchange registers) swaps the contents of the destination and the
  3523.  stack top registers. If the destination is not coded explicitly, ST(1) is
  3524.  used. Many 80387 instructions operate only on the stack top; FXCH provides a
  3525.  simple means of effectively using these instructions on lower stack
  3526.  elements. For example, the following sequence takes the square root of the
  3527.  third register from the top (assuming that ST is nonempty):
  3528.  
  3529.  FXCH ST(3)
  3530.  FSQRT
  3531.  FXCH ST(3)
  3532.  
  3533.  
  3534.  4.3.5  FILD source
  3535.  
  3536.  FILD (integer load) converts the source memory operand from its binary
  3537.  integer format (word, short, or long) to extended real and pushes the result
  3538.  onto the NPX stack. ST(7) must be empty to avoid causing an exception. The
  3539.  (new) stack top is tagged nonempty. FILD is an exact operation; the source
  3540.  is loaded with no rounding error.
  3541.  
  3542.  
  3543.  4.3.6  FIST destination
  3544.  
  3545.  FIST (integer store) stores the content of the stack top to an integer
  3546.  according to the RC field (rounding control) of the control word and
  3547.  transfers the result to the destination, leaving the stack top unchanged.
  3548.  The destination may define a word or short integer variable. Negative zero
  3549.  is stored in the same encoding as positive zero: 0000...00.
  3550.  
  3551.  
  3552.  4.3.7  FISTP destination
  3553.  
  3554.  FISTP (integer and pop) operates like FIST except that it also pops the NPX
  3555.  stack following the transfer. The destination may be any of the binary
  3556.  integer data types.
  3557.  
  3558.  
  3559.  4.3.8  FBLD source
  3560.  
  3561.  FBLD (packed decimal (BCD) load) converts the content of the source operand
  3562.  from packed decimal to extended real and pushes the result onto the NPX
  3563.  stack. ST(7) must be empty to avoid causing an exception. The sign of the
  3564.  source is preserved, including the case where the value is negative zero.
  3565.  FBLD is an exact operation; the source is loaded with no rounding error.
  3566.  
  3567.  The packed decimal digits of the source are assumed to be in the range 0-9.
  3568.  The instruction does not check for invalid digits (A-FH), and the result of
  3569.  attempting to load an invalid encoding is undefined.
  3570.  
  3571.  
  3572.  4.3.9  FBSTP destination
  3573.  
  3574.  FBSTP (packed decimal (BCD) store and pop) converts the content of the
  3575.  stack top to a packed decimal integer, stores the result at the destination
  3576.  in memory, and pops the stack. FBSTP rounds a nonintegral value according to
  3577.  the RC (rounding control) field of the control word.
  3578.  
  3579.  
  3580.  4.4  Nontranscendental Instructions
  3581.  
  3582.  The 80387's nontranscendental instruction set (Table 4-2) provides a wealth
  3583.  of variations on the basic add, subtract, multiply, and divide operations,
  3584.  and a number of other useful functions. These range from a simple absolute
  3585.  value to a square root instruction that executes faster than ordinary
  3586.  division; 80387 programmers no longer need to spend valuable time
  3587.  eliminating square roots from algorithms because they run too slowly. Other
  3588.  nontranscendental instructions perform exact modulo division, round real
  3589.  numbers to integers, and scale values by powers of two.
  3590.  
  3591.  The 80387's basic nontranscendental instructions (addition, subtraction,
  3592.  multiplication, and division) are designed to encourage the development of
  3593.  very efficient algorithms. In particular, they allow the programmer to
  3594.  reference memory as easily as the NPX register stack.
  3595.  
  3596.  Table 4-3 summarizes the available operation/operand forms that are
  3597.  provided for basic arithmetic. In addition to the four normal operations,
  3598.  two "reversed" instructions make subtraction and division "symmetrical" like
  3599.  addition and multiplication. The variety of instruction and operand forms
  3600.  give the programmer unusual flexibility:
  3601.  
  3602.    ■  Operands may be located in registers or memory.
  3603.  
  3604.    ■  Results may be deposited in a choice of registers.
  3605.  
  3606.    ■  Operands may be a variety of NPX data types: extended real, double
  3607.       real, single real, short integer or word integer, with automatic
  3608.       conversion to extended real performed by the 80387.
  3609.  
  3610.  Five basic instruction forms may be used across all six operations, as
  3611.  shown in Table 4-3. The classical stack form may be used to make the 80387
  3612.  operate like a classical stack machine. No operands are coded in this form,
  3613.  only the instruction mnemonic. The NPX picks the source operand from the
  3614.  stack top and the destination from the next stack element. It then pops the
  3615.  stack, performs the operation, and returns the result to the new stack top,
  3616.  effectively replacing the operands by the result.
  3617.  
  3618.  The register form is a generalization of the classical stack form; the
  3619.  programmer specifies the stack top as one operand and any register on the
  3620.  stack as the other operand. Coding the stack top as the destination provides
  3621.  a convenient way to access a constant, held elsewhere in the stack, from the
  3622.  stack top. The destination need not always be ST, however. All two operand
  3623.  instructions allow use of another register as the destination. This coding
  3624.  (ST is the source operand) allows, for example, adding the stack top into a
  3625.  register used as an accumulator.
  3626.  
  3627.  Often the operand in the stack top is needed for one operation but then is
  3628.  of no further use in the computation. The register pop form can be used to
  3629.  pick up the stack top as the source operand, and then discard it by popping
  3630.  the stack. Coding operands of ST(1), ST with a register pop mnemonic is
  3631.  equivalent to a classical stack operation: the top is popped and the result
  3632.  is left at the new top.
  3633.  
  3634.  The two memory forms increase the flexibility of the 80387's
  3635.  nontranscendental instructions. They permit a real number or a binary
  3636.  integer in memory to be used directly as a source operand. This is useful in
  3637.  situations where operands are not used frequently enough to justify holding
  3638.  them in registers. Note that any memory addressing method may be used to
  3639.  define these operands, so they may be elements in arrays, structures, or
  3640.  other data organizations, as well as simple scalars.
  3641.  
  3642.  The six basic operations are discussed further in the next paragraphs, and
  3643.  descriptions of the remaining seven operations follow.
  3644.  
  3645.  
  3646.  Table 4-2.  Nontranscendental Instructions
  3647.  
  3648.  Addition
  3649.  FADD              Add real
  3650.  FADDP             Add real and pop
  3651.  FIADD             Integer add
  3652.  
  3653.  Subtraction
  3654.  FSUB              Subtract real
  3655.  FSUBP             Subtract real and pop
  3656.  FISUB             Integer subtract
  3657.  FSUBR             Subtract real reversed
  3658.  FSUBRP            Subtract real reversed and pop
  3659.  FISUBR            Integer subtract reversed
  3660.  
  3661.  Multiplication
  3662.  FMUL              Multiply real
  3663.  FMULP             Multiply real and pop
  3664.  FIMUL             Integer multiply
  3665.  
  3666.  Division
  3667.  FDIV              Divide real
  3668.  FDIVP             Divide real and pop
  3669.  FIDIV             Integer divide
  3670.  FDIVR             Divide real reversed
  3671.  FDIVRP            Divide real reversed and pop
  3672.  FIDIVR            Integer divide reversed
  3673.  
  3674.  Other Operations
  3675.  FSQRT             Square root
  3676.  FSCALE            Scale
  3677.  FPREM             Partial remainder
  3678.  FPREM1            IEEE standard partial remainder
  3679.  FRNDINT           Round to integer
  3680.  FXTRACT           Extract exponent and significand
  3681.  FABS              Absolute value
  3682.  FCHS              Change sign
  3683.  
  3684.  
  3685.  Table 4-3.  Basic Nontranscendental Instructions and Operands
  3686.  
  3687.  Instruction Form           Mnemonic  Operand Forms
  3688.                             Form      destination, source    ASM386 Example
  3689.  
  3690.  Classical stack            Fop       [ST(1), ST]            FADD
  3691.  Classical stack, extra pop FopP      [ST(1), ST]            FADDP
  3692.  Register                   Fop       ST(i), ST or ST, ST(i) FSUB   ST, ST(3)
  3693.  Register pop               FopP      ST(i), ST              FMULP  ST(2), ST
  3694.  Real memory                Fop       [ST,] single/double    FDIV   AZIMUTH
  3695.  Integer memory             FIop      [ST,] word-integer/    FIDIV  PULSES
  3696.                                             short-integer
  3697.  
  3698.  ───────────────────────────────────────────────────────────────────────────
  3699.  NOTES
  3700.    Brackets ([]) surround implicit operands; these are not coded, and are
  3701.    shown here for information only.
  3702.  
  3703.    op=              ADD    destination  destination + source
  3704.                     SUB    destination  destination - source
  3705.                     SUBR   destination  source - destination
  3706.                     MUL    destination  destination * source
  3707.                     DIV    destination  destination ÷ source
  3708.                     DIVR   destination  source ÷ destination
  3709.  ───────────────────────────────────────────────────────────────────────────
  3710.  
  3711.  
  3712.  4.4.1  Addition
  3713.  
  3714.  FADD     //source/destination,source
  3715.  FADDP    //destination,source
  3716.  FIADD    source
  3717.  
  3718.  The addition instructions (add real, add real and pop, integer add) add the
  3719.  source and destination operands and return the sum to the destination. The
  3720.  operand at the stack top may be doubled by coding:
  3721.  
  3722.  FADD ST, ST(0)
  3723.  
  3724.  If the source operand is in memory, conversion of an integer, a single
  3725.  real, or a double real operand to extended real is performed automatically.
  3726.  
  3727.  
  3728.  4.4.2  Normal Subtraction
  3729.  
  3730.  FSUB     //source/destination,source
  3731.  FSUBP    //destination,source
  3732.  FISUB    source
  3733.  
  3734.  The normal subtraction instructions (subtract real, subtract real and pop,
  3735.  integer subtract) subtract the source operand from the destination and
  3736.  return the difference to the destination.
  3737.  
  3738.  
  3739.  4.4.3  Reversed Subtraction
  3740.  
  3741.  FSUBR    //source/destination,source
  3742.  FSUBRP   //destination,source
  3743.  FISUBR   source
  3744.  
  3745.  The reversed subtraction instructions (subtract real reversed, subtract
  3746.  real reversed and pop, integer subtract reversed) subtract the destination
  3747.  from the source and return the difference to the destination. For example,
  3748.  FSUBR ST, ST(1) means subtract ST from ST(1) and leave the result in ST.
  3749.  
  3750.  
  3751.  4.4.4  Multiplication
  3752.  
  3753.  FMUL     //source/destination,source
  3754.  FMULP    //destination,source
  3755.  FIMUL    source
  3756.  
  3757.  The multiplication instructions (multiply real, multiply real and pop,
  3758.  integer multiply) multiply the source and destination operands and return
  3759.  the product to the destination. Coding FMUL ST, ST(0) squares the content of
  3760.  the stack top.
  3761.  
  3762.  
  3763.  4.4.5  Normal Division
  3764.  
  3765.  FDIV     //source/destination,source
  3766.  FDIVP    //destination,source
  3767.  FIDIV    source
  3768.  
  3769.  The normal division instructions (divide real, divide real and pop, integer
  3770.  divide) divide the destination by the source and return the quotient to the
  3771.  destination.
  3772.  
  3773.  
  3774.  4.4.6  Reversed Division
  3775.  
  3776.  FDIVR    //source/destination,source
  3777.  FDIVRP   //destination,source
  3778.  FIDIVR   source
  3779.  
  3780.  The reversed division instructions (divide real reversed, divide real
  3781.  reversed and pop, integer divide reversed) divide the source operand by the
  3782.  destination and return the quotient to the destination.
  3783.  
  3784.  
  3785.  4.4.7  FSQRT
  3786.  
  3787.  FSQRT (square root) replaces the content of the top stack element with its
  3788.  square root. (Note: The square root of -0 is defined to be -0.)
  3789.  
  3790.  
  3791.  4.4.8  FSCALE
  3792.  
  3793.  FSCALE (scale) interprets the value contained in ST(1) as an integer and
  3794.  adds this value to the exponent of the number in ST. This is equivalent to
  3795.  
  3796.  ST  ST * 2^(ST(1))
  3797.  
  3798.  Thus, FSCALE provides rapid multiplication or division by integral powers
  3799.  of 2. It is particularly useful for scaling the elements of a vector.
  3800.  
  3801.  There is no limit on the range of the scale factor in ST(1). If the value
  3802.  is not integral, FSCALE uses the nearest integer smaller in magnitude; i.e.,
  3803.  it chops the value toward 0. If the resulting integer is zero, the value in
  3804.  ST is not changed.
  3805.  
  3806.  
  3807.  4.4.9  FPREM ── Partial Remainder (80287/8087-Compatible)
  3808.  
  3809.  FPREM computes the remainder of division of ST by ST(1) and leaves the
  3810.  result in ST. FPREM finds a remainder REM and a quotient Q such that
  3811.  
  3812.  REM = ST - ST(1)*Q
  3813.  
  3814.  The quotient Q is chosen to be the integer obtained by chopping the exact
  3815.  value of ST/ST(1) toward zero. The sign of the remainder is the same as the
  3816.  sign of the original dividend from ST.
  3817.  
  3818.  By ignoring precision control, the 80387 produces an exact result with
  3819.  FPREM. The precision (inexact) exception does not occur and the rounding
  3820.  control has no effect.
  3821.  
  3822.  The FPREM instruction is not the remainder operation specified in the IEEE
  3823.  standard. To get that remainder, the FPREM1 instruction should be used.
  3824.  
  3825.  The FPREM instruction is designed to be executed iteratively in a
  3826.  software-controlled loop. It operates by performing successive scaled
  3827.  subtractions; therefore, obtaining the exact remainder when the operands
  3828.  differ greatly in magnitude can consume large amounts of execution time.
  3829.  Because the 80387 can only be preempted between instructions, the remainder
  3830.  function could seriously increase interrupt latency in these cases. For
  3831.  this reason, the maximum number of iterations is limited. The instruction
  3832.  may terminate before it has completely terminated the calculation. The C2
  3833.  bit of the status word indicates whether the calculation is complete or
  3834.  whether the instruction must be executed again.
  3835.  
  3836.  FPREM can reduce the exponent of ST by up to (but not including) 64 in one
  3837.  execution. If FPREM produces a remainder that is less than the modulus
  3838.  (i.e., the divisor), the function is complete and bit C2 of the status word
  3839.  condition code is cleared. If the function is incomplete, C2 is set to 1;
  3840.  the result in ST is then called the partial remainder. Software can inspect
  3841.  C2 by storing the status word following execution of FPREM, reexecuting the
  3842.  instruction (using the partial remainder in ST as the dividend) until C2 is
  3843.  cleared. A higher priority interrupting routine that needs the 80387 can
  3844.  force a context switch between the instructions in the remainder loop.
  3845.  
  3846.  An important use for FPREM is to reduce arguments (operands) of
  3847.  transcendental functions to the range permitted by these instructions. For
  3848.  example, the FPTAN (tangent) instruction requires its argument ST to be less
  3849.  than 2^(63). For π/4 < │ST│ < 2^(63), FPTAN (as well as the other
  3850.  trigonometric instructions) performs an internal reduction of ST to a value
  3851.  less than π/4 using an internally stored π/4 divisor that has 67 significant
  3852.  bits. Because of its greater accuracy, this method of reduction is
  3853.  recommended when the argument is within the required range.
  3854.  
  3855.  However, when │ST│ ≥ 2^(63), FPREM can be employed to reduce ST. With π/4 as
  3856.  a modulus, FPREM can reduce an argument so that it is within range of FPTAN
  3857.  and so that no further reduction is required by FPTAN.
  3858.  
  3859.  Because FPREM produces an exact result, the argument reduction does not
  3860.  introduce roundoff error into the calculation, even if several iterations
  3861.  are required to bring the argument into range. However, π is never accurate.
  3862.  The rounding of π, when it is used by FPREM to reduce an argument for a
  3863.  periodic trigonometric function, does not create the effect of a rounded
  3864.  argument, but of a rounded period.
  3865.  
  3866.  When reduction is complete, FPREM provides the least-significant three bits
  3867.  of the quotient generated by FPREM (in C{3}, C{1}, C{0}). This is also
  3868.  important for transcendental argument reduction, because it locates the
  3869.  original angle in the correct one of eight π/4 segments of the unit circle
  3870.  (see Table 4-4).
  3871.  
  3872.  
  3873.  Table 4-4.  Condition Code Interpretation after FPREM and FPREM1
  3874.              Instructions
  3875.  
  3876.  ┌── Condition Code ──┐             Interpretation after
  3877.  C2(PF)  C3    C1    C0             FPREM and FPREM1
  3878.  ───────────────────────────────────────────────────────────────────────────
  3879.                                     Incomplete Reduction:
  3880.    1     X     X     X        ───   further interation required
  3881.                                      or complete reduction
  3882.          Q1    Q0    Q2  Q MOD 8
  3883.  
  3884.          0     0     0     0  ─┐
  3885.          0     1     0     1   │
  3886.          1     0     0     2   │    Complete Reduction:
  3887.    0     1     1     0     3   ├─   C0, C3, C1 contain three least
  3888.          0     0     1     4   │     significant bits of quotient
  3889.          0     1     1     5   │
  3890.          1     0     1     6   │
  3891.          1     1     1     7  ─┘
  3892.  
  3893.  
  3894.  4.4.10  FPREM1──Partial Remainder (IEEE Std. 754-Compatible)
  3895.  
  3896.  FPREM1 computes the remainder of division of ST by ST(1) and leaves the
  3897.  result in ST. FPREM1 finds a remainder REM1 and a quotient Q1 such that
  3898.  
  3899.  REM1 = ST - ST(1)*Q1
  3900.  
  3901.  The quotient Q1 is chosen to be the integer nearest to the exact value of
  3902.  ST/ST(1). When ST/ST(1) is exactly N + 1/2 (for some integer N), there are
  3903.  two integers equally close to ST/ST(1). In this case the value chosen for Q1
  3904.  is the even integer.
  3905.  
  3906.  The result produced by FPREM1 is always exact; no rounding is necessary,
  3907.  and therefore the precision exception does not occur and the rounding
  3908.  control has no effect.
  3909.  
  3910.  The FPREM1 instruction is designed to be executed iteratively in a
  3911.  software-controlled loop. FPREM1 operates by performing successive scaled
  3912.  subtractions; therefore, obtaining the exact remainder when the operands
  3913.  differ greatly in magnitude can consume large amounts of execution time.
  3914.  Because the 80387 can only be preempted between instructions, the remainder
  3915.  function could seriously increase interrupt latency in these cases. For
  3916.  this reason, the maximum number of iterations is limited. The instruction
  3917.  may terminate before it has completely terminated the calculation. The C2
  3918.  bit of the status word indicates whether the calculation is complete or
  3919.  whether the instruction must be executed again.
  3920.  
  3921.  FPREM1 can reduce the exponent of ST by up to (but not including) 64 in one
  3922.  execution. If FPREM1 produces a remainder that is less than the modulus
  3923.  (i.e., the divisor), the function is complete and bit C2 of the status word
  3924.  condition code is cleared. If the function is incomplete, C2 is set to 1;
  3925.  the result in ST is then called the partial remainder. Software can inspect
  3926.  C2 by storing the status word following execution of FPREM1, reexecuting
  3927.  the instruction (using the partial remainder in ST as the dividend) until C2
  3928.  is cleared. When C2 is cleared, FPREM1 also provides the least-significant
  3929.  three bits of the quotient generated by FPREM1 (in C{3}, C{1}, C{0}).
  3930.  
  3931.  The uses for FPREM1 are the same as those for FPREM.
  3932.  
  3933.  FPREM1 differs from FPREM it these respects:
  3934.  
  3935.    ■  FPREM and FPREM1 choose the value of the quotient differently; the
  3936.       low-order three bits of the quotient as reported in bits C3, C1, C0 of
  3937.       the status word may differ by one in some cases.
  3938.  
  3939.    ■  FPREM and FPREM1 may produce different remainders. FPREM produces a
  3940.       remainder R such that 0 ≤ R < │ST(1)│ or -│ST(1)│ < R ≤ 0, depending
  3941.       on the sign of the dividend. FPREM1 produces a remainder R1 such that
  3942.       -│ST(1)│/2 < R1 < +│ST(1)│/2.
  3943.  
  3944.  
  3945.  4.4.11  FRNDINT
  3946.  
  3947.  FRNDINT (round to integer) rounds the top stack element to an integer
  3948.  according to the RC bits of the control word. For example, assume that ST
  3949.  contains the 80387 real number encoding of the decimal value 155.625.
  3950.  FRNDINT will change the value to 155 if the RC field of the control word is
  3951.  set to down or chop, or to 156 if it is set to up or nearest.
  3952.  
  3953.  
  3954.  4.4.12  FXTRACT
  3955.  
  3956.  FXTRACT (extract exponent and significand) performs a superset of the
  3957.  IEEE-recommended logb(x) function by "decomposing" the number in the stack
  3958.  top into two numbers that represent the actual value of the operand's
  3959.  exponent and significand fields. The "exponent" replaces the original
  3960.  operand on the stack and the "significand" is pushed onto the stack. (ST(7)
  3961.  must be empty to avoid causing the invalid-operation exception.) Following
  3962.  execution of FXTRACT, ST (the new stack top) contains the value of the
  3963.  original significand expressed as a real number: its sign is the same as the
  3964.  operand's, its exponent is 0 true (16,383 or 3FFFH biased), and its
  3965.  significand is identical to the original operand's. ST(1) contains the value
  3966.  of the original operand's true (unbiased) exponent expressed as a real
  3967.  number.
  3968.  
  3969.  If the original operand is zero, FXTRACT leaves -∞ in ST(1) (the exponent)
  3970.  while ST is assigned the value zero with a sign equal to that of the
  3971.  original operand. The zero-divide exception is raised in this case, as well.
  3972.  
  3973.  To illustrate the operation of FXTRACT, assume that ST contains a number
  3974.  whose true exponent is +4 (i.e., its exponent field contains 4003H). After
  3975.  executing FXTRACT, ST(1) will contain the real number +4.0; its sign will be
  3976.  positive, its exponent field will contain 4001H (+2 true) and its
  3977.  significand field will contain 1{}00...00B. In other words, the value in
  3978.  ST(1) will be 1.0 * 2² = 4. If ST contains an operand whose true exponent
  3979.  is -7 (i.e., its exponent field contains 3FF8H), then FXTRACT will return an
  3980.  "exponent" of -7.0; after the instruction executes, ST(1)'s sign and
  3981.  exponent fields will contain C001H (negative sign, true exponent of 2), and
  3982.  its significand will be 1{}1100...00B. In other words, the value in ST(1)
  3983.  will be -1.75 * 2² = -7.0. In both cases, following FXTRACT, ST's sign and
  3984.  significand fields will be the same as the original operand's, and its
  3985.  exponent field will contain 3FFFH (0 true).
  3986.  
  3987.  FXTRACT is useful for power and range scaling operations. Both FXTRACT and
  3988.  the base 2 exponential instruction F2XM1 are needed to perform a general
  3989.  power operation. Converting numbers in 80387 extended real format to decimal
  3990.  representations (e.g., for printing or displaying) requires not only FBSTP
  3991.  but also FXTRACT to allow scaling that does not overflow the range of the
  3992.  extended format. FXTRACT can also be useful for debugging, because it allows
  3993.  the exponent and significand parts of a real number to be examined
  3994.  separately.
  3995.  
  3996.  
  3997.  4.4.13  FABS
  3998.  
  3999.  FABS (absolute value) changes the top stack element to its absolute value
  4000.  by making its sign positive. Note that the invalid-operation exception is
  4001.  not signaled even if the operand is a signaling NaN or has a format that is
  4002.  not supported.
  4003.  
  4004.  
  4005.  4.4.14  FCHS
  4006.  
  4007.  FCHS (change sign) complements (reverses) the sign of the top stack
  4008.  element. Note that the invalid-operation exception is not signaled even if
  4009.  the operand is a signaling NaN or has a format that is not supported.
  4010.  
  4011.  
  4012.  4.5  Comparison Instructions
  4013.  
  4014.  The instructions of this class allow comparison of numbers of all supported
  4015.  real and integer data types. Each of these instructions (Table 4-5)
  4016.  analyzes the top stack element, often in relationship to another operand,
  4017.  and reports the result as a condition code in the status word.
  4018.  
  4019.  The basic operations are compare, test (compare with zero), and examine
  4020.  (report type, sign, and normalization). Special forms of the compare
  4021.  operation are provided to optimize algorithms by allowing direct comparisons
  4022.  with binary integers and real numbers in memory, as well as popping the
  4023.  stack after a comparison.
  4024.  
  4025.  The FSTSW (store status word) instruction may be used following a
  4026.  comparison to transfer the condition code to memory or to the 80386 AX
  4027.  register for inspection. The 80386 SAHF instruction is recommended for
  4028.  copying the 80387 flags from AX to the 80386 flags for easy conditional
  4029.  branching.
  4030.  
  4031.  Note that instructions other than those in the comparison group may update
  4032.  the condition code. To ensure that the status word is not altered
  4033.  inadvertently, store it immediately following a comparison operation.
  4034.  
  4035.  
  4036.  Table 4-5.  Comparison Instructions
  4037.  
  4038.  FCOM           Compare real
  4039.  FCOMP          Compare real and pop
  4040.  FCOMPP         Compare real and pop twice
  4041.  FICOM          Integer compare
  4042.  FICOMP         Integer compare and pop
  4043.  FTST           Test
  4044.  FUCOM          Unordered compare real
  4045.  FUCOMP         Unordered compare real and pop
  4046.  FUCOMPP        Unordered compare real and pop twice
  4047.  FXAM           Examine
  4048.  
  4049.  
  4050.  4.5.1  FCOM //source
  4051.  
  4052.  FCOM (compare real) compares the stack top to the source operand. The
  4053.  source operand may be a register on the stack, or a single or double real
  4054.  memory operand. If an operand is not coded, ST is compared to ST(1). The
  4055.  sign of zero is ignored, so that +0 = -0. Following the instruction, the
  4056.  condition codes reflect the order of the operands as shown in Table 4-6.
  4057.  
  4058.  If either operand is a NaN (either quiet or signaling) or an undefined
  4059.  format, or if a stack fault occurs, the invalid-operation exception is
  4060.  raised and the condition bits are set to "unordered."
  4061.  
  4062.  
  4063.  Table 4-6.  Condition Code Resulting from Comparisons
  4064.  
  4065.                                                  80386
  4066.  Order           C3 (ZF)   C2 (PF)   C0 (CF)     Conditional
  4067.                                                  Branch
  4068.  
  4069.  ST > Operand    0         0         0           JA
  4070.  ST < Operand    0         0         1           JB
  4071.  ST = Operand    1         0         0           JE
  4072.  Unordered       1         1         1           JP
  4073.  
  4074.  
  4075.  4.5.2  FCOMP //source
  4076.  
  4077.  FCOMP (compare real and pop) operates like FCOM, and in addition pops the
  4078.  stack.
  4079.  
  4080.  
  4081.  4.5.3  FCOMPP
  4082.  
  4083.  FCOMPP (compare real and pop twice) operates like FCOM and additionally
  4084.  pops the stack twice, discarding both operands. FCOMPP always compares ST to
  4085.  ST(1); no operands may be explicitly specified.
  4086.  
  4087.  
  4088.  4.5.4  FICOM source
  4089.  
  4090.  FICOM (integer compare) converts the source operand, which may reference a
  4091.  word or short binary integer variable, to extended real and compares the
  4092.  stack top to it. The condition code bits in the status word are set as for
  4093.  FCOM.
  4094.  
  4095.  
  4096.  4.5.5  FICOMP source
  4097.  
  4098.  FICOMP (integer compare and pop) operates identically to FICOM and
  4099.  additionally discards the value in ST by popping the NPX stack.
  4100.  
  4101.  
  4102.  4.5.6  FTST
  4103.  
  4104.  FTST (test) tests the top stack element by comparing it to zero. The result
  4105.  is posted to the condition codes as shown in Table 4-7.
  4106.  
  4107.  
  4108.  Table 4-7.  Condition Code Resulting from FTST
  4109.  
  4110.                                                  83086
  4111.  Order           C3 (ZF)   C2 (ZF)   C0 (ZF)     Conditional
  4112.                                                  Branch
  4113.  
  4114.  ST > 0.0        0         0         0           JA
  4115.  ST < 0.0        0         0         1           JB
  4116.  ST = 0.0        1         0         0           JE
  4117.  Unordered       1         1         1           JP
  4118.  
  4119.  
  4120.  4.5.7  FUCOM //source
  4121.  
  4122.  FUCOM (unordered compare real) operates like FCOM, with two differences:
  4123.  
  4124.    1.  It does not cause an invalid-operation exception when one of the
  4125.        operands is a NaN. If either operand is a NaN, the condition bits of
  4126.        the status word are set to unordered as shown in Table 4-6.
  4127.  
  4128.    2.  Only operands on the NPX stack can be compared.
  4129.  
  4130.  
  4131.  4.5.8  FUCOMP //source
  4132.  
  4133.  FUCOMP (unordered compare real and pop) operates like FUCOM and in addition
  4134.  pops the NPX stack.
  4135.  
  4136.  
  4137.  4.5.9  FUCOMPP
  4138.  
  4139.  FUCOMPP (unordered compare real and pop) operates like FUCOM and in
  4140.  addition pops the NPX stack twice, discarding both operands. FUCOMPP always
  4141.  compares ST to ST(1); no operands can be explicitly specified.
  4142.  
  4143.  
  4144.  4.5.10  FXAM
  4145.  
  4146.  FXAM (examine) reports the content of the top stack element as
  4147.  positive/negative and NaN, denormal, normal, zero, infinity, unsupported, or
  4148.  empty. Table 4-8 lists and interprets all the condition code values that
  4149.  FXAM generates.
  4150.  
  4151.  
  4152.  4.6  Transcendental Instructions
  4153.  
  4154.  The instructions in this group (Table 4-9) perform the time-consuming core
  4155.  calculations for all common trigonometric, inverse trigonometric,
  4156.  hyperbolic, inverse hyperbolic, logarithmic, and exponential functions. The
  4157.  transcendentals operate on the top one or two stack elements, and they
  4158.  return their results to the stack. The trigonometric operations assume their
  4159.  arguments are expressed in radians. The logarithmic and exponential
  4160.  operations work in base 2.
  4161.  
  4162.  The results of transcendental instructions are highly accurate. The
  4163.  absolute value of the relative error of the transcendental instructions is
  4164.  guaranteed to be less than 2^(-62). (Relative error is the ratio between the
  4165.  absolute error and the exact value.)
  4166.  
  4167.  The trigonometric functions accept a practically unrestricted range of
  4168.  operands, whereas the other transcendental instructions require that
  4169.  arguments be more restricted in range. FPREM or FPREM1 may be used to bring
  4170.  the otherwise valid operand of a periodic function into range. Prologue and
  4171.  epilogue software may be used to reduce arguments for other instructions to
  4172.  the expected range and to adjust the result to correspond to the original
  4173.  arguments if necessary. The instruction descriptions in this section
  4174.  document the allowed operand range for each instruction.
  4175.  
  4176.  
  4177.  Table 4-8.  Condition Code Defining Operand Class
  4178.  
  4179.  C3  C2  C1  C0    Value at TOP
  4180.  
  4181.  0   0   0   0    +Unsupported
  4182.  0   0   0   1    +NaN
  4183.  0   0   1   0    -Unsupported
  4184.  0   0   1   1    -NaN
  4185.  0   1   0   0    +Normal
  4186.  0   1   0   1    +Infinity
  4187.  0   1   1   0    -Normal
  4188.  0   1   1   1    -Infinity
  4189.  1   0   0   0    +0
  4190.  1   0   0   1    +Empty
  4191.  1   0   1   0    -0
  4192.  1   0   1   1    -Empty
  4193.  1   1   0   0    +Denormal
  4194.  1   1   1   0    -Denormal
  4195.  
  4196.  
  4197.  Table 4-9.  Transcendental Instructions
  4198.  
  4199.  FSIN         Sine
  4200.  FCOS         Cosine
  4201.  FSINCOS      Sine and cosine
  4202.  FPTAN        Tangent of ST
  4203.  FPATAN       Arctangent of ST(1)/ST
  4204.  F2XM1        2{X-1}
  4205.  FYL2X        Y * log{2}X;        Y is ST(1), X is ST
  4206.  FYL2XP1      Y * log{2}(X + 1);  Y is ST(1), X is ST
  4207.  
  4208.  
  4209.  4.6.1  FCOS
  4210.  
  4211.  When complete, this function replaces the contents of ST with COS(ST). ST,
  4212.  expressed in radians, must lie in the range │Θ│ < 2^(63) (for most practical
  4213.  purposes unrestricted). If ST is in range, C2 of the status word is cleared
  4214.  and the result of the operation is produced.
  4215.  
  4216.  If the operand is outside of the range, C2 is set to one (function
  4217.  incomplete) and ST remains intact (i.e., no reduction of the operand is
  4218.  performed). It is the programmers responsibility to reduce the operand to an
  4219.  absolute value smaller than 2^(63). The instructions FPREM1 and FPREM are
  4220.  available for this purpose.
  4221.  
  4222.  
  4223.  4.6.2  FSIN
  4224.  
  4225.  When complete, this function replaces the contents of ST with SIN(ST). FSIN
  4226.  is equivalent to FCOS in the way it reduces the operand. ST is expressed in
  4227.  radians.
  4228.  
  4229.  
  4230.  4.6.3  FSINCOS
  4231.  
  4232.  When complete, this instruction replaces the contents of ST with SIN(ST),
  4233.  then pushes COS(ST) onto the stack. (ST(7) must be empty to avoid an invalid
  4234.  exception.) FSINCOS is equivalent to FCOS in the way it reduces the operand.
  4235.  ST is expressed in radians.
  4236.  
  4237.  
  4238.  4.6.4  FPTAN
  4239.  
  4240.  When complete, FPTAN (partial tangent) computes the function Y = TAN (ST).
  4241.  ST is expressed in radians. Y replaces ST, then the value 1 is pushed,
  4242.  becoming the new stack top. (ST(7) must be empty to avoid an invalid
  4243.  exception.) When the function is complete ST(1) = TAN (arg) and ST = 1.
  4244.  FPTAN is equivalent to FCOS in the way it reduces the operand.
  4245.  
  4246.  The fact that FPTAN places two results on the stack maintains compatibility
  4247.  with the 8087/80287 and aids the calculation of other trigonometric
  4248.  functions that can be derived from tan via standard trigonometric
  4249.  identities. For example, the cot function is given by this identity:
  4250.  
  4251.  cot x = 1/tan x.
  4252.  
  4253.  Therefore, simply executing the reverse divide instruction FDIVR after
  4254.  FPTAN yields the cot function.
  4255.  
  4256.  
  4257.  4.6.5  FPATAN
  4258.  
  4259.  FPATAN (arctangent) computes the function Θ = ARCTAN (Y/X). X is taken from
  4260.  ST(0) and Y from ST(1). The instruction pops the NPX stack and returns Θ to
  4261.  the (new) stack top, overwriting the Y operand. The result is expressed in
  4262.  radians. The range of operands is not restricted; however, the range of the
  4263.  result depends on the relationship between the operands according to Table
  4264.  4-10.
  4265.  
  4266.  The fact that the argument of FPATAN is a ratio aids calculation of other
  4267.  trigonometric functions, including Arcsin and Arccos. These can be derived
  4268.  from Arctan via standard trigonometric identities. For example, the Arcsin
  4269.  function can be easily calculated using this identity:
  4270.  
  4271.  Arcsin x = Arctan (x / √(1 - x²)).
  4272.  
  4273.  Thus, to find Arcsin (Y), push Y onto the NPX stack, then calculate
  4274.  X = √(1 - Y²), pushing the result X onto the stack. Executing FPATAN then
  4275.  leaves Arcsin (Y) at the top of the stack.
  4276.  
  4277.  
  4278.  4.6.6  F2XM1
  4279.  
  4280.  F2XM1 (2 to the X minus 1) calculates the function Y = 2^(X) - 1. X is taken
  4281.  from the stack top and must be in the range -1 ≤ X ≤ 1. The result Y
  4282.  replaces the argument X at the stack top. If the argument is out of range,
  4283.  the results are undefined.
  4284.  
  4285.  This instruction is designed to produce a very accurate result even when X
  4286.  is close to 0. For values of the argument very close in magnitude to 1, a
  4287.  larger error will be incurred. To obtain Y = 2^(X), add 1 to the result
  4288.  delivered by F2XM1.
  4289.  
  4290.  The following formulas show how values other than 2 may be raised to a
  4291.  power of X:
  4292.  
  4293.  10^(X) = 2^(X * LOG2(10))
  4294.  
  4295.  e^(X) = 2^(X * LOG2(e))
  4296.  
  4297.  y^(X) = 2^(X * LOG2(Y))
  4298.  
  4299.  As shown in the next section, the 80387 has built-in instructions for
  4300.  loading the constants LOG{2}10 and LOG{2}e, and the FYL2X instruction may be
  4301.  used to calculate X*LOG{2}Y.
  4302.  
  4303.  
  4304.  Table 4-10.  Results of FPATAN
  4305.  
  4306.  Sign(Y)    Sign(X)     │Y│ < │X│?      Final Result
  4307.  
  4308.  +          +           Yes                   0 < atan(Y/X) < π/4
  4309.  +          +           No                  π/4 < atan(Y/X) < π/2
  4310.  +          -           No                  π/2 < atan(Y/X) < 3 * π/4
  4311.  +          -           Yes             3 * π/4 < atan(Y/X) < π
  4312.  -          +           Yes                -π/4 < atan(Y/X) < 0
  4313.  -          +           No                 -π/2 < atan(Y/X) < -π/4
  4314.  -          -           No             -3 * π/4 < atan(Y/X) < -π/2
  4315.  -          -           Yes                  -π < atan(Y/X) < -3 * π/4
  4316.  
  4317.  
  4318.  4.6.7  FYL2X
  4319.  
  4320.  FYL2X (Y log base 2 of X) calculates the function Z = Y * LOG{2}X. X is
  4321.  taken from the stack top and Y from ST(1). The operands must be in the
  4322.  following ranges:
  4323.  
  4324.  0 ≤ X < +∞
  4325.  -∞ < Y < +∞
  4326.  
  4327.  The instruction pops the NPX stack and returns Z at the (new) stack top,
  4328.  replacing the Y operand. If the operand is out of range (i.e., in negative)
  4329.  the invalid-operation exception occurs.
  4330.  
  4331.  This function optimizes the calculations of log to any base other than two,
  4332.  because a multiplication is always required:
  4333.  
  4334.  LOG{N}x = (LOG{2}N){-1} * LOG{2}x
  4335.  
  4336.  
  4337.  4.6.8  FYL2XP1
  4338.  
  4339.  FYL2XP1 (Y log base 2 of (X + 1)) calculates the function Z = Y*LOG{2}
  4340.  (X+1). X is taken from the stack top and must be in the range -(1-SQRT(2)/2)
  4341.  < X <1-SQRT(2)/2. Y is taken from  ST(1) and is unlimited in range (-∞ < Y
  4342.  < +∞). FYL2XP1 pops the stack and returns Z at the (new) stack top,
  4343.  replacing Y. If the argument is out of range, the results are undefined.
  4344.  
  4345.  This instruction provides improved accuracy over FYL2X when computing the
  4346.  logarithm of a number very close to 1, for example 1 + ε where ε << 1.
  4347.  Providing ε rather than 1 + ε as the input to the function allows more
  4348.  significant digits to be retained.
  4349.  
  4350.  
  4351.  Table 4-11.  Constant Instructions
  4352.  
  4353.  FLDZ     Load + 0.0
  4354.  FLD1     Load + 1.0
  4355.  FLDPI    Load π
  4356.  FLDL2T   Load log{2}10
  4357.  FLDL2E   Load log{2}e
  4358.  FLDLG2   Load log{10}2
  4359.  FLDLN2   Load log{e}2
  4360.  
  4361.  
  4362.  4.7  Constant Instructions
  4363.  
  4364.  Each of these instructions (Table 4-11) loads (pushes) a commonly used
  4365.  constant onto the stack. (ST(7) must be empty to avoid an invalid
  4366.  exception.) The values have full extended real precision (64 bits) and are
  4367.  accurate to approximately 19 decimal digits. Because an external real
  4368.  constant occupies 10 memory bytes, the constant instructions, which are
  4369.  only two bytes long, save storage and improve execution speed, in addition
  4370.  to simplifying programming.
  4371.  
  4372.  The constants used by these instructions are stored internally in a format
  4373.  more precise even than extended real. When loading the constant, the 80387
  4374.  rounds the more precise internal constant according the RC (rounding
  4375.  control) bit of the control word. However, in spite of this rounding, the
  4376.  precision exception is not raised (to maintain compatibility). When the
  4377.  rounding control is set to round to nearest on the 80387, the 80387
  4378.  produces the same constant that is produced by the 80287.
  4379.  
  4380.  
  4381.  4.7.1  FLDZ
  4382.  
  4383.  FLDZ (load zero) loads (pushes) +0.0 onto the NPX stack.
  4384.  
  4385.  
  4386.  4.7.2  FLD1
  4387.  
  4388.  FLD1 (load one) loads (pushes) +1.0 onto the NPX stack.
  4389.  
  4390.  
  4391.  4.7.3  FLDPI
  4392.  
  4393.  FLDPI (load π) loads (pushes) π onto the NPX stack.
  4394.  
  4395.  
  4396.  4.7.4  FLDL2T
  4397.  
  4398.  FLDL2T (load log base 2 of 10) loads (pushes) the value LOG{2}10 onto the
  4399.  NPX stack.
  4400.  
  4401.  
  4402.  4.7.5  FLDL2E
  4403.  
  4404.  FLDL2E (load log base 2 of e) loads (pushes) the value LOG{2}e onto the NPX
  4405.  stack.
  4406.  
  4407.  
  4408.  4.7.6  FLDLG2
  4409.  
  4410.  FLDLG2 (load log base 10 of 2) loads (pushes) the value LOG{10}2 onto the
  4411.  NPX stack.
  4412.  
  4413.  
  4414.  4.7.7  FLDLN2
  4415.  
  4416.  FLDLN2 (load log base e of 2) loads (pushes) the value LOG{e}2 onto the NPX
  4417.  stack.
  4418.  
  4419.  
  4420.  4.8  Processor Control Instructions
  4421.  
  4422.  The processor control instructions are shown in Table 4-12. The instruction
  4423.  FSTSW is commonly used for conditional branching. The remaining instructions
  4424.  are not typically used in calculations; they provide control over the 80387
  4425.  NPX for system-level activities. These activities include initialization,
  4426.  exception handling, and task switching.
  4427.  
  4428.  As shown in Table 4-12, many of the NPX processor control instructions have
  4429.  two forms of assembler mnemonic:
  4430.  
  4431.    1.  A wait form, where the mnemonic is prefixed only with an F, such as
  4432.        FSTSW. This form checks for unmasked numeric exceptions.
  4433.  
  4434.    2.  A no-wait form, where the mnemonic is prefixed with an FN, such as
  4435.        FNSTSW. This form ignores unmasked numeric exceptions.
  4436.  
  4437.  When the control instruction is coded using the no-wait form of the
  4438.  mnemonic, the ASM386 assembler does not precede the ESC instruction with a
  4439.  wait instruction, and the CPU does not test the ERROR# status line from the
  4440.  NPX before executing the processor control instruction.
  4441.  
  4442.  Only the processor control class of instructions have this alternate
  4443.  no-wait form. All numeric instructions are automatically synchronized by the
  4444.  80386; the CPU transfers all operands before initiating the next
  4445.  instruction. Because of this automatic synchronization by the 80386, numeric
  4446.  instructions for the 80387 need not be preceded by a CPU wait instruction
  4447.  in order to execute correctly.
  4448.  
  4449.  It should also be noted that the 8087 instructions FENI and FDISI and the
  4450.  80287 instruction FSETPF perform no function in the 80387. If these opcodes
  4451.  are detected in an 80386/80387 instruction stream, the 80387 performs no
  4452.  specific operation and no internal states are affected. For programmers
  4453.  interested in porting numeric software from 80287 or 8087 environments to
  4454.  the 80386, however, it should be noted that program sections containing
  4455.  these exception-handling instructions are not likely to be completely
  4456.  portable to the 80387. Appendix C and Appendix D contains a more complete
  4457.  description of the differences between the 80387 and the 80287/8087.
  4458.  
  4459.  
  4460.  Table 4-12.  Processor Control Instructions
  4461.  
  4462.  FINIT/FNINIT           Initialize processor
  4463.  FLDCW                  Load control word
  4464.  FSTCW/FNSTCW           Store control word
  4465.  FSTSW/FNSTSW           Store status word
  4466.  FSTSW AX/FNSTSW AX     Store status word to AX
  4467.  FCLEX/FNCLEX           Clear exceptions
  4468.  FSTENV/FNSTENV         Store environment
  4469.  FLDENV                 Load environment
  4470.  FSAVE/FNSAVE           Save state
  4471.  FRSTOR                 Restore state
  4472.  FINCSTP                Increment stack pointer
  4473.  FDECSTP                Decrement stack pointer
  4474.  FFREE                  Free register
  4475.  FNOP                   No operation
  4476.  FWAIT                  CPU Wait
  4477.  
  4478.  
  4479.  4.8.1  FINIT/FNINIT
  4480.  
  4481.  FINIT/FNINIT (initialize processor) sets the 80387 NPX into a known state,
  4482.  unaffected by any previous activity. It sets the control word to its default
  4483.  value 037FH (round to nearest, all exceptions masked, 64 bits of precision),
  4484.  clears the status word, and empties all floating-point stack registers. The
  4485.  no-wait form of this instruction causes the 80387 to abort any previous
  4486.  numeric operations currently executing in the NEU.
  4487.  
  4488.  This instruction performs the functional equivalent of a hardware RESET,
  4489.  with one exception: RESET causes the IM bit of the control word to be reset
  4490.  and the ES and IE bits of the status word to be set as a means of signaling
  4491.  the presence of an 80387; FINIT puts the opposite values in these bits.
  4492.  
  4493.  FINIT checks for unmasked numeric exceptions, FNINIT does not. Note that if
  4494.  FNINIT is executed while a previous 80387 memory-referencing instruction is
  4495.  running, 80387 bus cycles in progress are aborted. This instruction may be
  4496.  necessary to clear the 80387 if a processor-extension segment-overrun
  4497.  exception (interrupt 9) is detected by the CPU.
  4498.  
  4499.  
  4500.  4.8.2  FLDCW source
  4501.  
  4502.  FLDCW (load control word) replaces the current processor control word with
  4503.  the word defined by the source operand. This instruction is typically used
  4504.  to establish or change the 80387's mode of operation. Note that if an
  4505.  exception bit in the status word is set, loading a new control word that
  4506.  unmasks that exception will activate the ERROR# output of the 80387. When
  4507.  changing modes, the recommended procedure is to first clear any exceptions
  4508.  and then load the new control word.
  4509.  
  4510.  
  4511.  4.8.3  FSTCW/FNSTCW destination
  4512.  
  4513.  FSTCW/FNSTCW (store control word) writes the processor control word to the
  4514.  memory location defined by the destination. FSTCW checks for unmasked
  4515.  numeric exceptions; FNSTCW does not.
  4516.  
  4517.  
  4518.  4.8.4  FSTSW/FNSTSW destination
  4519.  
  4520.  FSTSW/FNSTSW (store status word) writes the current value of the 80387
  4521.  status word to the destination operand in memory. The instruction is used to
  4522.  
  4523.    ■  Implement conditional branching following a comparison, FPREM, or
  4524.       FPREM1 instruction (FSTSW).
  4525.  
  4526.    ■  Invoke exception handlers (by polling the exception bits) in
  4527.       environments that do not use interrupts (FSTSW).
  4528.  
  4529.  FSTSW checks for unmasked numeric exceptions, FNSTSW does not.
  4530.  
  4531.  
  4532.  4.8.5  FSTSW AX/FNSTSW AX
  4533.  
  4534.  FSTSW AX/FNSTSW AX (store status word to AX) is a special 80387 instruction
  4535.  that writes the current value of the 80387 status word directly into the
  4536.  80386 AX register. This instruction optimizes conditional branching in
  4537.  numeric programs, where the 80386 CPU must test the condition of various NPX
  4538.  status bits. The waited form FSTSW AX checks for unmasked numeric
  4539.  exceptions, the non-waited form FNSTSW AX does not.
  4540.  
  4541.  When this instruction is executed, the 80386 AX register is updated with
  4542.  the NPX status word before the CPU executes any further instructions. The
  4543.  status stored is that from the completion of the prior ESC instruction.
  4544.  
  4545.  
  4546.  4.8.6  FCLEX/FNCLEX
  4547.  
  4548.  FCLEX/FNCLEX (clear exceptions) clears all exception flags, the exception
  4549.  status flag and the busy flag in the status word. As a consequence, the
  4550.  80387's ERROR# line goes inactive. FCLEX checks for unmasked numeric
  4551.  exceptions, FNCLEX does not.
  4552.  
  4553.  
  4554.  4.8.7  FSAVE/FNSAVE destination
  4555.  
  4556.  FSAVE/FNSAVE (save state) writes the full 80387 state──environment plus
  4557.  register stack──to the memory location defined by the destination operand.
  4558.  Figure 4-1 and Figure 4-2 show the layout of the save area; the size and
  4559.  layout of the save the operating mode of the 80386 (real-address mode or
  4560.  protected mode) and on the operand-size attribute in effect for the
  4561.  instruction (32-bit operand or 16-bit operand). When the 80386 is in
  4562.  virtual-8086 mode, the real-address mode formats are used. Typically the
  4563.  instruction is coded to save this image on the CPU stack.
  4564.  
  4565.  The values in the tag word in memory are determined during the execution of
  4566.  FSAVE/FNSAVE. If the tag in the status register indicates that the
  4567.  corresponding register is nonempty, the 80387 examines the data in the
  4568.  register and stores the appropriate tag in memory. Thus the tag that is
  4569.  stored always reflects the actual content of the register.
  4570.  
  4571.  FNSAVE delays its execution until all NPX activity completes normally.
  4572.  Thus, the save image reflects the state of the NPX following the completion
  4573.  of any running instruction. After writing the state image to memory,
  4574.  FSAVE/FNSAVE initializes the 80387 as if FINIT/FNINIT had been executed.
  4575.  
  4576.  FSAVE/FNSAVE is useful whenever a program wants to save the current state
  4577.  of the NPX and initialize it for a new routine. Three examples are
  4578.  
  4579.    1.  An operating system needs to perform a context switch (suspend the
  4580.        task that had been running and give control to a new task).
  4581.  
  4582.    2.  An exception handler needs to use the 80387.
  4583.  
  4584.    3.  An application task wants to pass a "clean" 80387 to a subroutine.
  4585.  
  4586.  FSAVE checks for unmasked numeric exceptions before executing, FNSAVE does
  4587.  not.
  4588.  
  4589.  
  4590.  Figure 4-1.  FSAVE/FRSTOR Memory Layout (32-Bit)
  4591.  
  4592.                 41          23          15          7         0
  4593.                ╔═══════════╪═══════════╪═══════════╪═══════════╗+0H
  4594.                ╟───────────|───────────|───────────|───────────╢+4H
  4595.                ╟───────────|────────       ────────|───────────╢+8H
  4596.                ╟───────────|───── ENVIRONMENT ─────|───────────╢+CH
  4597.                ╟───────────|────────       ────────|───────────╢+10H
  4598.                ╟───────────|───────────|───────────|───────────╢+14H
  4599.                ╟───────────|───────────|───────────|───────────╢+18H
  4600.                ╚═══════════╪═══════════╪═══════════╪═══════════╝
  4601.  
  4602.          ╔════╤════════╤══════════════════════════════════════════════╗
  4603.     ST(0)║SIGN│EXPONENT│                  SIGNIFICAND                 ║+1CH
  4604.     ST(1)╟────┼────────┼──────────────────────────────────────────────╢+26H
  4605.     ST(2)╟────┼────────┼──────────────────────────────────────────────╢+30H
  4606.     ST(3)╟────┼────────┼──────────────────────────────────────────────╢+3AH
  4607.     ST(4)╟────┼────────┼──────────────────────────────────────────────╢+44H
  4608.     ST(5)╟────┼────────┼──────────────────────────────────────────────╢+4EH
  4609.     ST(6)╟────┼────────┼──────────────────────────────────────────────╢+58H
  4610.     ST(7)╟────┼────────┼──────────────────────────────────────────────╢+62H
  4611.          ╚════╧════════╧══════════════════════════════════════════════╝
  4612.             79 78    64 63                                           0
  4613.  
  4614.  
  4615.  Figure 4-2.  FSAVE/FRSTOR Memory Layout (16-Bit)
  4616.  
  4617.                            15         7        0
  4618.                           ╔══════════╪══════════╗+0H
  4619.                           ╟──────────|──────────╢+2H
  4620.                           ╟───────       ───────╢+4H
  4621.                           ╟──── ENVIRONMENT ────╢+6H
  4622.                           ╟───────       ───────╢+8H
  4623.                           ╟──────────|──────────╢+AH
  4624.                           ╟──────────|──────────╢+CH
  4625.                           ╚══════════╪══════════╝
  4626.  
  4627.          ╔════╤════════╤══════════════════════════════════════════════╗
  4628.     ST(0)║SIGN│EXPONENT│                  SIGNIFICAND                 ║+EH
  4629.     ST(1)╟────┼────────┼──────────────────────────────────────────────╢+18H
  4630.     ST(2)╟────┼────────┼──────────────────────────────────────────────╢+22H
  4631.     ST(3)╟────┼────────┼──────────────────────────────────────────────╢+2CH
  4632.     ST(4)╟────┼────────┼──────────────────────────────────────────────╢+36H
  4633.     ST(5)╟────┼────────┼──────────────────────────────────────────────╢+40H
  4634.     ST(6)╟────┼────────┼──────────────────────────────────────────────╢+4AH
  4635.     ST(7)╟────┼────────┼──────────────────────────────────────────────╢+54H
  4636.          ╚════╧════════╧══════════════════════════════════════════════╝
  4637.             79 78    64 63                                           0
  4638.  
  4639.  
  4640.  4.8.8  FRSTOR source
  4641.  
  4642.  FRSTOR (restore state) reloads the 80387 state from the memory area defined
  4643.  by the source operand. This information should have been written by a
  4644.  previous FSAVE/FNSAVE instruction and not altered by any other instruction.
  4645.  FRSTOR automatically waits checking for interrupts until all data transfers
  4646.  are completed before continuing to the next instruction.
  4647.  
  4648.  Note that the 80387 "reacts" to its new state at the conclusion of the
  4649.  FRSTOR. It generates an exception request, for example, if the exception and
  4650.  mask bits in the memory image so indicate when the next WAIT or
  4651.  exception-checking ESC instruction is executed.
  4652.  
  4653.  
  4654.  4.8.9  FSTENV/FNSTENV destination
  4655.  
  4656.  FSTENV/FNSTENV (store environment) writes the 80387's basic
  4657.  status──control, status, and tag words, and exception pointers──to the
  4658.  memory location defined by the destination operand. Typically, the
  4659.  environment is saved on the CPU stack. FSTENV/FNSTENV is often used by
  4660.  exception handlers because it provides access to the exception pointers
  4661.  that identify the offending instruction and operand. After saving the
  4662.  environment, FSTENV/FNSTENV sets all exception masks in the 80387 control
  4663.  word (i.e., masks all exceptions). FSTENV checks for pending exceptions
  4664.  before executing, FNSTENV does not.
  4665.  
  4666.  Figures 4-3 through 4-6 show the format of the environment data in memory
  4667.  the size and layout of the save area depends on the operating mode of the
  4668.  80386 (real-address mode or protected mode) and on the operand-size
  4669.  attribute in effect for the instruction (32-bit operand or 16-bit operand).
  4670.  When the 80386 is in virtual-8086 mode, the real-address mode formats are
  4671.  used. FNSTENV does not store the environment until all NPX activity has
  4672.  completed. Thus, the data saved by the instruction reflects the 80387 after
  4673.  any previously decoded instruction has been executed.
  4674.  
  4675.  The values in the tag word in memory are determined during the execution of
  4676.  FNSTENV/FSTENV. If the tag in the status register indicates that the
  4677.  corresponding register is nonempty, the 80387 examines the data in the
  4678.  register and stores the appropriate tag in memory. Thus the tag that is
  4679.  stored always reflects the actual content of the register.
  4680.  
  4681.  
  4682.  Figure 4-3.  Protected Mode 80387 Environment, 32-Bit Format
  4683.  
  4684.                        32-BIT PROTECTED MODE FORMAT
  4685.  
  4686.   31                23                15                7               0
  4687.  ╔═════════════════╪═════════════════╤═════════════════╪═════════════════╗
  4688.  ║             RESERVED              │            CONTROL WORD           ║0H
  4689.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4690.  ║             RESERVED              │            STATUS WORD            ║4H
  4691.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4692.  ║             RESERVED              │              TAG WORD             ║8H
  4693.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4694.  ║                               IP OFFSET                               ║CH
  4695.  ╟──────────┬──────┼─────────────────┼─────────────────┼─────────────────╢
  4696.  ║ 0 0 0 0 0│      OPCODE 10..0      │            CS SELECTOR            ║10H
  4697.  ╟──────────┴──────┼─────────────────┼─────────────────┼─────────────────╢
  4698.  ║                          DATA OPERAND OFFSET                          ║14H
  4699.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4700.  ║             RESERVED              │          OPERAND SELECTOR         ║18H
  4701.  ╚═════════════════╪═════════════════╧═════════════════╪═════════════════╝
  4702.  
  4703.  
  4704.  Figure 4-4.  Real Mode 80387 Environment, 32-Bit Format
  4705.  
  4706.                         32-BIT PROTECTED MODE FORMAT
  4707.  
  4708.   31                23                15                7               0
  4709.  ╔═════════════════╪═════════════════╤═════════════════╪═════════════════╗
  4710.  ║             RESERVED              │            CONTROL WORD           ║0H
  4711.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4712.  ║             RESERVED              │            STATUS WORD            ║4H
  4713.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4714.  ║             RESERVED              │              TAG WORD             ║8H
  4715.  ╟─────────────────┼─────────────────┼─────────────────┼─────────────────╢
  4716.  ║             RESERVED              │      INSTRUCTION POINTER 15..0    ║CH
  4717.  ╟─────────┬───────┼─────────────────┼───────────┬─┬───┼─────────────────╢
  4718.  ║ 0 0 0 0 │     INSTRUCTION POINTER 31..16      │0│    OPCODE 10..0     ║10H
  4719.  ╟─────────┴───────┼─────────────────┼───────────┴─┴───┼─────────────────╢
  4720.  ║             RESERVED              │       OPERAND POINTER 15..0       ║14H
  4721.  ╟─────────┬───────┼─────────────────┼───────────┬─────┼─────────────────╢
  4722.  ║ 0 0 0 0 │       OPERAND POINTER 31..16        │0 0 0 0 0 0 0 0 0 0 0 0║18H
  4723.  ╚═════════╧═══════╪═════════════════╧═══════════╧═════╪═════════════════╝
  4724.  
  4725.  
  4726.  Figure 4-5.  Protected Mode 80387 Environment, 16-Bit Format
  4727.  
  4728.                          16-BIT PROTECTED MODE FORMAT
  4729.  
  4730.                       15               7              0
  4731.                      ╔════════════════╪════════════════╗
  4732.                      ║          CONTROL WORD           ║ 0H
  4733.                      ╟────────────────┼────────────────╢
  4734.                      ║           STATUS WORD           ║ 2H
  4735.                      ╟────────────────┼────────────────╢
  4736.                      ║            TAG WORD             ║ 4H
  4737.                      ╟────────────────┼────────────────╢
  4738.                      ║            IP OFFSET            ║ 6H
  4739.                      ╟────────────────┼────────────────╢
  4740.                      ║           CB SELECTOR           ║ 8H
  4741.                      ╟────────────────┼────────────────╢
  4742.                      ║         OPERAND OFFSET          ║ AH
  4743.                      ╟────────────────┼────────────────╢
  4744.                      ║        OPERAND SELECTOR         ║ CH
  4745.                      ╚════════════════╪════════════════╝
  4746.  
  4747.  
  4748.  Figure 4-6.  Real Mode 80387 Environment, 16-Bit Format
  4749.  
  4750.                            16-BIT REAL-ADDRESS MODE
  4751.                          AND VIRTUAL-8086 MODE FORMAT
  4752.  
  4753.                       15               7              0
  4754.                      ╔════════════════╪════════════════╗
  4755.                      ║          CONTROL WORD           ║ 0H
  4756.                      ╟────────────────┼────────────────╢
  4757.                      ║           STATUS WORD           ║ 2H
  4758.                      ╟────────────────┼────────────────╢
  4759.                      ║            TAG WORD             ║ 4H
  4760.                      ╟────────────────┼────────────────╢
  4761.                      ║    INSTRUCTION POINTER 15..0    ║ 6H
  4762.                      ╟─────────┬─┬────┼────────────────╢
  4763.                      ║IP 19..16│0│      OPCODE 10..0   ║ 8H
  4764.                      ╟─────────┴─┴────┼────────────────╢
  4765.                      ║      OPERAND POINTER 15..0      ║ AH
  4766.                      ╟─────────┬─┬────┼────────────────╢
  4767.                      ║OP 19..16│0│0 0 0 0 0 0 0 0 0 0 0║ CH
  4768.                      ╚═════════╧═╧════╪════════════════╝
  4769.  
  4770.  
  4771.  4.8.10  FLDENV source
  4772.  
  4773.  FLDENV (load environment) reloads the environment from the memory area
  4774.  defined by the source operand. This data should have been written by a
  4775.  previous FSTENV/FNSTENV instruction. CPU instructions (that do not reference
  4776.  the environment image) may immediately follow FLDENV. FLDENV automatically
  4777.  waits for all data transfers to complete before executing the next
  4778.  instruction.
  4779.  
  4780.  Note that loading an environment image that contains an unmasked exception
  4781.  causes a numeric exception when the next WAIT or exception-checking ESC
  4782.  instruction is executed.
  4783.  
  4784.  
  4785.  4.8.11  FINCSTP
  4786.  
  4787.  FINCSTP (increment NPX stack pointer) adds 1 to the stack top pointer (TOP)
  4788.  in the status word. It does not alter tags or register contents, nor does it
  4789.  transfer data. It is not equivalent to popping the stack, because it does
  4790.  not set the tag of the previous stack top to empty. Incrementing the stack
  4791.  pointer when ST=7 produces ST=0.
  4792.  
  4793.  
  4794.  4.8.12  FDECSTP
  4795.  
  4796.  FDECSTP (decrement NPX stack pointer) subtracts 1 from ST, the stack top
  4797.  pointer in the status word. No tags or registers are altered, nor is any
  4798.  data transferred. Executing FDECSTP when ST=0 produces ST=7.
  4799.  
  4800.  
  4801.  4.8.13  FFREE destination
  4802.  
  4803.  FFREE (free register) changes the destination register's tag to empty; the
  4804.  content of the register is unaffected.
  4805.  
  4806.  
  4807.  4.8.14  FNOP
  4808.  
  4809.  FNOP (no operation) effectively performs no operation.
  4810.  
  4811.  
  4812.  4.8.15  FWAIT (CPU Instruction)
  4813.  
  4814.  FWAIT is not actually an 80387 instruction, but an alternate mnemonic for
  4815.  the 80386 WAIT instruction. The FWAIT or WAIT mnemonic should be coded
  4816.  whenever the programmer wants to check for a pending error before modifying
  4817.  a variable used in the previous floating-point instruction. Coding an FWAIT
  4818.  instruction after an 80387 instruction ensures that unmasked numeric
  4819.  exceptions occur and exception handlers are invoked before the next
  4820.  instruction has a chance to examine the results of the 80387 instruction.
  4821.  
  4822.  More information on when to code an FWAIT instruction is given in Chapter 5
  4823.  in the section "Concurrent Processing with the 80387."
  4824.  
  4825.  
  4826.  
  4827.  Chapter 5  Programming Numeric Applications
  4828.  
  4829.  ───────────────────────────────────────────────────────────────────────────
  4830.  
  4831.  5.1  Programming Facilities
  4832.  
  4833.  As described previously, the 80387 NPX is programmed simply as an extension
  4834.  of the 80386 CPU. This section describes how programmers in ASM386 and in a
  4835.  variety of higher-level languages can work with the 80387.
  4836.  
  4837.  The level of detail in this section is intended to give programmers a basic
  4838.  understanding of the software tools that can be used with the 80387, but
  4839.  this information does not document the full capabilities of these
  4840.  facilities. Complete documentation is available with each program
  4841.  development product.
  4842.  
  4843.  
  4844.  5.1.1  High-Level Languages
  4845.  
  4846.  For programmers using high-level languages, the programming and operation
  4847.  of the NPX is handled automatically by the compiler. A variety of Intel
  4848.  high-level languages are available that automatically make use of the 80387
  4849.  NPX when appropriate. These languages include C-386 and PL/M-386. In
  4850.  addition many high-level language compilers are available from independent
  4851.  software vendors.
  4852.  
  4853.  Each of these high-level languages has special numeric libraries allowing
  4854.  programs to take advantage of the capabilities of the 80387 NPX. No special
  4855.  programming conventions are necessary to make use of the 80387 NPX when
  4856.  programming numeric applications in any of these languages.
  4857.  
  4858.  Programmers in PL/M-386 and ASM386 can also make use of many of these
  4859.  library routines by using routines contained in the 80387 Support Library.
  4860.  These libraries implement many of the functions provided by higher-level
  4861.  languages, including exception handlers, ASCII-to-floating-point
  4862.  conversions, and a more complete set of transcendental functions than that
  4863.  provided by the 80387 instruction set.
  4864.  
  4865.  
  4866.  5.1.2  C Programs
  4867.  
  4868.  C programmers automatically cause the C compiler to generate 80387
  4869.  instructions when they use the double and float data types. The float type
  4870.  corresponds to the 80387's single real format; the double type corresponds
  4871.  to the 80387's double real format. The statement #include <math.h> causes
  4872.  mathematical functions such as sin and sqrt to return values of type
  4873.  double. Figure 5-1 illustrates the ease with which C programs interface
  4874.  with the 80387.
  4875.  
  4876.  
  4877.  Figure 5-1.  Sample C-386 Program
  4878.  
  4879.  XENIX286 C386 COMPILER,  V0.2 COMPILATION OF MODULE SAMPLE
  4880.  OBJECT MODULE PLACED IN  sample.obj
  4881.  COMPILER INVOKED BY:  c386 sample.c
  4882.  
  4883.  stmt level
  4884.  
  4885.        1         /******************************************************
  4886.        2         *                                                      *
  4887.        3         *                  SAMPLE C PROGRAM                    *
  4888.        4         *                                                      *
  4889.        5         ******************************************************/
  4890.        6
  4891.        7         /** Include /usr/include/stdio.h if necessary **/
  4892.        8         /** Include math declarations for transcendenatals and others
  4893.        9
  4894.       10         #include </usr/include/math.h>
  4895.       36         #define PI 3.141592654
  4896.       37
  4897.       38         main()
  4898.       39         {
  4899.       40   1     double        sin_result, cos_result;
  4900.       41   1     double        angle_deg = 0.0, angle_rad;
  4901.       42   1     int           i, no_of_trial = 4;
  4902.       43
  4903.       44   1          for( i = 1; i <= no_of_trial; i++){
  4904.       45   2              angle_rad = angle_deg * PI / 180.0;
  4905.       46   2              sin_result = sin (angle_rad);
  4906.       47   2              cos_result = cos (angle_rad);
  4907.       48   2              printf("sine of %f degrees equals %f\n", angle_deg,
  4908.       49   2              printf("cosine of %f degrees equals %f\n\n", angle_d
  4909.       50   2              angle_deg = angle_deg + 30.0;
  4910.       51   2              }
  4911.       52   1     /** etc. **/
  4912.       53   1     }
  4913.  
  4914.  C386 COMPILATION COMPLETE. 0 WARNINGS, 0 ERRORS
  4915.  
  4916.  
  4917.  5.1.3  PL/M-386
  4918.  
  4919.  Programmers in PL/M-386 can access a very useful subset of the 80387's
  4920.  numeric capabilities. The PL/M-386 REAL data type corresponds to the NPX's
  4921.  single real (32-bit) format. This data type provides a range of about
  4922.  8.43 * 10^(-37) ≤ │X│ ≤ 3.38 * 10^(38), with about seven significant decimal
  4923.  digits. This representation is adequate for the data manipulated by many
  4924.  microcomputer applications.
  4925.  
  4926.  The utility of the REAL data type is extended by the PL/M-386 compiler's
  4927.  practice of holding intermediate results in the 80387's extended real
  4928.  format. This means that the full range and precision of the processor are
  4929.  utilized for intermediate results. Underflow, overflow, and rounding
  4930.  exceptions are most likely to occur during intermediate computations rather
  4931.  than during calculation of an expression's final result. Holding
  4932.  intermediate results in extended-precision real format greatly reduces the
  4933.  likelihood of overflow and underflow and eliminates roundoff as a serious
  4934.  source of error until the final assignment of the result is performed.
  4935.  
  4936.  The compiler generates 80387 code to evaluate expressions that contain REAL
  4937.  data types, whether variables or constants or both. This means that
  4938.  addition, subtraction, multiplication, division, comparison, and assignment
  4939.  of REALs will be performed by the NPX. INTEGER expressions, on the other
  4940.  hand, are evaluated on the CPU.
  4941.  
  4942.  Five built-in procedures (Table 5-1) give the PL/M-386 programmer access to
  4943.  80387 functions manipulated by the processor control instructions. Prior to
  4944.  any arithmetic operations, a typical PL/M-386 program will set up the NPX
  4945.  using the INIT$REAL$MATH$UNIT procedure and then issue SET$REAL$MODE to
  4946.  configure the NPX. SET$REAL$MODE loads the 80387 control word, and its
  4947.  16-bit parameter has the format shown for the control word in Chapter 2.
  4948.  The recommended value of this parameter is 033EH (round to nearest, 64-bit
  4949.  precision, all exceptions masked except invalid operation). Other settings
  4950.  may be used at the programmer's discretion.
  4951.  
  4952.  If any exceptions are unmasked, an exception handler must be provided in
  4953.  the form of an interrupt procedure that is designated to be invoked via CPU
  4954.  interrupt vector number 16. The exception handler can use the GET$REAL$ERROR
  4955.  procedure to obtain the low-order byte of the 80387 status word and to then
  4956.  clear the exception flags. The byte returned by GET$REAL$ERROR contains the
  4957.  exception flags; these can be examined to determine the source of the
  4958.  exception.
  4959.  
  4960.  The SAVE$REAL$STATUS and RESTORE$REAL$STATUS procedures are provided
  4961.  for multitasking environments where a running task that uses the 80387 may
  4962.  be preempted by another task that also uses the 80387. It is the
  4963.  responsibility of the operating system to issue SAVE$REAL$STATUS before it
  4964.  executes any statements that affect the 80387; these include the
  4965.  INIT$REAL$MATH$UNIT and SET$REAL$MODE procedures as well as arithmetic
  4966.  expressions. SAVE$REAL$STATUS saves the 80387 state (registers, status, and
  4967.  control words, etc.) on the CPU's stack. RESTORE$REAL$STATUS reloads the
  4968.  state information; the preempting task must invoke this procedure before
  4969.  terminating in order to restore the 80387 to its state at the time the
  4970.  running task was preempted. This enables the preempted task to resume
  4971.  execution from the point of its preemption.
  4972.  
  4973.  
  4974.  Table 5-1.  PL/M-386 Built-In Procedures
  4975.  
  4976.  Procedure                80387         Description
  4977.                           Instruction
  4978.  
  4979.  INIT$REAL$MATH$UNIT      FINIT         Initialize processor.
  4980.  SET$REAL$MODE            FLDCW         Set exception masks, rounding
  4981.                                         precision, and infinity controls.
  4982.  GET$REAL$ERROR           FNSTSW        Store, then clear, exception flags.
  4983.                           & FNCLEX
  4984.  SAVE$REAL$STATUS         FNSAVE        Save processor state.
  4985.  RESTORE$REAL$STATUS      FRSTOR        Restore processor state.
  4986.  
  4987.  
  4988.  5.1.4  ASM386
  4989.  
  4990.  The ASM386 assembly language provides programmers with complete access to
  4991.  all of the facilities of the 80386 and 80387 processors.
  4992.  
  4993.  The programmer's view of the 80386/80387 hardware is a single machine with
  4994.  these resources:
  4995.  
  4996.    ■  160 instructions
  4997.    ■  12 data types
  4998.    ■  8 general registers
  4999.    ■  6 segment registers
  5000.    ■  8 floating-point registers, organized as a stack
  5001.  
  5002.  
  5003.  5.1.4.1  Defining Data
  5004.  
  5005.  The ASM386 directives shown in Table 5-2 allocate storage for 80387
  5006.  variables and constants. As with other storage allocation directives, the
  5007.  assembler associates a type with any variable defined with these directives.
  5008.  The type value is equal to the length of the storage unit in bytes (10 for
  5009.  DT, 8 for DQ, etc.). The assembler checks the type of any variable coded in
  5010.  an instruction to be certain that it is compatible with the instruction.
  5011.  For example, the coding FIADD ALPHA will be flagged as an error if ALPHA's
  5012.  type is not 2 or 4, because integer addition is only available for word and
  5013.  short integer (doubleword) data types. The operand's type also tells the
  5014.  assembler which machine instruction to produce; although to the programmer
  5015.  there is only an FIADD instruction, a different machine instruction is
  5016.  required for each operand type.
  5017.  
  5018.  On occasion it is desirable to use an instruction with an operand that has
  5019.  no declared type. For example, if register BX points to a short integer
  5020.  variable, a programmer may want to code FIADD [BX]. This can be done by
  5021.  informing the assembler of the operand's type in the instruction, coding
  5022.  FIADD DWORD PTR [BX]. The corresponding overrides for the other storage
  5023.  allocations are WORD PTR, QWORD PTR, and TBYTE PTR.
  5024.  
  5025.  The assembler does not, however, check the types of operands used in
  5026.  processor control instructions. Coding FRSTOR [BP] implies that the
  5027.  programmer has set up register BP to point to the location (probably in the
  5028.  stack) where the processor's 94-byte state record has been previously saved.
  5029.  
  5030.  The initial values for 80387 constants may be coded in several different
  5031.  ways. Binary integer constants may be specified as bit strings, decimal
  5032.  integers, octal integers, or hexadecimal strings. Packed decimal values are
  5033.  normally written as decimal integers, although the assembler will accept and
  5034.  convert other representations of integers. Real values may be written as
  5035.  ordinary decimal real numbers (decimal point required), as decimal numbers
  5036.  in scientific notation, or as hexadecimal strings. Using hexadecimal strings
  5037.  is primarily intended for defining special values such as infinities, NaNs,
  5038.  and denormalized numbers. Most programmers will find that ordinary decimal
  5039.  and scientific decimal provide the simplest way to initialize 80387
  5040.  constants. Figure 5-2 compares several ways of setting the various 80387
  5041.  data types to the same initial value.
  5042.  
  5043.  Note that preceding 80387 variables and constants with the ASM386 EVEN
  5044.  directive ensures that the operands will be word-aligned in memory. The best
  5045.  performance is obtained when data transfers are double-word aligned. All
  5046.  80387 data types occupy integral numbers of words so that no storage is
  5047.  "wasted" if blocks of variables are defined together and preceded by a
  5048.  single EVEN declarative.
  5049.  
  5050.  
  5051.  Table 5-2.  ASM386 Storage Allocation Directives
  5052.  
  5053.  Directive   Interpretation       Data Types
  5054.  
  5055.  DW          Define Word          Word integer
  5056.  DD          Define Doubleword    Short integer, short real
  5057.  DQ          Dfine Quadword       Long integer, long real
  5058.  DT          Define Tenbyte       Packed decimal, temporary real
  5059.  
  5060.  
  5061.  Figure 5-2.  Sample 80387 Constants
  5062.  
  5063.  ; THE FOLLOWING ALL ALLOCATE THE CONSTANT: -126
  5064.  ; NOTE TWO'S COMPLETE STORAGE OF NEGATIVE BINARY INTEGERS.
  5065.  ;
  5066.  ; EVEN                                  ; FORCE WORD ALIGNMENT
  5067.  WORD_INTEGER    DW  111111111000010B    ; BIT STRING
  5068.  SHORT_INTEGER   DD  0FFFFFF82H          ; HEX STRING MUST START
  5069.                                          ; WITH DIGIT
  5070.  LONG_INTEGER    DQ  -126                ; ORDINARY DECIMAL
  5071.  SINGLE_REAL     DD  -126.0              ; NOTE PRESENCE OF '.'
  5072.  DOUBLE_REAL     DD  -1.26E2             ; "SCIENTIFIC"
  5073.  PACKED_DECIMAL  DT  -126                ; ORDINARY DECIMAL INTEGER
  5074.  ;
  5075.  ; IN THE FOLLOWING, SIGN AND EXPONENT IS 'C005'
  5076.  ;    SIGNIFICAND IS '7E00...00', 'R' INFORMS ASSEMBLER THAT
  5077.  ;    THE STRING REPRESENTS A REAL DATA TYPE.
  5078.  ;
  5079.  EXTENDED_REAL   DT  0C0057E00000000000000R  ; HEX STRING
  5080.  
  5081.  
  5082.  5.1.4.2  Records and Structures
  5083.  
  5084.  The ASM386 RECORD and STRUC (structure) declaratives can be very useful in
  5085.  NPX programming. The record facility can be used to define the bit fields of
  5086.  the control, status, and tag words. Figure 5-3 shows one definition of the
  5087.  status word and how it might be used in a routine that polls the 80387 until
  5088.  it has completed an instruction.
  5089.  
  5090.  Because structures allow different but related data types to be grouped
  5091.  together, they often provide a natural way to represent "real world" data
  5092.  organizations. The fact that the structure template may be "moved" about in
  5093.  memory adds to its flexibility. Figure 5-4 shows a simple structure that
  5094.  might be used to represent data consisting of a series of test score
  5095.  samples. A structure could also be used to define the organization of the
  5096.  information stored and loaded by the FSTENV and FLDENV instructions.
  5097.  
  5098.  
  5099.  Figure 5-3.  Status Word Record Definition
  5100.  
  5101.  ; RESERVE SPACE FOR STATUS WORD
  5102.  STATUS_WORD
  5103.  ; LAY OUT STATUS WORD FIELDS
  5104.  STATUS RECORD
  5105.  &   BUSY:           1,
  5106.  &   COND_CODE3:     1,
  5107.  &   STACK_TOP:      3,
  5108.  &   COND_CODE2:     1,
  5109.  &   COND_CODE1:     1,
  5110.  &   COND_CODE0:     1,
  5111.  &   INT_REQ:        1,
  5112.  &   S_FLAG:         1,
  5113.  &   P_FLAG:         1,
  5114.  &   U_FLAG:         1,
  5115.  &   O_FLAG:         1,
  5116.  &   Z_FLAG:         1,
  5117.  &   D_FLAG:         1,
  5118.  &   I_FLAG:         1
  5119.  ; REDUCE UNTIL COMPLETE
  5120.  REDUCE: FPREM1
  5121.          FNSTSW  STATUS_WORD
  5122.          TEST    STATUS_WORD, MASK_COND_CODE2
  5123.          JNZ     REDUCE
  5124.  
  5125.  
  5126.  Figure 5-4.  Structure Definition
  5127.  
  5128.  SAMPLE     STRUC
  5129.      N_OBS   DD  ?   ; SHORT INTEGER
  5130.      MEAN    DQ  ?   ; DOUBLE REAL
  5131.      MODE    DW  ?   ; WORD INTEGER
  5132.      STD_DEV DQ  ?   ; DOUBLE REAL
  5133.      ; ARRAY OF OBSERVATIONS -- WORD INTEGER
  5134.      TEST_SCORES DW 1000 DUP (?)
  5135.  SAMPLE     ENDS
  5136.  
  5137.  
  5138.  5.1.4.3  Addressing Methods
  5139.  
  5140.  80387 memory data can be accessed with any of the memory addressing methods
  5141.  provided by the ModR/M byte and (optionally) the SIB byte. This means that
  5142.  80387 data types can be incorporated in data aggregates ranging from simple
  5143.  to complex according to the needs of the application. The addressing methods
  5144.  and the ASM386 notation used to specify them in instructions make the
  5145.  accessing of structures, arrays, arrays of structures, and other
  5146.  organizations direct and straightforward. Table 5-3 gives several examples
  5147.  of 80387 instructions coded with operands that illustrate different
  5148.  addressing methods.
  5149.  
  5150.  
  5151.  Table 5-3.  Addressing Method Examples
  5152.  
  5153.  Coding                    Interpretation
  5154.  
  5155.  FIADD ALPHA               ALPHA is a simple scalar (mode is direct).
  5156.  
  5157.  FDIVR ALPHA.BETA          BETA is a field in a structure that is
  5158.                            "overlaid" on ALPHA (mode is direct).
  5159.  
  5160.  FMUL QWORD PTR [BX]       BX contains the address of a long real
  5161.                            variable (mode is register indirect).
  5162.  
  5163.  FSUB ALPHA [SI]           ALPHA is an array and SI contains the
  5164.                            offset of an array element from the start of
  5165.                            the array (mode is indexed).
  5166.  
  5167.  FILD [BP].BETA            BP contains the address of a structure on
  5168.                            the CPU stack and BETA is a field in the
  5169.                            structure (mode is based).
  5170.  
  5171.  FBLD TBYTE PTR [BX] [DI]  BX contains the address of a packed
  5172.                            decimal array and DI contains the offset of
  5173.                            an array element (mode is based indexed).
  5174.  
  5175.  
  5176.  5.1.5  Comparative Programming Example
  5177.  
  5178.  Figures 5-5 and 5-6 show the PL/M-386 and ASM386 code for a simple 80387
  5179.  program, called ARRSUM. The program references an array (X$ARRAY), which
  5180.  contains 0-100 single real values; the integer variable N$OF$X indicates the
  5181.  number of array elements the program is to consider. ARRSUM steps through
  5182.  X$ARRAY accumulating three sums:
  5183.  
  5184.    ■  SUM$X, the sum of the array values
  5185.  
  5186.    ■  SUM$INDEXES, the sum of each array value times its index, where the
  5187.       index of the first element is 1, the second is 2, etc.
  5188.  
  5189.    ■  SUM$SQUARES, the sum of each array element squared
  5190.  
  5191.  (A true program, of course, would go beyond these steps to store and use
  5192.  the results of these calculations.) The control word is set with the
  5193.  recommended values: round to nearest, 64-bit precision, interrupts enabled,
  5194.  and all exceptions masked except invalid operation. It is assumed that an
  5195.  exception handler has been written to field the invalid operation if it
  5196.  occurs, and that it is invoked by interrupt pointer 16. Either version of
  5197.  the program will run on an actual or an emulated 80387 without altering the
  5198.  code shown.
  5199.  
  5200.  The PL/M-386 version of ARRSUM (Figure 5-5) is very straightforward and
  5201.  illustrates how easily the 80387 can be used in this language. After
  5202.  declaring variables, the program calls built-in procedures to initialize the
  5203.  processor (or its emulator) and to load to the control word. The program
  5204.  clears the sum variables and then steps through X$ARRAY with a DO-loop. The
  5205.  loop control takes into account PL/M-386's practice of considering the
  5206.  index of the first element of an array to be 0. In the computation of
  5207.  SUM$INDEXES, the built-in procedure FLOAT converts I+1 from integer to real
  5208.  because the language does not support "mixed mode" arithmetic. One of the
  5209.  strengths of the NPX, of course, is that it does support arithmetic on mixed
  5210.  data types (because all values are converted internally to the 80-bit
  5211.  extended-precision real format).
  5212.  
  5213.  The ASM386 version (Figure 5-6) defines the external procedure INIT387,
  5214.  which makes the different initialization requirements of the processor and
  5215.  its emulator transparent to the source code. After defining the data and
  5216.  setting up the segment registers and stack pointer, the program calls
  5217.  INIT387 and loads the control word. The computation begins with the next
  5218.  three instructions, which clear three registers by loading (pushing) zeros
  5219.  onto the stack. As shown in Figure 5-7, these registers remain at the
  5220.  bottom of the stack throughout the computation while temporary values are
  5221.  pushed on and popped off the stack above them.
  5222.  
  5223.  The program uses the CPU LOOP instruction to control its iteration through
  5224.  X_ARRAY; register ECX, which LOOP automatically decrements, is loaded with
  5225.  N_OF_X, the number of array elements to be summed. Register ESI is used to
  5226.  select (index) the array elements. The program steps through X_ARRAY from
  5227.  back to front, so ESI is initialized to point at the element just beyond the
  5228.  first element to be processed. The ASM386 TYPE operator is used to determine
  5229.  the number of bytes in each array element. This permits changing X_ARRAY to
  5230.  a double-precision real array by simply changing its definition (DD to DQ)
  5231.  and reassembling.
  5232.  
  5233.  Figure 5-7 shows the effect of the instructions in the program loop on the
  5234.  NPX register stack. The figure assumes that the program is in its first
  5235.  iteration, that N_OF_X is 20, and that X_ARRAY(19) (the 20th element)
  5236.  contains the value 2.5. When the loop terminates, the three sums are left as
  5237.  the top stack elements so that the program ends by simply popping them into
  5238.  memory variables.
  5239.  
  5240.  
  5241.  Figure 5-5.  Sample PL/M-386 Program
  5242.  
  5243.  XENIX286 PL/M-386 DEBUG X291a COMPILATION OF MODULE ARRAYSUM
  5244.  OBJECT MODULE PLACED IN arraysum.obj
  5245.  COMPILER INVOKED BY:  plm386 arraysum.plm
  5246.  
  5247.  
  5248.              /***********************************************************
  5249.              *                                                          *
  5250.              *                      ARRAYSUM  MODDULE                   *
  5251.              *                                                          *
  5252.              ***********************************************************/
  5253.  
  5254.    1         array$sum:      do;
  5255.  
  5256.    2   1        declare (sum$x, sum$indexes, sum$squares) real;
  5257.    3   1        declare x$array(100) real;
  5258.    4   1        declare (n$of$x, i) integer;
  5259.    5   1        declare control$387 literally `033eh';
  5260.  
  5261.                 /* Assume x$array and n$of$x are initialized */
  5262.    6   1        call init$real$math$unit;
  5263.    7   1        call set$real$mode(control$387);
  5264.  
  5265.                 /* Clear sums */
  5266.    8   1        sum$x, sum$indexes, sum$squares = 0.0;
  5267.  
  5268.                 /* Loop through array, accumulating sums */
  5269.    9   1        do i = 0 to n$of$x - 1;
  5270.   10   2             sum$x = sum$x + x$array(i);
  5271.   11   2             sum$indexes = sum$indexes + (x$array(i)*float(i+1));
  5272.   12   2             sum$squares = sum$squares + (x$array(i)*x$array(i));
  5273.   13   2        end;
  5274.  
  5275.                 /* etc. */
  5276.  
  5277.   14   1     end array$sum;
  5278.  
  5279.  
  5280.   MODULE INFORMATION:
  5281.  
  5282.     CODE AREA SIZE      = 000000A0H       160D
  5283.     CONSTANT AREA SIZE  = 00000004H         4D
  5284.     VARIABLE AREA SIZE  = 000001A4H       420D
  5285.     MAXIMUM  STACK SIZE = 00000004H         4D
  5286.     32 LINES READ
  5287.     0 PROGRAM WARNINGS
  5288.     0 PROGRAM ERRORS
  5289.  
  5290.   DICTIONARY SUMMARY:
  5291.  
  5292.     8KB MEMORY USED
  5293.     0KB DISK SPACE USED
  5294.  
  5295.   END OF PL/M-386 COMPILATION
  5296.  
  5297.  
  5298.  Figure 5-6.  Sample ASM386 Program
  5299.  
  5300.  XENIX286 80386 MACRO ASSEMBLER V1.0, ASSEMBLY OF MODULE ARRAYSUM
  5301.  OBJECT MODULE PLACED IN arraysum.obj
  5302.  ASSEMBLER INVOKED BY: asm386 arraysum.asm
  5303.  
  5304.  LOC       OBJ                         LINE    SOURCE
  5305.  
  5306.                                 1    name       arraysum
  5307.                                 2
  5308.                                 3    ; Define initialization routine
  5309.                                 4
  5310.                                 5    extrn      init387:far
  5311.                                 6
  5312.                                 7    ; Allocate space for data
  5313.                                 8
  5314.  --------                       9    data       segment rw public
  5315.  00000000  3E03                10    control_387        dw 033eh
  5316.  00000002  ????????            11    n_of_x             dd ?
  5317.  00000006  (100                12    x_array            cd 100 dup (?)
  5318.            ????????
  5319.            )
  5320.  00000196  ????????            13    sum_squares        dd ?
  5321.  0000019A  ????????            14    sum_indexes        dd ?
  5322.  0000019E  ????????            15    sum_x              dd ?
  5323.  --------                      16    data       ends
  5324.                                17
  5325.                                18    ; Allocate CPU stack space
  5326.                                19
  5327.  --------                      20    stack      stackseg   400
  5328.                                21
  5329.                                22    ; Begin code
  5330.                                23
  5331.  --------                      24    code       segment er public
  5332.                                25
  5333.                                26    assume  ds:data, ss:stack
  5334.                                27
  5335.  00000000                      28    start:
  5336.  00000000  66B8----        R   29         mov     ax, data
  5337.  00000004  8ED8                30         mov     ds, ax
  5338.  00000006  66B8----        R   31         mov     ax, stack
  5339.  0000000A  B800000000          32         mov     eax, 0h
  5340.  0000000F  8E00                33         mov     ss, ax
  5341.  00000011  BC00000000      R   34         mov     esp, stackstart stack
  5342.                                35
  5343.                                36    ; Assume x_array and n_of_x have
  5344.                                37    ; been initialized
  5345.                                38
  5346.                                39    ; Prepare the 80387 or its emulator
  5347.                                40
  5348.  00000016  9A00000000----  E   41         call    init387
  5349.  0000001D  D92D00000000    R   42         fldcw   control_387
  5350.                                43
  5351.                                44    ; Clear three registers to hold
  5352.                                45    ; running sums
  5353.                                46
  5354.  00000023  D9EE                47         fldz
  5355.  00000025  D9EE                48         fldz
  5356.  00000027  D9EE                49         fldz
  5357.                                50
  5358.                                51    ; Setup ECX as loop counter and ESI
  5359.                                52    ; as index into x array
  5360.                                53
  5361.  00000029  8B0D02000000    R   54         mov     ecx, n of x
  5362.  0000002F  F7E9                55         imul    ecx
  5363.  00000031  8BF0                56         mov     esi, eax
  5364.                                57
  5365.                                58    ; ESI now contains index of last
  5366.                                59    ; element + 1
  5367.                                60    ; Loop through x_array and
  5368.                                61    ; accumulate sum
  5369.                                62
  5370.  00000033                      43    sum_next:
  5371.                                64    ; backup one element and push on
  5372.                                65    ; the stack
  5373.                                66
  5374.  00000033  83EE04              67         sub     esi,  type x_array
  5375.  00000036  D98606000000    R   68         fld     x_array[esi]
  5376.                                69
  5377.                                70    ; add to the sum and duplicate x
  5378.                                71    ; on the stack
  5379.                                72
  5380.  0000003C  DCC3                73         fadd    st(3), st
  5381.  0000003E  D9C0                74         fld     st
  5382.                                75
  5383.                                76    ; square it and add into the sum of
  5384.                                77    ; (index+1) and discard
  5385.                                78
  5386.  00000040  DCC8                79         fmul    st, st
  5387.  00000042  DEC2                80         facdp   st(2), st
  5388.                                81
  5389.                                82    ; reduce index for next iteration
  5390.                                83
  5391.  00000044  FF0D02000000    R   84         dec     n_of_x
  5392.  0000004A  E2E7                85         loop    sum_next
  5393.                                86
  5394.                                87    ; Pop sums into memory
  5395.                                88
  5396.  0000004C                      89    pop_results:
  5397.  0000004C  D91D96010000    R   90         fstp    sum_squares
  5398.  00000052  D91D9A010000    R   91         fstp    sum_indexes
  5399.  00000058  D91D9E010000    R   92         fstp    sum_x
  5400.  0000005E  9B                  93         fwait
  5401.                                94
  5402.                                95    ;
  5403.                                96    ; Etc.
  5404.                                97    ;
  5405.  --------                      98    code       ends
  5406.                                99    end     start, ds:data, ss:stack
  5407.  
  5408.  ASSEMBLY COMPLETE,    NO WARNINGS,    NO ERRORS.
  5409.  
  5410.  
  5411.  Figure 5-7.  Instructions and Register Stack
  5412.  
  5413.           FLDZ, FLDZ, FLDZ                       FLD X_ARRAY[SI]
  5414.           ╔══════════════╗─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╔══════════════╗
  5415.      ST(0)║      0.0     ║ SUM_SQUARES     ST(O)║      2.5     ║ X_ARRAY(19)
  5416.           ╠══════════════╣                      ╠══════════════╣
  5417.      ST(1)║      0.0     ║ SUM_INDEXES     ST(1)║              ║ SUM_SQUARES
  5418.           ╠══════════════╣                      ╠══════════════╣
  5419.      ST(2)║      0.0     ║ SUM_X           ST(2)║      0.0     ║ SUM_INDEXES
  5420.           ╚══════════════╝                      ╠══════════════╣
  5421.                                            ST(3)║      0.0     ║ SUM_X
  5422.                             ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╚══════════════╝
  5423.                             │
  5424.            FADD_ST(3), ST ─┘                        FLD_ST
  5425.           ╔══════════════╗─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╔══════════════╗
  5426.      ST(O)║      2.5     ║ X_ARRAY(19)     ST(O)║      2.5     ║ X_ARRAY(19)
  5427.           ╠══════════════╣                      ╠══════════════╣
  5428.      ST(1)║      0.0     ║ SUM_SQUARES     ST(1)║      2.5     ║ X_ARRAY(19)
  5429.           ╠══════════════╣                      ╠══════════════╣
  5430.      ST(2)║      0.0     ║ SUM_INDEXES     ST(2)║      0.0     ║ SUM_SQUARES
  5431.           ╠══════════════╣                      ╠══════════════╣
  5432.      ST(3)║      2.5     ║ SUM_X           ST(3)║      0.0     ║ SUM_INDEXES
  5433.           ╚══════════════╝                      ╠══════════════╣
  5434.                                            ST(4)║      2.5     ║ SUM_X
  5435.                             ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╚══════════════╝
  5436.                             │
  5437.             FMUL_ST, ST  ──┘                    FADDP_ST(2), ST
  5438.           ╔══════════════╗─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╔══════════════╗
  5439.      ST(0)║      6.25    ║ X_ARRAY(19)²    ST(O)║      2.5     ║ X_ARRAY(19)
  5440.           ╠══════════════╣                      ╠══════════════╣
  5441.      ST(1)║      2.5     ║ X_ARRAY(19)     ST(1)║      6.25    ║ SUM_SQUARES
  5442.           ╠══════════════╣                      ╠══════════════╣
  5443.      ST(2)║      0.0     ║ SUM_SQUARES     ST(2)║      0.0     ║ SUM_INDEXES
  5444.           ╠══════════════╣                      ╠══════════════╣
  5445.      ST(3)║      0.0     ║ SUM_INDEXES     ST(3)║      2.5     ║ SUM_X
  5446.           ╠══════════════╣                      ╚══════════════╝
  5447.      ST(4)║      2.5     ║ SUM_X                │
  5448.           ╚══════════════╝                      │
  5449.                             ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
  5450.             FIMUL N_OF_X ──┘                    FADDP_ST(2), ST
  5451.           ╔══════════════╗─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╔══════════════╗
  5452.      ST(O)║      50.0    ║ X_ARRAY(19)*20  ST(O)║      6.25    ║ SUM_SQUARES
  5453.           ╠══════════════╣                      ╠══════════════╣
  5454.      ST(1)║      6.25    ║ SUM_SQUARES     ST(1)║      50.0    ║ SUM_INDEXES
  5455.           ╠══════════════╣                      ╠══════════════╣
  5456.      ST(2)║      0.0     ║ SUM_INDEXES     ST(2)║      2.5     ║ SUM_X
  5457.           ╠══════════════╣                      ╚══════════════╝
  5458.      ST(3)║      2.5     ║ SUM_X
  5459.           ╚══════════════╝
  5460.  
  5461.  
  5462.  5.1.6  80387 Emulation
  5463.  
  5464.  The programming of applications to execute on both 80386 with an 80387 and
  5465.  80386 systems without an 80387 is made much easier by the existence of an
  5466.  80387 emulator for 80386 systems. The Intel EMUL387 emulator offers a
  5467.  complete software counterpart to the 80387 hardware; NPX instructions can be
  5468.  simply emulated in software rather than being executed in hardware. With
  5469.  software emulation, the distinction between 80386 systems with or without an
  5470.  80387 is reduced to a simple performance differential. Identical numeric
  5471.  programs will simply execute more slowly (using software emulation of NPX
  5472.  instructions) on 80386 systems without an 80387 than on an 80386/80387
  5473.  system executing NPX instructions directly.
  5474.  
  5475.  When incorporated into the systems software, the emulation of NPX
  5476.  instructions on the 80386 systems is completely transparent to the
  5477.  applications programmer. Applications software needs no special libraries,
  5478.  linking, or other activity to allow it to run on an 80386 with 80387
  5479.  emulation.
  5480.  
  5481.  To the applications programmer, the development of programs for 80386
  5482.  systems is the same whether the 80387 NPX hardware is available or not. The
  5483.  full 80387 instruction set is available for use, with NPX instructions being
  5484.  either emulated or executed directly. Applications programmers need not be
  5485.  concerned with the hardware configuration of the computer systems on which
  5486.  their applications will eventually run.
  5487.  
  5488.  For systems programmers, details relating to 80387 emulators are described
  5489.  in Chapter 6.
  5490.  
  5491.  The EMUL387 software emulator for 80386 systems is available from Intel as
  5492.  a separate program product.
  5493.  
  5494.  
  5495.  5.2  Concurrent Processing With the 80387
  5496.  
  5497.  Because the 80386 CPU and the 80387 NPX have separate execution units, it
  5498.  is possible for the NPX to execute numeric instructions in parallel with
  5499.  instructions executed by the CPU. This simultaneous execution of different
  5500.  instructions is called concurrency.
  5501.  
  5502.  No special programming techniques are required to gain the advantages of
  5503.  concurrent execution; numeric instructions for the NPX are simply placed in
  5504.  line with the instructions for the CPU. CPU and numeric instructions are
  5505.  initiated in the same order as they are encountered by the CPU in its
  5506.  instruction stream. However, because numeric operations performed by the NPX
  5507.  generally require more time than operations performed by the CPU, the CPU
  5508.  can often execute several of its instructions before the NPX completes a
  5509.  numeric instruction previously initiated.
  5510.  
  5511.  This concurrency offers obvious advantages in terms of execution
  5512.  performance, but concurrency also imposes several rules that must be
  5513.  observed in order to assure proper synchronization of the 80386 CPU and
  5514.  80387 NPX.
  5515.  
  5516.  All Intel high-level languages automatically provide for and manage
  5517.  concurrency in the NPX. Assembly-language programmers, however, must
  5518.  understand and manage some areas of concurrency in exchange for the
  5519.  flexibility and performance of programming in assembly language. This
  5520.  section is for the assembly-language programmer or well-informed
  5521.  high-level-language programmer.
  5522.  
  5523.  
  5524.  5.2.1  Managing Concurrency
  5525.  
  5526.  Concurrent execution of the host and 80387 is easy to establish and
  5527.  maintain. The activities of numeric programs can be split into two major
  5528.  areas: program control and arithmetic. The program control part performs
  5529.  activities such as deciding what functions to perform, calculating addresses
  5530.  of numeric operands, and loop control. The arithmetic part simply adds,
  5531.  subtracts, multiplies, and performs other operations on the numeric
  5532.  operands. The NPX and host are designed to handle these two parts separately
  5533.  and efficiently.
  5534.  
  5535.  Concurrency management is required to check for an exception before letting
  5536.  the 80386 change a value just used by the 80387. Almost any numeric
  5537.  instruction can, under the wrong circumstances, produce a numeric exception.
  5538.  For programmers in higher-level languages, all required synchronization is
  5539.  automatically provided by the appropriate compiler. For assembly-language
  5540.  programmers exception synchronization remains the responsibility of the
  5541.  assembly-language programmer.
  5542.  
  5543.  A complication is that a programmer may not expect his numeric program to
  5544.  cause numeric exceptions, but in some systems, they may regularly happen. To
  5545.  better understand these points, consider what can happen when the NPX
  5546.  detects an exception.
  5547.  
  5548.  Depending on options determined by the software system designer, the NPX
  5549.  can perform one of two things when a numeric exception occurs:
  5550.  
  5551.    ■  The NPX can provide a default fix-up for selected numeric exceptions.
  5552.       Programs can mask individual exception types to indicate that the NPX
  5553.       should generate a safe, reasonable result whenever that exception
  5554.       occurs. The default exception fix-up activity is treated by the NPX as
  5555.       part of the instruction causing the exception; no external indication
  5556.       of the exception is given. When exceptions are detected, a flag is set
  5557.       in the numeric status register, but no information regarding where or
  5558.       when is available. If the NPX performs its default action for all
  5559.       exceptions, then the need for exception synchronization is not
  5560.       manifest. However, as will be shown later, this is not sufficient
  5561.       reason to ignore exception synchronization when designing programs that
  5562.       use the 80387.
  5563.  
  5564.    ■  As an alternative to the NPX default fix-up of numeric exceptions, the
  5565.       80386 CPU can be notified whenever an exception occurs. When a numeric
  5566.       exception is unmasked and the exception occurs, the NPX stops further
  5567.       execution of the numeric instruction and signals this event to the CPU.
  5568.       On the next occurrence of an ESC or WAIT instruction, the CPU traps to
  5569.       a software exception handler. The exception handler can then implement
  5570.       any sort of recovery procedures desired for any numeric exception
  5571.       detectable by the NPX. Some ESC instructions do not check for
  5572.       exceptions. These are the nonwaiting forms FNINIT, FNSTENV, FNSAVE,
  5573.       FNSTSW, FNSTCW, and FNCLEX.
  5574.  
  5575.  When the NPX signals an unmasked exception condition, it is requesting
  5576.  help. The fact that the exception was unmasked indicates that further
  5577.  numeric program execution under the arithmetic and programming rules of the
  5578.  NPX is unreasonable.
  5579.  
  5580.  If concurrent execution is allowed, the state of the CPU when it recognizes
  5581.  the exception is undefined. The CPU may have changed many of its internal
  5582.  registers and be executing a totally different program by the time the
  5583.  exception occurs. To handle this situation, the NPX has special registers
  5584.  updated at the start of each numeric instruction to describe the state of
  5585.  the numeric program when the failed instruction was attempted.
  5586.  
  5587.  Exception synchronization ensures that the NPX is in a well-defined state
  5588.  after an unmasked numeric exception occurs. Without a well-defined state, it
  5589.  would be impossible for exception recovery routines to determine why the
  5590.  numeric exception occurred, or to recover successfully from the exception.
  5591.  
  5592.  The following two sections illustrate the need to always consider
  5593.  exception synchronization when writing 80387 code, even when the code is
  5594.  initially intended for execution with exceptions masked. If the code is
  5595.  later moved to an environment where exceptions are unmasked, the same code
  5596.  may not work correctly. An example of how some instructions written without
  5597.  exception synchronization will work initially, but fail when moved into a
  5598.  new environment is shown in Figure 5-8.
  5599.  
  5600.  
  5601.  Figure 5-8.  Exception Synchronization Examples
  5602.  
  5603.  INCORRECT ERROR SYNCHRONIZATION
  5604.  
  5605.  FILD   COUNT  ; NPX instruction
  5606.  INC    COUNT  ; CPU instruction alters operand
  5607.  FSQRT  COUNT  ; subsequent NPX instruction -- error from
  5608.                ;    previous NPX instruction detected here
  5609.  
  5610.  PROPER ERROR SYNCHRONIZATION
  5611.  
  5612.  FILD   COUNT  ; NPX instruction
  5613.  FSQRT         ; subsequent NPX instruction -- error from
  5614.                ;    previous NPX instruction detected here
  5615.  INC    COUNT  ; CPU instruction alters operand
  5616.  
  5617.  
  5618.  5.2.1.1  Incorrect Exception Synchronization
  5619.  
  5620.  In Figure 5-8, three instructions are shown to load an integer, calculate
  5621.  its square root, then increment the integer. The 80386-to-80387 interface
  5622.  and synchronous execution of the NPX emulator will allow this program to
  5623.  execute correctly when no exceptions occur on the FILD instruction.
  5624.  
  5625.  This situation changes if the 80387 numeric register stack is extended to
  5626.  memory. To extend the NPX stack to memory, the invalid exception is
  5627.  unmasked. A push to a full register or pop from an empty register sets SF
  5628.  and causes an invalid exception.
  5629.  
  5630.  The recovery routine for the exception must recognize this situation, fix
  5631.  up the stack, then perform the original operation.  The recovery routine
  5632.  will not work correctly in the first example shown in the figure. The
  5633.  problem is that the value of COUNT is incremented before the NPX can signal
  5634.  the exception to the CPU. Because COUNT is incremented before the exception
  5635.  handler is invoked, the recovery routine will load an incorrect value of
  5636.  COUNT, causing the program to fail or behave unreliably.
  5637.  
  5638.  
  5639.  5.2.1.2  Proper Exception Synchronization
  5640.  
  5641.  Exception synchronization relies on the WAIT instruction and the BUSY# and
  5642.  ERROR# signals of the 80387. When an unmasked exception occurs in the 80387,
  5643.  it asserts the ERROR# signal, signaling to the CPU that a numeric exception
  5644.  has occurred. The next time the CPU encounters a WAIT instruction or an
  5645.  exception-checking ESC instruction, the CPU acknowledges the ERROR# signal
  5646.  by trapping automatically to Interrupt #16, the processor-extension
  5647.  exception vector. If the following ESC or WAIT instruction is properly
  5648.  placed, the CPU will not yet have disturbed any information vital to
  5649.  recovery from the exception.
  5650.  
  5651.  
  5652.  Chapter 6  System-Level Numeric Programming
  5653.  
  5654.  ────────────────────────────────────────────────────────────────────────────
  5655.  
  5656.  System programming for 80387 systems requires a more detailed understanding
  5657.  of the 80387 NPX than does application programming. Such things as
  5658.  emulation, initialization, exception handling, and data and error
  5659.  synchronization are all the responsibility of the systems programmer. These
  5660.  topics are covered in detail in the sections that follow.
  5661.  
  5662.  
  5663.  6.1  80386/80387 Architecture
  5664.  
  5665.  On a software level, the 80387 NPX appears as an extension of the 80386
  5666.  CPU. On the hardware level, however, the mechanisms by which the 80386 and
  5667.  80387 interact are more complex. This section describes how the 80387 NPX
  5668.  and 80386 CPU interact and points out features of this interaction that are
  5669.  of interest to systems programmers.
  5670.  
  5671.  
  5672.  6.1.1  Instruction and Operand Transfer
  5673.  
  5674.  All transfers of instructions and operands between the 80387 and system
  5675.  memory are performed by the 80386 using I/O bus cycles. The 80387 appears to
  5676.  the CPU as a special peripheral device. It is special in two respects: the
  5677.  CPU initiates I/O automatically when it encounters ESC instructions, and the
  5678.  CPU uses reserved I/O addresses to communicate with the 80387. These I/O
  5679.  operations are completely transparent to software.
  5680.  
  5681.  Because the 80386 actually performs all transfers between the 80387 and
  5682.  memory, no additional bus drivers, controllers, or other components are
  5683.  necessary to interface the 80387 NPX to the local bus. The 80387 can utilize
  5684.  instructions and operands located in any memory accessible to the 80386 CPU.
  5685.  
  5686.  
  5687.  6.1.2  Independent of CPU Addressing Modes
  5688.  
  5689.  Unlike the 80287, the 80387 is not sensitive to the addressing and memory
  5690.  management of the CPU. The 80387 operates the same regardless of whether the
  5691.  80386 CPU is operating in real-address mode, in protected mode, or in
  5692.  virtual 8086 mode.
  5693.  
  5694.  The instruction FSETPM that was necessary in 80286/80287 systems to set the
  5695.  80287 into protected mode is not needed for the 80387. The 80387 treats this
  5696.  instruction as a no-op.
  5697.  
  5698.  Because the 80386 actually performs all transfers between the 80387 and
  5699.  memory, 80387 instructions can utilize any memory location accessible by the
  5700.  task currently executing on the 80386. When operating in protected mode, all
  5701.  references to memory operands are automatically verified by the 80386's
  5702.  memory management and protection mechanisms as for any other memory
  5703.  references by the currently-executing task. Protection violations associated
  5704.  with NPX instructions automatically cause the 80386 to trap to an
  5705.  appropriate exception handler.
  5706.  
  5707.  To the numerics programmer, the operating modes of the 80386 affect only
  5708.  the manner in which the NPX instruction and data pointers are represented in
  5709.  memory following an FSAVE or FSTENV instruction. Each of these instructions
  5710.  produces one of four formats depending on both the operating mode and on the
  5711.  operand-size attribute in effect for the instruction. The differences are
  5712.  detailed in the discussion of the FSAVE and FSTENV instructions in
  5713.  Chapter 4.
  5714.  
  5715.  
  5716.  6.1.3  Dedicated I/O Locations
  5717.  
  5718.  The 80387 NPX does not require that any memory addresses be set aside for
  5719.  special purposes. The 80387 does make use of I/O port addresses, but these
  5720.  are 32-bit addresses with the high-order bit set (i.e. > 80000000H);
  5721.  therefore, these I/O operations are completely transparent to the 80386
  5722.  software. Because these addresses are beyond the 64 Kbyte I/O addressing
  5723.  limit of I/O instructions, 80386 programs cannot reference these reserved
  5724.  I/O addresses directly.
  5725.  
  5726.  
  5727.  6.2  Processor Initialization and Control
  5728.  
  5729.  One of the principal responsibilities of systems software is the
  5730.  initialization, monitoring, and control of the hardware and software
  5731.  resources of the system, including the 80387 NPX. In this section, issues
  5732.  related to system initialization and control are described, including
  5733.  recognition of the NPX, emulation of the 80387 NPX in software if the
  5734.  hardware is not available, and the handling of exceptions that may occur
  5735.  during the execution of the 80387.
  5736.  
  5737.  
  5738.  6.2.1  System Initialization
  5739.  
  5740.  During initialization of an 80386 system, systems software must
  5741.  
  5742.    ■  Recognize the presence or absence of the NPX.
  5743.  
  5744.    ■  Set flags in the 80386 MSW to reflect the state of the numeric
  5745.       environment.
  5746.  
  5747.  If an 80387 NPX is present in the system, the NPX must be initialized. All
  5748.  of these activities can be quickly and easily performed as part of the
  5749.  overall system initialization.
  5750.  
  5751.  
  5752.  6.2.2  Hardware Recognition of the NPX
  5753.  
  5754.  The 80386 identifies the type of its coprocessor (80287 or 80387) by
  5755.  sampling its ERROR# input some time after the falling edge of RESET and
  5756.  before executing the first ESC instruction. The 80287 keeps its ERROR#
  5757.  output in inactive state after hardware reset; the 80387 keeps its ERROR#
  5758.  output in active state after hardware reset. The 80386 records this
  5759.  difference in the ET bit of control register zero (CR0). The 80386
  5760.  subsequently uses ET to control its interface with the coprocessor. If ET is
  5761.  set, it employs the 32-bit protocol of the 80387; if ET is not set, it
  5762.  employs the 16-bit protocol of the 80287.
  5763.  
  5764.  Systems software can (if necessary) change the value of ET. There are three
  5765.  reasons that ET may not be set:
  5766.  
  5767.    1.  An 80287 is actually present.
  5768.  
  5769.    2.  No coprocessor is present.
  5770.  
  5771.    3.  An 80387 is present but it is connected in a nonstandard manner that
  5772.        does not trigger the setting of ET.
  5773.  
  5774.  An example of case three is the PC/AT-compatible design described in
  5775.  Appendix F. In such cases, initialization software may need to change the
  5776.  value of ET.
  5777.  
  5778.  
  5779.  6.2.3  Software Recognition of the NPX
  5780.  
  5781.  Figure 6-1 shows an example of a recognition routine that determines
  5782.  whether an NPX is present, and distinguishes between the 80387 and the
  5783.  8087/80287. This routine can be executed on any 80386, 80286, or 8086
  5784.  hardware configuration that has an NPX socket.
  5785.  
  5786.  The example guards against the possibility of accidentally reading an
  5787.  expected value from a floating data bus when no NPX is present. Data read
  5788.  from a floating bus is undefined. By expecting to read a specific bit
  5789.  pattern from the NPX, the routine protects itself from the indeterminate
  5790.  state of the bus. The example also avoids depending on any values in
  5791.  reserved bits, thereby maintaining compatibility with future numerics
  5792.  coprocessors.
  5793.  
  5794.  
  5795.  Figure 6-1.  Software Routine to Recognize the 80287
  5796.  
  5797.  8086/87/88/186 MACRO ASSEMBLER  Test for presence of a Numerics Chip, Revisio
  5798.  
  5799.  
  5800.  DOS 3.20 (033-N) 8086/87/88/186 MACRO ASSEMBLER V2.0 ASSEMBLY OF MODULE TEST_
  5801.  OBJECT MODULE PLACED IN FINDNPX.OBJ
  5802.  
  5803.  LOC   OBJ         LINE    SOURCE
  5804.  
  5805.                       1 +1 $title('Test for presence of a Numerics Chip, Revis
  5806.                       2
  5807.                       3            name    Test_NPX
  5808.                       4
  5809.  ----                 5    stack   segment stack 'stack'
  5810.  0000  (100           6            dw      100 dup (?)
  5811.        ????
  5812.        )
  5813.  00C8  ????           7    sst     dw              ?
  5814.  ----                 8    stack   ends
  5815.                       9
  5816.  ----                10    data    segment public 'data'
  5817.  0000  0000          11    temp    dw      0h
  5818.  ----                12    data    ends
  5819.                      13
  5820.                      14    dgroup group    data, stack
  5821.                      15    cgroup group    code
  5822.                      16
  5823.  ----                17    code    segment public 'code'
  5824.                      18            assume cs:cgroup, ds:dgroup
  5825.                      19
  5826.  0000                20    start:
  5827.                      21    ;
  5828.                      22    ;       Look for an 8087, 80287, or 80387 NPX.
  5829.                      23    ;       Note that we cannot execute WAIT on 8086/88
  5830.                      24    ;
  5831.  0000                25    test npx:
  5832.  0000  90DBE3        26            fninit                  ; Must use non-wait
  5833.  0003  BE0000     R  27            mov     [si],offset dgroup:temp
  5834.  0006  C7045A5A      28            mov     word ptr [si],5A5AH ; Initialize te
  5835.  000A  90DD3C        29            fnstsw  [si]            ; Must use non-wait
  5836.                      30                                    ; It is not necessa
  5837.                      31                                    ;  after fnstsw or
  5838.  000D  803C00        32            cmp     byte ptr [si],0 ; See if correct st
  5839.  0010  752A          33            jne     no_npx          ; Jump if not a val
  5840.                      34    ;
  5841.                      35    ;       Now see if ones can be correctly written fr
  5842.                      36    ;
  5843.  0012  90D93C        37            fnstcw  [si]            ; Look at the contr
  5844.                      38                                    ; Do not use a WAIT
  5845.  0015  8B04          39            mov     ax,[si]         ; See if ones can b
  5846.  0017  253F10        40            and     ax,103fh        ; See if selected p
  5847.  001A  3D3F00        41            cmp     ax,3fh          ; Check that ones a
  5848.  001D  7510          42            jne     no npx          ; Jump if no NPX is
  5849.                      43    ;
  5850.                      44    ;       Some numerics chip is installed.  NPX instr
  5851.                      45    ;       See if the NPX is an 8087, 80287, or 80387.
  5852.                      46    ;       This code is necessary if a denormal except
  5853.                      47    ;       new 80387 instructions will be used.
  5854.                      48    ;
  5855.  001F 98D9E8         49            fld1                    ; Must use default
  5856.  0022 9BD9EE         50            fldz                    ; Form infinity
  5857.  0025 9BDEF9         51            fdiv                    ; 8087/287 says +in
  5858.  0028 9BD9C0         52            fld     st              ; Form negative inf
  5859.  002B 9BD9E0         53            fchs                    ; 80387 says +inf <
  5860.  002E 9BDED9         54            fcompp                  ; See if they are t
  5861.  0031 9BDD3C         55            fstsw   [si]            ; Look at status fr
  5862.  0034 8B04           56            mov     ax,[si]
  5863.  0036 9E             57            sahf                    ; See if the infini
  5864.  0037 7406           58            je      found_87_287    ; Jump if 8087/287
  5865.                      59    ;
  5866.                      60    ;       An 80387 is present.  If denormal exception
  5867.                      61    ;       they must be masked.  The 80387 will automa
  5868.                      62    ;       operands faster than an exception handler c
  5869.                      63    ;
  5870.  0039 EB0790         64            jmp     found_387
  5871.  003C                65    no_npx:
  5872.                      66    ;       set up for no NPX
  5873.                      67    ;               ...
  5874.                      68    ;
  5875.  003C EB0490         69            jmp exit
  5876.  003F                70    found_87_287:
  5877.                      71    ;       set up for 87/287
  5878.                      72    ;               ...
  5879.                      73    ;
  5880.  003F EB0190         74            jmp exit
  5881.  0042                75    found_387:
  5882.                      76    ;       set up for 387
  5883.                      77    ;               ...
  5884.                      78    ;
  5885.  0042                79    exit:
  5886.  ----                80    code    ends
  5887.                      81            end     start,ds:dgroup,ss:dgroup:sst
  5888.  
  5889.  ASSEMBLY COMPLETE, NO ERRORS FOUND
  5890.  
  5891.  
  5892.  6.2.4  Configuring the Numerics Environment
  5893.  
  5894.  Once the 80386 CPU has determined the presence or absence of the 80387 or
  5895.  80287 NPX, the 80386 must set either the MP or the EM bit in its own control
  5896.  register zero (CR0) accordingly. The initialization routine can either
  5897.  
  5898.    ■  Set the MP bit in CR0 to allow numeric instructions to be executed
  5899.       directly by the NPX.
  5900.  
  5901.    ■  Set the EM bit in the CR0 to permit software emulation of the numeric
  5902.       instructions.
  5903.  
  5904.  The MP (monitor coprocessor) flag of CR0 indicates to the 80386 whether an
  5905.  NPX is physically available in the system. The MP flag controls the function
  5906.  of the WAIT instruction. When executing a WAIT instruction, the 80386 tests
  5907.  the task switched (TS) bit only if MP is set; if it finds TS set under these
  5908.  conditions, the CPU traps to exception #7.
  5909.  
  5910.  The Emulation Mode (EM) bit of CR0 indicates to the 80386 whether NPX
  5911.  functions are to be emulated. If the CPU finds EM set when it executes an
  5912.  ESC instruction, program control is automatically trapped to exception #7,
  5913.  giving the exception handler the opportunity to emulate the functions of an
  5914.  80387.
  5915.  
  5916.  For correct 80386 operation, the EM bit must never be set concurrently with
  5917.  MP. The EM and MP bits of the 80386 are described in more detail in the
  5918.  80386 Programmer's Reference Manual. More information on software
  5919.  emulation for the 80387 NPX is described in the "80387 Emulation" section
  5920.  later in this chapter. In any case, if ESC instructions are to be executed,
  5921.  either the MP or EM bit must be set, but not both.
  5922.  
  5923.  
  5924.  6.2.5  Initializing the 80387
  5925.  
  5926.  Initializing the 80387 NPX simply means placing the NPX in a known state
  5927.  unaffected by any activity performed earlier. A single FNINIT instruction
  5928.  performs this initialization. All the error masks are set, all registers are
  5929.  tagged empty, TOP is set to zero, and default rounding and precision
  5930.  controls are set. Table 6-1 shows the state of the 80387 NPX following
  5931.  FINIT or FNINIT. This state is compatible with that of the 80287 after
  5932.  FINIT or after hardware RESET.
  5933.  
  5934.  The FNINIT instruction does not leave the 80387 in the same state as that
  5935.  which results from the hardware RESET signal. Following a hardware RESET
  5936.  signal, such as after initial power-up, the state of the 80387 differs in
  5937.  the following respects:
  5938.  
  5939.    1.  The mask bit for the invalid-operation exception is reset.
  5940.  
  5941.    2.  The invalid-operation exception flag is set.
  5942.  
  5943.    3.  The exception-summary bit is set (along with its mirror image, the
  5944.        B-bit).
  5945.  
  5946.  These settings cause assertion of the ERROR# signal as described
  5947.  previously. The FNINIT instruction must be used to change the 80387 state to
  5948.  one compatible with the 80287.
  5949.  
  5950.  
  5951.  Table 6-1.  NPX Processor State Following Initialization
  5952.  
  5953.  Field                   Value               Interpretation
  5954.  
  5955.  Control Word
  5956.     (Infinity Control)    0                 Affine
  5957.     Rounding Control       00                Round to nearest
  5958.     Precision Control      11                64 bits
  5959.     Exception Masks        111111            All exceptions masked
  5960.  Status Word
  5961.     (Busy)                 0                 ──
  5962.     Condition Code         0000              ──
  5963.     Stack Top              000               Register 0 is stack top
  5964.     Exception Summary      0                 No exceptions
  5965.     Stack Flag             0                 ──
  5966.     Exception Flags        000000            No exceptions
  5967.  Tag Word
  5968.     Tags                   11                Empty
  5969.     Registers              N.C.              Not changed
  5970.  Exception Pointers
  5971.     Instruction Code       N.C.              Not changed
  5972.     Instruction Address    N.C.              Not changed
  5973.     Operand Address        N.C.              Not changed
  5974.  
  5975.  
  5976.  6.2.6  80387 Emulation
  5977.  
  5978.  If it is determined that no 80387 NPX is available in the system, systems
  5979.  software may decide to emulate ESC instructions in software. This emulation
  5980.  is easily supported by the 80386 hardware, because the 80386 can be
  5981.  configured to trap to a software emulation routine whenever it encounters an
  5982.  ESC instruction in its instruction stream.
  5983.  
  5984.  Whenever the 80386 CPU encounters an ESC instruction, and its MP and EM
  5985.  status bits are set appropriately (MP=0, EM=1), the 80386 automatically
  5986.  traps to interrupt #7, the "processor extension not available" exception.
  5987.  The return link stored on the stack points to the first byte of the ESC
  5988.  instruction, including the prefix byte(s), if any. The exception handler can
  5989.  use this return link to examine the ESC instruction and proceed to emulate
  5990.  the numeric instruction in software.
  5991.  
  5992.  The emulator must step the return pointer so that, upon return from the
  5993.  exception handler, execution can resume at the first instruction following
  5994.  the ESC instruction.
  5995.  
  5996.  To an application program, execution on an 80386 system with 80387
  5997.  emulation is almost indistinguishable from execution on a system with an
  5998.  80387, except for the difference in execution speeds.
  5999.  
  6000.  There are several important considerations when using emulation on an 80386
  6001.  system:
  6002.  
  6003.    ■  When operating in protected mode, numeric applications using the
  6004.       emulator must be executed in execute-readable code segments. Numeric
  6005.       software cannot be emulated if it is executed in execute-only code
  6006.       segments. This is because the emulator must be able to examine the
  6007.       particular numeric instruction that caused the emulation trap.
  6008.  
  6009.    ■  Only privileged tasks can place the 80386 in emulation mode. The
  6010.       instructions necessary to place the 80386 in emulation mode are
  6011.       privileged instructions, and are not typically accessible to an
  6012.       application.
  6013.  
  6014.  An emulator package (EMUL387) that runs on 80386 systems is available from
  6015.  Intel. This emulation package operates in both real and protected mode as
  6016.  well as in virtual 8086 mode, providing a complete functional equivalent for
  6017.  the 80387 emulated in software.
  6018.  
  6019.  When using the EMUL387 emulator, writers of numeric exception handlers
  6020.  should be aware of one slight difference between the emulated 80387 and the
  6021.  80387 hardware:
  6022.  
  6023.    ■  On the 80387 hardware, exception handlers are invoked by the 80386 at
  6024.       the first WAIT or ESC instruction following the instruction causing the
  6025.       exception. The return link, stored on the 80386 stack, points to this
  6026.       second WAIT or ESC instruction where execution will resume following a
  6027.       return from the exception handler.
  6028.  
  6029.    ■  Using the EMUL387 emulator, numeric exception handlers are invoked
  6030.       from within the emulator itself. The return link stored on the stack
  6031.       when the exception handler is invoked will therefore point back to the
  6032.       EMUL387 emulator, rather than to the program code actually being
  6033.       executed (emulated). An IRET return from the exception handler returns
  6034.       to the emulator, which then returns immediately to the emulated
  6035.       program. This added layer of indirection should not cause confusion,
  6036.       however, because the instruction causing the exception can always be
  6037.       identified from the 80387's instruction and data pointers.
  6038.  
  6039.  
  6040.  6.2.7  Handling Numerics Exceptions
  6041.  
  6042.  Once the 80387 has been initialized and normal execution of applications
  6043.  has been commenced, the 80387 NPX may occasionally require attention in
  6044.  order to recover from numeric processing exceptions. This section provides
  6045.  details for writing software exception handlers for numeric exceptions.
  6046.  Numeric processing exceptions have already been introduced in Chapter 3.
  6047.  
  6048.  The 80387 NPX can take one of two actions when it recognizes a numeric
  6049.  exception:
  6050.  
  6051.    ■  If the exception is masked, the NPX will automatically perform its own
  6052.       masked exception response, correcting the exception condition according
  6053.       to fixed rules, and then continuing with its instruction execution.
  6054.  
  6055.    ■  If the exception is unmasked, the NPX signals the exception to the
  6056.       80386 CPU using the ERROR# status line between the two processors. Each
  6057.       time the 80386 encounters an ESC or WAIT instruction in its instruction
  6058.       stream, the CPU checks the condition of this ERROR# status line. If
  6059.       ERROR# is active, the CPU automatically traps to Interrupt vector #16,
  6060.       the Processor Extension Error trap.
  6061.  
  6062.  Interrupt vector #16 typically points to a software exception handler,
  6063.  which may or may not be a part of systems software. This exception handler
  6064.  takes the form of an 80386 interrupt procedure.
  6065.  
  6066.  When handling numeric errors, the CPU has two responsibilities:
  6067.  
  6068.    ■  The CPU must not disturb the numeric context when an error is
  6069.       detected.
  6070.  
  6071.    ■  The CPU must clear the error and attempt recovery from the error.
  6072.  
  6073.  Although the manner in which programmers may treat these responsibilities
  6074.  varies from one implementation to the next, most exception handlers will
  6075.  include these basic steps:
  6076.  
  6077.    ■  Store the NPX environment (control, status, and tag words, operand and
  6078.       instruction pointers) as it existed at the time of the exception.
  6079.  
  6080.    ■  Clear the exception bits in the status word.
  6081.  
  6082.    ■  Enable interrupts on the CPU.
  6083.  
  6084.    ■  Identify the exception by examining the status and control words in
  6085.       the saved environment.
  6086.  
  6087.    ■  Take some system-dependent action to rectify the exception.
  6088.  
  6089.    ■  Return to the interrupted program and resume normal execution.
  6090.  
  6091.  
  6092.  6.2.8  Simultaneous Exception Response
  6093.  
  6094.  In cases where multiple exceptions arise simultaneously, the 80387 signals
  6095.  one exception according to the precedence shown at the end of Chapter 3.
  6096.  This means, for example, that an SNaN divided by zero results in an invalid
  6097.  operation, not in a zero divide exception.
  6098.  
  6099.  
  6100.  6.2.9  Exception Recovery Examples
  6101.  
  6102.  Recovery routines for NPX exceptions can take a variety of forms. They can
  6103.  change the arithmetic and programming rules of the NPX. These changes may
  6104.  redefine the default fix-up for an error, change the appearance of the NPX
  6105.  to the programmer, or change how arithmetic is defined on the NPX.
  6106.  
  6107.  A change to an exception response might be to automatically normalize all
  6108.  denormals loaded from memory. A change in appearance might be extending the
  6109.  register stack into memory to provide an "infinite" number of numeric
  6110.  registers. The arithmetic of the NPX can be changed to automatically extend
  6111.  the precision and range of variables when exceeded. All these functions can
  6112.  be implemented on the NPX via numeric exceptions and associated recovery
  6113.  routines in a manner transparent to the application programmer.
  6114.  
  6115.  Some other possible application-dependent actions might include:
  6116.  
  6117.    ■  Incrementing an exception counter for later display or printing
  6118.  
  6119.    ■  Printing or displaying diagnostic information (e.g., the 80387
  6120.       environment andregisters)
  6121.  
  6122.    ■  Aborting further execution
  6123.  
  6124.    ■  Storing a diagnostic value (a NaN) in the result and continuing with
  6125.       the computation
  6126.  
  6127.  Notice that an exception may or may not constitute an error, depending on
  6128.  the application. Once the exception handler corrects the condition causing
  6129.  the exception, the floating-point instruction that caused the exception can
  6130.  be restarted, if appropriate. This cannot be accomplished using the IRET
  6131.  instruction, however, because the trap occurs at the ESC or WAIT instruction
  6132.  following the offending ESC instruction. The exception handler must obtain
  6133.  (using FSAVE or FSTENV) the address of the offending instruction in the task
  6134.  that initiated it, make a copy of it, execute the copy in the context of the
  6135.  offending task, and then return via IRET to the current CPU instruction
  6136.  stream.
  6137.  
  6138.  In order to correct the condition causing the numeric exception, exception
  6139.  handlers must recognize the precise state of the NPX at the time the
  6140.  exception handler was invoked, and be able to reconstruct the state of the
  6141.  NPX when the exception initially occurred. To reconstruct the state of the
  6142.  NPX, programmers must understand when, during the execution of an NPX
  6143.  instruction, exceptions are actually recognized.
  6144.  
  6145.  Invalid operation, zero divide, and denormalized exceptions are detected
  6146.  before an operation begins, whereas overflow, underflow, and precision
  6147.  exceptions are not raised until a true result has been computed. When a
  6148.  before exception is detected, the NPX register stack and memory have
  6149.  not yet been updated, and appear as if the offending instructions has not
  6150.  been executed.
  6151.  
  6152.  When an after exception is detected, the register stack and memory appear
  6153.  as if the instruction has run to completion; i.e., they may be updated.
  6154.  (However, in a store or store-and-pop operation, unmasked over/underflow is
  6155.  handled like a before exception; memory is not updated and the stack is not
  6156.  popped.) The programming examples contained in Chapter 7 include an outline
  6157.  of several exception handlers to process numeric exceptions for the 80387.
  6158.  
  6159.  
  6160.  Chapter 7  Numeric Programming Examples
  6161.  
  6162.  ───────────────────────────────────────────────────────────────────────────
  6163.  
  6164.  The following sections contain examples of numeric programs for the 80387
  6165.  NPX written in ASM386. These examples are intended to illustrate some of the
  6166.  techniques for programming the 80386/80387 computing system for numeric
  6167.  applications.
  6168.  
  6169.  
  6170.  7.1  Conditional Branching Example
  6171.  
  6172.  As discussed in Chapter 2, several numeric instructions post their results
  6173.  to the condition code bits of the 80387 status word. Although there are many
  6174.  ways to implement conditional branching following a comparison, the basic
  6175.  approach is as follows:
  6176.  
  6177.    ■  Execute the comparison.
  6178.  
  6179.    ■  Store the status word. (80387 allows storing status directly into AX
  6180.       register.)
  6181.  
  6182.    ■  Inspect the condition code bits.
  6183.  
  6184.    ■  Jump on the result.
  6185.  
  6186.  Figure 7-1 is a code fragment that illustrates how two memory-resident
  6187.  double-format real numbers might be compared (similar code could be used
  6188.  with the FTST instruction). The numbers are called A and B, and the
  6189.  comparison is A to B.
  6190.  
  6191.  The comparison itself requires loading A onto the top of the 80387 register
  6192.  stack and then comparing it to B, while popping the stack with the same
  6193.  instruction. The status word is then written into the 80386 AX register.
  6194.  
  6195.  A and B have four possible orderings, and bits C3, C2, and C0 of the
  6196.  condition code indicate which ordering holds. These bits are positioned in
  6197.  the upper byte of the NPX status word so as to correspond to the CPU's zero,
  6198.  parity, and carry flags (ZF, PF, and CF), when the byte is written into the
  6199.  flags. The code fragment sets ZF, PF, and CF of the CPU status word to the
  6200.  values of C3, C2, and C0 of the NPX status word, and then uses the CPU
  6201.  conditional jump instructions to test the flags. The resulting code is
  6202.  extremely compact, requiring only seven instructions.
  6203.  
  6204.  The FXAM instruction updates all four condition code bits. Figure 7-2 shows
  6205.  how a jump table can be used to determine the characteristics of the value
  6206.  examined. The jump table (FXAM_TBL) is initialized to contain the 32-bit
  6207.  displacement of 16 labels, one for each possible condition code setting.
  6208.  Note that four of the table entries contain the same value, "EMPTY." The
  6209.  first two condition code settings correspond to "EMPTY." The two other table
  6210.  entries that contain "EMPTY" will never be used on the 80387, but may be
  6211.  used if the code is executed with an 80287.
  6212.  
  6213.  The program fragment performs the FXAM and stores the status word. It then
  6214.  manipulates the condition code bits to finally produce a number in register
  6215.  BX that equals the condition code times 2. This involves zeroing the unused
  6216.  bits in the byte that contains the code, shifting C3 to the right so that it
  6217.  is adjacent to C2, and then shifting the code to multiply it by 2. The
  6218.  resulting value is used as an index that selects one of the displacements
  6219.  from FXAM_TBL (the multiplication of the condition code is required because
  6220.  of the 2-byte length of each value in FXAM_TBL). The unconditional JMP
  6221.  instruction effectively vectors through the jump table to the labeled
  6222.  routine that contains code (not shown in the example) to process each
  6223.  possible result of the FXAM instruction.
  6224.  
  6225.  
  6226.  Figure 7-1.  Conditional Branching for Compares
  6227.  
  6228.      .
  6229.      .
  6230.      .
  6231.  A   DQ  ?
  6232.  B   DQ  ?
  6233.      .
  6234.      .
  6235.      .
  6236.      FLD     A  ; LOAD A ONTO TOP OF 387 STACK
  6237.      FCOMP   B  ; COMPARE A:B, POP A
  6238.      FSTSW   AX ; STORE RESULT TO CPU AX REGISTER
  6239.  ;
  6240.  ; CPU AX REGISTER CONTAINS CONDITION CODES
  6241.  ;   (RESULTS OF COMPARE)
  6242.  ; LOAD CONDITION CODES INTO CPU FLAGS
  6243.  ;
  6244.      SAHF
  6245.  ;
  6246.  ; USE CONDITIONAL JUMPS TO DETERMINE ORDERING OF A TO B
  6247.  ;
  6248.      JP A_B_UNORDERED            ; TEST C2 (PF)
  6249.      JB A_LESS          ; TEST C0 (CF)
  6250.      JE A_EQUAL         ; TEST C3 (ZF)
  6251.  A_GREATER:             ; C0 (CF) = 0, C3 (ZF) = 0
  6252.      .
  6253.      .
  6254.  A_EQUAL:                   ; C0 (CF) = 0, C3 (ZF) = 1
  6255.      .
  6256.      .
  6257.  A_LESS:                    ; C0 (CF) = 1, C3 (ZF) = 0
  6258.      .
  6259.      .
  6260.  A_B_UNORDERED:             ; C2 (PF) = 1
  6261.      .
  6262.      .
  6263.  
  6264.  
  6265.  Figure 7-2.  Conditional Branching for FXAM
  6266.  
  6267.  ; JUMP TABLE FOR EXAMINE ROUTINE
  6268.  ;
  6269.  FXAM_TBL  DD POS_UNNORM, POS NAN, NEG_UNNORM, NEG_NAN,
  6270.  &         POS_NORM, POS_INFINITY, NEG_NORM,
  6271.  &         NEG_INFINITY, POS_ZERO, EMPTY, NEG_ZERO,
  6272.  &         EMPTY, POS_DENORM, EMPTY, NEG_DENORM, EMPTY
  6273.      .
  6274.      .
  6275.  ; EXAMINE ST AND STORE RESULT (CONDITION CODES)
  6276.  
  6277.      FXAM
  6278.      XOR EAX,EAX ; CLEAR EAX
  6279.      FSTSW AX
  6280.  
  6281.  ; CALCULATE OFFSET INTO JUMP TABLE
  6282.  
  6283.      AND AX,0100011100000000B ; CLEAR ALL BITS EXCEPT C3, C2-C0
  6284.      SHR EAX,6    ;  SHIFT C2-C0 INTO PLACE    (0000XXX0)
  6285.      SAL AH,5     ;  POSITION C3               (000X0000)
  6286.      OR  AL,AH    ;  DROP C3 IN ADJACENT TO C2 (000XXXX0)
  6287.      XOR AH,AH    ;  CLEAR OUT THE OLD COPY OF C3
  6288.  
  6289.  ; JUMP TO THE ROUTINE `ADDRESSED' BY CONDITION CODE
  6290.  
  6291.      JMP FXAM_TBL[EAX]
  6292.  
  6293.  ; HERE ARE THE JUMP TARGETS, ONE TO HANDLE
  6294.  ;    EACH POSSIBLE RESULT OF FXAM
  6295.  
  6296.  POS_UNNORM:
  6297.      .
  6298.  POS_NAN:
  6299.      .
  6300.  NEG_UNNORM:
  6301.      .
  6302.  NEG_NAN:
  6303.      .
  6304.  POS_NORM:
  6305.      .
  6306.  POS_INFINITY:
  6307.      .
  6308.  NEG_NORM:
  6309.      .
  6310.  NEG_INFINITY:
  6311.      .
  6312.  POS_ZERO:
  6313.      .
  6314.  EMPTY:
  6315.      .
  6316.  NEG_ZERO:
  6317.      .
  6318.  POS_DENORM:
  6319.      .
  6320.  NEG_DENORM:
  6321.  
  6322.  
  6323.  7.2  Exception Handling Examples
  6324.  
  6325.  There are many approaches to writing exception handlers. One useful
  6326.  technique is to consider the exception handler procedure as consisting of
  6327.  "prologue," "body," and "epilogue" sections of code. This procedure is
  6328.  invoked via interrupt number 16.
  6329.  
  6330.  At the beginning of the prologue, CPU interrupts have been disabled. The
  6331.  prologue performs all functions that must be protected from possible
  6332.  interruption by higher-priority sources. Typically, this involves saving CPU
  6333.  registers and transferring diagnostic information from the 80387 to memory.
  6334.  When the critical processing has been completed, the prologue may enable CPU
  6335.  interrupts to allow higher-priority interrupt handlers to preempt the
  6336.  exception handler.
  6337.  
  6338.  The body of the exception handler examines the diagnostic information and
  6339.  makes a response that is necessarily application-dependent. This response
  6340.  may range from halting execution, to displaying a message, to attempting to
  6341.  repair the problem and proceed with normal execution.
  6342.  
  6343.  The epilogue essentially reverses the actions of the prologue, restoring
  6344.  the CPU and the NPX so that normal execution can be resumed. The epilogue
  6345.  must not load an unmasked exception flag into the 80387 or another exception
  6346.  will be requested immediately.
  6347.  
  6348.  Figures 7-3 through 7-5 show the ASM386 coding of three skeleton
  6349.  exception handlers. They show how prologues and epilogues can be written for
  6350.  various situations, but provide comments indicating only where the
  6351.  application dependent exception handling body should be placed.
  6352.  
  6353.  Figures 7-3 and 7-4 are very similar; their only substantial difference is
  6354.  their choice of instructions to save and restore the 80387. The tradeoff
  6355.  here is between the increased diagnostic information provided by FNSAVE and
  6356.  the faster execution of FNSTENV. For applications that are sensitive to
  6357.  interrupt latency or that do not need to examine register contents, FNSTENV
  6358.  reduces the duration of the "critical region," during which the CPU does not
  6359.  recognize another interrupt request.
  6360.  
  6361.  After the exception handler body, the epilogues prepare the CPU and the NPX
  6362.  to resume execution from the point of interruption (i.e., the instruction
  6363.  following the one that generated the unmasked exception). Notice that the
  6364.  exception flags in the memory image that is loaded into the 80387 are
  6365.  cleared to zero prior to reloading (in fact, in these examples, the entire
  6366.  status word image is cleared).
  6367.  
  6368.  The examples in Figures 7-3 and 7-4 assume that the exception handler
  6369.  itself will not cause an unmasked exception. Where this is a possibility,
  6370.  the general approach shown in Figure 7-5 can be employed. The basic
  6371.  technique is to save the full 80387 state and then to load a new control
  6372.  word in the prologue. Note that considerable care should be taken when
  6373.  designing an exception handler of this type to prevent the handler from
  6374.  being reentered endlessly.
  6375.  
  6376.  
  6377.  Figure 7-3.  Full-State Exception Handler
  6378.  
  6379.  SAVE_ALL         PROC
  6380.  ;
  6381.  ; SAVE CPU REGISTERS, ALLOCATE STACK SPACE
  6382.  ; FOR 80387 STATE IMAGE
  6383.      PUSH EBP
  6384.      MOV  EBP,ESP
  6385.      SUB  ESP,108
  6386.  ; SAVE FULL 80387 STATE, ENABLE CPU INTERRUPTS
  6387.      FNSAVE  [EBP-108]
  6388.      STI
  6389.  ;
  6390.  ; APPLICATION-DEPENDENT EXCEPTION HANDLING
  6391.  ; CODE GOES HERE
  6392.  ;
  6393.  ; CLEAR EXCEPTION FLAGS IN STATUS WORD
  6394.  ;  (WHICH IS IN MEMORY)
  6395.  ; RESTORE MODIFIED STATE IMAGE
  6396.      MOV BYTE PTR [EBP-104], 0H
  6397.      FRSTOR  [EBP-108]
  6398.  ; DEALLOCATE STACK SPACE, RESTORE CPU REGISTERS
  6399.      MOVE ESP,EBP
  6400.        .
  6401.        .
  6402.      POP EBP
  6403.  ;
  6404.  ; RETURN TO INTERRUPTED CALCULATION
  6405.      IRET
  6406.  SAVE_ALL         ENDP
  6407.  
  6408.  
  6409.  Figure 7-4.  Reduced-Latency Exception Handler
  6410.  
  6411.  SAVE_ENVIRONMENT PROC
  6412.  ;
  6413.  ; SAVE CPU REGISTERS, ALLOCATE STACK SPACE
  6414.  ; FOR 80387 ENVIRONMENT
  6415.      PUSH    EBP
  6416.         .
  6417.      MOV     EBP,ESP
  6418.      SUB     ESP,28
  6419.  ; SAVE ENVIRONMENT, ENABLE CPU INTERRUPTS
  6420.      FNSTENV [EBP-28]
  6421.      STI
  6422.  ;
  6423.  ; APPLICATION EXCEPTION-HANDLING CODE GOES HERE
  6424.  ;
  6425.  ; CLEAR EXCEPTION FLAGS IN STATUS WORD
  6426.  ;  (WHICH IS IN MEMORY)
  6427.  ; RESTORE MODIFIED ENVIRONMENT IMAGE
  6428.      MOV     BYTE PTR [EBP-24], 0H
  6429.      FLDENV  [EBP-28]
  6430.  ; DE-ALLOCATE STACK SPACE, RESTORE CPU REGISTERS
  6431.      MOV     ESP,EBP
  6432.      POP     EBP
  6433.  ;
  6434.  ; RETURN TO INTERRUPTED CALCULATION
  6435.      IRET
  6436.  SAVE_ENVIRONMENT ENDP
  6437.  
  6438.  
  6439.  Figure 7-5.  Reentrant Exception Handler
  6440.  
  6441.          .
  6442.          .
  6443.          .
  6444.      LOCAL CONTROL  DW  ?  ; ASSUME INITIALIZED
  6445.          .
  6446.          .
  6447.          .
  6448.  REENTRANT             PROC
  6449.  ;
  6450.  ; SAVE CPU REGISTERS, ALLOCATE STACK SPACE FOR
  6451.  ; 80387 STATE IMAGE
  6452.      PUSH    EBP
  6453.         .
  6454.         .
  6455.         .
  6456.      MOV     EBP,ESP
  6457.      SUB     ESP,108
  6458.  ; SAVE STATE, LOAD NEW CONTROL WORD,
  6459.  ; ENABLE CPU INTERRUPTS
  6460.      FNSAVE  [EBP-108]
  6461.      FLDCW   LOCAL_CONTROL
  6462.      STI
  6463.         .
  6464.         .
  6465.         .
  6466.  ; APPLICATION EXCEPTION HANDLING CODE GOES HERE.
  6467.  ; AN UNMASKED EXCEPTION GENERATED HERE WILL
  6468.  ; CAUSE THE EXCEPTION HANDLER TO BE REENTERED.
  6469.  ; IF LOCAL STORAGE IS NEEDED, IT MUST BE
  6470.  ; ALLOCATED ON THE CPU STACK.
  6471.         .
  6472.         .
  6473.         .
  6474.  ; CLEAR EXCEPTION FLAGS IN STATUS WORD
  6475.  ;  (WHICH IS IN MEMORY)
  6476.  ; RESTORE MODIFIED STATE IMAGE
  6477.      MOV     BYTE PTR [EBP-104], 0H
  6478.      FRSTOR  [EBP-108]
  6479.  ; DE-ALLOCATE STACK SPACE, RESTORE CPU REGISTERS
  6480.      MOV     ESP,EBP
  6481.         .
  6482.         .
  6483.         .
  6484.      POP     EBP
  6485.  ; RETURN TO POINT OF INTERRUPTION
  6486.      IRET
  6487.  REENTRANT             ENDP
  6488.  
  6489.  
  6490.  7.3  Flaoting-Point to ASCII Conversion Examples
  6491.  
  6492.  Numeric programs must typically format their results at some point for
  6493.  presentation and inspection by the program user. In many cases, numeric
  6494.  results are formatted as ASCII strings for printing or display. This example
  6495.  shows how floating-point values can be converted to decimal ASCII character
  6496.  strings. The function shown in Figure 7-6 can be invoked from PL/M-386,
  6497.  Pascal-386, FORTRAN-386, or ASM386 routines.
  6498.  
  6499.  Shortness, speed, and accuracy were chosen rather than providing the
  6500.  maximum number of significant digits possible. An attempt is made to keep
  6501.  integers in their own domain to avoid unnecessary conversion errors.
  6502.  
  6503.  Using the extended precision real number format, this routine achieves a
  6504.  worst case accuracy of three units in the 16th decimal position for a
  6505.  noninteger value or integers greater than 10^(18). This is double precision
  6506.  accuracy. With values having decimal exponents less than 100 in magnitude,
  6507.  the accuracy is one unit in the 17th decimal position.
  6508.  
  6509.  Higher precision can be achieved with greater care in programming, larger
  6510.  program size, and lower performance.
  6511.  
  6512.  
  6513.  Figure 7-6.  Floating-Point to ASCII Conversion Routine
  6514.  
  6515.  XENIX286 80380 MACRO ASSEMBLER V1.0, ASSEMBLY OF MODULE FLOATING_TO_ASCII
  6516.  OBJECT MODULE PLACED IN fpasc.obj
  6517.  ASSEMBLER INVOKED BY: asm386 fpasc.asm
  6518.  
  6519.  LOC      OBJ                          LINE    SOURCE
  6520.  
  6521.                                  1 +1  $title(`Convert a floating point number
  6522.                                  2
  6523.                                  3                    name    floating_to_asci
  6524.                                  4
  6525.  00000000                        5                    public  floating_to_asci
  6526.                                  6                    extrn   get_power_10:nea
  6527.                                  7    ;
  6528.                                  8    ; This subroutine will convert the float
  6529.                                  9    ; number in the top of the NPX stack to
  6530.                                 10    ; string and separate power of 10 scalin
  6531.                                 11    ; (in binary).  The maximum width of the
  6532.                                 12    ; formed is controlled by a parameter wh
  6533.                                 13    ; > 1.  Unnormal values, denormal values
  6534.                                 14    ; zeroes will be correctly converted. Ho
  6535.                                 15    ; and pseudo zeros are no longer support
  6536.                                 16    ; 80387( in conformance with the IEEE fl
  6537.                                 17    ; standard) and hence not generated inte
  6538.                                 18    ; returned value will indicate how many
  6539.                                 19    ; of precision were lost in an unnormal
  6540.                                 20    ; value.  The magnitude (in terms of bin
  6541.                                 21    ; of a pseudo zero will also be indicate
  6542.                                 22    ; less than 10**18 in magnitude are accu
  6543.                                 23    ; if the destination ASCII string field
  6544.                                 24    ; to hold all the digits. Otherwise the
  6545.                                 25    ; to scientific notation.
  6546.                                 26    ;
  6547.                                 27    ; The status of the conversion is identi
  6548.                                 28    ; return value, it can be:
  6549.                                 29    ;
  6550.                                 30    ;       0       conversion complete, str
  6551.                                 31    ;       1       invalid arguments
  6552.                                 32    ;       2       exact integer conversion
  6553.                                 33    ;       3       indefinite
  6554.                                 34    ;       4       + NAN (Not A Number)
  6555.                                 35    ;       5       - NAN
  6556.                                 36    ;       6       + Infinity
  6557.                                 37    ;       7       - Infinity
  6558.                                 38    ;       8       pseudo zero found, strin
  6559.                                 39    ;
  6560.                                 40    ;         The PLM/386 calling convention
  6561.                                 41    ;
  6562.                                 42    ; floating_to_ascii:
  6563.                                 43    ;       procedure (number,denormal_ptr,s
  6564.                                 44    ;       field_size, power_ptr) word exte
  6565.                                 45    ;       declare (denormal_ptr,string_ptr
  6566.                                 46    ;       pointer;
  6567.                                 47    ;       declare field_size word,
  6568.                                 48    ;       string_size based size ptr word;
  6569.                                 49    ;       declare number real;
  6570.                                 50    ;       declare denormal integer based d
  6571.                                 51    ;       declare power integer based powe
  6572.                                 52    ;       end floating_to_ascii:
  6573.                                 53    ;
  6574.                                 54    ;         The floating point value is ex
  6575.                                 55    ;   on the top of the  NPX stack.  This
  6576.                                 56    ;   expects 3 free entries on the NPX st
  6577.                                 57    ;   will pop the passed value off when d
  6578.                                 58    ;   generated ASCII string will have a l
  6579.                                 59    ;   character either `-' or `+' indicati
  6580.                                 60    ;   of the value.  The ASCII decimal dig
  6581.                                 61    ;   immediately follow. The numeric valu
  6582.                                 62    ;   ASCII string is (ASCII STRING.)*10**
  6583.                                 63    ;   the given number was zero, the ASCII
  6584.                                 64    ;   contain a sign and a single zero cha
  6585.                                 65    ;   value string_size indicates the tota
  6586.                                 66    ;   the ASCII string including the sign
  6587.                                 67    ;   String(0) will always hold the sign.
  6588.                                 68    ;   possible for string size to be less
  6589.                                 69    ;   field_size. This occurs for zeroes o
  6590.                                 70    ;   values.  A pseudo zero will return a
  6591.                                 71    ;   return code.  The denormal count wil
  6592.                                 72    ;      the power of two originally assoc
  6593.                                 73    ;   value.  The power of ten and ASCII s
  6594.                                 74    ;   be as if the value was an ordinary z
  6595.                                 75    ;
  6596.                                 76    ;   This subroutine is accurate up to a
  6597.                                 77    ;   18 decimal digits for integers.  Int
  6598.                                 78    ;   will have a decimal power of zero as
  6599.                                 79    ;   with them. For non integers, the res
  6600.                                 80    ;   accurate to within 2 decimal digits
  6601.                                 81    ;   decimal place(double precision).  Th
  6602.                                 82    ;   instruction is also used for scaling
  6603.                                 83    ;   the range acceptable for the BCD dat
  6604.                                 84    ;   roundirg mode in effect on entry to
  6605.                                 85    ;   subroutine is used for the conversio
  6606.                                 86    ;
  6607.                                 87    ;         The following registers are no
  6608.                                 88    ;
  6609.                                 89    ;               eax ebx ecx edx esi edi
  6610.                                 90    ;
  6611.                                 91    ;
  6612.                                 92    ;         Define the stack layout.
  6613.                                 93    ;
  6614.  00000000[]                     94    ebp_save       equ     dword ptr [ebp]
  6615.  00000004[]                     95    es_save        equ     ebp_save + size e
  6616.  00000008[]                     96    return_ptr     equ     es_save + size es
  6617.  0000000C[]                     97    power_ptr      equ     return_ptr + size
  6618.  00000010[]                     98    field_size     equ     power_ptr + size
  6619.  00000014[]                     99    size_ptr       equ     field_size + size
  6620.  00000018[]                    100    string_ptr     equ     size_ptr + size s
  6621.  0000001C[]                    101    denormal_ptr   equ     string_ptr + size
  6622.                                102
  6623.  0014                          103    parms_size     equ     size power_ptr +
  6624.                                104    &              size size_ptr + size stri
  6625.                                105    &              size denormal_ptr
  6626.                                106    ;
  6627.                                107    ;        Define constants used
  6628.                                108    ;
  6629.                                109    BCD_DIGITS     equ     18       ; Number
  6630.                                110    WORD_SIZE      equ     4
  6631.                                111    BCD_SIZE       equ     10
  6632.                                112    MINUS          equ     1        ; Define
  6633.                                113    NAN            equ     4        ; The ex
  6634.                                114    INFINITY       equ     6        ; here a
  6635.                                115    INDEFINITE     equ     3        ; corres
  6636.                                116    PSEUDO_ZERO    equ     8        ; values
  6637.                                117    INVALID        equ     -2       ; order
  6638.                                118    ZERO           equ     -4
  6639.                                119    DENORMAL       equ     -6
  6640.                                120    UNNORMAL       equ     -8
  6641.                                121    NORMAL         equ     0
  6642.                                122    EXACT          equ     2
  6643.                                123    ;
  6644.                                124    ;        Define layout of temporary stor
  6645.                                125    ;
  6646.                                126    power_two      equ     word ptr [ebp - W
  6647.                                127    bcd_value      equ     tbyte ptr power t
  6648.                                128    bcd_byte       equ     byte ptr bcd_valu
  6649.                                129    fraction       equ     bcd_value
  6650.                                130
  6651.                                131    local_size     equ     size power_two +
  6652.                                132    ;
  6653.                                133    ;        Allocate stack space for the te
  6654.                                134    ;    the stack will be big enough
  6655.                                135    ;
  6656.                                136    stack  stackseg (local_size+6) ; Allocat
  6657.                                137                                   ; space f
  6658.                                138 +1 $eject
  6659.                                139    code           segment public er
  6660.                                140                   extrn   power_table:qword
  6661.                                141    ;
  6662.                                142    ;       Constants used by this function.
  6663.                                143    ;
  6664.                                144                   even                    ;
  6665.  00000000 0A00                 145    const10        dw      10              ;
  6666.                                140    ;                      ; too big BCD
  6667.                                147    ;
  6668.                                148    ; Convert the C3,C2,C1,C0 encoding from
  6669.                                149    ; into meaningful bit flags and values.
  6670.                                150    ;
  6671.  00000002 F8                   151    status_table   db      UNNORMAL, NAN, UN
  6672.  00000003 04                   152    &       NAN + MINUS, NORMAL, INFINITY,
  6673.  00000004 F9                   153    &       NORMAL + MINUS,  INFINITY + MINU
  6674.  00000005 05                   154    &              ZERO, INVALID, ZERO + MIN
  6675.  00000006 00                   155    &              DENORMAL, INVALID, DENORM
  6676.  00000007 06
  6677.  00000008 01
  6678.  00000009 07
  6679.  0000000A FC
  6680.  0000000B FE
  6681.  0000000C FD
  6682.  0000000D FE
  6683.  0000000E FA
  6684.  0000000F FE
  6685.  00000010 FB
  6686.  00000011 FE
  6687.                                156
  6688.  00000012                      157    floating_to_ascii proc
  6689.                                158
  6690.  00000012 E800000000        E  159            call   tos_status       ; Look a
  6691.                                160
  6692.                                161    ; Get descriptor from table
  6693.  00000017 2E0FB68002000000  R  162            movzx  eax, status_table[eax]
  6694.  0000001F 3CFE                 163            cmp    al,INVALID              ;
  6695.  00000021 7527                 164            jne    not_empty
  6696.                                165    ;
  6697.                                166    ;         ST(0) is empty!  Return the st
  6698.                                167    ;
  6699.  00000023 C21400               168            ret    parms_size
  6700.                                169    ;
  6701.                                170    ;         Remove infinity from stack and
  6702.                                171    ;
  6703.  00000026                      172    found_infinity:
  6704.  00000026 DDD8                 173            fstp   st(0)            ; OK to
  6705.  00000028 EB02                 174            jmp    short exit_proc
  6706.                                175    ;
  6707.                                176    ;         String space is too small!
  6708.                                177    ;      Return invalid code.
  6709.                                178    ;
  6710.  0000002A                      179    small_string:
  6711.  0000002A B0FE                 180            mov    al,INVALID
  6712.  0000002C                      181    exit_proc:
  6713.  0000002C C9                   182            leave          ; Restore stack s
  6714.  0000002D 07                   183            pop     es
  6715.  0000002E C21400               184            ret     parms_size
  6716.                                185    ;
  6717.                                186    ; ST(0) is NAN or indefinite.  Store the
  6718.                                187    ; value in memory and look at the fracti
  6719.                                188    ; field to separate indefinite from an o
  6720.                                189    ;
  6721.  00000031                      190    NAN_or_indefinite:
  6722.  00000031 DB7DF2               191            fstp    fraction        ; Remove
  6723.                                192                                ; for examin
  6724.  00000034 A801                 193            test    al,MINUS        ; Look a
  6725.  00000036 9B                   194            fwait
  6726.  00000037 74F3                 195            jz      exit_proc
  6727.                                196                                ; positive
  6728.                                197
  6729.  00000039 BB000000C0           198            mov     ebx,0C0000000H  ; Match
  6730.                                199                                ;bits of fra
  6731.                                200
  6732.                                201    ; Compare bits 63-32
  6733.  0000003E 2B5DF6               202            sub     ebx, dword ptr fraction
  6734.                                203
  6735.                                204    ; Bits 31-0 must be zero
  6736.  00000041 0B5DF2               205            or      ebx, dword ptr fraction
  6737.  00000044 75E6                 206            jnz     exit_proc
  6738.                                207
  6739.                                208    ; Set return value for indefinite value
  6740.  00000046 B003                 209        mov al,INDEFINITE
  6741.  00000048 EBE2                 210            jmp     exit_proc
  6742.                                211    ;
  6743.                                212    ;         Allocate stack space for local
  6744.                                213    ;     and establish parameter addressibi
  6745.                                214    ;
  6746.  0000004A                      215    not_empty:
  6747.  0000004A 06                   216            push    es              ; Save w
  6748.  0000004B C80C0000             217            enter local_size, 0     ; Setup
  6749.                                218
  6750.                                219
  6751.                                220    ; Check for enough string space
  6752.  0000004F 8B4D10               221            mov     ecx,field size
  6753.  00000052 83F902               222            cmp     ecx,2
  6754.  00000055 7CD3                 223            jl      small_string
  6755.                                224
  6756.  00000057 49                   225            dec     ecx             ; Adjust
  6757.                                226
  6758.                                227    ; See if string is too large for BCD
  6759.  00000058 83F912               228            cmp     ecx,BCD_DIGITS
  6760.  0000005B 7605                 229            jbe     size_ok
  6761.                                230
  6762.                                231    ; Else set maximum string size
  6763.  0000005D B912000000           232            mov     ecx,BCD_DIGITS
  6764.  00000002                      233    size_ok:
  6765.  00000062 3C06                 234            cmp     al,INFINITY     ; Look f
  6766.                                235
  6767.                                236    ; Return status value for + or - inf
  6768.  00000064 7DC0                 237            jge     found_infinity
  6769.                                238
  6770.  00000066 3C04                 239             cmp     al,NAN          ; Look
  6771.  00000068 7DC7                 240             jge     NAN_or_indefinite
  6772.                                241    ;
  6773.                                242    ;  Set default return values and check t
  6774.                                243    ;  the number is normalized.
  6775.                                244    ;
  6776.  0000006A D9E1                 245            fabs    ; Use positive value onl
  6777.                                246                            ; sign bit in al
  6778.  0000006C 31D2                 247            xor     edx,edx
  6779.  0000006E 8B7D1C               248            mov     edi,denormal_ptr; Zero d
  6780.  00000071 668917               249            mov     [edi], dx
  6781.  00000074 8B5D0C               250            mov     ebx,power_ptr   ; Zero p
  6782.  00000077 668913               251            mov     [ebx], dx
  6783.  0000007A 88C2                 252            mov dl, al
  6784.  0000007C 80E201               253            and dl, 1
  6785.  0000007F 80C202               254        add dl, EXACT
  6786.  00000082 3CFC                 255            cmp     al,ZERO
  6787.  00000084 0F83BC000000         256            jae     convert_integer ; Ship p
  6788.                                257
  6789.  0000008A DB7DF2               258        fstp   fraction
  6790.  00000080 9B                   259        fwait
  6791.  0000008E 8A45F9               260        mov    al, bcd_byte + 7
  6792.  00000091 804DF980             261        or     byte ptr bcd_byte +  7, 80h
  6793.  00000095 DB6DF2               262        fld    fraction
  6794.  00000098 D9F4                 263        fxtract
  6795.  0000009A A880                 264        test   al, 80h
  6796.  0000009C 7524                 265        jnz    normal_value
  6797.                                266
  6798.  0000009E D9E8                 267        fld1
  6799.  000000A0 DEE9                 268        fsub
  6800.  000000A2 D9E4                 269        ftat
  6801.  000000A4 9BDFE0               270        fatsw  ax
  6802.  000000A7 9E                   271        sahf
  6803.  000000A8 7510                 272        jnz    set_unnormal_count
  6804.                                273    ;
  6805.                                274    ;   Found a pseudo zero
  6806.                                275    ;
  6807.  000000AA D9EC                 276        fldlg2              ; Develop power
  6808.  000000AC 80C206               277        add    dl, PSEUDO ZERO - EXACT
  6809.  000000AF DECA                 278        fmulp  st(2), st
  6810.  000000B1 D9C9                 279        fxch                  ; Get power of
  6811.  000000B3 DF1B                 280        fistp  word ptr [ebx] ; Set power of
  6812.  000000B5 E98C000000           281        jmp    convert_integer
  6813.                                282
  6814.  000000BA                      283    set_unnonmal_count:
  6815.  000000BA D9F4                 284        fxtract               ; Get original
  6816.                                285                              ; now normaliz
  6817.  000000BC D9C9                 286        fxch                  ; Get unnormal
  6818.  000000BE D9E0                 287        fchs
  6819.  000000C0 DF1F                 288        fistp  word ptr [edi] ; Set unnormal
  6820.                                289
  6821.                                290
  6822.                                291    ;  Calculate the decimal magnitude assoc
  6823.                                292    ;  with this number to within one order.
  6824.                                293    ;  error will always be inevitable due t
  6825.                                294    ;  rounding and lost precision. As a res
  6826.                                295    ;  we will deliberately fail to consider
  6827.                                296    ;  LOG10 of the fraction value in calcul
  6828.                                297    ;  the order. Since the fraction will al
  6829.                                298    ;  be 1 <= F < 2, its  LOG10 will not ch
  6830.                                299    ;  the basic accuracy of the function. T
  6831.                                300    ;  get the decimal order of magnitude, s
  6832.                                301    ;  multiply the power of two by LOG10(2)
  6833.                                302    ;  truncate the result to an integer.
  6834.                                303    ;
  6835.                                304    normal_value:
  6836.                                305            fstp   fraction         ; Save t
  6837.                                306                               ; for later u
  6838.                                307            fist   power_two        ; Save p
  6839.                                308            fldlg2
  6840.                                309
  6841.                                310            fmul            ; Form LOG10(of
  6842.                                311            fistp  word ptr [ebx]   ; Any ro
  6843.                                312
  6844.                                313    ;
  6845.                                314    ;         Check if the magnitude of the
  6846.                                315    ;      out treating it as an integer.
  6847.                                316    ;
  6848.                                317    ;       CX has the maximum number of dec
  6849.                                318    ;   allowed.
  6850.                                319    ;
  6851.                                320            fwait           ; Wait for power
  6852.                                321
  6853.                                322    ; Get power of ten of value
  6854.                                323            movsx si, word ptr [ebx]
  6855.                                324            sub    esi,ecx
  6856.                                325                                ; necessary
  6857.                                326            ja     adjust result    ; Jump i
  6858.                                327    ;
  6859.                                328    ;         The number is between 1 and 10
  6860.                                329    ;       Test if it is an integer.
  6861.                                330    ;
  6862.                                331            fild   power_two        ; Restor
  6863.                                332            sub    dl,NORMAL-EXACT  ; Conver
  6864.                                333                                ; value
  6865.                                334            fld    fraction
  6866.                                335            fscale
  6867.                                336                                ; is safe he
  6868.                                337            fst    st(1)
  6869.                                338            frndint
  6870.                                339            fcomp
  6871.                                340            fstsw  ax
  6872.                                341            sahf
  6873.                                342                                ; an integer
  6874.                                343            jnz    convert_integer
  6875.                                344
  6876.                                345            fstp   st(0)            ; Remove
  6877.                                346            add    dl,NORMAL-EXACT  ; Restor
  6878.                                347    ;
  6879.                                348    ;      Scale the number to within the ra
  6880.                                349    ;  by the BCD format.The scaling operati
  6881.                                350    ;  produce a number within one decimal o
  6882.                                351    ;  magnitude of the largest decimal numb
  6883.                                352    ;  representable within the given string
  6884.                                353    ;
  6885.                                354    ;        The scaling power of ten value
  6886.                                355    ;
  6887.  000000F2                      356    adjust_result:
  6888.  000000F2 8BC6                 357           mov     eax,esi                 ;
  6889.  000000F4 668903               358           mov     word ptr [ebx],ax       ;
  6890.                                359                                    ; of ten
  6891.  000000F7 F7D8                 360           neg     eax              ; Subtra
  6892.                                361                                    ; magnit
  6893.  000000F9 E800000000        E  362           call    get_power_10     ; Scalin
  6894.                                363                                    ; return
  6895.                                364                                    ; expone
  6896.  000000FE DB6DF2               365           fld     fraction
  6897.  00000101 DEC9                 366           fmul
  6898.  00000103 8BF1                 367           mov     esi,ecx                 ;
  6899.                                368                                    ; the ma
  6900.  00000105 C1E603               369           shl     esi,3
  6901.                                370                                    ; the st
  6902.  00000108 DF45FC               371           fild    power_two               ;
  6903.  0000010B DEC2                 372           faddp   st(2),st
  6904.  0000010D D9FD                 373           fscale
  6905.                                374                                    ; expone
  6906.  0000010F DDD9                 375           fstp    st(1)                   ;
  6907.                                376    ;
  6908.                                377    ;        Test the adjusted value against
  6909.                                378    ;    of exact powers of ten. The combine
  6910.                                379    ;    of the magnitude estimate and power
  6911.                                380    ;    can result in a value one order of
  6912.                                381    ;    too small or too large to fit corre
  6913.                                382    ;    the BCD field. To handle this probl
  6914.                                383    ;    the adjusted value, if it is too sm
  6915.                                384    ;    large, then adjust it by ten and ad
  6916.                                385    ;    power of ten value.
  6917.                                386    ;
  6918.  00000111                      387    test_power:
  6919.                                388
  6920.                                389    ; Compare against exact power entry. Use
  6921.                                390    ; entry since cx has been decremented by
  6922.  00000111 2EDC9608000000    E  391            fcom    power_table[esi]+type po
  6923.  00000118 9BDFE0               392            fstsw ax
  6924.  0000011B 9E                   393            sahf                ; If C3 = C0
  6925.  0000011C 720F                 394            jb      test_for_small  ; too bi
  6926.                                395
  6927.  0000011E 2EDE3500000000    R  396            fidiv   const10          ; Else
  6928.  00000125 80E2FD               397            and     dl,not EXACT     ; Remov
  6929.  00000128 66FF03               398            inc     word ptr [ebx]   ; Adjus
  6930.  0000012B EB17                 399            jmp     short in range   ; Conve
  6931.                                400                                ;  integer
  6932.  0000012D                      401    test for small:
  6933.  0000012D 2EDC9600000000    E  402            fcom    power table[esi]
  6934.  0000134 9BDFE0                403            fstsw   ax
  6935.  0000137 9E                    404            sahf
  6936.                                405
  6937.  10000138 720A                 406            jc      in_range
  6938.                                407
  6939.                                408
  6940.  000013A 2EDE0D00000000     R  409            fimul   const10         ; Adjust
  6941.  0000141 66FF0B                410            dec     word ptr [ebx]  ; Adjust
  6942.  0000144                       411    in_range:
  6943.  0000144 D9FC                  412            frndint
  6944.                                413    ;
  6945.                                414    ;       Assert: 0 <= TOS <= 999,999,999,
  6946.                                415    ;       The TOS number will be exactly r
  6947.                                416    ;    in 18 digit BCD format.
  6948.                                417    ;
  6949.  00000146                      418    convert_integer:
  6950.  00000146 DF75F2               419            fbstp   bcd_value       ; Store
  6951.                                420    ;
  6952.                                421    ;         while the store BCD runs, setu
  6953.                                422    ;      for the conversion to ASCII.
  6954.                                423    ;
  6955.  00000149 BE08000000           424            mov     esi,BCD_SIZE.2  ; Initia
  6956.  0000014E 66B9040F             425            mov     cx,0f04h
  6957.  00000152 BB01000000           426            mov     ebx,1
  6958.                                427                                ; field for
  6959.  00000157 8B7D18               428            mov     edi,string_ptr  ; Get ad
  6960.                                429                                ; ASCII stri
  6961.  0000015A 8CD8                 430            mov     ax,ds
  6962.  0000015C 8EC0                 431            mov     es,ax
  6963.  0000015E FC                   432            cld
  6964.  0000015F B02B                 433            mov     al,'+'
  6965.  00000161 F6C201               434            test    dl,MINUS        ; Look f
  6966.  00000164 7402                 435            jz      positive_result
  6967.                                436
  6968.  00000166 B02D                 437            mov     al,`.'
  6969.  00000168                      438    positive_result:
  6970.  00000168 AA                   439            stosb
  6971.                                440                                ; past sign
  6972.  00000169 80E2FE               441            and     dl,not MINUS    ; Turn o
  6973.  0000016C 9B                   442            fwait
  6974.                                443    ;
  6975.                                444    ;         Register usage:
  6976.                                445    ;                               ah:
  6977.                                446    ;                               al:
  6978.                                447    ;                               dx:
  6979.                                448    ;                               ch:
  6980.                                449    ;                               cl:
  6981.                                450    ;                               bx:
  6982.                                451    ;                               esi:
  6983.                                452    ;                               di:
  6984.                                453    ;                               ds,es:
  6985.                                454    ;
  6986.                                455    ;         Remove leading zeroes from the
  6987.                                456    ;
  6988.  0000016D                      457    skip_leading_zeroes:
  6989.  0000016D 8A6435F2             458           mov     ah,bcd_byte[esi]
  6990.  00000171 88E0                 459           mov     al,ah                   ;
  6991.  00000173 D2E8                 460           shr     al,cl                   ;
  6992.  00000175 240F                 461           and     al,0fh                  ;
  6993.  00000177 7517                 462           jnz     enter_odd               ;
  6994.                                463                               ; non zero fo
  6995.                                464
  6996.  00000179 88E0                 465           mov     al,ah                   ;
  6997.  0000017B 240F                 466           and     al,0fh                  ;
  6998.  0000017D 7519                 467           jnz     enter_even              ;
  6999.                                468                               ; digit found
  7000.                                469
  7001.  0000017F 4E                   470           dec     esi
  7002.  00000180 79EB                 471           jns     ship_leading_zeroes
  7003.                                472    ;
  7004.                                473    ;        The significand was all zeroes.
  7005.                                474    ;
  7006.  00000182 B030                 475           mov     al,`O'                  ;
  7007.  00000184 AA                   476           stosb
  7008.  00000185 43                   477           inc     ebx
  7009.  00000186 EB17                 478           jmo     short exit_with_value
  7010.                                479    ;
  7011.                                480    ;        Now expand the BCD string into
  7012.                                481    ;     per byte values 0-9.
  7013.                                482    ;
  7014.  00000188                      483    digit_loop:
  7015.  00000188 8A6435F2             484           mov     ah,bcd_byte[esi]        ;
  7016.  0000018C 88E0                 485           mov     al,ah
  7017.  0000018E D2E8                 486           shr     al,cl                   ;
  7018.  00000190                      487    enter_odd:
  7019.  00000190 0430                 488           add     al,`O'                  ;
  7020.  00000192 AA                   489           stosb                           ;
  7021.                                490                               ; string area
  7022.  00000193 88E0                 491           mov     al,ah                   ;
  7023.  00000195 240F                 492           and     al,0fh
  7024.  00000197 43                   493           inc     ebx                     ;
  7025.  00000198                      494    enter_even:
  7026.  00000198 0430                 495           add     al,`0'           ; Conver
  7027.  0000019A AA                   496           stosb                    ; Put di
  7028.  0000019B 43                   497           inc     ebx                     ;
  7029.  0000019C 4E                   498           dec     esi                     ;
  7030.  0000019D 79E9                 499           jns     digit_loop
  7031.                                500    ;
  7032.                                501    ;        Conversion complete.  Set the s
  7033.                                502    ;     size and remainder.
  7034.                                503    ;
  7035.  0000019F                      504    exit_with_value:
  7036.  0000019F 8B7D14               505           mov     edi,size_ptr
  7037.  000001A2 66891F               506           mov     word ptr [edi],bx
  7038.  000001A5 8BC2                 507           mov     eax,edx                 ;
  7039.  000001A7 E980FEFFFF           508           jmp     exit_proc
  7040.                                509
  7041.  000001AC                      510    floating_to_ascii      endp
  7042.                                511
  7043.  --------                      512    code                   ends
  7044.                                513                           end
  7045.  
  7046.  ASSEMBLY COMPLETE,   NO WARNINGS,   NO ERRORS.
  7047.  
  7048.  
  7049.  XENIX286 80386 MACRO ASSEMBLER V1.0, ASSEMBLY OF MODULE_GET_POWER 10
  7050.  OBJECT MODULE PLACED IN power10.obj
  7051.  ASSEMBLER INVOKED BY: asm386 power10.asm
  7052.  
  7053.  LOC      OBJ                         LINE     SOURCE
  7054.  
  7055.                               1 +1 $title(Calculate the value of 10**ax)
  7056.                               2    ;
  7057.                               3    ;       This subroutine will calculate the
  7058.                               4    ;    value of 10**eax.  For values of
  7059.                               5    ;    0 <= eax < 19, the result will exact.
  7060.                               6    ;    All 80386 registers are transparent
  7061.                               7    ;    and the value is returned on the TOS
  7062.                               8    ;    as two numbers, exponent in ST(1) and
  7063.                               9    ;    fraction in ST(0). The exponent value
  7064.                              10    ;    can be larger than the largest
  7065.                              11    ;    exponent of an extended real format
  7066.                              12    ;    number.  Three stack entries are used.
  7067.                              13    ;
  7068.                              14                    name    get_power_10
  7069.  00000000                    15                    public  get_power_10,power_
  7070.                              16
  7071.  --------                    17    stack           stackseg    8
  7072.                              18
  7073.  --------                    19    code            segment public er
  7074.                              20    ;
  7075.                              21    ;         Use exact values from 1.0 to 1e18
  7076.                              22    ;
  7077.                              23                    even            ; Optimize
  7078.  00000000 000000000000F03F   24    power_table     dq      1.0,1e1,1e2,1e3
  7079.  00000008 00000000000D2440
  7080.  00000010 0000000000005940
  7081.  00000018 0000000000408F40
  7082.  00000020 000000000088C340   25                    dq      1e4,1e5,1e6,1e7
  7083.  00000028 00000000006AF840
  7084.  00000030 0000000080842E41
  7085.  00000038 00000000D0126341
  7086.  00000040 0000000084D79741   26                    dq      1e8,1e9,1e10,1e11
  7087.  00000048 0000000065CDCD41
  7088.  00000050 000000205FA00242
  7089.  00000058 000000E876483742
  7090.  00000060 000000A2941A6D42   27                    dq      1e12,1e13,1e14,1e15
  7091.  00000068 000040E59C30A242
  7092.  00000070 0000901EC4BCD642
  7093.  00000078 00003420F56B0C43
  7094.  00000080 0080E03779C34143   28                    dq      1e16,1e17,1e18
  7095.  00000088 00A0D88557347643
  7096.  00000090 00C84E676DC1ABC3
  7097.                              29
  7098.  00000098                    30    get_power_10    proc
  7099.                              31
  7100.  00000098 3D12000000         32            cmp     eax,18          ; Test for
  7101.  0000009D 770B               33            ja      out_of_range
  7102.                              34
  7103.  0000009F 2EDD04C500000000 R 35            fld     power_table[eax*8]; Get exa
  7104.  000000A7 D9F4               36            fxtract                         ; S
  7105.  
  7106.  
  7107.  7.3.1  Function Partitioning
  7108.  
  7109.  Three separate modules implement the conversion. Most of the work of the
  7110.  conversion is done in the module FLOATING_TO_ASCII. The other modules are
  7111.  provided separately, because they have a more general use. One of them,
  7112.  GET_POWER_10, is also used by the ASCII to floating-point conversion
  7113.  routine. The other small module, TOS_STATUS, identifies what, if anything,
  7114.  is in the top of the numeric register stack.
  7115.  
  7116.  
  7117.  7.3.2  Exception Considerations
  7118.  
  7119.  Care is taken inside the function to avoid generating exceptions. Any
  7120.  possible numeric value is accepted. The only possible exception is
  7121.  insufficient space on the numeric register stack.
  7122.  
  7123.  The value passed in the numeric stack is checked for existence, type (NaN
  7124.  or infinity), and status (denormal, zero, sign). The string size is tested
  7125.  for a minimum and maximum value. If the top of the register stack is empty,
  7126.  or the string size is too small, the function returns with an error code.
  7127.  
  7128.  Overflow and underflow is avoided inside the function for very large or
  7129.  very small numbers.
  7130.  
  7131.  
  7132.  7.3.3  Special Instructions
  7133.  
  7134.  The functions demonstrate the operation of several numeric instructions,
  7135.  different data types, and precision control. Shown are instructions for
  7136.  automatic conversion to BCD, calculating the value of 10 raised to an
  7137.  integer value, establishing and maintaining concurrency, data
  7138.  synchronization, and use of directed rounding on the NPX.
  7139.  
  7140.  Without the extended precision data type and built-in exponential function,
  7141.  the double precision accuracy of this function could not be attained with
  7142.  the size and speed of the shown example.
  7143.  
  7144.  The function relies on the numeric BCD data type for conversion from binary
  7145.  floating-point to decimal. It is not difficult to unpack the BCD digits into
  7146.  separate ASCII decimal digits. The major work involves scaling the
  7147.  floating-point value to the comparatively limited range of BCD values. To
  7148.  print a 9-digit result requires accurately scaling the given value to an
  7149.  integer between 10^(8) and 10^(9). For example, the number +0.123456789
  7150.  requires a scaling factor of 10^(9) to produce the value +123456789.0, which
  7151.  can be stored in 9 BCD digits. The scale factor must be an exact power of
  7152.  10 to avoid changing any of the printed digit values.
  7153.  
  7154.  These routines should exactly convert all values exactly representable in
  7155.  decimal in the field size given. Integer values that fit in the given string
  7156.  size are not be scaled, but directly stored into the BCD form. Noninteger
  7157.  values exactly representable in decimal within the string size limits are
  7158.  also exactly converted. For example, 0.125 is exactly representable in
  7159.  binary or decimal. To convert this floating-point value to decimal, the
  7160.  scaling factor is 1000, resulting in 125. When scaling a value, the function
  7161.  must keep track of where the decimal point lies in the final decimal value.
  7162.  
  7163.  
  7164.  7.3.4  Description of Operation
  7165.  
  7166.  Converting a floating-point number to decimal ASCII takes three major
  7167.  steps: identifying the magnitude of the number, scaling it for the BCD data
  7168.  type, and converting the BCD data type to a decimal ASCII string.
  7169.  
  7170.  Identifying the magnitude of the result requires finding the value X such
  7171.  that the number is represented by I * 10^(X), where 1.0 ≤ I < 10.0. Scaling
  7172.  the number requires multiplying it by a scaling factor 10^(S), so that the
  7173.  result is an integer requiring no more decimal digits than provided for in
  7174.  the ASCII string.
  7175.  
  7176.  Once scaled, the numeric rounding modes and BCD conversion put the number
  7177.  in a form easy to convert to decimal ASCII by host software.
  7178.  
  7179.  Implementing each of these three steps requires attention to detail. To
  7180.  begin with, not all floating-point values have a numeric meaning. Values
  7181.  such as infinity, indefinite, or NaN may be encountered by the conversion
  7182.  routine. The conversion routine should recognize these values and identify
  7183.  them uniquely.
  7184.  
  7185.  Special cases of numeric values also exist. Denormals have numeric values,
  7186.  but should be recognized because they indicate that precision was lost
  7187.  during some earlier calculations.
  7188.  
  7189.  Once it has been determined that the number has a numeric value, and it is
  7190.  normalized (setting appropriate denormal flags, if necessary, to indicate
  7191.  this to the calling program), the value must be scaled to the BCD range.
  7192.  
  7193.  
  7194.  7.3.5  Scaling the Value
  7195.  
  7196.  To scale the number, its magnitude must be determined. It is sufficient to
  7197.  calculate the magnitude to an accuracy of 1 unit, or within a factor of 10
  7198.  of the required value. After scaling the number, a check is made to see if
  7199.  the result falls in the range expected. If not, the result can be adjusted
  7200.  one decimal order of magnitude up or down. The adjustment test after the
  7201.  scaling is necessary due to inevitable inaccuracies in the scaling value.
  7202.  
  7203.  Because the magnitude estimate for the scale factor need only be close, a
  7204.  fast technique is used. The magnitude is estimated by multiplying the power
  7205.  of 2, the unbiased floating-point exponent, associated with the number by
  7206.  log{10}2. Rounding the result to an integer produces an estimate of
  7207.  sufficient accuracy. Ignoring the fraction value can introduce a maximum
  7208.  error of 0.32 in the result.
  7209.  
  7210.  Using the magnitude of the value and size of the number string, the scaling
  7211.  factor can be calculated. Calculating the scaling factor is the most
  7212.  inaccurate operation of the conversion process. The relation
  7213.  10^(X) = 2^(X * log{2}10) is used for this function. The exponentiate
  7214.  instruction F2XM1 is used.
  7215.  
  7216.  Due to restrictions on the range of values allowed by the F2XM1
  7217.  instruction, the power of 2 value is split into integer and fraction
  7218.  components. The relation 2^(I + F) = 2^(I) * 2^(F) allows using the FSCALE
  7219.  instruction to recombine the 2^(F) value, calculated through F2XM1, and the
  7220.  2^(I) part.
  7221.  
  7222.  
  7223.  7.3.5.1  Inaccuracy in Scaling
  7224.  
  7225.  The inaccuracy in calculating the scale factor arises because of the
  7226.  trailing zeros placed into the fraction value of the power of two when
  7227.  stripping off the integer valued bits. For each integer valued bit in the
  7228.  power of 2 value separated from the fraction bits, one bit of precision is
  7229.  lost in the fraction field due to the zero fill occurring in the least
  7230.  significant bits.
  7231.  
  7232.  Up to 14 bits may be lost in the fraction because the largest allowed
  7233.  floating point exponent value is 2^(14) - 1. These bits directly reduce the
  7234.  accuracy of the calculated scale factor, thereby reducing the accuracy of
  7235.  the scaled value. For numbers in the range of 10^(±30), a maximum of 8 bits
  7236.  of precision are lost in the scaling process.
  7237.  
  7238.  
  7239.  7.3.5.2  Avoiding Underflow and Overflow
  7240.  
  7241.  The fraction and exponent fields of the number are separated to avoid
  7242.  underflow and overflow in calculating the scaling values. For example, to
  7243.  scale 10^(-4932) to 10^(8) requires a scaling factor of 10^(4950), which
  7244.  cannot be represented by the NPX.
  7245.  
  7246.  By separating the exponent and fraction, the scaling operation involves
  7247.  adding the exponents separate from multiplying the fractions. The exponent
  7248.  arithmetic involves small integers, all easily represented by the NPX.
  7249.  
  7250.  
  7251.  7.3.5.3  Final Adjustments
  7252.  
  7253.  It is possible that the power function (Get_Power_10) could produce a
  7254.  scaling value such that it forms a scaled result larger than the ASCII field
  7255.  could allow. For example, scaling 9.9999999999999999 * 10^(4900) by
  7256.  1.00000000000000010 * 10^(-4883) produces 1.00000000000000009 * 10^(18). The
  7257.  scale factor is within the accuracy of the NPX and the result is within the
  7258.  conversion accuracy, but it cannot be represented in BCD format. This is why
  7259.  there is a post-scaling test on the magnitude of the result. The result can
  7260.  be multiplied or divided by 10, depending on whether the result was too
  7261.  small or too large, respectively.
  7262.  
  7263.  
  7264.  7.3.6  Output Format
  7265.  
  7266.  For maximum flexibility in output formats, the position of the decimal
  7267.  point is indicated by a binary integer called the power value. If the power
  7268.  value is zero, then the decimal point is assumed to be at the right of the
  7269.  rightmost digit. Power values greater than zero indicate how many trailing
  7270.  zeros are not shown. For each unit below zero, move the decimal point to the
  7271.  left in the string.
  7272.  
  7273.  The last step of the conversion is storing the result in BCD and indicating
  7274.  where the decimal point lies. The BCD string is then unpacked into ASCII
  7275.  decimal characters. The ASCII sign is set corresponding to the sign of the
  7276.  original value.
  7277.  
  7278.  
  7279.  7.4  Trigonometric Calculation Examples (Not Tested)
  7280.  
  7281.  In this example, the kinematics of a robot arm is modeled with the 4 * 4
  7282.  homogeneous transformation matrices proposed by Denavit and Hartenberg.
  7283.  The translational and rotational relationships between adjacent links are
  7284.  described with these matrices using the D-H matrix method. For each link,
  7285.  there is a 4 * 4 homogeneous transformation matrix that represents the
  7286.  link's coordinate system (L{i}) at the joint (J{i}) with respect to the
  7287.  previous link's coordinate system (J{i-1}, L{i-1}). The following four
  7288.  geometric quantities completely describe the motion of any rigid joint/link
  7289.  pair (J{i}, L{i}), as Figure 7-7 illustrates.
  7290.  
  7291.    Θ{i} =  The angular displacement of the x{i} axis from the x{i-1} axis by
  7292.            rotating around the z{i-1} axis (anticlockwise).
  7293.  
  7294.    d{i} =  The distance from the origin of the (i-1)^(th) coordinate system
  7295.            along the z{i-1} axis to the x{i} axis.
  7296.  
  7297.    a{i} =  The distance of the origin of the i^(th) coordinate system from
  7298.            the z{i-1} axis along the -x{i} axis.
  7299.  
  7300.    α{i} =  The angular displacement of the z{i} axis from the z{i-1} about
  7301.            the x{i} axis (anticlockwise).
  7302.  
  7303.  The D-H transformation matrix A=^(i){i-1} for adjacent coordinate frames
  7304.  (from joint{i-1} to joint{i}) is calculated as follows:
  7305.  
  7306.    A^(i){i-1}  =  T{z,d} * T{z,Θ} * T{x,a} * T{x,α}
  7307.  
  7308.  ...where...
  7309.  
  7310.    T{z,d}    represents a translation along the z=i-1 axis
  7311.  
  7312.    T{z,Θ}    represents a rotation of angle Θ about the z=i-1 axis
  7313.  
  7314.    T{x,a}    represents a translation along the x{i}axis
  7315.  
  7316.    T{x,α}    represents a rotation of angle α about the x{i}axis
  7317.  
  7318.                │ COS Θ{i}   -COS α{i}SIN Θ{i}  SIN α{i}SIN Θ{i}    COS Θ{i} │
  7319.  A^(i){i-1} =  │ SIN Θ{i}   COS α{i}COS Θ{i}   -SIN α{i}COS Θ{i}   SIN Θ{i} │
  7320.                │ 0          SIN α{i}           COS α{i}            d{i}     │
  7321.                │ 0          0                  0                   1        │
  7322.  
  7323.  The composite homogeneous matrix T which represents the position and
  7324.  orientation of the joint/link pair with respect to the base system is
  7325.  obtained by successively multiplying the D-H transformation matrices for
  7326.  adjacent coordinate frames.
  7327.  
  7328.    T^(i){0} = A^(1){0}  *  A^(2){1}  * ... *  A^(i){i-1}
  7329.  
  7330.  This example in Figure 7-8 illustrates how the transformation process can
  7331.  be accomplished using the 80387. The program consists of two major
  7332.  procedures. The first procedure TRANS_PROC is used to calculate the elements
  7333.  in each D-H matrix, A^(i){i-1}.  The second procedure MATRIXMUL_PROC finds
  7334.  the product of two successive D-H matrices.
  7335.  
  7336.  
  7337.  Figure 7-8.  Robot Arm Kinematics Example
  7338.  
  7339.  XENIX286 80386 MACRO ASSEMBLER V1.0, ASSEMBLY OF MODULE TOS_STATUS
  7340.  OBJECT MODULE PLACED IN tos.obj
  7341.  ASSEMBLER INVOKED BY: asm386 tos.asm
  7342.  
  7343.  LOC      OBJ                LINE    SOURCE
  7344.  
  7345.                         1 +1 $title(Determine TOS register contents)
  7346.                         2    ;
  7347.                         3    ;         This subroutine will return a value
  7348.                         4    ;    from 0-15 in eax corresponding
  7349.                         5    ;         to the contents of NPX TOS.  All
  7350.                         6    ;    registers are transparent and no
  7351.                         7    ;         errors are possible.  The return
  7352.                         8    ;    value corresponds to c3,c2,c1,c0
  7353.                         9    ;         of FXAM instruction.
  7354.                        10    ;
  7355.                        11            name    tos_status
  7356.  00000000              12            public  tos_status
  7357.                        13
  7358.  --------              14    stack           stackseg      6
  7359.                        15
  7360.  --------              16    code            segment public er
  7361.                        17
  7362.  00000000              18    tos_status      proc
  7363.                        19
  7364.  00000000 D9E5         20            fxam                    ; Get status of T
  7365.  00000002 9BDFE0       21            fstsw  ax       ; Get current status
  7366.  00000D05 88E0         22            mov     al,ah           ; Put bit 10.8 in
  7367.  00000007 2507400000   23            and     eax,4007h       ; Mask out bits c
  7368.  0000000C C0EC03       24            shr     ah, 3           ; Put bit c3 into
  7369.  0000000F 08E0         25            or      al,ah           ; Put c3 into bit
  7370.  00000011 B400         26            mov     ah,0            ; Clear return va
  7371.  00000013 C3           27            ret
  7372.                        28
  7373.  00000014              29    tos_status      endp
  7374.                        30
  7375.  --------              31    code            ends
  7376.                        32                    end
  7377.  
  7378.  ASSEMBLY COMPLETE,   NO WARNINGS,    NO ERRORS.
  7379.  
  7380.  
  7381.  LOC      OBJ                LINE    SOURCE
  7382.  
  7383.                      37                                ; and fraction
  7384.  000000A9 C3         38            rat             ; OK to leave fxtract runni
  7385.                      39    ;
  7386.                      40    ;         Calculate the value using the
  7387.                      41    ;     exponentiate instruction. The following
  7388.                      42    ;     relations are used:
  7389.                      43    ;               10**x = 2**(log2(10)*x)
  7390.                      44    ;               2**(I+F) = 2**I  * 2**F
  7391.                      45    ;       if st(1) = I and st(0)  = 2**F then
  7392.                      46    ;       fscale produces 2**(I+F)
  7393.                      47    ;
  7394.  000000AA            48    out of range:
  7395.                      49
  7396.  000000AA D9E9       50            fld12t                  ; TOS = LOG2(10)
  7397.  000000AC C8040000   51            enter   4,0
  7398.                      52
  7399.                      53        ; save power of 10 value, P
  7400.  000000B0 8945FC     54        mov     [ebp-4],eax
  7401.                      55
  7402.                      56        ; T0S,X = LOG2(10)*P =  LOG2(10**P)
  7403.  000000B3 DA4DFC     57            fimul   dword ptr [ebp-4]
  7404.  000000B6 D9E8       58            fld1            ; Set TOS = -1.0
  7405.  000000B8 D9E0       59            fchs
  7406.  000000BA D9C1       60            fld     st(1)   ; Copy power value
  7407.                      61                            ; in base two
  7408.  000000BC D9FC       62            frndint         ; TOS = I: -inf < I <= X
  7409.                      63                            ; where I is an integer
  7410.                      64                            ; Rounding mode does
  7411.                      65                            ; not matter
  7412.  0000003E D9CA       66            fxch    st(2)   ; TOS = X, ST(1) = -1.0
  7413.                      67                                ; ST(2) = I
  7414.  000000C0 D8E2       68            fsub    st,st(2)    ; T0S,F = X-I:
  7415.                      69                                ; -1.0 < TOS <= 1.0
  7416.                      70
  7417.                      71            ; Restore orignal rounding control
  7418.  000000C2 58         72            pop     eax
  7419.  000000C3 D9F0       73            f2xm1                   ; TOS = 2**(F) - 1.
  7420.  000000C5 C9         74            leave                   ; Restore stack
  7421.  000000C6 DEE1       75            fsubr                   ; Form 2**(F)
  7422.  000000C8 C3         76            rat                     ; OK to leave fsubr
  7423.                      77
  7424.  000000C9            78    get_power_10    endp
  7425.                      79
  7426.  --------            80    code            ends
  7427.                      81                    end
  7428.  
  7429.  ASSEMBLY COMPLETE,   NO WARNINGS,   NO ERRORS.
  7430.  
  7431.  
  7432.  XENIX286 80386 MACRO ASSEMBLER V1.0, ASSEMBLY OF MODULE ROT_MATRIX_CAL
  7433.  OBJECT MODULE PLACED IN transx.obj
  7434.  ASSEMBLER INVOKED BY: asm386 transx.asm
  7435.  
  7436.  LOC      OBJ                LINE    SOURCE
  7437.  
  7438.                                 1    Name ROT_MATRIX_CAL
  7439.                                 2
  7440.                                 3
  7441.                                 4
  7442.                                 5    ; This example illustrates the use
  7443.                                 6    ; of the 80387 floating point
  7444.                                 7    ; instructions, in particular, the
  7445.                                 8    ; FSINCOS function which  gives both
  7446.                                 9    ; the SIN and COS values.
  7447.                                 10   ; The program calculates the
  7448.                                 11   ; composite matrix for base to
  7449.                                 12   ; end-effector transformation.
  7450.                                 13   ;
  7451.                                 14   ; Only the kinematics is considered in
  7452.                                 15   ; this example.
  7453.                                 16   ;
  7454.                                 17   ; If the composite matrix mentioned above
  7455.                                 18   ; is given by:
  7456.                                 19   ; T1n = A1 x A2 x ... x An
  7457.                                 20   ; T1n is found by successively calling
  7458.                                 21   ; trans_proc and matrixmul_pro until
  7459.                                 22   ; all matrices have been exhausted.
  7460.                                 23   ;
  7461.                                 24   ; trans_proc calculates entries in each
  7462.                                 25   ; A(A1,...,An) while matrixmul_proc
  7463.                                 26   ; performs the matrix multiplication for
  7464.                                 27   ; Ai and Ai+1. matrixmul_proc in turn
  7465.                                 28   ; calls matrix_row and matrix_elem to
  7466.                                 29   ; do the multiplication.
  7467.                                 30
  7468.                                 31
  7469.                                 32   ; Define stack space
  7470.                                 33
  7471.  --------                       34   trans_stack stackseg 400
  7472.                                 35
  7473.                                 36   ; Define the matrix structure for
  7474.                                 37   ; 4X4 transformational matrices
  7475.                                 38
  7476.  --------                       39     a_matrix struc
  7477.  00000000                       40             a11    dq    ?
  7478.  00000008                       41             a12    dq    ?
  7479.  00000010                       42             a13    dq    ?
  7480.  00000018                       43             a14    dq    ?
  7481.  00000020                       44             a21    dq    ?
  7482.  00000028                       45             a22    dq    ?
  7483.  00000030                       46             a23    dq    ?
  7484.  00000038                       47             a24    dq    ?
  7485.  00000040                       48             a31    dq    0h
  7486.  00000048                       49             a32    dq    ?
  7487.  00000050                       50             a33    dq    ?
  7488.  00000058                       51             a34    dq    ?
  7489.  00000060                       52             a41    dq    0h
  7490.  00000068                       53             a42    dq    0h
  7491.  00000070                       54             a43    dq    0h
  7492.  00000078                       55             a44    dq    1h
  7493.  --------                       56     a_matrix ends
  7494.                                 57
  7495.                                 58   ; Assume One joint in the storage
  7496.                                 59   ; allocation and hence for
  7497.                                 60   ; two sets of parameters; however,
  7498.                                 61   ; more joints are possible
  7499.                                 62   ;
  7500.                                 63     alp_deg struc
  7501.  00000000                       64             alpha_deg1 dd  ?
  7502.  00000004                       65             alpha_deg2 dd
  7503.  --------                       66     alp_deg ends
  7504.                                 67
  7505.  --------                       68     tht_deg struc
  7506.  00000000                       69             theta_deg1 dd  ?
  7507.  00000004                       70             theta_deg2 dd
  7508.  --------                       71     tht_deg ends
  7509.                                 72
  7510.  --------                       73     A_array struc
  7511.  00000000                       74             A1         dq  ?
  7512.  00000008                       75             A2         dq  ?
  7513.  --------                       76     A_array ends
  7514.                                 77
  7515.  --------                       78     D_array struc
  7516.  00000000                       79             D1         dq  ?
  7517.  00000008                       80             D2         dq  ?
  7518.  --------                       81     D_array ends
  7519.                                 82
  7520.                                 83   ; trans_data is the data segment
  7521.                                 84   ;
  7522.                                 85
  7523.  -------                        86   trans_data       segment rw public
  7524.                                 87
  7525.                                 88           Amx            a_matrix<>
  7526.  00000000 ????????????????
  7527.  00000008 ????????????????
  7528.  00000010 ????????????????
  7529.  00000018 ????????????????
  7530.  00000020 ????????????????
  7531.  00000028 ????????????????
  7532.  00000030 ????????????????
  7533.  00000038 ????????????????
  7534.  00000040 0000000000000000
  7535.  00000048 ????????????????
  7536.  00000050 ????????????????
  7537.  00000058 ????????????????
  7538.  00000060 0000000000000000
  7539.  00000068 0000000000000000
  7540.  00000070 0000000000000000
  7541.  00000078 0100000000000000
  7542.  00000080 ????????????????      89           Bmx            a_matrix<>
  7543.  00000088 ????????????????
  7544.  00000090 ????????????????
  7545.  00000098 ????????????????
  7546.  000000A0 ????????????????
  7547.  000000A8 ????????????????
  7548.  000000B0 ????????????????
  7549.  000000B8 ????????????????
  7550.  000000C0 0000000000000000
  7551.  000000C8 ????????????????
  7552.  000000D0 ????????????????
  7553.  000000D8 ????????????????
  7554.  000000E0 0000000000000000
  7555.  000000E8 0000000000000000
  7556.  000000F0 0000000000000000
  7557.  000000F8 0100000000000000
  7558.  00000100 ????????????????      90           Tmx            a matrix<>
  7559.  00000108 ????????????????
  7560.  00000110 ????????????????
  7561.  00000118 ????????????????
  7562.  00000120 ????????????????
  7563.  00000128 ????????????????
  7564.  00000130 ????????????????
  7565.  00000138 ????????????????
  7566.  00000140 0000000000000000
  7567.  00000148 ????????????????
  7568.  00000150 ????????????????
  7569.  00000158 ????????????????
  7570.  00000160 0000000000000000
  7571.  00000168 0000000000000000
  7572.  00000170 0000000000000000
  7573.  00000178 0100000000000000
  7574.  00000180 ????????              91           ALPHA_DEG      alp_deg<>
  7575.  00000184 ????????
  7576.  00000188 ????????              92           THETA_DEG      tht_deg<>
  7577.  0000018C ????????
  7578.  00000190 ????????????????      93           A_VECT0R       A_array<>
  7579.  00000198 ????????????????
  7580.  000001A0 ????????????????      94           D_VECT0R       D_array<>
  7581.  000001A8 ????????????????
  7582.  000001B0 00000000              95           ZER0           dd            0
  7583.  000001B4 B4000000              96           d180           dd          180
  7584.    0001                         97           NUM_JOIMT      equ           1
  7585.    0004                         98           NUM_ROW        equ           4
  7586.    0004                         99           NUM_CDL        equ           4
  7587.  000001B8 01                   100           REVERSE        db            1h
  7588.  --------                      101   trans_data ends
  7589.                                102
  7590.                                103   assume    ds:trans_data, es:trans_data
  7591.                                104
  7592.                                105
  7593.                                106   ; trans_code contains the procedures
  7594.                                107   ; for calculating matrix elements and
  7595.                                108   ; matrix multiplications
  7596.                                109
  7597.  --------                      110   trans_code    segment    er public
  7598.                                111
  7599.                                112   ; create mnemonics for fsincos which is n
  7600.                                113   ; yet available from ASM386 as of now
  7601.                                114
  7602.     C MACRO                    115   codemacro fsincos
  7603.         #                      116   dw 0fbd9h
  7604.         #                      117   endm
  7605.                                118
  7606.  00000000                      119   trans_proc proc far
  7607.                                120
  7608.                                121
  7609.                                122       ; Calculate alpha and theta in radian
  7610.                                123       ; from their values in degrees
  7611.                                124
  7612.  00000000 D9EB                 125         fldpi
  7613.  00000002 D835B4010000    R    126         fdiv    d180
  7614.                                127
  7615.                                128       ; Duplicate pi/180
  7616.  00000008 D9C0                 129         fld     st
  7617.                                130
  7618.  0000000A DC0CCD80010000  R    131         fmul    qword ptr ALPHA_DEG[ecx*8]
  7619.  00000011 D9C9                 132         fxch    st(1)
  7620.  00000013 DC0CCD88010000  R    133         fmul    qword ptr THETA_DEG[ecx*8]
  7621.                                134
  7622.                                135       ; theta(radians) in ST and
  7623.                                136       ; alpha(radians) in ST(1)
  7624.                                137
  7625.                                138       ; Calculate matrix elements
  7626.                                139       ; a11 = cos theta
  7627.                                140       ; a12 = - cos alpha * sin theta
  7628.                                141       ; a13 = sin alpha * sin theta
  7629.                                142       ; a14 = A * cos theta
  7630.                                143       ; a21 = sin theta
  7631.                                144       ; a22 = cos alpha * cos theta
  7632.                                145       ; a23 = -sin alpha * cos theta
  7633.                                146       ; a24 = A * sin theta
  7634.                                147       ; a32 = sin alpha
  7635.                                148       ; a33 = cos alpha
  7636.                                149       ; a34 = D
  7637.                                150       ; a31 = a41 = a42 = a43 = 0.0
  7638.                                151       ; a44 =1
  7639.                                152
  7640.                                153       ; ebx contains the offset for the mat
  7641.                                154
  7642.  0000001A D9FB                 155        fsincos           ;cos theta in ST
  7643.                                156                          ;sin theta in ST(1
  7644.  0000001C D9C0                 157        fld     st        ;duplicate cos the
  7645.  0000001E DD13                 158        fst     [ebx].a11 ;cos theta in a11
  7646.  00000020 DC0CCD90010000  R    159        fmul    qword ptr A_VECTOR[ecx*8]
  7647.  00000027 DD5B18               160        fstp    [ebx].a14 ;A * cos theta in
  7648.  0000002A D9C9                 161        fxch    st(1)     ;sin theta in ST
  7649.  0000002C DD5320               162        fst     [ebx].a21 ;sin theta in a21
  7650.  0000002F D9C0                 163        fld     st        ;duplicate sin the
  7651.  00000031 DC0CCD90010000  R    164        fmul    qword ptr A_VECTOR[ecx*8]
  7652.  00000038 DD5B38               165        fstp    [ebx].a24 ;A * sin theta in
  7653.  0000003B D9C2                 166        fld     st(2)     ;alpha in ST
  7654.  0000003D D9FB                 167        fsincos           ;cos alpha in ST
  7655.                                168                          ;sin alpha in ST(1
  7656.                                169                          ;sin theta in ST(2
  7657.                                170                          ;cos theta in ST(3
  7658.  0000003F DD5350               171        fst     [ebx].a33 ;cos alpha in a33
  7659.  00000042 D9C9                 172        fxch    st(1)     ;sin alpha in ST
  7660.  00000044 DD5348               173        fat     [ebx].a32 ;sin alpha in a32
  7661.  00000047 D9C2                 174        fld     ST(2)     ;sin theta in ST
  7662.                                175                          ;sin alpha in ST(1
  7663.  00000049 D8C9                 176        fmul    st,st(1)  ;sin alpha * sin t
  7664.  0000004B DD5B10               177        fstp    [ebx].a13 ;stored in a13
  7665.  0000004E D8CB                 178        fmul    st,st(3)  ;cos theta * sin a
  7666.  00000050 D9E0                 179        fchs              ;-cos theta * sin
  7667.  00000052 DD5B30               180        fstp    [ebx].a23 ;stored in a23
  7668.  00000055 D9C2                 181        fld     st(2)     ;cos theta in ST
  7669.                                182                          ;cos alpha in ST(1
  7670.                                183                          ;sin theta in ST(2
  7671.                                184                          ;cos theta in ST(3
  7672.  00000057 D8C9                 185        fmul    st,st(1)  ;cos theta * cos a
  7673.  00000059 DD5B28               186        fstp    [ebx].a22 ;stored in a22
  7674.  0000005C D8C9                 187        fmul    st,st(1)  ;cos alpha * sin t
  7675.                                188       ;
  7676.                                189       ; To take advantage of parallel opera
  7677.                                190       ; between the CPU and NPX
  7678.                                191       ;
  7679.  0000005E 50                   192        push    eax  ; save eax
  7680.                                193       ;
  7681.                                194       ; also move D into a34 in a faster wa
  7682.  0000005F 8B04CDA0010000  R    195        mov     eax, dword ptr D_VECTOR[ecx*
  7683.  00000066 894358               196        mov     dword ptr [ebx + 88], eax
  7684.  00000069 8B04CDA4010000  R    197        mov     eax, dword ptr D VECTOR[ecx*
  7685.  00000070 89435C               198        mov     dword ptr [ebx + 92], eax
  7686.  00000073 58                   199        pop     eax  ; restore eax
  7687.  00000074 D9E0                 200        fchs              ;-cos alpha * sin
  7688.  00000076 DD5B08               201        fstp    [ebx].a12 ;stored in a12
  7689.                                202                          ;and all nonzero e
  7690.                                203                          ;have been calcula
  7691.  00000079 CB                   204        rat
  7692.                                205
  7693.  0000007A                      206   trans_proc endp
  7694.                                207
  7695.                                208
  7696.  0000007A                      209   matrix_elem proc far
  7697.                                210
  7698.                                211       ; This procedure calculate the dot pr
  7699.                                212       ; of the ith row of the first matrix
  7700.                                213       ; the jth column of the second matrix
  7701.                                214       ;
  7702.                                215       ; Tij where Tij = sum of Aik x Bkj ov
  7703.                                216       ;
  7704.                                217       ; parameters passed from the calling
  7705.                                218       ; matrix_row:
  7706.                                219       ; ESI = (i-1)*8
  7707.                                220       ; EDI = (j-1)*8
  7708.                                221       ; local register, EBP = (k-1)*8
  7709.                                222       ;
  7710.  0000007A 55                   223         push    ebp     ; save ebp
  7711.  0000007B 51                   224         push    ecx     ; ecx to be used as
  7712.  0000007C 8BCE                 225         mov     ecx, esi; save it for later
  7713.                                226
  7714.                                227       ; locating the element in the first m
  7715.  0000007E 6BC904               228         imul    ecx, NUM_COL   ; ecx contai
  7716.                                229                                ; to precedi
  7717.                                230                                ; offset is
  7718.                                231                                ; beginning
  7719.                                232
  7720.  00000081 31ED                 233         xor     ebp, ebp; clear ebp, which
  7721.                                234                         ; used a temp reg t
  7722.                                235                         ; across the ith ro
  7723.                                236                         ; matrix as well as
  7724.                                237                         ; column of the sec
  7725.                                238
  7726.                                239       ; clear Tij for accumulating Aik*Bkj
  7727.  00000083 892C39               240         mov     dword ptr [ecx][edi],ebp
  7728.  00000086 896C3904             241         mov     dword ptr [ecx][edi+4], ebp
  7729.                                242
  7730.  0000008A 51                   243         push    ecx     ; save on stack: es
  7731.                                244                         ; the offset of the
  7732.                                245                         ; of the ith row fr
  7733.                                246                         ; beginning of the
  7734.                                247
  7735.  0000008B                      248   NXT_k:
  7736.  0000008B 01E9                 249         add     ecx, ebp ; get to the kth c
  7737.                                250                          ; of the ith row o
  7738.                                251
  7739.                                252       ; load AiK into 80387
  7740.  0000008D DD0408               253         fld     qword ptr [eax][ecx]
  7741.                                254
  7742.                                255       ; locating  Bkj
  7743.  00000090 8BCD                 256         mov     ecx, ebp
  7744.  00000092 6BC904               257         imul    ecx, NUM_ROW ; ecx contains
  7745.                                258                              ; of the begin
  7746.                                259                              ; kth row from
  7747.                                260                              ; beginning of
  7748.  00000095 01F9                 261         add    ecx, edi      ; get to the j
  7749.                                262                              ; of the kth r
  7750.                                263                              ; matrix
  7751.  00000097 DC0C0B               264         fmul   qword ptr [ebx][ecx]; Aik *
  7752.  0000009A 59                   265         pop    ecx           ; esi * num_co
  7753.                                266                              ; in ecx again
  7754.  0000009B 51                   267         push   ecx           ; also at top
  7755.                                268                              ; stack
  7756.                                269
  7757.                                270       ; add to the result in the output mat
  7758.  0000009C 01F9                 271         add    ecx, edi
  7759.                                272
  7760.                                273       ; accumulating the sum of Aik * Bkj
  7761.  0000009E DC040A               274         fadd   qword ptr [edx][ecx]
  7762.  000000A1 DD1C0A               275         fstp   qword ptr [edx][ecx]
  7763.                                276       ; increment k by 1, i.e., ebp by 8
  7764.  000000A4 83C508               277         add    ebp, 8
  7765.                                278
  7766.                                279       ; Has k reached the width of the matr
  7767.  000000A7 83FD20               280         cmp    ebp, NUM_COL*8
  7768.  000000AA 7CDF                 281         jl     NXT_k
  7769.                                282
  7770.                                283       ; Restore registers
  7771.  000000AC 59                   284         pop    ecx      ; clear esi*num_col
  7772.  000000AD 59                   285         pop    ecx      ; restore ecx
  7773.  000000AE 5D                   286         pop    ebp      ; restore ebp
  7774.  000000AF CB                   287         ret
  7775.                                288
  7776.  000000B0                      289   matrix_elem endp
  7777.                                290
  7778.                                291
  7779.  000000B0                      292   matrix_row proc far
  7780.                                293
  7781.  000000B0 31FF                 294         xor    edi, edi
  7782.                                295       ; scan across a row
  7783.                                296
  7784.  000000B2                      297   NXT_COL:
  7785.  000000B2 9A7A000000....  R    298         call   matrix_elem
  7786.  000000B9 83C708               299         add    edi, 8
  7787.  000000BC 83FF20               300         cmp    edi, NUM_COL*8
  7788.  000000BF 7CF1                 301         jl     NXT_COL
  7789.  000000C1 CB                   302         ret
  7790.                                303
  7791.  000000C2                      304   matrix_row endp
  7792.                                305
  7793.                                306
  7794.  000000C2                      307   matrixmul_proc proc far
  7795.                                308
  7796.                                309       ; This procedure does the matrix
  7797.                                310       ; multiplication by calling matrix_ro
  7798.                                311       ; to calculate entries in each row
  7799.                                312       ;
  7800.                                313       ; The matrix multiplication is
  7801.                                314       ; performed in the following manner,
  7802.                                315       ;   Tij = Aik x Bkj
  7803.                                316       ; where i and j denote the row and co
  7804.                                317       ; respectively and k is the index for
  7805.                                318       ; scanning across the ith row of the
  7806.                                319       ; first matrix and the jth column of
  7807.                                320       ; second matrix.
  7808.  000000C2 5A                   321         pop     edx ; offset Tmx in edx
  7809.  000000C3 5B                   322         pop     ebx ; offset Bmx in ebx
  7810.  000000C4 58                   323         pop     eax ; offset Amx in eax
  7811.                                324
  7812.                                325       ; setup esi and edi
  7813.                                326       ; edi points to the column
  7814.                                327       ; eai points to the row
  7815.                                328
  7816.  000000C5 31F6                 329         xor     esi, esi ; clear esi
  7817.                                330
  7818.  000000C7                      331   NXT_ROW:
  7819.  000000C7 9AB0000000----  R    332         call    matrix_row
  7820.  000000CE 83C608               333         add     esi, 8
  7821.  000000D1 83FE20               334         cmp     esi, NUM_ROW*8
  7822.  000000D4 7CF1                 335         jl      NXT_ROW
  7823.  000000D6 CB                   336         ret
  7824.                                337
  7825.  000000D7                      338   matrixmul_proc endp
  7826.                                339
  7827.                                340
  7828.  --------                      341   trans_code ends
  7829.                                342
  7830.                                343   ;***************************************
  7831.                                344   ;                                      ;
  7832.                                345   ;                                      ;
  7833.                                346   ;                                      ;
  7834.                                347   ;             Main program             ;
  7835.                                348   ;                                      ;
  7836.                                349   ;                                      ;
  7837.                                350   ;                                      ;
  7838.                                351   ;***************************************
  7839.                                352
  7840.  --------                      353   main_code segment er
  7841.                                354
  7842.  00000000                      355   START:
  7843.                                356
  7844.  00000000 BC00000000      R    357         mov  esp,  stackstart trans_stack
  7845.                                358       ; save all registers
  7846.                                359
  7847.  00000005 60                   360         pushed
  7848.                                361
  7849.                                362       ; ECX denotes the number of joints
  7850.                                363       ; where no of matrices = NUM_JOINT +
  7851.                                364       ; Find the first matrix( from the bas
  7852.                                365       ; of the system to the first joint)
  7853.                                366       ; and call it Bmx
  7854.  00000006 31C9                 367         xor  ecx, ecx          ; 1st matrix
  7855.  00000008 BB80000000      R    368         mov  ebx, offset Bmx  ;
  7856.  0000000D 9A00000000----  R    369         call trans_proc        ; is Bmx
  7857.  00000014 41                   370         inc  ecx
  7858.                                371
  7859.  00000015                      372   NXT MATRIX:
  7860.                                373       ; From the 2nd matrix and on, it
  7861.                                374       ; will be stored in Amx.
  7862.                                375       ; The result from the first matrix mu
  7863.                                376       ; is stored in Tmx but will be access
  7864.                                377       ; as Bmx in the next multiplication.
  7865.                                378       ; As a matter of fact, the roles of B
  7866.                                379       ; and Tmx alternate in successive
  7867.                                380       ; multiplications. This is achieved b
  7868.                                381       ; reversing the order of the Bmx and
  7869.                                382       ; pointers being passed onto the prog
  7870.                                383       ; stack:  Thus, this is invisible to
  7871.                                384       ; matrix multiplication procedure.
  7872.                                385       ; REVERSE serves as the indicator;
  7873.                                386       ; REVERSE = 0 means that the result
  7874.                                387       ;             is to placed in Tmx.
  7875.                                388
  7876.  00000015 BB00000000      R    389         mov     ebx, offset Amx  ;find Amx
  7877.  0000001A 9A00000000----  R    390         call    trans_proc
  7878.  00000021 41                   391         inc     ecx
  7879.  00000022 8035B801000001  R    392         xor     REVERSE, 1h
  7880.  00000029 7511                 393         jnz     Bmx_as_Tmx
  7881.                                394
  7882.                                395       ; no reversing.  Bmx as the second in
  7883.                                396       ; matrix while Tmx as the output matr
  7884.  0000002B 6800000000      R    397         push    offset Amx
  7885.  00000030 6880000000      R    398         push    offset Bmx
  7886.  00000035 6800010000      R    399         push    offset Tmx
  7887.  0000003A EB0F                 400         jmp     CONTINUE
  7888.                                481
  7889.                                402       ; reversing. Tmx as the second input
  7890.                                403       ; matrix while Bmx as the output matr
  7891.  0000003C                      404   Bmx_as_Tmx:
  7892.  0000003C 6800000000      R    405         push    offset Amx
  7893.  00000041 6800010000      R    406         push    offset Tmx  ;reversing the
  7894.  00000046 6880000000      R    407         push    offset Bmx  ;pointers passe
  7895.                                408
  7896.  UUUUUU4B                      409   CONTINUE:
  7897.  0000004B 9AC2000000----  R    410         call    matrixmul_proc
  7898.  00000052 83F901               411         cmp     ecx, NUM_JOINT
  7899.  00000055 7EBE                 412         jle     NXT_MATRIX
  7900.                                413
  7901.                                414       ; if REVERSE = 1 then the final answe
  7902.                                415       ; will be in Bmx otherwise, in Tmx.
  7903.                                416
  7904.  00000057 61                   417         popad
  7905.                                418
  7906.  --------                      419   main_code  ends
  7907.                                420
  7908.                                421   end START, ds:trans data, ss:trans stack
  7909.  
  7910.  ASSEMBLY COMPLETE,   NO WARNINGS,   NO ERRORS.
  7911.  
  7912.  
  7913.  Appendix A  Machine Instruction Encoding and Decoding
  7914.  
  7915.  ───────────────────────────────────────────────────────────────────────────
  7916. ╓┌────┌───────────┌─────────────┌────────────┌───────────────────────────────╖
  7917.  ┌──1st  Byte──┐
  7918.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  7919.  ┌──1st  Byte──┐
  7920.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  7921.  
  7922.  D8   1101 1000   MOD 000 R/M   SIB, displ   FADD       single-real
  7923.  D8   1101 1000   MOD 001 R/M   SIB, displ   FMUL       single-real
  7924.  D8   1101 1000   MOD 010 R/M   SIB, displ   FCOM       single-real
  7925.  D8   1101 1000   MOD 011 R/M   SIB, displ   FCOMP      single-real
  7926.  D8   1101 1000   MOD 100 R/M   SIB, displ   FSUB       single-real
  7927.  D8   1101 1000   MOD 101 R/M   SIB, displ   FSUBR      single-real
  7928.  D8   1101 1000   MOD 110 R/M   SIB, displ   FDIV       single-real
  7929.  D8   1101 1000   MOD 111 R/M   SIB, displ   FDIVR      single-real
  7930.  D8   1101 1000   1100 0 REG                 FADD       ST,ST(i)
  7931.  D8   1101 1000   1100 1 REG                 FMUL       ST,ST(i)
  7932.  D8   1101 1000   1101 0 REG                 FCOM       ST(i)
  7933.  D8   1101 1000   1101 1 REG                 FCOMP      ST(i)
  7934.  D8   1101 1000   1110 0 REG                 FSUB       ST,ST(i)
  7935.  D8   1101 1000   1110 1 REG                 FSUBR      ST,ST(i)
  7936.  D8   1101 1000   1111 0 REG                 FDIV       ST,ST(i)
  7937.  D8   1101 1000   1111 1 REG                 FDIVR      ST,ST(i)
  7938.  D9   1101 1001   MOD 000 R/M   SIB, displ   FLD        single-real
  7939.  D9   1101 1001   MOD 001 R/M                reserved
  7940.  ┌──1st  Byte──┐
  7941.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  7942. D9   1101 1001   MOD 001 R/M                reserved
  7943.  D9   1101 1001   MOD 010 R/M   SIB, displ   FST        single-real
  7944.  D9   1101 1001   MOD 011 R/M   SIB, displ   FSTP       single-real
  7945.  D9   1101 1001   MOD 100 R/M   SIB, displ   FLDENV     14 or 28 bytes
  7946.  
  7947.  
  7948.  
  7949.  
  7950.  D9   1101 1001   MOD 101 R/M   SIB, displ   FLDCW      2 bytes
  7951.  D9   1101 1001   MOD 110 R/M   SIB, displ   FSTENV     14 or 28 bytes
  7952.  
  7953.  
  7954.  
  7955.  
  7956.  D9   1101 1001   MOD 111 R/M   SIB, displ   FSTCW      2 bytes
  7957.  D9   1101 1001   1100 0 REG                 FLD        ST(i)
  7958.  D9   1101 1001   1100 1 REG                 FXCH       ST(i)
  7959.  D9   1101 1001   1101 0000                  FNOP
  7960.  D9   1101 1001   1101 0001                  reserved
  7961.  ┌──1st  Byte──┐
  7962.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  7963. D9   1101 1001   1101 0001                  reserved
  7964.  D9   1101 1001   1101 001-                  reserved
  7965.  D9   1101 1001   1101 01--                  reserved
  7966.  D9   1101 1001   1101 1 REG                 reserved
  7967.  D9   1101 1001   1110 0000                  FCHS
  7968.  D9   1101 1001   1110 0001                  FABS
  7969.  D9   1101 1001   1110 001-                  reserved
  7970.  D9   1101 1001   1110 0100                  FTST
  7971.  D9   1101 1001   1110 0101                  FXAM
  7972.  D9   1101 1001   1110 011-                  reserved
  7973.  D9   1101 1001   1110 1000                  FLD1
  7974.  D9   1101 1001   1110 1001                  FLDL2T
  7975.  D9   1101 1001   1110 1010                  FLDL2E
  7976.  D9   1101 1001   1110 1011                  FLDPI
  7977.  D9   1101 1001   1110 1100                  FLDLG2
  7978.  D9   1101 1001   1110 1101                  FLDLN2
  7979.  D9   1101 1001   1110 1110                  FLDZ
  7980.  D9   1101 1001   1110 1111                  reserved
  7981.  D9   1101 1001   1111 0000                  F2XM1
  7982.  ┌──1st  Byte──┐
  7983.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  7984. D9   1101 1001   1111 0000                  F2XM1
  7985.  D9   1101 1001   1111 0001                  FYL2X
  7986.  D9   1101 1001   1111 0010                  FPTAN
  7987.  D9   1101 1001   1111 0011                  FPATAN
  7988.  D9   1101 1001   1111 0100                  FXTRACT
  7989.  D9   1101 1001   1111 0101                  FPREM1
  7990.  D9   1101 1001   1111 0110                  FDECSTP
  7991.  D9   1101 1001   1111 0111                  FINCSTP
  7992.  D9   1101 1001   1111 1000                  FPREM
  7993.  D9   1101 1001   1111 1001                  FYL2XP1
  7994.  D9   1101 1001   1111 1010                  FSQRT
  7995.  D9   1101 1001   1111 1011                  FSINCOS
  7996.  D9   1101 1001   1111 1100                  FRNDINT
  7997.  D9   1101 1001   1111 1101                  FSCALE
  7998.  D9   1101 1001   1111 1110                  FSIN
  7999.  D9   1101 1001   1111 1111                  FCOS
  8000.  DA   1101 1010   MOD 000 R/M   SIB, displ   FIADD      short-integer
  8001.  DA   1101 1010   MOD 001 R/M   SIB, displ   FIMUL      short-integer
  8002.  DA   1101 1010   MOD 010 R/M   SIB, displ   FICOM      short-integer
  8003.  ┌──1st  Byte──┐
  8004.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8005. DA   1101 1010   MOD 010 R/M   SIB, displ   FICOM      short-integer
  8006.  DA   1101 1010   MOD 011 R/M   SIB, displ   FICOMP     short-integer
  8007.  DA   1101 1010   MOD 100 R/M   SIB, displ   FISUB      short-integer
  8008.  DA   1101 1010   MOD 101 R/M   SIB, displ   FISUBR     short-integer
  8009.  DA   1101 1010   MOD 110 R/M   SIB, displ   FIDIV      short-integer
  8010.  DA   1101 1010   MOD 111 R/M   SIB, displ   FIDIVR     short-integer
  8011.  DA   1101 1010   110- ----                  reserved
  8012.  DA   1101 1010   1110 0---                  reserved
  8013.  DA   1101 1010   1110 1000                  reserved
  8014.  DA   1010 1010   1110 1001                  FUCOMPP
  8015.  DA   1101 1010   1110 101-                  reserved
  8016.  DA   1101 1010   1110 11--                  reserved
  8017.  DA   1101 1010   1111 ----                  reserved
  8018.  DB   1101 1011   MOD 000 R/M   SIB, displ   FILD       short-integer
  8019.  DB   1101 1011   MOD 001 R/M   SIB, displ   reserved
  8020.  DB   1101 1011   MOD 010 R/M   SIB, displ   FIST       short-integer
  8021.  DB   1101 1011   MOD 011 R/M   SIB, displ   FISTP      short-integer
  8022.  DB   1101 1011   MOD 100 R/M   SIB, displ   reserved
  8023.  DB   1101 1011   MOD 101 R/M   SIB, displ   FLD        extended-real
  8024.  ┌──1st  Byte──┐
  8025.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8026. DB   1101 1011   MOD 101 R/M   SIB, displ   FLD        extended-real
  8027.  DB   1101 1011   MOD 110 R/M   SIB, displ   reserved
  8028.  DB   1101 1011   MOD 111 R/M   SIB, displ   FSTP       extended-real
  8029.  DB   1101 1011   110- ----                  reserved
  8030.  DB   1101 1011   1110 0000                  
  8031.  
  8032.  
  8033.  
  8034.  
  8035.  DB   1101 1011   1110 0001                  
  8036.  
  8037.  
  8038.  
  8039.  
  8040.  DB   1101 1011   1110 0010                  FCLEX
  8041.  DB   1101 1011   1110 0011                  FINIT
  8042.  DB   1101 1011   1110 0100                  
  8043.  
  8044.  
  8045.  ┌──1st  Byte──┐
  8046.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8047. 
  8048.  
  8049.  
  8050.  DB   1101 1011   1110 0101                  reserved
  8051.  DB   1101 1011   1110 011-                  reserved
  8052.  DB   1101 1011   1110 1---                  reserved
  8053.  DB   1101 1011   1111 ----                  reserved
  8054.  DC   1101 1100   MOD 000 R/M   SIB, displ   FADD       double-real
  8055.  DC   1101 1100   MOD 001 R/M   SIB, displ   FMUL       double-real
  8056.  DC   1101 1100   MOD 010 R/M   SIB, displ   FCOM       double-real
  8057.  DC   1101 1100   MOD 011 R/M   SIB, displ   FCOMP      double-real
  8058.  DC   1101 1100   MOD 100 R/M   SIB, displ   FSUB       double-real
  8059.  DC   1101 1100   MOD 101 R/M   SIB, displ   FSUBR      double-real
  8060.  DC   1101 1100   MOD 110 R/M   SIB, displ   FDIV       double-real
  8061.  DC   1101 1100   MOD 111 R/M   SIB, displ   FDIVR      double-real
  8062.  DC   1101 1100   1100 0 REG                 FADD       ST(i),ST
  8063.  DC   1101 1100   1100 1 REG                 FMUL       ST(i),ST
  8064.  DC   1101 1100   1101 0 REG                 reserved
  8065.  DC   1101 100    1101 1 REG                 reserved
  8066.  ┌──1st  Byte──┐
  8067.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8068. DC   1101 100    1101 1 REG                 reserved
  8069.  DC   1101 1100   1110 0 REG                 FSUBR      ST(i),ST
  8070.  DC   1101 1100   1110 1 REG                 FSUB       ST(i),ST
  8071.  DC   1101 1100   1111 0 REG                 FDIVR      ST(i),ST
  8072.  DC   1101 1100   1111 1 REG                 FDIV       ST(i),ST
  8073.  DD   1101 1101   MOD 000 R/M   SIB, displ   FLD        double-real
  8074.  DD   1101 1101   MOD 001 R/M                reserved
  8075.  DD   1101 1101   MOD 010 R/M   SIB, displ   FST        double-real
  8076.  DD   1101 1101   MOD 011 R/M   SIB, displ   FSTP       double-real
  8077.  DD   1101 1101   MOD 100 R/M   SIB, displ   FRSTOR     94 or 108 bytes
  8078.  
  8079.  
  8080.  
  8081.  
  8082.  DD   1101 1101   MOD 101 R/M   SIB, displ   reserved
  8083.  DD   1101 1101   MOD 110 R/M   SIB, displ   FSAVE      94 or 108 bytes
  8084.  
  8085.  
  8086.  
  8087.  ┌──1st  Byte──┐
  8088.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8089. 
  8090.  
  8091.  DD   1101 1101   MOD 111 R/M   SIB, displ   FSTSW      2 bytes
  8092.  DD   1101 1101   1100 0 REG                 FFREE      ST(i)
  8093.  DD   1101 1101   1100 1 REG                 reserved
  8094.  DD   1101 1101   1101 0 REG                 FST        ST(i)
  8095.  DD   1101 1101   1101 1 REG                 FSTP       ST(i)
  8096.  DD   1101 1101   1110 0 REG                 FUCOM      ST(i)
  8097.  DD   1101 1101   1110 1 REG                 FUCOMP     ST(i)
  8098.  DD   1101 1101   1111 ----                  reserved
  8099.  DE   1101 1110   MOD 000 R/M   SIB, displ   FIADD      word-integer
  8100.  DE   1101 1110   MOD 001 R/M   SIB, displ   FIMUL      word-integer
  8101.  DE   1101 1110   MOD 010 R/M   SIB, displ   FICOM      word-integer
  8102.  DE   1101 1110   MOD 011 R/M   SIB, displ   FICOMP     word-integer
  8103.  DE   1101 1110   MOD 100 R/M   SIB, displ   FISUB      word-integer
  8104.  DE   1101 1110   MOD 101 R/M   SIB, displ   FISUBR     word-integer
  8105.  DE   1101 1110   MOD 110 R/M   SIB, displ   FIDIV      word-integer
  8106.  DE   1101 1110   MOD 111 R/M   SIB, displ   FIDIVR     word-integer
  8107.  DE   1101 1110   1100 0 REG                 FADDP      ST(i),ST
  8108.  ┌──1st  Byte──┐
  8109.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8110. DE   1101 1110   1100 0 REG                 FADDP      ST(i),ST
  8111.  DE   1101 1110   1100 1 REG                 FMULP      ST(i),ST
  8112.  DE   1101 1110   1101 0---                  reserved
  8113.  DE   1101 1110   1101 1000                  reserved
  8114.  DE   1101 1110   1101 1001                  FCOMPP
  8115.  DE   1101 1110   1101 101-                  reserved
  8116.  DE   1101 1110   1101 11--                  reserved
  8117.  DE   1101 1110   1110 0 REG                 FSUBRP     ST(i),ST
  8118.  DE   1101 1110   1110 1 REG                 FSUBP      ST(i),ST
  8119.  DE   1101 1110   1111 0 REG                 FDIVRP     ST(i),ST
  8120.  DE   1101 1110   1111 1 REG                 FDIVP      ST(i),ST
  8121.  DF   1101 1111   MOD 000 R/M   SIB, displ   FILD       word-integer
  8122.  DF   1101 1111   MOD 001 R/M   SIB, displ   reserved
  8123.  DF   1101 1111   MOD 010 R/M   SIB, displ   FIST       word-integer
  8124.  DF   1101 1111   MOD 011 R/M   SIB, displ   FISTP      word-integer
  8125.  DF   1101 1111   MOD 100 R/M   SIB, displ   FBLD       packed-decimal
  8126.  DF   1101 1111   MOD 101 R/M   SIB, displ   FILD       long-integer
  8127.  DF   1101 1111   MOD 110 R/M   SIB, displ   FBSTP      packed-decimal
  8128.  DF   1101 1111   MOD 111 R/M   SIB, displ   FISTP      long-integer
  8129.  ┌──1st  Byte──┐
  8130.  Hex  Binary      2nd Byte      Bytes 3-7    ASM386 Instruction Format
  8131. DF   1101 1111   MOD 111 R/M   SIB, displ   FISTP      long-integer
  8132.  DF   1101 1111   1100 0 REG                 reserved
  8133.  DF   1101 1111   1100 1 REG                 reserved
  8134.  DF   1101 1111   1101 0 REG                 reserved
  8135.  DF   1101 1111   1101 1 REG                 reserved
  8136.  DF   1101 1111   1110 0000                  FSTSW AX
  8137.  DF   1101 1111   1110 0001                  reserved
  8138.  DF   1101 1111   1110 001-                  reserved
  8139.  DF   1101 1111   1110 01--                  reserved
  8140.  DF   1101 1111   1110 1---                  reserved
  8141.  DF   1101 1111   1111 ----                  reserved
  8142.  
  8143.  
  8144.  Appendix B  Exception Summary
  8145.  
  8146.  ────────────────────────────────────────────────────────────────────────────
  8147.  
  8148.  The following table lists the instruction mnemonics in alphabetical order.
  8149.  For each mnemonic, it summarizes the exceptions that the instruction may
  8150.  cause. When writing 80387 programs that may be used in an environment that
  8151.  employs numerics exception handlers, assembly-language programmers should be
  8152.  aware of the possible exceptions for each instruction in order to determine
  8153.  the need for exception synchronization. Chapter 4 explains the need for
  8154.  exception synchronization.
  8155.  
  8156. ╓┌───────────────────┌───────────────────────┌────┌───┌───┌───┌───┌───┌──────╖
  8157.  Mnemonic            Instruction             IS  I  D  Z  O  U  P
  8158.  
  8159.  
  8160.  
  8161.  
  8162.  
  8163.  F2XM1               2^(X) - 1                Y   Y   Y           Y   Y
  8164.  FABS                Absolute value           Y
  8165.  FADD(P)             Add real                 Y   Y   Y       Y   Y   Y
  8166.  FBLD                BCD load                 Y
  8167.  FBSTP               BCD store and pop        Y   Y                   Y
  8168.  FCHS                Change sign              Y
  8169.  FCLEX               Clear exceptions
  8170.  FCOM(P)(P)          Compare real             Y   Y   Y
  8171.  Mnemonic            Instruction             IS  I  D  Z  O  U  P
  8172. FCOM(P)(P)          Compare real             Y   Y   Y
  8173.  FCOS                Cosine                   Y   Y   Y           Y   Y
  8174.  FDECSTP             Decrement stack pointer
  8175.  FDIV(R)(P)          Divide real              Y   Y   Y   Y   Y   Y   Y
  8176.  FFREE               Free register
  8177.  FIADD               Integer add              Y   Y   Y       Y   Y   Y
  8178.  FICOM(P)            Integer compare          Y   Y   Y
  8179.  FIDIV               Integer divide           Y   Y   Y   Y       Y   Y
  8180.  FIDIVR              Integer divide reversed  Y   Y   Y   Y   Y   Y   Y
  8181.  FILD                Integer load             Y
  8182.  FIMUL               Integer multiply         Y   Y   Y   Y   Y   Y
  8183.  FINCSTP             Increment stack pointer
  8184.  FINIT               Initialize processor
  8185.  FIST(P)             Integer store            Y   Y                   Y
  8186.  FISUB(R)            Integer subtract         Y   Y   Y       Y   Y   Y
  8187.  FLD extended
  8188.  or stack            Load real                Y
  8189.  FLD single
  8190.  or double           Load real                Y   Y   Y
  8191.  FLD1                Load + 1.0               Y
  8192.  Mnemonic            Instruction             IS  I  D  Z  O  U  P
  8193. FLD1                Load + 1.0               Y
  8194.  FLDCW               Load Control word        Y   Y   Y   Y   Y   Y   Y
  8195.  FLDENV              Load environment         Y   Y   Y   Y   Y   Y   Y
  8196.  FLDL2E              Load log{2}e             Y
  8197.  FLDL2T              Load log{2}10            Y
  8198.  FLDLG2              Load log{10}2            Y
  8199.  FLDLN2              Load log{e}2             Y
  8200.  FLDPI               Load π                   Y
  8201.  FLDZ                Load + 0.0               Y
  8202.  FMUL(P)             Multiply real            Y   Y   Y       Y   Y   Y
  8203.  FNOP                No operation
  8204.  FPATAN              Partial arctangent       Y   Y   Y           Y   Y
  8205.  FPREM               Partial remainder        Y   Y   Y           Y
  8206.  FPREM1              IEEE partial remainder   Y   Y   Y           Y
  8207.  FPTAN               Partial tangent          Y   Y   Y           Y   Y
  8208.  FRNDINT             Round to integer         Y   Y   Y               Y
  8209.  FRSTOR              Restore state            Y   Y   Y   Y   Y   Y   Y
  8210.  FSAVE               Save state
  8211.  FSCALE              Scale                    Y   Y   Y       Y   Y   Y
  8212.  FSIN                Sine                     Y   Y   Y           Y   Y
  8213.  Mnemonic            Instruction             IS  I  D  Z  O  U  P
  8214. FSIN                Sine                     Y   Y   Y           Y   Y
  8215.  FSINCOS             Sine and cosine          Y   Y   Y           Y   Y
  8216.  FSQRT               Square root              Y   Y   Y               Y
  8217.  FST(P) stack
  8218.  or extended         Store real               Y
  8219.  FST(P) single
  8220.  or double           Store real               Y   Y   Y       Y   Y   Y
  8221.  FSTCW               Store control word
  8222.  FSTENV              Store Environment
  8223.  FSTSW (AX)          Store status word
  8224.  FSUB(R)(P)          Subtract real            Y   Y   Y       Y   Y   Y
  8225.  FTST                Test                     Y   Y   Y
  8226.  FUCOM(P)(P)         Unordered compare real   Y   Y   Y
  8227.  FWAIT               CPU Wait
  8228.  FXAM                Examine
  8229.  FXCH                Exchange registers       Y
  8230.  FXTRACT             Extract                  Y   Y   Y   Y
  8231.  FYL2X               Y * log{2}X              Y   Y   Y   Y   Y   Y   Y
  8232.  FYL2XP1             Y * log{2}(X + 1)        Y   Y   Y           Y   Y
  8233.  
  8234.  
  8235.  Appendix C  Compatibility Between the 80387 and the 80287/8087
  8236.  
  8237.  ───────────────────────────────────────────────────────────────────────────
  8238.  
  8239.  This appendix summarizes the differences between the 80387 and its
  8240.  predecessors the 80287 and the 8087, and analyzes the impact of these
  8241.  differences on software that must be transported from the 80287 or 8087 to
  8242.  the 80387. Any migration from the 8087 directly to the 80387 must also take
  8243.  into account the additional differences between the 8087 and the 80387 as
  8244.  listed in Appendix D of this manual.
  8245.  
  8246. ╓┌───────────────┌────────────────────────────────┌──────────────────────────
  8247.                  ┌────────────────────Difference Description──────────────────
  8248.  Issue            80387 Behavior                  8087/80287 Behavior
  8249.  
  8250.  C.1  INITIALIZATION SEQUENCE
  8251.  
  8252.  RESET,           After a hardware RESET,         No difference between
  8253.  FINIT,           the ERROR# output is            RESET and FINIT.
  8254.  and              asserted to indicate that an
  8255.                  ┌────────────────────Difference Description──────────────────
  8256.  Issue            80387 Behavior                  8087/80287 Behavior
  8257. and              asserted to indicate that an
  8258.  ERROR#           80387 is present. To
  8259.  PIN              accomplish this, the IE and
  8260.                   ES bits of the status word
  8261.                   are set, and the IM bit in
  8262.                   the control word is reset.
  8263.                   After FINIT, the status
  8264.                   word and the control word
  8265.                   have the same values as in
  8266.                   an 80287/8087 after
  8267.                   RESET.
  8268.  
  8269.  C.2  DATA TYPES AND EXCEPTION HANDLING
  8270.  
  8271.  NaN              The 80387 distinguishes         The 80287/8087 only
  8272.                   between signaling NaNs          generates one kind of NaN
  8273.                   and quiet NaNs. The 80387       (the equivalent of a quiet
  8274.                   only generates quiet NaNs.      NaN) but raises an
  8275.                   An invalid-operation            invalid-operation exception
  8276.                  ┌────────────────────Difference Description──────────────────
  8277.  Issue            80387 Behavior                  8087/80287 Behavior
  8278.                  An invalid-operation            invalid-operation exception
  8279.                   exception is raised only        upon encountering any kind
  8280.                   upon encountering a             of NaN.
  8281.                   signaling NaN (except for
  8282.                   FCOM, FIST, and FBSTP
  8283.                   which also raise IE for
  8284.                   quiet NaNs).
  8285.  
  8286.  Pseudozero,      The 80387 neither               The 80287/8087 defines
  8287.  Pseudo-NaN,      generates not supports these    and supports special
  8288.  Pseudoinfinity,  formats; it raises an           handling for these formats.
  8289.  and Unnormal     invalid-operation exception
  8290.  Formats          whenever it encounters
  8291.                   them in an arithmetic
  8292.                   operation.
  8293.  
  8294.  Tag Word         The encoding in the tag         The encoding for pseudo-
  8295.  Bits for         word for the unsupported        zero and unnormal is
  8296.  Unsupported      data formats mentioned in       "valid" (type 00); the
  8297.                  ┌────────────────────Difference Description──────────────────
  8298.  Issue            80387 Behavior                  8087/80287 Behavior
  8299. Unsupported      data formats mentioned in       "valid" (type 00); the
  8300.  Data             Section C.2.2 is "special       others are"special data"
  8301.  Formats          data" (type 10).                (type 10).
  8302.  
  8303.  Invalid-         No invalid-operation            Upon encountering a
  8304.  Operation        exception is raised upon        denormal in FSQRT, FDIV,
  8305.  Exception        encountering a denormal in      or FPREM or upon
  8306.                   FSQRT, FDIV, or FPREM           conversion to BCD or to
  8307.                   or upon conversion to           integer, the invalid-
  8308.                   BCD or to integer. The          operation exception is
  8309.                   operation proceeds by first     raised.
  8310.                   normalizing the value.
  8311.  
  8312.  Denormal         The denormal exception is       The denormal exception is
  8313.  Exception        raised in transcendental        not raised in transcendental
  8314.                   instructions and FXTRACT.       instructions and FXTRACT.
  8315.  
  8316.  
  8317.  Overflow         Overflow exception              Overflow exception
  8318.                  ┌────────────────────Difference Description──────────────────
  8319.  Issue            80387 Behavior                  8087/80287 Behavior
  8320. Overflow         Overflow exception              Overflow exception
  8321.  Exception        masked.                         masked.
  8322.                   If the rounding mode is set     The 80287/8087 does not
  8323.                   to chop (toward zero), the      signal the overflow
  8324.                   result is the most positive     exception when the masked
  8325.                   or most negative number.        response is not infinity;
  8326.                                                   i.e., it signals overflow
  8327.                                                   only when the rounding
  8328.                                                   control is not set to round
  8329.                                                   to zero .If rounding is set
  8330.                                                   to chop (toward zero), the
  8331.                                                   result is positive or
  8332.                                                   negative infinity.
  8333.  
  8334.                   Overflow exception not          Overflow exception not
  8335.                   masked.                         masked.
  8336.                   The precision exception is      The precision exception is
  8337.                   flagged. When the result is     not flagged and the
  8338.                   stored in the stack, the        significand is not rounded.
  8339.                  ┌────────────────────Difference Description──────────────────
  8340.  Issue            80387 Behavior                  8087/80287 Behavior
  8341.                  stored in the stack, the        significand is not rounded.
  8342.                   significand is rounded
  8343.                   according to the precision
  8344.                   control (PC) bit of the
  8345.                   control word of according
  8346.                   to the opcode.
  8347.  
  8348.  Underflow        Conditions for underflow.       Conditions for underflow.
  8349.  Exception        When the underflow              When the underflow
  8350.                   exception is masked, the        exception is masked and
  8351.  Two related      underflow exception is          rounding is toward zero, the
  8352.  events           signaled when both the          underflow exception flag is
  8353.  contribute to    result is tiny and              raised on tininess,
  8354.  underflow:       denormalization results         regardless of loss of
  8355.                   in a loss of accuracy.          accuracy.
  8356.  1. The creation
  8357.     tiny result.  Response to underflow.          Response to underflow.
  8358.     A tiny        When the underflow              When the underflow
  8359.     number,       exception is unmasked           exception is not masked and
  8360.                  ┌────────────────────Difference Description──────────────────
  8361.  Issue            80387 Behavior                  8087/80287 Behavior
  8362.    number,       exception is unmasked           exception is not masked and
  8363.     because it    and the instruction is          the destination is the
  8364.     is so small,  supposed to store the           stack, the significand is
  8365.     may cause     result on the stack, the        not rounded but rather is
  8366.     some other    significand is rounded to       left as is.
  8367.     exception     the appropriate precision
  8368.     later (such   (according to the precision
  8369.     as overflow   control (PC) bit of the
  8370.     upon          control word, for those
  8371.     division).    instructions controlled by
  8372.                   PC, otherwise to extended
  8373.   2. Loss of      precision).
  8374.     accuracy
  8375.     during the
  8376.     denormaliza-
  8377.     tion of a
  8378.     tiny number.
  8379.     Which of
  8380.     these events
  8381.                  ┌────────────────────Difference Description──────────────────
  8382.  Issue            80387 Behavior                  8087/80287 Behavior
  8383.    these events
  8384.     triggers the
  8385.     underflow
  8386.     exception
  8387.     depends on
  8388.     whether the
  8389.     underflow
  8390.     exception
  8391.     is masked.
  8392.  
  8393.  Which of these
  8394.  events triggers
  8395.  the underflow
  8396.  exception
  8397.  depends on
  8398.  whether the
  8399.  underflow
  8400.  exception is
  8401.  masked.
  8402.                  ┌────────────────────Difference Description──────────────────
  8403.  Issue            80387 Behavior                  8087/80287 Behavior
  8404. masked.
  8405.  
  8406.  Exception       There is no difference in       When the denormal
  8407.  Precedence      the precedence of the           exception is not masked,
  8408.                  denormal exception,             it takes precedence over
  8409.                  whether it be masked or         all other exceptions.
  8410.                  not.
  8411.  
  8412.  C.3  TAG, STATUS, AND CONTROL WORDS
  8413.  
  8414.  Bits C3-C0 of   After FINIT, incomplete         After FINIT, incomplete
  8415.  Status Word     FPREM, and hardware             FPREM, and hardware
  8416.                  reset, the 80387 sets these     reset, the 80287/8087
  8417.                  bits to zero.                   leaves these bits intact
  8418.                                                  (they contain the prior
  8419.                                                  value).
  8420.  
  8421.  Bit C2 of       Bit 10 (C2) serves as an        This bit is undefined for
  8422.  Status Word     incomplete bit for FPTAN.       FPTAN.
  8423.                  ┌────────────────────Difference Description──────────────────
  8424.  Issue            80387 Behavior                  8087/80287 Behavior
  8425. Status Word     incomplete bit for FPTAN.       FPTAN.
  8426.  
  8427.  
  8428.  Infinity        Only affine closure is          Both affine and projective
  8429.  Control         supported. Bit 12 remains       closures are supported.
  8430.                  programmable but has no         After RESET, the default
  8431.                  effect on 80387 operation.      value in the control word is
  8432.                                                  projective.
  8433.  
  8434.  Status Word     When an invalid-operation       When an invalid-operation
  8435.  Bit 6 for       exception occurs due to         exception occurs due to
  8436.  Stack Fault     stack overflow or               stack overflow or underflow,
  8437.                  underflow, not only is bit 0    only bit 0 (IE) of the
  8438.                  (IE) the status word set, but   status word is set. Bit 6 is
  8439.                  also bit 6 is set to indicate   RESERVED.
  8440.                  a stack fault and bit 9 (C1)
  8441.                  specifies overflow or
  8442.                  underflow. Bit 6 is called
  8443.                  SF and serves to distinguish
  8444.                  ┌────────────────────Difference Description──────────────────
  8445.  Issue            80387 Behavior                  8087/80287 Behavior
  8446.                 SF and serves to distinguish
  8447.                  invalid exceptions caused by
  8448.                  stack overflow/underflow from
  8449.                  those caused by numeric
  8450.                  operations.
  8451.  
  8452.  Tag Word        When loading the tag word       The corresponding tag is
  8453.                  with an FLDENV or               checked before each
  8454.                  FRSTOR instruction, the         register access to determine
  8455.                  only interpretations of tag     the class of operand in the
  8456.                  values used by the 80387        register; the tag is updated
  8457.                  are empty (value 11) and        after every change to a
  8458.                  Nonempty (values 00, 01,        register so that the tag
  8459.                  and 10). Subsequent             always reflects the most
  8460.                  operations on a nonempty        recent status of the
  8461.                  register always examine         register. Programmers can
  8462.                  the value in the register,      load a tag with a value that
  8463.                  not the value in its tag.       disagrees with the contents
  8464.                  The FSTENV and FSAVE            of a register (for example,
  8465.                  ┌────────────────────Difference Description──────────────────
  8466.  Issue            80387 Behavior                  8087/80287 Behavior
  8467.                 The FSTENV and FSAVE            of a register (for example,
  8468.                  instructions examine the        the register contains valid
  8469.                  nonempty registers and          contents, but the tag says
  8470.                  put the correct values in       special; the 80287/8087, in
  8471.                  the tags before storing the     this case, honors the tag
  8472.                  tag word.                       and does not examine the
  8473.                                                  register).
  8474.  
  8475.  C.4  INSTRUCTION SET
  8476.  
  8477.  FBSTP, FDIV,    Operation on denormal           Operation on denormal
  8478.  FIST(P), FPREM, operand is supported. An        operand raises
  8479.  FSQRT           underflow exception can         invalid-operation exception.
  8480.                  occur.                          Underflow is not possible.
  8481.  
  8482.  
  8483.  
  8484.  
  8485.  FSCALE          The range of the scaling        The range of the scaling
  8486.                  ┌────────────────────Difference Description──────────────────
  8487.  Issue            80387 Behavior                  8087/80287 Behavior
  8488. FSCALE          The range of the scaling        The range of the scaling
  8489.                  operand is not restricted.      operand is retricted. If 0 <
  8490.                  If 0 < │ST(1)│ < 1, the         │ST(1)│ < 1, the result is
  8491.                  scaling factor is zero;         undefined and no exception
  8492.                  therefore, ST(0) remains        is signaled.
  8493.                  unchanged. If the rounded
  8494.                  result is not exact or if
  8495.                  there was a loss of
  8496.                  accuracy (masked underflow),
  8497.                  the precision exception
  8498.                  is signaled.
  8499.  
  8500.  FPREM1          Performs partial remainder      Does not exist.
  8501.                  according to IEEE
  8502.                  Standard 754 standard.
  8503.  
  8504.  FPREM           Bits C0, C3, C1 of the          The quotient bits are
  8505.                  status word, correctly          incorrect when performing a
  8506.                  reflect the three low-order     reduction of 64^(N) + M when
  8507.                  ┌────────────────────Difference Description──────────────────
  8508.  Issue            80387 Behavior                  8087/80287 Behavior
  8509.                 reflect the three low-order     reduction of 64^(N) + M when
  8510.                  bits of the quotient.           N ≥ 1 and M=1 or M=2.
  8511.  
  8512.  
  8513.  FUCOM, FUCOMP,  Perform unordered               Do not exist.
  8514.  FUCOMPP         compare according to
  8515.                  IEEE Standard 754
  8516.                  standard.
  8517.  
  8518.  FPTAN           Range of operand is much        Range of operand is
  8519.                  less restricted (│ST(0)│ <      restricted (│ST(0)│ < π/4);
  8520.                  2^(63)); reduces operand        operand must be reduced
  8521.                  internally using an internal    to range using FPREM.
  8522.                  π/4 constant that is more
  8523.                  accurate.
  8524.  
  8525.                  After a stack overflow          After a stack overflow
  8526.                  when the invalid-operation      when the invalid-operation
  8527.                  exception is masked, both       exception is masked, the
  8528.                  ┌────────────────────Difference Description──────────────────
  8529.  Issue            80387 Behavior                  8087/80287 Behavior
  8530.                 exception is masked, both       exception is masked, the
  8531.                  ST and ST(1) contain quiet      original operand remains
  8532.                  NaNs.                           unchanged, but is pushed
  8533.                                                  to ST(1).
  8534.  
  8535.  FSIN, FCOS,     Perform three common            Do not exist.
  8536.  FSINCOS         trigonometric functions.
  8537.  
  8538.  FPATAN          Range of operands is            │ST(0)│ must be smaller
  8539.                  unrestricted.                   than │ST(1)│.
  8540.  
  8541.  F2XM1           Wider range of operand          The supported operand
  8542.                  (-1 ≤ ST(0) ≤ +1).              range is 0 ≤ ST(0) ≤ 0.5.
  8543.  
  8544.  FLD             Does not report denormal        Reports denormal exception.
  8545.  extended-real   exception because the
  8546.                  instruction is not arithmetic.
  8547.  
  8548.  FXTRACT         If the operand is zero, the     If the operand is zero,
  8549.                  ┌────────────────────Difference Description──────────────────
  8550.  Issue            80387 Behavior                  8087/80287 Behavior
  8551. FXTRACT         If the operand is zero, the     If the operand is zero,
  8552.                  zero-divide exception is        ST(1) is zero and no
  8553.                  reported and ST(1) is -∞.       exception is reported. If
  8554.                  If the operand is +∞, no        the operand is +∞, the
  8555.                  exception is reported.          invalid-operation exception
  8556.                                                  is reported.
  8557.  
  8558.  FLD constant    Rounding control is in          Rounding control is not in
  8559.                  effect.                         effect.
  8560.  
  8561.  
  8562.  
  8563.  
  8564.  
  8565.  
  8566.  
  8567.  
  8568.  
  8569.  
  8570.                  ┌────────────────────Difference Description──────────────────
  8571.  Issue            80387 Behavior                  8087/80287 Behavior
  8572. 
  8573.  
  8574.  
  8575.  FLD             Loading a denormal              Loading a denormal causes
  8576.  single/double   causes the number to be         the number to be converted
  8577.  precision       converted to extended           to an unnormal.
  8578.                  precision (because it is put
  8579.                  on the stack).
  8580.  
  8581.  FLD             When loading a signaling        Does not raise an
  8582.  single/double   NaN, raises invalid exception.  exception when loading a
  8583.  precision                                       signaling NaN.
  8584.  
  8585.  FSETPM          Treated as FNOP (no             Informs the 80287 that the
  8586.                  operation).                     system is in protected
  8587.                                                  mode.
  8588.  
  8589.  
  8590.  
  8591.                  ┌────────────────────Difference Description──────────────────
  8592.  Issue            80387 Behavior                  8087/80287 Behavior
  8593. 
  8594.  FXAM            When encountering an            May generate these
  8595.                  empty register, the 80387       combinations, among others.
  8596.                  will not generate
  8597.                  combinations of C3-C0 equal to
  8598.                  1101 or 1111.
  8599.  
  8600.  All             May generate different          Round-up bit of status
  8601.  Transcendental  results in round-up bit of      word is undefined for these
  8602.  Instructions    status word.                    instructions.
  8603.  
  8604.  
  8605.  Appendix D  Compatibility Between the 80387 and the 8087
  8606.  
  8607.  ───────────────────────────────────────────────────────────────────────────
  8608.  
  8609.  The 80386/80387 operating in real-address mode will execute 8087 programs
  8610.  without major modification. However, because of differences in the handling
  8611.  of numeric exceptions between the 80387 NPX and the 8087 NPX,
  8612.  exception-handling routines may need to be changed.
  8613.  
  8614.  This appendix summarizes the additional differences between the 80387 NPX
  8615.  and the 8087 NPX (other than those already included in Appendix B), and
  8616.  provides details showing how 8087 programs can be ported to the 80387.
  8617.  
  8618.    1.  The 80387 signals exceptions through a dedicated ERROR# line to
  8619.        the 80386; no interrupt controller is needed for this purpose. The
  8620.        8087 requires an interrupt controller (8259A) to interrupt the CPU
  8621.        when an unmasked exception occurs. Therefore, any
  8622.        interrupt-controller-oriented instructions in numeric exception
  8623.        handlers for the 8087 should be deleted.
  8624.  
  8625.    2.  The 8087 instructions FENI/FNENI and FDISI/FNDISI perform no useful
  8626.        function in the 80387. If the 80387 encounters one of these opcodes in
  8627.        its instruction stream, the instruction will effectively be
  8628.        ignored──none of the 80387 internal states will be updated. While 8087
  8629.        code containing these instructions may be executed on the 80387, it
  8630.        is unlikely that the exception-handling routines containing these
  8631.        instructions will be completely portable to the 80387.
  8632.  
  8633.    3.  In real mode and protected mode (not including virtual 8086 mode),
  8634.        interrupt vector 16 must point to the numeric exception handling
  8635.        routine. In virtual 8086 mode, the V86 monitor can be programmed to
  8636.        accommodate a different location of the interrupt vector for numeric
  8637.        exceptions.
  8638.  
  8639.    4.  The ESC instruction address saved in the 80386/80387 or 80386/80287
  8640.        includes any leading prefixes before the ESC opcode. The corresponding
  8641.        address saved in the 8086/8087 does not include leading prefixes.
  8642.  
  8643.    5.  In protected mode (not including virtual 8086 mode), the format of
  8644.        the 80387's saved instruction and address pointers is different than
  8645.        for the 8087. The instruction opcode is not saved in protected
  8646.        mode──exception handlers will have to retrieve the opcode from memory
  8647.        if needed.
  8648.  
  8649.    6.  Interrupt 7 will occur in the 80386 when executing ESC instructions
  8650.        with either TS (task switched) or EM (emulation) of the 80386 MSW set
  8651.        (TS=1 or EM=1). If TS is set, then a WAIT instruction will also cause
  8652.        interrupt 7. An exception handler should be included in 80387 code to
  8653.        handle these situations.
  8654.  
  8655.    7.  Interrupt 9 will occur if the second or subsequent words of a
  8656.        floating-point operand fall outside a segment's size. Interrupt 13
  8657.        will occur if the starting address of a numeric operand falls outside
  8658.        a segment's size. An exception handler should be included to report
  8659.        these programming errors.
  8660.  
  8661.    8.  Except for the processor control instructions, all of the 80387
  8662.        numeric instructions are automatically synchronized by the 80386
  8663.        CPU──the 80386 automatically waits until all operands have been
  8664.        transferred between the 80386 and the 80387 before executing the
  8665.        next ESC instruction. No explicit WAIT instructions are required to
  8666.        assure this synchronization. For the 8087 used with 8086 and 8088
  8667.        processors, explicit WAITs are required before each numeric
  8668.        instruction to ensure synchronization. Although 8087 programs having
  8669.        explicit WAIT instructions will execute perfectly on the 80387
  8670.        without reassembly, these WAIT instructions are unnecessary.
  8671.  
  8672.    9.  Since the 80387 does not require WAIT instructions before each
  8673.        numeric instruction, the ASM386 assembler does not automatically
  8674.        generate these WAIT instructions. The ASM86 assembler, however,
  8675.        automatically precedes every ESC instruction with a WAIT
  8676.        instruction. Although numeric routines generated using the ASM86
  8677.        assembler will generally execute correctly on the 80386/20,
  8678.        reassembly using ASM386 may result in a more compact code image and
  8679.        faster execution.
  8680.  
  8681.        The processor control instructions for the 80387 may be coded using
  8682.        either a WAIT or No-WAIT form of mnemonic. The WAIT forms of these
  8683.        instructions cause ASM386 to precede the ESC instruction with a CPU
  8684.        WAIT instruction, in the identical manner as does ASM86.
  8685.  
  8686.    10. The address of a memory operand stored by FSAVE or FSTENV is
  8687.        undefined if the previous ESC instruction did not refer to memory.
  8688.  
  8689.    11. Because the 80387 automatically normalizes denormal numbers when
  8690.        possible, an 8087 program that uses the denormal exception solely to
  8691.        normalize denormal operands can run on an 80387 by masking the
  8692.        denormal exception. The 8087 denormal exception handler would not be
  8693.        used by the 80387 in this case. A numerics program runs faster when
  8694.        the 80387 performs normalization of denormal operands. A program can
  8695.        detect at run-time whether it is running on an 80387 or 8087/80287 and
  8696.        disable the denormal exception when an 80387 is used.
  8697.  
  8698.  
  8699.  Appendix E  80387 80-Bit CHMOS III Numeric Processor Extension
  8700.  
  8701.  For Advance Information on the Intel 80387 please consult Appendix E of the
  8702.  printed version of this book or the 80387 Data Sheet, order number 231920.
  8703.  
  8704.  
  8705.  Appendix F  PC/AT-Compatible 80387 Connection
  8706.  
  8707.  ───────────────────────────────────────────────────────────────────────────
  8708.  
  8709.  The PC/AT uses a nonstandard scheme to report 80287 exceptions to the
  8710.  80286. When replicating the PC/AT coprocessor interface in 80386-based
  8711.  systems, the PC/AT interface cannot be used in exactly the same way;
  8712.  however, this appendix outlines a similar interface that works on
  8713.  80386/80387 systems and maintains compatibility with the nonstandard PC/AT
  8714.  scheme.
  8715.  
  8716.  Note that the interface outlined here does not represent a new interface
  8717.  standard; it needs to be incorporated in AT-compatible designs only because
  8718.  the 80286 and 80287 in the PC/AT are not connected according to the
  8719.  standards defined by Intel. The standard 80386/80387 connection recommended
  8720.  by Intel in the 80387 Data Sheet functions properly; the 80386
  8721.  implementation has not been and will not be altered.
  8722.  
  8723.  
  8724.  F.1  The PC/AT Interface
  8725.  
  8726.  In the PC/AT, the ERROR# input to the 80286 is tied inactive (high)
  8727.  permanently. The ERROR# output of the 80287 is tied to an interrupt port
  8728.  (IRQ13). This interrupt replaces exception signaling via the 80286's ERROR#
  8729.  input. To guarantee (in the case of an 80287 exception) that INTR 13 will be
  8730.  serviced prior to the execution of any further 80287 instructions, an
  8731.  edge-triggered flip-flop latches BUSY# using ERROR# as a clock. The output
  8732.  of this latch is ORed with the BUSY# output of the 80287 and drives the
  8733.  BUSY# input of the 80286. This PC/AT scheme effectively delays deactivation
  8734.  of BUSY# at the 80286 whenever an 80287 ERROR# is signaled.
  8735.  
  8736.  Since the 80286 BUSY# input remains active after an exception, the 80286
  8737.  interrupt 13 handler is guaranteed to execute before any other 80287
  8738.  instructions may begin. The interrupt 13 handler clears the BUSY# latch (via
  8739.  a write to a special I/O port), thus allowing execution of 80287
  8740.  instructions to proceed. The interrupt 13 handler then branches to the NMI
  8741.  handler, where the user-defined numerics exception handler resides in
  8742.  PC-compatible systems.
  8743.  
  8744.  The use of an interrupt guarantees that an exception from a coprocessor
  8745.  instruction will be detected. Latching BUSY# guarantees that any coprocessor
  8746.  instruction (except FINIT, FSETPM, and FCLEX) following the instruction that
  8747.  raised the exception will not be executed before the NMI handler is
  8748.  executed.
  8749.  
  8750.  This PC/AT scheme approximates the exception reporting scheme between the
  8751.  8087 and 8088 in the original PC.
  8752.  
  8753.  
  8754.  F.2  How to Achieve the Same Effect in an 80386 System
  8755.  
  8756.  The 80386 can use a PC/AT-compatible interface to communicate with an 80387
  8757.  provided that, when an NPX exception occurs, BUSY# active time is extended
  8758.  and PEREQ is reactivated only after 80387 BUSY# has gone inactive. The 80387
  8759.  is left active (tying STEN high) at all times. Also, the 80386 and 80387
  8760.  must be reset by the same RESET signal.
  8761.  
  8762.  The reactivation of PEREQ for the 80386 is needed for store instructions
  8763.  (for example, FST mem) because the 80387 drops PEREQ once it signals an
  8764.  exception. While the 80386 has not yet recognized the occurrence of the
  8765.  exception, it still expects the data transfers to complete via PEREQ
  8766.  reactivation. It is permissible for the 80386 to receive undefined data
  8767.  during such I/O read cycles. Disabling the 80387 is not necessary, because
  8768.  the dummy data-transfer cycles directed to the 80387 when PEREQ is
  8769.  externally reactivated for the 80386 will not disturb the operation of the
  8770.  80387. The interrupt 13 handler should remove the extension of BUSY# and
  8771.  reactivation of PEREQ via a write to PC/AT-compatible hardware at I/O port
  8772.  F0H.
  8773.  
  8774.  
  8775.  Glossary of 80387 and Floating-Point Terminology
  8776.  
  8777.  ───────────────────────────────────────────────────────────────────────────
  8778.  
  8779.  This glossary defines many terms that have precise technical meanings as
  8780.  specified in the IEEE 754 Standard or as specified in this manual. Where
  8781.  these terms are used, they have been italicized to emphasize the precision
  8782.  of their meanings.
  8783.  
  8784.  Base
  8785.    (1) a term used in logarithms and exponentials. In both contexts, it is a
  8786.    number that is being raised to a power. The two equations (y = log base b
  8787.    of x) and (b^(y) = x) are the same.
  8788.  
  8789.  Base
  8790.    (2) a number that defines the representation being used for a string of
  8791.    digits. Base 2 is the binary representation; base 10 is the decimal
  8792.    representation; base 16 is the hexadecimal representation. In each case,
  8793.    the base is the factor of increased significance for each succeeding
  8794.    digit (working up from the bottom).
  8795.  
  8796.  Bias
  8797.    a constant that is added to the true exponent of a real number to obtain
  8798.    the exponent field of that number's floating-point representation in the
  8799.    80387. To obtain the true exponent, you must subtract the bias from the
  8800.    given exponent. For example, the single real format has a bias of 127
  8801.    whenever the given exponent is nonzero. If the 8-bit exponent field
  8802.    contains 10000011, which is 131, the true exponent is 131-127, or +4.
  8803.  
  8804.  Biased Exponent
  8805.    the exponent as it appears in a floating-point representation of a number.
  8806.    The biased exponent is interpreted as an unsigned, positive number. In the
  8807.    above example, 131 is the biased exponent.
  8808.  
  8809.  Binary Coded Decimal
  8810.    a method of storing numbers that retains a base 10 representation. Each
  8811.    decimal digit occupies 4 full bits (one hexadecimal digit). The
  8812.    hexadecimal values A through F (1010 through 1111) are not used. The
  8813.    80387 supports a packed decimal format that consists of 9 bytes of binary
  8814.    coded decimal (18 decimal digits) and one sign byte.
  8815.  
  8816.  Binary Point
  8817.    an entity just like a decimal point, except that it exists in binary
  8818.    numbers. Each binary digit to the right of the binary point is multiplied
  8819.    by an increasing negative power of two.
  8820.  
  8821.  C3──C0
  8822.    the four "condition code" bits of the 80387 status word. These bits are
  8823.    set to certain values by the compare, test, examine, and remainder
  8824.    functions of the 80387.
  8825.  
  8826.  Characteristic
  8827.    a term used for some non-Intel computers, meaning the exponent field of a
  8828.    floating-point number.
  8829.  
  8830.  Chop
  8831.    to set one or more low-order bits of a real number to zero, yielding the
  8832.    nearest representable number in the direction of zero.
  8833.  
  8834.  Condition Code
  8835.    the four bits of the 80387 status word that indicate the results of the
  8836.    compare, test, examine, and remainder functions of the 80387.
  8837.  
  8838.  Control Word
  8839.    a 16-bit 80387 register that the user can set, to determine the modes of
  8840.    computation the 80387 will use and the exception interrupts that will be
  8841.    enabled.
  8842.  
  8843.  Denormal
  8844.    a special form of floating-point number. On the 80387, a denormal is
  8845.    defined as a number that has a biased exponent of zero. By providing a
  8846.    significand with leading zeros, the range of possible negative
  8847.    exponents can be extended by the number of bits in the significand.
  8848.    Each leading zero is a bit of lost accuracy, so the extended exponent
  8849.    range is obtained by reducing significance.
  8850.  
  8851.  Double Extended
  8852.    the Standard's term for the 80387's extended format, with more exponent
  8853.    and significand bits than the double format and an explicit integer bit
  8854.    in the significand.
  8855.  
  8856.  Double Format
  8857.    a floating-point format supported by the 80387 that consists of a sign, an
  8858.    11-bit biased exponent, an implicit integer bit, and a 52-bit
  8859.    significand──a total of 64 explicit bits.
  8860.  
  8861.  Environment
  8862.    the 14 or 28 (depending on addressing mode) bytes of 80387 registers
  8863.    affected by the FSTENV and FLDENV instructions. It encompasses the entire
  8864.    state of the 80387, except for the 8 registers of the 80387 stack.
  8865.    Included are the control word, status word, tag word, and the instruction,
  8866.    opcode, and operand information provided by interrupts.
  8867.  
  8868.  Exception
  8869.    any of the six conditions (invalid operand, denormal, numeric overflow,
  8870.    numeric underflow, zero-divide, and precision) detected by the 80387 that
  8871.    may be signaled by status flags or by traps.
  8872.  
  8873.  Exception Pointers
  8874.    The data maintained by the 80386 to help exception handlers identify
  8875.    the cause of an exception. This data consists of a pointer to the most
  8876.    recently executed ESC instruction and a pointer to the memory operand of
  8877.    this instruction, if it had a memory operand. An exception handler can use
  8878.    the FSTENV and FSAVE instructions to access these pointers.
  8879.  
  8880.  Exponent
  8881.    (1) any number that indicates the power to which another number is raised.
  8882.  
  8883.  Exponent
  8884.    (2) the field of a floating-point number that indicates the magnitude of
  8885.    the number. This would fall under the above more general definition (1),
  8886.    except that a bias sometimes needs to be subtracted to obtain the correct
  8887.    power.
  8888.  
  8889.  Extended Format
  8890.    the 80387's implementation of the Standard's double extended format.
  8891.    Extended format is the main floating-point format used by the 80387.
  8892.    It consists of a sign, a 15-bit biased exponent, and a significand with an
  8893.    explicit integer bit and 63 fractional-part bits.
  8894.  
  8895.  Floating-Point
  8896.    of or pertaining to a number that is expressed as base, a sign, a
  8897.    significand, and a signed exponent. The value of the number is the signed
  8898.    product of its significand and the base raised to the power of the
  8899.    exponent. Floating-point representations are more versatile than integer
  8900.    representations in two ways. First, they include fractions. Second, their
  8901.    exponent parts allow a much wider range of magnitude than possible with
  8902.    fixed-length integer representations.
  8903.  
  8904.  Gradual Underflow
  8905.    a method of handling the underflow error condition that minimizes the loss
  8906.    of accuracy in the result. If there is a denormal number that represents
  8907.    the correct result, that denormal is returned. Thus, digits are lost only
  8908.    to the extent of denormalization. Most computers return zero when
  8909.    underflow occurs, losing all significant digits.
  8910.  
  8911.  Implicit Integer Bit
  8912.    a part of the significand in the single real and double real formats
  8913.    that is not explicitly given. In these formats, the entire given
  8914.    significand is considered to be to the right of the binary point. A single
  8915.    implicit integer bit to the left of the binary point is always one, except
  8916.    in one case. When the exponent is the minimum (biased exponent is zero),
  8917.    the implicit integer bit is zero.
  8918.  
  8919.  Indefinite
  8920.    a special value that is returned by functions when the inputs are such
  8921.    that no other sensible answer is possible. For each floating-point format
  8922.    there exists one quiet NaN that is designated as the indefinite value. For
  8923.    binary integer formats, the negative number furthest from zero is often
  8924.    considered the indefinite value. For the 80387 packed decimal format, the
  8925.    indefinite value contains all 1's in the sign byte and the uppermost
  8926.    digits byte.
  8927.  
  8928.  Inexact
  8929.    The Standard's term for the 80387's precision exception.
  8930.  
  8931.  Infinity
  8932.    a value that has greater magnitude than any integer or any real number. It
  8933.    is often useful to consider infinity as another number, subject to special
  8934.    rules of arithmetic. All three Intel floating-point formats provide
  8935.    representations for +∞ and -∞.
  8936.  
  8937.  Integer
  8938.    a number (positive, negative, or zero) that is finite and has no
  8939.    fractional part. Integer can also mean the computer representation for
  8940.    such a number: a sequence of data bytes, interpreted in a standard way. It
  8941.    is perfectly reasonable for integers to be represented in a floating-point
  8942.    format; this is what the 80387 does whenever an integer is pushed onto the
  8943.    80387 stack.
  8944.  
  8945.  Integer Bit
  8946.    a part of the significand in floating-point formats. In these formats, the
  8947.    integer bit is the only part of the significand considered to be to the
  8948.    left of the binary point. The integer bit is always one, except in one
  8949.    case: when the exponent is the minimum (biased exponent is zero), the
  8950.    integer bit is zero. In the extended format the integer bit is explicit;
  8951.    in the single format and double format the integer bit is implicit; i.e.,
  8952.    it is not actually stored in memory.
  8953.  
  8954.  Invalid Operation
  8955.    the exception condition for the 80387 that covers all cases not covered by
  8956.    other exceptions. Included are 80387 stack overflow and underflow, NaN
  8957.    inputs, illegal infinite inputs, out-of-range inputs, and inputs in
  8958.    unsupported formats.
  8959.  
  8960.  Long Integer
  8961.    an integer format supported by the 80387 that consists of a 64-bit two's
  8962.    complement quantity.
  8963.  
  8964.  Long Real
  8965.    an older term for the 80387's 64-bit double format.
  8966.  
  8967.  Mantissa
  8968.    a term used with some non-Intel computers for the significand of a
  8969.    floating-point number.
  8970.  
  8971.  Masked
  8972.    a term that applies to each of the six 80387 exceptions I,D,Z,O,U,P. An
  8973.    exception is masked if a corresponding bit in the 80387 control word is
  8974.    set to one. If an exception is masked, the 80387 will not generate an
  8975.    interrupt when the exception condition occurs; it will instead provide its
  8976.    own exception recovery.
  8977.  
  8978.  Mode
  8979.    One of the status word fields "rounding control" and "precision control"
  8980.    which programs can set, sense, save, and restore to control the execution
  8981.    of subsequent arithmetic operations.
  8982.  
  8983.  NaN
  8984.    an abbreviation for "Not a Number"; a floating-point quantity that does
  8985.    not represent any numeric or infinite quantity. NaNs should be returned
  8986.    by functions that encounter serious errors. If created during a sequence
  8987.    of calculations, they are transmitted to the final answer and can contain
  8988.    information about where the error occurred.
  8989.  
  8990.  Normal
  8991.    the representation of a number in a floating-point format in which the
  8992.    significand has an integer bit one (either explicit or implicit).
  8993.  
  8994.  Normalize
  8995.    convert a denormal representation of a number to a normal representation.
  8996.  
  8997.  NPX
  8998.    Numeric Processor Extension. This is the 80387, 80287, or 8087.
  8999.  
  9000.  Overflow
  9001.    an exception condition in which the correct answer is finite, but has
  9002.    magnitude too great to be represented in the destination format. This kind
  9003.    of overflow (also called numeric overflow) is not to be confused with
  9004.    stack overflow.
  9005.  
  9006.  Packed Decimal
  9007.    an integer format supported by the 80387. A packed decimal number is a
  9008.    10-byte quantity, with nine bytes of 18 binary coded decimal digits and
  9009.    one byte for the sign.
  9010.  
  9011.  Pop
  9012.    to remove from a stack the last item that was placed on the stack.
  9013.  
  9014.  Precision
  9015.    The effective number of bits in the significand of the floating-point
  9016.    representation of a number.
  9017.  
  9018.  Precision Control
  9019.    an option, programmed through the 80387 control word, that allows all
  9020.    80387 arithmetic to be performed with reduced precision. Because no
  9021.    speed advantage results from this option, its only use is for strict
  9022.    compatibility with the standard and with other computer systems.
  9023.  
  9024.  Precision Exception
  9025.    an 80387 exception condition that results when a calculation does not
  9026.    return an exact answer. This exception is usually masked and ignored; it
  9027.    is used only in extremely critical applications, when the user must know
  9028.    if the results are exact. The precision exception is called inexact
  9029.    in the standard.
  9030.  
  9031.  Pseudozero
  9032.    one of a set of special values of the extended real format. The set
  9033.    consists of numbers with a zero significand and an exponent that is
  9034.    neither all zeros nor all ones. Pseudozeros are not created by the 80387
  9035.    but are handled correctly when encountered as operands.
  9036.  
  9037.  Quiet NaN
  9038.    a NaN in which the most significant bit of the fractional part of the
  9039.    significand is one. By convention, these NaNs can undergo certain
  9040.    operations without causing anexception.
  9041.  
  9042.  Real
  9043.    any finite value (negative, positive, or zero) that can be represented by
  9044.    a (possibly infinite) decimal expansion. Reals can be represented as the
  9045.    points of a line marked off like a ruler. The term real can also refer
  9046.    to a floating-point number that represents a real value.
  9047.  
  9048.  Short Integer
  9049.    an integer format supported by the 80387 that consists of a 32-bit two's
  9050.    complement quantity. short integer is not the shortest 80387 integer
  9051.    format──the 16-bit word integer is.
  9052.  
  9053.  Short Real
  9054.    an older term for the 80387's 32-bit single format.
  9055.  
  9056.  Signaling NaN
  9057.    a NaN that causes an invalid-operation exception whenever it enters into
  9058.    a calculation or comparison, even a nonordered comparison.
  9059.  
  9060.  Significand
  9061.    the part of a floating-point number that consists of the most significant
  9062.    nonzero bits of the number, if the number were written out in an unlimited
  9063.    binary format. The significand is composed of an integer bit and a
  9064.    fraction. The integer bit is implicit in the single format and double
  9065.    format. The significand is considered to have a binary point after the
  9066.    integer bit; the binary point is then moved according to the value of the
  9067.    exponent.
  9068.  
  9069.  Single Extended
  9070.    a floating-point format, required by the standard, that provides greater
  9071.    precision than single; it also provides an explicit integer bit in the
  9072.    significand. The 80387's extended format meets the single extended
  9073.    requirement as well as the double extended requirement.
  9074.  
  9075.  Single Format
  9076.    a floating-point format supported by the 80387, which consists of a sign,
  9077.    an 8-bit biased exponent, an implicit integer bit, and a 23-bit
  9078.    significand──a total of 32 explicit bits.
  9079.  
  9080.  Stack Fault
  9081.    a special case of the invalid-operation exception which is indicated by a
  9082.    one in the SF bit of the status word. This condition usually results from
  9083.    stack underflow or overflow.
  9084.  
  9085.  Standard
  9086.    "IEEE Standard for Binary Floating-Point Arithmetic," ANSI/IEEE
  9087.    Std 754-1985.
  9088.  
  9089.  Status Word
  9090.    A 16-bit 80387 register that can be manually set, but which is usually
  9091.    controlled by side effects to 80387 instructions. It contains condition
  9092.    codes, the 80387 stack pointer, busy and interrupt bits, and exception
  9093.    flags.
  9094.  
  9095.  Tag Word
  9096.    a 16-bit 80387 register that is automatically maintained by the 80387. For
  9097.    each space in the 80387 stack, it tells if the space is occupied by a
  9098.    number; if so, it gives information about what kind of number.
  9099.  
  9100.  Temporary Real
  9101.    an older term for the 80387's 80-bit extended format.
  9102.  
  9103.  Tiny
  9104.    of or pertaining to a floating-point number that is so close to zero that
  9105.    its exponent is smaller than smallest exponent that can be represented in
  9106.    the destination format.
  9107.  
  9108.  TOP
  9109.    The three-bit field of the status word that indicates which 80387 register
  9110.    is the current top of stack.
  9111.  
  9112.  Transcendental
  9113.    one of a class of functions for which polynomial formulas are always
  9114.    approximate, never exact for more than isolated values. The 80387 supports
  9115.    trigonometric, exponential, and logarithmic functions; all are
  9116.    transcendental.
  9117.  
  9118.  Two's Complement
  9119.    a method of representing integers. If the uppermost bit is zero, the
  9120.    number is considered positive, with the value given by the rest of the
  9121.    bits. If the uppermost bit is one, the number is negative, with the value
  9122.    obtained by subtracting (2^(bit count)) from all the given bits. For
  9123.    example, the 8-bit number 11111100 is -4, obtained by subtracting 2^(8)
  9124.    from 252.
  9125.  
  9126.  Unbiased Exponent
  9127.    the true value that tells how far and in which direction to move the
  9128.    binary point of the significand of a floating-point number. For example,
  9129.    if a single-format exponent is 131, we subtract the Bias 127 to obtain the
  9130.    unbiased exponent +4. Thus, the real number being represented is the
  9131.    significand with the binary point shifted 4 bits to the right.
  9132.  
  9133.  Underflow
  9134.    an exception condition in which the correct answer is nonzero, but has a
  9135.    magnitude too small to be represented as a normal number in the
  9136.    destination floating-point format. The Standard specifies that an attempt
  9137.    be made to represent the number as a denormal. This denormalization may
  9138.    result in a loss of significant bits from the significand. This kind of
  9139.    underflow (also called numeric overflow) is not to be confused with stack
  9140.    underflow.
  9141.  
  9142.  Unmasked
  9143.    a term that applies to each of the six 80387 exceptions: I,D,Z,O,U,P. An
  9144.    exception is unmasked if a corresponding bit in the 80387 control word is
  9145.    set to zero. If an exception is unmasked, the 80387 will generate an
  9146.    interrupt when the exception condition occurs. You can provide an
  9147.    interrupt routine that customizes your exception recovery.
  9148.  
  9149.  Unnormal
  9150.    a extended real representation in which the explicit integer bit of the
  9151.    significand is zero and the exponent is nonzero. Unnormal values are
  9152.    not supported by the 80387; they cause the invalid-operation exception
  9153.    when encountered as operands.
  9154.  
  9155.  Unsupported Format
  9156.    Any number representation that is not recognized by the 80387. This
  9157.    includes several formats that are recognized by the 8087 and 80287;
  9158.    namely: pseudo-NaN, pseudoinfinity, and unnormal.
  9159.  
  9160.  Word Integer
  9161.    an integer format supported by both the 80386 and the 80387 that consists
  9162.    of a 16-bit two's complement quantity.
  9163.  
  9164.  Zero divide
  9165.    an exception condition in which the inputs are finite, but the correct
  9166.    answer, even with an unlimited exponent, has infinite magnitude.
  9167.