aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/ashldi3.c47
-rw-r--r--arch/arm/lib/ashrdi3.c48
-rw-r--r--arch/arm/lib/gcclib.h27
-rw-r--r--arch/arm/lib/io-writesw-armv4.S6
-rw-r--r--arch/arm/lib/longlong.h68
-rw-r--r--arch/arm/lib/lshrdi3.c47
-rw-r--r--arch/arm/lib/muldi3.c31
-rw-r--r--arch/arm/lib/ucmpdi2.c30
-rw-r--r--arch/arm/lib/udivdi3.c372
9 files changed, 316 insertions, 360 deletions
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
index 130f5a839669..b62875cfd8f8 100644
--- a/arch/arm/lib/ashldi3.c
+++ b/arch/arm/lib/ashldi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __ashldi3(s64 u, int b)
35__ashldi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 w.s.low = 0;
49 w.s.low = 0; 48 w.s.high = (u32) uu.s.low << -bm;
50 w.s.high = (USItype)uu.s.low << -bm; 49 } else {
51 } 50 u32 carries = (u32) uu.s.low >> bm;
52 else 51 w.s.low = (u32) uu.s.low << b;
53 { 52 w.s.high = ((u32) uu.s.high << b) | carries;
54 USItype carries = (USItype)uu.s.low >> bm; 53 }
55 w.s.low = (USItype)uu.s.low << b; 54
56 w.s.high = ((USItype)uu.s.high << b) | carries; 55 return w.ll;
57 }
58
59 return w.ll;
60} 56}
61
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
index 71625d218f8d..9a8600a7543f 100644
--- a/arch/arm/lib/ashrdi3.c
+++ b/arch/arm/lib/ashrdi3.c
@@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __ashrdi3(s64 u, int b)
35__ashrdi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 /* w.s.high = 1..1 or 0..0 */
49 /* w.s.high = 1..1 or 0..0 */ 48 w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
50 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); 49 w.s.low = uu.s.high >> -bm;
51 w.s.low = uu.s.high >> -bm; 50 } else {
52 } 51 u32 carries = (u32) uu.s.high << bm;
53 else 52 w.s.high = uu.s.high >> b;
54 { 53 w.s.low = ((u32) uu.s.low >> b) | carries;
55 USItype carries = (USItype)uu.s.high << bm; 54 }
56 w.s.high = uu.s.high >> b; 55
57 w.s.low = ((USItype)uu.s.low >> b) | carries; 56 return w.ll;
58 }
59
60 return w.ll;
61} 57}
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
index 65314a3d9e27..8b6dcc656de7 100644
--- a/arch/arm/lib/gcclib.h
+++ b/arch/arm/lib/gcclib.h
@@ -1,25 +1,22 @@
1/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */ 1/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
2/* I Molton 29/07/01 */ 2/* I Molton 29/07/01 */
3 3
4#define BITS_PER_UNIT 8 4#include <linux/types.h>
5#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
6 5
7typedef unsigned int UQItype __attribute__ ((mode (QI))); 6#define BITS_PER_UNIT 8
8typedef int SItype __attribute__ ((mode (SI))); 7#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
9typedef unsigned int USItype __attribute__ ((mode (SI)));
10typedef int DItype __attribute__ ((mode (DI)));
11typedef int word_type __attribute__ ((mode (__word__)));
12typedef unsigned int UDItype __attribute__ ((mode (DI)));
13 8
14#ifdef __ARMEB__ 9#ifdef __ARMEB__
15 struct DIstruct {SItype high, low;}; 10struct DIstruct {
11 s32 high, low;
12};
16#else 13#else
17 struct DIstruct {SItype low, high;}; 14struct DIstruct {
15 s32 low, high;
16};
18#endif 17#endif
19 18
20typedef union 19typedef union {
21{ 20 struct DIstruct s;
22 struct DIstruct s; 21 s64 ll;
23 DItype ll;
24} DIunion; 22} DIunion;
25
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index 6d1d7c27806e..5e240e452af6 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw)
87 subs r2, r2, #2 87 subs r2, r2, #2
88 orr ip, ip, r3, push_hbyte1 88 orr ip, ip, r3, push_hbyte1
89 strh ip, [r0] 89 strh ip, [r0]
90 bpl 2b 90 bpl 1b
91 91
923: tst r2, #1 92 tst r2, #1
932: movne ip, r3, lsr #8 933: movne ip, r3, lsr #8
94 strneh ip, [r0] 94 strneh ip, [r0]
95 mov pc, lr 95 mov pc, lr
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
index 179eea4edc35..90ae647e4d76 100644
--- a/arch/arm/lib/longlong.h
+++ b/arch/arm/lib/longlong.h
@@ -26,18 +26,18 @@
26 26
27#define __BITS4 (SI_TYPE_SIZE / 4) 27#define __BITS4 (SI_TYPE_SIZE / 4)
28#define __ll_B (1L << (SI_TYPE_SIZE / 2)) 28#define __ll_B (1L << (SI_TYPE_SIZE / 2))
29#define __ll_lowpart(t) ((USItype) (t) % __ll_B) 29#define __ll_lowpart(t) ((u32) (t) % __ll_B)
30#define __ll_highpart(t) ((USItype) (t) / __ll_B) 30#define __ll_highpart(t) ((u32) (t) / __ll_B)
31 31
32/* Define auxiliary asm macros. 32/* Define auxiliary asm macros.
33 33
34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) 34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
35 multiplies two USItype integers MULTIPLER and MULTIPLICAND, 35 multiplies two u32 integers MULTIPLER and MULTIPLICAND,
36 and generates a two-part USItype product in HIGH_PROD and 36 and generates a two-part u32 product in HIGH_PROD and
37 LOW_PROD. 37 LOW_PROD.
38 38
39 2) __umulsidi3(a,b) multiplies two USItype integers A and B, 39 2) __umulsidi3(a,b) multiplies two u32 integers A and B,
40 and returns a UDItype product. This is just a variant of umul_ppmm. 40 and returns a u64 product. This is just a variant of umul_ppmm.
41 41
42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
43 denominator) divides a two-word unsigned integer, composed by the 43 denominator) divides a two-word unsigned integer, composed by the
@@ -77,23 +77,23 @@
77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
78 __asm__ ("adds %1, %4, %5 \n\ 78 __asm__ ("adds %1, %4, %5 \n\
79 adc %0, %2, %3" \ 79 adc %0, %2, %3" \
80 : "=r" ((USItype) (sh)), \ 80 : "=r" ((u32) (sh)), \
81 "=&r" ((USItype) (sl)) \ 81 "=&r" ((u32) (sl)) \
82 : "%r" ((USItype) (ah)), \ 82 : "%r" ((u32) (ah)), \
83 "rI" ((USItype) (bh)), \ 83 "rI" ((u32) (bh)), \
84 "%r" ((USItype) (al)), \ 84 "%r" ((u32) (al)), \
85 "rI" ((USItype) (bl))) 85 "rI" ((u32) (bl)))
86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
87 __asm__ ("subs %1, %4, %5 \n\ 87 __asm__ ("subs %1, %4, %5 \n\
88 sbc %0, %2, %3" \ 88 sbc %0, %2, %3" \
89 : "=r" ((USItype) (sh)), \ 89 : "=r" ((u32) (sh)), \
90 "=&r" ((USItype) (sl)) \ 90 "=&r" ((u32) (sl)) \
91 : "r" ((USItype) (ah)), \ 91 : "r" ((u32) (ah)), \
92 "rI" ((USItype) (bh)), \ 92 "rI" ((u32) (bh)), \
93 "r" ((USItype) (al)), \ 93 "r" ((u32) (al)), \
94 "rI" ((USItype) (bl))) 94 "rI" ((u32) (bl)))
95#define umul_ppmm(xh, xl, a, b) \ 95#define umul_ppmm(xh, xl, a, b) \
96{register USItype __t0, __t1, __t2; \ 96{register u32 __t0, __t1, __t2; \
97 __asm__ ("%@ Inlined umul_ppmm \n\ 97 __asm__ ("%@ Inlined umul_ppmm \n\
98 mov %2, %5, lsr #16 \n\ 98 mov %2, %5, lsr #16 \n\
99 mov %0, %6, lsr #16 \n\ 99 mov %0, %6, lsr #16 \n\
@@ -107,14 +107,14 @@
107 addcs %0, %0, #65536 \n\ 107 addcs %0, %0, #65536 \n\
108 adds %1, %1, %3, lsl #16 \n\ 108 adds %1, %1, %3, lsl #16 \n\
109 adc %0, %0, %3, lsr #16" \ 109 adc %0, %0, %3, lsr #16" \
110 : "=&r" ((USItype) (xh)), \ 110 : "=&r" ((u32) (xh)), \
111 "=r" ((USItype) (xl)), \ 111 "=r" ((u32) (xl)), \
112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
113 : "r" ((USItype) (a)), \ 113 : "r" ((u32) (a)), \
114 "r" ((USItype) (b)));} 114 "r" ((u32) (b)));}
115#define UMUL_TIME 20 115#define UMUL_TIME 20
116#define UDIV_TIME 100 116#define UDIV_TIME 100
117#endif /* __arm__ */ 117#endif /* __arm__ */
118 118
119#define __umulsidi3(u, v) \ 119#define __umulsidi3(u, v) \
120 ({DIunion __w; \ 120 ({DIunion __w; \
@@ -123,14 +123,14 @@
123 123
124#define __udiv_qrnnd_c(q, r, n1, n0, d) \ 124#define __udiv_qrnnd_c(q, r, n1, n0, d) \
125 do { \ 125 do { \
126 USItype __d1, __d0, __q1, __q0; \ 126 u32 __d1, __d0, __q1, __q0; \
127 USItype __r1, __r0, __m; \ 127 u32 __r1, __r0, __m; \
128 __d1 = __ll_highpart (d); \ 128 __d1 = __ll_highpart (d); \
129 __d0 = __ll_lowpart (d); \ 129 __d0 = __ll_lowpart (d); \
130 \ 130 \
131 __r1 = (n1) % __d1; \ 131 __r1 = (n1) % __d1; \
132 __q1 = (n1) / __d1; \ 132 __q1 = (n1) / __d1; \
133 __m = (USItype) __q1 * __d0; \ 133 __m = (u32) __q1 * __d0; \
134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \ 134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
135 if (__r1 < __m) \ 135 if (__r1 < __m) \
136 { \ 136 { \
@@ -143,7 +143,7 @@
143 \ 143 \
144 __r0 = __r1 % __d1; \ 144 __r0 = __r1 % __d1; \
145 __q0 = __r1 / __d1; \ 145 __q0 = __r1 / __d1; \
146 __m = (USItype) __q0 * __d0; \ 146 __m = (u32) __q0 * __d0; \
147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ 147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
148 if (__r0 < __m) \ 148 if (__r0 < __m) \
149 { \ 149 { \
@@ -154,7 +154,7 @@
154 } \ 154 } \
155 __r0 -= __m; \ 155 __r0 -= __m; \
156 \ 156 \
157 (q) = (USItype) __q1 * __ll_B | __q0; \ 157 (q) = (u32) __q1 * __ll_B | __q0; \
158 (r) = __r0; \ 158 (r) = __r0; \
159 } while (0) 159 } while (0)
160 160
@@ -163,14 +163,14 @@
163 163
164#define count_leading_zeros(count, x) \ 164#define count_leading_zeros(count, x) \
165 do { \ 165 do { \
166 USItype __xr = (x); \ 166 u32 __xr = (x); \
167 USItype __a; \ 167 u32 __a; \
168 \ 168 \
169 if (SI_TYPE_SIZE <= 32) \ 169 if (SI_TYPE_SIZE <= 32) \
170 { \ 170 { \
171 __a = __xr < ((USItype)1<<2*__BITS4) \ 171 __a = __xr < ((u32)1<<2*__BITS4) \
172 ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \ 172 ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
173 : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 173 : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
174 } \ 174 } \
175 else \ 175 else \
176 { \ 176 { \
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
index b666f1bad451..3681f49d2b6e 100644
--- a/arch/arm/lib/lshrdi3.c
+++ b/arch/arm/lib/lshrdi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __lshrdi3(s64 u, int b)
35__lshrdi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 w.s.high = 0;
49 w.s.high = 0; 48 w.s.low = (u32) uu.s.high >> -bm;
50 w.s.low = (USItype)uu.s.high >> -bm; 49 } else {
51 } 50 u32 carries = (u32) uu.s.high << bm;
52 else 51 w.s.high = (u32) uu.s.high >> b;
53 { 52 w.s.low = ((u32) uu.s.low >> b) | carries;
54 USItype carries = (USItype)uu.s.high << bm; 53 }
55 w.s.high = (USItype)uu.s.high >> b; 54
56 w.s.low = ((USItype)uu.s.low >> b) | carries; 55 return w.ll;
57 }
58
59 return w.ll;
60} 56}
61
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
index 44d611b1cfdb..0a3b93313f18 100644
--- a/arch/arm/lib/muldi3.c
+++ b/arch/arm/lib/muldi3.c
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34#define umul_ppmm(xh, xl, a, b) \ 34#define umul_ppmm(xh, xl, a, b) \
35{register USItype __t0, __t1, __t2; \ 35{register u32 __t0, __t1, __t2; \
36 __asm__ ("%@ Inlined umul_ppmm \n\ 36 __asm__ ("%@ Inlined umul_ppmm \n\
37 mov %2, %5, lsr #16 \n\ 37 mov %2, %5, lsr #16 \n\
38 mov %0, %6, lsr #16 \n\ 38 mov %0, %6, lsr #16 \n\
@@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA. */
46 addcs %0, %0, #65536 \n\ 46 addcs %0, %0, #65536 \n\
47 adds %1, %1, %3, lsl #16 \n\ 47 adds %1, %1, %3, lsl #16 \n\
48 adc %0, %0, %3, lsr #16" \ 48 adc %0, %0, %3, lsr #16" \
49 : "=&r" ((USItype) (xh)), \ 49 : "=&r" ((u32) (xh)), \
50 "=r" ((USItype) (xl)), \ 50 "=r" ((u32) (xl)), \
51 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 51 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
52 : "r" ((USItype) (a)), \ 52 : "r" ((u32) (a)), \
53 "r" ((USItype) (b)));} 53 "r" ((u32) (b)));}
54
55 54
56#define __umulsidi3(u, v) \ 55#define __umulsidi3(u, v) \
57 ({DIunion __w; \ 56 ({DIunion __w; \
58 umul_ppmm (__w.s.high, __w.s.low, u, v); \ 57 umul_ppmm (__w.s.high, __w.s.low, u, v); \
59 __w.ll; }) 58 __w.ll; })
60 59
61 60s64 __muldi3(s64 u, s64 v)
62DItype
63__muldi3 (DItype u, DItype v)
64{ 61{
65 DIunion w; 62 DIunion w;
66 DIunion uu, vv; 63 DIunion uu, vv;
67 64
68 uu.ll = u, 65 uu.ll = u, vv.ll = v;
69 vv.ll = v;
70 66
71 w.ll = __umulsidi3 (uu.s.low, vv.s.low); 67 w.ll = __umulsidi3(uu.s.low, vv.s.low);
72 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 68 w.s.high += ((u32) uu.s.low * (u32) vv.s.high
73 + (USItype) uu.s.high * (USItype) vv.s.low); 69 + (u32) uu.s.high * (u32) vv.s.low);
74 70
75 return w.ll; 71 return w.ll;
76} 72}
77
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
index 6c6ae63efa02..57f3f2df3850 100644
--- a/arch/arm/lib/ucmpdi2.c
+++ b/arch/arm/lib/ucmpdi2.c
@@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34word_type 34int __ucmpdi2(s64 a, s64 b)
35__ucmpdi2 (DItype a, DItype b)
36{ 35{
37 DIunion au, bu; 36 DIunion au, bu;
38 37
39 au.ll = a, bu.ll = b; 38 au.ll = a, bu.ll = b;
40 39
41 if ((USItype) au.s.high < (USItype) bu.s.high) 40 if ((u32) au.s.high < (u32) bu.s.high)
42 return 0; 41 return 0;
43 else if ((USItype) au.s.high > (USItype) bu.s.high) 42 else if ((u32) au.s.high > (u32) bu.s.high)
44 return 2; 43 return 2;
45 if ((USItype) au.s.low < (USItype) bu.s.low) 44 if ((u32) au.s.low < (u32) bu.s.low)
46 return 0; 45 return 0;
47 else if ((USItype) au.s.low > (USItype) bu.s.low) 46 else if ((u32) au.s.low > (u32) bu.s.low)
48 return 2; 47 return 2;
49 return 1; 48 return 1;
50} 49}
51
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
index d25195f673f4..e343be4c6642 100644
--- a/arch/arm/lib/udivdi3.c
+++ b/arch/arm/lib/udivdi3.c
@@ -32,211 +32,191 @@ Boston, MA 02111-1307, USA. */
32#include "gcclib.h" 32#include "gcclib.h"
33#include "longlong.h" 33#include "longlong.h"
34 34
35static const UQItype __clz_tab[] = 35static const u8 __clz_tab[] = {
36{ 36 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
37 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, 37 5, 5, 5, 5, 5, 5, 5, 5,
38 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, 38 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
39 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, 39 6, 6, 6, 6, 6, 6, 6, 6,
40 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, 40 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
41 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, 41 7, 7, 7, 7, 7, 7, 7, 7,
42 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, 42 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
43 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, 43 7, 7, 7, 7, 7, 7, 7, 7,
44 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, 44 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
45 8, 8, 8, 8, 8, 8, 8, 8,
46 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
47 8, 8, 8, 8, 8, 8, 8, 8,
48 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
49 8, 8, 8, 8, 8, 8, 8, 8,
50 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
51 8, 8, 8, 8, 8, 8, 8, 8,
45}; 52};
46 53
47UDItype 54u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
48__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
49{ 55{
50 DIunion ww; 56 DIunion ww;
51 DIunion nn, dd; 57 DIunion nn, dd;
52 DIunion rr; 58 DIunion rr;
53 USItype d0, d1, n0, n1, n2; 59 u32 d0, d1, n0, n1, n2;
54 USItype q0, q1; 60 u32 q0, q1;
55 USItype b, bm; 61 u32 b, bm;
56 62
57 nn.ll = n; 63 nn.ll = n;
58 dd.ll = d; 64 dd.ll = d;
59 65
60 d0 = dd.s.low; 66 d0 = dd.s.low;
61 d1 = dd.s.high; 67 d1 = dd.s.high;
62 n0 = nn.s.low; 68 n0 = nn.s.low;
63 n1 = nn.s.high; 69 n1 = nn.s.high;
64 70
65 if (d1 == 0) 71 if (d1 == 0) {
66 { 72 if (d0 > n1) {
67 if (d0 > n1) 73 /* 0q = nn / 0D */
68 { 74
69 /* 0q = nn / 0D */ 75 count_leading_zeros(bm, d0);
70 76
71 count_leading_zeros (bm, d0); 77 if (bm != 0) {
72 78 /* Normalize, i.e. make the most significant bit of the
73 if (bm != 0) 79 denominator set. */
74 { 80
75 /* Normalize, i.e. make the most significant bit of the 81 d0 = d0 << bm;
76 denominator set. */ 82 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
77 83 n0 = n0 << bm;
78 d0 = d0 << bm; 84 }
79 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); 85
80 n0 = n0 << bm; 86 udiv_qrnnd(q0, n0, n1, n0, d0);
81 } 87 q1 = 0;
82 88
83 udiv_qrnnd (q0, n0, n1, n0, d0); 89 /* Remainder in n0 >> bm. */
84 q1 = 0; 90 } else {
85 91 /* qq = NN / 0d */
86 /* Remainder in n0 >> bm. */ 92
87 } 93 if (d0 == 0)
88 else 94 d0 = 1 / d0; /* Divide intentionally by zero. */
89 { 95
90 /* qq = NN / 0d */ 96 count_leading_zeros(bm, d0);
91 97
92 if (d0 == 0) 98 if (bm == 0) {
93 d0 = 1 / d0; /* Divide intentionally by zero. */ 99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
94 100 conclude (the most significant bit of n1 is set) /\ (the
95 count_leading_zeros (bm, d0); 101 leading quotient digit q1 = 1).
96 102
97 if (bm == 0) 103 This special case is necessary, not an optimization.
98 { 104 (Shifts counts of SI_TYPE_SIZE are undefined.) */
99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 105
100 conclude (the most significant bit of n1 is set) /\ (the 106 n1 -= d0;
101 leading quotient digit q1 = 1). 107 q1 = 1;
102 108 } else {
103 This special case is necessary, not an optimization. 109 /* Normalize. */
104 (Shifts counts of SI_TYPE_SIZE are undefined.) */ 110
105 111 b = SI_TYPE_SIZE - bm;
106 n1 -= d0; 112
107 q1 = 1; 113 d0 = d0 << bm;
108 } 114 n2 = n1 >> b;
109 else 115 n1 = (n1 << bm) | (n0 >> b);
110 { 116 n0 = n0 << bm;
111 /* Normalize. */ 117
112 118 udiv_qrnnd(q1, n1, n2, n1, d0);
113 b = SI_TYPE_SIZE - bm; 119 }
114 120
115 d0 = d0 << bm; 121 /* n1 != d0... */
116 n2 = n1 >> b; 122
117 n1 = (n1 << bm) | (n0 >> b); 123 udiv_qrnnd(q0, n0, n1, n0, d0);
118 n0 = n0 << bm; 124
119 125 /* Remainder in n0 >> bm. */
120 udiv_qrnnd (q1, n1, n2, n1, d0); 126 }
121 } 127
122 128 if (rp != 0) {
123 /* n1 != d0... */ 129 rr.s.low = n0 >> bm;
124 130 rr.s.high = 0;
125 udiv_qrnnd (q0, n0, n1, n0, d0); 131 *rp = rr.ll;
126 132 }
127 /* Remainder in n0 >> bm. */ 133 } else {
128 } 134 if (d1 > n1) {
129 135 /* 00 = nn / DD */
130 if (rp != 0) 136
131 { 137 q0 = 0;
132 rr.s.low = n0 >> bm; 138 q1 = 0;
133 rr.s.high = 0; 139
134 *rp = rr.ll; 140 /* Remainder in n1n0. */
135 } 141 if (rp != 0) {
136 } 142 rr.s.low = n0;
137 else 143 rr.s.high = n1;
138 { 144 *rp = rr.ll;
139 if (d1 > n1) 145 }
140 { 146 } else {
141 /* 00 = nn / DD */ 147 /* 0q = NN / dd */
142 148
143 q0 = 0; 149 count_leading_zeros(bm, d1);
144 q1 = 0; 150 if (bm == 0) {
145 151 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
146 /* Remainder in n1n0. */ 152 conclude (the most significant bit of n1 is set) /\ (the
147 if (rp != 0) 153 quotient digit q0 = 0 or 1).
148 { 154
149 rr.s.low = n0; 155 This special case is necessary, not an optimization. */
150 rr.s.high = n1; 156
151 *rp = rr.ll; 157 /* The condition on the next line takes advantage of that
152 } 158 n1 >= d1 (true due to program flow). */
153 } 159 if (n1 > d1 || n0 >= d0) {
154 else 160 q0 = 1;
155 { 161 sub_ddmmss(n1, n0, n1, n0, d1, d0);
156 /* 0q = NN / dd */ 162 } else
157 163 q0 = 0;
158 count_leading_zeros (bm, d1); 164
159 if (bm == 0) 165 q1 = 0;
160 { 166
161 /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 167 if (rp != 0) {
162 conclude (the most significant bit of n1 is set) /\ (the 168 rr.s.low = n0;
163 quotient digit q0 = 0 or 1). 169 rr.s.high = n1;
164 170 *rp = rr.ll;
165 This special case is necessary, not an optimization. */ 171 }
166 172 } else {
167 /* The condition on the next line takes advantage of that 173 u32 m1, m0;
168 n1 >= d1 (true due to program flow). */ 174 /* Normalize. */
169 if (n1 > d1 || n0 >= d0) 175
170 { 176 b = SI_TYPE_SIZE - bm;
171 q0 = 1; 177
172 sub_ddmmss (n1, n0, n1, n0, d1, d0); 178 d1 = (d1 << bm) | (d0 >> b);
173 } 179 d0 = d0 << bm;
174 else 180 n2 = n1 >> b;
175 q0 = 0; 181 n1 = (n1 << bm) | (n0 >> b);
176 182 n0 = n0 << bm;
177 q1 = 0; 183
178 184 udiv_qrnnd(q0, n1, n2, n1, d1);
179 if (rp != 0) 185 umul_ppmm(m1, m0, q0, d0);
180 { 186
181 rr.s.low = n0; 187 if (m1 > n1 || (m1 == n1 && m0 > n0)) {
182 rr.s.high = n1; 188 q0--;
183 *rp = rr.ll; 189 sub_ddmmss(m1, m0, m1, m0, d1, d0);
184 } 190 }
185 } 191
186 else 192 q1 = 0;
187 { 193
188 USItype m1, m0; 194 /* Remainder in (n1n0 - m1m0) >> bm. */
189 /* Normalize. */ 195 if (rp != 0) {
190 196 sub_ddmmss(n1, n0, n1, n0, m1, m0);
191 b = SI_TYPE_SIZE - bm; 197 rr.s.low = (n1 << b) | (n0 >> bm);
192 198 rr.s.high = n1 >> bm;
193 d1 = (d1 << bm) | (d0 >> b); 199 *rp = rr.ll;
194 d0 = d0 << bm; 200 }
195 n2 = n1 >> b; 201 }
196 n1 = (n1 << bm) | (n0 >> b); 202 }
197 n0 = n0 << bm; 203 }
198 204
199 udiv_qrnnd (q0, n1, n2, n1, d1); 205 ww.s.low = q0;
200 umul_ppmm (m1, m0, q0, d0); 206 ww.s.high = q1;
201 207 return ww.ll;
202 if (m1 > n1 || (m1 == n1 && m0 > n0))
203 {
204 q0--;
205 sub_ddmmss (m1, m0, m1, m0, d1, d0);
206 }
207
208 q1 = 0;
209
210 /* Remainder in (n1n0 - m1m0) >> bm. */
211 if (rp != 0)
212 {
213 sub_ddmmss (n1, n0, n1, n0, m1, m0);
214 rr.s.low = (n1 << b) | (n0 >> bm);
215 rr.s.high = n1 >> bm;
216 *rp = rr.ll;
217 }
218 }
219 }
220 }
221
222 ww.s.low = q0;
223 ww.s.high = q1;
224 return ww.ll;
225} 208}
226 209
227UDItype 210u64 __udivdi3(u64 n, u64 d)
228__udivdi3 (UDItype n, UDItype d)
229{ 211{
230 return __udivmoddi4 (n, d, (UDItype *) 0); 212 return __udivmoddi4(n, d, (u64 *) 0);
231} 213}
232 214
233UDItype 215u64 __umoddi3(u64 u, u64 v)
234__umoddi3 (UDItype u, UDItype v)
235{ 216{
236 UDItype w; 217 u64 w;
237 218
238 (void) __udivmoddi4 (u ,v, &w); 219 (void)__udivmoddi4(u, v, &w);
239 220
240 return w; 221 return w;
241} 222}
242