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 )