diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/math-emu/udivmodti4.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/ppc/math-emu/udivmodti4.c')
-rw-r--r-- | arch/ppc/math-emu/udivmodti4.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/arch/ppc/math-emu/udivmodti4.c b/arch/ppc/math-emu/udivmodti4.c new file mode 100644 index 000000000000..7e112dc1e2f2 --- /dev/null +++ b/arch/ppc/math-emu/udivmodti4.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */ | ||
2 | |||
3 | #include "soft-fp.h" | ||
4 | |||
5 | #undef count_leading_zeros | ||
6 | #define count_leading_zeros __FP_CLZ | ||
7 | |||
8 | void | ||
9 | _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2], | ||
10 | _FP_W_TYPE n1, _FP_W_TYPE n0, | ||
11 | _FP_W_TYPE d1, _FP_W_TYPE d0) | ||
12 | { | ||
13 | _FP_W_TYPE q0, q1, r0, r1; | ||
14 | _FP_I_TYPE b, bm; | ||
15 | |||
16 | if (d1 == 0) | ||
17 | { | ||
18 | #if !UDIV_NEEDS_NORMALIZATION | ||
19 | if (d0 > n1) | ||
20 | { | ||
21 | /* 0q = nn / 0D */ | ||
22 | |||
23 | udiv_qrnnd (q0, n0, n1, n0, d0); | ||
24 | q1 = 0; | ||
25 | |||
26 | /* Remainder in n0. */ | ||
27 | } | ||
28 | else | ||
29 | { | ||
30 | /* qq = NN / 0d */ | ||
31 | |||
32 | if (d0 == 0) | ||
33 | d0 = 1 / d0; /* Divide intentionally by zero. */ | ||
34 | |||
35 | udiv_qrnnd (q1, n1, 0, n1, d0); | ||
36 | udiv_qrnnd (q0, n0, n1, n0, d0); | ||
37 | |||
38 | /* Remainder in n0. */ | ||
39 | } | ||
40 | |||
41 | r0 = n0; | ||
42 | r1 = 0; | ||
43 | |||
44 | #else /* UDIV_NEEDS_NORMALIZATION */ | ||
45 | |||
46 | if (d0 > n1) | ||
47 | { | ||
48 | /* 0q = nn / 0D */ | ||
49 | |||
50 | count_leading_zeros (bm, d0); | ||
51 | |||
52 | if (bm != 0) | ||
53 | { | ||
54 | /* Normalize, i.e. make the most significant bit of the | ||
55 | denominator set. */ | ||
56 | |||
57 | d0 = d0 << bm; | ||
58 | n1 = (n1 << bm) | (n0 >> (_FP_W_TYPE_SIZE - bm)); | ||
59 | n0 = n0 << bm; | ||
60 | } | ||
61 | |||
62 | udiv_qrnnd (q0, n0, n1, n0, d0); | ||
63 | q1 = 0; | ||
64 | |||
65 | /* Remainder in n0 >> bm. */ | ||
66 | } | ||
67 | else | ||
68 | { | ||
69 | /* qq = NN / 0d */ | ||
70 | |||
71 | if (d0 == 0) | ||
72 | d0 = 1 / d0; /* Divide intentionally by zero. */ | ||
73 | |||
74 | count_leading_zeros (bm, d0); | ||
75 | |||
76 | if (bm == 0) | ||
77 | { | ||
78 | /* From (n1 >= d0) /\ (the most significant bit of d0 is set), | ||
79 | conclude (the most significant bit of n1 is set) /\ (the | ||
80 | leading quotient digit q1 = 1). | ||
81 | |||
82 | This special case is necessary, not an optimization. | ||
83 | (Shifts counts of SI_TYPE_SIZE are undefined.) */ | ||
84 | |||
85 | n1 -= d0; | ||
86 | q1 = 1; | ||
87 | } | ||
88 | else | ||
89 | { | ||
90 | _FP_W_TYPE n2; | ||
91 | |||
92 | /* Normalize. */ | ||
93 | |||
94 | b = _FP_W_TYPE_SIZE - bm; | ||
95 | |||
96 | d0 = d0 << bm; | ||
97 | n2 = n1 >> b; | ||
98 | n1 = (n1 << bm) | (n0 >> b); | ||
99 | n0 = n0 << bm; | ||
100 | |||
101 | udiv_qrnnd (q1, n1, n2, n1, d0); | ||
102 | } | ||
103 | |||
104 | /* n1 != d0... */ | ||
105 | |||
106 | udiv_qrnnd (q0, n0, n1, n0, d0); | ||
107 | |||
108 | /* Remainder in n0 >> bm. */ | ||
109 | } | ||
110 | |||
111 | r0 = n0 >> bm; | ||
112 | r1 = 0; | ||
113 | #endif /* UDIV_NEEDS_NORMALIZATION */ | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | if (d1 > n1) | ||
118 | { | ||
119 | /* 00 = nn / DD */ | ||
120 | |||
121 | q0 = 0; | ||
122 | q1 = 0; | ||
123 | |||
124 | /* Remainder in n1n0. */ | ||
125 | r0 = n0; | ||
126 | r1 = n1; | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | /* 0q = NN / dd */ | ||
131 | |||
132 | count_leading_zeros (bm, d1); | ||
133 | if (bm == 0) | ||
134 | { | ||
135 | /* From (n1 >= d1) /\ (the most significant bit of d1 is set), | ||
136 | conclude (the most significant bit of n1 is set) /\ (the | ||
137 | quotient digit q0 = 0 or 1). | ||
138 | |||
139 | This special case is necessary, not an optimization. */ | ||
140 | |||
141 | /* The condition on the next line takes advantage of that | ||
142 | n1 >= d1 (true due to program flow). */ | ||
143 | if (n1 > d1 || n0 >= d0) | ||
144 | { | ||
145 | q0 = 1; | ||
146 | sub_ddmmss (n1, n0, n1, n0, d1, d0); | ||
147 | } | ||
148 | else | ||
149 | q0 = 0; | ||
150 | |||
151 | q1 = 0; | ||
152 | |||
153 | r0 = n0; | ||
154 | r1 = n1; | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | _FP_W_TYPE m1, m0, n2; | ||
159 | |||
160 | /* Normalize. */ | ||
161 | |||
162 | b = _FP_W_TYPE_SIZE - bm; | ||
163 | |||
164 | d1 = (d1 << bm) | (d0 >> b); | ||
165 | d0 = d0 << bm; | ||
166 | n2 = n1 >> b; | ||
167 | n1 = (n1 << bm) | (n0 >> b); | ||
168 | n0 = n0 << bm; | ||
169 | |||
170 | udiv_qrnnd (q0, n1, n2, n1, d1); | ||
171 | umul_ppmm (m1, m0, q0, d0); | ||
172 | |||
173 | if (m1 > n1 || (m1 == n1 && m0 > n0)) | ||
174 | { | ||
175 | q0--; | ||
176 | sub_ddmmss (m1, m0, m1, m0, d1, d0); | ||
177 | } | ||
178 | |||
179 | q1 = 0; | ||
180 | |||
181 | /* Remainder in (n1n0 - m1m0) >> bm. */ | ||
182 | sub_ddmmss (n1, n0, n1, n0, m1, m0); | ||
183 | r0 = (n1 << b) | (n0 >> bm); | ||
184 | r1 = n1 >> bm; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | |||
189 | q[0] = q0; q[1] = q1; | ||
190 | r[0] = r0, r[1] = r1; | ||
191 | } | ||