xref: /aosp_15_r20/external/boringssl/src/crypto/perlasm/arm-xlate.pl (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker#! /usr/bin/env perl
2*8fb009dcSAndroid Build Coastguard Worker# Copyright 2015-2016 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 Workeruse strict;
10*8fb009dcSAndroid Build Coastguard Worker
11*8fb009dcSAndroid Build Coastguard Workermy $flavour = shift;
12*8fb009dcSAndroid Build Coastguard Workermy $output = shift;
13*8fb009dcSAndroid Build Coastguard Workeropen STDOUT,">$output" || die "can't open $output: $!";
14*8fb009dcSAndroid Build Coastguard Worker
15*8fb009dcSAndroid Build Coastguard Worker$flavour = "linux32" if (!$flavour or $flavour eq "void");
16*8fb009dcSAndroid Build Coastguard Worker
17*8fb009dcSAndroid Build Coastguard Workermy %GLOBALS;
18*8fb009dcSAndroid Build Coastguard Workermy $dotinlocallabels=($flavour=~/linux/)?1:0;
19*8fb009dcSAndroid Build Coastguard Worker
20*8fb009dcSAndroid Build Coastguard Worker################################################################
21*8fb009dcSAndroid Build Coastguard Worker# directives which need special treatment on different platforms
22*8fb009dcSAndroid Build Coastguard Worker################################################################
23*8fb009dcSAndroid Build Coastguard Workermy $arch = sub {
24*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /linux/)	{ ".arch\t".join(',',@_); }
25*8fb009dcSAndroid Build Coastguard Worker    elsif ($flavour =~ /win64/) { ".arch\t".join(',',@_); }
26*8fb009dcSAndroid Build Coastguard Worker    else			{ ""; }
27*8fb009dcSAndroid Build Coastguard Worker};
28*8fb009dcSAndroid Build Coastguard Workermy $fpu = sub {
29*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /linux/)	{ ".fpu\t".join(',',@_); }
30*8fb009dcSAndroid Build Coastguard Worker    else			{ ""; }
31*8fb009dcSAndroid Build Coastguard Worker};
32*8fb009dcSAndroid Build Coastguard Workermy $hidden = sub {
33*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /ios/)	{ ".private_extern\t".join(',',@_); }
34*8fb009dcSAndroid Build Coastguard Worker    elsif ($flavour =~ /win64/) { ""; }
35*8fb009dcSAndroid Build Coastguard Worker    else			{ ".hidden\t".join(',',@_); }
36*8fb009dcSAndroid Build Coastguard Worker};
37*8fb009dcSAndroid Build Coastguard Workermy $comm = sub {
38*8fb009dcSAndroid Build Coastguard Worker    my @args = split(/,\s*/,shift);
39*8fb009dcSAndroid Build Coastguard Worker    my $name = @args[0];
40*8fb009dcSAndroid Build Coastguard Worker    my $global = \$GLOBALS{$name};
41*8fb009dcSAndroid Build Coastguard Worker    my $ret;
42*8fb009dcSAndroid Build Coastguard Worker
43*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /ios32/)	{
44*8fb009dcSAndroid Build Coastguard Worker	$ret = ".comm\t_$name,@args[1]\n";
45*8fb009dcSAndroid Build Coastguard Worker	$ret .= ".non_lazy_symbol_pointer\n";
46*8fb009dcSAndroid Build Coastguard Worker	$ret .= "$name:\n";
47*8fb009dcSAndroid Build Coastguard Worker	$ret .= ".indirect_symbol\t_$name\n";
48*8fb009dcSAndroid Build Coastguard Worker	$ret .= ".long\t0";
49*8fb009dcSAndroid Build Coastguard Worker	$name = "_$name";
50*8fb009dcSAndroid Build Coastguard Worker    } else			{ $ret = ".comm\t".join(',',@args); }
51*8fb009dcSAndroid Build Coastguard Worker
52*8fb009dcSAndroid Build Coastguard Worker    $$global = $name;
53*8fb009dcSAndroid Build Coastguard Worker    $ret;
54*8fb009dcSAndroid Build Coastguard Worker};
55*8fb009dcSAndroid Build Coastguard Workermy $globl = sub {
56*8fb009dcSAndroid Build Coastguard Worker    my $name = shift;
57*8fb009dcSAndroid Build Coastguard Worker    my $global = \$GLOBALS{$name};
58*8fb009dcSAndroid Build Coastguard Worker    my $ret;
59*8fb009dcSAndroid Build Coastguard Worker
60*8fb009dcSAndroid Build Coastguard Worker    SWITCH: for ($flavour) {
61*8fb009dcSAndroid Build Coastguard Worker	/ios/		&& do { $name = "_$name";
62*8fb009dcSAndroid Build Coastguard Worker				last;
63*8fb009dcSAndroid Build Coastguard Worker			      };
64*8fb009dcSAndroid Build Coastguard Worker    }
65*8fb009dcSAndroid Build Coastguard Worker
66*8fb009dcSAndroid Build Coastguard Worker    $ret = ".globl	$name\n";
67*8fb009dcSAndroid Build Coastguard Worker    # All symbols in assembly files are hidden.
68*8fb009dcSAndroid Build Coastguard Worker    $ret .= &$hidden($name);
69*8fb009dcSAndroid Build Coastguard Worker    $$global = $name;
70*8fb009dcSAndroid Build Coastguard Worker    $ret;
71*8fb009dcSAndroid Build Coastguard Worker};
72*8fb009dcSAndroid Build Coastguard Workermy $global = $globl;
73*8fb009dcSAndroid Build Coastguard Workermy $extern = sub {
74*8fb009dcSAndroid Build Coastguard Worker    &$globl(@_);
75*8fb009dcSAndroid Build Coastguard Worker    return;	# return nothing
76*8fb009dcSAndroid Build Coastguard Worker};
77*8fb009dcSAndroid Build Coastguard Workermy $type = sub {
78*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /linux/)	{ ".type\t".join(',',@_); }
79*8fb009dcSAndroid Build Coastguard Worker    elsif ($flavour =~ /ios32/)	{ if (join(',',@_) =~ /(\w+),%function/) {
80*8fb009dcSAndroid Build Coastguard Worker					"#ifdef __thumb2__\n".
81*8fb009dcSAndroid Build Coastguard Worker					".thumb_func	$1\n".
82*8fb009dcSAndroid Build Coastguard Worker					"#endif";
83*8fb009dcSAndroid Build Coastguard Worker				  }
84*8fb009dcSAndroid Build Coastguard Worker			        }
85*8fb009dcSAndroid Build Coastguard Worker    elsif ($flavour =~ /win64/) { if (join(',',@_) =~ /(\w+),%function/) {
86*8fb009dcSAndroid Build Coastguard Worker                # See https://sourceware.org/binutils/docs/as/Pseudo-Ops.html
87*8fb009dcSAndroid Build Coastguard Worker                # Per https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#coff-symbol-table,
88*8fb009dcSAndroid Build Coastguard Worker                # the type for functions is 0x20, or 32.
89*8fb009dcSAndroid Build Coastguard Worker                ".def $1\n".
90*8fb009dcSAndroid Build Coastguard Worker                "   .type 32\n".
91*8fb009dcSAndroid Build Coastguard Worker                ".endef";
92*8fb009dcSAndroid Build Coastguard Worker            }
93*8fb009dcSAndroid Build Coastguard Worker        }
94*8fb009dcSAndroid Build Coastguard Worker    else			{ ""; }
95*8fb009dcSAndroid Build Coastguard Worker};
96*8fb009dcSAndroid Build Coastguard Workermy $size = sub {
97*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /linux/)	{ ".size\t".join(',',@_); }
98*8fb009dcSAndroid Build Coastguard Worker    else			{ ""; }
99*8fb009dcSAndroid Build Coastguard Worker};
100*8fb009dcSAndroid Build Coastguard Workermy $inst = sub {
101*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /linux/)    { ".inst\t".join(',',@_); }
102*8fb009dcSAndroid Build Coastguard Worker    else                        { ".long\t".join(',',@_); }
103*8fb009dcSAndroid Build Coastguard Worker};
104*8fb009dcSAndroid Build Coastguard Workermy $asciz = sub {
105*8fb009dcSAndroid Build Coastguard Worker    my $line = join(",",@_);
106*8fb009dcSAndroid Build Coastguard Worker    if ($line =~ /^"(.*)"$/)
107*8fb009dcSAndroid Build Coastguard Worker    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
108*8fb009dcSAndroid Build Coastguard Worker    else
109*8fb009dcSAndroid Build Coastguard Worker    {	"";	}
110*8fb009dcSAndroid Build Coastguard Worker};
111*8fb009dcSAndroid Build Coastguard Workermy $section = sub {
112*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /ios/) {
113*8fb009dcSAndroid Build Coastguard Worker        if ($_[0] eq ".rodata") {
114*8fb009dcSAndroid Build Coastguard Worker            return ".section\t__TEXT,__const";
115*8fb009dcSAndroid Build Coastguard Worker        }
116*8fb009dcSAndroid Build Coastguard Worker        die "Unknown section name $_[0]";
117*8fb009dcSAndroid Build Coastguard Worker    } else {
118*8fb009dcSAndroid Build Coastguard Worker        return ".section\t" . join(",", @_);
119*8fb009dcSAndroid Build Coastguard Worker    }
120*8fb009dcSAndroid Build Coastguard Worker};
121*8fb009dcSAndroid Build Coastguard Worker
122*8fb009dcSAndroid Build Coastguard Workersub range {
123*8fb009dcSAndroid Build Coastguard Worker  my ($r,$sfx,$start,$end) = @_;
124*8fb009dcSAndroid Build Coastguard Worker
125*8fb009dcSAndroid Build Coastguard Worker    join(",",map("$r$_$sfx",($start..$end)));
126*8fb009dcSAndroid Build Coastguard Worker}
127*8fb009dcSAndroid Build Coastguard Worker
128*8fb009dcSAndroid Build Coastguard Workersub expand_line {
129*8fb009dcSAndroid Build Coastguard Worker  my $line = shift;
130*8fb009dcSAndroid Build Coastguard Worker  my @ret = ();
131*8fb009dcSAndroid Build Coastguard Worker
132*8fb009dcSAndroid Build Coastguard Worker    pos($line)=0;
133*8fb009dcSAndroid Build Coastguard Worker
134*8fb009dcSAndroid Build Coastguard Worker    while ($line =~ m/\G[^@\/\{\"]*/g) {
135*8fb009dcSAndroid Build Coastguard Worker	if ($line =~ m/\G(@|\/\/|$)/gc) {
136*8fb009dcSAndroid Build Coastguard Worker	    last;
137*8fb009dcSAndroid Build Coastguard Worker	}
138*8fb009dcSAndroid Build Coastguard Worker	elsif ($line =~ m/\G\{/gc) {
139*8fb009dcSAndroid Build Coastguard Worker	    my $saved_pos = pos($line);
140*8fb009dcSAndroid Build Coastguard Worker	    $line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
141*8fb009dcSAndroid Build Coastguard Worker	    pos($line) = $saved_pos;
142*8fb009dcSAndroid Build Coastguard Worker	    $line =~ m/\G[^\}]*\}/g;
143*8fb009dcSAndroid Build Coastguard Worker	}
144*8fb009dcSAndroid Build Coastguard Worker	elsif ($line =~ m/\G\"/gc) {
145*8fb009dcSAndroid Build Coastguard Worker	    $line =~ m/\G[^\"]*\"/g;
146*8fb009dcSAndroid Build Coastguard Worker	}
147*8fb009dcSAndroid Build Coastguard Worker    }
148*8fb009dcSAndroid Build Coastguard Worker
149*8fb009dcSAndroid Build Coastguard Worker    $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
150*8fb009dcSAndroid Build Coastguard Worker
151*8fb009dcSAndroid Build Coastguard Worker    return $line;
152*8fb009dcSAndroid Build Coastguard Worker}
153*8fb009dcSAndroid Build Coastguard Worker
154*8fb009dcSAndroid Build Coastguard Workermy ($arch_defines, $target_defines);
155*8fb009dcSAndroid Build Coastguard Workerif ($flavour =~ /32/) {
156*8fb009dcSAndroid Build Coastguard Worker    $arch_defines = "defined(OPENSSL_ARM)";
157*8fb009dcSAndroid Build Coastguard Worker} elsif ($flavour =~ /64/) {
158*8fb009dcSAndroid Build Coastguard Worker    $arch_defines = "defined(OPENSSL_AARCH64)";
159*8fb009dcSAndroid Build Coastguard Worker} else {
160*8fb009dcSAndroid Build Coastguard Worker    die "unknown architecture: $flavour";
161*8fb009dcSAndroid Build Coastguard Worker}
162*8fb009dcSAndroid Build Coastguard Workerif ($flavour =~ /linux/) {
163*8fb009dcSAndroid Build Coastguard Worker    # Although the flavour is specified as "linux", it is really used by all
164*8fb009dcSAndroid Build Coastguard Worker    # ELF platforms.
165*8fb009dcSAndroid Build Coastguard Worker    $target_defines = "defined(__ELF__)";
166*8fb009dcSAndroid Build Coastguard Worker} elsif ($flavour =~ /ios/) {
167*8fb009dcSAndroid Build Coastguard Worker    # Although the flavour is specified as "ios", it is really used by all Apple
168*8fb009dcSAndroid Build Coastguard Worker    # platforms.
169*8fb009dcSAndroid Build Coastguard Worker    $target_defines = "defined(__APPLE__)";
170*8fb009dcSAndroid Build Coastguard Worker} elsif ($flavour =~ /win/) {
171*8fb009dcSAndroid Build Coastguard Worker    $target_defines = "defined(_WIN32)";
172*8fb009dcSAndroid Build Coastguard Worker} else {
173*8fb009dcSAndroid Build Coastguard Worker    die "unknown target: $flavour";
174*8fb009dcSAndroid Build Coastguard Worker}
175*8fb009dcSAndroid Build Coastguard Worker
176*8fb009dcSAndroid Build Coastguard Workerprint <<___;
177*8fb009dcSAndroid Build Coastguard Worker// This file is generated from a similarly-named Perl script in the BoringSSL
178*8fb009dcSAndroid Build Coastguard Worker// source tree. Do not edit by hand.
179*8fb009dcSAndroid Build Coastguard Worker
180*8fb009dcSAndroid Build Coastguard Worker#include <openssl/asm_base.h>
181*8fb009dcSAndroid Build Coastguard Worker
182*8fb009dcSAndroid Build Coastguard Worker#if !defined(OPENSSL_NO_ASM) && $arch_defines && $target_defines
183*8fb009dcSAndroid Build Coastguard Worker___
184*8fb009dcSAndroid Build Coastguard Worker
185*8fb009dcSAndroid Build Coastguard Workerwhile(my $line=<>) {
186*8fb009dcSAndroid Build Coastguard Worker
187*8fb009dcSAndroid Build Coastguard Worker    if ($line =~ m/^\s*(#|@|\/\/)/)	{ print $line; next; }
188*8fb009dcSAndroid Build Coastguard Worker
189*8fb009dcSAndroid Build Coastguard Worker    $line =~ s|/\*.*\*/||;	# get rid of C-style comments...
190*8fb009dcSAndroid Build Coastguard Worker    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
191*8fb009dcSAndroid Build Coastguard Worker    $line =~ s|\s+$||;		# ... and at the end
192*8fb009dcSAndroid Build Coastguard Worker
193*8fb009dcSAndroid Build Coastguard Worker    if ($flavour =~ /64/) {
194*8fb009dcSAndroid Build Coastguard Worker	my $copy = $line;
195*8fb009dcSAndroid Build Coastguard Worker	# Also remove line comments.
196*8fb009dcSAndroid Build Coastguard Worker	$copy =~ s|//.*||;
197*8fb009dcSAndroid Build Coastguard Worker	if ($copy =~ /\b[wx]18\b/) {
198*8fb009dcSAndroid Build Coastguard Worker	    die "r18 is reserved by the platform and may not be used.";
199*8fb009dcSAndroid Build Coastguard Worker	}
200*8fb009dcSAndroid Build Coastguard Worker    }
201*8fb009dcSAndroid Build Coastguard Worker
202*8fb009dcSAndroid Build Coastguard Worker    {
203*8fb009dcSAndroid Build Coastguard Worker	$line =~ s|[\b\.]L(\w{2,})|L$1|g;	# common denominator for Locallabel
204*8fb009dcSAndroid Build Coastguard Worker	$line =~ s|\bL(\w{2,})|\.L$1|g	if ($dotinlocallabels);
205*8fb009dcSAndroid Build Coastguard Worker    }
206*8fb009dcSAndroid Build Coastguard Worker
207*8fb009dcSAndroid Build Coastguard Worker    {
208*8fb009dcSAndroid Build Coastguard Worker	$line =~ s|(^[\.\w]+)\:\s*||;
209*8fb009dcSAndroid Build Coastguard Worker	my $label = $1;
210*8fb009dcSAndroid Build Coastguard Worker	if ($label) {
211*8fb009dcSAndroid Build Coastguard Worker	    printf "%s:",($GLOBALS{$label} or $label);
212*8fb009dcSAndroid Build Coastguard Worker	}
213*8fb009dcSAndroid Build Coastguard Worker    }
214*8fb009dcSAndroid Build Coastguard Worker
215*8fb009dcSAndroid Build Coastguard Worker    if ($line !~ m/^[#@]/) {
216*8fb009dcSAndroid Build Coastguard Worker	$line =~ s|^\s*(\.?)(\S+)\s*||;
217*8fb009dcSAndroid Build Coastguard Worker	my $c = $1; $c = "\t" if ($c eq "");
218*8fb009dcSAndroid Build Coastguard Worker	my $mnemonic = $2;
219*8fb009dcSAndroid Build Coastguard Worker	my $opcode;
220*8fb009dcSAndroid Build Coastguard Worker	if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
221*8fb009dcSAndroid Build Coastguard Worker	    $opcode = eval("\$$1_$2");
222*8fb009dcSAndroid Build Coastguard Worker	} else {
223*8fb009dcSAndroid Build Coastguard Worker	    $opcode = eval("\$$mnemonic");
224*8fb009dcSAndroid Build Coastguard Worker	}
225*8fb009dcSAndroid Build Coastguard Worker
226*8fb009dcSAndroid Build Coastguard Worker	if ($flavour =~ /ios/) {
227*8fb009dcSAndroid Build Coastguard Worker	    # Mach-O and ELF use different syntax for these relocations. Note
228*8fb009dcSAndroid Build Coastguard Worker	    # that we require :pg_hi21: to be explicitly listed. It is normally
229*8fb009dcSAndroid Build Coastguard Worker	    # optional with adrp instructions.
230*8fb009dcSAndroid Build Coastguard Worker	    $line =~ s|:pg_hi21:(\w+)|\1\@PAGE|;
231*8fb009dcSAndroid Build Coastguard Worker	    $line =~ s|:lo12:(\w+)|\1\@PAGEOFF|;
232*8fb009dcSAndroid Build Coastguard Worker	} else {
233*8fb009dcSAndroid Build Coastguard Worker	    # Clang's integrated assembly does not support the optional
234*8fb009dcSAndroid Build Coastguard Worker	    # :pg_hi21: markers, so erase them.
235*8fb009dcSAndroid Build Coastguard Worker	    $line =~ s|:pg_hi21:||;
236*8fb009dcSAndroid Build Coastguard Worker	}
237*8fb009dcSAndroid Build Coastguard Worker
238*8fb009dcSAndroid Build Coastguard Worker	my $arg=expand_line($line);
239*8fb009dcSAndroid Build Coastguard Worker
240*8fb009dcSAndroid Build Coastguard Worker	if (ref($opcode) eq 'CODE') {
241*8fb009dcSAndroid Build Coastguard Worker		$line = &$opcode($arg);
242*8fb009dcSAndroid Build Coastguard Worker	} elsif ($mnemonic)         {
243*8fb009dcSAndroid Build Coastguard Worker		$line = $c.$mnemonic;
244*8fb009dcSAndroid Build Coastguard Worker		$line.= "\t$arg" if ($arg ne "");
245*8fb009dcSAndroid Build Coastguard Worker	}
246*8fb009dcSAndroid Build Coastguard Worker    }
247*8fb009dcSAndroid Build Coastguard Worker
248*8fb009dcSAndroid Build Coastguard Worker    print $line if ($line);
249*8fb009dcSAndroid Build Coastguard Worker    print "\n";
250*8fb009dcSAndroid Build Coastguard Worker}
251*8fb009dcSAndroid Build Coastguard Worker
252*8fb009dcSAndroid Build Coastguard Workerprint <<___;
253*8fb009dcSAndroid Build Coastguard Worker#endif  // !OPENSSL_NO_ASM && $arch_defines && $target_defines
254*8fb009dcSAndroid Build Coastguard Worker___
255*8fb009dcSAndroid Build Coastguard Worker
256*8fb009dcSAndroid Build Coastguard Workerclose STDOUT or die "error closing STDOUT: $!";
257