sparc64/144900: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Sat Apr 24 12:20:07 UTC 2010


The following reply was made to PR sparc64/144900; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: sparc64/144900: commit references a PR
Date: Sat, 24 Apr 2010 12:11:59 +0000 (UTC)

 Author: marius
 Date: Sat Apr 24 12:11:41 2010
 New Revision: 207151
 URL: http://svn.freebsd.org/changeset/base/207151
 
 Log:
   Add a TestFloat based test suite for floating-point implementations
   currently supporting sparc64. After a `make depend all` there are
   three programs; testsoftfloat for testing against the SoftFloat in
   src/lib/libc/softfloat for reference purposes, testemufloat for
   testing the emulator source in src/lib/libc/sparc64/fpu and testfloat
   for testing with the installed libc. Support for other architectures
   can be added as needed.
   
   PR:		144900
   Submitted by:	Peter Jeremy
 
 Added:
   head/tools/test/testfloat/
   head/tools/test/testfloat/README.txt
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/README.txt
   head/tools/test/testfloat/fail.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/fail.c
   head/tools/test/testfloat/fail.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/fail.h
   head/tools/test/testfloat/random.c   (contents, props changed)
      - copied, changed from r207134, vendor/testfloat/dist/testfloat/random.c
   head/tools/test/testfloat/random.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/random.h
   head/tools/test/testfloat/slowfloat-32.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/slowfloat-32.c
   head/tools/test/testfloat/slowfloat-64.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/slowfloat-64.c
   head/tools/test/testfloat/slowfloat.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/slowfloat.c
   head/tools/test/testfloat/slowfloat.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/slowfloat.h
   head/tools/test/testfloat/sparc64/
   head/tools/test/testfloat/sparc64/Makefile   (contents, props changed)
   head/tools/test/testfloat/sparc64/fpu_emul.S   (contents, props changed)
   head/tools/test/testfloat/sparc64/fpu_reg.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/fpu_util.c   (contents, props changed)
   head/tools/test/testfloat/sparc64/libc_private.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/milieu.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/namespace.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/softfloat.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/sparc64.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/systflags.c   (contents, props changed)
   head/tools/test/testfloat/sparc64/systfloat.S   (contents, props changed)
   head/tools/test/testfloat/sparc64/systfloat.h   (contents, props changed)
   head/tools/test/testfloat/sparc64/systmodes.c   (contents, props changed)
   head/tools/test/testfloat/sparc64/un-namespace.h   (contents, props changed)
   head/tools/test/testfloat/systemBugs.txt
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/systemBugs.txt
   head/tools/test/testfloat/systflags.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/systflags.h
   head/tools/test/testfloat/systfloat.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/systfloat.c
   head/tools/test/testfloat/systmodes.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/systmodes.h
   head/tools/test/testfloat/testCases.c   (contents, props changed)
      - copied, changed from r207134, vendor/testfloat/dist/testfloat/testCases.c
   head/tools/test/testfloat/testCases.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testCases.h
   head/tools/test/testfloat/testFunction.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testFunction.c
   head/tools/test/testfloat/testFunction.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testFunction.h
   head/tools/test/testfloat/testLoops.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testLoops.c
   head/tools/test/testfloat/testLoops.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testLoops.h
   head/tools/test/testfloat/testfloat-history.txt
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testfloat-history.txt
   head/tools/test/testfloat/testfloat-source.txt
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testfloat-source.txt
   head/tools/test/testfloat/testfloat.c   (contents, props changed)
      - copied, changed from r207134, vendor/testfloat/dist/testfloat/testfloat.c
   head/tools/test/testfloat/testfloat.txt
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/testfloat.txt
   head/tools/test/testfloat/testsoftfloat.c   (contents, props changed)
      - copied, changed from r207134, vendor/testfloat/dist/testfloat/testsoftfloat.c
   head/tools/test/testfloat/writeHex.c
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/writeHex.c
   head/tools/test/testfloat/writeHex.h
      - copied unchanged from r207134, vendor/testfloat/dist/testfloat/writeHex.h
 Modified:
   head/tools/test/README
 
 Modified: head/tools/test/README
 ==============================================================================
 --- head/tools/test/README	Sat Apr 24 10:22:08 2010	(r207150)
 +++ head/tools/test/README	Sat Apr 24 12:11:41 2010	(r207151)
 @@ -11,3 +11,4 @@ devrandom	Programs to test /dev/*random.
  dtrace		DTrace test suite
  malloc		A program to test and benchmark malloc().
  posixshm	A program to test POSIX shared memory.
 +testfloat	Programs to test floating-point implementations
 
 Copied: head/tools/test/testfloat/README.txt (from r207134, vendor/testfloat/dist/testfloat/README.txt)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/test/testfloat/README.txt	Sat Apr 24 12:11:41 2010	(r207151, copy of r207134, vendor/testfloat/dist/testfloat/README.txt)
 @@ -0,0 +1,50 @@
 +
 +Package Overview for TestFloat Release 2a
 +
 +John R. Hauser
 +1998 December 16
 +
 +
 +TestFloat is a program for testing that a floating-point implementation
 +conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 +TestFloat is distributed in the form of C source code.  The TestFloat
 +package actually provides two related programs:
 +
 +-- The `testfloat' program tests a system's floating-point for conformance
 +   to the IEC/IEEE Standard.  This program uses the SoftFloat software
 +   floating-point implementation as a basis for comparison.
 +
 +-- The `testsoftfloat' program tests SoftFloat itself for conformance to
 +   the IEC/IEEE Standard.  These tests are performed by comparing against a
 +   separate, slower software floating-point that is included in the TestFloat
 +   package.
 +
 +TestFloat depends on SoftFloat, but SoftFloat is not included in the
 +TestFloat package.  SoftFloat can be obtained through the Web page `http://
 +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
 +
 +TestFloat is documented in three text files:
 +
 +   testfloat.txt          Documentation for using the TestFloat programs
 +                              (both `testfloat' and `testsoftfloat').
 +   testfloat-source.txt   Documentation for porting and compiling TestFloat.
 +   testfloat-history.txt  History of major changes to TestFloat.
 +
 +The following file is also provided:
 +
 +   systemBugs.txt         Information about processor bugs found using
 +                              TestFloat.
 +
 +Other files in the package comprise the source code for TestFloat.
 +
 +Please be aware that some work is involved in porting this software to other
 +targets.  It is not just a matter of getting `make' to complete without
 +error messages.  I would have written the code that way if I could, but
 +there are fundamental differences between systems that I can't make go away.
 +You should not attempt to compile the TestFloat sources without first
 +reading `testfloat-source.txt'.
 +
 +At the time of this writing, the most up-to-date information about
 +TestFloat and the latest release can be found at the Web page `http://
 +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 +
 
 Copied: head/tools/test/testfloat/fail.c (from r207134, vendor/testfloat/dist/testfloat/fail.c)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/test/testfloat/fail.c	Sat Apr 24 12:11:41 2010	(r207151, copy of r207134, vendor/testfloat/dist/testfloat/fail.c)
 @@ -0,0 +1,46 @@
 +
 +/*
 +===============================================================================
 +
 +This C source file is part of TestFloat, Release 2a, a package of programs
 +for testing the correctness of floating-point arithmetic complying to the
 +IEC/IEEE Standard for Floating-Point.
 +
 +Written by John R. Hauser.  More information is available through the Web
 +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 +
 +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
 +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
 +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
 +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
 +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 +
 +Derivative works are acceptable, even for commercial purposes, so long as
 +(1) they include prominent notice that the work is derivative, and (2) they
 +include prominent notice akin to these four paragraphs for those parts of
 +this code that are retained.
 +
 +===============================================================================
 +*/
 +
 +#include <stdlib.h>
 +#include <stdarg.h>
 +#include <stdio.h>
 +#include "milieu.h"
 +#include "fail.h"
 +
 +char *fail_programName = "";
 +
 +void fail( const char *message, ... )
 +{
 +    va_list varArgs;
 +
 +    fprintf( stderr, "%s: ", fail_programName );
 +    va_start( varArgs, message );
 +    vfprintf( stderr, message, varArgs );
 +    va_end( varArgs );
 +    fputs( ".\n", stderr );
 +    exit( EXIT_FAILURE );
 +
 +}
 +
 
 Copied: head/tools/test/testfloat/fail.h (from r207134, vendor/testfloat/dist/testfloat/fail.h)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/test/testfloat/fail.h	Sat Apr 24 12:11:41 2010	(r207151, copy of r207134, vendor/testfloat/dist/testfloat/fail.h)
 @@ -0,0 +1,29 @@
 +
 +/*
 +===============================================================================
 +
 +This C header file is part of TestFloat, Release 2a, a package of programs
 +for testing the correctness of floating-point arithmetic complying to the
 +IEC/IEEE Standard for Floating-Point.
 +
 +Written by John R. Hauser.  More information is available through the Web
 +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 +
 +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
 +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
 +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
 +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
 +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 +
 +Derivative works are acceptable, even for commercial purposes, so long as
 +(1) they include prominent notice that the work is derivative, and (2) they
 +include prominent notice akin to these four paragraphs for those parts of
 +this code that are retained.
 +
 +===============================================================================
 +*/
 +
 +extern char *fail_programName;
 +
 +void fail( const char *, ... );
 +
 
 Copied and modified: head/tools/test/testfloat/random.c (from r207134, vendor/testfloat/dist/testfloat/random.c)
 ==============================================================================
 --- vendor/testfloat/dist/testfloat/random.c	Fri Apr 23 19:48:31 2010	(r207134, copy source)
 +++ head/tools/test/testfloat/random.c	Sat Apr 24 12:11:41 2010	(r207151)
 @@ -23,6 +23,9 @@ this code that are retained.
  ===============================================================================
  */
  
 +#include <sys/cdefs.h>
 +__FBSDID("$FreeBSD$");
 +
  #include <stdlib.h>
  #include "milieu.h"
  #include "random.h"
 @@ -30,26 +33,21 @@ this code that are retained.
  uint8 randomUint8( void )
  {
  
 -    return (bits8) ( rand()>>4 );
 +    return (bits8) ( random()>>4 );
  
  }
  
  uint16 randomUint16( void )
  {
  
 -    return ( ( rand() & 0x0FF0 )<<4 ) | ( ( rand()>>4 ) & 0xFF );
 +    return ( random() & 0x0000ffff );
  
  }
  
  uint32 randomUint32( void )
  {
  
 -    return
 -          ( ( (uint32) ( rand() & 0x0FF0 ) )<<20 )
 -        | ( ( (uint32) ( rand() & 0x0FF0 ) )<<12 )
 -        | ( ( rand() & 0x0FF0 )<<4 )
 -        | ( ( rand()>>4 ) & 0xFF );
 -
 +    return ( ( (uint32) random()<<16) | ( (uint32) random() & 0x0000ffff) );
  }
  
  #ifdef BITS64
 
 Copied: head/tools/test/testfloat/random.h (from r207134, vendor/testfloat/dist/testfloat/random.h)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/test/testfloat/random.h	Sat Apr 24 12:11:41 2010	(r207151, copy of r207134, vendor/testfloat/dist/testfloat/random.h)
 @@ -0,0 +1,32 @@
 +
 +/*
 +===============================================================================
 +
 +This C header file is part of TestFloat, Release 2a, a package of programs
 +for testing the correctness of floating-point arithmetic complying to the
 +IEC/IEEE Standard for Floating-Point.
 +
 +Written by John R. Hauser.  More information is available through the Web
 +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 +
 +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
 +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
 +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
 +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
 +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 +
 +Derivative works are acceptable, even for commercial purposes, so long as
 +(1) they include prominent notice that the work is derivative, and (2) they
 +include prominent notice akin to these four paragraphs for those parts of
 +this code that are retained.
 +
 +===============================================================================
 +*/
 +
 +uint8 randomUint8( void );
 +uint16 randomUint16( void );
 +uint32 randomUint32( void );
 +#ifdef BITS64
 +uint64 randomUint64( void );
 +#endif
 +
 
 Copied: head/tools/test/testfloat/slowfloat-32.c (from r207134, vendor/testfloat/dist/testfloat/slowfloat-32.c)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/test/testfloat/slowfloat-32.c	Sat Apr 24 12:11:41 2010	(r207151, copy of r207134, vendor/testfloat/dist/testfloat/slowfloat-32.c)
 @@ -0,0 +1,1183 @@
 +
 +/*
 +===============================================================================
 +
 +This C source file is part of TestFloat, Release 2a, a package of programs
 +for testing the correctness of floating-point arithmetic complying to the
 +IEC/IEEE Standard for Floating-Point.
 +
 +Written by John R. Hauser.  More information is available through the Web
 +page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
 +
 +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
 +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
 +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
 +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
 +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 +
 +Derivative works are acceptable, even for commercial purposes, so long as
 +(1) they include prominent notice that the work is derivative, and (2) they
 +include prominent notice akin to these four paragraphs for those parts of
 +this code that are retained.
 +
 +===============================================================================
 +*/
 +
 +int8 slow_float_rounding_mode;
 +int8 slow_float_exception_flags;
 +int8 slow_float_detect_tininess;
 +
 +typedef struct {
 +    bits32 a0, a1;
 +} bits64X;
 +
 +typedef struct {
 +    flag isNaN;
 +    flag isInf;
 +    flag isZero;
 +    flag sign;
 +    int16 exp;
 +    bits64X sig;
 +} floatX;
 +
 +static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
 +static const floatX floatXPositiveZero =
 +    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
 +static const floatX floatXNegativeZero =
 +    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
 +
 +static bits64X shortShift64Left( bits64X a, int8 shiftCount )
 +{
 +    int8 negShiftCount;
 +
 +    negShiftCount = ( - shiftCount & 31 );
 +    a.a0 = ( a.a0<<shiftCount ) | ( a.a1>>negShiftCount );
 +    a.a1 <<= shiftCount;
 +    return a;
 +
 +}
 +
 +static bits64X shortShift64RightJamming( bits64X a, int8 shiftCount )
 +{
 +    int8 negShiftCount;
 +    bits32 extra;
 +
 +    negShiftCount = ( - shiftCount & 31 );
 +    extra = a.a1<<negShiftCount;
 +    a.a1 = ( a.a0<<negShiftCount ) | ( a.a1>>shiftCount ) | ( extra != 0 );
 +    a.a0 >>= shiftCount;
 +    return a;
 +
 +}
 +
 +static bits64X neg64( bits64X a )
 +{
 +
 +    if ( a.a1 == 0 ) {
 +        a.a0 = - a.a0;
 +    }
 +    else {
 +        a.a1 = - a.a1;
 +        a.a0 = ~ a.a0;
 +    }
 +    return a;
 +
 +}
 +
 +static bits64X add64( bits64X a, bits64X b )
 +{
 +
 +    a.a1 += b.a1;
 +    a.a0 += b.a0 + ( a.a1 < b.a1 );
 +    return a;
 +
 +}
 +
 +static flag eq64( bits64X a, bits64X b )
 +{
 +
 +    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
 +
 +}
 +
 +static flag le64( bits64X a, bits64X b )
 +{
 +
 +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
 +
 +}
 +
 +static flag lt64( bits64X a, bits64X b )
 +{
 +
 +    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
 +
 +}
 +
 +static floatX roundFloatXTo24( flag isTiny, floatX zx )
 +{
 +
 +    if ( zx.sig.a1 ) {
 +        slow_float_exception_flags |= float_flag_inexact;
 +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
 +        switch ( slow_float_rounding_mode ) {
 +         case float_round_nearest_even:
 +            if ( zx.sig.a1 < 0x80000000 ) goto noIncrement;
 +            if ( ( zx.sig.a1 == 0x80000000 ) && ! ( zx.sig.a0 & 1 ) ) {
 +                goto noIncrement;
 +            }
 +            break;
 +         case float_round_to_zero:
 +            goto noIncrement;
 +         case float_round_down:
 +            if ( ! zx.sign ) goto noIncrement;
 +            break;
 +         case float_round_up:
 +            if ( zx.sign ) goto noIncrement;
 +            break;
 +        }
 +        ++zx.sig.a0;
 +        if ( zx.sig.a0 == 0x01000000 ) {
 +            zx.sig.a0 = 0x00800000;
 +            ++zx.exp;
 +        }
 +    }
 + noIncrement:
 +    zx.sig.a1 = 0;
 +    return zx;
 +
 +}
 +
 +static floatX roundFloatXTo53( flag isTiny, floatX zx )
 +{
 +    int8 roundBits;
 +
 +    roundBits = zx.sig.a1 & 7;
 +    zx.sig.a1 -= roundBits;
 +    if ( roundBits ) {
 +        slow_float_exception_flags |= float_flag_inexact;
 +        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
 +        switch ( slow_float_rounding_mode ) {
 +         case float_round_nearest_even:
 +            if ( roundBits < 4 ) goto noIncrement;
 +            if ( ( roundBits == 4 ) && ! ( zx.sig.a1 & 8 ) ) goto noIncrement;
 +            break;
 +         case float_round_to_zero:
 +            goto noIncrement;
 +         case float_round_down:
 +            if ( ! zx.sign ) goto noIncrement;
 +            break;
 +         case float_round_up:
 +            if ( zx.sign ) goto noIncrement;
 +            break;
 +        }
 +        zx.sig.a1 += 8;
 +        zx.sig.a0 += ( zx.sig.a1 == 0 );
 +        if ( zx.sig.a0 == 0x01000000 ) {
 +            zx.sig.a0 = 0x00800000;
 +            ++zx.exp;
 +        }
 +    }
 + noIncrement:
 +    return zx;
 +
 +}
 +
 +static floatX int32ToFloatX( int32 a )
 +{
 +    floatX ax;
 +
 +    ax.isNaN = FALSE;
 +    ax.isInf = FALSE;
 +    ax.sign = ( a < 0 );
 +    ax.sig.a1 = ax.sign ? - a : a;
 +    ax.sig.a0 = 0;
 +    if ( a == 0 ) {
 +        ax.isZero = TRUE;
 +        return ax;
 +    }
 +    ax.isZero = FALSE;
 +    ax.sig = shortShift64Left( ax.sig, 23 );
 +    ax.exp = 32;
 +    while ( ax.sig.a0 < 0x00800000 ) {
 +        ax.sig = shortShift64Left( ax.sig, 1 );
 +        --ax.exp;
 +    }
 +    return ax;
 +
 +}
 +
 +static int32 floatXToInt32( floatX ax )
 +{
 +    int8 savedExceptionFlags;
 +    int16 shiftCount;
 +    int32 z;
 +
 +    if ( ax.isInf || ax.isNaN ) {
 +        slow_float_exception_flags |= float_flag_invalid;
 +        return ( ax.isInf & ax.sign ) ? 0x80000000 : 0x7FFFFFFF;
 +    }
 +    if ( ax.isZero ) return 0;
 +    savedExceptionFlags = slow_float_exception_flags;
 +    shiftCount = 52 - ax.exp;
 +    if ( 56 < shiftCount ) {
 +        ax.sig.a1 = 1;
 +        ax.sig.a0 = 0;
 +    }
 +    else {
 +        while ( 0 < shiftCount ) {
 +            ax.sig = shortShift64RightJamming( ax.sig, 1 );
 +            --shiftCount;
 +        }
 +    }
 +    ax = roundFloatXTo53( FALSE, ax );
 +    ax.sig = shortShift64RightJamming( ax.sig, 3 );
 +    z = ax.sig.a1;
 +    if ( ax.sign ) z = - z;
 +    if (    ( shiftCount < 0 )
 +         || ax.sig.a0
 +         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
 +       ) {
 +        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
 +        return ax.sign ? 0x80000000 : 0x7FFFFFFF;
 +    }
 +    return z;
 +
 +}
 +
 +static floatX float32ToFloatX( float32 a )
 +{
 +    int16 expField;
 +    floatX ax;
 +
 +    ax.isNaN = FALSE;
 +    ax.isInf = FALSE;
 +    ax.isZero = FALSE;
 +    ax.sign = ( ( a & 0x80000000 ) != 0 );
 +    expField = ( a>>23 ) & 0xFF;
 +    ax.sig.a1 = 0;
 +    ax.sig.a0 = a & 0x007FFFFF;
 +    if ( expField == 0 ) {
 +        if ( ax.sig.a0 == 0 ) {
 +            ax.isZero = TRUE;
 +        }
 +        else {
 +            expField = 1 - 0x7F;
 +            do {
 +                ax.sig.a0 <<= 1;
 +                --expField;
 +            } while ( ax.sig.a0 < 0x00800000 );
 +            ax.exp = expField;
 +        }
 +    }
 +    else if ( expField == 0xFF ) {
 +        if ( ax.sig.a0 == 0 ) {
 +            ax.isInf = TRUE;
 +        }
 +        else {
 +            ax.isNaN = TRUE;
 +        }
 +    }
 +    else {
 +        ax.sig.a0 |= 0x00800000;
 +        ax.exp = expField - 0x7F;
 +    }
 +    return ax;
 +
 +}
 +
 +static float32 floatXToFloat32( floatX zx )
 +{
 +    floatX savedZ;
 +    flag isTiny;
 +    int16 expField;
 +    float32 z;
 +
 +    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
 +    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
 +    if ( zx.isNaN ) return 0xFFFFFFFF;
 +    while ( 0x01000000 <= zx.sig.a0 ) {
 +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +        ++zx.exp;
 +    }
 +    while ( zx.sig.a0 < 0x00800000 ) {
 +        zx.sig = shortShift64Left( zx.sig, 1 );
 +        --zx.exp;
 +    }
 +    savedZ = zx;
 +    isTiny =
 +           ( slow_float_detect_tininess == float_tininess_before_rounding )
 +        && ( zx.exp + 0x7F <= 0 );
 +    zx = roundFloatXTo24( isTiny, zx );
 +    expField = zx.exp + 0x7F;
 +    if ( 0xFF <= expField ) {
 +        slow_float_exception_flags |=
 +            float_flag_overflow | float_flag_inexact;
 +        if ( zx.sign ) {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_down:
 +                z = 0xFF800000;
 +                break;
 +             case float_round_to_zero:
 +             case float_round_up:
 +                z = 0xFF7FFFFF;
 +                break;
 +            }
 +        }
 +        else {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_up:
 +                z = 0x7F800000;
 +                break;
 +             case float_round_to_zero:
 +             case float_round_down:
 +                z = 0x7F7FFFFF;
 +                break;
 +            }
 +        }
 +        return z;
 +    }
 +    if ( expField <= 0 ) {
 +        isTiny = TRUE;
 +        zx = savedZ;
 +        expField = zx.exp + 0x7F;
 +        if ( expField < -27 ) {
 +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
 +            zx.sig.a0 = 0;
 +        }
 +        else {
 +            while ( expField <= 0 ) {
 +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +                ++expField;
 +            }
 +        }
 +        zx = roundFloatXTo24( isTiny, zx );
 +        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
 +    }
 +    z = expField;
 +    z <<= 23;
 +    if ( zx.sign ) z |= 0x80000000;
 +    z |= zx.sig.a0 & 0x007FFFFF;
 +    return z;
 +
 +}
 +
 +static floatX float64ToFloatX( float64 a )
 +{
 +    int16 expField;
 +    floatX ax;
 +
 +    ax.isNaN = FALSE;
 +    ax.isInf = FALSE;
 +    ax.isZero = FALSE;
 +#ifdef BITS64
 +    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
 +    expField = ( a>>52 ) & 0x7FF;
 +    ax.sig.a1 = a;
 +    ax.sig.a0 = ( a>>32 ) & 0x000FFFFF;
 +#else
 +    ax.sign = ( ( a.high & 0x80000000 ) != 0 );
 +    expField = ( a.high>>( 52 - 32 ) ) & 0x7FF;
 +    ax.sig.a1 = a.low;
 +    ax.sig.a0 = a.high & 0x000FFFFF;
 +#endif
 +    if ( expField == 0 ) {
 +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
 +            ax.isZero = TRUE;
 +        }
 +        else {
 +            expField = 1 - 0x3FF;
 +            do {
 +                ax.sig = shortShift64Left( ax.sig, 1 );
 +                --expField;
 +            } while ( ax.sig.a0 < 0x00100000 );
 +            ax.exp = expField;
 +        }
 +    }
 +    else if ( expField == 0x7FF ) {
 +        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
 +            ax.isInf = TRUE;
 +        }
 +        else {
 +            ax.isNaN = TRUE;
 +        }
 +    }
 +    else {
 +        ax.exp = expField - 0x3FF;
 +        ax.sig.a0 |= 0x00100000;
 +    }
 +    ax.sig = shortShift64Left( ax.sig, 3 );
 +    return ax;
 +
 +}
 +
 +static float64 floatXToFloat64( floatX zx )
 +{
 +    floatX savedZ;
 +    flag isTiny;
 +    int16 expField;
 +    float64 z;
 +
 +#ifdef BITS64
 +    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
 +    if ( zx.isInf ) {
 +        return
 +              zx.sign ? LIT64( 0xFFF0000000000000 )
 +            : LIT64( 0x7FF0000000000000 );
 +    }
 +    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
 +#else
 +    if ( zx.isZero ) {
 +        z.low = 0;
 +        z.high = zx.sign ? 0x80000000 : 0;
 +        return z;
 +    }
 +    if ( zx.isInf ) {
 +        z.low = 0;
 +        z.high = zx.sign ? 0xFFF00000 : 0x7FF00000;
 +        return z;
 +    }
 +    if ( zx.isNaN ) {
 +        z.high = z.low = 0xFFFFFFFF;
 +        return z;
 +    }
 +#endif
 +    while ( 0x01000000 <= zx.sig.a0 ) {
 +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +        ++zx.exp;
 +    }
 +    while ( zx.sig.a0 < 0x00800000 ) {
 +        zx.sig = shortShift64Left( zx.sig, 1 );
 +        --zx.exp;
 +    }
 +    savedZ = zx;
 +    isTiny =
 +           ( slow_float_detect_tininess == float_tininess_before_rounding )
 +        && ( zx.exp + 0x3FF <= 0 );
 +    zx = roundFloatXTo53( isTiny, zx );
 +    expField = zx.exp + 0x3FF;
 +    if ( 0x7FF <= expField ) {
 +        slow_float_exception_flags |=
 +            float_flag_overflow | float_flag_inexact;
 +#ifdef BITS64
 +        if ( zx.sign ) {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_down:
 +                z = LIT64( 0xFFF0000000000000 );
 +                break;
 +             case float_round_to_zero:
 +             case float_round_up:
 +                z = LIT64( 0xFFEFFFFFFFFFFFFF );
 +                break;
 +            }
 +        }
 +        else {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_up:
 +                z = LIT64( 0x7FF0000000000000 );
 +                break;
 +             case float_round_to_zero:
 +             case float_round_down:
 +                z = LIT64( 0x7FEFFFFFFFFFFFFF );
 +                break;
 +            }
 +        }
 +#else
 +        if ( zx.sign ) {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_down:
 +                z.low = 0;
 +                z.high = 0xFFF00000;
 +                break;
 +             case float_round_to_zero:
 +             case float_round_up:
 +                z.low = 0xFFFFFFFF;
 +                z.high = 0xFFEFFFFF;
 +                break;
 +            }
 +        }
 +        else {
 +            switch ( slow_float_rounding_mode ) {
 +             case float_round_nearest_even:
 +             case float_round_up:
 +                z.low = 0;
 +                z.high = 0x7FF00000;
 +                break;
 +             case float_round_to_zero:
 +             case float_round_down:
 +                z.low = 0xFFFFFFFF;
 +                z.high = 0x7FEFFFFF;
 +                break;
 +            }
 +        }
 +#endif
 +        return z;
 +    }
 +    if ( expField <= 0 ) {
 +        isTiny = TRUE;
 +        zx = savedZ;
 +        expField = zx.exp + 0x3FF;
 +        if ( expField < -56 ) {
 +            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
 +            zx.sig.a0 = 0;
 +        }
 +        else {
 +            while ( expField <= 0 ) {
 +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +                ++expField;
 +            }
 +        }
 +        zx = roundFloatXTo53( isTiny, zx );
 +        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
 +    }
 +    zx.sig = shortShift64RightJamming( zx.sig, 3 );
 +#ifdef BITS64
 +    z = expField;
 +    z <<= 52;
 +    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
 +    z |= ( ( (bits64) ( zx.sig.a0 & 0x000FFFFF ) )<<32 ) | zx.sig.a1;
 +#else
 +    z.low = zx.sig.a1;
 +    z.high = expField;
 +    z.high <<= 52 - 32;
 +    if ( zx.sign ) z.high |= 0x80000000;
 +    z.high |= zx.sig.a0 & 0x000FFFFF;
 +#endif
 +    return z;
 +
 +}
 +
 +static floatX floatXInvalid( void )
 +{
 +
 +    slow_float_exception_flags |= float_flag_invalid;
 +    return floatXNaN;
 +
 +}
 +
 +static floatX floatXRoundToInt( floatX ax )
 +{
 +    int16 shiftCount, i;
 +
 +    if ( ax.isNaN || ax.isInf ) return ax;
 +    shiftCount = 52 - ax.exp;
 +    if ( shiftCount <= 0 ) return ax;
 +    if ( 55 < shiftCount ) {
 +        ax.exp = 52;
 +        ax.sig.a1 = ! ax.isZero;
 +        ax.sig.a0 = 0;
 +    }
 +    else {
 +        while ( 0 < shiftCount ) {
 +            ax.sig = shortShift64RightJamming( ax.sig, 1 );
 +            ++ax.exp;
 +            --shiftCount;
 +        }
 +    }
 +    ax = roundFloatXTo53( FALSE, ax );
 +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
 +    return ax;
 +
 +}
 +
 +static floatX floatXAdd( floatX ax, floatX bx )
 +{
 +    int16 expDiff;
 +    floatX zx;
 +
 +    if ( ax.isNaN ) return ax;
 +    if ( bx.isNaN ) return bx;
 +    if ( ax.isInf && bx.isInf ) {
 +        if ( ax.sign == bx.sign ) return ax;
 +        return floatXInvalid();
 +    }
 +    if ( ax.isInf ) return ax;
 +    if ( bx.isInf ) return bx;
 +    if ( ax.isZero && bx.isZero ) {
 +        if ( ax.sign == bx.sign ) return ax;
 +        goto completeCancellation;
 +    }
 +    if (    ( ax.sign != bx.sign )
 +         && ( ax.exp == bx.exp )
 +         && eq64( ax.sig, bx.sig )
 +       ) {
 + completeCancellation:
 +        return
 +              ( slow_float_rounding_mode == float_round_down ) ?
 +                  floatXNegativeZero
 +            : floatXPositiveZero;
 +    }
 +    if ( ax.isZero ) return bx;
 +    if ( bx.isZero ) return ax;
 +    expDiff = ax.exp - bx.exp;
 +    if ( expDiff < 0 ) {
 +        zx = ax;
 +        zx.exp = bx.exp;
 +        if ( expDiff < -56 ) {
 +            zx.sig.a1 = 1;
 +            zx.sig.a0 = 0;
 +        }
 +        else {
 +            while ( expDiff < 0 ) {
 +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +                ++expDiff;
 +            }
 +        }
 +        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
 +        zx.sign = bx.sign;
 +        zx.sig = add64( zx.sig, bx.sig );
 +    }
 +    else {
 +        zx = bx;
 +        zx.exp = ax.exp;
 +        if ( 56 < expDiff ) {
 +            zx.sig.a1 = 1;
 +            zx.sig.a0 = 0;
 +        }
 +        else {
 +            while ( 0 < expDiff ) {
 +                zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +                --expDiff;
 +            }
 +        }
 +        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
 +        zx.sign = ax.sign;
 +        zx.sig = add64( zx.sig, ax.sig );
 +    }
 +    if ( zx.sig.a0 & 0x80000000 ) {
 +        zx.sig = neg64( zx.sig );
 +        zx.sign = ! zx.sign;
 +    }
 +    return zx;
 +
 +}
 +
 +static floatX floatXMul( floatX ax, floatX bx )
 +{
 +    int8 bitNum;
 +    floatX zx;
 +
 +    if ( ax.isNaN ) return ax;
 +    if ( bx.isNaN ) return bx;
 +    if ( ax.isInf ) {
 +        if ( bx.isZero ) return floatXInvalid();
 +        if ( bx.sign ) ax.sign = ! ax.sign;
 +        return ax;
 +    }
 +    if ( bx.isInf ) {
 +        if ( ax.isZero ) return floatXInvalid();
 +        if ( ax.sign ) bx.sign = ! bx.sign;
 +        return bx;
 +    }
 +    zx = ax;
 +    zx.sign ^= bx.sign;
 +    if ( ax.isZero || bx.isZero ) {
 +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
 +    }
 +    zx.exp += bx.exp + 1;
 +    zx.sig.a1 = 0;
 +    zx.sig.a0 = 0;
 +    for ( bitNum = 0; bitNum < 55; ++bitNum ) {
 +        if ( bx.sig.a1 & 2 ) zx.sig = add64( zx.sig, ax.sig );
 +        bx.sig = shortShift64RightJamming( bx.sig, 1 );
 +        zx.sig = shortShift64RightJamming( zx.sig, 1 );
 +    }
 +    return zx;
 +
 +}
 +
 +static floatX floatXDiv( floatX ax, floatX bx )
 +{
 +    bits64X negBSig;
 +    int8 bitNum;
 +    floatX zx;
 +
 +    if ( ax.isNaN ) return ax;
 +    if ( bx.isNaN ) return bx;
 +    if ( ax.isInf ) {
 +        if ( bx.isInf ) return floatXInvalid();
 +        if ( bx.sign ) ax.sign = ! ax.sign;
 +        return ax;
 +    }
 +    if ( bx.isZero ) {
 +        if ( ax.isZero ) return floatXInvalid();
 +        slow_float_exception_flags |= float_flag_divbyzero;
 +        if ( ax.sign ) bx.sign = ! bx.sign;
 +        bx.isZero = FALSE;
 +        bx.isInf = TRUE;
 +        return bx;
 +    }
 +    zx = ax;
 +    zx.sign ^= bx.sign;
 +    if ( ax.isZero || bx.isInf ) {
 +        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
 +    }
 +    zx.exp -= bx.exp + 1;
 +    zx.sig.a1 = 0;
 +    zx.sig.a0 = 0;
 +    negBSig = neg64( bx.sig );
 +    for ( bitNum = 0; bitNum < 56; ++bitNum ) {
 +        if ( le64( bx.sig, ax.sig ) ) {
 +            zx.sig.a1 |= 1;
 +            ax.sig = add64( ax.sig, negBSig );
 +        }
 +        ax.sig = shortShift64Left( ax.sig, 1 );
 +        zx.sig = shortShift64Left( zx.sig, 1 );
 +    }
 +    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
 +    return zx;
 +
 +}
 +
 +static floatX floatXRem( floatX ax, floatX bx )
 +{
 +    bits64X negBSig;
 +    flag lastQuotientBit;
 +    bits64X savedASig;
 +
 +    if ( ax.isNaN ) return ax;
 +    if ( bx.isNaN ) return bx;
 +    if ( ax.isInf || bx.isZero ) return floatXInvalid();
 +    if ( ax.isZero || bx.isInf ) return ax;
 +    --bx.exp;
 +    if ( ax.exp < bx.exp ) return ax;
 +    bx.sig = shortShift64Left( bx.sig, 1 );
 +    negBSig = neg64( bx.sig );
 +    while ( bx.exp < ax.exp ) {
 +        if ( le64( bx.sig, ax.sig ) ) ax.sig = add64( ax.sig, negBSig );
 +        ax.sig = shortShift64Left( ax.sig, 1 );
 +        --ax.exp;
 +    }
 +    lastQuotientBit = le64( bx.sig, ax.sig );
 +    if ( lastQuotientBit ) ax.sig = add64( ax.sig, negBSig );
 +    savedASig = ax.sig;
 +    ax.sig = neg64( add64( ax.sig, negBSig ) );
 +    if ( lt64( ax.sig, savedASig ) ) {
 +        ax.sign = ! ax.sign;
 +    }
 +    else if ( lt64( savedASig, ax.sig ) ) {
 +        ax.sig = savedASig;
 +    }
 +    else {
 +        if ( lastQuotientBit ) {
 +            ax.sign = ! ax.sign;
 +        }
 +        else {
 +            ax.sig = savedASig;
 +        }
 +    }
 +    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
 +    return ax;
 +
 +}
 +
 +static floatX floatXSqrt( floatX ax )
 
 *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-sparc64 mailing list