
        Introduction to 1.3 IEEE Double Precision Libraries
        ===================================================

Notes:

   1. This article refers to several files found on other disks:

         Libraries in LIBS directory of Workbench1.3
              mathieeedoubbas.library
              mathieedoubtrans.library

         Linker Libraries in LIB directory of Include.strip
              mathieeedoubbas_lib.lib
              mathieeedoubtrans_lib.lib

         FD files in FD1.3 directory of Extras1.3
              mathieeedoubbas_lib.fd
              mathieeedoubtrans_lib.fd


   2. This article was written for the Beta2 ieee libraries.
      The libraries on Workbench1.3g4 are a later version.

   3. Every task must open these libraries themselves rather
      than sharing library bases to insure the 68881 is properly
      initialized for each task.
      

The basic double precision IEEE library has been rewritten for 1.3
The new library is up to seven times faster than the old one and
averages twice as fast for +,-,*,/.  It more properly handles
degenerate cases like NotANumber, Infinity, and denormalized numbers.
There is a table of approximate speed-ups per function at the end
of this article.

Besides the faster software emulation of floating point, this
library recognizes and uses the 68020/68881* combination and
will use the floating point instructions available. Also, if an
preexisting math resource** is available it will use that as well.
Normally this resource will point to the base of a 68881 designed
as a 16 bit i/o port, but maybe a different device instead.
We also provide the ability to programmatically trap math errors such
as overflow and divide by zero. Your program can now ignore them
or take suitable action without visiting the GURU.

A brand new library has been written for 1.3. It is the IEEE
double precision transcendental library. It supports the same functions
as the transcendental library for the Motorola fast floating point.
This library also identifies and uses the 68020/68881 combination as
well as the math resource. It has a very fast software square root routine.

Why should you use these libraries?

These libraries are highly optimized and provide very fast emulation
of IEEE double functions.

Your code can share the IEEE libraries with other applications.
This saves 16k bytes per user with the transcendental library.

If you need the precision of IEEE double, and wish to have a transparent
improvement in speed when your programs run on machines with math
coprocessors, then you should use these libraries. All the decision
making is done by the library when it is first initialized and it will
use the fastest available resources to do your math. You only need
one program to support a standard Amiga, a 68020/68881 Amiga, or an
external math coprocessor Amiga.

Why wouldn't you use these libraries?

For ultimate speed on a 68020/68881 system, you will want to use
the new instructions available from the 68020/68881 directly in
your code. This, however, prevents your code from running on conventional
68000 powered Amigas. In this case, you may need to supply different
versions of your code, one for each different configuration.

These libraries should be placed in the libs: directory.
The basic library will replace the old library, and the transcendental
library is an addition.

For programmers there are additional files to link with as well as
a new .fd file for the transcendental functions.

* There are several manufactures of 68020/68881 upgrade boards such
  as CSA. Commodore-Amiga has also announced such a product.

** Math Resources have been announced by Microbotics and ASDG.



Hardware Developer information.

To make use of CBM's standard peripheral support for 68881 you
must design your peripheral to autoconfig. Your autoconfig
software must create a resource and add it to the resource list.
The name of this resource is "MathIEEE.resource".
The IEEE library will attempt to open this resource. If it finds it,
it will extract the BaseAddr pointer and copy it into its library
structure. If the BaseAddr pointer is non-null it will use a different
list of routine entry points when the IEEE library is initialized.

After the IEEE library is initialized, the library again checks the
resource for alternate function bits in Flags of the resource. The Basic
library only checks the
DblBasAlt bit, and the transcendental library only checks the
DblTransAlt bit. If they are set, the library routine will call the
function whose address is in the corresponding Init field.
The arguments passed are a6 = sysbase,a1=resource,a2=mathlibrary.

If your device is not a 68881 then you may need to use this.
There are separate bits for different library capabilities in case
your math resource is only able to handle a limited set of functions.
This will let you tie a math processor in that may only provide
add/subtract/multiply/divide. The rest of software  will
use it transparently by calling your alternate routines.

Amiga does not provide for arbitrating a math accelerator in
a multitasking environment. So you must provide some support there
when your device autoconfigs. The only exception is the 68020/68881
combination where support for that has been standard since V1.2
Arbitration usually involves saving and restoring the state of you
hardware device between task switches.

