Missing sparcv8.o rule.
[oweals/openssl.git] / crypto / bn / asm / mips3.s
index 2193c954b209f63a7daf469980cb6bfbd6852c24..dca4105c7db1b4ce9b02713ea1f57c7f3d833df0 100644 (file)
@@ -1,5 +1,5 @@
 .rdata
-.asciiz "mips3.s, Version 1.0 (prerelease)"
+.asciiz        "mips3.s, Version 1.1"
 .asciiz        "MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
 
 /*
  * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
  * module. For updates see http://fy.chalmers.se/~appro/hpe/.
  *
- * The module is designed to work with "new" IRIX ABI(5), namely
- * N32 and N64. But it was tested only with MIPSpro 7.2.x assembler,
- * i.e. depends on preprocessor options set up by MIPSspro 7.2.x
- * driver. Another neat gadget offered by MIPSpro 7.2.x assembler is
- * an peep-hole(?) optimization pass. This gave me the opportunity
- * to make the code looking more regular as all those architecture
- * dependent(!) instruction rescheduling details were left to the
- * assembler. Cool, huh? Do note that I have no idea if GNU assembler
- * does anything similar nor how GNU C will do with this module.
- * Feedback on the matter is therefore very much appreciated:-)
+ * The module is designed to work with either of the "new" MIPS ABI(5),
+ * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
+ * IRIX 5.x not only because it doesn't support new ABIs but also
+ * because 5.x kernels put R4x00 CPU into 32-bit mode and all those
+ * 64-bit instructions (daddu, dmultu, etc.) found below gonna only
+ * cause illegal instruction exception:-(
+ *
+ * In addition the code depends on preprocessor flags set up by MIPSpro
+ * compiler driver (either as or cc) and therefore (probably?) can't be
+ * compiled by the GNU assembler. GNU C driver manages fine though...
+ * I mean as long as -mmips-as is specified or is the default option,
+ * because then it simply invokes /usr/bin/as which in turn takes
+ * perfect care of the preprocessor definitions. Another neat feature
+ * offered by the MIPSpro assembler is an optimization pass. This gave
+ * me the opportunity to have the code looking more regular as all those
+ * architecture dependent instruction rescheduling details were left to
+ * the assembler. Cool, huh?
  *
  * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
- * exhibits 3-3.5-3.7 times improvement!
+ * goes way over 3 times faster!
  *
  *                                     <appro@fy.chalmers.se>
  */
@@ -56,8 +63,8 @@
 
 #define        MINUS4  v1
 
+.align 5
 LEAF(bn_mul_add_words)
-       .align  5
        .set    noreorder
        bgtzl   a2,.L_bn_mul_add_words_proceed
        ld      t0,0(a1)
@@ -185,8 +192,8 @@ LEAF(bn_mul_add_words)
        jr      ra
 END(bn_mul_add_words)
 
+.align 5
 LEAF(bn_mul_words)
-       .align  5
        .set    noreorder
        bgtzl   a2,.L_bn_mul_words_proceed
        ld      t0,0(a1)
@@ -284,8 +291,8 @@ LEAF(bn_mul_words)
        jr      ra
 END(bn_mul_words)
 
+.align 5
 LEAF(bn_sqr_words)
-       .align  5
        .set    noreorder
        bgtzl   a2,.L_bn_sqr_words_proceed
        ld      t0,0(a1)
@@ -371,8 +378,8 @@ LEAF(bn_sqr_words)
        jr      ra
 END(bn_sqr_words)
 
+.align 5
 LEAF(bn_add_words)
-       .align  5
        .set    noreorder
        bgtzl   a3,.L_bn_add_words_proceed
        ld      t0,0(a1)
@@ -388,32 +395,32 @@ LEAF(bn_add_words)
 
 .L_bn_add_words_loop:
        ld      ta0,0(a2)
+       subu    a3,4
        ld      t1,8(a1)
-       ld      ta1,8(a2)
+       and     AT,a3,MINUS4
        ld      t2,16(a1)
-       ld      ta2,16(a2)
+       PTR_ADD a2,32
        ld      t3,24(a1)
-       ld      ta3,24(a2)
+       PTR_ADD a0,32
+       ld      ta1,-24(a2)
+       PTR_ADD a1,32
+       ld      ta2,-16(a2)
+       ld      ta3,-8(a2)
        daddu   ta0,t0
