]> granicus.if.org Git - openssl/commitdiff
bn/asm/*-mont.pl: harmonize with BN_from_montgomery_word.
authorAndy Polyakov <appro@openssl.org>
Mon, 30 Apr 2018 20:59:51 +0000 (22:59 +0200)
committerAndy Polyakov <appro@openssl.org>
Fri, 4 May 2018 09:45:23 +0000 (11:45 +0200)
Montgomery multiplication post-conditions in some of code paths were
formally non-constant time. Cache access pattern was result-neutral,
but a little bit asymmetric, which might have produced a signal [if
processor reordered load and stores at run-time].

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6163)

(cherry picked from commit 774ff8fed67e19d4f5f0df2f59050f2737abab2a)

Resolved conflicts in ppc-mont.pl and x86_64-mont.pl.

(cherry picked from commit d067ba3bcc4944140578bdbf857affa6faf9e8c1)

15 files changed:
crypto/bn/asm/alpha-mont.pl
crypto/bn/asm/armv4-mont.pl
crypto/bn/asm/ia64-mont.pl
crypto/bn/asm/mips-mont.pl
crypto/bn/asm/parisc-mont.pl
crypto/bn/asm/ppc-mont.pl
crypto/bn/asm/ppc64-mont.pl
crypto/bn/asm/s390x-mont.pl
crypto/bn/asm/sparct4-mont.pl
crypto/bn/asm/sparcv9-mont.pl
crypto/bn/asm/via-mont.pl
crypto/bn/asm/vis3-mont.pl
crypto/bn/asm/x86-mont.pl
crypto/bn/asm/x86_64-mont.pl
crypto/bn/asm/x86_64-mont5.pl

index 03596e2014d4035d02440316cc1cf025f726d772..f80cca2f1c9148eb6d3f96c40897d7dd93295b50 100644 (file)
@@ -287,15 +287,12 @@ bn_mul_mont:
        mov     sp,$tp
        mov     $bp,$rp         # restore rp
 
-       and     sp,$hi0,$ap
-       bic     $bp,$hi0,$bp
-       bis     $bp,$ap,$ap     # ap=borrow?tp:rp
-
 .align 4
-.Lcopy:        ldq     $aj,0($ap)      # copy or in-place refresh
+.Lcopy:        ldq     $aj,0($tp)      # conditional copy
+       ldq     $nj,0($rp)
        lda     $tp,8($tp)
        lda     $rp,8($rp)
-       lda     $ap,8($ap)
+       cmoveq  $hi0,$nj,$aj
        stq     zero,-8($tp)    # zap tp
        cmpult  $tp,$tj,AT
        stq     $aj,-8($rp)
index 1d330e9f8aa3111907aa2cca00c4a948c7501878..8961180c0095e10d56454a8a206743916bcbe267 100644 (file)
@@ -216,14 +216,15 @@ bn_mul_mont:
        mov     $tp,sp                  @ "rewind" $tp
        sub     $rp,$rp,$aj             @ "rewind" $rp
 
-       and     $ap,$tp,$nhi
-       bic     $np,$rp,$nhi
-       orr     $ap,$ap,$np             @ ap=borrow?tp:rp
-
-.Lcopy:        ldr     $tj,[$ap],#4            @ copy or in-place refresh
+.Lcopy:        ldr     $tj,[$tp]               @ conditional copy
+       ldr     $aj,[$rp]
        str     sp,[$tp],#4             @ zap tp
-       str     $tj,[$rp],#4
-       cmp     $tp,$num
+#ifdef __thumb2__
+       it      cc
+#endif
+       movcc   $aj,$tj
+       str     $aj,[$rp],#4
+       teq     $tp,$num                @ preserve carry
        bne     .Lcopy
 
        add     sp,$num,#4              @ skip over tp[num+1]
index e258658428a3fbc07492de3f637da659a34cf869..7dae817ddd98b63e902dbd81f786ab843ebc64d5 100644 (file)
@@ -332,19 +332,19 @@ bn_mul_mont_general:
 { .mmb;        sub     rptr=rptr,len           // rewind
        sub     tptr=tptr,len
        clrrrb.pr                       };;
-{ .mmi;        and     aptr=tptr,topbit
-       andcm   bptr=rptr,topbit
+{ .mmi;        mov     aptr=rptr
+       mov     bptr=tptr
        mov     pr.rot=1<<16            };;
-{ .mii;        or      nptr=aptr,bptr
+{ .mii;        cmp.eq  p0,p6=topbit,r0
        mov     ar.lc=lc
-       mov     ar.ec=3                 };;
+       mov     ar.ec=2                 };;
 
 .Lcopy_ctop:
-{ .mmb;        (p16)   ld8     n[0]=[nptr],8
-       (p18)   st8     [tptr]=r0,8
-       (p16)   nop.b   0               }
-{ .mmb;        (p16)   nop.m   0
-       (p18)   st8     [rptr]=n[2],8
+{ .mmi;        (p16)   ld8     a[0]=[aptr],8
+       (p16)   ld8     t[0]=[bptr],8
+       (p6)    mov     a[1]=t[1]       };;     // (p17)
+{ .mmb;        (p17)   st8     [rptr]=a[1],8
+       (p17)   st8     [tptr]=r0,8
        br.ctop.sptk    .Lcopy_ctop     };;
 .Lcopy_cend:
 
index a33cdf411121ff0a14aa3c1084a19956022e82ff..9b80e84140d786239d7258462a7f81c655aeab6a 100644 (file)
@@ -377,15 +377,13 @@ $code.=<<___;
        $PTR_SUB $rp,$num       # restore rp
        not     $hi1,$hi0
 
-       and     $ap,$hi0,$sp
-       and     $bp,$hi1,$rp
-       or      $ap,$ap,$bp     # ap=borrow?tp:rp
-
-.align 4
-.Lcopy:        $LD     $aj,($ap)
-       $PTR_ADD $ap,$BNSZ
+.Lcopy:        $LD     $nj,($tp)       # conditional move
+       $LD     $aj,($rp)
        $ST     $zero,($tp)
        $PTR_ADD $tp,$BNSZ
+       and     $nj,$hi0
+       and     $aj,$hi1
+       or      $aj,$nj
        sltu    $at,$tp,$tj
        $ST     $aj,($rp)
        bnez    $at,.Lcopy
index c02ef6f014668324649265efc84709312158ad3f..53e179d188041eb89b2a427cc18128d708113539 100644 (file)
@@ -510,7 +510,6 @@ L\$sub
        stws,ma         $hi1,4($rp)
 
        subb            $ti0,%r0,$hi1
-       ldo             -4($tp),$tp
 ___
 $code.=<<___ if ($BN_SZ==8);
        ldd,ma          8($tp),$ti0
@@ -525,21 +524,19 @@ L\$sub
 
        extrd,u         $ti0,31,32,$ti0         ; carry in flipped word order
        sub,db          $ti0,%r0,$hi1
-       ldo             -8($tp),$tp
 ___
 $code.=<<___;
-       and             $tp,$hi1,$ap
-       andcm           $rp,$hi1,$bp
-       or              $ap,$bp,$np
-
+       ldo             `$LOCALS+32`($fp),$tp
        sub             $rp,$arrsz,$rp          ; rewind rp
        subi            0,$arrsz,$idx
-       ldo             `$LOCALS+32`($fp),$tp
 L\$copy
-       ldd             $idx($np),$hi0
+       ldd             0($tp),$ti0
+       ldd             0($rp),$hi0
        std,ma          %r0,8($tp)
-       addib,<>        8,$idx,.-8              ; L\$copy
-       std,ma          $hi0,8($rp)     
+       comiclr,=       0,$hi1,%r0
+       copy            $ti0,$hi0
+       addib,<>        8,$idx,L\$copy
+       std,ma          $hi0,8($rp)
 ___
 
 if ($BN_SZ==4) {                               # PA-RISC 1.1 code-path
@@ -849,17 +846,16 @@ L\$sub_pa11
        stws,ma         $hi1,4($rp)
 
        subb            $ti0,%r0,$hi1
-       ldo             -4($tp),$tp
-       and             $tp,$hi1,$ap
-       andcm           $rp,$hi1,$bp
-       or              $ap,$bp,$np
 
+       ldo             `$LOCALS+32`($fp),$tp
        sub             $rp,$arrsz,$rp          ; rewind rp
        subi            0,$arrsz,$idx
-       ldo             `$LOCALS+32`($fp),$tp
 L\$copy_pa11
-       ldwx            $idx($np),$hi0
+       ldw             0($tp),$ti0
+       ldw             0($rp),$hi0
        stws,ma         %r0,4($tp)
+       comiclr,=       0,$hi1,%r0
+       copy            $ti0,$hi0
        addib,<>        4,$idx,L\$copy_pa11
        stws,ma         $hi0,4($rp)     
 
index 6930a3acebd2e4bf02c3c7f9bd5d4d6da8644949..ac3b4a4c9bca5c55804c5c9f407a949c6467d9db 100644 (file)
@@ -294,15 +294,16 @@ Lsub:     $LDX    $tj,$tp,$j
        li      $j,0
        mtctr   $num
        subfe   $ovf,$j,$ovf    ; handle upmost overflow bit
-       and     $ap,$tp,$ovf
-       andc    $np,$rp,$ovf
-       or      $ap,$ap,$np     ; ap=borrow?tp:rp
 
 .align 4
-Lcopy:                         ; copy or in-place refresh
-       $LDX    $tj,$ap,$j
-       $STX    $tj,$rp,$j
+Lcopy:                         ; conditional copy
+       $LDX    $tj,$tp,$j
+       $LDX    $aj,$rp,$j
+       and     $tj,$tj,$ovf
+       andc    $aj,$aj,$ovf
        $STX    $j,$tp,$j       ; zap at once
+       or      $aj,$aj,$tj
+       $STX    $aj,$rp,$j
        addi    $j,$j,$BNSZ
        bdnz    Lcopy
 
index 595fc6d31f60cbac7212f0a95d02b7a1e5d0a006..6cf99c5db33011a5eae6703bb123c520d102888a 100644 (file)
@@ -1494,16 +1494,14 @@ Lsub:   ldx     $t0,$tp,$i
 
        li      $i,0
        subfe   $ovf,$i,$ovf    ; handle upmost overflow bit
-       and     $ap,$tp,$ovf
-       andc    $np,$rp,$ovf
-       or      $ap,$ap,$np     ; ap=borrow?tp:rp
-       addi    $t7,$ap,8
        mtctr   $j
 
 .align 4
-Lcopy:                         ; copy or in-place refresh
-       ldx     $t0,$ap,$i
-       ldx     $t1,$t7,$i
+Lcopy:                         ; conditional copy
+       ldx     $t0,$tp,$i
+       ldx     $t1,$t4,$i
+       ldx     $t2,$rp,$i
+       ldx     $t3,$t6,$i
        std     $i,8($nap_d)    ; zap nap_d
        std     $i,16($nap_d)
        std     $i,24($nap_d)
@@ -1512,6 +1510,12 @@ Lcopy:                           ; copy or in-place refresh
        std     $i,48($nap_d)
        std     $i,56($nap_d)
        stdu    $i,64($nap_d)
+       and     $t0,$t0,$ovf
+       and     $t1,$t1,$ovf
+       andc    $t2,$t2,$ovf
+       andc    $t3,$t3,$ovf
+       or      $t0,$t0,$t2
+       or      $t1,$t1,$t3
        stdx    $t0,$rp,$i
        stdx    $t1,$t6,$i
        stdx    $i,$tp,$i       ; zap tp at once
@@ -1554,20 +1558,21 @@ Lsub:   lwz     $t0,12($tp)     ; load tp[j..j+3] in 64-bit word order
 
        li      $i,0
        subfe   $ovf,$i,$ovf    ; handle upmost overflow bit
-       addi    $tp,$sp,`$FRAME+$TRANSFER+4`
+       addi    $ap,$sp,`$FRAME+$TRANSFER+4`
        subf    $rp,$num,$rp    ; rewind rp
-       and     $ap,$tp,$ovf
-       andc    $np,$rp,$ovf
-       or      $ap,$ap,$np     ; ap=borrow?tp:rp
        addi    $tp,$sp,`$FRAME+$TRANSFER`
        mtctr   $j
 
 .align 4
-Lcopy:                         ; copy or in-place refresh
+Lcopy:                         ; conditional copy
        lwz     $t0,4($ap)
        lwz     $t1,8($ap)
        lwz     $t2,12($ap)
        lwzu    $t3,16($ap)
+       lwz     $t4,4($rp)
+       lwz     $t5,8($rp)
+       lwz     $t6,12($rp)
+       lwz     $t7,16($rp)
        std     $i,8($nap_d)    ; zap nap_d
        std     $i,16($nap_d)
        std     $i,24($nap_d)
@@ -1576,6 +1581,18 @@ Lcopy:                           ; copy or in-place refresh
        std     $i,48($nap_d)
        std     $i,56($nap_d)
        stdu    $i,64($nap_d)
+       and     $t0,$t0,$ovf
+       and     $t1,$t1,$ovf
+       and     $t2,$t2,$ovf
+       and     $t3,$t3,$ovf
+       andc    $t4,$t4,$ovf
+       andc    $t5,$t5,$ovf
+       andc    $t6,$t6,$ovf
+       andc    $t7,$t7,$ovf
+       or      $t0,$t0,$t4
+       or      $t1,$t1,$t5
+       or      $t2,$t2,$t6
+       or      $t3,$t3,$t7
        stw     $t0,4($rp)
        stw     $t1,8($rp)
        stw     $t2,12($rp)
index 9fd64e81eef36cbde53332d10743b934218530e5..46188ebb7e5b8826e4457309a84fd0fcbed38f49 100644 (file)
@@ -245,16 +245,16 @@ $code.=<<___;
        brct    $count,.Lsub
        lghi    $ahi,0
        slbgr   $AHI,$ahi       # handle upmost carry
-
-       ngr     $ap,$AHI
-       lghi    $np,-1
-       xgr     $np,$AHI
-       ngr     $np,$rp
-       ogr     $ap,$np         # ap=borrow?tp:rp
+       lghi    $NHI,-1
+       xgr     $NHI,$AHI
 
        la      $j,0(%r0)
        lgr     $count,$num
-.Lcopy:        lg      $alo,0($j,$ap)          # copy or in-place refresh
+.Lcopy:        lg      $ahi,$stdframe($j,$sp)  # conditional copy
+       lg      $alo,0($j,$rp)
+       ngr     $ahi,$AHI
+       ngr     $alo,$NHI
+       ogr     $alo,$ahi
        _dswap  $alo
        stg     $j,$stdframe($j,$sp)    # zap tp
        stg     $alo,0($j,$rp)
index 71b45002a42f739e9a3a30282771f1399a1cdf00..cac60f9978744807e0fa83ccb37388419b314eb8 100755 (executable)
@@ -878,19 +878,17 @@ $code.=<<___;
        sub     $tp,    $num,   $tp
        sub     $rp,    $num,   $rp
 
-       subc    $ovf,   %g0,    $ovf    ! handle upmost overflow bit
-       and     $tp,    $ovf,   $ap
-       andn    $rp,    $ovf,   $np
-       or      $np,    $ap,    $ap     ! ap=borrow?tp:rp
+       subccc  $ovf,   %g0,    $ovf    ! handle upmost overflow bit
        ba      .Lcopy
        sub     $num,   8,      $cnt
 
 .align 16
-.Lcopy:                                        ! copy or in-place refresh
-       ldx     [$ap+0],        $t2
-       add     $ap,    8,      $ap
+.Lcopy:                                        ! conditional copy
+       ldx     [$tp],          $tj
+       ldx     [$rp+0],        $t2
        stx     %g0,    [$tp]           ! zap
        add     $tp,    8,      $tp
+       movcs   %icc,   $tj,    $t2
        stx     $t2,    [$rp+0]
        add     $rp,    8,      $rp
        brnz    $cnt,   .Lcopy
@@ -1126,19 +1124,17 @@ $code.=<<___;
        sub     $tp,    $num,   $tp
        sub     $rp,    $num,   $rp
 
-       subc    $ovf,   %g0,    $ovf    ! handle upmost overflow bit
-       and     $tp,    $ovf,   $ap
-       andn    $rp,    $ovf,   $np
-       or      $np,    $ap,    $ap     ! ap=borrow?tp:rp
+       subccc  $ovf,   %g0,    $ovf    ! handle upmost overflow bit
        ba      .Lcopy_g5
        sub     $num,   8,      $cnt
 
 .align 16
-.Lcopy_g5:                             ! copy or in-place refresh
-       ldx     [$ap+0],        $t2
-       add     $ap,    8,      $ap
+.Lcopy_g5:                             ! conditional copy
+       ldx     [$tp],          $tj
+       ldx     [$rp+0],        $t2
        stx     %g0,    [$tp]           ! zap
        add     $tp,    8,      $tp
+       movcs   %icc,   $tj,    $t2
        stx     $t2,    [$rp+0]
        add     $rp,    8,      $rp
        brnz    $cnt,   .Lcopy_g5
index d8662878006eac393ea6cd6b16a00f75a4c3e980..30db95e157c20d5ea8e6c47ebe27b25c5b05a450 100644 (file)
@@ -255,7 +255,6 @@ $fname:
 .Ltail:
        add     $np,$num,$np
        add     $rp,$num,$rp
-       mov     $tp,$ap
        sub     %g0,$num,%o7            ! k=-num
        ba      .Lsub
        subcc   %g0,%g0,%g0             ! clear %icc.c
@@ -268,15 +267,14 @@ $fname:
        add     %o7,4,%o7
        brnz    %o7,.Lsub
        st      %o1,[$i]
-       subc    $car2,0,$car2           ! handle upmost overflow bit
-       and     $tp,$car2,$ap
-       andn    $rp,$car2,$np
-       or      $ap,$np,$ap
+       subccc  $car2,0,$car2           ! handle upmost overflow bit
        sub     %g0,$num,%o7
 
 .Lcopy:
-       ld      [$ap+%o7],%o0           ! copy or in-place refresh
+       ld      [$tp+%o7],%o1           ! conditional copy
+       ld      [$rp+%o7],%o0
        st      %g0,[$tp+%o7]           ! zap tp
+       movcs   %icc,%o1,%o0
        st      %o0,[$rp+%o7]
        add     %o7,4,%o7
        brnz    %o7,.Lcopy
index c046a514c873fb9e773384b635ac066883f5e565..917942136fcf94816f8513926f2f3c64b8473a77 100644 (file)
@@ -203,18 +203,15 @@ $sp=&DWP(28,"esp");
 
        &mov    ("eax",&DWP(0,"esi","edx",4));  # upmost overflow bit
        &sbb    ("eax",0);
-       &and    ("esi","eax");
-       &not    ("eax");
-       &mov    ("ebp","edi");
-       &and    ("ebp","eax");
-       &or     ("esi","ebp");                  # tp=carry?tp:rp
 
        &mov    ("ecx","edx");                  # num
-       &xor    ("edx","edx");                  # i=0
+       &mov    ("edx",0);                      # i=0
 
 &set_label("copy",8);
-       &mov    ("eax",&DWP(0,"esi","edx",4));
-       &mov    (&DWP(64,"esp","edx",4),"ecx"); # zap tp
+       &mov    ("ebx",&DWP(0,"esi","edx",4));
+       &mov    ("eax",&DWP(0,"edi","edx",4));
+       &mov    (&DWP(0,"esi","edx",4),"ecx");  # zap tp
+       &cmovc  ("eax","ebx");
        &mov    (&DWP(0,"edi","edx",4),"eax");
        &lea    ("edx",&DWP(1,"edx"));          # i++
        &loop   (&label("copy"));
index 263ac02b6f45b750827b126109a8e2d2fb9aa7ab..002c00c2abc621ae5c9583001afcc82cf5fda4c0 100644 (file)
@@ -299,23 +299,23 @@ $code.=<<___;
        sub     $anp,   $num,   $anp
        sub     $rp,    $num,   $rp
 
-       subc    $ovf,   %g0,    $ovf    ! handle upmost overflow bit
-       and     $tp,    $ovf,   $ap
-       andn    $rp,    $ovf,   $np
-       or      $np,    $ap,    $ap     ! ap=borrow?tp:rp
+       subccc  $ovf,   %g0,    $ovf    ! handle upmost overflow bit
        ba      .Lcopy
        sub     $num,   8,      $cnt
 
 .align 16
-.Lcopy:                                        ! copy or in-place refresh
-       ld      [$ap+0],        $t2
-       ld      [$ap+4],        $t3
-       add     $ap,    8,      $ap
+.Lcopy:                                        ! conditional copy
+       ld      [$tp+0],        $t0
+       ld      [$tp+4],        $t1
+       ld      [$rp+0],        $t2
+       ld      [$rp+4],        $t3
        stx     %g0,    [$tp]           ! zap
        add     $tp,    8,      $tp
        stx     %g0,    [$anp]          ! zap
        stx     %g0,    [$anp+8]
        add     $anp,   16,     $anp
+       movcs   %icc,   $t0,    $t2
+       movcs   %icc,   $t1,    $t3
        st      $t3,    [$rp+0]         ! flip order
        st      $t2,    [$rp+4]
        add     $rp,    8,      $rp
index 1c4003efc20a799452e9cfb77f5ec8010f91ec81..d72eb00132b0a006dea84f62f8dead874a8e3e26 100755 (executable)
@@ -592,16 +592,18 @@ $sbit=$num;
        &jge    (&label("sub"));
 
        &sbb    ("eax",0);                      # handle upmost overflow bit
-       &and    ($tp,"eax");
-       &not    ("eax");
-       &mov    ($np,$rp);
-       &and    ($np,"eax");
-       &or     ($tp,$np);                      # tp=carry?tp:rp
-
-&set_label("copy",16);                         # copy or in-place refresh
-       &mov    ("eax",&DWP(0,$tp,$num,4));
-       &mov    (&DWP(0,$rp,$num,4),"eax");     # rp[i]=tp[i]
+       &mov    ("edx",-1);
+       &xor    ("edx","eax");
+       &jmp    (&label("copy"));
+
+&set_label("copy",16);                         # conditional copy
+       &mov    ($tp,&DWP($frame,"esp",$num,4));
+       &mov    ($np,&DWP(0,$rp,$num,4));
        &mov    (&DWP($frame,"esp",$num,4),$j); # zap temporary vector
+       &and    ($tp,"eax");
+       &and    ($np,"edx");
+       &or     ($np,$tp);
+       &mov    (&DWP(0,$rp,$num,4),$np);
        &dec    ($num);
        &jge    (&label("copy"));
 
index 80492d8e6381655c8dd6f11e1d035cc81cfe9631..2074fd802446404b64c11e29a48ff61487a3d4d9 100755 (executable)
@@ -293,30 +293,30 @@ $code.=<<___;
 
        xor     $i,$i                   # i=0 and clear CF!
        mov     (%rsp),%rax             # tp[0]
-       lea     (%rsp),$ap              # borrow ap for tp
        mov     $num,$j                 # j=num
-       jmp     .Lsub
+
 .align 16
 .Lsub: sbb     ($np,$i,8),%rax
        mov     %rax,($rp,$i,8)         # rp[i]=tp[i]-np[i]
-       mov     8($ap,$i,8),%rax        # tp[i+1]
+       mov     8(%rsp,$i,8),%rax       # tp[i+1]
        lea     1($i),$i                # i++
        dec     $j                      # doesnn't affect CF!
        jnz     .Lsub
 
        sbb     \$0,%rax                # handle upmost overflow bit
+       mov     \$-1,%rbx
+       xor     %rax,%rbx               # not %rax
        xor     $i,$i
-       and     %rax,$ap
-       not     %rax
-       mov     $rp,$np
-       and     %rax,$np
        mov     $num,$j                 # j=num
-       or      $np,$ap                 # ap=borrow?tp:rp
-.align 16
-.Lcopy:                                        # copy or in-place refresh
-       mov     ($ap,$i,8),%rax
-       mov     $i,(%rsp,$i,8)          # zap temporary vector
-       mov     %rax,($rp,$i,8)         # rp[i]=tp[i]
+
+.Lcopy:                                        # conditional copy
+       mov     ($rp,$i,8),%rcx
+       mov     (%rsp,$i,8),%rdx
+       and     %rbx,%rcx
+       and     %rax,%rdx
+       mov     $num,(%rsp,$i,8)        # zap temporary vector
+       or      %rcx,%rdx
+       mov     %rdx,($rp,$i,8)         # rp[i]=tp[i]
        lea     1($i),$i
        sub     \$1,$j
        jnz     .Lcopy
@@ -686,10 +686,10 @@ ___
 my @ri=("%rax","%rdx",$m0,$m1);
 $code.=<<___;
        mov     16(%rsp,$num,8),$rp     # restore $rp
+       lea     -4($num),$j
        mov     0(%rsp),@ri[0]          # tp[0]
-       pxor    %xmm0,%xmm0
        mov     8(%rsp),@ri[1]          # tp[1]
-       shr     \$2,$num                # num/=4
+       shr     \$2,$j                  # j=num/4-1
        lea     (%rsp),$ap              # borrow ap for tp
        xor     $i,$i                   # i=0 and clear CF!
 
@@ -697,9 +697,7 @@ $code.=<<___;
        mov     16($ap),@ri[2]          # tp[2]
        mov     24($ap),@ri[3]          # tp[3]
        sbb     8($np),@ri[1]
-       lea     -1($num),$j             # j=num/4-1
-       jmp     .Lsub4x
-.align 16
+
 .Lsub4x:
        mov     @ri[0],0($rp,$i,8)      # rp[i]=tp[i]-np[i]
        mov     @ri[1],8($rp,$i,8)      # rp[i]=tp[i]-np[i]
@@ -726,34 +724,35 @@ $code.=<<___;
 
        sbb     \$0,@ri[0]              # handle upmost overflow bit
        mov     @ri[3],24($rp,$i,8)     # rp[i]=tp[i]-np[i]
-       xor     $i,$i                   # i=0
-       and     @ri[0],$ap
-       not     @ri[0]
-       mov     $rp,$np
-       and     @ri[0],$np
-       lea     -1($num),$j
-       or      $np,$ap                 # ap=borrow?tp:rp
-
-       movdqu  ($ap),%xmm1
-       movdqa  %xmm0,(%rsp)
-       movdqu  %xmm1,($rp)
+       pxor    %xmm0,%xmm0
+       movq    @ri[0],%xmm4
+       pcmpeqd %xmm5,%xmm5
+       pshufd  \$0,%xmm4,%xmm4
+       mov     $num,$j
+       pxor    %xmm4,%xmm5
+       shr     \$2,$j                  # j=num/4
+       xor     %eax,%eax               # i=0
+
        jmp     .Lcopy4x
 .align 16
-.Lcopy4x:                                      # copy or in-place refresh
-       movdqu  16($ap,$i),%xmm2
-       movdqu  32($ap,$i),%xmm1
-       movdqa  %xmm0,16(%rsp,$i)
-       movdqu  %xmm2,16($rp,$i)
-       movdqa  %xmm0,32(%rsp,$i)
-       movdqu  %xmm1,32($rp,$i)
-       lea     32($i),$i
+.Lcopy4x:                              # conditional copy
+       movdqa  (%rsp,%rax),%xmm1
+       movdqu  ($rp,%rax),%xmm2
+       pand    %xmm4,%xmm1
+       pand    %xmm5,%xmm2
+       movdqa  16(%rsp,%rax),%xmm3
+       movdqa  %xmm0,(%rsp,%rax)
+       por     %xmm2,%xmm1
+       movdqu  16($rp,%rax),%xmm2
+       movdqu  %xmm1,($rp,%rax)
+       pand    %xmm4,%xmm3
+       pand    %xmm5,%xmm2
+       movdqa  %xmm0,16(%rsp,%rax)
+       por     %xmm2,%xmm3
+       movdqu  %xmm3,16($rp,%rax)
+       lea     32(%rax),%rax
        dec     $j
        jnz     .Lcopy4x
-
-       shl     \$2,$num
-       movdqu  16($ap,$i),%xmm2
-       movdqa  %xmm0,16(%rsp,$i)
-       movdqu  %xmm2,16($rp,$i)
 ___
 }
 $code.=<<___;
index 42178e455a981d4c5cfd304be4382a9764f29587..f8ff822ba298722ed4232ae09aa86ca2ea184747 100755 (executable)
@@ -405,18 +405,19 @@ $code.=<<___;
        jnz     .Lsub
 
        sbb     \$0,%rax                # handle upmost overflow bit
+       mov     \$-1,%rbx
+       xor     %rax,%rbx
        xor     $i,$i
-       and     %rax,$ap
-       not     %rax
-       mov     $rp,$np
-       and     %rax,$np
        mov     $num,$j                 # j=num
-       or      $np,$ap                 # ap=borrow?tp:rp
-.align 16
-.Lcopy:                                        # copy or in-place refresh
-       mov     ($ap,$i,8),%rax
+
+.Lcopy:                                        # conditional copy
+       mov     ($rp,$i,8),%rcx
+       mov     (%rsp,$i,8),%rdx
+       and     %rbx,%rcx
+       and     %rax,%rdx
        mov     $i,(%rsp,$i,8)          # zap temporary vector
-       mov     %rax,($rp,$i,8)         # rp[i]=tp[i]
+       or      %rcx,%rdx
+       mov     %rdx,($rp,$i,8)         # rp[i]=tp[i]
        lea     1($i),$i
        sub     \$1,$j
        jnz     .Lcopy