We recommend that you look at the tc_Switch/tc_Launch vectors in
the task data structure. These are called each time control transfers
from one task to another. And remember not to assume that you are
the only process needing to use those vectors.

The resource data structure is as follows:

 STRUCTURE  MathIEEE,LN_SIZE
        UWORD   MathIEEE_Flags
        ULONG   MathIEEE_BaseAddr       ; for standard 68881 support
        ULONG   MathIEEE_DblBasInit     ; something else besides 68881
        ULONG   MathIEEE_DblTransInit   ; something else besides 68881
        ULONG   MathIEEE_SnglBasInit    ; something else besides 68881
        ULONG   MathIEEE_SnglTransInit  ; something else besides 68881
 LABEL  MathIEEE_sizeof

* the MathIEEE resource structure may grow in the future. Extensions
* will be added only as Amiga may define new capabilities. Such
* as 80 bit extended format.

*       bits for MathIEEE_flags
*       all unassigned bits must be 0
        BITDEF  MathIEEE,DblBasAlt,0            ; alternate Basic library
        BITDEF  MathIEEE,DblTransAlt,1          ; alternate Trans library
        BITDEF  MathIEEE,SnglBasAlt,2           ; alternate Basic library
        BITDEF  MathIEEE,SnglTransAlt,3         ; alternate Trans library

*       The 'Init' entries are only used if the corresponding
*       Bit is set in the Flags field
*       So if you are just a 68881, you do not need the Init stuff
*       just make sure you have cleared the Flags field
*       This should allow us to add Extended Precision later
*       For Init users, make sure you splice yourself into the
*       Open/Close/Expunge vectors for this library

The library structure that is used is tentatively laid out this way.
I say tentatively because the name of the entries may change yet, but
I will not change their order, usage, or size.
Naturally we  may add stuff to the end.

    STRUCTURE  MI,LIB_SIZE      ; Standard library node
        UBYTE   io8_Flags       ; is this 68881?
        UBYTE   io8_pad         ; line up to next 32bit boundary
        ULONG   io8_68881       ; ptr to io68881 base
        ULONG   io8_SysLib      ; ptr to SysBase
        ULONG   io8_SegList     ; ptr to this SegList
        ULONG   io8_Resource    ; ptr to mathIEEE.resource
        ULONG   io8_opentask    ; called when task opens
        ULONG   io8_closetask   ; called when task closes
    LABEL   MI_SIZE

Of particular interest to hardware developers are the opentask/closetask
entry points. These functions will be called when a task calls
OpenLibrary and CloseLibrary. This will give the vendor the opportunity
to set up any per task initialization necessary. The Amiga library
presently sets them up as NOPs in the case of straight emulation.
It puts the 68881 initialization stuff in there for 68020/68881 as well
as the peripheral 68881. That initialization stuff currently sets up
rounding modes and interrupt requests.
If you need to override the defaults, you will have to set the appropriate
Alt bits in the Resource structure and overwrite the opentask/closetask
fields when your AltInit function is called. The OpenLibrary routine
checks the return value of opentask for errors. If a nonzero is in d0.l
then OpenLibrary will return 0 to the task trying to OpenLibrary.

Table of Approximate Speed Ups from 1.2 to 1.3
--------------------------------------------------
Function          Times faster in 1.3/68000     
==================================================
IEEEDPFlt      2.1
IEEEDPFix      5.01
IEEEDPAbs      1.6
IEEEDPNeg      2.9
IEEEDPTst      2.7
IEEEDPFloor      7.6
IEEEDPCeil      7.2
IEEEDPCmp      2.8
IEEEDPAdd      1.9
IEEEDPSub      1.8
IEEEDPMul      2.1
IEEEDPDiv      2.1

Of course, your mileage may vary.

A 68010 improved results about 5% for multiply and about 9% for divide.


On the 68020/68881 some new exceptions are generated. Unfortunately
the V1.2 os does not properly initialize these. For users of the new
ramkick/A2024 system, the fixes have been added to the exec.library.
For the rest we provide a program to run during your startup sequence
to initialize the vectors and redirect processing back to exec when
the new exceptions occur. This is only necessary on 68020/68881 systems.

