Blame crypto/bn/asm/co-586.pl

Packit c4476c
#! /usr/bin/env perl
Packit c4476c
# Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
#
Packit c4476c
# Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
# this file except in compliance with the License.  You can obtain a copy
Packit c4476c
# in the file LICENSE in the source distribution or at
Packit c4476c
# https://www.openssl.org/source/license.html
Packit c4476c
Packit c4476c
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
Packit c4476c
push(@INC,"${dir}","${dir}../../perlasm");
Packit c4476c
require "x86asm.pl";
Packit c4476c
Packit c4476c
$output = pop;
Packit c4476c
open STDOUT,">$output";
Packit c4476c
Packit c4476c
&asm_init($ARGV[0]);
Packit c4476c
Packit c4476c
&bn_mul_comba("bn_mul_comba8",8);
Packit c4476c
&bn_mul_comba("bn_mul_comba4",4);
Packit c4476c
&bn_sqr_comba("bn_sqr_comba8",8);
Packit c4476c
&bn_sqr_comba("bn_sqr_comba4",4);
Packit c4476c
Packit c4476c
&asm_finish();
Packit c4476c
Packit c4476c
close STDOUT or die "error closing STDOUT: $!";
Packit c4476c
Packit c4476c
sub mul_add_c
Packit c4476c
	{
Packit c4476c
	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
Packit c4476c
Packit c4476c
	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
Packit c4476c
	# words, and 1 if load return value
Packit c4476c
Packit c4476c
	&comment("mul a[$ai]*b[$bi]");
Packit c4476c
Packit c4476c
	# "eax" and "edx" will always be pre-loaded.
Packit c4476c
	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
Packit c4476c
	# &mov("edx",&DWP($bi*4,$b,"",0));
Packit c4476c
Packit c4476c
	&mul("edx");
Packit c4476c
	&add($c0,"eax");
Packit c4476c
	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
Packit c4476c
	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
Packit c4476c
	 ###
Packit c4476c
	&adc($c1,"edx");
Packit c4476c
	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# load next b
Packit c4476c
	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# load next b
Packit c4476c
	 ###
Packit c4476c
	&adc($c2,0);
Packit c4476c
	 # is pos > 1, it means it is the last loop
Packit c4476c
	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
Packit c4476c
	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next a
Packit c4476c
	}
Packit c4476c
Packit c4476c
sub sqr_add_c
Packit c4476c
	{
Packit c4476c
	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
Packit c4476c
Packit c4476c
	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
Packit c4476c
	# words, and 1 if load return value
Packit c4476c
Packit c4476c
	&comment("sqr a[$ai]*a[$bi]");
Packit c4476c
Packit c4476c
	# "eax" and "edx" will always be pre-loaded.
Packit c4476c
	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
Packit c4476c
	# &mov("edx",&DWP($bi*4,$b,"",0));
Packit c4476c
Packit c4476c
	if ($ai == $bi)
Packit c4476c
		{ &mul("eax");}
Packit c4476c
	else
Packit c4476c
		{ &mul("edx");}
Packit c4476c
	&add($c0,"eax");
Packit c4476c
	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
Packit c4476c
	 ###
Packit c4476c
	&adc($c1,"edx");
Packit c4476c
	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
Packit c4476c
	 ###
Packit c4476c
	&adc($c2,0);
Packit c4476c
	 # is pos > 1, it means it is the last loop
Packit c4476c
	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
Packit c4476c
	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
Packit c4476c
	}
Packit c4476c
Packit c4476c
sub sqr_add_c2
Packit c4476c
	{
Packit c4476c
	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
Packit c4476c
Packit c4476c
	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
Packit c4476c
	# words, and 1 if load return value
Packit c4476c
Packit c4476c
	&comment("sqr a[$ai]*a[$bi]");
Packit c4476c
Packit c4476c
	# "eax" and "edx" will always be pre-loaded.
Packit c4476c
	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
Packit c4476c
	# &mov("edx",&DWP($bi*4,$a,"",0));
Packit c4476c
Packit c4476c
	if ($ai == $bi)
Packit c4476c
		{ &mul("eax");}
Packit c4476c
	else
Packit c4476c
		{ &mul("edx");}
Packit c4476c
	&add("eax","eax");
Packit c4476c
	 ###
Packit c4476c
	&adc("edx","edx");
Packit c4476c
	 ###
Packit c4476c
	&adc($c2,0);
Packit c4476c
	 &add($c0,"eax");
Packit c4476c
	&adc($c1,"edx");
Packit c4476c
	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
Packit c4476c
	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
Packit c4476c
	&adc($c2,0);
Packit c4476c
	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
Packit c4476c
	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
Packit c4476c
	 ###
Packit c4476c
	}
