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