regs.pl: Introduce is_register() helper
[nasm.git] / regs.pl
blobe6350f92b0ec605c0cb220aa9371fe447ab6e606
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:
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.
33 ## --------------------------------------------------------------------------
36 # Read regs.dat and output regs.h and regs.c (included in names.c)
39 $nline = 0;
41 sub toint($) {
42 my($v) = @_;
44 return ($v =~ /^0/) ? oct $v : $v+0;
47 sub process_line($) {
48 my($line) = @_;
49 my @v;
51 if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
52 die "regs.dat:$nline: invalid input\n";
54 $reg = $1;
55 $aclass = $2;
56 $dclasses = $3;
57 $x86regno = toint($4);
59 if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
60 $nregs = $3-$2+1;
61 $reg = $1.$2.$4;
62 $reg_nr = $2;
63 $reg_prefix = $1;
64 $reg_suffix = $4;
65 } else {
66 $nregs = 1;
67 undef $reg_prefix, $reg_suffix;
70 while ($nregs--) {
71 $regs{$reg} = $aclass;
72 $regvals{$reg} = $x86regno;
74 foreach $dclass (split(/,/, $dclasses)) {
75 if ( !defined($disclass{$dclass}) ) {
76 $disclass{$dclass} = [];
79 $disclass{$dclass}->[$x86regno] = $reg;
82 # Compute the next register, if any
83 if (defined($reg_prefix)) {
84 $x86regno++;
85 $reg_nr++;
86 $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix);
87 } else {
88 # Not a dashed sequence
89 die if ($nregs);
94 ($fmt, $file) = @ARGV;
96 %regs = ();
97 %regvals = ();
98 %disclass = ();
99 open(REGS, "< ${file}") or die "$0: Cannot open $file\n";
100 while ( defined($line = <REGS>) ) {
101 $nline++;
103 chomp $line;
104 $line =~ s/\s*(\#.*|)$//;
106 next if ( $line eq '' );
108 process_line($line);
110 close(REGS);
112 if ( $fmt eq 'h' ) {
113 # Output regs.h
114 print "/* automatically generated from $file - do not edit */\n\n";
115 print "#ifndef NASM_REGS_H\n";
116 print "#define NASM_REGS_H\n\n";
118 $expr_regs = 1;
119 printf "#define EXPR_REG_START %d\n\n", $expr_regs;
120 print "enum reg_enum {\n";
121 # Unfortunately the code uses both 0 and -1 as "no register" in
122 # different places...
123 print " R_zero = 0,\n";
124 print " R_none = -1,\n";
125 $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1
126 foreach $reg ( sort(keys(%regs)) ) {
127 print " R_\U${reg}\E${attach},\n";
128 $attach = '';
129 $expr_regs++;
131 print " REG_ENUM_LIMIT\n";
132 print "};\n\n";
133 printf "#define EXPR_REG_END %d\n\n", $expr_regs-1;
134 foreach $reg ( sort(keys(%regs)) ) {
135 printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg};
138 print "\n";
139 print "static inline int is_register(int reg)\n";
140 print "{\n";
141 print " return reg >= EXPR_REG_START && reg < REG_ENUM_LIMIT;\n";
142 print "}\n";
144 print "\n\n#endif /* NASM_REGS_H */\n";
145 } elsif ( $fmt eq 'c' ) {
146 # Output regs.c
147 print "/* automatically generated from $file - do not edit */\n\n";
148 print "#include \"tables.h\"\n\n";
149 print "const char * const nasm_reg_names[] = "; $ch = '{';
150 # This one has no dummy entry for 0
151 foreach $reg ( sort(keys(%regs)) ) {
152 print "$ch\n \"${reg}\"";
153 $ch = ',';
155 print "\n};\n";
156 } elsif ( $fmt eq 'fc' ) {
157 # Output regflags.c
158 print "/* automatically generated from $file - do not edit */\n\n";
159 print "#include \"tables.h\"\n";
160 print "#include \"nasm.h\"\n\n";
161 print "const opflags_t nasm_reg_flags[] = {\n";
162 printf " 0,\n"; # Dummy entry for 0
163 foreach $reg ( sort(keys(%regs)) ) {
164 # Print the class of the register
165 printf " %-15s /* %-5s */\n",
166 $regs{$reg}.',', $reg;
168 print "};\n";
169 } elsif ( $fmt eq 'vc' ) {
170 # Output regvals.c
171 print "/* automatically generated from $file - do not edit */\n\n";
172 print "#include \"tables.h\"\n\n";
173 print "const int nasm_regvals[] = {\n";
174 print " -1,\n"; # Dummy entry for 0
175 foreach $reg ( sort(keys(%regs)) ) {
176 # Print the x86 value of the register
177 printf " %2d, /* %-5s */\n", $regvals{$reg}, $reg;
179 print "};\n";
180 } elsif ( $fmt eq 'dc' ) {
181 # Output regdis.c
182 print "/* automatically generated from $file - do not edit */\n\n";
183 print "#include \"regdis.h\"\n\n";
184 foreach $class ( sort(keys(%disclass)) ) {
185 printf "const enum reg_enum nasm_rd_%-8s[%2d] = {",
186 $class, scalar @{$disclass{$class}};
187 @foo = @{$disclass{$class}};
188 @bar = ();
189 for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
190 if (defined($foo[$i])) {
191 push(@bar, "R_\U$foo[$i]\E");
192 } else {
193 die "$0: No register name for class $class, value $i\n";
196 print join(',', @bar), "};\n";
198 } elsif ( $fmt eq 'dh' ) {
199 # Output regdis.h
200 print "/* automatically generated from $file - do not edit */\n\n";
201 print "#ifndef NASM_REGDIS_H\n";
202 print "#define NASM_REGDIS_H\n\n";
203 print "#include \"regs.h\"\n\n";
204 foreach $class ( sort(keys(%disclass)) ) {
205 printf "extern const enum reg_enum nasm_rd_%-8s[%2d];\n",
206 $class, scalar @{$disclass{$class}};
208 print "\n#endif /* NASM_REGDIS_H */\n";
209 } else {
210 die "$0: Unknown output format\n";