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