-       subu    a3,4
        sltu    t8,ta0,t0
        daddu   t0,ta0,v0
-       PTR_ADD a0,32
        sltu    v0,t0,ta0
        sd      t0,-32(a0)
        daddu   v0,t8
 
        daddu   ta1,t1
-       PTR_ADD a1,32
        sltu    t9,ta1,t1
        daddu   t1,ta1,v0
-       PTR_ADD a2,32
        sltu    v0,t1,ta1
        sd      t1,-24(a0)
        daddu   v0,t9
 
        daddu   ta2,t2
-       and     AT,a3,MINUS4
        sltu    t8,ta2,t2
        daddu   t2,ta2,v0
        sltu    v0,t2,ta2
@@ -471,8 +478,8 @@ LEAF(bn_add_words)
        jr      ra
 END(bn_add_words)
 
+.align 5
 LEAF(bn_sub_words)
-       .align  5
        .set    noreorder
        bgtzl   a3,.L_bn_sub_words_proceed
        ld      t0,0(a1)
@@ -488,25 +495,26 @@ LEAF(bn_sub_words)
 
 .L_bn_sub_words_loop:
        ld      ta0,0(a2)
+       subu    a3,4
        ld      t1,8(a1)
-       ld      ta1,8(a2)
+       and     AT,a3,MINUS4
        ld      t2,16(a1)
-       ld      ta2,16(a2)
+       PTR_ADD a2,32
        ld      t3,24(a1)
-       ld      ta3,24(a2)
+       PTR_ADD a0,32
+       ld      ta1,-24(a2)
+       PTR_ADD a1,32
+       ld      ta2,-16(a2)
+       ld      ta3,-8(a2)
        sltu    t8,t0,ta0
        dsubu   t0,ta0
-       subu    a3,4
        dsubu   ta0,t0,v0
-       and     AT,a3,MINUS4
-       sd      ta0,0(a0)
+       sd      ta0,-32(a0)
        MOVNZ   (t0,v0,t8)
 
        sltu    t9,t1,ta1
        dsubu   t1,ta1
-       PTR_ADD a0,32
        dsubu   ta1,t1,v0
-       PTR_ADD a1,32
        sd      ta1,-24(a0)
        MOVNZ   (t1,v0,t9)
 
@@ -514,7 +522,6 @@ LEAF(bn_sub_words)
        sltu    t8,t2,ta2
        dsubu   t2,ta2
        dsubu   ta2,t2,v0
-       PTR_ADD a2,32
        sd      ta2,-16(a0)
        MOVNZ   (t2,v0,t8)
 
@@ -567,24 +574,69 @@ END(bn_sub_words)
 
 #undef MINUS4
 
+.align 5
+LEAF(bn_div_3_words)
+       .set    reorder
+       move    a3,a0           /* we know that bn_div_words doesn't
+                                * touch a3, ta2, ta3 and preserves a2
+                                * so that we can save two arguments
+                                * and return address in registers
+                                * instead of stack:-)
+                                */
+       ld      a0,(a3)
+       move    ta2,a1
+       ld      a1,-8(a3)
+       bne     a0,a2,.L_bn_div_3_words_proceed
+       li      v0,-1
+       jr      ra
+.L_bn_div_3_words_proceed:
+       move    ta3,ra
+       bal     bn_div_words
+       move    ra,ta3
+       dmultu  ta2,v0
+       ld      t2,-16(a3)
+       move    ta0,zero
+       mfhi    t1
+       mflo    t0
+       sltu    t8,t1,v1
+.L_bn_div_3_words_inner_loop:
+       bnez    t8,.L_bn_div_3_words_inner_loop_done
+       sgeu    AT,t2,t0
+       seq     t9,t1,v1
+       and     AT,t9
+       sltu    t3,t0,ta2
+       daddu   v1,a2
+       dsubu   t1,t3
+       dsubu   t0,ta2
+       sltu    t8,t1,v1
+       sltu    ta0,v1,a2
+       or      t8,ta0
+       .set    noreorder
+       beqzl   AT,.L_bn_div_3_words_inner_loop
+       dsubu   v0,1
+       .set    reorder
+.L_bn_div_3_words_inner_loop_done:
+       jr      ra
+END(bn_div_3_words)
+
+.align 5
 LEAF(bn_div_words)
