openssl/crypto/sha/asm/sha1-s390x.pl

222 lines
4.2 KiB
Perl
Raw Normal View History

2007-04-30 08:42:54 +00:00
#!/usr/bin/env perl
# ====================================================================
# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
# 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/.
# ====================================================================
# SHA1 block procedure for s390x.
# April 2007.
#
# Performance is >30% better than gcc 3.3 generated code. But the real
# twist is that SHA1 hardware support is detected and utilized. In
# which case performance can reach further >4.5x for larger chunks.
2007-04-30 08:42:54 +00:00
2009-02-09 15:42:04 +00:00
# January 2009.
#
# Optimize Xupdate for amount of memory references and reschedule
# instructions to favour dual-issue z10 pipeline. On z10 hardware is
# "only" ~2.3x faster than software.
2007-04-30 08:42:54 +00:00
$kimdfunc=1; # magic function code for kimd instruction
$output=shift;
open STDOUT,">$output";
2009-02-09 15:42:04 +00:00
$K_00_39="%r0"; $K=$K_00_39;
$K_40_79="%r1";
$ctx="%r2"; $prefetch="%r2";
2007-04-30 08:42:54 +00:00
$inp="%r3";
$len="%r4";
$A="%r5";
$B="%r6";
$C="%r7";
$D="%r8";
$E="%r9"; @V=($A,$B,$C,$D,$E);
2009-02-09 15:42:04 +00:00
$t0="%r10";
$t1="%r11";
@X=("%r12","%r13","%r14");
2007-04-30 08:42:54 +00:00
$sp="%r15";
$frame=160+16*4;
sub Xupdate {
my $i=shift;
2009-02-09 15:42:04 +00:00
$code.=<<___ if ($i==15);
lg $prefetch,160($sp) ### Xupdate(16) warm-up
lr $X[0],$X[2]
___
2007-04-30 08:42:54 +00:00
return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle
2009-02-09 15:42:04 +00:00
$code.=<<___ if ($i<16);
lg $X[0],`$i*4`($inp) ### Xload($i)
rllg $X[1],$X[0],32
2007-04-30 08:42:54 +00:00
___
2009-02-09 15:42:04 +00:00
$code.=<<___ if ($i>=16);
xgr $X[0],$prefetch ### Xupdate($i)
lg $prefetch,`160+4*(($i+2)%16)`($sp)
xg $X[0],`160+4*(($i+8)%16)`($sp)
xgr $X[0],$prefetch
rll $X[0],$X[0],1
rllg $X[1],$X[0],32
rll $X[1],$X[1],1
rllg $X[0],$X[1],32
lr $X[2],$X[1] # feedback
2007-04-30 08:42:54 +00:00
___
2009-02-09 15:42:04 +00:00
$code.=<<___ if ($i<=70);
stg $X[0],`160+4*($i%16)`($sp)
2007-04-30 08:42:54 +00:00
___
2009-02-09 15:42:04 +00:00
unshift(@X,pop(@X));
2007-04-30 08:42:54 +00:00
}
2009-02-09 15:42:04 +00:00
sub BODY_00_19 {
my ($i,$a,$b,$c,$d,$e)=@_;
my $xi=$X[1];
&Xupdate($i);
2007-04-30 08:42:54 +00:00
$code.=<<___;
2009-02-09 15:42:04 +00:00
alr $e,$K ### $i
rll $t1,$a,5
lr $t0,$d
xr $t0,$c
alr $e,$t1
nr $t0,$b
alr $e,$xi
xr $t0,$d
rll $b,$b,30
alr $e,$t0
2007-04-30 08:42:54 +00:00
___
}
sub BODY_20_39 {
my ($i,$a,$b,$c,$d,$e)=@_;
2009-02-09 15:42:04 +00:00
my $xi=$X[1];
2007-04-30 08:42:54 +00:00
&Xupdate($i);
$code.=<<___;
2009-02-09 15:42:04 +00:00
alr $e,$K ### $i
rll $t1,$a,5
2007-04-30 08:42:54 +00:00
lr $t0,$b
2009-02-09 15:42:04 +00:00
alr $e,$t1
2007-04-30 08:42:54 +00:00
xr $t0,$c
2009-02-09 15:42:04 +00:00
alr $e,$xi
2007-04-30 08:42:54 +00:00
xr $t0,$d
rll $b,$b,30
2009-02-09 15:42:04 +00:00
alr $e,$t0
2007-04-30 08:42:54 +00:00
___
}
sub BODY_40_59 {
my ($i,$a,$b,$c,$d,$e)=@_;
2009-02-09 15:42:04 +00:00
my $xi=$X[1];
2007-04-30 08:42:54 +00:00
&Xupdate($i);
$code.=<<___;
2009-02-09 15:42:04 +00:00
alr $e,$K ### $i
rll $t1,$a,5
2007-04-30 08:42:54 +00:00
lr $t0,$b
2009-02-09 15:42:04 +00:00
alr $e,$t1
2007-04-30 08:42:54 +00:00
or $t0,$c
lr $t1,$b
2009-02-09 15:42:04 +00:00
nr $t0,$d
2007-04-30 08:42:54 +00:00
nr $t1,$c
2009-02-09 15:42:04 +00:00
alr $e,$xi
2007-04-30 08:42:54 +00:00
or $t0,$t1
rll $b,$b,30
2009-02-09 15:42:04 +00:00
alr $e,$t0
2007-04-30 08:42:54 +00:00
___
}
$code.=<<___;
.text
2009-02-09 15:42:04 +00:00
.align 64
.type Ktable,\@object
Ktable: .long 0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
.skip 48 #.long 0,0,0,0,0,0,0,0,0,0,0,0
.size Ktable,.-Ktable
2007-04-30 08:42:54 +00:00
.globl sha1_block_data_order
.type sha1_block_data_order,\@function
sha1_block_data_order:
___
$code.=<<___ if ($kimdfunc);
lghi %r0,0
la %r1,16($sp)
.long 0xb93e0002 # kimd %r0,%r2
lg %r0,16($sp)
tmhh %r0,`0x8000>>$kimdfunc`
jz .Lsoftware
lghi %r0,$kimdfunc
lgr %r1,$ctx
lgr %r2,$inp
sllg %r3,$len,6
.long 0xb93e0002 # kimd %r0,%r2
brc 1,.-4 # pay attention to "partial completion"
2007-04-30 08:42:54 +00:00
br %r14
2009-04-26 18:11:25 +00:00
.align 16
2007-04-30 08:42:54 +00:00
.Lsoftware:
___
$code.=<<___;
2009-02-09 15:42:04 +00:00
lghi %r1,-$frame
stg $ctx,16($sp)
2007-04-30 08:42:54 +00:00
stmg %r6,%r15,48($sp)
lgr %r0,$sp
2009-02-09 15:42:04 +00:00
la $sp,0(%r1,$sp)
2007-04-30 08:42:54 +00:00
stg %r0,0($sp)
2009-02-09 15:42:04 +00:00
larl $t0,Ktable
2007-04-30 08:42:54 +00:00
llgf $A,0($ctx)
llgf $B,4($ctx)
llgf $C,8($ctx)
llgf $D,12($ctx)
llgf $E,16($ctx)
2009-02-09 15:42:04 +00:00
lg $K_00_39,0($t0)
lg $K_40_79,8($t0)
2007-04-30 08:42:54 +00:00
.Lloop:
2009-02-09 15:42:04 +00:00
rllg $K_00_39,$K_00_39,32
___
for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
rllg $K_00_39,$K_00_39,32
2007-04-30 08:42:54 +00:00
___
for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
2009-02-09 15:42:04 +00:00
$code.=<<___; $K=$K_40_79;
rllg $K_40_79,$K_40_79,32
___
2007-04-30 08:42:54 +00:00
for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
2009-02-09 15:42:04 +00:00
$code.=<<___;
rllg $K_40_79,$K_40_79,32
___
2007-04-30 08:42:54 +00:00
for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
2009-02-09 15:42:04 +00:00
lg $ctx,`$frame+16`($sp)
la $inp,64($inp)
2007-04-30 08:42:54 +00:00
al $A,0($ctx)
al $B,4($ctx)
al $C,8($ctx)
al $D,12($ctx)
al $E,16($ctx)
st $A,0($ctx)
st $B,4($ctx)
st $C,8($ctx)
st $D,12($ctx)
st $E,16($ctx)
2009-02-09 15:42:04 +00:00
brct $len,.Lloop
2007-04-30 08:42:54 +00:00
lmg %r6,%r15,`$frame+48`($sp)
br %r14
.size sha1_block_data_order,.-sha1_block_data_order
.string "SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
___
$code =~ s/\`([^\`]*)\`/eval $1/gem;
print $code;
close STDOUT;