Update documentation
[platform/upstream/nasm.git] / regs.pl
diff --git a/regs.pl b/regs.pl
index 5835493..9dde682 100755 (executable)
--- a/regs.pl
+++ b/regs.pl
@@ -1,31 +1,61 @@
 #!/usr/bin/perl
-# $Id$
 #
 # Read regs.dat and output regs.h and regs.c (included in names.c)
 #
 
 $nline = 0;
 
+sub toint($) {
+    my($v) = @_;
+
+    return ($v =~ /^0/) ? oct $v : $v+0;
+}
+
 sub process_line($) {
     my($line) = @_;
     my @v;
 
-    if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)\s*$/ ) {
+    if ( $line !~ /^\s*(\S+)\s*(\S+)\s*(\S+)\s*([0-9]+)$/i ) {
        die "regs.dat:$nline: invalid input\n";
     }
-    $reg    = $1;
-    $aclass = $2;
-    $dclass = $3;
-    $regval   = $4;
-
-    $regs{$reg} = $aclass;
-    $regvals{$reg} = $regval;
+    $reg      = $1;
+    $aclass   = $2;
+    $dclasses = $3;
+    $x86regno = toint($4);
 
-    if ( !defined($disclass{$dclass}) ) {
-       $disclass{$dclass} = [(undef) x 8];
+    if ($reg =~ /^(.*[^0-9])([0-9]+)\-([0-9]+)(|[^0-9].*)$/) {
+       $nregs = $3-$2+1;
+       $reg = $1.$2.$4;
+       $reg_nr = $2;
+       $reg_prefix = $1;
+       $reg_suffix = $4;
+    } else {
+       $nregs = 1;
+       undef $reg_prefix, $reg_suffix;
     }
 
-    $disclass{$dclass}->[$regval] = $reg;
+    while ($nregs--) {
+       $regs{$reg} = $aclass;
+       $regvals{$reg} = $x86regno;
+
+       foreach $dclass (split(/,/, $dclasses)) {
+           if ( !defined($disclass{$dclass}) ) {
+               $disclass{$dclass} = [];
+           }
+           
+           $disclass{$dclass}->[$x86regno] = $reg;
+       }
+
+       # Compute the next register, if any
+       if (defined($reg_prefix)) {
+           $x86regno++;
+           $reg_nr++;
+           $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix);
+       } else {
+           # Not a dashed sequence
+           die if ($nregs);
+       }
+    }
 }
 
 ($fmt, $file) = @ARGV;
@@ -42,36 +72,37 @@ while ( defined($line = <REGS>) ) {
     
     next if ( $line eq '' );
 
-    if ( $line =~ /\*/ ) {
-       for ( $i = 0 ; $i < 8 ; $i++ ) {
-           ($xline = $line) =~ s/\*/$i/g;
-           process_line($xline);
-       }
-    } else {
-       process_line($line);
-    }
+    process_line($line);
 }
 close(REGS);
 
 if ( $fmt eq 'h' ) {
     # Output regs.h
     print "/* automatically generated from $file - do not edit */\n";
+    $expr_regs = 1;
+    printf "#define EXPR_REG_START %d\n", $expr_regs;
     print "enum reg_enum {\n";
     $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1
     foreach $reg ( sort(keys(%regs)) ) {
        print "    R_\U${reg}\E${attach},\n";
-       $attach = ''; $ch = ',';
+       $attach = '';
+       $expr_regs++;
     }
-    print "    REG_ENUM_LIMIT\n";
+    print "    REG_ENUM_LIMIT,\n";
+    # Unfortunately the code uses both 0 and -1 as "no register" in
+    # different places...
+    print "    R_zero = 0,\n";
+    print "    R_none = -1";
     print "};\n\n";
+    printf "#define EXPR_REG_END %d\n", $expr_regs-1;
     foreach $reg ( sort(keys(%regs)) ) {
-       print "#define REG_NUM_\U${reg}     $regvals{$reg}\n";
+       printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg};
     }
     print "\n";
 } elsif ( $fmt eq 'c' ) {
     # Output regs.c
     print "/* automatically generated from $file - do not edit */\n";
-    print "static const char *reg_names[] = "; $ch = '{';
+    print "static const char * const reg_names[] = "; $ch = '{';
     # This one has no dummy entry for 0
     foreach $reg ( sort(keys(%regs)) ) {
        print "$ch\n    \"${reg}\"";
@@ -93,21 +124,21 @@ if ( $fmt eq 'h' ) {
     print "static const int regvals[] = {\n";
     print "    -1";            # Dummy entry for 0
     foreach $reg ( sort(keys(%regs)) ) {
-       print ",\n    ", $regvals{$reg}; # Print the regval of the register
+       printf ",\n    %2d", $regvals{$reg}; # Print the regval of the register
     }
     print "\n};\n";
 } elsif ( $fmt eq 'dc' ) {
     # Output regdis.c
     print "/* automatically generated from $file - do not edit */\n";
     foreach $class ( sort(keys(%disclass)) ) {
-       printf "static const int %-8s[] = {", $class;
+       printf "static const enum reg_enum rd_%-8s[] = {", $class;
        @foo = @{$disclass{$class}};
-       @bar = 0;
-       $counter = 0;
+       @bar = ();
        for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) {
             if (defined($foo[$i])) {
-               $bar[$counter] = "R_\U$foo[$i]\E";
-               $counter ++;
+               push(@bar, "R_\U$foo[$i]\E");
+           } else {
+               die "$0: No register name for class $class, value $i\n";
             }
        }
        print join(',', @bar), "};\n";