-       .align  5
        .set    noreorder
        bnezl   a2,.L_bn_div_words_proceed
-       move    t0,zero
+       move    v1,zero
        jr      ra
        li      v0,-1           /* I'd rather signal div-by-zero
                                 * which can be done with 'break 7' */
-       .set    reorder
 
 .L_bn_div_words_proceed:
        bltz    a2,.L_bn_div_words_body
-       .set    noreorder
+       move    t9,v1
        dsll    a2,1
        bgtz    a2,.-4
-       addu    t0,1
+       addu    t9,1
+
        .set    reorder
-       negu    t1,t0
+       negu    t1,t9
        li      t2,-1
        dsll    t2,t1
        and     t2,a0
@@ -593,62 +645,90 @@ LEAF(bn_div_words)
        bnezl   t2,.+8
        break   6               /* signal overflow */
        .set    reorder
-       dsll    a0,t0
-       dsll    a1,t0
+       dsll    a0,t9
+       dsll    a1,t9
        or      a0,AT
 
 #define        QT      ta0
-#define        DH      ta1
-#define        HH      ta2
-#define        MINUS1  ta3
+#define        HH      ta1
+#define        DH      v1
 .L_bn_div_words_body:
        dsrl    DH,a2,32
-       li      v1,2
        sgeu    AT,a0,a2
-       li      MINUS1,-1
        .set    noreorder
        bnezl   AT,.+8
        dsubu   a0,a2
        .set    reorder
 
-.L_bn_div_words_outer_loop:
+       li      QT,-1
        dsrl    HH,a0,32
-       subu    v1,1
-       dsrl    QT,MINUS1,32    /* q=0xffffffff */
-       beq     DH,HH,.L_bn_div_words_inner_loop
+       dsrl    QT,32   /* q=0xffffffff */
+       beq     DH,HH,.L_bn_div_words_skip_div1
        ddivu   zero,a0,DH
        mflo    QT
-.L_bn_div_words_inner_loop:
+.L_bn_div_words_skip_div1:
        dmultu  a2,QT
        dsll    t3,a0,32
        dsrl    AT,a1,32
        or      t3,AT
        mflo    t0
        mfhi    t1
+.L_bn_div_words_inner_loop1:
        sltu    t2,t3,t0
        seq     t8,HH,t1
        sltu    AT,HH,t1
        and     t2,t8
+       sltu    v0,t0,a2
        or      AT,t2
        .set    noreorder
-       bnezl   AT,.L_bn_div_words_inner_loop
+       beqz    AT,.L_bn_div_words_inner_loop1_done
+       dsubu   t1,v0
+       dsubu   t0,a2
+       b       .L_bn_div_words_inner_loop1
        dsubu   QT,1
        .set    reorder
-       
-       dsubu   a0,t3,t0
-       beqz    v1,.L_bn_div_words_outer_loop_done
+.L_bn_div_words_inner_loop1_done:
 
        dsll    a1,32
+       dsubu   a0,t3,t0
        dsll    v0,QT,32
-       b       .L_bn_div_words_outer_loop
 
-.L_bn_div_words_outer_loop_done:
+       li      QT,-1
+       dsrl    HH,a0,32
+       dsrl    QT,32   /* q=0xffffffff */
+       beq     DH,HH,.L_bn_div_words_skip_div2
+       ddivu   zero,a0,DH
+       mflo    QT
+.L_bn_div_words_skip_div2:
+#undef DH
+       dmultu  a2,QT
+       dsll    t3,a0,32
+       dsrl    AT,a1,32
+       or      t3,AT
+       mflo    t0
+       mfhi    t1
+.L_bn_div_words_inner_loop2:
+       sltu    t2,t3,t0
+       seq     t8,HH,t1
+       sltu    AT,HH,t1
+       and     t2,t8
+       sltu    v1,t0,a2
+       or      AT,t2
+       .set    noreorder
+       beqz    AT,.L_bn_div_words_inner_loop2_done
+       dsubu   t1,v1
+       dsubu   t0,a2
+       b       .L_bn_div_words_inner_loop2
+       dsubu   QT,1
+       .set    reorder
+.L_bn_div_words_inner_loop2_done:      
+#undef HH
+
+       dsubu   a0,t3,t0
        or      v0,QT
