18c2ecf20Sopenharmony_ci 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci=============================================================================== 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point 68c2ecf20Sopenharmony_ciArithmetic Package, Release 2. 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ciWritten by John R. Hauser. This work was made possible in part by the 98c2ecf20Sopenharmony_ciInternational Computer Science Institute, located at Suite 600, 1947 Center 108c2ecf20Sopenharmony_ciStreet, Berkeley, California 94704. Funding was partially provided by the 118c2ecf20Sopenharmony_ciNational Science Foundation under grant MIP-9311980. The original version 128c2ecf20Sopenharmony_ciof this code was written as part of a project to build a fixed-point vector 138c2ecf20Sopenharmony_ciprocessor in collaboration with the University of California at Berkeley, 148c2ecf20Sopenharmony_cioverseen by Profs. Nelson Morgan and John Wawrzynek. More information 158c2ecf20Sopenharmony_ciis available through the web page 168c2ecf20Sopenharmony_cihttp://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ciTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 198c2ecf20Sopenharmony_cihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 208c2ecf20Sopenharmony_ciTIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 218c2ecf20Sopenharmony_ciPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 228c2ecf20Sopenharmony_ciAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciDerivative works are acceptable, even for commercial purposes, so long as 258c2ecf20Sopenharmony_ci(1) they include prominent notice that the work is derivative, and (2) they 268c2ecf20Sopenharmony_ciinclude prominent notice akin to these three paragraphs for those parts of 278c2ecf20Sopenharmony_cithis code that are retained. 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci=============================================================================== 308c2ecf20Sopenharmony_ci*/ 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 348c2ecf20Sopenharmony_ciShifts `a' right by the number of bits given in `count'. If any nonzero 358c2ecf20Sopenharmony_cibits are shifted off, they are ``jammed'' into the least significant bit of 368c2ecf20Sopenharmony_cithe result by setting the least significant bit to 1. The value of `count' 378c2ecf20Sopenharmony_cican be arbitrarily large; in particular, if `count' is greater than 32, the 388c2ecf20Sopenharmony_ciresult will be either 0 or 1, depending on whether `a' is zero or nonzero. 398c2ecf20Sopenharmony_ciThe result is stored in the location pointed to by `zPtr'. 408c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 418c2ecf20Sopenharmony_ci*/ 428c2ecf20Sopenharmony_ciINLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci bits32 z; 458c2ecf20Sopenharmony_ci if ( count == 0 ) { 468c2ecf20Sopenharmony_ci z = a; 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci else if ( count < 32 ) { 498c2ecf20Sopenharmony_ci z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); 508c2ecf20Sopenharmony_ci } 518c2ecf20Sopenharmony_ci else { 528c2ecf20Sopenharmony_ci z = ( a != 0 ); 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci *zPtr = z; 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 598c2ecf20Sopenharmony_ciShifts `a' right by the number of bits given in `count'. If any nonzero 608c2ecf20Sopenharmony_cibits are shifted off, they are ``jammed'' into the least significant bit of 618c2ecf20Sopenharmony_cithe result by setting the least significant bit to 1. The value of `count' 628c2ecf20Sopenharmony_cican be arbitrarily large; in particular, if `count' is greater than 64, the 638c2ecf20Sopenharmony_ciresult will be either 0 or 1, depending on whether `a' is zero or nonzero. 648c2ecf20Sopenharmony_ciThe result is stored in the location pointed to by `zPtr'. 658c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 668c2ecf20Sopenharmony_ci*/ 678c2ecf20Sopenharmony_ciINLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci bits64 z; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci __asm__("@shift64RightJamming -- start"); 728c2ecf20Sopenharmony_ci if ( count == 0 ) { 738c2ecf20Sopenharmony_ci z = a; 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci else if ( count < 64 ) { 768c2ecf20Sopenharmony_ci z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci else { 798c2ecf20Sopenharmony_ci z = ( a != 0 ); 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci __asm__("@shift64RightJamming -- end"); 828c2ecf20Sopenharmony_ci *zPtr = z; 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/* 868c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 878c2ecf20Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 888c2ecf20Sopenharmony_ci_plus_ the number of bits given in `count'. The shifted result is at most 898c2ecf20Sopenharmony_ci64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The 908c2ecf20Sopenharmony_cibits shifted off form a second 64-bit result as follows: The _last_ bit 918c2ecf20Sopenharmony_cishifted off is the most-significant bit of the extra result, and the other 928c2ecf20Sopenharmony_ci63 bits of the extra result are all zero if and only if _all_but_the_last_ 938c2ecf20Sopenharmony_cibits shifted off were all zero. This extra result is stored in the location 948c2ecf20Sopenharmony_cipointed to by `z1Ptr'. The value of `count' can be arbitrarily large. 958c2ecf20Sopenharmony_ci (This routine makes more sense if `a0' and `a1' are considered to form a 968c2ecf20Sopenharmony_cifixed-point value with binary point between `a0' and `a1'. This fixed-point 978c2ecf20Sopenharmony_civalue is shifted right by the number of bits given in `count', and the 988c2ecf20Sopenharmony_ciinteger part of the result is returned at the location pointed to by 998c2ecf20Sopenharmony_ci`z0Ptr'. The fractional part of the result may be slightly corrupted as 1008c2ecf20Sopenharmony_cidescribed above, and is returned at the location pointed to by `z1Ptr'.) 1018c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 1028c2ecf20Sopenharmony_ci*/ 1038c2ecf20Sopenharmony_ciINLINE void 1048c2ecf20Sopenharmony_ci shift64ExtraRightJamming( 1058c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci bits64 z0, z1; 1088c2ecf20Sopenharmony_ci int8 negCount = ( - count ) & 63; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if ( count == 0 ) { 1118c2ecf20Sopenharmony_ci z1 = a1; 1128c2ecf20Sopenharmony_ci z0 = a0; 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci else if ( count < 64 ) { 1158c2ecf20Sopenharmony_ci z1 = ( a0<<negCount ) | ( a1 != 0 ); 1168c2ecf20Sopenharmony_ci z0 = a0>>count; 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci else { 1198c2ecf20Sopenharmony_ci if ( count == 64 ) { 1208c2ecf20Sopenharmony_ci z1 = a0 | ( a1 != 0 ); 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci else { 1238c2ecf20Sopenharmony_ci z1 = ( ( a0 | a1 ) != 0 ); 1248c2ecf20Sopenharmony_ci } 1258c2ecf20Sopenharmony_ci z0 = 0; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci *z1Ptr = z1; 1288c2ecf20Sopenharmony_ci *z0Ptr = z0; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/* 1338c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 1348c2ecf20Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by the 1358c2ecf20Sopenharmony_cinumber of bits given in `count'. Any bits shifted off are lost. The value 1368c2ecf20Sopenharmony_ciof `count' can be arbitrarily large; in particular, if `count' is greater 1378c2ecf20Sopenharmony_cithan 128, the result will be 0. The result is broken into two 64-bit pieces 1388c2ecf20Sopenharmony_ciwhich are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. 1398c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 1408c2ecf20Sopenharmony_ci*/ 1418c2ecf20Sopenharmony_ciINLINE void 1428c2ecf20Sopenharmony_ci shift128Right( 1438c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci bits64 z0, z1; 1468c2ecf20Sopenharmony_ci int8 negCount = ( - count ) & 63; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci if ( count == 0 ) { 1498c2ecf20Sopenharmony_ci z1 = a1; 1508c2ecf20Sopenharmony_ci z0 = a0; 1518c2ecf20Sopenharmony_ci } 1528c2ecf20Sopenharmony_ci else if ( count < 64 ) { 1538c2ecf20Sopenharmony_ci z1 = ( a0<<negCount ) | ( a1>>count ); 1548c2ecf20Sopenharmony_ci z0 = a0>>count; 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci else { 1578c2ecf20Sopenharmony_ci z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; 1588c2ecf20Sopenharmony_ci z0 = 0; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci *z1Ptr = z1; 1618c2ecf20Sopenharmony_ci *z0Ptr = z0; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* 1668c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 1678c2ecf20Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' right by the 1688c2ecf20Sopenharmony_cinumber of bits given in `count'. If any nonzero bits are shifted off, they 1698c2ecf20Sopenharmony_ciare ``jammed'' into the least significant bit of the result by setting the 1708c2ecf20Sopenharmony_cileast significant bit to 1. The value of `count' can be arbitrarily large; 1718c2ecf20Sopenharmony_ciin particular, if `count' is greater than 128, the result will be either 0 1728c2ecf20Sopenharmony_cior 1, depending on whether the concatenation of `a0' and `a1' is zero or 1738c2ecf20Sopenharmony_cinonzero. The result is broken into two 64-bit pieces which are stored at 1748c2ecf20Sopenharmony_cithe locations pointed to by `z0Ptr' and `z1Ptr'. 1758c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 1768c2ecf20Sopenharmony_ci*/ 1778c2ecf20Sopenharmony_ciINLINE void 1788c2ecf20Sopenharmony_ci shift128RightJamming( 1798c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci bits64 z0, z1; 1828c2ecf20Sopenharmony_ci int8 negCount = ( - count ) & 63; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci if ( count == 0 ) { 1858c2ecf20Sopenharmony_ci z1 = a1; 1868c2ecf20Sopenharmony_ci z0 = a0; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci else if ( count < 64 ) { 1898c2ecf20Sopenharmony_ci z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 ); 1908c2ecf20Sopenharmony_ci z0 = a0>>count; 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci else { 1938c2ecf20Sopenharmony_ci if ( count == 64 ) { 1948c2ecf20Sopenharmony_ci z1 = a0 | ( a1 != 0 ); 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci else if ( count < 128 ) { 1978c2ecf20Sopenharmony_ci z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 ); 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci else { 2008c2ecf20Sopenharmony_ci z1 = ( ( a0 | a1 ) != 0 ); 2018c2ecf20Sopenharmony_ci } 2028c2ecf20Sopenharmony_ci z0 = 0; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci *z1Ptr = z1; 2058c2ecf20Sopenharmony_ci *z0Ptr = z0; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* 2108c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 2118c2ecf20Sopenharmony_ciShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right 2128c2ecf20Sopenharmony_ciby 64 _plus_ the number of bits given in `count'. The shifted result is 2138c2ecf20Sopenharmony_ciat most 128 nonzero bits; these are broken into two 64-bit pieces which are 2148c2ecf20Sopenharmony_cistored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted 2158c2ecf20Sopenharmony_cioff form a third 64-bit result as follows: The _last_ bit shifted off is 2168c2ecf20Sopenharmony_cithe most-significant bit of the extra result, and the other 63 bits of the 2178c2ecf20Sopenharmony_ciextra result are all zero if and only if _all_but_the_last_ bits shifted off 2188c2ecf20Sopenharmony_ciwere all zero. This extra result is stored in the location pointed to by 2198c2ecf20Sopenharmony_ci`z2Ptr'. The value of `count' can be arbitrarily large. 2208c2ecf20Sopenharmony_ci (This routine makes more sense if `a0', `a1', and `a2' are considered 2218c2ecf20Sopenharmony_cito form a fixed-point value with binary point between `a1' and `a2'. This 2228c2ecf20Sopenharmony_cifixed-point value is shifted right by the number of bits given in `count', 2238c2ecf20Sopenharmony_ciand the integer part of the result is returned at the locations pointed to 2248c2ecf20Sopenharmony_ciby `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly 2258c2ecf20Sopenharmony_cicorrupted as described above, and is returned at the location pointed to by 2268c2ecf20Sopenharmony_ci`z2Ptr'.) 2278c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 2288c2ecf20Sopenharmony_ci*/ 2298c2ecf20Sopenharmony_ciINLINE void 2308c2ecf20Sopenharmony_ci shift128ExtraRightJamming( 2318c2ecf20Sopenharmony_ci bits64 a0, 2328c2ecf20Sopenharmony_ci bits64 a1, 2338c2ecf20Sopenharmony_ci bits64 a2, 2348c2ecf20Sopenharmony_ci int16 count, 2358c2ecf20Sopenharmony_ci bits64 *z0Ptr, 2368c2ecf20Sopenharmony_ci bits64 *z1Ptr, 2378c2ecf20Sopenharmony_ci bits64 *z2Ptr 2388c2ecf20Sopenharmony_ci ) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci bits64 z0, z1, z2; 2418c2ecf20Sopenharmony_ci int8 negCount = ( - count ) & 63; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci if ( count == 0 ) { 2448c2ecf20Sopenharmony_ci z2 = a2; 2458c2ecf20Sopenharmony_ci z1 = a1; 2468c2ecf20Sopenharmony_ci z0 = a0; 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci else { 2498c2ecf20Sopenharmony_ci if ( count < 64 ) { 2508c2ecf20Sopenharmony_ci z2 = a1<<negCount; 2518c2ecf20Sopenharmony_ci z1 = ( a0<<negCount ) | ( a1>>count ); 2528c2ecf20Sopenharmony_ci z0 = a0>>count; 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci else { 2558c2ecf20Sopenharmony_ci if ( count == 64 ) { 2568c2ecf20Sopenharmony_ci z2 = a1; 2578c2ecf20Sopenharmony_ci z1 = a0; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci else { 2608c2ecf20Sopenharmony_ci a2 |= a1; 2618c2ecf20Sopenharmony_ci if ( count < 128 ) { 2628c2ecf20Sopenharmony_ci z2 = a0<<negCount; 2638c2ecf20Sopenharmony_ci z1 = a0>>( count & 63 ); 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci else { 2668c2ecf20Sopenharmony_ci z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); 2678c2ecf20Sopenharmony_ci z1 = 0; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci z0 = 0; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci z2 |= ( a2 != 0 ); 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci *z2Ptr = z2; 2758c2ecf20Sopenharmony_ci *z1Ptr = z1; 2768c2ecf20Sopenharmony_ci *z0Ptr = z0; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci/* 2818c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 2828c2ecf20Sopenharmony_ciShifts the 128-bit value formed by concatenating `a0' and `a1' left by the 2838c2ecf20Sopenharmony_cinumber of bits given in `count'. Any bits shifted off are lost. The value 2848c2ecf20Sopenharmony_ciof `count' must be less than 64. The result is broken into two 64-bit 2858c2ecf20Sopenharmony_cipieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. 2868c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 2878c2ecf20Sopenharmony_ci*/ 2888c2ecf20Sopenharmony_ciINLINE void 2898c2ecf20Sopenharmony_ci shortShift128Left( 2908c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci *z1Ptr = a1<<count; 2948c2ecf20Sopenharmony_ci *z0Ptr = 2958c2ecf20Sopenharmony_ci ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) ); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci/* 3008c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3018c2ecf20Sopenharmony_ciShifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left 3028c2ecf20Sopenharmony_ciby the number of bits given in `count'. Any bits shifted off are lost. 3038c2ecf20Sopenharmony_ciThe value of `count' must be less than 64. The result is broken into three 3048c2ecf20Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr', 3058c2ecf20Sopenharmony_ci`z1Ptr', and `z2Ptr'. 3068c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3078c2ecf20Sopenharmony_ci*/ 3088c2ecf20Sopenharmony_ciINLINE void 3098c2ecf20Sopenharmony_ci shortShift192Left( 3108c2ecf20Sopenharmony_ci bits64 a0, 3118c2ecf20Sopenharmony_ci bits64 a1, 3128c2ecf20Sopenharmony_ci bits64 a2, 3138c2ecf20Sopenharmony_ci int16 count, 3148c2ecf20Sopenharmony_ci bits64 *z0Ptr, 3158c2ecf20Sopenharmony_ci bits64 *z1Ptr, 3168c2ecf20Sopenharmony_ci bits64 *z2Ptr 3178c2ecf20Sopenharmony_ci ) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci bits64 z0, z1, z2; 3208c2ecf20Sopenharmony_ci int8 negCount; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci z2 = a2<<count; 3238c2ecf20Sopenharmony_ci z1 = a1<<count; 3248c2ecf20Sopenharmony_ci z0 = a0<<count; 3258c2ecf20Sopenharmony_ci if ( 0 < count ) { 3268c2ecf20Sopenharmony_ci negCount = ( ( - count ) & 63 ); 3278c2ecf20Sopenharmony_ci z1 |= a2>>negCount; 3288c2ecf20Sopenharmony_ci z0 |= a1>>negCount; 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci *z2Ptr = z2; 3318c2ecf20Sopenharmony_ci *z1Ptr = z1; 3328c2ecf20Sopenharmony_ci *z0Ptr = z0; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci/* 3378c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3388c2ecf20Sopenharmony_ciAdds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit 3398c2ecf20Sopenharmony_civalue formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so 3408c2ecf20Sopenharmony_ciany carry out is lost. The result is broken into two 64-bit pieces which 3418c2ecf20Sopenharmony_ciare stored at the locations pointed to by `z0Ptr' and `z1Ptr'. 3428c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3438c2ecf20Sopenharmony_ci*/ 3448c2ecf20Sopenharmony_ciINLINE void 3458c2ecf20Sopenharmony_ci add128( 3468c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) 3478c2ecf20Sopenharmony_ci{ 3488c2ecf20Sopenharmony_ci bits64 z1; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci z1 = a1 + b1; 3518c2ecf20Sopenharmony_ci *z1Ptr = z1; 3528c2ecf20Sopenharmony_ci *z0Ptr = a0 + b0 + ( z1 < a1 ); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci} 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci/* 3578c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3588c2ecf20Sopenharmony_ciAdds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the 3598c2ecf20Sopenharmony_ci192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is 3608c2ecf20Sopenharmony_cimodulo 2^192, so any carry out is lost. The result is broken into three 3618c2ecf20Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr', 3628c2ecf20Sopenharmony_ci`z1Ptr', and `z2Ptr'. 3638c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3648c2ecf20Sopenharmony_ci*/ 3658c2ecf20Sopenharmony_ciINLINE void 3668c2ecf20Sopenharmony_ci add192( 3678c2ecf20Sopenharmony_ci bits64 a0, 3688c2ecf20Sopenharmony_ci bits64 a1, 3698c2ecf20Sopenharmony_ci bits64 a2, 3708c2ecf20Sopenharmony_ci bits64 b0, 3718c2ecf20Sopenharmony_ci bits64 b1, 3728c2ecf20Sopenharmony_ci bits64 b2, 3738c2ecf20Sopenharmony_ci bits64 *z0Ptr, 3748c2ecf20Sopenharmony_ci bits64 *z1Ptr, 3758c2ecf20Sopenharmony_ci bits64 *z2Ptr 3768c2ecf20Sopenharmony_ci ) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci bits64 z0, z1, z2; 3798c2ecf20Sopenharmony_ci int8 carry0, carry1; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci z2 = a2 + b2; 3828c2ecf20Sopenharmony_ci carry1 = ( z2 < a2 ); 3838c2ecf20Sopenharmony_ci z1 = a1 + b1; 3848c2ecf20Sopenharmony_ci carry0 = ( z1 < a1 ); 3858c2ecf20Sopenharmony_ci z0 = a0 + b0; 3868c2ecf20Sopenharmony_ci z1 += carry1; 3878c2ecf20Sopenharmony_ci z0 += ( z1 < carry1 ); 3888c2ecf20Sopenharmony_ci z0 += carry0; 3898c2ecf20Sopenharmony_ci *z2Ptr = z2; 3908c2ecf20Sopenharmony_ci *z1Ptr = z1; 3918c2ecf20Sopenharmony_ci *z0Ptr = z0; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci} 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci/* 3968c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 3978c2ecf20Sopenharmony_ciSubtracts the 128-bit value formed by concatenating `b0' and `b1' from the 3988c2ecf20Sopenharmony_ci128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo 3998c2ecf20Sopenharmony_ci2^128, so any borrow out (carry out) is lost. The result is broken into two 4008c2ecf20Sopenharmony_ci64-bit pieces which are stored at the locations pointed to by `z0Ptr' and 4018c2ecf20Sopenharmony_ci`z1Ptr'. 4028c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4038c2ecf20Sopenharmony_ci*/ 4048c2ecf20Sopenharmony_ciINLINE void 4058c2ecf20Sopenharmony_ci sub128( 4068c2ecf20Sopenharmony_ci bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci *z1Ptr = a1 - b1; 4108c2ecf20Sopenharmony_ci *z0Ptr = a0 - b0 - ( a1 < b1 ); 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci/* 4158c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4168c2ecf20Sopenharmony_ciSubtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' 4178c2ecf20Sopenharmony_cifrom the 192-bit value formed by concatenating `a0', `a1', and `a2'. 4188c2ecf20Sopenharmony_ciSubtraction is modulo 2^192, so any borrow out (carry out) is lost. The 4198c2ecf20Sopenharmony_ciresult is broken into three 64-bit pieces which are stored at the locations 4208c2ecf20Sopenharmony_cipointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. 4218c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4228c2ecf20Sopenharmony_ci*/ 4238c2ecf20Sopenharmony_ciINLINE void 4248c2ecf20Sopenharmony_ci sub192( 4258c2ecf20Sopenharmony_ci bits64 a0, 4268c2ecf20Sopenharmony_ci bits64 a1, 4278c2ecf20Sopenharmony_ci bits64 a2, 4288c2ecf20Sopenharmony_ci bits64 b0, 4298c2ecf20Sopenharmony_ci bits64 b1, 4308c2ecf20Sopenharmony_ci bits64 b2, 4318c2ecf20Sopenharmony_ci bits64 *z0Ptr, 4328c2ecf20Sopenharmony_ci bits64 *z1Ptr, 4338c2ecf20Sopenharmony_ci bits64 *z2Ptr 4348c2ecf20Sopenharmony_ci ) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci bits64 z0, z1, z2; 4378c2ecf20Sopenharmony_ci int8 borrow0, borrow1; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci z2 = a2 - b2; 4408c2ecf20Sopenharmony_ci borrow1 = ( a2 < b2 ); 4418c2ecf20Sopenharmony_ci z1 = a1 - b1; 4428c2ecf20Sopenharmony_ci borrow0 = ( a1 < b1 ); 4438c2ecf20Sopenharmony_ci z0 = a0 - b0; 4448c2ecf20Sopenharmony_ci z0 -= ( z1 < borrow1 ); 4458c2ecf20Sopenharmony_ci z1 -= borrow1; 4468c2ecf20Sopenharmony_ci z0 -= borrow0; 4478c2ecf20Sopenharmony_ci *z2Ptr = z2; 4488c2ecf20Sopenharmony_ci *z1Ptr = z1; 4498c2ecf20Sopenharmony_ci *z0Ptr = z0; 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci/* 4548c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4558c2ecf20Sopenharmony_ciMultiplies `a' by `b' to obtain a 128-bit product. The product is broken 4568c2ecf20Sopenharmony_ciinto two 64-bit pieces which are stored at the locations pointed to by 4578c2ecf20Sopenharmony_ci`z0Ptr' and `z1Ptr'. 4588c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4598c2ecf20Sopenharmony_ci*/ 4608c2ecf20Sopenharmony_ciINLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci bits32 aHigh, aLow, bHigh, bLow; 4638c2ecf20Sopenharmony_ci bits64 z0, zMiddleA, zMiddleB, z1; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci aLow = a; 4668c2ecf20Sopenharmony_ci aHigh = a>>32; 4678c2ecf20Sopenharmony_ci bLow = b; 4688c2ecf20Sopenharmony_ci bHigh = b>>32; 4698c2ecf20Sopenharmony_ci z1 = ( (bits64) aLow ) * bLow; 4708c2ecf20Sopenharmony_ci zMiddleA = ( (bits64) aLow ) * bHigh; 4718c2ecf20Sopenharmony_ci zMiddleB = ( (bits64) aHigh ) * bLow; 4728c2ecf20Sopenharmony_ci z0 = ( (bits64) aHigh ) * bHigh; 4738c2ecf20Sopenharmony_ci zMiddleA += zMiddleB; 4748c2ecf20Sopenharmony_ci z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); 4758c2ecf20Sopenharmony_ci zMiddleA <<= 32; 4768c2ecf20Sopenharmony_ci z1 += zMiddleA; 4778c2ecf20Sopenharmony_ci z0 += ( z1 < zMiddleA ); 4788c2ecf20Sopenharmony_ci *z1Ptr = z1; 4798c2ecf20Sopenharmony_ci *z0Ptr = z0; 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci} 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci/* 4848c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4858c2ecf20Sopenharmony_ciMultiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to 4868c2ecf20Sopenharmony_ciobtain a 192-bit product. The product is broken into three 64-bit pieces 4878c2ecf20Sopenharmony_ciwhich are stored at the locations pointed to by `z0Ptr', `z1Ptr', and 4888c2ecf20Sopenharmony_ci`z2Ptr'. 4898c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 4908c2ecf20Sopenharmony_ci*/ 4918c2ecf20Sopenharmony_ciINLINE void 4928c2ecf20Sopenharmony_ci mul128By64To192( 4938c2ecf20Sopenharmony_ci bits64 a0, 4948c2ecf20Sopenharmony_ci bits64 a1, 4958c2ecf20Sopenharmony_ci bits64 b, 4968c2ecf20Sopenharmony_ci bits64 *z0Ptr, 4978c2ecf20Sopenharmony_ci bits64 *z1Ptr, 4988c2ecf20Sopenharmony_ci bits64 *z2Ptr 4998c2ecf20Sopenharmony_ci ) 5008c2ecf20Sopenharmony_ci{ 5018c2ecf20Sopenharmony_ci bits64 z0, z1, z2, more1; 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci mul64To128( a1, b, &z1, &z2 ); 5048c2ecf20Sopenharmony_ci mul64To128( a0, b, &z0, &more1 ); 5058c2ecf20Sopenharmony_ci add128( z0, more1, 0, z1, &z0, &z1 ); 5068c2ecf20Sopenharmony_ci *z2Ptr = z2; 5078c2ecf20Sopenharmony_ci *z1Ptr = z1; 5088c2ecf20Sopenharmony_ci *z0Ptr = z0; 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci} 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci/* 5138c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 5148c2ecf20Sopenharmony_ciMultiplies the 128-bit value formed by concatenating `a0' and `a1' to the 5158c2ecf20Sopenharmony_ci128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit 5168c2ecf20Sopenharmony_ciproduct. The product is broken into four 64-bit pieces which are stored at 5178c2ecf20Sopenharmony_cithe locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. 5188c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 5198c2ecf20Sopenharmony_ci*/ 5208c2ecf20Sopenharmony_ciINLINE void 5218c2ecf20Sopenharmony_ci mul128To256( 5228c2ecf20Sopenharmony_ci bits64 a0, 5238c2ecf20Sopenharmony_ci bits64 a1, 5248c2ecf20Sopenharmony_ci bits64 b0, 5258c2ecf20Sopenharmony_ci bits64 b1, 5268c2ecf20Sopenharmony_ci bits64 *z0Ptr, 5278c2ecf20Sopenharmony_ci bits64 *z1Ptr, 5288c2ecf20Sopenharmony_ci bits64 *z2Ptr, 5298c2ecf20Sopenharmony_ci bits64 *z3Ptr 5308c2ecf20Sopenharmony_ci ) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci bits64 z0, z1, z2, z3; 5338c2ecf20Sopenharmony_ci bits64 more1, more2; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci mul64To128( a1, b1, &z2, &z3 ); 5368c2ecf20Sopenharmony_ci mul64To128( a1, b0, &z1, &more2 ); 5378c2ecf20Sopenharmony_ci add128( z1, more2, 0, z2, &z1, &z2 ); 5388c2ecf20Sopenharmony_ci mul64To128( a0, b0, &z0, &more1 ); 5398c2ecf20Sopenharmony_ci add128( z0, more1, 0, z1, &z0, &z1 ); 5408c2ecf20Sopenharmony_ci mul64To128( a0, b1, &more1, &more2 ); 5418c2ecf20Sopenharmony_ci add128( more1, more2, 0, z2, &more1, &z2 ); 5428c2ecf20Sopenharmony_ci add128( z0, z1, 0, more1, &z0, &z1 ); 5438c2ecf20Sopenharmony_ci *z3Ptr = z3; 5448c2ecf20Sopenharmony_ci *z2Ptr = z2; 5458c2ecf20Sopenharmony_ci *z1Ptr = z1; 5468c2ecf20Sopenharmony_ci *z0Ptr = z0; 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci/* 5518c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 5528c2ecf20Sopenharmony_ciReturns an approximation to the 64-bit integer quotient obtained by dividing 5538c2ecf20Sopenharmony_ci`b' into the 128-bit value formed by concatenating `a0' and `a1'. The 5548c2ecf20Sopenharmony_cidivisor `b' must be at least 2^63. If q is the exact quotient truncated 5558c2ecf20Sopenharmony_citoward zero, the approximation returned lies between q and q + 2 inclusive. 5568c2ecf20Sopenharmony_ciIf the exact quotient q is larger than 64 bits, the maximum positive 64-bit 5578c2ecf20Sopenharmony_ciunsigned integer is returned. 5588c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 5598c2ecf20Sopenharmony_ci*/ 5608c2ecf20Sopenharmony_cistatic bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) 5618c2ecf20Sopenharmony_ci{ 5628c2ecf20Sopenharmony_ci bits64 b0, b1; 5638c2ecf20Sopenharmony_ci bits64 rem0, rem1, term0, term1; 5648c2ecf20Sopenharmony_ci bits64 z; 5658c2ecf20Sopenharmony_ci if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); 5668c2ecf20Sopenharmony_ci b0 = b>>32; /* hence b0 is 32 bits wide now */ 5678c2ecf20Sopenharmony_ci if ( b0<<32 <= a0 ) { 5688c2ecf20Sopenharmony_ci z = LIT64( 0xFFFFFFFF00000000 ); 5698c2ecf20Sopenharmony_ci } else { 5708c2ecf20Sopenharmony_ci z = a0; 5718c2ecf20Sopenharmony_ci do_div( z, b0 ); 5728c2ecf20Sopenharmony_ci z <<= 32; 5738c2ecf20Sopenharmony_ci } 5748c2ecf20Sopenharmony_ci mul64To128( b, z, &term0, &term1 ); 5758c2ecf20Sopenharmony_ci sub128( a0, a1, term0, term1, &rem0, &rem1 ); 5768c2ecf20Sopenharmony_ci while ( ( (sbits64) rem0 ) < 0 ) { 5778c2ecf20Sopenharmony_ci z -= LIT64( 0x100000000 ); 5788c2ecf20Sopenharmony_ci b1 = b<<32; 5798c2ecf20Sopenharmony_ci add128( rem0, rem1, b0, b1, &rem0, &rem1 ); 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci rem0 = ( rem0<<32 ) | ( rem1>>32 ); 5828c2ecf20Sopenharmony_ci if ( b0<<32 <= rem0 ) { 5838c2ecf20Sopenharmony_ci z |= 0xFFFFFFFF; 5848c2ecf20Sopenharmony_ci } else { 5858c2ecf20Sopenharmony_ci do_div( rem0, b0 ); 5868c2ecf20Sopenharmony_ci z |= rem0; 5878c2ecf20Sopenharmony_ci } 5888c2ecf20Sopenharmony_ci return z; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci/* 5938c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 5948c2ecf20Sopenharmony_ciReturns an approximation to the square root of the 32-bit significand given 5958c2ecf20Sopenharmony_ciby `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of 5968c2ecf20Sopenharmony_ci`aExp' (the least significant bit) is 1, the integer returned approximates 5978c2ecf20Sopenharmony_ci2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' 5988c2ecf20Sopenharmony_ciis 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either 5998c2ecf20Sopenharmony_cicase, the approximation returned lies strictly within +/-2 of the exact 6008c2ecf20Sopenharmony_civalue. 6018c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 6028c2ecf20Sopenharmony_ci*/ 6038c2ecf20Sopenharmony_cistatic bits32 estimateSqrt32( int16 aExp, bits32 a ) 6048c2ecf20Sopenharmony_ci{ 6058c2ecf20Sopenharmony_ci static const bits16 sqrtOddAdjustments[] = { 6068c2ecf20Sopenharmony_ci 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, 6078c2ecf20Sopenharmony_ci 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 6088c2ecf20Sopenharmony_ci }; 6098c2ecf20Sopenharmony_ci static const bits16 sqrtEvenAdjustments[] = { 6108c2ecf20Sopenharmony_ci 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, 6118c2ecf20Sopenharmony_ci 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 6128c2ecf20Sopenharmony_ci }; 6138c2ecf20Sopenharmony_ci int8 index; 6148c2ecf20Sopenharmony_ci bits32 z; 6158c2ecf20Sopenharmony_ci bits64 A; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci index = ( a>>27 ) & 15; 6188c2ecf20Sopenharmony_ci if ( aExp & 1 ) { 6198c2ecf20Sopenharmony_ci z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; 6208c2ecf20Sopenharmony_ci z = ( ( a / z )<<14 ) + ( z<<15 ); 6218c2ecf20Sopenharmony_ci a >>= 1; 6228c2ecf20Sopenharmony_ci } 6238c2ecf20Sopenharmony_ci else { 6248c2ecf20Sopenharmony_ci z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; 6258c2ecf20Sopenharmony_ci z = a / z + z; 6268c2ecf20Sopenharmony_ci z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); 6278c2ecf20Sopenharmony_ci if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); 6288c2ecf20Sopenharmony_ci } 6298c2ecf20Sopenharmony_ci A = ( (bits64) a )<<31; 6308c2ecf20Sopenharmony_ci do_div( A, z ); 6318c2ecf20Sopenharmony_ci return ( (bits32) A ) + ( z>>1 ); 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci} 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci/* 6368c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 6378c2ecf20Sopenharmony_ciReturns the number of leading 0 bits before the most-significant 1 bit 6388c2ecf20Sopenharmony_ciof `a'. If `a' is zero, 32 is returned. 6398c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 6408c2ecf20Sopenharmony_ci*/ 6418c2ecf20Sopenharmony_cistatic int8 countLeadingZeros32( bits32 a ) 6428c2ecf20Sopenharmony_ci{ 6438c2ecf20Sopenharmony_ci static const int8 countLeadingZerosHigh[] = { 6448c2ecf20Sopenharmony_ci 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 6458c2ecf20Sopenharmony_ci 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6468c2ecf20Sopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6478c2ecf20Sopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6488c2ecf20Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6498c2ecf20Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6508c2ecf20Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6518c2ecf20Sopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6528c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6538c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6548c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6558c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6568c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6578c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6588c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6598c2ecf20Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 6608c2ecf20Sopenharmony_ci }; 6618c2ecf20Sopenharmony_ci int8 shiftCount; 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci shiftCount = 0; 6648c2ecf20Sopenharmony_ci if ( a < 0x10000 ) { 6658c2ecf20Sopenharmony_ci shiftCount += 16; 6668c2ecf20Sopenharmony_ci a <<= 16; 6678c2ecf20Sopenharmony_ci } 6688c2ecf20Sopenharmony_ci if ( a < 0x1000000 ) { 6698c2ecf20Sopenharmony_ci shiftCount += 8; 6708c2ecf20Sopenharmony_ci a <<= 8; 6718c2ecf20Sopenharmony_ci } 6728c2ecf20Sopenharmony_ci shiftCount += countLeadingZerosHigh[ a>>24 ]; 6738c2ecf20Sopenharmony_ci return shiftCount; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci/* 6788c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 6798c2ecf20Sopenharmony_ciReturns the number of leading 0 bits before the most-significant 1 bit 6808c2ecf20Sopenharmony_ciof `a'. If `a' is zero, 64 is returned. 6818c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 6828c2ecf20Sopenharmony_ci*/ 6838c2ecf20Sopenharmony_cistatic int8 countLeadingZeros64( bits64 a ) 6848c2ecf20Sopenharmony_ci{ 6858c2ecf20Sopenharmony_ci int8 shiftCount; 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ci shiftCount = 0; 6888c2ecf20Sopenharmony_ci if ( a < ( (bits64) 1 )<<32 ) { 6898c2ecf20Sopenharmony_ci shiftCount += 32; 6908c2ecf20Sopenharmony_ci } 6918c2ecf20Sopenharmony_ci else { 6928c2ecf20Sopenharmony_ci a >>= 32; 6938c2ecf20Sopenharmony_ci } 6948c2ecf20Sopenharmony_ci shiftCount += countLeadingZeros32( a ); 6958c2ecf20Sopenharmony_ci return shiftCount; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci} 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci/* 7008c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7018c2ecf20Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' 7028c2ecf20Sopenharmony_ciis equal to the 128-bit value formed by concatenating `b0' and `b1'. 7038c2ecf20Sopenharmony_ciOtherwise, returns 0. 7048c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7058c2ecf20Sopenharmony_ci*/ 7068c2ecf20Sopenharmony_ciINLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) 7078c2ecf20Sopenharmony_ci{ 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci return ( a0 == b0 ) && ( a1 == b1 ); 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci} 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci/* 7148c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7158c2ecf20Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less 7168c2ecf20Sopenharmony_cithan or equal to the 128-bit value formed by concatenating `b0' and `b1'. 7178c2ecf20Sopenharmony_ciOtherwise, returns 0. 7188c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7198c2ecf20Sopenharmony_ci*/ 7208c2ecf20Sopenharmony_ciINLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) 7218c2ecf20Sopenharmony_ci{ 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci} 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci/* 7288c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7298c2ecf20Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less 7308c2ecf20Sopenharmony_cithan the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, 7318c2ecf20Sopenharmony_cireturns 0. 7328c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7338c2ecf20Sopenharmony_ci*/ 7348c2ecf20Sopenharmony_ciINLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) 7358c2ecf20Sopenharmony_ci{ 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci} 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci/* 7428c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7438c2ecf20Sopenharmony_ciReturns 1 if the 128-bit value formed by concatenating `a0' and `a1' is 7448c2ecf20Sopenharmony_cinot equal to the 128-bit value formed by concatenating `b0' and `b1'. 7458c2ecf20Sopenharmony_ciOtherwise, returns 0. 7468c2ecf20Sopenharmony_ci------------------------------------------------------------------------------- 7478c2ecf20Sopenharmony_ci*/ 7488c2ecf20Sopenharmony_ciINLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) 7498c2ecf20Sopenharmony_ci{ 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci return ( a0 != b0 ) || ( a1 != b1 ); 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci} 7548c2ecf20Sopenharmony_ci 755