ads2gas_apple.pl 4.6 KB

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