~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/lib/softfloat/softfloat.h

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
#endif
59
59
 
60
60
/*----------------------------------------------------------------------------
 
61
| Primitive arithmetic functions, including multi-word arithmetic, and
 
62
| division and square root approximations.  (Can be specialized to target if
 
63
| desired.)
 
64
*----------------------------------------------------------------------------*/
 
65
#include "softfloat-macros"
 
66
 
 
67
/*----------------------------------------------------------------------------
61
68
| Software IEC/IEEE floating-point underflow tininess-detection mode.
62
69
*----------------------------------------------------------------------------*/
63
70
extern int8 float_detect_tininess;
197
204
#endif
198
205
 
199
206
/*----------------------------------------------------------------------------
 
207
| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
 
208
| extended double-precision floating-point value, returning the result.
 
209
*----------------------------------------------------------------------------*/
 
210
 
 
211
INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
 
212
{
 
213
    floatx80 z;
 
214
 
 
215
    z.low = zSig;
 
216
    z.high = ( ( (bits16) zSign )<<15 ) + zExp;
 
217
    return z;
 
218
 
 
219
}
 
220
 
 
221
/*----------------------------------------------------------------------------
200
222
| Software IEC/IEEE extended double-precision rounding precision.  Valid
201
223
| values are 32, 64, and 80.
202
224
*----------------------------------------------------------------------------*/
220
242
flag floatx80_lt_quiet( floatx80, floatx80 );
221
243
flag floatx80_is_signaling_nan( floatx80 );
222
244
 
 
245
int floatx80_fsin(floatx80 &a);
 
246
int floatx80_fcos(floatx80 &a);
 
247
int floatx80_ftan(floatx80 &a);
 
248
 
223
249
#endif
224
250
 
225
251
#ifdef FLOAT128
255
281
flag float128_lt_quiet( float128, float128 );
256
282
flag float128_is_signaling_nan( float128 );
257
283
 
 
284
/*----------------------------------------------------------------------------
 
285
| Packs the sign `zSign', the exponent `zExp', and the significand formed
 
286
| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
 
287
| floating-point value, returning the result.  After being shifted into the
 
288
| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
 
289
| added together to form the most significant 32 bits of the result.  This
 
290
| means that any integer portion of `zSig0' will be added into the exponent.
 
291
| Since a properly normalized significand will have an integer portion equal
 
292
| to 1, the `zExp' input should be 1 less than the desired result exponent
 
293
| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
 
294
| significand.
 
295
*----------------------------------------------------------------------------*/
 
296
 
 
297
INLINE float128
 
298
 packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
 
299
{
 
300
    float128 z;
 
301
 
 
302
    z.low = zSig1;
 
303
    z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
 
304
    return z;
 
305
 
 
306
}
 
307
 
 
308
/*----------------------------------------------------------------------------
 
309
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
310
| and extended significand formed by the concatenation of `zSig0', `zSig1',
 
311
| and `zSig2', and returns the proper quadruple-precision floating-point value
 
312
| corresponding to the abstract input.  Ordinarily, the abstract value is
 
313
| simply rounded and packed into the quadruple-precision format, with the
 
314
| inexact exception raised if the abstract input cannot be represented
 
315
| exactly.  However, if the abstract value is too large, the overflow and
 
316
| inexact exceptions are raised and an infinity or maximal finite value is
 
317
| returned.  If the abstract value is too small, the input value is rounded to
 
318
| a subnormal number, and the underflow and inexact exceptions are raised if
 
319
| the abstract input cannot be represented exactly as a subnormal quadruple-
 
320
| precision floating-point number.
 
321
|     The input significand must be normalized or smaller.  If the input
 
322
| significand is not normalized, `zExp' must be 0; in that case, the result
 
323
| returned is a subnormal number, and it must not require rounding.  In the
 
324
| usual case that the input significand is normalized, `zExp' must be 1 less
 
325
| than the ``true'' floating-point exponent.  The handling of underflow and
 
326
| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 
327
*----------------------------------------------------------------------------*/
 
328
 
 
329
INLINE float128
 
