Home | History | Annotate | Download | only in make
      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 
     21 use FindBin;
     22 use lib $FindBin::Bin;
     23 use thumb;
     24 
     25 my $thumb = 0;
     26 
     27 foreach my $arg (@ARGV) {
     28     $thumb = 1 if ($arg eq "-thumb");
     29 }
     30 
     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";
     34 if ($thumb) {
     35     print "\t.syntax unified\n";
     36     print "\t.thumb\n";
     37 }
     38 
     39 # Stack of procedure names.
     40 @proc_stack = ();
     41 
     42 while (<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.
    228 printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");
    229