xref: /freebsd/lib/libc/softfloat/bits64/softfloat-macros (revision c36abe0dcf91e964fbb194f3f8589dc8f05cd146)
1*c36abe0dSDavid Schultz/* $NetBSD: softfloat-macros,v 1.2 2009/02/16 10:23:35 tron Exp $ */
215144b0fSOlivier Houchard/* $FreeBSD$ */
315144b0fSOlivier Houchard
415144b0fSOlivier Houchard/*
515144b0fSOlivier Houchard===============================================================================
615144b0fSOlivier Houchard
715144b0fSOlivier HouchardThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point
815144b0fSOlivier HouchardArithmetic Package, Release 2a.
915144b0fSOlivier Houchard
1015144b0fSOlivier HouchardWritten by John R. Hauser.  This work was made possible in part by the
1115144b0fSOlivier HouchardInternational Computer Science Institute, located at Suite 600, 1947 Center
1215144b0fSOlivier HouchardStreet, Berkeley, California 94704.  Funding was partially provided by the
1315144b0fSOlivier HouchardNational Science Foundation under grant MIP-9311980.  The original version
1415144b0fSOlivier Houchardof this code was written as part of a project to build a fixed-point vector
1515144b0fSOlivier Houchardprocessor in collaboration with the University of California at Berkeley,
1615144b0fSOlivier Houchardoverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
1715144b0fSOlivier Houchardis available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
1815144b0fSOlivier Houchardarithmetic/SoftFloat.html'.
1915144b0fSOlivier Houchard
2015144b0fSOlivier HouchardTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
2115144b0fSOlivier Houchardhas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
2215144b0fSOlivier HouchardTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
2315144b0fSOlivier HouchardPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
2415144b0fSOlivier HouchardAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
2515144b0fSOlivier Houchard
2615144b0fSOlivier HouchardDerivative works are acceptable, even for commercial purposes, so long as
2715144b0fSOlivier Houchard(1) they include prominent notice that the work is derivative, and (2) they
2815144b0fSOlivier Houchardinclude prominent notice akin to these four paragraphs for those parts of
2915144b0fSOlivier Houchardthis code that are retained.
3015144b0fSOlivier Houchard
3115144b0fSOlivier Houchard===============================================================================
3215144b0fSOlivier Houchard*/
3315144b0fSOlivier Houchard
3415144b0fSOlivier Houchard/*
3515144b0fSOlivier Houchard-------------------------------------------------------------------------------
3615144b0fSOlivier HouchardShifts `a' right by the number of bits given in `count'.  If any nonzero
3715144b0fSOlivier Houchardbits are shifted off, they are ``jammed'' into the least significant bit of
3815144b0fSOlivier Houchardthe result by setting the least significant bit to 1.  The value of `count'
3915144b0fSOlivier Houchardcan be arbitrarily large; in particular, if `count' is greater than 32, the
4015144b0fSOlivier Houchardresult will be either 0 or 1, depending on whether `a' is zero or nonzero.
4115144b0fSOlivier HouchardThe result is stored in the location pointed to by `zPtr'.
4215144b0fSOlivier Houchard-------------------------------------------------------------------------------
4315144b0fSOlivier Houchard*/
4415144b0fSOlivier HouchardINLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
4515144b0fSOlivier Houchard{
4615144b0fSOlivier Houchard    bits32 z;
4715144b0fSOlivier Houchard
4815144b0fSOlivier Houchard    if ( count == 0 ) {
4915144b0fSOlivier Houchard        z = a;
5015144b0fSOlivier Houchard    }
5115144b0fSOlivier Houchard    else if ( count < 32 ) {
5215144b0fSOlivier Houchard        z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
5315144b0fSOlivier Houchard    }
5415144b0fSOlivier Houchard    else {
5515144b0fSOlivier Houchard        z = ( a != 0 );
5615144b0fSOlivier Houchard    }
5715144b0fSOlivier Houchard    *zPtr = z;
5815144b0fSOlivier Houchard
5915144b0fSOlivier Houchard}
6015144b0fSOlivier Houchard
6115144b0fSOlivier Houchard/*
6215144b0fSOlivier Houchard-------------------------------------------------------------------------------
6315144b0fSOlivier HouchardShifts `a' right by the number of bits given in `count'.  If any nonzero
6415144b0fSOlivier Houchardbits are shifted off, they are ``jammed'' into the least significant bit of
6515144b0fSOlivier Houchardthe result by setting the least significant bit to 1.  The value of `count'
6615144b0fSOlivier Houchardcan be arbitrarily large; in particular, if `count' is greater than 64, the
6715144b0fSOlivier Houchardresult will be either 0 or 1, depending on whether `a' is zero or nonzero.
6815144b0fSOlivier HouchardThe result is stored in the location pointed to by `zPtr'.
6915144b0fSOlivier Houchard-------------------------------------------------------------------------------
7015144b0fSOlivier Houchard*/
7115144b0fSOlivier HouchardINLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
7215144b0fSOlivier Houchard{
7315144b0fSOlivier Houchard    bits64 z;
7415144b0fSOlivier Houchard
7515144b0fSOlivier Houchard    if ( count == 0 ) {
7615144b0fSOlivier Houchard        z = a;
7715144b0fSOlivier Houchard    }
7815144b0fSOlivier Houchard    else if ( count < 64 ) {
7915144b0fSOlivier Houchard        z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
8015144b0fSOlivier Houchard    }
8115144b0fSOlivier Houchard    else {
8215144b0fSOlivier Houchard        z = ( a != 0 );
8315144b0fSOlivier Houchard    }
8415144b0fSOlivier Houchard    *zPtr = z;
8515144b0fSOlivier Houchard
8615144b0fSOlivier Houchard}
8715144b0fSOlivier Houchard
8815144b0fSOlivier Houchard/*
8915144b0fSOlivier Houchard-------------------------------------------------------------------------------
9015144b0fSOlivier HouchardShifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
9115144b0fSOlivier Houchard_plus_ the number of bits given in `count'.  The shifted result is at most
9215144b0fSOlivier Houchard64 nonzero bits; this is stored at the location pointed to by `z0Ptr'.  The
9315144b0fSOlivier Houchardbits shifted off form a second 64-bit result as follows:  The _last_ bit
9415144b0fSOlivier Houchardshifted off is the most-significant bit of the extra result, and the other
9515144b0fSOlivier Houchard63 bits of the extra result are all zero if and only if _all_but_the_last_
9615144b0fSOlivier Houchardbits shifted off were all zero.  This extra result is stored in the location
9715144b0fSOlivier Houchardpointed to by `z1Ptr'.  The value of `count' can be arbitrarily large.
9815144b0fSOlivier Houchard    (This routine makes more sense if `a0' and `a1' are considered to form a
9915144b0fSOlivier Houchardfixed-point value with binary point between `a0' and `a1'.  This fixed-point
10015144b0fSOlivier Houchardvalue is shifted right by the number of bits given in `count', and the
10115144b0fSOlivier Houchardinteger part of the result is returned at the location pointed to by
10215144b0fSOlivier Houchard`z0Ptr'.  The fractional part of the result may be slightly corrupted as
10315144b0fSOlivier Houcharddescribed above, and is returned at the location pointed to by `z1Ptr'.)
10415144b0fSOlivier Houchard-------------------------------------------------------------------------------
10515144b0fSOlivier Houchard*/
10615144b0fSOlivier HouchardINLINE void
10715144b0fSOlivier Houchard shift64ExtraRightJamming(
10815144b0fSOlivier Houchard     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
10915144b0fSOlivier Houchard{
11015144b0fSOlivier Houchard    bits64 z0, z1;
11115144b0fSOlivier Houchard    int8 negCount = ( - count ) & 63;
11215144b0fSOlivier Houchard
11315144b0fSOlivier Houchard    if ( count == 0 ) {
11415144b0fSOlivier Houchard        z1 = a1;
11515144b0fSOlivier Houchard        z0 = a0;
11615144b0fSOlivier Houchard    }
11715144b0fSOlivier Houchard    else if ( count < 64 ) {
11815144b0fSOlivier Houchard        z1 = ( a0<<negCount ) | ( a1 != 0 );
11915144b0fSOlivier Houchard        z0 = a0>>count;
12015144b0fSOlivier Houchard    }
12115144b0fSOlivier Houchard    else {
12215144b0fSOlivier Houchard        if ( count == 64 ) {
12315144b0fSOlivier Houchard            z1 = a0 | ( a1 != 0 );
12415144b0fSOlivier Houchard        }
12515144b0fSOlivier Houchard        else {
12615144b0fSOlivier Houchard            z1 = ( ( a0 | a1 ) != 0 );
12715144b0fSOlivier Houchard        }
12815144b0fSOlivier Houchard        z0 = 0;
12915144b0fSOlivier Houchard    }
13015144b0fSOlivier Houchard    *z1Ptr = z1;
13115144b0fSOlivier Houchard    *z0Ptr = z0;
13215144b0fSOlivier Houchard
13315144b0fSOlivier Houchard}
13415144b0fSOlivier Houchard
13515144b0fSOlivier Houchard/*
13615144b0fSOlivier Houchard-------------------------------------------------------------------------------
13715144b0fSOlivier HouchardShifts the 128-bit value formed by concatenating `a0' and `a1' right by the
13815144b0fSOlivier Houchardnumber of bits given in `count'.  Any bits shifted off are lost.  The value
13915144b0fSOlivier Houchardof `count' can be arbitrarily large; in particular, if `count' is greater
14015144b0fSOlivier Houchardthan 128, the result will be 0.  The result is broken into two 64-bit pieces
14115144b0fSOlivier Houchardwhich are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
14215144b0fSOlivier Houchard-------------------------------------------------------------------------------
14315144b0fSOlivier Houchard*/
14415144b0fSOlivier HouchardINLINE void
14515144b0fSOlivier Houchard shift128Right(
14615144b0fSOlivier Houchard     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
14715144b0fSOlivier Houchard{
14815144b0fSOlivier Houchard    bits64 z0, z1;
14915144b0fSOlivier Houchard    int8 negCount = ( - count ) & 63;
15015144b0fSOlivier Houchard
15115144b0fSOlivier Houchard    if ( count == 0 ) {
15215144b0fSOlivier Houchard        z1 = a1;
15315144b0fSOlivier Houchard        z0 = a0;
15415144b0fSOlivier Houchard    }
15515144b0fSOlivier Houchard    else if ( count < 64 ) {
15615144b0fSOlivier Houchard        z1 = ( a0<<negCount ) | ( a1>>count );
15715144b0fSOlivier Houchard        z0 = a0>>count;
15815144b0fSOlivier Houchard    }
15915144b0fSOlivier Houchard    else {
16015144b0fSOlivier Houchard        z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
16115144b0fSOlivier Houchard        z0 = 0;
16215144b0fSOlivier Houchard    }
16315144b0fSOlivier Houchard    *z1Ptr = z1;
16415144b0fSOlivier Houchard    *z0Ptr = z0;
16515144b0fSOlivier Houchard
16615144b0fSOlivier Houchard}
16715144b0fSOlivier Houchard
16815144b0fSOlivier Houchard/*
16915144b0fSOlivier Houchard-------------------------------------------------------------------------------
17015144b0fSOlivier HouchardShifts the 128-bit value formed by concatenating `a0' and `a1' right by the
17115144b0fSOlivier Houchardnumber of bits given in `count'.  If any nonzero bits are shifted off, they
17215144b0fSOlivier Houchardare ``jammed'' into the least significant bit of the result by setting the
17315144b0fSOlivier Houchardleast significant bit to 1.  The value of `count' can be arbitrarily large;
17415144b0fSOlivier Houchardin particular, if `count' is greater than 128, the result will be either
17515144b0fSOlivier Houchard0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
17615144b0fSOlivier Houchardnonzero.  The result is broken into two 64-bit pieces which are stored at
17715144b0fSOlivier Houchardthe locations pointed to by `z0Ptr' and `z1Ptr'.
17815144b0fSOlivier Houchard-------------------------------------------------------------------------------
17915144b0fSOlivier Houchard*/
18015144b0fSOlivier HouchardINLINE void
18115144b0fSOlivier Houchard shift128RightJamming(
18215144b0fSOlivier Houchard     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
18315144b0fSOlivier Houchard{
18415144b0fSOlivier Houchard    bits64 z0, z1;
18515144b0fSOlivier Houchard    int8 negCount = ( - count ) & 63;
18615144b0fSOlivier Houchard
18715144b0fSOlivier Houchard    if ( count == 0 ) {
18815144b0fSOlivier Houchard        z1 = a1;
18915144b0fSOlivier Houchard        z0 = a0;
19015144b0fSOlivier Houchard    }
19115144b0fSOlivier Houchard    else if ( count < 64 ) {
19215144b0fSOlivier Houchard        z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
19315144b0fSOlivier Houchard        z0 = a0>>count;
19415144b0fSOlivier Houchard    }
19515144b0fSOlivier Houchard    else {
19615144b0fSOlivier Houchard        if ( count == 64 ) {
19715144b0fSOlivier Houchard            z1 = a0 | ( a1 != 0 );
19815144b0fSOlivier Houchard        }
19915144b0fSOlivier Houchard        else if ( count < 128 ) {
20015144b0fSOlivier Houchard            z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
20115144b0fSOlivier Houchard        }
20215144b0fSOlivier Houchard        else {
20315144b0fSOlivier Houchard            z1 = ( ( a0 | a1 ) != 0 );
20415144b0fSOlivier Houchard        }
20515144b0fSOlivier Houchard        z0 = 0;
20615144b0fSOlivier Houchard    }
20715144b0fSOlivier Houchard    *z1Ptr = z1;
20815144b0fSOlivier Houchard    *z0Ptr = z0;
20915144b0fSOlivier Houchard
21015144b0fSOlivier Houchard}
21115144b0fSOlivier Houchard
21215144b0fSOlivier Houchard/*
21315144b0fSOlivier Houchard-------------------------------------------------------------------------------
21415144b0fSOlivier HouchardShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
21515144b0fSOlivier Houchardby 64 _plus_ the number of bits given in `count'.  The shifted result is
21615144b0fSOlivier Houchardat most 128 nonzero bits; these are broken into two 64-bit pieces which are
21715144b0fSOlivier Houchardstored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
21815144b0fSOlivier Houchardoff form a third 64-bit result as follows:  The _last_ bit shifted off is
21915144b0fSOlivier Houchardthe most-significant bit of the extra result, and the other 63 bits of the
22015144b0fSOlivier Houchardextra result are all zero if and only if _all_but_the_last_ bits shifted off
22115144b0fSOlivier Houchardwere all zero.  This extra result is stored in the location pointed to by
22215144b0fSOlivier Houchard`z2Ptr'.  The value of `count' can be arbitrarily large.
22315144b0fSOlivier Houchard    (This routine makes more sense if `a0', `a1', and `a2' are considered
22415144b0fSOlivier Houchardto form a fixed-point value with binary point between `a1' and `a2'.  This
22515144b0fSOlivier Houchardfixed-point value is shifted right by the number of bits given in `count',
22615144b0fSOlivier Houchardand the integer part of the result is returned at the locations pointed to
22715144b0fSOlivier Houchardby `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
22815144b0fSOlivier Houchardcorrupted as described above, and is returned at the location pointed to by
22915144b0fSOlivier Houchard`z2Ptr'.)
23015144b0fSOlivier Houchard-------------------------------------------------------------------------------
23115144b0fSOlivier Houchard*/
23215144b0fSOlivier HouchardINLINE void
23315144b0fSOlivier Houchard shift128ExtraRightJamming(
23415144b0fSOlivier Houchard     bits64 a0,
23515144b0fSOlivier Houchard     bits64 a1,
23615144b0fSOlivier Houchard     bits64 a2,
23715144b0fSOlivier Houchard     int16 count,
23815144b0fSOlivier Houchard     bits64 *z0Ptr,
23915144b0fSOlivier Houchard     bits64 *z1Ptr,
24015144b0fSOlivier Houchard     bits64 *z2Ptr
24115144b0fSOlivier Houchard )
24215144b0fSOlivier Houchard{
24315144b0fSOlivier Houchard    bits64 z0, z1, z2;
24415144b0fSOlivier Houchard    int8 negCount = ( - count ) & 63;
24515144b0fSOlivier Houchard
24615144b0fSOlivier Houchard    if ( count == 0 ) {
24715144b0fSOlivier Houchard        z2 = a2;
24815144b0fSOlivier Houchard        z1 = a1;
24915144b0fSOlivier Houchard        z0 = a0;
25015144b0fSOlivier Houchard    }
25115144b0fSOlivier Houchard    else {
25215144b0fSOlivier Houchard        if ( count < 64 ) {
25315144b0fSOlivier Houchard            z2 = a1<<negCount;
25415144b0fSOlivier Houchard            z1 = ( a0<<negCount ) | ( a1>>count );
25515144b0fSOlivier Houchard            z0 = a0>>count;
25615144b0fSOlivier Houchard        }
25715144b0fSOlivier Houchard        else {
25815144b0fSOlivier Houchard            if ( count == 64 ) {
25915144b0fSOlivier Houchard                z2 = a1;
26015144b0fSOlivier Houchard                z1 = a0;
26115144b0fSOlivier Houchard            }
26215144b0fSOlivier Houchard            else {
26315144b0fSOlivier Houchard                a2 |= a1;
26415144b0fSOlivier Houchard                if ( count < 128 ) {
26515144b0fSOlivier Houchard                    z2 = a0<<negCount;
26615144b0fSOlivier Houchard                    z1 = a0>>( count & 63 );
26715144b0fSOlivier Houchard                }
26815144b0fSOlivier Houchard                else {
26915144b0fSOlivier Houchard                    z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
27015144b0fSOlivier Houchard                    z1 = 0;
27115144b0fSOlivier Houchard                }
27215144b0fSOlivier Houchard            }
27315144b0fSOlivier Houchard            z0 = 0;
27415144b0fSOlivier Houchard        }
27515144b0fSOlivier Houchard        z2 |= ( a2 != 0 );
27615144b0fSOlivier Houchard    }
27715144b0fSOlivier Houchard    *z2Ptr = z2;
27815144b0fSOlivier Houchard    *z1Ptr = z1;
27915144b0fSOlivier Houchard    *z0Ptr = z0;
28015144b0fSOlivier Houchard
28115144b0fSOlivier Houchard}
28215144b0fSOlivier Houchard
28315144b0fSOlivier Houchard/*
28415144b0fSOlivier Houchard-------------------------------------------------------------------------------
28515144b0fSOlivier HouchardShifts the 128-bit value formed by concatenating `a0' and `a1' left by the
28615144b0fSOlivier Houchardnumber of bits given in `count'.  Any bits shifted off are lost.  The value
28715144b0fSOlivier Houchardof `count' must be less than 64.  The result is broken into two 64-bit
28815144b0fSOlivier Houchardpieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
28915144b0fSOlivier Houchard-------------------------------------------------------------------------------
29015144b0fSOlivier Houchard*/
29115144b0fSOlivier HouchardINLINE void
29215144b0fSOlivier Houchard shortShift128Left(
29315144b0fSOlivier Houchard     bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
29415144b0fSOlivier Houchard{
29515144b0fSOlivier Houchard
29615144b0fSOlivier Houchard    *z1Ptr = a1<<count;
29715144b0fSOlivier Houchard    *z0Ptr =
29815144b0fSOlivier Houchard        ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
29915144b0fSOlivier Houchard
30015144b0fSOlivier Houchard}
30115144b0fSOlivier Houchard
30215144b0fSOlivier Houchard/*
30315144b0fSOlivier Houchard-------------------------------------------------------------------------------
30415144b0fSOlivier HouchardShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
30515144b0fSOlivier Houchardby the number of bits given in `count'.  Any bits shifted off are lost.
30615144b0fSOlivier HouchardThe value of `count' must be less than 64.  The result is broken into three
30715144b0fSOlivier Houchard64-bit pieces which are stored at the locations pointed to by `z0Ptr',
30815144b0fSOlivier Houchard`z1Ptr', and `z2Ptr'.
30915144b0fSOlivier Houchard-------------------------------------------------------------------------------
31015144b0fSOlivier Houchard*/
31115144b0fSOlivier HouchardINLINE void
31215144b0fSOlivier Houchard shortShift192Left(
31315144b0fSOlivier Houchard     bits64 a0,
31415144b0fSOlivier Houchard     bits64 a1,
31515144b0fSOlivier Houchard     bits64 a2,
31615144b0fSOlivier Houchard     int16 count,
31715144b0fSOlivier Houchard     bits64 *z0Ptr,
31815144b0fSOlivier Houchard     bits64 *z1Ptr,
31915144b0fSOlivier Houchard     bits64 *z2Ptr
32015144b0fSOlivier Houchard )
32115144b0fSOlivier Houchard{
32215144b0fSOlivier Houchard    bits64 z0, z1, z2;
32315144b0fSOlivier Houchard    int8 negCount;
32415144b0fSOlivier Houchard
32515144b0fSOlivier Houchard    z2 = a2<<count;
32615144b0fSOlivier Houchard    z1 = a1<<count;
32715144b0fSOlivier Houchard    z0 = a0<<count;
32815144b0fSOlivier Houchard    if ( 0 < count ) {
32915144b0fSOlivier Houchard        negCount = ( ( - count ) & 63 );
33015144b0fSOlivier Houchard        z1 |= a2>>negCount;
33115144b0fSOlivier Houchard        z0 |= a1>>negCount;
33215144b0fSOlivier Houchard    }
33315144b0fSOlivier Houchard    *z2Ptr = z2;
33415144b0fSOlivier Houchard    *z1Ptr = z1;
33515144b0fSOlivier Houchard    *z0Ptr = z0;
33615144b0fSOlivier Houchard
33715144b0fSOlivier Houchard}
33815144b0fSOlivier Houchard
33915144b0fSOlivier Houchard/*
34015144b0fSOlivier Houchard-------------------------------------------------------------------------------
34115144b0fSOlivier HouchardAdds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
34215144b0fSOlivier Houchardvalue formed by concatenating `b0' and `b1'.  Addition is modulo 2^128, so
34315144b0fSOlivier Houchardany carry out is lost.  The result is broken into two 64-bit pieces which
34415144b0fSOlivier Houchardare stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
34515144b0fSOlivier Houchard-------------------------------------------------------------------------------
34615144b0fSOlivier Houchard*/
34715144b0fSOlivier HouchardINLINE void
34815144b0fSOlivier Houchard add128(
34915144b0fSOlivier Houchard     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
35015144b0fSOlivier Houchard{
35115144b0fSOlivier Houchard    bits64 z1;
35215144b0fSOlivier Houchard
35315144b0fSOlivier Houchard    z1 = a1 + b1;
35415144b0fSOlivier Houchard    *z1Ptr = z1;
35515144b0fSOlivier Houchard    *z0Ptr = a0 + b0 + ( z1 < a1 );
35615144b0fSOlivier Houchard
35715144b0fSOlivier Houchard}
35815144b0fSOlivier Houchard
35915144b0fSOlivier Houchard/*
36015144b0fSOlivier Houchard-------------------------------------------------------------------------------
36115144b0fSOlivier HouchardAdds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
36215144b0fSOlivier Houchard192-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
36315144b0fSOlivier Houchardmodulo 2^192, so any carry out is lost.  The result is broken into three
36415144b0fSOlivier Houchard64-bit pieces which are stored at the locations pointed to by `z0Ptr',
36515144b0fSOlivier Houchard`z1Ptr', and `z2Ptr'.
36615144b0fSOlivier Houchard-------------------------------------------------------------------------------
36715144b0fSOlivier Houchard*/
36815144b0fSOlivier HouchardINLINE void
36915144b0fSOlivier Houchard add192(
37015144b0fSOlivier Houchard     bits64 a0,
37115144b0fSOlivier Houchard     bits64 a1,
37215144b0fSOlivier Houchard     bits64 a2,
37315144b0fSOlivier Houchard     bits64 b0,
37415144b0fSOlivier Houchard     bits64 b1,
37515144b0fSOlivier Houchard     bits64 b2,
37615144b0fSOlivier Houchard     bits64 *z0Ptr,
37715144b0fSOlivier Houchard     bits64 *z1Ptr,
37815144b0fSOlivier Houchard     bits64 *z2Ptr
37915144b0fSOlivier Houchard )
38015144b0fSOlivier Houchard{
38115144b0fSOlivier Houchard    bits64 z0, z1, z2;
38215144b0fSOlivier Houchard    int8 carry0, carry1;
38315144b0fSOlivier Houchard
38415144b0fSOlivier Houchard    z2 = a2 + b2;
38515144b0fSOlivier Houchard    carry1 = ( z2 < a2 );
38615144b0fSOlivier Houchard    z1 = a1 + b1;
38715144b0fSOlivier Houchard    carry0 = ( z1 < a1 );
38815144b0fSOlivier Houchard    z0 = a0 + b0;
38915144b0fSOlivier Houchard    z1 += carry1;
390*c36abe0dSDavid Schultz    z0 += ( z1 < (bits64)carry1 );
39115144b0fSOlivier Houchard    z0 += carry0;
39215144b0fSOlivier Houchard    *z2Ptr = z2;
39315144b0fSOlivier Houchard    *z1Ptr = z1;
39415144b0fSOlivier Houchard    *z0Ptr = z0;
39515144b0fSOlivier Houchard
39615144b0fSOlivier Houchard}
39715144b0fSOlivier Houchard
39815144b0fSOlivier Houchard/*
39915144b0fSOlivier Houchard-------------------------------------------------------------------------------
40015144b0fSOlivier HouchardSubtracts the 128-bit value formed by concatenating `b0' and `b1' from the
40115144b0fSOlivier Houchard128-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
40215144b0fSOlivier Houchard2^128, so any borrow out (carry out) is lost.  The result is broken into two
40315144b0fSOlivier Houchard64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
40415144b0fSOlivier Houchard`z1Ptr'.
40515144b0fSOlivier Houchard-------------------------------------------------------------------------------
40615144b0fSOlivier Houchard*/
40715144b0fSOlivier HouchardINLINE void
40815144b0fSOlivier Houchard sub128(
40915144b0fSOlivier Houchard     bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
41015144b0fSOlivier Houchard{
41115144b0fSOlivier Houchard
41215144b0fSOlivier Houchard    *z1Ptr = a1 - b1;
41315144b0fSOlivier Houchard    *z0Ptr = a0 - b0 - ( a1 < b1 );
41415144b0fSOlivier Houchard
41515144b0fSOlivier Houchard}
41615144b0fSOlivier Houchard
41715144b0fSOlivier Houchard/*
41815144b0fSOlivier Houchard-------------------------------------------------------------------------------
41915144b0fSOlivier HouchardSubtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
42015144b0fSOlivier Houchardfrom the 192-bit value formed by concatenating `a0', `a1', and `a2'.
42115144b0fSOlivier HouchardSubtraction is modulo 2^192, so any borrow out (carry out) is lost.  The
42215144b0fSOlivier Houchardresult is broken into three 64-bit pieces which are stored at the locations
42315144b0fSOlivier Houchardpointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
42415144b0fSOlivier Houchard-------------------------------------------------------------------------------
42515144b0fSOlivier Houchard*/
42615144b0fSOlivier HouchardINLINE void
42715144b0fSOlivier Houchard sub192(
42815144b0fSOlivier Houchard     bits64 a0,
42915144b0fSOlivier Houchard     bits64 a1,
43015144b0fSOlivier Houchard     bits64 a2,
43115144b0fSOlivier Houchard     bits64 b0,
43215144b0fSOlivier Houchard     bits64 b1,
43315144b0fSOlivier Houchard     bits64 b2,
43415144b0fSOlivier Houchard     bits64 *z0Ptr,
43515144b0fSOlivier Houchard     bits64 *z1Ptr,
43615144b0fSOlivier Houchard     bits64 *z2Ptr
43715144b0fSOlivier Houchard )
43815144b0fSOlivier Houchard{
43915144b0fSOlivier Houchard    bits64 z0, z1, z2;
44015144b0fSOlivier Houchard    int8 borrow0, borrow1;
44115144b0fSOlivier Houchard
44215144b0fSOlivier Houchard    z2 = a2 - b2;
44315144b0fSOlivier Houchard    borrow1 = ( a2 < b2 );
44415144b0fSOlivier Houchard    z1 = a1 - b1;
44515144b0fSOlivier Houchard    borrow0 = ( a1 < b1 );
44615144b0fSOlivier Houchard    z0 = a0 - b0;
447*c36abe0dSDavid Schultz    z0 -= ( z1 < (bits64)borrow1 );
44815144b0fSOlivier Houchard    z1 -= borrow1;
44915144b0fSOlivier Houchard    z0 -= borrow0;
45015144b0fSOlivier Houchard    *z2Ptr = z2;
45115144b0fSOlivier Houchard    *z1Ptr = z1;
45215144b0fSOlivier Houchard    *z0Ptr = z0;
45315144b0fSOlivier Houchard
45415144b0fSOlivier Houchard}
45515144b0fSOlivier Houchard
45615144b0fSOlivier Houchard/*
45715144b0fSOlivier Houchard-------------------------------------------------------------------------------
45815144b0fSOlivier HouchardMultiplies `a' by `b' to obtain a 128-bit product.  The product is broken
45915144b0fSOlivier Houchardinto two 64-bit pieces which are stored at the locations pointed to by
46015144b0fSOlivier Houchard`z0Ptr' and `z1Ptr'.
46115144b0fSOlivier Houchard-------------------------------------------------------------------------------
46215144b0fSOlivier Houchard*/
46315144b0fSOlivier HouchardINLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
46415144b0fSOlivier Houchard{
46515144b0fSOlivier Houchard    bits32 aHigh, aLow, bHigh, bLow;
46615144b0fSOlivier Houchard    bits64 z0, zMiddleA, zMiddleB, z1;
46715144b0fSOlivier Houchard
46815144b0fSOlivier Houchard    aLow = a;
46915144b0fSOlivier Houchard    aHigh = a>>32;
47015144b0fSOlivier Houchard    bLow = b;
47115144b0fSOlivier Houchard    bHigh = b>>32;
47215144b0fSOlivier Houchard    z1 = ( (bits64) aLow ) * bLow;
47315144b0fSOlivier Houchard    zMiddleA = ( (bits64) aLow ) * bHigh;
47415144b0fSOlivier Houchard    zMiddleB = ( (bits64) aHigh ) * bLow;
47515144b0fSOlivier Houchard    z0 = ( (bits64) aHigh ) * bHigh;
47615144b0fSOlivier Houchard    zMiddleA += zMiddleB;
47715144b0fSOlivier Houchard    z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
47815144b0fSOlivier Houchard    zMiddleA <<= 32;
47915144b0fSOlivier Houchard    z1 += zMiddleA;
48015144b0fSOlivier Houchard    z0 += ( z1 < zMiddleA );
48115144b0fSOlivier Houchard    *z1Ptr = z1;
48215144b0fSOlivier Houchard    *z0Ptr = z0;
48315144b0fSOlivier Houchard
48415144b0fSOlivier Houchard}
48515144b0fSOlivier Houchard
48615144b0fSOlivier Houchard/*
48715144b0fSOlivier Houchard-------------------------------------------------------------------------------
48815144b0fSOlivier HouchardMultiplies the 128-bit value formed by concatenating `a0' and `a1' by
48915144b0fSOlivier Houchard`b' to obtain a 192-bit product.  The product is broken into three 64-bit
49015144b0fSOlivier Houchardpieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
49115144b0fSOlivier Houchard`z2Ptr'.
49215144b0fSOlivier Houchard-------------------------------------------------------------------------------
49315144b0fSOlivier Houchard*/
49415144b0fSOlivier HouchardINLINE void
49515144b0fSOlivier Houchard mul128By64To192(
49615144b0fSOlivier Houchard     bits64 a0,
49715144b0fSOlivier Houchard     bits64 a1,
49815144b0fSOlivier Houchard     bits64 b,
49915144b0fSOlivier Houchard     bits64 *z0Ptr,
50015144b0fSOlivier Houchard     bits64 *z1Ptr,
50115144b0fSOlivier Houchard     bits64 *z2Ptr
50215144b0fSOlivier Houchard )
50315144b0fSOlivier Houchard{
50415144b0fSOlivier Houchard    bits64 z0, z1, z2, more1;
50515144b0fSOlivier Houchard
50615144b0fSOlivier Houchard    mul64To128( a1, b, &z1, &z2 );
50715144b0fSOlivier Houchard    mul64To128( a0, b, &z0, &more1 );
50815144b0fSOlivier Houchard    add128( z0, more1, 0, z1, &z0, &z1 );
50915144b0fSOlivier Houchard    *z2Ptr = z2;
51015144b0fSOlivier Houchard    *z1Ptr = z1;
51115144b0fSOlivier Houchard    *z0Ptr = z0;
51215144b0fSOlivier Houchard
51315144b0fSOlivier Houchard}
51415144b0fSOlivier Houchard
51515144b0fSOlivier Houchard/*
51615144b0fSOlivier Houchard-------------------------------------------------------------------------------
51715144b0fSOlivier HouchardMultiplies the 128-bit value formed by concatenating `a0' and `a1' to the
51815144b0fSOlivier Houchard128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
51915144b0fSOlivier Houchardproduct.  The product is broken into four 64-bit pieces which are stored at
52015144b0fSOlivier Houchardthe locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
52115144b0fSOlivier Houchard-------------------------------------------------------------------------------
52215144b0fSOlivier Houchard*/
52315144b0fSOlivier HouchardINLINE void
52415144b0fSOlivier Houchard mul128To256(
52515144b0fSOlivier Houchard     bits64 a0,
52615144b0fSOlivier Houchard     bits64 a1,
52715144b0fSOlivier Houchard     bits64 b0,
52815144b0fSOlivier Houchard     bits64 b1,
52915144b0fSOlivier Houchard     bits64 *z0Ptr,
53015144b0fSOlivier Houchard     bits64 *z1Ptr,
53115144b0fSOlivier Houchard     bits64 *z2Ptr,
53215144b0fSOlivier Houchard     bits64 *z3Ptr
53315144b0fSOlivier Houchard )
53415144b0fSOlivier Houchard{
53515144b0fSOlivier Houchard    bits64 z0, z1, z2, z3;
53615144b0fSOlivier Houchard    bits64 more1, more2;
53715144b0fSOlivier Houchard
53815144b0fSOlivier Houchard    mul64To128( a1, b1, &z2, &z3 );
53915144b0fSOlivier Houchard    mul64To128( a1, b0, &z1, &more2 );
54015144b0fSOlivier Houchard    add128( z1, more2, 0, z2, &z1, &z2 );
54115144b0fSOlivier Houchard    mul64To128( a0, b0, &z0, &more1 );
54215144b0fSOlivier Houchard    add128( z0, more1, 0, z1, &z0, &z1 );
54315144b0fSOlivier Houchard    mul64To128( a0, b1, &more1, &more2 );
54415144b0fSOlivier Houchard    add128( more1, more2, 0, z2, &more1, &z2 );
54515144b0fSOlivier Houchard    add128( z0, z1, 0, more1, &z0, &z1 );
54615144b0fSOlivier Houchard    *z3Ptr = z3;
54715144b0fSOlivier Houchard    *z2Ptr = z2;
54815144b0fSOlivier Houchard    *z1Ptr = z1;
54915144b0fSOlivier Houchard    *z0Ptr = z0;
55015144b0fSOlivier Houchard
55115144b0fSOlivier Houchard}
55215144b0fSOlivier Houchard
55315144b0fSOlivier Houchard/*
55415144b0fSOlivier Houchard-------------------------------------------------------------------------------
55515144b0fSOlivier HouchardReturns an approximation to the 64-bit integer quotient obtained by dividing
55615144b0fSOlivier Houchard`b' into the 128-bit value formed by concatenating `a0' and `a1'.  The
55715144b0fSOlivier Houcharddivisor `b' must be at least 2^63.  If q is the exact quotient truncated
55815144b0fSOlivier Houchardtoward zero, the approximation returned lies between q and q + 2 inclusive.
55915144b0fSOlivier HouchardIf the exact quotient q is larger than 64 bits, the maximum positive 64-bit
56015144b0fSOlivier Houchardunsigned integer is returned.
56115144b0fSOlivier Houchard-------------------------------------------------------------------------------
56215144b0fSOlivier Houchard*/
56315144b0fSOlivier Houchardstatic bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
56415144b0fSOlivier Houchard{
56515144b0fSOlivier Houchard    bits64 b0, b1;
56615144b0fSOlivier Houchard    bits64 rem0, rem1, term0, term1;
56715144b0fSOlivier Houchard    bits64 z;
56815144b0fSOlivier Houchard
56915144b0fSOlivier Houchard    if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
57015144b0fSOlivier Houchard    b0 = b>>32;
57115144b0fSOlivier Houchard    z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
57215144b0fSOlivier Houchard    mul64To128( b, z, &term0, &term1 );
57315144b0fSOlivier Houchard    sub128( a0, a1, term0, term1, &rem0, &rem1 );
57415144b0fSOlivier Houchard    while ( ( (sbits64) rem0 ) < 0 ) {
57515144b0fSOlivier Houchard        z -= LIT64( 0x100000000 );
57615144b0fSOlivier Houchard        b1 = b<<32;
57715144b0fSOlivier Houchard        add128( rem0, rem1, b0, b1, &rem0, &rem1 );
57815144b0fSOlivier Houchard    }
57915144b0fSOlivier Houchard    rem0 = ( rem0<<32 ) | ( rem1>>32 );
58015144b0fSOlivier Houchard    z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
58115144b0fSOlivier Houchard    return z;
58215144b0fSOlivier Houchard
58315144b0fSOlivier Houchard}
58415144b0fSOlivier Houchard
58515144b0fSOlivier Houchard#if !defined(SOFTFLOAT_FOR_GCC) || defined(FLOATX80) || defined(FLOAT128)
58615144b0fSOlivier Houchard/*
58715144b0fSOlivier Houchard-------------------------------------------------------------------------------
58815144b0fSOlivier HouchardReturns an approximation to the square root of the 32-bit significand given
58915144b0fSOlivier Houchardby `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
59015144b0fSOlivier Houchard`aExp' (the least significant bit) is 1, the integer returned approximates
59115144b0fSOlivier Houchard2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
59215144b0fSOlivier Houchardis 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
59315144b0fSOlivier Houchardcase, the approximation returned lies strictly within +/-2 of the exact
59415144b0fSOlivier Houchardvalue.
59515144b0fSOlivier Houchard-------------------------------------------------------------------------------
59615144b0fSOlivier Houchard*/
59715144b0fSOlivier Houchardstatic bits32 estimateSqrt32( int16 aExp, bits32 a )
59815144b0fSOlivier Houchard{
59915144b0fSOlivier Houchard    static const bits16 sqrtOddAdjustments[] = {
60015144b0fSOlivier Houchard        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
60115144b0fSOlivier Houchard        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
60215144b0fSOlivier Houchard    };
60315144b0fSOlivier Houchard    static const bits16 sqrtEvenAdjustments[] = {
60415144b0fSOlivier Houchard        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
60515144b0fSOlivier Houchard        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
60615144b0fSOlivier Houchard    };
60715144b0fSOlivier Houchard    int8 idx;
60815144b0fSOlivier Houchard    bits32 z;
60915144b0fSOlivier Houchard
61015144b0fSOlivier Houchard    idx = ( a>>27 ) & 15;
61115144b0fSOlivier Houchard    if ( aExp & 1 ) {
61215144b0fSOlivier Houchard        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ idx ];
61315144b0fSOlivier Houchard        z = ( ( a / z )<<14 ) + ( z<<15 );
61415144b0fSOlivier Houchard        a >>= 1;
61515144b0fSOlivier Houchard    }
61615144b0fSOlivier Houchard    else {
61715144b0fSOlivier Houchard        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ idx ];
61815144b0fSOlivier Houchard        z = a / z + z;
61915144b0fSOlivier Houchard        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
62015144b0fSOlivier Houchard        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
62115144b0fSOlivier Houchard    }
62215144b0fSOlivier Houchard    return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
62315144b0fSOlivier Houchard
62415144b0fSOlivier Houchard}
62515144b0fSOlivier Houchard#endif
62615144b0fSOlivier Houchard
62715144b0fSOlivier Houchard/*
62815144b0fSOlivier Houchard-------------------------------------------------------------------------------
62915144b0fSOlivier HouchardReturns the number of leading 0 bits before the most-significant 1 bit of
63015144b0fSOlivier Houchard`a'.  If `a' is zero, 32 is returned.
63115144b0fSOlivier Houchard-------------------------------------------------------------------------------
63215144b0fSOlivier Houchard*/
63315144b0fSOlivier Houchardstatic int8 countLeadingZeros32( bits32 a )
63415144b0fSOlivier Houchard{
63515144b0fSOlivier Houchard    static const int8 countLeadingZerosHigh[] = {
63615144b0fSOlivier Houchard        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
63715144b0fSOlivier Houchard        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
63815144b0fSOlivier Houchard        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
63915144b0fSOlivier Houchard        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
64015144b0fSOlivier Houchard        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64115144b0fSOlivier Houchard        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64215144b0fSOlivier Houchard        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64315144b0fSOlivier Houchard        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64415144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64515144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64615144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64715144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64815144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64915144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65015144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65115144b0fSOlivier Houchard        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
65215144b0fSOlivier Houchard    };
65315144b0fSOlivier Houchard    int8 shiftCount;
65415144b0fSOlivier Houchard
65515144b0fSOlivier Houchard    shiftCount = 0;
65615144b0fSOlivier Houchard    if ( a < 0x10000 ) {
65715144b0fSOlivier Houchard        shiftCount += 16;
65815144b0fSOlivier Houchard        a <<= 16;
65915144b0fSOlivier Houchard    }
66015144b0fSOlivier Houchard    if ( a < 0x1000000 ) {
66115144b0fSOlivier Houchard        shiftCount += 8;
66215144b0fSOlivier Houchard        a <<= 8;
66315144b0fSOlivier Houchard    }
66415144b0fSOlivier Houchard    shiftCount += countLeadingZerosHigh[ a>>24 ];
66515144b0fSOlivier Houchard    return shiftCount;
66615144b0fSOlivier Houchard
66715144b0fSOlivier Houchard}
66815144b0fSOlivier Houchard
66915144b0fSOlivier Houchard/*
67015144b0fSOlivier Houchard-------------------------------------------------------------------------------
67115144b0fSOlivier HouchardReturns the number of leading 0 bits before the most-significant 1 bit of
67215144b0fSOlivier Houchard`a'.  If `a' is zero, 64 is returned.
67315144b0fSOlivier Houchard-------------------------------------------------------------------------------
67415144b0fSOlivier Houchard*/
67515144b0fSOlivier Houchardstatic int8 countLeadingZeros64( bits64 a )
67615144b0fSOlivier Houchard{
67715144b0fSOlivier Houchard    int8 shiftCount;
67815144b0fSOlivier Houchard
67915144b0fSOlivier Houchard    shiftCount = 0;
68015144b0fSOlivier Houchard    if ( a < ( (bits64) 1 )<<32 ) {
68115144b0fSOlivier Houchard        shiftCount += 32;
68215144b0fSOlivier Houchard    }
68315144b0fSOlivier Houchard    else {
68415144b0fSOlivier Houchard        a >>= 32;
68515144b0fSOlivier Houchard    }
68615144b0fSOlivier Houchard    shiftCount += countLeadingZeros32( a );
68715144b0fSOlivier Houchard    return shiftCount;
68815144b0fSOlivier Houchard
68915144b0fSOlivier Houchard}
69015144b0fSOlivier Houchard
69115144b0fSOlivier Houchard/*
69215144b0fSOlivier Houchard-------------------------------------------------------------------------------
69315144b0fSOlivier HouchardReturns 1 if the 128-bit value formed by concatenating `a0' and `a1'
69415144b0fSOlivier Houchardis equal to the 128-bit value formed by concatenating `b0' and `b1'.
69515144b0fSOlivier HouchardOtherwise, returns 0.
69615144b0fSOlivier Houchard-------------------------------------------------------------------------------
69715144b0fSOlivier Houchard*/
69815144b0fSOlivier HouchardINLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
69915144b0fSOlivier Houchard{
70015144b0fSOlivier Houchard
70115144b0fSOlivier Houchard    return ( a0 == b0 ) && ( a1 == b1 );
70215144b0fSOlivier Houchard
70315144b0fSOlivier Houchard}
70415144b0fSOlivier Houchard
70515144b0fSOlivier Houchard/*
70615144b0fSOlivier Houchard-------------------------------------------------------------------------------
70715144b0fSOlivier HouchardReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
70815144b0fSOlivier Houchardthan or equal to the 128-bit value formed by concatenating `b0' and `b1'.
70915144b0fSOlivier HouchardOtherwise, returns 0.
71015144b0fSOlivier Houchard-------------------------------------------------------------------------------
71115144b0fSOlivier Houchard*/
71215144b0fSOlivier HouchardINLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
71315144b0fSOlivier Houchard{
71415144b0fSOlivier Houchard
71515144b0fSOlivier Houchard    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
71615144b0fSOlivier Houchard
71715144b0fSOlivier Houchard}
71815144b0fSOlivier Houchard
71915144b0fSOlivier Houchard/*
72015144b0fSOlivier Houchard-------------------------------------------------------------------------------
72115144b0fSOlivier HouchardReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
72215144b0fSOlivier Houchardthan the 128-bit value formed by concatenating `b0' and `b1'.  Otherwise,
72315144b0fSOlivier Houchardreturns 0.
72415144b0fSOlivier Houchard-------------------------------------------------------------------------------
72515144b0fSOlivier Houchard*/
72615144b0fSOlivier HouchardINLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
72715144b0fSOlivier Houchard{
72815144b0fSOlivier Houchard
72915144b0fSOlivier Houchard    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
73015144b0fSOlivier Houchard
73115144b0fSOlivier Houchard}
73215144b0fSOlivier Houchard
73315144b0fSOlivier Houchard/*
73415144b0fSOlivier Houchard-------------------------------------------------------------------------------
73515144b0fSOlivier HouchardReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
73615144b0fSOlivier Houchardnot equal to the 128-bit value formed by concatenating `b0' and `b1'.
73715144b0fSOlivier HouchardOtherwise, returns 0.
73815144b0fSOlivier Houchard-------------------------------------------------------------------------------
73915144b0fSOlivier Houchard*/
74015144b0fSOlivier HouchardINLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
74115144b0fSOlivier Houchard{
74215144b0fSOlivier Houchard
74315144b0fSOlivier Houchard    return ( a0 != b0 ) || ( a1 != b1 );
74415144b0fSOlivier Houchard
74515144b0fSOlivier Houchard}
74615144b0fSOlivier Houchard
747