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#
20print "@ This file was created from a .asm file\n";
21print "@  using the ads2gas.pl script.\n";
22print "\t.equ DO1STROUNDING, 0\n";
23
24while (<STDIN>)
25{
26    # Comment character
27    s/;/@/g;
28
29    # Hexadecimal constants prefaced by 0x
30    s/#&/#0x/g;
31
32    # Convert :OR: to |
33    s/:OR:/ | /g;
34
35    # Convert :AND: to &
36    s/:AND:/ & /g;
37
38    # Convert :NOT: to ~
39    s/:NOT:/ ~ /g;
40
41    # Convert :SHL: to <<
42    s/:SHL:/ << /g;
43
44    # Convert :SHR: to >>
45    s/:SHR:/ >> /g;
46
47    # Convert ELSE to .else
48    s/ELSE/.else/g;
49
50    # Convert ENDIF to .endif
51    s/ENDIF/.endif/g;
52
53    # Convert ELSEIF to .elseif
54    s/ELSEIF/.elseif/g;
55
56    # Convert LTORG to .ltorg
57    s/LTORG/.ltorg/g;
58
59    # Convert IF :DEF:to .if
60    # gcc doesn't have the ability to do a conditional
61    # if defined variable that is set by IF :DEF: on
62    # armasm, so convert it to a normal .if and then
63    # make sure to define a value elesewhere
64    if (s/\bIF :DEF:\b/.if /g)
65    {
66        s/=/==/g;
67    }
68
69    # Convert IF to .if
70    if (s/\bIF\b/.if/g)
71    {
72        s/=+/==/g;
73    }
74
75    # Convert INCLUDE to .INCLUDE "file"
76    s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
77
78    # Code directive (ARM vs Thumb)
79    s/CODE([0-9][0-9])/.code $1/;
80
81    # No AREA required
82    s/^\s*AREA.*$/.text/;
83
84    # DCD to .word
85    # This one is for incoming symbols
86    s/DCD\s+\|(\w*)\|/.long $1/;
87
88    # DCW to .short
89    s/DCW\s+\|(\w*)\|/.short $1/;
90    s/DCW(.*)/.short $1/;
91
92    # Constants defined in scope
93    s/DCD(.*)/.long $1/;
94    s/DCB(.*)/.byte $1/;
95
96    # RN to .req
97    if (s/RN\s+([Rr]\d+|lr)/.req $1/)
98    {
99        print;
100        next;
101    }
102
103    # Make function visible to linker, and make additional symbol with
104    # prepended underscore
105    s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
106    s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
107
108    # No vertical bars required; make additional symbol with prepended
109    # underscore
110    s/^\|(\$?\w+)\|/_$1\n\t$1:/g;
111
112    # Labels need trailing colon
113#   s/^(\w+)/$1:/ if !/EQU/;
114    # put the colon at the end of the line in the macro
115    s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
116
117    # Strip ALIGN
118    s/\sALIGN/@ ALIGN/g;
119
120    # Strip ARM
121    s/\sARM/@ ARM/g;
122
123    # Strip REQUIRE8
124    #s/\sREQUIRE8/@ REQUIRE8/g;
125    s/\sREQUIRE8/@ /g;      #EQU cause problem
126
127    # Strip PRESERVE8
128    s/\sPRESERVE8/@ PRESERVE8/g;
129
130    # Strip PROC and ENDPROC
131    s/\sPROC/@/g;
132    s/\sENDP/@/g;
133
134    # EQU directive
135    s/(.*)EQU(.*)/.equ $1, $2/;
136
137    # Begin macro definition
138    if (/MACRO/) {
139        $_ = <STDIN>;
140        s/^/.macro/;
141        s/\$//g;                # remove formal param reference
142        s/;/@/g;                # change comment characters
143    }
144
145    # For macros, use \ to reference formal params
146    s/\$/\\/g;                  # End macro definition
147    s/MEND/.endm/;              # No need to tell it where to stop assembling
148    next if /^\s*END\s*$/;
149    print;
150}
151