Martin Storsjo | 95eae0c | 2014-02-05 11:17:04 +0200 | [diff] [blame] | 1 | #!/usr/bin/env perl |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | ## Copyright (c) 2016, Alliance for Open Media. All rights reserved |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 3 | ## |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 4 | ## 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 Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 | # |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 20 | |
Martin Storsjo | 5f76080 | 2013-05-15 16:08:19 +0300 | [diff] [blame] | 21 | use FindBin; |
| 22 | use lib $FindBin::Bin; |
| 23 | use thumb; |
| 24 | |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 25 | my $thumb = 0; |
| 26 | |
| 27 | foreach my $arg (@ARGV) { |
Martin Storsjo | 7097781 | 2013-05-15 20:54:20 +0300 | [diff] [blame] | 28 | $thumb = 1 if ($arg eq "-thumb"); |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 29 | } |
| 30 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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"; |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 34 | if ($thumb) { |
| 35 | print "\t.syntax unified\n"; |
| 36 | print "\t.thumb\n"; |
| 37 | } |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 38 | |
Timothy B. Terriberry | 1647f00 | 2011-07-19 12:13:18 -0700 | [diff] [blame] | 39 | # Stack of procedure names. |
| 40 | @proc_stack = (); |
| 41 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 42 | while (<STDIN>) |
| 43 | { |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 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 | |
Tero Rintaluoma | 33fa7c4 | 2011-04-11 12:04:17 +0300 | [diff] [blame] | 57 | # Load and store alignment |
| 58 | s/@/,:/g; |
| 59 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 79 | s/\bELSE\b/.else/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 80 | |
| 81 | # Convert ENDIF to .endif |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 82 | s/\bENDIF\b/.endif/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 83 | |
| 84 | # Convert ELSEIF to .elseif |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 85 | s/\bELSEIF\b/.elseif/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 86 | |
| 87 | # Convert LTORG to .ltorg |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 88 | s/\bLTORG\b/.ltorg/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 89 | |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 90 | # Convert endfunc to nothing. |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 91 | s/\bendfunc\b//ig; |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 92 | |
| 93 | # Convert FUNCTION to nothing. |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 94 | s/\bFUNCTION\b//g; |
| 95 | s/\bfunction\b//g; |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 96 | |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 97 | s/\bENTRY\b//g; |
| 98 | s/\bMSARMASM\b/0/g; |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 99 | s/^\s+end\s+$//g; |
| 100 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Johann | 2007c3b | 2011-06-27 11:38:26 -0400 | [diff] [blame] | 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/; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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; |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 145 | print "$comment_sub$comment\n" if defined $comment; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 | |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 154 | s/EXPORT\s+([\$\w]*)/.global $1/; |
| 155 | s/export\s+([\$\w]*)/.global $1/; |
| 156 | |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 | |
Tero Rintaluoma | 33fa7c4 | 2011-04-11 12:04:17 +0300 | [diff] [blame] | 166 | # ALIGN directive |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 167 | s/\bALIGN\b/.balign/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 168 | |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 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 | } |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 176 | |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 177 | # push/pop |
| 178 | s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; |
| 179 | s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g; |
| 180 | |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 181 | # NEON code |
| 182 | s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g; |
| 183 | s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g; |
| 184 | |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 185 | if ($thumb) { |
Martin Storsjo | 6b9a7b3 | 2013-05-15 17:09:22 +0300 | [diff] [blame] | 186 | thumb::FixThumbInstructions($_, 0); |
Martin Storsjo | 644587c | 2013-05-12 02:15:45 +0300 | [diff] [blame] | 187 | } |
| 188 | |
Fritz Koenig | b73e6c8 | 2012-01-04 10:54:01 -0800 | [diff] [blame] | 189 | # eabi_attributes numerical equivalents can be found in the |
| 190 | # "ARM IHI 0045C" document. |
| 191 | |
Attila Nagy | c5434ab | 2011-11-18 12:28:43 +0200 | [diff] [blame] | 192 | # REQUIRE8 Stack is required to be 8-byte aligned |
Fritz Koenig | b73e6c8 | 2012-01-04 10:54:01 -0800 | [diff] [blame] | 193 | s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 194 | |
Attila Nagy | c5434ab | 2011-11-18 12:28:43 +0200 | [diff] [blame] | 195 | # PRESERVE8 Stack 8-byte align is preserved |
Fritz Koenig | b73e6c8 | 2012-01-04 10:54:01 -0800 | [diff] [blame] | 196 | s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 197 | |
Timothy B. Terriberry | 1647f00 | 2011-07-19 12:13:18 -0700 | [diff] [blame] | 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 | } |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 215 | |
| 216 | # EQU directive |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 217 | s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 218 | |
| 219 | # Begin macro definition |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 220 | if (/\bMACRO\b/) { |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 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 |
Ahmad Sharif | 7ebcaeb | 2012-11-08 15:14:44 -0800 | [diff] [blame] | 229 | s/\bMEND\b/.endm/; # No need to tell it where to stop assembling |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 230 | next if /^\s*END\s*$/; |
| 231 | print; |
Ahmad Sharif | b0e1c5f | 2012-11-01 13:01:14 -0700 | [diff] [blame] | 232 | print "$comment_sub$comment\n" if defined $comment; |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 233 | } |
Timothy B. Terriberry | 0453aca | 2011-07-19 13:09:22 -0700 | [diff] [blame] | 234 | |
| 235 | # Mark that this object doesn't need an executable stack. |
| 236 | printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n"); |