ads2gas.pl 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. # ads2gas.pl
  12. # Author: Eric Fung (efung (at) acm.org)
  13. #
  14. # Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format
  15. #
  16. # Usage: cat inputfile | perl ads2gas.pl > outputfile
  17. #
  18. use FindBin;
  19. use lib $FindBin::Bin;
  20. use thumb;
  21. my $thumb = 0;
  22. foreach my $arg (@ARGV) {
  23. $thumb = 1 if ($arg eq "-thumb");
  24. }
  25. print "@ This file was created from a .asm file\n";
  26. print "@ using the ads2gas.pl script.\n";
  27. print "\t.equ DO1STROUNDING, 0\n";
  28. if ($thumb) {
  29. print "\t.syntax unified\n";
  30. print "\t.thumb\n";
  31. }
  32. # Stack of procedure names.
  33. @proc_stack = ();
  34. while (<STDIN>)
  35. {
  36. undef $comment;
  37. undef $line;
  38. $comment_char = ";";
  39. $comment_sub = "@";
  40. # Handle comments.
  41. if (/$comment_char/)
  42. {
  43. $comment = "";
  44. ($line, $comment) = /(.*?)$comment_char(.*)/;
  45. $_ = $line;
  46. }
  47. # Load and store alignment
  48. s/@/,:/g;
  49. # Hexadecimal constants prefaced by 0x
  50. s/#&/#0x/g;
  51. # Convert :OR: to |
  52. s/:OR:/ | /g;
  53. # Convert :AND: to &
  54. s/:AND:/ & /g;
  55. # Convert :NOT: to ~
  56. s/:NOT:/ ~ /g;
  57. # Convert :SHL: to <<
  58. s/:SHL:/ << /g;
  59. # Convert :SHR: to >>
  60. s/:SHR:/ >> /g;
  61. # Convert ELSE to .else
  62. s/\bELSE\b/.else/g;
  63. # Convert ENDIF to .endif
  64. s/\bENDIF\b/.endif/g;
  65. # Convert ELSEIF to .elseif
  66. s/\bELSEIF\b/.elseif/g;
  67. # Convert LTORG to .ltorg
  68. s/\bLTORG\b/.ltorg/g;
  69. # Convert endfunc to nothing.
  70. s/\bendfunc\b//ig;
  71. # Convert FUNCTION to nothing.
  72. s/\bFUNCTION\b//g;
  73. s/\bfunction\b//g;
  74. s/\bENTRY\b//g;
  75. s/\bMSARMASM\b/0/g;
  76. s/^\s+end\s+$//g;
  77. # Convert IF :DEF:to .if
  78. # gcc doesn't have the ability to do a conditional
  79. # if defined variable that is set by IF :DEF: on
  80. # armasm, so convert it to a normal .if and then
  81. # make sure to define a value elesewhere
  82. if (s/\bIF :DEF:\b/.if /g)
  83. {
  84. s/=/==/g;
  85. }
  86. # Convert IF to .if
  87. if (s/\bIF\b/.if/g)
  88. {
  89. s/=+/==/g;
  90. }
  91. # Convert INCLUDE to .INCLUDE "file"
  92. s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
  93. # Code directive (ARM vs Thumb)
  94. s/CODE([0-9][0-9])/.code $1/;
  95. # No AREA required
  96. # But ALIGNs in AREA must be obeyed
  97. s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
  98. # If no ALIGN, strip the AREA and align to 4 bytes
  99. s/^\s*AREA.*$/.text\n.p2align 2/;
  100. # DCD to .word
  101. # This one is for incoming symbols
  102. s/DCD\s+\|(\w*)\|/.long $1/;
  103. # DCW to .short
  104. s/DCW\s+\|(\w*)\|/.short $1/;
  105. s/DCW(.*)/.short $1/;
  106. # Constants defined in scope
  107. s/DCD(.*)/.long $1/;
  108. s/DCB(.*)/.byte $1/;
  109. # Make function visible to linker, and make additional symbol with
  110. # prepended underscore
  111. s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
  112. s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
  113. s/EXPORT\s+([\$\w]*)/.global $1/;
  114. s/export\s+([\$\w]*)/.global $1/;
  115. # No vertical bars required; make additional symbol with prepended
  116. # underscore
  117. s/^\|(\$?\w+)\|/_$1\n\t$1:/g;
  118. # Labels need trailing colon
  119. # s/^(\w+)/$1:/ if !/EQU/;
  120. # put the colon at the end of the line in the macro
  121. s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
  122. # ALIGN directive
  123. s/\bALIGN\b/.balign/g;
  124. if ($thumb) {
  125. # ARM code - we force everything to thumb with the declaration in the header
  126. s/\sARM//g;
  127. } else {
  128. # ARM code
  129. s/\sARM/.arm/g;
  130. }
  131. # push/pop
  132. s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g;
  133. s/(pop\s+)(r\d+)/ldmia sp\!, \{$2\}/g;
  134. # NEON code
  135. s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g;
  136. s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g;
  137. if ($thumb) {
  138. thumb::FixThumbInstructions($_, 0);
  139. }
  140. # eabi_attributes numerical equivalents can be found in the
  141. # "ARM IHI 0045C" document.
  142. # REQUIRE8 Stack is required to be 8-byte aligned
  143. s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
  144. # PRESERVE8 Stack 8-byte align is preserved
  145. s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
  146. # Use PROC and ENDP to give the symbols a .size directive.
  147. # This makes them show up properly in debugging tools like gdb and valgrind.
  148. if (/\bPROC\b/)
  149. {
  150. my $proc;
  151. /^_([\.0-9A-Z_a-z]\w+)\b/;
  152. $proc = $1;
  153. push(@proc_stack, $proc) if ($proc);
  154. s/\bPROC\b/@ $&/;
  155. }
  156. if (/\bENDP\b/)
  157. {
  158. my $proc;
  159. s/\bENDP\b/@ $&/;
  160. $proc = pop(@proc_stack);
  161. $_ = "\t.size $proc, .-$proc".$_ if ($proc);
  162. }
  163. # EQU directive
  164. s/(\S+\s+)EQU(\s+\S+)/.equ $1, $2/;
  165. # Begin macro definition
  166. if (/\bMACRO\b/) {
  167. $_ = <STDIN>;
  168. s/^/.macro/;
  169. s/\$//g; # remove formal param reference
  170. s/;/@/g; # change comment characters
  171. }
  172. # For macros, use \ to reference formal params
  173. s/\$/\\/g; # End macro definition
  174. s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
  175. next if /^\s*END\s*$/;
  176. print;
  177. print "$comment_sub$comment\n" if defined $comment;
  178. }
  179. # Mark that this object doesn't need an executable stack.
  180. printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");