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# 20print "@ This file was created from a .asm file\n"; 21print "@ using the ads2gas_apple.pl script.\n\n"; 22print "\t.set WIDE_REFERENCE, 0\n"; 23print "\t.set ARCHITECTURE, 5\n"; 24print "\t.set DO1STROUNDING, 0\n"; 25 26my %register_aliases; 27my %macro_aliases; 28 29my @mapping_list = ("\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7", "\$8", "\$9"); 30 31my @incoming_array; 32 33# Perl trim function to remove whitespace from the start and end of the string 34sub trim($) 35{ 36 my $string = shift; 37 $string =~ s/^\s+//; 38 $string =~ s/\s+$//; 39 return $string; 40} 41 42while (<STDIN>) 43{ 44 # Comment character 45 s/;/@/g; 46 47 # Hexadecimal constants prefaced by 0x 48 s/#&/#0x/g; 49 50 # Convert :OR: to | 51 s/:OR:/ | /g; 52 53 # Convert :AND: to & 54 s/:AND:/ & /g; 55 56 # Convert :NOT: to ~ 57 s/:NOT:/ ~ /g; 58 59 # Convert :SHL: to << 60 s/:SHL:/ << /g; 61 62 # Convert :SHR: to >> 63 s/:SHR:/ >> /g; 64 65 # Convert ELSE to .else 66 s/ELSE/.else/g; 67 68 # Convert ENDIF to .endif 69 s/ENDIF/.endif/g; 70 71 # Convert ELSEIF to .elseif 72 s/ELSEIF/.elseif/g; 73 74 # Convert LTORG to .ltorg 75 s/LTORG/.ltorg/g; 76 77 # Convert IF :DEF:to .if 78 # gcc doesn't have the ability to do a conditional 79 # if defined variable that is set by IF :DEF: on 80 # armasm, so convert it to a normal .if and then 81 # make sure to define a value elesewhere 82 if (s/\bIF :DEF:\b/.if /g) 83 { 84 s/=/==/g; 85 } 86 87 # Convert IF to .if 88 if (s/\bIF\b/.if/g) 89 { 90 s/=/==/g; 91 } 92 93 # Convert INCLUDE to .INCLUDE "file" 94 s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/; 95 96 # Code directive (ARM vs Thumb) 97 s/CODE([0-9][0-9])/.code $1/; 98 99 # No AREA required 100 s/^\s*AREA.*$/.text/; 101 102 # DCD to .word 103 # This one is for incoming symbols 104 s/DCD\s+\|(\w*)\|/.long $1/; 105 106 # DCW to .short 107 s/DCW\s+\|(\w*)\|/.short $1/; 108 s/DCW(.*)/.short $1/; 109 110 # Constants defined in scope 111 s/DCD(.*)/.long $1/; 112 s/DCB(.*)/.byte $1/; 113 114 # Build a hash of all the register - alias pairs. 115 if (s/(.*)RN(.*)/$1 .req $2/g) 116 { 117 $register_aliases{trim($1)} = trim($2); 118 next; 119 } 120 121 while (($key, $value) = each(%register_aliases)) 122 { 123 s/\b$key\b/$value/g; 124 } 125 126 # Make function visible to linker, and make additional symbol with 127 # prepended underscore 128 s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/; 129 s/IMPORT\s+\|([\$\w]*)\|/.globl $1/; 130 131 # No vertical bars required; make additional symbol with prepended 132 # underscore 133 s/^\|(\$?\w+)\|/_$1\n\t$1:/g; 134 135 # Labels need trailing colon 136# s/^(\w+)/$1:/ if !/EQU/; 137 # put the colon at the end of the line in the macro 138 s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/; 139 140 # Strip ALIGN 141 s/\sALIGN/@ ALIGN/g; 142 143 # Strip ARM 144 s/\sARM/@ ARM/g; 145 146 # Strip REQUIRE8 147 #s/\sREQUIRE8/@ REQUIRE8/g; 148 s/\sREQUIRE8/@ /g; 149 150 # Strip PRESERVE8 151 s/\sPRESERVE8/@ PRESERVE8/g; 152 153 # Strip PROC and ENDPROC 154 s/PROC/@/g; 155 s/ENDP/@/g; 156 157 # EQU directive 158 s/(.*)EQU(.*)/.set $1, $2/; 159 160 # Begin macro definition 161 if (/MACRO/) 162 { 163 # Process next line down, which will be the macro definition 164 $_ = <STDIN>; 165 166 $trimmed = trim($_); 167 168 # remove commas that are separating list 169 $trimmed =~ s/,//g; 170 171 # string to array 172 @incoming_array = split(/ /, $trimmed); 173 174 print ".macro @incoming_array[0]\n"; 175 176 # remove the first element, as that is the name of the macro 177 shift (@incoming_array); 178 179 @macro_aliases{@incoming_array} = @mapping_list; 180 181 next; 182 } 183 184 while (($key, $value) = each(%macro_aliases)) 185 { 186 $key =~ s/\$/\\\$/; 187 s/$key\b/$value/g; 188 } 189 190 # For macros, use \ to reference formal params 191# s/\$/\\/g; # End macro definition 192 s/MEND/.endm/; # No need to tell it where to stop assembling 193 next if /^\s*END\s*$/; 194 print; 195} 196