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