Reworked test files for better error reporting
[nasm/perl-rewrite.git] / regs.pl
blob4fc30df10bd698f05040e5483e866c77f30df762
1 #!/usr/bin/env perl
3 # Read regs.dat and output regs.h and regs.c (included in names.c)
6 use lib 'perllib';
8 $nline = 0;
10 sub toint($) {
11 my($v) = @_;
13 return ($v =~ /^0/) ? oct $v : $v+0;
16 sub process_line($) {
17 my($line) = @_;
18 my @v;
20 if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
21 die "regs.dat:$nline: invalid input\n";
23 $reg = $1;
24 $aclass = $2;
25 $dclasses = $3;
26 $x86regno = toint($4);
28 if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
29 $nregs = $3-$2+1;
30 $reg = $1.$2.$4;
31 $reg_nr = $2;
32 $reg_prefix = $1;
33 $reg_suffix = $4;
34 } else {
35 $nregs = 1;
36 undef $reg_prefix, $reg_suffix;
39 while ($nregs--) {
40 $regs{$reg} = $aclass;
41 $regvals{$reg} = $x86regno;
43 foreach $dclass (split(/,/, $dclasses)) {
44 if ( !defined($disclass{$dclass}) ) {
45 $disclass{$dclass} = [];
48 $disclass{$dclass}->[$x86regno] = $reg;
49 push @{$drclass{$reg}}, $dclass;
52 # Compute the next register, if any
53 if (defined($reg_prefix)) {
54 $x86regno++;
55 $reg_nr++;
56 $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix);
57 } else {
58 # Not a dashed sequence
59 die if ($nregs);
64 ($fmt, $file) = @ARGV;
66 %regs = ();
67 %regvals = ();
68 %disclass = ();
69 open(REGS, "< ${file}") or die "$0: Cannot open $file\n";
70 while ( defined($line = <REGS>) ) {
71 $nline++;
73 chomp $line;
74 $line =~ s/\s*(\#.*|)$//;
76 next if ( $line eq '' );
78 process_line($line);
80 close(REGS);
82 if ( $fmt eq 'h' ) {
83 # Output regs.h
84 print "/* automatically generated from $file - do not edit */\n\n";
85 print "#ifndef NASM_REGS_H\n";
86 print "#define NASM_REGS_H\n\n";
88 $expr_regs = 1;
89 printf "#define EXPR_REG_START %d\n\n", $expr_regs;
90 print "enum reg_enum {\n";
91 # Unfortunately the code uses both 0 and -1 as "no register" in
92 # different places...
93 print " R_zero = 0,\n";
94 print " R_none = -1,\n";
95 $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1
96 foreach $reg ( sort(keys(%regs)) ) {
97 print " R_\U${reg}\E${attach},\n";
98 $attach = '';
99 $expr_regs++;
101 print " REG_ENUM_LIMIT\n";
102 print "};\n\n";
103 printf "#define EXPR_REG_END %d\n\n", $expr_regs-1;
104 foreach $reg ( sort(keys(%regs)) ) {
105 printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg};
107 print "\n\n#endif /* NASM_REGS_H */\n";
108 } elsif ( $fmt eq 'c' ) {
109 # Output regs.c
110 print "/* automatically generated from $file - do not edit */\n\n";
111 print "#include \"tables.h\"\n\n";
112 print "const char * const nasm_reg_names[] = "; $ch = '{';
113 # This one has no dummy entry for 0
114 foreach $reg ( sort(keys(%regs)) ) {
115 print "$ch\n \"${reg}\"";
116 $ch = ',';
118 print "\n};\n";
119 } elsif ( $fmt eq 'fc' ) {
120 # Output regflags.c
121 print "/* automatically generated from $file - do not edit */\n\n";
122 print "#include \"tables.h\"\n";
123 print "#include \"nasm.h\"\n\n";
124 print "const int32_t nasm_reg_flags[] = {\n";
125 printf " 0,\n"; # Dummy entry for 0
126 foreach $reg ( sort(keys(%regs)) ) {
127 # Print the class of the register
128 printf " %-15s /* %-5s */\n",
129 $regs{$reg}.',', $reg;
131 print "};\n";
132 } elsif ( $fmt eq 'vc' ) {
133 # Output regvals.c
134 print "/* automatically generated from $file - do not edit */\n\n";
135 print "#include \"tables.h\"\n\n";
136 print "const int nasm_regvals[] = {\n";
137 print " -1,\n"; # Dummy entry for 0
138 foreach $reg ( sort(keys(%regs)) ) {
139 # Print the x86 value of the register
140 printf " %2d, /* %-5s */\n", $regvals{$reg}, $reg;
142 print "};\n";
143 } elsif ( $fmt eq 'dc' ) {
144 # Output regdis.c
145 print "/* automatically generated from $file - do not edit */\n\n";
146 print "#include \"regdis.h\"\n\n";
147 foreach $class ( sort(keys(%disclass)) ) {
148 printf "const enum reg_enum nasm_rd_%-8s[%2d] = {",
149 $class, scalar @{$disclass{$class}};
150 @foo = @{$disclass{$class}};
151 @bar = ();
152 for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
153 if (defined($foo[$i])) {
154 push(@bar, "R_\U$foo[$i]\E");
155 } else {
156 die "$0: No register name for class $class, value $i\n";
159 print join(',', @bar), "};\n";
161 } elsif ( $fmt eq 'dh' ) {
162 # Output regdis.h
163 print "/* automatically generated from $file - do not edit */\n\n";
164 print "#ifndef NASM_REGDIS_H\n";
165 print "#define NASM_REGDIS_H\n\n";
166 print "#include \"regs.h\"\n\n";
167 foreach $class ( sort(keys(%disclass)) ) {
168 printf "extern const enum reg_enum nasm_rd_%-8s[%2d];\n",
169 $class, scalar @{$disclass{$class}};
171 print "\n#endif /* NASM_REGDIS_H */\n";
172 } elsif ( $fmt eq 'yaml' ) {
173 require YAML::XS;
175 my @names = sort keys %regs;
176 my %data;
178 my $count = 1;
179 for my $name (@names){
180 $data{$name} = {
181 AssemblerClass => $regs{$name},
182 DisassemblerClasses => $drclass{$name},
183 x86RegisterNumber => $regvals{$name},
184 Index => $count++
188 print YAML::XS::Dump(\%data), "\n";
189 } elsif ( $fmt eq 'order' ) {
190 use 5.010;
191 say for sort keys %regs;
192 } else {
193 die "$0: Unknown output format\n";