xref: /OK3568_Linux_fs/u-boot/arch/nios2/lib/libgcc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * This file is part of GNU CC.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun typedef unsigned int UWtype;
8*4882a593Smuzhiyun typedef unsigned int UHWtype;
9*4882a593Smuzhiyun typedef unsigned long long UDWtype;
10*4882a593Smuzhiyun #define W_TYPE_SIZE 32
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun typedef unsigned char UQItype;
13*4882a593Smuzhiyun typedef long SItype;
14*4882a593Smuzhiyun typedef unsigned long USItype;
15*4882a593Smuzhiyun typedef long long DItype;
16*4882a593Smuzhiyun typedef unsigned long long DSItype;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "longlong.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun typedef int word_type;
22*4882a593Smuzhiyun typedef long Wtype;
23*4882a593Smuzhiyun typedef long long DWtype;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun struct DWstruct { Wtype low, high;};
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun typedef union
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun   struct DWstruct s;
30*4882a593Smuzhiyun   DWtype ll;
31*4882a593Smuzhiyun } DWunion;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define BITS_PER_UNIT 8
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun UDWtype
36*4882a593Smuzhiyun __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun const UQItype __clz_tab[256] =
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun   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,
41*4882a593Smuzhiyun   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,
42*4882a593Smuzhiyun   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,
43*4882a593Smuzhiyun   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,
44*4882a593Smuzhiyun   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,
45*4882a593Smuzhiyun   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,
46*4882a593Smuzhiyun   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,
47*4882a593Smuzhiyun   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
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun DWtype
__ashldi3(DWtype u,word_type b)52*4882a593Smuzhiyun __ashldi3 (DWtype u, word_type b)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun   if (b == 0)
55*4882a593Smuzhiyun     return u;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun   const DWunion uu = {.ll = u};
58*4882a593Smuzhiyun   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
59*4882a593Smuzhiyun   DWunion w;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun   if (bm <= 0)
62*4882a593Smuzhiyun     {
63*4882a593Smuzhiyun       w.s.low = 0;
64*4882a593Smuzhiyun       w.s.high = (UWtype) uu.s.low << -bm;
65*4882a593Smuzhiyun     }
66*4882a593Smuzhiyun   else
67*4882a593Smuzhiyun     {
68*4882a593Smuzhiyun       const UWtype carries = (UWtype) uu.s.low >> bm;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun       w.s.low = (UWtype) uu.s.low << b;
71*4882a593Smuzhiyun       w.s.high = ((UWtype) uu.s.high << b) | carries;
72*4882a593Smuzhiyun     }
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun   return w.ll;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun DWtype
__ashrdi3(DWtype u,word_type b)78*4882a593Smuzhiyun __ashrdi3 (DWtype u, word_type b)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun   if (b == 0)
81*4882a593Smuzhiyun     return u;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun   const DWunion uu = {.ll = u};
84*4882a593Smuzhiyun   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
85*4882a593Smuzhiyun   DWunion w;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun   if (bm <= 0)
88*4882a593Smuzhiyun     {
89*4882a593Smuzhiyun       /* w.s.high = 1..1 or 0..0 */
90*4882a593Smuzhiyun       w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
91*4882a593Smuzhiyun       w.s.low = uu.s.high >> -bm;
92*4882a593Smuzhiyun     }
93*4882a593Smuzhiyun   else
94*4882a593Smuzhiyun     {
95*4882a593Smuzhiyun       const UWtype carries = (UWtype) uu.s.high << bm;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun       w.s.high = uu.s.high >> b;
98*4882a593Smuzhiyun       w.s.low = ((UWtype) uu.s.low >> b) | carries;
99*4882a593Smuzhiyun     }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun   return w.ll;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun DWtype
__lshrdi3(DWtype u,word_type b)105*4882a593Smuzhiyun __lshrdi3 (DWtype u, word_type b)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun   if (b == 0)
108*4882a593Smuzhiyun     return u;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun   const DWunion uu = {.ll = u};
111*4882a593Smuzhiyun   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
112*4882a593Smuzhiyun   DWunion w;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun   if (bm <= 0)
115*4882a593Smuzhiyun     {
116*4882a593Smuzhiyun       w.s.high = 0;
117*4882a593Smuzhiyun       w.s.low = (UWtype) uu.s.high >> -bm;
118*4882a593Smuzhiyun     }
119*4882a593Smuzhiyun   else
120*4882a593Smuzhiyun     {
121*4882a593Smuzhiyun       const UWtype carries = (UWtype) uu.s.high << bm;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun       w.s.high = (UWtype) uu.s.high >> b;
124*4882a593Smuzhiyun       w.s.low = ((UWtype) uu.s.low >> b) | carries;
125*4882a593Smuzhiyun     }
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun   return w.ll;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun word_type
__cmpdi2(DWtype a,DWtype b)131*4882a593Smuzhiyun __cmpdi2 (DWtype a, DWtype b)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun   const DWunion au = {.ll = a};
134*4882a593Smuzhiyun   const DWunion bu = {.ll = b};
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun   if (au.s.high < bu.s.high)
137*4882a593Smuzhiyun     return 0;
138*4882a593Smuzhiyun   else if (au.s.high > bu.s.high)
139*4882a593Smuzhiyun     return 2;
140*4882a593Smuzhiyun   if ((UWtype) au.s.low < (UWtype) bu.s.low)
141*4882a593Smuzhiyun     return 0;
142*4882a593Smuzhiyun   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
143*4882a593Smuzhiyun     return 2;
144*4882a593Smuzhiyun   return 1;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun UDWtype
__udivmoddi4(UDWtype n,UDWtype d,UDWtype * rp)148*4882a593Smuzhiyun __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun   const DWunion nn = {.ll = n};
151*4882a593Smuzhiyun   const DWunion dd = {.ll = d};
152*4882a593Smuzhiyun   DWunion rr;
153*4882a593Smuzhiyun   UWtype d0, d1, n0, n1, n2;
154*4882a593Smuzhiyun   UWtype q0, q1;
155*4882a593Smuzhiyun   UWtype b, bm;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun   d0 = dd.s.low;
158*4882a593Smuzhiyun   d1 = dd.s.high;
159*4882a593Smuzhiyun   n0 = nn.s.low;
160*4882a593Smuzhiyun   n1 = nn.s.high;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #if !UDIV_NEEDS_NORMALIZATION
163*4882a593Smuzhiyun   if (d1 == 0)
164*4882a593Smuzhiyun     {
165*4882a593Smuzhiyun       if (d0 > n1)
166*4882a593Smuzhiyun 	{
167*4882a593Smuzhiyun 	  /* 0q = nn / 0D */
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	  udiv_qrnnd (q0, n0, n1, n0, d0);
170*4882a593Smuzhiyun 	  q1 = 0;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	  /* Remainder in n0.  */
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun       else
175*4882a593Smuzhiyun 	{
176*4882a593Smuzhiyun 	  /* qq = NN / 0d */
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	  if (d0 == 0)
179*4882a593Smuzhiyun 	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	  udiv_qrnnd (q1, n1, 0, n1, d0);
182*4882a593Smuzhiyun 	  udiv_qrnnd (q0, n0, n1, n0, d0);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	  /* Remainder in n0.  */
185*4882a593Smuzhiyun 	}
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun       if (rp != 0)
188*4882a593Smuzhiyun 	{
189*4882a593Smuzhiyun 	  rr.s.low = n0;
190*4882a593Smuzhiyun 	  rr.s.high = 0;
191*4882a593Smuzhiyun 	  *rp = rr.ll;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun     }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #else /* UDIV_NEEDS_NORMALIZATION */
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun   if (d1 == 0)
198*4882a593Smuzhiyun     {
199*4882a593Smuzhiyun       if (d0 > n1)
200*4882a593Smuzhiyun 	{
201*4882a593Smuzhiyun 	  /* 0q = nn / 0D */
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	  count_leading_zeros (bm, d0);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	  if (bm != 0)
206*4882a593Smuzhiyun 	    {
207*4882a593Smuzhiyun 	      /* Normalize, i.e. make the most significant bit of the
208*4882a593Smuzhiyun 		 denominator set.  */
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	      d0 = d0 << bm;
211*4882a593Smuzhiyun 	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
212*4882a593Smuzhiyun 	      n0 = n0 << bm;
213*4882a593Smuzhiyun 	    }
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	  udiv_qrnnd (q0, n0, n1, n0, d0);
216*4882a593Smuzhiyun 	  q1 = 0;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	  /* Remainder in n0 >> bm.  */
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun       else
221*4882a593Smuzhiyun 	{
222*4882a593Smuzhiyun 	  /* qq = NN / 0d */
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	  if (d0 == 0)
225*4882a593Smuzhiyun 	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	  count_leading_zeros (bm, d0);
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	  if (bm == 0)
230*4882a593Smuzhiyun 	    {
231*4882a593Smuzhiyun 	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
232*4882a593Smuzhiyun 		 conclude (the most significant bit of n1 is set) /\ (the
233*4882a593Smuzhiyun 		 leading quotient digit q1 = 1).
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		 This special case is necessary, not an optimization.
236*4882a593Smuzhiyun 		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	      n1 -= d0;
239*4882a593Smuzhiyun 	      q1 = 1;
240*4882a593Smuzhiyun 	    }
241*4882a593Smuzhiyun 	  else
242*4882a593Smuzhiyun 	    {
243*4882a593Smuzhiyun 	      /* Normalize.  */
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	      b = W_TYPE_SIZE - bm;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	      d0 = d0 << bm;
248*4882a593Smuzhiyun 	      n2 = n1 >> b;
249*4882a593Smuzhiyun 	      n1 = (n1 << bm) | (n0 >> b);
250*4882a593Smuzhiyun 	      n0 = n0 << bm;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	      udiv_qrnnd (q1, n1, n2, n1, d0);
253*4882a593Smuzhiyun 	    }
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	  /* n1 != d0...  */
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	  udiv_qrnnd (q0, n0, n1, n0, d0);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	  /* Remainder in n0 >> bm.  */
260*4882a593Smuzhiyun 	}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun       if (rp != 0)
263*4882a593Smuzhiyun 	{
264*4882a593Smuzhiyun 	  rr.s.low = n0 >> bm;
265*4882a593Smuzhiyun 	  rr.s.high = 0;
266*4882a593Smuzhiyun 	  *rp = rr.ll;
267*4882a593Smuzhiyun 	}
268*4882a593Smuzhiyun     }
269*4882a593Smuzhiyun #endif /* UDIV_NEEDS_NORMALIZATION */
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun   else
272*4882a593Smuzhiyun     {
273*4882a593Smuzhiyun       if (d1 > n1)
274*4882a593Smuzhiyun 	{
275*4882a593Smuzhiyun 	  /* 00 = nn / DD */
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	  q0 = 0;
278*4882a593Smuzhiyun 	  q1 = 0;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	  /* Remainder in n1n0.  */
281*4882a593Smuzhiyun 	  if (rp != 0)
282*4882a593Smuzhiyun 	    {
283*4882a593Smuzhiyun 	      rr.s.low = n0;
284*4882a593Smuzhiyun 	      rr.s.high = n1;
285*4882a593Smuzhiyun 	      *rp = rr.ll;
286*4882a593Smuzhiyun 	    }
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun       else
289*4882a593Smuzhiyun 	{
290*4882a593Smuzhiyun 	  /* 0q = NN / dd */
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	  count_leading_zeros (bm, d1);
293*4882a593Smuzhiyun 	  if (bm == 0)
294*4882a593Smuzhiyun 	    {
295*4882a593Smuzhiyun 	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
296*4882a593Smuzhiyun 		 conclude (the most significant bit of n1 is set) /\ (the
297*4882a593Smuzhiyun 		 quotient digit q0 = 0 or 1).
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		 This special case is necessary, not an optimization.  */
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	      /* The condition on the next line takes advantage of that
302*4882a593Smuzhiyun 		 n1 >= d1 (true due to program flow).  */
303*4882a593Smuzhiyun 	      if (n1 > d1 || n0 >= d0)
304*4882a593Smuzhiyun 		{
305*4882a593Smuzhiyun 		  q0 = 1;
306*4882a593Smuzhiyun 		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 	      else
309*4882a593Smuzhiyun 		q0 = 0;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	      q1 = 0;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	      if (rp != 0)
314*4882a593Smuzhiyun 		{
315*4882a593Smuzhiyun 		  rr.s.low = n0;
316*4882a593Smuzhiyun 		  rr.s.high = n1;
317*4882a593Smuzhiyun 		  *rp = rr.ll;
318*4882a593Smuzhiyun 		}
319*4882a593Smuzhiyun 	    }
320*4882a593Smuzhiyun 	  else
321*4882a593Smuzhiyun 	    {
322*4882a593Smuzhiyun 	      UWtype m1, m0;
323*4882a593Smuzhiyun 	      /* Normalize.  */
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	      b = W_TYPE_SIZE - bm;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	      d1 = (d1 << bm) | (d0 >> b);
328*4882a593Smuzhiyun 	      d0 = d0 << bm;
329*4882a593Smuzhiyun 	      n2 = n1 >> b;
330*4882a593Smuzhiyun 	      n1 = (n1 << bm) | (n0 >> b);
331*4882a593Smuzhiyun 	      n0 = n0 << bm;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	      udiv_qrnnd (q0, n1, n2, n1, d1);
334*4882a593Smuzhiyun 	      umul_ppmm (m1, m0, q0, d0);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	      if (m1 > n1 || (m1 == n1 && m0 > n0))
337*4882a593Smuzhiyun 		{
338*4882a593Smuzhiyun 		  q0--;
339*4882a593Smuzhiyun 		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
340*4882a593Smuzhiyun 		}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	      q1 = 0;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	      /* Remainder in (n1n0 - m1m0) >> bm.  */
345*4882a593Smuzhiyun 	      if (rp != 0)
346*4882a593Smuzhiyun 		{
347*4882a593Smuzhiyun 		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
348*4882a593Smuzhiyun 		  rr.s.low = (n1 << b) | (n0 >> bm);
349*4882a593Smuzhiyun 		  rr.s.high = n1 >> bm;
350*4882a593Smuzhiyun 		  *rp = rr.ll;
351*4882a593Smuzhiyun 		}
352*4882a593Smuzhiyun 	    }
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun     }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun   const DWunion ww = {{.low = q0, .high = q1}};
357*4882a593Smuzhiyun   return ww.ll;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun DWtype
__divdi3(DWtype u,DWtype v)361*4882a593Smuzhiyun __divdi3 (DWtype u, DWtype v)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun   word_type c = 0;
364*4882a593Smuzhiyun   DWunion uu = {.ll = u};
365*4882a593Smuzhiyun   DWunion vv = {.ll = v};
366*4882a593Smuzhiyun   DWtype w;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun   if (uu.s.high < 0)
369*4882a593Smuzhiyun     c = ~c,
370*4882a593Smuzhiyun     uu.ll = -uu.ll;
371*4882a593Smuzhiyun   if (vv.s.high < 0)
372*4882a593Smuzhiyun     c = ~c,
373*4882a593Smuzhiyun     vv.ll = -vv.ll;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
376*4882a593Smuzhiyun   if (c)
377*4882a593Smuzhiyun     w = -w;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun   return w;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun DWtype
__negdi2(DWtype u)383*4882a593Smuzhiyun __negdi2 (DWtype u)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun   const DWunion uu = {.ll = u};
386*4882a593Smuzhiyun   const DWunion w = { {.low = -uu.s.low,
387*4882a593Smuzhiyun 		       .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun   return w.ll;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun DWtype
__muldi3(DWtype u,DWtype v)394*4882a593Smuzhiyun __muldi3 (DWtype u, DWtype v)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun   const DWunion uu = {.ll = u};
397*4882a593Smuzhiyun   const DWunion vv = {.ll = v};
398*4882a593Smuzhiyun   DWunion  w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
401*4882a593Smuzhiyun   + (UWtype) uu.s.high * (UWtype) vv.s.low);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun   return w.ll;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun DWtype
__moddi3(DWtype u,DWtype v)407*4882a593Smuzhiyun __moddi3 (DWtype u, DWtype v)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun   word_type c = 0;
410*4882a593Smuzhiyun   DWunion uu = {.ll = u};
411*4882a593Smuzhiyun   DWunion vv = {.ll = v};
412*4882a593Smuzhiyun   DWtype w;
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun   if (uu.s.high < 0)
415*4882a593Smuzhiyun     c = ~c,
416*4882a593Smuzhiyun     uu.ll = -uu.ll;
417*4882a593Smuzhiyun   if (vv.s.high < 0)
418*4882a593Smuzhiyun     vv.ll = -vv.ll;
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun   (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
421*4882a593Smuzhiyun   if (c)
422*4882a593Smuzhiyun     w = -w;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun   return w;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun word_type
__ucmpdi2(DWtype a,DWtype b)428*4882a593Smuzhiyun __ucmpdi2 (DWtype a, DWtype b)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun   const DWunion au = {.ll = a};
431*4882a593Smuzhiyun   const DWunion bu = {.ll = b};
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun   if ((UWtype) au.s.high < (UWtype) bu.s.high)
434*4882a593Smuzhiyun     return 0;
435*4882a593Smuzhiyun   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
436*4882a593Smuzhiyun     return 2;
437*4882a593Smuzhiyun   if ((UWtype) au.s.low < (UWtype) bu.s.low)
438*4882a593Smuzhiyun     return 0;
439*4882a593Smuzhiyun   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
440*4882a593Smuzhiyun     return 2;
441*4882a593Smuzhiyun   return 1;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun UDWtype
__udivdi3(UDWtype n,UDWtype d)446*4882a593Smuzhiyun __udivdi3 (UDWtype n, UDWtype d)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun   return __udivmoddi4 (n, d, (UDWtype *) 0);
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun UDWtype
__umoddi3(UDWtype u,UDWtype v)452*4882a593Smuzhiyun __umoddi3 (UDWtype u, UDWtype v)
453*4882a593Smuzhiyun {
454*4882a593Smuzhiyun   UDWtype w;
455*4882a593Smuzhiyun   (void) __udivmoddi4 (u, v, &w);
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun   return w;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun static USItype
udivmodsi4(USItype num,USItype den,word_type modwanted)461*4882a593Smuzhiyun udivmodsi4(USItype num, USItype den, word_type modwanted)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun   USItype bit = 1;
464*4882a593Smuzhiyun   USItype res = 0;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun   while (den < num && bit && !(den & (1L<<31)))
467*4882a593Smuzhiyun     {
468*4882a593Smuzhiyun       den <<=1;
469*4882a593Smuzhiyun       bit <<=1;
470*4882a593Smuzhiyun     }
471*4882a593Smuzhiyun   while (bit)
472*4882a593Smuzhiyun     {
473*4882a593Smuzhiyun       if (num >= den)
474*4882a593Smuzhiyun 	{
475*4882a593Smuzhiyun 	  num -= den;
476*4882a593Smuzhiyun 	  res |= bit;
477*4882a593Smuzhiyun 	}
478*4882a593Smuzhiyun       bit >>=1;
479*4882a593Smuzhiyun       den >>=1;
480*4882a593Smuzhiyun     }
481*4882a593Smuzhiyun   if (modwanted) return num;
482*4882a593Smuzhiyun   return res;
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun SItype
__divsi3(SItype a,SItype b)486*4882a593Smuzhiyun __divsi3 (SItype a, SItype b)
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun   word_type neg = 0;
489*4882a593Smuzhiyun   SItype res;
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun   if (a < 0)
492*4882a593Smuzhiyun     {
493*4882a593Smuzhiyun       a = -a;
494*4882a593Smuzhiyun       neg = !neg;
495*4882a593Smuzhiyun     }
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun   if (b < 0)
498*4882a593Smuzhiyun     {
499*4882a593Smuzhiyun       b = -b;
500*4882a593Smuzhiyun       neg = !neg;
501*4882a593Smuzhiyun     }
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun   res = udivmodsi4 (a, b, 0);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun   if (neg)
506*4882a593Smuzhiyun     res = -res;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun   return res;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun SItype
__udivsi3(SItype a,SItype b)513*4882a593Smuzhiyun __udivsi3 (SItype a, SItype b)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun   return udivmodsi4 (a, b, 0);
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun SItype
__modsi3(SItype a,SItype b)520*4882a593Smuzhiyun __modsi3 (SItype a, SItype b)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun   word_type neg = 0;
523*4882a593Smuzhiyun   SItype res;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun   if (a < 0)
526*4882a593Smuzhiyun     {
527*4882a593Smuzhiyun       a = -a;
528*4882a593Smuzhiyun       neg = 1;
529*4882a593Smuzhiyun     }
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun   if (b < 0)
532*4882a593Smuzhiyun     b = -b;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun   res = udivmodsi4 (a, b, 1);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun   if (neg)
537*4882a593Smuzhiyun     res = -res;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun   return res;
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun SItype
__mulsi3(SItype a,SItype b)543*4882a593Smuzhiyun __mulsi3 (SItype a, SItype b)
544*4882a593Smuzhiyun {
545*4882a593Smuzhiyun   SItype res = 0;
546*4882a593Smuzhiyun   USItype cnt = a;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun   while (cnt)
549*4882a593Smuzhiyun     {
550*4882a593Smuzhiyun       if (cnt & 1)
551*4882a593Smuzhiyun 	{
552*4882a593Smuzhiyun 	  res += b;
553*4882a593Smuzhiyun 	}
554*4882a593Smuzhiyun       b <<= 1;
555*4882a593Smuzhiyun       cnt >>= 1;
556*4882a593Smuzhiyun     }
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun   return res;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun SItype
__umodsi3(SItype a,SItype b)562*4882a593Smuzhiyun __umodsi3 (SItype a, SItype b)
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun   return udivmodsi4 (a, b, 1);
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun int
__gcc_bcmp(const unsigned char * s1,const unsigned char * s2,unsigned long size)569*4882a593Smuzhiyun __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, unsigned long size)
570*4882a593Smuzhiyun {
571*4882a593Smuzhiyun   while (size > 0)
572*4882a593Smuzhiyun     {
573*4882a593Smuzhiyun       const unsigned char c1 = *s1++, c2 = *s2++;
574*4882a593Smuzhiyun       if (c1 != c2)
575*4882a593Smuzhiyun 	return c1 - c2;
576*4882a593Smuzhiyun       size--;
577*4882a593Smuzhiyun     }
578*4882a593Smuzhiyun   return 0;
579*4882a593Smuzhiyun }
580