From de8f24ea083384bb66b32ec105dc4743c5663cdf Mon Sep 17 00:00:00 2001 From: beck <> Date: Wed, 29 Sep 1999 04:37:45 +0000 Subject: OpenSSL 0.9.4 merge --- src/lib/libcrypto/perlasm/alpha.pl | 434 +++++++++++++++++++++++++++++++++++ src/lib/libcrypto/perlasm/cbc.pl | 2 +- src/lib/libcrypto/perlasm/x86asm.pl | 11 +- src/lib/libcrypto/perlasm/x86ms.pl | 12 +- src/lib/libcrypto/perlasm/x86nasm.pl | 342 +++++++++++++++++++++++++++ src/lib/libcrypto/perlasm/x86unix.pl | 42 +++- 6 files changed, 828 insertions(+), 15 deletions(-) create mode 100644 src/lib/libcrypto/perlasm/alpha.pl create mode 100644 src/lib/libcrypto/perlasm/x86nasm.pl (limited to 'src/lib/libcrypto/perlasm') diff --git a/src/lib/libcrypto/perlasm/alpha.pl b/src/lib/libcrypto/perlasm/alpha.pl new file mode 100644 index 0000000000..3dac571743 --- /dev/null +++ b/src/lib/libcrypto/perlasm/alpha.pl @@ -0,0 +1,434 @@ +#!/usr/local/bin/perl + +package alpha; +use Carp qw(croak cluck); + +$label="100"; + +$n_debug=0; +$smear_regs=1; +$reg_alloc=1; + +$align="3"; +$com_start="#"; + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } +sub main'external_label { push(@labels,@_); } + +# General registers + +%regs=( 'r0', '$0', + 'r1', '$1', + 'r2', '$2', + 'r3', '$3', + 'r4', '$4', + 'r5', '$5', + 'r6', '$6', + 'r7', '$7', + 'r8', '$8', + 'r9', '$22', + 'r10', '$23', + 'r11', '$24', + 'r12', '$25', + 'r13', '$27', + 'r14', '$28', + 'r15', '$21', # argc == 5 + 'r16', '$20', # argc == 4 + 'r17', '$19', # argc == 3 + 'r18', '$18', # argc == 2 + 'r19', '$17', # argc == 1 + 'r20', '$16', # argc == 0 + 'r21', '$9', # save 0 + 'r22', '$10', # save 1 + 'r23', '$11', # save 2 + 'r24', '$12', # save 3 + 'r25', '$13', # save 4 + 'r26', '$14', # save 5 + + 'a0', '$16', + 'a1', '$17', + 'a2', '$18', + 'a3', '$19', + 'a4', '$20', + 'a5', '$21', + + 's0', '$9', + 's1', '$10', + 's2', '$11', + 's3', '$12', + 's4', '$13', + 's5', '$14', + 'zero', '$31', + 'sp', '$30', + ); + +$main'reg_s0="r21"; +$main'reg_s1="r22"; +$main'reg_s2="r23"; +$main'reg_s3="r24"; +$main'reg_s4="r25"; +$main'reg_s5="r26"; + +@reg=( '$0', '$1' ,'$2' ,'$3' ,'$4' ,'$5' ,'$6' ,'$7' ,'$8', + '$22','$23','$24','$25','$20','$21','$27','$28'); + + +sub main'sub { &out3("subq",@_); } +sub main'add { &out3("addq",@_); } +sub main'mov { &out3("bis",$_[0],$_[0],$_[1]); } +sub main'or { &out3("bis",@_); } +sub main'bis { &out3("bis",@_); } +sub main'br { &out1("br",@_); } +sub main'ld { &out2("ldq",@_); } +sub main'st { &out2("stq",@_); } +sub main'cmpult { &out3("cmpult",@_); } +sub main'cmplt { &out3("cmplt",@_); } +sub main'bgt { &out2("bgt",@_); } +sub main'ble { &out2("ble",@_); } +sub main'blt { &out2("blt",@_); } +sub main'mul { &out3("mulq",@_); } +sub main'muh { &out3("umulh",@_); } + +$main'QWS=8; + +sub main'asm_add + { + push(@out,@_); + } + +sub main'asm_finish + { + &main'file_end(); + print &main'asm_get_output(); + } + +sub main'asm_init + { + ($type,$fn)=@_; + $filename=$fn; + + &main'asm_init_output(); + &main'comment("Don't even think of reading this code"); + &main'comment("It was automatically generated by $filename"); + &main'comment("Which is a perl program used to generate the alpha assember."); + &main'comment("eric "); + &main'comment(""); + + $filename =~ s/\.pl$//; + &main'file($filename); + } + +sub conv + { + local($r)=@_; + local($v); + + return($regs{$r}) if defined($regs{$r}); + return($r); + } + +sub main'QWPw + { + local($off,$reg)=@_; + + return(&main'QWP($off*8,$reg)); + } + +sub main'QWP + { + local($off,$reg)=@_; + + $ret="$off(".&conv($reg).")"; + return($ret); + } + +sub out3 + { + local($name,$p1,$p2,$p3)=@_; + + $p1=&conv($p1); + $p2=&conv($p2); + $p3=&conv($p3); + push(@out,"\t$name\t"); + $l=length($p1)+1; + push(@out,$p1.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + $l=length($p2)+1; + push(@out,$p2.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + push(@out,&conv($p3)."\n"); + } + +sub out2 + { + local($name,$p1,$p2,$p3)=@_; + + $p1=&conv($p1); + $p2=&conv($p2); + push(@out,"\t$name\t"); + $l=length($p1)+1; + push(@out,$p1.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + push(@out,&conv($p2)."\n"); + } + +sub out1 + { + local($name,$p1)=@_; + + $p1=&conv($p1); + push(@out,"\t$name\t".$p1."\n"); + } + +sub out0 + { + push(@out,"\t$_[0]\n"); + } + +sub main'file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + # DEC Alpha assember + # Generated from perl scripts contains in SSLeay + .file 1 "$file.s" + .set noat +EOF + push(@out,$tmp); + } + +sub main'function_begin + { + local($func)=@_; + +print STDERR "$func\n"; + local($tmp)=<<"EOF"; + .text + .align $align + .globl $func + .ent $func +${func}: +${func}..ng: + .frame \$30,0,\$26,0 + .prologue 0 +EOF + push(@out,$tmp); + $stack=0; + } + +sub main'function_end + { + local($func)=@_; + + local($tmp)=<<"EOF"; + ret \$31,(\$26),1 + .end $func +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + ret \$31,(\$26),1 +EOF + push(@out,$tmp); + } + +sub main'function_end_B + { + local($func)=@_; + + $func=$under.$func; + + push(@out,"\t.end $func\n"); + $stack=0; + %label=(); + } + +sub main'wparam + { + local($num)=@_; + + if ($num < 6) + { + $num=20-$num; + return("r$num"); + } + else + { return(&main'QWP($stack+$num*8,"sp")); } + } + +sub main'stack_push + { + local($num)=@_; + $stack+=$num*8; + &main'sub("sp",$num*8,"sp"); + } + +sub main'stack_pop + { + local($num)=@_; + $stack-=$num*8; + &main'add("sp",$num*8,"sp"); + } + +sub main'swtmp + { + return(&main'QWP(($_[0])*8,"sp")); + } + +# Should use swtmp, which is above sp. Linix can trash the stack above esp +#sub main'wtmp +# { +# local($num)=@_; +# +# return(&main'QWP(-($num+1)*4,"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + if (/^\s*$/) + { push(@out,"\n"); } + else + { push(@out,"\t$com_start $_ $com_end\n"); } + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=$label; + $label++; + } + return('$'.$label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=$label; + $label++; + } +# push(@out,".align $align\n") if ($_[1] != 0); + push(@out,'$'."$label{$_[0]}:\n"); + } + +sub main'file_end + { + } + +sub main'data_word + { + push(@out,"\t.long $_[0]\n"); + } + +@pool_free=(); +@pool_taken=(); +$curr_num=0; +$max=0; + +sub main'init_pool + { + local($args)=@_; + local($i); + + @pool_free=(); + for ($i=(14+(6-$args)); $i >= 0; $i--) + { + push(@pool_free,"r$i"); + } + print STDERR "START :register pool:@pool_free\n"; + $curr_num=$max=0; + } + +sub main'fin_pool + { + printf STDERR "END %2d:register pool:@pool_free\n",$max; + } + +sub main'GR + { + local($r)=@_; + local($i,@n,$_); + + foreach (@pool_free) + { + if ($r ne $_) + { push(@n,$_); } + else + { + $curr_num++; + $max=$curr_num if ($curr_num > $max); + } + } + @pool_free=@n; +print STDERR "GR:@pool_free\n" if $reg_alloc; + return(@_); + } + +sub main'NR + { + local($num)=@_; + local(@ret); + + $num=1 if $num == 0; + ($#pool_free >= ($num-1)) || croak "out of registers: want $num, have @pool_free"; + while ($num > 0) + { + push(@ret,pop @pool_free); + $curr_num++; + $max=$curr_num if ($curr_num > $max); + $num-- + } + print STDERR "nr @ret\n" if $n_debug; +print STDERR "NR:@pool_free\n" if $reg_alloc; + return(@ret); + + } + +sub main'FR + { + local(@r)=@_; + local(@a,$v,$w); + + print STDERR "fr @r\n" if $n_debug; +# cluck "fr @r"; + for $w (@pool_free) + { + foreach $v (@r) + { + croak "double register free of $v (@pool_free)" if $w eq $v; + } + } + foreach $v (@r) + { + croak "bad argument to FR" if ($v !~ /^r\d+$/); + if ($smear_regs) + { unshift(@pool_free,$v); } + else { push(@pool_free,$v); } + $curr_num--; + } +print STDERR "FR:@pool_free\n" if $reg_alloc; + } +1; diff --git a/src/lib/libcrypto/perlasm/cbc.pl b/src/lib/libcrypto/perlasm/cbc.pl index 2789305790..0145c4f0cc 100644 --- a/src/lib/libcrypto/perlasm/cbc.pl +++ b/src/lib/libcrypto/perlasm/cbc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/local/bin/perl # void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) # des_cblock (*input); diff --git a/src/lib/libcrypto/perlasm/x86asm.pl b/src/lib/libcrypto/perlasm/x86asm.pl index 6a9156ae9a..44e330eb8d 100644 --- a/src/lib/libcrypto/perlasm/x86asm.pl +++ b/src/lib/libcrypto/perlasm/x86asm.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/local/bin/perl # require 'x86asm.pl'; # &asm_init("cpp","des-586.pl"); @@ -15,7 +15,7 @@ sub main'asm_finish sub main'asm_init { - ($type,$fn)=@_; + ($type,$fn,$i386)=@_; $filename=$fn; $cpp=$sol=$aout=$win32=0; @@ -29,6 +29,8 @@ sub main'asm_init { $cpp=1; require "x86unix.pl"; } elsif ( ($type eq "win32")) { $win32=1; require "x86ms.pl"; } + elsif ( ($type eq "win32n")) + { $win32=1; require "x86nasm.pl"; } else { print STDERR <<"EOF"; @@ -38,6 +40,7 @@ Pick one target type from sol - x86 solaris cpp - format so x86unix.cpp can be used win32 - Windows 95/Windows NT + win32n - Windows 95/Windows NT NASM format EOF exit(1); } @@ -75,7 +78,7 @@ sub asm_finish_cpp #define TYPE(a,b) .type a,b #define SIZE(a,b) .size a,b -#if defined(OUT) || defined(BSDI) +#if defined(OUT) || (defined(BSDI) && !defined(ELF)) $tmp #endif @@ -84,7 +87,7 @@ $tmp #define ALIGN 4 #endif -#ifdef BSDI +#if defined(BSDI) && !defined(ELF) #define OK 1 #define ALIGN 4 #undef SIZE diff --git a/src/lib/libcrypto/perlasm/x86ms.pl b/src/lib/libcrypto/perlasm/x86ms.pl index 893b50b1a4..51dcce067f 100644 --- a/src/lib/libcrypto/perlasm/x86ms.pl +++ b/src/lib/libcrypto/perlasm/x86ms.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/local/bin/perl package x86ms; @@ -51,6 +51,16 @@ sub main'DWP &get_mem("DWORD",@_); } +sub main'BC + { + return @_; + } + +sub main'DWC + { + return @_; + } + sub main'stack_push { local($num)=@_; diff --git a/src/lib/libcrypto/perlasm/x86nasm.pl b/src/lib/libcrypto/perlasm/x86nasm.pl new file mode 100644 index 0000000000..b4da364bbf --- /dev/null +++ b/src/lib/libcrypto/perlasm/x86nasm.pl @@ -0,0 +1,342 @@ +#!/usr/local/bin/perl + +package x86nasm; + +$label="L000"; + +%lb=( 'eax', 'al', + 'ebx', 'bl', + 'ecx', 'cl', + 'edx', 'dl', + 'ax', 'al', + 'bx', 'bl', + 'cx', 'cl', + 'dx', 'dl', + ); + +%hb=( 'eax', 'ah', + 'ebx', 'bh', + 'ecx', 'ch', + 'edx', 'dh', + 'ax', 'ah', + 'bx', 'bh', + 'cx', 'ch', + 'dx', 'dh', + ); + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } + +sub main'external_label +{ + push(@labels,@_); + foreach (@_) { + push(@out, "extern\t_$_\n"); + } +} + +sub main'LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main'HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main'BP + { + &get_mem("BYTE",@_); + } + +sub main'DWP + { + &get_mem("DWORD",@_); + } + +sub main'BC + { + return "BYTE @_"; + } + +sub main'DWC + { + return "DWORD @_"; + } + +sub main'stack_push + { + my($num)=@_; + $stack+=$num*4; + &main'sub("esp",$num*4); + } + +sub main'stack_pop + { + my($num)=@_; + $stack-=$num*4; + &main'add("esp",$num*4); + } + +sub get_mem + { + my($size,$addr,$reg1,$reg2,$idx)=@_; + my($t,$post); + my($ret)="["; + $addr =~ s/^\s+//; + if ($addr =~ /^(.+)\+(.+)$/) + { + $reg2=&conv($1); + $addr="_$2"; + } + elsif ($addr =~ /^[_a-zA-Z]/) + { + $addr="_$addr"; + } + + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + if (($addr ne "") && ($addr ne 0)) + { + if ($addr !~ /^-/) + { $ret.="${addr}+"; } + else { $post=$addr; } + } + if ($reg2 ne "") + { + $t=""; + $t="*$idx" if ($idx != 0); + $reg1="+".$reg1 if ("$reg1$post" ne ""); + $ret.="$reg2$t$reg1$post]"; + } + else + { + $ret.="$reg1$post]" + } + return($ret); + } + +sub main'mov { &out2("mov",@_); } +sub main'movb { &out2("mov",@_); } +sub main'and { &out2("and",@_); } +sub main'or { &out2("or",@_); } +sub main'shl { &out2("shl",@_); } +sub main'shr { &out2("shr",@_); } +sub main'xor { &out2("xor",@_); } +sub main'xorb { &out2("xor",@_); } +sub main'add { &out2("add",@_); } +sub main'adc { &out2("adc",@_); } +sub main'sub { &out2("sub",@_); } +sub main'rotl { &out2("rol",@_); } +sub main'rotr { &out2("ror",@_); } +sub main'exch { &out2("xchg",@_); } +sub main'cmp { &out2("cmp",@_); } +sub main'lea { &out2("lea",@_); } +sub main'mul { &out1("mul",@_); } +sub main'div { &out1("div",@_); } +sub main'dec { &out1("dec",@_); } +sub main'inc { &out1("inc",@_); } +sub main'jmp { &out1("jmp",@_); } +sub main'jmp_ptr { &out1p("jmp",@_); } + +# This is a bit of a kludge: declare all branches as NEAR. +sub main'je { &out1("je NEAR",@_); } +sub main'jle { &out1("jle NEAR",@_); } +sub main'jz { &out1("jz NEAR",@_); } +sub main'jge { &out1("jge NEAR",@_); } +sub main'jl { &out1("jl NEAR",@_); } +sub main'jb { &out1("jb NEAR",@_); } +sub main'jc { &out1("jc NEAR",@_); } +sub main'jnc { &out1("jnc NEAR",@_); } +sub main'jnz { &out1("jnz NEAR",@_); } +sub main'jne { &out1("jne NEAR",@_); } +sub main'jno { &out1("jno NEAR",@_); } + +sub main'push { &out1("push",@_); $stack+=4; } +sub main'pop { &out1("pop",@_); $stack-=4; } +sub main'bswap { &out1("bswap",@_); &using486(); } +sub main'not { &out1("not",@_); } +sub main'call { &out1("call",'_'.$_[0]); } +sub main'ret { &out0("ret"); } +sub main'nop { &out0("nop"); } + +sub out2 + { + my($name,$p1,$p2)=@_; + my($l,$t); + + push(@out,"\t$name\t"); + $t=&conv($p1).","; + $l=length($t); + push(@out,$t); + $l=4-($l+9)/8; + push(@out,"\t" x $l); + push(@out,&conv($p2)); + push(@out,"\n"); + } + +sub out0 + { + my($name)=@_; + + push(@out,"\t$name\n"); + } + +sub out1 + { + my($name,$p1)=@_; + my($l,$t); + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub conv + { + my($p)=@_; + $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + return $p; + } + +sub using486 + { + return if $using486; + $using486++; + grep(s/\.386/\.486/,@out); + } + +sub main'file + { + push(@out, "segment .text\n"); + } + +sub main'function_begin + { + my($func,$extra)=@_; + + push(@labels,$func); + my($tmp)=<<"EOF"; +global _$func +_$func: + push ebp + push ebx + push esi + push edi +EOF + push(@out,$tmp); + $stack=20; + } + +sub main'function_begin_B + { + my($func,$extra)=@_; + my($tmp)=<<"EOF"; +global _$func +_$func: +EOF + push(@out,$tmp); + $stack=4; + } + +sub main'function_end + { + my($func)=@_; + + my($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_B + { + $stack=0; + %label=(); + } + +sub main'function_end_A + { + my($func)=@_; + + my($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + } + +sub main'file_end + { + } + +sub main'wparam + { + my($num)=@_; + + return(&main'DWP($stack+$num*4,"esp","",0)); + } + +sub main'swtmp + { + return(&main'DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main'wtmp +# { +# my($num)=@_; +# +# return(&main'DWP(-(($num+1)*4),"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + push(@out,"\t; $_\n"); + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="\$${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="${label}${_[0]}"; + $label++; + } + push(@out,"$label{$_[0]}:\n"); + } + +sub main'data_word + { + push(@out,"\tDD\t$_[0]\n"); + } + +sub out1p + { + my($name,$p1)=@_; + my($l,$t); + + push(@out,"\t$name\t ".&conv($p1)."\n"); + } diff --git a/src/lib/libcrypto/perlasm/x86unix.pl b/src/lib/libcrypto/perlasm/x86unix.pl index 6ee4dd3245..8c456b14af 100644 --- a/src/lib/libcrypto/perlasm/x86unix.pl +++ b/src/lib/libcrypto/perlasm/x86unix.pl @@ -1,10 +1,4 @@ -#!/usr/bin/perl - -# Because the bswapl instruction is not supported for old assembers -# (it was a new instruction for the 486), I've added .byte xxxx code -# to put it in. -# eric 24-Apr-1998 -# +#!/usr/local/bin/perl package x86unix; @@ -90,7 +84,12 @@ sub main'DWP $reg2="$regs{$reg2}" if defined($regs{$reg2}); $ret.=$addr if ($addr ne "") && ($addr ne 0); if ($reg2 ne "") - { $ret.="($reg1,$reg2,$idx)"; } + { + if($idx ne "") + { $ret.="($reg1,$reg2,$idx)"; } + else + { $ret.="($reg1,$reg2)"; } + } else { $ret.="($reg1)" } return($ret); @@ -101,6 +100,16 @@ sub main'BP return(&main'DWP(@_)); } +sub main'BC + { + return @_; + } + +sub main'DWC + { + return @_; + } + #sub main'BP # { # local($addr,$reg1,$reg2,$idx)=@_; @@ -153,12 +162,27 @@ sub main'dec { &out1("decl",@_); } sub main'inc { &out1("incl",@_); } sub main'push { &out1("pushl",@_); $stack+=4; } sub main'pop { &out1("popl",@_); $stack-=4; } -sub main'bswap { &out1("bswapl",@_); } sub main'not { &out1("notl",@_); } sub main'call { &out1("call",$under.$_[0]); } sub main'ret { &out0("ret"); } sub main'nop { &out0("nop"); } +# The bswapl instruction is new for the 486. Emulate if i386. +sub main'bswap + { + if ($main'i386) + { + &main'comment("bswapl @_"); + &main'exch(main'HB(@_),main'LB(@_)); + &main'rotr(@_,16); + &main'exch(main'HB(@_),main'LB(@_)); + } + else + { + &out1("bswapl",@_); + } + } + sub out2 { local($name,$p1,$p2)=@_; -- cgit v1.2.3-55-g6feb