• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
26my $elf = 1;
27
28foreach my $arg (@ARGV) {
29    $thumb = 1 if ($arg eq "-thumb");
30    $elf = 0 if ($arg eq "-noelf");
31}
32
33print "@ This file was created from a .asm file\n";
34print "@  using the ads2gas.pl script.\n";
35print ".syntax unified\n";
36if ($thumb) {
37    print "\t.thumb\n";
38}
39
40# Stack of procedure names.
41@proc_stack = ();
42
43while (<STDIN>)
44{
45    # Load and store alignment
46    s/@/,:/g;
47
48    # Comment character
49    s/;/@/;
50
51    # Convert ELSE to .else
52    s/\bELSE\b/.else/g;
53
54    # Convert ENDIF to .endif
55    s/\bENDIF\b/.endif/g;
56
57    # Convert IF to .if
58    if (s/\bIF\b/.if/g) {
59        s/=+/==/g;
60    }
61
62    # Convert INCLUDE to .INCLUDE "file"
63    s/INCLUDE\s?(.*)$/.include \"$1\"/;
64
65    # No AREA required
66    # But ALIGNs in AREA must be obeyed
67    s/^(\s*)\bAREA\b.*ALIGN=([0-9])$/$1.text\n$1.p2align $2/;
68    # If no ALIGN, strip the AREA and align to 4 bytes
69    s/^(\s*)\bAREA\b.*$/$1.text\n$1.p2align 2/;
70
71    # Make function visible to linker.
72    if ($elf) {
73        s/(\s*)EXPORT\s+\|([\$\w]*)\|/$1.global $2\n$1.type $2, function/;
74    } else {
75        s/(\s*)EXPORT\s+\|([\$\w]*)\|/$1.global $2/;
76    }
77
78    # No vertical bars on function names
79    s/^\|(\$?\w+)\|/$1/g;
80
81    # Labels need trailing colon
82    s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
83
84    # ALIGN directive
85    s/\bALIGN\b/.balign/g;
86
87    if ($thumb) {
88        # ARM code - we force everything to thumb with the declaration in the
89        # header
90        s/\bARM\b//g;
91    } else {
92        # ARM code
93        s/\bARM\b/.arm/g;
94    }
95
96    # push/pop
97    s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g;
98    s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g;
99
100    if ($thumb) {
101        thumb::FixThumbInstructions($_);
102    }
103
104    # eabi_attributes numerical equivalents can be found in the
105    # "ARM IHI 0045C" document.
106
107    if ($elf) {
108        # REQUIRE8 Stack is required to be 8-byte aligned
109        s/\bREQUIRE8\b/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
110
111        # PRESERVE8 Stack 8-byte align is preserved
112        s/\bPRESERVE8\b/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
113    } else {
114        s/\bREQUIRE8\b//;
115        s/\bPRESERVE8\b//;
116    }
117
118    # Use PROC and ENDP to give the symbols a .size directive.
119    # This makes them show up properly in debugging tools like gdb and valgrind.
120    if (/\bPROC\b/) {
121        my $proc;
122        # Match the function name so it can be stored in $proc
123        /^([\.0-9A-Z_a-z]\w+)\b/;
124        $proc = $1;
125        push(@proc_stack, $proc) if ($proc);
126        s/\bPROC\b/@ $&/;
127    }
128
129    if (/\bENDP\b/) {
130        my $proc;
131        s/\bENDP\b/@ $&/;
132        $proc = pop(@proc_stack);
133        $_ = ".size $proc, .-$proc".$_ if ($proc and $elf);
134    }
135
136    # EQU directive
137    s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/;
138
139    # Begin macro definition
140    if (/\bMACRO\b/) {
141        # Process next line down, which will be the macro definition
142        $_ = <STDIN>;
143        s/^/.macro/;
144        s/\$//g;             # Remove $ from the variables in the declaration
145    }
146
147    s/\$/\\/g;               # Use \ to reference formal parameters
148    # End macro definition
149
150    s/\bMEND\b/.endm/;       # No need to tell it where to stop assembling
151    next if /^\s*END\s*$/;
152    s/[ \t]+$//;
153    print;
154}
155
156# Mark that this object doesn't need an executable stack.
157printf ("    .section .note.GNU-stack,\"\",\%\%progbits\n") if $elf;
158