regs.pl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #!/usr/bin/perl
  2. ## --------------------------------------------------------------------------
  3. ##
  4. ## Copyright 1996-2009 The NASM Authors - All Rights Reserved
  5. ## See the file AUTHORS included with the NASM distribution for
  6. ## the specific copyright holders.
  7. ##
  8. ## Redistribution and use in source and binary forms, with or without
  9. ## modification, are permitted provided that the following
  10. ## conditions are met:
  11. ##
  12. ## * Redistributions of source code must retain the above copyright
  13. ## notice, this list of conditions and the following disclaimer.
  14. ## * Redistributions in binary form must reproduce the above
  15. ## copyright notice, this list of conditions and the following
  16. ## disclaimer in the documentation and/or other materials provided
  17. ## with the distribution.
  18. ##
  19. ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  20. ## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  21. ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  22. ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23. ## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24. ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  30. ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  31. ## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. ##
  33. ## --------------------------------------------------------------------------
  34. #
  35. # Read regs.dat and output regs.h and regs.c (included in names.c)
  36. #
  37. $nline = 0;
  38. sub toint($) {
  39. my($v) = @_;
  40. return ($v =~ /^0/) ? oct $v : $v+0;
  41. }
  42. sub process_line($) {
  43. my($line) = @_;
  44. my @v;
  45. if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)\s*(\S*)/i ) {
  46. die "regs.dat:$nline: invalid input\n";
  47. }
  48. $reg = $1;
  49. $aclass = $2;
  50. $dclasses = $3;
  51. $x86regno = toint($4);
  52. if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
  53. $nregs = $3-$2+1;
  54. $reg = $1.$2.$4;
  55. $reg_nr = $2;
  56. $reg_prefix = $1;
  57. $reg_suffix = $4;
  58. } else {
  59. $nregs = 1;
  60. undef $reg_prefix, $reg_suffix;
  61. }
  62. while ($nregs--) {
  63. $regs{$reg} = $aclass;
  64. $regvals{$reg} = $x86regno;
  65. foreach $dclass (split(/,/, $dclasses)) {
  66. if ( !defined($disclass{$dclass}) ) {
  67. $disclass{$dclass} = [];
  68. }
  69. $disclass{$dclass}->[$x86regno] = $reg;
  70. }
  71. # Compute the next register, if any
  72. if (defined($reg_prefix)) {
  73. $x86regno++;
  74. $reg_nr++;
  75. $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix);
  76. } else {
  77. # Not a dashed sequence
  78. die if ($nregs);
  79. }
  80. }
  81. }
  82. ($fmt, $file) = @ARGV;
  83. %regs = ();
  84. %regvals = ();
  85. %disclass = ();
  86. open(REGS, '<', $file) or die "$0: Cannot open $file\n";
  87. while ( defined($line = <REGS>) ) {
  88. $nline++;
  89. chomp $line;
  90. $line =~ s/\s*(\#.*|)$//;
  91. next if ( $line eq '' );
  92. process_line($line);
  93. }
  94. close(REGS);
  95. if ( $fmt eq 'h' ) {
  96. # Output regs.h
  97. print "/* automatically generated from $file - do not edit */\n\n";
  98. print "#ifndef NASM_REGS_H\n";
  99. print "#define NASM_REGS_H\n\n";
  100. $expr_regs = 1;
  101. printf "#define EXPR_REG_START %d\n\n", $expr_regs;
  102. print "enum reg_enum {\n";
  103. # Unfortunately the code uses both 0 and -1 as "no register" in
  104. # different places...
  105. print " R_zero = 0,\n";
  106. print " R_none = -1,\n";
  107. $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1
  108. foreach $reg ( sort(keys(%regs)) ) {
  109. print " R_\U${reg}\E${attach},\n";
  110. $attach = '';
  111. $expr_regs++;
  112. }
  113. print " REG_ENUM_LIMIT\n";
  114. print "};\n\n";
  115. printf "#define EXPR_REG_END %d\n\n", $expr_regs-1;
  116. foreach $reg ( sort(keys(%regs)) ) {
  117. printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg};
  118. }
  119. print "\n\n#endif /* NASM_REGS_H */\n";
  120. } elsif ( $fmt eq 'c' ) {
  121. # Output regs.c
  122. print "/* automatically generated from $file - do not edit */\n\n";
  123. print "#include \"tables.h\"\n\n";
  124. print "const char * const nasm_reg_names[] = "; $ch = '{';
  125. # This one has no dummy entry for 0
  126. foreach $reg ( sort(keys(%regs)) ) {
  127. print "$ch\n \"${reg}\"";
  128. $ch = ',';
  129. }
  130. print "\n};\n";
  131. } elsif ( $fmt eq 'fc' ) {
  132. # Output regflags.c
  133. print "/* automatically generated from $file - do not edit */\n\n";
  134. print "#include \"tables.h\"\n";
  135. print "#include \"nasm.h\"\n\n";
  136. print "const opflags_t nasm_reg_flags[] = {\n";
  137. printf " 0,\n"; # Dummy entry for 0
  138. foreach $reg ( sort(keys(%regs)) ) {
  139. # Print the class of the register
  140. printf " %-15s /* %-5s */\n",
  141. $regs{$reg}.',', $reg;
  142. }
  143. print "};\n";
  144. } elsif ( $fmt eq 'vc' ) {
  145. # Output regvals.c
  146. print "/* automatically generated from $file - do not edit */\n\n";
  147. print "#include \"tables.h\"\n\n";
  148. print "const int nasm_regvals[] = {\n";
  149. print " -1,\n"; # Dummy entry for 0
  150. foreach $reg ( sort(keys(%regs)) ) {
  151. # Print the x86 value of the register
  152. printf " %2d, /* %-5s */\n", $regvals{$reg}, $reg;
  153. }
  154. print "};\n";
  155. } elsif ( $fmt eq 'dc' ) {
  156. # Output regdis.c
  157. print "/* automatically generated from $file - do not edit */\n\n";
  158. print "#include \"regdis.h\"\n\n";
  159. foreach $class ( sort(keys(%disclass)) ) {
  160. printf "const enum reg_enum nasm_rd_%-8s[%2d] = {",
  161. $class, scalar @{$disclass{$class}};
  162. @foo = @{$disclass{$class}};
  163. @bar = ();
  164. for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
  165. if (defined($foo[$i])) {
  166. push(@bar, "R_\U$foo[$i]\E");
  167. } else {
  168. die "$0: No register name for class $class, value $i\n";
  169. }
  170. }
  171. print join(',', @bar), "};\n";
  172. }
  173. } elsif ( $fmt eq 'dh' ) {
  174. # Output regdis.h
  175. print "/* automatically generated from $file - do not edit */\n\n";
  176. print "#ifndef NASM_REGDIS_H\n";
  177. print "#define NASM_REGDIS_H\n\n";
  178. print "#include \"regs.h\"\n\n";
  179. foreach $class ( sort(keys(%disclass)) ) {
  180. printf "extern const enum reg_enum nasm_rd_%-8s[%2d];\n",
  181. $class, scalar @{$disclass{$class}};
  182. }
  183. print "\n#endif /* NASM_REGDIS_H */\n";
  184. } else {
  185. die "$0: Unknown output format\n";
  186. }