330
 roundAndPackFloat128(
 
331
     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
 
332
{
 
333
    int8 roundingMode;
 
334
    flag roundNearestEven, increment, isTiny;
 
335
 
 
336
    roundingMode = float_rounding_mode;
 
337
    roundNearestEven = ( roundingMode == float_round_nearest_even );
 
338
    increment = ( (sbits64) zSig2 < 0 );
 
339
    if ( ! roundNearestEven ) {
 
340
        if ( roundingMode == float_round_to_zero ) {
 
341
            increment = 0;
 
342
        }
 
343
        else {
 
344
            if ( zSign ) {
 
345
                increment = ( roundingMode == float_round_down ) && zSig2;
 
346
            }
 
347
            else {
 
348
                increment = ( roundingMode == float_round_up ) && zSig2;
 
349
            }
 
350
        }
 
351
    }
 
352
    if ( 0x7FFD <= (bits32) zExp ) {
 
353
        if (    ( 0x7FFD < zExp )
 
354
             || (    ( zExp == 0x7FFD )
 
355
                  && eq128(
 
356
                         LIT64( 0x0001FFFFFFFFFFFF ),
 
357
                         LIT64( 0xFFFFFFFFFFFFFFFF ),
 
358
                         zSig0,
 
359
                         zSig1
 
360
                     )
 
361
                  && increment
 
362
                )
 
363
           ) {
 
364
            float_raise( float_flag_overflow | float_flag_inexact );
 
365
            if (    ( roundingMode == float_round_to_zero )
 
366
                 || ( zSign && ( roundingMode == float_round_up ) )
 
367
                 || ( ! zSign && ( roundingMode == float_round_down ) )
 
368
               ) {
 
369
                return
 
370
                    packFloat128(
 
371
                        zSign,
 
372
                        0x7FFE,
 
373
                        LIT64( 0x0000FFFFFFFFFFFF ),
 
374
                        LIT64( 0xFFFFFFFFFFFFFFFF )
 
375
                    );
 
376
            }
 
377
            return packFloat128( zSign, 0x7FFF, 0, 0 );
 
378
        }
 
379
        if ( zExp < 0 ) {
 
380
            isTiny =
 
381
                   ( float_detect_tininess == float_tininess_before_rounding )
 
382
                || ( zExp < -1 )
 
383
                || ! increment
 
384
                || lt128(
 
385
                       zSig0,
 
386
                       zSig1,
 
387
                       LIT64( 0x0001FFFFFFFFFFFF ),
 
388
                       LIT64( 0xFFFFFFFFFFFFFFFF )
 
389
                   );
 
390
            shift128ExtraRightJamming(
 
391
                zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
 
392
            zExp = 0;
 
393
            if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
 
394
            if ( roundNearestEven ) {
 
395
                increment = ( (sbits64) zSig2 < 0 );
 
396
            }
 
397
            else {
 
398
                if ( zSign ) {
 
399
                    increment = ( roundingMode == float_round_down ) && zSig2;
 
400
                }
 
401
                else {
 
402
                    increment = ( roundingMode == float_round_up ) && zSig2;
 
403
                }
 
404
            }
 
405
        }
 
406
    }
 
407
    if ( zSig2 ) float_exception_flags |= float_flag_inexact;
 
408
    if ( increment ) {
 
409
        add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
 
410
        zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
 
411
    }
 
412
    else {
 
413
        if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
 
414
    }
 
415
    return packFloat128( zSign, zExp, zSig0, zSig1 );
 
416
 
 
417
}
 
418
 
 
419
/*----------------------------------------------------------------------------
 
420
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 
421
| and significand formed by the concatenation of `zSig0' and `zSig1', and
 
422
| returns the proper quadruple-precision floating-point value corresponding
 
423
| to the abstract input.  This routine is just like `roundAndPackFloat128'
 
424
| except that the input significand has fewer bits and does not have to be
 
425
| normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
 
426
| point exponent.
 
427
*----------------------------------------------------------------------------*/
 
428
 
 
429
INLINE float128
 
430
 normalizeRoundAndPackFloat128(
 
431
     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
 
432
{
 
433
    int8 shiftCount;
 
434
    bits64 zSig2;
 
435
 
 
436
    if ( zSig0 == 0 ) {
 
437
        zSig0 = zSig1;
 
438
        zSig1 = 0;
 
439
        zExp -= 64;
 
440
    }
 
441
    shiftCount = countLeadingZeros64( zSig0 ) - 15;
 
442
    if ( 0 <= shiftCount ) {
 
443
        zSig2 = 0;
 
444
        shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
 
445
    }
 
446
    else {
 
447
        shift128ExtraRightJamming(
 
448
            zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
 
449
    }
 
450
    zExp -= shiftCount;
 
451
    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
 
452
 
 
453
}
 
454
 
258
455
#endif
259
456