PPC assembly pack: add .size directives.
[openssl.git] / crypto / bn / asm / ppc-mont.pl
index 8a260212b76a06a6fa3ad64bd422d617cc0dd08b..da69c6aaaf6a55b07114333a008c39571f153721 100644 (file)
@@ -2,8 +2,9 @@
 
 # ====================================================================
 # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
-# project. Rights for redistribution and usage in source and binary
-# forms are granted according to the OpenSSL license.
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
 # ====================================================================
 
 # April 2006
 # 2048-bit     +18%
 # 4096-bit     +4%
 
-$output = shift;
+$flavour = shift;
 
-if ($output =~ /32\-mont\.s/) {
+if ($flavour =~ /32/) {
        $BITS=  32;
        $BNSZ=  $BITS/8;
        $SIZE_T=4;
        $RZONE= 224;
-       $FRAME= $SIZE_T*16;
 
        $LD=    "lwz";          # load
        $LDU=   "lwzu";         # load and update
@@ -42,14 +42,14 @@ if ($output =~ /32\-mont\.s/) {
        $UMULL= "mullw";        # unsigned multiply low
        $UMULH= "mulhwu";       # unsigned multiply high
        $UCMP=  "cmplw";        # unsigned compare
+       $SHRI=  "srwi";         # unsigned shift right by immediate     
        $PUSH=  $ST;
        $POP=   $LD;
-} elsif ($output =~ /64\-mont\.s/) {
+} elsif ($flavour =~ /64/) {
        $BITS=  64;
        $BNSZ=  $BITS/8;
        $SIZE_T=8;
        $RZONE= 288;
-       $FRAME= $SIZE_T*16;
 
        # same as above, but 64-bit mnemonics...
        $LD=    "ld";           # load
@@ -62,12 +62,20 @@ if ($output =~ /32\-mont\.s/) {
        $UMULL= "mulld";        # unsigned multiply low
        $UMULH= "mulhdu";       # unsigned multiply high
        $UCMP=  "cmpld";        # unsigned compare
+       $SHRI=  "srdi";         # unsigned shift right by immediate     
        $PUSH=  $ST;
        $POP=   $LD;
-} else { die "nonsense $output"; }
+} else { die "nonsense $flavour"; }
 
-( defined shift || open STDOUT,"| $^X ../perlasm/ppc-xlate.pl $output" ) ||
-       die "can't call ../perlasm/ppc-xlate.pl: $!";
+$FRAME=8*$SIZE_T+$RZONE;
+$LOCALS=8*$SIZE_T;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
 
 $sp="r1";
 $toc="r2";
@@ -82,60 +90,67 @@ $aj="r10";
 $nj="r11";
 $tj="r12";
 # non-volatile registers
-$i="r14";
-$j="r15";
-$tp="r16";
-$m0="r17";
-$m1="r18";
-$lo0="r19";
-$hi0="r20";
-$lo1="r21";
-$hi1="r22";
-$alo="r23";
-$ahi="r24";
-$nlo="r25";
+$i="r20";
+$j="r21";
+$tp="r22";
+$m0="r23";
+$m1="r24";
+$lo0="r25";
+$hi0="r26";
+$lo1="r27";
+$hi1="r28";
+$alo="r29";
+$ahi="r30";
+$nlo="r31";
 #
 $nhi="r0";
 
 $code=<<___;
+.machine "any"
 .text
 
-.globl .bn_mul_mont
+.globl .bn_mul_mont_int
 .align 4
-.bn_mul_mont:
+.bn_mul_mont_int:
        cmpwi   $num,4
        mr      $rp,r3          ; $rp is reassigned
        li      r3,0
        bltlr
-
+___
+$code.=<<___ if ($BNSZ==4);
+       cmpwi   $num,32         ; longer key performance is not better
+       bgelr
+___
+$code.=<<___;
        slwi    $num,$num,`log($BNSZ)/log(2)`
        li      $tj,-4096
-       addi    $ovf,$num,`$FRAME+$RZONE`
+       addi    $ovf,$num,$FRAME
        subf    $ovf,$ovf,$sp   ; $sp-$ovf
        and     $ovf,$ovf,$tj   ; minimize TLB usage
        subf    $ovf,$sp,$ovf   ; $ovf-$sp
+       mr      $tj,$sp
        srwi    $num,$num,`log($BNSZ)/log(2)`
        $STUX   $sp,$sp,$ovf
 
-       $PUSH   r14,`4*$SIZE_T`($sp)
-       $PUSH   r15,`5*$SIZE_T`($sp)
-       $PUSH   r16,`6*$SIZE_T`($sp)
-       $PUSH   r17,`7*$SIZE_T`($sp)
-       $PUSH   r18,`8*$SIZE_T`($sp)
-       $PUSH   r19,`9*$SIZE_T`($sp)
-       $PUSH   r20,`10*$SIZE_T`($sp)
-       $PUSH   r21,`11*$SIZE_T`($sp)
-       $PUSH   r22,`12*$SIZE_T`($sp)
-       $PUSH   r23,`13*$SIZE_T`($sp)
-       $PUSH   r24,`14*$SIZE_T`($sp)
-       $PUSH   r25,`15*$SIZE_T`($sp)
+       $PUSH   r20,`-12*$SIZE_T`($tj)
+       $PUSH   r21,`-11*$SIZE_T`($tj)
+       $PUSH   r22,`-10*$SIZE_T`($tj)
+       $PUSH   r23,`-9*$SIZE_T`($tj)
+       $PUSH   r24,`-8*$SIZE_T`($tj)
+       $PUSH   r25,`-7*$SIZE_T`($tj)
+       $PUSH   r26,`-6*$SIZE_T`($tj)
+       $PUSH   r27,`-5*$SIZE_T`($tj)
+       $PUSH   r28,`-4*$SIZE_T`($tj)
+       $PUSH   r29,`-3*$SIZE_T`($tj)
+       $PUSH   r30,`-2*$SIZE_T`($tj)
+       $PUSH   r31,`-1*$SIZE_T`($tj)
 
        $LD     $n0,0($n0)      ; pull n0[0] value
        addi    $num,$num,-2    ; adjust $num for counter register
 \f
        $LD     $m0,0($bp)      ; m0=bp[0]
        $LD     $aj,0($ap)      ; ap[0]
-       addi    $tp,$sp,$FRAME
+       addi    $tp,$sp,$LOCALS
        $UMULL  $lo0,$aj,$m0    ; ap[0]*bp[0]
        $UMULH  $hi0,$aj,$m0
 
@@ -161,17 +176,16 @@ $code=<<___;
 .align 4
 L1st:
        $LDX    $aj,$ap,$j      ; ap[j]
-       $LDX    $nj,$np,$j      ; np[j]
        addc    $lo0,$alo,$hi0
+       $LDX    $nj,$np,$j      ; np[j]
        addze   $hi0,$ahi
        $UMULL  $alo,$aj,$m0    ; ap[j]*bp[0]
-       $UMULH  $ahi,$aj,$m0
-
        addc    $lo1,$nlo,$hi1
+       $UMULH  $ahi,$aj,$m0
        addze   $hi1,$nhi
        $UMULL  $nlo,$nj,$m1    ; np[j]*m1
-       $UMULH  $nhi,$nj,$m1
        addc    $lo1,$lo1,$lo0  ; np[j]*m1+ap[j]*bp[0]
+       $UMULH  $nhi,$nj,$m1
        addze   $hi1,$hi1
        $ST     $lo1,0($tp)     ; tp[j-1]
 
@@ -198,27 +212,23 @@ L1st:
 Louter:
        $LDX    $m0,$bp,$i      ; m0=bp[i]
        $LD     $aj,0($ap)      ; ap[0]
-       addi    $tp,$sp,$FRAME
-       $LD     $tj,$FRAME($sp) ; tp[0]
+       addi    $tp,$sp,$LOCALS
+       $LD     $tj,$LOCALS($sp); tp[0]
        $UMULL  $lo0,$aj,$m0    ; ap[0]*bp[i]
        $UMULH  $hi0,$aj,$m0
        $LD     $aj,$BNSZ($ap)  ; ap[1]
        $LD     $nj,0($np)      ; np[0]
        addc    $lo0,$lo0,$tj   ; ap[0]*bp[i]+tp[0]
+       $UMULL  $alo,$aj,$m0    ; ap[j]*bp[i]
        addze   $hi0,$hi0
-
        $UMULL  $m1,$lo0,$n0    ; tp[0]*n0
-
-       $UMULL  $alo,$aj,$m0    ; ap[j]*bp[i]
        $UMULH  $ahi,$aj,$m0
-
        $UMULL  $lo1,$nj,$m1    ; np[0]*m1
        $UMULH  $hi1,$nj,$m1
        $LD     $nj,$BNSZ($np)  ; np[1]
        addc    $lo1,$lo1,$lo0
-       addze   $hi1,$hi1
-
        $UMULL  $nlo,$nj,$m1    ; np[1]*m1
+       addze   $hi1,$hi1
        $UMULH  $nhi,$nj,$m1
 \f
        mtctr   $num
@@ -226,24 +236,22 @@ Louter:
 .align 4
 Linner:
        $LDX    $aj,$ap,$j      ; ap[j]
-       $LD     $tj,$BNSZ($tp)  ; tp[j]
        addc    $lo0,$alo,$hi0
+       $LD     $tj,$BNSZ($tp)  ; tp[j]
        addze   $hi0,$ahi
        $LDX    $nj,$np,$j      ; np[j]
-       addc    $lo0,$lo0,$tj   ; ap[j]*bp[i]+tp[j]
-       addze   $hi0,$hi0
-       $UMULL  $alo,$aj,$m0    ; ap[j]*bp[i]
-       $UMULH  $ahi,$aj,$m0
-
        addc    $lo1,$nlo,$hi1
+       $UMULL  $alo,$aj,$m0    ; ap[j]*bp[i]
        addze   $hi1,$nhi
+       $UMULH  $ahi,$aj,$m0
+       addc    $lo0,$lo0,$tj   ; ap[j]*bp[i]+tp[j]
        $UMULL  $nlo,$nj,$m1    ; np[j]*m1
+       addze   $hi0,$hi0
        $UMULH  $nhi,$nj,$m1
        addc    $lo1,$lo1,$lo0  ; np[j]*m1+ap[j]*bp[i]+tp[j]
+       addi    $j,$j,$BNSZ     ; j++
        addze   $hi1,$hi1
        $ST     $lo1,0($tp)     ; tp[j-1]
-
-       addi    $j,$j,$BNSZ     ; j++
        addi    $tp,$tp,$BNSZ   ; tp++
        bdnz-   Linner
 ;Linner
@@ -271,55 +279,55 @@ Linner:
        ble-    Louter
 \f
        addi    $num,$num,2     ; restore $num
-       addi    $tp,$sp,$FRAME
+       subfc   $j,$j,$j        ; j=0 and "clear" XER[CA]
+       addi    $tp,$sp,$LOCALS
        mtctr   $num
+
+.align 4
+Lsub:  $LDX    $tj,$tp,$j
+       $LDX    $nj,$np,$j
+       subfe   $aj,$nj,$tj     ; tp[j]-np[j]
+       $STX    $aj,$rp,$j
+       addi    $j,$j,$BNSZ
+       bdnz-   Lsub
+
        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
 
-       subfc.  $ovf,$j,$ovf    ; sets XER[CA]
-       bne     Lsub
-       $UCMP   $hi1,$nj
-       bge     Lsub
 .align 4
-Lcopy:
-       $LDX    $tj,$tp,$j
+Lcopy:                         ; copy or in-place refresh
+       $LDX    $tj,$ap,$j
        $STX    $tj,$rp,$j
        $STX    $j,$tp,$j       ; zap at once
        addi    $j,$j,$BNSZ
        bdnz-   Lcopy
 
-Lexit:
-       $POP    r14,`4*$SIZE_T`($sp)
-       $POP    r15,`5*$SIZE_T`($sp)
-       $POP    r16,`6*$SIZE_T`($sp)
-       $POP    r17,`7*$SIZE_T`($sp)
-       $POP    r18,`8*$SIZE_T`($sp)
-       $POP    r19,`9*$SIZE_T`($sp)
-       $POP    r20,`10*$SIZE_T`($sp)
-       $POP    r21,`11*$SIZE_T`($sp)
-       $POP    r22,`12*$SIZE_T`($sp)
-       $POP    r23,`13*$SIZE_T`($sp)
-       $POP    r24,`14*$SIZE_T`($sp)
-       $POP    r25,`15*$SIZE_T`($sp)
-       $POP    $sp,0($sp)
+       $POP    $tj,0($sp)
        li      r3,1
+       $POP    r20,`-12*$SIZE_T`($tj)
+       $POP    r21,`-11*$SIZE_T`($tj)
+       $POP    r22,`-10*$SIZE_T`($tj)
+       $POP    r23,`-9*$SIZE_T`($tj)
+       $POP    r24,`-8*$SIZE_T`($tj)
+       $POP    r25,`-7*$SIZE_T`($tj)
+       $POP    r26,`-6*$SIZE_T`($tj)
+       $POP    r27,`-5*$SIZE_T`($tj)
+       $POP    r28,`-4*$SIZE_T`($tj)
+       $POP    r29,`-3*$SIZE_T`($tj)
+       $POP    r30,`-2*$SIZE_T`($tj)
+       $POP    r31,`-1*$SIZE_T`($tj)
+       mr      $sp,$tj
        blr
        .long   0
-.align 4
-Lsub:  $LDX    $tj,$tp,$j
-       $LDX    $nj,$np,$j
-       subfe   $tj,$nj,$tj     ; tp[j]-np[j]
-       $STX    $tj,$rp,$j
-       addi    $j,$j,$BNSZ
-       bdnz-   Lsub
-       li      $j,0
-       subfe.  $ovf,$j,$ovf
-       mtctr   $num
-       bne     Lcopy
-.align 4
-Lzap:  $STX    $j,$tp,$j
-       addi    $j,$j,$BNSZ
-       bdnz-   Lzap
-       b       Lexit
+       .byte   0,12,4,0,0x80,12,6,0
+       .long   0
+.size  .bn_mul_mont_int,.-.bn_mul_mont_int
+
+.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@openssl.org>"
 ___
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;