ads2gas_apple.pl 4.7 KB

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