Packit c4476c
Packit c4476c
sub bn_mul_comba
Packit c4476c
	{
Packit c4476c
	local($name,$num)=@_;
Packit c4476c
	local($a,$b,$c0,$c1,$c2);
Packit c4476c
	local($i,$as,$ae,$bs,$be,$ai,$bi);
Packit c4476c
	local($tot,$end);
Packit c4476c
Packit c4476c
	&function_begin_B($name,"");
Packit c4476c
Packit c4476c
	$c0="ebx";
Packit c4476c
	$c1="ecx";
Packit c4476c
	$c2="ebp";
Packit c4476c
	$a="esi";
Packit c4476c
	$b="edi";
Packit c4476c
Packit c4476c
	$as=0;
Packit c4476c
	$ae=0;
Packit c4476c
	$bs=0;
Packit c4476c
	$be=0;
Packit c4476c
	$tot=$num+$num-1;
Packit c4476c
Packit c4476c
	&push("esi");
Packit c4476c
	 &mov($a,&wparam(1));
Packit c4476c
	&push("edi");
Packit c4476c
	 &mov($b,&wparam(2));
Packit c4476c
	&push("ebp");
Packit c4476c
	 &push("ebx");
Packit c4476c
Packit c4476c
	&xor($c0,$c0);
Packit c4476c
	 &mov("eax",&DWP(0,$a,"",0));	# load the first word
Packit c4476c
	&xor($c1,$c1);
Packit c4476c
	 &mov("edx",&DWP(0,$b,"",0));	# load the first second
Packit c4476c
Packit c4476c
	for ($i=0; $i<$tot; $i++)
Packit c4476c
		{
Packit c4476c
		$ai=$as;
Packit c4476c
		$bi=$bs;
Packit c4476c
		$end=$be+1;
Packit c4476c
Packit c4476c
		&comment("################## Calculate word $i");
Packit c4476c
Packit c4476c
		for ($j=$bs; $j<$end; $j++)
Packit c4476c
			{
Packit c4476c
			&xor($c2,$c2) if ($j == $bs);
Packit c4476c
			if (($j+1) == $end)
Packit c4476c
				{
Packit c4476c
				$v=1;
Packit c4476c
				$v=2 if (($i+1) == $tot);
Packit c4476c
				}
Packit c4476c
			else
Packit c4476c
				{ $v=0; }
Packit c4476c
			if (($j+1) != $end)
Packit c4476c
				{
Packit c4476c
				$na=($ai-1);
Packit c4476c
				$nb=($bi+1);
Packit c4476c
				}
Packit c4476c
			else
Packit c4476c
				{
Packit c4476c
				$na=$as+($i < ($num-1));
Packit c4476c
				$nb=$bs+($i >= ($num-1));
Packit c4476c
				}
Packit c4476c
#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
Packit c4476c
			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
Packit c4476c
			if ($v)
Packit c4476c
				{
Packit c4476c
				&comment("saved r[$i]");
Packit c4476c
				# &mov("eax",&wparam(0));
Packit c4476c
				# &mov(&DWP($i*4,"eax","",0),$c0);
Packit c4476c
				($c0,$c1,$c2)=($c1,$c2,$c0);
Packit c4476c
				}
Packit c4476c
			$ai--;
Packit c4476c
			$bi++;
Packit c4476c
			}
Packit c4476c
		$as++ if ($i < ($num-1));
Packit c4476c
		$ae++ if ($i >= ($num-1));
Packit c4476c
Packit c4476c
		$bs++ if ($i >= ($num-1));
Packit c4476c
		$be++ if ($i < ($num-1));
Packit c4476c
		}
Packit c4476c
	&comment("save r[$i]");
Packit c4476c
	# &mov("eax",&wparam(0));
Packit c4476c
	&mov(&DWP($i*4,"eax","",0),$c0);
Packit c4476c
Packit c4476c
	&pop("ebx");
Packit c4476c
	&pop("ebp");
Packit c4476c
	&pop("edi");
Packit c4476c
	&pop("esi");
Packit c4476c
	&ret();
Packit c4476c
	&function_end_B($name);
Packit c4476c
	}
