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