-       move    v1,a0   /* v1 contains remainder if one wants it */
+       dsrl    v1,a0,t9        /* v1 contains remainder if anybody wants it */
+       dsrl    a2,t9           /* restore a2 */
        jr      ra
-#undef MINUS1
-#undef HH
-#undef DH
 #undef QT
 END(bn_div_words)
 
@@ -679,20 +759,19 @@ END(bn_div_words)
 
 #define        FRAME_SIZE      48
 
+.align 5
 LEAF(bn_mul_comba8)
-       .align  5
        .set    noreorder
        PTR_SUB sp,FRAME_SIZE
        .frame  sp,64,ra
        .set    reorder
-       ld      a_0,0(a1)       /* If compiled with -mips3 options
-                                * assembler barks on this line with
-                                * "shouldn't have mult/div as last
-                                * instruction in bb (R10K bug)"
-                                * warning. If anybody out there has
-                                * a clue on what does "bb" mean and
-                                * how to circumvent this do send me
-                                * a note.
+       ld      a_0,0(a1)       /* If compiled with -mips3 option on
+                                * R5000 box assembler barks on this
+                                * line with "shouldn't have mult/div
+                                * as last instruction in bb (R10K
+                                * bug)" warning. If anybody out there
+                                * has a clue about how to circumvent
+                                * this do send me a note.
                                 *              <appro@fy.chalmers.se>
                                 */
        ld      b_0,0(a2)
@@ -770,6 +849,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
+       sltu    c_3,c_2,t_2
        dmultu  a_1,b_2         /* mul_add_c(a[1],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -777,7 +857,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_2,b_1         /* mul_add_c(a[2],b[1],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -805,6 +886,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
+       sltu    c_1,c_3,t_2
        dmultu  a_3,b_1         /* mul_add_c(a[3],b[1],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -812,7 +894,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_2,b_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -849,6 +932,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
+       sltu    c_2,c_1,t_2
        dmultu  a_1,b_4         /* mul_add_c(a[1],b[4],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -856,7 +940,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_2,b_3         /* mul_add_c(a[2],b[3],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -902,6 +987,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
+       sltu    c_3,c_2,t_2
        dmultu  a_5,b_1         /* mul_add_c(a[5],b[1],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -909,7 +995,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_4,b_2         /* mul_add_c(a[4],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -964,6 +1051,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
+       sltu    c_1,c_3,t_2
        dmultu  a_1,b_6         /* mul_add_c(a[1],b[6],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -971,7 +1059,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_2,b_5         /* mul_add_c(a[2],b[5],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1035,6 +1124,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
+       sltu    c_2,c_1,t_2
        dmultu  a_6,b_2         /* mul_add_c(a[6],b[2],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1042,7 +1132,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_5,b_3         /* mul_add_c(a[5],b[3],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1097,6 +1188,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
+       sltu    c_3,c_2,t_2
        dmultu  a_3,b_6         /* mul_add_c(a[3],b[6],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1104,7 +1196,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_4,b_5         /* mul_add_c(a[4],b[5],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1150,6 +1243,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
+       sltu    c_1,c_3,t_2
        dmultu  a_6,b_4         /* mul_add_c(a[6],b[4],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1157,7 +1251,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_5,b_5         /* mul_add_c(a[5],b[5],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1194,6 +1289,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
+       sltu    c_2,c_1,t_2
        dmultu  a_5,b_6         /* mul_add_c(a[5],b[6],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1201,7 +1297,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_6,b_5         /* mul_add_c(a[6],b[5],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1229,6 +1326,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
+       sltu    c_3,c_2,t_2
        dmultu  a_6,b_6         /* mul_add_c(a[6],b[6],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1236,7 +1334,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_5,b_7         /* mul_add_c(a[5],b[7],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1255,6 +1354,7 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
+       sltu    c_1,c_3,t_2
        dmultu  a_7,b_6         /* mul_add_c(a[7],b[6],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1262,7 +1362,8 @@ LEAF(bn_mul_comba8)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        sd      c_2,104(a0)     /* r[13]=c2; */
 
        dmultu  a_7,b_7         /* mul_add_c(a[7],b[7],c3,c1,c2); */
@@ -1286,8 +1387,8 @@ LEAF(bn_mul_comba8)
        jr      ra
 END(bn_mul_comba8)
 
+.align 5
 LEAF(bn_mul_comba4)
-       .align  5
        .set    reorder
        ld      a_0,0(a1)
        ld      b_0,0(a2)
