]> gcc.gnu.org Git - gcc.git/blame - gcc/longlong.h
*** empty log message ***
[gcc.git] / gcc / longlong.h
CommitLineData
e1a79915 1/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
d83dd29a 2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
e1a79915
RS
3
4 This definition file is free software; you can redistribute it
5 and/or modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 2, or (at your option) any later version.
8
9 This definition file is distributed in the hope that it will be
10 useful, but WITHOUT ANY WARRANTY; without even the implied
11 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 See the GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18#ifndef LONG_TYPE_SIZE
19#define LONG_TYPE_SIZE 32
20#endif
21
22#define __BITS4 (LONG_TYPE_SIZE / 4)
23#define __ll_B (1L << (LONG_TYPE_SIZE / 2))
e6c5404d
TG
24#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
25#define __ll_highpart(t) ((USItype) (t) / __ll_B)
e1a79915 26
2e8a6600 27/* Define auxiliary asm macros.
e1a79915
RS
28
29 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
e6c5404d
TG
30 multiplies two USItype integers MULTIPLER and MULTIPLICAND,
31 and generates a two-part USItype product in HIGH_PROD and
e1a79915
RS
32 LOW_PROD.
33
e6c5404d
TG
34 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
35 and returns a UDItype product. This is just a variant of umul_ppmm.
e1a79915
RS
36
37 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
38 denominator) divides a two-word unsigned integer, composed by the
39 integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
40 places the quotient in QUOTIENT and the remainder in REMAINDER.
41 HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
42 If, in addition, the most significant bit of DENOMINATOR must be 1,
43 then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
44
45 4) count_leading_zeros(count, x) counts the number of zero-bits from
46 the msb to the first non-zero bit. This is the number of steps X
47 needs to be shifted left to set the msb. Undefined for X == 0.
48
49 5) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
50 high_addend_2, low_addend_2) adds two two-word unsigned integers,
51 composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
52 LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
53 LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
54 lost.
55
56 6) sub_ddmmss(high_difference, low_difference, high_minuend,
57 low_minuend, high_subtrahend, low_subtrahend) subtracts two
58 two-word unsigned integers, composed by HIGH_MINUEND_1 and
59 LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
60 respectively. The result is placed in HIGH_DIFFERENCE and
61 LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
62 and is lost.
63
64 If any of these macros are left undefined for a particular CPU,
65 C macros are used. */
66
67/* The CPUs come in alphabetical order below.
68
69 Please add support for more CPUs here, or improve the current support
70 for the CPUs below!
d83dd29a
TG
71 (E.g. WE32100, i960, IBM360.) */
72
3a0d22dd
MM
73#if defined (__GNUC__) && !defined (NO_ASM)
74
d83dd29a
TG
75/* We sometimes need to clobber "cc" with gcc2, but that would not be
76 understood by gcc1. Use cpp to avoid major code duplication. */
77#if __GNUC__ < 2
78#define __CLOBBER_CC
79#define __AND_CLOBBER_CC
80#else /* __GNUC__ >= 2 */
81#define __CLOBBER_CC : "cc"
82#define __AND_CLOBBER_CC , "cc"
83#endif /* __GNUC__ < 2 */
e1a79915 84
e1a79915
RS
85#if defined (__a29k__) || defined (___AM29K__)
86#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
87 __asm__ ("add %1,%4,%5
88 addc %0,%2,%3" \
e6c5404d
TG
89 : "=r" ((USItype)(sh)), \
90 "=&r" ((USItype)(sl)) \
91 : "%r" ((USItype)(ah)), \
92 "rI" ((USItype)(bh)), \
93 "%r" ((USItype)(al)), \
94 "rI" ((USItype)(bl)))
e1a79915
RS
95#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
96 __asm__ ("sub %1,%4,%5
97 subc %0,%2,%3" \
e6c5404d
TG
98 : "=r" ((USItype)(sh)), \
99 "=&r" ((USItype)(sl)) \
100 : "r" ((USItype)(ah)), \
101 "rI" ((USItype)(bh)), \
102 "r" ((USItype)(al)), \
103 "rI" ((USItype)(bl)))
e1a79915
RS
104#define umul_ppmm(xh, xl, m0, m1) \
105 do { \
e6c5404d 106 USItype __m0 = (m0), __m1 = (m1); \
d83dd29a 107 __asm__ ("multiplu %0,%1,%2" \
e6c5404d 108 : "=r" ((USItype)(xl)) \
d83dd29a
TG
109 : "r" (__m0), \
110 "r" (__m1)); \
111 __asm__ ("multmu %0,%1,%2" \
e6c5404d 112 : "=r" ((USItype)(xh)) \
d83dd29a
TG
113 : "r" (__m0), \
114 "r" (__m1)); \
e1a79915
RS
115 } while (0)
116#define udiv_qrnnd(q, r, n1, n0, d) \
117 __asm__ ("dividu %0,%3,%4" \
e6c5404d
TG
118 : "=r" ((USItype)(q)), \
119 "=q" ((USItype)(r)) \
120 : "1" ((USItype)(n1)), \
121 "r" ((USItype)(n0)), \
122 "r" ((USItype)(d)))
e1a79915 123#define count_leading_zeros(count, x) \
d83dd29a 124 __asm__ ("clz %0,%1" \
e6c5404d
TG
125 : "=r" ((USItype)(count)) \
126 : "r" ((USItype)(x)))
e1a79915
RS
127#endif /* __a29k__ */
128
129#if defined (__arm__)
130#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
131 __asm__ ("adds %1,%4,%5
132 adc %0,%2,%3" \
e6c5404d
TG
133 : "=r" ((USItype)(sh)), \
134 "=&r" ((USItype)(sl)) \
135 : "%r" ((USItype)(ah)), \
136 "rI" ((USItype)(bh)), \
137 "%r" ((USItype)(al)), \
138 "rI" ((USItype)(bl)))
e1a79915
RS
139#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
140 __asm__ ("subs %1,%4,%5
141 sbc %0,%2,%3" \
e6c5404d
TG
142 : "=r" ((USItype)(sh)), \
143 "=&r" ((USItype)(sl)) \
144 : "r" ((USItype)(ah)), \
145 "rI" ((USItype)(bh)), \
146 "r" ((USItype)(al)), \
147 "rI" ((USItype)(bl)))
e1a79915
RS
148#endif /* __arm__ */
149
150#if defined (__gmicro__)
151#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
152 __asm__ ("add.w %5,%1
153 addx %3,%0" \
e6c5404d
TG
154 : "=g" ((USItype)(sh)), \
155 "=&g" ((USItype)(sl)) \
156 : "%0" ((USItype)(ah)), \
157 "g" ((USItype)(bh)), \
158 "%1" ((USItype)(al)), \
159 "g" ((USItype)(bl)))
e1a79915
RS
160#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
161 __asm__ ("sub.w %5,%1
162 subx %3,%0" \
e6c5404d
TG
163 : "=g" ((USItype)(sh)), \
164 "=&g" ((USItype)(sl)) \
165 : "0" ((USItype)(ah)), \
166 "g" ((USItype)(bh)), \
167 "1" ((USItype)(al)), \
168 "g" ((USItype)(bl)))
e1a79915
RS
169#define umul_ppmm(ph, pl, m0, m1) \
170 __asm__ ("mulx %3,%0,%1" \
e6c5404d
TG
171 : "=g" ((USItype)(ph)), \
172 "=r" ((USItype)(pl)) \
173 : "%0" ((USItype)(m0)), \
174 "g" ((USItype)(m1)))
e1a79915
RS
175#define udiv_qrnnd(q, r, nh, nl, d) \
176 __asm__ ("divx %4,%0,%1" \
e6c5404d
TG
177 : "=g" ((USItype)(q)), \
178 "=r" ((USItype)(r)) \
179 : "1" ((USItype)(nh)), \
180 "0" ((USItype)(nl)), \
181 "g" ((USItype)(d)))
e1a79915
RS
182#define count_leading_zeros(count, x) \
183 __asm__ ("bsch/1 %1,%0" \
d83dd29a 184 : "=g" (count) \
e6c5404d
TG
185 : "g" ((USItype)(x)), \
186 "0" ((USItype)0))
e1a79915
RS
187#endif
188
189#if defined (__hppa)
190#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
191 __asm__ ("add %4,%5,%1
192 addc %2,%3,%0" \
e6c5404d
TG
193 : "=r" ((USItype)(sh)), \
194 "=&r" ((USItype)(sl)) \
195 : "%rM" ((USItype)(ah)), \
196 "rM" ((USItype)(bh)), \
197 "%rM" ((USItype)(al)), \
198 "rM" ((USItype)(bl)))
e1a79915
RS
199#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
200 __asm__ ("sub %5,%4,%1
201 subb %3,%2,%0" \
e6c5404d
TG
202 : "=r" ((USItype)(sh)), \
203 "=&r" ((USItype)(sl)) \
204 : "rM" ((USItype)(ah)), \
205 "rM" ((USItype)(bh)), \
206 "rM" ((USItype)(al)), \
207 "rM" ((USItype)(bl)))
d83dd29a
TG
208#if defined (_PA_RISC1_1)
209#define umul_ppmm(w1, w0, u, v) \
210 do { \
211 union \
212 { \
e6c5404d
TG
213 UDItype __f; \
214 struct {USItype __w1, __w0;} __w1w0; \
d83dd29a
TG
215 } __t; \
216 __asm__ ("xmpyu %1,%2,%0" \
217 : "=x" (__t.__f) \
e6c5404d
TG
218 : "x" ((USItype)(u)), \
219 "x" ((USItype)(v))); \
d83dd29a
TG
220 (w1) = __t.__w1w0.__w1; \
221 (w0) = __t.__w1w0.__w0; \
222 } while (0)
223#define UMUL_TIME 8
224#else
225#define UMUL_TIME 30
226#endif
227#define UDIV_TIME 40
e1a79915
RS
228#endif
229
230#if defined (__i386__) || defined (__i486__)
231#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
232 __asm__ ("addl %5,%1
233 adcl %3,%0" \
e6c5404d
TG
234 : "=r" ((USItype)(sh)), \
235 "=&r" ((USItype)(sl)) \
236 : "%0" ((USItype)(ah)), \
237 "g" ((USItype)(bh)), \
238 "%1" ((USItype)(al)), \
239 "g" ((USItype)(bl)))
e1a79915
RS
240#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
241 __asm__ ("subl %5,%1
242 sbbl %3,%0" \
e6c5404d
TG
243 : "=r" ((USItype)(sh)), \
244 "=&r" ((USItype)(sl)) \
245 : "0" ((USItype)(ah)), \
246 "g" ((USItype)(bh)), \
247 "1" ((USItype)(al)), \
248 "g" ((USItype)(bl)))
e1a79915
RS
249#define umul_ppmm(w1, w0, u, v) \
250 __asm__ ("mull %3" \
e6c5404d
TG
251 : "=a" ((USItype)(w0)), \
252 "=d" ((USItype)(w1)) \
253 : "%0" ((USItype)(u)), \
254 "rm" ((USItype)(v)))
e1a79915
RS
255#define udiv_qrnnd(q, r, n1, n0, d) \
256 __asm__ ("divl %4" \
e6c5404d
TG
257 : "=a" ((USItype)(q)), \
258 "=d" ((USItype)(r)) \
259 : "0" ((USItype)(n0)), \
260 "1" ((USItype)(n1)), \
261 "rm" ((USItype)(d)))
e1a79915
RS
262#define count_leading_zeros(count, x) \
263 do { \
e6c5404d 264 USItype __cbtmp; \
e1a79915 265 __asm__ ("bsrl %1,%0" \
e6c5404d 266 : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
e1a79915
RS
267 (count) = __cbtmp ^ 31; \
268 } while (0)
d83dd29a
TG
269#define UMUL_TIME 40
270#define UDIV_TIME 40
e1a79915
RS
271#endif /* 80x86 */
272
273#if defined (__i860__)
274#if 0
275/* Make sure these patterns really improve the code before
276 switching them on. */
277#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
278 do { \
279 union \
280 { \
e6c5404d
TG
281 DItype __ll; \
282 struct {USItype __l, __h;} __i; \
e1a79915 283 } __a, __b, __s; \
e6c5404d
TG
284 __a.__i.__l = (al); \
285 __a.__i.__h = (ah); \
286 __b.__i.__l = (bl); \
287 __b.__i.__h = (bh); \
e1a79915 288 __asm__ ("fiadd.dd %1,%2,%0" \
e6c5404d
TG
289 : "=f" (__s.__ll) \
290 : "%f" (__a.__ll), "f" (__b.__ll)); \
291 (sh) = __s.__i.__h; \
292 (sl) = __s.__i.__l; \
e1a79915
RS
293 } while (0)
294#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
295 do { \
296 union \
297 { \
e6c5404d
TG
298 DItype __ll; \
299 struct {USItype __l, __h;} __i; \
e1a79915 300 } __a, __b, __s; \
e6c5404d
TG
301 __a.__i.__l = (al); \
302 __a.__i.__h = (ah); \
303 __b.__i.__l = (bl); \
304 __b.__i.__h = (bh); \
e1a79915 305 __asm__ ("fisub.dd %1,%2,%0" \
e6c5404d
TG
306 : "=f" (__s.__ll) \
307 : "%f" (__a.__ll), "f" (__b.__ll)); \
308 (sh) = __s.__i.__h; \
309 (sl) = __s.__i.__l; \
e1a79915
RS
310 } while (0)
311#endif
312#endif /* __i860__ */
313
314#if defined (___IBMR2__) /* IBM RS6000 */
315#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
d83dd29a 316 __asm__ ("a%I5 %1,%4,%5
e1a79915 317 ae %0,%2,%3" \
e6c5404d
TG
318 : "=r" ((USItype)(sh)), \
319 "=&r" ((USItype)(sl)) \
320 : "%r" ((USItype)(ah)), \
321 "r" ((USItype)(bh)), \
322 "%r" ((USItype)(al)), \
323 "rI" ((USItype)(bl)))
e1a79915 324#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
d83dd29a 325 __asm__ ("sf%I4 %1,%5,%4
e1a79915 326 sfe %0,%3,%2" \
e6c5404d
TG
327 : "=r" ((USItype)(sh)), \
328 "=&r" ((USItype)(sl)) \
329 : "r" ((USItype)(ah)), \
330 "r" ((USItype)(bh)), \
331 "rI" ((USItype)(al)), \
332 "r" ((USItype)(bl)))
e1a79915
RS
333#define umul_ppmm(xh, xl, m0, m1) \
334 do { \
e6c5404d 335 USItype __m0 = (m0), __m1 = (m1); \
e1a79915 336 __asm__ ("mul %0,%2,%3" \
e6c5404d
TG
337 : "=r" ((USItype)(xh)), \
338 "=q" ((USItype)(xl)) \
d83dd29a
TG
339 : "r" (__m0), \
340 "r" (__m1)); \
e6c5404d
TG
341 (xh) += ((((SItype) __m0 >> 31) & __m1) \
342 + (((SItype) __m1 >> 31) & __m0)); \
e1a79915 343 } while (0)
d83dd29a
TG
344#define smul_ppmm(xh, xl, m0, m1) \
345 __asm__ ("mul %0,%2,%3" \
e6c5404d
TG
346 : "=r" ((USItype)(xh)), \
347 "=q" ((USItype)(xl)) \
348 : "r" ((USItype)(m0)), \
349 "r" ((USItype)(m1)))
e1a79915 350#define UMUL_TIME 8
d83dd29a
TG
351#define sdiv_qrnnd(q, r, nh, nl, d) \
352 __asm__ ("div %0,%2,%4" \
e6c5404d
TG
353 : "=r" ((USItype)(q)), "=q" ((USItype)(r)) \
354 : "r" ((USItype)(nh)), "1" ((USItype)(nl)), "r" ((USItype)(d)))
e1a79915
RS
355#define UDIV_TIME 40
356#define UDIV_NEEDS_NORMALIZATION 1
357#define count_leading_zeros(count, x) \
358 __asm__ ("cntlz %0,%1" \
e6c5404d
TG
359 : "=r" ((USItype)(count)) \
360 : "r" ((USItype)(x)))
e1a79915
RS
361#endif /* ___IBMR2__ */
362
363#if defined (__mc68000__)
364#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
365 __asm__ ("add%.l %5,%1
366 addx%.l %3,%0" \
e6c5404d
TG
367 : "=d" ((USItype)(sh)), \
368 "=&d" ((USItype)(sl)) \
369 : "%0" ((USItype)(ah)), \
370 "d" ((USItype)(bh)), \
371 "%1" ((USItype)(al)), \
372 "g" ((USItype)(bl)))
e1a79915
RS
373#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
374 __asm__ ("sub%.l %5,%1
375 subx%.l %3,%0" \
e6c5404d
TG
376 : "=d" ((USItype)(sh)), \
377 "=&d" ((USItype)(sl)) \
378 : "0" ((USItype)(ah)), \
379 "d" ((USItype)(bh)), \
380 "1" ((USItype)(al)), \
381 "g" ((USItype)(bl)))
e1a79915
RS
382#if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
383#define umul_ppmm(w1, w0, u, v) \
384 __asm__ ("mulu%.l %3,%1:%0" \
e6c5404d
TG
385 : "=d" ((USItype)(w0)), \
386 "=d" ((USItype)(w1)) \
387 : "%0" ((USItype)(u)), \
388 "dmi" ((USItype)(v)))
d83dd29a 389#define UMUL_TIME 45
e1a79915
RS
390#define udiv_qrnnd(q, r, n1, n0, d) \
391 __asm__ ("divu%.l %4,%1:%0" \
e6c5404d
TG
392 : "=d" ((USItype)(q)), \
393 "=d" ((USItype)(r)) \
394 : "0" ((USItype)(n0)), \
395 "1" ((USItype)(n1)), \
396 "dmi" ((USItype)(d)))
d83dd29a
TG
397#define UDIV_TIME 90
398#define sdiv_qrnnd(q, r, n1, n0, d) \
399 __asm__ ("divs%.l %4,%1:%0" \
e6c5404d
TG
400 : "=d" ((USItype)(q)), \
401 "=d" ((USItype)(r)) \
402 : "0" ((USItype)(n0)), \
403 "1" ((USItype)(n1)), \
404 "dmi" ((USItype)(d)))
e1a79915
RS
405#define count_leading_zeros(count, x) \
406 __asm__ ("bfffo %1{%b2:%b2},%0" \
e6c5404d
TG
407 : "=d" ((USItype)(count)) \
408 : "od" ((USItype)(x)), "n" (0))
e1a79915
RS
409#else /* not mc68020 */
410#define umul_ppmm(xh, xl, a, b) \
411 __asm__ ("| Inlined umul_ppmm
412 movel %2,d0
413 movel %3,d1
414 movel d0,d2
415 swap d0
416 movel d1,d3
417 swap d1
418 movew d2,d4
419 mulu d3,d4
420 mulu d1,d2
421 mulu d0,d3
422 mulu d0,d1
423 movel d4,d0
424 eorw d0,d0
425 swap d0
426 addl d0,d2
427 addl d3,d2
428 jcc 1f
429 addl #65536,d1
4301: swap d2
431 moveq #0,d0
432 movew d2,d0
433 movew d4,d2
434 movel d2,%1
435 addl d1,d0
436 movel d0,%0" \
e6c5404d
TG
437 : "=g" ((USItype)(xh)), \
438 "=g" ((USItype)(xl)) \
439 : "g" ((USItype)(a)), \
440 "g" ((USItype)(b)) \
d83dd29a
TG
441 : "d0", "d1", "d2", "d3", "d4")
442#define UMUL_TIME 100
443#define UDIV_TIME 400
e1a79915
RS
444#endif /* not mc68020 */
445#endif /* mc68000 */
446
447#if defined (__m88000__)
448#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
449 __asm__ ("addu.co %1,%r4,%r5
450 addu.ci %0,%r2,%r3" \
e6c5404d
TG
451 : "=r" ((USItype)(sh)), \
452 "=&r" ((USItype)(sl)) \
453 : "%rJ" ((USItype)(ah)), \
454 "rJ" ((USItype)(bh)), \
455 "%rJ" ((USItype)(al)), \
456 "rJ" ((USItype)(bl)))
e1a79915
RS
457#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
458 __asm__ ("subu.co %1,%r4,%r5
459 subu.ci %0,%r2,%r3" \
e6c5404d
TG
460 : "=r" ((USItype)(sh)), \
461 "=&r" ((USItype)(sl)) \
462 : "rJ" ((USItype)(ah)), \
463 "rJ" ((USItype)(bh)), \
464 "rJ" ((USItype)(al)), \
465 "rJ" ((USItype)(bl)))
e1a79915
RS
466#define UMUL_TIME 17
467#define UDIV_TIME 150
468#define count_leading_zeros(count, x) \
469 do { \
e6c5404d 470 USItype __cbtmp; \
e1a79915 471 __asm__ ("ff1 %0,%1" \
d83dd29a 472 : "=r" (__cbtmp) \
e6c5404d 473 : "r" ((USItype)(x))); \
e1a79915
RS
474 (count) = __cbtmp ^ 31; \
475 } while (0)
d83dd29a
TG
476#if defined (__mc88110__)
477#define umul_ppmm(w1, w0, u, v) \
478 __asm__ ("mulu.d r10,%2,%3
479 or %0,r10,0
480 or %1,r11,0" \
481 : "=r" (w1), \
482 "=r" (w0) \
e6c5404d
TG
483 : "r" ((USItype)(u)), \
484 "r" ((USItype)(v)) \
d83dd29a
TG
485 : "r10", "r11")
486#define udiv_qrnnd(q, r, n1, n0, d) \
487 __asm__ ("or r10,%2,0
488 or r11,%3,0
489 divu.d r10,r10,%4
490 mulu %1,%4,r11
491 subu %1,%3,%1
492 or %0,r11,0" \
493 : "=r" (q), \
494 "=&r" (r) \
e6c5404d
TG
495 : "r" ((USItype)(n1)), \
496 "r" ((USItype)(n0)), \
497 "r" ((USItype)(d)) \
d83dd29a
TG
498 : "r10", "r11")
499#endif
e1a79915
RS
500#endif /* __m88000__ */
501
502#if defined (__mips__)
d28e1517
TG
503#define umul_ppmm(w1, w0, u, v) \
504 __asm__ ("multu %2,%3
505 mflo %0
e1a79915 506 mfhi %1" \
e6c5404d
TG
507 : "=d" ((USItype)(w0)), \
508 "=d" ((USItype)(w1)) \
509 : "d" ((USItype)(u)), \
510 "d" ((USItype)(v)))
e1a79915
RS
511#define UMUL_TIME 5
512#define UDIV_TIME 100
513#endif /* __mips__ */
514
515#if defined (__ns32000__)
516#define __umulsidi3(u, v) \
e6c5404d 517 ({UDItype __w; \
d83dd29a
TG
518 __asm__ ("meid %2,%0" \
519 : "=g" (__w) \
e6c5404d
TG
520 : "%0" ((USItype)(u)), \
521 "g" ((USItype)(v))); \
d83dd29a 522 __w; })
e1a79915
RS
523#define div_qrnnd(q, r, n1, n0, d) \
524 __asm__ ("movd %2,r0
525 movd %3,r1
526 deid %4,r0
527 movd r1,%0
528 movd r0,%1" \
e6c5404d
TG
529 : "=g" ((USItype)(q)), \
530 "=g" ((USItype)(r)) \
531 : "g" ((USItype)(n0)), \
532 "g" ((USItype)(n1)), \
533 "g" ((USItype)(d)) \
d83dd29a 534 : "r0", "r1")
e1a79915
RS
535#endif /* __ns32000__ */
536
537#if defined (__pyr__)
538#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
539 __asm__ ("addw %5,%1
540 addwc %3,%0" \
e6c5404d
TG
541 : "=r" ((USItype)(sh)), \
542 "=&r" ((USItype)(sl)) \
543 : "%0" ((USItype)(ah)), \
544 "g" ((USItype)(bh)), \
545 "%1" ((USItype)(al)), \
546 "g" ((USItype)(bl)))
e1a79915
RS
547#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
548 __asm__ ("subw %5,%1
549 subwb %3,%0" \
e6c5404d
TG
550 : "=r" ((USItype)(sh)), \
551 "=&r" ((USItype)(sl)) \
552 : "0" ((USItype)(ah)), \
553 "g" ((USItype)(bh)), \
554 "1" ((USItype)(al)), \
555 "g" ((USItype)(bl)))
e1a79915
RS
556/* This insn doesn't work on ancient pyramids. */
557#define umul_ppmm(w1, w0, u, v) \
e6c5404d
TG
558 ({union { \
559 UDItype __ll; \
560 struct {USItype __h, __l;} __i; \
561 } __xx; \
562 __xx.__i.__l = u; \
d83dd29a 563 __asm__ ("uemul %3,%0" \
e6c5404d
TG
564 : "=r" (__xx.__i.__h), \
565 "=r" (__xx.__i.__l) \
566 : "1" (__xx.__i.__l), \
567 "g" ((UDItype)(v))); \
568 (w1) = __xx.__i.__h; \
569 (w0) = __xx.__i.__l;})
e1a79915
RS
570#endif /* __pyr__ */
571
572#if defined (__ibm032__) /* RT/ROMP */
573#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
574 __asm__ ("a %1,%5
575 ae %0,%3" \
e6c5404d
TG
576 : "=r" ((USItype)(sh)), \
577 "=&r" ((USItype)(sl)) \
578 : "%0" ((USItype)(ah)), \
579 "r" ((USItype)(bh)), \
580 "%1" ((USItype)(al)), \
581 "r" ((USItype)(bl)))
e1a79915
RS
582#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
583 __asm__ ("s %1,%5
584 se %0,%3" \
e6c5404d
TG
585 : "=r" ((USItype)(sh)), \
586 "=&r" ((USItype)(sl)) \
587 : "0" ((USItype)(ah)), \
588 "r" ((USItype)(bh)), \
589 "1" ((USItype)(al)), \
590 "r" ((USItype)(bl)))
e1a79915
RS
591#define umul_ppmm(ph, pl, m0, m1) \
592 do { \
e6c5404d 593 USItype __m0 = (m0), __m1 = (m1); \
e1a79915
RS
594 __asm__ ( \
595 "s r2,r2
596 mts r10,%2
597 m r2,%3
598 m r2,%3
599 m r2,%3
600 m r2,%3
601 m r2,%3
602 m r2,%3
603 m r2,%3
604 m r2,%3
605 m r2,%3
606 m r2,%3
607 m r2,%3
608 m r2,%3
609 m r2,%3
610 m r2,%3
611 m r2,%3
612 m r2,%3
613 cas %0,r2,r0
614 mfs r10,%1" \
e6c5404d
TG
615 : "=r" ((USItype)(ph)), \
616 "=r" ((USItype)(pl)) \
d83dd29a
TG
617 : "%r" (__m0), \
618 "r" (__m1) \
619 : "r2"); \
e6c5404d
TG
620 (ph) += ((((SItype) __m0 >> 31) & __m1) \
621 + (((SItype) __m1 >> 31) & __m0)); \
e1a79915 622 } while (0)
d83dd29a
TG
623#define UMUL_TIME 20
624#define UDIV_TIME 200
e1a79915
RS
625#define count_leading_zeros(count, x) \
626 do { \
627 if ((x) >= 0x10000) \
628 __asm__ ("clz %0,%1" \
e6c5404d
TG
629 : "=r" ((USItype)(count)) \
630 : "r" ((USItype)(x) >> 16)); \
e1a79915
RS
631 else \
632 { \
633 __asm__ ("clz %0,%1" \
e6c5404d
TG
634 : "=r" ((USItype)(count)) \
635 : "r" ((USItype)(x))); \
e1a79915
RS
636 (count) += 16; \
637 } \
638 } while (0)
639#endif
640
641#if defined (__sparc__)
642#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
643 __asm__ ("addcc %4,%5,%1
644 addx %2,%3,%0" \
e6c5404d
TG
645 : "=r" ((USItype)(sh)), \
646 "=&r" ((USItype)(sl)) \
647 : "%r" ((USItype)(ah)), \
648 "rI" ((USItype)(bh)), \
649 "%r" ((USItype)(al)), \
650 "rI" ((USItype)(bl)) \
d83dd29a 651 __CLOBBER_CC)
e1a79915
RS
652#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
653 __asm__ ("subcc %4,%5,%1
654 subx %2,%3,%0" \
e6c5404d
TG
655 : "=r" ((USItype)(sh)), \
656 "=&r" ((USItype)(sl)) \
657 : "r" ((USItype)(ah)), \
658 "rI" ((USItype)(bh)), \
659 "r" ((USItype)(al)), \
660 "rI" ((USItype)(bl)) \
d83dd29a 661 __CLOBBER_CC)
454f2ef2 662#if defined (__sparcv8__)
e1a79915
RS
663#define umul_ppmm(w1, w0, u, v) \
664 __asm__ ("umul %2,%3,%1;rd %%y,%0" \
e6c5404d
TG
665 : "=r" ((USItype)(w1)), \
666 "=r" ((USItype)(w0)) \
667 : "r" ((USItype)(u)), \
668 "r" ((USItype)(v)))
e1a79915
RS
669#define udiv_qrnnd(q, r, n1, n0, d) \
670 __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
e6c5404d
TG
671 : "=&r" ((USItype)(q)), \
672 "=&r" ((USItype)(r)) \
673 : "r" ((USItype)(n1)), \
674 "r" ((USItype)(n0)), \
675 "r" ((USItype)(d)))
e1a79915
RS
676#else
677/* SPARC without integer multiplication and divide instructions.
678 (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
679#define umul_ppmm(w1, w0, u, v) \
680 __asm__ ("! Inlined umul_ppmm
681 wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr
682 sra %3,31,%%g2 ! Don't move this insn
683 and %2,%%g2,%%g2 ! Don't move this insn
684 andcc %%g0,0,%%g1 ! Don't move this insn
685 mulscc %%g1,%3,%%g1
686 mulscc %%g1,%3,%%g1
687 mulscc %%g1,%3,%%g1
688 mulscc %%g1,%3,%%g1
689 mulscc %%g1,%3,%%g1
690 mulscc %%g1,%3,%%g1
691 mulscc %%g1,%3,%%g1
692 mulscc %%g1,%3,%%g1
693 mulscc %%g1,%3,%%g1
694 mulscc %%g1,%3,%%g1
695 mulscc %%g1,%3,%%g1
696 mulscc %%g1,%3,%%g1
697 mulscc %%g1,%3,%%g1
698 mulscc %%g1,%3,%%g1
699 mulscc %%g1,%3,%%g1
700 mulscc %%g1,%3,%%g1
701 mulscc %%g1,%3,%%g1
702 mulscc %%g1,%3,%%g1
703 mulscc %%g1,%3,%%g1
704 mulscc %%g1,%3,%%g1
705 mulscc %%g1,%3,%%g1
706 mulscc %%g1,%3,%%g1
707 mulscc %%g1,%3,%%g1
708 mulscc %%g1,%3,%%g1
709 mulscc %%g1,%3,%%g1
710 mulscc %%g1,%3,%%g1
711 mulscc %%g1,%3,%%g1
712 mulscc %%g1,%3,%%g1
713 mulscc %%g1,%3,%%g1
714 mulscc %%g1,%3,%%g1
715 mulscc %%g1,%3,%%g1
716 mulscc %%g1,%3,%%g1
717 mulscc %%g1,0,%%g1
718 add %%g1,%%g2,%0
719 rd %%y,%1" \
e6c5404d
TG
720 : "=r" ((USItype)(w1)), \
721 "=r" ((USItype)(w0)) \
722 : "%rI" ((USItype)(u)), \
723 "r" ((USItype)(v)) \
d83dd29a 724 : "%g1", "%g2" __AND_CLOBBER_CC)
e1a79915
RS
725#define UMUL_TIME 39 /* 39 instructions */
726/* It's quite necessary to add this much assembler for the sparc.
727 The default udiv_qrnnd (in C) is more than 10 times slower! */
728#define udiv_qrnnd(q, r, n1, n0, d) \
729 __asm__ ("! Inlined udiv_qrnnd
730 mov 32,%%g1
731 subcc %1,%2,%%g0
7321: bcs 5f
733 addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
734 sub %1,%2,%1 ! this kills msb of n
735 addx %1,%1,%1 ! so this can't give carry
736 subcc %%g1,1,%%g1
7372: bne 1b
738 subcc %1,%2,%%g0
739 bcs 3f
740 addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
741 b 3f
742 sub %1,%2,%1 ! this kills msb of n
7434: sub %1,%2,%1
7445: addxcc %1,%1,%1
745 bcc 2b
746 subcc %%g1,1,%%g1
747! Got carry from n. Subtract next step to cancel this carry.
748 bne 4b
749 addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb
750 sub %1,%2,%1
7513: xnor %0,0,%0
752 ! End of inline udiv_qrnnd" \
e6c5404d
TG
753 : "=&r" ((USItype)(q)), \
754 "=&r" ((USItype)(r)) \
755 : "r" ((USItype)(d)), \
756 "1" ((USItype)(n1)), \
757 "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC)
e1a79915 758#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */
e1a79915 759#endif /* __sparc8__ */
d83dd29a 760#endif /* __sparc__ */
e1a79915
RS
761
762#if defined (__vax__)
763#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
764 __asm__ ("addl2 %5,%1
765 adwc %3,%0" \
e6c5404d
TG
766 : "=g" ((USItype)(sh)), \
767 "=&g" ((USItype)(sl)) \
768 : "%0" ((USItype)(ah)), \
769 "g" ((USItype)(bh)), \
770 "%1" ((USItype)(al)), \
771 "g" ((USItype)(bl)))
e1a79915
RS
772#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
773 __asm__ ("subl2 %5,%1
774 sbwc %3,%0" \
e6c5404d
TG
775 : "=g" ((USItype)(sh)), \
776 "=&g" ((USItype)(sl)) \
777 : "0" ((USItype)(ah)), \
778 "g" ((USItype)(bh)), \
779 "1" ((USItype)(al)), \
780 "g" ((USItype)(bl)))
e1a79915
RS
781#define umul_ppmm(xh, xl, m0, m1) \
782 do { \
e6c5404d
TG
783 union { \
784 UDItype __ll; \
785 struct {USItype __l, __h;} __i; \
786 } __xx; \
787 USItype __m0 = (m0), __m1 = (m1); \
e1a79915 788 __asm__ ("emul %1,%2,$0,%0" \
e6c5404d 789 : "=r" (__xx.__ll) \
d83dd29a
TG
790 : "g" (__m0), \
791 "g" (__m1)); \
e6c5404d
TG
792 (xh) = __xx.__i.__h; \
793 (xl) = __xx.__i.__l; \
794 (xh) += ((((SItype) __m0 >> 31) & __m1) \
795 + (((SItype) __m1 >> 31) & __m0)); \
e1a79915
RS
796 } while (0)
797#endif /* __vax__ */
798
799#endif /* __GNUC__ */
800
801/* If this machine has no inline assembler, use C macros. */
802
803#if !defined (add_ssaaaa)
804#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
805 do { \
e6c5404d 806 USItype __x; \
e1a79915
RS
807 __x = (al) + (bl); \
808 (sh) = (ah) + (bh) + (__x < (al)); \
809 (sl) = __x; \
810 } while (0)
811#endif
812
813#if !defined (sub_ddmmss)
814#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
815 do { \
e6c5404d 816 USItype __x; \
e1a79915
RS
817 __x = (al) - (bl); \
818 (sh) = (ah) - (bh) - (__x > (al)); \
819 (sl) = __x; \
820 } while (0)
821#endif
822
823#if !defined (umul_ppmm)
824#define umul_ppmm(w1, w0, u, v) \
825 do { \
e6c5404d
TG
826 USItype __x0, __x1, __x2, __x3; \
827 USItype __ul, __vl, __uh, __vh; \
e1a79915
RS
828 \
829 __ul = __ll_lowpart (u); \
830 __uh = __ll_highpart (u); \
831 __vl = __ll_lowpart (v); \
832 __vh = __ll_highpart (v); \
833 \
e6c5404d
TG
834 __x0 = (USItype) __ul * __vl; \
835 __x1 = (USItype) __ul * __vh; \
836 __x2 = (USItype) __uh * __vl; \
837 __x3 = (USItype) __uh * __vh; \
e1a79915
RS
838 \
839 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
840 __x1 += __x2; /* but this indeed can */ \
841 if (__x1 < __x2) /* did we get it? */ \
842 __x3 += __ll_B; /* yes, add it in the proper pos. */ \
843 \
844 (w1) = __x3 + __ll_highpart (__x1); \
845 (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
846 } while (0)
847#endif
848
849#if !defined (__umulsidi3)
850#define __umulsidi3(u, v) \
e6c5404d 851 ({DIunion __w; \
e1a79915
RS
852 umul_ppmm (__w.s.high, __w.s.low, u, v); \
853 __w.ll; })
854#endif
855
d83dd29a
TG
856/* Define this unconditionally, so it can be used for debugging. */
857#define __udiv_qrnnd_c(q, r, n1, n0, d) \
e1a79915 858 do { \
e6c5404d
TG
859 USItype __d1, __d0, __q1, __q0; \
860 USItype __r1, __r0, __m; \
e1a79915
RS
861 __d1 = __ll_highpart (d); \
862 __d0 = __ll_lowpart (d); \
863 \
864 __r1 = (n1) % __d1; \
865 __q1 = (n1) / __d1; \
e6c5404d 866 __m = (USItype) __q1 * __d0; \
e1a79915
RS
867 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
868 if (__r1 < __m) \
869 { \
870 __q1--, __r1 += (d); \
871 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
872 if (__r1 < __m) \
873 __q1--, __r1 += (d); \
874 } \
875 __r1 -= __m; \
876 \
877 __r0 = __r1 % __d1; \
878 __q0 = __r1 / __d1; \
e6c5404d 879 __m = (USItype) __q0 * __d0; \
e1a79915
RS
880 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
881 if (__r0 < __m) \
882 { \
883 __q0--, __r0 += (d); \
884 if (__r0 >= (d)) \
885 if (__r0 < __m) \
886 __q0--, __r0 += (d); \
887 } \
888 __r0 -= __m; \
889 \
e6c5404d 890 (q) = (USItype) __q1 * __ll_B | __q0; \
e1a79915
RS
891 (r) = __r0; \
892 } while (0)
d83dd29a
TG
893/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
894#if !defined (udiv_qrnnd)
895#define UDIV_NEEDS_NORMALIZATION 1
896#define udiv_qrnnd __udiv_qrnnd_c
e1a79915
RS
897#endif
898
899#if !defined (count_leading_zeros)
e6c5404d 900extern const UQItype __clz_tab[];
e1a79915
RS
901#define count_leading_zeros(count, x) \
902 do { \
e6c5404d
TG
903 USItype __xr = (x); \
904 USItype __a; \
e1a79915 905 \
d83dd29a
TG
906 if (LONG_TYPE_SIZE <= 32) \
907 { \
908 __a = __xr < (1<<2*__BITS4) \
909 ? (__xr < (1<<__BITS4) ? 0 : __BITS4) \
910 : (__xr < (1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
911 } \
912 else \
913 { \
914 for (__a = LONG_TYPE_SIZE - 8; __a > 0; __a -= 8) \
915 if (((__xr >> __a) & 0xff) != 0) \
916 break; \
917 } \
e1a79915 918 \
d83dd29a 919 (count) = LONG_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
e1a79915
RS
920 } while (0)
921#endif
922
923#ifndef UDIV_NEEDS_NORMALIZATION
924#define UDIV_NEEDS_NORMALIZATION 0
925#endif
This page took 0.174519 seconds and 5 git commands to generate.