1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
28d52ea6dSThomas Chou /*
38d52ea6dSThomas Chou * This file is part of GNU CC.
48d52ea6dSThomas Chou */
58d52ea6dSThomas Chou
68d52ea6dSThomas Chou typedef unsigned int UWtype;
78d52ea6dSThomas Chou typedef unsigned int UHWtype;
88d52ea6dSThomas Chou typedef unsigned long long UDWtype;
98d52ea6dSThomas Chou #define W_TYPE_SIZE 32
108d52ea6dSThomas Chou
118d52ea6dSThomas Chou typedef unsigned char UQItype;
128d52ea6dSThomas Chou typedef long SItype;
138d52ea6dSThomas Chou typedef unsigned long USItype;
148d52ea6dSThomas Chou typedef long long DItype;
158d52ea6dSThomas Chou typedef unsigned long long DSItype;
168d52ea6dSThomas Chou
178d52ea6dSThomas Chou #include "longlong.h"
188d52ea6dSThomas Chou
198d52ea6dSThomas Chou
208d52ea6dSThomas Chou typedef int word_type;
218d52ea6dSThomas Chou typedef long Wtype;
228d52ea6dSThomas Chou typedef long long DWtype;
238d52ea6dSThomas Chou
248d52ea6dSThomas Chou struct DWstruct { Wtype low, high;};
258d52ea6dSThomas Chou
268d52ea6dSThomas Chou typedef union
278d52ea6dSThomas Chou {
288d52ea6dSThomas Chou struct DWstruct s;
298d52ea6dSThomas Chou DWtype ll;
308d52ea6dSThomas Chou } DWunion;
318d52ea6dSThomas Chou
328d52ea6dSThomas Chou #define BITS_PER_UNIT 8
338d52ea6dSThomas Chou
348d52ea6dSThomas Chou UDWtype
358d52ea6dSThomas Chou __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
368d52ea6dSThomas Chou
378d52ea6dSThomas Chou const UQItype __clz_tab[256] =
388d52ea6dSThomas Chou {
398d52ea6dSThomas Chou 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
408d52ea6dSThomas Chou 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
418d52ea6dSThomas Chou 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
428d52ea6dSThomas Chou 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
438d52ea6dSThomas Chou 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
448d52ea6dSThomas Chou 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
458d52ea6dSThomas Chou 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
468d52ea6dSThomas Chou 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
478d52ea6dSThomas Chou };
488d52ea6dSThomas Chou
498d52ea6dSThomas Chou
508d52ea6dSThomas Chou DWtype
__ashldi3(DWtype u,word_type b)518d52ea6dSThomas Chou __ashldi3 (DWtype u, word_type b)
528d52ea6dSThomas Chou {
538d52ea6dSThomas Chou if (b == 0)
548d52ea6dSThomas Chou return u;
558d52ea6dSThomas Chou
568d52ea6dSThomas Chou const DWunion uu = {.ll = u};
578d52ea6dSThomas Chou const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
588d52ea6dSThomas Chou DWunion w;
598d52ea6dSThomas Chou
608d52ea6dSThomas Chou if (bm <= 0)
618d52ea6dSThomas Chou {
628d52ea6dSThomas Chou w.s.low = 0;
638d52ea6dSThomas Chou w.s.high = (UWtype) uu.s.low << -bm;
648d52ea6dSThomas Chou }
658d52ea6dSThomas Chou else
668d52ea6dSThomas Chou {
678d52ea6dSThomas Chou const UWtype carries = (UWtype) uu.s.low >> bm;
688d52ea6dSThomas Chou
698d52ea6dSThomas Chou w.s.low = (UWtype) uu.s.low << b;
708d52ea6dSThomas Chou w.s.high = ((UWtype) uu.s.high << b) | carries;
718d52ea6dSThomas Chou }
728d52ea6dSThomas Chou
738d52ea6dSThomas Chou return w.ll;
748d52ea6dSThomas Chou }
758d52ea6dSThomas Chou
768d52ea6dSThomas Chou DWtype
__ashrdi3(DWtype u,word_type b)778d52ea6dSThomas Chou __ashrdi3 (DWtype u, word_type b)
788d52ea6dSThomas Chou {
798d52ea6dSThomas Chou if (b == 0)
808d52ea6dSThomas Chou return u;
818d52ea6dSThomas Chou
828d52ea6dSThomas Chou const DWunion uu = {.ll = u};
838d52ea6dSThomas Chou const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
848d52ea6dSThomas Chou DWunion w;
858d52ea6dSThomas Chou
868d52ea6dSThomas Chou if (bm <= 0)
878d52ea6dSThomas Chou {
888d52ea6dSThomas Chou /* w.s.high = 1..1 or 0..0 */
898d52ea6dSThomas Chou w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
908d52ea6dSThomas Chou w.s.low = uu.s.high >> -bm;
918d52ea6dSThomas Chou }
928d52ea6dSThomas Chou else
938d52ea6dSThomas Chou {
948d52ea6dSThomas Chou const UWtype carries = (UWtype) uu.s.high << bm;
958d52ea6dSThomas Chou
968d52ea6dSThomas Chou w.s.high = uu.s.high >> b;
978d52ea6dSThomas Chou w.s.low = ((UWtype) uu.s.low >> b) | carries;
988d52ea6dSThomas Chou }
998d52ea6dSThomas Chou
1008d52ea6dSThomas Chou return w.ll;
1018d52ea6dSThomas Chou }
1028d52ea6dSThomas Chou
1038d52ea6dSThomas Chou DWtype
__lshrdi3(DWtype u,word_type b)1048d52ea6dSThomas Chou __lshrdi3 (DWtype u, word_type b)
1058d52ea6dSThomas Chou {
1068d52ea6dSThomas Chou if (b == 0)
1078d52ea6dSThomas Chou return u;
1088d52ea6dSThomas Chou
1098d52ea6dSThomas Chou const DWunion uu = {.ll = u};
1108d52ea6dSThomas Chou const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
1118d52ea6dSThomas Chou DWunion w;
1128d52ea6dSThomas Chou
1138d52ea6dSThomas Chou if (bm <= 0)
1148d52ea6dSThomas Chou {
1158d52ea6dSThomas Chou w.s.high = 0;
1168d52ea6dSThomas Chou w.s.low = (UWtype) uu.s.high >> -bm;
1178d52ea6dSThomas Chou }
1188d52ea6dSThomas Chou else
1198d52ea6dSThomas Chou {
1208d52ea6dSThomas Chou const UWtype carries = (UWtype) uu.s.high << bm;
1218d52ea6dSThomas Chou
1228d52ea6dSThomas Chou w.s.high = (UWtype) uu.s.high >> b;
1238d52ea6dSThomas Chou w.s.low = ((UWtype) uu.s.low >> b) | carries;
1248d52ea6dSThomas Chou }
1258d52ea6dSThomas Chou
1268d52ea6dSThomas Chou return w.ll;
1278d52ea6dSThomas Chou }
1288d52ea6dSThomas Chou
1298d52ea6dSThomas Chou word_type
__cmpdi2(DWtype a,DWtype b)1308d52ea6dSThomas Chou __cmpdi2 (DWtype a, DWtype b)
1318d52ea6dSThomas Chou {
1328d52ea6dSThomas Chou const DWunion au = {.ll = a};
1338d52ea6dSThomas Chou const DWunion bu = {.ll = b};
1348d52ea6dSThomas Chou
1358d52ea6dSThomas Chou if (au.s.high < bu.s.high)
1368d52ea6dSThomas Chou return 0;
1378d52ea6dSThomas Chou else if (au.s.high > bu.s.high)
1388d52ea6dSThomas Chou return 2;
1398d52ea6dSThomas Chou if ((UWtype) au.s.low < (UWtype) bu.s.low)
1408d52ea6dSThomas Chou return 0;
1418d52ea6dSThomas Chou else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1428d52ea6dSThomas Chou return 2;
1438d52ea6dSThomas Chou return 1;
1448d52ea6dSThomas Chou }
1458d52ea6dSThomas Chou
1468d52ea6dSThomas Chou UDWtype
__udivmoddi4(UDWtype n,UDWtype d,UDWtype * rp)1478d52ea6dSThomas Chou __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
1488d52ea6dSThomas Chou {
1498d52ea6dSThomas Chou const DWunion nn = {.ll = n};
1508d52ea6dSThomas Chou const DWunion dd = {.ll = d};
1518d52ea6dSThomas Chou DWunion rr;
1528d52ea6dSThomas Chou UWtype d0, d1, n0, n1, n2;
1538d52ea6dSThomas Chou UWtype q0, q1;
1548d52ea6dSThomas Chou UWtype b, bm;
1558d52ea6dSThomas Chou
1568d52ea6dSThomas Chou d0 = dd.s.low;
1578d52ea6dSThomas Chou d1 = dd.s.high;
1588d52ea6dSThomas Chou n0 = nn.s.low;
1598d52ea6dSThomas Chou n1 = nn.s.high;
1608d52ea6dSThomas Chou
1618d52ea6dSThomas Chou #if !UDIV_NEEDS_NORMALIZATION
1628d52ea6dSThomas Chou if (d1 == 0)
1638d52ea6dSThomas Chou {
1648d52ea6dSThomas Chou if (d0 > n1)
1658d52ea6dSThomas Chou {
1668d52ea6dSThomas Chou /* 0q = nn / 0D */
1678d52ea6dSThomas Chou
1688d52ea6dSThomas Chou udiv_qrnnd (q0, n0, n1, n0, d0);
1698d52ea6dSThomas Chou q1 = 0;
1708d52ea6dSThomas Chou
1718d52ea6dSThomas Chou /* Remainder in n0. */
1728d52ea6dSThomas Chou }
1738d52ea6dSThomas Chou else
1748d52ea6dSThomas Chou {
1758d52ea6dSThomas Chou /* qq = NN / 0d */
1768d52ea6dSThomas Chou
1778d52ea6dSThomas Chou if (d0 == 0)
1788d52ea6dSThomas Chou d0 = 1 / d0; /* Divide intentionally by zero. */
1798d52ea6dSThomas Chou
1808d52ea6dSThomas Chou udiv_qrnnd (q1, n1, 0, n1, d0);
1818d52ea6dSThomas Chou udiv_qrnnd (q0, n0, n1, n0, d0);
1828d52ea6dSThomas Chou
1838d52ea6dSThomas Chou /* Remainder in n0. */
1848d52ea6dSThomas Chou }
1858d52ea6dSThomas Chou
1868d52ea6dSThomas Chou if (rp != 0)
1878d52ea6dSThomas Chou {
1888d52ea6dSThomas Chou rr.s.low = n0;
1898d52ea6dSThomas Chou rr.s.high = 0;
1908d52ea6dSThomas Chou *rp = rr.ll;
1918d52ea6dSThomas Chou }
1928d52ea6dSThomas Chou }
1938d52ea6dSThomas Chou
1948d52ea6dSThomas Chou #else /* UDIV_NEEDS_NORMALIZATION */
1958d52ea6dSThomas Chou
1968d52ea6dSThomas Chou if (d1 == 0)
1978d52ea6dSThomas Chou {
1988d52ea6dSThomas Chou if (d0 > n1)
1998d52ea6dSThomas Chou {
2008d52ea6dSThomas Chou /* 0q = nn / 0D */
2018d52ea6dSThomas Chou
2028d52ea6dSThomas Chou count_leading_zeros (bm, d0);
2038d52ea6dSThomas Chou
2048d52ea6dSThomas Chou if (bm != 0)
2058d52ea6dSThomas Chou {
2068d52ea6dSThomas Chou /* Normalize, i.e. make the most significant bit of the
2078d52ea6dSThomas Chou denominator set. */
2088d52ea6dSThomas Chou
2098d52ea6dSThomas Chou d0 = d0 << bm;
2108d52ea6dSThomas Chou n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
2118d52ea6dSThomas Chou n0 = n0 << bm;
2128d52ea6dSThomas Chou }
2138d52ea6dSThomas Chou
2148d52ea6dSThomas Chou udiv_qrnnd (q0, n0, n1, n0, d0);
2158d52ea6dSThomas Chou q1 = 0;
2168d52ea6dSThomas Chou
2178d52ea6dSThomas Chou /* Remainder in n0 >> bm. */
2188d52ea6dSThomas Chou }
2198d52ea6dSThomas Chou else
2208d52ea6dSThomas Chou {
2218d52ea6dSThomas Chou /* qq = NN / 0d */
2228d52ea6dSThomas Chou
2238d52ea6dSThomas Chou if (d0 == 0)
2248d52ea6dSThomas Chou d0 = 1 / d0; /* Divide intentionally by zero. */
2258d52ea6dSThomas Chou
2268d52ea6dSThomas Chou count_leading_zeros (bm, d0);
2278d52ea6dSThomas Chou
2288d52ea6dSThomas Chou if (bm == 0)
2298d52ea6dSThomas Chou {
2308d52ea6dSThomas Chou /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
2318d52ea6dSThomas Chou conclude (the most significant bit of n1 is set) /\ (the
2328d52ea6dSThomas Chou leading quotient digit q1 = 1).
2338d52ea6dSThomas Chou
2348d52ea6dSThomas Chou This special case is necessary, not an optimization.
2358d52ea6dSThomas Chou (Shifts counts of W_TYPE_SIZE are undefined.) */
2368d52ea6dSThomas Chou
2378d52ea6dSThomas Chou n1 -= d0;
2388d52ea6dSThomas Chou q1 = 1;
2398d52ea6dSThomas Chou }
2408d52ea6dSThomas Chou else
2418d52ea6dSThomas Chou {
2428d52ea6dSThomas Chou /* Normalize. */
2438d52ea6dSThomas Chou
2448d52ea6dSThomas Chou b = W_TYPE_SIZE - bm;
2458d52ea6dSThomas Chou
2468d52ea6dSThomas Chou d0 = d0 << bm;
2478d52ea6dSThomas Chou n2 = n1 >> b;
2488d52ea6dSThomas Chou n1 = (n1 << bm) | (n0 >> b);
2498d52ea6dSThomas Chou n0 = n0 << bm;
2508d52ea6dSThomas Chou
2518d52ea6dSThomas Chou udiv_qrnnd (q1, n1, n2, n1, d0);
2528d52ea6dSThomas Chou }
2538d52ea6dSThomas Chou
2548d52ea6dSThomas Chou /* n1 != d0... */
2558d52ea6dSThomas Chou
2568d52ea6dSThomas Chou udiv_qrnnd (q0, n0, n1, n0, d0);
2578d52ea6dSThomas Chou
2588d52ea6dSThomas Chou /* Remainder in n0 >> bm. */
2598d52ea6dSThomas Chou }
2608d52ea6dSThomas Chou
2618d52ea6dSThomas Chou if (rp != 0)
2628d52ea6dSThomas Chou {
2638d52ea6dSThomas Chou rr.s.low = n0 >> bm;
2648d52ea6dSThomas Chou rr.s.high = 0;
2658d52ea6dSThomas Chou *rp = rr.ll;
2668d52ea6dSThomas Chou }
2678d52ea6dSThomas Chou }
2688d52ea6dSThomas Chou #endif /* UDIV_NEEDS_NORMALIZATION */
2698d52ea6dSThomas Chou
2708d52ea6dSThomas Chou else
2718d52ea6dSThomas Chou {
2728d52ea6dSThomas Chou if (d1 > n1)
2738d52ea6dSThomas Chou {
2748d52ea6dSThomas Chou /* 00 = nn / DD */
2758d52ea6dSThomas Chou
2768d52ea6dSThomas Chou q0 = 0;
2778d52ea6dSThomas Chou q1 = 0;
2788d52ea6dSThomas Chou
2798d52ea6dSThomas Chou /* Remainder in n1n0. */
2808d52ea6dSThomas Chou if (rp != 0)
2818d52ea6dSThomas Chou {
2828d52ea6dSThomas Chou rr.s.low = n0;
2838d52ea6dSThomas Chou rr.s.high = n1;
2848d52ea6dSThomas Chou *rp = rr.ll;
2858d52ea6dSThomas Chou }
2868d52ea6dSThomas Chou }
2878d52ea6dSThomas Chou else
2888d52ea6dSThomas Chou {
2898d52ea6dSThomas Chou /* 0q = NN / dd */
2908d52ea6dSThomas Chou
2918d52ea6dSThomas Chou count_leading_zeros (bm, d1);
2928d52ea6dSThomas Chou if (bm == 0)
2938d52ea6dSThomas Chou {
2948d52ea6dSThomas Chou /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
2958d52ea6dSThomas Chou conclude (the most significant bit of n1 is set) /\ (the
2968d52ea6dSThomas Chou quotient digit q0 = 0 or 1).
2978d52ea6dSThomas Chou
2988d52ea6dSThomas Chou This special case is necessary, not an optimization. */
2998d52ea6dSThomas Chou
3008d52ea6dSThomas Chou /* The condition on the next line takes advantage of that
3018d52ea6dSThomas Chou n1 >= d1 (true due to program flow). */
3028d52ea6dSThomas Chou if (n1 > d1 || n0 >= d0)
3038d52ea6dSThomas Chou {
3048d52ea6dSThomas Chou q0 = 1;
3058d52ea6dSThomas Chou sub_ddmmss (n1, n0, n1, n0, d1, d0);
3068d52ea6dSThomas Chou }
3078d52ea6dSThomas Chou else
3088d52ea6dSThomas Chou q0 = 0;
3098d52ea6dSThomas Chou
3108d52ea6dSThomas Chou q1 = 0;
3118d52ea6dSThomas Chou
3128d52ea6dSThomas Chou if (rp != 0)
3138d52ea6dSThomas Chou {
3148d52ea6dSThomas Chou rr.s.low = n0;
3158d52ea6dSThomas Chou rr.s.high = n1;
3168d52ea6dSThomas Chou *rp = rr.ll;
3178d52ea6dSThomas Chou }
3188d52ea6dSThomas Chou }
3198d52ea6dSThomas Chou else
3208d52ea6dSThomas Chou {
3218d52ea6dSThomas Chou UWtype m1, m0;
3228d52ea6dSThomas Chou /* Normalize. */
3238d52ea6dSThomas Chou
3248d52ea6dSThomas Chou b = W_TYPE_SIZE - bm;
3258d52ea6dSThomas Chou
3268d52ea6dSThomas Chou d1 = (d1 << bm) | (d0 >> b);
3278d52ea6dSThomas Chou d0 = d0 << bm;
3288d52ea6dSThomas Chou n2 = n1 >> b;
3298d52ea6dSThomas Chou n1 = (n1 << bm) | (n0 >> b);
3308d52ea6dSThomas Chou n0 = n0 << bm;
3318d52ea6dSThomas Chou
3328d52ea6dSThomas Chou udiv_qrnnd (q0, n1, n2, n1, d1);
3338d52ea6dSThomas Chou umul_ppmm (m1, m0, q0, d0);
3348d52ea6dSThomas Chou
3358d52ea6dSThomas Chou if (m1 > n1 || (m1 == n1 && m0 > n0))
3368d52ea6dSThomas Chou {
3378d52ea6dSThomas Chou q0--;
3388d52ea6dSThomas Chou sub_ddmmss (m1, m0, m1, m0, d1, d0);
3398d52ea6dSThomas Chou }
3408d52ea6dSThomas Chou
3418d52ea6dSThomas Chou q1 = 0;
3428d52ea6dSThomas Chou
3438d52ea6dSThomas Chou /* Remainder in (n1n0 - m1m0) >> bm. */
3448d52ea6dSThomas Chou if (rp != 0)
3458d52ea6dSThomas Chou {
3468d52ea6dSThomas Chou sub_ddmmss (n1, n0, n1, n0, m1, m0);
3478d52ea6dSThomas Chou rr.s.low = (n1 << b) | (n0 >> bm);
3488d52ea6dSThomas Chou rr.s.high = n1 >> bm;
3498d52ea6dSThomas Chou *rp = rr.ll;
3508d52ea6dSThomas Chou }
3518d52ea6dSThomas Chou }
3528d52ea6dSThomas Chou }
3538d52ea6dSThomas Chou }
3548d52ea6dSThomas Chou
3558d52ea6dSThomas Chou const DWunion ww = {{.low = q0, .high = q1}};
3568d52ea6dSThomas Chou return ww.ll;
3578d52ea6dSThomas Chou }
3588d52ea6dSThomas Chou
3598d52ea6dSThomas Chou DWtype
__divdi3(DWtype u,DWtype v)3608d52ea6dSThomas Chou __divdi3 (DWtype u, DWtype v)
3618d52ea6dSThomas Chou {
3628d52ea6dSThomas Chou word_type c = 0;
3638d52ea6dSThomas Chou DWunion uu = {.ll = u};
3648d52ea6dSThomas Chou DWunion vv = {.ll = v};
3658d52ea6dSThomas Chou DWtype w;
3668d52ea6dSThomas Chou
3678d52ea6dSThomas Chou if (uu.s.high < 0)
3688d52ea6dSThomas Chou c = ~c,
3698d52ea6dSThomas Chou uu.ll = -uu.ll;
3708d52ea6dSThomas Chou if (vv.s.high < 0)
3718d52ea6dSThomas Chou c = ~c,
3728d52ea6dSThomas Chou vv.ll = -vv.ll;
3738d52ea6dSThomas Chou
3748d52ea6dSThomas Chou w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
3758d52ea6dSThomas Chou if (c)
3768d52ea6dSThomas Chou w = -w;
3778d52ea6dSThomas Chou
3788d52ea6dSThomas Chou return w;
3798d52ea6dSThomas Chou }
3808d52ea6dSThomas Chou
3818d52ea6dSThomas Chou DWtype
__negdi2(DWtype u)3828d52ea6dSThomas Chou __negdi2 (DWtype u)
3838d52ea6dSThomas Chou {
3848d52ea6dSThomas Chou const DWunion uu = {.ll = u};
3858d52ea6dSThomas Chou const DWunion w = { {.low = -uu.s.low,
3868d52ea6dSThomas Chou .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
3878d52ea6dSThomas Chou
3888d52ea6dSThomas Chou return w.ll;
3898d52ea6dSThomas Chou }
3908d52ea6dSThomas Chou
3918d52ea6dSThomas Chou
3928d52ea6dSThomas Chou DWtype
__muldi3(DWtype u,DWtype v)3938d52ea6dSThomas Chou __muldi3 (DWtype u, DWtype v)
3948d52ea6dSThomas Chou {
3958d52ea6dSThomas Chou const DWunion uu = {.ll = u};
3968d52ea6dSThomas Chou const DWunion vv = {.ll = v};
3978d52ea6dSThomas Chou DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
3988d52ea6dSThomas Chou
3998d52ea6dSThomas Chou w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
4008d52ea6dSThomas Chou + (UWtype) uu.s.high * (UWtype) vv.s.low);
4018d52ea6dSThomas Chou
4028d52ea6dSThomas Chou return w.ll;
4038d52ea6dSThomas Chou }
4048d52ea6dSThomas Chou
4058d52ea6dSThomas Chou DWtype
__moddi3(DWtype u,DWtype v)4068d52ea6dSThomas Chou __moddi3 (DWtype u, DWtype v)
4078d52ea6dSThomas Chou {
4088d52ea6dSThomas Chou word_type c = 0;
4098d52ea6dSThomas Chou DWunion uu = {.ll = u};
4108d52ea6dSThomas Chou DWunion vv = {.ll = v};
4118d52ea6dSThomas Chou DWtype w;
4128d52ea6dSThomas Chou
4138d52ea6dSThomas Chou if (uu.s.high < 0)
4148d52ea6dSThomas Chou c = ~c,
4158d52ea6dSThomas Chou uu.ll = -uu.ll;
4168d52ea6dSThomas Chou if (vv.s.high < 0)
4178d52ea6dSThomas Chou vv.ll = -vv.ll;
4188d52ea6dSThomas Chou
4198d52ea6dSThomas Chou (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
4208d52ea6dSThomas Chou if (c)
4218d52ea6dSThomas Chou w = -w;
4228d52ea6dSThomas Chou
4238d52ea6dSThomas Chou return w;
4248d52ea6dSThomas Chou }
4258d52ea6dSThomas Chou
4268d52ea6dSThomas Chou word_type
__ucmpdi2(DWtype a,DWtype b)4278d52ea6dSThomas Chou __ucmpdi2 (DWtype a, DWtype b)
4288d52ea6dSThomas Chou {
4298d52ea6dSThomas Chou const DWunion au = {.ll = a};
4308d52ea6dSThomas Chou const DWunion bu = {.ll = b};
4318d52ea6dSThomas Chou
4328d52ea6dSThomas Chou if ((UWtype) au.s.high < (UWtype) bu.s.high)
4338d52ea6dSThomas Chou return 0;
4348d52ea6dSThomas Chou else if ((UWtype) au.s.high > (UWtype) bu.s.high)
4358d52ea6dSThomas Chou return 2;
4368d52ea6dSThomas Chou if ((UWtype) au.s.low < (UWtype) bu.s.low)
4378d52ea6dSThomas Chou return 0;
4388d52ea6dSThomas Chou else if ((UWtype) au.s.low > (UWtype) bu.s.low)
4398d52ea6dSThomas Chou return 2;
4408d52ea6dSThomas Chou return 1;
4418d52ea6dSThomas Chou }
4428d52ea6dSThomas Chou
4438d52ea6dSThomas Chou
4448d52ea6dSThomas Chou UDWtype
__udivdi3(UDWtype n,UDWtype d)4458d52ea6dSThomas Chou __udivdi3 (UDWtype n, UDWtype d)
4468d52ea6dSThomas Chou {
4478d52ea6dSThomas Chou return __udivmoddi4 (n, d, (UDWtype *) 0);
4488d52ea6dSThomas Chou }
4498d52ea6dSThomas Chou
4508d52ea6dSThomas Chou UDWtype
__umoddi3(UDWtype u,UDWtype v)4518d52ea6dSThomas Chou __umoddi3 (UDWtype u, UDWtype v)
4528d52ea6dSThomas Chou {
4538d52ea6dSThomas Chou UDWtype w;
4548d52ea6dSThomas Chou (void) __udivmoddi4 (u, v, &w);
4558d52ea6dSThomas Chou
4568d52ea6dSThomas Chou return w;
4578d52ea6dSThomas Chou }
4588d52ea6dSThomas Chou
4598d52ea6dSThomas Chou static USItype
udivmodsi4(USItype num,USItype den,word_type modwanted)4608d52ea6dSThomas Chou udivmodsi4(USItype num, USItype den, word_type modwanted)
4618d52ea6dSThomas Chou {
4628d52ea6dSThomas Chou USItype bit = 1;
4638d52ea6dSThomas Chou USItype res = 0;
4648d52ea6dSThomas Chou
4658d52ea6dSThomas Chou while (den < num && bit && !(den & (1L<<31)))
4668d52ea6dSThomas Chou {
4678d52ea6dSThomas Chou den <<=1;
4688d52ea6dSThomas Chou bit <<=1;
4698d52ea6dSThomas Chou }
4708d52ea6dSThomas Chou while (bit)
4718d52ea6dSThomas Chou {
4728d52ea6dSThomas Chou if (num >= den)
4738d52ea6dSThomas Chou {
4748d52ea6dSThomas Chou num -= den;
4758d52ea6dSThomas Chou res |= bit;
4768d52ea6dSThomas Chou }
4778d52ea6dSThomas Chou bit >>=1;
4788d52ea6dSThomas Chou den >>=1;
4798d52ea6dSThomas Chou }
4808d52ea6dSThomas Chou if (modwanted) return num;
4818d52ea6dSThomas Chou return res;
4828d52ea6dSThomas Chou }
4838d52ea6dSThomas Chou
4848d52ea6dSThomas Chou SItype
__divsi3(SItype a,SItype b)4858d52ea6dSThomas Chou __divsi3 (SItype a, SItype b)
4868d52ea6dSThomas Chou {
4878d52ea6dSThomas Chou word_type neg = 0;
4888d52ea6dSThomas Chou SItype res;
4898d52ea6dSThomas Chou
4908d52ea6dSThomas Chou if (a < 0)
4918d52ea6dSThomas Chou {
4928d52ea6dSThomas Chou a = -a;
4938d52ea6dSThomas Chou neg = !neg;
4948d52ea6dSThomas Chou }
4958d52ea6dSThomas Chou
4968d52ea6dSThomas Chou if (b < 0)
4978d52ea6dSThomas Chou {
4988d52ea6dSThomas Chou b = -b;
4998d52ea6dSThomas Chou neg = !neg;
5008d52ea6dSThomas Chou }
5018d52ea6dSThomas Chou
5028d52ea6dSThomas Chou res = udivmodsi4 (a, b, 0);
5038d52ea6dSThomas Chou
5048d52ea6dSThomas Chou if (neg)
5058d52ea6dSThomas Chou res = -res;
5068d52ea6dSThomas Chou
5078d52ea6dSThomas Chou return res;
5088d52ea6dSThomas Chou }
5098d52ea6dSThomas Chou
5108d52ea6dSThomas Chou
5118d52ea6dSThomas Chou SItype
__udivsi3(SItype a,SItype b)5128d52ea6dSThomas Chou __udivsi3 (SItype a, SItype b)
5138d52ea6dSThomas Chou {
5148d52ea6dSThomas Chou return udivmodsi4 (a, b, 0);
5158d52ea6dSThomas Chou }
5168d52ea6dSThomas Chou
5178d52ea6dSThomas Chou
5188d52ea6dSThomas Chou SItype
__modsi3(SItype a,SItype b)5198d52ea6dSThomas Chou __modsi3 (SItype a, SItype b)
5208d52ea6dSThomas Chou {
5218d52ea6dSThomas Chou word_type neg = 0;
5228d52ea6dSThomas Chou SItype res;
5238d52ea6dSThomas Chou
5248d52ea6dSThomas Chou if (a < 0)
5258d52ea6dSThomas Chou {
5268d52ea6dSThomas Chou a = -a;
5278d52ea6dSThomas Chou neg = 1;
5288d52ea6dSThomas Chou }
5298d52ea6dSThomas Chou
5308d52ea6dSThomas Chou if (b < 0)
5318d52ea6dSThomas Chou b = -b;
5328d52ea6dSThomas Chou
5338d52ea6dSThomas Chou res = udivmodsi4 (a, b, 1);
5348d52ea6dSThomas Chou
5358d52ea6dSThomas Chou if (neg)
5368d52ea6dSThomas Chou res = -res;
5378d52ea6dSThomas Chou
5388d52ea6dSThomas Chou return res;
5398d52ea6dSThomas Chou }
5408d52ea6dSThomas Chou
5418d52ea6dSThomas Chou SItype
__mulsi3(SItype a,SItype b)5428d52ea6dSThomas Chou __mulsi3 (SItype a, SItype b)
5438d52ea6dSThomas Chou {
5448d52ea6dSThomas Chou SItype res = 0;
5458d52ea6dSThomas Chou USItype cnt = a;
5468d52ea6dSThomas Chou
5478d52ea6dSThomas Chou while (cnt)
5488d52ea6dSThomas Chou {
5498d52ea6dSThomas Chou if (cnt & 1)
5508d52ea6dSThomas Chou {
5518d52ea6dSThomas Chou res += b;
5528d52ea6dSThomas Chou }
5538d52ea6dSThomas Chou b <<= 1;
5548d52ea6dSThomas Chou cnt >>= 1;
5558d52ea6dSThomas Chou }
5568d52ea6dSThomas Chou
5578d52ea6dSThomas Chou return res;
5588d52ea6dSThomas Chou }
5598d52ea6dSThomas Chou
5608d52ea6dSThomas Chou SItype
__umodsi3(SItype a,SItype b)5618d52ea6dSThomas Chou __umodsi3 (SItype a, SItype b)
5628d52ea6dSThomas Chou
5638d52ea6dSThomas Chou {
5648d52ea6dSThomas Chou return udivmodsi4 (a, b, 1);
5658d52ea6dSThomas Chou }
5668d52ea6dSThomas Chou
5678d52ea6dSThomas Chou int
__gcc_bcmp(const unsigned char * s1,const unsigned char * s2,unsigned long size)5688d52ea6dSThomas Chou __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, unsigned long size)
5698d52ea6dSThomas Chou {
5708d52ea6dSThomas Chou while (size > 0)
5718d52ea6dSThomas Chou {
5728d52ea6dSThomas Chou const unsigned char c1 = *s1++, c2 = *s2++;
5738d52ea6dSThomas Chou if (c1 != c2)
5748d52ea6dSThomas Chou return c1 - c2;
5758d52ea6dSThomas Chou size--;
5768d52ea6dSThomas Chou }
5778d52ea6dSThomas Chou return 0;
5788d52ea6dSThomas Chou }
579