FPU Object
Updated: Sep 24, 2004

With some practice and perhaps the help of a manual on FPU function,
even the beginning programmer can use the FPU object.  In brief, one
loads one or more values and uses methods to modify them.  A statement
as simple as x=FPU.pop retrieves the result.

Developers can implement their formulas by using both the conventional
and FPU object instructions and compare the results as follows:

  DEFREAL10 x1,x2
  x1=y*cos(z) 'conventional coding
  FPU.load y: FPU.load z: FPU.cos: FPU.mul: x2=FPU.pop
' alternatively,
' WITH FPU
' .load y: .load z: .cos: .mul
' END WITH: x2=FPU.pop
  IF x1=x2 THEN PRINT "I coded it right."

Now the x2 calculation may appear to be more cumbersome than the x1.
Sure, but imagine you are multiplying var y times a million numbers.
With the conventional coding for x1, you would be loading var y 999,999
times for nothing.  The x2 steps above illustrate that one can load y
just once and then proceed through your million values of z.

The exclusive HotBasic FPU Object differs from conventional coding in 
several ways.  For operations on two operands (specifically ADD, SUB,
SUBR, MUL, DIV, DIVR, IADD, ISUB, ISUBR, IMUL, IDIV and IDIVR) the 
operand loaded first stays on the FPU.  E.g, if a matrix is to be
multiplied by a constant, that value would have to be loaded just once.

Normally, IDIV and IDIVR can result in floating values; however, the
FPU Object is coded to produce integer results similar to the "\" 
operator in conventional coding.  E.g., i = a \ b  'is integer divide.

Note: "top" refers to ST or ST(0) or last value loaded.


PROPERTIES (Read/Write):
~~~~~~~~~~ ~~~~~~~~~~~~~
CONTROL    Returns or stores FPU control word.  See STATUS examples.

STATE      Saves or restores coprocesser state to/from a 14 byte buffer.

STATUS     Returns FPU status word.  fpustat=FPU.status
           Stores  FPU status word.  FPU.status=fpustat


PROPERTIES (Read Only Numeric):
~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
ERROR      0 = no exception.

  FPU.error returns 7 FPU exception bits which may be examined:
  invalid operation (&H1), denormalized (&H2), divide by zero (&H4),
  overflow (&H8), underflow (&H10), precision reduced (&H20),
  FPU stack fault (&H40).

  i = FPU.error  'assign to non-float to avoid resetting FPU error flags
  IF i OR 28 THEN PRINT "zero divide or overflow or underflow"


Except where specified, METHODS modify the value at "top" of FPU stack:

METHODS    Arguments & Comments
~~~~~~~    ~~~~~~~~~~~~~~~~~~~~
ABS        Absolute value       
ACOS       Arc cosine
ADD        Add
AND        Logical AND
ASIN       Arc sine
ATAN,ATN   Arc tangent where top = x/y
BCDLOAD src Load BCD data from src; src = real10-dimensioned variable.    
BCDPOP dst dst receives BCD data; dst = real10 variable (10 byte buffer).
CHS        Change sign
COPY       Load copy of top value; e.g, .load x: .copy: .mul gives x^2
COS        Cosine
DIV        Divide 
DIVR       Divide reverse operand order
EXAM       Examine top value and set condition codes in STATUS.
EXP        Exponential function; e raised to the power of top
EXCHANGE n Exchange FPU value n by top, n = 1 to 7; default n = 1
EXTRACT    Exponent replaces top; mantissa pushed on to FPU stack.
FLOOR      Round down to negative infinity
FRAC       Fractional part of top replaces top
HCOS       Hyperbolic cosine
HSIN       Hyperbolic sine
HTAN       Hyperbolic tangent
IADD       Integer add (integer result)
IDIV       Integer divide (integer result)
IDIVR      Integer divide reverse operand order (integer result)
IMUL       Integer multiply (integer result)
INIT       Initialize FPU unit
INT        Convert to integer less than or equal to top
ISUB       Integer subtract (integer result)
ISUBR      Integer subtract reverse operand order (integer result)
LOAD scr   Load FPU from scr, any valid numeric data type.
LOADENV scr Load FPU environment from scr (94 byte buffer)
LN         Natural logarithm
LNTWO      Load natural log of 2
LOG        Logarithm base 10
LOG2E      Load logarithm base 2 of e
LOG2TEN    Load logarithm base 2 of 10
LOGTWO     Load logarithm base 10 of 2
MUL        Multiply
NAPIER     Load napier value e
NEG        Change sign; same as CHS
ONE        Load value = 1
OR         Logical OR FPU value 1 and top
PI         Load pi
POP        Retrieve value and "pop" FPU stack. E.g., x=FPU.pop
PREM       Partial remainder
READ       Retrieve value. E.g., x=FPU.read
ROUND      Convert to integer by round method
SAVEENV dst Save FPU environment to dst (94 byte buffer)
SCALE      Scale by power of 2
SGN        Get sign (1,0,-1) of top
SIN        Sine
SINCOS     FPU sincos generation
SQR        Square root
SUB        Subtract
SUBR       Subtract reverse operand order
TAN        Tangent
TEST       Integer compare and pop
XOR        Logical XOR FPU value 1 and top
XEXPY      X ^ Y where X is FPU value 1; Y is top
YL2X       Y * logarithm base 2 of X
YL2XP1     Y * logarithm base 2 of (X+1)
2XM1       (2 ^ X) - 1
ZERO       Load value of zero


###########
hotfpu.bas shows FPU Object coding examples.

A future release will allow one to "dimension" a FPU object. With
this feature, several objects could be dimensioned with the advantage
that (1) a FPU type structure will conveniently hold saved environments
and other values and (2) allow easy change between sets of incompleted
calculations.

Copyright 2003-2005 James J Keene PhD
Original Publication: Aug 26, 2003
