RealConvertImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Stewart January 14, 1984 4:59 pm
Rovner On May 4, 1983 10:16 am
Levin, August 8, 1983 4:41 pm
Russ Atkinson (RRA) May 22, 1985 5:12:55 pm PDT
Doug Wyatt, April 25, 1985 5:28:57 pm PST
DIRECTORY
Basics USING [LongNumber],
Ieee USING [ExponentBias, ExpSingleMax, ExpSingleMin, HiFractionMask, NaNExponent, SingleReal],
PrincOpsUtils USING [BITAND],
PrincOps USING [zEXCH],
Real USING [PlusZero],
RealConvert USING [BcplReal, Mesa5Real];
RealConvertImpl: PROGRAM
IMPORTS PrincOpsUtils
EXPORTS RealConvert
= BEGIN OPEN Basics, RealConvert;
BcplHiddenBit: CARDINAL = 200B;
BcplBiasDifference: INTEGER = 1; -- Bias difference
MesaBiasDifference: INTEGER = 2;
MaxBiasedExponent: INTEGER = Ieee.ExpSingleMax + Ieee.ExponentBias;
MinBiasedExponent: INTEGER = Ieee.ExpSingleMin + Ieee.ExponentBias;
MostNegativeBcpl: LONG INTEGER = FIRST[LONG INTEGER];
MostPositiveBcpl: LONG INTEGER = LAST[LONG INTEGER];
CVError: PUBLIC SAFE ERROR = CODE;
BitOn: PROC [a, b: WORD] RETURNS [BOOL] = INLINE {
RETURN[PrincOpsUtils.BITAND[a, b] # 0];
};
Swaw: PROC [r: LongNumber] RETURNS [LongNumber] = MACHINE CODE {
PrincOps.zEXCH;
};
Mesa5ToIeee: PUBLIC SAFE PROC [a: Mesa5Real] RETURNS [REAL] = TRUSTED {
fl: Ieee.SingleReal ← LOOPHOLE[a, Ieee.SingleReal];
first convert to sign magnitude
IF LOOPHOLE[a, LONG CARDINAL] = 0 THEN RETURN[Real.PlusZero];
IF fl.sign THEN {
fl ← LOOPHOLE[-LOOPHOLE[a, INT], Ieee.SingleReal];
fl.sign ← TRUE; };
IF fl.exp < (MinBiasedExponent + MesaBiasDifference)
THEN {
Need to denormalize!
frac: LongNumber ← LOOPHOLE[fl, LongNumber];
frac.highbits ←
PrincOpsUtils.BITAND[frac.highbits, Ieee.HiFractionMask] + BcplHiddenBit;
THROUGH [fl.exp..(MinBiasedExponent + MesaBiasDifference)) DO
frac.lc ← frac.lc/2; ENDLOOP;
fl.exp ← 0;
fl.m1 ← frac.highbits;
fl.m2 ← frac.lowbits;
} -- Bias the exponent
ELSE fl.exp ← fl.exp - MesaBiasDifference;
RETURN[LOOPHOLE[fl, REAL]];
};
BcplToIeee: PUBLIC SAFE PROC [a: BcplReal] RETURNS [b: REAL] = TRUSTED {
fl: Ieee.SingleReal ← LOOPHOLE[Swaw[LOOPHOLE[a]]];
frac: LongNumber;
exp: INTEGER;
IF fl.sign THEN {
fl ← LOOPHOLE[-LOOPHOLE[fl, LONG INTEGER], Ieee.SingleReal];
fl.sign ← TRUE;
};
exp ← fl.exp;
frac ← LOOPHOLE[fl, LongNumber];
frac.highbits ← PrincOpsUtils.BITAND[frac.highbits, Ieee.HiFractionMask];
IF frac.lc = 0 THEN RETURN[Real.PlusZero];
Normalize, (will always go at least one step)
WHILE NOT BitOn[frac.highbits, BcplHiddenBit] DO
exp ← exp - 1; frac.lc ← frac.lc+frac.lc; -- Bias the exponent
ENDLOOP;
exp ← exp - BcplBiasDifference;
SELECT exp FROM
< MinBiasedExponent => {
THROUGH [exp..MinBiasedExponent) DO frac.lc ← frac.lc/2; ENDLOOP;
exp ← 0;
};
IN [MinBiasedExponent..MaxBiasedExponent] => NULL;
ENDCASE => ERROR;
fl.m1 ← PrincOpsUtils.BITAND[frac.highbits, Ieee.HiFractionMask];
fl.m2 ← frac.lowbits;
fl.exp ← exp;
RETURN[LOOPHOLE[fl, REAL]];
};
IeeeToBcpl: PUBLIC SAFE PROC [a: REAL] RETURNS [BcplReal] = TRUSTED {
fl: Ieee.SingleReal ← LOOPHOLE[a, Ieee.SingleReal];
sign: BOOL ← fl.sign;
frac: LongNumber;
exp: INTEGER ← fl.exp;
IF fl.exp = Ieee.NaNExponent + Ieee.ExponentBias AND (fl.m2 # 0 OR fl.m1 # 0) THEN
ERROR CVError[];
fl.sign ← FALSE;
frac ← LOOPHOLE[fl, LongNumber];
IF frac.lc = 0 THEN RETURN[[0]];
frac.highbits ← PrincOpsUtils.BITAND[frac.highbits, Ieee.HiFractionMask];
SELECT exp FROM
< MinBiasedExponent => {
Ieee number is denormalized
Normalize
exp ← exp + 1;
WHILE NOT BitOn[frac.highbits, BcplHiddenBit] DO
exp ← exp - 1; frac.lc ← frac.lc*2;
ENDLOOP;
frac.lc ← frac.lc/2;
exp ← exp + MesaBiasDifference; -- Denormalize
WHILE exp < 0 DO exp ← exp + 1; frac.lc ← frac.lc/2; ENDLOOP;
};
ENDCASE => {
frac.highbits ← frac.highbits + BcplHiddenBit;
put in leading one and round
IF BitOn[frac.lowbits, 1] AND BitOn[frac.lowbits, 2] THEN
frac.lc ← frac.lc + 1;
frac.lc ← frac.lc/2;
exp ← exp + MesaBiasDifference;
IF BitOn[frac.highbits, BcplHiddenBit] THEN {
exp ← exp + 1; frac.lc ← frac.lc/2;
};
IF exp > 377B THEN
RETURN[LOOPHOLE[Swaw[LOOPHOLE[IF fl.sign THEN MostNegativeBcpl ELSE MostPositiveBcpl]]]];
};
fl.m1 ← PrincOpsUtils.BITAND[frac.highbits, Ieee.HiFractionMask];
fl.m2 ← frac.lowbits;
fl.exp ← exp;
IF sign THEN fl ← LOOPHOLE[-LOOPHOLE[fl, INT], Ieee.SingleReal];
RETURN[LOOPHOLE[Swaw[LOOPHOLE[fl]]]];
};
END.
L. Stewart August 13, 1980 3:17 PM modified from RealConvert.mesa
L. Stewart August 14, 1980 3:30 PM added BcplToIeee
L. Stewart August 15, 1980 12:31 PM fixes to BcplToIeee
August 25, 1980 1:17 PM, LStewart; added IeeeToBcpl
August 27, 1982 1:21 pm, L. Stewart; SAFE
January 14, 1984 5:04 pm, Stewart, change to Ieee