]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdlib/longlong.h
Update.
[thirdparty/glibc.git] / stdlib / longlong.h
CommitLineData
28f540f4 1/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
62818cfd 2 Copyright (C) 1991,92,94,95,96,97,98,99 Free Software Foundation, Inc.
28f540f4 3
1da2d51a
UD
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.
28f540f4 8
1da2d51a
UD
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.
28f540f4 13
1da2d51a
UD
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., 59 Temple Place - Suite 330,
478b92f0 17 Boston, MA 02111-1307, USA. */
28f540f4 18
1da2d51a
UD
19#ifndef SI_TYPE_SIZE
20#define SI_TYPE_SIZE 32
b928942e
RM
21#endif
22
1da2d51a
UD
23#define __BITS4 (SI_TYPE_SIZE / 4)
24#define __ll_B (1L << (SI_TYPE_SIZE / 2))
25#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
26#define __ll_highpart(t) ((USItype) (t) / __ll_B)
04fbd653 27
28f540f4
RM
28/* Define auxiliary asm macros.
29
1da2d51a
UD
30 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
31 multiplies two USItype integers MULTIPLER and MULTIPLICAND,
32 and generates a two-part USItype product in HIGH_PROD and
33 LOW_PROD.
28f540f4 34
1da2d51a
UD
35 2) __umulsidi3(a,b) multiplies two USItype integers A and B,
36 and returns a UDItype product. This is just a variant of umul_ppmm.
28f540f4
RM
37
38 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
1da2d51a
UD
39 denominator) divides a two-word unsigned integer, composed by the
40 integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
41 places the quotient in QUOTIENT and the remainder in REMAINDER.
42 HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
43 If, in addition, the most significant bit of DENOMINATOR must be 1,
44 then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
28f540f4
RM
45
46 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
1da2d51a
UD
47 denominator). Like udiv_qrnnd but the numbers are signed. The
48 quotient is rounded towards 0.
49
50 5) count_leading_zeros(count, x) counts the number of zero-bits from
51 the msb to the first non-zero bit. This is the number of steps X
52 needs to be shifted left to set the msb. Undefined for X == 0.
53
62818cfd
UD
54 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
55 from the least significant end.
56
57 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
1da2d51a
UD
58 high_addend_2, low_addend_2) adds two two-word unsigned integers,
59 composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
60 LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
61 LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
62 lost.
63
62818cfd 64 8) sub_ddmmss(high_difference, low_difference, high_minuend,
1da2d51a
UD
65 low_minuend, high_subtrahend, low_subtrahend) subtracts two
66 two-word unsigned integers, composed by HIGH_MINUEND_1 and
67 LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
68 respectively. The result is placed in HIGH_DIFFERENCE and
69 LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
28f540f4
RM
70 and is lost.
71
72 If any of these macros are left undefined for a particular CPU,
73 C macros are used. */
74
75/* The CPUs come in alphabetical order below.
76
77 Please add support for more CPUs here, or improve the current support
1da2d51a
UD
78 for the CPUs below!
79 (E.g. WE32100, IBM360.) */
28f540f4
RM
80
81#if defined (__GNUC__) && !defined (NO_ASM)
82
83/* We sometimes need to clobber "cc" with gcc2, but that would not be
84 understood by gcc1. Use cpp to avoid major code duplication. */
85#if __GNUC__ < 2
86#define __CLOBBER_CC
87#define __AND_CLOBBER_CC
88#else /* __GNUC__ >= 2 */
89#define __CLOBBER_CC : "cc"
90#define __AND_CLOBBER_CC , "cc"
91#endif /* __GNUC__ < 2 */
92
1da2d51a 93#if defined (__a29k__) || defined (_AM29K)
28f540f4
RM
94#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
95 __asm__ ("add %1,%4,%5
96 addc %0,%2,%3" \
1da2d51a
UD
97 : "=r" ((USItype) (sh)), \
98 "=&r" ((USItype) (sl)) \
99 : "%r" ((USItype) (ah)), \
100 "rI" ((USItype) (bh)), \
101 "%r" ((USItype) (al)), \
102 "rI" ((USItype) (bl)))
28f540f4
RM
103#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
104 __asm__ ("sub %1,%4,%5
105 subc %0,%2,%3" \
1da2d51a
UD
106 : "=r" ((USItype) (sh)), \
107 "=&r" ((USItype) (sl)) \
108 : "r" ((USItype) (ah)), \
109 "rI" ((USItype) (bh)), \
110 "r" ((USItype) (al)), \
111 "rI" ((USItype) (bl)))
28f540f4
RM
112#define umul_ppmm(xh, xl, m0, m1) \
113 do { \
114 USItype __m0 = (m0), __m1 = (m1); \
115 __asm__ ("multiplu %0,%1,%2" \
1da2d51a 116 : "=r" ((USItype) (xl)) \
28f540f4
RM
117 : "r" (__m0), \
118 "r" (__m1)); \
119 __asm__ ("multmu %0,%1,%2" \
1da2d51a 120 : "=r" ((USItype) (xh)) \
28f540f4
RM
121 : "r" (__m0), \
122 "r" (__m1)); \
123 } while (0)
124#define udiv_qrnnd(q, r, n1, n0, d) \
125 __asm__ ("dividu %0,%3,%4" \
1da2d51a
UD
126 : "=r" ((USItype) (q)), \
127 "=q" ((USItype) (r)) \
128 : "1" ((USItype) (n1)), \
129 "r" ((USItype) (n0)), \
130 "r" ((USItype) (d)))
28f540f4
RM
131#define count_leading_zeros(count, x) \
132 __asm__ ("clz %0,%1" \
1da2d51a
UD
133 : "=r" ((USItype) (count)) \
134 : "r" ((USItype) (x)))
28f540f4
RM
135#endif /* __a29k__ */
136
1da2d51a
UD
137#if defined (__arc__)
138#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
139 __asm__ ("add.f %1, %4, %5
140 adc %0, %2, %3" \
141 : "=r" ((USItype) (sh)), \
142 "=&r" ((USItype) (sl)) \
143 : "%r" ((USItype) (ah)), \
144 "rIJ" ((USItype) (bh)), \
145 "%r" ((USItype) (al)), \
146 "rIJ" ((USItype) (bl)))
147#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
148 __asm__ ("sub.f %1, %4, %5
149 sbc %0, %2, %3" \
150 : "=r" ((USItype) (sh)), \
151 "=&r" ((USItype) (sl)) \
152 : "r" ((USItype) (ah)), \
153 "rIJ" ((USItype) (bh)), \
154 "r" ((USItype) (al)), \
155 "rIJ" ((USItype) (bl)))
156/* Call libgcc1 routine. */
157#define umul_ppmm(w1, w0, u, v) \
158do { \
159 DIunion __w; \
160 __w.ll = __umulsidi3 (u, v); \
161 w1 = __w.s.high; \
162 w0 = __w.s.low; \
163} while (0)
164#define __umulsidi3 __umulsidi3
165UDItype __umulsidi3 (USItype, USItype);
166#endif
28f540f4 167
1da2d51a 168#if defined (__arm__)
28f540f4 169#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
8f5ca04b
RM
170 __asm__ ("adds %1, %4, %5
171 adc %0, %2, %3" \
1da2d51a
UD
172 : "=r" ((USItype) (sh)), \
173 "=&r" ((USItype) (sl)) \
174 : "%r" ((USItype) (ah)), \
175 "rI" ((USItype) (bh)), \
176 "%r" ((USItype) (al)), \
177 "rI" ((USItype) (bl)))
28f540f4 178#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
8f5ca04b
RM
179 __asm__ ("subs %1, %4, %5
180 sbc %0, %2, %3" \
1da2d51a
UD
181 : "=r" ((USItype) (sh)), \
182 "=&r" ((USItype) (sl)) \
183 : "r" ((USItype) (ah)), \
184 "rI" ((USItype) (bh)), \
185 "r" ((USItype) (al)), \
186 "rI" ((USItype) (bl)))
28f540f4 187#define umul_ppmm(xh, xl, a, b) \
1da2d51a 188{register USItype __t0, __t1, __t2; \
8f5ca04b 189 __asm__ ("%@ Inlined umul_ppmm
1da2d51a
UD
190 mov %2, %5, lsr #16
191 mov %0, %6, lsr #16
192 bic %3, %5, %2, lsl #16
193 bic %4, %6, %0, lsl #16
194 mul %1, %3, %4
195 mul %4, %2, %4
196 mul %3, %0, %3
197 mul %0, %2, %0
198 adds %3, %4, %3
8f5ca04b 199 addcs %0, %0, #65536
1da2d51a
UD
200 adds %1, %1, %3, lsl #16
201 adc %0, %0, %3, lsr #16" \
202 : "=&r" ((USItype) (xh)), \
203 "=r" ((USItype) (xl)), \
204 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
205 : "r" ((USItype) (a)), \
206 "r" ((USItype) (b)));}
28f540f4
RM
207#define UMUL_TIME 20
208#define UDIV_TIME 100
209#endif /* __arm__ */
210
1da2d51a 211#if defined (__clipper__)
28f540f4
RM
212#define umul_ppmm(w1, w0, u, v) \
213 ({union {UDItype __ll; \
214 struct {USItype __l, __h;} __i; \
215 } __xx; \
216 __asm__ ("mulwux %2,%0" \
217 : "=r" (__xx.__ll) \
1da2d51a
UD
218 : "%0" ((USItype) (u)), \
219 "r" ((USItype) (v))); \
28f540f4
RM
220 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
221#define smul_ppmm(w1, w0, u, v) \
222 ({union {DItype __ll; \
223 struct {SItype __l, __h;} __i; \
224 } __xx; \
225 __asm__ ("mulwx %2,%0" \
226 : "=r" (__xx.__ll) \
1da2d51a
UD
227 : "%0" ((SItype) (u)), \
228 "r" ((SItype) (v))); \
28f540f4
RM
229 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
230#define __umulsidi3(u, v) \
231 ({UDItype __w; \
232 __asm__ ("mulwux %2,%0" \
233 : "=r" (__w) \
1da2d51a
UD
234 : "%0" ((USItype) (u)), \
235 "r" ((USItype) (v))); \
28f540f4
RM
236 __w; })
237#endif /* __clipper__ */
238
1da2d51a 239#if defined (__gmicro__)
28f540f4
RM
240#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
241 __asm__ ("add.w %5,%1
242 addx %3,%0" \
1da2d51a
UD
243 : "=g" ((USItype) (sh)), \
244 "=&g" ((USItype) (sl)) \
245 : "%0" ((USItype) (ah)), \
246 "g" ((USItype) (bh)), \
247 "%1" ((USItype) (al)), \
248 "g" ((USItype) (bl)))
28f540f4
RM
249#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
250 __asm__ ("sub.w %5,%1
251 subx %3,%0" \
1da2d51a
UD
252 : "=g" ((USItype) (sh)), \
253 "=&g" ((USItype) (sl)) \
254 : "0" ((USItype) (ah)), \
255 "g" ((USItype) (bh)), \
256 "1" ((USItype) (al)), \
257 "g" ((USItype) (bl)))
28f540f4
RM
258#define umul_ppmm(ph, pl, m0, m1) \
259 __asm__ ("mulx %3,%0,%1" \
1da2d51a
UD
260 : "=g" ((USItype) (ph)), \
261 "=r" ((USItype) (pl)) \
262 : "%0" ((USItype) (m0)), \
263 "g" ((USItype) (m1)))
28f540f4
RM
264#define udiv_qrnnd(q, r, nh, nl, d) \
265 __asm__ ("divx %4,%0,%1" \
1da2d51a
UD
266 : "=g" ((USItype) (q)), \
267 "=r" ((USItype) (r)) \
268 : "1" ((USItype) (nh)), \
269 "0" ((USItype) (nl)), \
270 "g" ((USItype) (d)))
28f540f4
RM
271#define count_leading_zeros(count, x) \
272 __asm__ ("bsch/1 %1,%0" \
273 : "=g" (count) \
1da2d51a
UD
274 : "g" ((USItype) (x)), \
275 "0" ((USItype) 0))
28f540f4
RM
276#endif
277
1da2d51a 278#if defined (__hppa)
28f540f4
RM
279#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
280 __asm__ ("add %4,%5,%1
281 addc %2,%3,%0" \
1da2d51a
UD
282 : "=r" ((USItype) (sh)), \
283 "=&r" ((USItype) (sl)) \
284 : "%rM" ((USItype) (ah)), \
285 "rM" ((USItype) (bh)), \
286 "%rM" ((USItype) (al)), \
287 "rM" ((USItype) (bl)))
28f540f4
RM
288#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
289 __asm__ ("sub %4,%5,%1
290 subb %2,%3,%0" \
1da2d51a
UD
291 : "=r" ((USItype) (sh)), \
292 "=&r" ((USItype) (sl)) \
293 : "rM" ((USItype) (ah)), \
294 "rM" ((USItype) (bh)), \
295 "rM" ((USItype) (al)), \
296 "rM" ((USItype) (bl)))
28f540f4 297#if defined (_PA_RISC1_1)
1da2d51a 298#define umul_ppmm(w1, w0, u, v) \
28f540f4 299 do { \
1da2d51a
UD
300 union \
301 { \
302 UDItype __f; \
303 struct {USItype __w1, __w0;} __w1w0; \
304 } __t; \
28f540f4 305 __asm__ ("xmpyu %1,%2,%0" \
1da2d51a
UD
306 : "=x" (__t.__f) \
307 : "x" ((USItype) (u)), \
308 "x" ((USItype) (v))); \
309 (w1) = __t.__w1w0.__w1; \
310 (w0) = __t.__w1w0.__w0; \
311 } while (0)
28f540f4 312#define UMUL_TIME 8
28f540f4 313#else
1da2d51a 314#define UMUL_TIME 30
28f540f4 315#endif
1da2d51a 316#define UDIV_TIME 40
28f540f4
RM
317#define count_leading_zeros(count, x) \
318 do { \
319 USItype __tmp; \
320 __asm__ ( \
321 "ldi 1,%0
322 extru,= %1,15,16,%%r0 ; Bits 31..16 zero?
323 extru,tr %1,15,16,%1 ; No. Shift down, skip add.
324 ldo 16(%0),%0 ; Yes. Perform add.
325 extru,= %1,23,8,%%r0 ; Bits 15..8 zero?
326 extru,tr %1,23,8,%1 ; No. Shift down, skip add.
327 ldo 8(%0),%0 ; Yes. Perform add.
328 extru,= %1,27,4,%%r0 ; Bits 7..4 zero?
329 extru,tr %1,27,4,%1 ; No. Shift down, skip add.
330 ldo 4(%0),%0 ; Yes. Perform add.
331 extru,= %1,29,2,%%r0 ; Bits 3..2 zero?
332 extru,tr %1,29,2,%1 ; No. Shift down, skip add.
333 ldo 2(%0),%0 ; Yes. Perform add.
334 extru %1,30,1,%1 ; Extract bit 1.
335 sub %0,%1,%0 ; Subtract it.
336 " : "=r" (count), "=r" (__tmp) : "1" (x)); \
337 } while (0)
28f540f4
RM
338#endif
339
1da2d51a 340#if defined (__i386__) || defined (__i486__)
28f540f4
RM
341#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
342 __asm__ ("addl %5,%1
343 adcl %3,%0" \
1da2d51a
UD
344 : "=r" ((USItype) (sh)), \
345 "=&r" ((USItype) (sl)) \
346 : "%0" ((USItype) (ah)), \
347 "g" ((USItype) (bh)), \
348 "%1" ((USItype) (al)), \
349 "g" ((USItype) (bl)))
28f540f4
RM
350#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
351 __asm__ ("subl %5,%1
352 sbbl %3,%0" \
1da2d51a
UD
353 : "=r" ((USItype) (sh)), \
354 "=&r" ((USItype) (sl)) \
355 : "0" ((USItype) (ah)), \
356 "g" ((USItype) (bh)), \
357 "1" ((USItype) (al)), \
358 "g" ((USItype) (bl)))
28f540f4
RM
359#define umul_ppmm(w1, w0, u, v) \
360 __asm__ ("mull %3" \
1da2d51a
UD
361 : "=a" ((USItype) (w0)), \
362 "=d" ((USItype) (w1)) \
363 : "%0" ((USItype) (u)), \
364 "rm" ((USItype) (v)))
28f540f4
RM
365#define udiv_qrnnd(q, r, n1, n0, d) \
366 __asm__ ("divl %4" \
1da2d51a
UD
367 : "=a" ((USItype) (q)), \
368 "=d" ((USItype) (r)) \
369 : "0" ((USItype) (n0)), \
370 "1" ((USItype) (n1)), \
371 "rm" ((USItype) (d)))
28f540f4
RM
372#define count_leading_zeros(count, x) \
373 do { \
374 USItype __cbtmp; \
375 __asm__ ("bsrl %1,%0" \
1da2d51a 376 : "=r" (__cbtmp) : "rm" ((USItype) (x))); \
28f540f4
RM
377 (count) = __cbtmp ^ 31; \
378 } while (0)
62818cfd
UD
379#define count_trailing_zeros(count, x) \
380 __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
28f540f4
RM
381#define UMUL_TIME 40
382#define UDIV_TIME 40
383#endif /* 80x86 */
384
1da2d51a
UD
385#if defined (__i860__)
386#if 0
387/* Make sure these patterns really improve the code before
388 switching them on. */
ba848785 389#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1da2d51a
UD
390 do { \
391 union \
392 { \
393 DItype __ll; \
394 struct {USItype __l, __h;} __i; \
395 } __a, __b, __s; \
396 __a.__i.__l = (al); \
397 __a.__i.__h = (ah); \
398 __b.__i.__l = (bl); \
399 __b.__i.__h = (bh); \
400 __asm__ ("fiadd.dd %1,%2,%0" \
401 : "=f" (__s.__ll) \
402 : "%f" (__a.__ll), "f" (__b.__ll)); \
403 (sh) = __s.__i.__h; \
404 (sl) = __s.__i.__l; \
405 } while (0)
ba848785 406#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1da2d51a
UD
407 do { \
408 union \
409 { \
410 DItype __ll; \
411 struct {USItype __l, __h;} __i; \
412 } __a, __b, __s; \
413 __a.__i.__l = (al); \
414 __a.__i.__h = (ah); \
415 __b.__i.__l = (bl); \
416 __b.__i.__h = (bh); \
417 __asm__ ("fisub.dd %1,%2,%0" \
418 : "=f" (__s.__ll) \
419 : "%f" (__a.__ll), "f" (__b.__ll)); \
420 (sh) = __s.__i.__h; \
421 (sl) = __s.__i.__l; \
422 } while (0)
423#endif
424#endif /* __i860__ */
425
426#if defined (__i960__)
28f540f4
RM
427#define umul_ppmm(w1, w0, u, v) \
428 ({union {UDItype __ll; \
429 struct {USItype __l, __h;} __i; \
430 } __xx; \
431 __asm__ ("emul %2,%1,%0" \
432 : "=d" (__xx.__ll) \
1da2d51a
UD
433 : "%dI" ((USItype) (u)), \
434 "dI" ((USItype) (v))); \
28f540f4
RM
435 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
436#define __umulsidi3(u, v) \
437 ({UDItype __w; \
438 __asm__ ("emul %2,%1,%0" \
439 : "=d" (__w) \
1da2d51a
UD
440 : "%dI" ((USItype) (u)), \
441 "dI" ((USItype) (v))); \
62818cfd 442 __w; })
1da2d51a 443#endif /* __i960__ */
28f540f4 444
1da2d51a
UD
445#if defined (__M32R__)
446#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
447 /* The cmp clears the condition bit. */ \
448 __asm__ ("cmp %0,%0
449 addx %%5,%1
450 addx %%3,%0" \
451 : "=r" ((USItype) (sh)), \
452 "=&r" ((USItype) (sl)) \
453 : "%0" ((USItype) (ah)), \
454 "r" ((USItype) (bh)), \
455 "%1" ((USItype) (al)), \
456 "r" ((USItype) (bl)) \
457 : "cbit")
458#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
459 /* The cmp clears the condition bit. */ \
460 __asm__ ("cmp %0,%0
461 subx %5,%1
462 subx %3,%0" \
463 : "=r" ((USItype) (sh)), \
464 "=&r" ((USItype) (sl)) \
465 : "0" ((USItype) (ah)), \
466 "r" ((USItype) (bh)), \
467 "1" ((USItype) (al)), \
468 "r" ((USItype) (bl)) \
469 : "cbit")
470#endif /* __M32R__ */
471
472#if defined (__mc68000__)
28f540f4
RM
473#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
474 __asm__ ("add%.l %5,%1
475 addx%.l %3,%0" \
1da2d51a
UD
476 : "=d" ((USItype) (sh)), \
477 "=&d" ((USItype) (sl)) \
478 : "%0" ((USItype) (ah)), \
479 "d" ((USItype) (bh)), \
480 "%1" ((USItype) (al)), \
481 "g" ((USItype) (bl)))
28f540f4
RM
482#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
483 __asm__ ("sub%.l %5,%1
484 subx%.l %3,%0" \
1da2d51a
UD
485 : "=d" ((USItype) (sh)), \
486 "=&d" ((USItype) (sl)) \
487 : "0" ((USItype) (ah)), \
488 "d" ((USItype) (bh)), \
489 "1" ((USItype) (al)), \
490 "g" ((USItype) (bl)))
491
492/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */
493#if defined (__mc68020__) || defined(mc68020) \
494 || defined(__mc68030__) || defined(mc68030) \
495 || defined(__mc68040__) || defined(mc68040) \
496 || defined(__mcpu32__) || defined(mcpu32) \
497 || defined(__NeXT__)
28f540f4
RM
498#define umul_ppmm(w1, w0, u, v) \
499 __asm__ ("mulu%.l %3,%1:%0" \
1da2d51a
UD
500 : "=d" ((USItype) (w0)), \
501 "=d" ((USItype) (w1)) \
502 : "%0" ((USItype) (u)), \
503 "dmi" ((USItype) (v)))
28f540f4
RM
504#define UMUL_TIME 45
505#define udiv_qrnnd(q, r, n1, n0, d) \
506 __asm__ ("divu%.l %4,%1:%0" \
1da2d51a
UD
507 : "=d" ((USItype) (q)), \
508 "=d" ((USItype) (r)) \
509 : "0" ((USItype) (n0)), \
510 "1" ((USItype) (n1)), \
511 "dmi" ((USItype) (d)))
28f540f4
RM
512#define UDIV_TIME 90
513#define sdiv_qrnnd(q, r, n1, n0, d) \
514 __asm__ ("divs%.l %4,%1:%0" \
1da2d51a
UD
515 : "=d" ((USItype) (q)), \
516 "=d" ((USItype) (r)) \
517 : "0" ((USItype) (n0)), \
518 "1" ((USItype) (n1)), \
519 "dmi" ((USItype) (d)))
520
28f540f4 521#else /* not mc68020 */
1da2d51a
UD
522#if !defined(__mcf5200__)
523/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */
ba848785 524#define umul_ppmm(xh, xl, a, b) \
1da2d51a
UD
525 __asm__ ("| Inlined umul_ppmm
526 move%.l %2,%/d0
527 move%.l %3,%/d1
528 move%.l %/d0,%/d2
529 swap %/d0
530 move%.l %/d1,%/d3
531 swap %/d1
532 move%.w %/d2,%/d4
533 mulu %/d3,%/d4
534 mulu %/d1,%/d2
535 mulu %/d0,%/d3
536 mulu %/d0,%/d1
537 move%.l %/d4,%/d0
538 eor%.w %/d0,%/d0
539 swap %/d0
540 add%.l %/d0,%/d2
541 add%.l %/d3,%/d2
28f540f4 542 jcc 1f
1da2d51a
UD
543 add%.l %#65536,%/d1
5441: swap %/d2
545 moveq %#0,%/d0
546 move%.w %/d2,%/d0
547 move%.w %/d4,%/d2
548 move%.l %/d2,%1
549 add%.l %/d1,%/d0
550 move%.l %/d0,%0" \
551 : "=g" ((USItype) (xh)), \
552 "=g" ((USItype) (xl)) \
553 : "g" ((USItype) (a)), \
554 "g" ((USItype) (b)) \
555 : "d0", "d1", "d2", "d3", "d4")
28f540f4
RM
556#define UMUL_TIME 100
557#define UDIV_TIME 400
1da2d51a 558#endif /* not mcf5200 */
28f540f4 559#endif /* not mc68020 */
1da2d51a
UD
560
561/* The '020, '030, '040 and '060 have bitfield insns. */
562#if defined (__mc68020__) || defined(mc68020) \
563 || defined(__mc68030__) || defined(mc68030) \
564 || defined(__mc68040__) || defined(mc68040) \
565 || defined(__mc68060__) || defined(mc68060) \
566 || defined(__NeXT__)
567#define count_leading_zeros(count, x) \
568 __asm__ ("bfffo %1{%b2:%b2},%0" \
569 : "=d" ((USItype) (count)) \
570 : "od" ((USItype) (x)), "n" (0))
571#endif
28f540f4
RM
572#endif /* mc68000 */
573
1da2d51a 574#if defined (__m88000__)
28f540f4
RM
575#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
576 __asm__ ("addu.co %1,%r4,%r5
577 addu.ci %0,%r2,%r3" \
1da2d51a
UD
578 : "=r" ((USItype) (sh)), \
579 "=&r" ((USItype) (sl)) \
580 : "%rJ" ((USItype) (ah)), \
581 "rJ" ((USItype) (bh)), \
582 "%rJ" ((USItype) (al)), \
583 "rJ" ((USItype) (bl)))
28f540f4
RM
584#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
585 __asm__ ("subu.co %1,%r4,%r5
586 subu.ci %0,%r2,%r3" \
1da2d51a
UD
587 : "=r" ((USItype) (sh)), \
588 "=&r" ((USItype) (sl)) \
589 : "rJ" ((USItype) (ah)), \
590 "rJ" ((USItype) (bh)), \
591 "rJ" ((USItype) (al)), \
592 "rJ" ((USItype) (bl)))
28f540f4
RM
593#define count_leading_zeros(count, x) \
594 do { \
595 USItype __cbtmp; \
596 __asm__ ("ff1 %0,%1" \
597 : "=r" (__cbtmp) \
1da2d51a 598 : "r" ((USItype) (x))); \
28f540f4
RM
599 (count) = __cbtmp ^ 31; \
600 } while (0)
1da2d51a 601#if defined (__mc88110__)
28f540f4
RM
602#define umul_ppmm(wh, wl, u, v) \
603 do { \
604 union {UDItype __ll; \
605 struct {USItype __h, __l;} __i; \
606 } __xx; \
607 __asm__ ("mulu.d %0,%1,%2" \
608 : "=r" (__xx.__ll) \
1da2d51a
UD
609 : "r" ((USItype) (u)), \
610 "r" ((USItype) (v))); \
28f540f4
RM
611 (wh) = __xx.__i.__h; \
612 (wl) = __xx.__i.__l; \
613 } while (0)
614#define udiv_qrnnd(q, r, n1, n0, d) \
615 ({union {UDItype __ll; \
616 struct {USItype __h, __l;} __i; \
617 } __xx; \
618 USItype __q; \
619 __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
620 __asm__ ("divu.d %0,%1,%2" \
621 : "=r" (__q) \
622 : "r" (__xx.__ll), \
1da2d51a 623 "r" ((USItype) (d))); \
28f540f4
RM
624 (r) = (n0) - __q * (d); (q) = __q; })
625#define UMUL_TIME 5
626#define UDIV_TIME 25
627#else
628#define UMUL_TIME 17
629#define UDIV_TIME 150
1da2d51a 630#endif /* __mc88110__ */
28f540f4
RM
631#endif /* __m88000__ */
632
1da2d51a 633#if defined (__mips__)
8f5ca04b
RM
634#define umul_ppmm(w1, w0, u, v) \
635 __asm__ ("multu %2,%3" \
1da2d51a
UD
636 : "=l" ((USItype) (w0)), \
637 "=h" ((USItype) (w1)) \
638 : "d" ((USItype) (u)), \
639 "d" ((USItype) (v)))
28f540f4
RM
640#define UMUL_TIME 10
641#define UDIV_TIME 100
642#endif /* __mips__ */
643
1da2d51a 644#if defined (__ns32000__)
28f540f4
RM
645#define umul_ppmm(w1, w0, u, v) \
646 ({union {UDItype __ll; \
647 struct {USItype __l, __h;} __i; \
648 } __xx; \
649 __asm__ ("meid %2,%0" \
650 : "=g" (__xx.__ll) \
1da2d51a
UD
651 : "%0" ((USItype) (u)), \
652 "g" ((USItype) (v))); \
28f540f4
RM
653 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
654#define __umulsidi3(u, v) \
655 ({UDItype __w; \
656 __asm__ ("meid %2,%0" \
657 : "=g" (__w) \
1da2d51a
UD
658 : "%0" ((USItype) (u)), \
659 "g" ((USItype) (v))); \
28f540f4
RM
660 __w; })
661#define udiv_qrnnd(q, r, n1, n0, d) \
662 ({union {UDItype __ll; \
663 struct {USItype __l, __h;} __i; \
664 } __xx; \
665 __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
666 __asm__ ("deid %2,%0" \
667 : "=g" (__xx.__ll) \
668 : "0" (__xx.__ll), \
1da2d51a 669 "g" ((USItype) (d))); \
28f540f4 670 (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
62818cfd
UD
671#define count_trailing_zeros(count,x) \
672 do {
673 __asm__ ("ffsd %2,%0" \
674 : "=r" ((USItype) (count)) \
675 : "0" ((USItype) 0), \
676 "r" ((USItype) (x))); \
677 } while (0)
28f540f4
RM
678#endif /* __ns32000__ */
679
8f5ca04b 680#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
28f540f4
RM
681#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
682 do { \
683 if (__builtin_constant_p (bh) && (bh) == 0) \
684 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
1da2d51a
UD
685 : "=r" ((USItype) (sh)), \
686 "=&r" ((USItype) (sl)) \
687 : "%r" ((USItype) (ah)), \
688 "%r" ((USItype) (al)), \
689 "rI" ((USItype) (bl))); \
28f540f4
RM
690 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
691 __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
1da2d51a
UD
692 : "=r" ((USItype) (sh)), \
693 "=&r" ((USItype) (sl)) \
694 : "%r" ((USItype) (ah)), \
695 "%r" ((USItype) (al)), \
696 "rI" ((USItype) (bl))); \
28f540f4
RM
697 else \
698 __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
1da2d51a
UD
699 : "=r" ((USItype) (sh)), \
700 "=&r" ((USItype) (sl)) \
701 : "%r" ((USItype) (ah)), \
702 "r" ((USItype) (bh)), \
703 "%r" ((USItype) (al)), \
704 "rI" ((USItype) (bl))); \
28f540f4
RM
705 } while (0)
706#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
707 do { \
708 if (__builtin_constant_p (ah) && (ah) == 0) \
8f5ca04b 709 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
1da2d51a
UD
710 : "=r" ((USItype) (sh)), \
711 "=&r" ((USItype) (sl)) \
712 : "r" ((USItype) (bh)), \
713 "rI" ((USItype) (al)), \
714 "r" ((USItype) (bl))); \
28f540f4 715 else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
8f5ca04b 716 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
1da2d51a
UD
717 : "=r" ((USItype) (sh)), \
718 "=&r" ((USItype) (sl)) \
719 : "r" ((USItype) (bh)), \
720 "rI" ((USItype) (al)), \
721 "r" ((USItype) (bl))); \
28f540f4
RM
722 else if (__builtin_constant_p (bh) && (bh) == 0) \
723 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
1da2d51a
UD
724 : "=r" ((USItype) (sh)), \
725 "=&r" ((USItype) (sl)) \
726 : "r" ((USItype) (ah)), \
727 "rI" ((USItype) (al)), \
728 "r" ((USItype) (bl))); \
28f540f4
RM
729 else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
730 __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
1da2d51a
UD
731 : "=r" ((USItype) (sh)), \
732 "=&r" ((USItype) (sl)) \
733 : "r" ((USItype) (ah)), \
734 "rI" ((USItype) (al)), \
735 "r" ((USItype) (bl))); \
28f540f4
RM
736 else \
737 __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
1da2d51a
UD
738 : "=r" ((USItype) (sh)), \
739 "=&r" ((USItype) (sl)) \
740 : "r" ((USItype) (ah)), \
741 "r" ((USItype) (bh)), \
742 "rI" ((USItype) (al)), \
743 "r" ((USItype) (bl))); \
28f540f4
RM
744 } while (0)
745#define count_leading_zeros(count, x) \
746 __asm__ ("{cntlz|cntlzw} %0,%1" \
1da2d51a
UD
747 : "=r" ((USItype) (count)) \
748 : "r" ((USItype) (x)))
8f5ca04b 749#if defined (_ARCH_PPC)
28f540f4
RM
750#define umul_ppmm(ph, pl, m0, m1) \
751 do { \
752 USItype __m0 = (m0), __m1 = (m1); \
753 __asm__ ("mulhwu %0,%1,%2" \
754 : "=r" ((USItype) ph) \
755 : "%r" (__m0), \
756 "r" (__m1)); \
757 (pl) = __m0 * __m1; \
758 } while (0)
759#define UMUL_TIME 15
760#define smul_ppmm(ph, pl, m0, m1) \
761 do { \
762 SItype __m0 = (m0), __m1 = (m1); \
763 __asm__ ("mulhw %0,%1,%2" \
764 : "=r" ((SItype) ph) \
765 : "%r" (__m0), \
766 "r" (__m1)); \
767 (pl) = __m0 * __m1; \
768 } while (0)
769#define SMUL_TIME 14
770#define UDIV_TIME 120
771#else
772#define umul_ppmm(xh, xl, m0, m1) \
773 do { \
774 USItype __m0 = (m0), __m1 = (m1); \
775 __asm__ ("mul %0,%2,%3" \
1da2d51a
UD
776 : "=r" ((USItype) (xh)), \
777 "=q" ((USItype) (xl)) \
28f540f4
RM
778 : "r" (__m0), \
779 "r" (__m1)); \
780 (xh) += ((((SItype) __m0 >> 31) & __m1) \
781 + (((SItype) __m1 >> 31) & __m0)); \
782 } while (0)
783#define UMUL_TIME 8
784#define smul_ppmm(xh, xl, m0, m1) \
785 __asm__ ("mul %0,%2,%3" \
1da2d51a
UD
786 : "=r" ((SItype) (xh)), \
787 "=q" ((SItype) (xl)) \
28f540f4
RM
788 : "r" (m0), \
789 "r" (m1))
790#define SMUL_TIME 4
791#define sdiv_qrnnd(q, r, nh, nl, d) \
792 __asm__ ("div %0,%2,%4" \
1da2d51a
UD
793 : "=r" ((SItype) (q)), "=q" ((SItype) (r)) \
794 : "r" ((SItype) (nh)), "1" ((SItype) (nl)), "r" ((SItype) (d)))
28f540f4
RM
795#define UDIV_TIME 100
796#endif
797#endif /* Power architecture variants. */
798
1da2d51a 799#if defined (__pyr__)
28f540f4
RM
800#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
801 __asm__ ("addw %5,%1
802 addwc %3,%0" \
1da2d51a
UD
803 : "=r" ((USItype) (sh)), \
804 "=&r" ((USItype) (sl)) \
805 : "%0" ((USItype) (ah)), \
806 "g" ((USItype) (bh)), \
807 "%1" ((USItype) (al)), \
808 "g" ((USItype) (bl)))
28f540f4
RM
809#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
810 __asm__ ("subw %5,%1
811 subwb %3,%0" \
1da2d51a
UD
812 : "=r" ((USItype) (sh)), \
813 "=&r" ((USItype) (sl)) \
814 : "0" ((USItype) (ah)), \
815 "g" ((USItype) (bh)), \
816 "1" ((USItype) (al)), \
817 "g" ((USItype) (bl)))
8f5ca04b 818/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
28f540f4
RM
819#define umul_ppmm(w1, w0, u, v) \
820 ({union {UDItype __ll; \
821 struct {USItype __h, __l;} __i; \
822 } __xx; \
8f5ca04b
RM
823 __asm__ ("movw %1,%R0
824 uemul %2,%0" \
825 : "=&r" (__xx.__ll) \
826 : "g" ((USItype) (u)), \
1da2d51a 827 "g" ((USItype) (v))); \
28f540f4
RM
828 (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
829#endif /* __pyr__ */
830
1da2d51a 831#if defined (__ibm032__) /* RT/ROMP */
28f540f4
RM
832#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
833 __asm__ ("a %1,%5
834 ae %0,%3" \
1da2d51a
UD
835 : "=r" ((USItype) (sh)), \
836 "=&r" ((USItype) (sl)) \
837 : "%0" ((USItype) (ah)), \
838 "r" ((USItype) (bh)), \
839 "%1" ((USItype) (al)), \
840 "r" ((USItype) (bl)))
28f540f4
RM
841#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
842 __asm__ ("s %1,%5
843 se %0,%3" \
1da2d51a
UD
844 : "=r" ((USItype) (sh)), \
845 "=&r" ((USItype) (sl)) \
846 : "0" ((USItype) (ah)), \
847 "r" ((USItype) (bh)), \
848 "1" ((USItype) (al)), \
849 "r" ((USItype) (bl)))
28f540f4
RM
850#define umul_ppmm(ph, pl, m0, m1) \
851 do { \
852 USItype __m0 = (m0), __m1 = (m1); \
853 __asm__ ( \
854 "s r2,r2
855 mts r10,%2
856 m r2,%3
857 m r2,%3
858 m r2,%3
859 m r2,%3
860 m r2,%3
861 m r2,%3
862 m r2,%3
863 m r2,%3
864 m r2,%3
865 m r2,%3
866 m r2,%3
867 m r2,%3
868 m r2,%3
869 m r2,%3
870 m r2,%3
871 m r2,%3
872 cas %0,r2,r0
873 mfs r10,%1" \
1da2d51a
UD
874 : "=r" ((USItype) (ph)), \
875 "=r" ((USItype) (pl)) \
28f540f4
RM
876 : "%r" (__m0), \
877 "r" (__m1) \
878 : "r2"); \
879 (ph) += ((((SItype) __m0 >> 31) & __m1) \
880 + (((SItype) __m1 >> 31) & __m0)); \
881 } while (0)
882#define UMUL_TIME 20
883#define UDIV_TIME 200
884#define count_leading_zeros(count, x) \
885 do { \
886 if ((x) >= 0x10000) \
887 __asm__ ("clz %0,%1" \
1da2d51a
UD
888 : "=r" ((USItype) (count)) \
889 : "r" ((USItype) (x) >> 16)); \
28f540f4
RM
890 else \
891 { \
892 __asm__ ("clz %0,%1" \
1da2d51a
UD
893 : "=r" ((USItype) (count)) \
894 : "r" ((USItype) (x))); \
28f540f4
RM
895 (count) += 16; \
896 } \
897 } while (0)
8f5ca04b
RM
898#endif
899
1da2d51a 900#if defined (__sparc__)
28f540f4
RM
901#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
902 __asm__ ("addcc %r4,%5,%1
903 addx %r2,%3,%0" \
1da2d51a
UD
904 : "=r" ((USItype) (sh)), \
905 "=&r" ((USItype) (sl)) \
906 : "%rJ" ((USItype) (ah)), \
907 "rI" ((USItype) (bh)), \
908 "%rJ" ((USItype) (al)), \
909 "rI" ((USItype) (bl)) \
28f540f4
RM
910 __CLOBBER_CC)
911#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
912 __asm__ ("subcc %r4,%5,%1
913 subx %r2,%3,%0" \
1da2d51a
UD
914 : "=r" ((USItype) (sh)), \
915 "=&r" ((USItype) (sl)) \
916 : "rJ" ((USItype) (ah)), \
917 "rI" ((USItype) (bh)), \
918 "rJ" ((USItype) (al)), \
919 "rI" ((USItype) (bl)) \
28f540f4
RM
920 __CLOBBER_CC)
921#if defined (__sparc_v8__)
28f540f4
RM
922#define umul_ppmm(w1, w0, u, v) \
923 __asm__ ("umul %2,%3,%1;rd %%y,%0" \
1da2d51a
UD
924 : "=r" ((USItype) (w1)), \
925 "=r" ((USItype) (w0)) \
926 : "r" ((USItype) (u)), \
927 "r" ((USItype) (v)))
28f540f4 928#define udiv_qrnnd(q, r, n1, n0, d) \
1da2d51a
UD
929 __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
930 : "=&r" ((USItype) (q)), \
931 "=&r" ((USItype) (r)) \
932 : "r" ((USItype) (n1)), \
933 "r" ((USItype) (n0)), \
934 "r" ((USItype) (d)))
935#else
28f540f4
RM
936#if defined (__sparclite__)
937/* This has hardware multiply but not divide. It also has two additional
938 instructions scan (ffs from high bit) and divscc. */
939#define umul_ppmm(w1, w0, u, v) \
940 __asm__ ("umul %2,%3,%1;rd %%y,%0" \
1da2d51a
UD
941 : "=r" ((USItype) (w1)), \
942 "=r" ((USItype) (w0)) \
943 : "r" ((USItype) (u)), \
944 "r" ((USItype) (v)))
28f540f4
RM
945#define udiv_qrnnd(q, r, n1, n0, d) \
946 __asm__ ("! Inlined udiv_qrnnd
947 wr %%g0,%2,%%y ! Not a delayed write for sparclite
948 tst %%g0
949 divscc %3,%4,%%g1
950 divscc %%g1,%4,%%g1
951 divscc %%g1,%4,%%g1
952 divscc %%g1,%4,%%g1
953 divscc %%g1,%4,%%g1
954 divscc %%g1,%4,%%g1
955 divscc %%g1,%4,%%g1
956 divscc %%g1,%4,%%g1
957 divscc %%g1,%4,%%g1
958 divscc %%g1,%4,%%g1
959 divscc %%g1,%4,%%g1
960 divscc %%g1,%4,%%g1
961 divscc %%g1,%4,%%g1
962 divscc %%g1,%4,%%g1
963 divscc %%g1,%4,%%g1
964 divscc %%g1,%4,%%g1
965 divscc %%g1,%4,%%g1
966 divscc %%g1,%4,%%g1
967 divscc %%g1,%4,%%g1
968 divscc %%g1,%4,%%g1
969 divscc %%g1,%4,%%g1
970 divscc %%g1,%4,%%g1
971 divscc %%g1,%4,%%g1
972 divscc %%g1,%4,%%g1
973 divscc %%g1,%4,%%g1
974 divscc %%g1,%4,%%g1
975 divscc %%g1,%4,%%g1
976 divscc %%g1,%4,%%g1
977 divscc %%g1,%4,%%g1
978 divscc %%g1,%4,%%g1
979 divscc %%g1,%4,%%g1
980 divscc %%g1,%4,%0
981 rd %%y,%1
982 bl,a 1f
983 add %1,%4,%1
9841: ! End of inline udiv_qrnnd" \
1da2d51a
UD
985 : "=r" ((USItype) (q)), \
986 "=r" ((USItype) (r)) \
987 : "r" ((USItype) (n1)), \
988 "r" ((USItype) (n0)), \
989 "rI" ((USItype) (d)) \
28f540f4
RM
990 : "%g1" __AND_CLOBBER_CC)
991#define UDIV_TIME 37
992#define count_leading_zeros(count, x) \
1da2d51a
UD
993 do { \
994 __asm__ ("scan %1,1,%0" \
995 : "=r" ((USItype) (count)) \
996 : "r" ((USItype) (x))); \
62818cfd 997 } while (0)
1da2d51a
UD
998#else
999/* SPARC without integer multiplication and divide instructions.
1000 (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
28f540f4
RM
1001#define umul_ppmm(w1, w0, u, v) \
1002 __asm__ ("! Inlined umul_ppmm
1003 wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr
1004 sra %3,31,%%g2 ! Don't move this insn
1005 and %2,%%g2,%%g2 ! Don't move this insn
1006 andcc %%g0,0,%%g1 ! Don't move this insn
1007 mulscc %%g1,%3,%%g1
1008 mulscc %%g1,%3,%%g1
1009 mulscc %%g1,%3,%%g1
1010 mulscc %%g1,%3,%%g1
1011 mulscc %%g1,%3,%%g1
1012 mulscc %%g1,%3,%%g1
1013 mulscc %%g1,%3,%%g1
1014 mulscc %%g1,%3,%%g1
1015 mulscc %%g1,%3,%%g1
1016 mulscc %%g1,%3,%%g1
1017 mulscc %%g1,%3,%%g1
1018 mulscc %%g1,%3,%%g1
1019 mulscc %%g1,%3,%%g1
1020 mulscc %%g1,%3,%%g1
1021 mulscc %%g1,%3,%%g1
1022 mulscc %%g1,%3,%%g1
1023 mulscc %%g1,%3,%%g1
1024 mulscc %%g1,%3,%%g1
1025 mulscc %%g1,%3,%%g1
1026 mulscc %%g1,%3,%%g1
1027 mulscc %%g1,%3,%%g1
1028 mulscc %%g1,%3,%%g1
1029 mulscc %%g1,%3,%%g1
1030 mulscc %%g1,%3,%%g1
1031 mulscc %%g1,%3,%%g1
1032 mulscc %%g1,%3,%%g1
1033 mulscc %%g1,%3,%%g1
1034 mulscc %%g1,%3,%%g1
1035 mulscc %%g1,%3,%%g1
1036 mulscc %%g1,%3,%%g1
1037 mulscc %%g1,%3,%%g1
1038 mulscc %%g1,%3,%%g1
1039 mulscc %%g1,0,%%g1
1040 add %%g1,%%g2,%0
1041 rd %%y,%1" \
1da2d51a
UD
1042 : "=r" ((USItype) (w1)), \
1043 "=r" ((USItype) (w0)) \
1044 : "%rI" ((USItype) (u)), \
1045 "r" ((USItype) (v)) \
28f540f4
RM
1046 : "%g1", "%g2" __AND_CLOBBER_CC)
1047#define UMUL_TIME 39 /* 39 instructions */
390a4882
UD
1048/* It's quite necessary to add this much assembler for the sparc.
1049 The default udiv_qrnnd (in C) is more than 10 times slower! */
28f540f4 1050#define udiv_qrnnd(q, r, n1, n0, d) \
390a4882
UD
1051 __asm__ ("! Inlined udiv_qrnnd
1052 mov 32,%%g1
1053 subcc %1,%2,%%g0
10541: bcs 5f
1055 addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
1056 sub %1,%2,%1 ! this kills msb of n
1057 addx %1,%1,%1 ! so this can't give carry
1058 subcc %%g1,1,%%g1
10592: bne 1b
1060 subcc %1,%2,%%g0
1061 bcs 3f
1062 addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb
1063 b 3f
1064 sub %1,%2,%1 ! this kills msb of n
10654: sub %1,%2,%1
10665: addxcc %1,%1,%1
1067 bcc 2b
1068 subcc %%g1,1,%%g1
1069! Got carry from n. Subtract next step to cancel this carry.
1070 bne 4b
1071 addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb
1072 sub %1,%2,%1
10733: xnor %0,0,%0
1074 ! End of inline udiv_qrnnd" \
1da2d51a
UD
1075 : "=&r" ((USItype) (q)), \
1076 "=&r" ((USItype) (r)) \
1077 : "r" ((USItype) (d)), \
1078 "1" ((USItype) (n1)), \
1079 "0" ((USItype) (n0)) : "%g1" __AND_CLOBBER_CC)
390a4882 1080#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */
1da2d51a
UD
1081#endif /* __sparclite__ */
1082#endif /* __sparc_v8__ */
28f540f4
RM
1083#endif /* __sparc__ */
1084
1da2d51a 1085#if defined (__vax__)
28f540f4
RM
1086#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1087 __asm__ ("addl2 %5,%1
1088 adwc %3,%0" \
1da2d51a
UD
1089 : "=g" ((USItype) (sh)), \
1090 "=&g" ((USItype) (sl)) \
1091 : "%0" ((USItype) (ah)), \
1092 "g" ((USItype) (bh)), \
1093 "%1" ((USItype) (al)), \
1094 "g" ((USItype) (bl)))
28f540f4
RM
1095#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1096 __asm__ ("subl2 %5,%1
1097 sbwc %3,%0" \
1da2d51a
UD
1098 : "=g" ((USItype) (sh)), \
1099 "=&g" ((USItype) (sl)) \
1100 : "0" ((USItype) (ah)), \
1101 "g" ((USItype) (bh)), \
1102 "1" ((USItype) (al)), \
1103 "g" ((USItype) (bl)))
28f540f4
RM
1104#define umul_ppmm(xh, xl, m0, m1) \
1105 do { \
1da2d51a
UD
1106 union { \
1107 UDItype __ll; \
1108 struct {USItype __l, __h;} __i; \
1109 } __xx; \
28f540f4
RM
1110 USItype __m0 = (m0), __m1 = (m1); \
1111 __asm__ ("emul %1,%2,$0,%0" \
1da2d51a 1112 : "=r" (__xx.__ll) \
28f540f4
RM
1113 : "g" (__m0), \
1114 "g" (__m1)); \
1da2d51a
UD
1115 (xh) = __xx.__i.__h; \
1116 (xl) = __xx.__i.__l; \
28f540f4
RM
1117 (xh) += ((((SItype) __m0 >> 31) & __m1) \
1118 + (((SItype) __m1 >> 31) & __m0)); \
1119 } while (0)
1120#define sdiv_qrnnd(q, r, n1, n0, d) \
1121 do { \
1122 union {DItype __ll; \
1123 struct {SItype __l, __h;} __i; \
1124 } __xx; \
1125 __xx.__i.__h = n1; __xx.__i.__l = n0; \
1126 __asm__ ("ediv %3,%2,%0,%1" \
1127 : "=g" (q), "=g" (r) \
1da2d51a 1128 : "g" (__xx.__ll), "g" (d)); \
28f540f4
RM
1129 } while (0)
1130#endif /* __vax__ */
1131
28f540f4
RM
1132#endif /* __GNUC__ */
1133
28f540f4
RM
1134/* If this machine has no inline assembler, use C macros. */
1135
1136#if !defined (add_ssaaaa)
1137#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1138 do { \
1da2d51a 1139 USItype __x; \
28f540f4
RM
1140 __x = (al) + (bl); \
1141 (sh) = (ah) + (bh) + (__x < (al)); \
1142 (sl) = __x; \
1143 } while (0)
1144#endif
1145
1146#if !defined (sub_ddmmss)
1147#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1148 do { \
1da2d51a 1149 USItype __x; \
28f540f4
RM
1150 __x = (al) - (bl); \
1151 (sh) = (ah) - (bh) - (__x > (al)); \
1152 (sl) = __x; \
1153 } while (0)
1154#endif
1155
1156#if !defined (umul_ppmm)
1157#define umul_ppmm(w1, w0, u, v) \
1158 do { \
1da2d51a
UD
1159 USItype __x0, __x1, __x2, __x3; \
1160 USItype __ul, __vl, __uh, __vh; \
28f540f4 1161 \
1da2d51a
UD
1162 __ul = __ll_lowpart (u); \
1163 __uh = __ll_highpart (u); \
1164 __vl = __ll_lowpart (v); \
1165 __vh = __ll_highpart (v); \
28f540f4 1166 \
1da2d51a
UD
1167 __x0 = (USItype) __ul * __vl; \
1168 __x1 = (USItype) __ul * __vh; \
1169 __x2 = (USItype) __uh * __vl; \
1170 __x3 = (USItype) __uh * __vh; \
28f540f4
RM
1171 \
1172 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
1173 __x1 += __x2; /* but this indeed can */ \
1174 if (__x1 < __x2) /* did we get it? */ \
1175 __x3 += __ll_B; /* yes, add it in the proper pos. */ \
1176 \
1177 (w1) = __x3 + __ll_highpart (__x1); \
1da2d51a 1178 (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
28f540f4
RM
1179 } while (0)
1180#endif
1181
1da2d51a
UD
1182#if !defined (__umulsidi3)
1183#define __umulsidi3(u, v) \
1184 ({DIunion __w; \
1185 umul_ppmm (__w.s.high, __w.s.low, u, v); \
1186 __w.ll; })
8f5ca04b
RM
1187#endif
1188
28f540f4
RM
1189/* Define this unconditionally, so it can be used for debugging. */
1190#define __udiv_qrnnd_c(q, r, n1, n0, d) \
1191 do { \
1da2d51a
UD
1192 USItype __d1, __d0, __q1, __q0; \
1193 USItype __r1, __r0, __m; \
28f540f4
RM
1194 __d1 = __ll_highpart (d); \
1195 __d0 = __ll_lowpart (d); \
1196 \
1197 __r1 = (n1) % __d1; \
1198 __q1 = (n1) / __d1; \
1da2d51a 1199 __m = (USItype) __q1 * __d0; \
28f540f4
RM
1200 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
1201 if (__r1 < __m) \
1202 { \
1203 __q1--, __r1 += (d); \
1204 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
1205 if (__r1 < __m) \
1206 __q1--, __r1 += (d); \
1207 } \
1208 __r1 -= __m; \
1209 \
1210 __r0 = __r1 % __d1; \
1211 __q0 = __r1 / __d1; \
1da2d51a 1212 __m = (USItype) __q0 * __d0; \
28f540f4
RM
1213 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
1214 if (__r0 < __m) \
1215 { \
1216 __q0--, __r0 += (d); \
1217 if (__r0 >= (d)) \
1218 if (__r0 < __m) \
1219 __q0--, __r0 += (d); \
1220 } \
1221 __r0 -= __m; \
1222 \
1da2d51a 1223 (q) = (USItype) __q1 * __ll_B | __q0; \
28f540f4
RM
1224 (r) = __r0; \
1225 } while (0)
1226
1227/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
1228 __udiv_w_sdiv (defined in libgcc or elsewhere). */
1229#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
1230#define udiv_qrnnd(q, r, nh, nl, d) \
1231 do { \
1da2d51a
UD
1232 USItype __r; \
1233 (q) = __udiv_w_sdiv (&__r, nh, nl, d); \
28f540f4
RM
1234 (r) = __r; \
1235 } while (0)
1236#endif
1237
1238/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
1239#if !defined (udiv_qrnnd)
1240#define UDIV_NEEDS_NORMALIZATION 1
1241#define udiv_qrnnd __udiv_qrnnd_c
1242#endif
1243
1244#if !defined (count_leading_zeros)
1da2d51a 1245extern const UQItype __clz_tab[];
28f540f4
RM
1246#define count_leading_zeros(count, x) \
1247 do { \
1da2d51a
UD
1248 USItype __xr = (x); \
1249 USItype __a; \
28f540f4 1250 \
1da2d51a 1251 if (SI_TYPE_SIZE <= 32) \
28f540f4 1252 { \
1da2d51a
UD
1253 __a = __xr < ((USItype)1<<2*__BITS4) \
1254 ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
1255 : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
28f540f4
RM
1256 } \
1257 else \
1258 { \
1da2d51a 1259 for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
28f540f4
RM
1260 if (((__xr >> __a) & 0xff) != 0) \
1261 break; \
1262 } \
1263 \
1da2d51a 1264 (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
28f540f4
RM
1265 } while (0)
1266#endif
1267
62818cfd
UD
1268#if !defined (count_trailing_zeros)
1269/* Define count_trailing_zeros using count_leading_zeros. The latter might be
1270 defined in asm, but if it is not, the C version above is good enough. */
1271#define count_trailing_zeros(count, x) \
1272 do { \
1273 USItype __ctz_x = (x); \
1274 USItype __ctz_c; \
1275 count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
1276 (count) = SI_TYPE_SIZE - 1 - __ctz_c; \
1277 } while (0)
1278#endif
1279
28f540f4
RM
1280#ifndef UDIV_NEEDS_NORMALIZATION
1281#define UDIV_NEEDS_NORMALIZATION 0
1282#endif