BasicArithmetic.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, August 2, 1991 12:41 pm PDT
DIRECTORY Basics USING [Comparison];
BasicArithmetic: CEDAR DEFINITIONS
~ BEGIN
Signed numbers (INT)
MixedMul: PROC [x: CARD, y: INT] RETURNS [INT] ~ TRUSTED MACHINE CODE {
"XR←MixedMul"
};
returns x * y
raises
ArithmeticOverflow if the result is not expressible as an INT
note
especially efficient when x is small
how about optional efficient special cases for various machines?
IntMul: PROC [x, y: INT] RETURNS [INT] ~ TRUSTED MACHINE CODE {
"XR←IntMul"
};
returns x * y
raises
ArithmeticOverflow if the result is not expressible as an INT
IntDiv: PROC [x, y: INT] RETURNS [INT] ~ TRUSTED MACHINE CODE {
"XR←IntDiv"
};
returns x / y
raises
ZeroDivisor if y = 0
ArithmeticOverflow if the result is not expressible as an INT
IntMod: PROC [x,y: INT] RETURNS [INT] ~ TRUSTED MACHINE CODE {
"XR←IntMod"
};
returns x MOD y (always IN [0..ABS[y]) )
raises
ZeroDivisor if y = 0
ArithmeticOverflow if the result is not expressible as an INT
(i.e. FIRST[INT]/-1)
Signed division note:
let q = IntDiv[x, y], r = IntMod[x, y], with no exceptions
then x = IntMul[q, y] + r, and 0 d r < ABS[y]
Unsigned numbers (CARD)
CardMul: PROC [x, y: CARD] RETURNS [CARD] ~ TRUSTED MACHINE CODE {
"XR�rdMul"
};
returns x * y
note
no overflow checking
CardDiv: PROC [x, y: CARD] RETURNS [CARD] ~ TRUSTED MACHINE CODE {
"XR�rdDiv"
};
returns x / y
raises
ZeroDivisor if y = 0
note
no overflow checking
CardMod: PROC [x, y: CARD] RETURNS [CARD] ~ TRUSTED MACHINE CODE {
"XR�rdMod"
};
returns x MOD y
raises
ZeroDivisor if y = 0
note
no overflow checking
Unigned division note:
let q = CardDiv[x, y], r = CardMod[x, y], with no exceptions
then x = CardMul[q, y] + r, and 0 d r < y
Real numbers (32-bit IEEE)
If these routines are implemented as macros, the arguments must not be evaluated twice unless specified.
The compiler generates calls to these procedures using int as type for the parameters or returns; to get the real numbers, the parameter must be loopholed, NOT casted.
By using int the c2c compiler ensures that the C compiler will not convert these parameters to double precision.
Once in the glorious future we will also need 64 bits.
RealNeg: PROC [a: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealNeg"
};
RealAbs: PROC [a: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealAbs"
};
RealCompare: PROC [x, y: REAL] RETURNS [Basics.Comparison] ~ TRUSTED MACHINE CODE {
"XR←RealCompare"
};
compares x and y
raises RealException as specified by the IEEE standard
RealAdd: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealAdd"
};
RealSub: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealSub"
};
(a-b)
RealMul: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealMul"
};
RealDiv: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealDiv"
};
(a/b)
FloatInt: PROC [i: INT32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR𡤏loatInt"
};
FloatCard: PROC [i: CARD32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR𡤏loatCard"
};
RealMax: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealMax"
};
RealMin: PROC [a, b: REAL32] RETURNS [REAL32] ~ TRUSTED MACHINE CODE {
"XR←RealMin"
};
RealGt: PROC [a, b: REAL32] RETURNS [BOOL] ~ TRUSTED MACHINE CODE {
"XR←RealGt"
};
(a>b)
RealGe: PROC [a, b: REAL32] RETURNS [BOOL]~ TRUSTED MACHINE CODE {
"XR←RealGe"
};
(a>=b)
Fix: PROC [r: REAL, mode: RoundingMode ← rn] RETURNS [INT];
returns the integer closest to r determined by the mode -- Real.mesa
raises RealException as specified by the IEEE standard
RoundingMode: TYPE = MACHINE DEPENDENT {rn, rz, rm, rp};
rn: Round to nearest (unbiased).
rz: Round to zero (truncate).
rp: Round to plus infinity (round up).
rm: Round to minus infinity (round down).
END.