Socket-Class
view release on metacpan or search on metacpan
xs/sc_ssl/openssl/source/crypto/camellia/asm/cmll-x86_64.pl view on Meta::CPAN
#!/usr/bin/env perl
# ====================================================================
# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
#
# This module may be used under the terms of either the GNU General
# Public License version 2 or later, the GNU Lesser General Public
# License version 2.1 or later, the Mozilla Public License version
# 1.1 or the BSD License. The exact terms of either license are
# distributed along with this module. For further details see
# http://www.openssl.org/~appro/camellia/.
# ====================================================================
# Performance in cycles per processed byte (less is better) in
# 'openssl speed ...' benchmark:
#
# AMD64 Core2 EM64T
# -evp camellia-128-ecb 16.7 21.0 22.7
# + over gcc 3.4.6 +25% +5% 0%
#
# camellia-128-cbc 15.7 20.4 21.1
#
# 128-bit key setup 128 216 205 cycles/key
# + over gcc 3.4.6 +54% +39% +15%
#
# Numbers in "+" rows represent performance improvement over compiler
# generated code. Key setup timings are impressive on AMD and Core2
# thanks to 64-bit operations being covertly deployed. Improvement on
# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
# apparently emulates some of 64-bit operations in [32-bit] microcode.
$flavour = shift;
$output = shift;
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
open STDOUT,"| $^X $xlate $flavour $output";
sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
$r =~ s/%[er]([sd]i)/%\1l/;
$r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; }
$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
@S=("%r8d","%r9d","%r10d","%r11d");
$i0="%esi";
$i1="%edi";
$Tbl="%rbp"; # size optimization
$inp="%r12";
$out="%r13";
$key="%r14";
$keyend="%r15";
$arg0d=$win64?"%ecx":"%edi";
# const unsigned int Camellia_SBOX[4][256];
# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
# and [2][] - with [3][]. This is done to minimize code size.
$SBOX1_1110=0; # Camellia_SBOX[0]
$SBOX4_4404=4; # Camellia_SBOX[1]
$SBOX2_0222=2048; # Camellia_SBOX[2]
$SBOX3_3033=2052; # Camellia_SBOX[3]
sub Camellia_Feistel {
my $i=@_[0];
my $seed=defined(@_[1])?@_[1]:0;
my $scale=$seed<0?-8:8;
my $j=($i&1)*2;
my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4];
$code.=<<___;
xor $s0,$t0 # t0^=key[0]
xor $s1,$t1 # t1^=key[1]
movz `&hi("$t0")`,$i0 # (t0>>8)&0xff
movz `&lo("$t1")`,$i1 # (t1>>0)&0xff
mov $SBOX3_3033($Tbl,$i0,8),$t3 # t3=SBOX3_3033[0]
mov $SBOX1_1110($Tbl,$i1,8),$t2 # t2=SBOX1_1110[1]
movz `&lo("$t0")`,$i0 # (t0>>0)&0xff
shr \$16,$t0
movz `&hi("$t1")`,$i1 # (t1>>8)&0xff
xor $SBOX4_4404($Tbl,$i0,8),$t3 # t3^=SBOX4_4404[0]
shr \$16,$t1
xor $SBOX4_4404($Tbl,$i1,8),$t2 # t2^=SBOX4_4404[1]
movz `&hi("$t0")`,$i0 # (t0>>24)&0xff
movz `&lo("$t1")`,$i1 # (t1>>16)&0xff
xor $SBOX1_1110($Tbl,$i0,8),$t3 # t3^=SBOX1_1110[0]
xor $SBOX3_3033($Tbl,$i1,8),$t2 # t2^=SBOX3_3033[1]
movz `&lo("$t0")`,$i0 # (t0>>16)&0xff
movz `&hi("$t1")`,$i1 # (t1>>24)&0xff
xor $SBOX2_0222($Tbl,$i0,8),$t3 # t3^=SBOX2_0222[0]
xor $SBOX2_0222($Tbl,$i1,8),$t2 # t2^=SBOX2_0222[1]
mov `$seed+($i+1)*$scale`($key),$t1 # prefetch key[i+1]
mov `$seed+($i+1)*$scale+4`($key),$t0
xor $t3,$t2 # t2^=t3
ror \$8,$t3 # t3=RightRotate(t3,8)
xor $t2,$s2
xor $t2,$s3
xor $t3,$s3
___
}
( run in 1.575 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )