mirror of
				https://github.com/netwide-assembler/nasm.git
				synced 2025-10-10 00:25:06 -04:00 
			
		
		
		
	pptok.dat: merge from preproc-rewrite branch macros.pl: merge from preproc-rewrite branch version: changed to 2.10rc2
		
			
				
	
	
		
			242 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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.
 | |
| ##
 | |
| ## --------------------------------------------------------------------------
 | |
| 
 | |
| #
 | |
| # macros.pl   produce macros.c from standard.mac
 | |
| #
 | |
| 
 | |
| require 'phash.ph';
 | |
| require 'pptok.ph';
 | |
| 
 | |
| use bytes;
 | |
| 
 | |
| my $fname;
 | |
| my $line = 0;
 | |
| my $index      = 0;
 | |
| my $tasm_count = 0;
 | |
| 
 | |
| #
 | |
| # Print out a string as a character array
 | |
| #
 | |
| sub charcify(@) {
 | |
|     my $l = '';
 | |
|     my $c, $o;
 | |
|     foreach $o (unpack("C*", join('',@_))) {
 | |
| 	$c = pack("C", $o);
 | |
| 	if ($o < 32 || $o > 126 || $c eq '"' || $c eq "\\") {
 | |
| 	    $l .= sprintf("%3d,", $o);
 | |
| 	} else {
 | |
| 	    $c =~ s/\'/\\'/;	# << sanitize single quote. 
 | |
| 	    $l .= "\'".$c."\',";
 | |
| 	}
 | |
|     }
 | |
|     return $l;
 | |
| }
 | |
| 
 | |
| 
 | |
| #
 | |
| # Generate macros.c
 | |
| #
 | |
| open(OUT,"> macros.c\0") or die "unable to open macros.c\n";
 | |
| 
 | |
| print OUT "/*\n";
 | |
| print OUT " * Do not edit - this file auto-generated by macros.pl from:\n";
 | |
| print OUT " *   ", join("\n *   ", @ARGV), "\n";
 | |
| print OUT " */\n";
 | |
| print OUT "\n";
 | |
| print OUT "#include \"tables.h\"\n";
 | |
| print OUT "#include \"nasmlib.h\"\n";
 | |
| print OUT "#include \"hashtbl.h\"\n";
 | |
| print OUT "#include \"output/outform.h\"\n";
 | |
| print OUT "\n";
 | |
| print OUT "#if 1\n";
 | |
| print OUT "const unsigned char nasm_stdmac[] = {";
 | |
| 
 | |
| my $npkg = 0;
 | |
| my @pkg_list   = ();
 | |
| my %pkg_number = ();
 | |
| my $pkg;
 | |
| my @out_list   = ();
 | |
| my $outfmt;
 | |
| my $lastname;
 | |
| my $z;
 | |
| 
 | |
