162306a36Sopenharmony_ci
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci===============================================================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point
662306a36Sopenharmony_ciArithmetic Package, Release 2.
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciWritten by John R. Hauser.  This work was made possible in part by the
962306a36Sopenharmony_ciInternational Computer Science Institute, located at Suite 600, 1947 Center
1062306a36Sopenharmony_ciStreet, Berkeley, California 94704.  Funding was partially provided by the
1162306a36Sopenharmony_ciNational Science Foundation under grant MIP-9311980.  The original version
1262306a36Sopenharmony_ciof this code was written as part of a project to build a fixed-point vector
1362306a36Sopenharmony_ciprocessor in collaboration with the University of California at Berkeley,
1462306a36Sopenharmony_cioverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
1562306a36Sopenharmony_ciis available through the web page
1662306a36Sopenharmony_cihttp://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
1962306a36Sopenharmony_cihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
2062306a36Sopenharmony_ciTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
2162306a36Sopenharmony_ciPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
2262306a36Sopenharmony_ciAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciDerivative works are acceptable, even for commercial purposes, so long as
2562306a36Sopenharmony_ci(1) they include prominent notice that the work is derivative, and (2) they
2662306a36Sopenharmony_ciinclude prominent notice akin to these three paragraphs for those parts of
2762306a36Sopenharmony_cithis code that are retained.
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci===============================================================================
3062306a36Sopenharmony_ci*/
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci-------------------------------------------------------------------------------
3462306a36Sopenharmony_ciShifts `a' right by the number of bits given in `count'.  If any nonzero
3562306a36Sopenharmony_cibits are shifted off, they are ``jammed'' into the least significant bit of
3662306a36Sopenharmony_cithe result by setting the least significant bit to 1.  The value of `count'
3762306a36Sopenharmony_cican be arbitrarily large; in particular, if `count' is greater than 32, the
3862306a36Sopenharmony_ciresult will be either 0 or 1, depending on whether `a' is zero or nonzero.
3962306a36Sopenharmony_ciThe result is stored in the location pointed to by `zPtr'.
4062306a36Sopenharmony_ci-------------------------------------------------------------------------------
4162306a36Sopenharmony_ci*/
4262306a36Sopenharmony_ciINLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci    bits32 z;
4562306a36Sopenharmony_ci    if ( count == 0 ) {
4662306a36Sopenharmony_ci        z = a;
4762306a36Sopenharmony_ci    }
4862306a36Sopenharmony_ci    else if ( count < 32 ) {
4962306a36Sopenharmony_ci        z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
5062306a36Sopenharmony_ci    }
5162306a36Sopenharmony_ci    else {
5262306a36Sopenharmony_ci        z = ( a != 0 );
5362306a36Sopenharmony_ci    }
5462306a36Sopenharmony_ci    *zPtr = z;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*
5862306a36Sopenharmony_ci-------------------------------------------------------------------------------
5962306a36Sopenharmony_ciShifts `a' right by the number of bits given in `count'.  If any nonzero
6062306a36Sopenharmony_cibits are shifted off, they are ``jammed'' into the least significant bit of
6162306a36Sopenharmony_cithe result by setting the least significant bit to 1.  The value of `count'
6262306a36Sopenharmony_cican be arbitrarily large; in particular, if `count' is greater than 64, the
6362306a36Sopenharmony_ciresult will be either 0 or 1, depending on whether `a' is zero or nonzero.
6462306a36Sopenharmony_ciThe result is stored in the location pointed to by `zPtr'.
6562306a36Sopenharmony_ci-------------------------------------------------------------------------------
6662306a36Sopenharmony_ci*/
6762306a36Sopenharmony_ciINLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci    bits64 z;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci __asm__("@shift64RightJamming -- start");   
7262306a36Sopenharmony_ci    if ( count == 0 ) {
7362306a36Sopenharmony_ci        z = a;
7462306a36Sopenharmony_ci    }
7562306a36Sopenharmony_ci    else if ( count < 64 ) {
7662306a36Sopenharmony_ci        z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
7762306a36Sopenharmony_ci    }
7862306a36Sopenharmony_ci    else {
7962306a36Sopenharmony_ci        z = ( a != 0 );
8062306a36Sopenharmony_ci    }
8162306a36Sopenharmony_ci __asm__("@shift64RightJamming -- end");   
8262306a36Sopenharmony_ci    *zPtr = z;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*
8662306a36Sopenharmony_ci-------------------------------------------------------------------------------
8762306a36Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
8862306a36Sopenharmony_ci_plus_ the number of bits given in `count'.  The shifted result is at most
8962306a36Sopenharmony_ci64 nonzero bits; this is stored at the location pointed to by `z0Ptr'.  The
9062306a36Sopenharmony_cibits shifted off form a second 64-bit result as follows:  The _last_ bit
9162306a36Sopenharmony_cishifted off is the most-significant bit of the extra result, and the other
9262306a36Sopenharmony_ci63 bits of the extra result are all zero if and only if _all_but_the_last_
9362306a36Sopenharmony_cibits shifted off were all zero.  This extra result is stored in the location
9462306a36Sopenharmony_cipointed to by `z1Ptr'.  The value of `count' can be arbitrarily large.
9562306a36Sopenharmony_ci    (This routine makes more sense if `a0' and `a1' are considered to form a
9662306a36Sopenharmony_cifixed-point value with binary point between `a0' and `a1'.  This fixed-point
9762306a36Sopenharmony_civalue is shifted right by the number of bits given in `count', and the
9862306a36Sopenharmony_ciinteger part of the result is returned at the location pointed to by
9962306a36Sopenharmony_ci`z0Ptr'.  The fractional part of the result may be slightly corrupted as
10062306a36Sopenharmony_cidescribed above, and is returned at the location pointed to by `z1Ptr'.)
10162306a36Sopenharmony_ci-------------------------------------------------------------------------------
10262306a36Sopenharmony_ci*/
10362306a36Sopenharmony_ciINLINE void
10462306a36Sopenharmony_ci shift64ExtraRightJamming(
10562306a36Sopenharmony_ci     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci    bits64 z0, z1;
10862306a36Sopenharmony_ci    int8 negCount = ( - count ) & 63;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci    if ( count == 0 ) {
11162306a36Sopenharmony_ci        z1 = a1;
11262306a36Sopenharmony_ci        z0 = a0;
11362306a36Sopenharmony_ci    }
11462306a36Sopenharmony_ci    else if ( count < 64 ) {
11562306a36Sopenharmony_ci        z1 = ( a0<<negCount ) | ( a1 != 0 );
11662306a36Sopenharmony_ci        z0 = a0>>count;
11762306a36Sopenharmony_ci    }
11862306a36Sopenharmony_ci    else {
11962306a36Sopenharmony_ci        if ( count == 64 ) {
12062306a36Sopenharmony_ci            z1 = a0 | ( a1 != 0 );
12162306a36Sopenharmony_ci        }
12262306a36Sopenharmony_ci        else {
12362306a36Sopenharmony_ci            z1 = ( ( a0 | a1 ) != 0 );
12462306a36Sopenharmony_ci        }
12562306a36Sopenharmony_ci        z0 = 0;
12662306a36Sopenharmony_ci    }
12762306a36Sopenharmony_ci    *z1Ptr = z1;
12862306a36Sopenharmony_ci    *z0Ptr = z0;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/*
13362306a36Sopenharmony_ci-------------------------------------------------------------------------------
13462306a36Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by the
13562306a36Sopenharmony_cinumber of bits given in `count'.  Any bits shifted off are lost.  The value
13662306a36Sopenharmony_ciof `count' can be arbitrarily large; in particular, if `count' is greater
13762306a36Sopenharmony_cithan 128, the result will be 0.  The result is broken into two 64-bit pieces
13862306a36Sopenharmony_ciwhich are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
13962306a36Sopenharmony_ci-------------------------------------------------------------------------------
14062306a36Sopenharmony_ci*/
14162306a36Sopenharmony_ciINLINE void
14262306a36Sopenharmony_ci shift128Right(
14362306a36Sopenharmony_ci     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci    bits64 z0, z1;
14662306a36Sopenharmony_ci    int8 negCount = ( - count ) & 63;
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci    if ( count == 0 ) {
14962306a36Sopenharmony_ci        z1 = a1;
15062306a36Sopenharmony_ci        z0 = a0;
15162306a36Sopenharmony_ci    }
15262306a36Sopenharmony_ci    else if ( count < 64 ) {
15362306a36Sopenharmony_ci        z1 = ( a0<<negCount ) | ( a1>>count );
15462306a36Sopenharmony_ci        z0 = a0>>count;
15562306a36Sopenharmony_ci    }
15662306a36Sopenharmony_ci    else {
15762306a36Sopenharmony_ci        z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
15862306a36Sopenharmony_ci        z0 = 0;
15962306a36Sopenharmony_ci    }
16062306a36Sopenharmony_ci    *z1Ptr = z1;
16162306a36Sopenharmony_ci    *z0Ptr = z0;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/*
16662306a36Sopenharmony_ci-------------------------------------------------------------------------------
16762306a36Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by the
16862306a36Sopenharmony_cinumber of bits given in `count'.  If any nonzero bits are shifted off, they
16962306a36Sopenharmony_ciare ``jammed'' into the least significant bit of the result by setting the
17062306a36Sopenharmony_cileast significant bit to 1.  The value of `count' can be arbitrarily large;
17162306a36Sopenharmony_ciin particular, if `count' is greater than 128, the result will be either 0
17262306a36Sopenharmony_cior 1, depending on whether the concatenation of `a0' and `a1' is zero or
17362306a36Sopenharmony_cinonzero.  The result is broken into two 64-bit pieces which are stored at
17462306a36Sopenharmony_cithe locations pointed to by `z0Ptr' and `z1Ptr'.
17562306a36Sopenharmony_ci-------------------------------------------------------------------------------
17662306a36Sopenharmony_ci*/
17762306a36Sopenharmony_ciINLINE void
17862306a36Sopenharmony_ci shift128RightJamming(
17962306a36Sopenharmony_ci     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci    bits64 z0, z1;
18262306a36Sopenharmony_ci    int8 negCount = ( - count ) & 63;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci    if ( count == 0 ) {
18562306a36Sopenharmony_ci        z1 = a1;
18662306a36Sopenharmony_ci        z0 = a0;
18762306a36Sopenharmony_ci    }
18862306a36Sopenharmony_ci    else if ( count < 64 ) {
18962306a36Sopenharmony_ci        z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
19062306a36Sopenharmony_ci        z0 = a0>>count;
19162306a36Sopenharmony_ci    }
19262306a36Sopenharmony_ci    else {
19362306a36Sopenharmony_ci        if ( count == 64 ) {
19462306a36Sopenharmony_ci            z1 = a0 | ( a1 != 0 );
19562306a36Sopenharmony_ci        }
19662306a36Sopenharmony_ci        else if ( count < 128 ) {
19762306a36Sopenharmony_ci            z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
19862306a36Sopenharmony_ci        }
19962306a36Sopenharmony_ci        else {
20062306a36Sopenharmony_ci            z1 = ( ( a0 | a1 ) != 0 );
20162306a36Sopenharmony_ci        }
20262306a36Sopenharmony_ci        z0 = 0;
20362306a36Sopenharmony_ci    }
20462306a36Sopenharmony_ci    *z1Ptr = z1;
20562306a36Sopenharmony_ci    *z0Ptr = z0;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/*
21062306a36Sopenharmony_ci-------------------------------------------------------------------------------
21162306a36Sopenharmony_ciShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
21262306a36Sopenharmony_ciby 64 _plus_ the number of bits given in `count'.  The shifted result is
21362306a36Sopenharmony_ciat most 128 nonzero bits; these are broken into two 64-bit pieces which are
21462306a36Sopenharmony_cistored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
21562306a36Sopenharmony_cioff form a third 64-bit result as follows:  The _last_ bit shifted off is
21662306a36Sopenharmony_cithe most-significant bit of the extra result, and the other 63 bits of the
21762306a36Sopenharmony_ciextra result are all zero if and only if _all_but_the_last_ bits shifted off
21862306a36Sopenharmony_ciwere all zero.  This extra result is stored in the location pointed to by
21962306a36Sopenharmony_ci`z2Ptr'.  The value of `count' can be arbitrarily large.
22062306a36Sopenharmony_ci    (This routine makes more sense if `a0', `a1', and `a2' are considered
22162306a36Sopenharmony_cito form a fixed-point value with binary point between `a1' and `a2'.  This
22262306a36Sopenharmony_cifixed-point value is shifted right by the number of bits given in `count',
22362306a36Sopenharmony_ciand the integer part of the result is returned at the locations pointed to
22462306a36Sopenharmony_ciby `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
22562306a36Sopenharmony_cicorrupted as described above, and is returned at the location pointed to by
22662306a36Sopenharmony_ci`z2Ptr'.)
22762306a36Sopenharmony_ci-------------------------------------------------------------------------------
22862306a36Sopenharmony_ci*/
22962306a36Sopenharmony_ciINLINE void
23062306a36Sopenharmony_ci shift128ExtraRightJamming(
23162306a36Sopenharmony_ci     bits64 a0,
23262306a36Sopenharmony_ci     bits64 a1,
23362306a36Sopenharmony_ci     bits64 a2,
23462306a36Sopenharmony_ci     int16 count,
23562306a36Sopenharmony_ci     bits64 *z0Ptr,
23662306a36Sopenharmony_ci     bits64 *z1Ptr,
23762306a36Sopenharmony_ci     bits64 *z2Ptr
23862306a36Sopenharmony_ci )
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci    bits64 z0, z1, z2;
24162306a36Sopenharmony_ci    int8 negCount = ( - count ) & 63;
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci    if ( count == 0 ) {
24462306a36Sopenharmony_ci        z2 = a2;
24562306a36Sopenharmony_ci        z1 = a1;
24662306a36Sopenharmony_ci        z0 = a0;
24762306a36Sopenharmony_ci    }
24862306a36Sopenharmony_ci    else {
24962306a36Sopenharmony_ci        if ( count < 64 ) {
25062306a36Sopenharmony_ci            z2 = a1<<negCount;
25162306a36Sopenharmony_ci            z1 = ( a0<<negCount ) | ( a1>>count );
25262306a36Sopenharmony_ci            z0 = a0>>count;
25362306a36Sopenharmony_ci        }
25462306a36Sopenharmony_ci        else {
25562306a36Sopenharmony_ci            if ( count == 64 ) {
25662306a36Sopenharmony_ci                z2 = a1;
25762306a36Sopenharmony_ci                z1 = a0;
25862306a36Sopenharmony_ci            }
25962306a36Sopenharmony_ci            else {
26062306a36Sopenharmony_ci                a2 |= a1;
26162306a36Sopenharmony_ci                if ( count < 128 ) {
26262306a36Sopenharmony_ci                    z2 = a0<<negCount;
26362306a36Sopenharmony_ci                    z1 = a0>>( count & 63 );
26462306a36Sopenharmony_ci                }
26562306a36Sopenharmony_ci                else {
26662306a36Sopenharmony_ci                    z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
26762306a36Sopenharmony_ci                    z1 = 0;
26862306a36Sopenharmony_ci                }
26962306a36Sopenharmony_ci            }
27062306a36Sopenharmony_ci            z0 = 0;
27162306a36Sopenharmony_ci        }
27262306a36Sopenharmony_ci        z2 |= ( a2 != 0 );
27362306a36Sopenharmony_ci    }
27462306a36Sopenharmony_ci    *z2Ptr = z2;
27562306a36Sopenharmony_ci    *z1Ptr = z1;
27662306a36Sopenharmony_ci    *z0Ptr = z0;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/*
28162306a36Sopenharmony_ci-------------------------------------------------------------------------------
28262306a36Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' left by the
28362306a36Sopenharmony_cinumber of bits given in `count'.  Any bits shifted off are lost.  The value
28462306a36Sopenharmony_ciof `count' must be less than 64.  The result is broken into two 64-bit
28562306a36Sopenharmony_cipieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
28662306a36Sopenharmony_ci-------------------------------------------------------------------------------
28762306a36Sopenharmony_ci*/
28862306a36Sopenharmony_ciINLINE void
28962306a36Sopenharmony_ci shortShift128Left(
29062306a36Sopenharmony_ci     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci    *z1Ptr = a1<<count;
29462306a36Sopenharmony_ci    *z0Ptr =
29562306a36Sopenharmony_ci        ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci/*
30062306a36Sopenharmony_ci-------------------------------------------------------------------------------
30162306a36Sopenharmony_ciShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
30262306a36Sopenharmony_ciby the number of bits given in `count'.  Any bits shifted off are lost.
30362306a36Sopenharmony_ciThe value of `count' must be less than 64.  The result is broken into three
30462306a36Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr',
30562306a36Sopenharmony_ci`z1Ptr', and `z2Ptr'.
30662306a36Sopenharmony_ci-------------------------------------------------------------------------------
30762306a36Sopenharmony_ci*/
30862306a36Sopenharmony_ciINLINE void
30962306a36Sopenharmony_ci shortShift192Left(
31062306a36Sopenharmony_ci     bits64 a0,
31162306a36Sopenharmony_ci     bits64 a1,
31262306a36Sopenharmony_ci     bits64 a2,
31362306a36Sopenharmony_ci     int16 count,
31462306a36Sopenharmony_ci     bits64 *z0Ptr,
31562306a36Sopenharmony_ci     bits64 *z1Ptr,
31662306a36Sopenharmony_ci     bits64 *z2Ptr
31762306a36Sopenharmony_ci )
31862306a36Sopenharmony_ci{
31962306a36Sopenharmony_ci    bits64 z0, z1, z2;
32062306a36Sopenharmony_ci    int8 negCount;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci    z2 = a2<<count;
32362306a36Sopenharmony_ci    z1 = a1<<count;
32462306a36Sopenharmony_ci    z0 = a0<<count;
32562306a36Sopenharmony_ci    if ( 0 < count ) {
32662306a36Sopenharmony_ci        negCount = ( ( - count ) & 63 );
32762306a36Sopenharmony_ci        z1 |= a2>>negCount;
32862306a36Sopenharmony_ci        z0 |= a1>>negCount;
32962306a36Sopenharmony_ci    }
33062306a36Sopenharmony_ci    *z2Ptr = z2;
33162306a36Sopenharmony_ci    *z1Ptr = z1;
33262306a36Sopenharmony_ci    *z0Ptr = z0;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci/*
33762306a36Sopenharmony_ci-------------------------------------------------------------------------------
33862306a36Sopenharmony_ciAdds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
33962306a36Sopenharmony_civalue formed by concatenating `b0' and `b1'.  Addition is modulo 2^128, so
34062306a36Sopenharmony_ciany carry out is lost.  The result is broken into two 64-bit pieces which
34162306a36Sopenharmony_ciare stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
34262306a36Sopenharmony_ci-------------------------------------------------------------------------------
34362306a36Sopenharmony_ci*/
34462306a36Sopenharmony_ciINLINE void
34562306a36Sopenharmony_ci add128(
34662306a36Sopenharmony_ci     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
34762306a36Sopenharmony_ci{
34862306a36Sopenharmony_ci    bits64 z1;
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci    z1 = a1 + b1;
35162306a36Sopenharmony_ci    *z1Ptr = z1;
35262306a36Sopenharmony_ci    *z0Ptr = a0 + b0 + ( z1 < a1 );
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci/*
35762306a36Sopenharmony_ci-------------------------------------------------------------------------------
35862306a36Sopenharmony_ciAdds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
35962306a36Sopenharmony_ci192-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
36062306a36Sopenharmony_cimodulo 2^192, so any carry out is lost.  The result is broken into three
36162306a36Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr',
36262306a36Sopenharmony_ci`z1Ptr', and `z2Ptr'.
36362306a36Sopenharmony_ci-------------------------------------------------------------------------------
36462306a36Sopenharmony_ci*/
36562306a36Sopenharmony_ciINLINE void
36662306a36Sopenharmony_ci add192(
36762306a36Sopenharmony_ci     bits64 a0,
36862306a36Sopenharmony_ci     bits64 a1,
36962306a36Sopenharmony_ci     bits64 a2,
37062306a36Sopenharmony_ci     bits64 b0,
37162306a36Sopenharmony_ci     bits64 b1,
37262306a36Sopenharmony_ci     bits64 b2,
37362306a36Sopenharmony_ci     bits64 *z0Ptr,
37462306a36Sopenharmony_ci     bits64 *z1Ptr,
37562306a36Sopenharmony_ci     bits64 *z2Ptr
37662306a36Sopenharmony_ci )
37762306a36Sopenharmony_ci{
37862306a36Sopenharmony_ci    bits64 z0, z1, z2;
37962306a36Sopenharmony_ci    int8 carry0, carry1;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci    z2 = a2 + b2;
38262306a36Sopenharmony_ci    carry1 = ( z2 < a2 );
38362306a36Sopenharmony_ci    z1 = a1 + b1;
38462306a36Sopenharmony_ci    carry0 = ( z1 < a1 );
38562306a36Sopenharmony_ci    z0 = a0 + b0;
38662306a36Sopenharmony_ci    z1 += carry1;
38762306a36Sopenharmony_ci    z0 += ( z1 < carry1 );
38862306a36Sopenharmony_ci    z0 += carry0;
38962306a36Sopenharmony_ci    *z2Ptr = z2;
39062306a36Sopenharmony_ci    *z1Ptr = z1;
39162306a36Sopenharmony_ci    *z0Ptr = z0;
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci}
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci/*
39662306a36Sopenharmony_ci-------------------------------------------------------------------------------
39762306a36Sopenharmony_ciSubtracts the 128-bit value formed by concatenating `b0' and `b1' from the
39862306a36Sopenharmony_ci128-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
39962306a36Sopenharmony_ci2^128, so any borrow out (carry out) is lost.  The result is broken into two
40062306a36Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
40162306a36Sopenharmony_ci`z1Ptr'.
40262306a36Sopenharmony_ci-------------------------------------------------------------------------------
40362306a36Sopenharmony_ci*/
40462306a36Sopenharmony_ciINLINE void
40562306a36Sopenharmony_ci sub128(
40662306a36Sopenharmony_ci     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci    *z1Ptr = a1 - b1;
41062306a36Sopenharmony_ci    *z0Ptr = a0 - b0 - ( a1 < b1 );
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci/*
41562306a36Sopenharmony_ci-------------------------------------------------------------------------------
41662306a36Sopenharmony_ciSubtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
41762306a36Sopenharmony_cifrom the 192-bit value formed by concatenating `a0', `a1', and `a2'.
41862306a36Sopenharmony_ciSubtraction is modulo 2^192, so any borrow out (carry out) is lost.  The
41962306a36Sopenharmony_ciresult is broken into three 64-bit pieces which are stored at the locations
42062306a36Sopenharmony_cipointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
42162306a36Sopenharmony_ci-------------------------------------------------------------------------------
42262306a36Sopenharmony_ci*/
42362306a36Sopenharmony_ciINLINE void
42462306a36Sopenharmony_ci sub192(
42562306a36Sopenharmony_ci     bits64 a0,
42662306a36Sopenharmony_ci     bits64 a1,
42762306a36Sopenharmony_ci     bits64 a2,
42862306a36Sopenharmony_ci     bits64 b0,
42962306a36Sopenharmony_ci     bits64 b1,
43062306a36Sopenharmony_ci     bits64 b2,
43162306a36Sopenharmony_ci     bits64 *z0Ptr,
43262306a36Sopenharmony_ci     bits64 *z1Ptr,
43362306a36Sopenharmony_ci     bits64 *z2Ptr
43462306a36Sopenharmony_ci )
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci    bits64 z0, z1, z2;
43762306a36Sopenharmony_ci    int8 borrow0, borrow1;
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci    z2 = a2 - b2;
44062306a36Sopenharmony_ci    borrow1 = ( a2 < b2 );
44162306a36Sopenharmony_ci    z1 = a1 - b1;
44262306a36Sopenharmony_ci    borrow0 = ( a1 < b1 );
44362306a36Sopenharmony_ci    z0 = a0 - b0;
44462306a36Sopenharmony_ci    z0 -= ( z1 < borrow1 );
44562306a36Sopenharmony_ci    z1 -= borrow1;
44662306a36Sopenharmony_ci    z0 -= borrow0;
44762306a36Sopenharmony_ci    *z2Ptr = z2;
44862306a36Sopenharmony_ci    *z1Ptr = z1;
44962306a36Sopenharmony_ci    *z0Ptr = z0;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci/*
45462306a36Sopenharmony_ci-------------------------------------------------------------------------------
45562306a36Sopenharmony_ciMultiplies `a' by `b' to obtain a 128-bit product.  The product is broken
45662306a36Sopenharmony_ciinto two 64-bit pieces which are stored at the locations pointed to by
45762306a36Sopenharmony_ci`z0Ptr' and `z1Ptr'.
45862306a36Sopenharmony_ci-------------------------------------------------------------------------------
45962306a36Sopenharmony_ci*/
46062306a36Sopenharmony_ciINLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci    bits32 aHigh, aLow, bHigh, bLow;
46362306a36Sopenharmony_ci    bits64 z0, zMiddleA, zMiddleB, z1;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci    aLow = a;
46662306a36Sopenharmony_ci    aHigh = a>>32;
46762306a36Sopenharmony_ci    bLow = b;
46862306a36Sopenharmony_ci    bHigh = b>>32;
46962306a36Sopenharmony_ci    z1 = ( (bits64) aLow ) * bLow;
47062306a36Sopenharmony_ci    zMiddleA = ( (bits64) aLow ) * bHigh;
47162306a36Sopenharmony_ci    zMiddleB = ( (bits64) aHigh ) * bLow;
47262306a36Sopenharmony_ci    z0 = ( (bits64) aHigh ) * bHigh;
47362306a36Sopenharmony_ci    zMiddleA += zMiddleB;
47462306a36Sopenharmony_ci    z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
47562306a36Sopenharmony_ci    zMiddleA <<= 32;
47662306a36Sopenharmony_ci    z1 += zMiddleA;
47762306a36Sopenharmony_ci    z0 += ( z1 < zMiddleA );
47862306a36Sopenharmony_ci    *z1Ptr = z1;
47962306a36Sopenharmony_ci    *z0Ptr = z0;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci}
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci/*
48462306a36Sopenharmony_ci-------------------------------------------------------------------------------
48562306a36Sopenharmony_ciMultiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to
48662306a36Sopenharmony_ciobtain a 192-bit product.  The product is broken into three 64-bit pieces
48762306a36Sopenharmony_ciwhich are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
48862306a36Sopenharmony_ci`z2Ptr'.
48962306a36Sopenharmony_ci-------------------------------------------------------------------------------
49062306a36Sopenharmony_ci*/
49162306a36Sopenharmony_ciINLINE void
49262306a36Sopenharmony_ci mul128By64To192(
49362306a36Sopenharmony_ci     bits64 a0,
49462306a36Sopenharmony_ci     bits64 a1,
49562306a36Sopenharmony_ci     bits64 b,
49662306a36Sopenharmony_ci     bits64 *z0Ptr,
49762306a36Sopenharmony_ci     bits64 *z1Ptr,
49862306a36Sopenharmony_ci     bits64 *z2Ptr
49962306a36Sopenharmony_ci )
50062306a36Sopenharmony_ci{
50162306a36Sopenharmony_ci    bits64 z0, z1, z2, more1;
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci    mul64To128( a1, b, &z1, &z2 );
50462306a36Sopenharmony_ci    mul64To128( a0, b, &z0, &more1 );
50562306a36Sopenharmony_ci    add128( z0, more1, 0, z1, &z0, &z1 );
50662306a36Sopenharmony_ci    *z2Ptr = z2;
50762306a36Sopenharmony_ci    *z1Ptr = z1;
50862306a36Sopenharmony_ci    *z0Ptr = z0;
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci/*
51362306a36Sopenharmony_ci-------------------------------------------------------------------------------
51462306a36Sopenharmony_ciMultiplies the 128-bit value formed by concatenating `a0' and `a1' to the
51562306a36Sopenharmony_ci128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
51662306a36Sopenharmony_ciproduct.  The product is broken into four 64-bit pieces which are stored at
51762306a36Sopenharmony_cithe locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
51862306a36Sopenharmony_ci-------------------------------------------------------------------------------
51962306a36Sopenharmony_ci*/
52062306a36Sopenharmony_ciINLINE void
52162306a36Sopenharmony_ci mul128To256(
52262306a36Sopenharmony_ci     bits64 a0,
52362306a36Sopenharmony_ci     bits64 a1,
52462306a36Sopenharmony_ci     bits64 b0,
52562306a36Sopenharmony_ci     bits64 b1,
52662306a36Sopenharmony_ci     bits64 *z0Ptr,
52762306a36Sopenharmony_ci     bits64 *z1Ptr,
52862306a36Sopenharmony_ci     bits64 *z2Ptr,
52962306a36Sopenharmony_ci     bits64 *z3Ptr
53062306a36Sopenharmony_ci )
53162306a36Sopenharmony_ci{
53262306a36Sopenharmony_ci    bits64 z0, z1, z2, z3;
53362306a36Sopenharmony_ci    bits64 more1, more2;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci    mul64To128( a1, b1, &z2, &z3 );
53662306a36Sopenharmony_ci    mul64To128( a1, b0, &z1, &more2 );
53762306a36Sopenharmony_ci    add128( z1, more2, 0, z2, &z1, &z2 );
53862306a36Sopenharmony_ci    mul64To128( a0, b0, &z0, &more1 );
53962306a36Sopenharmony_ci    add128( z0, more1, 0, z1, &z0, &z1 );
54062306a36Sopenharmony_ci    mul64To128( a0, b1, &more1, &more2 );
54162306a36Sopenharmony_ci    add128( more1, more2, 0, z2, &more1, &z2 );
54262306a36Sopenharmony_ci    add128( z0, z1, 0, more1, &z0, &z1 );
54362306a36Sopenharmony_ci    *z3Ptr = z3;
54462306a36Sopenharmony_ci    *z2Ptr = z2;
54562306a36Sopenharmony_ci    *z1Ptr = z1;
54662306a36Sopenharmony_ci    *z0Ptr = z0;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci}
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci/*
55162306a36Sopenharmony_ci-------------------------------------------------------------------------------
55262306a36Sopenharmony_ciReturns an approximation to the 64-bit integer quotient obtained by dividing
55362306a36Sopenharmony_ci`b' into the 128-bit value formed by concatenating `a0' and `a1'.  The
55462306a36Sopenharmony_cidivisor `b' must be at least 2^63.  If q is the exact quotient truncated
55562306a36Sopenharmony_citoward zero, the approximation returned lies between q and q + 2 inclusive.
55662306a36Sopenharmony_ciIf the exact quotient q is larger than 64 bits, the maximum positive 64-bit
55762306a36Sopenharmony_ciunsigned integer is returned.
55862306a36Sopenharmony_ci-------------------------------------------------------------------------------
55962306a36Sopenharmony_ci*/
56062306a36Sopenharmony_cistatic bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci    bits64 b0, b1;
56362306a36Sopenharmony_ci    bits64 rem0, rem1, term0, term1;
56462306a36Sopenharmony_ci    bits64 z;
56562306a36Sopenharmony_ci    if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
56662306a36Sopenharmony_ci    b0 = b>>32;  /* hence b0 is 32 bits wide now */
56762306a36Sopenharmony_ci    if ( b0<<32 <= a0 ) {
56862306a36Sopenharmony_ci        z = LIT64( 0xFFFFFFFF00000000 );
56962306a36Sopenharmony_ci    }  else {
57062306a36Sopenharmony_ci        z = a0;
57162306a36Sopenharmony_ci        do_div( z, b0 );
57262306a36Sopenharmony_ci        z <<= 32;
57362306a36Sopenharmony_ci    }
57462306a36Sopenharmony_ci    mul64To128( b, z, &term0, &term1 );
57562306a36Sopenharmony_ci    sub128( a0, a1, term0, term1, &rem0, &rem1 );
57662306a36Sopenharmony_ci    while ( ( (sbits64) rem0 ) < 0 ) {
57762306a36Sopenharmony_ci        z -= LIT64( 0x100000000 );
57862306a36Sopenharmony_ci        b1 = b<<32;
57962306a36Sopenharmony_ci        add128( rem0, rem1, b0, b1, &rem0, &rem1 );
58062306a36Sopenharmony_ci    }
58162306a36Sopenharmony_ci    rem0 = ( rem0<<32 ) | ( rem1>>32 );
58262306a36Sopenharmony_ci    if ( b0<<32 <= rem0 ) {
58362306a36Sopenharmony_ci        z |= 0xFFFFFFFF;
58462306a36Sopenharmony_ci    } else {
58562306a36Sopenharmony_ci        do_div( rem0, b0 );
58662306a36Sopenharmony_ci        z |= rem0;
58762306a36Sopenharmony_ci    }
58862306a36Sopenharmony_ci    return z;
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci/*
59362306a36Sopenharmony_ci-------------------------------------------------------------------------------
59462306a36Sopenharmony_ciReturns an approximation to the square root of the 32-bit significand given
59562306a36Sopenharmony_ciby `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
59662306a36Sopenharmony_ci`aExp' (the least significant bit) is 1, the integer returned approximates
59762306a36Sopenharmony_ci2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
59862306a36Sopenharmony_ciis 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
59962306a36Sopenharmony_cicase, the approximation returned lies strictly within +/-2 of the exact
60062306a36Sopenharmony_civalue.
60162306a36Sopenharmony_ci-------------------------------------------------------------------------------
60262306a36Sopenharmony_ci*/
60362306a36Sopenharmony_cistatic bits32 estimateSqrt32( int16 aExp, bits32 a )
60462306a36Sopenharmony_ci{
60562306a36Sopenharmony_ci    static const bits16 sqrtOddAdjustments[] = {
60662306a36Sopenharmony_ci        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
60762306a36Sopenharmony_ci        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
60862306a36Sopenharmony_ci    };
60962306a36Sopenharmony_ci    static const bits16 sqrtEvenAdjustments[] = {
61062306a36Sopenharmony_ci        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
61162306a36Sopenharmony_ci        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
61262306a36Sopenharmony_ci    };
61362306a36Sopenharmony_ci    int8 index;
61462306a36Sopenharmony_ci    bits32 z;
61562306a36Sopenharmony_ci    bits64 A;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci    index = ( a>>27 ) & 15;
61862306a36Sopenharmony_ci    if ( aExp & 1 ) {
61962306a36Sopenharmony_ci        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
62062306a36Sopenharmony_ci        z = ( ( a / z )<<14 ) + ( z<<15 );
62162306a36Sopenharmony_ci        a >>= 1;
62262306a36Sopenharmony_ci    }
62362306a36Sopenharmony_ci    else {
62462306a36Sopenharmony_ci        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
62562306a36Sopenharmony_ci        z = a / z + z;
62662306a36Sopenharmony_ci        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
62762306a36Sopenharmony_ci        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
62862306a36Sopenharmony_ci    }
62962306a36Sopenharmony_ci    A = ( (bits64) a )<<31;
63062306a36Sopenharmony_ci    do_div( A, z );
63162306a36Sopenharmony_ci    return ( (bits32) A ) + ( z>>1 );
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci}
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci/*
63662306a36Sopenharmony_ci-------------------------------------------------------------------------------
63762306a36Sopenharmony_ciReturns the number of leading 0 bits before the most-significant 1 bit
63862306a36Sopenharmony_ciof `a'.  If `a' is zero, 32 is returned.
63962306a36Sopenharmony_ci-------------------------------------------------------------------------------
64062306a36Sopenharmony_ci*/
64162306a36Sopenharmony_cistatic int8 countLeadingZeros32( bits32 a )
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci    static const int8 countLeadingZerosHigh[] = {
64462306a36Sopenharmony_ci        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
64562306a36Sopenharmony_ci        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
64662306a36Sopenharmony_ci        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
64762306a36Sopenharmony_ci        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
64862306a36Sopenharmony_ci        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64962306a36Sopenharmony_ci        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65062306a36Sopenharmony_ci        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65162306a36Sopenharmony_ci        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
65262306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65362306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65462306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65562306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65662306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65762306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65862306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65962306a36Sopenharmony_ci        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
66062306a36Sopenharmony_ci    };
66162306a36Sopenharmony_ci    int8 shiftCount;
66262306a36Sopenharmony_ci
66362306a36Sopenharmony_ci    shiftCount = 0;
66462306a36Sopenharmony_ci    if ( a < 0x10000 ) {
66562306a36Sopenharmony_ci        shiftCount += 16;
66662306a36Sopenharmony_ci        a <<= 16;
66762306a36Sopenharmony_ci    }
66862306a36Sopenharmony_ci    if ( a < 0x1000000 ) {
66962306a36Sopenharmony_ci        shiftCount += 8;
67062306a36Sopenharmony_ci        a <<= 8;
67162306a36Sopenharmony_ci    }
67262306a36Sopenharmony_ci    shiftCount += countLeadingZerosHigh[ a>>24 ];
67362306a36Sopenharmony_ci    return shiftCount;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci/*
67862306a36Sopenharmony_ci-------------------------------------------------------------------------------
67962306a36Sopenharmony_ciReturns the number of leading 0 bits before the most-significant 1 bit
68062306a36Sopenharmony_ciof `a'.  If `a' is zero, 64 is returned.
68162306a36Sopenharmony_ci-------------------------------------------------------------------------------
68262306a36Sopenharmony_ci*/
68362306a36Sopenharmony_cistatic int8 countLeadingZeros64( bits64 a )
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci    int8 shiftCount;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci    shiftCount = 0;
68862306a36Sopenharmony_ci    if ( a < ( (bits64) 1 )<<32 ) {
68962306a36Sopenharmony_ci        shiftCount += 32;
69062306a36Sopenharmony_ci    }
69162306a36Sopenharmony_ci    else {
69262306a36Sopenharmony_ci        a >>= 32;
69362306a36Sopenharmony_ci    }
69462306a36Sopenharmony_ci    shiftCount += countLeadingZeros32( a );
69562306a36Sopenharmony_ci    return shiftCount;
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci}
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci/*
70062306a36Sopenharmony_ci-------------------------------------------------------------------------------
70162306a36Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1'
70262306a36Sopenharmony_ciis equal to the 128-bit value formed by concatenating `b0' and `b1'.
70362306a36Sopenharmony_ciOtherwise, returns 0.
70462306a36Sopenharmony_ci-------------------------------------------------------------------------------
70562306a36Sopenharmony_ci*/
70662306a36Sopenharmony_ciINLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
70762306a36Sopenharmony_ci{
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci    return ( a0 == b0 ) && ( a1 == b1 );
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci/*
71462306a36Sopenharmony_ci-------------------------------------------------------------------------------
71562306a36Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
71662306a36Sopenharmony_cithan or equal to the 128-bit value formed by concatenating `b0' and `b1'.
71762306a36Sopenharmony_ciOtherwise, returns 0.
71862306a36Sopenharmony_ci-------------------------------------------------------------------------------
71962306a36Sopenharmony_ci*/
72062306a36Sopenharmony_ciINLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
72162306a36Sopenharmony_ci{
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci}
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci/*
72862306a36Sopenharmony_ci-------------------------------------------------------------------------------
72962306a36Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
73062306a36Sopenharmony_cithan the 128-bit value formed by concatenating `b0' and `b1'.  Otherwise,
73162306a36Sopenharmony_cireturns 0.
73262306a36Sopenharmony_ci-------------------------------------------------------------------------------
73362306a36Sopenharmony_ci*/
73462306a36Sopenharmony_ciINLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
73562306a36Sopenharmony_ci{
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci/*
74262306a36Sopenharmony_ci-------------------------------------------------------------------------------
74362306a36Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
74462306a36Sopenharmony_cinot equal to the 128-bit value formed by concatenating `b0' and `b1'.
74562306a36Sopenharmony_ciOtherwise, returns 0.
74662306a36Sopenharmony_ci-------------------------------------------------------------------------------
74762306a36Sopenharmony_ci*/
74862306a36Sopenharmony_ciINLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
74962306a36Sopenharmony_ci{
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci    return ( a0 != b0 ) || ( a1 != b1 );
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci}
75462306a36Sopenharmony_ci
755