1#!/usr/bin/env 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 21use FindBin; 22use lib $FindBin::Bin; 23use thumb; 24 25my $thumb = 0; 26 27foreach my $arg (@ARGV) { 28 $thumb = 1 if ($arg eq "-thumb"); 29} 30 31print "@ This file was created from a .asm file\n"; 32print "@ using the ads2gas.pl script.\n"; 33print "\t.equ DO1STROUNDING, 0\n"; 34if ($thumb) { 35 print "\t.syntax unified\n"; 36 print "\t.thumb\n"; 37} 38 39# Stack of procedure names. 40@proc_stack = (); 41 42while (<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 # Make function visible to linker, and make additional symbol with 142 # prepended underscore 143 s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/; 144 s/IMPORT\s+\|([\$\w]*)\|/.global $1/; 145 146 s/EXPORT\s+([\$\w]*)/.global $1/; 147 s/export\s+([\$\w]*)/.global $1/; 148 149 # No vertical bars required; make additional symbol with prepended 150 # underscore 151 s/^\|(\$?\w+)\|/_$1\n\t$1:/g; 152 153 # Labels need trailing colon 154# s/^(\w+)/$1:/ if !/EQU/; 155 # put the colon at the end of the line in the macro 156 s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/; 157 158 # ALIGN directive 159 s/\bALIGN\b/.balign/g; 160 161 if ($thumb) { 162 # ARM code - we force everything to thumb with the declaration in the header 163 s/\sARM//g; 164 } else { 165 # ARM code 166 s/\sARM/.arm/g; 167 } 168 169 # push/pop 170 s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; 171 s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g; 172 173 # NEON code 174 s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g; 175 s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g; 176 177 if ($thumb) { 178 thumb::FixThumbInstructions($_, 0); 179 } 180 181 # eabi_attributes numerical equivalents can be found in the 182 # "ARM IHI 0045C" document. 183 184 # REQUIRE8 Stack is required to be 8-byte aligned 185 s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g; 186 187 # PRESERVE8 Stack 8-byte align is preserved 188 s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g; 189 190 # Use PROC and ENDP to give the symbols a .size directive. 191 # This makes them show up properly in debugging tools like gdb and valgrind. 192 if (/\bPROC\b/) 193 { 194 my $proc; 195 /^_([\.0-9A-Z_a-z]\w+)\b/; 196 $proc = $1; 197 push(@proc_stack, $proc) if ($proc); 198 s/\bPROC\b/@ $&/; 199 } 200 if (/\bENDP\b/) 201 { 202 my $proc; 203 s/\bENDP\b/@ $&/; 204 $proc = pop(@proc_stack); 205 $_ = "\t.size $proc, .-$proc".$_ if ($proc); 206 } 207 208 # EQU directive 209 s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/; 210 211 # Begin macro definition 212 if (/\bMACRO\b/) { 213 $_ = <STDIN>; 214 s/^/.macro/; 215 s/\$//g; # remove formal param reference 216 s/;/@/g; # change comment characters 217 } 218 219 # For macros, use \ to reference formal params 220 s/\$/\\/g; # End macro definition 221 s/\bMEND\b/.endm/; # No need to tell it where to stop assembling 222 next if /^\s*END\s*$/; 223 print; 224 print "$comment_sub$comment\n" if defined $comment; 225} 226 227# Mark that this object doesn't need an executable stack. 228printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n"); 229