-- Ieee.mesa
-- Last Modified: Stewart August 27, 1982 11:10 am
-- Internal details of the IEEE FP implementation

DIRECTORY
  MiscAlpha USING [alpha, aFSTICKY],
  Mopcodes USING [zMISC],
  Real,
  RealOps,
  Inline;

Ieee: CEDAR DEFINITIONS IMPORTS Inline =
  BEGIN OPEN Inline, Real, RealOps;

  SingleReal: TYPE = MACHINE DEPENDENT RECORD [
    m2: CARDINAL, sign: BOOLEAN, exp: [0..377B], m1: [0..177B]];

  Details: TYPE = MACHINE DEPENDENT RECORD [
    sign: BOOLEAN, sticky: BOOLEAN, blank: [0..7777B], type: Real.NumberType];

  Ext: TYPE = RECORD [det: Details, exp: INTEGER, frac: Inline.LongNumber];

  -- constants

  HiBit: CARDINAL = 100000B;
  NotHiBit: CARDINAL = 077777B;
  ExponentBias: INTEGER = 127;
  ExponentMask: INTEGER = 077600B;
  ExponentShift: INTEGER = 7;
  HiFractionMask: INTEGER = 177B;
  LowSignificandMask: CARDINAL = 177400B;
  FractionShift: INTEGER = 8;
  LeastSignificandBit: INTEGER = 0400B;
  HiddenBit: CARDINAL = 100000B;
  StickyBits: CARDINAL = 77B;
  NotStickyBits: CARDINAL = 177700B;
  MagicLI: LONG INTEGER = LOOPHOLE[20000000000B];
  HalfLC: LONG CARDINAL = LOOPHOLE[20000000000B];
  MagicI: INTEGER = FIRST[INTEGER];
  SignBit: CARDINAL = 100000B;
  ExpSingleMax: INTEGER = 127;
  ExpSingleMin: INTEGER = -126;
  DenormalizedExponent: INTEGER = -127;
  NaNExponent: INTEGER = 128;
  LargestSignificand: LONG CARDINAL = 37777777400B;
  BiasAdjust: INTEGER = 192;

  -- global variables

  fpmode: RealOps.Mode;
  stickyFlags: ExceptionFlags;
  thisTimeExceptions: ExceptionFlags;

  LN: PROC [r: LONG UNSPECIFIED] RETURNS [LongNumber] = INLINE {
    RETURN[LOOPHOLE[r, LongNumber]]; };

  BitOn: PROC [a, b: UNSPECIFIED] RETURNS [BOOLEAN] = INLINE {
    RETURN[BITAND[a, b] # LOOPHOLE[0, UNSPECIFIED]]; };

  Normalized: PROC [g: INTEGER] RETURNS [BOOLEAN] = INLINE {
    RETURN[
    	BITAND[LOOPHOLE[g, UNSPECIFIED], LOOPHOLE[HiddenBit, UNSPECIFIED]]
    		# LOOPHOLE[0, UNSPECIFIED]]; };

  -- Add with Carry

  ADC3: PROC [a, b, c: CARDINAL] RETURNS [CARDINAL, CARDINAL] = INLINE {
    s: LongNumber;
    s.lc ← LONG[a] + LONG[b] + LONG[c];
    RETURN[s.highbits, s.lowbits];
    };

  -- Add two shorts to make a long

  ADC2: PROC [a, b: CARDINAL] RETURNS [CARDINAL, CARDINAL] = INLINE {
    s: LongNumber; s.lc ← LONG[a] + LONG[b]; RETURN[s.highbits, s.lowbits]; };

  -- Separate the packed REAL into its component elements

  Unpack: PROC [REAL] RETURNS [Ext];
  Pack: PROC [POINTER TO Ext] RETURNS [REAL];
  Round: PROC [POINTER TO Ext];
  StepTwo: PROC [POINTER TO Ext];
  GRS: PROC [g: INTEGER] RETURNS [INTEGER];
  PostNormalize: PROC [POINTER TO Ext];
  LongShift: PROC [z: LONG UNSPECIFIED, count: INTEGER]
    RETURNS [LONG UNSPECIFIED];
  RShift: PROC [z: LONG UNSPECIFIED] RETURNS [LONG UNSPECIFIED];
  LShift: PROC [z: LONG UNSPECIFIED] RETURNS [LONG UNSPECIFIED];
  RShift1in1: PROC [z: LONG UNSPECIFIED] RETURNS [LONG UNSPECIFIED];
  DeNormalize: PROC [z: POINTER TO Ext, count: INTEGER];
  Mul32: PROC [x, y: LongNumber] RETURNS [LongNumber, LongNumber];
  FixExtended: PUBLIC PROC [z: Ext, rmode: RoundingMode]
    RETURNS [v: LONG INTEGER, invalid, overflow: BOOLEAN];
  SetInexactResult: PROC;
  SetInvalidOperation: PROC;
  SetDivisionByZero: PROC;
  SetUnderflow: PROC [POINTER TO Ext];
  SetOverflow: PROC [POINTER TO Ext];
  SetFixOverflow: PROC;
  CVExtended: PROC [Ext] RETURNS [Real.Extended];
  CFExtended: PROC [zz: REF Extended, z: POINTER TO Ext];
  NormalType: PROC [x, y: Details] RETURNS [INTEGER];

  MicroStickySet: PROC;

  IResultSticky: CARDINAL = 1;
  IResultEnable: CARDINAL = 100000B;

  MicroSticky: PROC [CARDINAL] RETURNS [CARDINAL] =
     TRUSTED MACHINE CODE { Mopcodes.zMISC, MiscAlpha.aFSTICKY; };

  InitIeee: PROC;

  funny: INTEGER = 02B;
  TNnn: INTEGER = 00B;
  TNnz: INTEGER = 01B;
  TNzn: INTEGER = 02B;
  TNzz: INTEGER = 03B;

  END.
L. Stewart, July 6, 1980  12:28 PM, Added InitIeee
L. Stewart, July 6, 1980  4:15 PM, Added microcode sticky bit stuff
September 28, 1980  9:10 PM; Stewart, Added aSETS
June 3, 1982 11:09 am; Stewart, removed aSETS, what was it for?