Merge f_arithmetic.c into f_generic.c
[openssl.git] / crypto / ec / curve448 / arch_arm_32 / f_impl.c
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright 2014 Cryptography Research, Inc.
4  *
5  * Licensed under the OpenSSL license (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  *
10  * Originally written by Mike Hamburg
11  */
12
13 #include "f_field.h"
14
15 static inline void __attribute__ ((gnu_inline, always_inline))
16     smlal(uint64_t *acc, const uint32_t a, const uint32_t b)
17 {
18
19 #ifdef  __ARMEL__
20     uint32_t lo = *acc, hi = (*acc) >> 32;
21
22     __asm__ __volatile__ ("smlal %[lo], %[hi], %[a], %[b]"
23                           : [lo]"+&r"(lo), [hi]"+&r"(hi)
24                           : [a]"r"(a), [b]"r"(b));
25
26
27     *acc = lo + (((uint64_t)hi) << 32);
28 #else
29     *acc += (int64_t)(int32_t)a *(int64_t)(int32_t)b;
30 #endif
31 }
32
33 static inline void __attribute__ ((gnu_inline, always_inline))
34     smlal2(uint64_t *acc, const uint32_t a, const uint32_t b)
35 {
36 #ifdef __ARMEL__
37     uint32_t lo = *acc, hi = (*acc) >> 32;
38
39     __asm__ __volatile__ ("smlal %[lo], %[hi], %[a], %[b]"
40                           : [lo]"+&r"(lo), [hi]"+&r"(hi)
41                           : [a]"r"(a), [b]"r"(2 * b));
42
43
44
45     *acc = lo + (((uint64_t)hi) << 32);
46 #else
47     *acc += (int64_t)(int32_t)a *(int64_t)(int32_t)(b * 2);
48 #endif
49 }
50
51 static inline void __attribute__ ((gnu_inline, always_inline))
52     smull(uint64_t *acc, const uint32_t a, const uint32_t b)
53 {
54 #ifdef __ARMEL__
55     uint32_t lo, hi;
56
57     __asm__ __volatile__ ("smull %[lo], %[hi], %[a], %[b]"
58                           : [lo]"=&r"(lo), [hi]"=&r"(hi)
59                           : [a]"r"(a), [b]"r"(b));
60
61     *acc = lo + (((uint64_t)hi) << 32);
62 #else
63     *acc = (int64_t)(int32_t)a *(int64_t)(int32_t)b;
64 #endif
65 }
66
67 static inline void __attribute__ ((gnu_inline, always_inline))
68     smull2(uint64_t *acc, const uint32_t a, const uint32_t b)
69 {
70 #ifdef __ARMEL__
71     uint32_t lo, hi;
72
73     __asm__ /*__volatile__*/ ("smull %[lo], %[hi], %[a], %[b]"
74                               : [lo]"=&r"(lo), [hi]"=&r"(hi)
75                               : [a]"r"(a), [b]"r"(2*b));
76
77     *acc = lo + (((uint64_t)hi) << 32);
78 #else
79     *acc = (int64_t)(int32_t)a *(int64_t)(int32_t)(b * 2);
80 #endif
81 }
82
83 void gf_mul(gf_s * __restrict__ cs, const gf as, const gf bs)
84 {
85
86     const uint32_t *a = as->limb, *b = bs->limb;
87     uint32_t *c = cs->limb;
88
89     uint64_t accum0 = 0, accum1 = 0, accum2, accum3, accumC0, accumC1;
90     uint32_t mask = (1 << 28) - 1;
91
92     uint32_t aa[8], bm[8];
93
94     int i;
95     for (i = 0; i < 8; i++) {
96         aa[i] = a[i] + a[i + 8];
97         bm[i] = b[i] - b[i + 8];
98     }
99
100     uint32_t ax, bx;
101     {
102         /* t^3 terms */
103         smull(&accum1, ax = aa[1], bx = b[15]);
104         smull(&accum3, ax = aa[2], bx);
105         smlal(&accum1, ax, bx = b[14]);
106         smlal(&accum3, ax = aa[3], bx);
107         smlal(&accum1, ax, bx = b[13]);
108         smlal(&accum3, ax = aa[4], bx);
109         smlal(&accum1, ax, bx = b[12]);
110         smlal(&accum3, ax = aa[5], bx);
111         smlal(&accum1, ax, bx = b[11]);
112         smlal(&accum3, ax = aa[6], bx);
113         smlal(&accum1, ax, bx = b[10]);
114         smlal(&accum3, ax = aa[7], bx);
115         smlal(&accum1, ax, bx = b[9]);
116
117         accum0 = accum1;
118         accum2 = accum3;
119
120         /* t^2 terms */
121         smlal(&accum2, ax = aa[0], bx);
122         smlal(&accum0, ax, bx = b[8]);
123         smlal(&accum2, ax = aa[1], bx);
124
125         smlal(&accum0, ax = a[9], bx = b[7]);
126         smlal(&accum2, ax = a[10], bx);
127         smlal(&accum0, ax, bx = b[6]);
128         smlal(&accum2, ax = a[11], bx);
129         smlal(&accum0, ax, bx = b[5]);
130         smlal(&accum2, ax = a[12], bx);
131         smlal(&accum0, ax, bx = b[4]);
132         smlal(&accum2, ax = a[13], bx);
133         smlal(&accum0, ax, bx = b[3]);
134         smlal(&accum2, ax = a[14], bx);
135         smlal(&accum0, ax, bx = b[2]);
136         smlal(&accum2, ax = a[15], bx);
137         smlal(&accum0, ax, bx = b[1]);
138
139         /* t terms */
140         accum1 += accum0;
141         accum3 += accum2;
142         smlal(&accum3, ax = a[8], bx);
143         smlal(&accum1, ax, bx = b[0]);
144         smlal(&accum3, ax = a[9], bx);
145
146         smlal(&accum1, ax = a[1], bx = bm[7]);
147         smlal(&accum3, ax = a[2], bx);
148         smlal(&accum1, ax, bx = bm[6]);
149         smlal(&accum3, ax = a[3], bx);
150         smlal(&accum1, ax, bx = bm[5]);
151         smlal(&accum3, ax = a[4], bx);
152         smlal(&accum1, ax, bx = bm[4]);
153         smlal(&accum3, ax = a[5], bx);
154         smlal(&accum1, ax, bx = bm[3]);
155         smlal(&accum3, ax = a[6], bx);
156         smlal(&accum1, ax, bx = bm[2]);
157         smlal(&accum3, ax = a[7], bx);
158         smlal(&accum1, ax, bx = bm[1]);
159
160         /* 1 terms */
161         smlal(&accum2, ax = a[0], bx);
162         smlal(&accum0, ax, bx = bm[0]);
163         smlal(&accum2, ax = a[1], bx);
164
165         accum2 += accum0 >> 28;
166         accum3 += accum1 >> 28;
167
168         c[0] = ((uint32_t)(accum0)) & mask;
169         c[1] = ((uint32_t)(accum2)) & mask;
170         c[8] = ((uint32_t)(accum1)) & mask;
171         c[9] = ((uint32_t)(accum3)) & mask;
172
173         accumC0 = accum2 >> 28;
174         accumC1 = accum3 >> 28;
175     }
176     {
177         /* t^3 terms */
178         smull(&accum1, ax = aa[3], bx = b[15]);
179         smull(&accum3, ax = aa[4], bx);
180         smlal(&accum1, ax, bx = b[14]);
181         smlal(&accum3, ax = aa[5], bx);
182         smlal(&accum1, ax, bx = b[13]);
183         smlal(&accum3, ax = aa[6], bx);
184         smlal(&accum1, ax, bx = b[12]);
185         smlal(&accum3, ax = aa[7], bx);
186         smlal(&accum1, ax, bx = b[11]);
187
188         accum0 = accum1;
189         accum2 = accum3;
190
191         /* t^2 terms */
192         smlal(&accum2, ax = aa[0], bx);
193         smlal(&accum0, ax, bx = b[10]);
194         smlal(&accum2, ax = aa[1], bx);
195         smlal(&accum0, ax, bx = b[9]);
196         smlal(&accum2, ax = aa[2], bx);
197         smlal(&accum0, ax, bx = b[8]);
198         smlal(&accum2, ax = aa[3], bx);
199
200         smlal(&accum0, ax = a[11], bx = b[7]);
201         smlal(&accum2, ax = a[12], bx);
202         smlal(&accum0, ax, bx = b[6]);
203         smlal(&accum2, ax = a[13], bx);
204         smlal(&accum0, ax, bx = b[5]);
205         smlal(&accum2, ax = a[14], bx);
206         smlal(&accum0, ax, bx = b[4]);
207         smlal(&accum2, ax = a[15], bx);
208         smlal(&accum0, ax, bx = b[3]);
209
210         /* t terms */
211         accum1 += accum0;
212         accum3 += accum2;
213         smlal(&accum3, ax = a[8], bx);
214         smlal(&accum1, ax, bx = b[2]);
215         smlal(&accum3, ax = a[9], bx);
216         smlal(&accum1, ax, bx = b[1]);
217         smlal(&accum3, ax = a[10], bx);
218         smlal(&accum1, ax, bx = b[0]);
219         smlal(&accum3, ax = a[11], bx);
220
221         smlal(&accum1, ax = a[3], bx = bm[7]);
222         smlal(&accum3, ax = a[4], bx);
223         smlal(&accum1, ax, bx = bm[6]);
224         smlal(&accum3, ax = a[5], bx);
225         smlal(&accum1, ax, bx = bm[5]);
226         smlal(&accum3, ax = a[6], bx);
227         smlal(&accum1, ax, bx = bm[4]);
228         smlal(&accum3, ax = a[7], bx);
229         smlal(&accum1, ax, bx = bm[3]);
230
231         /* 1 terms */
232         smlal(&accum2, ax = a[0], bx);
233         smlal(&accum0, ax, bx = bm[2]);
234         smlal(&accum2, ax = a[1], bx);
235         smlal(&accum0, ax, bx = bm[1]);
236         smlal(&accum2, ax = a[2], bx);
237         smlal(&accum0, ax, bx = bm[0]);
238         smlal(&accum2, ax = a[3], bx);
239
240         accum0 += accumC0;
241         accum1 += accumC1;
242         accum2 += accum0 >> 28;
243         accum3 += accum1 >> 28;
244
245         c[2] = ((uint32_t)(accum0)) & mask;
246         c[3] = ((uint32_t)(accum2)) & mask;
247         c[10] = ((uint32_t)(accum1)) & mask;
248         c[11] = ((uint32_t)(accum3)) & mask;
249
250         accumC0 = accum2 >> 28;
251         accumC1 = accum3 >> 28;
252     }
253     {
254
255         /* t^3 terms */
256         smull(&accum1, ax = aa[5], bx = b[15]);
257         smull(&accum3, ax = aa[6], bx);
258         smlal(&accum1, ax, bx = b[14]);
259         smlal(&accum3, ax = aa[7], bx);
260         smlal(&accum1, ax, bx = b[13]);
261
262         accum0 = accum1;
263         accum2 = accum3;
264
265         /* t^2 terms */
266
267         smlal(&accum2, ax = aa[0], bx);
268         smlal(&accum0, ax, bx = b[12]);
269         smlal(&accum2, ax = aa[1], bx);
270         smlal(&accum0, ax, bx = b[11]);
271         smlal(&accum2, ax = aa[2], bx);
272         smlal(&accum0, ax, bx = b[10]);
273         smlal(&accum2, ax = aa[3], bx);
274         smlal(&accum0, ax, bx = b[9]);
275         smlal(&accum2, ax = aa[4], bx);
276         smlal(&accum0, ax, bx = b[8]);
277         smlal(&accum2, ax = aa[5], bx);
278
279         smlal(&accum0, ax = a[13], bx = b[7]);
280         smlal(&accum2, ax = a[14], bx);
281         smlal(&accum0, ax, bx = b[6]);
282         smlal(&accum2, ax = a[15], bx);
283         smlal(&accum0, ax, bx = b[5]);
284
285         /* t terms */
286         accum1 += accum0;
287         accum3 += accum2;
288
289         smlal(&accum3, ax = a[8], bx);
290         smlal(&accum1, ax, bx = b[4]);
291         smlal(&accum3, ax = a[9], bx);
292         smlal(&accum1, ax, bx = b[3]);
293         smlal(&accum3, ax = a[10], bx);
294         smlal(&accum1, ax, bx = b[2]);
295         smlal(&accum3, ax = a[11], bx);
296         smlal(&accum1, ax, bx = b[1]);
297         smlal(&accum3, ax = a[12], bx);
298         smlal(&accum1, ax, bx = b[0]);
299         smlal(&accum3, ax = a[13], bx);
300
301         smlal(&accum1, ax = a[5], bx = bm[7]);
302         smlal(&accum3, ax = a[6], bx);
303         smlal(&accum1, ax, bx = bm[6]);
304         smlal(&accum3, ax = a[7], bx);
305         smlal(&accum1, ax, bx = bm[5]);
306
307         /* 1 terms */
308
309         smlal(&accum2, ax = a[0], bx);
310         smlal(&accum0, ax, bx = bm[4]);
311         smlal(&accum2, ax = a[1], bx);
312         smlal(&accum0, ax, bx = bm[3]);
313         smlal(&accum2, ax = a[2], bx);
314         smlal(&accum0, ax, bx = bm[2]);
315         smlal(&accum2, ax = a[3], bx);
316         smlal(&accum0, ax, bx = bm[1]);
317         smlal(&accum2, ax = a[4], bx);
318         smlal(&accum0, ax, bx = bm[0]);
319         smlal(&accum2, ax = a[5], bx);
320
321         accum0 += accumC0;
322         accum1 += accumC1;
323         accum2 += accum0 >> 28;
324         accum3 += accum1 >> 28;
325
326         c[4] = ((uint32_t)(accum0)) & mask;
327         c[5] = ((uint32_t)(accum2)) & mask;
328         c[12] = ((uint32_t)(accum1)) & mask;
329         c[13] = ((uint32_t)(accum3)) & mask;
330
331         accumC0 = accum2 >> 28;
332         accumC1 = accum3 >> 28;
333     }
334     {
335
336         /* t^3 terms */
337         smull(&accum1, ax = aa[7], bx = b[15]);
338         accum0 = accum1;
339
340         /* t^2 terms */
341
342         smull(&accum2, ax = aa[0], bx);
343         smlal(&accum0, ax, bx = b[14]);
344         smlal(&accum2, ax = aa[1], bx);
345         smlal(&accum0, ax, bx = b[13]);
346         smlal(&accum2, ax = aa[2], bx);
347         smlal(&accum0, ax, bx = b[12]);
348         smlal(&accum2, ax = aa[3], bx);
349         smlal(&accum0, ax, bx = b[11]);
350         smlal(&accum2, ax = aa[4], bx);
351         smlal(&accum0, ax, bx = b[10]);
352         smlal(&accum2, ax = aa[5], bx);
353         smlal(&accum0, ax, bx = b[9]);
354         smlal(&accum2, ax = aa[6], bx);
355         smlal(&accum0, ax, bx = b[8]);
356         smlal(&accum2, ax = aa[7], bx);
357
358         smlal(&accum0, ax = a[15], bx = b[7]);
359
360         /* t terms */
361         accum1 += accum0;
362         accum3 = accum2;
363
364         smlal(&accum3, ax = a[8], bx);
365         smlal(&accum1, ax, bx = b[6]);
366         smlal(&accum3, ax = a[9], bx);
367         smlal(&accum1, ax, bx = b[5]);
368         smlal(&accum3, ax = a[10], bx);
369         smlal(&accum1, ax, bx = b[4]);
370         smlal(&accum3, ax = a[11], bx);
371         smlal(&accum1, ax, bx = b[3]);
372         smlal(&accum3, ax = a[12], bx);
373         smlal(&accum1, ax, bx = b[2]);
374         smlal(&accum3, ax = a[13], bx);
375         smlal(&accum1, ax, bx = b[1]);
376         smlal(&accum3, ax = a[14], bx);
377         smlal(&accum1, ax, bx = b[0]);
378         smlal(&accum3, ax = a[15], bx);
379
380         smlal(&accum1, ax = a[7], bx = bm[7]);
381
382         /* 1 terms */
383
384         smlal(&accum2, ax = a[0], bx);
385         smlal(&accum0, ax, bx = bm[6]);
386         smlal(&accum2, ax = a[1], bx);
387         smlal(&accum0, ax, bx = bm[5]);
388         smlal(&accum2, ax = a[2], bx);
389         smlal(&accum0, ax, bx = bm[4]);
390         smlal(&accum2, ax = a[3], bx);
391         smlal(&accum0, ax, bx = bm[3]);
392         smlal(&accum2, ax = a[4], bx);
393         smlal(&accum0, ax, bx = bm[2]);
394         smlal(&accum2, ax = a[5], bx);
395         smlal(&accum0, ax, bx = bm[1]);
396         smlal(&accum2, ax = a[6], bx);
397         smlal(&accum0, ax, bx = bm[0]);
398         smlal(&accum2, ax = a[7], bx);
399
400         accum0 += accumC0;
401         accum1 += accumC1;
402         accum2 += accum0 >> 28;
403         accum3 += accum1 >> 28;
404
405         c[6] = ((uint32_t)(accum0)) & mask;
406         c[7] = ((uint32_t)(accum2)) & mask;
407         c[14] = ((uint32_t)(accum1)) & mask;
408         c[15] = ((uint32_t)(accum3)) & mask;
409
410         accum0 = accum2 >> 28;
411         accum1 = accum3 >> 28;
412     }
413
414     accum0 += accum1;
415     accum0 += c[8];
416     accum1 += c[0];
417     c[8] = ((uint32_t)(accum0)) & mask;
418     c[0] = ((uint32_t)(accum1)) & mask;
419
420     accum0 >>= 28;
421     accum1 >>= 28;
422     c[9] += ((uint32_t)(accum0));
423     c[1] += ((uint32_t)(accum1));
424 }
425
426 void gf_sqr(gf_s * __restrict__ cs, const gf as)
427 {
428     const uint32_t *a = as->limb;
429     uint32_t *c = cs->limb;
430
431     uint64_t accum0 = 0, accum1 = 0, accum2, accum3, accumC0, accumC1, tmp;
432     uint32_t mask = (1 << 28) - 1;
433
434     uint32_t bm[8];
435
436     int i;
437     for (i = 0; i < 8; i++) {
438         bm[i] = a[i] - a[i + 8];
439     }
440
441     uint32_t ax, bx;
442     {
443         /* t^3 terms */
444         smull2(&accum1, ax = a[9], bx = a[15]);
445         smull2(&accum3, ax = a[10], bx);
446         smlal2(&accum1, ax, bx = a[14]);
447         smlal2(&accum3, ax = a[11], bx);
448         smlal2(&accum1, ax, bx = a[13]);
449         smlal2(&accum3, ax = a[12], bx);
450         smlal(&accum1, ax, ax);
451
452         accum0 = accum1;
453         accum2 = accum3;
454
455         /* t^2 terms */
456         smlal2(&accum2, ax = a[8], a[9]);
457         smlal(&accum0, ax, ax);
458
459         smlal2(&accum0, ax = a[1], bx = a[7]);
460         smlal2(&accum2, ax = a[2], bx);
461         smlal2(&accum0, ax, bx = a[6]);
462         smlal2(&accum2, ax = a[3], bx);
463         smlal2(&accum0, ax, bx = a[5]);
464         smlal2(&accum2, ax = a[4], bx);
465         smlal(&accum0, ax, ax);
466
467         /* t terms */
468         accum1 += accum0;
469         accum3 += accum2;
470         smlal2(&accum3, ax = a[0], bx = a[1]);
471         smlal(&accum1, ax, ax);
472
473         accum1 = -accum1;
474         accum3 = -accum3;
475         accum2 = -accum2;
476         accum0 = -accum0;
477
478         smlal2(&accum1, ax = bm[1], bx = bm[7]);
479         smlal2(&accum3, ax = bm[2], bx);
480         smlal2(&accum1, ax, bx = bm[6]);
481         smlal2(&accum3, ax = bm[3], bx);
482         smlal2(&accum1, ax, bx = bm[5]);
483         smlal2(&accum3, ax = bm[4], bx);
484         smlal(&accum1, ax, ax);
485
486         /* 1 terms */
487         smlal2(&accum2, ax = bm[0], bx = bm[1]);
488         smlal(&accum0, ax, ax);
489
490         tmp = -accum3;
491         accum3 = tmp - accum2;
492         accum2 = tmp;
493         tmp = -accum1;
494         accum1 = tmp - accum0;
495         accum0 = tmp;
496
497         accum2 += accum0 >> 28;
498         accum3 += accum1 >> 28;
499
500         c[0] = ((uint32_t)(accum0)) & mask;
501         c[1] = ((uint32_t)(accum2)) & mask;
502         c[8] = ((uint32_t)(accum1)) & mask;
503         c[9] = ((uint32_t)(accum3)) & mask;
504
505         accumC0 = accum2 >> 28;
506         accumC1 = accum3 >> 28;
507     }
508     {
509         /* t^3 terms */
510         smull2(&accum1, ax = a[11], bx = a[15]);
511         smull2(&accum3, ax = a[12], bx);
512         smlal2(&accum1, ax, bx = a[14]);
513         smlal2(&accum3, ax = a[13], bx);
514         smlal(&accum1, ax, ax);
515
516         accum0 = accum1;
517         accum2 = accum3;
518
519         /* t^2 terms */
520         smlal2(&accum2, ax = a[8], bx = a[11]);
521         smlal2(&accum0, ax, bx = a[10]);
522         smlal2(&accum2, ax = a[9], bx);
523         smlal(&accum0, ax, ax);
524
525         smlal2(&accum0, ax = a[3], bx = a[7]);
526         smlal2(&accum2, ax = a[4], bx);
527         smlal2(&accum0, ax, bx = a[6]);
528         smlal2(&accum2, ax = a[5], bx);
529         smlal(&accum0, ax, ax);
530
531         /* t terms */
532         accum1 += accum0;
533         accum3 += accum2;
534         smlal2(&accum3, ax = a[0], bx = a[3]);
535         smlal2(&accum1, ax, bx = a[2]);
536         smlal2(&accum3, ax = a[1], bx);
537         smlal(&accum1, ax, ax);
538
539         accum1 = -accum1;
540         accum3 = -accum3;
541         accum2 = -accum2;
542         accum0 = -accum0;
543
544         smlal2(&accum1, ax = bm[3], bx = bm[7]);
545         smlal2(&accum3, ax = bm[4], bx);
546         smlal2(&accum1, ax, bx = bm[6]);
547         smlal2(&accum3, ax = bm[5], bx);
548         smlal(&accum1, ax, ax);
549
550         /* 1 terms */
551         smlal2(&accum2, ax = bm[0], bx = bm[3]);
552         smlal2(&accum0, ax, bx = bm[2]);
553         smlal2(&accum2, ax = bm[1], bx);
554         smlal(&accum0, ax, ax);
555
556         tmp = -accum3;
557         accum3 = tmp - accum2;
558         accum2 = tmp;
559         tmp = -accum1;
560         accum1 = tmp - accum0;
561         accum0 = tmp;
562
563         accum0 += accumC0;
564         accum1 += accumC1;
565         accum2 += accum0 >> 28;
566         accum3 += accum1 >> 28;
567
568         c[2] = ((uint32_t)(accum0)) & mask;
569         c[3] = ((uint32_t)(accum2)) & mask;
570         c[10] = ((uint32_t)(accum1)) & mask;
571         c[11] = ((uint32_t)(accum3)) & mask;
572
573         accumC0 = accum2 >> 28;
574         accumC1 = accum3 >> 28;
575     }
576     {
577
578         /* t^3 terms */
579         smull2(&accum1, ax = a[13], bx = a[15]);
580         smull2(&accum3, ax = a[14], bx);
581         smlal(&accum1, ax, ax);
582
583         accum0 = accum1;
584         accum2 = accum3;
585
586         /* t^2 terms */
587
588         smlal2(&accum2, ax = a[8], bx = a[13]);
589         smlal2(&accum0, ax, bx = a[12]);
590         smlal2(&accum2, ax = a[9], bx);
591         smlal2(&accum0, ax, bx = a[11]);
592         smlal2(&accum2, ax = a[10], bx);
593         smlal(&accum0, ax, ax);
594
595         smlal2(&accum0, ax = a[5], bx = a[7]);
596         smlal2(&accum2, ax = a[6], bx);
597         smlal(&accum0, ax, ax);
598
599         /* t terms */
600         accum1 += accum0;
601         accum3 += accum2;
602
603         smlal2(&accum3, ax = a[0], bx = a[5]);
604         smlal2(&accum1, ax, bx = a[4]);
605         smlal2(&accum3, ax = a[1], bx);
606         smlal2(&accum1, ax, bx = a[3]);
607         smlal2(&accum3, ax = a[2], bx);
608         smlal(&accum1, ax, ax);
609
610         accum1 = -accum1;
611         accum3 = -accum3;
612         accum2 = -accum2;
613         accum0 = -accum0;
614
615         smlal2(&accum1, ax = bm[5], bx = bm[7]);
616         smlal2(&accum3, ax = bm[6], bx);
617         smlal(&accum1, ax, ax);
618
619         /* 1 terms */
620
621         smlal2(&accum2, ax = bm[0], bx = bm[5]);
622         smlal2(&accum0, ax, bx = bm[4]);
623         smlal2(&accum2, ax = bm[1], bx);
624         smlal2(&accum0, ax, bx = bm[3]);
625         smlal2(&accum2, ax = bm[2], bx);
626         smlal(&accum0, ax, ax);
627
628         tmp = -accum3;
629         accum3 = tmp - accum2;
630         accum2 = tmp;
631         tmp = -accum1;
632         accum1 = tmp - accum0;
633         accum0 = tmp;
634
635         accum0 += accumC0;
636         accum1 += accumC1;
637         accum2 += accum0 >> 28;
638         accum3 += accum1 >> 28;
639
640         c[4] = ((uint32_t)(accum0)) & mask;
641         c[5] = ((uint32_t)(accum2)) & mask;
642         c[12] = ((uint32_t)(accum1)) & mask;
643         c[13] = ((uint32_t)(accum3)) & mask;
644
645         accumC0 = accum2 >> 28;
646         accumC1 = accum3 >> 28;
647     }
648     {
649
650         /* t^3 terms */
651         smull(&accum1, ax = a[15], bx = a[15]);
652         accum0 = accum1;
653
654         /* t^2 terms */
655
656         smull2(&accum2, ax = a[8], bx);
657         smlal2(&accum0, ax, bx = a[14]);
658         smlal2(&accum2, ax = a[9], bx);
659         smlal2(&accum0, ax, bx = a[13]);
660         smlal2(&accum2, ax = a[10], bx);
661         smlal2(&accum0, ax, bx = a[12]);
662         smlal2(&accum2, ax = a[11], bx);
663         smlal(&accum0, ax, ax);
664
665         smlal(&accum0, ax = a[7], bx = a[7]);
666
667         /* t terms */
668         accum1 += accum0;
669         accum3 = accum2;
670
671         smlal2(&accum3, ax = a[0], bx);
672         smlal2(&accum1, ax, bx = a[6]);
673         smlal2(&accum3, ax = a[1], bx);
674         smlal2(&accum1, ax, bx = a[5]);
675         smlal2(&accum3, ax = a[2], bx);
676         smlal2(&accum1, ax, bx = a[4]);
677         smlal2(&accum3, ax = a[3], bx);
678         smlal(&accum1, ax, ax);
679
680         accum1 = -accum1;
681         accum3 = -accum3;
682         accum2 = -accum2;
683         accum0 = -accum0;
684
685         bx = bm[7];
686         smlal(&accum1, bx, bx);
687
688         /* 1 terms */
689
690         smlal2(&accum2, ax = bm[0], bx);
691         smlal2(&accum0, ax, bx = bm[6]);
692         smlal2(&accum2, ax = bm[1], bx);
693         smlal2(&accum0, ax, bx = bm[5]);
694         smlal2(&accum2, ax = bm[2], bx);
695         smlal2(&accum0, ax, bx = bm[4]);
696         smlal2(&accum2, ax = bm[3], bx);
697         smlal(&accum0, ax, ax);
698
699         tmp = -accum3;
700         accum3 = tmp - accum2;
701         accum2 = tmp;
702         tmp = -accum1;
703         accum1 = tmp - accum0;
704         accum0 = tmp;
705
706         accum0 += accumC0;
707         accum1 += accumC1;
708         accum2 += accum0 >> 28;
709         accum3 += accum1 >> 28;
710
711         c[6] = ((uint32_t)(accum0)) & mask;
712         c[7] = ((uint32_t)(accum2)) & mask;
713         c[14] = ((uint32_t)(accum1)) & mask;
714         c[15] = ((uint32_t)(accum3)) & mask;
715
716         accum0 = accum2 >> 28;
717         accum1 = accum3 >> 28;
718     }
719
720     accum0 += accum1;
721     accum0 += c[8];
722     accum1 += c[0];
723     c[8] = ((uint32_t)(accum0)) & mask;
724     c[0] = ((uint32_t)(accum1)) & mask;
725
726     accum0 >>= 28;
727     accum1 >>= 28;
728     c[9] += ((uint32_t)(accum0));
729     c[1] += ((uint32_t)(accum1));
730 }
731
732 void gf_mulw_unsigned(gf_s * __restrict__ cs, const gf as, uint32_t b)
733 {
734     uint32_t mask = (1ull << 28) - 1;
735     const uint32_t *a = as->limb;
736     uint32_t *c = cs->limb;
737     uint64_t accum0, accum8;
738     int i;
739     uint32_t c0, c8, n0, n8;
740
741     assert(b <= mask);
742
743     c0 = a[0];
744     c8 = a[8];
745     accum0 = widemul(b, c0);
746     accum8 = widemul(b, c8);
747
748     c[0] = accum0 & mask;
749     accum0 >>= 28;
750     c[8] = accum8 & mask;
751     accum8 >>= 28;
752
753     i = 1;
754     {
755         n0 = a[i];
756         n8 = a[i + 8];
757         smlal(&accum0, b, n0);
758         smlal(&accum8, b, n8);
759
760         c[i] = accum0 & mask;
761         accum0 >>= 28;
762         c[i + 8] = accum8 & mask;
763         accum8 >>= 28;
764         i++;
765     }
766     {
767         c0 = a[i];
768         c8 = a[i + 8];
769         smlal(&accum0, b, c0);
770         smlal(&accum8, b, c8);
771
772         c[i] = accum0 & mask;
773         accum0 >>= 28;
774         c[i + 8] = accum8 & mask;
775         accum8 >>= 28;
776         i++;
777     }
778     {
779         n0 = a[i];
780         n8 = a[i + 8];
781         smlal(&accum0, b, n0);
782         smlal(&accum8, b, n8);
783
784         c[i] = accum0 & mask;
785         accum0 >>= 28;
786         c[i + 8] = accum8 & mask;
787         accum8 >>= 28;
788         i++;
789     }
790     {
791         c0 = a[i];
792         c8 = a[i + 8];
793         smlal(&accum0, b, c0);
794         smlal(&accum8, b, c8);
795
796         c[i] = accum0 & mask;
797         accum0 >>= 28;
798         c[i + 8] = accum8 & mask;
799         accum8 >>= 28;
800         i++;
801     }
802     {
803         n0 = a[i];
804         n8 = a[i + 8];
805         smlal(&accum0, b, n0);
806         smlal(&accum8, b, n8);
807
808         c[i] = accum0 & mask;
809         accum0 >>= 28;
810         c[i + 8] = accum8 & mask;
811         accum8 >>= 28;
812         i++;
813     }
814     {
815         c0 = a[i];
816         c8 = a[i + 8];
817         smlal(&accum0, b, c0);
818         smlal(&accum8, b, c8);
819
820         c[i] = accum0 & mask;
821         accum0 >>= 28;
822         c[i + 8] = accum8 & mask;
823         accum8 >>= 28;
824         i++;
825     }
826     {
827         n0 = a[i];
828         n8 = a[i + 8];
829         smlal(&accum0, b, n0);
830         smlal(&accum8, b, n8);
831
832         c[i] = accum0 & mask;
833         accum0 >>= 28;
834         c[i + 8] = accum8 & mask;
835         accum8 >>= 28;
836         i++;
837     }
838
839     accum0 += accum8 + c[8];
840     c[8] = accum0 & mask;
841     c[9] += accum0 >> 28;
842
843     accum8 += c[0];
844     c[0] = accum8 & mask;
845     c[1] += accum8 >> 28;
846 }