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