2193c954b209f63a7daf469980cb6bfbd6852c24
[openssl.git] / crypto / bn / asm / mips3.s
1 .rdata
2 .asciiz "mips3.s, Version 1.0 (prerelease)"
3 .asciiz "MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
4
5 /*
6  * ====================================================================
7  * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
8  * project.
9  *
10  * Rights for redistribution and usage in source and binary forms are
11  * granted according to the OpenSSL license. Warranty of any kind is
12  * disclaimed.
13  * ====================================================================
14  */
15
16 /*
17  * This is my modest contributon to the OpenSSL project (see
18  * http://www.openssl.org/ for more information about it) and is
19  * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
20  * module. For updates see http://fy.chalmers.se/~appro/hpe/.
21  *
22  * The module is designed to work with "new" IRIX ABI(5), namely
23  * N32 and N64. But it was tested only with MIPSpro 7.2.x assembler,
24  * i.e. depends on preprocessor options set up by MIPSspro 7.2.x
25  * driver. Another neat gadget offered by MIPSpro 7.2.x assembler is
26  * an peep-hole(?) optimization pass. This gave me the opportunity
27  * to make the code looking more regular as all those architecture
28  * dependent(!) instruction rescheduling details were left to the
29  * assembler. Cool, huh? Do note that I have no idea if GNU assembler
30  * does anything similar nor how GNU C will do with this module.
31  * Feedback on the matter is therefore very much appreciated:-)
32  *
33  * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
34  * exhibits 3-3.5-3.7 times improvement!
35  *
36  *                                      <appro@fy.chalmers.se>
37  */
38 #include <asm.h>
39 #include <regdef.h>
40
41 #if _MIPS_ISA>=4
42 #define MOVNZ(cond,dst,src)     \
43         movn    dst,src,cond
44 #else
45 #define MOVNZ(cond,dst,src)     \
46         .set    noreorder;      \
47         bnezl   cond,.+8;       \
48         move    dst,src;        \
49         .set    reorder
50 #endif
51
52 .text
53
54 .set    noat
55 .set    reorder
56
57 #define MINUS4  v1
58
59 LEAF(bn_mul_add_words)
60         .align  5
61         .set    noreorder
62         bgtzl   a2,.L_bn_mul_add_words_proceed
63         ld      t0,0(a1)
64         jr      ra
65         move    v0,zero
66         .set    reorder
67
68 .L_bn_mul_add_words_proceed:
69         li      MINUS4,-4
70         and     ta0,a2,MINUS4
71         move    v0,zero
72         beqz    ta0,.L_bn_mul_add_words_tail
73
74 .L_bn_mul_add_words_loop:
75         dmultu  t0,a3
76         ld      t1,0(a0)
77         ld      t2,8(a1)
78         ld      t3,8(a0)
79         ld      ta0,16(a1)
80         ld      ta1,16(a0)
81         daddu   t1,v0
82         sltu    v0,t1,v0        /* All manuals say it "compares 32-bit
83                                  * values", but it seems to work fine
84                                  * even on 64-bit registers. */
85         mflo    AT
86         mfhi    t0
87         daddu   t1,AT
88         daddu   v0,t0
89         sltu    AT,t1,AT
90         sd      t1,0(a0)
91         daddu   v0,AT
92
93         dmultu  t2,a3
94         ld      ta2,24(a1)
95         ld      ta3,24(a0)
96         daddu   t3,v0
97         sltu    v0,t3,v0
98         mflo    AT
99         mfhi    t2
100         daddu   t3,AT
101         daddu   v0,t2
102         sltu    AT,t3,AT
103         sd      t3,8(a0)
104         daddu   v0,AT
105
106         dmultu  ta0,a3
107         subu    a2,4
108         PTR_ADD a0,32
109         PTR_ADD a1,32
110         daddu   ta1,v0
111         sltu    v0,ta1,v0
112         mflo    AT
113         mfhi    ta0
114         daddu   ta1,AT
115         daddu   v0,ta0
116         sltu    AT,ta1,AT
117         sd      ta1,-16(a0)
118         daddu   v0,AT
119
120
121         dmultu  ta2,a3
122         and     ta0,a2,MINUS4
123         daddu   ta3,v0
124         sltu    v0,ta3,v0
125         mflo    AT
126         mfhi    ta2
127         daddu   ta3,AT
128         daddu   v0,ta2
129         sltu    AT,ta3,AT
130         sd      ta3,-8(a0)
131         daddu   v0,AT
132         .set    noreorder
133         bgtzl   ta0,.L_bn_mul_add_words_loop
134         ld      t0,0(a1)
135
136         bnezl   a2,.L_bn_mul_add_words_tail
137         ld      t0,0(a1)
138         .set    reorder
139
140 .L_bn_mul_add_words_return:
141         jr      ra
142
143 .L_bn_mul_add_words_tail:
144         dmultu  t0,a3
145         ld      t1,0(a0)
146         subu    a2,1
147         daddu   t1,v0
148         sltu    v0,t1,v0
149         mflo    AT
150         mfhi    t0
151         daddu   t1,AT
152         daddu   v0,t0
153         sltu    AT,t1,AT
154         sd      t1,0(a0)
155         daddu   v0,AT
156         beqz    a2,.L_bn_mul_add_words_return
157
158         ld      t0,8(a1)
159         dmultu  t0,a3
160         ld      t1,8(a0)
161         subu    a2,1
162         daddu   t1,v0
163         sltu    v0,t1,v0
164         mflo    AT
165         mfhi    t0
166         daddu   t1,AT
167         daddu   v0,t0
168         sltu    AT,t1,AT
169         sd      t1,8(a0)
170         daddu   v0,AT
171         beqz    a2,.L_bn_mul_add_words_return
172
173         ld      t0,16(a1)
174         dmultu  t0,a3
175         ld      t1,16(a0)
176         daddu   t1,v0
177         sltu    v0,t1,v0
178         mflo    AT
179         mfhi    t0
180         daddu   t1,AT
181         daddu   v0,t0
182         sltu    AT,t1,AT
183         sd      t1,16(a0)
184         daddu   v0,AT
185         jr      ra
186 END(bn_mul_add_words)
187
188 LEAF(bn_mul_words)
189         .align  5
190         .set    noreorder
191         bgtzl   a2,.L_bn_mul_words_proceed
192         ld      t0,0(a1)
193         jr      ra
194         move    v0,zero
195         .set    reorder
196
197 .L_bn_mul_words_proceed:
198         li      MINUS4,-4
199         and     ta0,a2,MINUS4
200         move    v0,zero
201         beqz    ta0,.L_bn_mul_words_tail
202
203 .L_bn_mul_words_loop:
204         dmultu  t0,a3
205         ld      t2,8(a1)
206         ld      ta0,16(a1)
207         ld      ta2,24(a1)
208         mflo    AT
209         mfhi    t0
210         daddu   v0,AT
211         sltu    t1,v0,AT
212         sd      v0,0(a0)
213         daddu   v0,t1,t0
214
215         dmultu  t2,a3
216         subu    a2,4
217         PTR_ADD a0,32
218         PTR_ADD a1,32
219         mflo    AT
220         mfhi    t2
221         daddu   v0,AT
222         sltu    t3,v0,AT
223         sd      v0,-24(a0)
224         daddu   v0,t3,t2
225
226         dmultu  ta0,a3
227         mflo    AT
228         mfhi    ta0
229         daddu   v0,AT
230         sltu    ta1,v0,AT
231         sd      v0,-16(a0)
232         daddu   v0,ta1,ta0
233
234
235         dmultu  ta2,a3
236         and     ta0,a2,MINUS4
237         mflo    AT
238         mfhi    ta2
239         daddu   v0,AT
240         sltu    ta3,v0,AT
241         sd      v0,-8(a0)
242         daddu   v0,ta3,ta2
243         .set    noreorder
244         bgtzl   ta0,.L_bn_mul_words_loop
245         ld      t0,0(a1)
246
247         bnezl   a2,.L_bn_mul_words_tail
248         ld      t0,0(a1)
249         .set    reorder
250
251 .L_bn_mul_words_return:
252         jr      ra
253
254 .L_bn_mul_words_tail:
255         dmultu  t0,a3
256         subu    a2,1
257         mflo    AT
258         mfhi    t0
259         daddu   v0,AT
260         sltu    t1,v0,AT
261         sd      v0,0(a0)
262         daddu   v0,t1,t0
263         beqz    a2,.L_bn_mul_words_return
264
265         ld      t0,8(a1)
266         dmultu  t0,a3
267         subu    a2,1
268         mflo    AT
269         mfhi    t0
270         daddu   v0,AT
271         sltu    t1,v0,AT
272         sd      v0,8(a0)
273         daddu   v0,t1,t0
274         beqz    a2,.L_bn_mul_words_return
275
276         ld      t0,16(a1)
277         dmultu  t0,a3
278         mflo    AT
279         mfhi    t0
280         daddu   v0,AT
281         sltu    t1,v0,AT
282         sd      v0,16(a0)
283         daddu   v0,t1,t0
284         jr      ra
285 END(bn_mul_words)
286
287 LEAF(bn_sqr_words)
288         .align  5
289         .set    noreorder
290         bgtzl   a2,.L_bn_sqr_words_proceed
291         ld      t0,0(a1)
292         jr      ra
293         move    v0,zero
294         .set    reorder
295
296 .L_bn_sqr_words_proceed:
297         li      MINUS4,-4
298         and     ta0,a2,MINUS4
299         move    v0,zero
300         beqz    ta0,.L_bn_sqr_words_tail
301
302 .L_bn_sqr_words_loop:
303         dmultu  t0,t0
304         ld      t2,8(a1)
305         ld      ta0,16(a1)
306         ld      ta2,24(a1)
307         mflo    t1
308         mfhi    t0
309         sd      t1,0(a0)
310         sd      t0,8(a0)
311
312         dmultu  t2,t2
313         subu    a2,4
314         PTR_ADD a0,64
315         PTR_ADD a1,32
316         mflo    t3
317         mfhi    t2
318         sd      t3,-48(a0)
319         sd      t2,-40(a0)
320
321         dmultu  ta0,ta0
322         mflo    ta1
323         mfhi    ta0
324         sd      ta1,-32(a0)
325         sd      ta0,-24(a0)
326
327
328         dmultu  ta2,ta2
329         and     ta0,a2,MINUS4
330         mflo    ta3
331         mfhi    ta2
332         sd      ta3,-16(a0)
333         sd      ta2,-8(a0)
334
335         .set    noreorder
336         bgtzl   ta0,.L_bn_sqr_words_loop
337         ld      t0,0(a1)
338
339         bnezl   a2,.L_bn_sqr_words_tail
340         ld      t0,0(a1)
341         .set    reorder
342
343 .L_bn_sqr_words_return:
344         move    v0,zero
345         jr      ra
346
347 .L_bn_sqr_words_tail:
348         dmultu  t0,t0
349         subu    a2,1
350         mflo    t1
351         mfhi    t0
352         sd      t1,0(a0)
353         sd      t0,8(a0)
354         beqz    a2,.L_bn_sqr_words_return
355
356         ld      t0,8(a1)
357         dmultu  t0,t0
358         subu    a2,1
359         mflo    t1
360         mfhi    t0
361         sd      t1,16(a0)
362         sd      t0,24(a0)
363         beqz    a2,.L_bn_sqr_words_return
364
365         ld      t0,16(a1)
366         dmultu  t0,t0
367         mflo    t1
368         mfhi    t0
369         sd      t1,32(a0)
370         sd      t0,40(a0)
371         jr      ra
372 END(bn_sqr_words)
373
374 LEAF(bn_add_words)
375         .align  5
376         .set    noreorder
377         bgtzl   a3,.L_bn_add_words_proceed
378         ld      t0,0(a1)
379         jr      ra
380         move    v0,zero
381         .set    reorder
382
383 .L_bn_add_words_proceed:
384         li      MINUS4,-4
385         and     AT,a3,MINUS4
386         move    v0,zero
387         beqz    AT,.L_bn_add_words_tail
388
389 .L_bn_add_words_loop:
390         ld      ta0,0(a2)
391         ld      t1,8(a1)
392         ld      ta1,8(a2)
393         ld      t2,16(a1)
394         ld      ta2,16(a2)
395         ld      t3,24(a1)
396         ld      ta3,24(a2)
397         daddu   ta0,t0
398         subu    a3,4
399         sltu    t8,ta0,t0
400         daddu   t0,ta0,v0
401         PTR_ADD a0,32
402         sltu    v0,t0,ta0
403         sd      t0,-32(a0)
404         daddu   v0,t8
405
406         daddu   ta1,t1
407         PTR_ADD a1,32
408         sltu    t9,ta1,t1
409         daddu   t1,ta1,v0
410         PTR_ADD a2,32
411         sltu    v0,t1,ta1
412         sd      t1,-24(a0)
413         daddu   v0,t9
414
415         daddu   ta2,t2
416         and     AT,a3,MINUS4
417         sltu    t8,ta2,t2
418         daddu   t2,ta2,v0
419         sltu    v0,t2,ta2
420         sd      t2,-16(a0)
421         daddu   v0,t8
422         
423         daddu   ta3,t3
424         sltu    t9,ta3,t3
425         daddu   t3,ta3,v0
426         sltu    v0,t3,ta3
427         sd      t3,-8(a0)
428         daddu   v0,t9
429         
430         .set    noreorder
431         bgtzl   AT,.L_bn_add_words_loop
432         ld      t0,0(a1)
433
434         bnezl   a3,.L_bn_add_words_tail
435         ld      t0,0(a1)
436         .set    reorder
437
438 .L_bn_add_words_return:
439         jr      ra
440
441 .L_bn_add_words_tail:
442         ld      ta0,0(a2)
443         daddu   ta0,t0
444         subu    a3,1
445         sltu    t8,ta0,t0
446         daddu   t0,ta0,v0
447         sltu    v0,t0,ta0
448         sd      t0,0(a0)
449         daddu   v0,t8
450         beqz    a3,.L_bn_add_words_return
451
452         ld      t1,8(a1)
453         ld      ta1,8(a2)
454         daddu   ta1,t1
455         subu    a3,1
456         sltu    t9,ta1,t1
457         daddu   t1,ta1,v0
458         sltu    v0,t1,ta1
459         sd      t1,8(a0)
460         daddu   v0,t9
461         beqz    a3,.L_bn_add_words_return
462
463         ld      t2,16(a1)
464         ld      ta2,16(a2)
465         daddu   ta2,t2
466         sltu    t8,ta2,t2
467         daddu   t2,ta2,v0
468         sltu    v0,t2,ta2
469         sd      t2,16(a0)
470         daddu   v0,t8
471         jr      ra
472 END(bn_add_words)
473
474 LEAF(bn_sub_words)
475         .align  5
476         .set    noreorder
477         bgtzl   a3,.L_bn_sub_words_proceed
478         ld      t0,0(a1)
479         jr      ra
480         move    v0,zero
481         .set    reorder
482
483 .L_bn_sub_words_proceed:
484         li      MINUS4,-4
485         and     AT,a3,MINUS4
486         move    v0,zero
487         beqz    AT,.L_bn_sub_words_tail
488
489 .L_bn_sub_words_loop:
490         ld      ta0,0(a2)
491         ld      t1,8(a1)
492         ld      ta1,8(a2)
493         ld      t2,16(a1)
494         ld      ta2,16(a2)
495         ld      t3,24(a1)
496         ld      ta3,24(a2)
497         sltu    t8,t0,ta0
498         dsubu   t0,ta0
499         subu    a3,4
500         dsubu   ta0,t0,v0
501         and     AT,a3,MINUS4
502         sd      ta0,0(a0)
503         MOVNZ   (t0,v0,t8)
504
505         sltu    t9,t1,ta1
506         dsubu   t1,ta1
507         PTR_ADD a0,32
508         dsubu   ta1,t1,v0
509         PTR_ADD a1,32
510         sd      ta1,-24(a0)
511         MOVNZ   (t1,v0,t9)
512
513
514         sltu    t8,t2,ta2
515         dsubu   t2,ta2
516         dsubu   ta2,t2,v0
517         PTR_ADD a2,32
518         sd      ta2,-16(a0)
519         MOVNZ   (t2,v0,t8)
520
521         sltu    t9,t3,ta3
522         dsubu   t3,ta3
523         dsubu   ta3,t3,v0
524         sd      ta3,-8(a0)
525         MOVNZ   (t3,v0,t9)
526
527         .set    noreorder
528         bgtzl   AT,.L_bn_sub_words_loop
529         ld      t0,0(a1)
530
531         bnezl   a3,.L_bn_sub_words_tail
532         ld      t0,0(a1)
533         .set    reorder
534
535 .L_bn_sub_words_return:
536         jr      ra
537
538 .L_bn_sub_words_tail:
539         ld      ta0,0(a2)
540         subu    a3,1
541         sltu    t8,t0,ta0
542         dsubu   t0,ta0
543         dsubu   ta0,t0,v0
544         MOVNZ   (t0,v0,t8)
545         sd      ta0,0(a0)
546         beqz    a3,.L_bn_sub_words_return
547
548         ld      t1,8(a1)
549         subu    a3,1
550         ld      ta1,8(a2)
551         sltu    t9,t1,ta1
552         dsubu   t1,ta1
553         dsubu   ta1,t1,v0
554         MOVNZ   (t1,v0,t9)
555         sd      ta1,8(a0)
556         beqz    a3,.L_bn_sub_words_return
557
558         ld      t2,16(a1)
559         ld      ta2,16(a2)
560         sltu    t8,t2,ta2
561         dsubu   t2,ta2
562         dsubu   ta2,t2,v0
563         MOVNZ   (t2,v0,t8)
564         sd      ta2,16(a0)
565         jr      ra
566 END(bn_sub_words)
567
568 #undef  MINUS4
569
570 LEAF(bn_div_words)
571         .align  5
572         .set    noreorder
573         bnezl   a2,.L_bn_div_words_proceed
574         move    t0,zero
575         jr      ra
576         li      v0,-1           /* I'd rather signal div-by-zero
577                                  * which can be done with 'break 7' */
578         .set    reorder
579
580 .L_bn_div_words_proceed:
581         bltz    a2,.L_bn_div_words_body
582         .set    noreorder
583         dsll    a2,1
584         bgtz    a2,.-4
585         addu    t0,1
586         .set    reorder
587         negu    t1,t0
588         li      t2,-1
589         dsll    t2,t1
590         and     t2,a0
591         dsrl    AT,a1,t1
592         .set    noreorder
593         bnezl   t2,.+8
594         break   6               /* signal overflow */
595         .set    reorder
596         dsll    a0,t0
597         dsll    a1,t0
598         or      a0,AT
599
600 #define QT      ta0
601 #define DH      ta1
602 #define HH      ta2
603 #define MINUS1  ta3
604 .L_bn_div_words_body:
605         dsrl    DH,a2,32
606         li      v1,2
607         sgeu    AT,a0,a2
608         li      MINUS1,-1
609         .set    noreorder
610         bnezl   AT,.+8
611         dsubu   a0,a2
612         .set    reorder
613
614 .L_bn_div_words_outer_loop:
615         dsrl    HH,a0,32
616         subu    v1,1
617         dsrl    QT,MINUS1,32    /* q=0xffffffff */
618         beq     DH,HH,.L_bn_div_words_inner_loop
619         ddivu   zero,a0,DH
620         mflo    QT
621 .L_bn_div_words_inner_loop:
622         dmultu  a2,QT
623         dsll    t3,a0,32
624         dsrl    AT,a1,32
625         or      t3,AT
626         mflo    t0
627         mfhi    t1
628         sltu    t2,t3,t0
629         seq     t8,HH,t1
630         sltu    AT,HH,t1
631         and     t2,t8
632         or      AT,t2
633         .set    noreorder
634         bnezl   AT,.L_bn_div_words_inner_loop
635         dsubu   QT,1
636         .set    reorder
637         
638         dsubu   a0,t3,t0
639         beqz    v1,.L_bn_div_words_outer_loop_done
640
641         dsll    a1,32
642         dsll    v0,QT,32
643         b       .L_bn_div_words_outer_loop
644
645 .L_bn_div_words_outer_loop_done:
646         or      v0,QT
647         move    v1,a0   /* v1 contains remainder if one wants it */
648         jr      ra
649 #undef  MINUS1
650 #undef  HH
651 #undef  DH
652 #undef  QT
653 END(bn_div_words)
654
655 #define a_0     t0
656 #define a_1     t1
657 #define a_2     t2
658 #define a_3     t3
659 #define b_0     ta0
660 #define b_1     ta1
661 #define b_2     ta2
662 #define b_3     ta3
663
664 #define a_4     s0
665 #define a_5     s2
666 #define a_6     s4
667 #define a_7     a1      /* once we load a[7] we don't need a anymore */
668 #define b_4     s1
669 #define b_5     s3
670 #define b_6     s5
671 #define b_7     a2      /* once we load b[7] we don't need b anymore */
672
673 #define t_1     t8
674 #define t_2     t9
675
676 #define c_1     v0
677 #define c_2     v1
678 #define c_3     a3
679
680 #define FRAME_SIZE      48
681
682 LEAF(bn_mul_comba8)
683         .align  5
684         .set    noreorder
685         PTR_SUB sp,FRAME_SIZE
686         .frame  sp,64,ra
687         .set    reorder
688         ld      a_0,0(a1)       /* If compiled with -mips3 options
689                                  * assembler barks on this line with
690                                  * "shouldn't have mult/div as last
691                                  * instruction in bb (R10K bug)"
692                                  * warning. If anybody out there has
693                                  * a clue on what does "bb" mean and
694                                  * how to circumvent this do send me
695                                  * a note.
696                                  *              <appro@fy.chalmers.se>
697                                  */
698         ld      b_0,0(a2)
699         ld      a_1,8(a1)
700         ld      a_2,16(a1)
701         ld      a_3,24(a1)
702         ld      b_1,8(a2)
703         ld      b_2,16(a2)
704         ld      b_3,24(a2)
705         dmultu  a_0,b_0         /* mul_add_c(a[0],b[0],c1,c2,c3); */
706         sd      s0,0(sp)
707         sd      s1,8(sp)
708         sd      s2,16(sp)
709         sd      s3,24(sp)
710         sd      s4,32(sp)
711         sd      s5,40(sp)
712         mflo    c_1
713         mfhi    c_2
714
715         dmultu  a_0,b_1         /* mul_add_c(a[0],b[1],c2,c3,c1); */
716         ld      a_4,32(a1)
717         ld      a_5,40(a1)
718         ld      a_6,48(a1)
719         ld      a_7,56(a1)
720         ld      b_4,32(a2)
721         ld      b_5,40(a2)
722         mflo    t_1
723         mfhi    t_2
724         daddu   c_2,t_1
725         sltu    AT,c_2,t_1
726         daddu   c_3,t_2,AT
727         dmultu  a_1,b_0         /* mul_add_c(a[1],b[0],c2,c3,c1); */
728         ld      b_6,48(a2)
729         ld      b_7,56(a2)
730         sd      c_1,0(a0)       /* r[0]=c1; */
731         mflo    t_1
732         mfhi    t_2
733         daddu   c_2,t_1
734         sltu    AT,c_2,t_1
735         daddu   t_2,AT
736         daddu   c_3,t_2
737         sltu    c_1,c_3,t_2
738         sd      c_2,8(a0)       /* r[1]=c2; */
739
740         dmultu  a_2,b_0         /* mul_add_c(a[2],b[0],c3,c1,c2); */
741         mflo    t_1
742         mfhi    t_2
743         daddu   c_3,t_1
744         sltu    AT,c_3,t_1
745         daddu   t_2,AT
746         daddu   c_1,t_2
747         dmultu  a_1,b_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
748         mflo    t_1
749         mfhi    t_2
750         daddu   c_3,t_1
751         sltu    AT,c_3,t_1
752         daddu   t_2,AT
753         daddu   c_1,t_2
754         sltu    c_2,c_1,t_2
755         dmultu  a_0,b_2         /* mul_add_c(a[0],b[2],c3,c1,c2); */
756         mflo    t_1
757         mfhi    t_2
758         daddu   c_3,t_1
759         sltu    AT,c_3,t_1
760         daddu   t_2,AT
761         daddu   c_1,t_2
762         sltu    AT,c_1,t_2
763         daddu   c_2,AT
764         sd      c_3,16(a0)      /* r[2]=c3; */
765
766         dmultu  a_0,b_3         /* mul_add_c(a[0],b[3],c1,c2,c3); */
767         mflo    t_1
768         mfhi    t_2
769         daddu   c_1,t_1
770         sltu    AT,c_1,t_1
771         daddu   t_2,AT
772         daddu   c_2,t_2
773         dmultu  a_1,b_2         /* mul_add_c(a[1],b[2],c1,c2,c3); */
774         mflo    t_1
775         mfhi    t_2
776         daddu   c_1,t_1
777         sltu    AT,c_1,t_1
778         daddu   t_2,AT
779         daddu   c_2,t_2
780         sltu    c_3,c_2,t_2
781         dmultu  a_2,b_1         /* mul_add_c(a[2],b[1],c1,c2,c3); */
782         mflo    t_1
783         mfhi    t_2
784         daddu   c_1,t_1
785         sltu    AT,c_1,t_1
786         daddu   t_2,AT
787         daddu   c_2,t_2
788         sltu    AT,c_2,t_2
789         daddu   c_3,AT
790         dmultu  a_3,b_0         /* mul_add_c(a[3],b[0],c1,c2,c3); */
791         mflo    t_1
792         mfhi    t_2
793         daddu   c_1,t_1
794         sltu    AT,c_1,t_1
795         daddu   t_2,AT
796         daddu   c_2,t_2
797         sltu    AT,c_2,t_2
798         daddu   c_3,AT
799         sd      c_1,24(a0)      /* r[3]=c1; */
800
801         dmultu  a_4,b_0         /* mul_add_c(a[4],b[0],c2,c3,c1); */
802         mflo    t_1
803         mfhi    t_2
804         daddu   c_2,t_1
805         sltu    AT,c_2,t_1
806         daddu   t_2,AT
807         daddu   c_3,t_2
808         dmultu  a_3,b_1         /* mul_add_c(a[3],b[1],c2,c3,c1); */
809         mflo    t_1
810         mfhi    t_2
811         daddu   c_2,t_1
812         sltu    AT,c_2,t_1
813         daddu   t_2,AT
814         daddu   c_3,t_2
815         sltu    c_1,c_3,t_2
816         dmultu  a_2,b_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
817         mflo    t_1
818         mfhi    t_2
819         daddu   c_2,t_1
820         sltu    AT,c_2,t_1
821         daddu   t_2,AT
822         daddu   c_3,t_2
823         sltu    AT,c_3,t_2
824         daddu   c_1,AT
825         dmultu  a_1,b_3         /* mul_add_c(a[1],b[3],c2,c3,c1); */
826         mflo    t_1
827         mfhi    t_2
828         daddu   c_2,t_1
829         sltu    AT,c_2,t_1
830         daddu   t_2,AT
831         daddu   c_3,t_2
832         sltu    AT,c_3,t_2
833         daddu   c_1,AT
834         dmultu  a_0,b_4         /* mul_add_c(a[0],b[4],c2,c3,c1); */
835         mflo    t_1
836         mfhi    t_2
837         daddu   c_2,t_1
838         sltu    AT,c_2,t_1
839         daddu   t_2,AT
840         daddu   c_3,t_2
841         sltu    AT,c_3,t_2
842         daddu   c_1,AT
843         sd      c_2,32(a0)      /* r[4]=c2; */
844
845         dmultu  a_0,b_5         /* mul_add_c(a[0],b[5],c3,c1,c2); */
846         mflo    t_1
847         mfhi    t_2
848         daddu   c_3,t_1
849         sltu    AT,c_3,t_1
850         daddu   t_2,AT
851         daddu   c_1,t_2
852         dmultu  a_1,b_4         /* mul_add_c(a[1],b[4],c3,c1,c2); */
853         mflo    t_1
854         mfhi    t_2
855         daddu   c_3,t_1
856         sltu    AT,c_3,t_1
857         daddu   t_2,AT
858         daddu   c_1,t_2
859         sltu    c_2,c_1,t_2
860         dmultu  a_2,b_3         /* mul_add_c(a[2],b[3],c3,c1,c2); */
861         mflo    t_1
862         mfhi    t_2
863         daddu   c_3,t_1
864         sltu    AT,c_3,t_1
865         daddu   t_2,AT
866         daddu   c_1,t_2
867         sltu    AT,c_1,t_2
868         daddu   c_2,AT
869         dmultu  a_3,b_2         /* mul_add_c(a[3],b[2],c3,c1,c2); */
870         mflo    t_1
871         mfhi    t_2
872         daddu   c_3,t_1
873         sltu    AT,c_3,t_1
874         daddu   t_2,AT
875         daddu   c_1,t_2
876         sltu    AT,c_1,t_2
877         daddu   c_2,AT
878         dmultu  a_4,b_1         /* mul_add_c(a[4],b[1],c3,c1,c2); */
879         mflo    t_1
880         mfhi    t_2
881         daddu   c_3,t_1
882         sltu    AT,c_3,t_1
883         daddu   t_2,AT
884         daddu   c_1,t_2
885         sltu    AT,c_1,t_2
886         daddu   c_2,AT
887         dmultu  a_5,b_0         /* mul_add_c(a[5],b[0],c3,c1,c2); */
888         mflo    t_1
889         mfhi    t_2
890         daddu   c_3,t_1
891         sltu    AT,c_3,t_1
892         daddu   t_2,AT
893         daddu   c_1,t_2
894         sltu    AT,c_1,t_2
895         daddu   c_2,AT
896         sd      c_3,40(a0)      /* r[5]=c3; */
897
898         dmultu  a_6,b_0         /* mul_add_c(a[6],b[0],c1,c2,c3); */
899         mflo    t_1
900         mfhi    t_2
901         daddu   c_1,t_1
902         sltu    AT,c_1,t_1
903         daddu   t_2,AT
904         daddu   c_2,t_2
905         dmultu  a_5,b_1         /* mul_add_c(a[5],b[1],c1,c2,c3); */
906         mflo    t_1
907         mfhi    t_2
908         daddu   c_1,t_1
909         sltu    AT,c_1,t_1
910         daddu   t_2,AT
911         daddu   c_2,t_2
912         sltu    c_3,c_2,t_2
913         dmultu  a_4,b_2         /* mul_add_c(a[4],b[2],c1,c2,c3); */
914         mflo    t_1
915         mfhi    t_2
916         daddu   c_1,t_1
917         sltu    AT,c_1,t_1
918         daddu   t_2,AT
919         daddu   c_2,t_2
920         sltu    AT,c_2,t_2
921         daddu   c_3,AT
922         dmultu  a_3,b_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */
923         mflo    t_1
924         mfhi    t_2
925         daddu   c_1,t_1
926         sltu    AT,c_1,t_1
927         daddu   t_2,AT
928         daddu   c_2,t_2
929         sltu    AT,c_2,t_2
930         daddu   c_3,AT
931         dmultu  a_2,b_4         /* mul_add_c(a[2],b[4],c1,c2,c3); */
932         mflo    t_1
933         mfhi    t_2
934         daddu   c_1,t_1
935         sltu    AT,c_1,t_1
936         daddu   t_2,AT
937         daddu   c_2,t_2
938         sltu    AT,c_2,t_2
939         daddu   c_3,AT
940         dmultu  a_1,b_5         /* mul_add_c(a[1],b[5],c1,c2,c3); */
941         mflo    t_1
942         mfhi    t_2
943         daddu   c_1,t_1
944         sltu    AT,c_1,t_1
945         daddu   t_2,AT
946         daddu   c_2,t_2
947         sltu    AT,c_2,t_2
948         daddu   c_3,AT
949         dmultu  a_0,b_6         /* mul_add_c(a[0],b[6],c1,c2,c3); */
950         mflo    t_1
951         mfhi    t_2
952         daddu   c_1,t_1
953         sltu    AT,c_1,t_1
954         daddu   t_2,AT
955         daddu   c_2,t_2
956         sltu    AT,c_2,t_2
957         daddu   c_3,AT
958         sd      c_1,48(a0)      /* r[6]=c1; */
959
960         dmultu  a_0,b_7         /* mul_add_c(a[0],b[7],c2,c3,c1); */
961         mflo    t_1
962         mfhi    t_2
963         daddu   c_2,t_1
964         sltu    AT,c_2,t_1
965         daddu   t_2,AT
966         daddu   c_3,t_2
967         dmultu  a_1,b_6         /* mul_add_c(a[1],b[6],c2,c3,c1); */
968         mflo    t_1
969         mfhi    t_2
970         daddu   c_2,t_1
971         sltu    AT,c_2,t_1
972         daddu   t_2,AT
973         daddu   c_3,t_2
974         sltu    c_1,c_3,t_2
975         dmultu  a_2,b_5         /* mul_add_c(a[2],b[5],c2,c3,c1); */
976         mflo    t_1
977         mfhi    t_2
978         daddu   c_2,t_1
979         sltu    AT,c_2,t_1
980         daddu   t_2,AT
981         daddu   c_3,t_2
982         sltu    AT,c_3,t_2
983         daddu   c_1,AT
984         dmultu  a_3,b_4         /* mul_add_c(a[3],b[4],c2,c3,c1); */
985         mflo    t_1
986         mfhi    t_2
987         daddu   c_2,t_1
988         sltu    AT,c_2,t_1
989         daddu   t_2,AT
990         daddu   c_3,t_2
991         sltu    AT,c_3,t_2
992         daddu   c_1,AT
993         dmultu  a_4,b_3         /* mul_add_c(a[4],b[3],c2,c3,c1); */
994         mflo    t_1
995         mfhi    t_2
996         daddu   c_2,t_1
997         sltu    AT,c_2,t_1
998         daddu   t_2,AT
999         daddu   c_3,t_2
1000         sltu    AT,c_3,t_2
1001         daddu   c_1,AT
1002         dmultu  a_5,b_2         /* mul_add_c(a[5],b[2],c2,c3,c1); */
1003         mflo    t_1
1004         mfhi    t_2
1005         daddu   c_2,t_1
1006         sltu    AT,c_2,t_1
1007         daddu   t_2,AT
1008         daddu   c_3,t_2
1009         sltu    AT,c_3,t_2
1010         daddu   c_1,AT
1011         dmultu  a_6,b_1         /* mul_add_c(a[6],b[1],c2,c3,c1); */
1012         mflo    t_1
1013         mfhi    t_2
1014         daddu   c_2,t_1
1015         sltu    AT,c_2,t_1
1016         daddu   t_2,AT
1017         daddu   c_3,t_2
1018         sltu    AT,c_3,t_2
1019         daddu   c_1,AT
1020         dmultu  a_7,b_0         /* mul_add_c(a[7],b[0],c2,c3,c1); */
1021         mflo    t_1
1022         mfhi    t_2
1023         daddu   c_2,t_1
1024         sltu    AT,c_2,t_1
1025         daddu   t_2,AT
1026         daddu   c_3,t_2
1027         sltu    AT,c_3,t_2
1028         daddu   c_1,AT
1029         sd      c_2,56(a0)      /* r[7]=c2; */
1030
1031         dmultu  a_7,b_1         /* mul_add_c(a[7],b[1],c3,c1,c2); */
1032         mflo    t_1
1033         mfhi    t_2
1034         daddu   c_3,t_1
1035         sltu    AT,c_3,t_1
1036         daddu   t_2,AT
1037         daddu   c_1,t_2
1038         dmultu  a_6,b_2         /* mul_add_c(a[6],b[2],c3,c1,c2); */
1039         mflo    t_1
1040         mfhi    t_2
1041         daddu   c_3,t_1
1042         sltu    AT,c_3,t_1
1043         daddu   t_2,AT
1044         daddu   c_1,t_2
1045         sltu    c_2,c_1,t_2
1046         dmultu  a_5,b_3         /* mul_add_c(a[5],b[3],c3,c1,c2); */
1047         mflo    t_1
1048         mfhi    t_2
1049         daddu   c_3,t_1
1050         sltu    AT,c_3,t_1
1051         daddu   t_2,AT
1052         daddu   c_1,t_2
1053         sltu    AT,c_1,t_2
1054         daddu   c_2,AT
1055         dmultu  a_4,b_4         /* mul_add_c(a[4],b[4],c3,c1,c2); */
1056         mflo    t_1
1057         mfhi    t_2
1058         daddu   c_3,t_1
1059         sltu    AT,c_3,t_1
1060         daddu   t_2,AT
1061         daddu   c_1,t_2
1062         sltu    AT,c_1,t_2
1063         daddu   c_2,AT
1064         dmultu  a_3,b_5         /* mul_add_c(a[3],b[5],c3,c1,c2); */
1065         mflo    t_1
1066         mfhi    t_2
1067         daddu   c_3,t_1
1068         sltu    AT,c_3,t_1
1069         daddu   t_2,AT
1070         daddu   c_1,t_2
1071         sltu    AT,c_1,t_2
1072         daddu   c_2,AT
1073         dmultu  a_2,b_6         /* mul_add_c(a[2],b[6],c3,c1,c2); */
1074         mflo    t_1
1075         mfhi    t_2
1076         daddu   c_3,t_1
1077         sltu    AT,c_3,t_1
1078         daddu   t_2,AT
1079         daddu   c_1,t_2
1080         sltu    AT,c_1,t_2
1081         daddu   c_2,AT
1082         dmultu  a_1,b_7         /* mul_add_c(a[1],b[7],c3,c1,c2); */
1083         mflo    t_1
1084         mfhi    t_2
1085         daddu   c_3,t_1
1086         sltu    AT,c_3,t_1
1087         daddu   t_2,AT
1088         daddu   c_1,t_2
1089         sltu    AT,c_1,t_2
1090         daddu   c_2,AT
1091         sd      c_3,64(a0)      /* r[8]=c3; */
1092
1093         dmultu  a_2,b_7         /* mul_add_c(a[2],b[7],c1,c2,c3); */
1094         mflo    t_1
1095         mfhi    t_2
1096         daddu   c_1,t_1
1097         sltu    AT,c_1,t_1
1098         daddu   t_2,AT
1099         daddu   c_2,t_2
1100         dmultu  a_3,b_6         /* mul_add_c(a[3],b[6],c1,c2,c3); */
1101         mflo    t_1
1102         mfhi    t_2
1103         daddu   c_1,t_1
1104         sltu    AT,c_1,t_1
1105         daddu   t_2,AT
1106         daddu   c_2,t_2
1107         sltu    c_3,c_2,t_2
1108         dmultu  a_4,b_5         /* mul_add_c(a[4],b[5],c1,c2,c3); */
1109         mflo    t_1
1110         mfhi    t_2
1111         daddu   c_1,t_1
1112         sltu    AT,c_1,t_1
1113         daddu   t_2,AT
1114         daddu   c_2,t_2
1115         sltu    AT,c_2,t_2
1116         daddu   c_3,AT
1117         dmultu  a_5,b_4         /* mul_add_c(a[5],b[4],c1,c2,c3); */
1118         mflo    t_1
1119         mfhi    t_2
1120         daddu   c_1,t_1
1121         sltu    AT,c_1,t_1
1122         daddu   t_2,AT
1123         daddu   c_2,t_2
1124         sltu    AT,c_2,t_2
1125         daddu   c_3,AT
1126         dmultu  a_6,b_3         /* mul_add_c(a[6],b[3],c1,c2,c3); */
1127         mflo    t_1
1128         mfhi    t_2
1129         daddu   c_1,t_1
1130         sltu    AT,c_1,t_1
1131         daddu   t_2,AT
1132         daddu   c_2,t_2
1133         sltu    AT,c_2,t_2
1134         daddu   c_3,AT
1135         dmultu  a_7,b_2         /* mul_add_c(a[7],b[2],c1,c2,c3); */
1136         mflo    t_1
1137         mfhi    t_2
1138         daddu   c_1,t_1
1139         sltu    AT,c_1,t_1
1140         daddu   t_2,AT
1141         daddu   c_2,t_2
1142         sltu    AT,c_2,t_2
1143         daddu   c_3,AT
1144         sd      c_1,72(a0)      /* r[9]=c1; */
1145
1146         dmultu  a_7,b_3         /* mul_add_c(a[7],b[3],c2,c3,c1); */
1147         mflo    t_1
1148         mfhi    t_2
1149         daddu   c_2,t_1
1150         sltu    AT,c_2,t_1
1151         daddu   t_2,AT
1152         daddu   c_3,t_2
1153         dmultu  a_6,b_4         /* mul_add_c(a[6],b[4],c2,c3,c1); */
1154         mflo    t_1
1155         mfhi    t_2
1156         daddu   c_2,t_1
1157         sltu    AT,c_2,t_1
1158         daddu   t_2,AT
1159         daddu   c_3,t_2
1160         sltu    c_1,c_3,t_2
1161         dmultu  a_5,b_5         /* mul_add_c(a[5],b[5],c2,c3,c1); */
1162         mflo    t_1
1163         mfhi    t_2
1164         daddu   c_2,t_1
1165         sltu    AT,c_2,t_1
1166         daddu   t_2,AT
1167         daddu   c_3,t_2
1168         sltu    AT,c_3,t_2
1169         daddu   c_1,AT
1170         dmultu  a_4,b_6         /* mul_add_c(a[4],b[6],c2,c3,c1); */
1171         mflo    t_1
1172         mfhi    t_2
1173         daddu   c_2,t_1
1174         sltu    AT,c_2,t_1
1175         daddu   t_2,AT
1176         daddu   c_3,t_2
1177         sltu    AT,c_3,t_2
1178         daddu   c_1,AT
1179         dmultu  a_3,b_7         /* mul_add_c(a[3],b[7],c2,c3,c1); */
1180         mflo    t_1
1181         mfhi    t_2
1182         daddu   c_2,t_1
1183         sltu    AT,c_2,t_1
1184         daddu   t_2,AT
1185         daddu   c_3,t_2
1186         sltu    AT,c_3,t_2
1187         daddu   c_1,AT
1188         sd      c_2,80(a0)      /* r[10]=c2; */
1189
1190         dmultu  a_4,b_7         /* mul_add_c(a[4],b[7],c3,c1,c2); */
1191         mflo    t_1
1192         mfhi    t_2
1193         daddu   c_3,t_1
1194         sltu    AT,c_3,t_1
1195         daddu   t_2,AT
1196         daddu   c_1,t_2
1197         dmultu  a_5,b_6         /* mul_add_c(a[5],b[6],c3,c1,c2); */
1198         mflo    t_1
1199         mfhi    t_2
1200         daddu   c_3,t_1
1201         sltu    AT,c_3,t_1
1202         daddu   t_2,AT
1203         daddu   c_1,t_2
1204         sltu    c_2,c_1,t_2
1205         dmultu  a_6,b_5         /* mul_add_c(a[6],b[5],c3,c1,c2); */
1206         mflo    t_1
1207         mfhi    t_2
1208         daddu   c_3,t_1
1209         sltu    AT,c_3,t_1
1210         daddu   t_2,AT
1211         daddu   c_1,t_2
1212         sltu    AT,c_1,t_2
1213         daddu   c_2,AT
1214         dmultu  a_7,b_4         /* mul_add_c(a[7],b[4],c3,c1,c2); */
1215         mflo    t_1
1216         mfhi    t_2
1217         daddu   c_3,t_1
1218         sltu    AT,c_3,t_1
1219         daddu   t_2,AT
1220         daddu   c_1,t_2
1221         sltu    AT,c_1,t_2
1222         daddu   c_2,AT
1223         sd      c_3,88(a0)      /* r[11]=c3; */
1224
1225         dmultu  a_7,b_5         /* mul_add_c(a[7],b[5],c1,c2,c3); */
1226         mflo    t_1
1227         mfhi    t_2
1228         daddu   c_1,t_1
1229         sltu    AT,c_1,t_1
1230         daddu   t_2,AT
1231         daddu   c_2,t_2
1232         dmultu  a_6,b_6         /* mul_add_c(a[6],b[6],c1,c2,c3); */
1233         mflo    t_1
1234         mfhi    t_2
1235         daddu   c_1,t_1
1236         sltu    AT,c_1,t_1
1237         daddu   t_2,AT
1238         daddu   c_2,t_2
1239         sltu    c_3,c_2,t_2
1240         dmultu  a_5,b_7         /* mul_add_c(a[5],b[7],c1,c2,c3); */
1241         mflo    t_1
1242         mfhi    t_2
1243         daddu   c_1,t_1
1244         sltu    AT,c_1,t_1
1245         daddu   t_2,AT
1246         daddu   c_2,t_2
1247         sltu    AT,c_2,t_2
1248         daddu   c_3,AT
1249         sd      c_1,96(a0)      /* r[12]=c1; */
1250
1251         dmultu  a_6,b_7         /* mul_add_c(a[6],b[7],c2,c3,c1); */
1252         mflo    t_1
1253         mfhi    t_2
1254         daddu   c_2,t_1
1255         sltu    AT,c_2,t_1
1256         daddu   t_2,AT
1257         daddu   c_3,t_2
1258         dmultu  a_7,b_6         /* mul_add_c(a[7],b[6],c2,c3,c1); */
1259         mflo    t_1
1260         mfhi    t_2
1261         daddu   c_2,t_1
1262         sltu    AT,c_2,t_1
1263         daddu   t_2,AT
1264         daddu   c_3,t_2
1265         sltu    c_1,c_3,t_2
1266         sd      c_2,104(a0)     /* r[13]=c2; */
1267
1268         dmultu  a_7,b_7         /* mul_add_c(a[7],b[7],c3,c1,c2); */
1269         ld      s0,0(sp)
1270         ld      s1,8(sp)
1271         ld      s2,16(sp)
1272         ld      s3,24(sp)
1273         ld      s4,32(sp)
1274         ld      s5,40(sp)
1275         mflo    t_1
1276         mfhi    t_2
1277         daddu   c_3,t_1
1278         sltu    AT,c_3,t_1
1279         daddu   t_2,AT
1280         daddu   c_1,t_2
1281         sd      c_3,112(a0)     /* r[14]=c3; */
1282         sd      c_1,120(a0)     /* r[15]=c1; */
1283
1284         PTR_ADD sp,FRAME_SIZE
1285
1286         jr      ra
1287 END(bn_mul_comba8)
1288
1289 LEAF(bn_mul_comba4)
1290         .align  5
1291         .set    reorder
1292         ld      a_0,0(a1)
1293         ld      b_0,0(a2)
1294         ld      a_1,8(a1)
1295         ld      a_2,16(a1)
1296         dmultu  a_0,b_0         /* mul_add_c(a[0],b[0],c1,c2,c3); */
1297         ld      a_3,24(a1)
1298         ld      b_1,8(a2)
1299         ld      b_2,16(a2)
1300         ld      b_3,24(a2)
1301         mflo    c_1
1302         mfhi    c_2
1303         sd      c_1,0(a0)
1304
1305         dmultu  a_0,b_1         /* mul_add_c(a[0],b[1],c2,c3,c1); */
1306         mflo    t_1
1307         mfhi    t_2
1308         daddu   c_2,t_1
1309         sltu    AT,c_2,t_1
1310         daddu   c_3,t_2,AT
1311         dmultu  a_1,b_0         /* mul_add_c(a[1],b[0],c2,c3,c1); */
1312         mflo    t_1
1313         mfhi    t_2
1314         daddu   c_2,t_1
1315         sltu    AT,c_2,t_1
1316         daddu   t_2,AT
1317         daddu   c_3,t_2
1318         sltu    c_1,c_3,t_2
1319         sd      c_2,8(a0)
1320
1321         dmultu  a_2,b_0         /* mul_add_c(a[2],b[0],c3,c1,c2); */
1322         mflo    t_1
1323         mfhi    t_2
1324         daddu   c_3,t_1
1325         sltu    AT,c_3,t_1
1326         daddu   t_2,AT
1327         daddu   c_1,t_2
1328         dmultu  a_1,b_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
1329         mflo    t_1
1330         mfhi    t_2
1331         daddu   c_3,t_1
1332         sltu    AT,c_3,t_1
1333         daddu   t_2,AT
1334         daddu   c_1,t_2
1335         sltu    c_2,c_1,t_2
1336         dmultu  a_0,b_2         /* mul_add_c(a[0],b[2],c3,c1,c2); */
1337         mflo    t_1
1338         mfhi    t_2
1339         daddu   c_3,t_1
1340         sltu    AT,c_3,t_1
1341         daddu   t_2,AT
1342         daddu   c_1,t_2
1343         sltu    AT,c_1,t_2
1344         daddu   c_2,AT
1345         sd      c_3,16(a0)
1346
1347         dmultu  a_0,b_3         /* mul_add_c(a[0],b[3],c1,c2,c3); */
1348         mflo    t_1
1349         mfhi    t_2
1350         daddu   c_1,t_1
1351         sltu    AT,c_1,t_1
1352         daddu   t_2,AT
1353         daddu   c_2,t_2
1354         dmultu  a_1,b_2         /* mul_add_c(a[1],b[2],c1,c2,c3); */
1355         mflo    t_1
1356         mfhi    t_2
1357         daddu   c_1,t_1
1358         sltu    AT,c_1,t_1
1359         daddu   t_2,AT
1360         daddu   c_2,t_2
1361         sltu    c_3,c_2,t_2
1362         dmultu  a_2,b_1         /* mul_add_c(a[2],b[1],c1,c2,c3); */
1363         mflo    t_1
1364         mfhi    t_2
1365         daddu   c_1,t_1
1366         sltu    AT,c_1,t_1
1367         daddu   t_2,AT
1368         daddu   c_2,t_2
1369         sltu    AT,c_2,t_2
1370         daddu   c_3,AT
1371         dmultu  a_3,b_0         /* mul_add_c(a[3],b[0],c1,c2,c3); */
1372         mflo    t_1
1373         mfhi    t_2
1374         daddu   c_1,t_1
1375         sltu    AT,c_1,t_1
1376         daddu   t_2,AT
1377         daddu   c_2,t_2
1378         sltu    AT,c_2,t_2
1379         daddu   c_3,AT
1380         sd      c_1,24(a0)
1381
1382         dmultu  a_3,b_1         /* mul_add_c(a[3],b[1],c2,c3,c1); */
1383         mflo    t_1
1384         mfhi    t_2
1385         daddu   c_2,t_1
1386         sltu    AT,c_2,t_1
1387         daddu   t_2,AT
1388         daddu   c_3,t_2
1389         dmultu  a_2,b_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
1390         mflo    t_1
1391         mfhi    t_2
1392         daddu   c_2,t_1
1393         sltu    AT,c_2,t_1
1394         daddu   t_2,AT
1395         daddu   c_3,t_2
1396         sltu    c_1,c_3,t_2
1397         dmultu  a_1,b_3         /* mul_add_c(a[1],b[3],c2,c3,c1); */
1398         mflo    t_1
1399         mfhi    t_2
1400         daddu   c_2,t_1
1401         sltu    AT,c_2,t_1
1402         daddu   t_2,AT
1403         daddu   c_3,t_2
1404         sltu    AT,c_3,t_2
1405         daddu   c_1,AT
1406         sd      c_2,32(a0)
1407
1408         dmultu  a_2,b_3         /* mul_add_c(a[2],b[3],c3,c1,c2); */
1409         mflo    t_1
1410         mfhi    t_2
1411         daddu   c_3,t_1
1412         sltu    AT,c_3,t_1
1413         daddu   t_2,AT
1414         daddu   c_1,t_2
1415         dmultu  a_3,b_2         /* mul_add_c(a[3],b[2],c3,c1,c2); */
1416         mflo    t_1
1417         mfhi    t_2
1418         daddu   c_3,t_1
1419         sltu    AT,c_3,t_1
1420         daddu   t_2,AT
1421         daddu   c_1,t_2
1422         sltu    c_2,c_1,t_2
1423         sd      c_3,40(a0)
1424
1425         dmultu  a_3,b_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */
1426         mflo    t_1
1427         mfhi    t_2
1428         daddu   c_1,t_1
1429         sltu    AT,c_1,t_1
1430         daddu   t_2,AT
1431         daddu   c_2,t_2
1432         sd      c_1,48(a0)
1433         sd      c_2,56(a0)
1434
1435         jr      ra
1436 END(bn_mul_comba4)
1437
1438 #undef  a_4
1439 #undef  a_5
1440 #undef  a_6
1441 #undef  a_7
1442 #define a_4     b_0
1443 #define a_5     b_1
1444 #define a_6     b_2
1445 #define a_7     b_3
1446
1447 LEAF(bn_sqr_comba8)
1448         .align  5
1449         .set    reorder
1450         ld      a_0,0(a1)
1451         ld      a_1,8(a1)
1452         ld      a_2,16(a1)
1453         ld      a_3,24(a1)
1454
1455         dmultu  a_0,a_0         /* mul_add_c(a[0],b[0],c1,c2,c3); */
1456         ld      a_4,32(a1)
1457         ld      a_5,40(a1)
1458         ld      a_6,48(a1)
1459         ld      a_7,56(a1)
1460         mflo    c_1
1461         mfhi    c_2
1462         sd      c_1,0(a0)
1463
1464         dmultu  a_0,a_1         /* mul_add_c2(a[0],b[1],c2,c3,c1); */
1465         mflo    t_1
1466         mfhi    t_2
1467         daddu   c_2,t_1
1468         sltu    AT,c_2,t_1
1469         daddu   c_3,t_2,AT
1470         daddu   c_2,t_1
1471         sltu    AT,c_2,t_1
1472         daddu   t_2,AT
1473         daddu   c_3,t_2
1474         sltu    c_1,c_3,t_2
1475         sd      c_2,8(a0)
1476
1477         dmultu  a_2,a_0         /* mul_add_c2(a[2],b[0],c3,c1,c2); */
1478         mflo    t_1
1479         mfhi    t_2
1480         daddu   c_3,t_1
1481         sltu    AT,c_3,t_1
1482         daddu   a2,t_2,AT
1483         daddu   c_1,a2
1484         daddu   c_3,t_1
1485         sltu    AT,c_3,t_1
1486         daddu   t_2,AT
1487         daddu   c_1,t_2
1488         sltu    c_2,c_1,t_2
1489         dmultu  a_1,a_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
1490         mflo    t_1
1491         mfhi    t_2
1492         daddu   c_3,t_1
1493         sltu    AT,c_3,t_1
1494         daddu   t_2,AT
1495         daddu   c_1,t_2
1496         sltu    AT,c_1,t_2
1497         daddu   c_2,AT
1498         sd      c_3,16(a0)
1499
1500         dmultu  a_0,a_3         /* mul_add_c2(a[0],b[3],c1,c2,c3); */
1501         mflo    t_1
1502         mfhi    t_2
1503         daddu   c_1,t_1
1504         sltu    AT,c_1,t_1
1505         daddu   a2,t_2,AT
1506         daddu   c_2,a2
1507         daddu   c_1,t_1
1508         sltu    AT,c_1,t_1
1509         daddu   t_2,AT
1510         daddu   c_2,t_2
1511         sltu    c_3,c_2,t_2
1512         dmultu  a_1,a_2         /* mul_add_c2(a[1],b[2],c1,c2,c3); */
1513         mflo    t_1
1514         mfhi    t_2
1515         daddu   c_1,t_1
1516         sltu    AT,c_1,t_1
1517         daddu   a2,t_2,AT
1518         daddu   c_2,a2
1519         sltu    AT,c_2,a2
1520         daddu   c_3,AT
1521         daddu   c_1,t_1
1522         sltu    AT,c_1,t_1
1523         daddu   t_2,AT
1524         daddu   c_2,t_2
1525         sltu    AT,c_2,t_2
1526         daddu   c_3,AT
1527         sd      c_1,24(a0)
1528
1529         dmultu  a_4,a_0         /* mul_add_c2(a[4],b[0],c2,c3,c1); */
1530         mflo    t_1
1531         mfhi    t_2
1532         daddu   c_2,t_1
1533         sltu    AT,c_2,t_1
1534         daddu   a2,t_2,AT
1535         daddu   c_3,a2
1536         daddu   c_2,t_1
1537         sltu    AT,c_2,t_1
1538         daddu   t_2,AT
1539         daddu   c_3,t_2
1540         sltu    c_1,c_3,t_2
1541         dmultu  a_3,a_1         /* mul_add_c2(a[3],b[1],c2,c3,c1); */
1542         mflo    t_1
1543         mfhi    t_2
1544         daddu   c_2,t_1
1545         sltu    AT,c_2,t_1
1546         daddu   a2,t_2,AT
1547         daddu   c_3,a2
1548         sltu    AT,c_3,a2
1549         daddu   c_1,AT
1550         daddu   c_2,t_1
1551         sltu    AT,c_2,t_1
1552         daddu   t_2,AT
1553         daddu   c_3,t_2
1554         sltu    AT,c_3,t_2
1555         daddu   c_1,AT
1556         dmultu  a_2,a_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
1557         mflo    t_1
1558         mfhi    t_2
1559         daddu   c_2,t_1
1560         sltu    AT,c_2,t_1
1561         daddu   t_2,AT
1562         daddu   c_3,t_2
1563         sltu    AT,c_3,t_2
1564         daddu   c_1,AT
1565         sd      c_2,32(a0)
1566
1567         dmultu  a_0,a_5         /* mul_add_c2(a[0],b[5],c3,c1,c2); */
1568         mflo    t_1
1569         mfhi    t_2
1570         daddu   c_3,t_1
1571         sltu    AT,c_3,t_1
1572         daddu   a2,t_2,AT
1573         daddu   c_1,a2
1574         daddu   c_3,t_1
1575         sltu    AT,c_3,t_1
1576         daddu   t_2,AT
1577         daddu   c_1,t_2
1578         sltu    c_2,c_1,t_2
1579         dmultu  a_1,a_4         /* mul_add_c2(a[1],b[4],c3,c1,c2); */
1580         mflo    t_1
1581         mfhi    t_2
1582         daddu   c_3,t_1
1583         sltu    AT,c_3,t_1
1584         daddu   a2,t_2,AT
1585         daddu   c_1,a2
1586         sltu    AT,c_1,a2
1587         daddu   c_2,AT
1588         daddu   c_3,t_1
1589         sltu    AT,c_3,t_1
1590         daddu   t_2,AT
1591         daddu   c_1,t_2
1592         sltu    AT,c_1,t_2
1593         daddu   c_2,AT
1594         dmultu  a_2,a_3         /* mul_add_c2(a[2],b[3],c3,c1,c2); */
1595         mflo    t_1
1596         mfhi    t_2
1597         daddu   c_3,t_1
1598         sltu    AT,c_3,t_1
1599         daddu   a2,t_2,AT
1600         daddu   c_1,a2
1601         sltu    AT,c_1,a2
1602         daddu   c_2,AT
1603         daddu   c_3,t_1
1604         sltu    AT,c_3,t_1
1605         daddu   t_2,AT
1606         daddu   c_1,t_2
1607         sltu    AT,c_1,t_2
1608         daddu   c_2,AT
1609         sd      c_3,40(a0)
1610
1611         dmultu  a_6,a_0         /* mul_add_c2(a[6],b[0],c1,c2,c3); */
1612         mflo    t_1
1613         mfhi    t_2
1614         daddu   c_1,t_1
1615         sltu    AT,c_1,t_1
1616         daddu   a2,t_2,AT
1617         daddu   c_2,a2
1618         daddu   c_1,t_1
1619         sltu    AT,c_1,t_1
1620         daddu   t_2,AT
1621         daddu   c_2,t_2
1622         sltu    c_3,c_2,t_2
1623         dmultu  a_5,a_1         /* mul_add_c2(a[5],b[1],c1,c2,c3); */
1624         mflo    t_1
1625         mfhi    t_2
1626         daddu   c_1,t_1
1627         sltu    AT,c_1,t_1
1628         daddu   a2,t_2,AT
1629         daddu   c_2,a2
1630         sltu    AT,c_2,a2
1631         daddu   c_3,AT
1632         daddu   c_1,t_1
1633         sltu    AT,c_1,t_1
1634         daddu   t_2,AT
1635         daddu   c_2,t_2
1636         sltu    AT,c_2,t_2
1637         daddu   c_3,AT
1638         dmultu  a_4,a_2         /* mul_add_c2(a[4],b[2],c1,c2,c3); */
1639         mflo    t_1
1640         mfhi    t_2
1641         daddu   c_1,t_1
1642         sltu    AT,c_1,t_1
1643         daddu   a2,t_2,AT
1644         daddu   c_2,a2
1645         sltu    AT,c_2,a2
1646         daddu   c_3,AT
1647         daddu   c_1,t_1
1648         sltu    AT,c_1,t_1
1649         daddu   t_2,AT
1650         daddu   c_2,t_2
1651         sltu    AT,c_2,t_2
1652         daddu   c_3,AT
1653         dmultu  a_3,a_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */
1654         mflo    t_1
1655         mfhi    t_2
1656         daddu   c_1,t_1
1657         sltu    AT,c_1,t_1
1658         daddu   t_2,AT
1659         daddu   c_2,t_2
1660         sltu    AT,c_2,t_2
1661         daddu   c_3,AT
1662         sd      c_1,48(a0)
1663
1664         dmultu  a_0,a_7         /* mul_add_c2(a[0],b[7],c2,c3,c1); */
1665         mflo    t_1
1666         mfhi    t_2
1667         daddu   c_2,t_1
1668         sltu    AT,c_2,t_1
1669         daddu   a2,t_2,AT
1670         daddu   c_3,a2
1671         daddu   c_2,t_1
1672         sltu    AT,c_2,t_1
1673         daddu   t_2,AT
1674         daddu   c_3,t_2
1675         sltu    c_1,c_3,t_2
1676         dmultu  a_1,a_6         /* mul_add_c2(a[1],b[6],c2,c3,c1); */
1677         mflo    t_1
1678         mfhi    t_2
1679         daddu   c_2,t_1
1680         sltu    AT,c_2,t_1
1681         daddu   a2,t_2,AT
1682         daddu   c_3,a2
1683         sltu    AT,c_3,a2
1684         daddu   c_1,AT
1685         daddu   c_2,t_1
1686         sltu    AT,c_2,t_1
1687         daddu   t_2,AT
1688         daddu   c_3,t_2
1689         sltu    AT,c_3,t_2
1690         daddu   c_1,AT
1691         dmultu  a_2,a_5         /* mul_add_c2(a[2],b[5],c2,c3,c1); */
1692         mflo    t_1
1693         mfhi    t_2
1694         daddu   c_2,t_1
1695         sltu    AT,c_2,t_1
1696         daddu   a2,t_2,AT
1697         daddu   c_3,a2
1698         sltu    AT,c_3,a2
1699         daddu   c_1,AT
1700         daddu   c_2,t_1
1701         sltu    AT,c_2,t_1
1702         daddu   t_2,AT
1703         daddu   c_3,t_2
1704         sltu    AT,c_3,t_2
1705         daddu   c_1,AT
1706         dmultu  a_3,a_4         /* mul_add_c2(a[3],b[4],c2,c3,c1); */
1707         mflo    t_1
1708         mfhi    t_2
1709         daddu   c_2,t_1
1710         sltu    AT,c_2,t_1
1711         daddu   a2,t_2,AT
1712         daddu   c_3,a2
1713         sltu    AT,c_3,a2
1714         daddu   c_1,AT
1715         daddu   c_2,t_1
1716         sltu    AT,c_2,t_1
1717         daddu   t_2,AT
1718         daddu   c_3,t_2
1719         sltu    AT,c_3,t_2
1720         daddu   c_1,AT
1721         sd      c_2,56(a0)
1722
1723         dmultu  a_7,a_1         /* mul_add_c2(a[7],b[1],c3,c1,c2); */
1724         mflo    t_1
1725         mfhi    t_2
1726         daddu   c_3,t_1
1727         sltu    AT,c_3,t_1
1728         daddu   a2,t_2,AT
1729         daddu   c_1,a2
1730         daddu   c_3,t_1
1731         sltu    AT,c_3,t_1
1732         daddu   t_2,AT
1733         daddu   c_1,t_2
1734         sltu    c_2,c_1,t_2
1735         dmultu  a_6,a_2         /* mul_add_c2(a[6],b[2],c3,c1,c2); */
1736         mflo    t_1
1737         mfhi    t_2
1738         daddu   c_3,t_1
1739         sltu    AT,c_3,t_1
1740         daddu   a2,t_2,AT
1741         daddu   c_1,a2
1742         sltu    AT,c_1,a2
1743         daddu   c_2,AT
1744         daddu   c_3,t_1
1745         sltu    AT,c_3,t_1
1746         daddu   t_2,AT
1747         daddu   c_1,t_2
1748         sltu    AT,c_1,t_2
1749         daddu   c_2,AT
1750         dmultu  a_5,a_3         /* mul_add_c2(a[5],b[3],c3,c1,c2); */
1751         mflo    t_1
1752         mfhi    t_2
1753         daddu   c_3,t_1
1754         sltu    AT,c_3,t_1
1755         daddu   a2,t_2,AT
1756         daddu   c_1,a2
1757         sltu    AT,c_1,a2
1758         daddu   c_2,AT
1759         daddu   c_3,t_1
1760         sltu    AT,c_3,t_1
1761         daddu   t_2,AT
1762         daddu   c_1,t_2
1763         sltu    AT,c_1,t_2
1764         daddu   c_2,AT
1765         dmultu  a_4,a_4         /* mul_add_c(a[4],b[4],c3,c1,c2); */
1766         mflo    t_1
1767         mfhi    t_2
1768         daddu   c_3,t_1
1769         sltu    AT,c_3,t_1
1770         daddu   t_2,AT
1771         daddu   c_1,t_2
1772         sltu    AT,c_1,t_2
1773         daddu   c_2,AT
1774         sd      c_3,64(a0)
1775
1776         dmultu  a_2,a_7         /* mul_add_c2(a[2],b[7],c1,c2,c3); */
1777         mflo    t_1
1778         mfhi    t_2
1779         daddu   c_1,t_1
1780         sltu    AT,c_1,t_1
1781         daddu   a2,t_2,AT
1782         daddu   c_2,a2
1783         daddu   c_1,t_1
1784         sltu    AT,c_1,t_1
1785         daddu   t_2,AT
1786         daddu   c_2,t_2
1787         sltu    c_3,c_2,t_2
1788         dmultu  a_3,a_6         /* mul_add_c2(a[3],b[6],c1,c2,c3); */
1789         mflo    t_1
1790         mfhi    t_2
1791         daddu   c_1,t_1
1792         sltu    AT,c_1,t_1
1793         daddu   a2,t_2,AT
1794         daddu   c_2,a2
1795         sltu    AT,c_2,a2
1796         daddu   c_3,AT
1797         daddu   c_1,t_1
1798         sltu    AT,c_1,t_1
1799         daddu   t_2,AT
1800         daddu   c_2,t_2
1801         sltu    AT,c_2,t_2
1802         daddu   c_3,AT
1803         dmultu  a_4,a_5         /* mul_add_c2(a[4],b[5],c1,c2,c3); */
1804         mflo    t_1
1805         mfhi    t_2
1806         daddu   c_1,t_1
1807         sltu    AT,c_1,t_1
1808         daddu   a2,t_2,AT
1809         daddu   c_2,a2
1810         sltu    AT,c_2,a2
1811         daddu   c_3,AT
1812         daddu   c_1,t_1
1813         sltu    AT,c_1,t_1
1814         daddu   t_2,AT
1815         daddu   c_2,t_2
1816         sltu    AT,c_2,t_2
1817         daddu   c_3,AT
1818         sd      c_1,72(a0)
1819
1820         dmultu  a_7,a_3         /* mul_add_c2(a[7],b[3],c2,c3,c1); */
1821         mflo    t_1
1822         mfhi    t_2
1823         daddu   c_2,t_1
1824         sltu    AT,c_2,t_1
1825         daddu   a2,t_2,AT
1826         daddu   c_3,a2
1827         daddu   c_2,t_1
1828         sltu    AT,c_2,t_1
1829         daddu   t_2,AT
1830         daddu   c_3,t_2
1831         sltu    c_1,c_3,t_2
1832         dmultu  a_6,a_4         /* mul_add_c2(a[6],b[4],c2,c3,c1); */
1833         mflo    t_1
1834         mfhi    t_2
1835         daddu   c_2,t_1
1836         sltu    AT,c_2,t_1
1837         daddu   a2,t_2,AT
1838         daddu   c_3,a2
1839         sltu    AT,c_3,a2
1840         daddu   c_1,AT
1841         daddu   c_2,t_1
1842         sltu    AT,c_2,t_1
1843         daddu   t_2,AT
1844         daddu   c_3,t_2
1845         sltu    AT,c_3,t_2
1846         daddu   c_1,AT
1847         dmultu  a_5,a_5         /* mul_add_c(a[5],b[5],c2,c3,c1); */
1848         mflo    t_1
1849         mfhi    t_2
1850         daddu   c_2,t_1
1851         sltu    AT,c_2,t_1
1852         daddu   t_2,AT
1853         daddu   c_3,t_2
1854         sltu    AT,c_3,t_2
1855         daddu   c_1,AT
1856         sd      c_2,80(a0)
1857
1858         dmultu  a_4,a_7         /* mul_add_c2(a[4],b[7],c3,c1,c2); */
1859         mflo    t_1
1860         mfhi    t_2
1861         daddu   c_3,t_1
1862         sltu    AT,c_3,t_1
1863         daddu   a2,t_2,AT
1864         daddu   c_1,a2
1865         daddu   c_3,t_1
1866         sltu    AT,c_3,t_1
1867         daddu   t_2,AT
1868         daddu   c_1,t_2
1869         sltu    c_2,c_1,t_2
1870         dmultu  a_5,a_6         /* mul_add_c2(a[5],b[6],c3,c1,c2); */
1871         mflo    t_1
1872         mfhi    t_2
1873         daddu   c_3,t_1
1874         sltu    AT,c_3,t_1
1875         daddu   a2,t_2,AT
1876         daddu   c_1,a2
1877         sltu    AT,c_1,a2
1878         daddu   c_2,AT
1879         daddu   c_3,t_1
1880         sltu    AT,c_3,t_1
1881         daddu   t_2,AT
1882         daddu   c_1,t_2
1883         sltu    AT,c_1,t_2
1884         daddu   c_2,AT
1885         sd      c_3,88(a0)
1886
1887         dmultu  a_7,a_5         /* mul_add_c2(a[7],b[5],c1,c2,c3); */
1888         mflo    t_1
1889         mfhi    t_2
1890         daddu   c_1,t_1
1891         sltu    AT,c_1,t_1
1892         daddu   a2,t_2,AT
1893         daddu   c_2,a2
1894         daddu   c_1,t_1
1895         sltu    AT,c_1,t_1
1896         daddu   t_2,AT
1897         daddu   c_2,t_2
1898         sltu    c_3,c_2,t_2
1899         dmultu  a_6,a_6         /* mul_add_c(a[6],b[6],c1,c2,c3); */
1900         mflo    t_1
1901         mfhi    t_2
1902         daddu   c_1,t_1
1903         sltu    AT,c_1,t_1
1904         daddu   t_2,AT
1905         daddu   c_2,t_2
1906         sltu    AT,c_2,t_2
1907         daddu   c_3,AT
1908         sd      c_1,96(a0)
1909
1910         dmultu  a_6,a_7         /* mul_add_c2(a[6],b[7],c2,c3,c1); */
1911         mflo    t_1
1912         mfhi    t_2
1913         daddu   c_2,t_1
1914         sltu    AT,c_2,t_1
1915         daddu   a2,t_2,AT
1916         daddu   c_3,a2
1917         daddu   c_2,t_1
1918         sltu    AT,c_2,t_1
1919         daddu   t_2,AT
1920         daddu   c_3,t_2
1921         sltu    c_1,c_3,t_2
1922         sd      c_2,104(a0)
1923
1924         dmultu  a_7,a_7         /* mul_add_c(a[7],b[7],c3,c1,c2); */
1925         mflo    t_1
1926         mfhi    t_2
1927         daddu   c_3,t_1
1928         sltu    AT,c_3,t_1
1929         daddu   t_2,AT
1930         daddu   c_1,t_2
1931         sd      c_3,112(a0)
1932         sd      c_1,120(a0)
1933
1934         jr      ra
1935 END(bn_sqr_comba8)
1936
1937 LEAF(bn_sqr_comba4)
1938         .align  5
1939         .set    reorder
1940         ld      a_0,0(a1)
1941         ld      a_1,8(a1)
1942         ld      a_2,16(a1)
1943         ld      a_3,24(a1)
1944         dmultu  a_0,a_0         /* mul_add_c(a[0],b[0],c1,c2,c3); */
1945         mflo    c_1
1946         mfhi    c_2
1947         sd      c_1,0(a0)
1948
1949         dmultu  a_0,a_1         /* mul_add_c2(a[0],b[1],c2,c3,c1); */
1950         mflo    t_1
1951         mfhi    t_2
1952         daddu   c_2,t_1
1953         sltu    AT,c_2,t_1
1954         daddu   c_3,t_2,AT
1955         daddu   c_2,t_1
1956         sltu    AT,c_2,t_1
1957         daddu   t_2,AT
1958         daddu   c_3,t_2
1959         sltu    c_1,c_3,t_2
1960         sd      c_2,8(a0)
1961
1962         dmultu  a_2,a_0         /* mul_add_c2(a[2],b[0],c3,c1,c2); */
1963         mflo    t_1
1964         mfhi    t_2
1965         daddu   c_3,t_1
1966         sltu    AT,c_3,t_1
1967         daddu   a2,t_2,AT
1968         daddu   c_1,a2
1969         daddu   c_3,t_1
1970         sltu    AT,c_3,t_1
1971         daddu   t_2,AT
1972         daddu   c_1,t_2
1973         sltu    c_2,c_1,t_2
1974         dmultu  a_1,a_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
1975         mflo    t_1
1976         mfhi    t_2
1977         daddu   c_3,t_1
1978         sltu    AT,c_3,t_1
1979         daddu   t_2,AT
1980         daddu   c_1,t_2
1981         sltu    AT,c_1,t_2
1982         daddu   c_2,AT
1983         sd      c_3,16(a0)
1984
1985         dmultu  a_0,a_3         /* mul_add_c2(a[0],b[3],c1,c2,c3); */
1986         mflo    t_1
1987         mfhi    t_2
1988         daddu   c_1,t_1
1989         sltu    AT,c_1,t_1
1990         daddu   a2,t_2,AT
1991         daddu   c_2,a2
1992         daddu   c_1,t_1
1993         sltu    AT,c_1,t_1
1994         daddu   t_2,AT
1995         daddu   c_2,t_2
1996         sltu    c_3,c_2,t_2
1997         dmultu  a_1,a_2         /* mul_add_c(a2[1],b[2],c1,c2,c3); */
1998         mflo    t_1
1999         mfhi    t_2
2000         daddu   c_1,t_1
2001         sltu    AT,c_1,t_1
2002         daddu   a2,t_2,AT
2003         daddu   c_2,a2
2004         sltu    AT,c_2,a2
2005         daddu   c_3,AT
2006         daddu   c_1,t_1
2007         sltu    AT,c_1,t_1
2008         daddu   t_2,AT
2009         daddu   c_2,t_2
2010         sltu    AT,c_2,t_2
2011         daddu   c_3,AT
2012         sd      c_1,24(a0)
2013
2014         dmultu  a_3,a_1         /* mul_add_c2(a[3],b[1],c2,c3,c1); */
2015         mflo    t_1
2016         mfhi    t_2
2017         daddu   c_2,t_1
2018         sltu    AT,c_2,t_1
2019         daddu   a2,t_2,AT
2020         daddu   c_3,a2
2021         daddu   c_2,t_1
2022         sltu    AT,c_2,t_1
2023         daddu   t_2,AT
2024         daddu   c_3,t_2
2025         sltu    c_1,c_3,t_2
2026         dmultu  a_2,a_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
2027         mflo    t_1
2028         mfhi    t_2
2029         daddu   c_2,t_1
2030         sltu    AT,c_2,t_1
2031         daddu   t_2,AT
2032         daddu   c_3,t_2
2033         sltu    AT,c_3,t_2
2034         daddu   c_1,AT
2035         sd      c_2,32(a0)
2036
2037         dmultu  a_2,a_3         /* mul_add_c2(a[2],b[3],c3,c1,c2); */
2038         mflo    t_1
2039         mfhi    t_2
2040         daddu   c_3,t_1
2041         sltu    AT,c_3,t_1
2042         daddu   a2,t_2,AT
2043         daddu   c_1,a2
2044         daddu   c_3,t_1
2045         sltu    AT,c_3,t_1
2046         daddu   t_2,AT
2047         daddu   c_1,t_2
2048         sltu    c_2,c_1,t_2
2049         sd      c_3,40(a0)
2050
2051         dmultu  a_3,a_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */
2052         mflo    t_1
2053         mfhi    t_2
2054         daddu   c_1,t_1
2055         sltu    AT,c_1,t_1
2056         daddu   t_2,AT
2057         daddu   c_2,t_2
2058         sd      c_1,48(a0)
2059         sd      c_2,56(a0)
2060
2061         jr      ra
2062 END(bn_sqr_comba4)