|
@@ -687,3 +687,83 @@ static floatx80
|
|
|
increment = ( (sbits64) zSig1 < 0 );
|
|
|
}
|
|
|
else {
|
|
|
+ if ( zSign ) {
|
|
|
+ increment = ( roundingMode == float_round_down ) && zSig1;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ increment = ( roundingMode == float_round_up ) && zSig1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( increment ) {
|
|
|
+ ++zSig0;
|
|
|
+ zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
|
|
|
+ if ( (sbits64) zSig0 < 0 ) zExp = 1;
|
|
|
+ }
|
|
|
+ return packFloatx80( zSign, zExp, zSig0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ( zSig1 ) roundData->exception |= float_flag_inexact;
|
|
|
+ if ( increment ) {
|
|
|
+ ++zSig0;
|
|
|
+ if ( zSig0 == 0 ) {
|
|
|
+ ++zExp;
|
|
|
+ zSig0 = LIT64( 0x8000000000000000 );
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if ( zSig0 == 0 ) zExp = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return packFloatx80( zSign, zExp, zSig0 );
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+Takes an abstract floating-point value having sign `zSign', exponent
|
|
|
+`zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
|
|
|
+and returns the proper extended double-precision floating-point value
|
|
|
+corresponding to the abstract input. This routine is just like
|
|
|
+`roundAndPackFloatx80' except that the input significand does not have to be
|
|
|
+normalized.
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
+static floatx80
|
|
|
+ normalizeRoundAndPackFloatx80(
|
|
|
+ struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
|
|
|
+ )
|
|
|
+{
|
|
|
+ int8 shiftCount;
|
|
|
+
|
|
|
+ if ( zSig0 == 0 ) {
|
|
|
+ zSig0 = zSig1;
|
|
|
+ zSig1 = 0;
|
|
|
+ zExp -= 64;
|
|
|
+ }
|
|
|
+ shiftCount = countLeadingZeros64( zSig0 );
|
|
|
+ shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
|
|
|
+ zExp -= shiftCount;
|
|
|
+ return
|
|
|
+ roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+Returns the result of converting the 32-bit two's complement integer `a' to
|
|
|
+the single-precision floating-point format. The conversion is performed
|
|
|
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
|
|
|
+-------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
+float32 int32_to_float32(struct roundingData *roundData, int32 a)
|
|
|
+{
|
|
|
+ flag zSign;
|
|
|
+
|
|
|
+ if ( a == 0 ) return 0;
|
|
|
+ if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
|
|
|
+ zSign = ( a < 0 );
|
|
|
+ return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
|