|
@@ -170,3 +170,62 @@ shifted into the proper positions, the three fields are simply added
|
|
|
together to form the result. This means that any integer portion of `zSig'
|
|
|
will be added into the exponent. Since a properly normalized significand
|
|
|
will have an integer portion equal to 1, the `zExp' input should be 1 less
|
|
|
+than the desired result exponent whenever `zSig' is a complete, normalized
|
|
|
+significand.
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
+INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
|
|
|
+{
|
|
|
+#if 0
|
|
|
+ float32 f;
|
|
|
+ __asm__("@ packFloat32 \n\
|
|
|
+ mov %0, %1, asl #31 \n\
|
|
|
+ orr %0, %2, asl #23 \n\
|
|
|
+ orr %0, %3"
|
|
|
+ : /* no outputs */
|
|
|
+ : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
|
|
|
+ : "cc");
|
|
|
+ return f;
|
|
|
+#else
|
|
|
+ return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
|
|
|
+and significand `zSig', and returns the proper single-precision floating-
|
|
|
+point value corresponding to the abstract input. Ordinarily, the abstract
|
|
|
+value is simply rounded and packed into the single-precision format, with
|
|
|
+the inexact exception raised if the abstract input cannot be represented
|
|
|
+exactly. If the abstract value is too large, however, the overflow and
|
|
|
+inexact exceptions are raised and an infinity or maximal finite value is
|
|
|
+returned. If the abstract value is too small, the input value is rounded to
|
|
|
+a subnormal number, and the underflow and inexact exceptions are raised if
|
|
|
+the abstract input cannot be represented exactly as a subnormal single-
|
|
|
+precision floating-point number.
|
|
|
+ The input significand `zSig' has its binary point between bits 30
|
|
|
+and 29, which is 7 bits to the left of the usual location. This shifted
|
|
|
+significand must be normalized or smaller. If `zSig' is not normalized,
|
|
|
+`zExp' must be 0; in that case, the result returned is a subnormal number,
|
|
|
+and it must not require rounding. In the usual case that `zSig' is
|
|
|
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
|
|
|
+The handling of underflow and overflow follows the IEC/IEEE Standard for
|
|
|
+Binary Floating-point Arithmetic.
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
+static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
|
|
|
+{
|
|
|
+ int8 roundingMode;
|
|
|
+ flag roundNearestEven;
|
|
|
+ int8 roundIncrement, roundBits;
|
|
|
+ flag isTiny;
|
|
|
+
|
|
|
+ roundingMode = roundData->mode;
|
|
|
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
|
|
|
+ roundIncrement = 0x40;
|
|
|
+ if ( ! roundNearestEven ) {
|
|
|
+ if ( roundingMode == float_round_to_zero ) {
|
|
|
+ roundIncrement = 0;
|
|
|
+ }
|
|
|
+ else {
|