Implement REL/ABS modifiers
[nasm.git] / regs.pl
blob6c1aa7eddff51b713f583485ef1b67fb48705171
1 #!/usr/bin/perl
2 # $Id$
4 # Read regs.dat and output regs.h and regs.c (included in names.c)
7 $nline = 0;
9 sub toint($) {
10 my($v) = @_;
12 return ($v =~ /^0/) ? oct $v : $v+0;
15 sub process_line($) {
16 my($line) = @_;
17 my @v;
19 if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
20 die "regs.dat:$nline: invalid input\n";
22 $reg = $1;
23 $aclass = $2;
24 $dclasses = $3;
25 $x86regno = toint($4);
27 if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
28 $nregs = $3-$2+1;
29 $reg = $1.$2;
30 $reg_nr = $2;
31 $reg_prefix = $1;
32 $reg_suffix = $4;
33 } else {
34 $nregs = 1;
35 undef $reg_prefix, $reg_suffix;
38 while ($nregs--) {
39 $regs{$reg} = $aclass;
40 $regvals{$reg} = $x86regno;
42 foreach $dclass (split(/,/, $dclasses)) {
43 if ( !defined($disclass{$dclass}) ) {
44 $disclass{$dclass} = [];
47 $disclass{$dclass}->[$x86regno] = $reg;
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);
62 ($fmt, $file) = @ARGV;
64 %regs = ();
65 %regvals = ();
66 %disclass = ();
67 open(REGS, "< ${file}") or die "$0: Cannot open $file\n";
68 while ( defined($line = <REGS>) ) {
69 $nline++;
71 chomp $line;
72 $line =~ s/\s*(\#.*|)$//;
74 next if ( $line eq '' );
76 process_line($line);
78 close(REGS);
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++;
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};
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 *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 = ',';
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
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
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 int 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";
141 print join(',', @bar), "};\n";
143 } else {
144 die "$0: Unknown output format\n";