blob: adf45a3c91b86693aeb9db3bdde7d962b8bcde89 [file] [log] [blame]
Martin Storsjo95eae0c2014-02-05 11:17:04 +02001#!/usr/bin/env perl
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002## Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszar0ea50ce2010-05-18 11:58:33 -04003##
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004## This source code is subject to the terms of the BSD 2 Clause License and
5## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6## was not distributed with this source code in the LICENSE file, you can
7## obtain it at www.aomedia.org/license/software. If the Alliance for Open
8## Media Patent License 1.0 was not distributed with this source code in the
9## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
John Koleszar0ea50ce2010-05-18 11:58:33 -040010##
11
12
13# ads2gas.pl
14# Author: Eric Fung (efung (at) acm.org)
15#
16# Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format
17#
18# Usage: cat inputfile | perl ads2gas.pl > outputfile
19#
Martin Storsjo644587c2013-05-12 02:15:45 +030020
Martin Storsjo5f760802013-05-15 16:08:19 +030021use FindBin;
22use lib $FindBin::Bin;
23use thumb;
24
Martin Storsjo644587c2013-05-12 02:15:45 +030025my $thumb = 0;
26
27foreach my $arg (@ARGV) {
Martin Storsjo70977812013-05-15 20:54:20 +030028 $thumb = 1 if ($arg eq "-thumb");
Martin Storsjo644587c2013-05-12 02:15:45 +030029}
30
John Koleszar0ea50ce2010-05-18 11:58:33 -040031print "@ This file was created from a .asm file\n";
32print "@ using the ads2gas.pl script.\n";
33print "\t.equ DO1STROUNDING, 0\n";
Martin Storsjo644587c2013-05-12 02:15:45 +030034if ($thumb) {
35 print "\t.syntax unified\n";
36 print "\t.thumb\n";
37}
John Koleszar0ea50ce2010-05-18 11:58:33 -040038
Timothy B. Terriberry1647f002011-07-19 12:13:18 -070039# Stack of procedure names.
40@proc_stack = ();
41
John Koleszar0ea50ce2010-05-18 11:58:33 -040042while (<STDIN>)
43{
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -070044 undef $comment;
45 undef $line;
46 $comment_char = ";";
47 $comment_sub = "@";
48
49 # Handle comments.
50 if (/$comment_char/)
51 {
52 $comment = "";
53 ($line, $comment) = /(.*?)$comment_char(.*)/;
54 $_ = $line;
55 }
56
Tero Rintaluoma33fa7c42011-04-11 12:04:17 +030057 # Load and store alignment
58 s/@/,:/g;
59
John Koleszar0ea50ce2010-05-18 11:58:33 -040060 # Hexadecimal constants prefaced by 0x
61 s/#&/#0x/g;
62
63 # Convert :OR: to |
64 s/:OR:/ | /g;
65
66 # Convert :AND: to &
67 s/:AND:/ & /g;
68
69 # Convert :NOT: to ~
70 s/:NOT:/ ~ /g;
71
72 # Convert :SHL: to <<
73 s/:SHL:/ << /g;
74
75 # Convert :SHR: to >>
76 s/:SHR:/ >> /g;
77
78 # Convert ELSE to .else
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080079 s/\bELSE\b/.else/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -040080
81 # Convert ENDIF to .endif
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080082 s/\bENDIF\b/.endif/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -040083
84 # Convert ELSEIF to .elseif
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080085 s/\bELSEIF\b/.elseif/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -040086
87 # Convert LTORG to .ltorg
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080088 s/\bLTORG\b/.ltorg/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -040089
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -070090 # Convert endfunc to nothing.
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080091 s/\bendfunc\b//ig;
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -070092
93 # Convert FUNCTION to nothing.
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080094 s/\bFUNCTION\b//g;
95 s/\bfunction\b//g;
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -070096
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -080097 s/\bENTRY\b//g;
98 s/\bMSARMASM\b/0/g;
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -070099 s/^\s+end\s+$//g;
100
John Koleszar0ea50ce2010-05-18 11:58:33 -0400101 # Convert IF :DEF:to .if
102 # gcc doesn't have the ability to do a conditional
103 # if defined variable that is set by IF :DEF: on
104 # armasm, so convert it to a normal .if and then
105 # make sure to define a value elesewhere
106 if (s/\bIF :DEF:\b/.if /g)
107 {
108 s/=/==/g;
109 }
110
111 # Convert IF to .if
112 if (s/\bIF\b/.if/g)
113 {
114 s/=+/==/g;
115 }
116
117 # Convert INCLUDE to .INCLUDE "file"
118 s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
119
120 # Code directive (ARM vs Thumb)
121 s/CODE([0-9][0-9])/.code $1/;
122
123 # No AREA required
Johann2007c3b2011-06-27 11:38:26 -0400124 # But ALIGNs in AREA must be obeyed
125 s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
126 # If no ALIGN, strip the AREA and align to 4 bytes
127 s/^\s*AREA.*$/.text\n.p2align 2/;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400128
129 # DCD to .word
130 # This one is for incoming symbols
131 s/DCD\s+\|(\w*)\|/.long $1/;
132
133 # DCW to .short
134 s/DCW\s+\|(\w*)\|/.short $1/;
135 s/DCW(.*)/.short $1/;
136
137 # Constants defined in scope
138 s/DCD(.*)/.long $1/;
139 s/DCB(.*)/.byte $1/;
140
141 # RN to .req
142 if (s/RN\s+([Rr]\d+|lr)/.req $1/)
143 {
144 print;
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -0700145 print "$comment_sub$comment\n" if defined $comment;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400146 next;
147 }
148
149 # Make function visible to linker, and make additional symbol with
150 # prepended underscore
151 s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
152 s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
153
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -0700154 s/EXPORT\s+([\$\w]*)/.global $1/;
155 s/export\s+([\$\w]*)/.global $1/;
156
John Koleszar0ea50ce2010-05-18 11:58:33 -0400157 # No vertical bars required; make additional symbol with prepended
158 # underscore
159 s/^\|(\$?\w+)\|/_$1\n\t$1:/g;
160
161 # Labels need trailing colon
162# s/^(\w+)/$1:/ if !/EQU/;
163 # put the colon at the end of the line in the macro
164 s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
165
Tero Rintaluoma33fa7c42011-04-11 12:04:17 +0300166 # ALIGN directive
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -0800167 s/\bALIGN\b/.balign/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400168
Martin Storsjo644587c2013-05-12 02:15:45 +0300169 if ($thumb) {
170 # ARM code - we force everything to thumb with the declaration in the header
171 s/\sARM//g;
172 } else {
173 # ARM code
174 s/\sARM/.arm/g;
175 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400176
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -0800177 # push/pop
178 s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g;
179 s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g;
180
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -0700181 # NEON code
182 s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g;
183 s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g;
184
Martin Storsjo644587c2013-05-12 02:15:45 +0300185 if ($thumb) {
Martin Storsjo6b9a7b32013-05-15 17:09:22 +0300186 thumb::FixThumbInstructions($_, 0);
Martin Storsjo644587c2013-05-12 02:15:45 +0300187 }
188
Fritz Koenigb73e6c82012-01-04 10:54:01 -0800189 # eabi_attributes numerical equivalents can be found in the
190 # "ARM IHI 0045C" document.
191
Attila Nagyc5434ab2011-11-18 12:28:43 +0200192 # REQUIRE8 Stack is required to be 8-byte aligned
Fritz Koenigb73e6c82012-01-04 10:54:01 -0800193 s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400194
Attila Nagyc5434ab2011-11-18 12:28:43 +0200195 # PRESERVE8 Stack 8-byte align is preserved
Fritz Koenigb73e6c82012-01-04 10:54:01 -0800196 s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400197
Timothy B. Terriberry1647f002011-07-19 12:13:18 -0700198 # Use PROC and ENDP to give the symbols a .size directive.
199 # This makes them show up properly in debugging tools like gdb and valgrind.
200 if (/\bPROC\b/)
201 {
202 my $proc;
203 /^_([\.0-9A-Z_a-z]\w+)\b/;
204 $proc = $1;
205 push(@proc_stack, $proc) if ($proc);
206 s/\bPROC\b/@ $&/;
207 }
208 if (/\bENDP\b/)
209 {
210 my $proc;
211 s/\bENDP\b/@ $&/;
212 $proc = pop(@proc_stack);
213 $_ = "\t.size $proc, .-$proc".$_ if ($proc);
214 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400215
216 # EQU directive
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -0700217 s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400218
219 # Begin macro definition
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -0800220 if (/\bMACRO\b/) {
John Koleszar0ea50ce2010-05-18 11:58:33 -0400221 $_ = <STDIN>;
222 s/^/.macro/;
223 s/\$//g; # remove formal param reference
224 s/;/@/g; # change comment characters
225 }
226
227 # For macros, use \ to reference formal params
228 s/\$/\\/g; # End macro definition
Ahmad Sharif7ebcaeb2012-11-08 15:14:44 -0800229 s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
John Koleszar0ea50ce2010-05-18 11:58:33 -0400230 next if /^\s*END\s*$/;
231 print;
Ahmad Sharifb0e1c5f2012-11-01 13:01:14 -0700232 print "$comment_sub$comment\n" if defined $comment;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400233}
Timothy B. Terriberry0453aca2011-07-19 13:09:22 -0700234
235# Mark that this object doesn't need an executable stack.
236printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");