mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-26 23:23:40 +08:00
update
This commit is contained in:
@@ -150,7 +150,7 @@ sub cbc
|
||||
&set_label("PIC_point");
|
||||
&blindpop("edx");
|
||||
&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
|
||||
&mov($count,&DWP(0,"ecx",$count,4))
|
||||
&mov($count,&DWP(0,"ecx",$count,4));
|
||||
&add($count,"edx");
|
||||
&xor("ecx","ecx");
|
||||
&xor("edx","edx");
|
||||
@@ -158,7 +158,6 @@ sub cbc
|
||||
&jmp_ptr($count);
|
||||
|
||||
&set_label("ej7");
|
||||
&xor("edx", "edx") if $ppro; # ppro friendly
|
||||
&movb(&HB("edx"), &BP(6,$in,"",0));
|
||||
&shl("edx",8);
|
||||
&set_label("ej6");
|
||||
@@ -170,7 +169,6 @@ sub cbc
|
||||
&jmp(&label("ejend"));
|
||||
&set_label("ej3");
|
||||
&movb(&HB("ecx"), &BP(2,$in,"",0));
|
||||
&xor("ecx", "ecx") if $ppro; # ppro friendly
|
||||
&shl("ecx",8);
|
||||
&set_label("ej2");
|
||||
&movb(&HB("ecx"), &BP(1,$in,"",0));
|
||||
|
||||
@@ -27,18 +27,17 @@ my $globl = sub {
|
||||
/osx/ && do { $name = "_$name";
|
||||
last;
|
||||
};
|
||||
/linux.*32/ && do { $ret .= ".globl $name\n";
|
||||
/linux.*(32|64le)/
|
||||
&& do { $ret .= ".globl $name\n";
|
||||
$ret .= ".type $name,\@function";
|
||||
last;
|
||||
};
|
||||
/linux.*64/ && do { $ret .= ".globl .$name\n";
|
||||
$ret .= ".type .$name,\@function\n";
|
||||
/linux.*64/ && do { $ret .= ".globl $name\n";
|
||||
$ret .= ".type $name,\@function\n";
|
||||
$ret .= ".section \".opd\",\"aw\"\n";
|
||||
$ret .= ".globl $name\n";
|
||||
$ret .= ".align 3\n";
|
||||
$ret .= "$name:\n";
|
||||
$ret .= ".quad .$name,.TOC.\@tocbase,0\n";
|
||||
$ret .= ".size $name,24\n";
|
||||
$ret .= ".previous\n";
|
||||
|
||||
$name = ".$name";
|
||||
@@ -51,7 +50,9 @@ my $globl = sub {
|
||||
$ret;
|
||||
};
|
||||
my $text = sub {
|
||||
($flavour =~ /aix/) ? ".csect" : ".text";
|
||||
my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text";
|
||||
$ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/);
|
||||
$ret;
|
||||
};
|
||||
my $machine = sub {
|
||||
my $junk = shift;
|
||||
@@ -62,6 +63,17 @@ my $machine = sub {
|
||||
}
|
||||
".machine $arch";
|
||||
};
|
||||
my $size = sub {
|
||||
if ($flavour =~ /linux/)
|
||||
{ shift;
|
||||
my $name = shift; $name =~ s|^[\.\_]||;
|
||||
my $ret = ".size $name,.-".($flavour=~/64$/?".":"").$name;
|
||||
$ret .= "\n.size .$name,.-.$name" if ($flavour=~/64$/);
|
||||
$ret;
|
||||
}
|
||||
else
|
||||
{ ""; }
|
||||
};
|
||||
my $asciz = sub {
|
||||
shift;
|
||||
my $line = join(",",@_);
|
||||
@@ -70,6 +82,25 @@ my $asciz = sub {
|
||||
else
|
||||
{ ""; }
|
||||
};
|
||||
my $quad = sub {
|
||||
shift;
|
||||
my @ret;
|
||||
my ($hi,$lo);
|
||||
for (@_) {
|
||||
if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io)
|
||||
{ $hi=$1?"0x$1":"0"; $lo="0x$2"; }
|
||||
elsif (/^([0-9]+)$/o)
|
||||
{ $hi=$1>>32; $lo=$1&0xffffffff; } # error-prone with 32-bit perl
|
||||
else
|
||||
{ $hi=undef; $lo=$_; }
|
||||
|
||||
if (defined($hi))
|
||||
{ push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo"); }
|
||||
else
|
||||
{ push(@ret,".quad $lo"); }
|
||||
}
|
||||
join("\n",@ret);
|
||||
};
|
||||
|
||||
################################################################
|
||||
# simplified mnemonics not handled by at least one assembler
|
||||
@@ -115,6 +146,46 @@ my $extrdi = sub {
|
||||
$b = ($b+$n)&63; $n = 64-$n;
|
||||
" rldicl $ra,$rs,$b,$n";
|
||||
};
|
||||
my $vmr = sub {
|
||||
my ($f,$vx,$vy) = @_;
|
||||
" vor $vx,$vy,$vy";
|
||||
};
|
||||
|
||||
# PowerISA 2.06 stuff
|
||||
sub vsxmem_op {
|
||||
my ($f, $vrt, $ra, $rb, $op) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1);
|
||||
}
|
||||
# made-up unaligned memory reference AltiVec/VMX instructions
|
||||
my $lvx_u = sub { vsxmem_op(@_, 844); }; # lxvd2x
|
||||
my $stvx_u = sub { vsxmem_op(@_, 972); }; # stxvd2x
|
||||
my $lvdx_u = sub { vsxmem_op(@_, 588); }; # lxsdx
|
||||
my $stvdx_u = sub { vsxmem_op(@_, 716); }; # stxsdx
|
||||
my $lvx_4w = sub { vsxmem_op(@_, 780); }; # lxvw4x
|
||||
my $stvx_4w = sub { vsxmem_op(@_, 908); }; # stxvw4x
|
||||
|
||||
# PowerISA 2.07 stuff
|
||||
sub vcrypto_op {
|
||||
my ($f, $vrt, $vra, $vrb, $op) = @_;
|
||||
" .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op;
|
||||
}
|
||||
my $vcipher = sub { vcrypto_op(@_, 1288); };
|
||||
my $vcipherlast = sub { vcrypto_op(@_, 1289); };
|
||||
my $vncipher = sub { vcrypto_op(@_, 1352); };
|
||||
my $vncipherlast= sub { vcrypto_op(@_, 1353); };
|
||||
my $vsbox = sub { vcrypto_op(@_, 0, 1480); };
|
||||
my $vshasigmad = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); };
|
||||
my $vshasigmaw = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); };
|
||||
my $vpmsumb = sub { vcrypto_op(@_, 1032); };
|
||||
my $vpmsumd = sub { vcrypto_op(@_, 1224); };
|
||||
my $vpmsubh = sub { vcrypto_op(@_, 1096); };
|
||||
my $vpmsumw = sub { vcrypto_op(@_, 1160); };
|
||||
my $vaddudm = sub { vcrypto_op(@_, 192); };
|
||||
|
||||
my $mtsle = sub {
|
||||
my ($f, $arg) = @_;
|
||||
" .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2);
|
||||
};
|
||||
|
||||
while($line=<>) {
|
||||
|
||||
@@ -131,7 +202,10 @@ while($line=<>) {
|
||||
{
|
||||
$line =~ s|(^[\.\w]+)\:\s*||;
|
||||
my $label = $1;
|
||||
printf "%s:",($GLOBALS{$label} or $label) if ($label);
|
||||
if ($label) {
|
||||
printf "%s:",($GLOBALS{$label} or $label);
|
||||
printf "\n.localentry\t$GLOBALS{$label},0" if ($GLOBALS{$label} && $flavour =~ /linux.*64le/);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -140,7 +214,7 @@ while($line=<>) {
|
||||
my $mnemonic = $2;
|
||||
my $f = $3;
|
||||
my $opcode = eval("\$$mnemonic");
|
||||
$line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/);
|
||||
$line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/);
|
||||
if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
|
||||
elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; }
|
||||
}
|
||||
|
||||
1687
crypto/perlasm/sparcv9_modes.pl
Normal file
1687
crypto/perlasm/sparcv9_modes.pl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,12 +62,8 @@ my $flavour = shift;
|
||||
my $output = shift;
|
||||
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
|
||||
|
||||
{ my ($stddev,$stdino,@junk)=stat(STDOUT);
|
||||
my ($outdev,$outino,@junk)=stat($output);
|
||||
|
||||
open STDOUT,">$output" || die "can't open $output: $!"
|
||||
if ($stddev!=$outdev || $stdino!=$outino);
|
||||
}
|
||||
open STDOUT,">$output" || die "can't open $output: $!"
|
||||
if (defined($output));
|
||||
|
||||
my $gas=1; $gas=0 if ($output =~ /\.asm$/);
|
||||
my $elf=1; $elf=0 if (!$gas);
|
||||
@@ -116,12 +112,16 @@ my %globals;
|
||||
$line = substr($line,@+[0]); $line =~ s/^\s+//;
|
||||
|
||||
undef $self->{sz};
|
||||
if ($self->{op} =~ /^(movz)b.*/) { # movz is pain...
|
||||
if ($self->{op} =~ /^(movz)x?([bw]).*/) { # movz is pain...
|
||||
$self->{op} = $1;
|
||||
$self->{sz} = "b";
|
||||
$self->{sz} = $2;
|
||||
} elsif ($self->{op} =~ /call|jmp/) {
|
||||
$self->{sz} = "";
|
||||
} elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op)/) { # SSEn
|
||||
} elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
|
||||
$self->{sz} = "";
|
||||
} elsif ($self->{op} =~ /^v/) { # VEX
|
||||
$self->{sz} = "";
|
||||
} elsif ($self->{op} =~ /mov[dq]/ && $line =~ /%xmm/) {
|
||||
$self->{sz} = "";
|
||||
} elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
|
||||
$self->{op} = $1;
|
||||
@@ -246,35 +246,50 @@ my %globals;
|
||||
$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
|
||||
$self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
|
||||
|
||||
# Solaris /usr/ccs/bin/as can't handle multiplications
|
||||
# in $self->{label}, new gas requires sign extension...
|
||||
use integer;
|
||||
$self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
|
||||
$self->{label} =~ s/\b([0-9]+\s*[\*\/\%]\s*[0-9]+)\b/eval($1)/eg;
|
||||
$self->{label} =~ s/\b([0-9]+)\b/$1<<32>>32/eg;
|
||||
|
||||
if (!$self->{label} && $self->{index} && $self->{scale}==1 &&
|
||||
$self->{base} =~ /(rbp|r13)/) {
|
||||
$self->{base} = $self->{index}; $self->{index} = $1;
|
||||
}
|
||||
|
||||
if ($gas) {
|
||||
# Solaris /usr/ccs/bin/as can't handle multiplications
|
||||
# in $self->{label}, new gas requires sign extension...
|
||||
use integer;
|
||||
$self->{label} =~ s/(?<![\w\$\.])(0x?[0-9a-f]+)/oct($1)/egi;
|
||||
$self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg;
|
||||
$self->{label} =~ s/([0-9]+)/$1<<32>>32/eg;
|
||||
$self->{label} =~ s/^___imp_/__imp__/ if ($flavour eq "mingw64");
|
||||
|
||||
if (defined($self->{index})) {
|
||||
sprintf "%s%s(%%%s,%%%s,%d)",$self->{asterisk},
|
||||
$self->{label},$self->{base},
|
||||
sprintf "%s%s(%s,%%%s,%d)",$self->{asterisk},
|
||||
$self->{label},
|
||||
$self->{base}?"%$self->{base}":"",
|
||||
$self->{index},$self->{scale};
|
||||
} else {
|
||||
sprintf "%s%s(%%%s)", $self->{asterisk},$self->{label},$self->{base};
|
||||
}
|
||||
} else {
|
||||
%szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", q=>"QWORD$PTR" );
|
||||
%szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR",
|
||||
l=>"DWORD$PTR", d=>"DWORD$PTR",
|
||||
q=>"QWORD$PTR", o=>"OWORD$PTR",
|
||||
x=>"XMMWORD$PTR", y=>"YMMWORD$PTR", z=>"ZMMWORD$PTR" );
|
||||
|
||||
$self->{label} =~ s/\./\$/g;
|
||||
$self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
|
||||
$self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
|
||||
$sz="q" if ($self->{asterisk});
|
||||
|
||||
($self->{asterisk}) && ($sz="q") ||
|
||||
(opcode->mnemonic() =~ /^v?mov([qd])$/) && ($sz=$1) ||
|
||||
(opcode->mnemonic() =~ /^v?pinsr([qdwb])$/) && ($sz=$1) ||
|
||||
(opcode->mnemonic() =~ /^vpbroadcast([qdwb])$/) && ($sz=$1) ||
|
||||
(opcode->mnemonic() =~ /^vinsert[fi]128$/) && ($sz="x");
|
||||
|
||||
if (defined($self->{index})) {
|
||||
sprintf "%s[%s%s*%d+%s]",$szmap{$sz},
|
||||
sprintf "%s[%s%s*%d%s]",$szmap{$sz},
|
||||
$self->{label}?"$self->{label}+":"",
|
||||
$self->{index},$self->{scale},
|
||||
$self->{base};
|
||||
$self->{base}?"+$self->{base}":"";
|
||||
} elsif ($self->{base} eq "rip") {
|
||||
sprintf "%s[%s]",$szmap{$sz},$self->{label};
|
||||
} else {
|
||||
@@ -408,7 +423,7 @@ my %globals;
|
||||
}
|
||||
sub out {
|
||||
my $self = shift;
|
||||
if ($nasm && opcode->mnemonic()=~m/^j/) {
|
||||
if ($nasm && opcode->mnemonic()=~m/^j(?![re]cxz)/) {
|
||||
"NEAR ".$self->{value};
|
||||
} else {
|
||||
$self->{value};
|
||||
@@ -506,6 +521,12 @@ my %globals;
|
||||
}
|
||||
} elsif ($dir =~ /\.(text|data)/) {
|
||||
$current_segment=".$1";
|
||||
} elsif ($dir =~ /\.hidden/) {
|
||||
if ($flavour eq "macosx") { $self->{value} = ".private_extern\t$prefix$line"; }
|
||||
elsif ($flavour eq "mingw64") { $self->{value} = ""; }
|
||||
} elsif ($dir =~ /\.comm/) {
|
||||
$self->{value} = "$dir\t$prefix$line";
|
||||
$self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
|
||||
}
|
||||
$line = "";
|
||||
return $self;
|
||||
@@ -520,7 +541,7 @@ my %globals;
|
||||
$v="$current_segment\tENDS\n" if ($current_segment);
|
||||
$current_segment = ".text\$";
|
||||
$v.="$current_segment\tSEGMENT ";
|
||||
$v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
|
||||
$v.=$masm>=$masmref ? "ALIGN(256)" : "PAGE";
|
||||
$v.=" 'CODE'";
|
||||
}
|
||||
$self->{value} = $v;
|
||||
@@ -555,7 +576,8 @@ my %globals;
|
||||
$v.=" READONLY";
|
||||
$v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
|
||||
} elsif ($line=~/\.CRT\$/i) {
|
||||
$v.=" READONLY DWORD";
|
||||
$v.=" READONLY ";
|
||||
$v.=$masm>=$masmref ? "ALIGN(8)" : "DWORD";
|
||||
}
|
||||
}
|
||||
$current_segment = $line;
|
||||
@@ -577,7 +599,7 @@ my %globals;
|
||||
$self->{value}="${decor}SEH_end_$current_function->{name}:";
|
||||
$self->{value}.=":\n" if($masm);
|
||||
}
|
||||
$self->{value}.="$current_function->{name}\tENDP" if($masm);
|
||||
$self->{value}.="$current_function->{name}\tENDP" if($masm && $current_function->{name});
|
||||
undef $current_function;
|
||||
}
|
||||
last;
|
||||
@@ -613,6 +635,19 @@ my %globals;
|
||||
.join(",",@str) if (@str);
|
||||
last;
|
||||
};
|
||||
/\.comm/ && do { my @str=split(/,\s*/,$line);
|
||||
my $v=undef;
|
||||
if ($nasm) {
|
||||
$v.="common $prefix@str[0] @str[1]";
|
||||
} else {
|
||||
$v="$current_segment\tENDS\n" if ($current_segment);
|
||||
$current_segment = "_DATA";
|
||||
$v.="$current_segment\tSEGMENT\n";
|
||||
$v.="COMM @str[0]:DWORD:".@str[1]/4;
|
||||
}
|
||||
$self->{value} = $v;
|
||||
last;
|
||||
};
|
||||
}
|
||||
$line = "";
|
||||
}
|
||||
@@ -625,9 +660,187 @@ my %globals;
|
||||
}
|
||||
}
|
||||
|
||||
sub rex {
|
||||
local *opcode=shift;
|
||||
my ($dst,$src,$rex)=@_;
|
||||
|
||||
$rex|=0x04 if($dst>=8);
|
||||
$rex|=0x01 if($src>=8);
|
||||
push @opcode,($rex|0x40) if ($rex);
|
||||
}
|
||||
|
||||
# older gas and ml64 don't handle SSE>2 instructions
|
||||
my %regrm = ( "%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3,
|
||||
"%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7 );
|
||||
|
||||
my $movq = sub { # elderly gas can't handle inter-register movq
|
||||
my $arg = shift;
|
||||
my @opcode=(0x66);
|
||||
if ($arg =~ /%xmm([0-9]+),\s*%r(\w+)/) {
|
||||
my ($src,$dst)=($1,$2);
|
||||
if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
|
||||
rex(\@opcode,$src,$dst,0x8);
|
||||
push @opcode,0x0f,0x7e;
|
||||
push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
|
||||
@opcode;
|
||||
} elsif ($arg =~ /%r(\w+),\s*%xmm([0-9]+)/) {
|
||||
my ($src,$dst)=($2,$1);
|
||||
if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
|
||||
rex(\@opcode,$src,$dst,0x8);
|
||||
push @opcode,0x0f,0x6e;
|
||||
push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $pextrd = sub {
|
||||
if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*(%\w+)/) {
|
||||
my @opcode=(0x66);
|
||||
$imm=$1;
|
||||
$src=$2;
|
||||
$dst=$3;
|
||||
if ($dst =~ /%r([0-9]+)d/) { $dst = $1; }
|
||||
elsif ($dst =~ /%e/) { $dst = $regrm{$dst}; }
|
||||
rex(\@opcode,$src,$dst);
|
||||
push @opcode,0x0f,0x3a,0x16;
|
||||
push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
|
||||
push @opcode,$imm;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $pinsrd = sub {
|
||||
if (shift =~ /\$([0-9]+),\s*(%\w+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x66);
|
||||
$imm=$1;
|
||||
$src=$2;
|
||||
$dst=$3;
|
||||
if ($src =~ /%r([0-9]+)/) { $src = $1; }
|
||||
elsif ($src =~ /%e/) { $src = $regrm{$src}; }
|
||||
rex(\@opcode,$dst,$src);
|
||||
push @opcode,0x0f,0x3a,0x22;
|
||||
push @opcode,0xc0|(($dst&7)<<3)|($src&7); # ModR/M
|
||||
push @opcode,$imm;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $pshufb = sub {
|
||||
if (shift =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x66);
|
||||
rex(\@opcode,$2,$1);
|
||||
push @opcode,0x0f,0x38,0x00;
|
||||
push @opcode,0xc0|($1&7)|(($2&7)<<3); # ModR/M
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $palignr = sub {
|
||||
if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x66);
|
||||
rex(\@opcode,$3,$2);
|
||||
push @opcode,0x0f,0x3a,0x0f;
|
||||
push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
|
||||
push @opcode,$1;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $pclmulqdq = sub {
|
||||
if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x66);
|
||||
rex(\@opcode,$3,$2);
|
||||
push @opcode,0x0f,0x3a,0x44;
|
||||
push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
|
||||
my $c=$1;
|
||||
push @opcode,$c=~/^0/?oct($c):$c;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $rdrand = sub {
|
||||
if (shift =~ /%[er](\w+)/) {
|
||||
my @opcode=();
|
||||
my $dst=$1;
|
||||
if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
|
||||
rex(\@opcode,0,$1,8);
|
||||
push @opcode,0x0f,0xc7,0xf0|($dst&7);
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $rdseed = sub {
|
||||
if (shift =~ /%[er](\w+)/) {
|
||||
my @opcode=();
|
||||
my $dst=$1;
|
||||
if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
|
||||
rex(\@opcode,0,$1,8);
|
||||
push @opcode,0x0f,0xc7,0xf8|($dst&7);
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
sub rxb {
|
||||
local *opcode=shift;
|
||||
my ($dst,$src1,$src2,$rxb)=@_;
|
||||
|
||||
$rxb|=0x7<<5;
|
||||
$rxb&=~(0x04<<5) if($dst>=8);
|
||||
$rxb&=~(0x01<<5) if($src1>=8);
|
||||
$rxb&=~(0x02<<5) if($src2>=8);
|
||||
push @opcode,$rxb;
|
||||
}
|
||||
|
||||
my $vprotd = sub {
|
||||
if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x8f);
|
||||
rxb(\@opcode,$3,$2,-1,0x08);
|
||||
push @opcode,0x78,0xc2;
|
||||
push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
|
||||
my $c=$1;
|
||||
push @opcode,$c=~/^0/?oct($c):$c;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
my $vprotq = sub {
|
||||
if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
|
||||
my @opcode=(0x8f);
|
||||
rxb(\@opcode,$3,$2,-1,0x08);
|
||||
push @opcode,0x78,0xc3;
|
||||
push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M
|
||||
my $c=$1;
|
||||
push @opcode,$c=~/^0/?oct($c):$c;
|
||||
@opcode;
|
||||
} else {
|
||||
();
|
||||
}
|
||||
};
|
||||
|
||||
if ($nasm) {
|
||||
print <<___;
|
||||
default rel
|
||||
%define XMMWORD
|
||||
%define YMMWORD
|
||||
%define ZMMWORD
|
||||
___
|
||||
} elsif ($masm) {
|
||||
print <<___;
|
||||
@@ -641,17 +854,26 @@ while($line=<>) {
|
||||
$line =~ s|[#!].*$||; # get rid of asm-style comments...
|
||||
$line =~ s|/\*.*\*/||; # ... and C-style comments...
|
||||
$line =~ s|^\s+||; # ... and skip white spaces in beginning
|
||||
$line =~ s|\s+$||; # ... and at the end
|
||||
|
||||
undef $label;
|
||||
undef $opcode;
|
||||
undef $sz;
|
||||
undef @args;
|
||||
|
||||
if ($label=label->re(\$line)) { print $label->out(); }
|
||||
|
||||
if (directive->re(\$line)) {
|
||||
printf "%s",directive->out();
|
||||
} elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
|
||||
} elsif ($opcode=opcode->re(\$line)) {
|
||||
my $asm = eval("\$".$opcode->mnemonic());
|
||||
undef @bytes;
|
||||
|
||||
if ((ref($asm) eq 'CODE') && scalar(@bytes=&$asm($line))) {
|
||||
print $gas?".byte\t":"DB\t",join(',',@bytes),"\n";
|
||||
next;
|
||||
}
|
||||
|
||||
ARGUMENT: while (1) {
|
||||
my $arg;
|
||||
|
||||
if ($arg=register->re(\$line)) { opcode->size($arg->size()); }
|
||||
@@ -667,19 +889,28 @@ while($line=<>) {
|
||||
$line =~ s/^,\s*//;
|
||||
} # ARGUMENT:
|
||||
|
||||
$sz=opcode->size();
|
||||
|
||||
if ($#args>=0) {
|
||||
my $insn;
|
||||
my $sz=opcode->size();
|
||||
|
||||
if ($gas) {
|
||||
$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
|
||||
@args = map($_->out($sz),@args);
|
||||
printf "\t%s\t%s",$insn,join(",",@args);
|
||||
} else {
|
||||
$insn = $opcode->out();
|
||||
$insn .= $sz if (map($_->out() =~ /x?mm/,@args));
|
||||
foreach (@args) {
|
||||
my $arg = $_->out();
|
||||
# $insn.=$sz compensates for movq, pinsrw, ...
|
||||
if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; }
|
||||
if ($arg =~ /^ymm[0-9]+$/) { $insn.=$sz; $sz="y" if(!$sz); last; }
|
||||
if ($arg =~ /^zmm[0-9]+$/) { $insn.=$sz; $sz="z" if(!$sz); last; }
|
||||
if ($arg =~ /^mm[0-9]+$/) { $insn.=$sz; $sz="q" if(!$sz); last; }
|
||||
}
|
||||
@args = reverse(@args);
|
||||
undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
|
||||
printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
|
||||
}
|
||||
printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
|
||||
} else {
|
||||
printf "\t%s",$opcode->out();
|
||||
}
|
||||
|
||||
@@ -80,6 +80,91 @@ sub ::movq
|
||||
{ &::generic("movq",@_); }
|
||||
}
|
||||
|
||||
# SSE>2 instructions
|
||||
my %regrm = ( "eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
|
||||
"esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7 );
|
||||
sub ::pextrd
|
||||
{ my($dst,$src,$imm)=@_;
|
||||
if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
|
||||
{ &::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm); }
|
||||
else
|
||||
{ &::generic("pextrd",@_); }
|
||||
}
|
||||
|
||||
sub ::pinsrd
|
||||
{ my($dst,$src,$imm)=@_;
|
||||
if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
|
||||
{ &::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm); }
|
||||
else
|
||||
{ &::generic("pinsrd",@_); }
|
||||
}
|
||||
|
||||
sub ::pshufb
|
||||
{ my($dst,$src)=@_;
|
||||
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
||||
{ &data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2); }
|
||||
else
|
||||
{ &::generic("pshufb",@_); }
|
||||
}
|
||||
|
||||
sub ::palignr
|
||||
{ my($dst,$src,$imm)=@_;
|
||||
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
||||
{ &::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm); }
|
||||
else
|
||||
{ &::generic("palignr",@_); }
|
||||
}
|
||||
|
||||
sub ::pclmulqdq
|
||||
{ my($dst,$src,$imm)=@_;
|
||||
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
||||
{ &::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm); }
|
||||
else
|
||||
{ &::generic("pclmulqdq",@_); }
|
||||
}
|
||||
|
||||
sub ::rdrand
|
||||
{ my ($dst)=@_;
|
||||
if ($dst =~ /(e[a-dsd][ixp])/)
|
||||
{ &::data_byte(0x0f,0xc7,0xf0|$regrm{$dst}); }
|
||||
else
|
||||
{ &::generic("rdrand",@_); }
|
||||
}
|
||||
|
||||
sub ::rdseed
|
||||
{ my ($dst)=@_;
|
||||
if ($dst =~ /(e[a-dsd][ixp])/)
|
||||
{ &::data_byte(0x0f,0xc7,0xf8|$regrm{$dst}); }
|
||||
else
|
||||
{ &::generic("rdrand",@_); }
|
||||
}
|
||||
|
||||
sub rxb {
|
||||
local *opcode=shift;
|
||||
my ($dst,$src1,$src2,$rxb)=@_;
|
||||
|
||||
$rxb|=0x7<<5;
|
||||
$rxb&=~(0x04<<5) if($dst>=8);
|
||||
$rxb&=~(0x01<<5) if($src1>=8);
|
||||
$rxb&=~(0x02<<5) if($src2>=8);
|
||||
push @opcode,$rxb;
|
||||
}
|
||||
|
||||
sub ::vprotd
|
||||
{ my $args=join(',',@_);
|
||||
if ($args =~ /xmm([0-7]),xmm([0-7]),([x0-9a-f]+)/)
|
||||
{ my @opcode=(0x8f);
|
||||
rxb(\@opcode,$1,$2,-1,0x08);
|
||||
push @opcode,0x78,0xc2;
|
||||
push @opcode,0xc0|($2&7)|(($1&7)<<3); # ModR/M
|
||||
my $c=$3;
|
||||
push @opcode,$c=~/^0/?oct($c):$c;
|
||||
&::data_byte(@opcode);
|
||||
}
|
||||
else
|
||||
{ &::generic("vprotd",@_); }
|
||||
}
|
||||
|
||||
# label management
|
||||
$lbdecor="L"; # local label decoration, set by package
|
||||
$label="000";
|
||||
@@ -167,9 +252,11 @@ sub ::asm_init
|
||||
$filename=$fn;
|
||||
$i386=$cpu;
|
||||
|
||||
$elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=0;
|
||||
$elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0;
|
||||
if (($type eq "elf"))
|
||||
{ $elf=1; require "x86gas.pl"; }
|
||||
elsif (($type eq "elf-1"))
|
||||
{ $elf=-1; require "x86gas.pl"; }
|
||||
elsif (($type eq "a\.out"))
|
||||
{ $aout=1; require "x86gas.pl"; }
|
||||
elsif (($type eq "coff" or $type eq "gaswin"))
|
||||
@@ -184,6 +271,8 @@ sub ::asm_init
|
||||
{ $win32=1; require "x86masm.pl"; }
|
||||
elsif (($type eq "macosx"))
|
||||
{ $aout=1; $macosx=1; require "x86gas.pl"; }
|
||||
elsif (($type eq "android"))
|
||||
{ $elf=1; $android=1; require "x86gas.pl"; }
|
||||
else
|
||||
{ print STDERR <<"EOF";
|
||||
Pick one target type from
|
||||
@@ -204,4 +293,6 @@ EOF
|
||||
&file($filename);
|
||||
}
|
||||
|
||||
sub ::hidden {}
|
||||
|
||||
1;
|
||||
|
||||
@@ -45,9 +45,8 @@ sub ::generic
|
||||
undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
|
||||
|
||||
if ($#_==0) { &::emit($opcode); }
|
||||
elsif ($opcode =~ m/^j/o && $#_==1) { &::emit($opcode,@arg); }
|
||||
elsif ($opcode eq "call" && $#_==1) { &::emit($opcode,@arg); }
|
||||
elsif ($opcode =~ m/^set/&& $#_==1) { &::emit($opcode,@arg); }
|
||||
elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
|
||||
{ &::emit($opcode,@arg); }
|
||||
else { &::emit($opcode.$suffix,@arg);}
|
||||
|
||||
1;
|
||||
@@ -71,6 +70,8 @@ sub ::DWP
|
||||
{ my($addr,$reg1,$reg2,$idx)=@_;
|
||||
my $ret="";
|
||||
|
||||
if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }
|
||||
|
||||
$addr =~ s/^\s+//;
|
||||
# prepend global references with optional underscore
|
||||
$addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
|
||||
@@ -91,6 +92,7 @@ sub ::DWP
|
||||
}
|
||||
sub ::QWP { &::DWP(@_); }
|
||||
sub ::BP { &::DWP(@_); }
|
||||
sub ::WP { &::DWP(@_); }
|
||||
sub ::BC { @_; }
|
||||
sub ::DWC { @_; }
|
||||
|
||||
@@ -149,29 +151,30 @@ sub ::public_label
|
||||
{ push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); }
|
||||
|
||||
sub ::file_end
|
||||
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
|
||||
my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,4";
|
||||
if ($::elf) { push (@out,"$tmp,4\n"); }
|
||||
else { push (@out,"$tmp\n"); }
|
||||
}
|
||||
if ($::macosx)
|
||||
{ if ($::macosx)
|
||||
{ if (%non_lazy_ptr)
|
||||
{ push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
|
||||
foreach $i (keys %non_lazy_ptr)
|
||||
{ push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n"); }
|
||||
}
|
||||
}
|
||||
if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
|
||||
my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,16";
|
||||
if ($::macosx) { push (@out,"$tmp,2\n"); }
|
||||
elsif ($::elf) { push (@out,"$tmp,4\n"); }
|
||||
else { push (@out,"$tmp\n"); }
|
||||
}
|
||||
push(@out,$initseg) if ($initseg);
|
||||
}
|
||||
|
||||
sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); }
|
||||
sub ::data_short{ push(@out,".value\t".join(',',@_)."\n"); }
|
||||
sub ::data_word { push(@out,".long\t".join(',',@_)."\n"); }
|
||||
|
||||
sub ::align
|
||||
{ my $val=$_[0],$p2,$i;
|
||||
{ my $val=$_[0];
|
||||
if ($::aout)
|
||||
{ for ($p2=0;$val!=0;$val>>=1) { $p2++; }
|
||||
$val=$p2-1;
|
||||
{ $val=int(log($val)/log(2));
|
||||
$val.=",0x90";
|
||||
}
|
||||
push(@out,".align\t$val\n");
|
||||
@@ -180,7 +183,7 @@ sub ::align
|
||||
sub ::picmeup
|
||||
{ my($dst,$sym,$base,$reflabel)=@_;
|
||||
|
||||
if ($::pic && ($::elf || $::aout))
|
||||
if (($::pic && ($::elf || $::aout)) || $::macosx)
|
||||
{ if (!defined($base))
|
||||
{ &::call(&::label("PIC_me_up"));
|
||||
&::set_label("PIC_me_up");
|
||||
@@ -193,6 +196,8 @@ sub ::picmeup
|
||||
&::mov($dst,&::DWP("$indirect-$reflabel",$base));
|
||||
$non_lazy_ptr{"$nmdecor$sym"}=$indirect;
|
||||
}
|
||||
elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0)
|
||||
{ &::lea($dst,&::DWP("$sym-$reflabel",$base)); }
|
||||
else
|
||||
{ &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
|
||||
$base));
|
||||
@@ -206,13 +211,17 @@ sub ::picmeup
|
||||
sub ::initseg
|
||||
{ my $f=$nmdecor.shift;
|
||||
|
||||
if ($::elf)
|
||||
if ($::android)
|
||||
{ $initseg.=<<___;
|
||||
.section .init_array
|
||||
.align 4
|
||||
.long $f
|
||||
___
|
||||
}
|
||||
elsif ($::elf)
|
||||
{ $initseg.=<<___;
|
||||
.section .init
|
||||
call $f
|
||||
jmp .Linitalign
|
||||
.align $align
|
||||
.Linitalign:
|
||||
___
|
||||
}
|
||||
elsif ($::coff)
|
||||
@@ -244,4 +253,6 @@ ___
|
||||
sub ::dataseg
|
||||
{ push(@out,".data\n"); }
|
||||
|
||||
*::hidden = sub { push(@out,".hidden\t$nmdecor$_[0]\n"); } if ($::elf);
|
||||
|
||||
1;
|
||||
|
||||
@@ -14,9 +14,11 @@ sub ::generic
|
||||
{ my ($opcode,@arg)=@_;
|
||||
|
||||
# fix hexadecimal constants
|
||||
for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
|
||||
for (@arg) { s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/oi; }
|
||||
|
||||
if ($opcode !~ /movq/)
|
||||
if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+(\(.*\))$/OFFSET $1/) # no []
|
||||
{ $opcode="mov"; }
|
||||
elsif ($opcode !~ /movq/)
|
||||
{ # fix xmm references
|
||||
$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
|
||||
$arg[1] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[0]=~/\bxmm[0-7]\b/i);
|
||||
@@ -31,11 +33,14 @@ sub ::generic
|
||||
sub ::call { &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
|
||||
sub ::call_ptr { &::emit("call",@_); }
|
||||
sub ::jmp_ptr { &::emit("jmp",@_); }
|
||||
sub ::lock { &::data_byte(0xf0); }
|
||||
|
||||
sub get_mem
|
||||
{ my($size,$addr,$reg1,$reg2,$idx)=@_;
|
||||
my($post,$ret);
|
||||
|
||||
if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }
|
||||
|
||||
$ret .= "$size PTR " if ($size ne "");
|
||||
|
||||
$addr =~ s/^\s+//;
|
||||
@@ -65,6 +70,7 @@ sub get_mem
|
||||
$ret;
|
||||
}
|
||||
sub ::BP { &get_mem("BYTE",@_); }
|
||||
sub ::WP { &get_mem("WORD",@_); }
|
||||
sub ::DWP { &get_mem("DWORD",@_); }
|
||||
sub ::QWP { &get_mem("QWORD",@_); }
|
||||
sub ::BC { "@_"; }
|
||||
@@ -129,7 +135,7 @@ ___
|
||||
if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
||||
{ my $comm=<<___;
|
||||
.bss SEGMENT 'BSS'
|
||||
COMM ${nmdecor}OPENSSL_ia32cap_P:DWORD
|
||||
COMM ${nmdecor}OPENSSL_ia32cap_P:DWORD:4
|
||||
.bss ENDS
|
||||
___
|
||||
# comment out OPENSSL_ia32cap_P declarations
|
||||
@@ -156,6 +162,9 @@ sub ::public_label
|
||||
sub ::data_byte
|
||||
{ push(@out,("DB\t").join(',',@_)."\n"); }
|
||||
|
||||
sub ::data_short
|
||||
{ push(@out,("DW\t").join(',',@_)."\n"); }
|
||||
|
||||
sub ::data_word
|
||||
{ push(@out,("DD\t").join(',',@_)."\n"); }
|
||||
|
||||
@@ -181,4 +190,11 @@ ___
|
||||
sub ::dataseg
|
||||
{ push(@out,"$segment\tENDS\n_DATA\tSEGMENT\n"); $segment="_DATA"; }
|
||||
|
||||
sub ::safeseh
|
||||
{ my $nm=shift;
|
||||
push(@out,"IF \@Version GE 710\n");
|
||||
push(@out,".SAFESEH ".&::LABEL($nm,$nmdecor.$nm)."\n");
|
||||
push(@out,"ENDIF\n");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -19,6 +19,8 @@ sub ::generic
|
||||
{ $_[0] = "NEAR $_[0]"; }
|
||||
elsif ($opcode eq "lea" && $#_==1) # wipe storage qualifier from lea
|
||||
{ $_[1] =~ s/^[^\[]*\[/\[/o; }
|
||||
elsif ($opcode eq "clflush" && $#_==0)
|
||||
{ $_[0] =~ s/^[^\[]*\[/\[/o; }
|
||||
}
|
||||
&::emit($opcode,@_);
|
||||
1;
|
||||
@@ -34,6 +36,8 @@ sub get_mem
|
||||
{ my($size,$addr,$reg1,$reg2,$idx)=@_;
|
||||
my($post,$ret);
|
||||
|
||||
if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }
|
||||
|
||||
if ($size ne "")
|
||||
{ $ret .= "$size";
|
||||
$ret .= " PTR" if ($::mwerks);
|
||||
@@ -67,6 +71,7 @@ sub get_mem
|
||||
}
|
||||
sub ::BP { &get_mem("BYTE",@_); }
|
||||
sub ::DWP { &get_mem("DWORD",@_); }
|
||||
sub ::WP { &get_mem("WORD",@_); }
|
||||
sub ::QWP { &get_mem("",@_); }
|
||||
sub ::BC { (($::mwerks)?"":"BYTE ")."@_"; }
|
||||
sub ::DWC { (($::mwerks)?"":"DWORD ")."@_"; }
|
||||
@@ -114,7 +119,7 @@ sub ::file_end
|
||||
{ if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
|
||||
{ my $comm=<<___;
|
||||
${drdecor}segment .bss
|
||||
${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 4
|
||||
${drdecor}common ${nmdecor}OPENSSL_ia32cap_P 16
|
||||
___
|
||||
# comment out OPENSSL_ia32cap_P declarations
|
||||
grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
|
||||
@@ -135,7 +140,8 @@ sub ::public_label
|
||||
|
||||
sub ::data_byte
|
||||
{ push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n"); }
|
||||
|
||||
sub ::data_short
|
||||
{ push(@out,(($::mwerks)?".word\t":"dw\t").join(',',@_)."\n"); }
|
||||
sub ::data_word
|
||||
{ push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n"); }
|
||||
|
||||
@@ -163,4 +169,11 @@ sub ::dataseg
|
||||
else { push(@out,"section\t.data align=4\n"); }
|
||||
}
|
||||
|
||||
sub ::safeseh
|
||||
{ my $nm=shift;
|
||||
push(@out,"%if __NASM_VERSION_ID__ >= 0x02030000\n");
|
||||
push(@out,"safeseh ".&::LABEL($nm,$nmdecor.$nm)."\n");
|
||||
push(@out,"%endif\n");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Reference in New Issue
Block a user