@@ -1351,6 +1452,7 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
+       sltu    c_3,c_2,t_2
        dmultu  a_1,b_2         /* mul_add_c(a[1],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1358,7 +1460,8 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_2,b_1         /* mul_add_c(a[2],b[1],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1386,6 +1489,7 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
+       sltu    c_1,c_3,t_2
        dmultu  a_2,b_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1393,7 +1497,8 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_1,b_3         /* mul_add_c(a[1],b[3],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -1412,6 +1517,7 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
+       sltu    c_2,c_1,t_2
        dmultu  a_3,b_2         /* mul_add_c(a[3],b[2],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1419,7 +1525,8 @@ LEAF(bn_mul_comba4)
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        sd      c_3,40(a0)
 
        dmultu  a_3,b_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */
@@ -1444,8 +1551,8 @@ END(bn_mul_comba4)
 #define        a_6     b_2
 #define        a_7     b_3
 
+.align 5
 LEAF(bn_sqr_comba8)
-       .align  5
        .set    reorder
        ld      a_0,0(a1)
        ld      a_1,8(a1)
@@ -1464,28 +1571,30 @@ LEAF(bn_sqr_comba8)
        dmultu  a_0,a_1         /* mul_add_c2(a[0],b[1],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   c_3,t_2,AT
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   t_2,AT
-       daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
        sd      c_2,8(a0)
 
        dmultu  a_2,a_0         /* mul_add_c2(a[2],b[0],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_1,a_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1500,24 +1609,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_0,a_3         /* mul_add_c2(a[0],b[3],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
+       slt     c_3,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_1,a_2         /* mul_add_c2(a[1],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -1529,24 +1640,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_4,a_0         /* mul_add_c2(a[4],b[0],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_3,a_1         /* mul_add_c2(a[3],b[1],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
-       sltu    AT,c_3,a2
+       slt     AT,t_2,zero
        daddu   c_1,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
@@ -1567,24 +1680,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_0,a_5         /* mul_add_c2(a[0],b[5],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_1,a_4         /* mul_add_c2(a[1],b[4],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
-       sltu    AT,c_1,a2
+       slt     AT,t_2,zero
        daddu   c_2,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
@@ -1594,12 +1709,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_2,a_3         /* mul_add_c2(a[2],b[3],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
-       sltu    AT,c_1,a2
+       slt     AT,t_2,zero
        daddu   c_2,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
@@ -1611,24 +1726,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_6,a_0         /* mul_add_c2(a[6],b[0],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
+       slt     c_3,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_5,a_1         /* mul_add_c2(a[5],b[1],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -1638,12 +1755,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_4,a_2         /* mul_add_c2(a[4],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -1664,24 +1781,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_0,a_7         /* mul_add_c2(a[0],b[7],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_1,a_6         /* mul_add_c2(a[1],b[6],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
-       sltu    AT,c_3,a2
+       slt     AT,t_2,zero
        daddu   c_1,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
@@ -1691,12 +1810,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_2,a_5         /* mul_add_c2(a[2],b[5],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
-       sltu    AT,c_3,a2
+       slt     AT,t_2,zero
        daddu   c_1,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
@@ -1706,12 +1825,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_3,a_4         /* mul_add_c2(a[3],b[4],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
-       sltu    AT,c_3,a2
+       slt     AT,t_2,zero
        daddu   c_1,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
@@ -1723,24 +1842,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_7,a_1         /* mul_add_c2(a[7],b[1],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_6,a_2         /* mul_add_c2(a[6],b[2],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
-       sltu    AT,c_1,a2
+       slt     AT,t_2,zero
        daddu   c_2,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
@@ -1750,12 +1871,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_5,a_3         /* mul_add_c2(a[5],b[3],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
-       sltu    AT,c_1,a2
+       slt     AT,t_2,zero
        daddu   c_2,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
@@ -1776,24 +1897,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_2,a_7         /* mul_add_c2(a[2],b[7],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
+       slt     c_3,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_3,a_6         /* mul_add_c2(a[3],b[6],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -1803,12 +1926,12 @@ LEAF(bn_sqr_comba8)
        dmultu  a_4,a_5         /* mul_add_c2(a[4],b[5],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -1820,24 +1943,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_7,a_3         /* mul_add_c2(a[7],b[3],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_6,a_4         /* mul_add_c2(a[6],b[4],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
-       sltu    AT,c_3,a2
+       slt     AT,t_2,zero
        daddu   c_1,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
@@ -1858,24 +1983,26 @@ LEAF(bn_sqr_comba8)
        dmultu  a_4,a_7         /* mul_add_c2(a[4],b[7],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_5,a_6         /* mul_add_c2(a[5],b[6],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
-       sltu    AT,c_1,a2
+       slt     AT,t_2,zero
        daddu   c_2,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
@@ -1887,15 +2014,17 @@ LEAF(bn_sqr_comba8)
        dmultu  a_7,a_5         /* mul_add_c2(a[7],b[5],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
+       slt     c_3,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_6,a_6         /* mul_add_c(a[6],b[6],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
@@ -1910,15 +2039,17 @@ LEAF(bn_sqr_comba8)
        dmultu  a_6,a_7         /* mul_add_c2(a[6],b[7],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        sd      c_2,104(a0)
 
        dmultu  a_7,a_7         /* mul_add_c(a[7],b[7],c3,c1,c2); */
