xref: /aosp_15_r20/external/boringssl/src/crypto/perlasm/x86nasm.pl (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker#! /usr/bin/env perl
2*8fb009dcSAndroid Build Coastguard Worker# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
3*8fb009dcSAndroid Build Coastguard Worker#
4*8fb009dcSAndroid Build Coastguard Worker# Licensed under the OpenSSL license (the "License").  You may not use
5*8fb009dcSAndroid Build Coastguard Worker# this file except in compliance with the License.  You can obtain a copy
6*8fb009dcSAndroid Build Coastguard Worker# in the file LICENSE in the source distribution or at
7*8fb009dcSAndroid Build Coastguard Worker# https://www.openssl.org/source/license.html
8*8fb009dcSAndroid Build Coastguard Worker
9*8fb009dcSAndroid Build Coastguard Worker
10*8fb009dcSAndroid Build Coastguard Workerpackage x86nasm;
11*8fb009dcSAndroid Build Coastguard Worker
12*8fb009dcSAndroid Build Coastguard Worker*out=\@::out;
13*8fb009dcSAndroid Build Coastguard Worker
14*8fb009dcSAndroid Build Coastguard Worker$::lbdecor="L\$";		# local label decoration
15*8fb009dcSAndroid Build Coastguard Worker$nmdecor="_";			# external name decoration
16*8fb009dcSAndroid Build Coastguard Worker$drdecor=$::mwerks?".":"";	# directive decoration
17*8fb009dcSAndroid Build Coastguard Worker
18*8fb009dcSAndroid Build Coastguard Worker$initseg="";
19*8fb009dcSAndroid Build Coastguard Worker
20*8fb009dcSAndroid Build Coastguard Workersub ::generic
21*8fb009dcSAndroid Build Coastguard Worker{ my $opcode=shift;
22*8fb009dcSAndroid Build Coastguard Worker  my $tmp;
23*8fb009dcSAndroid Build Coastguard Worker
24*8fb009dcSAndroid Build Coastguard Worker    if (!$::mwerks)
25*8fb009dcSAndroid Build Coastguard Worker    {   if    ($opcode =~ m/^j/o && $#_==0) # optimize jumps
26*8fb009dcSAndroid Build Coastguard Worker	{   $_[0] = "NEAR $_[0]";   	}
27*8fb009dcSAndroid Build Coastguard Worker	elsif ($opcode eq "lea" && $#_==1)  # wipe storage qualifier from lea
28*8fb009dcSAndroid Build Coastguard Worker	{   $_[1] =~ s/^[^\[]*\[/\[/o;	}
29*8fb009dcSAndroid Build Coastguard Worker	elsif ($opcode eq "clflush" && $#_==0)
30*8fb009dcSAndroid Build Coastguard Worker	{   $_[0] =~ s/^[^\[]*\[/\[/o;	}
31*8fb009dcSAndroid Build Coastguard Worker    }
32*8fb009dcSAndroid Build Coastguard Worker    &::emit($opcode,@_);
33*8fb009dcSAndroid Build Coastguard Worker  1;
34*8fb009dcSAndroid Build Coastguard Worker}
35*8fb009dcSAndroid Build Coastguard Worker#
36*8fb009dcSAndroid Build Coastguard Worker# opcodes not covered by ::generic above, mostly inconsistent namings...
37*8fb009dcSAndroid Build Coastguard Worker#
38*8fb009dcSAndroid Build Coastguard Workersub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
39*8fb009dcSAndroid Build Coastguard Workersub ::call_ptr	{ &::emit("call",@_);	}
40*8fb009dcSAndroid Build Coastguard Workersub ::jmp_ptr	{ &::emit("jmp",@_);	}
41*8fb009dcSAndroid Build Coastguard Worker
42*8fb009dcSAndroid Build Coastguard Workersub get_mem
43*8fb009dcSAndroid Build Coastguard Worker{ my($size,$addr,$reg1,$reg2,$idx)=@_;
44*8fb009dcSAndroid Build Coastguard Worker  my($post,$ret);
45*8fb009dcSAndroid Build Coastguard Worker
46*8fb009dcSAndroid Build Coastguard Worker    if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }
47*8fb009dcSAndroid Build Coastguard Worker
48*8fb009dcSAndroid Build Coastguard Worker    if ($size ne "")
49*8fb009dcSAndroid Build Coastguard Worker    {	$ret .= "$size";
50*8fb009dcSAndroid Build Coastguard Worker	$ret .= " PTR" if ($::mwerks);
51*8fb009dcSAndroid Build Coastguard Worker	$ret .= " ";
52*8fb009dcSAndroid Build Coastguard Worker    }
53*8fb009dcSAndroid Build Coastguard Worker    $ret .= "[";
54*8fb009dcSAndroid Build Coastguard Worker
55*8fb009dcSAndroid Build Coastguard Worker    $addr =~ s/^\s+//;
56*8fb009dcSAndroid Build Coastguard Worker    # prepend global references with optional underscore
57*8fb009dcSAndroid Build Coastguard Worker    $addr =~ s/^([^\+\-0-9][^\+\-]*)/::islabel($1) or "$nmdecor$1"/ige;
58*8fb009dcSAndroid Build Coastguard Worker    # put address arithmetic expression in parenthesis
59*8fb009dcSAndroid Build Coastguard Worker    $addr="($addr)" if ($addr =~ /^.+[\-\+].+$/);
60*8fb009dcSAndroid Build Coastguard Worker
61*8fb009dcSAndroid Build Coastguard Worker    if (($addr ne "") && ($addr ne 0))
62*8fb009dcSAndroid Build Coastguard Worker    {	if ($addr !~ /^-/)	{ $ret .= "$addr+"; }
63*8fb009dcSAndroid Build Coastguard Worker	else			{ $post=$addr;      }
64*8fb009dcSAndroid Build Coastguard Worker    }
65*8fb009dcSAndroid Build Coastguard Worker
66*8fb009dcSAndroid Build Coastguard Worker    if ($reg2 ne "")
67*8fb009dcSAndroid Build Coastguard Worker    {	$idx!=0 or $idx=1;
68*8fb009dcSAndroid Build Coastguard Worker	$ret .= "$reg2*$idx";
69*8fb009dcSAndroid Build Coastguard Worker	$ret .= "+$reg1" if ($reg1 ne "");
70*8fb009dcSAndroid Build Coastguard Worker    }
71*8fb009dcSAndroid Build Coastguard Worker    else
72*8fb009dcSAndroid Build Coastguard Worker    {	$ret .= "$reg1";   }
73*8fb009dcSAndroid Build Coastguard Worker
74*8fb009dcSAndroid Build Coastguard Worker    $ret .= "$post]";
75*8fb009dcSAndroid Build Coastguard Worker    $ret =~ s/\+\]/]/; # in case $addr was the only argument
76*8fb009dcSAndroid Build Coastguard Worker
77*8fb009dcSAndroid Build Coastguard Worker  $ret;
78*8fb009dcSAndroid Build Coastguard Worker}
79*8fb009dcSAndroid Build Coastguard Workersub ::BP	{ &get_mem("BYTE",@_);  }
80*8fb009dcSAndroid Build Coastguard Workersub ::DWP	{ &get_mem("DWORD",@_); }
81*8fb009dcSAndroid Build Coastguard Workersub ::WP	{ &get_mem("WORD",@_);	}
82*8fb009dcSAndroid Build Coastguard Workersub ::QWP	{ &get_mem("",@_);      }
83*8fb009dcSAndroid Build Coastguard Workersub ::BC	{ (($::mwerks)?"":"BYTE ")."@_";  }
84*8fb009dcSAndroid Build Coastguard Workersub ::DWC	{ (($::mwerks)?"":"DWORD ")."@_"; }
85*8fb009dcSAndroid Build Coastguard Worker
86*8fb009dcSAndroid Build Coastguard Workersub ::file
87*8fb009dcSAndroid Build Coastguard Worker{   if ($::mwerks)	{ push(@out,".section\t.text,64\n"); }
88*8fb009dcSAndroid Build Coastguard Worker    else
89*8fb009dcSAndroid Build Coastguard Worker    { my $tmp=<<___;
90*8fb009dcSAndroid Build Coastguard Worker%ifidn __OUTPUT_FORMAT__,obj
91*8fb009dcSAndroid Build Coastguard Workersection	code	use32 class=code align=64
92*8fb009dcSAndroid Build Coastguard Worker%elifidn __OUTPUT_FORMAT__,win32
93*8fb009dcSAndroid Build Coastguard Worker\$\@feat.00 equ 1
94*8fb009dcSAndroid Build Coastguard Workersection	.text	code align=64
95*8fb009dcSAndroid Build Coastguard Worker%else
96*8fb009dcSAndroid Build Coastguard Workersection	.text	code
97*8fb009dcSAndroid Build Coastguard Worker%endif
98*8fb009dcSAndroid Build Coastguard Worker___
99*8fb009dcSAndroid Build Coastguard Worker	push(@out,$tmp);
100*8fb009dcSAndroid Build Coastguard Worker    }
101*8fb009dcSAndroid Build Coastguard Worker}
102*8fb009dcSAndroid Build Coastguard Worker
103*8fb009dcSAndroid Build Coastguard Workersub ::function_begin_B
104*8fb009dcSAndroid Build Coastguard Worker{ my $func=shift;
105*8fb009dcSAndroid Build Coastguard Worker  my $global=($func !~ /^_/);
106*8fb009dcSAndroid Build Coastguard Worker  my $begin="${::lbdecor}_${func}_begin";
107*8fb009dcSAndroid Build Coastguard Worker
108*8fb009dcSAndroid Build Coastguard Worker    $begin =~ s/^\@/./ if ($::mwerks);	# the torture never stops
109*8fb009dcSAndroid Build Coastguard Worker
110*8fb009dcSAndroid Build Coastguard Worker    &::LABEL($func,$global?"$begin":"$nmdecor$func");
111*8fb009dcSAndroid Build Coastguard Worker    $func=$nmdecor.$func;
112*8fb009dcSAndroid Build Coastguard Worker
113*8fb009dcSAndroid Build Coastguard Worker    push(@out,"${drdecor}global	$func\n")	if ($global);
114*8fb009dcSAndroid Build Coastguard Worker    push(@out,"${drdecor}align	16\n");
115*8fb009dcSAndroid Build Coastguard Worker    push(@out,"$func:\n");
116*8fb009dcSAndroid Build Coastguard Worker    push(@out,"$begin:\n")			if ($global);
117*8fb009dcSAndroid Build Coastguard Worker    $::stack=4;
118*8fb009dcSAndroid Build Coastguard Worker}
119*8fb009dcSAndroid Build Coastguard Worker
120*8fb009dcSAndroid Build Coastguard Workersub ::function_end_B
121*8fb009dcSAndroid Build Coastguard Worker{   $::stack=0;
122*8fb009dcSAndroid Build Coastguard Worker    &::wipe_labels();
123*8fb009dcSAndroid Build Coastguard Worker}
124*8fb009dcSAndroid Build Coastguard Worker
125*8fb009dcSAndroid Build Coastguard Workersub ::file_end
126*8fb009dcSAndroid Build Coastguard Worker{   if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out)
127*8fb009dcSAndroid Build Coastguard Worker    {	my $comm=<<___;
128*8fb009dcSAndroid Build Coastguard Worker${drdecor}segment	.bss
129*8fb009dcSAndroid Build Coastguard Worker${drdecor}common	${nmdecor}OPENSSL_ia32cap_P 16
130*8fb009dcSAndroid Build Coastguard Worker___
131*8fb009dcSAndroid Build Coastguard Worker	# comment out OPENSSL_ia32cap_P declarations
132*8fb009dcSAndroid Build Coastguard Worker	grep {s/(^extern\s+${nmdecor}OPENSSL_ia32cap_P)/\;$1/} @out;
133*8fb009dcSAndroid Build Coastguard Worker	push (@out,$comm)
134*8fb009dcSAndroid Build Coastguard Worker    }
135*8fb009dcSAndroid Build Coastguard Worker    push (@out,$initseg) if ($initseg);
136*8fb009dcSAndroid Build Coastguard Worker}
137*8fb009dcSAndroid Build Coastguard Worker
138*8fb009dcSAndroid Build Coastguard Workersub ::comment {   foreach (@_) { push(@out,"\t; $_\n"); }   }
139*8fb009dcSAndroid Build Coastguard Worker
140*8fb009dcSAndroid Build Coastguard Workersub ::external_label
141*8fb009dcSAndroid Build Coastguard Worker{   foreach(@_)
142*8fb009dcSAndroid Build Coastguard Worker    {	push(@out,"${drdecor}extern\t".&::LABEL($_,$nmdecor.$_)."\n");   }
143*8fb009dcSAndroid Build Coastguard Worker}
144*8fb009dcSAndroid Build Coastguard Worker
145*8fb009dcSAndroid Build Coastguard Workersub ::public_label
146*8fb009dcSAndroid Build Coastguard Worker{   push(@out,"${drdecor}global\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");  }
147*8fb009dcSAndroid Build Coastguard Worker
148*8fb009dcSAndroid Build Coastguard Workersub ::data_byte
149*8fb009dcSAndroid Build Coastguard Worker{   push(@out,(($::mwerks)?".byte\t":"db\t").join(',',@_)."\n");	}
150*8fb009dcSAndroid Build Coastguard Workersub ::data_short
151*8fb009dcSAndroid Build Coastguard Worker{   push(@out,(($::mwerks)?".word\t":"dw\t").join(',',@_)."\n");	}
152*8fb009dcSAndroid Build Coastguard Workersub ::data_word
153*8fb009dcSAndroid Build Coastguard Worker{   push(@out,(($::mwerks)?".long\t":"dd\t").join(',',@_)."\n");	}
154*8fb009dcSAndroid Build Coastguard Worker
155*8fb009dcSAndroid Build Coastguard Workersub ::align
156*8fb009dcSAndroid Build Coastguard Worker{   push(@out,"${drdecor}align\t$_[0]\n");	}
157*8fb009dcSAndroid Build Coastguard Worker
158*8fb009dcSAndroid Build Coastguard Workersub ::picmeup
159*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$sym)=@_;
160*8fb009dcSAndroid Build Coastguard Worker    &::lea($dst,&::DWP($sym));
161*8fb009dcSAndroid Build Coastguard Worker}
162*8fb009dcSAndroid Build Coastguard Worker
163*8fb009dcSAndroid Build Coastguard Workersub ::initseg
164*8fb009dcSAndroid Build Coastguard Worker{ my $f=$nmdecor.shift;
165*8fb009dcSAndroid Build Coastguard Worker    if ($::win32)
166*8fb009dcSAndroid Build Coastguard Worker    {	$initseg=<<___;
167*8fb009dcSAndroid Build Coastguard Workersegment	.CRT\$XCU data align=4
168*8fb009dcSAndroid Build Coastguard Workerextern	$f
169*8fb009dcSAndroid Build Coastguard Workerdd	$f
170*8fb009dcSAndroid Build Coastguard Worker___
171*8fb009dcSAndroid Build Coastguard Worker    }
172*8fb009dcSAndroid Build Coastguard Worker}
173*8fb009dcSAndroid Build Coastguard Worker
174*8fb009dcSAndroid Build Coastguard Workersub ::dataseg
175*8fb009dcSAndroid Build Coastguard Worker{   if ($mwerks)	{ push(@out,".section\t.data,4\n");   }
176*8fb009dcSAndroid Build Coastguard Worker    else		{ push(@out,"section\t.data align=4\n"); }
177*8fb009dcSAndroid Build Coastguard Worker}
178*8fb009dcSAndroid Build Coastguard Worker
179*8fb009dcSAndroid Build Coastguard Workersub ::safeseh
180*8fb009dcSAndroid Build Coastguard Worker{ my $nm=shift;
181*8fb009dcSAndroid Build Coastguard Worker    push(@out,"%if	__NASM_VERSION_ID__ >= 0x02030000\n");
182*8fb009dcSAndroid Build Coastguard Worker    push(@out,"safeseh	".&::LABEL($nm,$nmdecor.$nm)."\n");
183*8fb009dcSAndroid Build Coastguard Worker    push(@out,"%endif\n");
184*8fb009dcSAndroid Build Coastguard Worker}
185*8fb009dcSAndroid Build Coastguard Worker
186*8fb009dcSAndroid Build Coastguard Workersub ::preprocessor_ifdef
187*8fb009dcSAndroid Build Coastguard Worker{ my($define)=@_;
188*8fb009dcSAndroid Build Coastguard Worker    push(@out,"%ifdef ${define}\n");
189*8fb009dcSAndroid Build Coastguard Worker}
190*8fb009dcSAndroid Build Coastguard Worker
191*8fb009dcSAndroid Build Coastguard Workersub ::preprocessor_endif
192*8fb009dcSAndroid Build Coastguard Worker{ push(@out,"%endif\n");    }
193*8fb009dcSAndroid Build Coastguard Worker
194*8fb009dcSAndroid Build Coastguard Worker1;
195