Packit c4476c
Packit c4476c
sub bn_sqr_comba
Packit c4476c
	{
Packit c4476c
	local($name,$num)=@_;
Packit c4476c
	local($r,$a,$c0,$c1,$c2)=@_;
Packit c4476c
	local($i,$as,$ae,$bs,$be,$ai,$bi);
Packit c4476c
	local($b,$tot,$end,$half);
Packit c4476c
Packit c4476c
	&function_begin_B($name,"");
Packit c4476c
Packit c4476c
	$c0="ebx";
Packit c4476c
	$c1="ecx";
Packit c4476c
	$c2="ebp";
Packit c4476c
	$a="esi";
Packit c4476c
	$r="edi";
Packit c4476c
Packit c4476c
	&push("esi");
Packit c4476c
	 &push("edi");
Packit c4476c
	&push("ebp");
Packit c4476c
	 &push("ebx");
Packit c4476c
	&mov($r,&wparam(0));
Packit c4476c
	 &mov($a,&wparam(1));
Packit c4476c
	&xor($c0,$c0);
Packit c4476c
	 &xor($c1,$c1);
Packit c4476c
	&mov("eax",&DWP(0,$a,"",0)); # load the first word
Packit c4476c
Packit c4476c
	$as=0;
Packit c4476c
	$ae=0;
Packit c4476c
	$bs=0;
Packit c4476c
	$be=0;
Packit c4476c
	$tot=$num+$num-1;
Packit c4476c
Packit c4476c
	for ($i=0; $i<$tot; $i++)
Packit c4476c
		{
Packit c4476c
		$ai=$as;
Packit c4476c
		$bi=$bs;
Packit c4476c
		$end=$be+1;
Packit c4476c
Packit c4476c
		&comment("############### Calculate word $i");
Packit c4476c
		for ($j=$bs; $j<$end; $j++)
Packit c4476c
			{
Packit c4476c
			&xor($c2,$c2) if ($j == $bs);
Packit c4476c
			if (($ai-1) < ($bi+1))
Packit c4476c
				{
Packit c4476c
				$v=1;
Packit c4476c
				$v=2 if ($i+1) == $tot;
Packit c4476c
				}
Packit c4476c
			else
Packit c4476c
				{ $v=0; }
Packit c4476c
			if (!$v)
Packit c4476c
				{
Packit c4476c
				$na=$ai-1;
Packit c4476c
				$nb=$bi+1;
Packit c4476c
				}
Packit c4476c
			else
Packit c4476c
				{
Packit c4476c
				$na=$as+($i < ($num-1));
Packit c4476c
				$nb=$bs+($i >= ($num-1));
Packit c4476c
				}
Packit c4476c
			if ($ai == $bi)
Packit c4476c
				{
Packit c4476c
				&sqr_add_c($r,$a,$ai,$bi,
Packit c4476c
					$c0,$c1,$c2,$v,$i,$na,$nb);
Packit c4476c
				}
Packit c4476c
			else
Packit c4476c
				{
Packit c4476c
				&sqr_add_c2($r,$a,$ai,$bi,
Packit c4476c
					$c0,$c1,$c2,$v,$i,$na,$nb);
Packit c4476c
				}
Packit c4476c
			if ($v)
Packit c4476c
				{
Packit c4476c
				&comment("saved r[$i]");
Packit c4476c
				#&mov(&DWP($i*4,$r,"",0),$c0);
Packit c4476c
				($c0,$c1,$c2)=($c1,$c2,$c0);
Packit c4476c
				last;
Packit c4476c
				}
Packit c4476c
			$ai--;
Packit c4476c
			$bi++;
Packit c4476c
			}
Packit c4476c
		$as++ if ($i < ($num-1));
Packit c4476c
		$ae++ if ($i >= ($num-1));
Packit c4476c
Packit c4476c
		$bs++ if ($i >= ($num-1));
Packit c4476c
		$be++ if ($i < ($num-1));
Packit c4476c
		}
Packit c4476c
	&mov(&DWP($i*4,$r,"",0),$c0);
Packit c4476c
	&pop("ebx");
Packit c4476c
	&pop("ebp");
Packit c4476c
	&pop("edi");
Packit c4476c
	&pop("esi");
Packit c4476c
	&ret();
Packit c4476c
	&function_end_B($name);
Packit c4476c
	}