diff options
author | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
commit | fcedfddf00b3f994e4f4e40332ac7fc192c63244 (patch) | |
tree | 51d38e62c7bdfcc5f9a5e9435fe820c93cfc9a3d /vere/ext/nasm/macros/macros.pl |
claude is gud
Diffstat (limited to 'vere/ext/nasm/macros/macros.pl')
-rwxr-xr-x | vere/ext/nasm/macros/macros.pl | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/vere/ext/nasm/macros/macros.pl b/vere/ext/nasm/macros/macros.pl new file mode 100755 index 0000000..03a6486 --- /dev/null +++ b/vere/ext/nasm/macros/macros.pl @@ -0,0 +1,311 @@ +#!/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 'asm/pptok.ph'; + +use bytes; + +my $fname; +my $line = 0; +my $index = 0; +my $tasm_count = 0; +my @pname; + +# Default names for various bytes +for (my $o = 0; $o < 256; $o++) { + my $c = chr($o); + if ($o < 32 || $o > 126) { + $pname[$o] = sprintf("%d", $o); + } elsif ($c =~ /^[\'\"\\]$/) { + $pname[$o] = "\'\\".$c."\'"; + } else { + $pname[$o] = "\'".$c."\'"; + } +} + +# +# Print out a string as a character array +# +sub charcify(@) { + my $l = ''; + my ($c, $o); + my $space = 1; + my $quote = 0; + + foreach $o (unpack("C*", join('',@_))) { + $c = pack("C", $o); + if ($quote) { + if ($o == $quote) { + $quote = 0; + } + } elsif ($c =~ /^[\'\"\`]$/) { + $quote = $o; + } else { + if ($c eq ' ') { + next if ($space); + $o = 32; + $c = ' '; + $space = 1; + } elsif ($o < 32 || $o > 126) { + $space = 1; # Implicit space after compacted directive + } else { + $space = 0; + } + } + $l .= $pname[$o]; + $l .= ','; + } + return $l; +} + + +# +# Generate macros.c +# +open(OUT, '>', 'macros/macros.c') 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 \"outform.h\"\n"; +print OUT "\n"; + +my $name = undef; +my $npkg = 0; +my @pkg_list = (); +my %pkg_number = (); +my $pkg; +my @out_list = (); +my @std_list = (); +my $outfmt; +my $lastname; +my $z; + +my @pptok_list = sort { $pptok_hash{$a} <=> $pptok_hash{$b} } keys %pptok_hash; +my %pnum; + +foreach my $pt (@pptok_list) { + my $n = $pptok_hash{$pt}; + if ($pt !~ /[A-Z]/ && $n < 256-96) { + $n = ($n+128) & 255; + (my $et = $pt) =~ s/^\%/p_/; + printf OUT "#define %-24s %3d\n", $et, $n; + $pnum{$pt} = $n; + $pname[$n] = $et; + } +} +printf OUT "#define %-24s %3d\n\n", 'EOL', 127; + +foreach $args ( @ARGV ) { + my @file_list = glob ( $args ); + foreach $fname ( @file_list ) { + open(INPUT,'<', $fname) or die "$0: $fname: $!\n"; + while (<INPUT>) { + $line++; + chomp; + while (/^(.*)\\$/) { + $_ = $1; + $_ .= <INPUT>; + chomp; + $line++; + } + s/^\s*(([^\'\"\;]|\"[^\"]*\"|\'[^\']*\')*?)\s*(\;.*)?$/$1/; + s/\s+/ /g; + next if ($_ eq ''); + + if (m/^OUT:\s*(\S.*)$/) { + undef $pkg; + my @out_alias = split(/\s+/, $1); + if (defined($name)) { + printf OUT " /* %4d */ EOL\n", $index++; + print OUT "};\n#endif\n"; + undef $name; + } + $index = 0; + print OUT "\n"; + my $pfx = '#if'; + foreach my $al (@out_alias) { + print OUT $pfx, " defined(OF_\U${al}\E)"; + $pfx = ' ||'; + } + $name = $out_alias[0] . '_stdmac'; + print OUT "\nconst unsigned char ${name}[] = {\n"; + print OUT " /* From $fname */\n"; + $lastname = $fname; + } elsif (m/^STD:\s*(\S+)$/) { + undef $pkg; + my $std = $1; + if (defined($name)) { + printf OUT " /* %4d */ EOL\n", $index++; + print OUT "};\n#endif\n"; + undef $name; + } + $index = 0; + print OUT "\n#if 1"; + $name = 'nasm_stdmac_' . $std; + print OUT "\nconst unsigned char ${name}[] = {\n"; + print OUT " /* From $fname */\n"; + $lastname = $fname; + } elsif (m/^USE:\s*(\S+)$/) { + $pkg = $1; + if (defined($pkg_number{$pkg})) { + die "$0: $fname: duplicate package: $pkg\n"; + } + if (defined($name)) { + printf OUT " /* %4d */ EOL\n", $index++; + print OUT "};\n#endif\n"; + undef $name; + } + $index = 0; + print OUT "\n#if 1"; + $name = 'nasm_usemac_' . $pkg; + print OUT "\nstatic const unsigned char ${name}[] = {\n"; + print OUT " /* From $fname */\n"; + $lastname = $fname; + push(@pkg_list, $pkg); + $pkg_number{$pkg} = $npkg++; + $z = pack("C", $pnum{'%define'})."__?USE_\U$pkg\E?__"; + printf OUT " /* %4d */ %sEOL,\n", $index, charcify($z); + $z = pack("C", $pnum{'%defalias'})."__USE_\U$pkg\E__ __?USE\U$pkg\E?__"; + printf OUT " /* %4d */ %sEOL,\n", $index, charcify($z); + $index += length($z)+1; + } else { + my($s1, $s2, $pd, $ws); + + if (!defined($name)) { + die "$0: $fname: macro declarations outside a known block\n"; + } + + $s1 = $_; + $s2 = ''; + while ($s1 =~ /(\%[a-zA-Z_][a-zA-Z0-9_]*)((\s+)(.*)|)$/) { + $s2 .= "$'"; + $pd = $1; + $ws = $3; + $s1 = $4; + if (defined($pnum{$pd})) { + $s2 .= pack("C", $pnum{$pd}); + } 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 */ %sEOL,\n", + $index, charcify($s2); + $index += length($s2)+1; + } + } + } + close(INPUT); + } +} + +if (defined($name)) { + printf OUT " /* %4d */ EOL\n", $index++; + print OUT "};\n#endif\n"; + undef $name; +} + +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)); +$n <<= 1; + +printf OUT "const int use_package_count = %d;\n\n", $npkg; + +print OUT "const struct use_package *nasm_find_use_package(const char *name)\n"; +print OUT "{\n"; +print OUT " static const struct use_package packages[$npkg] = {\n"; +my $ix = 0; +foreach $pkg (@pkg_list) { + printf OUT " { \"%s\", nasm_usemac_%s, %d },\n", + $pkg, $pkg, $ix++; +} +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 INVALID_HASH_ENTRY (65535/3)\n"; + +print OUT " static const int16_t hashdata[$n] = {\n"; +for ($i = 0; $i < $n; $i++) { + my $h = ${$g}[$i]; + print OUT " ", defined($h) ? $h : 'INVALID_HASH_ENTRY', ",\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), name);\n", + $$sv[0], $$sv[1]; +printf OUT " k1 = ((uint32_t)crc & 0x%x) + 0;\n", $n-2; +printf OUT " k2 = ((uint32_t)(crc >> 32) & 0x%x) + 1;\n", $n-2; +print OUT "\n"; +printf OUT " ix = hashdata[k1] + hashdata[k2];\n"; +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, name))\n"; +print OUT " return NULL;\n"; +print OUT "\n"; +print OUT " return &packages[ix];\n"; +print OUT "}\n"; + +close(OUT); |