1 /* $Id: asm1.h 7697 2006-02-16 17:34:46Z kb $
2
3 Copyright (C) 2000 The PARI group.
4
5 This file is part of the PARI/GP package.
6
7 PARI/GP is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY WHATSOEVER.
11
12 Check the License for details. You should have received a copy of it, along
13 with the package; see the file 'COPYING'. If not, write to the Free Software
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15
16 /* This file is a slight adaptation of source code extracted from gmp-3.1.1
17 (from T. Granlund), files longlong.h and gmp-impl.h
18
19 Copyright (C) 2000 Free Software Foundation, Inc.
20
21 * FIXME: This file is unused until somebody implements
22 * invert_word(x) = return floor( 2^(2*BIL)/x ) */
23
24 extern ulong invert_word(ulong);
25
26 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
27 do { \
28 ulong __x; \
29 __x = (al) - (bl); \
30 (sh) = (ah) - (bh) - (__x > (al)); \
31 (sl) = __x; \
32 } while (0)
33
34 #ifdef __GNUC__
35
36 #define divll(x, y) \
37 ({ \
38 register ulong _di, _x = (x), _y = (y), _q, _ql, _r; \
39 register ulong _xh, _xl, _k, __hire; \
40 \
41 if (_y & 0x8000000000000000UL) \
42 { _k = 0; __hire = hiremainder; } \
43 else \
44 { \
45 _k = bfffo(_y); \
46 __hire = (hiremainder << _k) | (_x >> (64 - _k)); \
47 _x <<= _k; _y <<= _k; \
48 } \
49 _di = invert_word(_y); \
50 _ql = mulll (__hire, _di); \
51 _q = __hire + hiremainder; \
52 _xl = mulll(_q, _y); _xh = hiremainder; \
53 sub_ddmmss (_xh, _r, __hire, _x, _xh, _xl); \
54 if (_xh != 0) \
55 { \
56 sub_ddmmss (_xh, _r, _xh, _r, 0, _y); _q += 1; \
57 if (_xh != 0) \
58 { sub_ddmmss (_xh, _r, _xh, _r, 0, _y); _q += 1; } \
59 } \
60 if (_r >= _y) \
61 { _r -= _y; _q += 1; } \
62 hiremainder = _r >> _k; \
63 _q; \
64 })
65
66 #else /* __GNUC__ */
67
68 static ulong
divll(ulong x,ulong y)69 divll(ulong x, ulong y)
70 {
71 register ulong _di, _x = (x), _y = (y), _q, _ql, _r;
72 register ulong _xh, _xl, _k, __hire;
73
74 if (_y & 0x8000000000000000UL)
75 { _k = 0; __hire = hiremainder; }
76 else
77 {
78 _k = bfffo(_y);
79 __hire = (hiremainder << _k) | (_x >> (64 - _k));
80 _x <<= _k; _y <<= _k;
81 }
82 _di = invert_word(_y);
83 _ql = mulll (__hire, _di);
84 _q = __hire + hiremainder;
85 _xl = mulll(_q, _y); _xh = hiremainder;
86 sub_ddmmss (_xh, _r, __hire, _x, _xh, _xl);
87 if (_xh != 0)
88 {
89 sub_ddmmss (_xh, _r, _xh, _r, 0, _y); _q += 1;
90 if (_xh != 0)
91 { sub_ddmmss (_xh, _r, _xh, _r, 0, _y); _q += 1; }
92 }
93 if (_r >= _y)
94 { _r -= _y; _q += 1; }
95 hiremainder = _r >> _k;
96 return _q;
97 }
98
99 #endif /* __GNUC__ */
100