Use enums to make debugging easier
[platform/upstream/nasm.git] / regs.pl
1 #!/usr/bin/perl
2 # $Id$
3 #
4 # Read regs.dat and output regs.h and regs.c (included in names.c)
5 #
6
7 $nline = 0;
8
9 sub toint($) {
10     my($v) = @_;
11
12     return ($v =~ /^0/) ? oct $v : $v+0;
13 }
14
15 sub process_line($) {
16     my($line) = @_;
17     my @v;
18
19     if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
20         die "regs.dat:$nline: invalid input\n";
21     }
22     $reg      = $1;
23     $aclass   = $2;
24     $dclasses = $3;
25     $x86regno = toint($4);
26
27     if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
28         $nregs = $3-$2+1;
29         $reg = $1.$2.$4;
30         $reg_nr = $2;
31         $reg_prefix = $1;
32         $reg_suffix = $4;
33     } else {
34         $nregs = 1;
35         undef $reg_prefix, $reg_suffix;
36     }
37
38     while ($nregs--) {
39         $regs{$reg} = $aclass;
40         $regvals{$reg} = $x86regno;
41
42         foreach $dclass (split(/,/, $dclasses)) {
43             if ( !defined($disclass{$dclass}) ) {
44                 $disclass{$dclass} = [];
45             }
46             
47             $disclass{$dclass}->[$x86regno] = $reg;
48         }
49
50         # Compute the next register, if any
51         if (defined($reg_prefix)) {
52             $x86regno++;
53             $reg_nr++;
54             $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix);
55         } else {
56             # Not a dashed sequence
57             die if ($nregs);
58         }
59     }
60 }
61
62 ($fmt, $file) = @ARGV;
63
64 %regs = ();
65 %regvals = ();
66 %disclass = ();
67 open(REGS, "< ${file}") or die "$0: Cannot open $file\n";
68 while ( defined($line = <REGS>) ) {
69     $nline++;
70
71     chomp $line;
72     $line =~ s/\s*(\#.*|)$//;
73     
74     next if ( $line eq '' );
75
76     process_line($line);
77 }
78 close(REGS);
79
80 if ( $fmt eq 'h' ) {
81     # Output regs.h
82     print "/* automatically generated from $file - do not edit */\n";
83     $expr_regs = 1;
84     printf "#define EXPR_REG_START %d\n", $expr_regs;
85     print "enum reg_enum {\n";
86     $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1
87     foreach $reg ( sort(keys(%regs)) ) {
88         print "    R_\U${reg}\E${attach},\n";
89         $attach = ''; $ch = ',';
90         $expr_regs++;
91     }
92     print "    REG_ENUM_LIMIT\n";
93     print "};\n\n";
94     printf "#define EXPR_REG_END %d\n", $expr_regs-1;
95     foreach $reg ( sort(keys(%regs)) ) {
96         printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg};
97     }
98     print "\n";
99 } elsif ( $fmt eq 'c' ) {
100     # Output regs.c
101     print "/* automatically generated from $file - do not edit */\n";
102     print "static const char * const reg_names[] = "; $ch = '{';
103     # This one has no dummy entry for 0
104     foreach $reg ( sort(keys(%regs)) ) {
105         print "$ch\n    \"${reg}\"";
106         $ch = ',';
107     }
108     print "\n};\n";
109 } elsif ( $fmt eq 'fc' ) {
110     # Output regflags.c
111     print "/* automatically generated from $file - do not edit */\n";
112     print "static const int32_t reg_flags[] = {\n";
113     print "    0";              # Dummy entry for 0
114     foreach $reg ( sort(keys(%regs)) ) {
115         print ",\n    ", $regs{$reg}; # Print the class of the register
116     }
117     print "\n};\n";
118 } elsif ( $fmt eq 'vc' ) {
119     # Output regvals.c
120     print "/* automatically generated from $file - do not edit */\n";
121     print "static const int regvals[] = {\n";
122     print "    -1";             # Dummy entry for 0
123     foreach $reg ( sort(keys(%regs)) ) {
124         printf ",\n    %2d", $regvals{$reg}; # Print the regval of the register
125     }
126     print "\n};\n";
127 } elsif ( $fmt eq 'dc' ) {
128     # Output regdis.c
129     print "/* automatically generated from $file - do not edit */\n";
130     foreach $class ( sort(keys(%disclass)) ) {
131         printf "static const enum reg_enum rd_%-8s[] = {", $class;
132         @foo = @{$disclass{$class}};
133         @bar = ();
134         for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
135             if (defined($foo[$i])) {
136                 push(@bar, "R_\U$foo[$i]\E");
137             } else {
138                 die "$0: No register name for class $class, value $i\n";
139             }
140         }
141         print join(',', @bar), "};\n";
142     }
143 } else {
144     die "$0: Unknown output format\n";
145 }