xref: /aosp_15_r20/external/boringssl/src/crypto/perlasm/x86asm.pl (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker#! /usr/bin/env perl
2*8fb009dcSAndroid Build Coastguard Worker# Copyright 1995-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 Worker# require 'x86asm.pl';
11*8fb009dcSAndroid Build Coastguard Worker# &asm_init(<flavor>[,$i386only]);
12*8fb009dcSAndroid Build Coastguard Worker# &function_begin("foo");
13*8fb009dcSAndroid Build Coastguard Worker# ...
14*8fb009dcSAndroid Build Coastguard Worker# &function_end("foo");
15*8fb009dcSAndroid Build Coastguard Worker# &asm_finish
16*8fb009dcSAndroid Build Coastguard Worker
17*8fb009dcSAndroid Build Coastguard Worker$out=();
18*8fb009dcSAndroid Build Coastguard Worker$i386=0;
19*8fb009dcSAndroid Build Coastguard Worker
20*8fb009dcSAndroid Build Coastguard Worker# AUTOLOAD is this context has quite unpleasant side effect, namely
21*8fb009dcSAndroid Build Coastguard Worker# that typos in function calls effectively go to assembler output,
22*8fb009dcSAndroid Build Coastguard Worker# but on the pros side we don't have to implement one subroutine per
23*8fb009dcSAndroid Build Coastguard Worker# each opcode...
24*8fb009dcSAndroid Build Coastguard Workersub ::AUTOLOAD
25*8fb009dcSAndroid Build Coastguard Worker{ my $opcode = $AUTOLOAD;
26*8fb009dcSAndroid Build Coastguard Worker
27*8fb009dcSAndroid Build Coastguard Worker    die "more than 4 arguments passed to $opcode" if ($#_>3);
28*8fb009dcSAndroid Build Coastguard Worker
29*8fb009dcSAndroid Build Coastguard Worker    $opcode =~ s/.*:://;
30*8fb009dcSAndroid Build Coastguard Worker    if    ($opcode =~ /^push/) { $stack+=4; }
31*8fb009dcSAndroid Build Coastguard Worker    elsif ($opcode =~ /^pop/)  { $stack-=4; }
32*8fb009dcSAndroid Build Coastguard Worker
33*8fb009dcSAndroid Build Coastguard Worker    &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
34*8fb009dcSAndroid Build Coastguard Worker}
35*8fb009dcSAndroid Build Coastguard Worker
36*8fb009dcSAndroid Build Coastguard Worker# record_function_hit(int) writes a byte with value one to the given offset of
37*8fb009dcSAndroid Build Coastguard Worker# |BORINGSSL_function_hit|, but only if BORINGSSL_DISPATCH_TEST is defined.
38*8fb009dcSAndroid Build Coastguard Worker# This is used in impl_dispatch_test.cc to test whether the expected assembly
39*8fb009dcSAndroid Build Coastguard Worker# functions are triggered by high-level API calls.
40*8fb009dcSAndroid Build Coastguard Workersub ::record_function_hit
41*8fb009dcSAndroid Build Coastguard Worker{ my($index)=@_;
42*8fb009dcSAndroid Build Coastguard Worker    &preprocessor_ifdef("BORINGSSL_DISPATCH_TEST");
43*8fb009dcSAndroid Build Coastguard Worker    &push("ebx");
44*8fb009dcSAndroid Build Coastguard Worker    &push("edx");
45*8fb009dcSAndroid Build Coastguard Worker    &call(&label("pic_for_function_hit"));
46*8fb009dcSAndroid Build Coastguard Worker    &set_label("pic_for_function_hit");
47*8fb009dcSAndroid Build Coastguard Worker    &blindpop("ebx");
48*8fb009dcSAndroid Build Coastguard Worker    &lea("ebx",&DWP("BORINGSSL_function_hit+$index"."-".&label("pic_for_function_hit"),"ebx"));
49*8fb009dcSAndroid Build Coastguard Worker    &mov("edx", 1);
50*8fb009dcSAndroid Build Coastguard Worker    &movb(&BP(0, "ebx"), "dl");
51*8fb009dcSAndroid Build Coastguard Worker    &pop("edx");
52*8fb009dcSAndroid Build Coastguard Worker    &pop("ebx");
53*8fb009dcSAndroid Build Coastguard Worker    &preprocessor_endif();
54*8fb009dcSAndroid Build Coastguard Worker}
55*8fb009dcSAndroid Build Coastguard Worker
56*8fb009dcSAndroid Build Coastguard Workersub ::emit
57*8fb009dcSAndroid Build Coastguard Worker{ my $opcode=shift;
58*8fb009dcSAndroid Build Coastguard Worker
59*8fb009dcSAndroid Build Coastguard Worker    if ($#_==-1)    { push(@out,"\t$opcode\n");				}
60*8fb009dcSAndroid Build Coastguard Worker    else            { push(@out,"\t$opcode\t".join(',',@_)."\n");	}
61*8fb009dcSAndroid Build Coastguard Worker}
62*8fb009dcSAndroid Build Coastguard Worker
63*8fb009dcSAndroid Build Coastguard Workersub ::LB
64*8fb009dcSAndroid Build Coastguard Worker{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
65*8fb009dcSAndroid Build Coastguard Worker  $1."l";
66*8fb009dcSAndroid Build Coastguard Worker}
67*8fb009dcSAndroid Build Coastguard Workersub ::HB
68*8fb009dcSAndroid Build Coastguard Worker{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
69*8fb009dcSAndroid Build Coastguard Worker  $1."h";
70*8fb009dcSAndroid Build Coastguard Worker}
71*8fb009dcSAndroid Build Coastguard Workersub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num);	}
72*8fb009dcSAndroid Build Coastguard Workersub ::stack_pop	{ my $num=$_[0]*4; $stack-=$num; &add("esp",$num);	}
73*8fb009dcSAndroid Build Coastguard Workersub ::blindpop	{ &pop($_[0]); $stack+=4;				}
74*8fb009dcSAndroid Build Coastguard Workersub ::wparam	{ &DWP($stack+4*$_[0],"esp");				}
75*8fb009dcSAndroid Build Coastguard Workersub ::swtmp	{ &DWP(4*$_[0],"esp");					}
76*8fb009dcSAndroid Build Coastguard Worker
77*8fb009dcSAndroid Build Coastguard Workersub ::bswap
78*8fb009dcSAndroid Build Coastguard Worker{   if ($i386)	# emulate bswap for i386
79*8fb009dcSAndroid Build Coastguard Worker    {	&comment("bswap @_");
80*8fb009dcSAndroid Build Coastguard Worker	&xchg(&HB(@_),&LB(@_));
81*8fb009dcSAndroid Build Coastguard Worker	&ror (@_,16);
82*8fb009dcSAndroid Build Coastguard Worker	&xchg(&HB(@_),&LB(@_));
83*8fb009dcSAndroid Build Coastguard Worker    }
84*8fb009dcSAndroid Build Coastguard Worker    else
85*8fb009dcSAndroid Build Coastguard Worker    {	&generic("bswap",@_);	}
86*8fb009dcSAndroid Build Coastguard Worker}
87*8fb009dcSAndroid Build Coastguard Worker# These are made-up opcodes introduced over the years essentially
88*8fb009dcSAndroid Build Coastguard Worker# by ignorance, just alias them to real ones...
89*8fb009dcSAndroid Build Coastguard Workersub ::movb	{ &mov(@_);	}
90*8fb009dcSAndroid Build Coastguard Workersub ::xorb	{ &xor(@_);	}
91*8fb009dcSAndroid Build Coastguard Workersub ::rotl	{ &rol(@_);	}
92*8fb009dcSAndroid Build Coastguard Workersub ::rotr	{ &ror(@_);	}
93*8fb009dcSAndroid Build Coastguard Workersub ::exch	{ &xchg(@_);	}
94*8fb009dcSAndroid Build Coastguard Workersub ::halt	{ &hlt;		}
95*8fb009dcSAndroid Build Coastguard Workersub ::movz	{ &movzx(@_);	}
96*8fb009dcSAndroid Build Coastguard Workersub ::pushf	{ &pushfd;	}
97*8fb009dcSAndroid Build Coastguard Workersub ::popf	{ &popfd;	}
98*8fb009dcSAndroid Build Coastguard Worker
99*8fb009dcSAndroid Build Coastguard Worker# 3 argument instructions
100*8fb009dcSAndroid Build Coastguard Workersub ::movq
101*8fb009dcSAndroid Build Coastguard Worker{ my($p1,$p2,$optimize)=@_;
102*8fb009dcSAndroid Build Coastguard Worker
103*8fb009dcSAndroid Build Coastguard Worker    if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
104*8fb009dcSAndroid Build Coastguard Worker    # movq between mmx registers can sink Intel CPUs
105*8fb009dcSAndroid Build Coastguard Worker    {	&::pshufw($p1,$p2,0xe4);		}
106*8fb009dcSAndroid Build Coastguard Worker    else
107*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("movq",@_);			}
108*8fb009dcSAndroid Build Coastguard Worker}
109*8fb009dcSAndroid Build Coastguard Worker
110*8fb009dcSAndroid Build Coastguard Worker# SSE>2 instructions
111*8fb009dcSAndroid Build Coastguard Workermy %regrm = (	"eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
112*8fb009dcSAndroid Build Coastguard Worker		"esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7	);
113*8fb009dcSAndroid Build Coastguard Workersub ::pextrd
114*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$src,$imm)=@_;
115*8fb009dcSAndroid Build Coastguard Worker    if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
116*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm);	}
117*8fb009dcSAndroid Build Coastguard Worker    else
118*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("pextrd",@_);		}
119*8fb009dcSAndroid Build Coastguard Worker}
120*8fb009dcSAndroid Build Coastguard Worker
121*8fb009dcSAndroid Build Coastguard Workersub ::pinsrd
122*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$src,$imm)=@_;
123*8fb009dcSAndroid Build Coastguard Worker    if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
124*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm);	}
125*8fb009dcSAndroid Build Coastguard Worker    else
126*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("pinsrd",@_);		}
127*8fb009dcSAndroid Build Coastguard Worker}
128*8fb009dcSAndroid Build Coastguard Worker
129*8fb009dcSAndroid Build Coastguard Workersub ::pshufb
130*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$src)=@_;
131*8fb009dcSAndroid Build Coastguard Worker    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
132*8fb009dcSAndroid Build Coastguard Worker    {	&data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2);	}
133*8fb009dcSAndroid Build Coastguard Worker    else
134*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("pshufb",@_);		}
135*8fb009dcSAndroid Build Coastguard Worker}
136*8fb009dcSAndroid Build Coastguard Worker
137*8fb009dcSAndroid Build Coastguard Workersub ::palignr
138*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$src,$imm)=@_;
139*8fb009dcSAndroid Build Coastguard Worker    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
140*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm);	}
141*8fb009dcSAndroid Build Coastguard Worker    else
142*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("palignr",@_);		}
143*8fb009dcSAndroid Build Coastguard Worker}
144*8fb009dcSAndroid Build Coastguard Worker
145*8fb009dcSAndroid Build Coastguard Workersub ::pclmulqdq
146*8fb009dcSAndroid Build Coastguard Worker{ my($dst,$src,$imm)=@_;
147*8fb009dcSAndroid Build Coastguard Worker    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
148*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm);	}
149*8fb009dcSAndroid Build Coastguard Worker    else
150*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("pclmulqdq",@_);		}
151*8fb009dcSAndroid Build Coastguard Worker}
152*8fb009dcSAndroid Build Coastguard Worker
153*8fb009dcSAndroid Build Coastguard Workersub ::rdrand
154*8fb009dcSAndroid Build Coastguard Worker{ my ($dst)=@_;
155*8fb009dcSAndroid Build Coastguard Worker    if ($dst =~ /(e[a-dsd][ixp])/)
156*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x0f,0xc7,0xf0|$regrm{$dst});	}
157*8fb009dcSAndroid Build Coastguard Worker    else
158*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("rdrand",@_);	}
159*8fb009dcSAndroid Build Coastguard Worker}
160*8fb009dcSAndroid Build Coastguard Worker
161*8fb009dcSAndroid Build Coastguard Workersub ::rdseed
162*8fb009dcSAndroid Build Coastguard Worker{ my ($dst)=@_;
163*8fb009dcSAndroid Build Coastguard Worker    if ($dst =~ /(e[a-dsd][ixp])/)
164*8fb009dcSAndroid Build Coastguard Worker    {	&::data_byte(0x0f,0xc7,0xf8|$regrm{$dst});	}
165*8fb009dcSAndroid Build Coastguard Worker    else
166*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("rdrand",@_);	}
167*8fb009dcSAndroid Build Coastguard Worker}
168*8fb009dcSAndroid Build Coastguard Worker
169*8fb009dcSAndroid Build Coastguard Workersub rxb {
170*8fb009dcSAndroid Build Coastguard Worker local *opcode=shift;
171*8fb009dcSAndroid Build Coastguard Worker my ($dst,$src1,$src2,$rxb)=@_;
172*8fb009dcSAndroid Build Coastguard Worker
173*8fb009dcSAndroid Build Coastguard Worker   $rxb|=0x7<<5;
174*8fb009dcSAndroid Build Coastguard Worker   $rxb&=~(0x04<<5) if($dst>=8);
175*8fb009dcSAndroid Build Coastguard Worker   $rxb&=~(0x01<<5) if($src1>=8);
176*8fb009dcSAndroid Build Coastguard Worker   $rxb&=~(0x02<<5) if($src2>=8);
177*8fb009dcSAndroid Build Coastguard Worker   push @opcode,$rxb;
178*8fb009dcSAndroid Build Coastguard Worker}
179*8fb009dcSAndroid Build Coastguard Worker
180*8fb009dcSAndroid Build Coastguard Workersub ::vprotd
181*8fb009dcSAndroid Build Coastguard Worker{ my $args=join(',',@_);
182*8fb009dcSAndroid Build Coastguard Worker    if ($args =~ /xmm([0-7]),xmm([0-7]),([x0-9a-f]+)/)
183*8fb009dcSAndroid Build Coastguard Worker    { my @opcode=(0x8f);
184*8fb009dcSAndroid Build Coastguard Worker	rxb(\@opcode,$1,$2,-1,0x08);
185*8fb009dcSAndroid Build Coastguard Worker	push @opcode,0x78,0xc2;
186*8fb009dcSAndroid Build Coastguard Worker	push @opcode,0xc0|($2&7)|(($1&7)<<3);		# ModR/M
187*8fb009dcSAndroid Build Coastguard Worker	my $c=$3;
188*8fb009dcSAndroid Build Coastguard Worker	push @opcode,$c=~/^0/?oct($c):$c;
189*8fb009dcSAndroid Build Coastguard Worker	&::data_byte(@opcode);
190*8fb009dcSAndroid Build Coastguard Worker    }
191*8fb009dcSAndroid Build Coastguard Worker    else
192*8fb009dcSAndroid Build Coastguard Worker    {	&::generic("vprotd",@_);	}
193*8fb009dcSAndroid Build Coastguard Worker}
194*8fb009dcSAndroid Build Coastguard Worker
195*8fb009dcSAndroid Build Coastguard Workersub ::endbranch
196*8fb009dcSAndroid Build Coastguard Worker{
197*8fb009dcSAndroid Build Coastguard Worker    &::data_byte(0xf3,0x0f,0x1e,0xfb);
198*8fb009dcSAndroid Build Coastguard Worker}
199*8fb009dcSAndroid Build Coastguard Worker
200*8fb009dcSAndroid Build Coastguard Worker# label management
201*8fb009dcSAndroid Build Coastguard Worker$lbdecor="L";		# local label decoration, set by package
202*8fb009dcSAndroid Build Coastguard Worker$label="000";
203*8fb009dcSAndroid Build Coastguard Worker
204*8fb009dcSAndroid Build Coastguard Workersub ::islabel		# see is argument is a known label
205*8fb009dcSAndroid Build Coastguard Worker{ my $i;
206*8fb009dcSAndroid Build Coastguard Worker    foreach $i (values %label) { return $i if ($i eq $_[0]); }
207*8fb009dcSAndroid Build Coastguard Worker  $label{$_[0]};	# can be undef
208*8fb009dcSAndroid Build Coastguard Worker}
209*8fb009dcSAndroid Build Coastguard Worker
210*8fb009dcSAndroid Build Coastguard Workersub ::label		# instantiate a function-scope label
211*8fb009dcSAndroid Build Coastguard Worker{   if (!defined($label{$_[0]}))
212*8fb009dcSAndroid Build Coastguard Worker    {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   }
213*8fb009dcSAndroid Build Coastguard Worker  $label{$_[0]};
214*8fb009dcSAndroid Build Coastguard Worker}
215*8fb009dcSAndroid Build Coastguard Worker
216*8fb009dcSAndroid Build Coastguard Workersub ::LABEL		# instantiate a file-scope label
217*8fb009dcSAndroid Build Coastguard Worker{   $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
218*8fb009dcSAndroid Build Coastguard Worker  $label{$_[0]};
219*8fb009dcSAndroid Build Coastguard Worker}
220*8fb009dcSAndroid Build Coastguard Worker
221*8fb009dcSAndroid Build Coastguard Workersub ::static_label	{ &::LABEL($_[0],$lbdecor.$_[0]); }
222*8fb009dcSAndroid Build Coastguard Worker
223*8fb009dcSAndroid Build Coastguard Workersub ::set_label_B	{ push(@out,"@_:\n"); }
224*8fb009dcSAndroid Build Coastguard Workersub ::set_label
225*8fb009dcSAndroid Build Coastguard Worker{ my $label=&::label($_[0]);
226*8fb009dcSAndroid Build Coastguard Worker    &::align($_[1]) if ($_[1]>1);
227*8fb009dcSAndroid Build Coastguard Worker    &::set_label_B($label);
228*8fb009dcSAndroid Build Coastguard Worker  $label;
229*8fb009dcSAndroid Build Coastguard Worker}
230*8fb009dcSAndroid Build Coastguard Worker
231*8fb009dcSAndroid Build Coastguard Workersub ::wipe_labels	# wipes function-scope labels
232*8fb009dcSAndroid Build Coastguard Worker{   foreach $i (keys %label)
233*8fb009dcSAndroid Build Coastguard Worker    {	delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/);	}
234*8fb009dcSAndroid Build Coastguard Worker}
235*8fb009dcSAndroid Build Coastguard Worker
236*8fb009dcSAndroid Build Coastguard Worker# subroutine management
237*8fb009dcSAndroid Build Coastguard Workersub ::function_begin
238*8fb009dcSAndroid Build Coastguard Worker{   &function_begin_B(@_);
239*8fb009dcSAndroid Build Coastguard Worker    $stack=4;
240*8fb009dcSAndroid Build Coastguard Worker    &push("ebp");
241*8fb009dcSAndroid Build Coastguard Worker    &push("ebx");
242*8fb009dcSAndroid Build Coastguard Worker    &push("esi");
243*8fb009dcSAndroid Build Coastguard Worker    &push("edi");
244*8fb009dcSAndroid Build Coastguard Worker}
245*8fb009dcSAndroid Build Coastguard Worker
246*8fb009dcSAndroid Build Coastguard Workersub ::function_end
247*8fb009dcSAndroid Build Coastguard Worker{   &pop("edi");
248*8fb009dcSAndroid Build Coastguard Worker    &pop("esi");
249*8fb009dcSAndroid Build Coastguard Worker    &pop("ebx");
250*8fb009dcSAndroid Build Coastguard Worker    &pop("ebp");
251*8fb009dcSAndroid Build Coastguard Worker    &ret();
252*8fb009dcSAndroid Build Coastguard Worker    &function_end_B(@_);
253*8fb009dcSAndroid Build Coastguard Worker    $stack=0;
254*8fb009dcSAndroid Build Coastguard Worker    &wipe_labels();
255*8fb009dcSAndroid Build Coastguard Worker}
256*8fb009dcSAndroid Build Coastguard Worker
257*8fb009dcSAndroid Build Coastguard Workersub ::function_end_A
258*8fb009dcSAndroid Build Coastguard Worker{   &pop("edi");
259*8fb009dcSAndroid Build Coastguard Worker    &pop("esi");
260*8fb009dcSAndroid Build Coastguard Worker    &pop("ebx");
261*8fb009dcSAndroid Build Coastguard Worker    &pop("ebp");
262*8fb009dcSAndroid Build Coastguard Worker    &ret();
263*8fb009dcSAndroid Build Coastguard Worker    $stack+=16;	# readjust esp as if we didn't pop anything
264*8fb009dcSAndroid Build Coastguard Worker}
265*8fb009dcSAndroid Build Coastguard Worker
266*8fb009dcSAndroid Build Coastguard Workersub ::asciz
267*8fb009dcSAndroid Build Coastguard Worker{ my @str=unpack("C*",shift);
268*8fb009dcSAndroid Build Coastguard Worker    push @str,0;
269*8fb009dcSAndroid Build Coastguard Worker    while ($#str>15) {
270*8fb009dcSAndroid Build Coastguard Worker	&data_byte(@str[0..15]);
271*8fb009dcSAndroid Build Coastguard Worker	foreach (0..15) { shift @str; }
272*8fb009dcSAndroid Build Coastguard Worker    }
273*8fb009dcSAndroid Build Coastguard Worker    &data_byte(@str) if (@str);
274*8fb009dcSAndroid Build Coastguard Worker}
275*8fb009dcSAndroid Build Coastguard Worker
276*8fb009dcSAndroid Build Coastguard Workersub ::asm_finish
277*8fb009dcSAndroid Build Coastguard Worker{   &file_end();
278*8fb009dcSAndroid Build Coastguard Worker    my $comment = "//";
279*8fb009dcSAndroid Build Coastguard Worker    $comment = ";" if ($win32);
280*8fb009dcSAndroid Build Coastguard Worker    print <<___;
281*8fb009dcSAndroid Build Coastguard Worker$comment This file is generated from a similarly-named Perl script in the BoringSSL
282*8fb009dcSAndroid Build Coastguard Worker$comment source tree. Do not edit by hand.
283*8fb009dcSAndroid Build Coastguard Worker
284*8fb009dcSAndroid Build Coastguard Worker___
285*8fb009dcSAndroid Build Coastguard Worker    if ($win32) {
286*8fb009dcSAndroid Build Coastguard Worker        print <<___ unless $masm;
287*8fb009dcSAndroid Build Coastguard Worker\%ifdef BORINGSSL_PREFIX
288*8fb009dcSAndroid Build Coastguard Worker\%include "boringssl_prefix_symbols_nasm.inc"
289*8fb009dcSAndroid Build Coastguard Worker\%endif
290*8fb009dcSAndroid Build Coastguard Worker\%ifidn __OUTPUT_FORMAT__, win32
291*8fb009dcSAndroid Build Coastguard Worker___
292*8fb009dcSAndroid Build Coastguard Worker        print @out;
293*8fb009dcSAndroid Build Coastguard Worker        print <<___ unless $masm;
294*8fb009dcSAndroid Build Coastguard Worker\%else
295*8fb009dcSAndroid Build Coastguard Worker; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
296*8fb009dcSAndroid Build Coastguard Workerret
297*8fb009dcSAndroid Build Coastguard Worker\%endif
298*8fb009dcSAndroid Build Coastguard Worker___
299*8fb009dcSAndroid Build Coastguard Worker    } else {
300*8fb009dcSAndroid Build Coastguard Worker        my $target;
301*8fb009dcSAndroid Build Coastguard Worker        if ($elf) {
302*8fb009dcSAndroid Build Coastguard Worker            $target = "defined(__ELF__)";
303*8fb009dcSAndroid Build Coastguard Worker        } elsif ($macosx) {
304*8fb009dcSAndroid Build Coastguard Worker            $target = "defined(__APPLE__)";
305*8fb009dcSAndroid Build Coastguard Worker        } else {
306*8fb009dcSAndroid Build Coastguard Worker            die "unknown target";
307*8fb009dcSAndroid Build Coastguard Worker        }
308*8fb009dcSAndroid Build Coastguard Worker
309*8fb009dcSAndroid Build Coastguard Worker        print <<___;
310*8fb009dcSAndroid Build Coastguard Worker#include <openssl/asm_base.h>
311*8fb009dcSAndroid Build Coastguard Worker
312*8fb009dcSAndroid Build Coastguard Worker#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && $target
313*8fb009dcSAndroid Build Coastguard Worker___
314*8fb009dcSAndroid Build Coastguard Worker        print @out;
315*8fb009dcSAndroid Build Coastguard Worker        print <<___;
316*8fb009dcSAndroid Build Coastguard Worker#endif  // !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && $target
317*8fb009dcSAndroid Build Coastguard Worker___
318*8fb009dcSAndroid Build Coastguard Worker    }
319*8fb009dcSAndroid Build Coastguard Worker}
320*8fb009dcSAndroid Build Coastguard Worker
321*8fb009dcSAndroid Build Coastguard Workersub ::asm_init
322*8fb009dcSAndroid Build Coastguard Worker{ my ($type,$cpu)=@_;
323*8fb009dcSAndroid Build Coastguard Worker
324*8fb009dcSAndroid Build Coastguard Worker    $i386=$cpu;
325*8fb009dcSAndroid Build Coastguard Worker
326*8fb009dcSAndroid Build Coastguard Worker    $elf=$cpp=$coff=$aout=$macosx=$win32=$mwerks=$android=0;
327*8fb009dcSAndroid Build Coastguard Worker    if    (($type eq "elf"))
328*8fb009dcSAndroid Build Coastguard Worker    {	$elf=1;			require "x86gas.pl";	}
329*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "elf-1"))
330*8fb009dcSAndroid Build Coastguard Worker    {	$elf=-1;		require "x86gas.pl";	}
331*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "a\.out"))
332*8fb009dcSAndroid Build Coastguard Worker    {	$aout=1;		require "x86gas.pl";	}
333*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "coff" or $type eq "gaswin"))
334*8fb009dcSAndroid Build Coastguard Worker    {	$coff=1;		require "x86gas.pl";	}
335*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "win32n"))
336*8fb009dcSAndroid Build Coastguard Worker    {	$win32=1;		require "x86nasm.pl";	}
337*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "win32"))
338*8fb009dcSAndroid Build Coastguard Worker    {	$win32=1; $masm=1;	require "x86masm.pl";	}
339*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "macosx"))
340*8fb009dcSAndroid Build Coastguard Worker    {	$aout=1; $macosx=1;	require "x86gas.pl";	}
341*8fb009dcSAndroid Build Coastguard Worker    elsif (($type eq "android"))
342*8fb009dcSAndroid Build Coastguard Worker    {	$elf=1; $android=1;	require "x86gas.pl";	}
343*8fb009dcSAndroid Build Coastguard Worker    else
344*8fb009dcSAndroid Build Coastguard Worker    {	print STDERR <<"EOF";
345*8fb009dcSAndroid Build Coastguard WorkerPick one target type from
346*8fb009dcSAndroid Build Coastguard Worker	elf	- Linux, FreeBSD, Solaris x86, etc.
347*8fb009dcSAndroid Build Coastguard Worker	a.out	- DJGPP, elder OpenBSD, etc.
348*8fb009dcSAndroid Build Coastguard Worker	coff	- GAS/COFF such as Win32 targets
349*8fb009dcSAndroid Build Coastguard Worker	win32n	- Windows 95/Windows NT NASM format
350*8fb009dcSAndroid Build Coastguard Worker	macosx	- Mac OS X
351*8fb009dcSAndroid Build Coastguard WorkerEOF
352*8fb009dcSAndroid Build Coastguard Worker	exit(1);
353*8fb009dcSAndroid Build Coastguard Worker    }
354*8fb009dcSAndroid Build Coastguard Worker
355*8fb009dcSAndroid Build Coastguard Worker    $pic=0;
356*8fb009dcSAndroid Build Coastguard Worker    for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
357*8fb009dcSAndroid Build Coastguard Worker
358*8fb009dcSAndroid Build Coastguard Worker    &file();
359*8fb009dcSAndroid Build Coastguard Worker}
360*8fb009dcSAndroid Build Coastguard Worker
361*8fb009dcSAndroid Build Coastguard Workersub ::hidden {}
362*8fb009dcSAndroid Build Coastguard Worker
363*8fb009dcSAndroid Build Coastguard Worker1;
364