summaryrefslogtreecommitdiff
path: root/vere/ext/nasm/macros/macros.pl
diff options
context:
space:
mode:
Diffstat (limited to 'vere/ext/nasm/macros/macros.pl')
-rwxr-xr-xvere/ext/nasm/macros/macros.pl311
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);