From 47308e9797b1e9ff92ebbfc648dd04c123e273a7 Mon Sep 17 00:00:00 2001 From: Keith Kanios Date: Sat, 9 Apr 2011 22:18:47 -0500 Subject: initial branch of %pragma support --- Makefile.in | 95 +++++++++++++++------------ pptok.dat | 1 + preproc.c | 42 ++++++++++++ preproc.h | 4 ++ prtok.dat | 35 ++++++++++ prtok.pl | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 348 insertions(+), 42 deletions(-) create mode 100644 prtok.dat create mode 100755 prtok.pl diff --git a/Makefile.in b/Makefile.in index 8370d9af..98f40bc6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -72,9 +72,9 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \ output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \ output/outdbg.$(O) output/outieee.$(O) output/outmac32.$(O) \ output/outmac64.$(O) preproc.$(O) quote.$(O) pptok.$(O) \ - macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) \ - strfunc.$(O) tokhash.$(O) regvals.$(O) regflags.$(O) \ - ilog2.$(O) \ + prtok.$(O) macros.$(O) listing.$(O) eval.$(O) exprlib.$(O) \ + stdscan.$(O) strfunc.$(O) tokhash.$(O) regvals.$(O) \ + regflags.$(O) ilog2.$(O) \ lib/strlcpy.$(O) NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) ver.$(O) \ @@ -160,6 +160,14 @@ pptok.c: pptok.dat pptok.pl perllib/phash.ph pptok.ph: pptok.dat pptok.pl perllib/phash.ph $(PERL) $(srcdir)/pptok.pl ph $(srcdir)/pptok.dat pptok.ph +# Pragmas token hash +prtok.h: prtok.dat prtok.pl perllib/phash.ph + $(PERL) $(srcdir)/prtok.pl h $(srcdir)/prtok.dat prtok.h +prtok.c: prtok.dat prtok.pl perllib/phash.ph + $(PERL) $(srcdir)/prtok.pl c $(srcdir)/prtok.dat prtok.c +prtok.ph: prtok.dat prtok.pl perllib/phash.ph + $(PERL) $(srcdir)/prtok.pl ph $(srcdir)/prtok.dat prtok.ph + # Directives hash directiv.h: directiv.dat directiv.pl perllib/phash.ph $(PERL) $(srcdir)/directiv.pl h $(srcdir)/directiv.dat directiv.h @@ -171,6 +179,7 @@ directiv.c: directiv.dat directiv.pl perllib/phash.ph PERLREQ = macros.c insnsb.c insnsa.c insnsd.c insnsi.h insnsn.c \ regs.c regs.h regflags.c regdis.c regdis.h regvals.c \ tokhash.c tokens.h pptok.h pptok.c pptok.ph \ + prtok.h prtok.c prtok.ph \ directiv.c directiv.h \ version.h version.mac version.mak version.nsh perlreq: $(PERLREQ) @@ -272,71 +281,71 @@ alldeps: perlreq # @path-separator: "/" #-- Everything below is generated by mkdep.pl - do not edit --# assemble.$(O): assemble.c assemble.h compiler.h config.h directiv.h insns.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h tables.h \ + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tables.h \ tokens.h crc64.$(O): crc64.c compiler.h config.h nasmlib.h directiv.$(O): directiv.c compiler.h config.h directiv.h hashtbl.h insnsi.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h disasm.$(O): disasm.c compiler.h config.h directiv.h disasm.h insns.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regdis.h regs.h \ + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regdis.h regs.h \ sync.h tables.h tokens.h eval.$(O): eval.c compiler.h config.h directiv.h eval.h float.h insnsi.h \ - labels.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + labels.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h exprlib.$(O): exprlib.c compiler.h config.h directiv.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h float.$(O): float.c compiler.h config.h directiv.h float.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h hashtbl.$(O): hashtbl.c compiler.h config.h directiv.h hashtbl.h insnsi.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h ilog2.$(O): ilog2.c compiler.h config.h nasmlib.h insnsa.$(O): insnsa.c compiler.h config.h directiv.h insns.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h tokens.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tokens.h insnsb.$(O): insnsb.c compiler.h config.h directiv.h insns.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h tokens.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tokens.h insnsd.$(O): insnsd.c compiler.h config.h directiv.h insns.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h tokens.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tokens.h insnsn.$(O): insnsn.c compiler.h config.h insnsi.h opflags.h tables.h labels.$(O): labels.c compiler.h config.h directiv.h hashtbl.h insnsi.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h lib/snprintf.$(O): lib/snprintf.c compiler.h config.h nasmlib.h lib/strlcpy.$(O): lib/strlcpy.c compiler.h config.h lib/vsnprintf.$(O): lib/vsnprintf.c compiler.h config.h nasmlib.h listing.$(O): listing.c compiler.h config.h directiv.h insnsi.h listing.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h macros.$(O): macros.c compiler.h config.h directiv.h hashtbl.h insnsi.h \ - nasm.h nasmlib.h opflags.h output/outform.h pptok.h preproc.h regs.h \ + nasm.h nasmlib.h opflags.h output/outform.h pptok.h prtok.h preproc.h regs.h \ tables.h nasm.$(O): nasm.c assemble.h compiler.h config.h directiv.h eval.h float.h \ insns.h insnsi.h labels.h listing.h nasm.h nasmlib.h opflags.h \ - output/outform.h parser.h pptok.h preproc.h raa.h regs.h saa.h stdscan.h \ + output/outform.h parser.h pptok.h prtok.h preproc.h raa.h regs.h saa.h stdscan.h \ tokens.h nasmlib.$(O): nasmlib.c compiler.h config.h directiv.h insns.h insnsi.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h tokens.h + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tokens.h ndisasm.$(O): ndisasm.c compiler.h config.h directiv.h disasm.h insns.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h sync.h \ + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h sync.h \ tokens.h output/nulldbg.$(O): output/nulldbg.c compiler.h config.h directiv.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h output/nullout.$(O): output/nullout.c compiler.h config.h directiv.h \ - insnsi.h nasm.h nasmlib.h opflags.h output/outlib.h pptok.h preproc.h \ + insnsi.h nasm.h nasmlib.h opflags.h output/outlib.h pptok.h prtok.h preproc.h \ regs.h output/outaout.$(O): output/outaout.c compiler.h config.h directiv.h eval.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h raa.h regs.h saa.h stdscan.h + pptok.h prtok.h preproc.h raa.h regs.h saa.h stdscan.h output/outas86.$(O): output/outas86.c compiler.h config.h directiv.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h raa.h regs.h saa.h + pptok.h prtok.h preproc.h raa.h regs.h saa.h output/outbin.$(O): output/outbin.c compiler.h config.h directiv.h eval.h \ insnsi.h labels.h nasm.h nasmlib.h opflags.h output/outform.h \ - output/outlib.h pptok.h preproc.h regs.h saa.h stdscan.h + output/outlib.h pptok.h prtok.h preproc.h regs.h saa.h stdscan.h output/outcoff.$(O): output/outcoff.c compiler.h config.h directiv.h eval.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - output/pecoff.h pptok.h preproc.h raa.h regs.h saa.h + output/pecoff.h pptok.h prtok.h preproc.h raa.h regs.h saa.h output/outdbg.$(O): output/outdbg.c compiler.h config.h directiv.h insnsi.h \ - nasm.h nasmlib.h opflags.h output/outform.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h output/outform.h pptok.h prtok.h preproc.h regs.h output/outelf.$(O): output/outelf.c compiler.h config.h directiv.h insnsi.h \ nasm.h nasmlib.h opflags.h output/dwarf.h output/elf.h output/outelf.h \ - output/outform.h pptok.h preproc.h regs.h + output/outform.h pptok.h prtok.h preproc.h regs.h output/outelf32.$(O): output/outelf32.c compiler.h config.h directiv.h \ eval.h insnsi.h nasm.h nasmlib.h opflags.h output/dwarf.h output/elf.h \ output/outelf.h output/outform.h output/outlib.h output/stabs.h pptok.h \ @@ -346,49 +355,51 @@ output/outelf64.$(O): output/outelf64.c compiler.h config.h directiv.h \ output/outelf.h output/outform.h output/outlib.h output/stabs.h pptok.h \ preproc.h raa.h rbtree.h regs.h saa.h stdscan.h output/outform.$(O): output/outform.c compiler.h config.h directiv.h \ - insnsi.h nasm.h nasmlib.h opflags.h output/outform.h pptok.h preproc.h \ + insnsi.h nasm.h nasmlib.h opflags.h output/outform.h pptok.h prtok.h preproc.h \ regs.h output/outieee.$(O): output/outieee.c compiler.h config.h directiv.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h regs.h + pptok.h prtok.h preproc.h regs.h output/outlib.$(O): output/outlib.c compiler.h config.h directiv.h insnsi.h \ - nasm.h nasmlib.h opflags.h output/outlib.h pptok.h preproc.h regs.h + nasm.h nasmlib.h opflags.h output/outlib.h pptok.h prtok.h preproc.h regs.h output/outmac32.$(O): output/outmac32.c compiler.h config.h directiv.h \ eval.h insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h raa.h regs.h saa.h + pptok.h prtok.h preproc.h raa.h regs.h saa.h output/outmac64.$(O): output/outmac64.c compiler.h config.h directiv.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h raa.h regs.h saa.h + pptok.h prtok.h preproc.h raa.h regs.h saa.h output/outobj.$(O): output/outobj.c compiler.h config.h directiv.h eval.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h regs.h stdscan.h + pptok.h prtok.h preproc.h regs.h stdscan.h output/outrdf2.$(O): output/outrdf2.c compiler.h config.h directiv.h \ insnsi.h nasm.h nasmlib.h opflags.h output/outform.h output/outlib.h \ - pptok.h preproc.h rdoff/rdoff.h regs.h saa.h + pptok.h prtok.h preproc.h rdoff/rdoff.h regs.h saa.h parser.$(O): parser.c compiler.h config.h directiv.h eval.h float.h insns.h \ - insnsi.h nasm.h nasmlib.h opflags.h parser.h pptok.h preproc.h regs.h \ + insnsi.h nasm.h nasmlib.h opflags.h parser.h pptok.h prtok.h preproc.h regs.h \ stdscan.h tables.h tokens.h pptok.$(O): pptok.c compiler.h config.h hashtbl.h nasmlib.h pptok.h \ preproc.h +prtok.$(O): prtok.c compiler.h config.h hashtbl.h nasmlib.h prtok.h \ + preproc.h preproc.$(O): preproc.c compiler.h config.h directiv.h eval.h hashtbl.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h regs.h \ - stdscan.h tables.h tokens.h + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h prtok.h quote.h \ + regs.h stdscan.h tables.h tokens.h quote.$(O): quote.c compiler.h config.h nasmlib.h quote.h raa.$(O): raa.c compiler.h config.h nasmlib.h raa.h rbtree.$(O): rbtree.c compiler.h config.h rbtree.h regdis.$(O): regdis.c regdis.h regs.h regflags.$(O): regflags.c compiler.h config.h directiv.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h tables.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tables.h regs.$(O): regs.c compiler.h config.h insnsi.h opflags.h tables.h regvals.$(O): regvals.c compiler.h config.h insnsi.h opflags.h tables.h saa.$(O): saa.c compiler.h config.h nasmlib.h saa.h stdscan.$(O): stdscan.c compiler.h config.h directiv.h insns.h insnsi.h \ - nasm.h nasmlib.h opflags.h pptok.h preproc.h quote.h regs.h stdscan.h \ + nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h quote.h regs.h stdscan.h \ tokens.h strfunc.$(O): strfunc.c compiler.h config.h directiv.h insnsi.h nasm.h \ - nasmlib.h opflags.h pptok.h preproc.h regs.h + nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h sync.$(O): sync.c compiler.h config.h nasmlib.h sync.h tokhash.$(O): tokhash.c compiler.h config.h directiv.h hashtbl.h insns.h \ - insnsi.h nasm.h nasmlib.h opflags.h pptok.h preproc.h regs.h tokens.h + insnsi.h nasm.h nasmlib.h opflags.h pptok.h prtok.h preproc.h regs.h tokens.h ver.$(O): ver.c compiler.h config.h directiv.h insnsi.h nasm.h nasmlib.h \ - opflags.h pptok.h preproc.h regs.h version.h + opflags.h pptok.h prtok.h preproc.h regs.h version.h diff --git a/pptok.dat b/pptok.dat index 7680356a..88083118 100644 --- a/pptok.dat +++ b/pptok.dat @@ -83,6 +83,7 @@ %macro %pathsearch %pop +%pragma %push %rep %repl diff --git a/preproc.c b/preproc.c index 5fdeab26..96b1f250 100644 --- a/preproc.c +++ b/preproc.c @@ -2276,6 +2276,36 @@ static int parse_size(const char *str) { return sizes[bsii(str, size_names, ARRAY_SIZE(size_names))+1]; } +/** + * find and process pragma directive in passed line + * Find out if a line contains a pragma directive, and deal + * with it if so. + * + * @param tline a pointer to the current tokeninzed line linked list + * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND + * + */ +static int do_pragma(Token * tline) +{ + enum pragma_token i; + + i = pr_token_hash(tline->text); + + switch (i) { + case PR_INVALID: + error(ERR_NONFATAL, "unknown pragma directive `%s'", + tline->text); + return NO_DIRECTIVE_FOUND; /* didn't get it */ + + default: + error(ERR_FATAL, + "pragma directive `%s' not yet implemented", + pr_directives[i]); + return DIRECTIVE_FOUND; + + } +} + /** * find and process preprocessor directive in passed line * Find out if a line contains a preprocessor directive, and deal @@ -3903,6 +3933,18 @@ issue_error: free_tlist(origline); return DIRECTIVE_FOUND; + case PP_PRAGMA: + if (defining != NULL) return NO_DIRECTIVE_FOUND; + tline = tline->next; + skip_white_(tline); + if (tline == NULL) { + error(ERR_NONFATAL, "`%%pragma' expects at least one parameter"); + } else { + do_pragma(tline); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + default: error(ERR_FATAL, "preprocessor directive `%s' not yet implemented", diff --git a/preproc.h b/preproc.h index e48addae..8774d9d1 100644 --- a/preproc.h +++ b/preproc.h @@ -39,14 +39,18 @@ #define NASM_PREPROC_H #include "pptok.h" +#include "prtok.h" extern const char * const pp_directives[]; extern const uint8_t pp_directives_len[]; +extern const char * const pr_directives[]; +extern const uint8_t pr_directives_len[]; /* Pointer to a macro chain */ typedef const unsigned char macros_t; enum preproc_token pp_token_hash(const char *token); +enum pragma_token pr_token_hash(const char *token); void pp_include_path(char *); void pp_pre_include(char *); void pp_pre_define(char *); diff --git a/prtok.dat b/prtok.dat new file mode 100644 index 00000000..f91da024 --- /dev/null +++ b/prtok.dat @@ -0,0 +1,35 @@ +## -------------------------------------------------------------------------- +## +## Copyright 1996-2011 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. +## +## -------------------------------------------------------------------------- + +# pragmas.dat table of pragmas for the Netwide Assembler +replace diff --git a/prtok.pl b/prtok.pl new file mode 100755 index 00000000..3de5284b --- /dev/null +++ b/prtok.pl @@ -0,0 +1,213 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2011 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. +## +## -------------------------------------------------------------------------- + +# +# Produce prtok.c, prtok.h and prtok.ph from prtok.dat +# + +require 'phash.ph'; + +my($what, $in, $out) = @ARGV; + +# +# Read prtok.dat +# +open(IN, "< $in") or die "$0: cannot open: $in\n"; +while (defined($line = )) { + chomp $line; + $line =~ s/^\s+//; # Remove leading whitespace + $line =~ s/\s*\#.*$//; # Remove comments and trailing whitespace + next if ($line eq ''); + + if ($line =~ /^(.*)$/) { + push(@prtok, $1); + } +} +close(IN); + +@prtok = sort @prtok; + +open(OUT, "> $out") or die "$0: cannot open: $out\n"; + +# +# Output prtok.h +# +if ($what eq 'h') { + print OUT "/* Automatically generated from $in by $0 */\n"; + print OUT "/* Do not edit */\n"; + print OUT "\n"; + + print OUT "enum pragma_token {\n"; + $n = 0; + foreach $pt (@prtok) { + if (defined($pt)) { + printf OUT " %-16s = %3d,\n", "PR_\U$pt\E", $n; + } + $n++; + } + printf OUT " %-16s = %3d\n", 'PR_INVALID', -1; + print OUT "};\n"; + print OUT "\n"; +} + +# +# Output prtok.c +# +if ($what eq 'c') { + print OUT "/* Automatically generated from $in by $0 */\n"; + print OUT "/* Do not edit */\n"; + print OUT "\n"; + + my %tokens = (); + my @tokendata = (); + + my $n = 0; + foreach $pt (@prtok) { + if (defined($pt)) { + $tokens{'%'.$pt} = $n; + if ($pt =~ /[\@\[\]\\_]/) { + # Fail on characters which look like upper-case letters + # to the quick-and-dirty downcasing in the prehash + # (see below) + die "$in: invalid character in token: $pt"; + } + } + $n++; + } + + my @hashinfo = gen_perfect_hash(\%tokens); + if (!@hashinfo) { + die "$0: no hash found\n"; + } + + # Paranoia... + verify_hash_table(\%tokens, \@hashinfo); + + ($n, $sv, $g) = @hashinfo; + $sv2 = $sv+2; + + die if ($n & ($n-1)); + + print OUT "#include \"compiler.h\"\n"; + print OUT "#include \n"; + print OUT "#include \n"; + print OUT "#include \"nasmlib.h\"\n"; + print OUT "#include \"hashtbl.h\"\n"; + print OUT "#include \"preproc.h\"\n"; + print OUT "\n"; + + # Note that this is global. + printf OUT "const char * const pr_directives[%d] = {\n", scalar(@prtok); + foreach $d (@prtok) { + if (defined($d)) { + print OUT " \"$d\",\n"; + } else { + print OUT " NULL,\n"; + } + } + print OUT "};\n"; + + printf OUT "const uint8_t pr_directives_len[%d] = {\n", scalar(@prtok); + foreach $d (@prtok) { + printf OUT " %d,\n", defined($d) ? length($d)+1 : 0; + } + print OUT "};\n"; + + print OUT "enum pragma_token pr_token_hash(const char *token)\n"; + 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), token);\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(@prtok); + print OUT " return PR_INVALID;\n"; + print OUT "\n"; + + print OUT " if (!pr_directives[ix] || nasm_stricmp(pr_directives[ix], token))\n"; + print OUT " return PR_INVALID;\n"; + print OUT "\n"; + print OUT " return ix;\n"; + print OUT "}\n"; +} + +# +# Output prtok.ph +# +if ($what eq 'ph') { + print OUT "# Automatically generated from $in by $0\n"; + print OUT "# Do not edit\n"; + print OUT "\n"; + + print OUT "%prtok_hash = (\n"; + $n = 0; + foreach $tok (@prtok) { + if (defined($tok)) { + printf OUT " '%%%s' => %d,\n", $tok, $n; + } + $n++; + } + print OUT ");\n"; + print OUT "1;\n"; +} + + -- cgit v1.2.1