| foreach $fname ( @ARGV ) {
 | |
|     open(INPUT,"< $fname\0") or die "$0: $fname: $!\n";
 | |
|     while (<INPUT>) {
 | |
| 	$line++;
 | |
| 	chomp;
 | |
| 	while (/^(.*)\\$/) {
 | |
| 	    $_ = $1;
 | |
| 	    $_ .= <INPUT>;
 | |
| 	    chomp;
 | |
| 	    $line++;
 | |
| 	}
 | |
| 	if (m/^\s*\*END\*TASM\*MACROS\*\s*$/) {
 | |
| 	    $tasm_count = $index;
 | |
| 	    print OUT "    /* End of TASM macros */\n";
 | |
| 	} elsif (m/^OUT:\s*(.*\S)\s*$/) {
 | |
| 	    undef $pkg;
 | |
| 	    my @out_alias = split(/\s+/, $1);
 | |
| 	    printf OUT "        /* %4d */ 0\n", $index++;
 | |
| 	    print OUT "};\n#endif\n";
 | |
| 	    $index = 0;
 | |
| 	    print OUT "\n";
 | |
| 	    my $pfx = '#if';
 | |
| 	    foreach my $al (@out_alias) {
 | |
| 		print OUT $pfx, " defined(OF_\U${al}\E)";
 | |
| 		$pfx = ' ||';
 | |
| 	    }
 | |
| 	    printf OUT "\nconst unsigned char %s_stdmac[] = {\n", $out_alias[0];
 | |
| 	    print  OUT "    /* From $fname */\n";
 | |
| 	    $lastname = $fname;
 | |
| 	    push(@out_list, $out_alias[0]);
 | |
| 	    $out_index{$out_alias[0]} = $index;
 | |
| 	} elsif (m/^USE:\s*(\S+)\s*$/) {
 | |
| 	    $pkg = $1;
 | |
| 	    if (defined($pkg_number{$pkg})) {
 | |
| 		die "$0: $fname: duplicate package: $pkg\n";
 | |
| 	    }
 | |
| 	    printf OUT "        /* %4d */ 0\n", $index++;
 | |
| 	    print OUT "};\n#endif\n";
 | |
| 	    $index = 0;
 | |
| 	    print OUT "\n#if 1\n";
 | |
| 	    printf OUT "static const unsigned char nasm_stdmac_%s[] = {\n", $pkg;
 | |
| 	    print  OUT "    /* From $fname */\n";
 | |
| 	    $lastname = $fname;
 | |
| 	    push(@pkg_list, $pkg);
 | |
| 	    $pkg_number{$pkg} = $npkg++;
 | |
| 	    $z = pack("C", $pptok_hash{'%define'}+128)."__USE_\U$pkg\E__";
 | |
| 	    printf OUT "        /* %4d */ %s0,\n", $index, charcify($z);
 | |
| 	    $index += length($z)+1;
 | |
| 	} elsif (m/^\s*((\s*([^\"\';\s]+|\"[^\"]*\"|\'[^\']*\'))*)\s*(;.*)?$/) {
 | |
| 	    my $s1, $s2, $pd, $ws;
 | |
| 	    $s1 = $1;
 | |
| 	    $s2 = '';
 | |
| 	    while ($s1 =~ /(\%[a-zA-Z_][a-zA-Z0-9_]*)((\s+)(.*)|)$/) {
 | |
| 		$s2 .= "$'";
 | |
| 		$pd = $1;
 | |
| 		$ws = $3;
 | |
| 		$s1 = $4;
 | |
| 		if (defined($pptok_hash{$pd}) &&
 | |
| 		    $pptok_hash{$pd} <= 127) {
 | |
| 		    $s2 .= pack("C", $pptok_hash{$pd}+128);
 | |
| 		} else {
 | |
| 		    $s2 .= $pd.$ws;
 | |
| 		}
 | |
| 	    }
 | |
| 	    $s2 .= $s1;
 | |
| 	    if (length($s2) > 0) {
 | |
| 		if ($lastname ne $fname) {
 | |
| 		    print OUT "\n    /* From $fname */\n";
 | |
| 		    $lastname = $fname;
 | |
| 		}	
 | |
| 		printf OUT "        /* %4d */ %s0,\n",
 | |
| 		    $index, charcify($s2);
 | |
| 		$index += length($s2)+1;
 | |
| 	    }
 | |
| 	} else {
 | |
| 	    die "$fname:$line:  error unterminated quote";
 | |
| 	}
 | |
|     }
 | |
|     close(INPUT);
 | |
| }
 | |
| printf OUT "        /* %4d */ 0\n};\n#endif\n\n", $index++;
 | |
| print OUT "const unsigned char * const nasm_stdmac_after_tasm = ",
 | |
|     "&nasm_stdmac[$tasm_count];\n\n";
 | |
| 
 | |
| my @hashinfo = gen_perfect_hash(\%pkg_number);
 | |
| if (!@hashinfo) {
 | |
|     die "$0: no hash found\n";
 | |
| }
 | |
| # Paranoia...
 | |
| verify_hash_table(\%pkg_number, \@hashinfo);
 | |
| my ($n, $sv, $g) = @hashinfo;
 | |
| die if ($n & ($n-1));
 | |
| 
 | |
| print OUT "const unsigned char *nasm_stdmac_find_package(const char *package)\n";
 | |
| print OUT "{\n";
 | |
| print OUT "    static const struct {\n";
 | |
| print OUT "         const char *package;\n";
 | |
| print OUT "         const unsigned char *macros;\n";
 | |
| print OUT "    } packages[$npkg] = {\n";
 | |
| foreach $pkg (@pkg_list) {
 | |
|     printf OUT "        { \"%s\", nasm_stdmac_%s },\n",
 | |
| 	$pkg, $pkg;
 | |
| }
 | |
| print OUT "    };\n";
 | |
| 
 | |
| # Put a large value in unused slots.  This makes it extremely unlikely
 | |
| # that any combination that involves unused slot will pass the range test.
 | |
| # This speeds up rejection of unrecognized tokens, i.e. identifiers.
 | |
| print OUT "#define UNUSED 16383\n";
 | |
| 
 | |
| print OUT "    static const int16_t hash1[$n] = {\n";
 | |
| for ($i = 0; $i < $n; $i++) {
 | |
|     my $h = ${$g}[$i*2+0];
 | |
|     print OUT "        ", defined($h) ? $h : 'UNUSED', ",\n";
 | |
| }
 | |
| print OUT "    };\n";
 | |
| 
 | |
| print OUT "    static const int16_t hash2[$n] = {\n";
 | |
| for ($i = 0; $i < $n; $i++) {
 | |
|     my $h = ${$g}[$i*2+1];
 | |
|     print OUT "        ", defined($h) ? $h : 'UNUSED', ",\n";
 | |
| }
 | |
| print OUT "    };\n";
 | |
| 
 | |
| print OUT  "    uint32_t k1, k2;\n";
 | |
| print OUT  "    uint64_t crc;\n";
 | |
| # For correct overflow behavior, "ix" should be unsigned of the same
 | |
| # width as the hash arrays.
 | |
| print OUT  "    uint16_t ix;\n";
 | |
| print OUT  "\n";
 | |
| 
 | |
| printf OUT "    crc = crc64i(UINT64_C(0x%08x%08x), package);\n",
 | |
|     $$sv[0], $$sv[1];
 | |
| print  OUT "    k1 = (uint32_t)crc;\n";
 | |
| print  OUT "    k2 = (uint32_t)(crc >> 32);\n";
 | |
| print  OUT "\n";
 | |
| printf OUT "    ix = hash1[k1 & 0x%x] + hash2[k2 & 0x%x];\n", $n-1, $n-1;
 | |
| printf OUT "    if (ix >= %d)\n", scalar(@pkg_list);
 | |
| print OUT  "        return NULL;\n";
 | |
| print OUT  "\n";
 | |
| print OUT  "    if (nasm_stricmp(packages[ix].package, package))\n";
 | |
| print OUT  "        return NULL;\n";
 | |
| print OUT  "\n";
 | |
| print OUT  "    return packages[ix].macros;\n";
 | |
| print OUT  "}\n";
 | |
| 
 | |
| close(OUT);
 |