Add copyright verbiage to Perl scripts; update LICENSE
[platform/upstream/nasm.git] / regs.pl
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 #
36 # Read regs.dat and output regs.h and regs.c (included in names.c)
37 #
38
39 $nline = 0;
40
41 sub toint($) {
42     my($v) = @_;
43
44     return ($v =~ /^0/) ? oct $v : $v+0;
45 }
46
47 sub process_line($) {
48     my($line) = @_;
49     my @v;
50
51     if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
52         die "regs.dat:$nline: invalid input\n";
53     }
54     $reg      = $1;
55     $aclass   = $2;
56     $dclasses = $3;
57     $x86regno = toint($4);
58
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;
68     }
69
70     while ($nregs--) {
71         $regs{$reg} = $aclass;
72         $regvals{$reg} = $x86regno;
73
74         foreach $dclass (split(/,/, $dclasses)) {
75             if ( !defined($disclass{$dclass}) ) {
76                 $disclass{$dclass} = [];
77             }
78
79             $disclass{$dclass}->[$x86regno] = $reg;
80         }
81
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);
90         }
91     }
92 }
93
94 ($fmt, $file) = @ARGV;
95
96 %regs = ();
97 %regvals = ();
98 %disclass = ();
99 open(REGS, "< ${file}") or die "$0: Cannot open $file\n";
100 while ( defined($line = <REGS>) ) {
101     $nline++;
102
103     chomp $line;
104     $line =~ s/\s*(\#.*|)$//;
105
106     next if ( $line eq '' );
107
108     process_line($line);
109 }
110 close(REGS);
111
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";
117
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++;
130     }
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};
136     }
137     print "\n\n#endif /* NASM_REGS_H */\n";
138 } elsif ( $fmt eq 'c' ) {
139     # Output regs.c
140     print "/* automatically generated from $file - do not edit */\n\n";
141     print "#include \"tables.h\"\n\n";
142     print "const char * const nasm_reg_names[] = "; $ch = '{';
143     # This one has no dummy entry for 0
144     foreach $reg ( sort(keys(%regs)) ) {
145         print "$ch\n    \"${reg}\"";
146         $ch = ',';
147     }
148     print "\n};\n";
149 } elsif ( $fmt eq 'fc' ) {
150     # Output regflags.c
151     print "/* automatically generated from $file - do not edit */\n\n";
152     print "#include \"tables.h\"\n";
153     print "#include \"nasm.h\"\n\n";
154     print "const int32_t nasm_reg_flags[] = {\n";
155     printf "    0,\n";          # Dummy entry for 0
156     foreach $reg ( sort(keys(%regs)) ) {
157         # Print the class of the register
158         printf "    %-15s /* %-5s */\n",
159                 $regs{$reg}.',', $reg;
160     }
161     print "};\n";
162 } elsif ( $fmt eq 'vc' ) {
163     # Output regvals.c
164     print "/* automatically generated from $file - do not edit */\n\n";
165     print "#include \"tables.h\"\n\n";
166     print "const int nasm_regvals[] = {\n";
167     print "    -1,\n";          # Dummy entry for 0
168     foreach $reg ( sort(keys(%regs)) ) {
169         # Print the x86 value of the register
170         printf "    %2d,  /* %-5s */\n", $regvals{$reg}, $reg;
171     }
172     print "};\n";
173 } elsif ( $fmt eq 'dc' ) {
174     # Output regdis.c
175     print "/* automatically generated from $file - do not edit */\n\n";
176     print "#include \"regdis.h\"\n\n";
177     foreach $class ( sort(keys(%disclass)) ) {
178         printf "const enum reg_enum nasm_rd_%-8s[%2d] = {",
179                 $class, scalar @{$disclass{$class}};
180         @foo = @{$disclass{$class}};
181         @bar = ();
182         for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
183             if (defined($foo[$i])) {
184                 push(@bar, "R_\U$foo[$i]\E");
185             } else {
186                 die "$0: No register name for class $class, value $i\n";
187             }
188         }
189         print join(',', @bar), "};\n";
190     }
191 } elsif ( $fmt eq 'dh' ) {
192     # Output regdis.h
193     print "/* automatically generated from $file - do not edit */\n\n";
194     print "#ifndef NASM_REGDIS_H\n";
195     print "#define NASM_REGDIS_H\n\n";
196     print "#include \"regs.h\"\n\n";
197     foreach $class ( sort(keys(%disclass)) ) {
198         printf "extern const enum reg_enum nasm_rd_%-8s[%2d];\n",
199                 $class, scalar @{$disclass{$class}};
200     }
201     print "\n#endif /* NASM_REGDIS_H */\n";
202 } else {
203     die "$0: Unknown output format\n";
204 }