- Timestamp:
- Apr 19, 2022 9:22:30 PM (3 years ago)
- Location:
- trunk/src/libs/softfloat-3e
- Files:
-
- 2 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/softfloat-3e/Makefile.kmk
r94548 r94638 267 267 source/extF80_div.c \ 268 268 source/extF80_rem.c \ 269 source/extF80_partialRem.c \ 269 270 source/extF80_sqrt.c \ 270 271 source/extF80_eq.c \ -
trunk/src/libs/softfloat-3e/source/extF80_partialRem.c
r94621 r94638 41 41 #include "specialize.h" 42 42 #include "softfloat.h" 43 44 extFloat80_t extF80_rem( extFloat80_t a, extFloat80_t b SOFTFLOAT_STATE_DECL_COMMA ) 43 #include <iprt/cdefs.h> /* RT_BIT_64 */ 44 #include <iprt/x86.h> /* X86_FSW_C? */ 45 #include <iprt/assert.h> 46 47 /** VBox: Copy of extF80_rem modified to fit FPREM and FPREM1. */ 48 extFloat80_t extF80_partialRem( extFloat80_t a, extFloat80_t b, uint8_t roundingMode, 49 uint16_t *pfCxFlags, softfloat_state_t *pState ) 45 50 { 46 51 union { struct extFloat80M s; extFloat80_t f; } uA; … … 67 72 union { struct extFloat80M s; extFloat80_t f; } uZ; 68 73 74 *pfCxFlags = 0; /* C2=0 - complete */ /* VBox */ 75 69 76 /*------------------------------------------------------------------------ 70 77 *------------------------------------------------------------------------*/ … … 84 91 if ( expA == 0x7FFF ) { 85 92 if ( 86 (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) 87 || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) 93 (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) /* VBox: NaN or Indefinite */ 94 || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) /* VBox: NaN or Indefinite */ 88 95 ) { 89 96 goto propagateNaN; 90 97 } 91 goto invalid; 98 goto invalid; /* VBox: Infinity */ 92 99 } 93 100 if ( expB == 0x7FFF ) { 94 if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; 101 if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; /* VBox: NaN or Indefinite */ 95 102 /*-------------------------------------------------------------------- 96 103 | Argument b is an infinity. Doubling `expB' is an easy way to ensure … … 104 111 if ( ! expB ) expB = 1; 105 112 if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { 106 if ( ! sigB ) goto invalid; 113 if ( ! sigB ) goto invalid; /* VBox: Zero -> /0 -> invalid. */ 107 114 normExpSig = softfloat_normSubnormalExtF80Sig( sigB ); 108 115 expB += normExpSig.exp; … … 112 119 if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { 113 120 if ( ! sigA ) { 121 #if 0 /* A is zero. VBox: Don't mix denormals and zero returns! */ /* VBox */ 114 122 expA = 0; 115 123 goto copyA; 124 #else /* VBox */ 125 uiZ64 = packToExtF80UI64( signA, 0); /* VBox */ 126 uiZ0 = 0; /* VBox */ 127 goto uiZ; /* VBox */ 128 #endif /* VBox */ 116 129 } 117 130 normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); … … 122 135 *------------------------------------------------------------------------*/ 123 136 expDiff = expA - expB; 137 138 /*------------------------------------------------------------------------ VBox 139 | Do at most 63 rounds. If exponent difference is 64 or higher, return VBox 140 | a partial remainder. VBox 141 *------------------------------------------------------------------------*/ /* VBox */ 142 bool const fPartial = expDiff >= 64; /* VBox */ 143 if ( fPartial ) { /* VBox */ /* VBox */ 144 unsigned N = 32 + ((unsigned)expDiff % 32); /* (Amount of work documented by AMD.) */ /* VBox */ 145 expB = expA - N; /* VBox */ 146 expDiff = N; /* VBox */ 147 roundingMode = softfloat_round_minMag; /* VBox */ 148 } /* VBox */ 149 150 /*------------------------------------------------------------------------ 151 | The final rounds. 152 *------------------------------------------------------------------------*/ 124 153 if ( expDiff < -1 ) goto copyA; 125 154 rem = softfloat_shortShiftLeft128( 0, sigA, 32 ); 126 155 shiftedSigB = softfloat_shortShiftLeft128( 0, sigB, 32 ); 156 uint64_t quotient = 0; /* VBox */ 127 157 if ( expDiff < 1 ) { 128 158 if ( expDiff ) { … … 132 162 } else { 133 163 q = (sigB <= sigA); 164 quotient = q; /* VBox */ 134 165 if ( q ) { 135 166 rem = … … 145 176 if ( expDiff < 0 ) break; 146 177 q = (q64 + 0x80000000)>>32; 178 quotient = (quotient << 29) + q; /* VBox */ 147 179 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); 148 180 term = softfloat_mul64ByShifted32To128( sigB, q ); … … 152 184 softfloat_add128( 153 185 rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 ); 186 quotient--; /* VBox */ 154 187 } 155 188 expDiff -= 29; … … 159 192 *--------------------------------------------------------------------*/ 160 193 q = (uint32_t) (q64>>32)>>(~expDiff & 31); 194 quotient = (quotient << (expDiff + 30)) + q; /* VBox */ 161 195 rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 ); 162 196 term = softfloat_mul64ByShifted32To128( sigB, q ); … … 174 208 altRem = rem; 175 209 ++q; 210 quotient++; /* VBox */ 176 211 rem = 177 212 softfloat_sub128( … … 179 214 } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ); 180 215 selectRem: 181 meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 ); 182 if ( 183 (meanRem.v64 & UINT64_C( 0x8000000000000000 )) 184 || (! (meanRem.v64 | meanRem.v0) && (q & 1)) 185 ) { 186 rem = altRem; 187 } 216 if (roundingMode == softfloat_round_near_even) { /* VBox */ 217 meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 ); 218 if ( 219 (meanRem.v64 & UINT64_C( 0x8000000000000000 )) 220 || (! (meanRem.v64 | meanRem.v0) && (q & 1)) 221 ) { 222 rem = altRem; 223 quotient--; /* VBox */ 224 } 225 } /* VBox */ 188 226 signRem = signA; 189 227 if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { 190 signRem = ! signRem; 191 rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 ); 192 } 228 if (roundingMode != softfloat_round_near_even) { /* VBox */ 229 rem = altRem; /* VBox */ 230 quotient--; /* VBox */ 231 } else { /* VBox */ 232 signRem = ! signRem; 233 rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 ); 234 Assert(!fPartial); /* VBox */ 235 } /* VBox */ 236 } else Assert(roundingMode == softfloat_round_near_even); /* VBox */ 237 238 /* VBox: Set pfCxFlags */ /* VBox */ 239 if ( fPartial ) { /* VBox */ 240 *pfCxFlags = X86_FSW_C2; /* C2 = 1 - incomplete */ /* VBox */ 241 } else { /* VBox */ 242 *pfCxFlags = X86_FSW_CX_FROM_QUOTIENT( quotient ); /* C2 = 0 - complete */ /* VBox */ 243 } /* VBox */ 244 193 245 return 194 246 softfloat_normRoundPackToExtF80( … … 212 264 copyA: 213 265 if ( expA < 1 ) { 266 #if 0 /* VBox */ 214 267 sigA >>= 1 - expA; 215 268 expA = 0; 269 #else /* VBox */ 270 Assert(sigA != 0); /* We don't get here for zero values, only denormals. */ /* VBox */ 271 /* Apply the bias adjust if underflows exceptions aren't masked, unless VBox 272 the divisor is +/-Infinity. VBox 273 Note! extB has been tweaked, so don't use if for Inf classification. */ /* VBox */ 274 if ( (pState->exceptionMask & softfloat_flag_underflow) /* VBox */ 275 || (expExtF80UI64( b.signExp ) == 0x7fff && !(sigB & (RT_BIT_64( 63 ) - 1))) ) { /* VBox */ 276 sigA >>= 1 - expA; /* VBox */ 277 expA = 0; /* VBox */ 278 } else { /* VBox */ 279 softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox */ 280 expA = (expA + RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX; /* VBox */ 281 } /* VBox */ 282 #endif /* VBox */ 216 283 } 217 284 uiZ64 = packToExtF80UI64( signA, expA ); -
trunk/src/libs/softfloat-3e/source/include/softfloat.h
r94558 r94638 297 297 extFloat80_t extF80_div( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA ); 298 298 extFloat80_t extF80_rem( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA ); 299 extFloat80_t extF80_partialRem( extFloat80_t a, extFloat80_t b, uint8_t roundingMode, /* VBox: FPREM/FPREM1 */ 300 uint16_t *pfCxFlags, softfloat_state_t *pState ); /* VBox: FPREM/FPREM1 */ 299 301 extFloat80_t extF80_sqrt( extFloat80_t SOFTFLOAT_STATE_DECL_COMMA ); 300 302 bool extF80_eq( extFloat80_t, extFloat80_t SOFTFLOAT_STATE_DECL_COMMA );
Note:
See TracChangeset
for help on using the changeset viewer.