#!/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]+)$/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 = ) ) { $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"; }