@@ -1934,8 +2065,8 @@ LEAF(bn_sqr_comba8)
        jr      ra
 END(bn_sqr_comba8)
 
+.align 5
 LEAF(bn_sqr_comba4)
-       .align  5
        .set    reorder
        ld      a_0,0(a1)
        ld      a_1,8(a1)
@@ -1949,28 +2080,30 @@ LEAF(bn_sqr_comba4)
        dmultu  a_0,a_1         /* mul_add_c2(a[0],b[1],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   c_3,t_2,AT
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   t_2,AT
-       daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
        sd      c_2,8(a0)
 
        dmultu  a_2,a_0         /* mul_add_c2(a[2],b[0],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        dmultu  a_1,a_1         /* mul_add_c(a[1],b[1],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
@@ -1985,24 +2118,26 @@ LEAF(bn_sqr_comba4)
        dmultu  a_0,a_3         /* mul_add_c2(a[0],b[3],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
+       slt     c_3,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
        daddu   c_2,t_2
-       sltu    c_3,c_2,t_2
+       sltu    AT,c_2,t_2
+       daddu   c_3,AT
        dmultu  a_1,a_2         /* mul_add_c(a2[1],b[2],c1,c2,c3); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_1,t_1
-       sltu    AT,c_1,t_1
-       daddu   a2,t_2,AT
-       daddu   c_2,a2
-       sltu    AT,c_2,a2
+       slt     AT,t_2,zero
        daddu   c_3,AT
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_1,t_1
        sltu    AT,c_1,t_1
        daddu   t_2,AT
@@ -2014,15 +2149,17 @@ LEAF(bn_sqr_comba4)
        dmultu  a_3,a_1         /* mul_add_c2(a[3],b[1],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_2,t_1
-       sltu    AT,c_2,t_1
-       daddu   a2,t_2,AT
-       daddu   c_3,a2
+       slt     c_1,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_2,t_1
        sltu    AT,c_2,t_1
        daddu   t_2,AT
        daddu   c_3,t_2
-       sltu    c_1,c_3,t_2
+       sltu    AT,c_3,t_2
+       daddu   c_1,AT
        dmultu  a_2,a_2         /* mul_add_c(a[2],b[2],c2,c3,c1); */
        mflo    t_1
        mfhi    t_2
@@ -2037,15 +2174,17 @@ LEAF(bn_sqr_comba4)
        dmultu  a_2,a_3         /* mul_add_c2(a[2],b[3],c3,c1,c2); */
        mflo    t_1
        mfhi    t_2
-       daddu   c_3,t_1
-       sltu    AT,c_3,t_1
-       daddu   a2,t_2,AT
-       daddu   c_1,a2
+       slt     c_2,t_2,zero
+       dsll    t_2,1
+       slt     a2,t_1,zero
+       daddu   t_2,a2
+       dsll    t_1,1
        daddu   c_3,t_1
        sltu    AT,c_3,t_1
        daddu   t_2,AT
        daddu   c_1,t_2
-       sltu    c_2,c_1,t_2
+       sltu    AT,c_1,t_2
+       daddu   c_2,AT
        sd      c_3,40(a0)
 
        dmultu  a_3,a_3         /* mul_add_c(a[3],b[3],c1,c2,c3); */