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