PolarSSL v1.3.4
bn_mul.h
Go to the documentation of this file.
1 
27 /*
28  * Multiply source vector [s] with b, add result
29  * to destination vector [d] and set carry c.
30  *
31  * Currently supports:
32  *
33  * . IA-32 (386+) . AMD64 / EM64T
34  * . IA-32 (SSE2) . Motorola 68000
35  * . PowerPC, 32-bit . MicroBlaze
36  * . PowerPC, 64-bit . TriCore
37  * . SPARC v8 . ARM v3+
38  * . Alpha . MIPS32
39  * . C, longlong . C, generic
40  */
41 #ifndef POLARSSL_BN_MUL_H
42 #define POLARSSL_BN_MUL_H
43 
44 #include "bignum.h"
45 
46 #if defined(POLARSSL_HAVE_ASM)
47 
48 #if defined(__GNUC__)
49 #if defined(__i386__)
50 
51 #define MULADDC_INIT \
52  asm( " \
53  movl %%ebx, %0; \
54  movl %5, %%esi; \
55  movl %6, %%edi; \
56  movl %7, %%ecx; \
57  movl %8, %%ebx; \
58  "
59 
60 #define MULADDC_CORE \
61  " \
62  lodsl; \
63  mull %%ebx; \
64  addl %%ecx, %%eax; \
65  adcl $0, %%edx; \
66  addl (%%edi), %%eax; \
67  adcl $0, %%edx; \
68  movl %%edx, %%ecx; \
69  stosl; \
70  "
71 
72 #if defined(POLARSSL_HAVE_SSE2)
73 
74 #define MULADDC_HUIT \
75  " \
76  movd %%ecx, %%mm1; \
77  movd %%ebx, %%mm0; \
78  movd (%%edi), %%mm3; \
79  paddq %%mm3, %%mm1; \
80  movd (%%esi), %%mm2; \
81  pmuludq %%mm0, %%mm2; \
82  movd 4(%%esi), %%mm4; \
83  pmuludq %%mm0, %%mm4; \
84  movd 8(%%esi), %%mm6; \
85  pmuludq %%mm0, %%mm6; \
86  movd 12(%%esi), %%mm7; \
87  pmuludq %%mm0, %%mm7; \
88  paddq %%mm2, %%mm1; \
89  movd 4(%%edi), %%mm3; \
90  paddq %%mm4, %%mm3; \
91  movd 8(%%edi), %%mm5; \
92  paddq %%mm6, %%mm5; \
93  movd 12(%%edi), %%mm4; \
94  paddq %%mm4, %%mm7; \
95  movd %%mm1, (%%edi); \
96  movd 16(%%esi), %%mm2; \
97  pmuludq %%mm0, %%mm2; \
98  psrlq $32, %%mm1; \
99  movd 20(%%esi), %%mm4; \
100  pmuludq %%mm0, %%mm4; \
101  paddq %%mm3, %%mm1; \
102  movd 24(%%esi), %%mm6; \
103  pmuludq %%mm0, %%mm6; \
104  movd %%mm1, 4(%%edi); \
105  psrlq $32, %%mm1; \
106  movd 28(%%esi), %%mm3; \
107  pmuludq %%mm0, %%mm3; \
108  paddq %%mm5, %%mm1; \
109  movd 16(%%edi), %%mm5; \
110  paddq %%mm5, %%mm2; \
111  movd %%mm1, 8(%%edi); \
112  psrlq $32, %%mm1; \
113  paddq %%mm7, %%mm1; \
114  movd 20(%%edi), %%mm5; \
115  paddq %%mm5, %%mm4; \
116  movd %%mm1, 12(%%edi); \
117  psrlq $32, %%mm1; \
118  paddq %%mm2, %%mm1; \
119  movd 24(%%edi), %%mm5; \
120  paddq %%mm5, %%mm6; \
121  movd %%mm1, 16(%%edi); \
122  psrlq $32, %%mm1; \
123  paddq %%mm4, %%mm1; \
124  movd 28(%%edi), %%mm5; \
125  paddq %%mm5, %%mm3; \
126  movd %%mm1, 20(%%edi); \
127  psrlq $32, %%mm1; \
128  paddq %%mm6, %%mm1; \
129  movd %%mm1, 24(%%edi); \
130  psrlq $32, %%mm1; \
131  paddq %%mm3, %%mm1; \
132  movd %%mm1, 28(%%edi); \
133  addl $32, %%edi; \
134  addl $32, %%esi; \
135  psrlq $32, %%mm1; \
136  movd %%mm1, %%ecx; \
137  "
138 
139 #define MULADDC_STOP \
140  " \
141  emms; \
142  movl %4, %%ebx; \
143  movl %%ecx, %1; \
144  movl %%edi, %2; \
145  movl %%esi, %3; \
146  " \
147  : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
148  : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
149  : "eax", "ecx", "edx", "esi", "edi" \
150  );
151 
152 #else
153 
154 #define MULADDC_STOP \
155  " \
156  movl %4, %%ebx; \
157  movl %%ecx, %1; \
158  movl %%edi, %2; \
159  movl %%esi, %3; \
160  " \
161  : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
162  : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
163  : "eax", "ecx", "edx", "esi", "edi" \
164  );
165 #endif /* SSE2 */
166 #endif /* i386 */
167 
168 #if defined(__amd64__) || defined (__x86_64__)
169 
170 #define MULADDC_INIT \
171  asm( \
172  " \
173  movq %3, %%rsi; \
174  movq %4, %%rdi; \
175  movq %5, %%rcx; \
176  movq %6, %%rbx; \
177  xorq %%r8, %%r8; \
178  "
179 
180 #define MULADDC_CORE \
181  " \
182  movq (%%rsi), %%rax; \
183  mulq %%rbx; \
184  addq $8, %%rsi; \
185  addq %%rcx, %%rax; \
186  movq %%r8, %%rcx; \
187  adcq $0, %%rdx; \
188  nop; \
189  addq %%rax, (%%rdi); \
190  adcq %%rdx, %%rcx; \
191  addq $8, %%rdi; \
192  "
193 
194 #define MULADDC_STOP \
195  " \
196  movq %%rcx, %0; \
197  movq %%rdi, %1; \
198  movq %%rsi, %2; \
199  " \
200  : "=m" (c), "=m" (d), "=m" (s) \
201  : "m" (s), "m" (d), "m" (c), "m" (b) \
202  : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \
203  );
204 
205 #endif /* AMD64 */
206 
207 #if defined(__mc68020__) || defined(__mcpu32__)
208 
209 #define MULADDC_INIT \
210  asm( \
211  " \
212  movl %3, %%a2; \
213  movl %4, %%a3; \
214  movl %5, %%d3; \
215  movl %6, %%d2; \
216  moveq #0, %%d0; \
217  "
218 
219 #define MULADDC_CORE \
220  " \
221  movel %%a2@+, %%d1; \
222  mulul %%d2, %%d4:%%d1; \
223  addl %%d3, %%d1; \
224  addxl %%d0, %%d4; \
225  moveq #0, %%d3; \
226  addl %%d1, %%a3@+; \
227  addxl %%d4, %%d3; \
228  "
229 
230 #define MULADDC_STOP \
231  " \
232  movl %%d3, %0; \
233  movl %%a3, %1; \
234  movl %%a2, %2; \
235  " \
236  : "=m" (c), "=m" (d), "=m" (s) \
237  : "m" (s), "m" (d), "m" (c), "m" (b) \
238  : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
239  );
240 
241 #define MULADDC_HUIT \
242  " \
243  movel %%a2@+, %%d1; \
244  mulul %%d2, %%d4:%%d1; \
245  addxl %%d3, %%d1; \
246  addxl %%d0, %%d4; \
247  addl %%d1, %%a3@+; \
248  movel %%a2@+, %%d1; \
249  mulul %%d2, %%d3:%%d1; \
250  addxl %%d4, %%d1; \
251  addxl %%d0, %%d3; \
252  addl %%d1, %%a3@+; \
253  movel %%a2@+, %%d1; \
254  mulul %%d2, %%d4:%%d1; \
255  addxl %%d3, %%d1; \
256  addxl %%d0, %%d4; \
257  addl %%d1, %%a3@+; \
258  movel %%a2@+, %%d1; \
259  mulul %%d2, %%d3:%%d1; \
260  addxl %%d4, %%d1; \
261  addxl %%d0, %%d3; \
262  addl %%d1, %%a3@+; \
263  movel %%a2@+, %%d1; \
264  mulul %%d2, %%d4:%%d1; \
265  addxl %%d3, %%d1; \
266  addxl %%d0, %%d4; \
267  addl %%d1, %%a3@+; \
268  movel %%a2@+, %%d1; \
269  mulul %%d2, %%d3:%%d1; \
270  addxl %%d4, %%d1; \
271  addxl %%d0, %%d3; \
272  addl %%d1, %%a3@+; \
273  movel %%a2@+, %%d1; \
274  mulul %%d2, %%d4:%%d1; \
275  addxl %%d3, %%d1; \
276  addxl %%d0, %%d4; \
277  addl %%d1, %%a3@+; \
278  movel %%a2@+, %%d1; \
279  mulul %%d2, %%d3:%%d1; \
280  addxl %%d4, %%d1; \
281  addxl %%d0, %%d3; \
282  addl %%d1, %%a3@+; \
283  addxl %%d0, %%d3; \
284  "
285 
286 #endif /* MC68000 */
287 
288 #if defined(__powerpc__) || defined(__ppc__)
289 #if defined(__powerpc64__) || defined(__ppc64__)
290 
291 #if defined(__MACH__) && defined(__APPLE__)
292 
293 #define MULADDC_INIT \
294  asm( \
295  " \
296  ld r3, %3; \
297  ld r4, %4; \
298  ld r5, %5; \
299  ld r6, %6; \
300  addi r3, r3, -8; \
301  addi r4, r4, -8; \
302  addic r5, r5, 0; \
303  "
304 
305 #define MULADDC_CORE \
306  " \
307  ldu r7, 8(r3); \
308  mulld r8, r7, r6; \
309  mulhdu r9, r7, r6; \
310  adde r8, r8, r5; \
311  ld r7, 8(r4); \
312  addze r5, r9; \
313  addc r8, r8, r7; \
314  stdu r8, 8(r4); \
315  "
316 
317 #define MULADDC_STOP \
318  " \
319  addze r5, r5; \
320  addi r4, r4, 8; \
321  addi r3, r3, 8; \
322  std r5, %0; \
323  std r4, %1; \
324  std r3, %2; \
325  " \
326  : "=m" (c), "=m" (d), "=m" (s) \
327  : "m" (s), "m" (d), "m" (c), "m" (b) \
328  : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
329  );
330 
331 
332 #else
333 
334 #define MULADDC_INIT \
335  asm( \
336  " \
337  ld %%r3, %3; \
338  ld %%r4, %4; \
339  ld %%r5, %5; \
340  ld %%r6, %6; \
341  addi %%r3, %%r3, -8; \
342  addi %%r4, %%r4, -8; \
343  addic %%r5, %%r5, 0; \
344  "
345 
346 #define MULADDC_CORE \
347  " \
348  ldu %%r7, 8(%%r3); \
349  mulld %%r8, %%r7, %%r6; \
350  mulhdu %%r9, %%r7, %%r6; \
351  adde %%r8, %%r8, %%r5; \
352  ld %%r7, 8(%%r4); \
353  addze %%r5, %%r9; \
354  addc %%r8, %%r8, %%r7; \
355  stdu %%r8, 8(%%r4); \
356  "
357 
358 #define MULADDC_STOP \
359  " \
360  addze %%r5, %%r5; \
361  addi %%r4, %%r4, 8; \
362  addi %%r3, %%r3, 8; \
363  std %%r5, %0; \
364  std %%r4, %1; \
365  std %%r3, %2; \
366  " \
367  : "=m" (c), "=m" (d), "=m" (s) \
368  : "m" (s), "m" (d), "m" (c), "m" (b) \
369  : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
370  );
371 
372 #endif
373 
374 #else /* PPC32 */
375 
376 #if defined(__MACH__) && defined(__APPLE__)
377 
378 #define MULADDC_INIT \
379  asm( \
380  " \
381  lwz r3, %3; \
382  lwz r4, %4; \
383  lwz r5, %5; \
384  lwz r6, %6; \
385  addi r3, r3, -4; \
386  addi r4, r4, -4; \
387  addic r5, r5, 0; \
388  "
389 
390 #define MULADDC_CORE \
391  " \
392  lwzu r7, 4(r3); \
393  mullw r8, r7, r6; \
394  mulhwu r9, r7, r6; \
395  adde r8, r8, r5; \
396  lwz r7, 4(r4); \
397  addze r5, r9; \
398  addc r8, r8, r7; \
399  stwu r8, 4(r4); \
400  "
401 
402 #define MULADDC_STOP \
403  " \
404  addze r5, r5; \
405  addi r4, r4, 4; \
406  addi r3, r3, 4; \
407  stw r5, %0; \
408  stw r4, %1; \
409  stw r3, %2; \
410  " \
411  : "=m" (c), "=m" (d), "=m" (s) \
412  : "m" (s), "m" (d), "m" (c), "m" (b) \
413  : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
414  );
415 
416 #else
417 
418 #define MULADDC_INIT \
419  asm( \
420  " \
421  lwz %%r3, %3; \
422  lwz %%r4, %4; \
423  lwz %%r5, %5; \
424  lwz %%r6, %6; \
425  addi %%r3, %%r3, -4; \
426  addi %%r4, %%r4, -4; \
427  addic %%r5, %%r5, 0; \
428  "
429 
430 #define MULADDC_CORE \
431  " \
432  lwzu %%r7, 4(%%r3); \
433  mullw %%r8, %%r7, %%r6; \
434  mulhwu %%r9, %%r7, %%r6; \
435  adde %%r8, %%r8, %%r5; \
436  lwz %%r7, 4(%%r4); \
437  addze %%r5, %%r9; \
438  addc %%r8, %%r8, %%r7; \
439  stwu %%r8, 4(%%r4); \
440  "
441 
442 #define MULADDC_STOP \
443  " \
444  addze %%r5, %%r5; \
445  addi %%r4, %%r4, 4; \
446  addi %%r3, %%r3, 4; \
447  stw %%r5, %0; \
448  stw %%r4, %1; \
449  stw %%r3, %2; \
450  " \
451  : "=m" (c), "=m" (d), "=m" (s) \
452  : "m" (s), "m" (d), "m" (c), "m" (b) \
453  : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
454  );
455 
456 #endif
457 
458 #endif /* PPC32 */
459 #endif /* PPC64 */
460 
461 #if defined(__sparc__) && defined(__sparc64__)
462 
463 #define MULADDC_INIT \
464  asm( \
465  " \
466  ldx %3, %%o0; \
467  ldx %4, %%o1; \
468  ld %5, %%o2; \
469  ld %6, %%o3; \
470  "
471 
472 #define MULADDC_CORE \
473  " \
474  ld [%%o0], %%o4; \
475  inc 4, %%o0; \
476  ld [%%o1], %%o5; \
477  umul %%o3, %%o4, %%o4; \
478  addcc %%o4, %%o2, %%o4; \
479  rd %%y, %%g1; \
480  addx %%g1, 0, %%g1; \
481  addcc %%o4, %%o5, %%o4; \
482  st %%o4, [%%o1]; \
483  addx %%g1, 0, %%o2; \
484  inc 4, %%o1; \
485  "
486 
487 #define MULADDC_STOP \
488  " \
489  st %%o2, %0; \
490  stx %%o1, %1; \
491  stx %%o0, %2; \
492  " \
493  : "=m" (c), "=m" (d), "=m" (s) \
494  : "m" (s), "m" (d), "m" (c), "m" (b) \
495  : "g1", "o0", "o1", "o2", "o3", "o4", \
496  "o5" \
497  );
498 #endif /* SPARCv9 */
499 
500 #if defined(__sparc__) && !defined(__sparc64__)
501 
502 #define MULADDC_INIT \
503  asm( \
504  " \
505  ld %3, %%o0; \
506  ld %4, %%o1; \
507  ld %5, %%o2; \
508  ld %6, %%o3; \
509  "
510 
511 #define MULADDC_CORE \
512  " \
513  ld [%%o0], %%o4; \
514  inc 4, %%o0; \
515  ld [%%o1], %%o5; \
516  umul %%o3, %%o4, %%o4; \
517  addcc %%o4, %%o2, %%o4; \
518  rd %%y, %%g1; \
519  addx %%g1, 0, %%g1; \
520  addcc %%o4, %%o5, %%o4; \
521  st %%o4, [%%o1]; \
522  addx %%g1, 0, %%o2; \
523  inc 4, %%o1; \
524  "
525 
526 #define MULADDC_STOP \
527  " \
528  st %%o2, %0; \
529  st %%o1, %1; \
530  st %%o0, %2; \
531  " \
532  : "=m" (c), "=m" (d), "=m" (s) \
533  : "m" (s), "m" (d), "m" (c), "m" (b) \
534  : "g1", "o0", "o1", "o2", "o3", "o4", \
535  "o5" \
536  );
537 
538 #endif /* SPARCv8 */
539 
540 #if defined(__microblaze__) || defined(microblaze)
541 
542 #define MULADDC_INIT \
543  asm( \
544  " \
545  lwi r3, %3; \
546  lwi r4, %4; \
547  lwi r5, %5; \
548  lwi r6, %6; \
549  andi r7, r6, 0xffff; \
550  bsrli r6, r6, 16; \
551  "
552 
553 #define MULADDC_CORE \
554  " \
555  lhui r8, r3, 0; \
556  addi r3, r3, 2; \
557  lhui r9, r3, 0; \
558  addi r3, r3, 2; \
559  mul r10, r9, r6; \
560  mul r11, r8, r7; \
561  mul r12, r9, r7; \
562  mul r13, r8, r6; \
563  bsrli r8, r10, 16; \
564  bsrli r9, r11, 16; \
565  add r13, r13, r8; \
566  add r13, r13, r9; \
567  bslli r10, r10, 16; \
568  bslli r11, r11, 16; \
569  add r12, r12, r10; \
570  addc r13, r13, r0; \
571  add r12, r12, r11; \
572  addc r13, r13, r0; \
573  lwi r10, r4, 0; \
574  add r12, r12, r10; \
575  addc r13, r13, r0; \
576  add r12, r12, r5; \
577  addc r5, r13, r0; \
578  swi r12, r4, 0; \
579  addi r4, r4, 4; \
580  "
581 
582 #define MULADDC_STOP \
583  " \
584  swi r5, %0; \
585  swi r4, %1; \
586  swi r3, %2; \
587  " \
588  : "=m" (c), "=m" (d), "=m" (s) \
589  : "m" (s), "m" (d), "m" (c), "m" (b) \
590  : "r3", "r4" "r5", "r6", "r7", "r8", \
591  "r9", "r10", "r11", "r12", "r13" \
592  );
593 
594 #endif /* MicroBlaze */
595 
596 #if defined(__tricore__)
597 
598 #define MULADDC_INIT \
599  asm( \
600  " \
601  ld.a %%a2, %3; \
602  ld.a %%a3, %4; \
603  ld.w %%d4, %5; \
604  ld.w %%d1, %6; \
605  xor %%d5, %%d5; \
606  "
607 
608 #define MULADDC_CORE \
609  " \
610  ld.w %%d0, [%%a2+]; \
611  madd.u %%e2, %%e4, %%d0, %%d1; \
612  ld.w %%d0, [%%a3]; \
613  addx %%d2, %%d2, %%d0; \
614  addc %%d3, %%d3, 0; \
615  mov %%d4, %%d3; \
616  st.w [%%a3+], %%d2; \
617  "
618 
619 #define MULADDC_STOP \
620  " \
621  st.w %0, %%d4; \
622  st.a %1, %%a3; \
623  st.a %2, %%a2; \
624  " \
625  : "=m" (c), "=m" (d), "=m" (s) \
626  : "m" (s), "m" (d), "m" (c), "m" (b) \
627  : "d0", "d1", "e2", "d4", "a2", "a3" \
628  );
629 
630 #endif /* TriCore */
631 
632 #if defined(__arm__)
633 
634 #if defined(__thumb__) && !defined(__thumb2__)
635 
636 #define MULADDC_INIT \
637  asm( \
638  " \
639  ldr r0, %3; \
640  ldr r1, %4; \
641  ldr r2, %5; \
642  ldr r3, %6; \
643  lsr r7, r3, #16; \
644  mov r9, r7; \
645  lsl r7, r3, #16; \
646  lsr r7, r7, #16; \
647  mov r8, r7; \
648  "
649 
650 #define MULADDC_CORE \
651  " \
652  ldmia r0!, {r6}; \
653  lsr r7, r6, #16; \
654  lsl r6, r6, #16; \
655  lsr r6, r6, #16; \
656  mov r4, r8; \
657  mul r4, r6; \
658  mov r3, r9; \
659  mul r6, r3; \
660  mov r5, r9; \
661  mul r5, r7; \
662  mov r3, r8; \
663  mul r7, r3; \
664  lsr r3, r6, #16; \
665  add r5, r5, r3; \
666  lsr r3, r7, #16; \
667  add r5, r5, r3; \
668  add r4, r4, r2; \
669  mov r2, #0; \
670  adc r5, r2; \
671  lsl r3, r6, #16; \
672  add r4, r4, r3; \
673  adc r5, r2; \
674  lsl r3, r7, #16; \
675  add r4, r4, r3; \
676  adc r5, r2; \
677  ldr r3, [r1]; \
678  add r4, r4, r3; \
679  adc r2, r5; \
680  stmia r1!, {r4}; \
681  "
682 
683 #define MULADDC_STOP \
684  " \
685  str r2, %0; \
686  str r1, %1; \
687  str r0, %2; \
688  " \
689  : "=m" (c), "=m" (d), "=m" (s) \
690  : "m" (s), "m" (d), "m" (c), "m" (b) \
691  : "r0", "r1", "r2", "r3", "r4", "r5", \
692  "r6", "r7", "r8", "r9", "cc" \
693  );
694 
695 #else
696 
697 #define MULADDC_INIT \
698  asm( \
699  " \
700  ldr r0, %3; \
701  ldr r1, %4; \
702  ldr r2, %5; \
703  ldr r3, %6; \
704  "
705 
706 #define MULADDC_CORE \
707  " \
708  ldr r4, [r0], #4; \
709  mov r5, #0; \
710  ldr r6, [r1]; \
711  umlal r2, r5, r3, r4; \
712  adds r7, r6, r2; \
713  adc r2, r5, #0; \
714  str r7, [r1], #4; \
715  "
716 
717 #define MULADDC_STOP \
718  " \
719  str r2, %0; \
720  str r1, %1; \
721  str r0, %2; \
722  " \
723  : "=m" (c), "=m" (d), "=m" (s) \
724  : "m" (s), "m" (d), "m" (c), "m" (b) \
725  : "r0", "r1", "r2", "r3", "r4", "r5", \
726  "r6", "r7", "cc" \
727  );
728 
729 #endif /* Thumb */
730 
731 #endif /* ARMv3 */
732 
733 #if defined(__alpha__)
734 
735 #define MULADDC_INIT \
736  asm( \
737  " \
738  ldq $1, %3; \
739  ldq $2, %4; \
740  ldq $3, %5; \
741  ldq $4, %6; \
742  "
743 
744 #define MULADDC_CORE \
745  " \
746  ldq $6, 0($1); \
747  addq $1, 8, $1; \
748  mulq $6, $4, $7; \
749  umulh $6, $4, $6; \
750  addq $7, $3, $7; \
751  cmpult $7, $3, $3; \
752  ldq $5, 0($2); \
753  addq $7, $5, $7; \
754  cmpult $7, $5, $5; \
755  stq $7, 0($2); \
756  addq $2, 8, $2; \
757  addq $6, $3, $3; \
758  addq $5, $3, $3; \
759  "
760 
761 #define MULADDC_STOP \
762  " \
763  stq $3, %0; \
764  stq $2, %1; \
765  stq $1, %2; \
766  " \
767  : "=m" (c), "=m" (d), "=m" (s) \
768  : "m" (s), "m" (d), "m" (c), "m" (b) \
769  : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
770  );
771 #endif /* Alpha */
772 
773 #if defined(__mips__)
774 
775 #define MULADDC_INIT \
776  asm( \
777  " \
778  lw $10, %3; \
779  lw $11, %4; \
780  lw $12, %5; \
781  lw $13, %6; \
782  "
783 
784 #define MULADDC_CORE \
785  " \
786  lw $14, 0($10); \
787  multu $13, $14; \
788  addi $10, $10, 4; \
789  mflo $14; \
790  mfhi $9; \
791  addu $14, $12, $14; \
792  lw $15, 0($11); \
793  sltu $12, $14, $12; \
794  addu $15, $14, $15; \
795  sltu $14, $15, $14; \
796  addu $12, $12, $9; \
797  sw $15, 0($11); \
798  addu $12, $12, $14; \
799  addi $11, $11, 4; \
800  "
801 
802 #define MULADDC_STOP \
803  " \
804  sw $12, %0; \
805  sw $11, %1; \
806  sw $10, %2; \
807  " \
808  : "=m" (c), "=m" (d), "=m" (s) \
809  : "m" (s), "m" (d), "m" (c), "m" (b) \
810  : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \
811  );
812 
813 #endif /* MIPS */
814 #endif /* GNUC */
815 
816 #if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
817 
818 #define MULADDC_INIT \
819  __asm mov esi, s \
820  __asm mov edi, d \
821  __asm mov ecx, c \
822  __asm mov ebx, b
823 
824 #define MULADDC_CORE \
825  __asm lodsd \
826  __asm mul ebx \
827  __asm add eax, ecx \
828  __asm adc edx, 0 \
829  __asm add eax, [edi] \
830  __asm adc edx, 0 \
831  __asm mov ecx, edx \
832  __asm stosd
833 
834 #if defined(POLARSSL_HAVE_SSE2)
835 
836 #define EMIT __asm _emit
837 
838 #define MULADDC_HUIT \
839  EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
840  EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
841  EMIT 0x0F EMIT 0x6E EMIT 0x1F \
842  EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
843  EMIT 0x0F EMIT 0x6E EMIT 0x16 \
844  EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
845  EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
846  EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
847  EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
848  EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
849  EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
850  EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
851  EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
852  EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
853  EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
854  EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
855  EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
856  EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
857  EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
858  EMIT 0x0F EMIT 0x7E EMIT 0x0F \
859  EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
860  EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
861  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
862  EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
863  EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
864  EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
865  EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
866  EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
867  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
868  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
869  EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
870  EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
871  EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
872  EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
873  EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
874  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
875  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
876  EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
877  EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
878  EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
879  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
880  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
881  EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
882  EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
883  EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
884  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
885  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
886  EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
887  EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
888  EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
889  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
890  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
891  EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
892  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
893  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
894  EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
895  EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
896  EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
897  EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
898  EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
899  EMIT 0x0F EMIT 0x7E EMIT 0xC9
900 
901 #define MULADDC_STOP \
902  EMIT 0x0F EMIT 0x77 \
903  __asm mov c, ecx \
904  __asm mov d, edi \
905  __asm mov s, esi \
906 
907 #else
908 
909 #define MULADDC_STOP \
910  __asm mov c, ecx \
911  __asm mov d, edi \
912  __asm mov s, esi \
913 
914 #endif /* SSE2 */
915 #endif /* MSVC */
916 
917 #endif /* POLARSSL_HAVE_ASM */
918 
919 #if !defined(MULADDC_CORE)
920 #if defined(POLARSSL_HAVE_UDBL)
921 
922 #define MULADDC_INIT \
923 { \
924  t_udbl r; \
925  t_uint r0, r1;
926 
927 #define MULADDC_CORE \
928  r = *(s++) * (t_udbl) b; \
929  r0 = r; \
930  r1 = r >> biL; \
931  r0 += c; r1 += (r0 < c); \
932  r0 += *d; r1 += (r0 < *d); \
933  c = r1; *(d++) = r0;
934 
935 #define MULADDC_STOP \
936 }
937 
938 #else
939 #define MULADDC_INIT \
940 { \
941  t_uint s0, s1, b0, b1; \
942  t_uint r0, r1, rx, ry; \
943  b0 = ( b << biH ) >> biH; \
944  b1 = ( b >> biH );
945 
946 #define MULADDC_CORE \
947  s0 = ( *s << biH ) >> biH; \
948  s1 = ( *s >> biH ); s++; \
949  rx = s0 * b1; r0 = s0 * b0; \
950  ry = s1 * b0; r1 = s1 * b1; \
951  r1 += ( rx >> biH ); \
952  r1 += ( ry >> biH ); \
953  rx <<= biH; ry <<= biH; \
954  r0 += rx; r1 += (r0 < rx); \
955  r0 += ry; r1 += (r0 < ry); \
956  r0 += c; r1 += (r0 < c); \
957  r0 += *d; r1 += (r0 < *d); \
958  c = r1; *(d++) = r0;
959 
960 #define MULADDC_STOP \
961 }
962 
963 #endif /* C (generic) */
964 #endif /* C (longlong) */
965 
966 #endif /* bn_mul.h */
Multi-precision integer library.