1 #ifndef MPFQ_FIXMP_LONGLONG_H_
2 #define MPFQ_FIXMP_LONGLONG_H_
3 
4 /* MPFQ generated file -- do not edit */
5 
6 #include <gmp.h>
7 #include <limits.h>
8 #ifdef	MPFQ_LAST_GENERATED_TAG
9 #undef	MPFQ_LAST_GENERATED_TAG
10 #endif
11 #define MPFQ_LAST_GENERATED_TAG      fixmp
12 
13 /* Options used:{ features={  }, tag=fixmp, w=0, } */
14 
15 
16 #ifdef  __cplusplus
17 extern "C" {
18 #endif
19 static inline
20 mp_limb_t mpfq_fixmp_1_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
21 static inline
22 mp_limb_t mpfq_fixmp_1_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
23 static inline
24 void mpfq_fixmp_1_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
25 static inline
26 void mpfq_fixmp_1_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
27 static inline
28 mp_limb_t mpfq_fixmp_1_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
29 static inline
30 mp_limb_t mpfq_fixmp_1_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
31 static inline
32 void mpfq_fixmp_1_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
33 static inline
34 void mpfq_fixmp_1_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
35 static inline
36 int mpfq_fixmp_1_cmp(const mp_limb_t *, const mp_limb_t *);
37 static inline
38 int mpfq_fixmp_1_cmp_ui(const mp_limb_t *, mp_limb_t);
39 static inline
40 mp_limb_t mpfq_fixmp_1_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
41 static inline
42 void mpfq_fixmp_1_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
43 static inline
44 mp_limb_t mpfq_fixmp_1_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
45 static inline
46 void mpfq_fixmp_1_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
47 static inline
48 void mpfq_fixmp_1_sqr(mp_limb_t *, const mp_limb_t *);
49 static inline
50 void mpfq_fixmp_1_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
51 static inline
52 void mpfq_fixmp_1_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
53 static inline
54 void mpfq_fixmp_1_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
55 static inline
56 int mpfq_fixmp_1_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
57 static inline
58 void mpfq_fixmp_1_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
59 static inline
60 void mpfq_fixmp_1_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
61 static inline
62 void mpfq_fixmp_1_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
63 static inline
64 void mpfq_fixmp_1_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
65 static inline
66 void mpfq_fixmp_1_lshift(mp_limb_t *, int);
67 static inline
68 void mpfq_fixmp_1_rshift(mp_limb_t *, int);
69 static inline
70 void mpfq_fixmp_1_long_lshift(mp_limb_t *, int, int);
71 static inline
72 void mpfq_fixmp_1_long_rshift(mp_limb_t *, int, int);
73 static inline
74 mp_limb_t mpfq_fixmp_2_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
75 static inline
76 mp_limb_t mpfq_fixmp_2_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
77 static inline
78 void mpfq_fixmp_2_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
79 static inline
80 void mpfq_fixmp_2_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
81 static inline
82 mp_limb_t mpfq_fixmp_2_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
83 static inline
84 mp_limb_t mpfq_fixmp_2_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
85 static inline
86 void mpfq_fixmp_2_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
87 static inline
88 void mpfq_fixmp_2_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
89 static inline
90 int mpfq_fixmp_2_cmp(const mp_limb_t *, const mp_limb_t *);
91 static inline
92 int mpfq_fixmp_2_cmp_ui(const mp_limb_t *, mp_limb_t);
93 static inline
94 mp_limb_t mpfq_fixmp_2_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
95 static inline
96 void mpfq_fixmp_2_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
97 static inline
98 mp_limb_t mpfq_fixmp_2_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
99 static inline
100 void mpfq_fixmp_2_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
101 static inline
102 void mpfq_fixmp_2_sqr(mp_limb_t *, const mp_limb_t *);
103 static inline
104 void mpfq_fixmp_2_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
105 static inline
106 void mpfq_fixmp_2_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
107 static inline
108 void mpfq_fixmp_2_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
109 static inline
110 void mpfq_fixmp_2_rshift(mp_limb_t *, int);
111 static inline
112 void mpfq_fixmp_2_long_rshift(mp_limb_t *, int, int);
113 static inline
114 void mpfq_fixmp_2_long_lshift(mp_limb_t *, int, int);
115 static inline
116 int mpfq_fixmp_2_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
117 static inline
118 void mpfq_fixmp_2_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
119 static inline
120 void mpfq_fixmp_2_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
121 static inline
122 void mpfq_fixmp_2_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
123 static inline
124 void mpfq_fixmp_2_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
125 static inline
126 void mpfq_fixmp_2_lshift(mp_limb_t *, int);
127 static inline
128 mp_limb_t mpfq_fixmp_3_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
129 static inline
130 mp_limb_t mpfq_fixmp_3_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
131 static inline
132 void mpfq_fixmp_3_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
133 static inline
134 void mpfq_fixmp_3_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
135 static inline
136 mp_limb_t mpfq_fixmp_3_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
137 static inline
138 mp_limb_t mpfq_fixmp_3_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
139 static inline
140 void mpfq_fixmp_3_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
141 static inline
142 void mpfq_fixmp_3_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
143 static inline
144 int mpfq_fixmp_3_cmp(const mp_limb_t *, const mp_limb_t *);
145 static inline
146 int mpfq_fixmp_3_cmp_ui(const mp_limb_t *, mp_limb_t);
147 static inline
148 mp_limb_t mpfq_fixmp_3_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
149 static inline
150 void mpfq_fixmp_3_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
151 static inline
152 mp_limb_t mpfq_fixmp_3_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
153 static inline
154 void mpfq_fixmp_3_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
155 static inline
156 void mpfq_fixmp_3_sqr(mp_limb_t *, const mp_limb_t *);
157 static inline
158 void mpfq_fixmp_3_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
159 static inline
160 void mpfq_fixmp_3_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
161 static inline
162 void mpfq_fixmp_3_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
163 static inline
164 void mpfq_fixmp_3_rshift(mp_limb_t *, int);
165 static inline
166 void mpfq_fixmp_3_long_rshift(mp_limb_t *, int, int);
167 static inline
168 void mpfq_fixmp_3_long_lshift(mp_limb_t *, int, int);
169 static inline
170 int mpfq_fixmp_3_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
171 static inline
172 void mpfq_fixmp_3_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
173 static inline
174 void mpfq_fixmp_3_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
175 static inline
176 void mpfq_fixmp_3_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
177 static inline
178 void mpfq_fixmp_3_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
179 static inline
180 void mpfq_fixmp_3_lshift(mp_limb_t *, int);
181 static inline
182 mp_limb_t mpfq_fixmp_4_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
183 static inline
184 mp_limb_t mpfq_fixmp_4_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
185 static inline
186 void mpfq_fixmp_4_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
187 static inline
188 void mpfq_fixmp_4_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
189 static inline
190 mp_limb_t mpfq_fixmp_4_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
191 static inline
192 mp_limb_t mpfq_fixmp_4_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
193 static inline
194 void mpfq_fixmp_4_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
195 static inline
196 void mpfq_fixmp_4_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
197 static inline
198 int mpfq_fixmp_4_cmp(const mp_limb_t *, const mp_limb_t *);
199 static inline
200 int mpfq_fixmp_4_cmp_ui(const mp_limb_t *, mp_limb_t);
201 static inline
202 mp_limb_t mpfq_fixmp_4_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
203 static inline
204 void mpfq_fixmp_4_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
205 static inline
206 mp_limb_t mpfq_fixmp_4_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
207 static inline
208 void mpfq_fixmp_4_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
209 static inline
210 void mpfq_fixmp_4_sqr(mp_limb_t *, const mp_limb_t *);
211 static inline
212 void mpfq_fixmp_4_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
213 static inline
214 void mpfq_fixmp_4_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
215 static inline
216 void mpfq_fixmp_4_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
217 static inline
218 void mpfq_fixmp_4_rshift(mp_limb_t *, int);
219 static inline
220 void mpfq_fixmp_4_long_rshift(mp_limb_t *, int, int);
221 static inline
222 void mpfq_fixmp_4_long_lshift(mp_limb_t *, int, int);
223 static inline
224 int mpfq_fixmp_4_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
225 static inline
226 void mpfq_fixmp_4_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
227 static inline
228 void mpfq_fixmp_4_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
229 static inline
230 void mpfq_fixmp_4_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
231 static inline
232 void mpfq_fixmp_4_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
233 static inline
234 void mpfq_fixmp_4_lshift(mp_limb_t *, int);
235 static inline
236 mp_limb_t mpfq_fixmp_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
237 static inline
238 mp_limb_t mpfq_fixmp_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
239 static inline
240 void mpfq_fixmp_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
241 static inline
242 void mpfq_fixmp_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
243 static inline
244 mp_limb_t mpfq_fixmp_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
245 static inline
246 mp_limb_t mpfq_fixmp_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
247 static inline
248 void mpfq_fixmp_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
249 static inline
250 void mpfq_fixmp_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
251 static inline
252 int mpfq_fixmp_5_cmp(const mp_limb_t *, const mp_limb_t *);
253 static inline
254 int mpfq_fixmp_5_cmp_ui(const mp_limb_t *, mp_limb_t);
255 static inline
256 mp_limb_t mpfq_fixmp_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
257 static inline
258 void mpfq_fixmp_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
259 static inline
260 mp_limb_t mpfq_fixmp_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
261 static inline
262 void mpfq_fixmp_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
263 static inline
264 void mpfq_fixmp_5_sqr(mp_limb_t *, const mp_limb_t *);
265 static inline
266 void mpfq_fixmp_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
267 static inline
268 void mpfq_fixmp_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
269 static inline
270 void mpfq_fixmp_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
271 static inline
272 void mpfq_fixmp_5_rshift(mp_limb_t *, int);
273 static inline
274 void mpfq_fixmp_5_long_rshift(mp_limb_t *, int, int);
275 static inline
276 void mpfq_fixmp_5_long_lshift(mp_limb_t *, int, int);
277 static inline
278 int mpfq_fixmp_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
279 static inline
280 void mpfq_fixmp_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
281 static inline
282 void mpfq_fixmp_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
283 static inline
284 void mpfq_fixmp_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
285 static inline
286 void mpfq_fixmp_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
287 static inline
288 void mpfq_fixmp_5_lshift(mp_limb_t *, int);
289 static inline
290 mp_limb_t mpfq_fixmp_6_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
291 static inline
292 mp_limb_t mpfq_fixmp_6_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
293 static inline
294 void mpfq_fixmp_6_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
295 static inline
296 void mpfq_fixmp_6_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
297 static inline
298 mp_limb_t mpfq_fixmp_6_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
299 static inline
300 mp_limb_t mpfq_fixmp_6_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
301 static inline
302 void mpfq_fixmp_6_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
303 static inline
304 void mpfq_fixmp_6_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
305 static inline
306 int mpfq_fixmp_6_cmp(const mp_limb_t *, const mp_limb_t *);
307 static inline
308 int mpfq_fixmp_6_cmp_ui(const mp_limb_t *, mp_limb_t);
309 static inline
310 mp_limb_t mpfq_fixmp_6_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
311 static inline
312 void mpfq_fixmp_6_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
313 static inline
314 mp_limb_t mpfq_fixmp_6_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
315 static inline
316 void mpfq_fixmp_6_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
317 static inline
318 void mpfq_fixmp_6_sqr(mp_limb_t *, const mp_limb_t *);
319 static inline
320 void mpfq_fixmp_6_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
321 static inline
322 void mpfq_fixmp_6_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
323 static inline
324 void mpfq_fixmp_6_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
325 static inline
326 void mpfq_fixmp_6_rshift(mp_limb_t *, int);
327 static inline
328 void mpfq_fixmp_6_long_rshift(mp_limb_t *, int, int);
329 static inline
330 void mpfq_fixmp_6_long_lshift(mp_limb_t *, int, int);
331 static inline
332 int mpfq_fixmp_6_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
333 static inline
334 void mpfq_fixmp_6_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
335 static inline
336 void mpfq_fixmp_6_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
337 static inline
338 void mpfq_fixmp_6_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
339 static inline
340 void mpfq_fixmp_6_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
341 static inline
342 void mpfq_fixmp_6_lshift(mp_limb_t *, int);
343 static inline
344 mp_limb_t mpfq_fixmp_7_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
345 static inline
346 mp_limb_t mpfq_fixmp_7_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
347 static inline
348 void mpfq_fixmp_7_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
349 static inline
350 void mpfq_fixmp_7_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
351 static inline
352 mp_limb_t mpfq_fixmp_7_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
353 static inline
354 mp_limb_t mpfq_fixmp_7_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
355 static inline
356 void mpfq_fixmp_7_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
357 static inline
358 void mpfq_fixmp_7_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
359 static inline
360 int mpfq_fixmp_7_cmp(const mp_limb_t *, const mp_limb_t *);
361 static inline
362 int mpfq_fixmp_7_cmp_ui(const mp_limb_t *, mp_limb_t);
363 static inline
364 mp_limb_t mpfq_fixmp_7_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
365 static inline
366 void mpfq_fixmp_7_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
367 static inline
368 mp_limb_t mpfq_fixmp_7_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
369 static inline
370 void mpfq_fixmp_7_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
371 static inline
372 void mpfq_fixmp_7_sqr(mp_limb_t *, const mp_limb_t *);
373 static inline
374 void mpfq_fixmp_7_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
375 static inline
376 void mpfq_fixmp_7_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
377 static inline
378 void mpfq_fixmp_7_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
379 static inline
380 void mpfq_fixmp_7_rshift(mp_limb_t *, int);
381 static inline
382 void mpfq_fixmp_7_long_rshift(mp_limb_t *, int, int);
383 static inline
384 void mpfq_fixmp_7_long_lshift(mp_limb_t *, int, int);
385 static inline
386 int mpfq_fixmp_7_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
387 static inline
388 void mpfq_fixmp_7_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
389 static inline
390 void mpfq_fixmp_7_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
391 static inline
392 void mpfq_fixmp_7_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
393 static inline
394 void mpfq_fixmp_7_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
395 static inline
396 void mpfq_fixmp_7_lshift(mp_limb_t *, int);
397 static inline
398 mp_limb_t mpfq_fixmp_8_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
399 static inline
400 mp_limb_t mpfq_fixmp_8_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
401 static inline
402 void mpfq_fixmp_8_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
403 static inline
404 void mpfq_fixmp_8_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
405 static inline
406 mp_limb_t mpfq_fixmp_8_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
407 static inline
408 mp_limb_t mpfq_fixmp_8_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
409 static inline
410 void mpfq_fixmp_8_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
411 static inline
412 void mpfq_fixmp_8_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
413 static inline
414 int mpfq_fixmp_8_cmp(const mp_limb_t *, const mp_limb_t *);
415 static inline
416 int mpfq_fixmp_8_cmp_ui(const mp_limb_t *, mp_limb_t);
417 static inline
418 mp_limb_t mpfq_fixmp_8_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
419 static inline
420 void mpfq_fixmp_8_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
421 static inline
422 mp_limb_t mpfq_fixmp_8_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
423 static inline
424 void mpfq_fixmp_8_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
425 static inline
426 void mpfq_fixmp_8_sqr(mp_limb_t *, const mp_limb_t *);
427 static inline
428 void mpfq_fixmp_8_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
429 static inline
430 void mpfq_fixmp_8_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
431 static inline
432 void mpfq_fixmp_8_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
433 static inline
434 void mpfq_fixmp_8_rshift(mp_limb_t *, int);
435 static inline
436 void mpfq_fixmp_8_long_rshift(mp_limb_t *, int, int);
437 static inline
438 void mpfq_fixmp_8_long_lshift(mp_limb_t *, int, int);
439 static inline
440 int mpfq_fixmp_8_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
441 static inline
442 void mpfq_fixmp_8_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
443 static inline
444 void mpfq_fixmp_8_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
445 static inline
446 void mpfq_fixmp_8_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
447 static inline
448 void mpfq_fixmp_8_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
449 static inline
450 void mpfq_fixmp_8_lshift(mp_limb_t *, int);
451 static inline
452 mp_limb_t mpfq_fixmp_9_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
453 static inline
454 mp_limb_t mpfq_fixmp_9_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
455 static inline
456 void mpfq_fixmp_9_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
457 static inline
458 void mpfq_fixmp_9_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
459 static inline
460 mp_limb_t mpfq_fixmp_9_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
461 static inline
462 mp_limb_t mpfq_fixmp_9_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
463 static inline
464 void mpfq_fixmp_9_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
465 static inline
466 void mpfq_fixmp_9_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
467 static inline
468 int mpfq_fixmp_9_cmp(const mp_limb_t *, const mp_limb_t *);
469 static inline
470 int mpfq_fixmp_9_cmp_ui(const mp_limb_t *, mp_limb_t);
471 static inline
472 mp_limb_t mpfq_fixmp_9_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
473 static inline
474 void mpfq_fixmp_9_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
475 static inline
476 mp_limb_t mpfq_fixmp_9_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
477 static inline
478 void mpfq_fixmp_9_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
479 static inline
480 void mpfq_fixmp_9_sqr(mp_limb_t *, const mp_limb_t *);
481 static inline
482 void mpfq_fixmp_9_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
483 static inline
484 void mpfq_fixmp_9_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
485 static inline
486 void mpfq_fixmp_9_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
487 static inline
488 void mpfq_fixmp_9_rshift(mp_limb_t *, int);
489 static inline
490 void mpfq_fixmp_9_long_rshift(mp_limb_t *, int, int);
491 static inline
492 void mpfq_fixmp_9_long_lshift(mp_limb_t *, int, int);
493 static inline
494 int mpfq_fixmp_9_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
495 static inline
496 void mpfq_fixmp_9_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
497 static inline
498 void mpfq_fixmp_9_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
499 static inline
500 void mpfq_fixmp_9_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
501 static inline
502 void mpfq_fixmp_9_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
503 static inline
504 void mpfq_fixmp_9_lshift(mp_limb_t *, int);
505 static inline
506 mp_limb_t mpfq_fixmp_10_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
507 static inline
508 mp_limb_t mpfq_fixmp_10_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
509 static inline
510 void mpfq_fixmp_10_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
511 static inline
512 void mpfq_fixmp_10_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
513 static inline
514 mp_limb_t mpfq_fixmp_10_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
515 static inline
516 mp_limb_t mpfq_fixmp_10_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
517 static inline
518 void mpfq_fixmp_10_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
519 static inline
520 void mpfq_fixmp_10_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
521 static inline
522 int mpfq_fixmp_10_cmp(const mp_limb_t *, const mp_limb_t *);
523 static inline
524 int mpfq_fixmp_10_cmp_ui(const mp_limb_t *, mp_limb_t);
525 static inline
526 mp_limb_t mpfq_fixmp_10_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
527 static inline
528 void mpfq_fixmp_10_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
529 static inline
530 mp_limb_t mpfq_fixmp_10_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
531 static inline
532 void mpfq_fixmp_10_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
533 static inline
534 void mpfq_fixmp_10_sqr(mp_limb_t *, const mp_limb_t *);
535 static inline
536 void mpfq_fixmp_10_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
537 static inline
538 void mpfq_fixmp_10_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
539 static inline
540 void mpfq_fixmp_10_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
541 static inline
542 void mpfq_fixmp_10_rshift(mp_limb_t *, int);
543 static inline
544 void mpfq_fixmp_10_long_rshift(mp_limb_t *, int, int);
545 static inline
546 void mpfq_fixmp_10_long_lshift(mp_limb_t *, int, int);
547 static inline
548 int mpfq_fixmp_10_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
549 static inline
550 void mpfq_fixmp_10_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
551 static inline
552 void mpfq_fixmp_10_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
553 static inline
554 void mpfq_fixmp_10_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
555 static inline
556 void mpfq_fixmp_10_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
557 static inline
558 void mpfq_fixmp_10_lshift(mp_limb_t *, int);
559 static inline
560 mp_limb_t mpfq_fixmp_11_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
561 static inline
562 mp_limb_t mpfq_fixmp_11_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
563 static inline
564 void mpfq_fixmp_11_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
565 static inline
566 void mpfq_fixmp_11_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
567 static inline
568 mp_limb_t mpfq_fixmp_11_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
569 static inline
570 mp_limb_t mpfq_fixmp_11_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
571 static inline
572 void mpfq_fixmp_11_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
573 static inline
574 void mpfq_fixmp_11_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
575 static inline
576 int mpfq_fixmp_11_cmp(const mp_limb_t *, const mp_limb_t *);
577 static inline
578 int mpfq_fixmp_11_cmp_ui(const mp_limb_t *, mp_limb_t);
579 static inline
580 mp_limb_t mpfq_fixmp_11_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
581 static inline
582 void mpfq_fixmp_11_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
583 static inline
584 mp_limb_t mpfq_fixmp_11_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
585 static inline
586 void mpfq_fixmp_11_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
587 static inline
588 void mpfq_fixmp_11_sqr(mp_limb_t *, const mp_limb_t *);
589 static inline
590 void mpfq_fixmp_11_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
591 static inline
592 void mpfq_fixmp_11_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
593 static inline
594 void mpfq_fixmp_11_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
595 static inline
596 void mpfq_fixmp_11_rshift(mp_limb_t *, int);
597 static inline
598 void mpfq_fixmp_11_long_rshift(mp_limb_t *, int, int);
599 static inline
600 void mpfq_fixmp_11_long_lshift(mp_limb_t *, int, int);
601 static inline
602 int mpfq_fixmp_11_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
603 static inline
604 void mpfq_fixmp_11_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
605 static inline
606 void mpfq_fixmp_11_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
607 static inline
608 void mpfq_fixmp_11_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
609 static inline
610 void mpfq_fixmp_11_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
611 static inline
612 void mpfq_fixmp_11_lshift(mp_limb_t *, int);
613 static inline
614 mp_limb_t mpfq_fixmp_12_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
615 static inline
616 mp_limb_t mpfq_fixmp_12_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
617 static inline
618 void mpfq_fixmp_12_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
619 static inline
620 void mpfq_fixmp_12_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
621 static inline
622 mp_limb_t mpfq_fixmp_12_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
623 static inline
624 mp_limb_t mpfq_fixmp_12_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
625 static inline
626 void mpfq_fixmp_12_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
627 static inline
628 void mpfq_fixmp_12_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
629 static inline
630 int mpfq_fixmp_12_cmp(const mp_limb_t *, const mp_limb_t *);
631 static inline
632 int mpfq_fixmp_12_cmp_ui(const mp_limb_t *, mp_limb_t);
633 static inline
634 mp_limb_t mpfq_fixmp_12_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
635 static inline
636 void mpfq_fixmp_12_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
637 static inline
638 mp_limb_t mpfq_fixmp_12_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
639 static inline
640 void mpfq_fixmp_12_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
641 static inline
642 void mpfq_fixmp_12_sqr(mp_limb_t *, const mp_limb_t *);
643 static inline
644 void mpfq_fixmp_12_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
645 static inline
646 void mpfq_fixmp_12_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
647 static inline
648 void mpfq_fixmp_12_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
649 static inline
650 void mpfq_fixmp_12_rshift(mp_limb_t *, int);
651 static inline
652 void mpfq_fixmp_12_long_rshift(mp_limb_t *, int, int);
653 static inline
654 void mpfq_fixmp_12_long_lshift(mp_limb_t *, int, int);
655 static inline
656 int mpfq_fixmp_12_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
657 static inline
658 void mpfq_fixmp_12_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
659 static inline
660 void mpfq_fixmp_12_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
661 static inline
662 void mpfq_fixmp_12_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
663 static inline
664 void mpfq_fixmp_12_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
665 static inline
666 void mpfq_fixmp_12_lshift(mp_limb_t *, int);
667 static inline
668 mp_limb_t mpfq_fixmp_13_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
669 static inline
670 mp_limb_t mpfq_fixmp_13_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
671 static inline
672 void mpfq_fixmp_13_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
673 static inline
674 void mpfq_fixmp_13_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
675 static inline
676 mp_limb_t mpfq_fixmp_13_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
677 static inline
678 mp_limb_t mpfq_fixmp_13_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
679 static inline
680 void mpfq_fixmp_13_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
681 static inline
682 void mpfq_fixmp_13_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
683 static inline
684 int mpfq_fixmp_13_cmp(const mp_limb_t *, const mp_limb_t *);
685 static inline
686 int mpfq_fixmp_13_cmp_ui(const mp_limb_t *, mp_limb_t);
687 static inline
688 mp_limb_t mpfq_fixmp_13_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
689 static inline
690 void mpfq_fixmp_13_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
691 static inline
692 mp_limb_t mpfq_fixmp_13_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
693 static inline
694 void mpfq_fixmp_13_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
695 static inline
696 void mpfq_fixmp_13_sqr(mp_limb_t *, const mp_limb_t *);
697 static inline
698 void mpfq_fixmp_13_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
699 static inline
700 void mpfq_fixmp_13_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
701 static inline
702 void mpfq_fixmp_13_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
703 static inline
704 void mpfq_fixmp_13_rshift(mp_limb_t *, int);
705 static inline
706 void mpfq_fixmp_13_long_rshift(mp_limb_t *, int, int);
707 static inline
708 void mpfq_fixmp_13_long_lshift(mp_limb_t *, int, int);
709 static inline
710 int mpfq_fixmp_13_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
711 static inline
712 void mpfq_fixmp_13_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
713 static inline
714 void mpfq_fixmp_13_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
715 static inline
716 void mpfq_fixmp_13_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
717 static inline
718 void mpfq_fixmp_13_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
719 static inline
720 void mpfq_fixmp_13_lshift(mp_limb_t *, int);
721 static inline
722 mp_limb_t mpfq_fixmp_14_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
723 static inline
724 mp_limb_t mpfq_fixmp_14_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
725 static inline
726 void mpfq_fixmp_14_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
727 static inline
728 void mpfq_fixmp_14_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
729 static inline
730 mp_limb_t mpfq_fixmp_14_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
731 static inline
732 mp_limb_t mpfq_fixmp_14_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
733 static inline
734 void mpfq_fixmp_14_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
735 static inline
736 void mpfq_fixmp_14_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
737 static inline
738 int mpfq_fixmp_14_cmp(const mp_limb_t *, const mp_limb_t *);
739 static inline
740 int mpfq_fixmp_14_cmp_ui(const mp_limb_t *, mp_limb_t);
741 static inline
742 mp_limb_t mpfq_fixmp_14_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
743 static inline
744 void mpfq_fixmp_14_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
745 static inline
746 mp_limb_t mpfq_fixmp_14_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
747 static inline
748 void mpfq_fixmp_14_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
749 static inline
750 void mpfq_fixmp_14_sqr(mp_limb_t *, const mp_limb_t *);
751 static inline
752 void mpfq_fixmp_14_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
753 static inline
754 void mpfq_fixmp_14_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
755 static inline
756 void mpfq_fixmp_14_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
757 static inline
758 void mpfq_fixmp_14_rshift(mp_limb_t *, int);
759 static inline
760 void mpfq_fixmp_14_long_rshift(mp_limb_t *, int, int);
761 static inline
762 void mpfq_fixmp_14_long_lshift(mp_limb_t *, int, int);
763 static inline
764 int mpfq_fixmp_14_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
765 static inline
766 void mpfq_fixmp_14_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
767 static inline
768 void mpfq_fixmp_14_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
769 static inline
770 void mpfq_fixmp_14_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
771 static inline
772 void mpfq_fixmp_14_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
773 static inline
774 void mpfq_fixmp_14_lshift(mp_limb_t *, int);
775 static inline
776 mp_limb_t mpfq_fixmp_15_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
777 static inline
778 mp_limb_t mpfq_fixmp_15_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
779 static inline
780 void mpfq_fixmp_15_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
781 static inline
782 void mpfq_fixmp_15_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
783 static inline
784 mp_limb_t mpfq_fixmp_15_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
785 static inline
786 mp_limb_t mpfq_fixmp_15_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
787 static inline
788 void mpfq_fixmp_15_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
789 static inline
790 void mpfq_fixmp_15_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
791 static inline
792 int mpfq_fixmp_15_cmp(const mp_limb_t *, const mp_limb_t *);
793 static inline
794 int mpfq_fixmp_15_cmp_ui(const mp_limb_t *, mp_limb_t);
795 static inline
796 mp_limb_t mpfq_fixmp_15_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
797 static inline
798 void mpfq_fixmp_15_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
799 static inline
800 mp_limb_t mpfq_fixmp_15_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
801 static inline
802 void mpfq_fixmp_15_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
803 static inline
804 void mpfq_fixmp_15_sqr(mp_limb_t *, const mp_limb_t *);
805 static inline
806 void mpfq_fixmp_15_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
807 static inline
808 void mpfq_fixmp_15_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
809 static inline
810 void mpfq_fixmp_15_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
811 static inline
812 void mpfq_fixmp_15_rshift(mp_limb_t *, int);
813 static inline
814 void mpfq_fixmp_15_long_rshift(mp_limb_t *, int, int);
815 static inline
816 void mpfq_fixmp_15_long_lshift(mp_limb_t *, int, int);
817 static inline
818 int mpfq_fixmp_15_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
819 static inline
820 void mpfq_fixmp_15_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
821 static inline
822 void mpfq_fixmp_15_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
823 static inline
824 void mpfq_fixmp_15_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
825 static inline
826 void mpfq_fixmp_15_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
827 static inline
828 void mpfq_fixmp_15_lshift(mp_limb_t *, int);
829 static inline
830 mp_limb_t mpfq_fixmp_0_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
831 static inline
832 mp_limb_t mpfq_fixmp_0_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
833 static inline
834 void mpfq_fixmp_0_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
835 static inline
836 void mpfq_fixmp_0_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
837 static inline
838 mp_limb_t mpfq_fixmp_0_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
839 static inline
840 mp_limb_t mpfq_fixmp_0_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
841 static inline
842 void mpfq_fixmp_0_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
843 static inline
844 void mpfq_fixmp_0_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
845 static inline
846 int mpfq_fixmp_0_5_cmp(const mp_limb_t *, const mp_limb_t *);
847 static inline
848 int mpfq_fixmp_0_5_cmp_ui(const mp_limb_t *, mp_limb_t);
849 static inline
850 mp_limb_t mpfq_fixmp_0_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
851 static inline
852 void mpfq_fixmp_0_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
853 static inline
854 mp_limb_t mpfq_fixmp_0_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
855 static inline
856 void mpfq_fixmp_0_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
857 static inline
858 void mpfq_fixmp_0_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
859 static inline
860 void mpfq_fixmp_0_5_sqr(mp_limb_t *, const mp_limb_t *);
861 static inline
862 void mpfq_fixmp_0_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
863 static inline
864 void mpfq_fixmp_0_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
865 static inline
866 mp_limb_t mpfq_fixmp_0_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
867 static inline
868 void mpfq_fixmp_0_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
869 static inline
870 void mpfq_fixmp_0_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
871 static inline
872 int mpfq_fixmp_0_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
873 static inline
874 void mpfq_fixmp_0_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
875 static inline
876 void mpfq_fixmp_0_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
877 static inline
878 void mpfq_fixmp_0_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
879 static inline
880 void mpfq_fixmp_0_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
881 static inline
882 void mpfq_fixmp_0_5_lshift(mp_limb_t *, int);
883 static inline
884 void mpfq_fixmp_0_5_rshift(mp_limb_t *, int);
885 static inline
886 void mpfq_fixmp_0_5_long_lshift(mp_limb_t *, int, int);
887 static inline
888 void mpfq_fixmp_0_5_long_rshift(mp_limb_t *, int, int);
889 static inline
890 mp_limb_t mpfq_fixmp_1_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
891 static inline
892 mp_limb_t mpfq_fixmp_1_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
893 static inline
894 void mpfq_fixmp_1_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
895 static inline
896 void mpfq_fixmp_1_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
897 static inline
898 mp_limb_t mpfq_fixmp_1_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
899 static inline
900 mp_limb_t mpfq_fixmp_1_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
901 static inline
902 void mpfq_fixmp_1_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
903 static inline
904 void mpfq_fixmp_1_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
905 static inline
906 int mpfq_fixmp_1_5_cmp(const mp_limb_t *, const mp_limb_t *);
907 static inline
908 int mpfq_fixmp_1_5_cmp_ui(const mp_limb_t *, mp_limb_t);
909 static inline
910 mp_limb_t mpfq_fixmp_1_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
911 static inline
912 void mpfq_fixmp_1_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
913 static inline
914 mp_limb_t mpfq_fixmp_1_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
915 static inline
916 void mpfq_fixmp_1_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
917 static inline
918 void mpfq_fixmp_1_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
919 static inline
920 void mpfq_fixmp_1_5_sqr(mp_limb_t *, const mp_limb_t *);
921 static inline
922 void mpfq_fixmp_1_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
923 static inline
924 void mpfq_fixmp_1_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
925 static inline
926 mp_limb_t mpfq_fixmp_1_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
927 static inline
928 void mpfq_fixmp_1_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
929 static inline
930 void mpfq_fixmp_1_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
931 static inline
932 void mpfq_fixmp_1_5_rshift(mp_limb_t *, int);
933 static inline
934 void mpfq_fixmp_1_5_long_rshift(mp_limb_t *, int, int);
935 static inline
936 void mpfq_fixmp_1_5_long_lshift(mp_limb_t *, int, int);
937 static inline
938 int mpfq_fixmp_1_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
939 static inline
940 void mpfq_fixmp_1_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
941 static inline
942 void mpfq_fixmp_1_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
943 static inline
944 void mpfq_fixmp_1_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
945 static inline
946 void mpfq_fixmp_1_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
947 static inline
948 void mpfq_fixmp_1_5_lshift(mp_limb_t *, int);
949 static inline
950 mp_limb_t mpfq_fixmp_2_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
951 static inline
952 mp_limb_t mpfq_fixmp_2_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
953 static inline
954 void mpfq_fixmp_2_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
955 static inline
956 void mpfq_fixmp_2_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
957 static inline
958 mp_limb_t mpfq_fixmp_2_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
959 static inline
960 mp_limb_t mpfq_fixmp_2_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
961 static inline
962 void mpfq_fixmp_2_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
963 static inline
964 void mpfq_fixmp_2_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
965 static inline
966 int mpfq_fixmp_2_5_cmp(const mp_limb_t *, const mp_limb_t *);
967 static inline
968 int mpfq_fixmp_2_5_cmp_ui(const mp_limb_t *, mp_limb_t);
969 static inline
970 mp_limb_t mpfq_fixmp_2_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
971 static inline
972 void mpfq_fixmp_2_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
973 static inline
974 mp_limb_t mpfq_fixmp_2_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
975 static inline
976 void mpfq_fixmp_2_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
977 static inline
978 void mpfq_fixmp_2_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
979 static inline
980 void mpfq_fixmp_2_5_sqr(mp_limb_t *, const mp_limb_t *);
981 static inline
982 void mpfq_fixmp_2_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
983 static inline
984 void mpfq_fixmp_2_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
985 static inline
986 mp_limb_t mpfq_fixmp_2_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
987 static inline
988 void mpfq_fixmp_2_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
989 static inline
990 void mpfq_fixmp_2_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
991 static inline
992 void mpfq_fixmp_2_5_rshift(mp_limb_t *, int);
993 static inline
994 void mpfq_fixmp_2_5_long_rshift(mp_limb_t *, int, int);
995 static inline
996 void mpfq_fixmp_2_5_long_lshift(mp_limb_t *, int, int);
997 static inline
998 int mpfq_fixmp_2_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
999 static inline
1000 void mpfq_fixmp_2_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1001 static inline
1002 void mpfq_fixmp_2_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1003 static inline
1004 void mpfq_fixmp_2_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1005 static inline
1006 void mpfq_fixmp_2_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1007 static inline
1008 void mpfq_fixmp_2_5_lshift(mp_limb_t *, int);
1009 static inline
1010 mp_limb_t mpfq_fixmp_3_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1011 static inline
1012 mp_limb_t mpfq_fixmp_3_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1013 static inline
1014 void mpfq_fixmp_3_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1015 static inline
1016 void mpfq_fixmp_3_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1017 static inline
1018 mp_limb_t mpfq_fixmp_3_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1019 static inline
1020 mp_limb_t mpfq_fixmp_3_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1021 static inline
1022 void mpfq_fixmp_3_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1023 static inline
1024 void mpfq_fixmp_3_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1025 static inline
1026 int mpfq_fixmp_3_5_cmp(const mp_limb_t *, const mp_limb_t *);
1027 static inline
1028 int mpfq_fixmp_3_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1029 static inline
1030 mp_limb_t mpfq_fixmp_3_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1031 static inline
1032 void mpfq_fixmp_3_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1033 static inline
1034 mp_limb_t mpfq_fixmp_3_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1035 static inline
1036 void mpfq_fixmp_3_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1037 static inline
1038 void mpfq_fixmp_3_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1039 static inline
1040 void mpfq_fixmp_3_5_sqr(mp_limb_t *, const mp_limb_t *);
1041 static inline
1042 void mpfq_fixmp_3_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1043 static inline
1044 void mpfq_fixmp_3_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1045 static inline
1046 mp_limb_t mpfq_fixmp_3_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1047 static inline
1048 void mpfq_fixmp_3_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1049 static inline
1050 void mpfq_fixmp_3_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1051 static inline
1052 void mpfq_fixmp_3_5_rshift(mp_limb_t *, int);
1053 static inline
1054 void mpfq_fixmp_3_5_long_rshift(mp_limb_t *, int, int);
1055 static inline
1056 void mpfq_fixmp_3_5_long_lshift(mp_limb_t *, int, int);
1057 static inline
1058 int mpfq_fixmp_3_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1059 static inline
1060 void mpfq_fixmp_3_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1061 static inline
1062 void mpfq_fixmp_3_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1063 static inline
1064 void mpfq_fixmp_3_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1065 static inline
1066 void mpfq_fixmp_3_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1067 static inline
1068 void mpfq_fixmp_3_5_lshift(mp_limb_t *, int);
1069 static inline
1070 mp_limb_t mpfq_fixmp_4_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1071 static inline
1072 mp_limb_t mpfq_fixmp_4_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1073 static inline
1074 void mpfq_fixmp_4_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1075 static inline
1076 void mpfq_fixmp_4_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1077 static inline
1078 mp_limb_t mpfq_fixmp_4_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1079 static inline
1080 mp_limb_t mpfq_fixmp_4_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1081 static inline
1082 void mpfq_fixmp_4_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1083 static inline
1084 void mpfq_fixmp_4_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1085 static inline
1086 int mpfq_fixmp_4_5_cmp(const mp_limb_t *, const mp_limb_t *);
1087 static inline
1088 int mpfq_fixmp_4_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1089 static inline
1090 mp_limb_t mpfq_fixmp_4_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1091 static inline
1092 void mpfq_fixmp_4_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1093 static inline
1094 mp_limb_t mpfq_fixmp_4_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1095 static inline
1096 void mpfq_fixmp_4_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1097 static inline
1098 void mpfq_fixmp_4_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1099 static inline
1100 void mpfq_fixmp_4_5_sqr(mp_limb_t *, const mp_limb_t *);
1101 static inline
1102 void mpfq_fixmp_4_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1103 static inline
1104 void mpfq_fixmp_4_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1105 static inline
1106 mp_limb_t mpfq_fixmp_4_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1107 static inline
1108 void mpfq_fixmp_4_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1109 static inline
1110 void mpfq_fixmp_4_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1111 static inline
1112 void mpfq_fixmp_4_5_rshift(mp_limb_t *, int);
1113 static inline
1114 void mpfq_fixmp_4_5_long_rshift(mp_limb_t *, int, int);
1115 static inline
1116 void mpfq_fixmp_4_5_long_lshift(mp_limb_t *, int, int);
1117 static inline
1118 int mpfq_fixmp_4_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1119 static inline
1120 void mpfq_fixmp_4_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1121 static inline
1122 void mpfq_fixmp_4_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1123 static inline
1124 void mpfq_fixmp_4_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1125 static inline
1126 void mpfq_fixmp_4_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1127 static inline
1128 void mpfq_fixmp_4_5_lshift(mp_limb_t *, int);
1129 static inline
1130 mp_limb_t mpfq_fixmp_5_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1131 static inline
1132 mp_limb_t mpfq_fixmp_5_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1133 static inline
1134 void mpfq_fixmp_5_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1135 static inline
1136 void mpfq_fixmp_5_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1137 static inline
1138 mp_limb_t mpfq_fixmp_5_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1139 static inline
1140 mp_limb_t mpfq_fixmp_5_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1141 static inline
1142 void mpfq_fixmp_5_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1143 static inline
1144 void mpfq_fixmp_5_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1145 static inline
1146 int mpfq_fixmp_5_5_cmp(const mp_limb_t *, const mp_limb_t *);
1147 static inline
1148 int mpfq_fixmp_5_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1149 static inline
1150 mp_limb_t mpfq_fixmp_5_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1151 static inline
1152 void mpfq_fixmp_5_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1153 static inline
1154 mp_limb_t mpfq_fixmp_5_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1155 static inline
1156 void mpfq_fixmp_5_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1157 static inline
1158 void mpfq_fixmp_5_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1159 static inline
1160 void mpfq_fixmp_5_5_sqr(mp_limb_t *, const mp_limb_t *);
1161 static inline
1162 void mpfq_fixmp_5_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1163 static inline
1164 void mpfq_fixmp_5_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1165 static inline
1166 mp_limb_t mpfq_fixmp_5_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1167 static inline
1168 void mpfq_fixmp_5_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1169 static inline
1170 void mpfq_fixmp_5_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1171 static inline
1172 void mpfq_fixmp_5_5_rshift(mp_limb_t *, int);
1173 static inline
1174 void mpfq_fixmp_5_5_long_rshift(mp_limb_t *, int, int);
1175 static inline
1176 void mpfq_fixmp_5_5_long_lshift(mp_limb_t *, int, int);
1177 static inline
1178 int mpfq_fixmp_5_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1179 static inline
1180 void mpfq_fixmp_5_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1181 static inline
1182 void mpfq_fixmp_5_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1183 static inline
1184 void mpfq_fixmp_5_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1185 static inline
1186 void mpfq_fixmp_5_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1187 static inline
1188 void mpfq_fixmp_5_5_lshift(mp_limb_t *, int);
1189 static inline
1190 mp_limb_t mpfq_fixmp_6_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1191 static inline
1192 mp_limb_t mpfq_fixmp_6_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1193 static inline
1194 void mpfq_fixmp_6_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1195 static inline
1196 void mpfq_fixmp_6_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1197 static inline
1198 mp_limb_t mpfq_fixmp_6_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1199 static inline
1200 mp_limb_t mpfq_fixmp_6_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1201 static inline
1202 void mpfq_fixmp_6_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1203 static inline
1204 void mpfq_fixmp_6_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1205 static inline
1206 int mpfq_fixmp_6_5_cmp(const mp_limb_t *, const mp_limb_t *);
1207 static inline
1208 int mpfq_fixmp_6_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1209 static inline
1210 mp_limb_t mpfq_fixmp_6_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1211 static inline
1212 void mpfq_fixmp_6_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1213 static inline
1214 mp_limb_t mpfq_fixmp_6_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1215 static inline
1216 void mpfq_fixmp_6_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1217 static inline
1218 void mpfq_fixmp_6_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1219 static inline
1220 void mpfq_fixmp_6_5_sqr(mp_limb_t *, const mp_limb_t *);
1221 static inline
1222 void mpfq_fixmp_6_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1223 static inline
1224 void mpfq_fixmp_6_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1225 static inline
1226 mp_limb_t mpfq_fixmp_6_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1227 static inline
1228 void mpfq_fixmp_6_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1229 static inline
1230 void mpfq_fixmp_6_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1231 static inline
1232 void mpfq_fixmp_6_5_rshift(mp_limb_t *, int);
1233 static inline
1234 void mpfq_fixmp_6_5_long_rshift(mp_limb_t *, int, int);
1235 static inline
1236 void mpfq_fixmp_6_5_long_lshift(mp_limb_t *, int, int);
1237 static inline
1238 int mpfq_fixmp_6_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1239 static inline
1240 void mpfq_fixmp_6_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1241 static inline
1242 void mpfq_fixmp_6_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1243 static inline
1244 void mpfq_fixmp_6_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1245 static inline
1246 void mpfq_fixmp_6_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1247 static inline
1248 void mpfq_fixmp_6_5_lshift(mp_limb_t *, int);
1249 static inline
1250 mp_limb_t mpfq_fixmp_7_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1251 static inline
1252 mp_limb_t mpfq_fixmp_7_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1253 static inline
1254 void mpfq_fixmp_7_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1255 static inline
1256 void mpfq_fixmp_7_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1257 static inline
1258 mp_limb_t mpfq_fixmp_7_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1259 static inline
1260 mp_limb_t mpfq_fixmp_7_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1261 static inline
1262 void mpfq_fixmp_7_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1263 static inline
1264 void mpfq_fixmp_7_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1265 static inline
1266 int mpfq_fixmp_7_5_cmp(const mp_limb_t *, const mp_limb_t *);
1267 static inline
1268 int mpfq_fixmp_7_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1269 static inline
1270 mp_limb_t mpfq_fixmp_7_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1271 static inline
1272 void mpfq_fixmp_7_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1273 static inline
1274 mp_limb_t mpfq_fixmp_7_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1275 static inline
1276 void mpfq_fixmp_7_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1277 static inline
1278 void mpfq_fixmp_7_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1279 static inline
1280 void mpfq_fixmp_7_5_sqr(mp_limb_t *, const mp_limb_t *);
1281 static inline
1282 void mpfq_fixmp_7_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1283 static inline
1284 void mpfq_fixmp_7_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1285 static inline
1286 mp_limb_t mpfq_fixmp_7_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1287 static inline
1288 void mpfq_fixmp_7_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1289 static inline
1290 void mpfq_fixmp_7_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1291 static inline
1292 void mpfq_fixmp_7_5_rshift(mp_limb_t *, int);
1293 static inline
1294 void mpfq_fixmp_7_5_long_rshift(mp_limb_t *, int, int);
1295 static inline
1296 void mpfq_fixmp_7_5_long_lshift(mp_limb_t *, int, int);
1297 static inline
1298 int mpfq_fixmp_7_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1299 static inline
1300 void mpfq_fixmp_7_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1301 static inline
1302 void mpfq_fixmp_7_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1303 static inline
1304 void mpfq_fixmp_7_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1305 static inline
1306 void mpfq_fixmp_7_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1307 static inline
1308 void mpfq_fixmp_7_5_lshift(mp_limb_t *, int);
1309 static inline
1310 mp_limb_t mpfq_fixmp_8_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1311 static inline
1312 mp_limb_t mpfq_fixmp_8_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1313 static inline
1314 void mpfq_fixmp_8_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1315 static inline
1316 void mpfq_fixmp_8_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1317 static inline
1318 mp_limb_t mpfq_fixmp_8_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1319 static inline
1320 mp_limb_t mpfq_fixmp_8_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1321 static inline
1322 void mpfq_fixmp_8_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1323 static inline
1324 void mpfq_fixmp_8_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1325 static inline
1326 int mpfq_fixmp_8_5_cmp(const mp_limb_t *, const mp_limb_t *);
1327 static inline
1328 int mpfq_fixmp_8_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1329 static inline
1330 mp_limb_t mpfq_fixmp_8_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1331 static inline
1332 void mpfq_fixmp_8_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1333 static inline
1334 mp_limb_t mpfq_fixmp_8_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1335 static inline
1336 void mpfq_fixmp_8_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1337 static inline
1338 void mpfq_fixmp_8_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1339 static inline
1340 void mpfq_fixmp_8_5_sqr(mp_limb_t *, const mp_limb_t *);
1341 static inline
1342 void mpfq_fixmp_8_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1343 static inline
1344 void mpfq_fixmp_8_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1345 static inline
1346 mp_limb_t mpfq_fixmp_8_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1347 static inline
1348 void mpfq_fixmp_8_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1349 static inline
1350 void mpfq_fixmp_8_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1351 static inline
1352 void mpfq_fixmp_8_5_rshift(mp_limb_t *, int);
1353 static inline
1354 void mpfq_fixmp_8_5_long_rshift(mp_limb_t *, int, int);
1355 static inline
1356 void mpfq_fixmp_8_5_long_lshift(mp_limb_t *, int, int);
1357 static inline
1358 int mpfq_fixmp_8_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1359 static inline
1360 void mpfq_fixmp_8_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1361 static inline
1362 void mpfq_fixmp_8_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1363 static inline
1364 void mpfq_fixmp_8_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1365 static inline
1366 void mpfq_fixmp_8_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1367 static inline
1368 void mpfq_fixmp_8_5_lshift(mp_limb_t *, int);
1369 static inline
1370 mp_limb_t mpfq_fixmp_9_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1371 static inline
1372 mp_limb_t mpfq_fixmp_9_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1373 static inline
1374 void mpfq_fixmp_9_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1375 static inline
1376 void mpfq_fixmp_9_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1377 static inline
1378 mp_limb_t mpfq_fixmp_9_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1379 static inline
1380 mp_limb_t mpfq_fixmp_9_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1381 static inline
1382 void mpfq_fixmp_9_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1383 static inline
1384 void mpfq_fixmp_9_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1385 static inline
1386 int mpfq_fixmp_9_5_cmp(const mp_limb_t *, const mp_limb_t *);
1387 static inline
1388 int mpfq_fixmp_9_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1389 static inline
1390 mp_limb_t mpfq_fixmp_9_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1391 static inline
1392 void mpfq_fixmp_9_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1393 static inline
1394 mp_limb_t mpfq_fixmp_9_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1395 static inline
1396 void mpfq_fixmp_9_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1397 static inline
1398 void mpfq_fixmp_9_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1399 static inline
1400 void mpfq_fixmp_9_5_sqr(mp_limb_t *, const mp_limb_t *);
1401 static inline
1402 void mpfq_fixmp_9_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1403 static inline
1404 void mpfq_fixmp_9_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1405 static inline
1406 mp_limb_t mpfq_fixmp_9_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1407 static inline
1408 void mpfq_fixmp_9_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1409 static inline
1410 void mpfq_fixmp_9_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1411 static inline
1412 void mpfq_fixmp_9_5_rshift(mp_limb_t *, int);
1413 static inline
1414 void mpfq_fixmp_9_5_long_rshift(mp_limb_t *, int, int);
1415 static inline
1416 void mpfq_fixmp_9_5_long_lshift(mp_limb_t *, int, int);
1417 static inline
1418 int mpfq_fixmp_9_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1419 static inline
1420 void mpfq_fixmp_9_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1421 static inline
1422 void mpfq_fixmp_9_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1423 static inline
1424 void mpfq_fixmp_9_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1425 static inline
1426 void mpfq_fixmp_9_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1427 static inline
1428 void mpfq_fixmp_9_5_lshift(mp_limb_t *, int);
1429 static inline
1430 mp_limb_t mpfq_fixmp_10_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1431 static inline
1432 mp_limb_t mpfq_fixmp_10_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1433 static inline
1434 void mpfq_fixmp_10_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1435 static inline
1436 void mpfq_fixmp_10_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1437 static inline
1438 mp_limb_t mpfq_fixmp_10_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1439 static inline
1440 mp_limb_t mpfq_fixmp_10_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1441 static inline
1442 void mpfq_fixmp_10_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1443 static inline
1444 void mpfq_fixmp_10_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1445 static inline
1446 int mpfq_fixmp_10_5_cmp(const mp_limb_t *, const mp_limb_t *);
1447 static inline
1448 int mpfq_fixmp_10_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1449 static inline
1450 mp_limb_t mpfq_fixmp_10_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1451 static inline
1452 void mpfq_fixmp_10_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1453 static inline
1454 mp_limb_t mpfq_fixmp_10_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1455 static inline
1456 void mpfq_fixmp_10_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1457 static inline
1458 void mpfq_fixmp_10_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1459 static inline
1460 void mpfq_fixmp_10_5_sqr(mp_limb_t *, const mp_limb_t *);
1461 static inline
1462 void mpfq_fixmp_10_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1463 static inline
1464 void mpfq_fixmp_10_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1465 static inline
1466 mp_limb_t mpfq_fixmp_10_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1467 static inline
1468 void mpfq_fixmp_10_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1469 static inline
1470 void mpfq_fixmp_10_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1471 static inline
1472 void mpfq_fixmp_10_5_rshift(mp_limb_t *, int);
1473 static inline
1474 void mpfq_fixmp_10_5_long_rshift(mp_limb_t *, int, int);
1475 static inline
1476 void mpfq_fixmp_10_5_long_lshift(mp_limb_t *, int, int);
1477 static inline
1478 int mpfq_fixmp_10_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1479 static inline
1480 void mpfq_fixmp_10_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1481 static inline
1482 void mpfq_fixmp_10_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1483 static inline
1484 void mpfq_fixmp_10_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1485 static inline
1486 void mpfq_fixmp_10_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1487 static inline
1488 void mpfq_fixmp_10_5_lshift(mp_limb_t *, int);
1489 static inline
1490 mp_limb_t mpfq_fixmp_11_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1491 static inline
1492 mp_limb_t mpfq_fixmp_11_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1493 static inline
1494 void mpfq_fixmp_11_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1495 static inline
1496 void mpfq_fixmp_11_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1497 static inline
1498 mp_limb_t mpfq_fixmp_11_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1499 static inline
1500 mp_limb_t mpfq_fixmp_11_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1501 static inline
1502 void mpfq_fixmp_11_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1503 static inline
1504 void mpfq_fixmp_11_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1505 static inline
1506 int mpfq_fixmp_11_5_cmp(const mp_limb_t *, const mp_limb_t *);
1507 static inline
1508 int mpfq_fixmp_11_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1509 static inline
1510 mp_limb_t mpfq_fixmp_11_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1511 static inline
1512 void mpfq_fixmp_11_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1513 static inline
1514 mp_limb_t mpfq_fixmp_11_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1515 static inline
1516 void mpfq_fixmp_11_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1517 static inline
1518 void mpfq_fixmp_11_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1519 static inline
1520 void mpfq_fixmp_11_5_sqr(mp_limb_t *, const mp_limb_t *);
1521 static inline
1522 void mpfq_fixmp_11_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1523 static inline
1524 void mpfq_fixmp_11_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1525 static inline
1526 mp_limb_t mpfq_fixmp_11_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1527 static inline
1528 void mpfq_fixmp_11_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1529 static inline
1530 void mpfq_fixmp_11_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1531 static inline
1532 void mpfq_fixmp_11_5_rshift(mp_limb_t *, int);
1533 static inline
1534 void mpfq_fixmp_11_5_long_rshift(mp_limb_t *, int, int);
1535 static inline
1536 void mpfq_fixmp_11_5_long_lshift(mp_limb_t *, int, int);
1537 static inline
1538 int mpfq_fixmp_11_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1539 static inline
1540 void mpfq_fixmp_11_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1541 static inline
1542 void mpfq_fixmp_11_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1543 static inline
1544 void mpfq_fixmp_11_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1545 static inline
1546 void mpfq_fixmp_11_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1547 static inline
1548 void mpfq_fixmp_11_5_lshift(mp_limb_t *, int);
1549 static inline
1550 mp_limb_t mpfq_fixmp_12_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1551 static inline
1552 mp_limb_t mpfq_fixmp_12_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1553 static inline
1554 void mpfq_fixmp_12_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1555 static inline
1556 void mpfq_fixmp_12_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1557 static inline
1558 mp_limb_t mpfq_fixmp_12_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1559 static inline
1560 mp_limb_t mpfq_fixmp_12_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1561 static inline
1562 void mpfq_fixmp_12_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1563 static inline
1564 void mpfq_fixmp_12_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1565 static inline
1566 int mpfq_fixmp_12_5_cmp(const mp_limb_t *, const mp_limb_t *);
1567 static inline
1568 int mpfq_fixmp_12_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1569 static inline
1570 mp_limb_t mpfq_fixmp_12_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1571 static inline
1572 void mpfq_fixmp_12_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1573 static inline
1574 mp_limb_t mpfq_fixmp_12_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1575 static inline
1576 void mpfq_fixmp_12_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1577 static inline
1578 void mpfq_fixmp_12_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1579 static inline
1580 void mpfq_fixmp_12_5_sqr(mp_limb_t *, const mp_limb_t *);
1581 static inline
1582 void mpfq_fixmp_12_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1583 static inline
1584 void mpfq_fixmp_12_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1585 static inline
1586 mp_limb_t mpfq_fixmp_12_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1587 static inline
1588 void mpfq_fixmp_12_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1589 static inline
1590 void mpfq_fixmp_12_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1591 static inline
1592 void mpfq_fixmp_12_5_rshift(mp_limb_t *, int);
1593 static inline
1594 void mpfq_fixmp_12_5_long_rshift(mp_limb_t *, int, int);
1595 static inline
1596 void mpfq_fixmp_12_5_long_lshift(mp_limb_t *, int, int);
1597 static inline
1598 int mpfq_fixmp_12_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1599 static inline
1600 void mpfq_fixmp_12_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1601 static inline
1602 void mpfq_fixmp_12_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1603 static inline
1604 void mpfq_fixmp_12_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1605 static inline
1606 void mpfq_fixmp_12_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1607 static inline
1608 void mpfq_fixmp_12_5_lshift(mp_limb_t *, int);
1609 static inline
1610 mp_limb_t mpfq_fixmp_13_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1611 static inline
1612 mp_limb_t mpfq_fixmp_13_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1613 static inline
1614 void mpfq_fixmp_13_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1615 static inline
1616 void mpfq_fixmp_13_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1617 static inline
1618 mp_limb_t mpfq_fixmp_13_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1619 static inline
1620 mp_limb_t mpfq_fixmp_13_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1621 static inline
1622 void mpfq_fixmp_13_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1623 static inline
1624 void mpfq_fixmp_13_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1625 static inline
1626 int mpfq_fixmp_13_5_cmp(const mp_limb_t *, const mp_limb_t *);
1627 static inline
1628 int mpfq_fixmp_13_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1629 static inline
1630 mp_limb_t mpfq_fixmp_13_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1631 static inline
1632 void mpfq_fixmp_13_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1633 static inline
1634 mp_limb_t mpfq_fixmp_13_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1635 static inline
1636 void mpfq_fixmp_13_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1637 static inline
1638 void mpfq_fixmp_13_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1639 static inline
1640 void mpfq_fixmp_13_5_sqr(mp_limb_t *, const mp_limb_t *);
1641 static inline
1642 void mpfq_fixmp_13_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1643 static inline
1644 void mpfq_fixmp_13_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1645 static inline
1646 mp_limb_t mpfq_fixmp_13_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1647 static inline
1648 void mpfq_fixmp_13_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1649 static inline
1650 void mpfq_fixmp_13_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1651 static inline
1652 void mpfq_fixmp_13_5_rshift(mp_limb_t *, int);
1653 static inline
1654 void mpfq_fixmp_13_5_long_rshift(mp_limb_t *, int, int);
1655 static inline
1656 void mpfq_fixmp_13_5_long_lshift(mp_limb_t *, int, int);
1657 static inline
1658 int mpfq_fixmp_13_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1659 static inline
1660 void mpfq_fixmp_13_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1661 static inline
1662 void mpfq_fixmp_13_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1663 static inline
1664 void mpfq_fixmp_13_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1665 static inline
1666 void mpfq_fixmp_13_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1667 static inline
1668 void mpfq_fixmp_13_5_lshift(mp_limb_t *, int);
1669 static inline
1670 mp_limb_t mpfq_fixmp_14_5_add(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1671 static inline
1672 mp_limb_t mpfq_fixmp_14_5_sub(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1673 static inline
1674 void mpfq_fixmp_14_5_add_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1675 static inline
1676 void mpfq_fixmp_14_5_sub_nc(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1677 static inline
1678 mp_limb_t mpfq_fixmp_14_5_add_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1679 static inline
1680 mp_limb_t mpfq_fixmp_14_5_sub_ui(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1681 static inline
1682 void mpfq_fixmp_14_5_add_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1683 static inline
1684 void mpfq_fixmp_14_5_sub_ui_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1685 static inline
1686 int mpfq_fixmp_14_5_cmp(const mp_limb_t *, const mp_limb_t *);
1687 static inline
1688 int mpfq_fixmp_14_5_cmp_ui(const mp_limb_t *, mp_limb_t);
1689 static inline
1690 mp_limb_t mpfq_fixmp_14_5_addmul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1691 static inline
1692 void mpfq_fixmp_14_5_addmul1_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1693 static inline
1694 mp_limb_t mpfq_fixmp_14_5_addmul1_shortz(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1695 static inline
1696 void mpfq_fixmp_14_5_addmul05_nc(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1697 static inline
1698 void mpfq_fixmp_14_5_mul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1699 static inline
1700 void mpfq_fixmp_14_5_sqr(mp_limb_t *, const mp_limb_t *);
1701 static inline
1702 void mpfq_fixmp_14_5_mul1(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1703 static inline
1704 void mpfq_fixmp_14_5_shortmul(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1705 static inline
1706 mp_limb_t mpfq_fixmp_14_5_addmul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1707 static inline
1708 void mpfq_fixmp_14_5_mul05(mp_limb_t *, const mp_limb_t *, mp_limb_t);
1709 static inline
1710 void mpfq_fixmp_14_5_mod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1711 static inline
1712 void mpfq_fixmp_14_5_rshift(mp_limb_t *, int);
1713 static inline
1714 void mpfq_fixmp_14_5_long_rshift(mp_limb_t *, int, int);
1715 static inline
1716 void mpfq_fixmp_14_5_long_lshift(mp_limb_t *, int, int);
1717 static inline
1718 int mpfq_fixmp_14_5_invmod(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1719 static inline
1720 void mpfq_fixmp_14_5_redc(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1721 static inline
1722 void mpfq_fixmp_14_5_redc_ur(mp_limb_t *, mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1723 static inline
1724 void mpfq_fixmp_14_5_mgy_encode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1725 static inline
1726 void mpfq_fixmp_14_5_mgy_decode(mp_limb_t *, const mp_limb_t *, const mp_limb_t *, const mp_limb_t *);
1727 static inline
1728 void mpfq_fixmp_14_5_lshift(mp_limb_t *, int);
1729 #ifdef  __cplusplus
1730 }
1731 #endif
1732 
1733 /* Implementations for inlines */
1734 #if !defined(HAVE_native_mpfq_fixmp_1_add)
1735 /* x, y, and z have 1 words. Result in z. Return carry bit */
1736 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
1737 /* Triggered by: 1_redc_ur */
1738 static inline
mpfq_fixmp_1_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)1739 mp_limb_t mpfq_fixmp_1_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
1740 {
1741     mp_limb_t r, s, t, cy, cy1, cy2;
1742     cy = 0;
1743     r = x[0];
1744     s = r + y[0];
1745     cy1 = s < r;
1746     t = s + cy;
1747     cy2 = t < s;
1748     cy = cy1 | cy2;
1749     z[0] = t;
1750     return cy;
1751 }
1752 #endif /* !defined(HAVE_native_mpfq_fixmp_1_add) */
1753 
1754 #if !defined(HAVE_native_mpfq_fixmp_1_sub)
1755 /* x, y, and z have 1 words. Result in z. Return borrow bit */
1756 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
1757 static inline
mpfq_fixmp_1_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)1758 mp_limb_t mpfq_fixmp_1_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
1759 {
1760     mp_limb_t r, s, t, cy, cy1, cy2;
1761     cy = 0;
1762     r = x[0];
1763     s = r - y[0];
1764     cy1 = s > r;
1765     t = s - cy;
1766     cy2 = t > s;
1767     cy = cy1 | cy2;
1768     z[0] = t;
1769     return cy;
1770 }
1771 #endif /* !defined(HAVE_native_mpfq_fixmp_1_sub) */
1772 
1773 #if !defined(HAVE_native_mpfq_fixmp_1_add_nc)
1774 /* x, y, and z have 1 words. Result in z. Carry bit is lost. */
1775 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
1776 static inline
mpfq_fixmp_1_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)1777 void mpfq_fixmp_1_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
1778 {
1779     mp_limb_t r, s, t, cy, cy1, cy2;
1780     cy = 0;
1781     r = x[0];
1782     s = r + y[0];
1783     cy1 = s < r;
1784     t = s + cy;
1785     cy2 = t < s;
1786     cy = cy1 | cy2;
1787     z[0] = t;
1788 }
1789 #endif /* !defined(HAVE_native_mpfq_fixmp_1_add_nc) */
1790 
1791 #if !defined(HAVE_native_mpfq_fixmp_1_sub_nc)
1792 /* x, y, and z have 1 words. Result in z. Borrow bit is lost. */
1793 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
1794 static inline
mpfq_fixmp_1_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)1795 void mpfq_fixmp_1_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
1796 {
1797     mp_limb_t r, s, t, cy, cy1, cy2;
1798     cy = 0;
1799     r = x[0];
1800     s = r - y[0];
1801     cy1 = s > r;
1802     t = s - cy;
1803     cy2 = t > s;
1804     cy = cy1 | cy2;
1805     z[0] = t;
1806 }
1807 #endif /* !defined(HAVE_native_mpfq_fixmp_1_sub_nc) */
1808 
1809 #if !defined(HAVE_native_mpfq_fixmp_1_add_ui)
1810 /* x, y, and z have 1 words. Result in z. Return carry bit */
1811 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
1812 static inline
mpfq_fixmp_1_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)1813 mp_limb_t mpfq_fixmp_1_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
1814 {
1815     mp_limb_t r, s, t, cy, cy1, cy2;
1816     cy = 0;
1817     r = x[0];
1818     s = r + y;
1819     cy1 = s < r;
1820     t = s + cy;
1821     cy2 = t < s;
1822     cy = cy1 | cy2;
1823     z[0] = t;
1824     return cy;
1825 }
1826 #endif /* !defined(HAVE_native_mpfq_fixmp_1_add_ui) */
1827 
1828 #if !defined(HAVE_native_mpfq_fixmp_1_sub_ui)
1829 /* x, y, and z have 1 words. Result in z. Return borrow bit */
1830 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
1831 static inline
mpfq_fixmp_1_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)1832 mp_limb_t mpfq_fixmp_1_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
1833 {
1834     mp_limb_t r, s, t, cy, cy1, cy2;
1835     cy = 0;
1836     r = x[0];
1837     s = r - y;
1838     cy1 = s > r;
1839     t = s - cy;
1840     cy2 = t > s;
1841     cy = cy1 | cy2;
1842     z[0] = t;
1843     return cy;
1844 }
1845 #endif /* !defined(HAVE_native_mpfq_fixmp_1_sub_ui) */
1846 
1847 #if !defined(HAVE_native_mpfq_fixmp_1_add_ui_nc)
1848 /* x, y, and z have 1 words. Result in z. Carry bit is lost. */
1849 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
1850 static inline
mpfq_fixmp_1_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)1851 void mpfq_fixmp_1_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
1852 {
1853     mp_limb_t r, s, t, cy, cy1, cy2;
1854     cy = 0;
1855     r = x[0];
1856     s = r + y;
1857     cy1 = s < r;
1858     t = s + cy;
1859     cy2 = t < s;
1860     cy = cy1 | cy2;
1861     z[0] = t;
1862 }
1863 #endif /* !defined(HAVE_native_mpfq_fixmp_1_add_ui_nc) */
1864 
1865 #if !defined(HAVE_native_mpfq_fixmp_1_sub_ui_nc)
1866 /* x, y, and z have 1 words. Result in z. Borrow bit is lost. */
1867 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
1868 static inline
mpfq_fixmp_1_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)1869 void mpfq_fixmp_1_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
1870 {
1871     mp_limb_t r, s, t, cy, cy1, cy2;
1872     cy = 0;
1873     r = x[0];
1874     s = r - y;
1875     cy1 = s > r;
1876     t = s - cy;
1877     cy2 = t > s;
1878     cy = cy1 | cy2;
1879     z[0] = t;
1880 }
1881 #endif /* !defined(HAVE_native_mpfq_fixmp_1_sub_ui_nc) */
1882 
1883 #if !defined(HAVE_native_mpfq_fixmp_1_cmp)
1884 /* x and y have 1 words. Return sign of difference x-y. */
1885 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
1886 static inline
mpfq_fixmp_1_cmp(const mp_limb_t * x,const mp_limb_t * y)1887 int mpfq_fixmp_1_cmp(const mp_limb_t * x, const mp_limb_t * y)
1888 {
1889     for (int i = 1-1; i >= 0; --i) {
1890         if (x[i] > y[i]) return 1;
1891         if (x[i] < y[i]) return -1;
1892     }
1893     return 0;
1894 }
1895 #endif /* !defined(HAVE_native_mpfq_fixmp_1_cmp) */
1896 
1897 #if !defined(HAVE_native_mpfq_fixmp_1_cmp_ui)
1898 /* x has 1 words. Return sign of difference x-y. */
1899 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
1900 static inline
mpfq_fixmp_1_cmp_ui(const mp_limb_t * x,mp_limb_t y)1901 int mpfq_fixmp_1_cmp_ui(const mp_limb_t * x, mp_limb_t y)
1902 {
1903     if (x[0]>y) return 1;
1904     if (x[0]<y) return -1;
1905     return 0;
1906 }
1907 #endif /* !defined(HAVE_native_mpfq_fixmp_1_cmp_ui) */
1908 
1909 #if !defined(HAVE_native_mpfq_fixmp_1_addmul1)
1910 /* x has 1 words, z has 3.
1911  * Put (z+x*c) in z. Return carry bit. */
1912 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
1913 /* Triggered by: 1_redc, 1_redc_ur */
1914 static inline
mpfq_fixmp_1_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)1915 mp_limb_t mpfq_fixmp_1_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
1916 {
1917     mp_limb_t hi, lo, carry, buf;
1918     carry = 0;
1919     mpfq_umul_ppmm(hi,lo,c,x[0]);
1920     lo += carry;
1921     carry = (lo<carry) + hi;
1922     buf = z[0];
1923     lo += buf;
1924     carry += (lo<buf);
1925     z[0] = lo;
1926     z[1] += carry;
1927     return (z[1]<carry);
1928 }
1929 #endif /* !defined(HAVE_native_mpfq_fixmp_1_addmul1) */
1930 
1931 #if !defined(HAVE_native_mpfq_fixmp_1_addmul1_nc)
1932 /* x has 1 words, z has 3.
1933  * Put (z+x*c) in z. Carry bit is lost. */
1934 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
1935 /* Triggered by: 1_mul, 1_mgy_decode, 2_sqr, 2_shortmul, 3_sqr, 3_shortmul, 4_sqr, 4_shortmul, 5_sqr, 5_shortmul, 6_sqr, 6_shortmul, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 1_5_sqr, 1_5_shortmul, 2_5_sqr, 2_5_shortmul, 3_5_sqr, 3_5_shortmul, 4_5_sqr, 4_5_shortmul, 5_5_sqr, 5_5_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
1936 static inline
mpfq_fixmp_1_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)1937 void mpfq_fixmp_1_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
1938 {
1939     mp_limb_t hi, lo, carry, buf;
1940     carry = 0;
1941     mpfq_umul_ppmm(hi,lo,c,x[0]);
1942     lo += carry;
1943     carry = (lo<carry) + hi;
1944     buf = z[0];
1945     lo += buf;
1946     carry += (lo<buf);
1947     z[0] = lo;
1948     z[1] += carry;
1949 }
1950 #endif /* !defined(HAVE_native_mpfq_fixmp_1_addmul1_nc) */
1951 
1952 #if !defined(HAVE_native_mpfq_fixmp_1_addmul1_shortz)
1953 /* x has 1 words, z has 2.
1954  * Put (z+x*c) in z. Return carry word. */
1955 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
1956 static inline
mpfq_fixmp_1_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)1957 mp_limb_t mpfq_fixmp_1_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
1958 {
1959     mp_limb_t hi, lo, carry, buf;
1960     carry = 0;
1961     mpfq_umul_ppmm(hi,lo,c,x[0]);
1962     lo += carry;
1963     carry = (lo<carry) + hi;
1964     buf = z[0];
1965     lo += buf;
1966     carry += (lo<buf);
1967     z[0] = lo;
1968     return carry;
1969 }
1970 #endif /* !defined(HAVE_native_mpfq_fixmp_1_addmul1_shortz) */
1971 
1972 #if !defined(HAVE_native_mpfq_fixmp_1_mul)
1973 /* x and y have 1 words, z has 4. Put x*y in z. */
1974 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
1975 /* Triggered by: 1_mgy_decode */
1976 static inline
mpfq_fixmp_1_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)1977 void mpfq_fixmp_1_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
1978 {
1979     assert(z != x && z != y);
1980     for (int i = 0; i < 2; z[i++] = 0) ;
1981     mpfq_fixmp_1_addmul1_nc (z + 0, x, y[0]);
1982 }
1983 #endif /* !defined(HAVE_native_mpfq_fixmp_1_mul) */
1984 
1985 #if !defined(HAVE_native_mpfq_fixmp_1_sqr)
1986 /* x has 1 words, z has 4. Put x*y in z. */
1987 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
1988 static inline
mpfq_fixmp_1_sqr(mp_limb_t * z,const mp_limb_t * x)1989 void mpfq_fixmp_1_sqr(mp_limb_t * z, const mp_limb_t * x)
1990 {
1991     mp_limb_t buf[2] = {0,};
1992     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
1993     mpn_lshift(buf, buf, 2, 1);
1994     mpn_add_n(z, z, buf, 2);
1995 }
1996 #endif /* !defined(HAVE_native_mpfq_fixmp_1_sqr) */
1997 
1998 #if !defined(HAVE_native_mpfq_fixmp_1_mul1)
1999 /* x has 1 words, z has 3. Put x*y in z. */
2000 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
2001 static inline
mpfq_fixmp_1_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)2002 void mpfq_fixmp_1_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
2003 {
2004     mp_limb_t hi, lo, carry;
2005     carry = 0;
2006     mpfq_umul_ppmm(hi,lo,c,x[0]);
2007     lo += carry;
2008     carry = (lo<carry) + hi;
2009     z[0] = lo;
2010     z[1] = carry;
2011 }
2012 #endif /* !defined(HAVE_native_mpfq_fixmp_1_mul1) */
2013 
2014 #if !defined(HAVE_native_mpfq_fixmp_1_shortmul)
2015 /* x and y have 1 words, z has 2.
2016  * Put the low 2 words of x*y in z. */
2017 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
2018 static inline
mpfq_fixmp_1_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2019 void mpfq_fixmp_1_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2020 {
2021     mpfq_zero(z, 1);
2022     z[1-1] += x[0]*y[1-1];
2023 }
2024 #endif /* !defined(HAVE_native_mpfq_fixmp_1_shortmul) */
2025 
2026 #if !defined(HAVE_native_mpfq_fixmp_1_mod)
2027 /* x has 4 words. z and p have 1 words, and the high word of p is non-zero.
2028  * Put x mod p in z. */
2029 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
2030 /* Triggered by: 1_mgy_decode */
2031 static inline
mpfq_fixmp_1_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)2032 void mpfq_fixmp_1_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
2033 {
2034     mp_limb_t q[1+1], r[1];
2035     assert (p[1-1] != 0);
2036     mpn_tdiv_qr(q, r, 0, x, 2, p, 1);
2037     mpfq_copy(z, r, 1);
2038 }
2039 #endif /* !defined(HAVE_native_mpfq_fixmp_1_mod) */
2040 
2041 #if !defined(HAVE_native_mpfq_fixmp_1_invmod)
2042 /* x, z, and p have 1 words. Put inverse of x mod p in z.
2043  * Return non-zero if an inverse could be found.
2044  * If no inverse could be found, return 0 and set z to zero.
2045  */
2046 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
2047 static inline
mpfq_fixmp_1_invmod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)2048 int mpfq_fixmp_1_invmod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
2049 {
2050       mp_limb_t a, b, u, v, fix;
2051       int t, lsh;
2052 
2053       a = *x;
2054       b = *p;
2055 
2056       if (a == 0 || a == b) {
2057         *z=0;
2058         return 0;
2059       }
2060       /* b must be odd and >a */
2061 
2062       fix = (b+1)>>1;
2063 
2064       assert (a < b);
2065 
2066       u = 1; v = 0; t = 0;
2067 
2068       /* compute u and t such that u*a_orig = 2^t mod b */
2069 
2070       /* we maintain:
2071        *    u*a_orig - (not kept)*b_orig = 2^t*a
2072        *    v*a_orig - (not kept)*b_orig = -2^t*b
2073        * a and b are both odd.
2074        * An update consists in reducing the largest by the smallest,
2075        * and then adjusting the valuation.  */
2076 
2077       lsh = mpfq_ctzl(a);
2078       a >>= lsh;
2079       t += lsh;
2080       v <<= lsh;
2081       do {
2082         do {
2083           b -= a; v += u;
2084           lsh = mpfq_ctzl(b);
2085           b >>= lsh;
2086           t += lsh;
2087           u <<= lsh;
2088         } while (a<b);
2089         if (a == b)
2090           break;
2091         do {
2092           a -= b; u += v;
2093           lsh = mpfq_ctzl(a);
2094           a >>= lsh;
2095           t += lsh;
2096           v <<= lsh;
2097         } while (b < a);
2098       } while (a != b);
2099       if (a != 1) {
2100         *z = a;
2101         return 0;
2102       }
2103       while (t>0) {
2104         mp_limb_t sig = u & 1UL;
2105         u >>= 1;
2106         if (sig)
2107           u += fix;
2108         --t;
2109       }
2110       *z = u;
2111       return 1;
2112 }
2113 #endif /* !defined(HAVE_native_mpfq_fixmp_1_invmod) */
2114 
2115 #if !defined(HAVE_native_mpfq_fixmp_1_redc)
2116 /* x has 4 words, z and p have 1 words.
2117  * only one word is read from invp.
2118  * Assuming R=W^2 is the redc modulus, we expect that x verifies:
2119  *   x < R*p,
2120  * so that we have eventually z < p, z congruent to x/R mod p.
2121  * The contents of the area pointed by x are clobbered by this call.
2122  * Note also that x may alias z.
2123  */
2124 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
2125 static inline
mpfq_fixmp_1_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)2126 void mpfq_fixmp_1_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
2127 {
2128     mp_limb_t t = x[0]*mip[0];
2129     mp_limb_t cy = mpfq_fixmp_1_addmul1(x, p, t);
2130     if (cy || (x[1]>=p[0])) {
2131         z[0] = x[1] - p[0];
2132     } else {
2133         z[0] = x[1];
2134     }
2135 }
2136 #endif /* !defined(HAVE_native_mpfq_fixmp_1_redc) */
2137 
2138 #if !defined(HAVE_native_mpfq_fixmp_1_redc_ur)
2139 /* x has 5 words, z and p have 1 words.
2140  * only one word is read from invp.
2141  * Assuming R=W^2 is the redc modulus, we expect that x verifies:
2142  *  x < W*W^1*p = W^0.5*R*p or the hw case, W*R*p otherwise,
2143  * so that we have eventually z < p, z congruent to x/R mod p.
2144  * The contents of the area pointed by x are clobbered by this call.
2145  * Note also that x may alias z.
2146  */
2147 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
2148 static inline
mpfq_fixmp_1_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)2149 void mpfq_fixmp_1_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
2150 {
2151     mp_limb_t cy, q[2];
2152     for (int i = 0; i < 1; ++i) {
2153         mp_limb_t t = x[i]*mip[0];
2154         cy = mpfq_fixmp_1_addmul1(x+i, p, t);
2155         assert (x[i] == 0);
2156         x[i] = cy;
2157     }
2158     cy=mpfq_fixmp_1_add(x+1+1, x+1+1, x);
2159     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
2160     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
2161     * x'/R < (W+1)*p
2162     */
2163     if (cy) {
2164         /* x'/R-p < W*p, which fits in n+1 words */
2165         mpn_sub(x+1,x+1,1+1,p,1);
2166     }
2167     mpn_tdiv_qr(q, z, 0, x+1, 1+1, p, 1);
2168 }
2169 #endif /* !defined(HAVE_native_mpfq_fixmp_1_redc_ur) */
2170 
2171 #if !defined(HAVE_native_mpfq_fixmp_1_mgy_encode)
2172 /* x, z, and p have 1 words.
2173  * Assuming R=W^2 is the redc modulus, we compute z=R*x mod p. */
2174 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
2175 static inline
mpfq_fixmp_1_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)2176 void mpfq_fixmp_1_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
2177 {
2178     mp_limb_t t[2] = { 0, x[0] };
2179     mpfq_fixmp_1_mod(z, t, p);
2180 }
2181 #endif /* !defined(HAVE_native_mpfq_fixmp_1_mgy_encode) */
2182 
2183 #if !defined(HAVE_native_mpfq_fixmp_1_mgy_decode)
2184 /* x, z, invR, and p have 1 words.
2185  * Assuming R=W^2 is the redc modulus, we compute z=x/R mod p. */
2186 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
2187 static inline
mpfq_fixmp_1_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)2188 void mpfq_fixmp_1_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
2189 {
2190     mp_limb_t t[2];
2191     mpfq_fixmp_1_mul(t, x, invR);
2192     mpfq_fixmp_1_mod(z, t, p);
2193 }
2194 #endif /* !defined(HAVE_native_mpfq_fixmp_1_mgy_decode) */
2195 
2196 #if !defined(HAVE_native_mpfq_fixmp_1_lshift)
2197 /* a has 1 words. Shift it in place by cnt bits to the left.
2198  * The shift count cnt must not exceed the word size.
2199  * Note that no carry is returned for the bits shifted out. */
2200 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
2201 static inline
mpfq_fixmp_1_lshift(mp_limb_t * a,int cnt)2202 void mpfq_fixmp_1_lshift(mp_limb_t * a, int cnt)
2203 {
2204     if (!cnt) return;
2205     a[0] <<= cnt;
2206 }
2207 #endif /* !defined(HAVE_native_mpfq_fixmp_1_lshift) */
2208 
2209 #if !defined(HAVE_native_mpfq_fixmp_1_rshift)
2210 /* a has 1 words. Shift it in place by cnt bits to the right.
2211  * The shift count cnt must not exceed the word size.
2212  * Note that no carry is returned for the bits shifted out. */
2213 /* *Mpfq::fixmp::longlong::code_for__fixmp_rshift */
2214 static inline
mpfq_fixmp_1_rshift(mp_limb_t * a,int cnt)2215 void mpfq_fixmp_1_rshift(mp_limb_t * a, int cnt)
2216 {
2217     if (!cnt) return;
2218     a[1-1] >>= cnt;
2219 }
2220 #endif /* !defined(HAVE_native_mpfq_fixmp_1_rshift) */
2221 
2222 #if !defined(HAVE_native_mpfq_fixmp_1_long_lshift)
2223 /* a has 1 words. Shift it in place by off words plus cnt bits to the left.
2224  * Note that no carry is returned for the bits shifted out. */
2225 /* *Mpfq::fixmp::longlong::code_for__fixmp_long_lshift */
2226 static inline
mpfq_fixmp_1_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)2227 void mpfq_fixmp_1_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
2228 {
2229     if (cnt) {
2230         a[0] <<= cnt;
2231     }
2232 }
2233 #endif /* !defined(HAVE_native_mpfq_fixmp_1_long_lshift) */
2234 
2235 #if !defined(HAVE_native_mpfq_fixmp_1_long_rshift)
2236 /* a has 1 words. Shift it in place by off words plus cnt bits to the left.
2237  * Note that no carry is returned for the bits shifted out. */
2238 /* *Mpfq::fixmp::longlong::code_for__fixmp_long_rshift */
2239 static inline
mpfq_fixmp_1_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)2240 void mpfq_fixmp_1_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
2241 {
2242     if (cnt) {
2243         a[0] >>= cnt;
2244     }
2245 }
2246 #endif /* !defined(HAVE_native_mpfq_fixmp_1_long_rshift) */
2247 
2248 #if !defined(HAVE_native_mpfq_fixmp_2_add)
2249 /* x, y, and z have 2 words. Result in z. Return carry bit */
2250 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
2251 /* Triggered by: 2_invmod, 2_redc, 2_redc_ur */
2252 static inline
mpfq_fixmp_2_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2253 mp_limb_t mpfq_fixmp_2_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2254 {
2255     mp_limb_t r, s, t, cy, cy1, cy2;
2256     cy = 0;
2257     r = x[0];
2258     s = r + y[0];
2259     cy1 = s < r;
2260     t = s + cy;
2261     cy2 = t < s;
2262     cy = cy1 | cy2;
2263     z[0] = t;
2264     r = x[1];
2265     s = r + y[1];
2266     cy1 = s < r;
2267     t = s + cy;
2268     cy2 = t < s;
2269     cy = cy1 | cy2;
2270     z[1] = t;
2271     return cy;
2272 }
2273 #endif /* !defined(HAVE_native_mpfq_fixmp_2_add) */
2274 
2275 #if !defined(HAVE_native_mpfq_fixmp_2_sub)
2276 /* x, y, and z have 2 words. Result in z. Return borrow bit */
2277 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
2278 /* Triggered by: 2_invmod, 2_redc */
2279 static inline
mpfq_fixmp_2_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2280 mp_limb_t mpfq_fixmp_2_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2281 {
2282     mp_limb_t r, s, t, cy, cy1, cy2;
2283     cy = 0;
2284     r = x[0];
2285     s = r - y[0];
2286     cy1 = s > r;
2287     t = s - cy;
2288     cy2 = t > s;
2289     cy = cy1 | cy2;
2290     z[0] = t;
2291     r = x[1];
2292     s = r - y[1];
2293     cy1 = s > r;
2294     t = s - cy;
2295     cy2 = t > s;
2296     cy = cy1 | cy2;
2297     z[1] = t;
2298     return cy;
2299 }
2300 #endif /* !defined(HAVE_native_mpfq_fixmp_2_sub) */
2301 
2302 #if !defined(HAVE_native_mpfq_fixmp_2_add_nc)
2303 /* x, y, and z have 2 words. Result in z. Carry bit is lost. */
2304 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
2305 static inline
mpfq_fixmp_2_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2306 void mpfq_fixmp_2_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2307 {
2308     mp_limb_t r, s, t, cy, cy1, cy2;
2309     cy = 0;
2310     r = x[0];
2311     s = r + y[0];
2312     cy1 = s < r;
2313     t = s + cy;
2314     cy2 = t < s;
2315     cy = cy1 | cy2;
2316     z[0] = t;
2317     r = x[1];
2318     s = r + y[1];
2319     cy1 = s < r;
2320     t = s + cy;
2321     cy2 = t < s;
2322     cy = cy1 | cy2;
2323     z[1] = t;
2324 }
2325 #endif /* !defined(HAVE_native_mpfq_fixmp_2_add_nc) */
2326 
2327 #if !defined(HAVE_native_mpfq_fixmp_2_sub_nc)
2328 /* x, y, and z have 2 words. Result in z. Borrow bit is lost. */
2329 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
2330 static inline
mpfq_fixmp_2_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2331 void mpfq_fixmp_2_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2332 {
2333     mp_limb_t r, s, t, cy, cy1, cy2;
2334     cy = 0;
2335     r = x[0];
2336     s = r - y[0];
2337     cy1 = s > r;
2338     t = s - cy;
2339     cy2 = t > s;
2340     cy = cy1 | cy2;
2341     z[0] = t;
2342     r = x[1];
2343     s = r - y[1];
2344     cy1 = s > r;
2345     t = s - cy;
2346     cy2 = t > s;
2347     cy = cy1 | cy2;
2348     z[1] = t;
2349 }
2350 #endif /* !defined(HAVE_native_mpfq_fixmp_2_sub_nc) */
2351 
2352 #if !defined(HAVE_native_mpfq_fixmp_2_add_ui)
2353 /* x, y, and z have 2 words. Result in z. Return carry bit */
2354 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
2355 static inline
mpfq_fixmp_2_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)2356 mp_limb_t mpfq_fixmp_2_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
2357 {
2358     mp_limb_t r, s, t, cy, cy1, cy2;
2359     cy = 0;
2360     r = x[0];
2361     s = r + y;
2362     cy1 = s < r;
2363     t = s + cy;
2364     cy2 = t < s;
2365     cy = cy1 | cy2;
2366     z[0] = t;
2367     s = x[1];
2368     t = s + cy;
2369     cy = t < s;
2370     z[1] = t;
2371     return cy;
2372 }
2373 #endif /* !defined(HAVE_native_mpfq_fixmp_2_add_ui) */
2374 
2375 #if !defined(HAVE_native_mpfq_fixmp_2_sub_ui)
2376 /* x, y, and z have 2 words. Result in z. Return borrow bit */
2377 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
2378 static inline
mpfq_fixmp_2_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)2379 mp_limb_t mpfq_fixmp_2_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
2380 {
2381     mp_limb_t r, s, t, cy, cy1, cy2;
2382     cy = 0;
2383     r = x[0];
2384     s = r - y;
2385     cy1 = s > r;
2386     t = s - cy;
2387     cy2 = t > s;
2388     cy = cy1 | cy2;
2389     z[0] = t;
2390     s = x[1];
2391     t = s - cy;
2392     cy = t > s;
2393     z[1] = t;
2394     return cy;
2395 }
2396 #endif /* !defined(HAVE_native_mpfq_fixmp_2_sub_ui) */
2397 
2398 #if !defined(HAVE_native_mpfq_fixmp_2_add_ui_nc)
2399 /* x, y, and z have 2 words. Result in z. Carry bit is lost. */
2400 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
2401 static inline
mpfq_fixmp_2_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)2402 void mpfq_fixmp_2_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
2403 {
2404     mp_limb_t r, s, t, cy, cy1, cy2;
2405     cy = 0;
2406     r = x[0];
2407     s = r + y;
2408     cy1 = s < r;
2409     t = s + cy;
2410     cy2 = t < s;
2411     cy = cy1 | cy2;
2412     z[0] = t;
2413     s = x[1];
2414     t = s + cy;
2415     cy = t < s;
2416     z[1] = t;
2417 }
2418 #endif /* !defined(HAVE_native_mpfq_fixmp_2_add_ui_nc) */
2419 
2420 #if !defined(HAVE_native_mpfq_fixmp_2_sub_ui_nc)
2421 /* x, y, and z have 2 words. Result in z. Borrow bit is lost. */
2422 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
2423 static inline
mpfq_fixmp_2_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)2424 void mpfq_fixmp_2_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
2425 {
2426     mp_limb_t r, s, t, cy, cy1, cy2;
2427     cy = 0;
2428     r = x[0];
2429     s = r - y;
2430     cy1 = s > r;
2431     t = s - cy;
2432     cy2 = t > s;
2433     cy = cy1 | cy2;
2434     z[0] = t;
2435     s = x[1];
2436     t = s - cy;
2437     cy = t > s;
2438     z[1] = t;
2439 }
2440 #endif /* !defined(HAVE_native_mpfq_fixmp_2_sub_ui_nc) */
2441 
2442 #if !defined(HAVE_native_mpfq_fixmp_2_cmp)
2443 /* x and y have 2 words. Return sign of difference x-y. */
2444 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
2445 /* Triggered by: 2_invmod, 2_redc */
2446 static inline
mpfq_fixmp_2_cmp(const mp_limb_t * x,const mp_limb_t * y)2447 int mpfq_fixmp_2_cmp(const mp_limb_t * x, const mp_limb_t * y)
2448 {
2449     for (int i = 2-1; i >= 0; --i) {
2450         if (x[i] > y[i]) return 1;
2451         if (x[i] < y[i]) return -1;
2452     }
2453     return 0;
2454 }
2455 #endif /* !defined(HAVE_native_mpfq_fixmp_2_cmp) */
2456 
2457 #if !defined(HAVE_native_mpfq_fixmp_2_cmp_ui)
2458 /* x has 2 words. Return sign of difference x-y. */
2459 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
2460 /* Triggered by: 2_invmod */
2461 static inline
mpfq_fixmp_2_cmp_ui(const mp_limb_t * x,mp_limb_t y)2462 int mpfq_fixmp_2_cmp_ui(const mp_limb_t * x, mp_limb_t y)
2463 {
2464     for (int i = 2-1; i > 0; --i) {
2465         if (x[i]) return 1;
2466     }
2467     if (x[0]>y) return 1;
2468     if (x[0]<y) return -1;
2469     return 0;
2470 }
2471 #endif /* !defined(HAVE_native_mpfq_fixmp_2_cmp_ui) */
2472 
2473 #if !defined(HAVE_native_mpfq_fixmp_2_addmul1)
2474 /* x has 2 words, z has 4.
2475  * Put (z+x*c) in z. Return carry bit. */
2476 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
2477 /* Triggered by: 2_redc_ur */
2478 static inline
mpfq_fixmp_2_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)2479 mp_limb_t mpfq_fixmp_2_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
2480 {
2481     mp_limb_t hi, lo, carry, buf;
2482     carry = 0;
2483     mpfq_umul_ppmm(hi,lo,c,x[0]);
2484     lo += carry;
2485     carry = (lo<carry) + hi;
2486     buf = z[0];
2487     lo += buf;
2488     carry += (lo<buf);
2489     z[0] = lo;
2490     mpfq_umul_ppmm(hi,lo,c,x[1]);
2491     lo += carry;
2492     carry = (lo<carry) + hi;
2493     buf = z[1];
2494     lo += buf;
2495     carry += (lo<buf);
2496     z[1] = lo;
2497     z[2] += carry;
2498     return (z[2]<carry);
2499 }
2500 #endif /* !defined(HAVE_native_mpfq_fixmp_2_addmul1) */
2501 
2502 #if !defined(HAVE_native_mpfq_fixmp_2_addmul1_nc)
2503 /* x has 2 words, z has 4.
2504  * Put (z+x*c) in z. Carry bit is lost. */
2505 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
2506 /* Triggered by: 2_mul, 2_mgy_decode, 3_sqr, 3_shortmul, 4_sqr, 4_shortmul, 5_sqr, 5_shortmul, 6_sqr, 6_shortmul, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 2_5_sqr, 2_5_shortmul, 3_5_sqr, 3_5_shortmul, 4_5_sqr, 4_5_shortmul, 5_5_sqr, 5_5_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
2507 static inline
mpfq_fixmp_2_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)2508 void mpfq_fixmp_2_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
2509 {
2510     mp_limb_t hi, lo, carry, buf;
2511     carry = 0;
2512     mpfq_umul_ppmm(hi,lo,c,x[0]);
2513     lo += carry;
2514     carry = (lo<carry) + hi;
2515     buf = z[0];
2516     lo += buf;
2517     carry += (lo<buf);
2518     z[0] = lo;
2519     mpfq_umul_ppmm(hi,lo,c,x[1]);
2520     lo += carry;
2521     carry = (lo<carry) + hi;
2522     buf = z[1];
2523     lo += buf;
2524     carry += (lo<buf);
2525     z[1] = lo;
2526     z[2] += carry;
2527 }
2528 #endif /* !defined(HAVE_native_mpfq_fixmp_2_addmul1_nc) */
2529 
2530 #if !defined(HAVE_native_mpfq_fixmp_2_addmul1_shortz)
2531 /* x has 2 words, z has 3.
2532  * Put (z+x*c) in z. Return carry word. */
2533 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
2534 /* Triggered by: 2_redc */
2535 static inline
mpfq_fixmp_2_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)2536 mp_limb_t mpfq_fixmp_2_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
2537 {
2538     mp_limb_t hi, lo, carry, buf;
2539     carry = 0;
2540     mpfq_umul_ppmm(hi,lo,c,x[0]);
2541     lo += carry;
2542     carry = (lo<carry) + hi;
2543     buf = z[0];
2544     lo += buf;
2545     carry += (lo<buf);
2546     z[0] = lo;
2547     mpfq_umul_ppmm(hi,lo,c,x[1]);
2548     lo += carry;
2549     carry = (lo<carry) + hi;
2550     buf = z[1];
2551     lo += buf;
2552     carry += (lo<buf);
2553     z[1] = lo;
2554     return carry;
2555 }
2556 #endif /* !defined(HAVE_native_mpfq_fixmp_2_addmul1_shortz) */
2557 
2558 #if !defined(HAVE_native_mpfq_fixmp_2_mul)
2559 /* x and y have 2 words, z has 6. Put x*y in z. */
2560 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
2561 /* Triggered by: 2_mgy_decode */
2562 static inline
mpfq_fixmp_2_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2563 void mpfq_fixmp_2_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2564 {
2565     assert(z != x && z != y);
2566     for (int i = 0; i < 4; z[i++] = 0) ;
2567     mpfq_fixmp_2_addmul1_nc (z + 0, x, y[0]);
2568     mpfq_fixmp_2_addmul1_nc (z + 1, x, y[1]);
2569 }
2570 #endif /* !defined(HAVE_native_mpfq_fixmp_2_mul) */
2571 
2572 #if !defined(HAVE_native_mpfq_fixmp_2_sqr)
2573 /* x has 2 words, z has 6. Put x*y in z. */
2574 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
2575 static inline
mpfq_fixmp_2_sqr(mp_limb_t * z,const mp_limb_t * x)2576 void mpfq_fixmp_2_sqr(mp_limb_t * z, const mp_limb_t * x)
2577 {
2578     mp_limb_t buf[4] = {0,};
2579     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
2580     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
2581     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
2582     mpn_lshift(buf, buf, 4, 1);
2583     mpn_add_n(z, z, buf, 4);
2584 }
2585 #endif /* !defined(HAVE_native_mpfq_fixmp_2_sqr) */
2586 
2587 #if !defined(HAVE_native_mpfq_fixmp_2_mul1)
2588 /* x has 2 words, z has 4. Put x*y in z. */
2589 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
2590 static inline
mpfq_fixmp_2_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)2591 void mpfq_fixmp_2_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
2592 {
2593     mp_limb_t hi, lo, carry;
2594     carry = 0;
2595     mpfq_umul_ppmm(hi,lo,c,x[0]);
2596     lo += carry;
2597     carry = (lo<carry) + hi;
2598     z[0] = lo;
2599     mpfq_umul_ppmm(hi,lo,c,x[1]);
2600     lo += carry;
2601     carry = (lo<carry) + hi;
2602     z[1] = lo;
2603     z[2] = carry;
2604 }
2605 #endif /* !defined(HAVE_native_mpfq_fixmp_2_mul1) */
2606 
2607 #if !defined(HAVE_native_mpfq_fixmp_2_shortmul)
2608 /* x and y have 2 words, z has 3.
2609  * Put the low 3 words of x*y in z. */
2610 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
2611 static inline
mpfq_fixmp_2_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2612 void mpfq_fixmp_2_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2613 {
2614     mpfq_zero(z, 2);
2615     mpfq_fixmp_1_addmul1_nc (z+0, x, y[0]);
2616     z[2-1] += x[1]*y[0];
2617     z[2-1] += x[0]*y[2-1];
2618 }
2619 #endif /* !defined(HAVE_native_mpfq_fixmp_2_shortmul) */
2620 
2621 #if !defined(HAVE_native_mpfq_fixmp_2_mod)
2622 /* x has 6 words. z and p have 2 words, and the high word of p is non-zero.
2623  * Put x mod p in z. */
2624 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
2625 /* Triggered by: 2_mgy_decode */
2626 static inline
mpfq_fixmp_2_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)2627 void mpfq_fixmp_2_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
2628 {
2629     mp_limb_t q[2+1], r[2];
2630     assert (p[2-1] != 0);
2631     mpn_tdiv_qr(q, r, 0, x, 4, p, 2);
2632     mpfq_copy(z, r, 2);
2633 }
2634 #endif /* !defined(HAVE_native_mpfq_fixmp_2_mod) */
2635 
2636 #if !defined(HAVE_native_mpfq_fixmp_2_rshift)
2637 /* a has 2 words. Shift it in place by cnt bits to the right.
2638  * The shift count cnt must not exceed the word size.
2639  * Note that no carry is returned for the bits shifted out. */
2640 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
2641 /* Triggered by: 2_invmod */
2642 static inline
mpfq_fixmp_2_rshift(mp_limb_t * a,int cnt)2643 void mpfq_fixmp_2_rshift(mp_limb_t * a, int cnt)
2644 {
2645     if (!cnt) return;
2646     int i;
2647     int dnt = GMP_NUMB_BITS - cnt;
2648     for (i = 0; i < 2-1; ++i) {
2649         a[i] >>= cnt;
2650         a[i] |= (a[i+1] << dnt);
2651     }
2652     a[2-1] >>= cnt;
2653 }
2654 #endif /* !defined(HAVE_native_mpfq_fixmp_2_rshift) */
2655 
2656 #if !defined(HAVE_native_mpfq_fixmp_2_long_rshift)
2657 /* a has 2 words. Shift it in place by off words plus cnt bits to the left.
2658  * Note that no carry is returned for the bits shifted out. */
2659 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
2660 /* Triggered by: 2_invmod */
2661 static inline
mpfq_fixmp_2_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)2662 void mpfq_fixmp_2_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
2663 {
2664     if (cnt) {
2665         int dnt = GMP_NUMB_BITS - cnt;
2666         for (int i = 0; i < 2 - off - 1; ++i) {
2667             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
2668         }
2669         a[2-off-1] = a[2-1]>>cnt;
2670     } else {
2671         mpfq_copyi(a, a + off, 2 - off);
2672     }
2673     mpfq_zero(a + 2 - off, off);
2674 }
2675 #endif /* !defined(HAVE_native_mpfq_fixmp_2_long_rshift) */
2676 
2677 #if !defined(HAVE_native_mpfq_fixmp_2_long_lshift)
2678 /* a has 2 words. Shift it in place by off words plus cnt bits to the left.
2679  * Note that no carry is returned for the bits shifted out. */
2680 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
2681 /* Triggered by: 2_invmod */
2682 static inline
mpfq_fixmp_2_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)2683 void mpfq_fixmp_2_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
2684 {
2685     int i;
2686     if (cnt) {
2687         int dnt = GMP_NUMB_BITS - cnt;
2688         for (i = 2-1; i>off; --i) {
2689             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
2690         }
2691         a[off] = a[0]<<cnt;
2692     } else {
2693         mpfq_copyd(a + off, a, 2 - off);
2694     }
2695     mpfq_zero(a, off);
2696 }
2697 #endif /* !defined(HAVE_native_mpfq_fixmp_2_long_lshift) */
2698 
2699 #if !defined(HAVE_native_mpfq_fixmp_2_invmod)
2700 /* x, z, and p have 2 words. Put inverse of x mod p in z.
2701  * Return non-zero if an inverse could be found.
2702  * If no inverse could be found, return 0 and set z to zero.
2703  */
2704 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
2705 static inline
mpfq_fixmp_2_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)2706 int mpfq_fixmp_2_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
2707 {
2708       mp_limb_t u[2], v[2], a[2], b[2], fix[2];
2709       int i, t, lsh;
2710 
2711       mpfq_zero(u, 2);
2712       mpfq_zero(v, 2);
2713       mpfq_copy(a, x, 2);
2714       mpfq_copy(b, p, 2);
2715       u[0] = 1UL;
2716 
2717       if (mpfq_fixmp_2_cmp(a, v) == 0 || mpfq_fixmp_2_cmp(a, b) == 0) {
2718         mpfq_zero(res, 2);
2719         return 0;
2720       }
2721 
2722       mpfq_fixmp_2_add(fix, b, u);
2723       mpfq_fixmp_2_rshift(fix, 1);
2724 
2725       assert (mpfq_fixmp_2_cmp(a,b) < 0);
2726 
2727       t = 0;
2728 
2729       for(i = 0 ; !a[i] ; i++) ;
2730       assert (i < 2);
2731       lsh = mpfq_ctzl(a[i]);
2732       mpfq_fixmp_2_long_rshift(a, i, lsh);
2733       t += lsh + i*GMP_NUMB_BITS;
2734       mpfq_fixmp_2_long_lshift(v, i, lsh);
2735 
2736       do {
2737         do {
2738           mpfq_fixmp_2_sub(b, b, a);
2739           mpfq_fixmp_2_add(v, v, u);
2740           for(i = 0 ; !b[i] ; i++) ;
2741           assert (i < 2);
2742           lsh = mpfq_ctzl(b[i]);
2743           mpfq_fixmp_2_long_rshift(b, i, lsh);
2744           t += lsh + i*GMP_NUMB_BITS;
2745           mpfq_fixmp_2_long_lshift(u, i, lsh);
2746         } while (mpfq_fixmp_2_cmp(a,b) < 0);
2747         if (mpfq_fixmp_2_cmp(a, b) == 0)
2748           break;
2749         do {
2750           mpfq_fixmp_2_sub(a, a, b);
2751           mpfq_fixmp_2_add(u, u, v);
2752           for(i = 0 ; !a[i] ; i++) ;
2753           assert (i < 2);
2754           lsh = mpfq_ctzl(a[i]);
2755           mpfq_fixmp_2_long_rshift(a, i, lsh);
2756           t += lsh + i*GMP_NUMB_BITS;
2757           mpfq_fixmp_2_long_lshift(v, i, lsh);
2758         } while (mpfq_fixmp_2_cmp(b,a)<0);
2759       } while (mpfq_fixmp_2_cmp(a,b) != 0);
2760       {
2761         if (mpfq_fixmp_2_cmp_ui(a, 1) != 0) {
2762           mpfq_copy(res, a, 2);
2763           return 0;
2764         }
2765       }
2766       while (t>0) {
2767         mp_limb_t sig = u[0] & 1UL;
2768         mpfq_fixmp_2_rshift(u, 1);
2769         if (sig)
2770           mpfq_fixmp_2_add(u, u, fix);
2771         --t;
2772       }
2773       mpfq_copy(res, u, 2);
2774       return 1;
2775 }
2776 #endif /* !defined(HAVE_native_mpfq_fixmp_2_invmod) */
2777 
2778 #if !defined(HAVE_native_mpfq_fixmp_2_redc)
2779 /* x has 6 words, z and p have 2 words.
2780  * only one word is read from invp.
2781  * Assuming R=W^3 is the redc modulus, we expect that x verifies:
2782  *   x < R*p,
2783  * so that we have eventually z < p, z congruent to x/R mod p.
2784  * The contents of the area pointed by x are clobbered by this call.
2785  * Note also that x may alias z.
2786  */
2787 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
2788 static inline
mpfq_fixmp_2_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)2789 void mpfq_fixmp_2_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
2790 {
2791     mp_limb_t cy;
2792     for(int i = 0; i < 2; ++i) {
2793         mp_limb_t t = x[i]*mip[0];
2794         cy = mpfq_fixmp_2_addmul1_shortz(x+i, p, t);
2795         assert (x[i] == 0);
2796         x[i] = cy;
2797     }
2798     cy = mpfq_fixmp_2_add(x, x, x + 2);
2799     /* At this point, we have (x' denotes x + cy*W^n here)
2800     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
2801     * x'/R < p + p
2802     */
2803     if (cy || mpfq_fixmp_2_cmp(x, p) >= 0) {
2804         mpfq_fixmp_2_sub(z, x, p);
2805     } else {
2806         mpfq_copy(z, x, 2);
2807     }
2808 }
2809 #endif /* !defined(HAVE_native_mpfq_fixmp_2_redc) */
2810 
2811 #if !defined(HAVE_native_mpfq_fixmp_2_redc_ur)
2812 /* x has 7 words, z and p have 2 words.
2813  * only one word is read from invp.
2814  * Assuming R=W^3 is the redc modulus, we expect that x verifies:
2815  *  x < W*W^2*p = W^0.5*R*p or the hw case, W*R*p otherwise,
2816  * so that we have eventually z < p, z congruent to x/R mod p.
2817  * The contents of the area pointed by x are clobbered by this call.
2818  * Note also that x may alias z.
2819  */
2820 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
2821 static inline
mpfq_fixmp_2_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)2822 void mpfq_fixmp_2_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
2823 {
2824     mp_limb_t cy, q[2];
2825     for (int i = 0; i < 2; ++i) {
2826         mp_limb_t t = x[i]*mip[0];
2827         cy = mpfq_fixmp_2_addmul1(x+i, p, t);
2828         assert (x[i] == 0);
2829         x[i] = cy;
2830     }
2831     cy=mpfq_fixmp_2_add(x+2+1, x+2+1, x);
2832     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
2833     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
2834     * x'/R < (W+1)*p
2835     */
2836     if (cy) {
2837         /* x'/R-p < W*p, which fits in n+1 words */
2838         mpn_sub(x+2,x+2,2+1,p,2);
2839     }
2840     mpn_tdiv_qr(q, z, 0, x+2, 2+1, p, 2);
2841 }
2842 #endif /* !defined(HAVE_native_mpfq_fixmp_2_redc_ur) */
2843 
2844 #if !defined(HAVE_native_mpfq_fixmp_2_mgy_encode)
2845 /* x, z, and p have 2 words.
2846  * Assuming R=W^3 is the redc modulus, we compute z=R*x mod p. */
2847 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
2848 static inline
mpfq_fixmp_2_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)2849 void mpfq_fixmp_2_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
2850 {
2851     mp_limb_t t[4] = { 0, 0, x[0], x[1] };
2852     mpfq_fixmp_2_mod(z, t, p);
2853 }
2854 #endif /* !defined(HAVE_native_mpfq_fixmp_2_mgy_encode) */
2855 
2856 #if !defined(HAVE_native_mpfq_fixmp_2_mgy_decode)
2857 /* x, z, invR, and p have 2 words.
2858  * Assuming R=W^3 is the redc modulus, we compute z=x/R mod p. */
2859 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
2860 static inline
mpfq_fixmp_2_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)2861 void mpfq_fixmp_2_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
2862 {
2863     mp_limb_t t[4];
2864     mpfq_fixmp_2_mul(t, x, invR);
2865     mpfq_fixmp_2_mod(z, t, p);
2866 }
2867 #endif /* !defined(HAVE_native_mpfq_fixmp_2_mgy_decode) */
2868 
2869 #if !defined(HAVE_native_mpfq_fixmp_2_lshift)
2870 /* a has 2 words. Shift it in place by cnt bits to the left.
2871  * The shift count cnt must not exceed the word size.
2872  * Note that no carry is returned for the bits shifted out. */
2873 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
2874 static inline
mpfq_fixmp_2_lshift(mp_limb_t * a,int cnt)2875 void mpfq_fixmp_2_lshift(mp_limb_t * a, int cnt)
2876 {
2877     if (!cnt) return;
2878     int i;
2879     int dnt = GMP_NUMB_BITS - cnt;
2880     for (i = 2-1; i>0; --i) {
2881         a[i] <<= cnt;
2882         a[i] |= (a[i-1] >> dnt);
2883     }
2884     a[0] <<= cnt;
2885 }
2886 #endif /* !defined(HAVE_native_mpfq_fixmp_2_lshift) */
2887 
2888 #if !defined(HAVE_native_mpfq_fixmp_3_add)
2889 /* x, y, and z have 3 words. Result in z. Return carry bit */
2890 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
2891 /* Triggered by: 3_invmod, 3_redc, 3_redc_ur */
2892 static inline
mpfq_fixmp_3_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2893 mp_limb_t mpfq_fixmp_3_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2894 {
2895     mp_limb_t r, s, t, cy, cy1, cy2;
2896     cy = 0;
2897     r = x[0];
2898     s = r + y[0];
2899     cy1 = s < r;
2900     t = s + cy;
2901     cy2 = t < s;
2902     cy = cy1 | cy2;
2903     z[0] = t;
2904     r = x[1];
2905     s = r + y[1];
2906     cy1 = s < r;
2907     t = s + cy;
2908     cy2 = t < s;
2909     cy = cy1 | cy2;
2910     z[1] = t;
2911     r = x[2];
2912     s = r + y[2];
2913     cy1 = s < r;
2914     t = s + cy;
2915     cy2 = t < s;
2916     cy = cy1 | cy2;
2917     z[2] = t;
2918     return cy;
2919 }
2920 #endif /* !defined(HAVE_native_mpfq_fixmp_3_add) */
2921 
2922 #if !defined(HAVE_native_mpfq_fixmp_3_sub)
2923 /* x, y, and z have 3 words. Result in z. Return borrow bit */
2924 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
2925 /* Triggered by: 3_invmod, 3_redc */
2926 static inline
mpfq_fixmp_3_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2927 mp_limb_t mpfq_fixmp_3_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2928 {
2929     mp_limb_t r, s, t, cy, cy1, cy2;
2930     cy = 0;
2931     r = x[0];
2932     s = r - y[0];
2933     cy1 = s > r;
2934     t = s - cy;
2935     cy2 = t > s;
2936     cy = cy1 | cy2;
2937     z[0] = t;
2938     r = x[1];
2939     s = r - y[1];
2940     cy1 = s > r;
2941     t = s - cy;
2942     cy2 = t > s;
2943     cy = cy1 | cy2;
2944     z[1] = t;
2945     r = x[2];
2946     s = r - y[2];
2947     cy1 = s > r;
2948     t = s - cy;
2949     cy2 = t > s;
2950     cy = cy1 | cy2;
2951     z[2] = t;
2952     return cy;
2953 }
2954 #endif /* !defined(HAVE_native_mpfq_fixmp_3_sub) */
2955 
2956 #if !defined(HAVE_native_mpfq_fixmp_3_add_nc)
2957 /* x, y, and z have 3 words. Result in z. Carry bit is lost. */
2958 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
2959 static inline
mpfq_fixmp_3_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2960 void mpfq_fixmp_3_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2961 {
2962     mp_limb_t r, s, t, cy, cy1, cy2;
2963     cy = 0;
2964     r = x[0];
2965     s = r + y[0];
2966     cy1 = s < r;
2967     t = s + cy;
2968     cy2 = t < s;
2969     cy = cy1 | cy2;
2970     z[0] = t;
2971     r = x[1];
2972     s = r + y[1];
2973     cy1 = s < r;
2974     t = s + cy;
2975     cy2 = t < s;
2976     cy = cy1 | cy2;
2977     z[1] = t;
2978     r = x[2];
2979     s = r + y[2];
2980     cy1 = s < r;
2981     t = s + cy;
2982     cy2 = t < s;
2983     cy = cy1 | cy2;
2984     z[2] = t;
2985 }
2986 #endif /* !defined(HAVE_native_mpfq_fixmp_3_add_nc) */
2987 
2988 #if !defined(HAVE_native_mpfq_fixmp_3_sub_nc)
2989 /* x, y, and z have 3 words. Result in z. Borrow bit is lost. */
2990 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
2991 static inline
mpfq_fixmp_3_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)2992 void mpfq_fixmp_3_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
2993 {
2994     mp_limb_t r, s, t, cy, cy1, cy2;
2995     cy = 0;
2996     r = x[0];
2997     s = r - y[0];
2998     cy1 = s > r;
2999     t = s - cy;
3000     cy2 = t > s;
3001     cy = cy1 | cy2;
3002     z[0] = t;
3003     r = x[1];
3004     s = r - y[1];
3005     cy1 = s > r;
3006     t = s - cy;
3007     cy2 = t > s;
3008     cy = cy1 | cy2;
3009     z[1] = t;
3010     r = x[2];
3011     s = r - y[2];
3012     cy1 = s > r;
3013     t = s - cy;
3014     cy2 = t > s;
3015     cy = cy1 | cy2;
3016     z[2] = t;
3017 }
3018 #endif /* !defined(HAVE_native_mpfq_fixmp_3_sub_nc) */
3019 
3020 #if !defined(HAVE_native_mpfq_fixmp_3_add_ui)
3021 /* x, y, and z have 3 words. Result in z. Return carry bit */
3022 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
3023 static inline
mpfq_fixmp_3_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3024 mp_limb_t mpfq_fixmp_3_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3025 {
3026     mp_limb_t r, s, t, cy, cy1, cy2;
3027     cy = 0;
3028     r = x[0];
3029     s = r + y;
3030     cy1 = s < r;
3031     t = s + cy;
3032     cy2 = t < s;
3033     cy = cy1 | cy2;
3034     z[0] = t;
3035     s = x[1];
3036     t = s + cy;
3037     cy = t < s;
3038     z[1] = t;
3039     s = x[2];
3040     t = s + cy;
3041     cy = t < s;
3042     z[2] = t;
3043     return cy;
3044 }
3045 #endif /* !defined(HAVE_native_mpfq_fixmp_3_add_ui) */
3046 
3047 #if !defined(HAVE_native_mpfq_fixmp_3_sub_ui)
3048 /* x, y, and z have 3 words. Result in z. Return borrow bit */
3049 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
3050 static inline
mpfq_fixmp_3_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3051 mp_limb_t mpfq_fixmp_3_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3052 {
3053     mp_limb_t r, s, t, cy, cy1, cy2;
3054     cy = 0;
3055     r = x[0];
3056     s = r - y;
3057     cy1 = s > r;
3058     t = s - cy;
3059     cy2 = t > s;
3060     cy = cy1 | cy2;
3061     z[0] = t;
3062     s = x[1];
3063     t = s - cy;
3064     cy = t > s;
3065     z[1] = t;
3066     s = x[2];
3067     t = s - cy;
3068     cy = t > s;
3069     z[2] = t;
3070     return cy;
3071 }
3072 #endif /* !defined(HAVE_native_mpfq_fixmp_3_sub_ui) */
3073 
3074 #if !defined(HAVE_native_mpfq_fixmp_3_add_ui_nc)
3075 /* x, y, and z have 3 words. Result in z. Carry bit is lost. */
3076 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
3077 static inline
mpfq_fixmp_3_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3078 void mpfq_fixmp_3_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3079 {
3080     mp_limb_t r, s, t, cy, cy1, cy2;
3081     cy = 0;
3082     r = x[0];
3083     s = r + y;
3084     cy1 = s < r;
3085     t = s + cy;
3086     cy2 = t < s;
3087     cy = cy1 | cy2;
3088     z[0] = t;
3089     s = x[1];
3090     t = s + cy;
3091     cy = t < s;
3092     z[1] = t;
3093     s = x[2];
3094     t = s + cy;
3095     cy = t < s;
3096     z[2] = t;
3097 }
3098 #endif /* !defined(HAVE_native_mpfq_fixmp_3_add_ui_nc) */
3099 
3100 #if !defined(HAVE_native_mpfq_fixmp_3_sub_ui_nc)
3101 /* x, y, and z have 3 words. Result in z. Borrow bit is lost. */
3102 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
3103 static inline
mpfq_fixmp_3_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3104 void mpfq_fixmp_3_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3105 {
3106     mp_limb_t r, s, t, cy, cy1, cy2;
3107     cy = 0;
3108     r = x[0];
3109     s = r - y;
3110     cy1 = s > r;
3111     t = s - cy;
3112     cy2 = t > s;
3113     cy = cy1 | cy2;
3114     z[0] = t;
3115     s = x[1];
3116     t = s - cy;
3117     cy = t > s;
3118     z[1] = t;
3119     s = x[2];
3120     t = s - cy;
3121     cy = t > s;
3122     z[2] = t;
3123 }
3124 #endif /* !defined(HAVE_native_mpfq_fixmp_3_sub_ui_nc) */
3125 
3126 #if !defined(HAVE_native_mpfq_fixmp_3_cmp)
3127 /* x and y have 3 words. Return sign of difference x-y. */
3128 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
3129 /* Triggered by: 3_invmod, 3_redc */
3130 static inline
mpfq_fixmp_3_cmp(const mp_limb_t * x,const mp_limb_t * y)3131 int mpfq_fixmp_3_cmp(const mp_limb_t * x, const mp_limb_t * y)
3132 {
3133     for (int i = 3-1; i >= 0; --i) {
3134         if (x[i] > y[i]) return 1;
3135         if (x[i] < y[i]) return -1;
3136     }
3137     return 0;
3138 }
3139 #endif /* !defined(HAVE_native_mpfq_fixmp_3_cmp) */
3140 
3141 #if !defined(HAVE_native_mpfq_fixmp_3_cmp_ui)
3142 /* x has 3 words. Return sign of difference x-y. */
3143 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
3144 /* Triggered by: 3_invmod */
3145 static inline
mpfq_fixmp_3_cmp_ui(const mp_limb_t * x,mp_limb_t y)3146 int mpfq_fixmp_3_cmp_ui(const mp_limb_t * x, mp_limb_t y)
3147 {
3148     for (int i = 3-1; i > 0; --i) {
3149         if (x[i]) return 1;
3150     }
3151     if (x[0]>y) return 1;
3152     if (x[0]<y) return -1;
3153     return 0;
3154 }
3155 #endif /* !defined(HAVE_native_mpfq_fixmp_3_cmp_ui) */
3156 
3157 #if !defined(HAVE_native_mpfq_fixmp_3_addmul1)
3158 /* x has 3 words, z has 5.
3159  * Put (z+x*c) in z. Return carry bit. */
3160 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
3161 /* Triggered by: 3_redc_ur */
3162 static inline
mpfq_fixmp_3_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3163 mp_limb_t mpfq_fixmp_3_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3164 {
3165     mp_limb_t hi, lo, carry, buf;
3166     carry = 0;
3167     mpfq_umul_ppmm(hi,lo,c,x[0]);
3168     lo += carry;
3169     carry = (lo<carry) + hi;
3170     buf = z[0];
3171     lo += buf;
3172     carry += (lo<buf);
3173     z[0] = lo;
3174     mpfq_umul_ppmm(hi,lo,c,x[1]);
3175     lo += carry;
3176     carry = (lo<carry) + hi;
3177     buf = z[1];
3178     lo += buf;
3179     carry += (lo<buf);
3180     z[1] = lo;
3181     mpfq_umul_ppmm(hi,lo,c,x[2]);
3182     lo += carry;
3183     carry = (lo<carry) + hi;
3184     buf = z[2];
3185     lo += buf;
3186     carry += (lo<buf);
3187     z[2] = lo;
3188     z[3] += carry;
3189     return (z[3]<carry);
3190 }
3191 #endif /* !defined(HAVE_native_mpfq_fixmp_3_addmul1) */
3192 
3193 #if !defined(HAVE_native_mpfq_fixmp_3_addmul1_nc)
3194 /* x has 3 words, z has 5.
3195  * Put (z+x*c) in z. Carry bit is lost. */
3196 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
3197 /* Triggered by: 3_mul, 3_mgy_decode, 4_sqr, 4_shortmul, 5_sqr, 5_shortmul, 6_sqr, 6_shortmul, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 3_5_sqr, 3_5_shortmul, 4_5_sqr, 4_5_shortmul, 5_5_sqr, 5_5_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
3198 static inline
mpfq_fixmp_3_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3199 void mpfq_fixmp_3_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3200 {
3201     mp_limb_t hi, lo, carry, buf;
3202     carry = 0;
3203     mpfq_umul_ppmm(hi,lo,c,x[0]);
3204     lo += carry;
3205     carry = (lo<carry) + hi;
3206     buf = z[0];
3207     lo += buf;
3208     carry += (lo<buf);
3209     z[0] = lo;
3210     mpfq_umul_ppmm(hi,lo,c,x[1]);
3211     lo += carry;
3212     carry = (lo<carry) + hi;
3213     buf = z[1];
3214     lo += buf;
3215     carry += (lo<buf);
3216     z[1] = lo;
3217     mpfq_umul_ppmm(hi,lo,c,x[2]);
3218     lo += carry;
3219     carry = (lo<carry) + hi;
3220     buf = z[2];
3221     lo += buf;
3222     carry += (lo<buf);
3223     z[2] = lo;
3224     z[3] += carry;
3225 }
3226 #endif /* !defined(HAVE_native_mpfq_fixmp_3_addmul1_nc) */
3227 
3228 #if !defined(HAVE_native_mpfq_fixmp_3_addmul1_shortz)
3229 /* x has 3 words, z has 4.
3230  * Put (z+x*c) in z. Return carry word. */
3231 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
3232 /* Triggered by: 3_redc */
3233 static inline
mpfq_fixmp_3_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3234 mp_limb_t mpfq_fixmp_3_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3235 {
3236     mp_limb_t hi, lo, carry, buf;
3237     carry = 0;
3238     mpfq_umul_ppmm(hi,lo,c,x[0]);
3239     lo += carry;
3240     carry = (lo<carry) + hi;
3241     buf = z[0];
3242     lo += buf;
3243     carry += (lo<buf);
3244     z[0] = lo;
3245     mpfq_umul_ppmm(hi,lo,c,x[1]);
3246     lo += carry;
3247     carry = (lo<carry) + hi;
3248     buf = z[1];
3249     lo += buf;
3250     carry += (lo<buf);
3251     z[1] = lo;
3252     mpfq_umul_ppmm(hi,lo,c,x[2]);
3253     lo += carry;
3254     carry = (lo<carry) + hi;
3255     buf = z[2];
3256     lo += buf;
3257     carry += (lo<buf);
3258     z[2] = lo;
3259     return carry;
3260 }
3261 #endif /* !defined(HAVE_native_mpfq_fixmp_3_addmul1_shortz) */
3262 
3263 #if !defined(HAVE_native_mpfq_fixmp_3_mul)
3264 /* x and y have 3 words, z has 8. Put x*y in z. */
3265 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
3266 /* Triggered by: 3_mgy_decode */
3267 static inline
mpfq_fixmp_3_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3268 void mpfq_fixmp_3_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3269 {
3270     assert(z != x && z != y);
3271     for (int i = 0; i < 6; z[i++] = 0) ;
3272     mpfq_fixmp_3_addmul1_nc (z + 0, x, y[0]);
3273     mpfq_fixmp_3_addmul1_nc (z + 1, x, y[1]);
3274     mpfq_fixmp_3_addmul1_nc (z + 2, x, y[2]);
3275 }
3276 #endif /* !defined(HAVE_native_mpfq_fixmp_3_mul) */
3277 
3278 #if !defined(HAVE_native_mpfq_fixmp_3_sqr)
3279 /* x has 3 words, z has 8. Put x*y in z. */
3280 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
3281 static inline
mpfq_fixmp_3_sqr(mp_limb_t * z,const mp_limb_t * x)3282 void mpfq_fixmp_3_sqr(mp_limb_t * z, const mp_limb_t * x)
3283 {
3284     mp_limb_t buf[6] = {0,};
3285     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
3286     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
3287     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
3288     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
3289     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
3290     mpn_lshift(buf, buf, 6, 1);
3291     mpn_add_n(z, z, buf, 6);
3292 }
3293 #endif /* !defined(HAVE_native_mpfq_fixmp_3_sqr) */
3294 
3295 #if !defined(HAVE_native_mpfq_fixmp_3_mul1)
3296 /* x has 3 words, z has 5. Put x*y in z. */
3297 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
3298 static inline
mpfq_fixmp_3_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3299 void mpfq_fixmp_3_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3300 {
3301     mp_limb_t hi, lo, carry;
3302     carry = 0;
3303     mpfq_umul_ppmm(hi,lo,c,x[0]);
3304     lo += carry;
3305     carry = (lo<carry) + hi;
3306     z[0] = lo;
3307     mpfq_umul_ppmm(hi,lo,c,x[1]);
3308     lo += carry;
3309     carry = (lo<carry) + hi;
3310     z[1] = lo;
3311     mpfq_umul_ppmm(hi,lo,c,x[2]);
3312     lo += carry;
3313     carry = (lo<carry) + hi;
3314     z[2] = lo;
3315     z[3] = carry;
3316 }
3317 #endif /* !defined(HAVE_native_mpfq_fixmp_3_mul1) */
3318 
3319 #if !defined(HAVE_native_mpfq_fixmp_3_shortmul)
3320 /* x and y have 3 words, z has 4.
3321  * Put the low 4 words of x*y in z. */
3322 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
3323 static inline
mpfq_fixmp_3_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3324 void mpfq_fixmp_3_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3325 {
3326     mpfq_zero(z, 3);
3327     mpfq_fixmp_2_addmul1_nc (z+0, x, y[0]);
3328     z[3-1] += x[2]*y[0];
3329     mpfq_fixmp_1_addmul1_nc (z+1, x, y[1]);
3330     z[3-1] += x[1]*y[1];
3331     z[3-1] += x[0]*y[3-1];
3332 }
3333 #endif /* !defined(HAVE_native_mpfq_fixmp_3_shortmul) */
3334 
3335 #if !defined(HAVE_native_mpfq_fixmp_3_mod)
3336 /* x has 8 words. z and p have 3 words, and the high word of p is non-zero.
3337  * Put x mod p in z. */
3338 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
3339 /* Triggered by: 3_mgy_decode */
3340 static inline
mpfq_fixmp_3_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)3341 void mpfq_fixmp_3_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
3342 {
3343     mp_limb_t q[3+1], r[3];
3344     assert (p[3-1] != 0);
3345     mpn_tdiv_qr(q, r, 0, x, 6, p, 3);
3346     mpfq_copy(z, r, 3);
3347 }
3348 #endif /* !defined(HAVE_native_mpfq_fixmp_3_mod) */
3349 
3350 #if !defined(HAVE_native_mpfq_fixmp_3_rshift)
3351 /* a has 3 words. Shift it in place by cnt bits to the right.
3352  * The shift count cnt must not exceed the word size.
3353  * Note that no carry is returned for the bits shifted out. */
3354 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
3355 /* Triggered by: 3_invmod */
3356 static inline
mpfq_fixmp_3_rshift(mp_limb_t * a,int cnt)3357 void mpfq_fixmp_3_rshift(mp_limb_t * a, int cnt)
3358 {
3359     if (!cnt) return;
3360     int i;
3361     int dnt = GMP_NUMB_BITS - cnt;
3362     for (i = 0; i < 3-1; ++i) {
3363         a[i] >>= cnt;
3364         a[i] |= (a[i+1] << dnt);
3365     }
3366     a[3-1] >>= cnt;
3367 }
3368 #endif /* !defined(HAVE_native_mpfq_fixmp_3_rshift) */
3369 
3370 #if !defined(HAVE_native_mpfq_fixmp_3_long_rshift)
3371 /* a has 3 words. Shift it in place by off words plus cnt bits to the left.
3372  * Note that no carry is returned for the bits shifted out. */
3373 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
3374 /* Triggered by: 3_invmod */
3375 static inline
mpfq_fixmp_3_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)3376 void mpfq_fixmp_3_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
3377 {
3378     if (cnt) {
3379         int dnt = GMP_NUMB_BITS - cnt;
3380         for (int i = 0; i < 3 - off - 1; ++i) {
3381             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
3382         }
3383         a[3-off-1] = a[3-1]>>cnt;
3384     } else {
3385         mpfq_copyi(a, a + off, 3 - off);
3386     }
3387     mpfq_zero(a + 3 - off, off);
3388 }
3389 #endif /* !defined(HAVE_native_mpfq_fixmp_3_long_rshift) */
3390 
3391 #if !defined(HAVE_native_mpfq_fixmp_3_long_lshift)
3392 /* a has 3 words. Shift it in place by off words plus cnt bits to the left.
3393  * Note that no carry is returned for the bits shifted out. */
3394 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
3395 /* Triggered by: 3_invmod */
3396 static inline
mpfq_fixmp_3_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)3397 void mpfq_fixmp_3_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
3398 {
3399     int i;
3400     if (cnt) {
3401         int dnt = GMP_NUMB_BITS - cnt;
3402         for (i = 3-1; i>off; --i) {
3403             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
3404         }
3405         a[off] = a[0]<<cnt;
3406     } else {
3407         mpfq_copyd(a + off, a, 3 - off);
3408     }
3409     mpfq_zero(a, off);
3410 }
3411 #endif /* !defined(HAVE_native_mpfq_fixmp_3_long_lshift) */
3412 
3413 #if !defined(HAVE_native_mpfq_fixmp_3_invmod)
3414 /* x, z, and p have 3 words. Put inverse of x mod p in z.
3415  * Return non-zero if an inverse could be found.
3416  * If no inverse could be found, return 0 and set z to zero.
3417  */
3418 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
3419 static inline
mpfq_fixmp_3_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)3420 int mpfq_fixmp_3_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
3421 {
3422       mp_limb_t u[3], v[3], a[3], b[3], fix[3];
3423       int i, t, lsh;
3424 
3425       mpfq_zero(u, 3);
3426       mpfq_zero(v, 3);
3427       mpfq_copy(a, x, 3);
3428       mpfq_copy(b, p, 3);
3429       u[0] = 1UL;
3430 
3431       if (mpfq_fixmp_3_cmp(a, v) == 0 || mpfq_fixmp_3_cmp(a, b) == 0) {
3432         mpfq_zero(res, 3);
3433         return 0;
3434       }
3435 
3436       mpfq_fixmp_3_add(fix, b, u);
3437       mpfq_fixmp_3_rshift(fix, 1);
3438 
3439       assert (mpfq_fixmp_3_cmp(a,b) < 0);
3440 
3441       t = 0;
3442 
3443       for(i = 0 ; !a[i] ; i++) ;
3444       assert (i < 3);
3445       lsh = mpfq_ctzl(a[i]);
3446       mpfq_fixmp_3_long_rshift(a, i, lsh);
3447       t += lsh + i*GMP_NUMB_BITS;
3448       mpfq_fixmp_3_long_lshift(v, i, lsh);
3449 
3450       do {
3451         do {
3452           mpfq_fixmp_3_sub(b, b, a);
3453           mpfq_fixmp_3_add(v, v, u);
3454           for(i = 0 ; !b[i] ; i++) ;
3455           assert (i < 3);
3456           lsh = mpfq_ctzl(b[i]);
3457           mpfq_fixmp_3_long_rshift(b, i, lsh);
3458           t += lsh + i*GMP_NUMB_BITS;
3459           mpfq_fixmp_3_long_lshift(u, i, lsh);
3460         } while (mpfq_fixmp_3_cmp(a,b) < 0);
3461         if (mpfq_fixmp_3_cmp(a, b) == 0)
3462           break;
3463         do {
3464           mpfq_fixmp_3_sub(a, a, b);
3465           mpfq_fixmp_3_add(u, u, v);
3466           for(i = 0 ; !a[i] ; i++) ;
3467           assert (i < 3);
3468           lsh = mpfq_ctzl(a[i]);
3469           mpfq_fixmp_3_long_rshift(a, i, lsh);
3470           t += lsh + i*GMP_NUMB_BITS;
3471           mpfq_fixmp_3_long_lshift(v, i, lsh);
3472         } while (mpfq_fixmp_3_cmp(b,a)<0);
3473       } while (mpfq_fixmp_3_cmp(a,b) != 0);
3474       {
3475         if (mpfq_fixmp_3_cmp_ui(a, 1) != 0) {
3476           mpfq_copy(res, a, 3);
3477           return 0;
3478         }
3479       }
3480       while (t>0) {
3481         mp_limb_t sig = u[0] & 1UL;
3482         mpfq_fixmp_3_rshift(u, 1);
3483         if (sig)
3484           mpfq_fixmp_3_add(u, u, fix);
3485         --t;
3486       }
3487       mpfq_copy(res, u, 3);
3488       return 1;
3489 }
3490 #endif /* !defined(HAVE_native_mpfq_fixmp_3_invmod) */
3491 
3492 #if !defined(HAVE_native_mpfq_fixmp_3_redc)
3493 /* x has 8 words, z and p have 3 words.
3494  * only one word is read from invp.
3495  * Assuming R=W^4 is the redc modulus, we expect that x verifies:
3496  *   x < R*p,
3497  * so that we have eventually z < p, z congruent to x/R mod p.
3498  * The contents of the area pointed by x are clobbered by this call.
3499  * Note also that x may alias z.
3500  */
3501 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
3502 static inline
mpfq_fixmp_3_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)3503 void mpfq_fixmp_3_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
3504 {
3505     mp_limb_t cy;
3506     for(int i = 0; i < 3; ++i) {
3507         mp_limb_t t = x[i]*mip[0];
3508         cy = mpfq_fixmp_3_addmul1_shortz(x+i, p, t);
3509         assert (x[i] == 0);
3510         x[i] = cy;
3511     }
3512     cy = mpfq_fixmp_3_add(x, x, x + 3);
3513     /* At this point, we have (x' denotes x + cy*W^n here)
3514     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
3515     * x'/R < p + p
3516     */
3517     if (cy || mpfq_fixmp_3_cmp(x, p) >= 0) {
3518         mpfq_fixmp_3_sub(z, x, p);
3519     } else {
3520         mpfq_copy(z, x, 3);
3521     }
3522 }
3523 #endif /* !defined(HAVE_native_mpfq_fixmp_3_redc) */
3524 
3525 #if !defined(HAVE_native_mpfq_fixmp_3_redc_ur)
3526 /* x has 9 words, z and p have 3 words.
3527  * only one word is read from invp.
3528  * Assuming R=W^4 is the redc modulus, we expect that x verifies:
3529  *  x < W*W^3*p = W^0.5*R*p or the hw case, W*R*p otherwise,
3530  * so that we have eventually z < p, z congruent to x/R mod p.
3531  * The contents of the area pointed by x are clobbered by this call.
3532  * Note also that x may alias z.
3533  */
3534 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
3535 static inline
mpfq_fixmp_3_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)3536 void mpfq_fixmp_3_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
3537 {
3538     mp_limb_t cy, q[2];
3539     for (int i = 0; i < 3; ++i) {
3540         mp_limb_t t = x[i]*mip[0];
3541         cy = mpfq_fixmp_3_addmul1(x+i, p, t);
3542         assert (x[i] == 0);
3543         x[i] = cy;
3544     }
3545     cy=mpfq_fixmp_3_add(x+3+1, x+3+1, x);
3546     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
3547     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
3548     * x'/R < (W+1)*p
3549     */
3550     if (cy) {
3551         /* x'/R-p < W*p, which fits in n+1 words */
3552         mpn_sub(x+3,x+3,3+1,p,3);
3553     }
3554     mpn_tdiv_qr(q, z, 0, x+3, 3+1, p, 3);
3555 }
3556 #endif /* !defined(HAVE_native_mpfq_fixmp_3_redc_ur) */
3557 
3558 #if !defined(HAVE_native_mpfq_fixmp_3_mgy_encode)
3559 /* x, z, and p have 3 words.
3560  * Assuming R=W^4 is the redc modulus, we compute z=R*x mod p. */
3561 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
3562 static inline
mpfq_fixmp_3_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)3563 void mpfq_fixmp_3_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
3564 {
3565     mp_limb_t t[6] = { 0, 0, 0, x[0], x[1], x[2] };
3566     mpfq_fixmp_3_mod(z, t, p);
3567 }
3568 #endif /* !defined(HAVE_native_mpfq_fixmp_3_mgy_encode) */
3569 
3570 #if !defined(HAVE_native_mpfq_fixmp_3_mgy_decode)
3571 /* x, z, invR, and p have 3 words.
3572  * Assuming R=W^4 is the redc modulus, we compute z=x/R mod p. */
3573 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
3574 static inline
mpfq_fixmp_3_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)3575 void mpfq_fixmp_3_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
3576 {
3577     mp_limb_t t[6];
3578     mpfq_fixmp_3_mul(t, x, invR);
3579     mpfq_fixmp_3_mod(z, t, p);
3580 }
3581 #endif /* !defined(HAVE_native_mpfq_fixmp_3_mgy_decode) */
3582 
3583 #if !defined(HAVE_native_mpfq_fixmp_3_lshift)
3584 /* a has 3 words. Shift it in place by cnt bits to the left.
3585  * The shift count cnt must not exceed the word size.
3586  * Note that no carry is returned for the bits shifted out. */
3587 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
3588 static inline
mpfq_fixmp_3_lshift(mp_limb_t * a,int cnt)3589 void mpfq_fixmp_3_lshift(mp_limb_t * a, int cnt)
3590 {
3591     if (!cnt) return;
3592     int i;
3593     int dnt = GMP_NUMB_BITS - cnt;
3594     for (i = 3-1; i>0; --i) {
3595         a[i] <<= cnt;
3596         a[i] |= (a[i-1] >> dnt);
3597     }
3598     a[0] <<= cnt;
3599 }
3600 #endif /* !defined(HAVE_native_mpfq_fixmp_3_lshift) */
3601 
3602 #if !defined(HAVE_native_mpfq_fixmp_4_add)
3603 /* x, y, and z have 4 words. Result in z. Return carry bit */
3604 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
3605 /* Triggered by: 4_invmod, 4_redc, 4_redc_ur */
3606 static inline
mpfq_fixmp_4_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3607 mp_limb_t mpfq_fixmp_4_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3608 {
3609     mp_limb_t r, s, t, cy, cy1, cy2;
3610     cy = 0;
3611     r = x[0];
3612     s = r + y[0];
3613     cy1 = s < r;
3614     t = s + cy;
3615     cy2 = t < s;
3616     cy = cy1 | cy2;
3617     z[0] = t;
3618     r = x[1];
3619     s = r + y[1];
3620     cy1 = s < r;
3621     t = s + cy;
3622     cy2 = t < s;
3623     cy = cy1 | cy2;
3624     z[1] = t;
3625     r = x[2];
3626     s = r + y[2];
3627     cy1 = s < r;
3628     t = s + cy;
3629     cy2 = t < s;
3630     cy = cy1 | cy2;
3631     z[2] = t;
3632     r = x[3];
3633     s = r + y[3];
3634     cy1 = s < r;
3635     t = s + cy;
3636     cy2 = t < s;
3637     cy = cy1 | cy2;
3638     z[3] = t;
3639     return cy;
3640 }
3641 #endif /* !defined(HAVE_native_mpfq_fixmp_4_add) */
3642 
3643 #if !defined(HAVE_native_mpfq_fixmp_4_sub)
3644 /* x, y, and z have 4 words. Result in z. Return borrow bit */
3645 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
3646 /* Triggered by: 4_invmod, 4_redc */
3647 static inline
mpfq_fixmp_4_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3648 mp_limb_t mpfq_fixmp_4_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3649 {
3650     mp_limb_t r, s, t, cy, cy1, cy2;
3651     cy = 0;
3652     r = x[0];
3653     s = r - y[0];
3654     cy1 = s > r;
3655     t = s - cy;
3656     cy2 = t > s;
3657     cy = cy1 | cy2;
3658     z[0] = t;
3659     r = x[1];
3660     s = r - y[1];
3661     cy1 = s > r;
3662     t = s - cy;
3663     cy2 = t > s;
3664     cy = cy1 | cy2;
3665     z[1] = t;
3666     r = x[2];
3667     s = r - y[2];
3668     cy1 = s > r;
3669     t = s - cy;
3670     cy2 = t > s;
3671     cy = cy1 | cy2;
3672     z[2] = t;
3673     r = x[3];
3674     s = r - y[3];
3675     cy1 = s > r;
3676     t = s - cy;
3677     cy2 = t > s;
3678     cy = cy1 | cy2;
3679     z[3] = t;
3680     return cy;
3681 }
3682 #endif /* !defined(HAVE_native_mpfq_fixmp_4_sub) */
3683 
3684 #if !defined(HAVE_native_mpfq_fixmp_4_add_nc)
3685 /* x, y, and z have 4 words. Result in z. Carry bit is lost. */
3686 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
3687 static inline
mpfq_fixmp_4_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3688 void mpfq_fixmp_4_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3689 {
3690     mp_limb_t r, s, t, cy, cy1, cy2;
3691     cy = 0;
3692     r = x[0];
3693     s = r + y[0];
3694     cy1 = s < r;
3695     t = s + cy;
3696     cy2 = t < s;
3697     cy = cy1 | cy2;
3698     z[0] = t;
3699     r = x[1];
3700     s = r + y[1];
3701     cy1 = s < r;
3702     t = s + cy;
3703     cy2 = t < s;
3704     cy = cy1 | cy2;
3705     z[1] = t;
3706     r = x[2];
3707     s = r + y[2];
3708     cy1 = s < r;
3709     t = s + cy;
3710     cy2 = t < s;
3711     cy = cy1 | cy2;
3712     z[2] = t;
3713     r = x[3];
3714     s = r + y[3];
3715     cy1 = s < r;
3716     t = s + cy;
3717     cy2 = t < s;
3718     cy = cy1 | cy2;
3719     z[3] = t;
3720 }
3721 #endif /* !defined(HAVE_native_mpfq_fixmp_4_add_nc) */
3722 
3723 #if !defined(HAVE_native_mpfq_fixmp_4_sub_nc)
3724 /* x, y, and z have 4 words. Result in z. Borrow bit is lost. */
3725 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
3726 static inline
mpfq_fixmp_4_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)3727 void mpfq_fixmp_4_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
3728 {
3729     mp_limb_t r, s, t, cy, cy1, cy2;
3730     cy = 0;
3731     r = x[0];
3732     s = r - y[0];
3733     cy1 = s > r;
3734     t = s - cy;
3735     cy2 = t > s;
3736     cy = cy1 | cy2;
3737     z[0] = t;
3738     r = x[1];
3739     s = r - y[1];
3740     cy1 = s > r;
3741     t = s - cy;
3742     cy2 = t > s;
3743     cy = cy1 | cy2;
3744     z[1] = t;
3745     r = x[2];
3746     s = r - y[2];
3747     cy1 = s > r;
3748     t = s - cy;
3749     cy2 = t > s;
3750     cy = cy1 | cy2;
3751     z[2] = t;
3752     r = x[3];
3753     s = r - y[3];
3754     cy1 = s > r;
3755     t = s - cy;
3756     cy2 = t > s;
3757     cy = cy1 | cy2;
3758     z[3] = t;
3759 }
3760 #endif /* !defined(HAVE_native_mpfq_fixmp_4_sub_nc) */
3761 
3762 #if !defined(HAVE_native_mpfq_fixmp_4_add_ui)
3763 /* x, y, and z have 4 words. Result in z. Return carry bit */
3764 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
3765 static inline
mpfq_fixmp_4_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3766 mp_limb_t mpfq_fixmp_4_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3767 {
3768     mp_limb_t r, s, t, cy, cy1, cy2;
3769     cy = 0;
3770     r = x[0];
3771     s = r + y;
3772     cy1 = s < r;
3773     t = s + cy;
3774     cy2 = t < s;
3775     cy = cy1 | cy2;
3776     z[0] = t;
3777     s = x[1];
3778     t = s + cy;
3779     cy = t < s;
3780     z[1] = t;
3781     s = x[2];
3782     t = s + cy;
3783     cy = t < s;
3784     z[2] = t;
3785     s = x[3];
3786     t = s + cy;
3787     cy = t < s;
3788     z[3] = t;
3789     return cy;
3790 }
3791 #endif /* !defined(HAVE_native_mpfq_fixmp_4_add_ui) */
3792 
3793 #if !defined(HAVE_native_mpfq_fixmp_4_sub_ui)
3794 /* x, y, and z have 4 words. Result in z. Return borrow bit */
3795 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
3796 static inline
mpfq_fixmp_4_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3797 mp_limb_t mpfq_fixmp_4_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3798 {
3799     mp_limb_t r, s, t, cy, cy1, cy2;
3800     cy = 0;
3801     r = x[0];
3802     s = r - y;
3803     cy1 = s > r;
3804     t = s - cy;
3805     cy2 = t > s;
3806     cy = cy1 | cy2;
3807     z[0] = t;
3808     s = x[1];
3809     t = s - cy;
3810     cy = t > s;
3811     z[1] = t;
3812     s = x[2];
3813     t = s - cy;
3814     cy = t > s;
3815     z[2] = t;
3816     s = x[3];
3817     t = s - cy;
3818     cy = t > s;
3819     z[3] = t;
3820     return cy;
3821 }
3822 #endif /* !defined(HAVE_native_mpfq_fixmp_4_sub_ui) */
3823 
3824 #if !defined(HAVE_native_mpfq_fixmp_4_add_ui_nc)
3825 /* x, y, and z have 4 words. Result in z. Carry bit is lost. */
3826 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
3827 static inline
mpfq_fixmp_4_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3828 void mpfq_fixmp_4_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3829 {
3830     mp_limb_t r, s, t, cy, cy1, cy2;
3831     cy = 0;
3832     r = x[0];
3833     s = r + y;
3834     cy1 = s < r;
3835     t = s + cy;
3836     cy2 = t < s;
3837     cy = cy1 | cy2;
3838     z[0] = t;
3839     s = x[1];
3840     t = s + cy;
3841     cy = t < s;
3842     z[1] = t;
3843     s = x[2];
3844     t = s + cy;
3845     cy = t < s;
3846     z[2] = t;
3847     s = x[3];
3848     t = s + cy;
3849     cy = t < s;
3850     z[3] = t;
3851 }
3852 #endif /* !defined(HAVE_native_mpfq_fixmp_4_add_ui_nc) */
3853 
3854 #if !defined(HAVE_native_mpfq_fixmp_4_sub_ui_nc)
3855 /* x, y, and z have 4 words. Result in z. Borrow bit is lost. */
3856 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
3857 static inline
mpfq_fixmp_4_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)3858 void mpfq_fixmp_4_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
3859 {
3860     mp_limb_t r, s, t, cy, cy1, cy2;
3861     cy = 0;
3862     r = x[0];
3863     s = r - y;
3864     cy1 = s > r;
3865     t = s - cy;
3866     cy2 = t > s;
3867     cy = cy1 | cy2;
3868     z[0] = t;
3869     s = x[1];
3870     t = s - cy;
3871     cy = t > s;
3872     z[1] = t;
3873     s = x[2];
3874     t = s - cy;
3875     cy = t > s;
3876     z[2] = t;
3877     s = x[3];
3878     t = s - cy;
3879     cy = t > s;
3880     z[3] = t;
3881 }
3882 #endif /* !defined(HAVE_native_mpfq_fixmp_4_sub_ui_nc) */
3883 
3884 #if !defined(HAVE_native_mpfq_fixmp_4_cmp)
3885 /* x and y have 4 words. Return sign of difference x-y. */
3886 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
3887 /* Triggered by: 4_invmod, 4_redc */
3888 static inline
mpfq_fixmp_4_cmp(const mp_limb_t * x,const mp_limb_t * y)3889 int mpfq_fixmp_4_cmp(const mp_limb_t * x, const mp_limb_t * y)
3890 {
3891     for (int i = 4-1; i >= 0; --i) {
3892         if (x[i] > y[i]) return 1;
3893         if (x[i] < y[i]) return -1;
3894     }
3895     return 0;
3896 }
3897 #endif /* !defined(HAVE_native_mpfq_fixmp_4_cmp) */
3898 
3899 #if !defined(HAVE_native_mpfq_fixmp_4_cmp_ui)
3900 /* x has 4 words. Return sign of difference x-y. */
3901 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
3902 /* Triggered by: 4_invmod */
3903 static inline
mpfq_fixmp_4_cmp_ui(const mp_limb_t * x,mp_limb_t y)3904 int mpfq_fixmp_4_cmp_ui(const mp_limb_t * x, mp_limb_t y)
3905 {
3906     for (int i = 4-1; i > 0; --i) {
3907         if (x[i]) return 1;
3908     }
3909     if (x[0]>y) return 1;
3910     if (x[0]<y) return -1;
3911     return 0;
3912 }
3913 #endif /* !defined(HAVE_native_mpfq_fixmp_4_cmp_ui) */
3914 
3915 #if !defined(HAVE_native_mpfq_fixmp_4_addmul1)
3916 /* x has 4 words, z has 6.
3917  * Put (z+x*c) in z. Return carry bit. */
3918 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
3919 /* Triggered by: 4_redc_ur */
3920 static inline
mpfq_fixmp_4_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3921 mp_limb_t mpfq_fixmp_4_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3922 {
3923     mp_limb_t hi, lo, carry, buf;
3924     carry = 0;
3925     mpfq_umul_ppmm(hi,lo,c,x[0]);
3926     lo += carry;
3927     carry = (lo<carry) + hi;
3928     buf = z[0];
3929     lo += buf;
3930     carry += (lo<buf);
3931     z[0] = lo;
3932     mpfq_umul_ppmm(hi,lo,c,x[1]);
3933     lo += carry;
3934     carry = (lo<carry) + hi;
3935     buf = z[1];
3936     lo += buf;
3937     carry += (lo<buf);
3938     z[1] = lo;
3939     mpfq_umul_ppmm(hi,lo,c,x[2]);
3940     lo += carry;
3941     carry = (lo<carry) + hi;
3942     buf = z[2];
3943     lo += buf;
3944     carry += (lo<buf);
3945     z[2] = lo;
3946     mpfq_umul_ppmm(hi,lo,c,x[3]);
3947     lo += carry;
3948     carry = (lo<carry) + hi;
3949     buf = z[3];
3950     lo += buf;
3951     carry += (lo<buf);
3952     z[3] = lo;
3953     z[4] += carry;
3954     return (z[4]<carry);
3955 }
3956 #endif /* !defined(HAVE_native_mpfq_fixmp_4_addmul1) */
3957 
3958 #if !defined(HAVE_native_mpfq_fixmp_4_addmul1_nc)
3959 /* x has 4 words, z has 6.
3960  * Put (z+x*c) in z. Carry bit is lost. */
3961 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
3962 /* Triggered by: 4_mul, 4_mgy_decode, 5_sqr, 5_shortmul, 6_sqr, 6_shortmul, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 4_5_sqr, 4_5_shortmul, 5_5_sqr, 5_5_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
3963 static inline
mpfq_fixmp_4_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)3964 void mpfq_fixmp_4_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
3965 {
3966     mp_limb_t hi, lo, carry, buf;
3967     carry = 0;
3968     mpfq_umul_ppmm(hi,lo,c,x[0]);
3969     lo += carry;
3970     carry = (lo<carry) + hi;
3971     buf = z[0];
3972     lo += buf;
3973     carry += (lo<buf);
3974     z[0] = lo;
3975     mpfq_umul_ppmm(hi,lo,c,x[1]);
3976     lo += carry;
3977     carry = (lo<carry) + hi;
3978     buf = z[1];
3979     lo += buf;
3980     carry += (lo<buf);
3981     z[1] = lo;
3982     mpfq_umul_ppmm(hi,lo,c,x[2]);
3983     lo += carry;
3984     carry = (lo<carry) + hi;
3985     buf = z[2];
3986     lo += buf;
3987     carry += (lo<buf);
3988     z[2] = lo;
3989     mpfq_umul_ppmm(hi,lo,c,x[3]);
3990     lo += carry;
3991     carry = (lo<carry) + hi;
3992     buf = z[3];
3993     lo += buf;
3994     carry += (lo<buf);
3995     z[3] = lo;
3996     z[4] += carry;
3997 }
3998 #endif /* !defined(HAVE_native_mpfq_fixmp_4_addmul1_nc) */
3999 
4000 #if !defined(HAVE_native_mpfq_fixmp_4_addmul1_shortz)
4001 /* x has 4 words, z has 5.
4002  * Put (z+x*c) in z. Return carry word. */
4003 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
4004 /* Triggered by: 4_redc */
4005 static inline
mpfq_fixmp_4_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4006 mp_limb_t mpfq_fixmp_4_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4007 {
4008     mp_limb_t hi, lo, carry, buf;
4009     carry = 0;
4010     mpfq_umul_ppmm(hi,lo,c,x[0]);
4011     lo += carry;
4012     carry = (lo<carry) + hi;
4013     buf = z[0];
4014     lo += buf;
4015     carry += (lo<buf);
4016     z[0] = lo;
4017     mpfq_umul_ppmm(hi,lo,c,x[1]);
4018     lo += carry;
4019     carry = (lo<carry) + hi;
4020     buf = z[1];
4021     lo += buf;
4022     carry += (lo<buf);
4023     z[1] = lo;
4024     mpfq_umul_ppmm(hi,lo,c,x[2]);
4025     lo += carry;
4026     carry = (lo<carry) + hi;
4027     buf = z[2];
4028     lo += buf;
4029     carry += (lo<buf);
4030     z[2] = lo;
4031     mpfq_umul_ppmm(hi,lo,c,x[3]);
4032     lo += carry;
4033     carry = (lo<carry) + hi;
4034     buf = z[3];
4035     lo += buf;
4036     carry += (lo<buf);
4037     z[3] = lo;
4038     return carry;
4039 }
4040 #endif /* !defined(HAVE_native_mpfq_fixmp_4_addmul1_shortz) */
4041 
4042 #if !defined(HAVE_native_mpfq_fixmp_4_mul)
4043 /* x and y have 4 words, z has 10. Put x*y in z. */
4044 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
4045 /* Triggered by: 4_mgy_decode */
4046 static inline
mpfq_fixmp_4_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4047 void mpfq_fixmp_4_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4048 {
4049     assert(z != x && z != y);
4050     for (int i = 0; i < 8; z[i++] = 0) ;
4051     mpfq_fixmp_4_addmul1_nc (z + 0, x, y[0]);
4052     mpfq_fixmp_4_addmul1_nc (z + 1, x, y[1]);
4053     mpfq_fixmp_4_addmul1_nc (z + 2, x, y[2]);
4054     mpfq_fixmp_4_addmul1_nc (z + 3, x, y[3]);
4055 }
4056 #endif /* !defined(HAVE_native_mpfq_fixmp_4_mul) */
4057 
4058 #if !defined(HAVE_native_mpfq_fixmp_4_sqr)
4059 /* x has 4 words, z has 10. Put x*y in z. */
4060 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
4061 static inline
mpfq_fixmp_4_sqr(mp_limb_t * z,const mp_limb_t * x)4062 void mpfq_fixmp_4_sqr(mp_limb_t * z, const mp_limb_t * x)
4063 {
4064     mp_limb_t buf[8] = {0,};
4065     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
4066     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
4067     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
4068     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
4069     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
4070     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
4071     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
4072     mpn_lshift(buf, buf, 8, 1);
4073     mpn_add_n(z, z, buf, 8);
4074 }
4075 #endif /* !defined(HAVE_native_mpfq_fixmp_4_sqr) */
4076 
4077 #if !defined(HAVE_native_mpfq_fixmp_4_mul1)
4078 /* x has 4 words, z has 6. Put x*y in z. */
4079 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
4080 static inline
mpfq_fixmp_4_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4081 void mpfq_fixmp_4_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4082 {
4083     mp_limb_t hi, lo, carry;
4084     carry = 0;
4085     mpfq_umul_ppmm(hi,lo,c,x[0]);
4086     lo += carry;
4087     carry = (lo<carry) + hi;
4088     z[0] = lo;
4089     mpfq_umul_ppmm(hi,lo,c,x[1]);
4090     lo += carry;
4091     carry = (lo<carry) + hi;
4092     z[1] = lo;
4093     mpfq_umul_ppmm(hi,lo,c,x[2]);
4094     lo += carry;
4095     carry = (lo<carry) + hi;
4096     z[2] = lo;
4097     mpfq_umul_ppmm(hi,lo,c,x[3]);
4098     lo += carry;
4099     carry = (lo<carry) + hi;
4100     z[3] = lo;
4101     z[4] = carry;
4102 }
4103 #endif /* !defined(HAVE_native_mpfq_fixmp_4_mul1) */
4104 
4105 #if !defined(HAVE_native_mpfq_fixmp_4_shortmul)
4106 /* x and y have 4 words, z has 5.
4107  * Put the low 5 words of x*y in z. */
4108 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
4109 static inline
mpfq_fixmp_4_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4110 void mpfq_fixmp_4_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4111 {
4112     mpfq_zero(z, 4);
4113     mpfq_fixmp_3_addmul1_nc (z+0, x, y[0]);
4114     z[4-1] += x[3]*y[0];
4115     mpfq_fixmp_2_addmul1_nc (z+1, x, y[1]);
4116     z[4-1] += x[2]*y[1];
4117     mpfq_fixmp_1_addmul1_nc (z+2, x, y[2]);
4118     z[4-1] += x[1]*y[2];
4119     z[4-1] += x[0]*y[4-1];
4120 }
4121 #endif /* !defined(HAVE_native_mpfq_fixmp_4_shortmul) */
4122 
4123 #if !defined(HAVE_native_mpfq_fixmp_4_mod)
4124 /* x has 10 words. z and p have 4 words, and the high word of p is non-zero.
4125  * Put x mod p in z. */
4126 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
4127 /* Triggered by: 4_mgy_decode */
4128 static inline
mpfq_fixmp_4_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)4129 void mpfq_fixmp_4_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
4130 {
4131     mp_limb_t q[4+1], r[4];
4132     assert (p[4-1] != 0);
4133     mpn_tdiv_qr(q, r, 0, x, 8, p, 4);
4134     mpfq_copy(z, r, 4);
4135 }
4136 #endif /* !defined(HAVE_native_mpfq_fixmp_4_mod) */
4137 
4138 #if !defined(HAVE_native_mpfq_fixmp_4_rshift)
4139 /* a has 4 words. Shift it in place by cnt bits to the right.
4140  * The shift count cnt must not exceed the word size.
4141  * Note that no carry is returned for the bits shifted out. */
4142 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
4143 /* Triggered by: 4_invmod */
4144 static inline
mpfq_fixmp_4_rshift(mp_limb_t * a,int cnt)4145 void mpfq_fixmp_4_rshift(mp_limb_t * a, int cnt)
4146 {
4147     if (!cnt) return;
4148     int i;
4149     int dnt = GMP_NUMB_BITS - cnt;
4150     for (i = 0; i < 4-1; ++i) {
4151         a[i] >>= cnt;
4152         a[i] |= (a[i+1] << dnt);
4153     }
4154     a[4-1] >>= cnt;
4155 }
4156 #endif /* !defined(HAVE_native_mpfq_fixmp_4_rshift) */
4157 
4158 #if !defined(HAVE_native_mpfq_fixmp_4_long_rshift)
4159 /* a has 4 words. Shift it in place by off words plus cnt bits to the left.
4160  * Note that no carry is returned for the bits shifted out. */
4161 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
4162 /* Triggered by: 4_invmod */
4163 static inline
mpfq_fixmp_4_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)4164 void mpfq_fixmp_4_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
4165 {
4166     if (cnt) {
4167         int dnt = GMP_NUMB_BITS - cnt;
4168         for (int i = 0; i < 4 - off - 1; ++i) {
4169             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
4170         }
4171         a[4-off-1] = a[4-1]>>cnt;
4172     } else {
4173         mpfq_copyi(a, a + off, 4 - off);
4174     }
4175     mpfq_zero(a + 4 - off, off);
4176 }
4177 #endif /* !defined(HAVE_native_mpfq_fixmp_4_long_rshift) */
4178 
4179 #if !defined(HAVE_native_mpfq_fixmp_4_long_lshift)
4180 /* a has 4 words. Shift it in place by off words plus cnt bits to the left.
4181  * Note that no carry is returned for the bits shifted out. */
4182 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
4183 /* Triggered by: 4_invmod */
4184 static inline
mpfq_fixmp_4_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)4185 void mpfq_fixmp_4_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
4186 {
4187     int i;
4188     if (cnt) {
4189         int dnt = GMP_NUMB_BITS - cnt;
4190         for (i = 4-1; i>off; --i) {
4191             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
4192         }
4193         a[off] = a[0]<<cnt;
4194     } else {
4195         mpfq_copyd(a + off, a, 4 - off);
4196     }
4197     mpfq_zero(a, off);
4198 }
4199 #endif /* !defined(HAVE_native_mpfq_fixmp_4_long_lshift) */
4200 
4201 #if !defined(HAVE_native_mpfq_fixmp_4_invmod)
4202 /* x, z, and p have 4 words. Put inverse of x mod p in z.
4203  * Return non-zero if an inverse could be found.
4204  * If no inverse could be found, return 0 and set z to zero.
4205  */
4206 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
4207 static inline
mpfq_fixmp_4_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)4208 int mpfq_fixmp_4_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
4209 {
4210       mp_limb_t u[4], v[4], a[4], b[4], fix[4];
4211       int i, t, lsh;
4212 
4213       mpfq_zero(u, 4);
4214       mpfq_zero(v, 4);
4215       mpfq_copy(a, x, 4);
4216       mpfq_copy(b, p, 4);
4217       u[0] = 1UL;
4218 
4219       if (mpfq_fixmp_4_cmp(a, v) == 0 || mpfq_fixmp_4_cmp(a, b) == 0) {
4220         mpfq_zero(res, 4);
4221         return 0;
4222       }
4223 
4224       mpfq_fixmp_4_add(fix, b, u);
4225       mpfq_fixmp_4_rshift(fix, 1);
4226 
4227       assert (mpfq_fixmp_4_cmp(a,b) < 0);
4228 
4229       t = 0;
4230 
4231       for(i = 0 ; !a[i] ; i++) ;
4232       assert (i < 4);
4233       lsh = mpfq_ctzl(a[i]);
4234       mpfq_fixmp_4_long_rshift(a, i, lsh);
4235       t += lsh + i*GMP_NUMB_BITS;
4236       mpfq_fixmp_4_long_lshift(v, i, lsh);
4237 
4238       do {
4239         do {
4240           mpfq_fixmp_4_sub(b, b, a);
4241           mpfq_fixmp_4_add(v, v, u);
4242           for(i = 0 ; !b[i] ; i++) ;
4243           assert (i < 4);
4244           lsh = mpfq_ctzl(b[i]);
4245           mpfq_fixmp_4_long_rshift(b, i, lsh);
4246           t += lsh + i*GMP_NUMB_BITS;
4247           mpfq_fixmp_4_long_lshift(u, i, lsh);
4248         } while (mpfq_fixmp_4_cmp(a,b) < 0);
4249         if (mpfq_fixmp_4_cmp(a, b) == 0)
4250           break;
4251         do {
4252           mpfq_fixmp_4_sub(a, a, b);
4253           mpfq_fixmp_4_add(u, u, v);
4254           for(i = 0 ; !a[i] ; i++) ;
4255           assert (i < 4);
4256           lsh = mpfq_ctzl(a[i]);
4257           mpfq_fixmp_4_long_rshift(a, i, lsh);
4258           t += lsh + i*GMP_NUMB_BITS;
4259           mpfq_fixmp_4_long_lshift(v, i, lsh);
4260         } while (mpfq_fixmp_4_cmp(b,a)<0);
4261       } while (mpfq_fixmp_4_cmp(a,b) != 0);
4262       {
4263         if (mpfq_fixmp_4_cmp_ui(a, 1) != 0) {
4264           mpfq_copy(res, a, 4);
4265           return 0;
4266         }
4267       }
4268       while (t>0) {
4269         mp_limb_t sig = u[0] & 1UL;
4270         mpfq_fixmp_4_rshift(u, 1);
4271         if (sig)
4272           mpfq_fixmp_4_add(u, u, fix);
4273         --t;
4274       }
4275       mpfq_copy(res, u, 4);
4276       return 1;
4277 }
4278 #endif /* !defined(HAVE_native_mpfq_fixmp_4_invmod) */
4279 
4280 #if !defined(HAVE_native_mpfq_fixmp_4_redc)
4281 /* x has 10 words, z and p have 4 words.
4282  * only one word is read from invp.
4283  * Assuming R=W^5 is the redc modulus, we expect that x verifies:
4284  *   x < R*p,
4285  * so that we have eventually z < p, z congruent to x/R mod p.
4286  * The contents of the area pointed by x are clobbered by this call.
4287  * Note also that x may alias z.
4288  */
4289 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
4290 static inline
mpfq_fixmp_4_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)4291 void mpfq_fixmp_4_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
4292 {
4293     mp_limb_t cy;
4294     for(int i = 0; i < 4; ++i) {
4295         mp_limb_t t = x[i]*mip[0];
4296         cy = mpfq_fixmp_4_addmul1_shortz(x+i, p, t);
4297         assert (x[i] == 0);
4298         x[i] = cy;
4299     }
4300     cy = mpfq_fixmp_4_add(x, x, x + 4);
4301     /* At this point, we have (x' denotes x + cy*W^n here)
4302     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
4303     * x'/R < p + p
4304     */
4305     if (cy || mpfq_fixmp_4_cmp(x, p) >= 0) {
4306         mpfq_fixmp_4_sub(z, x, p);
4307     } else {
4308         mpfq_copy(z, x, 4);
4309     }
4310 }
4311 #endif /* !defined(HAVE_native_mpfq_fixmp_4_redc) */
4312 
4313 #if !defined(HAVE_native_mpfq_fixmp_4_redc_ur)
4314 /* x has 11 words, z and p have 4 words.
4315  * only one word is read from invp.
4316  * Assuming R=W^5 is the redc modulus, we expect that x verifies:
4317  *  x < W*W^4*p = W^0.5*R*p or the hw case, W*R*p otherwise,
4318  * so that we have eventually z < p, z congruent to x/R mod p.
4319  * The contents of the area pointed by x are clobbered by this call.
4320  * Note also that x may alias z.
4321  */
4322 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
4323 static inline
mpfq_fixmp_4_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)4324 void mpfq_fixmp_4_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
4325 {
4326     mp_limb_t cy, q[2];
4327     for (int i = 0; i < 4; ++i) {
4328         mp_limb_t t = x[i]*mip[0];
4329         cy = mpfq_fixmp_4_addmul1(x+i, p, t);
4330         assert (x[i] == 0);
4331         x[i] = cy;
4332     }
4333     cy=mpfq_fixmp_4_add(x+4+1, x+4+1, x);
4334     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
4335     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
4336     * x'/R < (W+1)*p
4337     */
4338     if (cy) {
4339         /* x'/R-p < W*p, which fits in n+1 words */
4340         mpn_sub(x+4,x+4,4+1,p,4);
4341     }
4342     mpn_tdiv_qr(q, z, 0, x+4, 4+1, p, 4);
4343 }
4344 #endif /* !defined(HAVE_native_mpfq_fixmp_4_redc_ur) */
4345 
4346 #if !defined(HAVE_native_mpfq_fixmp_4_mgy_encode)
4347 /* x, z, and p have 4 words.
4348  * Assuming R=W^5 is the redc modulus, we compute z=R*x mod p. */
4349 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
4350 static inline
mpfq_fixmp_4_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)4351 void mpfq_fixmp_4_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
4352 {
4353     mp_limb_t t[8] = { 0, 0, 0, 0, x[0], x[1], x[2], x[3] };
4354     mpfq_fixmp_4_mod(z, t, p);
4355 }
4356 #endif /* !defined(HAVE_native_mpfq_fixmp_4_mgy_encode) */
4357 
4358 #if !defined(HAVE_native_mpfq_fixmp_4_mgy_decode)
4359 /* x, z, invR, and p have 4 words.
4360  * Assuming R=W^5 is the redc modulus, we compute z=x/R mod p. */
4361 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
4362 static inline
mpfq_fixmp_4_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)4363 void mpfq_fixmp_4_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
4364 {
4365     mp_limb_t t[8];
4366     mpfq_fixmp_4_mul(t, x, invR);
4367     mpfq_fixmp_4_mod(z, t, p);
4368 }
4369 #endif /* !defined(HAVE_native_mpfq_fixmp_4_mgy_decode) */
4370 
4371 #if !defined(HAVE_native_mpfq_fixmp_4_lshift)
4372 /* a has 4 words. Shift it in place by cnt bits to the left.
4373  * The shift count cnt must not exceed the word size.
4374  * Note that no carry is returned for the bits shifted out. */
4375 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
4376 static inline
mpfq_fixmp_4_lshift(mp_limb_t * a,int cnt)4377 void mpfq_fixmp_4_lshift(mp_limb_t * a, int cnt)
4378 {
4379     if (!cnt) return;
4380     int i;
4381     int dnt = GMP_NUMB_BITS - cnt;
4382     for (i = 4-1; i>0; --i) {
4383         a[i] <<= cnt;
4384         a[i] |= (a[i-1] >> dnt);
4385     }
4386     a[0] <<= cnt;
4387 }
4388 #endif /* !defined(HAVE_native_mpfq_fixmp_4_lshift) */
4389 
4390 #if !defined(HAVE_native_mpfq_fixmp_5_add)
4391 /* x, y, and z have 5 words. Result in z. Return carry bit */
4392 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
4393 /* Triggered by: 5_invmod, 5_redc, 5_redc_ur */
4394 static inline
mpfq_fixmp_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4395 mp_limb_t mpfq_fixmp_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4396 {
4397     mp_limb_t r, s, t, cy, cy1, cy2;
4398     cy = 0;
4399     r = x[0];
4400     s = r + y[0];
4401     cy1 = s < r;
4402     t = s + cy;
4403     cy2 = t < s;
4404     cy = cy1 | cy2;
4405     z[0] = t;
4406     r = x[1];
4407     s = r + y[1];
4408     cy1 = s < r;
4409     t = s + cy;
4410     cy2 = t < s;
4411     cy = cy1 | cy2;
4412     z[1] = t;
4413     r = x[2];
4414     s = r + y[2];
4415     cy1 = s < r;
4416     t = s + cy;
4417     cy2 = t < s;
4418     cy = cy1 | cy2;
4419     z[2] = t;
4420     r = x[3];
4421     s = r + y[3];
4422     cy1 = s < r;
4423     t = s + cy;
4424     cy2 = t < s;
4425     cy = cy1 | cy2;
4426     z[3] = t;
4427     r = x[4];
4428     s = r + y[4];
4429     cy1 = s < r;
4430     t = s + cy;
4431     cy2 = t < s;
4432     cy = cy1 | cy2;
4433     z[4] = t;
4434     return cy;
4435 }
4436 #endif /* !defined(HAVE_native_mpfq_fixmp_5_add) */
4437 
4438 #if !defined(HAVE_native_mpfq_fixmp_5_sub)
4439 /* x, y, and z have 5 words. Result in z. Return borrow bit */
4440 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
4441 /* Triggered by: 5_invmod, 5_redc */
4442 static inline
mpfq_fixmp_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4443 mp_limb_t mpfq_fixmp_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4444 {
4445     mp_limb_t r, s, t, cy, cy1, cy2;
4446     cy = 0;
4447     r = x[0];
4448     s = r - y[0];
4449     cy1 = s > r;
4450     t = s - cy;
4451     cy2 = t > s;
4452     cy = cy1 | cy2;
4453     z[0] = t;
4454     r = x[1];
4455     s = r - y[1];
4456     cy1 = s > r;
4457     t = s - cy;
4458     cy2 = t > s;
4459     cy = cy1 | cy2;
4460     z[1] = t;
4461     r = x[2];
4462     s = r - y[2];
4463     cy1 = s > r;
4464     t = s - cy;
4465     cy2 = t > s;
4466     cy = cy1 | cy2;
4467     z[2] = t;
4468     r = x[3];
4469     s = r - y[3];
4470     cy1 = s > r;
4471     t = s - cy;
4472     cy2 = t > s;
4473     cy = cy1 | cy2;
4474     z[3] = t;
4475     r = x[4];
4476     s = r - y[4];
4477     cy1 = s > r;
4478     t = s - cy;
4479     cy2 = t > s;
4480     cy = cy1 | cy2;
4481     z[4] = t;
4482     return cy;
4483 }
4484 #endif /* !defined(HAVE_native_mpfq_fixmp_5_sub) */
4485 
4486 #if !defined(HAVE_native_mpfq_fixmp_5_add_nc)
4487 /* x, y, and z have 5 words. Result in z. Carry bit is lost. */
4488 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
4489 static inline
mpfq_fixmp_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4490 void mpfq_fixmp_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4491 {
4492     mp_limb_t r, s, t, cy, cy1, cy2;
4493     cy = 0;
4494     r = x[0];
4495     s = r + y[0];
4496     cy1 = s < r;
4497     t = s + cy;
4498     cy2 = t < s;
4499     cy = cy1 | cy2;
4500     z[0] = t;
4501     r = x[1];
4502     s = r + y[1];
4503     cy1 = s < r;
4504     t = s + cy;
4505     cy2 = t < s;
4506     cy = cy1 | cy2;
4507     z[1] = t;
4508     r = x[2];
4509     s = r + y[2];
4510     cy1 = s < r;
4511     t = s + cy;
4512     cy2 = t < s;
4513     cy = cy1 | cy2;
4514     z[2] = t;
4515     r = x[3];
4516     s = r + y[3];
4517     cy1 = s < r;
4518     t = s + cy;
4519     cy2 = t < s;
4520     cy = cy1 | cy2;
4521     z[3] = t;
4522     r = x[4];
4523     s = r + y[4];
4524     cy1 = s < r;
4525     t = s + cy;
4526     cy2 = t < s;
4527     cy = cy1 | cy2;
4528     z[4] = t;
4529 }
4530 #endif /* !defined(HAVE_native_mpfq_fixmp_5_add_nc) */
4531 
4532 #if !defined(HAVE_native_mpfq_fixmp_5_sub_nc)
4533 /* x, y, and z have 5 words. Result in z. Borrow bit is lost. */
4534 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
4535 static inline
mpfq_fixmp_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4536 void mpfq_fixmp_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4537 {
4538     mp_limb_t r, s, t, cy, cy1, cy2;
4539     cy = 0;
4540     r = x[0];
4541     s = r - y[0];
4542     cy1 = s > r;
4543     t = s - cy;
4544     cy2 = t > s;
4545     cy = cy1 | cy2;
4546     z[0] = t;
4547     r = x[1];
4548     s = r - y[1];
4549     cy1 = s > r;
4550     t = s - cy;
4551     cy2 = t > s;
4552     cy = cy1 | cy2;
4553     z[1] = t;
4554     r = x[2];
4555     s = r - y[2];
4556     cy1 = s > r;
4557     t = s - cy;
4558     cy2 = t > s;
4559     cy = cy1 | cy2;
4560     z[2] = t;
4561     r = x[3];
4562     s = r - y[3];
4563     cy1 = s > r;
4564     t = s - cy;
4565     cy2 = t > s;
4566     cy = cy1 | cy2;
4567     z[3] = t;
4568     r = x[4];
4569     s = r - y[4];
4570     cy1 = s > r;
4571     t = s - cy;
4572     cy2 = t > s;
4573     cy = cy1 | cy2;
4574     z[4] = t;
4575 }
4576 #endif /* !defined(HAVE_native_mpfq_fixmp_5_sub_nc) */
4577 
4578 #if !defined(HAVE_native_mpfq_fixmp_5_add_ui)
4579 /* x, y, and z have 5 words. Result in z. Return carry bit */
4580 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
4581 static inline
mpfq_fixmp_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)4582 mp_limb_t mpfq_fixmp_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
4583 {
4584     mp_limb_t r, s, t, cy, cy1, cy2;
4585     cy = 0;
4586     r = x[0];
4587     s = r + y;
4588     cy1 = s < r;
4589     t = s + cy;
4590     cy2 = t < s;
4591     cy = cy1 | cy2;
4592     z[0] = t;
4593     s = x[1];
4594     t = s + cy;
4595     cy = t < s;
4596     z[1] = t;
4597     s = x[2];
4598     t = s + cy;
4599     cy = t < s;
4600     z[2] = t;
4601     s = x[3];
4602     t = s + cy;
4603     cy = t < s;
4604     z[3] = t;
4605     s = x[4];
4606     t = s + cy;
4607     cy = t < s;
4608     z[4] = t;
4609     return cy;
4610 }
4611 #endif /* !defined(HAVE_native_mpfq_fixmp_5_add_ui) */
4612 
4613 #if !defined(HAVE_native_mpfq_fixmp_5_sub_ui)
4614 /* x, y, and z have 5 words. Result in z. Return borrow bit */
4615 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
4616 static inline
mpfq_fixmp_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)4617 mp_limb_t mpfq_fixmp_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
4618 {
4619     mp_limb_t r, s, t, cy, cy1, cy2;
4620     cy = 0;
4621     r = x[0];
4622     s = r - y;
4623     cy1 = s > r;
4624     t = s - cy;
4625     cy2 = t > s;
4626     cy = cy1 | cy2;
4627     z[0] = t;
4628     s = x[1];
4629     t = s - cy;
4630     cy = t > s;
4631     z[1] = t;
4632     s = x[2];
4633     t = s - cy;
4634     cy = t > s;
4635     z[2] = t;
4636     s = x[3];
4637     t = s - cy;
4638     cy = t > s;
4639     z[3] = t;
4640     s = x[4];
4641     t = s - cy;
4642     cy = t > s;
4643     z[4] = t;
4644     return cy;
4645 }
4646 #endif /* !defined(HAVE_native_mpfq_fixmp_5_sub_ui) */
4647 
4648 #if !defined(HAVE_native_mpfq_fixmp_5_add_ui_nc)
4649 /* x, y, and z have 5 words. Result in z. Carry bit is lost. */
4650 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
4651 static inline
mpfq_fixmp_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)4652 void mpfq_fixmp_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
4653 {
4654     mp_limb_t r, s, t, cy, cy1, cy2;
4655     cy = 0;
4656     r = x[0];
4657     s = r + y;
4658     cy1 = s < r;
4659     t = s + cy;
4660     cy2 = t < s;
4661     cy = cy1 | cy2;
4662     z[0] = t;
4663     s = x[1];
4664     t = s + cy;
4665     cy = t < s;
4666     z[1] = t;
4667     s = x[2];
4668     t = s + cy;
4669     cy = t < s;
4670     z[2] = t;
4671     s = x[3];
4672     t = s + cy;
4673     cy = t < s;
4674     z[3] = t;
4675     s = x[4];
4676     t = s + cy;
4677     cy = t < s;
4678     z[4] = t;
4679 }
4680 #endif /* !defined(HAVE_native_mpfq_fixmp_5_add_ui_nc) */
4681 
4682 #if !defined(HAVE_native_mpfq_fixmp_5_sub_ui_nc)
4683 /* x, y, and z have 5 words. Result in z. Borrow bit is lost. */
4684 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
4685 static inline
mpfq_fixmp_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)4686 void mpfq_fixmp_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
4687 {
4688     mp_limb_t r, s, t, cy, cy1, cy2;
4689     cy = 0;
4690     r = x[0];
4691     s = r - y;
4692     cy1 = s > r;
4693     t = s - cy;
4694     cy2 = t > s;
4695     cy = cy1 | cy2;
4696     z[0] = t;
4697     s = x[1];
4698     t = s - cy;
4699     cy = t > s;
4700     z[1] = t;
4701     s = x[2];
4702     t = s - cy;
4703     cy = t > s;
4704     z[2] = t;
4705     s = x[3];
4706     t = s - cy;
4707     cy = t > s;
4708     z[3] = t;
4709     s = x[4];
4710     t = s - cy;
4711     cy = t > s;
4712     z[4] = t;
4713 }
4714 #endif /* !defined(HAVE_native_mpfq_fixmp_5_sub_ui_nc) */
4715 
4716 #if !defined(HAVE_native_mpfq_fixmp_5_cmp)
4717 /* x and y have 5 words. Return sign of difference x-y. */
4718 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
4719 /* Triggered by: 5_invmod, 5_redc */
4720 static inline
mpfq_fixmp_5_cmp(const mp_limb_t * x,const mp_limb_t * y)4721 int mpfq_fixmp_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
4722 {
4723     for (int i = 5-1; i >= 0; --i) {
4724         if (x[i] > y[i]) return 1;
4725         if (x[i] < y[i]) return -1;
4726     }
4727     return 0;
4728 }
4729 #endif /* !defined(HAVE_native_mpfq_fixmp_5_cmp) */
4730 
4731 #if !defined(HAVE_native_mpfq_fixmp_5_cmp_ui)
4732 /* x has 5 words. Return sign of difference x-y. */
4733 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
4734 /* Triggered by: 5_invmod */
4735 static inline
mpfq_fixmp_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)4736 int mpfq_fixmp_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
4737 {
4738     for (int i = 5-1; i > 0; --i) {
4739         if (x[i]) return 1;
4740     }
4741     if (x[0]>y) return 1;
4742     if (x[0]<y) return -1;
4743     return 0;
4744 }
4745 #endif /* !defined(HAVE_native_mpfq_fixmp_5_cmp_ui) */
4746 
4747 #if !defined(HAVE_native_mpfq_fixmp_5_addmul1)
4748 /* x has 5 words, z has 7.
4749  * Put (z+x*c) in z. Return carry bit. */
4750 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
4751 /* Triggered by: 5_redc_ur */
4752 static inline
mpfq_fixmp_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4753 mp_limb_t mpfq_fixmp_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4754 {
4755     mp_limb_t hi, lo, carry, buf;
4756     carry = 0;
4757     mpfq_umul_ppmm(hi,lo,c,x[0]);
4758     lo += carry;
4759     carry = (lo<carry) + hi;
4760     buf = z[0];
4761     lo += buf;
4762     carry += (lo<buf);
4763     z[0] = lo;
4764     mpfq_umul_ppmm(hi,lo,c,x[1]);
4765     lo += carry;
4766     carry = (lo<carry) + hi;
4767     buf = z[1];
4768     lo += buf;
4769     carry += (lo<buf);
4770     z[1] = lo;
4771     mpfq_umul_ppmm(hi,lo,c,x[2]);
4772     lo += carry;
4773     carry = (lo<carry) + hi;
4774     buf = z[2];
4775     lo += buf;
4776     carry += (lo<buf);
4777     z[2] = lo;
4778     mpfq_umul_ppmm(hi,lo,c,x[3]);
4779     lo += carry;
4780     carry = (lo<carry) + hi;
4781     buf = z[3];
4782     lo += buf;
4783     carry += (lo<buf);
4784     z[3] = lo;
4785     mpfq_umul_ppmm(hi,lo,c,x[4]);
4786     lo += carry;
4787     carry = (lo<carry) + hi;
4788     buf = z[4];
4789     lo += buf;
4790     carry += (lo<buf);
4791     z[4] = lo;
4792     z[5] += carry;
4793     return (z[5]<carry);
4794 }
4795 #endif /* !defined(HAVE_native_mpfq_fixmp_5_addmul1) */
4796 
4797 #if !defined(HAVE_native_mpfq_fixmp_5_addmul1_nc)
4798 /* x has 5 words, z has 7.
4799  * Put (z+x*c) in z. Carry bit is lost. */
4800 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
4801 /* Triggered by: 5_mul, 5_mgy_decode, 6_sqr, 6_shortmul, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 5_5_sqr, 5_5_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
4802 static inline
mpfq_fixmp_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4803 void mpfq_fixmp_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4804 {
4805     mp_limb_t hi, lo, carry, buf;
4806     carry = 0;
4807     mpfq_umul_ppmm(hi,lo,c,x[0]);
4808     lo += carry;
4809     carry = (lo<carry) + hi;
4810     buf = z[0];
4811     lo += buf;
4812     carry += (lo<buf);
4813     z[0] = lo;
4814     mpfq_umul_ppmm(hi,lo,c,x[1]);
4815     lo += carry;
4816     carry = (lo<carry) + hi;
4817     buf = z[1];
4818     lo += buf;
4819     carry += (lo<buf);
4820     z[1] = lo;
4821     mpfq_umul_ppmm(hi,lo,c,x[2]);
4822     lo += carry;
4823     carry = (lo<carry) + hi;
4824     buf = z[2];
4825     lo += buf;
4826     carry += (lo<buf);
4827     z[2] = lo;
4828     mpfq_umul_ppmm(hi,lo,c,x[3]);
4829     lo += carry;
4830     carry = (lo<carry) + hi;
4831     buf = z[3];
4832     lo += buf;
4833     carry += (lo<buf);
4834     z[3] = lo;
4835     mpfq_umul_ppmm(hi,lo,c,x[4]);
4836     lo += carry;
4837     carry = (lo<carry) + hi;
4838     buf = z[4];
4839     lo += buf;
4840     carry += (lo<buf);
4841     z[4] = lo;
4842     z[5] += carry;
4843 }
4844 #endif /* !defined(HAVE_native_mpfq_fixmp_5_addmul1_nc) */
4845 
4846 #if !defined(HAVE_native_mpfq_fixmp_5_addmul1_shortz)
4847 /* x has 5 words, z has 6.
4848  * Put (z+x*c) in z. Return carry word. */
4849 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
4850 /* Triggered by: 5_redc */
4851 static inline
mpfq_fixmp_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4852 mp_limb_t mpfq_fixmp_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4853 {
4854     mp_limb_t hi, lo, carry, buf;
4855     carry = 0;
4856     mpfq_umul_ppmm(hi,lo,c,x[0]);
4857     lo += carry;
4858     carry = (lo<carry) + hi;
4859     buf = z[0];
4860     lo += buf;
4861     carry += (lo<buf);
4862     z[0] = lo;
4863     mpfq_umul_ppmm(hi,lo,c,x[1]);
4864     lo += carry;
4865     carry = (lo<carry) + hi;
4866     buf = z[1];
4867     lo += buf;
4868     carry += (lo<buf);
4869     z[1] = lo;
4870     mpfq_umul_ppmm(hi,lo,c,x[2]);
4871     lo += carry;
4872     carry = (lo<carry) + hi;
4873     buf = z[2];
4874     lo += buf;
4875     carry += (lo<buf);
4876     z[2] = lo;
4877     mpfq_umul_ppmm(hi,lo,c,x[3]);
4878     lo += carry;
4879     carry = (lo<carry) + hi;
4880     buf = z[3];
4881     lo += buf;
4882     carry += (lo<buf);
4883     z[3] = lo;
4884     mpfq_umul_ppmm(hi,lo,c,x[4]);
4885     lo += carry;
4886     carry = (lo<carry) + hi;
4887     buf = z[4];
4888     lo += buf;
4889     carry += (lo<buf);
4890     z[4] = lo;
4891     return carry;
4892 }
4893 #endif /* !defined(HAVE_native_mpfq_fixmp_5_addmul1_shortz) */
4894 
4895 #if !defined(HAVE_native_mpfq_fixmp_5_mul)
4896 /* x and y have 5 words, z has 12. Put x*y in z. */
4897 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
4898 /* Triggered by: 5_mgy_decode */
4899 static inline
mpfq_fixmp_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4900 void mpfq_fixmp_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4901 {
4902     assert(z != x && z != y);
4903     for (int i = 0; i < 10; z[i++] = 0) ;
4904     mpfq_fixmp_5_addmul1_nc (z + 0, x, y[0]);
4905     mpfq_fixmp_5_addmul1_nc (z + 1, x, y[1]);
4906     mpfq_fixmp_5_addmul1_nc (z + 2, x, y[2]);
4907     mpfq_fixmp_5_addmul1_nc (z + 3, x, y[3]);
4908     mpfq_fixmp_5_addmul1_nc (z + 4, x, y[4]);
4909 }
4910 #endif /* !defined(HAVE_native_mpfq_fixmp_5_mul) */
4911 
4912 #if !defined(HAVE_native_mpfq_fixmp_5_sqr)
4913 /* x has 5 words, z has 12. Put x*y in z. */
4914 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
4915 static inline
mpfq_fixmp_5_sqr(mp_limb_t * z,const mp_limb_t * x)4916 void mpfq_fixmp_5_sqr(mp_limb_t * z, const mp_limb_t * x)
4917 {
4918     mp_limb_t buf[10] = {0,};
4919     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
4920     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
4921     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
4922     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
4923     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
4924     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
4925     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
4926     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
4927     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
4928     mpn_lshift(buf, buf, 10, 1);
4929     mpn_add_n(z, z, buf, 10);
4930 }
4931 #endif /* !defined(HAVE_native_mpfq_fixmp_5_sqr) */
4932 
4933 #if !defined(HAVE_native_mpfq_fixmp_5_mul1)
4934 /* x has 5 words, z has 7. Put x*y in z. */
4935 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
4936 static inline
mpfq_fixmp_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)4937 void mpfq_fixmp_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
4938 {
4939     mp_limb_t hi, lo, carry;
4940     carry = 0;
4941     mpfq_umul_ppmm(hi,lo,c,x[0]);
4942     lo += carry;
4943     carry = (lo<carry) + hi;
4944     z[0] = lo;
4945     mpfq_umul_ppmm(hi,lo,c,x[1]);
4946     lo += carry;
4947     carry = (lo<carry) + hi;
4948     z[1] = lo;
4949     mpfq_umul_ppmm(hi,lo,c,x[2]);
4950     lo += carry;
4951     carry = (lo<carry) + hi;
4952     z[2] = lo;
4953     mpfq_umul_ppmm(hi,lo,c,x[3]);
4954     lo += carry;
4955     carry = (lo<carry) + hi;
4956     z[3] = lo;
4957     mpfq_umul_ppmm(hi,lo,c,x[4]);
4958     lo += carry;
4959     carry = (lo<carry) + hi;
4960     z[4] = lo;
4961     z[5] = carry;
4962 }
4963 #endif /* !defined(HAVE_native_mpfq_fixmp_5_mul1) */
4964 
4965 #if !defined(HAVE_native_mpfq_fixmp_5_shortmul)
4966 /* x and y have 5 words, z has 6.
4967  * Put the low 6 words of x*y in z. */
4968 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
4969 static inline
mpfq_fixmp_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)4970 void mpfq_fixmp_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
4971 {
4972     mpfq_zero(z, 5);
4973     mpfq_fixmp_4_addmul1_nc (z+0, x, y[0]);
4974     z[5-1] += x[4]*y[0];
4975     mpfq_fixmp_3_addmul1_nc (z+1, x, y[1]);
4976     z[5-1] += x[3]*y[1];
4977     mpfq_fixmp_2_addmul1_nc (z+2, x, y[2]);
4978     z[5-1] += x[2]*y[2];
4979     mpfq_fixmp_1_addmul1_nc (z+3, x, y[3]);
4980     z[5-1] += x[1]*y[3];
4981     z[5-1] += x[0]*y[5-1];
4982 }
4983 #endif /* !defined(HAVE_native_mpfq_fixmp_5_shortmul) */
4984 
4985 #if !defined(HAVE_native_mpfq_fixmp_5_mod)
4986 /* x has 12 words. z and p have 5 words, and the high word of p is non-zero.
4987  * Put x mod p in z. */
4988 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
4989 /* Triggered by: 5_mgy_decode */
4990 static inline
mpfq_fixmp_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)4991 void mpfq_fixmp_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
4992 {
4993     mp_limb_t q[5+1], r[5];
4994     assert (p[5-1] != 0);
4995     mpn_tdiv_qr(q, r, 0, x, 10, p, 5);
4996     mpfq_copy(z, r, 5);
4997 }
4998 #endif /* !defined(HAVE_native_mpfq_fixmp_5_mod) */
4999 
5000 #if !defined(HAVE_native_mpfq_fixmp_5_rshift)
5001 /* a has 5 words. Shift it in place by cnt bits to the right.
5002  * The shift count cnt must not exceed the word size.
5003  * Note that no carry is returned for the bits shifted out. */
5004 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5005 /* Triggered by: 5_invmod */
5006 static inline
mpfq_fixmp_5_rshift(mp_limb_t * a,int cnt)5007 void mpfq_fixmp_5_rshift(mp_limb_t * a, int cnt)
5008 {
5009     if (!cnt) return;
5010     int i;
5011     int dnt = GMP_NUMB_BITS - cnt;
5012     for (i = 0; i < 5-1; ++i) {
5013         a[i] >>= cnt;
5014         a[i] |= (a[i+1] << dnt);
5015     }
5016     a[5-1] >>= cnt;
5017 }
5018 #endif /* !defined(HAVE_native_mpfq_fixmp_5_rshift) */
5019 
5020 #if !defined(HAVE_native_mpfq_fixmp_5_long_rshift)
5021 /* a has 5 words. Shift it in place by off words plus cnt bits to the left.
5022  * Note that no carry is returned for the bits shifted out. */
5023 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5024 /* Triggered by: 5_invmod */
5025 static inline
mpfq_fixmp_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)5026 void mpfq_fixmp_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
5027 {
5028     if (cnt) {
5029         int dnt = GMP_NUMB_BITS - cnt;
5030         for (int i = 0; i < 5 - off - 1; ++i) {
5031             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
5032         }
5033         a[5-off-1] = a[5-1]>>cnt;
5034     } else {
5035         mpfq_copyi(a, a + off, 5 - off);
5036     }
5037     mpfq_zero(a + 5 - off, off);
5038 }
5039 #endif /* !defined(HAVE_native_mpfq_fixmp_5_long_rshift) */
5040 
5041 #if !defined(HAVE_native_mpfq_fixmp_5_long_lshift)
5042 /* a has 5 words. Shift it in place by off words plus cnt bits to the left.
5043  * Note that no carry is returned for the bits shifted out. */
5044 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5045 /* Triggered by: 5_invmod */
5046 static inline
mpfq_fixmp_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)5047 void mpfq_fixmp_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
5048 {
5049     int i;
5050     if (cnt) {
5051         int dnt = GMP_NUMB_BITS - cnt;
5052         for (i = 5-1; i>off; --i) {
5053             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
5054         }
5055         a[off] = a[0]<<cnt;
5056     } else {
5057         mpfq_copyd(a + off, a, 5 - off);
5058     }
5059     mpfq_zero(a, off);
5060 }
5061 #endif /* !defined(HAVE_native_mpfq_fixmp_5_long_lshift) */
5062 
5063 #if !defined(HAVE_native_mpfq_fixmp_5_invmod)
5064 /* x, z, and p have 5 words. Put inverse of x mod p in z.
5065  * Return non-zero if an inverse could be found.
5066  * If no inverse could be found, return 0 and set z to zero.
5067  */
5068 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5069 static inline
mpfq_fixmp_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)5070 int mpfq_fixmp_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
5071 {
5072       mp_limb_t u[5], v[5], a[5], b[5], fix[5];
5073       int i, t, lsh;
5074 
5075       mpfq_zero(u, 5);
5076       mpfq_zero(v, 5);
5077       mpfq_copy(a, x, 5);
5078       mpfq_copy(b, p, 5);
5079       u[0] = 1UL;
5080 
5081       if (mpfq_fixmp_5_cmp(a, v) == 0 || mpfq_fixmp_5_cmp(a, b) == 0) {
5082         mpfq_zero(res, 5);
5083         return 0;
5084       }
5085 
5086       mpfq_fixmp_5_add(fix, b, u);
5087       mpfq_fixmp_5_rshift(fix, 1);
5088 
5089       assert (mpfq_fixmp_5_cmp(a,b) < 0);
5090 
5091       t = 0;
5092 
5093       for(i = 0 ; !a[i] ; i++) ;
5094       assert (i < 5);
5095       lsh = mpfq_ctzl(a[i]);
5096       mpfq_fixmp_5_long_rshift(a, i, lsh);
5097       t += lsh + i*GMP_NUMB_BITS;
5098       mpfq_fixmp_5_long_lshift(v, i, lsh);
5099 
5100       do {
5101         do {
5102           mpfq_fixmp_5_sub(b, b, a);
5103           mpfq_fixmp_5_add(v, v, u);
5104           for(i = 0 ; !b[i] ; i++) ;
5105           assert (i < 5);
5106           lsh = mpfq_ctzl(b[i]);
5107           mpfq_fixmp_5_long_rshift(b, i, lsh);
5108           t += lsh + i*GMP_NUMB_BITS;
5109           mpfq_fixmp_5_long_lshift(u, i, lsh);
5110         } while (mpfq_fixmp_5_cmp(a,b) < 0);
5111         if (mpfq_fixmp_5_cmp(a, b) == 0)
5112           break;
5113         do {
5114           mpfq_fixmp_5_sub(a, a, b);
5115           mpfq_fixmp_5_add(u, u, v);
5116           for(i = 0 ; !a[i] ; i++) ;
5117           assert (i < 5);
5118           lsh = mpfq_ctzl(a[i]);
5119           mpfq_fixmp_5_long_rshift(a, i, lsh);
5120           t += lsh + i*GMP_NUMB_BITS;
5121           mpfq_fixmp_5_long_lshift(v, i, lsh);
5122         } while (mpfq_fixmp_5_cmp(b,a)<0);
5123       } while (mpfq_fixmp_5_cmp(a,b) != 0);
5124       {
5125         if (mpfq_fixmp_5_cmp_ui(a, 1) != 0) {
5126           mpfq_copy(res, a, 5);
5127           return 0;
5128         }
5129       }
5130       while (t>0) {
5131         mp_limb_t sig = u[0] & 1UL;
5132         mpfq_fixmp_5_rshift(u, 1);
5133         if (sig)
5134           mpfq_fixmp_5_add(u, u, fix);
5135         --t;
5136       }
5137       mpfq_copy(res, u, 5);
5138       return 1;
5139 }
5140 #endif /* !defined(HAVE_native_mpfq_fixmp_5_invmod) */
5141 
5142 #if !defined(HAVE_native_mpfq_fixmp_5_redc)
5143 /* x has 12 words, z and p have 5 words.
5144  * only one word is read from invp.
5145  * Assuming R=W^6 is the redc modulus, we expect that x verifies:
5146  *   x < R*p,
5147  * so that we have eventually z < p, z congruent to x/R mod p.
5148  * The contents of the area pointed by x are clobbered by this call.
5149  * Note also that x may alias z.
5150  */
5151 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
5152 static inline
mpfq_fixmp_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)5153 void mpfq_fixmp_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
5154 {
5155     mp_limb_t cy;
5156     for(int i = 0; i < 5; ++i) {
5157         mp_limb_t t = x[i]*mip[0];
5158         cy = mpfq_fixmp_5_addmul1_shortz(x+i, p, t);
5159         assert (x[i] == 0);
5160         x[i] = cy;
5161     }
5162     cy = mpfq_fixmp_5_add(x, x, x + 5);
5163     /* At this point, we have (x' denotes x + cy*W^n here)
5164     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
5165     * x'/R < p + p
5166     */
5167     if (cy || mpfq_fixmp_5_cmp(x, p) >= 0) {
5168         mpfq_fixmp_5_sub(z, x, p);
5169     } else {
5170         mpfq_copy(z, x, 5);
5171     }
5172 }
5173 #endif /* !defined(HAVE_native_mpfq_fixmp_5_redc) */
5174 
5175 #if !defined(HAVE_native_mpfq_fixmp_5_redc_ur)
5176 /* x has 13 words, z and p have 5 words.
5177  * only one word is read from invp.
5178  * Assuming R=W^6 is the redc modulus, we expect that x verifies:
5179  *  x < W*W^5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
5180  * so that we have eventually z < p, z congruent to x/R mod p.
5181  * The contents of the area pointed by x are clobbered by this call.
5182  * Note also that x may alias z.
5183  */
5184 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
5185 static inline
mpfq_fixmp_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)5186 void mpfq_fixmp_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
5187 {
5188     mp_limb_t cy, q[2];
5189     for (int i = 0; i < 5; ++i) {
5190         mp_limb_t t = x[i]*mip[0];
5191         cy = mpfq_fixmp_5_addmul1(x+i, p, t);
5192         assert (x[i] == 0);
5193         x[i] = cy;
5194     }
5195     cy=mpfq_fixmp_5_add(x+5+1, x+5+1, x);
5196     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
5197     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
5198     * x'/R < (W+1)*p
5199     */
5200     if (cy) {
5201         /* x'/R-p < W*p, which fits in n+1 words */
5202         mpn_sub(x+5,x+5,5+1,p,5);
5203     }
5204     mpn_tdiv_qr(q, z, 0, x+5, 5+1, p, 5);
5205 }
5206 #endif /* !defined(HAVE_native_mpfq_fixmp_5_redc_ur) */
5207 
5208 #if !defined(HAVE_native_mpfq_fixmp_5_mgy_encode)
5209 /* x, z, and p have 5 words.
5210  * Assuming R=W^6 is the redc modulus, we compute z=R*x mod p. */
5211 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
5212 static inline
mpfq_fixmp_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)5213 void mpfq_fixmp_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
5214 {
5215     mp_limb_t t[10] = { 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4] };
5216     mpfq_fixmp_5_mod(z, t, p);
5217 }
5218 #endif /* !defined(HAVE_native_mpfq_fixmp_5_mgy_encode) */
5219 
5220 #if !defined(HAVE_native_mpfq_fixmp_5_mgy_decode)
5221 /* x, z, invR, and p have 5 words.
5222  * Assuming R=W^6 is the redc modulus, we compute z=x/R mod p. */
5223 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
5224 static inline
mpfq_fixmp_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)5225 void mpfq_fixmp_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
5226 {
5227     mp_limb_t t[10];
5228     mpfq_fixmp_5_mul(t, x, invR);
5229     mpfq_fixmp_5_mod(z, t, p);
5230 }
5231 #endif /* !defined(HAVE_native_mpfq_fixmp_5_mgy_decode) */
5232 
5233 #if !defined(HAVE_native_mpfq_fixmp_5_lshift)
5234 /* a has 5 words. Shift it in place by cnt bits to the left.
5235  * The shift count cnt must not exceed the word size.
5236  * Note that no carry is returned for the bits shifted out. */
5237 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
5238 static inline
mpfq_fixmp_5_lshift(mp_limb_t * a,int cnt)5239 void mpfq_fixmp_5_lshift(mp_limb_t * a, int cnt)
5240 {
5241     if (!cnt) return;
5242     int i;
5243     int dnt = GMP_NUMB_BITS - cnt;
5244     for (i = 5-1; i>0; --i) {
5245         a[i] <<= cnt;
5246         a[i] |= (a[i-1] >> dnt);
5247     }
5248     a[0] <<= cnt;
5249 }
5250 #endif /* !defined(HAVE_native_mpfq_fixmp_5_lshift) */
5251 
5252 #if !defined(HAVE_native_mpfq_fixmp_6_add)
5253 /* x, y, and z have 6 words. Result in z. Return carry bit */
5254 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
5255 /* Triggered by: 6_invmod, 6_redc, 6_redc_ur */
5256 static inline
mpfq_fixmp_6_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5257 mp_limb_t mpfq_fixmp_6_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5258 {
5259     mp_limb_t r, s, t, cy, cy1, cy2;
5260     cy = 0;
5261     r = x[0];
5262     s = r + y[0];
5263     cy1 = s < r;
5264     t = s + cy;
5265     cy2 = t < s;
5266     cy = cy1 | cy2;
5267     z[0] = t;
5268     r = x[1];
5269     s = r + y[1];
5270     cy1 = s < r;
5271     t = s + cy;
5272     cy2 = t < s;
5273     cy = cy1 | cy2;
5274     z[1] = t;
5275     r = x[2];
5276     s = r + y[2];
5277     cy1 = s < r;
5278     t = s + cy;
5279     cy2 = t < s;
5280     cy = cy1 | cy2;
5281     z[2] = t;
5282     r = x[3];
5283     s = r + y[3];
5284     cy1 = s < r;
5285     t = s + cy;
5286     cy2 = t < s;
5287     cy = cy1 | cy2;
5288     z[3] = t;
5289     r = x[4];
5290     s = r + y[4];
5291     cy1 = s < r;
5292     t = s + cy;
5293     cy2 = t < s;
5294     cy = cy1 | cy2;
5295     z[4] = t;
5296     r = x[5];
5297     s = r + y[5];
5298     cy1 = s < r;
5299     t = s + cy;
5300     cy2 = t < s;
5301     cy = cy1 | cy2;
5302     z[5] = t;
5303     return cy;
5304 }
5305 #endif /* !defined(HAVE_native_mpfq_fixmp_6_add) */
5306 
5307 #if !defined(HAVE_native_mpfq_fixmp_6_sub)
5308 /* x, y, and z have 6 words. Result in z. Return borrow bit */
5309 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
5310 /* Triggered by: 6_invmod, 6_redc */
5311 static inline
mpfq_fixmp_6_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5312 mp_limb_t mpfq_fixmp_6_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5313 {
5314     mp_limb_t r, s, t, cy, cy1, cy2;
5315     cy = 0;
5316     r = x[0];
5317     s = r - y[0];
5318     cy1 = s > r;
5319     t = s - cy;
5320     cy2 = t > s;
5321     cy = cy1 | cy2;
5322     z[0] = t;
5323     r = x[1];
5324     s = r - y[1];
5325     cy1 = s > r;
5326     t = s - cy;
5327     cy2 = t > s;
5328     cy = cy1 | cy2;
5329     z[1] = t;
5330     r = x[2];
5331     s = r - y[2];
5332     cy1 = s > r;
5333     t = s - cy;
5334     cy2 = t > s;
5335     cy = cy1 | cy2;
5336     z[2] = t;
5337     r = x[3];
5338     s = r - y[3];
5339     cy1 = s > r;
5340     t = s - cy;
5341     cy2 = t > s;
5342     cy = cy1 | cy2;
5343     z[3] = t;
5344     r = x[4];
5345     s = r - y[4];
5346     cy1 = s > r;
5347     t = s - cy;
5348     cy2 = t > s;
5349     cy = cy1 | cy2;
5350     z[4] = t;
5351     r = x[5];
5352     s = r - y[5];
5353     cy1 = s > r;
5354     t = s - cy;
5355     cy2 = t > s;
5356     cy = cy1 | cy2;
5357     z[5] = t;
5358     return cy;
5359 }
5360 #endif /* !defined(HAVE_native_mpfq_fixmp_6_sub) */
5361 
5362 #if !defined(HAVE_native_mpfq_fixmp_6_add_nc)
5363 /* x, y, and z have 6 words. Result in z. Carry bit is lost. */
5364 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
5365 static inline
mpfq_fixmp_6_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5366 void mpfq_fixmp_6_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5367 {
5368     mp_limb_t r, s, t, cy, cy1, cy2;
5369     cy = 0;
5370     r = x[0];
5371     s = r + y[0];
5372     cy1 = s < r;
5373     t = s + cy;
5374     cy2 = t < s;
5375     cy = cy1 | cy2;
5376     z[0] = t;
5377     r = x[1];
5378     s = r + y[1];
5379     cy1 = s < r;
5380     t = s + cy;
5381     cy2 = t < s;
5382     cy = cy1 | cy2;
5383     z[1] = t;
5384     r = x[2];
5385     s = r + y[2];
5386     cy1 = s < r;
5387     t = s + cy;
5388     cy2 = t < s;
5389     cy = cy1 | cy2;
5390     z[2] = t;
5391     r = x[3];
5392     s = r + y[3];
5393     cy1 = s < r;
5394     t = s + cy;
5395     cy2 = t < s;
5396     cy = cy1 | cy2;
5397     z[3] = t;
5398     r = x[4];
5399     s = r + y[4];
5400     cy1 = s < r;
5401     t = s + cy;
5402     cy2 = t < s;
5403     cy = cy1 | cy2;
5404     z[4] = t;
5405     r = x[5];
5406     s = r + y[5];
5407     cy1 = s < r;
5408     t = s + cy;
5409     cy2 = t < s;
5410     cy = cy1 | cy2;
5411     z[5] = t;
5412 }
5413 #endif /* !defined(HAVE_native_mpfq_fixmp_6_add_nc) */
5414 
5415 #if !defined(HAVE_native_mpfq_fixmp_6_sub_nc)
5416 /* x, y, and z have 6 words. Result in z. Borrow bit is lost. */
5417 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
5418 static inline
mpfq_fixmp_6_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5419 void mpfq_fixmp_6_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5420 {
5421     mp_limb_t r, s, t, cy, cy1, cy2;
5422     cy = 0;
5423     r = x[0];
5424     s = r - y[0];
5425     cy1 = s > r;
5426     t = s - cy;
5427     cy2 = t > s;
5428     cy = cy1 | cy2;
5429     z[0] = t;
5430     r = x[1];
5431     s = r - y[1];
5432     cy1 = s > r;
5433     t = s - cy;
5434     cy2 = t > s;
5435     cy = cy1 | cy2;
5436     z[1] = t;
5437     r = x[2];
5438     s = r - y[2];
5439     cy1 = s > r;
5440     t = s - cy;
5441     cy2 = t > s;
5442     cy = cy1 | cy2;
5443     z[2] = t;
5444     r = x[3];
5445     s = r - y[3];
5446     cy1 = s > r;
5447     t = s - cy;
5448     cy2 = t > s;
5449     cy = cy1 | cy2;
5450     z[3] = t;
5451     r = x[4];
5452     s = r - y[4];
5453     cy1 = s > r;
5454     t = s - cy;
5455     cy2 = t > s;
5456     cy = cy1 | cy2;
5457     z[4] = t;
5458     r = x[5];
5459     s = r - y[5];
5460     cy1 = s > r;
5461     t = s - cy;
5462     cy2 = t > s;
5463     cy = cy1 | cy2;
5464     z[5] = t;
5465 }
5466 #endif /* !defined(HAVE_native_mpfq_fixmp_6_sub_nc) */
5467 
5468 #if !defined(HAVE_native_mpfq_fixmp_6_add_ui)
5469 /* x, y, and z have 6 words. Result in z. Return carry bit */
5470 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
5471 static inline
mpfq_fixmp_6_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)5472 mp_limb_t mpfq_fixmp_6_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
5473 {
5474     mp_limb_t r, s, t, cy, cy1, cy2;
5475     cy = 0;
5476     r = x[0];
5477     s = r + y;
5478     cy1 = s < r;
5479     t = s + cy;
5480     cy2 = t < s;
5481     cy = cy1 | cy2;
5482     z[0] = t;
5483     s = x[1];
5484     t = s + cy;
5485     cy = t < s;
5486     z[1] = t;
5487     s = x[2];
5488     t = s + cy;
5489     cy = t < s;
5490     z[2] = t;
5491     s = x[3];
5492     t = s + cy;
5493     cy = t < s;
5494     z[3] = t;
5495     s = x[4];
5496     t = s + cy;
5497     cy = t < s;
5498     z[4] = t;
5499     s = x[5];
5500     t = s + cy;
5501     cy = t < s;
5502     z[5] = t;
5503     return cy;
5504 }
5505 #endif /* !defined(HAVE_native_mpfq_fixmp_6_add_ui) */
5506 
5507 #if !defined(HAVE_native_mpfq_fixmp_6_sub_ui)
5508 /* x, y, and z have 6 words. Result in z. Return borrow bit */
5509 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
5510 static inline
mpfq_fixmp_6_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)5511 mp_limb_t mpfq_fixmp_6_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
5512 {
5513     mp_limb_t r, s, t, cy, cy1, cy2;
5514     cy = 0;
5515     r = x[0];
5516     s = r - y;
5517     cy1 = s > r;
5518     t = s - cy;
5519     cy2 = t > s;
5520     cy = cy1 | cy2;
5521     z[0] = t;
5522     s = x[1];
5523     t = s - cy;
5524     cy = t > s;
5525     z[1] = t;
5526     s = x[2];
5527     t = s - cy;
5528     cy = t > s;
5529     z[2] = t;
5530     s = x[3];
5531     t = s - cy;
5532     cy = t > s;
5533     z[3] = t;
5534     s = x[4];
5535     t = s - cy;
5536     cy = t > s;
5537     z[4] = t;
5538     s = x[5];
5539     t = s - cy;
5540     cy = t > s;
5541     z[5] = t;
5542     return cy;
5543 }
5544 #endif /* !defined(HAVE_native_mpfq_fixmp_6_sub_ui) */
5545 
5546 #if !defined(HAVE_native_mpfq_fixmp_6_add_ui_nc)
5547 /* x, y, and z have 6 words. Result in z. Carry bit is lost. */
5548 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
5549 static inline
mpfq_fixmp_6_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)5550 void mpfq_fixmp_6_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
5551 {
5552     mp_limb_t r, s, t, cy, cy1, cy2;
5553     cy = 0;
5554     r = x[0];
5555     s = r + y;
5556     cy1 = s < r;
5557     t = s + cy;
5558     cy2 = t < s;
5559     cy = cy1 | cy2;
5560     z[0] = t;
5561     s = x[1];
5562     t = s + cy;
5563     cy = t < s;
5564     z[1] = t;
5565     s = x[2];
5566     t = s + cy;
5567     cy = t < s;
5568     z[2] = t;
5569     s = x[3];
5570     t = s + cy;
5571     cy = t < s;
5572     z[3] = t;
5573     s = x[4];
5574     t = s + cy;
5575     cy = t < s;
5576     z[4] = t;
5577     s = x[5];
5578     t = s + cy;
5579     cy = t < s;
5580     z[5] = t;
5581 }
5582 #endif /* !defined(HAVE_native_mpfq_fixmp_6_add_ui_nc) */
5583 
5584 #if !defined(HAVE_native_mpfq_fixmp_6_sub_ui_nc)
5585 /* x, y, and z have 6 words. Result in z. Borrow bit is lost. */
5586 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
5587 static inline
mpfq_fixmp_6_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)5588 void mpfq_fixmp_6_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
5589 {
5590     mp_limb_t r, s, t, cy, cy1, cy2;
5591     cy = 0;
5592     r = x[0];
5593     s = r - y;
5594     cy1 = s > r;
5595     t = s - cy;
5596     cy2 = t > s;
5597     cy = cy1 | cy2;
5598     z[0] = t;
5599     s = x[1];
5600     t = s - cy;
5601     cy = t > s;
5602     z[1] = t;
5603     s = x[2];
5604     t = s - cy;
5605     cy = t > s;
5606     z[2] = t;
5607     s = x[3];
5608     t = s - cy;
5609     cy = t > s;
5610     z[3] = t;
5611     s = x[4];
5612     t = s - cy;
5613     cy = t > s;
5614     z[4] = t;
5615     s = x[5];
5616     t = s - cy;
5617     cy = t > s;
5618     z[5] = t;
5619 }
5620 #endif /* !defined(HAVE_native_mpfq_fixmp_6_sub_ui_nc) */
5621 
5622 #if !defined(HAVE_native_mpfq_fixmp_6_cmp)
5623 /* x and y have 6 words. Return sign of difference x-y. */
5624 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
5625 /* Triggered by: 6_invmod, 6_redc */
5626 static inline
mpfq_fixmp_6_cmp(const mp_limb_t * x,const mp_limb_t * y)5627 int mpfq_fixmp_6_cmp(const mp_limb_t * x, const mp_limb_t * y)
5628 {
5629     for (int i = 6-1; i >= 0; --i) {
5630         if (x[i] > y[i]) return 1;
5631         if (x[i] < y[i]) return -1;
5632     }
5633     return 0;
5634 }
5635 #endif /* !defined(HAVE_native_mpfq_fixmp_6_cmp) */
5636 
5637 #if !defined(HAVE_native_mpfq_fixmp_6_cmp_ui)
5638 /* x has 6 words. Return sign of difference x-y. */
5639 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
5640 /* Triggered by: 6_invmod */
5641 static inline
mpfq_fixmp_6_cmp_ui(const mp_limb_t * x,mp_limb_t y)5642 int mpfq_fixmp_6_cmp_ui(const mp_limb_t * x, mp_limb_t y)
5643 {
5644     for (int i = 6-1; i > 0; --i) {
5645         if (x[i]) return 1;
5646     }
5647     if (x[0]>y) return 1;
5648     if (x[0]<y) return -1;
5649     return 0;
5650 }
5651 #endif /* !defined(HAVE_native_mpfq_fixmp_6_cmp_ui) */
5652 
5653 #if !defined(HAVE_native_mpfq_fixmp_6_addmul1)
5654 /* x has 6 words, z has 8.
5655  * Put (z+x*c) in z. Return carry bit. */
5656 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
5657 /* Triggered by: 6_redc_ur */
5658 static inline
mpfq_fixmp_6_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)5659 mp_limb_t mpfq_fixmp_6_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
5660 {
5661     mp_limb_t hi, lo, carry, buf;
5662     carry = 0;
5663     mpfq_umul_ppmm(hi,lo,c,x[0]);
5664     lo += carry;
5665     carry = (lo<carry) + hi;
5666     buf = z[0];
5667     lo += buf;
5668     carry += (lo<buf);
5669     z[0] = lo;
5670     mpfq_umul_ppmm(hi,lo,c,x[1]);
5671     lo += carry;
5672     carry = (lo<carry) + hi;
5673     buf = z[1];
5674     lo += buf;
5675     carry += (lo<buf);
5676     z[1] = lo;
5677     mpfq_umul_ppmm(hi,lo,c,x[2]);
5678     lo += carry;
5679     carry = (lo<carry) + hi;
5680     buf = z[2];
5681     lo += buf;
5682     carry += (lo<buf);
5683     z[2] = lo;
5684     mpfq_umul_ppmm(hi,lo,c,x[3]);
5685     lo += carry;
5686     carry = (lo<carry) + hi;
5687     buf = z[3];
5688     lo += buf;
5689     carry += (lo<buf);
5690     z[3] = lo;
5691     mpfq_umul_ppmm(hi,lo,c,x[4]);
5692     lo += carry;
5693     carry = (lo<carry) + hi;
5694     buf = z[4];
5695     lo += buf;
5696     carry += (lo<buf);
5697     z[4] = lo;
5698     mpfq_umul_ppmm(hi,lo,c,x[5]);
5699     lo += carry;
5700     carry = (lo<carry) + hi;
5701     buf = z[5];
5702     lo += buf;
5703     carry += (lo<buf);
5704     z[5] = lo;
5705     z[6] += carry;
5706     return (z[6]<carry);
5707 }
5708 #endif /* !defined(HAVE_native_mpfq_fixmp_6_addmul1) */
5709 
5710 #if !defined(HAVE_native_mpfq_fixmp_6_addmul1_nc)
5711 /* x has 6 words, z has 8.
5712  * Put (z+x*c) in z. Carry bit is lost. */
5713 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
5714 /* Triggered by: 6_mul, 6_mgy_decode, 7_sqr, 7_shortmul, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 6_5_sqr, 6_5_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
5715 static inline
mpfq_fixmp_6_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)5716 void mpfq_fixmp_6_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
5717 {
5718     mp_limb_t hi, lo, carry, buf;
5719     carry = 0;
5720     mpfq_umul_ppmm(hi,lo,c,x[0]);
5721     lo += carry;
5722     carry = (lo<carry) + hi;
5723     buf = z[0];
5724     lo += buf;
5725     carry += (lo<buf);
5726     z[0] = lo;
5727     mpfq_umul_ppmm(hi,lo,c,x[1]);
5728     lo += carry;
5729     carry = (lo<carry) + hi;
5730     buf = z[1];
5731     lo += buf;
5732     carry += (lo<buf);
5733     z[1] = lo;
5734     mpfq_umul_ppmm(hi,lo,c,x[2]);
5735     lo += carry;
5736     carry = (lo<carry) + hi;
5737     buf = z[2];
5738     lo += buf;
5739     carry += (lo<buf);
5740     z[2] = lo;
5741     mpfq_umul_ppmm(hi,lo,c,x[3]);
5742     lo += carry;
5743     carry = (lo<carry) + hi;
5744     buf = z[3];
5745     lo += buf;
5746     carry += (lo<buf);
5747     z[3] = lo;
5748     mpfq_umul_ppmm(hi,lo,c,x[4]);
5749     lo += carry;
5750     carry = (lo<carry) + hi;
5751     buf = z[4];
5752     lo += buf;
5753     carry += (lo<buf);
5754     z[4] = lo;
5755     mpfq_umul_ppmm(hi,lo,c,x[5]);
5756     lo += carry;
5757     carry = (lo<carry) + hi;
5758     buf = z[5];
5759     lo += buf;
5760     carry += (lo<buf);
5761     z[5] = lo;
5762     z[6] += carry;
5763 }
5764 #endif /* !defined(HAVE_native_mpfq_fixmp_6_addmul1_nc) */
5765 
5766 #if !defined(HAVE_native_mpfq_fixmp_6_addmul1_shortz)
5767 /* x has 6 words, z has 7.
5768  * Put (z+x*c) in z. Return carry word. */
5769 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
5770 /* Triggered by: 6_redc */
5771 static inline
mpfq_fixmp_6_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)5772 mp_limb_t mpfq_fixmp_6_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
5773 {
5774     mp_limb_t hi, lo, carry, buf;
5775     carry = 0;
5776     mpfq_umul_ppmm(hi,lo,c,x[0]);
5777     lo += carry;
5778     carry = (lo<carry) + hi;
5779     buf = z[0];
5780     lo += buf;
5781     carry += (lo<buf);
5782     z[0] = lo;
5783     mpfq_umul_ppmm(hi,lo,c,x[1]);
5784     lo += carry;
5785     carry = (lo<carry) + hi;
5786     buf = z[1];
5787     lo += buf;
5788     carry += (lo<buf);
5789     z[1] = lo;
5790     mpfq_umul_ppmm(hi,lo,c,x[2]);
5791     lo += carry;
5792     carry = (lo<carry) + hi;
5793     buf = z[2];
5794     lo += buf;
5795     carry += (lo<buf);
5796     z[2] = lo;
5797     mpfq_umul_ppmm(hi,lo,c,x[3]);
5798     lo += carry;
5799     carry = (lo<carry) + hi;
5800     buf = z[3];
5801     lo += buf;
5802     carry += (lo<buf);
5803     z[3] = lo;
5804     mpfq_umul_ppmm(hi,lo,c,x[4]);
5805     lo += carry;
5806     carry = (lo<carry) + hi;
5807     buf = z[4];
5808     lo += buf;
5809     carry += (lo<buf);
5810     z[4] = lo;
5811     mpfq_umul_ppmm(hi,lo,c,x[5]);
5812     lo += carry;
5813     carry = (lo<carry) + hi;
5814     buf = z[5];
5815     lo += buf;
5816     carry += (lo<buf);
5817     z[5] = lo;
5818     return carry;
5819 }
5820 #endif /* !defined(HAVE_native_mpfq_fixmp_6_addmul1_shortz) */
5821 
5822 #if !defined(HAVE_native_mpfq_fixmp_6_mul)
5823 /* x and y have 6 words, z has 14. Put x*y in z. */
5824 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
5825 /* Triggered by: 6_mgy_decode */
5826 static inline
mpfq_fixmp_6_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5827 void mpfq_fixmp_6_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5828 {
5829     assert(z != x && z != y);
5830     for (int i = 0; i < 12; z[i++] = 0) ;
5831     mpfq_fixmp_6_addmul1_nc (z + 0, x, y[0]);
5832     mpfq_fixmp_6_addmul1_nc (z + 1, x, y[1]);
5833     mpfq_fixmp_6_addmul1_nc (z + 2, x, y[2]);
5834     mpfq_fixmp_6_addmul1_nc (z + 3, x, y[3]);
5835     mpfq_fixmp_6_addmul1_nc (z + 4, x, y[4]);
5836     mpfq_fixmp_6_addmul1_nc (z + 5, x, y[5]);
5837 }
5838 #endif /* !defined(HAVE_native_mpfq_fixmp_6_mul) */
5839 
5840 #if !defined(HAVE_native_mpfq_fixmp_6_sqr)
5841 /* x has 6 words, z has 14. Put x*y in z. */
5842 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
5843 static inline
mpfq_fixmp_6_sqr(mp_limb_t * z,const mp_limb_t * x)5844 void mpfq_fixmp_6_sqr(mp_limb_t * z, const mp_limb_t * x)
5845 {
5846     mp_limb_t buf[12] = {0,};
5847     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
5848     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
5849     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
5850     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
5851     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
5852     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
5853     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
5854     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
5855     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
5856     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
5857     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
5858     mpn_lshift(buf, buf, 12, 1);
5859     mpn_add_n(z, z, buf, 12);
5860 }
5861 #endif /* !defined(HAVE_native_mpfq_fixmp_6_sqr) */
5862 
5863 #if !defined(HAVE_native_mpfq_fixmp_6_mul1)
5864 /* x has 6 words, z has 8. Put x*y in z. */
5865 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
5866 static inline
mpfq_fixmp_6_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)5867 void mpfq_fixmp_6_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
5868 {
5869     mp_limb_t hi, lo, carry;
5870     carry = 0;
5871     mpfq_umul_ppmm(hi,lo,c,x[0]);
5872     lo += carry;
5873     carry = (lo<carry) + hi;
5874     z[0] = lo;
5875     mpfq_umul_ppmm(hi,lo,c,x[1]);
5876     lo += carry;
5877     carry = (lo<carry) + hi;
5878     z[1] = lo;
5879     mpfq_umul_ppmm(hi,lo,c,x[2]);
5880     lo += carry;
5881     carry = (lo<carry) + hi;
5882     z[2] = lo;
5883     mpfq_umul_ppmm(hi,lo,c,x[3]);
5884     lo += carry;
5885     carry = (lo<carry) + hi;
5886     z[3] = lo;
5887     mpfq_umul_ppmm(hi,lo,c,x[4]);
5888     lo += carry;
5889     carry = (lo<carry) + hi;
5890     z[4] = lo;
5891     mpfq_umul_ppmm(hi,lo,c,x[5]);
5892     lo += carry;
5893     carry = (lo<carry) + hi;
5894     z[5] = lo;
5895     z[6] = carry;
5896 }
5897 #endif /* !defined(HAVE_native_mpfq_fixmp_6_mul1) */
5898 
5899 #if !defined(HAVE_native_mpfq_fixmp_6_shortmul)
5900 /* x and y have 6 words, z has 7.
5901  * Put the low 7 words of x*y in z. */
5902 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
5903 static inline
mpfq_fixmp_6_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)5904 void mpfq_fixmp_6_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
5905 {
5906     mpfq_zero(z, 6);
5907     mpfq_fixmp_5_addmul1_nc (z+0, x, y[0]);
5908     z[6-1] += x[5]*y[0];
5909     mpfq_fixmp_4_addmul1_nc (z+1, x, y[1]);
5910     z[6-1] += x[4]*y[1];
5911     mpfq_fixmp_3_addmul1_nc (z+2, x, y[2]);
5912     z[6-1] += x[3]*y[2];
5913     mpfq_fixmp_2_addmul1_nc (z+3, x, y[3]);
5914     z[6-1] += x[2]*y[3];
5915     mpfq_fixmp_1_addmul1_nc (z+4, x, y[4]);
5916     z[6-1] += x[1]*y[4];
5917     z[6-1] += x[0]*y[6-1];
5918 }
5919 #endif /* !defined(HAVE_native_mpfq_fixmp_6_shortmul) */
5920 
5921 #if !defined(HAVE_native_mpfq_fixmp_6_mod)
5922 /* x has 14 words. z and p have 6 words, and the high word of p is non-zero.
5923  * Put x mod p in z. */
5924 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
5925 /* Triggered by: 6_mgy_decode */
5926 static inline
mpfq_fixmp_6_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)5927 void mpfq_fixmp_6_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
5928 {
5929     mp_limb_t q[6+1], r[6];
5930     assert (p[6-1] != 0);
5931     mpn_tdiv_qr(q, r, 0, x, 12, p, 6);
5932     mpfq_copy(z, r, 6);
5933 }
5934 #endif /* !defined(HAVE_native_mpfq_fixmp_6_mod) */
5935 
5936 #if !defined(HAVE_native_mpfq_fixmp_6_rshift)
5937 /* a has 6 words. Shift it in place by cnt bits to the right.
5938  * The shift count cnt must not exceed the word size.
5939  * Note that no carry is returned for the bits shifted out. */
5940 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5941 /* Triggered by: 6_invmod */
5942 static inline
mpfq_fixmp_6_rshift(mp_limb_t * a,int cnt)5943 void mpfq_fixmp_6_rshift(mp_limb_t * a, int cnt)
5944 {
5945     if (!cnt) return;
5946     int i;
5947     int dnt = GMP_NUMB_BITS - cnt;
5948     for (i = 0; i < 6-1; ++i) {
5949         a[i] >>= cnt;
5950         a[i] |= (a[i+1] << dnt);
5951     }
5952     a[6-1] >>= cnt;
5953 }
5954 #endif /* !defined(HAVE_native_mpfq_fixmp_6_rshift) */
5955 
5956 #if !defined(HAVE_native_mpfq_fixmp_6_long_rshift)
5957 /* a has 6 words. Shift it in place by off words plus cnt bits to the left.
5958  * Note that no carry is returned for the bits shifted out. */
5959 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5960 /* Triggered by: 6_invmod */
5961 static inline
mpfq_fixmp_6_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)5962 void mpfq_fixmp_6_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
5963 {
5964     if (cnt) {
5965         int dnt = GMP_NUMB_BITS - cnt;
5966         for (int i = 0; i < 6 - off - 1; ++i) {
5967             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
5968         }
5969         a[6-off-1] = a[6-1]>>cnt;
5970     } else {
5971         mpfq_copyi(a, a + off, 6 - off);
5972     }
5973     mpfq_zero(a + 6 - off, off);
5974 }
5975 #endif /* !defined(HAVE_native_mpfq_fixmp_6_long_rshift) */
5976 
5977 #if !defined(HAVE_native_mpfq_fixmp_6_long_lshift)
5978 /* a has 6 words. Shift it in place by off words plus cnt bits to the left.
5979  * Note that no carry is returned for the bits shifted out. */
5980 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
5981 /* Triggered by: 6_invmod */
5982 static inline
mpfq_fixmp_6_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)5983 void mpfq_fixmp_6_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
5984 {
5985     int i;
5986     if (cnt) {
5987         int dnt = GMP_NUMB_BITS - cnt;
5988         for (i = 6-1; i>off; --i) {
5989             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
5990         }
5991         a[off] = a[0]<<cnt;
5992     } else {
5993         mpfq_copyd(a + off, a, 6 - off);
5994     }
5995     mpfq_zero(a, off);
5996 }
5997 #endif /* !defined(HAVE_native_mpfq_fixmp_6_long_lshift) */
5998 
5999 #if !defined(HAVE_native_mpfq_fixmp_6_invmod)
6000 /* x, z, and p have 6 words. Put inverse of x mod p in z.
6001  * Return non-zero if an inverse could be found.
6002  * If no inverse could be found, return 0 and set z to zero.
6003  */
6004 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
6005 static inline
mpfq_fixmp_6_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)6006 int mpfq_fixmp_6_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
6007 {
6008       mp_limb_t u[6], v[6], a[6], b[6], fix[6];
6009       int i, t, lsh;
6010 
6011       mpfq_zero(u, 6);
6012       mpfq_zero(v, 6);
6013       mpfq_copy(a, x, 6);
6014       mpfq_copy(b, p, 6);
6015       u[0] = 1UL;
6016 
6017       if (mpfq_fixmp_6_cmp(a, v) == 0 || mpfq_fixmp_6_cmp(a, b) == 0) {
6018         mpfq_zero(res, 6);
6019         return 0;
6020       }
6021 
6022       mpfq_fixmp_6_add(fix, b, u);
6023       mpfq_fixmp_6_rshift(fix, 1);
6024 
6025       assert (mpfq_fixmp_6_cmp(a,b) < 0);
6026 
6027       t = 0;
6028 
6029       for(i = 0 ; !a[i] ; i++) ;
6030       assert (i < 6);
6031       lsh = mpfq_ctzl(a[i]);
6032       mpfq_fixmp_6_long_rshift(a, i, lsh);
6033       t += lsh + i*GMP_NUMB_BITS;
6034       mpfq_fixmp_6_long_lshift(v, i, lsh);
6035 
6036       do {
6037         do {
6038           mpfq_fixmp_6_sub(b, b, a);
6039           mpfq_fixmp_6_add(v, v, u);
6040           for(i = 0 ; !b[i] ; i++) ;
6041           assert (i < 6);
6042           lsh = mpfq_ctzl(b[i]);
6043           mpfq_fixmp_6_long_rshift(b, i, lsh);
6044           t += lsh + i*GMP_NUMB_BITS;
6045           mpfq_fixmp_6_long_lshift(u, i, lsh);
6046         } while (mpfq_fixmp_6_cmp(a,b) < 0);
6047         if (mpfq_fixmp_6_cmp(a, b) == 0)
6048           break;
6049         do {
6050           mpfq_fixmp_6_sub(a, a, b);
6051           mpfq_fixmp_6_add(u, u, v);
6052           for(i = 0 ; !a[i] ; i++) ;
6053           assert (i < 6);
6054           lsh = mpfq_ctzl(a[i]);
6055           mpfq_fixmp_6_long_rshift(a, i, lsh);
6056           t += lsh + i*GMP_NUMB_BITS;
6057           mpfq_fixmp_6_long_lshift(v, i, lsh);
6058         } while (mpfq_fixmp_6_cmp(b,a)<0);
6059       } while (mpfq_fixmp_6_cmp(a,b) != 0);
6060       {
6061         if (mpfq_fixmp_6_cmp_ui(a, 1) != 0) {
6062           mpfq_copy(res, a, 6);
6063           return 0;
6064         }
6065       }
6066       while (t>0) {
6067         mp_limb_t sig = u[0] & 1UL;
6068         mpfq_fixmp_6_rshift(u, 1);
6069         if (sig)
6070           mpfq_fixmp_6_add(u, u, fix);
6071         --t;
6072       }
6073       mpfq_copy(res, u, 6);
6074       return 1;
6075 }
6076 #endif /* !defined(HAVE_native_mpfq_fixmp_6_invmod) */
6077 
6078 #if !defined(HAVE_native_mpfq_fixmp_6_redc)
6079 /* x has 14 words, z and p have 6 words.
6080  * only one word is read from invp.
6081  * Assuming R=W^7 is the redc modulus, we expect that x verifies:
6082  *   x < R*p,
6083  * so that we have eventually z < p, z congruent to x/R mod p.
6084  * The contents of the area pointed by x are clobbered by this call.
6085  * Note also that x may alias z.
6086  */
6087 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
6088 static inline
mpfq_fixmp_6_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)6089 void mpfq_fixmp_6_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
6090 {
6091     mp_limb_t cy;
6092     for(int i = 0; i < 6; ++i) {
6093         mp_limb_t t = x[i]*mip[0];
6094         cy = mpfq_fixmp_6_addmul1_shortz(x+i, p, t);
6095         assert (x[i] == 0);
6096         x[i] = cy;
6097     }
6098     cy = mpfq_fixmp_6_add(x, x, x + 6);
6099     /* At this point, we have (x' denotes x + cy*W^n here)
6100     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
6101     * x'/R < p + p
6102     */
6103     if (cy || mpfq_fixmp_6_cmp(x, p) >= 0) {
6104         mpfq_fixmp_6_sub(z, x, p);
6105     } else {
6106         mpfq_copy(z, x, 6);
6107     }
6108 }
6109 #endif /* !defined(HAVE_native_mpfq_fixmp_6_redc) */
6110 
6111 #if !defined(HAVE_native_mpfq_fixmp_6_redc_ur)
6112 /* x has 15 words, z and p have 6 words.
6113  * only one word is read from invp.
6114  * Assuming R=W^7 is the redc modulus, we expect that x verifies:
6115  *  x < W*W^6*p = W^0.5*R*p or the hw case, W*R*p otherwise,
6116  * so that we have eventually z < p, z congruent to x/R mod p.
6117  * The contents of the area pointed by x are clobbered by this call.
6118  * Note also that x may alias z.
6119  */
6120 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
6121 static inline
mpfq_fixmp_6_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)6122 void mpfq_fixmp_6_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
6123 {
6124     mp_limb_t cy, q[2];
6125     for (int i = 0; i < 6; ++i) {
6126         mp_limb_t t = x[i]*mip[0];
6127         cy = mpfq_fixmp_6_addmul1(x+i, p, t);
6128         assert (x[i] == 0);
6129         x[i] = cy;
6130     }
6131     cy=mpfq_fixmp_6_add(x+6+1, x+6+1, x);
6132     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
6133     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
6134     * x'/R < (W+1)*p
6135     */
6136     if (cy) {
6137         /* x'/R-p < W*p, which fits in n+1 words */
6138         mpn_sub(x+6,x+6,6+1,p,6);
6139     }
6140     mpn_tdiv_qr(q, z, 0, x+6, 6+1, p, 6);
6141 }
6142 #endif /* !defined(HAVE_native_mpfq_fixmp_6_redc_ur) */
6143 
6144 #if !defined(HAVE_native_mpfq_fixmp_6_mgy_encode)
6145 /* x, z, and p have 6 words.
6146  * Assuming R=W^7 is the redc modulus, we compute z=R*x mod p. */
6147 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
6148 static inline
mpfq_fixmp_6_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)6149 void mpfq_fixmp_6_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
6150 {
6151     mp_limb_t t[12] = { 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5] };
6152     mpfq_fixmp_6_mod(z, t, p);
6153 }
6154 #endif /* !defined(HAVE_native_mpfq_fixmp_6_mgy_encode) */
6155 
6156 #if !defined(HAVE_native_mpfq_fixmp_6_mgy_decode)
6157 /* x, z, invR, and p have 6 words.
6158  * Assuming R=W^7 is the redc modulus, we compute z=x/R mod p. */
6159 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
6160 static inline
mpfq_fixmp_6_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)6161 void mpfq_fixmp_6_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
6162 {
6163     mp_limb_t t[12];
6164     mpfq_fixmp_6_mul(t, x, invR);
6165     mpfq_fixmp_6_mod(z, t, p);
6166 }
6167 #endif /* !defined(HAVE_native_mpfq_fixmp_6_mgy_decode) */
6168 
6169 #if !defined(HAVE_native_mpfq_fixmp_6_lshift)
6170 /* a has 6 words. Shift it in place by cnt bits to the left.
6171  * The shift count cnt must not exceed the word size.
6172  * Note that no carry is returned for the bits shifted out. */
6173 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
6174 static inline
mpfq_fixmp_6_lshift(mp_limb_t * a,int cnt)6175 void mpfq_fixmp_6_lshift(mp_limb_t * a, int cnt)
6176 {
6177     if (!cnt) return;
6178     int i;
6179     int dnt = GMP_NUMB_BITS - cnt;
6180     for (i = 6-1; i>0; --i) {
6181         a[i] <<= cnt;
6182         a[i] |= (a[i-1] >> dnt);
6183     }
6184     a[0] <<= cnt;
6185 }
6186 #endif /* !defined(HAVE_native_mpfq_fixmp_6_lshift) */
6187 
6188 #if !defined(HAVE_native_mpfq_fixmp_7_add)
6189 /* x, y, and z have 7 words. Result in z. Return carry bit */
6190 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
6191 /* Triggered by: 7_invmod, 7_redc, 7_redc_ur */
6192 static inline
mpfq_fixmp_7_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6193 mp_limb_t mpfq_fixmp_7_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6194 {
6195     mp_limb_t r, s, t, cy, cy1, cy2;
6196     cy = 0;
6197     r = x[0];
6198     s = r + y[0];
6199     cy1 = s < r;
6200     t = s + cy;
6201     cy2 = t < s;
6202     cy = cy1 | cy2;
6203     z[0] = t;
6204     r = x[1];
6205     s = r + y[1];
6206     cy1 = s < r;
6207     t = s + cy;
6208     cy2 = t < s;
6209     cy = cy1 | cy2;
6210     z[1] = t;
6211     r = x[2];
6212     s = r + y[2];
6213     cy1 = s < r;
6214     t = s + cy;
6215     cy2 = t < s;
6216     cy = cy1 | cy2;
6217     z[2] = t;
6218     r = x[3];
6219     s = r + y[3];
6220     cy1 = s < r;
6221     t = s + cy;
6222     cy2 = t < s;
6223     cy = cy1 | cy2;
6224     z[3] = t;
6225     r = x[4];
6226     s = r + y[4];
6227     cy1 = s < r;
6228     t = s + cy;
6229     cy2 = t < s;
6230     cy = cy1 | cy2;
6231     z[4] = t;
6232     r = x[5];
6233     s = r + y[5];
6234     cy1 = s < r;
6235     t = s + cy;
6236     cy2 = t < s;
6237     cy = cy1 | cy2;
6238     z[5] = t;
6239     r = x[6];
6240     s = r + y[6];
6241     cy1 = s < r;
6242     t = s + cy;
6243     cy2 = t < s;
6244     cy = cy1 | cy2;
6245     z[6] = t;
6246     return cy;
6247 }
6248 #endif /* !defined(HAVE_native_mpfq_fixmp_7_add) */
6249 
6250 #if !defined(HAVE_native_mpfq_fixmp_7_sub)
6251 /* x, y, and z have 7 words. Result in z. Return borrow bit */
6252 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
6253 /* Triggered by: 7_invmod, 7_redc */
6254 static inline
mpfq_fixmp_7_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6255 mp_limb_t mpfq_fixmp_7_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6256 {
6257     mp_limb_t r, s, t, cy, cy1, cy2;
6258     cy = 0;
6259     r = x[0];
6260     s = r - y[0];
6261     cy1 = s > r;
6262     t = s - cy;
6263     cy2 = t > s;
6264     cy = cy1 | cy2;
6265     z[0] = t;
6266     r = x[1];
6267     s = r - y[1];
6268     cy1 = s > r;
6269     t = s - cy;
6270     cy2 = t > s;
6271     cy = cy1 | cy2;
6272     z[1] = t;
6273     r = x[2];
6274     s = r - y[2];
6275     cy1 = s > r;
6276     t = s - cy;
6277     cy2 = t > s;
6278     cy = cy1 | cy2;
6279     z[2] = t;
6280     r = x[3];
6281     s = r - y[3];
6282     cy1 = s > r;
6283     t = s - cy;
6284     cy2 = t > s;
6285     cy = cy1 | cy2;
6286     z[3] = t;
6287     r = x[4];
6288     s = r - y[4];
6289     cy1 = s > r;
6290     t = s - cy;
6291     cy2 = t > s;
6292     cy = cy1 | cy2;
6293     z[4] = t;
6294     r = x[5];
6295     s = r - y[5];
6296     cy1 = s > r;
6297     t = s - cy;
6298     cy2 = t > s;
6299     cy = cy1 | cy2;
6300     z[5] = t;
6301     r = x[6];
6302     s = r - y[6];
6303     cy1 = s > r;
6304     t = s - cy;
6305     cy2 = t > s;
6306     cy = cy1 | cy2;
6307     z[6] = t;
6308     return cy;
6309 }
6310 #endif /* !defined(HAVE_native_mpfq_fixmp_7_sub) */
6311 
6312 #if !defined(HAVE_native_mpfq_fixmp_7_add_nc)
6313 /* x, y, and z have 7 words. Result in z. Carry bit is lost. */
6314 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
6315 static inline
mpfq_fixmp_7_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6316 void mpfq_fixmp_7_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6317 {
6318     mp_limb_t r, s, t, cy, cy1, cy2;
6319     cy = 0;
6320     r = x[0];
6321     s = r + y[0];
6322     cy1 = s < r;
6323     t = s + cy;
6324     cy2 = t < s;
6325     cy = cy1 | cy2;
6326     z[0] = t;
6327     r = x[1];
6328     s = r + y[1];
6329     cy1 = s < r;
6330     t = s + cy;
6331     cy2 = t < s;
6332     cy = cy1 | cy2;
6333     z[1] = t;
6334     r = x[2];
6335     s = r + y[2];
6336     cy1 = s < r;
6337     t = s + cy;
6338     cy2 = t < s;
6339     cy = cy1 | cy2;
6340     z[2] = t;
6341     r = x[3];
6342     s = r + y[3];
6343     cy1 = s < r;
6344     t = s + cy;
6345     cy2 = t < s;
6346     cy = cy1 | cy2;
6347     z[3] = t;
6348     r = x[4];
6349     s = r + y[4];
6350     cy1 = s < r;
6351     t = s + cy;
6352     cy2 = t < s;
6353     cy = cy1 | cy2;
6354     z[4] = t;
6355     r = x[5];
6356     s = r + y[5];
6357     cy1 = s < r;
6358     t = s + cy;
6359     cy2 = t < s;
6360     cy = cy1 | cy2;
6361     z[5] = t;
6362     r = x[6];
6363     s = r + y[6];
6364     cy1 = s < r;
6365     t = s + cy;
6366     cy2 = t < s;
6367     cy = cy1 | cy2;
6368     z[6] = t;
6369 }
6370 #endif /* !defined(HAVE_native_mpfq_fixmp_7_add_nc) */
6371 
6372 #if !defined(HAVE_native_mpfq_fixmp_7_sub_nc)
6373 /* x, y, and z have 7 words. Result in z. Borrow bit is lost. */
6374 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
6375 static inline
mpfq_fixmp_7_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6376 void mpfq_fixmp_7_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6377 {
6378     mp_limb_t r, s, t, cy, cy1, cy2;
6379     cy = 0;
6380     r = x[0];
6381     s = r - y[0];
6382     cy1 = s > r;
6383     t = s - cy;
6384     cy2 = t > s;
6385     cy = cy1 | cy2;
6386     z[0] = t;
6387     r = x[1];
6388     s = r - y[1];
6389     cy1 = s > r;
6390     t = s - cy;
6391     cy2 = t > s;
6392     cy = cy1 | cy2;
6393     z[1] = t;
6394     r = x[2];
6395     s = r - y[2];
6396     cy1 = s > r;
6397     t = s - cy;
6398     cy2 = t > s;
6399     cy = cy1 | cy2;
6400     z[2] = t;
6401     r = x[3];
6402     s = r - y[3];
6403     cy1 = s > r;
6404     t = s - cy;
6405     cy2 = t > s;
6406     cy = cy1 | cy2;
6407     z[3] = t;
6408     r = x[4];
6409     s = r - y[4];
6410     cy1 = s > r;
6411     t = s - cy;
6412     cy2 = t > s;
6413     cy = cy1 | cy2;
6414     z[4] = t;
6415     r = x[5];
6416     s = r - y[5];
6417     cy1 = s > r;
6418     t = s - cy;
6419     cy2 = t > s;
6420     cy = cy1 | cy2;
6421     z[5] = t;
6422     r = x[6];
6423     s = r - y[6];
6424     cy1 = s > r;
6425     t = s - cy;
6426     cy2 = t > s;
6427     cy = cy1 | cy2;
6428     z[6] = t;
6429 }
6430 #endif /* !defined(HAVE_native_mpfq_fixmp_7_sub_nc) */
6431 
6432 #if !defined(HAVE_native_mpfq_fixmp_7_add_ui)
6433 /* x, y, and z have 7 words. Result in z. Return carry bit */
6434 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
6435 static inline
mpfq_fixmp_7_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)6436 mp_limb_t mpfq_fixmp_7_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
6437 {
6438     mp_limb_t r, s, t, cy, cy1, cy2;
6439     cy = 0;
6440     r = x[0];
6441     s = r + y;
6442     cy1 = s < r;
6443     t = s + cy;
6444     cy2 = t < s;
6445     cy = cy1 | cy2;
6446     z[0] = t;
6447     s = x[1];
6448     t = s + cy;
6449     cy = t < s;
6450     z[1] = t;
6451     s = x[2];
6452     t = s + cy;
6453     cy = t < s;
6454     z[2] = t;
6455     s = x[3];
6456     t = s + cy;
6457     cy = t < s;
6458     z[3] = t;
6459     s = x[4];
6460     t = s + cy;
6461     cy = t < s;
6462     z[4] = t;
6463     s = x[5];
6464     t = s + cy;
6465     cy = t < s;
6466     z[5] = t;
6467     s = x[6];
6468     t = s + cy;
6469     cy = t < s;
6470     z[6] = t;
6471     return cy;
6472 }
6473 #endif /* !defined(HAVE_native_mpfq_fixmp_7_add_ui) */
6474 
6475 #if !defined(HAVE_native_mpfq_fixmp_7_sub_ui)
6476 /* x, y, and z have 7 words. Result in z. Return borrow bit */
6477 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
6478 static inline
mpfq_fixmp_7_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)6479 mp_limb_t mpfq_fixmp_7_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
6480 {
6481     mp_limb_t r, s, t, cy, cy1, cy2;
6482     cy = 0;
6483     r = x[0];
6484     s = r - y;
6485     cy1 = s > r;
6486     t = s - cy;
6487     cy2 = t > s;
6488     cy = cy1 | cy2;
6489     z[0] = t;
6490     s = x[1];
6491     t = s - cy;
6492     cy = t > s;
6493     z[1] = t;
6494     s = x[2];
6495     t = s - cy;
6496     cy = t > s;
6497     z[2] = t;
6498     s = x[3];
6499     t = s - cy;
6500     cy = t > s;
6501     z[3] = t;
6502     s = x[4];
6503     t = s - cy;
6504     cy = t > s;
6505     z[4] = t;
6506     s = x[5];
6507     t = s - cy;
6508     cy = t > s;
6509     z[5] = t;
6510     s = x[6];
6511     t = s - cy;
6512     cy = t > s;
6513     z[6] = t;
6514     return cy;
6515 }
6516 #endif /* !defined(HAVE_native_mpfq_fixmp_7_sub_ui) */
6517 
6518 #if !defined(HAVE_native_mpfq_fixmp_7_add_ui_nc)
6519 /* x, y, and z have 7 words. Result in z. Carry bit is lost. */
6520 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
6521 static inline
mpfq_fixmp_7_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)6522 void mpfq_fixmp_7_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
6523 {
6524     mp_limb_t r, s, t, cy, cy1, cy2;
6525     cy = 0;
6526     r = x[0];
6527     s = r + y;
6528     cy1 = s < r;
6529     t = s + cy;
6530     cy2 = t < s;
6531     cy = cy1 | cy2;
6532     z[0] = t;
6533     s = x[1];
6534     t = s + cy;
6535     cy = t < s;
6536     z[1] = t;
6537     s = x[2];
6538     t = s + cy;
6539     cy = t < s;
6540     z[2] = t;
6541     s = x[3];
6542     t = s + cy;
6543     cy = t < s;
6544     z[3] = t;
6545     s = x[4];
6546     t = s + cy;
6547     cy = t < s;
6548     z[4] = t;
6549     s = x[5];
6550     t = s + cy;
6551     cy = t < s;
6552     z[5] = t;
6553     s = x[6];
6554     t = s + cy;
6555     cy = t < s;
6556     z[6] = t;
6557 }
6558 #endif /* !defined(HAVE_native_mpfq_fixmp_7_add_ui_nc) */
6559 
6560 #if !defined(HAVE_native_mpfq_fixmp_7_sub_ui_nc)
6561 /* x, y, and z have 7 words. Result in z. Borrow bit is lost. */
6562 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
6563 static inline
mpfq_fixmp_7_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)6564 void mpfq_fixmp_7_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
6565 {
6566     mp_limb_t r, s, t, cy, cy1, cy2;
6567     cy = 0;
6568     r = x[0];
6569     s = r - y;
6570     cy1 = s > r;
6571     t = s - cy;
6572     cy2 = t > s;
6573     cy = cy1 | cy2;
6574     z[0] = t;
6575     s = x[1];
6576     t = s - cy;
6577     cy = t > s;
6578     z[1] = t;
6579     s = x[2];
6580     t = s - cy;
6581     cy = t > s;
6582     z[2] = t;
6583     s = x[3];
6584     t = s - cy;
6585     cy = t > s;
6586     z[3] = t;
6587     s = x[4];
6588     t = s - cy;
6589     cy = t > s;
6590     z[4] = t;
6591     s = x[5];
6592     t = s - cy;
6593     cy = t > s;
6594     z[5] = t;
6595     s = x[6];
6596     t = s - cy;
6597     cy = t > s;
6598     z[6] = t;
6599 }
6600 #endif /* !defined(HAVE_native_mpfq_fixmp_7_sub_ui_nc) */
6601 
6602 #if !defined(HAVE_native_mpfq_fixmp_7_cmp)
6603 /* x and y have 7 words. Return sign of difference x-y. */
6604 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
6605 /* Triggered by: 7_invmod, 7_redc */
6606 static inline
mpfq_fixmp_7_cmp(const mp_limb_t * x,const mp_limb_t * y)6607 int mpfq_fixmp_7_cmp(const mp_limb_t * x, const mp_limb_t * y)
6608 {
6609     for (int i = 7-1; i >= 0; --i) {
6610         if (x[i] > y[i]) return 1;
6611         if (x[i] < y[i]) return -1;
6612     }
6613     return 0;
6614 }
6615 #endif /* !defined(HAVE_native_mpfq_fixmp_7_cmp) */
6616 
6617 #if !defined(HAVE_native_mpfq_fixmp_7_cmp_ui)
6618 /* x has 7 words. Return sign of difference x-y. */
6619 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
6620 /* Triggered by: 7_invmod */
6621 static inline
mpfq_fixmp_7_cmp_ui(const mp_limb_t * x,mp_limb_t y)6622 int mpfq_fixmp_7_cmp_ui(const mp_limb_t * x, mp_limb_t y)
6623 {
6624     for (int i = 7-1; i > 0; --i) {
6625         if (x[i]) return 1;
6626     }
6627     if (x[0]>y) return 1;
6628     if (x[0]<y) return -1;
6629     return 0;
6630 }
6631 #endif /* !defined(HAVE_native_mpfq_fixmp_7_cmp_ui) */
6632 
6633 #if !defined(HAVE_native_mpfq_fixmp_7_addmul1)
6634 /* x has 7 words, z has 9.
6635  * Put (z+x*c) in z. Return carry bit. */
6636 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
6637 /* Triggered by: 7_redc_ur */
6638 static inline
mpfq_fixmp_7_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)6639 mp_limb_t mpfq_fixmp_7_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
6640 {
6641     mp_limb_t hi, lo, carry, buf;
6642     carry = 0;
6643     mpfq_umul_ppmm(hi,lo,c,x[0]);
6644     lo += carry;
6645     carry = (lo<carry) + hi;
6646     buf = z[0];
6647     lo += buf;
6648     carry += (lo<buf);
6649     z[0] = lo;
6650     mpfq_umul_ppmm(hi,lo,c,x[1]);
6651     lo += carry;
6652     carry = (lo<carry) + hi;
6653     buf = z[1];
6654     lo += buf;
6655     carry += (lo<buf);
6656     z[1] = lo;
6657     mpfq_umul_ppmm(hi,lo,c,x[2]);
6658     lo += carry;
6659     carry = (lo<carry) + hi;
6660     buf = z[2];
6661     lo += buf;
6662     carry += (lo<buf);
6663     z[2] = lo;
6664     mpfq_umul_ppmm(hi,lo,c,x[3]);
6665     lo += carry;
6666     carry = (lo<carry) + hi;
6667     buf = z[3];
6668     lo += buf;
6669     carry += (lo<buf);
6670     z[3] = lo;
6671     mpfq_umul_ppmm(hi,lo,c,x[4]);
6672     lo += carry;
6673     carry = (lo<carry) + hi;
6674     buf = z[4];
6675     lo += buf;
6676     carry += (lo<buf);
6677     z[4] = lo;
6678     mpfq_umul_ppmm(hi,lo,c,x[5]);
6679     lo += carry;
6680     carry = (lo<carry) + hi;
6681     buf = z[5];
6682     lo += buf;
6683     carry += (lo<buf);
6684     z[5] = lo;
6685     mpfq_umul_ppmm(hi,lo,c,x[6]);
6686     lo += carry;
6687     carry = (lo<carry) + hi;
6688     buf = z[6];
6689     lo += buf;
6690     carry += (lo<buf);
6691     z[6] = lo;
6692     z[7] += carry;
6693     return (z[7]<carry);
6694 }
6695 #endif /* !defined(HAVE_native_mpfq_fixmp_7_addmul1) */
6696 
6697 #if !defined(HAVE_native_mpfq_fixmp_7_addmul1_nc)
6698 /* x has 7 words, z has 9.
6699  * Put (z+x*c) in z. Carry bit is lost. */
6700 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
6701 /* Triggered by: 7_mul, 7_mgy_decode, 8_sqr, 8_shortmul, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 7_5_sqr, 7_5_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
6702 static inline
mpfq_fixmp_7_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)6703 void mpfq_fixmp_7_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
6704 {
6705     mp_limb_t hi, lo, carry, buf;
6706     carry = 0;
6707     mpfq_umul_ppmm(hi,lo,c,x[0]);
6708     lo += carry;
6709     carry = (lo<carry) + hi;
6710     buf = z[0];
6711     lo += buf;
6712     carry += (lo<buf);
6713     z[0] = lo;
6714     mpfq_umul_ppmm(hi,lo,c,x[1]);
6715     lo += carry;
6716     carry = (lo<carry) + hi;
6717     buf = z[1];
6718     lo += buf;
6719     carry += (lo<buf);
6720     z[1] = lo;
6721     mpfq_umul_ppmm(hi,lo,c,x[2]);
6722     lo += carry;
6723     carry = (lo<carry) + hi;
6724     buf = z[2];
6725     lo += buf;
6726     carry += (lo<buf);
6727     z[2] = lo;
6728     mpfq_umul_ppmm(hi,lo,c,x[3]);
6729     lo += carry;
6730     carry = (lo<carry) + hi;
6731     buf = z[3];
6732     lo += buf;
6733     carry += (lo<buf);
6734     z[3] = lo;
6735     mpfq_umul_ppmm(hi,lo,c,x[4]);
6736     lo += carry;
6737     carry = (lo<carry) + hi;
6738     buf = z[4];
6739     lo += buf;
6740     carry += (lo<buf);
6741     z[4] = lo;
6742     mpfq_umul_ppmm(hi,lo,c,x[5]);
6743     lo += carry;
6744     carry = (lo<carry) + hi;
6745     buf = z[5];
6746     lo += buf;
6747     carry += (lo<buf);
6748     z[5] = lo;
6749     mpfq_umul_ppmm(hi,lo,c,x[6]);
6750     lo += carry;
6751     carry = (lo<carry) + hi;
6752     buf = z[6];
6753     lo += buf;
6754     carry += (lo<buf);
6755     z[6] = lo;
6756     z[7] += carry;
6757 }
6758 #endif /* !defined(HAVE_native_mpfq_fixmp_7_addmul1_nc) */
6759 
6760 #if !defined(HAVE_native_mpfq_fixmp_7_addmul1_shortz)
6761 /* x has 7 words, z has 8.
6762  * Put (z+x*c) in z. Return carry word. */
6763 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
6764 /* Triggered by: 7_redc */
6765 static inline
mpfq_fixmp_7_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)6766 mp_limb_t mpfq_fixmp_7_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
6767 {
6768     mp_limb_t hi, lo, carry, buf;
6769     carry = 0;
6770     mpfq_umul_ppmm(hi,lo,c,x[0]);
6771     lo += carry;
6772     carry = (lo<carry) + hi;
6773     buf = z[0];
6774     lo += buf;
6775     carry += (lo<buf);
6776     z[0] = lo;
6777     mpfq_umul_ppmm(hi,lo,c,x[1]);
6778     lo += carry;
6779     carry = (lo<carry) + hi;
6780     buf = z[1];
6781     lo += buf;
6782     carry += (lo<buf);
6783     z[1] = lo;
6784     mpfq_umul_ppmm(hi,lo,c,x[2]);
6785     lo += carry;
6786     carry = (lo<carry) + hi;
6787     buf = z[2];
6788     lo += buf;
6789     carry += (lo<buf);
6790     z[2] = lo;
6791     mpfq_umul_ppmm(hi,lo,c,x[3]);
6792     lo += carry;
6793     carry = (lo<carry) + hi;
6794     buf = z[3];
6795     lo += buf;
6796     carry += (lo<buf);
6797     z[3] = lo;
6798     mpfq_umul_ppmm(hi,lo,c,x[4]);
6799     lo += carry;
6800     carry = (lo<carry) + hi;
6801     buf = z[4];
6802     lo += buf;
6803     carry += (lo<buf);
6804     z[4] = lo;
6805     mpfq_umul_ppmm(hi,lo,c,x[5]);
6806     lo += carry;
6807     carry = (lo<carry) + hi;
6808     buf = z[5];
6809     lo += buf;
6810     carry += (lo<buf);
6811     z[5] = lo;
6812     mpfq_umul_ppmm(hi,lo,c,x[6]);
6813     lo += carry;
6814     carry = (lo<carry) + hi;
6815     buf = z[6];
6816     lo += buf;
6817     carry += (lo<buf);
6818     z[6] = lo;
6819     return carry;
6820 }
6821 #endif /* !defined(HAVE_native_mpfq_fixmp_7_addmul1_shortz) */
6822 
6823 #if !defined(HAVE_native_mpfq_fixmp_7_mul)
6824 /* x and y have 7 words, z has 16. Put x*y in z. */
6825 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
6826 /* Triggered by: 7_mgy_decode */
6827 static inline
mpfq_fixmp_7_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6828 void mpfq_fixmp_7_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6829 {
6830     assert(z != x && z != y);
6831     for (int i = 0; i < 14; z[i++] = 0) ;
6832     mpfq_fixmp_7_addmul1_nc (z + 0, x, y[0]);
6833     mpfq_fixmp_7_addmul1_nc (z + 1, x, y[1]);
6834     mpfq_fixmp_7_addmul1_nc (z + 2, x, y[2]);
6835     mpfq_fixmp_7_addmul1_nc (z + 3, x, y[3]);
6836     mpfq_fixmp_7_addmul1_nc (z + 4, x, y[4]);
6837     mpfq_fixmp_7_addmul1_nc (z + 5, x, y[5]);
6838     mpfq_fixmp_7_addmul1_nc (z + 6, x, y[6]);
6839 }
6840 #endif /* !defined(HAVE_native_mpfq_fixmp_7_mul) */
6841 
6842 #if !defined(HAVE_native_mpfq_fixmp_7_sqr)
6843 /* x has 7 words, z has 16. Put x*y in z. */
6844 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
6845 static inline
mpfq_fixmp_7_sqr(mp_limb_t * z,const mp_limb_t * x)6846 void mpfq_fixmp_7_sqr(mp_limb_t * z, const mp_limb_t * x)
6847 {
6848     mp_limb_t buf[14] = {0,};
6849     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
6850     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
6851     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
6852     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
6853     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
6854     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
6855     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
6856     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
6857     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
6858     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
6859     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
6860     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
6861     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
6862     mpn_lshift(buf, buf, 14, 1);
6863     mpn_add_n(z, z, buf, 14);
6864 }
6865 #endif /* !defined(HAVE_native_mpfq_fixmp_7_sqr) */
6866 
6867 #if !defined(HAVE_native_mpfq_fixmp_7_mul1)
6868 /* x has 7 words, z has 9. Put x*y in z. */
6869 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
6870 static inline
mpfq_fixmp_7_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)6871 void mpfq_fixmp_7_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
6872 {
6873     mp_limb_t hi, lo, carry;
6874     carry = 0;
6875     mpfq_umul_ppmm(hi,lo,c,x[0]);
6876     lo += carry;
6877     carry = (lo<carry) + hi;
6878     z[0] = lo;
6879     mpfq_umul_ppmm(hi,lo,c,x[1]);
6880     lo += carry;
6881     carry = (lo<carry) + hi;
6882     z[1] = lo;
6883     mpfq_umul_ppmm(hi,lo,c,x[2]);
6884     lo += carry;
6885     carry = (lo<carry) + hi;
6886     z[2] = lo;
6887     mpfq_umul_ppmm(hi,lo,c,x[3]);
6888     lo += carry;
6889     carry = (lo<carry) + hi;
6890     z[3] = lo;
6891     mpfq_umul_ppmm(hi,lo,c,x[4]);
6892     lo += carry;
6893     carry = (lo<carry) + hi;
6894     z[4] = lo;
6895     mpfq_umul_ppmm(hi,lo,c,x[5]);
6896     lo += carry;
6897     carry = (lo<carry) + hi;
6898     z[5] = lo;
6899     mpfq_umul_ppmm(hi,lo,c,x[6]);
6900     lo += carry;
6901     carry = (lo<carry) + hi;
6902     z[6] = lo;
6903     z[7] = carry;
6904 }
6905 #endif /* !defined(HAVE_native_mpfq_fixmp_7_mul1) */
6906 
6907 #if !defined(HAVE_native_mpfq_fixmp_7_shortmul)
6908 /* x and y have 7 words, z has 8.
6909  * Put the low 8 words of x*y in z. */
6910 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
6911 static inline
mpfq_fixmp_7_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)6912 void mpfq_fixmp_7_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
6913 {
6914     mpfq_zero(z, 7);
6915     mpfq_fixmp_6_addmul1_nc (z+0, x, y[0]);
6916     z[7-1] += x[6]*y[0];
6917     mpfq_fixmp_5_addmul1_nc (z+1, x, y[1]);
6918     z[7-1] += x[5]*y[1];
6919     mpfq_fixmp_4_addmul1_nc (z+2, x, y[2]);
6920     z[7-1] += x[4]*y[2];
6921     mpfq_fixmp_3_addmul1_nc (z+3, x, y[3]);
6922     z[7-1] += x[3]*y[3];
6923     mpfq_fixmp_2_addmul1_nc (z+4, x, y[4]);
6924     z[7-1] += x[2]*y[4];
6925     mpfq_fixmp_1_addmul1_nc (z+5, x, y[5]);
6926     z[7-1] += x[1]*y[5];
6927     z[7-1] += x[0]*y[7-1];
6928 }
6929 #endif /* !defined(HAVE_native_mpfq_fixmp_7_shortmul) */
6930 
6931 #if !defined(HAVE_native_mpfq_fixmp_7_mod)
6932 /* x has 16 words. z and p have 7 words, and the high word of p is non-zero.
6933  * Put x mod p in z. */
6934 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
6935 /* Triggered by: 7_mgy_decode */
6936 static inline
mpfq_fixmp_7_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)6937 void mpfq_fixmp_7_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
6938 {
6939     mp_limb_t q[7+1], r[7];
6940     assert (p[7-1] != 0);
6941     mpn_tdiv_qr(q, r, 0, x, 14, p, 7);
6942     mpfq_copy(z, r, 7);
6943 }
6944 #endif /* !defined(HAVE_native_mpfq_fixmp_7_mod) */
6945 
6946 #if !defined(HAVE_native_mpfq_fixmp_7_rshift)
6947 /* a has 7 words. Shift it in place by cnt bits to the right.
6948  * The shift count cnt must not exceed the word size.
6949  * Note that no carry is returned for the bits shifted out. */
6950 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
6951 /* Triggered by: 7_invmod */
6952 static inline
mpfq_fixmp_7_rshift(mp_limb_t * a,int cnt)6953 void mpfq_fixmp_7_rshift(mp_limb_t * a, int cnt)
6954 {
6955     if (!cnt) return;
6956     int i;
6957     int dnt = GMP_NUMB_BITS - cnt;
6958     for (i = 0; i < 7-1; ++i) {
6959         a[i] >>= cnt;
6960         a[i] |= (a[i+1] << dnt);
6961     }
6962     a[7-1] >>= cnt;
6963 }
6964 #endif /* !defined(HAVE_native_mpfq_fixmp_7_rshift) */
6965 
6966 #if !defined(HAVE_native_mpfq_fixmp_7_long_rshift)
6967 /* a has 7 words. Shift it in place by off words plus cnt bits to the left.
6968  * Note that no carry is returned for the bits shifted out. */
6969 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
6970 /* Triggered by: 7_invmod */
6971 static inline
mpfq_fixmp_7_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)6972 void mpfq_fixmp_7_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
6973 {
6974     if (cnt) {
6975         int dnt = GMP_NUMB_BITS - cnt;
6976         for (int i = 0; i < 7 - off - 1; ++i) {
6977             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
6978         }
6979         a[7-off-1] = a[7-1]>>cnt;
6980     } else {
6981         mpfq_copyi(a, a + off, 7 - off);
6982     }
6983     mpfq_zero(a + 7 - off, off);
6984 }
6985 #endif /* !defined(HAVE_native_mpfq_fixmp_7_long_rshift) */
6986 
6987 #if !defined(HAVE_native_mpfq_fixmp_7_long_lshift)
6988 /* a has 7 words. Shift it in place by off words plus cnt bits to the left.
6989  * Note that no carry is returned for the bits shifted out. */
6990 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
6991 /* Triggered by: 7_invmod */
6992 static inline
mpfq_fixmp_7_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)6993 void mpfq_fixmp_7_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
6994 {
6995     int i;
6996     if (cnt) {
6997         int dnt = GMP_NUMB_BITS - cnt;
6998         for (i = 7-1; i>off; --i) {
6999             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
7000         }
7001         a[off] = a[0]<<cnt;
7002     } else {
7003         mpfq_copyd(a + off, a, 7 - off);
7004     }
7005     mpfq_zero(a, off);
7006 }
7007 #endif /* !defined(HAVE_native_mpfq_fixmp_7_long_lshift) */
7008 
7009 #if !defined(HAVE_native_mpfq_fixmp_7_invmod)
7010 /* x, z, and p have 7 words. Put inverse of x mod p in z.
7011  * Return non-zero if an inverse could be found.
7012  * If no inverse could be found, return 0 and set z to zero.
7013  */
7014 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
7015 static inline
mpfq_fixmp_7_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)7016 int mpfq_fixmp_7_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
7017 {
7018       mp_limb_t u[7], v[7], a[7], b[7], fix[7];
7019       int i, t, lsh;
7020 
7021       mpfq_zero(u, 7);
7022       mpfq_zero(v, 7);
7023       mpfq_copy(a, x, 7);
7024       mpfq_copy(b, p, 7);
7025       u[0] = 1UL;
7026 
7027       if (mpfq_fixmp_7_cmp(a, v) == 0 || mpfq_fixmp_7_cmp(a, b) == 0) {
7028         mpfq_zero(res, 7);
7029         return 0;
7030       }
7031 
7032       mpfq_fixmp_7_add(fix, b, u);
7033       mpfq_fixmp_7_rshift(fix, 1);
7034 
7035       assert (mpfq_fixmp_7_cmp(a,b) < 0);
7036 
7037       t = 0;
7038 
7039       for(i = 0 ; !a[i] ; i++) ;
7040       assert (i < 7);
7041       lsh = mpfq_ctzl(a[i]);
7042       mpfq_fixmp_7_long_rshift(a, i, lsh);
7043       t += lsh + i*GMP_NUMB_BITS;
7044       mpfq_fixmp_7_long_lshift(v, i, lsh);
7045 
7046       do {
7047         do {
7048           mpfq_fixmp_7_sub(b, b, a);
7049           mpfq_fixmp_7_add(v, v, u);
7050           for(i = 0 ; !b[i] ; i++) ;
7051           assert (i < 7);
7052           lsh = mpfq_ctzl(b[i]);
7053           mpfq_fixmp_7_long_rshift(b, i, lsh);
7054           t += lsh + i*GMP_NUMB_BITS;
7055           mpfq_fixmp_7_long_lshift(u, i, lsh);
7056         } while (mpfq_fixmp_7_cmp(a,b) < 0);
7057         if (mpfq_fixmp_7_cmp(a, b) == 0)
7058           break;
7059         do {
7060           mpfq_fixmp_7_sub(a, a, b);
7061           mpfq_fixmp_7_add(u, u, v);
7062           for(i = 0 ; !a[i] ; i++) ;
7063           assert (i < 7);
7064           lsh = mpfq_ctzl(a[i]);
7065           mpfq_fixmp_7_long_rshift(a, i, lsh);
7066           t += lsh + i*GMP_NUMB_BITS;
7067           mpfq_fixmp_7_long_lshift(v, i, lsh);
7068         } while (mpfq_fixmp_7_cmp(b,a)<0);
7069       } while (mpfq_fixmp_7_cmp(a,b) != 0);
7070       {
7071         if (mpfq_fixmp_7_cmp_ui(a, 1) != 0) {
7072           mpfq_copy(res, a, 7);
7073           return 0;
7074         }
7075       }
7076       while (t>0) {
7077         mp_limb_t sig = u[0] & 1UL;
7078         mpfq_fixmp_7_rshift(u, 1);
7079         if (sig)
7080           mpfq_fixmp_7_add(u, u, fix);
7081         --t;
7082       }
7083       mpfq_copy(res, u, 7);
7084       return 1;
7085 }
7086 #endif /* !defined(HAVE_native_mpfq_fixmp_7_invmod) */
7087 
7088 #if !defined(HAVE_native_mpfq_fixmp_7_redc)
7089 /* x has 16 words, z and p have 7 words.
7090  * only one word is read from invp.
7091  * Assuming R=W^8 is the redc modulus, we expect that x verifies:
7092  *   x < R*p,
7093  * so that we have eventually z < p, z congruent to x/R mod p.
7094  * The contents of the area pointed by x are clobbered by this call.
7095  * Note also that x may alias z.
7096  */
7097 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
7098 static inline
mpfq_fixmp_7_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)7099 void mpfq_fixmp_7_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
7100 {
7101     mp_limb_t cy;
7102     for(int i = 0; i < 7; ++i) {
7103         mp_limb_t t = x[i]*mip[0];
7104         cy = mpfq_fixmp_7_addmul1_shortz(x+i, p, t);
7105         assert (x[i] == 0);
7106         x[i] = cy;
7107     }
7108     cy = mpfq_fixmp_7_add(x, x, x + 7);
7109     /* At this point, we have (x' denotes x + cy*W^n here)
7110     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
7111     * x'/R < p + p
7112     */
7113     if (cy || mpfq_fixmp_7_cmp(x, p) >= 0) {
7114         mpfq_fixmp_7_sub(z, x, p);
7115     } else {
7116         mpfq_copy(z, x, 7);
7117     }
7118 }
7119 #endif /* !defined(HAVE_native_mpfq_fixmp_7_redc) */
7120 
7121 #if !defined(HAVE_native_mpfq_fixmp_7_redc_ur)
7122 /* x has 17 words, z and p have 7 words.
7123  * only one word is read from invp.
7124  * Assuming R=W^8 is the redc modulus, we expect that x verifies:
7125  *  x < W*W^7*p = W^0.5*R*p or the hw case, W*R*p otherwise,
7126  * so that we have eventually z < p, z congruent to x/R mod p.
7127  * The contents of the area pointed by x are clobbered by this call.
7128  * Note also that x may alias z.
7129  */
7130 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
7131 static inline
mpfq_fixmp_7_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)7132 void mpfq_fixmp_7_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
7133 {
7134     mp_limb_t cy, q[2];
7135     for (int i = 0; i < 7; ++i) {
7136         mp_limb_t t = x[i]*mip[0];
7137         cy = mpfq_fixmp_7_addmul1(x+i, p, t);
7138         assert (x[i] == 0);
7139         x[i] = cy;
7140     }
7141     cy=mpfq_fixmp_7_add(x+7+1, x+7+1, x);
7142     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
7143     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
7144     * x'/R < (W+1)*p
7145     */
7146     if (cy) {
7147         /* x'/R-p < W*p, which fits in n+1 words */
7148         mpn_sub(x+7,x+7,7+1,p,7);
7149     }
7150     mpn_tdiv_qr(q, z, 0, x+7, 7+1, p, 7);
7151 }
7152 #endif /* !defined(HAVE_native_mpfq_fixmp_7_redc_ur) */
7153 
7154 #if !defined(HAVE_native_mpfq_fixmp_7_mgy_encode)
7155 /* x, z, and p have 7 words.
7156  * Assuming R=W^8 is the redc modulus, we compute z=R*x mod p. */
7157 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
7158 static inline
mpfq_fixmp_7_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)7159 void mpfq_fixmp_7_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
7160 {
7161     mp_limb_t t[14] = { 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6] };
7162     mpfq_fixmp_7_mod(z, t, p);
7163 }
7164 #endif /* !defined(HAVE_native_mpfq_fixmp_7_mgy_encode) */
7165 
7166 #if !defined(HAVE_native_mpfq_fixmp_7_mgy_decode)
7167 /* x, z, invR, and p have 7 words.
7168  * Assuming R=W^8 is the redc modulus, we compute z=x/R mod p. */
7169 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
7170 static inline
mpfq_fixmp_7_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)7171 void mpfq_fixmp_7_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
7172 {
7173     mp_limb_t t[14];
7174     mpfq_fixmp_7_mul(t, x, invR);
7175     mpfq_fixmp_7_mod(z, t, p);
7176 }
7177 #endif /* !defined(HAVE_native_mpfq_fixmp_7_mgy_decode) */
7178 
7179 #if !defined(HAVE_native_mpfq_fixmp_7_lshift)
7180 /* a has 7 words. Shift it in place by cnt bits to the left.
7181  * The shift count cnt must not exceed the word size.
7182  * Note that no carry is returned for the bits shifted out. */
7183 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
7184 static inline
mpfq_fixmp_7_lshift(mp_limb_t * a,int cnt)7185 void mpfq_fixmp_7_lshift(mp_limb_t * a, int cnt)
7186 {
7187     if (!cnt) return;
7188     int i;
7189     int dnt = GMP_NUMB_BITS - cnt;
7190     for (i = 7-1; i>0; --i) {
7191         a[i] <<= cnt;
7192         a[i] |= (a[i-1] >> dnt);
7193     }
7194     a[0] <<= cnt;
7195 }
7196 #endif /* !defined(HAVE_native_mpfq_fixmp_7_lshift) */
7197 
7198 #if !defined(HAVE_native_mpfq_fixmp_8_add)
7199 /* x, y, and z have 8 words. Result in z. Return carry bit */
7200 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
7201 /* Triggered by: 8_invmod, 8_redc, 8_redc_ur */
7202 static inline
mpfq_fixmp_8_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7203 mp_limb_t mpfq_fixmp_8_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7204 {
7205     mp_limb_t r, s, t, cy, cy1, cy2;
7206     cy = 0;
7207     r = x[0];
7208     s = r + y[0];
7209     cy1 = s < r;
7210     t = s + cy;
7211     cy2 = t < s;
7212     cy = cy1 | cy2;
7213     z[0] = t;
7214     r = x[1];
7215     s = r + y[1];
7216     cy1 = s < r;
7217     t = s + cy;
7218     cy2 = t < s;
7219     cy = cy1 | cy2;
7220     z[1] = t;
7221     r = x[2];
7222     s = r + y[2];
7223     cy1 = s < r;
7224     t = s + cy;
7225     cy2 = t < s;
7226     cy = cy1 | cy2;
7227     z[2] = t;
7228     r = x[3];
7229     s = r + y[3];
7230     cy1 = s < r;
7231     t = s + cy;
7232     cy2 = t < s;
7233     cy = cy1 | cy2;
7234     z[3] = t;
7235     r = x[4];
7236     s = r + y[4];
7237     cy1 = s < r;
7238     t = s + cy;
7239     cy2 = t < s;
7240     cy = cy1 | cy2;
7241     z[4] = t;
7242     r = x[5];
7243     s = r + y[5];
7244     cy1 = s < r;
7245     t = s + cy;
7246     cy2 = t < s;
7247     cy = cy1 | cy2;
7248     z[5] = t;
7249     r = x[6];
7250     s = r + y[6];
7251     cy1 = s < r;
7252     t = s + cy;
7253     cy2 = t < s;
7254     cy = cy1 | cy2;
7255     z[6] = t;
7256     r = x[7];
7257     s = r + y[7];
7258     cy1 = s < r;
7259     t = s + cy;
7260     cy2 = t < s;
7261     cy = cy1 | cy2;
7262     z[7] = t;
7263     return cy;
7264 }
7265 #endif /* !defined(HAVE_native_mpfq_fixmp_8_add) */
7266 
7267 #if !defined(HAVE_native_mpfq_fixmp_8_sub)
7268 /* x, y, and z have 8 words. Result in z. Return borrow bit */
7269 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
7270 /* Triggered by: 8_invmod, 8_redc */
7271 static inline
mpfq_fixmp_8_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7272 mp_limb_t mpfq_fixmp_8_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7273 {
7274     mp_limb_t r, s, t, cy, cy1, cy2;
7275     cy = 0;
7276     r = x[0];
7277     s = r - y[0];
7278     cy1 = s > r;
7279     t = s - cy;
7280     cy2 = t > s;
7281     cy = cy1 | cy2;
7282     z[0] = t;
7283     r = x[1];
7284     s = r - y[1];
7285     cy1 = s > r;
7286     t = s - cy;
7287     cy2 = t > s;
7288     cy = cy1 | cy2;
7289     z[1] = t;
7290     r = x[2];
7291     s = r - y[2];
7292     cy1 = s > r;
7293     t = s - cy;
7294     cy2 = t > s;
7295     cy = cy1 | cy2;
7296     z[2] = t;
7297     r = x[3];
7298     s = r - y[3];
7299     cy1 = s > r;
7300     t = s - cy;
7301     cy2 = t > s;
7302     cy = cy1 | cy2;
7303     z[3] = t;
7304     r = x[4];
7305     s = r - y[4];
7306     cy1 = s > r;
7307     t = s - cy;
7308     cy2 = t > s;
7309     cy = cy1 | cy2;
7310     z[4] = t;
7311     r = x[5];
7312     s = r - y[5];
7313     cy1 = s > r;
7314     t = s - cy;
7315     cy2 = t > s;
7316     cy = cy1 | cy2;
7317     z[5] = t;
7318     r = x[6];
7319     s = r - y[6];
7320     cy1 = s > r;
7321     t = s - cy;
7322     cy2 = t > s;
7323     cy = cy1 | cy2;
7324     z[6] = t;
7325     r = x[7];
7326     s = r - y[7];
7327     cy1 = s > r;
7328     t = s - cy;
7329     cy2 = t > s;
7330     cy = cy1 | cy2;
7331     z[7] = t;
7332     return cy;
7333 }
7334 #endif /* !defined(HAVE_native_mpfq_fixmp_8_sub) */
7335 
7336 #if !defined(HAVE_native_mpfq_fixmp_8_add_nc)
7337 /* x, y, and z have 8 words. Result in z. Carry bit is lost. */
7338 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
7339 static inline
mpfq_fixmp_8_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7340 void mpfq_fixmp_8_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7341 {
7342     mp_limb_t r, s, t, cy, cy1, cy2;
7343     cy = 0;
7344     r = x[0];
7345     s = r + y[0];
7346     cy1 = s < r;
7347     t = s + cy;
7348     cy2 = t < s;
7349     cy = cy1 | cy2;
7350     z[0] = t;
7351     r = x[1];
7352     s = r + y[1];
7353     cy1 = s < r;
7354     t = s + cy;
7355     cy2 = t < s;
7356     cy = cy1 | cy2;
7357     z[1] = t;
7358     r = x[2];
7359     s = r + y[2];
7360     cy1 = s < r;
7361     t = s + cy;
7362     cy2 = t < s;
7363     cy = cy1 | cy2;
7364     z[2] = t;
7365     r = x[3];
7366     s = r + y[3];
7367     cy1 = s < r;
7368     t = s + cy;
7369     cy2 = t < s;
7370     cy = cy1 | cy2;
7371     z[3] = t;
7372     r = x[4];
7373     s = r + y[4];
7374     cy1 = s < r;
7375     t = s + cy;
7376     cy2 = t < s;
7377     cy = cy1 | cy2;
7378     z[4] = t;
7379     r = x[5];
7380     s = r + y[5];
7381     cy1 = s < r;
7382     t = s + cy;
7383     cy2 = t < s;
7384     cy = cy1 | cy2;
7385     z[5] = t;
7386     r = x[6];
7387     s = r + y[6];
7388     cy1 = s < r;
7389     t = s + cy;
7390     cy2 = t < s;
7391     cy = cy1 | cy2;
7392     z[6] = t;
7393     r = x[7];
7394     s = r + y[7];
7395     cy1 = s < r;
7396     t = s + cy;
7397     cy2 = t < s;
7398     cy = cy1 | cy2;
7399     z[7] = t;
7400 }
7401 #endif /* !defined(HAVE_native_mpfq_fixmp_8_add_nc) */
7402 
7403 #if !defined(HAVE_native_mpfq_fixmp_8_sub_nc)
7404 /* x, y, and z have 8 words. Result in z. Borrow bit is lost. */
7405 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
7406 static inline
mpfq_fixmp_8_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7407 void mpfq_fixmp_8_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7408 {
7409     mp_limb_t r, s, t, cy, cy1, cy2;
7410     cy = 0;
7411     r = x[0];
7412     s = r - y[0];
7413     cy1 = s > r;
7414     t = s - cy;
7415     cy2 = t > s;
7416     cy = cy1 | cy2;
7417     z[0] = t;
7418     r = x[1];
7419     s = r - y[1];
7420     cy1 = s > r;
7421     t = s - cy;
7422     cy2 = t > s;
7423     cy = cy1 | cy2;
7424     z[1] = t;
7425     r = x[2];
7426     s = r - y[2];
7427     cy1 = s > r;
7428     t = s - cy;
7429     cy2 = t > s;
7430     cy = cy1 | cy2;
7431     z[2] = t;
7432     r = x[3];
7433     s = r - y[3];
7434     cy1 = s > r;
7435     t = s - cy;
7436     cy2 = t > s;
7437     cy = cy1 | cy2;
7438     z[3] = t;
7439     r = x[4];
7440     s = r - y[4];
7441     cy1 = s > r;
7442     t = s - cy;
7443     cy2 = t > s;
7444     cy = cy1 | cy2;
7445     z[4] = t;
7446     r = x[5];
7447     s = r - y[5];
7448     cy1 = s > r;
7449     t = s - cy;
7450     cy2 = t > s;
7451     cy = cy1 | cy2;
7452     z[5] = t;
7453     r = x[6];
7454     s = r - y[6];
7455     cy1 = s > r;
7456     t = s - cy;
7457     cy2 = t > s;
7458     cy = cy1 | cy2;
7459     z[6] = t;
7460     r = x[7];
7461     s = r - y[7];
7462     cy1 = s > r;
7463     t = s - cy;
7464     cy2 = t > s;
7465     cy = cy1 | cy2;
7466     z[7] = t;
7467 }
7468 #endif /* !defined(HAVE_native_mpfq_fixmp_8_sub_nc) */
7469 
7470 #if !defined(HAVE_native_mpfq_fixmp_8_add_ui)
7471 /* x, y, and z have 8 words. Result in z. Return carry bit */
7472 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
7473 static inline
mpfq_fixmp_8_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)7474 mp_limb_t mpfq_fixmp_8_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
7475 {
7476     mp_limb_t r, s, t, cy, cy1, cy2;
7477     cy = 0;
7478     r = x[0];
7479     s = r + y;
7480     cy1 = s < r;
7481     t = s + cy;
7482     cy2 = t < s;
7483     cy = cy1 | cy2;
7484     z[0] = t;
7485     s = x[1];
7486     t = s + cy;
7487     cy = t < s;
7488     z[1] = t;
7489     s = x[2];
7490     t = s + cy;
7491     cy = t < s;
7492     z[2] = t;
7493     s = x[3];
7494     t = s + cy;
7495     cy = t < s;
7496     z[3] = t;
7497     s = x[4];
7498     t = s + cy;
7499     cy = t < s;
7500     z[4] = t;
7501     s = x[5];
7502     t = s + cy;
7503     cy = t < s;
7504     z[5] = t;
7505     s = x[6];
7506     t = s + cy;
7507     cy = t < s;
7508     z[6] = t;
7509     s = x[7];
7510     t = s + cy;
7511     cy = t < s;
7512     z[7] = t;
7513     return cy;
7514 }
7515 #endif /* !defined(HAVE_native_mpfq_fixmp_8_add_ui) */
7516 
7517 #if !defined(HAVE_native_mpfq_fixmp_8_sub_ui)
7518 /* x, y, and z have 8 words. Result in z. Return borrow bit */
7519 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
7520 static inline
mpfq_fixmp_8_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)7521 mp_limb_t mpfq_fixmp_8_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
7522 {
7523     mp_limb_t r, s, t, cy, cy1, cy2;
7524     cy = 0;
7525     r = x[0];
7526     s = r - y;
7527     cy1 = s > r;
7528     t = s - cy;
7529     cy2 = t > s;
7530     cy = cy1 | cy2;
7531     z[0] = t;
7532     s = x[1];
7533     t = s - cy;
7534     cy = t > s;
7535     z[1] = t;
7536     s = x[2];
7537     t = s - cy;
7538     cy = t > s;
7539     z[2] = t;
7540     s = x[3];
7541     t = s - cy;
7542     cy = t > s;
7543     z[3] = t;
7544     s = x[4];
7545     t = s - cy;
7546     cy = t > s;
7547     z[4] = t;
7548     s = x[5];
7549     t = s - cy;
7550     cy = t > s;
7551     z[5] = t;
7552     s = x[6];
7553     t = s - cy;
7554     cy = t > s;
7555     z[6] = t;
7556     s = x[7];
7557     t = s - cy;
7558     cy = t > s;
7559     z[7] = t;
7560     return cy;
7561 }
7562 #endif /* !defined(HAVE_native_mpfq_fixmp_8_sub_ui) */
7563 
7564 #if !defined(HAVE_native_mpfq_fixmp_8_add_ui_nc)
7565 /* x, y, and z have 8 words. Result in z. Carry bit is lost. */
7566 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
7567 static inline
mpfq_fixmp_8_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)7568 void mpfq_fixmp_8_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
7569 {
7570     mp_limb_t r, s, t, cy, cy1, cy2;
7571     cy = 0;
7572     r = x[0];
7573     s = r + y;
7574     cy1 = s < r;
7575     t = s + cy;
7576     cy2 = t < s;
7577     cy = cy1 | cy2;
7578     z[0] = t;
7579     s = x[1];
7580     t = s + cy;
7581     cy = t < s;
7582     z[1] = t;
7583     s = x[2];
7584     t = s + cy;
7585     cy = t < s;
7586     z[2] = t;
7587     s = x[3];
7588     t = s + cy;
7589     cy = t < s;
7590     z[3] = t;
7591     s = x[4];
7592     t = s + cy;
7593     cy = t < s;
7594     z[4] = t;
7595     s = x[5];
7596     t = s + cy;
7597     cy = t < s;
7598     z[5] = t;
7599     s = x[6];
7600     t = s + cy;
7601     cy = t < s;
7602     z[6] = t;
7603     s = x[7];
7604     t = s + cy;
7605     cy = t < s;
7606     z[7] = t;
7607 }
7608 #endif /* !defined(HAVE_native_mpfq_fixmp_8_add_ui_nc) */
7609 
7610 #if !defined(HAVE_native_mpfq_fixmp_8_sub_ui_nc)
7611 /* x, y, and z have 8 words. Result in z. Borrow bit is lost. */
7612 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
7613 static inline
mpfq_fixmp_8_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)7614 void mpfq_fixmp_8_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
7615 {
7616     mp_limb_t r, s, t, cy, cy1, cy2;
7617     cy = 0;
7618     r = x[0];
7619     s = r - y;
7620     cy1 = s > r;
7621     t = s - cy;
7622     cy2 = t > s;
7623     cy = cy1 | cy2;
7624     z[0] = t;
7625     s = x[1];
7626     t = s - cy;
7627     cy = t > s;
7628     z[1] = t;
7629     s = x[2];
7630     t = s - cy;
7631     cy = t > s;
7632     z[2] = t;
7633     s = x[3];
7634     t = s - cy;
7635     cy = t > s;
7636     z[3] = t;
7637     s = x[4];
7638     t = s - cy;
7639     cy = t > s;
7640     z[4] = t;
7641     s = x[5];
7642     t = s - cy;
7643     cy = t > s;
7644     z[5] = t;
7645     s = x[6];
7646     t = s - cy;
7647     cy = t > s;
7648     z[6] = t;
7649     s = x[7];
7650     t = s - cy;
7651     cy = t > s;
7652     z[7] = t;
7653 }
7654 #endif /* !defined(HAVE_native_mpfq_fixmp_8_sub_ui_nc) */
7655 
7656 #if !defined(HAVE_native_mpfq_fixmp_8_cmp)
7657 /* x and y have 8 words. Return sign of difference x-y. */
7658 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
7659 /* Triggered by: 8_invmod, 8_redc */
7660 static inline
mpfq_fixmp_8_cmp(const mp_limb_t * x,const mp_limb_t * y)7661 int mpfq_fixmp_8_cmp(const mp_limb_t * x, const mp_limb_t * y)
7662 {
7663     for (int i = 8-1; i >= 0; --i) {
7664         if (x[i] > y[i]) return 1;
7665         if (x[i] < y[i]) return -1;
7666     }
7667     return 0;
7668 }
7669 #endif /* !defined(HAVE_native_mpfq_fixmp_8_cmp) */
7670 
7671 #if !defined(HAVE_native_mpfq_fixmp_8_cmp_ui)
7672 /* x has 8 words. Return sign of difference x-y. */
7673 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
7674 /* Triggered by: 8_invmod */
7675 static inline
mpfq_fixmp_8_cmp_ui(const mp_limb_t * x,mp_limb_t y)7676 int mpfq_fixmp_8_cmp_ui(const mp_limb_t * x, mp_limb_t y)
7677 {
7678     for (int i = 8-1; i > 0; --i) {
7679         if (x[i]) return 1;
7680     }
7681     if (x[0]>y) return 1;
7682     if (x[0]<y) return -1;
7683     return 0;
7684 }
7685 #endif /* !defined(HAVE_native_mpfq_fixmp_8_cmp_ui) */
7686 
7687 #if !defined(HAVE_native_mpfq_fixmp_8_addmul1)
7688 /* x has 8 words, z has 10.
7689  * Put (z+x*c) in z. Return carry bit. */
7690 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
7691 /* Triggered by: 8_redc_ur */
7692 static inline
mpfq_fixmp_8_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)7693 mp_limb_t mpfq_fixmp_8_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
7694 {
7695     mp_limb_t hi, lo, carry, buf;
7696     carry = 0;
7697     mpfq_umul_ppmm(hi,lo,c,x[0]);
7698     lo += carry;
7699     carry = (lo<carry) + hi;
7700     buf = z[0];
7701     lo += buf;
7702     carry += (lo<buf);
7703     z[0] = lo;
7704     mpfq_umul_ppmm(hi,lo,c,x[1]);
7705     lo += carry;
7706     carry = (lo<carry) + hi;
7707     buf = z[1];
7708     lo += buf;
7709     carry += (lo<buf);
7710     z[1] = lo;
7711     mpfq_umul_ppmm(hi,lo,c,x[2]);
7712     lo += carry;
7713     carry = (lo<carry) + hi;
7714     buf = z[2];
7715     lo += buf;
7716     carry += (lo<buf);
7717     z[2] = lo;
7718     mpfq_umul_ppmm(hi,lo,c,x[3]);
7719     lo += carry;
7720     carry = (lo<carry) + hi;
7721     buf = z[3];
7722     lo += buf;
7723     carry += (lo<buf);
7724     z[3] = lo;
7725     mpfq_umul_ppmm(hi,lo,c,x[4]);
7726     lo += carry;
7727     carry = (lo<carry) + hi;
7728     buf = z[4];
7729     lo += buf;
7730     carry += (lo<buf);
7731     z[4] = lo;
7732     mpfq_umul_ppmm(hi,lo,c,x[5]);
7733     lo += carry;
7734     carry = (lo<carry) + hi;
7735     buf = z[5];
7736     lo += buf;
7737     carry += (lo<buf);
7738     z[5] = lo;
7739     mpfq_umul_ppmm(hi,lo,c,x[6]);
7740     lo += carry;
7741     carry = (lo<carry) + hi;
7742     buf = z[6];
7743     lo += buf;
7744     carry += (lo<buf);
7745     z[6] = lo;
7746     mpfq_umul_ppmm(hi,lo,c,x[7]);
7747     lo += carry;
7748     carry = (lo<carry) + hi;
7749     buf = z[7];
7750     lo += buf;
7751     carry += (lo<buf);
7752     z[7] = lo;
7753     z[8] += carry;
7754     return (z[8]<carry);
7755 }
7756 #endif /* !defined(HAVE_native_mpfq_fixmp_8_addmul1) */
7757 
7758 #if !defined(HAVE_native_mpfq_fixmp_8_addmul1_nc)
7759 /* x has 8 words, z has 10.
7760  * Put (z+x*c) in z. Carry bit is lost. */
7761 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
7762 /* Triggered by: 8_mul, 8_mgy_decode, 9_sqr, 9_shortmul, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 8_5_sqr, 8_5_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
7763 static inline
mpfq_fixmp_8_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)7764 void mpfq_fixmp_8_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
7765 {
7766     mp_limb_t hi, lo, carry, buf;
7767     carry = 0;
7768     mpfq_umul_ppmm(hi,lo,c,x[0]);
7769     lo += carry;
7770     carry = (lo<carry) + hi;
7771     buf = z[0];
7772     lo += buf;
7773     carry += (lo<buf);
7774     z[0] = lo;
7775     mpfq_umul_ppmm(hi,lo,c,x[1]);
7776     lo += carry;
7777     carry = (lo<carry) + hi;
7778     buf = z[1];
7779     lo += buf;
7780     carry += (lo<buf);
7781     z[1] = lo;
7782     mpfq_umul_ppmm(hi,lo,c,x[2]);
7783     lo += carry;
7784     carry = (lo<carry) + hi;
7785     buf = z[2];
7786     lo += buf;
7787     carry += (lo<buf);
7788     z[2] = lo;
7789     mpfq_umul_ppmm(hi,lo,c,x[3]);
7790     lo += carry;
7791     carry = (lo<carry) + hi;
7792     buf = z[3];
7793     lo += buf;
7794     carry += (lo<buf);
7795     z[3] = lo;
7796     mpfq_umul_ppmm(hi,lo,c,x[4]);
7797     lo += carry;
7798     carry = (lo<carry) + hi;
7799     buf = z[4];
7800     lo += buf;
7801     carry += (lo<buf);
7802     z[4] = lo;
7803     mpfq_umul_ppmm(hi,lo,c,x[5]);
7804     lo += carry;
7805     carry = (lo<carry) + hi;
7806     buf = z[5];
7807     lo += buf;
7808     carry += (lo<buf);
7809     z[5] = lo;
7810     mpfq_umul_ppmm(hi,lo,c,x[6]);
7811     lo += carry;
7812     carry = (lo<carry) + hi;
7813     buf = z[6];
7814     lo += buf;
7815     carry += (lo<buf);
7816     z[6] = lo;
7817     mpfq_umul_ppmm(hi,lo,c,x[7]);
7818     lo += carry;
7819     carry = (lo<carry) + hi;
7820     buf = z[7];
7821     lo += buf;
7822     carry += (lo<buf);
7823     z[7] = lo;
7824     z[8] += carry;
7825 }
7826 #endif /* !defined(HAVE_native_mpfq_fixmp_8_addmul1_nc) */
7827 
7828 #if !defined(HAVE_native_mpfq_fixmp_8_addmul1_shortz)
7829 /* x has 8 words, z has 9.
7830  * Put (z+x*c) in z. Return carry word. */
7831 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
7832 /* Triggered by: 8_redc */
7833 static inline
mpfq_fixmp_8_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)7834 mp_limb_t mpfq_fixmp_8_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
7835 {
7836     mp_limb_t hi, lo, carry, buf;
7837     carry = 0;
7838     mpfq_umul_ppmm(hi,lo,c,x[0]);
7839     lo += carry;
7840     carry = (lo<carry) + hi;
7841     buf = z[0];
7842     lo += buf;
7843     carry += (lo<buf);
7844     z[0] = lo;
7845     mpfq_umul_ppmm(hi,lo,c,x[1]);
7846     lo += carry;
7847     carry = (lo<carry) + hi;
7848     buf = z[1];
7849     lo += buf;
7850     carry += (lo<buf);
7851     z[1] = lo;
7852     mpfq_umul_ppmm(hi,lo,c,x[2]);
7853     lo += carry;
7854     carry = (lo<carry) + hi;
7855     buf = z[2];
7856     lo += buf;
7857     carry += (lo<buf);
7858     z[2] = lo;
7859     mpfq_umul_ppmm(hi,lo,c,x[3]);
7860     lo += carry;
7861     carry = (lo<carry) + hi;
7862     buf = z[3];
7863     lo += buf;
7864     carry += (lo<buf);
7865     z[3] = lo;
7866     mpfq_umul_ppmm(hi,lo,c,x[4]);
7867     lo += carry;
7868     carry = (lo<carry) + hi;
7869     buf = z[4];
7870     lo += buf;
7871     carry += (lo<buf);
7872     z[4] = lo;
7873     mpfq_umul_ppmm(hi,lo,c,x[5]);
7874     lo += carry;
7875     carry = (lo<carry) + hi;
7876     buf = z[5];
7877     lo += buf;
7878     carry += (lo<buf);
7879     z[5] = lo;
7880     mpfq_umul_ppmm(hi,lo,c,x[6]);
7881     lo += carry;
7882     carry = (lo<carry) + hi;
7883     buf = z[6];
7884     lo += buf;
7885     carry += (lo<buf);
7886     z[6] = lo;
7887     mpfq_umul_ppmm(hi,lo,c,x[7]);
7888     lo += carry;
7889     carry = (lo<carry) + hi;
7890     buf = z[7];
7891     lo += buf;
7892     carry += (lo<buf);
7893     z[7] = lo;
7894     return carry;
7895 }
7896 #endif /* !defined(HAVE_native_mpfq_fixmp_8_addmul1_shortz) */
7897 
7898 #if !defined(HAVE_native_mpfq_fixmp_8_mul)
7899 /* x and y have 8 words, z has 18. Put x*y in z. */
7900 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
7901 /* Triggered by: 8_mgy_decode */
7902 static inline
mpfq_fixmp_8_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7903 void mpfq_fixmp_8_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7904 {
7905     assert(z != x && z != y);
7906     for (int i = 0; i < 16; z[i++] = 0) ;
7907     mpfq_fixmp_8_addmul1_nc (z + 0, x, y[0]);
7908     mpfq_fixmp_8_addmul1_nc (z + 1, x, y[1]);
7909     mpfq_fixmp_8_addmul1_nc (z + 2, x, y[2]);
7910     mpfq_fixmp_8_addmul1_nc (z + 3, x, y[3]);
7911     mpfq_fixmp_8_addmul1_nc (z + 4, x, y[4]);
7912     mpfq_fixmp_8_addmul1_nc (z + 5, x, y[5]);
7913     mpfq_fixmp_8_addmul1_nc (z + 6, x, y[6]);
7914     mpfq_fixmp_8_addmul1_nc (z + 7, x, y[7]);
7915 }
7916 #endif /* !defined(HAVE_native_mpfq_fixmp_8_mul) */
7917 
7918 #if !defined(HAVE_native_mpfq_fixmp_8_sqr)
7919 /* x has 8 words, z has 18. Put x*y in z. */
7920 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
7921 static inline
mpfq_fixmp_8_sqr(mp_limb_t * z,const mp_limb_t * x)7922 void mpfq_fixmp_8_sqr(mp_limb_t * z, const mp_limb_t * x)
7923 {
7924     mp_limb_t buf[16] = {0,};
7925     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
7926     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
7927     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
7928     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
7929     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
7930     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
7931     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
7932     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
7933     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
7934     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
7935     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
7936     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
7937     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
7938     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
7939     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
7940     mpn_lshift(buf, buf, 16, 1);
7941     mpn_add_n(z, z, buf, 16);
7942 }
7943 #endif /* !defined(HAVE_native_mpfq_fixmp_8_sqr) */
7944 
7945 #if !defined(HAVE_native_mpfq_fixmp_8_mul1)
7946 /* x has 8 words, z has 10. Put x*y in z. */
7947 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
7948 static inline
mpfq_fixmp_8_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)7949 void mpfq_fixmp_8_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
7950 {
7951     mp_limb_t hi, lo, carry;
7952     carry = 0;
7953     mpfq_umul_ppmm(hi,lo,c,x[0]);
7954     lo += carry;
7955     carry = (lo<carry) + hi;
7956     z[0] = lo;
7957     mpfq_umul_ppmm(hi,lo,c,x[1]);
7958     lo += carry;
7959     carry = (lo<carry) + hi;
7960     z[1] = lo;
7961     mpfq_umul_ppmm(hi,lo,c,x[2]);
7962     lo += carry;
7963     carry = (lo<carry) + hi;
7964     z[2] = lo;
7965     mpfq_umul_ppmm(hi,lo,c,x[3]);
7966     lo += carry;
7967     carry = (lo<carry) + hi;
7968     z[3] = lo;
7969     mpfq_umul_ppmm(hi,lo,c,x[4]);
7970     lo += carry;
7971     carry = (lo<carry) + hi;
7972     z[4] = lo;
7973     mpfq_umul_ppmm(hi,lo,c,x[5]);
7974     lo += carry;
7975     carry = (lo<carry) + hi;
7976     z[5] = lo;
7977     mpfq_umul_ppmm(hi,lo,c,x[6]);
7978     lo += carry;
7979     carry = (lo<carry) + hi;
7980     z[6] = lo;
7981     mpfq_umul_ppmm(hi,lo,c,x[7]);
7982     lo += carry;
7983     carry = (lo<carry) + hi;
7984     z[7] = lo;
7985     z[8] = carry;
7986 }
7987 #endif /* !defined(HAVE_native_mpfq_fixmp_8_mul1) */
7988 
7989 #if !defined(HAVE_native_mpfq_fixmp_8_shortmul)
7990 /* x and y have 8 words, z has 9.
7991  * Put the low 9 words of x*y in z. */
7992 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
7993 static inline
mpfq_fixmp_8_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)7994 void mpfq_fixmp_8_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
7995 {
7996     mpfq_zero(z, 8);
7997     mpfq_fixmp_7_addmul1_nc (z+0, x, y[0]);
7998     z[8-1] += x[7]*y[0];
7999     mpfq_fixmp_6_addmul1_nc (z+1, x, y[1]);
8000     z[8-1] += x[6]*y[1];
8001     mpfq_fixmp_5_addmul1_nc (z+2, x, y[2]);
8002     z[8-1] += x[5]*y[2];
8003     mpfq_fixmp_4_addmul1_nc (z+3, x, y[3]);
8004     z[8-1] += x[4]*y[3];
8005     mpfq_fixmp_3_addmul1_nc (z+4, x, y[4]);
8006     z[8-1] += x[3]*y[4];
8007     mpfq_fixmp_2_addmul1_nc (z+5, x, y[5]);
8008     z[8-1] += x[2]*y[5];
8009     mpfq_fixmp_1_addmul1_nc (z+6, x, y[6]);
8010     z[8-1] += x[1]*y[6];
8011     z[8-1] += x[0]*y[8-1];
8012 }
8013 #endif /* !defined(HAVE_native_mpfq_fixmp_8_shortmul) */
8014 
8015 #if !defined(HAVE_native_mpfq_fixmp_8_mod)
8016 /* x has 18 words. z and p have 8 words, and the high word of p is non-zero.
8017  * Put x mod p in z. */
8018 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
8019 /* Triggered by: 8_mgy_decode */
8020 static inline
mpfq_fixmp_8_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)8021 void mpfq_fixmp_8_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
8022 {
8023     mp_limb_t q[8+1], r[8];
8024     assert (p[8-1] != 0);
8025     mpn_tdiv_qr(q, r, 0, x, 16, p, 8);
8026     mpfq_copy(z, r, 8);
8027 }
8028 #endif /* !defined(HAVE_native_mpfq_fixmp_8_mod) */
8029 
8030 #if !defined(HAVE_native_mpfq_fixmp_8_rshift)
8031 /* a has 8 words. Shift it in place by cnt bits to the right.
8032  * The shift count cnt must not exceed the word size.
8033  * Note that no carry is returned for the bits shifted out. */
8034 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
8035 /* Triggered by: 8_invmod */
8036 static inline
mpfq_fixmp_8_rshift(mp_limb_t * a,int cnt)8037 void mpfq_fixmp_8_rshift(mp_limb_t * a, int cnt)
8038 {
8039     if (!cnt) return;
8040     int i;
8041     int dnt = GMP_NUMB_BITS - cnt;
8042     for (i = 0; i < 8-1; ++i) {
8043         a[i] >>= cnt;
8044         a[i] |= (a[i+1] << dnt);
8045     }
8046     a[8-1] >>= cnt;
8047 }
8048 #endif /* !defined(HAVE_native_mpfq_fixmp_8_rshift) */
8049 
8050 #if !defined(HAVE_native_mpfq_fixmp_8_long_rshift)
8051 /* a has 8 words. Shift it in place by off words plus cnt bits to the left.
8052  * Note that no carry is returned for the bits shifted out. */
8053 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
8054 /* Triggered by: 8_invmod */
8055 static inline
mpfq_fixmp_8_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)8056 void mpfq_fixmp_8_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
8057 {
8058     if (cnt) {
8059         int dnt = GMP_NUMB_BITS - cnt;
8060         for (int i = 0; i < 8 - off - 1; ++i) {
8061             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
8062         }
8063         a[8-off-1] = a[8-1]>>cnt;
8064     } else {
8065         mpfq_copyi(a, a + off, 8 - off);
8066     }
8067     mpfq_zero(a + 8 - off, off);
8068 }
8069 #endif /* !defined(HAVE_native_mpfq_fixmp_8_long_rshift) */
8070 
8071 #if !defined(HAVE_native_mpfq_fixmp_8_long_lshift)
8072 /* a has 8 words. Shift it in place by off words plus cnt bits to the left.
8073  * Note that no carry is returned for the bits shifted out. */
8074 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
8075 /* Triggered by: 8_invmod */
8076 static inline
mpfq_fixmp_8_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)8077 void mpfq_fixmp_8_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
8078 {
8079     int i;
8080     if (cnt) {
8081         int dnt = GMP_NUMB_BITS - cnt;
8082         for (i = 8-1; i>off; --i) {
8083             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
8084         }
8085         a[off] = a[0]<<cnt;
8086     } else {
8087         mpfq_copyd(a + off, a, 8 - off);
8088     }
8089     mpfq_zero(a, off);
8090 }
8091 #endif /* !defined(HAVE_native_mpfq_fixmp_8_long_lshift) */
8092 
8093 #if !defined(HAVE_native_mpfq_fixmp_8_invmod)
8094 /* x, z, and p have 8 words. Put inverse of x mod p in z.
8095  * Return non-zero if an inverse could be found.
8096  * If no inverse could be found, return 0 and set z to zero.
8097  */
8098 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
8099 static inline
mpfq_fixmp_8_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)8100 int mpfq_fixmp_8_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
8101 {
8102       mp_limb_t u[8], v[8], a[8], b[8], fix[8];
8103       int i, t, lsh;
8104 
8105       mpfq_zero(u, 8);
8106       mpfq_zero(v, 8);
8107       mpfq_copy(a, x, 8);
8108       mpfq_copy(b, p, 8);
8109       u[0] = 1UL;
8110 
8111       if (mpfq_fixmp_8_cmp(a, v) == 0 || mpfq_fixmp_8_cmp(a, b) == 0) {
8112         mpfq_zero(res, 8);
8113         return 0;
8114       }
8115 
8116       mpfq_fixmp_8_add(fix, b, u);
8117       mpfq_fixmp_8_rshift(fix, 1);
8118 
8119       assert (mpfq_fixmp_8_cmp(a,b) < 0);
8120 
8121       t = 0;
8122 
8123       for(i = 0 ; !a[i] ; i++) ;
8124       assert (i < 8);
8125       lsh = mpfq_ctzl(a[i]);
8126       mpfq_fixmp_8_long_rshift(a, i, lsh);
8127       t += lsh + i*GMP_NUMB_BITS;
8128       mpfq_fixmp_8_long_lshift(v, i, lsh);
8129 
8130       do {
8131         do {
8132           mpfq_fixmp_8_sub(b, b, a);
8133           mpfq_fixmp_8_add(v, v, u);
8134           for(i = 0 ; !b[i] ; i++) ;
8135           assert (i < 8);
8136           lsh = mpfq_ctzl(b[i]);
8137           mpfq_fixmp_8_long_rshift(b, i, lsh);
8138           t += lsh + i*GMP_NUMB_BITS;
8139           mpfq_fixmp_8_long_lshift(u, i, lsh);
8140         } while (mpfq_fixmp_8_cmp(a,b) < 0);
8141         if (mpfq_fixmp_8_cmp(a, b) == 0)
8142           break;
8143         do {
8144           mpfq_fixmp_8_sub(a, a, b);
8145           mpfq_fixmp_8_add(u, u, v);
8146           for(i = 0 ; !a[i] ; i++) ;
8147           assert (i < 8);
8148           lsh = mpfq_ctzl(a[i]);
8149           mpfq_fixmp_8_long_rshift(a, i, lsh);
8150           t += lsh + i*GMP_NUMB_BITS;
8151           mpfq_fixmp_8_long_lshift(v, i, lsh);
8152         } while (mpfq_fixmp_8_cmp(b,a)<0);
8153       } while (mpfq_fixmp_8_cmp(a,b) != 0);
8154       {
8155         if (mpfq_fixmp_8_cmp_ui(a, 1) != 0) {
8156           mpfq_copy(res, a, 8);
8157           return 0;
8158         }
8159       }
8160       while (t>0) {
8161         mp_limb_t sig = u[0] & 1UL;
8162         mpfq_fixmp_8_rshift(u, 1);
8163         if (sig)
8164           mpfq_fixmp_8_add(u, u, fix);
8165         --t;
8166       }
8167       mpfq_copy(res, u, 8);
8168       return 1;
8169 }
8170 #endif /* !defined(HAVE_native_mpfq_fixmp_8_invmod) */
8171 
8172 #if !defined(HAVE_native_mpfq_fixmp_8_redc)
8173 /* x has 18 words, z and p have 8 words.
8174  * only one word is read from invp.
8175  * Assuming R=W^9 is the redc modulus, we expect that x verifies:
8176  *   x < R*p,
8177  * so that we have eventually z < p, z congruent to x/R mod p.
8178  * The contents of the area pointed by x are clobbered by this call.
8179  * Note also that x may alias z.
8180  */
8181 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
8182 static inline
mpfq_fixmp_8_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)8183 void mpfq_fixmp_8_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
8184 {
8185     mp_limb_t cy;
8186     for(int i = 0; i < 8; ++i) {
8187         mp_limb_t t = x[i]*mip[0];
8188         cy = mpfq_fixmp_8_addmul1_shortz(x+i, p, t);
8189         assert (x[i] == 0);
8190         x[i] = cy;
8191     }
8192     cy = mpfq_fixmp_8_add(x, x, x + 8);
8193     /* At this point, we have (x' denotes x + cy*W^n here)
8194     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
8195     * x'/R < p + p
8196     */
8197     if (cy || mpfq_fixmp_8_cmp(x, p) >= 0) {
8198         mpfq_fixmp_8_sub(z, x, p);
8199     } else {
8200         mpfq_copy(z, x, 8);
8201     }
8202 }
8203 #endif /* !defined(HAVE_native_mpfq_fixmp_8_redc) */
8204 
8205 #if !defined(HAVE_native_mpfq_fixmp_8_redc_ur)
8206 /* x has 19 words, z and p have 8 words.
8207  * only one word is read from invp.
8208  * Assuming R=W^9 is the redc modulus, we expect that x verifies:
8209  *  x < W*W^8*p = W^0.5*R*p or the hw case, W*R*p otherwise,
8210  * so that we have eventually z < p, z congruent to x/R mod p.
8211  * The contents of the area pointed by x are clobbered by this call.
8212  * Note also that x may alias z.
8213  */
8214 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
8215 static inline
mpfq_fixmp_8_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)8216 void mpfq_fixmp_8_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
8217 {
8218     mp_limb_t cy, q[2];
8219     for (int i = 0; i < 8; ++i) {
8220         mp_limb_t t = x[i]*mip[0];
8221         cy = mpfq_fixmp_8_addmul1(x+i, p, t);
8222         assert (x[i] == 0);
8223         x[i] = cy;
8224     }
8225     cy=mpfq_fixmp_8_add(x+8+1, x+8+1, x);
8226     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
8227     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
8228     * x'/R < (W+1)*p
8229     */
8230     if (cy) {
8231         /* x'/R-p < W*p, which fits in n+1 words */
8232         mpn_sub(x+8,x+8,8+1,p,8);
8233     }
8234     mpn_tdiv_qr(q, z, 0, x+8, 8+1, p, 8);
8235 }
8236 #endif /* !defined(HAVE_native_mpfq_fixmp_8_redc_ur) */
8237 
8238 #if !defined(HAVE_native_mpfq_fixmp_8_mgy_encode)
8239 /* x, z, and p have 8 words.
8240  * Assuming R=W^9 is the redc modulus, we compute z=R*x mod p. */
8241 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
8242 static inline
mpfq_fixmp_8_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)8243 void mpfq_fixmp_8_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
8244 {
8245     mp_limb_t t[16] = { 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7] };
8246     mpfq_fixmp_8_mod(z, t, p);
8247 }
8248 #endif /* !defined(HAVE_native_mpfq_fixmp_8_mgy_encode) */
8249 
8250 #if !defined(HAVE_native_mpfq_fixmp_8_mgy_decode)
8251 /* x, z, invR, and p have 8 words.
8252  * Assuming R=W^9 is the redc modulus, we compute z=x/R mod p. */
8253 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
8254 static inline
mpfq_fixmp_8_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)8255 void mpfq_fixmp_8_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
8256 {
8257     mp_limb_t t[16];
8258     mpfq_fixmp_8_mul(t, x, invR);
8259     mpfq_fixmp_8_mod(z, t, p);
8260 }
8261 #endif /* !defined(HAVE_native_mpfq_fixmp_8_mgy_decode) */
8262 
8263 #if !defined(HAVE_native_mpfq_fixmp_8_lshift)
8264 /* a has 8 words. Shift it in place by cnt bits to the left.
8265  * The shift count cnt must not exceed the word size.
8266  * Note that no carry is returned for the bits shifted out. */
8267 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
8268 static inline
mpfq_fixmp_8_lshift(mp_limb_t * a,int cnt)8269 void mpfq_fixmp_8_lshift(mp_limb_t * a, int cnt)
8270 {
8271     if (!cnt) return;
8272     int i;
8273     int dnt = GMP_NUMB_BITS - cnt;
8274     for (i = 8-1; i>0; --i) {
8275         a[i] <<= cnt;
8276         a[i] |= (a[i-1] >> dnt);
8277     }
8278     a[0] <<= cnt;
8279 }
8280 #endif /* !defined(HAVE_native_mpfq_fixmp_8_lshift) */
8281 
8282 #if !defined(HAVE_native_mpfq_fixmp_9_add)
8283 /* x, y, and z have 9 words. Result in z. Return carry bit */
8284 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
8285 /* Triggered by: 9_invmod, 9_redc, 9_redc_ur */
8286 static inline
mpfq_fixmp_9_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)8287 mp_limb_t mpfq_fixmp_9_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
8288 {
8289     mp_limb_t r, s, t, cy, cy1, cy2;
8290     cy = 0;
8291     r = x[0];
8292     s = r + y[0];
8293     cy1 = s < r;
8294     t = s + cy;
8295     cy2 = t < s;
8296     cy = cy1 | cy2;
8297     z[0] = t;
8298     r = x[1];
8299     s = r + y[1];
8300     cy1 = s < r;
8301     t = s + cy;
8302     cy2 = t < s;
8303     cy = cy1 | cy2;
8304     z[1] = t;
8305     r = x[2];
8306     s = r + y[2];
8307     cy1 = s < r;
8308     t = s + cy;
8309     cy2 = t < s;
8310     cy = cy1 | cy2;
8311     z[2] = t;
8312     r = x[3];
8313     s = r + y[3];
8314     cy1 = s < r;
8315     t = s + cy;
8316     cy2 = t < s;
8317     cy = cy1 | cy2;
8318     z[3] = t;
8319     r = x[4];
8320     s = r + y[4];
8321     cy1 = s < r;
8322     t = s + cy;
8323     cy2 = t < s;
8324     cy = cy1 | cy2;
8325     z[4] = t;
8326     r = x[5];
8327     s = r + y[5];
8328     cy1 = s < r;
8329     t = s + cy;
8330     cy2 = t < s;
8331     cy = cy1 | cy2;
8332     z[5] = t;
8333     r = x[6];
8334     s = r + y[6];
8335     cy1 = s < r;
8336     t = s + cy;
8337     cy2 = t < s;
8338     cy = cy1 | cy2;
8339     z[6] = t;
8340     r = x[7];
8341     s = r + y[7];
8342     cy1 = s < r;
8343     t = s + cy;
8344     cy2 = t < s;
8345     cy = cy1 | cy2;
8346     z[7] = t;
8347     r = x[8];
8348     s = r + y[8];
8349     cy1 = s < r;
8350     t = s + cy;
8351     cy2 = t < s;
8352     cy = cy1 | cy2;
8353     z[8] = t;
8354     return cy;
8355 }
8356 #endif /* !defined(HAVE_native_mpfq_fixmp_9_add) */
8357 
8358 #if !defined(HAVE_native_mpfq_fixmp_9_sub)
8359 /* x, y, and z have 9 words. Result in z. Return borrow bit */
8360 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
8361 /* Triggered by: 9_invmod, 9_redc */
8362 static inline
mpfq_fixmp_9_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)8363 mp_limb_t mpfq_fixmp_9_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
8364 {
8365     mp_limb_t r, s, t, cy, cy1, cy2;
8366     cy = 0;
8367     r = x[0];
8368     s = r - y[0];
8369     cy1 = s > r;
8370     t = s - cy;
8371     cy2 = t > s;
8372     cy = cy1 | cy2;
8373     z[0] = t;
8374     r = x[1];
8375     s = r - y[1];
8376     cy1 = s > r;
8377     t = s - cy;
8378     cy2 = t > s;
8379     cy = cy1 | cy2;
8380     z[1] = t;
8381     r = x[2];
8382     s = r - y[2];
8383     cy1 = s > r;
8384     t = s - cy;
8385     cy2 = t > s;
8386     cy = cy1 | cy2;
8387     z[2] = t;
8388     r = x[3];
8389     s = r - y[3];
8390     cy1 = s > r;
8391     t = s - cy;
8392     cy2 = t > s;
8393     cy = cy1 | cy2;
8394     z[3] = t;
8395     r = x[4];
8396     s = r - y[4];
8397     cy1 = s > r;
8398     t = s - cy;
8399     cy2 = t > s;
8400     cy = cy1 | cy2;
8401     z[4] = t;
8402     r = x[5];
8403     s = r - y[5];
8404     cy1 = s > r;
8405     t = s - cy;
8406     cy2 = t > s;
8407     cy = cy1 | cy2;
8408     z[5] = t;
8409     r = x[6];
8410     s = r - y[6];
8411     cy1 = s > r;
8412     t = s - cy;
8413     cy2 = t > s;
8414     cy = cy1 | cy2;
8415     z[6] = t;
8416     r = x[7];
8417     s = r - y[7];
8418     cy1 = s > r;
8419     t = s - cy;
8420     cy2 = t > s;
8421     cy = cy1 | cy2;
8422     z[7] = t;
8423     r = x[8];
8424     s = r - y[8];
8425     cy1 = s > r;
8426     t = s - cy;
8427     cy2 = t > s;
8428     cy = cy1 | cy2;
8429     z[8] = t;
8430     return cy;
8431 }
8432 #endif /* !defined(HAVE_native_mpfq_fixmp_9_sub) */
8433 
8434 #if !defined(HAVE_native_mpfq_fixmp_9_add_nc)
8435 /* x, y, and z have 9 words. Result in z. Carry bit is lost. */
8436 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
8437 static inline
mpfq_fixmp_9_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)8438 void mpfq_fixmp_9_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
8439 {
8440     mp_limb_t r, s, t, cy, cy1, cy2;
8441     cy = 0;
8442     r = x[0];
8443     s = r + y[0];
8444     cy1 = s < r;
8445     t = s + cy;
8446     cy2 = t < s;
8447     cy = cy1 | cy2;
8448     z[0] = t;
8449     r = x[1];
8450     s = r + y[1];
8451     cy1 = s < r;
8452     t = s + cy;
8453     cy2 = t < s;
8454     cy = cy1 | cy2;
8455     z[1] = t;
8456     r = x[2];
8457     s = r + y[2];
8458     cy1 = s < r;
8459     t = s + cy;
8460     cy2 = t < s;
8461     cy = cy1 | cy2;
8462     z[2] = t;
8463     r = x[3];
8464     s = r + y[3];
8465     cy1 = s < r;
8466     t = s + cy;
8467     cy2 = t < s;
8468     cy = cy1 | cy2;
8469     z[3] = t;
8470     r = x[4];
8471     s = r + y[4];
8472     cy1 = s < r;
8473     t = s + cy;
8474     cy2 = t < s;
8475     cy = cy1 | cy2;
8476     z[4] = t;
8477     r = x[5];
8478     s = r + y[5];
8479     cy1 = s < r;
8480     t = s + cy;
8481     cy2 = t < s;
8482     cy = cy1 | cy2;
8483     z[5] = t;
8484     r = x[6];
8485     s = r + y[6];
8486     cy1 = s < r;
8487     t = s + cy;
8488     cy2 = t < s;
8489     cy = cy1 | cy2;
8490     z[6] = t;
8491     r = x[7];
8492     s = r + y[7];
8493     cy1 = s < r;
8494     t = s + cy;
8495     cy2 = t < s;
8496     cy = cy1 | cy2;
8497     z[7] = t;
8498     r = x[8];
8499     s = r + y[8];
8500     cy1 = s < r;
8501     t = s + cy;
8502     cy2 = t < s;
8503     cy = cy1 | cy2;
8504     z[8] = t;
8505 }
8506 #endif /* !defined(HAVE_native_mpfq_fixmp_9_add_nc) */
8507 
8508 #if !defined(HAVE_native_mpfq_fixmp_9_sub_nc)
8509 /* x, y, and z have 9 words. Result in z. Borrow bit is lost. */
8510 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
8511 static inline
mpfq_fixmp_9_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)8512 void mpfq_fixmp_9_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
8513 {
8514     mp_limb_t r, s, t, cy, cy1, cy2;
8515     cy = 0;
8516     r = x[0];
8517     s = r - y[0];
8518     cy1 = s > r;
8519     t = s - cy;
8520     cy2 = t > s;
8521     cy = cy1 | cy2;
8522     z[0] = t;
8523     r = x[1];
8524     s = r - y[1];
8525     cy1 = s > r;
8526     t = s - cy;
8527     cy2 = t > s;
8528     cy = cy1 | cy2;
8529     z[1] = t;
8530     r = x[2];
8531     s = r - y[2];
8532     cy1 = s > r;
8533     t = s - cy;
8534     cy2 = t > s;
8535     cy = cy1 | cy2;
8536     z[2] = t;
8537     r = x[3];
8538     s = r - y[3];
8539     cy1 = s > r;
8540     t = s - cy;
8541     cy2 = t > s;
8542     cy = cy1 | cy2;
8543     z[3] = t;
8544     r = x[4];
8545     s = r - y[4];
8546     cy1 = s > r;
8547     t = s - cy;
8548     cy2 = t > s;
8549     cy = cy1 | cy2;
8550     z[4] = t;
8551     r = x[5];
8552     s = r - y[5];
8553     cy1 = s > r;
8554     t = s - cy;
8555     cy2 = t > s;
8556     cy = cy1 | cy2;
8557     z[5] = t;
8558     r = x[6];
8559     s = r - y[6];
8560     cy1 = s > r;
8561     t = s - cy;
8562     cy2 = t > s;
8563     cy = cy1 | cy2;
8564     z[6] = t;
8565     r = x[7];
8566     s = r - y[7];
8567     cy1 = s > r;
8568     t = s - cy;
8569     cy2 = t > s;
8570     cy = cy1 | cy2;
8571     z[7] = t;
8572     r = x[8];
8573     s = r - y[8];
8574     cy1 = s > r;
8575     t = s - cy;
8576     cy2 = t > s;
8577     cy = cy1 | cy2;
8578     z[8] = t;
8579 }
8580 #endif /* !defined(HAVE_native_mpfq_fixmp_9_sub_nc) */
8581 
8582 #if !defined(HAVE_native_mpfq_fixmp_9_add_ui)
8583 /* x, y, and z have 9 words. Result in z. Return carry bit */
8584 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
8585 static inline
mpfq_fixmp_9_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)8586 mp_limb_t mpfq_fixmp_9_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
8587 {
8588     mp_limb_t r, s, t, cy, cy1, cy2;
8589     cy = 0;
8590     r = x[0];
8591     s = r + y;
8592     cy1 = s < r;
8593     t = s + cy;
8594     cy2 = t < s;
8595     cy = cy1 | cy2;
8596     z[0] = t;
8597     s = x[1];
8598     t = s + cy;
8599     cy = t < s;
8600     z[1] = t;
8601     s = x[2];
8602     t = s + cy;
8603     cy = t < s;
8604     z[2] = t;
8605     s = x[3];
8606     t = s + cy;
8607     cy = t < s;
8608     z[3] = t;
8609     s = x[4];
8610     t = s + cy;
8611     cy = t < s;
8612     z[4] = t;
8613     s = x[5];
8614     t = s + cy;
8615     cy = t < s;
8616     z[5] = t;
8617     s = x[6];
8618     t = s + cy;
8619     cy = t < s;
8620     z[6] = t;
8621     s = x[7];
8622     t = s + cy;
8623     cy = t < s;
8624     z[7] = t;
8625     s = x[8];
8626     t = s + cy;
8627     cy = t < s;
8628     z[8] = t;
8629     return cy;
8630 }
8631 #endif /* !defined(HAVE_native_mpfq_fixmp_9_add_ui) */
8632 
8633 #if !defined(HAVE_native_mpfq_fixmp_9_sub_ui)
8634 /* x, y, and z have 9 words. Result in z. Return borrow bit */
8635 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
8636 static inline
mpfq_fixmp_9_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)8637 mp_limb_t mpfq_fixmp_9_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
8638 {
8639     mp_limb_t r, s, t, cy, cy1, cy2;
8640     cy = 0;
8641     r = x[0];
8642     s = r - y;
8643     cy1 = s > r;
8644     t = s - cy;
8645     cy2 = t > s;
8646     cy = cy1 | cy2;
8647     z[0] = t;
8648     s = x[1];
8649     t = s - cy;
8650     cy = t > s;
8651     z[1] = t;
8652     s = x[2];
8653     t = s - cy;
8654     cy = t > s;
8655     z[2] = t;
8656     s = x[3];
8657     t = s - cy;
8658     cy = t > s;
8659     z[3] = t;
8660     s = x[4];
8661     t = s - cy;
8662     cy = t > s;
8663     z[4] = t;
8664     s = x[5];
8665     t = s - cy;
8666     cy = t > s;
8667     z[5] = t;
8668     s = x[6];
8669     t = s - cy;
8670     cy = t > s;
8671     z[6] = t;
8672     s = x[7];
8673     t = s - cy;
8674     cy = t > s;
8675     z[7] = t;
8676     s = x[8];
8677     t = s - cy;
8678     cy = t > s;
8679     z[8] = t;
8680     return cy;
8681 }
8682 #endif /* !defined(HAVE_native_mpfq_fixmp_9_sub_ui) */
8683 
8684 #if !defined(HAVE_native_mpfq_fixmp_9_add_ui_nc)
8685 /* x, y, and z have 9 words. Result in z. Carry bit is lost. */
8686 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
8687 static inline
mpfq_fixmp_9_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)8688 void mpfq_fixmp_9_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
8689 {
8690     mp_limb_t r, s, t, cy, cy1, cy2;
8691     cy = 0;
8692     r = x[0];
8693     s = r + y;
8694     cy1 = s < r;
8695     t = s + cy;
8696     cy2 = t < s;
8697     cy = cy1 | cy2;
8698     z[0] = t;
8699     s = x[1];
8700     t = s + cy;
8701     cy = t < s;
8702     z[1] = t;
8703     s = x[2];
8704     t = s + cy;
8705     cy = t < s;
8706     z[2] = t;
8707     s = x[3];
8708     t = s + cy;
8709     cy = t < s;
8710     z[3] = t;
8711     s = x[4];
8712     t = s + cy;
8713     cy = t < s;
8714     z[4] = t;
8715     s = x[5];
8716     t = s + cy;
8717     cy = t < s;
8718     z[5] = t;
8719     s = x[6];
8720     t = s + cy;
8721     cy = t < s;
8722     z[6] = t;
8723     s = x[7];
8724     t = s + cy;
8725     cy = t < s;
8726     z[7] = t;
8727     s = x[8];
8728     t = s + cy;
8729     cy = t < s;
8730     z[8] = t;
8731 }
8732 #endif /* !defined(HAVE_native_mpfq_fixmp_9_add_ui_nc) */
8733 
8734 #if !defined(HAVE_native_mpfq_fixmp_9_sub_ui_nc)
8735 /* x, y, and z have 9 words. Result in z. Borrow bit is lost. */
8736 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
8737 static inline
mpfq_fixmp_9_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)8738 void mpfq_fixmp_9_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
8739 {
8740     mp_limb_t r, s, t, cy, cy1, cy2;
8741     cy = 0;
8742     r = x[0];
8743     s = r - y;
8744     cy1 = s > r;
8745     t = s - cy;
8746     cy2 = t > s;
8747     cy = cy1 | cy2;
8748     z[0] = t;
8749     s = x[1];
8750     t = s - cy;
8751     cy = t > s;
8752     z[1] = t;
8753     s = x[2];
8754     t = s - cy;
8755     cy = t > s;
8756     z[2] = t;
8757     s = x[3];
8758     t = s - cy;
8759     cy = t > s;
8760     z[3] = t;
8761     s = x[4];
8762     t = s - cy;
8763     cy = t > s;
8764     z[4] = t;
8765     s = x[5];
8766     t = s - cy;
8767     cy = t > s;
8768     z[5] = t;
8769     s = x[6];
8770     t = s - cy;
8771     cy = t > s;
8772     z[6] = t;
8773     s = x[7];
8774     t = s - cy;
8775     cy = t > s;
8776     z[7] = t;
8777     s = x[8];
8778     t = s - cy;
8779     cy = t > s;
8780     z[8] = t;
8781 }
8782 #endif /* !defined(HAVE_native_mpfq_fixmp_9_sub_ui_nc) */
8783 
8784 #if !defined(HAVE_native_mpfq_fixmp_9_cmp)
8785 /* x and y have 9 words. Return sign of difference x-y. */
8786 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
8787 /* Triggered by: 9_invmod, 9_redc */
8788 static inline
mpfq_fixmp_9_cmp(const mp_limb_t * x,const mp_limb_t * y)8789 int mpfq_fixmp_9_cmp(const mp_limb_t * x, const mp_limb_t * y)
8790 {
8791     for (int i = 9-1; i >= 0; --i) {
8792         if (x[i] > y[i]) return 1;
8793         if (x[i] < y[i]) return -1;
8794     }
8795     return 0;
8796 }
8797 #endif /* !defined(HAVE_native_mpfq_fixmp_9_cmp) */
8798 
8799 #if !defined(HAVE_native_mpfq_fixmp_9_cmp_ui)
8800 /* x has 9 words. Return sign of difference x-y. */
8801 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
8802 /* Triggered by: 9_invmod */
8803 static inline
mpfq_fixmp_9_cmp_ui(const mp_limb_t * x,mp_limb_t y)8804 int mpfq_fixmp_9_cmp_ui(const mp_limb_t * x, mp_limb_t y)
8805 {
8806     for (int i = 9-1; i > 0; --i) {
8807         if (x[i]) return 1;
8808     }
8809     if (x[0]>y) return 1;
8810     if (x[0]<y) return -1;
8811     return 0;
8812 }
8813 #endif /* !defined(HAVE_native_mpfq_fixmp_9_cmp_ui) */
8814 
8815 #if !defined(HAVE_native_mpfq_fixmp_9_addmul1)
8816 /* x has 9 words, z has 11.
8817  * Put (z+x*c) in z. Return carry bit. */
8818 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
8819 /* Triggered by: 9_redc_ur */
8820 static inline
mpfq_fixmp_9_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)8821 mp_limb_t mpfq_fixmp_9_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
8822 {
8823     mp_limb_t hi, lo, carry, buf;
8824     carry = 0;
8825     mpfq_umul_ppmm(hi,lo,c,x[0]);
8826     lo += carry;
8827     carry = (lo<carry) + hi;
8828     buf = z[0];
8829     lo += buf;
8830     carry += (lo<buf);
8831     z[0] = lo;
8832     mpfq_umul_ppmm(hi,lo,c,x[1]);
8833     lo += carry;
8834     carry = (lo<carry) + hi;
8835     buf = z[1];
8836     lo += buf;
8837     carry += (lo<buf);
8838     z[1] = lo;
8839     mpfq_umul_ppmm(hi,lo,c,x[2]);
8840     lo += carry;
8841     carry = (lo<carry) + hi;
8842     buf = z[2];
8843     lo += buf;
8844     carry += (lo<buf);
8845     z[2] = lo;
8846     mpfq_umul_ppmm(hi,lo,c,x[3]);
8847     lo += carry;
8848     carry = (lo<carry) + hi;
8849     buf = z[3];
8850     lo += buf;
8851     carry += (lo<buf);
8852     z[3] = lo;
8853     mpfq_umul_ppmm(hi,lo,c,x[4]);
8854     lo += carry;
8855     carry = (lo<carry) + hi;
8856     buf = z[4];
8857     lo += buf;
8858     carry += (lo<buf);
8859     z[4] = lo;
8860     mpfq_umul_ppmm(hi,lo,c,x[5]);
8861     lo += carry;
8862     carry = (lo<carry) + hi;
8863     buf = z[5];
8864     lo += buf;
8865     carry += (lo<buf);
8866     z[5] = lo;
8867     mpfq_umul_ppmm(hi,lo,c,x[6]);
8868     lo += carry;
8869     carry = (lo<carry) + hi;
8870     buf = z[6];
8871     lo += buf;
8872     carry += (lo<buf);
8873     z[6] = lo;
8874     mpfq_umul_ppmm(hi,lo,c,x[7]);
8875     lo += carry;
8876     carry = (lo<carry) + hi;
8877     buf = z[7];
8878     lo += buf;
8879     carry += (lo<buf);
8880     z[7] = lo;
8881     mpfq_umul_ppmm(hi,lo,c,x[8]);
8882     lo += carry;
8883     carry = (lo<carry) + hi;
8884     buf = z[8];
8885     lo += buf;
8886     carry += (lo<buf);
8887     z[8] = lo;
8888     z[9] += carry;
8889     return (z[9]<carry);
8890 }
8891 #endif /* !defined(HAVE_native_mpfq_fixmp_9_addmul1) */
8892 
8893 #if !defined(HAVE_native_mpfq_fixmp_9_addmul1_nc)
8894 /* x has 9 words, z has 11.
8895  * Put (z+x*c) in z. Carry bit is lost. */
8896 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
8897 /* Triggered by: 9_mul, 9_mgy_decode, 10_sqr, 10_shortmul, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 9_5_sqr, 9_5_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
8898 static inline
mpfq_fixmp_9_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)8899 void mpfq_fixmp_9_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
8900 {
8901     mp_limb_t hi, lo, carry, buf;
8902     carry = 0;
8903     mpfq_umul_ppmm(hi,lo,c,x[0]);
8904     lo += carry;
8905     carry = (lo<carry) + hi;
8906     buf = z[0];
8907     lo += buf;
8908     carry += (lo<buf);
8909     z[0] = lo;
8910     mpfq_umul_ppmm(hi,lo,c,x[1]);
8911     lo += carry;
8912     carry = (lo<carry) + hi;
8913     buf = z[1];
8914     lo += buf;
8915     carry += (lo<buf);
8916     z[1] = lo;
8917     mpfq_umul_ppmm(hi,lo,c,x[2]);
8918     lo += carry;
8919     carry = (lo<carry) + hi;
8920     buf = z[2];
8921     lo += buf;
8922     carry += (lo<buf);
8923     z[2] = lo;
8924     mpfq_umul_ppmm(hi,lo,c,x[3]);
8925     lo += carry;
8926     carry = (lo<carry) + hi;
8927     buf = z[3];
8928     lo += buf;
8929     carry += (lo<buf);
8930     z[3] = lo;
8931     mpfq_umul_ppmm(hi,lo,c,x[4]);
8932     lo += carry;
8933     carry = (lo<carry) + hi;
8934     buf = z[4];
8935     lo += buf;
8936     carry += (lo<buf);
8937     z[4] = lo;
8938     mpfq_umul_ppmm(hi,lo,c,x[5]);
8939     lo += carry;
8940     carry = (lo<carry) + hi;
8941     buf = z[5];
8942     lo += buf;
8943     carry += (lo<buf);
8944     z[5] = lo;
8945     mpfq_umul_ppmm(hi,lo,c,x[6]);
8946     lo += carry;
8947     carry = (lo<carry) + hi;
8948     buf = z[6];
8949     lo += buf;
8950     carry += (lo<buf);
8951     z[6] = lo;
8952     mpfq_umul_ppmm(hi,lo,c,x[7]);
8953     lo += carry;
8954     carry = (lo<carry) + hi;
8955     buf = z[7];
8956     lo += buf;
8957     carry += (lo<buf);
8958     z[7] = lo;
8959     mpfq_umul_ppmm(hi,lo,c,x[8]);
8960     lo += carry;
8961     carry = (lo<carry) + hi;
8962     buf = z[8];
8963     lo += buf;
8964     carry += (lo<buf);
8965     z[8] = lo;
8966     z[9] += carry;
8967 }
8968 #endif /* !defined(HAVE_native_mpfq_fixmp_9_addmul1_nc) */
8969 
8970 #if !defined(HAVE_native_mpfq_fixmp_9_addmul1_shortz)
8971 /* x has 9 words, z has 10.
8972  * Put (z+x*c) in z. Return carry word. */
8973 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
8974 /* Triggered by: 9_redc */
8975 static inline
mpfq_fixmp_9_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)8976 mp_limb_t mpfq_fixmp_9_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
8977 {
8978     mp_limb_t hi, lo, carry, buf;
8979     carry = 0;
8980     mpfq_umul_ppmm(hi,lo,c,x[0]);
8981     lo += carry;
8982     carry = (lo<carry) + hi;
8983     buf = z[0];
8984     lo += buf;
8985     carry += (lo<buf);
8986     z[0] = lo;
8987     mpfq_umul_ppmm(hi,lo,c,x[1]);
8988     lo += carry;
8989     carry = (lo<carry) + hi;
8990     buf = z[1];
8991     lo += buf;
8992     carry += (lo<buf);
8993     z[1] = lo;
8994     mpfq_umul_ppmm(hi,lo,c,x[2]);
8995     lo += carry;
8996     carry = (lo<carry) + hi;
8997     buf = z[2];
8998     lo += buf;
8999     carry += (lo<buf);
9000     z[2] = lo;
9001     mpfq_umul_ppmm(hi,lo,c,x[3]);
9002     lo += carry;
9003     carry = (lo<carry) + hi;
9004     buf = z[3];
9005     lo += buf;
9006     carry += (lo<buf);
9007     z[3] = lo;
9008     mpfq_umul_ppmm(hi,lo,c,x[4]);
9009     lo += carry;
9010     carry = (lo<carry) + hi;
9011     buf = z[4];
9012     lo += buf;
9013     carry += (lo<buf);
9014     z[4] = lo;
9015     mpfq_umul_ppmm(hi,lo,c,x[5]);
9016     lo += carry;
9017     carry = (lo<carry) + hi;
9018     buf = z[5];
9019     lo += buf;
9020     carry += (lo<buf);
9021     z[5] = lo;
9022     mpfq_umul_ppmm(hi,lo,c,x[6]);
9023     lo += carry;
9024     carry = (lo<carry) + hi;
9025     buf = z[6];
9026     lo += buf;
9027     carry += (lo<buf);
9028     z[6] = lo;
9029     mpfq_umul_ppmm(hi,lo,c,x[7]);
9030     lo += carry;
9031     carry = (lo<carry) + hi;
9032     buf = z[7];
9033     lo += buf;
9034     carry += (lo<buf);
9035     z[7] = lo;
9036     mpfq_umul_ppmm(hi,lo,c,x[8]);
9037     lo += carry;
9038     carry = (lo<carry) + hi;
9039     buf = z[8];
9040     lo += buf;
9041     carry += (lo<buf);
9042     z[8] = lo;
9043     return carry;
9044 }
9045 #endif /* !defined(HAVE_native_mpfq_fixmp_9_addmul1_shortz) */
9046 
9047 #if !defined(HAVE_native_mpfq_fixmp_9_mul)
9048 /* x and y have 9 words, z has 20. Put x*y in z. */
9049 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
9050 /* Triggered by: 9_mgy_decode */
9051 static inline
mpfq_fixmp_9_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9052 void mpfq_fixmp_9_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9053 {
9054     assert(z != x && z != y);
9055     for (int i = 0; i < 18; z[i++] = 0) ;
9056     mpfq_fixmp_9_addmul1_nc (z + 0, x, y[0]);
9057     mpfq_fixmp_9_addmul1_nc (z + 1, x, y[1]);
9058     mpfq_fixmp_9_addmul1_nc (z + 2, x, y[2]);
9059     mpfq_fixmp_9_addmul1_nc (z + 3, x, y[3]);
9060     mpfq_fixmp_9_addmul1_nc (z + 4, x, y[4]);
9061     mpfq_fixmp_9_addmul1_nc (z + 5, x, y[5]);
9062     mpfq_fixmp_9_addmul1_nc (z + 6, x, y[6]);
9063     mpfq_fixmp_9_addmul1_nc (z + 7, x, y[7]);
9064     mpfq_fixmp_9_addmul1_nc (z + 8, x, y[8]);
9065 }
9066 #endif /* !defined(HAVE_native_mpfq_fixmp_9_mul) */
9067 
9068 #if !defined(HAVE_native_mpfq_fixmp_9_sqr)
9069 /* x has 9 words, z has 20. Put x*y in z. */
9070 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
9071 static inline
mpfq_fixmp_9_sqr(mp_limb_t * z,const mp_limb_t * x)9072 void mpfq_fixmp_9_sqr(mp_limb_t * z, const mp_limb_t * x)
9073 {
9074     mp_limb_t buf[18] = {0,};
9075     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
9076     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
9077     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
9078     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
9079     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
9080     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
9081     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
9082     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
9083     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
9084     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
9085     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
9086     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
9087     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
9088     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
9089     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
9090     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
9091     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
9092     mpn_lshift(buf, buf, 18, 1);
9093     mpn_add_n(z, z, buf, 18);
9094 }
9095 #endif /* !defined(HAVE_native_mpfq_fixmp_9_sqr) */
9096 
9097 #if !defined(HAVE_native_mpfq_fixmp_9_mul1)
9098 /* x has 9 words, z has 11. Put x*y in z. */
9099 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
9100 static inline
mpfq_fixmp_9_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)9101 void mpfq_fixmp_9_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
9102 {
9103     mp_limb_t hi, lo, carry;
9104     carry = 0;
9105     mpfq_umul_ppmm(hi,lo,c,x[0]);
9106     lo += carry;
9107     carry = (lo<carry) + hi;
9108     z[0] = lo;
9109     mpfq_umul_ppmm(hi,lo,c,x[1]);
9110     lo += carry;
9111     carry = (lo<carry) + hi;
9112     z[1] = lo;
9113     mpfq_umul_ppmm(hi,lo,c,x[2]);
9114     lo += carry;
9115     carry = (lo<carry) + hi;
9116     z[2] = lo;
9117     mpfq_umul_ppmm(hi,lo,c,x[3]);
9118     lo += carry;
9119     carry = (lo<carry) + hi;
9120     z[3] = lo;
9121     mpfq_umul_ppmm(hi,lo,c,x[4]);
9122     lo += carry;
9123     carry = (lo<carry) + hi;
9124     z[4] = lo;
9125     mpfq_umul_ppmm(hi,lo,c,x[5]);
9126     lo += carry;
9127     carry = (lo<carry) + hi;
9128     z[5] = lo;
9129     mpfq_umul_ppmm(hi,lo,c,x[6]);
9130     lo += carry;
9131     carry = (lo<carry) + hi;
9132     z[6] = lo;
9133     mpfq_umul_ppmm(hi,lo,c,x[7]);
9134     lo += carry;
9135     carry = (lo<carry) + hi;
9136     z[7] = lo;
9137     mpfq_umul_ppmm(hi,lo,c,x[8]);
9138     lo += carry;
9139     carry = (lo<carry) + hi;
9140     z[8] = lo;
9141     z[9] = carry;
9142 }
9143 #endif /* !defined(HAVE_native_mpfq_fixmp_9_mul1) */
9144 
9145 #if !defined(HAVE_native_mpfq_fixmp_9_shortmul)
9146 /* x and y have 9 words, z has 10.
9147  * Put the low 10 words of x*y in z. */
9148 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
9149 static inline
mpfq_fixmp_9_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9150 void mpfq_fixmp_9_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9151 {
9152     mpfq_zero(z, 9);
9153     mpfq_fixmp_8_addmul1_nc (z+0, x, y[0]);
9154     z[9-1] += x[8]*y[0];
9155     mpfq_fixmp_7_addmul1_nc (z+1, x, y[1]);
9156     z[9-1] += x[7]*y[1];
9157     mpfq_fixmp_6_addmul1_nc (z+2, x, y[2]);
9158     z[9-1] += x[6]*y[2];
9159     mpfq_fixmp_5_addmul1_nc (z+3, x, y[3]);
9160     z[9-1] += x[5]*y[3];
9161     mpfq_fixmp_4_addmul1_nc (z+4, x, y[4]);
9162     z[9-1] += x[4]*y[4];
9163     mpfq_fixmp_3_addmul1_nc (z+5, x, y[5]);
9164     z[9-1] += x[3]*y[5];
9165     mpfq_fixmp_2_addmul1_nc (z+6, x, y[6]);
9166     z[9-1] += x[2]*y[6];
9167     mpfq_fixmp_1_addmul1_nc (z+7, x, y[7]);
9168     z[9-1] += x[1]*y[7];
9169     z[9-1] += x[0]*y[9-1];
9170 }
9171 #endif /* !defined(HAVE_native_mpfq_fixmp_9_shortmul) */
9172 
9173 #if !defined(HAVE_native_mpfq_fixmp_9_mod)
9174 /* x has 20 words. z and p have 9 words, and the high word of p is non-zero.
9175  * Put x mod p in z. */
9176 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
9177 /* Triggered by: 9_mgy_decode */
9178 static inline
mpfq_fixmp_9_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)9179 void mpfq_fixmp_9_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
9180 {
9181     mp_limb_t q[9+1], r[9];
9182     assert (p[9-1] != 0);
9183     mpn_tdiv_qr(q, r, 0, x, 18, p, 9);
9184     mpfq_copy(z, r, 9);
9185 }
9186 #endif /* !defined(HAVE_native_mpfq_fixmp_9_mod) */
9187 
9188 #if !defined(HAVE_native_mpfq_fixmp_9_rshift)
9189 /* a has 9 words. Shift it in place by cnt bits to the right.
9190  * The shift count cnt must not exceed the word size.
9191  * Note that no carry is returned for the bits shifted out. */
9192 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
9193 /* Triggered by: 9_invmod */
9194 static inline
mpfq_fixmp_9_rshift(mp_limb_t * a,int cnt)9195 void mpfq_fixmp_9_rshift(mp_limb_t * a, int cnt)
9196 {
9197     if (!cnt) return;
9198     int i;
9199     int dnt = GMP_NUMB_BITS - cnt;
9200     for (i = 0; i < 9-1; ++i) {
9201         a[i] >>= cnt;
9202         a[i] |= (a[i+1] << dnt);
9203     }
9204     a[9-1] >>= cnt;
9205 }
9206 #endif /* !defined(HAVE_native_mpfq_fixmp_9_rshift) */
9207 
9208 #if !defined(HAVE_native_mpfq_fixmp_9_long_rshift)
9209 /* a has 9 words. Shift it in place by off words plus cnt bits to the left.
9210  * Note that no carry is returned for the bits shifted out. */
9211 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
9212 /* Triggered by: 9_invmod */
9213 static inline
mpfq_fixmp_9_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)9214 void mpfq_fixmp_9_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
9215 {
9216     if (cnt) {
9217         int dnt = GMP_NUMB_BITS - cnt;
9218         for (int i = 0; i < 9 - off - 1; ++i) {
9219             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
9220         }
9221         a[9-off-1] = a[9-1]>>cnt;
9222     } else {
9223         mpfq_copyi(a, a + off, 9 - off);
9224     }
9225     mpfq_zero(a + 9 - off, off);
9226 }
9227 #endif /* !defined(HAVE_native_mpfq_fixmp_9_long_rshift) */
9228 
9229 #if !defined(HAVE_native_mpfq_fixmp_9_long_lshift)
9230 /* a has 9 words. Shift it in place by off words plus cnt bits to the left.
9231  * Note that no carry is returned for the bits shifted out. */
9232 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
9233 /* Triggered by: 9_invmod */
9234 static inline
mpfq_fixmp_9_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)9235 void mpfq_fixmp_9_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
9236 {
9237     int i;
9238     if (cnt) {
9239         int dnt = GMP_NUMB_BITS - cnt;
9240         for (i = 9-1; i>off; --i) {
9241             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
9242         }
9243         a[off] = a[0]<<cnt;
9244     } else {
9245         mpfq_copyd(a + off, a, 9 - off);
9246     }
9247     mpfq_zero(a, off);
9248 }
9249 #endif /* !defined(HAVE_native_mpfq_fixmp_9_long_lshift) */
9250 
9251 #if !defined(HAVE_native_mpfq_fixmp_9_invmod)
9252 /* x, z, and p have 9 words. Put inverse of x mod p in z.
9253  * Return non-zero if an inverse could be found.
9254  * If no inverse could be found, return 0 and set z to zero.
9255  */
9256 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
9257 static inline
mpfq_fixmp_9_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)9258 int mpfq_fixmp_9_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
9259 {
9260       mp_limb_t u[9], v[9], a[9], b[9], fix[9];
9261       int i, t, lsh;
9262 
9263       mpfq_zero(u, 9);
9264       mpfq_zero(v, 9);
9265       mpfq_copy(a, x, 9);
9266       mpfq_copy(b, p, 9);
9267       u[0] = 1UL;
9268 
9269       if (mpfq_fixmp_9_cmp(a, v) == 0 || mpfq_fixmp_9_cmp(a, b) == 0) {
9270         mpfq_zero(res, 9);
9271         return 0;
9272       }
9273 
9274       mpfq_fixmp_9_add(fix, b, u);
9275       mpfq_fixmp_9_rshift(fix, 1);
9276 
9277       assert (mpfq_fixmp_9_cmp(a,b) < 0);
9278 
9279       t = 0;
9280 
9281       for(i = 0 ; !a[i] ; i++) ;
9282       assert (i < 9);
9283       lsh = mpfq_ctzl(a[i]);
9284       mpfq_fixmp_9_long_rshift(a, i, lsh);
9285       t += lsh + i*GMP_NUMB_BITS;
9286       mpfq_fixmp_9_long_lshift(v, i, lsh);
9287 
9288       do {
9289         do {
9290           mpfq_fixmp_9_sub(b, b, a);
9291           mpfq_fixmp_9_add(v, v, u);
9292           for(i = 0 ; !b[i] ; i++) ;
9293           assert (i < 9);
9294           lsh = mpfq_ctzl(b[i]);
9295           mpfq_fixmp_9_long_rshift(b, i, lsh);
9296           t += lsh + i*GMP_NUMB_BITS;
9297           mpfq_fixmp_9_long_lshift(u, i, lsh);
9298         } while (mpfq_fixmp_9_cmp(a,b) < 0);
9299         if (mpfq_fixmp_9_cmp(a, b) == 0)
9300           break;
9301         do {
9302           mpfq_fixmp_9_sub(a, a, b);
9303           mpfq_fixmp_9_add(u, u, v);
9304           for(i = 0 ; !a[i] ; i++) ;
9305           assert (i < 9);
9306           lsh = mpfq_ctzl(a[i]);
9307           mpfq_fixmp_9_long_rshift(a, i, lsh);
9308           t += lsh + i*GMP_NUMB_BITS;
9309           mpfq_fixmp_9_long_lshift(v, i, lsh);
9310         } while (mpfq_fixmp_9_cmp(b,a)<0);
9311       } while (mpfq_fixmp_9_cmp(a,b) != 0);
9312       {
9313         if (mpfq_fixmp_9_cmp_ui(a, 1) != 0) {
9314           mpfq_copy(res, a, 9);
9315           return 0;
9316         }
9317       }
9318       while (t>0) {
9319         mp_limb_t sig = u[0] & 1UL;
9320         mpfq_fixmp_9_rshift(u, 1);
9321         if (sig)
9322           mpfq_fixmp_9_add(u, u, fix);
9323         --t;
9324       }
9325       mpfq_copy(res, u, 9);
9326       return 1;
9327 }
9328 #endif /* !defined(HAVE_native_mpfq_fixmp_9_invmod) */
9329 
9330 #if !defined(HAVE_native_mpfq_fixmp_9_redc)
9331 /* x has 20 words, z and p have 9 words.
9332  * only one word is read from invp.
9333  * Assuming R=W^10 is the redc modulus, we expect that x verifies:
9334  *   x < R*p,
9335  * so that we have eventually z < p, z congruent to x/R mod p.
9336  * The contents of the area pointed by x are clobbered by this call.
9337  * Note also that x may alias z.
9338  */
9339 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
9340 static inline
mpfq_fixmp_9_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)9341 void mpfq_fixmp_9_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
9342 {
9343     mp_limb_t cy;
9344     for(int i = 0; i < 9; ++i) {
9345         mp_limb_t t = x[i]*mip[0];
9346         cy = mpfq_fixmp_9_addmul1_shortz(x+i, p, t);
9347         assert (x[i] == 0);
9348         x[i] = cy;
9349     }
9350     cy = mpfq_fixmp_9_add(x, x, x + 9);
9351     /* At this point, we have (x' denotes x + cy*W^n here)
9352     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
9353     * x'/R < p + p
9354     */
9355     if (cy || mpfq_fixmp_9_cmp(x, p) >= 0) {
9356         mpfq_fixmp_9_sub(z, x, p);
9357     } else {
9358         mpfq_copy(z, x, 9);
9359     }
9360 }
9361 #endif /* !defined(HAVE_native_mpfq_fixmp_9_redc) */
9362 
9363 #if !defined(HAVE_native_mpfq_fixmp_9_redc_ur)
9364 /* x has 21 words, z and p have 9 words.
9365  * only one word is read from invp.
9366  * Assuming R=W^10 is the redc modulus, we expect that x verifies:
9367  *  x < W*W^9*p = W^0.5*R*p or the hw case, W*R*p otherwise,
9368  * so that we have eventually z < p, z congruent to x/R mod p.
9369  * The contents of the area pointed by x are clobbered by this call.
9370  * Note also that x may alias z.
9371  */
9372 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
9373 static inline
mpfq_fixmp_9_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)9374 void mpfq_fixmp_9_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
9375 {
9376     mp_limb_t cy, q[2];
9377     for (int i = 0; i < 9; ++i) {
9378         mp_limb_t t = x[i]*mip[0];
9379         cy = mpfq_fixmp_9_addmul1(x+i, p, t);
9380         assert (x[i] == 0);
9381         x[i] = cy;
9382     }
9383     cy=mpfq_fixmp_9_add(x+9+1, x+9+1, x);
9384     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
9385     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
9386     * x'/R < (W+1)*p
9387     */
9388     if (cy) {
9389         /* x'/R-p < W*p, which fits in n+1 words */
9390         mpn_sub(x+9,x+9,9+1,p,9);
9391     }
9392     mpn_tdiv_qr(q, z, 0, x+9, 9+1, p, 9);
9393 }
9394 #endif /* !defined(HAVE_native_mpfq_fixmp_9_redc_ur) */
9395 
9396 #if !defined(HAVE_native_mpfq_fixmp_9_mgy_encode)
9397 /* x, z, and p have 9 words.
9398  * Assuming R=W^10 is the redc modulus, we compute z=R*x mod p. */
9399 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
9400 static inline
mpfq_fixmp_9_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)9401 void mpfq_fixmp_9_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
9402 {
9403     mp_limb_t t[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8] };
9404     mpfq_fixmp_9_mod(z, t, p);
9405 }
9406 #endif /* !defined(HAVE_native_mpfq_fixmp_9_mgy_encode) */
9407 
9408 #if !defined(HAVE_native_mpfq_fixmp_9_mgy_decode)
9409 /* x, z, invR, and p have 9 words.
9410  * Assuming R=W^10 is the redc modulus, we compute z=x/R mod p. */
9411 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
9412 static inline
mpfq_fixmp_9_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)9413 void mpfq_fixmp_9_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
9414 {
9415     mp_limb_t t[18];
9416     mpfq_fixmp_9_mul(t, x, invR);
9417     mpfq_fixmp_9_mod(z, t, p);
9418 }
9419 #endif /* !defined(HAVE_native_mpfq_fixmp_9_mgy_decode) */
9420 
9421 #if !defined(HAVE_native_mpfq_fixmp_9_lshift)
9422 /* a has 9 words. Shift it in place by cnt bits to the left.
9423  * The shift count cnt must not exceed the word size.
9424  * Note that no carry is returned for the bits shifted out. */
9425 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
9426 static inline
mpfq_fixmp_9_lshift(mp_limb_t * a,int cnt)9427 void mpfq_fixmp_9_lshift(mp_limb_t * a, int cnt)
9428 {
9429     if (!cnt) return;
9430     int i;
9431     int dnt = GMP_NUMB_BITS - cnt;
9432     for (i = 9-1; i>0; --i) {
9433         a[i] <<= cnt;
9434         a[i] |= (a[i-1] >> dnt);
9435     }
9436     a[0] <<= cnt;
9437 }
9438 #endif /* !defined(HAVE_native_mpfq_fixmp_9_lshift) */
9439 
9440 #if !defined(HAVE_native_mpfq_fixmp_10_add)
9441 /* x, y, and z have 10 words. Result in z. Return carry bit */
9442 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
9443 /* Triggered by: 10_invmod, 10_redc, 10_redc_ur */
9444 static inline
mpfq_fixmp_10_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9445 mp_limb_t mpfq_fixmp_10_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9446 {
9447     mp_limb_t r, s, t, cy, cy1, cy2;
9448     cy = 0;
9449     r = x[0];
9450     s = r + y[0];
9451     cy1 = s < r;
9452     t = s + cy;
9453     cy2 = t < s;
9454     cy = cy1 | cy2;
9455     z[0] = t;
9456     r = x[1];
9457     s = r + y[1];
9458     cy1 = s < r;
9459     t = s + cy;
9460     cy2 = t < s;
9461     cy = cy1 | cy2;
9462     z[1] = t;
9463     r = x[2];
9464     s = r + y[2];
9465     cy1 = s < r;
9466     t = s + cy;
9467     cy2 = t < s;
9468     cy = cy1 | cy2;
9469     z[2] = t;
9470     r = x[3];
9471     s = r + y[3];
9472     cy1 = s < r;
9473     t = s + cy;
9474     cy2 = t < s;
9475     cy = cy1 | cy2;
9476     z[3] = t;
9477     r = x[4];
9478     s = r + y[4];
9479     cy1 = s < r;
9480     t = s + cy;
9481     cy2 = t < s;
9482     cy = cy1 | cy2;
9483     z[4] = t;
9484     r = x[5];
9485     s = r + y[5];
9486     cy1 = s < r;
9487     t = s + cy;
9488     cy2 = t < s;
9489     cy = cy1 | cy2;
9490     z[5] = t;
9491     r = x[6];
9492     s = r + y[6];
9493     cy1 = s < r;
9494     t = s + cy;
9495     cy2 = t < s;
9496     cy = cy1 | cy2;
9497     z[6] = t;
9498     r = x[7];
9499     s = r + y[7];
9500     cy1 = s < r;
9501     t = s + cy;
9502     cy2 = t < s;
9503     cy = cy1 | cy2;
9504     z[7] = t;
9505     r = x[8];
9506     s = r + y[8];
9507     cy1 = s < r;
9508     t = s + cy;
9509     cy2 = t < s;
9510     cy = cy1 | cy2;
9511     z[8] = t;
9512     r = x[9];
9513     s = r + y[9];
9514     cy1 = s < r;
9515     t = s + cy;
9516     cy2 = t < s;
9517     cy = cy1 | cy2;
9518     z[9] = t;
9519     return cy;
9520 }
9521 #endif /* !defined(HAVE_native_mpfq_fixmp_10_add) */
9522 
9523 #if !defined(HAVE_native_mpfq_fixmp_10_sub)
9524 /* x, y, and z have 10 words. Result in z. Return borrow bit */
9525 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
9526 /* Triggered by: 10_invmod, 10_redc */
9527 static inline
mpfq_fixmp_10_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9528 mp_limb_t mpfq_fixmp_10_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9529 {
9530     mp_limb_t r, s, t, cy, cy1, cy2;
9531     cy = 0;
9532     r = x[0];
9533     s = r - y[0];
9534     cy1 = s > r;
9535     t = s - cy;
9536     cy2 = t > s;
9537     cy = cy1 | cy2;
9538     z[0] = t;
9539     r = x[1];
9540     s = r - y[1];
9541     cy1 = s > r;
9542     t = s - cy;
9543     cy2 = t > s;
9544     cy = cy1 | cy2;
9545     z[1] = t;
9546     r = x[2];
9547     s = r - y[2];
9548     cy1 = s > r;
9549     t = s - cy;
9550     cy2 = t > s;
9551     cy = cy1 | cy2;
9552     z[2] = t;
9553     r = x[3];
9554     s = r - y[3];
9555     cy1 = s > r;
9556     t = s - cy;
9557     cy2 = t > s;
9558     cy = cy1 | cy2;
9559     z[3] = t;
9560     r = x[4];
9561     s = r - y[4];
9562     cy1 = s > r;
9563     t = s - cy;
9564     cy2 = t > s;
9565     cy = cy1 | cy2;
9566     z[4] = t;
9567     r = x[5];
9568     s = r - y[5];
9569     cy1 = s > r;
9570     t = s - cy;
9571     cy2 = t > s;
9572     cy = cy1 | cy2;
9573     z[5] = t;
9574     r = x[6];
9575     s = r - y[6];
9576     cy1 = s > r;
9577     t = s - cy;
9578     cy2 = t > s;
9579     cy = cy1 | cy2;
9580     z[6] = t;
9581     r = x[7];
9582     s = r - y[7];
9583     cy1 = s > r;
9584     t = s - cy;
9585     cy2 = t > s;
9586     cy = cy1 | cy2;
9587     z[7] = t;
9588     r = x[8];
9589     s = r - y[8];
9590     cy1 = s > r;
9591     t = s - cy;
9592     cy2 = t > s;
9593     cy = cy1 | cy2;
9594     z[8] = t;
9595     r = x[9];
9596     s = r - y[9];
9597     cy1 = s > r;
9598     t = s - cy;
9599     cy2 = t > s;
9600     cy = cy1 | cy2;
9601     z[9] = t;
9602     return cy;
9603 }
9604 #endif /* !defined(HAVE_native_mpfq_fixmp_10_sub) */
9605 
9606 #if !defined(HAVE_native_mpfq_fixmp_10_add_nc)
9607 /* x, y, and z have 10 words. Result in z. Carry bit is lost. */
9608 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
9609 static inline
mpfq_fixmp_10_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9610 void mpfq_fixmp_10_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9611 {
9612     mp_limb_t r, s, t, cy, cy1, cy2;
9613     cy = 0;
9614     r = x[0];
9615     s = r + y[0];
9616     cy1 = s < r;
9617     t = s + cy;
9618     cy2 = t < s;
9619     cy = cy1 | cy2;
9620     z[0] = t;
9621     r = x[1];
9622     s = r + y[1];
9623     cy1 = s < r;
9624     t = s + cy;
9625     cy2 = t < s;
9626     cy = cy1 | cy2;
9627     z[1] = t;
9628     r = x[2];
9629     s = r + y[2];
9630     cy1 = s < r;
9631     t = s + cy;
9632     cy2 = t < s;
9633     cy = cy1 | cy2;
9634     z[2] = t;
9635     r = x[3];
9636     s = r + y[3];
9637     cy1 = s < r;
9638     t = s + cy;
9639     cy2 = t < s;
9640     cy = cy1 | cy2;
9641     z[3] = t;
9642     r = x[4];
9643     s = r + y[4];
9644     cy1 = s < r;
9645     t = s + cy;
9646     cy2 = t < s;
9647     cy = cy1 | cy2;
9648     z[4] = t;
9649     r = x[5];
9650     s = r + y[5];
9651     cy1 = s < r;
9652     t = s + cy;
9653     cy2 = t < s;
9654     cy = cy1 | cy2;
9655     z[5] = t;
9656     r = x[6];
9657     s = r + y[6];
9658     cy1 = s < r;
9659     t = s + cy;
9660     cy2 = t < s;
9661     cy = cy1 | cy2;
9662     z[6] = t;
9663     r = x[7];
9664     s = r + y[7];
9665     cy1 = s < r;
9666     t = s + cy;
9667     cy2 = t < s;
9668     cy = cy1 | cy2;
9669     z[7] = t;
9670     r = x[8];
9671     s = r + y[8];
9672     cy1 = s < r;
9673     t = s + cy;
9674     cy2 = t < s;
9675     cy = cy1 | cy2;
9676     z[8] = t;
9677     r = x[9];
9678     s = r + y[9];
9679     cy1 = s < r;
9680     t = s + cy;
9681     cy2 = t < s;
9682     cy = cy1 | cy2;
9683     z[9] = t;
9684 }
9685 #endif /* !defined(HAVE_native_mpfq_fixmp_10_add_nc) */
9686 
9687 #if !defined(HAVE_native_mpfq_fixmp_10_sub_nc)
9688 /* x, y, and z have 10 words. Result in z. Borrow bit is lost. */
9689 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
9690 static inline
mpfq_fixmp_10_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)9691 void mpfq_fixmp_10_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
9692 {
9693     mp_limb_t r, s, t, cy, cy1, cy2;
9694     cy = 0;
9695     r = x[0];
9696     s = r - y[0];
9697     cy1 = s > r;
9698     t = s - cy;
9699     cy2 = t > s;
9700     cy = cy1 | cy2;
9701     z[0] = t;
9702     r = x[1];
9703     s = r - y[1];
9704     cy1 = s > r;
9705     t = s - cy;
9706     cy2 = t > s;
9707     cy = cy1 | cy2;
9708     z[1] = t;
9709     r = x[2];
9710     s = r - y[2];
9711     cy1 = s > r;
9712     t = s - cy;
9713     cy2 = t > s;
9714     cy = cy1 | cy2;
9715     z[2] = t;
9716     r = x[3];
9717     s = r - y[3];
9718     cy1 = s > r;
9719     t = s - cy;
9720     cy2 = t > s;
9721     cy = cy1 | cy2;
9722     z[3] = t;
9723     r = x[4];
9724     s = r - y[4];
9725     cy1 = s > r;
9726     t = s - cy;
9727     cy2 = t > s;
9728     cy = cy1 | cy2;
9729     z[4] = t;
9730     r = x[5];
9731     s = r - y[5];
9732     cy1 = s > r;
9733     t = s - cy;
9734     cy2 = t > s;
9735     cy = cy1 | cy2;
9736     z[5] = t;
9737     r = x[6];
9738     s = r - y[6];
9739     cy1 = s > r;
9740     t = s - cy;
9741     cy2 = t > s;
9742     cy = cy1 | cy2;
9743     z[6] = t;
9744     r = x[7];
9745     s = r - y[7];
9746     cy1 = s > r;
9747     t = s - cy;
9748     cy2 = t > s;
9749     cy = cy1 | cy2;
9750     z[7] = t;
9751     r = x[8];
9752     s = r - y[8];
9753     cy1 = s > r;
9754     t = s - cy;
9755     cy2 = t > s;
9756     cy = cy1 | cy2;
9757     z[8] = t;
9758     r = x[9];
9759     s = r - y[9];
9760     cy1 = s > r;
9761     t = s - cy;
9762     cy2 = t > s;
9763     cy = cy1 | cy2;
9764     z[9] = t;
9765 }
9766 #endif /* !defined(HAVE_native_mpfq_fixmp_10_sub_nc) */
9767 
9768 #if !defined(HAVE_native_mpfq_fixmp_10_add_ui)
9769 /* x, y, and z have 10 words. Result in z. Return carry bit */
9770 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
9771 static inline
mpfq_fixmp_10_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)9772 mp_limb_t mpfq_fixmp_10_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
9773 {
9774     mp_limb_t r, s, t, cy, cy1, cy2;
9775     cy = 0;
9776     r = x[0];
9777     s = r + y;
9778     cy1 = s < r;
9779     t = s + cy;
9780     cy2 = t < s;
9781     cy = cy1 | cy2;
9782     z[0] = t;
9783     s = x[1];
9784     t = s + cy;
9785     cy = t < s;
9786     z[1] = t;
9787     s = x[2];
9788     t = s + cy;
9789     cy = t < s;
9790     z[2] = t;
9791     s = x[3];
9792     t = s + cy;
9793     cy = t < s;
9794     z[3] = t;
9795     s = x[4];
9796     t = s + cy;
9797     cy = t < s;
9798     z[4] = t;
9799     s = x[5];
9800     t = s + cy;
9801     cy = t < s;
9802     z[5] = t;
9803     s = x[6];
9804     t = s + cy;
9805     cy = t < s;
9806     z[6] = t;
9807     s = x[7];
9808     t = s + cy;
9809     cy = t < s;
9810     z[7] = t;
9811     s = x[8];
9812     t = s + cy;
9813     cy = t < s;
9814     z[8] = t;
9815     s = x[9];
9816     t = s + cy;
9817     cy = t < s;
9818     z[9] = t;
9819     return cy;
9820 }
9821 #endif /* !defined(HAVE_native_mpfq_fixmp_10_add_ui) */
9822 
9823 #if !defined(HAVE_native_mpfq_fixmp_10_sub_ui)
9824 /* x, y, and z have 10 words. Result in z. Return borrow bit */
9825 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
9826 static inline
mpfq_fixmp_10_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)9827 mp_limb_t mpfq_fixmp_10_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
9828 {
9829     mp_limb_t r, s, t, cy, cy1, cy2;
9830     cy = 0;
9831     r = x[0];
9832     s = r - y;
9833     cy1 = s > r;
9834     t = s - cy;
9835     cy2 = t > s;
9836     cy = cy1 | cy2;
9837     z[0] = t;
9838     s = x[1];
9839     t = s - cy;
9840     cy = t > s;
9841     z[1] = t;
9842     s = x[2];
9843     t = s - cy;
9844     cy = t > s;
9845     z[2] = t;
9846     s = x[3];
9847     t = s - cy;
9848     cy = t > s;
9849     z[3] = t;
9850     s = x[4];
9851     t = s - cy;
9852     cy = t > s;
9853     z[4] = t;
9854     s = x[5];
9855     t = s - cy;
9856     cy = t > s;
9857     z[5] = t;
9858     s = x[6];
9859     t = s - cy;
9860     cy = t > s;
9861     z[6] = t;
9862     s = x[7];
9863     t = s - cy;
9864     cy = t > s;
9865     z[7] = t;
9866     s = x[8];
9867     t = s - cy;
9868     cy = t > s;
9869     z[8] = t;
9870     s = x[9];
9871     t = s - cy;
9872     cy = t > s;
9873     z[9] = t;
9874     return cy;
9875 }
9876 #endif /* !defined(HAVE_native_mpfq_fixmp_10_sub_ui) */
9877 
9878 #if !defined(HAVE_native_mpfq_fixmp_10_add_ui_nc)
9879 /* x, y, and z have 10 words. Result in z. Carry bit is lost. */
9880 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
9881 static inline
mpfq_fixmp_10_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)9882 void mpfq_fixmp_10_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
9883 {
9884     mp_limb_t r, s, t, cy, cy1, cy2;
9885     cy = 0;
9886     r = x[0];
9887     s = r + y;
9888     cy1 = s < r;
9889     t = s + cy;
9890     cy2 = t < s;
9891     cy = cy1 | cy2;
9892     z[0] = t;
9893     s = x[1];
9894     t = s + cy;
9895     cy = t < s;
9896     z[1] = t;
9897     s = x[2];
9898     t = s + cy;
9899     cy = t < s;
9900     z[2] = t;
9901     s = x[3];
9902     t = s + cy;
9903     cy = t < s;
9904     z[3] = t;
9905     s = x[4];
9906     t = s + cy;
9907     cy = t < s;
9908     z[4] = t;
9909     s = x[5];
9910     t = s + cy;
9911     cy = t < s;
9912     z[5] = t;
9913     s = x[6];
9914     t = s + cy;
9915     cy = t < s;
9916     z[6] = t;
9917     s = x[7];
9918     t = s + cy;
9919     cy = t < s;
9920     z[7] = t;
9921     s = x[8];
9922     t = s + cy;
9923     cy = t < s;
9924     z[8] = t;
9925     s = x[9];
9926     t = s + cy;
9927     cy = t < s;
9928     z[9] = t;
9929 }
9930 #endif /* !defined(HAVE_native_mpfq_fixmp_10_add_ui_nc) */
9931 
9932 #if !defined(HAVE_native_mpfq_fixmp_10_sub_ui_nc)
9933 /* x, y, and z have 10 words. Result in z. Borrow bit is lost. */
9934 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
9935 static inline
mpfq_fixmp_10_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)9936 void mpfq_fixmp_10_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
9937 {
9938     mp_limb_t r, s, t, cy, cy1, cy2;
9939     cy = 0;
9940     r = x[0];
9941     s = r - y;
9942     cy1 = s > r;
9943     t = s - cy;
9944     cy2 = t > s;
9945     cy = cy1 | cy2;
9946     z[0] = t;
9947     s = x[1];
9948     t = s - cy;
9949     cy = t > s;
9950     z[1] = t;
9951     s = x[2];
9952     t = s - cy;
9953     cy = t > s;
9954     z[2] = t;
9955     s = x[3];
9956     t = s - cy;
9957     cy = t > s;
9958     z[3] = t;
9959     s = x[4];
9960     t = s - cy;
9961     cy = t > s;
9962     z[4] = t;
9963     s = x[5];
9964     t = s - cy;
9965     cy = t > s;
9966     z[5] = t;
9967     s = x[6];
9968     t = s - cy;
9969     cy = t > s;
9970     z[6] = t;
9971     s = x[7];
9972     t = s - cy;
9973     cy = t > s;
9974     z[7] = t;
9975     s = x[8];
9976     t = s - cy;
9977     cy = t > s;
9978     z[8] = t;
9979     s = x[9];
9980     t = s - cy;
9981     cy = t > s;
9982     z[9] = t;
9983 }
9984 #endif /* !defined(HAVE_native_mpfq_fixmp_10_sub_ui_nc) */
9985 
9986 #if !defined(HAVE_native_mpfq_fixmp_10_cmp)
9987 /* x and y have 10 words. Return sign of difference x-y. */
9988 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
9989 /* Triggered by: 10_invmod, 10_redc */
9990 static inline
mpfq_fixmp_10_cmp(const mp_limb_t * x,const mp_limb_t * y)9991 int mpfq_fixmp_10_cmp(const mp_limb_t * x, const mp_limb_t * y)
9992 {
9993     for (int i = 10-1; i >= 0; --i) {
9994         if (x[i] > y[i]) return 1;
9995         if (x[i] < y[i]) return -1;
9996     }
9997     return 0;
9998 }
9999 #endif /* !defined(HAVE_native_mpfq_fixmp_10_cmp) */
10000 
10001 #if !defined(HAVE_native_mpfq_fixmp_10_cmp_ui)
10002 /* x has 10 words. Return sign of difference x-y. */
10003 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
10004 /* Triggered by: 10_invmod */
10005 static inline
mpfq_fixmp_10_cmp_ui(const mp_limb_t * x,mp_limb_t y)10006 int mpfq_fixmp_10_cmp_ui(const mp_limb_t * x, mp_limb_t y)
10007 {
10008     for (int i = 10-1; i > 0; --i) {
10009         if (x[i]) return 1;
10010     }
10011     if (x[0]>y) return 1;
10012     if (x[0]<y) return -1;
10013     return 0;
10014 }
10015 #endif /* !defined(HAVE_native_mpfq_fixmp_10_cmp_ui) */
10016 
10017 #if !defined(HAVE_native_mpfq_fixmp_10_addmul1)
10018 /* x has 10 words, z has 12.
10019  * Put (z+x*c) in z. Return carry bit. */
10020 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
10021 /* Triggered by: 10_redc_ur */
10022 static inline
mpfq_fixmp_10_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)10023 mp_limb_t mpfq_fixmp_10_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
10024 {
10025     mp_limb_t hi, lo, carry, buf;
10026     carry = 0;
10027     mpfq_umul_ppmm(hi,lo,c,x[0]);
10028     lo += carry;
10029     carry = (lo<carry) + hi;
10030     buf = z[0];
10031     lo += buf;
10032     carry += (lo<buf);
10033     z[0] = lo;
10034     mpfq_umul_ppmm(hi,lo,c,x[1]);
10035     lo += carry;
10036     carry = (lo<carry) + hi;
10037     buf = z[1];
10038     lo += buf;
10039     carry += (lo<buf);
10040     z[1] = lo;
10041     mpfq_umul_ppmm(hi,lo,c,x[2]);
10042     lo += carry;
10043     carry = (lo<carry) + hi;
10044     buf = z[2];
10045     lo += buf;
10046     carry += (lo<buf);
10047     z[2] = lo;
10048     mpfq_umul_ppmm(hi,lo,c,x[3]);
10049     lo += carry;
10050     carry = (lo<carry) + hi;
10051     buf = z[3];
10052     lo += buf;
10053     carry += (lo<buf);
10054     z[3] = lo;
10055     mpfq_umul_ppmm(hi,lo,c,x[4]);
10056     lo += carry;
10057     carry = (lo<carry) + hi;
10058     buf = z[4];
10059     lo += buf;
10060     carry += (lo<buf);
10061     z[4] = lo;
10062     mpfq_umul_ppmm(hi,lo,c,x[5]);
10063     lo += carry;
10064     carry = (lo<carry) + hi;
10065     buf = z[5];
10066     lo += buf;
10067     carry += (lo<buf);
10068     z[5] = lo;
10069     mpfq_umul_ppmm(hi,lo,c,x[6]);
10070     lo += carry;
10071     carry = (lo<carry) + hi;
10072     buf = z[6];
10073     lo += buf;
10074     carry += (lo<buf);
10075     z[6] = lo;
10076     mpfq_umul_ppmm(hi,lo,c,x[7]);
10077     lo += carry;
10078     carry = (lo<carry) + hi;
10079     buf = z[7];
10080     lo += buf;
10081     carry += (lo<buf);
10082     z[7] = lo;
10083     mpfq_umul_ppmm(hi,lo,c,x[8]);
10084     lo += carry;
10085     carry = (lo<carry) + hi;
10086     buf = z[8];
10087     lo += buf;
10088     carry += (lo<buf);
10089     z[8] = lo;
10090     mpfq_umul_ppmm(hi,lo,c,x[9]);
10091     lo += carry;
10092     carry = (lo<carry) + hi;
10093     buf = z[9];
10094     lo += buf;
10095     carry += (lo<buf);
10096     z[9] = lo;
10097     z[10] += carry;
10098     return (z[10]<carry);
10099 }
10100 #endif /* !defined(HAVE_native_mpfq_fixmp_10_addmul1) */
10101 
10102 #if !defined(HAVE_native_mpfq_fixmp_10_addmul1_nc)
10103 /* x has 10 words, z has 12.
10104  * Put (z+x*c) in z. Carry bit is lost. */
10105 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
10106 /* Triggered by: 10_mul, 10_mgy_decode, 11_sqr, 11_shortmul, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 10_5_sqr, 10_5_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
10107 static inline
mpfq_fixmp_10_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)10108 void mpfq_fixmp_10_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
10109 {
10110     mp_limb_t hi, lo, carry, buf;
10111     carry = 0;
10112     mpfq_umul_ppmm(hi,lo,c,x[0]);
10113     lo += carry;
10114     carry = (lo<carry) + hi;
10115     buf = z[0];
10116     lo += buf;
10117     carry += (lo<buf);
10118     z[0] = lo;
10119     mpfq_umul_ppmm(hi,lo,c,x[1]);
10120     lo += carry;
10121     carry = (lo<carry) + hi;
10122     buf = z[1];
10123     lo += buf;
10124     carry += (lo<buf);
10125     z[1] = lo;
10126     mpfq_umul_ppmm(hi,lo,c,x[2]);
10127     lo += carry;
10128     carry = (lo<carry) + hi;
10129     buf = z[2];
10130     lo += buf;
10131     carry += (lo<buf);
10132     z[2] = lo;
10133     mpfq_umul_ppmm(hi,lo,c,x[3]);
10134     lo += carry;
10135     carry = (lo<carry) + hi;
10136     buf = z[3];
10137     lo += buf;
10138     carry += (lo<buf);
10139     z[3] = lo;
10140     mpfq_umul_ppmm(hi,lo,c,x[4]);
10141     lo += carry;
10142     carry = (lo<carry) + hi;
10143     buf = z[4];
10144     lo += buf;
10145     carry += (lo<buf);
10146     z[4] = lo;
10147     mpfq_umul_ppmm(hi,lo,c,x[5]);
10148     lo += carry;
10149     carry = (lo<carry) + hi;
10150     buf = z[5];
10151     lo += buf;
10152     carry += (lo<buf);
10153     z[5] = lo;
10154     mpfq_umul_ppmm(hi,lo,c,x[6]);
10155     lo += carry;
10156     carry = (lo<carry) + hi;
10157     buf = z[6];
10158     lo += buf;
10159     carry += (lo<buf);
10160     z[6] = lo;
10161     mpfq_umul_ppmm(hi,lo,c,x[7]);
10162     lo += carry;
10163     carry = (lo<carry) + hi;
10164     buf = z[7];
10165     lo += buf;
10166     carry += (lo<buf);
10167     z[7] = lo;
10168     mpfq_umul_ppmm(hi,lo,c,x[8]);
10169     lo += carry;
10170     carry = (lo<carry) + hi;
10171     buf = z[8];
10172     lo += buf;
10173     carry += (lo<buf);
10174     z[8] = lo;
10175     mpfq_umul_ppmm(hi,lo,c,x[9]);
10176     lo += carry;
10177     carry = (lo<carry) + hi;
10178     buf = z[9];
10179     lo += buf;
10180     carry += (lo<buf);
10181     z[9] = lo;
10182     z[10] += carry;
10183 }
10184 #endif /* !defined(HAVE_native_mpfq_fixmp_10_addmul1_nc) */
10185 
10186 #if !defined(HAVE_native_mpfq_fixmp_10_addmul1_shortz)
10187 /* x has 10 words, z has 11.
10188  * Put (z+x*c) in z. Return carry word. */
10189 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
10190 /* Triggered by: 10_redc */
10191 static inline
mpfq_fixmp_10_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)10192 mp_limb_t mpfq_fixmp_10_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
10193 {
10194     mp_limb_t hi, lo, carry, buf;
10195     carry = 0;
10196     mpfq_umul_ppmm(hi,lo,c,x[0]);
10197     lo += carry;
10198     carry = (lo<carry) + hi;
10199     buf = z[0];
10200     lo += buf;
10201     carry += (lo<buf);
10202     z[0] = lo;
10203     mpfq_umul_ppmm(hi,lo,c,x[1]);
10204     lo += carry;
10205     carry = (lo<carry) + hi;
10206     buf = z[1];
10207     lo += buf;
10208     carry += (lo<buf);
10209     z[1] = lo;
10210     mpfq_umul_ppmm(hi,lo,c,x[2]);
10211     lo += carry;
10212     carry = (lo<carry) + hi;
10213     buf = z[2];
10214     lo += buf;
10215     carry += (lo<buf);
10216     z[2] = lo;
10217     mpfq_umul_ppmm(hi,lo,c,x[3]);
10218     lo += carry;
10219     carry = (lo<carry) + hi;
10220     buf = z[3];
10221     lo += buf;
10222     carry += (lo<buf);
10223     z[3] = lo;
10224     mpfq_umul_ppmm(hi,lo,c,x[4]);
10225     lo += carry;
10226     carry = (lo<carry) + hi;
10227     buf = z[4];
10228     lo += buf;
10229     carry += (lo<buf);
10230     z[4] = lo;
10231     mpfq_umul_ppmm(hi,lo,c,x[5]);
10232     lo += carry;
10233     carry = (lo<carry) + hi;
10234     buf = z[5];
10235     lo += buf;
10236     carry += (lo<buf);
10237     z[5] = lo;
10238     mpfq_umul_ppmm(hi,lo,c,x[6]);
10239     lo += carry;
10240     carry = (lo<carry) + hi;
10241     buf = z[6];
10242     lo += buf;
10243     carry += (lo<buf);
10244     z[6] = lo;
10245     mpfq_umul_ppmm(hi,lo,c,x[7]);
10246     lo += carry;
10247     carry = (lo<carry) + hi;
10248     buf = z[7];
10249     lo += buf;
10250     carry += (lo<buf);
10251     z[7] = lo;
10252     mpfq_umul_ppmm(hi,lo,c,x[8]);
10253     lo += carry;
10254     carry = (lo<carry) + hi;
10255     buf = z[8];
10256     lo += buf;
10257     carry += (lo<buf);
10258     z[8] = lo;
10259     mpfq_umul_ppmm(hi,lo,c,x[9]);
10260     lo += carry;
10261     carry = (lo<carry) + hi;
10262     buf = z[9];
10263     lo += buf;
10264     carry += (lo<buf);
10265     z[9] = lo;
10266     return carry;
10267 }
10268 #endif /* !defined(HAVE_native_mpfq_fixmp_10_addmul1_shortz) */
10269 
10270 #if !defined(HAVE_native_mpfq_fixmp_10_mul)
10271 /* x and y have 10 words, z has 22. Put x*y in z. */
10272 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
10273 /* Triggered by: 10_mgy_decode */
10274 static inline
mpfq_fixmp_10_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10275 void mpfq_fixmp_10_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10276 {
10277     assert(z != x && z != y);
10278     for (int i = 0; i < 20; z[i++] = 0) ;
10279     mpfq_fixmp_10_addmul1_nc (z + 0, x, y[0]);
10280     mpfq_fixmp_10_addmul1_nc (z + 1, x, y[1]);
10281     mpfq_fixmp_10_addmul1_nc (z + 2, x, y[2]);
10282     mpfq_fixmp_10_addmul1_nc (z + 3, x, y[3]);
10283     mpfq_fixmp_10_addmul1_nc (z + 4, x, y[4]);
10284     mpfq_fixmp_10_addmul1_nc (z + 5, x, y[5]);
10285     mpfq_fixmp_10_addmul1_nc (z + 6, x, y[6]);
10286     mpfq_fixmp_10_addmul1_nc (z + 7, x, y[7]);
10287     mpfq_fixmp_10_addmul1_nc (z + 8, x, y[8]);
10288     mpfq_fixmp_10_addmul1_nc (z + 9, x, y[9]);
10289 }
10290 #endif /* !defined(HAVE_native_mpfq_fixmp_10_mul) */
10291 
10292 #if !defined(HAVE_native_mpfq_fixmp_10_sqr)
10293 /* x has 10 words, z has 22. Put x*y in z. */
10294 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
10295 static inline
mpfq_fixmp_10_sqr(mp_limb_t * z,const mp_limb_t * x)10296 void mpfq_fixmp_10_sqr(mp_limb_t * z, const mp_limb_t * x)
10297 {
10298     mp_limb_t buf[20] = {0,};
10299     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
10300     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
10301     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
10302     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
10303     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
10304     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
10305     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
10306     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
10307     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
10308     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
10309     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
10310     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
10311     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
10312     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
10313     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
10314     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
10315     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
10316     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
10317     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
10318     mpn_lshift(buf, buf, 20, 1);
10319     mpn_add_n(z, z, buf, 20);
10320 }
10321 #endif /* !defined(HAVE_native_mpfq_fixmp_10_sqr) */
10322 
10323 #if !defined(HAVE_native_mpfq_fixmp_10_mul1)
10324 /* x has 10 words, z has 12. Put x*y in z. */
10325 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
10326 static inline
mpfq_fixmp_10_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)10327 void mpfq_fixmp_10_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
10328 {
10329     mp_limb_t hi, lo, carry;
10330     carry = 0;
10331     mpfq_umul_ppmm(hi,lo,c,x[0]);
10332     lo += carry;
10333     carry = (lo<carry) + hi;
10334     z[0] = lo;
10335     mpfq_umul_ppmm(hi,lo,c,x[1]);
10336     lo += carry;
10337     carry = (lo<carry) + hi;
10338     z[1] = lo;
10339     mpfq_umul_ppmm(hi,lo,c,x[2]);
10340     lo += carry;
10341     carry = (lo<carry) + hi;
10342     z[2] = lo;
10343     mpfq_umul_ppmm(hi,lo,c,x[3]);
10344     lo += carry;
10345     carry = (lo<carry) + hi;
10346     z[3] = lo;
10347     mpfq_umul_ppmm(hi,lo,c,x[4]);
10348     lo += carry;
10349     carry = (lo<carry) + hi;
10350     z[4] = lo;
10351     mpfq_umul_ppmm(hi,lo,c,x[5]);
10352     lo += carry;
10353     carry = (lo<carry) + hi;
10354     z[5] = lo;
10355     mpfq_umul_ppmm(hi,lo,c,x[6]);
10356     lo += carry;
10357     carry = (lo<carry) + hi;
10358     z[6] = lo;
10359     mpfq_umul_ppmm(hi,lo,c,x[7]);
10360     lo += carry;
10361     carry = (lo<carry) + hi;
10362     z[7] = lo;
10363     mpfq_umul_ppmm(hi,lo,c,x[8]);
10364     lo += carry;
10365     carry = (lo<carry) + hi;
10366     z[8] = lo;
10367     mpfq_umul_ppmm(hi,lo,c,x[9]);
10368     lo += carry;
10369     carry = (lo<carry) + hi;
10370     z[9] = lo;
10371     z[10] = carry;
10372 }
10373 #endif /* !defined(HAVE_native_mpfq_fixmp_10_mul1) */
10374 
10375 #if !defined(HAVE_native_mpfq_fixmp_10_shortmul)
10376 /* x and y have 10 words, z has 11.
10377  * Put the low 11 words of x*y in z. */
10378 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
10379 static inline
mpfq_fixmp_10_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10380 void mpfq_fixmp_10_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10381 {
10382     mpfq_zero(z, 10);
10383     mpfq_fixmp_9_addmul1_nc (z+0, x, y[0]);
10384     z[10-1] += x[9]*y[0];
10385     mpfq_fixmp_8_addmul1_nc (z+1, x, y[1]);
10386     z[10-1] += x[8]*y[1];
10387     mpfq_fixmp_7_addmul1_nc (z+2, x, y[2]);
10388     z[10-1] += x[7]*y[2];
10389     mpfq_fixmp_6_addmul1_nc (z+3, x, y[3]);
10390     z[10-1] += x[6]*y[3];
10391     mpfq_fixmp_5_addmul1_nc (z+4, x, y[4]);
10392     z[10-1] += x[5]*y[4];
10393     mpfq_fixmp_4_addmul1_nc (z+5, x, y[5]);
10394     z[10-1] += x[4]*y[5];
10395     mpfq_fixmp_3_addmul1_nc (z+6, x, y[6]);
10396     z[10-1] += x[3]*y[6];
10397     mpfq_fixmp_2_addmul1_nc (z+7, x, y[7]);
10398     z[10-1] += x[2]*y[7];
10399     mpfq_fixmp_1_addmul1_nc (z+8, x, y[8]);
10400     z[10-1] += x[1]*y[8];
10401     z[10-1] += x[0]*y[10-1];
10402 }
10403 #endif /* !defined(HAVE_native_mpfq_fixmp_10_shortmul) */
10404 
10405 #if !defined(HAVE_native_mpfq_fixmp_10_mod)
10406 /* x has 22 words. z and p have 10 words, and the high word of p is non-zero.
10407  * Put x mod p in z. */
10408 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
10409 /* Triggered by: 10_mgy_decode */
10410 static inline
mpfq_fixmp_10_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)10411 void mpfq_fixmp_10_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
10412 {
10413     mp_limb_t q[10+1], r[10];
10414     assert (p[10-1] != 0);
10415     mpn_tdiv_qr(q, r, 0, x, 20, p, 10);
10416     mpfq_copy(z, r, 10);
10417 }
10418 #endif /* !defined(HAVE_native_mpfq_fixmp_10_mod) */
10419 
10420 #if !defined(HAVE_native_mpfq_fixmp_10_rshift)
10421 /* a has 10 words. Shift it in place by cnt bits to the right.
10422  * The shift count cnt must not exceed the word size.
10423  * Note that no carry is returned for the bits shifted out. */
10424 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
10425 /* Triggered by: 10_invmod */
10426 static inline
mpfq_fixmp_10_rshift(mp_limb_t * a,int cnt)10427 void mpfq_fixmp_10_rshift(mp_limb_t * a, int cnt)
10428 {
10429     if (!cnt) return;
10430     int i;
10431     int dnt = GMP_NUMB_BITS - cnt;
10432     for (i = 0; i < 10-1; ++i) {
10433         a[i] >>= cnt;
10434         a[i] |= (a[i+1] << dnt);
10435     }
10436     a[10-1] >>= cnt;
10437 }
10438 #endif /* !defined(HAVE_native_mpfq_fixmp_10_rshift) */
10439 
10440 #if !defined(HAVE_native_mpfq_fixmp_10_long_rshift)
10441 /* a has 10 words. Shift it in place by off words plus cnt bits to the left.
10442  * Note that no carry is returned for the bits shifted out. */
10443 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
10444 /* Triggered by: 10_invmod */
10445 static inline
mpfq_fixmp_10_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)10446 void mpfq_fixmp_10_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
10447 {
10448     if (cnt) {
10449         int dnt = GMP_NUMB_BITS - cnt;
10450         for (int i = 0; i < 10 - off - 1; ++i) {
10451             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
10452         }
10453         a[10-off-1] = a[10-1]>>cnt;
10454     } else {
10455         mpfq_copyi(a, a + off, 10 - off);
10456     }
10457     mpfq_zero(a + 10 - off, off);
10458 }
10459 #endif /* !defined(HAVE_native_mpfq_fixmp_10_long_rshift) */
10460 
10461 #if !defined(HAVE_native_mpfq_fixmp_10_long_lshift)
10462 /* a has 10 words. Shift it in place by off words plus cnt bits to the left.
10463  * Note that no carry is returned for the bits shifted out. */
10464 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
10465 /* Triggered by: 10_invmod */
10466 static inline
mpfq_fixmp_10_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)10467 void mpfq_fixmp_10_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
10468 {
10469     int i;
10470     if (cnt) {
10471         int dnt = GMP_NUMB_BITS - cnt;
10472         for (i = 10-1; i>off; --i) {
10473             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
10474         }
10475         a[off] = a[0]<<cnt;
10476     } else {
10477         mpfq_copyd(a + off, a, 10 - off);
10478     }
10479     mpfq_zero(a, off);
10480 }
10481 #endif /* !defined(HAVE_native_mpfq_fixmp_10_long_lshift) */
10482 
10483 #if !defined(HAVE_native_mpfq_fixmp_10_invmod)
10484 /* x, z, and p have 10 words. Put inverse of x mod p in z.
10485  * Return non-zero if an inverse could be found.
10486  * If no inverse could be found, return 0 and set z to zero.
10487  */
10488 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
10489 static inline
mpfq_fixmp_10_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)10490 int mpfq_fixmp_10_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
10491 {
10492       mp_limb_t u[10], v[10], a[10], b[10], fix[10];
10493       int i, t, lsh;
10494 
10495       mpfq_zero(u, 10);
10496       mpfq_zero(v, 10);
10497       mpfq_copy(a, x, 10);
10498       mpfq_copy(b, p, 10);
10499       u[0] = 1UL;
10500 
10501       if (mpfq_fixmp_10_cmp(a, v) == 0 || mpfq_fixmp_10_cmp(a, b) == 0) {
10502         mpfq_zero(res, 10);
10503         return 0;
10504       }
10505 
10506       mpfq_fixmp_10_add(fix, b, u);
10507       mpfq_fixmp_10_rshift(fix, 1);
10508 
10509       assert (mpfq_fixmp_10_cmp(a,b) < 0);
10510 
10511       t = 0;
10512 
10513       for(i = 0 ; !a[i] ; i++) ;
10514       assert (i < 10);
10515       lsh = mpfq_ctzl(a[i]);
10516       mpfq_fixmp_10_long_rshift(a, i, lsh);
10517       t += lsh + i*GMP_NUMB_BITS;
10518       mpfq_fixmp_10_long_lshift(v, i, lsh);
10519 
10520       do {
10521         do {
10522           mpfq_fixmp_10_sub(b, b, a);
10523           mpfq_fixmp_10_add(v, v, u);
10524           for(i = 0 ; !b[i] ; i++) ;
10525           assert (i < 10);
10526           lsh = mpfq_ctzl(b[i]);
10527           mpfq_fixmp_10_long_rshift(b, i, lsh);
10528           t += lsh + i*GMP_NUMB_BITS;
10529           mpfq_fixmp_10_long_lshift(u, i, lsh);
10530         } while (mpfq_fixmp_10_cmp(a,b) < 0);
10531         if (mpfq_fixmp_10_cmp(a, b) == 0)
10532           break;
10533         do {
10534           mpfq_fixmp_10_sub(a, a, b);
10535           mpfq_fixmp_10_add(u, u, v);
10536           for(i = 0 ; !a[i] ; i++) ;
10537           assert (i < 10);
10538           lsh = mpfq_ctzl(a[i]);
10539           mpfq_fixmp_10_long_rshift(a, i, lsh);
10540           t += lsh + i*GMP_NUMB_BITS;
10541           mpfq_fixmp_10_long_lshift(v, i, lsh);
10542         } while (mpfq_fixmp_10_cmp(b,a)<0);
10543       } while (mpfq_fixmp_10_cmp(a,b) != 0);
10544       {
10545         if (mpfq_fixmp_10_cmp_ui(a, 1) != 0) {
10546           mpfq_copy(res, a, 10);
10547           return 0;
10548         }
10549       }
10550       while (t>0) {
10551         mp_limb_t sig = u[0] & 1UL;
10552         mpfq_fixmp_10_rshift(u, 1);
10553         if (sig)
10554           mpfq_fixmp_10_add(u, u, fix);
10555         --t;
10556       }
10557       mpfq_copy(res, u, 10);
10558       return 1;
10559 }
10560 #endif /* !defined(HAVE_native_mpfq_fixmp_10_invmod) */
10561 
10562 #if !defined(HAVE_native_mpfq_fixmp_10_redc)
10563 /* x has 22 words, z and p have 10 words.
10564  * only one word is read from invp.
10565  * Assuming R=W^11 is the redc modulus, we expect that x verifies:
10566  *   x < R*p,
10567  * so that we have eventually z < p, z congruent to x/R mod p.
10568  * The contents of the area pointed by x are clobbered by this call.
10569  * Note also that x may alias z.
10570  */
10571 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
10572 static inline
mpfq_fixmp_10_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)10573 void mpfq_fixmp_10_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
10574 {
10575     mp_limb_t cy;
10576     for(int i = 0; i < 10; ++i) {
10577         mp_limb_t t = x[i]*mip[0];
10578         cy = mpfq_fixmp_10_addmul1_shortz(x+i, p, t);
10579         assert (x[i] == 0);
10580         x[i] = cy;
10581     }
10582     cy = mpfq_fixmp_10_add(x, x, x + 10);
10583     /* At this point, we have (x' denotes x + cy*W^n here)
10584     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
10585     * x'/R < p + p
10586     */
10587     if (cy || mpfq_fixmp_10_cmp(x, p) >= 0) {
10588         mpfq_fixmp_10_sub(z, x, p);
10589     } else {
10590         mpfq_copy(z, x, 10);
10591     }
10592 }
10593 #endif /* !defined(HAVE_native_mpfq_fixmp_10_redc) */
10594 
10595 #if !defined(HAVE_native_mpfq_fixmp_10_redc_ur)
10596 /* x has 23 words, z and p have 10 words.
10597  * only one word is read from invp.
10598  * Assuming R=W^11 is the redc modulus, we expect that x verifies:
10599  *  x < W*W^10*p = W^0.5*R*p or the hw case, W*R*p otherwise,
10600  * so that we have eventually z < p, z congruent to x/R mod p.
10601  * The contents of the area pointed by x are clobbered by this call.
10602  * Note also that x may alias z.
10603  */
10604 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
10605 static inline
mpfq_fixmp_10_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)10606 void mpfq_fixmp_10_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
10607 {
10608     mp_limb_t cy, q[2];
10609     for (int i = 0; i < 10; ++i) {
10610         mp_limb_t t = x[i]*mip[0];
10611         cy = mpfq_fixmp_10_addmul1(x+i, p, t);
10612         assert (x[i] == 0);
10613         x[i] = cy;
10614     }
10615     cy=mpfq_fixmp_10_add(x+10+1, x+10+1, x);
10616     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
10617     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
10618     * x'/R < (W+1)*p
10619     */
10620     if (cy) {
10621         /* x'/R-p < W*p, which fits in n+1 words */
10622         mpn_sub(x+10,x+10,10+1,p,10);
10623     }
10624     mpn_tdiv_qr(q, z, 0, x+10, 10+1, p, 10);
10625 }
10626 #endif /* !defined(HAVE_native_mpfq_fixmp_10_redc_ur) */
10627 
10628 #if !defined(HAVE_native_mpfq_fixmp_10_mgy_encode)
10629 /* x, z, and p have 10 words.
10630  * Assuming R=W^11 is the redc modulus, we compute z=R*x mod p. */
10631 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
10632 static inline
mpfq_fixmp_10_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)10633 void mpfq_fixmp_10_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
10634 {
10635     mp_limb_t t[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9] };
10636     mpfq_fixmp_10_mod(z, t, p);
10637 }
10638 #endif /* !defined(HAVE_native_mpfq_fixmp_10_mgy_encode) */
10639 
10640 #if !defined(HAVE_native_mpfq_fixmp_10_mgy_decode)
10641 /* x, z, invR, and p have 10 words.
10642  * Assuming R=W^11 is the redc modulus, we compute z=x/R mod p. */
10643 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
10644 static inline
mpfq_fixmp_10_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)10645 void mpfq_fixmp_10_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
10646 {
10647     mp_limb_t t[20];
10648     mpfq_fixmp_10_mul(t, x, invR);
10649     mpfq_fixmp_10_mod(z, t, p);
10650 }
10651 #endif /* !defined(HAVE_native_mpfq_fixmp_10_mgy_decode) */
10652 
10653 #if !defined(HAVE_native_mpfq_fixmp_10_lshift)
10654 /* a has 10 words. Shift it in place by cnt bits to the left.
10655  * The shift count cnt must not exceed the word size.
10656  * Note that no carry is returned for the bits shifted out. */
10657 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
10658 static inline
mpfq_fixmp_10_lshift(mp_limb_t * a,int cnt)10659 void mpfq_fixmp_10_lshift(mp_limb_t * a, int cnt)
10660 {
10661     if (!cnt) return;
10662     int i;
10663     int dnt = GMP_NUMB_BITS - cnt;
10664     for (i = 10-1; i>0; --i) {
10665         a[i] <<= cnt;
10666         a[i] |= (a[i-1] >> dnt);
10667     }
10668     a[0] <<= cnt;
10669 }
10670 #endif /* !defined(HAVE_native_mpfq_fixmp_10_lshift) */
10671 
10672 #if !defined(HAVE_native_mpfq_fixmp_11_add)
10673 /* x, y, and z have 11 words. Result in z. Return carry bit */
10674 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
10675 /* Triggered by: 11_invmod, 11_redc, 11_redc_ur */
10676 static inline
mpfq_fixmp_11_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10677 mp_limb_t mpfq_fixmp_11_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10678 {
10679     mp_limb_t r, s, t, cy, cy1, cy2;
10680     cy = 0;
10681     r = x[0];
10682     s = r + y[0];
10683     cy1 = s < r;
10684     t = s + cy;
10685     cy2 = t < s;
10686     cy = cy1 | cy2;
10687     z[0] = t;
10688     r = x[1];
10689     s = r + y[1];
10690     cy1 = s < r;
10691     t = s + cy;
10692     cy2 = t < s;
10693     cy = cy1 | cy2;
10694     z[1] = t;
10695     r = x[2];
10696     s = r + y[2];
10697     cy1 = s < r;
10698     t = s + cy;
10699     cy2 = t < s;
10700     cy = cy1 | cy2;
10701     z[2] = t;
10702     r = x[3];
10703     s = r + y[3];
10704     cy1 = s < r;
10705     t = s + cy;
10706     cy2 = t < s;
10707     cy = cy1 | cy2;
10708     z[3] = t;
10709     r = x[4];
10710     s = r + y[4];
10711     cy1 = s < r;
10712     t = s + cy;
10713     cy2 = t < s;
10714     cy = cy1 | cy2;
10715     z[4] = t;
10716     r = x[5];
10717     s = r + y[5];
10718     cy1 = s < r;
10719     t = s + cy;
10720     cy2 = t < s;
10721     cy = cy1 | cy2;
10722     z[5] = t;
10723     r = x[6];
10724     s = r + y[6];
10725     cy1 = s < r;
10726     t = s + cy;
10727     cy2 = t < s;
10728     cy = cy1 | cy2;
10729     z[6] = t;
10730     r = x[7];
10731     s = r + y[7];
10732     cy1 = s < r;
10733     t = s + cy;
10734     cy2 = t < s;
10735     cy = cy1 | cy2;
10736     z[7] = t;
10737     r = x[8];
10738     s = r + y[8];
10739     cy1 = s < r;
10740     t = s + cy;
10741     cy2 = t < s;
10742     cy = cy1 | cy2;
10743     z[8] = t;
10744     r = x[9];
10745     s = r + y[9];
10746     cy1 = s < r;
10747     t = s + cy;
10748     cy2 = t < s;
10749     cy = cy1 | cy2;
10750     z[9] = t;
10751     r = x[10];
10752     s = r + y[10];
10753     cy1 = s < r;
10754     t = s + cy;
10755     cy2 = t < s;
10756     cy = cy1 | cy2;
10757     z[10] = t;
10758     return cy;
10759 }
10760 #endif /* !defined(HAVE_native_mpfq_fixmp_11_add) */
10761 
10762 #if !defined(HAVE_native_mpfq_fixmp_11_sub)
10763 /* x, y, and z have 11 words. Result in z. Return borrow bit */
10764 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
10765 /* Triggered by: 11_invmod, 11_redc */
10766 static inline
mpfq_fixmp_11_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10767 mp_limb_t mpfq_fixmp_11_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10768 {
10769     mp_limb_t r, s, t, cy, cy1, cy2;
10770     cy = 0;
10771     r = x[0];
10772     s = r - y[0];
10773     cy1 = s > r;
10774     t = s - cy;
10775     cy2 = t > s;
10776     cy = cy1 | cy2;
10777     z[0] = t;
10778     r = x[1];
10779     s = r - y[1];
10780     cy1 = s > r;
10781     t = s - cy;
10782     cy2 = t > s;
10783     cy = cy1 | cy2;
10784     z[1] = t;
10785     r = x[2];
10786     s = r - y[2];
10787     cy1 = s > r;
10788     t = s - cy;
10789     cy2 = t > s;
10790     cy = cy1 | cy2;
10791     z[2] = t;
10792     r = x[3];
10793     s = r - y[3];
10794     cy1 = s > r;
10795     t = s - cy;
10796     cy2 = t > s;
10797     cy = cy1 | cy2;
10798     z[3] = t;
10799     r = x[4];
10800     s = r - y[4];
10801     cy1 = s > r;
10802     t = s - cy;
10803     cy2 = t > s;
10804     cy = cy1 | cy2;
10805     z[4] = t;
10806     r = x[5];
10807     s = r - y[5];
10808     cy1 = s > r;
10809     t = s - cy;
10810     cy2 = t > s;
10811     cy = cy1 | cy2;
10812     z[5] = t;
10813     r = x[6];
10814     s = r - y[6];
10815     cy1 = s > r;
10816     t = s - cy;
10817     cy2 = t > s;
10818     cy = cy1 | cy2;
10819     z[6] = t;
10820     r = x[7];
10821     s = r - y[7];
10822     cy1 = s > r;
10823     t = s - cy;
10824     cy2 = t > s;
10825     cy = cy1 | cy2;
10826     z[7] = t;
10827     r = x[8];
10828     s = r - y[8];
10829     cy1 = s > r;
10830     t = s - cy;
10831     cy2 = t > s;
10832     cy = cy1 | cy2;
10833     z[8] = t;
10834     r = x[9];
10835     s = r - y[9];
10836     cy1 = s > r;
10837     t = s - cy;
10838     cy2 = t > s;
10839     cy = cy1 | cy2;
10840     z[9] = t;
10841     r = x[10];
10842     s = r - y[10];
10843     cy1 = s > r;
10844     t = s - cy;
10845     cy2 = t > s;
10846     cy = cy1 | cy2;
10847     z[10] = t;
10848     return cy;
10849 }
10850 #endif /* !defined(HAVE_native_mpfq_fixmp_11_sub) */
10851 
10852 #if !defined(HAVE_native_mpfq_fixmp_11_add_nc)
10853 /* x, y, and z have 11 words. Result in z. Carry bit is lost. */
10854 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
10855 static inline
mpfq_fixmp_11_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10856 void mpfq_fixmp_11_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10857 {
10858     mp_limb_t r, s, t, cy, cy1, cy2;
10859     cy = 0;
10860     r = x[0];
10861     s = r + y[0];
10862     cy1 = s < r;
10863     t = s + cy;
10864     cy2 = t < s;
10865     cy = cy1 | cy2;
10866     z[0] = t;
10867     r = x[1];
10868     s = r + y[1];
10869     cy1 = s < r;
10870     t = s + cy;
10871     cy2 = t < s;
10872     cy = cy1 | cy2;
10873     z[1] = t;
10874     r = x[2];
10875     s = r + y[2];
10876     cy1 = s < r;
10877     t = s + cy;
10878     cy2 = t < s;
10879     cy = cy1 | cy2;
10880     z[2] = t;
10881     r = x[3];
10882     s = r + y[3];
10883     cy1 = s < r;
10884     t = s + cy;
10885     cy2 = t < s;
10886     cy = cy1 | cy2;
10887     z[3] = t;
10888     r = x[4];
10889     s = r + y[4];
10890     cy1 = s < r;
10891     t = s + cy;
10892     cy2 = t < s;
10893     cy = cy1 | cy2;
10894     z[4] = t;
10895     r = x[5];
10896     s = r + y[5];
10897     cy1 = s < r;
10898     t = s + cy;
10899     cy2 = t < s;
10900     cy = cy1 | cy2;
10901     z[5] = t;
10902     r = x[6];
10903     s = r + y[6];
10904     cy1 = s < r;
10905     t = s + cy;
10906     cy2 = t < s;
10907     cy = cy1 | cy2;
10908     z[6] = t;
10909     r = x[7];
10910     s = r + y[7];
10911     cy1 = s < r;
10912     t = s + cy;
10913     cy2 = t < s;
10914     cy = cy1 | cy2;
10915     z[7] = t;
10916     r = x[8];
10917     s = r + y[8];
10918     cy1 = s < r;
10919     t = s + cy;
10920     cy2 = t < s;
10921     cy = cy1 | cy2;
10922     z[8] = t;
10923     r = x[9];
10924     s = r + y[9];
10925     cy1 = s < r;
10926     t = s + cy;
10927     cy2 = t < s;
10928     cy = cy1 | cy2;
10929     z[9] = t;
10930     r = x[10];
10931     s = r + y[10];
10932     cy1 = s < r;
10933     t = s + cy;
10934     cy2 = t < s;
10935     cy = cy1 | cy2;
10936     z[10] = t;
10937 }
10938 #endif /* !defined(HAVE_native_mpfq_fixmp_11_add_nc) */
10939 
10940 #if !defined(HAVE_native_mpfq_fixmp_11_sub_nc)
10941 /* x, y, and z have 11 words. Result in z. Borrow bit is lost. */
10942 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
10943 static inline
mpfq_fixmp_11_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)10944 void mpfq_fixmp_11_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
10945 {
10946     mp_limb_t r, s, t, cy, cy1, cy2;
10947     cy = 0;
10948     r = x[0];
10949     s = r - y[0];
10950     cy1 = s > r;
10951     t = s - cy;
10952     cy2 = t > s;
10953     cy = cy1 | cy2;
10954     z[0] = t;
10955     r = x[1];
10956     s = r - y[1];
10957     cy1 = s > r;
10958     t = s - cy;
10959     cy2 = t > s;
10960     cy = cy1 | cy2;
10961     z[1] = t;
10962     r = x[2];
10963     s = r - y[2];
10964     cy1 = s > r;
10965     t = s - cy;
10966     cy2 = t > s;
10967     cy = cy1 | cy2;
10968     z[2] = t;
10969     r = x[3];
10970     s = r - y[3];
10971     cy1 = s > r;
10972     t = s - cy;
10973     cy2 = t > s;
10974     cy = cy1 | cy2;
10975     z[3] = t;
10976     r = x[4];
10977     s = r - y[4];
10978     cy1 = s > r;
10979     t = s - cy;
10980     cy2 = t > s;
10981     cy = cy1 | cy2;
10982     z[4] = t;
10983     r = x[5];
10984     s = r - y[5];
10985     cy1 = s > r;
10986     t = s - cy;
10987     cy2 = t > s;
10988     cy = cy1 | cy2;
10989     z[5] = t;
10990     r = x[6];
10991     s = r - y[6];
10992     cy1 = s > r;
10993     t = s - cy;
10994     cy2 = t > s;
10995     cy = cy1 | cy2;
10996     z[6] = t;
10997     r = x[7];
10998     s = r - y[7];
10999     cy1 = s > r;
11000     t = s - cy;
11001     cy2 = t > s;
11002     cy = cy1 | cy2;
11003     z[7] = t;
11004     r = x[8];
11005     s = r - y[8];
11006     cy1 = s > r;
11007     t = s - cy;
11008     cy2 = t > s;
11009     cy = cy1 | cy2;
11010     z[8] = t;
11011     r = x[9];
11012     s = r - y[9];
11013     cy1 = s > r;
11014     t = s - cy;
11015     cy2 = t > s;
11016     cy = cy1 | cy2;
11017     z[9] = t;
11018     r = x[10];
11019     s = r - y[10];
11020     cy1 = s > r;
11021     t = s - cy;
11022     cy2 = t > s;
11023     cy = cy1 | cy2;
11024     z[10] = t;
11025 }
11026 #endif /* !defined(HAVE_native_mpfq_fixmp_11_sub_nc) */
11027 
11028 #if !defined(HAVE_native_mpfq_fixmp_11_add_ui)
11029 /* x, y, and z have 11 words. Result in z. Return carry bit */
11030 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
11031 static inline
mpfq_fixmp_11_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)11032 mp_limb_t mpfq_fixmp_11_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
11033 {
11034     mp_limb_t r, s, t, cy, cy1, cy2;
11035     cy = 0;
11036     r = x[0];
11037     s = r + y;
11038     cy1 = s < r;
11039     t = s + cy;
11040     cy2 = t < s;
11041     cy = cy1 | cy2;
11042     z[0] = t;
11043     s = x[1];
11044     t = s + cy;
11045     cy = t < s;
11046     z[1] = t;
11047     s = x[2];
11048     t = s + cy;
11049     cy = t < s;
11050     z[2] = t;
11051     s = x[3];
11052     t = s + cy;
11053     cy = t < s;
11054     z[3] = t;
11055     s = x[4];
11056     t = s + cy;
11057     cy = t < s;
11058     z[4] = t;
11059     s = x[5];
11060     t = s + cy;
11061     cy = t < s;
11062     z[5] = t;
11063     s = x[6];
11064     t = s + cy;
11065     cy = t < s;
11066     z[6] = t;
11067     s = x[7];
11068     t = s + cy;
11069     cy = t < s;
11070     z[7] = t;
11071     s = x[8];
11072     t = s + cy;
11073     cy = t < s;
11074     z[8] = t;
11075     s = x[9];
11076     t = s + cy;
11077     cy = t < s;
11078     z[9] = t;
11079     s = x[10];
11080     t = s + cy;
11081     cy = t < s;
11082     z[10] = t;
11083     return cy;
11084 }
11085 #endif /* !defined(HAVE_native_mpfq_fixmp_11_add_ui) */
11086 
11087 #if !defined(HAVE_native_mpfq_fixmp_11_sub_ui)
11088 /* x, y, and z have 11 words. Result in z. Return borrow bit */
11089 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
11090 static inline
mpfq_fixmp_11_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)11091 mp_limb_t mpfq_fixmp_11_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
11092 {
11093     mp_limb_t r, s, t, cy, cy1, cy2;
11094     cy = 0;
11095     r = x[0];
11096     s = r - y;
11097     cy1 = s > r;
11098     t = s - cy;
11099     cy2 = t > s;
11100     cy = cy1 | cy2;
11101     z[0] = t;
11102     s = x[1];
11103     t = s - cy;
11104     cy = t > s;
11105     z[1] = t;
11106     s = x[2];
11107     t = s - cy;
11108     cy = t > s;
11109     z[2] = t;
11110     s = x[3];
11111     t = s - cy;
11112     cy = t > s;
11113     z[3] = t;
11114     s = x[4];
11115     t = s - cy;
11116     cy = t > s;
11117     z[4] = t;
11118     s = x[5];
11119     t = s - cy;
11120     cy = t > s;
11121     z[5] = t;
11122     s = x[6];
11123     t = s - cy;
11124     cy = t > s;
11125     z[6] = t;
11126     s = x[7];
11127     t = s - cy;
11128     cy = t > s;
11129     z[7] = t;
11130     s = x[8];
11131     t = s - cy;
11132     cy = t > s;
11133     z[8] = t;
11134     s = x[9];
11135     t = s - cy;
11136     cy = t > s;
11137     z[9] = t;
11138     s = x[10];
11139     t = s - cy;
11140     cy = t > s;
11141     z[10] = t;
11142     return cy;
11143 }
11144 #endif /* !defined(HAVE_native_mpfq_fixmp_11_sub_ui) */
11145 
11146 #if !defined(HAVE_native_mpfq_fixmp_11_add_ui_nc)
11147 /* x, y, and z have 11 words. Result in z. Carry bit is lost. */
11148 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
11149 static inline
mpfq_fixmp_11_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)11150 void mpfq_fixmp_11_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
11151 {
11152     mp_limb_t r, s, t, cy, cy1, cy2;
11153     cy = 0;
11154     r = x[0];
11155     s = r + y;
11156     cy1 = s < r;
11157     t = s + cy;
11158     cy2 = t < s;
11159     cy = cy1 | cy2;
11160     z[0] = t;
11161     s = x[1];
11162     t = s + cy;
11163     cy = t < s;
11164     z[1] = t;
11165     s = x[2];
11166     t = s + cy;
11167     cy = t < s;
11168     z[2] = t;
11169     s = x[3];
11170     t = s + cy;
11171     cy = t < s;
11172     z[3] = t;
11173     s = x[4];
11174     t = s + cy;
11175     cy = t < s;
11176     z[4] = t;
11177     s = x[5];
11178     t = s + cy;
11179     cy = t < s;
11180     z[5] = t;
11181     s = x[6];
11182     t = s + cy;
11183     cy = t < s;
11184     z[6] = t;
11185     s = x[7];
11186     t = s + cy;
11187     cy = t < s;
11188     z[7] = t;
11189     s = x[8];
11190     t = s + cy;
11191     cy = t < s;
11192     z[8] = t;
11193     s = x[9];
11194     t = s + cy;
11195     cy = t < s;
11196     z[9] = t;
11197     s = x[10];
11198     t = s + cy;
11199     cy = t < s;
11200     z[10] = t;
11201 }
11202 #endif /* !defined(HAVE_native_mpfq_fixmp_11_add_ui_nc) */
11203 
11204 #if !defined(HAVE_native_mpfq_fixmp_11_sub_ui_nc)
11205 /* x, y, and z have 11 words. Result in z. Borrow bit is lost. */
11206 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
11207 static inline
mpfq_fixmp_11_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)11208 void mpfq_fixmp_11_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
11209 {
11210     mp_limb_t r, s, t, cy, cy1, cy2;
11211     cy = 0;
11212     r = x[0];
11213     s = r - y;
11214     cy1 = s > r;
11215     t = s - cy;
11216     cy2 = t > s;
11217     cy = cy1 | cy2;
11218     z[0] = t;
11219     s = x[1];
11220     t = s - cy;
11221     cy = t > s;
11222     z[1] = t;
11223     s = x[2];
11224     t = s - cy;
11225     cy = t > s;
11226     z[2] = t;
11227     s = x[3];
11228     t = s - cy;
11229     cy = t > s;
11230     z[3] = t;
11231     s = x[4];
11232     t = s - cy;
11233     cy = t > s;
11234     z[4] = t;
11235     s = x[5];
11236     t = s - cy;
11237     cy = t > s;
11238     z[5] = t;
11239     s = x[6];
11240     t = s - cy;
11241     cy = t > s;
11242     z[6] = t;
11243     s = x[7];
11244     t = s - cy;
11245     cy = t > s;
11246     z[7] = t;
11247     s = x[8];
11248     t = s - cy;
11249     cy = t > s;
11250     z[8] = t;
11251     s = x[9];
11252     t = s - cy;
11253     cy = t > s;
11254     z[9] = t;
11255     s = x[10];
11256     t = s - cy;
11257     cy = t > s;
11258     z[10] = t;
11259 }
11260 #endif /* !defined(HAVE_native_mpfq_fixmp_11_sub_ui_nc) */
11261 
11262 #if !defined(HAVE_native_mpfq_fixmp_11_cmp)
11263 /* x and y have 11 words. Return sign of difference x-y. */
11264 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
11265 /* Triggered by: 11_invmod, 11_redc */
11266 static inline
mpfq_fixmp_11_cmp(const mp_limb_t * x,const mp_limb_t * y)11267 int mpfq_fixmp_11_cmp(const mp_limb_t * x, const mp_limb_t * y)
11268 {
11269     for (int i = 11-1; i >= 0; --i) {
11270         if (x[i] > y[i]) return 1;
11271         if (x[i] < y[i]) return -1;
11272     }
11273     return 0;
11274 }
11275 #endif /* !defined(HAVE_native_mpfq_fixmp_11_cmp) */
11276 
11277 #if !defined(HAVE_native_mpfq_fixmp_11_cmp_ui)
11278 /* x has 11 words. Return sign of difference x-y. */
11279 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
11280 /* Triggered by: 11_invmod */
11281 static inline
mpfq_fixmp_11_cmp_ui(const mp_limb_t * x,mp_limb_t y)11282 int mpfq_fixmp_11_cmp_ui(const mp_limb_t * x, mp_limb_t y)
11283 {
11284     for (int i = 11-1; i > 0; --i) {
11285         if (x[i]) return 1;
11286     }
11287     if (x[0]>y) return 1;
11288     if (x[0]<y) return -1;
11289     return 0;
11290 }
11291 #endif /* !defined(HAVE_native_mpfq_fixmp_11_cmp_ui) */
11292 
11293 #if !defined(HAVE_native_mpfq_fixmp_11_addmul1)
11294 /* x has 11 words, z has 13.
11295  * Put (z+x*c) in z. Return carry bit. */
11296 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
11297 /* Triggered by: 11_redc_ur */
11298 static inline
mpfq_fixmp_11_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)11299 mp_limb_t mpfq_fixmp_11_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
11300 {
11301     mp_limb_t hi, lo, carry, buf;
11302     carry = 0;
11303     mpfq_umul_ppmm(hi,lo,c,x[0]);
11304     lo += carry;
11305     carry = (lo<carry) + hi;
11306     buf = z[0];
11307     lo += buf;
11308     carry += (lo<buf);
11309     z[0] = lo;
11310     mpfq_umul_ppmm(hi,lo,c,x[1]);
11311     lo += carry;
11312     carry = (lo<carry) + hi;
11313     buf = z[1];
11314     lo += buf;
11315     carry += (lo<buf);
11316     z[1] = lo;
11317     mpfq_umul_ppmm(hi,lo,c,x[2]);
11318     lo += carry;
11319     carry = (lo<carry) + hi;
11320     buf = z[2];
11321     lo += buf;
11322     carry += (lo<buf);
11323     z[2] = lo;
11324     mpfq_umul_ppmm(hi,lo,c,x[3]);
11325     lo += carry;
11326     carry = (lo<carry) + hi;
11327     buf = z[3];
11328     lo += buf;
11329     carry += (lo<buf);
11330     z[3] = lo;
11331     mpfq_umul_ppmm(hi,lo,c,x[4]);
11332     lo += carry;
11333     carry = (lo<carry) + hi;
11334     buf = z[4];
11335     lo += buf;
11336     carry += (lo<buf);
11337     z[4] = lo;
11338     mpfq_umul_ppmm(hi,lo,c,x[5]);
11339     lo += carry;
11340     carry = (lo<carry) + hi;
11341     buf = z[5];
11342     lo += buf;
11343     carry += (lo<buf);
11344     z[5] = lo;
11345     mpfq_umul_ppmm(hi,lo,c,x[6]);
11346     lo += carry;
11347     carry = (lo<carry) + hi;
11348     buf = z[6];
11349     lo += buf;
11350     carry += (lo<buf);
11351     z[6] = lo;
11352     mpfq_umul_ppmm(hi,lo,c,x[7]);
11353     lo += carry;
11354     carry = (lo<carry) + hi;
11355     buf = z[7];
11356     lo += buf;
11357     carry += (lo<buf);
11358     z[7] = lo;
11359     mpfq_umul_ppmm(hi,lo,c,x[8]);
11360     lo += carry;
11361     carry = (lo<carry) + hi;
11362     buf = z[8];
11363     lo += buf;
11364     carry += (lo<buf);
11365     z[8] = lo;
11366     mpfq_umul_ppmm(hi,lo,c,x[9]);
11367     lo += carry;
11368     carry = (lo<carry) + hi;
11369     buf = z[9];
11370     lo += buf;
11371     carry += (lo<buf);
11372     z[9] = lo;
11373     mpfq_umul_ppmm(hi,lo,c,x[10]);
11374     lo += carry;
11375     carry = (lo<carry) + hi;
11376     buf = z[10];
11377     lo += buf;
11378     carry += (lo<buf);
11379     z[10] = lo;
11380     z[11] += carry;
11381     return (z[11]<carry);
11382 }
11383 #endif /* !defined(HAVE_native_mpfq_fixmp_11_addmul1) */
11384 
11385 #if !defined(HAVE_native_mpfq_fixmp_11_addmul1_nc)
11386 /* x has 11 words, z has 13.
11387  * Put (z+x*c) in z. Carry bit is lost. */
11388 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
11389 /* Triggered by: 11_mul, 11_mgy_decode, 12_sqr, 12_shortmul, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 11_5_sqr, 11_5_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
11390 static inline
mpfq_fixmp_11_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)11391 void mpfq_fixmp_11_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
11392 {
11393     mp_limb_t hi, lo, carry, buf;
11394     carry = 0;
11395     mpfq_umul_ppmm(hi,lo,c,x[0]);
11396     lo += carry;
11397     carry = (lo<carry) + hi;
11398     buf = z[0];
11399     lo += buf;
11400     carry += (lo<buf);
11401     z[0] = lo;
11402     mpfq_umul_ppmm(hi,lo,c,x[1]);
11403     lo += carry;
11404     carry = (lo<carry) + hi;
11405     buf = z[1];
11406     lo += buf;
11407     carry += (lo<buf);
11408     z[1] = lo;
11409     mpfq_umul_ppmm(hi,lo,c,x[2]);
11410     lo += carry;
11411     carry = (lo<carry) + hi;
11412     buf = z[2];
11413     lo += buf;
11414     carry += (lo<buf);
11415     z[2] = lo;
11416     mpfq_umul_ppmm(hi,lo,c,x[3]);
11417     lo += carry;
11418     carry = (lo<carry) + hi;
11419     buf = z[3];
11420     lo += buf;
11421     carry += (lo<buf);
11422     z[3] = lo;
11423     mpfq_umul_ppmm(hi,lo,c,x[4]);
11424     lo += carry;
11425     carry = (lo<carry) + hi;
11426     buf = z[4];
11427     lo += buf;
11428     carry += (lo<buf);
11429     z[4] = lo;
11430     mpfq_umul_ppmm(hi,lo,c,x[5]);
11431     lo += carry;
11432     carry = (lo<carry) + hi;
11433     buf = z[5];
11434     lo += buf;
11435     carry += (lo<buf);
11436     z[5] = lo;
11437     mpfq_umul_ppmm(hi,lo,c,x[6]);
11438     lo += carry;
11439     carry = (lo<carry) + hi;
11440     buf = z[6];
11441     lo += buf;
11442     carry += (lo<buf);
11443     z[6] = lo;
11444     mpfq_umul_ppmm(hi,lo,c,x[7]);
11445     lo += carry;
11446     carry = (lo<carry) + hi;
11447     buf = z[7];
11448     lo += buf;
11449     carry += (lo<buf);
11450     z[7] = lo;
11451     mpfq_umul_ppmm(hi,lo,c,x[8]);
11452     lo += carry;
11453     carry = (lo<carry) + hi;
11454     buf = z[8];
11455     lo += buf;
11456     carry += (lo<buf);
11457     z[8] = lo;
11458     mpfq_umul_ppmm(hi,lo,c,x[9]);
11459     lo += carry;
11460     carry = (lo<carry) + hi;
11461     buf = z[9];
11462     lo += buf;
11463     carry += (lo<buf);
11464     z[9] = lo;
11465     mpfq_umul_ppmm(hi,lo,c,x[10]);
11466     lo += carry;
11467     carry = (lo<carry) + hi;
11468     buf = z[10];
11469     lo += buf;
11470     carry += (lo<buf);
11471     z[10] = lo;
11472     z[11] += carry;
11473 }
11474 #endif /* !defined(HAVE_native_mpfq_fixmp_11_addmul1_nc) */
11475 
11476 #if !defined(HAVE_native_mpfq_fixmp_11_addmul1_shortz)
11477 /* x has 11 words, z has 12.
11478  * Put (z+x*c) in z. Return carry word. */
11479 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
11480 /* Triggered by: 11_redc */
11481 static inline
mpfq_fixmp_11_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)11482 mp_limb_t mpfq_fixmp_11_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
11483 {
11484     mp_limb_t hi, lo, carry, buf;
11485     carry = 0;
11486     mpfq_umul_ppmm(hi,lo,c,x[0]);
11487     lo += carry;
11488     carry = (lo<carry) + hi;
11489     buf = z[0];
11490     lo += buf;
11491     carry += (lo<buf);
11492     z[0] = lo;
11493     mpfq_umul_ppmm(hi,lo,c,x[1]);
11494     lo += carry;
11495     carry = (lo<carry) + hi;
11496     buf = z[1];
11497     lo += buf;
11498     carry += (lo<buf);
11499     z[1] = lo;
11500     mpfq_umul_ppmm(hi,lo,c,x[2]);
11501     lo += carry;
11502     carry = (lo<carry) + hi;
11503     buf = z[2];
11504     lo += buf;
11505     carry += (lo<buf);
11506     z[2] = lo;
11507     mpfq_umul_ppmm(hi,lo,c,x[3]);
11508     lo += carry;
11509     carry = (lo<carry) + hi;
11510     buf = z[3];
11511     lo += buf;
11512     carry += (lo<buf);
11513     z[3] = lo;
11514     mpfq_umul_ppmm(hi,lo,c,x[4]);
11515     lo += carry;
11516     carry = (lo<carry) + hi;
11517     buf = z[4];
11518     lo += buf;
11519     carry += (lo<buf);
11520     z[4] = lo;
11521     mpfq_umul_ppmm(hi,lo,c,x[5]);
11522     lo += carry;
11523     carry = (lo<carry) + hi;
11524     buf = z[5];
11525     lo += buf;
11526     carry += (lo<buf);
11527     z[5] = lo;
11528     mpfq_umul_ppmm(hi,lo,c,x[6]);
11529     lo += carry;
11530     carry = (lo<carry) + hi;
11531     buf = z[6];
11532     lo += buf;
11533     carry += (lo<buf);
11534     z[6] = lo;
11535     mpfq_umul_ppmm(hi,lo,c,x[7]);
11536     lo += carry;
11537     carry = (lo<carry) + hi;
11538     buf = z[7];
11539     lo += buf;
11540     carry += (lo<buf);
11541     z[7] = lo;
11542     mpfq_umul_ppmm(hi,lo,c,x[8]);
11543     lo += carry;
11544     carry = (lo<carry) + hi;
11545     buf = z[8];
11546     lo += buf;
11547     carry += (lo<buf);
11548     z[8] = lo;
11549     mpfq_umul_ppmm(hi,lo,c,x[9]);
11550     lo += carry;
11551     carry = (lo<carry) + hi;
11552     buf = z[9];
11553     lo += buf;
11554     carry += (lo<buf);
11555     z[9] = lo;
11556     mpfq_umul_ppmm(hi,lo,c,x[10]);
11557     lo += carry;
11558     carry = (lo<carry) + hi;
11559     buf = z[10];
11560     lo += buf;
11561     carry += (lo<buf);
11562     z[10] = lo;
11563     return carry;
11564 }
11565 #endif /* !defined(HAVE_native_mpfq_fixmp_11_addmul1_shortz) */
11566 
11567 #if !defined(HAVE_native_mpfq_fixmp_11_mul)
11568 /* x and y have 11 words, z has 24. Put x*y in z. */
11569 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
11570 /* Triggered by: 11_mgy_decode */
11571 static inline
mpfq_fixmp_11_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)11572 void mpfq_fixmp_11_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
11573 {
11574     assert(z != x && z != y);
11575     for (int i = 0; i < 22; z[i++] = 0) ;
11576     mpfq_fixmp_11_addmul1_nc (z + 0, x, y[0]);
11577     mpfq_fixmp_11_addmul1_nc (z + 1, x, y[1]);
11578     mpfq_fixmp_11_addmul1_nc (z + 2, x, y[2]);
11579     mpfq_fixmp_11_addmul1_nc (z + 3, x, y[3]);
11580     mpfq_fixmp_11_addmul1_nc (z + 4, x, y[4]);
11581     mpfq_fixmp_11_addmul1_nc (z + 5, x, y[5]);
11582     mpfq_fixmp_11_addmul1_nc (z + 6, x, y[6]);
11583     mpfq_fixmp_11_addmul1_nc (z + 7, x, y[7]);
11584     mpfq_fixmp_11_addmul1_nc (z + 8, x, y[8]);
11585     mpfq_fixmp_11_addmul1_nc (z + 9, x, y[9]);
11586     mpfq_fixmp_11_addmul1_nc (z + 10, x, y[10]);
11587 }
11588 #endif /* !defined(HAVE_native_mpfq_fixmp_11_mul) */
11589 
11590 #if !defined(HAVE_native_mpfq_fixmp_11_sqr)
11591 /* x has 11 words, z has 24. Put x*y in z. */
11592 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
11593 static inline
mpfq_fixmp_11_sqr(mp_limb_t * z,const mp_limb_t * x)11594 void mpfq_fixmp_11_sqr(mp_limb_t * z, const mp_limb_t * x)
11595 {
11596     mp_limb_t buf[22] = {0,};
11597     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
11598     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
11599     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
11600     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
11601     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
11602     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
11603     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
11604     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
11605     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
11606     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
11607     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
11608     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
11609     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
11610     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
11611     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
11612     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
11613     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
11614     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
11615     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
11616     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
11617     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
11618     mpn_lshift(buf, buf, 22, 1);
11619     mpn_add_n(z, z, buf, 22);
11620 }
11621 #endif /* !defined(HAVE_native_mpfq_fixmp_11_sqr) */
11622 
11623 #if !defined(HAVE_native_mpfq_fixmp_11_mul1)
11624 /* x has 11 words, z has 13. Put x*y in z. */
11625 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
11626 static inline
mpfq_fixmp_11_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)11627 void mpfq_fixmp_11_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
11628 {
11629     mp_limb_t hi, lo, carry;
11630     carry = 0;
11631     mpfq_umul_ppmm(hi,lo,c,x[0]);
11632     lo += carry;
11633     carry = (lo<carry) + hi;
11634     z[0] = lo;
11635     mpfq_umul_ppmm(hi,lo,c,x[1]);
11636     lo += carry;
11637     carry = (lo<carry) + hi;
11638     z[1] = lo;
11639     mpfq_umul_ppmm(hi,lo,c,x[2]);
11640     lo += carry;
11641     carry = (lo<carry) + hi;
11642     z[2] = lo;
11643     mpfq_umul_ppmm(hi,lo,c,x[3]);
11644     lo += carry;
11645     carry = (lo<carry) + hi;
11646     z[3] = lo;
11647     mpfq_umul_ppmm(hi,lo,c,x[4]);
11648     lo += carry;
11649     carry = (lo<carry) + hi;
11650     z[4] = lo;
11651     mpfq_umul_ppmm(hi,lo,c,x[5]);
11652     lo += carry;
11653     carry = (lo<carry) + hi;
11654     z[5] = lo;
11655     mpfq_umul_ppmm(hi,lo,c,x[6]);
11656     lo += carry;
11657     carry = (lo<carry) + hi;
11658     z[6] = lo;
11659     mpfq_umul_ppmm(hi,lo,c,x[7]);
11660     lo += carry;
11661     carry = (lo<carry) + hi;
11662     z[7] = lo;
11663     mpfq_umul_ppmm(hi,lo,c,x[8]);
11664     lo += carry;
11665     carry = (lo<carry) + hi;
11666     z[8] = lo;
11667     mpfq_umul_ppmm(hi,lo,c,x[9]);
11668     lo += carry;
11669     carry = (lo<carry) + hi;
11670     z[9] = lo;
11671     mpfq_umul_ppmm(hi,lo,c,x[10]);
11672     lo += carry;
11673     carry = (lo<carry) + hi;
11674     z[10] = lo;
11675     z[11] = carry;
11676 }
11677 #endif /* !defined(HAVE_native_mpfq_fixmp_11_mul1) */
11678 
11679 #if !defined(HAVE_native_mpfq_fixmp_11_shortmul)
11680 /* x and y have 11 words, z has 12.
11681  * Put the low 12 words of x*y in z. */
11682 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
11683 static inline
mpfq_fixmp_11_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)11684 void mpfq_fixmp_11_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
11685 {
11686     mpfq_zero(z, 11);
11687     mpfq_fixmp_10_addmul1_nc (z+0, x, y[0]);
11688     z[11-1] += x[10]*y[0];
11689     mpfq_fixmp_9_addmul1_nc (z+1, x, y[1]);
11690     z[11-1] += x[9]*y[1];
11691     mpfq_fixmp_8_addmul1_nc (z+2, x, y[2]);
11692     z[11-1] += x[8]*y[2];
11693     mpfq_fixmp_7_addmul1_nc (z+3, x, y[3]);
11694     z[11-1] += x[7]*y[3];
11695     mpfq_fixmp_6_addmul1_nc (z+4, x, y[4]);
11696     z[11-1] += x[6]*y[4];
11697     mpfq_fixmp_5_addmul1_nc (z+5, x, y[5]);
11698     z[11-1] += x[5]*y[5];
11699     mpfq_fixmp_4_addmul1_nc (z+6, x, y[6]);
11700     z[11-1] += x[4]*y[6];
11701     mpfq_fixmp_3_addmul1_nc (z+7, x, y[7]);
11702     z[11-1] += x[3]*y[7];
11703     mpfq_fixmp_2_addmul1_nc (z+8, x, y[8]);
11704     z[11-1] += x[2]*y[8];
11705     mpfq_fixmp_1_addmul1_nc (z+9, x, y[9]);
11706     z[11-1] += x[1]*y[9];
11707     z[11-1] += x[0]*y[11-1];
11708 }
11709 #endif /* !defined(HAVE_native_mpfq_fixmp_11_shortmul) */
11710 
11711 #if !defined(HAVE_native_mpfq_fixmp_11_mod)
11712 /* x has 24 words. z and p have 11 words, and the high word of p is non-zero.
11713  * Put x mod p in z. */
11714 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
11715 /* Triggered by: 11_mgy_decode */
11716 static inline
mpfq_fixmp_11_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)11717 void mpfq_fixmp_11_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
11718 {
11719     mp_limb_t q[11+1], r[11];
11720     assert (p[11-1] != 0);
11721     mpn_tdiv_qr(q, r, 0, x, 22, p, 11);
11722     mpfq_copy(z, r, 11);
11723 }
11724 #endif /* !defined(HAVE_native_mpfq_fixmp_11_mod) */
11725 
11726 #if !defined(HAVE_native_mpfq_fixmp_11_rshift)
11727 /* a has 11 words. Shift it in place by cnt bits to the right.
11728  * The shift count cnt must not exceed the word size.
11729  * Note that no carry is returned for the bits shifted out. */
11730 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
11731 /* Triggered by: 11_invmod */
11732 static inline
mpfq_fixmp_11_rshift(mp_limb_t * a,int cnt)11733 void mpfq_fixmp_11_rshift(mp_limb_t * a, int cnt)
11734 {
11735     if (!cnt) return;
11736     int i;
11737     int dnt = GMP_NUMB_BITS - cnt;
11738     for (i = 0; i < 11-1; ++i) {
11739         a[i] >>= cnt;
11740         a[i] |= (a[i+1] << dnt);
11741     }
11742     a[11-1] >>= cnt;
11743 }
11744 #endif /* !defined(HAVE_native_mpfq_fixmp_11_rshift) */
11745 
11746 #if !defined(HAVE_native_mpfq_fixmp_11_long_rshift)
11747 /* a has 11 words. Shift it in place by off words plus cnt bits to the left.
11748  * Note that no carry is returned for the bits shifted out. */
11749 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
11750 /* Triggered by: 11_invmod */
11751 static inline
mpfq_fixmp_11_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)11752 void mpfq_fixmp_11_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
11753 {
11754     if (cnt) {
11755         int dnt = GMP_NUMB_BITS - cnt;
11756         for (int i = 0; i < 11 - off - 1; ++i) {
11757             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
11758         }
11759         a[11-off-1] = a[11-1]>>cnt;
11760     } else {
11761         mpfq_copyi(a, a + off, 11 - off);
11762     }
11763     mpfq_zero(a + 11 - off, off);
11764 }
11765 #endif /* !defined(HAVE_native_mpfq_fixmp_11_long_rshift) */
11766 
11767 #if !defined(HAVE_native_mpfq_fixmp_11_long_lshift)
11768 /* a has 11 words. Shift it in place by off words plus cnt bits to the left.
11769  * Note that no carry is returned for the bits shifted out. */
11770 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
11771 /* Triggered by: 11_invmod */
11772 static inline
mpfq_fixmp_11_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)11773 void mpfq_fixmp_11_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
11774 {
11775     int i;
11776     if (cnt) {
11777         int dnt = GMP_NUMB_BITS - cnt;
11778         for (i = 11-1; i>off; --i) {
11779             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
11780         }
11781         a[off] = a[0]<<cnt;
11782     } else {
11783         mpfq_copyd(a + off, a, 11 - off);
11784     }
11785     mpfq_zero(a, off);
11786 }
11787 #endif /* !defined(HAVE_native_mpfq_fixmp_11_long_lshift) */
11788 
11789 #if !defined(HAVE_native_mpfq_fixmp_11_invmod)
11790 /* x, z, and p have 11 words. Put inverse of x mod p in z.
11791  * Return non-zero if an inverse could be found.
11792  * If no inverse could be found, return 0 and set z to zero.
11793  */
11794 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
11795 static inline
mpfq_fixmp_11_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)11796 int mpfq_fixmp_11_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
11797 {
11798       mp_limb_t u[11], v[11], a[11], b[11], fix[11];
11799       int i, t, lsh;
11800 
11801       mpfq_zero(u, 11);
11802       mpfq_zero(v, 11);
11803       mpfq_copy(a, x, 11);
11804       mpfq_copy(b, p, 11);
11805       u[0] = 1UL;
11806 
11807       if (mpfq_fixmp_11_cmp(a, v) == 0 || mpfq_fixmp_11_cmp(a, b) == 0) {
11808         mpfq_zero(res, 11);
11809         return 0;
11810       }
11811 
11812       mpfq_fixmp_11_add(fix, b, u);
11813       mpfq_fixmp_11_rshift(fix, 1);
11814 
11815       assert (mpfq_fixmp_11_cmp(a,b) < 0);
11816 
11817       t = 0;
11818 
11819       for(i = 0 ; !a[i] ; i++) ;
11820       assert (i < 11);
11821       lsh = mpfq_ctzl(a[i]);
11822       mpfq_fixmp_11_long_rshift(a, i, lsh);
11823       t += lsh + i*GMP_NUMB_BITS;
11824       mpfq_fixmp_11_long_lshift(v, i, lsh);
11825 
11826       do {
11827         do {
11828           mpfq_fixmp_11_sub(b, b, a);
11829           mpfq_fixmp_11_add(v, v, u);
11830           for(i = 0 ; !b[i] ; i++) ;
11831           assert (i < 11);
11832           lsh = mpfq_ctzl(b[i]);
11833           mpfq_fixmp_11_long_rshift(b, i, lsh);
11834           t += lsh + i*GMP_NUMB_BITS;
11835           mpfq_fixmp_11_long_lshift(u, i, lsh);
11836         } while (mpfq_fixmp_11_cmp(a,b) < 0);
11837         if (mpfq_fixmp_11_cmp(a, b) == 0)
11838           break;
11839         do {
11840           mpfq_fixmp_11_sub(a, a, b);
11841           mpfq_fixmp_11_add(u, u, v);
11842           for(i = 0 ; !a[i] ; i++) ;
11843           assert (i < 11);
11844           lsh = mpfq_ctzl(a[i]);
11845           mpfq_fixmp_11_long_rshift(a, i, lsh);
11846           t += lsh + i*GMP_NUMB_BITS;
11847           mpfq_fixmp_11_long_lshift(v, i, lsh);
11848         } while (mpfq_fixmp_11_cmp(b,a)<0);
11849       } while (mpfq_fixmp_11_cmp(a,b) != 0);
11850       {
11851         if (mpfq_fixmp_11_cmp_ui(a, 1) != 0) {
11852           mpfq_copy(res, a, 11);
11853           return 0;
11854         }
11855       }
11856       while (t>0) {
11857         mp_limb_t sig = u[0] & 1UL;
11858         mpfq_fixmp_11_rshift(u, 1);
11859         if (sig)
11860           mpfq_fixmp_11_add(u, u, fix);
11861         --t;
11862       }
11863       mpfq_copy(res, u, 11);
11864       return 1;
11865 }
11866 #endif /* !defined(HAVE_native_mpfq_fixmp_11_invmod) */
11867 
11868 #if !defined(HAVE_native_mpfq_fixmp_11_redc)
11869 /* x has 24 words, z and p have 11 words.
11870  * only one word is read from invp.
11871  * Assuming R=W^12 is the redc modulus, we expect that x verifies:
11872  *   x < R*p,
11873  * so that we have eventually z < p, z congruent to x/R mod p.
11874  * The contents of the area pointed by x are clobbered by this call.
11875  * Note also that x may alias z.
11876  */
11877 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
11878 static inline
mpfq_fixmp_11_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)11879 void mpfq_fixmp_11_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
11880 {
11881     mp_limb_t cy;
11882     for(int i = 0; i < 11; ++i) {
11883         mp_limb_t t = x[i]*mip[0];
11884         cy = mpfq_fixmp_11_addmul1_shortz(x+i, p, t);
11885         assert (x[i] == 0);
11886         x[i] = cy;
11887     }
11888     cy = mpfq_fixmp_11_add(x, x, x + 11);
11889     /* At this point, we have (x' denotes x + cy*W^n here)
11890     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
11891     * x'/R < p + p
11892     */
11893     if (cy || mpfq_fixmp_11_cmp(x, p) >= 0) {
11894         mpfq_fixmp_11_sub(z, x, p);
11895     } else {
11896         mpfq_copy(z, x, 11);
11897     }
11898 }
11899 #endif /* !defined(HAVE_native_mpfq_fixmp_11_redc) */
11900 
11901 #if !defined(HAVE_native_mpfq_fixmp_11_redc_ur)
11902 /* x has 25 words, z and p have 11 words.
11903  * only one word is read from invp.
11904  * Assuming R=W^12 is the redc modulus, we expect that x verifies:
11905  *  x < W*W^11*p = W^0.5*R*p or the hw case, W*R*p otherwise,
11906  * so that we have eventually z < p, z congruent to x/R mod p.
11907  * The contents of the area pointed by x are clobbered by this call.
11908  * Note also that x may alias z.
11909  */
11910 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
11911 static inline
mpfq_fixmp_11_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)11912 void mpfq_fixmp_11_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
11913 {
11914     mp_limb_t cy, q[2];
11915     for (int i = 0; i < 11; ++i) {
11916         mp_limb_t t = x[i]*mip[0];
11917         cy = mpfq_fixmp_11_addmul1(x+i, p, t);
11918         assert (x[i] == 0);
11919         x[i] = cy;
11920     }
11921     cy=mpfq_fixmp_11_add(x+11+1, x+11+1, x);
11922     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
11923     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
11924     * x'/R < (W+1)*p
11925     */
11926     if (cy) {
11927         /* x'/R-p < W*p, which fits in n+1 words */
11928         mpn_sub(x+11,x+11,11+1,p,11);
11929     }
11930     mpn_tdiv_qr(q, z, 0, x+11, 11+1, p, 11);
11931 }
11932 #endif /* !defined(HAVE_native_mpfq_fixmp_11_redc_ur) */
11933 
11934 #if !defined(HAVE_native_mpfq_fixmp_11_mgy_encode)
11935 /* x, z, and p have 11 words.
11936  * Assuming R=W^12 is the redc modulus, we compute z=R*x mod p. */
11937 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
11938 static inline
mpfq_fixmp_11_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)11939 void mpfq_fixmp_11_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
11940 {
11941     mp_limb_t t[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10] };
11942     mpfq_fixmp_11_mod(z, t, p);
11943 }
11944 #endif /* !defined(HAVE_native_mpfq_fixmp_11_mgy_encode) */
11945 
11946 #if !defined(HAVE_native_mpfq_fixmp_11_mgy_decode)
11947 /* x, z, invR, and p have 11 words.
11948  * Assuming R=W^12 is the redc modulus, we compute z=x/R mod p. */
11949 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
11950 static inline
mpfq_fixmp_11_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)11951 void mpfq_fixmp_11_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
11952 {
11953     mp_limb_t t[22];
11954     mpfq_fixmp_11_mul(t, x, invR);
11955     mpfq_fixmp_11_mod(z, t, p);
11956 }
11957 #endif /* !defined(HAVE_native_mpfq_fixmp_11_mgy_decode) */
11958 
11959 #if !defined(HAVE_native_mpfq_fixmp_11_lshift)
11960 /* a has 11 words. Shift it in place by cnt bits to the left.
11961  * The shift count cnt must not exceed the word size.
11962  * Note that no carry is returned for the bits shifted out. */
11963 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
11964 static inline
mpfq_fixmp_11_lshift(mp_limb_t * a,int cnt)11965 void mpfq_fixmp_11_lshift(mp_limb_t * a, int cnt)
11966 {
11967     if (!cnt) return;
11968     int i;
11969     int dnt = GMP_NUMB_BITS - cnt;
11970     for (i = 11-1; i>0; --i) {
11971         a[i] <<= cnt;
11972         a[i] |= (a[i-1] >> dnt);
11973     }
11974     a[0] <<= cnt;
11975 }
11976 #endif /* !defined(HAVE_native_mpfq_fixmp_11_lshift) */
11977 
11978 #if !defined(HAVE_native_mpfq_fixmp_12_add)
11979 /* x, y, and z have 12 words. Result in z. Return carry bit */
11980 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
11981 /* Triggered by: 12_invmod, 12_redc, 12_redc_ur */
11982 static inline
mpfq_fixmp_12_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)11983 mp_limb_t mpfq_fixmp_12_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
11984 {
11985     mp_limb_t r, s, t, cy, cy1, cy2;
11986     cy = 0;
11987     r = x[0];
11988     s = r + y[0];
11989     cy1 = s < r;
11990     t = s + cy;
11991     cy2 = t < s;
11992     cy = cy1 | cy2;
11993     z[0] = t;
11994     r = x[1];
11995     s = r + y[1];
11996     cy1 = s < r;
11997     t = s + cy;
11998     cy2 = t < s;
11999     cy = cy1 | cy2;
12000     z[1] = t;
12001     r = x[2];
12002     s = r + y[2];
12003     cy1 = s < r;
12004     t = s + cy;
12005     cy2 = t < s;
12006     cy = cy1 | cy2;
12007     z[2] = t;
12008     r = x[3];
12009     s = r + y[3];
12010     cy1 = s < r;
12011     t = s + cy;
12012     cy2 = t < s;
12013     cy = cy1 | cy2;
12014     z[3] = t;
12015     r = x[4];
12016     s = r + y[4];
12017     cy1 = s < r;
12018     t = s + cy;
12019     cy2 = t < s;
12020     cy = cy1 | cy2;
12021     z[4] = t;
12022     r = x[5];
12023     s = r + y[5];
12024     cy1 = s < r;
12025     t = s + cy;
12026     cy2 = t < s;
12027     cy = cy1 | cy2;
12028     z[5] = t;
12029     r = x[6];
12030     s = r + y[6];
12031     cy1 = s < r;
12032     t = s + cy;
12033     cy2 = t < s;
12034     cy = cy1 | cy2;
12035     z[6] = t;
12036     r = x[7];
12037     s = r + y[7];
12038     cy1 = s < r;
12039     t = s + cy;
12040     cy2 = t < s;
12041     cy = cy1 | cy2;
12042     z[7] = t;
12043     r = x[8];
12044     s = r + y[8];
12045     cy1 = s < r;
12046     t = s + cy;
12047     cy2 = t < s;
12048     cy = cy1 | cy2;
12049     z[8] = t;
12050     r = x[9];
12051     s = r + y[9];
12052     cy1 = s < r;
12053     t = s + cy;
12054     cy2 = t < s;
12055     cy = cy1 | cy2;
12056     z[9] = t;
12057     r = x[10];
12058     s = r + y[10];
12059     cy1 = s < r;
12060     t = s + cy;
12061     cy2 = t < s;
12062     cy = cy1 | cy2;
12063     z[10] = t;
12064     r = x[11];
12065     s = r + y[11];
12066     cy1 = s < r;
12067     t = s + cy;
12068     cy2 = t < s;
12069     cy = cy1 | cy2;
12070     z[11] = t;
12071     return cy;
12072 }
12073 #endif /* !defined(HAVE_native_mpfq_fixmp_12_add) */
12074 
12075 #if !defined(HAVE_native_mpfq_fixmp_12_sub)
12076 /* x, y, and z have 12 words. Result in z. Return borrow bit */
12077 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
12078 /* Triggered by: 12_invmod, 12_redc */
12079 static inline
mpfq_fixmp_12_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)12080 mp_limb_t mpfq_fixmp_12_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
12081 {
12082     mp_limb_t r, s, t, cy, cy1, cy2;
12083     cy = 0;
12084     r = x[0];
12085     s = r - y[0];
12086     cy1 = s > r;
12087     t = s - cy;
12088     cy2 = t > s;
12089     cy = cy1 | cy2;
12090     z[0] = t;
12091     r = x[1];
12092     s = r - y[1];
12093     cy1 = s > r;
12094     t = s - cy;
12095     cy2 = t > s;
12096     cy = cy1 | cy2;
12097     z[1] = t;
12098     r = x[2];
12099     s = r - y[2];
12100     cy1 = s > r;
12101     t = s - cy;
12102     cy2 = t > s;
12103     cy = cy1 | cy2;
12104     z[2] = t;
12105     r = x[3];
12106     s = r - y[3];
12107     cy1 = s > r;
12108     t = s - cy;
12109     cy2 = t > s;
12110     cy = cy1 | cy2;
12111     z[3] = t;
12112     r = x[4];
12113     s = r - y[4];
12114     cy1 = s > r;
12115     t = s - cy;
12116     cy2 = t > s;
12117     cy = cy1 | cy2;
12118     z[4] = t;
12119     r = x[5];
12120     s = r - y[5];
12121     cy1 = s > r;
12122     t = s - cy;
12123     cy2 = t > s;
12124     cy = cy1 | cy2;
12125     z[5] = t;
12126     r = x[6];
12127     s = r - y[6];
12128     cy1 = s > r;
12129     t = s - cy;
12130     cy2 = t > s;
12131     cy = cy1 | cy2;
12132     z[6] = t;
12133     r = x[7];
12134     s = r - y[7];
12135     cy1 = s > r;
12136     t = s - cy;
12137     cy2 = t > s;
12138     cy = cy1 | cy2;
12139     z[7] = t;
12140     r = x[8];
12141     s = r - y[8];
12142     cy1 = s > r;
12143     t = s - cy;
12144     cy2 = t > s;
12145     cy = cy1 | cy2;
12146     z[8] = t;
12147     r = x[9];
12148     s = r - y[9];
12149     cy1 = s > r;
12150     t = s - cy;
12151     cy2 = t > s;
12152     cy = cy1 | cy2;
12153     z[9] = t;
12154     r = x[10];
12155     s = r - y[10];
12156     cy1 = s > r;
12157     t = s - cy;
12158     cy2 = t > s;
12159     cy = cy1 | cy2;
12160     z[10] = t;
12161     r = x[11];
12162     s = r - y[11];
12163     cy1 = s > r;
12164     t = s - cy;
12165     cy2 = t > s;
12166     cy = cy1 | cy2;
12167     z[11] = t;
12168     return cy;
12169 }
12170 #endif /* !defined(HAVE_native_mpfq_fixmp_12_sub) */
12171 
12172 #if !defined(HAVE_native_mpfq_fixmp_12_add_nc)
12173 /* x, y, and z have 12 words. Result in z. Carry bit is lost. */
12174 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
12175 static inline
mpfq_fixmp_12_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)12176 void mpfq_fixmp_12_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
12177 {
12178     mp_limb_t r, s, t, cy, cy1, cy2;
12179     cy = 0;
12180     r = x[0];
12181     s = r + y[0];
12182     cy1 = s < r;
12183     t = s + cy;
12184     cy2 = t < s;
12185     cy = cy1 | cy2;
12186     z[0] = t;
12187     r = x[1];
12188     s = r + y[1];
12189     cy1 = s < r;
12190     t = s + cy;
12191     cy2 = t < s;
12192     cy = cy1 | cy2;
12193     z[1] = t;
12194     r = x[2];
12195     s = r + y[2];
12196     cy1 = s < r;
12197     t = s + cy;
12198     cy2 = t < s;
12199     cy = cy1 | cy2;
12200     z[2] = t;
12201     r = x[3];
12202     s = r + y[3];
12203     cy1 = s < r;
12204     t = s + cy;
12205     cy2 = t < s;
12206     cy = cy1 | cy2;
12207     z[3] = t;
12208     r = x[4];
12209     s = r + y[4];
12210     cy1 = s < r;
12211     t = s + cy;
12212     cy2 = t < s;
12213     cy = cy1 | cy2;
12214     z[4] = t;
12215     r = x[5];
12216     s = r + y[5];
12217     cy1 = s < r;
12218     t = s + cy;
12219     cy2 = t < s;
12220     cy = cy1 | cy2;
12221     z[5] = t;
12222     r = x[6];
12223     s = r + y[6];
12224     cy1 = s < r;
12225     t = s + cy;
12226     cy2 = t < s;
12227     cy = cy1 | cy2;
12228     z[6] = t;
12229     r = x[7];
12230     s = r + y[7];
12231     cy1 = s < r;
12232     t = s + cy;
12233     cy2 = t < s;
12234     cy = cy1 | cy2;
12235     z[7] = t;
12236     r = x[8];
12237     s = r + y[8];
12238     cy1 = s < r;
12239     t = s + cy;
12240     cy2 = t < s;
12241     cy = cy1 | cy2;
12242     z[8] = t;
12243     r = x[9];
12244     s = r + y[9];
12245     cy1 = s < r;
12246     t = s + cy;
12247     cy2 = t < s;
12248     cy = cy1 | cy2;
12249     z[9] = t;
12250     r = x[10];
12251     s = r + y[10];
12252     cy1 = s < r;
12253     t = s + cy;
12254     cy2 = t < s;
12255     cy = cy1 | cy2;
12256     z[10] = t;
12257     r = x[11];
12258     s = r + y[11];
12259     cy1 = s < r;
12260     t = s + cy;
12261     cy2 = t < s;
12262     cy = cy1 | cy2;
12263     z[11] = t;
12264 }
12265 #endif /* !defined(HAVE_native_mpfq_fixmp_12_add_nc) */
12266 
12267 #if !defined(HAVE_native_mpfq_fixmp_12_sub_nc)
12268 /* x, y, and z have 12 words. Result in z. Borrow bit is lost. */
12269 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
12270 static inline
mpfq_fixmp_12_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)12271 void mpfq_fixmp_12_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
12272 {
12273     mp_limb_t r, s, t, cy, cy1, cy2;
12274     cy = 0;
12275     r = x[0];
12276     s = r - y[0];
12277     cy1 = s > r;
12278     t = s - cy;
12279     cy2 = t > s;
12280     cy = cy1 | cy2;
12281     z[0] = t;
12282     r = x[1];
12283     s = r - y[1];
12284     cy1 = s > r;
12285     t = s - cy;
12286     cy2 = t > s;
12287     cy = cy1 | cy2;
12288     z[1] = t;
12289     r = x[2];
12290     s = r - y[2];
12291     cy1 = s > r;
12292     t = s - cy;
12293     cy2 = t > s;
12294     cy = cy1 | cy2;
12295     z[2] = t;
12296     r = x[3];
12297     s = r - y[3];
12298     cy1 = s > r;
12299     t = s - cy;
12300     cy2 = t > s;
12301     cy = cy1 | cy2;
12302     z[3] = t;
12303     r = x[4];
12304     s = r - y[4];
12305     cy1 = s > r;
12306     t = s - cy;
12307     cy2 = t > s;
12308     cy = cy1 | cy2;
12309     z[4] = t;
12310     r = x[5];
12311     s = r - y[5];
12312     cy1 = s > r;
12313     t = s - cy;
12314     cy2 = t > s;
12315     cy = cy1 | cy2;
12316     z[5] = t;
12317     r = x[6];
12318     s = r - y[6];
12319     cy1 = s > r;
12320     t = s - cy;
12321     cy2 = t > s;
12322     cy = cy1 | cy2;
12323     z[6] = t;
12324     r = x[7];
12325     s = r - y[7];
12326     cy1 = s > r;
12327     t = s - cy;
12328     cy2 = t > s;
12329     cy = cy1 | cy2;
12330     z[7] = t;
12331     r = x[8];
12332     s = r - y[8];
12333     cy1 = s > r;
12334     t = s - cy;
12335     cy2 = t > s;
12336     cy = cy1 | cy2;
12337     z[8] = t;
12338     r = x[9];
12339     s = r - y[9];
12340     cy1 = s > r;
12341     t = s - cy;
12342     cy2 = t > s;
12343     cy = cy1 | cy2;
12344     z[9] = t;
12345     r = x[10];
12346     s = r - y[10];
12347     cy1 = s > r;
12348     t = s - cy;
12349     cy2 = t > s;
12350     cy = cy1 | cy2;
12351     z[10] = t;
12352     r = x[11];
12353     s = r - y[11];
12354     cy1 = s > r;
12355     t = s - cy;
12356     cy2 = t > s;
12357     cy = cy1 | cy2;
12358     z[11] = t;
12359 }
12360 #endif /* !defined(HAVE_native_mpfq_fixmp_12_sub_nc) */
12361 
12362 #if !defined(HAVE_native_mpfq_fixmp_12_add_ui)
12363 /* x, y, and z have 12 words. Result in z. Return carry bit */
12364 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
12365 static inline
mpfq_fixmp_12_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)12366 mp_limb_t mpfq_fixmp_12_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
12367 {
12368     mp_limb_t r, s, t, cy, cy1, cy2;
12369     cy = 0;
12370     r = x[0];
12371     s = r + y;
12372     cy1 = s < r;
12373     t = s + cy;
12374     cy2 = t < s;
12375     cy = cy1 | cy2;
12376     z[0] = t;
12377     s = x[1];
12378     t = s + cy;
12379     cy = t < s;
12380     z[1] = t;
12381     s = x[2];
12382     t = s + cy;
12383     cy = t < s;
12384     z[2] = t;
12385     s = x[3];
12386     t = s + cy;
12387     cy = t < s;
12388     z[3] = t;
12389     s = x[4];
12390     t = s + cy;
12391     cy = t < s;
12392     z[4] = t;
12393     s = x[5];
12394     t = s + cy;
12395     cy = t < s;
12396     z[5] = t;
12397     s = x[6];
12398     t = s + cy;
12399     cy = t < s;
12400     z[6] = t;
12401     s = x[7];
12402     t = s + cy;
12403     cy = t < s;
12404     z[7] = t;
12405     s = x[8];
12406     t = s + cy;
12407     cy = t < s;
12408     z[8] = t;
12409     s = x[9];
12410     t = s + cy;
12411     cy = t < s;
12412     z[9] = t;
12413     s = x[10];
12414     t = s + cy;
12415     cy = t < s;
12416     z[10] = t;
12417     s = x[11];
12418     t = s + cy;
12419     cy = t < s;
12420     z[11] = t;
12421     return cy;
12422 }
12423 #endif /* !defined(HAVE_native_mpfq_fixmp_12_add_ui) */
12424 
12425 #if !defined(HAVE_native_mpfq_fixmp_12_sub_ui)
12426 /* x, y, and z have 12 words. Result in z. Return borrow bit */
12427 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
12428 static inline
mpfq_fixmp_12_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)12429 mp_limb_t mpfq_fixmp_12_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
12430 {
12431     mp_limb_t r, s, t, cy, cy1, cy2;
12432     cy = 0;
12433     r = x[0];
12434     s = r - y;
12435     cy1 = s > r;
12436     t = s - cy;
12437     cy2 = t > s;
12438     cy = cy1 | cy2;
12439     z[0] = t;
12440     s = x[1];
12441     t = s - cy;
12442     cy = t > s;
12443     z[1] = t;
12444     s = x[2];
12445     t = s - cy;
12446     cy = t > s;
12447     z[2] = t;
12448     s = x[3];
12449     t = s - cy;
12450     cy = t > s;
12451     z[3] = t;
12452     s = x[4];
12453     t = s - cy;
12454     cy = t > s;
12455     z[4] = t;
12456     s = x[5];
12457     t = s - cy;
12458     cy = t > s;
12459     z[5] = t;
12460     s = x[6];
12461     t = s - cy;
12462     cy = t > s;
12463     z[6] = t;
12464     s = x[7];
12465     t = s - cy;
12466     cy = t > s;
12467     z[7] = t;
12468     s = x[8];
12469     t = s - cy;
12470     cy = t > s;
12471     z[8] = t;
12472     s = x[9];
12473     t = s - cy;
12474     cy = t > s;
12475     z[9] = t;
12476     s = x[10];
12477     t = s - cy;
12478     cy = t > s;
12479     z[10] = t;
12480     s = x[11];
12481     t = s - cy;
12482     cy = t > s;
12483     z[11] = t;
12484     return cy;
12485 }
12486 #endif /* !defined(HAVE_native_mpfq_fixmp_12_sub_ui) */
12487 
12488 #if !defined(HAVE_native_mpfq_fixmp_12_add_ui_nc)
12489 /* x, y, and z have 12 words. Result in z. Carry bit is lost. */
12490 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
12491 static inline
mpfq_fixmp_12_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)12492 void mpfq_fixmp_12_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
12493 {
12494     mp_limb_t r, s, t, cy, cy1, cy2;
12495     cy = 0;
12496     r = x[0];
12497     s = r + y;
12498     cy1 = s < r;
12499     t = s + cy;
12500     cy2 = t < s;
12501     cy = cy1 | cy2;
12502     z[0] = t;
12503     s = x[1];
12504     t = s + cy;
12505     cy = t < s;
12506     z[1] = t;
12507     s = x[2];
12508     t = s + cy;
12509     cy = t < s;
12510     z[2] = t;
12511     s = x[3];
12512     t = s + cy;
12513     cy = t < s;
12514     z[3] = t;
12515     s = x[4];
12516     t = s + cy;
12517     cy = t < s;
12518     z[4] = t;
12519     s = x[5];
12520     t = s + cy;
12521     cy = t < s;
12522     z[5] = t;
12523     s = x[6];
12524     t = s + cy;
12525     cy = t < s;
12526     z[6] = t;
12527     s = x[7];
12528     t = s + cy;
12529     cy = t < s;
12530     z[7] = t;
12531     s = x[8];
12532     t = s + cy;
12533     cy = t < s;
12534     z[8] = t;
12535     s = x[9];
12536     t = s + cy;
12537     cy = t < s;
12538     z[9] = t;
12539     s = x[10];
12540     t = s + cy;
12541     cy = t < s;
12542     z[10] = t;
12543     s = x[11];
12544     t = s + cy;
12545     cy = t < s;
12546     z[11] = t;
12547 }
12548 #endif /* !defined(HAVE_native_mpfq_fixmp_12_add_ui_nc) */
12549 
12550 #if !defined(HAVE_native_mpfq_fixmp_12_sub_ui_nc)
12551 /* x, y, and z have 12 words. Result in z. Borrow bit is lost. */
12552 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
12553 static inline
mpfq_fixmp_12_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)12554 void mpfq_fixmp_12_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
12555 {
12556     mp_limb_t r, s, t, cy, cy1, cy2;
12557     cy = 0;
12558     r = x[0];
12559     s = r - y;
12560     cy1 = s > r;
12561     t = s - cy;
12562     cy2 = t > s;
12563     cy = cy1 | cy2;
12564     z[0] = t;
12565     s = x[1];
12566     t = s - cy;
12567     cy = t > s;
12568     z[1] = t;
12569     s = x[2];
12570     t = s - cy;
12571     cy = t > s;
12572     z[2] = t;
12573     s = x[3];
12574     t = s - cy;
12575     cy = t > s;
12576     z[3] = t;
12577     s = x[4];
12578     t = s - cy;
12579     cy = t > s;
12580     z[4] = t;
12581     s = x[5];
12582     t = s - cy;
12583     cy = t > s;
12584     z[5] = t;
12585     s = x[6];
12586     t = s - cy;
12587     cy = t > s;
12588     z[6] = t;
12589     s = x[7];
12590     t = s - cy;
12591     cy = t > s;
12592     z[7] = t;
12593     s = x[8];
12594     t = s - cy;
12595     cy = t > s;
12596     z[8] = t;
12597     s = x[9];
12598     t = s - cy;
12599     cy = t > s;
12600     z[9] = t;
12601     s = x[10];
12602     t = s - cy;
12603     cy = t > s;
12604     z[10] = t;
12605     s = x[11];
12606     t = s - cy;
12607     cy = t > s;
12608     z[11] = t;
12609 }
12610 #endif /* !defined(HAVE_native_mpfq_fixmp_12_sub_ui_nc) */
12611 
12612 #if !defined(HAVE_native_mpfq_fixmp_12_cmp)
12613 /* x and y have 12 words. Return sign of difference x-y. */
12614 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
12615 /* Triggered by: 12_invmod, 12_redc */
12616 static inline
mpfq_fixmp_12_cmp(const mp_limb_t * x,const mp_limb_t * y)12617 int mpfq_fixmp_12_cmp(const mp_limb_t * x, const mp_limb_t * y)
12618 {
12619     for (int i = 12-1; i >= 0; --i) {
12620         if (x[i] > y[i]) return 1;
12621         if (x[i] < y[i]) return -1;
12622     }
12623     return 0;
12624 }
12625 #endif /* !defined(HAVE_native_mpfq_fixmp_12_cmp) */
12626 
12627 #if !defined(HAVE_native_mpfq_fixmp_12_cmp_ui)
12628 /* x has 12 words. Return sign of difference x-y. */
12629 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
12630 /* Triggered by: 12_invmod */
12631 static inline
mpfq_fixmp_12_cmp_ui(const mp_limb_t * x,mp_limb_t y)12632 int mpfq_fixmp_12_cmp_ui(const mp_limb_t * x, mp_limb_t y)
12633 {
12634     for (int i = 12-1; i > 0; --i) {
12635         if (x[i]) return 1;
12636     }
12637     if (x[0]>y) return 1;
12638     if (x[0]<y) return -1;
12639     return 0;
12640 }
12641 #endif /* !defined(HAVE_native_mpfq_fixmp_12_cmp_ui) */
12642 
12643 #if !defined(HAVE_native_mpfq_fixmp_12_addmul1)
12644 /* x has 12 words, z has 14.
12645  * Put (z+x*c) in z. Return carry bit. */
12646 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
12647 /* Triggered by: 12_redc_ur */
12648 static inline
mpfq_fixmp_12_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)12649 mp_limb_t mpfq_fixmp_12_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
12650 {
12651     mp_limb_t hi, lo, carry, buf;
12652     carry = 0;
12653     mpfq_umul_ppmm(hi,lo,c,x[0]);
12654     lo += carry;
12655     carry = (lo<carry) + hi;
12656     buf = z[0];
12657     lo += buf;
12658     carry += (lo<buf);
12659     z[0] = lo;
12660     mpfq_umul_ppmm(hi,lo,c,x[1]);
12661     lo += carry;
12662     carry = (lo<carry) + hi;
12663     buf = z[1];
12664     lo += buf;
12665     carry += (lo<buf);
12666     z[1] = lo;
12667     mpfq_umul_ppmm(hi,lo,c,x[2]);
12668     lo += carry;
12669     carry = (lo<carry) + hi;
12670     buf = z[2];
12671     lo += buf;
12672     carry += (lo<buf);
12673     z[2] = lo;
12674     mpfq_umul_ppmm(hi,lo,c,x[3]);
12675     lo += carry;
12676     carry = (lo<carry) + hi;
12677     buf = z[3];
12678     lo += buf;
12679     carry += (lo<buf);
12680     z[3] = lo;
12681     mpfq_umul_ppmm(hi,lo,c,x[4]);
12682     lo += carry;
12683     carry = (lo<carry) + hi;
12684     buf = z[4];
12685     lo += buf;
12686     carry += (lo<buf);
12687     z[4] = lo;
12688     mpfq_umul_ppmm(hi,lo,c,x[5]);
12689     lo += carry;
12690     carry = (lo<carry) + hi;
12691     buf = z[5];
12692     lo += buf;
12693     carry += (lo<buf);
12694     z[5] = lo;
12695     mpfq_umul_ppmm(hi,lo,c,x[6]);
12696     lo += carry;
12697     carry = (lo<carry) + hi;
12698     buf = z[6];
12699     lo += buf;
12700     carry += (lo<buf);
12701     z[6] = lo;
12702     mpfq_umul_ppmm(hi,lo,c,x[7]);
12703     lo += carry;
12704     carry = (lo<carry) + hi;
12705     buf = z[7];
12706     lo += buf;
12707     carry += (lo<buf);
12708     z[7] = lo;
12709     mpfq_umul_ppmm(hi,lo,c,x[8]);
12710     lo += carry;
12711     carry = (lo<carry) + hi;
12712     buf = z[8];
12713     lo += buf;
12714     carry += (lo<buf);
12715     z[8] = lo;
12716     mpfq_umul_ppmm(hi,lo,c,x[9]);
12717     lo += carry;
12718     carry = (lo<carry) + hi;
12719     buf = z[9];
12720     lo += buf;
12721     carry += (lo<buf);
12722     z[9] = lo;
12723     mpfq_umul_ppmm(hi,lo,c,x[10]);
12724     lo += carry;
12725     carry = (lo<carry) + hi;
12726     buf = z[10];
12727     lo += buf;
12728     carry += (lo<buf);
12729     z[10] = lo;
12730     mpfq_umul_ppmm(hi,lo,c,x[11]);
12731     lo += carry;
12732     carry = (lo<carry) + hi;
12733     buf = z[11];
12734     lo += buf;
12735     carry += (lo<buf);
12736     z[11] = lo;
12737     z[12] += carry;
12738     return (z[12]<carry);
12739 }
12740 #endif /* !defined(HAVE_native_mpfq_fixmp_12_addmul1) */
12741 
12742 #if !defined(HAVE_native_mpfq_fixmp_12_addmul1_nc)
12743 /* x has 12 words, z has 14.
12744  * Put (z+x*c) in z. Carry bit is lost. */
12745 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
12746 /* Triggered by: 12_mul, 12_mgy_decode, 13_sqr, 13_shortmul, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 12_5_sqr, 12_5_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
12747 static inline
mpfq_fixmp_12_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)12748 void mpfq_fixmp_12_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
12749 {
12750     mp_limb_t hi, lo, carry, buf;
12751     carry = 0;
12752     mpfq_umul_ppmm(hi,lo,c,x[0]);
12753     lo += carry;
12754     carry = (lo<carry) + hi;
12755     buf = z[0];
12756     lo += buf;
12757     carry += (lo<buf);
12758     z[0] = lo;
12759     mpfq_umul_ppmm(hi,lo,c,x[1]);
12760     lo += carry;
12761     carry = (lo<carry) + hi;
12762     buf = z[1];
12763     lo += buf;
12764     carry += (lo<buf);
12765     z[1] = lo;
12766     mpfq_umul_ppmm(hi,lo,c,x[2]);
12767     lo += carry;
12768     carry = (lo<carry) + hi;
12769     buf = z[2];
12770     lo += buf;
12771     carry += (lo<buf);
12772     z[2] = lo;
12773     mpfq_umul_ppmm(hi,lo,c,x[3]);
12774     lo += carry;
12775     carry = (lo<carry) + hi;
12776     buf = z[3];
12777     lo += buf;
12778     carry += (lo<buf);
12779     z[3] = lo;
12780     mpfq_umul_ppmm(hi,lo,c,x[4]);
12781     lo += carry;
12782     carry = (lo<carry) + hi;
12783     buf = z[4];
12784     lo += buf;
12785     carry += (lo<buf);
12786     z[4] = lo;
12787     mpfq_umul_ppmm(hi,lo,c,x[5]);
12788     lo += carry;
12789     carry = (lo<carry) + hi;
12790     buf = z[5];
12791     lo += buf;
12792     carry += (lo<buf);
12793     z[5] = lo;
12794     mpfq_umul_ppmm(hi,lo,c,x[6]);
12795     lo += carry;
12796     carry = (lo<carry) + hi;
12797     buf = z[6];
12798     lo += buf;
12799     carry += (lo<buf);
12800     z[6] = lo;
12801     mpfq_umul_ppmm(hi,lo,c,x[7]);
12802     lo += carry;
12803     carry = (lo<carry) + hi;
12804     buf = z[7];
12805     lo += buf;
12806     carry += (lo<buf);
12807     z[7] = lo;
12808     mpfq_umul_ppmm(hi,lo,c,x[8]);
12809     lo += carry;
12810     carry = (lo<carry) + hi;
12811     buf = z[8];
12812     lo += buf;
12813     carry += (lo<buf);
12814     z[8] = lo;
12815     mpfq_umul_ppmm(hi,lo,c,x[9]);
12816     lo += carry;
12817     carry = (lo<carry) + hi;
12818     buf = z[9];
12819     lo += buf;
12820     carry += (lo<buf);
12821     z[9] = lo;
12822     mpfq_umul_ppmm(hi,lo,c,x[10]);
12823     lo += carry;
12824     carry = (lo<carry) + hi;
12825     buf = z[10];
12826     lo += buf;
12827     carry += (lo<buf);
12828     z[10] = lo;
12829     mpfq_umul_ppmm(hi,lo,c,x[11]);
12830     lo += carry;
12831     carry = (lo<carry) + hi;
12832     buf = z[11];
12833     lo += buf;
12834     carry += (lo<buf);
12835     z[11] = lo;
12836     z[12] += carry;
12837 }
12838 #endif /* !defined(HAVE_native_mpfq_fixmp_12_addmul1_nc) */
12839 
12840 #if !defined(HAVE_native_mpfq_fixmp_12_addmul1_shortz)
12841 /* x has 12 words, z has 13.
12842  * Put (z+x*c) in z. Return carry word. */
12843 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
12844 /* Triggered by: 12_redc */
12845 static inline
mpfq_fixmp_12_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)12846 mp_limb_t mpfq_fixmp_12_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
12847 {
12848     mp_limb_t hi, lo, carry, buf;
12849     carry = 0;
12850     mpfq_umul_ppmm(hi,lo,c,x[0]);
12851     lo += carry;
12852     carry = (lo<carry) + hi;
12853     buf = z[0];
12854     lo += buf;
12855     carry += (lo<buf);
12856     z[0] = lo;
12857     mpfq_umul_ppmm(hi,lo,c,x[1]);
12858     lo += carry;
12859     carry = (lo<carry) + hi;
12860     buf = z[1];
12861     lo += buf;
12862     carry += (lo<buf);
12863     z[1] = lo;
12864     mpfq_umul_ppmm(hi,lo,c,x[2]);
12865     lo += carry;
12866     carry = (lo<carry) + hi;
12867     buf = z[2];
12868     lo += buf;
12869     carry += (lo<buf);
12870     z[2] = lo;
12871     mpfq_umul_ppmm(hi,lo,c,x[3]);
12872     lo += carry;
12873     carry = (lo<carry) + hi;
12874     buf = z[3];
12875     lo += buf;
12876     carry += (lo<buf);
12877     z[3] = lo;
12878     mpfq_umul_ppmm(hi,lo,c,x[4]);
12879     lo += carry;
12880     carry = (lo<carry) + hi;
12881     buf = z[4];
12882     lo += buf;
12883     carry += (lo<buf);
12884     z[4] = lo;
12885     mpfq_umul_ppmm(hi,lo,c,x[5]);
12886     lo += carry;
12887     carry = (lo<carry) + hi;
12888     buf = z[5];
12889     lo += buf;
12890     carry += (lo<buf);
12891     z[5] = lo;
12892     mpfq_umul_ppmm(hi,lo,c,x[6]);
12893     lo += carry;
12894     carry = (lo<carry) + hi;
12895     buf = z[6];
12896     lo += buf;
12897     carry += (lo<buf);
12898     z[6] = lo;
12899     mpfq_umul_ppmm(hi,lo,c,x[7]);
12900     lo += carry;
12901     carry = (lo<carry) + hi;
12902     buf = z[7];
12903     lo += buf;
12904     carry += (lo<buf);
12905     z[7] = lo;
12906     mpfq_umul_ppmm(hi,lo,c,x[8]);
12907     lo += carry;
12908     carry = (lo<carry) + hi;
12909     buf = z[8];
12910     lo += buf;
12911     carry += (lo<buf);
12912     z[8] = lo;
12913     mpfq_umul_ppmm(hi,lo,c,x[9]);
12914     lo += carry;
12915     carry = (lo<carry) + hi;
12916     buf = z[9];
12917     lo += buf;
12918     carry += (lo<buf);
12919     z[9] = lo;
12920     mpfq_umul_ppmm(hi,lo,c,x[10]);
12921     lo += carry;
12922     carry = (lo<carry) + hi;
12923     buf = z[10];
12924     lo += buf;
12925     carry += (lo<buf);
12926     z[10] = lo;
12927     mpfq_umul_ppmm(hi,lo,c,x[11]);
12928     lo += carry;
12929     carry = (lo<carry) + hi;
12930     buf = z[11];
12931     lo += buf;
12932     carry += (lo<buf);
12933     z[11] = lo;
12934     return carry;
12935 }
12936 #endif /* !defined(HAVE_native_mpfq_fixmp_12_addmul1_shortz) */
12937 
12938 #if !defined(HAVE_native_mpfq_fixmp_12_mul)
12939 /* x and y have 12 words, z has 26. Put x*y in z. */
12940 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
12941 /* Triggered by: 12_mgy_decode */
12942 static inline
mpfq_fixmp_12_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)12943 void mpfq_fixmp_12_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
12944 {
12945     assert(z != x && z != y);
12946     for (int i = 0; i < 24; z[i++] = 0) ;
12947     mpfq_fixmp_12_addmul1_nc (z + 0, x, y[0]);
12948     mpfq_fixmp_12_addmul1_nc (z + 1, x, y[1]);
12949     mpfq_fixmp_12_addmul1_nc (z + 2, x, y[2]);
12950     mpfq_fixmp_12_addmul1_nc (z + 3, x, y[3]);
12951     mpfq_fixmp_12_addmul1_nc (z + 4, x, y[4]);
12952     mpfq_fixmp_12_addmul1_nc (z + 5, x, y[5]);
12953     mpfq_fixmp_12_addmul1_nc (z + 6, x, y[6]);
12954     mpfq_fixmp_12_addmul1_nc (z + 7, x, y[7]);
12955     mpfq_fixmp_12_addmul1_nc (z + 8, x, y[8]);
12956     mpfq_fixmp_12_addmul1_nc (z + 9, x, y[9]);
12957     mpfq_fixmp_12_addmul1_nc (z + 10, x, y[10]);
12958     mpfq_fixmp_12_addmul1_nc (z + 11, x, y[11]);
12959 }
12960 #endif /* !defined(HAVE_native_mpfq_fixmp_12_mul) */
12961 
12962 #if !defined(HAVE_native_mpfq_fixmp_12_sqr)
12963 /* x has 12 words, z has 26. Put x*y in z. */
12964 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
12965 static inline
mpfq_fixmp_12_sqr(mp_limb_t * z,const mp_limb_t * x)12966 void mpfq_fixmp_12_sqr(mp_limb_t * z, const mp_limb_t * x)
12967 {
12968     mp_limb_t buf[24] = {0,};
12969     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
12970     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
12971     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
12972     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
12973     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
12974     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
12975     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
12976     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
12977     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
12978     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
12979     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
12980     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
12981     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
12982     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
12983     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
12984     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
12985     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
12986     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
12987     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
12988     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
12989     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
12990     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
12991     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
12992     mpn_lshift(buf, buf, 24, 1);
12993     mpn_add_n(z, z, buf, 24);
12994 }
12995 #endif /* !defined(HAVE_native_mpfq_fixmp_12_sqr) */
12996 
12997 #if !defined(HAVE_native_mpfq_fixmp_12_mul1)
12998 /* x has 12 words, z has 14. Put x*y in z. */
12999 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
13000 static inline
mpfq_fixmp_12_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)13001 void mpfq_fixmp_12_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
13002 {
13003     mp_limb_t hi, lo, carry;
13004     carry = 0;
13005     mpfq_umul_ppmm(hi,lo,c,x[0]);
13006     lo += carry;
13007     carry = (lo<carry) + hi;
13008     z[0] = lo;
13009     mpfq_umul_ppmm(hi,lo,c,x[1]);
13010     lo += carry;
13011     carry = (lo<carry) + hi;
13012     z[1] = lo;
13013     mpfq_umul_ppmm(hi,lo,c,x[2]);
13014     lo += carry;
13015     carry = (lo<carry) + hi;
13016     z[2] = lo;
13017     mpfq_umul_ppmm(hi,lo,c,x[3]);
13018     lo += carry;
13019     carry = (lo<carry) + hi;
13020     z[3] = lo;
13021     mpfq_umul_ppmm(hi,lo,c,x[4]);
13022     lo += carry;
13023     carry = (lo<carry) + hi;
13024     z[4] = lo;
13025     mpfq_umul_ppmm(hi,lo,c,x[5]);
13026     lo += carry;
13027     carry = (lo<carry) + hi;
13028     z[5] = lo;
13029     mpfq_umul_ppmm(hi,lo,c,x[6]);
13030     lo += carry;
13031     carry = (lo<carry) + hi;
13032     z[6] = lo;
13033     mpfq_umul_ppmm(hi,lo,c,x[7]);
13034     lo += carry;
13035     carry = (lo<carry) + hi;
13036     z[7] = lo;
13037     mpfq_umul_ppmm(hi,lo,c,x[8]);
13038     lo += carry;
13039     carry = (lo<carry) + hi;
13040     z[8] = lo;
13041     mpfq_umul_ppmm(hi,lo,c,x[9]);
13042     lo += carry;
13043     carry = (lo<carry) + hi;
13044     z[9] = lo;
13045     mpfq_umul_ppmm(hi,lo,c,x[10]);
13046     lo += carry;
13047     carry = (lo<carry) + hi;
13048     z[10] = lo;
13049     mpfq_umul_ppmm(hi,lo,c,x[11]);
13050     lo += carry;
13051     carry = (lo<carry) + hi;
13052     z[11] = lo;
13053     z[12] = carry;
13054 }
13055 #endif /* !defined(HAVE_native_mpfq_fixmp_12_mul1) */
13056 
13057 #if !defined(HAVE_native_mpfq_fixmp_12_shortmul)
13058 /* x and y have 12 words, z has 13.
13059  * Put the low 13 words of x*y in z. */
13060 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
13061 static inline
mpfq_fixmp_12_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)13062 void mpfq_fixmp_12_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
13063 {
13064     mpfq_zero(z, 12);
13065     mpfq_fixmp_11_addmul1_nc (z+0, x, y[0]);
13066     z[12-1] += x[11]*y[0];
13067     mpfq_fixmp_10_addmul1_nc (z+1, x, y[1]);
13068     z[12-1] += x[10]*y[1];
13069     mpfq_fixmp_9_addmul1_nc (z+2, x, y[2]);
13070     z[12-1] += x[9]*y[2];
13071     mpfq_fixmp_8_addmul1_nc (z+3, x, y[3]);
13072     z[12-1] += x[8]*y[3];
13073     mpfq_fixmp_7_addmul1_nc (z+4, x, y[4]);
13074     z[12-1] += x[7]*y[4];
13075     mpfq_fixmp_6_addmul1_nc (z+5, x, y[5]);
13076     z[12-1] += x[6]*y[5];
13077     mpfq_fixmp_5_addmul1_nc (z+6, x, y[6]);
13078     z[12-1] += x[5]*y[6];
13079     mpfq_fixmp_4_addmul1_nc (z+7, x, y[7]);
13080     z[12-1] += x[4]*y[7];
13081     mpfq_fixmp_3_addmul1_nc (z+8, x, y[8]);
13082     z[12-1] += x[3]*y[8];
13083     mpfq_fixmp_2_addmul1_nc (z+9, x, y[9]);
13084     z[12-1] += x[2]*y[9];
13085     mpfq_fixmp_1_addmul1_nc (z+10, x, y[10]);
13086     z[12-1] += x[1]*y[10];
13087     z[12-1] += x[0]*y[12-1];
13088 }
13089 #endif /* !defined(HAVE_native_mpfq_fixmp_12_shortmul) */
13090 
13091 #if !defined(HAVE_native_mpfq_fixmp_12_mod)
13092 /* x has 26 words. z and p have 12 words, and the high word of p is non-zero.
13093  * Put x mod p in z. */
13094 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
13095 /* Triggered by: 12_mgy_decode */
13096 static inline
mpfq_fixmp_12_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)13097 void mpfq_fixmp_12_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
13098 {
13099     mp_limb_t q[12+1], r[12];
13100     assert (p[12-1] != 0);
13101     mpn_tdiv_qr(q, r, 0, x, 24, p, 12);
13102     mpfq_copy(z, r, 12);
13103 }
13104 #endif /* !defined(HAVE_native_mpfq_fixmp_12_mod) */
13105 
13106 #if !defined(HAVE_native_mpfq_fixmp_12_rshift)
13107 /* a has 12 words. Shift it in place by cnt bits to the right.
13108  * The shift count cnt must not exceed the word size.
13109  * Note that no carry is returned for the bits shifted out. */
13110 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
13111 /* Triggered by: 12_invmod */
13112 static inline
mpfq_fixmp_12_rshift(mp_limb_t * a,int cnt)13113 void mpfq_fixmp_12_rshift(mp_limb_t * a, int cnt)
13114 {
13115     if (!cnt) return;
13116     int i;
13117     int dnt = GMP_NUMB_BITS - cnt;
13118     for (i = 0; i < 12-1; ++i) {
13119         a[i] >>= cnt;
13120         a[i] |= (a[i+1] << dnt);
13121     }
13122     a[12-1] >>= cnt;
13123 }
13124 #endif /* !defined(HAVE_native_mpfq_fixmp_12_rshift) */
13125 
13126 #if !defined(HAVE_native_mpfq_fixmp_12_long_rshift)
13127 /* a has 12 words. Shift it in place by off words plus cnt bits to the left.
13128  * Note that no carry is returned for the bits shifted out. */
13129 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
13130 /* Triggered by: 12_invmod */
13131 static inline
mpfq_fixmp_12_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)13132 void mpfq_fixmp_12_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
13133 {
13134     if (cnt) {
13135         int dnt = GMP_NUMB_BITS - cnt;
13136         for (int i = 0; i < 12 - off - 1; ++i) {
13137             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
13138         }
13139         a[12-off-1] = a[12-1]>>cnt;
13140     } else {
13141         mpfq_copyi(a, a + off, 12 - off);
13142     }
13143     mpfq_zero(a + 12 - off, off);
13144 }
13145 #endif /* !defined(HAVE_native_mpfq_fixmp_12_long_rshift) */
13146 
13147 #if !defined(HAVE_native_mpfq_fixmp_12_long_lshift)
13148 /* a has 12 words. Shift it in place by off words plus cnt bits to the left.
13149  * Note that no carry is returned for the bits shifted out. */
13150 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
13151 /* Triggered by: 12_invmod */
13152 static inline
mpfq_fixmp_12_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)13153 void mpfq_fixmp_12_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
13154 {
13155     int i;
13156     if (cnt) {
13157         int dnt = GMP_NUMB_BITS - cnt;
13158         for (i = 12-1; i>off; --i) {
13159             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
13160         }
13161         a[off] = a[0]<<cnt;
13162     } else {
13163         mpfq_copyd(a + off, a, 12 - off);
13164     }
13165     mpfq_zero(a, off);
13166 }
13167 #endif /* !defined(HAVE_native_mpfq_fixmp_12_long_lshift) */
13168 
13169 #if !defined(HAVE_native_mpfq_fixmp_12_invmod)
13170 /* x, z, and p have 12 words. Put inverse of x mod p in z.
13171  * Return non-zero if an inverse could be found.
13172  * If no inverse could be found, return 0 and set z to zero.
13173  */
13174 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
13175 static inline
mpfq_fixmp_12_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)13176 int mpfq_fixmp_12_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
13177 {
13178       mp_limb_t u[12], v[12], a[12], b[12], fix[12];
13179       int i, t, lsh;
13180 
13181       mpfq_zero(u, 12);
13182       mpfq_zero(v, 12);
13183       mpfq_copy(a, x, 12);
13184       mpfq_copy(b, p, 12);
13185       u[0] = 1UL;
13186 
13187       if (mpfq_fixmp_12_cmp(a, v) == 0 || mpfq_fixmp_12_cmp(a, b) == 0) {
13188         mpfq_zero(res, 12);
13189         return 0;
13190       }
13191 
13192       mpfq_fixmp_12_add(fix, b, u);
13193       mpfq_fixmp_12_rshift(fix, 1);
13194 
13195       assert (mpfq_fixmp_12_cmp(a,b) < 0);
13196 
13197       t = 0;
13198 
13199       for(i = 0 ; !a[i] ; i++) ;
13200       assert (i < 12);
13201       lsh = mpfq_ctzl(a[i]);
13202       mpfq_fixmp_12_long_rshift(a, i, lsh);
13203       t += lsh + i*GMP_NUMB_BITS;
13204       mpfq_fixmp_12_long_lshift(v, i, lsh);
13205 
13206       do {
13207         do {
13208           mpfq_fixmp_12_sub(b, b, a);
13209           mpfq_fixmp_12_add(v, v, u);
13210           for(i = 0 ; !b[i] ; i++) ;
13211           assert (i < 12);
13212           lsh = mpfq_ctzl(b[i]);
13213           mpfq_fixmp_12_long_rshift(b, i, lsh);
13214           t += lsh + i*GMP_NUMB_BITS;
13215           mpfq_fixmp_12_long_lshift(u, i, lsh);
13216         } while (mpfq_fixmp_12_cmp(a,b) < 0);
13217         if (mpfq_fixmp_12_cmp(a, b) == 0)
13218           break;
13219         do {
13220           mpfq_fixmp_12_sub(a, a, b);
13221           mpfq_fixmp_12_add(u, u, v);
13222           for(i = 0 ; !a[i] ; i++) ;
13223           assert (i < 12);
13224           lsh = mpfq_ctzl(a[i]);
13225           mpfq_fixmp_12_long_rshift(a, i, lsh);
13226           t += lsh + i*GMP_NUMB_BITS;
13227           mpfq_fixmp_12_long_lshift(v, i, lsh);
13228         } while (mpfq_fixmp_12_cmp(b,a)<0);
13229       } while (mpfq_fixmp_12_cmp(a,b) != 0);
13230       {
13231         if (mpfq_fixmp_12_cmp_ui(a, 1) != 0) {
13232           mpfq_copy(res, a, 12);
13233           return 0;
13234         }
13235       }
13236       while (t>0) {
13237         mp_limb_t sig = u[0] & 1UL;
13238         mpfq_fixmp_12_rshift(u, 1);
13239         if (sig)
13240           mpfq_fixmp_12_add(u, u, fix);
13241         --t;
13242       }
13243       mpfq_copy(res, u, 12);
13244       return 1;
13245 }
13246 #endif /* !defined(HAVE_native_mpfq_fixmp_12_invmod) */
13247 
13248 #if !defined(HAVE_native_mpfq_fixmp_12_redc)
13249 /* x has 26 words, z and p have 12 words.
13250  * only one word is read from invp.
13251  * Assuming R=W^13 is the redc modulus, we expect that x verifies:
13252  *   x < R*p,
13253  * so that we have eventually z < p, z congruent to x/R mod p.
13254  * The contents of the area pointed by x are clobbered by this call.
13255  * Note also that x may alias z.
13256  */
13257 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
13258 static inline
mpfq_fixmp_12_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)13259 void mpfq_fixmp_12_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
13260 {
13261     mp_limb_t cy;
13262     for(int i = 0; i < 12; ++i) {
13263         mp_limb_t t = x[i]*mip[0];
13264         cy = mpfq_fixmp_12_addmul1_shortz(x+i, p, t);
13265         assert (x[i] == 0);
13266         x[i] = cy;
13267     }
13268     cy = mpfq_fixmp_12_add(x, x, x + 12);
13269     /* At this point, we have (x' denotes x + cy*W^n here)
13270     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
13271     * x'/R < p + p
13272     */
13273     if (cy || mpfq_fixmp_12_cmp(x, p) >= 0) {
13274         mpfq_fixmp_12_sub(z, x, p);
13275     } else {
13276         mpfq_copy(z, x, 12);
13277     }
13278 }
13279 #endif /* !defined(HAVE_native_mpfq_fixmp_12_redc) */
13280 
13281 #if !defined(HAVE_native_mpfq_fixmp_12_redc_ur)
13282 /* x has 27 words, z and p have 12 words.
13283  * only one word is read from invp.
13284  * Assuming R=W^13 is the redc modulus, we expect that x verifies:
13285  *  x < W*W^12*p = W^0.5*R*p or the hw case, W*R*p otherwise,
13286  * so that we have eventually z < p, z congruent to x/R mod p.
13287  * The contents of the area pointed by x are clobbered by this call.
13288  * Note also that x may alias z.
13289  */
13290 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
13291 static inline
mpfq_fixmp_12_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)13292 void mpfq_fixmp_12_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
13293 {
13294     mp_limb_t cy, q[2];
13295     for (int i = 0; i < 12; ++i) {
13296         mp_limb_t t = x[i]*mip[0];
13297         cy = mpfq_fixmp_12_addmul1(x+i, p, t);
13298         assert (x[i] == 0);
13299         x[i] = cy;
13300     }
13301     cy=mpfq_fixmp_12_add(x+12+1, x+12+1, x);
13302     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
13303     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
13304     * x'/R < (W+1)*p
13305     */
13306     if (cy) {
13307         /* x'/R-p < W*p, which fits in n+1 words */
13308         mpn_sub(x+12,x+12,12+1,p,12);
13309     }
13310     mpn_tdiv_qr(q, z, 0, x+12, 12+1, p, 12);
13311 }
13312 #endif /* !defined(HAVE_native_mpfq_fixmp_12_redc_ur) */
13313 
13314 #if !defined(HAVE_native_mpfq_fixmp_12_mgy_encode)
13315 /* x, z, and p have 12 words.
13316  * Assuming R=W^13 is the redc modulus, we compute z=R*x mod p. */
13317 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
13318 static inline
mpfq_fixmp_12_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)13319 void mpfq_fixmp_12_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
13320 {
13321     mp_limb_t t[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11] };
13322     mpfq_fixmp_12_mod(z, t, p);
13323 }
13324 #endif /* !defined(HAVE_native_mpfq_fixmp_12_mgy_encode) */
13325 
13326 #if !defined(HAVE_native_mpfq_fixmp_12_mgy_decode)
13327 /* x, z, invR, and p have 12 words.
13328  * Assuming R=W^13 is the redc modulus, we compute z=x/R mod p. */
13329 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
13330 static inline
mpfq_fixmp_12_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)13331 void mpfq_fixmp_12_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
13332 {
13333     mp_limb_t t[24];
13334     mpfq_fixmp_12_mul(t, x, invR);
13335     mpfq_fixmp_12_mod(z, t, p);
13336 }
13337 #endif /* !defined(HAVE_native_mpfq_fixmp_12_mgy_decode) */
13338 
13339 #if !defined(HAVE_native_mpfq_fixmp_12_lshift)
13340 /* a has 12 words. Shift it in place by cnt bits to the left.
13341  * The shift count cnt must not exceed the word size.
13342  * Note that no carry is returned for the bits shifted out. */
13343 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
13344 static inline
mpfq_fixmp_12_lshift(mp_limb_t * a,int cnt)13345 void mpfq_fixmp_12_lshift(mp_limb_t * a, int cnt)
13346 {
13347     if (!cnt) return;
13348     int i;
13349     int dnt = GMP_NUMB_BITS - cnt;
13350     for (i = 12-1; i>0; --i) {
13351         a[i] <<= cnt;
13352         a[i] |= (a[i-1] >> dnt);
13353     }
13354     a[0] <<= cnt;
13355 }
13356 #endif /* !defined(HAVE_native_mpfq_fixmp_12_lshift) */
13357 
13358 #if !defined(HAVE_native_mpfq_fixmp_13_add)
13359 /* x, y, and z have 13 words. Result in z. Return carry bit */
13360 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
13361 /* Triggered by: 13_invmod, 13_redc, 13_redc_ur */
13362 static inline
mpfq_fixmp_13_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)13363 mp_limb_t mpfq_fixmp_13_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
13364 {
13365     mp_limb_t r, s, t, cy, cy1, cy2;
13366     cy = 0;
13367     r = x[0];
13368     s = r + y[0];
13369     cy1 = s < r;
13370     t = s + cy;
13371     cy2 = t < s;
13372     cy = cy1 | cy2;
13373     z[0] = t;
13374     r = x[1];
13375     s = r + y[1];
13376     cy1 = s < r;
13377     t = s + cy;
13378     cy2 = t < s;
13379     cy = cy1 | cy2;
13380     z[1] = t;
13381     r = x[2];
13382     s = r + y[2];
13383     cy1 = s < r;
13384     t = s + cy;
13385     cy2 = t < s;
13386     cy = cy1 | cy2;
13387     z[2] = t;
13388     r = x[3];
13389     s = r + y[3];
13390     cy1 = s < r;
13391     t = s + cy;
13392     cy2 = t < s;
13393     cy = cy1 | cy2;
13394     z[3] = t;
13395     r = x[4];
13396     s = r + y[4];
13397     cy1 = s < r;
13398     t = s + cy;
13399     cy2 = t < s;
13400     cy = cy1 | cy2;
13401     z[4] = t;
13402     r = x[5];
13403     s = r + y[5];
13404     cy1 = s < r;
13405     t = s + cy;
13406     cy2 = t < s;
13407     cy = cy1 | cy2;
13408     z[5] = t;
13409     r = x[6];
13410     s = r + y[6];
13411     cy1 = s < r;
13412     t = s + cy;
13413     cy2 = t < s;
13414     cy = cy1 | cy2;
13415     z[6] = t;
13416     r = x[7];
13417     s = r + y[7];
13418     cy1 = s < r;
13419     t = s + cy;
13420     cy2 = t < s;
13421     cy = cy1 | cy2;
13422     z[7] = t;
13423     r = x[8];
13424     s = r + y[8];
13425     cy1 = s < r;
13426     t = s + cy;
13427     cy2 = t < s;
13428     cy = cy1 | cy2;
13429     z[8] = t;
13430     r = x[9];
13431     s = r + y[9];
13432     cy1 = s < r;
13433     t = s + cy;
13434     cy2 = t < s;
13435     cy = cy1 | cy2;
13436     z[9] = t;
13437     r = x[10];
13438     s = r + y[10];
13439     cy1 = s < r;
13440     t = s + cy;
13441     cy2 = t < s;
13442     cy = cy1 | cy2;
13443     z[10] = t;
13444     r = x[11];
13445     s = r + y[11];
13446     cy1 = s < r;
13447     t = s + cy;
13448     cy2 = t < s;
13449     cy = cy1 | cy2;
13450     z[11] = t;
13451     r = x[12];
13452     s = r + y[12];
13453     cy1 = s < r;
13454     t = s + cy;
13455     cy2 = t < s;
13456     cy = cy1 | cy2;
13457     z[12] = t;
13458     return cy;
13459 }
13460 #endif /* !defined(HAVE_native_mpfq_fixmp_13_add) */
13461 
13462 #if !defined(HAVE_native_mpfq_fixmp_13_sub)
13463 /* x, y, and z have 13 words. Result in z. Return borrow bit */
13464 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
13465 /* Triggered by: 13_invmod, 13_redc */
13466 static inline
mpfq_fixmp_13_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)13467 mp_limb_t mpfq_fixmp_13_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
13468 {
13469     mp_limb_t r, s, t, cy, cy1, cy2;
13470     cy = 0;
13471     r = x[0];
13472     s = r - y[0];
13473     cy1 = s > r;
13474     t = s - cy;
13475     cy2 = t > s;
13476     cy = cy1 | cy2;
13477     z[0] = t;
13478     r = x[1];
13479     s = r - y[1];
13480     cy1 = s > r;
13481     t = s - cy;
13482     cy2 = t > s;
13483     cy = cy1 | cy2;
13484     z[1] = t;
13485     r = x[2];
13486     s = r - y[2];
13487     cy1 = s > r;
13488     t = s - cy;
13489     cy2 = t > s;
13490     cy = cy1 | cy2;
13491     z[2] = t;
13492     r = x[3];
13493     s = r - y[3];
13494     cy1 = s > r;
13495     t = s - cy;
13496     cy2 = t > s;
13497     cy = cy1 | cy2;
13498     z[3] = t;
13499     r = x[4];
13500     s = r - y[4];
13501     cy1 = s > r;
13502     t = s - cy;
13503     cy2 = t > s;
13504     cy = cy1 | cy2;
13505     z[4] = t;
13506     r = x[5];
13507     s = r - y[5];
13508     cy1 = s > r;
13509     t = s - cy;
13510     cy2 = t > s;
13511     cy = cy1 | cy2;
13512     z[5] = t;
13513     r = x[6];
13514     s = r - y[6];
13515     cy1 = s > r;
13516     t = s - cy;
13517     cy2 = t > s;
13518     cy = cy1 | cy2;
13519     z[6] = t;
13520     r = x[7];
13521     s = r - y[7];
13522     cy1 = s > r;
13523     t = s - cy;
13524     cy2 = t > s;
13525     cy = cy1 | cy2;
13526     z[7] = t;
13527     r = x[8];
13528     s = r - y[8];
13529     cy1 = s > r;
13530     t = s - cy;
13531     cy2 = t > s;
13532     cy = cy1 | cy2;
13533     z[8] = t;
13534     r = x[9];
13535     s = r - y[9];
13536     cy1 = s > r;
13537     t = s - cy;
13538     cy2 = t > s;
13539     cy = cy1 | cy2;
13540     z[9] = t;
13541     r = x[10];
13542     s = r - y[10];
13543     cy1 = s > r;
13544     t = s - cy;
13545     cy2 = t > s;
13546     cy = cy1 | cy2;
13547     z[10] = t;
13548     r = x[11];
13549     s = r - y[11];
13550     cy1 = s > r;
13551     t = s - cy;
13552     cy2 = t > s;
13553     cy = cy1 | cy2;
13554     z[11] = t;
13555     r = x[12];
13556     s = r - y[12];
13557     cy1 = s > r;
13558     t = s - cy;
13559     cy2 = t > s;
13560     cy = cy1 | cy2;
13561     z[12] = t;
13562     return cy;
13563 }
13564 #endif /* !defined(HAVE_native_mpfq_fixmp_13_sub) */
13565 
13566 #if !defined(HAVE_native_mpfq_fixmp_13_add_nc)
13567 /* x, y, and z have 13 words. Result in z. Carry bit is lost. */
13568 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
13569 static inline
mpfq_fixmp_13_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)13570 void mpfq_fixmp_13_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
13571 {
13572     mp_limb_t r, s, t, cy, cy1, cy2;
13573     cy = 0;
13574     r = x[0];
13575     s = r + y[0];
13576     cy1 = s < r;
13577     t = s + cy;
13578     cy2 = t < s;
13579     cy = cy1 | cy2;
13580     z[0] = t;
13581     r = x[1];
13582     s = r + y[1];
13583     cy1 = s < r;
13584     t = s + cy;
13585     cy2 = t < s;
13586     cy = cy1 | cy2;
13587     z[1] = t;
13588     r = x[2];
13589     s = r + y[2];
13590     cy1 = s < r;
13591     t = s + cy;
13592     cy2 = t < s;
13593     cy = cy1 | cy2;
13594     z[2] = t;
13595     r = x[3];
13596     s = r + y[3];
13597     cy1 = s < r;
13598     t = s + cy;
13599     cy2 = t < s;
13600     cy = cy1 | cy2;
13601     z[3] = t;
13602     r = x[4];
13603     s = r + y[4];
13604     cy1 = s < r;
13605     t = s + cy;
13606     cy2 = t < s;
13607     cy = cy1 | cy2;
13608     z[4] = t;
13609     r = x[5];
13610     s = r + y[5];
13611     cy1 = s < r;
13612     t = s + cy;
13613     cy2 = t < s;
13614     cy = cy1 | cy2;
13615     z[5] = t;
13616     r = x[6];
13617     s = r + y[6];
13618     cy1 = s < r;
13619     t = s + cy;
13620     cy2 = t < s;
13621     cy = cy1 | cy2;
13622     z[6] = t;
13623     r = x[7];
13624     s = r + y[7];
13625     cy1 = s < r;
13626     t = s + cy;
13627     cy2 = t < s;
13628     cy = cy1 | cy2;
13629     z[7] = t;
13630     r = x[8];
13631     s = r + y[8];
13632     cy1 = s < r;
13633     t = s + cy;
13634     cy2 = t < s;
13635     cy = cy1 | cy2;
13636     z[8] = t;
13637     r = x[9];
13638     s = r + y[9];
13639     cy1 = s < r;
13640     t = s + cy;
13641     cy2 = t < s;
13642     cy = cy1 | cy2;
13643     z[9] = t;
13644     r = x[10];
13645     s = r + y[10];
13646     cy1 = s < r;
13647     t = s + cy;
13648     cy2 = t < s;
13649     cy = cy1 | cy2;
13650     z[10] = t;
13651     r = x[11];
13652     s = r + y[11];
13653     cy1 = s < r;
13654     t = s + cy;
13655     cy2 = t < s;
13656     cy = cy1 | cy2;
13657     z[11] = t;
13658     r = x[12];
13659     s = r + y[12];
13660     cy1 = s < r;
13661     t = s + cy;
13662     cy2 = t < s;
13663     cy = cy1 | cy2;
13664     z[12] = t;
13665 }
13666 #endif /* !defined(HAVE_native_mpfq_fixmp_13_add_nc) */
13667 
13668 #if !defined(HAVE_native_mpfq_fixmp_13_sub_nc)
13669 /* x, y, and z have 13 words. Result in z. Borrow bit is lost. */
13670 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
13671 static inline
mpfq_fixmp_13_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)13672 void mpfq_fixmp_13_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
13673 {
13674     mp_limb_t r, s, t, cy, cy1, cy2;
13675     cy = 0;
13676     r = x[0];
13677     s = r - y[0];
13678     cy1 = s > r;
13679     t = s - cy;
13680     cy2 = t > s;
13681     cy = cy1 | cy2;
13682     z[0] = t;
13683     r = x[1];
13684     s = r - y[1];
13685     cy1 = s > r;
13686     t = s - cy;
13687     cy2 = t > s;
13688     cy = cy1 | cy2;
13689     z[1] = t;
13690     r = x[2];
13691     s = r - y[2];
13692     cy1 = s > r;
13693     t = s - cy;
13694     cy2 = t > s;
13695     cy = cy1 | cy2;
13696     z[2] = t;
13697     r = x[3];
13698     s = r - y[3];
13699     cy1 = s > r;
13700     t = s - cy;
13701     cy2 = t > s;
13702     cy = cy1 | cy2;
13703     z[3] = t;
13704     r = x[4];
13705     s = r - y[4];
13706     cy1 = s > r;
13707     t = s - cy;
13708     cy2 = t > s;
13709     cy = cy1 | cy2;
13710     z[4] = t;
13711     r = x[5];
13712     s = r - y[5];
13713     cy1 = s > r;
13714     t = s - cy;
13715     cy2 = t > s;
13716     cy = cy1 | cy2;
13717     z[5] = t;
13718     r = x[6];
13719     s = r - y[6];
13720     cy1 = s > r;
13721     t = s - cy;
13722     cy2 = t > s;
13723     cy = cy1 | cy2;
13724     z[6] = t;
13725     r = x[7];
13726     s = r - y[7];
13727     cy1 = s > r;
13728     t = s - cy;
13729     cy2 = t > s;
13730     cy = cy1 | cy2;
13731     z[7] = t;
13732     r = x[8];
13733     s = r - y[8];
13734     cy1 = s > r;
13735     t = s - cy;
13736     cy2 = t > s;
13737     cy = cy1 | cy2;
13738     z[8] = t;
13739     r = x[9];
13740     s = r - y[9];
13741     cy1 = s > r;
13742     t = s - cy;
13743     cy2 = t > s;
13744     cy = cy1 | cy2;
13745     z[9] = t;
13746     r = x[10];
13747     s = r - y[10];
13748     cy1 = s > r;
13749     t = s - cy;
13750     cy2 = t > s;
13751     cy = cy1 | cy2;
13752     z[10] = t;
13753     r = x[11];
13754     s = r - y[11];
13755     cy1 = s > r;
13756     t = s - cy;
13757     cy2 = t > s;
13758     cy = cy1 | cy2;
13759     z[11] = t;
13760     r = x[12];
13761     s = r - y[12];
13762     cy1 = s > r;
13763     t = s - cy;
13764     cy2 = t > s;
13765     cy = cy1 | cy2;
13766     z[12] = t;
13767 }
13768 #endif /* !defined(HAVE_native_mpfq_fixmp_13_sub_nc) */
13769 
13770 #if !defined(HAVE_native_mpfq_fixmp_13_add_ui)
13771 /* x, y, and z have 13 words. Result in z. Return carry bit */
13772 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
13773 static inline
mpfq_fixmp_13_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)13774 mp_limb_t mpfq_fixmp_13_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
13775 {
13776     mp_limb_t r, s, t, cy, cy1, cy2;
13777     cy = 0;
13778     r = x[0];
13779     s = r + y;
13780     cy1 = s < r;
13781     t = s + cy;
13782     cy2 = t < s;
13783     cy = cy1 | cy2;
13784     z[0] = t;
13785     s = x[1];
13786     t = s + cy;
13787     cy = t < s;
13788     z[1] = t;
13789     s = x[2];
13790     t = s + cy;
13791     cy = t < s;
13792     z[2] = t;
13793     s = x[3];
13794     t = s + cy;
13795     cy = t < s;
13796     z[3] = t;
13797     s = x[4];
13798     t = s + cy;
13799     cy = t < s;
13800     z[4] = t;
13801     s = x[5];
13802     t = s + cy;
13803     cy = t < s;
13804     z[5] = t;
13805     s = x[6];
13806     t = s + cy;
13807     cy = t < s;
13808     z[6] = t;
13809     s = x[7];
13810     t = s + cy;
13811     cy = t < s;
13812     z[7] = t;
13813     s = x[8];
13814     t = s + cy;
13815     cy = t < s;
13816     z[8] = t;
13817     s = x[9];
13818     t = s + cy;
13819     cy = t < s;
13820     z[9] = t;
13821     s = x[10];
13822     t = s + cy;
13823     cy = t < s;
13824     z[10] = t;
13825     s = x[11];
13826     t = s + cy;
13827     cy = t < s;
13828     z[11] = t;
13829     s = x[12];
13830     t = s + cy;
13831     cy = t < s;
13832     z[12] = t;
13833     return cy;
13834 }
13835 #endif /* !defined(HAVE_native_mpfq_fixmp_13_add_ui) */
13836 
13837 #if !defined(HAVE_native_mpfq_fixmp_13_sub_ui)
13838 /* x, y, and z have 13 words. Result in z. Return borrow bit */
13839 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
13840 static inline
mpfq_fixmp_13_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)13841 mp_limb_t mpfq_fixmp_13_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
13842 {
13843     mp_limb_t r, s, t, cy, cy1, cy2;
13844     cy = 0;
13845     r = x[0];
13846     s = r - y;
13847     cy1 = s > r;
13848     t = s - cy;
13849     cy2 = t > s;
13850     cy = cy1 | cy2;
13851     z[0] = t;
13852     s = x[1];
13853     t = s - cy;
13854     cy = t > s;
13855     z[1] = t;
13856     s = x[2];
13857     t = s - cy;
13858     cy = t > s;
13859     z[2] = t;
13860     s = x[3];
13861     t = s - cy;
13862     cy = t > s;
13863     z[3] = t;
13864     s = x[4];
13865     t = s - cy;
13866     cy = t > s;
13867     z[4] = t;
13868     s = x[5];
13869     t = s - cy;
13870     cy = t > s;
13871     z[5] = t;
13872     s = x[6];
13873     t = s - cy;
13874     cy = t > s;
13875     z[6] = t;
13876     s = x[7];
13877     t = s - cy;
13878     cy = t > s;
13879     z[7] = t;
13880     s = x[8];
13881     t = s - cy;
13882     cy = t > s;
13883     z[8] = t;
13884     s = x[9];
13885     t = s - cy;
13886     cy = t > s;
13887     z[9] = t;
13888     s = x[10];
13889     t = s - cy;
13890     cy = t > s;
13891     z[10] = t;
13892     s = x[11];
13893     t = s - cy;
13894     cy = t > s;
13895     z[11] = t;
13896     s = x[12];
13897     t = s - cy;
13898     cy = t > s;
13899     z[12] = t;
13900     return cy;
13901 }
13902 #endif /* !defined(HAVE_native_mpfq_fixmp_13_sub_ui) */
13903 
13904 #if !defined(HAVE_native_mpfq_fixmp_13_add_ui_nc)
13905 /* x, y, and z have 13 words. Result in z. Carry bit is lost. */
13906 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
13907 static inline
mpfq_fixmp_13_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)13908 void mpfq_fixmp_13_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
13909 {
13910     mp_limb_t r, s, t, cy, cy1, cy2;
13911     cy = 0;
13912     r = x[0];
13913     s = r + y;
13914     cy1 = s < r;
13915     t = s + cy;
13916     cy2 = t < s;
13917     cy = cy1 | cy2;
13918     z[0] = t;
13919     s = x[1];
13920     t = s + cy;
13921     cy = t < s;
13922     z[1] = t;
13923     s = x[2];
13924     t = s + cy;
13925     cy = t < s;
13926     z[2] = t;
13927     s = x[3];
13928     t = s + cy;
13929     cy = t < s;
13930     z[3] = t;
13931     s = x[4];
13932     t = s + cy;
13933     cy = t < s;
13934     z[4] = t;
13935     s = x[5];
13936     t = s + cy;
13937     cy = t < s;
13938     z[5] = t;
13939     s = x[6];
13940     t = s + cy;
13941     cy = t < s;
13942     z[6] = t;
13943     s = x[7];
13944     t = s + cy;
13945     cy = t < s;
13946     z[7] = t;
13947     s = x[8];
13948     t = s + cy;
13949     cy = t < s;
13950     z[8] = t;
13951     s = x[9];
13952     t = s + cy;
13953     cy = t < s;
13954     z[9] = t;
13955     s = x[10];
13956     t = s + cy;
13957     cy = t < s;
13958     z[10] = t;
13959     s = x[11];
13960     t = s + cy;
13961     cy = t < s;
13962     z[11] = t;
13963     s = x[12];
13964     t = s + cy;
13965     cy = t < s;
13966     z[12] = t;
13967 }
13968 #endif /* !defined(HAVE_native_mpfq_fixmp_13_add_ui_nc) */
13969 
13970 #if !defined(HAVE_native_mpfq_fixmp_13_sub_ui_nc)
13971 /* x, y, and z have 13 words. Result in z. Borrow bit is lost. */
13972 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
13973 static inline
mpfq_fixmp_13_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)13974 void mpfq_fixmp_13_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
13975 {
13976     mp_limb_t r, s, t, cy, cy1, cy2;
13977     cy = 0;
13978     r = x[0];
13979     s = r - y;
13980     cy1 = s > r;
13981     t = s - cy;
13982     cy2 = t > s;
13983     cy = cy1 | cy2;
13984     z[0] = t;
13985     s = x[1];
13986     t = s - cy;
13987     cy = t > s;
13988     z[1] = t;
13989     s = x[2];
13990     t = s - cy;
13991     cy = t > s;
13992     z[2] = t;
13993     s = x[3];
13994     t = s - cy;
13995     cy = t > s;
13996     z[3] = t;
13997     s = x[4];
13998     t = s - cy;
13999     cy = t > s;
14000     z[4] = t;
14001     s = x[5];
14002     t = s - cy;
14003     cy = t > s;
14004     z[5] = t;
14005     s = x[6];
14006     t = s - cy;
14007     cy = t > s;
14008     z[6] = t;
14009     s = x[7];
14010     t = s - cy;
14011     cy = t > s;
14012     z[7] = t;
14013     s = x[8];
14014     t = s - cy;
14015     cy = t > s;
14016     z[8] = t;
14017     s = x[9];
14018     t = s - cy;
14019     cy = t > s;
14020     z[9] = t;
14021     s = x[10];
14022     t = s - cy;
14023     cy = t > s;
14024     z[10] = t;
14025     s = x[11];
14026     t = s - cy;
14027     cy = t > s;
14028     z[11] = t;
14029     s = x[12];
14030     t = s - cy;
14031     cy = t > s;
14032     z[12] = t;
14033 }
14034 #endif /* !defined(HAVE_native_mpfq_fixmp_13_sub_ui_nc) */
14035 
14036 #if !defined(HAVE_native_mpfq_fixmp_13_cmp)
14037 /* x and y have 13 words. Return sign of difference x-y. */
14038 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
14039 /* Triggered by: 13_invmod, 13_redc */
14040 static inline
mpfq_fixmp_13_cmp(const mp_limb_t * x,const mp_limb_t * y)14041 int mpfq_fixmp_13_cmp(const mp_limb_t * x, const mp_limb_t * y)
14042 {
14043     for (int i = 13-1; i >= 0; --i) {
14044         if (x[i] > y[i]) return 1;
14045         if (x[i] < y[i]) return -1;
14046     }
14047     return 0;
14048 }
14049 #endif /* !defined(HAVE_native_mpfq_fixmp_13_cmp) */
14050 
14051 #if !defined(HAVE_native_mpfq_fixmp_13_cmp_ui)
14052 /* x has 13 words. Return sign of difference x-y. */
14053 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
14054 /* Triggered by: 13_invmod */
14055 static inline
mpfq_fixmp_13_cmp_ui(const mp_limb_t * x,mp_limb_t y)14056 int mpfq_fixmp_13_cmp_ui(const mp_limb_t * x, mp_limb_t y)
14057 {
14058     for (int i = 13-1; i > 0; --i) {
14059         if (x[i]) return 1;
14060     }
14061     if (x[0]>y) return 1;
14062     if (x[0]<y) return -1;
14063     return 0;
14064 }
14065 #endif /* !defined(HAVE_native_mpfq_fixmp_13_cmp_ui) */
14066 
14067 #if !defined(HAVE_native_mpfq_fixmp_13_addmul1)
14068 /* x has 13 words, z has 15.
14069  * Put (z+x*c) in z. Return carry bit. */
14070 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
14071 /* Triggered by: 13_redc_ur */
14072 static inline
mpfq_fixmp_13_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)14073 mp_limb_t mpfq_fixmp_13_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
14074 {
14075     mp_limb_t hi, lo, carry, buf;
14076     carry = 0;
14077     mpfq_umul_ppmm(hi,lo,c,x[0]);
14078     lo += carry;
14079     carry = (lo<carry) + hi;
14080     buf = z[0];
14081     lo += buf;
14082     carry += (lo<buf);
14083     z[0] = lo;
14084     mpfq_umul_ppmm(hi,lo,c,x[1]);
14085     lo += carry;
14086     carry = (lo<carry) + hi;
14087     buf = z[1];
14088     lo += buf;
14089     carry += (lo<buf);
14090     z[1] = lo;
14091     mpfq_umul_ppmm(hi,lo,c,x[2]);
14092     lo += carry;
14093     carry = (lo<carry) + hi;
14094     buf = z[2];
14095     lo += buf;
14096     carry += (lo<buf);
14097     z[2] = lo;
14098     mpfq_umul_ppmm(hi,lo,c,x[3]);
14099     lo += carry;
14100     carry = (lo<carry) + hi;
14101     buf = z[3];
14102     lo += buf;
14103     carry += (lo<buf);
14104     z[3] = lo;
14105     mpfq_umul_ppmm(hi,lo,c,x[4]);
14106     lo += carry;
14107     carry = (lo<carry) + hi;
14108     buf = z[4];
14109     lo += buf;
14110     carry += (lo<buf);
14111     z[4] = lo;
14112     mpfq_umul_ppmm(hi,lo,c,x[5]);
14113     lo += carry;
14114     carry = (lo<carry) + hi;
14115     buf = z[5];
14116     lo += buf;
14117     carry += (lo<buf);
14118     z[5] = lo;
14119     mpfq_umul_ppmm(hi,lo,c,x[6]);
14120     lo += carry;
14121     carry = (lo<carry) + hi;
14122     buf = z[6];
14123     lo += buf;
14124     carry += (lo<buf);
14125     z[6] = lo;
14126     mpfq_umul_ppmm(hi,lo,c,x[7]);
14127     lo += carry;
14128     carry = (lo<carry) + hi;
14129     buf = z[7];
14130     lo += buf;
14131     carry += (lo<buf);
14132     z[7] = lo;
14133     mpfq_umul_ppmm(hi,lo,c,x[8]);
14134     lo += carry;
14135     carry = (lo<carry) + hi;
14136     buf = z[8];
14137     lo += buf;
14138     carry += (lo<buf);
14139     z[8] = lo;
14140     mpfq_umul_ppmm(hi,lo,c,x[9]);
14141     lo += carry;
14142     carry = (lo<carry) + hi;
14143     buf = z[9];
14144     lo += buf;
14145     carry += (lo<buf);
14146     z[9] = lo;
14147     mpfq_umul_ppmm(hi,lo,c,x[10]);
14148     lo += carry;
14149     carry = (lo<carry) + hi;
14150     buf = z[10];
14151     lo += buf;
14152     carry += (lo<buf);
14153     z[10] = lo;
14154     mpfq_umul_ppmm(hi,lo,c,x[11]);
14155     lo += carry;
14156     carry = (lo<carry) + hi;
14157     buf = z[11];
14158     lo += buf;
14159     carry += (lo<buf);
14160     z[11] = lo;
14161     mpfq_umul_ppmm(hi,lo,c,x[12]);
14162     lo += carry;
14163     carry = (lo<carry) + hi;
14164     buf = z[12];
14165     lo += buf;
14166     carry += (lo<buf);
14167     z[12] = lo;
14168     z[13] += carry;
14169     return (z[13]<carry);
14170 }
14171 #endif /* !defined(HAVE_native_mpfq_fixmp_13_addmul1) */
14172 
14173 #if !defined(HAVE_native_mpfq_fixmp_13_addmul1_nc)
14174 /* x has 13 words, z has 15.
14175  * Put (z+x*c) in z. Carry bit is lost. */
14176 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
14177 /* Triggered by: 13_mul, 13_mgy_decode, 14_sqr, 14_shortmul, 15_sqr, 15_shortmul, 13_5_sqr, 13_5_shortmul, 14_5_sqr, 14_5_shortmul */
14178 static inline
mpfq_fixmp_13_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)14179 void mpfq_fixmp_13_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
14180 {
14181     mp_limb_t hi, lo, carry, buf;
14182     carry = 0;
14183     mpfq_umul_ppmm(hi,lo,c,x[0]);
14184     lo += carry;
14185     carry = (lo<carry) + hi;
14186     buf = z[0];
14187     lo += buf;
14188     carry += (lo<buf);
14189     z[0] = lo;
14190     mpfq_umul_ppmm(hi,lo,c,x[1]);
14191     lo += carry;
14192     carry = (lo<carry) + hi;
14193     buf = z[1];
14194     lo += buf;
14195     carry += (lo<buf);
14196     z[1] = lo;
14197     mpfq_umul_ppmm(hi,lo,c,x[2]);
14198     lo += carry;
14199     carry = (lo<carry) + hi;
14200     buf = z[2];
14201     lo += buf;
14202     carry += (lo<buf);
14203     z[2] = lo;
14204     mpfq_umul_ppmm(hi,lo,c,x[3]);
14205     lo += carry;
14206     carry = (lo<carry) + hi;
14207     buf = z[3];
14208     lo += buf;
14209     carry += (lo<buf);
14210     z[3] = lo;
14211     mpfq_umul_ppmm(hi,lo,c,x[4]);
14212     lo += carry;
14213     carry = (lo<carry) + hi;
14214     buf = z[4];
14215     lo += buf;
14216     carry += (lo<buf);
14217     z[4] = lo;
14218     mpfq_umul_ppmm(hi,lo,c,x[5]);
14219     lo += carry;
14220     carry = (lo<carry) + hi;
14221     buf = z[5];
14222     lo += buf;
14223     carry += (lo<buf);
14224     z[5] = lo;
14225     mpfq_umul_ppmm(hi,lo,c,x[6]);
14226     lo += carry;
14227     carry = (lo<carry) + hi;
14228     buf = z[6];
14229     lo += buf;
14230     carry += (lo<buf);
14231     z[6] = lo;
14232     mpfq_umul_ppmm(hi,lo,c,x[7]);
14233     lo += carry;
14234     carry = (lo<carry) + hi;
14235     buf = z[7];
14236     lo += buf;
14237     carry += (lo<buf);
14238     z[7] = lo;
14239     mpfq_umul_ppmm(hi,lo,c,x[8]);
14240     lo += carry;
14241     carry = (lo<carry) + hi;
14242     buf = z[8];
14243     lo += buf;
14244     carry += (lo<buf);
14245     z[8] = lo;
14246     mpfq_umul_ppmm(hi,lo,c,x[9]);
14247     lo += carry;
14248     carry = (lo<carry) + hi;
14249     buf = z[9];
14250     lo += buf;
14251     carry += (lo<buf);
14252     z[9] = lo;
14253     mpfq_umul_ppmm(hi,lo,c,x[10]);
14254     lo += carry;
14255     carry = (lo<carry) + hi;
14256     buf = z[10];
14257     lo += buf;
14258     carry += (lo<buf);
14259     z[10] = lo;
14260     mpfq_umul_ppmm(hi,lo,c,x[11]);
14261     lo += carry;
14262     carry = (lo<carry) + hi;
14263     buf = z[11];
14264     lo += buf;
14265     carry += (lo<buf);
14266     z[11] = lo;
14267     mpfq_umul_ppmm(hi,lo,c,x[12]);
14268     lo += carry;
14269     carry = (lo<carry) + hi;
14270     buf = z[12];
14271     lo += buf;
14272     carry += (lo<buf);
14273     z[12] = lo;
14274     z[13] += carry;
14275 }
14276 #endif /* !defined(HAVE_native_mpfq_fixmp_13_addmul1_nc) */
14277 
14278 #if !defined(HAVE_native_mpfq_fixmp_13_addmul1_shortz)
14279 /* x has 13 words, z has 14.
14280  * Put (z+x*c) in z. Return carry word. */
14281 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
14282 /* Triggered by: 13_redc */
14283 static inline
mpfq_fixmp_13_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)14284 mp_limb_t mpfq_fixmp_13_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
14285 {
14286     mp_limb_t hi, lo, carry, buf;
14287     carry = 0;
14288     mpfq_umul_ppmm(hi,lo,c,x[0]);
14289     lo += carry;
14290     carry = (lo<carry) + hi;
14291     buf = z[0];
14292     lo += buf;
14293     carry += (lo<buf);
14294     z[0] = lo;
14295     mpfq_umul_ppmm(hi,lo,c,x[1]);
14296     lo += carry;
14297     carry = (lo<carry) + hi;
14298     buf = z[1];
14299     lo += buf;
14300     carry += (lo<buf);
14301     z[1] = lo;
14302     mpfq_umul_ppmm(hi,lo,c,x[2]);
14303     lo += carry;
14304     carry = (lo<carry) + hi;
14305     buf = z[2];
14306     lo += buf;
14307     carry += (lo<buf);
14308     z[2] = lo;
14309     mpfq_umul_ppmm(hi,lo,c,x[3]);
14310     lo += carry;
14311     carry = (lo<carry) + hi;
14312     buf = z[3];
14313     lo += buf;
14314     carry += (lo<buf);
14315     z[3] = lo;
14316     mpfq_umul_ppmm(hi,lo,c,x[4]);
14317     lo += carry;
14318     carry = (lo<carry) + hi;
14319     buf = z[4];
14320     lo += buf;
14321     carry += (lo<buf);
14322     z[4] = lo;
14323     mpfq_umul_ppmm(hi,lo,c,x[5]);
14324     lo += carry;
14325     carry = (lo<carry) + hi;
14326     buf = z[5];
14327     lo += buf;
14328     carry += (lo<buf);
14329     z[5] = lo;
14330     mpfq_umul_ppmm(hi,lo,c,x[6]);
14331     lo += carry;
14332     carry = (lo<carry) + hi;
14333     buf = z[6];
14334     lo += buf;
14335     carry += (lo<buf);
14336     z[6] = lo;
14337     mpfq_umul_ppmm(hi,lo,c,x[7]);
14338     lo += carry;
14339     carry = (lo<carry) + hi;
14340     buf = z[7];
14341     lo += buf;
14342     carry += (lo<buf);
14343     z[7] = lo;
14344     mpfq_umul_ppmm(hi,lo,c,x[8]);
14345     lo += carry;
14346     carry = (lo<carry) + hi;
14347     buf = z[8];
14348     lo += buf;
14349     carry += (lo<buf);
14350     z[8] = lo;
14351     mpfq_umul_ppmm(hi,lo,c,x[9]);
14352     lo += carry;
14353     carry = (lo<carry) + hi;
14354     buf = z[9];
14355     lo += buf;
14356     carry += (lo<buf);
14357     z[9] = lo;
14358     mpfq_umul_ppmm(hi,lo,c,x[10]);
14359     lo += carry;
14360     carry = (lo<carry) + hi;
14361     buf = z[10];
14362     lo += buf;
14363     carry += (lo<buf);
14364     z[10] = lo;
14365     mpfq_umul_ppmm(hi,lo,c,x[11]);
14366     lo += carry;
14367     carry = (lo<carry) + hi;
14368     buf = z[11];
14369     lo += buf;
14370     carry += (lo<buf);
14371     z[11] = lo;
14372     mpfq_umul_ppmm(hi,lo,c,x[12]);
14373     lo += carry;
14374     carry = (lo<carry) + hi;
14375     buf = z[12];
14376     lo += buf;
14377     carry += (lo<buf);
14378     z[12] = lo;
14379     return carry;
14380 }
14381 #endif /* !defined(HAVE_native_mpfq_fixmp_13_addmul1_shortz) */
14382 
14383 #if !defined(HAVE_native_mpfq_fixmp_13_mul)
14384 /* x and y have 13 words, z has 28. Put x*y in z. */
14385 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
14386 /* Triggered by: 13_mgy_decode */
14387 static inline
mpfq_fixmp_13_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)14388 void mpfq_fixmp_13_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
14389 {
14390     assert(z != x && z != y);
14391     for (int i = 0; i < 26; z[i++] = 0) ;
14392     mpfq_fixmp_13_addmul1_nc (z + 0, x, y[0]);
14393     mpfq_fixmp_13_addmul1_nc (z + 1, x, y[1]);
14394     mpfq_fixmp_13_addmul1_nc (z + 2, x, y[2]);
14395     mpfq_fixmp_13_addmul1_nc (z + 3, x, y[3]);
14396     mpfq_fixmp_13_addmul1_nc (z + 4, x, y[4]);
14397     mpfq_fixmp_13_addmul1_nc (z + 5, x, y[5]);
14398     mpfq_fixmp_13_addmul1_nc (z + 6, x, y[6]);
14399     mpfq_fixmp_13_addmul1_nc (z + 7, x, y[7]);
14400     mpfq_fixmp_13_addmul1_nc (z + 8, x, y[8]);
14401     mpfq_fixmp_13_addmul1_nc (z + 9, x, y[9]);
14402     mpfq_fixmp_13_addmul1_nc (z + 10, x, y[10]);
14403     mpfq_fixmp_13_addmul1_nc (z + 11, x, y[11]);
14404     mpfq_fixmp_13_addmul1_nc (z + 12, x, y[12]);
14405 }
14406 #endif /* !defined(HAVE_native_mpfq_fixmp_13_mul) */
14407 
14408 #if !defined(HAVE_native_mpfq_fixmp_13_sqr)
14409 /* x has 13 words, z has 28. Put x*y in z. */
14410 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
14411 static inline
mpfq_fixmp_13_sqr(mp_limb_t * z,const mp_limb_t * x)14412 void mpfq_fixmp_13_sqr(mp_limb_t * z, const mp_limb_t * x)
14413 {
14414     mp_limb_t buf[26] = {0,};
14415     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
14416     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
14417     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
14418     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
14419     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
14420     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
14421     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
14422     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
14423     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
14424     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
14425     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
14426     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
14427     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
14428     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
14429     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
14430     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
14431     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
14432     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
14433     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
14434     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
14435     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
14436     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
14437     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
14438     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
14439     mpfq_umul_ppmm(z[2*12+1], z[2*12], x[12], x[12]);
14440     mpn_lshift(buf, buf, 26, 1);
14441     mpn_add_n(z, z, buf, 26);
14442 }
14443 #endif /* !defined(HAVE_native_mpfq_fixmp_13_sqr) */
14444 
14445 #if !defined(HAVE_native_mpfq_fixmp_13_mul1)
14446 /* x has 13 words, z has 15. Put x*y in z. */
14447 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
14448 static inline
mpfq_fixmp_13_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)14449 void mpfq_fixmp_13_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
14450 {
14451     mp_limb_t hi, lo, carry;
14452     carry = 0;
14453     mpfq_umul_ppmm(hi,lo,c,x[0]);
14454     lo += carry;
14455     carry = (lo<carry) + hi;
14456     z[0] = lo;
14457     mpfq_umul_ppmm(hi,lo,c,x[1]);
14458     lo += carry;
14459     carry = (lo<carry) + hi;
14460     z[1] = lo;
14461     mpfq_umul_ppmm(hi,lo,c,x[2]);
14462     lo += carry;
14463     carry = (lo<carry) + hi;
14464     z[2] = lo;
14465     mpfq_umul_ppmm(hi,lo,c,x[3]);
14466     lo += carry;
14467     carry = (lo<carry) + hi;
14468     z[3] = lo;
14469     mpfq_umul_ppmm(hi,lo,c,x[4]);
14470     lo += carry;
14471     carry = (lo<carry) + hi;
14472     z[4] = lo;
14473     mpfq_umul_ppmm(hi,lo,c,x[5]);
14474     lo += carry;
14475     carry = (lo<carry) + hi;
14476     z[5] = lo;
14477     mpfq_umul_ppmm(hi,lo,c,x[6]);
14478     lo += carry;
14479     carry = (lo<carry) + hi;
14480     z[6] = lo;
14481     mpfq_umul_ppmm(hi,lo,c,x[7]);
14482     lo += carry;
14483     carry = (lo<carry) + hi;
14484     z[7] = lo;
14485     mpfq_umul_ppmm(hi,lo,c,x[8]);
14486     lo += carry;
14487     carry = (lo<carry) + hi;
14488     z[8] = lo;
14489     mpfq_umul_ppmm(hi,lo,c,x[9]);
14490     lo += carry;
14491     carry = (lo<carry) + hi;
14492     z[9] = lo;
14493     mpfq_umul_ppmm(hi,lo,c,x[10]);
14494     lo += carry;
14495     carry = (lo<carry) + hi;
14496     z[10] = lo;
14497     mpfq_umul_ppmm(hi,lo,c,x[11]);
14498     lo += carry;
14499     carry = (lo<carry) + hi;
14500     z[11] = lo;
14501     mpfq_umul_ppmm(hi,lo,c,x[12]);
14502     lo += carry;
14503     carry = (lo<carry) + hi;
14504     z[12] = lo;
14505     z[13] = carry;
14506 }
14507 #endif /* !defined(HAVE_native_mpfq_fixmp_13_mul1) */
14508 
14509 #if !defined(HAVE_native_mpfq_fixmp_13_shortmul)
14510 /* x and y have 13 words, z has 14.
14511  * Put the low 14 words of x*y in z. */
14512 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
14513 static inline
mpfq_fixmp_13_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)14514 void mpfq_fixmp_13_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
14515 {
14516     mpfq_zero(z, 13);
14517     mpfq_fixmp_12_addmul1_nc (z+0, x, y[0]);
14518     z[13-1] += x[12]*y[0];
14519     mpfq_fixmp_11_addmul1_nc (z+1, x, y[1]);
14520     z[13-1] += x[11]*y[1];
14521     mpfq_fixmp_10_addmul1_nc (z+2, x, y[2]);
14522     z[13-1] += x[10]*y[2];
14523     mpfq_fixmp_9_addmul1_nc (z+3, x, y[3]);
14524     z[13-1] += x[9]*y[3];
14525     mpfq_fixmp_8_addmul1_nc (z+4, x, y[4]);
14526     z[13-1] += x[8]*y[4];
14527     mpfq_fixmp_7_addmul1_nc (z+5, x, y[5]);
14528     z[13-1] += x[7]*y[5];
14529     mpfq_fixmp_6_addmul1_nc (z+6, x, y[6]);
14530     z[13-1] += x[6]*y[6];
14531     mpfq_fixmp_5_addmul1_nc (z+7, x, y[7]);
14532     z[13-1] += x[5]*y[7];
14533     mpfq_fixmp_4_addmul1_nc (z+8, x, y[8]);
14534     z[13-1] += x[4]*y[8];
14535     mpfq_fixmp_3_addmul1_nc (z+9, x, y[9]);
14536     z[13-1] += x[3]*y[9];
14537     mpfq_fixmp_2_addmul1_nc (z+10, x, y[10]);
14538     z[13-1] += x[2]*y[10];
14539     mpfq_fixmp_1_addmul1_nc (z+11, x, y[11]);
14540     z[13-1] += x[1]*y[11];
14541     z[13-1] += x[0]*y[13-1];
14542 }
14543 #endif /* !defined(HAVE_native_mpfq_fixmp_13_shortmul) */
14544 
14545 #if !defined(HAVE_native_mpfq_fixmp_13_mod)
14546 /* x has 28 words. z and p have 13 words, and the high word of p is non-zero.
14547  * Put x mod p in z. */
14548 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
14549 /* Triggered by: 13_mgy_decode */
14550 static inline
mpfq_fixmp_13_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)14551 void mpfq_fixmp_13_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
14552 {
14553     mp_limb_t q[13+1], r[13];
14554     assert (p[13-1] != 0);
14555     mpn_tdiv_qr(q, r, 0, x, 26, p, 13);
14556     mpfq_copy(z, r, 13);
14557 }
14558 #endif /* !defined(HAVE_native_mpfq_fixmp_13_mod) */
14559 
14560 #if !defined(HAVE_native_mpfq_fixmp_13_rshift)
14561 /* a has 13 words. Shift it in place by cnt bits to the right.
14562  * The shift count cnt must not exceed the word size.
14563  * Note that no carry is returned for the bits shifted out. */
14564 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
14565 /* Triggered by: 13_invmod */
14566 static inline
mpfq_fixmp_13_rshift(mp_limb_t * a,int cnt)14567 void mpfq_fixmp_13_rshift(mp_limb_t * a, int cnt)
14568 {
14569     if (!cnt) return;
14570     int i;
14571     int dnt = GMP_NUMB_BITS - cnt;
14572     for (i = 0; i < 13-1; ++i) {
14573         a[i] >>= cnt;
14574         a[i] |= (a[i+1] << dnt);
14575     }
14576     a[13-1] >>= cnt;
14577 }
14578 #endif /* !defined(HAVE_native_mpfq_fixmp_13_rshift) */
14579 
14580 #if !defined(HAVE_native_mpfq_fixmp_13_long_rshift)
14581 /* a has 13 words. Shift it in place by off words plus cnt bits to the left.
14582  * Note that no carry is returned for the bits shifted out. */
14583 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
14584 /* Triggered by: 13_invmod */
14585 static inline
mpfq_fixmp_13_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)14586 void mpfq_fixmp_13_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
14587 {
14588     if (cnt) {
14589         int dnt = GMP_NUMB_BITS - cnt;
14590         for (int i = 0; i < 13 - off - 1; ++i) {
14591             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
14592         }
14593         a[13-off-1] = a[13-1]>>cnt;
14594     } else {
14595         mpfq_copyi(a, a + off, 13 - off);
14596     }
14597     mpfq_zero(a + 13 - off, off);
14598 }
14599 #endif /* !defined(HAVE_native_mpfq_fixmp_13_long_rshift) */
14600 
14601 #if !defined(HAVE_native_mpfq_fixmp_13_long_lshift)
14602 /* a has 13 words. Shift it in place by off words plus cnt bits to the left.
14603  * Note that no carry is returned for the bits shifted out. */
14604 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
14605 /* Triggered by: 13_invmod */
14606 static inline
mpfq_fixmp_13_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)14607 void mpfq_fixmp_13_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
14608 {
14609     int i;
14610     if (cnt) {
14611         int dnt = GMP_NUMB_BITS - cnt;
14612         for (i = 13-1; i>off; --i) {
14613             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
14614         }
14615         a[off] = a[0]<<cnt;
14616     } else {
14617         mpfq_copyd(a + off, a, 13 - off);
14618     }
14619     mpfq_zero(a, off);
14620 }
14621 #endif /* !defined(HAVE_native_mpfq_fixmp_13_long_lshift) */
14622 
14623 #if !defined(HAVE_native_mpfq_fixmp_13_invmod)
14624 /* x, z, and p have 13 words. Put inverse of x mod p in z.
14625  * Return non-zero if an inverse could be found.
14626  * If no inverse could be found, return 0 and set z to zero.
14627  */
14628 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
14629 static inline
mpfq_fixmp_13_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)14630 int mpfq_fixmp_13_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
14631 {
14632       mp_limb_t u[13], v[13], a[13], b[13], fix[13];
14633       int i, t, lsh;
14634 
14635       mpfq_zero(u, 13);
14636       mpfq_zero(v, 13);
14637       mpfq_copy(a, x, 13);
14638       mpfq_copy(b, p, 13);
14639       u[0] = 1UL;
14640 
14641       if (mpfq_fixmp_13_cmp(a, v) == 0 || mpfq_fixmp_13_cmp(a, b) == 0) {
14642         mpfq_zero(res, 13);
14643         return 0;
14644       }
14645 
14646       mpfq_fixmp_13_add(fix, b, u);
14647       mpfq_fixmp_13_rshift(fix, 1);
14648 
14649       assert (mpfq_fixmp_13_cmp(a,b) < 0);
14650 
14651       t = 0;
14652 
14653       for(i = 0 ; !a[i] ; i++) ;
14654       assert (i < 13);
14655       lsh = mpfq_ctzl(a[i]);
14656       mpfq_fixmp_13_long_rshift(a, i, lsh);
14657       t += lsh + i*GMP_NUMB_BITS;
14658       mpfq_fixmp_13_long_lshift(v, i, lsh);
14659 
14660       do {
14661         do {
14662           mpfq_fixmp_13_sub(b, b, a);
14663           mpfq_fixmp_13_add(v, v, u);
14664           for(i = 0 ; !b[i] ; i++) ;
14665           assert (i < 13);
14666           lsh = mpfq_ctzl(b[i]);
14667           mpfq_fixmp_13_long_rshift(b, i, lsh);
14668           t += lsh + i*GMP_NUMB_BITS;
14669           mpfq_fixmp_13_long_lshift(u, i, lsh);
14670         } while (mpfq_fixmp_13_cmp(a,b) < 0);
14671         if (mpfq_fixmp_13_cmp(a, b) == 0)
14672           break;
14673         do {
14674           mpfq_fixmp_13_sub(a, a, b);
14675           mpfq_fixmp_13_add(u, u, v);
14676           for(i = 0 ; !a[i] ; i++) ;
14677           assert (i < 13);
14678           lsh = mpfq_ctzl(a[i]);
14679           mpfq_fixmp_13_long_rshift(a, i, lsh);
14680           t += lsh + i*GMP_NUMB_BITS;
14681           mpfq_fixmp_13_long_lshift(v, i, lsh);
14682         } while (mpfq_fixmp_13_cmp(b,a)<0);
14683       } while (mpfq_fixmp_13_cmp(a,b) != 0);
14684       {
14685         if (mpfq_fixmp_13_cmp_ui(a, 1) != 0) {
14686           mpfq_copy(res, a, 13);
14687           return 0;
14688         }
14689       }
14690       while (t>0) {
14691         mp_limb_t sig = u[0] & 1UL;
14692         mpfq_fixmp_13_rshift(u, 1);
14693         if (sig)
14694           mpfq_fixmp_13_add(u, u, fix);
14695         --t;
14696       }
14697       mpfq_copy(res, u, 13);
14698       return 1;
14699 }
14700 #endif /* !defined(HAVE_native_mpfq_fixmp_13_invmod) */
14701 
14702 #if !defined(HAVE_native_mpfq_fixmp_13_redc)
14703 /* x has 28 words, z and p have 13 words.
14704  * only one word is read from invp.
14705  * Assuming R=W^14 is the redc modulus, we expect that x verifies:
14706  *   x < R*p,
14707  * so that we have eventually z < p, z congruent to x/R mod p.
14708  * The contents of the area pointed by x are clobbered by this call.
14709  * Note also that x may alias z.
14710  */
14711 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
14712 static inline
mpfq_fixmp_13_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)14713 void mpfq_fixmp_13_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
14714 {
14715     mp_limb_t cy;
14716     for(int i = 0; i < 13; ++i) {
14717         mp_limb_t t = x[i]*mip[0];
14718         cy = mpfq_fixmp_13_addmul1_shortz(x+i, p, t);
14719         assert (x[i] == 0);
14720         x[i] = cy;
14721     }
14722     cy = mpfq_fixmp_13_add(x, x, x + 13);
14723     /* At this point, we have (x' denotes x + cy*W^n here)
14724     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
14725     * x'/R < p + p
14726     */
14727     if (cy || mpfq_fixmp_13_cmp(x, p) >= 0) {
14728         mpfq_fixmp_13_sub(z, x, p);
14729     } else {
14730         mpfq_copy(z, x, 13);
14731     }
14732 }
14733 #endif /* !defined(HAVE_native_mpfq_fixmp_13_redc) */
14734 
14735 #if !defined(HAVE_native_mpfq_fixmp_13_redc_ur)
14736 /* x has 29 words, z and p have 13 words.
14737  * only one word is read from invp.
14738  * Assuming R=W^14 is the redc modulus, we expect that x verifies:
14739  *  x < W*W^13*p = W^0.5*R*p or the hw case, W*R*p otherwise,
14740  * so that we have eventually z < p, z congruent to x/R mod p.
14741  * The contents of the area pointed by x are clobbered by this call.
14742  * Note also that x may alias z.
14743  */
14744 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
14745 static inline
mpfq_fixmp_13_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)14746 void mpfq_fixmp_13_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
14747 {
14748     mp_limb_t cy, q[2];
14749     for (int i = 0; i < 13; ++i) {
14750         mp_limb_t t = x[i]*mip[0];
14751         cy = mpfq_fixmp_13_addmul1(x+i, p, t);
14752         assert (x[i] == 0);
14753         x[i] = cy;
14754     }
14755     cy=mpfq_fixmp_13_add(x+13+1, x+13+1, x);
14756     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
14757     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
14758     * x'/R < (W+1)*p
14759     */
14760     if (cy) {
14761         /* x'/R-p < W*p, which fits in n+1 words */
14762         mpn_sub(x+13,x+13,13+1,p,13);
14763     }
14764     mpn_tdiv_qr(q, z, 0, x+13, 13+1, p, 13);
14765 }
14766 #endif /* !defined(HAVE_native_mpfq_fixmp_13_redc_ur) */
14767 
14768 #if !defined(HAVE_native_mpfq_fixmp_13_mgy_encode)
14769 /* x, z, and p have 13 words.
14770  * Assuming R=W^14 is the redc modulus, we compute z=R*x mod p. */
14771 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
14772 static inline
mpfq_fixmp_13_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)14773 void mpfq_fixmp_13_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
14774 {
14775     mp_limb_t t[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12] };
14776     mpfq_fixmp_13_mod(z, t, p);
14777 }
14778 #endif /* !defined(HAVE_native_mpfq_fixmp_13_mgy_encode) */
14779 
14780 #if !defined(HAVE_native_mpfq_fixmp_13_mgy_decode)
14781 /* x, z, invR, and p have 13 words.
14782  * Assuming R=W^14 is the redc modulus, we compute z=x/R mod p. */
14783 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
14784 static inline
mpfq_fixmp_13_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)14785 void mpfq_fixmp_13_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
14786 {
14787     mp_limb_t t[26];
14788     mpfq_fixmp_13_mul(t, x, invR);
14789     mpfq_fixmp_13_mod(z, t, p);
14790 }
14791 #endif /* !defined(HAVE_native_mpfq_fixmp_13_mgy_decode) */
14792 
14793 #if !defined(HAVE_native_mpfq_fixmp_13_lshift)
14794 /* a has 13 words. Shift it in place by cnt bits to the left.
14795  * The shift count cnt must not exceed the word size.
14796  * Note that no carry is returned for the bits shifted out. */
14797 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
14798 static inline
mpfq_fixmp_13_lshift(mp_limb_t * a,int cnt)14799 void mpfq_fixmp_13_lshift(mp_limb_t * a, int cnt)
14800 {
14801     if (!cnt) return;
14802     int i;
14803     int dnt = GMP_NUMB_BITS - cnt;
14804     for (i = 13-1; i>0; --i) {
14805         a[i] <<= cnt;
14806         a[i] |= (a[i-1] >> dnt);
14807     }
14808     a[0] <<= cnt;
14809 }
14810 #endif /* !defined(HAVE_native_mpfq_fixmp_13_lshift) */
14811 
14812 #if !defined(HAVE_native_mpfq_fixmp_14_add)
14813 /* x, y, and z have 14 words. Result in z. Return carry bit */
14814 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
14815 /* Triggered by: 14_invmod, 14_redc, 14_redc_ur */
14816 static inline
mpfq_fixmp_14_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)14817 mp_limb_t mpfq_fixmp_14_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
14818 {
14819     mp_limb_t r, s, t, cy, cy1, cy2;
14820     cy = 0;
14821     r = x[0];
14822     s = r + y[0];
14823     cy1 = s < r;
14824     t = s + cy;
14825     cy2 = t < s;
14826     cy = cy1 | cy2;
14827     z[0] = t;
14828     r = x[1];
14829     s = r + y[1];
14830     cy1 = s < r;
14831     t = s + cy;
14832     cy2 = t < s;
14833     cy = cy1 | cy2;
14834     z[1] = t;
14835     r = x[2];
14836     s = r + y[2];
14837     cy1 = s < r;
14838     t = s + cy;
14839     cy2 = t < s;
14840     cy = cy1 | cy2;
14841     z[2] = t;
14842     r = x[3];
14843     s = r + y[3];
14844     cy1 = s < r;
14845     t = s + cy;
14846     cy2 = t < s;
14847     cy = cy1 | cy2;
14848     z[3] = t;
14849     r = x[4];
14850     s = r + y[4];
14851     cy1 = s < r;
14852     t = s + cy;
14853     cy2 = t < s;
14854     cy = cy1 | cy2;
14855     z[4] = t;
14856     r = x[5];
14857     s = r + y[5];
14858     cy1 = s < r;
14859     t = s + cy;
14860     cy2 = t < s;
14861     cy = cy1 | cy2;
14862     z[5] = t;
14863     r = x[6];
14864     s = r + y[6];
14865     cy1 = s < r;
14866     t = s + cy;
14867     cy2 = t < s;
14868     cy = cy1 | cy2;
14869     z[6] = t;
14870     r = x[7];
14871     s = r + y[7];
14872     cy1 = s < r;
14873     t = s + cy;
14874     cy2 = t < s;
14875     cy = cy1 | cy2;
14876     z[7] = t;
14877     r = x[8];
14878     s = r + y[8];
14879     cy1 = s < r;
14880     t = s + cy;
14881     cy2 = t < s;
14882     cy = cy1 | cy2;
14883     z[8] = t;
14884     r = x[9];
14885     s = r + y[9];
14886     cy1 = s < r;
14887     t = s + cy;
14888     cy2 = t < s;
14889     cy = cy1 | cy2;
14890     z[9] = t;
14891     r = x[10];
14892     s = r + y[10];
14893     cy1 = s < r;
14894     t = s + cy;
14895     cy2 = t < s;
14896     cy = cy1 | cy2;
14897     z[10] = t;
14898     r = x[11];
14899     s = r + y[11];
14900     cy1 = s < r;
14901     t = s + cy;
14902     cy2 = t < s;
14903     cy = cy1 | cy2;
14904     z[11] = t;
14905     r = x[12];
14906     s = r + y[12];
14907     cy1 = s < r;
14908     t = s + cy;
14909     cy2 = t < s;
14910     cy = cy1 | cy2;
14911     z[12] = t;
14912     r = x[13];
14913     s = r + y[13];
14914     cy1 = s < r;
14915     t = s + cy;
14916     cy2 = t < s;
14917     cy = cy1 | cy2;
14918     z[13] = t;
14919     return cy;
14920 }
14921 #endif /* !defined(HAVE_native_mpfq_fixmp_14_add) */
14922 
14923 #if !defined(HAVE_native_mpfq_fixmp_14_sub)
14924 /* x, y, and z have 14 words. Result in z. Return borrow bit */
14925 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
14926 /* Triggered by: 14_invmod, 14_redc */
14927 static inline
mpfq_fixmp_14_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)14928 mp_limb_t mpfq_fixmp_14_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
14929 {
14930     mp_limb_t r, s, t, cy, cy1, cy2;
14931     cy = 0;
14932     r = x[0];
14933     s = r - y[0];
14934     cy1 = s > r;
14935     t = s - cy;
14936     cy2 = t > s;
14937     cy = cy1 | cy2;
14938     z[0] = t;
14939     r = x[1];
14940     s = r - y[1];
14941     cy1 = s > r;
14942     t = s - cy;
14943     cy2 = t > s;
14944     cy = cy1 | cy2;
14945     z[1] = t;
14946     r = x[2];
14947     s = r - y[2];
14948     cy1 = s > r;
14949     t = s - cy;
14950     cy2 = t > s;
14951     cy = cy1 | cy2;
14952     z[2] = t;
14953     r = x[3];
14954     s = r - y[3];
14955     cy1 = s > r;
14956     t = s - cy;
14957     cy2 = t > s;
14958     cy = cy1 | cy2;
14959     z[3] = t;
14960     r = x[4];
14961     s = r - y[4];
14962     cy1 = s > r;
14963     t = s - cy;
14964     cy2 = t > s;
14965     cy = cy1 | cy2;
14966     z[4] = t;
14967     r = x[5];
14968     s = r - y[5];
14969     cy1 = s > r;
14970     t = s - cy;
14971     cy2 = t > s;
14972     cy = cy1 | cy2;
14973     z[5] = t;
14974     r = x[6];
14975     s = r - y[6];
14976     cy1 = s > r;
14977     t = s - cy;
14978     cy2 = t > s;
14979     cy = cy1 | cy2;
14980     z[6] = t;
14981     r = x[7];
14982     s = r - y[7];
14983     cy1 = s > r;
14984     t = s - cy;
14985     cy2 = t > s;
14986     cy = cy1 | cy2;
14987     z[7] = t;
14988     r = x[8];
14989     s = r - y[8];
14990     cy1 = s > r;
14991     t = s - cy;
14992     cy2 = t > s;
14993     cy = cy1 | cy2;
14994     z[8] = t;
14995     r = x[9];
14996     s = r - y[9];
14997     cy1 = s > r;
14998     t = s - cy;
14999     cy2 = t > s;
15000     cy = cy1 | cy2;
15001     z[9] = t;
15002     r = x[10];
15003     s = r - y[10];
15004     cy1 = s > r;
15005     t = s - cy;
15006     cy2 = t > s;
15007     cy = cy1 | cy2;
15008     z[10] = t;
15009     r = x[11];
15010     s = r - y[11];
15011     cy1 = s > r;
15012     t = s - cy;
15013     cy2 = t > s;
15014     cy = cy1 | cy2;
15015     z[11] = t;
15016     r = x[12];
15017     s = r - y[12];
15018     cy1 = s > r;
15019     t = s - cy;
15020     cy2 = t > s;
15021     cy = cy1 | cy2;
15022     z[12] = t;
15023     r = x[13];
15024     s = r - y[13];
15025     cy1 = s > r;
15026     t = s - cy;
15027     cy2 = t > s;
15028     cy = cy1 | cy2;
15029     z[13] = t;
15030     return cy;
15031 }
15032 #endif /* !defined(HAVE_native_mpfq_fixmp_14_sub) */
15033 
15034 #if !defined(HAVE_native_mpfq_fixmp_14_add_nc)
15035 /* x, y, and z have 14 words. Result in z. Carry bit is lost. */
15036 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
15037 static inline
mpfq_fixmp_14_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)15038 void mpfq_fixmp_14_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
15039 {
15040     mp_limb_t r, s, t, cy, cy1, cy2;
15041     cy = 0;
15042     r = x[0];
15043     s = r + y[0];
15044     cy1 = s < r;
15045     t = s + cy;
15046     cy2 = t < s;
15047     cy = cy1 | cy2;
15048     z[0] = t;
15049     r = x[1];
15050     s = r + y[1];
15051     cy1 = s < r;
15052     t = s + cy;
15053     cy2 = t < s;
15054     cy = cy1 | cy2;
15055     z[1] = t;
15056     r = x[2];
15057     s = r + y[2];
15058     cy1 = s < r;
15059     t = s + cy;
15060     cy2 = t < s;
15061     cy = cy1 | cy2;
15062     z[2] = t;
15063     r = x[3];
15064     s = r + y[3];
15065     cy1 = s < r;
15066     t = s + cy;
15067     cy2 = t < s;
15068     cy = cy1 | cy2;
15069     z[3] = t;
15070     r = x[4];
15071     s = r + y[4];
15072     cy1 = s < r;
15073     t = s + cy;
15074     cy2 = t < s;
15075     cy = cy1 | cy2;
15076     z[4] = t;
15077     r = x[5];
15078     s = r + y[5];
15079     cy1 = s < r;
15080     t = s + cy;
15081     cy2 = t < s;
15082     cy = cy1 | cy2;
15083     z[5] = t;
15084     r = x[6];
15085     s = r + y[6];
15086     cy1 = s < r;
15087     t = s + cy;
15088     cy2 = t < s;
15089     cy = cy1 | cy2;
15090     z[6] = t;
15091     r = x[7];
15092     s = r + y[7];
15093     cy1 = s < r;
15094     t = s + cy;
15095     cy2 = t < s;
15096     cy = cy1 | cy2;
15097     z[7] = t;
15098     r = x[8];
15099     s = r + y[8];
15100     cy1 = s < r;
15101     t = s + cy;
15102     cy2 = t < s;
15103     cy = cy1 | cy2;
15104     z[8] = t;
15105     r = x[9];
15106     s = r + y[9];
15107     cy1 = s < r;
15108     t = s + cy;
15109     cy2 = t < s;
15110     cy = cy1 | cy2;
15111     z[9] = t;
15112     r = x[10];
15113     s = r + y[10];
15114     cy1 = s < r;
15115     t = s + cy;
15116     cy2 = t < s;
15117     cy = cy1 | cy2;
15118     z[10] = t;
15119     r = x[11];
15120     s = r + y[11];
15121     cy1 = s < r;
15122     t = s + cy;
15123     cy2 = t < s;
15124     cy = cy1 | cy2;
15125     z[11] = t;
15126     r = x[12];
15127     s = r + y[12];
15128     cy1 = s < r;
15129     t = s + cy;
15130     cy2 = t < s;
15131     cy = cy1 | cy2;
15132     z[12] = t;
15133     r = x[13];
15134     s = r + y[13];
15135     cy1 = s < r;
15136     t = s + cy;
15137     cy2 = t < s;
15138     cy = cy1 | cy2;
15139     z[13] = t;
15140 }
15141 #endif /* !defined(HAVE_native_mpfq_fixmp_14_add_nc) */
15142 
15143 #if !defined(HAVE_native_mpfq_fixmp_14_sub_nc)
15144 /* x, y, and z have 14 words. Result in z. Borrow bit is lost. */
15145 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
15146 static inline
mpfq_fixmp_14_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)15147 void mpfq_fixmp_14_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
15148 {
15149     mp_limb_t r, s, t, cy, cy1, cy2;
15150     cy = 0;
15151     r = x[0];
15152     s = r - y[0];
15153     cy1 = s > r;
15154     t = s - cy;
15155     cy2 = t > s;
15156     cy = cy1 | cy2;
15157     z[0] = t;
15158     r = x[1];
15159     s = r - y[1];
15160     cy1 = s > r;
15161     t = s - cy;
15162     cy2 = t > s;
15163     cy = cy1 | cy2;
15164     z[1] = t;
15165     r = x[2];
15166     s = r - y[2];
15167     cy1 = s > r;
15168     t = s - cy;
15169     cy2 = t > s;
15170     cy = cy1 | cy2;
15171     z[2] = t;
15172     r = x[3];
15173     s = r - y[3];
15174     cy1 = s > r;
15175     t = s - cy;
15176     cy2 = t > s;
15177     cy = cy1 | cy2;
15178     z[3] = t;
15179     r = x[4];
15180     s = r - y[4];
15181     cy1 = s > r;
15182     t = s - cy;
15183     cy2 = t > s;
15184     cy = cy1 | cy2;
15185     z[4] = t;
15186     r = x[5];
15187     s = r - y[5];
15188     cy1 = s > r;
15189     t = s - cy;
15190     cy2 = t > s;
15191     cy = cy1 | cy2;
15192     z[5] = t;
15193     r = x[6];
15194     s = r - y[6];
15195     cy1 = s > r;
15196     t = s - cy;
15197     cy2 = t > s;
15198     cy = cy1 | cy2;
15199     z[6] = t;
15200     r = x[7];
15201     s = r - y[7];
15202     cy1 = s > r;
15203     t = s - cy;
15204     cy2 = t > s;
15205     cy = cy1 | cy2;
15206     z[7] = t;
15207     r = x[8];
15208     s = r - y[8];
15209     cy1 = s > r;
15210     t = s - cy;
15211     cy2 = t > s;
15212     cy = cy1 | cy2;
15213     z[8] = t;
15214     r = x[9];
15215     s = r - y[9];
15216     cy1 = s > r;
15217     t = s - cy;
15218     cy2 = t > s;
15219     cy = cy1 | cy2;
15220     z[9] = t;
15221     r = x[10];
15222     s = r - y[10];
15223     cy1 = s > r;
15224     t = s - cy;
15225     cy2 = t > s;
15226     cy = cy1 | cy2;
15227     z[10] = t;
15228     r = x[11];
15229     s = r - y[11];
15230     cy1 = s > r;
15231     t = s - cy;
15232     cy2 = t > s;
15233     cy = cy1 | cy2;
15234     z[11] = t;
15235     r = x[12];
15236     s = r - y[12];
15237     cy1 = s > r;
15238     t = s - cy;
15239     cy2 = t > s;
15240     cy = cy1 | cy2;
15241     z[12] = t;
15242     r = x[13];
15243     s = r - y[13];
15244     cy1 = s > r;
15245     t = s - cy;
15246     cy2 = t > s;
15247     cy = cy1 | cy2;
15248     z[13] = t;
15249 }
15250 #endif /* !defined(HAVE_native_mpfq_fixmp_14_sub_nc) */
15251 
15252 #if !defined(HAVE_native_mpfq_fixmp_14_add_ui)
15253 /* x, y, and z have 14 words. Result in z. Return carry bit */
15254 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
15255 static inline
mpfq_fixmp_14_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)15256 mp_limb_t mpfq_fixmp_14_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
15257 {
15258     mp_limb_t r, s, t, cy, cy1, cy2;
15259     cy = 0;
15260     r = x[0];
15261     s = r + y;
15262     cy1 = s < r;
15263     t = s + cy;
15264     cy2 = t < s;
15265     cy = cy1 | cy2;
15266     z[0] = t;
15267     s = x[1];
15268     t = s + cy;
15269     cy = t < s;
15270     z[1] = t;
15271     s = x[2];
15272     t = s + cy;
15273     cy = t < s;
15274     z[2] = t;
15275     s = x[3];
15276     t = s + cy;
15277     cy = t < s;
15278     z[3] = t;
15279     s = x[4];
15280     t = s + cy;
15281     cy = t < s;
15282     z[4] = t;
15283     s = x[5];
15284     t = s + cy;
15285     cy = t < s;
15286     z[5] = t;
15287     s = x[6];
15288     t = s + cy;
15289     cy = t < s;
15290     z[6] = t;
15291     s = x[7];
15292     t = s + cy;
15293     cy = t < s;
15294     z[7] = t;
15295     s = x[8];
15296     t = s + cy;
15297     cy = t < s;
15298     z[8] = t;
15299     s = x[9];
15300     t = s + cy;
15301     cy = t < s;
15302     z[9] = t;
15303     s = x[10];
15304     t = s + cy;
15305     cy = t < s;
15306     z[10] = t;
15307     s = x[11];
15308     t = s + cy;
15309     cy = t < s;
15310     z[11] = t;
15311     s = x[12];
15312     t = s + cy;
15313     cy = t < s;
15314     z[12] = t;
15315     s = x[13];
15316     t = s + cy;
15317     cy = t < s;
15318     z[13] = t;
15319     return cy;
15320 }
15321 #endif /* !defined(HAVE_native_mpfq_fixmp_14_add_ui) */
15322 
15323 #if !defined(HAVE_native_mpfq_fixmp_14_sub_ui)
15324 /* x, y, and z have 14 words. Result in z. Return borrow bit */
15325 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
15326 static inline
mpfq_fixmp_14_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)15327 mp_limb_t mpfq_fixmp_14_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
15328 {
15329     mp_limb_t r, s, t, cy, cy1, cy2;
15330     cy = 0;
15331     r = x[0];
15332     s = r - y;
15333     cy1 = s > r;
15334     t = s - cy;
15335     cy2 = t > s;
15336     cy = cy1 | cy2;
15337     z[0] = t;
15338     s = x[1];
15339     t = s - cy;
15340     cy = t > s;
15341     z[1] = t;
15342     s = x[2];
15343     t = s - cy;
15344     cy = t > s;
15345     z[2] = t;
15346     s = x[3];
15347     t = s - cy;
15348     cy = t > s;
15349     z[3] = t;
15350     s = x[4];
15351     t = s - cy;
15352     cy = t > s;
15353     z[4] = t;
15354     s = x[5];
15355     t = s - cy;
15356     cy = t > s;
15357     z[5] = t;
15358     s = x[6];
15359     t = s - cy;
15360     cy = t > s;
15361     z[6] = t;
15362     s = x[7];
15363     t = s - cy;
15364     cy = t > s;
15365     z[7] = t;
15366     s = x[8];
15367     t = s - cy;
15368     cy = t > s;
15369     z[8] = t;
15370     s = x[9];
15371     t = s - cy;
15372     cy = t > s;
15373     z[9] = t;
15374     s = x[10];
15375     t = s - cy;
15376     cy = t > s;
15377     z[10] = t;
15378     s = x[11];
15379     t = s - cy;
15380     cy = t > s;
15381     z[11] = t;
15382     s = x[12];
15383     t = s - cy;
15384     cy = t > s;
15385     z[12] = t;
15386     s = x[13];
15387     t = s - cy;
15388     cy = t > s;
15389     z[13] = t;
15390     return cy;
15391 }
15392 #endif /* !defined(HAVE_native_mpfq_fixmp_14_sub_ui) */
15393 
15394 #if !defined(HAVE_native_mpfq_fixmp_14_add_ui_nc)
15395 /* x, y, and z have 14 words. Result in z. Carry bit is lost. */
15396 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
15397 static inline
mpfq_fixmp_14_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)15398 void mpfq_fixmp_14_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
15399 {
15400     mp_limb_t r, s, t, cy, cy1, cy2;
15401     cy = 0;
15402     r = x[0];
15403     s = r + y;
15404     cy1 = s < r;
15405     t = s + cy;
15406     cy2 = t < s;
15407     cy = cy1 | cy2;
15408     z[0] = t;
15409     s = x[1];
15410     t = s + cy;
15411     cy = t < s;
15412     z[1] = t;
15413     s = x[2];
15414     t = s + cy;
15415     cy = t < s;
15416     z[2] = t;
15417     s = x[3];
15418     t = s + cy;
15419     cy = t < s;
15420     z[3] = t;
15421     s = x[4];
15422     t = s + cy;
15423     cy = t < s;
15424     z[4] = t;
15425     s = x[5];
15426     t = s + cy;
15427     cy = t < s;
15428     z[5] = t;
15429     s = x[6];
15430     t = s + cy;
15431     cy = t < s;
15432     z[6] = t;
15433     s = x[7];
15434     t = s + cy;
15435     cy = t < s;
15436     z[7] = t;
15437     s = x[8];
15438     t = s + cy;
15439     cy = t < s;
15440     z[8] = t;
15441     s = x[9];
15442     t = s + cy;
15443     cy = t < s;
15444     z[9] = t;
15445     s = x[10];
15446     t = s + cy;
15447     cy = t < s;
15448     z[10] = t;
15449     s = x[11];
15450     t = s + cy;
15451     cy = t < s;
15452     z[11] = t;
15453     s = x[12];
15454     t = s + cy;
15455     cy = t < s;
15456     z[12] = t;
15457     s = x[13];
15458     t = s + cy;
15459     cy = t < s;
15460     z[13] = t;
15461 }
15462 #endif /* !defined(HAVE_native_mpfq_fixmp_14_add_ui_nc) */
15463 
15464 #if !defined(HAVE_native_mpfq_fixmp_14_sub_ui_nc)
15465 /* x, y, and z have 14 words. Result in z. Borrow bit is lost. */
15466 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
15467 static inline
mpfq_fixmp_14_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)15468 void mpfq_fixmp_14_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
15469 {
15470     mp_limb_t r, s, t, cy, cy1, cy2;
15471     cy = 0;
15472     r = x[0];
15473     s = r - y;
15474     cy1 = s > r;
15475     t = s - cy;
15476     cy2 = t > s;
15477     cy = cy1 | cy2;
15478     z[0] = t;
15479     s = x[1];
15480     t = s - cy;
15481     cy = t > s;
15482     z[1] = t;
15483     s = x[2];
15484     t = s - cy;
15485     cy = t > s;
15486     z[2] = t;
15487     s = x[3];
15488     t = s - cy;
15489     cy = t > s;
15490     z[3] = t;
15491     s = x[4];
15492     t = s - cy;
15493     cy = t > s;
15494     z[4] = t;
15495     s = x[5];
15496     t = s - cy;
15497     cy = t > s;
15498     z[5] = t;
15499     s = x[6];
15500     t = s - cy;
15501     cy = t > s;
15502     z[6] = t;
15503     s = x[7];
15504     t = s - cy;
15505     cy = t > s;
15506     z[7] = t;
15507     s = x[8];
15508     t = s - cy;
15509     cy = t > s;
15510     z[8] = t;
15511     s = x[9];
15512     t = s - cy;
15513     cy = t > s;
15514     z[9] = t;
15515     s = x[10];
15516     t = s - cy;
15517     cy = t > s;
15518     z[10] = t;
15519     s = x[11];
15520     t = s - cy;
15521     cy = t > s;
15522     z[11] = t;
15523     s = x[12];
15524     t = s - cy;
15525     cy = t > s;
15526     z[12] = t;
15527     s = x[13];
15528     t = s - cy;
15529     cy = t > s;
15530     z[13] = t;
15531 }
15532 #endif /* !defined(HAVE_native_mpfq_fixmp_14_sub_ui_nc) */
15533 
15534 #if !defined(HAVE_native_mpfq_fixmp_14_cmp)
15535 /* x and y have 14 words. Return sign of difference x-y. */
15536 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
15537 /* Triggered by: 14_invmod, 14_redc */
15538 static inline
mpfq_fixmp_14_cmp(const mp_limb_t * x,const mp_limb_t * y)15539 int mpfq_fixmp_14_cmp(const mp_limb_t * x, const mp_limb_t * y)
15540 {
15541     for (int i = 14-1; i >= 0; --i) {
15542         if (x[i] > y[i]) return 1;
15543         if (x[i] < y[i]) return -1;
15544     }
15545     return 0;
15546 }
15547 #endif /* !defined(HAVE_native_mpfq_fixmp_14_cmp) */
15548 
15549 #if !defined(HAVE_native_mpfq_fixmp_14_cmp_ui)
15550 /* x has 14 words. Return sign of difference x-y. */
15551 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
15552 /* Triggered by: 14_invmod */
15553 static inline
mpfq_fixmp_14_cmp_ui(const mp_limb_t * x,mp_limb_t y)15554 int mpfq_fixmp_14_cmp_ui(const mp_limb_t * x, mp_limb_t y)
15555 {
15556     for (int i = 14-1; i > 0; --i) {
15557         if (x[i]) return 1;
15558     }
15559     if (x[0]>y) return 1;
15560     if (x[0]<y) return -1;
15561     return 0;
15562 }
15563 #endif /* !defined(HAVE_native_mpfq_fixmp_14_cmp_ui) */
15564 
15565 #if !defined(HAVE_native_mpfq_fixmp_14_addmul1)
15566 /* x has 14 words, z has 16.
15567  * Put (z+x*c) in z. Return carry bit. */
15568 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
15569 /* Triggered by: 14_redc_ur */
15570 static inline
mpfq_fixmp_14_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)15571 mp_limb_t mpfq_fixmp_14_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
15572 {
15573     mp_limb_t hi, lo, carry, buf;
15574     carry = 0;
15575     mpfq_umul_ppmm(hi,lo,c,x[0]);
15576     lo += carry;
15577     carry = (lo<carry) + hi;
15578     buf = z[0];
15579     lo += buf;
15580     carry += (lo<buf);
15581     z[0] = lo;
15582     mpfq_umul_ppmm(hi,lo,c,x[1]);
15583     lo += carry;
15584     carry = (lo<carry) + hi;
15585     buf = z[1];
15586     lo += buf;
15587     carry += (lo<buf);
15588     z[1] = lo;
15589     mpfq_umul_ppmm(hi,lo,c,x[2]);
15590     lo += carry;
15591     carry = (lo<carry) + hi;
15592     buf = z[2];
15593     lo += buf;
15594     carry += (lo<buf);
15595     z[2] = lo;
15596     mpfq_umul_ppmm(hi,lo,c,x[3]);
15597     lo += carry;
15598     carry = (lo<carry) + hi;
15599     buf = z[3];
15600     lo += buf;
15601     carry += (lo<buf);
15602     z[3] = lo;
15603     mpfq_umul_ppmm(hi,lo,c,x[4]);
15604     lo += carry;
15605     carry = (lo<carry) + hi;
15606     buf = z[4];
15607     lo += buf;
15608     carry += (lo<buf);
15609     z[4] = lo;
15610     mpfq_umul_ppmm(hi,lo,c,x[5]);
15611     lo += carry;
15612     carry = (lo<carry) + hi;
15613     buf = z[5];
15614     lo += buf;
15615     carry += (lo<buf);
15616     z[5] = lo;
15617     mpfq_umul_ppmm(hi,lo,c,x[6]);
15618     lo += carry;
15619     carry = (lo<carry) + hi;
15620     buf = z[6];
15621     lo += buf;
15622     carry += (lo<buf);
15623     z[6] = lo;
15624     mpfq_umul_ppmm(hi,lo,c,x[7]);
15625     lo += carry;
15626     carry = (lo<carry) + hi;
15627     buf = z[7];
15628     lo += buf;
15629     carry += (lo<buf);
15630     z[7] = lo;
15631     mpfq_umul_ppmm(hi,lo,c,x[8]);
15632     lo += carry;
15633     carry = (lo<carry) + hi;
15634     buf = z[8];
15635     lo += buf;
15636     carry += (lo<buf);
15637     z[8] = lo;
15638     mpfq_umul_ppmm(hi,lo,c,x[9]);
15639     lo += carry;
15640     carry = (lo<carry) + hi;
15641     buf = z[9];
15642     lo += buf;
15643     carry += (lo<buf);
15644     z[9] = lo;
15645     mpfq_umul_ppmm(hi,lo,c,x[10]);
15646     lo += carry;
15647     carry = (lo<carry) + hi;
15648     buf = z[10];
15649     lo += buf;
15650     carry += (lo<buf);
15651     z[10] = lo;
15652     mpfq_umul_ppmm(hi,lo,c,x[11]);
15653     lo += carry;
15654     carry = (lo<carry) + hi;
15655     buf = z[11];
15656     lo += buf;
15657     carry += (lo<buf);
15658     z[11] = lo;
15659     mpfq_umul_ppmm(hi,lo,c,x[12]);
15660     lo += carry;
15661     carry = (lo<carry) + hi;
15662     buf = z[12];
15663     lo += buf;
15664     carry += (lo<buf);
15665     z[12] = lo;
15666     mpfq_umul_ppmm(hi,lo,c,x[13]);
15667     lo += carry;
15668     carry = (lo<carry) + hi;
15669     buf = z[13];
15670     lo += buf;
15671     carry += (lo<buf);
15672     z[13] = lo;
15673     z[14] += carry;
15674     return (z[14]<carry);
15675 }
15676 #endif /* !defined(HAVE_native_mpfq_fixmp_14_addmul1) */
15677 
15678 #if !defined(HAVE_native_mpfq_fixmp_14_addmul1_nc)
15679 /* x has 14 words, z has 16.
15680  * Put (z+x*c) in z. Carry bit is lost. */
15681 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
15682 /* Triggered by: 14_mul, 14_mgy_decode, 15_sqr, 15_shortmul, 14_5_sqr, 14_5_shortmul */
15683 static inline
mpfq_fixmp_14_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)15684 void mpfq_fixmp_14_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
15685 {
15686     mp_limb_t hi, lo, carry, buf;
15687     carry = 0;
15688     mpfq_umul_ppmm(hi,lo,c,x[0]);
15689     lo += carry;
15690     carry = (lo<carry) + hi;
15691     buf = z[0];
15692     lo += buf;
15693     carry += (lo<buf);
15694     z[0] = lo;
15695     mpfq_umul_ppmm(hi,lo,c,x[1]);
15696     lo += carry;
15697     carry = (lo<carry) + hi;
15698     buf = z[1];
15699     lo += buf;
15700     carry += (lo<buf);
15701     z[1] = lo;
15702     mpfq_umul_ppmm(hi,lo,c,x[2]);
15703     lo += carry;
15704     carry = (lo<carry) + hi;
15705     buf = z[2];
15706     lo += buf;
15707     carry += (lo<buf);
15708     z[2] = lo;
15709     mpfq_umul_ppmm(hi,lo,c,x[3]);
15710     lo += carry;
15711     carry = (lo<carry) + hi;
15712     buf = z[3];
15713     lo += buf;
15714     carry += (lo<buf);
15715     z[3] = lo;
15716     mpfq_umul_ppmm(hi,lo,c,x[4]);
15717     lo += carry;
15718     carry = (lo<carry) + hi;
15719     buf = z[4];
15720     lo += buf;
15721     carry += (lo<buf);
15722     z[4] = lo;
15723     mpfq_umul_ppmm(hi,lo,c,x[5]);
15724     lo += carry;
15725     carry = (lo<carry) + hi;
15726     buf = z[5];
15727     lo += buf;
15728     carry += (lo<buf);
15729     z[5] = lo;
15730     mpfq_umul_ppmm(hi,lo,c,x[6]);
15731     lo += carry;
15732     carry = (lo<carry) + hi;
15733     buf = z[6];
15734     lo += buf;
15735     carry += (lo<buf);
15736     z[6] = lo;
15737     mpfq_umul_ppmm(hi,lo,c,x[7]);
15738     lo += carry;
15739     carry = (lo<carry) + hi;
15740     buf = z[7];
15741     lo += buf;
15742     carry += (lo<buf);
15743     z[7] = lo;
15744     mpfq_umul_ppmm(hi,lo,c,x[8]);
15745     lo += carry;
15746     carry = (lo<carry) + hi;
15747     buf = z[8];
15748     lo += buf;
15749     carry += (lo<buf);
15750     z[8] = lo;
15751     mpfq_umul_ppmm(hi,lo,c,x[9]);
15752     lo += carry;
15753     carry = (lo<carry) + hi;
15754     buf = z[9];
15755     lo += buf;
15756     carry += (lo<buf);
15757     z[9] = lo;
15758     mpfq_umul_ppmm(hi,lo,c,x[10]);
15759     lo += carry;
15760     carry = (lo<carry) + hi;
15761     buf = z[10];
15762     lo += buf;
15763     carry += (lo<buf);
15764     z[10] = lo;
15765     mpfq_umul_ppmm(hi,lo,c,x[11]);
15766     lo += carry;
15767     carry = (lo<carry) + hi;
15768     buf = z[11];
15769     lo += buf;
15770     carry += (lo<buf);
15771     z[11] = lo;
15772     mpfq_umul_ppmm(hi,lo,c,x[12]);
15773     lo += carry;
15774     carry = (lo<carry) + hi;
15775     buf = z[12];
15776     lo += buf;
15777     carry += (lo<buf);
15778     z[12] = lo;
15779     mpfq_umul_ppmm(hi,lo,c,x[13]);
15780     lo += carry;
15781     carry = (lo<carry) + hi;
15782     buf = z[13];
15783     lo += buf;
15784     carry += (lo<buf);
15785     z[13] = lo;
15786     z[14] += carry;
15787 }
15788 #endif /* !defined(HAVE_native_mpfq_fixmp_14_addmul1_nc) */
15789 
15790 #if !defined(HAVE_native_mpfq_fixmp_14_addmul1_shortz)
15791 /* x has 14 words, z has 15.
15792  * Put (z+x*c) in z. Return carry word. */
15793 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
15794 /* Triggered by: 14_redc */
15795 static inline
mpfq_fixmp_14_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)15796 mp_limb_t mpfq_fixmp_14_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
15797 {
15798     mp_limb_t hi, lo, carry, buf;
15799     carry = 0;
15800     mpfq_umul_ppmm(hi,lo,c,x[0]);
15801     lo += carry;
15802     carry = (lo<carry) + hi;
15803     buf = z[0];
15804     lo += buf;
15805     carry += (lo<buf);
15806     z[0] = lo;
15807     mpfq_umul_ppmm(hi,lo,c,x[1]);
15808     lo += carry;
15809     carry = (lo<carry) + hi;
15810     buf = z[1];
15811     lo += buf;
15812     carry += (lo<buf);
15813     z[1] = lo;
15814     mpfq_umul_ppmm(hi,lo,c,x[2]);
15815     lo += carry;
15816     carry = (lo<carry) + hi;
15817     buf = z[2];
15818     lo += buf;
15819     carry += (lo<buf);
15820     z[2] = lo;
15821     mpfq_umul_ppmm(hi,lo,c,x[3]);
15822     lo += carry;
15823     carry = (lo<carry) + hi;
15824     buf = z[3];
15825     lo += buf;
15826     carry += (lo<buf);
15827     z[3] = lo;
15828     mpfq_umul_ppmm(hi,lo,c,x[4]);
15829     lo += carry;
15830     carry = (lo<carry) + hi;
15831     buf = z[4];
15832     lo += buf;
15833     carry += (lo<buf);
15834     z[4] = lo;
15835     mpfq_umul_ppmm(hi,lo,c,x[5]);
15836     lo += carry;
15837     carry = (lo<carry) + hi;
15838     buf = z[5];
15839     lo += buf;
15840     carry += (lo<buf);
15841     z[5] = lo;
15842     mpfq_umul_ppmm(hi,lo,c,x[6]);
15843     lo += carry;
15844     carry = (lo<carry) + hi;
15845     buf = z[6];
15846     lo += buf;
15847     carry += (lo<buf);
15848     z[6] = lo;
15849     mpfq_umul_ppmm(hi,lo,c,x[7]);
15850     lo += carry;
15851     carry = (lo<carry) + hi;
15852     buf = z[7];
15853     lo += buf;
15854     carry += (lo<buf);
15855     z[7] = lo;
15856     mpfq_umul_ppmm(hi,lo,c,x[8]);
15857     lo += carry;
15858     carry = (lo<carry) + hi;
15859     buf = z[8];
15860     lo += buf;
15861     carry += (lo<buf);
15862     z[8] = lo;
15863     mpfq_umul_ppmm(hi,lo,c,x[9]);
15864     lo += carry;
15865     carry = (lo<carry) + hi;
15866     buf = z[9];
15867     lo += buf;
15868     carry += (lo<buf);
15869     z[9] = lo;
15870     mpfq_umul_ppmm(hi,lo,c,x[10]);
15871     lo += carry;
15872     carry = (lo<carry) + hi;
15873     buf = z[10];
15874     lo += buf;
15875     carry += (lo<buf);
15876     z[10] = lo;
15877     mpfq_umul_ppmm(hi,lo,c,x[11]);
15878     lo += carry;
15879     carry = (lo<carry) + hi;
15880     buf = z[11];
15881     lo += buf;
15882     carry += (lo<buf);
15883     z[11] = lo;
15884     mpfq_umul_ppmm(hi,lo,c,x[12]);
15885     lo += carry;
15886     carry = (lo<carry) + hi;
15887     buf = z[12];
15888     lo += buf;
15889     carry += (lo<buf);
15890     z[12] = lo;
15891     mpfq_umul_ppmm(hi,lo,c,x[13]);
15892     lo += carry;
15893     carry = (lo<carry) + hi;
15894     buf = z[13];
15895     lo += buf;
15896     carry += (lo<buf);
15897     z[13] = lo;
15898     return carry;
15899 }
15900 #endif /* !defined(HAVE_native_mpfq_fixmp_14_addmul1_shortz) */
15901 
15902 #if !defined(HAVE_native_mpfq_fixmp_14_mul)
15903 /* x and y have 14 words, z has 30. Put x*y in z. */
15904 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
15905 /* Triggered by: 14_mgy_decode */
15906 static inline
mpfq_fixmp_14_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)15907 void mpfq_fixmp_14_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
15908 {
15909     assert(z != x && z != y);
15910     for (int i = 0; i < 28; z[i++] = 0) ;
15911     mpfq_fixmp_14_addmul1_nc (z + 0, x, y[0]);
15912     mpfq_fixmp_14_addmul1_nc (z + 1, x, y[1]);
15913     mpfq_fixmp_14_addmul1_nc (z + 2, x, y[2]);
15914     mpfq_fixmp_14_addmul1_nc (z + 3, x, y[3]);
15915     mpfq_fixmp_14_addmul1_nc (z + 4, x, y[4]);
15916     mpfq_fixmp_14_addmul1_nc (z + 5, x, y[5]);
15917     mpfq_fixmp_14_addmul1_nc (z + 6, x, y[6]);
15918     mpfq_fixmp_14_addmul1_nc (z + 7, x, y[7]);
15919     mpfq_fixmp_14_addmul1_nc (z + 8, x, y[8]);
15920     mpfq_fixmp_14_addmul1_nc (z + 9, x, y[9]);
15921     mpfq_fixmp_14_addmul1_nc (z + 10, x, y[10]);
15922     mpfq_fixmp_14_addmul1_nc (z + 11, x, y[11]);
15923     mpfq_fixmp_14_addmul1_nc (z + 12, x, y[12]);
15924     mpfq_fixmp_14_addmul1_nc (z + 13, x, y[13]);
15925 }
15926 #endif /* !defined(HAVE_native_mpfq_fixmp_14_mul) */
15927 
15928 #if !defined(HAVE_native_mpfq_fixmp_14_sqr)
15929 /* x has 14 words, z has 30. Put x*y in z. */
15930 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
15931 static inline
mpfq_fixmp_14_sqr(mp_limb_t * z,const mp_limb_t * x)15932 void mpfq_fixmp_14_sqr(mp_limb_t * z, const mp_limb_t * x)
15933 {
15934     mp_limb_t buf[28] = {0,};
15935     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
15936     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
15937     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
15938     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
15939     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
15940     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
15941     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
15942     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
15943     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
15944     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
15945     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
15946     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
15947     mpfq_fixmp_13_addmul1_nc(buf + 13, x, x[13]);
15948     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
15949     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
15950     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
15951     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
15952     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
15953     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
15954     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
15955     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
15956     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
15957     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
15958     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
15959     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
15960     mpfq_umul_ppmm(z[2*12+1], z[2*12], x[12], x[12]);
15961     mpfq_umul_ppmm(z[2*13+1], z[2*13], x[13], x[13]);
15962     mpn_lshift(buf, buf, 28, 1);
15963     mpn_add_n(z, z, buf, 28);
15964 }
15965 #endif /* !defined(HAVE_native_mpfq_fixmp_14_sqr) */
15966 
15967 #if !defined(HAVE_native_mpfq_fixmp_14_mul1)
15968 /* x has 14 words, z has 16. Put x*y in z. */
15969 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
15970 static inline
mpfq_fixmp_14_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)15971 void mpfq_fixmp_14_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
15972 {
15973     mp_limb_t hi, lo, carry;
15974     carry = 0;
15975     mpfq_umul_ppmm(hi,lo,c,x[0]);
15976     lo += carry;
15977     carry = (lo<carry) + hi;
15978     z[0] = lo;
15979     mpfq_umul_ppmm(hi,lo,c,x[1]);
15980     lo += carry;
15981     carry = (lo<carry) + hi;
15982     z[1] = lo;
15983     mpfq_umul_ppmm(hi,lo,c,x[2]);
15984     lo += carry;
15985     carry = (lo<carry) + hi;
15986     z[2] = lo;
15987     mpfq_umul_ppmm(hi,lo,c,x[3]);
15988     lo += carry;
15989     carry = (lo<carry) + hi;
15990     z[3] = lo;
15991     mpfq_umul_ppmm(hi,lo,c,x[4]);
15992     lo += carry;
15993     carry = (lo<carry) + hi;
15994     z[4] = lo;
15995     mpfq_umul_ppmm(hi,lo,c,x[5]);
15996     lo += carry;
15997     carry = (lo<carry) + hi;
15998     z[5] = lo;
15999     mpfq_umul_ppmm(hi,lo,c,x[6]);
16000     lo += carry;
16001     carry = (lo<carry) + hi;
16002     z[6] = lo;
16003     mpfq_umul_ppmm(hi,lo,c,x[7]);
16004     lo += carry;
16005     carry = (lo<carry) + hi;
16006     z[7] = lo;
16007     mpfq_umul_ppmm(hi,lo,c,x[8]);
16008     lo += carry;
16009     carry = (lo<carry) + hi;
16010     z[8] = lo;
16011     mpfq_umul_ppmm(hi,lo,c,x[9]);
16012     lo += carry;
16013     carry = (lo<carry) + hi;
16014     z[9] = lo;
16015     mpfq_umul_ppmm(hi,lo,c,x[10]);
16016     lo += carry;
16017     carry = (lo<carry) + hi;
16018     z[10] = lo;
16019     mpfq_umul_ppmm(hi,lo,c,x[11]);
16020     lo += carry;
16021     carry = (lo<carry) + hi;
16022     z[11] = lo;
16023     mpfq_umul_ppmm(hi,lo,c,x[12]);
16024     lo += carry;
16025     carry = (lo<carry) + hi;
16026     z[12] = lo;
16027     mpfq_umul_ppmm(hi,lo,c,x[13]);
16028     lo += carry;
16029     carry = (lo<carry) + hi;
16030     z[13] = lo;
16031     z[14] = carry;
16032 }
16033 #endif /* !defined(HAVE_native_mpfq_fixmp_14_mul1) */
16034 
16035 #if !defined(HAVE_native_mpfq_fixmp_14_shortmul)
16036 /* x and y have 14 words, z has 15.
16037  * Put the low 15 words of x*y in z. */
16038 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
16039 static inline
mpfq_fixmp_14_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)16040 void mpfq_fixmp_14_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
16041 {
16042     mpfq_zero(z, 14);
16043     mpfq_fixmp_13_addmul1_nc (z+0, x, y[0]);
16044     z[14-1] += x[13]*y[0];
16045     mpfq_fixmp_12_addmul1_nc (z+1, x, y[1]);
16046     z[14-1] += x[12]*y[1];
16047     mpfq_fixmp_11_addmul1_nc (z+2, x, y[2]);
16048     z[14-1] += x[11]*y[2];
16049     mpfq_fixmp_10_addmul1_nc (z+3, x, y[3]);
16050     z[14-1] += x[10]*y[3];
16051     mpfq_fixmp_9_addmul1_nc (z+4, x, y[4]);
16052     z[14-1] += x[9]*y[4];
16053     mpfq_fixmp_8_addmul1_nc (z+5, x, y[5]);
16054     z[14-1] += x[8]*y[5];
16055     mpfq_fixmp_7_addmul1_nc (z+6, x, y[6]);
16056     z[14-1] += x[7]*y[6];
16057     mpfq_fixmp_6_addmul1_nc (z+7, x, y[7]);
16058     z[14-1] += x[6]*y[7];
16059     mpfq_fixmp_5_addmul1_nc (z+8, x, y[8]);
16060     z[14-1] += x[5]*y[8];
16061     mpfq_fixmp_4_addmul1_nc (z+9, x, y[9]);
16062     z[14-1] += x[4]*y[9];
16063     mpfq_fixmp_3_addmul1_nc (z+10, x, y[10]);
16064     z[14-1] += x[3]*y[10];
16065     mpfq_fixmp_2_addmul1_nc (z+11, x, y[11]);
16066     z[14-1] += x[2]*y[11];
16067     mpfq_fixmp_1_addmul1_nc (z+12, x, y[12]);
16068     z[14-1] += x[1]*y[12];
16069     z[14-1] += x[0]*y[14-1];
16070 }
16071 #endif /* !defined(HAVE_native_mpfq_fixmp_14_shortmul) */
16072 
16073 #if !defined(HAVE_native_mpfq_fixmp_14_mod)
16074 /* x has 30 words. z and p have 14 words, and the high word of p is non-zero.
16075  * Put x mod p in z. */
16076 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
16077 /* Triggered by: 14_mgy_decode */
16078 static inline
mpfq_fixmp_14_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)16079 void mpfq_fixmp_14_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
16080 {
16081     mp_limb_t q[14+1], r[14];
16082     assert (p[14-1] != 0);
16083     mpn_tdiv_qr(q, r, 0, x, 28, p, 14);
16084     mpfq_copy(z, r, 14);
16085 }
16086 #endif /* !defined(HAVE_native_mpfq_fixmp_14_mod) */
16087 
16088 #if !defined(HAVE_native_mpfq_fixmp_14_rshift)
16089 /* a has 14 words. Shift it in place by cnt bits to the right.
16090  * The shift count cnt must not exceed the word size.
16091  * Note that no carry is returned for the bits shifted out. */
16092 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
16093 /* Triggered by: 14_invmod */
16094 static inline
mpfq_fixmp_14_rshift(mp_limb_t * a,int cnt)16095 void mpfq_fixmp_14_rshift(mp_limb_t * a, int cnt)
16096 {
16097     if (!cnt) return;
16098     int i;
16099     int dnt = GMP_NUMB_BITS - cnt;
16100     for (i = 0; i < 14-1; ++i) {
16101         a[i] >>= cnt;
16102         a[i] |= (a[i+1] << dnt);
16103     }
16104     a[14-1] >>= cnt;
16105 }
16106 #endif /* !defined(HAVE_native_mpfq_fixmp_14_rshift) */
16107 
16108 #if !defined(HAVE_native_mpfq_fixmp_14_long_rshift)
16109 /* a has 14 words. Shift it in place by off words plus cnt bits to the left.
16110  * Note that no carry is returned for the bits shifted out. */
16111 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
16112 /* Triggered by: 14_invmod */
16113 static inline
mpfq_fixmp_14_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)16114 void mpfq_fixmp_14_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
16115 {
16116     if (cnt) {
16117         int dnt = GMP_NUMB_BITS - cnt;
16118         for (int i = 0; i < 14 - off - 1; ++i) {
16119             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
16120         }
16121         a[14-off-1] = a[14-1]>>cnt;
16122     } else {
16123         mpfq_copyi(a, a + off, 14 - off);
16124     }
16125     mpfq_zero(a + 14 - off, off);
16126 }
16127 #endif /* !defined(HAVE_native_mpfq_fixmp_14_long_rshift) */
16128 
16129 #if !defined(HAVE_native_mpfq_fixmp_14_long_lshift)
16130 /* a has 14 words. Shift it in place by off words plus cnt bits to the left.
16131  * Note that no carry is returned for the bits shifted out. */
16132 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
16133 /* Triggered by: 14_invmod */
16134 static inline
mpfq_fixmp_14_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)16135 void mpfq_fixmp_14_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
16136 {
16137     int i;
16138     if (cnt) {
16139         int dnt = GMP_NUMB_BITS - cnt;
16140         for (i = 14-1; i>off; --i) {
16141             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
16142         }
16143         a[off] = a[0]<<cnt;
16144     } else {
16145         mpfq_copyd(a + off, a, 14 - off);
16146     }
16147     mpfq_zero(a, off);
16148 }
16149 #endif /* !defined(HAVE_native_mpfq_fixmp_14_long_lshift) */
16150 
16151 #if !defined(HAVE_native_mpfq_fixmp_14_invmod)
16152 /* x, z, and p have 14 words. Put inverse of x mod p in z.
16153  * Return non-zero if an inverse could be found.
16154  * If no inverse could be found, return 0 and set z to zero.
16155  */
16156 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
16157 static inline
mpfq_fixmp_14_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)16158 int mpfq_fixmp_14_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
16159 {
16160       mp_limb_t u[14], v[14], a[14], b[14], fix[14];
16161       int i, t, lsh;
16162 
16163       mpfq_zero(u, 14);
16164       mpfq_zero(v, 14);
16165       mpfq_copy(a, x, 14);
16166       mpfq_copy(b, p, 14);
16167       u[0] = 1UL;
16168 
16169       if (mpfq_fixmp_14_cmp(a, v) == 0 || mpfq_fixmp_14_cmp(a, b) == 0) {
16170         mpfq_zero(res, 14);
16171         return 0;
16172       }
16173 
16174       mpfq_fixmp_14_add(fix, b, u);
16175       mpfq_fixmp_14_rshift(fix, 1);
16176 
16177       assert (mpfq_fixmp_14_cmp(a,b) < 0);
16178 
16179       t = 0;
16180 
16181       for(i = 0 ; !a[i] ; i++) ;
16182       assert (i < 14);
16183       lsh = mpfq_ctzl(a[i]);
16184       mpfq_fixmp_14_long_rshift(a, i, lsh);
16185       t += lsh + i*GMP_NUMB_BITS;
16186       mpfq_fixmp_14_long_lshift(v, i, lsh);
16187 
16188       do {
16189         do {
16190           mpfq_fixmp_14_sub(b, b, a);
16191           mpfq_fixmp_14_add(v, v, u);
16192           for(i = 0 ; !b[i] ; i++) ;
16193           assert (i < 14);
16194           lsh = mpfq_ctzl(b[i]);
16195           mpfq_fixmp_14_long_rshift(b, i, lsh);
16196           t += lsh + i*GMP_NUMB_BITS;
16197           mpfq_fixmp_14_long_lshift(u, i, lsh);
16198         } while (mpfq_fixmp_14_cmp(a,b) < 0);
16199         if (mpfq_fixmp_14_cmp(a, b) == 0)
16200           break;
16201         do {
16202           mpfq_fixmp_14_sub(a, a, b);
16203           mpfq_fixmp_14_add(u, u, v);
16204           for(i = 0 ; !a[i] ; i++) ;
16205           assert (i < 14);
16206           lsh = mpfq_ctzl(a[i]);
16207           mpfq_fixmp_14_long_rshift(a, i, lsh);
16208           t += lsh + i*GMP_NUMB_BITS;
16209           mpfq_fixmp_14_long_lshift(v, i, lsh);
16210         } while (mpfq_fixmp_14_cmp(b,a)<0);
16211       } while (mpfq_fixmp_14_cmp(a,b) != 0);
16212       {
16213         if (mpfq_fixmp_14_cmp_ui(a, 1) != 0) {
16214           mpfq_copy(res, a, 14);
16215           return 0;
16216         }
16217       }
16218       while (t>0) {
16219         mp_limb_t sig = u[0] & 1UL;
16220         mpfq_fixmp_14_rshift(u, 1);
16221         if (sig)
16222           mpfq_fixmp_14_add(u, u, fix);
16223         --t;
16224       }
16225       mpfq_copy(res, u, 14);
16226       return 1;
16227 }
16228 #endif /* !defined(HAVE_native_mpfq_fixmp_14_invmod) */
16229 
16230 #if !defined(HAVE_native_mpfq_fixmp_14_redc)
16231 /* x has 30 words, z and p have 14 words.
16232  * only one word is read from invp.
16233  * Assuming R=W^15 is the redc modulus, we expect that x verifies:
16234  *   x < R*p,
16235  * so that we have eventually z < p, z congruent to x/R mod p.
16236  * The contents of the area pointed by x are clobbered by this call.
16237  * Note also that x may alias z.
16238  */
16239 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
16240 static inline
mpfq_fixmp_14_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)16241 void mpfq_fixmp_14_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
16242 {
16243     mp_limb_t cy;
16244     for(int i = 0; i < 14; ++i) {
16245         mp_limb_t t = x[i]*mip[0];
16246         cy = mpfq_fixmp_14_addmul1_shortz(x+i, p, t);
16247         assert (x[i] == 0);
16248         x[i] = cy;
16249     }
16250     cy = mpfq_fixmp_14_add(x, x, x + 14);
16251     /* At this point, we have (x' denotes x + cy*W^n here)
16252     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
16253     * x'/R < p + p
16254     */
16255     if (cy || mpfq_fixmp_14_cmp(x, p) >= 0) {
16256         mpfq_fixmp_14_sub(z, x, p);
16257     } else {
16258         mpfq_copy(z, x, 14);
16259     }
16260 }
16261 #endif /* !defined(HAVE_native_mpfq_fixmp_14_redc) */
16262 
16263 #if !defined(HAVE_native_mpfq_fixmp_14_redc_ur)
16264 /* x has 31 words, z and p have 14 words.
16265  * only one word is read from invp.
16266  * Assuming R=W^15 is the redc modulus, we expect that x verifies:
16267  *  x < W*W^14*p = W^0.5*R*p or the hw case, W*R*p otherwise,
16268  * so that we have eventually z < p, z congruent to x/R mod p.
16269  * The contents of the area pointed by x are clobbered by this call.
16270  * Note also that x may alias z.
16271  */
16272 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
16273 static inline
mpfq_fixmp_14_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)16274 void mpfq_fixmp_14_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
16275 {
16276     mp_limb_t cy, q[2];
16277     for (int i = 0; i < 14; ++i) {
16278         mp_limb_t t = x[i]*mip[0];
16279         cy = mpfq_fixmp_14_addmul1(x+i, p, t);
16280         assert (x[i] == 0);
16281         x[i] = cy;
16282     }
16283     cy=mpfq_fixmp_14_add(x+14+1, x+14+1, x);
16284     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
16285     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
16286     * x'/R < (W+1)*p
16287     */
16288     if (cy) {
16289         /* x'/R-p < W*p, which fits in n+1 words */
16290         mpn_sub(x+14,x+14,14+1,p,14);
16291     }
16292     mpn_tdiv_qr(q, z, 0, x+14, 14+1, p, 14);
16293 }
16294 #endif /* !defined(HAVE_native_mpfq_fixmp_14_redc_ur) */
16295 
16296 #if !defined(HAVE_native_mpfq_fixmp_14_mgy_encode)
16297 /* x, z, and p have 14 words.
16298  * Assuming R=W^15 is the redc modulus, we compute z=R*x mod p. */
16299 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
16300 static inline
mpfq_fixmp_14_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)16301 void mpfq_fixmp_14_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
16302 {
16303     mp_limb_t t[28] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13] };
16304     mpfq_fixmp_14_mod(z, t, p);
16305 }
16306 #endif /* !defined(HAVE_native_mpfq_fixmp_14_mgy_encode) */
16307 
16308 #if !defined(HAVE_native_mpfq_fixmp_14_mgy_decode)
16309 /* x, z, invR, and p have 14 words.
16310  * Assuming R=W^15 is the redc modulus, we compute z=x/R mod p. */
16311 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
16312 static inline
mpfq_fixmp_14_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)16313 void mpfq_fixmp_14_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
16314 {
16315     mp_limb_t t[28];
16316     mpfq_fixmp_14_mul(t, x, invR);
16317     mpfq_fixmp_14_mod(z, t, p);
16318 }
16319 #endif /* !defined(HAVE_native_mpfq_fixmp_14_mgy_decode) */
16320 
16321 #if !defined(HAVE_native_mpfq_fixmp_14_lshift)
16322 /* a has 14 words. Shift it in place by cnt bits to the left.
16323  * The shift count cnt must not exceed the word size.
16324  * Note that no carry is returned for the bits shifted out. */
16325 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
16326 static inline
mpfq_fixmp_14_lshift(mp_limb_t * a,int cnt)16327 void mpfq_fixmp_14_lshift(mp_limb_t * a, int cnt)
16328 {
16329     if (!cnt) return;
16330     int i;
16331     int dnt = GMP_NUMB_BITS - cnt;
16332     for (i = 14-1; i>0; --i) {
16333         a[i] <<= cnt;
16334         a[i] |= (a[i-1] >> dnt);
16335     }
16336     a[0] <<= cnt;
16337 }
16338 #endif /* !defined(HAVE_native_mpfq_fixmp_14_lshift) */
16339 
16340 #if !defined(HAVE_native_mpfq_fixmp_15_add)
16341 /* x, y, and z have 15 words. Result in z. Return carry bit */
16342 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
16343 /* Triggered by: 15_invmod, 15_redc, 15_redc_ur */
16344 static inline
mpfq_fixmp_15_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)16345 mp_limb_t mpfq_fixmp_15_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
16346 {
16347     mp_limb_t r, s, t, cy, cy1, cy2;
16348     cy = 0;
16349     r = x[0];
16350     s = r + y[0];
16351     cy1 = s < r;
16352     t = s + cy;
16353     cy2 = t < s;
16354     cy = cy1 | cy2;
16355     z[0] = t;
16356     r = x[1];
16357     s = r + y[1];
16358     cy1 = s < r;
16359     t = s + cy;
16360     cy2 = t < s;
16361     cy = cy1 | cy2;
16362     z[1] = t;
16363     r = x[2];
16364     s = r + y[2];
16365     cy1 = s < r;
16366     t = s + cy;
16367     cy2 = t < s;
16368     cy = cy1 | cy2;
16369     z[2] = t;
16370     r = x[3];
16371     s = r + y[3];
16372     cy1 = s < r;
16373     t = s + cy;
16374     cy2 = t < s;
16375     cy = cy1 | cy2;
16376     z[3] = t;
16377     r = x[4];
16378     s = r + y[4];
16379     cy1 = s < r;
16380     t = s + cy;
16381     cy2 = t < s;
16382     cy = cy1 | cy2;
16383     z[4] = t;
16384     r = x[5];
16385     s = r + y[5];
16386     cy1 = s < r;
16387     t = s + cy;
16388     cy2 = t < s;
16389     cy = cy1 | cy2;
16390     z[5] = t;
16391     r = x[6];
16392     s = r + y[6];
16393     cy1 = s < r;
16394     t = s + cy;
16395     cy2 = t < s;
16396     cy = cy1 | cy2;
16397     z[6] = t;
16398     r = x[7];
16399     s = r + y[7];
16400     cy1 = s < r;
16401     t = s + cy;
16402     cy2 = t < s;
16403     cy = cy1 | cy2;
16404     z[7] = t;
16405     r = x[8];
16406     s = r + y[8];
16407     cy1 = s < r;
16408     t = s + cy;
16409     cy2 = t < s;
16410     cy = cy1 | cy2;
16411     z[8] = t;
16412     r = x[9];
16413     s = r + y[9];
16414     cy1 = s < r;
16415     t = s + cy;
16416     cy2 = t < s;
16417     cy = cy1 | cy2;
16418     z[9] = t;
16419     r = x[10];
16420     s = r + y[10];
16421     cy1 = s < r;
16422     t = s + cy;
16423     cy2 = t < s;
16424     cy = cy1 | cy2;
16425     z[10] = t;
16426     r = x[11];
16427     s = r + y[11];
16428     cy1 = s < r;
16429     t = s + cy;
16430     cy2 = t < s;
16431     cy = cy1 | cy2;
16432     z[11] = t;
16433     r = x[12];
16434     s = r + y[12];
16435     cy1 = s < r;
16436     t = s + cy;
16437     cy2 = t < s;
16438     cy = cy1 | cy2;
16439     z[12] = t;
16440     r = x[13];
16441     s = r + y[13];
16442     cy1 = s < r;
16443     t = s + cy;
16444     cy2 = t < s;
16445     cy = cy1 | cy2;
16446     z[13] = t;
16447     r = x[14];
16448     s = r + y[14];
16449     cy1 = s < r;
16450     t = s + cy;
16451     cy2 = t < s;
16452     cy = cy1 | cy2;
16453     z[14] = t;
16454     return cy;
16455 }
16456 #endif /* !defined(HAVE_native_mpfq_fixmp_15_add) */
16457 
16458 #if !defined(HAVE_native_mpfq_fixmp_15_sub)
16459 /* x, y, and z have 15 words. Result in z. Return borrow bit */
16460 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
16461 /* Triggered by: 15_invmod, 15_redc */
16462 static inline
mpfq_fixmp_15_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)16463 mp_limb_t mpfq_fixmp_15_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
16464 {
16465     mp_limb_t r, s, t, cy, cy1, cy2;
16466     cy = 0;
16467     r = x[0];
16468     s = r - y[0];
16469     cy1 = s > r;
16470     t = s - cy;
16471     cy2 = t > s;
16472     cy = cy1 | cy2;
16473     z[0] = t;
16474     r = x[1];
16475     s = r - y[1];
16476     cy1 = s > r;
16477     t = s - cy;
16478     cy2 = t > s;
16479     cy = cy1 | cy2;
16480     z[1] = t;
16481     r = x[2];
16482     s = r - y[2];
16483     cy1 = s > r;
16484     t = s - cy;
16485     cy2 = t > s;
16486     cy = cy1 | cy2;
16487     z[2] = t;
16488     r = x[3];
16489     s = r - y[3];
16490     cy1 = s > r;
16491     t = s - cy;
16492     cy2 = t > s;
16493     cy = cy1 | cy2;
16494     z[3] = t;
16495     r = x[4];
16496     s = r - y[4];
16497     cy1 = s > r;
16498     t = s - cy;
16499     cy2 = t > s;
16500     cy = cy1 | cy2;
16501     z[4] = t;
16502     r = x[5];
16503     s = r - y[5];
16504     cy1 = s > r;
16505     t = s - cy;
16506     cy2 = t > s;
16507     cy = cy1 | cy2;
16508     z[5] = t;
16509     r = x[6];
16510     s = r - y[6];
16511     cy1 = s > r;
16512     t = s - cy;
16513     cy2 = t > s;
16514     cy = cy1 | cy2;
16515     z[6] = t;
16516     r = x[7];
16517     s = r - y[7];
16518     cy1 = s > r;
16519     t = s - cy;
16520     cy2 = t > s;
16521     cy = cy1 | cy2;
16522     z[7] = t;
16523     r = x[8];
16524     s = r - y[8];
16525     cy1 = s > r;
16526     t = s - cy;
16527     cy2 = t > s;
16528     cy = cy1 | cy2;
16529     z[8] = t;
16530     r = x[9];
16531     s = r - y[9];
16532     cy1 = s > r;
16533     t = s - cy;
16534     cy2 = t > s;
16535     cy = cy1 | cy2;
16536     z[9] = t;
16537     r = x[10];
16538     s = r - y[10];
16539     cy1 = s > r;
16540     t = s - cy;
16541     cy2 = t > s;
16542     cy = cy1 | cy2;
16543     z[10] = t;
16544     r = x[11];
16545     s = r - y[11];
16546     cy1 = s > r;
16547     t = s - cy;
16548     cy2 = t > s;
16549     cy = cy1 | cy2;
16550     z[11] = t;
16551     r = x[12];
16552     s = r - y[12];
16553     cy1 = s > r;
16554     t = s - cy;
16555     cy2 = t > s;
16556     cy = cy1 | cy2;
16557     z[12] = t;
16558     r = x[13];
16559     s = r - y[13];
16560     cy1 = s > r;
16561     t = s - cy;
16562     cy2 = t > s;
16563     cy = cy1 | cy2;
16564     z[13] = t;
16565     r = x[14];
16566     s = r - y[14];
16567     cy1 = s > r;
16568     t = s - cy;
16569     cy2 = t > s;
16570     cy = cy1 | cy2;
16571     z[14] = t;
16572     return cy;
16573 }
16574 #endif /* !defined(HAVE_native_mpfq_fixmp_15_sub) */
16575 
16576 #if !defined(HAVE_native_mpfq_fixmp_15_add_nc)
16577 /* x, y, and z have 15 words. Result in z. Carry bit is lost. */
16578 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
16579 static inline
mpfq_fixmp_15_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)16580 void mpfq_fixmp_15_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
16581 {
16582     mp_limb_t r, s, t, cy, cy1, cy2;
16583     cy = 0;
16584     r = x[0];
16585     s = r + y[0];
16586     cy1 = s < r;
16587     t = s + cy;
16588     cy2 = t < s;
16589     cy = cy1 | cy2;
16590     z[0] = t;
16591     r = x[1];
16592     s = r + y[1];
16593     cy1 = s < r;
16594     t = s + cy;
16595     cy2 = t < s;
16596     cy = cy1 | cy2;
16597     z[1] = t;
16598     r = x[2];
16599     s = r + y[2];
16600     cy1 = s < r;
16601     t = s + cy;
16602     cy2 = t < s;
16603     cy = cy1 | cy2;
16604     z[2] = t;
16605     r = x[3];
16606     s = r + y[3];
16607     cy1 = s < r;
16608     t = s + cy;
16609     cy2 = t < s;
16610     cy = cy1 | cy2;
16611     z[3] = t;
16612     r = x[4];
16613     s = r + y[4];
16614     cy1 = s < r;
16615     t = s + cy;
16616     cy2 = t < s;
16617     cy = cy1 | cy2;
16618     z[4] = t;
16619     r = x[5];
16620     s = r + y[5];
16621     cy1 = s < r;
16622     t = s + cy;
16623     cy2 = t < s;
16624     cy = cy1 | cy2;
16625     z[5] = t;
16626     r = x[6];
16627     s = r + y[6];
16628     cy1 = s < r;
16629     t = s + cy;
16630     cy2 = t < s;
16631     cy = cy1 | cy2;
16632     z[6] = t;
16633     r = x[7];
16634     s = r + y[7];
16635     cy1 = s < r;
16636     t = s + cy;
16637     cy2 = t < s;
16638     cy = cy1 | cy2;
16639     z[7] = t;
16640     r = x[8];
16641     s = r + y[8];
16642     cy1 = s < r;
16643     t = s + cy;
16644     cy2 = t < s;
16645     cy = cy1 | cy2;
16646     z[8] = t;
16647     r = x[9];
16648     s = r + y[9];
16649     cy1 = s < r;
16650     t = s + cy;
16651     cy2 = t < s;
16652     cy = cy1 | cy2;
16653     z[9] = t;
16654     r = x[10];
16655     s = r + y[10];
16656     cy1 = s < r;
16657     t = s + cy;
16658     cy2 = t < s;
16659     cy = cy1 | cy2;
16660     z[10] = t;
16661     r = x[11];
16662     s = r + y[11];
16663     cy1 = s < r;
16664     t = s + cy;
16665     cy2 = t < s;
16666     cy = cy1 | cy2;
16667     z[11] = t;
16668     r = x[12];
16669     s = r + y[12];
16670     cy1 = s < r;
16671     t = s + cy;
16672     cy2 = t < s;
16673     cy = cy1 | cy2;
16674     z[12] = t;
16675     r = x[13];
16676     s = r + y[13];
16677     cy1 = s < r;
16678     t = s + cy;
16679     cy2 = t < s;
16680     cy = cy1 | cy2;
16681     z[13] = t;
16682     r = x[14];
16683     s = r + y[14];
16684     cy1 = s < r;
16685     t = s + cy;
16686     cy2 = t < s;
16687     cy = cy1 | cy2;
16688     z[14] = t;
16689 }
16690 #endif /* !defined(HAVE_native_mpfq_fixmp_15_add_nc) */
16691 
16692 #if !defined(HAVE_native_mpfq_fixmp_15_sub_nc)
16693 /* x, y, and z have 15 words. Result in z. Borrow bit is lost. */
16694 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
16695 static inline
mpfq_fixmp_15_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)16696 void mpfq_fixmp_15_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
16697 {
16698     mp_limb_t r, s, t, cy, cy1, cy2;
16699     cy = 0;
16700     r = x[0];
16701     s = r - y[0];
16702     cy1 = s > r;
16703     t = s - cy;
16704     cy2 = t > s;
16705     cy = cy1 | cy2;
16706     z[0] = t;
16707     r = x[1];
16708     s = r - y[1];
16709     cy1 = s > r;
16710     t = s - cy;
16711     cy2 = t > s;
16712     cy = cy1 | cy2;
16713     z[1] = t;
16714     r = x[2];
16715     s = r - y[2];
16716     cy1 = s > r;
16717     t = s - cy;
16718     cy2 = t > s;
16719     cy = cy1 | cy2;
16720     z[2] = t;
16721     r = x[3];
16722     s = r - y[3];
16723     cy1 = s > r;
16724     t = s - cy;
16725     cy2 = t > s;
16726     cy = cy1 | cy2;
16727     z[3] = t;
16728     r = x[4];
16729     s = r - y[4];
16730     cy1 = s > r;
16731     t = s - cy;
16732     cy2 = t > s;
16733     cy = cy1 | cy2;
16734     z[4] = t;
16735     r = x[5];
16736     s = r - y[5];
16737     cy1 = s > r;
16738     t = s - cy;
16739     cy2 = t > s;
16740     cy = cy1 | cy2;
16741     z[5] = t;
16742     r = x[6];
16743     s = r - y[6];
16744     cy1 = s > r;
16745     t = s - cy;
16746     cy2 = t > s;
16747     cy = cy1 | cy2;
16748     z[6] = t;
16749     r = x[7];
16750     s = r - y[7];
16751     cy1 = s > r;
16752     t = s - cy;
16753     cy2 = t > s;
16754     cy = cy1 | cy2;
16755     z[7] = t;
16756     r = x[8];
16757     s = r - y[8];
16758     cy1 = s > r;
16759     t = s - cy;
16760     cy2 = t > s;
16761     cy = cy1 | cy2;
16762     z[8] = t;
16763     r = x[9];
16764     s = r - y[9];
16765     cy1 = s > r;
16766     t = s - cy;
16767     cy2 = t > s;
16768     cy = cy1 | cy2;
16769     z[9] = t;
16770     r = x[10];
16771     s = r - y[10];
16772     cy1 = s > r;
16773     t = s - cy;
16774     cy2 = t > s;
16775     cy = cy1 | cy2;
16776     z[10] = t;
16777     r = x[11];
16778     s = r - y[11];
16779     cy1 = s > r;
16780     t = s - cy;
16781     cy2 = t > s;
16782     cy = cy1 | cy2;
16783     z[11] = t;
16784     r = x[12];
16785     s = r - y[12];
16786     cy1 = s > r;
16787     t = s - cy;
16788     cy2 = t > s;
16789     cy = cy1 | cy2;
16790     z[12] = t;
16791     r = x[13];
16792     s = r - y[13];
16793     cy1 = s > r;
16794     t = s - cy;
16795     cy2 = t > s;
16796     cy = cy1 | cy2;
16797     z[13] = t;
16798     r = x[14];
16799     s = r - y[14];
16800     cy1 = s > r;
16801     t = s - cy;
16802     cy2 = t > s;
16803     cy = cy1 | cy2;
16804     z[14] = t;
16805 }
16806 #endif /* !defined(HAVE_native_mpfq_fixmp_15_sub_nc) */
16807 
16808 #if !defined(HAVE_native_mpfq_fixmp_15_add_ui)
16809 /* x, y, and z have 15 words. Result in z. Return carry bit */
16810 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
16811 static inline
mpfq_fixmp_15_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)16812 mp_limb_t mpfq_fixmp_15_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
16813 {
16814     mp_limb_t r, s, t, cy, cy1, cy2;
16815     cy = 0;
16816     r = x[0];
16817     s = r + y;
16818     cy1 = s < r;
16819     t = s + cy;
16820     cy2 = t < s;
16821     cy = cy1 | cy2;
16822     z[0] = t;
16823     s = x[1];
16824     t = s + cy;
16825     cy = t < s;
16826     z[1] = t;
16827     s = x[2];
16828     t = s + cy;
16829     cy = t < s;
16830     z[2] = t;
16831     s = x[3];
16832     t = s + cy;
16833     cy = t < s;
16834     z[3] = t;
16835     s = x[4];
16836     t = s + cy;
16837     cy = t < s;
16838     z[4] = t;
16839     s = x[5];
16840     t = s + cy;
16841     cy = t < s;
16842     z[5] = t;
16843     s = x[6];
16844     t = s + cy;
16845     cy = t < s;
16846     z[6] = t;
16847     s = x[7];
16848     t = s + cy;
16849     cy = t < s;
16850     z[7] = t;
16851     s = x[8];
16852     t = s + cy;
16853     cy = t < s;
16854     z[8] = t;
16855     s = x[9];
16856     t = s + cy;
16857     cy = t < s;
16858     z[9] = t;
16859     s = x[10];
16860     t = s + cy;
16861     cy = t < s;
16862     z[10] = t;
16863     s = x[11];
16864     t = s + cy;
16865     cy = t < s;
16866     z[11] = t;
16867     s = x[12];
16868     t = s + cy;
16869     cy = t < s;
16870     z[12] = t;
16871     s = x[13];
16872     t = s + cy;
16873     cy = t < s;
16874     z[13] = t;
16875     s = x[14];
16876     t = s + cy;
16877     cy = t < s;
16878     z[14] = t;
16879     return cy;
16880 }
16881 #endif /* !defined(HAVE_native_mpfq_fixmp_15_add_ui) */
16882 
16883 #if !defined(HAVE_native_mpfq_fixmp_15_sub_ui)
16884 /* x, y, and z have 15 words. Result in z. Return borrow bit */
16885 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
16886 static inline
mpfq_fixmp_15_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)16887 mp_limb_t mpfq_fixmp_15_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
16888 {
16889     mp_limb_t r, s, t, cy, cy1, cy2;
16890     cy = 0;
16891     r = x[0];
16892     s = r - y;
16893     cy1 = s > r;
16894     t = s - cy;
16895     cy2 = t > s;
16896     cy = cy1 | cy2;
16897     z[0] = t;
16898     s = x[1];
16899     t = s - cy;
16900     cy = t > s;
16901     z[1] = t;
16902     s = x[2];
16903     t = s - cy;
16904     cy = t > s;
16905     z[2] = t;
16906     s = x[3];
16907     t = s - cy;
16908     cy = t > s;
16909     z[3] = t;
16910     s = x[4];
16911     t = s - cy;
16912     cy = t > s;
16913     z[4] = t;
16914     s = x[5];
16915     t = s - cy;
16916     cy = t > s;
16917     z[5] = t;
16918     s = x[6];
16919     t = s - cy;
16920     cy = t > s;
16921     z[6] = t;
16922     s = x[7];
16923     t = s - cy;
16924     cy = t > s;
16925     z[7] = t;
16926     s = x[8];
16927     t = s - cy;
16928     cy = t > s;
16929     z[8] = t;
16930     s = x[9];
16931     t = s - cy;
16932     cy = t > s;
16933     z[9] = t;
16934     s = x[10];
16935     t = s - cy;
16936     cy = t > s;
16937     z[10] = t;
16938     s = x[11];
16939     t = s - cy;
16940     cy = t > s;
16941     z[11] = t;
16942     s = x[12];
16943     t = s - cy;
16944     cy = t > s;
16945     z[12] = t;
16946     s = x[13];
16947     t = s - cy;
16948     cy = t > s;
16949     z[13] = t;
16950     s = x[14];
16951     t = s - cy;
16952     cy = t > s;
16953     z[14] = t;
16954     return cy;
16955 }
16956 #endif /* !defined(HAVE_native_mpfq_fixmp_15_sub_ui) */
16957 
16958 #if !defined(HAVE_native_mpfq_fixmp_15_add_ui_nc)
16959 /* x, y, and z have 15 words. Result in z. Carry bit is lost. */
16960 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
16961 static inline
mpfq_fixmp_15_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)16962 void mpfq_fixmp_15_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
16963 {
16964     mp_limb_t r, s, t, cy, cy1, cy2;
16965     cy = 0;
16966     r = x[0];
16967     s = r + y;
16968     cy1 = s < r;
16969     t = s + cy;
16970     cy2 = t < s;
16971     cy = cy1 | cy2;
16972     z[0] = t;
16973     s = x[1];
16974     t = s + cy;
16975     cy = t < s;
16976     z[1] = t;
16977     s = x[2];
16978     t = s + cy;
16979     cy = t < s;
16980     z[2] = t;
16981     s = x[3];
16982     t = s + cy;
16983     cy = t < s;
16984     z[3] = t;
16985     s = x[4];
16986     t = s + cy;
16987     cy = t < s;
16988     z[4] = t;
16989     s = x[5];
16990     t = s + cy;
16991     cy = t < s;
16992     z[5] = t;
16993     s = x[6];
16994     t = s + cy;
16995     cy = t < s;
16996     z[6] = t;
16997     s = x[7];
16998     t = s + cy;
16999     cy = t < s;
17000     z[7] = t;
17001     s = x[8];
17002     t = s + cy;
17003     cy = t < s;
17004     z[8] = t;
17005     s = x[9];
17006     t = s + cy;
17007     cy = t < s;
17008     z[9] = t;
17009     s = x[10];
17010     t = s + cy;
17011     cy = t < s;
17012     z[10] = t;
17013     s = x[11];
17014     t = s + cy;
17015     cy = t < s;
17016     z[11] = t;
17017     s = x[12];
17018     t = s + cy;
17019     cy = t < s;
17020     z[12] = t;
17021     s = x[13];
17022     t = s + cy;
17023     cy = t < s;
17024     z[13] = t;
17025     s = x[14];
17026     t = s + cy;
17027     cy = t < s;
17028     z[14] = t;
17029 }
17030 #endif /* !defined(HAVE_native_mpfq_fixmp_15_add_ui_nc) */
17031 
17032 #if !defined(HAVE_native_mpfq_fixmp_15_sub_ui_nc)
17033 /* x, y, and z have 15 words. Result in z. Borrow bit is lost. */
17034 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
17035 static inline
mpfq_fixmp_15_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)17036 void mpfq_fixmp_15_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
17037 {
17038     mp_limb_t r, s, t, cy, cy1, cy2;
17039     cy = 0;
17040     r = x[0];
17041     s = r - y;
17042     cy1 = s > r;
17043     t = s - cy;
17044     cy2 = t > s;
17045     cy = cy1 | cy2;
17046     z[0] = t;
17047     s = x[1];
17048     t = s - cy;
17049     cy = t > s;
17050     z[1] = t;
17051     s = x[2];
17052     t = s - cy;
17053     cy = t > s;
17054     z[2] = t;
17055     s = x[3];
17056     t = s - cy;
17057     cy = t > s;
17058     z[3] = t;
17059     s = x[4];
17060     t = s - cy;
17061     cy = t > s;
17062     z[4] = t;
17063     s = x[5];
17064     t = s - cy;
17065     cy = t > s;
17066     z[5] = t;
17067     s = x[6];
17068     t = s - cy;
17069     cy = t > s;
17070     z[6] = t;
17071     s = x[7];
17072     t = s - cy;
17073     cy = t > s;
17074     z[7] = t;
17075     s = x[8];
17076     t = s - cy;
17077     cy = t > s;
17078     z[8] = t;
17079     s = x[9];
17080     t = s - cy;
17081     cy = t > s;
17082     z[9] = t;
17083     s = x[10];
17084     t = s - cy;
17085     cy = t > s;
17086     z[10] = t;
17087     s = x[11];
17088     t = s - cy;
17089     cy = t > s;
17090     z[11] = t;
17091     s = x[12];
17092     t = s - cy;
17093     cy = t > s;
17094     z[12] = t;
17095     s = x[13];
17096     t = s - cy;
17097     cy = t > s;
17098     z[13] = t;
17099     s = x[14];
17100     t = s - cy;
17101     cy = t > s;
17102     z[14] = t;
17103 }
17104 #endif /* !defined(HAVE_native_mpfq_fixmp_15_sub_ui_nc) */
17105 
17106 #if !defined(HAVE_native_mpfq_fixmp_15_cmp)
17107 /* x and y have 15 words. Return sign of difference x-y. */
17108 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
17109 /* Triggered by: 15_invmod, 15_redc */
17110 static inline
mpfq_fixmp_15_cmp(const mp_limb_t * x,const mp_limb_t * y)17111 int mpfq_fixmp_15_cmp(const mp_limb_t * x, const mp_limb_t * y)
17112 {
17113     for (int i = 15-1; i >= 0; --i) {
17114         if (x[i] > y[i]) return 1;
17115         if (x[i] < y[i]) return -1;
17116     }
17117     return 0;
17118 }
17119 #endif /* !defined(HAVE_native_mpfq_fixmp_15_cmp) */
17120 
17121 #if !defined(HAVE_native_mpfq_fixmp_15_cmp_ui)
17122 /* x has 15 words. Return sign of difference x-y. */
17123 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
17124 /* Triggered by: 15_invmod */
17125 static inline
mpfq_fixmp_15_cmp_ui(const mp_limb_t * x,mp_limb_t y)17126 int mpfq_fixmp_15_cmp_ui(const mp_limb_t * x, mp_limb_t y)
17127 {
17128     for (int i = 15-1; i > 0; --i) {
17129         if (x[i]) return 1;
17130     }
17131     if (x[0]>y) return 1;
17132     if (x[0]<y) return -1;
17133     return 0;
17134 }
17135 #endif /* !defined(HAVE_native_mpfq_fixmp_15_cmp_ui) */
17136 
17137 #if !defined(HAVE_native_mpfq_fixmp_15_addmul1)
17138 /* x has 15 words, z has 17.
17139  * Put (z+x*c) in z. Return carry bit. */
17140 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
17141 /* Triggered by: 15_redc_ur */
17142 static inline
mpfq_fixmp_15_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)17143 mp_limb_t mpfq_fixmp_15_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
17144 {
17145     mp_limb_t hi, lo, carry, buf;
17146     carry = 0;
17147     mpfq_umul_ppmm(hi,lo,c,x[0]);
17148     lo += carry;
17149     carry = (lo<carry) + hi;
17150     buf = z[0];
17151     lo += buf;
17152     carry += (lo<buf);
17153     z[0] = lo;
17154     mpfq_umul_ppmm(hi,lo,c,x[1]);
17155     lo += carry;
17156     carry = (lo<carry) + hi;
17157     buf = z[1];
17158     lo += buf;
17159     carry += (lo<buf);
17160     z[1] = lo;
17161     mpfq_umul_ppmm(hi,lo,c,x[2]);
17162     lo += carry;
17163     carry = (lo<carry) + hi;
17164     buf = z[2];
17165     lo += buf;
17166     carry += (lo<buf);
17167     z[2] = lo;
17168     mpfq_umul_ppmm(hi,lo,c,x[3]);
17169     lo += carry;
17170     carry = (lo<carry) + hi;
17171     buf = z[3];
17172     lo += buf;
17173     carry += (lo<buf);
17174     z[3] = lo;
17175     mpfq_umul_ppmm(hi,lo,c,x[4]);
17176     lo += carry;
17177     carry = (lo<carry) + hi;
17178     buf = z[4];
17179     lo += buf;
17180     carry += (lo<buf);
17181     z[4] = lo;
17182     mpfq_umul_ppmm(hi,lo,c,x[5]);
17183     lo += carry;
17184     carry = (lo<carry) + hi;
17185     buf = z[5];
17186     lo += buf;
17187     carry += (lo<buf);
17188     z[5] = lo;
17189     mpfq_umul_ppmm(hi,lo,c,x[6]);
17190     lo += carry;
17191     carry = (lo<carry) + hi;
17192     buf = z[6];
17193     lo += buf;
17194     carry += (lo<buf);
17195     z[6] = lo;
17196     mpfq_umul_ppmm(hi,lo,c,x[7]);
17197     lo += carry;
17198     carry = (lo<carry) + hi;
17199     buf = z[7];
17200     lo += buf;
17201     carry += (lo<buf);
17202     z[7] = lo;
17203     mpfq_umul_ppmm(hi,lo,c,x[8]);
17204     lo += carry;
17205     carry = (lo<carry) + hi;
17206     buf = z[8];
17207     lo += buf;
17208     carry += (lo<buf);
17209     z[8] = lo;
17210     mpfq_umul_ppmm(hi,lo,c,x[9]);
17211     lo += carry;
17212     carry = (lo<carry) + hi;
17213     buf = z[9];
17214     lo += buf;
17215     carry += (lo<buf);
17216     z[9] = lo;
17217     mpfq_umul_ppmm(hi,lo,c,x[10]);
17218     lo += carry;
17219     carry = (lo<carry) + hi;
17220     buf = z[10];
17221     lo += buf;
17222     carry += (lo<buf);
17223     z[10] = lo;
17224     mpfq_umul_ppmm(hi,lo,c,x[11]);
17225     lo += carry;
17226     carry = (lo<carry) + hi;
17227     buf = z[11];
17228     lo += buf;
17229     carry += (lo<buf);
17230     z[11] = lo;
17231     mpfq_umul_ppmm(hi,lo,c,x[12]);
17232     lo += carry;
17233     carry = (lo<carry) + hi;
17234     buf = z[12];
17235     lo += buf;
17236     carry += (lo<buf);
17237     z[12] = lo;
17238     mpfq_umul_ppmm(hi,lo,c,x[13]);
17239     lo += carry;
17240     carry = (lo<carry) + hi;
17241     buf = z[13];
17242     lo += buf;
17243     carry += (lo<buf);
17244     z[13] = lo;
17245     mpfq_umul_ppmm(hi,lo,c,x[14]);
17246     lo += carry;
17247     carry = (lo<carry) + hi;
17248     buf = z[14];
17249     lo += buf;
17250     carry += (lo<buf);
17251     z[14] = lo;
17252     z[15] += carry;
17253     return (z[15]<carry);
17254 }
17255 #endif /* !defined(HAVE_native_mpfq_fixmp_15_addmul1) */
17256 
17257 #if !defined(HAVE_native_mpfq_fixmp_15_addmul1_nc)
17258 /* x has 15 words, z has 17.
17259  * Put (z+x*c) in z. Carry bit is lost. */
17260 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
17261 /* Triggered by: 15_mul, 15_mgy_decode */
17262 static inline
mpfq_fixmp_15_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)17263 void mpfq_fixmp_15_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
17264 {
17265     mp_limb_t hi, lo, carry, buf;
17266     carry = 0;
17267     mpfq_umul_ppmm(hi,lo,c,x[0]);
17268     lo += carry;
17269     carry = (lo<carry) + hi;
17270     buf = z[0];
17271     lo += buf;
17272     carry += (lo<buf);
17273     z[0] = lo;
17274     mpfq_umul_ppmm(hi,lo,c,x[1]);
17275     lo += carry;
17276     carry = (lo<carry) + hi;
17277     buf = z[1];
17278     lo += buf;
17279     carry += (lo<buf);
17280     z[1] = lo;
17281     mpfq_umul_ppmm(hi,lo,c,x[2]);
17282     lo += carry;
17283     carry = (lo<carry) + hi;
17284     buf = z[2];
17285     lo += buf;
17286     carry += (lo<buf);
17287     z[2] = lo;
17288     mpfq_umul_ppmm(hi,lo,c,x[3]);
17289     lo += carry;
17290     carry = (lo<carry) + hi;
17291     buf = z[3];
17292     lo += buf;
17293     carry += (lo<buf);
17294     z[3] = lo;
17295     mpfq_umul_ppmm(hi,lo,c,x[4]);
17296     lo += carry;
17297     carry = (lo<carry) + hi;
17298     buf = z[4];
17299     lo += buf;
17300     carry += (lo<buf);
17301     z[4] = lo;
17302     mpfq_umul_ppmm(hi,lo,c,x[5]);
17303     lo += carry;
17304     carry = (lo<carry) + hi;
17305     buf = z[5];
17306     lo += buf;
17307     carry += (lo<buf);
17308     z[5] = lo;
17309     mpfq_umul_ppmm(hi,lo,c,x[6]);
17310     lo += carry;
17311     carry = (lo<carry) + hi;
17312     buf = z[6];
17313     lo += buf;
17314     carry += (lo<buf);
17315     z[6] = lo;
17316     mpfq_umul_ppmm(hi,lo,c,x[7]);
17317     lo += carry;
17318     carry = (lo<carry) + hi;
17319     buf = z[7];
17320     lo += buf;
17321     carry += (lo<buf);
17322     z[7] = lo;
17323     mpfq_umul_ppmm(hi,lo,c,x[8]);
17324     lo += carry;
17325     carry = (lo<carry) + hi;
17326     buf = z[8];
17327     lo += buf;
17328     carry += (lo<buf);
17329     z[8] = lo;
17330     mpfq_umul_ppmm(hi,lo,c,x[9]);
17331     lo += carry;
17332     carry = (lo<carry) + hi;
17333     buf = z[9];
17334     lo += buf;
17335     carry += (lo<buf);
17336     z[9] = lo;
17337     mpfq_umul_ppmm(hi,lo,c,x[10]);
17338     lo += carry;
17339     carry = (lo<carry) + hi;
17340     buf = z[10];
17341     lo += buf;
17342     carry += (lo<buf);
17343     z[10] = lo;
17344     mpfq_umul_ppmm(hi,lo,c,x[11]);
17345     lo += carry;
17346     carry = (lo<carry) + hi;
17347     buf = z[11];
17348     lo += buf;
17349     carry += (lo<buf);
17350     z[11] = lo;
17351     mpfq_umul_ppmm(hi,lo,c,x[12]);
17352     lo += carry;
17353     carry = (lo<carry) + hi;
17354     buf = z[12];
17355     lo += buf;
17356     carry += (lo<buf);
17357     z[12] = lo;
17358     mpfq_umul_ppmm(hi,lo,c,x[13]);
17359     lo += carry;
17360     carry = (lo<carry) + hi;
17361     buf = z[13];
17362     lo += buf;
17363     carry += (lo<buf);
17364     z[13] = lo;
17365     mpfq_umul_ppmm(hi,lo,c,x[14]);
17366     lo += carry;
17367     carry = (lo<carry) + hi;
17368     buf = z[14];
17369     lo += buf;
17370     carry += (lo<buf);
17371     z[14] = lo;
17372     z[15] += carry;
17373 }
17374 #endif /* !defined(HAVE_native_mpfq_fixmp_15_addmul1_nc) */
17375 
17376 #if !defined(HAVE_native_mpfq_fixmp_15_addmul1_shortz)
17377 /* x has 15 words, z has 16.
17378  * Put (z+x*c) in z. Return carry word. */
17379 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
17380 /* Triggered by: 15_redc */
17381 static inline
mpfq_fixmp_15_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)17382 mp_limb_t mpfq_fixmp_15_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
17383 {
17384     mp_limb_t hi, lo, carry, buf;
17385     carry = 0;
17386     mpfq_umul_ppmm(hi,lo,c,x[0]);
17387     lo += carry;
17388     carry = (lo<carry) + hi;
17389     buf = z[0];
17390     lo += buf;
17391     carry += (lo<buf);
17392     z[0] = lo;
17393     mpfq_umul_ppmm(hi,lo,c,x[1]);
17394     lo += carry;
17395     carry = (lo<carry) + hi;
17396     buf = z[1];
17397     lo += buf;
17398     carry += (lo<buf);
17399     z[1] = lo;
17400     mpfq_umul_ppmm(hi,lo,c,x[2]);
17401     lo += carry;
17402     carry = (lo<carry) + hi;
17403     buf = z[2];
17404     lo += buf;
17405     carry += (lo<buf);
17406     z[2] = lo;
17407     mpfq_umul_ppmm(hi,lo,c,x[3]);
17408     lo += carry;
17409     carry = (lo<carry) + hi;
17410     buf = z[3];
17411     lo += buf;
17412     carry += (lo<buf);
17413     z[3] = lo;
17414     mpfq_umul_ppmm(hi,lo,c,x[4]);
17415     lo += carry;
17416     carry = (lo<carry) + hi;
17417     buf = z[4];
17418     lo += buf;
17419     carry += (lo<buf);
17420     z[4] = lo;
17421     mpfq_umul_ppmm(hi,lo,c,x[5]);
17422     lo += carry;
17423     carry = (lo<carry) + hi;
17424     buf = z[5];
17425     lo += buf;
17426     carry += (lo<buf);
17427     z[5] = lo;
17428     mpfq_umul_ppmm(hi,lo,c,x[6]);
17429     lo += carry;
17430     carry = (lo<carry) + hi;
17431     buf = z[6];
17432     lo += buf;
17433     carry += (lo<buf);
17434     z[6] = lo;
17435     mpfq_umul_ppmm(hi,lo,c,x[7]);
17436     lo += carry;
17437     carry = (lo<carry) + hi;
17438     buf = z[7];
17439     lo += buf;
17440     carry += (lo<buf);
17441     z[7] = lo;
17442     mpfq_umul_ppmm(hi,lo,c,x[8]);
17443     lo += carry;
17444     carry = (lo<carry) + hi;
17445     buf = z[8];
17446     lo += buf;
17447     carry += (lo<buf);
17448     z[8] = lo;
17449     mpfq_umul_ppmm(hi,lo,c,x[9]);
17450     lo += carry;
17451     carry = (lo<carry) + hi;
17452     buf = z[9];
17453     lo += buf;
17454     carry += (lo<buf);
17455     z[9] = lo;
17456     mpfq_umul_ppmm(hi,lo,c,x[10]);
17457     lo += carry;
17458     carry = (lo<carry) + hi;
17459     buf = z[10];
17460     lo += buf;
17461     carry += (lo<buf);
17462     z[10] = lo;
17463     mpfq_umul_ppmm(hi,lo,c,x[11]);
17464     lo += carry;
17465     carry = (lo<carry) + hi;
17466     buf = z[11];
17467     lo += buf;
17468     carry += (lo<buf);
17469     z[11] = lo;
17470     mpfq_umul_ppmm(hi,lo,c,x[12]);
17471     lo += carry;
17472     carry = (lo<carry) + hi;
17473     buf = z[12];
17474     lo += buf;
17475     carry += (lo<buf);
17476     z[12] = lo;
17477     mpfq_umul_ppmm(hi,lo,c,x[13]);
17478     lo += carry;
17479     carry = (lo<carry) + hi;
17480     buf = z[13];
17481     lo += buf;
17482     carry += (lo<buf);
17483     z[13] = lo;
17484     mpfq_umul_ppmm(hi,lo,c,x[14]);
17485     lo += carry;
17486     carry = (lo<carry) + hi;
17487     buf = z[14];
17488     lo += buf;
17489     carry += (lo<buf);
17490     z[14] = lo;
17491     return carry;
17492 }
17493 #endif /* !defined(HAVE_native_mpfq_fixmp_15_addmul1_shortz) */
17494 
17495 #if !defined(HAVE_native_mpfq_fixmp_15_mul)
17496 /* x and y have 15 words, z has 32. Put x*y in z. */
17497 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
17498 /* Triggered by: 15_mgy_decode */
17499 static inline
mpfq_fixmp_15_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)17500 void mpfq_fixmp_15_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
17501 {
17502     assert(z != x && z != y);
17503     for (int i = 0; i < 30; z[i++] = 0) ;
17504     mpfq_fixmp_15_addmul1_nc (z + 0, x, y[0]);
17505     mpfq_fixmp_15_addmul1_nc (z + 1, x, y[1]);
17506     mpfq_fixmp_15_addmul1_nc (z + 2, x, y[2]);
17507     mpfq_fixmp_15_addmul1_nc (z + 3, x, y[3]);
17508     mpfq_fixmp_15_addmul1_nc (z + 4, x, y[4]);
17509     mpfq_fixmp_15_addmul1_nc (z + 5, x, y[5]);
17510     mpfq_fixmp_15_addmul1_nc (z + 6, x, y[6]);
17511     mpfq_fixmp_15_addmul1_nc (z + 7, x, y[7]);
17512     mpfq_fixmp_15_addmul1_nc (z + 8, x, y[8]);
17513     mpfq_fixmp_15_addmul1_nc (z + 9, x, y[9]);
17514     mpfq_fixmp_15_addmul1_nc (z + 10, x, y[10]);
17515     mpfq_fixmp_15_addmul1_nc (z + 11, x, y[11]);
17516     mpfq_fixmp_15_addmul1_nc (z + 12, x, y[12]);
17517     mpfq_fixmp_15_addmul1_nc (z + 13, x, y[13]);
17518     mpfq_fixmp_15_addmul1_nc (z + 14, x, y[14]);
17519 }
17520 #endif /* !defined(HAVE_native_mpfq_fixmp_15_mul) */
17521 
17522 #if !defined(HAVE_native_mpfq_fixmp_15_sqr)
17523 /* x has 15 words, z has 32. Put x*y in z. */
17524 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
17525 static inline
mpfq_fixmp_15_sqr(mp_limb_t * z,const mp_limb_t * x)17526 void mpfq_fixmp_15_sqr(mp_limb_t * z, const mp_limb_t * x)
17527 {
17528     mp_limb_t buf[30] = {0,};
17529     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
17530     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
17531     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
17532     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
17533     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
17534     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
17535     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
17536     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
17537     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
17538     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
17539     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
17540     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
17541     mpfq_fixmp_13_addmul1_nc(buf + 13, x, x[13]);
17542     mpfq_fixmp_14_addmul1_nc(buf + 14, x, x[14]);
17543     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
17544     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
17545     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
17546     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
17547     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
17548     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
17549     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
17550     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
17551     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
17552     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
17553     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
17554     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
17555     mpfq_umul_ppmm(z[2*12+1], z[2*12], x[12], x[12]);
17556     mpfq_umul_ppmm(z[2*13+1], z[2*13], x[13], x[13]);
17557     mpfq_umul_ppmm(z[2*14+1], z[2*14], x[14], x[14]);
17558     mpn_lshift(buf, buf, 30, 1);
17559     mpn_add_n(z, z, buf, 30);
17560 }
17561 #endif /* !defined(HAVE_native_mpfq_fixmp_15_sqr) */
17562 
17563 #if !defined(HAVE_native_mpfq_fixmp_15_mul1)
17564 /* x has 15 words, z has 17. Put x*y in z. */
17565 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
17566 static inline
mpfq_fixmp_15_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)17567 void mpfq_fixmp_15_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
17568 {
17569     mp_limb_t hi, lo, carry;
17570     carry = 0;
17571     mpfq_umul_ppmm(hi,lo,c,x[0]);
17572     lo += carry;
17573     carry = (lo<carry) + hi;
17574     z[0] = lo;
17575     mpfq_umul_ppmm(hi,lo,c,x[1]);
17576     lo += carry;
17577     carry = (lo<carry) + hi;
17578     z[1] = lo;
17579     mpfq_umul_ppmm(hi,lo,c,x[2]);
17580     lo += carry;
17581     carry = (lo<carry) + hi;
17582     z[2] = lo;
17583     mpfq_umul_ppmm(hi,lo,c,x[3]);
17584     lo += carry;
17585     carry = (lo<carry) + hi;
17586     z[3] = lo;
17587     mpfq_umul_ppmm(hi,lo,c,x[4]);
17588     lo += carry;
17589     carry = (lo<carry) + hi;
17590     z[4] = lo;
17591     mpfq_umul_ppmm(hi,lo,c,x[5]);
17592     lo += carry;
17593     carry = (lo<carry) + hi;
17594     z[5] = lo;
17595     mpfq_umul_ppmm(hi,lo,c,x[6]);
17596     lo += carry;
17597     carry = (lo<carry) + hi;
17598     z[6] = lo;
17599     mpfq_umul_ppmm(hi,lo,c,x[7]);
17600     lo += carry;
17601     carry = (lo<carry) + hi;
17602     z[7] = lo;
17603     mpfq_umul_ppmm(hi,lo,c,x[8]);
17604     lo += carry;
17605     carry = (lo<carry) + hi;
17606     z[8] = lo;
17607     mpfq_umul_ppmm(hi,lo,c,x[9]);
17608     lo += carry;
17609     carry = (lo<carry) + hi;
17610     z[9] = lo;
17611     mpfq_umul_ppmm(hi,lo,c,x[10]);
17612     lo += carry;
17613     carry = (lo<carry) + hi;
17614     z[10] = lo;
17615     mpfq_umul_ppmm(hi,lo,c,x[11]);
17616     lo += carry;
17617     carry = (lo<carry) + hi;
17618     z[11] = lo;
17619     mpfq_umul_ppmm(hi,lo,c,x[12]);
17620     lo += carry;
17621     carry = (lo<carry) + hi;
17622     z[12] = lo;
17623     mpfq_umul_ppmm(hi,lo,c,x[13]);
17624     lo += carry;
17625     carry = (lo<carry) + hi;
17626     z[13] = lo;
17627     mpfq_umul_ppmm(hi,lo,c,x[14]);
17628     lo += carry;
17629     carry = (lo<carry) + hi;
17630     z[14] = lo;
17631     z[15] = carry;
17632 }
17633 #endif /* !defined(HAVE_native_mpfq_fixmp_15_mul1) */
17634 
17635 #if !defined(HAVE_native_mpfq_fixmp_15_shortmul)
17636 /* x and y have 15 words, z has 16.
17637  * Put the low 16 words of x*y in z. */
17638 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
17639 static inline
mpfq_fixmp_15_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)17640 void mpfq_fixmp_15_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
17641 {
17642     mpfq_zero(z, 15);
17643     mpfq_fixmp_14_addmul1_nc (z+0, x, y[0]);
17644     z[15-1] += x[14]*y[0];
17645     mpfq_fixmp_13_addmul1_nc (z+1, x, y[1]);
17646     z[15-1] += x[13]*y[1];
17647     mpfq_fixmp_12_addmul1_nc (z+2, x, y[2]);
17648     z[15-1] += x[12]*y[2];
17649     mpfq_fixmp_11_addmul1_nc (z+3, x, y[3]);
17650     z[15-1] += x[11]*y[3];
17651     mpfq_fixmp_10_addmul1_nc (z+4, x, y[4]);
17652     z[15-1] += x[10]*y[4];
17653     mpfq_fixmp_9_addmul1_nc (z+5, x, y[5]);
17654     z[15-1] += x[9]*y[5];
17655     mpfq_fixmp_8_addmul1_nc (z+6, x, y[6]);
17656     z[15-1] += x[8]*y[6];
17657     mpfq_fixmp_7_addmul1_nc (z+7, x, y[7]);
17658     z[15-1] += x[7]*y[7];
17659     mpfq_fixmp_6_addmul1_nc (z+8, x, y[8]);
17660     z[15-1] += x[6]*y[8];
17661     mpfq_fixmp_5_addmul1_nc (z+9, x, y[9]);
17662     z[15-1] += x[5]*y[9];
17663     mpfq_fixmp_4_addmul1_nc (z+10, x, y[10]);
17664     z[15-1] += x[4]*y[10];
17665     mpfq_fixmp_3_addmul1_nc (z+11, x, y[11]);
17666     z[15-1] += x[3]*y[11];
17667     mpfq_fixmp_2_addmul1_nc (z+12, x, y[12]);
17668     z[15-1] += x[2]*y[12];
17669     mpfq_fixmp_1_addmul1_nc (z+13, x, y[13]);
17670     z[15-1] += x[1]*y[13];
17671     z[15-1] += x[0]*y[15-1];
17672 }
17673 #endif /* !defined(HAVE_native_mpfq_fixmp_15_shortmul) */
17674 
17675 #if !defined(HAVE_native_mpfq_fixmp_15_mod)
17676 /* x has 32 words. z and p have 15 words, and the high word of p is non-zero.
17677  * Put x mod p in z. */
17678 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
17679 /* Triggered by: 15_mgy_decode */
17680 static inline
mpfq_fixmp_15_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)17681 void mpfq_fixmp_15_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
17682 {
17683     mp_limb_t q[15+1], r[15];
17684     assert (p[15-1] != 0);
17685     mpn_tdiv_qr(q, r, 0, x, 30, p, 15);
17686     mpfq_copy(z, r, 15);
17687 }
17688 #endif /* !defined(HAVE_native_mpfq_fixmp_15_mod) */
17689 
17690 #if !defined(HAVE_native_mpfq_fixmp_15_rshift)
17691 /* a has 15 words. Shift it in place by cnt bits to the right.
17692  * The shift count cnt must not exceed the word size.
17693  * Note that no carry is returned for the bits shifted out. */
17694 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
17695 /* Triggered by: 15_invmod */
17696 static inline
mpfq_fixmp_15_rshift(mp_limb_t * a,int cnt)17697 void mpfq_fixmp_15_rshift(mp_limb_t * a, int cnt)
17698 {
17699     if (!cnt) return;
17700     int i;
17701     int dnt = GMP_NUMB_BITS - cnt;
17702     for (i = 0; i < 15-1; ++i) {
17703         a[i] >>= cnt;
17704         a[i] |= (a[i+1] << dnt);
17705     }
17706     a[15-1] >>= cnt;
17707 }
17708 #endif /* !defined(HAVE_native_mpfq_fixmp_15_rshift) */
17709 
17710 #if !defined(HAVE_native_mpfq_fixmp_15_long_rshift)
17711 /* a has 15 words. Shift it in place by off words plus cnt bits to the left.
17712  * Note that no carry is returned for the bits shifted out. */
17713 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
17714 /* Triggered by: 15_invmod */
17715 static inline
mpfq_fixmp_15_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)17716 void mpfq_fixmp_15_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
17717 {
17718     if (cnt) {
17719         int dnt = GMP_NUMB_BITS - cnt;
17720         for (int i = 0; i < 15 - off - 1; ++i) {
17721             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
17722         }
17723         a[15-off-1] = a[15-1]>>cnt;
17724     } else {
17725         mpfq_copyi(a, a + off, 15 - off);
17726     }
17727     mpfq_zero(a + 15 - off, off);
17728 }
17729 #endif /* !defined(HAVE_native_mpfq_fixmp_15_long_rshift) */
17730 
17731 #if !defined(HAVE_native_mpfq_fixmp_15_long_lshift)
17732 /* a has 15 words. Shift it in place by off words plus cnt bits to the left.
17733  * Note that no carry is returned for the bits shifted out. */
17734 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
17735 /* Triggered by: 15_invmod */
17736 static inline
mpfq_fixmp_15_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)17737 void mpfq_fixmp_15_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
17738 {
17739     int i;
17740     if (cnt) {
17741         int dnt = GMP_NUMB_BITS - cnt;
17742         for (i = 15-1; i>off; --i) {
17743             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
17744         }
17745         a[off] = a[0]<<cnt;
17746     } else {
17747         mpfq_copyd(a + off, a, 15 - off);
17748     }
17749     mpfq_zero(a, off);
17750 }
17751 #endif /* !defined(HAVE_native_mpfq_fixmp_15_long_lshift) */
17752 
17753 #if !defined(HAVE_native_mpfq_fixmp_15_invmod)
17754 /* x, z, and p have 15 words. Put inverse of x mod p in z.
17755  * Return non-zero if an inverse could be found.
17756  * If no inverse could be found, return 0 and set z to zero.
17757  */
17758 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
17759 static inline
mpfq_fixmp_15_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)17760 int mpfq_fixmp_15_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
17761 {
17762       mp_limb_t u[15], v[15], a[15], b[15], fix[15];
17763       int i, t, lsh;
17764 
17765       mpfq_zero(u, 15);
17766       mpfq_zero(v, 15);
17767       mpfq_copy(a, x, 15);
17768       mpfq_copy(b, p, 15);
17769       u[0] = 1UL;
17770 
17771       if (mpfq_fixmp_15_cmp(a, v) == 0 || mpfq_fixmp_15_cmp(a, b) == 0) {
17772         mpfq_zero(res, 15);
17773         return 0;
17774       }
17775 
17776       mpfq_fixmp_15_add(fix, b, u);
17777       mpfq_fixmp_15_rshift(fix, 1);
17778 
17779       assert (mpfq_fixmp_15_cmp(a,b) < 0);
17780 
17781       t = 0;
17782 
17783       for(i = 0 ; !a[i] ; i++) ;
17784       assert (i < 15);
17785       lsh = mpfq_ctzl(a[i]);
17786       mpfq_fixmp_15_long_rshift(a, i, lsh);
17787       t += lsh + i*GMP_NUMB_BITS;
17788       mpfq_fixmp_15_long_lshift(v, i, lsh);
17789 
17790       do {
17791         do {
17792           mpfq_fixmp_15_sub(b, b, a);
17793           mpfq_fixmp_15_add(v, v, u);
17794           for(i = 0 ; !b[i] ; i++) ;
17795           assert (i < 15);
17796           lsh = mpfq_ctzl(b[i]);
17797           mpfq_fixmp_15_long_rshift(b, i, lsh);
17798           t += lsh + i*GMP_NUMB_BITS;
17799           mpfq_fixmp_15_long_lshift(u, i, lsh);
17800         } while (mpfq_fixmp_15_cmp(a,b) < 0);
17801         if (mpfq_fixmp_15_cmp(a, b) == 0)
17802           break;
17803         do {
17804           mpfq_fixmp_15_sub(a, a, b);
17805           mpfq_fixmp_15_add(u, u, v);
17806           for(i = 0 ; !a[i] ; i++) ;
17807           assert (i < 15);
17808           lsh = mpfq_ctzl(a[i]);
17809           mpfq_fixmp_15_long_rshift(a, i, lsh);
17810           t += lsh + i*GMP_NUMB_BITS;
17811           mpfq_fixmp_15_long_lshift(v, i, lsh);
17812         } while (mpfq_fixmp_15_cmp(b,a)<0);
17813       } while (mpfq_fixmp_15_cmp(a,b) != 0);
17814       {
17815         if (mpfq_fixmp_15_cmp_ui(a, 1) != 0) {
17816           mpfq_copy(res, a, 15);
17817           return 0;
17818         }
17819       }
17820       while (t>0) {
17821         mp_limb_t sig = u[0] & 1UL;
17822         mpfq_fixmp_15_rshift(u, 1);
17823         if (sig)
17824           mpfq_fixmp_15_add(u, u, fix);
17825         --t;
17826       }
17827       mpfq_copy(res, u, 15);
17828       return 1;
17829 }
17830 #endif /* !defined(HAVE_native_mpfq_fixmp_15_invmod) */
17831 
17832 #if !defined(HAVE_native_mpfq_fixmp_15_redc)
17833 /* x has 32 words, z and p have 15 words.
17834  * only one word is read from invp.
17835  * Assuming R=W^16 is the redc modulus, we expect that x verifies:
17836  *   x < R*p,
17837  * so that we have eventually z < p, z congruent to x/R mod p.
17838  * The contents of the area pointed by x are clobbered by this call.
17839  * Note also that x may alias z.
17840  */
17841 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
17842 static inline
mpfq_fixmp_15_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)17843 void mpfq_fixmp_15_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
17844 {
17845     mp_limb_t cy;
17846     for(int i = 0; i < 15; ++i) {
17847         mp_limb_t t = x[i]*mip[0];
17848         cy = mpfq_fixmp_15_addmul1_shortz(x+i, p, t);
17849         assert (x[i] == 0);
17850         x[i] = cy;
17851     }
17852     cy = mpfq_fixmp_15_add(x, x, x + 15);
17853     /* At this point, we have (x' denotes x + cy*W^n here)
17854     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
17855     * x'/R < p + p
17856     */
17857     if (cy || mpfq_fixmp_15_cmp(x, p) >= 0) {
17858         mpfq_fixmp_15_sub(z, x, p);
17859     } else {
17860         mpfq_copy(z, x, 15);
17861     }
17862 }
17863 #endif /* !defined(HAVE_native_mpfq_fixmp_15_redc) */
17864 
17865 #if !defined(HAVE_native_mpfq_fixmp_15_redc_ur)
17866 /* x has 33 words, z and p have 15 words.
17867  * only one word is read from invp.
17868  * Assuming R=W^16 is the redc modulus, we expect that x verifies:
17869  *  x < W*W^15*p = W^0.5*R*p or the hw case, W*R*p otherwise,
17870  * so that we have eventually z < p, z congruent to x/R mod p.
17871  * The contents of the area pointed by x are clobbered by this call.
17872  * Note also that x may alias z.
17873  */
17874 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
17875 static inline
mpfq_fixmp_15_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)17876 void mpfq_fixmp_15_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
17877 {
17878     mp_limb_t cy, q[2];
17879     for (int i = 0; i < 15; ++i) {
17880         mp_limb_t t = x[i]*mip[0];
17881         cy = mpfq_fixmp_15_addmul1(x+i, p, t);
17882         assert (x[i] == 0);
17883         x[i] = cy;
17884     }
17885     cy=mpfq_fixmp_15_add(x+15+1, x+15+1, x);
17886     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
17887     * x' <= W*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
17888     * x'/R < (W+1)*p
17889     */
17890     if (cy) {
17891         /* x'/R-p < W*p, which fits in n+1 words */
17892         mpn_sub(x+15,x+15,15+1,p,15);
17893     }
17894     mpn_tdiv_qr(q, z, 0, x+15, 15+1, p, 15);
17895 }
17896 #endif /* !defined(HAVE_native_mpfq_fixmp_15_redc_ur) */
17897 
17898 #if !defined(HAVE_native_mpfq_fixmp_15_mgy_encode)
17899 /* x, z, and p have 15 words.
17900  * Assuming R=W^16 is the redc modulus, we compute z=R*x mod p. */
17901 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
17902 static inline
mpfq_fixmp_15_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)17903 void mpfq_fixmp_15_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
17904 {
17905     mp_limb_t t[30] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14] };
17906     mpfq_fixmp_15_mod(z, t, p);
17907 }
17908 #endif /* !defined(HAVE_native_mpfq_fixmp_15_mgy_encode) */
17909 
17910 #if !defined(HAVE_native_mpfq_fixmp_15_mgy_decode)
17911 /* x, z, invR, and p have 15 words.
17912  * Assuming R=W^16 is the redc modulus, we compute z=x/R mod p. */
17913 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
17914 static inline
mpfq_fixmp_15_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)17915 void mpfq_fixmp_15_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
17916 {
17917     mp_limb_t t[30];
17918     mpfq_fixmp_15_mul(t, x, invR);
17919     mpfq_fixmp_15_mod(z, t, p);
17920 }
17921 #endif /* !defined(HAVE_native_mpfq_fixmp_15_mgy_decode) */
17922 
17923 #if !defined(HAVE_native_mpfq_fixmp_15_lshift)
17924 /* a has 15 words. Shift it in place by cnt bits to the left.
17925  * The shift count cnt must not exceed the word size.
17926  * Note that no carry is returned for the bits shifted out. */
17927 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
17928 static inline
mpfq_fixmp_15_lshift(mp_limb_t * a,int cnt)17929 void mpfq_fixmp_15_lshift(mp_limb_t * a, int cnt)
17930 {
17931     if (!cnt) return;
17932     int i;
17933     int dnt = GMP_NUMB_BITS - cnt;
17934     for (i = 15-1; i>0; --i) {
17935         a[i] <<= cnt;
17936         a[i] |= (a[i-1] >> dnt);
17937     }
17938     a[0] <<= cnt;
17939 }
17940 #endif /* !defined(HAVE_native_mpfq_fixmp_15_lshift) */
17941 
17942 #if !defined(HAVE_native_mpfq_fixmp_0_5_add)
17943 /* x, y, and z have 0.5 words. Result in z. Return carry bit */
17944 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
17945 /* Triggered by: 0_5_redc_ur */
17946 static inline
mpfq_fixmp_0_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)17947 mp_limb_t mpfq_fixmp_0_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
17948 {
17949     mp_limb_t r, s, t, cy, cy1, cy2;
17950     cy = 0;
17951     r = x[0];
17952     s = r + y[0];
17953     cy1 = s < r;
17954     t = s + cy;
17955     cy2 = t < s;
17956     cy = cy1 | cy2;
17957     z[0] = t;
17958     return cy;
17959 }
17960 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_add) */
17961 
17962 #if !defined(HAVE_native_mpfq_fixmp_0_5_sub)
17963 /* x, y, and z have 0.5 words. Result in z. Return borrow bit */
17964 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
17965 /* Triggered by: 0_5_redc_ur */
17966 static inline
mpfq_fixmp_0_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)17967 mp_limb_t mpfq_fixmp_0_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
17968 {
17969     mp_limb_t r, s, t, cy, cy1, cy2;
17970     cy = 0;
17971     r = x[0];
17972     s = r - y[0];
17973     cy1 = s > r;
17974     t = s - cy;
17975     cy2 = t > s;
17976     cy = cy1 | cy2;
17977     z[0] = t;
17978     return cy;
17979 }
17980 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_sub) */
17981 
17982 #if !defined(HAVE_native_mpfq_fixmp_0_5_add_nc)
17983 /* x, y, and z have 0.5 words. Result in z. Carry bit is lost. */
17984 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
17985 static inline
mpfq_fixmp_0_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)17986 void mpfq_fixmp_0_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
17987 {
17988     mp_limb_t r, s, t, cy, cy1, cy2;
17989     cy = 0;
17990     r = x[0];
17991     s = r + y[0];
17992     cy1 = s < r;
17993     t = s + cy;
17994     cy2 = t < s;
17995     cy = cy1 | cy2;
17996     z[0] = t;
17997 }
17998 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_add_nc) */
17999 
18000 #if !defined(HAVE_native_mpfq_fixmp_0_5_sub_nc)
18001 /* x, y, and z have 0.5 words. Result in z. Borrow bit is lost. */
18002 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
18003 static inline
mpfq_fixmp_0_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18004 void mpfq_fixmp_0_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18005 {
18006     mp_limb_t r, s, t, cy, cy1, cy2;
18007     cy = 0;
18008     r = x[0];
18009     s = r - y[0];
18010     cy1 = s > r;
18011     t = s - cy;
18012     cy2 = t > s;
18013     cy = cy1 | cy2;
18014     z[0] = t;
18015 }
18016 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_sub_nc) */
18017 
18018 #if !defined(HAVE_native_mpfq_fixmp_0_5_add_ui)
18019 /* x, y, and z have 0.5 words. Result in z. Return carry bit */
18020 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
18021 static inline
mpfq_fixmp_0_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18022 mp_limb_t mpfq_fixmp_0_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18023 {
18024     mp_limb_t r, s, t, cy, cy1, cy2;
18025     cy = 0;
18026     r = x[0];
18027     s = r + y;
18028     cy1 = s < r;
18029     t = s + cy;
18030     cy2 = t < s;
18031     cy = cy1 | cy2;
18032     z[0] = t;
18033     return cy;
18034 }
18035 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_add_ui) */
18036 
18037 #if !defined(HAVE_native_mpfq_fixmp_0_5_sub_ui)
18038 /* x, y, and z have 0.5 words. Result in z. Return borrow bit */
18039 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
18040 static inline
mpfq_fixmp_0_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18041 mp_limb_t mpfq_fixmp_0_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18042 {
18043     mp_limb_t r, s, t, cy, cy1, cy2;
18044     cy = 0;
18045     r = x[0];
18046     s = r - y;
18047     cy1 = s > r;
18048     t = s - cy;
18049     cy2 = t > s;
18050     cy = cy1 | cy2;
18051     z[0] = t;
18052     return cy;
18053 }
18054 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_sub_ui) */
18055 
18056 #if !defined(HAVE_native_mpfq_fixmp_0_5_add_ui_nc)
18057 /* x, y, and z have 0.5 words. Result in z. Carry bit is lost. */
18058 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
18059 static inline
mpfq_fixmp_0_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18060 void mpfq_fixmp_0_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18061 {
18062     mp_limb_t r, s, t, cy, cy1, cy2;
18063     cy = 0;
18064     r = x[0];
18065     s = r + y;
18066     cy1 = s < r;
18067     t = s + cy;
18068     cy2 = t < s;
18069     cy = cy1 | cy2;
18070     z[0] = t;
18071 }
18072 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_add_ui_nc) */
18073 
18074 #if !defined(HAVE_native_mpfq_fixmp_0_5_sub_ui_nc)
18075 /* x, y, and z have 0.5 words. Result in z. Borrow bit is lost. */
18076 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
18077 static inline
mpfq_fixmp_0_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18078 void mpfq_fixmp_0_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18079 {
18080     mp_limb_t r, s, t, cy, cy1, cy2;
18081     cy = 0;
18082     r = x[0];
18083     s = r - y;
18084     cy1 = s > r;
18085     t = s - cy;
18086     cy2 = t > s;
18087     cy = cy1 | cy2;
18088     z[0] = t;
18089 }
18090 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_sub_ui_nc) */
18091 
18092 #if !defined(HAVE_native_mpfq_fixmp_0_5_cmp)
18093 /* x and y have 0.5 words. Return sign of difference x-y. */
18094 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
18095 /* Triggered by: 0_5_redc_ur */
18096 static inline
mpfq_fixmp_0_5_cmp(const mp_limb_t * x,const mp_limb_t * y)18097 int mpfq_fixmp_0_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
18098 {
18099     for (int i = 1-1; i >= 0; --i) {
18100         if (x[i] > y[i]) return 1;
18101         if (x[i] < y[i]) return -1;
18102     }
18103     return 0;
18104 }
18105 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_cmp) */
18106 
18107 #if !defined(HAVE_native_mpfq_fixmp_0_5_cmp_ui)
18108 /* x has 0.5 words. Return sign of difference x-y. */
18109 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
18110 static inline
mpfq_fixmp_0_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)18111 int mpfq_fixmp_0_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
18112 {
18113     if (x[0]>y) return 1;
18114     if (x[0]<y) return -1;
18115     return 0;
18116 }
18117 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_cmp_ui) */
18118 
18119 #if !defined(HAVE_native_mpfq_fixmp_0_5_addmul1)
18120 /* x has 0.5 words, z has 2.
18121  * Put (z+x*c) in z. Return carry bit. */
18122 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
18123 static inline
mpfq_fixmp_0_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18124 mp_limb_t mpfq_fixmp_0_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18125 {
18126     mp_limb_t hi, lo, carry, buf;
18127     carry = 0;
18128     mpfq_umul_ppmm(hi,lo,c,x[0]);
18129     lo += carry;
18130     carry = (lo<carry) + hi;
18131     buf = z[0];
18132     lo += buf;
18133     carry += (lo<buf);
18134     z[0] = lo;
18135     z[1] += carry;
18136     return (z[1]<carry);
18137 }
18138 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_addmul1) */
18139 
18140 #if !defined(HAVE_native_mpfq_fixmp_0_5_addmul1_nc)
18141 /* x has 0.5 words, z has 2.
18142  * Put (z+x*c) in z. Carry bit is lost. */
18143 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
18144 static inline
mpfq_fixmp_0_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18145 void mpfq_fixmp_0_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18146 {
18147     mp_limb_t hi, lo, carry, buf;
18148     carry = 0;
18149     mpfq_umul_ppmm(hi,lo,c,x[0]);
18150     lo += carry;
18151     carry = (lo<carry) + hi;
18152     buf = z[0];
18153     lo += buf;
18154     carry += (lo<buf);
18155     z[0] = lo;
18156     z[1] += carry;
18157 }
18158 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_addmul1_nc) */
18159 
18160 #if !defined(HAVE_native_mpfq_fixmp_0_5_addmul1_shortz)
18161 /* x has 0.5 words, z has 1.
18162  * Put (z+x*c) in z. Return carry word. */
18163 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
18164 /* Triggered by: 0_5_redc, 0_5_redc_ur */
18165 static inline
mpfq_fixmp_0_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18166 mp_limb_t mpfq_fixmp_0_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18167 {
18168     mp_limb_t hi, lo, carry, buf;
18169     carry = 0;
18170     mpfq_umul_ppmm(hi,lo,c,x[0]);
18171     lo += carry;
18172     carry = (lo<carry) + hi;
18173     buf = z[0];
18174     lo += buf;
18175     carry += (lo<buf);
18176     z[0] = lo;
18177     return carry;
18178 }
18179 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_addmul1_shortz) */
18180 
18181 #if !defined(HAVE_native_mpfq_fixmp_0_5_addmul05_nc)
18182 /* x has 0.5 words, z has 1. c is 0.5 word.
18183  * Put (z+x*c) in z. Carry bit is lost. */
18184 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
18185 /* Triggered by: 0_5_mul, 0_5_mgy_decode */
18186 static inline
mpfq_fixmp_0_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18187 void mpfq_fixmp_0_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18188 {
18189     mp_limb_t lo, carry;
18190     carry = 0;
18191     lo = c*x[0] + carry;
18192     assert(lo >= carry);
18193     z[0] += lo;
18194 }
18195 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_addmul05_nc) */
18196 
18197 #if !defined(HAVE_native_mpfq_fixmp_0_5_mul)
18198 /* x and y have 0.5 words, z has 1. Put x*y in z. */
18199 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
18200 /* Triggered by: 0_5_mgy_decode */
18201 static inline
mpfq_fixmp_0_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18202 void mpfq_fixmp_0_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18203 {
18204     assert(z != x && z != y);
18205     for (int i = 0; i < 1; z[i++] = 0) ;
18206     mpfq_fixmp_0_5_addmul05_nc (z + 0, x, y[0]);
18207 }
18208 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mul) */
18209 
18210 #if !defined(HAVE_native_mpfq_fixmp_0_5_sqr)
18211 /* x has 0.5 words, z has 1. Put x*y in z. */
18212 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
18213 static inline
mpfq_fixmp_0_5_sqr(mp_limb_t * z,const mp_limb_t * x)18214 void mpfq_fixmp_0_5_sqr(mp_limb_t * z, const mp_limb_t * x)
18215 {
18216     mp_limb_t buf[1] = {0,};
18217     z[2*0] = x[0] * x[0];
18218     mpn_lshift(buf, buf, 1, 1);
18219     mpn_add_n(z, z, buf, 1);
18220 }
18221 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_sqr) */
18222 
18223 #if !defined(HAVE_native_mpfq_fixmp_0_5_mul1)
18224 /* x has 0.5 words, z has 2. Put x*y in z. */
18225 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
18226 static inline
mpfq_fixmp_0_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18227 void mpfq_fixmp_0_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18228 {
18229     mp_limb_t hi, lo, carry;
18230     carry = 0;
18231     mpfq_umul_ppmm(hi,lo,c,x[0]);
18232     lo += carry;
18233     carry = (lo<carry) + hi;
18234     z[0] = lo;
18235     z[1] = carry;
18236 }
18237 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mul1) */
18238 
18239 #if !defined(HAVE_native_mpfq_fixmp_0_5_shortmul)
18240 /* x and y have 0.5 words, z has 1.
18241  * Put the low 1 words of x*y in z. */
18242 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
18243 static inline
mpfq_fixmp_0_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18244 void mpfq_fixmp_0_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18245 {
18246     mpfq_zero(z, 1);
18247     z[1-1] += x[0]*y[1-1];
18248 }
18249 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_shortmul) */
18250 
18251 #if !defined(HAVE_native_mpfq_fixmp_0_5_addmul05)
18252 /* x has 0.5 words, z has 1. c is 0.5 word.
18253  * Put (z+x*c) in z. Return carry bit. */
18254 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
18255 static inline
mpfq_fixmp_0_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18256 mp_limb_t mpfq_fixmp_0_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18257 {
18258     mp_limb_t lo, carry;
18259     carry = 0;
18260     lo = c*x[0] + carry;
18261     assert(lo >= carry);
18262     z[0] += lo;
18263     return z[0] < lo;
18264 }
18265 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_addmul05) */
18266 
18267 #if !defined(HAVE_native_mpfq_fixmp_0_5_mul05)
18268 /* x has 0.5 words, z has 1. c is 0.5 word.
18269  * Put (x*c) in z. No carry. */
18270 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
18271 static inline
mpfq_fixmp_0_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18272 void mpfq_fixmp_0_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18273 {
18274     mp_limb_t lo, carry;
18275     carry = 0;
18276     lo = c*x[0] + carry;
18277     assert(lo >= carry);
18278     z[0] = lo;
18279 }
18280 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mul05) */
18281 
18282 #if !defined(HAVE_native_mpfq_fixmp_0_5_mod)
18283 /* x has 1 words. z and p have 0.5 words, and the high word of p is non-zero.
18284  * Put x mod p in z. */
18285 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
18286 /* Triggered by: 0_5_mgy_decode */
18287 static inline
mpfq_fixmp_0_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)18288 void mpfq_fixmp_0_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
18289 {
18290     mp_limb_t q[0+1], r[1];
18291     assert (p[1-1] != 0);
18292     mpn_tdiv_qr(q, r, 0, x, 1, p, 1);
18293     mpfq_copy(z, r, 1);
18294 }
18295 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mod) */
18296 
18297 #if !defined(HAVE_native_mpfq_fixmp_0_5_invmod)
18298 /* x, z, and p have 0.5 words. Put inverse of x mod p in z.
18299  * Return non-zero if an inverse could be found.
18300  * If no inverse could be found, return 0 and set z to zero.
18301  */
18302 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
18303 static inline
mpfq_fixmp_0_5_invmod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)18304 int mpfq_fixmp_0_5_invmod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
18305 {
18306       mp_limb_t a, b, u, v, fix;
18307       int t, lsh;
18308 
18309       a = *x;
18310       b = *p;
18311 
18312       if (a == 0 || a == b) {
18313         *z=0;
18314         return 0;
18315       }
18316       /* b must be odd and >a */
18317 
18318       fix = (b+1)>>1;
18319 
18320       assert (a < b);
18321 
18322       u = 1; v = 0; t = 0;
18323 
18324       /* compute u and t such that u*a_orig = 2^t mod b */
18325 
18326       /* we maintain:
18327        *    u*a_orig - (not kept)*b_orig = 2^t*a
18328        *    v*a_orig - (not kept)*b_orig = -2^t*b
18329        * a and b are both odd.
18330        * An update consists in reducing the largest by the smallest,
18331        * and then adjusting the valuation.  */
18332 
18333       lsh = mpfq_ctzl(a);
18334       a >>= lsh;
18335       t += lsh;
18336       v <<= lsh;
18337       do {
18338         do {
18339           b -= a; v += u;
18340           lsh = mpfq_ctzl(b);
18341           b >>= lsh;
18342           t += lsh;
18343           u <<= lsh;
18344         } while (a<b);
18345         if (a == b)
18346           break;
18347         do {
18348           a -= b; u += v;
18349           lsh = mpfq_ctzl(a);
18350           a >>= lsh;
18351           t += lsh;
18352           v <<= lsh;
18353         } while (b < a);
18354       } while (a != b);
18355       if (a != 1) {
18356         *z = a;
18357         return 0;
18358       }
18359       while (t>0) {
18360         mp_limb_t sig = u & 1UL;
18361         u >>= 1;
18362         if (sig)
18363           u += fix;
18364         --t;
18365       }
18366       *z = u;
18367       return 1;
18368 }
18369 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_invmod) */
18370 
18371 #if !defined(HAVE_native_mpfq_fixmp_0_5_redc)
18372 /* x has 1 words, z and p have 0.5 words.
18373  * only one word is read from invp.
18374  * Assuming R=W^1 is the redc modulus, we expect that x verifies:
18375  *   x < R*p,
18376  * so that we have eventually z < p, z congruent to x/R mod p.
18377  * The contents of the area pointed by x are clobbered by this call.
18378  * Note also that x may alias z.
18379  */
18380 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
18381 static inline
mpfq_fixmp_0_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)18382 void mpfq_fixmp_0_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
18383 {
18384     mp_limb_t t = x[0]*mip[0];
18385     mp_limb_t cy = mpfq_fixmp_0_5_addmul1_shortz(x, p, t);
18386     if (cy >= p[0]) {
18387         z[0] = cy - p[0];
18388     } else {
18389         z[0] = cy;
18390     }
18391 }
18392 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_redc) */
18393 
18394 #if !defined(HAVE_native_mpfq_fixmp_0_5_redc_ur)
18395 /* x has 2 words, z and p have 0.5 words.
18396  * only one word is read from invp.
18397  * Assuming R=W^1 is the redc modulus, we expect that x verifies:
18398  *  x < W*W^0.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
18399  * so that we have eventually z < p, z congruent to x/R mod p.
18400  * The contents of the area pointed by x are clobbered by this call.
18401  * Note also that x may alias z.
18402  */
18403 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
18404 static inline
mpfq_fixmp_0_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)18405 void mpfq_fixmp_0_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
18406 {
18407     mp_limb_t cy, q[1];
18408     for(int i = 0; i < 1; ++i) {
18409         mp_limb_t t = x[i]*mip[0];
18410         cy = mpfq_fixmp_0_5_addmul1_shortz(x+i, p, t);
18411         assert (x[i] == 0);
18412         x[i] = cy;
18413     }
18414     cy = mpfq_fixmp_0_5_add(x + 1, x, x + 1);
18415     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
18416     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
18417     * x'/R < (W^0.5+1)*p
18418     */
18419     if (cy) {
18420         /* x'/R-p < W^0.5*p, which fits in n words. */
18421         mpfq_fixmp_0_5_sub(x + 1, x + 1, p);
18422     }
18423     mpn_tdiv_qr(q, z, 0, x + 1, 1, p, 1);
18424 }
18425 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_redc_ur) */
18426 
18427 #if !defined(HAVE_native_mpfq_fixmp_0_5_mgy_encode)
18428 /* x, z, and p have 0.5 words.
18429  * Assuming R=W^1 is the redc modulus, we compute z=R*x mod p. */
18430 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
18431 static inline
mpfq_fixmp_0_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)18432 void mpfq_fixmp_0_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
18433 {
18434     mp_limb_t t[2] = { 0, x[0] };
18435     mp_limb_t qq[1+1];
18436     mpn_tdiv_qr(qq, z, 0, t, 2, p, 1);
18437 }
18438 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mgy_encode) */
18439 
18440 #if !defined(HAVE_native_mpfq_fixmp_0_5_mgy_decode)
18441 /* x, z, invR, and p have 0.5 words.
18442  * Assuming R=W^1 is the redc modulus, we compute z=x/R mod p. */
18443 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
18444 static inline
mpfq_fixmp_0_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)18445 void mpfq_fixmp_0_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
18446 {
18447     mp_limb_t t[2];
18448     mpfq_fixmp_0_5_mul(t, x, invR);
18449     mpfq_fixmp_0_5_mod(z, t, p);
18450 }
18451 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_mgy_decode) */
18452 
18453 #if !defined(HAVE_native_mpfq_fixmp_0_5_lshift)
18454 /* a has 0.5 words. Shift it in place by cnt bits to the left.
18455  * The shift count cnt must not exceed the word size.
18456  * Note that no carry is returned for the bits shifted out. */
18457 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
18458 static inline
mpfq_fixmp_0_5_lshift(mp_limb_t * a,int cnt)18459 void mpfq_fixmp_0_5_lshift(mp_limb_t * a, int cnt)
18460 {
18461     if (!cnt) return;
18462     a[0] <<= cnt;
18463 }
18464 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_lshift) */
18465 
18466 #if !defined(HAVE_native_mpfq_fixmp_0_5_rshift)
18467 /* a has 0.5 words. Shift it in place by cnt bits to the right.
18468  * The shift count cnt must not exceed the word size.
18469  * Note that no carry is returned for the bits shifted out. */
18470 /* *Mpfq::fixmp::longlong::code_for__fixmp_rshift */
18471 static inline
mpfq_fixmp_0_5_rshift(mp_limb_t * a,int cnt)18472 void mpfq_fixmp_0_5_rshift(mp_limb_t * a, int cnt)
18473 {
18474     if (!cnt) return;
18475     a[1-1] >>= cnt;
18476 }
18477 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_rshift) */
18478 
18479 #if !defined(HAVE_native_mpfq_fixmp_0_5_long_lshift)
18480 /* a has 0.5 words. Shift it in place by off words plus cnt bits to the left.
18481  * Note that no carry is returned for the bits shifted out. */
18482 /* *Mpfq::fixmp::longlong::code_for__fixmp_long_lshift */
18483 static inline
mpfq_fixmp_0_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)18484 void mpfq_fixmp_0_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
18485 {
18486     if (cnt) {
18487         a[0] <<= cnt;
18488     }
18489 }
18490 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_long_lshift) */
18491 
18492 #if !defined(HAVE_native_mpfq_fixmp_0_5_long_rshift)
18493 /* a has 0.5 words. Shift it in place by off words plus cnt bits to the left.
18494  * Note that no carry is returned for the bits shifted out. */
18495 /* *Mpfq::fixmp::longlong::code_for__fixmp_long_rshift */
18496 static inline
mpfq_fixmp_0_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)18497 void mpfq_fixmp_0_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
18498 {
18499     if (cnt) {
18500         a[0] >>= cnt;
18501     }
18502 }
18503 #endif /* !defined(HAVE_native_mpfq_fixmp_0_5_long_rshift) */
18504 
18505 #if !defined(HAVE_native_mpfq_fixmp_1_5_add)
18506 /* x, y, and z have 1.5 words. Result in z. Return carry bit */
18507 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
18508 /* Triggered by: 1_5_invmod, 1_5_redc, 1_5_redc_ur */
18509 static inline
mpfq_fixmp_1_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18510 mp_limb_t mpfq_fixmp_1_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18511 {
18512     mp_limb_t r, s, t, cy, cy1, cy2;
18513     cy = 0;
18514     r = x[0];
18515     s = r + y[0];
18516     cy1 = s < r;
18517     t = s + cy;
18518     cy2 = t < s;
18519     cy = cy1 | cy2;
18520     z[0] = t;
18521     r = x[1];
18522     s = r + y[1];
18523     cy1 = s < r;
18524     t = s + cy;
18525     cy2 = t < s;
18526     cy = cy1 | cy2;
18527     z[1] = t;
18528     return cy;
18529 }
18530 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_add) */
18531 
18532 #if !defined(HAVE_native_mpfq_fixmp_1_5_sub)
18533 /* x, y, and z have 1.5 words. Result in z. Return borrow bit */
18534 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
18535 /* Triggered by: 1_5_invmod, 1_5_redc, 1_5_redc_ur */
18536 static inline
mpfq_fixmp_1_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18537 mp_limb_t mpfq_fixmp_1_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18538 {
18539     mp_limb_t r, s, t, cy, cy1, cy2;
18540     cy = 0;
18541     r = x[0];
18542     s = r - y[0];
18543     cy1 = s > r;
18544     t = s - cy;
18545     cy2 = t > s;
18546     cy = cy1 | cy2;
18547     z[0] = t;
18548     r = x[1];
18549     s = r - y[1];
18550     cy1 = s > r;
18551     t = s - cy;
18552     cy2 = t > s;
18553     cy = cy1 | cy2;
18554     z[1] = t;
18555     return cy;
18556 }
18557 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_sub) */
18558 
18559 #if !defined(HAVE_native_mpfq_fixmp_1_5_add_nc)
18560 /* x, y, and z have 1.5 words. Result in z. Carry bit is lost. */
18561 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
18562 static inline
mpfq_fixmp_1_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18563 void mpfq_fixmp_1_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18564 {
18565     mp_limb_t r, s, t, cy, cy1, cy2;
18566     cy = 0;
18567     r = x[0];
18568     s = r + y[0];
18569     cy1 = s < r;
18570     t = s + cy;
18571     cy2 = t < s;
18572     cy = cy1 | cy2;
18573     z[0] = t;
18574     r = x[1];
18575     s = r + y[1];
18576     cy1 = s < r;
18577     t = s + cy;
18578     cy2 = t < s;
18579     cy = cy1 | cy2;
18580     z[1] = t;
18581 }
18582 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_add_nc) */
18583 
18584 #if !defined(HAVE_native_mpfq_fixmp_1_5_sub_nc)
18585 /* x, y, and z have 1.5 words. Result in z. Borrow bit is lost. */
18586 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
18587 static inline
mpfq_fixmp_1_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18588 void mpfq_fixmp_1_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18589 {
18590     mp_limb_t r, s, t, cy, cy1, cy2;
18591     cy = 0;
18592     r = x[0];
18593     s = r - y[0];
18594     cy1 = s > r;
18595     t = s - cy;
18596     cy2 = t > s;
18597     cy = cy1 | cy2;
18598     z[0] = t;
18599     r = x[1];
18600     s = r - y[1];
18601     cy1 = s > r;
18602     t = s - cy;
18603     cy2 = t > s;
18604     cy = cy1 | cy2;
18605     z[1] = t;
18606 }
18607 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_sub_nc) */
18608 
18609 #if !defined(HAVE_native_mpfq_fixmp_1_5_add_ui)
18610 /* x, y, and z have 1.5 words. Result in z. Return carry bit */
18611 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
18612 static inline
mpfq_fixmp_1_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18613 mp_limb_t mpfq_fixmp_1_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18614 {
18615     mp_limb_t r, s, t, cy, cy1, cy2;
18616     cy = 0;
18617     r = x[0];
18618     s = r + y;
18619     cy1 = s < r;
18620     t = s + cy;
18621     cy2 = t < s;
18622     cy = cy1 | cy2;
18623     z[0] = t;
18624     s = x[1];
18625     t = s + cy;
18626     cy = t < s;
18627     z[1] = t;
18628     return cy;
18629 }
18630 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_add_ui) */
18631 
18632 #if !defined(HAVE_native_mpfq_fixmp_1_5_sub_ui)
18633 /* x, y, and z have 1.5 words. Result in z. Return borrow bit */
18634 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
18635 static inline
mpfq_fixmp_1_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18636 mp_limb_t mpfq_fixmp_1_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18637 {
18638     mp_limb_t r, s, t, cy, cy1, cy2;
18639     cy = 0;
18640     r = x[0];
18641     s = r - y;
18642     cy1 = s > r;
18643     t = s - cy;
18644     cy2 = t > s;
18645     cy = cy1 | cy2;
18646     z[0] = t;
18647     s = x[1];
18648     t = s - cy;
18649     cy = t > s;
18650     z[1] = t;
18651     return cy;
18652 }
18653 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_sub_ui) */
18654 
18655 #if !defined(HAVE_native_mpfq_fixmp_1_5_add_ui_nc)
18656 /* x, y, and z have 1.5 words. Result in z. Carry bit is lost. */
18657 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
18658 static inline
mpfq_fixmp_1_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18659 void mpfq_fixmp_1_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18660 {
18661     mp_limb_t r, s, t, cy, cy1, cy2;
18662     cy = 0;
18663     r = x[0];
18664     s = r + y;
18665     cy1 = s < r;
18666     t = s + cy;
18667     cy2 = t < s;
18668     cy = cy1 | cy2;
18669     z[0] = t;
18670     s = x[1];
18671     t = s + cy;
18672     cy = t < s;
18673     z[1] = t;
18674 }
18675 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_add_ui_nc) */
18676 
18677 #if !defined(HAVE_native_mpfq_fixmp_1_5_sub_ui_nc)
18678 /* x, y, and z have 1.5 words. Result in z. Borrow bit is lost. */
18679 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
18680 static inline
mpfq_fixmp_1_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)18681 void mpfq_fixmp_1_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
18682 {
18683     mp_limb_t r, s, t, cy, cy1, cy2;
18684     cy = 0;
18685     r = x[0];
18686     s = r - y;
18687     cy1 = s > r;
18688     t = s - cy;
18689     cy2 = t > s;
18690     cy = cy1 | cy2;
18691     z[0] = t;
18692     s = x[1];
18693     t = s - cy;
18694     cy = t > s;
18695     z[1] = t;
18696 }
18697 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_sub_ui_nc) */
18698 
18699 #if !defined(HAVE_native_mpfq_fixmp_1_5_cmp)
18700 /* x and y have 1.5 words. Return sign of difference x-y. */
18701 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
18702 /* Triggered by: 1_5_invmod, 1_5_redc, 1_5_redc_ur */
18703 static inline
mpfq_fixmp_1_5_cmp(const mp_limb_t * x,const mp_limb_t * y)18704 int mpfq_fixmp_1_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
18705 {
18706     for (int i = 2-1; i >= 0; --i) {
18707         if (x[i] > y[i]) return 1;
18708         if (x[i] < y[i]) return -1;
18709     }
18710     return 0;
18711 }
18712 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_cmp) */
18713 
18714 #if !defined(HAVE_native_mpfq_fixmp_1_5_cmp_ui)
18715 /* x has 1.5 words. Return sign of difference x-y. */
18716 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
18717 /* Triggered by: 1_5_invmod */
18718 static inline
mpfq_fixmp_1_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)18719 int mpfq_fixmp_1_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
18720 {
18721     for (int i = 2-1; i > 0; --i) {
18722         if (x[i]) return 1;
18723     }
18724     if (x[0]>y) return 1;
18725     if (x[0]<y) return -1;
18726     return 0;
18727 }
18728 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_cmp_ui) */
18729 
18730 #if !defined(HAVE_native_mpfq_fixmp_1_5_addmul1)
18731 /* x has 1.5 words, z has 3.
18732  * Put (z+x*c) in z. Return carry bit. */
18733 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
18734 static inline
mpfq_fixmp_1_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18735 mp_limb_t mpfq_fixmp_1_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18736 {
18737     mp_limb_t hi, lo, carry, buf;
18738     carry = 0;
18739     mpfq_umul_ppmm(hi,lo,c,x[0]);
18740     lo += carry;
18741     carry = (lo<carry) + hi;
18742     buf = z[0];
18743     lo += buf;
18744     carry += (lo<buf);
18745     z[0] = lo;
18746     mpfq_umul_ppmm(hi,lo,c,x[1]);
18747     lo += carry;
18748     carry = (lo<carry) + hi;
18749     buf = z[1];
18750     lo += buf;
18751     carry += (lo<buf);
18752     z[1] = lo;
18753     z[2] += carry;
18754     return (z[2]<carry);
18755 }
18756 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_addmul1) */
18757 
18758 #if !defined(HAVE_native_mpfq_fixmp_1_5_addmul1_nc)
18759 /* x has 1.5 words, z has 3.
18760  * Put (z+x*c) in z. Carry bit is lost. */
18761 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
18762 /* Triggered by: 1_5_mul, 1_5_mgy_decode */
18763 static inline
mpfq_fixmp_1_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18764 void mpfq_fixmp_1_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18765 {
18766     mp_limb_t hi, lo, carry, buf;
18767     carry = 0;
18768     mpfq_umul_ppmm(hi,lo,c,x[0]);
18769     lo += carry;
18770     carry = (lo<carry) + hi;
18771     buf = z[0];
18772     lo += buf;
18773     carry += (lo<buf);
18774     z[0] = lo;
18775     mpfq_umul_ppmm(hi,lo,c,x[1]);
18776     lo += carry;
18777     carry = (lo<carry) + hi;
18778     buf = z[1];
18779     lo += buf;
18780     carry += (lo<buf);
18781     z[1] = lo;
18782     z[2] += carry;
18783 }
18784 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_addmul1_nc) */
18785 
18786 #if !defined(HAVE_native_mpfq_fixmp_1_5_addmul1_shortz)
18787 /* x has 1.5 words, z has 2.
18788  * Put (z+x*c) in z. Return carry word. */
18789 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
18790 /* Triggered by: 1_5_redc, 1_5_redc_ur */
18791 static inline
mpfq_fixmp_1_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18792 mp_limb_t mpfq_fixmp_1_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18793 {
18794     mp_limb_t hi, lo, carry, buf;
18795     carry = 0;
18796     mpfq_umul_ppmm(hi,lo,c,x[0]);
18797     lo += carry;
18798     carry = (lo<carry) + hi;
18799     buf = z[0];
18800     lo += buf;
18801     carry += (lo<buf);
18802     z[0] = lo;
18803     mpfq_umul_ppmm(hi,lo,c,x[1]);
18804     lo += carry;
18805     carry = (lo<carry) + hi;
18806     buf = z[1];
18807     lo += buf;
18808     carry += (lo<buf);
18809     z[1] = lo;
18810     return carry;
18811 }
18812 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_addmul1_shortz) */
18813 
18814 #if !defined(HAVE_native_mpfq_fixmp_1_5_addmul05_nc)
18815 /* x has 1.5 words, z has 2. c is 0.5 word.
18816  * Put (z+x*c) in z. Carry bit is lost. */
18817 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
18818 /* Triggered by: 1_5_mul, 1_5_mgy_decode */
18819 static inline
mpfq_fixmp_1_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18820 void mpfq_fixmp_1_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18821 {
18822     mp_limb_t hi, lo, carry, buf;
18823     carry = 0;
18824     mpfq_umul_ppmm(hi,lo,c,x[0]);
18825     lo += carry;
18826     carry = (lo<carry) + hi;
18827     buf = z[0];
18828     lo += buf;
18829     carry += (lo<buf);
18830     z[0] = lo;
18831     lo = c*x[1] + carry;
18832     assert(lo >= carry);
18833     z[1] += lo;
18834 }
18835 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_addmul05_nc) */
18836 
18837 #if !defined(HAVE_native_mpfq_fixmp_1_5_mul)
18838 /* x and y have 1.5 words, z has 3. Put x*y in z. */
18839 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
18840 /* Triggered by: 1_5_mgy_decode */
18841 static inline
mpfq_fixmp_1_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18842 void mpfq_fixmp_1_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18843 {
18844     assert(z != x && z != y);
18845     for (int i = 0; i < 3; z[i++] = 0) ;
18846     mpfq_fixmp_1_5_addmul1_nc (z + 0, x, y[0]);
18847     mpfq_fixmp_1_5_addmul05_nc (z + 1, x, y[1]);
18848 }
18849 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mul) */
18850 
18851 #if !defined(HAVE_native_mpfq_fixmp_1_5_sqr)
18852 /* x has 1.5 words, z has 3. Put x*y in z. */
18853 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
18854 static inline
mpfq_fixmp_1_5_sqr(mp_limb_t * z,const mp_limb_t * x)18855 void mpfq_fixmp_1_5_sqr(mp_limb_t * z, const mp_limb_t * x)
18856 {
18857     mp_limb_t buf[3] = {0,};
18858     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
18859     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
18860     z[2*1] = x[1] * x[1];
18861     mpn_lshift(buf, buf, 3, 1);
18862     mpn_add_n(z, z, buf, 3);
18863 }
18864 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_sqr) */
18865 
18866 #if !defined(HAVE_native_mpfq_fixmp_1_5_mul1)
18867 /* x has 1.5 words, z has 3. Put x*y in z. */
18868 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
18869 static inline
mpfq_fixmp_1_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18870 void mpfq_fixmp_1_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18871 {
18872     mp_limb_t hi, lo, carry;
18873     carry = 0;
18874     mpfq_umul_ppmm(hi,lo,c,x[0]);
18875     lo += carry;
18876     carry = (lo<carry) + hi;
18877     z[0] = lo;
18878     mpfq_umul_ppmm(hi,lo,c,x[1]);
18879     lo += carry;
18880     carry = (lo<carry) + hi;
18881     z[1] = lo;
18882     z[2] = carry;
18883 }
18884 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mul1) */
18885 
18886 #if !defined(HAVE_native_mpfq_fixmp_1_5_shortmul)
18887 /* x and y have 1.5 words, z has 2.
18888  * Put the low 2 words of x*y in z. */
18889 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
18890 static inline
mpfq_fixmp_1_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)18891 void mpfq_fixmp_1_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
18892 {
18893     mpfq_zero(z, 2);
18894     mpfq_fixmp_1_addmul1_nc (z+0, x, y[0]);
18895     z[2-1] += x[1]*y[0];
18896     z[2-1] += x[0]*y[2-1];
18897 }
18898 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_shortmul) */
18899 
18900 #if !defined(HAVE_native_mpfq_fixmp_1_5_addmul05)
18901 /* x has 1.5 words, z has 2. c is 0.5 word.
18902  * Put (z+x*c) in z. Return carry bit. */
18903 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
18904 static inline
mpfq_fixmp_1_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18905 mp_limb_t mpfq_fixmp_1_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18906 {
18907     mp_limb_t hi, lo, carry, buf;
18908     carry = 0;
18909     mpfq_umul_ppmm(hi,lo,c,x[0]);
18910     lo += carry;
18911     carry = (lo<carry) + hi;
18912     buf = z[0];
18913     lo += buf;
18914     carry += (lo<buf);
18915     z[0] = lo;
18916     lo = c*x[1] + carry;
18917     assert(lo >= carry);
18918     z[1] += lo;
18919     return z[1] < lo;
18920 }
18921 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_addmul05) */
18922 
18923 #if !defined(HAVE_native_mpfq_fixmp_1_5_mul05)
18924 /* x has 1.5 words, z has 2. c is 0.5 word.
18925  * Put (x*c) in z. No carry. */
18926 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
18927 static inline
mpfq_fixmp_1_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)18928 void mpfq_fixmp_1_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
18929 {
18930     mp_limb_t hi, lo, carry;
18931     carry = 0;
18932     mpfq_umul_ppmm(hi,lo,c,x[0]);
18933     lo += carry;
18934     carry = (lo<carry) + hi;
18935     z[0] = lo;
18936     lo = c*x[1] + carry;
18937     assert(lo >= carry);
18938     z[1] = lo;
18939 }
18940 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mul05) */
18941 
18942 #if !defined(HAVE_native_mpfq_fixmp_1_5_mod)
18943 /* x has 3 words. z and p have 1.5 words, and the high word of p is non-zero.
18944  * Put x mod p in z. */
18945 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
18946 /* Triggered by: 1_5_mgy_decode */
18947 static inline
mpfq_fixmp_1_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)18948 void mpfq_fixmp_1_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
18949 {
18950     mp_limb_t q[1+1], r[2];
18951     assert (p[2-1] != 0);
18952     mpn_tdiv_qr(q, r, 0, x, 3, p, 2);
18953     mpfq_copy(z, r, 2);
18954 }
18955 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mod) */
18956 
18957 #if !defined(HAVE_native_mpfq_fixmp_1_5_rshift)
18958 /* a has 1.5 words. Shift it in place by cnt bits to the right.
18959  * The shift count cnt must not exceed the word size.
18960  * Note that no carry is returned for the bits shifted out. */
18961 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
18962 /* Triggered by: 1_5_invmod */
18963 static inline
mpfq_fixmp_1_5_rshift(mp_limb_t * a,int cnt)18964 void mpfq_fixmp_1_5_rshift(mp_limb_t * a, int cnt)
18965 {
18966     if (!cnt) return;
18967     int i;
18968     int dnt = GMP_NUMB_BITS - cnt;
18969     for (i = 0; i < 2-1; ++i) {
18970         a[i] >>= cnt;
18971         a[i] |= (a[i+1] << dnt);
18972     }
18973     a[2-1] >>= cnt;
18974 }
18975 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_rshift) */
18976 
18977 #if !defined(HAVE_native_mpfq_fixmp_1_5_long_rshift)
18978 /* a has 1.5 words. Shift it in place by off words plus cnt bits to the left.
18979  * Note that no carry is returned for the bits shifted out. */
18980 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
18981 /* Triggered by: 1_5_invmod */
18982 static inline
mpfq_fixmp_1_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)18983 void mpfq_fixmp_1_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
18984 {
18985     if (cnt) {
18986         int dnt = GMP_NUMB_BITS - cnt;
18987         for (int i = 0; i < 2 - off - 1; ++i) {
18988             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
18989         }
18990         a[2-off-1] = a[2-1]>>cnt;
18991     } else {
18992         mpfq_copyi(a, a + off, 2 - off);
18993     }
18994     mpfq_zero(a + 2 - off, off);
18995 }
18996 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_long_rshift) */
18997 
18998 #if !defined(HAVE_native_mpfq_fixmp_1_5_long_lshift)
18999 /* a has 1.5 words. Shift it in place by off words plus cnt bits to the left.
19000  * Note that no carry is returned for the bits shifted out. */
19001 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19002 /* Triggered by: 1_5_invmod */
19003 static inline
mpfq_fixmp_1_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)19004 void mpfq_fixmp_1_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
19005 {
19006     int i;
19007     if (cnt) {
19008         int dnt = GMP_NUMB_BITS - cnt;
19009         for (i = 2-1; i>off; --i) {
19010             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
19011         }
19012         a[off] = a[0]<<cnt;
19013     } else {
19014         mpfq_copyd(a + off, a, 2 - off);
19015     }
19016     mpfq_zero(a, off);
19017 }
19018 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_long_lshift) */
19019 
19020 #if !defined(HAVE_native_mpfq_fixmp_1_5_invmod)
19021 /* x, z, and p have 1.5 words. Put inverse of x mod p in z.
19022  * Return non-zero if an inverse could be found.
19023  * If no inverse could be found, return 0 and set z to zero.
19024  */
19025 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19026 static inline
mpfq_fixmp_1_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)19027 int mpfq_fixmp_1_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
19028 {
19029       mp_limb_t u[2], v[2], a[2], b[2], fix[2];
19030       int i, t, lsh;
19031 
19032       mpfq_zero(u, 2);
19033       mpfq_zero(v, 2);
19034       mpfq_copy(a, x, 2);
19035       mpfq_copy(b, p, 2);
19036       u[0] = 1UL;
19037 
19038       if (mpfq_fixmp_1_5_cmp(a, v) == 0 || mpfq_fixmp_1_5_cmp(a, b) == 0) {
19039         mpfq_zero(res, 2);
19040         return 0;
19041       }
19042 
19043       mpfq_fixmp_1_5_add(fix, b, u);
19044       mpfq_fixmp_1_5_rshift(fix, 1);
19045 
19046       assert (mpfq_fixmp_1_5_cmp(a,b) < 0);
19047 
19048       t = 0;
19049 
19050       for(i = 0 ; !a[i] ; i++) ;
19051       assert (i < 2);
19052       lsh = mpfq_ctzl(a[i]);
19053       mpfq_fixmp_1_5_long_rshift(a, i, lsh);
19054       t += lsh + i*GMP_NUMB_BITS;
19055       mpfq_fixmp_1_5_long_lshift(v, i, lsh);
19056 
19057       do {
19058         do {
19059           mpfq_fixmp_1_5_sub(b, b, a);
19060           mpfq_fixmp_1_5_add(v, v, u);
19061           for(i = 0 ; !b[i] ; i++) ;
19062           assert (i < 2);
19063           lsh = mpfq_ctzl(b[i]);
19064           mpfq_fixmp_1_5_long_rshift(b, i, lsh);
19065           t += lsh + i*GMP_NUMB_BITS;
19066           mpfq_fixmp_1_5_long_lshift(u, i, lsh);
19067         } while (mpfq_fixmp_1_5_cmp(a,b) < 0);
19068         if (mpfq_fixmp_1_5_cmp(a, b) == 0)
19069           break;
19070         do {
19071           mpfq_fixmp_1_5_sub(a, a, b);
19072           mpfq_fixmp_1_5_add(u, u, v);
19073           for(i = 0 ; !a[i] ; i++) ;
19074           assert (i < 2);
19075           lsh = mpfq_ctzl(a[i]);
19076           mpfq_fixmp_1_5_long_rshift(a, i, lsh);
19077           t += lsh + i*GMP_NUMB_BITS;
19078           mpfq_fixmp_1_5_long_lshift(v, i, lsh);
19079         } while (mpfq_fixmp_1_5_cmp(b,a)<0);
19080       } while (mpfq_fixmp_1_5_cmp(a,b) != 0);
19081       {
19082         if (mpfq_fixmp_1_5_cmp_ui(a, 1) != 0) {
19083           mpfq_copy(res, a, 2);
19084           return 0;
19085         }
19086       }
19087       while (t>0) {
19088         mp_limb_t sig = u[0] & 1UL;
19089         mpfq_fixmp_1_5_rshift(u, 1);
19090         if (sig)
19091           mpfq_fixmp_1_5_add(u, u, fix);
19092         --t;
19093       }
19094       mpfq_copy(res, u, 2);
19095       return 1;
19096 }
19097 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_invmod) */
19098 
19099 #if !defined(HAVE_native_mpfq_fixmp_1_5_redc)
19100 /* x has 3 words, z and p have 1.5 words.
19101  * only one word is read from invp.
19102  * Assuming R=W^2 is the redc modulus, we expect that x verifies:
19103  *   x < R*p,
19104  * so that we have eventually z < p, z congruent to x/R mod p.
19105  * The contents of the area pointed by x are clobbered by this call.
19106  * Note also that x may alias z.
19107  */
19108 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
19109 static inline
mpfq_fixmp_1_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)19110 void mpfq_fixmp_1_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
19111 {
19112     mp_limb_t cy;
19113     for(int i = 0; i < 2; ++i) {
19114         mp_limb_t t = x[i]*mip[0];
19115         cy = mpfq_fixmp_1_5_addmul1_shortz(x+i, p, t);
19116         assert (x[i] == 0);
19117         x[i] = cy;
19118     }
19119     {
19120         mp_limb_t ret[2] = { x[2], 0 };
19121         cy = mpfq_fixmp_1_5_add(x, x, ret);
19122     }
19123     /* At this point, we have (x' denotes x + cy*W^n here)
19124     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
19125     * x'/R < p + p
19126     */
19127     if (cy || mpfq_fixmp_1_5_cmp(x, p) >= 0) {
19128         mpfq_fixmp_1_5_sub(z, x, p);
19129     } else {
19130         mpfq_copy(z, x, 2);
19131     }
19132 }
19133 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_redc) */
19134 
19135 #if !defined(HAVE_native_mpfq_fixmp_1_5_redc_ur)
19136 /* x has 4 words, z and p have 1.5 words.
19137  * only one word is read from invp.
19138  * Assuming R=W^2 is the redc modulus, we expect that x verifies:
19139  *  x < W*W^1.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
19140  * so that we have eventually z < p, z congruent to x/R mod p.
19141  * The contents of the area pointed by x are clobbered by this call.
19142  * Note also that x may alias z.
19143  */
19144 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
19145 static inline
mpfq_fixmp_1_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)19146 void mpfq_fixmp_1_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
19147 {
19148     mp_limb_t cy, q[1];
19149     for(int i = 0; i < 2; ++i) {
19150         mp_limb_t t = x[i]*mip[0];
19151         cy = mpfq_fixmp_1_5_addmul1_shortz(x+i, p, t);
19152         assert (x[i] == 0);
19153         x[i] = cy;
19154     }
19155     cy = mpfq_fixmp_1_5_add(x + 2, x, x + 2);
19156     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
19157     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
19158     * x'/R < (W^0.5+1)*p
19159     */
19160     if (cy) {
19161         /* x'/R-p < W^0.5*p, which fits in n words. */
19162         mpfq_fixmp_1_5_sub(x + 2, x + 2, p);
19163     }
19164     mpn_tdiv_qr(q, z, 0, x + 2, 2, p, 2);
19165 }
19166 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_redc_ur) */
19167 
19168 #if !defined(HAVE_native_mpfq_fixmp_1_5_mgy_encode)
19169 /* x, z, and p have 1.5 words.
19170  * Assuming R=W^2 is the redc modulus, we compute z=R*x mod p. */
19171 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
19172 static inline
mpfq_fixmp_1_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)19173 void mpfq_fixmp_1_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
19174 {
19175     mp_limb_t t[4] = { 0, 0, x[0], x[1] };
19176     mp_limb_t qq[2+1];
19177     mpn_tdiv_qr(qq, z, 0, t, 4, p, 2);
19178 }
19179 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mgy_encode) */
19180 
19181 #if !defined(HAVE_native_mpfq_fixmp_1_5_mgy_decode)
19182 /* x, z, invR, and p have 1.5 words.
19183  * Assuming R=W^2 is the redc modulus, we compute z=x/R mod p. */
19184 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
19185 static inline
mpfq_fixmp_1_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)19186 void mpfq_fixmp_1_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
19187 {
19188     mp_limb_t t[4];
19189     mpfq_fixmp_1_5_mul(t, x, invR);
19190     mpfq_fixmp_1_5_mod(z, t, p);
19191 }
19192 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_mgy_decode) */
19193 
19194 #if !defined(HAVE_native_mpfq_fixmp_1_5_lshift)
19195 /* a has 1.5 words. Shift it in place by cnt bits to the left.
19196  * The shift count cnt must not exceed the word size.
19197  * Note that no carry is returned for the bits shifted out. */
19198 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
19199 static inline
mpfq_fixmp_1_5_lshift(mp_limb_t * a,int cnt)19200 void mpfq_fixmp_1_5_lshift(mp_limb_t * a, int cnt)
19201 {
19202     if (!cnt) return;
19203     int i;
19204     int dnt = GMP_NUMB_BITS - cnt;
19205     for (i = 2-1; i>0; --i) {
19206         a[i] <<= cnt;
19207         a[i] |= (a[i-1] >> dnt);
19208     }
19209     a[0] <<= cnt;
19210 }
19211 #endif /* !defined(HAVE_native_mpfq_fixmp_1_5_lshift) */
19212 
19213 #if !defined(HAVE_native_mpfq_fixmp_2_5_add)
19214 /* x, y, and z have 2.5 words. Result in z. Return carry bit */
19215 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
19216 /* Triggered by: 2_5_invmod, 2_5_redc, 2_5_redc_ur */
19217 static inline
mpfq_fixmp_2_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19218 mp_limb_t mpfq_fixmp_2_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19219 {
19220     mp_limb_t r, s, t, cy, cy1, cy2;
19221     cy = 0;
19222     r = x[0];
19223     s = r + y[0];
19224     cy1 = s < r;
19225     t = s + cy;
19226     cy2 = t < s;
19227     cy = cy1 | cy2;
19228     z[0] = t;
19229     r = x[1];
19230     s = r + y[1];
19231     cy1 = s < r;
19232     t = s + cy;
19233     cy2 = t < s;
19234     cy = cy1 | cy2;
19235     z[1] = t;
19236     r = x[2];
19237     s = r + y[2];
19238     cy1 = s < r;
19239     t = s + cy;
19240     cy2 = t < s;
19241     cy = cy1 | cy2;
19242     z[2] = t;
19243     return cy;
19244 }
19245 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_add) */
19246 
19247 #if !defined(HAVE_native_mpfq_fixmp_2_5_sub)
19248 /* x, y, and z have 2.5 words. Result in z. Return borrow bit */
19249 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
19250 /* Triggered by: 2_5_invmod, 2_5_redc, 2_5_redc_ur */
19251 static inline
mpfq_fixmp_2_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19252 mp_limb_t mpfq_fixmp_2_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19253 {
19254     mp_limb_t r, s, t, cy, cy1, cy2;
19255     cy = 0;
19256     r = x[0];
19257     s = r - y[0];
19258     cy1 = s > r;
19259     t = s - cy;
19260     cy2 = t > s;
19261     cy = cy1 | cy2;
19262     z[0] = t;
19263     r = x[1];
19264     s = r - y[1];
19265     cy1 = s > r;
19266     t = s - cy;
19267     cy2 = t > s;
19268     cy = cy1 | cy2;
19269     z[1] = t;
19270     r = x[2];
19271     s = r - y[2];
19272     cy1 = s > r;
19273     t = s - cy;
19274     cy2 = t > s;
19275     cy = cy1 | cy2;
19276     z[2] = t;
19277     return cy;
19278 }
19279 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_sub) */
19280 
19281 #if !defined(HAVE_native_mpfq_fixmp_2_5_add_nc)
19282 /* x, y, and z have 2.5 words. Result in z. Carry bit is lost. */
19283 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
19284 static inline
mpfq_fixmp_2_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19285 void mpfq_fixmp_2_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19286 {
19287     mp_limb_t r, s, t, cy, cy1, cy2;
19288     cy = 0;
19289     r = x[0];
19290     s = r + y[0];
19291     cy1 = s < r;
19292     t = s + cy;
19293     cy2 = t < s;
19294     cy = cy1 | cy2;
19295     z[0] = t;
19296     r = x[1];
19297     s = r + y[1];
19298     cy1 = s < r;
19299     t = s + cy;
19300     cy2 = t < s;
19301     cy = cy1 | cy2;
19302     z[1] = t;
19303     r = x[2];
19304     s = r + y[2];
19305     cy1 = s < r;
19306     t = s + cy;
19307     cy2 = t < s;
19308     cy = cy1 | cy2;
19309     z[2] = t;
19310 }
19311 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_add_nc) */
19312 
19313 #if !defined(HAVE_native_mpfq_fixmp_2_5_sub_nc)
19314 /* x, y, and z have 2.5 words. Result in z. Borrow bit is lost. */
19315 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
19316 static inline
mpfq_fixmp_2_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19317 void mpfq_fixmp_2_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19318 {
19319     mp_limb_t r, s, t, cy, cy1, cy2;
19320     cy = 0;
19321     r = x[0];
19322     s = r - y[0];
19323     cy1 = s > r;
19324     t = s - cy;
19325     cy2 = t > s;
19326     cy = cy1 | cy2;
19327     z[0] = t;
19328     r = x[1];
19329     s = r - y[1];
19330     cy1 = s > r;
19331     t = s - cy;
19332     cy2 = t > s;
19333     cy = cy1 | cy2;
19334     z[1] = t;
19335     r = x[2];
19336     s = r - y[2];
19337     cy1 = s > r;
19338     t = s - cy;
19339     cy2 = t > s;
19340     cy = cy1 | cy2;
19341     z[2] = t;
19342 }
19343 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_sub_nc) */
19344 
19345 #if !defined(HAVE_native_mpfq_fixmp_2_5_add_ui)
19346 /* x, y, and z have 2.5 words. Result in z. Return carry bit */
19347 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
19348 static inline
mpfq_fixmp_2_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)19349 mp_limb_t mpfq_fixmp_2_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
19350 {
19351     mp_limb_t r, s, t, cy, cy1, cy2;
19352     cy = 0;
19353     r = x[0];
19354     s = r + y;
19355     cy1 = s < r;
19356     t = s + cy;
19357     cy2 = t < s;
19358     cy = cy1 | cy2;
19359     z[0] = t;
19360     s = x[1];
19361     t = s + cy;
19362     cy = t < s;
19363     z[1] = t;
19364     s = x[2];
19365     t = s + cy;
19366     cy = t < s;
19367     z[2] = t;
19368     return cy;
19369 }
19370 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_add_ui) */
19371 
19372 #if !defined(HAVE_native_mpfq_fixmp_2_5_sub_ui)
19373 /* x, y, and z have 2.5 words. Result in z. Return borrow bit */
19374 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
19375 static inline
mpfq_fixmp_2_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)19376 mp_limb_t mpfq_fixmp_2_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
19377 {
19378     mp_limb_t r, s, t, cy, cy1, cy2;
19379     cy = 0;
19380     r = x[0];
19381     s = r - y;
19382     cy1 = s > r;
19383     t = s - cy;
19384     cy2 = t > s;
19385     cy = cy1 | cy2;
19386     z[0] = t;
19387     s = x[1];
19388     t = s - cy;
19389     cy = t > s;
19390     z[1] = t;
19391     s = x[2];
19392     t = s - cy;
19393     cy = t > s;
19394     z[2] = t;
19395     return cy;
19396 }
19397 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_sub_ui) */
19398 
19399 #if !defined(HAVE_native_mpfq_fixmp_2_5_add_ui_nc)
19400 /* x, y, and z have 2.5 words. Result in z. Carry bit is lost. */
19401 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
19402 static inline
mpfq_fixmp_2_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)19403 void mpfq_fixmp_2_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
19404 {
19405     mp_limb_t r, s, t, cy, cy1, cy2;
19406     cy = 0;
19407     r = x[0];
19408     s = r + y;
19409     cy1 = s < r;
19410     t = s + cy;
19411     cy2 = t < s;
19412     cy = cy1 | cy2;
19413     z[0] = t;
19414     s = x[1];
19415     t = s + cy;
19416     cy = t < s;
19417     z[1] = t;
19418     s = x[2];
19419     t = s + cy;
19420     cy = t < s;
19421     z[2] = t;
19422 }
19423 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_add_ui_nc) */
19424 
19425 #if !defined(HAVE_native_mpfq_fixmp_2_5_sub_ui_nc)
19426 /* x, y, and z have 2.5 words. Result in z. Borrow bit is lost. */
19427 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
19428 static inline
mpfq_fixmp_2_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)19429 void mpfq_fixmp_2_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
19430 {
19431     mp_limb_t r, s, t, cy, cy1, cy2;
19432     cy = 0;
19433     r = x[0];
19434     s = r - y;
19435     cy1 = s > r;
19436     t = s - cy;
19437     cy2 = t > s;
19438     cy = cy1 | cy2;
19439     z[0] = t;
19440     s = x[1];
19441     t = s - cy;
19442     cy = t > s;
19443     z[1] = t;
19444     s = x[2];
19445     t = s - cy;
19446     cy = t > s;
19447     z[2] = t;
19448 }
19449 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_sub_ui_nc) */
19450 
19451 #if !defined(HAVE_native_mpfq_fixmp_2_5_cmp)
19452 /* x and y have 2.5 words. Return sign of difference x-y. */
19453 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
19454 /* Triggered by: 2_5_invmod, 2_5_redc, 2_5_redc_ur */
19455 static inline
mpfq_fixmp_2_5_cmp(const mp_limb_t * x,const mp_limb_t * y)19456 int mpfq_fixmp_2_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
19457 {
19458     for (int i = 3-1; i >= 0; --i) {
19459         if (x[i] > y[i]) return 1;
19460         if (x[i] < y[i]) return -1;
19461     }
19462     return 0;
19463 }
19464 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_cmp) */
19465 
19466 #if !defined(HAVE_native_mpfq_fixmp_2_5_cmp_ui)
19467 /* x has 2.5 words. Return sign of difference x-y. */
19468 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
19469 /* Triggered by: 2_5_invmod */
19470 static inline
mpfq_fixmp_2_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)19471 int mpfq_fixmp_2_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
19472 {
19473     for (int i = 3-1; i > 0; --i) {
19474         if (x[i]) return 1;
19475     }
19476     if (x[0]>y) return 1;
19477     if (x[0]<y) return -1;
19478     return 0;
19479 }
19480 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_cmp_ui) */
19481 
19482 #if !defined(HAVE_native_mpfq_fixmp_2_5_addmul1)
19483 /* x has 2.5 words, z has 4.
19484  * Put (z+x*c) in z. Return carry bit. */
19485 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
19486 static inline
mpfq_fixmp_2_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19487 mp_limb_t mpfq_fixmp_2_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19488 {
19489     mp_limb_t hi, lo, carry, buf;
19490     carry = 0;
19491     mpfq_umul_ppmm(hi,lo,c,x[0]);
19492     lo += carry;
19493     carry = (lo<carry) + hi;
19494     buf = z[0];
19495     lo += buf;
19496     carry += (lo<buf);
19497     z[0] = lo;
19498     mpfq_umul_ppmm(hi,lo,c,x[1]);
19499     lo += carry;
19500     carry = (lo<carry) + hi;
19501     buf = z[1];
19502     lo += buf;
19503     carry += (lo<buf);
19504     z[1] = lo;
19505     mpfq_umul_ppmm(hi,lo,c,x[2]);
19506     lo += carry;
19507     carry = (lo<carry) + hi;
19508     buf = z[2];
19509     lo += buf;
19510     carry += (lo<buf);
19511     z[2] = lo;
19512     z[3] += carry;
19513     return (z[3]<carry);
19514 }
19515 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_addmul1) */
19516 
19517 #if !defined(HAVE_native_mpfq_fixmp_2_5_addmul1_nc)
19518 /* x has 2.5 words, z has 4.
19519  * Put (z+x*c) in z. Carry bit is lost. */
19520 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
19521 /* Triggered by: 2_5_mul, 2_5_mgy_decode */
19522 static inline
mpfq_fixmp_2_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19523 void mpfq_fixmp_2_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19524 {
19525     mp_limb_t hi, lo, carry, buf;
19526     carry = 0;
19527     mpfq_umul_ppmm(hi,lo,c,x[0]);
19528     lo += carry;
19529     carry = (lo<carry) + hi;
19530     buf = z[0];
19531     lo += buf;
19532     carry += (lo<buf);
19533     z[0] = lo;
19534     mpfq_umul_ppmm(hi,lo,c,x[1]);
19535     lo += carry;
19536     carry = (lo<carry) + hi;
19537     buf = z[1];
19538     lo += buf;
19539     carry += (lo<buf);
19540     z[1] = lo;
19541     mpfq_umul_ppmm(hi,lo,c,x[2]);
19542     lo += carry;
19543     carry = (lo<carry) + hi;
19544     buf = z[2];
19545     lo += buf;
19546     carry += (lo<buf);
19547     z[2] = lo;
19548     z[3] += carry;
19549 }
19550 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_addmul1_nc) */
19551 
19552 #if !defined(HAVE_native_mpfq_fixmp_2_5_addmul1_shortz)
19553 /* x has 2.5 words, z has 3.
19554  * Put (z+x*c) in z. Return carry word. */
19555 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
19556 /* Triggered by: 2_5_redc, 2_5_redc_ur */
19557 static inline
mpfq_fixmp_2_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19558 mp_limb_t mpfq_fixmp_2_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19559 {
19560     mp_limb_t hi, lo, carry, buf;
19561     carry = 0;
19562     mpfq_umul_ppmm(hi,lo,c,x[0]);
19563     lo += carry;
19564     carry = (lo<carry) + hi;
19565     buf = z[0];
19566     lo += buf;
19567     carry += (lo<buf);
19568     z[0] = lo;
19569     mpfq_umul_ppmm(hi,lo,c,x[1]);
19570     lo += carry;
19571     carry = (lo<carry) + hi;
19572     buf = z[1];
19573     lo += buf;
19574     carry += (lo<buf);
19575     z[1] = lo;
19576     mpfq_umul_ppmm(hi,lo,c,x[2]);
19577     lo += carry;
19578     carry = (lo<carry) + hi;
19579     buf = z[2];
19580     lo += buf;
19581     carry += (lo<buf);
19582     z[2] = lo;
19583     return carry;
19584 }
19585 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_addmul1_shortz) */
19586 
19587 #if !defined(HAVE_native_mpfq_fixmp_2_5_addmul05_nc)
19588 /* x has 2.5 words, z has 3. c is 0.5 word.
19589  * Put (z+x*c) in z. Carry bit is lost. */
19590 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
19591 /* Triggered by: 2_5_mul, 2_5_mgy_decode */
19592 static inline
mpfq_fixmp_2_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19593 void mpfq_fixmp_2_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19594 {
19595     mp_limb_t hi, lo, carry, buf;
19596     carry = 0;
19597     mpfq_umul_ppmm(hi,lo,c,x[0]);
19598     lo += carry;
19599     carry = (lo<carry) + hi;
19600     buf = z[0];
19601     lo += buf;
19602     carry += (lo<buf);
19603     z[0] = lo;
19604     mpfq_umul_ppmm(hi,lo,c,x[1]);
19605     lo += carry;
19606     carry = (lo<carry) + hi;
19607     buf = z[1];
19608     lo += buf;
19609     carry += (lo<buf);
19610     z[1] = lo;
19611     lo = c*x[2] + carry;
19612     assert(lo >= carry);
19613     z[2] += lo;
19614 }
19615 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_addmul05_nc) */
19616 
19617 #if !defined(HAVE_native_mpfq_fixmp_2_5_mul)
19618 /* x and y have 2.5 words, z has 5. Put x*y in z. */
19619 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
19620 /* Triggered by: 2_5_mgy_decode */
19621 static inline
mpfq_fixmp_2_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19622 void mpfq_fixmp_2_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19623 {
19624     assert(z != x && z != y);
19625     for (int i = 0; i < 5; z[i++] = 0) ;
19626     mpfq_fixmp_2_5_addmul1_nc (z + 0, x, y[0]);
19627     mpfq_fixmp_2_5_addmul1_nc (z + 1, x, y[1]);
19628     mpfq_fixmp_2_5_addmul05_nc (z + 2, x, y[2]);
19629 }
19630 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mul) */
19631 
19632 #if !defined(HAVE_native_mpfq_fixmp_2_5_sqr)
19633 /* x has 2.5 words, z has 5. Put x*y in z. */
19634 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
19635 static inline
mpfq_fixmp_2_5_sqr(mp_limb_t * z,const mp_limb_t * x)19636 void mpfq_fixmp_2_5_sqr(mp_limb_t * z, const mp_limb_t * x)
19637 {
19638     mp_limb_t buf[5] = {0,};
19639     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
19640     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
19641     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
19642     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
19643     z[2*2] = x[2] * x[2];
19644     mpn_lshift(buf, buf, 5, 1);
19645     mpn_add_n(z, z, buf, 5);
19646 }
19647 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_sqr) */
19648 
19649 #if !defined(HAVE_native_mpfq_fixmp_2_5_mul1)
19650 /* x has 2.5 words, z has 4. Put x*y in z. */
19651 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
19652 static inline
mpfq_fixmp_2_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19653 void mpfq_fixmp_2_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19654 {
19655     mp_limb_t hi, lo, carry;
19656     carry = 0;
19657     mpfq_umul_ppmm(hi,lo,c,x[0]);
19658     lo += carry;
19659     carry = (lo<carry) + hi;
19660     z[0] = lo;
19661     mpfq_umul_ppmm(hi,lo,c,x[1]);
19662     lo += carry;
19663     carry = (lo<carry) + hi;
19664     z[1] = lo;
19665     mpfq_umul_ppmm(hi,lo,c,x[2]);
19666     lo += carry;
19667     carry = (lo<carry) + hi;
19668     z[2] = lo;
19669     z[3] = carry;
19670 }
19671 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mul1) */
19672 
19673 #if !defined(HAVE_native_mpfq_fixmp_2_5_shortmul)
19674 /* x and y have 2.5 words, z has 3.
19675  * Put the low 3 words of x*y in z. */
19676 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
19677 static inline
mpfq_fixmp_2_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)19678 void mpfq_fixmp_2_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
19679 {
19680     mpfq_zero(z, 3);
19681     mpfq_fixmp_2_addmul1_nc (z+0, x, y[0]);
19682     z[3-1] += x[2]*y[0];
19683     mpfq_fixmp_1_addmul1_nc (z+1, x, y[1]);
19684     z[3-1] += x[1]*y[1];
19685     z[3-1] += x[0]*y[3-1];
19686 }
19687 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_shortmul) */
19688 
19689 #if !defined(HAVE_native_mpfq_fixmp_2_5_addmul05)
19690 /* x has 2.5 words, z has 3. c is 0.5 word.
19691  * Put (z+x*c) in z. Return carry bit. */
19692 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
19693 static inline
mpfq_fixmp_2_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19694 mp_limb_t mpfq_fixmp_2_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19695 {
19696     mp_limb_t hi, lo, carry, buf;
19697     carry = 0;
19698     mpfq_umul_ppmm(hi,lo,c,x[0]);
19699     lo += carry;
19700     carry = (lo<carry) + hi;
19701     buf = z[0];
19702     lo += buf;
19703     carry += (lo<buf);
19704     z[0] = lo;
19705     mpfq_umul_ppmm(hi,lo,c,x[1]);
19706     lo += carry;
19707     carry = (lo<carry) + hi;
19708     buf = z[1];
19709     lo += buf;
19710     carry += (lo<buf);
19711     z[1] = lo;
19712     lo = c*x[2] + carry;
19713     assert(lo >= carry);
19714     z[2] += lo;
19715     return z[2] < lo;
19716 }
19717 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_addmul05) */
19718 
19719 #if !defined(HAVE_native_mpfq_fixmp_2_5_mul05)
19720 /* x has 2.5 words, z has 3. c is 0.5 word.
19721  * Put (x*c) in z. No carry. */
19722 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
19723 static inline
mpfq_fixmp_2_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)19724 void mpfq_fixmp_2_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
19725 {
19726     mp_limb_t hi, lo, carry;
19727     carry = 0;
19728     mpfq_umul_ppmm(hi,lo,c,x[0]);
19729     lo += carry;
19730     carry = (lo<carry) + hi;
19731     z[0] = lo;
19732     mpfq_umul_ppmm(hi,lo,c,x[1]);
19733     lo += carry;
19734     carry = (lo<carry) + hi;
19735     z[1] = lo;
19736     lo = c*x[2] + carry;
19737     assert(lo >= carry);
19738     z[2] = lo;
19739 }
19740 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mul05) */
19741 
19742 #if !defined(HAVE_native_mpfq_fixmp_2_5_mod)
19743 /* x has 5 words. z and p have 2.5 words, and the high word of p is non-zero.
19744  * Put x mod p in z. */
19745 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
19746 /* Triggered by: 2_5_mgy_decode */
19747 static inline
mpfq_fixmp_2_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)19748 void mpfq_fixmp_2_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
19749 {
19750     mp_limb_t q[2+1], r[3];
19751     assert (p[3-1] != 0);
19752     mpn_tdiv_qr(q, r, 0, x, 5, p, 3);
19753     mpfq_copy(z, r, 3);
19754 }
19755 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mod) */
19756 
19757 #if !defined(HAVE_native_mpfq_fixmp_2_5_rshift)
19758 /* a has 2.5 words. Shift it in place by cnt bits to the right.
19759  * The shift count cnt must not exceed the word size.
19760  * Note that no carry is returned for the bits shifted out. */
19761 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19762 /* Triggered by: 2_5_invmod */
19763 static inline
mpfq_fixmp_2_5_rshift(mp_limb_t * a,int cnt)19764 void mpfq_fixmp_2_5_rshift(mp_limb_t * a, int cnt)
19765 {
19766     if (!cnt) return;
19767     int i;
19768     int dnt = GMP_NUMB_BITS - cnt;
19769     for (i = 0; i < 3-1; ++i) {
19770         a[i] >>= cnt;
19771         a[i] |= (a[i+1] << dnt);
19772     }
19773     a[3-1] >>= cnt;
19774 }
19775 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_rshift) */
19776 
19777 #if !defined(HAVE_native_mpfq_fixmp_2_5_long_rshift)
19778 /* a has 2.5 words. Shift it in place by off words plus cnt bits to the left.
19779  * Note that no carry is returned for the bits shifted out. */
19780 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19781 /* Triggered by: 2_5_invmod */
19782 static inline
mpfq_fixmp_2_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)19783 void mpfq_fixmp_2_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
19784 {
19785     if (cnt) {
19786         int dnt = GMP_NUMB_BITS - cnt;
19787         for (int i = 0; i < 3 - off - 1; ++i) {
19788             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
19789         }
19790         a[3-off-1] = a[3-1]>>cnt;
19791     } else {
19792         mpfq_copyi(a, a + off, 3 - off);
19793     }
19794     mpfq_zero(a + 3 - off, off);
19795 }
19796 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_long_rshift) */
19797 
19798 #if !defined(HAVE_native_mpfq_fixmp_2_5_long_lshift)
19799 /* a has 2.5 words. Shift it in place by off words plus cnt bits to the left.
19800  * Note that no carry is returned for the bits shifted out. */
19801 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19802 /* Triggered by: 2_5_invmod */
19803 static inline
mpfq_fixmp_2_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)19804 void mpfq_fixmp_2_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
19805 {
19806     int i;
19807     if (cnt) {
19808         int dnt = GMP_NUMB_BITS - cnt;
19809         for (i = 3-1; i>off; --i) {
19810             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
19811         }
19812         a[off] = a[0]<<cnt;
19813     } else {
19814         mpfq_copyd(a + off, a, 3 - off);
19815     }
19816     mpfq_zero(a, off);
19817 }
19818 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_long_lshift) */
19819 
19820 #if !defined(HAVE_native_mpfq_fixmp_2_5_invmod)
19821 /* x, z, and p have 2.5 words. Put inverse of x mod p in z.
19822  * Return non-zero if an inverse could be found.
19823  * If no inverse could be found, return 0 and set z to zero.
19824  */
19825 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
19826 static inline
mpfq_fixmp_2_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)19827 int mpfq_fixmp_2_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
19828 {
19829       mp_limb_t u[3], v[3], a[3], b[3], fix[3];
19830       int i, t, lsh;
19831 
19832       mpfq_zero(u, 3);
19833       mpfq_zero(v, 3);
19834       mpfq_copy(a, x, 3);
19835       mpfq_copy(b, p, 3);
19836       u[0] = 1UL;
19837 
19838       if (mpfq_fixmp_2_5_cmp(a, v) == 0 || mpfq_fixmp_2_5_cmp(a, b) == 0) {
19839         mpfq_zero(res, 3);
19840         return 0;
19841       }
19842 
19843       mpfq_fixmp_2_5_add(fix, b, u);
19844       mpfq_fixmp_2_5_rshift(fix, 1);
19845 
19846       assert (mpfq_fixmp_2_5_cmp(a,b) < 0);
19847 
19848       t = 0;
19849 
19850       for(i = 0 ; !a[i] ; i++) ;
19851       assert (i < 3);
19852       lsh = mpfq_ctzl(a[i]);
19853       mpfq_fixmp_2_5_long_rshift(a, i, lsh);
19854       t += lsh + i*GMP_NUMB_BITS;
19855       mpfq_fixmp_2_5_long_lshift(v, i, lsh);
19856 
19857       do {
19858         do {
19859           mpfq_fixmp_2_5_sub(b, b, a);
19860           mpfq_fixmp_2_5_add(v, v, u);
19861           for(i = 0 ; !b[i] ; i++) ;
19862           assert (i < 3);
19863           lsh = mpfq_ctzl(b[i]);
19864           mpfq_fixmp_2_5_long_rshift(b, i, lsh);
19865           t += lsh + i*GMP_NUMB_BITS;
19866           mpfq_fixmp_2_5_long_lshift(u, i, lsh);
19867         } while (mpfq_fixmp_2_5_cmp(a,b) < 0);
19868         if (mpfq_fixmp_2_5_cmp(a, b) == 0)
19869           break;
19870         do {
19871           mpfq_fixmp_2_5_sub(a, a, b);
19872           mpfq_fixmp_2_5_add(u, u, v);
19873           for(i = 0 ; !a[i] ; i++) ;
19874           assert (i < 3);
19875           lsh = mpfq_ctzl(a[i]);
19876           mpfq_fixmp_2_5_long_rshift(a, i, lsh);
19877           t += lsh + i*GMP_NUMB_BITS;
19878           mpfq_fixmp_2_5_long_lshift(v, i, lsh);
19879         } while (mpfq_fixmp_2_5_cmp(b,a)<0);
19880       } while (mpfq_fixmp_2_5_cmp(a,b) != 0);
19881       {
19882         if (mpfq_fixmp_2_5_cmp_ui(a, 1) != 0) {
19883           mpfq_copy(res, a, 3);
19884           return 0;
19885         }
19886       }
19887       while (t>0) {
19888         mp_limb_t sig = u[0] & 1UL;
19889         mpfq_fixmp_2_5_rshift(u, 1);
19890         if (sig)
19891           mpfq_fixmp_2_5_add(u, u, fix);
19892         --t;
19893       }
19894       mpfq_copy(res, u, 3);
19895       return 1;
19896 }
19897 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_invmod) */
19898 
19899 #if !defined(HAVE_native_mpfq_fixmp_2_5_redc)
19900 /* x has 5 words, z and p have 2.5 words.
19901  * only one word is read from invp.
19902  * Assuming R=W^3 is the redc modulus, we expect that x verifies:
19903  *   x < R*p,
19904  * so that we have eventually z < p, z congruent to x/R mod p.
19905  * The contents of the area pointed by x are clobbered by this call.
19906  * Note also that x may alias z.
19907  */
19908 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
19909 static inline
mpfq_fixmp_2_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)19910 void mpfq_fixmp_2_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
19911 {
19912     mp_limb_t cy;
19913     for(int i = 0; i < 3; ++i) {
19914         mp_limb_t t = x[i]*mip[0];
19915         cy = mpfq_fixmp_2_5_addmul1_shortz(x+i, p, t);
19916         assert (x[i] == 0);
19917         x[i] = cy;
19918     }
19919     {
19920         mp_limb_t ret[3] = { x[3], x[4], 0 };
19921         cy = mpfq_fixmp_2_5_add(x, x, ret);
19922     }
19923     /* At this point, we have (x' denotes x + cy*W^n here)
19924     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
19925     * x'/R < p + p
19926     */
19927     if (cy || mpfq_fixmp_2_5_cmp(x, p) >= 0) {
19928         mpfq_fixmp_2_5_sub(z, x, p);
19929     } else {
19930         mpfq_copy(z, x, 3);
19931     }
19932 }
19933 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_redc) */
19934 
19935 #if !defined(HAVE_native_mpfq_fixmp_2_5_redc_ur)
19936 /* x has 6 words, z and p have 2.5 words.
19937  * only one word is read from invp.
19938  * Assuming R=W^3 is the redc modulus, we expect that x verifies:
19939  *  x < W*W^2.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
19940  * so that we have eventually z < p, z congruent to x/R mod p.
19941  * The contents of the area pointed by x are clobbered by this call.
19942  * Note also that x may alias z.
19943  */
19944 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
19945 static inline
mpfq_fixmp_2_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)19946 void mpfq_fixmp_2_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
19947 {
19948     mp_limb_t cy, q[1];
19949     for(int i = 0; i < 3; ++i) {
19950         mp_limb_t t = x[i]*mip[0];
19951         cy = mpfq_fixmp_2_5_addmul1_shortz(x+i, p, t);
19952         assert (x[i] == 0);
19953         x[i] = cy;
19954     }
19955     cy = mpfq_fixmp_2_5_add(x + 3, x, x + 3);
19956     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
19957     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
19958     * x'/R < (W^0.5+1)*p
19959     */
19960     if (cy) {
19961         /* x'/R-p < W^0.5*p, which fits in n words. */
19962         mpfq_fixmp_2_5_sub(x + 3, x + 3, p);
19963     }
19964     mpn_tdiv_qr(q, z, 0, x + 3, 3, p, 3);
19965 }
19966 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_redc_ur) */
19967 
19968 #if !defined(HAVE_native_mpfq_fixmp_2_5_mgy_encode)
19969 /* x, z, and p have 2.5 words.
19970  * Assuming R=W^3 is the redc modulus, we compute z=R*x mod p. */
19971 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
19972 static inline
mpfq_fixmp_2_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)19973 void mpfq_fixmp_2_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
19974 {
19975     mp_limb_t t[6] = { 0, 0, 0, x[0], x[1], x[2] };
19976     mp_limb_t qq[3+1];
19977     mpn_tdiv_qr(qq, z, 0, t, 6, p, 3);
19978 }
19979 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mgy_encode) */
19980 
19981 #if !defined(HAVE_native_mpfq_fixmp_2_5_mgy_decode)
19982 /* x, z, invR, and p have 2.5 words.
19983  * Assuming R=W^3 is the redc modulus, we compute z=x/R mod p. */
19984 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
19985 static inline
mpfq_fixmp_2_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)19986 void mpfq_fixmp_2_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
19987 {
19988     mp_limb_t t[6];
19989     mpfq_fixmp_2_5_mul(t, x, invR);
19990     mpfq_fixmp_2_5_mod(z, t, p);
19991 }
19992 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_mgy_decode) */
19993 
19994 #if !defined(HAVE_native_mpfq_fixmp_2_5_lshift)
19995 /* a has 2.5 words. Shift it in place by cnt bits to the left.
19996  * The shift count cnt must not exceed the word size.
19997  * Note that no carry is returned for the bits shifted out. */
19998 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
19999 static inline
mpfq_fixmp_2_5_lshift(mp_limb_t * a,int cnt)20000 void mpfq_fixmp_2_5_lshift(mp_limb_t * a, int cnt)
20001 {
20002     if (!cnt) return;
20003     int i;
20004     int dnt = GMP_NUMB_BITS - cnt;
20005     for (i = 3-1; i>0; --i) {
20006         a[i] <<= cnt;
20007         a[i] |= (a[i-1] >> dnt);
20008     }
20009     a[0] <<= cnt;
20010 }
20011 #endif /* !defined(HAVE_native_mpfq_fixmp_2_5_lshift) */
20012 
20013 #if !defined(HAVE_native_mpfq_fixmp_3_5_add)
20014 /* x, y, and z have 3.5 words. Result in z. Return carry bit */
20015 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
20016 /* Triggered by: 3_5_invmod, 3_5_redc, 3_5_redc_ur */
20017 static inline
mpfq_fixmp_3_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20018 mp_limb_t mpfq_fixmp_3_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20019 {
20020     mp_limb_t r, s, t, cy, cy1, cy2;
20021     cy = 0;
20022     r = x[0];
20023     s = r + y[0];
20024     cy1 = s < r;
20025     t = s + cy;
20026     cy2 = t < s;
20027     cy = cy1 | cy2;
20028     z[0] = t;
20029     r = x[1];
20030     s = r + y[1];
20031     cy1 = s < r;
20032     t = s + cy;
20033     cy2 = t < s;
20034     cy = cy1 | cy2;
20035     z[1] = t;
20036     r = x[2];
20037     s = r + y[2];
20038     cy1 = s < r;
20039     t = s + cy;
20040     cy2 = t < s;
20041     cy = cy1 | cy2;
20042     z[2] = t;
20043     r = x[3];
20044     s = r + y[3];
20045     cy1 = s < r;
20046     t = s + cy;
20047     cy2 = t < s;
20048     cy = cy1 | cy2;
20049     z[3] = t;
20050     return cy;
20051 }
20052 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_add) */
20053 
20054 #if !defined(HAVE_native_mpfq_fixmp_3_5_sub)
20055 /* x, y, and z have 3.5 words. Result in z. Return borrow bit */
20056 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
20057 /* Triggered by: 3_5_invmod, 3_5_redc, 3_5_redc_ur */
20058 static inline
mpfq_fixmp_3_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20059 mp_limb_t mpfq_fixmp_3_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20060 {
20061     mp_limb_t r, s, t, cy, cy1, cy2;
20062     cy = 0;
20063     r = x[0];
20064     s = r - y[0];
20065     cy1 = s > r;
20066     t = s - cy;
20067     cy2 = t > s;
20068     cy = cy1 | cy2;
20069     z[0] = t;
20070     r = x[1];
20071     s = r - y[1];
20072     cy1 = s > r;
20073     t = s - cy;
20074     cy2 = t > s;
20075     cy = cy1 | cy2;
20076     z[1] = t;
20077     r = x[2];
20078     s = r - y[2];
20079     cy1 = s > r;
20080     t = s - cy;
20081     cy2 = t > s;
20082     cy = cy1 | cy2;
20083     z[2] = t;
20084     r = x[3];
20085     s = r - y[3];
20086     cy1 = s > r;
20087     t = s - cy;
20088     cy2 = t > s;
20089     cy = cy1 | cy2;
20090     z[3] = t;
20091     return cy;
20092 }
20093 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_sub) */
20094 
20095 #if !defined(HAVE_native_mpfq_fixmp_3_5_add_nc)
20096 /* x, y, and z have 3.5 words. Result in z. Carry bit is lost. */
20097 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
20098 static inline
mpfq_fixmp_3_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20099 void mpfq_fixmp_3_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20100 {
20101     mp_limb_t r, s, t, cy, cy1, cy2;
20102     cy = 0;
20103     r = x[0];
20104     s = r + y[0];
20105     cy1 = s < r;
20106     t = s + cy;
20107     cy2 = t < s;
20108     cy = cy1 | cy2;
20109     z[0] = t;
20110     r = x[1];
20111     s = r + y[1];
20112     cy1 = s < r;
20113     t = s + cy;
20114     cy2 = t < s;
20115     cy = cy1 | cy2;
20116     z[1] = t;
20117     r = x[2];
20118     s = r + y[2];
20119     cy1 = s < r;
20120     t = s + cy;
20121     cy2 = t < s;
20122     cy = cy1 | cy2;
20123     z[2] = t;
20124     r = x[3];
20125     s = r + y[3];
20126     cy1 = s < r;
20127     t = s + cy;
20128     cy2 = t < s;
20129     cy = cy1 | cy2;
20130     z[3] = t;
20131 }
20132 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_add_nc) */
20133 
20134 #if !defined(HAVE_native_mpfq_fixmp_3_5_sub_nc)
20135 /* x, y, and z have 3.5 words. Result in z. Borrow bit is lost. */
20136 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
20137 static inline
mpfq_fixmp_3_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20138 void mpfq_fixmp_3_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20139 {
20140     mp_limb_t r, s, t, cy, cy1, cy2;
20141     cy = 0;
20142     r = x[0];
20143     s = r - y[0];
20144     cy1 = s > r;
20145     t = s - cy;
20146     cy2 = t > s;
20147     cy = cy1 | cy2;
20148     z[0] = t;
20149     r = x[1];
20150     s = r - y[1];
20151     cy1 = s > r;
20152     t = s - cy;
20153     cy2 = t > s;
20154     cy = cy1 | cy2;
20155     z[1] = t;
20156     r = x[2];
20157     s = r - y[2];
20158     cy1 = s > r;
20159     t = s - cy;
20160     cy2 = t > s;
20161     cy = cy1 | cy2;
20162     z[2] = t;
20163     r = x[3];
20164     s = r - y[3];
20165     cy1 = s > r;
20166     t = s - cy;
20167     cy2 = t > s;
20168     cy = cy1 | cy2;
20169     z[3] = t;
20170 }
20171 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_sub_nc) */
20172 
20173 #if !defined(HAVE_native_mpfq_fixmp_3_5_add_ui)
20174 /* x, y, and z have 3.5 words. Result in z. Return carry bit */
20175 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
20176 static inline
mpfq_fixmp_3_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)20177 mp_limb_t mpfq_fixmp_3_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
20178 {
20179     mp_limb_t r, s, t, cy, cy1, cy2;
20180     cy = 0;
20181     r = x[0];
20182     s = r + y;
20183     cy1 = s < r;
20184     t = s + cy;
20185     cy2 = t < s;
20186     cy = cy1 | cy2;
20187     z[0] = t;
20188     s = x[1];
20189     t = s + cy;
20190     cy = t < s;
20191     z[1] = t;
20192     s = x[2];
20193     t = s + cy;
20194     cy = t < s;
20195     z[2] = t;
20196     s = x[3];
20197     t = s + cy;
20198     cy = t < s;
20199     z[3] = t;
20200     return cy;
20201 }
20202 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_add_ui) */
20203 
20204 #if !defined(HAVE_native_mpfq_fixmp_3_5_sub_ui)
20205 /* x, y, and z have 3.5 words. Result in z. Return borrow bit */
20206 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
20207 static inline
mpfq_fixmp_3_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)20208 mp_limb_t mpfq_fixmp_3_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
20209 {
20210     mp_limb_t r, s, t, cy, cy1, cy2;
20211     cy = 0;
20212     r = x[0];
20213     s = r - y;
20214     cy1 = s > r;
20215     t = s - cy;
20216     cy2 = t > s;
20217     cy = cy1 | cy2;
20218     z[0] = t;
20219     s = x[1];
20220     t = s - cy;
20221     cy = t > s;
20222     z[1] = t;
20223     s = x[2];
20224     t = s - cy;
20225     cy = t > s;
20226     z[2] = t;
20227     s = x[3];
20228     t = s - cy;
20229     cy = t > s;
20230     z[3] = t;
20231     return cy;
20232 }
20233 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_sub_ui) */
20234 
20235 #if !defined(HAVE_native_mpfq_fixmp_3_5_add_ui_nc)
20236 /* x, y, and z have 3.5 words. Result in z. Carry bit is lost. */
20237 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
20238 static inline
mpfq_fixmp_3_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)20239 void mpfq_fixmp_3_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
20240 {
20241     mp_limb_t r, s, t, cy, cy1, cy2;
20242     cy = 0;
20243     r = x[0];
20244     s = r + y;
20245     cy1 = s < r;
20246     t = s + cy;
20247     cy2 = t < s;
20248     cy = cy1 | cy2;
20249     z[0] = t;
20250     s = x[1];
20251     t = s + cy;
20252     cy = t < s;
20253     z[1] = t;
20254     s = x[2];
20255     t = s + cy;
20256     cy = t < s;
20257     z[2] = t;
20258     s = x[3];
20259     t = s + cy;
20260     cy = t < s;
20261     z[3] = t;
20262 }
20263 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_add_ui_nc) */
20264 
20265 #if !defined(HAVE_native_mpfq_fixmp_3_5_sub_ui_nc)
20266 /* x, y, and z have 3.5 words. Result in z. Borrow bit is lost. */
20267 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
20268 static inline
mpfq_fixmp_3_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)20269 void mpfq_fixmp_3_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
20270 {
20271     mp_limb_t r, s, t, cy, cy1, cy2;
20272     cy = 0;
20273     r = x[0];
20274     s = r - y;
20275     cy1 = s > r;
20276     t = s - cy;
20277     cy2 = t > s;
20278     cy = cy1 | cy2;
20279     z[0] = t;
20280     s = x[1];
20281     t = s - cy;
20282     cy = t > s;
20283     z[1] = t;
20284     s = x[2];
20285     t = s - cy;
20286     cy = t > s;
20287     z[2] = t;
20288     s = x[3];
20289     t = s - cy;
20290     cy = t > s;
20291     z[3] = t;
20292 }
20293 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_sub_ui_nc) */
20294 
20295 #if !defined(HAVE_native_mpfq_fixmp_3_5_cmp)
20296 /* x and y have 3.5 words. Return sign of difference x-y. */
20297 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
20298 /* Triggered by: 3_5_invmod, 3_5_redc, 3_5_redc_ur */
20299 static inline
mpfq_fixmp_3_5_cmp(const mp_limb_t * x,const mp_limb_t * y)20300 int mpfq_fixmp_3_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
20301 {
20302     for (int i = 4-1; i >= 0; --i) {
20303         if (x[i] > y[i]) return 1;
20304         if (x[i] < y[i]) return -1;
20305     }
20306     return 0;
20307 }
20308 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_cmp) */
20309 
20310 #if !defined(HAVE_native_mpfq_fixmp_3_5_cmp_ui)
20311 /* x has 3.5 words. Return sign of difference x-y. */
20312 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
20313 /* Triggered by: 3_5_invmod */
20314 static inline
mpfq_fixmp_3_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)20315 int mpfq_fixmp_3_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
20316 {
20317     for (int i = 4-1; i > 0; --i) {
20318         if (x[i]) return 1;
20319     }
20320     if (x[0]>y) return 1;
20321     if (x[0]<y) return -1;
20322     return 0;
20323 }
20324 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_cmp_ui) */
20325 
20326 #if !defined(HAVE_native_mpfq_fixmp_3_5_addmul1)
20327 /* x has 3.5 words, z has 5.
20328  * Put (z+x*c) in z. Return carry bit. */
20329 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
20330 static inline
mpfq_fixmp_3_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20331 mp_limb_t mpfq_fixmp_3_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20332 {
20333     mp_limb_t hi, lo, carry, buf;
20334     carry = 0;
20335     mpfq_umul_ppmm(hi,lo,c,x[0]);
20336     lo += carry;
20337     carry = (lo<carry) + hi;
20338     buf = z[0];
20339     lo += buf;
20340     carry += (lo<buf);
20341     z[0] = lo;
20342     mpfq_umul_ppmm(hi,lo,c,x[1]);
20343     lo += carry;
20344     carry = (lo<carry) + hi;
20345     buf = z[1];
20346     lo += buf;
20347     carry += (lo<buf);
20348     z[1] = lo;
20349     mpfq_umul_ppmm(hi,lo,c,x[2]);
20350     lo += carry;
20351     carry = (lo<carry) + hi;
20352     buf = z[2];
20353     lo += buf;
20354     carry += (lo<buf);
20355     z[2] = lo;
20356     mpfq_umul_ppmm(hi,lo,c,x[3]);
20357     lo += carry;
20358     carry = (lo<carry) + hi;
20359     buf = z[3];
20360     lo += buf;
20361     carry += (lo<buf);
20362     z[3] = lo;
20363     z[4] += carry;
20364     return (z[4]<carry);
20365 }
20366 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_addmul1) */
20367 
20368 #if !defined(HAVE_native_mpfq_fixmp_3_5_addmul1_nc)
20369 /* x has 3.5 words, z has 5.
20370  * Put (z+x*c) in z. Carry bit is lost. */
20371 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
20372 /* Triggered by: 3_5_mul, 3_5_mgy_decode */
20373 static inline
mpfq_fixmp_3_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20374 void mpfq_fixmp_3_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20375 {
20376     mp_limb_t hi, lo, carry, buf;
20377     carry = 0;
20378     mpfq_umul_ppmm(hi,lo,c,x[0]);
20379     lo += carry;
20380     carry = (lo<carry) + hi;
20381     buf = z[0];
20382     lo += buf;
20383     carry += (lo<buf);
20384     z[0] = lo;
20385     mpfq_umul_ppmm(hi,lo,c,x[1]);
20386     lo += carry;
20387     carry = (lo<carry) + hi;
20388     buf = z[1];
20389     lo += buf;
20390     carry += (lo<buf);
20391     z[1] = lo;
20392     mpfq_umul_ppmm(hi,lo,c,x[2]);
20393     lo += carry;
20394     carry = (lo<carry) + hi;
20395     buf = z[2];
20396     lo += buf;
20397     carry += (lo<buf);
20398     z[2] = lo;
20399     mpfq_umul_ppmm(hi,lo,c,x[3]);
20400     lo += carry;
20401     carry = (lo<carry) + hi;
20402     buf = z[3];
20403     lo += buf;
20404     carry += (lo<buf);
20405     z[3] = lo;
20406     z[4] += carry;
20407 }
20408 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_addmul1_nc) */
20409 
20410 #if !defined(HAVE_native_mpfq_fixmp_3_5_addmul1_shortz)
20411 /* x has 3.5 words, z has 4.
20412  * Put (z+x*c) in z. Return carry word. */
20413 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
20414 /* Triggered by: 3_5_redc, 3_5_redc_ur */
20415 static inline
mpfq_fixmp_3_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20416 mp_limb_t mpfq_fixmp_3_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20417 {
20418     mp_limb_t hi, lo, carry, buf;
20419     carry = 0;
20420     mpfq_umul_ppmm(hi,lo,c,x[0]);
20421     lo += carry;
20422     carry = (lo<carry) + hi;
20423     buf = z[0];
20424     lo += buf;
20425     carry += (lo<buf);
20426     z[0] = lo;
20427     mpfq_umul_ppmm(hi,lo,c,x[1]);
20428     lo += carry;
20429     carry = (lo<carry) + hi;
20430     buf = z[1];
20431     lo += buf;
20432     carry += (lo<buf);
20433     z[1] = lo;
20434     mpfq_umul_ppmm(hi,lo,c,x[2]);
20435     lo += carry;
20436     carry = (lo<carry) + hi;
20437     buf = z[2];
20438     lo += buf;
20439     carry += (lo<buf);
20440     z[2] = lo;
20441     mpfq_umul_ppmm(hi,lo,c,x[3]);
20442     lo += carry;
20443     carry = (lo<carry) + hi;
20444     buf = z[3];
20445     lo += buf;
20446     carry += (lo<buf);
20447     z[3] = lo;
20448     return carry;
20449 }
20450 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_addmul1_shortz) */
20451 
20452 #if !defined(HAVE_native_mpfq_fixmp_3_5_addmul05_nc)
20453 /* x has 3.5 words, z has 4. c is 0.5 word.
20454  * Put (z+x*c) in z. Carry bit is lost. */
20455 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
20456 /* Triggered by: 3_5_mul, 3_5_mgy_decode */
20457 static inline
mpfq_fixmp_3_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20458 void mpfq_fixmp_3_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20459 {
20460     mp_limb_t hi, lo, carry, buf;
20461     carry = 0;
20462     mpfq_umul_ppmm(hi,lo,c,x[0]);
20463     lo += carry;
20464     carry = (lo<carry) + hi;
20465     buf = z[0];
20466     lo += buf;
20467     carry += (lo<buf);
20468     z[0] = lo;
20469     mpfq_umul_ppmm(hi,lo,c,x[1]);
20470     lo += carry;
20471     carry = (lo<carry) + hi;
20472     buf = z[1];
20473     lo += buf;
20474     carry += (lo<buf);
20475     z[1] = lo;
20476     mpfq_umul_ppmm(hi,lo,c,x[2]);
20477     lo += carry;
20478     carry = (lo<carry) + hi;
20479     buf = z[2];
20480     lo += buf;
20481     carry += (lo<buf);
20482     z[2] = lo;
20483     lo = c*x[3] + carry;
20484     assert(lo >= carry);
20485     z[3] += lo;
20486 }
20487 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_addmul05_nc) */
20488 
20489 #if !defined(HAVE_native_mpfq_fixmp_3_5_mul)
20490 /* x and y have 3.5 words, z has 7. Put x*y in z. */
20491 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
20492 /* Triggered by: 3_5_mgy_decode */
20493 static inline
mpfq_fixmp_3_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20494 void mpfq_fixmp_3_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20495 {
20496     assert(z != x && z != y);
20497     for (int i = 0; i < 7; z[i++] = 0) ;
20498     mpfq_fixmp_3_5_addmul1_nc (z + 0, x, y[0]);
20499     mpfq_fixmp_3_5_addmul1_nc (z + 1, x, y[1]);
20500     mpfq_fixmp_3_5_addmul1_nc (z + 2, x, y[2]);
20501     mpfq_fixmp_3_5_addmul05_nc (z + 3, x, y[3]);
20502 }
20503 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mul) */
20504 
20505 #if !defined(HAVE_native_mpfq_fixmp_3_5_sqr)
20506 /* x has 3.5 words, z has 7. Put x*y in z. */
20507 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
20508 static inline
mpfq_fixmp_3_5_sqr(mp_limb_t * z,const mp_limb_t * x)20509 void mpfq_fixmp_3_5_sqr(mp_limb_t * z, const mp_limb_t * x)
20510 {
20511     mp_limb_t buf[7] = {0,};
20512     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
20513     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
20514     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
20515     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
20516     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
20517     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
20518     z[2*3] = x[3] * x[3];
20519     mpn_lshift(buf, buf, 7, 1);
20520     mpn_add_n(z, z, buf, 7);
20521 }
20522 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_sqr) */
20523 
20524 #if !defined(HAVE_native_mpfq_fixmp_3_5_mul1)
20525 /* x has 3.5 words, z has 5. Put x*y in z. */
20526 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
20527 static inline
mpfq_fixmp_3_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20528 void mpfq_fixmp_3_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20529 {
20530     mp_limb_t hi, lo, carry;
20531     carry = 0;
20532     mpfq_umul_ppmm(hi,lo,c,x[0]);
20533     lo += carry;
20534     carry = (lo<carry) + hi;
20535     z[0] = lo;
20536     mpfq_umul_ppmm(hi,lo,c,x[1]);
20537     lo += carry;
20538     carry = (lo<carry) + hi;
20539     z[1] = lo;
20540     mpfq_umul_ppmm(hi,lo,c,x[2]);
20541     lo += carry;
20542     carry = (lo<carry) + hi;
20543     z[2] = lo;
20544     mpfq_umul_ppmm(hi,lo,c,x[3]);
20545     lo += carry;
20546     carry = (lo<carry) + hi;
20547     z[3] = lo;
20548     z[4] = carry;
20549 }
20550 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mul1) */
20551 
20552 #if !defined(HAVE_native_mpfq_fixmp_3_5_shortmul)
20553 /* x and y have 3.5 words, z has 4.
20554  * Put the low 4 words of x*y in z. */
20555 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
20556 static inline
mpfq_fixmp_3_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20557 void mpfq_fixmp_3_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20558 {
20559     mpfq_zero(z, 4);
20560     mpfq_fixmp_3_addmul1_nc (z+0, x, y[0]);
20561     z[4-1] += x[3]*y[0];
20562     mpfq_fixmp_2_addmul1_nc (z+1, x, y[1]);
20563     z[4-1] += x[2]*y[1];
20564     mpfq_fixmp_1_addmul1_nc (z+2, x, y[2]);
20565     z[4-1] += x[1]*y[2];
20566     z[4-1] += x[0]*y[4-1];
20567 }
20568 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_shortmul) */
20569 
20570 #if !defined(HAVE_native_mpfq_fixmp_3_5_addmul05)
20571 /* x has 3.5 words, z has 4. c is 0.5 word.
20572  * Put (z+x*c) in z. Return carry bit. */
20573 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
20574 static inline
mpfq_fixmp_3_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20575 mp_limb_t mpfq_fixmp_3_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20576 {
20577     mp_limb_t hi, lo, carry, buf;
20578     carry = 0;
20579     mpfq_umul_ppmm(hi,lo,c,x[0]);
20580     lo += carry;
20581     carry = (lo<carry) + hi;
20582     buf = z[0];
20583     lo += buf;
20584     carry += (lo<buf);
20585     z[0] = lo;
20586     mpfq_umul_ppmm(hi,lo,c,x[1]);
20587     lo += carry;
20588     carry = (lo<carry) + hi;
20589     buf = z[1];
20590     lo += buf;
20591     carry += (lo<buf);
20592     z[1] = lo;
20593     mpfq_umul_ppmm(hi,lo,c,x[2]);
20594     lo += carry;
20595     carry = (lo<carry) + hi;
20596     buf = z[2];
20597     lo += buf;
20598     carry += (lo<buf);
20599     z[2] = lo;
20600     lo = c*x[3] + carry;
20601     assert(lo >= carry);
20602     z[3] += lo;
20603     return z[3] < lo;
20604 }
20605 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_addmul05) */
20606 
20607 #if !defined(HAVE_native_mpfq_fixmp_3_5_mul05)
20608 /* x has 3.5 words, z has 4. c is 0.5 word.
20609  * Put (x*c) in z. No carry. */
20610 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
20611 static inline
mpfq_fixmp_3_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)20612 void mpfq_fixmp_3_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
20613 {
20614     mp_limb_t hi, lo, carry;
20615     carry = 0;
20616     mpfq_umul_ppmm(hi,lo,c,x[0]);
20617     lo += carry;
20618     carry = (lo<carry) + hi;
20619     z[0] = lo;
20620     mpfq_umul_ppmm(hi,lo,c,x[1]);
20621     lo += carry;
20622     carry = (lo<carry) + hi;
20623     z[1] = lo;
20624     mpfq_umul_ppmm(hi,lo,c,x[2]);
20625     lo += carry;
20626     carry = (lo<carry) + hi;
20627     z[2] = lo;
20628     lo = c*x[3] + carry;
20629     assert(lo >= carry);
20630     z[3] = lo;
20631 }
20632 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mul05) */
20633 
20634 #if !defined(HAVE_native_mpfq_fixmp_3_5_mod)
20635 /* x has 7 words. z and p have 3.5 words, and the high word of p is non-zero.
20636  * Put x mod p in z. */
20637 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
20638 /* Triggered by: 3_5_mgy_decode */
20639 static inline
mpfq_fixmp_3_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)20640 void mpfq_fixmp_3_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
20641 {
20642     mp_limb_t q[3+1], r[4];
20643     assert (p[4-1] != 0);
20644     mpn_tdiv_qr(q, r, 0, x, 7, p, 4);
20645     mpfq_copy(z, r, 4);
20646 }
20647 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mod) */
20648 
20649 #if !defined(HAVE_native_mpfq_fixmp_3_5_rshift)
20650 /* a has 3.5 words. Shift it in place by cnt bits to the right.
20651  * The shift count cnt must not exceed the word size.
20652  * Note that no carry is returned for the bits shifted out. */
20653 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
20654 /* Triggered by: 3_5_invmod */
20655 static inline
mpfq_fixmp_3_5_rshift(mp_limb_t * a,int cnt)20656 void mpfq_fixmp_3_5_rshift(mp_limb_t * a, int cnt)
20657 {
20658     if (!cnt) return;
20659     int i;
20660     int dnt = GMP_NUMB_BITS - cnt;
20661     for (i = 0; i < 4-1; ++i) {
20662         a[i] >>= cnt;
20663         a[i] |= (a[i+1] << dnt);
20664     }
20665     a[4-1] >>= cnt;
20666 }
20667 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_rshift) */
20668 
20669 #if !defined(HAVE_native_mpfq_fixmp_3_5_long_rshift)
20670 /* a has 3.5 words. Shift it in place by off words plus cnt bits to the left.
20671  * Note that no carry is returned for the bits shifted out. */
20672 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
20673 /* Triggered by: 3_5_invmod */
20674 static inline
mpfq_fixmp_3_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)20675 void mpfq_fixmp_3_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
20676 {
20677     if (cnt) {
20678         int dnt = GMP_NUMB_BITS - cnt;
20679         for (int i = 0; i < 4 - off - 1; ++i) {
20680             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
20681         }
20682         a[4-off-1] = a[4-1]>>cnt;
20683     } else {
20684         mpfq_copyi(a, a + off, 4 - off);
20685     }
20686     mpfq_zero(a + 4 - off, off);
20687 }
20688 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_long_rshift) */
20689 
20690 #if !defined(HAVE_native_mpfq_fixmp_3_5_long_lshift)
20691 /* a has 3.5 words. Shift it in place by off words plus cnt bits to the left.
20692  * Note that no carry is returned for the bits shifted out. */
20693 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
20694 /* Triggered by: 3_5_invmod */
20695 static inline
mpfq_fixmp_3_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)20696 void mpfq_fixmp_3_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
20697 {
20698     int i;
20699     if (cnt) {
20700         int dnt = GMP_NUMB_BITS - cnt;
20701         for (i = 4-1; i>off; --i) {
20702             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
20703         }
20704         a[off] = a[0]<<cnt;
20705     } else {
20706         mpfq_copyd(a + off, a, 4 - off);
20707     }
20708     mpfq_zero(a, off);
20709 }
20710 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_long_lshift) */
20711 
20712 #if !defined(HAVE_native_mpfq_fixmp_3_5_invmod)
20713 /* x, z, and p have 3.5 words. Put inverse of x mod p in z.
20714  * Return non-zero if an inverse could be found.
20715  * If no inverse could be found, return 0 and set z to zero.
20716  */
20717 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
20718 static inline
mpfq_fixmp_3_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)20719 int mpfq_fixmp_3_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
20720 {
20721       mp_limb_t u[4], v[4], a[4], b[4], fix[4];
20722       int i, t, lsh;
20723 
20724       mpfq_zero(u, 4);
20725       mpfq_zero(v, 4);
20726       mpfq_copy(a, x, 4);
20727       mpfq_copy(b, p, 4);
20728       u[0] = 1UL;
20729 
20730       if (mpfq_fixmp_3_5_cmp(a, v) == 0 || mpfq_fixmp_3_5_cmp(a, b) == 0) {
20731         mpfq_zero(res, 4);
20732         return 0;
20733       }
20734 
20735       mpfq_fixmp_3_5_add(fix, b, u);
20736       mpfq_fixmp_3_5_rshift(fix, 1);
20737 
20738       assert (mpfq_fixmp_3_5_cmp(a,b) < 0);
20739 
20740       t = 0;
20741 
20742       for(i = 0 ; !a[i] ; i++) ;
20743       assert (i < 4);
20744       lsh = mpfq_ctzl(a[i]);
20745       mpfq_fixmp_3_5_long_rshift(a, i, lsh);
20746       t += lsh + i*GMP_NUMB_BITS;
20747       mpfq_fixmp_3_5_long_lshift(v, i, lsh);
20748 
20749       do {
20750         do {
20751           mpfq_fixmp_3_5_sub(b, b, a);
20752           mpfq_fixmp_3_5_add(v, v, u);
20753           for(i = 0 ; !b[i] ; i++) ;
20754           assert (i < 4);
20755           lsh = mpfq_ctzl(b[i]);
20756           mpfq_fixmp_3_5_long_rshift(b, i, lsh);
20757           t += lsh + i*GMP_NUMB_BITS;
20758           mpfq_fixmp_3_5_long_lshift(u, i, lsh);
20759         } while (mpfq_fixmp_3_5_cmp(a,b) < 0);
20760         if (mpfq_fixmp_3_5_cmp(a, b) == 0)
20761           break;
20762         do {
20763           mpfq_fixmp_3_5_sub(a, a, b);
20764           mpfq_fixmp_3_5_add(u, u, v);
20765           for(i = 0 ; !a[i] ; i++) ;
20766           assert (i < 4);
20767           lsh = mpfq_ctzl(a[i]);
20768           mpfq_fixmp_3_5_long_rshift(a, i, lsh);
20769           t += lsh + i*GMP_NUMB_BITS;
20770           mpfq_fixmp_3_5_long_lshift(v, i, lsh);
20771         } while (mpfq_fixmp_3_5_cmp(b,a)<0);
20772       } while (mpfq_fixmp_3_5_cmp(a,b) != 0);
20773       {
20774         if (mpfq_fixmp_3_5_cmp_ui(a, 1) != 0) {
20775           mpfq_copy(res, a, 4);
20776           return 0;
20777         }
20778       }
20779       while (t>0) {
20780         mp_limb_t sig = u[0] & 1UL;
20781         mpfq_fixmp_3_5_rshift(u, 1);
20782         if (sig)
20783           mpfq_fixmp_3_5_add(u, u, fix);
20784         --t;
20785       }
20786       mpfq_copy(res, u, 4);
20787       return 1;
20788 }
20789 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_invmod) */
20790 
20791 #if !defined(HAVE_native_mpfq_fixmp_3_5_redc)
20792 /* x has 7 words, z and p have 3.5 words.
20793  * only one word is read from invp.
20794  * Assuming R=W^4 is the redc modulus, we expect that x verifies:
20795  *   x < R*p,
20796  * so that we have eventually z < p, z congruent to x/R mod p.
20797  * The contents of the area pointed by x are clobbered by this call.
20798  * Note also that x may alias z.
20799  */
20800 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
20801 static inline
mpfq_fixmp_3_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)20802 void mpfq_fixmp_3_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
20803 {
20804     mp_limb_t cy;
20805     for(int i = 0; i < 4; ++i) {
20806         mp_limb_t t = x[i]*mip[0];
20807         cy = mpfq_fixmp_3_5_addmul1_shortz(x+i, p, t);
20808         assert (x[i] == 0);
20809         x[i] = cy;
20810     }
20811     {
20812         mp_limb_t ret[4] = { x[4], x[5], x[6], 0 };
20813         cy = mpfq_fixmp_3_5_add(x, x, ret);
20814     }
20815     /* At this point, we have (x' denotes x + cy*W^n here)
20816     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
20817     * x'/R < p + p
20818     */
20819     if (cy || mpfq_fixmp_3_5_cmp(x, p) >= 0) {
20820         mpfq_fixmp_3_5_sub(z, x, p);
20821     } else {
20822         mpfq_copy(z, x, 4);
20823     }
20824 }
20825 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_redc) */
20826 
20827 #if !defined(HAVE_native_mpfq_fixmp_3_5_redc_ur)
20828 /* x has 8 words, z and p have 3.5 words.
20829  * only one word is read from invp.
20830  * Assuming R=W^4 is the redc modulus, we expect that x verifies:
20831  *  x < W*W^3.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
20832  * so that we have eventually z < p, z congruent to x/R mod p.
20833  * The contents of the area pointed by x are clobbered by this call.
20834  * Note also that x may alias z.
20835  */
20836 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
20837 static inline
mpfq_fixmp_3_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)20838 void mpfq_fixmp_3_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
20839 {
20840     mp_limb_t cy, q[1];
20841     for(int i = 0; i < 4; ++i) {
20842         mp_limb_t t = x[i]*mip[0];
20843         cy = mpfq_fixmp_3_5_addmul1_shortz(x+i, p, t);
20844         assert (x[i] == 0);
20845         x[i] = cy;
20846     }
20847     cy = mpfq_fixmp_3_5_add(x + 4, x, x + 4);
20848     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
20849     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
20850     * x'/R < (W^0.5+1)*p
20851     */
20852     if (cy) {
20853         /* x'/R-p < W^0.5*p, which fits in n words. */
20854         mpfq_fixmp_3_5_sub(x + 4, x + 4, p);
20855     }
20856     mpn_tdiv_qr(q, z, 0, x + 4, 4, p, 4);
20857 }
20858 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_redc_ur) */
20859 
20860 #if !defined(HAVE_native_mpfq_fixmp_3_5_mgy_encode)
20861 /* x, z, and p have 3.5 words.
20862  * Assuming R=W^4 is the redc modulus, we compute z=R*x mod p. */
20863 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
20864 static inline
mpfq_fixmp_3_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)20865 void mpfq_fixmp_3_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
20866 {
20867     mp_limb_t t[8] = { 0, 0, 0, 0, x[0], x[1], x[2], x[3] };
20868     mp_limb_t qq[4+1];
20869     mpn_tdiv_qr(qq, z, 0, t, 8, p, 4);
20870 }
20871 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mgy_encode) */
20872 
20873 #if !defined(HAVE_native_mpfq_fixmp_3_5_mgy_decode)
20874 /* x, z, invR, and p have 3.5 words.
20875  * Assuming R=W^4 is the redc modulus, we compute z=x/R mod p. */
20876 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
20877 static inline
mpfq_fixmp_3_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)20878 void mpfq_fixmp_3_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
20879 {
20880     mp_limb_t t[8];
20881     mpfq_fixmp_3_5_mul(t, x, invR);
20882     mpfq_fixmp_3_5_mod(z, t, p);
20883 }
20884 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_mgy_decode) */
20885 
20886 #if !defined(HAVE_native_mpfq_fixmp_3_5_lshift)
20887 /* a has 3.5 words. Shift it in place by cnt bits to the left.
20888  * The shift count cnt must not exceed the word size.
20889  * Note that no carry is returned for the bits shifted out. */
20890 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
20891 static inline
mpfq_fixmp_3_5_lshift(mp_limb_t * a,int cnt)20892 void mpfq_fixmp_3_5_lshift(mp_limb_t * a, int cnt)
20893 {
20894     if (!cnt) return;
20895     int i;
20896     int dnt = GMP_NUMB_BITS - cnt;
20897     for (i = 4-1; i>0; --i) {
20898         a[i] <<= cnt;
20899         a[i] |= (a[i-1] >> dnt);
20900     }
20901     a[0] <<= cnt;
20902 }
20903 #endif /* !defined(HAVE_native_mpfq_fixmp_3_5_lshift) */
20904 
20905 #if !defined(HAVE_native_mpfq_fixmp_4_5_add)
20906 /* x, y, and z have 4.5 words. Result in z. Return carry bit */
20907 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
20908 /* Triggered by: 4_5_invmod, 4_5_redc, 4_5_redc_ur */
20909 static inline
mpfq_fixmp_4_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20910 mp_limb_t mpfq_fixmp_4_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20911 {
20912     mp_limb_t r, s, t, cy, cy1, cy2;
20913     cy = 0;
20914     r = x[0];
20915     s = r + y[0];
20916     cy1 = s < r;
20917     t = s + cy;
20918     cy2 = t < s;
20919     cy = cy1 | cy2;
20920     z[0] = t;
20921     r = x[1];
20922     s = r + y[1];
20923     cy1 = s < r;
20924     t = s + cy;
20925     cy2 = t < s;
20926     cy = cy1 | cy2;
20927     z[1] = t;
20928     r = x[2];
20929     s = r + y[2];
20930     cy1 = s < r;
20931     t = s + cy;
20932     cy2 = t < s;
20933     cy = cy1 | cy2;
20934     z[2] = t;
20935     r = x[3];
20936     s = r + y[3];
20937     cy1 = s < r;
20938     t = s + cy;
20939     cy2 = t < s;
20940     cy = cy1 | cy2;
20941     z[3] = t;
20942     r = x[4];
20943     s = r + y[4];
20944     cy1 = s < r;
20945     t = s + cy;
20946     cy2 = t < s;
20947     cy = cy1 | cy2;
20948     z[4] = t;
20949     return cy;
20950 }
20951 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_add) */
20952 
20953 #if !defined(HAVE_native_mpfq_fixmp_4_5_sub)
20954 /* x, y, and z have 4.5 words. Result in z. Return borrow bit */
20955 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
20956 /* Triggered by: 4_5_invmod, 4_5_redc, 4_5_redc_ur */
20957 static inline
mpfq_fixmp_4_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)20958 mp_limb_t mpfq_fixmp_4_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
20959 {
20960     mp_limb_t r, s, t, cy, cy1, cy2;
20961     cy = 0;
20962     r = x[0];
20963     s = r - y[0];
20964     cy1 = s > r;
20965     t = s - cy;
20966     cy2 = t > s;
20967     cy = cy1 | cy2;
20968     z[0] = t;
20969     r = x[1];
20970     s = r - y[1];
20971     cy1 = s > r;
20972     t = s - cy;
20973     cy2 = t > s;
20974     cy = cy1 | cy2;
20975     z[1] = t;
20976     r = x[2];
20977     s = r - y[2];
20978     cy1 = s > r;
20979     t = s - cy;
20980     cy2 = t > s;
20981     cy = cy1 | cy2;
20982     z[2] = t;
20983     r = x[3];
20984     s = r - y[3];
20985     cy1 = s > r;
20986     t = s - cy;
20987     cy2 = t > s;
20988     cy = cy1 | cy2;
20989     z[3] = t;
20990     r = x[4];
20991     s = r - y[4];
20992     cy1 = s > r;
20993     t = s - cy;
20994     cy2 = t > s;
20995     cy = cy1 | cy2;
20996     z[4] = t;
20997     return cy;
20998 }
20999 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_sub) */
21000 
21001 #if !defined(HAVE_native_mpfq_fixmp_4_5_add_nc)
21002 /* x, y, and z have 4.5 words. Result in z. Carry bit is lost. */
21003 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
21004 static inline
mpfq_fixmp_4_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21005 void mpfq_fixmp_4_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21006 {
21007     mp_limb_t r, s, t, cy, cy1, cy2;
21008     cy = 0;
21009     r = x[0];
21010     s = r + y[0];
21011     cy1 = s < r;
21012     t = s + cy;
21013     cy2 = t < s;
21014     cy = cy1 | cy2;
21015     z[0] = t;
21016     r = x[1];
21017     s = r + y[1];
21018     cy1 = s < r;
21019     t = s + cy;
21020     cy2 = t < s;
21021     cy = cy1 | cy2;
21022     z[1] = t;
21023     r = x[2];
21024     s = r + y[2];
21025     cy1 = s < r;
21026     t = s + cy;
21027     cy2 = t < s;
21028     cy = cy1 | cy2;
21029     z[2] = t;
21030     r = x[3];
21031     s = r + y[3];
21032     cy1 = s < r;
21033     t = s + cy;
21034     cy2 = t < s;
21035     cy = cy1 | cy2;
21036     z[3] = t;
21037     r = x[4];
21038     s = r + y[4];
21039     cy1 = s < r;
21040     t = s + cy;
21041     cy2 = t < s;
21042     cy = cy1 | cy2;
21043     z[4] = t;
21044 }
21045 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_add_nc) */
21046 
21047 #if !defined(HAVE_native_mpfq_fixmp_4_5_sub_nc)
21048 /* x, y, and z have 4.5 words. Result in z. Borrow bit is lost. */
21049 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
21050 static inline
mpfq_fixmp_4_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21051 void mpfq_fixmp_4_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21052 {
21053     mp_limb_t r, s, t, cy, cy1, cy2;
21054     cy = 0;
21055     r = x[0];
21056     s = r - y[0];
21057     cy1 = s > r;
21058     t = s - cy;
21059     cy2 = t > s;
21060     cy = cy1 | cy2;
21061     z[0] = t;
21062     r = x[1];
21063     s = r - y[1];
21064     cy1 = s > r;
21065     t = s - cy;
21066     cy2 = t > s;
21067     cy = cy1 | cy2;
21068     z[1] = t;
21069     r = x[2];
21070     s = r - y[2];
21071     cy1 = s > r;
21072     t = s - cy;
21073     cy2 = t > s;
21074     cy = cy1 | cy2;
21075     z[2] = t;
21076     r = x[3];
21077     s = r - y[3];
21078     cy1 = s > r;
21079     t = s - cy;
21080     cy2 = t > s;
21081     cy = cy1 | cy2;
21082     z[3] = t;
21083     r = x[4];
21084     s = r - y[4];
21085     cy1 = s > r;
21086     t = s - cy;
21087     cy2 = t > s;
21088     cy = cy1 | cy2;
21089     z[4] = t;
21090 }
21091 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_sub_nc) */
21092 
21093 #if !defined(HAVE_native_mpfq_fixmp_4_5_add_ui)
21094 /* x, y, and z have 4.5 words. Result in z. Return carry bit */
21095 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
21096 static inline
mpfq_fixmp_4_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)21097 mp_limb_t mpfq_fixmp_4_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
21098 {
21099     mp_limb_t r, s, t, cy, cy1, cy2;
21100     cy = 0;
21101     r = x[0];
21102     s = r + y;
21103     cy1 = s < r;
21104     t = s + cy;
21105     cy2 = t < s;
21106     cy = cy1 | cy2;
21107     z[0] = t;
21108     s = x[1];
21109     t = s + cy;
21110     cy = t < s;
21111     z[1] = t;
21112     s = x[2];
21113     t = s + cy;
21114     cy = t < s;
21115     z[2] = t;
21116     s = x[3];
21117     t = s + cy;
21118     cy = t < s;
21119     z[3] = t;
21120     s = x[4];
21121     t = s + cy;
21122     cy = t < s;
21123     z[4] = t;
21124     return cy;
21125 }
21126 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_add_ui) */
21127 
21128 #if !defined(HAVE_native_mpfq_fixmp_4_5_sub_ui)
21129 /* x, y, and z have 4.5 words. Result in z. Return borrow bit */
21130 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
21131 static inline
mpfq_fixmp_4_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)21132 mp_limb_t mpfq_fixmp_4_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
21133 {
21134     mp_limb_t r, s, t, cy, cy1, cy2;
21135     cy = 0;
21136     r = x[0];
21137     s = r - y;
21138     cy1 = s > r;
21139     t = s - cy;
21140     cy2 = t > s;
21141     cy = cy1 | cy2;
21142     z[0] = t;
21143     s = x[1];
21144     t = s - cy;
21145     cy = t > s;
21146     z[1] = t;
21147     s = x[2];
21148     t = s - cy;
21149     cy = t > s;
21150     z[2] = t;
21151     s = x[3];
21152     t = s - cy;
21153     cy = t > s;
21154     z[3] = t;
21155     s = x[4];
21156     t = s - cy;
21157     cy = t > s;
21158     z[4] = t;
21159     return cy;
21160 }
21161 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_sub_ui) */
21162 
21163 #if !defined(HAVE_native_mpfq_fixmp_4_5_add_ui_nc)
21164 /* x, y, and z have 4.5 words. Result in z. Carry bit is lost. */
21165 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
21166 static inline
mpfq_fixmp_4_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)21167 void mpfq_fixmp_4_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
21168 {
21169     mp_limb_t r, s, t, cy, cy1, cy2;
21170     cy = 0;
21171     r = x[0];
21172     s = r + y;
21173     cy1 = s < r;
21174     t = s + cy;
21175     cy2 = t < s;
21176     cy = cy1 | cy2;
21177     z[0] = t;
21178     s = x[1];
21179     t = s + cy;
21180     cy = t < s;
21181     z[1] = t;
21182     s = x[2];
21183     t = s + cy;
21184     cy = t < s;
21185     z[2] = t;
21186     s = x[3];
21187     t = s + cy;
21188     cy = t < s;
21189     z[3] = t;
21190     s = x[4];
21191     t = s + cy;
21192     cy = t < s;
21193     z[4] = t;
21194 }
21195 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_add_ui_nc) */
21196 
21197 #if !defined(HAVE_native_mpfq_fixmp_4_5_sub_ui_nc)
21198 /* x, y, and z have 4.5 words. Result in z. Borrow bit is lost. */
21199 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
21200 static inline
mpfq_fixmp_4_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)21201 void mpfq_fixmp_4_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
21202 {
21203     mp_limb_t r, s, t, cy, cy1, cy2;
21204     cy = 0;
21205     r = x[0];
21206     s = r - y;
21207     cy1 = s > r;
21208     t = s - cy;
21209     cy2 = t > s;
21210     cy = cy1 | cy2;
21211     z[0] = t;
21212     s = x[1];
21213     t = s - cy;
21214     cy = t > s;
21215     z[1] = t;
21216     s = x[2];
21217     t = s - cy;
21218     cy = t > s;
21219     z[2] = t;
21220     s = x[3];
21221     t = s - cy;
21222     cy = t > s;
21223     z[3] = t;
21224     s = x[4];
21225     t = s - cy;
21226     cy = t > s;
21227     z[4] = t;
21228 }
21229 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_sub_ui_nc) */
21230 
21231 #if !defined(HAVE_native_mpfq_fixmp_4_5_cmp)
21232 /* x and y have 4.5 words. Return sign of difference x-y. */
21233 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
21234 /* Triggered by: 4_5_invmod, 4_5_redc, 4_5_redc_ur */
21235 static inline
mpfq_fixmp_4_5_cmp(const mp_limb_t * x,const mp_limb_t * y)21236 int mpfq_fixmp_4_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
21237 {
21238     for (int i = 5-1; i >= 0; --i) {
21239         if (x[i] > y[i]) return 1;
21240         if (x[i] < y[i]) return -1;
21241     }
21242     return 0;
21243 }
21244 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_cmp) */
21245 
21246 #if !defined(HAVE_native_mpfq_fixmp_4_5_cmp_ui)
21247 /* x has 4.5 words. Return sign of difference x-y. */
21248 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
21249 /* Triggered by: 4_5_invmod */
21250 static inline
mpfq_fixmp_4_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)21251 int mpfq_fixmp_4_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
21252 {
21253     for (int i = 5-1; i > 0; --i) {
21254         if (x[i]) return 1;
21255     }
21256     if (x[0]>y) return 1;
21257     if (x[0]<y) return -1;
21258     return 0;
21259 }
21260 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_cmp_ui) */
21261 
21262 #if !defined(HAVE_native_mpfq_fixmp_4_5_addmul1)
21263 /* x has 4.5 words, z has 6.
21264  * Put (z+x*c) in z. Return carry bit. */
21265 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
21266 static inline
mpfq_fixmp_4_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21267 mp_limb_t mpfq_fixmp_4_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21268 {
21269     mp_limb_t hi, lo, carry, buf;
21270     carry = 0;
21271     mpfq_umul_ppmm(hi,lo,c,x[0]);
21272     lo += carry;
21273     carry = (lo<carry) + hi;
21274     buf = z[0];
21275     lo += buf;
21276     carry += (lo<buf);
21277     z[0] = lo;
21278     mpfq_umul_ppmm(hi,lo,c,x[1]);
21279     lo += carry;
21280     carry = (lo<carry) + hi;
21281     buf = z[1];
21282     lo += buf;
21283     carry += (lo<buf);
21284     z[1] = lo;
21285     mpfq_umul_ppmm(hi,lo,c,x[2]);
21286     lo += carry;
21287     carry = (lo<carry) + hi;
21288     buf = z[2];
21289     lo += buf;
21290     carry += (lo<buf);
21291     z[2] = lo;
21292     mpfq_umul_ppmm(hi,lo,c,x[3]);
21293     lo += carry;
21294     carry = (lo<carry) + hi;
21295     buf = z[3];
21296     lo += buf;
21297     carry += (lo<buf);
21298     z[3] = lo;
21299     mpfq_umul_ppmm(hi,lo,c,x[4]);
21300     lo += carry;
21301     carry = (lo<carry) + hi;
21302     buf = z[4];
21303     lo += buf;
21304     carry += (lo<buf);
21305     z[4] = lo;
21306     z[5] += carry;
21307     return (z[5]<carry);
21308 }
21309 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_addmul1) */
21310 
21311 #if !defined(HAVE_native_mpfq_fixmp_4_5_addmul1_nc)
21312 /* x has 4.5 words, z has 6.
21313  * Put (z+x*c) in z. Carry bit is lost. */
21314 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
21315 /* Triggered by: 4_5_mul, 4_5_mgy_decode */
21316 static inline
mpfq_fixmp_4_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21317 void mpfq_fixmp_4_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21318 {
21319     mp_limb_t hi, lo, carry, buf;
21320     carry = 0;
21321     mpfq_umul_ppmm(hi,lo,c,x[0]);
21322     lo += carry;
21323     carry = (lo<carry) + hi;
21324     buf = z[0];
21325     lo += buf;
21326     carry += (lo<buf);
21327     z[0] = lo;
21328     mpfq_umul_ppmm(hi,lo,c,x[1]);
21329     lo += carry;
21330     carry = (lo<carry) + hi;
21331     buf = z[1];
21332     lo += buf;
21333     carry += (lo<buf);
21334     z[1] = lo;
21335     mpfq_umul_ppmm(hi,lo,c,x[2]);
21336     lo += carry;
21337     carry = (lo<carry) + hi;
21338     buf = z[2];
21339     lo += buf;
21340     carry += (lo<buf);
21341     z[2] = lo;
21342     mpfq_umul_ppmm(hi,lo,c,x[3]);
21343     lo += carry;
21344     carry = (lo<carry) + hi;
21345     buf = z[3];
21346     lo += buf;
21347     carry += (lo<buf);
21348     z[3] = lo;
21349     mpfq_umul_ppmm(hi,lo,c,x[4]);
21350     lo += carry;
21351     carry = (lo<carry) + hi;
21352     buf = z[4];
21353     lo += buf;
21354     carry += (lo<buf);
21355     z[4] = lo;
21356     z[5] += carry;
21357 }
21358 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_addmul1_nc) */
21359 
21360 #if !defined(HAVE_native_mpfq_fixmp_4_5_addmul1_shortz)
21361 /* x has 4.5 words, z has 5.
21362  * Put (z+x*c) in z. Return carry word. */
21363 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
21364 /* Triggered by: 4_5_redc, 4_5_redc_ur */
21365 static inline
mpfq_fixmp_4_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21366 mp_limb_t mpfq_fixmp_4_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21367 {
21368     mp_limb_t hi, lo, carry, buf;
21369     carry = 0;
21370     mpfq_umul_ppmm(hi,lo,c,x[0]);
21371     lo += carry;
21372     carry = (lo<carry) + hi;
21373     buf = z[0];
21374     lo += buf;
21375     carry += (lo<buf);
21376     z[0] = lo;
21377     mpfq_umul_ppmm(hi,lo,c,x[1]);
21378     lo += carry;
21379     carry = (lo<carry) + hi;
21380     buf = z[1];
21381     lo += buf;
21382     carry += (lo<buf);
21383     z[1] = lo;
21384     mpfq_umul_ppmm(hi,lo,c,x[2]);
21385     lo += carry;
21386     carry = (lo<carry) + hi;
21387     buf = z[2];
21388     lo += buf;
21389     carry += (lo<buf);
21390     z[2] = lo;
21391     mpfq_umul_ppmm(hi,lo,c,x[3]);
21392     lo += carry;
21393     carry = (lo<carry) + hi;
21394     buf = z[3];
21395     lo += buf;
21396     carry += (lo<buf);
21397     z[3] = lo;
21398     mpfq_umul_ppmm(hi,lo,c,x[4]);
21399     lo += carry;
21400     carry = (lo<carry) + hi;
21401     buf = z[4];
21402     lo += buf;
21403     carry += (lo<buf);
21404     z[4] = lo;
21405     return carry;
21406 }
21407 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_addmul1_shortz) */
21408 
21409 #if !defined(HAVE_native_mpfq_fixmp_4_5_addmul05_nc)
21410 /* x has 4.5 words, z has 5. c is 0.5 word.
21411  * Put (z+x*c) in z. Carry bit is lost. */
21412 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
21413 /* Triggered by: 4_5_mul, 4_5_mgy_decode */
21414 static inline
mpfq_fixmp_4_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21415 void mpfq_fixmp_4_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21416 {
21417     mp_limb_t hi, lo, carry, buf;
21418     carry = 0;
21419     mpfq_umul_ppmm(hi,lo,c,x[0]);
21420     lo += carry;
21421     carry = (lo<carry) + hi;
21422     buf = z[0];
21423     lo += buf;
21424     carry += (lo<buf);
21425     z[0] = lo;
21426     mpfq_umul_ppmm(hi,lo,c,x[1]);
21427     lo += carry;
21428     carry = (lo<carry) + hi;
21429     buf = z[1];
21430     lo += buf;
21431     carry += (lo<buf);
21432     z[1] = lo;
21433     mpfq_umul_ppmm(hi,lo,c,x[2]);
21434     lo += carry;
21435     carry = (lo<carry) + hi;
21436     buf = z[2];
21437     lo += buf;
21438     carry += (lo<buf);
21439     z[2] = lo;
21440     mpfq_umul_ppmm(hi,lo,c,x[3]);
21441     lo += carry;
21442     carry = (lo<carry) + hi;
21443     buf = z[3];
21444     lo += buf;
21445     carry += (lo<buf);
21446     z[3] = lo;
21447     lo = c*x[4] + carry;
21448     assert(lo >= carry);
21449     z[4] += lo;
21450 }
21451 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_addmul05_nc) */
21452 
21453 #if !defined(HAVE_native_mpfq_fixmp_4_5_mul)
21454 /* x and y have 4.5 words, z has 9. Put x*y in z. */
21455 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
21456 /* Triggered by: 4_5_mgy_decode */
21457 static inline
mpfq_fixmp_4_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21458 void mpfq_fixmp_4_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21459 {
21460     assert(z != x && z != y);
21461     for (int i = 0; i < 9; z[i++] = 0) ;
21462     mpfq_fixmp_4_5_addmul1_nc (z + 0, x, y[0]);
21463     mpfq_fixmp_4_5_addmul1_nc (z + 1, x, y[1]);
21464     mpfq_fixmp_4_5_addmul1_nc (z + 2, x, y[2]);
21465     mpfq_fixmp_4_5_addmul1_nc (z + 3, x, y[3]);
21466     mpfq_fixmp_4_5_addmul05_nc (z + 4, x, y[4]);
21467 }
21468 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mul) */
21469 
21470 #if !defined(HAVE_native_mpfq_fixmp_4_5_sqr)
21471 /* x has 4.5 words, z has 9. Put x*y in z. */
21472 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
21473 static inline
mpfq_fixmp_4_5_sqr(mp_limb_t * z,const mp_limb_t * x)21474 void mpfq_fixmp_4_5_sqr(mp_limb_t * z, const mp_limb_t * x)
21475 {
21476     mp_limb_t buf[9] = {0,};
21477     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
21478     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
21479     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
21480     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
21481     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
21482     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
21483     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
21484     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
21485     z[2*4] = x[4] * x[4];
21486     mpn_lshift(buf, buf, 9, 1);
21487     mpn_add_n(z, z, buf, 9);
21488 }
21489 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_sqr) */
21490 
21491 #if !defined(HAVE_native_mpfq_fixmp_4_5_mul1)
21492 /* x has 4.5 words, z has 6. Put x*y in z. */
21493 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
21494 static inline
mpfq_fixmp_4_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21495 void mpfq_fixmp_4_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21496 {
21497     mp_limb_t hi, lo, carry;
21498     carry = 0;
21499     mpfq_umul_ppmm(hi,lo,c,x[0]);
21500     lo += carry;
21501     carry = (lo<carry) + hi;
21502     z[0] = lo;
21503     mpfq_umul_ppmm(hi,lo,c,x[1]);
21504     lo += carry;
21505     carry = (lo<carry) + hi;
21506     z[1] = lo;
21507     mpfq_umul_ppmm(hi,lo,c,x[2]);
21508     lo += carry;
21509     carry = (lo<carry) + hi;
21510     z[2] = lo;
21511     mpfq_umul_ppmm(hi,lo,c,x[3]);
21512     lo += carry;
21513     carry = (lo<carry) + hi;
21514     z[3] = lo;
21515     mpfq_umul_ppmm(hi,lo,c,x[4]);
21516     lo += carry;
21517     carry = (lo<carry) + hi;
21518     z[4] = lo;
21519     z[5] = carry;
21520 }
21521 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mul1) */
21522 
21523 #if !defined(HAVE_native_mpfq_fixmp_4_5_shortmul)
21524 /* x and y have 4.5 words, z has 5.
21525  * Put the low 5 words of x*y in z. */
21526 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
21527 static inline
mpfq_fixmp_4_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21528 void mpfq_fixmp_4_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21529 {
21530     mpfq_zero(z, 5);
21531     mpfq_fixmp_4_addmul1_nc (z+0, x, y[0]);
21532     z[5-1] += x[4]*y[0];
21533     mpfq_fixmp_3_addmul1_nc (z+1, x, y[1]);
21534     z[5-1] += x[3]*y[1];
21535     mpfq_fixmp_2_addmul1_nc (z+2, x, y[2]);
21536     z[5-1] += x[2]*y[2];
21537     mpfq_fixmp_1_addmul1_nc (z+3, x, y[3]);
21538     z[5-1] += x[1]*y[3];
21539     z[5-1] += x[0]*y[5-1];
21540 }
21541 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_shortmul) */
21542 
21543 #if !defined(HAVE_native_mpfq_fixmp_4_5_addmul05)
21544 /* x has 4.5 words, z has 5. c is 0.5 word.
21545  * Put (z+x*c) in z. Return carry bit. */
21546 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
21547 static inline
mpfq_fixmp_4_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21548 mp_limb_t mpfq_fixmp_4_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21549 {
21550     mp_limb_t hi, lo, carry, buf;
21551     carry = 0;
21552     mpfq_umul_ppmm(hi,lo,c,x[0]);
21553     lo += carry;
21554     carry = (lo<carry) + hi;
21555     buf = z[0];
21556     lo += buf;
21557     carry += (lo<buf);
21558     z[0] = lo;
21559     mpfq_umul_ppmm(hi,lo,c,x[1]);
21560     lo += carry;
21561     carry = (lo<carry) + hi;
21562     buf = z[1];
21563     lo += buf;
21564     carry += (lo<buf);
21565     z[1] = lo;
21566     mpfq_umul_ppmm(hi,lo,c,x[2]);
21567     lo += carry;
21568     carry = (lo<carry) + hi;
21569     buf = z[2];
21570     lo += buf;
21571     carry += (lo<buf);
21572     z[2] = lo;
21573     mpfq_umul_ppmm(hi,lo,c,x[3]);
21574     lo += carry;
21575     carry = (lo<carry) + hi;
21576     buf = z[3];
21577     lo += buf;
21578     carry += (lo<buf);
21579     z[3] = lo;
21580     lo = c*x[4] + carry;
21581     assert(lo >= carry);
21582     z[4] += lo;
21583     return z[4] < lo;
21584 }
21585 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_addmul05) */
21586 
21587 #if !defined(HAVE_native_mpfq_fixmp_4_5_mul05)
21588 /* x has 4.5 words, z has 5. c is 0.5 word.
21589  * Put (x*c) in z. No carry. */
21590 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
21591 static inline
mpfq_fixmp_4_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)21592 void mpfq_fixmp_4_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
21593 {
21594     mp_limb_t hi, lo, carry;
21595     carry = 0;
21596     mpfq_umul_ppmm(hi,lo,c,x[0]);
21597     lo += carry;
21598     carry = (lo<carry) + hi;
21599     z[0] = lo;
21600     mpfq_umul_ppmm(hi,lo,c,x[1]);
21601     lo += carry;
21602     carry = (lo<carry) + hi;
21603     z[1] = lo;
21604     mpfq_umul_ppmm(hi,lo,c,x[2]);
21605     lo += carry;
21606     carry = (lo<carry) + hi;
21607     z[2] = lo;
21608     mpfq_umul_ppmm(hi,lo,c,x[3]);
21609     lo += carry;
21610     carry = (lo<carry) + hi;
21611     z[3] = lo;
21612     lo = c*x[4] + carry;
21613     assert(lo >= carry);
21614     z[4] = lo;
21615 }
21616 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mul05) */
21617 
21618 #if !defined(HAVE_native_mpfq_fixmp_4_5_mod)
21619 /* x has 9 words. z and p have 4.5 words, and the high word of p is non-zero.
21620  * Put x mod p in z. */
21621 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
21622 /* Triggered by: 4_5_mgy_decode */
21623 static inline
mpfq_fixmp_4_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)21624 void mpfq_fixmp_4_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
21625 {
21626     mp_limb_t q[4+1], r[5];
21627     assert (p[5-1] != 0);
21628     mpn_tdiv_qr(q, r, 0, x, 9, p, 5);
21629     mpfq_copy(z, r, 5);
21630 }
21631 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mod) */
21632 
21633 #if !defined(HAVE_native_mpfq_fixmp_4_5_rshift)
21634 /* a has 4.5 words. Shift it in place by cnt bits to the right.
21635  * The shift count cnt must not exceed the word size.
21636  * Note that no carry is returned for the bits shifted out. */
21637 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
21638 /* Triggered by: 4_5_invmod */
21639 static inline
mpfq_fixmp_4_5_rshift(mp_limb_t * a,int cnt)21640 void mpfq_fixmp_4_5_rshift(mp_limb_t * a, int cnt)
21641 {
21642     if (!cnt) return;
21643     int i;
21644     int dnt = GMP_NUMB_BITS - cnt;
21645     for (i = 0; i < 5-1; ++i) {
21646         a[i] >>= cnt;
21647         a[i] |= (a[i+1] << dnt);
21648     }
21649     a[5-1] >>= cnt;
21650 }
21651 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_rshift) */
21652 
21653 #if !defined(HAVE_native_mpfq_fixmp_4_5_long_rshift)
21654 /* a has 4.5 words. Shift it in place by off words plus cnt bits to the left.
21655  * Note that no carry is returned for the bits shifted out. */
21656 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
21657 /* Triggered by: 4_5_invmod */
21658 static inline
mpfq_fixmp_4_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)21659 void mpfq_fixmp_4_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
21660 {
21661     if (cnt) {
21662         int dnt = GMP_NUMB_BITS - cnt;
21663         for (int i = 0; i < 5 - off - 1; ++i) {
21664             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
21665         }
21666         a[5-off-1] = a[5-1]>>cnt;
21667     } else {
21668         mpfq_copyi(a, a + off, 5 - off);
21669     }
21670     mpfq_zero(a + 5 - off, off);
21671 }
21672 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_long_rshift) */
21673 
21674 #if !defined(HAVE_native_mpfq_fixmp_4_5_long_lshift)
21675 /* a has 4.5 words. Shift it in place by off words plus cnt bits to the left.
21676  * Note that no carry is returned for the bits shifted out. */
21677 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
21678 /* Triggered by: 4_5_invmod */
21679 static inline
mpfq_fixmp_4_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)21680 void mpfq_fixmp_4_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
21681 {
21682     int i;
21683     if (cnt) {
21684         int dnt = GMP_NUMB_BITS - cnt;
21685         for (i = 5-1; i>off; --i) {
21686             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
21687         }
21688         a[off] = a[0]<<cnt;
21689     } else {
21690         mpfq_copyd(a + off, a, 5 - off);
21691     }
21692     mpfq_zero(a, off);
21693 }
21694 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_long_lshift) */
21695 
21696 #if !defined(HAVE_native_mpfq_fixmp_4_5_invmod)
21697 /* x, z, and p have 4.5 words. Put inverse of x mod p in z.
21698  * Return non-zero if an inverse could be found.
21699  * If no inverse could be found, return 0 and set z to zero.
21700  */
21701 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
21702 static inline
mpfq_fixmp_4_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)21703 int mpfq_fixmp_4_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
21704 {
21705       mp_limb_t u[5], v[5], a[5], b[5], fix[5];
21706       int i, t, lsh;
21707 
21708       mpfq_zero(u, 5);
21709       mpfq_zero(v, 5);
21710       mpfq_copy(a, x, 5);
21711       mpfq_copy(b, p, 5);
21712       u[0] = 1UL;
21713 
21714       if (mpfq_fixmp_4_5_cmp(a, v) == 0 || mpfq_fixmp_4_5_cmp(a, b) == 0) {
21715         mpfq_zero(res, 5);
21716         return 0;
21717       }
21718 
21719       mpfq_fixmp_4_5_add(fix, b, u);
21720       mpfq_fixmp_4_5_rshift(fix, 1);
21721 
21722       assert (mpfq_fixmp_4_5_cmp(a,b) < 0);
21723 
21724       t = 0;
21725 
21726       for(i = 0 ; !a[i] ; i++) ;
21727       assert (i < 5);
21728       lsh = mpfq_ctzl(a[i]);
21729       mpfq_fixmp_4_5_long_rshift(a, i, lsh);
21730       t += lsh + i*GMP_NUMB_BITS;
21731       mpfq_fixmp_4_5_long_lshift(v, i, lsh);
21732 
21733       do {
21734         do {
21735           mpfq_fixmp_4_5_sub(b, b, a);
21736           mpfq_fixmp_4_5_add(v, v, u);
21737           for(i = 0 ; !b[i] ; i++) ;
21738           assert (i < 5);
21739           lsh = mpfq_ctzl(b[i]);
21740           mpfq_fixmp_4_5_long_rshift(b, i, lsh);
21741           t += lsh + i*GMP_NUMB_BITS;
21742           mpfq_fixmp_4_5_long_lshift(u, i, lsh);
21743         } while (mpfq_fixmp_4_5_cmp(a,b) < 0);
21744         if (mpfq_fixmp_4_5_cmp(a, b) == 0)
21745           break;
21746         do {
21747           mpfq_fixmp_4_5_sub(a, a, b);
21748           mpfq_fixmp_4_5_add(u, u, v);
21749           for(i = 0 ; !a[i] ; i++) ;
21750           assert (i < 5);
21751           lsh = mpfq_ctzl(a[i]);
21752           mpfq_fixmp_4_5_long_rshift(a, i, lsh);
21753           t += lsh + i*GMP_NUMB_BITS;
21754           mpfq_fixmp_4_5_long_lshift(v, i, lsh);
21755         } while (mpfq_fixmp_4_5_cmp(b,a)<0);
21756       } while (mpfq_fixmp_4_5_cmp(a,b) != 0);
21757       {
21758         if (mpfq_fixmp_4_5_cmp_ui(a, 1) != 0) {
21759           mpfq_copy(res, a, 5);
21760           return 0;
21761         }
21762       }
21763       while (t>0) {
21764         mp_limb_t sig = u[0] & 1UL;
21765         mpfq_fixmp_4_5_rshift(u, 1);
21766         if (sig)
21767           mpfq_fixmp_4_5_add(u, u, fix);
21768         --t;
21769       }
21770       mpfq_copy(res, u, 5);
21771       return 1;
21772 }
21773 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_invmod) */
21774 
21775 #if !defined(HAVE_native_mpfq_fixmp_4_5_redc)
21776 /* x has 9 words, z and p have 4.5 words.
21777  * only one word is read from invp.
21778  * Assuming R=W^5 is the redc modulus, we expect that x verifies:
21779  *   x < R*p,
21780  * so that we have eventually z < p, z congruent to x/R mod p.
21781  * The contents of the area pointed by x are clobbered by this call.
21782  * Note also that x may alias z.
21783  */
21784 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
21785 static inline
mpfq_fixmp_4_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)21786 void mpfq_fixmp_4_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
21787 {
21788     mp_limb_t cy;
21789     for(int i = 0; i < 5; ++i) {
21790         mp_limb_t t = x[i]*mip[0];
21791         cy = mpfq_fixmp_4_5_addmul1_shortz(x+i, p, t);
21792         assert (x[i] == 0);
21793         x[i] = cy;
21794     }
21795     {
21796         mp_limb_t ret[5] = { x[5], x[6], x[7], x[8], 0 };
21797         cy = mpfq_fixmp_4_5_add(x, x, ret);
21798     }
21799     /* At this point, we have (x' denotes x + cy*W^n here)
21800     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
21801     * x'/R < p + p
21802     */
21803     if (cy || mpfq_fixmp_4_5_cmp(x, p) >= 0) {
21804         mpfq_fixmp_4_5_sub(z, x, p);
21805     } else {
21806         mpfq_copy(z, x, 5);
21807     }
21808 }
21809 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_redc) */
21810 
21811 #if !defined(HAVE_native_mpfq_fixmp_4_5_redc_ur)
21812 /* x has 10 words, z and p have 4.5 words.
21813  * only one word is read from invp.
21814  * Assuming R=W^5 is the redc modulus, we expect that x verifies:
21815  *  x < W*W^4.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
21816  * so that we have eventually z < p, z congruent to x/R mod p.
21817  * The contents of the area pointed by x are clobbered by this call.
21818  * Note also that x may alias z.
21819  */
21820 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
21821 static inline
mpfq_fixmp_4_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)21822 void mpfq_fixmp_4_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
21823 {
21824     mp_limb_t cy, q[1];
21825     for(int i = 0; i < 5; ++i) {
21826         mp_limb_t t = x[i]*mip[0];
21827         cy = mpfq_fixmp_4_5_addmul1_shortz(x+i, p, t);
21828         assert (x[i] == 0);
21829         x[i] = cy;
21830     }
21831     cy = mpfq_fixmp_4_5_add(x + 5, x, x + 5);
21832     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
21833     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
21834     * x'/R < (W^0.5+1)*p
21835     */
21836     if (cy) {
21837         /* x'/R-p < W^0.5*p, which fits in n words. */
21838         mpfq_fixmp_4_5_sub(x + 5, x + 5, p);
21839     }
21840     mpn_tdiv_qr(q, z, 0, x + 5, 5, p, 5);
21841 }
21842 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_redc_ur) */
21843 
21844 #if !defined(HAVE_native_mpfq_fixmp_4_5_mgy_encode)
21845 /* x, z, and p have 4.5 words.
21846  * Assuming R=W^5 is the redc modulus, we compute z=R*x mod p. */
21847 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
21848 static inline
mpfq_fixmp_4_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)21849 void mpfq_fixmp_4_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
21850 {
21851     mp_limb_t t[10] = { 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4] };
21852     mp_limb_t qq[5+1];
21853     mpn_tdiv_qr(qq, z, 0, t, 10, p, 5);
21854 }
21855 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mgy_encode) */
21856 
21857 #if !defined(HAVE_native_mpfq_fixmp_4_5_mgy_decode)
21858 /* x, z, invR, and p have 4.5 words.
21859  * Assuming R=W^5 is the redc modulus, we compute z=x/R mod p. */
21860 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
21861 static inline
mpfq_fixmp_4_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)21862 void mpfq_fixmp_4_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
21863 {
21864     mp_limb_t t[10];
21865     mpfq_fixmp_4_5_mul(t, x, invR);
21866     mpfq_fixmp_4_5_mod(z, t, p);
21867 }
21868 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_mgy_decode) */
21869 
21870 #if !defined(HAVE_native_mpfq_fixmp_4_5_lshift)
21871 /* a has 4.5 words. Shift it in place by cnt bits to the left.
21872  * The shift count cnt must not exceed the word size.
21873  * Note that no carry is returned for the bits shifted out. */
21874 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
21875 static inline
mpfq_fixmp_4_5_lshift(mp_limb_t * a,int cnt)21876 void mpfq_fixmp_4_5_lshift(mp_limb_t * a, int cnt)
21877 {
21878     if (!cnt) return;
21879     int i;
21880     int dnt = GMP_NUMB_BITS - cnt;
21881     for (i = 5-1; i>0; --i) {
21882         a[i] <<= cnt;
21883         a[i] |= (a[i-1] >> dnt);
21884     }
21885     a[0] <<= cnt;
21886 }
21887 #endif /* !defined(HAVE_native_mpfq_fixmp_4_5_lshift) */
21888 
21889 #if !defined(HAVE_native_mpfq_fixmp_5_5_add)
21890 /* x, y, and z have 5.5 words. Result in z. Return carry bit */
21891 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
21892 /* Triggered by: 5_5_invmod, 5_5_redc, 5_5_redc_ur */
21893 static inline
mpfq_fixmp_5_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21894 mp_limb_t mpfq_fixmp_5_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21895 {
21896     mp_limb_t r, s, t, cy, cy1, cy2;
21897     cy = 0;
21898     r = x[0];
21899     s = r + y[0];
21900     cy1 = s < r;
21901     t = s + cy;
21902     cy2 = t < s;
21903     cy = cy1 | cy2;
21904     z[0] = t;
21905     r = x[1];
21906     s = r + y[1];
21907     cy1 = s < r;
21908     t = s + cy;
21909     cy2 = t < s;
21910     cy = cy1 | cy2;
21911     z[1] = t;
21912     r = x[2];
21913     s = r + y[2];
21914     cy1 = s < r;
21915     t = s + cy;
21916     cy2 = t < s;
21917     cy = cy1 | cy2;
21918     z[2] = t;
21919     r = x[3];
21920     s = r + y[3];
21921     cy1 = s < r;
21922     t = s + cy;
21923     cy2 = t < s;
21924     cy = cy1 | cy2;
21925     z[3] = t;
21926     r = x[4];
21927     s = r + y[4];
21928     cy1 = s < r;
21929     t = s + cy;
21930     cy2 = t < s;
21931     cy = cy1 | cy2;
21932     z[4] = t;
21933     r = x[5];
21934     s = r + y[5];
21935     cy1 = s < r;
21936     t = s + cy;
21937     cy2 = t < s;
21938     cy = cy1 | cy2;
21939     z[5] = t;
21940     return cy;
21941 }
21942 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_add) */
21943 
21944 #if !defined(HAVE_native_mpfq_fixmp_5_5_sub)
21945 /* x, y, and z have 5.5 words. Result in z. Return borrow bit */
21946 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
21947 /* Triggered by: 5_5_invmod, 5_5_redc, 5_5_redc_ur */
21948 static inline
mpfq_fixmp_5_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)21949 mp_limb_t mpfq_fixmp_5_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
21950 {
21951     mp_limb_t r, s, t, cy, cy1, cy2;
21952     cy = 0;
21953     r = x[0];
21954     s = r - y[0];
21955     cy1 = s > r;
21956     t = s - cy;
21957     cy2 = t > s;
21958     cy = cy1 | cy2;
21959     z[0] = t;
21960     r = x[1];
21961     s = r - y[1];
21962     cy1 = s > r;
21963     t = s - cy;
21964     cy2 = t > s;
21965     cy = cy1 | cy2;
21966     z[1] = t;
21967     r = x[2];
21968     s = r - y[2];
21969     cy1 = s > r;
21970     t = s - cy;
21971     cy2 = t > s;
21972     cy = cy1 | cy2;
21973     z[2] = t;
21974     r = x[3];
21975     s = r - y[3];
21976     cy1 = s > r;
21977     t = s - cy;
21978     cy2 = t > s;
21979     cy = cy1 | cy2;
21980     z[3] = t;
21981     r = x[4];
21982     s = r - y[4];
21983     cy1 = s > r;
21984     t = s - cy;
21985     cy2 = t > s;
21986     cy = cy1 | cy2;
21987     z[4] = t;
21988     r = x[5];
21989     s = r - y[5];
21990     cy1 = s > r;
21991     t = s - cy;
21992     cy2 = t > s;
21993     cy = cy1 | cy2;
21994     z[5] = t;
21995     return cy;
21996 }
21997 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_sub) */
21998 
21999 #if !defined(HAVE_native_mpfq_fixmp_5_5_add_nc)
22000 /* x, y, and z have 5.5 words. Result in z. Carry bit is lost. */
22001 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
22002 static inline
mpfq_fixmp_5_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)22003 void mpfq_fixmp_5_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
22004 {
22005     mp_limb_t r, s, t, cy, cy1, cy2;
22006     cy = 0;
22007     r = x[0];
22008     s = r + y[0];
22009     cy1 = s < r;
22010     t = s + cy;
22011     cy2 = t < s;
22012     cy = cy1 | cy2;
22013     z[0] = t;
22014     r = x[1];
22015     s = r + y[1];
22016     cy1 = s < r;
22017     t = s + cy;
22018     cy2 = t < s;
22019     cy = cy1 | cy2;
22020     z[1] = t;
22021     r = x[2];
22022     s = r + y[2];
22023     cy1 = s < r;
22024     t = s + cy;
22025     cy2 = t < s;
22026     cy = cy1 | cy2;
22027     z[2] = t;
22028     r = x[3];
22029     s = r + y[3];
22030     cy1 = s < r;
22031     t = s + cy;
22032     cy2 = t < s;
22033     cy = cy1 | cy2;
22034     z[3] = t;
22035     r = x[4];
22036     s = r + y[4];
22037     cy1 = s < r;
22038     t = s + cy;
22039     cy2 = t < s;
22040     cy = cy1 | cy2;
22041     z[4] = t;
22042     r = x[5];
22043     s = r + y[5];
22044     cy1 = s < r;
22045     t = s + cy;
22046     cy2 = t < s;
22047     cy = cy1 | cy2;
22048     z[5] = t;
22049 }
22050 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_add_nc) */
22051 
22052 #if !defined(HAVE_native_mpfq_fixmp_5_5_sub_nc)
22053 /* x, y, and z have 5.5 words. Result in z. Borrow bit is lost. */
22054 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
22055 static inline
mpfq_fixmp_5_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)22056 void mpfq_fixmp_5_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
22057 {
22058     mp_limb_t r, s, t, cy, cy1, cy2;
22059     cy = 0;
22060     r = x[0];
22061     s = r - y[0];
22062     cy1 = s > r;
22063     t = s - cy;
22064     cy2 = t > s;
22065     cy = cy1 | cy2;
22066     z[0] = t;
22067     r = x[1];
22068     s = r - y[1];
22069     cy1 = s > r;
22070     t = s - cy;
22071     cy2 = t > s;
22072     cy = cy1 | cy2;
22073     z[1] = t;
22074     r = x[2];
22075     s = r - y[2];
22076     cy1 = s > r;
22077     t = s - cy;
22078     cy2 = t > s;
22079     cy = cy1 | cy2;
22080     z[2] = t;
22081     r = x[3];
22082     s = r - y[3];
22083     cy1 = s > r;
22084     t = s - cy;
22085     cy2 = t > s;
22086     cy = cy1 | cy2;
22087     z[3] = t;
22088     r = x[4];
22089     s = r - y[4];
22090     cy1 = s > r;
22091     t = s - cy;
22092     cy2 = t > s;
22093     cy = cy1 | cy2;
22094     z[4] = t;
22095     r = x[5];
22096     s = r - y[5];
22097     cy1 = s > r;
22098     t = s - cy;
22099     cy2 = t > s;
22100     cy = cy1 | cy2;
22101     z[5] = t;
22102 }
22103 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_sub_nc) */
22104 
22105 #if !defined(HAVE_native_mpfq_fixmp_5_5_add_ui)
22106 /* x, y, and z have 5.5 words. Result in z. Return carry bit */
22107 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
22108 static inline
mpfq_fixmp_5_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)22109 mp_limb_t mpfq_fixmp_5_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
22110 {
22111     mp_limb_t r, s, t, cy, cy1, cy2;
22112     cy = 0;
22113     r = x[0];
22114     s = r + y;
22115     cy1 = s < r;
22116     t = s + cy;
22117     cy2 = t < s;
22118     cy = cy1 | cy2;
22119     z[0] = t;
22120     s = x[1];
22121     t = s + cy;
22122     cy = t < s;
22123     z[1] = t;
22124     s = x[2];
22125     t = s + cy;
22126     cy = t < s;
22127     z[2] = t;
22128     s = x[3];
22129     t = s + cy;
22130     cy = t < s;
22131     z[3] = t;
22132     s = x[4];
22133     t = s + cy;
22134     cy = t < s;
22135     z[4] = t;
22136     s = x[5];
22137     t = s + cy;
22138     cy = t < s;
22139     z[5] = t;
22140     return cy;
22141 }
22142 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_add_ui) */
22143 
22144 #if !defined(HAVE_native_mpfq_fixmp_5_5_sub_ui)
22145 /* x, y, and z have 5.5 words. Result in z. Return borrow bit */
22146 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
22147 static inline
mpfq_fixmp_5_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)22148 mp_limb_t mpfq_fixmp_5_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
22149 {
22150     mp_limb_t r, s, t, cy, cy1, cy2;
22151     cy = 0;
22152     r = x[0];
22153     s = r - y;
22154     cy1 = s > r;
22155     t = s - cy;
22156     cy2 = t > s;
22157     cy = cy1 | cy2;
22158     z[0] = t;
22159     s = x[1];
22160     t = s - cy;
22161     cy = t > s;
22162     z[1] = t;
22163     s = x[2];
22164     t = s - cy;
22165     cy = t > s;
22166     z[2] = t;
22167     s = x[3];
22168     t = s - cy;
22169     cy = t > s;
22170     z[3] = t;
22171     s = x[4];
22172     t = s - cy;
22173     cy = t > s;
22174     z[4] = t;
22175     s = x[5];
22176     t = s - cy;
22177     cy = t > s;
22178     z[5] = t;
22179     return cy;
22180 }
22181 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_sub_ui) */
22182 
22183 #if !defined(HAVE_native_mpfq_fixmp_5_5_add_ui_nc)
22184 /* x, y, and z have 5.5 words. Result in z. Carry bit is lost. */
22185 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
22186 static inline
mpfq_fixmp_5_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)22187 void mpfq_fixmp_5_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
22188 {
22189     mp_limb_t r, s, t, cy, cy1, cy2;
22190     cy = 0;
22191     r = x[0];
22192     s = r + y;
22193     cy1 = s < r;
22194     t = s + cy;
22195     cy2 = t < s;
22196     cy = cy1 | cy2;
22197     z[0] = t;
22198     s = x[1];
22199     t = s + cy;
22200     cy = t < s;
22201     z[1] = t;
22202     s = x[2];
22203     t = s + cy;
22204     cy = t < s;
22205     z[2] = t;
22206     s = x[3];
22207     t = s + cy;
22208     cy = t < s;
22209     z[3] = t;
22210     s = x[4];
22211     t = s + cy;
22212     cy = t < s;
22213     z[4] = t;
22214     s = x[5];
22215     t = s + cy;
22216     cy = t < s;
22217     z[5] = t;
22218 }
22219 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_add_ui_nc) */
22220 
22221 #if !defined(HAVE_native_mpfq_fixmp_5_5_sub_ui_nc)
22222 /* x, y, and z have 5.5 words. Result in z. Borrow bit is lost. */
22223 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
22224 static inline
mpfq_fixmp_5_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)22225 void mpfq_fixmp_5_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
22226 {
22227     mp_limb_t r, s, t, cy, cy1, cy2;
22228     cy = 0;
22229     r = x[0];
22230     s = r - y;
22231     cy1 = s > r;
22232     t = s - cy;
22233     cy2 = t > s;
22234     cy = cy1 | cy2;
22235     z[0] = t;
22236     s = x[1];
22237     t = s - cy;
22238     cy = t > s;
22239     z[1] = t;
22240     s = x[2];
22241     t = s - cy;
22242     cy = t > s;
22243     z[2] = t;
22244     s = x[3];
22245     t = s - cy;
22246     cy = t > s;
22247     z[3] = t;
22248     s = x[4];
22249     t = s - cy;
22250     cy = t > s;
22251     z[4] = t;
22252     s = x[5];
22253     t = s - cy;
22254     cy = t > s;
22255     z[5] = t;
22256 }
22257 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_sub_ui_nc) */
22258 
22259 #if !defined(HAVE_native_mpfq_fixmp_5_5_cmp)
22260 /* x and y have 5.5 words. Return sign of difference x-y. */
22261 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
22262 /* Triggered by: 5_5_invmod, 5_5_redc, 5_5_redc_ur */
22263 static inline
mpfq_fixmp_5_5_cmp(const mp_limb_t * x,const mp_limb_t * y)22264 int mpfq_fixmp_5_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
22265 {
22266     for (int i = 6-1; i >= 0; --i) {
22267         if (x[i] > y[i]) return 1;
22268         if (x[i] < y[i]) return -1;
22269     }
22270     return 0;
22271 }
22272 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_cmp) */
22273 
22274 #if !defined(HAVE_native_mpfq_fixmp_5_5_cmp_ui)
22275 /* x has 5.5 words. Return sign of difference x-y. */
22276 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
22277 /* Triggered by: 5_5_invmod */
22278 static inline
mpfq_fixmp_5_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)22279 int mpfq_fixmp_5_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
22280 {
22281     for (int i = 6-1; i > 0; --i) {
22282         if (x[i]) return 1;
22283     }
22284     if (x[0]>y) return 1;
22285     if (x[0]<y) return -1;
22286     return 0;
22287 }
22288 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_cmp_ui) */
22289 
22290 #if !defined(HAVE_native_mpfq_fixmp_5_5_addmul1)
22291 /* x has 5.5 words, z has 7.
22292  * Put (z+x*c) in z. Return carry bit. */
22293 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
22294 static inline
mpfq_fixmp_5_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22295 mp_limb_t mpfq_fixmp_5_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22296 {
22297     mp_limb_t hi, lo, carry, buf;
22298     carry = 0;
22299     mpfq_umul_ppmm(hi,lo,c,x[0]);
22300     lo += carry;
22301     carry = (lo<carry) + hi;
22302     buf = z[0];
22303     lo += buf;
22304     carry += (lo<buf);
22305     z[0] = lo;
22306     mpfq_umul_ppmm(hi,lo,c,x[1]);
22307     lo += carry;
22308     carry = (lo<carry) + hi;
22309     buf = z[1];
22310     lo += buf;
22311     carry += (lo<buf);
22312     z[1] = lo;
22313     mpfq_umul_ppmm(hi,lo,c,x[2]);
22314     lo += carry;
22315     carry = (lo<carry) + hi;
22316     buf = z[2];
22317     lo += buf;
22318     carry += (lo<buf);
22319     z[2] = lo;
22320     mpfq_umul_ppmm(hi,lo,c,x[3]);
22321     lo += carry;
22322     carry = (lo<carry) + hi;
22323     buf = z[3];
22324     lo += buf;
22325     carry += (lo<buf);
22326     z[3] = lo;
22327     mpfq_umul_ppmm(hi,lo,c,x[4]);
22328     lo += carry;
22329     carry = (lo<carry) + hi;
22330     buf = z[4];
22331     lo += buf;
22332     carry += (lo<buf);
22333     z[4] = lo;
22334     mpfq_umul_ppmm(hi,lo,c,x[5]);
22335     lo += carry;
22336     carry = (lo<carry) + hi;
22337     buf = z[5];
22338     lo += buf;
22339     carry += (lo<buf);
22340     z[5] = lo;
22341     z[6] += carry;
22342     return (z[6]<carry);
22343 }
22344 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_addmul1) */
22345 
22346 #if !defined(HAVE_native_mpfq_fixmp_5_5_addmul1_nc)
22347 /* x has 5.5 words, z has 7.
22348  * Put (z+x*c) in z. Carry bit is lost. */
22349 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
22350 /* Triggered by: 5_5_mul, 5_5_mgy_decode */
22351 static inline
mpfq_fixmp_5_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22352 void mpfq_fixmp_5_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22353 {
22354     mp_limb_t hi, lo, carry, buf;
22355     carry = 0;
22356     mpfq_umul_ppmm(hi,lo,c,x[0]);
22357     lo += carry;
22358     carry = (lo<carry) + hi;
22359     buf = z[0];
22360     lo += buf;
22361     carry += (lo<buf);
22362     z[0] = lo;
22363     mpfq_umul_ppmm(hi,lo,c,x[1]);
22364     lo += carry;
22365     carry = (lo<carry) + hi;
22366     buf = z[1];
22367     lo += buf;
22368     carry += (lo<buf);
22369     z[1] = lo;
22370     mpfq_umul_ppmm(hi,lo,c,x[2]);
22371     lo += carry;
22372     carry = (lo<carry) + hi;
22373     buf = z[2];
22374     lo += buf;
22375     carry += (lo<buf);
22376     z[2] = lo;
22377     mpfq_umul_ppmm(hi,lo,c,x[3]);
22378     lo += carry;
22379     carry = (lo<carry) + hi;
22380     buf = z[3];
22381     lo += buf;
22382     carry += (lo<buf);
22383     z[3] = lo;
22384     mpfq_umul_ppmm(hi,lo,c,x[4]);
22385     lo += carry;
22386     carry = (lo<carry) + hi;
22387     buf = z[4];
22388     lo += buf;
22389     carry += (lo<buf);
22390     z[4] = lo;
22391     mpfq_umul_ppmm(hi,lo,c,x[5]);
22392     lo += carry;
22393     carry = (lo<carry) + hi;
22394     buf = z[5];
22395     lo += buf;
22396     carry += (lo<buf);
22397     z[5] = lo;
22398     z[6] += carry;
22399 }
22400 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_addmul1_nc) */
22401 
22402 #if !defined(HAVE_native_mpfq_fixmp_5_5_addmul1_shortz)
22403 /* x has 5.5 words, z has 6.
22404  * Put (z+x*c) in z. Return carry word. */
22405 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
22406 /* Triggered by: 5_5_redc, 5_5_redc_ur */
22407 static inline
mpfq_fixmp_5_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22408 mp_limb_t mpfq_fixmp_5_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22409 {
22410     mp_limb_t hi, lo, carry, buf;
22411     carry = 0;
22412     mpfq_umul_ppmm(hi,lo,c,x[0]);
22413     lo += carry;
22414     carry = (lo<carry) + hi;
22415     buf = z[0];
22416     lo += buf;
22417     carry += (lo<buf);
22418     z[0] = lo;
22419     mpfq_umul_ppmm(hi,lo,c,x[1]);
22420     lo += carry;
22421     carry = (lo<carry) + hi;
22422     buf = z[1];
22423     lo += buf;
22424     carry += (lo<buf);
22425     z[1] = lo;
22426     mpfq_umul_ppmm(hi,lo,c,x[2]);
22427     lo += carry;
22428     carry = (lo<carry) + hi;
22429     buf = z[2];
22430     lo += buf;
22431     carry += (lo<buf);
22432     z[2] = lo;
22433     mpfq_umul_ppmm(hi,lo,c,x[3]);
22434     lo += carry;
22435     carry = (lo<carry) + hi;
22436     buf = z[3];
22437     lo += buf;
22438     carry += (lo<buf);
22439     z[3] = lo;
22440     mpfq_umul_ppmm(hi,lo,c,x[4]);
22441     lo += carry;
22442     carry = (lo<carry) + hi;
22443     buf = z[4];
22444     lo += buf;
22445     carry += (lo<buf);
22446     z[4] = lo;
22447     mpfq_umul_ppmm(hi,lo,c,x[5]);
22448     lo += carry;
22449     carry = (lo<carry) + hi;
22450     buf = z[5];
22451     lo += buf;
22452     carry += (lo<buf);
22453     z[5] = lo;
22454     return carry;
22455 }
22456 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_addmul1_shortz) */
22457 
22458 #if !defined(HAVE_native_mpfq_fixmp_5_5_addmul05_nc)
22459 /* x has 5.5 words, z has 6. c is 0.5 word.
22460  * Put (z+x*c) in z. Carry bit is lost. */
22461 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
22462 /* Triggered by: 5_5_mul, 5_5_mgy_decode */
22463 static inline
mpfq_fixmp_5_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22464 void mpfq_fixmp_5_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22465 {
22466     mp_limb_t hi, lo, carry, buf;
22467     carry = 0;
22468     mpfq_umul_ppmm(hi,lo,c,x[0]);
22469     lo += carry;
22470     carry = (lo<carry) + hi;
22471     buf = z[0];
22472     lo += buf;
22473     carry += (lo<buf);
22474     z[0] = lo;
22475     mpfq_umul_ppmm(hi,lo,c,x[1]);
22476     lo += carry;
22477     carry = (lo<carry) + hi;
22478     buf = z[1];
22479     lo += buf;
22480     carry += (lo<buf);
22481     z[1] = lo;
22482     mpfq_umul_ppmm(hi,lo,c,x[2]);
22483     lo += carry;
22484     carry = (lo<carry) + hi;
22485     buf = z[2];
22486     lo += buf;
22487     carry += (lo<buf);
22488     z[2] = lo;
22489     mpfq_umul_ppmm(hi,lo,c,x[3]);
22490     lo += carry;
22491     carry = (lo<carry) + hi;
22492     buf = z[3];
22493     lo += buf;
22494     carry += (lo<buf);
22495     z[3] = lo;
22496     mpfq_umul_ppmm(hi,lo,c,x[4]);
22497     lo += carry;
22498     carry = (lo<carry) + hi;
22499     buf = z[4];
22500     lo += buf;
22501     carry += (lo<buf);
22502     z[4] = lo;
22503     lo = c*x[5] + carry;
22504     assert(lo >= carry);
22505     z[5] += lo;
22506 }
22507 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_addmul05_nc) */
22508 
22509 #if !defined(HAVE_native_mpfq_fixmp_5_5_mul)
22510 /* x and y have 5.5 words, z has 11. Put x*y in z. */
22511 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
22512 /* Triggered by: 5_5_mgy_decode */
22513 static inline
mpfq_fixmp_5_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)22514 void mpfq_fixmp_5_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
22515 {
22516     assert(z != x && z != y);
22517     for (int i = 0; i < 11; z[i++] = 0) ;
22518     mpfq_fixmp_5_5_addmul1_nc (z + 0, x, y[0]);
22519     mpfq_fixmp_5_5_addmul1_nc (z + 1, x, y[1]);
22520     mpfq_fixmp_5_5_addmul1_nc (z + 2, x, y[2]);
22521     mpfq_fixmp_5_5_addmul1_nc (z + 3, x, y[3]);
22522     mpfq_fixmp_5_5_addmul1_nc (z + 4, x, y[4]);
22523     mpfq_fixmp_5_5_addmul05_nc (z + 5, x, y[5]);
22524 }
22525 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mul) */
22526 
22527 #if !defined(HAVE_native_mpfq_fixmp_5_5_sqr)
22528 /* x has 5.5 words, z has 11. Put x*y in z. */
22529 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
22530 static inline
mpfq_fixmp_5_5_sqr(mp_limb_t * z,const mp_limb_t * x)22531 void mpfq_fixmp_5_5_sqr(mp_limb_t * z, const mp_limb_t * x)
22532 {
22533     mp_limb_t buf[11] = {0,};
22534     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
22535     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
22536     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
22537     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
22538     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
22539     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
22540     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
22541     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
22542     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
22543     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
22544     z[2*5] = x[5] * x[5];
22545     mpn_lshift(buf, buf, 11, 1);
22546     mpn_add_n(z, z, buf, 11);
22547 }
22548 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_sqr) */
22549 
22550 #if !defined(HAVE_native_mpfq_fixmp_5_5_mul1)
22551 /* x has 5.5 words, z has 7. Put x*y in z. */
22552 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
22553 static inline
mpfq_fixmp_5_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22554 void mpfq_fixmp_5_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22555 {
22556     mp_limb_t hi, lo, carry;
22557     carry = 0;
22558     mpfq_umul_ppmm(hi,lo,c,x[0]);
22559     lo += carry;
22560     carry = (lo<carry) + hi;
22561     z[0] = lo;
22562     mpfq_umul_ppmm(hi,lo,c,x[1]);
22563     lo += carry;
22564     carry = (lo<carry) + hi;
22565     z[1] = lo;
22566     mpfq_umul_ppmm(hi,lo,c,x[2]);
22567     lo += carry;
22568     carry = (lo<carry) + hi;
22569     z[2] = lo;
22570     mpfq_umul_ppmm(hi,lo,c,x[3]);
22571     lo += carry;
22572     carry = (lo<carry) + hi;
22573     z[3] = lo;
22574     mpfq_umul_ppmm(hi,lo,c,x[4]);
22575     lo += carry;
22576     carry = (lo<carry) + hi;
22577     z[4] = lo;
22578     mpfq_umul_ppmm(hi,lo,c,x[5]);
22579     lo += carry;
22580     carry = (lo<carry) + hi;
22581     z[5] = lo;
22582     z[6] = carry;
22583 }
22584 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mul1) */
22585 
22586 #if !defined(HAVE_native_mpfq_fixmp_5_5_shortmul)
22587 /* x and y have 5.5 words, z has 6.
22588  * Put the low 6 words of x*y in z. */
22589 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
22590 static inline
mpfq_fixmp_5_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)22591 void mpfq_fixmp_5_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
22592 {
22593     mpfq_zero(z, 6);
22594     mpfq_fixmp_5_addmul1_nc (z+0, x, y[0]);
22595     z[6-1] += x[5]*y[0];
22596     mpfq_fixmp_4_addmul1_nc (z+1, x, y[1]);
22597     z[6-1] += x[4]*y[1];
22598     mpfq_fixmp_3_addmul1_nc (z+2, x, y[2]);
22599     z[6-1] += x[3]*y[2];
22600     mpfq_fixmp_2_addmul1_nc (z+3, x, y[3]);
22601     z[6-1] += x[2]*y[3];
22602     mpfq_fixmp_1_addmul1_nc (z+4, x, y[4]);
22603     z[6-1] += x[1]*y[4];
22604     z[6-1] += x[0]*y[6-1];
22605 }
22606 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_shortmul) */
22607 
22608 #if !defined(HAVE_native_mpfq_fixmp_5_5_addmul05)
22609 /* x has 5.5 words, z has 6. c is 0.5 word.
22610  * Put (z+x*c) in z. Return carry bit. */
22611 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
22612 static inline
mpfq_fixmp_5_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22613 mp_limb_t mpfq_fixmp_5_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22614 {
22615     mp_limb_t hi, lo, carry, buf;
22616     carry = 0;
22617     mpfq_umul_ppmm(hi,lo,c,x[0]);
22618     lo += carry;
22619     carry = (lo<carry) + hi;
22620     buf = z[0];
22621     lo += buf;
22622     carry += (lo<buf);
22623     z[0] = lo;
22624     mpfq_umul_ppmm(hi,lo,c,x[1]);
22625     lo += carry;
22626     carry = (lo<carry) + hi;
22627     buf = z[1];
22628     lo += buf;
22629     carry += (lo<buf);
22630     z[1] = lo;
22631     mpfq_umul_ppmm(hi,lo,c,x[2]);
22632     lo += carry;
22633     carry = (lo<carry) + hi;
22634     buf = z[2];
22635     lo += buf;
22636     carry += (lo<buf);
22637     z[2] = lo;
22638     mpfq_umul_ppmm(hi,lo,c,x[3]);
22639     lo += carry;
22640     carry = (lo<carry) + hi;
22641     buf = z[3];
22642     lo += buf;
22643     carry += (lo<buf);
22644     z[3] = lo;
22645     mpfq_umul_ppmm(hi,lo,c,x[4]);
22646     lo += carry;
22647     carry = (lo<carry) + hi;
22648     buf = z[4];
22649     lo += buf;
22650     carry += (lo<buf);
22651     z[4] = lo;
22652     lo = c*x[5] + carry;
22653     assert(lo >= carry);
22654     z[5] += lo;
22655     return z[5] < lo;
22656 }
22657 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_addmul05) */
22658 
22659 #if !defined(HAVE_native_mpfq_fixmp_5_5_mul05)
22660 /* x has 5.5 words, z has 6. c is 0.5 word.
22661  * Put (x*c) in z. No carry. */
22662 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
22663 static inline
mpfq_fixmp_5_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)22664 void mpfq_fixmp_5_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
22665 {
22666     mp_limb_t hi, lo, carry;
22667     carry = 0;
22668     mpfq_umul_ppmm(hi,lo,c,x[0]);
22669     lo += carry;
22670     carry = (lo<carry) + hi;
22671     z[0] = lo;
22672     mpfq_umul_ppmm(hi,lo,c,x[1]);
22673     lo += carry;
22674     carry = (lo<carry) + hi;
22675     z[1] = lo;
22676     mpfq_umul_ppmm(hi,lo,c,x[2]);
22677     lo += carry;
22678     carry = (lo<carry) + hi;
22679     z[2] = lo;
22680     mpfq_umul_ppmm(hi,lo,c,x[3]);
22681     lo += carry;
22682     carry = (lo<carry) + hi;
22683     z[3] = lo;
22684     mpfq_umul_ppmm(hi,lo,c,x[4]);
22685     lo += carry;
22686     carry = (lo<carry) + hi;
22687     z[4] = lo;
22688     lo = c*x[5] + carry;
22689     assert(lo >= carry);
22690     z[5] = lo;
22691 }
22692 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mul05) */
22693 
22694 #if !defined(HAVE_native_mpfq_fixmp_5_5_mod)
22695 /* x has 11 words. z and p have 5.5 words, and the high word of p is non-zero.
22696  * Put x mod p in z. */
22697 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
22698 /* Triggered by: 5_5_mgy_decode */
22699 static inline
mpfq_fixmp_5_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)22700 void mpfq_fixmp_5_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
22701 {
22702     mp_limb_t q[5+1], r[6];
22703     assert (p[6-1] != 0);
22704     mpn_tdiv_qr(q, r, 0, x, 11, p, 6);
22705     mpfq_copy(z, r, 6);
22706 }
22707 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mod) */
22708 
22709 #if !defined(HAVE_native_mpfq_fixmp_5_5_rshift)
22710 /* a has 5.5 words. Shift it in place by cnt bits to the right.
22711  * The shift count cnt must not exceed the word size.
22712  * Note that no carry is returned for the bits shifted out. */
22713 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
22714 /* Triggered by: 5_5_invmod */
22715 static inline
mpfq_fixmp_5_5_rshift(mp_limb_t * a,int cnt)22716 void mpfq_fixmp_5_5_rshift(mp_limb_t * a, int cnt)
22717 {
22718     if (!cnt) return;
22719     int i;
22720     int dnt = GMP_NUMB_BITS - cnt;
22721     for (i = 0; i < 6-1; ++i) {
22722         a[i] >>= cnt;
22723         a[i] |= (a[i+1] << dnt);
22724     }
22725     a[6-1] >>= cnt;
22726 }
22727 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_rshift) */
22728 
22729 #if !defined(HAVE_native_mpfq_fixmp_5_5_long_rshift)
22730 /* a has 5.5 words. Shift it in place by off words plus cnt bits to the left.
22731  * Note that no carry is returned for the bits shifted out. */
22732 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
22733 /* Triggered by: 5_5_invmod */
22734 static inline
mpfq_fixmp_5_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)22735 void mpfq_fixmp_5_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
22736 {
22737     if (cnt) {
22738         int dnt = GMP_NUMB_BITS - cnt;
22739         for (int i = 0; i < 6 - off - 1; ++i) {
22740             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
22741         }
22742         a[6-off-1] = a[6-1]>>cnt;
22743     } else {
22744         mpfq_copyi(a, a + off, 6 - off);
22745     }
22746     mpfq_zero(a + 6 - off, off);
22747 }
22748 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_long_rshift) */
22749 
22750 #if !defined(HAVE_native_mpfq_fixmp_5_5_long_lshift)
22751 /* a has 5.5 words. Shift it in place by off words plus cnt bits to the left.
22752  * Note that no carry is returned for the bits shifted out. */
22753 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
22754 /* Triggered by: 5_5_invmod */
22755 static inline
mpfq_fixmp_5_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)22756 void mpfq_fixmp_5_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
22757 {
22758     int i;
22759     if (cnt) {
22760         int dnt = GMP_NUMB_BITS - cnt;
22761         for (i = 6-1; i>off; --i) {
22762             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
22763         }
22764         a[off] = a[0]<<cnt;
22765     } else {
22766         mpfq_copyd(a + off, a, 6 - off);
22767     }
22768     mpfq_zero(a, off);
22769 }
22770 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_long_lshift) */
22771 
22772 #if !defined(HAVE_native_mpfq_fixmp_5_5_invmod)
22773 /* x, z, and p have 5.5 words. Put inverse of x mod p in z.
22774  * Return non-zero if an inverse could be found.
22775  * If no inverse could be found, return 0 and set z to zero.
22776  */
22777 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
22778 static inline
mpfq_fixmp_5_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)22779 int mpfq_fixmp_5_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
22780 {
22781       mp_limb_t u[6], v[6], a[6], b[6], fix[6];
22782       int i, t, lsh;
22783 
22784       mpfq_zero(u, 6);
22785       mpfq_zero(v, 6);
22786       mpfq_copy(a, x, 6);
22787       mpfq_copy(b, p, 6);
22788       u[0] = 1UL;
22789 
22790       if (mpfq_fixmp_5_5_cmp(a, v) == 0 || mpfq_fixmp_5_5_cmp(a, b) == 0) {
22791         mpfq_zero(res, 6);
22792         return 0;
22793       }
22794 
22795       mpfq_fixmp_5_5_add(fix, b, u);
22796       mpfq_fixmp_5_5_rshift(fix, 1);
22797 
22798       assert (mpfq_fixmp_5_5_cmp(a,b) < 0);
22799 
22800       t = 0;
22801 
22802       for(i = 0 ; !a[i] ; i++) ;
22803       assert (i < 6);
22804       lsh = mpfq_ctzl(a[i]);
22805       mpfq_fixmp_5_5_long_rshift(a, i, lsh);
22806       t += lsh + i*GMP_NUMB_BITS;
22807       mpfq_fixmp_5_5_long_lshift(v, i, lsh);
22808 
22809       do {
22810         do {
22811           mpfq_fixmp_5_5_sub(b, b, a);
22812           mpfq_fixmp_5_5_add(v, v, u);
22813           for(i = 0 ; !b[i] ; i++) ;
22814           assert (i < 6);
22815           lsh = mpfq_ctzl(b[i]);
22816           mpfq_fixmp_5_5_long_rshift(b, i, lsh);
22817           t += lsh + i*GMP_NUMB_BITS;
22818           mpfq_fixmp_5_5_long_lshift(u, i, lsh);
22819         } while (mpfq_fixmp_5_5_cmp(a,b) < 0);
22820         if (mpfq_fixmp_5_5_cmp(a, b) == 0)
22821           break;
22822         do {
22823           mpfq_fixmp_5_5_sub(a, a, b);
22824           mpfq_fixmp_5_5_add(u, u, v);
22825           for(i = 0 ; !a[i] ; i++) ;
22826           assert (i < 6);
22827           lsh = mpfq_ctzl(a[i]);
22828           mpfq_fixmp_5_5_long_rshift(a, i, lsh);
22829           t += lsh + i*GMP_NUMB_BITS;
22830           mpfq_fixmp_5_5_long_lshift(v, i, lsh);
22831         } while (mpfq_fixmp_5_5_cmp(b,a)<0);
22832       } while (mpfq_fixmp_5_5_cmp(a,b) != 0);
22833       {
22834         if (mpfq_fixmp_5_5_cmp_ui(a, 1) != 0) {
22835           mpfq_copy(res, a, 6);
22836           return 0;
22837         }
22838       }
22839       while (t>0) {
22840         mp_limb_t sig = u[0] & 1UL;
22841         mpfq_fixmp_5_5_rshift(u, 1);
22842         if (sig)
22843           mpfq_fixmp_5_5_add(u, u, fix);
22844         --t;
22845       }
22846       mpfq_copy(res, u, 6);
22847       return 1;
22848 }
22849 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_invmod) */
22850 
22851 #if !defined(HAVE_native_mpfq_fixmp_5_5_redc)
22852 /* x has 11 words, z and p have 5.5 words.
22853  * only one word is read from invp.
22854  * Assuming R=W^6 is the redc modulus, we expect that x verifies:
22855  *   x < R*p,
22856  * so that we have eventually z < p, z congruent to x/R mod p.
22857  * The contents of the area pointed by x are clobbered by this call.
22858  * Note also that x may alias z.
22859  */
22860 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
22861 static inline
mpfq_fixmp_5_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)22862 void mpfq_fixmp_5_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
22863 {
22864     mp_limb_t cy;
22865     for(int i = 0; i < 6; ++i) {
22866         mp_limb_t t = x[i]*mip[0];
22867         cy = mpfq_fixmp_5_5_addmul1_shortz(x+i, p, t);
22868         assert (x[i] == 0);
22869         x[i] = cy;
22870     }
22871     {
22872         mp_limb_t ret[6] = { x[6], x[7], x[8], x[9], x[10], 0 };
22873         cy = mpfq_fixmp_5_5_add(x, x, ret);
22874     }
22875     /* At this point, we have (x' denotes x + cy*W^n here)
22876     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
22877     * x'/R < p + p
22878     */
22879     if (cy || mpfq_fixmp_5_5_cmp(x, p) >= 0) {
22880         mpfq_fixmp_5_5_sub(z, x, p);
22881     } else {
22882         mpfq_copy(z, x, 6);
22883     }
22884 }
22885 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_redc) */
22886 
22887 #if !defined(HAVE_native_mpfq_fixmp_5_5_redc_ur)
22888 /* x has 12 words, z and p have 5.5 words.
22889  * only one word is read from invp.
22890  * Assuming R=W^6 is the redc modulus, we expect that x verifies:
22891  *  x < W*W^5.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
22892  * so that we have eventually z < p, z congruent to x/R mod p.
22893  * The contents of the area pointed by x are clobbered by this call.
22894  * Note also that x may alias z.
22895  */
22896 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
22897 static inline
mpfq_fixmp_5_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)22898 void mpfq_fixmp_5_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
22899 {
22900     mp_limb_t cy, q[1];
22901     for(int i = 0; i < 6; ++i) {
22902         mp_limb_t t = x[i]*mip[0];
22903         cy = mpfq_fixmp_5_5_addmul1_shortz(x+i, p, t);
22904         assert (x[i] == 0);
22905         x[i] = cy;
22906     }
22907     cy = mpfq_fixmp_5_5_add(x + 6, x, x + 6);
22908     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
22909     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
22910     * x'/R < (W^0.5+1)*p
22911     */
22912     if (cy) {
22913         /* x'/R-p < W^0.5*p, which fits in n words. */
22914         mpfq_fixmp_5_5_sub(x + 6, x + 6, p);
22915     }
22916     mpn_tdiv_qr(q, z, 0, x + 6, 6, p, 6);
22917 }
22918 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_redc_ur) */
22919 
22920 #if !defined(HAVE_native_mpfq_fixmp_5_5_mgy_encode)
22921 /* x, z, and p have 5.5 words.
22922  * Assuming R=W^6 is the redc modulus, we compute z=R*x mod p. */
22923 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
22924 static inline
mpfq_fixmp_5_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)22925 void mpfq_fixmp_5_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
22926 {
22927     mp_limb_t t[12] = { 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5] };
22928     mp_limb_t qq[6+1];
22929     mpn_tdiv_qr(qq, z, 0, t, 12, p, 6);
22930 }
22931 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mgy_encode) */
22932 
22933 #if !defined(HAVE_native_mpfq_fixmp_5_5_mgy_decode)
22934 /* x, z, invR, and p have 5.5 words.
22935  * Assuming R=W^6 is the redc modulus, we compute z=x/R mod p. */
22936 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
22937 static inline
mpfq_fixmp_5_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)22938 void mpfq_fixmp_5_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
22939 {
22940     mp_limb_t t[12];
22941     mpfq_fixmp_5_5_mul(t, x, invR);
22942     mpfq_fixmp_5_5_mod(z, t, p);
22943 }
22944 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_mgy_decode) */
22945 
22946 #if !defined(HAVE_native_mpfq_fixmp_5_5_lshift)
22947 /* a has 5.5 words. Shift it in place by cnt bits to the left.
22948  * The shift count cnt must not exceed the word size.
22949  * Note that no carry is returned for the bits shifted out. */
22950 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
22951 static inline
mpfq_fixmp_5_5_lshift(mp_limb_t * a,int cnt)22952 void mpfq_fixmp_5_5_lshift(mp_limb_t * a, int cnt)
22953 {
22954     if (!cnt) return;
22955     int i;
22956     int dnt = GMP_NUMB_BITS - cnt;
22957     for (i = 6-1; i>0; --i) {
22958         a[i] <<= cnt;
22959         a[i] |= (a[i-1] >> dnt);
22960     }
22961     a[0] <<= cnt;
22962 }
22963 #endif /* !defined(HAVE_native_mpfq_fixmp_5_5_lshift) */
22964 
22965 #if !defined(HAVE_native_mpfq_fixmp_6_5_add)
22966 /* x, y, and z have 6.5 words. Result in z. Return carry bit */
22967 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
22968 /* Triggered by: 6_5_invmod, 6_5_redc, 6_5_redc_ur */
22969 static inline
mpfq_fixmp_6_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)22970 mp_limb_t mpfq_fixmp_6_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
22971 {
22972     mp_limb_t r, s, t, cy, cy1, cy2;
22973     cy = 0;
22974     r = x[0];
22975     s = r + y[0];
22976     cy1 = s < r;
22977     t = s + cy;
22978     cy2 = t < s;
22979     cy = cy1 | cy2;
22980     z[0] = t;
22981     r = x[1];
22982     s = r + y[1];
22983     cy1 = s < r;
22984     t = s + cy;
22985     cy2 = t < s;
22986     cy = cy1 | cy2;
22987     z[1] = t;
22988     r = x[2];
22989     s = r + y[2];
22990     cy1 = s < r;
22991     t = s + cy;
22992     cy2 = t < s;
22993     cy = cy1 | cy2;
22994     z[2] = t;
22995     r = x[3];
22996     s = r + y[3];
22997     cy1 = s < r;
22998     t = s + cy;
22999     cy2 = t < s;
23000     cy = cy1 | cy2;
23001     z[3] = t;
23002     r = x[4];
23003     s = r + y[4];
23004     cy1 = s < r;
23005     t = s + cy;
23006     cy2 = t < s;
23007     cy = cy1 | cy2;
23008     z[4] = t;
23009     r = x[5];
23010     s = r + y[5];
23011     cy1 = s < r;
23012     t = s + cy;
23013     cy2 = t < s;
23014     cy = cy1 | cy2;
23015     z[5] = t;
23016     r = x[6];
23017     s = r + y[6];
23018     cy1 = s < r;
23019     t = s + cy;
23020     cy2 = t < s;
23021     cy = cy1 | cy2;
23022     z[6] = t;
23023     return cy;
23024 }
23025 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_add) */
23026 
23027 #if !defined(HAVE_native_mpfq_fixmp_6_5_sub)
23028 /* x, y, and z have 6.5 words. Result in z. Return borrow bit */
23029 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
23030 /* Triggered by: 6_5_invmod, 6_5_redc, 6_5_redc_ur */
23031 static inline
mpfq_fixmp_6_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)23032 mp_limb_t mpfq_fixmp_6_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
23033 {
23034     mp_limb_t r, s, t, cy, cy1, cy2;
23035     cy = 0;
23036     r = x[0];
23037     s = r - y[0];
23038     cy1 = s > r;
23039     t = s - cy;
23040     cy2 = t > s;
23041     cy = cy1 | cy2;
23042     z[0] = t;
23043     r = x[1];
23044     s = r - y[1];
23045     cy1 = s > r;
23046     t = s - cy;
23047     cy2 = t > s;
23048     cy = cy1 | cy2;
23049     z[1] = t;
23050     r = x[2];
23051     s = r - y[2];
23052     cy1 = s > r;
23053     t = s - cy;
23054     cy2 = t > s;
23055     cy = cy1 | cy2;
23056     z[2] = t;
23057     r = x[3];
23058     s = r - y[3];
23059     cy1 = s > r;
23060     t = s - cy;
23061     cy2 = t > s;
23062     cy = cy1 | cy2;
23063     z[3] = t;
23064     r = x[4];
23065     s = r - y[4];
23066     cy1 = s > r;
23067     t = s - cy;
23068     cy2 = t > s;
23069     cy = cy1 | cy2;
23070     z[4] = t;
23071     r = x[5];
23072     s = r - y[5];
23073     cy1 = s > r;
23074     t = s - cy;
23075     cy2 = t > s;
23076     cy = cy1 | cy2;
23077     z[5] = t;
23078     r = x[6];
23079     s = r - y[6];
23080     cy1 = s > r;
23081     t = s - cy;
23082     cy2 = t > s;
23083     cy = cy1 | cy2;
23084     z[6] = t;
23085     return cy;
23086 }
23087 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_sub) */
23088 
23089 #if !defined(HAVE_native_mpfq_fixmp_6_5_add_nc)
23090 /* x, y, and z have 6.5 words. Result in z. Carry bit is lost. */
23091 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
23092 static inline
mpfq_fixmp_6_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)23093 void mpfq_fixmp_6_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
23094 {
23095     mp_limb_t r, s, t, cy, cy1, cy2;
23096     cy = 0;
23097     r = x[0];
23098     s = r + y[0];
23099     cy1 = s < r;
23100     t = s + cy;
23101     cy2 = t < s;
23102     cy = cy1 | cy2;
23103     z[0] = t;
23104     r = x[1];
23105     s = r + y[1];
23106     cy1 = s < r;
23107     t = s + cy;
23108     cy2 = t < s;
23109     cy = cy1 | cy2;
23110     z[1] = t;
23111     r = x[2];
23112     s = r + y[2];
23113     cy1 = s < r;
23114     t = s + cy;
23115     cy2 = t < s;
23116     cy = cy1 | cy2;
23117     z[2] = t;
23118     r = x[3];
23119     s = r + y[3];
23120     cy1 = s < r;
23121     t = s + cy;
23122     cy2 = t < s;
23123     cy = cy1 | cy2;
23124     z[3] = t;
23125     r = x[4];
23126     s = r + y[4];
23127     cy1 = s < r;
23128     t = s + cy;
23129     cy2 = t < s;
23130     cy = cy1 | cy2;
23131     z[4] = t;
23132     r = x[5];
23133     s = r + y[5];
23134     cy1 = s < r;
23135     t = s + cy;
23136     cy2 = t < s;
23137     cy = cy1 | cy2;
23138     z[5] = t;
23139     r = x[6];
23140     s = r + y[6];
23141     cy1 = s < r;
23142     t = s + cy;
23143     cy2 = t < s;
23144     cy = cy1 | cy2;
23145     z[6] = t;
23146 }
23147 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_add_nc) */
23148 
23149 #if !defined(HAVE_native_mpfq_fixmp_6_5_sub_nc)
23150 /* x, y, and z have 6.5 words. Result in z. Borrow bit is lost. */
23151 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
23152 static inline
mpfq_fixmp_6_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)23153 void mpfq_fixmp_6_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
23154 {
23155     mp_limb_t r, s, t, cy, cy1, cy2;
23156     cy = 0;
23157     r = x[0];
23158     s = r - y[0];
23159     cy1 = s > r;
23160     t = s - cy;
23161     cy2 = t > s;
23162     cy = cy1 | cy2;
23163     z[0] = t;
23164     r = x[1];
23165     s = r - y[1];
23166     cy1 = s > r;
23167     t = s - cy;
23168     cy2 = t > s;
23169     cy = cy1 | cy2;
23170     z[1] = t;
23171     r = x[2];
23172     s = r - y[2];
23173     cy1 = s > r;
23174     t = s - cy;
23175     cy2 = t > s;
23176     cy = cy1 | cy2;
23177     z[2] = t;
23178     r = x[3];
23179     s = r - y[3];
23180     cy1 = s > r;
23181     t = s - cy;
23182     cy2 = t > s;
23183     cy = cy1 | cy2;
23184     z[3] = t;
23185     r = x[4];
23186     s = r - y[4];
23187     cy1 = s > r;
23188     t = s - cy;
23189     cy2 = t > s;
23190     cy = cy1 | cy2;
23191     z[4] = t;
23192     r = x[5];
23193     s = r - y[5];
23194     cy1 = s > r;
23195     t = s - cy;
23196     cy2 = t > s;
23197     cy = cy1 | cy2;
23198     z[5] = t;
23199     r = x[6];
23200     s = r - y[6];
23201     cy1 = s > r;
23202     t = s - cy;
23203     cy2 = t > s;
23204     cy = cy1 | cy2;
23205     z[6] = t;
23206 }
23207 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_sub_nc) */
23208 
23209 #if !defined(HAVE_native_mpfq_fixmp_6_5_add_ui)
23210 /* x, y, and z have 6.5 words. Result in z. Return carry bit */
23211 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
23212 static inline
mpfq_fixmp_6_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)23213 mp_limb_t mpfq_fixmp_6_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
23214 {
23215     mp_limb_t r, s, t, cy, cy1, cy2;
23216     cy = 0;
23217     r = x[0];
23218     s = r + y;
23219     cy1 = s < r;
23220     t = s + cy;
23221     cy2 = t < s;
23222     cy = cy1 | cy2;
23223     z[0] = t;
23224     s = x[1];
23225     t = s + cy;
23226     cy = t < s;
23227     z[1] = t;
23228     s = x[2];
23229     t = s + cy;
23230     cy = t < s;
23231     z[2] = t;
23232     s = x[3];
23233     t = s + cy;
23234     cy = t < s;
23235     z[3] = t;
23236     s = x[4];
23237     t = s + cy;
23238     cy = t < s;
23239     z[4] = t;
23240     s = x[5];
23241     t = s + cy;
23242     cy = t < s;
23243     z[5] = t;
23244     s = x[6];
23245     t = s + cy;
23246     cy = t < s;
23247     z[6] = t;
23248     return cy;
23249 }
23250 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_add_ui) */
23251 
23252 #if !defined(HAVE_native_mpfq_fixmp_6_5_sub_ui)
23253 /* x, y, and z have 6.5 words. Result in z. Return borrow bit */
23254 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
23255 static inline
mpfq_fixmp_6_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)23256 mp_limb_t mpfq_fixmp_6_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
23257 {
23258     mp_limb_t r, s, t, cy, cy1, cy2;
23259     cy = 0;
23260     r = x[0];
23261     s = r - y;
23262     cy1 = s > r;
23263     t = s - cy;
23264     cy2 = t > s;
23265     cy = cy1 | cy2;
23266     z[0] = t;
23267     s = x[1];
23268     t = s - cy;
23269     cy = t > s;
23270     z[1] = t;
23271     s = x[2];
23272     t = s - cy;
23273     cy = t > s;
23274     z[2] = t;
23275     s = x[3];
23276     t = s - cy;
23277     cy = t > s;
23278     z[3] = t;
23279     s = x[4];
23280     t = s - cy;
23281     cy = t > s;
23282     z[4] = t;
23283     s = x[5];
23284     t = s - cy;
23285     cy = t > s;
23286     z[5] = t;
23287     s = x[6];
23288     t = s - cy;
23289     cy = t > s;
23290     z[6] = t;
23291     return cy;
23292 }
23293 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_sub_ui) */
23294 
23295 #if !defined(HAVE_native_mpfq_fixmp_6_5_add_ui_nc)
23296 /* x, y, and z have 6.5 words. Result in z. Carry bit is lost. */
23297 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
23298 static inline
mpfq_fixmp_6_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)23299 void mpfq_fixmp_6_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
23300 {
23301     mp_limb_t r, s, t, cy, cy1, cy2;
23302     cy = 0;
23303     r = x[0];
23304     s = r + y;
23305     cy1 = s < r;
23306     t = s + cy;
23307     cy2 = t < s;
23308     cy = cy1 | cy2;
23309     z[0] = t;
23310     s = x[1];
23311     t = s + cy;
23312     cy = t < s;
23313     z[1] = t;
23314     s = x[2];
23315     t = s + cy;
23316     cy = t < s;
23317     z[2] = t;
23318     s = x[3];
23319     t = s + cy;
23320     cy = t < s;
23321     z[3] = t;
23322     s = x[4];
23323     t = s + cy;
23324     cy = t < s;
23325     z[4] = t;
23326     s = x[5];
23327     t = s + cy;
23328     cy = t < s;
23329     z[5] = t;
23330     s = x[6];
23331     t = s + cy;
23332     cy = t < s;
23333     z[6] = t;
23334 }
23335 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_add_ui_nc) */
23336 
23337 #if !defined(HAVE_native_mpfq_fixmp_6_5_sub_ui_nc)
23338 /* x, y, and z have 6.5 words. Result in z. Borrow bit is lost. */
23339 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
23340 static inline
mpfq_fixmp_6_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)23341 void mpfq_fixmp_6_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
23342 {
23343     mp_limb_t r, s, t, cy, cy1, cy2;
23344     cy = 0;
23345     r = x[0];
23346     s = r - y;
23347     cy1 = s > r;
23348     t = s - cy;
23349     cy2 = t > s;
23350     cy = cy1 | cy2;
23351     z[0] = t;
23352     s = x[1];
23353     t = s - cy;
23354     cy = t > s;
23355     z[1] = t;
23356     s = x[2];
23357     t = s - cy;
23358     cy = t > s;
23359     z[2] = t;
23360     s = x[3];
23361     t = s - cy;
23362     cy = t > s;
23363     z[3] = t;
23364     s = x[4];
23365     t = s - cy;
23366     cy = t > s;
23367     z[4] = t;
23368     s = x[5];
23369     t = s - cy;
23370     cy = t > s;
23371     z[5] = t;
23372     s = x[6];
23373     t = s - cy;
23374     cy = t > s;
23375     z[6] = t;
23376 }
23377 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_sub_ui_nc) */
23378 
23379 #if !defined(HAVE_native_mpfq_fixmp_6_5_cmp)
23380 /* x and y have 6.5 words. Return sign of difference x-y. */
23381 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
23382 /* Triggered by: 6_5_invmod, 6_5_redc, 6_5_redc_ur */
23383 static inline
mpfq_fixmp_6_5_cmp(const mp_limb_t * x,const mp_limb_t * y)23384 int mpfq_fixmp_6_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
23385 {
23386     for (int i = 7-1; i >= 0; --i) {
23387         if (x[i] > y[i]) return 1;
23388         if (x[i] < y[i]) return -1;
23389     }
23390     return 0;
23391 }
23392 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_cmp) */
23393 
23394 #if !defined(HAVE_native_mpfq_fixmp_6_5_cmp_ui)
23395 /* x has 6.5 words. Return sign of difference x-y. */
23396 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
23397 /* Triggered by: 6_5_invmod */
23398 static inline
mpfq_fixmp_6_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)23399 int mpfq_fixmp_6_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
23400 {
23401     for (int i = 7-1; i > 0; --i) {
23402         if (x[i]) return 1;
23403     }
23404     if (x[0]>y) return 1;
23405     if (x[0]<y) return -1;
23406     return 0;
23407 }
23408 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_cmp_ui) */
23409 
23410 #if !defined(HAVE_native_mpfq_fixmp_6_5_addmul1)
23411 /* x has 6.5 words, z has 8.
23412  * Put (z+x*c) in z. Return carry bit. */
23413 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
23414 static inline
mpfq_fixmp_6_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23415 mp_limb_t mpfq_fixmp_6_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23416 {
23417     mp_limb_t hi, lo, carry, buf;
23418     carry = 0;
23419     mpfq_umul_ppmm(hi,lo,c,x[0]);
23420     lo += carry;
23421     carry = (lo<carry) + hi;
23422     buf = z[0];
23423     lo += buf;
23424     carry += (lo<buf);
23425     z[0] = lo;
23426     mpfq_umul_ppmm(hi,lo,c,x[1]);
23427     lo += carry;
23428     carry = (lo<carry) + hi;
23429     buf = z[1];
23430     lo += buf;
23431     carry += (lo<buf);
23432     z[1] = lo;
23433     mpfq_umul_ppmm(hi,lo,c,x[2]);
23434     lo += carry;
23435     carry = (lo<carry) + hi;
23436     buf = z[2];
23437     lo += buf;
23438     carry += (lo<buf);
23439     z[2] = lo;
23440     mpfq_umul_ppmm(hi,lo,c,x[3]);
23441     lo += carry;
23442     carry = (lo<carry) + hi;
23443     buf = z[3];
23444     lo += buf;
23445     carry += (lo<buf);
23446     z[3] = lo;
23447     mpfq_umul_ppmm(hi,lo,c,x[4]);
23448     lo += carry;
23449     carry = (lo<carry) + hi;
23450     buf = z[4];
23451     lo += buf;
23452     carry += (lo<buf);
23453     z[4] = lo;
23454     mpfq_umul_ppmm(hi,lo,c,x[5]);
23455     lo += carry;
23456     carry = (lo<carry) + hi;
23457     buf = z[5];
23458     lo += buf;
23459     carry += (lo<buf);
23460     z[5] = lo;
23461     mpfq_umul_ppmm(hi,lo,c,x[6]);
23462     lo += carry;
23463     carry = (lo<carry) + hi;
23464     buf = z[6];
23465     lo += buf;
23466     carry += (lo<buf);
23467     z[6] = lo;
23468     z[7] += carry;
23469     return (z[7]<carry);
23470 }
23471 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_addmul1) */
23472 
23473 #if !defined(HAVE_native_mpfq_fixmp_6_5_addmul1_nc)
23474 /* x has 6.5 words, z has 8.
23475  * Put (z+x*c) in z. Carry bit is lost. */
23476 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
23477 /* Triggered by: 6_5_mul, 6_5_mgy_decode */
23478 static inline
mpfq_fixmp_6_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23479 void mpfq_fixmp_6_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23480 {
23481     mp_limb_t hi, lo, carry, buf;
23482     carry = 0;
23483     mpfq_umul_ppmm(hi,lo,c,x[0]);
23484     lo += carry;
23485     carry = (lo<carry) + hi;
23486     buf = z[0];
23487     lo += buf;
23488     carry += (lo<buf);
23489     z[0] = lo;
23490     mpfq_umul_ppmm(hi,lo,c,x[1]);
23491     lo += carry;
23492     carry = (lo<carry) + hi;
23493     buf = z[1];
23494     lo += buf;
23495     carry += (lo<buf);
23496     z[1] = lo;
23497     mpfq_umul_ppmm(hi,lo,c,x[2]);
23498     lo += carry;
23499     carry = (lo<carry) + hi;
23500     buf = z[2];
23501     lo += buf;
23502     carry += (lo<buf);
23503     z[2] = lo;
23504     mpfq_umul_ppmm(hi,lo,c,x[3]);
23505     lo += carry;
23506     carry = (lo<carry) + hi;
23507     buf = z[3];
23508     lo += buf;
23509     carry += (lo<buf);
23510     z[3] = lo;
23511     mpfq_umul_ppmm(hi,lo,c,x[4]);
23512     lo += carry;
23513     carry = (lo<carry) + hi;
23514     buf = z[4];
23515     lo += buf;
23516     carry += (lo<buf);
23517     z[4] = lo;
23518     mpfq_umul_ppmm(hi,lo,c,x[5]);
23519     lo += carry;
23520     carry = (lo<carry) + hi;
23521     buf = z[5];
23522     lo += buf;
23523     carry += (lo<buf);
23524     z[5] = lo;
23525     mpfq_umul_ppmm(hi,lo,c,x[6]);
23526     lo += carry;
23527     carry = (lo<carry) + hi;
23528     buf = z[6];
23529     lo += buf;
23530     carry += (lo<buf);
23531     z[6] = lo;
23532     z[7] += carry;
23533 }
23534 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_addmul1_nc) */
23535 
23536 #if !defined(HAVE_native_mpfq_fixmp_6_5_addmul1_shortz)
23537 /* x has 6.5 words, z has 7.
23538  * Put (z+x*c) in z. Return carry word. */
23539 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
23540 /* Triggered by: 6_5_redc, 6_5_redc_ur */
23541 static inline
mpfq_fixmp_6_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23542 mp_limb_t mpfq_fixmp_6_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23543 {
23544     mp_limb_t hi, lo, carry, buf;
23545     carry = 0;
23546     mpfq_umul_ppmm(hi,lo,c,x[0]);
23547     lo += carry;
23548     carry = (lo<carry) + hi;
23549     buf = z[0];
23550     lo += buf;
23551     carry += (lo<buf);
23552     z[0] = lo;
23553     mpfq_umul_ppmm(hi,lo,c,x[1]);
23554     lo += carry;
23555     carry = (lo<carry) + hi;
23556     buf = z[1];
23557     lo += buf;
23558     carry += (lo<buf);
23559     z[1] = lo;
23560     mpfq_umul_ppmm(hi,lo,c,x[2]);
23561     lo += carry;
23562     carry = (lo<carry) + hi;
23563     buf = z[2];
23564     lo += buf;
23565     carry += (lo<buf);
23566     z[2] = lo;
23567     mpfq_umul_ppmm(hi,lo,c,x[3]);
23568     lo += carry;
23569     carry = (lo<carry) + hi;
23570     buf = z[3];
23571     lo += buf;
23572     carry += (lo<buf);
23573     z[3] = lo;
23574     mpfq_umul_ppmm(hi,lo,c,x[4]);
23575     lo += carry;
23576     carry = (lo<carry) + hi;
23577     buf = z[4];
23578     lo += buf;
23579     carry += (lo<buf);
23580     z[4] = lo;
23581     mpfq_umul_ppmm(hi,lo,c,x[5]);
23582     lo += carry;
23583     carry = (lo<carry) + hi;
23584     buf = z[5];
23585     lo += buf;
23586     carry += (lo<buf);
23587     z[5] = lo;
23588     mpfq_umul_ppmm(hi,lo,c,x[6]);
23589     lo += carry;
23590     carry = (lo<carry) + hi;
23591     buf = z[6];
23592     lo += buf;
23593     carry += (lo<buf);
23594     z[6] = lo;
23595     return carry;
23596 }
23597 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_addmul1_shortz) */
23598 
23599 #if !defined(HAVE_native_mpfq_fixmp_6_5_addmul05_nc)
23600 /* x has 6.5 words, z has 7. c is 0.5 word.
23601  * Put (z+x*c) in z. Carry bit is lost. */
23602 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
23603 /* Triggered by: 6_5_mul, 6_5_mgy_decode */
23604 static inline
mpfq_fixmp_6_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23605 void mpfq_fixmp_6_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23606 {
23607     mp_limb_t hi, lo, carry, buf;
23608     carry = 0;
23609     mpfq_umul_ppmm(hi,lo,c,x[0]);
23610     lo += carry;
23611     carry = (lo<carry) + hi;
23612     buf = z[0];
23613     lo += buf;
23614     carry += (lo<buf);
23615     z[0] = lo;
23616     mpfq_umul_ppmm(hi,lo,c,x[1]);
23617     lo += carry;
23618     carry = (lo<carry) + hi;
23619     buf = z[1];
23620     lo += buf;
23621     carry += (lo<buf);
23622     z[1] = lo;
23623     mpfq_umul_ppmm(hi,lo,c,x[2]);
23624     lo += carry;
23625     carry = (lo<carry) + hi;
23626     buf = z[2];
23627     lo += buf;
23628     carry += (lo<buf);
23629     z[2] = lo;
23630     mpfq_umul_ppmm(hi,lo,c,x[3]);
23631     lo += carry;
23632     carry = (lo<carry) + hi;
23633     buf = z[3];
23634     lo += buf;
23635     carry += (lo<buf);
23636     z[3] = lo;
23637     mpfq_umul_ppmm(hi,lo,c,x[4]);
23638     lo += carry;
23639     carry = (lo<carry) + hi;
23640     buf = z[4];
23641     lo += buf;
23642     carry += (lo<buf);
23643     z[4] = lo;
23644     mpfq_umul_ppmm(hi,lo,c,x[5]);
23645     lo += carry;
23646     carry = (lo<carry) + hi;
23647     buf = z[5];
23648     lo += buf;
23649     carry += (lo<buf);
23650     z[5] = lo;
23651     lo = c*x[6] + carry;
23652     assert(lo >= carry);
23653     z[6] += lo;
23654 }
23655 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_addmul05_nc) */
23656 
23657 #if !defined(HAVE_native_mpfq_fixmp_6_5_mul)
23658 /* x and y have 6.5 words, z has 13. Put x*y in z. */
23659 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
23660 /* Triggered by: 6_5_mgy_decode */
23661 static inline
mpfq_fixmp_6_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)23662 void mpfq_fixmp_6_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
23663 {
23664     assert(z != x && z != y);
23665     for (int i = 0; i < 13; z[i++] = 0) ;
23666     mpfq_fixmp_6_5_addmul1_nc (z + 0, x, y[0]);
23667     mpfq_fixmp_6_5_addmul1_nc (z + 1, x, y[1]);
23668     mpfq_fixmp_6_5_addmul1_nc (z + 2, x, y[2]);
23669     mpfq_fixmp_6_5_addmul1_nc (z + 3, x, y[3]);
23670     mpfq_fixmp_6_5_addmul1_nc (z + 4, x, y[4]);
23671     mpfq_fixmp_6_5_addmul1_nc (z + 5, x, y[5]);
23672     mpfq_fixmp_6_5_addmul05_nc (z + 6, x, y[6]);
23673 }
23674 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mul) */
23675 
23676 #if !defined(HAVE_native_mpfq_fixmp_6_5_sqr)
23677 /* x has 6.5 words, z has 13. Put x*y in z. */
23678 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
23679 static inline
mpfq_fixmp_6_5_sqr(mp_limb_t * z,const mp_limb_t * x)23680 void mpfq_fixmp_6_5_sqr(mp_limb_t * z, const mp_limb_t * x)
23681 {
23682     mp_limb_t buf[13] = {0,};
23683     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
23684     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
23685     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
23686     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
23687     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
23688     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
23689     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
23690     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
23691     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
23692     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
23693     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
23694     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
23695     z[2*6] = x[6] * x[6];
23696     mpn_lshift(buf, buf, 13, 1);
23697     mpn_add_n(z, z, buf, 13);
23698 }
23699 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_sqr) */
23700 
23701 #if !defined(HAVE_native_mpfq_fixmp_6_5_mul1)
23702 /* x has 6.5 words, z has 8. Put x*y in z. */
23703 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
23704 static inline
mpfq_fixmp_6_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23705 void mpfq_fixmp_6_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23706 {
23707     mp_limb_t hi, lo, carry;
23708     carry = 0;
23709     mpfq_umul_ppmm(hi,lo,c,x[0]);
23710     lo += carry;
23711     carry = (lo<carry) + hi;
23712     z[0] = lo;
23713     mpfq_umul_ppmm(hi,lo,c,x[1]);
23714     lo += carry;
23715     carry = (lo<carry) + hi;
23716     z[1] = lo;
23717     mpfq_umul_ppmm(hi,lo,c,x[2]);
23718     lo += carry;
23719     carry = (lo<carry) + hi;
23720     z[2] = lo;
23721     mpfq_umul_ppmm(hi,lo,c,x[3]);
23722     lo += carry;
23723     carry = (lo<carry) + hi;
23724     z[3] = lo;
23725     mpfq_umul_ppmm(hi,lo,c,x[4]);
23726     lo += carry;
23727     carry = (lo<carry) + hi;
23728     z[4] = lo;
23729     mpfq_umul_ppmm(hi,lo,c,x[5]);
23730     lo += carry;
23731     carry = (lo<carry) + hi;
23732     z[5] = lo;
23733     mpfq_umul_ppmm(hi,lo,c,x[6]);
23734     lo += carry;
23735     carry = (lo<carry) + hi;
23736     z[6] = lo;
23737     z[7] = carry;
23738 }
23739 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mul1) */
23740 
23741 #if !defined(HAVE_native_mpfq_fixmp_6_5_shortmul)
23742 /* x and y have 6.5 words, z has 7.
23743  * Put the low 7 words of x*y in z. */
23744 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
23745 static inline
mpfq_fixmp_6_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)23746 void mpfq_fixmp_6_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
23747 {
23748     mpfq_zero(z, 7);
23749     mpfq_fixmp_6_addmul1_nc (z+0, x, y[0]);
23750     z[7-1] += x[6]*y[0];
23751     mpfq_fixmp_5_addmul1_nc (z+1, x, y[1]);
23752     z[7-1] += x[5]*y[1];
23753     mpfq_fixmp_4_addmul1_nc (z+2, x, y[2]);
23754     z[7-1] += x[4]*y[2];
23755     mpfq_fixmp_3_addmul1_nc (z+3, x, y[3]);
23756     z[7-1] += x[3]*y[3];
23757     mpfq_fixmp_2_addmul1_nc (z+4, x, y[4]);
23758     z[7-1] += x[2]*y[4];
23759     mpfq_fixmp_1_addmul1_nc (z+5, x, y[5]);
23760     z[7-1] += x[1]*y[5];
23761     z[7-1] += x[0]*y[7-1];
23762 }
23763 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_shortmul) */
23764 
23765 #if !defined(HAVE_native_mpfq_fixmp_6_5_addmul05)
23766 /* x has 6.5 words, z has 7. c is 0.5 word.
23767  * Put (z+x*c) in z. Return carry bit. */
23768 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
23769 static inline
mpfq_fixmp_6_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23770 mp_limb_t mpfq_fixmp_6_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23771 {
23772     mp_limb_t hi, lo, carry, buf;
23773     carry = 0;
23774     mpfq_umul_ppmm(hi,lo,c,x[0]);
23775     lo += carry;
23776     carry = (lo<carry) + hi;
23777     buf = z[0];
23778     lo += buf;
23779     carry += (lo<buf);
23780     z[0] = lo;
23781     mpfq_umul_ppmm(hi,lo,c,x[1]);
23782     lo += carry;
23783     carry = (lo<carry) + hi;
23784     buf = z[1];
23785     lo += buf;
23786     carry += (lo<buf);
23787     z[1] = lo;
23788     mpfq_umul_ppmm(hi,lo,c,x[2]);
23789     lo += carry;
23790     carry = (lo<carry) + hi;
23791     buf = z[2];
23792     lo += buf;
23793     carry += (lo<buf);
23794     z[2] = lo;
23795     mpfq_umul_ppmm(hi,lo,c,x[3]);
23796     lo += carry;
23797     carry = (lo<carry) + hi;
23798     buf = z[3];
23799     lo += buf;
23800     carry += (lo<buf);
23801     z[3] = lo;
23802     mpfq_umul_ppmm(hi,lo,c,x[4]);
23803     lo += carry;
23804     carry = (lo<carry) + hi;
23805     buf = z[4];
23806     lo += buf;
23807     carry += (lo<buf);
23808     z[4] = lo;
23809     mpfq_umul_ppmm(hi,lo,c,x[5]);
23810     lo += carry;
23811     carry = (lo<carry) + hi;
23812     buf = z[5];
23813     lo += buf;
23814     carry += (lo<buf);
23815     z[5] = lo;
23816     lo = c*x[6] + carry;
23817     assert(lo >= carry);
23818     z[6] += lo;
23819     return z[6] < lo;
23820 }
23821 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_addmul05) */
23822 
23823 #if !defined(HAVE_native_mpfq_fixmp_6_5_mul05)
23824 /* x has 6.5 words, z has 7. c is 0.5 word.
23825  * Put (x*c) in z. No carry. */
23826 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
23827 static inline
mpfq_fixmp_6_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)23828 void mpfq_fixmp_6_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
23829 {
23830     mp_limb_t hi, lo, carry;
23831     carry = 0;
23832     mpfq_umul_ppmm(hi,lo,c,x[0]);
23833     lo += carry;
23834     carry = (lo<carry) + hi;
23835     z[0] = lo;
23836     mpfq_umul_ppmm(hi,lo,c,x[1]);
23837     lo += carry;
23838     carry = (lo<carry) + hi;
23839     z[1] = lo;
23840     mpfq_umul_ppmm(hi,lo,c,x[2]);
23841     lo += carry;
23842     carry = (lo<carry) + hi;
23843     z[2] = lo;
23844     mpfq_umul_ppmm(hi,lo,c,x[3]);
23845     lo += carry;
23846     carry = (lo<carry) + hi;
23847     z[3] = lo;
23848     mpfq_umul_ppmm(hi,lo,c,x[4]);
23849     lo += carry;
23850     carry = (lo<carry) + hi;
23851     z[4] = lo;
23852     mpfq_umul_ppmm(hi,lo,c,x[5]);
23853     lo += carry;
23854     carry = (lo<carry) + hi;
23855     z[5] = lo;
23856     lo = c*x[6] + carry;
23857     assert(lo >= carry);
23858     z[6] = lo;
23859 }
23860 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mul05) */
23861 
23862 #if !defined(HAVE_native_mpfq_fixmp_6_5_mod)
23863 /* x has 13 words. z and p have 6.5 words, and the high word of p is non-zero.
23864  * Put x mod p in z. */
23865 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
23866 /* Triggered by: 6_5_mgy_decode */
23867 static inline
mpfq_fixmp_6_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)23868 void mpfq_fixmp_6_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
23869 {
23870     mp_limb_t q[6+1], r[7];
23871     assert (p[7-1] != 0);
23872     mpn_tdiv_qr(q, r, 0, x, 13, p, 7);
23873     mpfq_copy(z, r, 7);
23874 }
23875 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mod) */
23876 
23877 #if !defined(HAVE_native_mpfq_fixmp_6_5_rshift)
23878 /* a has 6.5 words. Shift it in place by cnt bits to the right.
23879  * The shift count cnt must not exceed the word size.
23880  * Note that no carry is returned for the bits shifted out. */
23881 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
23882 /* Triggered by: 6_5_invmod */
23883 static inline
mpfq_fixmp_6_5_rshift(mp_limb_t * a,int cnt)23884 void mpfq_fixmp_6_5_rshift(mp_limb_t * a, int cnt)
23885 {
23886     if (!cnt) return;
23887     int i;
23888     int dnt = GMP_NUMB_BITS - cnt;
23889     for (i = 0; i < 7-1; ++i) {
23890         a[i] >>= cnt;
23891         a[i] |= (a[i+1] << dnt);
23892     }
23893     a[7-1] >>= cnt;
23894 }
23895 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_rshift) */
23896 
23897 #if !defined(HAVE_native_mpfq_fixmp_6_5_long_rshift)
23898 /* a has 6.5 words. Shift it in place by off words plus cnt bits to the left.
23899  * Note that no carry is returned for the bits shifted out. */
23900 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
23901 /* Triggered by: 6_5_invmod */
23902 static inline
mpfq_fixmp_6_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)23903 void mpfq_fixmp_6_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
23904 {
23905     if (cnt) {
23906         int dnt = GMP_NUMB_BITS - cnt;
23907         for (int i = 0; i < 7 - off - 1; ++i) {
23908             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
23909         }
23910         a[7-off-1] = a[7-1]>>cnt;
23911     } else {
23912         mpfq_copyi(a, a + off, 7 - off);
23913     }
23914     mpfq_zero(a + 7 - off, off);
23915 }
23916 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_long_rshift) */
23917 
23918 #if !defined(HAVE_native_mpfq_fixmp_6_5_long_lshift)
23919 /* a has 6.5 words. Shift it in place by off words plus cnt bits to the left.
23920  * Note that no carry is returned for the bits shifted out. */
23921 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
23922 /* Triggered by: 6_5_invmod */
23923 static inline
mpfq_fixmp_6_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)23924 void mpfq_fixmp_6_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
23925 {
23926     int i;
23927     if (cnt) {
23928         int dnt = GMP_NUMB_BITS - cnt;
23929         for (i = 7-1; i>off; --i) {
23930             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
23931         }
23932         a[off] = a[0]<<cnt;
23933     } else {
23934         mpfq_copyd(a + off, a, 7 - off);
23935     }
23936     mpfq_zero(a, off);
23937 }
23938 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_long_lshift) */
23939 
23940 #if !defined(HAVE_native_mpfq_fixmp_6_5_invmod)
23941 /* x, z, and p have 6.5 words. Put inverse of x mod p in z.
23942  * Return non-zero if an inverse could be found.
23943  * If no inverse could be found, return 0 and set z to zero.
23944  */
23945 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
23946 static inline
mpfq_fixmp_6_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)23947 int mpfq_fixmp_6_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
23948 {
23949       mp_limb_t u[7], v[7], a[7], b[7], fix[7];
23950       int i, t, lsh;
23951 
23952       mpfq_zero(u, 7);
23953       mpfq_zero(v, 7);
23954       mpfq_copy(a, x, 7);
23955       mpfq_copy(b, p, 7);
23956       u[0] = 1UL;
23957 
23958       if (mpfq_fixmp_6_5_cmp(a, v) == 0 || mpfq_fixmp_6_5_cmp(a, b) == 0) {
23959         mpfq_zero(res, 7);
23960         return 0;
23961       }
23962 
23963       mpfq_fixmp_6_5_add(fix, b, u);
23964       mpfq_fixmp_6_5_rshift(fix, 1);
23965 
23966       assert (mpfq_fixmp_6_5_cmp(a,b) < 0);
23967 
23968       t = 0;
23969 
23970       for(i = 0 ; !a[i] ; i++) ;
23971       assert (i < 7);
23972       lsh = mpfq_ctzl(a[i]);
23973       mpfq_fixmp_6_5_long_rshift(a, i, lsh);
23974       t += lsh + i*GMP_NUMB_BITS;
23975       mpfq_fixmp_6_5_long_lshift(v, i, lsh);
23976 
23977       do {
23978         do {
23979           mpfq_fixmp_6_5_sub(b, b, a);
23980           mpfq_fixmp_6_5_add(v, v, u);
23981           for(i = 0 ; !b[i] ; i++) ;
23982           assert (i < 7);
23983           lsh = mpfq_ctzl(b[i]);
23984           mpfq_fixmp_6_5_long_rshift(b, i, lsh);
23985           t += lsh + i*GMP_NUMB_BITS;
23986           mpfq_fixmp_6_5_long_lshift(u, i, lsh);
23987         } while (mpfq_fixmp_6_5_cmp(a,b) < 0);
23988         if (mpfq_fixmp_6_5_cmp(a, b) == 0)
23989           break;
23990         do {
23991           mpfq_fixmp_6_5_sub(a, a, b);
23992           mpfq_fixmp_6_5_add(u, u, v);
23993           for(i = 0 ; !a[i] ; i++) ;
23994           assert (i < 7);
23995           lsh = mpfq_ctzl(a[i]);
23996           mpfq_fixmp_6_5_long_rshift(a, i, lsh);
23997           t += lsh + i*GMP_NUMB_BITS;
23998           mpfq_fixmp_6_5_long_lshift(v, i, lsh);
23999         } while (mpfq_fixmp_6_5_cmp(b,a)<0);
24000       } while (mpfq_fixmp_6_5_cmp(a,b) != 0);
24001       {
24002         if (mpfq_fixmp_6_5_cmp_ui(a, 1) != 0) {
24003           mpfq_copy(res, a, 7);
24004           return 0;
24005         }
24006       }
24007       while (t>0) {
24008         mp_limb_t sig = u[0] & 1UL;
24009         mpfq_fixmp_6_5_rshift(u, 1);
24010         if (sig)
24011           mpfq_fixmp_6_5_add(u, u, fix);
24012         --t;
24013       }
24014       mpfq_copy(res, u, 7);
24015       return 1;
24016 }
24017 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_invmod) */
24018 
24019 #if !defined(HAVE_native_mpfq_fixmp_6_5_redc)
24020 /* x has 13 words, z and p have 6.5 words.
24021  * only one word is read from invp.
24022  * Assuming R=W^7 is the redc modulus, we expect that x verifies:
24023  *   x < R*p,
24024  * so that we have eventually z < p, z congruent to x/R mod p.
24025  * The contents of the area pointed by x are clobbered by this call.
24026  * Note also that x may alias z.
24027  */
24028 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
24029 static inline
mpfq_fixmp_6_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)24030 void mpfq_fixmp_6_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
24031 {
24032     mp_limb_t cy;
24033     for(int i = 0; i < 7; ++i) {
24034         mp_limb_t t = x[i]*mip[0];
24035         cy = mpfq_fixmp_6_5_addmul1_shortz(x+i, p, t);
24036         assert (x[i] == 0);
24037         x[i] = cy;
24038     }
24039     {
24040         mp_limb_t ret[7] = { x[7], x[8], x[9], x[10], x[11], x[12], 0 };
24041         cy = mpfq_fixmp_6_5_add(x, x, ret);
24042     }
24043     /* At this point, we have (x' denotes x + cy*W^n here)
24044     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
24045     * x'/R < p + p
24046     */
24047     if (cy || mpfq_fixmp_6_5_cmp(x, p) >= 0) {
24048         mpfq_fixmp_6_5_sub(z, x, p);
24049     } else {
24050         mpfq_copy(z, x, 7);
24051     }
24052 }
24053 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_redc) */
24054 
24055 #if !defined(HAVE_native_mpfq_fixmp_6_5_redc_ur)
24056 /* x has 14 words, z and p have 6.5 words.
24057  * only one word is read from invp.
24058  * Assuming R=W^7 is the redc modulus, we expect that x verifies:
24059  *  x < W*W^6.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
24060  * so that we have eventually z < p, z congruent to x/R mod p.
24061  * The contents of the area pointed by x are clobbered by this call.
24062  * Note also that x may alias z.
24063  */
24064 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
24065 static inline
mpfq_fixmp_6_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)24066 void mpfq_fixmp_6_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
24067 {
24068     mp_limb_t cy, q[1];
24069     for(int i = 0; i < 7; ++i) {
24070         mp_limb_t t = x[i]*mip[0];
24071         cy = mpfq_fixmp_6_5_addmul1_shortz(x+i, p, t);
24072         assert (x[i] == 0);
24073         x[i] = cy;
24074     }
24075     cy = mpfq_fixmp_6_5_add(x + 7, x, x + 7);
24076     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
24077     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
24078     * x'/R < (W^0.5+1)*p
24079     */
24080     if (cy) {
24081         /* x'/R-p < W^0.5*p, which fits in n words. */
24082         mpfq_fixmp_6_5_sub(x + 7, x + 7, p);
24083     }
24084     mpn_tdiv_qr(q, z, 0, x + 7, 7, p, 7);
24085 }
24086 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_redc_ur) */
24087 
24088 #if !defined(HAVE_native_mpfq_fixmp_6_5_mgy_encode)
24089 /* x, z, and p have 6.5 words.
24090  * Assuming R=W^7 is the redc modulus, we compute z=R*x mod p. */
24091 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
24092 static inline
mpfq_fixmp_6_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)24093 void mpfq_fixmp_6_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
24094 {
24095     mp_limb_t t[14] = { 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6] };
24096     mp_limb_t qq[7+1];
24097     mpn_tdiv_qr(qq, z, 0, t, 14, p, 7);
24098 }
24099 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mgy_encode) */
24100 
24101 #if !defined(HAVE_native_mpfq_fixmp_6_5_mgy_decode)
24102 /* x, z, invR, and p have 6.5 words.
24103  * Assuming R=W^7 is the redc modulus, we compute z=x/R mod p. */
24104 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
24105 static inline
mpfq_fixmp_6_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)24106 void mpfq_fixmp_6_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
24107 {
24108     mp_limb_t t[14];
24109     mpfq_fixmp_6_5_mul(t, x, invR);
24110     mpfq_fixmp_6_5_mod(z, t, p);
24111 }
24112 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_mgy_decode) */
24113 
24114 #if !defined(HAVE_native_mpfq_fixmp_6_5_lshift)
24115 /* a has 6.5 words. Shift it in place by cnt bits to the left.
24116  * The shift count cnt must not exceed the word size.
24117  * Note that no carry is returned for the bits shifted out. */
24118 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
24119 static inline
mpfq_fixmp_6_5_lshift(mp_limb_t * a,int cnt)24120 void mpfq_fixmp_6_5_lshift(mp_limb_t * a, int cnt)
24121 {
24122     if (!cnt) return;
24123     int i;
24124     int dnt = GMP_NUMB_BITS - cnt;
24125     for (i = 7-1; i>0; --i) {
24126         a[i] <<= cnt;
24127         a[i] |= (a[i-1] >> dnt);
24128     }
24129     a[0] <<= cnt;
24130 }
24131 #endif /* !defined(HAVE_native_mpfq_fixmp_6_5_lshift) */
24132 
24133 #if !defined(HAVE_native_mpfq_fixmp_7_5_add)
24134 /* x, y, and z have 7.5 words. Result in z. Return carry bit */
24135 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
24136 /* Triggered by: 7_5_invmod, 7_5_redc, 7_5_redc_ur */
24137 static inline
mpfq_fixmp_7_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24138 mp_limb_t mpfq_fixmp_7_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24139 {
24140     mp_limb_t r, s, t, cy, cy1, cy2;
24141     cy = 0;
24142     r = x[0];
24143     s = r + y[0];
24144     cy1 = s < r;
24145     t = s + cy;
24146     cy2 = t < s;
24147     cy = cy1 | cy2;
24148     z[0] = t;
24149     r = x[1];
24150     s = r + y[1];
24151     cy1 = s < r;
24152     t = s + cy;
24153     cy2 = t < s;
24154     cy = cy1 | cy2;
24155     z[1] = t;
24156     r = x[2];
24157     s = r + y[2];
24158     cy1 = s < r;
24159     t = s + cy;
24160     cy2 = t < s;
24161     cy = cy1 | cy2;
24162     z[2] = t;
24163     r = x[3];
24164     s = r + y[3];
24165     cy1 = s < r;
24166     t = s + cy;
24167     cy2 = t < s;
24168     cy = cy1 | cy2;
24169     z[3] = t;
24170     r = x[4];
24171     s = r + y[4];
24172     cy1 = s < r;
24173     t = s + cy;
24174     cy2 = t < s;
24175     cy = cy1 | cy2;
24176     z[4] = t;
24177     r = x[5];
24178     s = r + y[5];
24179     cy1 = s < r;
24180     t = s + cy;
24181     cy2 = t < s;
24182     cy = cy1 | cy2;
24183     z[5] = t;
24184     r = x[6];
24185     s = r + y[6];
24186     cy1 = s < r;
24187     t = s + cy;
24188     cy2 = t < s;
24189     cy = cy1 | cy2;
24190     z[6] = t;
24191     r = x[7];
24192     s = r + y[7];
24193     cy1 = s < r;
24194     t = s + cy;
24195     cy2 = t < s;
24196     cy = cy1 | cy2;
24197     z[7] = t;
24198     return cy;
24199 }
24200 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_add) */
24201 
24202 #if !defined(HAVE_native_mpfq_fixmp_7_5_sub)
24203 /* x, y, and z have 7.5 words. Result in z. Return borrow bit */
24204 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
24205 /* Triggered by: 7_5_invmod, 7_5_redc, 7_5_redc_ur */
24206 static inline
mpfq_fixmp_7_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24207 mp_limb_t mpfq_fixmp_7_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24208 {
24209     mp_limb_t r, s, t, cy, cy1, cy2;
24210     cy = 0;
24211     r = x[0];
24212     s = r - y[0];
24213     cy1 = s > r;
24214     t = s - cy;
24215     cy2 = t > s;
24216     cy = cy1 | cy2;
24217     z[0] = t;
24218     r = x[1];
24219     s = r - y[1];
24220     cy1 = s > r;
24221     t = s - cy;
24222     cy2 = t > s;
24223     cy = cy1 | cy2;
24224     z[1] = t;
24225     r = x[2];
24226     s = r - y[2];
24227     cy1 = s > r;
24228     t = s - cy;
24229     cy2 = t > s;
24230     cy = cy1 | cy2;
24231     z[2] = t;
24232     r = x[3];
24233     s = r - y[3];
24234     cy1 = s > r;
24235     t = s - cy;
24236     cy2 = t > s;
24237     cy = cy1 | cy2;
24238     z[3] = t;
24239     r = x[4];
24240     s = r - y[4];
24241     cy1 = s > r;
24242     t = s - cy;
24243     cy2 = t > s;
24244     cy = cy1 | cy2;
24245     z[4] = t;
24246     r = x[5];
24247     s = r - y[5];
24248     cy1 = s > r;
24249     t = s - cy;
24250     cy2 = t > s;
24251     cy = cy1 | cy2;
24252     z[5] = t;
24253     r = x[6];
24254     s = r - y[6];
24255     cy1 = s > r;
24256     t = s - cy;
24257     cy2 = t > s;
24258     cy = cy1 | cy2;
24259     z[6] = t;
24260     r = x[7];
24261     s = r - y[7];
24262     cy1 = s > r;
24263     t = s - cy;
24264     cy2 = t > s;
24265     cy = cy1 | cy2;
24266     z[7] = t;
24267     return cy;
24268 }
24269 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_sub) */
24270 
24271 #if !defined(HAVE_native_mpfq_fixmp_7_5_add_nc)
24272 /* x, y, and z have 7.5 words. Result in z. Carry bit is lost. */
24273 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
24274 static inline
mpfq_fixmp_7_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24275 void mpfq_fixmp_7_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24276 {
24277     mp_limb_t r, s, t, cy, cy1, cy2;
24278     cy = 0;
24279     r = x[0];
24280     s = r + y[0];
24281     cy1 = s < r;
24282     t = s + cy;
24283     cy2 = t < s;
24284     cy = cy1 | cy2;
24285     z[0] = t;
24286     r = x[1];
24287     s = r + y[1];
24288     cy1 = s < r;
24289     t = s + cy;
24290     cy2 = t < s;
24291     cy = cy1 | cy2;
24292     z[1] = t;
24293     r = x[2];
24294     s = r + y[2];
24295     cy1 = s < r;
24296     t = s + cy;
24297     cy2 = t < s;
24298     cy = cy1 | cy2;
24299     z[2] = t;
24300     r = x[3];
24301     s = r + y[3];
24302     cy1 = s < r;
24303     t = s + cy;
24304     cy2 = t < s;
24305     cy = cy1 | cy2;
24306     z[3] = t;
24307     r = x[4];
24308     s = r + y[4];
24309     cy1 = s < r;
24310     t = s + cy;
24311     cy2 = t < s;
24312     cy = cy1 | cy2;
24313     z[4] = t;
24314     r = x[5];
24315     s = r + y[5];
24316     cy1 = s < r;
24317     t = s + cy;
24318     cy2 = t < s;
24319     cy = cy1 | cy2;
24320     z[5] = t;
24321     r = x[6];
24322     s = r + y[6];
24323     cy1 = s < r;
24324     t = s + cy;
24325     cy2 = t < s;
24326     cy = cy1 | cy2;
24327     z[6] = t;
24328     r = x[7];
24329     s = r + y[7];
24330     cy1 = s < r;
24331     t = s + cy;
24332     cy2 = t < s;
24333     cy = cy1 | cy2;
24334     z[7] = t;
24335 }
24336 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_add_nc) */
24337 
24338 #if !defined(HAVE_native_mpfq_fixmp_7_5_sub_nc)
24339 /* x, y, and z have 7.5 words. Result in z. Borrow bit is lost. */
24340 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
24341 static inline
mpfq_fixmp_7_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24342 void mpfq_fixmp_7_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24343 {
24344     mp_limb_t r, s, t, cy, cy1, cy2;
24345     cy = 0;
24346     r = x[0];
24347     s = r - y[0];
24348     cy1 = s > r;
24349     t = s - cy;
24350     cy2 = t > s;
24351     cy = cy1 | cy2;
24352     z[0] = t;
24353     r = x[1];
24354     s = r - y[1];
24355     cy1 = s > r;
24356     t = s - cy;
24357     cy2 = t > s;
24358     cy = cy1 | cy2;
24359     z[1] = t;
24360     r = x[2];
24361     s = r - y[2];
24362     cy1 = s > r;
24363     t = s - cy;
24364     cy2 = t > s;
24365     cy = cy1 | cy2;
24366     z[2] = t;
24367     r = x[3];
24368     s = r - y[3];
24369     cy1 = s > r;
24370     t = s - cy;
24371     cy2 = t > s;
24372     cy = cy1 | cy2;
24373     z[3] = t;
24374     r = x[4];
24375     s = r - y[4];
24376     cy1 = s > r;
24377     t = s - cy;
24378     cy2 = t > s;
24379     cy = cy1 | cy2;
24380     z[4] = t;
24381     r = x[5];
24382     s = r - y[5];
24383     cy1 = s > r;
24384     t = s - cy;
24385     cy2 = t > s;
24386     cy = cy1 | cy2;
24387     z[5] = t;
24388     r = x[6];
24389     s = r - y[6];
24390     cy1 = s > r;
24391     t = s - cy;
24392     cy2 = t > s;
24393     cy = cy1 | cy2;
24394     z[6] = t;
24395     r = x[7];
24396     s = r - y[7];
24397     cy1 = s > r;
24398     t = s - cy;
24399     cy2 = t > s;
24400     cy = cy1 | cy2;
24401     z[7] = t;
24402 }
24403 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_sub_nc) */
24404 
24405 #if !defined(HAVE_native_mpfq_fixmp_7_5_add_ui)
24406 /* x, y, and z have 7.5 words. Result in z. Return carry bit */
24407 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
24408 static inline
mpfq_fixmp_7_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)24409 mp_limb_t mpfq_fixmp_7_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
24410 {
24411     mp_limb_t r, s, t, cy, cy1, cy2;
24412     cy = 0;
24413     r = x[0];
24414     s = r + y;
24415     cy1 = s < r;
24416     t = s + cy;
24417     cy2 = t < s;
24418     cy = cy1 | cy2;
24419     z[0] = t;
24420     s = x[1];
24421     t = s + cy;
24422     cy = t < s;
24423     z[1] = t;
24424     s = x[2];
24425     t = s + cy;
24426     cy = t < s;
24427     z[2] = t;
24428     s = x[3];
24429     t = s + cy;
24430     cy = t < s;
24431     z[3] = t;
24432     s = x[4];
24433     t = s + cy;
24434     cy = t < s;
24435     z[4] = t;
24436     s = x[5];
24437     t = s + cy;
24438     cy = t < s;
24439     z[5] = t;
24440     s = x[6];
24441     t = s + cy;
24442     cy = t < s;
24443     z[6] = t;
24444     s = x[7];
24445     t = s + cy;
24446     cy = t < s;
24447     z[7] = t;
24448     return cy;
24449 }
24450 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_add_ui) */
24451 
24452 #if !defined(HAVE_native_mpfq_fixmp_7_5_sub_ui)
24453 /* x, y, and z have 7.5 words. Result in z. Return borrow bit */
24454 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
24455 static inline
mpfq_fixmp_7_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)24456 mp_limb_t mpfq_fixmp_7_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
24457 {
24458     mp_limb_t r, s, t, cy, cy1, cy2;
24459     cy = 0;
24460     r = x[0];
24461     s = r - y;
24462     cy1 = s > r;
24463     t = s - cy;
24464     cy2 = t > s;
24465     cy = cy1 | cy2;
24466     z[0] = t;
24467     s = x[1];
24468     t = s - cy;
24469     cy = t > s;
24470     z[1] = t;
24471     s = x[2];
24472     t = s - cy;
24473     cy = t > s;
24474     z[2] = t;
24475     s = x[3];
24476     t = s - cy;
24477     cy = t > s;
24478     z[3] = t;
24479     s = x[4];
24480     t = s - cy;
24481     cy = t > s;
24482     z[4] = t;
24483     s = x[5];
24484     t = s - cy;
24485     cy = t > s;
24486     z[5] = t;
24487     s = x[6];
24488     t = s - cy;
24489     cy = t > s;
24490     z[6] = t;
24491     s = x[7];
24492     t = s - cy;
24493     cy = t > s;
24494     z[7] = t;
24495     return cy;
24496 }
24497 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_sub_ui) */
24498 
24499 #if !defined(HAVE_native_mpfq_fixmp_7_5_add_ui_nc)
24500 /* x, y, and z have 7.5 words. Result in z. Carry bit is lost. */
24501 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
24502 static inline
mpfq_fixmp_7_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)24503 void mpfq_fixmp_7_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
24504 {
24505     mp_limb_t r, s, t, cy, cy1, cy2;
24506     cy = 0;
24507     r = x[0];
24508     s = r + y;
24509     cy1 = s < r;
24510     t = s + cy;
24511     cy2 = t < s;
24512     cy = cy1 | cy2;
24513     z[0] = t;
24514     s = x[1];
24515     t = s + cy;
24516     cy = t < s;
24517     z[1] = t;
24518     s = x[2];
24519     t = s + cy;
24520     cy = t < s;
24521     z[2] = t;
24522     s = x[3];
24523     t = s + cy;
24524     cy = t < s;
24525     z[3] = t;
24526     s = x[4];
24527     t = s + cy;
24528     cy = t < s;
24529     z[4] = t;
24530     s = x[5];
24531     t = s + cy;
24532     cy = t < s;
24533     z[5] = t;
24534     s = x[6];
24535     t = s + cy;
24536     cy = t < s;
24537     z[6] = t;
24538     s = x[7];
24539     t = s + cy;
24540     cy = t < s;
24541     z[7] = t;
24542 }
24543 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_add_ui_nc) */
24544 
24545 #if !defined(HAVE_native_mpfq_fixmp_7_5_sub_ui_nc)
24546 /* x, y, and z have 7.5 words. Result in z. Borrow bit is lost. */
24547 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
24548 static inline
mpfq_fixmp_7_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)24549 void mpfq_fixmp_7_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
24550 {
24551     mp_limb_t r, s, t, cy, cy1, cy2;
24552     cy = 0;
24553     r = x[0];
24554     s = r - y;
24555     cy1 = s > r;
24556     t = s - cy;
24557     cy2 = t > s;
24558     cy = cy1 | cy2;
24559     z[0] = t;
24560     s = x[1];
24561     t = s - cy;
24562     cy = t > s;
24563     z[1] = t;
24564     s = x[2];
24565     t = s - cy;
24566     cy = t > s;
24567     z[2] = t;
24568     s = x[3];
24569     t = s - cy;
24570     cy = t > s;
24571     z[3] = t;
24572     s = x[4];
24573     t = s - cy;
24574     cy = t > s;
24575     z[4] = t;
24576     s = x[5];
24577     t = s - cy;
24578     cy = t > s;
24579     z[5] = t;
24580     s = x[6];
24581     t = s - cy;
24582     cy = t > s;
24583     z[6] = t;
24584     s = x[7];
24585     t = s - cy;
24586     cy = t > s;
24587     z[7] = t;
24588 }
24589 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_sub_ui_nc) */
24590 
24591 #if !defined(HAVE_native_mpfq_fixmp_7_5_cmp)
24592 /* x and y have 7.5 words. Return sign of difference x-y. */
24593 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
24594 /* Triggered by: 7_5_invmod, 7_5_redc, 7_5_redc_ur */
24595 static inline
mpfq_fixmp_7_5_cmp(const mp_limb_t * x,const mp_limb_t * y)24596 int mpfq_fixmp_7_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
24597 {
24598     for (int i = 8-1; i >= 0; --i) {
24599         if (x[i] > y[i]) return 1;
24600         if (x[i] < y[i]) return -1;
24601     }
24602     return 0;
24603 }
24604 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_cmp) */
24605 
24606 #if !defined(HAVE_native_mpfq_fixmp_7_5_cmp_ui)
24607 /* x has 7.5 words. Return sign of difference x-y. */
24608 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
24609 /* Triggered by: 7_5_invmod */
24610 static inline
mpfq_fixmp_7_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)24611 int mpfq_fixmp_7_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
24612 {
24613     for (int i = 8-1; i > 0; --i) {
24614         if (x[i]) return 1;
24615     }
24616     if (x[0]>y) return 1;
24617     if (x[0]<y) return -1;
24618     return 0;
24619 }
24620 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_cmp_ui) */
24621 
24622 #if !defined(HAVE_native_mpfq_fixmp_7_5_addmul1)
24623 /* x has 7.5 words, z has 9.
24624  * Put (z+x*c) in z. Return carry bit. */
24625 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
24626 static inline
mpfq_fixmp_7_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)24627 mp_limb_t mpfq_fixmp_7_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
24628 {
24629     mp_limb_t hi, lo, carry, buf;
24630     carry = 0;
24631     mpfq_umul_ppmm(hi,lo,c,x[0]);
24632     lo += carry;
24633     carry = (lo<carry) + hi;
24634     buf = z[0];
24635     lo += buf;
24636     carry += (lo<buf);
24637     z[0] = lo;
24638     mpfq_umul_ppmm(hi,lo,c,x[1]);
24639     lo += carry;
24640     carry = (lo<carry) + hi;
24641     buf = z[1];
24642     lo += buf;
24643     carry += (lo<buf);
24644     z[1] = lo;
24645     mpfq_umul_ppmm(hi,lo,c,x[2]);
24646     lo += carry;
24647     carry = (lo<carry) + hi;
24648     buf = z[2];
24649     lo += buf;
24650     carry += (lo<buf);
24651     z[2] = lo;
24652     mpfq_umul_ppmm(hi,lo,c,x[3]);
24653     lo += carry;
24654     carry = (lo<carry) + hi;
24655     buf = z[3];
24656     lo += buf;
24657     carry += (lo<buf);
24658     z[3] = lo;
24659     mpfq_umul_ppmm(hi,lo,c,x[4]);
24660     lo += carry;
24661     carry = (lo<carry) + hi;
24662     buf = z[4];
24663     lo += buf;
24664     carry += (lo<buf);
24665     z[4] = lo;
24666     mpfq_umul_ppmm(hi,lo,c,x[5]);
24667     lo += carry;
24668     carry = (lo<carry) + hi;
24669     buf = z[5];
24670     lo += buf;
24671     carry += (lo<buf);
24672     z[5] = lo;
24673     mpfq_umul_ppmm(hi,lo,c,x[6]);
24674     lo += carry;
24675     carry = (lo<carry) + hi;
24676     buf = z[6];
24677     lo += buf;
24678     carry += (lo<buf);
24679     z[6] = lo;
24680     mpfq_umul_ppmm(hi,lo,c,x[7]);
24681     lo += carry;
24682     carry = (lo<carry) + hi;
24683     buf = z[7];
24684     lo += buf;
24685     carry += (lo<buf);
24686     z[7] = lo;
24687     z[8] += carry;
24688     return (z[8]<carry);
24689 }
24690 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_addmul1) */
24691 
24692 #if !defined(HAVE_native_mpfq_fixmp_7_5_addmul1_nc)
24693 /* x has 7.5 words, z has 9.
24694  * Put (z+x*c) in z. Carry bit is lost. */
24695 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
24696 /* Triggered by: 7_5_mul, 7_5_mgy_decode */
24697 static inline
mpfq_fixmp_7_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)24698 void mpfq_fixmp_7_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
24699 {
24700     mp_limb_t hi, lo, carry, buf;
24701     carry = 0;
24702     mpfq_umul_ppmm(hi,lo,c,x[0]);
24703     lo += carry;
24704     carry = (lo<carry) + hi;
24705     buf = z[0];
24706     lo += buf;
24707     carry += (lo<buf);
24708     z[0] = lo;
24709     mpfq_umul_ppmm(hi,lo,c,x[1]);
24710     lo += carry;
24711     carry = (lo<carry) + hi;
24712     buf = z[1];
24713     lo += buf;
24714     carry += (lo<buf);
24715     z[1] = lo;
24716     mpfq_umul_ppmm(hi,lo,c,x[2]);
24717     lo += carry;
24718     carry = (lo<carry) + hi;
24719     buf = z[2];
24720     lo += buf;
24721     carry += (lo<buf);
24722     z[2] = lo;
24723     mpfq_umul_ppmm(hi,lo,c,x[3]);
24724     lo += carry;
24725     carry = (lo<carry) + hi;
24726     buf = z[3];
24727     lo += buf;
24728     carry += (lo<buf);
24729     z[3] = lo;
24730     mpfq_umul_ppmm(hi,lo,c,x[4]);
24731     lo += carry;
24732     carry = (lo<carry) + hi;
24733     buf = z[4];
24734     lo += buf;
24735     carry += (lo<buf);
24736     z[4] = lo;
24737     mpfq_umul_ppmm(hi,lo,c,x[5]);
24738     lo += carry;
24739     carry = (lo<carry) + hi;
24740     buf = z[5];
24741     lo += buf;
24742     carry += (lo<buf);
24743     z[5] = lo;
24744     mpfq_umul_ppmm(hi,lo,c,x[6]);
24745     lo += carry;
24746     carry = (lo<carry) + hi;
24747     buf = z[6];
24748     lo += buf;
24749     carry += (lo<buf);
24750     z[6] = lo;
24751     mpfq_umul_ppmm(hi,lo,c,x[7]);
24752     lo += carry;
24753     carry = (lo<carry) + hi;
24754     buf = z[7];
24755     lo += buf;
24756     carry += (lo<buf);
24757     z[7] = lo;
24758     z[8] += carry;
24759 }
24760 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_addmul1_nc) */
24761 
24762 #if !defined(HAVE_native_mpfq_fixmp_7_5_addmul1_shortz)
24763 /* x has 7.5 words, z has 8.
24764  * Put (z+x*c) in z. Return carry word. */
24765 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
24766 /* Triggered by: 7_5_redc, 7_5_redc_ur */
24767 static inline
mpfq_fixmp_7_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)24768 mp_limb_t mpfq_fixmp_7_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
24769 {
24770     mp_limb_t hi, lo, carry, buf;
24771     carry = 0;
24772     mpfq_umul_ppmm(hi,lo,c,x[0]);
24773     lo += carry;
24774     carry = (lo<carry) + hi;
24775     buf = z[0];
24776     lo += buf;
24777     carry += (lo<buf);
24778     z[0] = lo;
24779     mpfq_umul_ppmm(hi,lo,c,x[1]);
24780     lo += carry;
24781     carry = (lo<carry) + hi;
24782     buf = z[1];
24783     lo += buf;
24784     carry += (lo<buf);
24785     z[1] = lo;
24786     mpfq_umul_ppmm(hi,lo,c,x[2]);
24787     lo += carry;
24788     carry = (lo<carry) + hi;
24789     buf = z[2];
24790     lo += buf;
24791     carry += (lo<buf);
24792     z[2] = lo;
24793     mpfq_umul_ppmm(hi,lo,c,x[3]);
24794     lo += carry;
24795     carry = (lo<carry) + hi;
24796     buf = z[3];
24797     lo += buf;
24798     carry += (lo<buf);
24799     z[3] = lo;
24800     mpfq_umul_ppmm(hi,lo,c,x[4]);
24801     lo += carry;
24802     carry = (lo<carry) + hi;
24803     buf = z[4];
24804     lo += buf;
24805     carry += (lo<buf);
24806     z[4] = lo;
24807     mpfq_umul_ppmm(hi,lo,c,x[5]);
24808     lo += carry;
24809     carry = (lo<carry) + hi;
24810     buf = z[5];
24811     lo += buf;
24812     carry += (lo<buf);
24813     z[5] = lo;
24814     mpfq_umul_ppmm(hi,lo,c,x[6]);
24815     lo += carry;
24816     carry = (lo<carry) + hi;
24817     buf = z[6];
24818     lo += buf;
24819     carry += (lo<buf);
24820     z[6] = lo;
24821     mpfq_umul_ppmm(hi,lo,c,x[7]);
24822     lo += carry;
24823     carry = (lo<carry) + hi;
24824     buf = z[7];
24825     lo += buf;
24826     carry += (lo<buf);
24827     z[7] = lo;
24828     return carry;
24829 }
24830 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_addmul1_shortz) */
24831 
24832 #if !defined(HAVE_native_mpfq_fixmp_7_5_addmul05_nc)
24833 /* x has 7.5 words, z has 8. c is 0.5 word.
24834  * Put (z+x*c) in z. Carry bit is lost. */
24835 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
24836 /* Triggered by: 7_5_mul, 7_5_mgy_decode */
24837 static inline
mpfq_fixmp_7_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)24838 void mpfq_fixmp_7_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
24839 {
24840     mp_limb_t hi, lo, carry, buf;
24841     carry = 0;
24842     mpfq_umul_ppmm(hi,lo,c,x[0]);
24843     lo += carry;
24844     carry = (lo<carry) + hi;
24845     buf = z[0];
24846     lo += buf;
24847     carry += (lo<buf);
24848     z[0] = lo;
24849     mpfq_umul_ppmm(hi,lo,c,x[1]);
24850     lo += carry;
24851     carry = (lo<carry) + hi;
24852     buf = z[1];
24853     lo += buf;
24854     carry += (lo<buf);
24855     z[1] = lo;
24856     mpfq_umul_ppmm(hi,lo,c,x[2]);
24857     lo += carry;
24858     carry = (lo<carry) + hi;
24859     buf = z[2];
24860     lo += buf;
24861     carry += (lo<buf);
24862     z[2] = lo;
24863     mpfq_umul_ppmm(hi,lo,c,x[3]);
24864     lo += carry;
24865     carry = (lo<carry) + hi;
24866     buf = z[3];
24867     lo += buf;
24868     carry += (lo<buf);
24869     z[3] = lo;
24870     mpfq_umul_ppmm(hi,lo,c,x[4]);
24871     lo += carry;
24872     carry = (lo<carry) + hi;
24873     buf = z[4];
24874     lo += buf;
24875     carry += (lo<buf);
24876     z[4] = lo;
24877     mpfq_umul_ppmm(hi,lo,c,x[5]);
24878     lo += carry;
24879     carry = (lo<carry) + hi;
24880     buf = z[5];
24881     lo += buf;
24882     carry += (lo<buf);
24883     z[5] = lo;
24884     mpfq_umul_ppmm(hi,lo,c,x[6]);
24885     lo += carry;
24886     carry = (lo<carry) + hi;
24887     buf = z[6];
24888     lo += buf;
24889     carry += (lo<buf);
24890     z[6] = lo;
24891     lo = c*x[7] + carry;
24892     assert(lo >= carry);
24893     z[7] += lo;
24894 }
24895 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_addmul05_nc) */
24896 
24897 #if !defined(HAVE_native_mpfq_fixmp_7_5_mul)
24898 /* x and y have 7.5 words, z has 15. Put x*y in z. */
24899 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
24900 /* Triggered by: 7_5_mgy_decode */
24901 static inline
mpfq_fixmp_7_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24902 void mpfq_fixmp_7_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24903 {
24904     assert(z != x && z != y);
24905     for (int i = 0; i < 15; z[i++] = 0) ;
24906     mpfq_fixmp_7_5_addmul1_nc (z + 0, x, y[0]);
24907     mpfq_fixmp_7_5_addmul1_nc (z + 1, x, y[1]);
24908     mpfq_fixmp_7_5_addmul1_nc (z + 2, x, y[2]);
24909     mpfq_fixmp_7_5_addmul1_nc (z + 3, x, y[3]);
24910     mpfq_fixmp_7_5_addmul1_nc (z + 4, x, y[4]);
24911     mpfq_fixmp_7_5_addmul1_nc (z + 5, x, y[5]);
24912     mpfq_fixmp_7_5_addmul1_nc (z + 6, x, y[6]);
24913     mpfq_fixmp_7_5_addmul05_nc (z + 7, x, y[7]);
24914 }
24915 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mul) */
24916 
24917 #if !defined(HAVE_native_mpfq_fixmp_7_5_sqr)
24918 /* x has 7.5 words, z has 15. Put x*y in z. */
24919 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
24920 static inline
mpfq_fixmp_7_5_sqr(mp_limb_t * z,const mp_limb_t * x)24921 void mpfq_fixmp_7_5_sqr(mp_limb_t * z, const mp_limb_t * x)
24922 {
24923     mp_limb_t buf[15] = {0,};
24924     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
24925     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
24926     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
24927     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
24928     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
24929     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
24930     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
24931     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
24932     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
24933     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
24934     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
24935     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
24936     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
24937     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
24938     z[2*7] = x[7] * x[7];
24939     mpn_lshift(buf, buf, 15, 1);
24940     mpn_add_n(z, z, buf, 15);
24941 }
24942 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_sqr) */
24943 
24944 #if !defined(HAVE_native_mpfq_fixmp_7_5_mul1)
24945 /* x has 7.5 words, z has 9. Put x*y in z. */
24946 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
24947 static inline
mpfq_fixmp_7_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)24948 void mpfq_fixmp_7_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
24949 {
24950     mp_limb_t hi, lo, carry;
24951     carry = 0;
24952     mpfq_umul_ppmm(hi,lo,c,x[0]);
24953     lo += carry;
24954     carry = (lo<carry) + hi;
24955     z[0] = lo;
24956     mpfq_umul_ppmm(hi,lo,c,x[1]);
24957     lo += carry;
24958     carry = (lo<carry) + hi;
24959     z[1] = lo;
24960     mpfq_umul_ppmm(hi,lo,c,x[2]);
24961     lo += carry;
24962     carry = (lo<carry) + hi;
24963     z[2] = lo;
24964     mpfq_umul_ppmm(hi,lo,c,x[3]);
24965     lo += carry;
24966     carry = (lo<carry) + hi;
24967     z[3] = lo;
24968     mpfq_umul_ppmm(hi,lo,c,x[4]);
24969     lo += carry;
24970     carry = (lo<carry) + hi;
24971     z[4] = lo;
24972     mpfq_umul_ppmm(hi,lo,c,x[5]);
24973     lo += carry;
24974     carry = (lo<carry) + hi;
24975     z[5] = lo;
24976     mpfq_umul_ppmm(hi,lo,c,x[6]);
24977     lo += carry;
24978     carry = (lo<carry) + hi;
24979     z[6] = lo;
24980     mpfq_umul_ppmm(hi,lo,c,x[7]);
24981     lo += carry;
24982     carry = (lo<carry) + hi;
24983     z[7] = lo;
24984     z[8] = carry;
24985 }
24986 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mul1) */
24987 
24988 #if !defined(HAVE_native_mpfq_fixmp_7_5_shortmul)
24989 /* x and y have 7.5 words, z has 8.
24990  * Put the low 8 words of x*y in z. */
24991 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
24992 static inline
mpfq_fixmp_7_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)24993 void mpfq_fixmp_7_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
24994 {
24995     mpfq_zero(z, 8);
24996     mpfq_fixmp_7_addmul1_nc (z+0, x, y[0]);
24997     z[8-1] += x[7]*y[0];
24998     mpfq_fixmp_6_addmul1_nc (z+1, x, y[1]);
24999     z[8-1] += x[6]*y[1];
25000     mpfq_fixmp_5_addmul1_nc (z+2, x, y[2]);
25001     z[8-1] += x[5]*y[2];
25002     mpfq_fixmp_4_addmul1_nc (z+3, x, y[3]);
25003     z[8-1] += x[4]*y[3];
25004     mpfq_fixmp_3_addmul1_nc (z+4, x, y[4]);
25005     z[8-1] += x[3]*y[4];
25006     mpfq_fixmp_2_addmul1_nc (z+5, x, y[5]);
25007     z[8-1] += x[2]*y[5];
25008     mpfq_fixmp_1_addmul1_nc (z+6, x, y[6]);
25009     z[8-1] += x[1]*y[6];
25010     z[8-1] += x[0]*y[8-1];
25011 }
25012 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_shortmul) */
25013 
25014 #if !defined(HAVE_native_mpfq_fixmp_7_5_addmul05)
25015 /* x has 7.5 words, z has 8. c is 0.5 word.
25016  * Put (z+x*c) in z. Return carry bit. */
25017 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
25018 static inline
mpfq_fixmp_7_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)25019 mp_limb_t mpfq_fixmp_7_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
25020 {
25021     mp_limb_t hi, lo, carry, buf;
25022     carry = 0;
25023     mpfq_umul_ppmm(hi,lo,c,x[0]);
25024     lo += carry;
25025     carry = (lo<carry) + hi;
25026     buf = z[0];
25027     lo += buf;
25028     carry += (lo<buf);
25029     z[0] = lo;
25030     mpfq_umul_ppmm(hi,lo,c,x[1]);
25031     lo += carry;
25032     carry = (lo<carry) + hi;
25033     buf = z[1];
25034     lo += buf;
25035     carry += (lo<buf);
25036     z[1] = lo;
25037     mpfq_umul_ppmm(hi,lo,c,x[2]);
25038     lo += carry;
25039     carry = (lo<carry) + hi;
25040     buf = z[2];
25041     lo += buf;
25042     carry += (lo<buf);
25043     z[2] = lo;
25044     mpfq_umul_ppmm(hi,lo,c,x[3]);
25045     lo += carry;
25046     carry = (lo<carry) + hi;
25047     buf = z[3];
25048     lo += buf;
25049     carry += (lo<buf);
25050     z[3] = lo;
25051     mpfq_umul_ppmm(hi,lo,c,x[4]);
25052     lo += carry;
25053     carry = (lo<carry) + hi;
25054     buf = z[4];
25055     lo += buf;
25056     carry += (lo<buf);
25057     z[4] = lo;
25058     mpfq_umul_ppmm(hi,lo,c,x[5]);
25059     lo += carry;
25060     carry = (lo<carry) + hi;
25061     buf = z[5];
25062     lo += buf;
25063     carry += (lo<buf);
25064     z[5] = lo;
25065     mpfq_umul_ppmm(hi,lo,c,x[6]);
25066     lo += carry;
25067     carry = (lo<carry) + hi;
25068     buf = z[6];
25069     lo += buf;
25070     carry += (lo<buf);
25071     z[6] = lo;
25072     lo = c*x[7] + carry;
25073     assert(lo >= carry);
25074     z[7] += lo;
25075     return z[7] < lo;
25076 }
25077 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_addmul05) */
25078 
25079 #if !defined(HAVE_native_mpfq_fixmp_7_5_mul05)
25080 /* x has 7.5 words, z has 8. c is 0.5 word.
25081  * Put (x*c) in z. No carry. */
25082 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
25083 static inline
mpfq_fixmp_7_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)25084 void mpfq_fixmp_7_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
25085 {
25086     mp_limb_t hi, lo, carry;
25087     carry = 0;
25088     mpfq_umul_ppmm(hi,lo,c,x[0]);
25089     lo += carry;
25090     carry = (lo<carry) + hi;
25091     z[0] = lo;
25092     mpfq_umul_ppmm(hi,lo,c,x[1]);
25093     lo += carry;
25094     carry = (lo<carry) + hi;
25095     z[1] = lo;
25096     mpfq_umul_ppmm(hi,lo,c,x[2]);
25097     lo += carry;
25098     carry = (lo<carry) + hi;
25099     z[2] = lo;
25100     mpfq_umul_ppmm(hi,lo,c,x[3]);
25101     lo += carry;
25102     carry = (lo<carry) + hi;
25103     z[3] = lo;
25104     mpfq_umul_ppmm(hi,lo,c,x[4]);
25105     lo += carry;
25106     carry = (lo<carry) + hi;
25107     z[4] = lo;
25108     mpfq_umul_ppmm(hi,lo,c,x[5]);
25109     lo += carry;
25110     carry = (lo<carry) + hi;
25111     z[5] = lo;
25112     mpfq_umul_ppmm(hi,lo,c,x[6]);
25113     lo += carry;
25114     carry = (lo<carry) + hi;
25115     z[6] = lo;
25116     lo = c*x[7] + carry;
25117     assert(lo >= carry);
25118     z[7] = lo;
25119 }
25120 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mul05) */
25121 
25122 #if !defined(HAVE_native_mpfq_fixmp_7_5_mod)
25123 /* x has 15 words. z and p have 7.5 words, and the high word of p is non-zero.
25124  * Put x mod p in z. */
25125 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
25126 /* Triggered by: 7_5_mgy_decode */
25127 static inline
mpfq_fixmp_7_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)25128 void mpfq_fixmp_7_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
25129 {
25130     mp_limb_t q[7+1], r[8];
25131     assert (p[8-1] != 0);
25132     mpn_tdiv_qr(q, r, 0, x, 15, p, 8);
25133     mpfq_copy(z, r, 8);
25134 }
25135 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mod) */
25136 
25137 #if !defined(HAVE_native_mpfq_fixmp_7_5_rshift)
25138 /* a has 7.5 words. Shift it in place by cnt bits to the right.
25139  * The shift count cnt must not exceed the word size.
25140  * Note that no carry is returned for the bits shifted out. */
25141 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
25142 /* Triggered by: 7_5_invmod */
25143 static inline
mpfq_fixmp_7_5_rshift(mp_limb_t * a,int cnt)25144 void mpfq_fixmp_7_5_rshift(mp_limb_t * a, int cnt)
25145 {
25146     if (!cnt) return;
25147     int i;
25148     int dnt = GMP_NUMB_BITS - cnt;
25149     for (i = 0; i < 8-1; ++i) {
25150         a[i] >>= cnt;
25151         a[i] |= (a[i+1] << dnt);
25152     }
25153     a[8-1] >>= cnt;
25154 }
25155 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_rshift) */
25156 
25157 #if !defined(HAVE_native_mpfq_fixmp_7_5_long_rshift)
25158 /* a has 7.5 words. Shift it in place by off words plus cnt bits to the left.
25159  * Note that no carry is returned for the bits shifted out. */
25160 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
25161 /* Triggered by: 7_5_invmod */
25162 static inline
mpfq_fixmp_7_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)25163 void mpfq_fixmp_7_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
25164 {
25165     if (cnt) {
25166         int dnt = GMP_NUMB_BITS - cnt;
25167         for (int i = 0; i < 8 - off - 1; ++i) {
25168             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
25169         }
25170         a[8-off-1] = a[8-1]>>cnt;
25171     } else {
25172         mpfq_copyi(a, a + off, 8 - off);
25173     }
25174     mpfq_zero(a + 8 - off, off);
25175 }
25176 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_long_rshift) */
25177 
25178 #if !defined(HAVE_native_mpfq_fixmp_7_5_long_lshift)
25179 /* a has 7.5 words. Shift it in place by off words plus cnt bits to the left.
25180  * Note that no carry is returned for the bits shifted out. */
25181 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
25182 /* Triggered by: 7_5_invmod */
25183 static inline
mpfq_fixmp_7_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)25184 void mpfq_fixmp_7_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
25185 {
25186     int i;
25187     if (cnt) {
25188         int dnt = GMP_NUMB_BITS - cnt;
25189         for (i = 8-1; i>off; --i) {
25190             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
25191         }
25192         a[off] = a[0]<<cnt;
25193     } else {
25194         mpfq_copyd(a + off, a, 8 - off);
25195     }
25196     mpfq_zero(a, off);
25197 }
25198 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_long_lshift) */
25199 
25200 #if !defined(HAVE_native_mpfq_fixmp_7_5_invmod)
25201 /* x, z, and p have 7.5 words. Put inverse of x mod p in z.
25202  * Return non-zero if an inverse could be found.
25203  * If no inverse could be found, return 0 and set z to zero.
25204  */
25205 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
25206 static inline
mpfq_fixmp_7_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)25207 int mpfq_fixmp_7_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
25208 {
25209       mp_limb_t u[8], v[8], a[8], b[8], fix[8];
25210       int i, t, lsh;
25211 
25212       mpfq_zero(u, 8);
25213       mpfq_zero(v, 8);
25214       mpfq_copy(a, x, 8);
25215       mpfq_copy(b, p, 8);
25216       u[0] = 1UL;
25217 
25218       if (mpfq_fixmp_7_5_cmp(a, v) == 0 || mpfq_fixmp_7_5_cmp(a, b) == 0) {
25219         mpfq_zero(res, 8);
25220         return 0;
25221       }
25222 
25223       mpfq_fixmp_7_5_add(fix, b, u);
25224       mpfq_fixmp_7_5_rshift(fix, 1);
25225 
25226       assert (mpfq_fixmp_7_5_cmp(a,b) < 0);
25227 
25228       t = 0;
25229 
25230       for(i = 0 ; !a[i] ; i++) ;
25231       assert (i < 8);
25232       lsh = mpfq_ctzl(a[i]);
25233       mpfq_fixmp_7_5_long_rshift(a, i, lsh);
25234       t += lsh + i*GMP_NUMB_BITS;
25235       mpfq_fixmp_7_5_long_lshift(v, i, lsh);
25236 
25237       do {
25238         do {
25239           mpfq_fixmp_7_5_sub(b, b, a);
25240           mpfq_fixmp_7_5_add(v, v, u);
25241           for(i = 0 ; !b[i] ; i++) ;
25242           assert (i < 8);
25243           lsh = mpfq_ctzl(b[i]);
25244           mpfq_fixmp_7_5_long_rshift(b, i, lsh);
25245           t += lsh + i*GMP_NUMB_BITS;
25246           mpfq_fixmp_7_5_long_lshift(u, i, lsh);
25247         } while (mpfq_fixmp_7_5_cmp(a,b) < 0);
25248         if (mpfq_fixmp_7_5_cmp(a, b) == 0)
25249           break;
25250         do {
25251           mpfq_fixmp_7_5_sub(a, a, b);
25252           mpfq_fixmp_7_5_add(u, u, v);
25253           for(i = 0 ; !a[i] ; i++) ;
25254           assert (i < 8);
25255           lsh = mpfq_ctzl(a[i]);
25256           mpfq_fixmp_7_5_long_rshift(a, i, lsh);
25257           t += lsh + i*GMP_NUMB_BITS;
25258           mpfq_fixmp_7_5_long_lshift(v, i, lsh);
25259         } while (mpfq_fixmp_7_5_cmp(b,a)<0);
25260       } while (mpfq_fixmp_7_5_cmp(a,b) != 0);
25261       {
25262         if (mpfq_fixmp_7_5_cmp_ui(a, 1) != 0) {
25263           mpfq_copy(res, a, 8);
25264           return 0;
25265         }
25266       }
25267       while (t>0) {
25268         mp_limb_t sig = u[0] & 1UL;
25269         mpfq_fixmp_7_5_rshift(u, 1);
25270         if (sig)
25271           mpfq_fixmp_7_5_add(u, u, fix);
25272         --t;
25273       }
25274       mpfq_copy(res, u, 8);
25275       return 1;
25276 }
25277 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_invmod) */
25278 
25279 #if !defined(HAVE_native_mpfq_fixmp_7_5_redc)
25280 /* x has 15 words, z and p have 7.5 words.
25281  * only one word is read from invp.
25282  * Assuming R=W^8 is the redc modulus, we expect that x verifies:
25283  *   x < R*p,
25284  * so that we have eventually z < p, z congruent to x/R mod p.
25285  * The contents of the area pointed by x are clobbered by this call.
25286  * Note also that x may alias z.
25287  */
25288 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
25289 static inline
mpfq_fixmp_7_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)25290 void mpfq_fixmp_7_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
25291 {
25292     mp_limb_t cy;
25293     for(int i = 0; i < 8; ++i) {
25294         mp_limb_t t = x[i]*mip[0];
25295         cy = mpfq_fixmp_7_5_addmul1_shortz(x+i, p, t);
25296         assert (x[i] == 0);
25297         x[i] = cy;
25298     }
25299     {
25300         mp_limb_t ret[8] = { x[8], x[9], x[10], x[11], x[12], x[13], x[14], 0 };
25301         cy = mpfq_fixmp_7_5_add(x, x, ret);
25302     }
25303     /* At this point, we have (x' denotes x + cy*W^n here)
25304     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
25305     * x'/R < p + p
25306     */
25307     if (cy || mpfq_fixmp_7_5_cmp(x, p) >= 0) {
25308         mpfq_fixmp_7_5_sub(z, x, p);
25309     } else {
25310         mpfq_copy(z, x, 8);
25311     }
25312 }
25313 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_redc) */
25314 
25315 #if !defined(HAVE_native_mpfq_fixmp_7_5_redc_ur)
25316 /* x has 16 words, z and p have 7.5 words.
25317  * only one word is read from invp.
25318  * Assuming R=W^8 is the redc modulus, we expect that x verifies:
25319  *  x < W*W^7.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
25320  * so that we have eventually z < p, z congruent to x/R mod p.
25321  * The contents of the area pointed by x are clobbered by this call.
25322  * Note also that x may alias z.
25323  */
25324 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
25325 static inline
mpfq_fixmp_7_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)25326 void mpfq_fixmp_7_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
25327 {
25328     mp_limb_t cy, q[1];
25329     for(int i = 0; i < 8; ++i) {
25330         mp_limb_t t = x[i]*mip[0];
25331         cy = mpfq_fixmp_7_5_addmul1_shortz(x+i, p, t);
25332         assert (x[i] == 0);
25333         x[i] = cy;
25334     }
25335     cy = mpfq_fixmp_7_5_add(x + 8, x, x + 8);
25336     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
25337     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
25338     * x'/R < (W^0.5+1)*p
25339     */
25340     if (cy) {
25341         /* x'/R-p < W^0.5*p, which fits in n words. */
25342         mpfq_fixmp_7_5_sub(x + 8, x + 8, p);
25343     }
25344     mpn_tdiv_qr(q, z, 0, x + 8, 8, p, 8);
25345 }
25346 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_redc_ur) */
25347 
25348 #if !defined(HAVE_native_mpfq_fixmp_7_5_mgy_encode)
25349 /* x, z, and p have 7.5 words.
25350  * Assuming R=W^8 is the redc modulus, we compute z=R*x mod p. */
25351 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
25352 static inline
mpfq_fixmp_7_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)25353 void mpfq_fixmp_7_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
25354 {
25355     mp_limb_t t[16] = { 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7] };
25356     mp_limb_t qq[8+1];
25357     mpn_tdiv_qr(qq, z, 0, t, 16, p, 8);
25358 }
25359 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mgy_encode) */
25360 
25361 #if !defined(HAVE_native_mpfq_fixmp_7_5_mgy_decode)
25362 /* x, z, invR, and p have 7.5 words.
25363  * Assuming R=W^8 is the redc modulus, we compute z=x/R mod p. */
25364 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
25365 static inline
mpfq_fixmp_7_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)25366 void mpfq_fixmp_7_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
25367 {
25368     mp_limb_t t[16];
25369     mpfq_fixmp_7_5_mul(t, x, invR);
25370     mpfq_fixmp_7_5_mod(z, t, p);
25371 }
25372 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_mgy_decode) */
25373 
25374 #if !defined(HAVE_native_mpfq_fixmp_7_5_lshift)
25375 /* a has 7.5 words. Shift it in place by cnt bits to the left.
25376  * The shift count cnt must not exceed the word size.
25377  * Note that no carry is returned for the bits shifted out. */
25378 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
25379 static inline
mpfq_fixmp_7_5_lshift(mp_limb_t * a,int cnt)25380 void mpfq_fixmp_7_5_lshift(mp_limb_t * a, int cnt)
25381 {
25382     if (!cnt) return;
25383     int i;
25384     int dnt = GMP_NUMB_BITS - cnt;
25385     for (i = 8-1; i>0; --i) {
25386         a[i] <<= cnt;
25387         a[i] |= (a[i-1] >> dnt);
25388     }
25389     a[0] <<= cnt;
25390 }
25391 #endif /* !defined(HAVE_native_mpfq_fixmp_7_5_lshift) */
25392 
25393 #if !defined(HAVE_native_mpfq_fixmp_8_5_add)
25394 /* x, y, and z have 8.5 words. Result in z. Return carry bit */
25395 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
25396 /* Triggered by: 8_5_invmod, 8_5_redc, 8_5_redc_ur */
25397 static inline
mpfq_fixmp_8_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)25398 mp_limb_t mpfq_fixmp_8_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
25399 {
25400     mp_limb_t r, s, t, cy, cy1, cy2;
25401     cy = 0;
25402     r = x[0];
25403     s = r + y[0];
25404     cy1 = s < r;
25405     t = s + cy;
25406     cy2 = t < s;
25407     cy = cy1 | cy2;
25408     z[0] = t;
25409     r = x[1];
25410     s = r + y[1];
25411     cy1 = s < r;
25412     t = s + cy;
25413     cy2 = t < s;
25414     cy = cy1 | cy2;
25415     z[1] = t;
25416     r = x[2];
25417     s = r + y[2];
25418     cy1 = s < r;
25419     t = s + cy;
25420     cy2 = t < s;
25421     cy = cy1 | cy2;
25422     z[2] = t;
25423     r = x[3];
25424     s = r + y[3];
25425     cy1 = s < r;
25426     t = s + cy;
25427     cy2 = t < s;
25428     cy = cy1 | cy2;
25429     z[3] = t;
25430     r = x[4];
25431     s = r + y[4];
25432     cy1 = s < r;
25433     t = s + cy;
25434     cy2 = t < s;
25435     cy = cy1 | cy2;
25436     z[4] = t;
25437     r = x[5];
25438     s = r + y[5];
25439     cy1 = s < r;
25440     t = s + cy;
25441     cy2 = t < s;
25442     cy = cy1 | cy2;
25443     z[5] = t;
25444     r = x[6];
25445     s = r + y[6];
25446     cy1 = s < r;
25447     t = s + cy;
25448     cy2 = t < s;
25449     cy = cy1 | cy2;
25450     z[6] = t;
25451     r = x[7];
25452     s = r + y[7];
25453     cy1 = s < r;
25454     t = s + cy;
25455     cy2 = t < s;
25456     cy = cy1 | cy2;
25457     z[7] = t;
25458     r = x[8];
25459     s = r + y[8];
25460     cy1 = s < r;
25461     t = s + cy;
25462     cy2 = t < s;
25463     cy = cy1 | cy2;
25464     z[8] = t;
25465     return cy;
25466 }
25467 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_add) */
25468 
25469 #if !defined(HAVE_native_mpfq_fixmp_8_5_sub)
25470 /* x, y, and z have 8.5 words. Result in z. Return borrow bit */
25471 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
25472 /* Triggered by: 8_5_invmod, 8_5_redc, 8_5_redc_ur */
25473 static inline
mpfq_fixmp_8_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)25474 mp_limb_t mpfq_fixmp_8_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
25475 {
25476     mp_limb_t r, s, t, cy, cy1, cy2;
25477     cy = 0;
25478     r = x[0];
25479     s = r - y[0];
25480     cy1 = s > r;
25481     t = s - cy;
25482     cy2 = t > s;
25483     cy = cy1 | cy2;
25484     z[0] = t;
25485     r = x[1];
25486     s = r - y[1];
25487     cy1 = s > r;
25488     t = s - cy;
25489     cy2 = t > s;
25490     cy = cy1 | cy2;
25491     z[1] = t;
25492     r = x[2];
25493     s = r - y[2];
25494     cy1 = s > r;
25495     t = s - cy;
25496     cy2 = t > s;
25497     cy = cy1 | cy2;
25498     z[2] = t;
25499     r = x[3];
25500     s = r - y[3];
25501     cy1 = s > r;
25502     t = s - cy;
25503     cy2 = t > s;
25504     cy = cy1 | cy2;
25505     z[3] = t;
25506     r = x[4];
25507     s = r - y[4];
25508     cy1 = s > r;
25509     t = s - cy;
25510     cy2 = t > s;
25511     cy = cy1 | cy2;
25512     z[4] = t;
25513     r = x[5];
25514     s = r - y[5];
25515     cy1 = s > r;
25516     t = s - cy;
25517     cy2 = t > s;
25518     cy = cy1 | cy2;
25519     z[5] = t;
25520     r = x[6];
25521     s = r - y[6];
25522     cy1 = s > r;
25523     t = s - cy;
25524     cy2 = t > s;
25525     cy = cy1 | cy2;
25526     z[6] = t;
25527     r = x[7];
25528     s = r - y[7];
25529     cy1 = s > r;
25530     t = s - cy;
25531     cy2 = t > s;
25532     cy = cy1 | cy2;
25533     z[7] = t;
25534     r = x[8];
25535     s = r - y[8];
25536     cy1 = s > r;
25537     t = s - cy;
25538     cy2 = t > s;
25539     cy = cy1 | cy2;
25540     z[8] = t;
25541     return cy;
25542 }
25543 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_sub) */
25544 
25545 #if !defined(HAVE_native_mpfq_fixmp_8_5_add_nc)
25546 /* x, y, and z have 8.5 words. Result in z. Carry bit is lost. */
25547 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
25548 static inline
mpfq_fixmp_8_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)25549 void mpfq_fixmp_8_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
25550 {
25551     mp_limb_t r, s, t, cy, cy1, cy2;
25552     cy = 0;
25553     r = x[0];
25554     s = r + y[0];
25555     cy1 = s < r;
25556     t = s + cy;
25557     cy2 = t < s;
25558     cy = cy1 | cy2;
25559     z[0] = t;
25560     r = x[1];
25561     s = r + y[1];
25562     cy1 = s < r;
25563     t = s + cy;
25564     cy2 = t < s;
25565     cy = cy1 | cy2;
25566     z[1] = t;
25567     r = x[2];
25568     s = r + y[2];
25569     cy1 = s < r;
25570     t = s + cy;
25571     cy2 = t < s;
25572     cy = cy1 | cy2;
25573     z[2] = t;
25574     r = x[3];
25575     s = r + y[3];
25576     cy1 = s < r;
25577     t = s + cy;
25578     cy2 = t < s;
25579     cy = cy1 | cy2;
25580     z[3] = t;
25581     r = x[4];
25582     s = r + y[4];
25583     cy1 = s < r;
25584     t = s + cy;
25585     cy2 = t < s;
25586     cy = cy1 | cy2;
25587     z[4] = t;
25588     r = x[5];
25589     s = r + y[5];
25590     cy1 = s < r;
25591     t = s + cy;
25592     cy2 = t < s;
25593     cy = cy1 | cy2;
25594     z[5] = t;
25595     r = x[6];
25596     s = r + y[6];
25597     cy1 = s < r;
25598     t = s + cy;
25599     cy2 = t < s;
25600     cy = cy1 | cy2;
25601     z[6] = t;
25602     r = x[7];
25603     s = r + y[7];
25604     cy1 = s < r;
25605     t = s + cy;
25606     cy2 = t < s;
25607     cy = cy1 | cy2;
25608     z[7] = t;
25609     r = x[8];
25610     s = r + y[8];
25611     cy1 = s < r;
25612     t = s + cy;
25613     cy2 = t < s;
25614     cy = cy1 | cy2;
25615     z[8] = t;
25616 }
25617 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_add_nc) */
25618 
25619 #if !defined(HAVE_native_mpfq_fixmp_8_5_sub_nc)
25620 /* x, y, and z have 8.5 words. Result in z. Borrow bit is lost. */
25621 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
25622 static inline
mpfq_fixmp_8_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)25623 void mpfq_fixmp_8_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
25624 {
25625     mp_limb_t r, s, t, cy, cy1, cy2;
25626     cy = 0;
25627     r = x[0];
25628     s = r - y[0];
25629     cy1 = s > r;
25630     t = s - cy;
25631     cy2 = t > s;
25632     cy = cy1 | cy2;
25633     z[0] = t;
25634     r = x[1];
25635     s = r - y[1];
25636     cy1 = s > r;
25637     t = s - cy;
25638     cy2 = t > s;
25639     cy = cy1 | cy2;
25640     z[1] = t;
25641     r = x[2];
25642     s = r - y[2];
25643     cy1 = s > r;
25644     t = s - cy;
25645     cy2 = t > s;
25646     cy = cy1 | cy2;
25647     z[2] = t;
25648     r = x[3];
25649     s = r - y[3];
25650     cy1 = s > r;
25651     t = s - cy;
25652     cy2 = t > s;
25653     cy = cy1 | cy2;
25654     z[3] = t;
25655     r = x[4];
25656     s = r - y[4];
25657     cy1 = s > r;
25658     t = s - cy;
25659     cy2 = t > s;
25660     cy = cy1 | cy2;
25661     z[4] = t;
25662     r = x[5];
25663     s = r - y[5];
25664     cy1 = s > r;
25665     t = s - cy;
25666     cy2 = t > s;
25667     cy = cy1 | cy2;
25668     z[5] = t;
25669     r = x[6];
25670     s = r - y[6];
25671     cy1 = s > r;
25672     t = s - cy;
25673     cy2 = t > s;
25674     cy = cy1 | cy2;
25675     z[6] = t;
25676     r = x[7];
25677     s = r - y[7];
25678     cy1 = s > r;
25679     t = s - cy;
25680     cy2 = t > s;
25681     cy = cy1 | cy2;
25682     z[7] = t;
25683     r = x[8];
25684     s = r - y[8];
25685     cy1 = s > r;
25686     t = s - cy;
25687     cy2 = t > s;
25688     cy = cy1 | cy2;
25689     z[8] = t;
25690 }
25691 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_sub_nc) */
25692 
25693 #if !defined(HAVE_native_mpfq_fixmp_8_5_add_ui)
25694 /* x, y, and z have 8.5 words. Result in z. Return carry bit */
25695 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
25696 static inline
mpfq_fixmp_8_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)25697 mp_limb_t mpfq_fixmp_8_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
25698 {
25699     mp_limb_t r, s, t, cy, cy1, cy2;
25700     cy = 0;
25701     r = x[0];
25702     s = r + y;
25703     cy1 = s < r;
25704     t = s + cy;
25705     cy2 = t < s;
25706     cy = cy1 | cy2;
25707     z[0] = t;
25708     s = x[1];
25709     t = s + cy;
25710     cy = t < s;
25711     z[1] = t;
25712     s = x[2];
25713     t = s + cy;
25714     cy = t < s;
25715     z[2] = t;
25716     s = x[3];
25717     t = s + cy;
25718     cy = t < s;
25719     z[3] = t;
25720     s = x[4];
25721     t = s + cy;
25722     cy = t < s;
25723     z[4] = t;
25724     s = x[5];
25725     t = s + cy;
25726     cy = t < s;
25727     z[5] = t;
25728     s = x[6];
25729     t = s + cy;
25730     cy = t < s;
25731     z[6] = t;
25732     s = x[7];
25733     t = s + cy;
25734     cy = t < s;
25735     z[7] = t;
25736     s = x[8];
25737     t = s + cy;
25738     cy = t < s;
25739     z[8] = t;
25740     return cy;
25741 }
25742 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_add_ui) */
25743 
25744 #if !defined(HAVE_native_mpfq_fixmp_8_5_sub_ui)
25745 /* x, y, and z have 8.5 words. Result in z. Return borrow bit */
25746 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
25747 static inline
mpfq_fixmp_8_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)25748 mp_limb_t mpfq_fixmp_8_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
25749 {
25750     mp_limb_t r, s, t, cy, cy1, cy2;
25751     cy = 0;
25752     r = x[0];
25753     s = r - y;
25754     cy1 = s > r;
25755     t = s - cy;
25756     cy2 = t > s;
25757     cy = cy1 | cy2;
25758     z[0] = t;
25759     s = x[1];
25760     t = s - cy;
25761     cy = t > s;
25762     z[1] = t;
25763     s = x[2];
25764     t = s - cy;
25765     cy = t > s;
25766     z[2] = t;
25767     s = x[3];
25768     t = s - cy;
25769     cy = t > s;
25770     z[3] = t;
25771     s = x[4];
25772     t = s - cy;
25773     cy = t > s;
25774     z[4] = t;
25775     s = x[5];
25776     t = s - cy;
25777     cy = t > s;
25778     z[5] = t;
25779     s = x[6];
25780     t = s - cy;
25781     cy = t > s;
25782     z[6] = t;
25783     s = x[7];
25784     t = s - cy;
25785     cy = t > s;
25786     z[7] = t;
25787     s = x[8];
25788     t = s - cy;
25789     cy = t > s;
25790     z[8] = t;
25791     return cy;
25792 }
25793 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_sub_ui) */
25794 
25795 #if !defined(HAVE_native_mpfq_fixmp_8_5_add_ui_nc)
25796 /* x, y, and z have 8.5 words. Result in z. Carry bit is lost. */
25797 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
25798 static inline
mpfq_fixmp_8_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)25799 void mpfq_fixmp_8_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
25800 {
25801     mp_limb_t r, s, t, cy, cy1, cy2;
25802     cy = 0;
25803     r = x[0];
25804     s = r + y;
25805     cy1 = s < r;
25806     t = s + cy;
25807     cy2 = t < s;
25808     cy = cy1 | cy2;
25809     z[0] = t;
25810     s = x[1];
25811     t = s + cy;
25812     cy = t < s;
25813     z[1] = t;
25814     s = x[2];
25815     t = s + cy;
25816     cy = t < s;
25817     z[2] = t;
25818     s = x[3];
25819     t = s + cy;
25820     cy = t < s;
25821     z[3] = t;
25822     s = x[4];
25823     t = s + cy;
25824     cy = t < s;
25825     z[4] = t;
25826     s = x[5];
25827     t = s + cy;
25828     cy = t < s;
25829     z[5] = t;
25830     s = x[6];
25831     t = s + cy;
25832     cy = t < s;
25833     z[6] = t;
25834     s = x[7];
25835     t = s + cy;
25836     cy = t < s;
25837     z[7] = t;
25838     s = x[8];
25839     t = s + cy;
25840     cy = t < s;
25841     z[8] = t;
25842 }
25843 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_add_ui_nc) */
25844 
25845 #if !defined(HAVE_native_mpfq_fixmp_8_5_sub_ui_nc)
25846 /* x, y, and z have 8.5 words. Result in z. Borrow bit is lost. */
25847 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
25848 static inline
mpfq_fixmp_8_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)25849 void mpfq_fixmp_8_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
25850 {
25851     mp_limb_t r, s, t, cy, cy1, cy2;
25852     cy = 0;
25853     r = x[0];
25854     s = r - y;
25855     cy1 = s > r;
25856     t = s - cy;
25857     cy2 = t > s;
25858     cy = cy1 | cy2;
25859     z[0] = t;
25860     s = x[1];
25861     t = s - cy;
25862     cy = t > s;
25863     z[1] = t;
25864     s = x[2];
25865     t = s - cy;
25866     cy = t > s;
25867     z[2] = t;
25868     s = x[3];
25869     t = s - cy;
25870     cy = t > s;
25871     z[3] = t;
25872     s = x[4];
25873     t = s - cy;
25874     cy = t > s;
25875     z[4] = t;
25876     s = x[5];
25877     t = s - cy;
25878     cy = t > s;
25879     z[5] = t;
25880     s = x[6];
25881     t = s - cy;
25882     cy = t > s;
25883     z[6] = t;
25884     s = x[7];
25885     t = s - cy;
25886     cy = t > s;
25887     z[7] = t;
25888     s = x[8];
25889     t = s - cy;
25890     cy = t > s;
25891     z[8] = t;
25892 }
25893 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_sub_ui_nc) */
25894 
25895 #if !defined(HAVE_native_mpfq_fixmp_8_5_cmp)
25896 /* x and y have 8.5 words. Return sign of difference x-y. */
25897 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
25898 /* Triggered by: 8_5_invmod, 8_5_redc, 8_5_redc_ur */
25899 static inline
mpfq_fixmp_8_5_cmp(const mp_limb_t * x,const mp_limb_t * y)25900 int mpfq_fixmp_8_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
25901 {
25902     for (int i = 9-1; i >= 0; --i) {
25903         if (x[i] > y[i]) return 1;
25904         if (x[i] < y[i]) return -1;
25905     }
25906     return 0;
25907 }
25908 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_cmp) */
25909 
25910 #if !defined(HAVE_native_mpfq_fixmp_8_5_cmp_ui)
25911 /* x has 8.5 words. Return sign of difference x-y. */
25912 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
25913 /* Triggered by: 8_5_invmod */
25914 static inline
mpfq_fixmp_8_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)25915 int mpfq_fixmp_8_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
25916 {
25917     for (int i = 9-1; i > 0; --i) {
25918         if (x[i]) return 1;
25919     }
25920     if (x[0]>y) return 1;
25921     if (x[0]<y) return -1;
25922     return 0;
25923 }
25924 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_cmp_ui) */
25925 
25926 #if !defined(HAVE_native_mpfq_fixmp_8_5_addmul1)
25927 /* x has 8.5 words, z has 10.
25928  * Put (z+x*c) in z. Return carry bit. */
25929 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
25930 static inline
mpfq_fixmp_8_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)25931 mp_limb_t mpfq_fixmp_8_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
25932 {
25933     mp_limb_t hi, lo, carry, buf;
25934     carry = 0;
25935     mpfq_umul_ppmm(hi,lo,c,x[0]);
25936     lo += carry;
25937     carry = (lo<carry) + hi;
25938     buf = z[0];
25939     lo += buf;
25940     carry += (lo<buf);
25941     z[0] = lo;
25942     mpfq_umul_ppmm(hi,lo,c,x[1]);
25943     lo += carry;
25944     carry = (lo<carry) + hi;
25945     buf = z[1];
25946     lo += buf;
25947     carry += (lo<buf);
25948     z[1] = lo;
25949     mpfq_umul_ppmm(hi,lo,c,x[2]);
25950     lo += carry;
25951     carry = (lo<carry) + hi;
25952     buf = z[2];
25953     lo += buf;
25954     carry += (lo<buf);
25955     z[2] = lo;
25956     mpfq_umul_ppmm(hi,lo,c,x[3]);
25957     lo += carry;
25958     carry = (lo<carry) + hi;
25959     buf = z[3];
25960     lo += buf;
25961     carry += (lo<buf);
25962     z[3] = lo;
25963     mpfq_umul_ppmm(hi,lo,c,x[4]);
25964     lo += carry;
25965     carry = (lo<carry) + hi;
25966     buf = z[4];
25967     lo += buf;
25968     carry += (lo<buf);
25969     z[4] = lo;
25970     mpfq_umul_ppmm(hi,lo,c,x[5]);
25971     lo += carry;
25972     carry = (lo<carry) + hi;
25973     buf = z[5];
25974     lo += buf;
25975     carry += (lo<buf);
25976     z[5] = lo;
25977     mpfq_umul_ppmm(hi,lo,c,x[6]);
25978     lo += carry;
25979     carry = (lo<carry) + hi;
25980     buf = z[6];
25981     lo += buf;
25982     carry += (lo<buf);
25983     z[6] = lo;
25984     mpfq_umul_ppmm(hi,lo,c,x[7]);
25985     lo += carry;
25986     carry = (lo<carry) + hi;
25987     buf = z[7];
25988     lo += buf;
25989     carry += (lo<buf);
25990     z[7] = lo;
25991     mpfq_umul_ppmm(hi,lo,c,x[8]);
25992     lo += carry;
25993     carry = (lo<carry) + hi;
25994     buf = z[8];
25995     lo += buf;
25996     carry += (lo<buf);
25997     z[8] = lo;
25998     z[9] += carry;
25999     return (z[9]<carry);
26000 }
26001 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_addmul1) */
26002 
26003 #if !defined(HAVE_native_mpfq_fixmp_8_5_addmul1_nc)
26004 /* x has 8.5 words, z has 10.
26005  * Put (z+x*c) in z. Carry bit is lost. */
26006 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
26007 /* Triggered by: 8_5_mul, 8_5_mgy_decode */
26008 static inline
mpfq_fixmp_8_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26009 void mpfq_fixmp_8_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26010 {
26011     mp_limb_t hi, lo, carry, buf;
26012     carry = 0;
26013     mpfq_umul_ppmm(hi,lo,c,x[0]);
26014     lo += carry;
26015     carry = (lo<carry) + hi;
26016     buf = z[0];
26017     lo += buf;
26018     carry += (lo<buf);
26019     z[0] = lo;
26020     mpfq_umul_ppmm(hi,lo,c,x[1]);
26021     lo += carry;
26022     carry = (lo<carry) + hi;
26023     buf = z[1];
26024     lo += buf;
26025     carry += (lo<buf);
26026     z[1] = lo;
26027     mpfq_umul_ppmm(hi,lo,c,x[2]);
26028     lo += carry;
26029     carry = (lo<carry) + hi;
26030     buf = z[2];
26031     lo += buf;
26032     carry += (lo<buf);
26033     z[2] = lo;
26034     mpfq_umul_ppmm(hi,lo,c,x[3]);
26035     lo += carry;
26036     carry = (lo<carry) + hi;
26037     buf = z[3];
26038     lo += buf;
26039     carry += (lo<buf);
26040     z[3] = lo;
26041     mpfq_umul_ppmm(hi,lo,c,x[4]);
26042     lo += carry;
26043     carry = (lo<carry) + hi;
26044     buf = z[4];
26045     lo += buf;
26046     carry += (lo<buf);
26047     z[4] = lo;
26048     mpfq_umul_ppmm(hi,lo,c,x[5]);
26049     lo += carry;
26050     carry = (lo<carry) + hi;
26051     buf = z[5];
26052     lo += buf;
26053     carry += (lo<buf);
26054     z[5] = lo;
26055     mpfq_umul_ppmm(hi,lo,c,x[6]);
26056     lo += carry;
26057     carry = (lo<carry) + hi;
26058     buf = z[6];
26059     lo += buf;
26060     carry += (lo<buf);
26061     z[6] = lo;
26062     mpfq_umul_ppmm(hi,lo,c,x[7]);
26063     lo += carry;
26064     carry = (lo<carry) + hi;
26065     buf = z[7];
26066     lo += buf;
26067     carry += (lo<buf);
26068     z[7] = lo;
26069     mpfq_umul_ppmm(hi,lo,c,x[8]);
26070     lo += carry;
26071     carry = (lo<carry) + hi;
26072     buf = z[8];
26073     lo += buf;
26074     carry += (lo<buf);
26075     z[8] = lo;
26076     z[9] += carry;
26077 }
26078 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_addmul1_nc) */
26079 
26080 #if !defined(HAVE_native_mpfq_fixmp_8_5_addmul1_shortz)
26081 /* x has 8.5 words, z has 9.
26082  * Put (z+x*c) in z. Return carry word. */
26083 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
26084 /* Triggered by: 8_5_redc, 8_5_redc_ur */
26085 static inline
mpfq_fixmp_8_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26086 mp_limb_t mpfq_fixmp_8_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26087 {
26088     mp_limb_t hi, lo, carry, buf;
26089     carry = 0;
26090     mpfq_umul_ppmm(hi,lo,c,x[0]);
26091     lo += carry;
26092     carry = (lo<carry) + hi;
26093     buf = z[0];
26094     lo += buf;
26095     carry += (lo<buf);
26096     z[0] = lo;
26097     mpfq_umul_ppmm(hi,lo,c,x[1]);
26098     lo += carry;
26099     carry = (lo<carry) + hi;
26100     buf = z[1];
26101     lo += buf;
26102     carry += (lo<buf);
26103     z[1] = lo;
26104     mpfq_umul_ppmm(hi,lo,c,x[2]);
26105     lo += carry;
26106     carry = (lo<carry) + hi;
26107     buf = z[2];
26108     lo += buf;
26109     carry += (lo<buf);
26110     z[2] = lo;
26111     mpfq_umul_ppmm(hi,lo,c,x[3]);
26112     lo += carry;
26113     carry = (lo<carry) + hi;
26114     buf = z[3];
26115     lo += buf;
26116     carry += (lo<buf);
26117     z[3] = lo;
26118     mpfq_umul_ppmm(hi,lo,c,x[4]);
26119     lo += carry;
26120     carry = (lo<carry) + hi;
26121     buf = z[4];
26122     lo += buf;
26123     carry += (lo<buf);
26124     z[4] = lo;
26125     mpfq_umul_ppmm(hi,lo,c,x[5]);
26126     lo += carry;
26127     carry = (lo<carry) + hi;
26128     buf = z[5];
26129     lo += buf;
26130     carry += (lo<buf);
26131     z[5] = lo;
26132     mpfq_umul_ppmm(hi,lo,c,x[6]);
26133     lo += carry;
26134     carry = (lo<carry) + hi;
26135     buf = z[6];
26136     lo += buf;
26137     carry += (lo<buf);
26138     z[6] = lo;
26139     mpfq_umul_ppmm(hi,lo,c,x[7]);
26140     lo += carry;
26141     carry = (lo<carry) + hi;
26142     buf = z[7];
26143     lo += buf;
26144     carry += (lo<buf);
26145     z[7] = lo;
26146     mpfq_umul_ppmm(hi,lo,c,x[8]);
26147     lo += carry;
26148     carry = (lo<carry) + hi;
26149     buf = z[8];
26150     lo += buf;
26151     carry += (lo<buf);
26152     z[8] = lo;
26153     return carry;
26154 }
26155 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_addmul1_shortz) */
26156 
26157 #if !defined(HAVE_native_mpfq_fixmp_8_5_addmul05_nc)
26158 /* x has 8.5 words, z has 9. c is 0.5 word.
26159  * Put (z+x*c) in z. Carry bit is lost. */
26160 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
26161 /* Triggered by: 8_5_mul, 8_5_mgy_decode */
26162 static inline
mpfq_fixmp_8_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26163 void mpfq_fixmp_8_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26164 {
26165     mp_limb_t hi, lo, carry, buf;
26166     carry = 0;
26167     mpfq_umul_ppmm(hi,lo,c,x[0]);
26168     lo += carry;
26169     carry = (lo<carry) + hi;
26170     buf = z[0];
26171     lo += buf;
26172     carry += (lo<buf);
26173     z[0] = lo;
26174     mpfq_umul_ppmm(hi,lo,c,x[1]);
26175     lo += carry;
26176     carry = (lo<carry) + hi;
26177     buf = z[1];
26178     lo += buf;
26179     carry += (lo<buf);
26180     z[1] = lo;
26181     mpfq_umul_ppmm(hi,lo,c,x[2]);
26182     lo += carry;
26183     carry = (lo<carry) + hi;
26184     buf = z[2];
26185     lo += buf;
26186     carry += (lo<buf);
26187     z[2] = lo;
26188     mpfq_umul_ppmm(hi,lo,c,x[3]);
26189     lo += carry;
26190     carry = (lo<carry) + hi;
26191     buf = z[3];
26192     lo += buf;
26193     carry += (lo<buf);
26194     z[3] = lo;
26195     mpfq_umul_ppmm(hi,lo,c,x[4]);
26196     lo += carry;
26197     carry = (lo<carry) + hi;
26198     buf = z[4];
26199     lo += buf;
26200     carry += (lo<buf);
26201     z[4] = lo;
26202     mpfq_umul_ppmm(hi,lo,c,x[5]);
26203     lo += carry;
26204     carry = (lo<carry) + hi;
26205     buf = z[5];
26206     lo += buf;
26207     carry += (lo<buf);
26208     z[5] = lo;
26209     mpfq_umul_ppmm(hi,lo,c,x[6]);
26210     lo += carry;
26211     carry = (lo<carry) + hi;
26212     buf = z[6];
26213     lo += buf;
26214     carry += (lo<buf);
26215     z[6] = lo;
26216     mpfq_umul_ppmm(hi,lo,c,x[7]);
26217     lo += carry;
26218     carry = (lo<carry) + hi;
26219     buf = z[7];
26220     lo += buf;
26221     carry += (lo<buf);
26222     z[7] = lo;
26223     lo = c*x[8] + carry;
26224     assert(lo >= carry);
26225     z[8] += lo;
26226 }
26227 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_addmul05_nc) */
26228 
26229 #if !defined(HAVE_native_mpfq_fixmp_8_5_mul)
26230 /* x and y have 8.5 words, z has 17. Put x*y in z. */
26231 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
26232 /* Triggered by: 8_5_mgy_decode */
26233 static inline
mpfq_fixmp_8_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26234 void mpfq_fixmp_8_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26235 {
26236     assert(z != x && z != y);
26237     for (int i = 0; i < 17; z[i++] = 0) ;
26238     mpfq_fixmp_8_5_addmul1_nc (z + 0, x, y[0]);
26239     mpfq_fixmp_8_5_addmul1_nc (z + 1, x, y[1]);
26240     mpfq_fixmp_8_5_addmul1_nc (z + 2, x, y[2]);
26241     mpfq_fixmp_8_5_addmul1_nc (z + 3, x, y[3]);
26242     mpfq_fixmp_8_5_addmul1_nc (z + 4, x, y[4]);
26243     mpfq_fixmp_8_5_addmul1_nc (z + 5, x, y[5]);
26244     mpfq_fixmp_8_5_addmul1_nc (z + 6, x, y[6]);
26245     mpfq_fixmp_8_5_addmul1_nc (z + 7, x, y[7]);
26246     mpfq_fixmp_8_5_addmul05_nc (z + 8, x, y[8]);
26247 }
26248 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mul) */
26249 
26250 #if !defined(HAVE_native_mpfq_fixmp_8_5_sqr)
26251 /* x has 8.5 words, z has 17. Put x*y in z. */
26252 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
26253 static inline
mpfq_fixmp_8_5_sqr(mp_limb_t * z,const mp_limb_t * x)26254 void mpfq_fixmp_8_5_sqr(mp_limb_t * z, const mp_limb_t * x)
26255 {
26256     mp_limb_t buf[17] = {0,};
26257     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
26258     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
26259     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
26260     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
26261     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
26262     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
26263     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
26264     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
26265     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
26266     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
26267     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
26268     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
26269     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
26270     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
26271     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
26272     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
26273     z[2*8] = x[8] * x[8];
26274     mpn_lshift(buf, buf, 17, 1);
26275     mpn_add_n(z, z, buf, 17);
26276 }
26277 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_sqr) */
26278 
26279 #if !defined(HAVE_native_mpfq_fixmp_8_5_mul1)
26280 /* x has 8.5 words, z has 10. Put x*y in z. */
26281 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
26282 static inline
mpfq_fixmp_8_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26283 void mpfq_fixmp_8_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26284 {
26285     mp_limb_t hi, lo, carry;
26286     carry = 0;
26287     mpfq_umul_ppmm(hi,lo,c,x[0]);
26288     lo += carry;
26289     carry = (lo<carry) + hi;
26290     z[0] = lo;
26291     mpfq_umul_ppmm(hi,lo,c,x[1]);
26292     lo += carry;
26293     carry = (lo<carry) + hi;
26294     z[1] = lo;
26295     mpfq_umul_ppmm(hi,lo,c,x[2]);
26296     lo += carry;
26297     carry = (lo<carry) + hi;
26298     z[2] = lo;
26299     mpfq_umul_ppmm(hi,lo,c,x[3]);
26300     lo += carry;
26301     carry = (lo<carry) + hi;
26302     z[3] = lo;
26303     mpfq_umul_ppmm(hi,lo,c,x[4]);
26304     lo += carry;
26305     carry = (lo<carry) + hi;
26306     z[4] = lo;
26307     mpfq_umul_ppmm(hi,lo,c,x[5]);
26308     lo += carry;
26309     carry = (lo<carry) + hi;
26310     z[5] = lo;
26311     mpfq_umul_ppmm(hi,lo,c,x[6]);
26312     lo += carry;
26313     carry = (lo<carry) + hi;
26314     z[6] = lo;
26315     mpfq_umul_ppmm(hi,lo,c,x[7]);
26316     lo += carry;
26317     carry = (lo<carry) + hi;
26318     z[7] = lo;
26319     mpfq_umul_ppmm(hi,lo,c,x[8]);
26320     lo += carry;
26321     carry = (lo<carry) + hi;
26322     z[8] = lo;
26323     z[9] = carry;
26324 }
26325 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mul1) */
26326 
26327 #if !defined(HAVE_native_mpfq_fixmp_8_5_shortmul)
26328 /* x and y have 8.5 words, z has 9.
26329  * Put the low 9 words of x*y in z. */
26330 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
26331 static inline
mpfq_fixmp_8_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26332 void mpfq_fixmp_8_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26333 {
26334     mpfq_zero(z, 9);
26335     mpfq_fixmp_8_addmul1_nc (z+0, x, y[0]);
26336     z[9-1] += x[8]*y[0];
26337     mpfq_fixmp_7_addmul1_nc (z+1, x, y[1]);
26338     z[9-1] += x[7]*y[1];
26339     mpfq_fixmp_6_addmul1_nc (z+2, x, y[2]);
26340     z[9-1] += x[6]*y[2];
26341     mpfq_fixmp_5_addmul1_nc (z+3, x, y[3]);
26342     z[9-1] += x[5]*y[3];
26343     mpfq_fixmp_4_addmul1_nc (z+4, x, y[4]);
26344     z[9-1] += x[4]*y[4];
26345     mpfq_fixmp_3_addmul1_nc (z+5, x, y[5]);
26346     z[9-1] += x[3]*y[5];
26347     mpfq_fixmp_2_addmul1_nc (z+6, x, y[6]);
26348     z[9-1] += x[2]*y[6];
26349     mpfq_fixmp_1_addmul1_nc (z+7, x, y[7]);
26350     z[9-1] += x[1]*y[7];
26351     z[9-1] += x[0]*y[9-1];
26352 }
26353 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_shortmul) */
26354 
26355 #if !defined(HAVE_native_mpfq_fixmp_8_5_addmul05)
26356 /* x has 8.5 words, z has 9. c is 0.5 word.
26357  * Put (z+x*c) in z. Return carry bit. */
26358 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
26359 static inline
mpfq_fixmp_8_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26360 mp_limb_t mpfq_fixmp_8_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26361 {
26362     mp_limb_t hi, lo, carry, buf;
26363     carry = 0;
26364     mpfq_umul_ppmm(hi,lo,c,x[0]);
26365     lo += carry;
26366     carry = (lo<carry) + hi;
26367     buf = z[0];
26368     lo += buf;
26369     carry += (lo<buf);
26370     z[0] = lo;
26371     mpfq_umul_ppmm(hi,lo,c,x[1]);
26372     lo += carry;
26373     carry = (lo<carry) + hi;
26374     buf = z[1];
26375     lo += buf;
26376     carry += (lo<buf);
26377     z[1] = lo;
26378     mpfq_umul_ppmm(hi,lo,c,x[2]);
26379     lo += carry;
26380     carry = (lo<carry) + hi;
26381     buf = z[2];
26382     lo += buf;
26383     carry += (lo<buf);
26384     z[2] = lo;
26385     mpfq_umul_ppmm(hi,lo,c,x[3]);
26386     lo += carry;
26387     carry = (lo<carry) + hi;
26388     buf = z[3];
26389     lo += buf;
26390     carry += (lo<buf);
26391     z[3] = lo;
26392     mpfq_umul_ppmm(hi,lo,c,x[4]);
26393     lo += carry;
26394     carry = (lo<carry) + hi;
26395     buf = z[4];
26396     lo += buf;
26397     carry += (lo<buf);
26398     z[4] = lo;
26399     mpfq_umul_ppmm(hi,lo,c,x[5]);
26400     lo += carry;
26401     carry = (lo<carry) + hi;
26402     buf = z[5];
26403     lo += buf;
26404     carry += (lo<buf);
26405     z[5] = lo;
26406     mpfq_umul_ppmm(hi,lo,c,x[6]);
26407     lo += carry;
26408     carry = (lo<carry) + hi;
26409     buf = z[6];
26410     lo += buf;
26411     carry += (lo<buf);
26412     z[6] = lo;
26413     mpfq_umul_ppmm(hi,lo,c,x[7]);
26414     lo += carry;
26415     carry = (lo<carry) + hi;
26416     buf = z[7];
26417     lo += buf;
26418     carry += (lo<buf);
26419     z[7] = lo;
26420     lo = c*x[8] + carry;
26421     assert(lo >= carry);
26422     z[8] += lo;
26423     return z[8] < lo;
26424 }
26425 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_addmul05) */
26426 
26427 #if !defined(HAVE_native_mpfq_fixmp_8_5_mul05)
26428 /* x has 8.5 words, z has 9. c is 0.5 word.
26429  * Put (x*c) in z. No carry. */
26430 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
26431 static inline
mpfq_fixmp_8_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)26432 void mpfq_fixmp_8_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
26433 {
26434     mp_limb_t hi, lo, carry;
26435     carry = 0;
26436     mpfq_umul_ppmm(hi,lo,c,x[0]);
26437     lo += carry;
26438     carry = (lo<carry) + hi;
26439     z[0] = lo;
26440     mpfq_umul_ppmm(hi,lo,c,x[1]);
26441     lo += carry;
26442     carry = (lo<carry) + hi;
26443     z[1] = lo;
26444     mpfq_umul_ppmm(hi,lo,c,x[2]);
26445     lo += carry;
26446     carry = (lo<carry) + hi;
26447     z[2] = lo;
26448     mpfq_umul_ppmm(hi,lo,c,x[3]);
26449     lo += carry;
26450     carry = (lo<carry) + hi;
26451     z[3] = lo;
26452     mpfq_umul_ppmm(hi,lo,c,x[4]);
26453     lo += carry;
26454     carry = (lo<carry) + hi;
26455     z[4] = lo;
26456     mpfq_umul_ppmm(hi,lo,c,x[5]);
26457     lo += carry;
26458     carry = (lo<carry) + hi;
26459     z[5] = lo;
26460     mpfq_umul_ppmm(hi,lo,c,x[6]);
26461     lo += carry;
26462     carry = (lo<carry) + hi;
26463     z[6] = lo;
26464     mpfq_umul_ppmm(hi,lo,c,x[7]);
26465     lo += carry;
26466     carry = (lo<carry) + hi;
26467     z[7] = lo;
26468     lo = c*x[8] + carry;
26469     assert(lo >= carry);
26470     z[8] = lo;
26471 }
26472 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mul05) */
26473 
26474 #if !defined(HAVE_native_mpfq_fixmp_8_5_mod)
26475 /* x has 17 words. z and p have 8.5 words, and the high word of p is non-zero.
26476  * Put x mod p in z. */
26477 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
26478 /* Triggered by: 8_5_mgy_decode */
26479 static inline
mpfq_fixmp_8_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)26480 void mpfq_fixmp_8_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
26481 {
26482     mp_limb_t q[8+1], r[9];
26483     assert (p[9-1] != 0);
26484     mpn_tdiv_qr(q, r, 0, x, 17, p, 9);
26485     mpfq_copy(z, r, 9);
26486 }
26487 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mod) */
26488 
26489 #if !defined(HAVE_native_mpfq_fixmp_8_5_rshift)
26490 /* a has 8.5 words. Shift it in place by cnt bits to the right.
26491  * The shift count cnt must not exceed the word size.
26492  * Note that no carry is returned for the bits shifted out. */
26493 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
26494 /* Triggered by: 8_5_invmod */
26495 static inline
mpfq_fixmp_8_5_rshift(mp_limb_t * a,int cnt)26496 void mpfq_fixmp_8_5_rshift(mp_limb_t * a, int cnt)
26497 {
26498     if (!cnt) return;
26499     int i;
26500     int dnt = GMP_NUMB_BITS - cnt;
26501     for (i = 0; i < 9-1; ++i) {
26502         a[i] >>= cnt;
26503         a[i] |= (a[i+1] << dnt);
26504     }
26505     a[9-1] >>= cnt;
26506 }
26507 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_rshift) */
26508 
26509 #if !defined(HAVE_native_mpfq_fixmp_8_5_long_rshift)
26510 /* a has 8.5 words. Shift it in place by off words plus cnt bits to the left.
26511  * Note that no carry is returned for the bits shifted out. */
26512 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
26513 /* Triggered by: 8_5_invmod */
26514 static inline
mpfq_fixmp_8_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)26515 void mpfq_fixmp_8_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
26516 {
26517     if (cnt) {
26518         int dnt = GMP_NUMB_BITS - cnt;
26519         for (int i = 0; i < 9 - off - 1; ++i) {
26520             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
26521         }
26522         a[9-off-1] = a[9-1]>>cnt;
26523     } else {
26524         mpfq_copyi(a, a + off, 9 - off);
26525     }
26526     mpfq_zero(a + 9 - off, off);
26527 }
26528 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_long_rshift) */
26529 
26530 #if !defined(HAVE_native_mpfq_fixmp_8_5_long_lshift)
26531 /* a has 8.5 words. Shift it in place by off words plus cnt bits to the left.
26532  * Note that no carry is returned for the bits shifted out. */
26533 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
26534 /* Triggered by: 8_5_invmod */
26535 static inline
mpfq_fixmp_8_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)26536 void mpfq_fixmp_8_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
26537 {
26538     int i;
26539     if (cnt) {
26540         int dnt = GMP_NUMB_BITS - cnt;
26541         for (i = 9-1; i>off; --i) {
26542             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
26543         }
26544         a[off] = a[0]<<cnt;
26545     } else {
26546         mpfq_copyd(a + off, a, 9 - off);
26547     }
26548     mpfq_zero(a, off);
26549 }
26550 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_long_lshift) */
26551 
26552 #if !defined(HAVE_native_mpfq_fixmp_8_5_invmod)
26553 /* x, z, and p have 8.5 words. Put inverse of x mod p in z.
26554  * Return non-zero if an inverse could be found.
26555  * If no inverse could be found, return 0 and set z to zero.
26556  */
26557 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
26558 static inline
mpfq_fixmp_8_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)26559 int mpfq_fixmp_8_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
26560 {
26561       mp_limb_t u[9], v[9], a[9], b[9], fix[9];
26562       int i, t, lsh;
26563 
26564       mpfq_zero(u, 9);
26565       mpfq_zero(v, 9);
26566       mpfq_copy(a, x, 9);
26567       mpfq_copy(b, p, 9);
26568       u[0] = 1UL;
26569 
26570       if (mpfq_fixmp_8_5_cmp(a, v) == 0 || mpfq_fixmp_8_5_cmp(a, b) == 0) {
26571         mpfq_zero(res, 9);
26572         return 0;
26573       }
26574 
26575       mpfq_fixmp_8_5_add(fix, b, u);
26576       mpfq_fixmp_8_5_rshift(fix, 1);
26577 
26578       assert (mpfq_fixmp_8_5_cmp(a,b) < 0);
26579 
26580       t = 0;
26581 
26582       for(i = 0 ; !a[i] ; i++) ;
26583       assert (i < 9);
26584       lsh = mpfq_ctzl(a[i]);
26585       mpfq_fixmp_8_5_long_rshift(a, i, lsh);
26586       t += lsh + i*GMP_NUMB_BITS;
26587       mpfq_fixmp_8_5_long_lshift(v, i, lsh);
26588 
26589       do {
26590         do {
26591           mpfq_fixmp_8_5_sub(b, b, a);
26592           mpfq_fixmp_8_5_add(v, v, u);
26593           for(i = 0 ; !b[i] ; i++) ;
26594           assert (i < 9);
26595           lsh = mpfq_ctzl(b[i]);
26596           mpfq_fixmp_8_5_long_rshift(b, i, lsh);
26597           t += lsh + i*GMP_NUMB_BITS;
26598           mpfq_fixmp_8_5_long_lshift(u, i, lsh);
26599         } while (mpfq_fixmp_8_5_cmp(a,b) < 0);
26600         if (mpfq_fixmp_8_5_cmp(a, b) == 0)
26601           break;
26602         do {
26603           mpfq_fixmp_8_5_sub(a, a, b);
26604           mpfq_fixmp_8_5_add(u, u, v);
26605           for(i = 0 ; !a[i] ; i++) ;
26606           assert (i < 9);
26607           lsh = mpfq_ctzl(a[i]);
26608           mpfq_fixmp_8_5_long_rshift(a, i, lsh);
26609           t += lsh + i*GMP_NUMB_BITS;
26610           mpfq_fixmp_8_5_long_lshift(v, i, lsh);
26611         } while (mpfq_fixmp_8_5_cmp(b,a)<0);
26612       } while (mpfq_fixmp_8_5_cmp(a,b) != 0);
26613       {
26614         if (mpfq_fixmp_8_5_cmp_ui(a, 1) != 0) {
26615           mpfq_copy(res, a, 9);
26616           return 0;
26617         }
26618       }
26619       while (t>0) {
26620         mp_limb_t sig = u[0] & 1UL;
26621         mpfq_fixmp_8_5_rshift(u, 1);
26622         if (sig)
26623           mpfq_fixmp_8_5_add(u, u, fix);
26624         --t;
26625       }
26626       mpfq_copy(res, u, 9);
26627       return 1;
26628 }
26629 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_invmod) */
26630 
26631 #if !defined(HAVE_native_mpfq_fixmp_8_5_redc)
26632 /* x has 17 words, z and p have 8.5 words.
26633  * only one word is read from invp.
26634  * Assuming R=W^9 is the redc modulus, we expect that x verifies:
26635  *   x < R*p,
26636  * so that we have eventually z < p, z congruent to x/R mod p.
26637  * The contents of the area pointed by x are clobbered by this call.
26638  * Note also that x may alias z.
26639  */
26640 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
26641 static inline
mpfq_fixmp_8_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)26642 void mpfq_fixmp_8_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
26643 {
26644     mp_limb_t cy;
26645     for(int i = 0; i < 9; ++i) {
26646         mp_limb_t t = x[i]*mip[0];
26647         cy = mpfq_fixmp_8_5_addmul1_shortz(x+i, p, t);
26648         assert (x[i] == 0);
26649         x[i] = cy;
26650     }
26651     {
26652         mp_limb_t ret[9] = { x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], 0 };
26653         cy = mpfq_fixmp_8_5_add(x, x, ret);
26654     }
26655     /* At this point, we have (x' denotes x + cy*W^n here)
26656     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
26657     * x'/R < p + p
26658     */
26659     if (cy || mpfq_fixmp_8_5_cmp(x, p) >= 0) {
26660         mpfq_fixmp_8_5_sub(z, x, p);
26661     } else {
26662         mpfq_copy(z, x, 9);
26663     }
26664 }
26665 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_redc) */
26666 
26667 #if !defined(HAVE_native_mpfq_fixmp_8_5_redc_ur)
26668 /* x has 18 words, z and p have 8.5 words.
26669  * only one word is read from invp.
26670  * Assuming R=W^9 is the redc modulus, we expect that x verifies:
26671  *  x < W*W^8.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
26672  * so that we have eventually z < p, z congruent to x/R mod p.
26673  * The contents of the area pointed by x are clobbered by this call.
26674  * Note also that x may alias z.
26675  */
26676 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
26677 static inline
mpfq_fixmp_8_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)26678 void mpfq_fixmp_8_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
26679 {
26680     mp_limb_t cy, q[1];
26681     for(int i = 0; i < 9; ++i) {
26682         mp_limb_t t = x[i]*mip[0];
26683         cy = mpfq_fixmp_8_5_addmul1_shortz(x+i, p, t);
26684         assert (x[i] == 0);
26685         x[i] = cy;
26686     }
26687     cy = mpfq_fixmp_8_5_add(x + 9, x, x + 9);
26688     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
26689     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
26690     * x'/R < (W^0.5+1)*p
26691     */
26692     if (cy) {
26693         /* x'/R-p < W^0.5*p, which fits in n words. */
26694         mpfq_fixmp_8_5_sub(x + 9, x + 9, p);
26695     }
26696     mpn_tdiv_qr(q, z, 0, x + 9, 9, p, 9);
26697 }
26698 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_redc_ur) */
26699 
26700 #if !defined(HAVE_native_mpfq_fixmp_8_5_mgy_encode)
26701 /* x, z, and p have 8.5 words.
26702  * Assuming R=W^9 is the redc modulus, we compute z=R*x mod p. */
26703 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
26704 static inline
mpfq_fixmp_8_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)26705 void mpfq_fixmp_8_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
26706 {
26707     mp_limb_t t[18] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8] };
26708     mp_limb_t qq[9+1];
26709     mpn_tdiv_qr(qq, z, 0, t, 18, p, 9);
26710 }
26711 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mgy_encode) */
26712 
26713 #if !defined(HAVE_native_mpfq_fixmp_8_5_mgy_decode)
26714 /* x, z, invR, and p have 8.5 words.
26715  * Assuming R=W^9 is the redc modulus, we compute z=x/R mod p. */
26716 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
26717 static inline
mpfq_fixmp_8_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)26718 void mpfq_fixmp_8_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
26719 {
26720     mp_limb_t t[18];
26721     mpfq_fixmp_8_5_mul(t, x, invR);
26722     mpfq_fixmp_8_5_mod(z, t, p);
26723 }
26724 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_mgy_decode) */
26725 
26726 #if !defined(HAVE_native_mpfq_fixmp_8_5_lshift)
26727 /* a has 8.5 words. Shift it in place by cnt bits to the left.
26728  * The shift count cnt must not exceed the word size.
26729  * Note that no carry is returned for the bits shifted out. */
26730 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
26731 static inline
mpfq_fixmp_8_5_lshift(mp_limb_t * a,int cnt)26732 void mpfq_fixmp_8_5_lshift(mp_limb_t * a, int cnt)
26733 {
26734     if (!cnt) return;
26735     int i;
26736     int dnt = GMP_NUMB_BITS - cnt;
26737     for (i = 9-1; i>0; --i) {
26738         a[i] <<= cnt;
26739         a[i] |= (a[i-1] >> dnt);
26740     }
26741     a[0] <<= cnt;
26742 }
26743 #endif /* !defined(HAVE_native_mpfq_fixmp_8_5_lshift) */
26744 
26745 #if !defined(HAVE_native_mpfq_fixmp_9_5_add)
26746 /* x, y, and z have 9.5 words. Result in z. Return carry bit */
26747 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
26748 /* Triggered by: 9_5_invmod, 9_5_redc, 9_5_redc_ur */
26749 static inline
mpfq_fixmp_9_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26750 mp_limb_t mpfq_fixmp_9_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26751 {
26752     mp_limb_t r, s, t, cy, cy1, cy2;
26753     cy = 0;
26754     r = x[0];
26755     s = r + y[0];
26756     cy1 = s < r;
26757     t = s + cy;
26758     cy2 = t < s;
26759     cy = cy1 | cy2;
26760     z[0] = t;
26761     r = x[1];
26762     s = r + y[1];
26763     cy1 = s < r;
26764     t = s + cy;
26765     cy2 = t < s;
26766     cy = cy1 | cy2;
26767     z[1] = t;
26768     r = x[2];
26769     s = r + y[2];
26770     cy1 = s < r;
26771     t = s + cy;
26772     cy2 = t < s;
26773     cy = cy1 | cy2;
26774     z[2] = t;
26775     r = x[3];
26776     s = r + y[3];
26777     cy1 = s < r;
26778     t = s + cy;
26779     cy2 = t < s;
26780     cy = cy1 | cy2;
26781     z[3] = t;
26782     r = x[4];
26783     s = r + y[4];
26784     cy1 = s < r;
26785     t = s + cy;
26786     cy2 = t < s;
26787     cy = cy1 | cy2;
26788     z[4] = t;
26789     r = x[5];
26790     s = r + y[5];
26791     cy1 = s < r;
26792     t = s + cy;
26793     cy2 = t < s;
26794     cy = cy1 | cy2;
26795     z[5] = t;
26796     r = x[6];
26797     s = r + y[6];
26798     cy1 = s < r;
26799     t = s + cy;
26800     cy2 = t < s;
26801     cy = cy1 | cy2;
26802     z[6] = t;
26803     r = x[7];
26804     s = r + y[7];
26805     cy1 = s < r;
26806     t = s + cy;
26807     cy2 = t < s;
26808     cy = cy1 | cy2;
26809     z[7] = t;
26810     r = x[8];
26811     s = r + y[8];
26812     cy1 = s < r;
26813     t = s + cy;
26814     cy2 = t < s;
26815     cy = cy1 | cy2;
26816     z[8] = t;
26817     r = x[9];
26818     s = r + y[9];
26819     cy1 = s < r;
26820     t = s + cy;
26821     cy2 = t < s;
26822     cy = cy1 | cy2;
26823     z[9] = t;
26824     return cy;
26825 }
26826 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_add) */
26827 
26828 #if !defined(HAVE_native_mpfq_fixmp_9_5_sub)
26829 /* x, y, and z have 9.5 words. Result in z. Return borrow bit */
26830 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
26831 /* Triggered by: 9_5_invmod, 9_5_redc, 9_5_redc_ur */
26832 static inline
mpfq_fixmp_9_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26833 mp_limb_t mpfq_fixmp_9_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26834 {
26835     mp_limb_t r, s, t, cy, cy1, cy2;
26836     cy = 0;
26837     r = x[0];
26838     s = r - y[0];
26839     cy1 = s > r;
26840     t = s - cy;
26841     cy2 = t > s;
26842     cy = cy1 | cy2;
26843     z[0] = t;
26844     r = x[1];
26845     s = r - y[1];
26846     cy1 = s > r;
26847     t = s - cy;
26848     cy2 = t > s;
26849     cy = cy1 | cy2;
26850     z[1] = t;
26851     r = x[2];
26852     s = r - y[2];
26853     cy1 = s > r;
26854     t = s - cy;
26855     cy2 = t > s;
26856     cy = cy1 | cy2;
26857     z[2] = t;
26858     r = x[3];
26859     s = r - y[3];
26860     cy1 = s > r;
26861     t = s - cy;
26862     cy2 = t > s;
26863     cy = cy1 | cy2;
26864     z[3] = t;
26865     r = x[4];
26866     s = r - y[4];
26867     cy1 = s > r;
26868     t = s - cy;
26869     cy2 = t > s;
26870     cy = cy1 | cy2;
26871     z[4] = t;
26872     r = x[5];
26873     s = r - y[5];
26874     cy1 = s > r;
26875     t = s - cy;
26876     cy2 = t > s;
26877     cy = cy1 | cy2;
26878     z[5] = t;
26879     r = x[6];
26880     s = r - y[6];
26881     cy1 = s > r;
26882     t = s - cy;
26883     cy2 = t > s;
26884     cy = cy1 | cy2;
26885     z[6] = t;
26886     r = x[7];
26887     s = r - y[7];
26888     cy1 = s > r;
26889     t = s - cy;
26890     cy2 = t > s;
26891     cy = cy1 | cy2;
26892     z[7] = t;
26893     r = x[8];
26894     s = r - y[8];
26895     cy1 = s > r;
26896     t = s - cy;
26897     cy2 = t > s;
26898     cy = cy1 | cy2;
26899     z[8] = t;
26900     r = x[9];
26901     s = r - y[9];
26902     cy1 = s > r;
26903     t = s - cy;
26904     cy2 = t > s;
26905     cy = cy1 | cy2;
26906     z[9] = t;
26907     return cy;
26908 }
26909 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_sub) */
26910 
26911 #if !defined(HAVE_native_mpfq_fixmp_9_5_add_nc)
26912 /* x, y, and z have 9.5 words. Result in z. Carry bit is lost. */
26913 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
26914 static inline
mpfq_fixmp_9_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26915 void mpfq_fixmp_9_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26916 {
26917     mp_limb_t r, s, t, cy, cy1, cy2;
26918     cy = 0;
26919     r = x[0];
26920     s = r + y[0];
26921     cy1 = s < r;
26922     t = s + cy;
26923     cy2 = t < s;
26924     cy = cy1 | cy2;
26925     z[0] = t;
26926     r = x[1];
26927     s = r + y[1];
26928     cy1 = s < r;
26929     t = s + cy;
26930     cy2 = t < s;
26931     cy = cy1 | cy2;
26932     z[1] = t;
26933     r = x[2];
26934     s = r + y[2];
26935     cy1 = s < r;
26936     t = s + cy;
26937     cy2 = t < s;
26938     cy = cy1 | cy2;
26939     z[2] = t;
26940     r = x[3];
26941     s = r + y[3];
26942     cy1 = s < r;
26943     t = s + cy;
26944     cy2 = t < s;
26945     cy = cy1 | cy2;
26946     z[3] = t;
26947     r = x[4];
26948     s = r + y[4];
26949     cy1 = s < r;
26950     t = s + cy;
26951     cy2 = t < s;
26952     cy = cy1 | cy2;
26953     z[4] = t;
26954     r = x[5];
26955     s = r + y[5];
26956     cy1 = s < r;
26957     t = s + cy;
26958     cy2 = t < s;
26959     cy = cy1 | cy2;
26960     z[5] = t;
26961     r = x[6];
26962     s = r + y[6];
26963     cy1 = s < r;
26964     t = s + cy;
26965     cy2 = t < s;
26966     cy = cy1 | cy2;
26967     z[6] = t;
26968     r = x[7];
26969     s = r + y[7];
26970     cy1 = s < r;
26971     t = s + cy;
26972     cy2 = t < s;
26973     cy = cy1 | cy2;
26974     z[7] = t;
26975     r = x[8];
26976     s = r + y[8];
26977     cy1 = s < r;
26978     t = s + cy;
26979     cy2 = t < s;
26980     cy = cy1 | cy2;
26981     z[8] = t;
26982     r = x[9];
26983     s = r + y[9];
26984     cy1 = s < r;
26985     t = s + cy;
26986     cy2 = t < s;
26987     cy = cy1 | cy2;
26988     z[9] = t;
26989 }
26990 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_add_nc) */
26991 
26992 #if !defined(HAVE_native_mpfq_fixmp_9_5_sub_nc)
26993 /* x, y, and z have 9.5 words. Result in z. Borrow bit is lost. */
26994 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
26995 static inline
mpfq_fixmp_9_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)26996 void mpfq_fixmp_9_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
26997 {
26998     mp_limb_t r, s, t, cy, cy1, cy2;
26999     cy = 0;
27000     r = x[0];
27001     s = r - y[0];
27002     cy1 = s > r;
27003     t = s - cy;
27004     cy2 = t > s;
27005     cy = cy1 | cy2;
27006     z[0] = t;
27007     r = x[1];
27008     s = r - y[1];
27009     cy1 = s > r;
27010     t = s - cy;
27011     cy2 = t > s;
27012     cy = cy1 | cy2;
27013     z[1] = t;
27014     r = x[2];
27015     s = r - y[2];
27016     cy1 = s > r;
27017     t = s - cy;
27018     cy2 = t > s;
27019     cy = cy1 | cy2;
27020     z[2] = t;
27021     r = x[3];
27022     s = r - y[3];
27023     cy1 = s > r;
27024     t = s - cy;
27025     cy2 = t > s;
27026     cy = cy1 | cy2;
27027     z[3] = t;
27028     r = x[4];
27029     s = r - y[4];
27030     cy1 = s > r;
27031     t = s - cy;
27032     cy2 = t > s;
27033     cy = cy1 | cy2;
27034     z[4] = t;
27035     r = x[5];
27036     s = r - y[5];
27037     cy1 = s > r;
27038     t = s - cy;
27039     cy2 = t > s;
27040     cy = cy1 | cy2;
27041     z[5] = t;
27042     r = x[6];
27043     s = r - y[6];
27044     cy1 = s > r;
27045     t = s - cy;
27046     cy2 = t > s;
27047     cy = cy1 | cy2;
27048     z[6] = t;
27049     r = x[7];
27050     s = r - y[7];
27051     cy1 = s > r;
27052     t = s - cy;
27053     cy2 = t > s;
27054     cy = cy1 | cy2;
27055     z[7] = t;
27056     r = x[8];
27057     s = r - y[8];
27058     cy1 = s > r;
27059     t = s - cy;
27060     cy2 = t > s;
27061     cy = cy1 | cy2;
27062     z[8] = t;
27063     r = x[9];
27064     s = r - y[9];
27065     cy1 = s > r;
27066     t = s - cy;
27067     cy2 = t > s;
27068     cy = cy1 | cy2;
27069     z[9] = t;
27070 }
27071 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_sub_nc) */
27072 
27073 #if !defined(HAVE_native_mpfq_fixmp_9_5_add_ui)
27074 /* x, y, and z have 9.5 words. Result in z. Return carry bit */
27075 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
27076 static inline
mpfq_fixmp_9_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)27077 mp_limb_t mpfq_fixmp_9_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
27078 {
27079     mp_limb_t r, s, t, cy, cy1, cy2;
27080     cy = 0;
27081     r = x[0];
27082     s = r + y;
27083     cy1 = s < r;
27084     t = s + cy;
27085     cy2 = t < s;
27086     cy = cy1 | cy2;
27087     z[0] = t;
27088     s = x[1];
27089     t = s + cy;
27090     cy = t < s;
27091     z[1] = t;
27092     s = x[2];
27093     t = s + cy;
27094     cy = t < s;
27095     z[2] = t;
27096     s = x[3];
27097     t = s + cy;
27098     cy = t < s;
27099     z[3] = t;
27100     s = x[4];
27101     t = s + cy;
27102     cy = t < s;
27103     z[4] = t;
27104     s = x[5];
27105     t = s + cy;
27106     cy = t < s;
27107     z[5] = t;
27108     s = x[6];
27109     t = s + cy;
27110     cy = t < s;
27111     z[6] = t;
27112     s = x[7];
27113     t = s + cy;
27114     cy = t < s;
27115     z[7] = t;
27116     s = x[8];
27117     t = s + cy;
27118     cy = t < s;
27119     z[8] = t;
27120     s = x[9];
27121     t = s + cy;
27122     cy = t < s;
27123     z[9] = t;
27124     return cy;
27125 }
27126 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_add_ui) */
27127 
27128 #if !defined(HAVE_native_mpfq_fixmp_9_5_sub_ui)
27129 /* x, y, and z have 9.5 words. Result in z. Return borrow bit */
27130 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
27131 static inline
mpfq_fixmp_9_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)27132 mp_limb_t mpfq_fixmp_9_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
27133 {
27134     mp_limb_t r, s, t, cy, cy1, cy2;
27135     cy = 0;
27136     r = x[0];
27137     s = r - y;
27138     cy1 = s > r;
27139     t = s - cy;
27140     cy2 = t > s;
27141     cy = cy1 | cy2;
27142     z[0] = t;
27143     s = x[1];
27144     t = s - cy;
27145     cy = t > s;
27146     z[1] = t;
27147     s = x[2];
27148     t = s - cy;
27149     cy = t > s;
27150     z[2] = t;
27151     s = x[3];
27152     t = s - cy;
27153     cy = t > s;
27154     z[3] = t;
27155     s = x[4];
27156     t = s - cy;
27157     cy = t > s;
27158     z[4] = t;
27159     s = x[5];
27160     t = s - cy;
27161     cy = t > s;
27162     z[5] = t;
27163     s = x[6];
27164     t = s - cy;
27165     cy = t > s;
27166     z[6] = t;
27167     s = x[7];
27168     t = s - cy;
27169     cy = t > s;
27170     z[7] = t;
27171     s = x[8];
27172     t = s - cy;
27173     cy = t > s;
27174     z[8] = t;
27175     s = x[9];
27176     t = s - cy;
27177     cy = t > s;
27178     z[9] = t;
27179     return cy;
27180 }
27181 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_sub_ui) */
27182 
27183 #if !defined(HAVE_native_mpfq_fixmp_9_5_add_ui_nc)
27184 /* x, y, and z have 9.5 words. Result in z. Carry bit is lost. */
27185 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
27186 static inline
mpfq_fixmp_9_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)27187 void mpfq_fixmp_9_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
27188 {
27189     mp_limb_t r, s, t, cy, cy1, cy2;
27190     cy = 0;
27191     r = x[0];
27192     s = r + y;
27193     cy1 = s < r;
27194     t = s + cy;
27195     cy2 = t < s;
27196     cy = cy1 | cy2;
27197     z[0] = t;
27198     s = x[1];
27199     t = s + cy;
27200     cy = t < s;
27201     z[1] = t;
27202     s = x[2];
27203     t = s + cy;
27204     cy = t < s;
27205     z[2] = t;
27206     s = x[3];
27207     t = s + cy;
27208     cy = t < s;
27209     z[3] = t;
27210     s = x[4];
27211     t = s + cy;
27212     cy = t < s;
27213     z[4] = t;
27214     s = x[5];
27215     t = s + cy;
27216     cy = t < s;
27217     z[5] = t;
27218     s = x[6];
27219     t = s + cy;
27220     cy = t < s;
27221     z[6] = t;
27222     s = x[7];
27223     t = s + cy;
27224     cy = t < s;
27225     z[7] = t;
27226     s = x[8];
27227     t = s + cy;
27228     cy = t < s;
27229     z[8] = t;
27230     s = x[9];
27231     t = s + cy;
27232     cy = t < s;
27233     z[9] = t;
27234 }
27235 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_add_ui_nc) */
27236 
27237 #if !defined(HAVE_native_mpfq_fixmp_9_5_sub_ui_nc)
27238 /* x, y, and z have 9.5 words. Result in z. Borrow bit is lost. */
27239 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
27240 static inline
mpfq_fixmp_9_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)27241 void mpfq_fixmp_9_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
27242 {
27243     mp_limb_t r, s, t, cy, cy1, cy2;
27244     cy = 0;
27245     r = x[0];
27246     s = r - y;
27247     cy1 = s > r;
27248     t = s - cy;
27249     cy2 = t > s;
27250     cy = cy1 | cy2;
27251     z[0] = t;
27252     s = x[1];
27253     t = s - cy;
27254     cy = t > s;
27255     z[1] = t;
27256     s = x[2];
27257     t = s - cy;
27258     cy = t > s;
27259     z[2] = t;
27260     s = x[3];
27261     t = s - cy;
27262     cy = t > s;
27263     z[3] = t;
27264     s = x[4];
27265     t = s - cy;
27266     cy = t > s;
27267     z[4] = t;
27268     s = x[5];
27269     t = s - cy;
27270     cy = t > s;
27271     z[5] = t;
27272     s = x[6];
27273     t = s - cy;
27274     cy = t > s;
27275     z[6] = t;
27276     s = x[7];
27277     t = s - cy;
27278     cy = t > s;
27279     z[7] = t;
27280     s = x[8];
27281     t = s - cy;
27282     cy = t > s;
27283     z[8] = t;
27284     s = x[9];
27285     t = s - cy;
27286     cy = t > s;
27287     z[9] = t;
27288 }
27289 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_sub_ui_nc) */
27290 
27291 #if !defined(HAVE_native_mpfq_fixmp_9_5_cmp)
27292 /* x and y have 9.5 words. Return sign of difference x-y. */
27293 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
27294 /* Triggered by: 9_5_invmod, 9_5_redc, 9_5_redc_ur */
27295 static inline
mpfq_fixmp_9_5_cmp(const mp_limb_t * x,const mp_limb_t * y)27296 int mpfq_fixmp_9_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
27297 {
27298     for (int i = 10-1; i >= 0; --i) {
27299         if (x[i] > y[i]) return 1;
27300         if (x[i] < y[i]) return -1;
27301     }
27302     return 0;
27303 }
27304 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_cmp) */
27305 
27306 #if !defined(HAVE_native_mpfq_fixmp_9_5_cmp_ui)
27307 /* x has 9.5 words. Return sign of difference x-y. */
27308 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
27309 /* Triggered by: 9_5_invmod */
27310 static inline
mpfq_fixmp_9_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)27311 int mpfq_fixmp_9_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
27312 {
27313     for (int i = 10-1; i > 0; --i) {
27314         if (x[i]) return 1;
27315     }
27316     if (x[0]>y) return 1;
27317     if (x[0]<y) return -1;
27318     return 0;
27319 }
27320 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_cmp_ui) */
27321 
27322 #if !defined(HAVE_native_mpfq_fixmp_9_5_addmul1)
27323 /* x has 9.5 words, z has 11.
27324  * Put (z+x*c) in z. Return carry bit. */
27325 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
27326 static inline
mpfq_fixmp_9_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27327 mp_limb_t mpfq_fixmp_9_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27328 {
27329     mp_limb_t hi, lo, carry, buf;
27330     carry = 0;
27331     mpfq_umul_ppmm(hi,lo,c,x[0]);
27332     lo += carry;
27333     carry = (lo<carry) + hi;
27334     buf = z[0];
27335     lo += buf;
27336     carry += (lo<buf);
27337     z[0] = lo;
27338     mpfq_umul_ppmm(hi,lo,c,x[1]);
27339     lo += carry;
27340     carry = (lo<carry) + hi;
27341     buf = z[1];
27342     lo += buf;
27343     carry += (lo<buf);
27344     z[1] = lo;
27345     mpfq_umul_ppmm(hi,lo,c,x[2]);
27346     lo += carry;
27347     carry = (lo<carry) + hi;
27348     buf = z[2];
27349     lo += buf;
27350     carry += (lo<buf);
27351     z[2] = lo;
27352     mpfq_umul_ppmm(hi,lo,c,x[3]);
27353     lo += carry;
27354     carry = (lo<carry) + hi;
27355     buf = z[3];
27356     lo += buf;
27357     carry += (lo<buf);
27358     z[3] = lo;
27359     mpfq_umul_ppmm(hi,lo,c,x[4]);
27360     lo += carry;
27361     carry = (lo<carry) + hi;
27362     buf = z[4];
27363     lo += buf;
27364     carry += (lo<buf);
27365     z[4] = lo;
27366     mpfq_umul_ppmm(hi,lo,c,x[5]);
27367     lo += carry;
27368     carry = (lo<carry) + hi;
27369     buf = z[5];
27370     lo += buf;
27371     carry += (lo<buf);
27372     z[5] = lo;
27373     mpfq_umul_ppmm(hi,lo,c,x[6]);
27374     lo += carry;
27375     carry = (lo<carry) + hi;
27376     buf = z[6];
27377     lo += buf;
27378     carry += (lo<buf);
27379     z[6] = lo;
27380     mpfq_umul_ppmm(hi,lo,c,x[7]);
27381     lo += carry;
27382     carry = (lo<carry) + hi;
27383     buf = z[7];
27384     lo += buf;
27385     carry += (lo<buf);
27386     z[7] = lo;
27387     mpfq_umul_ppmm(hi,lo,c,x[8]);
27388     lo += carry;
27389     carry = (lo<carry) + hi;
27390     buf = z[8];
27391     lo += buf;
27392     carry += (lo<buf);
27393     z[8] = lo;
27394     mpfq_umul_ppmm(hi,lo,c,x[9]);
27395     lo += carry;
27396     carry = (lo<carry) + hi;
27397     buf = z[9];
27398     lo += buf;
27399     carry += (lo<buf);
27400     z[9] = lo;
27401     z[10] += carry;
27402     return (z[10]<carry);
27403 }
27404 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_addmul1) */
27405 
27406 #if !defined(HAVE_native_mpfq_fixmp_9_5_addmul1_nc)
27407 /* x has 9.5 words, z has 11.
27408  * Put (z+x*c) in z. Carry bit is lost. */
27409 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
27410 /* Triggered by: 9_5_mul, 9_5_mgy_decode */
27411 static inline
mpfq_fixmp_9_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27412 void mpfq_fixmp_9_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27413 {
27414     mp_limb_t hi, lo, carry, buf;
27415     carry = 0;
27416     mpfq_umul_ppmm(hi,lo,c,x[0]);
27417     lo += carry;
27418     carry = (lo<carry) + hi;
27419     buf = z[0];
27420     lo += buf;
27421     carry += (lo<buf);
27422     z[0] = lo;
27423     mpfq_umul_ppmm(hi,lo,c,x[1]);
27424     lo += carry;
27425     carry = (lo<carry) + hi;
27426     buf = z[1];
27427     lo += buf;
27428     carry += (lo<buf);
27429     z[1] = lo;
27430     mpfq_umul_ppmm(hi,lo,c,x[2]);
27431     lo += carry;
27432     carry = (lo<carry) + hi;
27433     buf = z[2];
27434     lo += buf;
27435     carry += (lo<buf);
27436     z[2] = lo;
27437     mpfq_umul_ppmm(hi,lo,c,x[3]);
27438     lo += carry;
27439     carry = (lo<carry) + hi;
27440     buf = z[3];
27441     lo += buf;
27442     carry += (lo<buf);
27443     z[3] = lo;
27444     mpfq_umul_ppmm(hi,lo,c,x[4]);
27445     lo += carry;
27446     carry = (lo<carry) + hi;
27447     buf = z[4];
27448     lo += buf;
27449     carry += (lo<buf);
27450     z[4] = lo;
27451     mpfq_umul_ppmm(hi,lo,c,x[5]);
27452     lo += carry;
27453     carry = (lo<carry) + hi;
27454     buf = z[5];
27455     lo += buf;
27456     carry += (lo<buf);
27457     z[5] = lo;
27458     mpfq_umul_ppmm(hi,lo,c,x[6]);
27459     lo += carry;
27460     carry = (lo<carry) + hi;
27461     buf = z[6];
27462     lo += buf;
27463     carry += (lo<buf);
27464     z[6] = lo;
27465     mpfq_umul_ppmm(hi,lo,c,x[7]);
27466     lo += carry;
27467     carry = (lo<carry) + hi;
27468     buf = z[7];
27469     lo += buf;
27470     carry += (lo<buf);
27471     z[7] = lo;
27472     mpfq_umul_ppmm(hi,lo,c,x[8]);
27473     lo += carry;
27474     carry = (lo<carry) + hi;
27475     buf = z[8];
27476     lo += buf;
27477     carry += (lo<buf);
27478     z[8] = lo;
27479     mpfq_umul_ppmm(hi,lo,c,x[9]);
27480     lo += carry;
27481     carry = (lo<carry) + hi;
27482     buf = z[9];
27483     lo += buf;
27484     carry += (lo<buf);
27485     z[9] = lo;
27486     z[10] += carry;
27487 }
27488 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_addmul1_nc) */
27489 
27490 #if !defined(HAVE_native_mpfq_fixmp_9_5_addmul1_shortz)
27491 /* x has 9.5 words, z has 10.
27492  * Put (z+x*c) in z. Return carry word. */
27493 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
27494 /* Triggered by: 9_5_redc, 9_5_redc_ur */
27495 static inline
mpfq_fixmp_9_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27496 mp_limb_t mpfq_fixmp_9_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27497 {
27498     mp_limb_t hi, lo, carry, buf;
27499     carry = 0;
27500     mpfq_umul_ppmm(hi,lo,c,x[0]);
27501     lo += carry;
27502     carry = (lo<carry) + hi;
27503     buf = z[0];
27504     lo += buf;
27505     carry += (lo<buf);
27506     z[0] = lo;
27507     mpfq_umul_ppmm(hi,lo,c,x[1]);
27508     lo += carry;
27509     carry = (lo<carry) + hi;
27510     buf = z[1];
27511     lo += buf;
27512     carry += (lo<buf);
27513     z[1] = lo;
27514     mpfq_umul_ppmm(hi,lo,c,x[2]);
27515     lo += carry;
27516     carry = (lo<carry) + hi;
27517     buf = z[2];
27518     lo += buf;
27519     carry += (lo<buf);
27520     z[2] = lo;
27521     mpfq_umul_ppmm(hi,lo,c,x[3]);
27522     lo += carry;
27523     carry = (lo<carry) + hi;
27524     buf = z[3];
27525     lo += buf;
27526     carry += (lo<buf);
27527     z[3] = lo;
27528     mpfq_umul_ppmm(hi,lo,c,x[4]);
27529     lo += carry;
27530     carry = (lo<carry) + hi;
27531     buf = z[4];
27532     lo += buf;
27533     carry += (lo<buf);
27534     z[4] = lo;
27535     mpfq_umul_ppmm(hi,lo,c,x[5]);
27536     lo += carry;
27537     carry = (lo<carry) + hi;
27538     buf = z[5];
27539     lo += buf;
27540     carry += (lo<buf);
27541     z[5] = lo;
27542     mpfq_umul_ppmm(hi,lo,c,x[6]);
27543     lo += carry;
27544     carry = (lo<carry) + hi;
27545     buf = z[6];
27546     lo += buf;
27547     carry += (lo<buf);
27548     z[6] = lo;
27549     mpfq_umul_ppmm(hi,lo,c,x[7]);
27550     lo += carry;
27551     carry = (lo<carry) + hi;
27552     buf = z[7];
27553     lo += buf;
27554     carry += (lo<buf);
27555     z[7] = lo;
27556     mpfq_umul_ppmm(hi,lo,c,x[8]);
27557     lo += carry;
27558     carry = (lo<carry) + hi;
27559     buf = z[8];
27560     lo += buf;
27561     carry += (lo<buf);
27562     z[8] = lo;
27563     mpfq_umul_ppmm(hi,lo,c,x[9]);
27564     lo += carry;
27565     carry = (lo<carry) + hi;
27566     buf = z[9];
27567     lo += buf;
27568     carry += (lo<buf);
27569     z[9] = lo;
27570     return carry;
27571 }
27572 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_addmul1_shortz) */
27573 
27574 #if !defined(HAVE_native_mpfq_fixmp_9_5_addmul05_nc)
27575 /* x has 9.5 words, z has 10. c is 0.5 word.
27576  * Put (z+x*c) in z. Carry bit is lost. */
27577 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
27578 /* Triggered by: 9_5_mul, 9_5_mgy_decode */
27579 static inline
mpfq_fixmp_9_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27580 void mpfq_fixmp_9_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27581 {
27582     mp_limb_t hi, lo, carry, buf;
27583     carry = 0;
27584     mpfq_umul_ppmm(hi,lo,c,x[0]);
27585     lo += carry;
27586     carry = (lo<carry) + hi;
27587     buf = z[0];
27588     lo += buf;
27589     carry += (lo<buf);
27590     z[0] = lo;
27591     mpfq_umul_ppmm(hi,lo,c,x[1]);
27592     lo += carry;
27593     carry = (lo<carry) + hi;
27594     buf = z[1];
27595     lo += buf;
27596     carry += (lo<buf);
27597     z[1] = lo;
27598     mpfq_umul_ppmm(hi,lo,c,x[2]);
27599     lo += carry;
27600     carry = (lo<carry) + hi;
27601     buf = z[2];
27602     lo += buf;
27603     carry += (lo<buf);
27604     z[2] = lo;
27605     mpfq_umul_ppmm(hi,lo,c,x[3]);
27606     lo += carry;
27607     carry = (lo<carry) + hi;
27608     buf = z[3];
27609     lo += buf;
27610     carry += (lo<buf);
27611     z[3] = lo;
27612     mpfq_umul_ppmm(hi,lo,c,x[4]);
27613     lo += carry;
27614     carry = (lo<carry) + hi;
27615     buf = z[4];
27616     lo += buf;
27617     carry += (lo<buf);
27618     z[4] = lo;
27619     mpfq_umul_ppmm(hi,lo,c,x[5]);
27620     lo += carry;
27621     carry = (lo<carry) + hi;
27622     buf = z[5];
27623     lo += buf;
27624     carry += (lo<buf);
27625     z[5] = lo;
27626     mpfq_umul_ppmm(hi,lo,c,x[6]);
27627     lo += carry;
27628     carry = (lo<carry) + hi;
27629     buf = z[6];
27630     lo += buf;
27631     carry += (lo<buf);
27632     z[6] = lo;
27633     mpfq_umul_ppmm(hi,lo,c,x[7]);
27634     lo += carry;
27635     carry = (lo<carry) + hi;
27636     buf = z[7];
27637     lo += buf;
27638     carry += (lo<buf);
27639     z[7] = lo;
27640     mpfq_umul_ppmm(hi,lo,c,x[8]);
27641     lo += carry;
27642     carry = (lo<carry) + hi;
27643     buf = z[8];
27644     lo += buf;
27645     carry += (lo<buf);
27646     z[8] = lo;
27647     lo = c*x[9] + carry;
27648     assert(lo >= carry);
27649     z[9] += lo;
27650 }
27651 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_addmul05_nc) */
27652 
27653 #if !defined(HAVE_native_mpfq_fixmp_9_5_mul)
27654 /* x and y have 9.5 words, z has 19. Put x*y in z. */
27655 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
27656 /* Triggered by: 9_5_mgy_decode */
27657 static inline
mpfq_fixmp_9_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)27658 void mpfq_fixmp_9_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
27659 {
27660     assert(z != x && z != y);
27661     for (int i = 0; i < 19; z[i++] = 0) ;
27662     mpfq_fixmp_9_5_addmul1_nc (z + 0, x, y[0]);
27663     mpfq_fixmp_9_5_addmul1_nc (z + 1, x, y[1]);
27664     mpfq_fixmp_9_5_addmul1_nc (z + 2, x, y[2]);
27665     mpfq_fixmp_9_5_addmul1_nc (z + 3, x, y[3]);
27666     mpfq_fixmp_9_5_addmul1_nc (z + 4, x, y[4]);
27667     mpfq_fixmp_9_5_addmul1_nc (z + 5, x, y[5]);
27668     mpfq_fixmp_9_5_addmul1_nc (z + 6, x, y[6]);
27669     mpfq_fixmp_9_5_addmul1_nc (z + 7, x, y[7]);
27670     mpfq_fixmp_9_5_addmul1_nc (z + 8, x, y[8]);
27671     mpfq_fixmp_9_5_addmul05_nc (z + 9, x, y[9]);
27672 }
27673 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mul) */
27674 
27675 #if !defined(HAVE_native_mpfq_fixmp_9_5_sqr)
27676 /* x has 9.5 words, z has 19. Put x*y in z. */
27677 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
27678 static inline
mpfq_fixmp_9_5_sqr(mp_limb_t * z,const mp_limb_t * x)27679 void mpfq_fixmp_9_5_sqr(mp_limb_t * z, const mp_limb_t * x)
27680 {
27681     mp_limb_t buf[19] = {0,};
27682     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
27683     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
27684     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
27685     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
27686     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
27687     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
27688     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
27689     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
27690     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
27691     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
27692     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
27693     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
27694     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
27695     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
27696     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
27697     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
27698     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
27699     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
27700     z[2*9] = x[9] * x[9];
27701     mpn_lshift(buf, buf, 19, 1);
27702     mpn_add_n(z, z, buf, 19);
27703 }
27704 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_sqr) */
27705 
27706 #if !defined(HAVE_native_mpfq_fixmp_9_5_mul1)
27707 /* x has 9.5 words, z has 11. Put x*y in z. */
27708 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
27709 static inline
mpfq_fixmp_9_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27710 void mpfq_fixmp_9_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27711 {
27712     mp_limb_t hi, lo, carry;
27713     carry = 0;
27714     mpfq_umul_ppmm(hi,lo,c,x[0]);
27715     lo += carry;
27716     carry = (lo<carry) + hi;
27717     z[0] = lo;
27718     mpfq_umul_ppmm(hi,lo,c,x[1]);
27719     lo += carry;
27720     carry = (lo<carry) + hi;
27721     z[1] = lo;
27722     mpfq_umul_ppmm(hi,lo,c,x[2]);
27723     lo += carry;
27724     carry = (lo<carry) + hi;
27725     z[2] = lo;
27726     mpfq_umul_ppmm(hi,lo,c,x[3]);
27727     lo += carry;
27728     carry = (lo<carry) + hi;
27729     z[3] = lo;
27730     mpfq_umul_ppmm(hi,lo,c,x[4]);
27731     lo += carry;
27732     carry = (lo<carry) + hi;
27733     z[4] = lo;
27734     mpfq_umul_ppmm(hi,lo,c,x[5]);
27735     lo += carry;
27736     carry = (lo<carry) + hi;
27737     z[5] = lo;
27738     mpfq_umul_ppmm(hi,lo,c,x[6]);
27739     lo += carry;
27740     carry = (lo<carry) + hi;
27741     z[6] = lo;
27742     mpfq_umul_ppmm(hi,lo,c,x[7]);
27743     lo += carry;
27744     carry = (lo<carry) + hi;
27745     z[7] = lo;
27746     mpfq_umul_ppmm(hi,lo,c,x[8]);
27747     lo += carry;
27748     carry = (lo<carry) + hi;
27749     z[8] = lo;
27750     mpfq_umul_ppmm(hi,lo,c,x[9]);
27751     lo += carry;
27752     carry = (lo<carry) + hi;
27753     z[9] = lo;
27754     z[10] = carry;
27755 }
27756 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mul1) */
27757 
27758 #if !defined(HAVE_native_mpfq_fixmp_9_5_shortmul)
27759 /* x and y have 9.5 words, z has 10.
27760  * Put the low 10 words of x*y in z. */
27761 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
27762 static inline
mpfq_fixmp_9_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)27763 void mpfq_fixmp_9_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
27764 {
27765     mpfq_zero(z, 10);
27766     mpfq_fixmp_9_addmul1_nc (z+0, x, y[0]);
27767     z[10-1] += x[9]*y[0];
27768     mpfq_fixmp_8_addmul1_nc (z+1, x, y[1]);
27769     z[10-1] += x[8]*y[1];
27770     mpfq_fixmp_7_addmul1_nc (z+2, x, y[2]);
27771     z[10-1] += x[7]*y[2];
27772     mpfq_fixmp_6_addmul1_nc (z+3, x, y[3]);
27773     z[10-1] += x[6]*y[3];
27774     mpfq_fixmp_5_addmul1_nc (z+4, x, y[4]);
27775     z[10-1] += x[5]*y[4];
27776     mpfq_fixmp_4_addmul1_nc (z+5, x, y[5]);
27777     z[10-1] += x[4]*y[5];
27778     mpfq_fixmp_3_addmul1_nc (z+6, x, y[6]);
27779     z[10-1] += x[3]*y[6];
27780     mpfq_fixmp_2_addmul1_nc (z+7, x, y[7]);
27781     z[10-1] += x[2]*y[7];
27782     mpfq_fixmp_1_addmul1_nc (z+8, x, y[8]);
27783     z[10-1] += x[1]*y[8];
27784     z[10-1] += x[0]*y[10-1];
27785 }
27786 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_shortmul) */
27787 
27788 #if !defined(HAVE_native_mpfq_fixmp_9_5_addmul05)
27789 /* x has 9.5 words, z has 10. c is 0.5 word.
27790  * Put (z+x*c) in z. Return carry bit. */
27791 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
27792 static inline
mpfq_fixmp_9_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27793 mp_limb_t mpfq_fixmp_9_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27794 {
27795     mp_limb_t hi, lo, carry, buf;
27796     carry = 0;
27797     mpfq_umul_ppmm(hi,lo,c,x[0]);
27798     lo += carry;
27799     carry = (lo<carry) + hi;
27800     buf = z[0];
27801     lo += buf;
27802     carry += (lo<buf);
27803     z[0] = lo;
27804     mpfq_umul_ppmm(hi,lo,c,x[1]);
27805     lo += carry;
27806     carry = (lo<carry) + hi;
27807     buf = z[1];
27808     lo += buf;
27809     carry += (lo<buf);
27810     z[1] = lo;
27811     mpfq_umul_ppmm(hi,lo,c,x[2]);
27812     lo += carry;
27813     carry = (lo<carry) + hi;
27814     buf = z[2];
27815     lo += buf;
27816     carry += (lo<buf);
27817     z[2] = lo;
27818     mpfq_umul_ppmm(hi,lo,c,x[3]);
27819     lo += carry;
27820     carry = (lo<carry) + hi;
27821     buf = z[3];
27822     lo += buf;
27823     carry += (lo<buf);
27824     z[3] = lo;
27825     mpfq_umul_ppmm(hi,lo,c,x[4]);
27826     lo += carry;
27827     carry = (lo<carry) + hi;
27828     buf = z[4];
27829     lo += buf;
27830     carry += (lo<buf);
27831     z[4] = lo;
27832     mpfq_umul_ppmm(hi,lo,c,x[5]);
27833     lo += carry;
27834     carry = (lo<carry) + hi;
27835     buf = z[5];
27836     lo += buf;
27837     carry += (lo<buf);
27838     z[5] = lo;
27839     mpfq_umul_ppmm(hi,lo,c,x[6]);
27840     lo += carry;
27841     carry = (lo<carry) + hi;
27842     buf = z[6];
27843     lo += buf;
27844     carry += (lo<buf);
27845     z[6] = lo;
27846     mpfq_umul_ppmm(hi,lo,c,x[7]);
27847     lo += carry;
27848     carry = (lo<carry) + hi;
27849     buf = z[7];
27850     lo += buf;
27851     carry += (lo<buf);
27852     z[7] = lo;
27853     mpfq_umul_ppmm(hi,lo,c,x[8]);
27854     lo += carry;
27855     carry = (lo<carry) + hi;
27856     buf = z[8];
27857     lo += buf;
27858     carry += (lo<buf);
27859     z[8] = lo;
27860     lo = c*x[9] + carry;
27861     assert(lo >= carry);
27862     z[9] += lo;
27863     return z[9] < lo;
27864 }
27865 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_addmul05) */
27866 
27867 #if !defined(HAVE_native_mpfq_fixmp_9_5_mul05)
27868 /* x has 9.5 words, z has 10. c is 0.5 word.
27869  * Put (x*c) in z. No carry. */
27870 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
27871 static inline
mpfq_fixmp_9_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)27872 void mpfq_fixmp_9_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
27873 {
27874     mp_limb_t hi, lo, carry;
27875     carry = 0;
27876     mpfq_umul_ppmm(hi,lo,c,x[0]);
27877     lo += carry;
27878     carry = (lo<carry) + hi;
27879     z[0] = lo;
27880     mpfq_umul_ppmm(hi,lo,c,x[1]);
27881     lo += carry;
27882     carry = (lo<carry) + hi;
27883     z[1] = lo;
27884     mpfq_umul_ppmm(hi,lo,c,x[2]);
27885     lo += carry;
27886     carry = (lo<carry) + hi;
27887     z[2] = lo;
27888     mpfq_umul_ppmm(hi,lo,c,x[3]);
27889     lo += carry;
27890     carry = (lo<carry) + hi;
27891     z[3] = lo;
27892     mpfq_umul_ppmm(hi,lo,c,x[4]);
27893     lo += carry;
27894     carry = (lo<carry) + hi;
27895     z[4] = lo;
27896     mpfq_umul_ppmm(hi,lo,c,x[5]);
27897     lo += carry;
27898     carry = (lo<carry) + hi;
27899     z[5] = lo;
27900     mpfq_umul_ppmm(hi,lo,c,x[6]);
27901     lo += carry;
27902     carry = (lo<carry) + hi;
27903     z[6] = lo;
27904     mpfq_umul_ppmm(hi,lo,c,x[7]);
27905     lo += carry;
27906     carry = (lo<carry) + hi;
27907     z[7] = lo;
27908     mpfq_umul_ppmm(hi,lo,c,x[8]);
27909     lo += carry;
27910     carry = (lo<carry) + hi;
27911     z[8] = lo;
27912     lo = c*x[9] + carry;
27913     assert(lo >= carry);
27914     z[9] = lo;
27915 }
27916 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mul05) */
27917 
27918 #if !defined(HAVE_native_mpfq_fixmp_9_5_mod)
27919 /* x has 19 words. z and p have 9.5 words, and the high word of p is non-zero.
27920  * Put x mod p in z. */
27921 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
27922 /* Triggered by: 9_5_mgy_decode */
27923 static inline
mpfq_fixmp_9_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)27924 void mpfq_fixmp_9_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
27925 {
27926     mp_limb_t q[9+1], r[10];
27927     assert (p[10-1] != 0);
27928     mpn_tdiv_qr(q, r, 0, x, 19, p, 10);
27929     mpfq_copy(z, r, 10);
27930 }
27931 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mod) */
27932 
27933 #if !defined(HAVE_native_mpfq_fixmp_9_5_rshift)
27934 /* a has 9.5 words. Shift it in place by cnt bits to the right.
27935  * The shift count cnt must not exceed the word size.
27936  * Note that no carry is returned for the bits shifted out. */
27937 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
27938 /* Triggered by: 9_5_invmod */
27939 static inline
mpfq_fixmp_9_5_rshift(mp_limb_t * a,int cnt)27940 void mpfq_fixmp_9_5_rshift(mp_limb_t * a, int cnt)
27941 {
27942     if (!cnt) return;
27943     int i;
27944     int dnt = GMP_NUMB_BITS - cnt;
27945     for (i = 0; i < 10-1; ++i) {
27946         a[i] >>= cnt;
27947         a[i] |= (a[i+1] << dnt);
27948     }
27949     a[10-1] >>= cnt;
27950 }
27951 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_rshift) */
27952 
27953 #if !defined(HAVE_native_mpfq_fixmp_9_5_long_rshift)
27954 /* a has 9.5 words. Shift it in place by off words plus cnt bits to the left.
27955  * Note that no carry is returned for the bits shifted out. */
27956 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
27957 /* Triggered by: 9_5_invmod */
27958 static inline
mpfq_fixmp_9_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)27959 void mpfq_fixmp_9_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
27960 {
27961     if (cnt) {
27962         int dnt = GMP_NUMB_BITS - cnt;
27963         for (int i = 0; i < 10 - off - 1; ++i) {
27964             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
27965         }
27966         a[10-off-1] = a[10-1]>>cnt;
27967     } else {
27968         mpfq_copyi(a, a + off, 10 - off);
27969     }
27970     mpfq_zero(a + 10 - off, off);
27971 }
27972 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_long_rshift) */
27973 
27974 #if !defined(HAVE_native_mpfq_fixmp_9_5_long_lshift)
27975 /* a has 9.5 words. Shift it in place by off words plus cnt bits to the left.
27976  * Note that no carry is returned for the bits shifted out. */
27977 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
27978 /* Triggered by: 9_5_invmod */
27979 static inline
mpfq_fixmp_9_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)27980 void mpfq_fixmp_9_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
27981 {
27982     int i;
27983     if (cnt) {
27984         int dnt = GMP_NUMB_BITS - cnt;
27985         for (i = 10-1; i>off; --i) {
27986             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
27987         }
27988         a[off] = a[0]<<cnt;
27989     } else {
27990         mpfq_copyd(a + off, a, 10 - off);
27991     }
27992     mpfq_zero(a, off);
27993 }
27994 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_long_lshift) */
27995 
27996 #if !defined(HAVE_native_mpfq_fixmp_9_5_invmod)
27997 /* x, z, and p have 9.5 words. Put inverse of x mod p in z.
27998  * Return non-zero if an inverse could be found.
27999  * If no inverse could be found, return 0 and set z to zero.
28000  */
28001 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
28002 static inline
mpfq_fixmp_9_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)28003 int mpfq_fixmp_9_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
28004 {
28005       mp_limb_t u[10], v[10], a[10], b[10], fix[10];
28006       int i, t, lsh;
28007 
28008       mpfq_zero(u, 10);
28009       mpfq_zero(v, 10);
28010       mpfq_copy(a, x, 10);
28011       mpfq_copy(b, p, 10);
28012       u[0] = 1UL;
28013 
28014       if (mpfq_fixmp_9_5_cmp(a, v) == 0 || mpfq_fixmp_9_5_cmp(a, b) == 0) {
28015         mpfq_zero(res, 10);
28016         return 0;
28017       }
28018 
28019       mpfq_fixmp_9_5_add(fix, b, u);
28020       mpfq_fixmp_9_5_rshift(fix, 1);
28021 
28022       assert (mpfq_fixmp_9_5_cmp(a,b) < 0);
28023 
28024       t = 0;
28025 
28026       for(i = 0 ; !a[i] ; i++) ;
28027       assert (i < 10);
28028       lsh = mpfq_ctzl(a[i]);
28029       mpfq_fixmp_9_5_long_rshift(a, i, lsh);
28030       t += lsh + i*GMP_NUMB_BITS;
28031       mpfq_fixmp_9_5_long_lshift(v, i, lsh);
28032 
28033       do {
28034         do {
28035           mpfq_fixmp_9_5_sub(b, b, a);
28036           mpfq_fixmp_9_5_add(v, v, u);
28037           for(i = 0 ; !b[i] ; i++) ;
28038           assert (i < 10);
28039           lsh = mpfq_ctzl(b[i]);
28040           mpfq_fixmp_9_5_long_rshift(b, i, lsh);
28041           t += lsh + i*GMP_NUMB_BITS;
28042           mpfq_fixmp_9_5_long_lshift(u, i, lsh);
28043         } while (mpfq_fixmp_9_5_cmp(a,b) < 0);
28044         if (mpfq_fixmp_9_5_cmp(a, b) == 0)
28045           break;
28046         do {
28047           mpfq_fixmp_9_5_sub(a, a, b);
28048           mpfq_fixmp_9_5_add(u, u, v);
28049           for(i = 0 ; !a[i] ; i++) ;
28050           assert (i < 10);
28051           lsh = mpfq_ctzl(a[i]);
28052           mpfq_fixmp_9_5_long_rshift(a, i, lsh);
28053           t += lsh + i*GMP_NUMB_BITS;
28054           mpfq_fixmp_9_5_long_lshift(v, i, lsh);
28055         } while (mpfq_fixmp_9_5_cmp(b,a)<0);
28056       } while (mpfq_fixmp_9_5_cmp(a,b) != 0);
28057       {
28058         if (mpfq_fixmp_9_5_cmp_ui(a, 1) != 0) {
28059           mpfq_copy(res, a, 10);
28060           return 0;
28061         }
28062       }
28063       while (t>0) {
28064         mp_limb_t sig = u[0] & 1UL;
28065         mpfq_fixmp_9_5_rshift(u, 1);
28066         if (sig)
28067           mpfq_fixmp_9_5_add(u, u, fix);
28068         --t;
28069       }
28070       mpfq_copy(res, u, 10);
28071       return 1;
28072 }
28073 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_invmod) */
28074 
28075 #if !defined(HAVE_native_mpfq_fixmp_9_5_redc)
28076 /* x has 19 words, z and p have 9.5 words.
28077  * only one word is read from invp.
28078  * Assuming R=W^10 is the redc modulus, we expect that x verifies:
28079  *   x < R*p,
28080  * so that we have eventually z < p, z congruent to x/R mod p.
28081  * The contents of the area pointed by x are clobbered by this call.
28082  * Note also that x may alias z.
28083  */
28084 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
28085 static inline
mpfq_fixmp_9_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)28086 void mpfq_fixmp_9_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
28087 {
28088     mp_limb_t cy;
28089     for(int i = 0; i < 10; ++i) {
28090         mp_limb_t t = x[i]*mip[0];
28091         cy = mpfq_fixmp_9_5_addmul1_shortz(x+i, p, t);
28092         assert (x[i] == 0);
28093         x[i] = cy;
28094     }
28095     {
28096         mp_limb_t ret[10] = { x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], 0 };
28097         cy = mpfq_fixmp_9_5_add(x, x, ret);
28098     }
28099     /* At this point, we have (x' denotes x + cy*W^n here)
28100     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
28101     * x'/R < p + p
28102     */
28103     if (cy || mpfq_fixmp_9_5_cmp(x, p) >= 0) {
28104         mpfq_fixmp_9_5_sub(z, x, p);
28105     } else {
28106         mpfq_copy(z, x, 10);
28107     }
28108 }
28109 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_redc) */
28110 
28111 #if !defined(HAVE_native_mpfq_fixmp_9_5_redc_ur)
28112 /* x has 20 words, z and p have 9.5 words.
28113  * only one word is read from invp.
28114  * Assuming R=W^10 is the redc modulus, we expect that x verifies:
28115  *  x < W*W^9.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
28116  * so that we have eventually z < p, z congruent to x/R mod p.
28117  * The contents of the area pointed by x are clobbered by this call.
28118  * Note also that x may alias z.
28119  */
28120 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
28121 static inline
mpfq_fixmp_9_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)28122 void mpfq_fixmp_9_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
28123 {
28124     mp_limb_t cy, q[1];
28125     for(int i = 0; i < 10; ++i) {
28126         mp_limb_t t = x[i]*mip[0];
28127         cy = mpfq_fixmp_9_5_addmul1_shortz(x+i, p, t);
28128         assert (x[i] == 0);
28129         x[i] = cy;
28130     }
28131     cy = mpfq_fixmp_9_5_add(x + 10, x, x + 10);
28132     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
28133     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
28134     * x'/R < (W^0.5+1)*p
28135     */
28136     if (cy) {
28137         /* x'/R-p < W^0.5*p, which fits in n words. */
28138         mpfq_fixmp_9_5_sub(x + 10, x + 10, p);
28139     }
28140     mpn_tdiv_qr(q, z, 0, x + 10, 10, p, 10);
28141 }
28142 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_redc_ur) */
28143 
28144 #if !defined(HAVE_native_mpfq_fixmp_9_5_mgy_encode)
28145 /* x, z, and p have 9.5 words.
28146  * Assuming R=W^10 is the redc modulus, we compute z=R*x mod p. */
28147 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
28148 static inline
mpfq_fixmp_9_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)28149 void mpfq_fixmp_9_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
28150 {
28151     mp_limb_t t[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9] };
28152     mp_limb_t qq[10+1];
28153     mpn_tdiv_qr(qq, z, 0, t, 20, p, 10);
28154 }
28155 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mgy_encode) */
28156 
28157 #if !defined(HAVE_native_mpfq_fixmp_9_5_mgy_decode)
28158 /* x, z, invR, and p have 9.5 words.
28159  * Assuming R=W^10 is the redc modulus, we compute z=x/R mod p. */
28160 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
28161 static inline
mpfq_fixmp_9_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)28162 void mpfq_fixmp_9_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
28163 {
28164     mp_limb_t t[20];
28165     mpfq_fixmp_9_5_mul(t, x, invR);
28166     mpfq_fixmp_9_5_mod(z, t, p);
28167 }
28168 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_mgy_decode) */
28169 
28170 #if !defined(HAVE_native_mpfq_fixmp_9_5_lshift)
28171 /* a has 9.5 words. Shift it in place by cnt bits to the left.
28172  * The shift count cnt must not exceed the word size.
28173  * Note that no carry is returned for the bits shifted out. */
28174 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
28175 static inline
mpfq_fixmp_9_5_lshift(mp_limb_t * a,int cnt)28176 void mpfq_fixmp_9_5_lshift(mp_limb_t * a, int cnt)
28177 {
28178     if (!cnt) return;
28179     int i;
28180     int dnt = GMP_NUMB_BITS - cnt;
28181     for (i = 10-1; i>0; --i) {
28182         a[i] <<= cnt;
28183         a[i] |= (a[i-1] >> dnt);
28184     }
28185     a[0] <<= cnt;
28186 }
28187 #endif /* !defined(HAVE_native_mpfq_fixmp_9_5_lshift) */
28188 
28189 #if !defined(HAVE_native_mpfq_fixmp_10_5_add)
28190 /* x, y, and z have 10.5 words. Result in z. Return carry bit */
28191 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
28192 /* Triggered by: 10_5_invmod, 10_5_redc, 10_5_redc_ur */
28193 static inline
mpfq_fixmp_10_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)28194 mp_limb_t mpfq_fixmp_10_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
28195 {
28196     mp_limb_t r, s, t, cy, cy1, cy2;
28197     cy = 0;
28198     r = x[0];
28199     s = r + y[0];
28200     cy1 = s < r;
28201     t = s + cy;
28202     cy2 = t < s;
28203     cy = cy1 | cy2;
28204     z[0] = t;
28205     r = x[1];
28206     s = r + y[1];
28207     cy1 = s < r;
28208     t = s + cy;
28209     cy2 = t < s;
28210     cy = cy1 | cy2;
28211     z[1] = t;
28212     r = x[2];
28213     s = r + y[2];
28214     cy1 = s < r;
28215     t = s + cy;
28216     cy2 = t < s;
28217     cy = cy1 | cy2;
28218     z[2] = t;
28219     r = x[3];
28220     s = r + y[3];
28221     cy1 = s < r;
28222     t = s + cy;
28223     cy2 = t < s;
28224     cy = cy1 | cy2;
28225     z[3] = t;
28226     r = x[4];
28227     s = r + y[4];
28228     cy1 = s < r;
28229     t = s + cy;
28230     cy2 = t < s;
28231     cy = cy1 | cy2;
28232     z[4] = t;
28233     r = x[5];
28234     s = r + y[5];
28235     cy1 = s < r;
28236     t = s + cy;
28237     cy2 = t < s;
28238     cy = cy1 | cy2;
28239     z[5] = t;
28240     r = x[6];
28241     s = r + y[6];
28242     cy1 = s < r;
28243     t = s + cy;
28244     cy2 = t < s;
28245     cy = cy1 | cy2;
28246     z[6] = t;
28247     r = x[7];
28248     s = r + y[7];
28249     cy1 = s < r;
28250     t = s + cy;
28251     cy2 = t < s;
28252     cy = cy1 | cy2;
28253     z[7] = t;
28254     r = x[8];
28255     s = r + y[8];
28256     cy1 = s < r;
28257     t = s + cy;
28258     cy2 = t < s;
28259     cy = cy1 | cy2;
28260     z[8] = t;
28261     r = x[9];
28262     s = r + y[9];
28263     cy1 = s < r;
28264     t = s + cy;
28265     cy2 = t < s;
28266     cy = cy1 | cy2;
28267     z[9] = t;
28268     r = x[10];
28269     s = r + y[10];
28270     cy1 = s < r;
28271     t = s + cy;
28272     cy2 = t < s;
28273     cy = cy1 | cy2;
28274     z[10] = t;
28275     return cy;
28276 }
28277 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_add) */
28278 
28279 #if !defined(HAVE_native_mpfq_fixmp_10_5_sub)
28280 /* x, y, and z have 10.5 words. Result in z. Return borrow bit */
28281 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
28282 /* Triggered by: 10_5_invmod, 10_5_redc, 10_5_redc_ur */
28283 static inline
mpfq_fixmp_10_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)28284 mp_limb_t mpfq_fixmp_10_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
28285 {
28286     mp_limb_t r, s, t, cy, cy1, cy2;
28287     cy = 0;
28288     r = x[0];
28289     s = r - y[0];
28290     cy1 = s > r;
28291     t = s - cy;
28292     cy2 = t > s;
28293     cy = cy1 | cy2;
28294     z[0] = t;
28295     r = x[1];
28296     s = r - y[1];
28297     cy1 = s > r;
28298     t = s - cy;
28299     cy2 = t > s;
28300     cy = cy1 | cy2;
28301     z[1] = t;
28302     r = x[2];
28303     s = r - y[2];
28304     cy1 = s > r;
28305     t = s - cy;
28306     cy2 = t > s;
28307     cy = cy1 | cy2;
28308     z[2] = t;
28309     r = x[3];
28310     s = r - y[3];
28311     cy1 = s > r;
28312     t = s - cy;
28313     cy2 = t > s;
28314     cy = cy1 | cy2;
28315     z[3] = t;
28316     r = x[4];
28317     s = r - y[4];
28318     cy1 = s > r;
28319     t = s - cy;
28320     cy2 = t > s;
28321     cy = cy1 | cy2;
28322     z[4] = t;
28323     r = x[5];
28324     s = r - y[5];
28325     cy1 = s > r;
28326     t = s - cy;
28327     cy2 = t > s;
28328     cy = cy1 | cy2;
28329     z[5] = t;
28330     r = x[6];
28331     s = r - y[6];
28332     cy1 = s > r;
28333     t = s - cy;
28334     cy2 = t > s;
28335     cy = cy1 | cy2;
28336     z[6] = t;
28337     r = x[7];
28338     s = r - y[7];
28339     cy1 = s > r;
28340     t = s - cy;
28341     cy2 = t > s;
28342     cy = cy1 | cy2;
28343     z[7] = t;
28344     r = x[8];
28345     s = r - y[8];
28346     cy1 = s > r;
28347     t = s - cy;
28348     cy2 = t > s;
28349     cy = cy1 | cy2;
28350     z[8] = t;
28351     r = x[9];
28352     s = r - y[9];
28353     cy1 = s > r;
28354     t = s - cy;
28355     cy2 = t > s;
28356     cy = cy1 | cy2;
28357     z[9] = t;
28358     r = x[10];
28359     s = r - y[10];
28360     cy1 = s > r;
28361     t = s - cy;
28362     cy2 = t > s;
28363     cy = cy1 | cy2;
28364     z[10] = t;
28365     return cy;
28366 }
28367 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_sub) */
28368 
28369 #if !defined(HAVE_native_mpfq_fixmp_10_5_add_nc)
28370 /* x, y, and z have 10.5 words. Result in z. Carry bit is lost. */
28371 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
28372 static inline
mpfq_fixmp_10_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)28373 void mpfq_fixmp_10_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
28374 {
28375     mp_limb_t r, s, t, cy, cy1, cy2;
28376     cy = 0;
28377     r = x[0];
28378     s = r + y[0];
28379     cy1 = s < r;
28380     t = s + cy;
28381     cy2 = t < s;
28382     cy = cy1 | cy2;
28383     z[0] = t;
28384     r = x[1];
28385     s = r + y[1];
28386     cy1 = s < r;
28387     t = s + cy;
28388     cy2 = t < s;
28389     cy = cy1 | cy2;
28390     z[1] = t;
28391     r = x[2];
28392     s = r + y[2];
28393     cy1 = s < r;
28394     t = s + cy;
28395     cy2 = t < s;
28396     cy = cy1 | cy2;
28397     z[2] = t;
28398     r = x[3];
28399     s = r + y[3];
28400     cy1 = s < r;
28401     t = s + cy;
28402     cy2 = t < s;
28403     cy = cy1 | cy2;
28404     z[3] = t;
28405     r = x[4];
28406     s = r + y[4];
28407     cy1 = s < r;
28408     t = s + cy;
28409     cy2 = t < s;
28410     cy = cy1 | cy2;
28411     z[4] = t;
28412     r = x[5];
28413     s = r + y[5];
28414     cy1 = s < r;
28415     t = s + cy;
28416     cy2 = t < s;
28417     cy = cy1 | cy2;
28418     z[5] = t;
28419     r = x[6];
28420     s = r + y[6];
28421     cy1 = s < r;
28422     t = s + cy;
28423     cy2 = t < s;
28424     cy = cy1 | cy2;
28425     z[6] = t;
28426     r = x[7];
28427     s = r + y[7];
28428     cy1 = s < r;
28429     t = s + cy;
28430     cy2 = t < s;
28431     cy = cy1 | cy2;
28432     z[7] = t;
28433     r = x[8];
28434     s = r + y[8];
28435     cy1 = s < r;
28436     t = s + cy;
28437     cy2 = t < s;
28438     cy = cy1 | cy2;
28439     z[8] = t;
28440     r = x[9];
28441     s = r + y[9];
28442     cy1 = s < r;
28443     t = s + cy;
28444     cy2 = t < s;
28445     cy = cy1 | cy2;
28446     z[9] = t;
28447     r = x[10];
28448     s = r + y[10];
28449     cy1 = s < r;
28450     t = s + cy;
28451     cy2 = t < s;
28452     cy = cy1 | cy2;
28453     z[10] = t;
28454 }
28455 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_add_nc) */
28456 
28457 #if !defined(HAVE_native_mpfq_fixmp_10_5_sub_nc)
28458 /* x, y, and z have 10.5 words. Result in z. Borrow bit is lost. */
28459 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
28460 static inline
mpfq_fixmp_10_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)28461 void mpfq_fixmp_10_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
28462 {
28463     mp_limb_t r, s, t, cy, cy1, cy2;
28464     cy = 0;
28465     r = x[0];
28466     s = r - y[0];
28467     cy1 = s > r;
28468     t = s - cy;
28469     cy2 = t > s;
28470     cy = cy1 | cy2;
28471     z[0] = t;
28472     r = x[1];
28473     s = r - y[1];
28474     cy1 = s > r;
28475     t = s - cy;
28476     cy2 = t > s;
28477     cy = cy1 | cy2;
28478     z[1] = t;
28479     r = x[2];
28480     s = r - y[2];
28481     cy1 = s > r;
28482     t = s - cy;
28483     cy2 = t > s;
28484     cy = cy1 | cy2;
28485     z[2] = t;
28486     r = x[3];
28487     s = r - y[3];
28488     cy1 = s > r;
28489     t = s - cy;
28490     cy2 = t > s;
28491     cy = cy1 | cy2;
28492     z[3] = t;
28493     r = x[4];
28494     s = r - y[4];
28495     cy1 = s > r;
28496     t = s - cy;
28497     cy2 = t > s;
28498     cy = cy1 | cy2;
28499     z[4] = t;
28500     r = x[5];
28501     s = r - y[5];
28502     cy1 = s > r;
28503     t = s - cy;
28504     cy2 = t > s;
28505     cy = cy1 | cy2;
28506     z[5] = t;
28507     r = x[6];
28508     s = r - y[6];
28509     cy1 = s > r;
28510     t = s - cy;
28511     cy2 = t > s;
28512     cy = cy1 | cy2;
28513     z[6] = t;
28514     r = x[7];
28515     s = r - y[7];
28516     cy1 = s > r;
28517     t = s - cy;
28518     cy2 = t > s;
28519     cy = cy1 | cy2;
28520     z[7] = t;
28521     r = x[8];
28522     s = r - y[8];
28523     cy1 = s > r;
28524     t = s - cy;
28525     cy2 = t > s;
28526     cy = cy1 | cy2;
28527     z[8] = t;
28528     r = x[9];
28529     s = r - y[9];
28530     cy1 = s > r;
28531     t = s - cy;
28532     cy2 = t > s;
28533     cy = cy1 | cy2;
28534     z[9] = t;
28535     r = x[10];
28536     s = r - y[10];
28537     cy1 = s > r;
28538     t = s - cy;
28539     cy2 = t > s;
28540     cy = cy1 | cy2;
28541     z[10] = t;
28542 }
28543 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_sub_nc) */
28544 
28545 #if !defined(HAVE_native_mpfq_fixmp_10_5_add_ui)
28546 /* x, y, and z have 10.5 words. Result in z. Return carry bit */
28547 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
28548 static inline
mpfq_fixmp_10_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)28549 mp_limb_t mpfq_fixmp_10_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
28550 {
28551     mp_limb_t r, s, t, cy, cy1, cy2;
28552     cy = 0;
28553     r = x[0];
28554     s = r + y;
28555     cy1 = s < r;
28556     t = s + cy;
28557     cy2 = t < s;
28558     cy = cy1 | cy2;
28559     z[0] = t;
28560     s = x[1];
28561     t = s + cy;
28562     cy = t < s;
28563     z[1] = t;
28564     s = x[2];
28565     t = s + cy;
28566     cy = t < s;
28567     z[2] = t;
28568     s = x[3];
28569     t = s + cy;
28570     cy = t < s;
28571     z[3] = t;
28572     s = x[4];
28573     t = s + cy;
28574     cy = t < s;
28575     z[4] = t;
28576     s = x[5];
28577     t = s + cy;
28578     cy = t < s;
28579     z[5] = t;
28580     s = x[6];
28581     t = s + cy;
28582     cy = t < s;
28583     z[6] = t;
28584     s = x[7];
28585     t = s + cy;
28586     cy = t < s;
28587     z[7] = t;
28588     s = x[8];
28589     t = s + cy;
28590     cy = t < s;
28591     z[8] = t;
28592     s = x[9];
28593     t = s + cy;
28594     cy = t < s;
28595     z[9] = t;
28596     s = x[10];
28597     t = s + cy;
28598     cy = t < s;
28599     z[10] = t;
28600     return cy;
28601 }
28602 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_add_ui) */
28603 
28604 #if !defined(HAVE_native_mpfq_fixmp_10_5_sub_ui)
28605 /* x, y, and z have 10.5 words. Result in z. Return borrow bit */
28606 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
28607 static inline
mpfq_fixmp_10_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)28608 mp_limb_t mpfq_fixmp_10_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
28609 {
28610     mp_limb_t r, s, t, cy, cy1, cy2;
28611     cy = 0;
28612     r = x[0];
28613     s = r - y;
28614     cy1 = s > r;
28615     t = s - cy;
28616     cy2 = t > s;
28617     cy = cy1 | cy2;
28618     z[0] = t;
28619     s = x[1];
28620     t = s - cy;
28621     cy = t > s;
28622     z[1] = t;
28623     s = x[2];
28624     t = s - cy;
28625     cy = t > s;
28626     z[2] = t;
28627     s = x[3];
28628     t = s - cy;
28629     cy = t > s;
28630     z[3] = t;
28631     s = x[4];
28632     t = s - cy;
28633     cy = t > s;
28634     z[4] = t;
28635     s = x[5];
28636     t = s - cy;
28637     cy = t > s;
28638     z[5] = t;
28639     s = x[6];
28640     t = s - cy;
28641     cy = t > s;
28642     z[6] = t;
28643     s = x[7];
28644     t = s - cy;
28645     cy = t > s;
28646     z[7] = t;
28647     s = x[8];
28648     t = s - cy;
28649     cy = t > s;
28650     z[8] = t;
28651     s = x[9];
28652     t = s - cy;
28653     cy = t > s;
28654     z[9] = t;
28655     s = x[10];
28656     t = s - cy;
28657     cy = t > s;
28658     z[10] = t;
28659     return cy;
28660 }
28661 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_sub_ui) */
28662 
28663 #if !defined(HAVE_native_mpfq_fixmp_10_5_add_ui_nc)
28664 /* x, y, and z have 10.5 words. Result in z. Carry bit is lost. */
28665 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
28666 static inline
mpfq_fixmp_10_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)28667 void mpfq_fixmp_10_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
28668 {
28669     mp_limb_t r, s, t, cy, cy1, cy2;
28670     cy = 0;
28671     r = x[0];
28672     s = r + y;
28673     cy1 = s < r;
28674     t = s + cy;
28675     cy2 = t < s;
28676     cy = cy1 | cy2;
28677     z[0] = t;
28678     s = x[1];
28679     t = s + cy;
28680     cy = t < s;
28681     z[1] = t;
28682     s = x[2];
28683     t = s + cy;
28684     cy = t < s;
28685     z[2] = t;
28686     s = x[3];
28687     t = s + cy;
28688     cy = t < s;
28689     z[3] = t;
28690     s = x[4];
28691     t = s + cy;
28692     cy = t < s;
28693     z[4] = t;
28694     s = x[5];
28695     t = s + cy;
28696     cy = t < s;
28697     z[5] = t;
28698     s = x[6];
28699     t = s + cy;
28700     cy = t < s;
28701     z[6] = t;
28702     s = x[7];
28703     t = s + cy;
28704     cy = t < s;
28705     z[7] = t;
28706     s = x[8];
28707     t = s + cy;
28708     cy = t < s;
28709     z[8] = t;
28710     s = x[9];
28711     t = s + cy;
28712     cy = t < s;
28713     z[9] = t;
28714     s = x[10];
28715     t = s + cy;
28716     cy = t < s;
28717     z[10] = t;
28718 }
28719 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_add_ui_nc) */
28720 
28721 #if !defined(HAVE_native_mpfq_fixmp_10_5_sub_ui_nc)
28722 /* x, y, and z have 10.5 words. Result in z. Borrow bit is lost. */
28723 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
28724 static inline
mpfq_fixmp_10_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)28725 void mpfq_fixmp_10_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
28726 {
28727     mp_limb_t r, s, t, cy, cy1, cy2;
28728     cy = 0;
28729     r = x[0];
28730     s = r - y;
28731     cy1 = s > r;
28732     t = s - cy;
28733     cy2 = t > s;
28734     cy = cy1 | cy2;
28735     z[0] = t;
28736     s = x[1];
28737     t = s - cy;
28738     cy = t > s;
28739     z[1] = t;
28740     s = x[2];
28741     t = s - cy;
28742     cy = t > s;
28743     z[2] = t;
28744     s = x[3];
28745     t = s - cy;
28746     cy = t > s;
28747     z[3] = t;
28748     s = x[4];
28749     t = s - cy;
28750     cy = t > s;
28751     z[4] = t;
28752     s = x[5];
28753     t = s - cy;
28754     cy = t > s;
28755     z[5] = t;
28756     s = x[6];
28757     t = s - cy;
28758     cy = t > s;
28759     z[6] = t;
28760     s = x[7];
28761     t = s - cy;
28762     cy = t > s;
28763     z[7] = t;
28764     s = x[8];
28765     t = s - cy;
28766     cy = t > s;
28767     z[8] = t;
28768     s = x[9];
28769     t = s - cy;
28770     cy = t > s;
28771     z[9] = t;
28772     s = x[10];
28773     t = s - cy;
28774     cy = t > s;
28775     z[10] = t;
28776 }
28777 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_sub_ui_nc) */
28778 
28779 #if !defined(HAVE_native_mpfq_fixmp_10_5_cmp)
28780 /* x and y have 10.5 words. Return sign of difference x-y. */
28781 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
28782 /* Triggered by: 10_5_invmod, 10_5_redc, 10_5_redc_ur */
28783 static inline
mpfq_fixmp_10_5_cmp(const mp_limb_t * x,const mp_limb_t * y)28784 int mpfq_fixmp_10_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
28785 {
28786     for (int i = 11-1; i >= 0; --i) {
28787         if (x[i] > y[i]) return 1;
28788         if (x[i] < y[i]) return -1;
28789     }
28790     return 0;
28791 }
28792 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_cmp) */
28793 
28794 #if !defined(HAVE_native_mpfq_fixmp_10_5_cmp_ui)
28795 /* x has 10.5 words. Return sign of difference x-y. */
28796 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
28797 /* Triggered by: 10_5_invmod */
28798 static inline
mpfq_fixmp_10_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)28799 int mpfq_fixmp_10_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
28800 {
28801     for (int i = 11-1; i > 0; --i) {
28802         if (x[i]) return 1;
28803     }
28804     if (x[0]>y) return 1;
28805     if (x[0]<y) return -1;
28806     return 0;
28807 }
28808 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_cmp_ui) */
28809 
28810 #if !defined(HAVE_native_mpfq_fixmp_10_5_addmul1)
28811 /* x has 10.5 words, z has 12.
28812  * Put (z+x*c) in z. Return carry bit. */
28813 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
28814 static inline
mpfq_fixmp_10_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)28815 mp_limb_t mpfq_fixmp_10_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
28816 {
28817     mp_limb_t hi, lo, carry, buf;
28818     carry = 0;
28819     mpfq_umul_ppmm(hi,lo,c,x[0]);
28820     lo += carry;
28821     carry = (lo<carry) + hi;
28822     buf = z[0];
28823     lo += buf;
28824     carry += (lo<buf);
28825     z[0] = lo;
28826     mpfq_umul_ppmm(hi,lo,c,x[1]);
28827     lo += carry;
28828     carry = (lo<carry) + hi;
28829     buf = z[1];
28830     lo += buf;
28831     carry += (lo<buf);
28832     z[1] = lo;
28833     mpfq_umul_ppmm(hi,lo,c,x[2]);
28834     lo += carry;
28835     carry = (lo<carry) + hi;
28836     buf = z[2];
28837     lo += buf;
28838     carry += (lo<buf);
28839     z[2] = lo;
28840     mpfq_umul_ppmm(hi,lo,c,x[3]);
28841     lo += carry;
28842     carry = (lo<carry) + hi;
28843     buf = z[3];
28844     lo += buf;
28845     carry += (lo<buf);
28846     z[3] = lo;
28847     mpfq_umul_ppmm(hi,lo,c,x[4]);
28848     lo += carry;
28849     carry = (lo<carry) + hi;
28850     buf = z[4];
28851     lo += buf;
28852     carry += (lo<buf);
28853     z[4] = lo;
28854     mpfq_umul_ppmm(hi,lo,c,x[5]);
28855     lo += carry;
28856     carry = (lo<carry) + hi;
28857     buf = z[5];
28858     lo += buf;
28859     carry += (lo<buf);
28860     z[5] = lo;
28861     mpfq_umul_ppmm(hi,lo,c,x[6]);
28862     lo += carry;
28863     carry = (lo<carry) + hi;
28864     buf = z[6];
28865     lo += buf;
28866     carry += (lo<buf);
28867     z[6] = lo;
28868     mpfq_umul_ppmm(hi,lo,c,x[7]);
28869     lo += carry;
28870     carry = (lo<carry) + hi;
28871     buf = z[7];
28872     lo += buf;
28873     carry += (lo<buf);
28874     z[7] = lo;
28875     mpfq_umul_ppmm(hi,lo,c,x[8]);
28876     lo += carry;
28877     carry = (lo<carry) + hi;
28878     buf = z[8];
28879     lo += buf;
28880     carry += (lo<buf);
28881     z[8] = lo;
28882     mpfq_umul_ppmm(hi,lo,c,x[9]);
28883     lo += carry;
28884     carry = (lo<carry) + hi;
28885     buf = z[9];
28886     lo += buf;
28887     carry += (lo<buf);
28888     z[9] = lo;
28889     mpfq_umul_ppmm(hi,lo,c,x[10]);
28890     lo += carry;
28891     carry = (lo<carry) + hi;
28892     buf = z[10];
28893     lo += buf;
28894     carry += (lo<buf);
28895     z[10] = lo;
28896     z[11] += carry;
28897     return (z[11]<carry);
28898 }
28899 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_addmul1) */
28900 
28901 #if !defined(HAVE_native_mpfq_fixmp_10_5_addmul1_nc)
28902 /* x has 10.5 words, z has 12.
28903  * Put (z+x*c) in z. Carry bit is lost. */
28904 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
28905 /* Triggered by: 10_5_mul, 10_5_mgy_decode */
28906 static inline
mpfq_fixmp_10_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)28907 void mpfq_fixmp_10_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
28908 {
28909     mp_limb_t hi, lo, carry, buf;
28910     carry = 0;
28911     mpfq_umul_ppmm(hi,lo,c,x[0]);
28912     lo += carry;
28913     carry = (lo<carry) + hi;
28914     buf = z[0];
28915     lo += buf;
28916     carry += (lo<buf);
28917     z[0] = lo;
28918     mpfq_umul_ppmm(hi,lo,c,x[1]);
28919     lo += carry;
28920     carry = (lo<carry) + hi;
28921     buf = z[1];
28922     lo += buf;
28923     carry += (lo<buf);
28924     z[1] = lo;
28925     mpfq_umul_ppmm(hi,lo,c,x[2]);
28926     lo += carry;
28927     carry = (lo<carry) + hi;
28928     buf = z[2];
28929     lo += buf;
28930     carry += (lo<buf);
28931     z[2] = lo;
28932     mpfq_umul_ppmm(hi,lo,c,x[3]);
28933     lo += carry;
28934     carry = (lo<carry) + hi;
28935     buf = z[3];
28936     lo += buf;
28937     carry += (lo<buf);
28938     z[3] = lo;
28939     mpfq_umul_ppmm(hi,lo,c,x[4]);
28940     lo += carry;
28941     carry = (lo<carry) + hi;
28942     buf = z[4];
28943     lo += buf;
28944     carry += (lo<buf);
28945     z[4] = lo;
28946     mpfq_umul_ppmm(hi,lo,c,x[5]);
28947     lo += carry;
28948     carry = (lo<carry) + hi;
28949     buf = z[5];
28950     lo += buf;
28951     carry += (lo<buf);
28952     z[5] = lo;
28953     mpfq_umul_ppmm(hi,lo,c,x[6]);
28954     lo += carry;
28955     carry = (lo<carry) + hi;
28956     buf = z[6];
28957     lo += buf;
28958     carry += (lo<buf);
28959     z[6] = lo;
28960     mpfq_umul_ppmm(hi,lo,c,x[7]);
28961     lo += carry;
28962     carry = (lo<carry) + hi;
28963     buf = z[7];
28964     lo += buf;
28965     carry += (lo<buf);
28966     z[7] = lo;
28967     mpfq_umul_ppmm(hi,lo,c,x[8]);
28968     lo += carry;
28969     carry = (lo<carry) + hi;
28970     buf = z[8];
28971     lo += buf;
28972     carry += (lo<buf);
28973     z[8] = lo;
28974     mpfq_umul_ppmm(hi,lo,c,x[9]);
28975     lo += carry;
28976     carry = (lo<carry) + hi;
28977     buf = z[9];
28978     lo += buf;
28979     carry += (lo<buf);
28980     z[9] = lo;
28981     mpfq_umul_ppmm(hi,lo,c,x[10]);
28982     lo += carry;
28983     carry = (lo<carry) + hi;
28984     buf = z[10];
28985     lo += buf;
28986     carry += (lo<buf);
28987     z[10] = lo;
28988     z[11] += carry;
28989 }
28990 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_addmul1_nc) */
28991 
28992 #if !defined(HAVE_native_mpfq_fixmp_10_5_addmul1_shortz)
28993 /* x has 10.5 words, z has 11.
28994  * Put (z+x*c) in z. Return carry word. */
28995 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
28996 /* Triggered by: 10_5_redc, 10_5_redc_ur */
28997 static inline
mpfq_fixmp_10_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)28998 mp_limb_t mpfq_fixmp_10_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
28999 {
29000     mp_limb_t hi, lo, carry, buf;
29001     carry = 0;
29002     mpfq_umul_ppmm(hi,lo,c,x[0]);
29003     lo += carry;
29004     carry = (lo<carry) + hi;
29005     buf = z[0];
29006     lo += buf;
29007     carry += (lo<buf);
29008     z[0] = lo;
29009     mpfq_umul_ppmm(hi,lo,c,x[1]);
29010     lo += carry;
29011     carry = (lo<carry) + hi;
29012     buf = z[1];
29013     lo += buf;
29014     carry += (lo<buf);
29015     z[1] = lo;
29016     mpfq_umul_ppmm(hi,lo,c,x[2]);
29017     lo += carry;
29018     carry = (lo<carry) + hi;
29019     buf = z[2];
29020     lo += buf;
29021     carry += (lo<buf);
29022     z[2] = lo;
29023     mpfq_umul_ppmm(hi,lo,c,x[3]);
29024     lo += carry;
29025     carry = (lo<carry) + hi;
29026     buf = z[3];
29027     lo += buf;
29028     carry += (lo<buf);
29029     z[3] = lo;
29030     mpfq_umul_ppmm(hi,lo,c,x[4]);
29031     lo += carry;
29032     carry = (lo<carry) + hi;
29033     buf = z[4];
29034     lo += buf;
29035     carry += (lo<buf);
29036     z[4] = lo;
29037     mpfq_umul_ppmm(hi,lo,c,x[5]);
29038     lo += carry;
29039     carry = (lo<carry) + hi;
29040     buf = z[5];
29041     lo += buf;
29042     carry += (lo<buf);
29043     z[5] = lo;
29044     mpfq_umul_ppmm(hi,lo,c,x[6]);
29045     lo += carry;
29046     carry = (lo<carry) + hi;
29047     buf = z[6];
29048     lo += buf;
29049     carry += (lo<buf);
29050     z[6] = lo;
29051     mpfq_umul_ppmm(hi,lo,c,x[7]);
29052     lo += carry;
29053     carry = (lo<carry) + hi;
29054     buf = z[7];
29055     lo += buf;
29056     carry += (lo<buf);
29057     z[7] = lo;
29058     mpfq_umul_ppmm(hi,lo,c,x[8]);
29059     lo += carry;
29060     carry = (lo<carry) + hi;
29061     buf = z[8];
29062     lo += buf;
29063     carry += (lo<buf);
29064     z[8] = lo;
29065     mpfq_umul_ppmm(hi,lo,c,x[9]);
29066     lo += carry;
29067     carry = (lo<carry) + hi;
29068     buf = z[9];
29069     lo += buf;
29070     carry += (lo<buf);
29071     z[9] = lo;
29072     mpfq_umul_ppmm(hi,lo,c,x[10]);
29073     lo += carry;
29074     carry = (lo<carry) + hi;
29075     buf = z[10];
29076     lo += buf;
29077     carry += (lo<buf);
29078     z[10] = lo;
29079     return carry;
29080 }
29081 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_addmul1_shortz) */
29082 
29083 #if !defined(HAVE_native_mpfq_fixmp_10_5_addmul05_nc)
29084 /* x has 10.5 words, z has 11. c is 0.5 word.
29085  * Put (z+x*c) in z. Carry bit is lost. */
29086 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
29087 /* Triggered by: 10_5_mul, 10_5_mgy_decode */
29088 static inline
mpfq_fixmp_10_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)29089 void mpfq_fixmp_10_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
29090 {
29091     mp_limb_t hi, lo, carry, buf;
29092     carry = 0;
29093     mpfq_umul_ppmm(hi,lo,c,x[0]);
29094     lo += carry;
29095     carry = (lo<carry) + hi;
29096     buf = z[0];
29097     lo += buf;
29098     carry += (lo<buf);
29099     z[0] = lo;
29100     mpfq_umul_ppmm(hi,lo,c,x[1]);
29101     lo += carry;
29102     carry = (lo<carry) + hi;
29103     buf = z[1];
29104     lo += buf;
29105     carry += (lo<buf);
29106     z[1] = lo;
29107     mpfq_umul_ppmm(hi,lo,c,x[2]);
29108     lo += carry;
29109     carry = (lo<carry) + hi;
29110     buf = z[2];
29111     lo += buf;
29112     carry += (lo<buf);
29113     z[2] = lo;
29114     mpfq_umul_ppmm(hi,lo,c,x[3]);
29115     lo += carry;
29116     carry = (lo<carry) + hi;
29117     buf = z[3];
29118     lo += buf;
29119     carry += (lo<buf);
29120     z[3] = lo;
29121     mpfq_umul_ppmm(hi,lo,c,x[4]);
29122     lo += carry;
29123     carry = (lo<carry) + hi;
29124     buf = z[4];
29125     lo += buf;
29126     carry += (lo<buf);
29127     z[4] = lo;
29128     mpfq_umul_ppmm(hi,lo,c,x[5]);
29129     lo += carry;
29130     carry = (lo<carry) + hi;
29131     buf = z[5];
29132     lo += buf;
29133     carry += (lo<buf);
29134     z[5] = lo;
29135     mpfq_umul_ppmm(hi,lo,c,x[6]);
29136     lo += carry;
29137     carry = (lo<carry) + hi;
29138     buf = z[6];
29139     lo += buf;
29140     carry += (lo<buf);
29141     z[6] = lo;
29142     mpfq_umul_ppmm(hi,lo,c,x[7]);
29143     lo += carry;
29144     carry = (lo<carry) + hi;
29145     buf = z[7];
29146     lo += buf;
29147     carry += (lo<buf);
29148     z[7] = lo;
29149     mpfq_umul_ppmm(hi,lo,c,x[8]);
29150     lo += carry;
29151     carry = (lo<carry) + hi;
29152     buf = z[8];
29153     lo += buf;
29154     carry += (lo<buf);
29155     z[8] = lo;
29156     mpfq_umul_ppmm(hi,lo,c,x[9]);
29157     lo += carry;
29158     carry = (lo<carry) + hi;
29159     buf = z[9];
29160     lo += buf;
29161     carry += (lo<buf);
29162     z[9] = lo;
29163     lo = c*x[10] + carry;
29164     assert(lo >= carry);
29165     z[10] += lo;
29166 }
29167 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_addmul05_nc) */
29168 
29169 #if !defined(HAVE_native_mpfq_fixmp_10_5_mul)
29170 /* x and y have 10.5 words, z has 21. Put x*y in z. */
29171 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
29172 /* Triggered by: 10_5_mgy_decode */
29173 static inline
mpfq_fixmp_10_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)29174 void mpfq_fixmp_10_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
29175 {
29176     assert(z != x && z != y);
29177     for (int i = 0; i < 21; z[i++] = 0) ;
29178     mpfq_fixmp_10_5_addmul1_nc (z + 0, x, y[0]);
29179     mpfq_fixmp_10_5_addmul1_nc (z + 1, x, y[1]);
29180     mpfq_fixmp_10_5_addmul1_nc (z + 2, x, y[2]);
29181     mpfq_fixmp_10_5_addmul1_nc (z + 3, x, y[3]);
29182     mpfq_fixmp_10_5_addmul1_nc (z + 4, x, y[4]);
29183     mpfq_fixmp_10_5_addmul1_nc (z + 5, x, y[5]);
29184     mpfq_fixmp_10_5_addmul1_nc (z + 6, x, y[6]);
29185     mpfq_fixmp_10_5_addmul1_nc (z + 7, x, y[7]);
29186     mpfq_fixmp_10_5_addmul1_nc (z + 8, x, y[8]);
29187     mpfq_fixmp_10_5_addmul1_nc (z + 9, x, y[9]);
29188     mpfq_fixmp_10_5_addmul05_nc (z + 10, x, y[10]);
29189 }
29190 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mul) */
29191 
29192 #if !defined(HAVE_native_mpfq_fixmp_10_5_sqr)
29193 /* x has 10.5 words, z has 21. Put x*y in z. */
29194 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
29195 static inline
mpfq_fixmp_10_5_sqr(mp_limb_t * z,const mp_limb_t * x)29196 void mpfq_fixmp_10_5_sqr(mp_limb_t * z, const mp_limb_t * x)
29197 {
29198     mp_limb_t buf[21] = {0,};
29199     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
29200     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
29201     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
29202     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
29203     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
29204     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
29205     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
29206     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
29207     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
29208     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
29209     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
29210     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
29211     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
29212     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
29213     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
29214     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
29215     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
29216     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
29217     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
29218     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
29219     z[2*10] = x[10] * x[10];
29220     mpn_lshift(buf, buf, 21, 1);
29221     mpn_add_n(z, z, buf, 21);
29222 }
29223 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_sqr) */
29224 
29225 #if !defined(HAVE_native_mpfq_fixmp_10_5_mul1)
29226 /* x has 10.5 words, z has 12. Put x*y in z. */
29227 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
29228 static inline
mpfq_fixmp_10_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)29229 void mpfq_fixmp_10_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
29230 {
29231     mp_limb_t hi, lo, carry;
29232     carry = 0;
29233     mpfq_umul_ppmm(hi,lo,c,x[0]);
29234     lo += carry;
29235     carry = (lo<carry) + hi;
29236     z[0] = lo;
29237     mpfq_umul_ppmm(hi,lo,c,x[1]);
29238     lo += carry;
29239     carry = (lo<carry) + hi;
29240     z[1] = lo;
29241     mpfq_umul_ppmm(hi,lo,c,x[2]);
29242     lo += carry;
29243     carry = (lo<carry) + hi;
29244     z[2] = lo;
29245     mpfq_umul_ppmm(hi,lo,c,x[3]);
29246     lo += carry;
29247     carry = (lo<carry) + hi;
29248     z[3] = lo;
29249     mpfq_umul_ppmm(hi,lo,c,x[4]);
29250     lo += carry;
29251     carry = (lo<carry) + hi;
29252     z[4] = lo;
29253     mpfq_umul_ppmm(hi,lo,c,x[5]);
29254     lo += carry;
29255     carry = (lo<carry) + hi;
29256     z[5] = lo;
29257     mpfq_umul_ppmm(hi,lo,c,x[6]);
29258     lo += carry;
29259     carry = (lo<carry) + hi;
29260     z[6] = lo;
29261     mpfq_umul_ppmm(hi,lo,c,x[7]);
29262     lo += carry;
29263     carry = (lo<carry) + hi;
29264     z[7] = lo;
29265     mpfq_umul_ppmm(hi,lo,c,x[8]);
29266     lo += carry;
29267     carry = (lo<carry) + hi;
29268     z[8] = lo;
29269     mpfq_umul_ppmm(hi,lo,c,x[9]);
29270     lo += carry;
29271     carry = (lo<carry) + hi;
29272     z[9] = lo;
29273     mpfq_umul_ppmm(hi,lo,c,x[10]);
29274     lo += carry;
29275     carry = (lo<carry) + hi;
29276     z[10] = lo;
29277     z[11] = carry;
29278 }
29279 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mul1) */
29280 
29281 #if !defined(HAVE_native_mpfq_fixmp_10_5_shortmul)
29282 /* x and y have 10.5 words, z has 11.
29283  * Put the low 11 words of x*y in z. */
29284 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
29285 static inline
mpfq_fixmp_10_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)29286 void mpfq_fixmp_10_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
29287 {
29288     mpfq_zero(z, 11);
29289     mpfq_fixmp_10_addmul1_nc (z+0, x, y[0]);
29290     z[11-1] += x[10]*y[0];
29291     mpfq_fixmp_9_addmul1_nc (z+1, x, y[1]);
29292     z[11-1] += x[9]*y[1];
29293     mpfq_fixmp_8_addmul1_nc (z+2, x, y[2]);
29294     z[11-1] += x[8]*y[2];
29295     mpfq_fixmp_7_addmul1_nc (z+3, x, y[3]);
29296     z[11-1] += x[7]*y[3];
29297     mpfq_fixmp_6_addmul1_nc (z+4, x, y[4]);
29298     z[11-1] += x[6]*y[4];
29299     mpfq_fixmp_5_addmul1_nc (z+5, x, y[5]);
29300     z[11-1] += x[5]*y[5];
29301     mpfq_fixmp_4_addmul1_nc (z+6, x, y[6]);
29302     z[11-1] += x[4]*y[6];
29303     mpfq_fixmp_3_addmul1_nc (z+7, x, y[7]);
29304     z[11-1] += x[3]*y[7];
29305     mpfq_fixmp_2_addmul1_nc (z+8, x, y[8]);
29306     z[11-1] += x[2]*y[8];
29307     mpfq_fixmp_1_addmul1_nc (z+9, x, y[9]);
29308     z[11-1] += x[1]*y[9];
29309     z[11-1] += x[0]*y[11-1];
29310 }
29311 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_shortmul) */
29312 
29313 #if !defined(HAVE_native_mpfq_fixmp_10_5_addmul05)
29314 /* x has 10.5 words, z has 11. c is 0.5 word.
29315  * Put (z+x*c) in z. Return carry bit. */
29316 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
29317 static inline
mpfq_fixmp_10_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)29318 mp_limb_t mpfq_fixmp_10_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
29319 {
29320     mp_limb_t hi, lo, carry, buf;
29321     carry = 0;
29322     mpfq_umul_ppmm(hi,lo,c,x[0]);
29323     lo += carry;
29324     carry = (lo<carry) + hi;
29325     buf = z[0];
29326     lo += buf;
29327     carry += (lo<buf);
29328     z[0] = lo;
29329     mpfq_umul_ppmm(hi,lo,c,x[1]);
29330     lo += carry;
29331     carry = (lo<carry) + hi;
29332     buf = z[1];
29333     lo += buf;
29334     carry += (lo<buf);
29335     z[1] = lo;
29336     mpfq_umul_ppmm(hi,lo,c,x[2]);
29337     lo += carry;
29338     carry = (lo<carry) + hi;
29339     buf = z[2];
29340     lo += buf;
29341     carry += (lo<buf);
29342     z[2] = lo;
29343     mpfq_umul_ppmm(hi,lo,c,x[3]);
29344     lo += carry;
29345     carry = (lo<carry) + hi;
29346     buf = z[3];
29347     lo += buf;
29348     carry += (lo<buf);
29349     z[3] = lo;
29350     mpfq_umul_ppmm(hi,lo,c,x[4]);
29351     lo += carry;
29352     carry = (lo<carry) + hi;
29353     buf = z[4];
29354     lo += buf;
29355     carry += (lo<buf);
29356     z[4] = lo;
29357     mpfq_umul_ppmm(hi,lo,c,x[5]);
29358     lo += carry;
29359     carry = (lo<carry) + hi;
29360     buf = z[5];
29361     lo += buf;
29362     carry += (lo<buf);
29363     z[5] = lo;
29364     mpfq_umul_ppmm(hi,lo,c,x[6]);
29365     lo += carry;
29366     carry = (lo<carry) + hi;
29367     buf = z[6];
29368     lo += buf;
29369     carry += (lo<buf);
29370     z[6] = lo;
29371     mpfq_umul_ppmm(hi,lo,c,x[7]);
29372     lo += carry;
29373     carry = (lo<carry) + hi;
29374     buf = z[7];
29375     lo += buf;
29376     carry += (lo<buf);
29377     z[7] = lo;
29378     mpfq_umul_ppmm(hi,lo,c,x[8]);
29379     lo += carry;
29380     carry = (lo<carry) + hi;
29381     buf = z[8];
29382     lo += buf;
29383     carry += (lo<buf);
29384     z[8] = lo;
29385     mpfq_umul_ppmm(hi,lo,c,x[9]);
29386     lo += carry;
29387     carry = (lo<carry) + hi;
29388     buf = z[9];
29389     lo += buf;
29390     carry += (lo<buf);
29391     z[9] = lo;
29392     lo = c*x[10] + carry;
29393     assert(lo >= carry);
29394     z[10] += lo;
29395     return z[10] < lo;
29396 }
29397 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_addmul05) */
29398 
29399 #if !defined(HAVE_native_mpfq_fixmp_10_5_mul05)
29400 /* x has 10.5 words, z has 11. c is 0.5 word.
29401  * Put (x*c) in z. No carry. */
29402 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
29403 static inline
mpfq_fixmp_10_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)29404 void mpfq_fixmp_10_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
29405 {
29406     mp_limb_t hi, lo, carry;
29407     carry = 0;
29408     mpfq_umul_ppmm(hi,lo,c,x[0]);
29409     lo += carry;
29410     carry = (lo<carry) + hi;
29411     z[0] = lo;
29412     mpfq_umul_ppmm(hi,lo,c,x[1]);
29413     lo += carry;
29414     carry = (lo<carry) + hi;
29415     z[1] = lo;
29416     mpfq_umul_ppmm(hi,lo,c,x[2]);
29417     lo += carry;
29418     carry = (lo<carry) + hi;
29419     z[2] = lo;
29420     mpfq_umul_ppmm(hi,lo,c,x[3]);
29421     lo += carry;
29422     carry = (lo<carry) + hi;
29423     z[3] = lo;
29424     mpfq_umul_ppmm(hi,lo,c,x[4]);
29425     lo += carry;
29426     carry = (lo<carry) + hi;
29427     z[4] = lo;
29428     mpfq_umul_ppmm(hi,lo,c,x[5]);
29429     lo += carry;
29430     carry = (lo<carry) + hi;
29431     z[5] = lo;
29432     mpfq_umul_ppmm(hi,lo,c,x[6]);
29433     lo += carry;
29434     carry = (lo<carry) + hi;
29435     z[6] = lo;
29436     mpfq_umul_ppmm(hi,lo,c,x[7]);
29437     lo += carry;
29438     carry = (lo<carry) + hi;
29439     z[7] = lo;
29440     mpfq_umul_ppmm(hi,lo,c,x[8]);
29441     lo += carry;
29442     carry = (lo<carry) + hi;
29443     z[8] = lo;
29444     mpfq_umul_ppmm(hi,lo,c,x[9]);
29445     lo += carry;
29446     carry = (lo<carry) + hi;
29447     z[9] = lo;
29448     lo = c*x[10] + carry;
29449     assert(lo >= carry);
29450     z[10] = lo;
29451 }
29452 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mul05) */
29453 
29454 #if !defined(HAVE_native_mpfq_fixmp_10_5_mod)
29455 /* x has 21 words. z and p have 10.5 words, and the high word of p is non-zero.
29456  * Put x mod p in z. */
29457 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
29458 /* Triggered by: 10_5_mgy_decode */
29459 static inline
mpfq_fixmp_10_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)29460 void mpfq_fixmp_10_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
29461 {
29462     mp_limb_t q[10+1], r[11];
29463     assert (p[11-1] != 0);
29464     mpn_tdiv_qr(q, r, 0, x, 21, p, 11);
29465     mpfq_copy(z, r, 11);
29466 }
29467 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mod) */
29468 
29469 #if !defined(HAVE_native_mpfq_fixmp_10_5_rshift)
29470 /* a has 10.5 words. Shift it in place by cnt bits to the right.
29471  * The shift count cnt must not exceed the word size.
29472  * Note that no carry is returned for the bits shifted out. */
29473 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
29474 /* Triggered by: 10_5_invmod */
29475 static inline
mpfq_fixmp_10_5_rshift(mp_limb_t * a,int cnt)29476 void mpfq_fixmp_10_5_rshift(mp_limb_t * a, int cnt)
29477 {
29478     if (!cnt) return;
29479     int i;
29480     int dnt = GMP_NUMB_BITS - cnt;
29481     for (i = 0; i < 11-1; ++i) {
29482         a[i] >>= cnt;
29483         a[i] |= (a[i+1] << dnt);
29484     }
29485     a[11-1] >>= cnt;
29486 }
29487 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_rshift) */
29488 
29489 #if !defined(HAVE_native_mpfq_fixmp_10_5_long_rshift)
29490 /* a has 10.5 words. Shift it in place by off words plus cnt bits to the left.
29491  * Note that no carry is returned for the bits shifted out. */
29492 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
29493 /* Triggered by: 10_5_invmod */
29494 static inline
mpfq_fixmp_10_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)29495 void mpfq_fixmp_10_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
29496 {
29497     if (cnt) {
29498         int dnt = GMP_NUMB_BITS - cnt;
29499         for (int i = 0; i < 11 - off - 1; ++i) {
29500             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
29501         }
29502         a[11-off-1] = a[11-1]>>cnt;
29503     } else {
29504         mpfq_copyi(a, a + off, 11 - off);
29505     }
29506     mpfq_zero(a + 11 - off, off);
29507 }
29508 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_long_rshift) */
29509 
29510 #if !defined(HAVE_native_mpfq_fixmp_10_5_long_lshift)
29511 /* a has 10.5 words. Shift it in place by off words plus cnt bits to the left.
29512  * Note that no carry is returned for the bits shifted out. */
29513 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
29514 /* Triggered by: 10_5_invmod */
29515 static inline
mpfq_fixmp_10_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)29516 void mpfq_fixmp_10_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
29517 {
29518     int i;
29519     if (cnt) {
29520         int dnt = GMP_NUMB_BITS - cnt;
29521         for (i = 11-1; i>off; --i) {
29522             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
29523         }
29524         a[off] = a[0]<<cnt;
29525     } else {
29526         mpfq_copyd(a + off, a, 11 - off);
29527     }
29528     mpfq_zero(a, off);
29529 }
29530 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_long_lshift) */
29531 
29532 #if !defined(HAVE_native_mpfq_fixmp_10_5_invmod)
29533 /* x, z, and p have 10.5 words. Put inverse of x mod p in z.
29534  * Return non-zero if an inverse could be found.
29535  * If no inverse could be found, return 0 and set z to zero.
29536  */
29537 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
29538 static inline
mpfq_fixmp_10_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)29539 int mpfq_fixmp_10_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
29540 {
29541       mp_limb_t u[11], v[11], a[11], b[11], fix[11];
29542       int i, t, lsh;
29543 
29544       mpfq_zero(u, 11);
29545       mpfq_zero(v, 11);
29546       mpfq_copy(a, x, 11);
29547       mpfq_copy(b, p, 11);
29548       u[0] = 1UL;
29549 
29550       if (mpfq_fixmp_10_5_cmp(a, v) == 0 || mpfq_fixmp_10_5_cmp(a, b) == 0) {
29551         mpfq_zero(res, 11);
29552         return 0;
29553       }
29554 
29555       mpfq_fixmp_10_5_add(fix, b, u);
29556       mpfq_fixmp_10_5_rshift(fix, 1);
29557 
29558       assert (mpfq_fixmp_10_5_cmp(a,b) < 0);
29559 
29560       t = 0;
29561 
29562       for(i = 0 ; !a[i] ; i++) ;
29563       assert (i < 11);
29564       lsh = mpfq_ctzl(a[i]);
29565       mpfq_fixmp_10_5_long_rshift(a, i, lsh);
29566       t += lsh + i*GMP_NUMB_BITS;
29567       mpfq_fixmp_10_5_long_lshift(v, i, lsh);
29568 
29569       do {
29570         do {
29571           mpfq_fixmp_10_5_sub(b, b, a);
29572           mpfq_fixmp_10_5_add(v, v, u);
29573           for(i = 0 ; !b[i] ; i++) ;
29574           assert (i < 11);
29575           lsh = mpfq_ctzl(b[i]);
29576           mpfq_fixmp_10_5_long_rshift(b, i, lsh);
29577           t += lsh + i*GMP_NUMB_BITS;
29578           mpfq_fixmp_10_5_long_lshift(u, i, lsh);
29579         } while (mpfq_fixmp_10_5_cmp(a,b) < 0);
29580         if (mpfq_fixmp_10_5_cmp(a, b) == 0)
29581           break;
29582         do {
29583           mpfq_fixmp_10_5_sub(a, a, b);
29584           mpfq_fixmp_10_5_add(u, u, v);
29585           for(i = 0 ; !a[i] ; i++) ;
29586           assert (i < 11);
29587           lsh = mpfq_ctzl(a[i]);
29588           mpfq_fixmp_10_5_long_rshift(a, i, lsh);
29589           t += lsh + i*GMP_NUMB_BITS;
29590           mpfq_fixmp_10_5_long_lshift(v, i, lsh);
29591         } while (mpfq_fixmp_10_5_cmp(b,a)<0);
29592       } while (mpfq_fixmp_10_5_cmp(a,b) != 0);
29593       {
29594         if (mpfq_fixmp_10_5_cmp_ui(a, 1) != 0) {
29595           mpfq_copy(res, a, 11);
29596           return 0;
29597         }
29598       }
29599       while (t>0) {
29600         mp_limb_t sig = u[0] & 1UL;
29601         mpfq_fixmp_10_5_rshift(u, 1);
29602         if (sig)
29603           mpfq_fixmp_10_5_add(u, u, fix);
29604         --t;
29605       }
29606       mpfq_copy(res, u, 11);
29607       return 1;
29608 }
29609 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_invmod) */
29610 
29611 #if !defined(HAVE_native_mpfq_fixmp_10_5_redc)
29612 /* x has 21 words, z and p have 10.5 words.
29613  * only one word is read from invp.
29614  * Assuming R=W^11 is the redc modulus, we expect that x verifies:
29615  *   x < R*p,
29616  * so that we have eventually z < p, z congruent to x/R mod p.
29617  * The contents of the area pointed by x are clobbered by this call.
29618  * Note also that x may alias z.
29619  */
29620 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
29621 static inline
mpfq_fixmp_10_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)29622 void mpfq_fixmp_10_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
29623 {
29624     mp_limb_t cy;
29625     for(int i = 0; i < 11; ++i) {
29626         mp_limb_t t = x[i]*mip[0];
29627         cy = mpfq_fixmp_10_5_addmul1_shortz(x+i, p, t);
29628         assert (x[i] == 0);
29629         x[i] = cy;
29630     }
29631     {
29632         mp_limb_t ret[11] = { x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19], x[20], 0 };
29633         cy = mpfq_fixmp_10_5_add(x, x, ret);
29634     }
29635     /* At this point, we have (x' denotes x + cy*W^n here)
29636     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
29637     * x'/R < p + p
29638     */
29639     if (cy || mpfq_fixmp_10_5_cmp(x, p) >= 0) {
29640         mpfq_fixmp_10_5_sub(z, x, p);
29641     } else {
29642         mpfq_copy(z, x, 11);
29643     }
29644 }
29645 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_redc) */
29646 
29647 #if !defined(HAVE_native_mpfq_fixmp_10_5_redc_ur)
29648 /* x has 22 words, z and p have 10.5 words.
29649  * only one word is read from invp.
29650  * Assuming R=W^11 is the redc modulus, we expect that x verifies:
29651  *  x < W*W^10.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
29652  * so that we have eventually z < p, z congruent to x/R mod p.
29653  * The contents of the area pointed by x are clobbered by this call.
29654  * Note also that x may alias z.
29655  */
29656 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
29657 static inline
mpfq_fixmp_10_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)29658 void mpfq_fixmp_10_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
29659 {
29660     mp_limb_t cy, q[1];
29661     for(int i = 0; i < 11; ++i) {
29662         mp_limb_t t = x[i]*mip[0];
29663         cy = mpfq_fixmp_10_5_addmul1_shortz(x+i, p, t);
29664         assert (x[i] == 0);
29665         x[i] = cy;
29666     }
29667     cy = mpfq_fixmp_10_5_add(x + 11, x, x + 11);
29668     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
29669     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
29670     * x'/R < (W^0.5+1)*p
29671     */
29672     if (cy) {
29673         /* x'/R-p < W^0.5*p, which fits in n words. */
29674         mpfq_fixmp_10_5_sub(x + 11, x + 11, p);
29675     }
29676     mpn_tdiv_qr(q, z, 0, x + 11, 11, p, 11);
29677 }
29678 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_redc_ur) */
29679 
29680 #if !defined(HAVE_native_mpfq_fixmp_10_5_mgy_encode)
29681 /* x, z, and p have 10.5 words.
29682  * Assuming R=W^11 is the redc modulus, we compute z=R*x mod p. */
29683 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
29684 static inline
mpfq_fixmp_10_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)29685 void mpfq_fixmp_10_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
29686 {
29687     mp_limb_t t[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10] };
29688     mp_limb_t qq[11+1];
29689     mpn_tdiv_qr(qq, z, 0, t, 22, p, 11);
29690 }
29691 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mgy_encode) */
29692 
29693 #if !defined(HAVE_native_mpfq_fixmp_10_5_mgy_decode)
29694 /* x, z, invR, and p have 10.5 words.
29695  * Assuming R=W^11 is the redc modulus, we compute z=x/R mod p. */
29696 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
29697 static inline
mpfq_fixmp_10_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)29698 void mpfq_fixmp_10_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
29699 {
29700     mp_limb_t t[22];
29701     mpfq_fixmp_10_5_mul(t, x, invR);
29702     mpfq_fixmp_10_5_mod(z, t, p);
29703 }
29704 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_mgy_decode) */
29705 
29706 #if !defined(HAVE_native_mpfq_fixmp_10_5_lshift)
29707 /* a has 10.5 words. Shift it in place by cnt bits to the left.
29708  * The shift count cnt must not exceed the word size.
29709  * Note that no carry is returned for the bits shifted out. */
29710 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
29711 static inline
mpfq_fixmp_10_5_lshift(mp_limb_t * a,int cnt)29712 void mpfq_fixmp_10_5_lshift(mp_limb_t * a, int cnt)
29713 {
29714     if (!cnt) return;
29715     int i;
29716     int dnt = GMP_NUMB_BITS - cnt;
29717     for (i = 11-1; i>0; --i) {
29718         a[i] <<= cnt;
29719         a[i] |= (a[i-1] >> dnt);
29720     }
29721     a[0] <<= cnt;
29722 }
29723 #endif /* !defined(HAVE_native_mpfq_fixmp_10_5_lshift) */
29724 
29725 #if !defined(HAVE_native_mpfq_fixmp_11_5_add)
29726 /* x, y, and z have 11.5 words. Result in z. Return carry bit */
29727 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
29728 /* Triggered by: 11_5_invmod, 11_5_redc, 11_5_redc_ur */
29729 static inline
mpfq_fixmp_11_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)29730 mp_limb_t mpfq_fixmp_11_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
29731 {
29732     mp_limb_t r, s, t, cy, cy1, cy2;
29733     cy = 0;
29734     r = x[0];
29735     s = r + y[0];
29736     cy1 = s < r;
29737     t = s + cy;
29738     cy2 = t < s;
29739     cy = cy1 | cy2;
29740     z[0] = t;
29741     r = x[1];
29742     s = r + y[1];
29743     cy1 = s < r;
29744     t = s + cy;
29745     cy2 = t < s;
29746     cy = cy1 | cy2;
29747     z[1] = t;
29748     r = x[2];
29749     s = r + y[2];
29750     cy1 = s < r;
29751     t = s + cy;
29752     cy2 = t < s;
29753     cy = cy1 | cy2;
29754     z[2] = t;
29755     r = x[3];
29756     s = r + y[3];
29757     cy1 = s < r;
29758     t = s + cy;
29759     cy2 = t < s;
29760     cy = cy1 | cy2;
29761     z[3] = t;
29762     r = x[4];
29763     s = r + y[4];
29764     cy1 = s < r;
29765     t = s + cy;
29766     cy2 = t < s;
29767     cy = cy1 | cy2;
29768     z[4] = t;
29769     r = x[5];
29770     s = r + y[5];
29771     cy1 = s < r;
29772     t = s + cy;
29773     cy2 = t < s;
29774     cy = cy1 | cy2;
29775     z[5] = t;
29776     r = x[6];
29777     s = r + y[6];
29778     cy1 = s < r;
29779     t = s + cy;
29780     cy2 = t < s;
29781     cy = cy1 | cy2;
29782     z[6] = t;
29783     r = x[7];
29784     s = r + y[7];
29785     cy1 = s < r;
29786     t = s + cy;
29787     cy2 = t < s;
29788     cy = cy1 | cy2;
29789     z[7] = t;
29790     r = x[8];
29791     s = r + y[8];
29792     cy1 = s < r;
29793     t = s + cy;
29794     cy2 = t < s;
29795     cy = cy1 | cy2;
29796     z[8] = t;
29797     r = x[9];
29798     s = r + y[9];
29799     cy1 = s < r;
29800     t = s + cy;
29801     cy2 = t < s;
29802     cy = cy1 | cy2;
29803     z[9] = t;
29804     r = x[10];
29805     s = r + y[10];
29806     cy1 = s < r;
29807     t = s + cy;
29808     cy2 = t < s;
29809     cy = cy1 | cy2;
29810     z[10] = t;
29811     r = x[11];
29812     s = r + y[11];
29813     cy1 = s < r;
29814     t = s + cy;
29815     cy2 = t < s;
29816     cy = cy1 | cy2;
29817     z[11] = t;
29818     return cy;
29819 }
29820 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_add) */
29821 
29822 #if !defined(HAVE_native_mpfq_fixmp_11_5_sub)
29823 /* x, y, and z have 11.5 words. Result in z. Return borrow bit */
29824 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
29825 /* Triggered by: 11_5_invmod, 11_5_redc, 11_5_redc_ur */
29826 static inline
mpfq_fixmp_11_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)29827 mp_limb_t mpfq_fixmp_11_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
29828 {
29829     mp_limb_t r, s, t, cy, cy1, cy2;
29830     cy = 0;
29831     r = x[0];
29832     s = r - y[0];
29833     cy1 = s > r;
29834     t = s - cy;
29835     cy2 = t > s;
29836     cy = cy1 | cy2;
29837     z[0] = t;
29838     r = x[1];
29839     s = r - y[1];
29840     cy1 = s > r;
29841     t = s - cy;
29842     cy2 = t > s;
29843     cy = cy1 | cy2;
29844     z[1] = t;
29845     r = x[2];
29846     s = r - y[2];
29847     cy1 = s > r;
29848     t = s - cy;
29849     cy2 = t > s;
29850     cy = cy1 | cy2;
29851     z[2] = t;
29852     r = x[3];
29853     s = r - y[3];
29854     cy1 = s > r;
29855     t = s - cy;
29856     cy2 = t > s;
29857     cy = cy1 | cy2;
29858     z[3] = t;
29859     r = x[4];
29860     s = r - y[4];
29861     cy1 = s > r;
29862     t = s - cy;
29863     cy2 = t > s;
29864     cy = cy1 | cy2;
29865     z[4] = t;
29866     r = x[5];
29867     s = r - y[5];
29868     cy1 = s > r;
29869     t = s - cy;
29870     cy2 = t > s;
29871     cy = cy1 | cy2;
29872     z[5] = t;
29873     r = x[6];
29874     s = r - y[6];
29875     cy1 = s > r;
29876     t = s - cy;
29877     cy2 = t > s;
29878     cy = cy1 | cy2;
29879     z[6] = t;
29880     r = x[7];
29881     s = r - y[7];
29882     cy1 = s > r;
29883     t = s - cy;
29884     cy2 = t > s;
29885     cy = cy1 | cy2;
29886     z[7] = t;
29887     r = x[8];
29888     s = r - y[8];
29889     cy1 = s > r;
29890     t = s - cy;
29891     cy2 = t > s;
29892     cy = cy1 | cy2;
29893     z[8] = t;
29894     r = x[9];
29895     s = r - y[9];
29896     cy1 = s > r;
29897     t = s - cy;
29898     cy2 = t > s;
29899     cy = cy1 | cy2;
29900     z[9] = t;
29901     r = x[10];
29902     s = r - y[10];
29903     cy1 = s > r;
29904     t = s - cy;
29905     cy2 = t > s;
29906     cy = cy1 | cy2;
29907     z[10] = t;
29908     r = x[11];
29909     s = r - y[11];
29910     cy1 = s > r;
29911     t = s - cy;
29912     cy2 = t > s;
29913     cy = cy1 | cy2;
29914     z[11] = t;
29915     return cy;
29916 }
29917 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_sub) */
29918 
29919 #if !defined(HAVE_native_mpfq_fixmp_11_5_add_nc)
29920 /* x, y, and z have 11.5 words. Result in z. Carry bit is lost. */
29921 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
29922 static inline
mpfq_fixmp_11_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)29923 void mpfq_fixmp_11_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
29924 {
29925     mp_limb_t r, s, t, cy, cy1, cy2;
29926     cy = 0;
29927     r = x[0];
29928     s = r + y[0];
29929     cy1 = s < r;
29930     t = s + cy;
29931     cy2 = t < s;
29932     cy = cy1 | cy2;
29933     z[0] = t;
29934     r = x[1];
29935     s = r + y[1];
29936     cy1 = s < r;
29937     t = s + cy;
29938     cy2 = t < s;
29939     cy = cy1 | cy2;
29940     z[1] = t;
29941     r = x[2];
29942     s = r + y[2];
29943     cy1 = s < r;
29944     t = s + cy;
29945     cy2 = t < s;
29946     cy = cy1 | cy2;
29947     z[2] = t;
29948     r = x[3];
29949     s = r + y[3];
29950     cy1 = s < r;
29951     t = s + cy;
29952     cy2 = t < s;
29953     cy = cy1 | cy2;
29954     z[3] = t;
29955     r = x[4];
29956     s = r + y[4];
29957     cy1 = s < r;
29958     t = s + cy;
29959     cy2 = t < s;
29960     cy = cy1 | cy2;
29961     z[4] = t;
29962     r = x[5];
29963     s = r + y[5];
29964     cy1 = s < r;
29965     t = s + cy;
29966     cy2 = t < s;
29967     cy = cy1 | cy2;
29968     z[5] = t;
29969     r = x[6];
29970     s = r + y[6];
29971     cy1 = s < r;
29972     t = s + cy;
29973     cy2 = t < s;
29974     cy = cy1 | cy2;
29975     z[6] = t;
29976     r = x[7];
29977     s = r + y[7];
29978     cy1 = s < r;
29979     t = s + cy;
29980     cy2 = t < s;
29981     cy = cy1 | cy2;
29982     z[7] = t;
29983     r = x[8];
29984     s = r + y[8];
29985     cy1 = s < r;
29986     t = s + cy;
29987     cy2 = t < s;
29988     cy = cy1 | cy2;
29989     z[8] = t;
29990     r = x[9];
29991     s = r + y[9];
29992     cy1 = s < r;
29993     t = s + cy;
29994     cy2 = t < s;
29995     cy = cy1 | cy2;
29996     z[9] = t;
29997     r = x[10];
29998     s = r + y[10];
29999     cy1 = s < r;
30000     t = s + cy;
30001     cy2 = t < s;
30002     cy = cy1 | cy2;
30003     z[10] = t;
30004     r = x[11];
30005     s = r + y[11];
30006     cy1 = s < r;
30007     t = s + cy;
30008     cy2 = t < s;
30009     cy = cy1 | cy2;
30010     z[11] = t;
30011 }
30012 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_add_nc) */
30013 
30014 #if !defined(HAVE_native_mpfq_fixmp_11_5_sub_nc)
30015 /* x, y, and z have 11.5 words. Result in z. Borrow bit is lost. */
30016 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
30017 static inline
mpfq_fixmp_11_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)30018 void mpfq_fixmp_11_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
30019 {
30020     mp_limb_t r, s, t, cy, cy1, cy2;
30021     cy = 0;
30022     r = x[0];
30023     s = r - y[0];
30024     cy1 = s > r;
30025     t = s - cy;
30026     cy2 = t > s;
30027     cy = cy1 | cy2;
30028     z[0] = t;
30029     r = x[1];
30030     s = r - y[1];
30031     cy1 = s > r;
30032     t = s - cy;
30033     cy2 = t > s;
30034     cy = cy1 | cy2;
30035     z[1] = t;
30036     r = x[2];
30037     s = r - y[2];
30038     cy1 = s > r;
30039     t = s - cy;
30040     cy2 = t > s;
30041     cy = cy1 | cy2;
30042     z[2] = t;
30043     r = x[3];
30044     s = r - y[3];
30045     cy1 = s > r;
30046     t = s - cy;
30047     cy2 = t > s;
30048     cy = cy1 | cy2;
30049     z[3] = t;
30050     r = x[4];
30051     s = r - y[4];
30052     cy1 = s > r;
30053     t = s - cy;
30054     cy2 = t > s;
30055     cy = cy1 | cy2;
30056     z[4] = t;
30057     r = x[5];
30058     s = r - y[5];
30059     cy1 = s > r;
30060     t = s - cy;
30061     cy2 = t > s;
30062     cy = cy1 | cy2;
30063     z[5] = t;
30064     r = x[6];
30065     s = r - y[6];
30066     cy1 = s > r;
30067     t = s - cy;
30068     cy2 = t > s;
30069     cy = cy1 | cy2;
30070     z[6] = t;
30071     r = x[7];
30072     s = r - y[7];
30073     cy1 = s > r;
30074     t = s - cy;
30075     cy2 = t > s;
30076     cy = cy1 | cy2;
30077     z[7] = t;
30078     r = x[8];
30079     s = r - y[8];
30080     cy1 = s > r;
30081     t = s - cy;
30082     cy2 = t > s;
30083     cy = cy1 | cy2;
30084     z[8] = t;
30085     r = x[9];
30086     s = r - y[9];
30087     cy1 = s > r;
30088     t = s - cy;
30089     cy2 = t > s;
30090     cy = cy1 | cy2;
30091     z[9] = t;
30092     r = x[10];
30093     s = r - y[10];
30094     cy1 = s > r;
30095     t = s - cy;
30096     cy2 = t > s;
30097     cy = cy1 | cy2;
30098     z[10] = t;
30099     r = x[11];
30100     s = r - y[11];
30101     cy1 = s > r;
30102     t = s - cy;
30103     cy2 = t > s;
30104     cy = cy1 | cy2;
30105     z[11] = t;
30106 }
30107 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_sub_nc) */
30108 
30109 #if !defined(HAVE_native_mpfq_fixmp_11_5_add_ui)
30110 /* x, y, and z have 11.5 words. Result in z. Return carry bit */
30111 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
30112 static inline
mpfq_fixmp_11_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)30113 mp_limb_t mpfq_fixmp_11_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
30114 {
30115     mp_limb_t r, s, t, cy, cy1, cy2;
30116     cy = 0;
30117     r = x[0];
30118     s = r + y;
30119     cy1 = s < r;
30120     t = s + cy;
30121     cy2 = t < s;
30122     cy = cy1 | cy2;
30123     z[0] = t;
30124     s = x[1];
30125     t = s + cy;
30126     cy = t < s;
30127     z[1] = t;
30128     s = x[2];
30129     t = s + cy;
30130     cy = t < s;
30131     z[2] = t;
30132     s = x[3];
30133     t = s + cy;
30134     cy = t < s;
30135     z[3] = t;
30136     s = x[4];
30137     t = s + cy;
30138     cy = t < s;
30139     z[4] = t;
30140     s = x[5];
30141     t = s + cy;
30142     cy = t < s;
30143     z[5] = t;
30144     s = x[6];
30145     t = s + cy;
30146     cy = t < s;
30147     z[6] = t;
30148     s = x[7];
30149     t = s + cy;
30150     cy = t < s;
30151     z[7] = t;
30152     s = x[8];
30153     t = s + cy;
30154     cy = t < s;
30155     z[8] = t;
30156     s = x[9];
30157     t = s + cy;
30158     cy = t < s;
30159     z[9] = t;
30160     s = x[10];
30161     t = s + cy;
30162     cy = t < s;
30163     z[10] = t;
30164     s = x[11];
30165     t = s + cy;
30166     cy = t < s;
30167     z[11] = t;
30168     return cy;
30169 }
30170 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_add_ui) */
30171 
30172 #if !defined(HAVE_native_mpfq_fixmp_11_5_sub_ui)
30173 /* x, y, and z have 11.5 words. Result in z. Return borrow bit */
30174 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
30175 static inline
mpfq_fixmp_11_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)30176 mp_limb_t mpfq_fixmp_11_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
30177 {
30178     mp_limb_t r, s, t, cy, cy1, cy2;
30179     cy = 0;
30180     r = x[0];
30181     s = r - y;
30182     cy1 = s > r;
30183     t = s - cy;
30184     cy2 = t > s;
30185     cy = cy1 | cy2;
30186     z[0] = t;
30187     s = x[1];
30188     t = s - cy;
30189     cy = t > s;
30190     z[1] = t;
30191     s = x[2];
30192     t = s - cy;
30193     cy = t > s;
30194     z[2] = t;
30195     s = x[3];
30196     t = s - cy;
30197     cy = t > s;
30198     z[3] = t;
30199     s = x[4];
30200     t = s - cy;
30201     cy = t > s;
30202     z[4] = t;
30203     s = x[5];
30204     t = s - cy;
30205     cy = t > s;
30206     z[5] = t;
30207     s = x[6];
30208     t = s - cy;
30209     cy = t > s;
30210     z[6] = t;
30211     s = x[7];
30212     t = s - cy;
30213     cy = t > s;
30214     z[7] = t;
30215     s = x[8];
30216     t = s - cy;
30217     cy = t > s;
30218     z[8] = t;
30219     s = x[9];
30220     t = s - cy;
30221     cy = t > s;
30222     z[9] = t;
30223     s = x[10];
30224     t = s - cy;
30225     cy = t > s;
30226     z[10] = t;
30227     s = x[11];
30228     t = s - cy;
30229     cy = t > s;
30230     z[11] = t;
30231     return cy;
30232 }
30233 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_sub_ui) */
30234 
30235 #if !defined(HAVE_native_mpfq_fixmp_11_5_add_ui_nc)
30236 /* x, y, and z have 11.5 words. Result in z. Carry bit is lost. */
30237 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
30238 static inline
mpfq_fixmp_11_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)30239 void mpfq_fixmp_11_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
30240 {
30241     mp_limb_t r, s, t, cy, cy1, cy2;
30242     cy = 0;
30243     r = x[0];
30244     s = r + y;
30245     cy1 = s < r;
30246     t = s + cy;
30247     cy2 = t < s;
30248     cy = cy1 | cy2;
30249     z[0] = t;
30250     s = x[1];
30251     t = s + cy;
30252     cy = t < s;
30253     z[1] = t;
30254     s = x[2];
30255     t = s + cy;
30256     cy = t < s;
30257     z[2] = t;
30258     s = x[3];
30259     t = s + cy;
30260     cy = t < s;
30261     z[3] = t;
30262     s = x[4];
30263     t = s + cy;
30264     cy = t < s;
30265     z[4] = t;
30266     s = x[5];
30267     t = s + cy;
30268     cy = t < s;
30269     z[5] = t;
30270     s = x[6];
30271     t = s + cy;
30272     cy = t < s;
30273     z[6] = t;
30274     s = x[7];
30275     t = s + cy;
30276     cy = t < s;
30277     z[7] = t;
30278     s = x[8];
30279     t = s + cy;
30280     cy = t < s;
30281     z[8] = t;
30282     s = x[9];
30283     t = s + cy;
30284     cy = t < s;
30285     z[9] = t;
30286     s = x[10];
30287     t = s + cy;
30288     cy = t < s;
30289     z[10] = t;
30290     s = x[11];
30291     t = s + cy;
30292     cy = t < s;
30293     z[11] = t;
30294 }
30295 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_add_ui_nc) */
30296 
30297 #if !defined(HAVE_native_mpfq_fixmp_11_5_sub_ui_nc)
30298 /* x, y, and z have 11.5 words. Result in z. Borrow bit is lost. */
30299 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
30300 static inline
mpfq_fixmp_11_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)30301 void mpfq_fixmp_11_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
30302 {
30303     mp_limb_t r, s, t, cy, cy1, cy2;
30304     cy = 0;
30305     r = x[0];
30306     s = r - y;
30307     cy1 = s > r;
30308     t = s - cy;
30309     cy2 = t > s;
30310     cy = cy1 | cy2;
30311     z[0] = t;
30312     s = x[1];
30313     t = s - cy;
30314     cy = t > s;
30315     z[1] = t;
30316     s = x[2];
30317     t = s - cy;
30318     cy = t > s;
30319     z[2] = t;
30320     s = x[3];
30321     t = s - cy;
30322     cy = t > s;
30323     z[3] = t;
30324     s = x[4];
30325     t = s - cy;
30326     cy = t > s;
30327     z[4] = t;
30328     s = x[5];
30329     t = s - cy;
30330     cy = t > s;
30331     z[5] = t;
30332     s = x[6];
30333     t = s - cy;
30334     cy = t > s;
30335     z[6] = t;
30336     s = x[7];
30337     t = s - cy;
30338     cy = t > s;
30339     z[7] = t;
30340     s = x[8];
30341     t = s - cy;
30342     cy = t > s;
30343     z[8] = t;
30344     s = x[9];
30345     t = s - cy;
30346     cy = t > s;
30347     z[9] = t;
30348     s = x[10];
30349     t = s - cy;
30350     cy = t > s;
30351     z[10] = t;
30352     s = x[11];
30353     t = s - cy;
30354     cy = t > s;
30355     z[11] = t;
30356 }
30357 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_sub_ui_nc) */
30358 
30359 #if !defined(HAVE_native_mpfq_fixmp_11_5_cmp)
30360 /* x and y have 11.5 words. Return sign of difference x-y. */
30361 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
30362 /* Triggered by: 11_5_invmod, 11_5_redc, 11_5_redc_ur */
30363 static inline
mpfq_fixmp_11_5_cmp(const mp_limb_t * x,const mp_limb_t * y)30364 int mpfq_fixmp_11_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
30365 {
30366     for (int i = 12-1; i >= 0; --i) {
30367         if (x[i] > y[i]) return 1;
30368         if (x[i] < y[i]) return -1;
30369     }
30370     return 0;
30371 }
30372 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_cmp) */
30373 
30374 #if !defined(HAVE_native_mpfq_fixmp_11_5_cmp_ui)
30375 /* x has 11.5 words. Return sign of difference x-y. */
30376 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
30377 /* Triggered by: 11_5_invmod */
30378 static inline
mpfq_fixmp_11_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)30379 int mpfq_fixmp_11_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
30380 {
30381     for (int i = 12-1; i > 0; --i) {
30382         if (x[i]) return 1;
30383     }
30384     if (x[0]>y) return 1;
30385     if (x[0]<y) return -1;
30386     return 0;
30387 }
30388 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_cmp_ui) */
30389 
30390 #if !defined(HAVE_native_mpfq_fixmp_11_5_addmul1)
30391 /* x has 11.5 words, z has 13.
30392  * Put (z+x*c) in z. Return carry bit. */
30393 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
30394 static inline
mpfq_fixmp_11_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30395 mp_limb_t mpfq_fixmp_11_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30396 {
30397     mp_limb_t hi, lo, carry, buf;
30398     carry = 0;
30399     mpfq_umul_ppmm(hi,lo,c,x[0]);
30400     lo += carry;
30401     carry = (lo<carry) + hi;
30402     buf = z[0];
30403     lo += buf;
30404     carry += (lo<buf);
30405     z[0] = lo;
30406     mpfq_umul_ppmm(hi,lo,c,x[1]);
30407     lo += carry;
30408     carry = (lo<carry) + hi;
30409     buf = z[1];
30410     lo += buf;
30411     carry += (lo<buf);
30412     z[1] = lo;
30413     mpfq_umul_ppmm(hi,lo,c,x[2]);
30414     lo += carry;
30415     carry = (lo<carry) + hi;
30416     buf = z[2];
30417     lo += buf;
30418     carry += (lo<buf);
30419     z[2] = lo;
30420     mpfq_umul_ppmm(hi,lo,c,x[3]);
30421     lo += carry;
30422     carry = (lo<carry) + hi;
30423     buf = z[3];
30424     lo += buf;
30425     carry += (lo<buf);
30426     z[3] = lo;
30427     mpfq_umul_ppmm(hi,lo,c,x[4]);
30428     lo += carry;
30429     carry = (lo<carry) + hi;
30430     buf = z[4];
30431     lo += buf;
30432     carry += (lo<buf);
30433     z[4] = lo;
30434     mpfq_umul_ppmm(hi,lo,c,x[5]);
30435     lo += carry;
30436     carry = (lo<carry) + hi;
30437     buf = z[5];
30438     lo += buf;
30439     carry += (lo<buf);
30440     z[5] = lo;
30441     mpfq_umul_ppmm(hi,lo,c,x[6]);
30442     lo += carry;
30443     carry = (lo<carry) + hi;
30444     buf = z[6];
30445     lo += buf;
30446     carry += (lo<buf);
30447     z[6] = lo;
30448     mpfq_umul_ppmm(hi,lo,c,x[7]);
30449     lo += carry;
30450     carry = (lo<carry) + hi;
30451     buf = z[7];
30452     lo += buf;
30453     carry += (lo<buf);
30454     z[7] = lo;
30455     mpfq_umul_ppmm(hi,lo,c,x[8]);
30456     lo += carry;
30457     carry = (lo<carry) + hi;
30458     buf = z[8];
30459     lo += buf;
30460     carry += (lo<buf);
30461     z[8] = lo;
30462     mpfq_umul_ppmm(hi,lo,c,x[9]);
30463     lo += carry;
30464     carry = (lo<carry) + hi;
30465     buf = z[9];
30466     lo += buf;
30467     carry += (lo<buf);
30468     z[9] = lo;
30469     mpfq_umul_ppmm(hi,lo,c,x[10]);
30470     lo += carry;
30471     carry = (lo<carry) + hi;
30472     buf = z[10];
30473     lo += buf;
30474     carry += (lo<buf);
30475     z[10] = lo;
30476     mpfq_umul_ppmm(hi,lo,c,x[11]);
30477     lo += carry;
30478     carry = (lo<carry) + hi;
30479     buf = z[11];
30480     lo += buf;
30481     carry += (lo<buf);
30482     z[11] = lo;
30483     z[12] += carry;
30484     return (z[12]<carry);
30485 }
30486 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_addmul1) */
30487 
30488 #if !defined(HAVE_native_mpfq_fixmp_11_5_addmul1_nc)
30489 /* x has 11.5 words, z has 13.
30490  * Put (z+x*c) in z. Carry bit is lost. */
30491 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
30492 /* Triggered by: 11_5_mul, 11_5_mgy_decode */
30493 static inline
mpfq_fixmp_11_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30494 void mpfq_fixmp_11_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30495 {
30496     mp_limb_t hi, lo, carry, buf;
30497     carry = 0;
30498     mpfq_umul_ppmm(hi,lo,c,x[0]);
30499     lo += carry;
30500     carry = (lo<carry) + hi;
30501     buf = z[0];
30502     lo += buf;
30503     carry += (lo<buf);
30504     z[0] = lo;
30505     mpfq_umul_ppmm(hi,lo,c,x[1]);
30506     lo += carry;
30507     carry = (lo<carry) + hi;
30508     buf = z[1];
30509     lo += buf;
30510     carry += (lo<buf);
30511     z[1] = lo;
30512     mpfq_umul_ppmm(hi,lo,c,x[2]);
30513     lo += carry;
30514     carry = (lo<carry) + hi;
30515     buf = z[2];
30516     lo += buf;
30517     carry += (lo<buf);
30518     z[2] = lo;
30519     mpfq_umul_ppmm(hi,lo,c,x[3]);
30520     lo += carry;
30521     carry = (lo<carry) + hi;
30522     buf = z[3];
30523     lo += buf;
30524     carry += (lo<buf);
30525     z[3] = lo;
30526     mpfq_umul_ppmm(hi,lo,c,x[4]);
30527     lo += carry;
30528     carry = (lo<carry) + hi;
30529     buf = z[4];
30530     lo += buf;
30531     carry += (lo<buf);
30532     z[4] = lo;
30533     mpfq_umul_ppmm(hi,lo,c,x[5]);
30534     lo += carry;
30535     carry = (lo<carry) + hi;
30536     buf = z[5];
30537     lo += buf;
30538     carry += (lo<buf);
30539     z[5] = lo;
30540     mpfq_umul_ppmm(hi,lo,c,x[6]);
30541     lo += carry;
30542     carry = (lo<carry) + hi;
30543     buf = z[6];
30544     lo += buf;
30545     carry += (lo<buf);
30546     z[6] = lo;
30547     mpfq_umul_ppmm(hi,lo,c,x[7]);
30548     lo += carry;
30549     carry = (lo<carry) + hi;
30550     buf = z[7];
30551     lo += buf;
30552     carry += (lo<buf);
30553     z[7] = lo;
30554     mpfq_umul_ppmm(hi,lo,c,x[8]);
30555     lo += carry;
30556     carry = (lo<carry) + hi;
30557     buf = z[8];
30558     lo += buf;
30559     carry += (lo<buf);
30560     z[8] = lo;
30561     mpfq_umul_ppmm(hi,lo,c,x[9]);
30562     lo += carry;
30563     carry = (lo<carry) + hi;
30564     buf = z[9];
30565     lo += buf;
30566     carry += (lo<buf);
30567     z[9] = lo;
30568     mpfq_umul_ppmm(hi,lo,c,x[10]);
30569     lo += carry;
30570     carry = (lo<carry) + hi;
30571     buf = z[10];
30572     lo += buf;
30573     carry += (lo<buf);
30574     z[10] = lo;
30575     mpfq_umul_ppmm(hi,lo,c,x[11]);
30576     lo += carry;
30577     carry = (lo<carry) + hi;
30578     buf = z[11];
30579     lo += buf;
30580     carry += (lo<buf);
30581     z[11] = lo;
30582     z[12] += carry;
30583 }
30584 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_addmul1_nc) */
30585 
30586 #if !defined(HAVE_native_mpfq_fixmp_11_5_addmul1_shortz)
30587 /* x has 11.5 words, z has 12.
30588  * Put (z+x*c) in z. Return carry word. */
30589 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
30590 /* Triggered by: 11_5_redc, 11_5_redc_ur */
30591 static inline
mpfq_fixmp_11_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30592 mp_limb_t mpfq_fixmp_11_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30593 {
30594     mp_limb_t hi, lo, carry, buf;
30595     carry = 0;
30596     mpfq_umul_ppmm(hi,lo,c,x[0]);
30597     lo += carry;
30598     carry = (lo<carry) + hi;
30599     buf = z[0];
30600     lo += buf;
30601     carry += (lo<buf);
30602     z[0] = lo;
30603     mpfq_umul_ppmm(hi,lo,c,x[1]);
30604     lo += carry;
30605     carry = (lo<carry) + hi;
30606     buf = z[1];
30607     lo += buf;
30608     carry += (lo<buf);
30609     z[1] = lo;
30610     mpfq_umul_ppmm(hi,lo,c,x[2]);
30611     lo += carry;
30612     carry = (lo<carry) + hi;
30613     buf = z[2];
30614     lo += buf;
30615     carry += (lo<buf);
30616     z[2] = lo;
30617     mpfq_umul_ppmm(hi,lo,c,x[3]);
30618     lo += carry;
30619     carry = (lo<carry) + hi;
30620     buf = z[3];
30621     lo += buf;
30622     carry += (lo<buf);
30623     z[3] = lo;
30624     mpfq_umul_ppmm(hi,lo,c,x[4]);
30625     lo += carry;
30626     carry = (lo<carry) + hi;
30627     buf = z[4];
30628     lo += buf;
30629     carry += (lo<buf);
30630     z[4] = lo;
30631     mpfq_umul_ppmm(hi,lo,c,x[5]);
30632     lo += carry;
30633     carry = (lo<carry) + hi;
30634     buf = z[5];
30635     lo += buf;
30636     carry += (lo<buf);
30637     z[5] = lo;
30638     mpfq_umul_ppmm(hi,lo,c,x[6]);
30639     lo += carry;
30640     carry = (lo<carry) + hi;
30641     buf = z[6];
30642     lo += buf;
30643     carry += (lo<buf);
30644     z[6] = lo;
30645     mpfq_umul_ppmm(hi,lo,c,x[7]);
30646     lo += carry;
30647     carry = (lo<carry) + hi;
30648     buf = z[7];
30649     lo += buf;
30650     carry += (lo<buf);
30651     z[7] = lo;
30652     mpfq_umul_ppmm(hi,lo,c,x[8]);
30653     lo += carry;
30654     carry = (lo<carry) + hi;
30655     buf = z[8];
30656     lo += buf;
30657     carry += (lo<buf);
30658     z[8] = lo;
30659     mpfq_umul_ppmm(hi,lo,c,x[9]);
30660     lo += carry;
30661     carry = (lo<carry) + hi;
30662     buf = z[9];
30663     lo += buf;
30664     carry += (lo<buf);
30665     z[9] = lo;
30666     mpfq_umul_ppmm(hi,lo,c,x[10]);
30667     lo += carry;
30668     carry = (lo<carry) + hi;
30669     buf = z[10];
30670     lo += buf;
30671     carry += (lo<buf);
30672     z[10] = lo;
30673     mpfq_umul_ppmm(hi,lo,c,x[11]);
30674     lo += carry;
30675     carry = (lo<carry) + hi;
30676     buf = z[11];
30677     lo += buf;
30678     carry += (lo<buf);
30679     z[11] = lo;
30680     return carry;
30681 }
30682 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_addmul1_shortz) */
30683 
30684 #if !defined(HAVE_native_mpfq_fixmp_11_5_addmul05_nc)
30685 /* x has 11.5 words, z has 12. c is 0.5 word.
30686  * Put (z+x*c) in z. Carry bit is lost. */
30687 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
30688 /* Triggered by: 11_5_mul, 11_5_mgy_decode */
30689 static inline
mpfq_fixmp_11_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30690 void mpfq_fixmp_11_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30691 {
30692     mp_limb_t hi, lo, carry, buf;
30693     carry = 0;
30694     mpfq_umul_ppmm(hi,lo,c,x[0]);
30695     lo += carry;
30696     carry = (lo<carry) + hi;
30697     buf = z[0];
30698     lo += buf;
30699     carry += (lo<buf);
30700     z[0] = lo;
30701     mpfq_umul_ppmm(hi,lo,c,x[1]);
30702     lo += carry;
30703     carry = (lo<carry) + hi;
30704     buf = z[1];
30705     lo += buf;
30706     carry += (lo<buf);
30707     z[1] = lo;
30708     mpfq_umul_ppmm(hi,lo,c,x[2]);
30709     lo += carry;
30710     carry = (lo<carry) + hi;
30711     buf = z[2];
30712     lo += buf;
30713     carry += (lo<buf);
30714     z[2] = lo;
30715     mpfq_umul_ppmm(hi,lo,c,x[3]);
30716     lo += carry;
30717     carry = (lo<carry) + hi;
30718     buf = z[3];
30719     lo += buf;
30720     carry += (lo<buf);
30721     z[3] = lo;
30722     mpfq_umul_ppmm(hi,lo,c,x[4]);
30723     lo += carry;
30724     carry = (lo<carry) + hi;
30725     buf = z[4];
30726     lo += buf;
30727     carry += (lo<buf);
30728     z[4] = lo;
30729     mpfq_umul_ppmm(hi,lo,c,x[5]);
30730     lo += carry;
30731     carry = (lo<carry) + hi;
30732     buf = z[5];
30733     lo += buf;
30734     carry += (lo<buf);
30735     z[5] = lo;
30736     mpfq_umul_ppmm(hi,lo,c,x[6]);
30737     lo += carry;
30738     carry = (lo<carry) + hi;
30739     buf = z[6];
30740     lo += buf;
30741     carry += (lo<buf);
30742     z[6] = lo;
30743     mpfq_umul_ppmm(hi,lo,c,x[7]);
30744     lo += carry;
30745     carry = (lo<carry) + hi;
30746     buf = z[7];
30747     lo += buf;
30748     carry += (lo<buf);
30749     z[7] = lo;
30750     mpfq_umul_ppmm(hi,lo,c,x[8]);
30751     lo += carry;
30752     carry = (lo<carry) + hi;
30753     buf = z[8];
30754     lo += buf;
30755     carry += (lo<buf);
30756     z[8] = lo;
30757     mpfq_umul_ppmm(hi,lo,c,x[9]);
30758     lo += carry;
30759     carry = (lo<carry) + hi;
30760     buf = z[9];
30761     lo += buf;
30762     carry += (lo<buf);
30763     z[9] = lo;
30764     mpfq_umul_ppmm(hi,lo,c,x[10]);
30765     lo += carry;
30766     carry = (lo<carry) + hi;
30767     buf = z[10];
30768     lo += buf;
30769     carry += (lo<buf);
30770     z[10] = lo;
30771     lo = c*x[11] + carry;
30772     assert(lo >= carry);
30773     z[11] += lo;
30774 }
30775 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_addmul05_nc) */
30776 
30777 #if !defined(HAVE_native_mpfq_fixmp_11_5_mul)
30778 /* x and y have 11.5 words, z has 23. Put x*y in z. */
30779 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
30780 /* Triggered by: 11_5_mgy_decode */
30781 static inline
mpfq_fixmp_11_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)30782 void mpfq_fixmp_11_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
30783 {
30784     assert(z != x && z != y);
30785     for (int i = 0; i < 23; z[i++] = 0) ;
30786     mpfq_fixmp_11_5_addmul1_nc (z + 0, x, y[0]);
30787     mpfq_fixmp_11_5_addmul1_nc (z + 1, x, y[1]);
30788     mpfq_fixmp_11_5_addmul1_nc (z + 2, x, y[2]);
30789     mpfq_fixmp_11_5_addmul1_nc (z + 3, x, y[3]);
30790     mpfq_fixmp_11_5_addmul1_nc (z + 4, x, y[4]);
30791     mpfq_fixmp_11_5_addmul1_nc (z + 5, x, y[5]);
30792     mpfq_fixmp_11_5_addmul1_nc (z + 6, x, y[6]);
30793     mpfq_fixmp_11_5_addmul1_nc (z + 7, x, y[7]);
30794     mpfq_fixmp_11_5_addmul1_nc (z + 8, x, y[8]);
30795     mpfq_fixmp_11_5_addmul1_nc (z + 9, x, y[9]);
30796     mpfq_fixmp_11_5_addmul1_nc (z + 10, x, y[10]);
30797     mpfq_fixmp_11_5_addmul05_nc (z + 11, x, y[11]);
30798 }
30799 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mul) */
30800 
30801 #if !defined(HAVE_native_mpfq_fixmp_11_5_sqr)
30802 /* x has 11.5 words, z has 23. Put x*y in z. */
30803 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
30804 static inline
mpfq_fixmp_11_5_sqr(mp_limb_t * z,const mp_limb_t * x)30805 void mpfq_fixmp_11_5_sqr(mp_limb_t * z, const mp_limb_t * x)
30806 {
30807     mp_limb_t buf[23] = {0,};
30808     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
30809     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
30810     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
30811     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
30812     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
30813     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
30814     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
30815     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
30816     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
30817     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
30818     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
30819     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
30820     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
30821     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
30822     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
30823     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
30824     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
30825     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
30826     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
30827     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
30828     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
30829     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
30830     z[2*11] = x[11] * x[11];
30831     mpn_lshift(buf, buf, 23, 1);
30832     mpn_add_n(z, z, buf, 23);
30833 }
30834 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_sqr) */
30835 
30836 #if !defined(HAVE_native_mpfq_fixmp_11_5_mul1)
30837 /* x has 11.5 words, z has 13. Put x*y in z. */
30838 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
30839 static inline
mpfq_fixmp_11_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30840 void mpfq_fixmp_11_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30841 {
30842     mp_limb_t hi, lo, carry;
30843     carry = 0;
30844     mpfq_umul_ppmm(hi,lo,c,x[0]);
30845     lo += carry;
30846     carry = (lo<carry) + hi;
30847     z[0] = lo;
30848     mpfq_umul_ppmm(hi,lo,c,x[1]);
30849     lo += carry;
30850     carry = (lo<carry) + hi;
30851     z[1] = lo;
30852     mpfq_umul_ppmm(hi,lo,c,x[2]);
30853     lo += carry;
30854     carry = (lo<carry) + hi;
30855     z[2] = lo;
30856     mpfq_umul_ppmm(hi,lo,c,x[3]);
30857     lo += carry;
30858     carry = (lo<carry) + hi;
30859     z[3] = lo;
30860     mpfq_umul_ppmm(hi,lo,c,x[4]);
30861     lo += carry;
30862     carry = (lo<carry) + hi;
30863     z[4] = lo;
30864     mpfq_umul_ppmm(hi,lo,c,x[5]);
30865     lo += carry;
30866     carry = (lo<carry) + hi;
30867     z[5] = lo;
30868     mpfq_umul_ppmm(hi,lo,c,x[6]);
30869     lo += carry;
30870     carry = (lo<carry) + hi;
30871     z[6] = lo;
30872     mpfq_umul_ppmm(hi,lo,c,x[7]);
30873     lo += carry;
30874     carry = (lo<carry) + hi;
30875     z[7] = lo;
30876     mpfq_umul_ppmm(hi,lo,c,x[8]);
30877     lo += carry;
30878     carry = (lo<carry) + hi;
30879     z[8] = lo;
30880     mpfq_umul_ppmm(hi,lo,c,x[9]);
30881     lo += carry;
30882     carry = (lo<carry) + hi;
30883     z[9] = lo;
30884     mpfq_umul_ppmm(hi,lo,c,x[10]);
30885     lo += carry;
30886     carry = (lo<carry) + hi;
30887     z[10] = lo;
30888     mpfq_umul_ppmm(hi,lo,c,x[11]);
30889     lo += carry;
30890     carry = (lo<carry) + hi;
30891     z[11] = lo;
30892     z[12] = carry;
30893 }
30894 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mul1) */
30895 
30896 #if !defined(HAVE_native_mpfq_fixmp_11_5_shortmul)
30897 /* x and y have 11.5 words, z has 12.
30898  * Put the low 12 words of x*y in z. */
30899 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
30900 static inline
mpfq_fixmp_11_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)30901 void mpfq_fixmp_11_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
30902 {
30903     mpfq_zero(z, 12);
30904     mpfq_fixmp_11_addmul1_nc (z+0, x, y[0]);
30905     z[12-1] += x[11]*y[0];
30906     mpfq_fixmp_10_addmul1_nc (z+1, x, y[1]);
30907     z[12-1] += x[10]*y[1];
30908     mpfq_fixmp_9_addmul1_nc (z+2, x, y[2]);
30909     z[12-1] += x[9]*y[2];
30910     mpfq_fixmp_8_addmul1_nc (z+3, x, y[3]);
30911     z[12-1] += x[8]*y[3];
30912     mpfq_fixmp_7_addmul1_nc (z+4, x, y[4]);
30913     z[12-1] += x[7]*y[4];
30914     mpfq_fixmp_6_addmul1_nc (z+5, x, y[5]);
30915     z[12-1] += x[6]*y[5];
30916     mpfq_fixmp_5_addmul1_nc (z+6, x, y[6]);
30917     z[12-1] += x[5]*y[6];
30918     mpfq_fixmp_4_addmul1_nc (z+7, x, y[7]);
30919     z[12-1] += x[4]*y[7];
30920     mpfq_fixmp_3_addmul1_nc (z+8, x, y[8]);
30921     z[12-1] += x[3]*y[8];
30922     mpfq_fixmp_2_addmul1_nc (z+9, x, y[9]);
30923     z[12-1] += x[2]*y[9];
30924     mpfq_fixmp_1_addmul1_nc (z+10, x, y[10]);
30925     z[12-1] += x[1]*y[10];
30926     z[12-1] += x[0]*y[12-1];
30927 }
30928 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_shortmul) */
30929 
30930 #if !defined(HAVE_native_mpfq_fixmp_11_5_addmul05)
30931 /* x has 11.5 words, z has 12. c is 0.5 word.
30932  * Put (z+x*c) in z. Return carry bit. */
30933 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
30934 static inline
mpfq_fixmp_11_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)30935 mp_limb_t mpfq_fixmp_11_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
30936 {
30937     mp_limb_t hi, lo, carry, buf;
30938     carry = 0;
30939     mpfq_umul_ppmm(hi,lo,c,x[0]);
30940     lo += carry;
30941     carry = (lo<carry) + hi;
30942     buf = z[0];
30943     lo += buf;
30944     carry += (lo<buf);
30945     z[0] = lo;
30946     mpfq_umul_ppmm(hi,lo,c,x[1]);
30947     lo += carry;
30948     carry = (lo<carry) + hi;
30949     buf = z[1];
30950     lo += buf;
30951     carry += (lo<buf);
30952     z[1] = lo;
30953     mpfq_umul_ppmm(hi,lo,c,x[2]);
30954     lo += carry;
30955     carry = (lo<carry) + hi;
30956     buf = z[2];
30957     lo += buf;
30958     carry += (lo<buf);
30959     z[2] = lo;
30960     mpfq_umul_ppmm(hi,lo,c,x[3]);
30961     lo += carry;
30962     carry = (lo<carry) + hi;
30963     buf = z[3];
30964     lo += buf;
30965     carry += (lo<buf);
30966     z[3] = lo;
30967     mpfq_umul_ppmm(hi,lo,c,x[4]);
30968     lo += carry;
30969     carry = (lo<carry) + hi;
30970     buf = z[4];
30971     lo += buf;
30972     carry += (lo<buf);
30973     z[4] = lo;
30974     mpfq_umul_ppmm(hi,lo,c,x[5]);
30975     lo += carry;
30976     carry = (lo<carry) + hi;
30977     buf = z[5];
30978     lo += buf;
30979     carry += (lo<buf);
30980     z[5] = lo;
30981     mpfq_umul_ppmm(hi,lo,c,x[6]);
30982     lo += carry;
30983     carry = (lo<carry) + hi;
30984     buf = z[6];
30985     lo += buf;
30986     carry += (lo<buf);
30987     z[6] = lo;
30988     mpfq_umul_ppmm(hi,lo,c,x[7]);
30989     lo += carry;
30990     carry = (lo<carry) + hi;
30991     buf = z[7];
30992     lo += buf;
30993     carry += (lo<buf);
30994     z[7] = lo;
30995     mpfq_umul_ppmm(hi,lo,c,x[8]);
30996     lo += carry;
30997     carry = (lo<carry) + hi;
30998     buf = z[8];
30999     lo += buf;
31000     carry += (lo<buf);
31001     z[8] = lo;
31002     mpfq_umul_ppmm(hi,lo,c,x[9]);
31003     lo += carry;
31004     carry = (lo<carry) + hi;
31005     buf = z[9];
31006     lo += buf;
31007     carry += (lo<buf);
31008     z[9] = lo;
31009     mpfq_umul_ppmm(hi,lo,c,x[10]);
31010     lo += carry;
31011     carry = (lo<carry) + hi;
31012     buf = z[10];
31013     lo += buf;
31014     carry += (lo<buf);
31015     z[10] = lo;
31016     lo = c*x[11] + carry;
31017     assert(lo >= carry);
31018     z[11] += lo;
31019     return z[11] < lo;
31020 }
31021 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_addmul05) */
31022 
31023 #if !defined(HAVE_native_mpfq_fixmp_11_5_mul05)
31024 /* x has 11.5 words, z has 12. c is 0.5 word.
31025  * Put (x*c) in z. No carry. */
31026 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
31027 static inline
mpfq_fixmp_11_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)31028 void mpfq_fixmp_11_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
31029 {
31030     mp_limb_t hi, lo, carry;
31031     carry = 0;
31032     mpfq_umul_ppmm(hi,lo,c,x[0]);
31033     lo += carry;
31034     carry = (lo<carry) + hi;
31035     z[0] = lo;
31036     mpfq_umul_ppmm(hi,lo,c,x[1]);
31037     lo += carry;
31038     carry = (lo<carry) + hi;
31039     z[1] = lo;
31040     mpfq_umul_ppmm(hi,lo,c,x[2]);
31041     lo += carry;
31042     carry = (lo<carry) + hi;
31043     z[2] = lo;
31044     mpfq_umul_ppmm(hi,lo,c,x[3]);
31045     lo += carry;
31046     carry = (lo<carry) + hi;
31047     z[3] = lo;
31048     mpfq_umul_ppmm(hi,lo,c,x[4]);
31049     lo += carry;
31050     carry = (lo<carry) + hi;
31051     z[4] = lo;
31052     mpfq_umul_ppmm(hi,lo,c,x[5]);
31053     lo += carry;
31054     carry = (lo<carry) + hi;
31055     z[5] = lo;
31056     mpfq_umul_ppmm(hi,lo,c,x[6]);
31057     lo += carry;
31058     carry = (lo<carry) + hi;
31059     z[6] = lo;
31060     mpfq_umul_ppmm(hi,lo,c,x[7]);
31061     lo += carry;
31062     carry = (lo<carry) + hi;
31063     z[7] = lo;
31064     mpfq_umul_ppmm(hi,lo,c,x[8]);
31065     lo += carry;
31066     carry = (lo<carry) + hi;
31067     z[8] = lo;
31068     mpfq_umul_ppmm(hi,lo,c,x[9]);
31069     lo += carry;
31070     carry = (lo<carry) + hi;
31071     z[9] = lo;
31072     mpfq_umul_ppmm(hi,lo,c,x[10]);
31073     lo += carry;
31074     carry = (lo<carry) + hi;
31075     z[10] = lo;
31076     lo = c*x[11] + carry;
31077     assert(lo >= carry);
31078     z[11] = lo;
31079 }
31080 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mul05) */
31081 
31082 #if !defined(HAVE_native_mpfq_fixmp_11_5_mod)
31083 /* x has 23 words. z and p have 11.5 words, and the high word of p is non-zero.
31084  * Put x mod p in z. */
31085 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
31086 /* Triggered by: 11_5_mgy_decode */
31087 static inline
mpfq_fixmp_11_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)31088 void mpfq_fixmp_11_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
31089 {
31090     mp_limb_t q[11+1], r[12];
31091     assert (p[12-1] != 0);
31092     mpn_tdiv_qr(q, r, 0, x, 23, p, 12);
31093     mpfq_copy(z, r, 12);
31094 }
31095 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mod) */
31096 
31097 #if !defined(HAVE_native_mpfq_fixmp_11_5_rshift)
31098 /* a has 11.5 words. Shift it in place by cnt bits to the right.
31099  * The shift count cnt must not exceed the word size.
31100  * Note that no carry is returned for the bits shifted out. */
31101 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
31102 /* Triggered by: 11_5_invmod */
31103 static inline
mpfq_fixmp_11_5_rshift(mp_limb_t * a,int cnt)31104 void mpfq_fixmp_11_5_rshift(mp_limb_t * a, int cnt)
31105 {
31106     if (!cnt) return;
31107     int i;
31108     int dnt = GMP_NUMB_BITS - cnt;
31109     for (i = 0; i < 12-1; ++i) {
31110         a[i] >>= cnt;
31111         a[i] |= (a[i+1] << dnt);
31112     }
31113     a[12-1] >>= cnt;
31114 }
31115 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_rshift) */
31116 
31117 #if !defined(HAVE_native_mpfq_fixmp_11_5_long_rshift)
31118 /* a has 11.5 words. Shift it in place by off words plus cnt bits to the left.
31119  * Note that no carry is returned for the bits shifted out. */
31120 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
31121 /* Triggered by: 11_5_invmod */
31122 static inline
mpfq_fixmp_11_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)31123 void mpfq_fixmp_11_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
31124 {
31125     if (cnt) {
31126         int dnt = GMP_NUMB_BITS - cnt;
31127         for (int i = 0; i < 12 - off - 1; ++i) {
31128             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
31129         }
31130         a[12-off-1] = a[12-1]>>cnt;
31131     } else {
31132         mpfq_copyi(a, a + off, 12 - off);
31133     }
31134     mpfq_zero(a + 12 - off, off);
31135 }
31136 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_long_rshift) */
31137 
31138 #if !defined(HAVE_native_mpfq_fixmp_11_5_long_lshift)
31139 /* a has 11.5 words. Shift it in place by off words plus cnt bits to the left.
31140  * Note that no carry is returned for the bits shifted out. */
31141 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
31142 /* Triggered by: 11_5_invmod */
31143 static inline
mpfq_fixmp_11_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)31144 void mpfq_fixmp_11_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
31145 {
31146     int i;
31147     if (cnt) {
31148         int dnt = GMP_NUMB_BITS - cnt;
31149         for (i = 12-1; i>off; --i) {
31150             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
31151         }
31152         a[off] = a[0]<<cnt;
31153     } else {
31154         mpfq_copyd(a + off, a, 12 - off);
31155     }
31156     mpfq_zero(a, off);
31157 }
31158 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_long_lshift) */
31159 
31160 #if !defined(HAVE_native_mpfq_fixmp_11_5_invmod)
31161 /* x, z, and p have 11.5 words. Put inverse of x mod p in z.
31162  * Return non-zero if an inverse could be found.
31163  * If no inverse could be found, return 0 and set z to zero.
31164  */
31165 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
31166 static inline
mpfq_fixmp_11_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)31167 int mpfq_fixmp_11_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
31168 {
31169       mp_limb_t u[12], v[12], a[12], b[12], fix[12];
31170       int i, t, lsh;
31171 
31172       mpfq_zero(u, 12);
31173       mpfq_zero(v, 12);
31174       mpfq_copy(a, x, 12);
31175       mpfq_copy(b, p, 12);
31176       u[0] = 1UL;
31177 
31178       if (mpfq_fixmp_11_5_cmp(a, v) == 0 || mpfq_fixmp_11_5_cmp(a, b) == 0) {
31179         mpfq_zero(res, 12);
31180         return 0;
31181       }
31182 
31183       mpfq_fixmp_11_5_add(fix, b, u);
31184       mpfq_fixmp_11_5_rshift(fix, 1);
31185 
31186       assert (mpfq_fixmp_11_5_cmp(a,b) < 0);
31187 
31188       t = 0;
31189 
31190       for(i = 0 ; !a[i] ; i++) ;
31191       assert (i < 12);
31192       lsh = mpfq_ctzl(a[i]);
31193       mpfq_fixmp_11_5_long_rshift(a, i, lsh);
31194       t += lsh + i*GMP_NUMB_BITS;
31195       mpfq_fixmp_11_5_long_lshift(v, i, lsh);
31196 
31197       do {
31198         do {
31199           mpfq_fixmp_11_5_sub(b, b, a);
31200           mpfq_fixmp_11_5_add(v, v, u);
31201           for(i = 0 ; !b[i] ; i++) ;
31202           assert (i < 12);
31203           lsh = mpfq_ctzl(b[i]);
31204           mpfq_fixmp_11_5_long_rshift(b, i, lsh);
31205           t += lsh + i*GMP_NUMB_BITS;
31206           mpfq_fixmp_11_5_long_lshift(u, i, lsh);
31207         } while (mpfq_fixmp_11_5_cmp(a,b) < 0);
31208         if (mpfq_fixmp_11_5_cmp(a, b) == 0)
31209           break;
31210         do {
31211           mpfq_fixmp_11_5_sub(a, a, b);
31212           mpfq_fixmp_11_5_add(u, u, v);
31213           for(i = 0 ; !a[i] ; i++) ;
31214           assert (i < 12);
31215           lsh = mpfq_ctzl(a[i]);
31216           mpfq_fixmp_11_5_long_rshift(a, i, lsh);
31217           t += lsh + i*GMP_NUMB_BITS;
31218           mpfq_fixmp_11_5_long_lshift(v, i, lsh);
31219         } while (mpfq_fixmp_11_5_cmp(b,a)<0);
31220       } while (mpfq_fixmp_11_5_cmp(a,b) != 0);
31221       {
31222         if (mpfq_fixmp_11_5_cmp_ui(a, 1) != 0) {
31223           mpfq_copy(res, a, 12);
31224           return 0;
31225         }
31226       }
31227       while (t>0) {
31228         mp_limb_t sig = u[0] & 1UL;
31229         mpfq_fixmp_11_5_rshift(u, 1);
31230         if (sig)
31231           mpfq_fixmp_11_5_add(u, u, fix);
31232         --t;
31233       }
31234       mpfq_copy(res, u, 12);
31235       return 1;
31236 }
31237 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_invmod) */
31238 
31239 #if !defined(HAVE_native_mpfq_fixmp_11_5_redc)
31240 /* x has 23 words, z and p have 11.5 words.
31241  * only one word is read from invp.
31242  * Assuming R=W^12 is the redc modulus, we expect that x verifies:
31243  *   x < R*p,
31244  * so that we have eventually z < p, z congruent to x/R mod p.
31245  * The contents of the area pointed by x are clobbered by this call.
31246  * Note also that x may alias z.
31247  */
31248 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
31249 static inline
mpfq_fixmp_11_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)31250 void mpfq_fixmp_11_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
31251 {
31252     mp_limb_t cy;
31253     for(int i = 0; i < 12; ++i) {
31254         mp_limb_t t = x[i]*mip[0];
31255         cy = mpfq_fixmp_11_5_addmul1_shortz(x+i, p, t);
31256         assert (x[i] == 0);
31257         x[i] = cy;
31258     }
31259     {
31260         mp_limb_t ret[12] = { x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19], x[20], x[21], x[22], 0 };
31261         cy = mpfq_fixmp_11_5_add(x, x, ret);
31262     }
31263     /* At this point, we have (x' denotes x + cy*W^n here)
31264     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
31265     * x'/R < p + p
31266     */
31267     if (cy || mpfq_fixmp_11_5_cmp(x, p) >= 0) {
31268         mpfq_fixmp_11_5_sub(z, x, p);
31269     } else {
31270         mpfq_copy(z, x, 12);
31271     }
31272 }
31273 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_redc) */
31274 
31275 #if !defined(HAVE_native_mpfq_fixmp_11_5_redc_ur)
31276 /* x has 24 words, z and p have 11.5 words.
31277  * only one word is read from invp.
31278  * Assuming R=W^12 is the redc modulus, we expect that x verifies:
31279  *  x < W*W^11.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
31280  * so that we have eventually z < p, z congruent to x/R mod p.
31281  * The contents of the area pointed by x are clobbered by this call.
31282  * Note also that x may alias z.
31283  */
31284 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
31285 static inline
mpfq_fixmp_11_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)31286 void mpfq_fixmp_11_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
31287 {
31288     mp_limb_t cy, q[1];
31289     for(int i = 0; i < 12; ++i) {
31290         mp_limb_t t = x[i]*mip[0];
31291         cy = mpfq_fixmp_11_5_addmul1_shortz(x+i, p, t);
31292         assert (x[i] == 0);
31293         x[i] = cy;
31294     }
31295     cy = mpfq_fixmp_11_5_add(x + 12, x, x + 12);
31296     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
31297     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
31298     * x'/R < (W^0.5+1)*p
31299     */
31300     if (cy) {
31301         /* x'/R-p < W^0.5*p, which fits in n words. */
31302         mpfq_fixmp_11_5_sub(x + 12, x + 12, p);
31303     }
31304     mpn_tdiv_qr(q, z, 0, x + 12, 12, p, 12);
31305 }
31306 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_redc_ur) */
31307 
31308 #if !defined(HAVE_native_mpfq_fixmp_11_5_mgy_encode)
31309 /* x, z, and p have 11.5 words.
31310  * Assuming R=W^12 is the redc modulus, we compute z=R*x mod p. */
31311 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
31312 static inline
mpfq_fixmp_11_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)31313 void mpfq_fixmp_11_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
31314 {
31315     mp_limb_t t[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11] };
31316     mp_limb_t qq[12+1];
31317     mpn_tdiv_qr(qq, z, 0, t, 24, p, 12);
31318 }
31319 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mgy_encode) */
31320 
31321 #if !defined(HAVE_native_mpfq_fixmp_11_5_mgy_decode)
31322 /* x, z, invR, and p have 11.5 words.
31323  * Assuming R=W^12 is the redc modulus, we compute z=x/R mod p. */
31324 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
31325 static inline
mpfq_fixmp_11_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)31326 void mpfq_fixmp_11_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
31327 {
31328     mp_limb_t t[24];
31329     mpfq_fixmp_11_5_mul(t, x, invR);
31330     mpfq_fixmp_11_5_mod(z, t, p);
31331 }
31332 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_mgy_decode) */
31333 
31334 #if !defined(HAVE_native_mpfq_fixmp_11_5_lshift)
31335 /* a has 11.5 words. Shift it in place by cnt bits to the left.
31336  * The shift count cnt must not exceed the word size.
31337  * Note that no carry is returned for the bits shifted out. */
31338 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
31339 static inline
mpfq_fixmp_11_5_lshift(mp_limb_t * a,int cnt)31340 void mpfq_fixmp_11_5_lshift(mp_limb_t * a, int cnt)
31341 {
31342     if (!cnt) return;
31343     int i;
31344     int dnt = GMP_NUMB_BITS - cnt;
31345     for (i = 12-1; i>0; --i) {
31346         a[i] <<= cnt;
31347         a[i] |= (a[i-1] >> dnt);
31348     }
31349     a[0] <<= cnt;
31350 }
31351 #endif /* !defined(HAVE_native_mpfq_fixmp_11_5_lshift) */
31352 
31353 #if !defined(HAVE_native_mpfq_fixmp_12_5_add)
31354 /* x, y, and z have 12.5 words. Result in z. Return carry bit */
31355 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
31356 /* Triggered by: 12_5_invmod, 12_5_redc, 12_5_redc_ur */
31357 static inline
mpfq_fixmp_12_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)31358 mp_limb_t mpfq_fixmp_12_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
31359 {
31360     mp_limb_t r, s, t, cy, cy1, cy2;
31361     cy = 0;
31362     r = x[0];
31363     s = r + y[0];
31364     cy1 = s < r;
31365     t = s + cy;
31366     cy2 = t < s;
31367     cy = cy1 | cy2;
31368     z[0] = t;
31369     r = x[1];
31370     s = r + y[1];
31371     cy1 = s < r;
31372     t = s + cy;
31373     cy2 = t < s;
31374     cy = cy1 | cy2;
31375     z[1] = t;
31376     r = x[2];
31377     s = r + y[2];
31378     cy1 = s < r;
31379     t = s + cy;
31380     cy2 = t < s;
31381     cy = cy1 | cy2;
31382     z[2] = t;
31383     r = x[3];
31384     s = r + y[3];
31385     cy1 = s < r;
31386     t = s + cy;
31387     cy2 = t < s;
31388     cy = cy1 | cy2;
31389     z[3] = t;
31390     r = x[4];
31391     s = r + y[4];
31392     cy1 = s < r;
31393     t = s + cy;
31394     cy2 = t < s;
31395     cy = cy1 | cy2;
31396     z[4] = t;
31397     r = x[5];
31398     s = r + y[5];
31399     cy1 = s < r;
31400     t = s + cy;
31401     cy2 = t < s;
31402     cy = cy1 | cy2;
31403     z[5] = t;
31404     r = x[6];
31405     s = r + y[6];
31406     cy1 = s < r;
31407     t = s + cy;
31408     cy2 = t < s;
31409     cy = cy1 | cy2;
31410     z[6] = t;
31411     r = x[7];
31412     s = r + y[7];
31413     cy1 = s < r;
31414     t = s + cy;
31415     cy2 = t < s;
31416     cy = cy1 | cy2;
31417     z[7] = t;
31418     r = x[8];
31419     s = r + y[8];
31420     cy1 = s < r;
31421     t = s + cy;
31422     cy2 = t < s;
31423     cy = cy1 | cy2;
31424     z[8] = t;
31425     r = x[9];
31426     s = r + y[9];
31427     cy1 = s < r;
31428     t = s + cy;
31429     cy2 = t < s;
31430     cy = cy1 | cy2;
31431     z[9] = t;
31432     r = x[10];
31433     s = r + y[10];
31434     cy1 = s < r;
31435     t = s + cy;
31436     cy2 = t < s;
31437     cy = cy1 | cy2;
31438     z[10] = t;
31439     r = x[11];
31440     s = r + y[11];
31441     cy1 = s < r;
31442     t = s + cy;
31443     cy2 = t < s;
31444     cy = cy1 | cy2;
31445     z[11] = t;
31446     r = x[12];
31447     s = r + y[12];
31448     cy1 = s < r;
31449     t = s + cy;
31450     cy2 = t < s;
31451     cy = cy1 | cy2;
31452     z[12] = t;
31453     return cy;
31454 }
31455 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_add) */
31456 
31457 #if !defined(HAVE_native_mpfq_fixmp_12_5_sub)
31458 /* x, y, and z have 12.5 words. Result in z. Return borrow bit */
31459 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
31460 /* Triggered by: 12_5_invmod, 12_5_redc, 12_5_redc_ur */
31461 static inline
mpfq_fixmp_12_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)31462 mp_limb_t mpfq_fixmp_12_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
31463 {
31464     mp_limb_t r, s, t, cy, cy1, cy2;
31465     cy = 0;
31466     r = x[0];
31467     s = r - y[0];
31468     cy1 = s > r;
31469     t = s - cy;
31470     cy2 = t > s;
31471     cy = cy1 | cy2;
31472     z[0] = t;
31473     r = x[1];
31474     s = r - y[1];
31475     cy1 = s > r;
31476     t = s - cy;
31477     cy2 = t > s;
31478     cy = cy1 | cy2;
31479     z[1] = t;
31480     r = x[2];
31481     s = r - y[2];
31482     cy1 = s > r;
31483     t = s - cy;
31484     cy2 = t > s;
31485     cy = cy1 | cy2;
31486     z[2] = t;
31487     r = x[3];
31488     s = r - y[3];
31489     cy1 = s > r;
31490     t = s - cy;
31491     cy2 = t > s;
31492     cy = cy1 | cy2;
31493     z[3] = t;
31494     r = x[4];
31495     s = r - y[4];
31496     cy1 = s > r;
31497     t = s - cy;
31498     cy2 = t > s;
31499     cy = cy1 | cy2;
31500     z[4] = t;
31501     r = x[5];
31502     s = r - y[5];
31503     cy1 = s > r;
31504     t = s - cy;
31505     cy2 = t > s;
31506     cy = cy1 | cy2;
31507     z[5] = t;
31508     r = x[6];
31509     s = r - y[6];
31510     cy1 = s > r;
31511     t = s - cy;
31512     cy2 = t > s;
31513     cy = cy1 | cy2;
31514     z[6] = t;
31515     r = x[7];
31516     s = r - y[7];
31517     cy1 = s > r;
31518     t = s - cy;
31519     cy2 = t > s;
31520     cy = cy1 | cy2;
31521     z[7] = t;
31522     r = x[8];
31523     s = r - y[8];
31524     cy1 = s > r;
31525     t = s - cy;
31526     cy2 = t > s;
31527     cy = cy1 | cy2;
31528     z[8] = t;
31529     r = x[9];
31530     s = r - y[9];
31531     cy1 = s > r;
31532     t = s - cy;
31533     cy2 = t > s;
31534     cy = cy1 | cy2;
31535     z[9] = t;
31536     r = x[10];
31537     s = r - y[10];
31538     cy1 = s > r;
31539     t = s - cy;
31540     cy2 = t > s;
31541     cy = cy1 | cy2;
31542     z[10] = t;
31543     r = x[11];
31544     s = r - y[11];
31545     cy1 = s > r;
31546     t = s - cy;
31547     cy2 = t > s;
31548     cy = cy1 | cy2;
31549     z[11] = t;
31550     r = x[12];
31551     s = r - y[12];
31552     cy1 = s > r;
31553     t = s - cy;
31554     cy2 = t > s;
31555     cy = cy1 | cy2;
31556     z[12] = t;
31557     return cy;
31558 }
31559 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_sub) */
31560 
31561 #if !defined(HAVE_native_mpfq_fixmp_12_5_add_nc)
31562 /* x, y, and z have 12.5 words. Result in z. Carry bit is lost. */
31563 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
31564 static inline
mpfq_fixmp_12_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)31565 void mpfq_fixmp_12_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
31566 {
31567     mp_limb_t r, s, t, cy, cy1, cy2;
31568     cy = 0;
31569     r = x[0];
31570     s = r + y[0];
31571     cy1 = s < r;
31572     t = s + cy;
31573     cy2 = t < s;
31574     cy = cy1 | cy2;
31575     z[0] = t;
31576     r = x[1];
31577     s = r + y[1];
31578     cy1 = s < r;
31579     t = s + cy;
31580     cy2 = t < s;
31581     cy = cy1 | cy2;
31582     z[1] = t;
31583     r = x[2];
31584     s = r + y[2];
31585     cy1 = s < r;
31586     t = s + cy;
31587     cy2 = t < s;
31588     cy = cy1 | cy2;
31589     z[2] = t;
31590     r = x[3];
31591     s = r + y[3];
31592     cy1 = s < r;
31593     t = s + cy;
31594     cy2 = t < s;
31595     cy = cy1 | cy2;
31596     z[3] = t;
31597     r = x[4];
31598     s = r + y[4];
31599     cy1 = s < r;
31600     t = s + cy;
31601     cy2 = t < s;
31602     cy = cy1 | cy2;
31603     z[4] = t;
31604     r = x[5];
31605     s = r + y[5];
31606     cy1 = s < r;
31607     t = s + cy;
31608     cy2 = t < s;
31609     cy = cy1 | cy2;
31610     z[5] = t;
31611     r = x[6];
31612     s = r + y[6];
31613     cy1 = s < r;
31614     t = s + cy;
31615     cy2 = t < s;
31616     cy = cy1 | cy2;
31617     z[6] = t;
31618     r = x[7];
31619     s = r + y[7];
31620     cy1 = s < r;
31621     t = s + cy;
31622     cy2 = t < s;
31623     cy = cy1 | cy2;
31624     z[7] = t;
31625     r = x[8];
31626     s = r + y[8];
31627     cy1 = s < r;
31628     t = s + cy;
31629     cy2 = t < s;
31630     cy = cy1 | cy2;
31631     z[8] = t;
31632     r = x[9];
31633     s = r + y[9];
31634     cy1 = s < r;
31635     t = s + cy;
31636     cy2 = t < s;
31637     cy = cy1 | cy2;
31638     z[9] = t;
31639     r = x[10];
31640     s = r + y[10];
31641     cy1 = s < r;
31642     t = s + cy;
31643     cy2 = t < s;
31644     cy = cy1 | cy2;
31645     z[10] = t;
31646     r = x[11];
31647     s = r + y[11];
31648     cy1 = s < r;
31649     t = s + cy;
31650     cy2 = t < s;
31651     cy = cy1 | cy2;
31652     z[11] = t;
31653     r = x[12];
31654     s = r + y[12];
31655     cy1 = s < r;
31656     t = s + cy;
31657     cy2 = t < s;
31658     cy = cy1 | cy2;
31659     z[12] = t;
31660 }
31661 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_add_nc) */
31662 
31663 #if !defined(HAVE_native_mpfq_fixmp_12_5_sub_nc)
31664 /* x, y, and z have 12.5 words. Result in z. Borrow bit is lost. */
31665 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
31666 static inline
mpfq_fixmp_12_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)31667 void mpfq_fixmp_12_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
31668 {
31669     mp_limb_t r, s, t, cy, cy1, cy2;
31670     cy = 0;
31671     r = x[0];
31672     s = r - y[0];
31673     cy1 = s > r;
31674     t = s - cy;
31675     cy2 = t > s;
31676     cy = cy1 | cy2;
31677     z[0] = t;
31678     r = x[1];
31679     s = r - y[1];
31680     cy1 = s > r;
31681     t = s - cy;
31682     cy2 = t > s;
31683     cy = cy1 | cy2;
31684     z[1] = t;
31685     r = x[2];
31686     s = r - y[2];
31687     cy1 = s > r;
31688     t = s - cy;
31689     cy2 = t > s;
31690     cy = cy1 | cy2;
31691     z[2] = t;
31692     r = x[3];
31693     s = r - y[3];
31694     cy1 = s > r;
31695     t = s - cy;
31696     cy2 = t > s;
31697     cy = cy1 | cy2;
31698     z[3] = t;
31699     r = x[4];
31700     s = r - y[4];
31701     cy1 = s > r;
31702     t = s - cy;
31703     cy2 = t > s;
31704     cy = cy1 | cy2;
31705     z[4] = t;
31706     r = x[5];
31707     s = r - y[5];
31708     cy1 = s > r;
31709     t = s - cy;
31710     cy2 = t > s;
31711     cy = cy1 | cy2;
31712     z[5] = t;
31713     r = x[6];
31714     s = r - y[6];
31715     cy1 = s > r;
31716     t = s - cy;
31717     cy2 = t > s;
31718     cy = cy1 | cy2;
31719     z[6] = t;
31720     r = x[7];
31721     s = r - y[7];
31722     cy1 = s > r;
31723     t = s - cy;
31724     cy2 = t > s;
31725     cy = cy1 | cy2;
31726     z[7] = t;
31727     r = x[8];
31728     s = r - y[8];
31729     cy1 = s > r;
31730     t = s - cy;
31731     cy2 = t > s;
31732     cy = cy1 | cy2;
31733     z[8] = t;
31734     r = x[9];
31735     s = r - y[9];
31736     cy1 = s > r;
31737     t = s - cy;
31738     cy2 = t > s;
31739     cy = cy1 | cy2;
31740     z[9] = t;
31741     r = x[10];
31742     s = r - y[10];
31743     cy1 = s > r;
31744     t = s - cy;
31745     cy2 = t > s;
31746     cy = cy1 | cy2;
31747     z[10] = t;
31748     r = x[11];
31749     s = r - y[11];
31750     cy1 = s > r;
31751     t = s - cy;
31752     cy2 = t > s;
31753     cy = cy1 | cy2;
31754     z[11] = t;
31755     r = x[12];
31756     s = r - y[12];
31757     cy1 = s > r;
31758     t = s - cy;
31759     cy2 = t > s;
31760     cy = cy1 | cy2;
31761     z[12] = t;
31762 }
31763 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_sub_nc) */
31764 
31765 #if !defined(HAVE_native_mpfq_fixmp_12_5_add_ui)
31766 /* x, y, and z have 12.5 words. Result in z. Return carry bit */
31767 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
31768 static inline
mpfq_fixmp_12_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)31769 mp_limb_t mpfq_fixmp_12_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
31770 {
31771     mp_limb_t r, s, t, cy, cy1, cy2;
31772     cy = 0;
31773     r = x[0];
31774     s = r + y;
31775     cy1 = s < r;
31776     t = s + cy;
31777     cy2 = t < s;
31778     cy = cy1 | cy2;
31779     z[0] = t;
31780     s = x[1];
31781     t = s + cy;
31782     cy = t < s;
31783     z[1] = t;
31784     s = x[2];
31785     t = s + cy;
31786     cy = t < s;
31787     z[2] = t;
31788     s = x[3];
31789     t = s + cy;
31790     cy = t < s;
31791     z[3] = t;
31792     s = x[4];
31793     t = s + cy;
31794     cy = t < s;
31795     z[4] = t;
31796     s = x[5];
31797     t = s + cy;
31798     cy = t < s;
31799     z[5] = t;
31800     s = x[6];
31801     t = s + cy;
31802     cy = t < s;
31803     z[6] = t;
31804     s = x[7];
31805     t = s + cy;
31806     cy = t < s;
31807     z[7] = t;
31808     s = x[8];
31809     t = s + cy;
31810     cy = t < s;
31811     z[8] = t;
31812     s = x[9];
31813     t = s + cy;
31814     cy = t < s;
31815     z[9] = t;
31816     s = x[10];
31817     t = s + cy;
31818     cy = t < s;
31819     z[10] = t;
31820     s = x[11];
31821     t = s + cy;
31822     cy = t < s;
31823     z[11] = t;
31824     s = x[12];
31825     t = s + cy;
31826     cy = t < s;
31827     z[12] = t;
31828     return cy;
31829 }
31830 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_add_ui) */
31831 
31832 #if !defined(HAVE_native_mpfq_fixmp_12_5_sub_ui)
31833 /* x, y, and z have 12.5 words. Result in z. Return borrow bit */
31834 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
31835 static inline
mpfq_fixmp_12_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)31836 mp_limb_t mpfq_fixmp_12_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
31837 {
31838     mp_limb_t r, s, t, cy, cy1, cy2;
31839     cy = 0;
31840     r = x[0];
31841     s = r - y;
31842     cy1 = s > r;
31843     t = s - cy;
31844     cy2 = t > s;
31845     cy = cy1 | cy2;
31846     z[0] = t;
31847     s = x[1];
31848     t = s - cy;
31849     cy = t > s;
31850     z[1] = t;
31851     s = x[2];
31852     t = s - cy;
31853     cy = t > s;
31854     z[2] = t;
31855     s = x[3];
31856     t = s - cy;
31857     cy = t > s;
31858     z[3] = t;
31859     s = x[4];
31860     t = s - cy;
31861     cy = t > s;
31862     z[4] = t;
31863     s = x[5];
31864     t = s - cy;
31865     cy = t > s;
31866     z[5] = t;
31867     s = x[6];
31868     t = s - cy;
31869     cy = t > s;
31870     z[6] = t;
31871     s = x[7];
31872     t = s - cy;
31873     cy = t > s;
31874     z[7] = t;
31875     s = x[8];
31876     t = s - cy;
31877     cy = t > s;
31878     z[8] = t;
31879     s = x[9];
31880     t = s - cy;
31881     cy = t > s;
31882     z[9] = t;
31883     s = x[10];
31884     t = s - cy;
31885     cy = t > s;
31886     z[10] = t;
31887     s = x[11];
31888     t = s - cy;
31889     cy = t > s;
31890     z[11] = t;
31891     s = x[12];
31892     t = s - cy;
31893     cy = t > s;
31894     z[12] = t;
31895     return cy;
31896 }
31897 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_sub_ui) */
31898 
31899 #if !defined(HAVE_native_mpfq_fixmp_12_5_add_ui_nc)
31900 /* x, y, and z have 12.5 words. Result in z. Carry bit is lost. */
31901 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
31902 static inline
mpfq_fixmp_12_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)31903 void mpfq_fixmp_12_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
31904 {
31905     mp_limb_t r, s, t, cy, cy1, cy2;
31906     cy = 0;
31907     r = x[0];
31908     s = r + y;
31909     cy1 = s < r;
31910     t = s + cy;
31911     cy2 = t < s;
31912     cy = cy1 | cy2;
31913     z[0] = t;
31914     s = x[1];
31915     t = s + cy;
31916     cy = t < s;
31917     z[1] = t;
31918     s = x[2];
31919     t = s + cy;
31920     cy = t < s;
31921     z[2] = t;
31922     s = x[3];
31923     t = s + cy;
31924     cy = t < s;
31925     z[3] = t;
31926     s = x[4];
31927     t = s + cy;
31928     cy = t < s;
31929     z[4] = t;
31930     s = x[5];
31931     t = s + cy;
31932     cy = t < s;
31933     z[5] = t;
31934     s = x[6];
31935     t = s + cy;
31936     cy = t < s;
31937     z[6] = t;
31938     s = x[7];
31939     t = s + cy;
31940     cy = t < s;
31941     z[7] = t;
31942     s = x[8];
31943     t = s + cy;
31944     cy = t < s;
31945     z[8] = t;
31946     s = x[9];
31947     t = s + cy;
31948     cy = t < s;
31949     z[9] = t;
31950     s = x[10];
31951     t = s + cy;
31952     cy = t < s;
31953     z[10] = t;
31954     s = x[11];
31955     t = s + cy;
31956     cy = t < s;
31957     z[11] = t;
31958     s = x[12];
31959     t = s + cy;
31960     cy = t < s;
31961     z[12] = t;
31962 }
31963 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_add_ui_nc) */
31964 
31965 #if !defined(HAVE_native_mpfq_fixmp_12_5_sub_ui_nc)
31966 /* x, y, and z have 12.5 words. Result in z. Borrow bit is lost. */
31967 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
31968 static inline
mpfq_fixmp_12_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)31969 void mpfq_fixmp_12_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
31970 {
31971     mp_limb_t r, s, t, cy, cy1, cy2;
31972     cy = 0;
31973     r = x[0];
31974     s = r - y;
31975     cy1 = s > r;
31976     t = s - cy;
31977     cy2 = t > s;
31978     cy = cy1 | cy2;
31979     z[0] = t;
31980     s = x[1];
31981     t = s - cy;
31982     cy = t > s;
31983     z[1] = t;
31984     s = x[2];
31985     t = s - cy;
31986     cy = t > s;
31987     z[2] = t;
31988     s = x[3];
31989     t = s - cy;
31990     cy = t > s;
31991     z[3] = t;
31992     s = x[4];
31993     t = s - cy;
31994     cy = t > s;
31995     z[4] = t;
31996     s = x[5];
31997     t = s - cy;
31998     cy = t > s;
31999     z[5] = t;
32000     s = x[6];
32001     t = s - cy;
32002     cy = t > s;
32003     z[6] = t;
32004     s = x[7];
32005     t = s - cy;
32006     cy = t > s;
32007     z[7] = t;
32008     s = x[8];
32009     t = s - cy;
32010     cy = t > s;
32011     z[8] = t;
32012     s = x[9];
32013     t = s - cy;
32014     cy = t > s;
32015     z[9] = t;
32016     s = x[10];
32017     t = s - cy;
32018     cy = t > s;
32019     z[10] = t;
32020     s = x[11];
32021     t = s - cy;
32022     cy = t > s;
32023     z[11] = t;
32024     s = x[12];
32025     t = s - cy;
32026     cy = t > s;
32027     z[12] = t;
32028 }
32029 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_sub_ui_nc) */
32030 
32031 #if !defined(HAVE_native_mpfq_fixmp_12_5_cmp)
32032 /* x and y have 12.5 words. Return sign of difference x-y. */
32033 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
32034 /* Triggered by: 12_5_invmod, 12_5_redc, 12_5_redc_ur */
32035 static inline
mpfq_fixmp_12_5_cmp(const mp_limb_t * x,const mp_limb_t * y)32036 int mpfq_fixmp_12_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
32037 {
32038     for (int i = 13-1; i >= 0; --i) {
32039         if (x[i] > y[i]) return 1;
32040         if (x[i] < y[i]) return -1;
32041     }
32042     return 0;
32043 }
32044 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_cmp) */
32045 
32046 #if !defined(HAVE_native_mpfq_fixmp_12_5_cmp_ui)
32047 /* x has 12.5 words. Return sign of difference x-y. */
32048 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
32049 /* Triggered by: 12_5_invmod */
32050 static inline
mpfq_fixmp_12_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)32051 int mpfq_fixmp_12_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
32052 {
32053     for (int i = 13-1; i > 0; --i) {
32054         if (x[i]) return 1;
32055     }
32056     if (x[0]>y) return 1;
32057     if (x[0]<y) return -1;
32058     return 0;
32059 }
32060 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_cmp_ui) */
32061 
32062 #if !defined(HAVE_native_mpfq_fixmp_12_5_addmul1)
32063 /* x has 12.5 words, z has 14.
32064  * Put (z+x*c) in z. Return carry bit. */
32065 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
32066 static inline
mpfq_fixmp_12_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32067 mp_limb_t mpfq_fixmp_12_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32068 {
32069     mp_limb_t hi, lo, carry, buf;
32070     carry = 0;
32071     mpfq_umul_ppmm(hi,lo,c,x[0]);
32072     lo += carry;
32073     carry = (lo<carry) + hi;
32074     buf = z[0];
32075     lo += buf;
32076     carry += (lo<buf);
32077     z[0] = lo;
32078     mpfq_umul_ppmm(hi,lo,c,x[1]);
32079     lo += carry;
32080     carry = (lo<carry) + hi;
32081     buf = z[1];
32082     lo += buf;
32083     carry += (lo<buf);
32084     z[1] = lo;
32085     mpfq_umul_ppmm(hi,lo,c,x[2]);
32086     lo += carry;
32087     carry = (lo<carry) + hi;
32088     buf = z[2];
32089     lo += buf;
32090     carry += (lo<buf);
32091     z[2] = lo;
32092     mpfq_umul_ppmm(hi,lo,c,x[3]);
32093     lo += carry;
32094     carry = (lo<carry) + hi;
32095     buf = z[3];
32096     lo += buf;
32097     carry += (lo<buf);
32098     z[3] = lo;
32099     mpfq_umul_ppmm(hi,lo,c,x[4]);
32100     lo += carry;
32101     carry = (lo<carry) + hi;
32102     buf = z[4];
32103     lo += buf;
32104     carry += (lo<buf);
32105     z[4] = lo;
32106     mpfq_umul_ppmm(hi,lo,c,x[5]);
32107     lo += carry;
32108     carry = (lo<carry) + hi;
32109     buf = z[5];
32110     lo += buf;
32111     carry += (lo<buf);
32112     z[5] = lo;
32113     mpfq_umul_ppmm(hi,lo,c,x[6]);
32114     lo += carry;
32115     carry = (lo<carry) + hi;
32116     buf = z[6];
32117     lo += buf;
32118     carry += (lo<buf);
32119     z[6] = lo;
32120     mpfq_umul_ppmm(hi,lo,c,x[7]);
32121     lo += carry;
32122     carry = (lo<carry) + hi;
32123     buf = z[7];
32124     lo += buf;
32125     carry += (lo<buf);
32126     z[7] = lo;
32127     mpfq_umul_ppmm(hi,lo,c,x[8]);
32128     lo += carry;
32129     carry = (lo<carry) + hi;
32130     buf = z[8];
32131     lo += buf;
32132     carry += (lo<buf);
32133     z[8] = lo;
32134     mpfq_umul_ppmm(hi,lo,c,x[9]);
32135     lo += carry;
32136     carry = (lo<carry) + hi;
32137     buf = z[9];
32138     lo += buf;
32139     carry += (lo<buf);
32140     z[9] = lo;
32141     mpfq_umul_ppmm(hi,lo,c,x[10]);
32142     lo += carry;
32143     carry = (lo<carry) + hi;
32144     buf = z[10];
32145     lo += buf;
32146     carry += (lo<buf);
32147     z[10] = lo;
32148     mpfq_umul_ppmm(hi,lo,c,x[11]);
32149     lo += carry;
32150     carry = (lo<carry) + hi;
32151     buf = z[11];
32152     lo += buf;
32153     carry += (lo<buf);
32154     z[11] = lo;
32155     mpfq_umul_ppmm(hi,lo,c,x[12]);
32156     lo += carry;
32157     carry = (lo<carry) + hi;
32158     buf = z[12];
32159     lo += buf;
32160     carry += (lo<buf);
32161     z[12] = lo;
32162     z[13] += carry;
32163     return (z[13]<carry);
32164 }
32165 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_addmul1) */
32166 
32167 #if !defined(HAVE_native_mpfq_fixmp_12_5_addmul1_nc)
32168 /* x has 12.5 words, z has 14.
32169  * Put (z+x*c) in z. Carry bit is lost. */
32170 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
32171 /* Triggered by: 12_5_mul, 12_5_mgy_decode */
32172 static inline
mpfq_fixmp_12_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32173 void mpfq_fixmp_12_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32174 {
32175     mp_limb_t hi, lo, carry, buf;
32176     carry = 0;
32177     mpfq_umul_ppmm(hi,lo,c,x[0]);
32178     lo += carry;
32179     carry = (lo<carry) + hi;
32180     buf = z[0];
32181     lo += buf;
32182     carry += (lo<buf);
32183     z[0] = lo;
32184     mpfq_umul_ppmm(hi,lo,c,x[1]);
32185     lo += carry;
32186     carry = (lo<carry) + hi;
32187     buf = z[1];
32188     lo += buf;
32189     carry += (lo<buf);
32190     z[1] = lo;
32191     mpfq_umul_ppmm(hi,lo,c,x[2]);
32192     lo += carry;
32193     carry = (lo<carry) + hi;
32194     buf = z[2];
32195     lo += buf;
32196     carry += (lo<buf);
32197     z[2] = lo;
32198     mpfq_umul_ppmm(hi,lo,c,x[3]);
32199     lo += carry;
32200     carry = (lo<carry) + hi;
32201     buf = z[3];
32202     lo += buf;
32203     carry += (lo<buf);
32204     z[3] = lo;
32205     mpfq_umul_ppmm(hi,lo,c,x[4]);
32206     lo += carry;
32207     carry = (lo<carry) + hi;
32208     buf = z[4];
32209     lo += buf;
32210     carry += (lo<buf);
32211     z[4] = lo;
32212     mpfq_umul_ppmm(hi,lo,c,x[5]);
32213     lo += carry;
32214     carry = (lo<carry) + hi;
32215     buf = z[5];
32216     lo += buf;
32217     carry += (lo<buf);
32218     z[5] = lo;
32219     mpfq_umul_ppmm(hi,lo,c,x[6]);
32220     lo += carry;
32221     carry = (lo<carry) + hi;
32222     buf = z[6];
32223     lo += buf;
32224     carry += (lo<buf);
32225     z[6] = lo;
32226     mpfq_umul_ppmm(hi,lo,c,x[7]);
32227     lo += carry;
32228     carry = (lo<carry) + hi;
32229     buf = z[7];
32230     lo += buf;
32231     carry += (lo<buf);
32232     z[7] = lo;
32233     mpfq_umul_ppmm(hi,lo,c,x[8]);
32234     lo += carry;
32235     carry = (lo<carry) + hi;
32236     buf = z[8];
32237     lo += buf;
32238     carry += (lo<buf);
32239     z[8] = lo;
32240     mpfq_umul_ppmm(hi,lo,c,x[9]);
32241     lo += carry;
32242     carry = (lo<carry) + hi;
32243     buf = z[9];
32244     lo += buf;
32245     carry += (lo<buf);
32246     z[9] = lo;
32247     mpfq_umul_ppmm(hi,lo,c,x[10]);
32248     lo += carry;
32249     carry = (lo<carry) + hi;
32250     buf = z[10];
32251     lo += buf;
32252     carry += (lo<buf);
32253     z[10] = lo;
32254     mpfq_umul_ppmm(hi,lo,c,x[11]);
32255     lo += carry;
32256     carry = (lo<carry) + hi;
32257     buf = z[11];
32258     lo += buf;
32259     carry += (lo<buf);
32260     z[11] = lo;
32261     mpfq_umul_ppmm(hi,lo,c,x[12]);
32262     lo += carry;
32263     carry = (lo<carry) + hi;
32264     buf = z[12];
32265     lo += buf;
32266     carry += (lo<buf);
32267     z[12] = lo;
32268     z[13] += carry;
32269 }
32270 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_addmul1_nc) */
32271 
32272 #if !defined(HAVE_native_mpfq_fixmp_12_5_addmul1_shortz)
32273 /* x has 12.5 words, z has 13.
32274  * Put (z+x*c) in z. Return carry word. */
32275 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
32276 /* Triggered by: 12_5_redc, 12_5_redc_ur */
32277 static inline
mpfq_fixmp_12_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32278 mp_limb_t mpfq_fixmp_12_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32279 {
32280     mp_limb_t hi, lo, carry, buf;
32281     carry = 0;
32282     mpfq_umul_ppmm(hi,lo,c,x[0]);
32283     lo += carry;
32284     carry = (lo<carry) + hi;
32285     buf = z[0];
32286     lo += buf;
32287     carry += (lo<buf);
32288     z[0] = lo;
32289     mpfq_umul_ppmm(hi,lo,c,x[1]);
32290     lo += carry;
32291     carry = (lo<carry) + hi;
32292     buf = z[1];
32293     lo += buf;
32294     carry += (lo<buf);
32295     z[1] = lo;
32296     mpfq_umul_ppmm(hi,lo,c,x[2]);
32297     lo += carry;
32298     carry = (lo<carry) + hi;
32299     buf = z[2];
32300     lo += buf;
32301     carry += (lo<buf);
32302     z[2] = lo;
32303     mpfq_umul_ppmm(hi,lo,c,x[3]);
32304     lo += carry;
32305     carry = (lo<carry) + hi;
32306     buf = z[3];
32307     lo += buf;
32308     carry += (lo<buf);
32309     z[3] = lo;
32310     mpfq_umul_ppmm(hi,lo,c,x[4]);
32311     lo += carry;
32312     carry = (lo<carry) + hi;
32313     buf = z[4];
32314     lo += buf;
32315     carry += (lo<buf);
32316     z[4] = lo;
32317     mpfq_umul_ppmm(hi,lo,c,x[5]);
32318     lo += carry;
32319     carry = (lo<carry) + hi;
32320     buf = z[5];
32321     lo += buf;
32322     carry += (lo<buf);
32323     z[5] = lo;
32324     mpfq_umul_ppmm(hi,lo,c,x[6]);
32325     lo += carry;
32326     carry = (lo<carry) + hi;
32327     buf = z[6];
32328     lo += buf;
32329     carry += (lo<buf);
32330     z[6] = lo;
32331     mpfq_umul_ppmm(hi,lo,c,x[7]);
32332     lo += carry;
32333     carry = (lo<carry) + hi;
32334     buf = z[7];
32335     lo += buf;
32336     carry += (lo<buf);
32337     z[7] = lo;
32338     mpfq_umul_ppmm(hi,lo,c,x[8]);
32339     lo += carry;
32340     carry = (lo<carry) + hi;
32341     buf = z[8];
32342     lo += buf;
32343     carry += (lo<buf);
32344     z[8] = lo;
32345     mpfq_umul_ppmm(hi,lo,c,x[9]);
32346     lo += carry;
32347     carry = (lo<carry) + hi;
32348     buf = z[9];
32349     lo += buf;
32350     carry += (lo<buf);
32351     z[9] = lo;
32352     mpfq_umul_ppmm(hi,lo,c,x[10]);
32353     lo += carry;
32354     carry = (lo<carry) + hi;
32355     buf = z[10];
32356     lo += buf;
32357     carry += (lo<buf);
32358     z[10] = lo;
32359     mpfq_umul_ppmm(hi,lo,c,x[11]);
32360     lo += carry;
32361     carry = (lo<carry) + hi;
32362     buf = z[11];
32363     lo += buf;
32364     carry += (lo<buf);
32365     z[11] = lo;
32366     mpfq_umul_ppmm(hi,lo,c,x[12]);
32367     lo += carry;
32368     carry = (lo<carry) + hi;
32369     buf = z[12];
32370     lo += buf;
32371     carry += (lo<buf);
32372     z[12] = lo;
32373     return carry;
32374 }
32375 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_addmul1_shortz) */
32376 
32377 #if !defined(HAVE_native_mpfq_fixmp_12_5_addmul05_nc)
32378 /* x has 12.5 words, z has 13. c is 0.5 word.
32379  * Put (z+x*c) in z. Carry bit is lost. */
32380 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
32381 /* Triggered by: 12_5_mul, 12_5_mgy_decode */
32382 static inline
mpfq_fixmp_12_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32383 void mpfq_fixmp_12_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32384 {
32385     mp_limb_t hi, lo, carry, buf;
32386     carry = 0;
32387     mpfq_umul_ppmm(hi,lo,c,x[0]);
32388     lo += carry;
32389     carry = (lo<carry) + hi;
32390     buf = z[0];
32391     lo += buf;
32392     carry += (lo<buf);
32393     z[0] = lo;
32394     mpfq_umul_ppmm(hi,lo,c,x[1]);
32395     lo += carry;
32396     carry = (lo<carry) + hi;
32397     buf = z[1];
32398     lo += buf;
32399     carry += (lo<buf);
32400     z[1] = lo;
32401     mpfq_umul_ppmm(hi,lo,c,x[2]);
32402     lo += carry;
32403     carry = (lo<carry) + hi;
32404     buf = z[2];
32405     lo += buf;
32406     carry += (lo<buf);
32407     z[2] = lo;
32408     mpfq_umul_ppmm(hi,lo,c,x[3]);
32409     lo += carry;
32410     carry = (lo<carry) + hi;
32411     buf = z[3];
32412     lo += buf;
32413     carry += (lo<buf);
32414     z[3] = lo;
32415     mpfq_umul_ppmm(hi,lo,c,x[4]);
32416     lo += carry;
32417     carry = (lo<carry) + hi;
32418     buf = z[4];
32419     lo += buf;
32420     carry += (lo<buf);
32421     z[4] = lo;
32422     mpfq_umul_ppmm(hi,lo,c,x[5]);
32423     lo += carry;
32424     carry = (lo<carry) + hi;
32425     buf = z[5];
32426     lo += buf;
32427     carry += (lo<buf);
32428     z[5] = lo;
32429     mpfq_umul_ppmm(hi,lo,c,x[6]);
32430     lo += carry;
32431     carry = (lo<carry) + hi;
32432     buf = z[6];
32433     lo += buf;
32434     carry += (lo<buf);
32435     z[6] = lo;
32436     mpfq_umul_ppmm(hi,lo,c,x[7]);
32437     lo += carry;
32438     carry = (lo<carry) + hi;
32439     buf = z[7];
32440     lo += buf;
32441     carry += (lo<buf);
32442     z[7] = lo;
32443     mpfq_umul_ppmm(hi,lo,c,x[8]);
32444     lo += carry;
32445     carry = (lo<carry) + hi;
32446     buf = z[8];
32447     lo += buf;
32448     carry += (lo<buf);
32449     z[8] = lo;
32450     mpfq_umul_ppmm(hi,lo,c,x[9]);
32451     lo += carry;
32452     carry = (lo<carry) + hi;
32453     buf = z[9];
32454     lo += buf;
32455     carry += (lo<buf);
32456     z[9] = lo;
32457     mpfq_umul_ppmm(hi,lo,c,x[10]);
32458     lo += carry;
32459     carry = (lo<carry) + hi;
32460     buf = z[10];
32461     lo += buf;
32462     carry += (lo<buf);
32463     z[10] = lo;
32464     mpfq_umul_ppmm(hi,lo,c,x[11]);
32465     lo += carry;
32466     carry = (lo<carry) + hi;
32467     buf = z[11];
32468     lo += buf;
32469     carry += (lo<buf);
32470     z[11] = lo;
32471     lo = c*x[12] + carry;
32472     assert(lo >= carry);
32473     z[12] += lo;
32474 }
32475 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_addmul05_nc) */
32476 
32477 #if !defined(HAVE_native_mpfq_fixmp_12_5_mul)
32478 /* x and y have 12.5 words, z has 25. Put x*y in z. */
32479 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
32480 /* Triggered by: 12_5_mgy_decode */
32481 static inline
mpfq_fixmp_12_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)32482 void mpfq_fixmp_12_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
32483 {
32484     assert(z != x && z != y);
32485     for (int i = 0; i < 25; z[i++] = 0) ;
32486     mpfq_fixmp_12_5_addmul1_nc (z + 0, x, y[0]);
32487     mpfq_fixmp_12_5_addmul1_nc (z + 1, x, y[1]);
32488     mpfq_fixmp_12_5_addmul1_nc (z + 2, x, y[2]);
32489     mpfq_fixmp_12_5_addmul1_nc (z + 3, x, y[3]);
32490     mpfq_fixmp_12_5_addmul1_nc (z + 4, x, y[4]);
32491     mpfq_fixmp_12_5_addmul1_nc (z + 5, x, y[5]);
32492     mpfq_fixmp_12_5_addmul1_nc (z + 6, x, y[6]);
32493     mpfq_fixmp_12_5_addmul1_nc (z + 7, x, y[7]);
32494     mpfq_fixmp_12_5_addmul1_nc (z + 8, x, y[8]);
32495     mpfq_fixmp_12_5_addmul1_nc (z + 9, x, y[9]);
32496     mpfq_fixmp_12_5_addmul1_nc (z + 10, x, y[10]);
32497     mpfq_fixmp_12_5_addmul1_nc (z + 11, x, y[11]);
32498     mpfq_fixmp_12_5_addmul05_nc (z + 12, x, y[12]);
32499 }
32500 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mul) */
32501 
32502 #if !defined(HAVE_native_mpfq_fixmp_12_5_sqr)
32503 /* x has 12.5 words, z has 25. Put x*y in z. */
32504 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
32505 static inline
mpfq_fixmp_12_5_sqr(mp_limb_t * z,const mp_limb_t * x)32506 void mpfq_fixmp_12_5_sqr(mp_limb_t * z, const mp_limb_t * x)
32507 {
32508     mp_limb_t buf[25] = {0,};
32509     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
32510     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
32511     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
32512     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
32513     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
32514     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
32515     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
32516     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
32517     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
32518     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
32519     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
32520     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
32521     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
32522     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
32523     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
32524     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
32525     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
32526     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
32527     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
32528     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
32529     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
32530     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
32531     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
32532     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
32533     z[2*12] = x[12] * x[12];
32534     mpn_lshift(buf, buf, 25, 1);
32535     mpn_add_n(z, z, buf, 25);
32536 }
32537 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_sqr) */
32538 
32539 #if !defined(HAVE_native_mpfq_fixmp_12_5_mul1)
32540 /* x has 12.5 words, z has 14. Put x*y in z. */
32541 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
32542 static inline
mpfq_fixmp_12_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32543 void mpfq_fixmp_12_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32544 {
32545     mp_limb_t hi, lo, carry;
32546     carry = 0;
32547     mpfq_umul_ppmm(hi,lo,c,x[0]);
32548     lo += carry;
32549     carry = (lo<carry) + hi;
32550     z[0] = lo;
32551     mpfq_umul_ppmm(hi,lo,c,x[1]);
32552     lo += carry;
32553     carry = (lo<carry) + hi;
32554     z[1] = lo;
32555     mpfq_umul_ppmm(hi,lo,c,x[2]);
32556     lo += carry;
32557     carry = (lo<carry) + hi;
32558     z[2] = lo;
32559     mpfq_umul_ppmm(hi,lo,c,x[3]);
32560     lo += carry;
32561     carry = (lo<carry) + hi;
32562     z[3] = lo;
32563     mpfq_umul_ppmm(hi,lo,c,x[4]);
32564     lo += carry;
32565     carry = (lo<carry) + hi;
32566     z[4] = lo;
32567     mpfq_umul_ppmm(hi,lo,c,x[5]);
32568     lo += carry;
32569     carry = (lo<carry) + hi;
32570     z[5] = lo;
32571     mpfq_umul_ppmm(hi,lo,c,x[6]);
32572     lo += carry;
32573     carry = (lo<carry) + hi;
32574     z[6] = lo;
32575     mpfq_umul_ppmm(hi,lo,c,x[7]);
32576     lo += carry;
32577     carry = (lo<carry) + hi;
32578     z[7] = lo;
32579     mpfq_umul_ppmm(hi,lo,c,x[8]);
32580     lo += carry;
32581     carry = (lo<carry) + hi;
32582     z[8] = lo;
32583     mpfq_umul_ppmm(hi,lo,c,x[9]);
32584     lo += carry;
32585     carry = (lo<carry) + hi;
32586     z[9] = lo;
32587     mpfq_umul_ppmm(hi,lo,c,x[10]);
32588     lo += carry;
32589     carry = (lo<carry) + hi;
32590     z[10] = lo;
32591     mpfq_umul_ppmm(hi,lo,c,x[11]);
32592     lo += carry;
32593     carry = (lo<carry) + hi;
32594     z[11] = lo;
32595     mpfq_umul_ppmm(hi,lo,c,x[12]);
32596     lo += carry;
32597     carry = (lo<carry) + hi;
32598     z[12] = lo;
32599     z[13] = carry;
32600 }
32601 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mul1) */
32602 
32603 #if !defined(HAVE_native_mpfq_fixmp_12_5_shortmul)
32604 /* x and y have 12.5 words, z has 13.
32605  * Put the low 13 words of x*y in z. */
32606 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
32607 static inline
mpfq_fixmp_12_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)32608 void mpfq_fixmp_12_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
32609 {
32610     mpfq_zero(z, 13);
32611     mpfq_fixmp_12_addmul1_nc (z+0, x, y[0]);
32612     z[13-1] += x[12]*y[0];
32613     mpfq_fixmp_11_addmul1_nc (z+1, x, y[1]);
32614     z[13-1] += x[11]*y[1];
32615     mpfq_fixmp_10_addmul1_nc (z+2, x, y[2]);
32616     z[13-1] += x[10]*y[2];
32617     mpfq_fixmp_9_addmul1_nc (z+3, x, y[3]);
32618     z[13-1] += x[9]*y[3];
32619     mpfq_fixmp_8_addmul1_nc (z+4, x, y[4]);
32620     z[13-1] += x[8]*y[4];
32621     mpfq_fixmp_7_addmul1_nc (z+5, x, y[5]);
32622     z[13-1] += x[7]*y[5];
32623     mpfq_fixmp_6_addmul1_nc (z+6, x, y[6]);
32624     z[13-1] += x[6]*y[6];
32625     mpfq_fixmp_5_addmul1_nc (z+7, x, y[7]);
32626     z[13-1] += x[5]*y[7];
32627     mpfq_fixmp_4_addmul1_nc (z+8, x, y[8]);
32628     z[13-1] += x[4]*y[8];
32629     mpfq_fixmp_3_addmul1_nc (z+9, x, y[9]);
32630     z[13-1] += x[3]*y[9];
32631     mpfq_fixmp_2_addmul1_nc (z+10, x, y[10]);
32632     z[13-1] += x[2]*y[10];
32633     mpfq_fixmp_1_addmul1_nc (z+11, x, y[11]);
32634     z[13-1] += x[1]*y[11];
32635     z[13-1] += x[0]*y[13-1];
32636 }
32637 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_shortmul) */
32638 
32639 #if !defined(HAVE_native_mpfq_fixmp_12_5_addmul05)
32640 /* x has 12.5 words, z has 13. c is 0.5 word.
32641  * Put (z+x*c) in z. Return carry bit. */
32642 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
32643 static inline
mpfq_fixmp_12_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32644 mp_limb_t mpfq_fixmp_12_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32645 {
32646     mp_limb_t hi, lo, carry, buf;
32647     carry = 0;
32648     mpfq_umul_ppmm(hi,lo,c,x[0]);
32649     lo += carry;
32650     carry = (lo<carry) + hi;
32651     buf = z[0];
32652     lo += buf;
32653     carry += (lo<buf);
32654     z[0] = lo;
32655     mpfq_umul_ppmm(hi,lo,c,x[1]);
32656     lo += carry;
32657     carry = (lo<carry) + hi;
32658     buf = z[1];
32659     lo += buf;
32660     carry += (lo<buf);
32661     z[1] = lo;
32662     mpfq_umul_ppmm(hi,lo,c,x[2]);
32663     lo += carry;
32664     carry = (lo<carry) + hi;
32665     buf = z[2];
32666     lo += buf;
32667     carry += (lo<buf);
32668     z[2] = lo;
32669     mpfq_umul_ppmm(hi,lo,c,x[3]);
32670     lo += carry;
32671     carry = (lo<carry) + hi;
32672     buf = z[3];
32673     lo += buf;
32674     carry += (lo<buf);
32675     z[3] = lo;
32676     mpfq_umul_ppmm(hi,lo,c,x[4]);
32677     lo += carry;
32678     carry = (lo<carry) + hi;
32679     buf = z[4];
32680     lo += buf;
32681     carry += (lo<buf);
32682     z[4] = lo;
32683     mpfq_umul_ppmm(hi,lo,c,x[5]);
32684     lo += carry;
32685     carry = (lo<carry) + hi;
32686     buf = z[5];
32687     lo += buf;
32688     carry += (lo<buf);
32689     z[5] = lo;
32690     mpfq_umul_ppmm(hi,lo,c,x[6]);
32691     lo += carry;
32692     carry = (lo<carry) + hi;
32693     buf = z[6];
32694     lo += buf;
32695     carry += (lo<buf);
32696     z[6] = lo;
32697     mpfq_umul_ppmm(hi,lo,c,x[7]);
32698     lo += carry;
32699     carry = (lo<carry) + hi;
32700     buf = z[7];
32701     lo += buf;
32702     carry += (lo<buf);
32703     z[7] = lo;
32704     mpfq_umul_ppmm(hi,lo,c,x[8]);
32705     lo += carry;
32706     carry = (lo<carry) + hi;
32707     buf = z[8];
32708     lo += buf;
32709     carry += (lo<buf);
32710     z[8] = lo;
32711     mpfq_umul_ppmm(hi,lo,c,x[9]);
32712     lo += carry;
32713     carry = (lo<carry) + hi;
32714     buf = z[9];
32715     lo += buf;
32716     carry += (lo<buf);
32717     z[9] = lo;
32718     mpfq_umul_ppmm(hi,lo,c,x[10]);
32719     lo += carry;
32720     carry = (lo<carry) + hi;
32721     buf = z[10];
32722     lo += buf;
32723     carry += (lo<buf);
32724     z[10] = lo;
32725     mpfq_umul_ppmm(hi,lo,c,x[11]);
32726     lo += carry;
32727     carry = (lo<carry) + hi;
32728     buf = z[11];
32729     lo += buf;
32730     carry += (lo<buf);
32731     z[11] = lo;
32732     lo = c*x[12] + carry;
32733     assert(lo >= carry);
32734     z[12] += lo;
32735     return z[12] < lo;
32736 }
32737 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_addmul05) */
32738 
32739 #if !defined(HAVE_native_mpfq_fixmp_12_5_mul05)
32740 /* x has 12.5 words, z has 13. c is 0.5 word.
32741  * Put (x*c) in z. No carry. */
32742 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
32743 static inline
mpfq_fixmp_12_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)32744 void mpfq_fixmp_12_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
32745 {
32746     mp_limb_t hi, lo, carry;
32747     carry = 0;
32748     mpfq_umul_ppmm(hi,lo,c,x[0]);
32749     lo += carry;
32750     carry = (lo<carry) + hi;
32751     z[0] = lo;
32752     mpfq_umul_ppmm(hi,lo,c,x[1]);
32753     lo += carry;
32754     carry = (lo<carry) + hi;
32755     z[1] = lo;
32756     mpfq_umul_ppmm(hi,lo,c,x[2]);
32757     lo += carry;
32758     carry = (lo<carry) + hi;
32759     z[2] = lo;
32760     mpfq_umul_ppmm(hi,lo,c,x[3]);
32761     lo += carry;
32762     carry = (lo<carry) + hi;
32763     z[3] = lo;
32764     mpfq_umul_ppmm(hi,lo,c,x[4]);
32765     lo += carry;
32766     carry = (lo<carry) + hi;
32767     z[4] = lo;
32768     mpfq_umul_ppmm(hi,lo,c,x[5]);
32769     lo += carry;
32770     carry = (lo<carry) + hi;
32771     z[5] = lo;
32772     mpfq_umul_ppmm(hi,lo,c,x[6]);
32773     lo += carry;
32774     carry = (lo<carry) + hi;
32775     z[6] = lo;
32776     mpfq_umul_ppmm(hi,lo,c,x[7]);
32777     lo += carry;
32778     carry = (lo<carry) + hi;
32779     z[7] = lo;
32780     mpfq_umul_ppmm(hi,lo,c,x[8]);
32781     lo += carry;
32782     carry = (lo<carry) + hi;
32783     z[8] = lo;
32784     mpfq_umul_ppmm(hi,lo,c,x[9]);
32785     lo += carry;
32786     carry = (lo<carry) + hi;
32787     z[9] = lo;
32788     mpfq_umul_ppmm(hi,lo,c,x[10]);
32789     lo += carry;
32790     carry = (lo<carry) + hi;
32791     z[10] = lo;
32792     mpfq_umul_ppmm(hi,lo,c,x[11]);
32793     lo += carry;
32794     carry = (lo<carry) + hi;
32795     z[11] = lo;
32796     lo = c*x[12] + carry;
32797     assert(lo >= carry);
32798     z[12] = lo;
32799 }
32800 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mul05) */
32801 
32802 #if !defined(HAVE_native_mpfq_fixmp_12_5_mod)
32803 /* x has 25 words. z and p have 12.5 words, and the high word of p is non-zero.
32804  * Put x mod p in z. */
32805 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
32806 /* Triggered by: 12_5_mgy_decode */
32807 static inline
mpfq_fixmp_12_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)32808 void mpfq_fixmp_12_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
32809 {
32810     mp_limb_t q[12+1], r[13];
32811     assert (p[13-1] != 0);
32812     mpn_tdiv_qr(q, r, 0, x, 25, p, 13);
32813     mpfq_copy(z, r, 13);
32814 }
32815 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mod) */
32816 
32817 #if !defined(HAVE_native_mpfq_fixmp_12_5_rshift)
32818 /* a has 12.5 words. Shift it in place by cnt bits to the right.
32819  * The shift count cnt must not exceed the word size.
32820  * Note that no carry is returned for the bits shifted out. */
32821 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
32822 /* Triggered by: 12_5_invmod */
32823 static inline
mpfq_fixmp_12_5_rshift(mp_limb_t * a,int cnt)32824 void mpfq_fixmp_12_5_rshift(mp_limb_t * a, int cnt)
32825 {
32826     if (!cnt) return;
32827     int i;
32828     int dnt = GMP_NUMB_BITS - cnt;
32829     for (i = 0; i < 13-1; ++i) {
32830         a[i] >>= cnt;
32831         a[i] |= (a[i+1] << dnt);
32832     }
32833     a[13-1] >>= cnt;
32834 }
32835 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_rshift) */
32836 
32837 #if !defined(HAVE_native_mpfq_fixmp_12_5_long_rshift)
32838 /* a has 12.5 words. Shift it in place by off words plus cnt bits to the left.
32839  * Note that no carry is returned for the bits shifted out. */
32840 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
32841 /* Triggered by: 12_5_invmod */
32842 static inline
mpfq_fixmp_12_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)32843 void mpfq_fixmp_12_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
32844 {
32845     if (cnt) {
32846         int dnt = GMP_NUMB_BITS - cnt;
32847         for (int i = 0; i < 13 - off - 1; ++i) {
32848             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
32849         }
32850         a[13-off-1] = a[13-1]>>cnt;
32851     } else {
32852         mpfq_copyi(a, a + off, 13 - off);
32853     }
32854     mpfq_zero(a + 13 - off, off);
32855 }
32856 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_long_rshift) */
32857 
32858 #if !defined(HAVE_native_mpfq_fixmp_12_5_long_lshift)
32859 /* a has 12.5 words. Shift it in place by off words plus cnt bits to the left.
32860  * Note that no carry is returned for the bits shifted out. */
32861 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
32862 /* Triggered by: 12_5_invmod */
32863 static inline
mpfq_fixmp_12_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)32864 void mpfq_fixmp_12_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
32865 {
32866     int i;
32867     if (cnt) {
32868         int dnt = GMP_NUMB_BITS - cnt;
32869         for (i = 13-1; i>off; --i) {
32870             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
32871         }
32872         a[off] = a[0]<<cnt;
32873     } else {
32874         mpfq_copyd(a + off, a, 13 - off);
32875     }
32876     mpfq_zero(a, off);
32877 }
32878 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_long_lshift) */
32879 
32880 #if !defined(HAVE_native_mpfq_fixmp_12_5_invmod)
32881 /* x, z, and p have 12.5 words. Put inverse of x mod p in z.
32882  * Return non-zero if an inverse could be found.
32883  * If no inverse could be found, return 0 and set z to zero.
32884  */
32885 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
32886 static inline
mpfq_fixmp_12_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)32887 int mpfq_fixmp_12_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
32888 {
32889       mp_limb_t u[13], v[13], a[13], b[13], fix[13];
32890       int i, t, lsh;
32891 
32892       mpfq_zero(u, 13);
32893       mpfq_zero(v, 13);
32894       mpfq_copy(a, x, 13);
32895       mpfq_copy(b, p, 13);
32896       u[0] = 1UL;
32897 
32898       if (mpfq_fixmp_12_5_cmp(a, v) == 0 || mpfq_fixmp_12_5_cmp(a, b) == 0) {
32899         mpfq_zero(res, 13);
32900         return 0;
32901       }
32902 
32903       mpfq_fixmp_12_5_add(fix, b, u);
32904       mpfq_fixmp_12_5_rshift(fix, 1);
32905 
32906       assert (mpfq_fixmp_12_5_cmp(a,b) < 0);
32907 
32908       t = 0;
32909 
32910       for(i = 0 ; !a[i] ; i++) ;
32911       assert (i < 13);
32912       lsh = mpfq_ctzl(a[i]);
32913       mpfq_fixmp_12_5_long_rshift(a, i, lsh);
32914       t += lsh + i*GMP_NUMB_BITS;
32915       mpfq_fixmp_12_5_long_lshift(v, i, lsh);
32916 
32917       do {
32918         do {
32919           mpfq_fixmp_12_5_sub(b, b, a);
32920           mpfq_fixmp_12_5_add(v, v, u);
32921           for(i = 0 ; !b[i] ; i++) ;
32922           assert (i < 13);
32923           lsh = mpfq_ctzl(b[i]);
32924           mpfq_fixmp_12_5_long_rshift(b, i, lsh);
32925           t += lsh + i*GMP_NUMB_BITS;
32926           mpfq_fixmp_12_5_long_lshift(u, i, lsh);
32927         } while (mpfq_fixmp_12_5_cmp(a,b) < 0);
32928         if (mpfq_fixmp_12_5_cmp(a, b) == 0)
32929           break;
32930         do {
32931           mpfq_fixmp_12_5_sub(a, a, b);
32932           mpfq_fixmp_12_5_add(u, u, v);
32933           for(i = 0 ; !a[i] ; i++) ;
32934           assert (i < 13);
32935           lsh = mpfq_ctzl(a[i]);
32936           mpfq_fixmp_12_5_long_rshift(a, i, lsh);
32937           t += lsh + i*GMP_NUMB_BITS;
32938           mpfq_fixmp_12_5_long_lshift(v, i, lsh);
32939         } while (mpfq_fixmp_12_5_cmp(b,a)<0);
32940       } while (mpfq_fixmp_12_5_cmp(a,b) != 0);
32941       {
32942         if (mpfq_fixmp_12_5_cmp_ui(a, 1) != 0) {
32943           mpfq_copy(res, a, 13);
32944           return 0;
32945         }
32946       }
32947       while (t>0) {
32948         mp_limb_t sig = u[0] & 1UL;
32949         mpfq_fixmp_12_5_rshift(u, 1);
32950         if (sig)
32951           mpfq_fixmp_12_5_add(u, u, fix);
32952         --t;
32953       }
32954       mpfq_copy(res, u, 13);
32955       return 1;
32956 }
32957 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_invmod) */
32958 
32959 #if !defined(HAVE_native_mpfq_fixmp_12_5_redc)
32960 /* x has 25 words, z and p have 12.5 words.
32961  * only one word is read from invp.
32962  * Assuming R=W^13 is the redc modulus, we expect that x verifies:
32963  *   x < R*p,
32964  * so that we have eventually z < p, z congruent to x/R mod p.
32965  * The contents of the area pointed by x are clobbered by this call.
32966  * Note also that x may alias z.
32967  */
32968 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
32969 static inline
mpfq_fixmp_12_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)32970 void mpfq_fixmp_12_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
32971 {
32972     mp_limb_t cy;
32973     for(int i = 0; i < 13; ++i) {
32974         mp_limb_t t = x[i]*mip[0];
32975         cy = mpfq_fixmp_12_5_addmul1_shortz(x+i, p, t);
32976         assert (x[i] == 0);
32977         x[i] = cy;
32978     }
32979     {
32980         mp_limb_t ret[13] = { x[13], x[14], x[15], x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], x[24], 0 };
32981         cy = mpfq_fixmp_12_5_add(x, x, ret);
32982     }
32983     /* At this point, we have (x' denotes x + cy*W^n here)
32984     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
32985     * x'/R < p + p
32986     */
32987     if (cy || mpfq_fixmp_12_5_cmp(x, p) >= 0) {
32988         mpfq_fixmp_12_5_sub(z, x, p);
32989     } else {
32990         mpfq_copy(z, x, 13);
32991     }
32992 }
32993 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_redc) */
32994 
32995 #if !defined(HAVE_native_mpfq_fixmp_12_5_redc_ur)
32996 /* x has 26 words, z and p have 12.5 words.
32997  * only one word is read from invp.
32998  * Assuming R=W^13 is the redc modulus, we expect that x verifies:
32999  *  x < W*W^12.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
33000  * so that we have eventually z < p, z congruent to x/R mod p.
33001  * The contents of the area pointed by x are clobbered by this call.
33002  * Note also that x may alias z.
33003  */
33004 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
33005 static inline
mpfq_fixmp_12_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)33006 void mpfq_fixmp_12_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
33007 {
33008     mp_limb_t cy, q[1];
33009     for(int i = 0; i < 13; ++i) {
33010         mp_limb_t t = x[i]*mip[0];
33011         cy = mpfq_fixmp_12_5_addmul1_shortz(x+i, p, t);
33012         assert (x[i] == 0);
33013         x[i] = cy;
33014     }
33015     cy = mpfq_fixmp_12_5_add(x + 13, x, x + 13);
33016     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
33017     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
33018     * x'/R < (W^0.5+1)*p
33019     */
33020     if (cy) {
33021         /* x'/R-p < W^0.5*p, which fits in n words. */
33022         mpfq_fixmp_12_5_sub(x + 13, x + 13, p);
33023     }
33024     mpn_tdiv_qr(q, z, 0, x + 13, 13, p, 13);
33025 }
33026 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_redc_ur) */
33027 
33028 #if !defined(HAVE_native_mpfq_fixmp_12_5_mgy_encode)
33029 /* x, z, and p have 12.5 words.
33030  * Assuming R=W^13 is the redc modulus, we compute z=R*x mod p. */
33031 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
33032 static inline
mpfq_fixmp_12_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)33033 void mpfq_fixmp_12_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
33034 {
33035     mp_limb_t t[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12] };
33036     mp_limb_t qq[13+1];
33037     mpn_tdiv_qr(qq, z, 0, t, 26, p, 13);
33038 }
33039 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mgy_encode) */
33040 
33041 #if !defined(HAVE_native_mpfq_fixmp_12_5_mgy_decode)
33042 /* x, z, invR, and p have 12.5 words.
33043  * Assuming R=W^13 is the redc modulus, we compute z=x/R mod p. */
33044 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
33045 static inline
mpfq_fixmp_12_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)33046 void mpfq_fixmp_12_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
33047 {
33048     mp_limb_t t[26];
33049     mpfq_fixmp_12_5_mul(t, x, invR);
33050     mpfq_fixmp_12_5_mod(z, t, p);
33051 }
33052 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_mgy_decode) */
33053 
33054 #if !defined(HAVE_native_mpfq_fixmp_12_5_lshift)
33055 /* a has 12.5 words. Shift it in place by cnt bits to the left.
33056  * The shift count cnt must not exceed the word size.
33057  * Note that no carry is returned for the bits shifted out. */
33058 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
33059 static inline
mpfq_fixmp_12_5_lshift(mp_limb_t * a,int cnt)33060 void mpfq_fixmp_12_5_lshift(mp_limb_t * a, int cnt)
33061 {
33062     if (!cnt) return;
33063     int i;
33064     int dnt = GMP_NUMB_BITS - cnt;
33065     for (i = 13-1; i>0; --i) {
33066         a[i] <<= cnt;
33067         a[i] |= (a[i-1] >> dnt);
33068     }
33069     a[0] <<= cnt;
33070 }
33071 #endif /* !defined(HAVE_native_mpfq_fixmp_12_5_lshift) */
33072 
33073 #if !defined(HAVE_native_mpfq_fixmp_13_5_add)
33074 /* x, y, and z have 13.5 words. Result in z. Return carry bit */
33075 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
33076 /* Triggered by: 13_5_invmod, 13_5_redc, 13_5_redc_ur */
33077 static inline
mpfq_fixmp_13_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)33078 mp_limb_t mpfq_fixmp_13_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
33079 {
33080     mp_limb_t r, s, t, cy, cy1, cy2;
33081     cy = 0;
33082     r = x[0];
33083     s = r + y[0];
33084     cy1 = s < r;
33085     t = s + cy;
33086     cy2 = t < s;
33087     cy = cy1 | cy2;
33088     z[0] = t;
33089     r = x[1];
33090     s = r + y[1];
33091     cy1 = s < r;
33092     t = s + cy;
33093     cy2 = t < s;
33094     cy = cy1 | cy2;
33095     z[1] = t;
33096     r = x[2];
33097     s = r + y[2];
33098     cy1 = s < r;
33099     t = s + cy;
33100     cy2 = t < s;
33101     cy = cy1 | cy2;
33102     z[2] = t;
33103     r = x[3];
33104     s = r + y[3];
33105     cy1 = s < r;
33106     t = s + cy;
33107     cy2 = t < s;
33108     cy = cy1 | cy2;
33109     z[3] = t;
33110     r = x[4];
33111     s = r + y[4];
33112     cy1 = s < r;
33113     t = s + cy;
33114     cy2 = t < s;
33115     cy = cy1 | cy2;
33116     z[4] = t;
33117     r = x[5];
33118     s = r + y[5];
33119     cy1 = s < r;
33120     t = s + cy;
33121     cy2 = t < s;
33122     cy = cy1 | cy2;
33123     z[5] = t;
33124     r = x[6];
33125     s = r + y[6];
33126     cy1 = s < r;
33127     t = s + cy;
33128     cy2 = t < s;
33129     cy = cy1 | cy2;
33130     z[6] = t;
33131     r = x[7];
33132     s = r + y[7];
33133     cy1 = s < r;
33134     t = s + cy;
33135     cy2 = t < s;
33136     cy = cy1 | cy2;
33137     z[7] = t;
33138     r = x[8];
33139     s = r + y[8];
33140     cy1 = s < r;
33141     t = s + cy;
33142     cy2 = t < s;
33143     cy = cy1 | cy2;
33144     z[8] = t;
33145     r = x[9];
33146     s = r + y[9];
33147     cy1 = s < r;
33148     t = s + cy;
33149     cy2 = t < s;
33150     cy = cy1 | cy2;
33151     z[9] = t;
33152     r = x[10];
33153     s = r + y[10];
33154     cy1 = s < r;
33155     t = s + cy;
33156     cy2 = t < s;
33157     cy = cy1 | cy2;
33158     z[10] = t;
33159     r = x[11];
33160     s = r + y[11];
33161     cy1 = s < r;
33162     t = s + cy;
33163     cy2 = t < s;
33164     cy = cy1 | cy2;
33165     z[11] = t;
33166     r = x[12];
33167     s = r + y[12];
33168     cy1 = s < r;
33169     t = s + cy;
33170     cy2 = t < s;
33171     cy = cy1 | cy2;
33172     z[12] = t;
33173     r = x[13];
33174     s = r + y[13];
33175     cy1 = s < r;
33176     t = s + cy;
33177     cy2 = t < s;
33178     cy = cy1 | cy2;
33179     z[13] = t;
33180     return cy;
33181 }
33182 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_add) */
33183 
33184 #if !defined(HAVE_native_mpfq_fixmp_13_5_sub)
33185 /* x, y, and z have 13.5 words. Result in z. Return borrow bit */
33186 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
33187 /* Triggered by: 13_5_invmod, 13_5_redc, 13_5_redc_ur */
33188 static inline
mpfq_fixmp_13_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)33189 mp_limb_t mpfq_fixmp_13_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
33190 {
33191     mp_limb_t r, s, t, cy, cy1, cy2;
33192     cy = 0;
33193     r = x[0];
33194     s = r - y[0];
33195     cy1 = s > r;
33196     t = s - cy;
33197     cy2 = t > s;
33198     cy = cy1 | cy2;
33199     z[0] = t;
33200     r = x[1];
33201     s = r - y[1];
33202     cy1 = s > r;
33203     t = s - cy;
33204     cy2 = t > s;
33205     cy = cy1 | cy2;
33206     z[1] = t;
33207     r = x[2];
33208     s = r - y[2];
33209     cy1 = s > r;
33210     t = s - cy;
33211     cy2 = t > s;
33212     cy = cy1 | cy2;
33213     z[2] = t;
33214     r = x[3];
33215     s = r - y[3];
33216     cy1 = s > r;
33217     t = s - cy;
33218     cy2 = t > s;
33219     cy = cy1 | cy2;
33220     z[3] = t;
33221     r = x[4];
33222     s = r - y[4];
33223     cy1 = s > r;
33224     t = s - cy;
33225     cy2 = t > s;
33226     cy = cy1 | cy2;
33227     z[4] = t;
33228     r = x[5];
33229     s = r - y[5];
33230     cy1 = s > r;
33231     t = s - cy;
33232     cy2 = t > s;
33233     cy = cy1 | cy2;
33234     z[5] = t;
33235     r = x[6];
33236     s = r - y[6];
33237     cy1 = s > r;
33238     t = s - cy;
33239     cy2 = t > s;
33240     cy = cy1 | cy2;
33241     z[6] = t;
33242     r = x[7];
33243     s = r - y[7];
33244     cy1 = s > r;
33245     t = s - cy;
33246     cy2 = t > s;
33247     cy = cy1 | cy2;
33248     z[7] = t;
33249     r = x[8];
33250     s = r - y[8];
33251     cy1 = s > r;
33252     t = s - cy;
33253     cy2 = t > s;
33254     cy = cy1 | cy2;
33255     z[8] = t;
33256     r = x[9];
33257     s = r - y[9];
33258     cy1 = s > r;
33259     t = s - cy;
33260     cy2 = t > s;
33261     cy = cy1 | cy2;
33262     z[9] = t;
33263     r = x[10];
33264     s = r - y[10];
33265     cy1 = s > r;
33266     t = s - cy;
33267     cy2 = t > s;
33268     cy = cy1 | cy2;
33269     z[10] = t;
33270     r = x[11];
33271     s = r - y[11];
33272     cy1 = s > r;
33273     t = s - cy;
33274     cy2 = t > s;
33275     cy = cy1 | cy2;
33276     z[11] = t;
33277     r = x[12];
33278     s = r - y[12];
33279     cy1 = s > r;
33280     t = s - cy;
33281     cy2 = t > s;
33282     cy = cy1 | cy2;
33283     z[12] = t;
33284     r = x[13];
33285     s = r - y[13];
33286     cy1 = s > r;
33287     t = s - cy;
33288     cy2 = t > s;
33289     cy = cy1 | cy2;
33290     z[13] = t;
33291     return cy;
33292 }
33293 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_sub) */
33294 
33295 #if !defined(HAVE_native_mpfq_fixmp_13_5_add_nc)
33296 /* x, y, and z have 13.5 words. Result in z. Carry bit is lost. */
33297 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
33298 static inline
mpfq_fixmp_13_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)33299 void mpfq_fixmp_13_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
33300 {
33301     mp_limb_t r, s, t, cy, cy1, cy2;
33302     cy = 0;
33303     r = x[0];
33304     s = r + y[0];
33305     cy1 = s < r;
33306     t = s + cy;
33307     cy2 = t < s;
33308     cy = cy1 | cy2;
33309     z[0] = t;
33310     r = x[1];
33311     s = r + y[1];
33312     cy1 = s < r;
33313     t = s + cy;
33314     cy2 = t < s;
33315     cy = cy1 | cy2;
33316     z[1] = t;
33317     r = x[2];
33318     s = r + y[2];
33319     cy1 = s < r;
33320     t = s + cy;
33321     cy2 = t < s;
33322     cy = cy1 | cy2;
33323     z[2] = t;
33324     r = x[3];
33325     s = r + y[3];
33326     cy1 = s < r;
33327     t = s + cy;
33328     cy2 = t < s;
33329     cy = cy1 | cy2;
33330     z[3] = t;
33331     r = x[4];
33332     s = r + y[4];
33333     cy1 = s < r;
33334     t = s + cy;
33335     cy2 = t < s;
33336     cy = cy1 | cy2;
33337     z[4] = t;
33338     r = x[5];
33339     s = r + y[5];
33340     cy1 = s < r;
33341     t = s + cy;
33342     cy2 = t < s;
33343     cy = cy1 | cy2;
33344     z[5] = t;
33345     r = x[6];
33346     s = r + y[6];
33347     cy1 = s < r;
33348     t = s + cy;
33349     cy2 = t < s;
33350     cy = cy1 | cy2;
33351     z[6] = t;
33352     r = x[7];
33353     s = r + y[7];
33354     cy1 = s < r;
33355     t = s + cy;
33356     cy2 = t < s;
33357     cy = cy1 | cy2;
33358     z[7] = t;
33359     r = x[8];
33360     s = r + y[8];
33361     cy1 = s < r;
33362     t = s + cy;
33363     cy2 = t < s;
33364     cy = cy1 | cy2;
33365     z[8] = t;
33366     r = x[9];
33367     s = r + y[9];
33368     cy1 = s < r;
33369     t = s + cy;
33370     cy2 = t < s;
33371     cy = cy1 | cy2;
33372     z[9] = t;
33373     r = x[10];
33374     s = r + y[10];
33375     cy1 = s < r;
33376     t = s + cy;
33377     cy2 = t < s;
33378     cy = cy1 | cy2;
33379     z[10] = t;
33380     r = x[11];
33381     s = r + y[11];
33382     cy1 = s < r;
33383     t = s + cy;
33384     cy2 = t < s;
33385     cy = cy1 | cy2;
33386     z[11] = t;
33387     r = x[12];
33388     s = r + y[12];
33389     cy1 = s < r;
33390     t = s + cy;
33391     cy2 = t < s;
33392     cy = cy1 | cy2;
33393     z[12] = t;
33394     r = x[13];
33395     s = r + y[13];
33396     cy1 = s < r;
33397     t = s + cy;
33398     cy2 = t < s;
33399     cy = cy1 | cy2;
33400     z[13] = t;
33401 }
33402 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_add_nc) */
33403 
33404 #if !defined(HAVE_native_mpfq_fixmp_13_5_sub_nc)
33405 /* x, y, and z have 13.5 words. Result in z. Borrow bit is lost. */
33406 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
33407 static inline
mpfq_fixmp_13_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)33408 void mpfq_fixmp_13_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
33409 {
33410     mp_limb_t r, s, t, cy, cy1, cy2;
33411     cy = 0;
33412     r = x[0];
33413     s = r - y[0];
33414     cy1 = s > r;
33415     t = s - cy;
33416     cy2 = t > s;
33417     cy = cy1 | cy2;
33418     z[0] = t;
33419     r = x[1];
33420     s = r - y[1];
33421     cy1 = s > r;
33422     t = s - cy;
33423     cy2 = t > s;
33424     cy = cy1 | cy2;
33425     z[1] = t;
33426     r = x[2];
33427     s = r - y[2];
33428     cy1 = s > r;
33429     t = s - cy;
33430     cy2 = t > s;
33431     cy = cy1 | cy2;
33432     z[2] = t;
33433     r = x[3];
33434     s = r - y[3];
33435     cy1 = s > r;
33436     t = s - cy;
33437     cy2 = t > s;
33438     cy = cy1 | cy2;
33439     z[3] = t;
33440     r = x[4];
33441     s = r - y[4];
33442     cy1 = s > r;
33443     t = s - cy;
33444     cy2 = t > s;
33445     cy = cy1 | cy2;
33446     z[4] = t;
33447     r = x[5];
33448     s = r - y[5];
33449     cy1 = s > r;
33450     t = s - cy;
33451     cy2 = t > s;
33452     cy = cy1 | cy2;
33453     z[5] = t;
33454     r = x[6];
33455     s = r - y[6];
33456     cy1 = s > r;
33457     t = s - cy;
33458     cy2 = t > s;
33459     cy = cy1 | cy2;
33460     z[6] = t;
33461     r = x[7];
33462     s = r - y[7];
33463     cy1 = s > r;
33464     t = s - cy;
33465     cy2 = t > s;
33466     cy = cy1 | cy2;
33467     z[7] = t;
33468     r = x[8];
33469     s = r - y[8];
33470     cy1 = s > r;
33471     t = s - cy;
33472     cy2 = t > s;
33473     cy = cy1 | cy2;
33474     z[8] = t;
33475     r = x[9];
33476     s = r - y[9];
33477     cy1 = s > r;
33478     t = s - cy;
33479     cy2 = t > s;
33480     cy = cy1 | cy2;
33481     z[9] = t;
33482     r = x[10];
33483     s = r - y[10];
33484     cy1 = s > r;
33485     t = s - cy;
33486     cy2 = t > s;
33487     cy = cy1 | cy2;
33488     z[10] = t;
33489     r = x[11];
33490     s = r - y[11];
33491     cy1 = s > r;
33492     t = s - cy;
33493     cy2 = t > s;
33494     cy = cy1 | cy2;
33495     z[11] = t;
33496     r = x[12];
33497     s = r - y[12];
33498     cy1 = s > r;
33499     t = s - cy;
33500     cy2 = t > s;
33501     cy = cy1 | cy2;
33502     z[12] = t;
33503     r = x[13];
33504     s = r - y[13];
33505     cy1 = s > r;
33506     t = s - cy;
33507     cy2 = t > s;
33508     cy = cy1 | cy2;
33509     z[13] = t;
33510 }
33511 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_sub_nc) */
33512 
33513 #if !defined(HAVE_native_mpfq_fixmp_13_5_add_ui)
33514 /* x, y, and z have 13.5 words. Result in z. Return carry bit */
33515 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
33516 static inline
mpfq_fixmp_13_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)33517 mp_limb_t mpfq_fixmp_13_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
33518 {
33519     mp_limb_t r, s, t, cy, cy1, cy2;
33520     cy = 0;
33521     r = x[0];
33522     s = r + y;
33523     cy1 = s < r;
33524     t = s + cy;
33525     cy2 = t < s;
33526     cy = cy1 | cy2;
33527     z[0] = t;
33528     s = x[1];
33529     t = s + cy;
33530     cy = t < s;
33531     z[1] = t;
33532     s = x[2];
33533     t = s + cy;
33534     cy = t < s;
33535     z[2] = t;
33536     s = x[3];
33537     t = s + cy;
33538     cy = t < s;
33539     z[3] = t;
33540     s = x[4];
33541     t = s + cy;
33542     cy = t < s;
33543     z[4] = t;
33544     s = x[5];
33545     t = s + cy;
33546     cy = t < s;
33547     z[5] = t;
33548     s = x[6];
33549     t = s + cy;
33550     cy = t < s;
33551     z[6] = t;
33552     s = x[7];
33553     t = s + cy;
33554     cy = t < s;
33555     z[7] = t;
33556     s = x[8];
33557     t = s + cy;
33558     cy = t < s;
33559     z[8] = t;
33560     s = x[9];
33561     t = s + cy;
33562     cy = t < s;
33563     z[9] = t;
33564     s = x[10];
33565     t = s + cy;
33566     cy = t < s;
33567     z[10] = t;
33568     s = x[11];
33569     t = s + cy;
33570     cy = t < s;
33571     z[11] = t;
33572     s = x[12];
33573     t = s + cy;
33574     cy = t < s;
33575     z[12] = t;
33576     s = x[13];
33577     t = s + cy;
33578     cy = t < s;
33579     z[13] = t;
33580     return cy;
33581 }
33582 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_add_ui) */
33583 
33584 #if !defined(HAVE_native_mpfq_fixmp_13_5_sub_ui)
33585 /* x, y, and z have 13.5 words. Result in z. Return borrow bit */
33586 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
33587 static inline
mpfq_fixmp_13_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)33588 mp_limb_t mpfq_fixmp_13_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
33589 {
33590     mp_limb_t r, s, t, cy, cy1, cy2;
33591     cy = 0;
33592     r = x[0];
33593     s = r - y;
33594     cy1 = s > r;
33595     t = s - cy;
33596     cy2 = t > s;
33597     cy = cy1 | cy2;
33598     z[0] = t;
33599     s = x[1];
33600     t = s - cy;
33601     cy = t > s;
33602     z[1] = t;
33603     s = x[2];
33604     t = s - cy;
33605     cy = t > s;
33606     z[2] = t;
33607     s = x[3];
33608     t = s - cy;
33609     cy = t > s;
33610     z[3] = t;
33611     s = x[4];
33612     t = s - cy;
33613     cy = t > s;
33614     z[4] = t;
33615     s = x[5];
33616     t = s - cy;
33617     cy = t > s;
33618     z[5] = t;
33619     s = x[6];
33620     t = s - cy;
33621     cy = t > s;
33622     z[6] = t;
33623     s = x[7];
33624     t = s - cy;
33625     cy = t > s;
33626     z[7] = t;
33627     s = x[8];
33628     t = s - cy;
33629     cy = t > s;
33630     z[8] = t;
33631     s = x[9];
33632     t = s - cy;
33633     cy = t > s;
33634     z[9] = t;
33635     s = x[10];
33636     t = s - cy;
33637     cy = t > s;
33638     z[10] = t;
33639     s = x[11];
33640     t = s - cy;
33641     cy = t > s;
33642     z[11] = t;
33643     s = x[12];
33644     t = s - cy;
33645     cy = t > s;
33646     z[12] = t;
33647     s = x[13];
33648     t = s - cy;
33649     cy = t > s;
33650     z[13] = t;
33651     return cy;
33652 }
33653 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_sub_ui) */
33654 
33655 #if !defined(HAVE_native_mpfq_fixmp_13_5_add_ui_nc)
33656 /* x, y, and z have 13.5 words. Result in z. Carry bit is lost. */
33657 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
33658 static inline
mpfq_fixmp_13_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)33659 void mpfq_fixmp_13_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
33660 {
33661     mp_limb_t r, s, t, cy, cy1, cy2;
33662     cy = 0;
33663     r = x[0];
33664     s = r + y;
33665     cy1 = s < r;
33666     t = s + cy;
33667     cy2 = t < s;
33668     cy = cy1 | cy2;
33669     z[0] = t;
33670     s = x[1];
33671     t = s + cy;
33672     cy = t < s;
33673     z[1] = t;
33674     s = x[2];
33675     t = s + cy;
33676     cy = t < s;
33677     z[2] = t;
33678     s = x[3];
33679     t = s + cy;
33680     cy = t < s;
33681     z[3] = t;
33682     s = x[4];
33683     t = s + cy;
33684     cy = t < s;
33685     z[4] = t;
33686     s = x[5];
33687     t = s + cy;
33688     cy = t < s;
33689     z[5] = t;
33690     s = x[6];
33691     t = s + cy;
33692     cy = t < s;
33693     z[6] = t;
33694     s = x[7];
33695     t = s + cy;
33696     cy = t < s;
33697     z[7] = t;
33698     s = x[8];
33699     t = s + cy;
33700     cy = t < s;
33701     z[8] = t;
33702     s = x[9];
33703     t = s + cy;
33704     cy = t < s;
33705     z[9] = t;
33706     s = x[10];
33707     t = s + cy;
33708     cy = t < s;
33709     z[10] = t;
33710     s = x[11];
33711     t = s + cy;
33712     cy = t < s;
33713     z[11] = t;
33714     s = x[12];
33715     t = s + cy;
33716     cy = t < s;
33717     z[12] = t;
33718     s = x[13];
33719     t = s + cy;
33720     cy = t < s;
33721     z[13] = t;
33722 }
33723 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_add_ui_nc) */
33724 
33725 #if !defined(HAVE_native_mpfq_fixmp_13_5_sub_ui_nc)
33726 /* x, y, and z have 13.5 words. Result in z. Borrow bit is lost. */
33727 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
33728 static inline
mpfq_fixmp_13_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)33729 void mpfq_fixmp_13_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
33730 {
33731     mp_limb_t r, s, t, cy, cy1, cy2;
33732     cy = 0;
33733     r = x[0];
33734     s = r - y;
33735     cy1 = s > r;
33736     t = s - cy;
33737     cy2 = t > s;
33738     cy = cy1 | cy2;
33739     z[0] = t;
33740     s = x[1];
33741     t = s - cy;
33742     cy = t > s;
33743     z[1] = t;
33744     s = x[2];
33745     t = s - cy;
33746     cy = t > s;
33747     z[2] = t;
33748     s = x[3];
33749     t = s - cy;
33750     cy = t > s;
33751     z[3] = t;
33752     s = x[4];
33753     t = s - cy;
33754     cy = t > s;
33755     z[4] = t;
33756     s = x[5];
33757     t = s - cy;
33758     cy = t > s;
33759     z[5] = t;
33760     s = x[6];
33761     t = s - cy;
33762     cy = t > s;
33763     z[6] = t;
33764     s = x[7];
33765     t = s - cy;
33766     cy = t > s;
33767     z[7] = t;
33768     s = x[8];
33769     t = s - cy;
33770     cy = t > s;
33771     z[8] = t;
33772     s = x[9];
33773     t = s - cy;
33774     cy = t > s;
33775     z[9] = t;
33776     s = x[10];
33777     t = s - cy;
33778     cy = t > s;
33779     z[10] = t;
33780     s = x[11];
33781     t = s - cy;
33782     cy = t > s;
33783     z[11] = t;
33784     s = x[12];
33785     t = s - cy;
33786     cy = t > s;
33787     z[12] = t;
33788     s = x[13];
33789     t = s - cy;
33790     cy = t > s;
33791     z[13] = t;
33792 }
33793 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_sub_ui_nc) */
33794 
33795 #if !defined(HAVE_native_mpfq_fixmp_13_5_cmp)
33796 /* x and y have 13.5 words. Return sign of difference x-y. */
33797 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
33798 /* Triggered by: 13_5_invmod, 13_5_redc, 13_5_redc_ur */
33799 static inline
mpfq_fixmp_13_5_cmp(const mp_limb_t * x,const mp_limb_t * y)33800 int mpfq_fixmp_13_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
33801 {
33802     for (int i = 14-1; i >= 0; --i) {
33803         if (x[i] > y[i]) return 1;
33804         if (x[i] < y[i]) return -1;
33805     }
33806     return 0;
33807 }
33808 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_cmp) */
33809 
33810 #if !defined(HAVE_native_mpfq_fixmp_13_5_cmp_ui)
33811 /* x has 13.5 words. Return sign of difference x-y. */
33812 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
33813 /* Triggered by: 13_5_invmod */
33814 static inline
mpfq_fixmp_13_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)33815 int mpfq_fixmp_13_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
33816 {
33817     for (int i = 14-1; i > 0; --i) {
33818         if (x[i]) return 1;
33819     }
33820     if (x[0]>y) return 1;
33821     if (x[0]<y) return -1;
33822     return 0;
33823 }
33824 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_cmp_ui) */
33825 
33826 #if !defined(HAVE_native_mpfq_fixmp_13_5_addmul1)
33827 /* x has 13.5 words, z has 15.
33828  * Put (z+x*c) in z. Return carry bit. */
33829 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
33830 static inline
mpfq_fixmp_13_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)33831 mp_limb_t mpfq_fixmp_13_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
33832 {
33833     mp_limb_t hi, lo, carry, buf;
33834     carry = 0;
33835     mpfq_umul_ppmm(hi,lo,c,x[0]);
33836     lo += carry;
33837     carry = (lo<carry) + hi;
33838     buf = z[0];
33839     lo += buf;
33840     carry += (lo<buf);
33841     z[0] = lo;
33842     mpfq_umul_ppmm(hi,lo,c,x[1]);
33843     lo += carry;
33844     carry = (lo<carry) + hi;
33845     buf = z[1];
33846     lo += buf;
33847     carry += (lo<buf);
33848     z[1] = lo;
33849     mpfq_umul_ppmm(hi,lo,c,x[2]);
33850     lo += carry;
33851     carry = (lo<carry) + hi;
33852     buf = z[2];
33853     lo += buf;
33854     carry += (lo<buf);
33855     z[2] = lo;
33856     mpfq_umul_ppmm(hi,lo,c,x[3]);
33857     lo += carry;
33858     carry = (lo<carry) + hi;
33859     buf = z[3];
33860     lo += buf;
33861     carry += (lo<buf);
33862     z[3] = lo;
33863     mpfq_umul_ppmm(hi,lo,c,x[4]);
33864     lo += carry;
33865     carry = (lo<carry) + hi;
33866     buf = z[4];
33867     lo += buf;
33868     carry += (lo<buf);
33869     z[4] = lo;
33870     mpfq_umul_ppmm(hi,lo,c,x[5]);
33871     lo += carry;
33872     carry = (lo<carry) + hi;
33873     buf = z[5];
33874     lo += buf;
33875     carry += (lo<buf);
33876     z[5] = lo;
33877     mpfq_umul_ppmm(hi,lo,c,x[6]);
33878     lo += carry;
33879     carry = (lo<carry) + hi;
33880     buf = z[6];
33881     lo += buf;
33882     carry += (lo<buf);
33883     z[6] = lo;
33884     mpfq_umul_ppmm(hi,lo,c,x[7]);
33885     lo += carry;
33886     carry = (lo<carry) + hi;
33887     buf = z[7];
33888     lo += buf;
33889     carry += (lo<buf);
33890     z[7] = lo;
33891     mpfq_umul_ppmm(hi,lo,c,x[8]);
33892     lo += carry;
33893     carry = (lo<carry) + hi;
33894     buf = z[8];
33895     lo += buf;
33896     carry += (lo<buf);
33897     z[8] = lo;
33898     mpfq_umul_ppmm(hi,lo,c,x[9]);
33899     lo += carry;
33900     carry = (lo<carry) + hi;
33901     buf = z[9];
33902     lo += buf;
33903     carry += (lo<buf);
33904     z[9] = lo;
33905     mpfq_umul_ppmm(hi,lo,c,x[10]);
33906     lo += carry;
33907     carry = (lo<carry) + hi;
33908     buf = z[10];
33909     lo += buf;
33910     carry += (lo<buf);
33911     z[10] = lo;
33912     mpfq_umul_ppmm(hi,lo,c,x[11]);
33913     lo += carry;
33914     carry = (lo<carry) + hi;
33915     buf = z[11];
33916     lo += buf;
33917     carry += (lo<buf);
33918     z[11] = lo;
33919     mpfq_umul_ppmm(hi,lo,c,x[12]);
33920     lo += carry;
33921     carry = (lo<carry) + hi;
33922     buf = z[12];
33923     lo += buf;
33924     carry += (lo<buf);
33925     z[12] = lo;
33926     mpfq_umul_ppmm(hi,lo,c,x[13]);
33927     lo += carry;
33928     carry = (lo<carry) + hi;
33929     buf = z[13];
33930     lo += buf;
33931     carry += (lo<buf);
33932     z[13] = lo;
33933     z[14] += carry;
33934     return (z[14]<carry);
33935 }
33936 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_addmul1) */
33937 
33938 #if !defined(HAVE_native_mpfq_fixmp_13_5_addmul1_nc)
33939 /* x has 13.5 words, z has 15.
33940  * Put (z+x*c) in z. Carry bit is lost. */
33941 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
33942 /* Triggered by: 13_5_mul, 13_5_mgy_decode */
33943 static inline
mpfq_fixmp_13_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)33944 void mpfq_fixmp_13_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
33945 {
33946     mp_limb_t hi, lo, carry, buf;
33947     carry = 0;
33948     mpfq_umul_ppmm(hi,lo,c,x[0]);
33949     lo += carry;
33950     carry = (lo<carry) + hi;
33951     buf = z[0];
33952     lo += buf;
33953     carry += (lo<buf);
33954     z[0] = lo;
33955     mpfq_umul_ppmm(hi,lo,c,x[1]);
33956     lo += carry;
33957     carry = (lo<carry) + hi;
33958     buf = z[1];
33959     lo += buf;
33960     carry += (lo<buf);
33961     z[1] = lo;
33962     mpfq_umul_ppmm(hi,lo,c,x[2]);
33963     lo += carry;
33964     carry = (lo<carry) + hi;
33965     buf = z[2];
33966     lo += buf;
33967     carry += (lo<buf);
33968     z[2] = lo;
33969     mpfq_umul_ppmm(hi,lo,c,x[3]);
33970     lo += carry;
33971     carry = (lo<carry) + hi;
33972     buf = z[3];
33973     lo += buf;
33974     carry += (lo<buf);
33975     z[3] = lo;
33976     mpfq_umul_ppmm(hi,lo,c,x[4]);
33977     lo += carry;
33978     carry = (lo<carry) + hi;
33979     buf = z[4];
33980     lo += buf;
33981     carry += (lo<buf);
33982     z[4] = lo;
33983     mpfq_umul_ppmm(hi,lo,c,x[5]);
33984     lo += carry;
33985     carry = (lo<carry) + hi;
33986     buf = z[5];
33987     lo += buf;
33988     carry += (lo<buf);
33989     z[5] = lo;
33990     mpfq_umul_ppmm(hi,lo,c,x[6]);
33991     lo += carry;
33992     carry = (lo<carry) + hi;
33993     buf = z[6];
33994     lo += buf;
33995     carry += (lo<buf);
33996     z[6] = lo;
33997     mpfq_umul_ppmm(hi,lo,c,x[7]);
33998     lo += carry;
33999     carry = (lo<carry) + hi;
34000     buf = z[7];
34001     lo += buf;
34002     carry += (lo<buf);
34003     z[7] = lo;
34004     mpfq_umul_ppmm(hi,lo,c,x[8]);
34005     lo += carry;
34006     carry = (lo<carry) + hi;
34007     buf = z[8];
34008     lo += buf;
34009     carry += (lo<buf);
34010     z[8] = lo;
34011     mpfq_umul_ppmm(hi,lo,c,x[9]);
34012     lo += carry;
34013     carry = (lo<carry) + hi;
34014     buf = z[9];
34015     lo += buf;
34016     carry += (lo<buf);
34017     z[9] = lo;
34018     mpfq_umul_ppmm(hi,lo,c,x[10]);
34019     lo += carry;
34020     carry = (lo<carry) + hi;
34021     buf = z[10];
34022     lo += buf;
34023     carry += (lo<buf);
34024     z[10] = lo;
34025     mpfq_umul_ppmm(hi,lo,c,x[11]);
34026     lo += carry;
34027     carry = (lo<carry) + hi;
34028     buf = z[11];
34029     lo += buf;
34030     carry += (lo<buf);
34031     z[11] = lo;
34032     mpfq_umul_ppmm(hi,lo,c,x[12]);
34033     lo += carry;
34034     carry = (lo<carry) + hi;
34035     buf = z[12];
34036     lo += buf;
34037     carry += (lo<buf);
34038     z[12] = lo;
34039     mpfq_umul_ppmm(hi,lo,c,x[13]);
34040     lo += carry;
34041     carry = (lo<carry) + hi;
34042     buf = z[13];
34043     lo += buf;
34044     carry += (lo<buf);
34045     z[13] = lo;
34046     z[14] += carry;
34047 }
34048 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_addmul1_nc) */
34049 
34050 #if !defined(HAVE_native_mpfq_fixmp_13_5_addmul1_shortz)
34051 /* x has 13.5 words, z has 14.
34052  * Put (z+x*c) in z. Return carry word. */
34053 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
34054 /* Triggered by: 13_5_redc, 13_5_redc_ur */
34055 static inline
mpfq_fixmp_13_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)34056 mp_limb_t mpfq_fixmp_13_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
34057 {
34058     mp_limb_t hi, lo, carry, buf;
34059     carry = 0;
34060     mpfq_umul_ppmm(hi,lo,c,x[0]);
34061     lo += carry;
34062     carry = (lo<carry) + hi;
34063     buf = z[0];
34064     lo += buf;
34065     carry += (lo<buf);
34066     z[0] = lo;
34067     mpfq_umul_ppmm(hi,lo,c,x[1]);
34068     lo += carry;
34069     carry = (lo<carry) + hi;
34070     buf = z[1];
34071     lo += buf;
34072     carry += (lo<buf);
34073     z[1] = lo;
34074     mpfq_umul_ppmm(hi,lo,c,x[2]);
34075     lo += carry;
34076     carry = (lo<carry) + hi;
34077     buf = z[2];
34078     lo += buf;
34079     carry += (lo<buf);
34080     z[2] = lo;
34081     mpfq_umul_ppmm(hi,lo,c,x[3]);
34082     lo += carry;
34083     carry = (lo<carry) + hi;
34084     buf = z[3];
34085     lo += buf;
34086     carry += (lo<buf);
34087     z[3] = lo;
34088     mpfq_umul_ppmm(hi,lo,c,x[4]);
34089     lo += carry;
34090     carry = (lo<carry) + hi;
34091     buf = z[4];
34092     lo += buf;
34093     carry += (lo<buf);
34094     z[4] = lo;
34095     mpfq_umul_ppmm(hi,lo,c,x[5]);
34096     lo += carry;
34097     carry = (lo<carry) + hi;
34098     buf = z[5];
34099     lo += buf;
34100     carry += (lo<buf);
34101     z[5] = lo;
34102     mpfq_umul_ppmm(hi,lo,c,x[6]);
34103     lo += carry;
34104     carry = (lo<carry) + hi;
34105     buf = z[6];
34106     lo += buf;
34107     carry += (lo<buf);
34108     z[6] = lo;
34109     mpfq_umul_ppmm(hi,lo,c,x[7]);
34110     lo += carry;
34111     carry = (lo<carry) + hi;
34112     buf = z[7];
34113     lo += buf;
34114     carry += (lo<buf);
34115     z[7] = lo;
34116     mpfq_umul_ppmm(hi,lo,c,x[8]);
34117     lo += carry;
34118     carry = (lo<carry) + hi;
34119     buf = z[8];
34120     lo += buf;
34121     carry += (lo<buf);
34122     z[8] = lo;
34123     mpfq_umul_ppmm(hi,lo,c,x[9]);
34124     lo += carry;
34125     carry = (lo<carry) + hi;
34126     buf = z[9];
34127     lo += buf;
34128     carry += (lo<buf);
34129     z[9] = lo;
34130     mpfq_umul_ppmm(hi,lo,c,x[10]);
34131     lo += carry;
34132     carry = (lo<carry) + hi;
34133     buf = z[10];
34134     lo += buf;
34135     carry += (lo<buf);
34136     z[10] = lo;
34137     mpfq_umul_ppmm(hi,lo,c,x[11]);
34138     lo += carry;
34139     carry = (lo<carry) + hi;
34140     buf = z[11];
34141     lo += buf;
34142     carry += (lo<buf);
34143     z[11] = lo;
34144     mpfq_umul_ppmm(hi,lo,c,x[12]);
34145     lo += carry;
34146     carry = (lo<carry) + hi;
34147     buf = z[12];
34148     lo += buf;
34149     carry += (lo<buf);
34150     z[12] = lo;
34151     mpfq_umul_ppmm(hi,lo,c,x[13]);
34152     lo += carry;
34153     carry = (lo<carry) + hi;
34154     buf = z[13];
34155     lo += buf;
34156     carry += (lo<buf);
34157     z[13] = lo;
34158     return carry;
34159 }
34160 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_addmul1_shortz) */
34161 
34162 #if !defined(HAVE_native_mpfq_fixmp_13_5_addmul05_nc)
34163 /* x has 13.5 words, z has 14. c is 0.5 word.
34164  * Put (z+x*c) in z. Carry bit is lost. */
34165 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
34166 /* Triggered by: 13_5_mul, 13_5_mgy_decode */
34167 static inline
mpfq_fixmp_13_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)34168 void mpfq_fixmp_13_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
34169 {
34170     mp_limb_t hi, lo, carry, buf;
34171     carry = 0;
34172     mpfq_umul_ppmm(hi,lo,c,x[0]);
34173     lo += carry;
34174     carry = (lo<carry) + hi;
34175     buf = z[0];
34176     lo += buf;
34177     carry += (lo<buf);
34178     z[0] = lo;
34179     mpfq_umul_ppmm(hi,lo,c,x[1]);
34180     lo += carry;
34181     carry = (lo<carry) + hi;
34182     buf = z[1];
34183     lo += buf;
34184     carry += (lo<buf);
34185     z[1] = lo;
34186     mpfq_umul_ppmm(hi,lo,c,x[2]);
34187     lo += carry;
34188     carry = (lo<carry) + hi;
34189     buf = z[2];
34190     lo += buf;
34191     carry += (lo<buf);
34192     z[2] = lo;
34193     mpfq_umul_ppmm(hi,lo,c,x[3]);
34194     lo += carry;
34195     carry = (lo<carry) + hi;
34196     buf = z[3];
34197     lo += buf;
34198     carry += (lo<buf);
34199     z[3] = lo;
34200     mpfq_umul_ppmm(hi,lo,c,x[4]);
34201     lo += carry;
34202     carry = (lo<carry) + hi;
34203     buf = z[4];
34204     lo += buf;
34205     carry += (lo<buf);
34206     z[4] = lo;
34207     mpfq_umul_ppmm(hi,lo,c,x[5]);
34208     lo += carry;
34209     carry = (lo<carry) + hi;
34210     buf = z[5];
34211     lo += buf;
34212     carry += (lo<buf);
34213     z[5] = lo;
34214     mpfq_umul_ppmm(hi,lo,c,x[6]);
34215     lo += carry;
34216     carry = (lo<carry) + hi;
34217     buf = z[6];
34218     lo += buf;
34219     carry += (lo<buf);
34220     z[6] = lo;
34221     mpfq_umul_ppmm(hi,lo,c,x[7]);
34222     lo += carry;
34223     carry = (lo<carry) + hi;
34224     buf = z[7];
34225     lo += buf;
34226     carry += (lo<buf);
34227     z[7] = lo;
34228     mpfq_umul_ppmm(hi,lo,c,x[8]);
34229     lo += carry;
34230     carry = (lo<carry) + hi;
34231     buf = z[8];
34232     lo += buf;
34233     carry += (lo<buf);
34234     z[8] = lo;
34235     mpfq_umul_ppmm(hi,lo,c,x[9]);
34236     lo += carry;
34237     carry = (lo<carry) + hi;
34238     buf = z[9];
34239     lo += buf;
34240     carry += (lo<buf);
34241     z[9] = lo;
34242     mpfq_umul_ppmm(hi,lo,c,x[10]);
34243     lo += carry;
34244     carry = (lo<carry) + hi;
34245     buf = z[10];
34246     lo += buf;
34247     carry += (lo<buf);
34248     z[10] = lo;
34249     mpfq_umul_ppmm(hi,lo,c,x[11]);
34250     lo += carry;
34251     carry = (lo<carry) + hi;
34252     buf = z[11];
34253     lo += buf;
34254     carry += (lo<buf);
34255     z[11] = lo;
34256     mpfq_umul_ppmm(hi,lo,c,x[12]);
34257     lo += carry;
34258     carry = (lo<carry) + hi;
34259     buf = z[12];
34260     lo += buf;
34261     carry += (lo<buf);
34262     z[12] = lo;
34263     lo = c*x[13] + carry;
34264     assert(lo >= carry);
34265     z[13] += lo;
34266 }
34267 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_addmul05_nc) */
34268 
34269 #if !defined(HAVE_native_mpfq_fixmp_13_5_mul)
34270 /* x and y have 13.5 words, z has 27. Put x*y in z. */
34271 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
34272 /* Triggered by: 13_5_mgy_decode */
34273 static inline
mpfq_fixmp_13_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)34274 void mpfq_fixmp_13_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
34275 {
34276     assert(z != x && z != y);
34277     for (int i = 0; i < 27; z[i++] = 0) ;
34278     mpfq_fixmp_13_5_addmul1_nc (z + 0, x, y[0]);
34279     mpfq_fixmp_13_5_addmul1_nc (z + 1, x, y[1]);
34280     mpfq_fixmp_13_5_addmul1_nc (z + 2, x, y[2]);
34281     mpfq_fixmp_13_5_addmul1_nc (z + 3, x, y[3]);
34282     mpfq_fixmp_13_5_addmul1_nc (z + 4, x, y[4]);
34283     mpfq_fixmp_13_5_addmul1_nc (z + 5, x, y[5]);
34284     mpfq_fixmp_13_5_addmul1_nc (z + 6, x, y[6]);
34285     mpfq_fixmp_13_5_addmul1_nc (z + 7, x, y[7]);
34286     mpfq_fixmp_13_5_addmul1_nc (z + 8, x, y[8]);
34287     mpfq_fixmp_13_5_addmul1_nc (z + 9, x, y[9]);
34288     mpfq_fixmp_13_5_addmul1_nc (z + 10, x, y[10]);
34289     mpfq_fixmp_13_5_addmul1_nc (z + 11, x, y[11]);
34290     mpfq_fixmp_13_5_addmul1_nc (z + 12, x, y[12]);
34291     mpfq_fixmp_13_5_addmul05_nc (z + 13, x, y[13]);
34292 }
34293 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mul) */
34294 
34295 #if !defined(HAVE_native_mpfq_fixmp_13_5_sqr)
34296 /* x has 13.5 words, z has 27. Put x*y in z. */
34297 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
34298 static inline
mpfq_fixmp_13_5_sqr(mp_limb_t * z,const mp_limb_t * x)34299 void mpfq_fixmp_13_5_sqr(mp_limb_t * z, const mp_limb_t * x)
34300 {
34301     mp_limb_t buf[27] = {0,};
34302     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
34303     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
34304     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
34305     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
34306     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
34307     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
34308     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
34309     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
34310     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
34311     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
34312     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
34313     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
34314     mpfq_fixmp_13_addmul1_nc(buf + 13, x, x[13]);
34315     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
34316     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
34317     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
34318     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
34319     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
34320     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
34321     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
34322     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
34323     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
34324     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
34325     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
34326     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
34327     mpfq_umul_ppmm(z[2*12+1], z[2*12], x[12], x[12]);
34328     z[2*13] = x[13] * x[13];
34329     mpn_lshift(buf, buf, 27, 1);
34330     mpn_add_n(z, z, buf, 27);
34331 }
34332 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_sqr) */
34333 
34334 #if !defined(HAVE_native_mpfq_fixmp_13_5_mul1)
34335 /* x has 13.5 words, z has 15. Put x*y in z. */
34336 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
34337 static inline
mpfq_fixmp_13_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)34338 void mpfq_fixmp_13_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
34339 {
34340     mp_limb_t hi, lo, carry;
34341     carry = 0;
34342     mpfq_umul_ppmm(hi,lo,c,x[0]);
34343     lo += carry;
34344     carry = (lo<carry) + hi;
34345     z[0] = lo;
34346     mpfq_umul_ppmm(hi,lo,c,x[1]);
34347     lo += carry;
34348     carry = (lo<carry) + hi;
34349     z[1] = lo;
34350     mpfq_umul_ppmm(hi,lo,c,x[2]);
34351     lo += carry;
34352     carry = (lo<carry) + hi;
34353     z[2] = lo;
34354     mpfq_umul_ppmm(hi,lo,c,x[3]);
34355     lo += carry;
34356     carry = (lo<carry) + hi;
34357     z[3] = lo;
34358     mpfq_umul_ppmm(hi,lo,c,x[4]);
34359     lo += carry;
34360     carry = (lo<carry) + hi;
34361     z[4] = lo;
34362     mpfq_umul_ppmm(hi,lo,c,x[5]);
34363     lo += carry;
34364     carry = (lo<carry) + hi;
34365     z[5] = lo;
34366     mpfq_umul_ppmm(hi,lo,c,x[6]);
34367     lo += carry;
34368     carry = (lo<carry) + hi;
34369     z[6] = lo;
34370     mpfq_umul_ppmm(hi,lo,c,x[7]);
34371     lo += carry;
34372     carry = (lo<carry) + hi;
34373     z[7] = lo;
34374     mpfq_umul_ppmm(hi,lo,c,x[8]);
34375     lo += carry;
34376     carry = (lo<carry) + hi;
34377     z[8] = lo;
34378     mpfq_umul_ppmm(hi,lo,c,x[9]);
34379     lo += carry;
34380     carry = (lo<carry) + hi;
34381     z[9] = lo;
34382     mpfq_umul_ppmm(hi,lo,c,x[10]);
34383     lo += carry;
34384     carry = (lo<carry) + hi;
34385     z[10] = lo;
34386     mpfq_umul_ppmm(hi,lo,c,x[11]);
34387     lo += carry;
34388     carry = (lo<carry) + hi;
34389     z[11] = lo;
34390     mpfq_umul_ppmm(hi,lo,c,x[12]);
34391     lo += carry;
34392     carry = (lo<carry) + hi;
34393     z[12] = lo;
34394     mpfq_umul_ppmm(hi,lo,c,x[13]);
34395     lo += carry;
34396     carry = (lo<carry) + hi;
34397     z[13] = lo;
34398     z[14] = carry;
34399 }
34400 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mul1) */
34401 
34402 #if !defined(HAVE_native_mpfq_fixmp_13_5_shortmul)
34403 /* x and y have 13.5 words, z has 14.
34404  * Put the low 14 words of x*y in z. */
34405 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
34406 static inline
mpfq_fixmp_13_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)34407 void mpfq_fixmp_13_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
34408 {
34409     mpfq_zero(z, 14);
34410     mpfq_fixmp_13_addmul1_nc (z+0, x, y[0]);
34411     z[14-1] += x[13]*y[0];
34412     mpfq_fixmp_12_addmul1_nc (z+1, x, y[1]);
34413     z[14-1] += x[12]*y[1];
34414     mpfq_fixmp_11_addmul1_nc (z+2, x, y[2]);
34415     z[14-1] += x[11]*y[2];
34416     mpfq_fixmp_10_addmul1_nc (z+3, x, y[3]);
34417     z[14-1] += x[10]*y[3];
34418     mpfq_fixmp_9_addmul1_nc (z+4, x, y[4]);
34419     z[14-1] += x[9]*y[4];
34420     mpfq_fixmp_8_addmul1_nc (z+5, x, y[5]);
34421     z[14-1] += x[8]*y[5];
34422     mpfq_fixmp_7_addmul1_nc (z+6, x, y[6]);
34423     z[14-1] += x[7]*y[6];
34424     mpfq_fixmp_6_addmul1_nc (z+7, x, y[7]);
34425     z[14-1] += x[6]*y[7];
34426     mpfq_fixmp_5_addmul1_nc (z+8, x, y[8]);
34427     z[14-1] += x[5]*y[8];
34428     mpfq_fixmp_4_addmul1_nc (z+9, x, y[9]);
34429     z[14-1] += x[4]*y[9];
34430     mpfq_fixmp_3_addmul1_nc (z+10, x, y[10]);
34431     z[14-1] += x[3]*y[10];
34432     mpfq_fixmp_2_addmul1_nc (z+11, x, y[11]);
34433     z[14-1] += x[2]*y[11];
34434     mpfq_fixmp_1_addmul1_nc (z+12, x, y[12]);
34435     z[14-1] += x[1]*y[12];
34436     z[14-1] += x[0]*y[14-1];
34437 }
34438 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_shortmul) */
34439 
34440 #if !defined(HAVE_native_mpfq_fixmp_13_5_addmul05)
34441 /* x has 13.5 words, z has 14. c is 0.5 word.
34442  * Put (z+x*c) in z. Return carry bit. */
34443 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
34444 static inline
mpfq_fixmp_13_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)34445 mp_limb_t mpfq_fixmp_13_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
34446 {
34447     mp_limb_t hi, lo, carry, buf;
34448     carry = 0;
34449     mpfq_umul_ppmm(hi,lo,c,x[0]);
34450     lo += carry;
34451     carry = (lo<carry) + hi;
34452     buf = z[0];
34453     lo += buf;
34454     carry += (lo<buf);
34455     z[0] = lo;
34456     mpfq_umul_ppmm(hi,lo,c,x[1]);
34457     lo += carry;
34458     carry = (lo<carry) + hi;
34459     buf = z[1];
34460     lo += buf;
34461     carry += (lo<buf);
34462     z[1] = lo;
34463     mpfq_umul_ppmm(hi,lo,c,x[2]);
34464     lo += carry;
34465     carry = (lo<carry) + hi;
34466     buf = z[2];
34467     lo += buf;
34468     carry += (lo<buf);
34469     z[2] = lo;
34470     mpfq_umul_ppmm(hi,lo,c,x[3]);
34471     lo += carry;
34472     carry = (lo<carry) + hi;
34473     buf = z[3];
34474     lo += buf;
34475     carry += (lo<buf);
34476     z[3] = lo;
34477     mpfq_umul_ppmm(hi,lo,c,x[4]);
34478     lo += carry;
34479     carry = (lo<carry) + hi;
34480     buf = z[4];
34481     lo += buf;
34482     carry += (lo<buf);
34483     z[4] = lo;
34484     mpfq_umul_ppmm(hi,lo,c,x[5]);
34485     lo += carry;
34486     carry = (lo<carry) + hi;
34487     buf = z[5];
34488     lo += buf;
34489     carry += (lo<buf);
34490     z[5] = lo;
34491     mpfq_umul_ppmm(hi,lo,c,x[6]);
34492     lo += carry;
34493     carry = (lo<carry) + hi;
34494     buf = z[6];
34495     lo += buf;
34496     carry += (lo<buf);
34497     z[6] = lo;
34498     mpfq_umul_ppmm(hi,lo,c,x[7]);
34499     lo += carry;
34500     carry = (lo<carry) + hi;
34501     buf = z[7];
34502     lo += buf;
34503     carry += (lo<buf);
34504     z[7] = lo;
34505     mpfq_umul_ppmm(hi,lo,c,x[8]);
34506     lo += carry;
34507     carry = (lo<carry) + hi;
34508     buf = z[8];
34509     lo += buf;
34510     carry += (lo<buf);
34511     z[8] = lo;
34512     mpfq_umul_ppmm(hi,lo,c,x[9]);
34513     lo += carry;
34514     carry = (lo<carry) + hi;
34515     buf = z[9];
34516     lo += buf;
34517     carry += (lo<buf);
34518     z[9] = lo;
34519     mpfq_umul_ppmm(hi,lo,c,x[10]);
34520     lo += carry;
34521     carry = (lo<carry) + hi;
34522     buf = z[10];
34523     lo += buf;
34524     carry += (lo<buf);
34525     z[10] = lo;
34526     mpfq_umul_ppmm(hi,lo,c,x[11]);
34527     lo += carry;
34528     carry = (lo<carry) + hi;
34529     buf = z[11];
34530     lo += buf;
34531     carry += (lo<buf);
34532     z[11] = lo;
34533     mpfq_umul_ppmm(hi,lo,c,x[12]);
34534     lo += carry;
34535     carry = (lo<carry) + hi;
34536     buf = z[12];
34537     lo += buf;
34538     carry += (lo<buf);
34539     z[12] = lo;
34540     lo = c*x[13] + carry;
34541     assert(lo >= carry);
34542     z[13] += lo;
34543     return z[13] < lo;
34544 }
34545 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_addmul05) */
34546 
34547 #if !defined(HAVE_native_mpfq_fixmp_13_5_mul05)
34548 /* x has 13.5 words, z has 14. c is 0.5 word.
34549  * Put (x*c) in z. No carry. */
34550 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
34551 static inline
mpfq_fixmp_13_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)34552 void mpfq_fixmp_13_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
34553 {
34554     mp_limb_t hi, lo, carry;
34555     carry = 0;
34556     mpfq_umul_ppmm(hi,lo,c,x[0]);
34557     lo += carry;
34558     carry = (lo<carry) + hi;
34559     z[0] = lo;
34560     mpfq_umul_ppmm(hi,lo,c,x[1]);
34561     lo += carry;
34562     carry = (lo<carry) + hi;
34563     z[1] = lo;
34564     mpfq_umul_ppmm(hi,lo,c,x[2]);
34565     lo += carry;
34566     carry = (lo<carry) + hi;
34567     z[2] = lo;
34568     mpfq_umul_ppmm(hi,lo,c,x[3]);
34569     lo += carry;
34570     carry = (lo<carry) + hi;
34571     z[3] = lo;
34572     mpfq_umul_ppmm(hi,lo,c,x[4]);
34573     lo += carry;
34574     carry = (lo<carry) + hi;
34575     z[4] = lo;
34576     mpfq_umul_ppmm(hi,lo,c,x[5]);
34577     lo += carry;
34578     carry = (lo<carry) + hi;
34579     z[5] = lo;
34580     mpfq_umul_ppmm(hi,lo,c,x[6]);
34581     lo += carry;
34582     carry = (lo<carry) + hi;
34583     z[6] = lo;
34584     mpfq_umul_ppmm(hi,lo,c,x[7]);
34585     lo += carry;
34586     carry = (lo<carry) + hi;
34587     z[7] = lo;
34588     mpfq_umul_ppmm(hi,lo,c,x[8]);
34589     lo += carry;
34590     carry = (lo<carry) + hi;
34591     z[8] = lo;
34592     mpfq_umul_ppmm(hi,lo,c,x[9]);
34593     lo += carry;
34594     carry = (lo<carry) + hi;
34595     z[9] = lo;
34596     mpfq_umul_ppmm(hi,lo,c,x[10]);
34597     lo += carry;
34598     carry = (lo<carry) + hi;
34599     z[10] = lo;
34600     mpfq_umul_ppmm(hi,lo,c,x[11]);
34601     lo += carry;
34602     carry = (lo<carry) + hi;
34603     z[11] = lo;
34604     mpfq_umul_ppmm(hi,lo,c,x[12]);
34605     lo += carry;
34606     carry = (lo<carry) + hi;
34607     z[12] = lo;
34608     lo = c*x[13] + carry;
34609     assert(lo >= carry);
34610     z[13] = lo;
34611 }
34612 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mul05) */
34613 
34614 #if !defined(HAVE_native_mpfq_fixmp_13_5_mod)
34615 /* x has 27 words. z and p have 13.5 words, and the high word of p is non-zero.
34616  * Put x mod p in z. */
34617 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
34618 /* Triggered by: 13_5_mgy_decode */
34619 static inline
mpfq_fixmp_13_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)34620 void mpfq_fixmp_13_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
34621 {
34622     mp_limb_t q[13+1], r[14];
34623     assert (p[14-1] != 0);
34624     mpn_tdiv_qr(q, r, 0, x, 27, p, 14);
34625     mpfq_copy(z, r, 14);
34626 }
34627 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mod) */
34628 
34629 #if !defined(HAVE_native_mpfq_fixmp_13_5_rshift)
34630 /* a has 13.5 words. Shift it in place by cnt bits to the right.
34631  * The shift count cnt must not exceed the word size.
34632  * Note that no carry is returned for the bits shifted out. */
34633 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
34634 /* Triggered by: 13_5_invmod */
34635 static inline
mpfq_fixmp_13_5_rshift(mp_limb_t * a,int cnt)34636 void mpfq_fixmp_13_5_rshift(mp_limb_t * a, int cnt)
34637 {
34638     if (!cnt) return;
34639     int i;
34640     int dnt = GMP_NUMB_BITS - cnt;
34641     for (i = 0; i < 14-1; ++i) {
34642         a[i] >>= cnt;
34643         a[i] |= (a[i+1] << dnt);
34644     }
34645     a[14-1] >>= cnt;
34646 }
34647 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_rshift) */
34648 
34649 #if !defined(HAVE_native_mpfq_fixmp_13_5_long_rshift)
34650 /* a has 13.5 words. Shift it in place by off words plus cnt bits to the left.
34651  * Note that no carry is returned for the bits shifted out. */
34652 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
34653 /* Triggered by: 13_5_invmod */
34654 static inline
mpfq_fixmp_13_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)34655 void mpfq_fixmp_13_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
34656 {
34657     if (cnt) {
34658         int dnt = GMP_NUMB_BITS - cnt;
34659         for (int i = 0; i < 14 - off - 1; ++i) {
34660             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
34661         }
34662         a[14-off-1] = a[14-1]>>cnt;
34663     } else {
34664         mpfq_copyi(a, a + off, 14 - off);
34665     }
34666     mpfq_zero(a + 14 - off, off);
34667 }
34668 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_long_rshift) */
34669 
34670 #if !defined(HAVE_native_mpfq_fixmp_13_5_long_lshift)
34671 /* a has 13.5 words. Shift it in place by off words plus cnt bits to the left.
34672  * Note that no carry is returned for the bits shifted out. */
34673 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
34674 /* Triggered by: 13_5_invmod */
34675 static inline
mpfq_fixmp_13_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)34676 void mpfq_fixmp_13_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
34677 {
34678     int i;
34679     if (cnt) {
34680         int dnt = GMP_NUMB_BITS - cnt;
34681         for (i = 14-1; i>off; --i) {
34682             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
34683         }
34684         a[off] = a[0]<<cnt;
34685     } else {
34686         mpfq_copyd(a + off, a, 14 - off);
34687     }
34688     mpfq_zero(a, off);
34689 }
34690 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_long_lshift) */
34691 
34692 #if !defined(HAVE_native_mpfq_fixmp_13_5_invmod)
34693 /* x, z, and p have 13.5 words. Put inverse of x mod p in z.
34694  * Return non-zero if an inverse could be found.
34695  * If no inverse could be found, return 0 and set z to zero.
34696  */
34697 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
34698 static inline
mpfq_fixmp_13_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)34699 int mpfq_fixmp_13_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
34700 {
34701       mp_limb_t u[14], v[14], a[14], b[14], fix[14];
34702       int i, t, lsh;
34703 
34704       mpfq_zero(u, 14);
34705       mpfq_zero(v, 14);
34706       mpfq_copy(a, x, 14);
34707       mpfq_copy(b, p, 14);
34708       u[0] = 1UL;
34709 
34710       if (mpfq_fixmp_13_5_cmp(a, v) == 0 || mpfq_fixmp_13_5_cmp(a, b) == 0) {
34711         mpfq_zero(res, 14);
34712         return 0;
34713       }
34714 
34715       mpfq_fixmp_13_5_add(fix, b, u);
34716       mpfq_fixmp_13_5_rshift(fix, 1);
34717 
34718       assert (mpfq_fixmp_13_5_cmp(a,b) < 0);
34719 
34720       t = 0;
34721 
34722       for(i = 0 ; !a[i] ; i++) ;
34723       assert (i < 14);
34724       lsh = mpfq_ctzl(a[i]);
34725       mpfq_fixmp_13_5_long_rshift(a, i, lsh);
34726       t += lsh + i*GMP_NUMB_BITS;
34727       mpfq_fixmp_13_5_long_lshift(v, i, lsh);
34728 
34729       do {
34730         do {
34731           mpfq_fixmp_13_5_sub(b, b, a);
34732           mpfq_fixmp_13_5_add(v, v, u);
34733           for(i = 0 ; !b[i] ; i++) ;
34734           assert (i < 14);
34735           lsh = mpfq_ctzl(b[i]);
34736           mpfq_fixmp_13_5_long_rshift(b, i, lsh);
34737           t += lsh + i*GMP_NUMB_BITS;
34738           mpfq_fixmp_13_5_long_lshift(u, i, lsh);
34739         } while (mpfq_fixmp_13_5_cmp(a,b) < 0);
34740         if (mpfq_fixmp_13_5_cmp(a, b) == 0)
34741           break;
34742         do {
34743           mpfq_fixmp_13_5_sub(a, a, b);
34744           mpfq_fixmp_13_5_add(u, u, v);
34745           for(i = 0 ; !a[i] ; i++) ;
34746           assert (i < 14);
34747           lsh = mpfq_ctzl(a[i]);
34748           mpfq_fixmp_13_5_long_rshift(a, i, lsh);
34749           t += lsh + i*GMP_NUMB_BITS;
34750           mpfq_fixmp_13_5_long_lshift(v, i, lsh);
34751         } while (mpfq_fixmp_13_5_cmp(b,a)<0);
34752       } while (mpfq_fixmp_13_5_cmp(a,b) != 0);
34753       {
34754         if (mpfq_fixmp_13_5_cmp_ui(a, 1) != 0) {
34755           mpfq_copy(res, a, 14);
34756           return 0;
34757         }
34758       }
34759       while (t>0) {
34760         mp_limb_t sig = u[0] & 1UL;
34761         mpfq_fixmp_13_5_rshift(u, 1);
34762         if (sig)
34763           mpfq_fixmp_13_5_add(u, u, fix);
34764         --t;
34765       }
34766       mpfq_copy(res, u, 14);
34767       return 1;
34768 }
34769 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_invmod) */
34770 
34771 #if !defined(HAVE_native_mpfq_fixmp_13_5_redc)
34772 /* x has 27 words, z and p have 13.5 words.
34773  * only one word is read from invp.
34774  * Assuming R=W^14 is the redc modulus, we expect that x verifies:
34775  *   x < R*p,
34776  * so that we have eventually z < p, z congruent to x/R mod p.
34777  * The contents of the area pointed by x are clobbered by this call.
34778  * Note also that x may alias z.
34779  */
34780 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
34781 static inline
mpfq_fixmp_13_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)34782 void mpfq_fixmp_13_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
34783 {
34784     mp_limb_t cy;
34785     for(int i = 0; i < 14; ++i) {
34786         mp_limb_t t = x[i]*mip[0];
34787         cy = mpfq_fixmp_13_5_addmul1_shortz(x+i, p, t);
34788         assert (x[i] == 0);
34789         x[i] = cy;
34790     }
34791     {
34792         mp_limb_t ret[14] = { x[14], x[15], x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], x[24], x[25], x[26], 0 };
34793         cy = mpfq_fixmp_13_5_add(x, x, ret);
34794     }
34795     /* At this point, we have (x' denotes x + cy*W^n here)
34796     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
34797     * x'/R < p + p
34798     */
34799     if (cy || mpfq_fixmp_13_5_cmp(x, p) >= 0) {
34800         mpfq_fixmp_13_5_sub(z, x, p);
34801     } else {
34802         mpfq_copy(z, x, 14);
34803     }
34804 }
34805 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_redc) */
34806 
34807 #if !defined(HAVE_native_mpfq_fixmp_13_5_redc_ur)
34808 /* x has 28 words, z and p have 13.5 words.
34809  * only one word is read from invp.
34810  * Assuming R=W^14 is the redc modulus, we expect that x verifies:
34811  *  x < W*W^13.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
34812  * so that we have eventually z < p, z congruent to x/R mod p.
34813  * The contents of the area pointed by x are clobbered by this call.
34814  * Note also that x may alias z.
34815  */
34816 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
34817 static inline
mpfq_fixmp_13_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)34818 void mpfq_fixmp_13_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
34819 {
34820     mp_limb_t cy, q[1];
34821     for(int i = 0; i < 14; ++i) {
34822         mp_limb_t t = x[i]*mip[0];
34823         cy = mpfq_fixmp_13_5_addmul1_shortz(x+i, p, t);
34824         assert (x[i] == 0);
34825         x[i] = cy;
34826     }
34827     cy = mpfq_fixmp_13_5_add(x + 14, x, x + 14);
34828     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
34829     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
34830     * x'/R < (W^0.5+1)*p
34831     */
34832     if (cy) {
34833         /* x'/R-p < W^0.5*p, which fits in n words. */
34834         mpfq_fixmp_13_5_sub(x + 14, x + 14, p);
34835     }
34836     mpn_tdiv_qr(q, z, 0, x + 14, 14, p, 14);
34837 }
34838 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_redc_ur) */
34839 
34840 #if !defined(HAVE_native_mpfq_fixmp_13_5_mgy_encode)
34841 /* x, z, and p have 13.5 words.
34842  * Assuming R=W^14 is the redc modulus, we compute z=R*x mod p. */
34843 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
34844 static inline
mpfq_fixmp_13_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)34845 void mpfq_fixmp_13_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
34846 {
34847     mp_limb_t t[28] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13] };
34848     mp_limb_t qq[14+1];
34849     mpn_tdiv_qr(qq, z, 0, t, 28, p, 14);
34850 }
34851 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mgy_encode) */
34852 
34853 #if !defined(HAVE_native_mpfq_fixmp_13_5_mgy_decode)
34854 /* x, z, invR, and p have 13.5 words.
34855  * Assuming R=W^14 is the redc modulus, we compute z=x/R mod p. */
34856 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
34857 static inline
mpfq_fixmp_13_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)34858 void mpfq_fixmp_13_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
34859 {
34860     mp_limb_t t[28];
34861     mpfq_fixmp_13_5_mul(t, x, invR);
34862     mpfq_fixmp_13_5_mod(z, t, p);
34863 }
34864 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_mgy_decode) */
34865 
34866 #if !defined(HAVE_native_mpfq_fixmp_13_5_lshift)
34867 /* a has 13.5 words. Shift it in place by cnt bits to the left.
34868  * The shift count cnt must not exceed the word size.
34869  * Note that no carry is returned for the bits shifted out. */
34870 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
34871 static inline
mpfq_fixmp_13_5_lshift(mp_limb_t * a,int cnt)34872 void mpfq_fixmp_13_5_lshift(mp_limb_t * a, int cnt)
34873 {
34874     if (!cnt) return;
34875     int i;
34876     int dnt = GMP_NUMB_BITS - cnt;
34877     for (i = 14-1; i>0; --i) {
34878         a[i] <<= cnt;
34879         a[i] |= (a[i-1] >> dnt);
34880     }
34881     a[0] <<= cnt;
34882 }
34883 #endif /* !defined(HAVE_native_mpfq_fixmp_13_5_lshift) */
34884 
34885 #if !defined(HAVE_native_mpfq_fixmp_14_5_add)
34886 /* x, y, and z have 14.5 words. Result in z. Return carry bit */
34887 /* *Mpfq::fixmp::longlong::code_for__fixmp_add */
34888 /* Triggered by: 14_5_invmod, 14_5_redc, 14_5_redc_ur */
34889 static inline
mpfq_fixmp_14_5_add(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)34890 mp_limb_t mpfq_fixmp_14_5_add(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
34891 {
34892     mp_limb_t r, s, t, cy, cy1, cy2;
34893     cy = 0;
34894     r = x[0];
34895     s = r + y[0];
34896     cy1 = s < r;
34897     t = s + cy;
34898     cy2 = t < s;
34899     cy = cy1 | cy2;
34900     z[0] = t;
34901     r = x[1];
34902     s = r + y[1];
34903     cy1 = s < r;
34904     t = s + cy;
34905     cy2 = t < s;
34906     cy = cy1 | cy2;
34907     z[1] = t;
34908     r = x[2];
34909     s = r + y[2];
34910     cy1 = s < r;
34911     t = s + cy;
34912     cy2 = t < s;
34913     cy = cy1 | cy2;
34914     z[2] = t;
34915     r = x[3];
34916     s = r + y[3];
34917     cy1 = s < r;
34918     t = s + cy;
34919     cy2 = t < s;
34920     cy = cy1 | cy2;
34921     z[3] = t;
34922     r = x[4];
34923     s = r + y[4];
34924     cy1 = s < r;
34925     t = s + cy;
34926     cy2 = t < s;
34927     cy = cy1 | cy2;
34928     z[4] = t;
34929     r = x[5];
34930     s = r + y[5];
34931     cy1 = s < r;
34932     t = s + cy;
34933     cy2 = t < s;
34934     cy = cy1 | cy2;
34935     z[5] = t;
34936     r = x[6];
34937     s = r + y[6];
34938     cy1 = s < r;
34939     t = s + cy;
34940     cy2 = t < s;
34941     cy = cy1 | cy2;
34942     z[6] = t;
34943     r = x[7];
34944     s = r + y[7];
34945     cy1 = s < r;
34946     t = s + cy;
34947     cy2 = t < s;
34948     cy = cy1 | cy2;
34949     z[7] = t;
34950     r = x[8];
34951     s = r + y[8];
34952     cy1 = s < r;
34953     t = s + cy;
34954     cy2 = t < s;
34955     cy = cy1 | cy2;
34956     z[8] = t;
34957     r = x[9];
34958     s = r + y[9];
34959     cy1 = s < r;
34960     t = s + cy;
34961     cy2 = t < s;
34962     cy = cy1 | cy2;
34963     z[9] = t;
34964     r = x[10];
34965     s = r + y[10];
34966     cy1 = s < r;
34967     t = s + cy;
34968     cy2 = t < s;
34969     cy = cy1 | cy2;
34970     z[10] = t;
34971     r = x[11];
34972     s = r + y[11];
34973     cy1 = s < r;
34974     t = s + cy;
34975     cy2 = t < s;
34976     cy = cy1 | cy2;
34977     z[11] = t;
34978     r = x[12];
34979     s = r + y[12];
34980     cy1 = s < r;
34981     t = s + cy;
34982     cy2 = t < s;
34983     cy = cy1 | cy2;
34984     z[12] = t;
34985     r = x[13];
34986     s = r + y[13];
34987     cy1 = s < r;
34988     t = s + cy;
34989     cy2 = t < s;
34990     cy = cy1 | cy2;
34991     z[13] = t;
34992     r = x[14];
34993     s = r + y[14];
34994     cy1 = s < r;
34995     t = s + cy;
34996     cy2 = t < s;
34997     cy = cy1 | cy2;
34998     z[14] = t;
34999     return cy;
35000 }
35001 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_add) */
35002 
35003 #if !defined(HAVE_native_mpfq_fixmp_14_5_sub)
35004 /* x, y, and z have 14.5 words. Result in z. Return borrow bit */
35005 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub */
35006 /* Triggered by: 14_5_invmod, 14_5_redc, 14_5_redc_ur */
35007 static inline
mpfq_fixmp_14_5_sub(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)35008 mp_limb_t mpfq_fixmp_14_5_sub(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
35009 {
35010     mp_limb_t r, s, t, cy, cy1, cy2;
35011     cy = 0;
35012     r = x[0];
35013     s = r - y[0];
35014     cy1 = s > r;
35015     t = s - cy;
35016     cy2 = t > s;
35017     cy = cy1 | cy2;
35018     z[0] = t;
35019     r = x[1];
35020     s = r - y[1];
35021     cy1 = s > r;
35022     t = s - cy;
35023     cy2 = t > s;
35024     cy = cy1 | cy2;
35025     z[1] = t;
35026     r = x[2];
35027     s = r - y[2];
35028     cy1 = s > r;
35029     t = s - cy;
35030     cy2 = t > s;
35031     cy = cy1 | cy2;
35032     z[2] = t;
35033     r = x[3];
35034     s = r - y[3];
35035     cy1 = s > r;
35036     t = s - cy;
35037     cy2 = t > s;
35038     cy = cy1 | cy2;
35039     z[3] = t;
35040     r = x[4];
35041     s = r - y[4];
35042     cy1 = s > r;
35043     t = s - cy;
35044     cy2 = t > s;
35045     cy = cy1 | cy2;
35046     z[4] = t;
35047     r = x[5];
35048     s = r - y[5];
35049     cy1 = s > r;
35050     t = s - cy;
35051     cy2 = t > s;
35052     cy = cy1 | cy2;
35053     z[5] = t;
35054     r = x[6];
35055     s = r - y[6];
35056     cy1 = s > r;
35057     t = s - cy;
35058     cy2 = t > s;
35059     cy = cy1 | cy2;
35060     z[6] = t;
35061     r = x[7];
35062     s = r - y[7];
35063     cy1 = s > r;
35064     t = s - cy;
35065     cy2 = t > s;
35066     cy = cy1 | cy2;
35067     z[7] = t;
35068     r = x[8];
35069     s = r - y[8];
35070     cy1 = s > r;
35071     t = s - cy;
35072     cy2 = t > s;
35073     cy = cy1 | cy2;
35074     z[8] = t;
35075     r = x[9];
35076     s = r - y[9];
35077     cy1 = s > r;
35078     t = s - cy;
35079     cy2 = t > s;
35080     cy = cy1 | cy2;
35081     z[9] = t;
35082     r = x[10];
35083     s = r - y[10];
35084     cy1 = s > r;
35085     t = s - cy;
35086     cy2 = t > s;
35087     cy = cy1 | cy2;
35088     z[10] = t;
35089     r = x[11];
35090     s = r - y[11];
35091     cy1 = s > r;
35092     t = s - cy;
35093     cy2 = t > s;
35094     cy = cy1 | cy2;
35095     z[11] = t;
35096     r = x[12];
35097     s = r - y[12];
35098     cy1 = s > r;
35099     t = s - cy;
35100     cy2 = t > s;
35101     cy = cy1 | cy2;
35102     z[12] = t;
35103     r = x[13];
35104     s = r - y[13];
35105     cy1 = s > r;
35106     t = s - cy;
35107     cy2 = t > s;
35108     cy = cy1 | cy2;
35109     z[13] = t;
35110     r = x[14];
35111     s = r - y[14];
35112     cy1 = s > r;
35113     t = s - cy;
35114     cy2 = t > s;
35115     cy = cy1 | cy2;
35116     z[14] = t;
35117     return cy;
35118 }
35119 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_sub) */
35120 
35121 #if !defined(HAVE_native_mpfq_fixmp_14_5_add_nc)
35122 /* x, y, and z have 14.5 words. Result in z. Carry bit is lost. */
35123 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_nc */
35124 static inline
mpfq_fixmp_14_5_add_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)35125 void mpfq_fixmp_14_5_add_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
35126 {
35127     mp_limb_t r, s, t, cy, cy1, cy2;
35128     cy = 0;
35129     r = x[0];
35130     s = r + y[0];
35131     cy1 = s < r;
35132     t = s + cy;
35133     cy2 = t < s;
35134     cy = cy1 | cy2;
35135     z[0] = t;
35136     r = x[1];
35137     s = r + y[1];
35138     cy1 = s < r;
35139     t = s + cy;
35140     cy2 = t < s;
35141     cy = cy1 | cy2;
35142     z[1] = t;
35143     r = x[2];
35144     s = r + y[2];
35145     cy1 = s < r;
35146     t = s + cy;
35147     cy2 = t < s;
35148     cy = cy1 | cy2;
35149     z[2] = t;
35150     r = x[3];
35151     s = r + y[3];
35152     cy1 = s < r;
35153     t = s + cy;
35154     cy2 = t < s;
35155     cy = cy1 | cy2;
35156     z[3] = t;
35157     r = x[4];
35158     s = r + y[4];
35159     cy1 = s < r;
35160     t = s + cy;
35161     cy2 = t < s;
35162     cy = cy1 | cy2;
35163     z[4] = t;
35164     r = x[5];
35165     s = r + y[5];
35166     cy1 = s < r;
35167     t = s + cy;
35168     cy2 = t < s;
35169     cy = cy1 | cy2;
35170     z[5] = t;
35171     r = x[6];
35172     s = r + y[6];
35173     cy1 = s < r;
35174     t = s + cy;
35175     cy2 = t < s;
35176     cy = cy1 | cy2;
35177     z[6] = t;
35178     r = x[7];
35179     s = r + y[7];
35180     cy1 = s < r;
35181     t = s + cy;
35182     cy2 = t < s;
35183     cy = cy1 | cy2;
35184     z[7] = t;
35185     r = x[8];
35186     s = r + y[8];
35187     cy1 = s < r;
35188     t = s + cy;
35189     cy2 = t < s;
35190     cy = cy1 | cy2;
35191     z[8] = t;
35192     r = x[9];
35193     s = r + y[9];
35194     cy1 = s < r;
35195     t = s + cy;
35196     cy2 = t < s;
35197     cy = cy1 | cy2;
35198     z[9] = t;
35199     r = x[10];
35200     s = r + y[10];
35201     cy1 = s < r;
35202     t = s + cy;
35203     cy2 = t < s;
35204     cy = cy1 | cy2;
35205     z[10] = t;
35206     r = x[11];
35207     s = r + y[11];
35208     cy1 = s < r;
35209     t = s + cy;
35210     cy2 = t < s;
35211     cy = cy1 | cy2;
35212     z[11] = t;
35213     r = x[12];
35214     s = r + y[12];
35215     cy1 = s < r;
35216     t = s + cy;
35217     cy2 = t < s;
35218     cy = cy1 | cy2;
35219     z[12] = t;
35220     r = x[13];
35221     s = r + y[13];
35222     cy1 = s < r;
35223     t = s + cy;
35224     cy2 = t < s;
35225     cy = cy1 | cy2;
35226     z[13] = t;
35227     r = x[14];
35228     s = r + y[14];
35229     cy1 = s < r;
35230     t = s + cy;
35231     cy2 = t < s;
35232     cy = cy1 | cy2;
35233     z[14] = t;
35234 }
35235 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_add_nc) */
35236 
35237 #if !defined(HAVE_native_mpfq_fixmp_14_5_sub_nc)
35238 /* x, y, and z have 14.5 words. Result in z. Borrow bit is lost. */
35239 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_nc */
35240 static inline
mpfq_fixmp_14_5_sub_nc(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)35241 void mpfq_fixmp_14_5_sub_nc(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
35242 {
35243     mp_limb_t r, s, t, cy, cy1, cy2;
35244     cy = 0;
35245     r = x[0];
35246     s = r - y[0];
35247     cy1 = s > r;
35248     t = s - cy;
35249     cy2 = t > s;
35250     cy = cy1 | cy2;
35251     z[0] = t;
35252     r = x[1];
35253     s = r - y[1];
35254     cy1 = s > r;
35255     t = s - cy;
35256     cy2 = t > s;
35257     cy = cy1 | cy2;
35258     z[1] = t;
35259     r = x[2];
35260     s = r - y[2];
35261     cy1 = s > r;
35262     t = s - cy;
35263     cy2 = t > s;
35264     cy = cy1 | cy2;
35265     z[2] = t;
35266     r = x[3];
35267     s = r - y[3];
35268     cy1 = s > r;
35269     t = s - cy;
35270     cy2 = t > s;
35271     cy = cy1 | cy2;
35272     z[3] = t;
35273     r = x[4];
35274     s = r - y[4];
35275     cy1 = s > r;
35276     t = s - cy;
35277     cy2 = t > s;
35278     cy = cy1 | cy2;
35279     z[4] = t;
35280     r = x[5];
35281     s = r - y[5];
35282     cy1 = s > r;
35283     t = s - cy;
35284     cy2 = t > s;
35285     cy = cy1 | cy2;
35286     z[5] = t;
35287     r = x[6];
35288     s = r - y[6];
35289     cy1 = s > r;
35290     t = s - cy;
35291     cy2 = t > s;
35292     cy = cy1 | cy2;
35293     z[6] = t;
35294     r = x[7];
35295     s = r - y[7];
35296     cy1 = s > r;
35297     t = s - cy;
35298     cy2 = t > s;
35299     cy = cy1 | cy2;
35300     z[7] = t;
35301     r = x[8];
35302     s = r - y[8];
35303     cy1 = s > r;
35304     t = s - cy;
35305     cy2 = t > s;
35306     cy = cy1 | cy2;
35307     z[8] = t;
35308     r = x[9];
35309     s = r - y[9];
35310     cy1 = s > r;
35311     t = s - cy;
35312     cy2 = t > s;
35313     cy = cy1 | cy2;
35314     z[9] = t;
35315     r = x[10];
35316     s = r - y[10];
35317     cy1 = s > r;
35318     t = s - cy;
35319     cy2 = t > s;
35320     cy = cy1 | cy2;
35321     z[10] = t;
35322     r = x[11];
35323     s = r - y[11];
35324     cy1 = s > r;
35325     t = s - cy;
35326     cy2 = t > s;
35327     cy = cy1 | cy2;
35328     z[11] = t;
35329     r = x[12];
35330     s = r - y[12];
35331     cy1 = s > r;
35332     t = s - cy;
35333     cy2 = t > s;
35334     cy = cy1 | cy2;
35335     z[12] = t;
35336     r = x[13];
35337     s = r - y[13];
35338     cy1 = s > r;
35339     t = s - cy;
35340     cy2 = t > s;
35341     cy = cy1 | cy2;
35342     z[13] = t;
35343     r = x[14];
35344     s = r - y[14];
35345     cy1 = s > r;
35346     t = s - cy;
35347     cy2 = t > s;
35348     cy = cy1 | cy2;
35349     z[14] = t;
35350 }
35351 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_sub_nc) */
35352 
35353 #if !defined(HAVE_native_mpfq_fixmp_14_5_add_ui)
35354 /* x, y, and z have 14.5 words. Result in z. Return carry bit */
35355 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui */
35356 static inline
mpfq_fixmp_14_5_add_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)35357 mp_limb_t mpfq_fixmp_14_5_add_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
35358 {
35359     mp_limb_t r, s, t, cy, cy1, cy2;
35360     cy = 0;
35361     r = x[0];
35362     s = r + y;
35363     cy1 = s < r;
35364     t = s + cy;
35365     cy2 = t < s;
35366     cy = cy1 | cy2;
35367     z[0] = t;
35368     s = x[1];
35369     t = s + cy;
35370     cy = t < s;
35371     z[1] = t;
35372     s = x[2];
35373     t = s + cy;
35374     cy = t < s;
35375     z[2] = t;
35376     s = x[3];
35377     t = s + cy;
35378     cy = t < s;
35379     z[3] = t;
35380     s = x[4];
35381     t = s + cy;
35382     cy = t < s;
35383     z[4] = t;
35384     s = x[5];
35385     t = s + cy;
35386     cy = t < s;
35387     z[5] = t;
35388     s = x[6];
35389     t = s + cy;
35390     cy = t < s;
35391     z[6] = t;
35392     s = x[7];
35393     t = s + cy;
35394     cy = t < s;
35395     z[7] = t;
35396     s = x[8];
35397     t = s + cy;
35398     cy = t < s;
35399     z[8] = t;
35400     s = x[9];
35401     t = s + cy;
35402     cy = t < s;
35403     z[9] = t;
35404     s = x[10];
35405     t = s + cy;
35406     cy = t < s;
35407     z[10] = t;
35408     s = x[11];
35409     t = s + cy;
35410     cy = t < s;
35411     z[11] = t;
35412     s = x[12];
35413     t = s + cy;
35414     cy = t < s;
35415     z[12] = t;
35416     s = x[13];
35417     t = s + cy;
35418     cy = t < s;
35419     z[13] = t;
35420     s = x[14];
35421     t = s + cy;
35422     cy = t < s;
35423     z[14] = t;
35424     return cy;
35425 }
35426 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_add_ui) */
35427 
35428 #if !defined(HAVE_native_mpfq_fixmp_14_5_sub_ui)
35429 /* x, y, and z have 14.5 words. Result in z. Return borrow bit */
35430 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui */
35431 static inline
mpfq_fixmp_14_5_sub_ui(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)35432 mp_limb_t mpfq_fixmp_14_5_sub_ui(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
35433 {
35434     mp_limb_t r, s, t, cy, cy1, cy2;
35435     cy = 0;
35436     r = x[0];
35437     s = r - y;
35438     cy1 = s > r;
35439     t = s - cy;
35440     cy2 = t > s;
35441     cy = cy1 | cy2;
35442     z[0] = t;
35443     s = x[1];
35444     t = s - cy;
35445     cy = t > s;
35446     z[1] = t;
35447     s = x[2];
35448     t = s - cy;
35449     cy = t > s;
35450     z[2] = t;
35451     s = x[3];
35452     t = s - cy;
35453     cy = t > s;
35454     z[3] = t;
35455     s = x[4];
35456     t = s - cy;
35457     cy = t > s;
35458     z[4] = t;
35459     s = x[5];
35460     t = s - cy;
35461     cy = t > s;
35462     z[5] = t;
35463     s = x[6];
35464     t = s - cy;
35465     cy = t > s;
35466     z[6] = t;
35467     s = x[7];
35468     t = s - cy;
35469     cy = t > s;
35470     z[7] = t;
35471     s = x[8];
35472     t = s - cy;
35473     cy = t > s;
35474     z[8] = t;
35475     s = x[9];
35476     t = s - cy;
35477     cy = t > s;
35478     z[9] = t;
35479     s = x[10];
35480     t = s - cy;
35481     cy = t > s;
35482     z[10] = t;
35483     s = x[11];
35484     t = s - cy;
35485     cy = t > s;
35486     z[11] = t;
35487     s = x[12];
35488     t = s - cy;
35489     cy = t > s;
35490     z[12] = t;
35491     s = x[13];
35492     t = s - cy;
35493     cy = t > s;
35494     z[13] = t;
35495     s = x[14];
35496     t = s - cy;
35497     cy = t > s;
35498     z[14] = t;
35499     return cy;
35500 }
35501 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_sub_ui) */
35502 
35503 #if !defined(HAVE_native_mpfq_fixmp_14_5_add_ui_nc)
35504 /* x, y, and z have 14.5 words. Result in z. Carry bit is lost. */
35505 /* *Mpfq::fixmp::longlong::code_for__fixmp_add_ui_nc */
35506 static inline
mpfq_fixmp_14_5_add_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)35507 void mpfq_fixmp_14_5_add_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
35508 {
35509     mp_limb_t r, s, t, cy, cy1, cy2;
35510     cy = 0;
35511     r = x[0];
35512     s = r + y;
35513     cy1 = s < r;
35514     t = s + cy;
35515     cy2 = t < s;
35516     cy = cy1 | cy2;
35517     z[0] = t;
35518     s = x[1];
35519     t = s + cy;
35520     cy = t < s;
35521     z[1] = t;
35522     s = x[2];
35523     t = s + cy;
35524     cy = t < s;
35525     z[2] = t;
35526     s = x[3];
35527     t = s + cy;
35528     cy = t < s;
35529     z[3] = t;
35530     s = x[4];
35531     t = s + cy;
35532     cy = t < s;
35533     z[4] = t;
35534     s = x[5];
35535     t = s + cy;
35536     cy = t < s;
35537     z[5] = t;
35538     s = x[6];
35539     t = s + cy;
35540     cy = t < s;
35541     z[6] = t;
35542     s = x[7];
35543     t = s + cy;
35544     cy = t < s;
35545     z[7] = t;
35546     s = x[8];
35547     t = s + cy;
35548     cy = t < s;
35549     z[8] = t;
35550     s = x[9];
35551     t = s + cy;
35552     cy = t < s;
35553     z[9] = t;
35554     s = x[10];
35555     t = s + cy;
35556     cy = t < s;
35557     z[10] = t;
35558     s = x[11];
35559     t = s + cy;
35560     cy = t < s;
35561     z[11] = t;
35562     s = x[12];
35563     t = s + cy;
35564     cy = t < s;
35565     z[12] = t;
35566     s = x[13];
35567     t = s + cy;
35568     cy = t < s;
35569     z[13] = t;
35570     s = x[14];
35571     t = s + cy;
35572     cy = t < s;
35573     z[14] = t;
35574 }
35575 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_add_ui_nc) */
35576 
35577 #if !defined(HAVE_native_mpfq_fixmp_14_5_sub_ui_nc)
35578 /* x, y, and z have 14.5 words. Result in z. Borrow bit is lost. */
35579 /* *Mpfq::fixmp::longlong::code_for__fixmp_sub_ui_nc */
35580 static inline
mpfq_fixmp_14_5_sub_ui_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t y)35581 void mpfq_fixmp_14_5_sub_ui_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t y)
35582 {
35583     mp_limb_t r, s, t, cy, cy1, cy2;
35584     cy = 0;
35585     r = x[0];
35586     s = r - y;
35587     cy1 = s > r;
35588     t = s - cy;
35589     cy2 = t > s;
35590     cy = cy1 | cy2;
35591     z[0] = t;
35592     s = x[1];
35593     t = s - cy;
35594     cy = t > s;
35595     z[1] = t;
35596     s = x[2];
35597     t = s - cy;
35598     cy = t > s;
35599     z[2] = t;
35600     s = x[3];
35601     t = s - cy;
35602     cy = t > s;
35603     z[3] = t;
35604     s = x[4];
35605     t = s - cy;
35606     cy = t > s;
35607     z[4] = t;
35608     s = x[5];
35609     t = s - cy;
35610     cy = t > s;
35611     z[5] = t;
35612     s = x[6];
35613     t = s - cy;
35614     cy = t > s;
35615     z[6] = t;
35616     s = x[7];
35617     t = s - cy;
35618     cy = t > s;
35619     z[7] = t;
35620     s = x[8];
35621     t = s - cy;
35622     cy = t > s;
35623     z[8] = t;
35624     s = x[9];
35625     t = s - cy;
35626     cy = t > s;
35627     z[9] = t;
35628     s = x[10];
35629     t = s - cy;
35630     cy = t > s;
35631     z[10] = t;
35632     s = x[11];
35633     t = s - cy;
35634     cy = t > s;
35635     z[11] = t;
35636     s = x[12];
35637     t = s - cy;
35638     cy = t > s;
35639     z[12] = t;
35640     s = x[13];
35641     t = s - cy;
35642     cy = t > s;
35643     z[13] = t;
35644     s = x[14];
35645     t = s - cy;
35646     cy = t > s;
35647     z[14] = t;
35648 }
35649 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_sub_ui_nc) */
35650 
35651 #if !defined(HAVE_native_mpfq_fixmp_14_5_cmp)
35652 /* x and y have 14.5 words. Return sign of difference x-y. */
35653 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp */
35654 /* Triggered by: 14_5_invmod, 14_5_redc, 14_5_redc_ur */
35655 static inline
mpfq_fixmp_14_5_cmp(const mp_limb_t * x,const mp_limb_t * y)35656 int mpfq_fixmp_14_5_cmp(const mp_limb_t * x, const mp_limb_t * y)
35657 {
35658     for (int i = 15-1; i >= 0; --i) {
35659         if (x[i] > y[i]) return 1;
35660         if (x[i] < y[i]) return -1;
35661     }
35662     return 0;
35663 }
35664 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_cmp) */
35665 
35666 #if !defined(HAVE_native_mpfq_fixmp_14_5_cmp_ui)
35667 /* x has 14.5 words. Return sign of difference x-y. */
35668 /* *Mpfq::fixmp::longlong::code_for__fixmp_cmp_ui */
35669 /* Triggered by: 14_5_invmod */
35670 static inline
mpfq_fixmp_14_5_cmp_ui(const mp_limb_t * x,mp_limb_t y)35671 int mpfq_fixmp_14_5_cmp_ui(const mp_limb_t * x, mp_limb_t y)
35672 {
35673     for (int i = 15-1; i > 0; --i) {
35674         if (x[i]) return 1;
35675     }
35676     if (x[0]>y) return 1;
35677     if (x[0]<y) return -1;
35678     return 0;
35679 }
35680 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_cmp_ui) */
35681 
35682 #if !defined(HAVE_native_mpfq_fixmp_14_5_addmul1)
35683 /* x has 14.5 words, z has 16.
35684  * Put (z+x*c) in z. Return carry bit. */
35685 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1 */
35686 static inline
mpfq_fixmp_14_5_addmul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)35687 mp_limb_t mpfq_fixmp_14_5_addmul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
35688 {
35689     mp_limb_t hi, lo, carry, buf;
35690     carry = 0;
35691     mpfq_umul_ppmm(hi,lo,c,x[0]);
35692     lo += carry;
35693     carry = (lo<carry) + hi;
35694     buf = z[0];
35695     lo += buf;
35696     carry += (lo<buf);
35697     z[0] = lo;
35698     mpfq_umul_ppmm(hi,lo,c,x[1]);
35699     lo += carry;
35700     carry = (lo<carry) + hi;
35701     buf = z[1];
35702     lo += buf;
35703     carry += (lo<buf);
35704     z[1] = lo;
35705     mpfq_umul_ppmm(hi,lo,c,x[2]);
35706     lo += carry;
35707     carry = (lo<carry) + hi;
35708     buf = z[2];
35709     lo += buf;
35710     carry += (lo<buf);
35711     z[2] = lo;
35712     mpfq_umul_ppmm(hi,lo,c,x[3]);
35713     lo += carry;
35714     carry = (lo<carry) + hi;
35715     buf = z[3];
35716     lo += buf;
35717     carry += (lo<buf);
35718     z[3] = lo;
35719     mpfq_umul_ppmm(hi,lo,c,x[4]);
35720     lo += carry;
35721     carry = (lo<carry) + hi;
35722     buf = z[4];
35723     lo += buf;
35724     carry += (lo<buf);
35725     z[4] = lo;
35726     mpfq_umul_ppmm(hi,lo,c,x[5]);
35727     lo += carry;
35728     carry = (lo<carry) + hi;
35729     buf = z[5];
35730     lo += buf;
35731     carry += (lo<buf);
35732     z[5] = lo;
35733     mpfq_umul_ppmm(hi,lo,c,x[6]);
35734     lo += carry;
35735     carry = (lo<carry) + hi;
35736     buf = z[6];
35737     lo += buf;
35738     carry += (lo<buf);
35739     z[6] = lo;
35740     mpfq_umul_ppmm(hi,lo,c,x[7]);
35741     lo += carry;
35742     carry = (lo<carry) + hi;
35743     buf = z[7];
35744     lo += buf;
35745     carry += (lo<buf);
35746     z[7] = lo;
35747     mpfq_umul_ppmm(hi,lo,c,x[8]);
35748     lo += carry;
35749     carry = (lo<carry) + hi;
35750     buf = z[8];
35751     lo += buf;
35752     carry += (lo<buf);
35753     z[8] = lo;
35754     mpfq_umul_ppmm(hi,lo,c,x[9]);
35755     lo += carry;
35756     carry = (lo<carry) + hi;
35757     buf = z[9];
35758     lo += buf;
35759     carry += (lo<buf);
35760     z[9] = lo;
35761     mpfq_umul_ppmm(hi,lo,c,x[10]);
35762     lo += carry;
35763     carry = (lo<carry) + hi;
35764     buf = z[10];
35765     lo += buf;
35766     carry += (lo<buf);
35767     z[10] = lo;
35768     mpfq_umul_ppmm(hi,lo,c,x[11]);
35769     lo += carry;
35770     carry = (lo<carry) + hi;
35771     buf = z[11];
35772     lo += buf;
35773     carry += (lo<buf);
35774     z[11] = lo;
35775     mpfq_umul_ppmm(hi,lo,c,x[12]);
35776     lo += carry;
35777     carry = (lo<carry) + hi;
35778     buf = z[12];
35779     lo += buf;
35780     carry += (lo<buf);
35781     z[12] = lo;
35782     mpfq_umul_ppmm(hi,lo,c,x[13]);
35783     lo += carry;
35784     carry = (lo<carry) + hi;
35785     buf = z[13];
35786     lo += buf;
35787     carry += (lo<buf);
35788     z[13] = lo;
35789     mpfq_umul_ppmm(hi,lo,c,x[14]);
35790     lo += carry;
35791     carry = (lo<carry) + hi;
35792     buf = z[14];
35793     lo += buf;
35794     carry += (lo<buf);
35795     z[14] = lo;
35796     z[15] += carry;
35797     return (z[15]<carry);
35798 }
35799 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_addmul1) */
35800 
35801 #if !defined(HAVE_native_mpfq_fixmp_14_5_addmul1_nc)
35802 /* x has 14.5 words, z has 16.
35803  * Put (z+x*c) in z. Carry bit is lost. */
35804 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_nc */
35805 /* Triggered by: 14_5_mul, 14_5_mgy_decode */
35806 static inline
mpfq_fixmp_14_5_addmul1_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)35807 void mpfq_fixmp_14_5_addmul1_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
35808 {
35809     mp_limb_t hi, lo, carry, buf;
35810     carry = 0;
35811     mpfq_umul_ppmm(hi,lo,c,x[0]);
35812     lo += carry;
35813     carry = (lo<carry) + hi;
35814     buf = z[0];
35815     lo += buf;
35816     carry += (lo<buf);
35817     z[0] = lo;
35818     mpfq_umul_ppmm(hi,lo,c,x[1]);
35819     lo += carry;
35820     carry = (lo<carry) + hi;
35821     buf = z[1];
35822     lo += buf;
35823     carry += (lo<buf);
35824     z[1] = lo;
35825     mpfq_umul_ppmm(hi,lo,c,x[2]);
35826     lo += carry;
35827     carry = (lo<carry) + hi;
35828     buf = z[2];
35829     lo += buf;
35830     carry += (lo<buf);
35831     z[2] = lo;
35832     mpfq_umul_ppmm(hi,lo,c,x[3]);
35833     lo += carry;
35834     carry = (lo<carry) + hi;
35835     buf = z[3];
35836     lo += buf;
35837     carry += (lo<buf);
35838     z[3] = lo;
35839     mpfq_umul_ppmm(hi,lo,c,x[4]);
35840     lo += carry;
35841     carry = (lo<carry) + hi;
35842     buf = z[4];
35843     lo += buf;
35844     carry += (lo<buf);
35845     z[4] = lo;
35846     mpfq_umul_ppmm(hi,lo,c,x[5]);
35847     lo += carry;
35848     carry = (lo<carry) + hi;
35849     buf = z[5];
35850     lo += buf;
35851     carry += (lo<buf);
35852     z[5] = lo;
35853     mpfq_umul_ppmm(hi,lo,c,x[6]);
35854     lo += carry;
35855     carry = (lo<carry) + hi;
35856     buf = z[6];
35857     lo += buf;
35858     carry += (lo<buf);
35859     z[6] = lo;
35860     mpfq_umul_ppmm(hi,lo,c,x[7]);
35861     lo += carry;
35862     carry = (lo<carry) + hi;
35863     buf = z[7];
35864     lo += buf;
35865     carry += (lo<buf);
35866     z[7] = lo;
35867     mpfq_umul_ppmm(hi,lo,c,x[8]);
35868     lo += carry;
35869     carry = (lo<carry) + hi;
35870     buf = z[8];
35871     lo += buf;
35872     carry += (lo<buf);
35873     z[8] = lo;
35874     mpfq_umul_ppmm(hi,lo,c,x[9]);
35875     lo += carry;
35876     carry = (lo<carry) + hi;
35877     buf = z[9];
35878     lo += buf;
35879     carry += (lo<buf);
35880     z[9] = lo;
35881     mpfq_umul_ppmm(hi,lo,c,x[10]);
35882     lo += carry;
35883     carry = (lo<carry) + hi;
35884     buf = z[10];
35885     lo += buf;
35886     carry += (lo<buf);
35887     z[10] = lo;
35888     mpfq_umul_ppmm(hi,lo,c,x[11]);
35889     lo += carry;
35890     carry = (lo<carry) + hi;
35891     buf = z[11];
35892     lo += buf;
35893     carry += (lo<buf);
35894     z[11] = lo;
35895     mpfq_umul_ppmm(hi,lo,c,x[12]);
35896     lo += carry;
35897     carry = (lo<carry) + hi;
35898     buf = z[12];
35899     lo += buf;
35900     carry += (lo<buf);
35901     z[12] = lo;
35902     mpfq_umul_ppmm(hi,lo,c,x[13]);
35903     lo += carry;
35904     carry = (lo<carry) + hi;
35905     buf = z[13];
35906     lo += buf;
35907     carry += (lo<buf);
35908     z[13] = lo;
35909     mpfq_umul_ppmm(hi,lo,c,x[14]);
35910     lo += carry;
35911     carry = (lo<carry) + hi;
35912     buf = z[14];
35913     lo += buf;
35914     carry += (lo<buf);
35915     z[14] = lo;
35916     z[15] += carry;
35917 }
35918 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_addmul1_nc) */
35919 
35920 #if !defined(HAVE_native_mpfq_fixmp_14_5_addmul1_shortz)
35921 /* x has 14.5 words, z has 15.
35922  * Put (z+x*c) in z. Return carry word. */
35923 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul1_shortz */
35924 /* Triggered by: 14_5_redc, 14_5_redc_ur */
35925 static inline
mpfq_fixmp_14_5_addmul1_shortz(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)35926 mp_limb_t mpfq_fixmp_14_5_addmul1_shortz(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
35927 {
35928     mp_limb_t hi, lo, carry, buf;
35929     carry = 0;
35930     mpfq_umul_ppmm(hi,lo,c,x[0]);
35931     lo += carry;
35932     carry = (lo<carry) + hi;
35933     buf = z[0];
35934     lo += buf;
35935     carry += (lo<buf);
35936     z[0] = lo;
35937     mpfq_umul_ppmm(hi,lo,c,x[1]);
35938     lo += carry;
35939     carry = (lo<carry) + hi;
35940     buf = z[1];
35941     lo += buf;
35942     carry += (lo<buf);
35943     z[1] = lo;
35944     mpfq_umul_ppmm(hi,lo,c,x[2]);
35945     lo += carry;
35946     carry = (lo<carry) + hi;
35947     buf = z[2];
35948     lo += buf;
35949     carry += (lo<buf);
35950     z[2] = lo;
35951     mpfq_umul_ppmm(hi,lo,c,x[3]);
35952     lo += carry;
35953     carry = (lo<carry) + hi;
35954     buf = z[3];
35955     lo += buf;
35956     carry += (lo<buf);
35957     z[3] = lo;
35958     mpfq_umul_ppmm(hi,lo,c,x[4]);
35959     lo += carry;
35960     carry = (lo<carry) + hi;
35961     buf = z[4];
35962     lo += buf;
35963     carry += (lo<buf);
35964     z[4] = lo;
35965     mpfq_umul_ppmm(hi,lo,c,x[5]);
35966     lo += carry;
35967     carry = (lo<carry) + hi;
35968     buf = z[5];
35969     lo += buf;
35970     carry += (lo<buf);
35971     z[5] = lo;
35972     mpfq_umul_ppmm(hi,lo,c,x[6]);
35973     lo += carry;
35974     carry = (lo<carry) + hi;
35975     buf = z[6];
35976     lo += buf;
35977     carry += (lo<buf);
35978     z[6] = lo;
35979     mpfq_umul_ppmm(hi,lo,c,x[7]);
35980     lo += carry;
35981     carry = (lo<carry) + hi;
35982     buf = z[7];
35983     lo += buf;
35984     carry += (lo<buf);
35985     z[7] = lo;
35986     mpfq_umul_ppmm(hi,lo,c,x[8]);
35987     lo += carry;
35988     carry = (lo<carry) + hi;
35989     buf = z[8];
35990     lo += buf;
35991     carry += (lo<buf);
35992     z[8] = lo;
35993     mpfq_umul_ppmm(hi,lo,c,x[9]);
35994     lo += carry;
35995     carry = (lo<carry) + hi;
35996     buf = z[9];
35997     lo += buf;
35998     carry += (lo<buf);
35999     z[9] = lo;
36000     mpfq_umul_ppmm(hi,lo,c,x[10]);
36001     lo += carry;
36002     carry = (lo<carry) + hi;
36003     buf = z[10];
36004     lo += buf;
36005     carry += (lo<buf);
36006     z[10] = lo;
36007     mpfq_umul_ppmm(hi,lo,c,x[11]);
36008     lo += carry;
36009     carry = (lo<carry) + hi;
36010     buf = z[11];
36011     lo += buf;
36012     carry += (lo<buf);
36013     z[11] = lo;
36014     mpfq_umul_ppmm(hi,lo,c,x[12]);
36015     lo += carry;
36016     carry = (lo<carry) + hi;
36017     buf = z[12];
36018     lo += buf;
36019     carry += (lo<buf);
36020     z[12] = lo;
36021     mpfq_umul_ppmm(hi,lo,c,x[13]);
36022     lo += carry;
36023     carry = (lo<carry) + hi;
36024     buf = z[13];
36025     lo += buf;
36026     carry += (lo<buf);
36027     z[13] = lo;
36028     mpfq_umul_ppmm(hi,lo,c,x[14]);
36029     lo += carry;
36030     carry = (lo<carry) + hi;
36031     buf = z[14];
36032     lo += buf;
36033     carry += (lo<buf);
36034     z[14] = lo;
36035     return carry;
36036 }
36037 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_addmul1_shortz) */
36038 
36039 #if !defined(HAVE_native_mpfq_fixmp_14_5_addmul05_nc)
36040 /* x has 14.5 words, z has 15. c is 0.5 word.
36041  * Put (z+x*c) in z. Carry bit is lost. */
36042 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
36043 /* Triggered by: 14_5_mul, 14_5_mgy_decode */
36044 static inline
mpfq_fixmp_14_5_addmul05_nc(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)36045 void mpfq_fixmp_14_5_addmul05_nc(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
36046 {
36047     mp_limb_t hi, lo, carry, buf;
36048     carry = 0;
36049     mpfq_umul_ppmm(hi,lo,c,x[0]);
36050     lo += carry;
36051     carry = (lo<carry) + hi;
36052     buf = z[0];
36053     lo += buf;
36054     carry += (lo<buf);
36055     z[0] = lo;
36056     mpfq_umul_ppmm(hi,lo,c,x[1]);
36057     lo += carry;
36058     carry = (lo<carry) + hi;
36059     buf = z[1];
36060     lo += buf;
36061     carry += (lo<buf);
36062     z[1] = lo;
36063     mpfq_umul_ppmm(hi,lo,c,x[2]);
36064     lo += carry;
36065     carry = (lo<carry) + hi;
36066     buf = z[2];
36067     lo += buf;
36068     carry += (lo<buf);
36069     z[2] = lo;
36070     mpfq_umul_ppmm(hi,lo,c,x[3]);
36071     lo += carry;
36072     carry = (lo<carry) + hi;
36073     buf = z[3];
36074     lo += buf;
36075     carry += (lo<buf);
36076     z[3] = lo;
36077     mpfq_umul_ppmm(hi,lo,c,x[4]);
36078     lo += carry;
36079     carry = (lo<carry) + hi;
36080     buf = z[4];
36081     lo += buf;
36082     carry += (lo<buf);
36083     z[4] = lo;
36084     mpfq_umul_ppmm(hi,lo,c,x[5]);
36085     lo += carry;
36086     carry = (lo<carry) + hi;
36087     buf = z[5];
36088     lo += buf;
36089     carry += (lo<buf);
36090     z[5] = lo;
36091     mpfq_umul_ppmm(hi,lo,c,x[6]);
36092     lo += carry;
36093     carry = (lo<carry) + hi;
36094     buf = z[6];
36095     lo += buf;
36096     carry += (lo<buf);
36097     z[6] = lo;
36098     mpfq_umul_ppmm(hi,lo,c,x[7]);
36099     lo += carry;
36100     carry = (lo<carry) + hi;
36101     buf = z[7];
36102     lo += buf;
36103     carry += (lo<buf);
36104     z[7] = lo;
36105     mpfq_umul_ppmm(hi,lo,c,x[8]);
36106     lo += carry;
36107     carry = (lo<carry) + hi;
36108     buf = z[8];
36109     lo += buf;
36110     carry += (lo<buf);
36111     z[8] = lo;
36112     mpfq_umul_ppmm(hi,lo,c,x[9]);
36113     lo += carry;
36114     carry = (lo<carry) + hi;
36115     buf = z[9];
36116     lo += buf;
36117     carry += (lo<buf);
36118     z[9] = lo;
36119     mpfq_umul_ppmm(hi,lo,c,x[10]);
36120     lo += carry;
36121     carry = (lo<carry) + hi;
36122     buf = z[10];
36123     lo += buf;
36124     carry += (lo<buf);
36125     z[10] = lo;
36126     mpfq_umul_ppmm(hi,lo,c,x[11]);
36127     lo += carry;
36128     carry = (lo<carry) + hi;
36129     buf = z[11];
36130     lo += buf;
36131     carry += (lo<buf);
36132     z[11] = lo;
36133     mpfq_umul_ppmm(hi,lo,c,x[12]);
36134     lo += carry;
36135     carry = (lo<carry) + hi;
36136     buf = z[12];
36137     lo += buf;
36138     carry += (lo<buf);
36139     z[12] = lo;
36140     mpfq_umul_ppmm(hi,lo,c,x[13]);
36141     lo += carry;
36142     carry = (lo<carry) + hi;
36143     buf = z[13];
36144     lo += buf;
36145     carry += (lo<buf);
36146     z[13] = lo;
36147     lo = c*x[14] + carry;
36148     assert(lo >= carry);
36149     z[14] += lo;
36150 }
36151 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_addmul05_nc) */
36152 
36153 #if !defined(HAVE_native_mpfq_fixmp_14_5_mul)
36154 /* x and y have 14.5 words, z has 29. Put x*y in z. */
36155 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul */
36156 /* Triggered by: 14_5_mgy_decode */
36157 static inline
mpfq_fixmp_14_5_mul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)36158 void mpfq_fixmp_14_5_mul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
36159 {
36160     assert(z != x && z != y);
36161     for (int i = 0; i < 29; z[i++] = 0) ;
36162     mpfq_fixmp_14_5_addmul1_nc (z + 0, x, y[0]);
36163     mpfq_fixmp_14_5_addmul1_nc (z + 1, x, y[1]);
36164     mpfq_fixmp_14_5_addmul1_nc (z + 2, x, y[2]);
36165     mpfq_fixmp_14_5_addmul1_nc (z + 3, x, y[3]);
36166     mpfq_fixmp_14_5_addmul1_nc (z + 4, x, y[4]);
36167     mpfq_fixmp_14_5_addmul1_nc (z + 5, x, y[5]);
36168     mpfq_fixmp_14_5_addmul1_nc (z + 6, x, y[6]);
36169     mpfq_fixmp_14_5_addmul1_nc (z + 7, x, y[7]);
36170     mpfq_fixmp_14_5_addmul1_nc (z + 8, x, y[8]);
36171     mpfq_fixmp_14_5_addmul1_nc (z + 9, x, y[9]);
36172     mpfq_fixmp_14_5_addmul1_nc (z + 10, x, y[10]);
36173     mpfq_fixmp_14_5_addmul1_nc (z + 11, x, y[11]);
36174     mpfq_fixmp_14_5_addmul1_nc (z + 12, x, y[12]);
36175     mpfq_fixmp_14_5_addmul1_nc (z + 13, x, y[13]);
36176     mpfq_fixmp_14_5_addmul05_nc (z + 14, x, y[14]);
36177 }
36178 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mul) */
36179 
36180 #if !defined(HAVE_native_mpfq_fixmp_14_5_sqr)
36181 /* x has 14.5 words, z has 29. Put x*y in z. */
36182 /* *Mpfq::fixmp::longlong::code_for__fixmp_sqr */
36183 static inline
mpfq_fixmp_14_5_sqr(mp_limb_t * z,const mp_limb_t * x)36184 void mpfq_fixmp_14_5_sqr(mp_limb_t * z, const mp_limb_t * x)
36185 {
36186     mp_limb_t buf[29] = {0,};
36187     mpfq_fixmp_1_addmul1_nc(buf + 1, x, x[1]);
36188     mpfq_fixmp_2_addmul1_nc(buf + 2, x, x[2]);
36189     mpfq_fixmp_3_addmul1_nc(buf + 3, x, x[3]);
36190     mpfq_fixmp_4_addmul1_nc(buf + 4, x, x[4]);
36191     mpfq_fixmp_5_addmul1_nc(buf + 5, x, x[5]);
36192     mpfq_fixmp_6_addmul1_nc(buf + 6, x, x[6]);
36193     mpfq_fixmp_7_addmul1_nc(buf + 7, x, x[7]);
36194     mpfq_fixmp_8_addmul1_nc(buf + 8, x, x[8]);
36195     mpfq_fixmp_9_addmul1_nc(buf + 9, x, x[9]);
36196     mpfq_fixmp_10_addmul1_nc(buf + 10, x, x[10]);
36197     mpfq_fixmp_11_addmul1_nc(buf + 11, x, x[11]);
36198     mpfq_fixmp_12_addmul1_nc(buf + 12, x, x[12]);
36199     mpfq_fixmp_13_addmul1_nc(buf + 13, x, x[13]);
36200     mpfq_fixmp_14_addmul1_nc(buf + 14, x, x[14]);
36201     mpfq_umul_ppmm(z[2*0+1], z[2*0], x[0], x[0]);
36202     mpfq_umul_ppmm(z[2*1+1], z[2*1], x[1], x[1]);
36203     mpfq_umul_ppmm(z[2*2+1], z[2*2], x[2], x[2]);
36204     mpfq_umul_ppmm(z[2*3+1], z[2*3], x[3], x[3]);
36205     mpfq_umul_ppmm(z[2*4+1], z[2*4], x[4], x[4]);
36206     mpfq_umul_ppmm(z[2*5+1], z[2*5], x[5], x[5]);
36207     mpfq_umul_ppmm(z[2*6+1], z[2*6], x[6], x[6]);
36208     mpfq_umul_ppmm(z[2*7+1], z[2*7], x[7], x[7]);
36209     mpfq_umul_ppmm(z[2*8+1], z[2*8], x[8], x[8]);
36210     mpfq_umul_ppmm(z[2*9+1], z[2*9], x[9], x[9]);
36211     mpfq_umul_ppmm(z[2*10+1], z[2*10], x[10], x[10]);
36212     mpfq_umul_ppmm(z[2*11+1], z[2*11], x[11], x[11]);
36213     mpfq_umul_ppmm(z[2*12+1], z[2*12], x[12], x[12]);
36214     mpfq_umul_ppmm(z[2*13+1], z[2*13], x[13], x[13]);
36215     z[2*14] = x[14] * x[14];
36216     mpn_lshift(buf, buf, 29, 1);
36217     mpn_add_n(z, z, buf, 29);
36218 }
36219 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_sqr) */
36220 
36221 #if !defined(HAVE_native_mpfq_fixmp_14_5_mul1)
36222 /* x has 14.5 words, z has 16. Put x*y in z. */
36223 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul1 */
36224 static inline
mpfq_fixmp_14_5_mul1(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)36225 void mpfq_fixmp_14_5_mul1(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
36226 {
36227     mp_limb_t hi, lo, carry;
36228     carry = 0;
36229     mpfq_umul_ppmm(hi,lo,c,x[0]);
36230     lo += carry;
36231     carry = (lo<carry) + hi;
36232     z[0] = lo;
36233     mpfq_umul_ppmm(hi,lo,c,x[1]);
36234     lo += carry;
36235     carry = (lo<carry) + hi;
36236     z[1] = lo;
36237     mpfq_umul_ppmm(hi,lo,c,x[2]);
36238     lo += carry;
36239     carry = (lo<carry) + hi;
36240     z[2] = lo;
36241     mpfq_umul_ppmm(hi,lo,c,x[3]);
36242     lo += carry;
36243     carry = (lo<carry) + hi;
36244     z[3] = lo;
36245     mpfq_umul_ppmm(hi,lo,c,x[4]);
36246     lo += carry;
36247     carry = (lo<carry) + hi;
36248     z[4] = lo;
36249     mpfq_umul_ppmm(hi,lo,c,x[5]);
36250     lo += carry;
36251     carry = (lo<carry) + hi;
36252     z[5] = lo;
36253     mpfq_umul_ppmm(hi,lo,c,x[6]);
36254     lo += carry;
36255     carry = (lo<carry) + hi;
36256     z[6] = lo;
36257     mpfq_umul_ppmm(hi,lo,c,x[7]);
36258     lo += carry;
36259     carry = (lo<carry) + hi;
36260     z[7] = lo;
36261     mpfq_umul_ppmm(hi,lo,c,x[8]);
36262     lo += carry;
36263     carry = (lo<carry) + hi;
36264     z[8] = lo;
36265     mpfq_umul_ppmm(hi,lo,c,x[9]);
36266     lo += carry;
36267     carry = (lo<carry) + hi;
36268     z[9] = lo;
36269     mpfq_umul_ppmm(hi,lo,c,x[10]);
36270     lo += carry;
36271     carry = (lo<carry) + hi;
36272     z[10] = lo;
36273     mpfq_umul_ppmm(hi,lo,c,x[11]);
36274     lo += carry;
36275     carry = (lo<carry) + hi;
36276     z[11] = lo;
36277     mpfq_umul_ppmm(hi,lo,c,x[12]);
36278     lo += carry;
36279     carry = (lo<carry) + hi;
36280     z[12] = lo;
36281     mpfq_umul_ppmm(hi,lo,c,x[13]);
36282     lo += carry;
36283     carry = (lo<carry) + hi;
36284     z[13] = lo;
36285     mpfq_umul_ppmm(hi,lo,c,x[14]);
36286     lo += carry;
36287     carry = (lo<carry) + hi;
36288     z[14] = lo;
36289     z[15] = carry;
36290 }
36291 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mul1) */
36292 
36293 #if !defined(HAVE_native_mpfq_fixmp_14_5_shortmul)
36294 /* x and y have 14.5 words, z has 15.
36295  * Put the low 15 words of x*y in z. */
36296 /* *Mpfq::fixmp::longlong::code_for__fixmp_shortmul */
36297 static inline
mpfq_fixmp_14_5_shortmul(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * y)36298 void mpfq_fixmp_14_5_shortmul(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * y)
36299 {
36300     mpfq_zero(z, 15);
36301     mpfq_fixmp_14_addmul1_nc (z+0, x, y[0]);
36302     z[15-1] += x[14]*y[0];
36303     mpfq_fixmp_13_addmul1_nc (z+1, x, y[1]);
36304     z[15-1] += x[13]*y[1];
36305     mpfq_fixmp_12_addmul1_nc (z+2, x, y[2]);
36306     z[15-1] += x[12]*y[2];
36307     mpfq_fixmp_11_addmul1_nc (z+3, x, y[3]);
36308     z[15-1] += x[11]*y[3];
36309     mpfq_fixmp_10_addmul1_nc (z+4, x, y[4]);
36310     z[15-1] += x[10]*y[4];
36311     mpfq_fixmp_9_addmul1_nc (z+5, x, y[5]);
36312     z[15-1] += x[9]*y[5];
36313     mpfq_fixmp_8_addmul1_nc (z+6, x, y[6]);
36314     z[15-1] += x[8]*y[6];
36315     mpfq_fixmp_7_addmul1_nc (z+7, x, y[7]);
36316     z[15-1] += x[7]*y[7];
36317     mpfq_fixmp_6_addmul1_nc (z+8, x, y[8]);
36318     z[15-1] += x[6]*y[8];
36319     mpfq_fixmp_5_addmul1_nc (z+9, x, y[9]);
36320     z[15-1] += x[5]*y[9];
36321     mpfq_fixmp_4_addmul1_nc (z+10, x, y[10]);
36322     z[15-1] += x[4]*y[10];
36323     mpfq_fixmp_3_addmul1_nc (z+11, x, y[11]);
36324     z[15-1] += x[3]*y[11];
36325     mpfq_fixmp_2_addmul1_nc (z+12, x, y[12]);
36326     z[15-1] += x[2]*y[12];
36327     mpfq_fixmp_1_addmul1_nc (z+13, x, y[13]);
36328     z[15-1] += x[1]*y[13];
36329     z[15-1] += x[0]*y[15-1];
36330 }
36331 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_shortmul) */
36332 
36333 #if !defined(HAVE_native_mpfq_fixmp_14_5_addmul05)
36334 /* x has 14.5 words, z has 15. c is 0.5 word.
36335  * Put (z+x*c) in z. Return carry bit. */
36336 /* *Mpfq::fixmp::longlong::code_for__fixmp_addmul05 */
36337 static inline
mpfq_fixmp_14_5_addmul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)36338 mp_limb_t mpfq_fixmp_14_5_addmul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
36339 {
36340     mp_limb_t hi, lo, carry, buf;
36341     carry = 0;
36342     mpfq_umul_ppmm(hi,lo,c,x[0]);
36343     lo += carry;
36344     carry = (lo<carry) + hi;
36345     buf = z[0];
36346     lo += buf;
36347     carry += (lo<buf);
36348     z[0] = lo;
36349     mpfq_umul_ppmm(hi,lo,c,x[1]);
36350     lo += carry;
36351     carry = (lo<carry) + hi;
36352     buf = z[1];
36353     lo += buf;
36354     carry += (lo<buf);
36355     z[1] = lo;
36356     mpfq_umul_ppmm(hi,lo,c,x[2]);
36357     lo += carry;
36358     carry = (lo<carry) + hi;
36359     buf = z[2];
36360     lo += buf;
36361     carry += (lo<buf);
36362     z[2] = lo;
36363     mpfq_umul_ppmm(hi,lo,c,x[3]);
36364     lo += carry;
36365     carry = (lo<carry) + hi;
36366     buf = z[3];
36367     lo += buf;
36368     carry += (lo<buf);
36369     z[3] = lo;
36370     mpfq_umul_ppmm(hi,lo,c,x[4]);
36371     lo += carry;
36372     carry = (lo<carry) + hi;
36373     buf = z[4];
36374     lo += buf;
36375     carry += (lo<buf);
36376     z[4] = lo;
36377     mpfq_umul_ppmm(hi,lo,c,x[5]);
36378     lo += carry;
36379     carry = (lo<carry) + hi;
36380     buf = z[5];
36381     lo += buf;
36382     carry += (lo<buf);
36383     z[5] = lo;
36384     mpfq_umul_ppmm(hi,lo,c,x[6]);
36385     lo += carry;
36386     carry = (lo<carry) + hi;
36387     buf = z[6];
36388     lo += buf;
36389     carry += (lo<buf);
36390     z[6] = lo;
36391     mpfq_umul_ppmm(hi,lo,c,x[7]);
36392     lo += carry;
36393     carry = (lo<carry) + hi;
36394     buf = z[7];
36395     lo += buf;
36396     carry += (lo<buf);
36397     z[7] = lo;
36398     mpfq_umul_ppmm(hi,lo,c,x[8]);
36399     lo += carry;
36400     carry = (lo<carry) + hi;
36401     buf = z[8];
36402     lo += buf;
36403     carry += (lo<buf);
36404     z[8] = lo;
36405     mpfq_umul_ppmm(hi,lo,c,x[9]);
36406     lo += carry;
36407     carry = (lo<carry) + hi;
36408     buf = z[9];
36409     lo += buf;
36410     carry += (lo<buf);
36411     z[9] = lo;
36412     mpfq_umul_ppmm(hi,lo,c,x[10]);
36413     lo += carry;
36414     carry = (lo<carry) + hi;
36415     buf = z[10];
36416     lo += buf;
36417     carry += (lo<buf);
36418     z[10] = lo;
36419     mpfq_umul_ppmm(hi,lo,c,x[11]);
36420     lo += carry;
36421     carry = (lo<carry) + hi;
36422     buf = z[11];
36423     lo += buf;
36424     carry += (lo<buf);
36425     z[11] = lo;
36426     mpfq_umul_ppmm(hi,lo,c,x[12]);
36427     lo += carry;
36428     carry = (lo<carry) + hi;
36429     buf = z[12];
36430     lo += buf;
36431     carry += (lo<buf);
36432     z[12] = lo;
36433     mpfq_umul_ppmm(hi,lo,c,x[13]);
36434     lo += carry;
36435     carry = (lo<carry) + hi;
36436     buf = z[13];
36437     lo += buf;
36438     carry += (lo<buf);
36439     z[13] = lo;
36440     lo = c*x[14] + carry;
36441     assert(lo >= carry);
36442     z[14] += lo;
36443     return z[14] < lo;
36444 }
36445 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_addmul05) */
36446 
36447 #if !defined(HAVE_native_mpfq_fixmp_14_5_mul05)
36448 /* x has 14.5 words, z has 15. c is 0.5 word.
36449  * Put (x*c) in z. No carry. */
36450 /* *Mpfq::fixmp::longlong::code_for__fixmp_mul05 */
36451 static inline
mpfq_fixmp_14_5_mul05(mp_limb_t * z,const mp_limb_t * x,mp_limb_t c)36452 void mpfq_fixmp_14_5_mul05(mp_limb_t * z, const mp_limb_t * x, mp_limb_t c)
36453 {
36454     mp_limb_t hi, lo, carry;
36455     carry = 0;
36456     mpfq_umul_ppmm(hi,lo,c,x[0]);
36457     lo += carry;
36458     carry = (lo<carry) + hi;
36459     z[0] = lo;
36460     mpfq_umul_ppmm(hi,lo,c,x[1]);
36461     lo += carry;
36462     carry = (lo<carry) + hi;
36463     z[1] = lo;
36464     mpfq_umul_ppmm(hi,lo,c,x[2]);
36465     lo += carry;
36466     carry = (lo<carry) + hi;
36467     z[2] = lo;
36468     mpfq_umul_ppmm(hi,lo,c,x[3]);
36469     lo += carry;
36470     carry = (lo<carry) + hi;
36471     z[3] = lo;
36472     mpfq_umul_ppmm(hi,lo,c,x[4]);
36473     lo += carry;
36474     carry = (lo<carry) + hi;
36475     z[4] = lo;
36476     mpfq_umul_ppmm(hi,lo,c,x[5]);
36477     lo += carry;
36478     carry = (lo<carry) + hi;
36479     z[5] = lo;
36480     mpfq_umul_ppmm(hi,lo,c,x[6]);
36481     lo += carry;
36482     carry = (lo<carry) + hi;
36483     z[6] = lo;
36484     mpfq_umul_ppmm(hi,lo,c,x[7]);
36485     lo += carry;
36486     carry = (lo<carry) + hi;
36487     z[7] = lo;
36488     mpfq_umul_ppmm(hi,lo,c,x[8]);
36489     lo += carry;
36490     carry = (lo<carry) + hi;
36491     z[8] = lo;
36492     mpfq_umul_ppmm(hi,lo,c,x[9]);
36493     lo += carry;
36494     carry = (lo<carry) + hi;
36495     z[9] = lo;
36496     mpfq_umul_ppmm(hi,lo,c,x[10]);
36497     lo += carry;
36498     carry = (lo<carry) + hi;
36499     z[10] = lo;
36500     mpfq_umul_ppmm(hi,lo,c,x[11]);
36501     lo += carry;
36502     carry = (lo<carry) + hi;
36503     z[11] = lo;
36504     mpfq_umul_ppmm(hi,lo,c,x[12]);
36505     lo += carry;
36506     carry = (lo<carry) + hi;
36507     z[12] = lo;
36508     mpfq_umul_ppmm(hi,lo,c,x[13]);
36509     lo += carry;
36510     carry = (lo<carry) + hi;
36511     z[13] = lo;
36512     lo = c*x[14] + carry;
36513     assert(lo >= carry);
36514     z[14] = lo;
36515 }
36516 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mul05) */
36517 
36518 #if !defined(HAVE_native_mpfq_fixmp_14_5_mod)
36519 /* x has 29 words. z and p have 14.5 words, and the high word of p is non-zero.
36520  * Put x mod p in z. */
36521 /* *Mpfq::fixmp::longlong::code_for__fixmp_mod */
36522 /* Triggered by: 14_5_mgy_decode */
36523 static inline
mpfq_fixmp_14_5_mod(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)36524 void mpfq_fixmp_14_5_mod(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
36525 {
36526     mp_limb_t q[14+1], r[15];
36527     assert (p[15-1] != 0);
36528     mpn_tdiv_qr(q, r, 0, x, 29, p, 15);
36529     mpfq_copy(z, r, 15);
36530 }
36531 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mod) */
36532 
36533 #if !defined(HAVE_native_mpfq_fixmp_14_5_rshift)
36534 /* a has 14.5 words. Shift it in place by cnt bits to the right.
36535  * The shift count cnt must not exceed the word size.
36536  * Note that no carry is returned for the bits shifted out. */
36537 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
36538 /* Triggered by: 14_5_invmod */
36539 static inline
mpfq_fixmp_14_5_rshift(mp_limb_t * a,int cnt)36540 void mpfq_fixmp_14_5_rshift(mp_limb_t * a, int cnt)
36541 {
36542     if (!cnt) return;
36543     int i;
36544     int dnt = GMP_NUMB_BITS - cnt;
36545     for (i = 0; i < 15-1; ++i) {
36546         a[i] >>= cnt;
36547         a[i] |= (a[i+1] << dnt);
36548     }
36549     a[15-1] >>= cnt;
36550 }
36551 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_rshift) */
36552 
36553 #if !defined(HAVE_native_mpfq_fixmp_14_5_long_rshift)
36554 /* a has 14.5 words. Shift it in place by off words plus cnt bits to the left.
36555  * Note that no carry is returned for the bits shifted out. */
36556 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
36557 /* Triggered by: 14_5_invmod */
36558 static inline
mpfq_fixmp_14_5_long_rshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)36559 void mpfq_fixmp_14_5_long_rshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
36560 {
36561     if (cnt) {
36562         int dnt = GMP_NUMB_BITS - cnt;
36563         for (int i = 0; i < 15 - off - 1; ++i) {
36564             a[i] = (a[i+off]>>cnt) | (a[i+off+1]<<dnt);
36565         }
36566         a[15-off-1] = a[15-1]>>cnt;
36567     } else {
36568         mpfq_copyi(a, a + off, 15 - off);
36569     }
36570     mpfq_zero(a + 15 - off, off);
36571 }
36572 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_long_rshift) */
36573 
36574 #if !defined(HAVE_native_mpfq_fixmp_14_5_long_lshift)
36575 /* a has 14.5 words. Shift it in place by off words plus cnt bits to the left.
36576  * Note that no carry is returned for the bits shifted out. */
36577 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
36578 /* Triggered by: 14_5_invmod */
36579 static inline
mpfq_fixmp_14_5_long_lshift(mp_limb_t * a,int off MAYBE_UNUSED,int cnt)36580 void mpfq_fixmp_14_5_long_lshift(mp_limb_t * a, int off MAYBE_UNUSED, int cnt)
36581 {
36582     int i;
36583     if (cnt) {
36584         int dnt = GMP_NUMB_BITS - cnt;
36585         for (i = 15-1; i>off; --i) {
36586             a[i] = (a[i-off]<<cnt) | (a[i-off-1]>>dnt);
36587         }
36588         a[off] = a[0]<<cnt;
36589     } else {
36590         mpfq_copyd(a + off, a, 15 - off);
36591     }
36592     mpfq_zero(a, off);
36593 }
36594 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_long_lshift) */
36595 
36596 #if !defined(HAVE_native_mpfq_fixmp_14_5_invmod)
36597 /* x, z, and p have 14.5 words. Put inverse of x mod p in z.
36598  * Return non-zero if an inverse could be found.
36599  * If no inverse could be found, return 0 and set z to zero.
36600  */
36601 /* *Mpfq::fixmp::longlong::code_for__fixmp_invmod */
36602 static inline
mpfq_fixmp_14_5_invmod(mp_limb_t * res,const mp_limb_t * x,const mp_limb_t * p)36603 int mpfq_fixmp_14_5_invmod(mp_limb_t * res, const mp_limb_t * x, const mp_limb_t * p)
36604 {
36605       mp_limb_t u[15], v[15], a[15], b[15], fix[15];
36606       int i, t, lsh;
36607 
36608       mpfq_zero(u, 15);
36609       mpfq_zero(v, 15);
36610       mpfq_copy(a, x, 15);
36611       mpfq_copy(b, p, 15);
36612       u[0] = 1UL;
36613 
36614       if (mpfq_fixmp_14_5_cmp(a, v) == 0 || mpfq_fixmp_14_5_cmp(a, b) == 0) {
36615         mpfq_zero(res, 15);
36616         return 0;
36617       }
36618 
36619       mpfq_fixmp_14_5_add(fix, b, u);
36620       mpfq_fixmp_14_5_rshift(fix, 1);
36621 
36622       assert (mpfq_fixmp_14_5_cmp(a,b) < 0);
36623 
36624       t = 0;
36625 
36626       for(i = 0 ; !a[i] ; i++) ;
36627       assert (i < 15);
36628       lsh = mpfq_ctzl(a[i]);
36629       mpfq_fixmp_14_5_long_rshift(a, i, lsh);
36630       t += lsh + i*GMP_NUMB_BITS;
36631       mpfq_fixmp_14_5_long_lshift(v, i, lsh);
36632 
36633       do {
36634         do {
36635           mpfq_fixmp_14_5_sub(b, b, a);
36636           mpfq_fixmp_14_5_add(v, v, u);
36637           for(i = 0 ; !b[i] ; i++) ;
36638           assert (i < 15);
36639           lsh = mpfq_ctzl(b[i]);
36640           mpfq_fixmp_14_5_long_rshift(b, i, lsh);
36641           t += lsh + i*GMP_NUMB_BITS;
36642           mpfq_fixmp_14_5_long_lshift(u, i, lsh);
36643         } while (mpfq_fixmp_14_5_cmp(a,b) < 0);
36644         if (mpfq_fixmp_14_5_cmp(a, b) == 0)
36645           break;
36646         do {
36647           mpfq_fixmp_14_5_sub(a, a, b);
36648           mpfq_fixmp_14_5_add(u, u, v);
36649           for(i = 0 ; !a[i] ; i++) ;
36650           assert (i < 15);
36651           lsh = mpfq_ctzl(a[i]);
36652           mpfq_fixmp_14_5_long_rshift(a, i, lsh);
36653           t += lsh + i*GMP_NUMB_BITS;
36654           mpfq_fixmp_14_5_long_lshift(v, i, lsh);
36655         } while (mpfq_fixmp_14_5_cmp(b,a)<0);
36656       } while (mpfq_fixmp_14_5_cmp(a,b) != 0);
36657       {
36658         if (mpfq_fixmp_14_5_cmp_ui(a, 1) != 0) {
36659           mpfq_copy(res, a, 15);
36660           return 0;
36661         }
36662       }
36663       while (t>0) {
36664         mp_limb_t sig = u[0] & 1UL;
36665         mpfq_fixmp_14_5_rshift(u, 1);
36666         if (sig)
36667           mpfq_fixmp_14_5_add(u, u, fix);
36668         --t;
36669       }
36670       mpfq_copy(res, u, 15);
36671       return 1;
36672 }
36673 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_invmod) */
36674 
36675 #if !defined(HAVE_native_mpfq_fixmp_14_5_redc)
36676 /* x has 29 words, z and p have 14.5 words.
36677  * only one word is read from invp.
36678  * Assuming R=W^15 is the redc modulus, we expect that x verifies:
36679  *   x < R*p,
36680  * so that we have eventually z < p, z congruent to x/R mod p.
36681  * The contents of the area pointed by x are clobbered by this call.
36682  * Note also that x may alias z.
36683  */
36684 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc */
36685 static inline
mpfq_fixmp_14_5_redc(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)36686 void mpfq_fixmp_14_5_redc(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
36687 {
36688     mp_limb_t cy;
36689     for(int i = 0; i < 15; ++i) {
36690         mp_limb_t t = x[i]*mip[0];
36691         cy = mpfq_fixmp_14_5_addmul1_shortz(x+i, p, t);
36692         assert (x[i] == 0);
36693         x[i] = cy;
36694     }
36695     {
36696         mp_limb_t ret[15] = { x[15], x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], x[24], x[25], x[26], x[27], x[28], 0 };
36697         cy = mpfq_fixmp_14_5_add(x, x, ret);
36698     }
36699     /* At this point, we have (x' denotes x + cy*W^n here)
36700     * x' <= R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
36701     * x'/R < p + p
36702     */
36703     if (cy || mpfq_fixmp_14_5_cmp(x, p) >= 0) {
36704         mpfq_fixmp_14_5_sub(z, x, p);
36705     } else {
36706         mpfq_copy(z, x, 15);
36707     }
36708 }
36709 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_redc) */
36710 
36711 #if !defined(HAVE_native_mpfq_fixmp_14_5_redc_ur)
36712 /* x has 30 words, z and p have 14.5 words.
36713  * only one word is read from invp.
36714  * Assuming R=W^15 is the redc modulus, we expect that x verifies:
36715  *  x < W*W^14.5*p = W^0.5*R*p or the hw case, W*R*p otherwise,
36716  * so that we have eventually z < p, z congruent to x/R mod p.
36717  * The contents of the area pointed by x are clobbered by this call.
36718  * Note also that x may alias z.
36719  */
36720 /* *Mpfq::fixmp::longlong::code_for__fixmp_redc_ur */
36721 static inline
mpfq_fixmp_14_5_redc_ur(mp_limb_t * z,mp_limb_t * x,const mp_limb_t * mip,const mp_limb_t * p)36722 void mpfq_fixmp_14_5_redc_ur(mp_limb_t * z, mp_limb_t * x, const mp_limb_t * mip, const mp_limb_t * p)
36723 {
36724     mp_limb_t cy, q[1];
36725     for(int i = 0; i < 15; ++i) {
36726         mp_limb_t t = x[i]*mip[0];
36727         cy = mpfq_fixmp_14_5_addmul1_shortz(x+i, p, t);
36728         assert (x[i] == 0);
36729         x[i] = cy;
36730     }
36731     cy = mpfq_fixmp_14_5_add(x + 15, x, x + 15);
36732     /* At this point, we have (x' denotes x + cy*W^(n+1) here)
36733     * x' <= W^0.5*R*p-1 + (W-1)*p*(1+W+...+W^{n-1}) and x = mod R.
36734     * x'/R < (W^0.5+1)*p
36735     */
36736     if (cy) {
36737         /* x'/R-p < W^0.5*p, which fits in n words. */
36738         mpfq_fixmp_14_5_sub(x + 15, x + 15, p);
36739     }
36740     mpn_tdiv_qr(q, z, 0, x + 15, 15, p, 15);
36741 }
36742 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_redc_ur) */
36743 
36744 #if !defined(HAVE_native_mpfq_fixmp_14_5_mgy_encode)
36745 /* x, z, and p have 14.5 words.
36746  * Assuming R=W^15 is the redc modulus, we compute z=R*x mod p. */
36747 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_encode */
36748 static inline
mpfq_fixmp_14_5_mgy_encode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * p)36749 void mpfq_fixmp_14_5_mgy_encode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * p)
36750 {
36751     mp_limb_t t[30] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14] };
36752     mp_limb_t qq[15+1];
36753     mpn_tdiv_qr(qq, z, 0, t, 30, p, 15);
36754 }
36755 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mgy_encode) */
36756 
36757 #if !defined(HAVE_native_mpfq_fixmp_14_5_mgy_decode)
36758 /* x, z, invR, and p have 14.5 words.
36759  * Assuming R=W^15 is the redc modulus, we compute z=x/R mod p. */
36760 /* *Mpfq::fixmp::longlong::code_for__fixmp_mgy_decode */
36761 static inline
mpfq_fixmp_14_5_mgy_decode(mp_limb_t * z,const mp_limb_t * x,const mp_limb_t * invR,const mp_limb_t * p)36762 void mpfq_fixmp_14_5_mgy_decode(mp_limb_t * z, const mp_limb_t * x, const mp_limb_t * invR, const mp_limb_t * p)
36763 {
36764     mp_limb_t t[30];
36765     mpfq_fixmp_14_5_mul(t, x, invR);
36766     mpfq_fixmp_14_5_mod(z, t, p);
36767 }
36768 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_mgy_decode) */
36769 
36770 #if !defined(HAVE_native_mpfq_fixmp_14_5_lshift)
36771 /* a has 14.5 words. Shift it in place by cnt bits to the left.
36772  * The shift count cnt must not exceed the word size.
36773  * Note that no carry is returned for the bits shifted out. */
36774 /* *Mpfq::fixmp::longlong::code_for__fixmp_lshift */
36775 static inline
mpfq_fixmp_14_5_lshift(mp_limb_t * a,int cnt)36776 void mpfq_fixmp_14_5_lshift(mp_limb_t * a, int cnt)
36777 {
36778     if (!cnt) return;
36779     int i;
36780     int dnt = GMP_NUMB_BITS - cnt;
36781     for (i = 15-1; i>0; --i) {
36782         a[i] <<= cnt;
36783         a[i] |= (a[i-1] >> dnt);
36784     }
36785     a[0] <<= cnt;
36786 }
36787 #endif /* !defined(HAVE_native_mpfq_fixmp_14_5_lshift) */
36788 
36789 
36790 #endif  /* MPFQ_FIXMP_LONGLONG_H_ */
36791 
36792 /* vim:set ft=cpp: */
36793