|
1 #!/usr/bin/perl |
|
2 ## |
|
3 ## Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
|
4 ## |
|
5 ## Use of this source code is governed by a BSD-style license |
|
6 ## that can be found in the LICENSE file in the root of the source |
|
7 ## tree. An additional intellectual property rights grant can be found |
|
8 ## in the file PATENTS. All contributing project authors may |
|
9 ## be found in the AUTHORS file in the root of the source tree. |
|
10 ## |
|
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 # |
|
20 |
|
21 use FindBin; |
|
22 use lib $FindBin::Bin; |
|
23 use thumb; |
|
24 |
|
25 my $thumb = 0; |
|
26 |
|
27 foreach my $arg (@ARGV) { |
|
28 $thumb = 1 if ($arg eq "-thumb"); |
|
29 } |
|
30 |
|
31 print "@ This file was created from a .asm file\n"; |
|
32 print "@ using the ads2gas.pl script.\n"; |
|
33 print "\t.equ DO1STROUNDING, 0\n"; |
|
34 if ($thumb) { |
|
35 print "\t.syntax unified\n"; |
|
36 print "\t.thumb\n"; |
|
37 } |
|
38 |
|
39 # Stack of procedure names. |
|
40 @proc_stack = (); |
|
41 |
|
42 while (<STDIN>) |
|
43 { |
|
44 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 |
|
57 # Load and store alignment |
|
58 s/@/,:/g; |
|
59 |
|
60 # 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 |
|
79 s/\bELSE\b/.else/g; |
|
80 |
|
81 # Convert ENDIF to .endif |
|
82 s/\bENDIF\b/.endif/g; |
|
83 |
|
84 # Convert ELSEIF to .elseif |
|
85 s/\bELSEIF\b/.elseif/g; |
|
86 |
|
87 # Convert LTORG to .ltorg |
|
88 s/\bLTORG\b/.ltorg/g; |
|
89 |
|
90 # Convert endfunc to nothing. |
|
91 s/\bendfunc\b//ig; |
|
92 |
|
93 # Convert FUNCTION to nothing. |
|
94 s/\bFUNCTION\b//g; |
|
95 s/\bfunction\b//g; |
|
96 |
|
97 s/\bENTRY\b//g; |
|
98 s/\bMSARMASM\b/0/g; |
|
99 s/^\s+end\s+$//g; |
|
100 |
|
101 # 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 |
|
124 # 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/; |
|
128 |
|
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; |
|
145 print "$comment_sub$comment\n" if defined $comment; |
|
146 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 |
|
154 s/EXPORT\s+([\$\w]*)/.global $1/; |
|
155 s/export\s+([\$\w]*)/.global $1/; |
|
156 |
|
157 # 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 |
|
166 # ALIGN directive |
|
167 s/\bALIGN\b/.balign/g; |
|
168 |
|
169 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 } |
|
176 |
|
177 # push/pop |
|
178 s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; |
|
179 s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g; |
|
180 |
|
181 # NEON code |
|
182 s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g; |
|
183 s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g; |
|
184 |
|
185 if ($thumb) { |
|
186 thumb::FixThumbInstructions($_, 0); |
|
187 } |
|
188 |
|
189 # eabi_attributes numerical equivalents can be found in the |
|
190 # "ARM IHI 0045C" document. |
|
191 |
|
192 # REQUIRE8 Stack is required to be 8-byte aligned |
|
193 s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g; |
|
194 |
|
195 # PRESERVE8 Stack 8-byte align is preserved |
|
196 s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g; |
|
197 |
|
198 # 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 } |
|
215 |
|
216 # EQU directive |
|
217 s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/; |
|
218 |
|
219 # Begin macro definition |
|
220 if (/\bMACRO\b/) { |
|
221 $_ = <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 |
|
229 s/\bMEND\b/.endm/; # No need to tell it where to stop assembling |
|
230 next if /^\s*END\s*$/; |
|
231 print; |
|
232 print "$comment_sub$comment\n" if defined $comment; |
|
233 } |
|
234 |
|
235 # Mark that this object doesn't need an executable stack. |
|
236 printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n"); |