| #!/usr/bin/perl |
| ## -------------------------------------------------------------------------- |
| ## |
| ## Copyright 1996-2009 The NASM Authors - All Rights Reserved |
| ## See the file AUTHORS included with the NASM distribution for |
| ## the specific copyright holders. |
| ## |
| ## Redistribution and use in source and binary forms, with or without |
| ## modification, are permitted provided that the following |
| ## conditions are met: |
| ## |
| ## * Redistributions of source code must retain the above copyright |
| ## notice, this list of conditions and the following disclaimer. |
| ## * Redistributions in binary form must reproduce the above |
| ## copyright notice, this list of conditions and the following |
| ## disclaimer in the documentation and/or other materials provided |
| ## with the distribution. |
| ## |
| ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
| ## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| ## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| ## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| ## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| ## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ## |
| ## -------------------------------------------------------------------------- |
| |
| # |
| # 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*(\S*)/i ) { |
| die "regs.dat:$nline: invalid input\n"; |
| } |
| $reg = $1; |
| $aclass = $2; |
| $dclasses = $3; |
| $x86regno = toint($4); |
| |
| 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; |
| } |
| |
| 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; |
| |
| %regs = (); |
| %regvals = (); |
| %disclass = (); |
| open(REGS, '<', $file) or die "$0: Cannot open $file\n"; |
| while ( defined($line = <REGS>) ) { |
| $nline++; |
| |
| chomp $line; |
| $line =~ s/\s*(\#.*|)$//; |
| |
| next if ( $line eq '' ); |
| |
| process_line($line); |
| } |
| close(REGS); |
| |
| if ( $fmt eq 'h' ) { |
| # Output regs.h |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#ifndef NASM_REGS_H\n"; |
| print "#define NASM_REGS_H\n\n"; |
| |
| $expr_regs = 1; |
| printf "#define EXPR_REG_START %d\n\n", $expr_regs; |
| print "enum reg_enum {\n"; |
| # Unfortunately the code uses both 0 and -1 as "no register" in |
| # different places... |
| print " R_zero = 0,\n"; |
| print " R_none = -1,\n"; |
| $attach = ' = EXPR_REG_START'; # EXPR_REG_START == 1 |
| foreach $reg ( sort(keys(%regs)) ) { |
| print " R_\U${reg}\E${attach},\n"; |
| $attach = ''; |
| $expr_regs++; |
| } |
| print " REG_ENUM_LIMIT\n"; |
| print "};\n\n"; |
| printf "#define EXPR_REG_END %d\n\n", $expr_regs-1; |
| foreach $reg ( sort(keys(%regs)) ) { |
| printf "#define %-15s %2d\n", "REG_NUM_\U${reg}", $regvals{$reg}; |
| } |
| print "\n\n#endif /* NASM_REGS_H */\n"; |
| } elsif ( $fmt eq 'c' ) { |
| # Output regs.c |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#include \"tables.h\"\n\n"; |
| print "const char * const nasm_reg_names[] = "; $ch = '{'; |
| # This one has no dummy entry for 0 |
| foreach $reg ( sort(keys(%regs)) ) { |
| print "$ch\n \"${reg}\""; |
| $ch = ','; |
| } |
| print "\n};\n"; |
| } elsif ( $fmt eq 'fc' ) { |
| # Output regflags.c |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#include \"tables.h\"\n"; |
| print "#include \"nasm.h\"\n\n"; |
| print "const opflags_t nasm_reg_flags[] = {\n"; |
| printf " 0,\n"; # Dummy entry for 0 |
| foreach $reg ( sort(keys(%regs)) ) { |
| # Print the class of the register |
| printf " %-15s /* %-5s */\n", |
| $regs{$reg}.',', $reg; |
| } |
| print "};\n"; |
| } elsif ( $fmt eq 'vc' ) { |
| # Output regvals.c |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#include \"tables.h\"\n\n"; |
| print "const int nasm_regvals[] = {\n"; |
| print " -1,\n"; # Dummy entry for 0 |
| foreach $reg ( sort(keys(%regs)) ) { |
| # Print the x86 value of the register |
| printf " %2d, /* %-5s */\n", $regvals{$reg}, $reg; |
| } |
| print "};\n"; |
| } elsif ( $fmt eq 'dc' ) { |
| # Output regdis.c |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#include \"regdis.h\"\n\n"; |
| foreach $class ( sort(keys(%disclass)) ) { |
| printf "const enum reg_enum nasm_rd_%-8s[%2d] = {", |
| $class, scalar @{$disclass{$class}}; |
| @foo = @{$disclass{$class}}; |
| @bar = (); |
| for ( $i = 0 ; $i < scalar(@foo) ; $i++ ) { |
| if (defined($foo[$i])) { |
| push(@bar, "R_\U$foo[$i]\E"); |
| } else { |
| die "$0: No register name for class $class, value $i\n"; |
| } |
| } |
| print join(',', @bar), "};\n"; |
| } |
| } elsif ( $fmt eq 'dh' ) { |
| # Output regdis.h |
| print "/* automatically generated from $file - do not edit */\n\n"; |
| print "#ifndef NASM_REGDIS_H\n"; |
| print "#define NASM_REGDIS_H\n\n"; |
| print "#include \"regs.h\"\n\n"; |
| foreach $class ( sort(keys(%disclass)) ) { |
| printf "extern const enum reg_enum nasm_rd_%-8s[%2d];\n", |
| $class, scalar @{$disclass{$class}}; |
| } |
| print "\n#endif /* NASM_REGDIS_H */\n"; |
| } else { |
| die "$0: Unknown output format\n"; |
| } |