diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..8a398ac --- /dev/null +++ b/AUTHORS @@ -0,0 +1,137 @@ +This is the AUTHORS file for the NASM project located at: +http://nasm.sourceforge.net/ + +Names should be inserted as follows: + +N: Name Here +E: Email Here +D: Description Here +D: Additional Description Here.... and so on +C: Copyright information + +Such is life. +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +N: Julian Hall +E: Jules@acris.co.uk +D: Original author and co-conspirator + +N: Simon Tatham +E: anakin@pobox.com +D: Original author and co-conspirator + +N: Nelson Rush +E: palisade@users.sourceforge.net +D: Some guy. + +N: Frank Kotler +E: fbkotler@users.sf.net +D: Bug smashing. +D: Documentation - "KATMAI" and "3DNow!" instructions supported by 0.98 +D: General coordination and moral support. + +N: Stephen Silver +E: nasm@argentum.freeserve.co.uk +D: Documentation - "3dNow!" instructions and misc. +D: insns.dat fixes and new instructions. + +N: AMD Inc. (names of developers here?) +E: +D: 3DNow instructions +D: New Athlon instructions +D: Makefile.vc fix + +N: John Coffman +E: johninsd@users.sourceforge.net +D: added Jcc optimizations; CPU level checks +D: bug fixes, compilation fixes + +N: Yuri Zaporozhets +E: r_tty@yahoo.co.uk +D: RDOFF support + +N: H. Peter Anvin +E: hpa@zytor.com +D: Primary maintainer for the 0.98, late 0.98.x and 2.x releases. +C: Contributions since 2008-12-15 are Copyright Intel Corporation. + +N: John Fine +E: johnfine@earthlink.net +D: Preprocessor and OBJ (OMF) output format driver +D: Organized DOS versions of 0.98 release + +N: Kendall Bennet +E: KendallB@scitechsoft.com +D: NASM enhancements +D: macros +D: Syntax modifications + +N: Gary Clark +E: +D: AMD 3DNow! instructions + +N: Andrew Crabtree +E: +D: Debugging support + +N: Rafael R. Sevilla +E: dido@pacific.net.ph +D: RDF2HEX utility + +N: Jaime Tejedor Gómez, aka Metalbrain +E: metalbrain_coder@gmx.net +D: jecxz bug fix + +N: James Seter +E: pharos@zsnes.com +D: --POSTFIX, --PREFIX switches +D: ? + +N: Edward J. Beroset +E: beroset@mindspring.com +D: added %substr and %strlen + +N: Stanislav Karchebny, aka berkus, madfire, daemonhunter +E: madfire@users.sourceforge.net +D: multiple sections support for -fbin format +D: cvs maintenance +D: webpage at http://nasm.2y.net maintenance + +N: Debbie Wiles, aka debs +E: debs@dwiles.demon.co.uk +D: Work on docs, added undocumented instructions (esp SSE2 and 3D-Now!) +D: Added other documentation and tidied up docs +D: Added a few instructions to insns.dat and tidied it up. + +N: Trevor Woerner +E: FIXME +D: Quiet compiler warnings + +N: Michael K. Ter Louw +E: mterlo1 "at" uic "dot" edu +D: Multisection support for "-f bin" + +N: Martin Wawro +E: FIXME +D: stabs debug support for "-f elf" + +N: Alexei Frounze +E: alexfru@users.sourceforge.net +D: "-I" paths searched for "incbined" files +D: bugswatting + +N: Keith Kanios, aka SpooK +E: keith@kanios.net +D: c99 Compliance +D: General x64 Support +D: win64 (x86-64 COFF) output format +D: __BITS__ Standard Macro +D: Website Maintenance @ http://nasm.sourceforge.net/ + +N: Chuck Crayne +E: ccrayne@users.sourceforge.net +D: elf64 (x86_64) output format + +N: Cyrill Gorcunov +E: gorcunov@gmail.com +D: AMD XOP/FMA4/CVT16 instructions diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..b89696f --- /dev/null +++ b/CHANGES @@ -0,0 +1,2 @@ +The revision history has moved to the file doc/changes.src, and +is now included in the documentation as Appendix C. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..ff3befc --- /dev/null +++ b/ChangeLog @@ -0,0 +1,2905 @@ +Sat Nov 24 16:31:48 2007 -0800 H. Peter Anvin + * Typo fixes in documentation +Tue Nov 20 23:37:46 2007 -0800 H. Peter Anvin + * NASM 2.00rc3 +Tue Nov 20 21:45:16 2007 -0800 H. Peter Anvin + * Unbreak CMPSW/CMPSD/CMPSQ +Tue Nov 20 13:23:34 2007 -0800 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Tue Nov 20 13:22:58 2007 -0800 H. Peter Anvin + * ndisasm: handle the case of "no more sync points" +Mon Nov 19 23:09:31 2007 -0800 H. Peter Anvin + * NASM 2.00rc2 +Mon Nov 19 23:09:24 2007 -0800 H. Peter Anvin + * tag-release: a simple script to tag the repository for release +Mon Nov 19 13:14:59 2007 -0800 H. Peter Anvin + * Slightly faster implementation of the deadman counter +Mon Nov 19 12:26:50 2007 -0800 H. Peter Anvin + * BR 812417: Deadman counter for macro expansion +Mon Nov 19 12:02:38 2007 -0800 H. Peter Anvin + * BR 877583: Fix RAA memory leak +Mon Nov 19 11:53:18 2007 -0800 H. Peter Anvin + * BR 863173: Fix offsets of TIMES/INCBIN in list file +Mon Nov 19 11:45:40 2007 -0800 H. Peter Anvin + * BR 1834731: Remove redundant error messages for no input file +Mon Nov 19 11:44:05 2007 -0800 H. Peter Anvin + * insns.pl: remove debugging output +Sun Nov 18 22:18:09 2007 -0800 H. Peter Anvin + * Clean up remaining build warnings +Sun Nov 18 21:55:26 2007 -0800 H. Peter Anvin + * BR 1834292: Fix multiple disassembler bugs +Sun Nov 18 12:01:05 2007 -0800 H. Peter Anvin + * BR 1834056: Remove warnings in rdoff/rdoff.c +Sun Nov 18 11:55:10 2007 -0800 H. Peter Anvin + * BR 1091926: Bounds checking for command line parsing +Sat Nov 17 21:21:18 2007 -0800 H. Peter Anvin + * Remove FIXME from documentation +Sat Nov 17 21:08:33 2007 -0800 Charles Crayne + * Check in Keith's Fixes +Sat Nov 17 14:35:19 2007 -0800 H. Peter Anvin + * Make the definition for float_const() match the prototype +Fri Nov 16 00:03:02 2007 -0800 H. Peter Anvin + * NASM 2.00rc1 +Thu Nov 15 17:12:29 2007 -0800 H. Peter Anvin + * Clean up the command-line parsing; make -w/-W match others +Thu Nov 15 14:38:19 2007 -0800 H. Peter Anvin + * BR 993895: Support zero-operand floating-point insn +Thu Nov 15 10:25:52 2007 -0800 H. Peter Anvin + * Remove some vestiges of "native" RESW/RESD support +Thu Nov 15 10:24:55 2007 -0800 H. Peter Anvin + * outbin.c: fix one missed change from type -> size +Tue Nov 13 19:52:54 2007 -0800 root + * Support setting OSABI value in ELF header. +Tue Nov 13 11:34:34 2007 -0800 H. Peter Anvin + * Enable a few warnings by default; clean up warning descriptions +Tue Nov 13 11:31:15 2007 -0800 H. Peter Anvin + * Add gcc-style -W/-Wno- warning selections; -Wall; -Werror +Tue Nov 13 10:37:23 2007 -0800 H. Peter Anvin + * Clean up the fwrite*() function definitions somewhat +Tue Nov 13 09:49:51 2007 -0800 H. Peter Anvin + * Cast 64-bit switch expressions to (int) to keep OpenWatcom happy +Tue Nov 13 09:46:38 2007 -0800 H. Peter Anvin + * x86-host-specific performance improvement +Tue Nov 13 09:37:59 2007 -0800 H. Peter Anvin + * Address data is int64_t; simplify writing an address object +Mon Nov 12 23:00:31 2007 -0800 H. Peter Anvin + * ndisasm: factor out the common operand-extraction code +Mon Nov 12 22:56:07 2007 -0800 H. Peter Anvin + * Un-special-case "xchg rax,rax"; disassemble o64 +Mon Nov 12 22:11:46 2007 -0800 H. Peter Anvin + * BR 1709392: Fix alignment handling in Mach-O format +Mon Nov 12 22:05:31 2007 -0800 H. Peter Anvin + * BR 1828866: fix handling of LAR/LSL +Mon Nov 12 21:57:00 2007 -0800 H. Peter Anvin + * Better (but not *good!*) handling of 64-bit addressing in ndisasm +Mon Nov 12 21:02:33 2007 -0800 H. Peter Anvin + * Fix disassembly of XCHG +Mon Nov 12 20:18:33 2007 -0800 H. Peter Anvin + * Test of XCHG +Mon Nov 12 20:18:05 2007 -0800 H. Peter Anvin + * Fix handling of XCHG in 64-bit mode +Mon Nov 12 19:36:13 2007 -0800 H. Peter Anvin + * More \321 -> \324 bug fixes +Mon Nov 12 18:26:31 2007 -0800 H. Peter Anvin + * float.c: all warnings and errors are pass 1 only +Sat Nov 10 21:55:19 2007 -0800 Charles Crayne + * Update documentation for stack relative directives. +Sat Nov 10 17:52:23 2007 -0800 Charles Crayne + * Clean up a few more 32-bit bottlenecks +Fri Nov 9 16:37:41 2007 -0800 Charles Crayne + * Update documantation for stack relative directives +Fri Nov 9 16:33:54 2007 -0800 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Fri Nov 9 16:25:43 2007 -0800 Charles Crayne + * Update documentation for stack relative directives +Fri Nov 9 14:44:02 2007 -0800 H. Peter Anvin + * Don't combine type and size into a single argument +Thu Nov 8 22:11:14 2007 -0800 Charles Crayne + * Add flat64 to %stacksize choices +Thu Nov 8 20:43:22 2007 -0800 H. Peter Anvin + * Fix building under OpenWatcom +Thu Nov 8 20:29:37 2007 -0800 H. Peter Anvin + * ps2pdf: remove -dOptimize=true +Thu Nov 8 20:21:41 2007 -0800 H. Peter Anvin + * No binary files left in the source distro; unbreak release script +Thu Nov 8 20:01:11 2007 -0800 H. Peter Anvin + * BR 1828103: Fix %arg and %local +Thu Nov 8 19:34:01 2007 -0800 H. Peter Anvin + * nasmlib.c: prefix_name(): use the elements() macro +Thu Nov 8 19:30:22 2007 -0800 H. Peter Anvin + * Move elements() to nasmlib.h +Thu Nov 8 19:15:33 2007 -0800 H. Peter Anvin + * constipate the "str" argument to bsi() and bsii() +Wed Nov 7 19:03:46 2007 -0800 Charles Crayne + * Upgrade RAA functions to hold 64-bit data. +Tue Nov 6 21:48:12 2007 -0800 Charles Crayne + * Pass 64-bit instruction lengths to back-ends. +Tue Nov 6 18:27:23 2007 -0800 Charles Crayne + * Prepare for 64-bit instruction lengths +Mon Nov 5 21:49:49 2007 -0800 Charles Crayne + * Disambiguate error messages +Mon Nov 5 17:19:32 2007 -0800 Charles Crayne + * Upgrade label functions to 64-bit +Sun Nov 4 21:10:42 2007 -0800 H. Peter Anvin + * Permit opcode names as labels as long as they are followed by a colon +Sun Nov 4 15:28:30 2007 -0800 Charles Crayne + * Make warning limit valid for both i386 and x86_64 +Sat Nov 3 22:06:13 2007 -0700 Charles Crayne + * Warn on out of bounds EA displacements +Thu Nov 1 15:08:27 2007 -0700 H. Peter Anvin + * Treat info files as binary when creating xdoc distro file +Thu Nov 1 15:07:42 2007 -0700 H. Peter Anvin + * Remove obsolete binary files from the distribution +Thu Nov 1 14:53:32 2007 -0700 H. Peter Anvin + * Move declarations before statements +Wed Oct 31 23:37:35 2007 -0700 H. Peter Anvin + * NASM 0.99.06 +Wed Oct 31 23:37:19 2007 -0700 H. Peter Anvin + * Script to tag the tree for release +Wed Oct 31 10:59:26 2007 -0700 H. Peter Anvin + * Even more "riprel" tests +Tue Oct 30 01:17:57 2007 -0700 H. Peter Anvin + * floatx.asm: add tests for "rounds up to smallest denorm" +Tue Oct 30 01:13:27 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Tue Oct 30 01:13:09 2007 -0700 H. Peter Anvin + * float.c: handle round-up-to-denorm correctly. +Tue Oct 30 00:59:27 2007 -0700 H. Peter Anvin + * Exhaustive test for 8-bit floating point values +Mon Oct 29 23:12:47 2007 -0700 H. Peter Anvin + * Clean up the handing of operands in assemble.c +Mon Oct 29 22:56:08 2007 -0700 H. Peter Anvin + * Don't warn for segmented references +Mon Oct 29 20:20:12 2007 -0700 H. Peter Anvin + * Use a 32-bit floating-point limb size; support 8-bit float +Mon Oct 29 18:24:59 2007 -0700 Charles Crayne + * Reduce severity of redundant prefixes from error to warning. +Sun Oct 28 23:23:24 2007 -0700 H. Peter Anvin + * Test of some addressing modes in 64-bit mode. +Sun Oct 28 23:21:46 2007 -0700 H. Peter Anvin + * Fix bogus flagging of effective addresses as invalid +Sun Oct 28 23:10:34 2007 -0700 H. Peter Anvin + * Actually shut up the warning in rdfload.c +Sun Oct 28 22:04:42 2007 -0700 H. Peter Anvin + * Clean up stealth whitespace +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * Fix warning about cast to pointer in rdfload.c +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * 64-bit addressing and prefix handling changes +Sun Oct 28 15:29:54 2007 -0700 Charles Crayne + * Adjust stabs symbol index to match symbol table. +Fri Oct 26 21:38:02 2007 -0700 H. Peter Anvin + * readnum(): handle prefix-suffix collision like "0h" +Fri Oct 26 18:49:29 2007 -0700 H. Peter Anvin + * Better handling of platforms which hide "extended" functionality +Wed Oct 24 15:51:40 2007 -0700 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Wed Oct 24 15:30:17 2007 -0700 Charles Crayne + * Update sections about debug info formats +Wed Oct 24 15:29:51 2007 -0700 H. Peter Anvin + * Fix the handling of floating-point tokens in the preprocessor +Tue Oct 23 19:28:39 2007 -0700 Charles Crayne + * Fix bugs item #1817677 +Tue Oct 23 00:08:58 2007 -0700 H. Peter Anvin + * Slightly simplify the radix-detection code +Mon Oct 22 19:48:06 2007 -0700 H. Peter Anvin + * Unbreak particularly tricky hex constants +Mon Oct 22 19:37:36 2007 -0700 H. Peter Anvin + * Decimal floating point can also start with 0. 0e 0E +Mon Oct 22 17:34:10 2007 -0700 H. Peter Anvin + * Support binary and octal floating-point +Mon Oct 22 16:53:48 2007 -0700 H. Peter Anvin + * More consistent handling of radix letters +Sun Oct 21 15:33:01 2007 -0700 H. Peter Anvin + * float.c: correct exponent capping +Sun Oct 21 14:21:43 2007 -0700 Charles Crayne + * Clean up elf symbol table section +Fri Oct 19 18:33:57 2007 -0700 H. Peter Anvin + * Allow $-prefixed hexadecimal FP as an alternative to 0x +Fri Oct 19 14:43:22 2007 -0700 H. Peter Anvin + * Scripts to remove stealth whitespace +Fri Oct 19 14:42:29 2007 -0700 H. Peter Anvin + * Formatting: kill off "stealth whitespace" +Fri Oct 19 14:26:52 2007 -0700 H. Peter Anvin + * test/floatx.asm: fix test case +Fri Oct 19 14:19:52 2007 -0700 H. Peter Anvin + * uscore.asm: Fix test case +Fri Oct 19 14:17:51 2007 -0700 H. Peter Anvin + * float.c: mark read_exponent() static +Fri Oct 19 14:10:35 2007 -0700 H. Peter Anvin + * Don't confuse suffixed hexadecimal with floating-point +Fri Oct 19 13:17:24 2007 -0700 H. Peter Anvin + * Anchor filename locations in .gitignore +Fri Oct 19 13:16:51 2007 -0700 H. Peter Anvin + * test/Makefile: Use -Ox instead of -O999 +Fri Oct 19 13:14:06 2007 -0700 H. Peter Anvin + * Test of underscored constants +Fri Oct 19 13:10:46 2007 -0700 H. Peter Anvin + * Allow underscores in numbers; better detection of FP +Fri Oct 19 10:52:31 2007 -0700 H. Peter Anvin + * Modernize nasm.spec.in and make it closer to the Fedora version +Thu Oct 18 23:33:06 2007 -0700 Charles Crayne + * Suppress datarootdir warnings from configure +Thu Oct 18 21:17:20 2007 -0700 Charles Crayne + * Suppress signedness warnings in disassembler +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * Cleaner solution for MinGW handling of __STRICT_ANSI__ +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * configure: Undefine __STRICT_ANSI__ for mingw's benefit +Thu Oct 18 19:14:07 2007 -0700 H. Peter Anvin + * Fix invocation of readnum() +Thu Oct 18 19:02:42 2007 -0700 Charles Crayne + * Suppress a few signedness warnings +Thu Oct 18 17:04:10 2007 -0700 root + * Avoid unnecessary warning on redefinition of section (bug 801180) +Wed Oct 17 17:55:45 2007 -0700 Charles Crayne + * Generate stabs entries for any executable section +Tue Oct 16 22:59:09 2007 -0700 H. Peter Anvin + * NASM 0.99.05 +Tue Oct 16 15:46:04 2007 -0700 H. Peter Anvin + * Tests of obscenely large exponents +Tue Oct 16 14:42:32 2007 -0700 H. Peter Anvin + * Comma-separate contents of __FLOAT__ +Tue Oct 16 14:40:27 2007 -0700 H. Peter Anvin + * Implement floating-point option control directive +Tue Oct 16 11:48:07 2007 -0700 H. Peter Anvin + * Floating-point warning fixes; fix round-to-overflow +Tue Oct 16 11:32:58 2007 -0700 H. Peter Anvin + * Handle rounding of denorms correctly; make fp overflow a warning +Tue Oct 16 10:35:02 2007 -0700 H. Peter Anvin + * Additional entries for .gitignore +Tue Oct 16 10:32:57 2007 -0700 H. Peter Anvin + * Refactor floating-point formatting code; fix 80-bit denorms +Tue Oct 16 10:31:16 2007 -0700 H. Peter Anvin + * Add 1.5 as a test case: representative of an exact fraction +Mon Oct 15 20:06:06 2007 -0700 H. Peter Anvin + * Recognize 'd', 't' and 'y' as radix suffixes +Mon Oct 15 19:53:10 2007 -0700 H. Peter Anvin + * Fix FISTTP opcodes (BR 689695) +Mon Oct 15 19:46:32 2007 -0700 H. Peter Anvin + * New floating-point conversion routines +Mon Oct 15 17:48:43 2007 -0700 H. Peter Anvin + * Add testnos3 from the gdtoa package (floating-point test) +Sat Oct 13 23:19:21 2007 -0700 H. Peter Anvin + * .gitignore file doesn't need to be in the release file +Sat Oct 13 23:17:41 2007 -0700 H. Peter Anvin + * Add .gitignore file so "git status" produces something sane +Sat Oct 13 23:12:46 2007 -0700 H. Peter Anvin + * autoconf: drop AC_USE_SYSTEM_EXTENSIONS to support autoconf 2.59 +Sat Oct 13 07:09:22 2007 -0700 Keith Kanios + * Fix 32-bit types in preproc.c and eval.c +Thu Oct 11 20:32:33 2007 -0700 Charles Crayne + * Must define types before using them +Thu Oct 11 13:42:09 2007 -0700 H. Peter Anvin + * preproc.c: move smacro define/undef to separate functions +Thu Oct 11 13:38:38 2007 -0700 H. Peter Anvin + * preproc.c: PP_DEFINE and PP_XDEFINE are case-sensitive +Thu Oct 11 12:52:03 2007 -0700 H. Peter Anvin + * preproc.c: normalize the handling of case sensitivity +Thu Oct 11 12:51:06 2007 -0700 H. Peter Anvin + * Define macros necessary for on C++ +Thu Oct 11 10:12:58 2007 -0700 H. Peter Anvin + * More "bool" fixes +Thu Oct 11 10:11:57 2007 -0700 H. Peter Anvin + * preproc.c: allow 64-bit repeat counts +Thu Oct 11 10:06:19 2007 -0700 H. Peter Anvin + * preproc.c: For an SMacro, in_progress really is a boolean (no %rep) +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * Additional uses of bool and enum +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * preproc.c: MMacro.in_progress is not a boolean +Wed Oct 10 18:07:51 2007 -0700 H. Peter Anvin + * saa_fread/fwrite: when seeking, must set [rw]ptr as well +Wed Oct 10 14:58:45 2007 -0700 H. Peter Anvin + * Use the compiler-provided booleans if available, otherwise emulate +Wed Oct 10 14:55:14 2007 -0700 H. Peter Anvin + * owlinux.mak: don't clean things we won't be able to +Wed Oct 10 14:29:53 2007 -0700 H. Peter Anvin + * configure.in: looks like we need autoconf 2.61 :( +Wed Oct 10 14:06:59 2007 -0700 H. Peter Anvin + * Create option -Ox to tell NASM to do unlimited passes +Mon Oct 8 19:26:57 2007 -0700 H. Peter Anvin + * Revert "floatb.asm: fix broken testcase" +Mon Oct 8 18:39:24 2007 -0700 H. Peter Anvin + * floatb.asm: fix broken testcase +Mon Oct 8 12:41:00 2007 -0700 H. Peter Anvin + * saa_rstruct: fix overrun check +Mon Oct 8 12:12:23 2007 -0700 H. Peter Anvin + * Add Frank's floattest.asm test file +Sun Oct 7 21:13:14 2007 -0700 H. Peter Anvin + * saa_fpwrite: initializing "len" should be part of the loop +Sun Oct 7 18:46:57 2007 -0700 Charles Crayne + * Fix infinite loop in function saa_fpwrite +Fri Oct 5 17:44:16 2007 -0700 H. Peter Anvin + * zerobyte.asm: use a real instruction to avoid confusing ndisasm +Fri Oct 5 17:42:31 2007 -0700 H. Peter Anvin + * zerobyte.asm: add test cases for non-initial \170 uses +Fri Oct 5 17:29:01 2007 -0700 H. Peter Anvin + * Check in the proper zerobyte test +Fri Oct 5 17:04:32 2007 -0700 H. Peter Anvin + * Emit REX prefix before literal zero (\170) +Fri Oct 5 17:01:15 2007 -0700 H. Peter Anvin + * LICENSE: Break long line +Fri Oct 5 14:36:03 2007 -0700 H. Peter Anvin + * Add test for problematic floats +Thu Oct 4 23:51:08 2007 -0700 H. Peter Anvin + * floatx.asm: add Inf and NaN to the boundary condition tests +Thu Oct 4 23:09:19 2007 -0700 H. Peter Anvin + * floatx.asm: add specific tests for exponent boundary conditions +Thu Oct 4 22:51:08 2007 -0700 H. Peter Anvin + * float.c: correct the exponent +Thu Oct 4 15:18:23 2007 -0700 H. Peter Anvin + * Additional rules in test/Makefile +Thu Oct 4 13:42:56 2007 -0700 H. Peter Anvin + * Rewrite the handling of SAA's to allow random access +Wed Oct 3 21:30:57 2007 -0700 H. Peter Anvin + * Change cloc_t to struct location, and reorder the members +Wed Oct 3 21:24:51 2007 -0700 H. Peter Anvin + * BR 1352920: change loc_t -> cloc_t +Wed Oct 3 21:22:16 2007 -0700 H. Peter Anvin + * BR 1352920: Handle upper case %line +Wed Oct 3 17:40:12 2007 -0700 H. Peter Anvin + * Use autoconf to request feature macros +Tue Oct 2 22:04:15 2007 -0700 H. Peter Anvin + * preproc.c: constipation +Tue Oct 2 21:57:27 2007 -0700 H. Peter Anvin + * make alldeps +Tue Oct 2 21:53:51 2007 -0700 H. Peter Anvin + * Portability fixes +Tue Oct 2 21:13:18 2007 -0700 H. Peter Anvin + * Run "make alldeps". +Tue Oct 2 17:40:00 2007 -0700 H. Peter Anvin + * Use the crc64 we already use as the perfect hash function prehash +Tue Oct 2 15:09:33 2007 -0700 H. Peter Anvin + * insns.dat: add systematic names for the hinting NOPs (0F18-0F1F) +Mon Oct 1 11:28:32 2007 -0700 H. Peter Anvin + * Unspecified files are null strings, not null pointers +Mon Oct 1 11:26:31 2007 -0700 H. Peter Anvin + * Check for the most basic filename overlaps +Sun Sep 30 22:15:36 2007 -0700 Charles Crayne + * modified: nasm.1 to add newer command line options +Fri Sep 28 21:27:41 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 20:17:12 2007 -0700 H. Peter Anvin + * configure.in: AC_SUBST_FILE should have been AC_SUBST +Fri Sep 28 17:17:20 2007 -0700 H. Peter Anvin + * Unbreak relative references to immediate addresses +Fri Sep 28 15:16:47 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 12:01:55 2007 -0700 H. Peter Anvin + * lib/vsnprintf.c: correct boundary conditions +Fri Sep 28 10:50:20 2007 -0700 H. Peter Anvin + * Add substitutes for snprintf() and vsnprintf() +Fri Sep 28 02:03:41 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Thu Sep 27 21:35:04 2007 -0700 H. Peter Anvin + * Exclude config.h from the dependency list for the canned makefiles +Thu Sep 27 21:12:17 2007 -0700 H. Peter Anvin + * version.pl: Add support for daily snapshot releases +Thu Sep 27 19:46:55 2007 -0700 H. Peter Anvin + * Add Makefile for Linux -> DOS, Win32, OS/2 using OpenWatcom +Wed Sep 26 19:57:07 2007 -0700 H. Peter Anvin + * Add Makefile for OpenWatcom (DOS, OS/2 or Win32 output) +Wed Sep 26 17:00:18 2007 -0700 H. Peter Anvin + * Test for various addressing modes in 64-bit mode +Wed Sep 26 15:19:28 2007 -0700 H. Peter Anvin + * nasm option reshuffling, -E -> -Z +Tue Sep 25 23:57:21 2007 -0400 Frank Kotler + * Version 0.99.04 +Tue Sep 25 20:36:45 2007 -0700 H. Peter Anvin + * nasmdoc: corrections on 64-bit immediates/displacements +Tue Sep 25 16:02:21 2007 -0700 H. Peter Anvin + * nasmdoc: shorten lines which are too long +Tue Sep 25 16:01:07 2007 -0700 H. Peter Anvin + * Document NASM behaviour for 64-bit immediates and displacements +Tue Sep 25 15:44:40 2007 -0700 H. Peter Anvin + * test/movimm.asm: add optimizable forms +Tue Sep 25 15:41:19 2007 -0700 H. Peter Anvin + * assemble.c: clean up whitespace +Tue Sep 25 15:40:36 2007 -0700 H. Peter Anvin + * Correct the handling of "MOV" with immediate in 64-bit mode +Tue Sep 25 15:39:42 2007 -0700 H. Peter Anvin + * Test of immediate handling on 64-bit mode +Tue Sep 25 14:27:34 2007 -0700 H. Peter Anvin + * Add nasm_zalloc() to nasmlib.c +Tue Sep 25 14:26:03 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 14:11:29 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 13:34:55 2007 -0700 H. Peter Anvin + * Makefile.in: make "make install" create directories +Tue Sep 25 08:48:37 2007 -0700 H. Peter Anvin + * Fix BR 1445441: uninitialized use of "error_file" +Mon Sep 24 21:33:17 2007 -0700 H. Peter Anvin + * preproc.c: fix the loop in %undef +Mon Sep 24 20:53:48 2007 -0700 H. Peter Anvin + * float.c: clear off uninitialized warning +Mon Sep 24 17:02:41 2007 -0700 H. Peter Anvin + * outcoff: set the "virtual size field" to zero (BR 1351586) +Mon Sep 24 15:56:02 2007 -0700 H. Peter Anvin + * insns.dat: SMINT - mark ND, DMINT - fix opcode +Mon Sep 24 15:55:20 2007 -0700 H. Peter Anvin + * 0F0F is a 3Dnow! prefix; remove from prefix list +Mon Sep 24 15:48:09 2007 -0700 H. Peter Anvin + * Additional compaction missed by script +Mon Sep 24 15:42:53 2007 -0700 H. Peter Anvin + * insns.dat: machine-generated compaction mmx/xmmreg,mem -> mmx/xmmrm +Mon Sep 24 13:54:00 2007 -0700 H. Peter Anvin + * nasmdoc: grammar fix +Mon Sep 24 13:44:02 2007 -0700 H. Peter Anvin + * nasmdoc: remove stray periods +Mon Sep 24 13:42:09 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Mon Sep 24 13:41:58 2007 -0700 H. Peter Anvin + * Implement the -MG option (SF RFE 1564264) +Mon Sep 24 12:52:09 2007 -0700 H. Peter Anvin + * nasmdoc: clarify __float*__ example +Mon Sep 24 12:44:38 2007 -0700 H. Peter Anvin + * nasmdoc: document the __float*__ operators +Mon Sep 24 12:30:54 2007 -0700 H. Peter Anvin + * Support __float*__ for floating-point numbers in expressions +Mon Sep 24 10:51:07 2007 -0700 H. Peter Anvin + * eval.c: replace sequence of ifs with switch +Mon Sep 24 10:50:23 2007 -0700 H. Peter Anvin + * tokhash: allow a bit smarter pattern matching +Sat Sep 22 22:35:28 2007 -0700 H. Peter Anvin + * Implement INVLPGA according to the documentation +Sat Sep 22 22:02:34 2007 -0700 H. Peter Anvin + * Reformat insns.dat to uniform column width +Sat Sep 22 21:50:03 2007 -0700 H. Peter Anvin + * Simple test for 0x67 prefixes +Sat Sep 22 21:49:51 2007 -0700 H. Peter Anvin + * Auto-generate 0x67 prefixes without the need for \30x codes +Sat Sep 22 21:47:13 2007 -0700 H. Peter Anvin + * Make test/Makefile a bit more useful +Sat Sep 22 21:29:41 2007 -0700 H. Peter Anvin + * Add TY_OWORD for "DO" output +Sat Sep 22 19:52:11 2007 -0700 H. Peter Anvin + * LDDQU needs \301 (BR 1103549) +Sat Sep 22 19:51:13 2007 -0700 H. Peter Anvin + * RDTSCP and INVLPGA aren't 64-bit specific +Sat Sep 22 19:40:37 2007 -0700 H. Peter Anvin + * Cyrix GX1 instructions: BBx_RESET, CPU_READ, CPU_WRITE +Sat Sep 22 19:28:14 2007 -0700 H. Peter Anvin + * Centaur XSHA1, XSHA256, MONTMUL +Sat Sep 22 19:20:56 2007 -0700 H. Peter Anvin + * Implement Centaur's XCRYPT instructions +Sat Sep 22 19:13:05 2007 -0700 H. Peter Anvin + * Add Geode LX (AMD's Cyrix-derived core) instructions +Sat Sep 22 19:05:11 2007 -0700 H. Peter Anvin + * Add the GETSEC instruction for Intel SMX +Sat Sep 22 18:59:18 2007 -0700 H. Peter Anvin + * Add the AMD SSE4a and LZCNT instructions +Sat Sep 22 18:23:20 2007 -0700 H. Peter Anvin + * Tag UMOV as ND (no disassembly) to avoid collision +Sat Sep 22 18:20:49 2007 -0700 H. Peter Anvin + * Disallow optimizing by less than 5 passes. +Sat Sep 22 17:45:45 2007 -0700 H. Peter Anvin + * BR 1783117: Document that %+ needs a space after it, and fix crash +Sat Sep 22 16:44:56 2007 -0700 H. Peter Anvin + * nasm.spec.in: minor fixes +Sat Sep 22 16:38:25 2007 -0700 H. Peter Anvin + * release script: handle stricter CLI parsing for "git tag" +Sat Sep 22 16:35:11 2007 -0700 H. Peter Anvin + * Update nasm.spec.in and make it handle rc releases +Sat Sep 22 16:19:19 2007 -0700 H. Peter Anvin + * version.pl: support version numbers of the form X.Y[.Z]rcW +Thu Sep 20 21:33:43 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Thu Sep 20 21:12:33 2007 -0700 Charles Crayne + * modified: misc/release to fix bug in removing .git +Wed Sep 19 21:41:43 2007 -0700 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Wed Sep 19 21:41:27 2007 -0700 H. Peter Anvin + * Update manual pages +Wed Sep 19 21:41:02 2007 -0700 H. Peter Anvin + * Remove limit on number of sync points +Wed Sep 19 21:40:37 2007 -0700 H. Peter Anvin + * Make nasm_malloc() et al available from inside ndisasm +Wed Sep 19 21:07:32 2007 -0400 Frank Kotler + * Version 0.99.03 +Wed Sep 19 21:06:59 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Wed Sep 19 16:22:03 2007 -0700 H. Peter Anvin + * Merge commit 'origin/sse5' +Wed Sep 19 16:15:22 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Tue Sep 18 22:54:40 2007 -0700 H. Peter Anvin + * Slightly optimize the interface to nasm_token_hash() +Wed Sep 19 01:34:55 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Tue Sep 18 22:23:42 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 22:22:49 2007 -0700 H. Peter Anvin + * elf64: fix 32-bit truncations +Tue Sep 18 22:08:04 2007 -0700 H. Peter Anvin + * Document Infinity and NaN +Tue Sep 18 21:55:56 2007 -0700 H. Peter Anvin + * Support generating NaNs and infinities +Tue Sep 18 19:12:26 2007 -0700 H. Peter Anvin + * Update documentation +Tue Sep 18 18:37:36 2007 -0700 H. Peter Anvin + * Simple test for hexadecimal floating-point numbers +Tue Sep 18 18:33:17 2007 -0700 H. Peter Anvin + * Fix error-reporting in hexadecimal floating-point numbers +Tue Sep 18 18:31:26 2007 -0700 H. Peter Anvin + * Support C99-style hexadecimal floating point. +Tue Sep 18 17:50:34 2007 -0700 H. Peter Anvin + * Unify all standard IEEE floating-point formats; add 128-bit +Tue Sep 18 17:49:09 2007 -0700 H. Peter Anvin + * Fix handling of DO; support unary + for floating-point numbers +Tue Sep 18 16:39:03 2007 -0700 H. Peter Anvin + * Support 16-bit IEEE floating point; used in SSE5 +Tue Sep 18 15:43:40 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 15:43:08 2007 -0700 H. Peter Anvin + * Add NOP with argument to the instruction list +Tue Sep 18 15:24:38 2007 -0700 H. Peter Anvin + * Remove 0FC2 from list of instruction prefixes +Tue Sep 18 15:08:20 2007 -0700 H. Peter Anvin + * Speed up the disassembler by allowing prefixed instruction tables +Tue Sep 18 13:45:12 2007 -0700 H. Peter Anvin + * Document oword, do and reso +Tue Sep 18 13:01:32 2007 -0700 H. Peter Anvin + * Implement "oword" (128 bits) as a first-class size +Tue Sep 18 12:38:07 2007 -0700 H. Peter Anvin + * Change the token prehash function for better convergence +Tue Sep 18 12:23:21 2007 -0700 H. Peter Anvin + * SSE5 instruction table +Tue Sep 18 02:06:09 2007 -0400 Frank Kotler + * add "const" to output/outdbg.c +Mon Sep 17 18:45:44 2007 -0700 H. Peter Anvin + * Disassembler support for SSE5 instructions +Mon Sep 17 17:27:46 2007 -0700 H. Peter Anvin + * insns.dat: All SSE5 instructions are AMD +Mon Sep 17 17:25:27 2007 -0700 H. Peter Anvin + * Actually generate SSE5 instructions +Mon Sep 17 16:55:04 2007 -0700 H. Peter Anvin + * Initial support for generating DREX suffixes +Mon Sep 17 16:31:33 2007 -0700 H. Peter Anvin + * Fix a few instances of missing renumbers +Mon Sep 17 16:20:45 2007 -0700 H. Peter Anvin + * Enable IF_AR3 +Mon Sep 17 15:49:53 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Mon Sep 17 15:49:30 2007 -0700 H. Peter Anvin + * Initial support for four arguments per instruction +Mon Sep 17 15:48:32 2007 -0700 H. Peter Anvin + * CLFLUSH: Neither an x64 instruction nor AMD +Mon Sep 17 13:56:26 2007 -0700 H. Peter Anvin + * Sort dependency lists +Mon Sep 17 13:53:14 2007 -0700 H. Peter Anvin + * Cleaner way to handle MSVC's _snprintf() underscore damage +Mon Sep 17 13:19:25 2007 -0700 H. Peter Anvin + * test/r13.asm: test special-casing of rbp and r13 in 64-bit mode +Mon Sep 17 13:03:33 2007 -0700 H. Peter Anvin + * Additional documentation for 64-bit programming +Sun Sep 16 22:27:07 2007 -0700 H. Peter Anvin + * INSTALL: MSVC++ compilation instructions +Sun Sep 16 22:17:29 2007 -0700 H. Peter Anvin + * make alldeps: change Mkfiles/Makefile.* to Mkfiles/*.mak +Sun Sep 16 22:16:24 2007 -0700 H. Peter Anvin + * Fix Makefile for MSVC++ 2005, delete obsolete Makefiles +Sun Sep 16 22:15:34 2007 -0700 H. Peter Anvin + * Minor fixes needed to compile with MSVC++ 2005 +Sun Sep 16 18:35:02 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Sun Sep 16 18:04:57 2007 -0700 H. Peter Anvin + * Switch the preprocessor over to using the hash table library +Sun Sep 16 17:53:17 2007 -0700 H. Peter Anvin + * Fix the handling of local labels +Fri Sep 14 18:36:01 2007 -0700 H. Peter Anvin + * preproc.c: remove unnecessary int64_t +Fri Sep 14 18:03:29 2007 -0700 H. Peter Anvin + * Use the new hash table function library to store labels +Fri Sep 14 09:24:38 2007 -0700 H. Peter Anvin + * Define a proper hash table library +Thu Sep 13 18:13:20 2007 -0700 H. Peter Anvin + * Simple performance benchmarks: label, macro and token lookups +Thu Sep 13 12:25:32 2007 -0700 H. Peter Anvin + * release script: fix final cleanup +Thu Sep 13 12:22:00 2007 -0700 H. Peter Anvin + * Modify release script for a git-centric world +Thu Sep 13 11:06:42 2007 -0700 H. Peter Anvin + * pptok.c: don't insist on C99 compiler behaviour +Wed Sep 12 22:02:06 2007 -0700 H. Peter Anvin + * Fix literal F2 and F3 prefixes +Wed Sep 12 21:58:51 2007 -0700 H. Peter Anvin + * Add (untested!) SSSE3, SSE4.1, SSE4.2 instructions +Wed Sep 12 21:06:36 2007 -0700 H. Peter Anvin + * Add support for Tejas New Instructions (SSSE3) +Wed Sep 12 21:05:06 2007 -0700 H. Peter Anvin + * Remove $Id$ tags (useless with git) +Wed Sep 12 21:04:58 2007 -0700 H. Peter Anvin + * Use rm32 operands for VMREAD/VMWRITE +Wed Sep 12 21:04:51 2007 -0700 H. Peter Anvin + * Macros for SSSE3/SSE4 instruction sets +Wed Sep 12 21:04:39 2007 -0700 H. Peter Anvin + * Support r/m operands for non-integer types +Wed Sep 12 20:27:41 2007 -0700 H. Peter Anvin + * Use enumerations where practical to ease debugging +Wed Sep 12 17:02:55 2007 +0000 H. Peter Anvin + * pptok.c: quick-and-dirty downcasing during prehashing +Wed Sep 12 16:55:57 2007 +0000 H. Peter Anvin + * phash: Tell the user when the graph is OK +Wed Sep 12 05:18:20 2007 +0000 H. Peter Anvin + * pptok.c: handle holes in the pp_directives array +Wed Sep 12 04:20:08 2007 +0000 H. Peter Anvin + * preproc.c: adjust whitespace +Wed Sep 12 04:18:37 2007 +0000 H. Peter Anvin + * More automation in the preprocessor conditionals handling +Wed Sep 12 02:13:39 2007 +0000 H. Peter Anvin + * pptok.c: fix spacing +Wed Sep 12 02:12:07 2007 +0000 H. Peter Anvin + * Generate automatically correct tests for %if and %elif +Wed Sep 12 01:34:19 2007 +0000 H. Peter Anvin + * Run "make alldeps"; add dependencies missing from the previous checkin +Wed Sep 12 01:29:43 2007 +0000 H. Peter Anvin + * Use a perfect hash to look up preprocessor directives +Wed Sep 12 01:27:53 2007 +0000 H. Peter Anvin + * phash: Be a bit more aggressive about trying to make a small hash +Wed Sep 12 00:22:29 2007 +0000 H. Peter Anvin + * Add RCXZ as a known preprocessor condition +Tue Sep 11 23:57:23 2007 +0000 H. Peter Anvin + * doc: add some cross-references +Tue Sep 11 23:52:01 2007 +0000 H. Peter Anvin + * Feeble attempt at updating the documentation; remove Appendix B +Tue Sep 11 22:44:03 2007 +0000 H. Peter Anvin + * Handle instructions which can have both REX.W and OSP +Tue Sep 11 22:14:18 2007 +0000 H. Peter Anvin + * Use enums to make debugging easier +Tue Sep 11 22:13:17 2007 +0000 H. Peter Anvin + * ndisasm: handle \366 codes, prefer unprefixed instructions +Tue Sep 11 22:00:34 2007 +0000 H. Peter Anvin + * Simplify tokens.dat slightly +Tue Sep 11 04:26:44 2007 +0000 H. Peter Anvin + * Quiet gcc warning about uninitialized variables +Tue Sep 11 04:16:57 2007 +0000 H. Peter Anvin + * Make the big instruction arrays "const" +Mon Sep 10 23:32:05 2007 +0000 H. Peter Anvin + * Use an actual enum for the opcode +Mon Sep 10 23:30:21 2007 +0000 H. Peter Anvin + * Fix order of token arguments +Mon Sep 10 18:59:26 2007 +0000 H. Peter Anvin + * assemble.c: correct special handing of ESP/RSP +Mon Sep 10 18:59:01 2007 +0000 H. Peter Anvin + * tokhash: correct duplicate-token test +Mon Sep 10 18:58:40 2007 +0000 H. Peter Anvin + * tokhash: adjust table types to reduce size +Mon Sep 10 18:55:52 2007 +0000 H. Peter Anvin + * Fix the MMXREG and XMMREG flags definitions. +Wed Sep 5 06:48:38 2007 +0000 H. Peter Anvin + * nasm.spec.in: Copyright -> License +Wed Sep 5 06:40:51 2007 +0000 H. Peter Anvin + * Fix "make tar"; useful for RPM testing +Wed Sep 5 06:24:43 2007 +0000 H. Peter Anvin + * Remove obsolete Serial: construct; we shouldn't need it anyway. +Tue Sep 4 01:29:43 2007 +0000 Chuck Crayne + * Provide 64-bit support for ORG directive +Sun Sep 2 16:37:03 2007 +0000 H. Peter Anvin + * Fix some MMX/SSE irregularities which interact with the 64-bit support +Sun Sep 2 14:46:00 2007 +0000 H. Peter Anvin + * phash.ph: yet another attempt at getting Perl to behave, arithmetically +Sun Sep 2 06:23:29 2007 +0000 H. Peter Anvin + * Simple 64-bit org test +Sun Sep 2 06:20:15 2007 +0000 H. Peter Anvin + * phash.ph: remove some stale code +Sun Sep 2 01:00:34 2007 +0000 Chuck Crayne + * Force use of integer values for generating hash keys. +Fri Aug 31 18:10:23 2007 +0000 H. Peter Anvin + * phash: don't rely on the build platform Perl version of rand() +Fri Aug 31 07:31:51 2007 +0000 H. Peter Anvin + * tokhash.pl: formatting changes for readability +Fri Aug 31 07:23:31 2007 +0000 H. Peter Anvin + * tokhash: Speed up the rejection of unhashed values +Fri Aug 31 06:06:17 2007 +0000 H. Peter Anvin + * tokhash.pl: "ix" should have the same width as the "hash" arrays +Fri Aug 31 00:28:35 2007 +0000 H. Peter Anvin + * Add "do not edit" comment to tokhash.c +Fri Aug 31 00:23:40 2007 +0000 H. Peter Anvin + * Make the token hash a bit smaller by using 16-bit hash tables +Fri Aug 31 00:16:10 2007 +0000 H. Peter Anvin + * Minor cleanup; remove duplication of names.c +Thu Aug 30 23:42:39 2007 +0000 H. Peter Anvin + * phash.ph: use a bipartite graph to reduce the storage requirements +Thu Aug 30 22:35:34 2007 +0000 H. Peter Anvin + * Finishing touches on perfect hash tokenizer; actually turn the thing on +Thu Aug 30 21:50:20 2007 +0000 H. Peter Anvin + * Makefile rule for tokhash.c +Thu Aug 30 21:47:46 2007 +0000 H. Peter Anvin + * tokens.dat: Data file containing alphanumeric tokens not in other .dats +Thu Aug 30 21:45:56 2007 +0000 H. Peter Anvin + * Generate a perfect hash for the token parser +Thu Aug 30 21:40:08 2007 +0000 H. Peter Anvin + * Fix bugs in repeated suffix handling, which led to missing r8d/r8w/r8d +Thu Aug 30 21:39:37 2007 +0000 H. Peter Anvin + * phash.ph: more powerful prehashing +Thu Aug 30 20:15:25 2007 +0000 H. Peter Anvin + * Make the perfect hash generator an includable module +Wed Aug 29 20:30:31 2007 +0000 H. Peter Anvin + * Correct the logic for recording fs: and gs: overrides. +Wed Aug 29 18:20:19 2007 +0000 H. Peter Anvin + * Generate R_X86_64_64 relocations in elf64 output +Wed Aug 29 17:24:03 2007 +0000 H. Peter Anvin + * Add README file +Wed Aug 29 17:20:09 2007 +0000 H. Peter Anvin + * Create a Perl library directory, and add the Graph module to it +Wed Aug 29 17:05:17 2007 +0000 H. Peter Anvin + * Perfect hash generator, as a perl script +Wed Aug 29 16:41:43 2007 +0000 H. Peter Anvin + * Use standard macro for the default directive +Wed Aug 29 16:40:26 2007 +0000 H. Peter Anvin + * Add standard macro for [default] directive +Wed Aug 29 16:38:47 2007 +0000 H. Peter Anvin + * More test cases for rel and abs addressing +Wed Aug 29 16:38:05 2007 +0000 H. Peter Anvin + * Add [default] directive +Wed Aug 29 16:25:46 2007 +0000 H. Peter Anvin + * nasmlib: add bsii() case-insensitive version of bsi() +Wed Aug 29 15:49:53 2007 +0000 H. Peter Anvin + * Add test cases for IP-relative addressing +Wed Aug 29 15:19:19 2007 +0000 H. Peter Anvin + * Suppress IP-relative only for fs: and gs: overrides +Tue Aug 28 23:06:00 2007 +0000 H. Peter Anvin + * Implement REL/ABS modifiers +Sun Aug 26 05:51:39 2007 +0000 Frank Kotler + * attempt to make static makefiles aware of outelf32/outelf64 +Sun Aug 26 05:48:54 2007 +0000 Frank Kotler + * add nasm_strsep to nasmlib, for output/outmacho.c - strtok doesn't work +Sun Aug 26 05:41:33 2007 +0000 Frank Kotler + * remove "#include from rdoff directory - two places - it annoyed Windows users and seems unneeded +Sun Aug 26 05:10:24 2007 +0000 Frank Kotler + * finally commit Mike Frysinger's "elf-visibility" patch +Mon Aug 20 21:03:14 2007 +0000 H. Peter Anvin + * regs.pl: handle dashed sequences with suffixes +Mon Aug 20 20:10:04 2007 +0000 H. Peter Anvin + * sync.c: change ULONG_MAX to UINT32_MAX +Mon Aug 20 20:09:11 2007 +0000 H. Peter Anvin + * Add _MIN and _MAX macros for the fixed-size types. +Mon Aug 20 20:02:17 2007 +0000 H. Peter Anvin + * ldrdf: cast output of sizeof() before passing to printf(), to avoid warning. +Sun Aug 19 18:49:26 2007 +0000 Keith Kanios + * Fixed RIP address processing ambiguity found by Charles Crayne. +Fri Aug 17 07:37:52 2007 +0000 Keith Kanios + * Fixed issues with REX prefix effective address generation. Fixed XMM instruction output. +Fri Aug 17 02:03:10 2007 +0000 Keith Kanios + * Changed MMXREG and XMMREG flags to help resolve invalid REX prefix generation for MMX instructions. +Sat Jul 7 02:01:08 2007 +0000 H. Peter Anvin + * More int/int32_t confusion +Sat Jul 7 01:59:52 2007 +0000 H. Peter Anvin + * regflag() should return int32_t. +Thu Jun 21 19:00:12 2007 +0000 H. Peter Anvin + * Detect missing and include ersatz version if missing +Thu Jun 21 06:24:23 2007 +0000 H. Peter Anvin + * inttypes.h: for older preprocessors, specify L and LL as appropriate +Thu Jun 21 06:20:43 2007 +0000 H. Peter Anvin + * inttypes.h: Fix spelling of SHRT_MAX +Thu Jun 21 06:15:42 2007 +0000 H. Peter Anvin + * inttypes.h: do a single ersatz based on +Sun Jun 3 02:42:41 2007 +0000 Chuck Crayne + * Support 32-bit direct addressing in 64-bit mode without base or index regs +Sat Jun 2 02:26:21 2007 +0000 H. Peter Anvin + * Fix the [U]INT*_C() creation macros +Sat Jun 2 00:05:35 2007 +0000 H. Peter Anvin + * For platforms that don't have them, provide for common models. +Wed May 30 22:21:11 2007 +0000 H. Peter Anvin + * Fix the handling of the \313 code. +Wed May 30 22:20:01 2007 +0000 H. Peter Anvin + * Machine-generated \321->\324 corrections +Wed May 30 21:22:33 2007 +0000 Frank Kotler + * update "version" to 0.99.02 +Wed May 30 20:30:15 2007 +0000 H. Peter Anvin + * Correct the generation of 67 prefixes. +Wed May 30 18:30:18 2007 +0000 H. Peter Anvin + * Update dependencies. +Wed May 30 16:34:29 2007 +0000 Frank Kotler + * update cvs server name in misc/release script +Wed May 30 04:28:50 2007 +0000 H. Peter Anvin + * Avoid magic values; we have more than 124 registers now +Wed May 30 04:27:58 2007 +0000 H. Peter Anvin + * Remove bogus redundant tests +Wed May 30 03:44:50 2007 +0000 H. Peter Anvin + * More \321 -> \324 +Wed May 30 03:44:02 2007 +0000 H. Peter Anvin + * Remove bogus check for 64-bitness +Wed May 30 03:25:21 2007 +0000 H. Peter Anvin + * Get rid of magic open-coded "register numbers" +Wed May 30 02:48:51 2007 +0000 H. Peter Anvin + * MOV reg64,reg64 takes \324 (64 bit with REX) not \321 (32 bit) +Wed May 30 00:18:26 2007 +0000 H. Peter Anvin + * Rename REGNORM to REG_EA +Wed May 30 00:15:25 2007 +0000 H. Peter Anvin + * More instruction flag surgery +Wed May 30 00:05:00 2007 +0000 H. Peter Anvin + * More cleanup of operand flags/register classes +Tue May 29 23:57:12 2007 +0000 H. Peter Anvin + * Clean up the existing operand flag definitions, and document +Tue May 29 21:44:55 2007 +0000 H. Peter Anvin + * Run "make alldeps" +Thu May 24 22:33:07 2007 +0000 Frank Kotler + * update version number to 0.99.01 +Tue May 15 04:33:43 2007 +0000 H. Peter Anvin + * regs.dat: fix comment +Fri May 4 18:47:16 2007 +0000 H. Peter Anvin + * 16-bit relocations are standard in ELF64 (at my request, incidentally) +Fri May 4 02:16:08 2007 +0000 Chuck Crayne + * Addition of elf32 and elf64 output formats. +Wed May 2 04:21:26 2007 +0000 Chuck Crayne + * Allow '!' to be used in expressions with same meaning as in C. +Wed May 2 01:59:16 2007 +0000 Chuck Crayne + * Add %IFN and %ELIFN as per RFE #786286 +Mon Apr 30 22:26:58 2007 +0000 Chuck Crayne + * Accept responsibility for support of outelf64.c +Sun Apr 29 20:57:53 2007 +0000 Chuck Crayne + * Clarify comments about relocation entries. +Sun Apr 29 00:28:24 2007 +0000 Chuck Crayne + * Allow ELF32 to be invoked either as -f elf or -f elf32 +Sat Apr 28 22:18:04 2007 +0000 Chuck Crayne + * Eliminate shift count warnings when building on 32-bit systems +Sat Apr 28 06:18:48 2007 +0000 Chuck Crayne + * Initial support for ELF64 +Wed Apr 18 02:27:18 2007 +0000 H. Peter Anvin + * Fix the handling of \324 for computing the length +Wed Apr 18 02:24:34 2007 +0000 Keith Kanios + * Fixed RDF/2 to comply with "maxbits" use. +Tue Apr 17 20:23:11 2007 +0000 H. Peter Anvin + * Handle "LOCK as REX.R" for MOV CRx; fix warning for invalid 64-bit regs +Mon Apr 16 18:16:46 2007 +0000 Keith Kanios + * MEM_OFFSET Instructions Fixed. +Mon Apr 16 15:46:46 2007 +0000 Keith Kanios + * Fixed 64-bit Mode Segment Selection. +Mon Apr 16 14:31:54 2007 +0000 Keith Kanios + * Fixed distinction between [LOCAL]SYMBOL/IMMEDIATE for RIP-relative addressing. +Mon Apr 16 14:05:01 2007 +0000 Keith Kanios + * Fixed long mode MEM_OFFS issue. +Mon Apr 16 13:54:49 2007 +0000 Keith Kanios + * Filled in all RIP Register Flags. +Mon Apr 16 05:26:29 2007 +0000 H. Peter Anvin + * More \321 -> \324 for 64-bit instructions +Mon Apr 16 04:56:06 2007 +0000 Keith Kanios + * Fixed 64-bit offset generation. +Mon Apr 16 02:39:56 2007 +0000 H. Peter Anvin + * More 64-bit ndisasm fixes. +Mon Apr 16 02:02:06 2007 +0000 H. Peter Anvin + * Fixes for 64-bit ndisasm. +Mon Apr 16 01:21:29 2007 +0000 H. Peter Anvin + * Use + instead of * for extension; it feels cleaner with the new meaning. +Mon Apr 16 01:18:30 2007 +0000 H. Peter Anvin + * Initial 64-bit support for ndisasm. Still a work in progress. +Sun Apr 15 23:12:17 2007 +0000 H. Peter Anvin + * Clean up the 64-bitification of regs.dat for 64-bit ndisasm support +Sun Apr 15 23:10:26 2007 +0000 H. Peter Anvin + * Remove @GCCFLAGS@ +Sun Apr 15 23:09:23 2007 +0000 H. Peter Anvin + * CR8 is not special in any way as far as the assembler is concerned. +Sun Apr 15 23:03:28 2007 +0000 H. Peter Anvin Sat Nov 24 16:31:48 2007 -0800 H. Peter Anvin + * Typo fixes in documentation +Tue Nov 20 23:37:46 2007 -0800 H. Peter Anvin + * NASM 2.00rc3 +Tue Nov 20 21:45:16 2007 -0800 H. Peter Anvin + * Unbreak CMPSW/CMPSD/CMPSQ +Tue Nov 20 13:23:34 2007 -0800 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Tue Nov 20 13:22:58 2007 -0800 H. Peter Anvin + * ndisasm: handle the case of "no more sync points" +Mon Nov 19 23:09:31 2007 -0800 H. Peter Anvin + * NASM 2.00rc2 +Mon Nov 19 23:09:24 2007 -0800 H. Peter Anvin + * tag-release: a simple script to tag the repository for release +Mon Nov 19 13:14:59 2007 -0800 H. Peter Anvin + * Slightly faster implementation of the deadman counter +Mon Nov 19 12:26:50 2007 -0800 H. Peter Anvin + * BR 812417: Deadman counter for macro expansion +Mon Nov 19 12:02:38 2007 -0800 H. Peter Anvin + * BR 877583: Fix RAA memory leak +Mon Nov 19 11:53:18 2007 -0800 H. Peter Anvin + * BR 863173: Fix offsets of TIMES/INCBIN in list file +Mon Nov 19 11:45:40 2007 -0800 H. Peter Anvin + * BR 1834731: Remove redundant error messages for no input file +Mon Nov 19 11:44:05 2007 -0800 H. Peter Anvin + * insns.pl: remove debugging output +Sun Nov 18 22:18:09 2007 -0800 H. Peter Anvin + * Clean up remaining build warnings +Sun Nov 18 21:55:26 2007 -0800 H. Peter Anvin + * BR 1834292: Fix multiple disassembler bugs +Sun Nov 18 12:01:05 2007 -0800 H. Peter Anvin + * BR 1834056: Remove warnings in rdoff/rdoff.c +Sun Nov 18 11:55:10 2007 -0800 H. Peter Anvin + * BR 1091926: Bounds checking for command line parsing +Sat Nov 17 21:21:18 2007 -0800 H. Peter Anvin + * Remove FIXME from documentation +Sat Nov 17 21:08:33 2007 -0800 Charles Crayne + * Check in Keith's Fixes +Sat Nov 17 14:35:19 2007 -0800 H. Peter Anvin + * Make the definition for float_const() match the prototype +Fri Nov 16 00:03:02 2007 -0800 H. Peter Anvin + * NASM 2.00rc1 +Thu Nov 15 17:12:29 2007 -0800 H. Peter Anvin + * Clean up the command-line parsing; make -w/-W match others +Thu Nov 15 14:38:19 2007 -0800 H. Peter Anvin + * BR 993895: Support zero-operand floating-point insn +Thu Nov 15 10:25:52 2007 -0800 H. Peter Anvin + * Remove some vestiges of "native" RESW/RESD support +Thu Nov 15 10:24:55 2007 -0800 H. Peter Anvin + * outbin.c: fix one missed change from type -> size +Tue Nov 13 19:52:54 2007 -0800 root + * Support setting OSABI value in ELF header. +Tue Nov 13 11:34:34 2007 -0800 H. Peter Anvin + * Enable a few warnings by default; clean up warning descriptions +Tue Nov 13 11:31:15 2007 -0800 H. Peter Anvin + * Add gcc-style -W/-Wno- warning selections; -Wall; -Werror +Tue Nov 13 10:37:23 2007 -0800 H. Peter Anvin + * Clean up the fwrite*() function definitions somewhat +Tue Nov 13 09:49:51 2007 -0800 H. Peter Anvin + * Cast 64-bit switch expressions to (int) to keep OpenWatcom happy +Tue Nov 13 09:46:38 2007 -0800 H. Peter Anvin + * x86-host-specific performance improvement +Tue Nov 13 09:37:59 2007 -0800 H. Peter Anvin + * Address data is int64_t; simplify writing an address object +Mon Nov 12 23:00:31 2007 -0800 H. Peter Anvin + * ndisasm: factor out the common operand-extraction code +Mon Nov 12 22:56:07 2007 -0800 H. Peter Anvin + * Un-special-case "xchg rax,rax"; disassemble o64 +Mon Nov 12 22:11:46 2007 -0800 H. Peter Anvin + * BR 1709392: Fix alignment handling in Mach-O formatSat Nov 24 16:31:48 2007 -0800 H. Peter Anvin + * Typo fixes in documentation +Tue Nov 20 23:37:46 2007 -0800 H. Peter Anvin + * NASM 2.00rc3 +Tue Nov 20 21:45:16 2007 -0800 H. Peter Anvin + * Unbreak CMPSW/CMPSD/CMPSQ +Tue Nov 20 13:23:34 2007 -0800 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Tue Nov 20 13:22:58 2007 -0800 H. Peter Anvin + * ndisasm: handle the case of "no more sync points" +Mon Nov 19 23:09:31 2007 -0800 H. Peter Anvin + * NASM 2.00rc2 +Mon Nov 19 23:09:24 2007 -0800 H. Peter Anvin + * tag-release: a simple script to tag the repository for release +Mon Nov 19 13:14:59 2007 -0800 H. Peter Anvin + * Slightly faster implementation of the deadman counter +Mon Nov 19 12:26:50 2007 -0800 H. Peter Anvin + * BR 812417: Deadman counter for macro expansion +Mon Nov 19 12:02:38 2007 -0800 H. Peter Anvin + * BR 877583: Fix RAA memory leak +Mon Nov 19 11:53:18 2007 -0800 H. Peter Anvin + * BR 863173: Fix offsets of TIMES/INCBIN in list file +Mon Nov 19 11:45:40 2007 -0800 H. Peter Anvin + * BR 1834731: Remove redundant error messages for no input file +Mon Nov 19 11:44:05 2007 -0800 H. Peter Anvin + * insns.pl: remove debugging output +Sun Nov 18 22:18:09 2007 -0800 H. Peter Anvin + * Clean up remaining build warnings +Sun Nov 18 21:55:26 2007 -0800 H. Peter Anvin + * BR 1834292: Fix multiple disassembler bugs +Sun Nov 18 12:01:05 2007 -0800 H. Peter Anvin + * BR 1834056: Remove warnings in rdoff/rdoff.c +Sun Nov 18 11:55:10 2007 -0800 H. Peter Anvin + * BR 1091926: Bounds checking for command line parsing +Sat Nov 17 21:21:18 2007 -0800 H. Peter Anvin + * Remove FIXME from documentation +Sat Nov 17 21:08:33 2007 -0800 Charles Crayne + * Check in Keith's Fixes +Sat Nov 17 14:35:19 2007 -0800 H. Peter Anvin + * Make the definition for float_const() match the prototype +Fri Nov 16 00:03:02 2007 -0800 H. Peter Anvin + * NASM 2.00rc1 +Thu Nov 15 17:12:29 2007 -0800 H. Peter Anvin + * Clean up the command-line parsing; make -w/-W match others +Thu Nov 15 14:38:19 2007 -0800 H. Peter Anvin + * BR 993895: Support zero-operand floating-point insn +Thu Nov 15 10:25:52 2007 -0800 H. Peter Anvin + * Remove some vestiges of "native" RESW/RESD support +Thu Nov 15 10:24:55 2007 -0800 H. Peter Anvin + * outbin.c: fix one missed change from type -> size +Tue Nov 13 19:52:54 2007 -0800 root + * Support setting OSABI value in ELF header. +Tue Nov 13 11:34:34 2007 -0800 H. Peter Anvin + * Enable a few warnings by default; clean up warning descriptions +Tue Nov 13 11:31:15 2007 -0800 H. Peter Anvin + * Add gcc-style -W/-Wno- warning selections; -Wall; -Werror +Tue Nov 13 10:37:23 2007 -0800 H. Peter Anvin + * Clean up the fwrite*() function definitions somewhat +Tue Nov 13 09:49:51 2007 -0800 H. Peter Anvin + * Cast 64-bit switch expressions to (int) to keep OpenWatcom happy +Tue Nov 13 09:46:38 2007 -0800 H. Peter Anvin + * x86-host-specific performance improvement +Tue Nov 13 09:37:59 2007 -0800 H. Peter Anvin + * Address data is int64_t; simplify writing an address object +Mon Nov 12 23:00:31 2007 -0800 H. Peter Anvin + * ndisasm: factor out the common operand-extraction code +Mon Nov 12 22:56:07 2007 -0800 H. Peter Anvin + * Un-special-case "xchg rax,rax"; disassemble o64 +Mon Nov 12 22:11:46 2007 -0800 H. Peter Anvin + * BR 1709392: Fix alignment handling in Mach-O format +Mon Nov 12 22:05:31 2007 -0800 H. Peter Anvin + * BR 1828866: fix handling of LAR/LSL +Mon Nov 12 21:57:00 2007 -0800 H. Peter Anvin + * Better (but not *good!*) handling of 64-bit addressing in ndisasm +Mon Nov 12 21:02:33 2007 -0800 H. Peter Anvin + * Fix disassembly of XCHG +Mon Nov 12 20:18:33 2007 -0800 H. Peter Anvin + * Test of XCHG +Mon Nov 12 20:18:05 2007 -0800 H. Peter Anvin + * Fix handling of XCHG in 64-bit mode +Mon Nov 12 19:36:13 2007 -0800 H. Peter Anvin + * More \321 -> \324 bug fixes +Mon Nov 12 18:26:31 2007 -0800 H. Peter Anvin + * float.c: all warnings and errors are pass 1 only +Sat Nov 10 21:55:19 2007 -0800 Charles Crayne + * Update documentation for stack relative directives. +Sat Nov 10 17:52:23 2007 -0800 Charles Crayne + * Clean up a few more 32-bit bottlenecks +Fri Nov 9 16:37:41 2007 -0800 Charles Crayne + * Update documantation for stack relative directives +Fri Nov 9 16:33:54 2007 -0800 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Fri Nov 9 16:25:43 2007 -0800 Charles Crayne + * Update documentation for stack relative directives +Fri Nov 9 14:44:02 2007 -0800 H. Peter Anvin + * Don't combine type and size into a single argument +Thu Nov 8 22:11:14 2007 -0800 Charles Crayne + * Add flat64 to %stacksize choices +Thu Nov 8 20:43:22 2007 -0800 H. Peter Anvin + * Fix building under OpenWatcom +Thu Nov 8 20:29:37 2007 -0800 H. Peter Anvin + * ps2pdf: remove -dOptimize=true +Thu Nov 8 20:21:41 2007 -0800 H. Peter Anvin + * No binary files left in the source distro; unbreak release script +Thu Nov 8 20:01:11 2007 -0800 H. Peter Anvin + * BR 1828103: Fix %arg and %local +Thu Nov 8 19:34:01 2007 -0800 H. Peter Anvin + * nasmlib.c: prefix_name(): use the elements() macro +Thu Nov 8 19:30:22 2007 -0800 H. Peter Anvin + * Move elements() to nasmlib.h +Thu Nov 8 19:15:33 2007 -0800 H. Peter Anvin + * constipate the "str" argument to bsi() and bsii() +Wed Nov 7 19:03:46 2007 -0800 Charles Crayne + * Upgrade RAA functions to hold 64-bit data. +Tue Nov 6 21:48:12 2007 -0800 Charles Crayne + * Pass 64-bit instruction lengths to back-ends. +Tue Nov 6 18:27:23 2007 -0800 Charles Crayne + * Prepare for 64-bit instruction lengths +Mon Nov 5 21:49:49 2007 -0800 Charles Crayne + * Disambiguate error messages +Mon Nov 5 17:19:32 2007 -0800 Charles Crayne + * Upgrade label functions to 64-bit +Sun Nov 4 21:10:42 2007 -0800 H. Peter Anvin + * Permit opcode names as labels as long as they are followed by a colon +Sun Nov 4 15:28:30 2007 -0800 Charles Crayne + * Make warning limit valid for both i386 and x86_64 +Sat Nov 3 22:06:13 2007 -0700 Charles Crayne + * Warn on out of bounds EA displacements +Thu Nov 1 15:08:27 2007 -0700 H. Peter Anvin + * Treat info files as binary when creating xdoc distro file +Thu Nov 1 15:07:42 2007 -0700 H. Peter Anvin + * Remove obsolete binary files from the distribution +Thu Nov 1 14:53:32 2007 -0700 H. Peter Anvin + * Move declarations before statements +Wed Oct 31 23:37:35 2007 -0700 H. Peter Anvin + * NASM 0.99.06 +Wed Oct 31 23:37:19 2007 -0700 H. Peter Anvin + * Script to tag the tree for release +Wed Oct 31 10:59:26 2007 -0700 H. Peter Anvin + * Even more "riprel" tests +Tue Oct 30 01:17:57 2007 -0700 H. Peter Anvin + * floatx.asm: add tests for "rounds up to smallest denorm" +Tue Oct 30 01:13:27 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Tue Oct 30 01:13:09 2007 -0700 H. Peter Anvin + * float.c: handle round-up-to-denorm correctly. +Tue Oct 30 00:59:27 2007 -0700 H. Peter Anvin + * Exhaustive test for 8-bit floating point values +Mon Oct 29 23:12:47 2007 -0700 H. Peter Anvin + * Clean up the handing of operands in assemble.c +Mon Oct 29 22:56:08 2007 -0700 H. Peter Anvin + * Don't warn for segmented references +Mon Oct 29 20:20:12 2007 -0700 H. Peter Anvin + * Use a 32-bit floating-point limb size; support 8-bit float +Mon Oct 29 18:24:59 2007 -0700 Charles Crayne + * Reduce severity of redundant prefixes from error to warning. +Sun Oct 28 23:23:24 2007 -0700 H. Peter Anvin + * Test of some addressing modes in 64-bit mode. +Sun Oct 28 23:21:46 2007 -0700 H. Peter Anvin + * Fix bogus flagging of effective addresses as invalid +Sun Oct 28 23:10:34 2007 -0700 H. Peter Anvin + * Actually shut up the warning in rdfload.c +Sun Oct 28 22:04:42 2007 -0700 H. Peter Anvin + * Clean up stealth whitespace +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * Fix warning about cast to pointer in rdfload.c +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * 64-bit addressing and prefix handling changes +Sun Oct 28 15:29:54 2007 -0700 Charles Crayne + * Adjust stabs symbol index to match symbol table. +Fri Oct 26 21:38:02 2007 -0700 H. Peter Anvin + * readnum(): handle prefix-suffix collision like "0h" +Fri Oct 26 18:49:29 2007 -0700 H. Peter Anvin + * Better handling of platforms which hide "extended" functionality +Wed Oct 24 15:51:40 2007 -0700 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Wed Oct 24 15:30:17 2007 -0700 Charles Crayne + * Update sections about debug info formats +Wed Oct 24 15:29:51 2007 -0700 H. Peter Anvin + * Fix the handling of floating-point tokens in the preprocessor +Tue Oct 23 19:28:39 2007 -0700 Charles Crayne + * Fix bugs item #1817677 +Tue Oct 23 00:08:58 2007 -0700 H. Peter Anvin + * Slightly simplify the radix-detection code +Mon Oct 22 19:48:06 2007 -0700 H. Peter Anvin + * Unbreak particularly tricky hex constants +Mon Oct 22 19:37:36 2007 -0700 H. Peter Anvin + * Decimal floating point can also start with 0. 0e 0E +Mon Oct 22 17:34:10 2007 -0700 H. Peter Anvin + * Support binary and octal floating-point +Mon Oct 22 16:53:48 2007 -0700 H. Peter Anvin + * More consistent handling of radix letters +Sun Oct 21 15:33:01 2007 -0700 H. Peter Anvin + * float.c: correct exponent capping +Sun Oct 21 14:21:43 2007 -0700 Charles Crayne + * Clean up elf symbol table section +Fri Oct 19 18:33:57 2007 -0700 H. Peter Anvin + * Allow $-prefixed hexadecimal FP as an alternative to 0x +Fri Oct 19 14:43:22 2007 -0700 H. Peter Anvin + * Scripts to remove stealth whitespace +Fri Oct 19 14:42:29 2007 -0700 H. Peter Anvin + * Formatting: kill off "stealth whitespace" +Fri Oct 19 14:26:52 2007 -0700 H. Peter Anvin + * test/floatx.asm: fix test case +Fri Oct 19 14:19:52 2007 -0700 H. Peter Anvin + * uscore.asm: Fix test case +Fri Oct 19 14:17:51 2007 -0700 H. Peter Anvin + * float.c: mark read_exponent() static +Fri Oct 19 14:10:35 2007 -0700 H. Peter Anvin + * Don't confuse suffixed hexadecimal with floating-point +Fri Oct 19 13:17:24 2007 -0700 H. Peter Anvin + * Anchor filename locations in .gitignore +Fri Oct 19 13:16:51 2007 -0700 H. Peter Anvin + * test/Makefile: Use -Ox instead of -O999 +Fri Oct 19 13:14:06 2007 -0700 H. Peter Anvin + * Test of underscored constants +Fri Oct 19 13:10:46 2007 -0700 H. Peter Anvin + * Allow underscores in numbers; better detection of FP +Fri Oct 19 10:52:31 2007 -0700 H. Peter Anvin + * Modernize nasm.spec.in and make it closer to the Fedora version +Thu Oct 18 23:33:06 2007 -0700 Charles Crayne + * Suppress datarootdir warnings from configure +Thu Oct 18 21:17:20 2007 -0700 Charles Crayne + * Suppress signedness warnings in disassembler +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * Cleaner solution for MinGW handling of __STRICT_ANSI__ +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * configure: Undefine __STRICT_ANSI__ for mingw's benefit +Thu Oct 18 19:14:07 2007 -0700 H. Peter Anvin + * Fix invocation of readnum() +Thu Oct 18 19:02:42 2007 -0700 Charles Crayne + * Suppress a few signedness warnings +Thu Oct 18 17:04:10 2007 -0700 root + * Avoid unnecessary warning on redefinition of section (bug 801180) +Wed Oct 17 17:55:45 2007 -0700 Charles Crayne + * Generate stabs entries for any executable section +Tue Oct 16 22:59:09 2007 -0700 H. Peter Anvin + * NASM 0.99.05 +Tue Oct 16 15:46:04 2007 -0700 H. Peter Anvin + * Tests of obscenely large exponents +Tue Oct 16 14:42:32 2007 -0700 H. Peter Anvin + * Comma-separate contents of __FLOAT__ +Tue Oct 16 14:40:27 2007 -0700 H. Peter Anvin + * Implement floating-point option control directive +Tue Oct 16 11:48:07 2007 -0700 H. Peter Anvin + * Floating-point warning fixes; fix round-to-overflow +Tue Oct 16 11:32:58 2007 -0700 H. Peter Anvin + * Handle rounding of denorms correctly; make fp overflow a warning +Tue Oct 16 10:35:02 2007 -0700 H. Peter Anvin + * Additional entries for .gitignore +Tue Oct 16 10:32:57 2007 -0700 H. Peter Anvin + * Refactor floating-point formatting code; fix 80-bit denorms +Tue Oct 16 10:31:16 2007 -0700 H. Peter Anvin + * Add 1.5 as a test case: representative of an exact fraction +Mon Oct 15 20:06:06 2007 -0700 H. Peter Anvin + * Recognize 'd', 't' and 'y' as radix suffixes +Mon Oct 15 19:53:10 2007 -0700 H. Peter Anvin + * Fix FISTTP opcodes (BR 689695) +Mon Oct 15 19:46:32 2007 -0700 H. Peter Anvin + * New floating-point conversion routines +Mon Oct 15 17:48:43 2007 -0700 H. Peter Anvin + * Add testnos3 from the gdtoa package (floating-point test) +Sat Oct 13 23:19:21 2007 -0700 H. Peter Anvin + * .gitignore file doesn't need to be in the release file +Sat Oct 13 23:17:41 2007 -0700 H. Peter Anvin + * Add .gitignore file so "git status" produces something sane +Sat Oct 13 23:12:46 2007 -0700 H. Peter Anvin + * autoconf: drop AC_USE_SYSTEM_EXTENSIONS to support autoconf 2.59 +Sat Oct 13 07:09:22 2007 -0700 Keith Kanios + * Fix 32-bit types in preproc.c and eval.c +Thu Oct 11 20:32:33 2007 -0700 Charles Crayne + * Must define types before using them +Thu Oct 11 13:42:09 2007 -0700 H. Peter Anvin + * preproc.c: move smacro define/undef to separate functions +Thu Oct 11 13:38:38 2007 -0700 H. Peter Anvin + * preproc.c: PP_DEFINE and PP_XDEFINE are case-sensitive +Thu Oct 11 12:52:03 2007 -0700 H. Peter Anvin + * preproc.c: normalize the handling of case sensitivity +Thu Oct 11 12:51:06 2007 -0700 H. Peter Anvin + * Define macros necessary for on C++ +Thu Oct 11 10:12:58 2007 -0700 H. Peter Anvin + * More "bool" fixes +Thu Oct 11 10:11:57 2007 -0700 H. Peter Anvin + * preproc.c: allow 64-bit repeat counts +Thu Oct 11 10:06:19 2007 -0700 H. Peter Anvin + * preproc.c: For an SMacro, in_progress really is a boolean (no %rep) +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * Additional uses of bool and enum +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * preproc.c: MMacro.in_progress is not a boolean +Wed Oct 10 18:07:51 2007 -0700 H. Peter Anvin + * saa_fread/fwrite: when seeking, must set [rw]ptr as well +Wed Oct 10 14:58:45 2007 -0700 H. Peter Anvin + * Use the compiler-provided booleans if available, otherwise emulate +Wed Oct 10 14:55:14 2007 -0700 H. Peter Anvin + * owlinux.mak: don't clean things we won't be able to +Wed Oct 10 14:29:53 2007 -0700 H. Peter Anvin + * configure.in: looks like we need autoconf 2.61 :( +Wed Oct 10 14:06:59 2007 -0700 H. Peter Anvin + * Create option -Ox to tell NASM to do unlimited passes +Mon Oct 8 19:26:57 2007 -0700 H. Peter Anvin + * Revert "floatb.asm: fix broken testcase" +Mon Oct 8 18:39:24 2007 -0700 H. Peter Anvin + * floatb.asm: fix broken testcase +Mon Oct 8 12:41:00 2007 -0700 H. Peter Anvin + * saa_rstruct: fix overrun check +Mon Oct 8 12:12:23 2007 -0700 H. Peter Anvin + * Add Frank's floattest.asm test file +Sun Oct 7 21:13:14 2007 -0700 H. Peter Anvin + * saa_fpwrite: initializing "len" should be part of the loop +Sun Oct 7 18:46:57 2007 -0700 Charles Crayne + * Fix infinite loop in function saa_fpwrite +Fri Oct 5 17:44:16 2007 -0700 H. Peter Anvin + * zerobyte.asm: use a real instruction to avoid confusing ndisasm +Fri Oct 5 17:42:31 2007 -0700 H. Peter Anvin + * zerobyte.asm: add test cases for non-initial \170 uses +Fri Oct 5 17:29:01 2007 -0700 H. Peter Anvin + * Check in the proper zerobyte test +Fri Oct 5 17:04:32 2007 -0700 H. Peter Anvin + * Emit REX prefix before literal zero (\170) +Fri Oct 5 17:01:15 2007 -0700 H. Peter Anvin + * LICENSE: Break long line +Fri Oct 5 14:36:03 2007 -0700 H. Peter Anvin + * Add test for problematic floats +Thu Oct 4 23:51:08 2007 -0700 H. Peter Anvin + * floatx.asm: add Inf and NaN to the boundary condition tests +Thu Oct 4 23:09:19 2007 -0700 H. Peter Anvin + * floatx.asm: add specific tests for exponent boundary conditions +Thu Oct 4 22:51:08 2007 -0700 H. Peter Anvin + * float.c: correct the exponent +Thu Oct 4 15:18:23 2007 -0700 H. Peter Anvin + * Additional rules in test/Makefile +Thu Oct 4 13:42:56 2007 -0700 H. Peter Anvin + * Rewrite the handling of SAA's to allow random access +Wed Oct 3 21:30:57 2007 -0700 H. Peter Anvin + * Change cloc_t to struct location, and reorder the members +Wed Oct 3 21:24:51 2007 -0700 H. Peter Anvin + * BR 1352920: change loc_t -> cloc_t +Wed Oct 3 21:22:16 2007 -0700 H. Peter Anvin + * BR 1352920: Handle upper case %line +Wed Oct 3 17:40:12 2007 -0700 H. Peter Anvin + * Use autoconf to request feature macros +Tue Oct 2 22:04:15 2007 -0700 H. Peter Anvin + * preproc.c: constipation +Tue Oct 2 21:57:27 2007 -0700 H. Peter Anvin + * make alldeps +Tue Oct 2 21:53:51 2007 -0700 H. Peter Anvin + * Portability fixes +Tue Oct 2 21:13:18 2007 -0700 H. Peter Anvin + * Run "make alldeps". +Tue Oct 2 17:40:00 2007 -0700 H. Peter Anvin + * Use the crc64 we already use as the perfect hash function prehash +Tue Oct 2 15:09:33 2007 -0700 H. Peter Anvin + * insns.dat: add systematic names for the hinting NOPs (0F18-0F1F) +Mon Oct 1 11:28:32 2007 -0700 H. Peter Anvin + * Unspecified files are null strings, not null pointers +Mon Oct 1 11:26:31 2007 -0700 H. Peter Anvin + * Check for the most basic filename overlaps +Sun Sep 30 22:15:36 2007 -0700 Charles Crayne + * modified: nasm.1 to add newer command line options +Fri Sep 28 21:27:41 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 20:17:12 2007 -0700 H. Peter Anvin + * configure.in: AC_SUBST_FILE should have been AC_SUBST +Fri Sep 28 17:17:20 2007 -0700 H. Peter Anvin + * Unbreak relative references to immediate addresses +Fri Sep 28 15:16:47 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 12:01:55 2007 -0700 H. Peter Anvin + * lib/vsnprintf.c: correct boundary conditions +Fri Sep 28 10:50:20 2007 -0700 H. Peter Anvin + * Add substitutes for snprintf() and vsnprintf() +Fri Sep 28 02:03:41 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Thu Sep 27 21:35:04 2007 -0700 H. Peter Anvin + * Exclude config.h from the dependency list for the canned makefiles +Thu Sep 27 21:12:17 2007 -0700 H. Peter Anvin + * version.pl: Add support for daily snapshot releases +Thu Sep 27 19:46:55 2007 -0700 H. Peter Anvin + * Add Makefile for Linux -> DOS, Win32, OS/2 using OpenWatcom +Wed Sep 26 19:57:07 2007 -0700 H. Peter Anvin + * Add Makefile for OpenWatcom (DOS, OS/2 or Win32 output) +Wed Sep 26 17:00:18 2007 -0700 H. Peter Anvin + * Test for various addressing modes in 64-bit mode +Wed Sep 26 15:19:28 2007 -0700 H. Peter Anvin + * nasm option reshuffling, -E -> -Z +Tue Sep 25 23:57:21 2007 -0400 Frank Kotler + * Version 0.99.04 +Tue Sep 25 20:36:45 2007 -0700 H. Peter Anvin + * nasmdoc: corrections on 64-bit immediates/displacements +Tue Sep 25 16:02:21 2007 -0700 H. Peter Anvin + * nasmdoc: shorten lines which are too long +Tue Sep 25 16:01:07 2007 -0700 H. Peter Anvin + * Document NASM behaviour for 64-bit immediates and displacements +Tue Sep 25 15:44:40 2007 -0700 H. Peter Anvin + * test/movimm.asm: add optimizable forms +Tue Sep 25 15:41:19 2007 -0700 H. Peter Anvin + * assemble.c: clean up whitespace +Tue Sep 25 15:40:36 2007 -0700 H. Peter Anvin + * Correct the handling of "MOV" with immediate in 64-bit mode +Tue Sep 25 15:39:42 2007 -0700 H. Peter Anvin + * Test of immediate handling on 64-bit mode +Tue Sep 25 14:27:34 2007 -0700 H. Peter Anvin + * Add nasm_zalloc() to nasmlib.c +Tue Sep 25 14:26:03 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 14:11:29 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 13:34:55 2007 -0700 H. Peter Anvin + * Makefile.in: make "make install" create directories +Tue Sep 25 08:48:37 2007 -0700 H. Peter Anvin + * Fix BR 1445441: uninitialized use of "error_file" +Mon Sep 24 21:33:17 2007 -0700 H. Peter Anvin + * preproc.c: fix the loop in %undef +Mon Sep 24 20:53:48 2007 -0700 H. Peter Anvin + * float.c: clear off uninitialized warning +Mon Sep 24 17:02:41 2007 -0700 H. Peter Anvin + * outcoff: set the "virtual size field" to zero (BR 1351586) +Mon Sep 24 15:56:02 2007 -0700 H. Peter Anvin + * insns.dat: SMINT - mark ND, DMINT - fix opcode +Mon Sep 24 15:55:20 2007 -0700 H. Peter Anvin + * 0F0F is a 3Dnow! prefix; remove from prefix list +Mon Sep 24 15:48:09 2007 -0700 H. Peter Anvin + * Additional compaction missed by script +Mon Sep 24 15:42:53 2007 -0700 H. Peter Anvin + * insns.dat: machine-generated compaction mmx/xmmreg,mem -> mmx/xmmrm +Mon Sep 24 13:54:00 2007 -0700 H. Peter Anvin + * nasmdoc: grammar fix +Mon Sep 24 13:44:02 2007 -0700 H. Peter Anvin + * nasmdoc: remove stray periods +Mon Sep 24 13:42:09 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Mon Sep 24 13:41:58 2007 -0700 H. Peter Anvin + * Implement the -MG option (SF RFE 1564264) +Mon Sep 24 12:52:09 2007 -0700 H. Peter Anvin + * nasmdoc: clarify __float*__ example +Mon Sep 24 12:44:38 2007 -0700 H. Peter Anvin + * nasmdoc: document the __float*__ operators +Mon Sep 24 12:30:54 2007 -0700 H. Peter Anvin + * Support __float*__ for floating-point numbers in expressions +Mon Sep 24 10:51:07 2007 -0700 H. Peter Anvin + * eval.c: replace sequence of ifs with switch +Mon Sep 24 10:50:23 2007 -0700 H. Peter Anvin + * tokhash: allow a bit smarter pattern matching +Sat Sep 22 22:35:28 2007 -0700 H. Peter Anvin + * Implement INVLPGA according to the documentation +Sat Sep 22 22:02:34 2007 -0700 H. Peter Anvin + * Reformat insns.dat to uniform column width +Sat Sep 22 21:50:03 2007 -0700 H. Peter Anvin + * Simple test for 0x67 prefixes +Sat Sep 22 21:49:51 2007 -0700 H. Peter Anvin + * Auto-generate 0x67 prefixes without the need for \30x codes +Sat Sep 22 21:47:13 2007 -0700 H. Peter Anvin + * Make test/Makefile a bit more useful +Sat Sep 22 21:29:41 2007 -0700 H. Peter Anvin + * Add TY_OWORD for "DO" output +Sat Sep 22 19:52:11 2007 -0700 H. Peter Anvin + * LDDQU needs \301 (BR 1103549) +Sat Sep 22 19:51:13 2007 -0700 H. Peter Anvin + * RDTSCP and INVLPGA aren't 64-bit specific +Sat Sep 22 19:40:37 2007 -0700 H. Peter Anvin + * Cyrix GX1 instructions: BBx_RESET, CPU_READ, CPU_WRITE +Sat Sep 22 19:28:14 2007 -0700 H. Peter Anvin + * Centaur XSHA1, XSHA256, MONTMUL +Sat Sep 22 19:20:56 2007 -0700 H. Peter Anvin + * Implement Centaur's XCRYPT instructions +Sat Sep 22 19:13:05 2007 -0700 H. Peter Anvin + * Add Geode LX (AMD's Cyrix-derived core) instructions +Sat Sep 22 19:05:11 2007 -0700 H. Peter Anvin + * Add the GETSEC instruction for Intel SMX +Sat Sep 22 18:59:18 2007 -0700 H. Peter Anvin + * Add the AMD SSE4a and LZCNT instructions +Sat Sep 22 18:23:20 2007 -0700 H. Peter Anvin + * Tag UMOV as ND (no disassembly) to avoid collision +Sat Sep 22 18:20:49 2007 -0700 H. Peter Anvin + * Disallow optimizing by less than 5 passes. +Sat Sep 22 17:45:45 2007 -0700 H. Peter Anvin + * BR 1783117: Document that %+ needs a space after it, and fix crash +Sat Sep 22 16:44:56 2007 -0700 H. Peter Anvin + * nasm.spec.in: minor fixes +Sat Sep 22 16:38:25 2007 -0700 H. Peter Anvin + * release script: handle stricter CLI parsing for "git tag" +Sat Sep 22 16:35:11 2007 -0700 H. Peter Anvin + * Update nasm.spec.in and make it handle rc releases +Sat Sep 22 16:19:19 2007 -0700 H. Peter Anvin + * version.pl: support version numbers of the form X.Y[.Z]rcW +Thu Sep 20 21:33:43 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Thu Sep 20 21:12:33 2007 -0700 Charles Crayne + * modified: misc/release to fix bug in removing .git +Wed Sep 19 21:41:43 2007 -0700 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Wed Sep 19 21:41:27 2007 -0700 H. Peter Anvin + * Update manual pages +Wed Sep 19 21:41:02 2007 -0700 H. Peter Anvin + * Remove limit on number of sync points +Wed Sep 19 21:40:37 2007 -0700 H. Peter Anvin + * Make nasm_malloc() et al available from inside ndisasm +Wed Sep 19 21:07:32 2007 -0400 Frank Kotler + * Version 0.99.03 +Wed Sep 19 21:06:59 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Wed Sep 19 16:22:03 2007 -0700 H. Peter Anvin + * Merge commit 'origin/sse5' +Wed Sep 19 16:15:22 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Tue Sep 18 22:54:40 2007 -0700 H. Peter Anvin + * Slightly optimize the interface to nasm_token_hash() +Wed Sep 19 01:34:55 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Tue Sep 18 22:23:42 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 22:22:49 2007 -0700 H. Peter Anvin + * elf64: fix 32-bit truncations +Tue Sep 18 22:08:04 2007 -0700 H. Peter Anvin + * Document Infinity and NaN +Tue Sep 18 21:55:56 2007 -0700 H. Peter Anvin + * Support generating NaNs and infinities +Tue Sep 18 19:12:26 2007 -0700 H. Peter Anvin + * Update documentation +Tue Sep 18 18:37:36 2007 -0700 H. Peter Anvin + * Simple test for hexadecimal floating-point numbers +Tue Sep 18 18:33:17 2007 -0700 H. Peter Anvin + * Fix error-reporting in hexadecimal floating-point numbers +Tue Sep 18 18:31:26 2007 -0700 H. Peter Anvin + * Support C99-style hexadecimal floating point. +Tue Sep 18 17:50:34 2007 -0700 H. Peter Anvin + * Unify all standard IEEE floating-point formats; add 128-bit +Tue Sep 18 17:49:09 2007 -0700 H. Peter Anvin + * Fix handling of DO; support unary + for floating-point numbers +Tue Sep 18 16:39:03 2007 -0700 H. Peter Anvin + * Support 16-bit IEEE floating point; used in SSE5 +Tue Sep 18 15:43:40 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 15:43:08 2007 -0700 H. Peter Anvin + * Add NOP with argument to the instruction list +Tue Sep 18 15:24:38 2007 -0700 H. Peter Anvin + * Remove 0FC2 from list of instruction prefixes +Tue Sep 18 15:08:20 2007 -0700 H. Peter Anvin + * Speed up the disassembler by allowing prefixed instruction tables +Tue Sep 18 13:45:12 2007 -0700 H. Peter Anvin + * Document oword, do and reso +Tue Sep 18 13:01:32 2007 -0700 H. Peter Anvin + * Implement "oword" (128 bits) as a first-class size +Tue Sep 18 12:38:07 2007 -0700 H. Peter Anvin + * Change the token prehash function for better convergence +Tue Sep 18 12:23:21 2007 -0700 H. Peter Anvin + * SSE5 instruction table +Tue Sep 18 02:06:09 2007 -0400 Frank Kotler + * add "const" to output/outdbg.c +Mon Sep 17 18:45:44 2007 -0700 H. Peter Anvin + * Disassembler support for SSE5 instructions +Mon Sep 17 17:27:46 2007 -0700 H. Peter Anvin + * insns.dat: All SSE5 instructions are AMD +Mon Sep 17 17:25:27 2007 -0700 H. Peter Anvin + * Actually generate SSE5 instructions +Mon Sep 17 16:55:04 2007 -0700 H. Peter Anvin + * Initial support for generating DREX suffixes +Mon Sep 17 16:31:33 2007 -0700 H. Peter Anvin + * Fix a few instances of missing renumbers +Mon Sep 17 16:20:45 2007 -0700 H. Peter Anvin + * Enable IF_AR3 +Mon Sep 17 15:49:53 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Mon Sep 17 15:49:30 2007 -0700 H. Peter Anvin + * Initial support for four arguments per instruction +Mon Sep 17 15:48:32 2007 -0700 H. Peter Anvin + * CLFLUSH: Neither an x64 instruction nor AMD +Mon Sep 17 13:56:26 2007 -0700 H. Peter Anvin + * Sort dependency lists +Mon Sep 17 13:53:14 2007 -0700 H. Peter Anvin + * Cleaner way to handle MSVC's _snprintf() underscore damage +Mon Sep 17 13:19:25 2007 -0700 H. Peter Anvin + * test/r13.asm: test special-casing of rbp and r13 in 64-bit mode +Mon Sep 17 13:03:33 2007 -0700 H. Peter Anvin + * Additional documentation for 64-bit programming +Sun Sep 16 22:27:07 2007 -0700 H. Peter Anvin + * INSTALL: MSVC++ compilation instructions +Sun Sep 16 22:17:29 2007 -0700 H. Peter Anvin + * make alldeps: change Mkfiles/Makefile.* to Mkfiles/*.mak +Sun Sep 16 22:16:24 2007 -0700 H. Peter Anvin + * Fix Makefile for MSVC++ 2005, delete obsolete Makefiles +Sun Sep 16 22:15:34 2007 -0700 H. Peter Anvin + * Minor fixes needed to compile with MSVC++ 2005 +Sun Sep 16 18:35:02 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Sun Sep 16 18:04:57 2007 -0700 H. Peter Anvin + * Switch the preprocessor over to using the hash table library +Sun Sep 16 17:53:17 2007 -0700 H. Peter Anvin + * Fix the handling of local labels +Fri Sep 14 18:36:01 2007 -0700 H. Peter Anvin + * preproc.c: remove unnecessary int64_t +Fri Sep 14 18:03:29 2007 -0700 H. Peter Anvin + * Use the new hash table function library to store labels +Fri Sep 14 09:24:38 2007 -0700 H. Peter Anvin + * Define a proper hash table library +Thu Sep 13 18:13:20 2007 -0700 H. Peter Anvin + * Simple performance benchmarks: label, macro and token lookups +Thu Sep 13 12:25:32 2007 -0700 H. Peter Anvin + * release script: fix final cleanup +Thu Sep 13 12:22:00 2007 -0700 H. Peter Anvin + * Modify release script for a git-centric world +Thu Sep 13 11:06:42 2007 -0700 H. Peter Anvin + * pptok.c: don't insist on C99 compiler behaviour +Wed Sep 12 22:02:06 2007 -0700 H. Peter Anvin + * Fix literal F2 and F3 prefixes +Wed Sep 12 21:58:51 2007 -0700 H. Peter Anvin + * Add (untested!) SSSE3, SSE4.1, SSE4.2 instructions +Wed Sep 12 21:06:36 2007 -0700 H. Peter Anvin + * Add support for Tejas New Instructions (SSSE3) +Wed Sep 12 21:05:06 2007 -0700 H. Peter Anvin + * Remove $Id$ tags (useless with git) +Wed Sep 12 21:04:58 2007 -0700 H. Peter Anvin + * Use rm32 operands for VMREAD/VMWRITE +Wed Sep 12 21:04:51 2007 -0700 H. Peter Anvin + * Macros for SSSE3/SSE4 instruction sets +Wed Sep 12 21:04:39 2007 -0700 H. Peter Anvin + * Support r/m operands for non-integer types +Wed Sep 12 20:27:41 2007 -0700 H. Peter Anvin + * Use enumerations where practical to ease debugging +Wed Sep 12 17:02:55 2007 +0000 H. Peter Anvin + * pptok.c: quick-and-dirty downcasing during prehashing +Wed Sep 12 16:55:57 2007 +0000 H. Peter Anvin + * phash: Tell the user when the graph is OK +Wed Sep 12 05:18:20 2007 +0000 H. Peter Anvin + * pptok.c: handle holes in the pp_directives array +Wed Sep 12 04:20:08 2007 +0000 H. Peter Anvin + * preproc.c: adjust whitespace +Wed Sep 12 04:18:37 2007 +0000 H. Peter Anvin + * More automation in the preprocessor conditionals handling +Wed Sep 12 02:13:39 2007 +0000 H. Peter Anvin + * pptok.c: fix spacing +Wed Sep 12 02:12:07 2007 +0000 H. Peter Anvin + * Generate automatically correct tests for %if and %elif +Wed Sep 12 01:34:19 2007 +0000 H. Peter Anvin + * Run "make alldeps"; add dependencies missing from the previous checkin +Wed Sep 12 01:29:43 2007 +0000 H. Peter Anvin + * Use a perfect hash to look up preprocessor directives +Wed Sep 12 01:27:53 2007 +0000 H. Peter Anvin + * phash: Be a bit more aggressive about trying to make a small hash +Wed Sep 12 00:22:29 2007 +0000 H. Peter Anvin + * Add RCXZ as a known preprocessor condition +Tue Sep 11 23:57:23 2007 +0000 H. Peter Anvin + * doc: add some cross-references +Tue Sep 11 23:52:01 2007 +0000 H. Peter Anvin + * Feeble attempt at updating the documentation; remove Appendix B +Tue Sep 11 22:44:03 2007 +0000 H. Peter Anvin + * Handle instructions which can have both REX.W and OSP +Tue Sep 11 22:14:18 2007 +0000 H. Peter Anvin + * Use enums to make debugging easier +Tue Sep 11 22:13:17 2007 +0000 H. Peter Anvin + * ndisasm: handle \366 codes, prefer unprefixed instructions +Tue Sep 11 22:00:34 2007 +0000 H. Peter Anvin + * Simplify tokens.dat slightly +Tue Sep 11 04:26:44 2007 +0000 H. Peter Anvin + * Quiet gcc warning about uninitialized variables +Tue Sep 11 04:16:57 2007 +0000 H. Peter Anvin + * Make the big instruction arrays "const" +Mon Sep 10 23:32:05 2007 +0000 H. Peter Anvin + * Use an actual enum for the opcode +Mon Sep 10 23:30:21 2007 +0000 H. Peter Anvin + * Fix order of token arguments +Mon Sep 10 18:59:26 2007 +0000 H. Peter Anvin + * assemble.c: correct special handing of ESP/RSP +Mon Sep 10 18:59:01 2007 +0000 H. Peter Anvin + * tokhash: correct duplicate-token test +Mon Sep 10 18:58:40 2007 +0000 H. Peter Anvin + * tokhash: adjust table types to reduce size +Mon Sep 10 18:55:52 2007 +0000 H. Peter Anvin + * Fix the MMXREG and XMMREG flags definitions. +Wed Sep 5 06:48:38 2007 +0000 H. Peter Anvin + * nasm.spec.in: Copyright -> License +Wed Sep 5 06:40:51 2007 +0000 H. Peter Anvin + * Fix "make tar"; useful for RPM testing +Wed Sep 5 06:24:43 2007 +0000 H. Peter Anvin + * Remove obsolete Serial: construct; we shouldn't need it anyway. +Tue Sep 4 01:29:43 2007 +0000 Chuck Crayne + * Provide 64-bit support for ORG directive +Sun Sep 2 16:37:03 2007 +0000 H. Peter Anvin + * Fix some MMX/SSE irregularities which interact with the 64-bit support +Sun Sep 2 14:46:00 2007 +0000 H. Peter Anvin + * phash.ph: yet another attempt at getting Perl to behave, arithmetically +Sun Sep 2 06:23:29 2007 +0000 H. Peter Anvin + * Simple 64-bit org test +Sun Sep 2 06:20:15 2007 +0000 H. Peter Anvin + * phash.ph: remove some stale code +Sun Sep 2 01:00:34 2007 +0000 Chuck Crayne + * Force use of integer values for generating hash keys. +Fri Aug 31 18:10:23 2007 +0000 H. Peter Anvin + * phash: don't rely on the build platform Perl version of rand() +Fri Aug 31 07:31:51 2007 +0000 H. Peter Anvin + * tokhash.pl: formatting changes for readability +Fri Aug 31 07:23:31 2007 +0000 H. Peter Anvin + * tokhash: Speed up the rejection of unhashed values +Fri Aug 31 06:06:17 2007 +0000 H. Peter Anvin + * tokhash.pl: "ix" should have the same width as the "hash" arrays +Fri Aug 31 00:28:35 2007 +0000 H. Peter Anvin + * Add "do not edit" comment to tokhash.c +Fri Aug 31 00:23:40 2007 +0000 H. Peter Anvin + * Make the token hash a bit smaller by using 16-bit hash tables +Fri Aug 31 00:16:10 2007 +0000 H. Peter Anvin + * Minor cleanup; remove duplication of names.c +Thu Aug 30 23:42:39 2007 +0000 H. Peter Anvin + * phash.ph: use a bipartite graph to reduce the storage requirements +Thu Aug 30 22:35:34 2007 +0000 H. Peter Anvin + * Finishing touches on perfect hash tokenizer; actually turn the thing on +Thu Aug 30 21:50:20 2007 +0000 H. Peter Anvin + * Makefile rule for tokhash.c +Thu Aug 30 21:47:46 2007 +0000 H. Peter Anvin + * tokens.dat: Data file containing alphanumeric tokens not in other .dats +Thu Aug 30 21:45:56 2007 +0000 H. Peter Anvin + * Generate a perfect hash for the token parser +Thu Aug 30 21:40:08 2007 +0000 H. Peter Anvin + * Fix bugs in repeated suffix handling, which led to missing r8d/r8w/r8d +Thu Aug 30 21:39:37 2007 +0000 H. Peter Anvin + * phash.ph: more powerful prehashing +Thu Aug 30 20:15:25 2007 +0000 H. Peter Anvin + * Make the perfect hash generator an includable module +Wed Aug 29 20:30:31 2007 +0000 H. Peter Anvin + * Correct the logic for recording fs: and gs: overrides. +Wed Aug 29 18:20:19 2007 +0000 H. Peter Anvin + * Generate R_X86_64_64 relocations in elf64 output +Wed Aug 29 17:24:03 2007 +0000 H. Peter Anvin + * Add README file +Wed Aug 29 17:20:09 2007 +0000 H. Peter Anvin + * Create a Perl library directory, and add the Graph module to it +Wed Aug 29 17:05:17 2007 +0000 H. Peter Anvin + * Perfect hash generator, as a perl script +Wed Aug 29 16:41:43 2007 +0000 H. Peter Anvin + * Use standard macro for the default directive +Wed Aug 29 16:40:26 2007 +0000 H. Peter Anvin + * Add standard macro for [default] directive +Wed Aug 29 16:38:47 2007 +0000 H. Peter Anvin + * More test cases for rel and abs addressing +Wed Aug 29 16:38:05 2007 +0000 H. Peter Anvin + * Add [default] directive +Wed Aug 29 16:25:46 2007 +0000 H. Peter Anvin + * nasmlib: add bsii() case-insensitive version of bsi() +Wed Aug 29 15:49:53 2007 +0000 H. Peter Anvin + * Add test cases for IP-relative addressing +Wed Aug 29 15:19:19 2007 +0000 H. Peter Anvin + * Suppress IP-relative only for fs: and gs: overrides +Tue Aug 28 23:06:00 2007 +0000 H. Peter Anvin + * Implement REL/ABS modifiers +Sun Aug 26 05:51:39 2007 +0000 Frank Kotler + * attempt to make static makefiles aware of outelf32/outelf64 +Sun Aug 26 05:48:54 2007 +0000 Frank Kotler + * add nasm_strsep to nasmlib, for output/outmacho.c - strtok doesn't work +Sun Aug 26 05:41:33 2007 +0000 Frank Kotler + * remove "#include from rdoff directory - two places - it annoyed Windows users and seems unneeded +Sun Aug 26 05:10:24 2007 +0000 Frank Kotler + * finally commit Mike Frysinger's "elf-visibility" patch +Mon Aug 20 21:03:14 2007 +0000 H. Peter Anvin + * regs.pl: handle dashed sequences with suffixes +Mon Aug 20 20:10:04 2007 +0000 H. Peter Anvin + * sync.c: change ULONG_MAX to UINT32_MAX +Mon Aug 20 20:09:11 2007 +0000 H. Peter Anvin + * Add _MIN and _MAX macros for the fixed-size types. +Mon Aug 20 20:02:17 2007 +0000 H. Peter Anvin + * ldrdf: cast output of sizeof() before passing to printf(), to avoid warning. +Sun Aug 19 18:49:26 2007 +0000 Keith Kanios + * Fixed RIP address processing ambiguity found by Charles Crayne. +Fri Aug 17 07:37:52 2007 +0000 Keith Kanios + * Fixed issues with REX prefix effective address generation. Fixed XMM instruction output. +Fri Aug 17 02:03:10 2007 +0000 Keith Kanios + * Changed MMXREG and XMMREG flags to help resolve invalid REX prefix generation for MMX instructions. +Sat Jul 7 02:01:08 2007 +0000 H. Peter Anvin + * More int/int32_t confusion +Sat Jul 7 01:59:52 2007 +0000 H. Peter Anvin + * regflag() should return int32_t. +Thu Jun 21 19:00:12 2007 +0000 H. Peter Anvin + * Detect missing and include ersatz version if missing +Thu Jun 21 06:24:23 2007 +0000 H. Peter Anvin + * inttypes.h: for older preprocessors, specify L and LL as appropriate +Thu Jun 21 06:20:43 2007 +0000 H. Peter Anvin + * inttypes.h: Fix spelling of SHRT_MAX +Thu Jun 21 06:15:42 2007 +0000 H. Peter Anvin + * inttypes.h: do a single ersatz based on +Sun Jun 3 02:42:41 2007 +0000 Chuck Crayne + * Support 32-bit direct addressing in 64-bit mode without base or index regs +Sat Jun 2 02:26:21 2007 +0000 H. Peter Anvin + * Fix the [U]INT*_C() creation macros +Sat Jun 2 00:05:35 2007 +0000 H. Peter Anvin + * For platforms that don't have them, provide for common models. +Wed May 30 22:21:11 2007 +0000 H. Peter Anvin + * Fix the handling of the \313 code. +Wed May 30 22:20:01 2007 +0000 H. Peter Anvin + * Machine-generated \321->\324 corrections +Wed May 30 21:22:33 2007 +0000 Frank Kotler + * update "version" to 0.99.02 +Wed May 30 20:30:15 2007 +0000 H. Peter Anvin + * Correct the generation of 67 prefixes. +Wed May 30 18:30:18 2007 +0000 H. Peter Anvin + * Update dependencies. +Wed May 30 16:34:29 2007 +0000 Frank Kotler + * update cvs server name in misc/release script +Wed May 30 04:28:50 2007 +0000 H. Peter Anvin + * Avoid magic values; we have more than 124 registers now +Wed May 30 04:27:58 2007 +0000 H. Peter Anvin + * Remove bogus redundant tests +Wed May 30 03:44:50 2007 +0000 H. Peter Anvin + * More \321 -> \324 +Wed May 30 03:44:02 2007 +0000 H. Peter Anvin + * Remove bogus check for 64-bitness +Wed May 30 03:25:21 2007 +0000 H. Peter Anvin + * Get rid of magic open-coded "register numbers" +Wed May 30 02:48:51 2007 +0000 H. Peter Anvin + * MOV reg64,reg64 takes \324 (64 bit with REX) not \321 (32 bit) +Wed May 30 00:18:26 2007 +0000 H. Peter Anvin + * Rename REGNORM to REG_EA +Wed May 30 00:15:25 2007 +0000 H. Peter Anvin + * More instruction flag surgery +Wed May 30 00:05:00 2007 +0000 H. Peter Anvin + * More cleanup of operand flags/register classes +Tue May 29 23:57:12 2007 +0000 H. Peter Anvin + * Clean up the existing operand flag definitions, and document +Tue May 29 21:44:55 2007 +0000 H. Peter Anvin + * Run "make alldeps" +Thu May 24 22:33:07 2007 +0000 Frank Kotler + * update version number to 0.99.01 +Tue May 15 04:33:43 2007 +0000 H. Peter Anvin + * regs.dat: fix comment +Fri May 4 18:47:16 2007 +0000 H. Peter Anvin + * 16-bit relocations are standard in ELF64 (at my request, incidentally) +Fri May 4 02:16:08 2007 +0000 Chuck Crayne + * Addition of elf32 and elf64 output formats. +Wed May 2 04:21:26 2007 +0000 Chuck Crayne + * Allow '!' to be used in expressions with same meaning as in C. +Wed May 2 01:59:16 2007 +0000 Chuck Crayne + * Add %IFN and %ELIFN as per RFE #786286 +Mon Apr 30 22:26:58 2007 +0000 Chuck Crayne + * Accept responsibility for support of outelf64.c +Sun Apr 29 20:57:53 2007 +0000 Chuck Crayne + * Clarify comments about relocation entries. +Sun Apr 29 00:28:24 2007 +0000 Chuck Crayne + * Allow ELF32 to be invoked either as -f elf or -f elf32 +Sat Apr 28 22:18:04 2007 +0000 Chuck Crayne + * Eliminate shift count warnings when building on 32-bit systems +Sat Apr 28 06:18:48 2007 +0000 Chuck Crayne + * Initial support for ELF64 +Wed Apr 18 02:27:18 2007 +0000 H. Peter Anvin + * Fix the handling of \324 for computing the length +Wed Apr 18 02:24:34 2007 +0000 Keith Kanios + * Fixed RDF/2 to comply with "maxbits" use. +Tue Apr 17 20:23:11 2007 +0000 H. Peter Anvin + * Handle "LOCK as REX.R" for MOV CRx; fix warning for invalid 64-bit regs +Mon Apr 16 18:16:46 2007 +0000 Keith Kanios + * MEM_OFFSET Instructions Fixed. +Mon Apr 16 15:46:46 2007 +0000 Keith Kanios + * Fixed 64-bit Mode Segment Selection. +Mon Apr 16 14:31:54 2007 +0000 Keith Kanios + * Fixed distinction between [LOCAL]SYMBOL/IMMEDIATE for RIP-relative addressing. +Mon Apr 16 14:05:01 2007 +0000 Keith Kanios + * Fixed long mode MEM_OFFS issue. +Mon Apr 16 13:54:49 2007 +0000 Keith Kanios + * Filled in all RIP Register Flags. +Mon Apr 16 05:26:29 2007 +0000 H. Peter Anvin + * More \321 -> \324 for 64-bit instructions +Mon Apr 16 04:56:06 2007 +0000 Keith Kanios + * Fixed 64-bit offset generation. +Mon Apr 16 02:39:56 2007 +0000 H. Peter Anvin + * More 64-bit ndisasm fixes. +Mon Apr 16 02:02:06 2007 +0000 H. Peter Anvin + * Fixes for 64-bit ndisasm. +Mon Apr 16 01:21:29 2007 +0000 H. Peter Anvin + * Use + instead of * for extension; it feels cleaner with the new meaning. +Mon Apr 16 01:18:30 2007 +0000 H. Peter Anvin + * Initial 64-bit support for ndisasm. Still a work in progress. +Sun Apr 15 23:12:17 2007 +0000 H. Peter Anvin + * Clean up the 64-bitification of regs.dat for 64-bit ndisasm support +Sun Apr 15 23:10:26 2007 +0000 H. Peter Anvin + * Remove @GCCFLAGS@ +Sun Apr 15 23:09:23 2007 +0000 H. Peter Anvin + * CR8 is not special in any way as far as the assembler is concerned. +Sun Apr 15 23:03:28 2007 +0000 H. Peter Anvin + * Get rid of @GCCFLAGS@ +Sun Apr 15 22:45:25 2007 +0000 H. Peter Anvin + * Cleaner way to add gcc options +Sun Apr 15 22:08:30 2007 +0000 Keith Kanios + * Fixed distinction between RIP relative symbols and immediate values. +Sun Apr 15 05:40:43 2007 +0000 H. Peter Anvin + * Fix the register number for CR7 (it was using the same number as CR15). +Sun Apr 15 05:32:18 2007 +0000 H. Peter Anvin + * More perl-like idioms for generating regdis.c +Sun Apr 15 01:37:13 2007 +0000 Keith Kanios + * Fixed regdis.c generation. +Sat Apr 14 18:54:52 2007 +0000 Keith Kanios + * Added DQ constants for all BITS modes. +Sat Apr 14 08:03:02 2007 +0000 H. Peter Anvin + * outmacho.c: stylistic cleanups +Sat Apr 14 03:52:05 2007 +0000 Keith Kanios + * Fixed support for DQ constants in long mode. +Sat Apr 14 03:44:31 2007 +0000 Keith Kanios + * Hopefully it is actually fixed this time :P +Sat Apr 14 01:49:07 2007 +0000 Keith Kanios + * Fixed structure initialization issue. +Sat Apr 14 01:44:35 2007 +0000 Keith Kanios + * Refixed uninitialized data. +Sat Apr 14 01:40:24 2007 +0000 Keith Kanios + * Fixed uninitialized structure data. +Sat Apr 14 01:24:14 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Sat Apr 14 00:46:25 2007 +0000 Keith Kanios + * Placated unreferenced types. +Sat Apr 14 00:10:59 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Fri Apr 13 23:09:18 2007 +0000 Keith Kanios + * Added outmacho.* to static makefile. +Fri Apr 13 22:24:46 2007 +0000 Keith Kanios + * Fixed REGRIP -> RIPREG to match regs.dat. +Fri Apr 13 22:07:53 2007 +0000 Keith Kanios + * Fixed obj_fwrite() declaration to match "static" definition. +Fri Apr 13 22:03:24 2007 +0000 Keith Kanios + * Added appropriate "void" prototypes. +Fri Apr 13 22:00:42 2007 +0000 Keith Kanios + * Replaced str(n)casecmp with more standard str(n)icmp. +Fri Apr 13 20:06:41 2007 +0000 H. Peter Anvin + * AIf we have config.h, we should actually include it!! +Fri Apr 13 19:59:20 2007 +0000 H. Peter Anvin + * When compiling with gcc, compile with -W -Wall for maximum warnings. +Fri Apr 13 19:58:42 2007 +0000 H. Peter Anvin + * Macroize any compiler-specific code; macros defined in "compiler.h" +Fri Apr 13 16:47:53 2007 +0000 Keith Kanios + * Fixed distinction between char and int8_t data types. +Fri Apr 13 01:17:45 2007 +0000 Keith Kanios + * Comment "REX.I" should have been "REX.X" +Fri Apr 13 00:52:54 2007 +0000 Keith Kanios + * Fixed c99 data-types after removal of typedefs. +Fri Apr 13 00:43:50 2007 +0000 Keith Kanios + * Added Dev-Cpp Makefile +Fri Apr 13 00:38:29 2007 +0000 Keith Kanios + * *** empty log message *** +Thu Apr 12 17:58:02 2007 +0000 H. Peter Anvin + * Remove redundant inclusion of +Thu Apr 12 16:54:50 2007 +0000 H. Peter Anvin + * Remove obsolete types; add where needed; header fixes +Thu Apr 12 16:25:58 2007 +0000 H. Peter Anvin + * autogen.sh script to create configure, et al. +Thu Apr 12 16:23:11 2007 +0000 Keith Kanios + * Fixed c99 support for RDOFF Tools +Thu Apr 12 16:12:09 2007 +0000 H. Peter Anvin + * outmacho.c: Don't assume __builtin_ctzl exists for gcc < 4 + +Mon Nov 12 22:05:31 2007 -0800 H. Peter Anvin + * BR 1828866: fix handling of LAR/LSL +Mon Nov 12 21:57:00 2007 -0800 H. Peter Anvin + * Better (but not *good!*) handling of 64-bit addressing in ndisasm +Mon Nov 12 21:02:33 2007 -0800 H. Peter Anvin + * Fix disassembly of XCHG +Mon Nov 12 20:18:33 2007 -0800 H. Peter Anvin + * Test of XCHG +Mon Nov 12 20:18:05 2007 -0800 H. Peter Anvin + * Fix handling of XCHG in 64-bit mode +Mon Nov 12 19:36:13 2007 -0800 H. Peter Anvin + * More \321 -> \324 bug fixes +Mon Nov 12 18:26:31 2007 -0800 H. Peter Anvin + * float.c: all warnings and errors are pass 1 only +Sat Nov 10 21:55:19 2007 -0800 Charles Crayne + * Update documentation for stack relative directives. +Sat Nov 10 17:52:23 2007 -0800 Charles Crayne + * Clean up a few more 32-bit bottlenecks +Fri Nov 9 16:37:41 2007 -0800 Charles Crayne + * Update documantation for stack relative directives +Fri Nov 9 16:33:54 2007 -0800 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Fri Nov 9 16:25:43 2007 -0800 Charles Crayne + * Update documentation for stack relative directives +Fri Nov 9 14:44:02 2007 -0800 H. Peter Anvin + * Don't combine type and size into a single argument +Thu Nov 8 22:11:14 2007 -0800 Charles Crayne + * Add flat64 to %stacksize choices +Thu Nov 8 20:43:22 2007 -0800 H. Peter Anvin + * Fix building under OpenWatcom +Thu Nov 8 20:29:37 2007 -0800 H. Peter Anvin + * ps2pdf: remove -dOptimize=true +Thu Nov 8 20:21:41 2007 -0800 H. Peter Anvin + * No binary files left in the source distro; unbreak release script +Thu Nov 8 20:01:11 2007 -0800 H. Peter Anvin + * BR 1828103: Fix %arg and %local +Thu Nov 8 19:34:01 2007 -0800 H. Peter Anvin + * nasmlib.c: prefix_name(): use the elements() macro +Thu Nov 8 19:30:22 2007 -0800 H. Peter Anvin + * Move elements() to nasmlib.h +Thu Nov 8 19:15:33 2007 -0800 H. Peter Anvin + * constipate the "str" argument to bsi() and bsii() +Wed Nov 7 19:03:46 2007 -0800 Charles Crayne + * Upgrade RAA functions to hold 64-bit data. +Tue Nov 6 21:48:12 2007 -0800 Charles Crayne + * Pass 64-bit instruction lengths to back-ends. +Tue Nov 6 18:27:23 2007 -0800 Charles Crayne + * Prepare for 64-bit instruction lengths +Mon Nov 5 21:49:49 2007 -0800 Charles Crayne + * Disambiguate error messages +Mon Nov 5 17:19:32 2007 -0800 Charles Crayne + * Upgrade label functions to 64-bit +Sun Nov 4 21:10:42 2007 -0800 H. Peter Anvin + * Permit opcode names as labels as long as they are followed by a colon +Sun Nov 4 15:28:30 2007 -0800 Charles Crayne + * Make warning limit valid for both i386 and x86_64 +Sat Nov 3 22:06:13 2007 -0700 Charles Crayne + * Warn on out of bounds EA displacements +Thu Nov 1 15:08:27 2007 -0700 H. Peter Anvin + * Treat info files as binary when creating xdoc distro file +Thu Nov 1 15:07:42 2007 -0700 H. Peter Anvin + * Remove obsolete binary files from the distribution +Thu Nov 1 14:53:32 2007 -0700 H. Peter Anvin + * Move declarations before statements +Wed Oct 31 23:37:35 2007 -0700 H. Peter Anvin + * NASM 0.99.06 +Wed Oct 31 23:37:19 2007 -0700 H. Peter Anvin + * Script to tag the tree for release +Wed Oct 31 10:59:26 2007 -0700 H. Peter Anvin + * Even more "riprel" tests +Tue Oct 30 01:17:57 2007 -0700 H. Peter Anvin + * floatx.asm: add tests for "rounds up to smallest denorm" +Tue Oct 30 01:13:27 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Tue Oct 30 01:13:09 2007 -0700 H. Peter Anvin + * float.c: handle round-up-to-denorm correctly. +Tue Oct 30 00:59:27 2007 -0700 H. Peter Anvin + * Exhaustive test for 8-bit floating point values +Mon Oct 29 23:12:47 2007 -0700 H. Peter Anvin + * Clean up the handing of operands in assemble.c +Mon Oct 29 22:56:08 2007 -0700 H. Peter Anvin + * Don't warn for segmented references +Mon Oct 29 20:20:12 2007 -0700 H. Peter Anvin + * Use a 32-bit floating-point limb size; support 8-bit float +Mon Oct 29 18:24:59 2007 -0700 Charles Crayne + * Reduce severity of redundant prefixes from error to warning. +Sun Oct 28 23:23:24 2007 -0700 H. Peter Anvin + * Test of some addressing modes in 64-bit mode. +Sun Oct 28 23:21:46 2007 -0700 H. Peter Anvin + * Fix bogus flagging of effective addresses as invalid +Sun Oct 28 23:10:34 2007 -0700 H. Peter Anvin + * Actually shut up the warning in rdfload.c +Sun Oct 28 22:04:42 2007 -0700 H. Peter Anvin + * Clean up stealth whitespace +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * Fix warning about cast to pointer in rdfload.c +Sun Oct 28 22:04:00 2007 -0700 H. Peter Anvin + * 64-bit addressing and prefix handling changes +Sun Oct 28 15:29:54 2007 -0700 Charles Crayne + * Adjust stabs symbol index to match symbol table. +Fri Oct 26 21:38:02 2007 -0700 H. Peter Anvin + * readnum(): handle prefix-suffix collision like "0h" +Fri Oct 26 18:49:29 2007 -0700 H. Peter Anvin + * Better handling of platforms which hide "extended" functionality +Wed Oct 24 15:51:40 2007 -0700 Charles Crayne + * Merge branch 'master' of /home/chuck/development/gitnasm/ +Wed Oct 24 15:30:17 2007 -0700 Charles Crayne + * Update sections about debug info formats +Wed Oct 24 15:29:51 2007 -0700 H. Peter Anvin + * Fix the handling of floating-point tokens in the preprocessor +Tue Oct 23 19:28:39 2007 -0700 Charles Crayne + * Fix bugs item #1817677 +Tue Oct 23 00:08:58 2007 -0700 H. Peter Anvin + * Slightly simplify the radix-detection code +Mon Oct 22 19:48:06 2007 -0700 H. Peter Anvin + * Unbreak particularly tricky hex constants +Mon Oct 22 19:37:36 2007 -0700 H. Peter Anvin + * Decimal floating point can also start with 0. 0e 0E +Mon Oct 22 17:34:10 2007 -0700 H. Peter Anvin + * Support binary and octal floating-point +Mon Oct 22 16:53:48 2007 -0700 H. Peter Anvin + * More consistent handling of radix letters +Sun Oct 21 15:33:01 2007 -0700 H. Peter Anvin + * float.c: correct exponent capping +Sun Oct 21 14:21:43 2007 -0700 Charles Crayne + * Clean up elf symbol table section +Fri Oct 19 18:33:57 2007 -0700 H. Peter Anvin + * Allow $-prefixed hexadecimal FP as an alternative to 0x +Fri Oct 19 14:43:22 2007 -0700 H. Peter Anvin + * Scripts to remove stealth whitespace +Fri Oct 19 14:42:29 2007 -0700 H. Peter Anvin + * Formatting: kill off "stealth whitespace" +Fri Oct 19 14:26:52 2007 -0700 H. Peter Anvin + * test/floatx.asm: fix test case +Fri Oct 19 14:19:52 2007 -0700 H. Peter Anvin + * uscore.asm: Fix test case +Fri Oct 19 14:17:51 2007 -0700 H. Peter Anvin + * float.c: mark read_exponent() static +Fri Oct 19 14:10:35 2007 -0700 H. Peter Anvin + * Don't confuse suffixed hexadecimal with floating-point +Fri Oct 19 13:17:24 2007 -0700 H. Peter Anvin + * Anchor filename locations in .gitignore +Fri Oct 19 13:16:51 2007 -0700 H. Peter Anvin + * test/Makefile: Use -Ox instead of -O999 +Fri Oct 19 13:14:06 2007 -0700 H. Peter Anvin + * Test of underscored constants +Fri Oct 19 13:10:46 2007 -0700 H. Peter Anvin + * Allow underscores in numbers; better detection of FP +Fri Oct 19 10:52:31 2007 -0700 H. Peter Anvin + * Modernize nasm.spec.in and make it closer to the Fedora version +Thu Oct 18 23:33:06 2007 -0700 Charles Crayne + * Suppress datarootdir warnings from configure +Thu Oct 18 21:17:20 2007 -0700 Charles Crayne + * Suppress signedness warnings in disassembler +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * Cleaner solution for MinGW handling of __STRICT_ANSI__ +Thu Oct 18 19:14:08 2007 -0700 H. Peter Anvin + * configure: Undefine __STRICT_ANSI__ for mingw's benefit +Thu Oct 18 19:14:07 2007 -0700 H. Peter Anvin + * Fix invocation of readnum() +Thu Oct 18 19:02:42 2007 -0700 Charles Crayne + * Suppress a few signedness warnings +Thu Oct 18 17:04:10 2007 -0700 root + * Avoid unnecessary warning on redefinition of section (bug 801180) +Wed Oct 17 17:55:45 2007 -0700 Charles Crayne + * Generate stabs entries for any executable section +Tue Oct 16 22:59:09 2007 -0700 H. Peter Anvin + * NASM 0.99.05 +Tue Oct 16 15:46:04 2007 -0700 H. Peter Anvin + * Tests of obscenely large exponents +Tue Oct 16 14:42:32 2007 -0700 H. Peter Anvin + * Comma-separate contents of __FLOAT__ +Tue Oct 16 14:40:27 2007 -0700 H. Peter Anvin + * Implement floating-point option control directive +Tue Oct 16 11:48:07 2007 -0700 H. Peter Anvin + * Floating-point warning fixes; fix round-to-overflow +Tue Oct 16 11:32:58 2007 -0700 H. Peter Anvin + * Handle rounding of denorms correctly; make fp overflow a warning +Tue Oct 16 10:35:02 2007 -0700 H. Peter Anvin + * Additional entries for .gitignore +Tue Oct 16 10:32:57 2007 -0700 H. Peter Anvin + * Refactor floating-point formatting code; fix 80-bit denorms +Tue Oct 16 10:31:16 2007 -0700 H. Peter Anvin + * Add 1.5 as a test case: representative of an exact fraction +Mon Oct 15 20:06:06 2007 -0700 H. Peter Anvin + * Recognize 'd', 't' and 'y' as radix suffixes +Mon Oct 15 19:53:10 2007 -0700 H. Peter Anvin + * Fix FISTTP opcodes (BR 689695) +Mon Oct 15 19:46:32 2007 -0700 H. Peter Anvin + * New floating-point conversion routines +Mon Oct 15 17:48:43 2007 -0700 H. Peter Anvin + * Add testnos3 from the gdtoa package (floating-point test) +Sat Oct 13 23:19:21 2007 -0700 H. Peter Anvin + * .gitignore file doesn't need to be in the release file +Sat Oct 13 23:17:41 2007 -0700 H. Peter Anvin + * Add .gitignore file so "git status" produces something sane +Sat Oct 13 23:12:46 2007 -0700 H. Peter Anvin + * autoconf: drop AC_USE_SYSTEM_EXTENSIONS to support autoconf 2.59 +Sat Oct 13 07:09:22 2007 -0700 Keith Kanios + * Fix 32-bit types in preproc.c and eval.c +Thu Oct 11 20:32:33 2007 -0700 Charles Crayne + * Must define types before using them +Thu Oct 11 13:42:09 2007 -0700 H. Peter Anvin + * preproc.c: move smacro define/undef to separate functions +Thu Oct 11 13:38:38 2007 -0700 H. Peter Anvin + * preproc.c: PP_DEFINE and PP_XDEFINE are case-sensitive +Thu Oct 11 12:52:03 2007 -0700 H. Peter Anvin + * preproc.c: normalize the handling of case sensitivity +Thu Oct 11 12:51:06 2007 -0700 H. Peter Anvin + * Define macros necessary for on C++ +Thu Oct 11 10:12:58 2007 -0700 H. Peter Anvin + * More "bool" fixes +Thu Oct 11 10:11:57 2007 -0700 H. Peter Anvin + * preproc.c: allow 64-bit repeat counts +Thu Oct 11 10:06:19 2007 -0700 H. Peter Anvin + * preproc.c: For an SMacro, in_progress really is a boolean (no %rep) +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * Additional uses of bool and enum +Thu Oct 11 00:05:57 2007 -0700 H. Peter Anvin + * preproc.c: MMacro.in_progress is not a boolean +Wed Oct 10 18:07:51 2007 -0700 H. Peter Anvin + * saa_fread/fwrite: when seeking, must set [rw]ptr as well +Wed Oct 10 14:58:45 2007 -0700 H. Peter Anvin + * Use the compiler-provided booleans if available, otherwise emulate +Wed Oct 10 14:55:14 2007 -0700 H. Peter Anvin + * owlinux.mak: don't clean things we won't be able to +Wed Oct 10 14:29:53 2007 -0700 H. Peter Anvin + * configure.in: looks like we need autoconf 2.61 :( +Wed Oct 10 14:06:59 2007 -0700 H. Peter Anvin + * Create option -Ox to tell NASM to do unlimited passes +Mon Oct 8 19:26:57 2007 -0700 H. Peter Anvin + * Revert "floatb.asm: fix broken testcase" +Mon Oct 8 18:39:24 2007 -0700 H. Peter Anvin + * floatb.asm: fix broken testcase +Mon Oct 8 12:41:00 2007 -0700 H. Peter Anvin + * saa_rstruct: fix overrun check +Mon Oct 8 12:12:23 2007 -0700 H. Peter Anvin + * Add Frank's floattest.asm test file +Sun Oct 7 21:13:14 2007 -0700 H. Peter Anvin + * saa_fpwrite: initializing "len" should be part of the loop +Sun Oct 7 18:46:57 2007 -0700 Charles Crayne + * Fix infinite loop in function saa_fpwrite +Fri Oct 5 17:44:16 2007 -0700 H. Peter Anvin + * zerobyte.asm: use a real instruction to avoid confusing ndisasm +Fri Oct 5 17:42:31 2007 -0700 H. Peter Anvin + * zerobyte.asm: add test cases for non-initial \170 uses +Fri Oct 5 17:29:01 2007 -0700 H. Peter Anvin + * Check in the proper zerobyte test +Fri Oct 5 17:04:32 2007 -0700 H. Peter Anvin + * Emit REX prefix before literal zero (\170) +Fri Oct 5 17:01:15 2007 -0700 H. Peter Anvin + * LICENSE: Break long line +Fri Oct 5 14:36:03 2007 -0700 H. Peter Anvin + * Add test for problematic floats +Thu Oct 4 23:51:08 2007 -0700 H. Peter Anvin + * floatx.asm: add Inf and NaN to the boundary condition tests +Thu Oct 4 23:09:19 2007 -0700 H. Peter Anvin + * floatx.asm: add specific tests for exponent boundary conditions +Thu Oct 4 22:51:08 2007 -0700 H. Peter Anvin + * float.c: correct the exponent +Thu Oct 4 15:18:23 2007 -0700 H. Peter Anvin + * Additional rules in test/Makefile +Thu Oct 4 13:42:56 2007 -0700 H. Peter Anvin + * Rewrite the handling of SAA's to allow random access +Wed Oct 3 21:30:57 2007 -0700 H. Peter Anvin + * Change cloc_t to struct location, and reorder the members +Wed Oct 3 21:24:51 2007 -0700 H. Peter Anvin + * BR 1352920: change loc_t -> cloc_t +Wed Oct 3 21:22:16 2007 -0700 H. Peter Anvin + * BR 1352920: Handle upper case %line +Wed Oct 3 17:40:12 2007 -0700 H. Peter Anvin + * Use autoconf to request feature macros +Tue Oct 2 22:04:15 2007 -0700 H. Peter Anvin + * preproc.c: constipation +Tue Oct 2 21:57:27 2007 -0700 H. Peter Anvin + * make alldeps +Tue Oct 2 21:53:51 2007 -0700 H. Peter Anvin + * Portability fixes +Tue Oct 2 21:13:18 2007 -0700 H. Peter Anvin + * Run "make alldeps". +Tue Oct 2 17:40:00 2007 -0700 H. Peter Anvin + * Use the crc64 we already use as the perfect hash function prehash +Tue Oct 2 15:09:33 2007 -0700 H. Peter Anvin + * insns.dat: add systematic names for the hinting NOPs (0F18-0F1F) +Mon Oct 1 11:28:32 2007 -0700 H. Peter Anvin + * Unspecified files are null strings, not null pointers +Mon Oct 1 11:26:31 2007 -0700 H. Peter Anvin + * Check for the most basic filename overlaps +Sun Sep 30 22:15:36 2007 -0700 Charles Crayne + * modified: nasm.1 to add newer command line options +Fri Sep 28 21:27:41 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 20:17:12 2007 -0700 H. Peter Anvin + * configure.in: AC_SUBST_FILE should have been AC_SUBST +Fri Sep 28 17:17:20 2007 -0700 H. Peter Anvin + * Unbreak relative references to immediate addresses +Fri Sep 28 15:16:47 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Fri Sep 28 12:01:55 2007 -0700 H. Peter Anvin + * lib/vsnprintf.c: correct boundary conditions +Fri Sep 28 10:50:20 2007 -0700 H. Peter Anvin + * Add substitutes for snprintf() and vsnprintf() +Fri Sep 28 02:03:41 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Thu Sep 27 21:35:04 2007 -0700 H. Peter Anvin + * Exclude config.h from the dependency list for the canned makefiles +Thu Sep 27 21:12:17 2007 -0700 H. Peter Anvin + * version.pl: Add support for daily snapshot releases +Thu Sep 27 19:46:55 2007 -0700 H. Peter Anvin + * Add Makefile for Linux -> DOS, Win32, OS/2 using OpenWatcom +Wed Sep 26 19:57:07 2007 -0700 H. Peter Anvin + * Add Makefile for OpenWatcom (DOS, OS/2 or Win32 output) +Wed Sep 26 17:00:18 2007 -0700 H. Peter Anvin + * Test for various addressing modes in 64-bit mode +Wed Sep 26 15:19:28 2007 -0700 H. Peter Anvin + * nasm option reshuffling, -E -> -Z +Tue Sep 25 23:57:21 2007 -0400 Frank Kotler + * Version 0.99.04 +Tue Sep 25 20:36:45 2007 -0700 H. Peter Anvin + * nasmdoc: corrections on 64-bit immediates/displacements +Tue Sep 25 16:02:21 2007 -0700 H. Peter Anvin + * nasmdoc: shorten lines which are too long +Tue Sep 25 16:01:07 2007 -0700 H. Peter Anvin + * Document NASM behaviour for 64-bit immediates and displacements +Tue Sep 25 15:44:40 2007 -0700 H. Peter Anvin + * test/movimm.asm: add optimizable forms +Tue Sep 25 15:41:19 2007 -0700 H. Peter Anvin + * assemble.c: clean up whitespace +Tue Sep 25 15:40:36 2007 -0700 H. Peter Anvin + * Correct the handling of "MOV" with immediate in 64-bit mode +Tue Sep 25 15:39:42 2007 -0700 H. Peter Anvin + * Test of immediate handling on 64-bit mode +Tue Sep 25 14:27:34 2007 -0700 H. Peter Anvin + * Add nasm_zalloc() to nasmlib.c +Tue Sep 25 14:26:03 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 14:11:29 2007 -0700 H. Peter Anvin + * Fix BR 1490407: size of the second operand of LAR/LSL +Tue Sep 25 13:34:55 2007 -0700 H. Peter Anvin + * Makefile.in: make "make install" create directories +Tue Sep 25 08:48:37 2007 -0700 H. Peter Anvin + * Fix BR 1445441: uninitialized use of "error_file" +Mon Sep 24 21:33:17 2007 -0700 H. Peter Anvin + * preproc.c: fix the loop in %undef +Mon Sep 24 20:53:48 2007 -0700 H. Peter Anvin + * float.c: clear off uninitialized warning +Mon Sep 24 17:02:41 2007 -0700 H. Peter Anvin + * outcoff: set the "virtual size field" to zero (BR 1351586) +Mon Sep 24 15:56:02 2007 -0700 H. Peter Anvin + * insns.dat: SMINT - mark ND, DMINT - fix opcode +Mon Sep 24 15:55:20 2007 -0700 H. Peter Anvin + * 0F0F is a 3Dnow! prefix; remove from prefix list +Mon Sep 24 15:48:09 2007 -0700 H. Peter Anvin + * Additional compaction missed by script +Mon Sep 24 15:42:53 2007 -0700 H. Peter Anvin + * insns.dat: machine-generated compaction mmx/xmmreg,mem -> mmx/xmmrm +Mon Sep 24 13:54:00 2007 -0700 H. Peter Anvin + * nasmdoc: grammar fix +Mon Sep 24 13:44:02 2007 -0700 H. Peter Anvin + * nasmdoc: remove stray periods +Mon Sep 24 13:42:09 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Mon Sep 24 13:41:58 2007 -0700 H. Peter Anvin + * Implement the -MG option (SF RFE 1564264) +Mon Sep 24 12:52:09 2007 -0700 H. Peter Anvin + * nasmdoc: clarify __float*__ example +Mon Sep 24 12:44:38 2007 -0700 H. Peter Anvin + * nasmdoc: document the __float*__ operators +Mon Sep 24 12:30:54 2007 -0700 H. Peter Anvin + * Support __float*__ for floating-point numbers in expressions +Mon Sep 24 10:51:07 2007 -0700 H. Peter Anvin + * eval.c: replace sequence of ifs with switch +Mon Sep 24 10:50:23 2007 -0700 H. Peter Anvin + * tokhash: allow a bit smarter pattern matching +Sat Sep 22 22:35:28 2007 -0700 H. Peter Anvin + * Implement INVLPGA according to the documentation +Sat Sep 22 22:02:34 2007 -0700 H. Peter Anvin + * Reformat insns.dat to uniform column width +Sat Sep 22 21:50:03 2007 -0700 H. Peter Anvin + * Simple test for 0x67 prefixes +Sat Sep 22 21:49:51 2007 -0700 H. Peter Anvin + * Auto-generate 0x67 prefixes without the need for \30x codes +Sat Sep 22 21:47:13 2007 -0700 H. Peter Anvin + * Make test/Makefile a bit more useful +Sat Sep 22 21:29:41 2007 -0700 H. Peter Anvin + * Add TY_OWORD for "DO" output +Sat Sep 22 19:52:11 2007 -0700 H. Peter Anvin + * LDDQU needs \301 (BR 1103549) +Sat Sep 22 19:51:13 2007 -0700 H. Peter Anvin + * RDTSCP and INVLPGA aren't 64-bit specific +Sat Sep 22 19:40:37 2007 -0700 H. Peter Anvin + * Cyrix GX1 instructions: BBx_RESET, CPU_READ, CPU_WRITE +Sat Sep 22 19:28:14 2007 -0700 H. Peter Anvin + * Centaur XSHA1, XSHA256, MONTMUL +Sat Sep 22 19:20:56 2007 -0700 H. Peter Anvin + * Implement Centaur's XCRYPT instructions +Sat Sep 22 19:13:05 2007 -0700 H. Peter Anvin + * Add Geode LX (AMD's Cyrix-derived core) instructions +Sat Sep 22 19:05:11 2007 -0700 H. Peter Anvin + * Add the GETSEC instruction for Intel SMX +Sat Sep 22 18:59:18 2007 -0700 H. Peter Anvin + * Add the AMD SSE4a and LZCNT instructions +Sat Sep 22 18:23:20 2007 -0700 H. Peter Anvin + * Tag UMOV as ND (no disassembly) to avoid collision +Sat Sep 22 18:20:49 2007 -0700 H. Peter Anvin + * Disallow optimizing by less than 5 passes. +Sat Sep 22 17:45:45 2007 -0700 H. Peter Anvin + * BR 1783117: Document that %+ needs a space after it, and fix crash +Sat Sep 22 16:44:56 2007 -0700 H. Peter Anvin + * nasm.spec.in: minor fixes +Sat Sep 22 16:38:25 2007 -0700 H. Peter Anvin + * release script: handle stricter CLI parsing for "git tag" +Sat Sep 22 16:35:11 2007 -0700 H. Peter Anvin + * Update nasm.spec.in and make it handle rc releases +Sat Sep 22 16:19:19 2007 -0700 H. Peter Anvin + * version.pl: support version numbers of the form X.Y[.Z]rcW +Thu Sep 20 21:33:43 2007 -0700 Charles Crayne + * Merge branch 'master' of git+ssh://ccrayne@repo.or.cz/srv/git/nasm +Thu Sep 20 21:12:33 2007 -0700 Charles Crayne + * modified: misc/release to fix bug in removing .git +Wed Sep 19 21:41:43 2007 -0700 H. Peter Anvin + * Merge branch 'master' of git+ssh://repo.or.cz/srv/git/nasm +Wed Sep 19 21:41:27 2007 -0700 H. Peter Anvin + * Update manual pages +Wed Sep 19 21:41:02 2007 -0700 H. Peter Anvin + * Remove limit on number of sync points +Wed Sep 19 21:40:37 2007 -0700 H. Peter Anvin + * Make nasm_malloc() et al available from inside ndisasm +Wed Sep 19 21:07:32 2007 -0400 Frank Kotler + * Version 0.99.03 +Wed Sep 19 21:06:59 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Wed Sep 19 16:22:03 2007 -0700 H. Peter Anvin + * Merge commit 'origin/sse5' +Wed Sep 19 16:15:22 2007 -0700 H. Peter Anvin + * test/Makefile: make a bit more useful +Tue Sep 18 22:54:40 2007 -0700 H. Peter Anvin + * Slightly optimize the interface to nasm_token_hash() +Wed Sep 19 01:34:55 2007 -0400 Frank Kotler + * Merge branch 'master' of git+ssh://fbkotler@repo.or.cz/srv/git/nasm +Tue Sep 18 22:23:42 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 22:22:49 2007 -0700 H. Peter Anvin + * elf64: fix 32-bit truncations +Tue Sep 18 22:08:04 2007 -0700 H. Peter Anvin + * Document Infinity and NaN +Tue Sep 18 21:55:56 2007 -0700 H. Peter Anvin + * Support generating NaNs and infinities +Tue Sep 18 19:12:26 2007 -0700 H. Peter Anvin + * Update documentation +Tue Sep 18 18:37:36 2007 -0700 H. Peter Anvin + * Simple test for hexadecimal floating-point numbers +Tue Sep 18 18:33:17 2007 -0700 H. Peter Anvin + * Fix error-reporting in hexadecimal floating-point numbers +Tue Sep 18 18:31:26 2007 -0700 H. Peter Anvin + * Support C99-style hexadecimal floating point. +Tue Sep 18 17:50:34 2007 -0700 H. Peter Anvin + * Unify all standard IEEE floating-point formats; add 128-bit +Tue Sep 18 17:49:09 2007 -0700 H. Peter Anvin + * Fix handling of DO; support unary + for floating-point numbers +Tue Sep 18 16:39:03 2007 -0700 H. Peter Anvin + * Support 16-bit IEEE floating point; used in SSE5 +Tue Sep 18 15:43:40 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Tue Sep 18 15:43:08 2007 -0700 H. Peter Anvin + * Add NOP with argument to the instruction list +Tue Sep 18 15:24:38 2007 -0700 H. Peter Anvin + * Remove 0FC2 from list of instruction prefixes +Tue Sep 18 15:08:20 2007 -0700 H. Peter Anvin + * Speed up the disassembler by allowing prefixed instruction tables +Tue Sep 18 13:45:12 2007 -0700 H. Peter Anvin + * Document oword, do and reso +Tue Sep 18 13:01:32 2007 -0700 H. Peter Anvin + * Implement "oword" (128 bits) as a first-class size +Tue Sep 18 12:38:07 2007 -0700 H. Peter Anvin + * Change the token prehash function for better convergence +Tue Sep 18 12:23:21 2007 -0700 H. Peter Anvin + * SSE5 instruction table +Tue Sep 18 02:06:09 2007 -0400 Frank Kotler + * add "const" to output/outdbg.c +Mon Sep 17 18:45:44 2007 -0700 H. Peter Anvin + * Disassembler support for SSE5 instructions +Mon Sep 17 17:27:46 2007 -0700 H. Peter Anvin + * insns.dat: All SSE5 instructions are AMD +Mon Sep 17 17:25:27 2007 -0700 H. Peter Anvin + * Actually generate SSE5 instructions +Mon Sep 17 16:55:04 2007 -0700 H. Peter Anvin + * Initial support for generating DREX suffixes +Mon Sep 17 16:31:33 2007 -0700 H. Peter Anvin + * Fix a few instances of missing renumbers +Mon Sep 17 16:20:45 2007 -0700 H. Peter Anvin + * Enable IF_AR3 +Mon Sep 17 15:49:53 2007 -0700 H. Peter Anvin + * Merge commit 'origin/master' into sse5 +Mon Sep 17 15:49:30 2007 -0700 H. Peter Anvin + * Initial support for four arguments per instruction +Mon Sep 17 15:48:32 2007 -0700 H. Peter Anvin + * CLFLUSH: Neither an x64 instruction nor AMD +Mon Sep 17 13:56:26 2007 -0700 H. Peter Anvin + * Sort dependency lists +Mon Sep 17 13:53:14 2007 -0700 H. Peter Anvin + * Cleaner way to handle MSVC's _snprintf() underscore damage +Mon Sep 17 13:19:25 2007 -0700 H. Peter Anvin + * test/r13.asm: test special-casing of rbp and r13 in 64-bit mode +Mon Sep 17 13:03:33 2007 -0700 H. Peter Anvin + * Additional documentation for 64-bit programming +Sun Sep 16 22:27:07 2007 -0700 H. Peter Anvin + * INSTALL: MSVC++ compilation instructions +Sun Sep 16 22:17:29 2007 -0700 H. Peter Anvin + * make alldeps: change Mkfiles/Makefile.* to Mkfiles/*.mak +Sun Sep 16 22:16:24 2007 -0700 H. Peter Anvin + * Fix Makefile for MSVC++ 2005, delete obsolete Makefiles +Sun Sep 16 22:15:34 2007 -0700 H. Peter Anvin + * Minor fixes needed to compile with MSVC++ 2005 +Sun Sep 16 18:35:02 2007 -0700 H. Peter Anvin + * Run "make alldeps" +Sun Sep 16 18:04:57 2007 -0700 H. Peter Anvin + * Switch the preprocessor over to using the hash table library +Sun Sep 16 17:53:17 2007 -0700 H. Peter Anvin + * Fix the handling of local labels +Fri Sep 14 18:36:01 2007 -0700 H. Peter Anvin + * preproc.c: remove unnecessary int64_t +Fri Sep 14 18:03:29 2007 -0700 H. Peter Anvin + * Use the new hash table function library to store labels +Fri Sep 14 09:24:38 2007 -0700 H. Peter Anvin + * Define a proper hash table library +Thu Sep 13 18:13:20 2007 -0700 H. Peter Anvin + * Simple performance benchmarks: label, macro and token lookups +Thu Sep 13 12:25:32 2007 -0700 H. Peter Anvin + * release script: fix final cleanup +Thu Sep 13 12:22:00 2007 -0700 H. Peter Anvin + * Modify release script for a git-centric world +Thu Sep 13 11:06:42 2007 -0700 H. Peter Anvin + * pptok.c: don't insist on C99 compiler behaviour +Wed Sep 12 22:02:06 2007 -0700 H. Peter Anvin + * Fix literal F2 and F3 prefixes +Wed Sep 12 21:58:51 2007 -0700 H. Peter Anvin + * Add (untested!) SSSE3, SSE4.1, SSE4.2 instructions +Wed Sep 12 21:06:36 2007 -0700 H. Peter Anvin + * Add support for Tejas New Instructions (SSSE3) +Wed Sep 12 21:05:06 2007 -0700 H. Peter Anvin + * Remove $Id$ tags (useless with git) +Wed Sep 12 21:04:58 2007 -0700 H. Peter Anvin + * Use rm32 operands for VMREAD/VMWRITE +Wed Sep 12 21:04:51 2007 -0700 H. Peter Anvin + * Macros for SSSE3/SSE4 instruction sets +Wed Sep 12 21:04:39 2007 -0700 H. Peter Anvin + * Support r/m operands for non-integer types +Wed Sep 12 20:27:41 2007 -0700 H. Peter Anvin + * Use enumerations where practical to ease debugging +Wed Sep 12 17:02:55 2007 +0000 H. Peter Anvin + * pptok.c: quick-and-dirty downcasing during prehashing +Wed Sep 12 16:55:57 2007 +0000 H. Peter Anvin + * phash: Tell the user when the graph is OK +Wed Sep 12 05:18:20 2007 +0000 H. Peter Anvin + * pptok.c: handle holes in the pp_directives array +Wed Sep 12 04:20:08 2007 +0000 H. Peter Anvin + * preproc.c: adjust whitespace +Wed Sep 12 04:18:37 2007 +0000 H. Peter Anvin + * More automation in the preprocessor conditionals handling +Wed Sep 12 02:13:39 2007 +0000 H. Peter Anvin + * pptok.c: fix spacing +Wed Sep 12 02:12:07 2007 +0000 H. Peter Anvin + * Generate automatically correct tests for %if and %elif +Wed Sep 12 01:34:19 2007 +0000 H. Peter Anvin + * Run "make alldeps"; add dependencies missing from the previous checkin +Wed Sep 12 01:29:43 2007 +0000 H. Peter Anvin + * Use a perfect hash to look up preprocessor directives +Wed Sep 12 01:27:53 2007 +0000 H. Peter Anvin + * phash: Be a bit more aggressive about trying to make a small hash +Wed Sep 12 00:22:29 2007 +0000 H. Peter Anvin + * Add RCXZ as a known preprocessor condition +Tue Sep 11 23:57:23 2007 +0000 H. Peter Anvin + * doc: add some cross-references +Tue Sep 11 23:52:01 2007 +0000 H. Peter Anvin + * Feeble attempt at updating the documentation; remove Appendix B +Tue Sep 11 22:44:03 2007 +0000 H. Peter Anvin + * Handle instructions which can have both REX.W and OSP +Tue Sep 11 22:14:18 2007 +0000 H. Peter Anvin + * Use enums to make debugging easier +Tue Sep 11 22:13:17 2007 +0000 H. Peter Anvin + * ndisasm: handle \366 codes, prefer unprefixed instructions +Tue Sep 11 22:00:34 2007 +0000 H. Peter Anvin + * Simplify tokens.dat slightly +Tue Sep 11 04:26:44 2007 +0000 H. Peter Anvin + * Quiet gcc warning about uninitialized variables +Tue Sep 11 04:16:57 2007 +0000 H. Peter Anvin + * Make the big instruction arrays "const" +Mon Sep 10 23:32:05 2007 +0000 H. Peter Anvin + * Use an actual enum for the opcode +Mon Sep 10 23:30:21 2007 +0000 H. Peter Anvin + * Fix order of token arguments +Mon Sep 10 18:59:26 2007 +0000 H. Peter Anvin + * assemble.c: correct special handing of ESP/RSP +Mon Sep 10 18:59:01 2007 +0000 H. Peter Anvin + * tokhash: correct duplicate-token test +Mon Sep 10 18:58:40 2007 +0000 H. Peter Anvin + * tokhash: adjust table types to reduce size +Mon Sep 10 18:55:52 2007 +0000 H. Peter Anvin + * Fix the MMXREG and XMMREG flags definitions. +Wed Sep 5 06:48:38 2007 +0000 H. Peter Anvin + * nasm.spec.in: Copyright -> License +Wed Sep 5 06:40:51 2007 +0000 H. Peter Anvin + * Fix "make tar"; useful for RPM testing +Wed Sep 5 06:24:43 2007 +0000 H. Peter Anvin + * Remove obsolete Serial: construct; we shouldn't need it anyway. +Tue Sep 4 01:29:43 2007 +0000 Chuck Crayne + * Provide 64-bit support for ORG directive +Sun Sep 2 16:37:03 2007 +0000 H. Peter Anvin + * Fix some MMX/SSE irregularities which interact with the 64-bit support +Sun Sep 2 14:46:00 2007 +0000 H. Peter Anvin + * phash.ph: yet another attempt at getting Perl to behave, arithmetically +Sun Sep 2 06:23:29 2007 +0000 H. Peter Anvin + * Simple 64-bit org test +Sun Sep 2 06:20:15 2007 +0000 H. Peter Anvin + * phash.ph: remove some stale code +Sun Sep 2 01:00:34 2007 +0000 Chuck Crayne + * Force use of integer values for generating hash keys. +Fri Aug 31 18:10:23 2007 +0000 H. Peter Anvin + * phash: don't rely on the build platform Perl version of rand() +Fri Aug 31 07:31:51 2007 +0000 H. Peter Anvin + * tokhash.pl: formatting changes for readability +Fri Aug 31 07:23:31 2007 +0000 H. Peter Anvin + * tokhash: Speed up the rejection of unhashed values +Fri Aug 31 06:06:17 2007 +0000 H. Peter Anvin + * tokhash.pl: "ix" should have the same width as the "hash" arrays +Fri Aug 31 00:28:35 2007 +0000 H. Peter Anvin + * Add "do not edit" comment to tokhash.c +Fri Aug 31 00:23:40 2007 +0000 H. Peter Anvin + * Make the token hash a bit smaller by using 16-bit hash tables +Fri Aug 31 00:16:10 2007 +0000 H. Peter Anvin + * Minor cleanup; remove duplication of names.c +Thu Aug 30 23:42:39 2007 +0000 H. Peter Anvin + * phash.ph: use a bipartite graph to reduce the storage requirements +Thu Aug 30 22:35:34 2007 +0000 H. Peter Anvin + * Finishing touches on perfect hash tokenizer; actually turn the thing on +Thu Aug 30 21:50:20 2007 +0000 H. Peter Anvin + * Makefile rule for tokhash.c +Thu Aug 30 21:47:46 2007 +0000 H. Peter Anvin + * tokens.dat: Data file containing alphanumeric tokens not in other .dats +Thu Aug 30 21:45:56 2007 +0000 H. Peter Anvin + * Generate a perfect hash for the token parser +Thu Aug 30 21:40:08 2007 +0000 H. Peter Anvin + * Fix bugs in repeated suffix handling, which led to missing r8d/r8w/r8d +Thu Aug 30 21:39:37 2007 +0000 H. Peter Anvin + * phash.ph: more powerful prehashing +Thu Aug 30 20:15:25 2007 +0000 H. Peter Anvin + * Make the perfect hash generator an includable module +Wed Aug 29 20:30:31 2007 +0000 H. Peter Anvin + * Correct the logic for recording fs: and gs: overrides. +Wed Aug 29 18:20:19 2007 +0000 H. Peter Anvin + * Generate R_X86_64_64 relocations in elf64 output +Wed Aug 29 17:24:03 2007 +0000 H. Peter Anvin + * Add README file +Wed Aug 29 17:20:09 2007 +0000 H. Peter Anvin + * Create a Perl library directory, and add the Graph module to it +Wed Aug 29 17:05:17 2007 +0000 H. Peter Anvin + * Perfect hash generator, as a perl script +Wed Aug 29 16:41:43 2007 +0000 H. Peter Anvin + * Use standard macro for the default directive +Wed Aug 29 16:40:26 2007 +0000 H. Peter Anvin + * Add standard macro for [default] directive +Wed Aug 29 16:38:47 2007 +0000 H. Peter Anvin + * More test cases for rel and abs addressing +Wed Aug 29 16:38:05 2007 +0000 H. Peter Anvin + * Add [default] directive +Wed Aug 29 16:25:46 2007 +0000 H. Peter Anvin + * nasmlib: add bsii() case-insensitive version of bsi() +Wed Aug 29 15:49:53 2007 +0000 H. Peter Anvin + * Add test cases for IP-relative addressing +Wed Aug 29 15:19:19 2007 +0000 H. Peter Anvin + * Suppress IP-relative only for fs: and gs: overrides +Tue Aug 28 23:06:00 2007 +0000 H. Peter Anvin + * Implement REL/ABS modifiers +Sun Aug 26 05:51:39 2007 +0000 Frank Kotler + * attempt to make static makefiles aware of outelf32/outelf64 +Sun Aug 26 05:48:54 2007 +0000 Frank Kotler + * add nasm_strsep to nasmlib, for output/outmacho.c - strtok doesn't work +Sun Aug 26 05:41:33 2007 +0000 Frank Kotler + * remove "#include from rdoff directory - two places - it annoyed Windows users and seems unneeded +Sun Aug 26 05:10:24 2007 +0000 Frank Kotler + * finally commit Mike Frysinger's "elf-visibility" patch +Mon Aug 20 21:03:14 2007 +0000 H. Peter Anvin + * regs.pl: handle dashed sequences with suffixes +Mon Aug 20 20:10:04 2007 +0000 H. Peter Anvin + * sync.c: change ULONG_MAX to UINT32_MAX +Mon Aug 20 20:09:11 2007 +0000 H. Peter Anvin + * Add _MIN and _MAX macros for the fixed-size types. +Mon Aug 20 20:02:17 2007 +0000 H. Peter Anvin + * ldrdf: cast output of sizeof() before passing to printf(), to avoid warning. +Sun Aug 19 18:49:26 2007 +0000 Keith Kanios + * Fixed RIP address processing ambiguity found by Charles Crayne. +Fri Aug 17 07:37:52 2007 +0000 Keith Kanios + * Fixed issues with REX prefix effective address generation. Fixed XMM instruction output. +Fri Aug 17 02:03:10 2007 +0000 Keith Kanios + * Changed MMXREG and XMMREG flags to help resolve invalid REX prefix generation for MMX instructions. +Sat Jul 7 02:01:08 2007 +0000 H. Peter Anvin + * More int/int32_t confusion +Sat Jul 7 01:59:52 2007 +0000 H. Peter Anvin + * regflag() should return int32_t. +Thu Jun 21 19:00:12 2007 +0000 H. Peter Anvin + * Detect missing and include ersatz version if missing +Thu Jun 21 06:24:23 2007 +0000 H. Peter Anvin + * inttypes.h: for older preprocessors, specify L and LL as appropriate +Thu Jun 21 06:20:43 2007 +0000 H. Peter Anvin + * inttypes.h: Fix spelling of SHRT_MAX +Thu Jun 21 06:15:42 2007 +0000 H. Peter Anvin + * inttypes.h: do a single ersatz based on +Sun Jun 3 02:42:41 2007 +0000 Chuck Crayne + * Support 32-bit direct addressing in 64-bit mode without base or index regs +Sat Jun 2 02:26:21 2007 +0000 H. Peter Anvin + * Fix the [U]INT*_C() creation macros +Sat Jun 2 00:05:35 2007 +0000 H. Peter Anvin + * For platforms that don't have them, provide for common models. +Wed May 30 22:21:11 2007 +0000 H. Peter Anvin + * Fix the handling of the \313 code. +Wed May 30 22:20:01 2007 +0000 H. Peter Anvin + * Machine-generated \321->\324 corrections +Wed May 30 21:22:33 2007 +0000 Frank Kotler + * update "version" to 0.99.02 +Wed May 30 20:30:15 2007 +0000 H. Peter Anvin + * Correct the generation of 67 prefixes. +Wed May 30 18:30:18 2007 +0000 H. Peter Anvin + * Update dependencies. +Wed May 30 16:34:29 2007 +0000 Frank Kotler + * update cvs server name in misc/release script +Wed May 30 04:28:50 2007 +0000 H. Peter Anvin + * Avoid magic values; we have more than 124 registers now +Wed May 30 04:27:58 2007 +0000 H. Peter Anvin + * Remove bogus redundant tests +Wed May 30 03:44:50 2007 +0000 H. Peter Anvin + * More \321 -> \324 +Wed May 30 03:44:02 2007 +0000 H. Peter Anvin + * Remove bogus check for 64-bitness +Wed May 30 03:25:21 2007 +0000 H. Peter Anvin + * Get rid of magic open-coded "register numbers" +Wed May 30 02:48:51 2007 +0000 H. Peter Anvin + * MOV reg64,reg64 takes \324 (64 bit with REX) not \321 (32 bit) +Wed May 30 00:18:26 2007 +0000 H. Peter Anvin + * Rename REGNORM to REG_EA +Wed May 30 00:15:25 2007 +0000 H. Peter Anvin + * More instruction flag surgery +Wed May 30 00:05:00 2007 +0000 H. Peter Anvin + * More cleanup of operand flags/register classes +Tue May 29 23:57:12 2007 +0000 H. Peter Anvin + * Clean up the existing operand flag definitions, and document +Tue May 29 21:44:55 2007 +0000 H. Peter Anvin + * Run "make alldeps" +Thu May 24 22:33:07 2007 +0000 Frank Kotler + * update version number to 0.99.01 +Tue May 15 04:33:43 2007 +0000 H. Peter Anvin + * regs.dat: fix comment +Fri May 4 18:47:16 2007 +0000 H. Peter Anvin + * 16-bit relocations are standard in ELF64 (at my request, incidentally) +Fri May 4 02:16:08 2007 +0000 Chuck Crayne + * Addition of elf32 and elf64 output formats. +Wed May 2 04:21:26 2007 +0000 Chuck Crayne + * Allow '!' to be used in expressions with same meaning as in C. +Wed May 2 01:59:16 2007 +0000 Chuck Crayne + * Add %IFN and %ELIFN as per RFE #786286 +Mon Apr 30 22:26:58 2007 +0000 Chuck Crayne + * Accept responsibility for support of outelf64.c +Sun Apr 29 20:57:53 2007 +0000 Chuck Crayne + * Clarify comments about relocation entries. +Sun Apr 29 00:28:24 2007 +0000 Chuck Crayne + * Allow ELF32 to be invoked either as -f elf or -f elf32 +Sat Apr 28 22:18:04 2007 +0000 Chuck Crayne + * Eliminate shift count warnings when building on 32-bit systems +Sat Apr 28 06:18:48 2007 +0000 Chuck Crayne + * Initial support for ELF64 +Wed Apr 18 02:27:18 2007 +0000 H. Peter Anvin + * Fix the handling of \324 for computing the length +Wed Apr 18 02:24:34 2007 +0000 Keith Kanios + * Fixed RDF/2 to comply with "maxbits" use. +Tue Apr 17 20:23:11 2007 +0000 H. Peter Anvin + * Handle "LOCK as REX.R" for MOV CRx; fix warning for invalid 64-bit regs +Mon Apr 16 18:16:46 2007 +0000 Keith Kanios + * MEM_OFFSET Instructions Fixed. +Mon Apr 16 15:46:46 2007 +0000 Keith Kanios + * Fixed 64-bit Mode Segment Selection. +Mon Apr 16 14:31:54 2007 +0000 Keith Kanios + * Fixed distinction between [LOCAL]SYMBOL/IMMEDIATE for RIP-relative addressing. +Mon Apr 16 14:05:01 2007 +0000 Keith Kanios + * Fixed long mode MEM_OFFS issue. +Mon Apr 16 13:54:49 2007 +0000 Keith Kanios + * Filled in all RIP Register Flags. +Mon Apr 16 05:26:29 2007 +0000 H. Peter Anvin + * More \321 -> \324 for 64-bit instructions +Mon Apr 16 04:56:06 2007 +0000 Keith Kanios + * Fixed 64-bit offset generation. +Mon Apr 16 02:39:56 2007 +0000 H. Peter Anvin + * More 64-bit ndisasm fixes. +Mon Apr 16 02:02:06 2007 +0000 H. Peter Anvin + * Fixes for 64-bit ndisasm. +Mon Apr 16 01:21:29 2007 +0000 H. Peter Anvin + * Use + instead of * for extension; it feels cleaner with the new meaning. +Mon Apr 16 01:18:30 2007 +0000 H. Peter Anvin + * Initial 64-bit support for ndisasm. Still a work in progress. +Sun Apr 15 23:12:17 2007 +0000 H. Peter Anvin + * Clean up the 64-bitification of regs.dat for 64-bit ndisasm support +Sun Apr 15 23:10:26 2007 +0000 H. Peter Anvin + * Remove @GCCFLAGS@ +Sun Apr 15 23:09:23 2007 +0000 H. Peter Anvin + * CR8 is not special in any way as far as the assembler is concerned. +Sun Apr 15 23:03:28 2007 +0000 H. Peter Anvin + * Get rid of @GCCFLAGS@ +Sun Apr 15 22:45:25 2007 +0000 H. Peter Anvin + * Cleaner way to add gcc options +Sun Apr 15 22:08:30 2007 +0000 Keith Kanios + * Fixed distinction between RIP relative symbols and immediate values. +Sun Apr 15 05:40:43 2007 +0000 H. Peter Anvin + * Fix the register number for CR7 (it was using the same number as CR15). +Sun Apr 15 05:32:18 2007 +0000 H. Peter Anvin + * More perl-like idioms for generating regdis.c +Sun Apr 15 01:37:13 2007 +0000 Keith Kanios + * Fixed regdis.c generation. +Sat Apr 14 18:54:52 2007 +0000 Keith Kanios + * Added DQ constants for all BITS modes. +Sat Apr 14 08:03:02 2007 +0000 H. Peter Anvin + * outmacho.c: stylistic cleanups +Sat Apr 14 03:52:05 2007 +0000 Keith Kanios + * Fixed support for DQ constants in long mode. +Sat Apr 14 03:44:31 2007 +0000 Keith Kanios + * Hopefully it is actually fixed this time :P +Sat Apr 14 01:49:07 2007 +0000 Keith Kanios + * Fixed structure initialization issue. +Sat Apr 14 01:44:35 2007 +0000 Keith Kanios + * Refixed uninitialized data. +Sat Apr 14 01:40:24 2007 +0000 Keith Kanios + * Fixed uninitialized structure data. +Sat Apr 14 01:24:14 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Sat Apr 14 00:46:25 2007 +0000 Keith Kanios + * Placated unreferenced types. +Sat Apr 14 00:10:59 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Fri Apr 13 23:09:18 2007 +0000 Keith Kanios + * Added outmacho.* to static makefile. +Fri Apr 13 22:24:46 2007 +0000 Keith Kanios + * Fixed REGRIP -> RIPREG to match regs.dat. +Fri Apr 13 22:07:53 2007 +0000 Keith Kanios + * Fixed obj_fwrite() declaration to match "static" definition. +Fri Apr 13 22:03:24 2007 +0000 Keith Kanios + * Added appropriate "void" prototypes. +Fri Apr 13 22:00:42 2007 +0000 Keith Kanios + * Replaced str(n)casecmp with more standard str(n)icmp. +Fri Apr 13 20:06:41 2007 +0000 H. Peter Anvin + * AIf we have config.h, we should actually include it!! +Fri Apr 13 19:59:20 2007 +0000 H. Peter Anvin + * When compiling with gcc, compile with -W -Wall for maximum warnings. +Fri Apr 13 19:58:42 2007 +0000 H. Peter Anvin + * Macroize any compiler-specific code; macros defined in "compiler.h" +Fri Apr 13 16:47:53 2007 +0000 Keith Kanios + * Fixed distinction between char and int8_t data types. +Fri Apr 13 01:17:45 2007 +0000 Keith Kanios + * Comment "REX.I" should have been "REX.X" +Fri Apr 13 00:52:54 2007 +0000 Keith Kanios + * Fixed c99 data-types after removal of typedefs. +Fri Apr 13 00:43:50 2007 +0000 Keith Kanios + * Added Dev-Cpp Makefile +Fri Apr 13 00:38:29 2007 +0000 Keith Kanios + * *** empty log message *** +Thu Apr 12 17:58:02 2007 +0000 H. Peter Anvin + * Remove redundant inclusion of +Thu Apr 12 16:54:50 2007 +0000 H. Peter Anvin + * Remove obsolete types; add where needed; header fixes +Thu Apr 12 16:25:58 2007 +0000 H. Peter Anvin + * autogen.sh script to create configure, et al. +Thu Apr 12 16:23:11 2007 +0000 Keith Kanios + * Fixed c99 support for RDOFF Tools +Thu Apr 12 16:12:09 2007 +0000 H. Peter Anvin + * outmacho.c: Don't assume __builtin_ctzl exists for gcc < 4 + + * Get rid of @GCCFLAGS@ +Sun Apr 15 22:45:25 2007 +0000 H. Peter Anvin + * Cleaner way to add gcc options +Sun Apr 15 22:08:30 2007 +0000 Keith Kanios + * Fixed distinction between RIP relative symbols and immediate values. +Sun Apr 15 05:40:43 2007 +0000 H. Peter Anvin + * Fix the register number for CR7 (it was using the same number as CR15). +Sun Apr 15 05:32:18 2007 +0000 H. Peter Anvin + * More perl-like idioms for generating regdis.c +Sun Apr 15 01:37:13 2007 +0000 Keith Kanios + * Fixed regdis.c generation. +Sat Apr 14 18:54:52 2007 +0000 Keith Kanios + * Added DQ constants for all BITS modes. +Sat Apr 14 08:03:02 2007 +0000 H. Peter Anvin + * outmacho.c: stylistic cleanups +Sat Apr 14 03:52:05 2007 +0000 Keith Kanios + * Fixed support for DQ constants in long mode. +Sat Apr 14 03:44:31 2007 +0000 Keith Kanios + * Hopefully it is actually fixed this time :P +Sat Apr 14 01:49:07 2007 +0000 Keith Kanios + * Fixed structure initialization issue. +Sat Apr 14 01:44:35 2007 +0000 Keith Kanios + * Refixed uninitialized data. +Sat Apr 14 01:40:24 2007 +0000 Keith Kanios + * Fixed uninitialized structure data. +Sat Apr 14 01:24:14 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Sat Apr 14 00:46:25 2007 +0000 Keith Kanios + * Placated unreferenced types. +Sat Apr 14 00:10:59 2007 +0000 Keith Kanios + * c99 printf/fprintf compliance. +Fri Apr 13 23:09:18 2007 +0000 Keith Kanios + * Added outmacho.* to static makefile. +Fri Apr 13 22:24:46 2007 +0000 Keith Kanios + * Fixed REGRIP -> RIPREG to match regs.dat. +Fri Apr 13 22:07:53 2007 +0000 Keith Kanios + * Fixed obj_fwrite() declaration to match "static" definition. +Fri Apr 13 22:03:24 2007 +0000 Keith Kanios + * Added appropriate "void" prototypes. +Fri Apr 13 22:00:42 2007 +0000 Keith Kanios + * Replaced str(n)casecmp with more standard str(n)icmp. +Fri Apr 13 20:06:41 2007 +0000 H. Peter Anvin + * AIf we have config.h, we should actually include it!! +Fri Apr 13 19:59:20 2007 +0000 H. Peter Anvin + * When compiling with gcc, compile with -W -Wall for maximum warnings. +Fri Apr 13 19:58:42 2007 +0000 H. Peter Anvin + * Macroize any compiler-specific code; macros defined in "compiler.h" +Fri Apr 13 16:47:53 2007 +0000 Keith Kanios + * Fixed distinction between char and int8_t data types. +Fri Apr 13 01:17:45 2007 +0000 Keith Kanios + * Comment "REX.I" should have been "REX.X" +Fri Apr 13 00:52:54 2007 +0000 Keith Kanios + * Fixed c99 data-types after removal of typedefs. +Fri Apr 13 00:43:50 2007 +0000 Keith Kanios + * Added Dev-Cpp Makefile +Fri Apr 13 00:38:29 2007 +0000 Keith Kanios + * *** empty log message *** +Thu Apr 12 17:58:02 2007 +0000 H. Peter Anvin + * Remove redundant inclusion of +Thu Apr 12 16:54:50 2007 +0000 H. Peter Anvin + * Remove obsolete types; add where needed; header fixes +Thu Apr 12 16:25:58 2007 +0000 H. Peter Anvin + * autogen.sh script to create configure, et al. +Thu Apr 12 16:23:11 2007 +0000 Keith Kanios + * Fixed c99 support for RDOFF Tools +Thu Apr 12 16:12:09 2007 +0000 H. Peter Anvin + * outmacho.c: Don't assume __builtin_ctzl exists for gcc < 4 +2007-04-10 Keith Kanios + * (insns.dat): updated x86-64 general+system instruction set. + +2007-04-09 Keith Kanios + * (outrdf.c): added support for 64-bit addressing. + * (outrdf2.c): added support for 64-bit addressing. + +2007-04-08 Keith Kanios + * (standard.mac): added entry for __BITS__ standard macro. + * (preproc.c): added __BITS__ to the standard macro processing. + +2007-04-05 Keith Kanios + * (nasm.c): added [BITS 64] for the x86-64 architecture extension. + * (nasm.h): added general flags to support the x86-64 architecture. + * (nasmlib.h): updated to support the x86-64 architecture. + * (nasmlib.c): revamped readnum/readlinenum to support 64-bit. + * (assemble.c): modified for the x86-64 architecture extension. + * (regs.dat): added x86-64 register extensions; revamped flags. + * (insns.dat): added AMD64 instruction set support. + * (outbin.c): added support for 64-bit addressing. + * (outcoff.c): added win64 (x86-64 COFF) support. + * (outform.h): added entry for win64. + +2007-03-15 Keith Kanios + * (*.c): added c99 data-type compliance and inclusion. + * (*.pl): added c99 data-type compliance and inclusion. + * (*.h): added c99 data-type compliance. + * (assemble.h): fixed procedure defintions to sync with respective + procedure declarations. + +2002-05-16 Ed Beroset + * (preproc.c): fixed unterminated macro bug error reporting + * (nasmlib.h): changed strdup's arg to const char * + * (nasmlib.c): changed strdup's arg to const char * + +2002-05-12 Debbie Wiles + * (insns.dat): fixed incorrect processor flags + * (Mkfiles/Makefile.vc): added optimisation, and changed to work with 0.98.31 + * (doc/nasmdoc.src): added %ifmacro, and tidied up format of code items. + +2002-05-03 H. Peter Anvin + * (nasm.c): Change the NASM environment variable to NASMOPT. + +2002-05-03 H. Peter Anvin + * (Makefile.in Mkfiles/*): use new version -> version.{h,mac}. + * (macros.pl): support multiple input files (standard.mac, version.mac). + * (standard.mac): use an explicit delimiter to end the TASM macros. + * (nasm-version): remove, no longer needed. + * (version.pl): script to produce version.h and version.mac from version. + * (version): contains the official NASM version. + * (nasm.h): include version.h. + +2002-05-03 H. Peter Anvin + + * (configure.in): create output directory. + * (Makefile.in): change cd ; to cd &&. + * (rdoff/Makefile.in): handle building in a separate obj directory + correctly. + +2002-04-29 Stanislav Karchebny + + * (Makefile.in): added 'strip' target to strip debug info. + * (INSTALL): added INSTALL file. + * (nasm.1): added -v option description. + + +2002-04-29 Frank Kotler + + * (parser.c): fixed INCBIN bug reported by Rebel. + + +2002-04-11 Stanislav Karchebny + + * Started ChangeLog for recording per-file changes in the project. + We could get away without ChangeLog at all (use CVS logs), but we + lose CVS so often its better to have log glued to the sources =) + You should record changes in CHANGES also, not for every change + but rather when making a release. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..d184982 --- /dev/null +++ b/INSTALL @@ -0,0 +1,102 @@ +1. Installing NASM from source (Unix, MacOS X; Windows - Cygwin; + Windows - MinGW; DOS - DJGPP) +2. Installing NASM from source (Windows - MS Visual C++) +3. Installing NASM from source (DOS, Windows, OS/2 - OpenWatcom) + + +1. Installing NASM from source (Unix, MacOS X; Windows - Cygwin; + Windows - MinGW; DOS - DJGPP) +================================================================ + +Installing NASM is pretty straightforward on Unix or Unix-like systems +with a C compiler, Make, and standard shell tools installed, including +MinGW for Windows (with MSYS installed) and DJGPP for DOS with the +appropriate tools. Perl is not required for compiling unmodified +sources from a tarball, but is required to build from git or for most +source modifications. + +If you checked out source from git you will need to run autoconf to +generate configure, otherwise you don't have to. + +$ sh autogen.sh + +Then run configure to detect your platform settings and generate makefiles. + +$ sh configure + +You can get information about available configuration options by +running `sh configure --help`. + +If configure fails, please file a bug report with detailed platform +information at: + + http://www.sf.net/projects/nasm/ + +If everything went okay, type + +$ make + +to build NASM, ndisasm and rdoff tools, or + +$ make everything + +to build the former plus the docs. + +You can decrease the size of produces executables by stripping off +unnecessary information, to achieve this run + +$ make strip + +If you install to a system-wide location you might need to become +root: + +$ su + +then + +$ make install + +optionally followed by + +$ make install_rdf + +Or you can + +$ make install_everything + +to install everything =) + + +Thats it, enjoy! + + +2. Installing NASM from source (Windows - MS Visual C++) +======================================================== + +The recommended compiler for NASM on Windows is MinGW +(http://www.mingw.org/), but it is also possible to compile with +Microsoft Visual C++ (tested with Visual C++ 2005 Express Edition.) + +To do so, start the "Visual C++ Command Shell", go to the directory +where the NASM source code was extracted, and run: + +> nmake /f Mkfiles/msvc.mak + +We recommend MinGW over Visual C++ 2005 as we have found it to be more +up to date with regards to C99 compliance, and we are increasingly +using C99 features in NASM. + + +3. Installing NASM from source (DOS, Windows, OS/2 - OpenWatcom) +================================================================ + +NASM has been reported to build correctly with OpenWatcom 1.7 on the +Windows and OS/2 platforms. In addition, it *should* work under DOS +with the DOS4GW DOS extender, although the NASM developers recommend +using DJGPP with the CWSDPMI DOS extender instead. + +A WMAKE make file is provided: + +> wmake -f Mkfiles\openwcom.mak + +... where is "dos", "win32" or "os2". diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..331e260 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +NASM is now licensed under the 2-clause BSD license, also known as the +simplified BSD license. + + Copyright 1996-2010 the NASM Authors - All rights reserved. + + 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. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..949d013 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,529 @@ +# +# Auto-configuring Makefile for the Netwide Assembler. +# +# The Netwide Assembler is copyright (C) 1996 Simon Tatham and +# Julian Hall. All rights reserved. The software is +# redistributable under the license given in the file "LICENSE" +# distributed in the NASM archive. + +@SET_MAKE@ + +top_srcdir = @top_srcdir@ +srcdir = @srcdir@ +objdir = @builddir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ +datarootdir = @datarootdir@ + +CC = @CC@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +BUILD_CFLAGS = $(CPPFLAGS) $(CFLAGS) @DEFS@ +INTERNAL_CFLAGS = -I$(srcdir) -I$(objdir) \ + -I$(srcdir)/include -I$(objdir)/include \ + -I$(srcdir)/x86 -I$(objdir)/x86 \ + -I$(srcdir)/asm -I$(objdir)/asm \ + -I$(srcdir)/disasm -I$(objdir)/disasm \ + -I$(srcdir)/output -I$(objdir)/output +ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS) +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ + +AR = @AR@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ + +PERL = perl +PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir) +RUNPERL = $(PERL) $(PERLFLAGS) + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +NROFF = @NROFF@ +ASCIIDOC = @ASCIIDOC@ +XMLTO = @XMLTO@ + +MAKENSIS = makensis + +MKDIR = mkdir -p +RM_F = rm -f +RM_RF = rm -rf +LN_S = @LN_S@ +FIND = find + +# Binary suffixes +O = @OBJEXT@ +X = @EXEEXT@ +A = @LIBEXT@ + +# Debug stuff +ifeq ($(TRACE),1) + CFLAGS += -DNASM_TRACE +endif + +.SUFFIXES: +.SUFFIXES: $(X) .$(O) .$(A) .xml .1 .c .i .s .txt + +.PHONY: all doc rdf install clean distclean cleaner spotless install_rdf test +.PHONY: install_doc everything install_everything strip perlreq dist tags TAGS +.PHONY: manpages nsis + +.c.$(O): + $(CC) -c $(ALL_CFLAGS) -o $@ $< + +.c.s: + $(CC) -S $(ALL_CFLAGS) -o $@ $< + +.c.i: + $(CC) -E $(ALL_CFLAGS) -o $@ $< + +.txt.xml: + $(ASCIIDOC) -b docbook -d manpage -o $@ $< + +.xml.1: + $(XMLTO) man --skip-validation $< 2>/dev/null + +#-- Begin File Lists --# +NASM = asm/nasm.$(O) +NDISASM = disasm/ndisasm.$(O) + +LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \ + stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) \ + \ + nasmlib/ver.$(O) \ + nasmlib/crc64.$(O) nasmlib/malloc.$(O) \ + nasmlib/md5c.$(O) nasmlib/string.$(O) \ + nasmlib/file.$(O) nasmlib/mmap.$(O) nasmlib/ilog2.$(O) \ + nasmlib/realpath.$(O) nasmlib/path.$(O) \ + nasmlib/filename.$(O) nasmlib/srcfile.$(O) \ + nasmlib/zerobuf.$(O) nasmlib/readnum.$(O) nasmlib/bsi.$(O) \ + nasmlib/rbtree.$(O) nasmlib/hashtbl.$(O) \ + nasmlib/raa.$(O) nasmlib/saa.$(O) \ + nasmlib/strlist.$(O) \ + nasmlib/perfhash.$(O) nasmlib/badenum.$(O) \ + \ + common/common.$(O) \ + \ + x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsd.$(O) x86/insnsn.$(O) \ + x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) \ + x86/disp8.$(O) x86/iflag.$(O) \ + \ + asm/error.$(O) \ + asm/float.$(O) \ + asm/directiv.$(O) asm/directbl.$(O) \ + asm/pragma.$(O) \ + asm/assemble.$(O) asm/labels.$(O) asm/parser.$(O) \ + asm/preproc.$(O) asm/quote.$(O) asm/pptok.$(O) \ + asm/listing.$(O) asm/eval.$(O) asm/exprlib.$(O) asm/exprdump.$(O) \ + asm/stdscan.$(O) \ + asm/strfunc.$(O) asm/tokhash.$(O) \ + asm/segalloc.$(O) \ + asm/preproc-nop.$(O) \ + asm/rdstrnum.$(O) \ + \ + macros/macros.$(O) \ + \ + output/outform.$(O) output/outlib.$(O) output/legacy.$(O) \ + output/strtbl.$(O) \ + output/nulldbg.$(O) output/nullout.$(O) \ + output/outbin.$(O) output/outaout.$(O) output/outcoff.$(O) \ + output/outelf.$(O) \ + output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \ + output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \ + output/codeview.$(O) \ + \ + disasm/disasm.$(O) disasm/sync.$(O) + +SUBDIRS = stdlib nasmlib output asm disasm x86 common macros +XSUBDIRS = test doc nsis rdoff +DEPDIRS = . include config x86 rdoff $(SUBDIRS) +#-- End File Lists --# + +all: nasm$(X) ndisasm$(X) rdf + +NASMLIB = libnasm.$(A) + +$(NASMLIB): $(LIBOBJ) + $(RM_F) $(NASMLIB) + $(AR) cq $(NASMLIB) $(LIBOBJ) + $(RANLIB) $(NASMLIB) + +nasm$(X): $(NASM) $(NASMLIB) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o nasm$(X) $(NASM) $(NASMLIB) $(LIBS) + +ndisasm$(X): $(NDISASM) $(NASMLIB) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o ndisasm$(X) $(NDISASM) $(NASMLIB) $(LIBS) + +#-- Begin Generated File Rules --# + +# These source files are automagically generated from data files using +# Perl scripts. They're distributed, though, so it isn't necessary to +# have Perl just to recompile NASM from the distribution. + +# Perl-generated source files +PERLREQ = x86/insnsb.c x86/insnsa.c x86/insnsd.c x86/insnsi.h x86/insnsn.c \ + x86/regs.c x86/regs.h x86/regflags.c x86/regdis.c x86/regdis.h \ + x86/regvals.c asm/tokhash.c asm/tokens.h asm/pptok.h asm/pptok.c \ + x86/iflag.c x86/iflaggen.h \ + macros/macros.c \ + asm/pptok.ph asm/directbl.c asm/directiv.h \ + version.h version.mac version.mak nsis/version.nsh + +INSDEP = x86/insns.dat x86/insns.pl x86/insns-iflags.ph + +x86/iflag.c: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -fc \ + $(srcdir)/x86/insns.dat x86/iflag.c +x86/iflaggen.h: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -fh \ + $(srcdir)/x86/insns.dat x86/iflaggen.h +x86/insnsb.c: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -b \ + $(srcdir)/x86/insns.dat x86/insnsb.c +x86/insnsa.c: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -a \ + $(srcdir)/x86/insns.dat x86/insnsa.c +x86/insnsd.c: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -d \ + $(srcdir)/x86/insns.dat x86/insnsd.c +x86/insnsi.h: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -i \ + $(srcdir)/x86/insns.dat x86/insnsi.h +x86/insnsn.c: $(INSDEP) + $(RUNPERL) $(srcdir)/x86/insns.pl -n \ + $(srcdir)/x86/insns.dat x86/insnsn.c + +# These files contains all the standard macros that are derived from +# the version number. +version.h: version version.pl + $(RUNPERL) $(srcdir)/version.pl h < $(srcdir)/version > version.h +version.mac: version version.pl + $(RUNPERL) $(srcdir)/version.pl mac < $(srcdir)/version > version.mac +version.sed: version version.pl + $(RUNPERL) $(srcdir)/version.pl sed < $(srcdir)/version > version.sed +version.mak: version version.pl + $(RUNPERL) $(srcdir)/version.pl make < $(srcdir)/version > version.mak +nsis/version.nsh: version version.pl + $(RUNPERL) $(srcdir)/version.pl nsis < $(srcdir)/version > nsis/version.nsh + +# This source file is generated from the standard macros file +# `standard.mac' by another Perl script. Again, it's part of the +# standard distribution. +macros/macros.c: macros/macros.pl asm/pptok.ph version.mac \ + $(srcdir)/macros/*.mac $(srcdir)/output/*.mac + $(RUNPERL) $(srcdir)/macros/macros.pl version.mac \ + $(srcdir)/macros/*.mac $(srcdir)/output/*.mac + +# These source files are generated from regs.dat by yet another +# perl script. +x86/regs.c: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl c \ + $(srcdir)/x86/regs.dat > x86/regs.c +x86/regflags.c: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl fc \ + $(srcdir)/x86/regs.dat > x86/regflags.c +x86/regdis.c: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl dc \ + $(srcdir)/x86/regs.dat > x86/regdis.c +x86/regdis.h: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl dh \ + $(srcdir)/x86/regs.dat > x86/regdis.h +x86/regvals.c: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl vc \ + $(srcdir)/x86/regs.dat > x86/regvals.c +x86/regs.h: x86/regs.dat x86/regs.pl + $(RUNPERL) $(srcdir)/x86/regs.pl h \ + $(srcdir)/x86/regs.dat > x86/regs.h + +# Assembler token hash +asm/tokhash.c: x86/insns.dat x86/regs.dat asm/tokens.dat asm/tokhash.pl \ + perllib/phash.ph + $(RUNPERL) $(srcdir)/asm/tokhash.pl c \ + $(srcdir)/x86/insns.dat $(srcdir)/x86/regs.dat \ + $(srcdir)/asm/tokens.dat > asm/tokhash.c + +# Assembler token metadata +asm/tokens.h: x86/insns.dat x86/regs.dat asm/tokens.dat asm/tokhash.pl \ + perllib/phash.ph + $(RUNPERL) $(srcdir)/asm/tokhash.pl h \ + $(srcdir)/x86/insns.dat $(srcdir)/x86/regs.dat \ + $(srcdir)/asm/tokens.dat > asm/tokens.h + +# Preprocessor token hash +asm/pptok.h: asm/pptok.dat asm/pptok.pl perllib/phash.ph + $(RUNPERL) $(srcdir)/asm/pptok.pl h \ + $(srcdir)/asm/pptok.dat asm/pptok.h +asm/pptok.c: asm/pptok.dat asm/pptok.pl perllib/phash.ph + $(RUNPERL) $(srcdir)/asm/pptok.pl c \ + $(srcdir)/asm/pptok.dat asm/pptok.c +asm/pptok.ph: asm/pptok.dat asm/pptok.pl perllib/phash.ph + $(RUNPERL) $(srcdir)/asm/pptok.pl ph \ + $(srcdir)/asm/pptok.dat asm/pptok.ph + +# Directives hash +asm/directiv.h: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph + $(RUNPERL) $(srcdir)/nasmlib/perfhash.pl h \ + $(srcdir)/asm/directiv.dat asm/directiv.h +asm/directbl.c: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph + $(RUNPERL) $(srcdir)/nasmlib/perfhash.pl c \ + $(srcdir)/asm/directiv.dat asm/directbl.c + +#-- End Generated File Rules --# + +perlreq: $(PERLREQ) + +# This rule is only used for RDOFF +.$(O)$(X): + $(CC) $(ALL_CFLAGS) -o $@ $< $(LDFLAGS) $(RDFLIB) $(NASMLIB) $(LIBS) + +RDFLN = cd rdoff && ln -s +RDFLNPFX = + +#-- Begin RDOFF Shared Rules --# + +RDFLIBOBJ = rdoff/rdoff.$(O) rdoff/rdfload.$(O) rdoff/symtab.$(O) \ + rdoff/collectn.$(O) rdoff/rdlib.$(O) rdoff/segtab.$(O) \ + rdoff/hash.$(O) + +RDFPROGS = rdoff/rdfdump$(X) rdoff/ldrdf$(X) rdoff/rdx$(X) rdoff/rdflib$(X) \ + rdoff/rdf2bin$(X) +RDF2BINLINKS = rdoff/rdf2com$(X) rdoff/rdf2ith$(X) \ + rdoff/rdf2ihx$(X) rdoff/rdf2srec$(X) + +RDFLIB = rdoff/librdoff.$(A) +RDFLIBS = $(RDFLIB) $(NASMLIB) + +rdoff/rdfdump$(X): rdoff/rdfdump.$(O) $(RDFLIBS) +rdoff/ldrdf$(X): rdoff/ldrdf.$(O) $(RDFLIBS) +rdoff/rdx$(X): rdoff/rdx.$(O) $(RDFLIBS) +rdoff/rdflib$(X): rdoff/rdflib.$(O) $(RDFLIBS) +rdoff/rdf2bin$(X): rdoff/rdf2bin.$(O) $(RDFLIBS) +rdoff/rdf2com$(X): rdoff/rdf2bin$(X) + $(RM_F) rdoff/rdf2com$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2com$(X) +rdoff/rdf2ith$(X): rdoff/rdf2bin$(X) + $(RM_F) rdoff/rdf2ith$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ith$(X) +rdoff/rdf2ihx$(X): rdoff/rdf2bin$(X) + $(RM_F) rdoff/rdf2ihx$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ihx$(X) +rdoff/rdf2srec$(X): rdoff/rdf2bin$(X) + $(RM_F) rdoff/rdf2srec$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2srec$(X) + +#-- End RDOFF Shared Rules --# + +rdf: $(RDFPROGS) $(RDF2BINLINKS) + +$(RDFLIB): $(RDFLIBOBJ) + $(RM_F) $(RDFLIB) + $(AR) cq $(RDFLIB) $(RDFLIBOBJ) + $(RANLIB) $(RDFLIB) + +#-- Begin NSIS Rules --# + +# NSIS is not built except by explicit request, as it only applies to +# Windows platforms +nsis/arch.nsh: nsis/getpearch.pl nasm$(X) + $(PERL) $(srcdir)/nsis/getpearch.pl nasm$(X) > nsis/arch.nsh + +# Should only be done after "make everything". +# The use of redirection here keeps makensis from moving the cwd to the +# source directory. +nsis: nsis/nasm.nsi nsis/arch.nsh nsis/version.nsh + $(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis/nasm.nsi + +#-- End NSIS Rules --# + +# Generated manpages, also pregenerated for distribution +manpages: nasm.1 ndisasm.1 + +install: nasm$(X) ndisasm$(X) + $(MKDIR) $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) nasm$(X) $(DESTDIR)$(bindir)/nasm$(X) + $(INSTALL_PROGRAM) ndisasm$(X) $(DESTDIR)$(bindir)/ndisasm$(X) + $(MKDIR) $(DESTDIR)$(mandir)/man1 + $(INSTALL_DATA) $(srcdir)/nasm.1 $(DESTDIR)$(mandir)/man1/nasm.1 + $(INSTALL_DATA) $(srcdir)/ndisasm.1 $(DESTDIR)$(mandir)/man1/ndisasm.1 + +clean: + for d in . $(SUBDIRS) $(XSUBDIRS); do \ + $(RM_F) "$$d"/*.$(O) "$$d"/*.s "$$d"/*.i "$$d"/*.$(A) ; \ + done + $(RM_F) nasm$(X) ndisasm$(X) + $(RM_F) nasm-*-installer-*.exe + $(RM_F) tags TAGS + $(RM_F) nsis/arch.nsh + $(RM_F) perlbreq.si + $(RM_F) $(RDFPROGS) $(RDF2BINLINKS) + +distclean: clean + $(RM_F) config.log config.status config/config.h + for d in . $(SUBDIRS) $(XSUBDIRS); do \ + $(RM_F) "$$d"/*~ "$$d"/*.bak "$$d"/*.lst "$$d"/*.bin ; \ + done + $(RM_F) test/*.$(O) + $(RM_RF) autom4te*.cache + $(RM_F) Makefile *.dep + +cleaner: clean + $(RM_F) $(PERLREQ) *.1 nasm.spec + $(MAKE) -C doc clean + $(RM_F) *.dep + +spotless: distclean cleaner + $(RM_F) doc/Makefile + +strip: + $(STRIP) --strip-unneeded nasm$(X) ndisasm$(X) + +TAGS: + $(RM_F) TAGS + $(FIND) . -name '*.[hcS]' -print | xargs etags -a + +tags: + $(RM_F) tags + $(FIND) . -name '*.[hcS]' -print | xargs ctags -a + +cscope: + $(RM_F) cscope.out cscope.files + $(FIND) . -name '*.[hcS]' -print > cscope.files + cscope -b -f cscope.out + +rdf_install install_rdf install_rdoff: + $(MKDIR) $(DESTDIR)$(bindir) + for f in $(RDFPROGS); do \ + $(INSTALL_PROGRAM) "$$f" '$(DESTDIR)$(bindir)'/ ; \ + done + cd '$(DESTDIR)$(bindir)' && \ + for f in $(RDF2BINLINKS); do \ + bn=`basename "$$f"` && $(RM_F) "$$bn" && \ + $(LN_S) rdf2bin$(X) "$$bn" ; \ + done + $(MKDIR) $(DESTDIR)$(mandir)/man1 + $(INSTALL_DATA) $(srcdir)/rdoff/*.1 $(DESTDIR)$(mandir)/man1/ + +doc: + $(MAKE) -C doc all + +doc_install install_doc: + $(MAKE) -C doc install + +everything: all manpages doc rdf + +install_everything: everything install install_doc install_rdf + +dist: + $(MAKE) alldeps + $(MAKE) spotless perlreq manpages spec + autoheader + autoconf + $(RM_RF) ./autom4te*.cache + +tar: dist + tar -cvj --exclude CVS -C .. -f ../nasm-`cat version`-`date +%Y%m%d`.tar.bz2 `basename \`pwd\`` + +spec: nasm.spec + +ALLPERLSRC := $(shell find $(srcdir) -type f -name '*.p[lh]') + +perlbreq.si: $(ALLPERLSRC) + sed -n -r -e 's/^[[:space:]]*use[[:space:]]+([^[:space:];]+).*$$/BuildRequires: perl(\1)/p' $(ALLPERLSRC) | \ + sed -r -e '/perl\((strict|warnings|Win32.*)\)/d' | \ + sort | uniq > perlbreq.si || ( rm -f perlbreq.si ; false ) + +nasm.spec: nasm.spec.in nasm.spec.sed version.sed perlbreq.si + sed -f version.sed -f nasm.spec.sed \ + < nasm.spec.in > nasm.spec || ( rm -f nasm.spec ; false ) + +splint: + splint -weak *.c + +test: nasm$(X) + cd test && $(RUNPERL) performtest.pl --nasm=../nasm *.asm + +golden: nasm$(X) + cd test && $(RUNPERL) performtest.pl --golden --nasm=../nasm *.asm + +# +# Rules to run autoreconf if necessary +# +configure: configure.ac aclocal.m4 + autoreconf + +config.status: configure + @if [ ! -f config.status ]; then \ + echo "*** ERROR: Need to run configure!" 1>&2 ; \ + exit 1; \ + fi + sh config.status --recheck + +Makefile: config.status Makefile.in doc/Makefile.in + sh config.status + +doc/Makefile: Makefile + +config/config.h: config.status + +# +# Does this version of this file have external dependencies? This definition +# will be automatically updated by mkdep.pl as needed. +# +EXTERNAL_DEPENDENCIES = 1 + +# +# Generate dependency information for this Makefile only. +# If this Makefile has external dependency information, then +# the dependency information will remain external, so it doesn't +# pollute the git logs. +# +Makefile.dep: $(PERLREQ) tools/mkdep.pl config.status + $(RUNPERL) tools/mkdep.pl -M Makefile.in -- $(DEPDIRS) + +dep: Makefile.dep + +# +# This build dependencies in *ALL* makefiles, and forces all +# dependencies to be inserted inline. For that reason, it should only +# be invoked manually or via "make dist". It should be run before +# creating release archives. +# +alldeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl + $(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak + $(RUNPERL) tools/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \ + $(DEPDIRS) + $(RM_F) *.dep + if [ -f config.status ]; then \ + if [ $(EXTERNAL_DEPENDENCIES) -eq 1 ]; then \ + sh config.status --recheck; \ + fi; \ + sh config.status; \ + fi + +# Strip internal dependency information from all Makefiles; this makes +# the output good for git checkin +cleandeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl + $(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak + $(RUNPERL) tools/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \ + $(DEPDIRS) + $(RM_F) *.dep + if [ -f config.status ]; then \ + if [ $(EXTERNAL_DEPENDENCIES) -eq 0 ]; then \ + sh config.status --recheck; \ + fi; \ + sh config.status; \ + fi + +#-- Magic hints to mkdep.pl --# +# @object-ending: ".$(O)" +# @path-separator: "/" +# @external: "Makefile.dep" +# @include-command: "-include" +# @selfrule: "1" +#-- Everything below is generated by mkdep.pl - do not edit --# +-include Makefile.dep diff --git a/Mkfiles/README b/Mkfiles/README new file mode 100644 index 0000000..42d879f --- /dev/null +++ b/Mkfiles/README @@ -0,0 +1,46 @@ +These are pre-created Makefiles for various platforms, use them if +GNU autoconf/automake packages are not supported on your system. + +The Makefiles are: + + Filename Target Compiler Tested with + --------------------------------------------------------------------------- + msvc.mak Win32 MS Visual C++ Visual Visual Studio 2013-2017 + + For building on a Win32 host using Microsoft Visual C++. + + Usage: nmake /f Mkfiles\msvc.mak + + If the following tools are installed, the full installer package can + be built: + 1. Perl (5.6 or later), e.g. ActivePerl or StrawberryPerl + http://strawberryperl.com/ + 2. Nullsoft Scriptable Install System (makensis) + http://nsis.sourceforge.net/Download + 3. Ghostscript (ps2pdf) or Acrobat Distriller (acrodist) + https://downloads.ghostscript.com/ + 4. The Adobe Source Sans Pro and Source Code Pro fonts + https://github.com/adobe-fonts + 5. The Perl module Font::TTF (can usually be installed + via the "CPAN Client" in your Perl distribution) + http://search.cpan.org/~bhallissy/Font-TTF/ + 6. The Perl module Sort::Versions (can usually be installed + via the "CPAN Client" in your Perl distribution) + http://search.cpan.org/~neilb/Sort-Versions-1.62/lib/Sort/Versions.pm + + The tools need to be in your current path. To build the + installer package, run: + + nmake /f Mkfiles\msvc.mak everything nsis + + Filename Target Compiler Tested with + --------------------------------------------------------------------------- + openwcom.mak DOS,Win32,OS/2 OpenWatcom C OpenWatcom 1.7 (Win32) + Linux (386) OpenWatcom 1.9 (Linux) + + For building on a DOS, OS/2, Win32 or Linux host using OpenWatcom. + OpenWatcom can be downloaded from http://www.openwatcom.org/. + + Usage: wmake /f Mkfiles/openwcom.mak + + is dos, win32, os2, or linux386. diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak new file mode 100644 index 0000000..9aec80f --- /dev/null +++ b/Mkfiles/msvc.mak @@ -0,0 +1,399 @@ +# -*- makefile -*- +# +# Makefile for building NASM using Microsoft Visual C++ and NMAKE. +# Tested on Microsoft Visual C++ 2005 Express Edition. +# +# Make sure to put the appropriate directories in your PATH, in +# the case of MSVC++ 2005, they are ...\VC\bin and ...\Common7\IDE. +# +# This is typically done by opening the Visual Studio Command Prompt. +# + +top_srcdir = . +srcdir = . +objdir = . +VPATH = . +prefix = "C:\Program Files\NASM" +exec_prefix = $(prefix) +bindir = $(prefix)/bin +mandir = $(prefix)/man + +!IF "$(DEBUG)" == "1" +CFLAGS = /Od /Zi +LDFLAGS = /DEBUG +!ELSE +CFLAGS = /O2 /Zi +LDFLAGS = /DEBUG /OPT:REF /OPT:ICF # (latter two undoes /DEBUG harm) +!ENDIF + +CC = cl +AR = lib +CFLAGS = $(CFLAGS) /W2 +BUILD_CFLAGS = $(CFLAGS) +INTERNAL_CFLAGS = /I$(srcdir) /I. \ + /I$(srcdir)/include /I./include \ + /I$(srcdir)/x86 /I./x86 \ + /I$(srcdir)/asm /I./asm \ + /I$(srcdir)/disasm /I./disasm \ + /I$(srcdir)/output /I./output +ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS) +LDFLAGS = /link $(LINKFLAGS) /SUBSYSTEM:CONSOLE /RELEASE +LIBS = + +PERL = perl +PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir) +RUNPERL = $(PERL) $(PERLFLAGS) + +MAKENSIS = makensis + +RM_F = -del /f +LN_S = copy + +# Binary suffixes +O = obj +A = lib +X = .exe +.SUFFIXES: +.SUFFIXES: $(X) .$(A) .$(O) .c .i .s .1 .man + +.c.obj: + $(CC) /c $(ALL_CFLAGS) /Fo$@ $< + +#-- Begin File Lists --# +# Edit in Makefile.in, not here! +NASM = asm\nasm.$(O) +NDISASM = disasm\ndisasm.$(O) + +LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) \ + stdlib\strnlen.$(O) stdlib\strrchrnul.$(O) \ + \ + nasmlib\ver.$(O) \ + nasmlib\crc64.$(O) nasmlib\malloc.$(O) \ + nasmlib\md5c.$(O) nasmlib\string.$(O) \ + nasmlib\file.$(O) nasmlib\mmap.$(O) nasmlib\ilog2.$(O) \ + nasmlib\realpath.$(O) nasmlib\path.$(O) \ + nasmlib\filename.$(O) nasmlib\srcfile.$(O) \ + nasmlib\zerobuf.$(O) nasmlib\readnum.$(O) nasmlib\bsi.$(O) \ + nasmlib\rbtree.$(O) nasmlib\hashtbl.$(O) \ + nasmlib\raa.$(O) nasmlib\saa.$(O) \ + nasmlib\strlist.$(O) \ + nasmlib\perfhash.$(O) nasmlib\badenum.$(O) \ + \ + common\common.$(O) \ + \ + x86\insnsa.$(O) x86\insnsb.$(O) x86\insnsd.$(O) x86\insnsn.$(O) \ + x86\regs.$(O) x86\regvals.$(O) x86\regflags.$(O) x86\regdis.$(O) \ + x86\disp8.$(O) x86\iflag.$(O) \ + \ + asm\error.$(O) \ + asm\float.$(O) \ + asm\directiv.$(O) asm\directbl.$(O) \ + asm\pragma.$(O) \ + asm\assemble.$(O) asm\labels.$(O) asm\parser.$(O) \ + asm\preproc.$(O) asm\quote.$(O) asm\pptok.$(O) \ + asm\listing.$(O) asm\eval.$(O) asm\exprlib.$(O) asm\exprdump.$(O) \ + asm\stdscan.$(O) \ + asm\strfunc.$(O) asm\tokhash.$(O) \ + asm\segalloc.$(O) \ + asm\preproc-nop.$(O) \ + asm\rdstrnum.$(O) \ + \ + macros\macros.$(O) \ + \ + output\outform.$(O) output\outlib.$(O) output\legacy.$(O) \ + output\strtbl.$(O) \ + output\nulldbg.$(O) output\nullout.$(O) \ + output\outbin.$(O) output\outaout.$(O) output\outcoff.$(O) \ + output\outelf.$(O) \ + output\outobj.$(O) output\outas86.$(O) output\outrdf2.$(O) \ + output\outdbg.$(O) output\outieee.$(O) output\outmacho.$(O) \ + output\codeview.$(O) \ + \ + disasm\disasm.$(O) disasm\sync.$(O) + +SUBDIRS = stdlib nasmlib output asm disasm x86 common macros +XSUBDIRS = test doc nsis rdoff +DEPDIRS = . include config x86 rdoff $(SUBDIRS) +#-- End File Lists --# + +NASMLIB = libnasm.$(A) + +all: nasm$(X) ndisasm$(X) rdf + +nasm$(X): $(NASM) $(NASMLIB) + $(CC) /Fe$@ $(NASM) $(LDFLAGS) $(NASMLIB) $(LIBS) + +ndisasm$(X): $(NDISASM) $(NASMLIB) + $(CC) /Fe$@ $(NDISASM) $(LDFLAGS) $(NASMLIB) $(LIBS) + +$(NASMLIB): $(LIBOBJ) + $(AR) $(ARFLAGS) /OUT:$@ $** + +#-- Begin Generated File Rules --# +# Edit in Makefile.in, not here! + +# These source files are automagically generated from data files using +# Perl scripts. They're distributed, though, so it isn't necessary to +# have Perl just to recompile NASM from the distribution. + +# Perl-generated source files +PERLREQ = x86\insnsb.c x86\insnsa.c x86\insnsd.c x86\insnsi.h x86\insnsn.c \ + x86\regs.c x86\regs.h x86\regflags.c x86\regdis.c x86\regdis.h \ + x86\regvals.c asm\tokhash.c asm\tokens.h asm\pptok.h asm\pptok.c \ + x86\iflag.c x86\iflaggen.h \ + macros\macros.c \ + asm\pptok.ph asm\directbl.c asm\directiv.h \ + version.h version.mac version.mak nsis\version.nsh + +INSDEP = x86\insns.dat x86\insns.pl x86\insns-iflags.ph + +x86\iflag.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -fc \ + $(srcdir)\x86\insns.dat x86\iflag.c +x86\iflaggen.h: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -fh \ + $(srcdir)\x86\insns.dat x86\iflaggen.h +x86\insnsb.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -b \ + $(srcdir)\x86\insns.dat x86\insnsb.c +x86\insnsa.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -a \ + $(srcdir)\x86\insns.dat x86\insnsa.c +x86\insnsd.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -d \ + $(srcdir)\x86\insns.dat x86\insnsd.c +x86\insnsi.h: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -i \ + $(srcdir)\x86\insns.dat x86\insnsi.h +x86\insnsn.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -n \ + $(srcdir)\x86\insns.dat x86\insnsn.c + +# These files contains all the standard macros that are derived from +# the version number. +version.h: version version.pl + $(RUNPERL) $(srcdir)\version.pl h < $(srcdir)\version > version.h +version.mac: version version.pl + $(RUNPERL) $(srcdir)\version.pl mac < $(srcdir)\version > version.mac +version.sed: version version.pl + $(RUNPERL) $(srcdir)\version.pl sed < $(srcdir)\version > version.sed +version.mak: version version.pl + $(RUNPERL) $(srcdir)\version.pl make < $(srcdir)\version > version.mak +nsis\version.nsh: version version.pl + $(RUNPERL) $(srcdir)\version.pl nsis < $(srcdir)\version > nsis\version.nsh + +# This source file is generated from the standard macros file +# `standard.mac' by another Perl script. Again, it's part of the +# standard distribution. +macros\macros.c: macros\macros.pl asm\pptok.ph version.mac \ + $(srcdir)\macros\*.mac $(srcdir)\output\*.mac + $(RUNPERL) $(srcdir)\macros\macros.pl version.mac \ + $(srcdir)\macros\*.mac $(srcdir)\output\*.mac + +# These source files are generated from regs.dat by yet another +# perl script. +x86\regs.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl c \ + $(srcdir)\x86\regs.dat > x86\regs.c +x86\regflags.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl fc \ + $(srcdir)\x86\regs.dat > x86\regflags.c +x86\regdis.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl dc \ + $(srcdir)\x86\regs.dat > x86\regdis.c +x86\regdis.h: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl dh \ + $(srcdir)\x86\regs.dat > x86\regdis.h +x86\regvals.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl vc \ + $(srcdir)\x86\regs.dat > x86\regvals.c +x86\regs.h: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl h \ + $(srcdir)\x86\regs.dat > x86\regs.h + +# Assembler token hash +asm\tokhash.c: x86\insns.dat x86\regs.dat asm\tokens.dat asm\tokhash.pl \ + perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\tokhash.pl c \ + $(srcdir)\x86\insns.dat $(srcdir)\x86\regs.dat \ + $(srcdir)\asm\tokens.dat > asm\tokhash.c + +# Assembler token metadata +asm\tokens.h: x86\insns.dat x86\regs.dat asm\tokens.dat asm\tokhash.pl \ + perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\tokhash.pl h \ + $(srcdir)\x86\insns.dat $(srcdir)\x86\regs.dat \ + $(srcdir)\asm\tokens.dat > asm\tokens.h + +# Preprocessor token hash +asm\pptok.h: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl h \ + $(srcdir)\asm\pptok.dat asm\pptok.h +asm\pptok.c: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl c \ + $(srcdir)\asm\pptok.dat asm\pptok.c +asm\pptok.ph: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl ph \ + $(srcdir)\asm\pptok.dat asm\pptok.ph + +# Directives hash +asm\directiv.h: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\nasmlib\perfhash.pl h \ + $(srcdir)\asm\directiv.dat asm\directiv.h +asm\directbl.c: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\nasmlib\perfhash.pl c \ + $(srcdir)\asm\directiv.dat asm\directbl.c + +#-- End Generated File Rules --# + +perlreq: $(PERLREQ) + +# This rule is only used for RDOFF +.obj.exe: + $(CC) /Fe$@ $< $(LDFLAGS) $(RDFLIB) $(NASMLIB) $(LIBS) + +RDFLN = copy +RDFLNPFX = rdoff^\ + +#-- Begin RDOFF Shared Rules --# +# Edit in Makefile.in, not here! + +RDFLIBOBJ = rdoff\rdoff.$(O) rdoff\rdfload.$(O) rdoff\symtab.$(O) \ + rdoff\collectn.$(O) rdoff\rdlib.$(O) rdoff\segtab.$(O) \ + rdoff\hash.$(O) + +RDFPROGS = rdoff\rdfdump$(X) rdoff\ldrdf$(X) rdoff\rdx$(X) rdoff\rdflib$(X) \ + rdoff\rdf2bin$(X) +RDF2BINLINKS = rdoff\rdf2com$(X) rdoff\rdf2ith$(X) \ + rdoff\rdf2ihx$(X) rdoff\rdf2srec$(X) + +RDFLIB = rdoff\librdoff.$(A) +RDFLIBS = $(RDFLIB) $(NASMLIB) + +rdoff\rdfdump$(X): rdoff\rdfdump.$(O) $(RDFLIBS) +rdoff\ldrdf$(X): rdoff\ldrdf.$(O) $(RDFLIBS) +rdoff\rdx$(X): rdoff\rdx.$(O) $(RDFLIBS) +rdoff\rdflib$(X): rdoff\rdflib.$(O) $(RDFLIBS) +rdoff\rdf2bin$(X): rdoff\rdf2bin.$(O) $(RDFLIBS) +rdoff\rdf2com$(X): rdoff\rdf2bin$(X) + $(RM_F) rdoff\rdf2com$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2com$(X) +rdoff\rdf2ith$(X): rdoff\rdf2bin$(X) + $(RM_F) rdoff\rdf2ith$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ith$(X) +rdoff\rdf2ihx$(X): rdoff\rdf2bin$(X) + $(RM_F) rdoff\rdf2ihx$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2ihx$(X) +rdoff\rdf2srec$(X): rdoff\rdf2bin$(X) + $(RM_F) rdoff\rdf2srec$(X) + $(RDFLN) $(RDFLNPFX)rdf2bin$(X) $(RDFLNPFX)rdf2srec$(X) + +#-- End RDOFF Shared Rules --# + +rdf: $(RDFPROGS) $(RDF2BINLINKS) + +$(RDFLIB): $(RDFLIBOBJ) + $(AR) $(ARFLAGS) /OUT:$@ $** + +#-- Begin NSIS Rules --# +# Edit in Makefile.in, not here! + +# NSIS is not built except by explicit request, as it only applies to +# Windows platforms +nsis\arch.nsh: nsis\getpearch.pl nasm$(X) + $(PERL) $(srcdir)\nsis\getpearch.pl nasm$(X) > nsis\arch.nsh + +# Should only be done after "make everything". +# The use of redirection here keeps makensis from moving the cwd to the +# source directory. +nsis: nsis\nasm.nsi nsis\arch.nsh nsis\version.nsh + $(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi + +#-- End NSIS Rules --# + +clean: + -del /f /s *.$(O) + -del /f /s *.pdb + -del /f /s *.s + -del /f /s *.i + -del /f $(NASMLIB) $(RDFLIB) + -del /f nasm$(X) + -del /f ndisasm$(X) + -del /f rdoff\*$(X) + +distclean: clean + -del /f config.h + -del /f config.log + -del /f config.status + -del /f Makefile + -del /f /s *~ + -del /f /s *.bak + -del /f /s *.lst + -del /f /s *.bin + -del /f /s *.dep + -del /f output\*~ + -del /f output\*.bak + -del /f test\*.lst + -del /f test\*.bin + -del /f test\*.$(O) + -del /f test\*.bin + -del /f/s autom4te*.cache + rem cd rdoff && $(MAKE) distclean + +cleaner: clean + -del /f $(PERLREQ) + -del /f *.man + -del /f nasm.spec + rem cd doc && $(MAKE) clean + +spotless: distclean cleaner + -del /f doc\Makefile + -del doc\*~ + -del doc\*.bak + +strip: + +# Abuse doc/Makefile.in to build nasmdoc.pdf only +docs: + cd doc && $(MAKE) /f Makefile.in srcdir=. top_srcdir=.. \ + PERL=$(PERL) PDFOPT= nasmdoc.pdf + +everything: all docs nsis + +# +# Does this version of this file have external dependencies? This definition +# will be automatically updated by mkdep.pl as needed. +# +EXTERNAL_DEPENDENCIES = 1 + +# +# Generate dependency information for this Makefile only. +# If this Makefile has external dependency information, then +# the dependency information will remain external, so it doesn't +# pollute the git logs. +# +msvc.dep: $(PERLREQ) tools\mkdep.pl + $(RUNPERL) tools\mkdep.pl -M Mkfiles\msvc.mak -- $(DEPDIRS) + +dep: msvc.dep + +# Include and/or generate msvc.dep as needed. This is too complex to +# use the include-command feature, but we can open-code it here. +MKDEP=0 +!IF $(EXTERNAL_DEPENDENCIES) == 1 && $(MKDEP) == 0 +!IF EXISTS(msvc.dep) +!INCLUDE msvc.dep +!ELSEIF [$(MAKE) /c MKDEP=1 /f Mkfiles\msvc.mak msvc.dep] == 0 +!INCLUDE msvc.dep +!ELSE +!ERROR Unable to rebuild dependencies file msvc.dep +!ENDIF +!ENDIF + +#-- Magic hints to mkdep.pl --# +# @object-ending: ".$(O)" +# @path-separator: "\" +# @exclude: "config\config.h" +# @external: "msvc.dep" +# @selfrule: "1" +#-- Everything below is generated by mkdep.pl - do not edit --# diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak new file mode 100644 index 0000000..180706f --- /dev/null +++ b/Mkfiles/openwcom.mak @@ -0,0 +1,756 @@ +# -*- makefile -*- +# +# Makefile for building NASM using OpenWatcom +# cross-compile on a DOS/Win32/OS2 platform host +# + +top_srcdir = . +srcdir = . +VPATH = $(srcdir)\asm;$(srcdir)\x86;asm;x86;$(srcdir)\macros;macros;$(srcdir)\output;$(srcdir)\lib;$(srcdir)\common;$(srcdir)\stdlib;$(srcdir)\nasmlib;$(srcdir)\disasm +prefix = C:\Program Files\NASM +exec_prefix = $(prefix) +bindir = $(prefix)\bin +mandir = $(prefix)\man + +CC = *wcl386 +DEBUG = +CFLAGS = -zq -6 -ox -wx -ze -fpi $(DEBUG) +BUILD_CFLAGS = $(CFLAGS) $(%TARGET_CFLAGS) +INTERNAL_CFLAGS = -I$(srcdir) -I. -I$(srcdir)\include -I$(srcdir)\x86 -Ix86 -I$(srcdir)\asm -Iasm -I$(srcdir)\disasm -I$(srcdir)\output +ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS) +LD = *wlink +LDEBUG = +LDFLAGS = op quiet $(%TARGET_LFLAGS) $(LDEBUG) +LIBS = +STRIP = wstrip + +PERL = perl +PERLFLAGS = -I$(srcdir)\perllib -I$(srcdir) +RUNPERL = $(PERL) $(PERLFLAGS) + +MAKENSIS = makensis + +# Binary suffixes +O = obj +X = .exe + +# WMAKE errors out if a suffix is declared more than once, including +# its own built-in declarations. Thus, we need to explicitly clear the list +# first. Also, WMAKE only allows implicit rules that point "to the left" +# in this list! +.SUFFIXES: +.SUFFIXES: .man .1 .$(O) .i .c + +# Needed to find C files anywhere but in the current directory +.c : $(VPATH) + +.c.$(O): + @set INCLUDE= + $(CC) -c $(ALL_CFLAGS) -fo=$^@ $[@ + +#-- Begin File Lists --# +# Edit in Makefile.in, not here! +NASM = asm\nasm.$(O) +NDISASM = disasm\ndisasm.$(O) + +LIBOBJ = stdlib\snprintf.$(O) stdlib\vsnprintf.$(O) stdlib\strlcpy.$(O) & + stdlib\strnlen.$(O) stdlib\strrchrnul.$(O) & + & + nasmlib\ver.$(O) & + nasmlib\crc64.$(O) nasmlib\malloc.$(O) & + nasmlib\md5c.$(O) nasmlib\string.$(O) & + nasmlib\file.$(O) nasmlib\mmap.$(O) nasmlib\ilog2.$(O) & + nasmlib\realpath.$(O) nasmlib\path.$(O) & + nasmlib\filename.$(O) nasmlib\srcfile.$(O) & + nasmlib\zerobuf.$(O) nasmlib\readnum.$(O) nasmlib\bsi.$(O) & + nasmlib\rbtree.$(O) nasmlib\hashtbl.$(O) & + nasmlib\raa.$(O) nasmlib\saa.$(O) & + nasmlib\strlist.$(O) & + nasmlib\perfhash.$(O) nasmlib\badenum.$(O) & + & + common\common.$(O) & + & + x86\insnsa.$(O) x86\insnsb.$(O) x86\insnsd.$(O) x86\insnsn.$(O) & + x86\regs.$(O) x86\regvals.$(O) x86\regflags.$(O) x86\regdis.$(O) & + x86\disp8.$(O) x86\iflag.$(O) & + & + asm\error.$(O) & + asm\float.$(O) & + asm\directiv.$(O) asm\directbl.$(O) & + asm\pragma.$(O) & + asm\assemble.$(O) asm\labels.$(O) asm\parser.$(O) & + asm\preproc.$(O) asm\quote.$(O) asm\pptok.$(O) & + asm\listing.$(O) asm\eval.$(O) asm\exprlib.$(O) asm\exprdump.$(O) & + asm\stdscan.$(O) & + asm\strfunc.$(O) asm\tokhash.$(O) & + asm\segalloc.$(O) & + asm\preproc-nop.$(O) & + asm\rdstrnum.$(O) & + & + macros\macros.$(O) & + & + output\outform.$(O) output\outlib.$(O) output\legacy.$(O) & + output\strtbl.$(O) & + output\nulldbg.$(O) output\nullout.$(O) & + output\outbin.$(O) output\outaout.$(O) output\outcoff.$(O) & + output\outelf.$(O) & + output\outobj.$(O) output\outas86.$(O) output\outrdf2.$(O) & + output\outdbg.$(O) output\outieee.$(O) output\outmacho.$(O) & + output\codeview.$(O) & + & + disasm\disasm.$(O) disasm\sync.$(O) + +SUBDIRS = stdlib nasmlib output asm disasm x86 common macros +XSUBDIRS = test doc nsis rdoff +DEPDIRS = . include config x86 rdoff $(SUBDIRS) +#-- End File Lists --# + +what: .SYMBOLIC + @echo Please build "dos", "win32", "os2" or "linux386" + +dos: .SYMBOLIC + @set TARGET_CFLAGS=-bt=DOS -I"$(%WATCOM)\h" + @set TARGET_LFLAGS=sys causeway + @%make all + +win32: .SYMBOLIC + @set TARGET_CFLAGS=-bt=NT -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\nt" + @set TARGET_LFLAGS=sys nt + @%make all + +os2: .SYMBOLIC + @set TARGET_CFLAGS=-bt=OS2 -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\os2" + @set TARGET_LFLAGS=sys os2v2 + @%make all + +linux386: .SYMBOLIC + @set TARGET_CFLAGS=-bt=LINUX -I"$(%WATCOM)\lh" + @set TARGET_LFLAGS=sys linux + @%make all + +all: perlreq nasm$(X) ndisasm$(X) .SYMBOLIC +# cd rdoff && $(MAKE) all + +NASMLIB = nasm.lib + +nasm$(X): $(NASM) $(NASMLIB) + $(LD) $(LDFLAGS) name nasm$(X) libr {$(NASMLIB) $(LIBS)} file {$(NASM)} + +ndisasm$(X): $(NDISASM) $(LIBOBJ) + $(LD) $(LDFLAGS) name ndisasm$(X) libr {$(NASMLIB) $(LIBS)} file {$(NDISASM)} + +nasm.lib: $(LIBOBJ) + wlib -q -b -n $@ $(LIBOBJ) + +#-- Begin Generated File Rules --# +# Edit in Makefile.in, not here! + +# These source files are automagically generated from data files using +# Perl scripts. They're distributed, though, so it isn't necessary to +# have Perl just to recompile NASM from the distribution. + +# Perl-generated source files +PERLREQ = x86\insnsb.c x86\insnsa.c x86\insnsd.c x86\insnsi.h x86\insnsn.c & + x86\regs.c x86\regs.h x86\regflags.c x86\regdis.c x86\regdis.h & + x86\regvals.c asm\tokhash.c asm\tokens.h asm\pptok.h asm\pptok.c & + x86\iflag.c x86\iflaggen.h & + macros\macros.c & + asm\pptok.ph asm\directbl.c asm\directiv.h & + version.h version.mac version.mak nsis\version.nsh + +INSDEP = x86\insns.dat x86\insns.pl x86\insns-iflags.ph + +x86\iflag.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -fc & + $(srcdir)\x86\insns.dat x86\iflag.c +x86\iflaggen.h: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -fh & + $(srcdir)\x86\insns.dat x86\iflaggen.h +x86\insnsb.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -b & + $(srcdir)\x86\insns.dat x86\insnsb.c +x86\insnsa.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -a & + $(srcdir)\x86\insns.dat x86\insnsa.c +x86\insnsd.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -d & + $(srcdir)\x86\insns.dat x86\insnsd.c +x86\insnsi.h: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -i & + $(srcdir)\x86\insns.dat x86\insnsi.h +x86\insnsn.c: $(INSDEP) + $(RUNPERL) $(srcdir)\x86\insns.pl -n & + $(srcdir)\x86\insns.dat x86\insnsn.c + +# These files contains all the standard macros that are derived from +# the version number. +version.h: version version.pl + $(RUNPERL) $(srcdir)\version.pl h < $(srcdir)\version > version.h +version.mac: version version.pl + $(RUNPERL) $(srcdir)\version.pl mac < $(srcdir)\version > version.mac +version.sed: version version.pl + $(RUNPERL) $(srcdir)\version.pl sed < $(srcdir)\version > version.sed +version.mak: version version.pl + $(RUNPERL) $(srcdir)\version.pl make < $(srcdir)\version > version.mak +nsis\version.nsh: version version.pl + $(RUNPERL) $(srcdir)\version.pl nsis < $(srcdir)\version > nsis\version.nsh + +# This source file is generated from the standard macros file +# `standard.mac' by another Perl script. Again, it's part of the +# standard distribution. +macros\macros.c: macros\macros.pl asm\pptok.ph version.mac & + $(srcdir)\macros\*.mac $(srcdir)\output\*.mac + $(RUNPERL) $(srcdir)\macros\macros.pl version.mac & + $(srcdir)\macros\*.mac $(srcdir)\output\*.mac + +# These source files are generated from regs.dat by yet another +# perl script. +x86\regs.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl c & + $(srcdir)\x86\regs.dat > x86\regs.c +x86\regflags.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl fc & + $(srcdir)\x86\regs.dat > x86\regflags.c +x86\regdis.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl dc & + $(srcdir)\x86\regs.dat > x86\regdis.c +x86\regdis.h: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl dh & + $(srcdir)\x86\regs.dat > x86\regdis.h +x86\regvals.c: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl vc & + $(srcdir)\x86\regs.dat > x86\regvals.c +x86\regs.h: x86\regs.dat x86\regs.pl + $(RUNPERL) $(srcdir)\x86\regs.pl h & + $(srcdir)\x86\regs.dat > x86\regs.h + +# Assembler token hash +asm\tokhash.c: x86\insns.dat x86\regs.dat asm\tokens.dat asm\tokhash.pl & + perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\tokhash.pl c & + $(srcdir)\x86\insns.dat $(srcdir)\x86\regs.dat & + $(srcdir)\asm\tokens.dat > asm\tokhash.c + +# Assembler token metadata +asm\tokens.h: x86\insns.dat x86\regs.dat asm\tokens.dat asm\tokhash.pl & + perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\tokhash.pl h & + $(srcdir)\x86\insns.dat $(srcdir)\x86\regs.dat & + $(srcdir)\asm\tokens.dat > asm\tokens.h + +# Preprocessor token hash +asm\pptok.h: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl h & + $(srcdir)\asm\pptok.dat asm\pptok.h +asm\pptok.c: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl c & + $(srcdir)\asm\pptok.dat asm\pptok.c +asm\pptok.ph: asm\pptok.dat asm\pptok.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\asm\pptok.pl ph & + $(srcdir)\asm\pptok.dat asm\pptok.ph + +# Directives hash +asm\directiv.h: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\nasmlib\perfhash.pl h & + $(srcdir)\asm\directiv.dat asm\directiv.h +asm\directbl.c: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph + $(RUNPERL) $(srcdir)\nasmlib\perfhash.pl c & + $(srcdir)\asm\directiv.dat asm\directbl.c + +#-- End Generated File Rules --# + +perlreq: $(PERLREQ) .SYMBOLIC + +#-- Begin NSIS Rules --# +# Edit in Makefile.in, not here! + +# NSIS is not built except by explicit request, as it only applies to +# Windows platforms +nsis\arch.nsh: nsis\getpearch.pl nasm$(X) + $(PERL) $(srcdir)\nsis\getpearch.pl nasm$(X) > nsis\arch.nsh + +# Should only be done after "make everything". +# The use of redirection here keeps makensis from moving the cwd to the +# source directory. +nsis: nsis\nasm.nsi nsis\arch.nsh nsis\version.nsh + $(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi + +#-- End NSIS Rules --# + +clean: .SYMBOLIC + rm -f *.$(O) *.s *.i + rm -f asm\*.$(O) asm\*.s asm\*.i + rm -f x86\*.$(O) x86\*.s x86\*.i + rm -f lib\*.$(O) lib\*.s lib\*.i + rm -f macros\*.$(O) macros\*.s macros\*.i + rm -f output\*.$(O) output\*.s output\*.i + rm -f common\*.$(O) common\*.s common\*.i + rm -f stdlib\*.$(O) stdlib\*.s stdlib\*.i + rm -f nasmlib\*.$(O) nasmlib\*.s nasmlib\*.i + rm -f disasm\*.$(O) disasm\*.s disasm\*.i + rm -f config.h config.log config.status + rm -f nasm$(X) ndisasm$(X) $(NASMLIB) +# cd rdoff && $(MAKE) clean + +distclean: clean .SYMBOLIC + rm -f config.h config.log config.status + rm -f Makefile *~ *.bak *.lst *.bin + rm -f output\*~ output\*.bak + rm -f test\*.lst test\*.bin test\*.$(O) test\*.bin +# -del \s autom4te*.cache +# cd rdoff && $(MAKE) distclean + +cleaner: clean .SYMBOLIC + rm -f $(PERLREQ) + rm -f *.man + rm -f nasm.spec +# cd doc && $(MAKE) clean + +spotless: distclean cleaner .SYMBOLIC + rm -f doc\Makefile doc\*~ doc\*.bak + +strip: .SYMBOLIC + $(STRIP) *.exe + +rdf: +# cd rdoff && $(MAKE) + +doc: +# cd doc && $(MAKE) all + +everything: all doc rdf + +# +# This build dependencies in *ALL* makefiles. Partially for that reason, +# it's expected to be invoked manually. +# +alldeps: perlreq .SYMBOLIC + $(PERL) syncfiles.pl Makefile.in Mkfiles\openwcom.mak + $(PERL) mkdep.pl -M Makefile.in Mkfiles\openwcom.mak -- . output lib + +#-- Magic hints to mkdep.pl --# +# @object-ending: ".$(O)" +# @path-separator: "\" +# @exclude: "config/config.h" +# @continuation: "&" +#-- Everything below is generated by mkdep.pl - do not edit --# +asm\assemble.$(O): asm\assemble.c asm\assemble.h asm\directiv.h & + asm\listing.h asm\pptok.h asm\preproc.h asm\tokens.h config\msvc.h & + config\unknown.h config\watcom.h include\bytesex.h include\compiler.h & + include\disp8.h include\error.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\directbl.$(O): asm\directbl.c asm\directiv.h config\msvc.h & + config\unknown.h config\watcom.h include\bytesex.h include\compiler.h & + include\nasmint.h include\nasmlib.h include\perfhash.h +asm\directiv.$(O): asm\directiv.c asm\assemble.h asm\directiv.h asm\eval.h & + asm\float.h asm\listing.h asm\pptok.h asm\preproc.h asm\stdscan.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\iflag.h include\ilog2.h & + include\labels.h include\nasm.h include\nasmint.h include\nasmlib.h & + include\opflags.h include\perfhash.h include\strlist.h include\tables.h & + output\outform.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\error.$(O): asm\error.c config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\nasmint.h & + include\nasmlib.h +asm\eval.$(O): asm\eval.c asm\assemble.h asm\directiv.h asm\eval.h & + asm\float.h asm\pptok.h asm\preproc.h config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\iflag.h include\ilog2.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\exprdump.$(O): asm\exprdump.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\insnsi.h x86\regs.h +asm\exprlib.$(O): asm\exprlib.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\insnsi.h x86\regs.h +asm\float.$(O): asm\float.c asm\directiv.h asm\float.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +asm\labels.$(O): asm\labels.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\hashtbl.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +asm\listing.$(O): asm\listing.c asm\directiv.h asm\listing.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +asm\nasm.$(O): asm\nasm.c asm\assemble.h asm\directiv.h asm\eval.h & + asm\float.h asm\listing.h asm\parser.h asm\pptok.h asm\preproc.h & + asm\stdscan.h asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\iflag.h & + include\ilog2.h include\insns.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\raa.h include\saa.h include\strlist.h include\tables.h & + include\ver.h output\outform.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\parser.$(O): asm\parser.c asm\assemble.h asm\directiv.h asm\eval.h & + asm\float.h asm\parser.h asm\pptok.h asm\preproc.h asm\stdscan.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\iflag.h & + include\ilog2.h include\insns.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\pptok.$(O): asm\pptok.c asm\pptok.h asm\preproc.h config\msvc.h & + config\unknown.h config\watcom.h include\bytesex.h include\compiler.h & + include\hashtbl.h include\nasmint.h include\nasmlib.h +asm\pragma.$(O): asm\pragma.c asm\assemble.h asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\iflag.h & + include\ilog2.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\preproc-nop.$(O): asm\preproc-nop.c asm\directiv.h asm\listing.h & + asm\pptok.h asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +asm\preproc.$(O): asm\preproc.c asm\directiv.h asm\eval.h asm\listing.h & + asm\pptok.h asm\preproc.h asm\quote.h asm\stdscan.h asm\tokens.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\hashtbl.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +asm\quote.$(O): asm\quote.c asm\quote.h config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +asm\rdstrnum.$(O): asm\rdstrnum.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\insnsi.h x86\regs.h +asm\segalloc.$(O): asm\segalloc.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +asm\stdscan.$(O): asm\stdscan.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\quote.h asm\stdscan.h asm\tokens.h config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\iflag.h include\ilog2.h include\insns.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\iflaggen.h & + x86\insnsi.h x86\regs.h +asm\strfunc.$(O): asm\strfunc.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\insnsi.h x86\regs.h +asm\tokhash.$(O): asm\tokhash.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\stdscan.h asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\hashtbl.h include\iflag.h & + include\ilog2.h include\insns.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +common\common.$(O): common\common.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +disasm\disasm.$(O): disasm\disasm.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h disasm\disasm.h & + disasm\sync.h include\bytesex.h include\compiler.h include\disp8.h & + include\iflag.h include\ilog2.h include\insns.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\iflaggen.h & + x86\insnsi.h x86\regdis.h x86\regs.h +disasm\ndisasm.$(O): disasm\ndisasm.c asm\directiv.h asm\pptok.h & + asm\preproc.h asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + disasm\disasm.h disasm\sync.h include\bytesex.h include\compiler.h & + include\error.h include\iflag.h include\ilog2.h include\insns.h & + include\labels.h include\nasm.h include\nasmint.h include\nasmlib.h & + include\opflags.h include\perfhash.h include\strlist.h include\tables.h & + include\ver.h x86\iflaggen.h x86\insnsi.h x86\regs.h +disasm\sync.$(O): disasm\sync.c config\msvc.h config\unknown.h & + config\watcom.h disasm\sync.h include\bytesex.h include\compiler.h & + include\nasmint.h include\nasmlib.h +macros\macros.$(O): macros\macros.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\hashtbl.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h output\outform.h x86\insnsi.h x86\regs.h +nasmlib\badenum.$(O): nasmlib\badenum.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +nasmlib\bsi.$(O): nasmlib\bsi.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +nasmlib\crc64.$(O): nasmlib\crc64.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\hashtbl.h & + include\nasmint.h include\nasmlib.h +nasmlib\file.$(O): nasmlib\file.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h nasmlib\file.h +nasmlib\filename.$(O): nasmlib\filename.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h +nasmlib\hashtbl.$(O): nasmlib\hashtbl.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\hashtbl.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +nasmlib\ilog2.$(O): nasmlib\ilog2.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\ilog2.h include\nasmint.h +nasmlib\malloc.$(O): nasmlib\malloc.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h +nasmlib\md5c.$(O): nasmlib\md5c.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\md5.h include\nasmint.h +nasmlib\mmap.$(O): nasmlib\mmap.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h nasmlib\file.h +nasmlib\path.$(O): nasmlib\path.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h +nasmlib\perfhash.$(O): nasmlib\perfhash.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\hashtbl.h & + include\nasmint.h include\nasmlib.h include\perfhash.h +nasmlib\raa.$(O): nasmlib\raa.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h include\raa.h +nasmlib\rbtree.$(O): nasmlib\rbtree.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h include\rbtree.h +nasmlib\readnum.$(O): nasmlib\readnum.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h x86\insnsi.h & + x86\regs.h +nasmlib\realpath.$(O): nasmlib\realpath.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +nasmlib\saa.$(O): nasmlib\saa.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h include\saa.h +nasmlib\srcfile.$(O): nasmlib\srcfile.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\hashtbl.h & + include\nasmint.h include\nasmlib.h +nasmlib\string.$(O): nasmlib\string.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +nasmlib\strlist.$(O): nasmlib\strlist.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h include\strlist.h +nasmlib\ver.$(O): nasmlib\ver.c include\ver.h version.h +nasmlib\zerobuf.$(O): nasmlib\zerobuf.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +output\codeview.$(O): output\codeview.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\hashtbl.h & + include\labels.h include\md5.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\saa.h & + include\strlist.h include\tables.h output\outlib.h output\pecoff.h & + version.h x86\insnsi.h x86\regs.h +output\legacy.$(O): output\legacy.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h output\outlib.h x86\insnsi.h x86\regs.h +output\nulldbg.$(O): output\nulldbg.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h output\outlib.h & + x86\insnsi.h x86\regs.h +output\nullout.$(O): output\nullout.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h output\outlib.h & + x86\insnsi.h x86\regs.h +output\outaout.$(O): output\outaout.c asm\directiv.h asm\eval.h asm\pptok.h & + asm\preproc.h asm\stdscan.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\raa.h include\saa.h include\strlist.h & + include\tables.h output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\outas86.$(O): output\outas86.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\raa.h include\saa.h include\strlist.h & + include\tables.h output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\outbin.$(O): output\outbin.c asm\directiv.h asm\eval.h asm\pptok.h & + asm\preproc.h asm\stdscan.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\saa.h include\strlist.h include\tables.h & + output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\outcoff.$(O): output\outcoff.c asm\directiv.h asm\eval.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\ilog2.h & + include\labels.h include\nasm.h include\nasmint.h include\nasmlib.h & + include\opflags.h include\perfhash.h include\raa.h include\saa.h & + include\strlist.h include\tables.h output\outform.h output\outlib.h & + output\pecoff.h x86\insnsi.h x86\regs.h +output\outdbg.$(O): output\outdbg.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\iflag.h & + include\ilog2.h include\insns.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h output\outform.h output\outlib.h & + x86\iflaggen.h x86\insnsi.h x86\regs.h +output\outelf.$(O): output\outelf.c asm\directiv.h asm\eval.h asm\pptok.h & + asm\preproc.h asm\stdscan.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\raa.h include\rbtree.h include\saa.h & + include\strlist.h include\tables.h include\ver.h output\dwarf.h & + output\elf.h output\outelf.h output\outform.h output\outlib.h & + output\stabs.h x86\insnsi.h x86\regs.h +output\outform.$(O): output\outform.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h output\outform.h x86\insnsi.h x86\regs.h +output\outieee.$(O): output\outieee.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h include\ver.h & + output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\outlib.$(O): output\outlib.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h output\outlib.h x86\insnsi.h x86\regs.h +output\outmacho.$(O): output\outmacho.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\hashtbl.h & + include\ilog2.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\raa.h & + include\rbtree.h include\saa.h include\strlist.h include\tables.h & + include\ver.h output\dwarf.h output\outform.h output\outlib.h x86\insnsi.h & + x86\regs.h +output\outobj.$(O): output\outobj.c asm\directiv.h asm\eval.h asm\pptok.h & + asm\preproc.h asm\stdscan.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h include\ver.h & + output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\outrdf2.$(O): output\outrdf2.c asm\directiv.h asm\pptok.h & + asm\preproc.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\rdoff.h include\saa.h include\strlist.h & + include\tables.h output\outform.h output\outlib.h x86\insnsi.h x86\regs.h +output\strtbl.$(O): output\strtbl.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\error.h include\hashtbl.h include\labels.h & + include\nasm.h include\nasmint.h include\nasmlib.h include\opflags.h & + include\perfhash.h include\strlist.h include\tables.h output\strtbl.h & + x86\insnsi.h x86\regs.h +rdoff\collectn.$(O): rdoff\collectn.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\collectn.h & + rdoff\rdfutils.h +rdoff\hash.$(O): rdoff\hash.c config\msvc.h config\unknown.h config\watcom.h & + include\compiler.h include\nasmint.h rdoff\hash.h +rdoff\ldrdf.$(O): rdoff\ldrdf.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\collectn.h & + rdoff\ldsegs.h rdoff\rdfutils.h rdoff\rdlib.h rdoff\segtab.h rdoff\symtab.h +rdoff\rdf2bin.$(O): rdoff\rdf2bin.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfload.h & + rdoff\rdfutils.h +rdoff\rdfdump.$(O): rdoff\rdfdump.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfutils.h +rdoff\rdflib.$(O): rdoff\rdflib.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfutils.h +rdoff\rdfload.$(O): rdoff\rdfload.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\collectn.h & + rdoff\rdfload.h rdoff\rdfutils.h rdoff\symtab.h +rdoff\rdlar.$(O): rdoff\rdlar.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h rdoff\rdlar.h +rdoff\rdlib.$(O): rdoff\rdlib.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfutils.h & + rdoff\rdlar.h rdoff\rdlib.h +rdoff\rdoff.$(O): rdoff\rdoff.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfutils.h +rdoff\rdx.$(O): rdoff\rdx.c config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\error.h include\nasmint.h & + include\nasmlib.h include\rdoff.h rdoff\rdfload.h rdoff\rdfutils.h & + rdoff\symtab.h +rdoff\segtab.$(O): rdoff\segtab.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\rdfutils.h & + rdoff\segtab.h +rdoff\symtab.$(O): rdoff\symtab.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h include\rdoff.h rdoff\hash.h & + rdoff\rdfutils.h rdoff\symtab.h +stdlib\snprintf.$(O): stdlib\snprintf.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\nasmint.h & + include\nasmlib.h +stdlib\strlcpy.$(O): stdlib\strlcpy.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h +stdlib\strnlen.$(O): stdlib\strnlen.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h +stdlib\strrchrnul.$(O): stdlib\strrchrnul.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h +stdlib\vsnprintf.$(O): stdlib\vsnprintf.c config\msvc.h config\unknown.h & + config\watcom.h include\bytesex.h include\compiler.h include\error.h & + include\nasmint.h include\nasmlib.h +x86\disp8.$(O): x86\disp8.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\disp8.h include\labels.h include\nasm.h & + include\nasmint.h include\nasmlib.h include\opflags.h include\perfhash.h & + include\strlist.h include\tables.h x86\insnsi.h x86\regs.h +x86\iflag.$(O): x86\iflag.c config\msvc.h config\unknown.h config\watcom.h & + include\compiler.h include\iflag.h include\ilog2.h include\nasmint.h & + x86\iflaggen.h +x86\insnsa.$(O): x86\insnsa.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +x86\insnsb.$(O): x86\insnsb.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +x86\insnsd.$(O): x86\insnsd.c asm\directiv.h asm\pptok.h asm\preproc.h & + asm\tokens.h config\msvc.h config\unknown.h config\watcom.h & + include\bytesex.h include\compiler.h include\iflag.h include\ilog2.h & + include\insns.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\iflaggen.h x86\insnsi.h x86\regs.h +x86\insnsn.$(O): x86\insnsn.c config\msvc.h config\unknown.h config\watcom.h & + include\compiler.h include\nasmint.h include\tables.h x86\insnsi.h +x86\regdis.$(O): x86\regdis.c x86\regdis.h x86\regs.h +x86\regflags.$(O): x86\regflags.c asm\directiv.h asm\pptok.h asm\preproc.h & + config\msvc.h config\unknown.h config\watcom.h include\bytesex.h & + include\compiler.h include\labels.h include\nasm.h include\nasmint.h & + include\nasmlib.h include\opflags.h include\perfhash.h include\strlist.h & + include\tables.h x86\insnsi.h x86\regs.h +x86\regs.$(O): x86\regs.c config\msvc.h config\unknown.h config\watcom.h & + include\compiler.h include\nasmint.h include\tables.h x86\insnsi.h +x86\regvals.$(O): x86\regvals.c config\msvc.h config\unknown.h & + config\watcom.h include\compiler.h include\nasmint.h include\tables.h & + x86\insnsi.h diff --git a/README b/README new file mode 100644 index 0000000..792b038 --- /dev/null +++ b/README @@ -0,0 +1,23 @@ + NASM, the Netwide Assembler. + +Many many developers all over the net respect NASM for what it is +- a widespread (thus netwide), portable (thus netwide!), very +flexible and mature assembler tool with support for many output +formats (thus netwide!!). + +Now we have good news for you: NASM is licensed under the "simplified" +(2-clause) BSD license. This means its development is open to even +wider society of programmers wishing to improve their lovely +assembler. + +The NASM project is now situated at SourceForge.net, the most +popular Open Source development site on the Internet. + +Visit our website at http://nasm.sourceforge.net/ and our +SourceForge project at http://sourceforge.net/projects/nasm/ + +See the file CHANGES for the description of changes between revisions, +and the file AUTHORS for a list of contributors. + + With best regards, + NASM crew. diff --git a/SubmittingPatches b/SubmittingPatches new file mode 100644 index 0000000..168ab64 --- /dev/null +++ b/SubmittingPatches @@ -0,0 +1,116 @@ +How to submit patches into the NASM +=================================== + +Actually the rules are pretty simple + +Obtaining the source code +------------------------- + +The NASM sources are tracked by Git SCM at http://repo.or.cz/w/nasm.git +repository. You either could download packed sources or use git tool itself + + git clone git://repo.or.cz/nasm.git + +Changin the source code +----------------------- + +When you change the NASM source code keep in mind -- we prefer tabs and +indentations to be 4 characters width, space filled. + +Other "rules" could be learned from NASM sources -- just make your code +to look similar. + +Producing patch +--------------- + +There are at least two ways to make it right. + + 1) git format-patch + + You might need to read documentation on Git SCM how to prepare patch + for mail submission. Take a look on http://book.git-scm.com/ and/or + http://git-scm.com/documentation for details. It should not be hard + at all. + + 2) Use "diff -up" + + Use "diff -up" or "diff -uprN" to create patches. + +Signing your work +----------------- + +To improve tracking of who did what we've introduced a "sign-off" procedure +on patches that are being emailed around. + +The sign-off is a simple line at the end of the explanation for the +patch, which certifies that you wrote it or otherwise have the right to +pass it on as a open-source patch. The rules are pretty simple: if you +can certify the below: + + Developer's Certificate of Origin 1.1 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + +then you just add a line saying + + Signed-off-by: Random J Developer + +using your real name (please, no pseudonyms or anonymous contributions if +it possible) + +An example of patch message +--------------------------- + +From: Random J Developer +Subject: [PATCH] Short patch description + +Long patch description (could be skipped if patch +is trivial enough) + +Signed-off-by: Random J Developer +--- +Patch body here + +Mailing patches +--------------- + +The patches should be sent to NASM development mailing list + + nasm-devel@lists.sourceforge.net + +Please make sure the email client you're using doesn't screw +your patch (line wrapping and so on). + +Wait for response +----------------- + +Be patient. Most NASM developers are pretty busy people so if +there is no immediate response on your patch -- don't +be surprised, sometimes a patch may fly around a week(s) before +gets reviewed. But definitely the patches will not go to /dev/null. + + --- + With best regards, + NASM-team diff --git a/TODO b/TODO new file mode 100644 index 0000000..29a1b05 --- /dev/null +++ b/TODO @@ -0,0 +1,376 @@ +NASM TODO list +============== + +This, like the AUTHORS file, is intended for easy readability by both human +and machine, thus the format. + + F: feature + V: version you should expect it by + R: responsible person or - if unassigned + C: % complete + D: description + D: maybe on multiple lines + +Anything that doesn't start with /^[FVRCD]:/ should be ignored. + + F:-line triggers new entry. + Empty V,R,C assume: V: ?, R: -, C: 0% + +============= + +F: Extended x64 Support +D: Full FPU/MMX/SSE* instruction support for x64 + +F: ELF64 output format +D: Support for assembling code to the ELF64 output format + +F: NDISASM x64 Support +D: Ability to disassemble respective x64 code + +F: General x64 Support +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Support for assembling 64-bit code to various output formats + +F: win64 (x86-64 COFF) output format +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Support for assembling code to the win64 output format + +F: c99 data-type compliance +V: 0.99.00 +R: Keith Kanios +C: 99% +D: Revamped entire source-code base data-types for compliance +D: with c99 (inttypes.h) + +F: __BITS__ Standard Macro +V: 0.99.00 +R: Keith Kanios +C: 100% +D: __BITS__ standard macro that returns current [BITS XX] mode + +F: i18n via gettext +D: kkanios: be careful about that, stick to UTF-8 if anything + +F: Convert shallow code model to deep code model +D: Tired of messing between lots of unrelated files (especially .c/.h stuff) + +F: Automated dependency generation for Makefile +D: Current looks awful and will break if anything changes. + +F: Move output modules out*.c to output/ subdir +R: madfire +C: 100% + +== THESE ARE FROM old NASM's Wishlist +== THEY NEED SEVERE REVISING (seems they weren't updated for a couple of years or so) + +F: Check misc/ide.cfg into RCS as Watcom IDE enhancement thingy +V: 0.98 +D: (nop@dlc.fi) + +F: Package the Linux Assembler HOWTO +V: 0.98 + +F: 3DNow!, SSE and other extensions need documenting +V: 0.98 +D: hpa: Does it really make sense to have a whole instruction set +D: reference packaged with the assembler? +D: kkanios: Yes, for me it was a great help... and still is. + +F: prototypes of lrotate don't match in test/*. Fix. +V: 0.98 + +F: Build djgpp binaries for 0.98 onwards. Look into PMODE/W as a stub +V: 0.98 +D: it might be a lot better than CWSDPMI. It's in PMW133.ZIP. + +F: %undef operator that goes along with %define +V: ? +C: 100% + +F: Fix `%error' giving error messages twice. +V: 0.99 +D: Not especially important, as changes planned for 1.1x below will make +D: the preprocessor be only called once. + +F: Sort out problems with OBJ +V: 0.99 +D: * TLINK32 doesn't seem to like SEGDEF32 et al. So for that, we +D: should avoid xxx32 records wherever we can. +D: * However, didn't we change _to_ using xxx32 at some stage? Try +D: to remember why and when. +D: * Apparently Delphi's linker has trouble with two or more +D: globals being defined inside a PUBDEF32. Don't even know if it +D: _can_ cope with a PUBDEF16. +D: * Might need extra flags. *sigh* + +F: Symbol table output may possibly be useful. +V: 0.99 +D: Ken Martwick (kenm@efn.org) wants the following format: +D: labelname type offset(hex) repetition count +D: Possibly include xref addresses after repetition count? + +F: ELF fixes +V: 0.99 +D: There are various other bugs in outelf.c that make certain kinds +D: of relocation not work. See zbrown.asm. Looks like we may have to do +D: a major rewrite of parts of it. Compare some NASM code output with +D: equivalent GAS code output. Look at the ELF spec. Generally fix things. + +F: ELF fixes +V: 0.99 +D: NASM is currently using a kludge in ELF that involves defining +D: a symbol at a zero absolute offset. This isn't needed, as the +D: documented solution to the problem that this solves is to use +D: SHN_UNDEF. + +F: Debug information, in all formats it can be usefully done in. +V: 0.99 +D: * including line-number record support. +D: * "George C. Lindauer" +D: wants to have some say in how this goes through. +D: * Andrew Crabtree wants to help out. + +F: Think about a line-continuation character. +V: 0.99 + +F: Consider allowing declaration of two labels on the same line, +V: 0.99 +D: syntax 'label1[:] label2[:] ... instruction'. +D: Need to investigate feasibility. + +F: Quoting of quotes by doubling them, in string and char constants. +V: 0.99 + +F: Two-operand syntax for SEGMENT/SECTION macro to avoid warnings +D: of ignored section parameters on reissue of __SECT__. +D: Or maybe skip the warning if the given parameters are identical to +D: what was actually stored. Investigate. +V: 0.99 + +F: Apparently we are not missing a PSRAQ instruction, because it +D: doesn't exist. Check that it doesn't exist as an undocumented +D: instruction, or something stupid like that. +V: 0.99 + +F: Any assembled form starting 0x80 can also start 0x82. +V: 1.00 +D: ndisasm should know this. New special code in instruction encodings, probably. + +F: Pointing an EQU at an external symbol now generates an error. +V: 1.05 +D: There may be a better way of handling this; we should look into it. +D: Ideally, the label mechanism should be changed to cope with one +D: label being declared relative to another - that may work, but could be +D: a pain to implement (or is it? it may be easy enough that you just +D: need to declare a new offset in the same segment...) This should be done +D: before v1.0 is released. There is a comment regarding this in labels.c, +D: towards the end of the file, which discusses ways of fixing this. + +F: nested %rep used to cause a panic. +V: 1.10 +D: Now a more informative error message is produced. This problem whould +D: be fixed before v1.0. +D: See comment in switch() statement block for PP_REP in do_directive() +D: in preproc.c (line 1585, or thereabouts) + +F: Contribution +D: zgraeme.tar contains improved hash table routines +D: contributed by Graeme Defty for use in the +D: label manager. + +F: Contribution +D: zsyntax.zip contains a syntax-highlighting mode for +D: NASM, for use with the Aurora text editor (??). + +F: Contribution +D: zvim.zip contains a syntax-highlighting mode for NASM, for use with vim. + +F: Contribution +D: zkendal1.zip and zkendal2.zip contain Kendall +D: Bennett's () alternative syntax stuff, +D: providing an alternative syntax mode for NASM which allows a macro +D: set to be written that allows the same source files to be +D: assembled with NASM and TASM. +R: Kendall Bennett +C: 100% + +F: Add the UD2 instruction. +C: 100% + +F: Add the four instructions documented in 24368901.pdf (Intel's own document). +C: 100% + +F: Some means of avoiding MOV memoffs,EAX which apparently the +D: Pentium pairing detector thinks modifies EAX. Similar means of +D: choosing instruction encodings where necessary. +V: 1.10? + +F: The example of ..@ makes it clear that a ..@ label isn't just +D: local, but doesn't make it clear that it isn't just global either. + +F: hpa wants an evaluator operator for ceil(log2(x)). + +F: Extra reloc types in ELF +D: R_386_16 type 20, PC16 is 21, 8 is 22, PC8 is 23. +D: Add support for the 16s at least. + +F: Lazy section creation or selective section output +D: in COFF/win32 at least and probably other formats: don't bother to emit a section +D: if it contains no data. Particularly the default auto-created +D: section. We believe zero-length sections crash at least WLINK (in win32). + +F: Make the flags field in `struct itemplate' in insns.h a long instead of an int. +C: 100%? + +F: Implement %ifref to check whether a single-line macro has ever been expanded since (last re) definition. Or maybe not. We'll see. + +F: add pointer to \k{insLEAVE} and \k{insENTER} in chapters about mixed-language programming. + +F: Some equivalent to TASM's GLOBAL directive +D: ie something which defines a symbol as external if it doesn't end up being defined +D: but defines it as public if it does end up being defined. + +F: Documentation doesn't explain about C++ name mangling. + +F: see if BITS can be made to do anything sensible in obj (eg set the default new-segment property to Use32). + +F: OBJ: coalesce consecutive offset and segment fixups for the same location into full-32bit-pointer fixups. +D: This is apparently necessary because some twazzock in the PowerBASIC development +D: team didn't design to support the OMF spec the way the rest of the +D: world sees it. + +F: Allow % to be separated from the rest of a preproc directive, for alternative directive indentation styles. + +F: __DATE__, __TIME__, and text variants of __NASM_MAJOR__ and __NASM_MINOR__. + +F: Warn on TIMES combined with multi-line macros. +V: 1.00 +D: TIMES gets applied to first line only - should bring to users' attention. + +F: Re-work the evaluator, again, with a per-object-format fixup +D: routine, so as to be able to cope with section offsets "really" +D: being pure numbers; should be able to allow at _least_ the two +D: common idioms +D: TIMES 510-$ DB 0 ; bootsector +D: MOV AX,(PROG_END-100H)/16 ; .COM TSR +D: Would need to call the fixup throughout the evaluator, and the +D: fixup would have to be allowed to return UNKNOWN on pass one if it +D: had to. (_Always_ returning UNKNOWN on pass one, though a lovely +D: clean design, breaks the first of the above examples.) +V: 1.10 + +F: Preprocessor identifier concatenation? +V: 1.10 + +F: Arbitrary section names in `bin'. +V: 0.98.09 +D: Is this necessary? Is it even desirable? +D: hpa: Desirable, yes. Necessary? Probably not, but there are definitely cases where it becomes quite useful. +R: madfire +C: 100% + +F: Ability to read from a pipe. +V: 1.10 +D: Obviously not useful under dos, so memory problems with storing +D: entire input file aren't a problem either. + +F: File caching under DOS/32 bit... +V: 1.10? +D: maybe even implement discardable buffers that get thrown away +D: when we get a NULL returned from malloc(). Only really useful under +D: DOS. Think about it. + +F: possibly spool out the pre-processed stuff to a file, to avoid having to re-process it. +V: 1.10? +D: Possible problems with preprocessor values not known on pass 1? Have a look... + +F: Or maybe we can spool out a pre-parsed version...? +V: 1.10 +D: Need to investigate feasibility. Does the results from the parser +D: change from pass 1 to pass 2? Would it be feasible to alter it so that +D: the parser returns an invariant result, and this is then processed +D: afterwards to resolve label references, etc? + +F: Subsection support? + +F: A good ALIGN mechanism, similar to GAS's. +V: 0.98p1 +D: GAS pads out space by means of the following (32-bit) instructions: +D: 8DB42600000000 lea esi,[esi+0x0] +D: 8DB600000000 lea esi,[esi+0x0] +D: 8D742600 lea esi,[esi+0x0] +D: 8D7600 lea esi,[esi+0x0] +D: 8D36 lea esi,[esi] +D: 90 nop +D: It uses up to two of these instructions to do up to 14-byte pads; +D: when more than 14 bytes are needed, it issues a (short) jump to +D: the end of the padded section and then NOPs the rest. Come up with +D: a similar scheme for 16 bit mode, and also come up with a way to +D: use it - internal to the assembler, so that programs using ALIGN +D: don't knock over preprocess-only mode. +D: Also re-work the macro form so that when given one argument in a +D: code section it calls this feature. +R: Panos Minos +C: 100%? + +F: Possibly a means whereby FP constants can be specified as immediate operands to non-FP instructions. +D: * Possible syntax: MOV EAX,FLOAT 1.2 to get a single-precision FP +D: constant. Then maybe MOV EAX,HI_FLOAT 1.2 and MOV EAX,LO_FLOAT +D: 1.2 to get the two halves of a double-precision one. Best to +D: ignore extended-precision in case it bites. +D: * Alternatively, maybe MOV EAX,FLOAT(4,0-4,1.2) to get bytes 0-4 +D: (ie 0-3) of a 4-byte constant. Then HI_FLOAT is FLOAT(8,4-8,x) +D: and LO_FLOAT is FLOAT(8,0-4,x). But this version allows two-byte +D: chunks, one-byte chunks, even stranger chunks, and pieces of +D: ten-byte reals to be bandied around as well. + +F: A UNION macro might be quite cool +D: now that ABSOLUTE is sane enough to be able to handle it. + +F: An equivalent to gcc's ## stringify operator, plus string concatenation +D: somehow implemented without undue ugliness, so as +D: to be able to do `%include "/my/path/%1"' in a macro, or something +D: similar... + +F: Actually _do_ something with the processor, privileged and +D: undocumented flags in the instruction table. When this happens, +D: consider allowing PMULHRW to map to either of the Cyrix or AMD +D: versions? +D: hpa: The -p option to ndisasm now uses this to some extent. +V: 1.10 + +F: Maybe NEC V20/V30 instructions? ? +D: hpa: What are they? Should be trivial to implement. + +F: Yet more object formats. +D: * Possibly direct support for .EXE files? +V: 1.10 + +F: Symbol map in binary format. Format-specific options... +V: 1.10? + +F: REDESIGN: Think about EQU dependency, and about start-point specification in OBJ. Possibly re-think directive support. +V: 1.20? + +F: Think about a wrapper program like gcc? +V: 2.00? +D: Possibly invent a _patch_ for gcc so that it can take .asm files on the command line? +D: If a wrapper happens, think about adding an option to cause the +D: resulting executable file to be executed immediately, thus +D: allowing NASM source files to have #!... (probably silly) + +F: Multi-platform support? +D: If so: definitely Alpha; possibly Java byte code; +D: probably ARM/StrongARM; maybe Sparc; maybe Mips; maybe +D: Vax. Perhaps Z80 and 6502, just for a laugh? + +F: Consider a 'verbose' option that prints information about the resulting object file onto stdout. + +F: Line numbers in the .lst file don't match the line numbers in the input. +D: They probably should, rather than the current matching of the post-preprocessor line numbers. + diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..1af2dd5 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,202 @@ +dnl -------------------------------------------------------------------------- +dnl PA_SYM(prefix, string) +dnl +dnl Convert a (semi-) arbitrary string to a CPP symbol +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_SYM, +[[$1]m4_bpatsubsts(m4_toupper([$2]),[[^ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]+],[_],[^._?\(.*\)_.$],[[\1]])]) + +dnl -------------------------------------------------------------------------- +dnl PA_ADD_CFLAGS(flag [,actual_flag]) +dnl +dnl Attempt to add the given option to CFLAGS, if it doesn't break +dnl compilation. If the option to be tested is different than the +dnl option that should actually be added, add the option to be +dnl actually added as a second argument. +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_ADD_CFLAGS, +[AC_MSG_CHECKING([if $CC accepts $1]) + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_TRY_LINK(AC_INCLUDES_DEFAULT, + [printf("Hello, World!\n");], + [AC_MSG_RESULT([yes]) + CFLAGS="$pa_add_cflags__old_cflags ifelse([$2],[],[$1],[$2])" + AC_DEFINE(PA_SYM([CFLAG_],[$1]), 1, + [Define to 1 if compiled with the `$1' compiler flag])], + [AC_MSG_RESULT([no]) + CFLAGS="$pa_add_cflags__old_cflags"])]) + +dnl -------------------------------------------------------------------------- +dnl PA_ADD_CLDFLAGS(flag [,actual_flag]) +dnl +dnl Attempt to add the given option to CFLAGS and LDFLAGS, +dnl if it doesn't break compilation +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_ADD_CLDFLAGS, +[AC_MSG_CHECKING([if $CC accepts $1]) + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS $1" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_TRY_LINK(AC_INCLUDES_DEFAULT, + [printf("Hello, World!\n");], + [AC_MSG_RESULT([yes]) + CFLAGS="$pa_add_cldflags__old_cflags ifelse([$2],[],[$1],[$2])" + LDFLAGS="$pa_add_cldflags__old_ldflags ifelse([$2],[],[$1],[$2])" + AC_DEFINE(PA_SYM([CFLAG_],[$1]), 1, + [Define to 1 if compiled with the `$1' compiler flag])], + [AC_MSG_RESULT([no]) + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags"])]) + +dnl -------------------------------------------------------------------------- +dnl PA_HAVE_FUNC(func_name) +dnl +dnl Look for a function with the specified arguments which could be +dnl a builtin/intrinsic function. +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_HAVE_FUNC, +[AC_MSG_CHECKING([for $1]) + AC_LINK_IFELSE([AC_LANG_SOURCE([ +AC_INCLUDES_DEFAULT +int main(void) { + (void)$1$2; + return 0; +} + ])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(AS_TR_CPP([HAVE_$1]), 1, + [Define to 1 if you have the `$1' intrinsic function.])], + [AC_MSG_RESULT([no])]) +]) + +dnl -------------------------------------------------------------------------- +dnl PA_LIBEXT +dnl +dnl Guess the library extension based on the object extension +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_LIBEXT, +[AC_MSG_CHECKING([for suffix of library files]) +if test x"$LIBEXT" = x; then + case "$OBJEXT" in + obj ) + LIBEXT=lib + ;; + *) + LIBEXT=a + ;; + esac +fi +AC_MSG_RESULT([$LIBEXT]) +AC_SUBST([LIBEXT])]) + +dnl -------------------------------------------------------------------------- +dnl PA_FUNC_ATTRIBUTE(attribute_name) +dnl +dnl See if this compiler supports the equivalent of a specific gcc +dnl attribute on a function, using the __attribute__(()) syntax. +dnl All arguments except the attribute name are optional. +dnl PA_FUNC_ATTRIBUTE(attribute, attribute_opts, return_type, +dnl prototype_args, call_args) +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_FUNC_ATTRIBUTE, +[AC_MSG_CHECKING([if $CC supports the $1 function attribute]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +AC_INCLUDES_DEFAULT +extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2)) + bar(ifelse([$4],[],[int],[$4])); +ifelse([$3],[],[void *],[$3]) foo(void); +ifelse([$3],[],[void *],[$3]) foo(void) +{ + ifelse([$3],[void],[],[return]) + bar(ifelse([$5],[],[1],[$5])); +} + ])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(PA_SYM([HAVE_FUNC_ATTRIBUTE_],[$1]), 1, + [Define to 1 if your compiler supports __attribute__(($1)) on functions])], + [AC_MSG_RESULT([no])]) +]) + +dnl -------------------------------------------------------------------------- +dnl PA_FUNC_ATTRIBUTE_ERROR +dnl +dnl See if this compiler supports __attribute__((error("foo"))) +dnl The generic version of this doesn't work as it makes the compiler +dnl throw an error by design. +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_FUNC_ATTRIBUTE_ERROR, +[AC_MSG_CHECKING([if $CC supports the error function attribute]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +AC_INCLUDES_DEFAULT +extern void __attribute__((error("message"))) barf(void); +void foo(void); +void foo(void) +{ + if (0) + barf(); +} + ])], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_FUNC_ATTRIBUTE_ERROR], 1, + [Define to 1 if your compiler supports __attribute__((error)) on functions])], + [AC_MSG_RESULT([no])]) +]) + +dnl -------------------------------------------------------------------------- +dnl PA_ARG_ENABLED(option, helptext [,enabled_action [,disabled_action]]) +dnl PA_ARG_DISABLED(option, helptext [,disabled_action [,enabled_action]]) +dnl +dnl Simpler-to-use versions of AC_ARG_ENABLED, that include the +dnl test for $enableval and the AS_HELP_STRING definition +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_ARG_ENABLED, +[AC_ARG_ENABLE([$1], [AS_HELP_STRING([--enable-$1],[$2])], [], [enableval=no]) + AS_IF([test x"$enableval" != xno], [$3], [$4]) +]) + +AC_DEFUN(PA_ARG_DISABLED, +[AC_ARG_ENABLE([$1],[AS_HELP_STRING([--disable-$1],[$2])], [], [enableval=yes]) + AS_IF([test x"$enableval" = xno], [$3], [$4]) +]) + +dnl -------------------------------------------------------------------------- +dnl PA_ADD_HEADERS(headers...) +dnl +dnl Call AC_CHECK_HEADERS(), and add to ac_includes_default if found +dnl -------------------------------------------------------------------------- +AC_DEFUN(_PA_ADD_HEADER, +[AC_CHECK_HEADERS([$1],[ac_includes_default="$ac_includes_default +#include <$1>" +])]) + +AC_DEFUN(PA_ADD_HEADERS, +[m4_map_args_w([$1],[_PA_ADD_HEADER(],[)])]) + +dnl -------------------------------------------------------------------------- +dnl PA_CHECK_BAD_STDC_INLINE +dnl +dnl Some versions of gcc seem to apply -Wmissing-prototypes to C99 +dnl inline functions, which means we need to use GNU inline syntax +dnl -------------------------------------------------------------------------- +AC_DEFUN(PA_CHECK_BAD_STDC_INLINE, +[AC_MSG_CHECKING([if $CC supports C99 external inlines]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +AC_INCLUDES_DEFAULT + +/* Don't mistake GNU inlines for c99 */ +#ifdef __GNUC_GNU_INLINE__ +# error "Using gnu inline standard" +#endif + +inline int foo(int x) +{ + return x+1; +} + ])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_STDC_INLINE, 1, + [Define to 1 if your compiler supports C99 extern inline])], + [AC_MSG_RESULT([no]) + PA_ADD_CFLAGS([-fgnu89-inline])])]) diff --git a/asm/assemble.c b/asm/assemble.c new file mode 100644 index 0000000..30dc047 --- /dev/null +++ b/asm/assemble.c @@ -0,0 +1,2997 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * assemble.c code generation for the Netwide Assembler + * + * Bytecode specification + * ---------------------- + * + * + * Codes Mnemonic Explanation + * + * \0 terminates the code. (Unless it's a literal of course.) + * \1..\4 that many literal bytes follow in the code stream + * \5 add 4 to the primary operand number (b, low octdigit) + * \6 add 4 to the secondary operand number (a, middle octdigit) + * \7 add 4 to both the primary and the secondary operand number + * \10..\13 a literal byte follows in the code stream, to be added + * to the register value of operand 0..3 + * \14..\17 the position of index register operand in MIB (BND insns) + * \20..\23 ib a byte immediate operand, from operand 0..3 + * \24..\27 ib,u a zero-extended byte immediate operand, from operand 0..3 + * \30..\33 iw a word immediate operand, from operand 0..3 + * \34..\37 iwd select between \3[0-3] and \4[0-3] depending on 16/32 bit + * assembly mode or the operand-size override on the operand + * \40..\43 id a long immediate operand, from operand 0..3 + * \44..\47 iwdq select between \3[0-3], \4[0-3] and \5[4-7] + * depending on the address size of the instruction. + * \50..\53 rel8 a byte relative operand, from operand 0..3 + * \54..\57 iq a qword immediate operand, from operand 0..3 + * \60..\63 rel16 a word relative operand, from operand 0..3 + * \64..\67 rel select between \6[0-3] and \7[0-3] depending on 16/32 bit + * assembly mode or the operand-size override on the operand + * \70..\73 rel32 a long relative operand, from operand 0..3 + * \74..\77 seg a word constant, from the _segment_ part of operand 0..3 + * \1ab a ModRM, calculated on EA in operand a, with the spare + * field the register value of operand b. + * \172\ab the register number from operand a in bits 7..4, with + * the 4-bit immediate from operand b in bits 3..0. + * \173\xab the register number from operand a in bits 7..4, with + * the value b in bits 3..0. + * \174..\177 the register number from operand 0..3 in bits 7..4, and + * an arbitrary value in bits 3..0 (assembled as zero.) + * \2ab a ModRM, calculated on EA in operand a, with the spare + * field equal to digit b. + * + * \240..\243 this instruction uses EVEX rather than REX or VEX/XOP, with the + * V field taken from operand 0..3. + * \250 this instruction uses EVEX rather than REX or VEX/XOP, with the + * V field set to 1111b. + * + * EVEX prefixes are followed by the sequence: + * \cm\wlp\tup where cm is: + * cc 00m mmm + * c = 2 for EVEX and mmmm is the M field (EVEX.P0[3:0]) + * and wlp is: + * 00 wwl lpp + * [l0] ll = 0 (.128, .lz) + * [l1] ll = 1 (.256) + * [l2] ll = 2 (.512) + * [lig] ll = 3 for EVEX.L'L don't care (always assembled as 0) + * + * [w0] ww = 0 for W = 0 + * [w1] ww = 1 for W = 1 + * [wig] ww = 2 for W don't care (always assembled as 0) + * [ww] ww = 3 for W used as REX.W + * + * [p0] pp = 0 for no prefix + * [60] pp = 1 for legacy prefix 60 + * [f3] pp = 2 + * [f2] pp = 3 + * + * tup is tuple type for Disp8*N from %tuple_codes in insns.pl + * (compressed displacement encoding) + * + * \254..\257 id,s a signed 32-bit operand to be extended to 64 bits. + * \260..\263 this instruction uses VEX/XOP rather than REX, with the + * V field taken from operand 0..3. + * \270 this instruction uses VEX/XOP rather than REX, with the + * V field set to 1111b. + * + * VEX/XOP prefixes are followed by the sequence: + * \tmm\wlp where mm is the M field; and wlp is: + * 00 wwl lpp + * [l0] ll = 0 for L = 0 (.128, .lz) + * [l1] ll = 1 for L = 1 (.256) + * [lig] ll = 2 for L don't care (always assembled as 0) + * + * [w0] ww = 0 for W = 0 + * [w1 ] ww = 1 for W = 1 + * [wig] ww = 2 for W don't care (always assembled as 0) + * [ww] ww = 3 for W used as REX.W + * + * t = 0 for VEX (C4/C5), t = 1 for XOP (8F). + * + * \271 hlexr instruction takes XRELEASE (F3) with or without lock + * \272 hlenl instruction takes XACQUIRE/XRELEASE with or without lock + * \273 hle instruction takes XACQUIRE/XRELEASE with lock only + * \274..\277 ib,s a byte immediate operand, from operand 0..3, sign-extended + * to the operand size (if o16/o32/o64 present) or the bit size + * \310 a16 indicates fixed 16-bit address size, i.e. optional 0x67. + * \311 a32 indicates fixed 32-bit address size, i.e. optional 0x67. + * \312 adf (disassembler only) invalid with non-default address size. + * \313 a64 indicates fixed 64-bit address size, 0x67 invalid. + * \314 norexb (disassembler only) invalid with REX.B + * \315 norexx (disassembler only) invalid with REX.X + * \316 norexr (disassembler only) invalid with REX.R + * \317 norexw (disassembler only) invalid with REX.W + * \320 o16 indicates fixed 16-bit operand size, i.e. optional 0x66. + * \321 o32 indicates fixed 32-bit operand size, i.e. optional 0x66. + * \322 odf indicates that this instruction is only valid when the + * operand size is the default (instruction to disassembler, + * generates no code in the assembler) + * \323 o64nw indicates fixed 64-bit operand size, REX on extensions only. + * \324 o64 indicates 64-bit operand size requiring REX prefix. + * \325 nohi instruction which always uses spl/bpl/sil/dil + * \326 nof3 instruction not valid with 0xF3 REP prefix. Hint for + disassembler only; for SSE instructions. + * \330 a literal byte follows in the code stream, to be added + * to the condition code value of the instruction. + * \331 norep instruction not valid with REP prefix. Hint for + * disassembler only; for SSE instructions. + * \332 f2i REP prefix (0xF2 byte) used as opcode extension. + * \333 f3i REP prefix (0xF3 byte) used as opcode extension. + * \334 rex.l LOCK prefix used as REX.R (used in non-64-bit mode) + * \335 repe disassemble a rep (0xF3 byte) prefix as repe not rep. + * \336 mustrep force a REP(E) prefix (0xF3) even if not specified. + * \337 mustrepne force a REPNE prefix (0xF2) even if not specified. + * \336-\337 are still listed as prefixes in the disassembler. + * \340 resb reserve bytes of uninitialized storage. + * Operand 0 had better be a segmentless constant. + * \341 wait this instruction needs a WAIT "prefix" + * \360 np no SSE prefix (== \364\331) + * \361 66 SSE prefix (== \366\331) + * \364 !osp operand-size prefix (0x66) not permitted + * \365 !asp address-size prefix (0x67) not permitted + * \366 operand-size prefix (0x66) used as opcode extension + * \367 address-size prefix (0x67) used as opcode extension + * \370,\371 jcc8 match only if operand 0 meets byte jump criteria. + * jmp8 370 is used for Jcc, 371 is used for JMP. + * \373 jlen assemble 0x03 if bits==16, 0x05 if bits==32; + * used for conditional jump over longer jump + * \374 vsibx|vm32x|vm64x this instruction takes an XMM VSIB memory EA + * \375 vsiby|vm32y|vm64y this instruction takes an YMM VSIB memory EA + * \376 vsibz|vm32z|vm64z this instruction takes an ZMM VSIB memory EA + */ + +#include "compiler.h" + +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "assemble.h" +#include "insns.h" +#include "tables.h" +#include "disp8.h" +#include "listing.h" + +enum match_result { + /* + * Matching errors. These should be sorted so that more specific + * errors come later in the sequence. + */ + MERR_INVALOP, + MERR_OPSIZEMISSING, + MERR_OPSIZEMISMATCH, + MERR_BRNOTHERE, + MERR_BRNUMMISMATCH, + MERR_MASKNOTHERE, + MERR_DECONOTHERE, + MERR_BADCPU, + MERR_BADMODE, + MERR_BADHLE, + MERR_ENCMISMATCH, + MERR_BADBND, + MERR_BADREPNE, + MERR_REGSETSIZE, + MERR_REGSET, + /* + * Matching success; the conditional ones first + */ + MOK_JUMP, /* Matching OK but needs jmp_match() */ + MOK_GOOD /* Matching unconditionally OK */ +}; + +typedef struct { + enum ea_type type; /* what kind of EA is this? */ + int sib_present; /* is a SIB byte necessary? */ + int bytes; /* # of bytes of offset needed */ + int size; /* lazy - this is sib+bytes+1 */ + uint8_t modrm, sib, rex, rip; /* the bytes themselves */ + int8_t disp8; /* compressed displacement for EVEX */ +} ea; + +#define GEN_SIB(scale, index, base) \ + (((scale) << 6) | ((index) << 3) | ((base))) + +#define GEN_MODRM(mod, reg, rm) \ + (((mod) << 6) | (((reg) & 7) << 3) | ((rm) & 7)) + +static int64_t calcsize(int32_t, int64_t, int, insn *, + const struct itemplate *); +static int emit_prefix(struct out_data *data, const int bits, insn *ins); +static void gencode(struct out_data *data, insn *ins); +static enum match_result find_match(const struct itemplate **tempp, + insn *instruction, + int32_t segment, int64_t offset, int bits); +static enum match_result matches(const struct itemplate *, insn *, int bits); +static opflags_t regflag(const operand *); +static int32_t regval(const operand *); +static int rexflags(int, opflags_t, int); +static int op_rexflags(const operand *, int); +static int op_evexflags(const operand *, int, uint8_t); +static void add_asp(insn *, int); + +static enum ea_type process_ea(operand *, ea *, int, int, + opflags_t, insn *, const char **); + +static inline bool absolute_op(const struct operand *o) +{ + return o->segment == NO_SEG && o->wrt == NO_SEG && + !(o->opflags & OPFLAG_RELATIVE); +} + +static int has_prefix(insn * ins, enum prefix_pos pos, int prefix) +{ + return ins->prefixes[pos] == prefix; +} + +static void assert_no_prefix(insn * ins, enum prefix_pos pos) +{ + if (ins->prefixes[pos]) + nasm_error(ERR_NONFATAL, "invalid %s prefix", + prefix_name(ins->prefixes[pos])); +} + +static const char *size_name(int size) +{ + switch (size) { + case 1: + return "byte"; + case 2: + return "word"; + case 4: + return "dword"; + case 8: + return "qword"; + case 10: + return "tword"; + case 16: + return "oword"; + case 32: + return "yword"; + case 64: + return "zword"; + default: + return "???"; + } +} + +static void warn_overflow(int size) +{ + nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, + "%s data exceeds bounds", size_name(size)); +} + +static void warn_overflow_const(int64_t data, int size) +{ + if (overflow_general(data, size)) + warn_overflow(size); +} + +static void warn_overflow_out(int64_t data, int size, enum out_sign sign) +{ + bool err; + + switch (sign) { + case OUT_WRAP: + err = overflow_general(data, size); + break; + case OUT_SIGNED: + err = overflow_signed(data, size); + break; + case OUT_UNSIGNED: + err = overflow_unsigned(data, size); + break; + default: + panic(); + break; + } + + if (err) + warn_overflow(size); +} + +/* + * This routine wrappers the real output format's output routine, + * in order to pass a copy of the data off to the listing file + * generator at the same time, flatten unnecessary relocations, + * and verify backend compatibility. + */ +static void out(struct out_data *data) +{ + static int32_t lineno = 0; /* static!!! */ + static const char *lnfname = NULL; + union { + uint8_t b[8]; + uint64_t q; + } xdata; + size_t asize, amax; + uint64_t zeropad = 0; + int64_t addrval; + int32_t fixseg; /* Segment for which to produce fixed data */ + + if (!data->size) + return; /* Nothing to do */ + + /* + * Convert addresses to RAWDATA if possible + * XXX: not all backends want this for global symbols!!!! + */ + switch (data->type) { + case OUT_ADDRESS: + addrval = data->toffset; + fixseg = NO_SEG; /* Absolute address is fixed data */ + goto address; + + case OUT_RELADDR: + addrval = data->toffset - data->relbase; + fixseg = data->segment; /* Our own segment is fixed data */ + goto address; + + address: + nasm_assert(data->size <= 8); + asize = data->size; + amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */ + if ((ofmt->flags & OFMT_KEEP_ADDR) == 0 && data->tsegment == fixseg && + data->twrt == NO_SEG) { + warn_overflow_out(addrval, asize, data->sign); + xdata.q = cpu_to_le64(addrval); + data->data = xdata.b; + data->type = OUT_RAWDATA; + asize = amax = 0; /* No longer an address */ + } + break; + + case OUT_SEGMENT: + nasm_assert(data->size <= 8); + asize = data->size; + amax = 2; + break; + + default: + asize = amax = 0; /* Not an address */ + break; + } + + /* + * this call to src_get determines when we call the + * debug-format-specific "linenum" function + * it updates lineno and lnfname to the current values + * returning 0 if "same as last time", -2 if lnfname + * changed, and the amount by which lineno changed, + * if it did. thus, these variables must be static + */ + + if (src_get(&lineno, &lnfname)) + dfmt->linenum(lnfname, lineno, data->segment); + + if (asize > amax) { + if (data->type == OUT_RELADDR || data->sign == OUT_SIGNED) { + nasm_error(ERR_NONFATAL, + "%u-bit signed relocation unsupported by output format %s", + (unsigned int)(asize << 3), ofmt->shortname); + } else { + nasm_error(ERR_WARNING | ERR_WARN_ZEXTRELOC, + "%u-bit %s relocation zero-extended from %u bits", + (unsigned int)(asize << 3), + data->type == OUT_SEGMENT ? "segment" : "unsigned", + (unsigned int)(amax << 3)); + } + zeropad = data->size - amax; + data->size = amax; + } + lfmt->output(data); + ofmt->output(data); + data->offset += data->size; + data->insoffs += data->size; + + if (zeropad) { + data->type = OUT_ZERODATA; + data->size = zeropad; + lfmt->output(data); + ofmt->output(data); + data->offset += zeropad; + data->insoffs += zeropad; + data->size += zeropad; /* Restore original size value */ + } +} + +static inline void out_rawdata(struct out_data *data, const void *rawdata, + size_t size) +{ + data->type = OUT_RAWDATA; + data->data = rawdata; + data->size = size; + out(data); +} + +static void out_rawbyte(struct out_data *data, uint8_t byte) +{ + data->type = OUT_RAWDATA; + data->data = &byte; + data->size = 1; + out(data); +} + +static inline void out_reserve(struct out_data *data, uint64_t size) +{ + data->type = OUT_RESERVE; + data->size = size; + out(data); +} + +static void out_segment(struct out_data *data, const struct operand *opx) +{ + if (opx->opflags & OPFLAG_RELATIVE) + nasm_error(ERR_NONFATAL, "segment references cannot be relative"); + + data->type = OUT_SEGMENT; + data->sign = OUT_UNSIGNED; + data->size = 2; + data->toffset = opx->offset; + data->tsegment = ofmt->segbase(opx->segment | 1); + data->twrt = opx->wrt; + out(data); +} + +static void out_imm(struct out_data *data, const struct operand *opx, + int size, enum out_sign sign) +{ + if (opx->segment != NO_SEG && (opx->segment & 1)) { + /* + * This is actually a segment reference, but eval() has + * already called ofmt->segbase() for us. Sigh. + */ + if (size < 2) + nasm_error(ERR_NONFATAL, "segment reference must be 16 bits"); + + data->type = OUT_SEGMENT; + } else { + data->type = (opx->opflags & OPFLAG_RELATIVE) + ? OUT_RELADDR : OUT_ADDRESS; + } + data->sign = sign; + data->toffset = opx->offset; + data->tsegment = opx->segment; + data->twrt = opx->wrt; + /* + * XXX: improve this if at some point in the future we can + * distinguish the subtrahend in expressions like [foo - bar] + * where bar is a symbol in the current segment. However, at the + * current point, if OPFLAG_RELATIVE is set that subtraction has + * already occurred. + */ + data->relbase = 0; + data->size = size; + out(data); +} + +static void out_reladdr(struct out_data *data, const struct operand *opx, + int size) +{ + if (opx->opflags & OPFLAG_RELATIVE) + nasm_error(ERR_NONFATAL, "invalid use of self-relative expression"); + + data->type = OUT_RELADDR; + data->sign = OUT_SIGNED; + data->size = size; + data->toffset = opx->offset; + data->tsegment = opx->segment; + data->twrt = opx->wrt; + data->relbase = data->offset + (data->inslen - data->insoffs); + out(data); +} + +static bool jmp_match(int32_t segment, int64_t offset, int bits, + insn * ins, const struct itemplate *temp) +{ + int64_t isize; + const uint8_t *code = temp->code; + uint8_t c = code[0]; + bool is_byte; + + if (((c & ~1) != 0370) || (ins->oprs[0].type & STRICT)) + return false; + if (!optimizing.level || (optimizing.flag & OPTIM_DISABLE_JMP_MATCH)) + return false; + if (optimizing.level < 0 && c == 0371) + return false; + + isize = calcsize(segment, offset, bits, ins, temp); + + if (ins->oprs[0].opflags & OPFLAG_UNKNOWN) + /* Be optimistic in pass 1 */ + return true; + + if (ins->oprs[0].segment != segment) + return false; + + isize = ins->oprs[0].offset - offset - isize; /* isize is delta */ + is_byte = (isize >= -128 && isize <= 127); /* is it byte size? */ + + if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) { + /* jmp short (opcode eb) cannot be used with bnd prefix. */ + ins->prefixes[PPS_REP] = P_none; + nasm_error(ERR_WARNING | ERR_WARN_BND | ERR_PASS2 , + "jmp short does not init bnd regs - bnd prefix dropped."); + } + + return is_byte; +} + +/* This is totally just a wild guess what is reasonable... */ +#define INCBIN_MAX_BUF (ZERO_BUF_SIZE * 16) + +int64_t assemble(int32_t segment, int64_t start, int bits, insn *instruction) +{ + struct out_data data; + const struct itemplate *temp; + enum match_result m; + int64_t wsize; /* size for DB etc. */ + + nasm_zero(data); + data.offset = start; + data.segment = segment; + data.itemp = NULL; + data.bits = bits; + + wsize = db_bytes(instruction->opcode); + if (wsize == -1) + return 0; + + if (wsize) { + extop *e; + + list_for_each(e, instruction->eops) { + if (e->type == EOT_DB_NUMBER) { + if (wsize > 8) { + nasm_error(ERR_NONFATAL, + "integer supplied to a DT, DO, DY or DZ" + " instruction"); + } else { + data.insoffs = 0; + data.inslen = data.size = wsize; + data.toffset = e->offset; + data.twrt = e->wrt; + data.relbase = 0; + if (e->segment != NO_SEG && (e->segment & 1)) { + data.tsegment = e->segment; + data.type = OUT_SEGMENT; + data.sign = OUT_UNSIGNED; + } else { + data.tsegment = e->segment; + data.type = e->relative ? OUT_RELADDR : OUT_ADDRESS; + data.sign = OUT_WRAP; + } + out(&data); + } + } else if (e->type == EOT_DB_STRING || + e->type == EOT_DB_STRING_FREE) { + int align = e->stringlen % wsize; + if (align) + align = wsize - align; + + data.insoffs = 0; + data.inslen = e->stringlen + align; + + out_rawdata(&data, e->stringval, e->stringlen); + out_rawdata(&data, zero_buffer, align); + } + } + } else if (instruction->opcode == I_INCBIN) { + const char *fname = instruction->eops->stringval; + FILE *fp; + size_t t = instruction->times; /* INCBIN handles TIMES by itself */ + off_t base = 0; + off_t len; + const void *map = NULL; + char *buf = NULL; + size_t blk = 0; /* Buffered I/O block size */ + size_t m = 0; /* Bytes last read */ + + if (!t) + goto done; + + fp = nasm_open_read(fname, NF_BINARY|NF_FORMAP); + if (!fp) { + nasm_error(ERR_NONFATAL, "`incbin': unable to open file `%s'", + fname); + goto done; + } + + len = nasm_file_size(fp); + + if (len == (off_t)-1) { + nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'", + fname); + goto close_done; + } + + if (instruction->eops->next) { + base = instruction->eops->next->offset; + if (base >= len) { + len = 0; + } else { + len -= base; + if (instruction->eops->next->next && + len > (off_t)instruction->eops->next->next->offset) + len = (off_t)instruction->eops->next->next->offset; + } + } + + lfmt->set_offset(data.offset); + lfmt->uplevel(LIST_INCBIN); + + if (!len) + goto end_incbin; + + /* Try to map file data */ + map = nasm_map_file(fp, base, len); + if (!map) { + blk = len < (off_t)INCBIN_MAX_BUF ? (size_t)len : INCBIN_MAX_BUF; + buf = nasm_malloc(blk); + } + + while (t--) { + /* + * Consider these irrelevant for INCBIN, since it is fully + * possible that these might be (way) bigger than an int + * can hold; there is, however, no reason to widen these + * types just for INCBIN. data.inslen == 0 signals to the + * backend that these fields are meaningless, if at all + * needed. + */ + data.insoffs = 0; + data.inslen = 0; + + if (map) { + out_rawdata(&data, map, len); + } else if ((off_t)m == len) { + out_rawdata(&data, buf, len); + } else { + off_t l = len; + + if (fseeko(fp, base, SEEK_SET) < 0 || ferror(fp)) { + nasm_error(ERR_NONFATAL, + "`incbin': unable to seek on file `%s'", + fname); + goto end_incbin; + } + while (l > 0) { + m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp); + if (!m || feof(fp)) { + /* + * This shouldn't happen unless the file + * actually changes while we are reading + * it. + */ + nasm_error(ERR_NONFATAL, + "`incbin': unexpected EOF while" + " reading file `%s'", fname); + goto end_incbin; + } + out_rawdata(&data, buf, m); + l -= m; + } + } + } + end_incbin: + lfmt->downlevel(LIST_INCBIN); + if (instruction->times > 1) { + lfmt->uplevel(LIST_TIMES); + lfmt->downlevel(LIST_TIMES); + } + if (ferror(fp)) { + nasm_error(ERR_NONFATAL, + "`incbin': error while" + " reading file `%s'", fname); + } + close_done: + if (buf) + nasm_free(buf); + if (map) + nasm_unmap_file(map, len); + fclose(fp); + done: + instruction->times = 1; /* Tell the upper layer not to iterate */ + ; + } else { + /* "Real" instruction */ + + /* Check to see if we need an address-size prefix */ + add_asp(instruction, bits); + + m = find_match(&temp, instruction, data.segment, data.offset, bits); + + if (m == MOK_GOOD) { + /* Matches! */ + int64_t insn_size = calcsize(data.segment, data.offset, + bits, instruction, temp); + nasm_assert(insn_size >= 0); + + data.itemp = temp; + data.bits = bits; + data.insoffs = 0; + data.inslen = insn_size; + + gencode(&data, instruction); + nasm_assert(data.insoffs == insn_size); + } else { + /* No match */ + switch (m) { + case MERR_OPSIZEMISSING: + nasm_error(ERR_NONFATAL, "operation size not specified"); + break; + case MERR_OPSIZEMISMATCH: + nasm_error(ERR_NONFATAL, "mismatch in operand sizes"); + break; + case MERR_BRNOTHERE: + nasm_error(ERR_NONFATAL, + "broadcast not permitted on this operand"); + break; + case MERR_BRNUMMISMATCH: + nasm_error(ERR_NONFATAL, + "mismatch in the number of broadcasting elements"); + break; + case MERR_MASKNOTHERE: + nasm_error(ERR_NONFATAL, + "mask not permitted on this operand"); + break; + case MERR_DECONOTHERE: + nasm_error(ERR_NONFATAL, "unsupported mode decorator for instruction"); + break; + case MERR_BADCPU: + nasm_error(ERR_NONFATAL, "no instruction for this cpu level"); + break; + case MERR_BADMODE: + nasm_error(ERR_NONFATAL, "instruction not supported in %d-bit mode", + bits); + break; + case MERR_ENCMISMATCH: + nasm_error(ERR_NONFATAL, "specific encoding scheme not available"); + break; + case MERR_BADBND: + nasm_error(ERR_NONFATAL, "bnd prefix is not allowed"); + break; + case MERR_BADREPNE: + nasm_error(ERR_NONFATAL, "%s prefix is not allowed", + (has_prefix(instruction, PPS_REP, P_REPNE) ? + "repne" : "repnz")); + break; + case MERR_REGSETSIZE: + nasm_error(ERR_NONFATAL, "invalid register set size"); + break; + case MERR_REGSET: + nasm_error(ERR_NONFATAL, "register set not valid for operand"); + break; + default: + nasm_error(ERR_NONFATAL, + "invalid combination of opcode and operands"); + break; + } + + instruction->times = 1; /* Avoid repeated error messages */ + } + } + return data.offset - start; +} + +int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction) +{ + const struct itemplate *temp; + enum match_result m; + + if (instruction->opcode == I_none) + return 0; + + if (opcode_is_db(instruction->opcode)) { + extop *e; + int32_t isize, osize, wsize; + + isize = 0; + wsize = db_bytes(instruction->opcode); + nasm_assert(wsize > 0); + + list_for_each(e, instruction->eops) { + int32_t align; + + osize = 0; + if (e->type == EOT_DB_NUMBER) { + osize = 1; + warn_overflow_const(e->offset, wsize); + } else if (e->type == EOT_DB_STRING || + e->type == EOT_DB_STRING_FREE) + osize = e->stringlen; + + align = (-osize) % wsize; + if (align < 0) + align += wsize; + isize += osize + align; + } + return isize; + } + + if (instruction->opcode == I_INCBIN) { + const char *fname = instruction->eops->stringval; + off_t len; + + len = nasm_file_size_by_path(fname); + if (len == (off_t)-1) { + nasm_error(ERR_NONFATAL, "`incbin': unable to get length of file `%s'", + fname); + return 0; + } + + if (instruction->eops->next) { + if (len <= (off_t)instruction->eops->next->offset) { + len = 0; + } else { + len -= instruction->eops->next->offset; + if (instruction->eops->next->next && + len > (off_t)instruction->eops->next->next->offset) { + len = (off_t)instruction->eops->next->next->offset; + } + } + } + + len *= instruction->times; + instruction->times = 1; /* Tell the upper layer to not iterate */ + + return len; + } + + /* Check to see if we need an address-size prefix */ + add_asp(instruction, bits); + + m = find_match(&temp, instruction, segment, offset, bits); + if (m == MOK_GOOD) { + /* we've matched an instruction. */ + return calcsize(segment, offset, bits, instruction, temp); + } else { + return -1; /* didn't match any instruction */ + } +} + +static void bad_hle_warn(const insn * ins, uint8_t hleok) +{ + enum prefixes rep_pfx = ins->prefixes[PPS_REP]; + enum whatwarn { w_none, w_lock, w_inval } ww; + static const enum whatwarn warn[2][4] = + { + { w_inval, w_inval, w_none, w_lock }, /* XACQUIRE */ + { w_inval, w_none, w_none, w_lock }, /* XRELEASE */ + }; + unsigned int n; + + n = (unsigned int)rep_pfx - P_XACQUIRE; + if (n > 1) + return; /* Not XACQUIRE/XRELEASE */ + + ww = warn[n][hleok]; + if (!is_class(MEMORY, ins->oprs[0].type)) + ww = w_inval; /* HLE requires operand 0 to be memory */ + + switch (ww) { + case w_none: + break; + + case w_lock: + if (ins->prefixes[PPS_LOCK] != P_LOCK) { + nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2, + "%s with this instruction requires lock", + prefix_name(rep_pfx)); + } + break; + + case w_inval: + nasm_error(ERR_WARNING | ERR_WARN_HLE | ERR_PASS2, + "%s invalid with this instruction", + prefix_name(rep_pfx)); + break; + } +} + +/* Common construct */ +#define case3(x) case (x): case (x)+1: case (x)+2 +#define case4(x) case3(x): case (x)+3 + +static int64_t calcsize(int32_t segment, int64_t offset, int bits, + insn * ins, const struct itemplate *temp) +{ + const uint8_t *codes = temp->code; + int64_t length = 0; + uint8_t c; + int rex_mask = ~0; + int op1, op2; + struct operand *opx; + uint8_t opex = 0; + enum ea_type eat; + uint8_t hleok = 0; + bool lockcheck = true; + enum reg_enum mib_index = R_none; /* For a separate index MIB reg form */ + const char *errmsg; + + ins->rex = 0; /* Ensure REX is reset */ + eat = EA_SCALAR; /* Expect a scalar EA */ + memset(ins->evex_p, 0, 3); /* Ensure EVEX is reset */ + + if (ins->prefixes[PPS_OSIZE] == P_O64) + ins->rex |= REX_W; + + (void)segment; /* Don't warn that this parameter is unused */ + (void)offset; /* Don't warn that this parameter is unused */ + + while (*codes) { + c = *codes++; + op1 = (c & 3) + ((opex & 1) << 2); + op2 = ((c >> 3) & 3) + ((opex & 2) << 1); + opx = &ins->oprs[op1]; + opex = 0; /* For the next iteration */ + + switch (c) { + case4(01): + codes += c, length += c; + break; + + case3(05): + opex = c; + break; + + case4(010): + ins->rex |= + op_rexflags(opx, REX_B|REX_H|REX_P|REX_W); + codes++, length++; + break; + + case4(014): + /* this is an index reg of MIB operand */ + mib_index = opx->basereg; + break; + + case4(020): + case4(024): + length++; + break; + + case4(030): + length += 2; + break; + + case4(034): + if (opx->type & (BITS16 | BITS32 | BITS64)) + length += (opx->type & BITS16) ? 2 : 4; + else + length += (bits == 16) ? 2 : 4; + break; + + case4(040): + length += 4; + break; + + case4(044): + length += ins->addr_size >> 3; + break; + + case4(050): + length++; + break; + + case4(054): + length += 8; /* MOV reg64/imm */ + break; + + case4(060): + length += 2; + break; + + case4(064): + if (opx->type & (BITS16 | BITS32 | BITS64)) + length += (opx->type & BITS16) ? 2 : 4; + else + length += (bits == 16) ? 2 : 4; + break; + + case4(070): + length += 4; + break; + + case4(074): + length += 2; + break; + + case 0172: + case 0173: + codes++; + length++; + break; + + case4(0174): + length++; + break; + + case4(0240): + ins->rex |= REX_EV; + ins->vexreg = regval(opx); + ins->evex_p[2] |= op_evexflags(opx, EVEX_P2VP, 2); /* High-16 NDS */ + ins->vex_cm = *codes++; + ins->vex_wlp = *codes++; + ins->evex_tuple = (*codes++ - 0300); + break; + + case 0250: + ins->rex |= REX_EV; + ins->vexreg = 0; + ins->vex_cm = *codes++; + ins->vex_wlp = *codes++; + ins->evex_tuple = (*codes++ - 0300); + break; + + case4(0254): + length += 4; + break; + + case4(0260): + ins->rex |= REX_V; + ins->vexreg = regval(opx); + ins->vex_cm = *codes++; + ins->vex_wlp = *codes++; + break; + + case 0270: + ins->rex |= REX_V; + ins->vexreg = 0; + ins->vex_cm = *codes++; + ins->vex_wlp = *codes++; + break; + + case3(0271): + hleok = c & 3; + break; + + case4(0274): + length++; + break; + + case4(0300): + break; + + case 0310: + if (bits == 64) + return -1; + length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16); + break; + + case 0311: + length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32); + break; + + case 0312: + break; + + case 0313: + if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) || + has_prefix(ins, PPS_ASIZE, P_A32)) + return -1; + break; + + case4(0314): + break; + + case 0320: + { + enum prefixes pfx = ins->prefixes[PPS_OSIZE]; + if (pfx == P_O16) + break; + if (pfx != P_none) + nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix"); + else + ins->prefixes[PPS_OSIZE] = P_O16; + break; + } + + case 0321: + { + enum prefixes pfx = ins->prefixes[PPS_OSIZE]; + if (pfx == P_O32) + break; + if (pfx != P_none) + nasm_error(ERR_WARNING | ERR_PASS2, "invalid operand size prefix"); + else + ins->prefixes[PPS_OSIZE] = P_O32; + break; + } + + case 0322: + break; + + case 0323: + rex_mask &= ~REX_W; + break; + + case 0324: + ins->rex |= REX_W; + break; + + case 0325: + ins->rex |= REX_NH; + break; + + case 0326: + break; + + case 0330: + codes++, length++; + break; + + case 0331: + break; + + case 0332: + case 0333: + length++; + break; + + case 0334: + ins->rex |= REX_L; + break; + + case 0335: + break; + + case 0336: + if (!ins->prefixes[PPS_REP]) + ins->prefixes[PPS_REP] = P_REP; + break; + + case 0337: + if (!ins->prefixes[PPS_REP]) + ins->prefixes[PPS_REP] = P_REPNE; + break; + + case 0340: + if (!absolute_op(&ins->oprs[0])) + nasm_error(ERR_NONFATAL, "attempt to reserve non-constant" + " quantity of BSS space"); + else if (ins->oprs[0].opflags & OPFLAG_FORWARD) + nasm_error(ERR_WARNING | ERR_PASS1, + "forward reference in RESx can have unpredictable results"); + else + length += ins->oprs[0].offset; + break; + + case 0341: + if (!ins->prefixes[PPS_WAIT]) + ins->prefixes[PPS_WAIT] = P_WAIT; + break; + + case 0360: + break; + + case 0361: + length++; + break; + + case 0364: + case 0365: + break; + + case 0366: + case 0367: + length++; + break; + + case 0370: + case 0371: + break; + + case 0373: + length++; + break; + + case 0374: + eat = EA_XMMVSIB; + break; + + case 0375: + eat = EA_YMMVSIB; + break; + + case 0376: + eat = EA_ZMMVSIB; + break; + + case4(0100): + case4(0110): + case4(0120): + case4(0130): + case4(0200): + case4(0204): + case4(0210): + case4(0214): + case4(0220): + case4(0224): + case4(0230): + case4(0234): + { + ea ea_data; + int rfield; + opflags_t rflags; + struct operand *opy = &ins->oprs[op2]; + struct operand *op_er_sae; + + ea_data.rex = 0; /* Ensure ea.REX is initially 0 */ + + if (c <= 0177) { + /* pick rfield from operand b (opx) */ + rflags = regflag(opx); + rfield = nasm_regvals[opx->basereg]; + } else { + rflags = 0; + rfield = c & 7; + } + + /* EVEX.b1 : evex_brerop contains the operand position */ + op_er_sae = (ins->evex_brerop >= 0 ? + &ins->oprs[ins->evex_brerop] : NULL); + + if (op_er_sae && (op_er_sae->decoflags & (ER | SAE))) { + /* set EVEX.b */ + ins->evex_p[2] |= EVEX_P2B; + if (op_er_sae->decoflags & ER) { + /* set EVEX.RC (rounding control) */ + ins->evex_p[2] |= ((ins->evex_rm - BRC_RN) << 5) + & EVEX_P2RC; + } + } else { + /* set EVEX.L'L (vector length) */ + ins->evex_p[2] |= ((ins->vex_wlp << (5 - 2)) & EVEX_P2LL); + ins->evex_p[1] |= ((ins->vex_wlp << (7 - 4)) & EVEX_P1W); + if (opy->decoflags & BRDCAST_MASK) { + /* set EVEX.b */ + ins->evex_p[2] |= EVEX_P2B; + } + } + + if (itemp_has(temp, IF_MIB)) { + opy->eaflags |= EAF_MIB; + /* + * if a separate form of MIB (ICC style) is used, + * the index reg info is merged into mem operand + */ + if (mib_index != R_none) { + opy->indexreg = mib_index; + opy->scale = 1; + opy->hintbase = mib_index; + opy->hinttype = EAH_NOTBASE; + } + } + + if (process_ea(opy, &ea_data, bits, + rfield, rflags, ins, &errmsg) != eat) { + nasm_error(ERR_NONFATAL, "%s", errmsg); + return -1; + } else { + ins->rex |= ea_data.rex; + length += ea_data.size; + } + } + break; + + default: + nasm_panic(0, "internal instruction table corrupt" + ": instruction code \\%o (0x%02X) given", c, c); + break; + } + } + + ins->rex &= rex_mask; + + if (ins->rex & REX_NH) { + if (ins->rex & REX_H) { + nasm_error(ERR_NONFATAL, "instruction cannot use high registers"); + return -1; + } + ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */ + } + + switch (ins->prefixes[PPS_VEX]) { + case P_EVEX: + if (!(ins->rex & REX_EV)) + return -1; + break; + case P_VEX3: + case P_VEX2: + if (!(ins->rex & REX_V)) + return -1; + break; + default: + break; + } + + if (ins->rex & (REX_V | REX_EV)) { + int bad32 = REX_R|REX_W|REX_X|REX_B; + + if (ins->rex & REX_H) { + nasm_error(ERR_NONFATAL, "cannot use high register in AVX instruction"); + return -1; + } + switch (ins->vex_wlp & 060) { + case 000: + case 040: + ins->rex &= ~REX_W; + break; + case 020: + ins->rex |= REX_W; + bad32 &= ~REX_W; + break; + case 060: + /* Follow REX_W */ + break; + } + + if (bits != 64 && ((ins->rex & bad32) || ins->vexreg > 7)) { + nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode"); + return -1; + } else if (!(ins->rex & REX_EV) && + ((ins->vexreg > 15) || (ins->evex_p[0] & 0xf0))) { + nasm_error(ERR_NONFATAL, "invalid high-16 register in non-AVX-512"); + return -1; + } + if (ins->rex & REX_EV) + length += 4; + else if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || + ins->prefixes[PPS_VEX] == P_VEX3) + length += 3; + else + length += 2; + } else if (ins->rex & REX_MASK) { + if (ins->rex & REX_H) { + nasm_error(ERR_NONFATAL, "cannot use high register in rex instruction"); + return -1; + } else if (bits == 64) { + length++; + } else if ((ins->rex & REX_L) && + !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) && + iflag_cpu_level_ok(&cpu, IF_X86_64)) { + /* LOCK-as-REX.R */ + assert_no_prefix(ins, PPS_LOCK); + lockcheck = false; /* Already errored, no need for warning */ + length++; + } else { + nasm_error(ERR_NONFATAL, "invalid operands in non-64-bit mode"); + return -1; + } + } + + if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck && + (!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) { + nasm_error(ERR_WARNING | ERR_WARN_LOCK | ERR_PASS2 , + "instruction is not lockable"); + } + + bad_hle_warn(ins, hleok); + + /* + * when BND prefix is set by DEFAULT directive, + * BND prefix is added to every appropriate instruction line + * unless it is overridden by NOBND prefix. + */ + if (globalbnd && + (itemp_has(temp, IF_BND) && !has_prefix(ins, PPS_REP, P_NOBND))) + ins->prefixes[PPS_REP] = P_BND; + + /* + * Add length of legacy prefixes + */ + length += emit_prefix(NULL, bits, ins); + + return length; +} + +static inline void emit_rex(struct out_data *data, insn *ins) +{ + if (data->bits == 64) { + if ((ins->rex & REX_MASK) && + !(ins->rex & (REX_V | REX_EV)) && + !ins->rex_done) { + uint8_t rex = (ins->rex & REX_MASK) | REX_P; + out_rawbyte(data, rex); + ins->rex_done = true; + } + } +} + +static int emit_prefix(struct out_data *data, const int bits, insn *ins) +{ + int bytes = 0; + int j; + + for (j = 0; j < MAXPREFIX; j++) { + uint8_t c = 0; + switch (ins->prefixes[j]) { + case P_WAIT: + c = 0x9B; + break; + case P_LOCK: + c = 0xF0; + break; + case P_REPNE: + case P_REPNZ: + case P_XACQUIRE: + case P_BND: + c = 0xF2; + break; + case P_REPE: + case P_REPZ: + case P_REP: + case P_XRELEASE: + c = 0xF3; + break; + case R_CS: + if (bits == 64) { + nasm_error(ERR_WARNING | ERR_PASS2, + "cs segment base generated, but will be ignored in 64-bit mode"); + } + c = 0x2E; + break; + case R_DS: + if (bits == 64) { + nasm_error(ERR_WARNING | ERR_PASS2, + "ds segment base generated, but will be ignored in 64-bit mode"); + } + c = 0x3E; + break; + case R_ES: + if (bits == 64) { + nasm_error(ERR_WARNING | ERR_PASS2, + "es segment base generated, but will be ignored in 64-bit mode"); + } + c = 0x26; + break; + case R_FS: + c = 0x64; + break; + case R_GS: + c = 0x65; + break; + case R_SS: + if (bits == 64) { + nasm_error(ERR_WARNING | ERR_PASS2, + "ss segment base generated, but will be ignored in 64-bit mode"); + } + c = 0x36; + break; + case R_SEGR6: + case R_SEGR7: + nasm_error(ERR_NONFATAL, + "segr6 and segr7 cannot be used as prefixes"); + break; + case P_A16: + if (bits == 64) { + nasm_error(ERR_NONFATAL, + "16-bit addressing is not supported " + "in 64-bit mode"); + } else if (bits != 16) + c = 0x67; + break; + case P_A32: + if (bits != 32) + c = 0x67; + break; + case P_A64: + if (bits != 64) { + nasm_error(ERR_NONFATAL, + "64-bit addressing is only supported " + "in 64-bit mode"); + } + break; + case P_ASP: + c = 0x67; + break; + case P_O16: + if (bits != 16) + c = 0x66; + break; + case P_O32: + if (bits == 16) + c = 0x66; + break; + case P_O64: + /* REX.W */ + break; + case P_OSP: + c = 0x66; + break; + case P_EVEX: + case P_VEX3: + case P_VEX2: + case P_NOBND: + case P_none: + break; + default: + nasm_panic(0, "invalid instruction prefix"); + } + if (c) { + if (data) + out_rawbyte(data, c); + bytes++; + } + } + return bytes; +} + +static void gencode(struct out_data *data, insn *ins) +{ + uint8_t c; + uint8_t bytes[4]; + int64_t size; + int op1, op2; + struct operand *opx; + const uint8_t *codes = data->itemp->code; + uint8_t opex = 0; + enum ea_type eat = EA_SCALAR; + int r; + const int bits = data->bits; + const char *errmsg; + + ins->rex_done = false; + + emit_prefix(data, bits, ins); + + while (*codes) { + c = *codes++; + op1 = (c & 3) + ((opex & 1) << 2); + op2 = ((c >> 3) & 3) + ((opex & 2) << 1); + opx = &ins->oprs[op1]; + opex = 0; /* For the next iteration */ + + + switch (c) { + case 01: + case 02: + case 03: + case 04: + emit_rex(data, ins); + out_rawdata(data, codes, c); + codes += c; + break; + + case 05: + case 06: + case 07: + opex = c; + break; + + case4(010): + emit_rex(data, ins); + out_rawbyte(data, *codes++ + (regval(opx) & 7)); + break; + + case4(014): + break; + + case4(020): + out_imm(data, opx, 1, OUT_WRAP); + break; + + case4(024): + out_imm(data, opx, 1, OUT_UNSIGNED); + break; + + case4(030): + out_imm(data, opx, 2, OUT_WRAP); + break; + + case4(034): + if (opx->type & (BITS16 | BITS32)) + size = (opx->type & BITS16) ? 2 : 4; + else + size = (bits == 16) ? 2 : 4; + out_imm(data, opx, size, OUT_WRAP); + break; + + case4(040): + out_imm(data, opx, 4, OUT_WRAP); + break; + + case4(044): + size = ins->addr_size >> 3; + out_imm(data, opx, size, OUT_WRAP); + break; + + case4(050): + if (opx->segment == data->segment) { + int64_t delta = opx->offset - data->offset + - (data->inslen - data->insoffs); + if (delta > 127 || delta < -128) + nasm_error(ERR_NONFATAL, "short jump is out of range"); + } + out_reladdr(data, opx, 1); + break; + + case4(054): + out_imm(data, opx, 8, OUT_WRAP); + break; + + case4(060): + out_reladdr(data, opx, 2); + break; + + case4(064): + if (opx->type & (BITS16 | BITS32 | BITS64)) + size = (opx->type & BITS16) ? 2 : 4; + else + size = (bits == 16) ? 2 : 4; + + out_reladdr(data, opx, size); + break; + + case4(070): + out_reladdr(data, opx, 4); + break; + + case4(074): + if (opx->segment == NO_SEG) + nasm_error(ERR_NONFATAL, "value referenced by FAR is not" + " relocatable"); + out_segment(data, opx); + break; + + case 0172: + { + int mask = ins->prefixes[PPS_VEX] == P_EVEX ? 7 : 15; + const struct operand *opy; + + c = *codes++; + opx = &ins->oprs[c >> 3]; + opy = &ins->oprs[c & 7]; + if (!absolute_op(opy)) { + nasm_error(ERR_NONFATAL, + "non-absolute expression not permitted as argument %d", + c & 7); + } else if (opy->offset & ~mask) { + nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, + "is4 argument exceeds bounds"); + } + c = opy->offset & mask; + goto emit_is4; + } + + case 0173: + c = *codes++; + opx = &ins->oprs[c >> 4]; + c &= 15; + goto emit_is4; + + case4(0174): + c = 0; + emit_is4: + r = nasm_regvals[opx->basereg]; + out_rawbyte(data, (r << 4) | ((r & 0x10) >> 1) | c); + break; + + case4(0254): + if (absolute_op(opx) && + (int32_t)opx->offset != (int64_t)opx->offset) { + nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, + "signed dword immediate exceeds bounds"); + } + out_imm(data, opx, 4, OUT_SIGNED); + break; + + case4(0240): + case 0250: + codes += 3; + ins->evex_p[2] |= op_evexflags(&ins->oprs[0], + EVEX_P2Z | EVEX_P2AAA, 2); + ins->evex_p[2] ^= EVEX_P2VP; /* 1's complement */ + bytes[0] = 0x62; + /* EVEX.X can be set by either REX or EVEX for different reasons */ + bytes[1] = ((((ins->rex & 7) << 5) | + (ins->evex_p[0] & (EVEX_P0X | EVEX_P0RP))) ^ 0xf0) | + (ins->vex_cm & EVEX_P0MM); + bytes[2] = ((ins->rex & REX_W) << (7 - 3)) | + ((~ins->vexreg & 15) << 3) | + (1 << 2) | (ins->vex_wlp & 3); + bytes[3] = ins->evex_p[2]; + out_rawdata(data, bytes, 4); + break; + + case4(0260): + case 0270: + codes += 2; + if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || + ins->prefixes[PPS_VEX] == P_VEX3) { + bytes[0] = (ins->vex_cm >> 6) ? 0x8f : 0xc4; + bytes[1] = (ins->vex_cm & 31) | ((~ins->rex & 7) << 5); + bytes[2] = ((ins->rex & REX_W) << (7-3)) | + ((~ins->vexreg & 15)<< 3) | (ins->vex_wlp & 07); + out_rawdata(data, bytes, 3); + } else { + bytes[0] = 0xc5; + bytes[1] = ((~ins->rex & REX_R) << (7-2)) | + ((~ins->vexreg & 15) << 3) | (ins->vex_wlp & 07); + out_rawdata(data, bytes, 2); + } + break; + + case 0271: + case 0272: + case 0273: + break; + + case4(0274): + { + uint64_t uv, um; + int s; + + if (absolute_op(opx)) { + if (ins->rex & REX_W) + s = 64; + else if (ins->prefixes[PPS_OSIZE] == P_O16) + s = 16; + else if (ins->prefixes[PPS_OSIZE] == P_O32) + s = 32; + else + s = bits; + + um = (uint64_t)2 << (s-1); + uv = opx->offset; + + if (uv > 127 && uv < (uint64_t)-128 && + (uv < um-128 || uv > um-1)) { + /* If this wasn't explicitly byte-sized, warn as though we + * had fallen through to the imm16/32/64 case. + */ + nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, + "%s value exceeds bounds", + (opx->type & BITS8) ? "signed byte" : + s == 16 ? "word" : + s == 32 ? "dword" : + "signed dword"); + } + + /* Output as a raw byte to avoid byte overflow check */ + out_rawbyte(data, (uint8_t)uv); + } else { + out_imm(data, opx, 1, OUT_WRAP); /* XXX: OUT_SIGNED? */ + } + break; + } + + case4(0300): + break; + + case 0310: + if (bits == 32 && !has_prefix(ins, PPS_ASIZE, P_A16)) + out_rawbyte(data, 0x67); + break; + + case 0311: + if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) + out_rawbyte(data, 0x67); + break; + + case 0312: + break; + + case 0313: + ins->rex = 0; + break; + + case4(0314): + break; + + case 0320: + case 0321: + break; + + case 0322: + case 0323: + break; + + case 0324: + ins->rex |= REX_W; + break; + + case 0325: + break; + + case 0326: + break; + + case 0330: + out_rawbyte(data, *codes++ ^ get_cond_opcode(ins->condition)); + break; + + case 0331: + break; + + case 0332: + case 0333: + out_rawbyte(data, c - 0332 + 0xF2); + break; + + case 0334: + if (ins->rex & REX_R) + out_rawbyte(data, 0xF0); + ins->rex &= ~(REX_L|REX_R); + break; + + case 0335: + break; + + case 0336: + case 0337: + break; + + case 0340: + if (ins->oprs[0].segment != NO_SEG) + nasm_panic(0, "non-constant BSS size in pass two"); + + out_reserve(data, ins->oprs[0].offset); + break; + + case 0341: + break; + + case 0360: + break; + + case 0361: + out_rawbyte(data, 0x66); + break; + + case 0364: + case 0365: + break; + + case 0366: + case 0367: + out_rawbyte(data, c - 0366 + 0x66); + break; + + case3(0370): + break; + + case 0373: + out_rawbyte(data, bits == 16 ? 3 : 5); + break; + + case 0374: + eat = EA_XMMVSIB; + break; + + case 0375: + eat = EA_YMMVSIB; + break; + + case 0376: + eat = EA_ZMMVSIB; + break; + + case4(0100): + case4(0110): + case4(0120): + case4(0130): + case4(0200): + case4(0204): + case4(0210): + case4(0214): + case4(0220): + case4(0224): + case4(0230): + case4(0234): + { + ea ea_data; + int rfield; + opflags_t rflags; + uint8_t *p; + struct operand *opy = &ins->oprs[op2]; + + if (c <= 0177) { + /* pick rfield from operand b (opx) */ + rflags = regflag(opx); + rfield = nasm_regvals[opx->basereg]; + } else { + /* rfield is constant */ + rflags = 0; + rfield = c & 7; + } + + if (process_ea(opy, &ea_data, bits, + rfield, rflags, ins, &errmsg) != eat) + nasm_error(ERR_NONFATAL, "%s", errmsg); + + p = bytes; + *p++ = ea_data.modrm; + if (ea_data.sib_present) + *p++ = ea_data.sib; + out_rawdata(data, bytes, p - bytes); + + /* + * Make sure the address gets the right offset in case + * the line breaks in the .lst file (BR 1197827) + */ + + if (ea_data.bytes) { + /* use compressed displacement, if available */ + if (ea_data.disp8) { + out_rawbyte(data, ea_data.disp8); + } else if (ea_data.rip) { + out_reladdr(data, opy, ea_data.bytes); + } else { + int asize = ins->addr_size >> 3; + + if (overflow_general(opy->offset, asize) || + signed_bits(opy->offset, ins->addr_size) != + signed_bits(opy->offset, ea_data.bytes << 3)) + warn_overflow(ea_data.bytes); + + out_imm(data, opy, ea_data.bytes, + (asize > ea_data.bytes) + ? OUT_SIGNED : OUT_WRAP); + } + } + } + break; + + default: + nasm_panic(0, "internal instruction table corrupt" + ": instruction code \\%o (0x%02X) given", c, c); + break; + } + } +} + +static opflags_t regflag(const operand * o) +{ + if (!is_register(o->basereg)) + nasm_panic(0, "invalid operand passed to regflag()"); + return nasm_reg_flags[o->basereg]; +} + +static int32_t regval(const operand * o) +{ + if (!is_register(o->basereg)) + nasm_panic(0, "invalid operand passed to regval()"); + return nasm_regvals[o->basereg]; +} + +static int op_rexflags(const operand * o, int mask) +{ + opflags_t flags; + int val; + + if (!is_register(o->basereg)) + nasm_panic(0, "invalid operand passed to op_rexflags()"); + + flags = nasm_reg_flags[o->basereg]; + val = nasm_regvals[o->basereg]; + + return rexflags(val, flags, mask); +} + +static int rexflags(int val, opflags_t flags, int mask) +{ + int rex = 0; + + if (val >= 0 && (val & 8)) + rex |= REX_B|REX_X|REX_R; + if (flags & BITS64) + rex |= REX_W; + if (!(REG_HIGH & ~flags)) /* AH, CH, DH, BH */ + rex |= REX_H; + else if (!(REG8 & ~flags) && val >= 4) /* SPL, BPL, SIL, DIL */ + rex |= REX_P; + + return rex & mask; +} + +static int evexflags(int val, decoflags_t deco, + int mask, uint8_t byte) +{ + int evex = 0; + + switch (byte) { + case 0: + if (val >= 0 && (val & 16)) + evex |= (EVEX_P0RP | EVEX_P0X); + break; + case 2: + if (val >= 0 && (val & 16)) + evex |= EVEX_P2VP; + if (deco & Z) + evex |= EVEX_P2Z; + if (deco & OPMASK_MASK) + evex |= deco & EVEX_P2AAA; + break; + } + return evex & mask; +} + +static int op_evexflags(const operand * o, int mask, uint8_t byte) +{ + int val; + + val = nasm_regvals[o->basereg]; + + return evexflags(val, o->decoflags, mask, byte); +} + +static enum match_result find_match(const struct itemplate **tempp, + insn *instruction, + int32_t segment, int64_t offset, int bits) +{ + const struct itemplate *temp; + enum match_result m, merr; + opflags_t xsizeflags[MAX_OPERANDS]; + bool opsizemissing = false; + int8_t broadcast = instruction->evex_brerop; + int i; + + /* broadcasting uses a different data element size */ + for (i = 0; i < instruction->operands; i++) + if (i == broadcast) + xsizeflags[i] = instruction->oprs[i].decoflags & BRSIZE_MASK; + else + xsizeflags[i] = instruction->oprs[i].type & SIZE_MASK; + + merr = MERR_INVALOP; + + for (temp = nasm_instructions[instruction->opcode]; + temp->opcode != I_none; temp++) { + m = matches(temp, instruction, bits); + if (m == MOK_JUMP) { + if (jmp_match(segment, offset, bits, instruction, temp)) + m = MOK_GOOD; + else + m = MERR_INVALOP; + } else if (m == MERR_OPSIZEMISSING && !itemp_has(temp, IF_SX)) { + /* + * Missing operand size and a candidate for fuzzy matching... + */ + for (i = 0; i < temp->operands; i++) + if (i == broadcast) + xsizeflags[i] |= temp->deco[i] & BRSIZE_MASK; + else + xsizeflags[i] |= temp->opd[i] & SIZE_MASK; + opsizemissing = true; + } + if (m > merr) + merr = m; + if (merr == MOK_GOOD) + goto done; + } + + /* No match, but see if we can get a fuzzy operand size match... */ + if (!opsizemissing) + goto done; + + for (i = 0; i < instruction->operands; i++) { + /* + * We ignore extrinsic operand sizes on registers, so we should + * never try to fuzzy-match on them. This also resolves the case + * when we have e.g. "xmmrm128" in two different positions. + */ + if (is_class(REGISTER, instruction->oprs[i].type)) + continue; + + /* This tests if xsizeflags[i] has more than one bit set */ + if ((xsizeflags[i] & (xsizeflags[i]-1))) + goto done; /* No luck */ + + if (i == broadcast) { + instruction->oprs[i].decoflags |= xsizeflags[i]; + instruction->oprs[i].type |= (xsizeflags[i] == BR_BITS32 ? + BITS32 : BITS64); + } else { + instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */ + } + } + + /* Try matching again... */ + for (temp = nasm_instructions[instruction->opcode]; + temp->opcode != I_none; temp++) { + m = matches(temp, instruction, bits); + if (m == MOK_JUMP) { + if (jmp_match(segment, offset, bits, instruction, temp)) + m = MOK_GOOD; + else + m = MERR_INVALOP; + } + if (m > merr) + merr = m; + if (merr == MOK_GOOD) + goto done; + } + +done: + *tempp = temp; + return merr; +} + +static uint8_t get_broadcast_num(opflags_t opflags, opflags_t brsize) +{ + unsigned int opsize = (opflags & SIZE_MASK) >> SIZE_SHIFT; + uint8_t brcast_num; + + if (brsize > BITS64) + nasm_error(ERR_FATAL, + "size of broadcasting element is greater than 64 bits"); + + /* + * The shift term is to take care of the extra BITS80 inserted + * between BITS64 and BITS128. + */ + brcast_num = ((opsize / (BITS64 >> SIZE_SHIFT)) * (BITS64 / brsize)) + >> (opsize > (BITS64 >> SIZE_SHIFT)); + + return brcast_num; +} + +static enum match_result matches(const struct itemplate *itemp, + insn *instruction, int bits) +{ + opflags_t size[MAX_OPERANDS], asize; + bool opsizemissing = false; + int i, oprs; + + /* + * Check the opcode + */ + if (itemp->opcode != instruction->opcode) + return MERR_INVALOP; + + /* + * Count the operands + */ + if (itemp->operands != instruction->operands) + return MERR_INVALOP; + + /* + * Is it legal? + */ + if (!(optimizing.level > 0) && itemp_has(itemp, IF_OPT)) + return MERR_INVALOP; + + /* + * {evex} available? + */ + switch (instruction->prefixes[PPS_VEX]) { + case P_EVEX: + if (!itemp_has(itemp, IF_EVEX)) + return MERR_ENCMISMATCH; + break; + case P_VEX3: + case P_VEX2: + if (!itemp_has(itemp, IF_VEX)) + return MERR_ENCMISMATCH; + break; + default: + break; + } + + /* + * Check that no spurious colons or TOs are present + */ + for (i = 0; i < itemp->operands; i++) + if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO)) + return MERR_INVALOP; + + /* + * Process size flags + */ + switch (itemp_smask(itemp)) { + case IF_GENBIT(IF_SB): + asize = BITS8; + break; + case IF_GENBIT(IF_SW): + asize = BITS16; + break; + case IF_GENBIT(IF_SD): + asize = BITS32; + break; + case IF_GENBIT(IF_SQ): + asize = BITS64; + break; + case IF_GENBIT(IF_SO): + asize = BITS128; + break; + case IF_GENBIT(IF_SY): + asize = BITS256; + break; + case IF_GENBIT(IF_SZ): + asize = BITS512; + break; + case IF_GENBIT(IF_SIZE): + switch (bits) { + case 16: + asize = BITS16; + break; + case 32: + asize = BITS32; + break; + case 64: + asize = BITS64; + break; + default: + asize = 0; + break; + } + break; + default: + asize = 0; + break; + } + + if (itemp_armask(itemp)) { + /* S- flags only apply to a specific operand */ + i = itemp_arg(itemp); + memset(size, 0, sizeof size); + size[i] = asize; + } else { + /* S- flags apply to all operands */ + for (i = 0; i < MAX_OPERANDS; i++) + size[i] = asize; + } + + /* + * Check that the operand flags all match up, + * it's a bit tricky so lets be verbose: + * + * 1) Find out the size of operand. If instruction + * doesn't have one specified -- we're trying to + * guess it either from template (IF_S* flag) or + * from code bits. + * + * 2) If template operand do not match the instruction OR + * template has an operand size specified AND this size differ + * from which instruction has (perhaps we got it from code bits) + * we are: + * a) Check that only size of instruction and operand is differ + * other characteristics do match + * b) Perhaps it's a register specified in instruction so + * for such a case we just mark that operand as "size + * missing" and this will turn on fuzzy operand size + * logic facility (handled by a caller) + */ + for (i = 0; i < itemp->operands; i++) { + opflags_t type = instruction->oprs[i].type; + decoflags_t deco = instruction->oprs[i].decoflags; + decoflags_t ideco = itemp->deco[i]; + bool is_broadcast = deco & BRDCAST_MASK; + uint8_t brcast_num = 0; + opflags_t template_opsize, insn_opsize; + + if (!(type & SIZE_MASK)) + type |= size[i]; + + insn_opsize = type & SIZE_MASK; + if (!is_broadcast) { + template_opsize = itemp->opd[i] & SIZE_MASK; + } else { + decoflags_t deco_brsize = ideco & BRSIZE_MASK; + + if (~ideco & BRDCAST_MASK) + return MERR_BRNOTHERE; + + /* + * when broadcasting, the element size depends on + * the instruction type. decorator flag should match. + */ + if (deco_brsize) { + template_opsize = (deco_brsize == BR_BITS32 ? BITS32 : BITS64); + /* calculate the proper number : {1to} */ + brcast_num = get_broadcast_num(itemp->opd[i], template_opsize); + } else { + template_opsize = 0; + } + } + + if (~ideco & deco & OPMASK_MASK) + return MERR_MASKNOTHERE; + + if (~ideco & deco & (Z_MASK|STATICRND_MASK|SAE_MASK)) + return MERR_DECONOTHERE; + + if (itemp->opd[i] & ~type & ~(SIZE_MASK|REGSET_MASK)) + return MERR_INVALOP; + + if (~itemp->opd[i] & type & REGSET_MASK) + return (itemp->opd[i] & REGSET_MASK) + ? MERR_REGSETSIZE : MERR_REGSET; + + if (template_opsize) { + if (template_opsize != insn_opsize) { + if (insn_opsize) { + return MERR_INVALOP; + } else if (!is_class(REGISTER, type)) { + /* + * Note: we don't honor extrinsic operand sizes for registers, + * so "missing operand size" for a register should be + * considered a wildcard match rather than an error. + */ + opsizemissing = true; + } + } else if (is_broadcast && + (brcast_num != + (2U << ((deco & BRNUM_MASK) >> BRNUM_SHIFT)))) { + /* + * broadcasting opsize matches but the number of repeated memory + * element does not match. + * if 64b double precision float is broadcasted to ymm (256b), + * broadcasting decorator must be {1to4}. + */ + return MERR_BRNUMMISMATCH; + } + } + } + + if (opsizemissing) + return MERR_OPSIZEMISSING; + + /* + * Check operand sizes + */ + if (itemp_has(itemp, IF_SM) || itemp_has(itemp, IF_SM2)) { + oprs = (itemp_has(itemp, IF_SM2) ? 2 : itemp->operands); + for (i = 0; i < oprs; i++) { + asize = itemp->opd[i] & SIZE_MASK; + if (asize) { + for (i = 0; i < oprs; i++) + size[i] = asize; + break; + } + } + } else { + oprs = itemp->operands; + } + + for (i = 0; i < itemp->operands; i++) { + if (!(itemp->opd[i] & SIZE_MASK) && + (instruction->oprs[i].type & SIZE_MASK & ~size[i])) + return MERR_OPSIZEMISMATCH; + } + + /* + * Check template is okay at the set cpu level + */ + if (iflag_cmp_cpu_level(&insns_flags[itemp->iflag_idx], &cpu) > 0) + return MERR_BADCPU; + + /* + * Verify the appropriate long mode flag. + */ + if (itemp_has(itemp, (bits == 64 ? IF_NOLONG : IF_LONG))) + return MERR_BADMODE; + + /* + * If we have a HLE prefix, look for the NOHLE flag + */ + if (itemp_has(itemp, IF_NOHLE) && + (has_prefix(instruction, PPS_REP, P_XACQUIRE) || + has_prefix(instruction, PPS_REP, P_XRELEASE))) + return MERR_BADHLE; + + /* + * Check if special handling needed for Jumps + */ + if ((itemp->code[0] & ~1) == 0370) + return MOK_JUMP; + + /* + * Check if BND prefix is allowed. + * Other 0xF2 (REPNE/REPNZ) prefix is prohibited. + */ + if (!itemp_has(itemp, IF_BND) && + (has_prefix(instruction, PPS_REP, P_BND) || + has_prefix(instruction, PPS_REP, P_NOBND))) + return MERR_BADBND; + else if (itemp_has(itemp, IF_BND) && + (has_prefix(instruction, PPS_REP, P_REPNE) || + has_prefix(instruction, PPS_REP, P_REPNZ))) + return MERR_BADREPNE; + + return MOK_GOOD; +} + +/* + * Check if ModR/M.mod should/can be 01. + * - EAF_BYTEOFFS is set + * - offset can fit in a byte when EVEX is not used + * - offset can be compressed when EVEX is used + */ +#define IS_MOD_01() (!(input->eaflags & EAF_WORDOFFS) && \ + (ins->rex & REX_EV ? seg == NO_SEG && !forw_ref && \ + is_disp8n(input, ins, &output->disp8) : \ + input->eaflags & EAF_BYTEOFFS || (o >= -128 && \ + o <= 127 && seg == NO_SEG && !forw_ref))) + +static enum ea_type process_ea(operand *input, ea *output, int bits, + int rfield, opflags_t rflags, insn *ins, + const char **errmsg) +{ + bool forw_ref = !!(input->opflags & OPFLAG_UNKNOWN); + int addrbits = ins->addr_size; + int eaflags = input->eaflags; + + *errmsg = "invalid effective address"; /* Default error message */ + + output->type = EA_SCALAR; + output->rip = false; + output->disp8 = 0; + + /* REX flags for the rfield operand */ + output->rex |= rexflags(rfield, rflags, REX_R | REX_P | REX_W | REX_H); + /* EVEX.R' flag for the REG operand */ + ins->evex_p[0] |= evexflags(rfield, 0, EVEX_P0RP, 0); + + if (is_class(REGISTER, input->type)) { + /* + * It's a direct register. + */ + if (!is_register(input->basereg)) + goto err; + + if (!is_reg_class(REG_EA, input->basereg)) + goto err; + + /* broadcasting is not available with a direct register operand. */ + if (input->decoflags & BRDCAST_MASK) { + *errmsg = "broadcast not allowed with register operand"; + goto err; + } + + output->rex |= op_rexflags(input, REX_B | REX_P | REX_W | REX_H); + ins->evex_p[0] |= op_evexflags(input, EVEX_P0X, 0); + output->sib_present = false; /* no SIB necessary */ + output->bytes = 0; /* no offset necessary either */ + output->modrm = GEN_MODRM(3, rfield, nasm_regvals[input->basereg]); + } else { + /* + * It's a memory reference. + */ + + /* Embedded rounding or SAE is not available with a mem ref operand. */ + if (input->decoflags & (ER | SAE)) { + *errmsg = "embedded rounding is available only with " + "register-register operations"; + goto err; + } + + if (input->basereg == -1 && + (input->indexreg == -1 || input->scale == 0)) { + /* + * It's a pure offset. + */ + if (bits == 64 && ((input->type & IP_REL) == IP_REL)) { + if (input->segment == NO_SEG || + (input->opflags & OPFLAG_RELATIVE)) { + nasm_error(ERR_WARNING | ERR_PASS2, + "absolute address can not be RIP-relative"); + input->type &= ~IP_REL; + input->type |= MEMORY; + } + } + + if (bits == 64 && + !(IP_REL & ~input->type) && (eaflags & EAF_MIB)) { + *errmsg = "RIP-relative addressing is prohibited for MIB"; + goto err; + } + + if (eaflags & EAF_BYTEOFFS || + (eaflags & EAF_WORDOFFS && + input->disp_size != (addrbits != 16 ? 32 : 16))) { + nasm_error(ERR_WARNING | ERR_PASS1, + "displacement size ignored on absolute address"); + } + + if (bits == 64 && (~input->type & IP_REL)) { + output->sib_present = true; + output->sib = GEN_SIB(0, 4, 5); + output->bytes = 4; + output->modrm = GEN_MODRM(0, rfield, 4); + output->rip = false; + } else { + output->sib_present = false; + output->bytes = (addrbits != 16 ? 4 : 2); + output->modrm = GEN_MODRM(0, rfield, + (addrbits != 16 ? 5 : 6)); + output->rip = bits == 64; + } + } else { + /* + * It's an indirection. + */ + int i = input->indexreg, b = input->basereg, s = input->scale; + int32_t seg = input->segment; + int hb = input->hintbase, ht = input->hinttype; + int t, it, bt; /* register numbers */ + opflags_t x, ix, bx; /* register flags */ + + if (s == 0) + i = -1; /* make this easy, at least */ + + if (is_register(i)) { + it = nasm_regvals[i]; + ix = nasm_reg_flags[i]; + } else { + it = -1; + ix = 0; + } + + if (is_register(b)) { + bt = nasm_regvals[b]; + bx = nasm_reg_flags[b]; + } else { + bt = -1; + bx = 0; + } + + /* if either one are a vector register... */ + if ((ix|bx) & (XMMREG|YMMREG|ZMMREG) & ~REG_EA) { + opflags_t sok = BITS32 | BITS64; + int32_t o = input->offset; + int mod, scale, index, base; + + /* + * For a vector SIB, one has to be a vector and the other, + * if present, a GPR. The vector must be the index operand. + */ + if (it == -1 || (bx & (XMMREG|YMMREG|ZMMREG) & ~REG_EA)) { + if (s == 0) + s = 1; + else if (s != 1) + goto err; + + t = bt, bt = it, it = t; + x = bx, bx = ix, ix = x; + } + + if (bt != -1) { + if (REG_GPR & ~bx) + goto err; + if (!(REG64 & ~bx) || !(REG32 & ~bx)) + sok &= bx; + else + goto err; + } + + /* + * While we're here, ensure the user didn't specify + * WORD or QWORD + */ + if (input->disp_size == 16 || input->disp_size == 64) + goto err; + + if (addrbits == 16 || + (addrbits == 32 && !(sok & BITS32)) || + (addrbits == 64 && !(sok & BITS64))) + goto err; + + output->type = ((ix & ZMMREG & ~REG_EA) ? EA_ZMMVSIB + : ((ix & YMMREG & ~REG_EA) + ? EA_YMMVSIB : EA_XMMVSIB)); + + output->rex |= rexflags(it, ix, REX_X); + output->rex |= rexflags(bt, bx, REX_B); + ins->evex_p[2] |= evexflags(it, 0, EVEX_P2VP, 2); + + index = it & 7; /* it is known to be != -1 */ + + switch (s) { + case 1: + scale = 0; + break; + case 2: + scale = 1; + break; + case 4: + scale = 2; + break; + case 8: + scale = 3; + break; + default: /* then what the smeg is it? */ + goto err; /* panic */ + } + + if (bt == -1) { + base = 5; + mod = 0; + } else { + base = (bt & 7); + if (base != REG_NUM_EBP && o == 0 && + seg == NO_SEG && !forw_ref && + !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (IS_MOD_01()) + mod = 1; + else + mod = 2; + } + + output->sib_present = true; + output->bytes = (bt == -1 || mod == 2 ? 4 : mod); + output->modrm = GEN_MODRM(mod, rfield, 4); + output->sib = GEN_SIB(scale, index, base); + } else if ((ix|bx) & (BITS32|BITS64)) { + /* + * it must be a 32/64-bit memory reference. Firstly we have + * to check that all registers involved are type E/Rxx. + */ + opflags_t sok = BITS32 | BITS64; + int32_t o = input->offset; + + if (it != -1) { + if (!(REG64 & ~ix) || !(REG32 & ~ix)) + sok &= ix; + else + goto err; + } + + if (bt != -1) { + if (REG_GPR & ~bx) + goto err; /* Invalid register */ + if (~sok & bx & SIZE_MASK) + goto err; /* Invalid size */ + sok &= bx; + } + + /* + * While we're here, ensure the user didn't specify + * WORD or QWORD + */ + if (input->disp_size == 16 || input->disp_size == 64) + goto err; + + if (addrbits == 16 || + (addrbits == 32 && !(sok & BITS32)) || + (addrbits == 64 && !(sok & BITS64))) + goto err; + + /* now reorganize base/index */ + if (s == 1 && bt != it && bt != -1 && it != -1 && + ((hb == b && ht == EAH_NOTBASE) || + (hb == i && ht == EAH_MAKEBASE))) { + /* swap if hints say so */ + t = bt, bt = it, it = t; + x = bx, bx = ix, ix = x; + } + + if (bt == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE)) { + /* make single reg base, unless hint */ + bt = it, bx = ix, it = -1, ix = 0; + } + if (eaflags & EAF_MIB) { + /* only for mib operands */ + if (it == -1 && (hb == b && ht == EAH_NOTBASE)) { + /* + * make a single reg index [reg*1]. + * gas uses this form for an explicit index register. + */ + it = bt, ix = bx, bt = -1, bx = 0, s = 1; + } + if ((ht == EAH_SUMMED) && bt == -1) { + /* separate once summed index into [base, index] */ + bt = it, bx = ix, s--; + } + } else { + if (((s == 2 && it != REG_NUM_ESP && + (!(eaflags & EAF_TIMESTWO) || (ht == EAH_SUMMED))) || + s == 3 || s == 5 || s == 9) && bt == -1) { + /* convert 3*EAX to EAX+2*EAX */ + bt = it, bx = ix, s--; + } + if (it == -1 && (bt & 7) != REG_NUM_ESP && + (eaflags & EAF_TIMESTWO) && + (hb == b && ht == EAH_NOTBASE)) { + /* + * convert [NOSPLIT EAX*1] + * to sib format with 0x0 displacement - [EAX*1+0]. + */ + it = bt, ix = bx, bt = -1, bx = 0, s = 1; + } + } + if (s == 1 && it == REG_NUM_ESP) { + /* swap ESP into base if scale is 1 */ + t = it, it = bt, bt = t; + x = ix, ix = bx, bx = x; + } + if (it == REG_NUM_ESP || + (s != 1 && s != 2 && s != 4 && s != 8 && it != -1)) + goto err; /* wrong, for various reasons */ + + output->rex |= rexflags(it, ix, REX_X); + output->rex |= rexflags(bt, bx, REX_B); + + if (it == -1 && (bt & 7) != REG_NUM_ESP) { + /* no SIB needed */ + int mod, rm; + + if (bt == -1) { + rm = 5; + mod = 0; + } else { + rm = (bt & 7); + if (rm != REG_NUM_EBP && o == 0 && + seg == NO_SEG && !forw_ref && + !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (IS_MOD_01()) + mod = 1; + else + mod = 2; + } + + output->sib_present = false; + output->bytes = (bt == -1 || mod == 2 ? 4 : mod); + output->modrm = GEN_MODRM(mod, rfield, rm); + } else { + /* we need a SIB */ + int mod, scale, index, base; + + if (it == -1) + index = 4, s = 1; + else + index = (it & 7); + + switch (s) { + case 1: + scale = 0; + break; + case 2: + scale = 1; + break; + case 4: + scale = 2; + break; + case 8: + scale = 3; + break; + default: /* then what the smeg is it? */ + goto err; /* panic */ + } + + if (bt == -1) { + base = 5; + mod = 0; + } else { + base = (bt & 7); + if (base != REG_NUM_EBP && o == 0 && + seg == NO_SEG && !forw_ref && + !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (IS_MOD_01()) + mod = 1; + else + mod = 2; + } + + output->sib_present = true; + output->bytes = (bt == -1 || mod == 2 ? 4 : mod); + output->modrm = GEN_MODRM(mod, rfield, 4); + output->sib = GEN_SIB(scale, index, base); + } + } else { /* it's 16-bit */ + int mod, rm; + int16_t o = input->offset; + + /* check for 64-bit long mode */ + if (addrbits == 64) + goto err; + + /* check all registers are BX, BP, SI or DI */ + if ((b != -1 && b != R_BP && b != R_BX && b != R_SI && b != R_DI) || + (i != -1 && i != R_BP && i != R_BX && i != R_SI && i != R_DI)) + goto err; + + /* ensure the user didn't specify DWORD/QWORD */ + if (input->disp_size == 32 || input->disp_size == 64) + goto err; + + if (s != 1 && i != -1) + goto err; /* no can do, in 16-bit EA */ + if (b == -1 && i != -1) { + int tmp = b; + b = i; + i = tmp; + } /* swap */ + if ((b == R_SI || b == R_DI) && i != -1) { + int tmp = b; + b = i; + i = tmp; + } + /* have BX/BP as base, SI/DI index */ + if (b == i) + goto err; /* shouldn't ever happen, in theory */ + if (i != -1 && b != -1 && + (i == R_BP || i == R_BX || b == R_SI || b == R_DI)) + goto err; /* invalid combinations */ + if (b == -1) /* pure offset: handled above */ + goto err; /* so if it gets to here, panic! */ + + rm = -1; + if (i != -1) + switch (i * 256 + b) { + case R_SI * 256 + R_BX: + rm = 0; + break; + case R_DI * 256 + R_BX: + rm = 1; + break; + case R_SI * 256 + R_BP: + rm = 2; + break; + case R_DI * 256 + R_BP: + rm = 3; + break; + } else + switch (b) { + case R_SI: + rm = 4; + break; + case R_DI: + rm = 5; + break; + case R_BP: + rm = 6; + break; + case R_BX: + rm = 7; + break; + } + if (rm == -1) /* can't happen, in theory */ + goto err; /* so panic if it does */ + + if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 && + !(eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS))) + mod = 0; + else if (IS_MOD_01()) + mod = 1; + else + mod = 2; + + output->sib_present = false; /* no SIB - it's 16-bit */ + output->bytes = mod; /* bytes of offset needed */ + output->modrm = GEN_MODRM(mod, rfield, rm); + } + } + } + + output->size = 1 + output->sib_present + output->bytes; + return output->type; + +err: + return output->type = EA_INVALID; +} + +static void add_asp(insn *ins, int addrbits) +{ + int j, valid; + int defdisp; + + valid = (addrbits == 64) ? 64|32 : 32|16; + + switch (ins->prefixes[PPS_ASIZE]) { + case P_A16: + valid &= 16; + break; + case P_A32: + valid &= 32; + break; + case P_A64: + valid &= 64; + break; + case P_ASP: + valid &= (addrbits == 32) ? 16 : 32; + break; + default: + break; + } + + for (j = 0; j < ins->operands; j++) { + if (is_class(MEMORY, ins->oprs[j].type)) { + opflags_t i, b; + + /* Verify as Register */ + if (!is_register(ins->oprs[j].indexreg)) + i = 0; + else + i = nasm_reg_flags[ins->oprs[j].indexreg]; + + /* Verify as Register */ + if (!is_register(ins->oprs[j].basereg)) + b = 0; + else + b = nasm_reg_flags[ins->oprs[j].basereg]; + + if (ins->oprs[j].scale == 0) + i = 0; + + if (!i && !b) { + int ds = ins->oprs[j].disp_size; + if ((addrbits != 64 && ds > 8) || + (addrbits == 64 && ds == 16)) + valid &= ds; + } else { + if (!(REG16 & ~b)) + valid &= 16; + if (!(REG32 & ~b)) + valid &= 32; + if (!(REG64 & ~b)) + valid &= 64; + + if (!(REG16 & ~i)) + valid &= 16; + if (!(REG32 & ~i)) + valid &= 32; + if (!(REG64 & ~i)) + valid &= 64; + } + } + } + + if (valid & addrbits) { + ins->addr_size = addrbits; + } else if (valid & ((addrbits == 32) ? 16 : 32)) { + /* Add an address size prefix */ + ins->prefixes[PPS_ASIZE] = (addrbits == 32) ? P_A16 : P_A32;; + ins->addr_size = (addrbits == 32) ? 16 : 32; + } else { + /* Impossible... */ + nasm_error(ERR_NONFATAL, "impossible combination of address sizes"); + ins->addr_size = addrbits; /* Error recovery */ + } + + defdisp = ins->addr_size == 16 ? 16 : 32; + + for (j = 0; j < ins->operands; j++) { + if (!(MEM_OFFS & ~ins->oprs[j].type) && + (ins->oprs[j].disp_size ? ins->oprs[j].disp_size : defdisp) != ins->addr_size) { + /* + * mem_offs sizes must match the address size; if not, + * strip the MEM_OFFS bit and match only EA instructions + */ + ins->oprs[j].type &= ~(MEM_OFFS & ~MEMORY); + } + } +} diff --git a/asm/assemble.h b/asm/assemble.h new file mode 100644 index 0000000..f47ae03 --- /dev/null +++ b/asm/assemble.h @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 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. + * + * ----------------------------------------------------------------------- */ + +/* + * assemble.h - header file for stuff private to the assembler + */ + +#ifndef NASM_ASSEMBLE_H +#define NASM_ASSEMBLE_H + +#include "nasm.h" +#include "iflag.h" + +extern iflag_t cpu; +extern bool in_absolute; /* Are we in an absolute segment? */ +extern struct location absolute; + +int64_t insn_size(int32_t segment, int64_t offset, int bits, insn *instruction); +int64_t assemble(int32_t segment, int64_t offset, int bits, insn *instruction); + +bool process_directives(char *); +void process_pragma(char *); + +#endif diff --git a/asm/directbl.c b/asm/directbl.c new file mode 100644 index 0000000..cf6caa5 --- /dev/null +++ b/asm/directbl.c @@ -0,0 +1,126 @@ +/* + * This file is generated from ./asm/directiv.dat + * by perfhash.pl; do not edit. + */ + +#include "directiv.h" + +const char * const directive_tbl[38] = { + "absolute", + "bits", + "common", + "cpu", + "debug", + "default", + "extern", + "float", + "global", + "static", + "list", + "section", + "segment", + "warning", + "sectalign", + "pragma", + "export", + "group", + "import", + "library", + "map", + "module", + "org", + "osabi", + "safeseh", + "uppercase", + "prefix", + "suffix", + "gprefix", + "gsuffix", + "lprefix", + "lsuffix", + "limit", + "subsections_via_symbols", + "no_dead_strip", + "maxdump", + "nodepend", + "noseclabels" +}; + +#define UNUSED (65536/3) + +static const int16_t directive_hashvals[64] = { + 0, + UNUSED, + 0, + UNUSED, + 26, + -4, + 0, + 11, + 0, + 8, + UNUSED, + UNUSED, + 0, + -5, + 28, + 15, + UNUSED, + UNUSED, + UNUSED, + -16, + UNUSED, + 2, + 19, + -3, + -22, + 16, + UNUSED, + 6, + 11, + -20, + 16, + -13, + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + 0, + 6, + 0, + 22, + 2, + -28, + 32, + 12, + 23, + 3, + UNUSED, + 26, + UNUSED, + 12, + 29, + 10, + 17, + 28, + 34, + UNUSED, + UNUSED, + 1, + 9, + 27, + UNUSED, + 19, + 14 +}; + +const struct perfect_hash directive_hash = { + UINT64_C(0x076259c3e291c26c), + UINT32_C(0x1f), + UINT32_C(38), + 3, + (D_unknown), + directive_hashvals, + directive_tbl +}; diff --git a/asm/directiv.c b/asm/directiv.c new file mode 100644 index 0000000..89750c8 --- /dev/null +++ b/asm/directiv.c @@ -0,0 +1,515 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * Parse and handle assembler directives + */ + +#include "compiler.h" + +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "ilog2.h" +#include "error.h" +#include "float.h" +#include "stdscan.h" +#include "preproc.h" +#include "eval.h" +#include "assemble.h" +#include "outform.h" +#include "listing.h" +#include "labels.h" +#include "iflag.h" + +struct cpunames { + const char *name; + unsigned int level; + /* Eventually a table of features */ +}; + +static iflag_t get_cpu(const char *value) +{ + iflag_t r; + const struct cpunames *cpu; + static const struct cpunames cpunames[] = { + { "8086", IF_8086 }, + { "186", IF_186 }, + { "286", IF_286 }, + { "386", IF_386 }, + { "486", IF_486 }, + { "586", IF_PENT }, + { "pentium", IF_PENT }, + { "pentiummmx", IF_PENT }, + { "686", IF_P6 }, + { "p6", IF_P6 }, + { "ppro", IF_P6 }, + { "pentiumpro", IF_P6 }, + { "p2", IF_P6 }, /* +MMX */ + { "pentiumii", IF_P6 }, + { "p3", IF_KATMAI }, + { "katmai", IF_KATMAI }, + { "p4", IF_WILLAMETTE }, + { "willamette", IF_WILLAMETTE }, + { "prescott", IF_PRESCOTT }, + { "x64", IF_X86_64 }, + { "x86-64", IF_X86_64 }, + { "ia64", IF_IA64 }, + { "ia-64", IF_IA64 }, + { "itanium", IF_IA64 }, + { "itanic", IF_IA64 }, + { "merced", IF_IA64 }, + { "any", IF_PLEVEL }, + { "default", IF_PLEVEL }, + { "all", IF_PLEVEL }, + { NULL, IF_PLEVEL } /* Error and final default entry */ + }; + + iflag_clear_all(&r); + + for (cpu = cpunames; cpu->name; cpu++) { + if (!nasm_stricmp(value, cpu->name)) + break; + } + + if (!cpu->name) { + nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL, + "unknown 'cpu' type '%s'", value); + } + + iflag_set_cpu(&r, cpu->level); + return r; +} + +static int get_bits(const char *value) +{ + int i = atoi(value); + + switch (i) { + case 16: + break; /* Always safe */ + case 32: + if (!iflag_cpu_level_ok(&cpu, IF_386)) { + nasm_error(ERR_NONFATAL, + "cannot specify 32-bit segment on processor below a 386"); + i = 16; + } + break; + case 64: + if (!iflag_cpu_level_ok(&cpu, IF_X86_64)) { + nasm_error(ERR_NONFATAL, + "cannot specify 64-bit segment on processor below an x86-64"); + i = 16; + } + break; + default: + nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_FATAL, + "`%s' is not a valid segment size; must be 16, 32 or 64", + value); + i = 16; + break; + } + return i; +} + +static enum directive parse_directive_line(char **directive, char **value) +{ + char *p, *q, *buf; + + buf = nasm_skip_spaces(*directive); + + /* + * It should be enclosed in [ ]. + * XXX: we don't check there is nothing else on the remainder of the + * line, except a possible comment. + */ + if (*buf != '[') + return D_none; + q = strchr(buf, ']'); + if (!q) + return D_corrupt; + + /* + * Strip off the comments. XXX: this doesn't account for quoted + * strings inside a directive. We should really strip the + * comments in generic code, not here. While we're at it, it + * would be better to pass the backend a series of tokens instead + * of a raw string, and actually process quoted strings for it, + * like of like argv is handled in C. + */ + p = strchr(buf, ';'); + if (p) { + if (p < q) /* ouch! somewhere inside */ + return D_corrupt; + *p = '\0'; + } + + /* no brace, no trailing spaces */ + *q = '\0'; + nasm_zap_spaces_rev(--q); + + /* directive */ + p = nasm_skip_spaces(++buf); + q = nasm_skip_word(p); + if (!q) + return D_corrupt; /* sigh... no value there */ + *q = '\0'; + *directive = p; + + /* and value finally */ + p = nasm_skip_spaces(++q); + *value = p; + + return directive_find(*directive); +} + +/* + * Process a line from the assembler and try to handle it if it + * is a directive. Return true if the line was handled (including + * if it was an error), false otherwise. + */ +bool process_directives(char *directive) +{ + enum directive d; + char *value, *p, *q, *special; + struct tokenval tokval; + bool bad_param = false; + int pass2 = passn > 1 ? 2 : 1; + enum label_type type; + + d = parse_directive_line(&directive, &value); + + switch (d) { + case D_none: + return D_none; /* Not a directive */ + + case D_corrupt: + nasm_error(ERR_NONFATAL, "invalid directive line"); + break; + + default: /* It's a backend-specific directive */ + switch (ofmt->directive(d, value, pass2)) { + case DIRR_UNKNOWN: + goto unknown; + case DIRR_OK: + case DIRR_ERROR: + break; + case DIRR_BADPARAM: + bad_param = true; + break; + default: + panic(); + } + break; + + case D_unknown: + unknown: + nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, + "unrecognised directive [%s]", directive); + break; + + case D_SEGMENT: /* [SEGMENT n] */ + case D_SECTION: + { + int sb = globalbits; + int32_t seg = ofmt->section(value, pass2, &sb); + + if (seg == NO_SEG) { + nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, + "segment name `%s' not recognized", value); + } else { + globalbits = sb; + switch_segment(seg); + } + break; + } + + case D_SECTALIGN: /* [SECTALIGN n] */ + { + expr *e; + + if (*value) { + stdscan_reset(); + stdscan_set(value); + tokval.t_type = TOKEN_INVALID; + e = evaluate(stdscan, NULL, &tokval, NULL, pass2, NULL); + if (e) { + uint64_t align = e->value; + + if (!is_power2(e->value)) { + nasm_error(ERR_NONFATAL, + "segment alignment `%s' is not power of two", + value); + } else if (align > UINT64_C(0x7fffffff)) { + /* + * FIXME: Please make some sane message here + * ofmt should have some 'check' method which + * would report segment alignment bounds. + */ + nasm_error(ERR_NONFATAL, + "absurdly large segment alignment `%s' (2^%d)", + value, ilog2_64(align)); + } + + /* callee should be able to handle all details */ + if (location.segment != NO_SEG) + ofmt->sectalign(location.segment, align); + } + } + break; + } + + case D_BITS: /* [BITS bits] */ + globalbits = get_bits(value); + break; + + case D_GLOBAL: /* [GLOBAL|STATIC|EXTERN|COMMON symbol:special] */ + type = LBL_GLOBAL; + goto symdef; + case D_STATIC: + type = LBL_STATIC; + goto symdef; + case D_EXTERN: + type = LBL_EXTERN; + goto symdef; + case D_COMMON: + type = LBL_COMMON; + goto symdef; + + symdef: + { + bool validid = true; + int64_t size = 0; + char *sizestr; + bool rn_error; + + if (*value == '$') + value++; /* skip initial $ if present */ + + q = value; + if (!isidstart(*q)) { + validid = false; + } else { + q++; + while (*q && *q != ':' && !nasm_isspace(*q)) { + if (!isidchar(*q)) + validid = false; + q++; + } + } + if (!validid) { + nasm_error(ERR_NONFATAL, + "identifier expected after %s, got `%s'", + directive, value); + break; + } + + if (nasm_isspace(*q)) { + *q++ = '\0'; + sizestr = q = nasm_skip_spaces(q); + q = strchr(q, ':'); + } else { + sizestr = NULL; + } + + if (q && *q == ':') { + *q++ = '\0'; + special = q; + } else { + special = NULL; + } + + if (type == LBL_COMMON) { + if (sizestr) + size = readnum(sizestr, &rn_error); + if (!sizestr || rn_error) + nasm_error(ERR_NONFATAL, + "%s size specified in common declaration", + sizestr ? "invalid" : "no"); + } else if (sizestr) { + nasm_error(ERR_NONFATAL, "invalid syntax in %s declaration", + directive); + } + + if (!declare_label(value, type, special)) + break; + + if (type == LBL_COMMON || type == LBL_EXTERN) + define_label(value, 0, size, false); + + break; + } + + case D_ABSOLUTE: /* [ABSOLUTE address] */ + { + expr *e; + + stdscan_reset(); + stdscan_set(value); + tokval.t_type = TOKEN_INVALID; + e = evaluate(stdscan, NULL, &tokval, NULL, pass2, NULL); + if (e) { + if (!is_reloc(e)) + nasm_error(pass0 == + 1 ? ERR_NONFATAL : ERR_PANIC, + "cannot use non-relocatable expression as " + "ABSOLUTE address"); + else { + absolute.segment = reloc_seg(e); + absolute.offset = reloc_value(e); + } + } else if (passn == 1) + absolute.offset = 0x100; /* don't go near zero in case of / */ + else + nasm_panic(0, "invalid ABSOLUTE address " + "in pass two"); + in_absolute = true; + location.segment = NO_SEG; + location.offset = absolute.offset; + break; + } + + case D_DEBUG: /* [DEBUG] */ + { + bool badid, overlong; + char debugid[128]; + + p = value; + q = debugid; + badid = overlong = false; + if (!isidstart(*p)) { + badid = true; + } else { + while (*p && !nasm_isspace(*p)) { + if (q >= debugid + sizeof debugid - 1) { + overlong = true; + break; + } + if (!isidchar(*p)) + badid = true; + *q++ = *p++; + } + *q = 0; + } + if (badid) { + nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC, + "identifier expected after DEBUG"); + break; + } + if (overlong) { + nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC, + "DEBUG identifier too long"); + break; + } + p = nasm_skip_spaces(p); + if (pass0 == 2) + dfmt->debug_directive(debugid, p); + break; + } + + case D_WARNING: /* [WARNING {+|-|*}warn-name] */ + if (!set_warning_status(value)) { + nasm_error(ERR_WARNING|ERR_WARN_UNK_WARNING, + "unknown warning option: %s", value); + } + break; + + case D_CPU: /* [CPU] */ + cpu = get_cpu(value); + break; + + case D_LIST: /* [LIST {+|-}] */ + value = nasm_skip_spaces(value); + if (*value == '+') { + user_nolist = false; + } else { + if (*value == '-') { + user_nolist = true; + } else { + bad_param = true; + } + } + break; + + case D_DEFAULT: /* [DEFAULT] */ + stdscan_reset(); + stdscan_set(value); + tokval.t_type = TOKEN_INVALID; + if (stdscan(NULL, &tokval) != TOKEN_INVALID) { + switch (tokval.t_integer) { + case S_REL: + globalrel = 1; + break; + case S_ABS: + globalrel = 0; + break; + case P_BND: + globalbnd = 1; + break; + case P_NOBND: + globalbnd = 0; + break; + default: + bad_param = true; + break; + } + } else { + bad_param = true; + } + break; + + case D_FLOAT: + if (float_option(value)) { + nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC, + "unknown 'float' directive: %s", value); + } + break; + + case D_PRAGMA: + process_pragma(value); + break; + } + + + /* A common error message */ + if (bad_param) { + nasm_error(ERR_NONFATAL, "invalid parameter to [%s] directive", + directive); + } + + return d != D_none; +} diff --git a/asm/directiv.dat b/asm/directiv.dat new file mode 100644 index 0000000..185568a --- /dev/null +++ b/asm/directiv.dat @@ -0,0 +1,103 @@ +;; -------------------------------------------------------------------------- +;; +;; Copyright 1996-2017 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. +;; +;; -------------------------------------------------------------------------- +;; +;; List of global NASM directives and pragma operations codes +;; +;; ALL directives, including backend-specific, need to be added here. +;; +;; %pragma operation keywords (the second word, after facility) MAY +;; be added here too to assist in parsing, but it is not required. +;; See the definition of struct pragma in include/nasm.h. +;; +;; The same keyword can be used as a directive and as a pragma +;; operation, or as pragma operations in different namespaces. The +;; same D_ constant will be used for both, and this is perfectly +;; acceptable. +;; + +; --- General configuration +#name directive +#prefix D_ +#errval D_unknown +#header directiv.h + +; --- Special enum values +#special none = 0 ; Must be zero +#special unknown +#special corrupt + +; --- Global directives +absolute +bits +common +cpu +debug +default +extern +float +global +static +list +section +segment +warning +sectalign +pragma + +; --- Format-specific directives +export ; outcoff, outobj +group ; outobj +import ; outobj +library ; outrdf2 +map ; outbin +module ; outrdf2 +org ; outbin +osabi ; outelf +safeseh ; outcoff +uppercase ; outieee, outobj + +; --- Assembler pragmas +prefix +suffix +gprefix +gsuffix +lprefix +lsuffix +limit + +; --- Pragma operations +subsections_via_symbols ; macho +no_dead_strip ; macho +maxdump ; dbg +nodepend ; obj +noseclabels ; dbg diff --git a/asm/directiv.h b/asm/directiv.h new file mode 100644 index 0000000..20a6424 --- /dev/null +++ b/asm/directiv.h @@ -0,0 +1,77 @@ +/* + * This file is generated from ./asm/directiv.dat + * by perfhash.pl; do not edit. + */ + +#ifndef DIRECTIV_H +#define DIRECTIV_H 1 + +#include "perfhash.h" + +enum directive { + D_none, + D_unknown, + D_corrupt, + D_ABSOLUTE, + D_BITS, + D_COMMON, + D_CPU, + D_DEBUG, + D_DEFAULT, + D_EXTERN, + D_FLOAT, + D_GLOBAL, + D_STATIC, + D_LIST, + D_SECTION, + D_SEGMENT, + D_WARNING, + D_SECTALIGN, + D_PRAGMA, + D_EXPORT, + D_GROUP, + D_IMPORT, + D_LIBRARY, + D_MAP, + D_MODULE, + D_ORG, + D_OSABI, + D_SAFESEH, + D_UPPERCASE, + D_PREFIX, + D_SUFFIX, + D_GPREFIX, + D_GSUFFIX, + D_LPREFIX, + D_LSUFFIX, + D_LIMIT, + D_SUBSECTIONS_VIA_SYMBOLS, + D_NO_DEAD_STRIP, + D_MAXDUMP, + D_NODEPEND, + D_NOSECLABELS +}; + +extern const struct perfect_hash directive_hash; +extern const char * const directive_tbl[38]; + +static inline enum directive directive_find(const char *str) +{ + return perfhash_find(&directive_hash, str); +} + +static inline const char * directive_name(enum directive x) +{ + size_t ix = (size_t)x - (3); + if (ix >= 38) + return NULL; + return directive_tbl[ix]; +} + +static inline const char * directive_dname(enum directive x) +{ + const char *y = directive_name(x); + return y ? y : invalid_enum_str(x); +} + +#endif /* DIRECTIV_H */ diff --git a/asm/error.c b/asm/error.c new file mode 100644 index 0000000..73db744 --- /dev/null +++ b/asm/error.c @@ -0,0 +1,204 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * error.c - error message handling routines for the assembler + */ + +#include "compiler.h" + +#include + +#include "nasmlib.h" +#include "error.h" + +/* + * Description of the suppressible warnings for the command line and + * the [warning] directive. + */ +const struct warning warnings[ERR_WARN_ALL+1] = { + {"other", "any warning not specifially mentioned below", true}, + {"macro-params", "macro calls with wrong parameter count", true}, + {"macro-selfref", "cyclic macro references", false}, + {"macro-defaults", "macros with more default than optional parameters", true}, + {"orphan-labels", "labels alone on lines without trailing `:'", true}, + {"number-overflow", "numeric constant does not fit", true}, + {"gnu-elf-extensions", "using 8- or 16-bit relocation in ELF32, a GNU extension", false}, + {"float-overflow", "floating point overflow", true}, + {"float-denorm", "floating point denormal", false}, + {"float-underflow", "floating point underflow", false}, + {"float-toolong", "too many digits in floating-point number", true}, + {"user", "%warning directives", true}, + {"lock", "lock prefix on unlockable instructions", true}, + {"hle", "invalid hle prefixes", true}, + {"bnd", "invalid bnd prefixes", true}, + {"zext-reloc", "relocation zero-extended to match output format", true}, + {"ptr", "non-NASM keyword used in other assemblers", true}, + {"bad-pragma", "empty or malformed %pragma", false}, + {"unknown-pragma", "unknown %pragma facility or directive", false}, + {"not-my-pragma", "%pragma not applicable to this compilation", false}, + {"unknown-warning", "unknown warning in -W/-w or warning directive", false}, + {"negative-rep", "regative %rep count", true}, + {"phase", "phase error during stabilization", false}, + + /* THIS ENTRY MUST COME LAST */ + {"all", "all possible warnings", false} +}; + +uint8_t warning_state[ERR_WARN_ALL];/* Current state */ +uint8_t warning_state_init[ERR_WARN_ALL]; /* Command-line state, for reset */ + +vefunc nasm_verror; /* Global error handling function */ + +void nasm_error(int severity, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + nasm_verror(severity, fmt, ap); + va_end(ap); +} + +fatal_func nasm_fatal(int flags, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + nasm_verror(flags | ERR_FATAL, fmt, ap); + abort(); /* We should never get here */ +} + +fatal_func nasm_panic(int flags, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + nasm_verror(flags | ERR_PANIC, fmt, ap); + abort(); /* We should never get here */ +} + +fatal_func nasm_panic_from_macro(const char *file, int line) +{ + nasm_panic(ERR_NOFILE, "Internal error at %s:%d\n", file, line); +} + +fatal_func nasm_assert_failed(const char *file, int line, const char *msg) +{ + nasm_panic(0, "assertion %s failed at %s:%d", msg, file, line); +} + +/* + * This is called when processing a -w or -W option, or a warning directive. + * Returns true if if the action was successful. + */ +bool set_warning_status(const char *value) +{ + enum warn_action { WID_OFF, WID_ON, WID_RESET }; + enum warn_action action; + uint8_t mask; + int i; + bool ok = false; + + value = nasm_skip_spaces(value); + switch (*value) { + case '-': + action = WID_OFF; + value++; + break; + case '+': + action = WID_ON; + value++; + break; + case '*': + action = WID_RESET; + value++; + break; + case 'N': + case 'n': + if (!nasm_strnicmp(value, "no-", 3)) { + action = WID_OFF; + value += 3; + break; + } else if (!nasm_stricmp(value, "none")) { + action = WID_OFF; + value = NULL; + break; + } + /* else fall through */ + default: + action = WID_ON; + break; + } + + mask = WARN_ST_ENABLED; + + if (value && !nasm_strnicmp(value, "error", 5)) { + switch (value[5]) { + case '=': + mask = WARN_ST_ERROR; + value += 6; + break; + case '\0': + mask = WARN_ST_ERROR; + value = NULL; + break; + default: + /* Just an accidental prefix? */ + break; + } + } + + if (value && !nasm_stricmp(value, "all")) + value = NULL; + + /* This is inefficient, but it shouldn't matter... */ + for (i = 0; i < ERR_WARN_ALL; i++) { + if (!value || !nasm_stricmp(value, warnings[i].name)) { + ok = true; /* At least one action taken */ + switch (action) { + case WID_OFF: + warning_state[i] &= ~mask; + break; + case WID_ON: + warning_state[i] |= mask; + break; + case WID_RESET: + warning_state[i] &= ~mask; + warning_state[i] |= warning_state_init[i] & mask; + break; + } + } + } + + return ok; +} diff --git a/asm/eval.c b/asm/eval.c new file mode 100644 index 0000000..7e727a4 --- /dev/null +++ b/asm/eval.c @@ -0,0 +1,1023 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * eval.c expression evaluator for the Netwide Assembler + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "ilog2.h" +#include "error.h" +#include "eval.h" +#include "labels.h" +#include "float.h" +#include "assemble.h" + +#define TEMPEXPRS_DELTA 128 +#define TEMPEXPR_DELTA 8 + +static scanner scan; /* Address of scanner routine */ + +static expr **tempexprs = NULL; +static int ntempexprs; +static int tempexprs_size = 0; + +static expr *tempexpr; +static int ntempexpr; +static int tempexpr_size; + +static struct tokenval *tokval; /* The current token */ +static int i; /* The t_type of tokval */ + +static void *scpriv; +static int *opflags; + +static struct eval_hints *hint; +static int64_t deadman; + + +/* + * Unimportant cleanup is done to avoid confusing people who are trying + * to debug real memory leaks + */ +void eval_cleanup(void) +{ + while (ntempexprs) + nasm_free(tempexprs[--ntempexprs]); + nasm_free(tempexprs); +} + +/* + * Construct a temporary expression. + */ +static void begintemp(void) +{ + tempexpr = NULL; + tempexpr_size = ntempexpr = 0; +} + +static void addtotemp(int32_t type, int64_t value) +{ + while (ntempexpr >= tempexpr_size) { + tempexpr_size += TEMPEXPR_DELTA; + tempexpr = nasm_realloc(tempexpr, + tempexpr_size * sizeof(*tempexpr)); + } + tempexpr[ntempexpr].type = type; + tempexpr[ntempexpr++].value = value; +} + +static expr *finishtemp(void) +{ + addtotemp(0L, 0L); /* terminate */ + while (ntempexprs >= tempexprs_size) { + tempexprs_size += TEMPEXPRS_DELTA; + tempexprs = nasm_realloc(tempexprs, + tempexprs_size * sizeof(*tempexprs)); + } + return tempexprs[ntempexprs++] = tempexpr; +} + +/* + * Add two vector datatypes. We have some bizarre behaviour on far- + * absolute segment types: we preserve them during addition _only_ + * if one of the segments is a truly pure scalar. + */ +static expr *add_vectors(expr * p, expr * q) +{ + int preserve; + + preserve = is_really_simple(p) || is_really_simple(q); + + begintemp(); + + while (p->type && q->type && + p->type < EXPR_SEGBASE + SEG_ABS && + q->type < EXPR_SEGBASE + SEG_ABS) { + int lasttype; + + if (p->type > q->type) { + addtotemp(q->type, q->value); + lasttype = q++->type; + } else if (p->type < q->type) { + addtotemp(p->type, p->value); + lasttype = p++->type; + } else { /* *p and *q have same type */ + int64_t sum = p->value + q->value; + if (sum) { + addtotemp(p->type, sum); + if (hint) + hint->type = EAH_SUMMED; + } + lasttype = p->type; + p++, q++; + } + if (lasttype == EXPR_UNKNOWN) { + return finishtemp(); + } + } + while (p->type && (preserve || p->type < EXPR_SEGBASE + SEG_ABS)) { + addtotemp(p->type, p->value); + p++; + } + while (q->type && (preserve || q->type < EXPR_SEGBASE + SEG_ABS)) { + addtotemp(q->type, q->value); + q++; + } + + return finishtemp(); +} + +/* + * Multiply a vector by a scalar. Strip far-absolute segment part + * if present. + * + * Explicit treatment of UNKNOWN is not required in this routine, + * since it will silently do the Right Thing anyway. + * + * If `affect_hints' is set, we also change the hint type to + * NOTBASE if a MAKEBASE hint points at a register being + * multiplied. This allows [eax*1+ebx] to hint EBX rather than EAX + * as the base register. + */ +static expr *scalar_mult(expr * vect, int64_t scalar, int affect_hints) +{ + expr *p = vect; + + while (p->type && p->type < EXPR_SEGBASE + SEG_ABS) { + p->value = scalar * (p->value); + if (hint && hint->type == EAH_MAKEBASE && + p->type == hint->base && affect_hints) + hint->type = EAH_NOTBASE; + p++; + } + p->type = 0; + + return vect; +} + +static expr *scalarvect(int64_t scalar) +{ + begintemp(); + addtotemp(EXPR_SIMPLE, scalar); + return finishtemp(); +} + +static expr *unknown_expr(void) +{ + begintemp(); + addtotemp(EXPR_UNKNOWN, 1L); + return finishtemp(); +} + +/* + * The SEG operator: calculate the segment part of a relocatable + * value. Return NULL, as usual, if an error occurs. Report the + * error too. + */ +static expr *segment_part(expr * e) +{ + int32_t seg; + + if (is_unknown(e)) + return unknown_expr(); + + if (!is_reloc(e)) { + nasm_error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value"); + return NULL; + } + + seg = reloc_seg(e); + if (seg == NO_SEG) { + nasm_error(ERR_NONFATAL, "cannot apply SEG to a non-relocatable value"); + return NULL; + } else if (seg & SEG_ABS) { + return scalarvect(seg & ~SEG_ABS); + } else if (seg & 1) { + nasm_error(ERR_NONFATAL, "SEG applied to something which" + " is already a segment base"); + return NULL; + } else { + int32_t base = ofmt->segbase(seg + 1); + + begintemp(); + addtotemp((base == NO_SEG ? EXPR_UNKNOWN : EXPR_SEGBASE + base), + 1L); + return finishtemp(); + } +} + +/* + * Recursive-descent parser. Called with a single boolean operand, + * which is true if the evaluation is critical (i.e. unresolved + * symbols are an error condition). Must update the global `i' to + * reflect the token after the parsed string. May return NULL. + * + * evaluate() should report its own errors: on return it is assumed + * that if NULL has been returned, the error has already been + * reported. + */ + +/* + * Grammar parsed is: + * + * expr : bexpr [ WRT expr6 ] + * bexpr : rexp0 or expr0 depending on relative-mode setting + * rexp0 : rexp1 [ {||} rexp1...] + * rexp1 : rexp2 [ {^^} rexp2...] + * rexp2 : rexp3 [ {&&} rexp3...] + * rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=} expr0 ] + * expr0 : expr1 [ {|} expr1...] + * expr1 : expr2 [ {^} expr2...] + * expr2 : expr3 [ {&} expr3...] + * expr3 : expr4 [ {<<,>>} expr4...] + * expr4 : expr5 [ {+,-} expr5...] + * expr5 : expr6 [ {*,/,%,//,%%} expr6...] + * expr6 : { ~,+,-,IFUNC,SEG } expr6 + * | (bexpr) + * | symbol + * | $ + * | number + */ + +static expr *rexp0(int), *rexp1(int), *rexp2(int), *rexp3(int); + +static expr *expr0(int), *expr1(int), *expr2(int), *expr3(int); +static expr *expr4(int), *expr5(int), *expr6(int); + +static expr *(*bexpr) (int); + +static expr *rexp0(int critical) +{ + expr *e, *f; + + e = rexp1(critical); + if (!e) + return NULL; + + while (i == TOKEN_DBL_OR) { + i = scan(scpriv, tokval); + f = rexp1(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`|' operator may only be applied to" + " scalar values"); + } + + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect((int64_t)(reloc_value(e) || reloc_value(f))); + } + return e; +} + +static expr *rexp1(int critical) +{ + expr *e, *f; + + e = rexp2(critical); + if (!e) + return NULL; + + while (i == TOKEN_DBL_XOR) { + i = scan(scpriv, tokval); + f = rexp2(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`^' operator may only be applied to" + " scalar values"); + } + + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect((int64_t)(!reloc_value(e) ^ !reloc_value(f))); + } + return e; +} + +static expr *rexp2(int critical) +{ + expr *e, *f; + + e = rexp3(critical); + if (!e) + return NULL; + while (i == TOKEN_DBL_AND) { + i = scan(scpriv, tokval); + f = rexp3(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`&' operator may only be applied to" + " scalar values"); + } + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect((int64_t)(reloc_value(e) && reloc_value(f))); + } + return e; +} + +static expr *rexp3(int critical) +{ + expr *e, *f; + int64_t v; + + e = expr0(critical); + if (!e) + return NULL; + + while (i == TOKEN_EQ || i == TOKEN_LT || i == TOKEN_GT || + i == TOKEN_NE || i == TOKEN_LE || i == TOKEN_GE) { + int j = i; + i = scan(scpriv, tokval); + f = expr0(critical); + if (!f) + return NULL; + + e = add_vectors(e, scalar_mult(f, -1L, false)); + + switch (j) { + case TOKEN_EQ: + case TOKEN_NE: + if (is_unknown(e)) + v = -1; /* means unknown */ + else if (!is_really_simple(e) || reloc_value(e) != 0) + v = (j == TOKEN_NE); /* unequal, so return true if NE */ + else + v = (j == TOKEN_EQ); /* equal, so return true if EQ */ + break; + default: + if (is_unknown(e)) + v = -1; /* means unknown */ + else if (!is_really_simple(e)) { + nasm_error(ERR_NONFATAL, + "`%s': operands differ by a non-scalar", + (j == TOKEN_LE ? "<=" : j == TOKEN_LT ? "<" : j == + TOKEN_GE ? ">=" : ">")); + v = 0; /* must set it to _something_ */ + } else { + int64_t vv = reloc_value(e); + if (vv == 0) + v = (j == TOKEN_LE || j == TOKEN_GE); + else if (vv > 0) + v = (j == TOKEN_GE || j == TOKEN_GT); + else /* vv < 0 */ + v = (j == TOKEN_LE || j == TOKEN_LT); + } + break; + } + + if (v == -1) + e = unknown_expr(); + else + e = scalarvect(v); + } + return e; +} + +static expr *expr0(int critical) +{ + expr *e, *f; + + e = expr1(critical); + if (!e) + return NULL; + + while (i == '|') { + i = scan(scpriv, tokval); + f = expr1(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`|' operator may only be applied to" + " scalar values"); + } + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(reloc_value(e) | reloc_value(f)); + } + return e; +} + +static expr *expr1(int critical) +{ + expr *e, *f; + + e = expr2(critical); + if (!e) + return NULL; + + while (i == '^') { + i = scan(scpriv, tokval); + f = expr2(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`^' operator may only be applied to" + " scalar values"); + } + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(reloc_value(e) ^ reloc_value(f)); + } + return e; +} + +static expr *expr2(int critical) +{ + expr *e, *f; + + e = expr3(critical); + if (!e) + return NULL; + + while (i == '&') { + i = scan(scpriv, tokval); + f = expr3(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "`&' operator may only be applied to" + " scalar values"); + } + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(reloc_value(e) & reloc_value(f)); + } + return e; +} + +static expr *expr3(int critical) +{ + expr *e, *f; + + e = expr4(critical); + if (!e) + return NULL; + + while (i == TOKEN_SHL || i == TOKEN_SHR) { + int j = i; + i = scan(scpriv, tokval); + f = expr4(critical); + if (!f) + return NULL; + if (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f))) { + nasm_error(ERR_NONFATAL, "shift operator may only be applied to" + " scalar values"); + } else if (is_just_unknown(e) || is_just_unknown(f)) { + e = unknown_expr(); + } else + switch (j) { + case TOKEN_SHL: + e = scalarvect(reloc_value(e) << reloc_value(f)); + break; + case TOKEN_SHR: + e = scalarvect(((uint64_t)reloc_value(e)) >> + reloc_value(f)); + break; + } + } + return e; +} + +static expr *expr4(int critical) +{ + expr *e, *f; + + e = expr5(critical); + if (!e) + return NULL; + while (i == '+' || i == '-') { + int j = i; + i = scan(scpriv, tokval); + f = expr5(critical); + if (!f) + return NULL; + switch (j) { + case '+': + e = add_vectors(e, f); + break; + case '-': + e = add_vectors(e, scalar_mult(f, -1L, false)); + break; + } + } + return e; +} + +static expr *expr5(int critical) +{ + expr *e, *f; + + e = expr6(critical); + if (!e) + return NULL; + while (i == '*' || i == '/' || i == '%' || + i == TOKEN_SDIV || i == TOKEN_SMOD) { + int j = i; + i = scan(scpriv, tokval); + f = expr6(critical); + if (!f) + return NULL; + if (j != '*' && (!(is_simple(e) || is_just_unknown(e)) || + !(is_simple(f) || is_just_unknown(f)))) { + nasm_error(ERR_NONFATAL, "division operator may only be applied to" + " scalar values"); + return NULL; + } + if (j != '*' && !is_just_unknown(f) && reloc_value(f) == 0) { + nasm_error(ERR_NONFATAL, "division by zero"); + return NULL; + } + switch (j) { + case '*': + if (is_simple(e)) + e = scalar_mult(f, reloc_value(e), true); + else if (is_simple(f)) + e = scalar_mult(e, reloc_value(f), true); + else if (is_just_unknown(e) && is_just_unknown(f)) + e = unknown_expr(); + else { + nasm_error(ERR_NONFATAL, "unable to multiply two " + "non-scalar objects"); + return NULL; + } + break; + case '/': + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(((uint64_t)reloc_value(e)) / + ((uint64_t)reloc_value(f))); + break; + case '%': + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(((uint64_t)reloc_value(e)) % + ((uint64_t)reloc_value(f))); + break; + case TOKEN_SDIV: + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(((int64_t)reloc_value(e)) / + ((int64_t)reloc_value(f))); + break; + case TOKEN_SMOD: + if (is_just_unknown(e) || is_just_unknown(f)) + e = unknown_expr(); + else + e = scalarvect(((int64_t)reloc_value(e)) % + ((int64_t)reloc_value(f))); + break; + } + } + return e; +} + +static expr *eval_floatize(enum floatize type) +{ + uint8_t result[16], *p; /* Up to 128 bits */ + static const struct { + int bytes, start, len; + } formats[] = { + { 1, 0, 1 }, /* FLOAT_8 */ + { 2, 0, 2 }, /* FLOAT_16 */ + { 4, 0, 4 }, /* FLOAT_32 */ + { 8, 0, 8 }, /* FLOAT_64 */ + { 10, 0, 8 }, /* FLOAT_80M */ + { 10, 8, 2 }, /* FLOAT_80E */ + { 16, 0, 8 }, /* FLOAT_128L */ + { 16, 8, 8 }, /* FLOAT_128H */ + }; + int sign = 1; + int64_t val; + int j; + + i = scan(scpriv, tokval); + if (i != '(') { + nasm_error(ERR_NONFATAL, "expecting `('"); + return NULL; + } + i = scan(scpriv, tokval); + if (i == '-' || i == '+') { + sign = (i == '-') ? -1 : 1; + i = scan(scpriv, tokval); + } + if (i != TOKEN_FLOAT) { + nasm_error(ERR_NONFATAL, "expecting floating-point number"); + return NULL; + } + if (!float_const(tokval->t_charptr, sign, result, formats[type].bytes)) + return NULL; + i = scan(scpriv, tokval); + if (i != ')') { + nasm_error(ERR_NONFATAL, "expecting `)'"); + return NULL; + } + + p = result+formats[type].start+formats[type].len; + val = 0; + for (j = formats[type].len; j; j--) { + p--; + val = (val << 8) + *p; + } + + begintemp(); + addtotemp(EXPR_SIMPLE, val); + + i = scan(scpriv, tokval); + return finishtemp(); +} + +static expr *eval_strfunc(enum strfunc type) +{ + char *string; + size_t string_len; + int64_t val; + bool parens, rn_warn; + + parens = false; + i = scan(scpriv, tokval); + if (i == '(') { + parens = true; + i = scan(scpriv, tokval); + } + if (i != TOKEN_STR) { + nasm_error(ERR_NONFATAL, "expecting string"); + return NULL; + } + string_len = string_transform(tokval->t_charptr, tokval->t_inttwo, + &string, type); + if (string_len == (size_t)-1) { + nasm_error(ERR_NONFATAL, "invalid string for transform"); + return NULL; + } + + val = readstrnum(string, string_len, &rn_warn); + if (parens) { + i = scan(scpriv, tokval); + if (i != ')') { + nasm_error(ERR_NONFATAL, "expecting `)'"); + return NULL; + } + } + + if (rn_warn) + nasm_error(ERR_WARNING|ERR_PASS1, "character constant too long"); + + begintemp(); + addtotemp(EXPR_SIMPLE, val); + + i = scan(scpriv, tokval); + return finishtemp(); +} + +static int64_t eval_ifunc(int64_t val, enum ifunc func) +{ + int errtype; + uint64_t uval = (uint64_t)val; + int64_t rv; + + switch (func) { + case IFUNC_ILOG2E: + case IFUNC_ILOG2W: + errtype = (func == IFUNC_ILOG2E) ? ERR_NONFATAL : ERR_WARNING; + + if (!is_power2(uval)) + nasm_error(errtype, "ilog2 argument is not a power of two"); + /* fall through */ + case IFUNC_ILOG2F: + rv = ilog2_64(uval); + break; + + case IFUNC_ILOG2C: + rv = (uval < 2) ? 0 : ilog2_64(uval-1) + 1; + break; + + default: + nasm_panic(0, "invalid IFUNC token %d", func); + rv = 0; + break; + } + + return rv; +} + +static expr *expr6(int critical) +{ + int32_t type; + expr *e; + int32_t label_seg; + int64_t label_ofs; + int64_t tmpval; + bool rn_warn; + const char *scope; + + if (++deadman > nasm_limit[LIMIT_EVAL]) { + nasm_error(ERR_NONFATAL, "expression too long"); + return NULL; + } + + switch (i) { + case '-': + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + return scalar_mult(e, -1L, false); + + case '+': + i = scan(scpriv, tokval); + return expr6(critical); + + case '~': + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + if (is_just_unknown(e)) + return unknown_expr(); + else if (!is_simple(e)) { + nasm_error(ERR_NONFATAL, "`~' operator may only be applied to" + " scalar values"); + return NULL; + } + return scalarvect(~reloc_value(e)); + + case '!': + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + if (is_just_unknown(e)) + return unknown_expr(); + else if (!is_simple(e)) { + nasm_error(ERR_NONFATAL, "`!' operator may only be applied to" + " scalar values"); + return NULL; + } + return scalarvect(!reloc_value(e)); + + case TOKEN_IFUNC: + { + enum ifunc func = tokval->t_integer; + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + if (is_just_unknown(e)) + return unknown_expr(); + else if (!is_simple(e)) { + nasm_error(ERR_NONFATAL, "function may only be applied to" + " scalar values"); + return NULL; + } + return scalarvect(eval_ifunc(reloc_value(e), func)); + } + + case TOKEN_SEG: + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + e = segment_part(e); + if (!e) + return NULL; + if (is_unknown(e) && critical) { + nasm_error(ERR_NONFATAL, "unable to determine segment base"); + return NULL; + } + return e; + + case TOKEN_FLOATIZE: + return eval_floatize(tokval->t_integer); + + case TOKEN_STRFUNC: + return eval_strfunc(tokval->t_integer); + + case '(': + i = scan(scpriv, tokval); + e = bexpr(critical); + if (!e) + return NULL; + if (i != ')') { + nasm_error(ERR_NONFATAL, "expecting `)'"); + return NULL; + } + i = scan(scpriv, tokval); + return e; + + case TOKEN_NUM: + case TOKEN_STR: + case TOKEN_REG: + case TOKEN_ID: + case TOKEN_INSN: /* Opcodes that occur here are really labels */ + case TOKEN_HERE: + case TOKEN_BASE: + case TOKEN_DECORATOR: + begintemp(); + switch (i) { + case TOKEN_NUM: + addtotemp(EXPR_SIMPLE, tokval->t_integer); + break; + case TOKEN_STR: + tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn); + if (rn_warn) + nasm_error(ERR_WARNING|ERR_PASS1, "character constant too long"); + addtotemp(EXPR_SIMPLE, tmpval); + break; + case TOKEN_REG: + addtotemp(tokval->t_integer, 1L); + if (hint && hint->type == EAH_NOHINT) + hint->base = tokval->t_integer, hint->type = EAH_MAKEBASE; + break; + case TOKEN_ID: + case TOKEN_INSN: + case TOKEN_HERE: + case TOKEN_BASE: + /* + * If !location.known, this indicates that no + * symbol, Here or Base references are valid because we + * are in preprocess-only mode. + */ + if (!location.known) { + nasm_error(ERR_NONFATAL, + "%s not supported in preprocess-only mode", + (i == TOKEN_HERE ? "`$'" : + i == TOKEN_BASE ? "`$$'" : + "symbol references")); + addtotemp(EXPR_UNKNOWN, 1L); + break; + } + + type = EXPR_SIMPLE; /* might get overridden by UNKNOWN */ + if (i == TOKEN_BASE) { + label_seg = in_absolute ? absolute.segment : location.segment; + label_ofs = 0; + } else if (i == TOKEN_HERE) { + label_seg = in_absolute ? absolute.segment : location.segment; + label_ofs = in_absolute ? absolute.offset : location.offset; + } else { + if (!lookup_label(tokval->t_charptr, &label_seg, &label_ofs)) { + scope = local_scope(tokval->t_charptr); + if (critical == 2) { + nasm_error(ERR_NONFATAL, "symbol `%s%s' undefined", + scope,tokval->t_charptr); + return NULL; + } else if (critical == 1) { + nasm_error(ERR_NONFATAL, + "symbol `%s%s' not defined before use", + scope,tokval->t_charptr); + return NULL; + } else { + if (opflags) + *opflags |= OPFLAG_FORWARD; + type = EXPR_UNKNOWN; + label_seg = NO_SEG; + label_ofs = 1; + } + } + if (opflags && is_extern(tokval->t_charptr)) + *opflags |= OPFLAG_EXTERN; + } + addtotemp(type, label_ofs); + if (label_seg != NO_SEG) + addtotemp(EXPR_SEGBASE + label_seg, 1L); + break; + case TOKEN_DECORATOR: + addtotemp(EXPR_RDSAE, tokval->t_integer); + break; + } + i = scan(scpriv, tokval); + return finishtemp(); + + default: + nasm_error(ERR_NONFATAL, "expression syntax error"); + return NULL; + } +} + +expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, + int *fwref, int critical, struct eval_hints *hints) +{ + expr *e; + expr *f = NULL; + + deadman = 0; + + hint = hints; + if (hint) + hint->type = EAH_NOHINT; + + if (critical & CRITICAL) { + critical &= ~CRITICAL; + bexpr = rexp0; + } else + bexpr = expr0; + + scan = sc; + scpriv = scprivate; + tokval = tv; + opflags = fwref; + + if (tokval->t_type == TOKEN_INVALID) + i = scan(scpriv, tokval); + else + i = tokval->t_type; + + while (ntempexprs) /* initialize temporary storage */ + nasm_free(tempexprs[--ntempexprs]); + + e = bexpr(critical); + if (!e) + return NULL; + + if (i == TOKEN_WRT) { + i = scan(scpriv, tokval); /* eat the WRT */ + f = expr6(critical); + if (!f) + return NULL; + } + e = scalar_mult(e, 1L, false); /* strip far-absolute segment part */ + if (f) { + expr *g; + if (is_just_unknown(f)) + g = unknown_expr(); + else { + int64_t value; + begintemp(); + if (!is_reloc(f)) { + nasm_error(ERR_NONFATAL, "invalid right-hand operand to WRT"); + return NULL; + } + value = reloc_seg(f); + if (value == NO_SEG) + value = reloc_value(f) | SEG_ABS; + else if (!(value & SEG_ABS) && !(value % 2) && critical) { + nasm_error(ERR_NONFATAL, "invalid right-hand operand to WRT"); + return NULL; + } + addtotemp(EXPR_WRT, value); + g = finishtemp(); + } + e = add_vectors(e, g); + } + return e; +} diff --git a/asm/eval.h b/asm/eval.h new file mode 100644 index 0000000..7af17eb --- /dev/null +++ b/asm/eval.h @@ -0,0 +1,49 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * eval.h header file for eval.c + */ + +#ifndef NASM_EVAL_H +#define NASM_EVAL_H + +/* + * The evaluator itself. + */ +expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv, + int *fwref, int critical, struct eval_hints *hints); + +void eval_cleanup(void); + +#endif diff --git a/asm/exprdump.c b/asm/exprdump.c new file mode 100644 index 0000000..68a9b67 --- /dev/null +++ b/asm/exprdump.c @@ -0,0 +1,79 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 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. + * + * ----------------------------------------------------------------------- */ + +/* + * exprdump.c + * + * Debugging code to dump the contents of an expression vector to stdout + */ + +#include "nasm.h" + +static const char *expr_type(int32_t type) +{ + static char seg_str[64]; + + switch (type) { + case 0: + return "null"; + case EXPR_UNKNOWN: + return "unknown"; + case EXPR_SIMPLE: + return "simple"; + case EXPR_WRT: + return "wrt"; + case EXPR_RDSAE: + return "sae"; + default: + break; + } + + if (type >= EXPR_REG_START && type <= EXPR_REG_END) { + return nasm_reg_names[type - EXPR_REG_START]; + } else if (type >= EXPR_SEGBASE) { + snprintf(seg_str, sizeof seg_str, "%sseg %d", + (type - EXPR_SEGBASE) == location.segment ? "this " : "", + type - EXPR_SEGBASE); + return seg_str; + } else { + return "ERR"; + } +} + +void dump_expr(const expr *e) +{ + printf("["); + for (; e->type; e++) + printf("<%s(%d),%"PRId64">", expr_type(e->type), e->type, e->value); + printf("]\n"); +} diff --git a/asm/exprlib.c b/asm/exprlib.c new file mode 100644 index 0000000..f7cfbce --- /dev/null +++ b/asm/exprlib.c @@ -0,0 +1,200 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 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. + * + * ----------------------------------------------------------------------- */ + +/* + * exprlib.c + * + * Library routines to manipulate expression data types. + */ + +#include "nasm.h" + +/* + * Return true if the argument is a simple scalar. (Or a far- + * absolute, which counts.) + */ +bool is_simple(const expr *vect) +{ + while (vect->type && !vect->value) + vect++; + if (!vect->type) + return true; + if (vect->type != EXPR_SIMPLE) + return false; + do { + vect++; + } while (vect->type && !vect->value); + if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS) + return false; + return true; +} + +/* + * Return true if the argument is a simple scalar, _NOT_ a far- + * absolute. + */ +bool is_really_simple(const expr *vect) +{ + while (vect->type && !vect->value) + vect++; + if (!vect->type) + return true; + if (vect->type != EXPR_SIMPLE) + return false; + do { + vect++; + } while (vect->type && !vect->value); + if (vect->type) + return false; + return true; +} + +/* + * Return true if the argument is relocatable (i.e. a simple + * scalar, plus at most one segment-base, possibly a subtraction + * of the current segment base, plus possibly a WRT). + */ +bool is_reloc(const expr *vect) +{ + bool has_rel = false; /* Has a self-segment-subtract */ + bool has_seg = false; /* Has a segment base */ + + for (; vect->type; vect++) { + if (!vect->value) { + /* skip value-0 terms */ + continue; + } else if (vect->type < EXPR_SIMPLE) { + /* false if a register is present */ + return false; + } else if (vect->type == EXPR_SIMPLE) { + /* skip over a pure number term... */ + continue; + } else if (vect->type == EXPR_WRT) { + /* skip over a WRT term... */ + continue; + } else if (vect->type < EXPR_SEGBASE) { + /* other special type -> problem */ + return false; + } else if (vect->value == 1) { + if (has_seg) + return false; /* only one segbase allowed */ + has_seg = true; + } else if (vect->value == -1) { + if (vect->type != location.segment + EXPR_SEGBASE) + return false; /* can only subtract current segment */ + if (has_rel) + return false; /* already is relative */ + has_rel = true; + } + } + + return true; +} + +/* + * Return true if the argument contains an `unknown' part. + */ +bool is_unknown(const expr *vect) +{ + while (vect->type && vect->type < EXPR_UNKNOWN) + vect++; + return (vect->type == EXPR_UNKNOWN); +} + +/* + * Return true if the argument contains nothing but an `unknown' + * part. + */ +bool is_just_unknown(const expr *vect) +{ + while (vect->type && !vect->value) + vect++; + return (vect->type == EXPR_UNKNOWN); +} + +/* + * Return the scalar part of a relocatable vector. (Including + * simple scalar vectors - those qualify as relocatable.) + */ +int64_t reloc_value(const expr *vect) +{ + while (vect->type && !vect->value) + vect++; + if (!vect->type) + return 0; + if (vect->type == EXPR_SIMPLE) + return vect->value; + else + return 0; +} + +/* + * Return the segment number of a relocatable vector, or NO_SEG for + * simple scalars. + */ +int32_t reloc_seg(const expr *vect) +{ + for (; vect->type; vect++) { + if (vect->type >= EXPR_SEGBASE && vect->value == 1) + return vect->type - EXPR_SEGBASE; + } + + return NO_SEG; +} + +/* + * Return the WRT segment number of a relocatable vector, or NO_SEG + * if no WRT part is present. + */ +int32_t reloc_wrt(const expr *vect) +{ + while (vect->type && vect->type < EXPR_WRT) + vect++; + if (vect->type == EXPR_WRT) { + return vect->value; + } else + return NO_SEG; +} + +/* + * Return true if this expression contains a subtraction of the location + */ +bool is_self_relative(const expr *vect) +{ + for (; vect->type; vect++) { + if (vect->type == location.segment + EXPR_SEGBASE && vect->value == -1) + return true; + } + + return false; +} diff --git a/asm/float.c b/asm/float.c new file mode 100644 index 0000000..37f5585 --- /dev/null +++ b/asm/float.c @@ -0,0 +1,954 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2017 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. + * + * ----------------------------------------------------------------------- */ + +/* + * float.c floating-point constant support for the Netwide Assembler + */ + +#include "compiler.h" + +#include +#include +#include +#include + +#include "nasm.h" +#include "float.h" +#include "error.h" + +/* + * ----------------- + * local variables + * ----------------- + */ +static bool daz = false; /* denormals as zero */ +static enum float_round rc = FLOAT_RC_NEAR; /* rounding control */ + +/* + * ----------- + * constants + * ----------- + */ + +/* "A limb is like a digit but bigger */ +typedef uint32_t fp_limb; +typedef uint64_t fp_2limb; + +#define LIMB_BITS 32 +#define LIMB_BYTES (LIMB_BITS/8) +#define LIMB_TOP_BIT ((fp_limb)1 << (LIMB_BITS-1)) +#define LIMB_MASK ((fp_limb)(~0)) +#define LIMB_ALL_BYTES ((fp_limb)0x01010101) +#define LIMB_BYTE(x) ((x)*LIMB_ALL_BYTES) + +/* 112 bits + 64 bits for accuracy + 16 bits for rounding */ +#define MANT_LIMBS 6 + +/* 52 digits fit in 176 bits because 10^53 > 2^176 > 10^52 */ +#define MANT_DIGITS 52 + +/* the format and the argument list depend on MANT_LIMBS */ +#define MANT_FMT "%08x_%08x_%08x_%08x_%08x_%08x" +#define MANT_ARG SOME_ARG(mant, 0) + +#define SOME_ARG(a,i) (a)[(i)+0], (a)[(i)+1], (a)[(i)+2], \ + (a)[(i)+3], (a)[(i)+4], (a)[(i)+5] + +/* + * --------------------------------------------------------------------------- + * emit a printf()-like debug message... but only if DEBUG_FLOAT was defined + * --------------------------------------------------------------------------- + */ + +#ifdef DEBUG_FLOAT +#define dprintf(x) printf x +#else +#define dprintf(x) do { } while (0) +#endif + +/* + * --------------------------------------------------------------------------- + * multiply + * --------------------------------------------------------------------------- + */ +static int float_multiply(fp_limb *to, fp_limb *from) +{ + fp_2limb temp[MANT_LIMBS * 2]; + int i, j; + + /* + * guaranteed that top bit of 'from' is set -- so we only have + * to worry about _one_ bit shift to the left + */ + dprintf(("%s=" MANT_FMT "\n", "mul1", SOME_ARG(to, 0))); + dprintf(("%s=" MANT_FMT "\n", "mul2", SOME_ARG(from, 0))); + + memset(temp, 0, sizeof temp); + + for (i = 0; i < MANT_LIMBS; i++) { + for (j = 0; j < MANT_LIMBS; j++) { + fp_2limb n; + n = (fp_2limb) to[i] * (fp_2limb) from[j]; + temp[i + j] += n >> LIMB_BITS; + temp[i + j + 1] += (fp_limb)n; + } + } + + for (i = MANT_LIMBS * 2; --i;) { + temp[i - 1] += temp[i] >> LIMB_BITS; + temp[i] &= LIMB_MASK; + } + + dprintf(("%s=" MANT_FMT "_" MANT_FMT "\n", "temp", SOME_ARG(temp, 0), + SOME_ARG(temp, MANT_LIMBS))); + + if (temp[0] & LIMB_TOP_BIT) { + for (i = 0; i < MANT_LIMBS; i++) { + to[i] = temp[i] & LIMB_MASK; + } + dprintf(("%s=" MANT_FMT " (%i)\n", "prod", SOME_ARG(to, 0), 0)); + return 0; + } else { + for (i = 0; i < MANT_LIMBS; i++) { + to[i] = (temp[i] << 1) + !!(temp[i + 1] & LIMB_TOP_BIT); + } + dprintf(("%s=" MANT_FMT " (%i)\n", "prod", SOME_ARG(to, 0), -1)); + return -1; + } +} + +/* + * --------------------------------------------------------------------------- + * read an exponent; returns INT32_MAX on error + * --------------------------------------------------------------------------- + */ +static int32_t read_exponent(const char *string, int32_t max) +{ + int32_t i = 0; + bool neg = false; + + if (*string == '+') { + string++; + } else if (*string == '-') { + neg = true; + string++; + } + while (*string) { + if (*string >= '0' && *string <= '9') { + i = (i * 10) + (*string - '0'); + + /* + * To ensure that underflows and overflows are + * handled properly we must avoid wraparounds of + * the signed integer value that is used to hold + * the exponent. Therefore we cap the exponent at + * +/-5000, which is slightly more/less than + * what's required for normal and denormal numbers + * in single, double, and extended precision, but + * sufficient to avoid signed integer wraparound. + */ + if (i > max) + i = max; + } else if (*string == '_') { + /* do nothing */ + } else { + nasm_error(ERR_NONFATAL, + "invalid character in floating-point constant %s: '%c'", + "exponent", *string); + return INT32_MAX; + } + string++; + } + + return neg ? -i : i; +} + +/* + * --------------------------------------------------------------------------- + * convert + * --------------------------------------------------------------------------- + */ +static bool ieee_flconvert(const char *string, fp_limb *mant, + int32_t * exponent) +{ + char digits[MANT_DIGITS]; + char *p, *q, *r; + fp_limb mult[MANT_LIMBS], bit; + fp_limb *m; + int32_t tenpwr, twopwr; + int32_t extratwos; + bool started, seendot, warned; + + warned = false; + p = digits; + tenpwr = 0; + started = seendot = false; + + while (*string && *string != 'E' && *string != 'e') { + if (*string == '.') { + if (!seendot) { + seendot = true; + } else { + nasm_error(ERR_NONFATAL, + "too many periods in floating-point constant"); + return false; + } + } else if (*string >= '0' && *string <= '9') { + if (*string == '0' && !started) { + if (seendot) { + tenpwr--; + } + } else { + started = true; + if (p < digits + sizeof(digits)) { + *p++ = *string - '0'; + } else { + if (!warned) { + nasm_error(ERR_WARNING|ERR_WARN_FL_TOOLONG|ERR_PASS2, + "floating-point constant significand contains " + "more than %i digits", MANT_DIGITS); + warned = true; + } + } + if (!seendot) { + tenpwr++; + } + } + } else if (*string == '_') { + /* do nothing */ + } else { + nasm_error(ERR_NONFATAL|ERR_PASS2, + "invalid character in floating-point constant %s: '%c'", + "significand", *string); + return false; + } + string++; + } + + if (*string) { + int32_t e; + + string++; /* eat the E */ + e = read_exponent(string, 5000); + if (e == INT32_MAX) + return false; + tenpwr += e; + } + + /* + * At this point, the memory interval [digits,p) contains a + * series of decimal digits zzzzzzz, such that our number X + * satisfies X = 0.zzzzzzz * 10^tenpwr. + */ + q = digits; + dprintf(("X = 0.")); + while (q < p) { + dprintf(("%c", *q + '0')); + q++; + } + dprintf((" * 10^%i\n", tenpwr)); + + /* + * Now convert [digits,p) to our internal representation. + */ + bit = LIMB_TOP_BIT; + for (m = mant; m < mant + MANT_LIMBS; m++) { + *m = 0; + } + m = mant; + q = digits; + started = false; + twopwr = 0; + while (m < mant + MANT_LIMBS) { + fp_limb carry = 0; + while (p > q && !p[-1]) { + p--; + } + if (p <= q) { + break; + } + for (r = p; r-- > q;) { + int32_t i; + i = 2 * *r + carry; + if (i >= 10) { + carry = 1; + i -= 10; + } else { + carry = 0; + } + *r = i; + } + if (carry) { + *m |= bit; + started = true; + } + if (started) { + if (bit == 1) { + bit = LIMB_TOP_BIT; + m++; + } else { + bit >>= 1; + } + } else { + twopwr--; + } + } + twopwr += tenpwr; + + /* + * At this point, the 'mant' array contains the first frac- + * tional places of a base-2^16 real number which when mul- + * tiplied by 2^twopwr and 5^tenpwr gives X. + */ + dprintf(("X = " MANT_FMT " * 2^%i * 5^%i\n", MANT_ARG, twopwr, + tenpwr)); + + /* + * Now multiply 'mant' by 5^tenpwr. + */ + if (tenpwr < 0) { /* mult = 5^-1 = 0.2 */ + for (m = mult; m < mult + MANT_LIMBS - 1; m++) { + *m = LIMB_BYTE(0xcc); + } + mult[MANT_LIMBS - 1] = LIMB_BYTE(0xcc)+1; + extratwos = -2; + tenpwr = -tenpwr; + + /* + * If tenpwr was 1000...000b, then it becomes 1000...000b. See + * the "ANSI C" comment below for more details on that case. + * + * Because we already truncated tenpwr to +5000...-5000 inside + * the exponent parsing code, this shouldn't happen though. + */ + } else if (tenpwr > 0) { /* mult = 5^+1 = 5.0 */ + mult[0] = (fp_limb)5 << (LIMB_BITS-3); /* 0xA000... */ + for (m = mult + 1; m < mult + MANT_LIMBS; m++) { + *m = 0; + } + extratwos = 3; + } else { + extratwos = 0; + } + while (tenpwr) { + dprintf(("loop=" MANT_FMT " * 2^%i * 5^%i (%i)\n", MANT_ARG, + twopwr, tenpwr, extratwos)); + if (tenpwr & 1) { + dprintf(("mant*mult\n")); + twopwr += extratwos + float_multiply(mant, mult); + } + dprintf(("mult*mult\n")); + extratwos = extratwos * 2 + float_multiply(mult, mult); + tenpwr >>= 1; + + /* + * In ANSI C, the result of right-shifting a signed integer is + * considered implementation-specific. To ensure that the loop + * terminates even if tenpwr was 1000...000b to begin with, we + * manually clear the MSB, in case a 1 was shifted in. + * + * Because we already truncated tenpwr to +5000...-5000 inside + * the exponent parsing code, this shouldn't matter; neverthe- + * less it is the right thing to do here. + */ + tenpwr &= (uint32_t) - 1 >> 1; + } + + /* + * At this point, the 'mant' array contains the first frac- + * tional places of a base-2^16 real number in [0.5,1) that + * when multiplied by 2^twopwr gives X. Or it contains zero + * of course. We are done. + */ + *exponent = twopwr; + return true; +} + +/* + * --------------------------------------------------------------------------- + * operations of specific bits + * --------------------------------------------------------------------------- + */ + +/* Set a bit, using *bigendian* bit numbering (0 = MSB) */ +static void set_bit(fp_limb *mant, int bit) +{ + mant[bit/LIMB_BITS] |= LIMB_TOP_BIT >> (bit & (LIMB_BITS-1)); +} + +/* Test a single bit */ +static int test_bit(const fp_limb *mant, int bit) +{ + return (mant[bit/LIMB_BITS] >> (~bit & (LIMB_BITS-1))) & 1; +} + +/* Report if the mantissa value is all zero */ +static bool is_zero(const fp_limb *mant) +{ + int i; + + for (i = 0; i < MANT_LIMBS; i++) + if (mant[i]) + return false; + + return true; +} + +/* + * --------------------------------------------------------------------------- + * round a mantissa off after i words + * --------------------------------------------------------------------------- + */ + +#define ROUND_COLLECT_BITS \ + do { \ + m = mant[i] & (2*bit-1); \ + for (j = i+1; j < MANT_LIMBS; j++) \ + m = m | mant[j]; \ + } while (0) + +#define ROUND_ABS_DOWN \ + do { \ + mant[i] &= ~(bit-1); \ + for (j = i+1; j < MANT_LIMBS; j++) \ + mant[j] = 0; \ + return false; \ + } while (0) + +#define ROUND_ABS_UP \ + do { \ + mant[i] = (mant[i] & ~(bit-1)) + bit; \ + for (j = i+1; j < MANT_LIMBS; j++) \ + mant[j] = 0; \ + while (i > 0 && !mant[i]) \ + ++mant[--i]; \ + return !mant[0]; \ + } while (0) + +static bool ieee_round(bool minus, fp_limb *mant, int bits) +{ + fp_limb m = 0; + int32_t j; + int i = bits / LIMB_BITS; + int p = bits % LIMB_BITS; + fp_limb bit = LIMB_TOP_BIT >> p; + + if (rc == FLOAT_RC_NEAR) { + if (mant[i] & bit) { + mant[i] &= ~bit; + ROUND_COLLECT_BITS; + mant[i] |= bit; + if (m) { + ROUND_ABS_UP; + } else { + if (test_bit(mant, bits-1)) { + ROUND_ABS_UP; + } else { + ROUND_ABS_DOWN; + } + } + } else { + ROUND_ABS_DOWN; + } + } else if (rc == FLOAT_RC_ZERO || + rc == (minus ? FLOAT_RC_UP : FLOAT_RC_DOWN)) { + ROUND_ABS_DOWN; + } else { + /* rc == (minus ? FLOAT_RC_DOWN : FLOAT_RC_UP) */ + /* Round toward +/- infinity */ + ROUND_COLLECT_BITS; + if (m) { + ROUND_ABS_UP; + } else { + ROUND_ABS_DOWN; + } + } + return false; +} + +/* Returns a value >= 16 if not a valid hex digit */ +static unsigned int hexval(char c) +{ + unsigned int v = (unsigned char) c; + + if (v >= '0' && v <= '9') + return v - '0'; + else + return (v|0x20) - 'a' + 10; +} + +/* Handle floating-point numbers with radix 2^bits and binary exponent */ +static bool ieee_flconvert_bin(const char *string, int bits, + fp_limb *mant, int32_t *exponent) +{ + static const int log2tbl[16] = + { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 }; + fp_limb mult[MANT_LIMBS + 1], *mp; + int ms; + int32_t twopwr; + bool seendot, seendigit; + unsigned char c; + const int radix = 1 << bits; + fp_limb v; + + twopwr = 0; + seendot = seendigit = false; + ms = 0; + mp = NULL; + + memset(mult, 0, sizeof mult); + + while ((c = *string++) != '\0') { + if (c == '.') { + if (!seendot) + seendot = true; + else { + nasm_error(ERR_NONFATAL, + "too many periods in floating-point constant"); + return false; + } + } else if ((v = hexval(c)) < (unsigned int)radix) { + if (!seendigit && v) { + int l = log2tbl[v]; + + seendigit = true; + mp = mult; + ms = (LIMB_BITS-1)-l; + + twopwr += l+1-bits; + } + + if (seendigit) { + if (ms <= 0) { + *mp |= v >> -ms; + mp++; + if (mp > &mult[MANT_LIMBS]) + mp = &mult[MANT_LIMBS]; /* Guard slot */ + ms += LIMB_BITS; + } + *mp |= v << ms; + ms -= bits; + + if (!seendot) + twopwr += bits; + } else { + if (seendot) + twopwr -= bits; + } + } else if (c == 'p' || c == 'P') { + int32_t e; + e = read_exponent(string, 20000); + if (e == INT32_MAX) + return false; + twopwr += e; + break; + } else if (c == '_') { + /* ignore */ + } else { + nasm_error(ERR_NONFATAL, + "floating-point constant: `%c' is invalid character", c); + return false; + } + } + + if (!seendigit) { + memset(mant, 0, MANT_LIMBS*sizeof(fp_limb)); /* Zero */ + *exponent = 0; + } else { + memcpy(mant, mult, MANT_LIMBS*sizeof(fp_limb)); + *exponent = twopwr; + } + + return true; +} + +/* + * Shift a mantissa to the right by i bits. + */ +static void ieee_shr(fp_limb *mant, int i) +{ + fp_limb n, m; + int j = 0; + int sr, sl, offs; + + sr = i % LIMB_BITS; sl = LIMB_BITS-sr; + offs = i/LIMB_BITS; + + if (sr == 0) { + if (offs) + for (j = MANT_LIMBS-1; j >= offs; j--) + mant[j] = mant[j-offs]; + } else if (MANT_LIMBS-1-offs < 0) { + j = MANT_LIMBS-1; + } else { + n = mant[MANT_LIMBS-1-offs] >> sr; + for (j = MANT_LIMBS-1; j > offs; j--) { + m = mant[j-offs-1]; + mant[j] = (m << sl) | n; + n = m >> sr; + } + mant[j--] = n; + } + while (j >= 0) + mant[j--] = 0; +} + +/* Produce standard IEEE formats, with implicit or explicit integer + bit; this makes the following assumptions: + + - the sign bit is the MSB, followed by the exponent, + followed by the integer bit if present. + - the sign bit plus exponent fit in 16 bits. + - the exponent bias is 2^(n-1)-1 for an n-bit exponent */ + +struct ieee_format { + int bytes; + int mantissa; /* Fractional bits in the mantissa */ + int explicit; /* Explicit integer */ + int exponent; /* Bits in the exponent */ +}; + +/* + * The 16- and 128-bit formats are expected to be in IEEE 754r. + * AMD SSE5 uses the 16-bit format. + * + * The 32- and 64-bit formats are the original IEEE 754 formats. + * + * The 80-bit format is x87-specific, but widely used. + * + * The 8-bit format appears to be the consensus 8-bit floating-point + * format. It is apparently used in graphics applications. + */ +static const struct ieee_format ieee_8 = { 1, 3, 0, 4 }; +static const struct ieee_format ieee_16 = { 2, 10, 0, 5 }; +static const struct ieee_format ieee_32 = { 4, 23, 0, 8 }; +static const struct ieee_format ieee_64 = { 8, 52, 0, 11 }; +static const struct ieee_format ieee_80 = { 10, 63, 1, 15 }; +static const struct ieee_format ieee_128 = { 16, 112, 0, 15 }; + +/* Types of values we can generate */ +enum floats { + FL_ZERO, + FL_DENORMAL, + FL_NORMAL, + FL_INFINITY, + FL_QNAN, + FL_SNAN +}; + +static int to_packed_bcd(const char *str, const char *p, + int s, uint8_t *result, + const struct ieee_format *fmt) +{ + int n = 0; + char c; + int tv = -1; + + if (fmt != &ieee_80) { + nasm_error(ERR_NONFATAL, + "packed BCD requires an 80-bit format"); + return 0; + } + + while (p >= str) { + c = *p--; + if (c >= '0' && c <= '9') { + if (tv < 0) { + if (n == 9) { + nasm_error(ERR_WARNING|ERR_PASS2, + "packed BCD truncated to 18 digits"); + } + tv = c-'0'; + } else { + if (n < 9) + *result++ = tv + ((c-'0') << 4); + n++; + tv = -1; + } + } else if (c == '_') { + /* do nothing */ + } else { + nasm_error(ERR_NONFATAL, + "invalid character `%c' in packed BCD constant", c); + return 0; + } + } + if (tv >= 0) { + if (n < 9) + *result++ = tv; + n++; + } + while (n < 9) { + *result++ = 0; + n++; + } + *result = (s < 0) ? 0x80 : 0; + + return 1; /* success */ +} + +static int to_float(const char *str, int s, uint8_t *result, + const struct ieee_format *fmt) +{ + fp_limb mant[MANT_LIMBS]; + int32_t exponent = 0; + const int32_t expmax = 1 << (fmt->exponent - 1); + fp_limb one_mask = LIMB_TOP_BIT >> + ((fmt->exponent+fmt->explicit) % LIMB_BITS); + const int one_pos = (fmt->exponent+fmt->explicit)/LIMB_BITS; + int i; + int shift; + enum floats type; + bool ok; + const bool minus = s < 0; + const int bits = fmt->bytes * 8; + const char *strend; + + if (!str[0]) { + nasm_panic(0, + "internal errror: empty string passed to float_const"); + return 0; + } + + strend = strchr(str, '\0'); + if (strend[-1] == 'P' || strend[-1] == 'p') + return to_packed_bcd(str, strend-2, s, result, fmt); + + if (str[0] == '_') { + /* Special tokens */ + + switch (str[2]) { + case 'n': /* __nan__ */ + case 'N': + case 'q': /* __qnan__ */ + case 'Q': + type = FL_QNAN; + break; + case 's': /* __snan__ */ + case 'S': + type = FL_SNAN; + break; + case 'i': /* __infinity__ */ + case 'I': + type = FL_INFINITY; + break; + default: + nasm_error(ERR_NONFATAL, + "internal error: unknown FP constant token `%s'\n", str); + type = FL_QNAN; + break; + } + } else { + if (str[0] == '0') { + switch (str[1]) { + case 'x': case 'X': + case 'h': case 'H': + ok = ieee_flconvert_bin(str+2, 4, mant, &exponent); + break; + case 'o': case 'O': + case 'q': case 'Q': + ok = ieee_flconvert_bin(str+2, 3, mant, &exponent); + break; + case 'b': case 'B': + case 'y': case 'Y': + ok = ieee_flconvert_bin(str+2, 1, mant, &exponent); + break; + case 'd': case 'D': + case 't': case 'T': + ok = ieee_flconvert(str+2, mant, &exponent); + break; + case 'p': case 'P': + return to_packed_bcd(str+2, strend-1, s, result, fmt); + default: + /* Leading zero was just a zero? */ + ok = ieee_flconvert(str, mant, &exponent); + break; + } + } else if (str[0] == '$') { + ok = ieee_flconvert_bin(str+1, 4, mant, &exponent); + } else { + ok = ieee_flconvert(str, mant, &exponent); + } + + if (!ok) { + type = FL_QNAN; + } else if (mant[0] & LIMB_TOP_BIT) { + /* + * Non-zero. + */ + exponent--; + if (exponent >= 2 - expmax && exponent <= expmax) { + type = FL_NORMAL; + } else if (exponent > 0) { + if (pass0 == 1) + nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS2, + "overflow in floating-point constant"); + type = FL_INFINITY; + } else { + /* underflow or denormal; the denormal code handles + actual underflow. */ + type = FL_DENORMAL; + } + } else { + /* Zero */ + type = FL_ZERO; + } + } + + switch (type) { + case FL_ZERO: + zero: + memset(mant, 0, sizeof mant); + break; + + case FL_DENORMAL: + { + shift = -(exponent + expmax - 2 - fmt->exponent) + + fmt->explicit; + ieee_shr(mant, shift); + ieee_round(minus, mant, bits); + if (mant[one_pos] & one_mask) { + /* One's position is set, we rounded up into normal range */ + exponent = 1; + if (!fmt->explicit) + mant[one_pos] &= ~one_mask; /* remove explicit one */ + mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent); + } else { + if (daz || is_zero(mant)) { + /* Flush denormals to zero */ + nasm_error(ERR_WARNING|ERR_WARN_FL_UNDERFLOW|ERR_PASS2, + "underflow in floating-point constant"); + goto zero; + } else { + nasm_error(ERR_WARNING|ERR_WARN_FL_DENORM|ERR_PASS2, + "denormal floating-point constant"); + } + } + break; + } + + case FL_NORMAL: + exponent += expmax - 1; + ieee_shr(mant, fmt->exponent+fmt->explicit); + ieee_round(minus, mant, bits); + /* did we scale up by one? */ + if (test_bit(mant, fmt->exponent+fmt->explicit-1)) { + ieee_shr(mant, 1); + exponent++; + if (exponent >= (expmax << 1)-1) { + nasm_error(ERR_WARNING|ERR_WARN_FL_OVERFLOW|ERR_PASS2, + "overflow in floating-point constant"); + type = FL_INFINITY; + goto overflow; + } + } + + if (!fmt->explicit) + mant[one_pos] &= ~one_mask; /* remove explicit one */ + mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent); + break; + + case FL_INFINITY: + case FL_QNAN: + case FL_SNAN: + overflow: + memset(mant, 0, sizeof mant); + mant[0] = (((fp_limb)1 << fmt->exponent)-1) + << (LIMB_BITS-1 - fmt->exponent); + if (fmt->explicit) + mant[one_pos] |= one_mask; + if (type == FL_QNAN) + set_bit(mant, fmt->exponent+fmt->explicit+1); + else if (type == FL_SNAN) + set_bit(mant, fmt->exponent+fmt->explicit+fmt->mantissa); + break; + } + + mant[0] |= minus ? LIMB_TOP_BIT : 0; + + for (i = fmt->bytes - 1; i >= 0; i--) + *result++ = mant[i/LIMB_BYTES] >> (((LIMB_BYTES-1)-(i%LIMB_BYTES))*8); + + return 1; /* success */ +} + +int float_const(const char *number, int sign, uint8_t *result, int bytes) +{ + switch (bytes) { + case 1: + return to_float(number, sign, result, &ieee_8); + case 2: + return to_float(number, sign, result, &ieee_16); + case 4: + return to_float(number, sign, result, &ieee_32); + case 8: + return to_float(number, sign, result, &ieee_64); + case 10: + return to_float(number, sign, result, &ieee_80); + case 16: + return to_float(number, sign, result, &ieee_128); + default: + nasm_panic(0, "strange value %d passed to float_const", bytes); + return 0; + } +} + +/* Set floating-point options */ +int float_option(const char *option) +{ + if (!nasm_stricmp(option, "daz")) { + daz = true; + return 0; + } else if (!nasm_stricmp(option, "nodaz")) { + daz = false; + return 0; + } else if (!nasm_stricmp(option, "near")) { + rc = FLOAT_RC_NEAR; + return 0; + } else if (!nasm_stricmp(option, "down")) { + rc = FLOAT_RC_DOWN; + return 0; + } else if (!nasm_stricmp(option, "up")) { + rc = FLOAT_RC_UP; + return 0; + } else if (!nasm_stricmp(option, "zero")) { + rc = FLOAT_RC_ZERO; + return 0; + } else if (!nasm_stricmp(option, "default")) { + rc = FLOAT_RC_NEAR; + daz = false; + return 0; + } else { + return -1; /* Unknown option */ + } +} diff --git a/asm/float.h b/asm/float.h new file mode 100644 index 0000000..b07e542 --- /dev/null +++ b/asm/float.h @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * float.h header file for the floating-point constant module of + * the Netwide Assembler + */ + +#ifndef NASM_FLOAT_H +#define NASM_FLOAT_H + +#include "nasm.h" + +enum float_round { + FLOAT_RC_NEAR, + FLOAT_RC_ZERO, + FLOAT_RC_DOWN, + FLOAT_RC_UP +}; + +int float_const(const char *string, int sign, uint8_t *result, int bytes); +int float_option(const char *option); + +#endif diff --git a/asm/labels.c b/asm/labels.c new file mode 100644 index 0000000..c00d6e5 --- /dev/null +++ b/asm/labels.c @@ -0,0 +1,652 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * labels.c label handling for the Netwide Assembler + */ + +#include "compiler.h" + +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "hashtbl.h" +#include "labels.h" + +/* + * A dot-local label is one that begins with exactly one period. Things + * that begin with _two_ periods are NASM-specific things. + * + * If TASM compatibility is enabled, a local label can also begin with + * @@. + */ +static bool islocal(const char *l) +{ + if (tasm_compatible_mode) { + if (l[0] == '@' && l[1] == '@') + return true; + } + + return (l[0] == '.' && l[1] != '.'); +} + +/* + * Return true if this falls into NASM's '..' namespace + */ +static bool ismagic(const char *l) +{ + return l[0] == '.' && l[1] == '.' && l[2] != '@'; +} + +/* + * Return true if we should update the local label base + * as a result of this symbol. We must exclude local labels + * as well as any kind of special labels, including ..@ ones. + */ +static bool set_prevlabel(const char *l) +{ + if (tasm_compatible_mode) { + if (l[0] == '@' && l[1] == '@') + return false; + } + + return l[0] != '.'; +} + +#define LABEL_BLOCK 128 /* no. of labels/block */ +#define LBLK_SIZE (LABEL_BLOCK * sizeof(union label)) + +#define END_LIST -3 /* don't clash with NO_SEG! */ +#define END_BLOCK -2 + +#define PERMTS_SIZE 16384 /* size of text blocks */ +#if (PERMTS_SIZE < IDLEN_MAX) + #error "IPERMTS_SIZE must be greater than or equal to IDLEN_MAX" +#endif + +/* string values for enum label_type */ +static const char * const types[] = +{"local", "global", "static", "extern", "common", "special", + "output format special"}; + +union label { /* actual label structures */ + struct { + int32_t segment; + int32_t subsection; /* Available for ofmt->herelabel() */ + int64_t offset; + int64_t size; + char *label, *mangled, *special; + enum label_type type, mangled_type; + bool defined; + } defn; + struct { + int32_t movingon; + int64_t dummy; + union label *next; + } admin; +}; + +struct permts { /* permanent text storage */ + struct permts *next; /* for the linked list */ + unsigned int size, usage; /* size and used space in ... */ + char data[PERMTS_SIZE]; /* ... the data block itself */ +}; +#define PERMTS_HEADER offsetof(struct permts, data) + +uint64_t global_offset_changed; /* counter for global offset changes */ + +static struct hash_table ltab; /* labels hash table */ +static union label *ldata; /* all label data blocks */ +static union label *lfree; /* labels free block */ +static struct permts *perm_head; /* start of perm. text storage */ +static struct permts *perm_tail; /* end of perm. text storage */ + +static void init_block(union label *blk); +static char *perm_alloc(size_t len); +static char *perm_copy(const char *string); +static char *perm_copy3(const char *s1, const char *s2, const char *s3); +static const char *mangle_label_name(union label *lptr); + +static const char *prevlabel; + +static bool initialized = false; + +/* + * Emit a symdef to the output and the debug format backends. + */ +static void out_symdef(union label *lptr) +{ + int backend_type; + int64_t backend_offset; + + /* Backend-defined special segments are passed to symdef immediately */ + if (pass0 == 2) { + /* Emit special fixups for globals and commons */ + switch (lptr->defn.type) { + case LBL_GLOBAL: + case LBL_EXTERN: + case LBL_COMMON: + if (lptr->defn.special) + ofmt->symdef(lptr->defn.mangled, 0, 0, 3, lptr->defn.special); + break; + default: + break; + } + return; + } + + if (pass0 != 1 && lptr->defn.type != LBL_BACKEND) + return; + + /* Clean up this hack... */ + switch(lptr->defn.type) { + case LBL_GLOBAL: + case LBL_EXTERN: + backend_type = 1; + backend_offset = lptr->defn.offset; + break; + case LBL_COMMON: + backend_type = 2; + backend_offset = lptr->defn.size; + break; + default: + backend_type = 0; + backend_offset = lptr->defn.offset; + break; + } + + /* Might be necessary for a backend symbol */ + mangle_label_name(lptr); + + ofmt->symdef(lptr->defn.mangled, lptr->defn.segment, + backend_offset, backend_type, + lptr->defn.special); + + /* + * NASM special symbols are not passed to the debug format; none + * of the current backends want to see them. + */ + if (lptr->defn.type == LBL_SPECIAL || lptr->defn.type == LBL_BACKEND) + return; + + dfmt->debug_deflabel(lptr->defn.mangled, lptr->defn.segment, + lptr->defn.offset, backend_type, + lptr->defn.special); +} + +/* + * Internal routine: finds the `union label' corresponding to the + * given label name. Creates a new one, if it isn't found, and if + * `create' is true. + */ +static union label *find_label(const char *label, bool create, bool *created) +{ + union label *lptr, **lpp; + char *label_str = NULL; + struct hash_insert ip; + + nasm_assert(label != NULL); + + if (islocal(label)) + label = label_str = nasm_strcat(prevlabel, label); + + lpp = (union label **) hash_find(<ab, label, &ip); + lptr = lpp ? *lpp : NULL; + + if (lptr || !create) { + if (created) + *created = false; + return lptr; + } + + /* Create a new label... */ + if (lfree->admin.movingon == END_BLOCK) { + /* + * must allocate a new block + */ + lfree->admin.next = nasm_malloc(LBLK_SIZE); + lfree = lfree->admin.next; + init_block(lfree); + } + + if (created) + *created = true; + + nasm_zero(*lfree); + lfree->defn.label = perm_copy(label); + lfree->defn.subsection = NO_SEG; + if (label_str) + nasm_free(label_str); + + hash_add(&ip, lfree->defn.label, lfree); + return lfree++; +} + +bool lookup_label(const char *label, int32_t *segment, int64_t *offset) +{ + union label *lptr; + + if (!initialized) + return false; + + lptr = find_label(label, false, NULL); + if (lptr && lptr->defn.defined) { + *segment = lptr->defn.segment; + *offset = lptr->defn.offset; + return true; + } + + return false; +} + +bool is_extern(const char *label) +{ + union label *lptr; + + if (!initialized) + return false; + + lptr = find_label(label, false, NULL); + return lptr && lptr->defn.type == LBL_EXTERN; +} + +static const char *mangle_strings[] = {"", "", "", ""}; +static bool mangle_string_set[ARRAY_SIZE(mangle_strings)]; + +/* + * Set a prefix or suffix + */ +void set_label_mangle(enum mangle_index which, const char *what) +{ + if (mangle_string_set[which]) + return; /* Once set, do not change */ + + mangle_strings[which] = perm_copy(what); + mangle_string_set[which] = true; +} + +/* + * Format a label name with appropriate prefixes and suffixes + */ +static const char *mangle_label_name(union label *lptr) +{ + const char *prefix; + const char *suffix; + + if (likely(lptr->defn.mangled && + lptr->defn.mangled_type == lptr->defn.type)) + return lptr->defn.mangled; /* Already mangled */ + + switch (lptr->defn.type) { + case LBL_GLOBAL: + case LBL_STATIC: + case LBL_EXTERN: + prefix = mangle_strings[LM_GPREFIX]; + suffix = mangle_strings[LM_GSUFFIX]; + break; + case LBL_BACKEND: + case LBL_SPECIAL: + prefix = suffix = ""; + break; + default: + prefix = mangle_strings[LM_LPREFIX]; + suffix = mangle_strings[LM_LSUFFIX]; + break; + } + + lptr->defn.mangled_type = lptr->defn.type; + + if (!(*prefix) && !(*suffix)) + lptr->defn.mangled = lptr->defn.label; + else + lptr->defn.mangled = perm_copy3(prefix, lptr->defn.label, suffix); + + return lptr->defn.mangled; +} + +static void +handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset) +{ + int32_t oldseg; + + if (likely(!ofmt->herelabel)) + return; + + if (unlikely(location.segment == NO_SEG)) + return; + + oldseg = *segment; + + if (oldseg == location.segment && *offset == location.offset) { + /* This label is defined at this location */ + int32_t newseg; + bool copyoffset = false; + + nasm_assert(lptr->defn.mangled); + newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type, + oldseg, &lptr->defn.subsection, ©offset); + if (likely(newseg == oldseg)) + return; + + *segment = newseg; + if (copyoffset) { + /* Maintain the offset from the old to the new segment */ + switch_segment(newseg); + location.offset = *offset; + } else { + /* Keep a separate offset for the new segment */ + *offset = switch_segment(newseg); + } + } +} + +static bool declare_label_lptr(union label *lptr, + enum label_type type, const char *special) +{ + if (special && !special[0]) + special = NULL; + + if (lptr->defn.type == type || + (pass0 == 0 && lptr->defn.type == LBL_LOCAL)) { + lptr->defn.type = type; + if (special) { + if (!lptr->defn.special) + lptr->defn.special = perm_copy(special); + else if (nasm_stricmp(lptr->defn.special, special)) + nasm_error(ERR_NONFATAL, + "symbol `%s' has inconsistent attributes `%s' and `%s'", + lptr->defn.label, lptr->defn.special, special); + } + return true; + } + + /* EXTERN can be replaced with GLOBAL or COMMON */ + if (lptr->defn.type == LBL_EXTERN && + (type == LBL_GLOBAL || type == LBL_COMMON)) { + lptr->defn.type = type; + /* Override special unconditionally */ + if (special) + lptr->defn.special = perm_copy(special); + return true; + } + + /* GLOBAL or COMMON ignore subsequent EXTERN */ + if ((lptr->defn.type == LBL_GLOBAL || lptr->defn.type == LBL_COMMON) && + type == LBL_EXTERN) { + if (!lptr->defn.special) + lptr->defn.special = perm_copy(special); + return false; /* Don't call define_label() after this! */ + } + + nasm_error(ERR_NONFATAL, "symbol `%s' declared both as %s and %s", + lptr->defn.label, types[lptr->defn.type], types[type]); + + return false; +} + +bool declare_label(const char *label, enum label_type type, const char *special) +{ + union label *lptr = find_label(label, true, NULL); + return declare_label_lptr(lptr, type, special); +} + +/* + * The "normal" argument decides if we should update the local segment + * base name or not. + */ +void define_label(const char *label, int32_t segment, + int64_t offset, bool normal) +{ + union label *lptr; + bool created, changed; + int64_t size; + + /* + * Phase errors here can be one of two types: a new label appears, + * or the offset changes. Increment global_offset_changed when that + * happens, to tell the assembler core to make another pass. + */ + lptr = find_label(label, true, &created); + + if (segment) { + /* We are actually defining this label */ + if (lptr->defn.type == LBL_EXTERN) /* auto-promote EXTERN to GLOBAL */ + lptr->defn.type = LBL_GLOBAL; + } else { + /* It's a pseudo-segment (extern, common) */ + segment = lptr->defn.segment ? lptr->defn.segment : seg_alloc(); + } + + if (lptr->defn.defined || lptr->defn.type == LBL_BACKEND) { + /* We have seen this on at least one previous pass */ + mangle_label_name(lptr); + handle_herelabel(lptr, &segment, &offset); + } + + if (ismagic(label) && lptr->defn.type == LBL_LOCAL) + lptr->defn.type = LBL_SPECIAL; + + if (set_prevlabel(label) && normal) + prevlabel = lptr->defn.label; + + if (lptr->defn.type == LBL_COMMON) { + size = offset; + offset = 0; + } else { + size = 0; /* This is a hack... */ + } + + changed = created || !lptr->defn.defined || + lptr->defn.segment != segment || + lptr->defn.offset != offset || lptr->defn.size != size; + global_offset_changed += changed; + + /* + * This probably should be ERR_NONFATAL, but not quite yet. As a + * special case, LBL_SPECIAL symbols are allowed to be changed + * even during the last pass. + */ + if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) { + nasm_error(ERR_WARNING, "label `%s' %s during code generation", + lptr->defn.label, + created ? "defined" : "changed"); + } + + lptr->defn.segment = segment; + lptr->defn.offset = offset; + lptr->defn.size = size; + lptr->defn.defined = true; + + out_symdef(lptr); +} + +/* + * Define a special backend label + */ +void backend_label(const char *label, int32_t segment, int64_t offset) +{ + if (!declare_label(label, LBL_BACKEND, NULL)) + return; + + define_label(label, segment, offset, false); +} + +int init_labels(void) +{ + hash_init(<ab, HASH_LARGE); + + ldata = lfree = nasm_malloc(LBLK_SIZE); + init_block(lfree); + + perm_head = perm_tail = + nasm_malloc(sizeof(struct permts)); + + perm_head->next = NULL; + perm_head->size = PERMTS_SIZE; + perm_head->usage = 0; + + prevlabel = ""; + + initialized = true; + + return 0; +} + +void cleanup_labels(void) +{ + union label *lptr, *lhold; + + initialized = false; + + hash_free(<ab); + + lptr = lhold = ldata; + while (lptr) { + lptr = &lptr[LABEL_BLOCK-1]; + lptr = lptr->admin.next; + nasm_free(lhold); + lhold = lptr; + } + + while (perm_head) { + perm_tail = perm_head; + perm_head = perm_head->next; + nasm_free(perm_tail); + } +} + +static void init_block(union label *blk) +{ + int j; + + for (j = 0; j < LABEL_BLOCK - 1; j++) + blk[j].admin.movingon = END_LIST; + blk[LABEL_BLOCK - 1].admin.movingon = END_BLOCK; + blk[LABEL_BLOCK - 1].admin.next = NULL; +} + +static char * safe_alloc perm_alloc(size_t len) +{ + char *p; + + if (perm_tail->size - perm_tail->usage < len) { + size_t alloc_len = (len > PERMTS_SIZE) ? len : PERMTS_SIZE; + perm_tail->next = nasm_malloc(PERMTS_HEADER + alloc_len); + perm_tail = perm_tail->next; + perm_tail->next = NULL; + perm_tail->size = alloc_len; + perm_tail->usage = 0; + } + p = perm_tail->data + perm_tail->usage; + perm_tail->usage += len; + return p; +} + +static char *perm_copy(const char *string) +{ + char *p; + size_t len; + + if (!string) + return NULL; + + len = strlen(string)+1; /* Include final NUL */ + + p = perm_alloc(len); + memcpy(p, string, len); + + return p; +} + +static char * +perm_copy3(const char *s1, const char *s2, const char *s3) +{ + char *p; + size_t l1 = strlen(s1); + size_t l2 = strlen(s2); + size_t l3 = strlen(s3)+1; /* Include final NUL */ + + p = perm_alloc(l1+l2+l3); + memcpy(p, s1, l1); + memcpy(p+l1, s2, l2); + memcpy(p+l1+l2, s3, l3); + + return p; +} + +const char *local_scope(const char *label) +{ + return islocal(label) ? prevlabel : ""; +} + +/* + * Notes regarding bug involving redefinition of external segments. + * + * Up to and including v0.97, the following code didn't work. From 0.97 + * developers release 2 onwards, it will generate an error. + * + * EXTERN extlabel + * newlabel EQU extlabel + 1 + * + * The results of allowing this code through are that two import records + * are generated, one for 'extlabel' and one for 'newlabel'. + * + * The reason for this is an inadequacy in the defined interface between + * the label manager and the output formats. The problem lies in how the + * output format driver tells that a label is an external label for which + * a label import record must be produced. Most (all except bin?) produce + * the record if the segment number of the label is not one of the internal + * segments that the output driver is producing. + * + * A simple fix to this would be to make the output formats keep track of + * which symbols they've produced import records for, and make them not + * produce import records for segments that are already defined. + * + * The best way, which is slightly harder but reduces duplication of code + * and should therefore make the entire system smaller and more stable is + * to change the interface between assembler, define_label(), and + * the output module. The changes that are needed are: + * + * The semantics of the 'isextern' flag passed to define_label() need + * examining. This information may or may not tell us what we need to + * know (ie should we be generating an import record at this point for this + * label). If these aren't the semantics, the semantics should be changed + * to this. + * + * The output module interface needs changing, so that the `isextern' flag + * is passed to the module, so that it can be easily tested for. + */ diff --git a/asm/listing.c b/asm/listing.c new file mode 100644 index 0000000..6c459e1 --- /dev/null +++ b/asm/listing.c @@ -0,0 +1,355 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * listing.c listing file generator for the Netwide Assembler + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "listing.h" + +#define LIST_MAX_LEN 216 /* something sensible */ +#define LIST_INDENT 40 +#define LIST_HEXBIT 18 + +typedef struct MacroInhibit MacroInhibit; + +static struct MacroInhibit { + MacroInhibit *next; + int level; + int inhibiting; +} *mistack; + +static char xdigit[] = "0123456789ABCDEF"; + +#define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]); + +static char listline[LIST_MAX_LEN]; +static bool listlinep; + +static char listerror[LIST_MAX_LEN]; + +static char listdata[2 * LIST_INDENT]; /* we need less than that actually */ +static int32_t listoffset; + +static int32_t listlineno; + +static int32_t listp; + +static int suppress; /* for INCBIN & TIMES special cases */ + +static int listlevel, listlevel_e; + +static FILE *listfp; + +static void list_emit(void) +{ + int i; + + if (!listlinep && !listdata[0]) + return; + + fprintf(listfp, "%6"PRId32" ", listlineno); + + if (listdata[0]) + fprintf(listfp, "%08"PRIX32" %-*s", listoffset, LIST_HEXBIT + 1, + listdata); + else + fprintf(listfp, "%*s", LIST_HEXBIT + 10, ""); + + if (listlevel_e) + fprintf(listfp, "%s<%d>", (listlevel < 10 ? " " : ""), + listlevel_e); + else if (listlinep) + fprintf(listfp, " "); + + if (listlinep) + fprintf(listfp, " %s", listline); + + putc('\n', listfp); + listlinep = false; + listdata[0] = '\0'; + + if (listerror[0]) { + fprintf(listfp, "%6"PRId32" ", listlineno); + for (i = 0; i < LIST_HEXBIT; i++) + putc('*', listfp); + + if (listlevel_e) + fprintf(listfp, " %s<%d>", (listlevel < 10 ? " " : ""), + listlevel_e); + else + fprintf(listfp, " "); + + fprintf(listfp, " %s\n", listerror); + listerror[0] = '\0'; + } +} + +static void list_init(const char *fname) +{ + if (!fname || fname[0] == '\0') { + listfp = NULL; + return; + } + + listfp = nasm_open_write(fname, NF_TEXT); + if (!listfp) { + nasm_error(ERR_NONFATAL, "unable to open listing file `%s'", + fname); + return; + } + + *listline = '\0'; + listlineno = 0; + *listerror = '\0'; + listp = true; + listlevel = 0; + suppress = 0; + mistack = nasm_malloc(sizeof(MacroInhibit)); + mistack->next = NULL; + mistack->level = 0; + mistack->inhibiting = true; +} + +static void list_cleanup(void) +{ + if (!listp) + return; + + while (mistack) { + MacroInhibit *temp = mistack; + mistack = temp->next; + nasm_free(temp); + } + + list_emit(); + fclose(listfp); +} + +static void list_out(int64_t offset, char *str) +{ + if (strlen(listdata) + strlen(str) > LIST_HEXBIT) { + strcat(listdata, "-"); + list_emit(); + } + if (!listdata[0]) + listoffset = offset; + strcat(listdata, str); +} + +static void list_address(int64_t offset, const char *brackets, + int64_t addr, int size) +{ + char q[20]; + char *r = q; + + nasm_assert(size <= 8); + + *r++ = brackets[0]; + while (size--) { + HEX(r, addr); + addr >>= 8; + r += 2; + } + *r++ = brackets[1]; + *r = '\0'; + list_out(offset, q); +} + +static void list_output(const struct out_data *data) +{ + char q[24]; + uint64_t size = data->size; + uint64_t offset = data->offset; + const uint8_t *p = data->data; + + + if (!listp || suppress || user_nolist) + return; + + switch (data->type) { + case OUT_ZERODATA: + if (size > 16) { + snprintf(q, sizeof(q), "", size); + list_out(offset, q); + break; + } else { + p = zero_buffer; + } + /* fall through */ + case OUT_RAWDATA: + { + if (size == 0 && !listdata[0]) + listoffset = data->offset; + while (size--) { + HEX(q, *p); + q[2] = '\0'; + list_out(offset++, q); + p++; + } + break; + } + case OUT_ADDRESS: + list_address(offset, "[]", data->toffset, size); + break; + case OUT_SEGMENT: + q[0] = '['; + memset(q+1, 's', size << 1); + q[(size << 1)+1] = ']'; + q[(size << 1)+2] = '\0'; + list_out(offset, q); + offset += size; + break; + case OUT_RELADDR: + list_address(offset, "()", data->toffset, size); + break; + case OUT_RESERVE: + { + snprintf(q, sizeof(q), "", size); + list_out(offset, q); + break; + } + default: + panic(); + } +} + +static void list_line(int type, char *line) +{ + if (!listp) + return; + + if (user_nolist) + return; + + if (mistack && mistack->inhibiting) { + if (type == LIST_MACRO) + return; + else { /* pop the m i stack */ + MacroInhibit *temp = mistack; + mistack = temp->next; + nasm_free(temp); + } + } + list_emit(); + listlineno = src_get_linnum(); + listlinep = true; + strncpy(listline, line, LIST_MAX_LEN - 1); + listline[LIST_MAX_LEN - 1] = '\0'; + listlevel_e = listlevel; +} + +static void list_uplevel(int type) +{ + if (!listp) + return; + if (type == LIST_INCBIN || type == LIST_TIMES) { + suppress |= (type == LIST_INCBIN ? 1 : 2); + list_out(listoffset, type == LIST_INCBIN ? "" : ""); + return; + } + + listlevel++; + + if (mistack && mistack->inhibiting && type == LIST_INCLUDE) { + MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit)); + temp->next = mistack; + temp->level = listlevel; + temp->inhibiting = false; + mistack = temp; + } else if (type == LIST_MACRO_NOLIST) { + MacroInhibit *temp = nasm_malloc(sizeof(MacroInhibit)); + temp->next = mistack; + temp->level = listlevel; + temp->inhibiting = true; + mistack = temp; + } +} + +static void list_downlevel(int type) +{ + if (!listp) + return; + + if (type == LIST_INCBIN || type == LIST_TIMES) { + suppress &= ~(type == LIST_INCBIN ? 1 : 2); + return; + } + + listlevel--; + while (mistack && mistack->level > listlevel) { + MacroInhibit *temp = mistack; + mistack = temp->next; + nasm_free(temp); + } +} + +static void list_error(int severity, const char *pfx, const char *msg) +{ + if (!listfp) + return; + + snprintf(listerror, sizeof listerror, "%s%s", pfx, msg); + + if ((severity & ERR_MASK) >= ERR_FATAL) + list_emit(); +} + +static void list_set_offset(uint64_t offset) +{ + listoffset = offset; +} + +static const struct lfmt nasm_list = { + list_init, + list_cleanup, + list_output, + list_line, + list_uplevel, + list_downlevel, + list_error, + list_set_offset +}; + +const struct lfmt *lfmt = &nasm_list; diff --git a/asm/listing.h b/asm/listing.h new file mode 100644 index 0000000..df88e8a --- /dev/null +++ b/asm/listing.h @@ -0,0 +1,113 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * listing.h header file for listing.c + */ + +#ifndef NASM_LISTING_H +#define NASM_LISTING_H + +/* + * List-file generators should look like this: + */ +struct lfmt { + /* + * Called to initialize the listing file generator. Before this + * is called, the other routines will silently do nothing when + * called. The `char *' parameter is the file name to write the + * listing to. + */ + void (*init)(const char *fname); + + /* + * Called to clear stuff up and close the listing file. + */ + void (*cleanup)(void); + + /* + * Called to output binary data. Parameters are: the offset; + * the data; the data type. Data types are similar to the + * output-format interface, only OUT_ADDRESS will _always_ be + * displayed as if it's relocatable, so ensure that any non- + * relocatable address has been converted to OUT_RAWDATA by + * then. + */ + void (*output)(const struct out_data *data); + + /* + * Called to send a text line to the listing generator. The + * `int' parameter is LIST_READ or LIST_MACRO depending on + * whether the line came directly from an input file or is the + * result of a multi-line macro expansion. + */ + void (*line)(int type, char *line); + + /* + * Called to change one of the various levelled mechanisms in + * the listing generator. LIST_INCLUDE and LIST_MACRO can be + * used to increase the nesting level of include files and + * macro expansions; LIST_TIMES and LIST_INCBIN switch on the + * two binary-output-suppression mechanisms for large-scale + * pseudo-instructions. + * + * LIST_MACRO_NOLIST is synonymous with LIST_MACRO except that + * it indicates the beginning of the expansion of a `nolist' + * macro, so anything under that level won't be expanded unless + * it includes another file. + */ + void (*uplevel)(int type); + + /* + * Reverse the effects of uplevel. + */ + void (*downlevel)(int type); + + /* + * Called on a warning or error, with the error message. + */ + void (*error)(int severity, const char *pfx, const char *msg); + + /* + * Update the current offset. Used to give the listing generator + * an offset to work with when doing things like + * uplevel(LIST_TIMES) or uplevel(LIST_INCBIN); see + * list_set_offset(); + */ + void (*set_offset)(uint64_t offset); +}; + +extern const struct lfmt *lfmt; +extern bool user_nolist; + +#endif diff --git a/asm/nasm.c b/asm/nasm.c new file mode 100644 index 0000000..ae90b89 --- /dev/null +++ b/asm/nasm.c @@ -0,0 +1,2011 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * The Netwide Assembler main program module + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "saa.h" +#include "raa.h" +#include "float.h" +#include "stdscan.h" +#include "insns.h" +#include "preproc.h" +#include "parser.h" +#include "eval.h" +#include "assemble.h" +#include "labels.h" +#include "outform.h" +#include "listing.h" +#include "iflag.h" +#include "ver.h" + +/* + * This is the maximum number of optimization passes to do. If we ever + * find a case where the optimizer doesn't naturally converge, we might + * have to drop this value so the assembler doesn't appear to just hang. + */ +#define MAX_OPTIMIZE (INT_MAX >> 1) + +struct forwrefinfo { /* info held on forward refs. */ + int lineno; + int operand; +}; + +static void parse_cmdline(int, char **, int); +static void assemble_file(const char *, StrList **); +static bool is_suppressed_warning(int severity); +static bool skip_this_pass(int severity); +static void nasm_verror_gnu(int severity, const char *fmt, va_list args); +static void nasm_verror_vc(int severity, const char *fmt, va_list args); +static void nasm_verror_common(int severity, const char *fmt, va_list args); +static void usage(void); +static void help(char xopt); + +static bool using_debug_info, opt_verbose_info; +static const char *debug_format; + +#ifndef ABORT_ON_PANIC +# define ABORT_ON_PANIC 0 +#endif +static bool abort_on_panic = ABORT_ON_PANIC; +static bool keep_all; + +bool tasm_compatible_mode = false; +int pass0; +int64_t passn; +static int pass1, pass2; /* XXX: Get rid of these, they are redundant */ +int globalrel = 0; +int globalbnd = 0; + +struct compile_time official_compile_time; + +const char *inname; +const char *outname; +static const char *listname; +static const char *errname; + +static int64_t globallineno; /* for forward-reference tracking */ + +/* static int pass = 0; */ +const struct ofmt *ofmt = &OF_DEFAULT; +const struct ofmt_alias *ofmt_alias = NULL; +const struct dfmt *dfmt; + +static FILE *error_file; /* Where to write error messages */ + +FILE *ofile = NULL; +struct optimization optimizing = + { MAX_OPTIMIZE, OPTIM_ALL_ENABLED }; /* number of optimization passes to take */ +static int cmd_sb = 16; /* by default */ + +iflag_t cpu; +static iflag_t cmd_cpu; + +struct location location; +bool in_absolute; /* Flag we are in ABSOLUTE seg */ +struct location absolute; /* Segment/offset inside ABSOLUTE */ + +static struct RAA *offsets; + +static struct SAA *forwrefs; /* keep track of forward references */ +static const struct forwrefinfo *forwref; + +static const struct preproc_ops *preproc; + +#define OP_NORMAL (1u << 0) +#define OP_PREPROCESS (1u << 1) +#define OP_DEPEND (1u << 2) + +static unsigned int operating_mode; + +/* Dependency flags */ +static bool depend_emit_phony = false; +static bool depend_missing_ok = false; +static const char *depend_target = NULL; +static const char *depend_file = NULL; +StrList *depend_list; + +static bool want_usage; +static bool terminate_after_phase; +bool user_nolist = false; + +static char *quote_for_pmake(const char *str); +static char *quote_for_wmake(const char *str); +static char *(*quote_for_make)(const char *) = quote_for_pmake; + +/* + * Execution limits that can be set via a command-line option or %pragma + */ + +#define LIMIT_MAX_VAL (INT64_MAX >> 1) /* Effectively unlimited */ + +int64_t nasm_limit[LIMIT_MAX+1] = +{ LIMIT_MAX_VAL, 1000, 1000000, 1000000, 1000000, 2000000000 }; + +struct limit_info { + const char *name; + const char *help; +}; +static const struct limit_info limit_info[LIMIT_MAX+1] = { + { "passes", "total number of passes" }, + { "stalled-passes", "number of passes without forward progress" }, + { "macro-levels", "levels of macro expansion"}, + { "rep", "%rep count" }, + { "eval", "expression evaluation descent"}, + { "lines", "total source lines processed"} +}; + +enum directive_result +nasm_set_limit(const char *limit, const char *valstr) +{ + int i; + int64_t val; + bool rn_error; + int errlevel; + + for (i = 0; i <= LIMIT_MAX; i++) { + if (!nasm_stricmp(limit, limit_info[i].name)) + break; + } + if (i > LIMIT_MAX) { + if (passn == 0) + errlevel = ERR_WARNING|ERR_NOFILE|ERR_USAGE; + else + errlevel = ERR_WARNING|ERR_PASS1|ERR_WARN_UNKNOWN_PRAGMA; + nasm_error(errlevel, "unknown limit: `%s'", limit); + return DIRR_ERROR; + } + + if (!nasm_stricmp(valstr, "unlimited")) { + val = LIMIT_MAX_VAL; + } else { + val = readnum(valstr, &rn_error); + if (rn_error || val < 0) { + if (passn == 0) + errlevel = ERR_WARNING|ERR_NOFILE|ERR_USAGE; + else + errlevel = ERR_WARNING|ERR_PASS1|ERR_WARN_BAD_PRAGMA; + nasm_error(errlevel, "invalid limit value: `%s'", limit); + return DIRR_ERROR; + } + if (val > LIMIT_MAX_VAL) + val = LIMIT_MAX_VAL; + } + + nasm_limit[i] = val; + return DIRR_OK; +} + +int64_t switch_segment(int32_t segment) +{ + location.segment = segment; + if (segment == NO_SEG) { + location.offset = absolute.offset; + in_absolute = true; + } else { + location.offset = raa_read(offsets, segment); + in_absolute = false; + } + return location.offset; +} + +static void set_curr_offs(int64_t l_off) +{ + if (in_absolute) + absolute.offset = l_off; + else + offsets = raa_write(offsets, location.segment, l_off); +} + +static void increment_offset(int64_t delta) +{ + if (unlikely(delta == 0)) + return; + + location.offset += delta; + set_curr_offs(location.offset); +} + +static void nasm_fputs(const char *line, FILE * outfile) +{ + if (outfile) { + fputs(line, outfile); + putc('\n', outfile); + } else + puts(line); +} + +static void define_macros_early(void) +{ + const struct compile_time * const oct = &official_compile_time; + char temp[128]; + + if (oct->have_local) { + strftime(temp, sizeof temp, "__DATE__=\"%Y-%m-%d\"", &oct->local); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__DATE_NUM__=%Y%m%d", &oct->local); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__TIME__=\"%H:%M:%S\"", &oct->local); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__TIME_NUM__=%H%M%S", &oct->local); + preproc->pre_define(temp); + } + + if (oct->have_gm) { + strftime(temp, sizeof temp, "__UTC_DATE__=\"%Y-%m-%d\"", &oct->gm); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__UTC_DATE_NUM__=%Y%m%d", &oct->gm); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__UTC_TIME__=\"%H:%M:%S\"", &oct->gm); + preproc->pre_define(temp); + strftime(temp, sizeof temp, "__UTC_TIME_NUM__=%H%M%S", &oct->gm); + preproc->pre_define(temp); + } + + if (oct->have_posix) { + snprintf(temp, sizeof temp, "__POSIX_TIME__=%"PRId64, oct->posix); + preproc->pre_define(temp); + } +} + +static void define_macros_late(void) +{ + char temp[128]; + + /* + * In case if output format is defined by alias + * we have to put shortname of the alias itself here + * otherwise ABI backward compatibility gets broken. + */ + snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s", + ofmt_alias ? ofmt_alias->shortname : ofmt->shortname); + preproc->pre_define(temp); +} + +static void emit_dependencies(StrList *list) +{ + FILE *deps; + int linepos, len; + StrList *l, *nl; + bool wmake = (quote_for_make == quote_for_wmake); + const char *wrapstr, *nulltarget; + + wrapstr = wmake ? " &\n " : " \\\n "; + nulltarget = wmake ? "\t%null\n" : ""; + + if (depend_file && strcmp(depend_file, "-")) { + deps = nasm_open_write(depend_file, NF_TEXT); + if (!deps) { + nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE, + "unable to write dependency file `%s'", depend_file); + return; + } + } else { + deps = stdout; + } + + linepos = fprintf(deps, "%s :", depend_target); + list_for_each(l, list) { + char *file = quote_for_make(l->str); + len = strlen(file); + if (linepos + len > 62 && linepos > 1) { + fputs(wrapstr, deps); + linepos = 1; + } + fprintf(deps, " %s", file); + linepos += len+1; + nasm_free(file); + } + fprintf(deps, "\n\n"); + + list_for_each_safe(l, nl, list) { + if (depend_emit_phony) { + char *file = quote_for_make(l->str); + fprintf(deps, "%s :\n%s\n", file, nulltarget); + nasm_free(file); + } + nasm_free(l); + } + + if (deps != stdout) + fclose(deps); +} + +/* Convert a struct tm to a POSIX-style time constant */ +static int64_t make_posix_time(const struct tm *tm) +{ + int64_t t; + int64_t y = tm->tm_year; + + /* See IEEE 1003.1:2004, section 4.14 */ + + t = (y-70)*365 + (y-69)/4 - (y-1)/100 + (y+299)/400; + t += tm->tm_yday; + t *= 24; + t += tm->tm_hour; + t *= 60; + t += tm->tm_min; + t *= 60; + t += tm->tm_sec; + + return t; +} + +static void timestamp(void) +{ + struct compile_time * const oct = &official_compile_time; + const struct tm *tp, *best_gm; + + time(&oct->t); + + best_gm = NULL; + + tp = localtime(&oct->t); + if (tp) { + oct->local = *tp; + best_gm = &oct->local; + oct->have_local = true; + } + + tp = gmtime(&oct->t); + if (tp) { + oct->gm = *tp; + best_gm = &oct->gm; + oct->have_gm = true; + if (!oct->have_local) + oct->local = oct->gm; + } else { + oct->gm = oct->local; + } + + if (best_gm) { + oct->posix = make_posix_time(best_gm); + oct->have_posix = true; + } +} + +int main(int argc, char **argv) +{ + StrList **depend_ptr; + + timestamp(); + + iflag_set_default_cpu(&cpu); + iflag_set_default_cpu(&cmd_cpu); + + pass0 = 0; + want_usage = terminate_after_phase = false; + nasm_set_verror(nasm_verror_gnu); + + error_file = stderr; + + tolower_init(); + src_init(); + + /* + * We must call init_labels() before the command line parsing, + * because we may be setting prefixes/suffixes from the command + * line. + */ + init_labels(); + + offsets = raa_init(); + forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo)); + + preproc = &nasmpp; + operating_mode = OP_NORMAL; + + parse_cmdline(argc, argv, 1); + if (terminate_after_phase) { + if (want_usage) + usage(); + return 1; + } + + /* + * Define some macros dependent on the runtime, but not + * on the command line (as those are scanned in cmdline pass 2.) + */ + preproc->init(); + define_macros_early(); + + parse_cmdline(argc, argv, 2); + if (terminate_after_phase) { + if (want_usage) + usage(); + return 1; + } + + /* Save away the default state of warnings */ + memcpy(warning_state_init, warning_state, sizeof warning_state); + + if (!using_debug_info) { + /* No debug info, redirect to the null backend (empty stubs) */ + dfmt = &null_debug_form; + } else if (!debug_format) { + /* Default debug format for this backend */ + dfmt = ofmt->default_dfmt; + } else { + dfmt = dfmt_find(ofmt, debug_format); + if (!dfmt) { + nasm_fatal(ERR_NOFILE | ERR_USAGE, + "unrecognized debug format `%s' for" + " output format `%s'", + debug_format, ofmt->shortname); + } + } + + if (ofmt->stdmac) + preproc->extra_stdmac(ofmt->stdmac); + + /* + * If no output file name provided and this + * is a preprocess mode, we're perfectly + * fine to output into stdout. + */ + if (!outname) { + if (!(operating_mode & OP_PREPROCESS)) + outname = filename_set_extension(inname, ofmt->extension); + } + + /* define some macros dependent of command-line */ + define_macros_late(); + + depend_ptr = (depend_file || (operating_mode & OP_DEPEND)) ? &depend_list : NULL; + + if (!depend_target) + depend_target = quote_for_make(outname); + + if (operating_mode & OP_DEPEND) { + char *line; + + if (depend_missing_ok) + preproc->include_path(NULL); /* "assume generated" */ + + preproc->reset(inname, 0, depend_ptr); + ofile = NULL; + while ((line = preproc->getline())) + nasm_free(line); + preproc->cleanup(0); + } else if (operating_mode & OP_PREPROCESS) { + char *line; + const char *file_name = NULL; + int32_t prior_linnum = 0; + int lineinc = 0; + + if (outname) { + ofile = nasm_open_write(outname, NF_TEXT); + if (!ofile) + nasm_fatal(ERR_NOFILE, + "unable to open output file `%s'", + outname); + } else + ofile = NULL; + + location.known = false; + + /* pass = 1; */ + preproc->reset(inname, 3, depend_ptr); + + /* Revert all warnings to the default state */ + memcpy(warning_state, warning_state_init, sizeof warning_state); + + while ((line = preproc->getline())) { + /* + * We generate %line directives if needed for later programs + */ + int32_t linnum = prior_linnum += lineinc; + int altline = src_get(&linnum, &file_name); + if (altline) { + if (altline == 1 && lineinc == 1) + nasm_fputs("", ofile); + else { + lineinc = (altline != -1 || lineinc != 1); + fprintf(ofile ? ofile : stdout, + "%%line %"PRId32"+%d %s\n", linnum, lineinc, + file_name); + } + prior_linnum = linnum; + } + nasm_fputs(line, ofile); + nasm_free(line); + } + preproc->cleanup(0); + if (ofile) + fclose(ofile); + if (ofile && terminate_after_phase && !keep_all) + remove(outname); + ofile = NULL; + } + + if (operating_mode & OP_NORMAL) { + ofile = nasm_open_write(outname, (ofmt->flags & OFMT_TEXT) ? NF_TEXT : NF_BINARY); + if (!ofile) + nasm_fatal(ERR_NOFILE, + "unable to open output file `%s'", outname); + + ofmt->init(); + dfmt->init(); + + assemble_file(inname, depend_ptr); + + if (!terminate_after_phase) { + ofmt->cleanup(); + cleanup_labels(); + fflush(ofile); + if (ferror(ofile)) { + nasm_error(ERR_NONFATAL|ERR_NOFILE, + "write error on output file `%s'", outname); + terminate_after_phase = true; + } + } + + if (ofile) { + fclose(ofile); + if (terminate_after_phase && !keep_all) + remove(outname); + ofile = NULL; + } + } + + if (depend_list && !terminate_after_phase) + emit_dependencies(depend_list); + + if (want_usage) + usage(); + + raa_free(offsets); + saa_free(forwrefs); + eval_cleanup(); + stdscan_cleanup(); + src_free(); + + return terminate_after_phase; +} + +/* + * Get a parameter for a command line option. + * First arg must be in the form of e.g. -f... + */ +static char *get_param(char *p, char *q, bool *advance) +{ + *advance = false; + if (p[2]) /* the parameter's in the option */ + return nasm_skip_spaces(p + 2); + if (q && q[0]) { + *advance = true; + return q; + } + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "option `-%c' requires an argument", p[1]); + return NULL; +} + +/* + * Copy a filename + */ +static void copy_filename(const char **dst, const char *src, const char *what) +{ + if (*dst) + nasm_fatal(0, "more than one %s file specified: %s\n", what, src); + + *dst = nasm_strdup(src); +} + +/* + * Convert a string to a POSIX make-safe form + */ +static char *quote_for_pmake(const char *str) +{ + const char *p; + char *os, *q; + + size_t n = 1; /* Terminating zero */ + size_t nbs = 0; + + if (!str) + return NULL; + + for (p = str; *p; p++) { + switch (*p) { + case ' ': + case '\t': + /* Convert N backslashes + ws -> 2N+1 backslashes + ws */ + n += nbs + 2; + nbs = 0; + break; + case '$': + case '#': + nbs = 0; + n += 2; + break; + case '\\': + nbs++; + n++; + break; + default: + nbs = 0; + n++; + break; + } + } + + /* Convert N backslashes at the end of filename to 2N backslashes */ + if (nbs) + n += nbs; + + os = q = nasm_malloc(n); + + nbs = 0; + for (p = str; *p; p++) { + switch (*p) { + case ' ': + case '\t': + while (nbs--) + *q++ = '\\'; + *q++ = '\\'; + *q++ = *p; + break; + case '$': + *q++ = *p; + *q++ = *p; + nbs = 0; + break; + case '#': + *q++ = '\\'; + *q++ = *p; + nbs = 0; + break; + case '\\': + *q++ = *p; + nbs++; + break; + default: + *q++ = *p; + nbs = 0; + break; + } + } + while (nbs--) + *q++ = '\\'; + + *q = '\0'; + + return os; +} + +/* + * Convert a string to a Watcom make-safe form + */ +static char *quote_for_wmake(const char *str) +{ + const char *p; + char *os, *q; + bool quote = false; + + size_t n = 1; /* Terminating zero */ + + if (!str) + return NULL; + + for (p = str; *p; p++) { + switch (*p) { + case ' ': + case '\t': + case '&': + quote = true; + n++; + break; + case '\"': + quote = true; + n += 2; + break; + case '$': + case '#': + n += 2; + break; + default: + n++; + break; + } + } + + if (quote) + n += 2; + + os = q = nasm_malloc(n); + + if (quote) + *q++ = '\"'; + + for (p = str; *p; p++) { + switch (*p) { + case '$': + case '#': + *q++ = '$'; + *q++ = *p; + break; + case '\"': + *q++ = *p; + *q++ = *p; + break; + default: + *q++ = *p; + break; + } + } + + if (quote) + *q++ = '\"'; + + *q = '\0'; + + return os; +} + +enum text_options { + OPT_BOGUS, + OPT_VERSION, + OPT_HELP, + OPT_ABORT_ON_PANIC, + OPT_MANGLE, + OPT_INCLUDE, + OPT_PRAGMA, + OPT_BEFORE, + OPT_LIMIT, + OPT_KEEP_ALL +}; +struct textargs { + const char *label; + enum text_options opt; + bool need_arg; + int pvt; +}; +static const struct textargs textopts[] = { + {"v", OPT_VERSION, false, 0}, + {"version", OPT_VERSION, false, 0}, + {"help", OPT_HELP, false, 0}, + {"abort-on-panic", OPT_ABORT_ON_PANIC, false, 0}, + {"prefix", OPT_MANGLE, true, LM_GPREFIX}, + {"postfix", OPT_MANGLE, true, LM_GSUFFIX}, + {"gprefix", OPT_MANGLE, true, LM_GPREFIX}, + {"gpostfix", OPT_MANGLE, true, LM_GSUFFIX}, + {"lprefix", OPT_MANGLE, true, LM_LPREFIX}, + {"lpostfix", OPT_MANGLE, true, LM_LSUFFIX}, + {"include", OPT_INCLUDE, true, 0}, + {"pragma", OPT_PRAGMA, true, 0}, + {"before", OPT_BEFORE, true, 0}, + {"limit-", OPT_LIMIT, true, 0}, + {"keep-all", OPT_KEEP_ALL, false, 0}, + {NULL, OPT_BOGUS, false, 0} +}; + +static void show_version(void) +{ + printf("NASM version %s compiled on %s%s\n", + nasm_version, nasm_date, nasm_compile_options); + exit(0); +} + +static bool stopoptions = false; +static bool process_arg(char *p, char *q, int pass) +{ + char *param; + bool advance = false; + + if (!p || !p[0]) + return false; + + if (p[0] == '-' && !stopoptions) { + if (strchr("oOfpPdDiIlFXuUZwW", p[1])) { + /* These parameters take values */ + if (!(param = get_param(p, q, &advance))) + return advance; + } + + switch (p[1]) { + case 's': + if (pass == 1) + error_file = stdout; + break; + + case 'o': /* output file */ + if (pass == 2) + copy_filename(&outname, param, "output"); + break; + + case 'f': /* output format */ + if (pass == 1) { + ofmt = ofmt_find(param, &ofmt_alias); + if (!ofmt) { + nasm_fatal(ERR_NOFILE | ERR_USAGE, + "unrecognised output format `%s' - " + "use -hf for a list", param); + } + } + break; + + case 'O': /* Optimization level */ + if (pass == 2) { + int opt; + + if (!*param) { + /* Naked -O == -Ox */ + optimizing.level = MAX_OPTIMIZE; + } else { + while (*param) { + switch (*param) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + opt = strtoul(param, ¶m, 10); + + /* -O0 -> optimizing.level == -1, 0.98 behaviour */ + /* -O1 -> optimizing.level == 0, 0.98.09 behaviour */ + if (opt < 2) + optimizing.level = opt - 1; + else + optimizing.level = opt; + break; + + case 'v': + case '+': + param++; + opt_verbose_info = true; + break; + + case 'x': + param++; + optimizing.level = MAX_OPTIMIZE; + break; + + default: + nasm_fatal(0, + "unknown optimization option -O%c\n", + *param); + break; + } + } + if (optimizing.level > MAX_OPTIMIZE) + optimizing.level = MAX_OPTIMIZE; + } + } + break; + + case 'p': /* pre-include */ + case 'P': + if (pass == 2) + preproc->pre_include(param); + break; + + case 'd': /* pre-define */ + case 'D': + if (pass == 2) + preproc->pre_define(param); + break; + + case 'u': /* un-define */ + case 'U': + if (pass == 2) + preproc->pre_undefine(param); + break; + + case 'i': /* include search path */ + case 'I': + if (pass == 2) + preproc->include_path(param); + break; + + case 'l': /* listing file */ + if (pass == 2) + copy_filename(&listname, param, "listing"); + break; + + case 'Z': /* error messages file */ + if (pass == 1) + copy_filename(&errname, param, "error"); + break; + + case 'F': /* specify debug format */ + if (pass == 2) { + using_debug_info = true; + debug_format = param; + } + break; + + case 'X': /* specify error reporting format */ + if (pass == 1) { + if (nasm_stricmp("vc", param) == 0) + nasm_set_verror(nasm_verror_vc); + else if (nasm_stricmp("gnu", param) == 0) + nasm_set_verror(nasm_verror_gnu); + else + nasm_fatal(ERR_NOFILE | ERR_USAGE, + "unrecognized error reporting format `%s'", + param); + } + break; + + case 'g': + if (pass == 2) { + using_debug_info = true; + if (p[2]) + debug_format = nasm_skip_spaces(p + 2); + } + break; + + case 'h': + help(p[2]); + exit(0); /* never need usage message here */ + break; + + case 'y': + printf("\nvalid debug formats for '%s' output format are" + " ('*' denotes default):\n", ofmt->shortname); + dfmt_list(ofmt, stdout); + exit(0); + break; + + case 't': + if (pass == 2) + tasm_compatible_mode = true; + break; + + case 'v': + show_version(); + break; + + case 'e': /* preprocess only */ + case 'E': + if (pass == 1) + operating_mode = OP_PREPROCESS; + break; + + case 'a': /* assemble only - don't preprocess */ + if (pass == 1) + preproc = &preproc_nop; + break; + + case 'w': + case 'W': + if (pass == 2) { + if (!set_warning_status(param)) { + nasm_error(ERR_WARNING|ERR_NOFILE|ERR_WARN_UNK_WARNING, + "unknown warning option: %s", param); + } + } + break; + + case 'M': + if (pass == 1) { + switch (p[2]) { + case 'W': + quote_for_make = quote_for_wmake; + break; + case 'D': + case 'F': + case 'T': + case 'Q': + advance = true; + break; + default: + break; + } + } else { + switch (p[2]) { + case 0: + operating_mode = OP_DEPEND; + break; + case 'G': + operating_mode = OP_DEPEND; + depend_missing_ok = true; + break; + case 'P': + depend_emit_phony = true; + break; + case 'D': + operating_mode = OP_NORMAL; + depend_file = q; + advance = true; + break; + case 'F': + depend_file = q; + advance = true; + break; + case 'T': + depend_target = q; + advance = true; + break; + case 'Q': + depend_target = quote_for_make(q); + advance = true; + break; + case 'W': + /* handled in pass 1 */ + break; + default: + nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE, + "unknown dependency option `-M%c'", p[2]); + break; + } + } + if (advance && (!q || !q[0])) { + nasm_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE, + "option `-M%c' requires a parameter", p[2]); + break; + } + break; + + case '-': + { + const struct textargs *tx; + size_t olen, plen; + char *eqsave; + + p += 2; + + if (!*p) { /* -- => stop processing options */ + stopoptions = true; + break; + } + + plen = strlen(p); + for (tx = textopts; tx->label; tx++) { + olen = strlen(tx->label); + + if (olen > plen) + continue; + + if (nasm_memicmp(p, tx->label, olen)) + continue; + + if (tx->label[olen-1] == '-') + break; /* Incomplete option */ + + if (!p[olen] || p[olen] == '=') + break; /* Complete option */ + } + + if (!tx->label) { + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "unrecognized option `--%s'", p); + } + + eqsave = param = strchr(p+olen, '='); + if (param) + *param++ = '\0'; + + if (tx->need_arg) { + if (!param) { + param = q; + advance = true; + } + + /* Note: a null string is a valid parameter */ + if (!param) { + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "option `--%s' requires an argument", + p); + break; + } + } else { + if (param) { + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "option `--%s' does not take an argument", + p); + + } + } + + switch (tx->opt) { + case OPT_VERSION: + show_version(); + break; + case OPT_ABORT_ON_PANIC: + abort_on_panic = true; + break; + case OPT_MANGLE: + if (pass == 2) + set_label_mangle(tx->pvt, param); + break; + case OPT_INCLUDE: + if (pass == 2) + preproc->pre_include(q); + break; + case OPT_PRAGMA: + if (pass == 2) + preproc->pre_command("pragma", param); + break; + case OPT_BEFORE: + if (pass == 2) + preproc->pre_command(NULL, param); + break; + case OPT_LIMIT: + if (pass == 2) + nasm_set_limit(p+olen, param); + break; + case OPT_KEEP_ALL: + keep_all = true; + break; + case OPT_HELP: + help(0); + exit(0); + default: + panic(); + } + + if (eqsave) + *eqsave = '='; /* Restore = argument separator */ + + break; + } + + default: + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "unrecognised option `-%c'", p[1]); + break; + } + } else if (pass == 2) { + /* In theory we could allow multiple input files... */ + copy_filename(&inname, p, "input"); + } + + return advance; +} + +#define ARG_BUF_DELTA 128 + +static void process_respfile(FILE * rfile, int pass) +{ + char *buffer, *p, *q, *prevarg; + int bufsize, prevargsize; + + bufsize = prevargsize = ARG_BUF_DELTA; + buffer = nasm_malloc(ARG_BUF_DELTA); + prevarg = nasm_malloc(ARG_BUF_DELTA); + prevarg[0] = '\0'; + + while (1) { /* Loop to handle all lines in file */ + p = buffer; + while (1) { /* Loop to handle long lines */ + q = fgets(p, bufsize - (p - buffer), rfile); + if (!q) + break; + p += strlen(p); + if (p > buffer && p[-1] == '\n') + break; + if (p - buffer > bufsize - 10) { + int offset; + offset = p - buffer; + bufsize += ARG_BUF_DELTA; + buffer = nasm_realloc(buffer, bufsize); + p = buffer + offset; + } + } + + if (!q && p == buffer) { + if (prevarg[0]) + process_arg(prevarg, NULL, pass); + nasm_free(buffer); + nasm_free(prevarg); + return; + } + + /* + * Play safe: remove CRs, LFs and any spurious ^Zs, if any of + * them are present at the end of the line. + */ + *(p = &buffer[strcspn(buffer, "\r\n\032")]) = '\0'; + + while (p > buffer && nasm_isspace(p[-1])) + *--p = '\0'; + + p = nasm_skip_spaces(buffer); + + if (process_arg(prevarg, p, pass)) + *p = '\0'; + + if ((int) strlen(p) > prevargsize - 10) { + prevargsize += ARG_BUF_DELTA; + prevarg = nasm_realloc(prevarg, prevargsize); + } + strncpy(prevarg, p, prevargsize); + } +} + +/* Function to process args from a string of args, rather than the + * argv array. Used by the environment variable and response file + * processing. + */ +static void process_args(char *args, int pass) +{ + char *p, *q, *arg, *prevarg; + char separator = ' '; + + p = args; + if (*p && *p != '-') + separator = *p++; + arg = NULL; + while (*p) { + q = p; + while (*p && *p != separator) + p++; + while (*p == separator) + *p++ = '\0'; + prevarg = arg; + arg = q; + if (process_arg(prevarg, arg, pass)) + arg = NULL; + } + if (arg) + process_arg(arg, NULL, pass); +} + +static void process_response_file(const char *file, int pass) +{ + char str[2048]; + FILE *f = nasm_open_read(file, NF_TEXT); + if (!f) { + perror(file); + exit(-1); + } + while (fgets(str, sizeof str, f)) { + process_args(str, pass); + } + fclose(f); +} + +static void parse_cmdline(int argc, char **argv, int pass) +{ + FILE *rfile; + char *envreal, *envcopy = NULL, *p; + int i; + + /* Initialize all the warnings to their default state */ + for (i = 0; i < ERR_WARN_ALL; i++) { + warning_state_init[i] = warning_state[i] = + warnings[i].enabled ? WARN_ST_ENABLED : 0; + } + + /* + * First, process the NASMENV environment variable. + */ + envreal = getenv("NASMENV"); + if (envreal) { + envcopy = nasm_strdup(envreal); + process_args(envcopy, pass); + nasm_free(envcopy); + } + + /* + * Now process the actual command line. + */ + while (--argc) { + bool advance; + argv++; + if (argv[0][0] == '@') { + /* + * We have a response file, so process this as a set of + * arguments like the environment variable. This allows us + * to have multiple arguments on a single line, which is + * different to the -@resp file processing below for regular + * NASM. + */ + process_response_file(argv[0]+1, pass); + argc--; + argv++; + } + if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') { + p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &advance); + if (p) { + rfile = nasm_open_read(p, NF_TEXT); + if (rfile) { + process_respfile(rfile, pass); + fclose(rfile); + } else + nasm_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE, + "unable to open response file `%s'", p); + } + } else + advance = process_arg(argv[0], argc > 1 ? argv[1] : NULL, pass); + argv += advance, argc -= advance; + } + + /* + * Look for basic command line typos. This definitely doesn't + * catch all errors, but it might help cases of fumbled fingers. + */ + if (pass != 2) + return; + + if (!inname) + nasm_fatal(ERR_NOFILE | ERR_USAGE, "no input file specified"); + + else if ((errname && !strcmp(inname, errname)) || + (outname && !strcmp(inname, outname)) || + (listname && !strcmp(inname, listname)) || + (depend_file && !strcmp(inname, depend_file))) + nasm_fatal(ERR_USAGE, "will not overwrite input file"); + + if (errname) { + error_file = nasm_open_write(errname, NF_TEXT); + if (!error_file) { + error_file = stderr; /* Revert to default! */ + nasm_fatal(ERR_NOFILE | ERR_USAGE, + "cannot open file `%s' for error messages", + errname); + } + } +} + +static void assemble_file(const char *fname, StrList **depend_ptr) +{ + char *line; + insn output_ins; + int i; + uint64_t prev_offset_changed; + int64_t stall_count = 0; /* Make sure we make forward progress... */ + + switch (cmd_sb) { + case 16: + break; + case 32: + if (!iflag_cpu_level_ok(&cmd_cpu, IF_386)) + nasm_fatal(0, "command line: 32-bit segment size requires a higher cpu"); + break; + case 64: + if (!iflag_cpu_level_ok(&cmd_cpu, IF_X86_64)) + nasm_fatal(0, "command line: 64-bit segment size requires a higher cpu"); + break; + default: + panic(); + break; + } + + prev_offset_changed = nasm_limit[LIMIT_PASSES]; + for (passn = 1; pass0 <= 2; passn++) { + pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */ + pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */ + /* pass0 0, 0, 0, ..., 1, 2 */ + + globalbits = cmd_sb; /* set 'bits' to command line default */ + cpu = cmd_cpu; + if (pass0 == 2) { + lfmt->init(listname); + } else if (passn == 1 && listname && !keep_all) { + /* Remove the list file in case we die before the output pass */ + remove(listname); + } + in_absolute = false; + global_offset_changed = 0; /* set by redefine_label */ + if (passn > 1) { + saa_rewind(forwrefs); + forwref = saa_rstruct(forwrefs); + raa_free(offsets); + offsets = raa_init(); + } + location.segment = NO_SEG; + location.offset = 0; + if (passn == 1) + location.known = true; + ofmt->reset(); + switch_segment(ofmt->section(NULL, pass2, &globalbits)); + preproc->reset(fname, pass1, pass1 == 2 ? depend_ptr : NULL); + + /* Revert all warnings to the default state */ + memcpy(warning_state, warning_state_init, sizeof warning_state); + + globallineno = 0; + + while ((line = preproc->getline())) { + if (++globallineno > nasm_limit[LIMIT_LINES]) + nasm_fatal(0, + "overall line count exceeds the maximum %"PRId64"\n", + nasm_limit[LIMIT_LINES]); + + /* + * Here we parse our directives; this is not handled by the + * main parser. + */ + if (process_directives(line)) + goto end_of_line; /* Just do final cleanup */ + + /* Not a directive, or even something that starts with [ */ + parse_line(pass1, line, &output_ins); + + if (optimizing.level > 0) { + if (forwref != NULL && globallineno == forwref->lineno) { + output_ins.forw_ref = true; + do { + output_ins.oprs[forwref->operand].opflags |= OPFLAG_FORWARD; + forwref = saa_rstruct(forwrefs); + } while (forwref != NULL + && forwref->lineno == globallineno); + } else + output_ins.forw_ref = false; + + if (output_ins.forw_ref) { + if (passn == 1) { + for (i = 0; i < output_ins.operands; i++) { + if (output_ins.oprs[i].opflags & OPFLAG_FORWARD) { + struct forwrefinfo *fwinf = (struct forwrefinfo *)saa_wstruct(forwrefs); + fwinf->lineno = globallineno; + fwinf->operand = i; + } + } + } + } + } + + /* forw_ref */ + if (output_ins.opcode == I_EQU) { + if (!output_ins.label) { + nasm_error(ERR_NONFATAL, "EQU not preceded by label"); + } else if (output_ins.operands == 1 && + (output_ins.oprs[0].type & IMMEDIATE) && + output_ins.oprs[0].wrt == NO_SEG) { + define_label(output_ins.label, + output_ins.oprs[0].segment, + output_ins.oprs[0].offset, false); + } else if (output_ins.operands == 2 + && (output_ins.oprs[0].type & IMMEDIATE) + && (output_ins.oprs[0].type & COLON) + && output_ins.oprs[0].segment == NO_SEG + && output_ins.oprs[0].wrt == NO_SEG + && (output_ins.oprs[1].type & IMMEDIATE) + && output_ins.oprs[1].segment == NO_SEG + && output_ins.oprs[1].wrt == NO_SEG) { + define_label(output_ins.label, + output_ins.oprs[0].offset | SEG_ABS, + output_ins.oprs[1].offset, false); + } else { + nasm_error(ERR_NONFATAL, "bad syntax for EQU"); + } + } else { /* instruction isn't an EQU */ + int32_t n; + + nasm_assert(output_ins.times >= 0); + + for (n = 1; n <= output_ins.times; n++) { + if (pass1 == 1) { + int64_t l = insn_size(location.segment, + location.offset, + globalbits, &output_ins); + + /* if (using_debug_info) && output_ins.opcode != -1) */ + if (using_debug_info) + { /* fbk 03/25/01 */ + /* this is done here so we can do debug type info */ + int32_t typeinfo = + TYS_ELEMENTS(output_ins.operands); + switch (output_ins.opcode) { + case I_RESB: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE; + break; + case I_RESW: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD; + break; + case I_RESD: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD; + break; + case I_RESQ: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD; + break; + case I_REST: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE; + break; + case I_RESO: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_OWORD; + break; + case I_RESY: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_YWORD; + break; + case I_RESZ: + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_ZWORD; + break; + case I_DB: + typeinfo |= TY_BYTE; + break; + case I_DW: + typeinfo |= TY_WORD; + break; + case I_DD: + if (output_ins.eops_float) + typeinfo |= TY_FLOAT; + else + typeinfo |= TY_DWORD; + break; + case I_DQ: + typeinfo |= TY_QWORD; + break; + case I_DT: + typeinfo |= TY_TBYTE; + break; + case I_DO: + typeinfo |= TY_OWORD; + break; + case I_DY: + typeinfo |= TY_YWORD; + break; + case I_DZ: + typeinfo |= TY_ZWORD; + break; + default: + typeinfo = TY_LABEL; + break; + } + + dfmt->debug_typevalue(typeinfo); + } + + /* + * For INCBIN, let the code in assemble + * handle TIMES, so we don't have to read the + * input file over and over. + */ + if (l != -1) { + increment_offset(l); + } + /* + * else l == -1 => invalid instruction, which will be + * flagged as an error on pass 2 + */ + } else { + if (n == 2) + lfmt->uplevel(LIST_TIMES); + increment_offset(assemble(location.segment, + location.offset, + globalbits, &output_ins)); + } + } /* not an EQU */ + } + if (output_ins.times > 1) + lfmt->downlevel(LIST_TIMES); + + cleanup_insn(&output_ins); + + end_of_line: + nasm_free(line); + } /* end while (line = preproc->getline... */ + + if (global_offset_changed && !terminate_after_phase) { + switch (pass0) { + case 1: + nasm_error(ERR_WARNING|ERR_WARN_PHASE, + "phase error during stabilization pass, hoping for the best"); + break; + + case 2: + nasm_error(ERR_NONFATAL, + "phase error during code generation pass"); + break; + + default: + /* This is normal, we'll keep going... */ + break; + } + } + + if (pass1 == 1) + preproc->cleanup(1); + + /* + * Always run at least two optimization passes (pass0 == 0); + * things like subsections will fail miserably without that. + * Once we commit to a stabilization pass (pass0 == 1), we can't + * go back, and if something goes bad, we can only hope + * that we don't end up with a phase error at the end. + */ + if ((passn > 1 && !global_offset_changed) || pass0 > 0) { + pass0++; + } else if (global_offset_changed && + global_offset_changed < prev_offset_changed) { + prev_offset_changed = global_offset_changed; + stall_count = 0; + } else { + stall_count++; + } + + if (terminate_after_phase) + break; + + if ((stall_count > nasm_limit[LIMIT_STALLED]) || + (passn >= nasm_limit[LIMIT_PASSES])) { + /* We get here if the labels don't converge + * Example: FOO equ FOO + 1 + */ + nasm_error(ERR_NONFATAL, + "Can't find valid values for all labels " + "after %"PRId64" passes, giving up.", passn); + nasm_error(ERR_NONFATAL, + "Possible causes: recursive EQUs, macro abuse."); + break; + } + } + + preproc->cleanup(0); + lfmt->cleanup(); + if (!terminate_after_phase && opt_verbose_info) { + /* -On and -Ov switches */ + fprintf(stdout, "info: assembly required 1+%"PRId64"+1 passes\n", + passn-3); + } +} + +/** + * gnu style error reporting + * This function prints an error message to error_file in the + * style used by GNU. An example would be: + * file.asm:50: error: blah blah blah + * where file.asm is the name of the file, 50 is the line number on + * which the error occurs (or is detected) and "error:" is one of + * the possible optional diagnostics -- it can be "error" or "warning" + * or something else. Finally the line terminates with the actual + * error message. + * + * @param severity the severity of the warning or error + * @param fmt the printf style format string + */ +static void nasm_verror_gnu(int severity, const char *fmt, va_list ap) +{ + const char *currentfile = NULL; + int32_t lineno = 0; + + if (is_suppressed_warning(severity)) + return; + + if (!(severity & ERR_NOFILE)) { + src_get(&lineno, ¤tfile); + if (!currentfile || (severity & ERR_TOPFILE)) { + currentfile = inname[0] ? inname : outname[0] ? outname : NULL; + lineno = 0; + } + } + + if (!skip_this_pass(severity)) { + if (!lineno) + fprintf(error_file, "%s:", currentfile ? currentfile : "nasm"); + else + fprintf(error_file, "%s:%"PRId32": ", currentfile, lineno); + } + + nasm_verror_common(severity, fmt, ap); +} + +/** + * MS style error reporting + * This function prints an error message to error_file in the + * style used by Visual C and some other Microsoft tools. An example + * would be: + * file.asm(50) : error: blah blah blah + * where file.asm is the name of the file, 50 is the line number on + * which the error occurs (or is detected) and "error:" is one of + * the possible optional diagnostics -- it can be "error" or "warning" + * or something else. Finally the line terminates with the actual + * error message. + * + * @param severity the severity of the warning or error + * @param fmt the printf style format string + */ +static void nasm_verror_vc(int severity, const char *fmt, va_list ap) +{ + const char *currentfile = NULL; + int32_t lineno = 0; + + if (is_suppressed_warning(severity)) + return; + + if (!(severity & ERR_NOFILE)) + src_get(&lineno, ¤tfile); + + if (!skip_this_pass(severity)) { + if (currentfile) { + fprintf(error_file, "%s(%"PRId32") : ", currentfile, lineno); + } else { + fputs("nasm: ", error_file); + } + } + + nasm_verror_common(severity, fmt, ap); +} + +/* + * check to see if this is a suppressable warning + */ +static inline bool is_valid_warning(int severity) +{ + /* Not a warning at all */ + if ((severity & ERR_MASK) != ERR_WARNING) + return false; + + return WARN_IDX(severity) < ERR_WARN_ALL; +} + +/** + * check for suppressed warning + * checks for suppressed warning or pass one only warning and we're + * not in pass 1 + * + * @param severity the severity of the warning or error + * @return true if we should abort error/warning printing + */ +static bool is_suppressed_warning(int severity) +{ + /* Might be a warning but suppresed explicitly */ + if (is_valid_warning(severity) && !(severity & ERR_USAGE)) + return !(warning_state[WARN_IDX(severity)] & WARN_ST_ENABLED); + else + return false; +} + +static bool warning_is_error(int severity) +{ + if (is_valid_warning(severity)) + return !!(warning_state[WARN_IDX(severity)] & WARN_ST_ERROR); + else + return false; +} + +static bool skip_this_pass(int severity) +{ + /* + * See if it's a pass-specific error or warning which should be skipped. + * We cannot skip errors stronger than ERR_NONFATAL as by definition + * they cannot be resumed from. + */ + if ((severity & ERR_MASK) > ERR_NONFATAL) + return false; + + /* + * passn is 1 on the very first pass only. + * pass0 is 2 on the code-generation (final) pass only. + * These are the passes we care about in this case. + */ + return (((severity & ERR_PASS1) && passn != 1) || + ((severity & ERR_PASS2) && pass0 != 2)); +} + +/** + * common error reporting + * This is the common back end of the error reporting schemes currently + * implemented. It prints the nature of the warning and then the + * specific error message to error_file and may or may not return. It + * doesn't return if the error severity is a "panic" or "debug" type. + * + * @param severity the severity of the warning or error + * @param fmt the printf style format string + */ +static void nasm_verror_common(int severity, const char *fmt, va_list args) +{ + char msg[1024]; + const char *pfx; + + switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) { + case ERR_WARNING: + pfx = "warning: "; + break; + case ERR_NONFATAL: + pfx = "error: "; + break; + case ERR_FATAL: + pfx = "fatal: "; + break; + case ERR_PANIC: + pfx = "panic: "; + break; + case ERR_DEBUG: + pfx = "debug: "; + break; + default: + pfx = ""; + break; + } + + vsnprintf(msg, sizeof msg - 64, fmt, args); + if (is_valid_warning(severity) && WARN_IDX(severity) != ERR_WARN_OTHER) { + char *p = strchr(msg, '\0'); + snprintf(p, 64, " [-w+%s]", warnings[WARN_IDX(severity)].name); + } + + if (!skip_this_pass(severity)) + fprintf(error_file, "%s%s\n", pfx, msg); + + /* Are we recursing from error_list_macros? */ + if (severity & ERR_PP_LISTMACRO) + return; + + /* + * Don't suppress this with skip_this_pass(), or we don't get + * pass1 or preprocessor warnings in the list file + */ + lfmt->error(severity, pfx, msg); + + if (skip_this_pass(severity)) + return; + + if (severity & ERR_USAGE) + want_usage = true; + + preproc->error_list_macros(severity); + + switch (severity & ERR_MASK) { + case ERR_DEBUG: + /* no further action, by definition */ + break; + case ERR_WARNING: + /* Treat warnings as errors */ + if (warning_is_error(severity)) + terminate_after_phase = true; + break; + case ERR_NONFATAL: + terminate_after_phase = true; + break; + case ERR_FATAL: + if (ofile) { + fclose(ofile); + if (!keep_all) + remove(outname); + ofile = NULL; + } + if (want_usage) + usage(); + exit(1); /* instantly die */ + break; /* placate silly compilers */ + case ERR_PANIC: + fflush(NULL); + + if (abort_on_panic) + abort(); /* halt, catch fire, dump core/stop debugger */ + + if (ofile) { + fclose(ofile); + if (!keep_all) + remove(outname); + ofile = NULL; + } + exit(3); + break; + } +} + +static void usage(void) +{ + fputs("type `nasm -h' for help\n", error_file); +} + +static void help(const char xopt) +{ + int i; + + printf + ("usage: nasm [-@ response file] [-o outfile] [-f format] " + "[-l listfile]\n" + " [options...] [--] filename\n" + " or nasm -v (or --v) for version info\n\n" + "\n" + "Response files should contain command line parameters,\n" + "one per line.\n" + "\n" + " -t assemble in SciTech TASM compatible mode\n"); + printf + (" -E (or -e) preprocess only (writes output to stdout by default)\n" + " -a don't preprocess (assemble only)\n" + " -M generate Makefile dependencies on stdout\n" + " -MG d:o, missing files assumed generated\n" + " -MF file set Makefile dependency file\n" + " -MD file assemble and generate dependencies\n" + " -MT file dependency target name\n" + " -MQ file dependency target name (quoted)\n" + " -MP emit phony target\n\n" + " -Zfile redirect error messages to file\n" + " -s redirect error messages to stdout\n\n" + " -g generate debugging information\n\n" + " -F format select a debugging format\n\n" + " -gformat same as -g -F format\n\n" + " -o outfile write output to an outfile\n\n" + " -f format select an output format\n\n" + " -l listfile write listing to a listfile\n\n" + " -Ipath add a pathname to the include file path\n"); + printf + (" -Olevel optimize opcodes, immediates and branch offsets\n" + " -O0 no optimization\n" + " -O1 minimal optimization\n" + " -Ox multipass optimization (default)\n" + " -Pfile pre-include a file (also --include)\n" + " -Dmacro[=str] pre-define a macro\n" + " -Umacro undefine a macro\n" + " -Xformat specifiy error reporting format (gnu or vc)\n" + " -w+foo enable warning foo (equiv. -Wfoo)\n" + " -w-foo disable warning foo (equiv. -Wno-foo)\n" + " -w[+-]error[=foo]\n" + " promote [specific] warnings to errors\n" + " -h show invocation summary and exit (also --help)\n\n" + " --pragma str pre-executes a specific %%pragma\n" + " --before str add line (usually a preprocessor statement) before the input\n" + " --prefix str prepend the given string to all the given string\n" + " to all extern, common and global symbols (also --gprefix)\n" + " --postfix str append the given string to all the given string\n" + " to all extern, common and global symbols (also --gpostfix)\n" + " --lprefix str prepend the given string to all other symbols\n" + " --lpostfix str append the given string to all other symbols\n" + " --keep-all output files will not be removed even if an error happens\n" + " --limit-X val set execution limit X\n"); + + for (i = 0; i <= LIMIT_MAX; i++) { + printf(" %-15s %s (default ", + limit_info[i].name, limit_info[i].help); + if (nasm_limit[i] < LIMIT_MAX_VAL) { + printf("%"PRId64")\n", nasm_limit[i]); + } else { + printf("unlimited)\n"); + } + } + + printf("\nWarnings for the -W/-w options:\n"); + + for (i = 0; i <= ERR_WARN_ALL; i++) + printf(" %-23s %s%s\n", + warnings[i].name, warnings[i].help, + i == ERR_WARN_ALL ? "\n" : + warnings[i].enabled ? " (default on)" : + " (default off)"); + + if (xopt == 'f') { + printf("valid output formats for -f are" + " (`*' denotes default):\n"); + ofmt_list(ofmt, stdout); + } else { + printf("For a list of valid output formats, use -hf.\n"); + printf("For a list of debug formats, use -f -y.\n"); + } +} diff --git a/asm/parser.c b/asm/parser.c new file mode 100644 index 0000000..297af26 --- /dev/null +++ b/asm/parser.c @@ -0,0 +1,1208 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * parser.c source line parser for the Netwide Assembler + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "insns.h" +#include "nasmlib.h" +#include "error.h" +#include "stdscan.h" +#include "eval.h" +#include "parser.h" +#include "float.h" +#include "assemble.h" +#include "tables.h" + + +static int is_comma_next(void); + +static struct tokenval tokval; + +static int prefix_slot(int prefix) +{ + switch (prefix) { + case P_WAIT: + return PPS_WAIT; + case R_CS: + case R_DS: + case R_SS: + case R_ES: + case R_FS: + case R_GS: + return PPS_SEG; + case P_LOCK: + return PPS_LOCK; + case P_REP: + case P_REPE: + case P_REPZ: + case P_REPNE: + case P_REPNZ: + case P_XACQUIRE: + case P_XRELEASE: + case P_BND: + case P_NOBND: + return PPS_REP; + case P_O16: + case P_O32: + case P_O64: + case P_OSP: + return PPS_OSIZE; + case P_A16: + case P_A32: + case P_A64: + case P_ASP: + return PPS_ASIZE; + case P_EVEX: + case P_VEX3: + case P_VEX2: + return PPS_VEX; + default: + nasm_panic(0, "Invalid value %d passed to prefix_slot()", prefix); + return -1; + } +} + +static void process_size_override(insn *result, operand *op) +{ + if (tasm_compatible_mode) { + switch (tokval.t_integer) { + /* For TASM compatibility a size override inside the + * brackets changes the size of the operand, not the + * address type of the operand as it does in standard + * NASM syntax. Hence: + * + * mov eax,[DWORD val] + * + * is valid syntax in TASM compatibility mode. Note that + * you lose the ability to override the default address + * type for the instruction, but we never use anything + * but 32-bit flat model addressing in our code. + */ + case S_BYTE: + op->type |= BITS8; + break; + case S_WORD: + op->type |= BITS16; + break; + case S_DWORD: + case S_LONG: + op->type |= BITS32; + break; + case S_QWORD: + op->type |= BITS64; + break; + case S_TWORD: + op->type |= BITS80; + break; + case S_OWORD: + op->type |= BITS128; + break; + default: + nasm_error(ERR_NONFATAL, + "invalid operand size specification"); + break; + } + } else { + /* Standard NASM compatible syntax */ + switch (tokval.t_integer) { + case S_NOSPLIT: + op->eaflags |= EAF_TIMESTWO; + break; + case S_REL: + op->eaflags |= EAF_REL; + break; + case S_ABS: + op->eaflags |= EAF_ABS; + break; + case S_BYTE: + op->disp_size = 8; + op->eaflags |= EAF_BYTEOFFS; + break; + case P_A16: + case P_A32: + case P_A64: + if (result->prefixes[PPS_ASIZE] && + result->prefixes[PPS_ASIZE] != tokval.t_integer) + nasm_error(ERR_NONFATAL, + "conflicting address size specifications"); + else + result->prefixes[PPS_ASIZE] = tokval.t_integer; + break; + case S_WORD: + op->disp_size = 16; + op->eaflags |= EAF_WORDOFFS; + break; + case S_DWORD: + case S_LONG: + op->disp_size = 32; + op->eaflags |= EAF_WORDOFFS; + break; + case S_QWORD: + op->disp_size = 64; + op->eaflags |= EAF_WORDOFFS; + break; + default: + nasm_error(ERR_NONFATAL, "invalid size specification in" + " effective address"); + break; + } + } +} + +/* + * Brace decorators are are parsed here. opmask and zeroing + * decorators can be placed in any order. e.g. zmm1 {k2}{z} or zmm2 + * {z}{k3} decorator(s) are placed at the end of an operand. + */ +static bool parse_braces(decoflags_t *decoflags) +{ + int i, j; + + i = tokval.t_type; + + while (true) { + switch (i) { + case TOKEN_OPMASK: + if (*decoflags & OPMASK_MASK) { + nasm_error(ERR_NONFATAL, + "opmask k%"PRIu64" is already set", + *decoflags & OPMASK_MASK); + *decoflags &= ~OPMASK_MASK; + } + *decoflags |= VAL_OPMASK(nasm_regvals[tokval.t_integer]); + break; + case TOKEN_DECORATOR: + j = tokval.t_integer; + switch (j) { + case BRC_Z: + *decoflags |= Z_MASK; + break; + case BRC_1TO2: + case BRC_1TO4: + case BRC_1TO8: + case BRC_1TO16: + *decoflags |= BRDCAST_MASK | VAL_BRNUM(j - BRC_1TO2); + break; + default: + nasm_error(ERR_NONFATAL, + "{%s} is not an expected decorator", + tokval.t_charptr); + break; + } + break; + case ',': + case TOKEN_EOS: + return false; + default: + nasm_error(ERR_NONFATAL, + "only a series of valid decorators expected"); + return true; + } + i = stdscan(NULL, &tokval); + } +} + +static int parse_mref(operand *op, const expr *e) +{ + int b, i, s; /* basereg, indexreg, scale */ + int64_t o; /* offset */ + + b = i = -1; + o = s = 0; + op->segment = op->wrt = NO_SEG; + + if (e->type && e->type <= EXPR_REG_END) { /* this bit's a register */ + bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); + + if (is_gpr && e->value == 1) + b = e->type; /* It can be basereg */ + else /* No, it has to be indexreg */ + i = e->type, s = e->value; + e++; + } + if (e->type && e->type <= EXPR_REG_END) { /* it's a 2nd register */ + bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); + + if (b != -1) /* If the first was the base, ... */ + i = e->type, s = e->value; /* second has to be indexreg */ + + else if (!is_gpr || e->value != 1) { + /* If both want to be index */ + nasm_error(ERR_NONFATAL, + "invalid effective address: two index registers"); + return -1; + } else + b = e->type; + e++; + } + + if (e->type) { /* is there an offset? */ + if (e->type <= EXPR_REG_END) { /* in fact, is there an error? */ + nasm_error(ERR_NONFATAL, + "invalid effective address: impossible register"); + return -1; + } else { + if (e->type == EXPR_UNKNOWN) { + op->opflags |= OPFLAG_UNKNOWN; + o = 0; /* doesn't matter what */ + while (e->type) + e++; /* go to the end of the line */ + } else { + if (e->type == EXPR_SIMPLE) { + o = e->value; + e++; + } + if (e->type == EXPR_WRT) { + op->wrt = e->value; + e++; + } + /* + * Look for a segment base type. + */ + for (; e->type; e++) { + if (!e->value) + continue; + + if (e->type <= EXPR_REG_END) { + nasm_error(ERR_NONFATAL, + "invalid effective address: too many registers"); + return -1; + } else if (e->type < EXPR_SEGBASE) { + nasm_error(ERR_NONFATAL, + "invalid effective address: bad subexpression type"); + return -1; + } else if (e->value == 1) { + if (op->segment != NO_SEG) { + nasm_error(ERR_NONFATAL, + "invalid effective address: multiple base segments"); + return -1; + } + op->segment = e->type - EXPR_SEGBASE; + } else if (e->value == -1 && + e->type == location.segment + EXPR_SEGBASE && + !(op->opflags & OPFLAG_RELATIVE)) { + op->opflags |= OPFLAG_RELATIVE; + } else { + nasm_error(ERR_NONFATAL, + "invalid effective address: impossible segment base multiplier"); + return -1; + } + } + } + } + } + + nasm_assert(!e->type); /* We should be at the end */ + + op->basereg = b; + op->indexreg = i; + op->scale = s; + op->offset = o; + return 0; +} + +static void mref_set_optype(operand *op) +{ + int b = op->basereg; + int i = op->indexreg; + int s = op->scale; + + /* It is memory, but it can match any r/m operand */ + op->type |= MEMORY_ANY; + + if (b == -1 && (i == -1 || s == 0)) { + int is_rel = globalbits == 64 && + !(op->eaflags & EAF_ABS) && + ((globalrel && + !(op->eaflags & EAF_FSGS)) || + (op->eaflags & EAF_REL)); + + op->type |= is_rel ? IP_REL : MEM_OFFS; + } + + if (i != -1) { + opflags_t iclass = nasm_reg_flags[i]; + + if (is_class(XMMREG,iclass)) + op->type |= XMEM; + else if (is_class(YMMREG,iclass)) + op->type |= YMEM; + else if (is_class(ZMMREG,iclass)) + op->type |= ZMEM; + } +} + +/* + * Convert an expression vector returned from evaluate() into an + * extop structure. Return zero on success. + */ +static int value_to_extop(expr * vect, extop *eop, int32_t myseg) +{ + eop->type = EOT_DB_NUMBER; + eop->offset = 0; + eop->segment = eop->wrt = NO_SEG; + eop->relative = false; + + for (; vect->type; vect++) { + if (!vect->value) /* zero term, safe to ignore */ + continue; + + if (vect->type <= EXPR_REG_END) /* false if a register is present */ + return -1; + + if (vect->type == EXPR_UNKNOWN) /* something we can't resolve yet */ + return 0; + + if (vect->type == EXPR_SIMPLE) { + /* Simple number expression */ + eop->offset += vect->value; + continue; + } + if (eop->wrt == NO_SEG && !eop->relative && vect->type == EXPR_WRT) { + /* WRT term */ + eop->wrt = vect->value; + continue; + } + + if (!eop->relative && + vect->type == EXPR_SEGBASE + myseg && vect->value == -1) { + /* Expression of the form: foo - $ */ + eop->relative = true; + continue; + } + + if (eop->segment == NO_SEG && vect->type >= EXPR_SEGBASE && + vect->value == 1) { + eop->segment = vect->type - EXPR_SEGBASE; + continue; + } + + /* Otherwise, badness */ + return -1; + } + + /* We got to the end and it was all okay */ + return 0; +} + +insn *parse_line(int pass, char *buffer, insn *result) +{ + bool insn_is_label = false; + struct eval_hints hints; + int opnum; + int critical; + bool first; + bool recover; + int i; + + nasm_static_assert(P_none == 0); + +restart_parse: + first = true; + result->forw_ref = false; + + stdscan_reset(); + stdscan_set(buffer); + i = stdscan(NULL, &tokval); + + memset(result->prefixes, P_none, sizeof(result->prefixes)); + result->times = 1; /* No TIMES either yet */ + result->label = NULL; /* Assume no label */ + result->eops = NULL; /* must do this, whatever happens */ + result->operands = 0; /* must initialize this */ + result->evex_rm = 0; /* Ensure EVEX rounding mode is reset */ + result->evex_brerop = -1; /* Reset EVEX broadcasting/ER op position */ + + /* Ignore blank lines */ + if (i == TOKEN_EOS) + goto fail; + + if (i != TOKEN_ID && + i != TOKEN_INSN && + i != TOKEN_PREFIX && + (i != TOKEN_REG || !IS_SREG(tokval.t_integer))) { + nasm_error(ERR_NONFATAL, + "label or instruction expected at start of line"); + goto fail; + } + + if (i == TOKEN_ID || (insn_is_label && i == TOKEN_INSN)) { + /* there's a label here */ + first = false; + result->label = tokval.t_charptr; + i = stdscan(NULL, &tokval); + if (i == ':') { /* skip over the optional colon */ + i = stdscan(NULL, &tokval); + } else if (i == 0) { + nasm_error(ERR_WARNING | ERR_WARN_OL | ERR_PASS1, + "label alone on a line without a colon might be in error"); + } + if (i != TOKEN_INSN || tokval.t_integer != I_EQU) { + /* + * FIXME: location.segment could be NO_SEG, in which case + * it is possible we should be passing 'absolute.segment'. Look into this. + * Work out whether that is *really* what we should be doing. + * Generally fix things. I think this is right as it is, but + * am still not certain. + */ + define_label(result->label, + in_absolute ? absolute.segment : location.segment, + location.offset, true); + } + } + + /* Just a label here */ + if (i == TOKEN_EOS) + goto fail; + + while (i == TOKEN_PREFIX || + (i == TOKEN_REG && IS_SREG(tokval.t_integer))) { + first = false; + + /* + * Handle special case: the TIMES prefix. + */ + if (i == TOKEN_PREFIX && tokval.t_integer == P_TIMES) { + expr *value; + + i = stdscan(NULL, &tokval); + value = evaluate(stdscan, NULL, &tokval, NULL, pass0, NULL); + i = tokval.t_type; + if (!value) /* Error in evaluator */ + goto fail; + if (!is_simple(value)) { + nasm_error(ERR_NONFATAL, + "non-constant argument supplied to TIMES"); + result->times = 1L; + } else { + result->times = value->value; + if (value->value < 0) { + nasm_error(ERR_NONFATAL|ERR_PASS2, "TIMES value %"PRId64" is negative", value->value); + result->times = 0; + } + } + } else { + int slot = prefix_slot(tokval.t_integer); + if (result->prefixes[slot]) { + if (result->prefixes[slot] == tokval.t_integer) + nasm_error(ERR_WARNING | ERR_PASS1, + "instruction has redundant prefixes"); + else + nasm_error(ERR_NONFATAL, + "instruction has conflicting prefixes"); + } + result->prefixes[slot] = tokval.t_integer; + i = stdscan(NULL, &tokval); + } + } + + if (i != TOKEN_INSN) { + int j; + enum prefixes pfx; + + for (j = 0; j < MAXPREFIX; j++) { + if ((pfx = result->prefixes[j]) != P_none) + break; + } + + if (i == 0 && pfx != P_none) { + /* + * Instruction prefixes are present, but no actual + * instruction. This is allowed: at this point we + * invent a notional instruction of RESB 0. + */ + result->opcode = I_RESB; + result->operands = 1; + nasm_zero(result->oprs); + result->oprs[0].type = IMMEDIATE; + result->oprs[0].offset = 0L; + result->oprs[0].segment = result->oprs[0].wrt = NO_SEG; + return result; + } else { + nasm_error(ERR_NONFATAL, "parser: instruction expected"); + goto fail; + } + } + + result->opcode = tokval.t_integer; + result->condition = tokval.t_inttwo; + + /* + * INCBIN cannot be satisfied with incorrectly + * evaluated operands, since the correct values _must_ be known + * on the first pass. Hence, even in pass one, we set the + * `critical' flag on calling evaluate(), so that it will bomb + * out on undefined symbols. + */ + if (result->opcode == I_INCBIN) { + critical = (pass0 < 2 ? 1 : 2); + + } else + critical = (pass == 2 ? 2 : 0); + + if (opcode_is_db(result->opcode) || result->opcode == I_INCBIN) { + extop *eop, **tail = &result->eops, **fixptr; + int oper_num = 0; + int32_t sign; + + result->eops_float = false; + + /* + * Begin to read the DB/DW/DD/DQ/DT/DO/DY/DZ/INCBIN operands. + */ + while (1) { + i = stdscan(NULL, &tokval); + if (i == TOKEN_EOS) + break; + else if (first && i == ':') { + insn_is_label = true; + goto restart_parse; + } + first = false; + fixptr = tail; + eop = *tail = nasm_malloc(sizeof(extop)); + tail = &eop->next; + eop->next = NULL; + eop->type = EOT_NOTHING; + oper_num++; + sign = +1; + + /* + * is_comma_next() here is to distinguish this from + * a string used as part of an expression... + */ + if (i == TOKEN_STR && is_comma_next()) { + eop->type = EOT_DB_STRING; + eop->stringval = tokval.t_charptr; + eop->stringlen = tokval.t_inttwo; + i = stdscan(NULL, &tokval); /* eat the comma */ + } else if (i == TOKEN_STRFUNC) { + bool parens = false; + const char *funcname = tokval.t_charptr; + enum strfunc func = tokval.t_integer; + i = stdscan(NULL, &tokval); + if (i == '(') { + parens = true; + i = stdscan(NULL, &tokval); + } + if (i != TOKEN_STR) { + nasm_error(ERR_NONFATAL, + "%s must be followed by a string constant", + funcname); + eop->type = EOT_NOTHING; + } else { + eop->type = EOT_DB_STRING_FREE; + eop->stringlen = + string_transform(tokval.t_charptr, tokval.t_inttwo, + &eop->stringval, func); + if (eop->stringlen == (size_t)-1) { + nasm_error(ERR_NONFATAL, "invalid string for transform"); + eop->type = EOT_NOTHING; + } + } + if (parens && i && i != ')') { + i = stdscan(NULL, &tokval); + if (i != ')') { + nasm_error(ERR_NONFATAL, "unterminated %s function", + funcname); + } + } + if (i && i != ',') + i = stdscan(NULL, &tokval); + } else if (i == '-' || i == '+') { + char *save = stdscan_get(); + int token = i; + sign = (i == '-') ? -1 : 1; + i = stdscan(NULL, &tokval); + if (i != TOKEN_FLOAT) { + stdscan_set(save); + i = tokval.t_type = token; + goto is_expression; + } else { + goto is_float; + } + } else if (i == TOKEN_FLOAT) { +is_float: + eop->type = EOT_DB_STRING; + result->eops_float = true; + + eop->stringlen = db_bytes(result->opcode); + if (eop->stringlen > 16) { + nasm_error(ERR_NONFATAL, "floating-point constant" + " encountered in DY or DZ instruction"); + eop->stringlen = 0; + } else if (eop->stringlen < 1) { + nasm_error(ERR_NONFATAL, "floating-point constant" + " encountered in unknown instruction"); + /* + * fix suggested by Pedro Gimeno... original line was: + * eop->type = EOT_NOTHING; + */ + eop->stringlen = 0; + } + + eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen); + tail = &eop->next; + *fixptr = eop; + eop->stringval = (char *)eop + sizeof(extop); + if (!eop->stringlen || + !float_const(tokval.t_charptr, sign, + (uint8_t *)eop->stringval, eop->stringlen)) + eop->type = EOT_NOTHING; + i = stdscan(NULL, &tokval); /* eat the comma */ + } else { + /* anything else, assume it is an expression */ + expr *value; + +is_expression: + value = evaluate(stdscan, NULL, &tokval, NULL, + critical, NULL); + i = tokval.t_type; + if (!value) /* Error in evaluator */ + goto fail; + if (value_to_extop(value, eop, location.segment)) { + nasm_error(ERR_NONFATAL, + "operand %d: expression is not simple or relocatable", + oper_num); + } + } + + /* + * We're about to call stdscan(), which will eat the + * comma that we're currently sitting on between + * arguments. However, we'd better check first that it + * _is_ a comma. + */ + if (i == TOKEN_EOS) /* also could be EOL */ + break; + if (i != ',') { + nasm_error(ERR_NONFATAL, "comma expected after operand %d", + oper_num); + goto fail; + } + } + + if (result->opcode == I_INCBIN) { + /* + * Correct syntax for INCBIN is that there should be + * one string operand, followed by one or two numeric + * operands. + */ + if (!result->eops || result->eops->type != EOT_DB_STRING) + nasm_error(ERR_NONFATAL, "`incbin' expects a file name"); + else if (result->eops->next && + result->eops->next->type != EOT_DB_NUMBER) + nasm_error(ERR_NONFATAL, "`incbin': second parameter is" + " non-numeric"); + else if (result->eops->next && result->eops->next->next && + result->eops->next->next->type != EOT_DB_NUMBER) + nasm_error(ERR_NONFATAL, "`incbin': third parameter is" + " non-numeric"); + else if (result->eops->next && result->eops->next->next && + result->eops->next->next->next) + nasm_error(ERR_NONFATAL, + "`incbin': more than three parameters"); + else + return result; + /* + * If we reach here, one of the above errors happened. + * Throw the instruction away. + */ + goto fail; + } else /* DB ... */ if (oper_num == 0) + nasm_error(ERR_WARNING | ERR_PASS1, + "no operand for data declaration"); + else + result->operands = oper_num; + + return result; + } + + /* + * Now we begin to parse the operands. There may be up to four + * of these, separated by commas, and terminated by a zero token. + */ + + for (opnum = 0; opnum < MAX_OPERANDS; opnum++) { + operand *op = &result->oprs[opnum]; + expr *value; /* used most of the time */ + bool mref; /* is this going to be a memory ref? */ + bool bracket; /* is it a [] mref, or a & mref? */ + bool mib; /* compound (mib) mref? */ + int setsize = 0; + decoflags_t brace_flags = 0; /* flags for decorators in braces */ + + op->disp_size = 0; /* have to zero this whatever */ + op->eaflags = 0; /* and this */ + op->opflags = 0; + op->decoflags = 0; + + i = stdscan(NULL, &tokval); + if (i == TOKEN_EOS) + break; /* end of operands: get out of here */ + else if (first && i == ':') { + insn_is_label = true; + goto restart_parse; + } + first = false; + op->type = 0; /* so far, no override */ + while (i == TOKEN_SPECIAL) { /* size specifiers */ + switch (tokval.t_integer) { + case S_BYTE: + if (!setsize) /* we want to use only the first */ + op->type |= BITS8; + setsize = 1; + break; + case S_WORD: + if (!setsize) + op->type |= BITS16; + setsize = 1; + break; + case S_DWORD: + case S_LONG: + if (!setsize) + op->type |= BITS32; + setsize = 1; + break; + case S_QWORD: + if (!setsize) + op->type |= BITS64; + setsize = 1; + break; + case S_TWORD: + if (!setsize) + op->type |= BITS80; + setsize = 1; + break; + case S_OWORD: + if (!setsize) + op->type |= BITS128; + setsize = 1; + break; + case S_YWORD: + if (!setsize) + op->type |= BITS256; + setsize = 1; + break; + case S_ZWORD: + if (!setsize) + op->type |= BITS512; + setsize = 1; + break; + case S_TO: + op->type |= TO; + break; + case S_STRICT: + op->type |= STRICT; + break; + case S_FAR: + op->type |= FAR; + break; + case S_NEAR: + op->type |= NEAR; + break; + case S_SHORT: + op->type |= SHORT; + break; + default: + nasm_error(ERR_NONFATAL, "invalid operand size specification"); + } + i = stdscan(NULL, &tokval); + } + + if (i == '[' || i == '&') { /* memory reference */ + mref = true; + bracket = (i == '['); + i = stdscan(NULL, &tokval); /* then skip the colon */ + while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) { + process_size_override(result, op); + i = stdscan(NULL, &tokval); + } + /* when a comma follows an opening bracket - [ , eax*4] */ + if (i == ',') { + /* treat as if there is a zero displacement virtually */ + tokval.t_type = TOKEN_NUM; + tokval.t_integer = 0; + stdscan_set(stdscan_get() - 1); /* rewind the comma */ + } + } else { /* immediate operand, or register */ + mref = false; + bracket = false; /* placate optimisers */ + } + + if ((op->type & FAR) && !mref && + result->opcode != I_JMP && result->opcode != I_CALL) { + nasm_error(ERR_NONFATAL, "invalid use of FAR operand specifier"); + } + + value = evaluate(stdscan, NULL, &tokval, + &op->opflags, critical, &hints); + i = tokval.t_type; + if (op->opflags & OPFLAG_FORWARD) { + result->forw_ref = true; + } + if (!value) /* Error in evaluator */ + goto fail; + if (i == ':' && mref) { /* it was seg:offset */ + /* + * Process the segment override. + */ + if (value[1].type != 0 || + value->value != 1 || + !IS_SREG(value->type)) + nasm_error(ERR_NONFATAL, "invalid segment override"); + else if (result->prefixes[PPS_SEG]) + nasm_error(ERR_NONFATAL, + "instruction has conflicting segment overrides"); + else { + result->prefixes[PPS_SEG] = value->type; + if (IS_FSGS(value->type)) + op->eaflags |= EAF_FSGS; + } + + i = stdscan(NULL, &tokval); /* then skip the colon */ + while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) { + process_size_override(result, op); + i = stdscan(NULL, &tokval); + } + value = evaluate(stdscan, NULL, &tokval, + &op->opflags, critical, &hints); + i = tokval.t_type; + if (op->opflags & OPFLAG_FORWARD) { + result->forw_ref = true; + } + /* and get the offset */ + if (!value) /* Error in evaluator */ + goto fail; + } + + mib = false; + if (mref && bracket && i == ',') { + /* [seg:base+offset,index*scale] syntax (mib) */ + + operand o1, o2; /* Partial operands */ + + if (parse_mref(&o1, value)) + goto fail; + + i = stdscan(NULL, &tokval); /* Eat comma */ + value = evaluate(stdscan, NULL, &tokval, &op->opflags, + critical, &hints); + i = tokval.t_type; + if (!value) + goto fail; + + if (parse_mref(&o2, value)) + goto fail; + + if (o2.basereg != -1 && o2.indexreg == -1) { + o2.indexreg = o2.basereg; + o2.scale = 1; + o2.basereg = -1; + } + + if (o1.indexreg != -1 || o2.basereg != -1 || o2.offset != 0 || + o2.segment != NO_SEG || o2.wrt != NO_SEG) { + nasm_error(ERR_NONFATAL, "invalid mib expression"); + goto fail; + } + + op->basereg = o1.basereg; + op->indexreg = o2.indexreg; + op->scale = o2.scale; + op->offset = o1.offset; + op->segment = o1.segment; + op->wrt = o1.wrt; + + if (op->basereg != -1) { + op->hintbase = op->basereg; + op->hinttype = EAH_MAKEBASE; + } else if (op->indexreg != -1) { + op->hintbase = op->indexreg; + op->hinttype = EAH_NOTBASE; + } else { + op->hintbase = -1; + op->hinttype = EAH_NOHINT; + } + + mib = true; + } + + recover = false; + if (mref && bracket) { /* find ] at the end */ + if (i != ']') { + nasm_error(ERR_NONFATAL, "parser: expecting ]"); + recover = true; + } else { /* we got the required ] */ + i = stdscan(NULL, &tokval); + if (i == TOKEN_DECORATOR || i == TOKEN_OPMASK) { + /* parse opmask (and zeroing) after an operand */ + recover = parse_braces(&brace_flags); + i = tokval.t_type; + } + if (i != 0 && i != ',') { + nasm_error(ERR_NONFATAL, "comma or end of line expected"); + recover = true; + } + } + } else { /* immediate operand */ + if (i != 0 && i != ',' && i != ':' && + i != TOKEN_DECORATOR && i != TOKEN_OPMASK) { + nasm_error(ERR_NONFATAL, "comma, colon, decorator or end of " + "line expected after operand"); + recover = true; + } else if (i == ':') { + op->type |= COLON; + } else if (i == TOKEN_DECORATOR || i == TOKEN_OPMASK) { + /* parse opmask (and zeroing) after an operand */ + recover = parse_braces(&brace_flags); + } + } + if (recover) { + do { /* error recovery */ + i = stdscan(NULL, &tokval); + } while (i != 0 && i != ','); + } + + /* + * now convert the exprs returned from evaluate() + * into operand descriptions... + */ + op->decoflags |= brace_flags; + + if (mref) { /* it's a memory reference */ + /* A mib reference was fully parsed already */ + if (!mib) { + if (parse_mref(op, value)) + goto fail; + op->hintbase = hints.base; + op->hinttype = hints.type; + } + mref_set_optype(op); + } else { /* it's not a memory reference */ + if (is_just_unknown(value)) { /* it's immediate but unknown */ + op->type |= IMMEDIATE; + op->opflags |= OPFLAG_UNKNOWN; + op->offset = 0; /* don't care */ + op->segment = NO_SEG; /* don't care again */ + op->wrt = NO_SEG; /* still don't care */ + + if(optimizing.level >= 0 && !(op->type & STRICT)) { + /* Be optimistic */ + op->type |= + UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD; + } + } else if (is_reloc(value)) { /* it's immediate */ + uint64_t n = reloc_value(value); + + op->type |= IMMEDIATE; + op->offset = n; + op->segment = reloc_seg(value); + op->wrt = reloc_wrt(value); + op->opflags |= is_self_relative(value) ? OPFLAG_RELATIVE : 0; + + if (is_simple(value)) { + if (n == 1) + op->type |= UNITY; + if (optimizing.level >= 0 && !(op->type & STRICT)) { + if ((uint32_t) (n + 128) <= 255) + op->type |= SBYTEDWORD; + if ((uint16_t) (n + 128) <= 255) + op->type |= SBYTEWORD; + if (n <= UINT64_C(0xFFFFFFFF)) + op->type |= UDWORD; + if (n + UINT64_C(0x80000000) <= UINT64_C(0xFFFFFFFF)) + op->type |= SDWORD; + } + } + } else if (value->type == EXPR_RDSAE) { + /* + * it's not an operand but a rounding or SAE decorator. + * put the decorator information in the (opflag_t) type field + * of previous operand. + */ + opnum--; op--; + switch (value->value) { + case BRC_RN: + case BRC_RU: + case BRC_RD: + case BRC_RZ: + case BRC_SAE: + op->decoflags |= (value->value == BRC_SAE ? SAE : ER); + result->evex_rm = value->value; + break; + default: + nasm_error(ERR_NONFATAL, "invalid decorator"); + break; + } + } else { /* it's a register */ + opflags_t rs; + uint64_t regset_size = 0; + + if (value->type >= EXPR_SIMPLE || value->value != 1) { + nasm_error(ERR_NONFATAL, "invalid operand type"); + goto fail; + } + + /* + * We do not allow any kind of expression, except for + * reg+value in which case it is a register set. + */ + for (i = 1; value[i].type; i++) { + if (!value[i].value) + continue; + + switch (value[i].type) { + case EXPR_SIMPLE: + if (!regset_size) { + regset_size = value[i].value + 1; + break; + } + /* fallthrough */ + default: + nasm_error(ERR_NONFATAL, "invalid operand type"); + goto fail; + } + } + + if ((regset_size & (regset_size - 1)) || + regset_size >= (UINT64_C(1) << REGSET_BITS)) { + nasm_error(ERR_NONFATAL | ERR_PASS2, + "invalid register set size"); + regset_size = 0; + } + + /* clear overrides, except TO which applies to FPU regs */ + if (op->type & ~TO) { + /* + * we want to produce a warning iff the specified size + * is different from the register size + */ + rs = op->type & SIZE_MASK; + } else { + rs = 0; + } + + /* + * Make sure we're not out of nasm_reg_flags, still + * probably this should be fixed when we're defining + * the label. + * + * An easy trigger is + * + * e equ 0x80000000:0 + * pshufw word e-0 + * + */ + if (value->type < EXPR_REG_START || + value->type > EXPR_REG_END) { + nasm_error(ERR_NONFATAL, "invalid operand type"); + goto fail; + } + + op->type &= TO; + op->type |= REGISTER; + op->type |= nasm_reg_flags[value->type]; + op->type |= (regset_size >> 1) << REGSET_SHIFT; + op->decoflags |= brace_flags; + op->basereg = value->type; + + if (rs && (op->type & SIZE_MASK) != rs) + nasm_error(ERR_WARNING | ERR_PASS1, + "register size specification ignored"); + } + } + + /* remember the position of operand having broadcasting/ER mode */ + if (op->decoflags & (BRDCAST_MASK | ER | SAE)) + result->evex_brerop = opnum; + } + + result->operands = opnum; /* set operand count */ + + /* clear remaining operands */ + while (opnum < MAX_OPERANDS) + result->oprs[opnum++].type = 0; + + /* + * Transform RESW, RESD, RESQ, REST, RESO, RESY, RESZ into RESB. + */ + if (opcode_is_resb(result->opcode)) { + result->oprs[0].offset *= resb_bytes(result->opcode); + result->oprs[0].offset *= result->times; + result->times = 1; + result->opcode = I_RESB; + } + + return result; + +fail: + result->opcode = I_none; + return result; +} + +static int is_comma_next(void) +{ + struct tokenval tv; + char *p; + int i; + + p = stdscan_get(); + i = stdscan(NULL, &tv); + stdscan_set(p); + + return (i == ',' || i == ';' || !i); +} + +void cleanup_insn(insn * i) +{ + extop *e; + + while ((e = i->eops)) { + i->eops = e->next; + if (e->type == EOT_DB_STRING_FREE) + nasm_free(e->stringval); + nasm_free(e); + } +} diff --git a/asm/parser.h b/asm/parser.h new file mode 100644 index 0000000..cd2d136 --- /dev/null +++ b/asm/parser.h @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * parser.h header file for the parser module of the Netwide + * Assembler + */ + +#ifndef NASM_PARSER_H +#define NASM_PARSER_H + +insn *parse_line(int pass, char *buffer, insn *result); +void cleanup_insn(insn *instruction); + +#endif diff --git a/asm/phash.pl b/asm/phash.pl new file mode 100644 index 0000000..3ef6e71 --- /dev/null +++ b/asm/phash.pl @@ -0,0 +1,109 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2009 the NASM Authors - All rights reserved. +## +## 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. +## +## -------------------------------------------------------------------------- + +# +# Perfect Minimal Hash Generator written in Perl, which produces +# C output. +# + +require 'phash.ph'; + +# +# Read input file +# +sub read_input() { + my $key,$val; + my %out; + my $x = 0; + + while (defined($l = )) { + chomp $l; + $l =~ s/\s*(\#.*|)$//; + + next if ($l eq ''); + + if ($l =~ /^([^=]+)\=([^=]+)$/) { + $out{$1} = $2; + $x = $2; + } else { + $out{$l} = $x; + } + $x++; + } + + return %out; +} + +# +# Main program +# +sub main() { + my $n; + my %data; + my @hashinfo; + my $x, $i; + + %data = read_input(); + @hashinfo = gen_perfect_hash(\%data); + + if (!@hashinfo) { + die "$0: no hash found\n"; + } + + verify_hash_table(\%data, \@hashinfo); + + ($n, $sv, $f1, $f2, $g) = @hashinfo; + + print "static int HASHNAME_fg1[$n] =\n"; + print "{\n"; + for ($i = 0; $i < $n; $i++) { + print "\t", ${$g}[${$f1}[$i]], "\n"; + } + print "};\n\n"; + + print "static int HASHNAME_fg2[$n] =\n"; + print "{\n"; + for ($i = 0; $i < $n; $i++) { + print "\t", ${$g}[${$f2}[$i]], "\n"; + } + print "};\n\n"; + + print "struct p_hash HASHNAME =\n"; + print "{\n"; + print "\t$n\n"; + print "\t$sv\n"; + print "\tHASHNAME_fg1,\n"; + print "\tHASHNAME_fg2,\n"; + print "};\n"; +} + +main(); diff --git a/asm/pptok.c b/asm/pptok.c new file mode 100644 index 0000000..51a008c --- /dev/null +++ b/asm/pptok.c @@ -0,0 +1,511 @@ +/* Automatically generated from ./asm/pptok.dat by ./asm/pptok.pl */ +/* Do not edit */ + +#include "compiler.h" +#include +#include "nasmlib.h" +#include "hashtbl.h" +#include "preproc.h" + +const char * const pp_directives[109] = { + "%elif", + "%elifn", + "%elifctx", + "%elifnctx", + "%elifdef", + "%elifndef", + "%elifempty", + "%elifnempty", + "%elifenv", + "%elifnenv", + "%elifid", + "%elifnid", + "%elifidn", + "%elifnidn", + "%elifidni", + "%elifnidni", + "%elifmacro", + "%elifnmacro", + "%elifnum", + "%elifnnum", + "%elifstr", + "%elifnstr", + "%eliftoken", + "%elifntoken", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "%if", + "%ifn", + "%ifctx", + "%ifnctx", + "%ifdef", + "%ifndef", + "%ifempty", + "%ifnempty", + "%ifenv", + "%ifnenv", + "%ifid", + "%ifnid", + "%ifidn", + "%ifnidn", + "%ifidni", + "%ifnidni", + "%ifmacro", + "%ifnmacro", + "%ifnum", + "%ifnnum", + "%ifstr", + "%ifnstr", + "%iftoken", + "%ifntoken", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "%arg", + "%assign", + "%clear", + "%define", + "%defstr", + "%deftok", + "%depend", + "%else", + "%endif", + "%endm", + "%endmacro", + "%endrep", + "%error", + "%exitmacro", + "%exitrep", + "%fatal", + "%iassign", + "%idefine", + "%idefstr", + "%ideftok", + "%imacro", + "%include", + "%irmacro", + "%ixdefine", + "%line", + "%local", + "%macro", + "%pathsearch", + "%pop", + "%pragma", + "%push", + "%rep", + "%repl", + "%rmacro", + "%rotate", + "%stacksize", + "%strcat", + "%strlen", + "%substr", + "%undef", + "%unimacro", + "%unmacro", + "%use", + "%warning", + "%xdefine", +}; +const uint8_t pp_directives_len[109] = { + 5, + 6, + 8, + 9, + 8, + 9, + 10, + 11, + 8, + 9, + 7, + 8, + 8, + 9, + 9, + 10, + 10, + 11, + 8, + 9, + 8, + 9, + 10, + 11, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 4, + 6, + 7, + 6, + 7, + 8, + 9, + 6, + 7, + 5, + 6, + 6, + 7, + 7, + 8, + 8, + 9, + 6, + 7, + 6, + 7, + 8, + 9, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4, + 7, + 6, + 7, + 7, + 7, + 7, + 5, + 6, + 5, + 9, + 7, + 6, + 10, + 8, + 6, + 8, + 8, + 8, + 8, + 7, + 8, + 8, + 9, + 5, + 6, + 6, + 11, + 4, + 7, + 5, + 4, + 5, + 7, + 7, + 10, + 7, + 7, + 7, + 6, + 9, + 8, + 4, + 8, + 8, +}; +enum preproc_token pp_token_hash(const char *token) +{ +#define UNUSED (65535/3) + static const int16_t hash1[128] = { + UNUSED, + UNUSED, + 0, + 0, + 0, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + 0, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + -45, + UNUSED, + 0, + UNUSED, + -60, + 0, + UNUSED, + UNUSED, + -42, + UNUSED, + UNUSED, + -49, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 48, + UNUSED, + UNUSED, + 49, + 5, + UNUSED, + -53, + 65, + UNUSED, + UNUSED, + 0, + 0, + UNUSED, + 38, + UNUSED, + 31, + 0, + UNUSED, + 6, + 35, + UNUSED, + UNUSED, + 60, + 33, + UNUSED, + 136, + UNUSED, + -87, + -12, + 42, + 17, + 0, + 130, + -85, + UNUSED, + UNUSED, + 82, + 0, + UNUSED, + 16, + 98, + -66, + -100, + 0, + -10, + -76, + UNUSED, + 84, + UNUSED, + 1, + UNUSED, + 0, + 12, + UNUSED, + -145, + 41, + 106, + UNUSED, + 85, + UNUSED, + 43, + 85, + UNUSED, + 23, + 0, + -14, + UNUSED, + UNUSED, + 77, + -2, + UNUSED, + UNUSED, + 11, + 91, + -7, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 107, + 44, + UNUSED, + }; + static const int16_t hash2[128] = { + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + 80, + 0, + 64, + UNUSED, + 0, + 0, + 0, + 0, + UNUSED, + UNUSED, + UNUSED, + 64, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + 121, + 0, + UNUSED, + 22, + 100, + 63, + UNUSED, + 114, + UNUSED, + 178, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + -40, + UNUSED, + 88, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 87, + UNUSED, + 42, + UNUSED, + UNUSED, + 141, + UNUSED, + UNUSED, + UNUSED, + 103, + UNUSED, + 46, + 106, + 149, + UNUSED, + 23, + 53, + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 33, + 0, + 0, + 92, + UNUSED, + 50, + 72, + UNUSED, + 7, + 43, + 66, + UNUSED, + UNUSED, + 113, + 52, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 99, + 101, + 71, + UNUSED, + 20, + 63, + 32, + UNUSED, + UNUSED, + UNUSED, + 97, + 18, + 84, + 132, + UNUSED, + 37, + UNUSED, + 9, + 20, + UNUSED, + UNUSED, + 75, + 98, + UNUSED, + }; + uint32_t k1, k2; + uint64_t crc; + uint16_t ix; + + crc = crc64i(UINT64_C(0xaee7ac5ccabdec91), token); + k1 = (uint32_t)crc; + k2 = (uint32_t)(crc >> 32); + + ix = hash1[k1 & 0x7f] + hash2[k2 & 0x7f]; + if (ix >= 109) + return PP_INVALID; + + if (!pp_directives[ix] || nasm_stricmp(pp_directives[ix], token)) + return PP_INVALID; + + return ix; +} diff --git a/asm/pptok.dat b/asm/pptok.dat new file mode 100644 index 0000000..a2c64d0 --- /dev/null +++ b/asm/pptok.dat @@ -0,0 +1,96 @@ +## -------------------------------------------------------------------------- +## +## Copyright 1996-2016 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. +## +## -------------------------------------------------------------------------- + +# +# A * at the end indicates a condition; the list of conditions are +# on lines starting with *; the negatives are auto-generated +# +* +*ctx +*def +*empty +*env +*id +*idn +*idni +*macro +*num +*str +*token +%arg +%assign +%clear +%define +%defstr +%deftok +%depend +%elif* +%else +%endif +%endm +%endmacro +%endrep +%error +%exitmacro +%exitrep +%fatal +%iassign +%idefine +%idefstr +%ideftok +%if* +%imacro +%irmacro +%include +%ixdefine +%line +%local +%macro +%pathsearch +%pop +%pragma +%push +%rep +%repl +%rmacro +%rotate +%stacksize +%strcat +%strlen +%substr +%undef +%unimacro +%unmacro +%use +%warning +%xdefine diff --git a/asm/pptok.h b/asm/pptok.h new file mode 100644 index 0000000..9bbc8d1 --- /dev/null +++ b/asm/pptok.h @@ -0,0 +1,158 @@ +/* Automatically generated from ./asm/pptok.dat by ./asm/pptok.pl */ +/* Do not edit */ + +enum preproc_token { + PP_ELIF = 0, + PP_ELIFN = 1, + PP_ELIFCTX = 2, + PP_ELIFNCTX = 3, + PP_ELIFDEF = 4, + PP_ELIFNDEF = 5, + PP_ELIFEMPTY = 6, + PP_ELIFNEMPTY = 7, + PP_ELIFENV = 8, + PP_ELIFNENV = 9, + PP_ELIFID = 10, + PP_ELIFNID = 11, + PP_ELIFIDN = 12, + PP_ELIFNIDN = 13, + PP_ELIFIDNI = 14, + PP_ELIFNIDNI = 15, + PP_ELIFMACRO = 16, + PP_ELIFNMACRO = 17, + PP_ELIFNUM = 18, + PP_ELIFNNUM = 19, + PP_ELIFSTR = 20, + PP_ELIFNSTR = 21, + PP_ELIFTOKEN = 22, + PP_ELIFNTOKEN = 23, + PP_IF = 32, + PP_IFN = 33, + PP_IFCTX = 34, + PP_IFNCTX = 35, + PP_IFDEF = 36, + PP_IFNDEF = 37, + PP_IFEMPTY = 38, + PP_IFNEMPTY = 39, + PP_IFENV = 40, + PP_IFNENV = 41, + PP_IFID = 42, + PP_IFNID = 43, + PP_IFIDN = 44, + PP_IFNIDN = 45, + PP_IFIDNI = 46, + PP_IFNIDNI = 47, + PP_IFMACRO = 48, + PP_IFNMACRO = 49, + PP_IFNUM = 50, + PP_IFNNUM = 51, + PP_IFSTR = 52, + PP_IFNSTR = 53, + PP_IFTOKEN = 54, + PP_IFNTOKEN = 55, + PP_ARG = 64, + PP_ASSIGN = 65, + PP_CLEAR = 66, + PP_DEFINE = 67, + PP_DEFSTR = 68, + PP_DEFTOK = 69, + PP_DEPEND = 70, + PP_ELSE = 71, + PP_ENDIF = 72, + PP_ENDM = 73, + PP_ENDMACRO = 74, + PP_ENDREP = 75, + PP_ERROR = 76, + PP_EXITMACRO = 77, + PP_EXITREP = 78, + PP_FATAL = 79, + PP_IASSIGN = 80, + PP_IDEFINE = 81, + PP_IDEFSTR = 82, + PP_IDEFTOK = 83, + PP_IMACRO = 84, + PP_INCLUDE = 85, + PP_IRMACRO = 86, + PP_IXDEFINE = 87, + PP_LINE = 88, + PP_LOCAL = 89, + PP_MACRO = 90, + PP_PATHSEARCH = 91, + PP_POP = 92, + PP_PRAGMA = 93, + PP_PUSH = 94, + PP_REP = 95, + PP_REPL = 96, + PP_RMACRO = 97, + PP_ROTATE = 98, + PP_STACKSIZE = 99, + PP_STRCAT = 100, + PP_STRLEN = 101, + PP_SUBSTR = 102, + PP_UNDEF = 103, + PP_UNIMACRO = 104, + PP_UNMACRO = 105, + PP_USE = 106, + PP_WARNING = 107, + PP_XDEFINE = 108, + PP_INVALID = -1 +}; + +enum pp_conditional { + PPC_IF = 0, PPC_IFCTX = 2, PPC_IFDEF = 4, PPC_IFEMPTY = 6, PPC_IFENV = 8, PPC_IFID = 10, PPC_IFIDN = 12, PPC_IFIDNI = 14, PPC_IFMACRO = 16, PPC_IFNUM = 18, PPC_IFSTR = 20, PPC_IFTOKEN = 22 +}; + +#define PP_COND(x) ((enum pp_conditional)((x) & 0x1e)) +#define PP_IS_COND(x) ((unsigned int)(x) < PP_ARG) +#define PP_NEGATIVE(x) ((x) & 1) + +#define CASE_PP_ELIF \ + case PP_ELIF: \ + case PP_ELIFN:\ + case PP_ELIFCTX: \ + case PP_ELIFNCTX:\ + case PP_ELIFDEF: \ + case PP_ELIFNDEF:\ + case PP_ELIFEMPTY: \ + case PP_ELIFNEMPTY:\ + case PP_ELIFENV: \ + case PP_ELIFNENV:\ + case PP_ELIFID: \ + case PP_ELIFNID:\ + case PP_ELIFIDN: \ + case PP_ELIFNIDN:\ + case PP_ELIFIDNI: \ + case PP_ELIFNIDNI:\ + case PP_ELIFMACRO: \ + case PP_ELIFNMACRO:\ + case PP_ELIFNUM: \ + case PP_ELIFNNUM:\ + case PP_ELIFSTR: \ + case PP_ELIFNSTR:\ + case PP_ELIFTOKEN: \ + case PP_ELIFNTOKEN +#define CASE_PP_IF \ + case PP_IF: \ + case PP_IFN:\ + case PP_IFCTX: \ + case PP_IFNCTX:\ + case PP_IFDEF: \ + case PP_IFNDEF:\ + case PP_IFEMPTY: \ + case PP_IFNEMPTY:\ + case PP_IFENV: \ + case PP_IFNENV:\ + case PP_IFID: \ + case PP_IFNID:\ + case PP_IFIDN: \ + case PP_IFNIDN:\ + case PP_IFIDNI: \ + case PP_IFNIDNI:\ + case PP_IFMACRO: \ + case PP_IFNMACRO:\ + case PP_IFNUM: \ + case PP_IFNNUM:\ + case PP_IFSTR: \ + case PP_IFNSTR:\ + case PP_IFTOKEN: \ + case PP_IFNTOKEN diff --git a/asm/pptok.ph b/asm/pptok.ph new file mode 100644 index 0000000..d355e98 --- /dev/null +++ b/asm/pptok.ph @@ -0,0 +1,99 @@ +# Automatically generated from ./asm/pptok.dat by ./asm/pptok.pl +# Do not edit + +%pptok_hash = ( + '%elif' => 0, + '%elifn' => 1, + '%elifctx' => 2, + '%elifnctx' => 3, + '%elifdef' => 4, + '%elifndef' => 5, + '%elifempty' => 6, + '%elifnempty' => 7, + '%elifenv' => 8, + '%elifnenv' => 9, + '%elifid' => 10, + '%elifnid' => 11, + '%elifidn' => 12, + '%elifnidn' => 13, + '%elifidni' => 14, + '%elifnidni' => 15, + '%elifmacro' => 16, + '%elifnmacro' => 17, + '%elifnum' => 18, + '%elifnnum' => 19, + '%elifstr' => 20, + '%elifnstr' => 21, + '%eliftoken' => 22, + '%elifntoken' => 23, + '%if' => 32, + '%ifn' => 33, + '%ifctx' => 34, + '%ifnctx' => 35, + '%ifdef' => 36, + '%ifndef' => 37, + '%ifempty' => 38, + '%ifnempty' => 39, + '%ifenv' => 40, + '%ifnenv' => 41, + '%ifid' => 42, + '%ifnid' => 43, + '%ifidn' => 44, + '%ifnidn' => 45, + '%ifidni' => 46, + '%ifnidni' => 47, + '%ifmacro' => 48, + '%ifnmacro' => 49, + '%ifnum' => 50, + '%ifnnum' => 51, + '%ifstr' => 52, + '%ifnstr' => 53, + '%iftoken' => 54, + '%ifntoken' => 55, + '%arg' => 64, + '%assign' => 65, + '%clear' => 66, + '%define' => 67, + '%defstr' => 68, + '%deftok' => 69, + '%depend' => 70, + '%else' => 71, + '%endif' => 72, + '%endm' => 73, + '%endmacro' => 74, + '%endrep' => 75, + '%error' => 76, + '%exitmacro' => 77, + '%exitrep' => 78, + '%fatal' => 79, + '%iassign' => 80, + '%idefine' => 81, + '%idefstr' => 82, + '%ideftok' => 83, + '%imacro' => 84, + '%include' => 85, + '%irmacro' => 86, + '%ixdefine' => 87, + '%line' => 88, + '%local' => 89, + '%macro' => 90, + '%pathsearch' => 91, + '%pop' => 92, + '%pragma' => 93, + '%push' => 94, + '%rep' => 95, + '%repl' => 96, + '%rmacro' => 97, + '%rotate' => 98, + '%stacksize' => 99, + '%strcat' => 100, + '%strlen' => 101, + '%substr' => 102, + '%undef' => 103, + '%unimacro' => 104, + '%unmacro' => 105, + '%use' => 106, + '%warning' => 107, + '%xdefine' => 108, +); +1; diff --git a/asm/pptok.pl b/asm/pptok.pl new file mode 100644 index 0000000..41f5f9f --- /dev/null +++ b/asm/pptok.pl @@ -0,0 +1,271 @@ +#!/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. +## +## -------------------------------------------------------------------------- + +# +# Produce pptok.c, pptok.h and pptok.ph from pptok.dat +# + +require 'phash.ph'; + +my($what, $in, $out) = @ARGV; + +# +# Read pptok.dat +# +open(IN, '<', $in) or die "$0: cannot open: $in\n"; +while (defined($line = )) { + $line =~ s/\r?\n$//; # Remove trailing \r\n or \n + $line =~ s/^\s+//; # Remove leading whitespace + $line =~ s/\s*\#.*$//; # Remove comments and trailing whitespace + next if ($line eq ''); + + if ($line =~ /^\%(.*)\*$/) { + push(@cctok, $1); + } elsif ($line =~ /^\%(.*)$/) { + push(@pptok, $1); + } elsif ($line =~ /^\*(.*)$/) { + push(@cond, $1); + } +} +close(IN); + +@cctok = sort @cctok; +@cond = sort @cond; +@pptok = sort @pptok; + +# Generate the expanded list including conditionals. The conditionals +# are at the beginning, padded to a power of 2, with the inverses +# interspersed; this allows a simple mask to pick out the condition. + +while ((scalar @cond) & (scalar @cond)-1) { + push(@cond, undef); +} + +@cptok = (); +foreach $ct (@cctok) { + foreach $cc (@cond) { + if (defined($cc)) { + push(@cptok, $ct.$cc); + push(@cptok, $ct.'n'.$cc); + } else { + push(@cptok, undef, undef); + } + } +} +$first_uncond = $pptok[0]; +@pptok = (@cptok, @pptok); + +open(OUT, '>', $out) or die "$0: cannot open: $out\n"; + +# +# Output pptok.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 preproc_token {\n"; + $n = 0; + foreach $pt (@pptok) { + if (defined($pt)) { + printf OUT " %-16s = %3d,\n", "PP_\U$pt\E", $n; + } + $n++; + } + printf OUT " %-16s = %3d\n", 'PP_INVALID', -1; + print OUT "};\n"; + print OUT "\n"; + + print OUT "enum pp_conditional {\n"; + $n = 0; + $c = ''; + foreach $cc (@cond) { + if (defined($cc)) { + printf OUT "$c %-16s = %3d", "PPC_IF\U$cc\E", $n; + $c = ','; + } + $n += 2; + } + print OUT "\n};\n\n"; + + printf OUT "#define PP_COND(x) ((enum pp_conditional)((x) & 0x%x))\n", + (scalar(@cond)-1) << 1; + print OUT "#define PP_IS_COND(x) ((unsigned int)(x) < PP_\U$first_uncond\E)\n"; + print OUT "#define PP_NEGATIVE(x) ((x) & 1)\n"; + print OUT "\n"; + + foreach $ct (@cctok) { + print OUT "#define CASE_PP_\U$ct\E"; + $pref = " \\\n"; + foreach $cc (@cond) { + if (defined($cc)) { + print OUT "$pref\tcase PP_\U${ct}${cc}\E: \\\n"; + print OUT "\tcase PP_\U${ct}N${cc}\E"; + $pref = ":\\\n"; + } + } + print OUT "\n"; # No colon or newline on the last one + } +} + +# +# Output pptok.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 (@pptok) { + 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 \"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 pp_directives[%d] = {\n", scalar(@pptok); + foreach $d (@pptok) { + if (defined($d)) { + print OUT " \"%$d\",\n"; + } else { + print OUT " NULL,\n"; + } + } + print OUT "};\n"; + + printf OUT "const uint8_t pp_directives_len[%d] = {\n", scalar(@pptok); + foreach $d (@pptok) { + printf OUT " %d,\n", defined($d) ? length($d)+1 : 0; + } + print OUT "};\n"; + + print OUT "enum preproc_token pp_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 (65535/3)\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(@pptok); + print OUT " return PP_INVALID;\n"; + print OUT "\n"; + + print OUT " if (!pp_directives[ix] || nasm_stricmp(pp_directives[ix], token))\n"; + print OUT " return PP_INVALID;\n"; + print OUT "\n"; + print OUT " return ix;\n"; + print OUT "}\n"; +} + +# +# Output pptok.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 "%pptok_hash = (\n"; + $n = 0; + foreach $tok (@pptok) { + if (defined($tok)) { + printf OUT " '%%%s' => %d,\n", $tok, $n; + } + $n++; + } + print OUT ");\n"; + print OUT "1;\n"; +} + + diff --git a/asm/pragma.c b/asm/pragma.c new file mode 100644 index 0000000..a4e7609 --- /dev/null +++ b/asm/pragma.c @@ -0,0 +1,274 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * Parse and handle [pragma] directives. The preprocessor handles + * %pragma preproc directives separately, all other namespaces are + * simply converted to [pragma]. + */ + +#include "compiler.h" + +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "assemble.h" +#include "error.h" + +static enum directive_result output_pragma(const struct pragma *pragma); +static enum directive_result limit_pragma(const struct pragma *pragma); + +/* + * Handle [pragma] directives. [pragma] is generally produced by + * the %pragma preprocessor directive, which simply passes on any + * string that it finds *except* %pragma preproc. The idea is + * that pragmas are of the form: + * + * %pragma [...] + * + * ... where "facility" can be either a generic facility or a backend + * name. + * + * The following names are currently reserved for global facilities; + * so far none of these have any defined pragmas at all: + * + * preproc - preprocessor + * limit - limit setting + * asm - assembler + * list - listing generator + * file - generic file handling + * input - input file handling + * output - backend-independent output handling + * debug - backend-independent debug handling + * ignore - dummy pragma (can be used to "comment out") + * + * This function should generally not error out if it doesn't understand + * what a pragma is for, for unknown arguments, etc; the whole point of + * a pragma is that future releases might add new ones that should be + * ignored rather than be an error. Erroring out is acceptable for + * known pragmas suffering from parsing errors and so on. + * + * Adding default-suppressed warnings would, however, be a good idea + * at some point. + */ +static struct pragma_facility global_pragmas[] = +{ + { "asm", NULL }, + { "limit", limit_pragma }, + { "list", NULL }, + { "file", NULL }, + { "input", NULL }, + + /* None of these should actually happen due to special handling */ + { "preproc", NULL }, /* Handled in the preprocessor by necessity */ + { "output", NULL }, + { "debug", NULL }, + { "ignore", NULL }, + { NULL, NULL } +}; + +/* + * Search a pragma list for a known pragma facility and if so, invoke + * the handler. Return true if processing is complete. + * The "default name", if set, matches the final NULL entry (used + * for backends, so multiple backends can share the same list under + * some circumstances.) + */ +static bool search_pragma_list(const struct pragma_facility *list, + const char *default_name, + pragma_handler generic_handler, + struct pragma *pragma) +{ + const struct pragma_facility *pf; + enum directive_result rv; + + if (!list) + return false; + + for (pf = list; pf->name; pf++) { + if (!nasm_stricmp(pragma->facility_name, pf->name)) + goto found_it; + } + + if (default_name && !nasm_stricmp(pragma->facility_name, default_name)) + goto found_it; + + return false; + +found_it: + pragma->facility = pf; + + /* If the handler is NULL all pragmas are unknown... */ + if (pf->handler) + rv = pf->handler(pragma); + else + rv = DIRR_UNKNOWN; + + /* Is there an additional, applicable generic handler? */ + if (rv == DIRR_UNKNOWN && generic_handler) + rv = generic_handler(pragma); + + switch (rv) { + case DIRR_UNKNOWN: + switch (pragma->opcode) { + case D_none: + nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_BAD_PRAGMA, + "empty %%pragma %s", pragma->facility_name); + break; + default: + nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_UNKNOWN_PRAGMA, + "unknown %%pragma %s %s", + pragma->facility_name, pragma->opname); + break; + } + break; + + case DIRR_OK: + case DIRR_ERROR: + break; /* Nothing to do */ + + case DIRR_BADPARAM: + /* + * This one is an error. Don't use it if forward compatibility + * would be compromised, as opposed to an inherent error. + */ + nasm_error(ERR_NONFATAL, "bad argument to %%pragma %s %s", + pragma->facility_name, pragma->opname); + break; + + default: + panic(); + } + return true; +} + +void process_pragma(char *str) +{ + struct pragma pragma; + char *p; + + nasm_zero(pragma); + + pragma.facility_name = nasm_get_word(str, &p); + if (!pragma.facility_name) { + nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_BAD_PRAGMA, + "empty pragma directive"); + return; /* Empty pragma */ + } + + /* + * The facility "ignore" means just that; don't even complain of + * the absence of an operation. + */ + if (!nasm_stricmp(pragma.facility_name, "ignore")) + return; + + /* + * The "output" and "debug" facilities are aliases for the + * current output and debug formats, respectively. + */ + if (!nasm_stricmp(pragma.facility_name, "output")) + pragma.facility_name = ofmt->shortname; + if (!nasm_stricmp(pragma.facility_name, "debug")) + pragma.facility_name = dfmt->shortname; + + pragma.opname = nasm_get_word(p, &p); + if (!pragma.opname) + pragma.opcode = D_none; + else + pragma.opcode = directive_find(pragma.opname); + + pragma.tail = nasm_trim_spaces(p); + + /* Look for a global pragma namespace */ + if (search_pragma_list(global_pragmas, NULL, NULL, &pragma)) + return; + + /* Look to see if it is an output backend pragma */ + if (search_pragma_list(ofmt->pragmas, ofmt->shortname, + output_pragma, &pragma)) + return; + + /* Look to see if it is a debug format pragma */ + if (search_pragma_list(dfmt->pragmas, dfmt->shortname, NULL, &pragma)) + return; + + /* + * Note: it would be nice to warn for an unknown namespace, + * but in order to do so we need to walk *ALL* the backends + * in order to make sure we aren't dealing with a pragma that + * is for another backend. On the other hand, that could + * also be a warning with a separate warning flag. + * + * Leave this for the future, however, the warning classes are + * already defined for future compatibility. + */ +} + +/* + * Generic pragmas that apply to all output backends; these are handled + * specially so they can be made selective based on the output format. + */ +static enum directive_result output_pragma(const struct pragma *pragma) +{ + switch (pragma->opcode) { + case D_PREFIX: + case D_GPREFIX: + set_label_mangle(LM_GPREFIX, pragma->tail); + return DIRR_OK; + case D_SUFFIX: + case D_GSUFFIX: + set_label_mangle(LM_GSUFFIX, pragma->tail); + return DIRR_OK; + case D_LPREFIX: + set_label_mangle(LM_LPREFIX, pragma->tail); + return DIRR_OK; + case D_LSUFFIX: + set_label_mangle(LM_LSUFFIX, pragma->tail); + return DIRR_OK; + default: + return DIRR_UNKNOWN; + } +} + +/* + * %pragma limit to set resource limits + */ +static enum directive_result limit_pragma(const struct pragma *pragma) +{ + return nasm_set_limit(pragma->opname, pragma->tail); +} diff --git a/asm/preproc-nop.c b/asm/preproc-nop.c new file mode 100644 index 0000000..6f7aaf9 --- /dev/null +++ b/asm/preproc-nop.c @@ -0,0 +1,195 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * This is a null preprocessor which just copies lines from input + * to output. It's used when someone explicitly requests that NASM + * not preprocess their source file. + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "preproc.h" +#include "listing.h" + +#define BUF_DELTA 512 + +static FILE *nop_fp; +static int32_t nop_lineinc; + +static void nop_init(void) +{ + /* Nothing to do */ +} + +static void nop_reset(const char *file, int pass, StrList **deplist) +{ + src_set(0, file); + nop_lineinc = 1; + nop_fp = nasm_open_read(file, NF_TEXT); + + if (!nop_fp) + nasm_fatal(ERR_NOFILE, "unable to open input file `%s'", file); + (void)pass; /* placate compilers */ + + nasm_add_string_to_strlist(deplist, file); +} + +static char *nop_getline(void) +{ + char *buffer, *p, *q; + int bufsize; + + bufsize = BUF_DELTA; + buffer = nasm_malloc(BUF_DELTA); + src_set_linnum(src_get_linnum() + nop_lineinc); + + while (1) { /* Loop to handle %line */ + + p = buffer; + while (1) { /* Loop to handle long lines */ + q = fgets(p, bufsize - (p - buffer), nop_fp); + if (!q) + break; + p += strlen(p); + if (p > buffer && p[-1] == '\n') + break; + if (p - buffer > bufsize - 10) { + int offset; + offset = p - buffer; + bufsize += BUF_DELTA; + buffer = nasm_realloc(buffer, bufsize); + p = buffer + offset; + } + } + + if (!q && p == buffer) { + nasm_free(buffer); + return NULL; + } + + /* + * Play safe: remove CRs, LFs and any spurious ^Zs, if any of + * them are present at the end of the line. + */ + buffer[strcspn(buffer, "\r\n\032")] = '\0'; + + if (!nasm_strnicmp(buffer, "%line", 5)) { + int32_t ln; + int li; + char *nm = nasm_malloc(strlen(buffer)); + if (sscanf(buffer + 5, "%"PRId32"+%d %s", &ln, &li, nm) == 3) { + src_set(ln, nm); + nop_lineinc = li; + nasm_free(nm); + continue; + } + nasm_free(nm); + } + break; + } + + lfmt->line(LIST_READ, buffer); + + return buffer; +} + +static void nop_cleanup(int pass) +{ + (void)pass; /* placate GCC */ + if (nop_fp) { + fclose(nop_fp); + nop_fp = NULL; + } +} + +static void nop_extra_stdmac(macros_t *macros) +{ + (void)macros; +} + +static void nop_pre_define(char *definition) +{ + (void)definition; +} + +static void nop_pre_undefine(char *definition) +{ + (void)definition; +} + +static void nop_pre_include(char *fname) +{ + (void)fname; +} + +static void nop_pre_command(const char *what, char *string) +{ + (void)what; + (void)string; +} + +static void nop_include_path(char *path) +{ + (void)path; +} + +static void nop_error_list_macros(int severity) +{ + (void)severity; +} + +const struct preproc_ops preproc_nop = { + nop_init, + nop_reset, + nop_getline, + nop_cleanup, + nop_extra_stdmac, + nop_pre_define, + nop_pre_undefine, + nop_pre_include, + nop_pre_command, + nop_include_path, + nop_error_list_macros, +}; diff --git a/asm/preproc.c b/asm/preproc.c new file mode 100644 index 0000000..ecf89f1 --- /dev/null +++ b/asm/preproc.c @@ -0,0 +1,5484 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * preproc.c macro preprocessor for the Netwide Assembler + */ + +/* Typical flow of text through preproc + * + * pp_getline gets tokenized lines, either + * + * from a macro expansion + * + * or + * { + * read_line gets raw text from stdmacpos, or predef, or current input file + * tokenize converts to tokens + * } + * + * expand_mmac_params is used to expand %1 etc., unless a macro is being + * defined or a false conditional is being processed + * (%0, %1, %+1, %-1, %%foo + * + * do_directive checks for directives + * + * expand_smacro is used to expand single line macros + * + * expand_mmacro is used to expand multi-line macros + * + * detoken is used to convert the line back to text + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "preproc.h" +#include "hashtbl.h" +#include "quote.h" +#include "stdscan.h" +#include "eval.h" +#include "tokens.h" +#include "tables.h" +#include "listing.h" + +typedef struct SMacro SMacro; +typedef struct MMacro MMacro; +typedef struct MMacroInvocation MMacroInvocation; +typedef struct Context Context; +typedef struct Token Token; +typedef struct Blocks Blocks; +typedef struct Line Line; +typedef struct Include Include; +typedef struct Cond Cond; +typedef struct IncPath IncPath; + +/* + * Note on the storage of both SMacro and MMacros: the hash table + * indexes them case-insensitively, and we then have to go through a + * linked list of potential case aliases (and, for MMacros, parameter + * ranges); this is to preserve the matching semantics of the earlier + * code. If the number of case aliases for a specific macro is a + * performance issue, you may want to reconsider your coding style. + */ + +/* + * Store the definition of a single-line macro. + */ +struct SMacro { + SMacro *next; + char *name; + bool casesense; + bool in_progress; + unsigned int nparam; + Token *expansion; +}; + +/* + * Store the definition of a multi-line macro. This is also used to + * store the interiors of `%rep...%endrep' blocks, which are + * effectively self-re-invoking multi-line macros which simply + * don't have a name or bother to appear in the hash tables. %rep + * blocks are signified by having a NULL `name' field. + * + * In a MMacro describing a `%rep' block, the `in_progress' field + * isn't merely boolean, but gives the number of repeats left to + * run. + * + * The `next' field is used for storing MMacros in hash tables; the + * `next_active' field is for stacking them on istk entries. + * + * When a MMacro is being expanded, `params', `iline', `nparam', + * `paramlen', `rotate' and `unique' are local to the invocation. + */ +struct MMacro { + MMacro *next; + MMacroInvocation *prev; /* previous invocation */ + char *name; + int nparam_min, nparam_max; + bool casesense; + bool plus; /* is the last parameter greedy? */ + bool nolist; /* is this macro listing-inhibited? */ + int64_t in_progress; /* is this macro currently being expanded? */ + int32_t max_depth; /* maximum number of recursive expansions allowed */ + Token *dlist; /* All defaults as one list */ + Token **defaults; /* Parameter default pointers */ + int ndefs; /* number of default parameters */ + Line *expansion; + + MMacro *next_active; + MMacro *rep_nest; /* used for nesting %rep */ + Token **params; /* actual parameters */ + Token *iline; /* invocation line */ + unsigned int nparam, rotate; + int *paramlen; + uint64_t unique; + int lineno; /* Current line number on expansion */ + uint64_t condcnt; /* number of if blocks... */ + + const char *fname; /* File where defined */ + int32_t xline; /* First line in macro */ +}; + + +/* Store the definition of a multi-line macro, as defined in a + * previous recursive macro expansion. + */ +struct MMacroInvocation { + MMacroInvocation *prev; /* previous invocation */ + Token **params; /* actual parameters */ + Token *iline; /* invocation line */ + unsigned int nparam, rotate; + int *paramlen; + uint64_t unique; + uint64_t condcnt; +}; + + +/* + * The context stack is composed of a linked list of these. + */ +struct Context { + Context *next; + char *name; + struct hash_table localmac; + uint32_t number; +}; + +/* + * This is the internal form which we break input lines up into. + * Typically stored in linked lists. + * + * Note that `type' serves a double meaning: TOK_SMAC_PARAM is not + * necessarily used as-is, but is intended to denote the number of + * the substituted parameter. So in the definition + * + * %define a(x,y) ( (x) & ~(y) ) + * + * the token representing `x' will have its type changed to + * TOK_SMAC_PARAM, but the one representing `y' will be + * TOK_SMAC_PARAM+1. + * + * TOK_INTERNAL_STRING is a dirty hack: it's a single string token + * which doesn't need quotes around it. Used in the pre-include + * mechanism as an alternative to trying to find a sensible type of + * quote to use on the filename we were passed. + */ +enum pp_token_type { + TOK_NONE = 0, TOK_WHITESPACE, TOK_COMMENT, TOK_ID, + TOK_PREPROC_ID, TOK_STRING, + TOK_NUMBER, TOK_FLOAT, TOK_SMAC_END, TOK_OTHER, + TOK_INTERNAL_STRING, + TOK_PREPROC_Q, TOK_PREPROC_QQ, + TOK_PASTE, /* %+ */ + TOK_INDIRECT, /* %[...] */ + TOK_SMAC_PARAM, /* MUST BE LAST IN THE LIST!!! */ + TOK_MAX = INT_MAX /* Keep compiler from reducing the range */ +}; + +#define PP_CONCAT_MASK(x) (1 << (x)) +#define PP_CONCAT_MATCH(t, mask) (PP_CONCAT_MASK((t)->type) & mask) + +struct tokseq_match { + int mask_head; + int mask_tail; +}; + +struct Token { + Token *next; + char *text; + union { + SMacro *mac; /* associated macro for TOK_SMAC_END */ + size_t len; /* scratch length field */ + } a; /* Auxiliary data */ + enum pp_token_type type; +}; + +/* + * Multi-line macro definitions are stored as a linked list of + * these, which is essentially a container to allow several linked + * lists of Tokens. + * + * Note that in this module, linked lists are treated as stacks + * wherever possible. For this reason, Lines are _pushed_ on to the + * `expansion' field in MMacro structures, so that the linked list, + * if walked, would give the macro lines in reverse order; this + * means that we can walk the list when expanding a macro, and thus + * push the lines on to the `expansion' field in _istk_ in reverse + * order (so that when popped back off they are in the right + * order). It may seem cockeyed, and it relies on my design having + * an even number of steps in, but it works... + * + * Some of these structures, rather than being actual lines, are + * markers delimiting the end of the expansion of a given macro. + * This is for use in the cycle-tracking and %rep-handling code. + * Such structures have `finishes' non-NULL, and `first' NULL. All + * others have `finishes' NULL, but `first' may still be NULL if + * the line is blank. + */ +struct Line { + Line *next; + MMacro *finishes; + Token *first; +}; + +/* + * To handle an arbitrary level of file inclusion, we maintain a + * stack (ie linked list) of these things. + */ +struct Include { + Include *next; + FILE *fp; + Cond *conds; + Line *expansion; + const char *fname; + int lineno, lineinc; + MMacro *mstk; /* stack of active macros/reps */ +}; + +/* + * Include search path. This is simply a list of strings which get + * prepended, in turn, to the name of an include file, in an + * attempt to find the file if it's not in the current directory. + */ +struct IncPath { + IncPath *next; + char *path; +}; + +/* + * File real name hash, so we don't have to re-search the include + * path for every pass (and potentially more than that if a file + * is used more than once.) + */ +struct hash_table FileHash; + +/* + * Conditional assembly: we maintain a separate stack of these for + * each level of file inclusion. (The only reason we keep the + * stacks separate is to ensure that a stray `%endif' in a file + * included from within the true branch of a `%if' won't terminate + * it and cause confusion: instead, rightly, it'll cause an error.) + */ +struct Cond { + Cond *next; + int state; +}; +enum { + /* + * These states are for use just after %if or %elif: IF_TRUE + * means the condition has evaluated to truth so we are + * currently emitting, whereas IF_FALSE means we are not + * currently emitting but will start doing so if a %else comes + * up. In these states, all directives are admissible: %elif, + * %else and %endif. (And of course %if.) + */ + COND_IF_TRUE, COND_IF_FALSE, + /* + * These states come up after a %else: ELSE_TRUE means we're + * emitting, and ELSE_FALSE means we're not. In ELSE_* states, + * any %elif or %else will cause an error. + */ + COND_ELSE_TRUE, COND_ELSE_FALSE, + /* + * These states mean that we're not emitting now, and also that + * nothing until %endif will be emitted at all. COND_DONE is + * used when we've had our moment of emission + * and have now started seeing %elifs. COND_NEVER is used when + * the condition construct in question is contained within a + * non-emitting branch of a larger condition construct, + * or if there is an error. + */ + COND_DONE, COND_NEVER +}; +#define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE ) + +/* + * These defines are used as the possible return values for do_directive + */ +#define NO_DIRECTIVE_FOUND 0 +#define DIRECTIVE_FOUND 1 + +/* max reps */ +#define REP_LIMIT ((INT64_C(1) << 62)) + +/* + * Condition codes. Note that we use c_ prefix not C_ because C_ is + * used in nasm.h for the "real" condition codes. At _this_ level, + * we treat CXZ and ECXZ as condition codes, albeit non-invertible + * ones, so we need a different enum... + */ +static const char * const conditions[] = { + "a", "ae", "b", "be", "c", "cxz", "e", "ecxz", "g", "ge", "l", "le", + "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", + "np", "ns", "nz", "o", "p", "pe", "po", "rcxz", "s", "z" +}; +enum pp_conds { + c_A, c_AE, c_B, c_BE, c_C, c_CXZ, c_E, c_ECXZ, c_G, c_GE, c_L, c_LE, + c_NA, c_NAE, c_NB, c_NBE, c_NC, c_NE, c_NG, c_NGE, c_NL, c_NLE, c_NO, + c_NP, c_NS, c_NZ, c_O, c_P, c_PE, c_PO, c_RCXZ, c_S, c_Z, + c_none = -1 +}; +static const enum pp_conds inverse_ccs[] = { + c_NA, c_NAE, c_NB, c_NBE, c_NC, -1, c_NE, -1, c_NG, c_NGE, c_NL, c_NLE, + c_A, c_AE, c_B, c_BE, c_C, c_E, c_G, c_GE, c_L, c_LE, c_O, c_P, c_S, + c_Z, c_NO, c_NP, c_PO, c_PE, -1, c_NS, c_NZ +}; + +/* + * Directive names. + */ +/* If this is a an IF, ELIF, ELSE or ENDIF keyword */ +static int is_condition(enum preproc_token arg) +{ + return PP_IS_COND(arg) || (arg == PP_ELSE) || (arg == PP_ENDIF); +} + +/* For TASM compatibility we need to be able to recognise TASM compatible + * conditional compilation directives. Using the NASM pre-processor does + * not work, so we look for them specifically from the following list and + * then jam in the equivalent NASM directive into the input stream. + */ + +enum { + TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI, + TM_IFNDEF, TM_INCLUDE, TM_LOCAL +}; + +static const char * const tasm_directives[] = { + "arg", "elif", "else", "endif", "if", "ifdef", "ifdifi", + "ifndef", "include", "local" +}; + +static int StackSize = 4; +static const char *StackPointer = "ebp"; +static int ArgOffset = 8; +static int LocalOffset = 0; + +static Context *cstk; +static Include *istk; +static IncPath *ipath = NULL; + +static int pass; /* HACK: pass 0 = generate dependencies only */ +static StrList **dephead; + +static uint64_t unique; /* unique identifier numbers */ + +static Line *predef = NULL; +static bool do_predef; + +/* + * The current set of multi-line macros we have defined. + */ +static struct hash_table mmacros; + +/* + * The current set of single-line macros we have defined. + */ +static struct hash_table smacros; + +/* + * The multi-line macro we are currently defining, or the %rep + * block we are currently reading, if any. + */ +static MMacro *defining; + +static uint64_t nested_mac_count; +static uint64_t nested_rep_count; + +/* + * The number of macro parameters to allocate space for at a time. + */ +#define PARAM_DELTA 16 + +/* + * The standard macro set: defined in macros.c in a set of arrays. + * This gives our position in any macro set, while we are processing it. + * The stdmacset is an array of such macro sets. + */ +static macros_t *stdmacpos; +static macros_t **stdmacnext; +static macros_t *stdmacros[8]; +static macros_t *extrastdmac; + +/* + * Tokens are allocated in blocks to improve speed + */ +#define TOKEN_BLOCKSIZE 4096 +static Token *freeTokens = NULL; +struct Blocks { + Blocks *next; + void *chunk; +}; + +static Blocks blocks = { NULL, NULL }; + +/* + * Forward declarations. + */ +static void pp_add_stdmac(macros_t *macros); +static Token *expand_mmac_params(Token * tline); +static Token *expand_smacro(Token * tline); +static Token *expand_id(Token * tline); +static Context *get_ctx(const char *name, const char **namep); +static void make_tok_num(Token * tok, int64_t val); +static void pp_verror(int severity, const char *fmt, va_list ap); +static vefunc real_verror; +static void *new_Block(size_t size); +static void delete_Blocks(void); +static Token *new_Token(Token * next, enum pp_token_type type, + const char *text, int txtlen); +static Token *delete_Token(Token * t); + +/* + * Macros for safe checking of token pointers, avoid *(NULL) + */ +#define tok_type_(x,t) ((x) && (x)->type == (t)) +#define skip_white_(x) if (tok_type_((x), TOK_WHITESPACE)) (x)=(x)->next +#define tok_is_(x,v) (tok_type_((x), TOK_OTHER) && !strcmp((x)->text,(v))) +#define tok_isnt_(x,v) ((x) && ((x)->type!=TOK_OTHER || strcmp((x)->text,(v)))) + +/* + * nasm_unquote with error if the string contains NUL characters. + * If the string contains NUL characters, issue an error and return + * the C len, i.e. truncate at the NUL. + */ +static size_t nasm_unquote_cstr(char *qstr, enum preproc_token directive) +{ + size_t len = nasm_unquote(qstr, NULL); + size_t clen = strlen(qstr); + + if (len != clen) + nasm_error(ERR_NONFATAL, "NUL character in `%s' directive", + pp_directives[directive]); + + return clen; +} + +/* + * In-place reverse a list of tokens. + */ +static Token *reverse_tokens(Token *t) +{ + Token *prev = NULL; + Token *next; + + while (t) { + next = t->next; + t->next = prev; + prev = t; + t = next; + } + + return prev; +} + +/* + * Handle TASM specific directives, which do not contain a % in + * front of them. We do it here because I could not find any other + * place to do it for the moment, and it is a hack (ideally it would + * be nice to be able to use the NASM pre-processor to do it). + */ +static char *check_tasm_directive(char *line) +{ + int32_t i, j, k, m, len; + char *p, *q, *oldline, oldchar; + + p = nasm_skip_spaces(line); + + /* Binary search for the directive name */ + i = -1; + j = ARRAY_SIZE(tasm_directives); + q = nasm_skip_word(p); + len = q - p; + if (len) { + oldchar = p[len]; + p[len] = 0; + while (j - i > 1) { + k = (j + i) / 2; + m = nasm_stricmp(p, tasm_directives[k]); + if (m == 0) { + /* We have found a directive, so jam a % in front of it + * so that NASM will then recognise it as one if it's own. + */ + p[len] = oldchar; + len = strlen(p); + oldline = line; + line = nasm_malloc(len + 2); + line[0] = '%'; + if (k == TM_IFDIFI) { + /* + * NASM does not recognise IFDIFI, so we convert + * it to %if 0. This is not used in NASM + * compatible code, but does need to parse for the + * TASM macro package. + */ + strcpy(line + 1, "if 0"); + } else { + memcpy(line + 1, p, len + 1); + } + nasm_free(oldline); + return line; + } else if (m < 0) { + j = k; + } else + i = k; + } + p[len] = oldchar; + } + return line; +} + +/* + * The pre-preprocessing stage... This function translates line + * number indications as they emerge from GNU cpp (`# lineno "file" + * flags') into NASM preprocessor line number indications (`%line + * lineno file'). + */ +static char *prepreproc(char *line) +{ + int lineno, fnlen; + char *fname, *oldline; + + if (line[0] == '#' && line[1] == ' ') { + oldline = line; + fname = oldline + 2; + lineno = atoi(fname); + fname += strspn(fname, "0123456789 "); + if (*fname == '"') + fname++; + fnlen = strcspn(fname, "\""); + line = nasm_malloc(20 + fnlen); + snprintf(line, 20 + fnlen, "%%line %d %.*s", lineno, fnlen, fname); + nasm_free(oldline); + } + if (tasm_compatible_mode) + return check_tasm_directive(line); + return line; +} + +/* + * Free a linked list of tokens. + */ +static void free_tlist(Token * list) +{ + while (list) + list = delete_Token(list); +} + +/* + * Free a linked list of lines. + */ +static void free_llist(Line * list) +{ + Line *l, *tmp; + list_for_each_safe(l, tmp, list) { + free_tlist(l->first); + nasm_free(l); + } +} + +/* + * Free an MMacro + */ +static void free_mmacro(MMacro * m) +{ + nasm_free(m->name); + free_tlist(m->dlist); + nasm_free(m->defaults); + free_llist(m->expansion); + nasm_free(m); +} + +/* + * Free all currently defined macros, and free the hash tables + */ +static void free_smacro_table(struct hash_table *smt) +{ + SMacro *s, *tmp; + const char *key; + struct hash_tbl_node *it = NULL; + + while ((s = hash_iterate(smt, &it, &key)) != NULL) { + nasm_free((void *)key); + list_for_each_safe(s, tmp, s) { + nasm_free(s->name); + free_tlist(s->expansion); + nasm_free(s); + } + } + hash_free(smt); +} + +static void free_mmacro_table(struct hash_table *mmt) +{ + MMacro *m, *tmp; + const char *key; + struct hash_tbl_node *it = NULL; + + it = NULL; + while ((m = hash_iterate(mmt, &it, &key)) != NULL) { + nasm_free((void *)key); + list_for_each_safe(m ,tmp, m) + free_mmacro(m); + } + hash_free(mmt); +} + +static void free_macros(void) +{ + free_smacro_table(&smacros); + free_mmacro_table(&mmacros); +} + +/* + * Initialize the hash tables + */ +static void init_macros(void) +{ + hash_init(&smacros, HASH_LARGE); + hash_init(&mmacros, HASH_LARGE); +} + +/* + * Pop the context stack. + */ +static void ctx_pop(void) +{ + Context *c = cstk; + + cstk = cstk->next; + free_smacro_table(&c->localmac); + nasm_free(c->name); + nasm_free(c); +} + +/* + * Search for a key in the hash index; adding it if necessary + * (in which case we initialize the data pointer to NULL.) + */ +static void ** +hash_findi_add(struct hash_table *hash, const char *str) +{ + struct hash_insert hi; + void **r; + char *strx; + + r = hash_findi(hash, str, &hi); + if (r) + return r; + + strx = nasm_strdup(str); /* Use a more efficient allocator here? */ + return hash_add(&hi, strx, NULL); +} + +/* + * Like hash_findi, but returns the data element rather than a pointer + * to it. Used only when not adding a new element, hence no third + * argument. + */ +static void * +hash_findix(struct hash_table *hash, const char *str) +{ + void **p; + + p = hash_findi(hash, str, NULL); + return p ? *p : NULL; +} + +/* + * read line from standart macros set, + * if there no more left -- return NULL + */ +static char *line_from_stdmac(void) +{ + unsigned char c; + const unsigned char *p = stdmacpos; + char *line, *q; + size_t len = 0; + + if (!stdmacpos) + return NULL; + + while ((c = *p++)) { + if (c >= 0x80) + len += pp_directives_len[c - 0x80] + 1; + else + len++; + } + + line = nasm_malloc(len + 1); + q = line; + while ((c = *stdmacpos++)) { + if (c >= 0x80) { + memcpy(q, pp_directives[c - 0x80], pp_directives_len[c - 0x80]); + q += pp_directives_len[c - 0x80]; + *q++ = ' '; + } else { + *q++ = c; + } + } + stdmacpos = p; + *q = '\0'; + + if (!*stdmacpos) { + /* This was the last of this particular macro set */ + stdmacpos = NULL; + if (*stdmacnext) { + stdmacpos = *stdmacnext++; + } else if (do_predef) { + Line *pd, *l; + Token *head, **tail, *t; + + /* + * Nasty hack: here we push the contents of + * `predef' on to the top-level expansion stack, + * since this is the most convenient way to + * implement the pre-include and pre-define + * features. + */ + list_for_each(pd, predef) { + head = NULL; + tail = &head; + list_for_each(t, pd->first) { + *tail = new_Token(NULL, t->type, t->text, 0); + tail = &(*tail)->next; + } + + l = nasm_malloc(sizeof(Line)); + l->next = istk->expansion; + l->first = head; + l->finishes = NULL; + + istk->expansion = l; + } + do_predef = false; + } + } + + return line; +} + +static char *read_line(void) +{ + unsigned int size, c, next; + const unsigned int delta = 512; + const unsigned int pad = 8; + unsigned int nr_cont = 0; + bool cont = false; + char *buffer, *p; + + /* Standart macros set (predefined) goes first */ + p = line_from_stdmac(); + if (p) + return p; + + size = delta; + p = buffer = nasm_malloc(size); + + for (;;) { + c = fgetc(istk->fp); + if ((int)(c) == EOF) { + p[0] = 0; + break; + } + + switch (c) { + case '\r': + next = fgetc(istk->fp); + if (next != '\n') + ungetc(next, istk->fp); + if (cont) { + cont = false; + continue; + } + break; + + case '\n': + if (cont) { + cont = false; + continue; + } + break; + + case '\\': + next = fgetc(istk->fp); + ungetc(next, istk->fp); + if (next == '\r' || next == '\n') { + cont = true; + nr_cont++; + continue; + } + break; + } + + if (c == '\r' || c == '\n') { + *p++ = 0; + break; + } + + if (p >= (buffer + size - pad)) { + buffer = nasm_realloc(buffer, size + delta); + p = buffer + size - pad; + size += delta; + } + + *p++ = (unsigned char)c; + } + + if (p == buffer) { + nasm_free(buffer); + return NULL; + } + + src_set_linnum(src_get_linnum() + istk->lineinc + + (nr_cont * istk->lineinc)); + + /* + * Handle spurious ^Z, which may be inserted into source files + * by some file transfer utilities. + */ + buffer[strcspn(buffer, "\032")] = '\0'; + + lfmt->line(LIST_READ, buffer); + + return buffer; +} + +/* + * Tokenize a line of text. This is a very simple process since we + * don't need to parse the value out of e.g. numeric tokens: we + * simply split one string into many. + */ +static Token *tokenize(char *line) +{ + char c, *p = line; + enum pp_token_type type; + Token *list = NULL; + Token *t, **tail = &list; + + while (*line) { + p = line; + if (*p == '%') { + p++; + if (*p == '+' && !nasm_isdigit(p[1])) { + p++; + type = TOK_PASTE; + } else if (nasm_isdigit(*p) || + ((*p == '-' || *p == '+') && nasm_isdigit(p[1]))) { + do { + p++; + } + while (nasm_isdigit(*p)); + type = TOK_PREPROC_ID; + } else if (*p == '{') { + p++; + while (*p) { + if (*p == '}') + break; + p[-1] = *p; + p++; + } + if (*p != '}') + nasm_error(ERR_WARNING | ERR_PASS1, + "unterminated %%{ construct"); + p[-1] = '\0'; + if (*p) + p++; + type = TOK_PREPROC_ID; + } else if (*p == '[') { + int lvl = 1; + line += 2; /* Skip the leading %[ */ + p++; + while (lvl && (c = *p++)) { + switch (c) { + case ']': + lvl--; + break; + case '%': + if (*p == '[') + lvl++; + break; + case '\'': + case '\"': + case '`': + p = nasm_skip_string(p - 1); + if (*p) + p++; + break; + default: + break; + } + } + p--; + if (*p) + *p++ = '\0'; + if (lvl) + nasm_error(ERR_NONFATAL|ERR_PASS1, + "unterminated %%[ construct"); + type = TOK_INDIRECT; + } else if (*p == '?') { + type = TOK_PREPROC_Q; /* %? */ + p++; + if (*p == '?') { + type = TOK_PREPROC_QQ; /* %?? */ + p++; + } + } else if (*p == '!') { + type = TOK_PREPROC_ID; + p++; + if (isidchar(*p)) { + do { + p++; + } + while (isidchar(*p)); + } else if (*p == '\'' || *p == '\"' || *p == '`') { + p = nasm_skip_string(p); + if (*p) + p++; + else + nasm_error(ERR_NONFATAL|ERR_PASS1, + "unterminated %%! string"); + } else { + /* %! without string or identifier */ + type = TOK_OTHER; /* Legacy behavior... */ + } + } else if (isidchar(*p) || + ((*p == '!' || *p == '%' || *p == '$') && + isidchar(p[1]))) { + do { + p++; + } + while (isidchar(*p)); + type = TOK_PREPROC_ID; + } else { + type = TOK_OTHER; + if (*p == '%') + p++; + } + } else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) { + type = TOK_ID; + p++; + while (*p && isidchar(*p)) + p++; + } else if (*p == '\'' || *p == '"' || *p == '`') { + /* + * A string token. + */ + type = TOK_STRING; + p = nasm_skip_string(p); + + if (*p) { + p++; + } else { + nasm_error(ERR_WARNING|ERR_PASS1, "unterminated string"); + /* Handling unterminated strings by UNV */ + /* type = -1; */ + } + } else if (p[0] == '$' && p[1] == '$') { + type = TOK_OTHER; /* TOKEN_BASE */ + p += 2; + } else if (isnumstart(*p)) { + bool is_hex = false; + bool is_float = false; + bool has_e = false; + char c, *r; + + /* + * A numeric token. + */ + + if (*p == '$') { + p++; + is_hex = true; + } + + for (;;) { + c = *p++; + + if (!is_hex && (c == 'e' || c == 'E')) { + has_e = true; + if (*p == '+' || *p == '-') { + /* + * e can only be followed by +/- if it is either a + * prefixed hex number or a floating-point number + */ + p++; + is_float = true; + } + } else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') { + is_hex = true; + } else if (c == 'P' || c == 'p') { + is_float = true; + if (*p == '+' || *p == '-') + p++; + } else if (isnumchar(c)) + ; /* just advance */ + else if (c == '.') { + /* + * we need to deal with consequences of the legacy + * parser, like "1.nolist" being two tokens + * (TOK_NUMBER, TOK_ID) here; at least give it + * a shot for now. In the future, we probably need + * a flex-based scanner with proper pattern matching + * to do it as well as it can be done. Nothing in + * the world is going to help the person who wants + * 0x123.p16 interpreted as two tokens, though. + */ + r = p; + while (*r == '_') + r++; + + if (nasm_isdigit(*r) || (is_hex && nasm_isxdigit(*r)) || + (!is_hex && (*r == 'e' || *r == 'E')) || + (*r == 'p' || *r == 'P')) { + p = r; + is_float = true; + } else + break; /* Terminate the token */ + } else + break; + } + p--; /* Point to first character beyond number */ + + if (p == line+1 && *line == '$') { + type = TOK_OTHER; /* TOKEN_HERE */ + } else { + if (has_e && !is_hex) { + /* 1e13 is floating-point, but 1e13h is not */ + is_float = true; + } + + type = is_float ? TOK_FLOAT : TOK_NUMBER; + } + } else if (nasm_isspace(*p)) { + type = TOK_WHITESPACE; + p = nasm_skip_spaces(p); + /* + * Whitespace just before end-of-line is discarded by + * pretending it's a comment; whitespace just before a + * comment gets lumped into the comment. + */ + if (!*p || *p == ';') { + type = TOK_COMMENT; + while (*p) + p++; + } + } else if (*p == ';') { + type = TOK_COMMENT; + while (*p) + p++; + } else { + /* + * Anything else is an operator of some kind. We check + * for all the double-character operators (>>, <<, //, + * %%, <=, >=, ==, !=, <>, &&, ||, ^^), but anything + * else is a single-character operator. + */ + type = TOK_OTHER; + if ((p[0] == '>' && p[1] == '>') || + (p[0] == '<' && p[1] == '<') || + (p[0] == '/' && p[1] == '/') || + (p[0] == '<' && p[1] == '=') || + (p[0] == '>' && p[1] == '=') || + (p[0] == '=' && p[1] == '=') || + (p[0] == '!' && p[1] == '=') || + (p[0] == '<' && p[1] == '>') || + (p[0] == '&' && p[1] == '&') || + (p[0] == '|' && p[1] == '|') || + (p[0] == '^' && p[1] == '^')) { + p++; + } + p++; + } + + /* Handling unterminated string by UNV */ + /*if (type == -1) + { + *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1); + t->text[p-line] = *line; + tail = &t->next; + } + else */ + if (type != TOK_COMMENT) { + *tail = t = new_Token(NULL, type, line, p - line); + tail = &t->next; + } + line = p; + } + return list; +} + +/* + * this function allocates a new managed block of memory and + * returns a pointer to the block. The managed blocks are + * deleted only all at once by the delete_Blocks function. + */ +static void *new_Block(size_t size) +{ + Blocks *b = &blocks; + + /* first, get to the end of the linked list */ + while (b->next) + b = b->next; + /* now allocate the requested chunk */ + b->chunk = nasm_malloc(size); + + /* now allocate a new block for the next request */ + b->next = nasm_zalloc(sizeof(Blocks)); + return b->chunk; +} + +/* + * this function deletes all managed blocks of memory + */ +static void delete_Blocks(void) +{ + Blocks *a, *b = &blocks; + + /* + * keep in mind that the first block, pointed to by blocks + * is a static and not dynamically allocated, so we don't + * free it. + */ + while (b) { + if (b->chunk) + nasm_free(b->chunk); + a = b; + b = b->next; + if (a != &blocks) + nasm_free(a); + } + memset(&blocks, 0, sizeof(blocks)); +} + +/* + * this function creates a new Token and passes a pointer to it + * back to the caller. It sets the type and text elements, and + * also the a.mac and next elements to NULL. + */ +static Token *new_Token(Token * next, enum pp_token_type type, + const char *text, int txtlen) +{ + Token *t; + int i; + + if (!freeTokens) { + freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token)); + for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++) + freeTokens[i].next = &freeTokens[i + 1]; + freeTokens[i].next = NULL; + } + t = freeTokens; + freeTokens = t->next; + t->next = next; + t->a.mac = NULL; + t->type = type; + if (type == TOK_WHITESPACE || !text) { + t->text = NULL; + } else { + if (txtlen == 0) + txtlen = strlen(text); + t->text = nasm_malloc(txtlen+1); + memcpy(t->text, text, txtlen); + t->text[txtlen] = '\0'; + } + return t; +} + +static Token *delete_Token(Token * t) +{ + Token *next = t->next; + nasm_free(t->text); + t->next = freeTokens; + freeTokens = t; + return next; +} + +/* + * Convert a line of tokens back into text. + * If expand_locals is not zero, identifiers of the form "%$*xxx" + * will be transformed into ..@ctxnum.xxx + */ +static char *detoken(Token * tlist, bool expand_locals) +{ + Token *t; + char *line, *p; + const char *q; + int len = 0; + + list_for_each(t, tlist) { + if (t->type == TOK_PREPROC_ID && t->text && + t->text[0] && t->text[1] == '!') { + char *v; + char *q = t->text; + + v = t->text + 2; + if (*v == '\'' || *v == '\"' || *v == '`') { + size_t len = nasm_unquote(v, NULL); + size_t clen = strlen(v); + + if (len != clen) { + nasm_error(ERR_NONFATAL | ERR_PASS1, + "NUL character in %%! string"); + v = NULL; + } + } + + if (v) { + char *p = getenv(v); + if (!p) { + nasm_error(ERR_NONFATAL | ERR_PASS1, + "nonexistent environment variable `%s'", v); + /* + * FIXME We better should investigate if accessing + * ->text[1] without ->text[0] is safe enough. + */ + t->text = nasm_zalloc(2); + } else + t->text = nasm_strdup(p); + nasm_free(q); + } + } + + /* Expand local macros here and not during preprocessing */ + if (expand_locals && + t->type == TOK_PREPROC_ID && t->text && + t->text[0] == '%' && t->text[1] == '$') { + const char *q; + char *p; + Context *ctx = get_ctx(t->text, &q); + if (ctx) { + char buffer[40]; + snprintf(buffer, sizeof(buffer), "..@%"PRIu32".", ctx->number); + p = nasm_strcat(buffer, q); + nasm_free(t->text); + t->text = p; + } + } + if (t->type == TOK_WHITESPACE) + len++; + else if (t->text) + len += strlen(t->text); + } + + p = line = nasm_malloc(len + 1); + + list_for_each(t, tlist) { + if (t->type == TOK_WHITESPACE) { + *p++ = ' '; + } else if (t->text) { + q = t->text; + while (*q) + *p++ = *q++; + } + } + *p = '\0'; + + return line; +} + +/* + * A scanner, suitable for use by the expression evaluator, which + * operates on a line of Tokens. Expects a pointer to a pointer to + * the first token in the line to be passed in as its private_data + * field. + * + * FIX: This really needs to be unified with stdscan. + */ +static int ppscan(void *private_data, struct tokenval *tokval) +{ + Token **tlineptr = private_data; + Token *tline; + char ourcopy[MAX_KEYWORD+1], *p, *r, *s; + + do { + tline = *tlineptr; + *tlineptr = tline ? tline->next : NULL; + } while (tline && (tline->type == TOK_WHITESPACE || + tline->type == TOK_COMMENT)); + + if (!tline) + return tokval->t_type = TOKEN_EOS; + + tokval->t_charptr = tline->text; + + if (tline->text[0] == '$' && !tline->text[1]) + return tokval->t_type = TOKEN_HERE; + if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[2]) + return tokval->t_type = TOKEN_BASE; + + if (tline->type == TOK_ID) { + p = tokval->t_charptr = tline->text; + if (p[0] == '$') { + tokval->t_charptr++; + return tokval->t_type = TOKEN_ID; + } + + for (r = p, s = ourcopy; *r; r++) { + if (r >= p+MAX_KEYWORD) + return tokval->t_type = TOKEN_ID; /* Not a keyword */ + *s++ = nasm_tolower(*r); + } + *s = '\0'; + /* right, so we have an identifier sitting in temp storage. now, + * is it actually a register or instruction name, or what? */ + return nasm_token_hash(ourcopy, tokval); + } + + if (tline->type == TOK_NUMBER) { + bool rn_error; + tokval->t_integer = readnum(tline->text, &rn_error); + tokval->t_charptr = tline->text; + if (rn_error) + return tokval->t_type = TOKEN_ERRNUM; + else + return tokval->t_type = TOKEN_NUM; + } + + if (tline->type == TOK_FLOAT) { + return tokval->t_type = TOKEN_FLOAT; + } + + if (tline->type == TOK_STRING) { + char bq, *ep; + + bq = tline->text[0]; + tokval->t_charptr = tline->text; + tokval->t_inttwo = nasm_unquote(tline->text, &ep); + + if (ep[0] != bq || ep[1] != '\0') + return tokval->t_type = TOKEN_ERRSTR; + else + return tokval->t_type = TOKEN_STR; + } + + if (tline->type == TOK_OTHER) { + if (!strcmp(tline->text, "<<")) + return tokval->t_type = TOKEN_SHL; + if (!strcmp(tline->text, ">>")) + return tokval->t_type = TOKEN_SHR; + if (!strcmp(tline->text, "//")) + return tokval->t_type = TOKEN_SDIV; + if (!strcmp(tline->text, "%%")) + return tokval->t_type = TOKEN_SMOD; + if (!strcmp(tline->text, "==")) + return tokval->t_type = TOKEN_EQ; + if (!strcmp(tline->text, "<>")) + return tokval->t_type = TOKEN_NE; + if (!strcmp(tline->text, "!=")) + return tokval->t_type = TOKEN_NE; + if (!strcmp(tline->text, "<=")) + return tokval->t_type = TOKEN_LE; + if (!strcmp(tline->text, ">=")) + return tokval->t_type = TOKEN_GE; + if (!strcmp(tline->text, "&&")) + return tokval->t_type = TOKEN_DBL_AND; + if (!strcmp(tline->text, "^^")) + return tokval->t_type = TOKEN_DBL_XOR; + if (!strcmp(tline->text, "||")) + return tokval->t_type = TOKEN_DBL_OR; + } + + /* + * We have no other options: just return the first character of + * the token text. + */ + return tokval->t_type = tline->text[0]; +} + +/* + * Compare a string to the name of an existing macro; this is a + * simple wrapper which calls either strcmp or nasm_stricmp + * depending on the value of the `casesense' parameter. + */ +static int mstrcmp(const char *p, const char *q, bool casesense) +{ + return casesense ? strcmp(p, q) : nasm_stricmp(p, q); +} + +/* + * Compare a string to the name of an existing macro; this is a + * simple wrapper which calls either strcmp or nasm_stricmp + * depending on the value of the `casesense' parameter. + */ +static int mmemcmp(const char *p, const char *q, size_t l, bool casesense) +{ + return casesense ? memcmp(p, q, l) : nasm_memicmp(p, q, l); +} + +/* + * Return the Context structure associated with a %$ token. Return + * NULL, having _already_ reported an error condition, if the + * context stack isn't deep enough for the supplied number of $ + * signs. + * + * If "namep" is non-NULL, set it to the pointer to the macro name + * tail, i.e. the part beyond %$... + */ +static Context *get_ctx(const char *name, const char **namep) +{ + Context *ctx; + int i; + + if (namep) + *namep = name; + + if (!name || name[0] != '%' || name[1] != '$') + return NULL; + + if (!cstk) { + nasm_error(ERR_NONFATAL, "`%s': context stack is empty", name); + return NULL; + } + + name += 2; + ctx = cstk; + i = 0; + while (ctx && *name == '$') { + name++; + i++; + ctx = ctx->next; + } + if (!ctx) { + nasm_error(ERR_NONFATAL, "`%s': context stack is only" + " %d level%s deep", name, i, (i == 1 ? "" : "s")); + return NULL; + } + + if (namep) + *namep = name; + + return ctx; +} + +/* + * Open an include file. This routine must always return a valid + * file pointer if it returns - it's responsible for throwing an + * ERR_FATAL and bombing out completely if not. It should also try + * the include path one by one until it finds the file or reaches + * the end of the path. + * + * Note: for INC_PROBE the function returns NULL at all times; + * instead look for the + */ +enum incopen_mode { + INC_NEEDED, /* File must exist */ + INC_OPTIONAL, /* Missing is OK */ + INC_PROBE /* Only an existence probe */ +}; + +/* This is conducts a full pathname search */ +static FILE *inc_fopen_search(const char *file, StrList **slpath, + enum incopen_mode omode, enum file_flags fmode) +{ + FILE *fp; + char *prefix = ""; + const IncPath *ip = ipath; + int len; + StrList *sl; + char *sp; + bool found; + + while (1) { + sp = nasm_catfile(prefix, file); + len = strlen(sp) + 1; + sl = nasm_malloc(len + sizeof sl->next); + memcpy(sl->str, sp, len); + sl->next = NULL; + nasm_free(sp); + + if (omode == INC_PROBE) { + fp = NULL; + found = nasm_file_exists(sl->str); + } else { + fp = nasm_open_read(sl->str, fmode); + found = (fp != NULL); + } + if (found) { + *slpath = sl; + return fp; + } + + nasm_free(sl); + + if (!ip) + return NULL; + + prefix = ip->path; + ip = ip->next; + } +} + +/* + * Open a file, or test for the presence of one (depending on omode), + * considering the include path. + */ +static FILE *inc_fopen(const char *file, + StrList **dhead, + const char **found_path, + enum incopen_mode omode, + enum file_flags fmode) +{ + StrList *sl; + struct hash_insert hi; + void **hp; + char *path; + FILE *fp = NULL; + + hp = hash_find(&FileHash, file, &hi); + if (hp) { + path = *hp; + if (path || omode != INC_NEEDED) { + nasm_add_string_to_strlist(dhead, path ? path : file); + } + } else { + /* Need to do the actual path search */ + size_t file_len; + + sl = NULL; + fp = inc_fopen_search(file, &sl, omode, fmode); + + file_len = strlen(file); + + if (!sl) { + /* Store negative result for this file */ + sl = nasm_malloc(file_len + 1 + sizeof sl->next); + memcpy(sl->str, file, file_len+1); + sl->next = NULL; + file = sl->str; + path = NULL; + } else { + path = sl->str; + file = strchr(path, '\0') - file_len; + } + + hash_add(&hi, file, path); /* Positive or negative result */ + + /* + * Add file to dependency path. The in_list() is needed + * in case the file was already added with %depend. + */ + if (path || omode != INC_NEEDED) + nasm_add_to_strlist(dhead, sl); + } + + if (!path) { + if (omode == INC_NEEDED) + nasm_fatal(0, "unable to open include file `%s'", file); + + if (found_path) + *found_path = NULL; + + return NULL; + } + + if (!fp && omode != INC_PROBE) + fp = nasm_open_read(path, fmode); + + if (found_path) + *found_path = path; + + return fp; +} + +/* + * Opens an include or input file. Public version, for use by modules + * that get a file:lineno pair and need to look at the file again + * (e.g. the CodeView debug backend). Returns NULL on failure. + */ +FILE *pp_input_fopen(const char *filename, enum file_flags mode) +{ + return inc_fopen(filename, NULL, NULL, INC_OPTIONAL, mode); +} + +/* + * Determine if we should warn on defining a single-line macro of + * name `name', with `nparam' parameters. If nparam is 0 or -1, will + * return true if _any_ single-line macro of that name is defined. + * Otherwise, will return true if a single-line macro with either + * `nparam' or no parameters is defined. + * + * If a macro with precisely the right number of parameters is + * defined, or nparam is -1, the address of the definition structure + * will be returned in `defn'; otherwise NULL will be returned. If `defn' + * is NULL, no action will be taken regarding its contents, and no + * error will occur. + * + * Note that this is also called with nparam zero to resolve + * `ifdef'. + * + * If you already know which context macro belongs to, you can pass + * the context pointer as first parameter; if you won't but name begins + * with %$ the context will be automatically computed. If all_contexts + * is true, macro will be searched in outer contexts as well. + */ +static bool +smacro_defined(Context * ctx, const char *name, int nparam, SMacro ** defn, + bool nocase) +{ + struct hash_table *smtbl; + SMacro *m; + + if (ctx) { + smtbl = &ctx->localmac; + } else if (name[0] == '%' && name[1] == '$') { + if (cstk) + ctx = get_ctx(name, &name); + if (!ctx) + return false; /* got to return _something_ */ + smtbl = &ctx->localmac; + } else { + smtbl = &smacros; + } + m = (SMacro *) hash_findix(smtbl, name); + + while (m) { + if (!mstrcmp(m->name, name, m->casesense && nocase) && + (nparam <= 0 || m->nparam == 0 || nparam == (int) m->nparam)) { + if (defn) { + if (nparam == (int) m->nparam || nparam == -1) + *defn = m; + else + *defn = NULL; + } + return true; + } + m = m->next; + } + + return false; +} + +/* + * Count and mark off the parameters in a multi-line macro call. + * This is called both from within the multi-line macro expansion + * code, and also to mark off the default parameters when provided + * in a %macro definition line. + */ +static void count_mmac_params(Token * t, int *nparam, Token *** params) +{ + int paramsize, brace; + + *nparam = paramsize = 0; + *params = NULL; + while (t) { + /* +1: we need space for the final NULL */ + if (*nparam+1 >= paramsize) { + paramsize += PARAM_DELTA; + *params = nasm_realloc(*params, sizeof(**params) * paramsize); + } + skip_white_(t); + brace = 0; + if (tok_is_(t, "{")) + brace++; + (*params)[(*nparam)++] = t; + if (brace) { + while (brace && (t = t->next) != NULL) { + if (tok_is_(t, "{")) + brace++; + else if (tok_is_(t, "}")) + brace--; + } + + if (t) { + /* + * Now we've found the closing brace, look further + * for the comma. + */ + t = t->next; + skip_white_(t); + if (tok_isnt_(t, ",")) { + nasm_error(ERR_NONFATAL, + "braces do not enclose all of macro parameter"); + while (tok_isnt_(t, ",")) + t = t->next; + } + } + } else { + while (tok_isnt_(t, ",")) + t = t->next; + } + if (t) { /* got a comma/brace */ + t = t->next; /* eat the comma */ + } + } +} + +/* + * Determine whether one of the various `if' conditions is true or + * not. + * + * We must free the tline we get passed. + */ +static bool if_condition(Token * tline, enum preproc_token ct) +{ + enum pp_conditional i = PP_COND(ct); + bool j; + Token *t, *tt, **tptr, *origline; + struct tokenval tokval; + expr *evalresult; + enum pp_token_type needtype; + char *p; + + origline = tline; + + switch (i) { + case PPC_IFCTX: + j = false; /* have we matched yet? */ + while (true) { + skip_white_(tline); + if (!tline) + break; + if (tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, + "`%s' expects context identifiers", pp_directives[ct]); + free_tlist(origline); + return -1; + } + if (cstk && cstk->name && !nasm_stricmp(tline->text, cstk->name)) + j = true; + tline = tline->next; + } + break; + + case PPC_IFDEF: + j = false; /* have we matched yet? */ + while (tline) { + skip_white_(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%s' expects macro identifiers", pp_directives[ct]); + goto fail; + } + if (smacro_defined(NULL, tline->text, 0, NULL, true)) + j = true; + tline = tline->next; + } + break; + + case PPC_IFENV: + tline = expand_smacro(tline); + j = false; /* have we matched yet? */ + while (tline) { + skip_white_(tline); + if (!tline || (tline->type != TOK_ID && + tline->type != TOK_STRING && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '!'))) { + nasm_error(ERR_NONFATAL, + "`%s' expects environment variable names", + pp_directives[ct]); + goto fail; + } + p = tline->text; + if (tline->type == TOK_PREPROC_ID) + p += 2; /* Skip leading %! */ + if (*p == '\'' || *p == '\"' || *p == '`') + nasm_unquote_cstr(p, ct); + if (getenv(p)) + j = true; + tline = tline->next; + } + break; + + case PPC_IFIDN: + case PPC_IFIDNI: + tline = expand_smacro(tline); + t = tt = tline; + while (tok_isnt_(tt, ",")) + tt = tt->next; + if (!tt) { + nasm_error(ERR_NONFATAL, + "`%s' expects two comma-separated arguments", + pp_directives[ct]); + goto fail; + } + tt = tt->next; + j = true; /* assume equality unless proved not */ + while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) { + if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) { + nasm_error(ERR_NONFATAL, "`%s': more than one comma on line", + pp_directives[ct]); + goto fail; + } + if (t->type == TOK_WHITESPACE) { + t = t->next; + continue; + } + if (tt->type == TOK_WHITESPACE) { + tt = tt->next; + continue; + } + if (tt->type != t->type) { + j = false; /* found mismatching tokens */ + break; + } + /* When comparing strings, need to unquote them first */ + if (t->type == TOK_STRING) { + size_t l1 = nasm_unquote(t->text, NULL); + size_t l2 = nasm_unquote(tt->text, NULL); + + if (l1 != l2) { + j = false; + break; + } + if (mmemcmp(t->text, tt->text, l1, i == PPC_IFIDN)) { + j = false; + break; + } + } else if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) { + j = false; /* found mismatching tokens */ + break; + } + + t = t->next; + tt = tt->next; + } + if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt) + j = false; /* trailing gunk on one end or other */ + break; + + case PPC_IFMACRO: + { + bool found = false; + MMacro searching, *mmac; + + skip_white_(tline); + tline = expand_id(tline); + if (!tok_type_(tline, TOK_ID)) { + nasm_error(ERR_NONFATAL, + "`%s' expects a macro name", pp_directives[ct]); + goto fail; + } + searching.name = nasm_strdup(tline->text); + searching.casesense = true; + searching.plus = false; + searching.nolist = false; + searching.in_progress = 0; + searching.max_depth = 0; + searching.rep_nest = NULL; + searching.nparam_min = 0; + searching.nparam_max = INT_MAX; + tline = expand_smacro(tline->next); + skip_white_(tline); + if (!tline) { + } else if (!tok_type_(tline, TOK_NUMBER)) { + nasm_error(ERR_NONFATAL, + "`%s' expects a parameter count or nothing", + pp_directives[ct]); + } else { + searching.nparam_min = searching.nparam_max = + readnum(tline->text, &j); + if (j) + nasm_error(ERR_NONFATAL, + "unable to parse parameter count `%s'", + tline->text); + } + if (tline && tok_is_(tline->next, "-")) { + tline = tline->next->next; + if (tok_is_(tline, "*")) + searching.nparam_max = INT_MAX; + else if (!tok_type_(tline, TOK_NUMBER)) + nasm_error(ERR_NONFATAL, + "`%s' expects a parameter count after `-'", + pp_directives[ct]); + else { + searching.nparam_max = readnum(tline->text, &j); + if (j) + nasm_error(ERR_NONFATAL, + "unable to parse parameter count `%s'", + tline->text); + if (searching.nparam_min > searching.nparam_max) { + nasm_error(ERR_NONFATAL, + "minimum parameter count exceeds maximum"); + searching.nparam_max = searching.nparam_min; + } + } + } + if (tline && tok_is_(tline->next, "+")) { + tline = tline->next; + searching.plus = true; + } + mmac = (MMacro *) hash_findix(&mmacros, searching.name); + while (mmac) { + if (!strcmp(mmac->name, searching.name) && + (mmac->nparam_min <= searching.nparam_max + || searching.plus) + && (searching.nparam_min <= mmac->nparam_max + || mmac->plus)) { + found = true; + break; + } + mmac = mmac->next; + } + if (tline && tline->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after %%ifmacro ignored"); + nasm_free(searching.name); + j = found; + break; + } + + case PPC_IFID: + needtype = TOK_ID; + goto iftype; + case PPC_IFNUM: + needtype = TOK_NUMBER; + goto iftype; + case PPC_IFSTR: + needtype = TOK_STRING; + goto iftype; + +iftype: + t = tline = expand_smacro(tline); + + while (tok_type_(t, TOK_WHITESPACE) || + (needtype == TOK_NUMBER && + tok_type_(t, TOK_OTHER) && + (t->text[0] == '-' || t->text[0] == '+') && + !t->text[1])) + t = t->next; + + j = tok_type_(t, needtype); + break; + + case PPC_IFTOKEN: + t = tline = expand_smacro(tline); + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + + j = false; + if (t) { + t = t->next; /* Skip the actual token */ + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + j = !t; /* Should be nothing left */ + } + break; + + case PPC_IFEMPTY: + t = tline = expand_smacro(tline); + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + + j = !t; /* Should be empty */ + break; + + case PPC_IF: + t = tline = expand_smacro(tline); + tptr = &t; + tokval.t_type = TOKEN_INVALID; + evalresult = evaluate(ppscan, tptr, &tokval, + NULL, pass | CRITICAL, NULL); + if (!evalresult) + return -1; + if (tokval.t_type) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after expression ignored"); + if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, + "non-constant value given to `%s'", pp_directives[ct]); + goto fail; + } + j = reloc_value(evalresult) != 0; + break; + + default: + nasm_error(ERR_FATAL, + "preprocessor directive `%s' not yet implemented", + pp_directives[ct]); + goto fail; + } + + free_tlist(origline); + return j ^ PP_NEGATIVE(ct); + +fail: + free_tlist(origline); + return -1; +} + +/* + * Common code for defining an smacro + */ +static bool define_smacro(Context *ctx, const char *mname, bool casesense, + int nparam, Token *expansion) +{ + SMacro *smac, **smhead; + struct hash_table *smtbl; + + if (smacro_defined(ctx, mname, nparam, &smac, casesense)) { + if (!smac) { + nasm_error(ERR_WARNING|ERR_PASS1, + "single-line macro `%s' defined both with and" + " without parameters", mname); + /* + * Some instances of the old code considered this a failure, + * some others didn't. What is the right thing to do here? + */ + free_tlist(expansion); + return false; /* Failure */ + } else { + /* + * We're redefining, so we have to take over an + * existing SMacro structure. This means freeing + * what was already in it. + */ + nasm_free(smac->name); + free_tlist(smac->expansion); + } + } else { + smtbl = ctx ? &ctx->localmac : &smacros; + smhead = (SMacro **) hash_findi_add(smtbl, mname); + smac = nasm_malloc(sizeof(SMacro)); + smac->next = *smhead; + *smhead = smac; + } + smac->name = nasm_strdup(mname); + smac->casesense = casesense; + smac->nparam = nparam; + smac->expansion = expansion; + smac->in_progress = false; + return true; /* Success */ +} + +/* + * Undefine an smacro + */ +static void undef_smacro(Context *ctx, const char *mname) +{ + SMacro **smhead, *s, **sp; + struct hash_table *smtbl; + + smtbl = ctx ? &ctx->localmac : &smacros; + smhead = (SMacro **)hash_findi(smtbl, mname, NULL); + + if (smhead) { + /* + * We now have a macro name... go hunt for it. + */ + sp = smhead; + while ((s = *sp) != NULL) { + if (!mstrcmp(s->name, mname, s->casesense)) { + *sp = s->next; + nasm_free(s->name); + free_tlist(s->expansion); + nasm_free(s); + } else { + sp = &s->next; + } + } + } +} + +/* + * Parse a mmacro specification. + */ +static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive) +{ + bool err; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tok_type_(tline, TOK_ID)) { + nasm_error(ERR_NONFATAL, "`%s' expects a macro name", directive); + return false; + } + + def->prev = NULL; + def->name = nasm_strdup(tline->text); + def->plus = false; + def->nolist = false; + def->in_progress = 0; + def->rep_nest = NULL; + def->nparam_min = 0; + def->nparam_max = 0; + + tline = expand_smacro(tline->next); + skip_white_(tline); + if (!tok_type_(tline, TOK_NUMBER)) { + nasm_error(ERR_NONFATAL, "`%s' expects a parameter count", directive); + } else { + def->nparam_min = def->nparam_max = + readnum(tline->text, &err); + if (err) + nasm_error(ERR_NONFATAL, + "unable to parse parameter count `%s'", tline->text); + } + if (tline && tok_is_(tline->next, "-")) { + tline = tline->next->next; + if (tok_is_(tline, "*")) { + def->nparam_max = INT_MAX; + } else if (!tok_type_(tline, TOK_NUMBER)) { + nasm_error(ERR_NONFATAL, + "`%s' expects a parameter count after `-'", directive); + } else { + def->nparam_max = readnum(tline->text, &err); + if (err) { + nasm_error(ERR_NONFATAL, "unable to parse parameter count `%s'", + tline->text); + } + if (def->nparam_min > def->nparam_max) { + nasm_error(ERR_NONFATAL, "minimum parameter count exceeds maximum"); + def->nparam_max = def->nparam_min; + } + } + } + if (tline && tok_is_(tline->next, "+")) { + tline = tline->next; + def->plus = true; + } + if (tline && tok_type_(tline->next, TOK_ID) && + !nasm_stricmp(tline->next->text, ".nolist")) { + tline = tline->next; + def->nolist = true; + } + + /* + * Handle default parameters. + */ + if (tline && tline->next) { + def->dlist = tline->next; + tline->next = NULL; + count_mmac_params(def->dlist, &def->ndefs, &def->defaults); + } else { + def->dlist = NULL; + def->defaults = NULL; + } + def->expansion = NULL; + + if (def->defaults && def->ndefs > def->nparam_max - def->nparam_min && + !def->plus) + nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_MDP, + "too many default macro parameters"); + + return true; +} + + +/* + * Decode a size directive + */ +static int parse_size(const char *str) { + static const char *size_names[] = + { "byte", "dword", "oword", "qword", "tword", "word", "yword" }; + static const int sizes[] = + { 0, 1, 4, 16, 8, 10, 2, 32 }; + return str ? sizes[bsii(str, size_names, ARRAY_SIZE(size_names))+1] : 0; +} + +/* + * Process a preprocessor %pragma directive. Currently there are none. + * Gets passed the token list starting with the "preproc" token from + * "%pragma preproc". + */ +static void do_pragma_preproc(Token *tline) +{ + /* Skip to the real stuff */ + tline = tline->next; + skip_white_(tline); + if (!tline) + return; + + (void)tline; /* Nothing else to do at present */ +} + +/** + * find and process preprocessor directive in passed line + * Find out if a line contains a preprocessor directive, and deal + * with it if so. + * + * If a directive _is_ found, it is the responsibility of this routine + * (and not the caller) to free_tlist() the line. + * + * @param tline a pointer to the current tokeninzed line linked list + * @param output if this directive generated output + * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND + * + */ +static int do_directive(Token *tline, char **output) +{ + enum preproc_token i; + int j; + bool err; + int nparam; + bool nolist; + bool casesense; + int k, m; + int offset; + char *p, *pp; + const char *found_path; + const char *mname; + Include *inc; + Context *ctx; + Cond *cond; + MMacro *mmac, **mmhead; + Token *t = NULL, *tt, *param_start, *macro_start, *last, **tptr, *origline; + Line *l; + struct tokenval tokval; + expr *evalresult; + MMacro *tmp_defining; /* Used when manipulating rep_nest */ + int64_t count; + size_t len; + int severity; + + *output = NULL; /* No output generated */ + origline = tline; + + skip_white_(tline); + if (!tline || !tok_type_(tline, TOK_PREPROC_ID) || + (tline->text[0] && (tline->text[1] == '%' || + tline->text[1] == '$' || + tline->text[1] == '!'))) + return NO_DIRECTIVE_FOUND; + + i = pp_token_hash(tline->text); + + /* + * FIXME: We zap execution of PP_RMACRO, PP_IRMACRO, PP_EXITMACRO + * since they are known to be buggy at moment, we need to fix them + * in future release (2.09-2.10) + */ + if (i == PP_RMACRO || i == PP_IRMACRO || i == PP_EXITMACRO) { + nasm_error(ERR_NONFATAL, "unknown preprocessor directive `%s'", + tline->text); + return NO_DIRECTIVE_FOUND; + } + + /* + * If we're in a non-emitting branch of a condition construct, + * or walking to the end of an already terminated %rep block, + * we should ignore all directives except for condition + * directives. + */ + if (((istk->conds && !emitting(istk->conds->state)) || + (istk->mstk && !istk->mstk->in_progress)) && !is_condition(i)) { + return NO_DIRECTIVE_FOUND; + } + + /* + * If we're defining a macro or reading a %rep block, we should + * ignore all directives except for %macro/%imacro (which nest), + * %endm/%endmacro, and (only if we're in a %rep block) %endrep. + * If we're in a %rep block, another %rep nests, so should be let through. + */ + if (defining && i != PP_MACRO && i != PP_IMACRO && + i != PP_RMACRO && i != PP_IRMACRO && + i != PP_ENDMACRO && i != PP_ENDM && + (defining->name || (i != PP_ENDREP && i != PP_REP))) { + return NO_DIRECTIVE_FOUND; + } + + if (defining) { + if (i == PP_MACRO || i == PP_IMACRO || + i == PP_RMACRO || i == PP_IRMACRO) { + nested_mac_count++; + return NO_DIRECTIVE_FOUND; + } else if (nested_mac_count > 0) { + if (i == PP_ENDMACRO) { + nested_mac_count--; + return NO_DIRECTIVE_FOUND; + } + } + if (!defining->name) { + if (i == PP_REP) { + nested_rep_count++; + return NO_DIRECTIVE_FOUND; + } else if (nested_rep_count > 0) { + if (i == PP_ENDREP) { + nested_rep_count--; + return NO_DIRECTIVE_FOUND; + } + } + } + } + + switch (i) { + case PP_INVALID: + nasm_error(ERR_NONFATAL, "unknown preprocessor directive `%s'", + tline->text); + return NO_DIRECTIVE_FOUND; /* didn't get it */ + + case PP_PRAGMA: + /* + * %pragma namespace options... + * + * The namespace "preproc" is reserved for the preprocessor; + * all other namespaces generate a [pragma] assembly directive. + * + * Invalid %pragmas are ignored and may have different + * meaning in future versions of NASM. + */ + tline = tline->next; + skip_white_(tline); + tline = expand_smacro(tline); + if (tok_type_(tline, TOK_ID)) { + if (!nasm_stricmp(tline->text, "preproc")) { + /* Preprocessor pragma */ + do_pragma_preproc(tline); + } else { + /* Build the assembler directive */ + t = new_Token(NULL, TOK_OTHER, "[", 1); + t->next = new_Token(NULL, TOK_ID, "pragma", 6); + t->next->next = new_Token(tline, TOK_WHITESPACE, NULL, 0); + tline = t; + for (t = tline; t->next; t = t->next) + ; + t->next = new_Token(NULL, TOK_OTHER, "]", 1); + /* true here can be revisited in the future */ + *output = detoken(tline, true); + } + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_STACKSIZE: + /* Directive to tell NASM what the default stack size is. The + * default is for a 16-bit stack, and this can be overriden with + * %stacksize large. + */ + tline = tline->next; + if (tline && tline->type == TOK_WHITESPACE) + tline = tline->next; + if (!tline || tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, "`%%stacksize' missing size parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + if (nasm_stricmp(tline->text, "flat") == 0) { + /* All subsequent ARG directives are for a 32-bit stack */ + StackSize = 4; + StackPointer = "ebp"; + ArgOffset = 8; + LocalOffset = 0; + } else if (nasm_stricmp(tline->text, "flat64") == 0) { + /* All subsequent ARG directives are for a 64-bit stack */ + StackSize = 8; + StackPointer = "rbp"; + ArgOffset = 16; + LocalOffset = 0; + } else if (nasm_stricmp(tline->text, "large") == 0) { + /* All subsequent ARG directives are for a 16-bit stack, + * far function call. + */ + StackSize = 2; + StackPointer = "bp"; + ArgOffset = 4; + LocalOffset = 0; + } else if (nasm_stricmp(tline->text, "small") == 0) { + /* All subsequent ARG directives are for a 16-bit stack, + * far function call. We don't support near functions. + */ + StackSize = 2; + StackPointer = "bp"; + ArgOffset = 6; + LocalOffset = 0; + } else { + nasm_error(ERR_NONFATAL, "`%%stacksize' invalid size type"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_ARG: + /* TASM like ARG directive to define arguments to functions, in + * the following form: + * + * ARG arg1:WORD, arg2:DWORD, arg4:QWORD + */ + offset = ArgOffset; + do { + char *arg, directive[256]; + int size = StackSize; + + /* Find the argument name */ + tline = tline->next; + if (tline && tline->type == TOK_WHITESPACE) + tline = tline->next; + if (!tline || tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, "`%%arg' missing argument parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + arg = tline->text; + + /* Find the argument size type */ + tline = tline->next; + if (!tline || tline->type != TOK_OTHER + || tline->text[0] != ':') { + nasm_error(ERR_NONFATAL, + "Syntax error processing `%%arg' directive"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + tline = tline->next; + if (!tline || tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, "`%%arg' missing size type parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + /* Allow macro expansion of type parameter */ + tt = tokenize(tline->text); + tt = expand_smacro(tt); + size = parse_size(tt->text); + if (!size) { + nasm_error(ERR_NONFATAL, + "Invalid size type for `%%arg' missing directive"); + free_tlist(tt); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + free_tlist(tt); + + /* Round up to even stack slots */ + size = ALIGN(size, StackSize); + + /* Now define the macro for the argument */ + snprintf(directive, sizeof(directive), "%%define %s (%s+%d)", + arg, StackPointer, offset); + do_directive(tokenize(directive), output); + offset += size; + + /* Move to the next argument in the list */ + tline = tline->next; + if (tline && tline->type == TOK_WHITESPACE) + tline = tline->next; + } while (tline && tline->type == TOK_OTHER && tline->text[0] == ','); + ArgOffset = offset; + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_LOCAL: + /* TASM like LOCAL directive to define local variables for a + * function, in the following form: + * + * LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize + * + * The '= LocalSize' at the end is ignored by NASM, but is + * required by TASM to define the local parameter size (and used + * by the TASM macro package). + */ + offset = LocalOffset; + do { + char *local, directive[256]; + int size = StackSize; + + /* Find the argument name */ + tline = tline->next; + if (tline && tline->type == TOK_WHITESPACE) + tline = tline->next; + if (!tline || tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, + "`%%local' missing argument parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + local = tline->text; + + /* Find the argument size type */ + tline = tline->next; + if (!tline || tline->type != TOK_OTHER + || tline->text[0] != ':') { + nasm_error(ERR_NONFATAL, + "Syntax error processing `%%local' directive"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + tline = tline->next; + if (!tline || tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, + "`%%local' missing size type parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + /* Allow macro expansion of type parameter */ + tt = tokenize(tline->text); + tt = expand_smacro(tt); + size = parse_size(tt->text); + if (!size) { + nasm_error(ERR_NONFATAL, + "Invalid size type for `%%local' missing directive"); + free_tlist(tt); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + free_tlist(tt); + + /* Round up to even stack slots */ + size = ALIGN(size, StackSize); + + offset += size; /* Negative offset, increment before */ + + /* Now define the macro for the argument */ + snprintf(directive, sizeof(directive), "%%define %s (%s-%d)", + local, StackPointer, offset); + do_directive(tokenize(directive), output); + + /* Now define the assign to setup the enter_c macro correctly */ + snprintf(directive, sizeof(directive), + "%%assign %%$localsize %%$localsize+%d", size); + do_directive(tokenize(directive), output); + + /* Move to the next argument in the list */ + tline = tline->next; + if (tline && tline->type == TOK_WHITESPACE) + tline = tline->next; + } while (tline && tline->type == TOK_OTHER && tline->text[0] == ','); + LocalOffset = offset; + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_CLEAR: + if (tline->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%%clear' ignored"); + free_macros(); + init_macros(); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_DEPEND: + t = tline->next = expand_smacro(tline->next); + skip_white_(t); + if (!t || (t->type != TOK_STRING && + t->type != TOK_INTERNAL_STRING)) { + nasm_error(ERR_NONFATAL, "`%%depend' expects a file name"); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (t->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%%depend' ignored"); + p = t->text; + if (t->type != TOK_INTERNAL_STRING) + nasm_unquote_cstr(p, i); + nasm_add_string_to_strlist(dephead, p); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_INCLUDE: + t = tline->next = expand_smacro(tline->next); + skip_white_(t); + + if (!t || (t->type != TOK_STRING && + t->type != TOK_INTERNAL_STRING)) { + nasm_error(ERR_NONFATAL, "`%%include' expects a file name"); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (t->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%%include' ignored"); + p = t->text; + if (t->type != TOK_INTERNAL_STRING) + nasm_unquote_cstr(p, i); + inc = nasm_malloc(sizeof(Include)); + inc->next = istk; + inc->conds = NULL; + found_path = NULL; + inc->fp = inc_fopen(p, dephead, &found_path, + pass == 0 ? INC_OPTIONAL : INC_NEEDED, NF_TEXT); + if (!inc->fp) { + /* -MG given but file not found */ + nasm_free(inc); + } else { + inc->fname = src_set_fname(found_path ? found_path : p); + inc->lineno = src_set_linnum(0); + inc->lineinc = 1; + inc->expansion = NULL; + inc->mstk = NULL; + istk = inc; + lfmt->uplevel(LIST_INCLUDE); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_USE: + { + static macros_t *use_pkg; + const char *pkg_macro = NULL; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + + if (!tline || (tline->type != TOK_STRING && + tline->type != TOK_INTERNAL_STRING && + tline->type != TOK_ID)) { + nasm_error(ERR_NONFATAL, "`%%use' expects a package name"); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (tline->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%%use' ignored"); + if (tline->type == TOK_STRING) + nasm_unquote_cstr(tline->text, i); + use_pkg = nasm_stdmac_find_package(tline->text); + if (!use_pkg) + nasm_error(ERR_NONFATAL, "unknown `%%use' package: %s", tline->text); + else + pkg_macro = (char *)use_pkg + 1; /* The first string will be <%define>__USE_*__ */ + if (use_pkg && ! smacro_defined(NULL, pkg_macro, 0, NULL, true)) { + /* Not already included, go ahead and include it */ + stdmacpos = use_pkg; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + } + case PP_PUSH: + case PP_REPL: + case PP_POP: + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (tline) { + if (!tok_type_(tline, TOK_ID)) { + nasm_error(ERR_NONFATAL, "`%s' expects a context identifier", + pp_directives[i]); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (tline->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%s' ignored", + pp_directives[i]); + p = nasm_strdup(tline->text); + } else { + p = NULL; /* Anonymous */ + } + + if (i == PP_PUSH) { + ctx = nasm_malloc(sizeof(Context)); + ctx->next = cstk; + hash_init(&ctx->localmac, HASH_SMALL); + ctx->name = p; + ctx->number = unique++; + cstk = ctx; + } else { + /* %pop or %repl */ + if (!cstk) { + nasm_error(ERR_NONFATAL, "`%s': context stack is empty", + pp_directives[i]); + } else if (i == PP_POP) { + if (p && (!cstk->name || nasm_stricmp(p, cstk->name))) + nasm_error(ERR_NONFATAL, "`%%pop' in wrong context: %s, " + "expected %s", + cstk->name ? cstk->name : "anonymous", p); + else + ctx_pop(); + } else { + /* i == PP_REPL */ + nasm_free(cstk->name); + cstk->name = p; + p = NULL; + } + nasm_free(p); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + case PP_FATAL: + severity = ERR_FATAL; + goto issue_error; + case PP_ERROR: + severity = ERR_NONFATAL; + goto issue_error; + case PP_WARNING: + severity = ERR_WARNING|ERR_WARN_USER; + goto issue_error; + +issue_error: + { + /* Only error out if this is the final pass */ + if (pass != 2 && i != PP_FATAL) + return DIRECTIVE_FOUND; + + tline->next = expand_smacro(tline->next); + tline = tline->next; + skip_white_(tline); + t = tline ? tline->next : NULL; + skip_white_(t); + if (tok_type_(tline, TOK_STRING) && !t) { + /* The line contains only a quoted string */ + p = tline->text; + nasm_unquote(p, NULL); /* Ignore NUL character truncation */ + nasm_error(severity, "%s", p); + } else { + /* Not a quoted string, or more than a quoted string */ + p = detoken(tline, false); + nasm_error(severity, "%s", p); + nasm_free(p); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + CASE_PP_IF: + if (istk->conds && !emitting(istk->conds->state)) + j = COND_NEVER; + else { + j = if_condition(tline->next, i); + tline->next = NULL; /* it got freed */ + j = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE; + } + cond = nasm_malloc(sizeof(Cond)); + cond->next = istk->conds; + cond->state = j; + istk->conds = cond; + if(istk->mstk) + istk->mstk->condcnt ++; + free_tlist(origline); + return DIRECTIVE_FOUND; + + CASE_PP_ELIF: + if (!istk->conds) + nasm_error(ERR_FATAL, "`%s': no matching `%%if'", pp_directives[i]); + switch(istk->conds->state) { + case COND_IF_TRUE: + istk->conds->state = COND_DONE; + break; + + case COND_DONE: + case COND_NEVER: + break; + + case COND_ELSE_TRUE: + case COND_ELSE_FALSE: + nasm_error(ERR_WARNING|ERR_PASS1|ERR_PP_PRECOND, + "`%%elif' after `%%else' ignored"); + istk->conds->state = COND_NEVER; + break; + + case COND_IF_FALSE: + /* + * IMPORTANT: In the case of %if, we will already have + * called expand_mmac_params(); however, if we're + * processing an %elif we must have been in a + * non-emitting mode, which would have inhibited + * the normal invocation of expand_mmac_params(). + * Therefore, we have to do it explicitly here. + */ + j = if_condition(expand_mmac_params(tline->next), i); + tline->next = NULL; /* it got freed */ + istk->conds->state = + j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE; + break; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_ELSE: + if (tline->next) + nasm_error(ERR_WARNING|ERR_PASS1|ERR_PP_PRECOND, + "trailing garbage after `%%else' ignored"); + if (!istk->conds) + nasm_fatal(0, "`%%else: no matching `%%if'"); + switch(istk->conds->state) { + case COND_IF_TRUE: + case COND_DONE: + istk->conds->state = COND_ELSE_FALSE; + break; + + case COND_NEVER: + break; + + case COND_IF_FALSE: + istk->conds->state = COND_ELSE_TRUE; + break; + + case COND_ELSE_TRUE: + case COND_ELSE_FALSE: + nasm_error(ERR_WARNING|ERR_PASS1|ERR_PP_PRECOND, + "`%%else' after `%%else' ignored."); + istk->conds->state = COND_NEVER; + break; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_ENDIF: + if (tline->next) + nasm_error(ERR_WARNING|ERR_PASS1|ERR_PP_PRECOND, + "trailing garbage after `%%endif' ignored"); + if (!istk->conds) + nasm_error(ERR_FATAL, "`%%endif': no matching `%%if'"); + cond = istk->conds; + istk->conds = cond->next; + nasm_free(cond); + if(istk->mstk) + istk->mstk->condcnt --; + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_RMACRO: + case PP_IRMACRO: + case PP_MACRO: + case PP_IMACRO: + if (defining) { + nasm_error(ERR_FATAL, "`%s': already defining a macro", + pp_directives[i]); + return DIRECTIVE_FOUND; + } + defining = nasm_zalloc(sizeof(MMacro)); + defining->max_depth = ((i == PP_RMACRO) || (i == PP_IRMACRO)) + ? nasm_limit[LIMIT_MACROS] : 0; + defining->casesense = (i == PP_MACRO) || (i == PP_RMACRO); + if (!parse_mmacro_spec(tline, defining, pp_directives[i])) { + nasm_free(defining); + defining = NULL; + return DIRECTIVE_FOUND; + } + + src_get(&defining->xline, &defining->fname); + + mmac = (MMacro *) hash_findix(&mmacros, defining->name); + while (mmac) { + if (!strcmp(mmac->name, defining->name) && + (mmac->nparam_min <= defining->nparam_max + || defining->plus) + && (defining->nparam_min <= mmac->nparam_max + || mmac->plus)) { + nasm_error(ERR_WARNING|ERR_PASS1, + "redefining multi-line macro `%s'", defining->name); + return DIRECTIVE_FOUND; + } + mmac = mmac->next; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_ENDM: + case PP_ENDMACRO: + if (! (defining && defining->name)) { + nasm_error(ERR_NONFATAL, "`%s': not defining a macro", tline->text); + return DIRECTIVE_FOUND; + } + mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name); + defining->next = *mmhead; + *mmhead = defining; + defining = NULL; + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_EXITMACRO: + /* + * We must search along istk->expansion until we hit a + * macro-end marker for a macro with a name. Then we + * bypass all lines between exitmacro and endmacro. + */ + list_for_each(l, istk->expansion) + if (l->finishes && l->finishes->name) + break; + + if (l) { + /* + * Remove all conditional entries relative to this + * macro invocation. (safe to do in this context) + */ + for ( ; l->finishes->condcnt > 0; l->finishes->condcnt --) { + cond = istk->conds; + istk->conds = cond->next; + nasm_free(cond); + } + istk->expansion = l; + } else { + nasm_error(ERR_NONFATAL, "`%%exitmacro' not within `%%macro' block"); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_UNMACRO: + case PP_UNIMACRO: + { + MMacro **mmac_p; + MMacro spec; + + spec.casesense = (i == PP_UNMACRO); + if (!parse_mmacro_spec(tline, &spec, pp_directives[i])) { + return DIRECTIVE_FOUND; + } + mmac_p = (MMacro **) hash_findi(&mmacros, spec.name, NULL); + while (mmac_p && *mmac_p) { + mmac = *mmac_p; + if (mmac->casesense == spec.casesense && + !mstrcmp(mmac->name, spec.name, spec.casesense) && + mmac->nparam_min == spec.nparam_min && + mmac->nparam_max == spec.nparam_max && + mmac->plus == spec.plus) { + *mmac_p = mmac->next; + free_mmacro(mmac); + } else { + mmac_p = &mmac->next; + } + } + free_tlist(origline); + free_tlist(spec.dlist); + return DIRECTIVE_FOUND; + } + + case PP_ROTATE: + if (tline->next && tline->next->type == TOK_WHITESPACE) + tline = tline->next; + if (!tline->next) { + free_tlist(origline); + nasm_error(ERR_NONFATAL, "`%%rotate' missing rotate count"); + return DIRECTIVE_FOUND; + } + t = expand_smacro(tline->next); + tline->next = NULL; + free_tlist(origline); + tline = t; + tptr = &t; + tokval.t_type = TOKEN_INVALID; + evalresult = + evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + free_tlist(tline); + if (!evalresult) + return DIRECTIVE_FOUND; + if (tokval.t_type) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after expression ignored"); + if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, "non-constant value given to `%%rotate'"); + return DIRECTIVE_FOUND; + } + mmac = istk->mstk; + while (mmac && !mmac->name) /* avoid mistaking %reps for macros */ + mmac = mmac->next_active; + if (!mmac) { + nasm_error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call"); + } else if (mmac->nparam == 0) { + nasm_error(ERR_NONFATAL, + "`%%rotate' invoked within macro without parameters"); + } else { + int rotate = mmac->rotate + reloc_value(evalresult); + + rotate %= (int)mmac->nparam; + if (rotate < 0) + rotate += mmac->nparam; + + mmac->rotate = rotate; + } + return DIRECTIVE_FOUND; + + case PP_REP: + nolist = false; + do { + tline = tline->next; + } while (tok_type_(tline, TOK_WHITESPACE)); + + if (tok_type_(tline, TOK_ID) && + nasm_stricmp(tline->text, ".nolist") == 0) { + nolist = true; + do { + tline = tline->next; + } while (tok_type_(tline, TOK_WHITESPACE)); + } + + if (tline) { + t = expand_smacro(tline); + tptr = &t; + tokval.t_type = TOKEN_INVALID; + evalresult = + evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + if (!evalresult) { + free_tlist(origline); + return DIRECTIVE_FOUND; + } + if (tokval.t_type) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after expression ignored"); + if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, "non-constant value given to `%%rep'"); + return DIRECTIVE_FOUND; + } + count = reloc_value(evalresult); + if (count > nasm_limit[LIMIT_REP]) { + nasm_error(ERR_NONFATAL, + "`%%rep' count %"PRId64" exceeds limit (currently %"PRId64")", + count, nasm_limit[LIMIT_REP]); + count = 0; + } else if (count < 0) { + nasm_error(ERR_WARNING|ERR_PASS2|ERR_WARN_NEG_REP, + "negative `%%rep' count: %"PRId64, count); + count = 0; + } else { + count++; + } + } else { + nasm_error(ERR_NONFATAL, "`%%rep' expects a repeat count"); + count = 0; + } + free_tlist(origline); + + tmp_defining = defining; + defining = nasm_malloc(sizeof(MMacro)); + defining->prev = NULL; + defining->name = NULL; /* flags this macro as a %rep block */ + defining->casesense = false; + defining->plus = false; + defining->nolist = nolist; + defining->in_progress = count; + defining->max_depth = 0; + defining->nparam_min = defining->nparam_max = 0; + defining->defaults = NULL; + defining->dlist = NULL; + defining->expansion = NULL; + defining->next_active = istk->mstk; + defining->rep_nest = tmp_defining; + return DIRECTIVE_FOUND; + + case PP_ENDREP: + if (!defining || defining->name) { + nasm_error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'"); + return DIRECTIVE_FOUND; + } + + /* + * Now we have a "macro" defined - although it has no name + * and we won't be entering it in the hash tables - we must + * push a macro-end marker for it on to istk->expansion. + * After that, it will take care of propagating itself (a + * macro-end marker line for a macro which is really a %rep + * block will cause the macro to be re-expanded, complete + * with another macro-end marker to ensure the process + * continues) until the whole expansion is forcibly removed + * from istk->expansion by a %exitrep. + */ + l = nasm_malloc(sizeof(Line)); + l->next = istk->expansion; + l->finishes = defining; + l->first = NULL; + istk->expansion = l; + + istk->mstk = defining; + + lfmt->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO); + tmp_defining = defining; + defining = defining->rep_nest; + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_EXITREP: + /* + * We must search along istk->expansion until we hit a + * macro-end marker for a macro with no name. Then we set + * its `in_progress' flag to 0. + */ + list_for_each(l, istk->expansion) + if (l->finishes && !l->finishes->name) + break; + + if (l) + l->finishes->in_progress = 1; + else + nasm_error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block"); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_XDEFINE: + case PP_IXDEFINE: + case PP_DEFINE: + case PP_IDEFINE: + casesense = (i == PP_DEFINE || i == PP_XDEFINE); + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, "`%s' expects a macro identifier", + pp_directives[i]); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + ctx = get_ctx(tline->text, &mname); + last = tline; + param_start = tline = tline->next; + nparam = 0; + + /* Expand the macro definition now for %xdefine and %ixdefine */ + if ((i == PP_XDEFINE) || (i == PP_IXDEFINE)) + tline = expand_smacro(tline); + + if (tok_is_(tline, "(")) { + /* + * This macro has parameters. + */ + + tline = tline->next; + while (1) { + skip_white_(tline); + if (!tline) { + nasm_error(ERR_NONFATAL, "parameter identifier expected"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + if (tline->type != TOK_ID) { + nasm_error(ERR_NONFATAL, + "`%s': parameter identifier expected", + tline->text); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + tline->type = TOK_SMAC_PARAM + nparam++; + tline = tline->next; + skip_white_(tline); + if (tok_is_(tline, ",")) { + tline = tline->next; + } else { + if (!tok_is_(tline, ")")) { + nasm_error(ERR_NONFATAL, + "`)' expected to terminate macro template"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + break; + } + } + last = tline; + tline = tline->next; + } + if (tok_type_(tline, TOK_WHITESPACE)) + last = tline, tline = tline->next; + macro_start = NULL; + last->next = NULL; + t = tline; + while (t) { + if (t->type == TOK_ID) { + list_for_each(tt, param_start) + if (tt->type >= TOK_SMAC_PARAM && + !strcmp(tt->text, t->text)) + t->type = tt->type; + } + tt = t->next; + t->next = macro_start; + macro_start = t; + t = tt; + } + /* + * Good. We now have a macro name, a parameter count, and a + * token list (in reverse order) for an expansion. We ought + * to be OK just to create an SMacro, store it, and let + * free_tlist have the rest of the line (which we have + * carefully re-terminated after chopping off the expansion + * from the end). + */ + define_smacro(ctx, mname, casesense, nparam, macro_start); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_UNDEF: + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, "`%%undef' expects a macro identifier"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + if (tline->next) { + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after macro name ignored"); + } + + /* Find the context that symbol belongs to */ + ctx = get_ctx(tline->text, &mname); + undef_smacro(ctx, mname); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_DEFSTR: + case PP_IDEFSTR: + casesense = (i == PP_DEFSTR); + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, "`%s' expects a macro identifier", + pp_directives[i]); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + while (tok_type_(tline, TOK_WHITESPACE)) + tline = delete_Token(tline); + + p = detoken(tline, false); + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + macro_start->text = nasm_quote(p, strlen(p)); + macro_start->type = TOK_STRING; + macro_start->a.mac = NULL; + nasm_free(p); + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a string token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_DEFTOK: + case PP_IDEFTOK: + casesense = (i == PP_DEFTOK); + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%s' expects a macro identifier as first parameter", + pp_directives[i]); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + t = tline; + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + /* t should now point to the string */ + if (!tok_type_(t, TOK_STRING)) { + nasm_error(ERR_NONFATAL, + "`%s` requires string as second parameter", + pp_directives[i]); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + /* + * Convert the string to a token stream. Note that smacros + * are stored with the token stream reversed, so we have to + * reverse the output of tokenize(). + */ + nasm_unquote_cstr(t->text, i); + macro_start = reverse_tokens(tokenize(t->text)); + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a numeric token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_PATHSEARCH: + { + const char *found_path; + + casesense = true; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%%pathsearch' expects a macro identifier as first parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + t = tline; + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + + if (!t || (t->type != TOK_STRING && + t->type != TOK_INTERNAL_STRING)) { + nasm_error(ERR_NONFATAL, "`%%pathsearch' expects a file name"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (t->next) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after `%%pathsearch' ignored"); + p = t->text; + if (t->type != TOK_INTERNAL_STRING) + nasm_unquote(p, NULL); + + inc_fopen(p, NULL, &found_path, INC_PROBE, NF_BINARY); + if (!found_path) + found_path = p; + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + macro_start->text = nasm_quote(found_path, strlen(found_path)); + macro_start->type = TOK_STRING; + macro_start->a.mac = NULL; + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a string token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + case PP_STRLEN: + casesense = true; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%%strlen' expects a macro identifier as first parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + t = tline; + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + /* t should now point to the string */ + if (!tok_type_(t, TOK_STRING)) { + nasm_error(ERR_NONFATAL, + "`%%strlen` requires string as second parameter"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + make_tok_num(macro_start, nasm_unquote(t->text, NULL)); + macro_start->a.mac = NULL; + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a numeric token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_STRCAT: + casesense = true; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%%strcat' expects a macro identifier as first parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + len = 0; + list_for_each(t, tline) { + switch (t->type) { + case TOK_WHITESPACE: + break; + case TOK_STRING: + len += t->a.len = nasm_unquote(t->text, NULL); + break; + case TOK_OTHER: + if (!strcmp(t->text, ",")) /* permit comma separators */ + break; + /* else fall through */ + default: + nasm_error(ERR_NONFATAL, + "non-string passed to `%%strcat' (%d)", t->type); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + } + + p = pp = nasm_malloc(len); + list_for_each(t, tline) { + if (t->type == TOK_STRING) { + memcpy(p, t->text, t->a.len); + p += t->a.len; + } + } + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a numeric token to use as an expansion. Create + * and store an SMacro. + */ + macro_start = new_Token(NULL, TOK_STRING, NULL, 0); + macro_start->text = nasm_quote(pp, len); + nasm_free(pp); + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_SUBSTR: + { + int64_t start, count; + size_t len; + + casesense = true; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%%substr' expects a macro identifier as first parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + if (tline) /* skip expanded id */ + t = tline->next; + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + + /* t should now point to the string */ + if (!tok_type_(t, TOK_STRING)) { + nasm_error(ERR_NONFATAL, + "`%%substr` requires string as second parameter"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + tt = t->next; + tptr = &tt; + tokval.t_type = TOKEN_INVALID; + evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + if (!evalresult) { + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } else if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, "non-constant value given to `%%substr`"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + start = evalresult->value - 1; + + while (tok_type_(tt, TOK_WHITESPACE)) + tt = tt->next; + if (!tt) { + count = 1; /* Backwards compatibility: one character */ + } else { + tokval.t_type = TOKEN_INVALID; + evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + if (!evalresult) { + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } else if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, "non-constant value given to `%%substr`"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + count = evalresult->value; + } + + len = nasm_unquote(t->text, NULL); + + /* make start and count being in range */ + if (start < 0) + start = 0; + if (count < 0) + count = len + count + 1 - start; + if (start + count > (int64_t)len) + count = len - start; + if (!len || count < 0 || start >=(int64_t)len) + start = -1, count = 0; /* empty string */ + + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + macro_start->text = nasm_quote((start < 0) ? "" : t->text + start, count); + macro_start->type = TOK_STRING; + macro_start->a.mac = NULL; + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a numeric token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + case PP_ASSIGN: + case PP_IASSIGN: + casesense = (i == PP_ASSIGN); + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + nasm_error(ERR_NONFATAL, + "`%%%sassign' expects a macro identifier", + (i == PP_IASSIGN ? "i" : "")); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, &mname); + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + t = tline; + tptr = &t; + tokval.t_type = TOKEN_INVALID; + evalresult = evaluate(ppscan, tptr, &tokval, NULL, pass, NULL); + free_tlist(tline); + if (!evalresult) { + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + if (tokval.t_type) + nasm_error(ERR_WARNING|ERR_PASS1, + "trailing garbage after expression ignored"); + + if (!is_simple(evalresult)) { + nasm_error(ERR_NONFATAL, + "non-constant value given to `%%%sassign'", + (i == PP_IASSIGN ? "i" : "")); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + make_tok_num(macro_start, reloc_value(evalresult)); + macro_start->a.mac = NULL; + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a numeric token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(origline); + return DIRECTIVE_FOUND; + + case PP_LINE: + /* + * Syntax is `%line nnn[+mmm] [filename]' + */ + tline = tline->next; + skip_white_(tline); + if (!tok_type_(tline, TOK_NUMBER)) { + nasm_error(ERR_NONFATAL, "`%%line' expects line number"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + k = readnum(tline->text, &err); + m = 1; + tline = tline->next; + if (tok_is_(tline, "+")) { + tline = tline->next; + if (!tok_type_(tline, TOK_NUMBER)) { + nasm_error(ERR_NONFATAL, "`%%line' expects line increment"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + m = readnum(tline->text, &err); + tline = tline->next; + } + skip_white_(tline); + src_set_linnum(k); + istk->lineinc = m; + if (tline) { + char *fname = detoken(tline, false); + src_set_fname(fname); + nasm_free(fname); + } + free_tlist(origline); + return DIRECTIVE_FOUND; + + default: + nasm_error(ERR_FATAL, + "preprocessor directive `%s' not yet implemented", + pp_directives[i]); + return DIRECTIVE_FOUND; + } +} + +/* + * Ensure that a macro parameter contains a condition code and + * nothing else. Return the condition code index if so, or -1 + * otherwise. + */ +static int find_cc(Token * t) +{ + Token *tt; + + if (!t) + return -1; /* Probably a %+ without a space */ + + skip_white_(t); + if (!t) + return -1; + if (t->type != TOK_ID) + return -1; + tt = t->next; + skip_white_(tt); + if (tt && (tt->type != TOK_OTHER || strcmp(tt->text, ","))) + return -1; + + return bsii(t->text, (const char **)conditions, ARRAY_SIZE(conditions)); +} + +/* + * This routines walks over tokens strem and hadnles tokens + * pasting, if @handle_explicit passed then explicit pasting + * term is handled, otherwise -- implicit pastings only. + */ +static bool paste_tokens(Token **head, const struct tokseq_match *m, + size_t mnum, bool handle_explicit) +{ + Token *tok, *next, **prev_next, **prev_nonspace; + bool pasted = false; + char *buf, *p; + size_t len, i; + + /* + * The last token before pasting. We need it + * to be able to connect new handled tokens. + * In other words if there were a tokens stream + * + * A -> B -> C -> D + * + * and we've joined tokens B and C, the resulting + * stream should be + * + * A -> BC -> D + */ + tok = *head; + prev_next = NULL; + + if (!tok_type_(tok, TOK_WHITESPACE) && !tok_type_(tok, TOK_PASTE)) + prev_nonspace = head; + else + prev_nonspace = NULL; + + while (tok && (next = tok->next)) { + + switch (tok->type) { + case TOK_WHITESPACE: + /* Zap redundant whitespaces */ + while (tok_type_(next, TOK_WHITESPACE)) + next = delete_Token(next); + tok->next = next; + break; + + case TOK_PASTE: + /* Explicit pasting */ + if (!handle_explicit) + break; + next = delete_Token(tok); + + while (tok_type_(next, TOK_WHITESPACE)) + next = delete_Token(next); + + if (!pasted) + pasted = true; + + /* Left pasting token is start of line */ + if (!prev_nonspace) + nasm_error(ERR_FATAL, "No lvalue found on pasting"); + + /* + * No ending token, this might happen in two + * cases + * + * 1) There indeed no right token at all + * 2) There is a bare "%define ID" statement, + * and @ID does expand to whitespace. + * + * So technically we need to do a grammar analysis + * in another stage of parsing, but for now lets don't + * change the behaviour people used to. Simply allow + * whitespace after paste token. + */ + if (!next) { + /* + * Zap ending space tokens and that's all. + */ + tok = (*prev_nonspace)->next; + while (tok_type_(tok, TOK_WHITESPACE)) + tok = delete_Token(tok); + tok = *prev_nonspace; + tok->next = NULL; + break; + } + + tok = *prev_nonspace; + while (tok_type_(tok, TOK_WHITESPACE)) + tok = delete_Token(tok); + len = strlen(tok->text); + len += strlen(next->text); + + p = buf = nasm_malloc(len + 1); + strcpy(p, tok->text); + p = strchr(p, '\0'); + strcpy(p, next->text); + + delete_Token(tok); + + tok = tokenize(buf); + nasm_free(buf); + + *prev_nonspace = tok; + while (tok && tok->next) + tok = tok->next; + + tok->next = delete_Token(next); + + /* Restart from pasted tokens head */ + tok = *prev_nonspace; + break; + + default: + /* implicit pasting */ + for (i = 0; i < mnum; i++) { + if (!(PP_CONCAT_MATCH(tok, m[i].mask_head))) + continue; + + len = 0; + while (next && PP_CONCAT_MATCH(next, m[i].mask_tail)) { + len += strlen(next->text); + next = next->next; + } + + /* No match or no text to process */ + if (tok == next || len == 0) + break; + + len += strlen(tok->text); + p = buf = nasm_malloc(len + 1); + + strcpy(p, tok->text); + p = strchr(p, '\0'); + tok = delete_Token(tok); + + while (tok != next) { + if (PP_CONCAT_MATCH(tok, m[i].mask_tail)) { + strcpy(p, tok->text); + p = strchr(p, '\0'); + } + tok = delete_Token(tok); + } + + tok = tokenize(buf); + nasm_free(buf); + + if (prev_next) + *prev_next = tok; + else + *head = tok; + + /* + * Connect pasted into original stream, + * ie A -> new-tokens -> B + */ + while (tok && tok->next) + tok = tok->next; + tok->next = next; + + if (!pasted) + pasted = true; + + /* Restart from pasted tokens head */ + tok = prev_next ? *prev_next : *head; + } + + break; + } + + prev_next = &tok->next; + + if (tok->next && + !tok_type_(tok->next, TOK_WHITESPACE) && + !tok_type_(tok->next, TOK_PASTE)) + prev_nonspace = prev_next; + + tok = tok->next; + } + + return pasted; +} + +/* + * expands to a list of tokens from %{x:y} + */ +static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last) +{ + Token *t = tline, **tt, *tm, *head; + char *pos; + int fst, lst, j, i; + + pos = strchr(tline->text, ':'); + nasm_assert(pos); + + lst = atoi(pos + 1); + fst = atoi(tline->text + 1); + + /* + * only macros params are accounted so + * if someone passes %0 -- we reject such + * value(s) + */ + if (lst == 0 || fst == 0) + goto err; + + /* the values should be sane */ + if ((fst > (int)mac->nparam || fst < (-(int)mac->nparam)) || + (lst > (int)mac->nparam || lst < (-(int)mac->nparam))) + goto err; + + fst = fst < 0 ? fst + (int)mac->nparam + 1: fst; + lst = lst < 0 ? lst + (int)mac->nparam + 1: lst; + + /* counted from zero */ + fst--, lst--; + + /* + * It will be at least one token. Note we + * need to scan params until separator, otherwise + * only first token will be passed. + */ + tm = mac->params[(fst + mac->rotate) % mac->nparam]; + if (!tm) + goto err; + head = new_Token(NULL, tm->type, tm->text, 0); + tt = &head->next, tm = tm->next; + while (tok_isnt_(tm, ",")) { + t = new_Token(NULL, tm->type, tm->text, 0); + *tt = t, tt = &t->next, tm = tm->next; + } + + if (fst < lst) { + for (i = fst + 1; i <= lst; i++) { + t = new_Token(NULL, TOK_OTHER, ",", 0); + *tt = t, tt = &t->next; + j = (i + mac->rotate) % mac->nparam; + tm = mac->params[j]; + while (tok_isnt_(tm, ",")) { + t = new_Token(NULL, tm->type, tm->text, 0); + *tt = t, tt = &t->next, tm = tm->next; + } + } + } else { + for (i = fst - 1; i >= lst; i--) { + t = new_Token(NULL, TOK_OTHER, ",", 0); + *tt = t, tt = &t->next; + j = (i + mac->rotate) % mac->nparam; + tm = mac->params[j]; + while (tok_isnt_(tm, ",")) { + t = new_Token(NULL, tm->type, tm->text, 0); + *tt = t, tt = &t->next, tm = tm->next; + } + } + } + + *last = tt; + return head; + +err: + nasm_error(ERR_NONFATAL, "`%%{%s}': macro parameters out of range", + &tline->text[1]); + return tline; +} + +/* + * Expand MMacro-local things: parameter references (%0, %n, %+n, + * %-n) and MMacro-local identifiers (%%foo) as well as + * macro indirection (%[...]) and range (%{..:..}). + */ +static Token *expand_mmac_params(Token * tline) +{ + Token *t, *tt, **tail, *thead; + bool changed = false; + char *pos; + + tail = &thead; + thead = NULL; + + while (tline) { + if (tline->type == TOK_PREPROC_ID && tline->text && tline->text[0] && + (((tline->text[1] == '+' || tline->text[1] == '-') && tline->text[2]) || + (tline->text[1] >= '0' && tline->text[1] <= '9') || + tline->text[1] == '%')) { + char *text = NULL; + int type = 0, cc; /* type = 0 to placate optimisers */ + char tmpbuf[30]; + unsigned int n; + int i; + MMacro *mac; + + t = tline; + tline = tline->next; + + mac = istk->mstk; + while (mac && !mac->name) /* avoid mistaking %reps for macros */ + mac = mac->next_active; + if (!mac) { + nasm_error(ERR_NONFATAL, "`%s': not in a macro call", t->text); + } else { + pos = strchr(t->text, ':'); + if (!pos) { + switch (t->text[1]) { + /* + * We have to make a substitution of one of the + * forms %1, %-1, %+1, %%foo, %0. + */ + case '0': + type = TOK_NUMBER; + snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam); + text = nasm_strdup(tmpbuf); + break; + case '%': + type = TOK_ID; + snprintf(tmpbuf, sizeof(tmpbuf), "..@%"PRIu64".", + mac->unique); + text = nasm_strcat(tmpbuf, t->text + 2); + break; + case '-': + n = atoi(t->text + 2) - 1; + if (n >= mac->nparam) + tt = NULL; + else { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + cc = find_cc(tt); + if (cc == -1) { + nasm_error(ERR_NONFATAL, + "macro parameter %d is not a condition code", + n + 1); + text = NULL; + } else { + type = TOK_ID; + if (inverse_ccs[cc] == -1) { + nasm_error(ERR_NONFATAL, + "condition code `%s' is not invertible", + conditions[cc]); + text = NULL; + } else + text = nasm_strdup(conditions[inverse_ccs[cc]]); + } + break; + case '+': + n = atoi(t->text + 2) - 1; + if (n >= mac->nparam) + tt = NULL; + else { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + cc = find_cc(tt); + if (cc == -1) { + nasm_error(ERR_NONFATAL, + "macro parameter %d is not a condition code", + n + 1); + text = NULL; + } else { + type = TOK_ID; + text = nasm_strdup(conditions[cc]); + } + break; + default: + n = atoi(t->text + 1) - 1; + if (n >= mac->nparam) + tt = NULL; + else { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + if (tt) { + for (i = 0; i < mac->paramlen[n]; i++) { + *tail = new_Token(NULL, tt->type, tt->text, 0); + tail = &(*tail)->next; + tt = tt->next; + } + } + text = NULL; /* we've done it here */ + break; + } + } else { + /* + * seems we have a parameters range here + */ + Token *head, **last; + head = expand_mmac_params_range(mac, t, &last); + if (head != t) { + *tail = head; + *last = tline; + tline = head; + text = NULL; + } + } + } + if (!text) { + delete_Token(t); + } else { + *tail = t; + tail = &t->next; + t->type = type; + nasm_free(t->text); + t->text = text; + t->a.mac = NULL; + } + changed = true; + continue; + } else if (tline->type == TOK_INDIRECT) { + t = tline; + tline = tline->next; + tt = tokenize(t->text); + tt = expand_mmac_params(tt); + tt = expand_smacro(tt); + *tail = tt; + while (tt) { + tt->a.mac = NULL; /* Necessary? */ + tail = &tt->next; + tt = tt->next; + } + delete_Token(t); + changed = true; + } else { + t = *tail = tline; + tline = tline->next; + t->a.mac = NULL; + tail = &t->next; + } + } + *tail = NULL; + + if (changed) { + const struct tokseq_match t[] = { + { + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_FLOAT), /* head */ + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_NUMBER) | + PP_CONCAT_MASK(TOK_FLOAT) | + PP_CONCAT_MASK(TOK_OTHER) /* tail */ + }, + { + PP_CONCAT_MASK(TOK_NUMBER), /* head */ + PP_CONCAT_MASK(TOK_NUMBER) /* tail */ + } + }; + paste_tokens(&thead, t, ARRAY_SIZE(t), false); + } + + return thead; +} + +/* + * Expand all single-line macro calls made in the given line. + * Return the expanded version of the line. The original is deemed + * to be destroyed in the process. (In reality we'll just move + * Tokens from input to output a lot of the time, rather than + * actually bothering to destroy and replicate.) + */ + +static Token *expand_smacro(Token * tline) +{ + Token *t, *tt, *mstart, **tail, *thead; + SMacro *head = NULL, *m; + Token **params; + int *paramsize; + unsigned int nparam, sparam; + int brackets; + Token *org_tline = tline; + Context *ctx; + const char *mname; + int64_t deadman = nasm_limit[LIMIT_MACROS]; + bool expanded; + + /* + * Trick: we should avoid changing the start token pointer since it can + * be contained in "next" field of other token. Because of this + * we allocate a copy of first token and work with it; at the end of + * routine we copy it back + */ + if (org_tline) { + tline = new_Token(org_tline->next, org_tline->type, + org_tline->text, 0); + tline->a.mac = org_tline->a.mac; + nasm_free(org_tline->text); + org_tline->text = NULL; + } + + expanded = true; /* Always expand %+ at least once */ + +again: + thead = NULL; + tail = &thead; + + while (tline) { /* main token loop */ + if (!--deadman) { + nasm_error(ERR_NONFATAL, "interminable macro recursion"); + goto err; + } + + if ((mname = tline->text)) { + /* if this token is a local macro, look in local context */ + if (tline->type == TOK_ID) { + head = (SMacro *)hash_findix(&smacros, mname); + } else if (tline->type == TOK_PREPROC_ID) { + ctx = get_ctx(mname, &mname); + head = ctx ? (SMacro *)hash_findix(&ctx->localmac, mname) : NULL; + } else + head = NULL; + + /* + * We've hit an identifier. As in is_mmacro below, we first + * check whether the identifier is a single-line macro at + * all, then think about checking for parameters if + * necessary. + */ + list_for_each(m, head) + if (!mstrcmp(m->name, mname, m->casesense)) + break; + if (m) { + mstart = tline; + params = NULL; + paramsize = NULL; + if (m->nparam == 0) { + /* + * Simple case: the macro is parameterless. Discard the + * one token that the macro call took, and push the + * expansion back on the to-do stack. + */ + if (!m->expansion) { + if (!strcmp("__FILE__", m->name)) { + const char *file = src_get_fname(); + /* nasm_free(tline->text); here? */ + tline->text = nasm_quote(file, strlen(file)); + tline->type = TOK_STRING; + continue; + } + if (!strcmp("__LINE__", m->name)) { + nasm_free(tline->text); + make_tok_num(tline, src_get_linnum()); + continue; + } + if (!strcmp("__BITS__", m->name)) { + nasm_free(tline->text); + make_tok_num(tline, globalbits); + continue; + } + tline = delete_Token(tline); + continue; + } + } else { + /* + * Complicated case: at least one macro with this name + * exists and takes parameters. We must find the + * parameters in the call, count them, find the SMacro + * that corresponds to that form of the macro call, and + * substitute for the parameters when we expand. What a + * pain. + */ + /*tline = tline->next; + skip_white_(tline); */ + do { + t = tline->next; + while (tok_type_(t, TOK_SMAC_END)) { + t->a.mac->in_progress = false; + t->text = NULL; + t = tline->next = delete_Token(t); + } + tline = t; + } while (tok_type_(tline, TOK_WHITESPACE)); + if (!tok_is_(tline, "(")) { + /* + * This macro wasn't called with parameters: ignore + * the call. (Behaviour borrowed from gnu cpp.) + */ + tline = mstart; + m = NULL; + } else { + int paren = 0; + int white = 0; + brackets = 0; + nparam = 0; + sparam = PARAM_DELTA; + params = nasm_malloc(sparam * sizeof(Token *)); + params[0] = tline->next; + paramsize = nasm_malloc(sparam * sizeof(int)); + paramsize[0] = 0; + while (true) { /* parameter loop */ + /* + * For some unusual expansions + * which concatenates function call + */ + t = tline->next; + while (tok_type_(t, TOK_SMAC_END)) { + t->a.mac->in_progress = false; + t->text = NULL; + t = tline->next = delete_Token(t); + } + tline = t; + + if (!tline) { + nasm_error(ERR_NONFATAL, + "macro call expects terminating `)'"); + break; + } + if (tline->type == TOK_WHITESPACE + && brackets <= 0) { + if (paramsize[nparam]) + white++; + else + params[nparam] = tline->next; + continue; /* parameter loop */ + } + if (tline->type == TOK_OTHER + && tline->text[1] == 0) { + char ch = tline->text[0]; + if (ch == ',' && !paren && brackets <= 0) { + if (++nparam >= sparam) { + sparam += PARAM_DELTA; + params = nasm_realloc(params, + sparam * sizeof(Token *)); + paramsize = nasm_realloc(paramsize, + sparam * sizeof(int)); + } + params[nparam] = tline->next; + paramsize[nparam] = 0; + white = 0; + continue; /* parameter loop */ + } + if (ch == '{' && + (brackets > 0 || (brackets == 0 && + !paramsize[nparam]))) + { + if (!(brackets++)) { + params[nparam] = tline->next; + continue; /* parameter loop */ + } + } + if (ch == '}' && brackets > 0) + if (--brackets == 0) { + brackets = -1; + continue; /* parameter loop */ + } + if (ch == '(' && !brackets) + paren++; + if (ch == ')' && brackets <= 0) + if (--paren < 0) + break; + } + if (brackets < 0) { + brackets = 0; + nasm_error(ERR_NONFATAL, "braces do not " + "enclose all of macro parameter"); + } + paramsize[nparam] += white + 1; + white = 0; + } /* parameter loop */ + nparam++; + while (m && (m->nparam != nparam || + mstrcmp(m->name, mname, + m->casesense))) + m = m->next; + if (!m) + nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP, + "macro `%s' exists, " + "but not taking %d parameters", + mstart->text, nparam); + } + } + if (m && m->in_progress) + m = NULL; + if (!m) { /* in progess or didn't find '(' or wrong nparam */ + /* + * Design question: should we handle !tline, which + * indicates missing ')' here, or expand those + * macros anyway, which requires the (t) test a few + * lines down? + */ + nasm_free(params); + nasm_free(paramsize); + tline = mstart; + } else { + /* + * Expand the macro: we are placed on the last token of the + * call, so that we can easily split the call from the + * following tokens. We also start by pushing an SMAC_END + * token for the cycle removal. + */ + t = tline; + if (t) { + tline = t->next; + t->next = NULL; + } + tt = new_Token(tline, TOK_SMAC_END, NULL, 0); + tt->a.mac = m; + m->in_progress = true; + tline = tt; + list_for_each(t, m->expansion) { + if (t->type >= TOK_SMAC_PARAM) { + Token *pcopy = tline, **ptail = &pcopy; + Token *ttt, *pt; + int i; + + ttt = params[t->type - TOK_SMAC_PARAM]; + i = paramsize[t->type - TOK_SMAC_PARAM]; + while (--i >= 0) { + pt = *ptail = new_Token(tline, ttt->type, + ttt->text, 0); + ptail = &pt->next; + ttt = ttt->next; + if (!ttt && i > 0) { + /* + * FIXME: Need to handle more gracefully, + * exiting early on agruments analysis. + */ + nasm_error(ERR_FATAL, + "macro `%s' expects %d args", + mstart->text, + (int)paramsize[t->type - TOK_SMAC_PARAM]); + } + } + tline = pcopy; + } else if (t->type == TOK_PREPROC_Q) { + tt = new_Token(tline, TOK_ID, mname, 0); + tline = tt; + } else if (t->type == TOK_PREPROC_QQ) { + tt = new_Token(tline, TOK_ID, m->name, 0); + tline = tt; + } else { + tt = new_Token(tline, t->type, t->text, 0); + tline = tt; + } + } + + /* + * Having done that, get rid of the macro call, and clean + * up the parameters. + */ + nasm_free(params); + nasm_free(paramsize); + free_tlist(mstart); + expanded = true; + continue; /* main token loop */ + } + } + } + + if (tline->type == TOK_SMAC_END) { + /* On error path it might already be dropped */ + if (tline->a.mac) + tline->a.mac->in_progress = false; + tline = delete_Token(tline); + } else { + t = *tail = tline; + tline = tline->next; + t->a.mac = NULL; + t->next = NULL; + tail = &t->next; + } + } + + /* + * Now scan the entire line and look for successive TOK_IDs that resulted + * after expansion (they can't be produced by tokenize()). The successive + * TOK_IDs should be concatenated. + * Also we look for %+ tokens and concatenate the tokens before and after + * them (without white spaces in between). + */ + if (expanded) { + const struct tokseq_match t[] = { + { + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID), /* head */ + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID) | + PP_CONCAT_MASK(TOK_NUMBER) /* tail */ + } + }; + if (paste_tokens(&thead, t, ARRAY_SIZE(t), true)) { + /* + * If we concatenated something, *and* we had previously expanded + * an actual macro, scan the lines again for macros... + */ + tline = thead; + expanded = false; + goto again; + } + } + +err: + if (org_tline) { + if (thead) { + *org_tline = *thead; + /* since we just gave text to org_line, don't free it */ + thead->text = NULL; + delete_Token(thead); + } else { + /* the expression expanded to empty line; + we can't return NULL for some reasons + we just set the line to a single WHITESPACE token. */ + memset(org_tline, 0, sizeof(*org_tline)); + org_tline->text = NULL; + org_tline->type = TOK_WHITESPACE; + } + thead = org_tline; + } + + return thead; +} + +/* + * Similar to expand_smacro but used exclusively with macro identifiers + * right before they are fetched in. The reason is that there can be + * identifiers consisting of several subparts. We consider that if there + * are more than one element forming the name, user wants a expansion, + * otherwise it will be left as-is. Example: + * + * %define %$abc cde + * + * the identifier %$abc will be left as-is so that the handler for %define + * will suck it and define the corresponding value. Other case: + * + * %define _%$abc cde + * + * In this case user wants name to be expanded *before* %define starts + * working, so we'll expand %$abc into something (if it has a value; + * otherwise it will be left as-is) then concatenate all successive + * PP_IDs into one. + */ +static Token *expand_id(Token * tline) +{ + Token *cur, *oldnext = NULL; + + if (!tline || !tline->next) + return tline; + + cur = tline; + while (cur->next && + (cur->next->type == TOK_ID || + cur->next->type == TOK_PREPROC_ID + || cur->next->type == TOK_NUMBER)) + cur = cur->next; + + /* If identifier consists of just one token, don't expand */ + if (cur == tline) + return tline; + + if (cur) { + oldnext = cur->next; /* Detach the tail past identifier */ + cur->next = NULL; /* so that expand_smacro stops here */ + } + + tline = expand_smacro(tline); + + if (cur) { + /* expand_smacro possibly changhed tline; re-scan for EOL */ + cur = tline; + while (cur && cur->next) + cur = cur->next; + if (cur) + cur->next = oldnext; + } + + return tline; +} + +/* + * Determine whether the given line constitutes a multi-line macro + * call, and return the MMacro structure called if so. Doesn't have + * to check for an initial label - that's taken care of in + * expand_mmacro - but must check numbers of parameters. Guaranteed + * to be called with tline->type == TOK_ID, so the putative macro + * name is easy to find. + */ +static MMacro *is_mmacro(Token * tline, Token *** params_array) +{ + MMacro *head, *m; + Token **params; + int nparam; + + head = (MMacro *) hash_findix(&mmacros, tline->text); + + /* + * Efficiency: first we see if any macro exists with the given + * name. If not, we can return NULL immediately. _Then_ we + * count the parameters, and then we look further along the + * list if necessary to find the proper MMacro. + */ + list_for_each(m, head) + if (!mstrcmp(m->name, tline->text, m->casesense)) + break; + if (!m) + return NULL; + + /* + * OK, we have a potential macro. Count and demarcate the + * parameters. + */ + count_mmac_params(tline->next, &nparam, ¶ms); + + /* + * So we know how many parameters we've got. Find the MMacro + * structure that handles this number. + */ + while (m) { + if (m->nparam_min <= nparam + && (m->plus || nparam <= m->nparam_max)) { + /* + * This one is right. Just check if cycle removal + * prohibits us using it before we actually celebrate... + */ + if (m->in_progress > m->max_depth) { + if (m->max_depth > 0) { + nasm_error(ERR_WARNING, + "reached maximum recursion depth of %i", + m->max_depth); + } + nasm_free(params); + return NULL; + } + /* + * It's right, and we can use it. Add its default + * parameters to the end of our list if necessary. + */ + if (m->defaults && nparam < m->nparam_min + m->ndefs) { + params = + nasm_realloc(params, + ((m->nparam_min + m->ndefs + + 1) * sizeof(*params))); + while (nparam < m->nparam_min + m->ndefs) { + params[nparam] = m->defaults[nparam - m->nparam_min]; + nparam++; + } + } + /* + * If we've gone over the maximum parameter count (and + * we're in Plus mode), ignore parameters beyond + * nparam_max. + */ + if (m->plus && nparam > m->nparam_max) + nparam = m->nparam_max; + /* + * Then terminate the parameter list, and leave. + */ + if (!params) { /* need this special case */ + params = nasm_malloc(sizeof(*params)); + nparam = 0; + } + params[nparam] = NULL; + *params_array = params; + return m; + } + /* + * This one wasn't right: look for the next one with the + * same name. + */ + list_for_each(m, m->next) + if (!mstrcmp(m->name, tline->text, m->casesense)) + break; + } + + /* + * After all that, we didn't find one with the right number of + * parameters. Issue a warning, and fail to expand the macro. + */ + nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_MNP, + "macro `%s' exists, but not taking %d parameters", + tline->text, nparam); + nasm_free(params); + return NULL; +} + + +/* + * Save MMacro invocation specific fields in + * preparation for a recursive macro expansion + */ +static void push_mmacro(MMacro *m) +{ + MMacroInvocation *i; + + i = nasm_malloc(sizeof(MMacroInvocation)); + i->prev = m->prev; + i->params = m->params; + i->iline = m->iline; + i->nparam = m->nparam; + i->rotate = m->rotate; + i->paramlen = m->paramlen; + i->unique = m->unique; + i->condcnt = m->condcnt; + m->prev = i; +} + + +/* + * Restore MMacro invocation specific fields that were + * saved during a previous recursive macro expansion + */ +static void pop_mmacro(MMacro *m) +{ + MMacroInvocation *i; + + if (m->prev) { + i = m->prev; + m->prev = i->prev; + m->params = i->params; + m->iline = i->iline; + m->nparam = i->nparam; + m->rotate = i->rotate; + m->paramlen = i->paramlen; + m->unique = i->unique; + m->condcnt = i->condcnt; + nasm_free(i); + } +} + + +/* + * Expand the multi-line macro call made by the given line, if + * there is one to be expanded. If there is, push the expansion on + * istk->expansion and return 1. Otherwise return 0. + */ +static int expand_mmacro(Token * tline) +{ + Token *startline = tline; + Token *label = NULL; + int dont_prepend = 0; + Token **params, *t, *tt; + MMacro *m; + Line *l, *ll; + int i, nparam, *paramlen; + const char *mname; + + t = tline; + skip_white_(t); + /* if (!tok_type_(t, TOK_ID)) Lino 02/25/02 */ + if (!tok_type_(t, TOK_ID) && !tok_type_(t, TOK_PREPROC_ID)) + return 0; + m = is_mmacro(t, ¶ms); + if (m) { + mname = t->text; + } else { + Token *last; + /* + * We have an id which isn't a macro call. We'll assume + * it might be a label; we'll also check to see if a + * colon follows it. Then, if there's another id after + * that lot, we'll check it again for macro-hood. + */ + label = last = t; + t = t->next; + if (tok_type_(t, TOK_WHITESPACE)) + last = t, t = t->next; + if (tok_is_(t, ":")) { + dont_prepend = 1; + last = t, t = t->next; + if (tok_type_(t, TOK_WHITESPACE)) + last = t, t = t->next; + } + if (!tok_type_(t, TOK_ID) || !(m = is_mmacro(t, ¶ms))) + return 0; + last->next = NULL; + mname = t->text; + tline = t; + } + + /* + * Fix up the parameters: this involves stripping leading and + * trailing whitespace, then stripping braces if they are + * present. + */ + for (nparam = 0; params[nparam]; nparam++) ; + paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL; + + for (i = 0; params[i]; i++) { + int brace = 0; + int comma = (!m->plus || i < nparam - 1); + + t = params[i]; + skip_white_(t); + if (tok_is_(t, "{")) + t = t->next, brace++, comma = false; + params[i] = t; + paramlen[i] = 0; + while (t) { + if (comma && t->type == TOK_OTHER && !strcmp(t->text, ",")) + break; /* ... because we have hit a comma */ + if (comma && t->type == TOK_WHITESPACE + && tok_is_(t->next, ",")) + break; /* ... or a space then a comma */ + if (brace && t->type == TOK_OTHER) { + if (t->text[0] == '{') + brace++; /* ... or a nested opening brace */ + else if (t->text[0] == '}') + if (!--brace) + break; /* ... or a brace */ + } + t = t->next; + paramlen[i]++; + } + if (brace) + nasm_error(ERR_NONFATAL, "macro params should be enclosed in braces"); + } + + /* + * OK, we have a MMacro structure together with a set of + * parameters. We must now go through the expansion and push + * copies of each Line on to istk->expansion. Substitution of + * parameter tokens and macro-local tokens doesn't get done + * until the single-line macro substitution process; this is + * because delaying them allows us to change the semantics + * later through %rotate. + * + * First, push an end marker on to istk->expansion, mark this + * macro as in progress, and set up its invocation-specific + * variables. + */ + ll = nasm_malloc(sizeof(Line)); + ll->next = istk->expansion; + ll->finishes = m; + ll->first = NULL; + istk->expansion = ll; + + /* + * Save the previous MMacro expansion in the case of + * macro recursion + */ + if (m->max_depth && m->in_progress) + push_mmacro(m); + + m->in_progress ++; + m->params = params; + m->iline = tline; + m->nparam = nparam; + m->rotate = 0; + m->paramlen = paramlen; + m->unique = unique++; + m->lineno = 0; + m->condcnt = 0; + + m->next_active = istk->mstk; + istk->mstk = m; + + list_for_each(l, m->expansion) { + Token **tail; + + ll = nasm_malloc(sizeof(Line)); + ll->finishes = NULL; + ll->next = istk->expansion; + istk->expansion = ll; + tail = &ll->first; + + list_for_each(t, l->first) { + Token *x = t; + switch (t->type) { + case TOK_PREPROC_Q: + tt = *tail = new_Token(NULL, TOK_ID, mname, 0); + break; + case TOK_PREPROC_QQ: + tt = *tail = new_Token(NULL, TOK_ID, m->name, 0); + break; + case TOK_PREPROC_ID: + if (t->text[1] == '0' && t->text[2] == '0') { + dont_prepend = -1; + x = label; + if (!x) + continue; + } + /* fall through */ + default: + tt = *tail = new_Token(NULL, x->type, x->text, 0); + break; + } + tail = &tt->next; + } + *tail = NULL; + } + + /* + * If we had a label, push it on as the first line of + * the macro expansion. + */ + if (label) { + if (dont_prepend < 0) + free_tlist(startline); + else { + ll = nasm_malloc(sizeof(Line)); + ll->finishes = NULL; + ll->next = istk->expansion; + istk->expansion = ll; + ll->first = startline; + if (!dont_prepend) { + while (label->next) + label = label->next; + label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0); + } + } + } + + lfmt->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO); + + return 1; +} + +/* + * This function adds macro names to error messages, and suppresses + * them if necessary. + */ +static void pp_verror(int severity, const char *fmt, va_list arg) +{ + char buff[BUFSIZ]; + MMacro *mmac = NULL; + int delta = 0; + + /* + * If we're in a dead branch of IF or something like it, ignore the error. + * However, because %else etc are evaluated in the state context + * of the previous branch, errors might get lost: + * %if 0 ... %else trailing garbage ... %endif + * So %else etc should set the ERR_PP_PRECOND flag. + */ + if ((severity & ERR_MASK) < ERR_FATAL && + istk && istk->conds && + ((severity & ERR_PP_PRECOND) ? + istk->conds->state == COND_NEVER : + !emitting(istk->conds->state))) + return; + + /* get %macro name */ + if (!(severity & ERR_NOFILE) && istk && istk->mstk) { + mmac = istk->mstk; + /* but %rep blocks should be skipped */ + while (mmac && !mmac->name) + mmac = mmac->next_active, delta++; + } + + if (mmac) { + vsnprintf(buff, sizeof(buff), fmt, arg); + + nasm_set_verror(real_verror); + nasm_error(severity, "(%s:%d) %s", + mmac->name, mmac->lineno - delta, buff); + nasm_set_verror(pp_verror); + } else { + real_verror(severity, fmt, arg); + } +} + +static void +pp_reset(const char *file, int apass, StrList **deplist) +{ + Token *t; + + cstk = NULL; + istk = nasm_malloc(sizeof(Include)); + istk->next = NULL; + istk->conds = NULL; + istk->expansion = NULL; + istk->mstk = NULL; + istk->fp = nasm_open_read(file, NF_TEXT); + istk->fname = NULL; + src_set(0, file); + istk->lineinc = 1; + if (!istk->fp) + nasm_fatal(ERR_NOFILE, "unable to open input file `%s'", file); + defining = NULL; + nested_mac_count = 0; + nested_rep_count = 0; + init_macros(); + unique = 0; + + if (tasm_compatible_mode) + pp_add_stdmac(nasm_stdmac_tasm); + + pp_add_stdmac(nasm_stdmac_nasm); + pp_add_stdmac(nasm_stdmac_version); + + if (extrastdmac) + pp_add_stdmac(extrastdmac); + + stdmacpos = stdmacros[0]; + stdmacnext = &stdmacros[1]; + + do_predef = true; + + /* + * 0 for dependencies, 1 for preparatory passes, 2 for final pass. + * The caller, however, will also pass in 3 for preprocess-only so + * we can set __PASS__ accordingly. + */ + pass = apass > 2 ? 2 : apass; + + dephead = deplist; + nasm_add_string_to_strlist(dephead, file); + + /* + * Define the __PASS__ macro. This is defined here unlike + * all the other builtins, because it is special -- it varies between + * passes. + */ + t = nasm_malloc(sizeof(*t)); + t->next = NULL; + make_tok_num(t, apass); + t->a.mac = NULL; + define_smacro(NULL, "__PASS__", true, 0, t); +} + +static void pp_init(void) +{ + hash_init(&FileHash, HASH_MEDIUM); +} + +static char *pp_getline(void) +{ + char *line; + Token *tline; + + real_verror = nasm_set_verror(pp_verror); + + while (1) { + /* + * Fetch a tokenized line, either from the macro-expansion + * buffer or from the input file. + */ + tline = NULL; + while (istk->expansion && istk->expansion->finishes) { + Line *l = istk->expansion; + if (!l->finishes->name && l->finishes->in_progress > 1) { + Line *ll; + + /* + * This is a macro-end marker for a macro with no + * name, which means it's not really a macro at all + * but a %rep block, and the `in_progress' field is + * more than 1, meaning that we still need to + * repeat. (1 means the natural last repetition; 0 + * means termination by %exitrep.) We have + * therefore expanded up to the %endrep, and must + * push the whole block on to the expansion buffer + * again. We don't bother to remove the macro-end + * marker: we'd only have to generate another one + * if we did. + */ + l->finishes->in_progress--; + list_for_each(l, l->finishes->expansion) { + Token *t, *tt, **tail; + + ll = nasm_malloc(sizeof(Line)); + ll->next = istk->expansion; + ll->finishes = NULL; + ll->first = NULL; + tail = &ll->first; + + list_for_each(t, l->first) { + if (t->text || t->type == TOK_WHITESPACE) { + tt = *tail = new_Token(NULL, t->type, t->text, 0); + tail = &tt->next; + } + } + + istk->expansion = ll; + } + } else { + /* + * Check whether a `%rep' was started and not ended + * within this macro expansion. This can happen and + * should be detected. It's a fatal error because + * I'm too confused to work out how to recover + * sensibly from it. + */ + if (defining) { + if (defining->name) + nasm_panic(0, "defining with name in expansion"); + else if (istk->mstk->name) + nasm_fatal(0, "`%%rep' without `%%endrep' within" + " expansion of macro `%s'", + istk->mstk->name); + } + + /* + * FIXME: investigate the relationship at this point between + * istk->mstk and l->finishes + */ + { + MMacro *m = istk->mstk; + istk->mstk = m->next_active; + if (m->name) { + /* + * This was a real macro call, not a %rep, and + * therefore the parameter information needs to + * be freed. + */ + if (m->prev) { + pop_mmacro(m); + l->finishes->in_progress --; + } else { + nasm_free(m->params); + free_tlist(m->iline); + nasm_free(m->paramlen); + l->finishes->in_progress = 0; + } + } + + /* + * FIXME It is incorrect to always free_mmacro here. + * It leads to usage-after-free. + * + * https://bugzilla.nasm.us/show_bug.cgi?id=3392414 + */ +#if 0 + else + free_mmacro(m); +#endif + } + istk->expansion = l->next; + nasm_free(l); + lfmt->downlevel(LIST_MACRO); + } + } + while (1) { /* until we get a line we can use */ + + if (istk->expansion) { /* from a macro expansion */ + char *p; + Line *l = istk->expansion; + if (istk->mstk) + istk->mstk->lineno++; + tline = l->first; + istk->expansion = l->next; + nasm_free(l); + p = detoken(tline, false); + lfmt->line(LIST_MACRO, p); + nasm_free(p); + break; + } + line = read_line(); + if (line) { /* from the current input file */ + line = prepreproc(line); + tline = tokenize(line); + nasm_free(line); + break; + } + /* + * The current file has ended; work down the istk + */ + { + Include *i = istk; + fclose(i->fp); + if (i->conds) { + /* nasm_error can't be conditionally suppressed */ + nasm_fatal(0, + "expected `%%endif' before end of file"); + } + /* only set line and file name if there's a next node */ + if (i->next) + src_set(i->lineno, i->fname); + istk = i->next; + lfmt->downlevel(LIST_INCLUDE); + nasm_free(i); + if (!istk) { + line = NULL; + goto done; + } + if (istk->expansion && istk->expansion->finishes) + break; + } + } + + /* + * We must expand MMacro parameters and MMacro-local labels + * _before_ we plunge into directive processing, to cope + * with things like `%define something %1' such as STRUC + * uses. Unless we're _defining_ a MMacro, in which case + * those tokens should be left alone to go into the + * definition; and unless we're in a non-emitting + * condition, in which case we don't want to meddle with + * anything. + */ + if (!defining && !(istk->conds && !emitting(istk->conds->state)) + && !(istk->mstk && !istk->mstk->in_progress)) { + tline = expand_mmac_params(tline); + } + + /* + * Check the line to see if it's a preprocessor directive. + */ + if (do_directive(tline, &line) == DIRECTIVE_FOUND) { + if (line) + break; /* Directive generated output */ + else + continue; + } else if (defining) { + /* + * We're defining a multi-line macro. We emit nothing + * at all, and just + * shove the tokenized line on to the macro definition. + */ + Line *l = nasm_malloc(sizeof(Line)); + l->next = defining->expansion; + l->first = tline; + l->finishes = NULL; + defining->expansion = l; + continue; + } else if (istk->conds && !emitting(istk->conds->state)) { + /* + * We're in a non-emitting branch of a condition block. + * Emit nothing at all, not even a blank line: when we + * emerge from the condition we'll give a line-number + * directive so we keep our place correctly. + */ + free_tlist(tline); + continue; + } else if (istk->mstk && !istk->mstk->in_progress) { + /* + * We're in a %rep block which has been terminated, so + * we're walking through to the %endrep without + * emitting anything. Emit nothing at all, not even a + * blank line: when we emerge from the %rep block we'll + * give a line-number directive so we keep our place + * correctly. + */ + free_tlist(tline); + continue; + } else { + tline = expand_smacro(tline); + if (!expand_mmacro(tline)) { + /* + * De-tokenize the line again, and emit it. + */ + line = detoken(tline, true); + free_tlist(tline); + break; + } else { + continue; /* expand_mmacro calls free_tlist */ + } + } + } + +done: + nasm_set_verror(real_verror); + return line; +} + +static void pp_cleanup(int pass) +{ + real_verror = nasm_set_verror(pp_verror); + + if (defining) { + if (defining->name) { + nasm_error(ERR_NONFATAL, + "end of file while still defining macro `%s'", + defining->name); + } else { + nasm_error(ERR_NONFATAL, "end of file while still in %%rep"); + } + + free_mmacro(defining); + defining = NULL; + } + + nasm_set_verror(real_verror); + + while (cstk) + ctx_pop(); + free_macros(); + while (istk) { + Include *i = istk; + istk = istk->next; + fclose(i->fp); + nasm_free(i); + } + while (cstk) + ctx_pop(); + src_set_fname(NULL); + if (pass == 0) { + IncPath *i; + free_llist(predef); + predef = NULL; + delete_Blocks(); + freeTokens = NULL; + while ((i = ipath)) { + ipath = i->next; + if (i->path) + nasm_free(i->path); + nasm_free(i); + } + } +} + +static void pp_include_path(char *path) +{ + IncPath *i; + + i = nasm_malloc(sizeof(IncPath)); + i->path = path ? nasm_strdup(path) : NULL; + i->next = NULL; + + if (ipath) { + IncPath *j = ipath; + while (j->next) + j = j->next; + j->next = i; + } else { + ipath = i; + } +} + +static void pp_pre_include(char *fname) +{ + Token *inc, *space, *name; + Line *l; + + name = new_Token(NULL, TOK_INTERNAL_STRING, fname, 0); + space = new_Token(name, TOK_WHITESPACE, NULL, 0); + inc = new_Token(space, TOK_PREPROC_ID, "%include", 0); + + l = nasm_malloc(sizeof(Line)); + l->next = predef; + l->first = inc; + l->finishes = NULL; + predef = l; +} + +static void pp_pre_define(char *definition) +{ + Token *def, *space; + Line *l; + char *equals; + + real_verror = nasm_set_verror(pp_verror); + + equals = strchr(definition, '='); + space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); + def = new_Token(space, TOK_PREPROC_ID, "%define", 0); + if (equals) + *equals = ' '; + space->next = tokenize(definition); + if (equals) + *equals = '='; + + if (space->next->type != TOK_PREPROC_ID && + space->next->type != TOK_ID) + nasm_error(ERR_WARNING, "pre-defining non ID `%s\'\n", definition); + + l = nasm_malloc(sizeof(Line)); + l->next = predef; + l->first = def; + l->finishes = NULL; + predef = l; + + nasm_set_verror(real_verror); +} + +static void pp_pre_undefine(char *definition) +{ + Token *def, *space; + Line *l; + + space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); + def = new_Token(space, TOK_PREPROC_ID, "%undef", 0); + space->next = tokenize(definition); + + l = nasm_malloc(sizeof(Line)); + l->next = predef; + l->first = def; + l->finishes = NULL; + predef = l; +} + +/* Insert an early preprocessor command that doesn't need special handling */ +static void pp_pre_command(const char *what, char *string) +{ + char *cmd; + Token *def, *space; + Line *l; + + def = tokenize(string); + if (what) { + cmd = nasm_strcat(what[0] == '%' ? "" : "%", what); + space = new_Token(def, TOK_WHITESPACE, NULL, 0); + def = new_Token(space, TOK_PREPROC_ID, cmd, 0); + } + + l = nasm_malloc(sizeof(Line)); + l->next = predef; + l->first = def; + l->finishes = NULL; + predef = l; +} + +static void pp_add_stdmac(macros_t *macros) +{ + macros_t **mp; + + /* Find the end of the list and avoid duplicates */ + for (mp = stdmacros; *mp; mp++) { + if (*mp == macros) + return; /* Nothing to do */ + } + + nasm_assert(mp < &stdmacros[ARRAY_SIZE(stdmacros)-1]); + + *mp = macros; +} + +static void pp_extra_stdmac(macros_t *macros) +{ + extrastdmac = macros; +} + +static void make_tok_num(Token * tok, int64_t val) +{ + char numbuf[32]; + snprintf(numbuf, sizeof(numbuf), "%"PRId64"", val); + tok->text = nasm_strdup(numbuf); + tok->type = TOK_NUMBER; +} + +static void pp_list_one_macro(MMacro *m, int severity) +{ + if (!m) + return; + + /* We need to print the next_active list in reverse order */ + pp_list_one_macro(m->next_active, severity); + + if (m->name && !m->nolist) { + src_set(m->xline + m->lineno, m->fname); + nasm_error(severity, "... from macro `%s' defined here", m->name); + } +} + +static void pp_error_list_macros(int severity) +{ + int32_t saved_line; + const char *saved_fname = NULL; + + severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY; + src_get(&saved_line, &saved_fname); + + if (istk) + pp_list_one_macro(istk->mstk, severity); + + src_set(saved_line, saved_fname); +} + +const struct preproc_ops nasmpp = { + pp_init, + pp_reset, + pp_getline, + pp_cleanup, + pp_extra_stdmac, + pp_pre_define, + pp_pre_undefine, + pp_pre_include, + pp_pre_command, + pp_include_path, + pp_error_list_macros, +}; diff --git a/asm/preproc.h b/asm/preproc.h new file mode 100644 index 0000000..fcf8695 --- /dev/null +++ b/asm/preproc.h @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * preproc.h header file for preproc.c + */ + +#ifndef NASM_PREPROC_H +#define NASM_PREPROC_H + +#include "nasmlib.h" +#include "pptok.h" + +extern const char * const pp_directives[]; +extern const uint8_t pp_directives_len[]; + +/* Pointer to a macro chain */ +typedef const unsigned char macros_t; + +enum preproc_token pp_token_hash(const char *token); + +/* Opens an include file or input file. This uses the include path. */ +FILE *pp_input_fopen(const char *filename, enum file_flags mode); + +#endif diff --git a/asm/quote.c b/asm/quote.c new file mode 100644 index 0000000..75a9372 --- /dev/null +++ b/asm/quote.c @@ -0,0 +1,479 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * quote.c + */ + +#include "compiler.h" + +#include + +#include "nasmlib.h" +#include "quote.h" + +char *nasm_quote(const char *str, size_t len) +{ + const char *p, *ep; + char c, c1, *q, *nstr; + unsigned char uc; + bool sq_ok, dq_ok; + size_t qlen; + + sq_ok = dq_ok = true; + ep = str+len; + qlen = 0; /* Length if we need `...` quotes */ + for (p = str; p < ep; p++) { + c = *p; + switch (c) { + case '\'': + sq_ok = false; + qlen++; + break; + case '\"': + dq_ok = false; + qlen++; + break; + case '`': + case '\\': + qlen += 2; + break; + default: + if (c < ' ' || c > '~') { + sq_ok = dq_ok = false; + switch (c) { + case '\a': + case '\b': + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case 27: + qlen += 2; + break; + default: + c1 = (p+1 < ep) ? p[1] : 0; + if (c1 >= '0' && c1 <= '7') + uc = 0377; /* Must use the full form */ + else + uc = c; + if (uc > 077) + qlen++; + if (uc > 07) + qlen++; + qlen += 2; + break; + } + } else { + qlen++; + } + break; + } + } + + if (sq_ok || dq_ok) { + /* Use '...' or "..." */ + nstr = nasm_malloc(len+3); + nstr[0] = nstr[len+1] = sq_ok ? '\'' : '\"'; + nstr[len+2] = '\0'; + if (len > 0) + memcpy(nstr+1, str, len); + } else { + /* Need to use `...` quoted syntax */ + nstr = nasm_malloc(qlen+3); + q = nstr; + *q++ = '`'; + for (p = str; p < ep; p++) { + c = *p; + switch (c) { + case '`': + case '\\': + *q++ = '\\'; + *q++ = c; + break; + case 7: + *q++ = '\\'; + *q++ = 'a'; + break; + case 8: + *q++ = '\\'; + *q++ = 'b'; + break; + case 9: + *q++ = '\\'; + *q++ = 't'; + break; + case 10: + *q++ = '\\'; + *q++ = 'n'; + break; + case 11: + *q++ = '\\'; + *q++ = 'v'; + break; + case 12: + *q++ = '\\'; + *q++ = 'f'; + break; + case 13: + *q++ = '\\'; + *q++ = 'r'; + break; + case 27: + *q++ = '\\'; + *q++ = 'e'; + break; + default: + if (c < ' ' || c > '~') { + c1 = (p+1 < ep) ? p[1] : 0; + if (c1 >= '0' && c1 <= '7') + uc = 0377; /* Must use the full form */ + else + uc = c; + *q++ = '\\'; + if (uc > 077) + *q++ = ((unsigned char)c >> 6) + '0'; + if (uc > 07) + *q++ = (((unsigned char)c >> 3) & 7) + '0'; + *q++ = ((unsigned char)c & 7) + '0'; + break; + } else { + *q++ = c; + } + break; + } + } + *q++ = '`'; + *q++ = '\0'; + nasm_assert((size_t)(q-nstr) == qlen+3); + } + return nstr; +} + +static char *emit_utf8(char *q, int32_t v) +{ + if (v < 0) { + /* Impossible - do nothing */ + } else if (v <= 0x7f) { + *q++ = v; + } else if (v <= 0x000007ff) { + *q++ = 0xc0 | (v >> 6); + *q++ = 0x80 | (v & 63); + } else if (v <= 0x0000ffff) { + *q++ = 0xe0 | (v >> 12); + *q++ = 0x80 | ((v >> 6) & 63); + *q++ = 0x80 | (v & 63); + } else if (v <= 0x001fffff) { + *q++ = 0xf0 | (v >> 18); + *q++ = 0x80 | ((v >> 12) & 63); + *q++ = 0x80 | ((v >> 6) & 63); + *q++ = 0x80 | (v & 63); + } else if (v <= 0x03ffffff) { + *q++ = 0xf8 | (v >> 24); + *q++ = 0x80 | ((v >> 18) & 63); + *q++ = 0x80 | ((v >> 12) & 63); + *q++ = 0x80 | ((v >> 6) & 63); + *q++ = 0x80 | (v & 63); + } else { + *q++ = 0xfc | (v >> 30); + *q++ = 0x80 | ((v >> 24) & 63); + *q++ = 0x80 | ((v >> 18) & 63); + *q++ = 0x80 | ((v >> 12) & 63); + *q++ = 0x80 | ((v >> 6) & 63); + *q++ = 0x80 | (v & 63); + } + return q; +} + +/* + * Do an *in-place* dequoting of the specified string, returning the + * resulting length (which may be containing embedded nulls.) + * + * In-place replacement is possible since the unquoted length is always + * shorter than or equal to the quoted length. + * + * *ep points to the final quote, or to the null if improperly quoted. + */ +size_t nasm_unquote(char *str, char **ep) +{ + char bq; + char *p, *q; + char *escp = NULL; + char c; + enum unq_state { + st_start, + st_backslash, + st_hex, + st_oct, + st_ucs + } state; + int ndig = 0; + int32_t nval = 0; + + p = q = str; + + bq = *p++; + if (!bq) + return 0; + + switch (bq) { + case '\'': + case '\"': + /* '...' or "..." string */ + while ((c = *p) && c != bq) { + p++; + *q++ = c; + } + *q = '\0'; + break; + + case '`': + /* `...` string */ + state = st_start; + + while ((c = *p)) { + p++; + switch (state) { + case st_start: + switch (c) { + case '\\': + state = st_backslash; + break; + case '`': + p--; + goto out; + default: + *q++ = c; + break; + } + break; + + case st_backslash: + state = st_start; + escp = p; /* Beginning of argument sequence */ + nval = 0; + switch (c) { + case 'a': + *q++ = 7; + break; + case 'b': + *q++ = 8; + break; + case 'e': + *q++ = 27; + break; + case 'f': + *q++ = 12; + break; + case 'n': + *q++ = 10; + break; + case 'r': + *q++ = 13; + break; + case 't': + *q++ = 9; + break; + case 'u': + state = st_ucs; + ndig = 4; + break; + case 'U': + state = st_ucs; + ndig = 8; + break; + case 'v': + *q++ = 11; + break; + case 'x': + case 'X': + state = st_hex; + ndig = 2; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = st_oct; + ndig = 2; /* Up to two more digits */ + nval = c - '0'; + break; + default: + *q++ = c; + break; + } + break; + + case st_oct: + if (c >= '0' && c <= '7') { + nval = (nval << 3) + (c - '0'); + if (!--ndig) { + *q++ = nval; + state = st_start; + } + } else { + p--; /* Process this character again */ + *q++ = nval; + state = st_start; + } + break; + + case st_hex: + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'F') || + (c >= 'a' && c <= 'f')) { + nval = (nval << 4) + numvalue(c); + if (!--ndig) { + *q++ = nval; + state = st_start; + } + } else { + p--; /* Process this character again */ + *q++ = (p > escp) ? nval : escp[-1]; + state = st_start; + } + break; + + case st_ucs: + if ((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'F') || + (c >= 'a' && c <= 'f')) { + nval = (nval << 4) + numvalue(c); + if (!--ndig) { + q = emit_utf8(q, nval); + state = st_start; + } + } else { + p--; /* Process this character again */ + if (p > escp) + q = emit_utf8(q, nval); + else + *q++ = escp[-1]; + state = st_start; + } + break; + } + } + switch (state) { + case st_start: + case st_backslash: + break; + case st_oct: + *q++ = nval; + break; + case st_hex: + *q++ = (p > escp) ? nval : escp[-1]; + break; + case st_ucs: + if (p > escp) + q = emit_utf8(q, nval); + else + *q++ = escp[-1]; + break; + } + out: + break; + + default: + /* Not a quoted string, just return the input... */ + p = q = strchr(str, '\0'); + break; + } + + if (ep) + *ep = p; + return q-str; +} + +/* + * Find the end of a quoted string; returns the pointer to the terminating + * character (either the ending quote or the null character, if unterminated.) + */ +char *nasm_skip_string(char *str) +{ + char bq; + char *p; + char c; + enum unq_state { + st_start, + st_backslash + } state; + + bq = str[0]; + if (bq == '\'' || bq == '\"') { + /* '...' or "..." string */ + for (p = str+1; *p && *p != bq; p++) + ; + return p; + } else if (bq == '`') { + /* `...` string */ + state = st_start; + p = str+1; + if (!*p) + return p; + + while ((c = *p++)) { + switch (state) { + case st_start: + switch (c) { + case '\\': + state = st_backslash; + break; + case '`': + return p-1; /* Found the end */ + default: + break; + } + break; + + case st_backslash: + /* + * Note: for the purpose of finding the end of the string, + * all successor states to st_backslash are functionally + * equivalent to st_start, since either a backslash or + * a backquote will force a return to the st_start state. + */ + state = st_start; + break; + } + } + return p-1; /* Unterminated string... */ + } else { + return str; /* Not a string... */ + } +} diff --git a/asm/quote.h b/asm/quote.h new file mode 100644 index 0000000..2d8ce87 --- /dev/null +++ b/asm/quote.h @@ -0,0 +1,44 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +#ifndef NASM_QUOTE_H +#define NASM_QUOTE_H + +#include "compiler.h" + +char *nasm_quote(const char *str, size_t len); +size_t nasm_unquote(char *str, char **endptr); +char *nasm_skip_string(char *str); + +#endif /* NASM_QUOTE_H */ + diff --git a/asm/rdstrnum.c b/asm/rdstrnum.c new file mode 100644 index 0000000..319f140 --- /dev/null +++ b/asm/rdstrnum.c @@ -0,0 +1,70 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * rdstrnum.c + * + * This converts a NASM string to an integer, used when a string + * is used in an integer constant context. This is a binary conversion, + * not a conversion from a numeric constant in text form. + */ + +#include "compiler.h" +#include "nasmlib.h" +#include "nasm.h" + +int64_t readstrnum(char *str, int length, bool *warn) +{ + int64_t charconst = 0; + int i; + + *warn = false; + + str += length; + if (globalbits == 64) { + for (i = 0; i < length; i++) { + if (charconst & UINT64_C(0xFF00000000000000)) + *warn = true; + charconst &= ~UINT64_C(0xFF00000000000000); + charconst = (charconst << 8) + (uint8_t)*--str; + } + } else { + for (i = 0; i < length; i++) { + if (charconst & UINT32_C(0xFF000000)) + *warn = true; + charconst &= ~UINT32_C(0xFF000000); + charconst = (charconst << 8) + (uint8_t)*--str; + } + } + return charconst; +} diff --git a/asm/segalloc.c b/asm/segalloc.c new file mode 100644 index 0000000..6d7a420 --- /dev/null +++ b/asm/segalloc.c @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 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. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" +#include "nasm.h" +#include "nasmlib.h" +#include "insns.h" + +static int32_t next_seg = 2; + +int32_t seg_alloc(void) +{ + int32_t this_seg = next_seg; + + next_seg += 2; + return this_seg; +} diff --git a/asm/stdscan.c b/asm/stdscan.c new file mode 100644 index 0000000..8e17590 --- /dev/null +++ b/asm/stdscan.c @@ -0,0 +1,345 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +#include "compiler.h" + +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "quote.h" +#include "stdscan.h" +#include "insns.h" + +/* + * Standard scanner routine used by parser.c and some output + * formats. It keeps a succession of temporary-storage strings in + * stdscan_tempstorage, which can be cleared using stdscan_reset. + */ +static char *stdscan_bufptr = NULL; +static char **stdscan_tempstorage = NULL; +static int stdscan_tempsize = 0, stdscan_templen = 0; +#define STDSCAN_TEMP_DELTA 256 + +void stdscan_set(char *str) +{ + stdscan_bufptr = str; +} + +char *stdscan_get(void) +{ + return stdscan_bufptr; +} + +static void stdscan_pop(void) +{ + nasm_free(stdscan_tempstorage[--stdscan_templen]); +} + +void stdscan_reset(void) +{ + while (stdscan_templen > 0) + stdscan_pop(); +} + +/* + * Unimportant cleanup is done to avoid confusing people who are trying + * to debug real memory leaks + */ +void stdscan_cleanup(void) +{ + stdscan_reset(); + nasm_free(stdscan_tempstorage); +} + +static char *stdscan_copy(char *p, int len) +{ + char *text; + + text = nasm_malloc(len + 1); + memcpy(text, p, len); + text[len] = '\0'; + + if (stdscan_templen >= stdscan_tempsize) { + stdscan_tempsize += STDSCAN_TEMP_DELTA; + stdscan_tempstorage = nasm_realloc(stdscan_tempstorage, + stdscan_tempsize * + sizeof(char *)); + } + stdscan_tempstorage[stdscan_templen++] = text; + + return text; +} + +/* + * a token is enclosed with braces. proper token type will be assigned + * accordingly with the token flag. + */ +static int stdscan_handle_brace(struct tokenval *tv) +{ + if (!(tv->t_flag & TFLAG_BRC_ANY)) { + /* invalid token is put inside braces */ + nasm_error(ERR_NONFATAL, + "`%s' is not a valid decorator with braces", tv->t_charptr); + tv->t_type = TOKEN_INVALID; + } else if (tv->t_flag & TFLAG_BRC_OPT) { + if (is_reg_class(OPMASKREG, tv->t_integer)) { + /* within braces, opmask register is now used as a mask */ + tv->t_type = TOKEN_OPMASK; + } + } + + return tv->t_type; +} + +int stdscan(void *private_data, struct tokenval *tv) +{ + char ourcopy[MAX_KEYWORD + 1], *r, *s; + + (void)private_data; /* Don't warn that this parameter is unused */ + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + if (!*stdscan_bufptr) + return tv->t_type = TOKEN_EOS; + + /* we have a token; either an id, a number or a char */ + if (isidstart(*stdscan_bufptr) || + (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) { + /* now we've got an identifier */ + bool is_sym = false; + int token_type; + + if (*stdscan_bufptr == '$') { + is_sym = true; + stdscan_bufptr++; + } + + r = stdscan_bufptr++; + /* read the entire buffer to advance the buffer pointer but... */ + while (isidchar(*stdscan_bufptr)) + stdscan_bufptr++; + + /* ... copy only up to IDLEN_MAX-1 characters */ + tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r < IDLEN_MAX ? + stdscan_bufptr - r : IDLEN_MAX - 1); + + if (is_sym || stdscan_bufptr - r > MAX_KEYWORD) + return tv->t_type = TOKEN_ID; /* bypass all other checks */ + + for (s = tv->t_charptr, r = ourcopy; *s; s++) + *r++ = nasm_tolower(*s); + *r = '\0'; + /* right, so we have an identifier sitting in temp storage. now, + * is it actually a register or instruction name, or what? */ + token_type = nasm_token_hash(ourcopy, tv); + + if (unlikely(tv->t_flag & TFLAG_WARN)) { + nasm_error(ERR_WARNING|ERR_PASS1|ERR_WARN_PTR, + "`%s' is not a NASM keyword", tv->t_charptr); + } + + if (likely(!(tv->t_flag & TFLAG_BRC))) { + /* most of the tokens fall into this case */ + return token_type; + } else { + return tv->t_type = TOKEN_ID; + } + } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) { + /* + * It's a $ sign with no following hex number; this must + * mean it's a Here token ($), evaluating to the current + * assembly location, or a Base token ($$), evaluating to + * the base of the current segment. + */ + stdscan_bufptr++; + if (*stdscan_bufptr == '$') { + stdscan_bufptr++; + return tv->t_type = TOKEN_BASE; + } + return tv->t_type = TOKEN_HERE; + } else if (isnumstart(*stdscan_bufptr)) { /* now we've got a number */ + bool rn_error; + bool is_hex = false; + bool is_float = false; + bool has_e = false; + char c; + + r = stdscan_bufptr; + + if (*stdscan_bufptr == '$') { + stdscan_bufptr++; + is_hex = true; + } + + for (;;) { + c = *stdscan_bufptr++; + + if (!is_hex && (c == 'e' || c == 'E')) { + has_e = true; + if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') { + /* + * e can only be followed by +/- if it is either a + * prefixed hex number or a floating-point number + */ + is_float = true; + stdscan_bufptr++; + } + } else if (c == 'H' || c == 'h' || c == 'X' || c == 'x') { + is_hex = true; + } else if (c == 'P' || c == 'p') { + is_float = true; + if (*stdscan_bufptr == '+' || *stdscan_bufptr == '-') + stdscan_bufptr++; + } else if (isnumchar(c)) + ; /* just advance */ + else if (c == '.') + is_float = true; + else + break; + } + stdscan_bufptr--; /* Point to first character beyond number */ + + if (has_e && !is_hex) { + /* 1e13 is floating-point, but 1e13h is not */ + is_float = true; + } + + if (is_float) { + tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r); + return tv->t_type = TOKEN_FLOAT; + } else { + r = stdscan_copy(r, stdscan_bufptr - r); + tv->t_integer = readnum(r, &rn_error); + stdscan_pop(); + if (rn_error) { + /* some malformation occurred */ + return tv->t_type = TOKEN_ERRNUM; + } + tv->t_charptr = NULL; + return tv->t_type = TOKEN_NUM; + } + } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"' || + *stdscan_bufptr == '`') { + /* a quoted string */ + char start_quote = *stdscan_bufptr; + tv->t_charptr = stdscan_bufptr; + tv->t_inttwo = nasm_unquote(tv->t_charptr, &stdscan_bufptr); + if (*stdscan_bufptr != start_quote) + return tv->t_type = TOKEN_ERRSTR; + stdscan_bufptr++; /* Skip final quote */ + return tv->t_type = TOKEN_STR; + } else if (*stdscan_bufptr == '{') { + /* now we've got a decorator */ + int token_len; + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + + r = ++stdscan_bufptr; + /* + * read the entire buffer to advance the buffer pointer + * {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. + */ + while (isbrcchar(*stdscan_bufptr)) + stdscan_bufptr++; + + token_len = stdscan_bufptr - r; + + /* ... copy only up to DECOLEN_MAX-1 characters */ + tv->t_charptr = stdscan_copy(r, token_len < DECOLEN_MAX ? + token_len : DECOLEN_MAX - 1); + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + /* if brace is not closed properly or token is too long */ + if ((*stdscan_bufptr != '}') || (token_len > MAX_KEYWORD)) { + nasm_error(ERR_NONFATAL, + "invalid decorator token inside braces"); + return tv->t_type = TOKEN_INVALID; + } + + stdscan_bufptr++; /* skip closing brace */ + + for (s = tv->t_charptr, r = ourcopy; *s; s++) + *r++ = nasm_tolower(*s); + *r = '\0'; + + /* right, so we have a decorator sitting in temp storage. */ + nasm_token_hash(ourcopy, tv); + + /* handle tokens inside braces */ + return stdscan_handle_brace(tv); + } else if (*stdscan_bufptr == ';') { + /* a comment has happened - stay */ + return tv->t_type = TOKEN_EOS; + } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_SHR; + } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_SHL; + } else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_SDIV; + } else if (stdscan_bufptr[0] == '%' && stdscan_bufptr[1] == '%') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_SMOD; + } else if (stdscan_bufptr[0] == '=' && stdscan_bufptr[1] == '=') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_EQ; + } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '>') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_NE; + } else if (stdscan_bufptr[0] == '!' && stdscan_bufptr[1] == '=') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_NE; + } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '=') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_LE; + } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '=') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_GE; + } else if (stdscan_bufptr[0] == '&' && stdscan_bufptr[1] == '&') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_DBL_AND; + } else if (stdscan_bufptr[0] == '^' && stdscan_bufptr[1] == '^') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_DBL_XOR; + } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') { + stdscan_bufptr += 2; + return tv->t_type = TOKEN_DBL_OR; + } else /* just an ordinary char */ + return tv->t_type = (uint8_t)(*stdscan_bufptr++); +} diff --git a/asm/stdscan.h b/asm/stdscan.h new file mode 100644 index 0000000..8dbc2d0 --- /dev/null +++ b/asm/stdscan.h @@ -0,0 +1,49 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * stdscan.h header file for stdscan.c + */ + +#ifndef NASM_STDSCAN_H +#define NASM_STDSCAN_H + +/* Standard scanner */ +void stdscan_set(char *str); +char *stdscan_get(void); +void stdscan_reset(void); +int stdscan(void *private_data, struct tokenval *tv); +int nasm_token_hash(const char *token, struct tokenval *tv); +void stdscan_cleanup(void); + +#endif diff --git a/asm/strfunc.c b/asm/strfunc.c new file mode 100644 index 0000000..236b9d2 --- /dev/null +++ b/asm/strfunc.c @@ -0,0 +1,359 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * strfunc.c + * + * String transformation functions + */ + +#include "nasmlib.h" +#include "nasm.h" + +/* + * Convert a string in UTF-8 format to UTF-16LE + */ +static size_t utf8_to_16le(uint8_t *str, size_t len, char *op) +{ +#define EMIT(x) do { if (op) { WRITESHORT(op,x); } outlen++; } while(0) + + size_t outlen = 0; + int expect = 0; + uint8_t c; + uint32_t v = 0, vmin = 0; + + while (len--) { + c = *str++; + + if (expect) { + if ((c & 0xc0) != 0x80) { + expect = 0; + return -1; + } else { + v = (v << 6) | (c & 0x3f); + if (!--expect) { + if (v < vmin || v > 0x10ffff || + (v >= 0xd800 && v <= 0xdfff)) { + return -1; + } else if (v > 0xffff) { + v -= 0x10000; + EMIT(0xd800 | (v >> 10)); + EMIT(0xdc00 | (v & 0x3ff)); + } else { + EMIT(v); + } + } + continue; + } + } + + if (c < 0x80) { + EMIT(c); + } else if (c < 0xc0 || c >= 0xfe) { + /* Invalid UTF-8 */ + return -1; + } else if (c < 0xe0) { + v = c & 0x1f; + expect = 1; + vmin = 0x80; + } else if (c < 0xf0) { + v = c & 0x0f; + expect = 2; + vmin = 0x800; + } else if (c < 0xf8) { + v = c & 0x07; + expect = 3; + vmin = 0x10000; + } else if (c < 0xfc) { + v = c & 0x03; + expect = 4; + vmin = 0x200000; + } else { + v = c & 0x01; + expect = 5; + vmin = 0x4000000; + } + } + + return expect ? (size_t)-1 : outlen << 1; + +#undef EMIT +} + +/* + * Convert a string in UTF-8 format to UTF-16BE + */ +static size_t utf8_to_16be(uint8_t *str, size_t len, char *op) +{ +#define EMIT(x) \ + do { \ + uint16_t _y = (x); \ + if (op) { \ + WRITECHAR(op, _y >> 8); \ + WRITECHAR(op, _y); \ + } \ + outlen++; \ + } while (0) \ + + size_t outlen = 0; + int expect = 0; + uint8_t c; + uint32_t v = 0, vmin = 0; + + while (len--) { + c = *str++; + + if (expect) { + if ((c & 0xc0) != 0x80) { + expect = 0; + return -1; + } else { + v = (v << 6) | (c & 0x3f); + if (!--expect) { + if (v < vmin || v > 0x10ffff || + (v >= 0xd800 && v <= 0xdfff)) { + return -1; + } else if (v > 0xffff) { + v -= 0x10000; + EMIT(0xdc00 | (v & 0x3ff)); + EMIT(0xd800 | (v >> 10)); + } else { + EMIT(v); + } + } + continue; + } + } + + if (c < 0x80) { + EMIT(c); + } else if (c < 0xc0 || c >= 0xfe) { + /* Invalid UTF-8 */ + return -1; + } else if (c < 0xe0) { + v = c & 0x1f; + expect = 1; + vmin = 0x80; + } else if (c < 0xf0) { + v = c & 0x0f; + expect = 2; + vmin = 0x800; + } else if (c < 0xf8) { + v = c & 0x07; + expect = 3; + vmin = 0x10000; + } else if (c < 0xfc) { + v = c & 0x03; + expect = 4; + vmin = 0x200000; + } else { + v = c & 0x01; + expect = 5; + vmin = 0x4000000; + } + } + + return expect ? (size_t)-1 : outlen << 1; + +#undef EMIT +} + +/* + * Convert a string in UTF-8 format to UTF-32LE + */ +static size_t utf8_to_32le(uint8_t *str, size_t len, char *op) +{ +#define EMIT(x) do { if (op) { WRITELONG(op,x); } outlen++; } while(0) + + size_t outlen = 0; + int expect = 0; + uint8_t c; + uint32_t v = 0, vmin = 0; + + while (len--) { + c = *str++; + + if (expect) { + if ((c & 0xc0) != 0x80) { + return -1; + } else { + v = (v << 6) | (c & 0x3f); + if (!--expect) { + if (v < vmin || (v >= 0xd800 && v <= 0xdfff)) { + return -1; + } else { + EMIT(v); + } + } + continue; + } + } + + if (c < 0x80) { + EMIT(c); + } else if (c < 0xc0 || c >= 0xfe) { + /* Invalid UTF-8 */ + return -1; + } else if (c < 0xe0) { + v = c & 0x1f; + expect = 1; + vmin = 0x80; + } else if (c < 0xf0) { + v = c & 0x0f; + expect = 2; + vmin = 0x800; + } else if (c < 0xf8) { + v = c & 0x07; + expect = 3; + vmin = 0x10000; + } else if (c < 0xfc) { + v = c & 0x03; + expect = 4; + vmin = 0x200000; + } else { + v = c & 0x01; + expect = 5; + vmin = 0x4000000; + } + } + + return expect ? (size_t)-1 : outlen << 2; + +#undef EMIT +} + +/* + * Convert a string in UTF-8 format to UTF-32BE + */ +static size_t utf8_to_32be(uint8_t *str, size_t len, char *op) +{ +#define EMIT(x) \ + do { \ + uint32_t _y = (x); \ + if (op) { \ + WRITECHAR(op,_y >> 24); \ + WRITECHAR(op,_y >> 16); \ + WRITECHAR(op,_y >> 8); \ + WRITECHAR(op,_y); \ + } \ + outlen++; \ + } while (0) + + size_t outlen = 0; + int expect = 0; + uint8_t c; + uint32_t v = 0, vmin = 0; + + while (len--) { + c = *str++; + + if (expect) { + if ((c & 0xc0) != 0x80) { + return -1; + } else { + v = (v << 6) | (c & 0x3f); + if (!--expect) { + if (v < vmin || (v >= 0xd800 && v <= 0xdfff)) { + return -1; + } else { + EMIT(v); + } + } + continue; + } + } + + if (c < 0x80) { + EMIT(c); + } else if (c < 0xc0 || c >= 0xfe) { + /* Invalid UTF-8 */ + return -1; + } else if (c < 0xe0) { + v = c & 0x1f; + expect = 1; + vmin = 0x80; + } else if (c < 0xf0) { + v = c & 0x0f; + expect = 2; + vmin = 0x800; + } else if (c < 0xf8) { + v = c & 0x07; + expect = 3; + vmin = 0x10000; + } else if (c < 0xfc) { + v = c & 0x03; + expect = 4; + vmin = 0x200000; + } else { + v = c & 0x01; + expect = 5; + vmin = 0x4000000; + } + } + + return expect ? (size_t)-1 : outlen << 2; + +#undef EMIT +} + +typedef size_t (*transform_func)(uint8_t *, size_t, char *); + +/* + * Apply a specific string transform and return it in a nasm_malloc'd + * buffer, returning the length. On error, returns (size_t)-1 and no + * buffer is allocated. + */ +size_t string_transform(char *str, size_t len, char **out, enum strfunc func) +{ + /* This should match enum strfunc in nasm.h */ + static const transform_func str_transforms[] = { + utf8_to_16le, + utf8_to_16le, + utf8_to_16be, + utf8_to_32le, + utf8_to_32le, + utf8_to_32be, + }; + transform_func transform = str_transforms[func]; + size_t outlen; + uint8_t *s = (uint8_t *)str; + char *buf; + + outlen = transform(s, len, NULL); + if (outlen == (size_t)-1) + return -1; + + *out = buf = nasm_malloc(outlen+1); + buf[outlen] = '\0'; /* Forcibly null-terminate the buffer */ + return transform(s, len, buf); +} diff --git a/asm/tokens.dat b/asm/tokens.dat new file mode 100644 index 0000000..528f243 --- /dev/null +++ b/asm/tokens.dat @@ -0,0 +1,135 @@ +## -------------------------------------------------------------------------- +## +## Copyright 1996-2016 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. +## +## -------------------------------------------------------------------------- + +# +# Tokens other than instructions and registers +# + +% TOKEN_PREFIX, 0, 0, P_* +a16 +a32 +a64 +asp +lock +o16 +o32 +o64 +osp +rep +repe +repne +repnz +repz +times +wait +xacquire +xrelease +bnd +nobnd + +% TOKEN_SPECIAL, 0, 0, S_* +abs +byte +dword +far +long +near +nosplit +oword +qword +rel +short +strict +to +tword +word +yword +zword + +% TOKEN_ID, 0, TFLAG_WARN, 0 +ptr + +% TOKEN_FLOAT, 0, 0, 0 +__infinity__ +__nan__ +__qnan__ +__snan__ + +% TOKEN_FLOATIZE, 0, 0, FLOAT_{__float*__} +__float8__ +__float16__ +__float32__ +__float64__ +__float80m__ +__float80e__ +__float128l__ +__float128h__ + +% TOKEN_STRFUNC, 0, 0, STRFUNC_{__*__} +__utf16__ +__utf16le__ +__utf16be__ +__utf32__ +__utf32le__ +__utf32be__ + +% TOKEN_IFUNC, 0, 0, IFUNC_{__*__} +__ilog2e__ +__ilog2w__ +__ilog2f__ +__ilog2c__ + +% TOKEN_*, 0, 0, 0 +seg +wrt + +% TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO{1to*} +1to2 +1to4 +1to8 +1to16 + +% TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_{*-sae} +rn-sae +rd-sae +ru-sae +rz-sae + +% TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_* +sae +z + +% TOKEN_PREFIX, 0, TFLAG_BRC, P_* +evex +vex3 +vex2 diff --git a/asm/tokens.h b/asm/tokens.h new file mode 100644 index 0000000..b0e9887 --- /dev/null +++ b/asm/tokens.h @@ -0,0 +1,11 @@ +/* + * This file is generated from insns.dat, regs.dat and token.dat + * by tokhash.pl; do not edit. + */ + +#ifndef NASM_TOKENS_H +#define NASM_TOKENS_H + +#define MAX_KEYWORD 17 /* length of longest keyword */ + +#endif /* NASM_TOKENS_H */ diff --git a/asm/tokhash.c b/asm/tokhash.c new file mode 100644 index 0000000..9a5620e --- /dev/null +++ b/asm/tokhash.c @@ -0,0 +1,6431 @@ +/* + * This file is generated from insns.dat, regs.dat and token.dat + * by tokhash.pl; do not edit. + */ + +#include "compiler.h" +#include +#include "nasm.h" +#include "hashtbl.h" +#include "insns.h" +#include "stdscan.h" + +struct tokendata { + const char *string; + int16_t tokentype; + int8_t aux; + int8_t tokflag; + int32_t num; +}; + +int nasm_token_hash(const char *token, struct tokenval *tv) +{ +#define UNUSED (65535/3) + static const int16_t hash1[2048] = { + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + 0, + 6769, + 3411, + UNUSED, + 7328, + 0, + 5695, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + 0, + UNUSED, + 0, + 3082, + UNUSED, + 0, + UNUSED, + 0, + 0, + UNUSED, + 6709, + -830, + 5546, + 0, + 0, + 0, + 5038, + UNUSED, + 0, + 6444, + 0, + 0, + UNUSED, + 198, + 120, + 0, + 8767, + 0, + 0, + 11326, + 0, + -1516, + UNUSED, + 0, + 0, + 0, + 0, + 0, + 0, + UNUSED, + 0, + 0, + 2211, + UNUSED, + 0, + 2034, + 10643, + UNUSED, + UNUSED, + UNUSED, + 0, + 6349, + 0, + 11029, + UNUSED, + 0, + 0, + UNUSED, + 5764, + 0, + 0, + UNUSED, + 0, + 7690, + 4268, + -874, + 0, + UNUSED, + 8958, + 0, + 2777, + 1402, + 8375, + 1225, + UNUSED, + 7450, + 0, + UNUSED, + 2462, + 0, + 8935, + 3727, + 1901, + UNUSED, + UNUSED, + UNUSED, + 7671, + UNUSED, + -276, + 0, + 0, + 0, + UNUSED, + 8400, + 0, + UNUSED, + 403, + -122, + -907, + 7539, + 8821, + 0, + 0, + 373, + 11447, + -53, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + 433, + 7215, + 265, + 0, + 4892, + 0, + 0, + 1155, + UNUSED, + UNUSED, + 1932, + UNUSED, + -811, + 6943, + UNUSED, + -1638, + UNUSED, + 687, + 0, + 0, + 6991, + 2858, + 0, + 1946, + 0, + UNUSED, + UNUSED, + UNUSED, + 451, + 2522, + UNUSED, + -3714, + UNUSED, + 0, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1064, + 1480, + 113, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + 0, + 0, + 7672, + 6243, + UNUSED, + -2187, + 0, + UNUSED, + 6543, + 0, + 1664, + UNUSED, + UNUSED, + 0, + UNUSED, + 406, + UNUSED, + 6862, + UNUSED, + UNUSED, + 2745, + 0, + 0, + 0, + UNUSED, + 4663, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + 0, + 7678, + 0, + UNUSED, + UNUSED, + 0, + -2208, + 0, + 1565, + 0, + 0, + 66, + 8962, + UNUSED, + 0, + -589, + UNUSED, + -2123, + 0, + 0, + 1774, + UNUSED, + 0, + 0, + UNUSED, + UNUSED, + 2426, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 358, + UNUSED, + -1771, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + 7417, + 8800, + 0, + UNUSED, + UNUSED, + UNUSED, + 730, + 844, + 4783, + 0, + UNUSED, + 878, + 1112, + UNUSED, + UNUSED, + UNUSED, + 1442, + UNUSED, + 0, + UNUSED, + -1327, + UNUSED, + 6137, + -2278, + UNUSED, + 0, + 931, + UNUSED, + 838, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + 2201, + UNUSED, + 860, + 0, + 7689, + 1193, + UNUSED, + 1589, + 2616, + UNUSED, + 0, + 5534, + 592, + 1265, + 8352, + 8886, + UNUSED, + UNUSED, + UNUSED, + 0, + -2269, + 0, + 3460, + 2057, + 586, + 107, + 0, + UNUSED, + 0, + 0, + 201, + 0, + -299, + 1298, + 0, + UNUSED, + 0, + -1239, + 0, + UNUSED, + 0, + 7281, + 9022, + -547, + UNUSED, + 1158, + -3689, + 0, + 63, + 0, + 8750, + 4275, + 0, + -1229, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + UNUSED, + 6366, + 804, + UNUSED, + 2374, + 689, + -4609, + 0, + 69, + -4542, + 1282, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 1703, + 5791, + 2855, + UNUSED, + UNUSED, + 0, + UNUSED, + -2019, + UNUSED, + UNUSED, + -542, + 8880, + 9411, + UNUSED, + 2078, + -3135, + 9751, + 1723, + 741, + 1509, + 0, + 963, + 1795, + UNUSED, + 0, + UNUSED, + 7349, + 0, + 1094, + 0, + 0, + 3344, + 11061, + -826, + UNUSED, + UNUSED, + -2625, + 347, + 379, + 307, + UNUSED, + 800, + 3863, + 0, + 0, + 860, + UNUSED, + UNUSED, + 4615, + 0, + UNUSED, + 0, + 3716, + 473, + 0, + 0, + 3013, + 6441, + -182, + UNUSED, + UNUSED, + 1252, + UNUSED, + 1142, + UNUSED, + 3525, + UNUSED, + UNUSED, + 0, + UNUSED, + 11150, + 2366, + UNUSED, + UNUSED, + 6977, + 599, + UNUSED, + 1300, + 1224, + UNUSED, + 302, + 3140, + 1146, + -695, + 1250, + 1965, + 7990, + UNUSED, + 10394, + UNUSED, + 4383, + 702, + 9729, + UNUSED, + 1273, + UNUSED, + 93, + UNUSED, + 268, + UNUSED, + 10323, + -2155, + 1646, + -217, + 7271, + -263, + 0, + UNUSED, + UNUSED, + 3604, + -170, + 523, + 6655, + UNUSED, + UNUSED, + UNUSED, + 1579, + -854, + -6, + 1711, + 5204, + 5807, + 849, + 7226, + UNUSED, + 9487, + 3614, + -1057, + 603, + 7138, + UNUSED, + 0, + 8498, + 4475, + UNUSED, + 0, + 0, + 10377, + 1826, + UNUSED, + 10867, + -2483, + 0, + -1572, + 1364, + UNUSED, + 0, + 8527, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + 1509, + 1456, + -1077, + UNUSED, + 3590, + 0, + UNUSED, + -1468, + UNUSED, + 0, + 0, + UNUSED, + 751, + 394, + -392, + UNUSED, + UNUSED, + 0, + 108, + 1324, + UNUSED, + -2998, + UNUSED, + 3761, + 0, + 1607, + 0, + 211, + UNUSED, + UNUSED, + 1938, + -1836, + 135, + 542, + 0, + 905, + 1447, + 7709, + 0, + UNUSED, + UNUSED, + -1633, + 5737, + 6667, + 0, + 867, + UNUSED, + 921, + UNUSED, + UNUSED, + 9745, + 1482, + UNUSED, + UNUSED, + 1491, + 5301, + 11196, + 0, + UNUSED, + 2247, + 0, + UNUSED, + 1432, + 0, + 10676, + 0, + 1057, + UNUSED, + 2542, + UNUSED, + -279, + UNUSED, + UNUSED, + 18, + UNUSED, + 0, + -1422, + UNUSED, + -3092, + UNUSED, + -423, + UNUSED, + 650, + UNUSED, + 4900, + 0, + 5414, + -545, + -13, + 510, + 6540, + UNUSED, + -1586, + 6572, + UNUSED, + 972, + UNUSED, + UNUSED, + -129, + 2112, + 902, + UNUSED, + 3218, + 0, + 6551, + 2147, + 912, + 1625, + 6896, + UNUSED, + UNUSED, + UNUSED, + 8024, + UNUSED, + 4180, + UNUSED, + 916, + 649, + UNUSED, + 1706, + -1841, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1271, + 11257, + UNUSED, + 7478, + -585, + 1814, + 6356, + UNUSED, + -1173, + 2156, + UNUSED, + 0, + 1311, + 12458, + UNUSED, + 0, + 10272, + -457, + 5048, + 0, + UNUSED, + 6794, + 0, + 190, + 8954, + UNUSED, + 1588, + 2046, + 1133, + 1155, + 0, + 6665, + 2202, + -265, + 0, + 157, + 11069, + 5199, + 7725, + -482, + -1299, + 10509, + 11176, + UNUSED, + 63, + -1250, + -3442, + 724, + UNUSED, + UNUSED, + 1852, + UNUSED, + 0, + UNUSED, + UNUSED, + -1793, + UNUSED, + -969, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + 1792, + 0, + UNUSED, + 1276, + 9907, + 1154, + 426, + 230, + -280, + 0, + 8123, + 985, + 2978, + 5563, + -472, + 0, + 7659, + 0, + 4, + 0, + UNUSED, + -94, + -1317, + 763, + 1808, + UNUSED, + 844, + 3780, + UNUSED, + 5395, + UNUSED, + 1478, + 4845, + -4307, + 2426, + 0, + 1241, + 0, + UNUSED, + UNUSED, + 2598, + 0, + 4882, + 2278, + 0, + 0, + 0, + 0, + 5726, + 901, + 933, + 9683, + UNUSED, + 1519, + UNUSED, + 0, + 8452, + 3188, + 5667, + 0, + 2175, + UNUSED, + 7093, + 0, + 834, + UNUSED, + 840, + 3042, + 9154, + 1689, + UNUSED, + 0, + 0, + 430, + 2036, + -5039, + 3829, + 2377, + -2335, + UNUSED, + 9561, + 14811, + 1906, + 278, + 2300, + 2195, + -565, + 6644, + UNUSED, + 1088, + UNUSED, + UNUSED, + 1237, + UNUSED, + 1269, + UNUSED, + UNUSED, + 382, + 3666, + -756, + 1291, + 0, + 2138, + 0, + 7715, + 1967, + 1936, + UNUSED, + 0, + 7836, + UNUSED, + 9574, + 92, + UNUSED, + 7139, + UNUSED, + UNUSED, + 182, + 0, + 9819, + 2923, + 5955, + UNUSED, + 9074, + UNUSED, + UNUSED, + 21, + 0, + UNUSED, + 203, + 0, + 6541, + 252, + 342, + 175, + 2470, + -1248, + 1788, + -1198, + UNUSED, + 2334, + -93, + 465, + UNUSED, + 7666, + UNUSED, + UNUSED, + -2454, + 4893, + UNUSED, + 1109, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 242, + -758, + 8312, + UNUSED, + -253, + 1935, + UNUSED, + 0, + 2163, + 1566, + UNUSED, + UNUSED, + 260, + 1708, + -1052, + UNUSED, + 2693, + UNUSED, + UNUSED, + 11074, + 5712, + 0, + UNUSED, + UNUSED, + UNUSED, + -254, + 8653, + UNUSED, + -565, + UNUSED, + 527, + 1983, + UNUSED, + UNUSED, + 2688, + 408, + UNUSED, + 5048, + 1496, + 640, + UNUSED, + UNUSED, + 1080, + 0, + UNUSED, + UNUSED, + UNUSED, + -2078, + 8389, + 0, + UNUSED, + UNUSED, + -36, + -835, + 512, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 1530, + UNUSED, + 1593, + UNUSED, + 996, + UNUSED, + 1943, + 967, + 383, + 9556, + 803, + 2043, + UNUSED, + UNUSED, + 12293, + 1166, + UNUSED, + 2377, + -1625, + 1438, + UNUSED, + UNUSED, + 1620, + UNUSED, + -450, + 918, + -1248, + 0, + 854, + 2811, + 1521, + 0, + 1668, + 0, + -913, + UNUSED, + -975, + 1559, + UNUSED, + 1269, + UNUSED, + 0, + UNUSED, + 1924, + 2417, + 1067, + 6367, + 8621, + 400, + 2668, + 2282, + 8494, + 807, + -1114, + 10861, + UNUSED, + UNUSED, + 5324, + UNUSED, + UNUSED, + 12379, + UNUSED, + -845, + -1335, + 502, + 1497, + -1827, + 120, + 5867, + 0, + -99, + 0, + UNUSED, + -185, + 7964, + 502, + 6, + 8937, + UNUSED, + 5868, + 0, + 2094, + UNUSED, + 3890, + UNUSED, + 1495, + 7033, + 1310, + UNUSED, + 3612, + 7050, + UNUSED, + -958, + UNUSED, + 1804, + 3317, + 10446, + UNUSED, + 0, + -45, + 0, + UNUSED, + -4602, + 539, + 0, + 41, + 9886, + UNUSED, + UNUSED, + 422, + 11043, + 1362, + 815, + UNUSED, + UNUSED, + 1870, + 1962, + 676, + 0, + 1921, + 7075, + 586, + UNUSED, + 5061, + UNUSED, + 9450, + UNUSED, + UNUSED, + UNUSED, + 1340, + 0, + 9330, + -1303, + 0, + UNUSED, + 389, + -1073, + UNUSED, + 414, + 472, + 4843, + UNUSED, + 0, + UNUSED, + 10025, + 4350, + -501, + 384, + 1293, + 8243, + UNUSED, + -118, + 0, + -428, + 5667, + 990, + 2799, + 565, + 2410, + 0, + 669, + UNUSED, + 870, + 9277, + 8109, + 7234, + UNUSED, + 8627, + UNUSED, + UNUSED, + 1321, + 0, + 1200, + 129, + 7759, + 11283, + UNUSED, + 861, + UNUSED, + 0, + 2016, + UNUSED, + UNUSED, + 1530, + 2131, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 2901, + UNUSED, + 8931, + 664, + 5319, + UNUSED, + UNUSED, + 2181, + -1832, + 1543, + UNUSED, + 0, + 121, + UNUSED, + -73, + 658, + UNUSED, + UNUSED, + 7791, + UNUSED, + 1234, + 0, + 1467, + -1305, + UNUSED, + 5876, + 0, + 1945, + 73, + UNUSED, + 657, + -857, + -168, + UNUSED, + UNUSED, + 7330, + 7234, + UNUSED, + 223, + UNUSED, + UNUSED, + 2267, + UNUSED, + 2208, + UNUSED, + 5836, + UNUSED, + 7054, + 2127, + 1002, + 3220, + UNUSED, + 7699, + 6206, + 655, + -291, + 874, + UNUSED, + UNUSED, + UNUSED, + 2012, + 5526, + 0, + UNUSED, + UNUSED, + 3402, + 214, + UNUSED, + 1519, + 2062, + UNUSED, + 7015, + 425, + UNUSED, + -1015, + 0, + 1163, + 6814, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 2196, + UNUSED, + UNUSED, + 1545, + 9763, + -2018, + 0, + -239, + 431, + 2116, + UNUSED, + -1479, + UNUSED, + 1246, + UNUSED, + 8046, + 2061, + 0, + 308, + 770, + 323, + UNUSED, + 198, + UNUSED, + UNUSED, + 0, + 1895, + 0, + 6302, + UNUSED, + UNUSED, + 1095, + 1571, + 8396, + 594, + UNUSED, + UNUSED, + -21, + UNUSED, + 22, + UNUSED, + 0, + UNUSED, + -3182, + 2707, + 2675, + 1958, + 6177, + UNUSED, + -1150, + 0, + UNUSED, + 9528, + UNUSED, + UNUSED, + 2929, + 0, + UNUSED, + 1284, + -352, + UNUSED, + 1586, + 1827, + UNUSED, + 7548, + UNUSED, + UNUSED, + UNUSED, + 919, + 9180, + UNUSED, + -41, + UNUSED, + 96, + 0, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1985, + 13335, + 0, + 8505, + 2542, + 11482, + 116, + 1558, + UNUSED, + -651, + 2274, + 0, + 1333, + 2475, + 7865, + 0, + 0, + 1801, + UNUSED, + UNUSED, + UNUSED, + 72, + 3728, + 0, + 1457, + UNUSED, + UNUSED, + 912, + 0, + 7834, + 483, + UNUSED, + UNUSED, + 7309, + -341, + -17, + 2163, + UNUSED, + 878, + 1891, + 1398, + UNUSED, + 1354, + 1119, + UNUSED, + 1390, + 1697, + UNUSED, + UNUSED, + UNUSED, + 3493, + -746, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 126, + 1006, + 6742, + UNUSED, + UNUSED, + 639, + 511, + 7505, + 1796, + 113, + UNUSED, + 1072, + 66, + UNUSED, + 1973, + 246, + -205, + 0, + 904, + 1409, + -17, + 8301, + 6456, + 0, + -147, + 853, + 12095, + UNUSED, + -940, + 2348, + 3089, + UNUSED, + 2199, + 7562, + UNUSED, + 3938, + 1920, + 1147, + UNUSED, + 640, + 0, + 2477, + 629, + 801, + 868, + UNUSED, + 0, + 0, + 1254, + UNUSED, + 2965, + UNUSED, + 3069, + UNUSED, + 1407, + 955, + UNUSED, + UNUSED, + 2360, + 9304, + 403, + 984, + 4876, + 772, + UNUSED, + -891, + -231, + 594, + 4740, + 0, + UNUSED, + 7446, + UNUSED, + 127, + UNUSED, + -268, + 1848, + 758, + UNUSED, + -1346, + 1017, + -273, + 1281, + UNUSED, + 7111, + 4709, + 3475, + -565, + UNUSED, + 1014, + 3456, + 1402, + -347, + 1959, + 1035, + UNUSED, + 1574, + 684, + 2593, + UNUSED, + 314, + 1155, + 655, + UNUSED, + 1067, + 1179, + UNUSED, + -997, + UNUSED, + UNUSED, + 7712, + -681, + 1611, + 480, + UNUSED, + UNUSED, + 879, + UNUSED, + UNUSED, + UNUSED, + 5754, + 2981, + 6924, + 367, + 2125, + UNUSED, + 2342, + 14, + UNUSED, + UNUSED, + 7267, + 154, + 0, + UNUSED, + -1536, + UNUSED, + 0, + UNUSED, + 1552, + 683, + 6505, + UNUSED, + -718, + UNUSED, + 1393, + UNUSED, + -430, + 1172, + UNUSED, + 8590, + 9062, + 2024, + UNUSED, + UNUSED, + -1983, + UNUSED, + UNUSED, + 1395, + -2243, + -1014, + 7955, + 7535, + 220, + UNUSED, + UNUSED, + -387, + 1503, + 1602, + 259, + 0, + 6689, + -600, + 1403, + -3, + 4919, + 1937, + 6152, + 107, + UNUSED, + UNUSED, + 1057, + 0, + 5113, + UNUSED, + 1485, + 5817, + 841, + 248, + 6444, + 949, + 787, + 2418, + UNUSED, + UNUSED, + 799, + UNUSED, + UNUSED, + UNUSED, + 3080, + 6397, + 10984, + UNUSED, + 7528, + 1665, + UNUSED, + UNUSED, + 1798, + 1040, + UNUSED, + UNUSED, + 1960, + UNUSED, + 5031, + -2878, + 11694, + UNUSED, + 956, + -542, + UNUSED, + UNUSED, + 630, + 12284, + 11750, + 533, + 1929, + 5238, + 371, + UNUSED, + 0, + 6606, + 2052, + -1123, + 669, + -119, + 785, + -1307, + 1730, + 8933, + -2247, + 1550, + UNUSED, + UNUSED, + 2441, + -24, + UNUSED, + UNUSED, + UNUSED, + 680, + 9786, + 0, + 1600, + UNUSED, + UNUSED, + 1874, + 386, + UNUSED, + 1338, + 2826, + 6201, + 1356, + 713, + -332, + 1247, + UNUSED, + 1302, + 7395, + 264, + UNUSED, + UNUSED, + 1717, + UNUSED, + -596, + UNUSED, + -837, + 663, + 847, + UNUSED, + UNUSED, + 2703, + 2269, + 112, + 374, + 1037, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -668, + 8611, + UNUSED, + 3403, + 634, + -1489, + UNUSED, + 6527, + 4826, + UNUSED, + UNUSED, + 0, + 0, + 559, + 515, + UNUSED, + UNUSED, + UNUSED, + 5141, + 2500, + 6982, + 0, + UNUSED, + -157, + UNUSED, + UNUSED, + 8217, + UNUSED, + -1, + UNUSED, + -226, + -772, + 7632, + 2240, + 11105, + 1776, + 322, + UNUSED, + 1352, + 655, + UNUSED, + UNUSED, + 3338, + UNUSED, + UNUSED, + 5685, + UNUSED, + 1650, + 185, + 668, + 1947, + 556, + 4864, + 2709, + UNUSED, + 1977, + UNUSED, + 1216, + -3725, + UNUSED, + 6353, + -129, + UNUSED, + 1772, + 8389, + UNUSED, + UNUSED, + 6694, + UNUSED, + 2058, + 2142, + -1372, + UNUSED, + UNUSED, + 1745, + 1608, + 231, + 98, + 7390, + UNUSED, + 8277, + UNUSED, + 203, + 804, + 118, + 5072, + 1153, + UNUSED, + 457, + 2017, + UNUSED, + UNUSED, + UNUSED, + -5, + 865, + 2065, + 657, + UNUSED, + UNUSED, + UNUSED, + 5049, + UNUSED, + 11665, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 1896, + 1651, + 739, + 446, + UNUSED, + 1994, + 1604, + UNUSED, + 1806, + 4885, + 97, + 7841, + 1759, + UNUSED, + 1511, + 224, + -1615, + UNUSED, + UNUSED, + 21, + 2209, + 1637, + 6706, + UNUSED, + 2249, + 190, + -920, + 8047, + 0, + 1062, + 432, + 1919, + UNUSED, + UNUSED, + UNUSED, + 0, + -868, + 2045, + UNUSED, + 8578, + UNUSED, + 1561, + UNUSED, + -275, + UNUSED, + 1629, + UNUSED, + 195, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1671, + 2188, + 9893, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 9388, + 7203, + 22, + 7620, + 6299, + 420, + UNUSED, + 3461, + 1106, + 1557, + -3377, + 6661, + 52, + 968, + UNUSED, + 506, + 0, + 1316, + 697, + 1512, + 1037, + 423, + UNUSED, + -1518, + UNUSED, + 149, + 0, + UNUSED, + 290, + 8157, + 1742, + 1446, + UNUSED, + UNUSED, + 8473, + 981, + 364, + 4394, + 682, + UNUSED, + 1937, + UNUSED, + 9972, + 7123, + UNUSED, + -849, + 1108, + UNUSED, + UNUSED, + 9046, + 925, + -982, + -880, + 2234, + 1105, + 1546, + 9521, + 47, + UNUSED, + UNUSED, + 32, + 408, + 1365, + 1003, + -267, + 1147, + 1549, + 2127, + -3612, + UNUSED, + UNUSED, + 555, + 956, + 2132, + 11038, + UNUSED, + UNUSED, + -1137, + 1447, + UNUSED, + -433, + UNUSED, + UNUSED, + -568, + 642, + 8653, + -2549, + 2793, + 2407, + -665, + -787, + -140, + UNUSED, + 971, + 1137, + UNUSED, + UNUSED, + 5948, + 0, + 1670, + 26, + 3613, + 2298, + UNUSED, + 12230, + 389, + UNUSED, + 1267, + UNUSED, + -457, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 8768, + UNUSED, + UNUSED, + 1128, + -429, + 3933, + 843, + 1005, + 1710, + -1204, + -296, + UNUSED, + 883, + -1086, + UNUSED, + 877, + 1562, + 6529, + UNUSED, + 1045, + UNUSED, + UNUSED, + 7728, + 2028, + -297, + 8244, + UNUSED, + 1110, + 4681, + 384, + 5945, + 3103, + 7121, + 1124, + 366, + 7864, + UNUSED, + 1885, + 9532, + UNUSED, + 3755, + 1338, + UNUSED, + UNUSED, + UNUSED, + 3689, + -1207, + UNUSED, + 2049, + UNUSED, + 1025, + 266, + -602, + -18, + 3762, + UNUSED, + 778, + UNUSED, + UNUSED, + 1418, + UNUSED, + 1264, + 7271, + UNUSED, + UNUSED, + 8327, + UNUSED, + 960, + 1315, + UNUSED, + 2587, + UNUSED, + UNUSED, + 9821, + 4548, + 306, + 3107, + 2087, + UNUSED, + -11, + UNUSED, + 1611, + 12415, + 1437, + 774, + 347, + 2954, + 1106, + 1149, + 0, + UNUSED, + 1098, + 1212, + 8060, + 1904, + -706, + UNUSED, + UNUSED, + UNUSED, + 1782, + 2059, + UNUSED, + UNUSED, + 541, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -685, + UNUSED, + 1109, + UNUSED, + 262, + UNUSED, + UNUSED, + 1757, + UNUSED, + -2494, + 533, + 535, + 2894, + 1001, + UNUSED, + UNUSED, + 1691, + UNUSED, + 1865, + 1946, + 588, + 4338, + 1510, + 572, + UNUSED, + -3601, + 6938, + 1294, + 1762, + }; + static const int16_t hash2[2048] = { + UNUSED, + UNUSED, + -4377, + UNUSED, + 0, + 0, + UNUSED, + UNUSED, + 0, + 1428, + -984, + 0, + UNUSED, + UNUSED, + 0, + 0, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + -9771, + -9272, + 0, + 2037, + UNUSED, + 0, + -2371, + UNUSED, + UNUSED, + 0, + -7594, + 0, + UNUSED, + UNUSED, + -2667, + UNUSED, + -8814, + -6297, + 0, + 0, + -1740, + UNUSED, + UNUSED, + 23, + 0, + 0, + -403, + 0, + 0, + 0, + UNUSED, + 4801, + -6828, + -4752, + 0, + 926, + 0, + UNUSED, + 0, + 0, + 0, + 2680, + -5470, + UNUSED, + UNUSED, + -5655, + -10620, + 0, + 0, + 0, + 0, + UNUSED, + 996, + UNUSED, + 0, + 42, + 0, + 77, + 507, + 0, + 65, + -4354, + UNUSED, + UNUSED, + 509, + 0, + 0, + UNUSED, + 1729, + -4602, + 644, + 2638, + UNUSED, + -66, + 585, + 0, + 1562, + 0, + 0, + UNUSED, + -6266, + UNUSED, + UNUSED, + UNUSED, + 1572, + 0, + -187, + 999, + 0, + -5426, + -1288, + -9838, + 0, + 0, + 0, + -187, + UNUSED, + UNUSED, + 0, + UNUSED, + -1285, + 3658, + UNUSED, + 1283, + UNUSED, + 784, + UNUSED, + 2563, + 0, + -6284, + -810, + UNUSED, + -2974, + 0, + UNUSED, + 1209, + -10376, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + 0, + UNUSED, + 0, + -5950, + UNUSED, + 1133, + UNUSED, + -210, + -4481, + 0, + UNUSED, + 0, + UNUSED, + -2235, + -770, + -2103, + UNUSED, + -4451, + 0, + 0, + 0, + UNUSED, + 427, + 0, + 1553, + 0, + 0, + 1280, + 0, + UNUSED, + UNUSED, + 25, + UNUSED, + 179, + UNUSED, + UNUSED, + 2149, + UNUSED, + -500, + 0, + 1274, + 0, + 0, + UNUSED, + UNUSED, + -5179, + 0, + 1175, + 0, + UNUSED, + UNUSED, + UNUSED, + 0, + 0, + 0, + 0, + UNUSED, + UNUSED, + UNUSED, + -6758, + UNUSED, + UNUSED, + UNUSED, + 0, + 0, + 0, + 361, + 0, + UNUSED, + 0, + UNUSED, + -22, + -1382, + UNUSED, + UNUSED, + UNUSED, + 0, + -576, + -6812, + -4205, + UNUSED, + 0, + UNUSED, + 0, + -41, + UNUSED, + 0, + UNUSED, + -6077, + 0, + -1533, + 0, + -281, + 0, + 207, + 1037, + -7053, + -7326, + -6741, + UNUSED, + 0, + UNUSED, + UNUSED, + -625, + UNUSED, + 0, + -1691, + -5804, + -616, + -1289, + UNUSED, + -2095, + 1940, + UNUSED, + UNUSED, + UNUSED, + -1834, + -7248, + 0, + 0, + 0, + 219, + UNUSED, + 0, + 2508, + UNUSED, + UNUSED, + 0, + -1400, + 1204, + -5650, + 0, + -4881, + UNUSED, + -1761, + 0, + -7262, + UNUSED, + 1884, + 2516, + 80, + UNUSED, + UNUSED, + -931, + UNUSED, + -573, + 0, + UNUSED, + 0, + 221, + -4740, + -6670, + -4705, + UNUSED, + -4916, + 0, + 762, + UNUSED, + -6130, + 1034, + UNUSED, + 962, + -9557, + -1243, + UNUSED, + 3100, + 0, + 0, + UNUSED, + -6326, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -689, + UNUSED, + 376, + 0, + 2271, + -8653, + 410, + 0, + -489, + UNUSED, + 2895, + -6509, + UNUSED, + 0, + 146, + 4151, + -3215, + UNUSED, + 1406, + UNUSED, + 890, + 1516, + UNUSED, + UNUSED, + 0, + -3337, + 0, + -199, + UNUSED, + 0, + 831, + -5649, + UNUSED, + 0, + UNUSED, + 0, + UNUSED, + 0, + 1362, + 403, + 0, + 0, + -11142, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 0, + 0, + 0, + 142, + 0, + UNUSED, + -3679, + -1148, + UNUSED, + UNUSED, + 0, + 2044, + -552, + -985, + UNUSED, + 0, + UNUSED, + -6944, + 0, + UNUSED, + 7, + 0, + UNUSED, + -1709, + UNUSED, + 1694, + 0, + UNUSED, + 0, + 758, + UNUSED, + 0, + UNUSED, + 129, + UNUSED, + 1136, + -5188, + UNUSED, + -5809, + -5311, + 0, + 2209, + UNUSED, + 0, + 596, + UNUSED, + 2808, + 2232, + UNUSED, + 810, + 0, + 1656, + 1050, + -829, + 0, + UNUSED, + -7634, + UNUSED, + 1575, + UNUSED, + -9354, + 1402, + 792, + 0, + 2611, + -951, + UNUSED, + 852, + UNUSED, + 813, + 0, + 1845, + UNUSED, + UNUSED, + 0, + 1567, + 0, + 1529, + 1776, + 1330, + -797, + 311, + 790, + 769, + -2517, + 66, + UNUSED, + -2199, + 1941, + UNUSED, + 0, + UNUSED, + UNUSED, + 0, + 2250, + -6547, + 0, + -8407, + UNUSED, + 1077, + 742, + UNUSED, + 0, + 887, + 0, + 490, + UNUSED, + 0, + 2117, + UNUSED, + -767, + 2971, + 0, + -3407, + UNUSED, + 2218, + -5692, + 0, + UNUSED, + -1525, + UNUSED, + -2895, + 0, + UNUSED, + 1312, + UNUSED, + -1422, + 527, + 2021, + 0, + -129, + UNUSED, + UNUSED, + 0, + 949, + -3158, + UNUSED, + UNUSED, + -166, + -8299, + 0, + UNUSED, + UNUSED, + -6780, + 3151, + UNUSED, + UNUSED, + 1500, + 2046, + 2036, + 1763, + -11061, + 397, + 0, + -12785, + UNUSED, + -2828, + UNUSED, + -2901, + 1796, + -6471, + UNUSED, + UNUSED, + 0, + UNUSED, + 0, + 1148, + -1980, + UNUSED, + 0, + 0, + UNUSED, + 3622, + -8207, + 476, + UNUSED, + UNUSED, + -3977, + -32, + -5096, + UNUSED, + 0, + -5577, + -2318, + 1554, + 649, + UNUSED, + UNUSED, + 438, + -4683, + -14755, + -5922, + 5503, + 1707, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -529, + 3833, + UNUSED, + 232, + UNUSED, + 0, + -9781, + 0, + UNUSED, + -686, + UNUSED, + -678, + 0, + UNUSED, + UNUSED, + -493, + 192, + -7637, + -6627, + UNUSED, + UNUSED, + -1219, + -679, + UNUSED, + -5268, + 0, + 1225, + 0, + 762, + 0, + -687, + UNUSED, + -311, + -140, + UNUSED, + -1262, + 1049, + UNUSED, + 0, + 0, + 0, + UNUSED, + -10, + UNUSED, + 0, + 1773, + UNUSED, + 0, + 0, + -5164, + UNUSED, + 0, + UNUSED, + -5063, + -538, + -5907, + UNUSED, + 481, + UNUSED, + -3573, + UNUSED, + 0, + -511, + -62, + UNUSED, + 0, + -977, + UNUSED, + UNUSED, + 0, + 245, + UNUSED, + -351, + -7710, + UNUSED, + -4030, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -4305, + 1230, + -8829, + 1871, + 0, + UNUSED, + 920, + UNUSED, + UNUSED, + 678, + UNUSED, + UNUSED, + UNUSED, + -1343, + -5277, + UNUSED, + 2080, + -3150, + UNUSED, + -230, + -6413, + UNUSED, + -5861, + UNUSED, + 0, + 1270, + 819, + -4983, + UNUSED, + UNUSED, + UNUSED, + -2564, + -800, + 3242, + 0, + UNUSED, + 0, + -6, + UNUSED, + -2382, + UNUSED, + -5512, + 1328, + 106, + 816, + 2139, + 565, + -647, + 635, + 1718, + 1329, + -1623, + UNUSED, + -5377, + 1823, + -3492, + -7813, + -4718, + 592, + 677, + UNUSED, + UNUSED, + 1146, + UNUSED, + -3392, + 3289, + 1815, + 0, + UNUSED, + -4256, + 0, + 504, + 1232, + 1896, + UNUSED, + 0, + 5367, + 489, + -5174, + -1491, + UNUSED, + 1724, + UNUSED, + 779, + UNUSED, + -8145, + UNUSED, + 0, + -1033, + -8288, + 2141, + UNUSED, + -777, + UNUSED, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 2099, + -435, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -1407, + 0, + UNUSED, + -4032, + -7043, + -10318, + -4, + UNUSED, + 0, + 0, + UNUSED, + 3074, + UNUSED, + -6637, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1847, + -638, + -7323, + UNUSED, + -6445, + 0, + UNUSED, + -410, + 868, + UNUSED, + 2763, + 210, + UNUSED, + 4759, + UNUSED, + UNUSED, + 2394, + 0, + -949, + 441, + 0, + -6406, + -671, + UNUSED, + -4338, + UNUSED, + -1192, + UNUSED, + 0, + -2036, + -7505, + UNUSED, + -425, + 2137, + UNUSED, + 0, + 880, + UNUSED, + UNUSED, + -9732, + 1578, + UNUSED, + -7573, + -10141, + 1935, + -5213, + UNUSED, + -1351, + 0, + -52, + 0, + UNUSED, + UNUSED, + -1538, + UNUSED, + UNUSED, + -7777, + -1046, + -4613, + 153, + -2923, + -530, + UNUSED, + UNUSED, + -8716, + 1663, + 3353, + UNUSED, + -2024, + UNUSED, + UNUSED, + UNUSED, + -7615, + 0, + 1512, + 0, + 1096, + 1851, + UNUSED, + 3941, + UNUSED, + -10749, + UNUSED, + UNUSED, + 960, + -439, + 0, + 0, + -4571, + 1616, + -7723, + -7380, + -1208, + 528, + 0, + -7842, + -1820, + UNUSED, + UNUSED, + -1975, + -8365, + 0, + 1253, + UNUSED, + -8840, + 0, + UNUSED, + UNUSED, + -1534, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + 1481, + UNUSED, + -2954, + UNUSED, + -865, + 923, + 4446, + 1801, + 22, + 2264, + UNUSED, + 306, + 1969, + 0, + 866, + 0, + 400, + UNUSED, + 1515, + -1817, + 1388, + 1926, + UNUSED, + 2104, + 387, + -11977, + 2176, + 1646, + UNUSED, + -9226, + UNUSED, + -8976, + 0, + -1028, + 418, + -298, + 1325, + UNUSED, + UNUSED, + 217, + UNUSED, + UNUSED, + 2150, + 809, + 1096, + 58, + UNUSED, + UNUSED, + 0, + 1157, + UNUSED, + -86, + 855, + -6759, + UNUSED, + 862, + 0, + UNUSED, + UNUSED, + UNUSED, + 194, + 1471, + 1665, + 0, + 856, + UNUSED, + UNUSED, + UNUSED, + -107, + UNUSED, + -6444, + 1999, + -7186, + -8991, + UNUSED, + UNUSED, + 762, + UNUSED, + UNUSED, + 0, + UNUSED, + UNUSED, + 2619, + 826, + 1513, + UNUSED, + UNUSED, + 0, + 1881, + -735, + -5636, + -4643, + UNUSED, + UNUSED, + -1783, + 1468, + UNUSED, + 890, + UNUSED, + -61, + -8629, + 0, + -104, + UNUSED, + 0, + -7562, + 0, + 1346, + 1635, + UNUSED, + UNUSED, + 421, + UNUSED, + -3040, + -357, + 1150, + -1113, + 147, + 990, + 348, + -5049, + 1346, + -7104, + UNUSED, + UNUSED, + UNUSED, + 701, + -6115, + -9265, + 0, + 2777, + -2216, + -4253, + 0, + -6391, + 2483, + 1474, + 0, + 1305, + UNUSED, + UNUSED, + UNUSED, + 2492, + -371, + -7757, + -1472, + UNUSED, + 398, + UNUSED, + 1228, + UNUSED, + -161, + 520, + 936, + UNUSED, + 1738, + 0, + UNUSED, + -4433, + 253, + UNUSED, + -1822, + UNUSED, + 430, + UNUSED, + 1747, + 892, + UNUSED, + UNUSED, + UNUSED, + 556, + UNUSED, + -308, + UNUSED, + UNUSED, + UNUSED, + 275, + UNUSED, + -748, + -6892, + -5911, + UNUSED, + -627, + -7132, + UNUSED, + UNUSED, + 0, + 1066, + 0, + UNUSED, + -10380, + -708, + UNUSED, + UNUSED, + UNUSED, + 1920, + UNUSED, + 1902, + -703, + UNUSED, + UNUSED, + 2496, + UNUSED, + 1782, + UNUSED, + UNUSED, + 0, + 4141, + UNUSED, + 1914, + -4324, + -318, + 1734, + -313, + 0, + 1400, + -7067, + 0, + UNUSED, + 386, + 2040, + 3663, + 2184, + UNUSED, + -2281, + UNUSED, + UNUSED, + UNUSED, + 1462, + 0, + -138, + -221, + UNUSED, + 0, + -3745, + -9862, + -828, + UNUSED, + 4992, + 2055, + 0, + 953, + UNUSED, + -7443, + -579, + 859, + UNUSED, + 0, + 1512, + 0, + -767, + 953, + 1548, + 1034, + 1177, + UNUSED, + -696, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 136, + -610, + -7020, + UNUSED, + UNUSED, + UNUSED, + 29, + -7119, + 260, + 0, + 2577, + UNUSED, + 2187, + UNUSED, + -5556, + -6168, + UNUSED, + 50, + UNUSED, + 1029, + UNUSED, + UNUSED, + 862, + 885, + UNUSED, + -1922, + UNUSED, + 45, + 1953, + UNUSED, + 0, + -2598, + 828, + -974, + 1020, + UNUSED, + 544, + UNUSED, + 100, + 1162, + 0, + UNUSED, + 0, + -4334, + 711, + UNUSED, + UNUSED, + -1498, + 1856, + UNUSED, + -1125, + UNUSED, + -4870, + UNUSED, + -6288, + 648, + 814, + UNUSED, + -739, + 0, + 388, + 117, + -1147, + -3044, + -12076, + UNUSED, + 1682, + 2200, + -4996, + UNUSED, + -4977, + UNUSED, + 0, + UNUSED, + UNUSED, + UNUSED, + -1485, + -6978, + 1742, + 1951, + UNUSED, + -1036, + 1171, + UNUSED, + 801, + UNUSED, + 1960, + -119, + UNUSED, + -1956, + -1894, + 350, + -696, + UNUSED, + 0, + -6481, + 227, + 1720, + 0, + 1712, + 2391, + UNUSED, + UNUSED, + -371, + 0, + 987, + -48, + UNUSED, + 977, + -121, + 1352, + UNUSED, + -103, + -1398, + UNUSED, + 2372, + -3635, + 0, + 299, + -6317, + -4574, + 568, + -283, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1847, + 0, + UNUSED, + 1441, + -354, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1554, + -6179, + 0, + 491, + UNUSED, + -6777, + 877, + UNUSED, + -1874, + 606, + 711, + UNUSED, + 0, + -3385, + UNUSED, + -5925, + UNUSED, + 4810, + UNUSED, + 830, + -2086, + -4620, + UNUSED, + UNUSED, + 193, + -3544, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -6758, + 57, + -14713, + -4531, + -5600, + 1501, + -1287, + UNUSED, + UNUSED, + UNUSED, + -7264, + UNUSED, + UNUSED, + -1668, + -6054, + 2162, + 529, + 1613, + 887, + -8928, + UNUSED, + -5256, + 989, + UNUSED, + -1339, + 2052, + UNUSED, + 568, + 4806, + 0, + -1546, + UNUSED, + UNUSED, + UNUSED, + 395, + UNUSED, + 1869, + 5355, + UNUSED, + UNUSED, + -1218, + -6017, + 1576, + -6843, + UNUSED, + -21, + 0, + UNUSED, + UNUSED, + 2051, + UNUSED, + -699, + 1841, + -2940, + -6413, + 1597, + 1949, + 887, + 269, + UNUSED, + 2230, + 1291, + UNUSED, + -253, + 637, + UNUSED, + -6458, + 557, + -12385, + -6125, + -5021, + -5026, + 1826, + UNUSED, + UNUSED, + -7232, + -1614, + -2257, + 1895, + UNUSED, + UNUSED, + 2215, + 824, + 752, + -297, + 4756, + 836, + 972, + UNUSED, + -5552, + -1267, + UNUSED, + 396, + UNUSED, + UNUSED, + 2248, + 1695, + 2228, + 1960, + UNUSED, + 0, + UNUSED, + 0, + 187, + 321, + 303, + 1524, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1540, + 375, + UNUSED, + 1952, + 1642, + UNUSED, + -4746, + 800, + 2776, + 3123, + 2209, + -5751, + 346, + 199, + -3182, + 2119, + UNUSED, + 944, + 258, + 0, + -238, + -5240, + 1874, + 1814, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1173, + UNUSED, + -2123, + 1364, + 560, + -3764, + 837, + 1540, + 989, + UNUSED, + 393, + 1584, + -5563, + -5645, + 1336, + -680, + -990, + UNUSED, + UNUSED, + -606, + 480, + 1335, + 111, + -994, + 0, + UNUSED, + 3541, + UNUSED, + 132, + UNUSED, + -9303, + 390, + -6033, + 1945, + UNUSED, + -5182, + 0, + UNUSED, + 1974, + 2101, + UNUSED, + 483, + 265, + -9193, + 592, + UNUSED, + UNUSED, + -6411, + 415, + 909, + 2207, + 202, + 1569, + UNUSED, + 382, + UNUSED, + 0, + UNUSED, + UNUSED, + -8097, + UNUSED, + 0, + -227, + 482, + 2027, + UNUSED, + -160, + 592, + -559, + 464, + -4773, + 965, + 986, + -6729, + UNUSED, + 2163, + -1302, + 559, + 790, + UNUSED, + UNUSED, + -534, + UNUSED, + 952, + 1506, + UNUSED, + 616, + -9957, + UNUSED, + 60, + 161, + 1771, + UNUSED, + UNUSED, + 48, + -1134, + -254, + -712, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -699, + -8494, + 48, + -8271, + UNUSED, + UNUSED, + 1581, + UNUSED, + -1899, + UNUSED, + 1456, + -8000, + UNUSED, + 1529, + 651, + -1000, + 841, + -6453, + -4226, + -1508, + 1842, + UNUSED, + 2067, + -746, + 87, + -601, + 1258, + UNUSED, + UNUSED, + UNUSED, + 711, + -4573, + 280, + -5696, + UNUSED, + -6034, + 1817, + 0, + UNUSED, + 704, + 3119, + -4576, + 2221, + 4182, + 246, + -5038, + UNUSED, + UNUSED, + 554, + UNUSED, + 569, + 911, + UNUSED, + 613, + UNUSED, + UNUSED, + -4541, + -476, + -9963, + 997, + 124, + UNUSED, + 456, + 2133, + 120, + 1993, + -10933, + -129, + UNUSED, + 556, + UNUSED, + -8660, + 1093, + -6113, + 2777, + -19, + -5284, + UNUSED, + UNUSED, + 930, + 825, + -18, + -6603, + -10011, + 882, + 1018, + -6595, + UNUSED, + -7398, + 0, + UNUSED, + UNUSED, + UNUSED, + -1091, + 250, + -1616, + 845, + -8205, + 2200, + -8440, + -130, + UNUSED, + -5529, + UNUSED, + 43, + UNUSED, + -1958, + UNUSED, + -10917, + -7339, + UNUSED, + 1875, + 1586, + UNUSED, + -265, + -5545, + 10, + 432, + -78, + -11393, + 789, + UNUSED, + -7487, + -1303, + UNUSED, + UNUSED, + -4639, + 144, + -12097, + 206, + UNUSED, + UNUSED, + UNUSED, + 4219, + 458, + 0, + -3071, + UNUSED, + UNUSED, + -7365, + 1382, + -918, + -2140, + -771, + 0, + -193, + 103, + -331, + 0, + UNUSED, + -8161, + 633, + -11042, + -149, + 2173, + 3043, + -3034, + -4154, + -6214, + -1121, + UNUSED, + 1807, + 1825, + 94, + UNUSED, + -293, + UNUSED, + 497, + UNUSED, + 532, + 1396, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1555, + 40, + -5538, + 1355, + 0, + UNUSED, + 771, + 692, + -7163, + 2122, + -1534, + 395, + UNUSED, + 1334, + 1736, + UNUSED, + UNUSED, + 754, + 247, + 1344, + -13, + UNUSED, + 1372, + UNUSED, + -428, + 2159, + UNUSED, + UNUSED, + -1074, + 5383, + 1095, + 226, + UNUSED, + -1055, + UNUSED, + 0, + UNUSED, + 1413, + 873, + 83, + -468, + 2070, + UNUSED, + -1995, + 1715, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1303, + 53, + UNUSED, + -6009, + 486, + 512, + -10194, + UNUSED, + -2082, + UNUSED, + UNUSED, + -764, + 3208, + UNUSED, + UNUSED, + -7179, + 50, + 2025, + 733, + 319, + -208, + UNUSED, + 242, + 1304, + UNUSED, + -2188, + UNUSED, + UNUSED, + 664, + UNUSED, + UNUSED, + UNUSED, + 1907, + 2083, + 1354, + UNUSED, + UNUSED, + -278, + 1629, + UNUSED, + 1630, + -5126, + UNUSED, + UNUSED, + 175, + 443, + 254, + UNUSED, + UNUSED, + UNUSED, + 1777, + -558, + UNUSED, + 764, + UNUSED, + 1242, + -2798, + 1554, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + -4652, + 1790, + 616, + 3969, + -3305, + 876, + UNUSED, + -4718, + 1046, + UNUSED, + 2120, + -1760, + -5600, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 1407, + 1267, + 1460, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + UNUSED, + 625, + 1982, + 715, + -678, + UNUSED, + 905, + -5605, + 1978, + 478, + -2454, + 941, + 0, + UNUSED, + UNUSED, + UNUSED, + 1454, + 1511, + 1134, + -435, + 1570, + UNUSED, + 529, + 715, + -1981, + UNUSED, + UNUSED, + 1690, + 2107, + UNUSED, + -4814, + -1673, + 2238, + 1706, + UNUSED, + 356, + 2064, + -4497, + -6650, + -628, + 10, + -1111, + UNUSED, + -8057, + -6255, + -103, + UNUSED, + 1434, + 553, + 360, + 1167, + 908, + 839, + 1859, + 546, + 1499, + UNUSED, + -5594, + 1266, + 1364, + -6742, + 410, + UNUSED, + -7282, + UNUSED, + UNUSED, + -1940, + 1480, + 2430, + 1212, + 1957, + 1898, + UNUSED, + 1337, + UNUSED, + UNUSED, + 1813, + UNUSED, + 1163, + 888, + 805, + UNUSED, + UNUSED, + -9007, + -1004, + 484, + -6314, + 644, + UNUSED, + 1458, + 529, + 2684, + 323, + UNUSED, + 68, + 1019, + 415, + 35, + -3864, + -1538, + UNUSED, + 1017, + UNUSED, + 773, + 1122, + 2326, + UNUSED, + -1477, + -8611, + UNUSED, + 3167, + UNUSED, + UNUSED, + UNUSED, + 294, + 1135, + -7098, + 2135, + 257, + UNUSED, + -1217, + -6172, + UNUSED, + 801, + 1227, + -6893, + -8186, + UNUSED, + 1585, + 2005, + 1955, + -1886, + -209, + UNUSED, + UNUSED, + 453, + UNUSED, + -853, + 2176, + 1596, + 829, + -792, + -10623, + -5255, + 637, + UNUSED, + 803, + UNUSED, + 1343, + 820, + -5964, + -39, + UNUSED, + UNUSED, + -9029, + 211, + -8104, + 407, + UNUSED, + 1038, + 1658, + 102, + UNUSED, + UNUSED, + 137, + -9562, + UNUSED, + 1894, + -2483, + 1820, + 1059, + 921, + UNUSED, + -4361, + UNUSED, + }; + static const struct tokendata tokendata[2283] = { + { "db", TOKEN_INSN, C_none, 0, I_DB }, + { "dw", TOKEN_INSN, C_none, 0, I_DW }, + { "dd", TOKEN_INSN, C_none, 0, I_DD }, + { "dq", TOKEN_INSN, C_none, 0, I_DQ }, + { "dt", TOKEN_INSN, C_none, 0, I_DT }, + { "do", TOKEN_INSN, C_none, 0, I_DO }, + { "dy", TOKEN_INSN, C_none, 0, I_DY }, + { "dz", TOKEN_INSN, C_none, 0, I_DZ }, + { "resb", TOKEN_INSN, C_none, 0, I_RESB }, + { "resw", TOKEN_INSN, C_none, 0, I_RESW }, + { "resd", TOKEN_INSN, C_none, 0, I_RESD }, + { "resq", TOKEN_INSN, C_none, 0, I_RESQ }, + { "rest", TOKEN_INSN, C_none, 0, I_REST }, + { "reso", TOKEN_INSN, C_none, 0, I_RESO }, + { "resy", TOKEN_INSN, C_none, 0, I_RESY }, + { "resz", TOKEN_INSN, C_none, 0, I_RESZ }, + { "incbin", TOKEN_INSN, C_none, 0, I_INCBIN }, + { "aaa", TOKEN_INSN, C_none, 0, I_AAA }, + { "aad", TOKEN_INSN, C_none, 0, I_AAD }, + { "aam", TOKEN_INSN, C_none, 0, I_AAM }, + { "aas", TOKEN_INSN, C_none, 0, I_AAS }, + { "adc", TOKEN_INSN, C_none, 0, I_ADC }, + { "add", TOKEN_INSN, C_none, 0, I_ADD }, + { "and", TOKEN_INSN, C_none, 0, I_AND }, + { "arpl", TOKEN_INSN, C_none, 0, I_ARPL }, + { "bb0_reset", TOKEN_INSN, C_none, 0, I_BB0_RESET }, + { "bb1_reset", TOKEN_INSN, C_none, 0, I_BB1_RESET }, + { "bound", TOKEN_INSN, C_none, 0, I_BOUND }, + { "bsf", TOKEN_INSN, C_none, 0, I_BSF }, + { "bsr", TOKEN_INSN, C_none, 0, I_BSR }, + { "bswap", TOKEN_INSN, C_none, 0, I_BSWAP }, + { "bt", TOKEN_INSN, C_none, 0, I_BT }, + { "btc", TOKEN_INSN, C_none, 0, I_BTC }, + { "btr", TOKEN_INSN, C_none, 0, I_BTR }, + { "bts", TOKEN_INSN, C_none, 0, I_BTS }, + { "call", TOKEN_INSN, C_none, 0, I_CALL }, + { "cbw", TOKEN_INSN, C_none, 0, I_CBW }, + { "cdq", TOKEN_INSN, C_none, 0, I_CDQ }, + { "cdqe", TOKEN_INSN, C_none, 0, I_CDQE }, + { "clc", TOKEN_INSN, C_none, 0, I_CLC }, + { "cld", TOKEN_INSN, C_none, 0, I_CLD }, + { "cli", TOKEN_INSN, C_none, 0, I_CLI }, + { "clts", TOKEN_INSN, C_none, 0, I_CLTS }, + { "cmc", TOKEN_INSN, C_none, 0, I_CMC }, + { "cmp", TOKEN_INSN, C_none, 0, I_CMP }, + { "cmpsb", TOKEN_INSN, C_none, 0, I_CMPSB }, + { "cmpsd", TOKEN_INSN, C_none, 0, I_CMPSD }, + { "cmpsq", TOKEN_INSN, C_none, 0, I_CMPSQ }, + { "cmpsw", TOKEN_INSN, C_none, 0, I_CMPSW }, + { "cmpxchg", TOKEN_INSN, C_none, 0, I_CMPXCHG }, + { "cmpxchg486", TOKEN_INSN, C_none, 0, I_CMPXCHG486 }, + { "cmpxchg8b", TOKEN_INSN, C_none, 0, I_CMPXCHG8B }, + { "cmpxchg16b", TOKEN_INSN, C_none, 0, I_CMPXCHG16B }, + { "cpuid", TOKEN_INSN, C_none, 0, I_CPUID }, + { "cpu_read", TOKEN_INSN, C_none, 0, I_CPU_READ }, + { "cpu_write", TOKEN_INSN, C_none, 0, I_CPU_WRITE }, + { "cqo", TOKEN_INSN, C_none, 0, I_CQO }, + { "cwd", TOKEN_INSN, C_none, 0, I_CWD }, + { "cwde", TOKEN_INSN, C_none, 0, I_CWDE }, + { "daa", TOKEN_INSN, C_none, 0, I_DAA }, + { "das", TOKEN_INSN, C_none, 0, I_DAS }, + { "dec", TOKEN_INSN, C_none, 0, I_DEC }, + { "div", TOKEN_INSN, C_none, 0, I_DIV }, + { "dmint", TOKEN_INSN, C_none, 0, I_DMINT }, + { "emms", TOKEN_INSN, C_none, 0, I_EMMS }, + { "enter", TOKEN_INSN, C_none, 0, I_ENTER }, + { "equ", TOKEN_INSN, C_none, 0, I_EQU }, + { "f2xm1", TOKEN_INSN, C_none, 0, I_F2XM1 }, + { "fabs", TOKEN_INSN, C_none, 0, I_FABS }, + { "fadd", TOKEN_INSN, C_none, 0, I_FADD }, + { "faddp", TOKEN_INSN, C_none, 0, I_FADDP }, + { "fbld", TOKEN_INSN, C_none, 0, I_FBLD }, + { "fbstp", TOKEN_INSN, C_none, 0, I_FBSTP }, + { "fchs", TOKEN_INSN, C_none, 0, I_FCHS }, + { "fclex", TOKEN_INSN, C_none, 0, I_FCLEX }, + { "fcmovb", TOKEN_INSN, C_none, 0, I_FCMOVB }, + { "fcmovbe", TOKEN_INSN, C_none, 0, I_FCMOVBE }, + { "fcmove", TOKEN_INSN, C_none, 0, I_FCMOVE }, + { "fcmovnb", TOKEN_INSN, C_none, 0, I_FCMOVNB }, + { "fcmovnbe", TOKEN_INSN, C_none, 0, I_FCMOVNBE }, + { "fcmovne", TOKEN_INSN, C_none, 0, I_FCMOVNE }, + { "fcmovnu", TOKEN_INSN, C_none, 0, I_FCMOVNU }, + { "fcmovu", TOKEN_INSN, C_none, 0, I_FCMOVU }, + { "fcom", TOKEN_INSN, C_none, 0, I_FCOM }, + { "fcomi", TOKEN_INSN, C_none, 0, I_FCOMI }, + { "fcomip", TOKEN_INSN, C_none, 0, I_FCOMIP }, + { "fcomp", TOKEN_INSN, C_none, 0, I_FCOMP }, + { "fcompp", TOKEN_INSN, C_none, 0, I_FCOMPP }, + { "fcos", TOKEN_INSN, C_none, 0, I_FCOS }, + { "fdecstp", TOKEN_INSN, C_none, 0, I_FDECSTP }, + { "fdisi", TOKEN_INSN, C_none, 0, I_FDISI }, + { "fdiv", TOKEN_INSN, C_none, 0, I_FDIV }, + { "fdivp", TOKEN_INSN, C_none, 0, I_FDIVP }, + { "fdivr", TOKEN_INSN, C_none, 0, I_FDIVR }, + { "fdivrp", TOKEN_INSN, C_none, 0, I_FDIVRP }, + { "femms", TOKEN_INSN, C_none, 0, I_FEMMS }, + { "feni", TOKEN_INSN, C_none, 0, I_FENI }, + { "ffree", TOKEN_INSN, C_none, 0, I_FFREE }, + { "ffreep", TOKEN_INSN, C_none, 0, I_FFREEP }, + { "fiadd", TOKEN_INSN, C_none, 0, I_FIADD }, + { "ficom", TOKEN_INSN, C_none, 0, I_FICOM }, + { "ficomp", TOKEN_INSN, C_none, 0, I_FICOMP }, + { "fidiv", TOKEN_INSN, C_none, 0, I_FIDIV }, + { "fidivr", TOKEN_INSN, C_none, 0, I_FIDIVR }, + { "fild", TOKEN_INSN, C_none, 0, I_FILD }, + { "fimul", TOKEN_INSN, C_none, 0, I_FIMUL }, + { "fincstp", TOKEN_INSN, C_none, 0, I_FINCSTP }, + { "finit", TOKEN_INSN, C_none, 0, I_FINIT }, + { "fist", TOKEN_INSN, C_none, 0, I_FIST }, + { "fistp", TOKEN_INSN, C_none, 0, I_FISTP }, + { "fisttp", TOKEN_INSN, C_none, 0, I_FISTTP }, + { "fisub", TOKEN_INSN, C_none, 0, I_FISUB }, + { "fisubr", TOKEN_INSN, C_none, 0, I_FISUBR }, + { "fld", TOKEN_INSN, C_none, 0, I_FLD }, + { "fld1", TOKEN_INSN, C_none, 0, I_FLD1 }, + { "fldcw", TOKEN_INSN, C_none, 0, I_FLDCW }, + { "fldenv", TOKEN_INSN, C_none, 0, I_FLDENV }, + { "fldl2e", TOKEN_INSN, C_none, 0, I_FLDL2E }, + { "fldl2t", TOKEN_INSN, C_none, 0, I_FLDL2T }, + { "fldlg2", TOKEN_INSN, C_none, 0, I_FLDLG2 }, + { "fldln2", TOKEN_INSN, C_none, 0, I_FLDLN2 }, + { "fldpi", TOKEN_INSN, C_none, 0, I_FLDPI }, + { "fldz", TOKEN_INSN, C_none, 0, I_FLDZ }, + { "fmul", TOKEN_INSN, C_none, 0, I_FMUL }, + { "fmulp", TOKEN_INSN, C_none, 0, I_FMULP }, + { "fnclex", TOKEN_INSN, C_none, 0, I_FNCLEX }, + { "fndisi", TOKEN_INSN, C_none, 0, I_FNDISI }, + { "fneni", TOKEN_INSN, C_none, 0, I_FNENI }, + { "fninit", TOKEN_INSN, C_none, 0, I_FNINIT }, + { "fnop", TOKEN_INSN, C_none, 0, I_FNOP }, + { "fnsave", TOKEN_INSN, C_none, 0, I_FNSAVE }, + { "fnstcw", TOKEN_INSN, C_none, 0, I_FNSTCW }, + { "fnstenv", TOKEN_INSN, C_none, 0, I_FNSTENV }, + { "fnstsw", TOKEN_INSN, C_none, 0, I_FNSTSW }, + { "fpatan", TOKEN_INSN, C_none, 0, I_FPATAN }, + { "fprem", TOKEN_INSN, C_none, 0, I_FPREM }, + { "fprem1", TOKEN_INSN, C_none, 0, I_FPREM1 }, + { "fptan", TOKEN_INSN, C_none, 0, I_FPTAN }, + { "frndint", TOKEN_INSN, C_none, 0, I_FRNDINT }, + { "frstor", TOKEN_INSN, C_none, 0, I_FRSTOR }, + { "fsave", TOKEN_INSN, C_none, 0, I_FSAVE }, + { "fscale", TOKEN_INSN, C_none, 0, I_FSCALE }, + { "fsetpm", TOKEN_INSN, C_none, 0, I_FSETPM }, + { "fsin", TOKEN_INSN, C_none, 0, I_FSIN }, + { "fsincos", TOKEN_INSN, C_none, 0, I_FSINCOS }, + { "fsqrt", TOKEN_INSN, C_none, 0, I_FSQRT }, + { "fst", TOKEN_INSN, C_none, 0, I_FST }, + { "fstcw", TOKEN_INSN, C_none, 0, I_FSTCW }, + { "fstenv", TOKEN_INSN, C_none, 0, I_FSTENV }, + { "fstp", TOKEN_INSN, C_none, 0, I_FSTP }, + { "fstsw", TOKEN_INSN, C_none, 0, I_FSTSW }, + { "fsub", TOKEN_INSN, C_none, 0, I_FSUB }, + { "fsubp", TOKEN_INSN, C_none, 0, I_FSUBP }, + { "fsubr", TOKEN_INSN, C_none, 0, I_FSUBR }, + { "fsubrp", TOKEN_INSN, C_none, 0, I_FSUBRP }, + { "ftst", TOKEN_INSN, C_none, 0, I_FTST }, + { "fucom", TOKEN_INSN, C_none, 0, I_FUCOM }, + { "fucomi", TOKEN_INSN, C_none, 0, I_FUCOMI }, + { "fucomip", TOKEN_INSN, C_none, 0, I_FUCOMIP }, + { "fucomp", TOKEN_INSN, C_none, 0, I_FUCOMP }, + { "fucompp", TOKEN_INSN, C_none, 0, I_FUCOMPP }, + { "fxam", TOKEN_INSN, C_none, 0, I_FXAM }, + { "fxch", TOKEN_INSN, C_none, 0, I_FXCH }, + { "fxtract", TOKEN_INSN, C_none, 0, I_FXTRACT }, + { "fyl2x", TOKEN_INSN, C_none, 0, I_FYL2X }, + { "fyl2xp1", TOKEN_INSN, C_none, 0, I_FYL2XP1 }, + { "hlt", TOKEN_INSN, C_none, 0, I_HLT }, + { "ibts", TOKEN_INSN, C_none, 0, I_IBTS }, + { "icebp", TOKEN_INSN, C_none, 0, I_ICEBP }, + { "idiv", TOKEN_INSN, C_none, 0, I_IDIV }, + { "imul", TOKEN_INSN, C_none, 0, I_IMUL }, + { "in", TOKEN_INSN, C_none, 0, I_IN }, + { "inc", TOKEN_INSN, C_none, 0, I_INC }, + { "insb", TOKEN_INSN, C_none, 0, I_INSB }, + { "insd", TOKEN_INSN, C_none, 0, I_INSD }, + { "insw", TOKEN_INSN, C_none, 0, I_INSW }, + { "int", TOKEN_INSN, C_none, 0, I_INT }, + { "int01", TOKEN_INSN, C_none, 0, I_INT01 }, + { "int1", TOKEN_INSN, C_none, 0, I_INT1 }, + { "int03", TOKEN_INSN, C_none, 0, I_INT03 }, + { "int3", TOKEN_INSN, C_none, 0, I_INT3 }, + { "into", TOKEN_INSN, C_none, 0, I_INTO }, + { "invd", TOKEN_INSN, C_none, 0, I_INVD }, + { "invpcid", TOKEN_INSN, C_none, 0, I_INVPCID }, + { "invlpg", TOKEN_INSN, C_none, 0, I_INVLPG }, + { "invlpga", TOKEN_INSN, C_none, 0, I_INVLPGA }, + { "iret", TOKEN_INSN, C_none, 0, I_IRET }, + { "iretd", TOKEN_INSN, C_none, 0, I_IRETD }, + { "iretq", TOKEN_INSN, C_none, 0, I_IRETQ }, + { "iretw", TOKEN_INSN, C_none, 0, I_IRETW }, + { "jcxz", TOKEN_INSN, C_none, 0, I_JCXZ }, + { "jecxz", TOKEN_INSN, C_none, 0, I_JECXZ }, + { "jrcxz", TOKEN_INSN, C_none, 0, I_JRCXZ }, + { "jmp", TOKEN_INSN, C_none, 0, I_JMP }, + { "jmpe", TOKEN_INSN, C_none, 0, I_JMPE }, + { "lahf", TOKEN_INSN, C_none, 0, I_LAHF }, + { "lar", TOKEN_INSN, C_none, 0, I_LAR }, + { "lds", TOKEN_INSN, C_none, 0, I_LDS }, + { "lea", TOKEN_INSN, C_none, 0, I_LEA }, + { "leave", TOKEN_INSN, C_none, 0, I_LEAVE }, + { "les", TOKEN_INSN, C_none, 0, I_LES }, + { "lfence", TOKEN_INSN, C_none, 0, I_LFENCE }, + { "lfs", TOKEN_INSN, C_none, 0, I_LFS }, + { "lgdt", TOKEN_INSN, C_none, 0, I_LGDT }, + { "lgs", TOKEN_INSN, C_none, 0, I_LGS }, + { "lidt", TOKEN_INSN, C_none, 0, I_LIDT }, + { "lldt", TOKEN_INSN, C_none, 0, I_LLDT }, + { "lmsw", TOKEN_INSN, C_none, 0, I_LMSW }, + { "loadall", TOKEN_INSN, C_none, 0, I_LOADALL }, + { "loadall286", TOKEN_INSN, C_none, 0, I_LOADALL286 }, + { "lodsb", TOKEN_INSN, C_none, 0, I_LODSB }, + { "lodsd", TOKEN_INSN, C_none, 0, I_LODSD }, + { "lodsq", TOKEN_INSN, C_none, 0, I_LODSQ }, + { "lodsw", TOKEN_INSN, C_none, 0, I_LODSW }, + { "loop", TOKEN_INSN, C_none, 0, I_LOOP }, + { "loope", TOKEN_INSN, C_none, 0, I_LOOPE }, + { "loopne", TOKEN_INSN, C_none, 0, I_LOOPNE }, + { "loopnz", TOKEN_INSN, C_none, 0, I_LOOPNZ }, + { "loopz", TOKEN_INSN, C_none, 0, I_LOOPZ }, + { "lsl", TOKEN_INSN, C_none, 0, I_LSL }, + { "lss", TOKEN_INSN, C_none, 0, I_LSS }, + { "ltr", TOKEN_INSN, C_none, 0, I_LTR }, + { "mfence", TOKEN_INSN, C_none, 0, I_MFENCE }, + { "monitor", TOKEN_INSN, C_none, 0, I_MONITOR }, + { "monitorx", TOKEN_INSN, C_none, 0, I_MONITORX }, + { "mov", TOKEN_INSN, C_none, 0, I_MOV }, + { "movd", TOKEN_INSN, C_none, 0, I_MOVD }, + { "movq", TOKEN_INSN, C_none, 0, I_MOVQ }, + { "movsb", TOKEN_INSN, C_none, 0, I_MOVSB }, + { "movsd", TOKEN_INSN, C_none, 0, I_MOVSD }, + { "movsq", TOKEN_INSN, C_none, 0, I_MOVSQ }, + { "movsw", TOKEN_INSN, C_none, 0, I_MOVSW }, + { "movsx", TOKEN_INSN, C_none, 0, I_MOVSX }, + { "movsxd", TOKEN_INSN, C_none, 0, I_MOVSXD }, + { "movzx", TOKEN_INSN, C_none, 0, I_MOVZX }, + { "mul", TOKEN_INSN, C_none, 0, I_MUL }, + { "mwait", TOKEN_INSN, C_none, 0, I_MWAIT }, + { "mwaitx", TOKEN_INSN, C_none, 0, I_MWAITX }, + { "neg", TOKEN_INSN, C_none, 0, I_NEG }, + { "nop", TOKEN_INSN, C_none, 0, I_NOP }, + { "not", TOKEN_INSN, C_none, 0, I_NOT }, + { "or", TOKEN_INSN, C_none, 0, I_OR }, + { "out", TOKEN_INSN, C_none, 0, I_OUT }, + { "outsb", TOKEN_INSN, C_none, 0, I_OUTSB }, + { "outsd", TOKEN_INSN, C_none, 0, I_OUTSD }, + { "outsw", TOKEN_INSN, C_none, 0, I_OUTSW }, + { "packssdw", TOKEN_INSN, C_none, 0, I_PACKSSDW }, + { "packsswb", TOKEN_INSN, C_none, 0, I_PACKSSWB }, + { "packuswb", TOKEN_INSN, C_none, 0, I_PACKUSWB }, + { "paddb", TOKEN_INSN, C_none, 0, I_PADDB }, + { "paddd", TOKEN_INSN, C_none, 0, I_PADDD }, + { "paddsb", TOKEN_INSN, C_none, 0, I_PADDSB }, + { "paddsiw", TOKEN_INSN, C_none, 0, I_PADDSIW }, + { "paddsw", TOKEN_INSN, C_none, 0, I_PADDSW }, + { "paddusb", TOKEN_INSN, C_none, 0, I_PADDUSB }, + { "paddusw", TOKEN_INSN, C_none, 0, I_PADDUSW }, + { "paddw", TOKEN_INSN, C_none, 0, I_PADDW }, + { "pand", TOKEN_INSN, C_none, 0, I_PAND }, + { "pandn", TOKEN_INSN, C_none, 0, I_PANDN }, + { "pause", TOKEN_INSN, C_none, 0, I_PAUSE }, + { "paveb", TOKEN_INSN, C_none, 0, I_PAVEB }, + { "pavgusb", TOKEN_INSN, C_none, 0, I_PAVGUSB }, + { "pcmpeqb", TOKEN_INSN, C_none, 0, I_PCMPEQB }, + { "pcmpeqd", TOKEN_INSN, C_none, 0, I_PCMPEQD }, + { "pcmpeqw", TOKEN_INSN, C_none, 0, I_PCMPEQW }, + { "pcmpgtb", TOKEN_INSN, C_none, 0, I_PCMPGTB }, + { "pcmpgtd", TOKEN_INSN, C_none, 0, I_PCMPGTD }, + { "pcmpgtw", TOKEN_INSN, C_none, 0, I_PCMPGTW }, + { "pdistib", TOKEN_INSN, C_none, 0, I_PDISTIB }, + { "pf2id", TOKEN_INSN, C_none, 0, I_PF2ID }, + { "pfacc", TOKEN_INSN, C_none, 0, I_PFACC }, + { "pfadd", TOKEN_INSN, C_none, 0, I_PFADD }, + { "pfcmpeq", TOKEN_INSN, C_none, 0, I_PFCMPEQ }, + { "pfcmpge", TOKEN_INSN, C_none, 0, I_PFCMPGE }, + { "pfcmpgt", TOKEN_INSN, C_none, 0, I_PFCMPGT }, + { "pfmax", TOKEN_INSN, C_none, 0, I_PFMAX }, + { "pfmin", TOKEN_INSN, C_none, 0, I_PFMIN }, + { "pfmul", TOKEN_INSN, C_none, 0, I_PFMUL }, + { "pfrcp", TOKEN_INSN, C_none, 0, I_PFRCP }, + { "pfrcpit1", TOKEN_INSN, C_none, 0, I_PFRCPIT1 }, + { "pfrcpit2", TOKEN_INSN, C_none, 0, I_PFRCPIT2 }, + { "pfrsqit1", TOKEN_INSN, C_none, 0, I_PFRSQIT1 }, + { "pfrsqrt", TOKEN_INSN, C_none, 0, I_PFRSQRT }, + { "pfsub", TOKEN_INSN, C_none, 0, I_PFSUB }, + { "pfsubr", TOKEN_INSN, C_none, 0, I_PFSUBR }, + { "pi2fd", TOKEN_INSN, C_none, 0, I_PI2FD }, + { "pmachriw", TOKEN_INSN, C_none, 0, I_PMACHRIW }, + { "pmaddwd", TOKEN_INSN, C_none, 0, I_PMADDWD }, + { "pmagw", TOKEN_INSN, C_none, 0, I_PMAGW }, + { "pmulhriw", TOKEN_INSN, C_none, 0, I_PMULHRIW }, + { "pmulhrwa", TOKEN_INSN, C_none, 0, I_PMULHRWA }, + { "pmulhrwc", TOKEN_INSN, C_none, 0, I_PMULHRWC }, + { "pmulhw", TOKEN_INSN, C_none, 0, I_PMULHW }, + { "pmullw", TOKEN_INSN, C_none, 0, I_PMULLW }, + { "pmvgezb", TOKEN_INSN, C_none, 0, I_PMVGEZB }, + { "pmvlzb", TOKEN_INSN, C_none, 0, I_PMVLZB }, + { "pmvnzb", TOKEN_INSN, C_none, 0, I_PMVNZB }, + { "pmvzb", TOKEN_INSN, C_none, 0, I_PMVZB }, + { "pop", TOKEN_INSN, C_none, 0, I_POP }, + { "popa", TOKEN_INSN, C_none, 0, I_POPA }, + { "popad", TOKEN_INSN, C_none, 0, I_POPAD }, + { "popaw", TOKEN_INSN, C_none, 0, I_POPAW }, + { "popf", TOKEN_INSN, C_none, 0, I_POPF }, + { "popfd", TOKEN_INSN, C_none, 0, I_POPFD }, + { "popfq", TOKEN_INSN, C_none, 0, I_POPFQ }, + { "popfw", TOKEN_INSN, C_none, 0, I_POPFW }, + { "por", TOKEN_INSN, C_none, 0, I_POR }, + { "prefetch", TOKEN_INSN, C_none, 0, I_PREFETCH }, + { "prefetchw", TOKEN_INSN, C_none, 0, I_PREFETCHW }, + { "pslld", TOKEN_INSN, C_none, 0, I_PSLLD }, + { "psllq", TOKEN_INSN, C_none, 0, I_PSLLQ }, + { "psllw", TOKEN_INSN, C_none, 0, I_PSLLW }, + { "psrad", TOKEN_INSN, C_none, 0, I_PSRAD }, + { "psraw", TOKEN_INSN, C_none, 0, I_PSRAW }, + { "psrld", TOKEN_INSN, C_none, 0, I_PSRLD }, + { "psrlq", TOKEN_INSN, C_none, 0, I_PSRLQ }, + { "psrlw", TOKEN_INSN, C_none, 0, I_PSRLW }, + { "psubb", TOKEN_INSN, C_none, 0, I_PSUBB }, + { "psubd", TOKEN_INSN, C_none, 0, I_PSUBD }, + { "psubsb", TOKEN_INSN, C_none, 0, I_PSUBSB }, + { "psubsiw", TOKEN_INSN, C_none, 0, I_PSUBSIW }, + { "psubsw", TOKEN_INSN, C_none, 0, I_PSUBSW }, + { "psubusb", TOKEN_INSN, C_none, 0, I_PSUBUSB }, + { "psubusw", TOKEN_INSN, C_none, 0, I_PSUBUSW }, + { "psubw", TOKEN_INSN, C_none, 0, I_PSUBW }, + { "punpckhbw", TOKEN_INSN, C_none, 0, I_PUNPCKHBW }, + { "punpckhdq", TOKEN_INSN, C_none, 0, I_PUNPCKHDQ }, + { "punpckhwd", TOKEN_INSN, C_none, 0, I_PUNPCKHWD }, + { "punpcklbw", TOKEN_INSN, C_none, 0, I_PUNPCKLBW }, + { "punpckldq", TOKEN_INSN, C_none, 0, I_PUNPCKLDQ }, + { "punpcklwd", TOKEN_INSN, C_none, 0, I_PUNPCKLWD }, + { "push", TOKEN_INSN, C_none, 0, I_PUSH }, + { "pusha", TOKEN_INSN, C_none, 0, I_PUSHA }, + { "pushad", TOKEN_INSN, C_none, 0, I_PUSHAD }, + { "pushaw", TOKEN_INSN, C_none, 0, I_PUSHAW }, + { "pushf", TOKEN_INSN, C_none, 0, I_PUSHF }, + { "pushfd", TOKEN_INSN, C_none, 0, I_PUSHFD }, + { "pushfq", TOKEN_INSN, C_none, 0, I_PUSHFQ }, + { "pushfw", TOKEN_INSN, C_none, 0, I_PUSHFW }, + { "pxor", TOKEN_INSN, C_none, 0, I_PXOR }, + { "rcl", TOKEN_INSN, C_none, 0, I_RCL }, + { "rcr", TOKEN_INSN, C_none, 0, I_RCR }, + { "rdshr", TOKEN_INSN, C_none, 0, I_RDSHR }, + { "rdmsr", TOKEN_INSN, C_none, 0, I_RDMSR }, + { "rdpmc", TOKEN_INSN, C_none, 0, I_RDPMC }, + { "rdtsc", TOKEN_INSN, C_none, 0, I_RDTSC }, + { "rdtscp", TOKEN_INSN, C_none, 0, I_RDTSCP }, + { "ret", TOKEN_INSN, C_none, 0, I_RET }, + { "retf", TOKEN_INSN, C_none, 0, I_RETF }, + { "retn", TOKEN_INSN, C_none, 0, I_RETN }, + { "retw", TOKEN_INSN, C_none, 0, I_RETW }, + { "retfw", TOKEN_INSN, C_none, 0, I_RETFW }, + { "retnw", TOKEN_INSN, C_none, 0, I_RETNW }, + { "retd", TOKEN_INSN, C_none, 0, I_RETD }, + { "retfd", TOKEN_INSN, C_none, 0, I_RETFD }, + { "retnd", TOKEN_INSN, C_none, 0, I_RETND }, + { "retq", TOKEN_INSN, C_none, 0, I_RETQ }, + { "retfq", TOKEN_INSN, C_none, 0, I_RETFQ }, + { "retnq", TOKEN_INSN, C_none, 0, I_RETNQ }, + { "rol", TOKEN_INSN, C_none, 0, I_ROL }, + { "ror", TOKEN_INSN, C_none, 0, I_ROR }, + { "rdm", TOKEN_INSN, C_none, 0, I_RDM }, + { "rsdc", TOKEN_INSN, C_none, 0, I_RSDC }, + { "rsldt", TOKEN_INSN, C_none, 0, I_RSLDT }, + { "rsm", TOKEN_INSN, C_none, 0, I_RSM }, + { "rsts", TOKEN_INSN, C_none, 0, I_RSTS }, + { "sahf", TOKEN_INSN, C_none, 0, I_SAHF }, + { "sal", TOKEN_INSN, C_none, 0, I_SAL }, + { "salc", TOKEN_INSN, C_none, 0, I_SALC }, + { "sar", TOKEN_INSN, C_none, 0, I_SAR }, + { "sbb", TOKEN_INSN, C_none, 0, I_SBB }, + { "scasb", TOKEN_INSN, C_none, 0, I_SCASB }, + { "scasd", TOKEN_INSN, C_none, 0, I_SCASD }, + { "scasq", TOKEN_INSN, C_none, 0, I_SCASQ }, + { "scasw", TOKEN_INSN, C_none, 0, I_SCASW }, + { "sfence", TOKEN_INSN, C_none, 0, I_SFENCE }, + { "sgdt", TOKEN_INSN, C_none, 0, I_SGDT }, + { "shl", TOKEN_INSN, C_none, 0, I_SHL }, + { "shld", TOKEN_INSN, C_none, 0, I_SHLD }, + { "shr", TOKEN_INSN, C_none, 0, I_SHR }, + { "shrd", TOKEN_INSN, C_none, 0, I_SHRD }, + { "sidt", TOKEN_INSN, C_none, 0, I_SIDT }, + { "sldt", TOKEN_INSN, C_none, 0, I_SLDT }, + { "skinit", TOKEN_INSN, C_none, 0, I_SKINIT }, + { "smi", TOKEN_INSN, C_none, 0, I_SMI }, + { "smint", TOKEN_INSN, C_none, 0, I_SMINT }, + { "smintold", TOKEN_INSN, C_none, 0, I_SMINTOLD }, + { "smsw", TOKEN_INSN, C_none, 0, I_SMSW }, + { "stc", TOKEN_INSN, C_none, 0, I_STC }, + { "std", TOKEN_INSN, C_none, 0, I_STD }, + { "sti", TOKEN_INSN, C_none, 0, I_STI }, + { "stosb", TOKEN_INSN, C_none, 0, I_STOSB }, + { "stosd", TOKEN_INSN, C_none, 0, I_STOSD }, + { "stosq", TOKEN_INSN, C_none, 0, I_STOSQ }, + { "stosw", TOKEN_INSN, C_none, 0, I_STOSW }, + { "str", TOKEN_INSN, C_none, 0, I_STR }, + { "sub", TOKEN_INSN, C_none, 0, I_SUB }, + { "svdc", TOKEN_INSN, C_none, 0, I_SVDC }, + { "svldt", TOKEN_INSN, C_none, 0, I_SVLDT }, + { "svts", TOKEN_INSN, C_none, 0, I_SVTS }, + { "swapgs", TOKEN_INSN, C_none, 0, I_SWAPGS }, + { "syscall", TOKEN_INSN, C_none, 0, I_SYSCALL }, + { "sysenter", TOKEN_INSN, C_none, 0, I_SYSENTER }, + { "sysexit", TOKEN_INSN, C_none, 0, I_SYSEXIT }, + { "sysret", TOKEN_INSN, C_none, 0, I_SYSRET }, + { "test", TOKEN_INSN, C_none, 0, I_TEST }, + { "ud0", TOKEN_INSN, C_none, 0, I_UD0 }, + { "ud1", TOKEN_INSN, C_none, 0, I_UD1 }, + { "ud2b", TOKEN_INSN, C_none, 0, I_UD2B }, + { "ud2", TOKEN_INSN, C_none, 0, I_UD2 }, + { "ud2a", TOKEN_INSN, C_none, 0, I_UD2A }, + { "umov", TOKEN_INSN, C_none, 0, I_UMOV }, + { "verr", TOKEN_INSN, C_none, 0, I_VERR }, + { "verw", TOKEN_INSN, C_none, 0, I_VERW }, + { "fwait", TOKEN_INSN, C_none, 0, I_FWAIT }, + { "wbinvd", TOKEN_INSN, C_none, 0, I_WBINVD }, + { "wrshr", TOKEN_INSN, C_none, 0, I_WRSHR }, + { "wrmsr", TOKEN_INSN, C_none, 0, I_WRMSR }, + { "xadd", TOKEN_INSN, C_none, 0, I_XADD }, + { "xbts", TOKEN_INSN, C_none, 0, I_XBTS }, + { "xchg", TOKEN_INSN, C_none, 0, I_XCHG }, + { "xlatb", TOKEN_INSN, C_none, 0, I_XLATB }, + { "xlat", TOKEN_INSN, C_none, 0, I_XLAT }, + { "xor", TOKEN_INSN, C_none, 0, I_XOR }, + { "cmova", TOKEN_INSN, C_A, 0, I_CMOVcc }, + { "cmovae", TOKEN_INSN, C_AE, 0, I_CMOVcc }, + { "cmovb", TOKEN_INSN, C_B, 0, I_CMOVcc }, + { "cmovbe", TOKEN_INSN, C_BE, 0, I_CMOVcc }, + { "cmovc", TOKEN_INSN, C_C, 0, I_CMOVcc }, + { "cmove", TOKEN_INSN, C_E, 0, I_CMOVcc }, + { "cmovg", TOKEN_INSN, C_G, 0, I_CMOVcc }, + { "cmovge", TOKEN_INSN, C_GE, 0, I_CMOVcc }, + { "cmovl", TOKEN_INSN, C_L, 0, I_CMOVcc }, + { "cmovle", TOKEN_INSN, C_LE, 0, I_CMOVcc }, + { "cmovna", TOKEN_INSN, C_NA, 0, I_CMOVcc }, + { "cmovnae", TOKEN_INSN, C_NAE, 0, I_CMOVcc }, + { "cmovnb", TOKEN_INSN, C_NB, 0, I_CMOVcc }, + { "cmovnbe", TOKEN_INSN, C_NBE, 0, I_CMOVcc }, + { "cmovnc", TOKEN_INSN, C_NC, 0, I_CMOVcc }, + { "cmovne", TOKEN_INSN, C_NE, 0, I_CMOVcc }, + { "cmovng", TOKEN_INSN, C_NG, 0, I_CMOVcc }, + { "cmovnge", TOKEN_INSN, C_NGE, 0, I_CMOVcc }, + { "cmovnl", TOKEN_INSN, C_NL, 0, I_CMOVcc }, + { "cmovnle", TOKEN_INSN, C_NLE, 0, I_CMOVcc }, + { "cmovno", TOKEN_INSN, C_NO, 0, I_CMOVcc }, + { "cmovnp", TOKEN_INSN, C_NP, 0, I_CMOVcc }, + { "cmovns", TOKEN_INSN, C_NS, 0, I_CMOVcc }, + { "cmovnz", TOKEN_INSN, C_NZ, 0, I_CMOVcc }, + { "cmovo", TOKEN_INSN, C_O, 0, I_CMOVcc }, + { "cmovp", TOKEN_INSN, C_P, 0, I_CMOVcc }, + { "cmovpe", TOKEN_INSN, C_PE, 0, I_CMOVcc }, + { "cmovpo", TOKEN_INSN, C_PO, 0, I_CMOVcc }, + { "cmovs", TOKEN_INSN, C_S, 0, I_CMOVcc }, + { "cmovz", TOKEN_INSN, C_Z, 0, I_CMOVcc }, + { "ja", TOKEN_INSN, C_A, 0, I_Jcc }, + { "jae", TOKEN_INSN, C_AE, 0, I_Jcc }, + { "jb", TOKEN_INSN, C_B, 0, I_Jcc }, + { "jbe", TOKEN_INSN, C_BE, 0, I_Jcc }, + { "jc", TOKEN_INSN, C_C, 0, I_Jcc }, + { "je", TOKEN_INSN, C_E, 0, I_Jcc }, + { "jg", TOKEN_INSN, C_G, 0, I_Jcc }, + { "jge", TOKEN_INSN, C_GE, 0, I_Jcc }, + { "jl", TOKEN_INSN, C_L, 0, I_Jcc }, + { "jle", TOKEN_INSN, C_LE, 0, I_Jcc }, + { "jna", TOKEN_INSN, C_NA, 0, I_Jcc }, + { "jnae", TOKEN_INSN, C_NAE, 0, I_Jcc }, + { "jnb", TOKEN_INSN, C_NB, 0, I_Jcc }, + { "jnbe", TOKEN_INSN, C_NBE, 0, I_Jcc }, + { "jnc", TOKEN_INSN, C_NC, 0, I_Jcc }, + { "jne", TOKEN_INSN, C_NE, 0, I_Jcc }, + { "jng", TOKEN_INSN, C_NG, 0, I_Jcc }, + { "jnge", TOKEN_INSN, C_NGE, 0, I_Jcc }, + { "jnl", TOKEN_INSN, C_NL, 0, I_Jcc }, + { "jnle", TOKEN_INSN, C_NLE, 0, I_Jcc }, + { "jno", TOKEN_INSN, C_NO, 0, I_Jcc }, + { "jnp", TOKEN_INSN, C_NP, 0, I_Jcc }, + { "jns", TOKEN_INSN, C_NS, 0, I_Jcc }, + { "jnz", TOKEN_INSN, C_NZ, 0, I_Jcc }, + { "jo", TOKEN_INSN, C_O, 0, I_Jcc }, + { "jp", TOKEN_INSN, C_P, 0, I_Jcc }, + { "jpe", TOKEN_INSN, C_PE, 0, I_Jcc }, + { "jpo", TOKEN_INSN, C_PO, 0, I_Jcc }, + { "js", TOKEN_INSN, C_S, 0, I_Jcc }, + { "jz", TOKEN_INSN, C_Z, 0, I_Jcc }, + { "seta", TOKEN_INSN, C_A, 0, I_SETcc }, + { "setae", TOKEN_INSN, C_AE, 0, I_SETcc }, + { "setb", TOKEN_INSN, C_B, 0, I_SETcc }, + { "setbe", TOKEN_INSN, C_BE, 0, I_SETcc }, + { "setc", TOKEN_INSN, C_C, 0, I_SETcc }, + { "sete", TOKEN_INSN, C_E, 0, I_SETcc }, + { "setg", TOKEN_INSN, C_G, 0, I_SETcc }, + { "setge", TOKEN_INSN, C_GE, 0, I_SETcc }, + { "setl", TOKEN_INSN, C_L, 0, I_SETcc }, + { "setle", TOKEN_INSN, C_LE, 0, I_SETcc }, + { "setna", TOKEN_INSN, C_NA, 0, I_SETcc }, + { "setnae", TOKEN_INSN, C_NAE, 0, I_SETcc }, + { "setnb", TOKEN_INSN, C_NB, 0, I_SETcc }, + { "setnbe", TOKEN_INSN, C_NBE, 0, I_SETcc }, + { "setnc", TOKEN_INSN, C_NC, 0, I_SETcc }, + { "setne", TOKEN_INSN, C_NE, 0, I_SETcc }, + { "setng", TOKEN_INSN, C_NG, 0, I_SETcc }, + { "setnge", TOKEN_INSN, C_NGE, 0, I_SETcc }, + { "setnl", TOKEN_INSN, C_NL, 0, I_SETcc }, + { "setnle", TOKEN_INSN, C_NLE, 0, I_SETcc }, + { "setno", TOKEN_INSN, C_NO, 0, I_SETcc }, + { "setnp", TOKEN_INSN, C_NP, 0, I_SETcc }, + { "setns", TOKEN_INSN, C_NS, 0, I_SETcc }, + { "setnz", TOKEN_INSN, C_NZ, 0, I_SETcc }, + { "seto", TOKEN_INSN, C_O, 0, I_SETcc }, + { "setp", TOKEN_INSN, C_P, 0, I_SETcc }, + { "setpe", TOKEN_INSN, C_PE, 0, I_SETcc }, + { "setpo", TOKEN_INSN, C_PO, 0, I_SETcc }, + { "sets", TOKEN_INSN, C_S, 0, I_SETcc }, + { "setz", TOKEN_INSN, C_Z, 0, I_SETcc }, + { "addps", TOKEN_INSN, C_none, 0, I_ADDPS }, + { "addss", TOKEN_INSN, C_none, 0, I_ADDSS }, + { "andnps", TOKEN_INSN, C_none, 0, I_ANDNPS }, + { "andps", TOKEN_INSN, C_none, 0, I_ANDPS }, + { "cmpeqps", TOKEN_INSN, C_none, 0, I_CMPEQPS }, + { "cmpeqss", TOKEN_INSN, C_none, 0, I_CMPEQSS }, + { "cmpleps", TOKEN_INSN, C_none, 0, I_CMPLEPS }, + { "cmpless", TOKEN_INSN, C_none, 0, I_CMPLESS }, + { "cmpltps", TOKEN_INSN, C_none, 0, I_CMPLTPS }, + { "cmpltss", TOKEN_INSN, C_none, 0, I_CMPLTSS }, + { "cmpneqps", TOKEN_INSN, C_none, 0, I_CMPNEQPS }, + { "cmpneqss", TOKEN_INSN, C_none, 0, I_CMPNEQSS }, + { "cmpnleps", TOKEN_INSN, C_none, 0, I_CMPNLEPS }, + { "cmpnless", TOKEN_INSN, C_none, 0, I_CMPNLESS }, + { "cmpnltps", TOKEN_INSN, C_none, 0, I_CMPNLTPS }, + { "cmpnltss", TOKEN_INSN, C_none, 0, I_CMPNLTSS }, + { "cmpordps", TOKEN_INSN, C_none, 0, I_CMPORDPS }, + { "cmpordss", TOKEN_INSN, C_none, 0, I_CMPORDSS }, + { "cmpunordps", TOKEN_INSN, C_none, 0, I_CMPUNORDPS }, + { "cmpunordss", TOKEN_INSN, C_none, 0, I_CMPUNORDSS }, + { "cmpps", TOKEN_INSN, C_none, 0, I_CMPPS }, + { "cmpss", TOKEN_INSN, C_none, 0, I_CMPSS }, + { "comiss", TOKEN_INSN, C_none, 0, I_COMISS }, + { "cvtpi2ps", TOKEN_INSN, C_none, 0, I_CVTPI2PS }, + { "cvtps2pi", TOKEN_INSN, C_none, 0, I_CVTPS2PI }, + { "cvtsi2ss", TOKEN_INSN, C_none, 0, I_CVTSI2SS }, + { "cvtss2si", TOKEN_INSN, C_none, 0, I_CVTSS2SI }, + { "cvttps2pi", TOKEN_INSN, C_none, 0, I_CVTTPS2PI }, + { "cvttss2si", TOKEN_INSN, C_none, 0, I_CVTTSS2SI }, + { "divps", TOKEN_INSN, C_none, 0, I_DIVPS }, + { "divss", TOKEN_INSN, C_none, 0, I_DIVSS }, + { "ldmxcsr", TOKEN_INSN, C_none, 0, I_LDMXCSR }, + { "maxps", TOKEN_INSN, C_none, 0, I_MAXPS }, + { "maxss", TOKEN_INSN, C_none, 0, I_MAXSS }, + { "minps", TOKEN_INSN, C_none, 0, I_MINPS }, + { "minss", TOKEN_INSN, C_none, 0, I_MINSS }, + { "movaps", TOKEN_INSN, C_none, 0, I_MOVAPS }, + { "movhps", TOKEN_INSN, C_none, 0, I_MOVHPS }, + { "movlhps", TOKEN_INSN, C_none, 0, I_MOVLHPS }, + { "movlps", TOKEN_INSN, C_none, 0, I_MOVLPS }, + { "movhlps", TOKEN_INSN, C_none, 0, I_MOVHLPS }, + { "movmskps", TOKEN_INSN, C_none, 0, I_MOVMSKPS }, + { "movntps", TOKEN_INSN, C_none, 0, I_MOVNTPS }, + { "movss", TOKEN_INSN, C_none, 0, I_MOVSS }, + { "movups", TOKEN_INSN, C_none, 0, I_MOVUPS }, + { "mulps", TOKEN_INSN, C_none, 0, I_MULPS }, + { "mulss", TOKEN_INSN, C_none, 0, I_MULSS }, + { "orps", TOKEN_INSN, C_none, 0, I_ORPS }, + { "rcpps", TOKEN_INSN, C_none, 0, I_RCPPS }, + { "rcpss", TOKEN_INSN, C_none, 0, I_RCPSS }, + { "rsqrtps", TOKEN_INSN, C_none, 0, I_RSQRTPS }, + { "rsqrtss", TOKEN_INSN, C_none, 0, I_RSQRTSS }, + { "shufps", TOKEN_INSN, C_none, 0, I_SHUFPS }, + { "sqrtps", TOKEN_INSN, C_none, 0, I_SQRTPS }, + { "sqrtss", TOKEN_INSN, C_none, 0, I_SQRTSS }, + { "stmxcsr", TOKEN_INSN, C_none, 0, I_STMXCSR }, + { "subps", TOKEN_INSN, C_none, 0, I_SUBPS }, + { "subss", TOKEN_INSN, C_none, 0, I_SUBSS }, + { "ucomiss", TOKEN_INSN, C_none, 0, I_UCOMISS }, + { "unpckhps", TOKEN_INSN, C_none, 0, I_UNPCKHPS }, + { "unpcklps", TOKEN_INSN, C_none, 0, I_UNPCKLPS }, + { "xorps", TOKEN_INSN, C_none, 0, I_XORPS }, + { "fxrstor", TOKEN_INSN, C_none, 0, I_FXRSTOR }, + { "fxrstor64", TOKEN_INSN, C_none, 0, I_FXRSTOR64 }, + { "fxsave", TOKEN_INSN, C_none, 0, I_FXSAVE }, + { "fxsave64", TOKEN_INSN, C_none, 0, I_FXSAVE64 }, + { "xgetbv", TOKEN_INSN, C_none, 0, I_XGETBV }, + { "xsetbv", TOKEN_INSN, C_none, 0, I_XSETBV }, + { "xsave", TOKEN_INSN, C_none, 0, I_XSAVE }, + { "xsave64", TOKEN_INSN, C_none, 0, I_XSAVE64 }, + { "xsavec", TOKEN_INSN, C_none, 0, I_XSAVEC }, + { "xsavec64", TOKEN_INSN, C_none, 0, I_XSAVEC64 }, + { "xsaveopt", TOKEN_INSN, C_none, 0, I_XSAVEOPT }, + { "xsaveopt64", TOKEN_INSN, C_none, 0, I_XSAVEOPT64 }, + { "xsaves", TOKEN_INSN, C_none, 0, I_XSAVES }, + { "xsaves64", TOKEN_INSN, C_none, 0, I_XSAVES64 }, + { "xrstor", TOKEN_INSN, C_none, 0, I_XRSTOR }, + { "xrstor64", TOKEN_INSN, C_none, 0, I_XRSTOR64 }, + { "xrstors", TOKEN_INSN, C_none, 0, I_XRSTORS }, + { "xrstors64", TOKEN_INSN, C_none, 0, I_XRSTORS64 }, + { "prefetchnta", TOKEN_INSN, C_none, 0, I_PREFETCHNTA }, + { "prefetcht0", TOKEN_INSN, C_none, 0, I_PREFETCHT0 }, + { "prefetcht1", TOKEN_INSN, C_none, 0, I_PREFETCHT1 }, + { "prefetcht2", TOKEN_INSN, C_none, 0, I_PREFETCHT2 }, + { "maskmovq", TOKEN_INSN, C_none, 0, I_MASKMOVQ }, + { "movntq", TOKEN_INSN, C_none, 0, I_MOVNTQ }, + { "pavgb", TOKEN_INSN, C_none, 0, I_PAVGB }, + { "pavgw", TOKEN_INSN, C_none, 0, I_PAVGW }, + { "pextrw", TOKEN_INSN, C_none, 0, I_PEXTRW }, + { "pinsrw", TOKEN_INSN, C_none, 0, I_PINSRW }, + { "pmaxsw", TOKEN_INSN, C_none, 0, I_PMAXSW }, + { "pmaxub", TOKEN_INSN, C_none, 0, I_PMAXUB }, + { "pminsw", TOKEN_INSN, C_none, 0, I_PMINSW }, + { "pminub", TOKEN_INSN, C_none, 0, I_PMINUB }, + { "pmovmskb", TOKEN_INSN, C_none, 0, I_PMOVMSKB }, + { "pmulhuw", TOKEN_INSN, C_none, 0, I_PMULHUW }, + { "psadbw", TOKEN_INSN, C_none, 0, I_PSADBW }, + { "pshufw", TOKEN_INSN, C_none, 0, I_PSHUFW }, + { "pf2iw", TOKEN_INSN, C_none, 0, I_PF2IW }, + { "pfnacc", TOKEN_INSN, C_none, 0, I_PFNACC }, + { "pfpnacc", TOKEN_INSN, C_none, 0, I_PFPNACC }, + { "pi2fw", TOKEN_INSN, C_none, 0, I_PI2FW }, + { "pswapd", TOKEN_INSN, C_none, 0, I_PSWAPD }, + { "maskmovdqu", TOKEN_INSN, C_none, 0, I_MASKMOVDQU }, + { "clflush", TOKEN_INSN, C_none, 0, I_CLFLUSH }, + { "movntdq", TOKEN_INSN, C_none, 0, I_MOVNTDQ }, + { "movnti", TOKEN_INSN, C_none, 0, I_MOVNTI }, + { "movntpd", TOKEN_INSN, C_none, 0, I_MOVNTPD }, + { "movdqa", TOKEN_INSN, C_none, 0, I_MOVDQA }, + { "movdqu", TOKEN_INSN, C_none, 0, I_MOVDQU }, + { "movdq2q", TOKEN_INSN, C_none, 0, I_MOVDQ2Q }, + { "movq2dq", TOKEN_INSN, C_none, 0, I_MOVQ2DQ }, + { "paddq", TOKEN_INSN, C_none, 0, I_PADDQ }, + { "pmuludq", TOKEN_INSN, C_none, 0, I_PMULUDQ }, + { "pshufd", TOKEN_INSN, C_none, 0, I_PSHUFD }, + { "pshufhw", TOKEN_INSN, C_none, 0, I_PSHUFHW }, + { "pshuflw", TOKEN_INSN, C_none, 0, I_PSHUFLW }, + { "pslldq", TOKEN_INSN, C_none, 0, I_PSLLDQ }, + { "psrldq", TOKEN_INSN, C_none, 0, I_PSRLDQ }, + { "psubq", TOKEN_INSN, C_none, 0, I_PSUBQ }, + { "punpckhqdq", TOKEN_INSN, C_none, 0, I_PUNPCKHQDQ }, + { "punpcklqdq", TOKEN_INSN, C_none, 0, I_PUNPCKLQDQ }, + { "addpd", TOKEN_INSN, C_none, 0, I_ADDPD }, + { "addsd", TOKEN_INSN, C_none, 0, I_ADDSD }, + { "andnpd", TOKEN_INSN, C_none, 0, I_ANDNPD }, + { "andpd", TOKEN_INSN, C_none, 0, I_ANDPD }, + { "cmpeqpd", TOKEN_INSN, C_none, 0, I_CMPEQPD }, + { "cmpeqsd", TOKEN_INSN, C_none, 0, I_CMPEQSD }, + { "cmplepd", TOKEN_INSN, C_none, 0, I_CMPLEPD }, + { "cmplesd", TOKEN_INSN, C_none, 0, I_CMPLESD }, + { "cmpltpd", TOKEN_INSN, C_none, 0, I_CMPLTPD }, + { "cmpltsd", TOKEN_INSN, C_none, 0, I_CMPLTSD }, + { "cmpneqpd", TOKEN_INSN, C_none, 0, I_CMPNEQPD }, + { "cmpneqsd", TOKEN_INSN, C_none, 0, I_CMPNEQSD }, + { "cmpnlepd", TOKEN_INSN, C_none, 0, I_CMPNLEPD }, + { "cmpnlesd", TOKEN_INSN, C_none, 0, I_CMPNLESD }, + { "cmpnltpd", TOKEN_INSN, C_none, 0, I_CMPNLTPD }, + { "cmpnltsd", TOKEN_INSN, C_none, 0, I_CMPNLTSD }, + { "cmpordpd", TOKEN_INSN, C_none, 0, I_CMPORDPD }, + { "cmpordsd", TOKEN_INSN, C_none, 0, I_CMPORDSD }, + { "cmpunordpd", TOKEN_INSN, C_none, 0, I_CMPUNORDPD }, + { "cmpunordsd", TOKEN_INSN, C_none, 0, I_CMPUNORDSD }, + { "cmppd", TOKEN_INSN, C_none, 0, I_CMPPD }, + { "comisd", TOKEN_INSN, C_none, 0, I_COMISD }, + { "cvtdq2pd", TOKEN_INSN, C_none, 0, I_CVTDQ2PD }, + { "cvtdq2ps", TOKEN_INSN, C_none, 0, I_CVTDQ2PS }, + { "cvtpd2dq", TOKEN_INSN, C_none, 0, I_CVTPD2DQ }, + { "cvtpd2pi", TOKEN_INSN, C_none, 0, I_CVTPD2PI }, + { "cvtpd2ps", TOKEN_INSN, C_none, 0, I_CVTPD2PS }, + { "cvtpi2pd", TOKEN_INSN, C_none, 0, I_CVTPI2PD }, + { "cvtps2dq", TOKEN_INSN, C_none, 0, I_CVTPS2DQ }, + { "cvtps2pd", TOKEN_INSN, C_none, 0, I_CVTPS2PD }, + { "cvtsd2si", TOKEN_INSN, C_none, 0, I_CVTSD2SI }, + { "cvtsd2ss", TOKEN_INSN, C_none, 0, I_CVTSD2SS }, + { "cvtsi2sd", TOKEN_INSN, C_none, 0, I_CVTSI2SD }, + { "cvtss2sd", TOKEN_INSN, C_none, 0, I_CVTSS2SD }, + { "cvttpd2pi", TOKEN_INSN, C_none, 0, I_CVTTPD2PI }, + { "cvttpd2dq", TOKEN_INSN, C_none, 0, I_CVTTPD2DQ }, + { "cvttps2dq", TOKEN_INSN, C_none, 0, I_CVTTPS2DQ }, + { "cvttsd2si", TOKEN_INSN, C_none, 0, I_CVTTSD2SI }, + { "divpd", TOKEN_INSN, C_none, 0, I_DIVPD }, + { "divsd", TOKEN_INSN, C_none, 0, I_DIVSD }, + { "maxpd", TOKEN_INSN, C_none, 0, I_MAXPD }, + { "maxsd", TOKEN_INSN, C_none, 0, I_MAXSD }, + { "minpd", TOKEN_INSN, C_none, 0, I_MINPD }, + { "minsd", TOKEN_INSN, C_none, 0, I_MINSD }, + { "movapd", TOKEN_INSN, C_none, 0, I_MOVAPD }, + { "movhpd", TOKEN_INSN, C_none, 0, I_MOVHPD }, + { "movlpd", TOKEN_INSN, C_none, 0, I_MOVLPD }, + { "movmskpd", TOKEN_INSN, C_none, 0, I_MOVMSKPD }, + { "movupd", TOKEN_INSN, C_none, 0, I_MOVUPD }, + { "mulpd", TOKEN_INSN, C_none, 0, I_MULPD }, + { "mulsd", TOKEN_INSN, C_none, 0, I_MULSD }, + { "orpd", TOKEN_INSN, C_none, 0, I_ORPD }, + { "shufpd", TOKEN_INSN, C_none, 0, I_SHUFPD }, + { "sqrtpd", TOKEN_INSN, C_none, 0, I_SQRTPD }, + { "sqrtsd", TOKEN_INSN, C_none, 0, I_SQRTSD }, + { "subpd", TOKEN_INSN, C_none, 0, I_SUBPD }, + { "subsd", TOKEN_INSN, C_none, 0, I_SUBSD }, + { "ucomisd", TOKEN_INSN, C_none, 0, I_UCOMISD }, + { "unpckhpd", TOKEN_INSN, C_none, 0, I_UNPCKHPD }, + { "unpcklpd", TOKEN_INSN, C_none, 0, I_UNPCKLPD }, + { "xorpd", TOKEN_INSN, C_none, 0, I_XORPD }, + { "addsubpd", TOKEN_INSN, C_none, 0, I_ADDSUBPD }, + { "addsubps", TOKEN_INSN, C_none, 0, I_ADDSUBPS }, + { "haddpd", TOKEN_INSN, C_none, 0, I_HADDPD }, + { "haddps", TOKEN_INSN, C_none, 0, I_HADDPS }, + { "hsubpd", TOKEN_INSN, C_none, 0, I_HSUBPD }, + { "hsubps", TOKEN_INSN, C_none, 0, I_HSUBPS }, + { "lddqu", TOKEN_INSN, C_none, 0, I_LDDQU }, + { "movddup", TOKEN_INSN, C_none, 0, I_MOVDDUP }, + { "movshdup", TOKEN_INSN, C_none, 0, I_MOVSHDUP }, + { "movsldup", TOKEN_INSN, C_none, 0, I_MOVSLDUP }, + { "clgi", TOKEN_INSN, C_none, 0, I_CLGI }, + { "stgi", TOKEN_INSN, C_none, 0, I_STGI }, + { "vmcall", TOKEN_INSN, C_none, 0, I_VMCALL }, + { "vmclear", TOKEN_INSN, C_none, 0, I_VMCLEAR }, + { "vmfunc", TOKEN_INSN, C_none, 0, I_VMFUNC }, + { "vmlaunch", TOKEN_INSN, C_none, 0, I_VMLAUNCH }, + { "vmload", TOKEN_INSN, C_none, 0, I_VMLOAD }, + { "vmmcall", TOKEN_INSN, C_none, 0, I_VMMCALL }, + { "vmptrld", TOKEN_INSN, C_none, 0, I_VMPTRLD }, + { "vmptrst", TOKEN_INSN, C_none, 0, I_VMPTRST }, + { "vmread", TOKEN_INSN, C_none, 0, I_VMREAD }, + { "vmresume", TOKEN_INSN, C_none, 0, I_VMRESUME }, + { "vmrun", TOKEN_INSN, C_none, 0, I_VMRUN }, + { "vmsave", TOKEN_INSN, C_none, 0, I_VMSAVE }, + { "vmwrite", TOKEN_INSN, C_none, 0, I_VMWRITE }, + { "vmxoff", TOKEN_INSN, C_none, 0, I_VMXOFF }, + { "vmxon", TOKEN_INSN, C_none, 0, I_VMXON }, + { "invept", TOKEN_INSN, C_none, 0, I_INVEPT }, + { "invvpid", TOKEN_INSN, C_none, 0, I_INVVPID }, + { "pabsb", TOKEN_INSN, C_none, 0, I_PABSB }, + { "pabsw", TOKEN_INSN, C_none, 0, I_PABSW }, + { "pabsd", TOKEN_INSN, C_none, 0, I_PABSD }, + { "palignr", TOKEN_INSN, C_none, 0, I_PALIGNR }, + { "phaddw", TOKEN_INSN, C_none, 0, I_PHADDW }, + { "phaddd", TOKEN_INSN, C_none, 0, I_PHADDD }, + { "phaddsw", TOKEN_INSN, C_none, 0, I_PHADDSW }, + { "phsubw", TOKEN_INSN, C_none, 0, I_PHSUBW }, + { "phsubd", TOKEN_INSN, C_none, 0, I_PHSUBD }, + { "phsubsw", TOKEN_INSN, C_none, 0, I_PHSUBSW }, + { "pmaddubsw", TOKEN_INSN, C_none, 0, I_PMADDUBSW }, + { "pmulhrsw", TOKEN_INSN, C_none, 0, I_PMULHRSW }, + { "pshufb", TOKEN_INSN, C_none, 0, I_PSHUFB }, + { "psignb", TOKEN_INSN, C_none, 0, I_PSIGNB }, + { "psignw", TOKEN_INSN, C_none, 0, I_PSIGNW }, + { "psignd", TOKEN_INSN, C_none, 0, I_PSIGND }, + { "extrq", TOKEN_INSN, C_none, 0, I_EXTRQ }, + { "insertq", TOKEN_INSN, C_none, 0, I_INSERTQ }, + { "movntsd", TOKEN_INSN, C_none, 0, I_MOVNTSD }, + { "movntss", TOKEN_INSN, C_none, 0, I_MOVNTSS }, + { "lzcnt", TOKEN_INSN, C_none, 0, I_LZCNT }, + { "blendpd", TOKEN_INSN, C_none, 0, I_BLENDPD }, + { "blendps", TOKEN_INSN, C_none, 0, I_BLENDPS }, + { "blendvpd", TOKEN_INSN, C_none, 0, I_BLENDVPD }, + { "blendvps", TOKEN_INSN, C_none, 0, I_BLENDVPS }, + { "dppd", TOKEN_INSN, C_none, 0, I_DPPD }, + { "dpps", TOKEN_INSN, C_none, 0, I_DPPS }, + { "extractps", TOKEN_INSN, C_none, 0, I_EXTRACTPS }, + { "insertps", TOKEN_INSN, C_none, 0, I_INSERTPS }, + { "movntdqa", TOKEN_INSN, C_none, 0, I_MOVNTDQA }, + { "mpsadbw", TOKEN_INSN, C_none, 0, I_MPSADBW }, + { "packusdw", TOKEN_INSN, C_none, 0, I_PACKUSDW }, + { "pblendvb", TOKEN_INSN, C_none, 0, I_PBLENDVB }, + { "pblendw", TOKEN_INSN, C_none, 0, I_PBLENDW }, + { "pcmpeqq", TOKEN_INSN, C_none, 0, I_PCMPEQQ }, + { "pextrb", TOKEN_INSN, C_none, 0, I_PEXTRB }, + { "pextrd", TOKEN_INSN, C_none, 0, I_PEXTRD }, + { "pextrq", TOKEN_INSN, C_none, 0, I_PEXTRQ }, + { "phminposuw", TOKEN_INSN, C_none, 0, I_PHMINPOSUW }, + { "pinsrb", TOKEN_INSN, C_none, 0, I_PINSRB }, + { "pinsrd", TOKEN_INSN, C_none, 0, I_PINSRD }, + { "pinsrq", TOKEN_INSN, C_none, 0, I_PINSRQ }, + { "pmaxsb", TOKEN_INSN, C_none, 0, I_PMAXSB }, + { "pmaxsd", TOKEN_INSN, C_none, 0, I_PMAXSD }, + { "pmaxud", TOKEN_INSN, C_none, 0, I_PMAXUD }, + { "pmaxuw", TOKEN_INSN, C_none, 0, I_PMAXUW }, + { "pminsb", TOKEN_INSN, C_none, 0, I_PMINSB }, + { "pminsd", TOKEN_INSN, C_none, 0, I_PMINSD }, + { "pminud", TOKEN_INSN, C_none, 0, I_PMINUD }, + { "pminuw", TOKEN_INSN, C_none, 0, I_PMINUW }, + { "pmovsxbw", TOKEN_INSN, C_none, 0, I_PMOVSXBW }, + { "pmovsxbd", TOKEN_INSN, C_none, 0, I_PMOVSXBD }, + { "pmovsxbq", TOKEN_INSN, C_none, 0, I_PMOVSXBQ }, + { "pmovsxwd", TOKEN_INSN, C_none, 0, I_PMOVSXWD }, + { "pmovsxwq", TOKEN_INSN, C_none, 0, I_PMOVSXWQ }, + { "pmovsxdq", TOKEN_INSN, C_none, 0, I_PMOVSXDQ }, + { "pmovzxbw", TOKEN_INSN, C_none, 0, I_PMOVZXBW }, + { "pmovzxbd", TOKEN_INSN, C_none, 0, I_PMOVZXBD }, + { "pmovzxbq", TOKEN_INSN, C_none, 0, I_PMOVZXBQ }, + { "pmovzxwd", TOKEN_INSN, C_none, 0, I_PMOVZXWD }, + { "pmovzxwq", TOKEN_INSN, C_none, 0, I_PMOVZXWQ }, + { "pmovzxdq", TOKEN_INSN, C_none, 0, I_PMOVZXDQ }, + { "pmuldq", TOKEN_INSN, C_none, 0, I_PMULDQ }, + { "pmulld", TOKEN_INSN, C_none, 0, I_PMULLD }, + { "ptest", TOKEN_INSN, C_none, 0, I_PTEST }, + { "roundpd", TOKEN_INSN, C_none, 0, I_ROUNDPD }, + { "roundps", TOKEN_INSN, C_none, 0, I_ROUNDPS }, + { "roundsd", TOKEN_INSN, C_none, 0, I_ROUNDSD }, + { "roundss", TOKEN_INSN, C_none, 0, I_ROUNDSS }, + { "crc32", TOKEN_INSN, C_none, 0, I_CRC32 }, + { "pcmpestri", TOKEN_INSN, C_none, 0, I_PCMPESTRI }, + { "pcmpestrm", TOKEN_INSN, C_none, 0, I_PCMPESTRM }, + { "pcmpistri", TOKEN_INSN, C_none, 0, I_PCMPISTRI }, + { "pcmpistrm", TOKEN_INSN, C_none, 0, I_PCMPISTRM }, + { "pcmpgtq", TOKEN_INSN, C_none, 0, I_PCMPGTQ }, + { "popcnt", TOKEN_INSN, C_none, 0, I_POPCNT }, + { "getsec", TOKEN_INSN, C_none, 0, I_GETSEC }, + { "pfrcpv", TOKEN_INSN, C_none, 0, I_PFRCPV }, + { "pfrsqrtv", TOKEN_INSN, C_none, 0, I_PFRSQRTV }, + { "movbe", TOKEN_INSN, C_none, 0, I_MOVBE }, + { "aesenc", TOKEN_INSN, C_none, 0, I_AESENC }, + { "aesenclast", TOKEN_INSN, C_none, 0, I_AESENCLAST }, + { "aesdec", TOKEN_INSN, C_none, 0, I_AESDEC }, + { "aesdeclast", TOKEN_INSN, C_none, 0, I_AESDECLAST }, + { "aesimc", TOKEN_INSN, C_none, 0, I_AESIMC }, + { "aeskeygenassist", TOKEN_INSN, C_none, 0, I_AESKEYGENASSIST }, + { "vaesenc", TOKEN_INSN, C_none, 0, I_VAESENC }, + { "vaesenclast", TOKEN_INSN, C_none, 0, I_VAESENCLAST }, + { "vaesdec", TOKEN_INSN, C_none, 0, I_VAESDEC }, + { "vaesdeclast", TOKEN_INSN, C_none, 0, I_VAESDECLAST }, + { "vaesimc", TOKEN_INSN, C_none, 0, I_VAESIMC }, + { "vaeskeygenassist", TOKEN_INSN, C_none, 0, I_VAESKEYGENASSIST }, + { "vaddpd", TOKEN_INSN, C_none, 0, I_VADDPD }, + { "vaddps", TOKEN_INSN, C_none, 0, I_VADDPS }, + { "vaddsd", TOKEN_INSN, C_none, 0, I_VADDSD }, + { "vaddss", TOKEN_INSN, C_none, 0, I_VADDSS }, + { "vaddsubpd", TOKEN_INSN, C_none, 0, I_VADDSUBPD }, + { "vaddsubps", TOKEN_INSN, C_none, 0, I_VADDSUBPS }, + { "vandpd", TOKEN_INSN, C_none, 0, I_VANDPD }, + { "vandps", TOKEN_INSN, C_none, 0, I_VANDPS }, + { "vandnpd", TOKEN_INSN, C_none, 0, I_VANDNPD }, + { "vandnps", TOKEN_INSN, C_none, 0, I_VANDNPS }, + { "vblendpd", TOKEN_INSN, C_none, 0, I_VBLENDPD }, + { "vblendps", TOKEN_INSN, C_none, 0, I_VBLENDPS }, + { "vblendvpd", TOKEN_INSN, C_none, 0, I_VBLENDVPD }, + { "vblendvps", TOKEN_INSN, C_none, 0, I_VBLENDVPS }, + { "vbroadcastss", TOKEN_INSN, C_none, 0, I_VBROADCASTSS }, + { "vbroadcastsd", TOKEN_INSN, C_none, 0, I_VBROADCASTSD }, + { "vbroadcastf128", TOKEN_INSN, C_none, 0, I_VBROADCASTF128 }, + { "vcmpeq_ospd", TOKEN_INSN, C_none, 0, I_VCMPEQ_OSPD }, + { "vcmpeqpd", TOKEN_INSN, C_none, 0, I_VCMPEQPD }, + { "vcmplt_ospd", TOKEN_INSN, C_none, 0, I_VCMPLT_OSPD }, + { "vcmpltpd", TOKEN_INSN, C_none, 0, I_VCMPLTPD }, + { "vcmple_ospd", TOKEN_INSN, C_none, 0, I_VCMPLE_OSPD }, + { "vcmplepd", TOKEN_INSN, C_none, 0, I_VCMPLEPD }, + { "vcmpunord_qpd", TOKEN_INSN, C_none, 0, I_VCMPUNORD_QPD }, + { "vcmpunordpd", TOKEN_INSN, C_none, 0, I_VCMPUNORDPD }, + { "vcmpneq_uqpd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_UQPD }, + { "vcmpneqpd", TOKEN_INSN, C_none, 0, I_VCMPNEQPD }, + { "vcmpnlt_uspd", TOKEN_INSN, C_none, 0, I_VCMPNLT_USPD }, + { "vcmpnltpd", TOKEN_INSN, C_none, 0, I_VCMPNLTPD }, + { "vcmpnle_uspd", TOKEN_INSN, C_none, 0, I_VCMPNLE_USPD }, + { "vcmpnlepd", TOKEN_INSN, C_none, 0, I_VCMPNLEPD }, + { "vcmpord_qpd", TOKEN_INSN, C_none, 0, I_VCMPORD_QPD }, + { "vcmpordpd", TOKEN_INSN, C_none, 0, I_VCMPORDPD }, + { "vcmpeq_uqpd", TOKEN_INSN, C_none, 0, I_VCMPEQ_UQPD }, + { "vcmpnge_uspd", TOKEN_INSN, C_none, 0, I_VCMPNGE_USPD }, + { "vcmpngepd", TOKEN_INSN, C_none, 0, I_VCMPNGEPD }, + { "vcmpngt_uspd", TOKEN_INSN, C_none, 0, I_VCMPNGT_USPD }, + { "vcmpngtpd", TOKEN_INSN, C_none, 0, I_VCMPNGTPD }, + { "vcmpfalse_oqpd", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OQPD }, + { "vcmpfalsepd", TOKEN_INSN, C_none, 0, I_VCMPFALSEPD }, + { "vcmpneq_oqpd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OQPD }, + { "vcmpge_ospd", TOKEN_INSN, C_none, 0, I_VCMPGE_OSPD }, + { "vcmpgepd", TOKEN_INSN, C_none, 0, I_VCMPGEPD }, + { "vcmpgt_ospd", TOKEN_INSN, C_none, 0, I_VCMPGT_OSPD }, + { "vcmpgtpd", TOKEN_INSN, C_none, 0, I_VCMPGTPD }, + { "vcmptrue_uqpd", TOKEN_INSN, C_none, 0, I_VCMPTRUE_UQPD }, + { "vcmptruepd", TOKEN_INSN, C_none, 0, I_VCMPTRUEPD }, + { "vcmplt_oqpd", TOKEN_INSN, C_none, 0, I_VCMPLT_OQPD }, + { "vcmple_oqpd", TOKEN_INSN, C_none, 0, I_VCMPLE_OQPD }, + { "vcmpunord_spd", TOKEN_INSN, C_none, 0, I_VCMPUNORD_SPD }, + { "vcmpneq_uspd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_USPD }, + { "vcmpnlt_uqpd", TOKEN_INSN, C_none, 0, I_VCMPNLT_UQPD }, + { "vcmpnle_uqpd", TOKEN_INSN, C_none, 0, I_VCMPNLE_UQPD }, + { "vcmpord_spd", TOKEN_INSN, C_none, 0, I_VCMPORD_SPD }, + { "vcmpeq_uspd", TOKEN_INSN, C_none, 0, I_VCMPEQ_USPD }, + { "vcmpnge_uqpd", TOKEN_INSN, C_none, 0, I_VCMPNGE_UQPD }, + { "vcmpngt_uqpd", TOKEN_INSN, C_none, 0, I_VCMPNGT_UQPD }, + { "vcmpfalse_ospd", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OSPD }, + { "vcmpneq_ospd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OSPD }, + { "vcmpge_oqpd", TOKEN_INSN, C_none, 0, I_VCMPGE_OQPD }, + { "vcmpgt_oqpd", TOKEN_INSN, C_none, 0, I_VCMPGT_OQPD }, + { "vcmptrue_uspd", TOKEN_INSN, C_none, 0, I_VCMPTRUE_USPD }, + { "vcmppd", TOKEN_INSN, C_none, 0, I_VCMPPD }, + { "vcmpeq_osps", TOKEN_INSN, C_none, 0, I_VCMPEQ_OSPS }, + { "vcmpeqps", TOKEN_INSN, C_none, 0, I_VCMPEQPS }, + { "vcmplt_osps", TOKEN_INSN, C_none, 0, I_VCMPLT_OSPS }, + { "vcmpltps", TOKEN_INSN, C_none, 0, I_VCMPLTPS }, + { "vcmple_osps", TOKEN_INSN, C_none, 0, I_VCMPLE_OSPS }, + { "vcmpleps", TOKEN_INSN, C_none, 0, I_VCMPLEPS }, + { "vcmpunord_qps", TOKEN_INSN, C_none, 0, I_VCMPUNORD_QPS }, + { "vcmpunordps", TOKEN_INSN, C_none, 0, I_VCMPUNORDPS }, + { "vcmpneq_uqps", TOKEN_INSN, C_none, 0, I_VCMPNEQ_UQPS }, + { "vcmpneqps", TOKEN_INSN, C_none, 0, I_VCMPNEQPS }, + { "vcmpnlt_usps", TOKEN_INSN, C_none, 0, I_VCMPNLT_USPS }, + { "vcmpnltps", TOKEN_INSN, C_none, 0, I_VCMPNLTPS }, + { "vcmpnle_usps", TOKEN_INSN, C_none, 0, I_VCMPNLE_USPS }, + { "vcmpnleps", TOKEN_INSN, C_none, 0, I_VCMPNLEPS }, + { "vcmpord_qps", TOKEN_INSN, C_none, 0, I_VCMPORD_QPS }, + { "vcmpordps", TOKEN_INSN, C_none, 0, I_VCMPORDPS }, + { "vcmpeq_uqps", TOKEN_INSN, C_none, 0, I_VCMPEQ_UQPS }, + { "vcmpnge_usps", TOKEN_INSN, C_none, 0, I_VCMPNGE_USPS }, + { "vcmpngeps", TOKEN_INSN, C_none, 0, I_VCMPNGEPS }, + { "vcmpngt_usps", TOKEN_INSN, C_none, 0, I_VCMPNGT_USPS }, + { "vcmpngtps", TOKEN_INSN, C_none, 0, I_VCMPNGTPS }, + { "vcmpfalse_oqps", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OQPS }, + { "vcmpfalseps", TOKEN_INSN, C_none, 0, I_VCMPFALSEPS }, + { "vcmpneq_oqps", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OQPS }, + { "vcmpge_osps", TOKEN_INSN, C_none, 0, I_VCMPGE_OSPS }, + { "vcmpgeps", TOKEN_INSN, C_none, 0, I_VCMPGEPS }, + { "vcmpgt_osps", TOKEN_INSN, C_none, 0, I_VCMPGT_OSPS }, + { "vcmpgtps", TOKEN_INSN, C_none, 0, I_VCMPGTPS }, + { "vcmptrue_uqps", TOKEN_INSN, C_none, 0, I_VCMPTRUE_UQPS }, + { "vcmptrueps", TOKEN_INSN, C_none, 0, I_VCMPTRUEPS }, + { "vcmplt_oqps", TOKEN_INSN, C_none, 0, I_VCMPLT_OQPS }, + { "vcmple_oqps", TOKEN_INSN, C_none, 0, I_VCMPLE_OQPS }, + { "vcmpunord_sps", TOKEN_INSN, C_none, 0, I_VCMPUNORD_SPS }, + { "vcmpneq_usps", TOKEN_INSN, C_none, 0, I_VCMPNEQ_USPS }, + { "vcmpnlt_uqps", TOKEN_INSN, C_none, 0, I_VCMPNLT_UQPS }, + { "vcmpnle_uqps", TOKEN_INSN, C_none, 0, I_VCMPNLE_UQPS }, + { "vcmpord_sps", TOKEN_INSN, C_none, 0, I_VCMPORD_SPS }, + { "vcmpeq_usps", TOKEN_INSN, C_none, 0, I_VCMPEQ_USPS }, + { "vcmpnge_uqps", TOKEN_INSN, C_none, 0, I_VCMPNGE_UQPS }, + { "vcmpngt_uqps", TOKEN_INSN, C_none, 0, I_VCMPNGT_UQPS }, + { "vcmpfalse_osps", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OSPS }, + { "vcmpneq_osps", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OSPS }, + { "vcmpge_oqps", TOKEN_INSN, C_none, 0, I_VCMPGE_OQPS }, + { "vcmpgt_oqps", TOKEN_INSN, C_none, 0, I_VCMPGT_OQPS }, + { "vcmptrue_usps", TOKEN_INSN, C_none, 0, I_VCMPTRUE_USPS }, + { "vcmpps", TOKEN_INSN, C_none, 0, I_VCMPPS }, + { "vcmpeq_ossd", TOKEN_INSN, C_none, 0, I_VCMPEQ_OSSD }, + { "vcmpeqsd", TOKEN_INSN, C_none, 0, I_VCMPEQSD }, + { "vcmplt_ossd", TOKEN_INSN, C_none, 0, I_VCMPLT_OSSD }, + { "vcmpltsd", TOKEN_INSN, C_none, 0, I_VCMPLTSD }, + { "vcmple_ossd", TOKEN_INSN, C_none, 0, I_VCMPLE_OSSD }, + { "vcmplesd", TOKEN_INSN, C_none, 0, I_VCMPLESD }, + { "vcmpunord_qsd", TOKEN_INSN, C_none, 0, I_VCMPUNORD_QSD }, + { "vcmpunordsd", TOKEN_INSN, C_none, 0, I_VCMPUNORDSD }, + { "vcmpneq_uqsd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_UQSD }, + { "vcmpneqsd", TOKEN_INSN, C_none, 0, I_VCMPNEQSD }, + { "vcmpnlt_ussd", TOKEN_INSN, C_none, 0, I_VCMPNLT_USSD }, + { "vcmpnltsd", TOKEN_INSN, C_none, 0, I_VCMPNLTSD }, + { "vcmpnle_ussd", TOKEN_INSN, C_none, 0, I_VCMPNLE_USSD }, + { "vcmpnlesd", TOKEN_INSN, C_none, 0, I_VCMPNLESD }, + { "vcmpord_qsd", TOKEN_INSN, C_none, 0, I_VCMPORD_QSD }, + { "vcmpordsd", TOKEN_INSN, C_none, 0, I_VCMPORDSD }, + { "vcmpeq_uqsd", TOKEN_INSN, C_none, 0, I_VCMPEQ_UQSD }, + { "vcmpnge_ussd", TOKEN_INSN, C_none, 0, I_VCMPNGE_USSD }, + { "vcmpngesd", TOKEN_INSN, C_none, 0, I_VCMPNGESD }, + { "vcmpngt_ussd", TOKEN_INSN, C_none, 0, I_VCMPNGT_USSD }, + { "vcmpngtsd", TOKEN_INSN, C_none, 0, I_VCMPNGTSD }, + { "vcmpfalse_oqsd", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OQSD }, + { "vcmpfalsesd", TOKEN_INSN, C_none, 0, I_VCMPFALSESD }, + { "vcmpneq_oqsd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OQSD }, + { "vcmpge_ossd", TOKEN_INSN, C_none, 0, I_VCMPGE_OSSD }, + { "vcmpgesd", TOKEN_INSN, C_none, 0, I_VCMPGESD }, + { "vcmpgt_ossd", TOKEN_INSN, C_none, 0, I_VCMPGT_OSSD }, + { "vcmpgtsd", TOKEN_INSN, C_none, 0, I_VCMPGTSD }, + { "vcmptrue_uqsd", TOKEN_INSN, C_none, 0, I_VCMPTRUE_UQSD }, + { "vcmptruesd", TOKEN_INSN, C_none, 0, I_VCMPTRUESD }, + { "vcmplt_oqsd", TOKEN_INSN, C_none, 0, I_VCMPLT_OQSD }, + { "vcmple_oqsd", TOKEN_INSN, C_none, 0, I_VCMPLE_OQSD }, + { "vcmpunord_ssd", TOKEN_INSN, C_none, 0, I_VCMPUNORD_SSD }, + { "vcmpneq_ussd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_USSD }, + { "vcmpnlt_uqsd", TOKEN_INSN, C_none, 0, I_VCMPNLT_UQSD }, + { "vcmpnle_uqsd", TOKEN_INSN, C_none, 0, I_VCMPNLE_UQSD }, + { "vcmpord_ssd", TOKEN_INSN, C_none, 0, I_VCMPORD_SSD }, + { "vcmpeq_ussd", TOKEN_INSN, C_none, 0, I_VCMPEQ_USSD }, + { "vcmpnge_uqsd", TOKEN_INSN, C_none, 0, I_VCMPNGE_UQSD }, + { "vcmpngt_uqsd", TOKEN_INSN, C_none, 0, I_VCMPNGT_UQSD }, + { "vcmpfalse_ossd", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OSSD }, + { "vcmpneq_ossd", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OSSD }, + { "vcmpge_oqsd", TOKEN_INSN, C_none, 0, I_VCMPGE_OQSD }, + { "vcmpgt_oqsd", TOKEN_INSN, C_none, 0, I_VCMPGT_OQSD }, + { "vcmptrue_ussd", TOKEN_INSN, C_none, 0, I_VCMPTRUE_USSD }, + { "vcmpsd", TOKEN_INSN, C_none, 0, I_VCMPSD }, + { "vcmpeq_osss", TOKEN_INSN, C_none, 0, I_VCMPEQ_OSSS }, + { "vcmpeqss", TOKEN_INSN, C_none, 0, I_VCMPEQSS }, + { "vcmplt_osss", TOKEN_INSN, C_none, 0, I_VCMPLT_OSSS }, + { "vcmpltss", TOKEN_INSN, C_none, 0, I_VCMPLTSS }, + { "vcmple_osss", TOKEN_INSN, C_none, 0, I_VCMPLE_OSSS }, + { "vcmpless", TOKEN_INSN, C_none, 0, I_VCMPLESS }, + { "vcmpunord_qss", TOKEN_INSN, C_none, 0, I_VCMPUNORD_QSS }, + { "vcmpunordss", TOKEN_INSN, C_none, 0, I_VCMPUNORDSS }, + { "vcmpneq_uqss", TOKEN_INSN, C_none, 0, I_VCMPNEQ_UQSS }, + { "vcmpneqss", TOKEN_INSN, C_none, 0, I_VCMPNEQSS }, + { "vcmpnlt_usss", TOKEN_INSN, C_none, 0, I_VCMPNLT_USSS }, + { "vcmpnltss", TOKEN_INSN, C_none, 0, I_VCMPNLTSS }, + { "vcmpnle_usss", TOKEN_INSN, C_none, 0, I_VCMPNLE_USSS }, + { "vcmpnless", TOKEN_INSN, C_none, 0, I_VCMPNLESS }, + { "vcmpord_qss", TOKEN_INSN, C_none, 0, I_VCMPORD_QSS }, + { "vcmpordss", TOKEN_INSN, C_none, 0, I_VCMPORDSS }, + { "vcmpeq_uqss", TOKEN_INSN, C_none, 0, I_VCMPEQ_UQSS }, + { "vcmpnge_usss", TOKEN_INSN, C_none, 0, I_VCMPNGE_USSS }, + { "vcmpngess", TOKEN_INSN, C_none, 0, I_VCMPNGESS }, + { "vcmpngt_usss", TOKEN_INSN, C_none, 0, I_VCMPNGT_USSS }, + { "vcmpngtss", TOKEN_INSN, C_none, 0, I_VCMPNGTSS }, + { "vcmpfalse_oqss", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OQSS }, + { "vcmpfalsess", TOKEN_INSN, C_none, 0, I_VCMPFALSESS }, + { "vcmpneq_oqss", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OQSS }, + { "vcmpge_osss", TOKEN_INSN, C_none, 0, I_VCMPGE_OSSS }, + { "vcmpgess", TOKEN_INSN, C_none, 0, I_VCMPGESS }, + { "vcmpgt_osss", TOKEN_INSN, C_none, 0, I_VCMPGT_OSSS }, + { "vcmpgtss", TOKEN_INSN, C_none, 0, I_VCMPGTSS }, + { "vcmptrue_uqss", TOKEN_INSN, C_none, 0, I_VCMPTRUE_UQSS }, + { "vcmptruess", TOKEN_INSN, C_none, 0, I_VCMPTRUESS }, + { "vcmplt_oqss", TOKEN_INSN, C_none, 0, I_VCMPLT_OQSS }, + { "vcmple_oqss", TOKEN_INSN, C_none, 0, I_VCMPLE_OQSS }, + { "vcmpunord_sss", TOKEN_INSN, C_none, 0, I_VCMPUNORD_SSS }, + { "vcmpneq_usss", TOKEN_INSN, C_none, 0, I_VCMPNEQ_USSS }, + { "vcmpnlt_uqss", TOKEN_INSN, C_none, 0, I_VCMPNLT_UQSS }, + { "vcmpnle_uqss", TOKEN_INSN, C_none, 0, I_VCMPNLE_UQSS }, + { "vcmpord_sss", TOKEN_INSN, C_none, 0, I_VCMPORD_SSS }, + { "vcmpeq_usss", TOKEN_INSN, C_none, 0, I_VCMPEQ_USSS }, + { "vcmpnge_uqss", TOKEN_INSN, C_none, 0, I_VCMPNGE_UQSS }, + { "vcmpngt_uqss", TOKEN_INSN, C_none, 0, I_VCMPNGT_UQSS }, + { "vcmpfalse_osss", TOKEN_INSN, C_none, 0, I_VCMPFALSE_OSSS }, + { "vcmpneq_osss", TOKEN_INSN, C_none, 0, I_VCMPNEQ_OSSS }, + { "vcmpge_oqss", TOKEN_INSN, C_none, 0, I_VCMPGE_OQSS }, + { "vcmpgt_oqss", TOKEN_INSN, C_none, 0, I_VCMPGT_OQSS }, + { "vcmptrue_usss", TOKEN_INSN, C_none, 0, I_VCMPTRUE_USSS }, + { "vcmpss", TOKEN_INSN, C_none, 0, I_VCMPSS }, + { "vcomisd", TOKEN_INSN, C_none, 0, I_VCOMISD }, + { "vcomiss", TOKEN_INSN, C_none, 0, I_VCOMISS }, + { "vcvtdq2pd", TOKEN_INSN, C_none, 0, I_VCVTDQ2PD }, + { "vcvtdq2ps", TOKEN_INSN, C_none, 0, I_VCVTDQ2PS }, + { "vcvtpd2dq", TOKEN_INSN, C_none, 0, I_VCVTPD2DQ }, + { "vcvtpd2ps", TOKEN_INSN, C_none, 0, I_VCVTPD2PS }, + { "vcvtps2dq", TOKEN_INSN, C_none, 0, I_VCVTPS2DQ }, + { "vcvtps2pd", TOKEN_INSN, C_none, 0, I_VCVTPS2PD }, + { "vcvtsd2si", TOKEN_INSN, C_none, 0, I_VCVTSD2SI }, + { "vcvtsd2ss", TOKEN_INSN, C_none, 0, I_VCVTSD2SS }, + { "vcvtsi2sd", TOKEN_INSN, C_none, 0, I_VCVTSI2SD }, + { "vcvtsi2ss", TOKEN_INSN, C_none, 0, I_VCVTSI2SS }, + { "vcvtss2sd", TOKEN_INSN, C_none, 0, I_VCVTSS2SD }, + { "vcvtss2si", TOKEN_INSN, C_none, 0, I_VCVTSS2SI }, + { "vcvttpd2dq", TOKEN_INSN, C_none, 0, I_VCVTTPD2DQ }, + { "vcvttps2dq", TOKEN_INSN, C_none, 0, I_VCVTTPS2DQ }, + { "vcvttsd2si", TOKEN_INSN, C_none, 0, I_VCVTTSD2SI }, + { "vcvttss2si", TOKEN_INSN, C_none, 0, I_VCVTTSS2SI }, + { "vdivpd", TOKEN_INSN, C_none, 0, I_VDIVPD }, + { "vdivps", TOKEN_INSN, C_none, 0, I_VDIVPS }, + { "vdivsd", TOKEN_INSN, C_none, 0, I_VDIVSD }, + { "vdivss", TOKEN_INSN, C_none, 0, I_VDIVSS }, + { "vdppd", TOKEN_INSN, C_none, 0, I_VDPPD }, + { "vdpps", TOKEN_INSN, C_none, 0, I_VDPPS }, + { "vextractf128", TOKEN_INSN, C_none, 0, I_VEXTRACTF128 }, + { "vextractps", TOKEN_INSN, C_none, 0, I_VEXTRACTPS }, + { "vhaddpd", TOKEN_INSN, C_none, 0, I_VHADDPD }, + { "vhaddps", TOKEN_INSN, C_none, 0, I_VHADDPS }, + { "vhsubpd", TOKEN_INSN, C_none, 0, I_VHSUBPD }, + { "vhsubps", TOKEN_INSN, C_none, 0, I_VHSUBPS }, + { "vinsertf128", TOKEN_INSN, C_none, 0, I_VINSERTF128 }, + { "vinsertps", TOKEN_INSN, C_none, 0, I_VINSERTPS }, + { "vlddqu", TOKEN_INSN, C_none, 0, I_VLDDQU }, + { "vldqqu", TOKEN_INSN, C_none, 0, I_VLDQQU }, + { "vldmxcsr", TOKEN_INSN, C_none, 0, I_VLDMXCSR }, + { "vmaskmovdqu", TOKEN_INSN, C_none, 0, I_VMASKMOVDQU }, + { "vmaskmovps", TOKEN_INSN, C_none, 0, I_VMASKMOVPS }, + { "vmaskmovpd", TOKEN_INSN, C_none, 0, I_VMASKMOVPD }, + { "vmaxpd", TOKEN_INSN, C_none, 0, I_VMAXPD }, + { "vmaxps", TOKEN_INSN, C_none, 0, I_VMAXPS }, + { "vmaxsd", TOKEN_INSN, C_none, 0, I_VMAXSD }, + { "vmaxss", TOKEN_INSN, C_none, 0, I_VMAXSS }, + { "vminpd", TOKEN_INSN, C_none, 0, I_VMINPD }, + { "vminps", TOKEN_INSN, C_none, 0, I_VMINPS }, + { "vminsd", TOKEN_INSN, C_none, 0, I_VMINSD }, + { "vminss", TOKEN_INSN, C_none, 0, I_VMINSS }, + { "vmovapd", TOKEN_INSN, C_none, 0, I_VMOVAPD }, + { "vmovaps", TOKEN_INSN, C_none, 0, I_VMOVAPS }, + { "vmovd", TOKEN_INSN, C_none, 0, I_VMOVD }, + { "vmovq", TOKEN_INSN, C_none, 0, I_VMOVQ }, + { "vmovddup", TOKEN_INSN, C_none, 0, I_VMOVDDUP }, + { "vmovdqa", TOKEN_INSN, C_none, 0, I_VMOVDQA }, + { "vmovqqa", TOKEN_INSN, C_none, 0, I_VMOVQQA }, + { "vmovdqu", TOKEN_INSN, C_none, 0, I_VMOVDQU }, + { "vmovqqu", TOKEN_INSN, C_none, 0, I_VMOVQQU }, + { "vmovhlps", TOKEN_INSN, C_none, 0, I_VMOVHLPS }, + { "vmovhpd", TOKEN_INSN, C_none, 0, I_VMOVHPD }, + { "vmovhps", TOKEN_INSN, C_none, 0, I_VMOVHPS }, + { "vmovlhps", TOKEN_INSN, C_none, 0, I_VMOVLHPS }, + { "vmovlpd", TOKEN_INSN, C_none, 0, I_VMOVLPD }, + { "vmovlps", TOKEN_INSN, C_none, 0, I_VMOVLPS }, + { "vmovmskpd", TOKEN_INSN, C_none, 0, I_VMOVMSKPD }, + { "vmovmskps", TOKEN_INSN, C_none, 0, I_VMOVMSKPS }, + { "vmovntdq", TOKEN_INSN, C_none, 0, I_VMOVNTDQ }, + { "vmovntqq", TOKEN_INSN, C_none, 0, I_VMOVNTQQ }, + { "vmovntdqa", TOKEN_INSN, C_none, 0, I_VMOVNTDQA }, + { "vmovntpd", TOKEN_INSN, C_none, 0, I_VMOVNTPD }, + { "vmovntps", TOKEN_INSN, C_none, 0, I_VMOVNTPS }, + { "vmovsd", TOKEN_INSN, C_none, 0, I_VMOVSD }, + { "vmovshdup", TOKEN_INSN, C_none, 0, I_VMOVSHDUP }, + { "vmovsldup", TOKEN_INSN, C_none, 0, I_VMOVSLDUP }, + { "vmovss", TOKEN_INSN, C_none, 0, I_VMOVSS }, + { "vmovupd", TOKEN_INSN, C_none, 0, I_VMOVUPD }, + { "vmovups", TOKEN_INSN, C_none, 0, I_VMOVUPS }, + { "vmpsadbw", TOKEN_INSN, C_none, 0, I_VMPSADBW }, + { "vmulpd", TOKEN_INSN, C_none, 0, I_VMULPD }, + { "vmulps", TOKEN_INSN, C_none, 0, I_VMULPS }, + { "vmulsd", TOKEN_INSN, C_none, 0, I_VMULSD }, + { "vmulss", TOKEN_INSN, C_none, 0, I_VMULSS }, + { "vorpd", TOKEN_INSN, C_none, 0, I_VORPD }, + { "vorps", TOKEN_INSN, C_none, 0, I_VORPS }, + { "vpabsb", TOKEN_INSN, C_none, 0, I_VPABSB }, + { "vpabsw", TOKEN_INSN, C_none, 0, I_VPABSW }, + { "vpabsd", TOKEN_INSN, C_none, 0, I_VPABSD }, + { "vpacksswb", TOKEN_INSN, C_none, 0, I_VPACKSSWB }, + { "vpackssdw", TOKEN_INSN, C_none, 0, I_VPACKSSDW }, + { "vpackuswb", TOKEN_INSN, C_none, 0, I_VPACKUSWB }, + { "vpackusdw", TOKEN_INSN, C_none, 0, I_VPACKUSDW }, + { "vpaddb", TOKEN_INSN, C_none, 0, I_VPADDB }, + { "vpaddw", TOKEN_INSN, C_none, 0, I_VPADDW }, + { "vpaddd", TOKEN_INSN, C_none, 0, I_VPADDD }, + { "vpaddq", TOKEN_INSN, C_none, 0, I_VPADDQ }, + { "vpaddsb", TOKEN_INSN, C_none, 0, I_VPADDSB }, + { "vpaddsw", TOKEN_INSN, C_none, 0, I_VPADDSW }, + { "vpaddusb", TOKEN_INSN, C_none, 0, I_VPADDUSB }, + { "vpaddusw", TOKEN_INSN, C_none, 0, I_VPADDUSW }, + { "vpalignr", TOKEN_INSN, C_none, 0, I_VPALIGNR }, + { "vpand", TOKEN_INSN, C_none, 0, I_VPAND }, + { "vpandn", TOKEN_INSN, C_none, 0, I_VPANDN }, + { "vpavgb", TOKEN_INSN, C_none, 0, I_VPAVGB }, + { "vpavgw", TOKEN_INSN, C_none, 0, I_VPAVGW }, + { "vpblendvb", TOKEN_INSN, C_none, 0, I_VPBLENDVB }, + { "vpblendw", TOKEN_INSN, C_none, 0, I_VPBLENDW }, + { "vpcmpestri", TOKEN_INSN, C_none, 0, I_VPCMPESTRI }, + { "vpcmpestrm", TOKEN_INSN, C_none, 0, I_VPCMPESTRM }, + { "vpcmpistri", TOKEN_INSN, C_none, 0, I_VPCMPISTRI }, + { "vpcmpistrm", TOKEN_INSN, C_none, 0, I_VPCMPISTRM }, + { "vpcmpeqb", TOKEN_INSN, C_none, 0, I_VPCMPEQB }, + { "vpcmpeqw", TOKEN_INSN, C_none, 0, I_VPCMPEQW }, + { "vpcmpeqd", TOKEN_INSN, C_none, 0, I_VPCMPEQD }, + { "vpcmpeqq", TOKEN_INSN, C_none, 0, I_VPCMPEQQ }, + { "vpcmpgtb", TOKEN_INSN, C_none, 0, I_VPCMPGTB }, + { "vpcmpgtw", TOKEN_INSN, C_none, 0, I_VPCMPGTW }, + { "vpcmpgtd", TOKEN_INSN, C_none, 0, I_VPCMPGTD }, + { "vpcmpgtq", TOKEN_INSN, C_none, 0, I_VPCMPGTQ }, + { "vpermilpd", TOKEN_INSN, C_none, 0, I_VPERMILPD }, + { "vpermilps", TOKEN_INSN, C_none, 0, I_VPERMILPS }, + { "vperm2f128", TOKEN_INSN, C_none, 0, I_VPERM2F128 }, + { "vpextrb", TOKEN_INSN, C_none, 0, I_VPEXTRB }, + { "vpextrw", TOKEN_INSN, C_none, 0, I_VPEXTRW }, + { "vpextrd", TOKEN_INSN, C_none, 0, I_VPEXTRD }, + { "vpextrq", TOKEN_INSN, C_none, 0, I_VPEXTRQ }, + { "vphaddw", TOKEN_INSN, C_none, 0, I_VPHADDW }, + { "vphaddd", TOKEN_INSN, C_none, 0, I_VPHADDD }, + { "vphaddsw", TOKEN_INSN, C_none, 0, I_VPHADDSW }, + { "vphminposuw", TOKEN_INSN, C_none, 0, I_VPHMINPOSUW }, + { "vphsubw", TOKEN_INSN, C_none, 0, I_VPHSUBW }, + { "vphsubd", TOKEN_INSN, C_none, 0, I_VPHSUBD }, + { "vphsubsw", TOKEN_INSN, C_none, 0, I_VPHSUBSW }, + { "vpinsrb", TOKEN_INSN, C_none, 0, I_VPINSRB }, + { "vpinsrw", TOKEN_INSN, C_none, 0, I_VPINSRW }, + { "vpinsrd", TOKEN_INSN, C_none, 0, I_VPINSRD }, + { "vpinsrq", TOKEN_INSN, C_none, 0, I_VPINSRQ }, + { "vpmaddwd", TOKEN_INSN, C_none, 0, I_VPMADDWD }, + { "vpmaddubsw", TOKEN_INSN, C_none, 0, I_VPMADDUBSW }, + { "vpmaxsb", TOKEN_INSN, C_none, 0, I_VPMAXSB }, + { "vpmaxsw", TOKEN_INSN, C_none, 0, I_VPMAXSW }, + { "vpmaxsd", TOKEN_INSN, C_none, 0, I_VPMAXSD }, + { "vpmaxub", TOKEN_INSN, C_none, 0, I_VPMAXUB }, + { "vpmaxuw", TOKEN_INSN, C_none, 0, I_VPMAXUW }, + { "vpmaxud", TOKEN_INSN, C_none, 0, I_VPMAXUD }, + { "vpminsb", TOKEN_INSN, C_none, 0, I_VPMINSB }, + { "vpminsw", TOKEN_INSN, C_none, 0, I_VPMINSW }, + { "vpminsd", TOKEN_INSN, C_none, 0, I_VPMINSD }, + { "vpminub", TOKEN_INSN, C_none, 0, I_VPMINUB }, + { "vpminuw", TOKEN_INSN, C_none, 0, I_VPMINUW }, + { "vpminud", TOKEN_INSN, C_none, 0, I_VPMINUD }, + { "vpmovmskb", TOKEN_INSN, C_none, 0, I_VPMOVMSKB }, + { "vpmovsxbw", TOKEN_INSN, C_none, 0, I_VPMOVSXBW }, + { "vpmovsxbd", TOKEN_INSN, C_none, 0, I_VPMOVSXBD }, + { "vpmovsxbq", TOKEN_INSN, C_none, 0, I_VPMOVSXBQ }, + { "vpmovsxwd", TOKEN_INSN, C_none, 0, I_VPMOVSXWD }, + { "vpmovsxwq", TOKEN_INSN, C_none, 0, I_VPMOVSXWQ }, + { "vpmovsxdq", TOKEN_INSN, C_none, 0, I_VPMOVSXDQ }, + { "vpmovzxbw", TOKEN_INSN, C_none, 0, I_VPMOVZXBW }, + { "vpmovzxbd", TOKEN_INSN, C_none, 0, I_VPMOVZXBD }, + { "vpmovzxbq", TOKEN_INSN, C_none, 0, I_VPMOVZXBQ }, + { "vpmovzxwd", TOKEN_INSN, C_none, 0, I_VPMOVZXWD }, + { "vpmovzxwq", TOKEN_INSN, C_none, 0, I_VPMOVZXWQ }, + { "vpmovzxdq", TOKEN_INSN, C_none, 0, I_VPMOVZXDQ }, + { "vpmulhuw", TOKEN_INSN, C_none, 0, I_VPMULHUW }, + { "vpmulhrsw", TOKEN_INSN, C_none, 0, I_VPMULHRSW }, + { "vpmulhw", TOKEN_INSN, C_none, 0, I_VPMULHW }, + { "vpmullw", TOKEN_INSN, C_none, 0, I_VPMULLW }, + { "vpmulld", TOKEN_INSN, C_none, 0, I_VPMULLD }, + { "vpmuludq", TOKEN_INSN, C_none, 0, I_VPMULUDQ }, + { "vpmuldq", TOKEN_INSN, C_none, 0, I_VPMULDQ }, + { "vpor", TOKEN_INSN, C_none, 0, I_VPOR }, + { "vpsadbw", TOKEN_INSN, C_none, 0, I_VPSADBW }, + { "vpshufb", TOKEN_INSN, C_none, 0, I_VPSHUFB }, + { "vpshufd", TOKEN_INSN, C_none, 0, I_VPSHUFD }, + { "vpshufhw", TOKEN_INSN, C_none, 0, I_VPSHUFHW }, + { "vpshuflw", TOKEN_INSN, C_none, 0, I_VPSHUFLW }, + { "vpsignb", TOKEN_INSN, C_none, 0, I_VPSIGNB }, + { "vpsignw", TOKEN_INSN, C_none, 0, I_VPSIGNW }, + { "vpsignd", TOKEN_INSN, C_none, 0, I_VPSIGND }, + { "vpslldq", TOKEN_INSN, C_none, 0, I_VPSLLDQ }, + { "vpsrldq", TOKEN_INSN, C_none, 0, I_VPSRLDQ }, + { "vpsllw", TOKEN_INSN, C_none, 0, I_VPSLLW }, + { "vpslld", TOKEN_INSN, C_none, 0, I_VPSLLD }, + { "vpsllq", TOKEN_INSN, C_none, 0, I_VPSLLQ }, + { "vpsraw", TOKEN_INSN, C_none, 0, I_VPSRAW }, + { "vpsrad", TOKEN_INSN, C_none, 0, I_VPSRAD }, + { "vpsrlw", TOKEN_INSN, C_none, 0, I_VPSRLW }, + { "vpsrld", TOKEN_INSN, C_none, 0, I_VPSRLD }, + { "vpsrlq", TOKEN_INSN, C_none, 0, I_VPSRLQ }, + { "vptest", TOKEN_INSN, C_none, 0, I_VPTEST }, + { "vpsubb", TOKEN_INSN, C_none, 0, I_VPSUBB }, + { "vpsubw", TOKEN_INSN, C_none, 0, I_VPSUBW }, + { "vpsubd", TOKEN_INSN, C_none, 0, I_VPSUBD }, + { "vpsubq", TOKEN_INSN, C_none, 0, I_VPSUBQ }, + { "vpsubsb", TOKEN_INSN, C_none, 0, I_VPSUBSB }, + { "vpsubsw", TOKEN_INSN, C_none, 0, I_VPSUBSW }, + { "vpsubusb", TOKEN_INSN, C_none, 0, I_VPSUBUSB }, + { "vpsubusw", TOKEN_INSN, C_none, 0, I_VPSUBUSW }, + { "vpunpckhbw", TOKEN_INSN, C_none, 0, I_VPUNPCKHBW }, + { "vpunpckhwd", TOKEN_INSN, C_none, 0, I_VPUNPCKHWD }, + { "vpunpckhdq", TOKEN_INSN, C_none, 0, I_VPUNPCKHDQ }, + { "vpunpckhqdq", TOKEN_INSN, C_none, 0, I_VPUNPCKHQDQ }, + { "vpunpcklbw", TOKEN_INSN, C_none, 0, I_VPUNPCKLBW }, + { "vpunpcklwd", TOKEN_INSN, C_none, 0, I_VPUNPCKLWD }, + { "vpunpckldq", TOKEN_INSN, C_none, 0, I_VPUNPCKLDQ }, + { "vpunpcklqdq", TOKEN_INSN, C_none, 0, I_VPUNPCKLQDQ }, + { "vpxor", TOKEN_INSN, C_none, 0, I_VPXOR }, + { "vrcpps", TOKEN_INSN, C_none, 0, I_VRCPPS }, + { "vrcpss", TOKEN_INSN, C_none, 0, I_VRCPSS }, + { "vrsqrtps", TOKEN_INSN, C_none, 0, I_VRSQRTPS }, + { "vrsqrtss", TOKEN_INSN, C_none, 0, I_VRSQRTSS }, + { "vroundpd", TOKEN_INSN, C_none, 0, I_VROUNDPD }, + { "vroundps", TOKEN_INSN, C_none, 0, I_VROUNDPS }, + { "vroundsd", TOKEN_INSN, C_none, 0, I_VROUNDSD }, + { "vroundss", TOKEN_INSN, C_none, 0, I_VROUNDSS }, + { "vshufpd", TOKEN_INSN, C_none, 0, I_VSHUFPD }, + { "vshufps", TOKEN_INSN, C_none, 0, I_VSHUFPS }, + { "vsqrtpd", TOKEN_INSN, C_none, 0, I_VSQRTPD }, + { "vsqrtps", TOKEN_INSN, C_none, 0, I_VSQRTPS }, + { "vsqrtsd", TOKEN_INSN, C_none, 0, I_VSQRTSD }, + { "vsqrtss", TOKEN_INSN, C_none, 0, I_VSQRTSS }, + { "vstmxcsr", TOKEN_INSN, C_none, 0, I_VSTMXCSR }, + { "vsubpd", TOKEN_INSN, C_none, 0, I_VSUBPD }, + { "vsubps", TOKEN_INSN, C_none, 0, I_VSUBPS }, + { "vsubsd", TOKEN_INSN, C_none, 0, I_VSUBSD }, + { "vsubss", TOKEN_INSN, C_none, 0, I_VSUBSS }, + { "vtestps", TOKEN_INSN, C_none, 0, I_VTESTPS }, + { "vtestpd", TOKEN_INSN, C_none, 0, I_VTESTPD }, + { "vucomisd", TOKEN_INSN, C_none, 0, I_VUCOMISD }, + { "vucomiss", TOKEN_INSN, C_none, 0, I_VUCOMISS }, + { "vunpckhpd", TOKEN_INSN, C_none, 0, I_VUNPCKHPD }, + { "vunpckhps", TOKEN_INSN, C_none, 0, I_VUNPCKHPS }, + { "vunpcklpd", TOKEN_INSN, C_none, 0, I_VUNPCKLPD }, + { "vunpcklps", TOKEN_INSN, C_none, 0, I_VUNPCKLPS }, + { "vxorpd", TOKEN_INSN, C_none, 0, I_VXORPD }, + { "vxorps", TOKEN_INSN, C_none, 0, I_VXORPS }, + { "vzeroall", TOKEN_INSN, C_none, 0, I_VZEROALL }, + { "vzeroupper", TOKEN_INSN, C_none, 0, I_VZEROUPPER }, + { "pclmullqlqdq", TOKEN_INSN, C_none, 0, I_PCLMULLQLQDQ }, + { "pclmulhqlqdq", TOKEN_INSN, C_none, 0, I_PCLMULHQLQDQ }, + { "pclmullqhqdq", TOKEN_INSN, C_none, 0, I_PCLMULLQHQDQ }, + { "pclmulhqhqdq", TOKEN_INSN, C_none, 0, I_PCLMULHQHQDQ }, + { "pclmulqdq", TOKEN_INSN, C_none, 0, I_PCLMULQDQ }, + { "vpclmullqlqdq", TOKEN_INSN, C_none, 0, I_VPCLMULLQLQDQ }, + { "vpclmulhqlqdq", TOKEN_INSN, C_none, 0, I_VPCLMULHQLQDQ }, + { "vpclmullqhqdq", TOKEN_INSN, C_none, 0, I_VPCLMULLQHQDQ }, + { "vpclmulhqhqdq", TOKEN_INSN, C_none, 0, I_VPCLMULHQHQDQ }, + { "vpclmulqdq", TOKEN_INSN, C_none, 0, I_VPCLMULQDQ }, + { "vfmadd132ps", TOKEN_INSN, C_none, 0, I_VFMADD132PS }, + { "vfmadd132pd", TOKEN_INSN, C_none, 0, I_VFMADD132PD }, + { "vfmadd312ps", TOKEN_INSN, C_none, 0, I_VFMADD312PS }, + { "vfmadd312pd", TOKEN_INSN, C_none, 0, I_VFMADD312PD }, + { "vfmadd213ps", TOKEN_INSN, C_none, 0, I_VFMADD213PS }, + { "vfmadd213pd", TOKEN_INSN, C_none, 0, I_VFMADD213PD }, + { "vfmadd123ps", TOKEN_INSN, C_none, 0, I_VFMADD123PS }, + { "vfmadd123pd", TOKEN_INSN, C_none, 0, I_VFMADD123PD }, + { "vfmadd231ps", TOKEN_INSN, C_none, 0, I_VFMADD231PS }, + { "vfmadd231pd", TOKEN_INSN, C_none, 0, I_VFMADD231PD }, + { "vfmadd321ps", TOKEN_INSN, C_none, 0, I_VFMADD321PS }, + { "vfmadd321pd", TOKEN_INSN, C_none, 0, I_VFMADD321PD }, + { "vfmaddsub132ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB132PS }, + { "vfmaddsub132pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB132PD }, + { "vfmaddsub312ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB312PS }, + { "vfmaddsub312pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB312PD }, + { "vfmaddsub213ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB213PS }, + { "vfmaddsub213pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB213PD }, + { "vfmaddsub123ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB123PS }, + { "vfmaddsub123pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB123PD }, + { "vfmaddsub231ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB231PS }, + { "vfmaddsub231pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB231PD }, + { "vfmaddsub321ps", TOKEN_INSN, C_none, 0, I_VFMADDSUB321PS }, + { "vfmaddsub321pd", TOKEN_INSN, C_none, 0, I_VFMADDSUB321PD }, + { "vfmsub132ps", TOKEN_INSN, C_none, 0, I_VFMSUB132PS }, + { "vfmsub132pd", TOKEN_INSN, C_none, 0, I_VFMSUB132PD }, + { "vfmsub312ps", TOKEN_INSN, C_none, 0, I_VFMSUB312PS }, + { "vfmsub312pd", TOKEN_INSN, C_none, 0, I_VFMSUB312PD }, + { "vfmsub213ps", TOKEN_INSN, C_none, 0, I_VFMSUB213PS }, + { "vfmsub213pd", TOKEN_INSN, C_none, 0, I_VFMSUB213PD }, + { "vfmsub123ps", TOKEN_INSN, C_none, 0, I_VFMSUB123PS }, + { "vfmsub123pd", TOKEN_INSN, C_none, 0, I_VFMSUB123PD }, + { "vfmsub231ps", TOKEN_INSN, C_none, 0, I_VFMSUB231PS }, + { "vfmsub231pd", TOKEN_INSN, C_none, 0, I_VFMSUB231PD }, + { "vfmsub321ps", TOKEN_INSN, C_none, 0, I_VFMSUB321PS }, + { "vfmsub321pd", TOKEN_INSN, C_none, 0, I_VFMSUB321PD }, + { "vfmsubadd132ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD132PS }, + { "vfmsubadd132pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD132PD }, + { "vfmsubadd312ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD312PS }, + { "vfmsubadd312pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD312PD }, + { "vfmsubadd213ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD213PS }, + { "vfmsubadd213pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD213PD }, + { "vfmsubadd123ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD123PS }, + { "vfmsubadd123pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD123PD }, + { "vfmsubadd231ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD231PS }, + { "vfmsubadd231pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD231PD }, + { "vfmsubadd321ps", TOKEN_INSN, C_none, 0, I_VFMSUBADD321PS }, + { "vfmsubadd321pd", TOKEN_INSN, C_none, 0, I_VFMSUBADD321PD }, + { "vfnmadd132ps", TOKEN_INSN, C_none, 0, I_VFNMADD132PS }, + { "vfnmadd132pd", TOKEN_INSN, C_none, 0, I_VFNMADD132PD }, + { "vfnmadd312ps", TOKEN_INSN, C_none, 0, I_VFNMADD312PS }, + { "vfnmadd312pd", TOKEN_INSN, C_none, 0, I_VFNMADD312PD }, + { "vfnmadd213ps", TOKEN_INSN, C_none, 0, I_VFNMADD213PS }, + { "vfnmadd213pd", TOKEN_INSN, C_none, 0, I_VFNMADD213PD }, + { "vfnmadd123ps", TOKEN_INSN, C_none, 0, I_VFNMADD123PS }, + { "vfnmadd123pd", TOKEN_INSN, C_none, 0, I_VFNMADD123PD }, + { "vfnmadd231ps", TOKEN_INSN, C_none, 0, I_VFNMADD231PS }, + { "vfnmadd231pd", TOKEN_INSN, C_none, 0, I_VFNMADD231PD }, + { "vfnmadd321ps", TOKEN_INSN, C_none, 0, I_VFNMADD321PS }, + { "vfnmadd321pd", TOKEN_INSN, C_none, 0, I_VFNMADD321PD }, + { "vfnmsub132ps", TOKEN_INSN, C_none, 0, I_VFNMSUB132PS }, + { "vfnmsub132pd", TOKEN_INSN, C_none, 0, I_VFNMSUB132PD }, + { "vfnmsub312ps", TOKEN_INSN, C_none, 0, I_VFNMSUB312PS }, + { "vfnmsub312pd", TOKEN_INSN, C_none, 0, I_VFNMSUB312PD }, + { "vfnmsub213ps", TOKEN_INSN, C_none, 0, I_VFNMSUB213PS }, + { "vfnmsub213pd", TOKEN_INSN, C_none, 0, I_VFNMSUB213PD }, + { "vfnmsub123ps", TOKEN_INSN, C_none, 0, I_VFNMSUB123PS }, + { "vfnmsub123pd", TOKEN_INSN, C_none, 0, I_VFNMSUB123PD }, + { "vfnmsub231ps", TOKEN_INSN, C_none, 0, I_VFNMSUB231PS }, + { "vfnmsub231pd", TOKEN_INSN, C_none, 0, I_VFNMSUB231PD }, + { "vfnmsub321ps", TOKEN_INSN, C_none, 0, I_VFNMSUB321PS }, + { "vfnmsub321pd", TOKEN_INSN, C_none, 0, I_VFNMSUB321PD }, + { "vfmadd132ss", TOKEN_INSN, C_none, 0, I_VFMADD132SS }, + { "vfmadd132sd", TOKEN_INSN, C_none, 0, I_VFMADD132SD }, + { "vfmadd312ss", TOKEN_INSN, C_none, 0, I_VFMADD312SS }, + { "vfmadd312sd", TOKEN_INSN, C_none, 0, I_VFMADD312SD }, + { "vfmadd213ss", TOKEN_INSN, C_none, 0, I_VFMADD213SS }, + { "vfmadd213sd", TOKEN_INSN, C_none, 0, I_VFMADD213SD }, + { "vfmadd123ss", TOKEN_INSN, C_none, 0, I_VFMADD123SS }, + { "vfmadd123sd", TOKEN_INSN, C_none, 0, I_VFMADD123SD }, + { "vfmadd231ss", TOKEN_INSN, C_none, 0, I_VFMADD231SS }, + { "vfmadd231sd", TOKEN_INSN, C_none, 0, I_VFMADD231SD }, + { "vfmadd321ss", TOKEN_INSN, C_none, 0, I_VFMADD321SS }, + { "vfmadd321sd", TOKEN_INSN, C_none, 0, I_VFMADD321SD }, + { "vfmsub132ss", TOKEN_INSN, C_none, 0, I_VFMSUB132SS }, + { "vfmsub132sd", TOKEN_INSN, C_none, 0, I_VFMSUB132SD }, + { "vfmsub312ss", TOKEN_INSN, C_none, 0, I_VFMSUB312SS }, + { "vfmsub312sd", TOKEN_INSN, C_none, 0, I_VFMSUB312SD }, + { "vfmsub213ss", TOKEN_INSN, C_none, 0, I_VFMSUB213SS }, + { "vfmsub213sd", TOKEN_INSN, C_none, 0, I_VFMSUB213SD }, + { "vfmsub123ss", TOKEN_INSN, C_none, 0, I_VFMSUB123SS }, + { "vfmsub123sd", TOKEN_INSN, C_none, 0, I_VFMSUB123SD }, + { "vfmsub231ss", TOKEN_INSN, C_none, 0, I_VFMSUB231SS }, + { "vfmsub231sd", TOKEN_INSN, C_none, 0, I_VFMSUB231SD }, + { "vfmsub321ss", TOKEN_INSN, C_none, 0, I_VFMSUB321SS }, + { "vfmsub321sd", TOKEN_INSN, C_none, 0, I_VFMSUB321SD }, + { "vfnmadd132ss", TOKEN_INSN, C_none, 0, I_VFNMADD132SS }, + { "vfnmadd132sd", TOKEN_INSN, C_none, 0, I_VFNMADD132SD }, + { "vfnmadd312ss", TOKEN_INSN, C_none, 0, I_VFNMADD312SS }, + { "vfnmadd312sd", TOKEN_INSN, C_none, 0, I_VFNMADD312SD }, + { "vfnmadd213ss", TOKEN_INSN, C_none, 0, I_VFNMADD213SS }, + { "vfnmadd213sd", TOKEN_INSN, C_none, 0, I_VFNMADD213SD }, + { "vfnmadd123ss", TOKEN_INSN, C_none, 0, I_VFNMADD123SS }, + { "vfnmadd123sd", TOKEN_INSN, C_none, 0, I_VFNMADD123SD }, + { "vfnmadd231ss", TOKEN_INSN, C_none, 0, I_VFNMADD231SS }, + { "vfnmadd231sd", TOKEN_INSN, C_none, 0, I_VFNMADD231SD }, + { "vfnmadd321ss", TOKEN_INSN, C_none, 0, I_VFNMADD321SS }, + { "vfnmadd321sd", TOKEN_INSN, C_none, 0, I_VFNMADD321SD }, + { "vfnmsub132ss", TOKEN_INSN, C_none, 0, I_VFNMSUB132SS }, + { "vfnmsub132sd", TOKEN_INSN, C_none, 0, I_VFNMSUB132SD }, + { "vfnmsub312ss", TOKEN_INSN, C_none, 0, I_VFNMSUB312SS }, + { "vfnmsub312sd", TOKEN_INSN, C_none, 0, I_VFNMSUB312SD }, + { "vfnmsub213ss", TOKEN_INSN, C_none, 0, I_VFNMSUB213SS }, + { "vfnmsub213sd", TOKEN_INSN, C_none, 0, I_VFNMSUB213SD }, + { "vfnmsub123ss", TOKEN_INSN, C_none, 0, I_VFNMSUB123SS }, + { "vfnmsub123sd", TOKEN_INSN, C_none, 0, I_VFNMSUB123SD }, + { "vfnmsub231ss", TOKEN_INSN, C_none, 0, I_VFNMSUB231SS }, + { "vfnmsub231sd", TOKEN_INSN, C_none, 0, I_VFNMSUB231SD }, + { "vfnmsub321ss", TOKEN_INSN, C_none, 0, I_VFNMSUB321SS }, + { "vfnmsub321sd", TOKEN_INSN, C_none, 0, I_VFNMSUB321SD }, + { "rdfsbase", TOKEN_INSN, C_none, 0, I_RDFSBASE }, + { "rdgsbase", TOKEN_INSN, C_none, 0, I_RDGSBASE }, + { "rdrand", TOKEN_INSN, C_none, 0, I_RDRAND }, + { "wrfsbase", TOKEN_INSN, C_none, 0, I_WRFSBASE }, + { "wrgsbase", TOKEN_INSN, C_none, 0, I_WRGSBASE }, + { "vcvtph2ps", TOKEN_INSN, C_none, 0, I_VCVTPH2PS }, + { "vcvtps2ph", TOKEN_INSN, C_none, 0, I_VCVTPS2PH }, + { "adcx", TOKEN_INSN, C_none, 0, I_ADCX }, + { "adox", TOKEN_INSN, C_none, 0, I_ADOX }, + { "rdseed", TOKEN_INSN, C_none, 0, I_RDSEED }, + { "clac", TOKEN_INSN, C_none, 0, I_CLAC }, + { "stac", TOKEN_INSN, C_none, 0, I_STAC }, + { "xstore", TOKEN_INSN, C_none, 0, I_XSTORE }, + { "xcryptecb", TOKEN_INSN, C_none, 0, I_XCRYPTECB }, + { "xcryptcbc", TOKEN_INSN, C_none, 0, I_XCRYPTCBC }, + { "xcryptctr", TOKEN_INSN, C_none, 0, I_XCRYPTCTR }, + { "xcryptcfb", TOKEN_INSN, C_none, 0, I_XCRYPTCFB }, + { "xcryptofb", TOKEN_INSN, C_none, 0, I_XCRYPTOFB }, + { "montmul", TOKEN_INSN, C_none, 0, I_MONTMUL }, + { "xsha1", TOKEN_INSN, C_none, 0, I_XSHA1 }, + { "xsha256", TOKEN_INSN, C_none, 0, I_XSHA256 }, + { "llwpcb", TOKEN_INSN, C_none, 0, I_LLWPCB }, + { "slwpcb", TOKEN_INSN, C_none, 0, I_SLWPCB }, + { "lwpval", TOKEN_INSN, C_none, 0, I_LWPVAL }, + { "lwpins", TOKEN_INSN, C_none, 0, I_LWPINS }, + { "vfmaddpd", TOKEN_INSN, C_none, 0, I_VFMADDPD }, + { "vfmaddps", TOKEN_INSN, C_none, 0, I_VFMADDPS }, + { "vfmaddsd", TOKEN_INSN, C_none, 0, I_VFMADDSD }, + { "vfmaddss", TOKEN_INSN, C_none, 0, I_VFMADDSS }, + { "vfmaddsubpd", TOKEN_INSN, C_none, 0, I_VFMADDSUBPD }, + { "vfmaddsubps", TOKEN_INSN, C_none, 0, I_VFMADDSUBPS }, + { "vfmsubaddpd", TOKEN_INSN, C_none, 0, I_VFMSUBADDPD }, + { "vfmsubaddps", TOKEN_INSN, C_none, 0, I_VFMSUBADDPS }, + { "vfmsubpd", TOKEN_INSN, C_none, 0, I_VFMSUBPD }, + { "vfmsubps", TOKEN_INSN, C_none, 0, I_VFMSUBPS }, + { "vfmsubsd", TOKEN_INSN, C_none, 0, I_VFMSUBSD }, + { "vfmsubss", TOKEN_INSN, C_none, 0, I_VFMSUBSS }, + { "vfnmaddpd", TOKEN_INSN, C_none, 0, I_VFNMADDPD }, + { "vfnmaddps", TOKEN_INSN, C_none, 0, I_VFNMADDPS }, + { "vfnmaddsd", TOKEN_INSN, C_none, 0, I_VFNMADDSD }, + { "vfnmaddss", TOKEN_INSN, C_none, 0, I_VFNMADDSS }, + { "vfnmsubpd", TOKEN_INSN, C_none, 0, I_VFNMSUBPD }, + { "vfnmsubps", TOKEN_INSN, C_none, 0, I_VFNMSUBPS }, + { "vfnmsubsd", TOKEN_INSN, C_none, 0, I_VFNMSUBSD }, + { "vfnmsubss", TOKEN_INSN, C_none, 0, I_VFNMSUBSS }, + { "vfrczpd", TOKEN_INSN, C_none, 0, I_VFRCZPD }, + { "vfrczps", TOKEN_INSN, C_none, 0, I_VFRCZPS }, + { "vfrczsd", TOKEN_INSN, C_none, 0, I_VFRCZSD }, + { "vfrczss", TOKEN_INSN, C_none, 0, I_VFRCZSS }, + { "vpcmov", TOKEN_INSN, C_none, 0, I_VPCMOV }, + { "vpcomb", TOKEN_INSN, C_none, 0, I_VPCOMB }, + { "vpcomd", TOKEN_INSN, C_none, 0, I_VPCOMD }, + { "vpcomq", TOKEN_INSN, C_none, 0, I_VPCOMQ }, + { "vpcomub", TOKEN_INSN, C_none, 0, I_VPCOMUB }, + { "vpcomud", TOKEN_INSN, C_none, 0, I_VPCOMUD }, + { "vpcomuq", TOKEN_INSN, C_none, 0, I_VPCOMUQ }, + { "vpcomuw", TOKEN_INSN, C_none, 0, I_VPCOMUW }, + { "vpcomw", TOKEN_INSN, C_none, 0, I_VPCOMW }, + { "vphaddbd", TOKEN_INSN, C_none, 0, I_VPHADDBD }, + { "vphaddbq", TOKEN_INSN, C_none, 0, I_VPHADDBQ }, + { "vphaddbw", TOKEN_INSN, C_none, 0, I_VPHADDBW }, + { "vphadddq", TOKEN_INSN, C_none, 0, I_VPHADDDQ }, + { "vphaddubd", TOKEN_INSN, C_none, 0, I_VPHADDUBD }, + { "vphaddubq", TOKEN_INSN, C_none, 0, I_VPHADDUBQ }, + { "vphaddubw", TOKEN_INSN, C_none, 0, I_VPHADDUBW }, + { "vphaddudq", TOKEN_INSN, C_none, 0, I_VPHADDUDQ }, + { "vphadduwd", TOKEN_INSN, C_none, 0, I_VPHADDUWD }, + { "vphadduwq", TOKEN_INSN, C_none, 0, I_VPHADDUWQ }, + { "vphaddwd", TOKEN_INSN, C_none, 0, I_VPHADDWD }, + { "vphaddwq", TOKEN_INSN, C_none, 0, I_VPHADDWQ }, + { "vphsubbw", TOKEN_INSN, C_none, 0, I_VPHSUBBW }, + { "vphsubdq", TOKEN_INSN, C_none, 0, I_VPHSUBDQ }, + { "vphsubwd", TOKEN_INSN, C_none, 0, I_VPHSUBWD }, + { "vpmacsdd", TOKEN_INSN, C_none, 0, I_VPMACSDD }, + { "vpmacsdqh", TOKEN_INSN, C_none, 0, I_VPMACSDQH }, + { "vpmacsdql", TOKEN_INSN, C_none, 0, I_VPMACSDQL }, + { "vpmacssdd", TOKEN_INSN, C_none, 0, I_VPMACSSDD }, + { "vpmacssdqh", TOKEN_INSN, C_none, 0, I_VPMACSSDQH }, + { "vpmacssdql", TOKEN_INSN, C_none, 0, I_VPMACSSDQL }, + { "vpmacsswd", TOKEN_INSN, C_none, 0, I_VPMACSSWD }, + { "vpmacssww", TOKEN_INSN, C_none, 0, I_VPMACSSWW }, + { "vpmacswd", TOKEN_INSN, C_none, 0, I_VPMACSWD }, + { "vpmacsww", TOKEN_INSN, C_none, 0, I_VPMACSWW }, + { "vpmadcsswd", TOKEN_INSN, C_none, 0, I_VPMADCSSWD }, + { "vpmadcswd", TOKEN_INSN, C_none, 0, I_VPMADCSWD }, + { "vpperm", TOKEN_INSN, C_none, 0, I_VPPERM }, + { "vprotb", TOKEN_INSN, C_none, 0, I_VPROTB }, + { "vprotd", TOKEN_INSN, C_none, 0, I_VPROTD }, + { "vprotq", TOKEN_INSN, C_none, 0, I_VPROTQ }, + { "vprotw", TOKEN_INSN, C_none, 0, I_VPROTW }, + { "vpshab", TOKEN_INSN, C_none, 0, I_VPSHAB }, + { "vpshad", TOKEN_INSN, C_none, 0, I_VPSHAD }, + { "vpshaq", TOKEN_INSN, C_none, 0, I_VPSHAQ }, + { "vpshaw", TOKEN_INSN, C_none, 0, I_VPSHAW }, + { "vpshlb", TOKEN_INSN, C_none, 0, I_VPSHLB }, + { "vpshld", TOKEN_INSN, C_none, 0, I_VPSHLD }, + { "vpshlq", TOKEN_INSN, C_none, 0, I_VPSHLQ }, + { "vpshlw", TOKEN_INSN, C_none, 0, I_VPSHLW }, + { "vbroadcasti128", TOKEN_INSN, C_none, 0, I_VBROADCASTI128 }, + { "vpblendd", TOKEN_INSN, C_none, 0, I_VPBLENDD }, + { "vpbroadcastb", TOKEN_INSN, C_none, 0, I_VPBROADCASTB }, + { "vpbroadcastw", TOKEN_INSN, C_none, 0, I_VPBROADCASTW }, + { "vpbroadcastd", TOKEN_INSN, C_none, 0, I_VPBROADCASTD }, + { "vpbroadcastq", TOKEN_INSN, C_none, 0, I_VPBROADCASTQ }, + { "vpermd", TOKEN_INSN, C_none, 0, I_VPERMD }, + { "vpermpd", TOKEN_INSN, C_none, 0, I_VPERMPD }, + { "vpermps", TOKEN_INSN, C_none, 0, I_VPERMPS }, + { "vpermq", TOKEN_INSN, C_none, 0, I_VPERMQ }, + { "vperm2i128", TOKEN_INSN, C_none, 0, I_VPERM2I128 }, + { "vextracti128", TOKEN_INSN, C_none, 0, I_VEXTRACTI128 }, + { "vinserti128", TOKEN_INSN, C_none, 0, I_VINSERTI128 }, + { "vpmaskmovd", TOKEN_INSN, C_none, 0, I_VPMASKMOVD }, + { "vpmaskmovq", TOKEN_INSN, C_none, 0, I_VPMASKMOVQ }, + { "vpsllvd", TOKEN_INSN, C_none, 0, I_VPSLLVD }, + { "vpsllvq", TOKEN_INSN, C_none, 0, I_VPSLLVQ }, + { "vpsravd", TOKEN_INSN, C_none, 0, I_VPSRAVD }, + { "vpsrlvd", TOKEN_INSN, C_none, 0, I_VPSRLVD }, + { "vpsrlvq", TOKEN_INSN, C_none, 0, I_VPSRLVQ }, + { "vgatherdpd", TOKEN_INSN, C_none, 0, I_VGATHERDPD }, + { "vgatherqpd", TOKEN_INSN, C_none, 0, I_VGATHERQPD }, + { "vgatherdps", TOKEN_INSN, C_none, 0, I_VGATHERDPS }, + { "vgatherqps", TOKEN_INSN, C_none, 0, I_VGATHERQPS }, + { "vpgatherdd", TOKEN_INSN, C_none, 0, I_VPGATHERDD }, + { "vpgatherqd", TOKEN_INSN, C_none, 0, I_VPGATHERQD }, + { "vpgatherdq", TOKEN_INSN, C_none, 0, I_VPGATHERDQ }, + { "vpgatherqq", TOKEN_INSN, C_none, 0, I_VPGATHERQQ }, + { "xabort", TOKEN_INSN, C_none, 0, I_XABORT }, + { "xbegin", TOKEN_INSN, C_none, 0, I_XBEGIN }, + { "xend", TOKEN_INSN, C_none, 0, I_XEND }, + { "xtest", TOKEN_INSN, C_none, 0, I_XTEST }, + { "andn", TOKEN_INSN, C_none, 0, I_ANDN }, + { "bextr", TOKEN_INSN, C_none, 0, I_BEXTR }, + { "blci", TOKEN_INSN, C_none, 0, I_BLCI }, + { "blcic", TOKEN_INSN, C_none, 0, I_BLCIC }, + { "blsi", TOKEN_INSN, C_none, 0, I_BLSI }, + { "blsic", TOKEN_INSN, C_none, 0, I_BLSIC }, + { "blcfill", TOKEN_INSN, C_none, 0, I_BLCFILL }, + { "blsfill", TOKEN_INSN, C_none, 0, I_BLSFILL }, + { "blcmsk", TOKEN_INSN, C_none, 0, I_BLCMSK }, + { "blsmsk", TOKEN_INSN, C_none, 0, I_BLSMSK }, + { "blsr", TOKEN_INSN, C_none, 0, I_BLSR }, + { "blcs", TOKEN_INSN, C_none, 0, I_BLCS }, + { "bzhi", TOKEN_INSN, C_none, 0, I_BZHI }, + { "mulx", TOKEN_INSN, C_none, 0, I_MULX }, + { "pdep", TOKEN_INSN, C_none, 0, I_PDEP }, + { "pext", TOKEN_INSN, C_none, 0, I_PEXT }, + { "rorx", TOKEN_INSN, C_none, 0, I_RORX }, + { "sarx", TOKEN_INSN, C_none, 0, I_SARX }, + { "shlx", TOKEN_INSN, C_none, 0, I_SHLX }, + { "shrx", TOKEN_INSN, C_none, 0, I_SHRX }, + { "tzcnt", TOKEN_INSN, C_none, 0, I_TZCNT }, + { "tzmsk", TOKEN_INSN, C_none, 0, I_TZMSK }, + { "t1mskc", TOKEN_INSN, C_none, 0, I_T1MSKC }, + { "prefetchwt1", TOKEN_INSN, C_none, 0, I_PREFETCHWT1 }, + { "bndmk", TOKEN_INSN, C_none, 0, I_BNDMK }, + { "bndcl", TOKEN_INSN, C_none, 0, I_BNDCL }, + { "bndcu", TOKEN_INSN, C_none, 0, I_BNDCU }, + { "bndcn", TOKEN_INSN, C_none, 0, I_BNDCN }, + { "bndmov", TOKEN_INSN, C_none, 0, I_BNDMOV }, + { "bndldx", TOKEN_INSN, C_none, 0, I_BNDLDX }, + { "bndstx", TOKEN_INSN, C_none, 0, I_BNDSTX }, + { "sha1msg1", TOKEN_INSN, C_none, 0, I_SHA1MSG1 }, + { "sha1msg2", TOKEN_INSN, C_none, 0, I_SHA1MSG2 }, + { "sha1nexte", TOKEN_INSN, C_none, 0, I_SHA1NEXTE }, + { "sha1rnds4", TOKEN_INSN, C_none, 0, I_SHA1RNDS4 }, + { "sha256msg1", TOKEN_INSN, C_none, 0, I_SHA256MSG1 }, + { "sha256msg2", TOKEN_INSN, C_none, 0, I_SHA256MSG2 }, + { "sha256rnds2", TOKEN_INSN, C_none, 0, I_SHA256RNDS2 }, + { "kaddb", TOKEN_INSN, C_none, 0, I_KADDB }, + { "kaddd", TOKEN_INSN, C_none, 0, I_KADDD }, + { "kaddq", TOKEN_INSN, C_none, 0, I_KADDQ }, + { "kaddw", TOKEN_INSN, C_none, 0, I_KADDW }, + { "kandb", TOKEN_INSN, C_none, 0, I_KANDB }, + { "kandd", TOKEN_INSN, C_none, 0, I_KANDD }, + { "kandnb", TOKEN_INSN, C_none, 0, I_KANDNB }, + { "kandnd", TOKEN_INSN, C_none, 0, I_KANDND }, + { "kandnq", TOKEN_INSN, C_none, 0, I_KANDNQ }, + { "kandnw", TOKEN_INSN, C_none, 0, I_KANDNW }, + { "kandq", TOKEN_INSN, C_none, 0, I_KANDQ }, + { "kandw", TOKEN_INSN, C_none, 0, I_KANDW }, + { "kmovb", TOKEN_INSN, C_none, 0, I_KMOVB }, + { "kmovd", TOKEN_INSN, C_none, 0, I_KMOVD }, + { "kmovq", TOKEN_INSN, C_none, 0, I_KMOVQ }, + { "kmovw", TOKEN_INSN, C_none, 0, I_KMOVW }, + { "knotb", TOKEN_INSN, C_none, 0, I_KNOTB }, + { "knotd", TOKEN_INSN, C_none, 0, I_KNOTD }, + { "knotq", TOKEN_INSN, C_none, 0, I_KNOTQ }, + { "knotw", TOKEN_INSN, C_none, 0, I_KNOTW }, + { "korb", TOKEN_INSN, C_none, 0, I_KORB }, + { "kord", TOKEN_INSN, C_none, 0, I_KORD }, + { "korq", TOKEN_INSN, C_none, 0, I_KORQ }, + { "kortestb", TOKEN_INSN, C_none, 0, I_KORTESTB }, + { "kortestd", TOKEN_INSN, C_none, 0, I_KORTESTD }, + { "kortestq", TOKEN_INSN, C_none, 0, I_KORTESTQ }, + { "kortestw", TOKEN_INSN, C_none, 0, I_KORTESTW }, + { "korw", TOKEN_INSN, C_none, 0, I_KORW }, + { "kshiftlb", TOKEN_INSN, C_none, 0, I_KSHIFTLB }, + { "kshiftld", TOKEN_INSN, C_none, 0, I_KSHIFTLD }, + { "kshiftlq", TOKEN_INSN, C_none, 0, I_KSHIFTLQ }, + { "kshiftlw", TOKEN_INSN, C_none, 0, I_KSHIFTLW }, + { "kshiftrb", TOKEN_INSN, C_none, 0, I_KSHIFTRB }, + { "kshiftrd", TOKEN_INSN, C_none, 0, I_KSHIFTRD }, + { "kshiftrq", TOKEN_INSN, C_none, 0, I_KSHIFTRQ }, + { "kshiftrw", TOKEN_INSN, C_none, 0, I_KSHIFTRW }, + { "ktestb", TOKEN_INSN, C_none, 0, I_KTESTB }, + { "ktestd", TOKEN_INSN, C_none, 0, I_KTESTD }, + { "ktestq", TOKEN_INSN, C_none, 0, I_KTESTQ }, + { "ktestw", TOKEN_INSN, C_none, 0, I_KTESTW }, + { "kunpckbw", TOKEN_INSN, C_none, 0, I_KUNPCKBW }, + { "kunpckdq", TOKEN_INSN, C_none, 0, I_KUNPCKDQ }, + { "kunpckwd", TOKEN_INSN, C_none, 0, I_KUNPCKWD }, + { "kxnorb", TOKEN_INSN, C_none, 0, I_KXNORB }, + { "kxnord", TOKEN_INSN, C_none, 0, I_KXNORD }, + { "kxnorq", TOKEN_INSN, C_none, 0, I_KXNORQ }, + { "kxnorw", TOKEN_INSN, C_none, 0, I_KXNORW }, + { "kxorb", TOKEN_INSN, C_none, 0, I_KXORB }, + { "kxord", TOKEN_INSN, C_none, 0, I_KXORD }, + { "kxorq", TOKEN_INSN, C_none, 0, I_KXORQ }, + { "kxorw", TOKEN_INSN, C_none, 0, I_KXORW }, + { "valignd", TOKEN_INSN, C_none, 0, I_VALIGND }, + { "valignq", TOKEN_INSN, C_none, 0, I_VALIGNQ }, + { "vblendmpd", TOKEN_INSN, C_none, 0, I_VBLENDMPD }, + { "vblendmps", TOKEN_INSN, C_none, 0, I_VBLENDMPS }, + { "vbroadcastf32x2", TOKEN_INSN, C_none, 0, I_VBROADCASTF32X2 }, + { "vbroadcastf32x4", TOKEN_INSN, C_none, 0, I_VBROADCASTF32X4 }, + { "vbroadcastf32x8", TOKEN_INSN, C_none, 0, I_VBROADCASTF32X8 }, + { "vbroadcastf64x2", TOKEN_INSN, C_none, 0, I_VBROADCASTF64X2 }, + { "vbroadcastf64x4", TOKEN_INSN, C_none, 0, I_VBROADCASTF64X4 }, + { "vbroadcasti32x2", TOKEN_INSN, C_none, 0, I_VBROADCASTI32X2 }, + { "vbroadcasti32x4", TOKEN_INSN, C_none, 0, I_VBROADCASTI32X4 }, + { "vbroadcasti32x8", TOKEN_INSN, C_none, 0, I_VBROADCASTI32X8 }, + { "vbroadcasti64x2", TOKEN_INSN, C_none, 0, I_VBROADCASTI64X2 }, + { "vbroadcasti64x4", TOKEN_INSN, C_none, 0, I_VBROADCASTI64X4 }, + { "vcompresspd", TOKEN_INSN, C_none, 0, I_VCOMPRESSPD }, + { "vcompressps", TOKEN_INSN, C_none, 0, I_VCOMPRESSPS }, + { "vcvtpd2qq", TOKEN_INSN, C_none, 0, I_VCVTPD2QQ }, + { "vcvtpd2udq", TOKEN_INSN, C_none, 0, I_VCVTPD2UDQ }, + { "vcvtpd2uqq", TOKEN_INSN, C_none, 0, I_VCVTPD2UQQ }, + { "vcvtps2qq", TOKEN_INSN, C_none, 0, I_VCVTPS2QQ }, + { "vcvtps2udq", TOKEN_INSN, C_none, 0, I_VCVTPS2UDQ }, + { "vcvtps2uqq", TOKEN_INSN, C_none, 0, I_VCVTPS2UQQ }, + { "vcvtqq2pd", TOKEN_INSN, C_none, 0, I_VCVTQQ2PD }, + { "vcvtqq2ps", TOKEN_INSN, C_none, 0, I_VCVTQQ2PS }, + { "vcvtsd2usi", TOKEN_INSN, C_none, 0, I_VCVTSD2USI }, + { "vcvtss2usi", TOKEN_INSN, C_none, 0, I_VCVTSS2USI }, + { "vcvttpd2qq", TOKEN_INSN, C_none, 0, I_VCVTTPD2QQ }, + { "vcvttpd2udq", TOKEN_INSN, C_none, 0, I_VCVTTPD2UDQ }, + { "vcvttpd2uqq", TOKEN_INSN, C_none, 0, I_VCVTTPD2UQQ }, + { "vcvttps2qq", TOKEN_INSN, C_none, 0, I_VCVTTPS2QQ }, + { "vcvttps2udq", TOKEN_INSN, C_none, 0, I_VCVTTPS2UDQ }, + { "vcvttps2uqq", TOKEN_INSN, C_none, 0, I_VCVTTPS2UQQ }, + { "vcvttsd2usi", TOKEN_INSN, C_none, 0, I_VCVTTSD2USI }, + { "vcvttss2usi", TOKEN_INSN, C_none, 0, I_VCVTTSS2USI }, + { "vcvtudq2pd", TOKEN_INSN, C_none, 0, I_VCVTUDQ2PD }, + { "vcvtudq2ps", TOKEN_INSN, C_none, 0, I_VCVTUDQ2PS }, + { "vcvtuqq2pd", TOKEN_INSN, C_none, 0, I_VCVTUQQ2PD }, + { "vcvtuqq2ps", TOKEN_INSN, C_none, 0, I_VCVTUQQ2PS }, + { "vcvtusi2sd", TOKEN_INSN, C_none, 0, I_VCVTUSI2SD }, + { "vcvtusi2ss", TOKEN_INSN, C_none, 0, I_VCVTUSI2SS }, + { "vdbpsadbw", TOKEN_INSN, C_none, 0, I_VDBPSADBW }, + { "vexp2pd", TOKEN_INSN, C_none, 0, I_VEXP2PD }, + { "vexp2ps", TOKEN_INSN, C_none, 0, I_VEXP2PS }, + { "vexpandpd", TOKEN_INSN, C_none, 0, I_VEXPANDPD }, + { "vexpandps", TOKEN_INSN, C_none, 0, I_VEXPANDPS }, + { "vextractf32x4", TOKEN_INSN, C_none, 0, I_VEXTRACTF32X4 }, + { "vextractf32x8", TOKEN_INSN, C_none, 0, I_VEXTRACTF32X8 }, + { "vextractf64x2", TOKEN_INSN, C_none, 0, I_VEXTRACTF64X2 }, + { "vextractf64x4", TOKEN_INSN, C_none, 0, I_VEXTRACTF64X4 }, + { "vextracti32x4", TOKEN_INSN, C_none, 0, I_VEXTRACTI32X4 }, + { "vextracti32x8", TOKEN_INSN, C_none, 0, I_VEXTRACTI32X8 }, + { "vextracti64x2", TOKEN_INSN, C_none, 0, I_VEXTRACTI64X2 }, + { "vextracti64x4", TOKEN_INSN, C_none, 0, I_VEXTRACTI64X4 }, + { "vfixupimmpd", TOKEN_INSN, C_none, 0, I_VFIXUPIMMPD }, + { "vfixupimmps", TOKEN_INSN, C_none, 0, I_VFIXUPIMMPS }, + { "vfixupimmsd", TOKEN_INSN, C_none, 0, I_VFIXUPIMMSD }, + { "vfixupimmss", TOKEN_INSN, C_none, 0, I_VFIXUPIMMSS }, + { "vfpclasspd", TOKEN_INSN, C_none, 0, I_VFPCLASSPD }, + { "vfpclassps", TOKEN_INSN, C_none, 0, I_VFPCLASSPS }, + { "vfpclasssd", TOKEN_INSN, C_none, 0, I_VFPCLASSSD }, + { "vfpclassss", TOKEN_INSN, C_none, 0, I_VFPCLASSSS }, + { "vgatherpf0dpd", TOKEN_INSN, C_none, 0, I_VGATHERPF0DPD }, + { "vgatherpf0dps", TOKEN_INSN, C_none, 0, I_VGATHERPF0DPS }, + { "vgatherpf0qpd", TOKEN_INSN, C_none, 0, I_VGATHERPF0QPD }, + { "vgatherpf0qps", TOKEN_INSN, C_none, 0, I_VGATHERPF0QPS }, + { "vgatherpf1dpd", TOKEN_INSN, C_none, 0, I_VGATHERPF1DPD }, + { "vgatherpf1dps", TOKEN_INSN, C_none, 0, I_VGATHERPF1DPS }, + { "vgatherpf1qpd", TOKEN_INSN, C_none, 0, I_VGATHERPF1QPD }, + { "vgatherpf1qps", TOKEN_INSN, C_none, 0, I_VGATHERPF1QPS }, + { "vgetexppd", TOKEN_INSN, C_none, 0, I_VGETEXPPD }, + { "vgetexpps", TOKEN_INSN, C_none, 0, I_VGETEXPPS }, + { "vgetexpsd", TOKEN_INSN, C_none, 0, I_VGETEXPSD }, + { "vgetexpss", TOKEN_INSN, C_none, 0, I_VGETEXPSS }, + { "vgetmantpd", TOKEN_INSN, C_none, 0, I_VGETMANTPD }, + { "vgetmantps", TOKEN_INSN, C_none, 0, I_VGETMANTPS }, + { "vgetmantsd", TOKEN_INSN, C_none, 0, I_VGETMANTSD }, + { "vgetmantss", TOKEN_INSN, C_none, 0, I_VGETMANTSS }, + { "vinsertf32x4", TOKEN_INSN, C_none, 0, I_VINSERTF32X4 }, + { "vinsertf32x8", TOKEN_INSN, C_none, 0, I_VINSERTF32X8 }, + { "vinsertf64x2", TOKEN_INSN, C_none, 0, I_VINSERTF64X2 }, + { "vinsertf64x4", TOKEN_INSN, C_none, 0, I_VINSERTF64X4 }, + { "vinserti32x4", TOKEN_INSN, C_none, 0, I_VINSERTI32X4 }, + { "vinserti32x8", TOKEN_INSN, C_none, 0, I_VINSERTI32X8 }, + { "vinserti64x2", TOKEN_INSN, C_none, 0, I_VINSERTI64X2 }, + { "vinserti64x4", TOKEN_INSN, C_none, 0, I_VINSERTI64X4 }, + { "vmovdqa32", TOKEN_INSN, C_none, 0, I_VMOVDQA32 }, + { "vmovdqa64", TOKEN_INSN, C_none, 0, I_VMOVDQA64 }, + { "vmovdqu16", TOKEN_INSN, C_none, 0, I_VMOVDQU16 }, + { "vmovdqu32", TOKEN_INSN, C_none, 0, I_VMOVDQU32 }, + { "vmovdqu64", TOKEN_INSN, C_none, 0, I_VMOVDQU64 }, + { "vmovdqu8", TOKEN_INSN, C_none, 0, I_VMOVDQU8 }, + { "vpabsq", TOKEN_INSN, C_none, 0, I_VPABSQ }, + { "vpandd", TOKEN_INSN, C_none, 0, I_VPANDD }, + { "vpandnd", TOKEN_INSN, C_none, 0, I_VPANDND }, + { "vpandnq", TOKEN_INSN, C_none, 0, I_VPANDNQ }, + { "vpandq", TOKEN_INSN, C_none, 0, I_VPANDQ }, + { "vpblendmb", TOKEN_INSN, C_none, 0, I_VPBLENDMB }, + { "vpblendmd", TOKEN_INSN, C_none, 0, I_VPBLENDMD }, + { "vpblendmq", TOKEN_INSN, C_none, 0, I_VPBLENDMQ }, + { "vpblendmw", TOKEN_INSN, C_none, 0, I_VPBLENDMW }, + { "vpbroadcastmb2q", TOKEN_INSN, C_none, 0, I_VPBROADCASTMB2Q }, + { "vpbroadcastmw2d", TOKEN_INSN, C_none, 0, I_VPBROADCASTMW2D }, + { "vpcmpb", TOKEN_INSN, C_none, 0, I_VPCMPB }, + { "vpcmpd", TOKEN_INSN, C_none, 0, I_VPCMPD }, + { "vpcmpq", TOKEN_INSN, C_none, 0, I_VPCMPQ }, + { "vpcmpub", TOKEN_INSN, C_none, 0, I_VPCMPUB }, + { "vpcmpud", TOKEN_INSN, C_none, 0, I_VPCMPUD }, + { "vpcmpuq", TOKEN_INSN, C_none, 0, I_VPCMPUQ }, + { "vpcmpuw", TOKEN_INSN, C_none, 0, I_VPCMPUW }, + { "vpcmpw", TOKEN_INSN, C_none, 0, I_VPCMPW }, + { "vpcompressd", TOKEN_INSN, C_none, 0, I_VPCOMPRESSD }, + { "vpcompressq", TOKEN_INSN, C_none, 0, I_VPCOMPRESSQ }, + { "vpconflictd", TOKEN_INSN, C_none, 0, I_VPCONFLICTD }, + { "vpconflictq", TOKEN_INSN, C_none, 0, I_VPCONFLICTQ }, + { "vpermb", TOKEN_INSN, C_none, 0, I_VPERMB }, + { "vpermi2b", TOKEN_INSN, C_none, 0, I_VPERMI2B }, + { "vpermi2d", TOKEN_INSN, C_none, 0, I_VPERMI2D }, + { "vpermi2pd", TOKEN_INSN, C_none, 0, I_VPERMI2PD }, + { "vpermi2ps", TOKEN_INSN, C_none, 0, I_VPERMI2PS }, + { "vpermi2q", TOKEN_INSN, C_none, 0, I_VPERMI2Q }, + { "vpermi2w", TOKEN_INSN, C_none, 0, I_VPERMI2W }, + { "vpermt2b", TOKEN_INSN, C_none, 0, I_VPERMT2B }, + { "vpermt2d", TOKEN_INSN, C_none, 0, I_VPERMT2D }, + { "vpermt2pd", TOKEN_INSN, C_none, 0, I_VPERMT2PD }, + { "vpermt2ps", TOKEN_INSN, C_none, 0, I_VPERMT2PS }, + { "vpermt2q", TOKEN_INSN, C_none, 0, I_VPERMT2Q }, + { "vpermt2w", TOKEN_INSN, C_none, 0, I_VPERMT2W }, + { "vpermw", TOKEN_INSN, C_none, 0, I_VPERMW }, + { "vpexpandd", TOKEN_INSN, C_none, 0, I_VPEXPANDD }, + { "vpexpandq", TOKEN_INSN, C_none, 0, I_VPEXPANDQ }, + { "vplzcntd", TOKEN_INSN, C_none, 0, I_VPLZCNTD }, + { "vplzcntq", TOKEN_INSN, C_none, 0, I_VPLZCNTQ }, + { "vpmadd52huq", TOKEN_INSN, C_none, 0, I_VPMADD52HUQ }, + { "vpmadd52luq", TOKEN_INSN, C_none, 0, I_VPMADD52LUQ }, + { "vpmaxsq", TOKEN_INSN, C_none, 0, I_VPMAXSQ }, + { "vpmaxuq", TOKEN_INSN, C_none, 0, I_VPMAXUQ }, + { "vpminsq", TOKEN_INSN, C_none, 0, I_VPMINSQ }, + { "vpminuq", TOKEN_INSN, C_none, 0, I_VPMINUQ }, + { "vpmovb2m", TOKEN_INSN, C_none, 0, I_VPMOVB2M }, + { "vpmovd2m", TOKEN_INSN, C_none, 0, I_VPMOVD2M }, + { "vpmovdb", TOKEN_INSN, C_none, 0, I_VPMOVDB }, + { "vpmovdw", TOKEN_INSN, C_none, 0, I_VPMOVDW }, + { "vpmovm2b", TOKEN_INSN, C_none, 0, I_VPMOVM2B }, + { "vpmovm2d", TOKEN_INSN, C_none, 0, I_VPMOVM2D }, + { "vpmovm2q", TOKEN_INSN, C_none, 0, I_VPMOVM2Q }, + { "vpmovm2w", TOKEN_INSN, C_none, 0, I_VPMOVM2W }, + { "vpmovq2m", TOKEN_INSN, C_none, 0, I_VPMOVQ2M }, + { "vpmovqb", TOKEN_INSN, C_none, 0, I_VPMOVQB }, + { "vpmovqd", TOKEN_INSN, C_none, 0, I_VPMOVQD }, + { "vpmovqw", TOKEN_INSN, C_none, 0, I_VPMOVQW }, + { "vpmovsdb", TOKEN_INSN, C_none, 0, I_VPMOVSDB }, + { "vpmovsdw", TOKEN_INSN, C_none, 0, I_VPMOVSDW }, + { "vpmovsqb", TOKEN_INSN, C_none, 0, I_VPMOVSQB }, + { "vpmovsqd", TOKEN_INSN, C_none, 0, I_VPMOVSQD }, + { "vpmovsqw", TOKEN_INSN, C_none, 0, I_VPMOVSQW }, + { "vpmovswb", TOKEN_INSN, C_none, 0, I_VPMOVSWB }, + { "vpmovusdb", TOKEN_INSN, C_none, 0, I_VPMOVUSDB }, + { "vpmovusdw", TOKEN_INSN, C_none, 0, I_VPMOVUSDW }, + { "vpmovusqb", TOKEN_INSN, C_none, 0, I_VPMOVUSQB }, + { "vpmovusqd", TOKEN_INSN, C_none, 0, I_VPMOVUSQD }, + { "vpmovusqw", TOKEN_INSN, C_none, 0, I_VPMOVUSQW }, + { "vpmovuswb", TOKEN_INSN, C_none, 0, I_VPMOVUSWB }, + { "vpmovw2m", TOKEN_INSN, C_none, 0, I_VPMOVW2M }, + { "vpmovwb", TOKEN_INSN, C_none, 0, I_VPMOVWB }, + { "vpmullq", TOKEN_INSN, C_none, 0, I_VPMULLQ }, + { "vpmultishiftqb", TOKEN_INSN, C_none, 0, I_VPMULTISHIFTQB }, + { "vpord", TOKEN_INSN, C_none, 0, I_VPORD }, + { "vporq", TOKEN_INSN, C_none, 0, I_VPORQ }, + { "vprold", TOKEN_INSN, C_none, 0, I_VPROLD }, + { "vprolq", TOKEN_INSN, C_none, 0, I_VPROLQ }, + { "vprolvd", TOKEN_INSN, C_none, 0, I_VPROLVD }, + { "vprolvq", TOKEN_INSN, C_none, 0, I_VPROLVQ }, + { "vprord", TOKEN_INSN, C_none, 0, I_VPRORD }, + { "vprorq", TOKEN_INSN, C_none, 0, I_VPRORQ }, + { "vprorvd", TOKEN_INSN, C_none, 0, I_VPRORVD }, + { "vprorvq", TOKEN_INSN, C_none, 0, I_VPRORVQ }, + { "vpscatterdd", TOKEN_INSN, C_none, 0, I_VPSCATTERDD }, + { "vpscatterdq", TOKEN_INSN, C_none, 0, I_VPSCATTERDQ }, + { "vpscatterqd", TOKEN_INSN, C_none, 0, I_VPSCATTERQD }, + { "vpscatterqq", TOKEN_INSN, C_none, 0, I_VPSCATTERQQ }, + { "vpsllvw", TOKEN_INSN, C_none, 0, I_VPSLLVW }, + { "vpsraq", TOKEN_INSN, C_none, 0, I_VPSRAQ }, + { "vpsravq", TOKEN_INSN, C_none, 0, I_VPSRAVQ }, + { "vpsravw", TOKEN_INSN, C_none, 0, I_VPSRAVW }, + { "vpsrlvw", TOKEN_INSN, C_none, 0, I_VPSRLVW }, + { "vpternlogd", TOKEN_INSN, C_none, 0, I_VPTERNLOGD }, + { "vpternlogq", TOKEN_INSN, C_none, 0, I_VPTERNLOGQ }, + { "vptestmb", TOKEN_INSN, C_none, 0, I_VPTESTMB }, + { "vptestmd", TOKEN_INSN, C_none, 0, I_VPTESTMD }, + { "vptestmq", TOKEN_INSN, C_none, 0, I_VPTESTMQ }, + { "vptestmw", TOKEN_INSN, C_none, 0, I_VPTESTMW }, + { "vptestnmb", TOKEN_INSN, C_none, 0, I_VPTESTNMB }, + { "vptestnmd", TOKEN_INSN, C_none, 0, I_VPTESTNMD }, + { "vptestnmq", TOKEN_INSN, C_none, 0, I_VPTESTNMQ }, + { "vptestnmw", TOKEN_INSN, C_none, 0, I_VPTESTNMW }, + { "vpxord", TOKEN_INSN, C_none, 0, I_VPXORD }, + { "vpxorq", TOKEN_INSN, C_none, 0, I_VPXORQ }, + { "vrangepd", TOKEN_INSN, C_none, 0, I_VRANGEPD }, + { "vrangeps", TOKEN_INSN, C_none, 0, I_VRANGEPS }, + { "vrangesd", TOKEN_INSN, C_none, 0, I_VRANGESD }, + { "vrangess", TOKEN_INSN, C_none, 0, I_VRANGESS }, + { "vrcp14pd", TOKEN_INSN, C_none, 0, I_VRCP14PD }, + { "vrcp14ps", TOKEN_INSN, C_none, 0, I_VRCP14PS }, + { "vrcp14sd", TOKEN_INSN, C_none, 0, I_VRCP14SD }, + { "vrcp14ss", TOKEN_INSN, C_none, 0, I_VRCP14SS }, + { "vrcp28pd", TOKEN_INSN, C_none, 0, I_VRCP28PD }, + { "vrcp28ps", TOKEN_INSN, C_none, 0, I_VRCP28PS }, + { "vrcp28sd", TOKEN_INSN, C_none, 0, I_VRCP28SD }, + { "vrcp28ss", TOKEN_INSN, C_none, 0, I_VRCP28SS }, + { "vreducepd", TOKEN_INSN, C_none, 0, I_VREDUCEPD }, + { "vreduceps", TOKEN_INSN, C_none, 0, I_VREDUCEPS }, + { "vreducesd", TOKEN_INSN, C_none, 0, I_VREDUCESD }, + { "vreducess", TOKEN_INSN, C_none, 0, I_VREDUCESS }, + { "vrndscalepd", TOKEN_INSN, C_none, 0, I_VRNDSCALEPD }, + { "vrndscaleps", TOKEN_INSN, C_none, 0, I_VRNDSCALEPS }, + { "vrndscalesd", TOKEN_INSN, C_none, 0, I_VRNDSCALESD }, + { "vrndscaless", TOKEN_INSN, C_none, 0, I_VRNDSCALESS }, + { "vrsqrt14pd", TOKEN_INSN, C_none, 0, I_VRSQRT14PD }, + { "vrsqrt14ps", TOKEN_INSN, C_none, 0, I_VRSQRT14PS }, + { "vrsqrt14sd", TOKEN_INSN, C_none, 0, I_VRSQRT14SD }, + { "vrsqrt14ss", TOKEN_INSN, C_none, 0, I_VRSQRT14SS }, + { "vrsqrt28pd", TOKEN_INSN, C_none, 0, I_VRSQRT28PD }, + { "vrsqrt28ps", TOKEN_INSN, C_none, 0, I_VRSQRT28PS }, + { "vrsqrt28sd", TOKEN_INSN, C_none, 0, I_VRSQRT28SD }, + { "vrsqrt28ss", TOKEN_INSN, C_none, 0, I_VRSQRT28SS }, + { "vscalefpd", TOKEN_INSN, C_none, 0, I_VSCALEFPD }, + { "vscalefps", TOKEN_INSN, C_none, 0, I_VSCALEFPS }, + { "vscalefsd", TOKEN_INSN, C_none, 0, I_VSCALEFSD }, + { "vscalefss", TOKEN_INSN, C_none, 0, I_VSCALEFSS }, + { "vscatterdpd", TOKEN_INSN, C_none, 0, I_VSCATTERDPD }, + { "vscatterdps", TOKEN_INSN, C_none, 0, I_VSCATTERDPS }, + { "vscatterpf0dpd", TOKEN_INSN, C_none, 0, I_VSCATTERPF0DPD }, + { "vscatterpf0dps", TOKEN_INSN, C_none, 0, I_VSCATTERPF0DPS }, + { "vscatterpf0qpd", TOKEN_INSN, C_none, 0, I_VSCATTERPF0QPD }, + { "vscatterpf0qps", TOKEN_INSN, C_none, 0, I_VSCATTERPF0QPS }, + { "vscatterpf1dpd", TOKEN_INSN, C_none, 0, I_VSCATTERPF1DPD }, + { "vscatterpf1dps", TOKEN_INSN, C_none, 0, I_VSCATTERPF1DPS }, + { "vscatterpf1qpd", TOKEN_INSN, C_none, 0, I_VSCATTERPF1QPD }, + { "vscatterpf1qps", TOKEN_INSN, C_none, 0, I_VSCATTERPF1QPS }, + { "vscatterqpd", TOKEN_INSN, C_none, 0, I_VSCATTERQPD }, + { "vscatterqps", TOKEN_INSN, C_none, 0, I_VSCATTERQPS }, + { "vshuff32x4", TOKEN_INSN, C_none, 0, I_VSHUFF32X4 }, + { "vshuff64x2", TOKEN_INSN, C_none, 0, I_VSHUFF64X2 }, + { "vshufi32x4", TOKEN_INSN, C_none, 0, I_VSHUFI32X4 }, + { "vshufi64x2", TOKEN_INSN, C_none, 0, I_VSHUFI64X2 }, + { "rdpkru", TOKEN_INSN, C_none, 0, I_RDPKRU }, + { "wrpkru", TOKEN_INSN, C_none, 0, I_WRPKRU }, + { "rdpid", TOKEN_INSN, C_none, 0, I_RDPID }, + { "clflushopt", TOKEN_INSN, C_none, 0, I_CLFLUSHOPT }, + { "clwb", TOKEN_INSN, C_none, 0, I_CLWB }, + { "pcommit", TOKEN_INSN, C_none, 0, I_PCOMMIT }, + { "clzero", TOKEN_INSN, C_none, 0, I_CLZERO }, + { "ptwrite", TOKEN_INSN, C_none, 0, I_PTWRITE }, + { "cldemote", TOKEN_INSN, C_none, 0, I_CLDEMOTE }, + { "movdiri", TOKEN_INSN, C_none, 0, I_MOVDIRI }, + { "movdir64b", TOKEN_INSN, C_none, 0, I_MOVDIR64B }, + { "pconfig", TOKEN_INSN, C_none, 0, I_PCONFIG }, + { "tpause", TOKEN_INSN, C_none, 0, I_TPAUSE }, + { "umonitor", TOKEN_INSN, C_none, 0, I_UMONITOR }, + { "umwait", TOKEN_INSN, C_none, 0, I_UMWAIT }, + { "wbnoinvd", TOKEN_INSN, C_none, 0, I_WBNOINVD }, + { "gf2p8affineinvqb", TOKEN_INSN, C_none, 0, I_GF2P8AFFINEINVQB }, + { "vgf2p8affineinvqb", TOKEN_INSN, C_none, 0, I_VGF2P8AFFINEINVQB }, + { "gf2p8affineqb", TOKEN_INSN, C_none, 0, I_GF2P8AFFINEQB }, + { "vgf2p8affineqb", TOKEN_INSN, C_none, 0, I_VGF2P8AFFINEQB }, + { "gf2p8mulb", TOKEN_INSN, C_none, 0, I_GF2P8MULB }, + { "vgf2p8mulb", TOKEN_INSN, C_none, 0, I_VGF2P8MULB }, + { "vpcompressb", TOKEN_INSN, C_none, 0, I_VPCOMPRESSB }, + { "vpcompressw", TOKEN_INSN, C_none, 0, I_VPCOMPRESSW }, + { "vpexpandb", TOKEN_INSN, C_none, 0, I_VPEXPANDB }, + { "vpexpandw", TOKEN_INSN, C_none, 0, I_VPEXPANDW }, + { "vpshldw", TOKEN_INSN, C_none, 0, I_VPSHLDW }, + { "vpshldd", TOKEN_INSN, C_none, 0, I_VPSHLDD }, + { "vpshldq", TOKEN_INSN, C_none, 0, I_VPSHLDQ }, + { "vpshldvw", TOKEN_INSN, C_none, 0, I_VPSHLDVW }, + { "vpshldvd", TOKEN_INSN, C_none, 0, I_VPSHLDVD }, + { "vpshldvq", TOKEN_INSN, C_none, 0, I_VPSHLDVQ }, + { "vpshrdw", TOKEN_INSN, C_none, 0, I_VPSHRDW }, + { "vpshrdd", TOKEN_INSN, C_none, 0, I_VPSHRDD }, + { "vpshrdq", TOKEN_INSN, C_none, 0, I_VPSHRDQ }, + { "vpshrdvw", TOKEN_INSN, C_none, 0, I_VPSHRDVW }, + { "vpshrdvd", TOKEN_INSN, C_none, 0, I_VPSHRDVD }, + { "vpshrdvq", TOKEN_INSN, C_none, 0, I_VPSHRDVQ }, + { "vpdpbusd", TOKEN_INSN, C_none, 0, I_VPDPBUSD }, + { "vpdpbusds", TOKEN_INSN, C_none, 0, I_VPDPBUSDS }, + { "vpdpwssd", TOKEN_INSN, C_none, 0, I_VPDPWSSD }, + { "vpdpwssds", TOKEN_INSN, C_none, 0, I_VPDPWSSDS }, + { "vpopcntb", TOKEN_INSN, C_none, 0, I_VPOPCNTB }, + { "vpopcntw", TOKEN_INSN, C_none, 0, I_VPOPCNTW }, + { "vpopcntd", TOKEN_INSN, C_none, 0, I_VPOPCNTD }, + { "vpopcntq", TOKEN_INSN, C_none, 0, I_VPOPCNTQ }, + { "vpshufbitqmb", TOKEN_INSN, C_none, 0, I_VPSHUFBITQMB }, + { "v4fmaddps", TOKEN_INSN, C_none, 0, I_V4FMADDPS }, + { "v4fnmaddps", TOKEN_INSN, C_none, 0, I_V4FNMADDPS }, + { "v4fmaddss", TOKEN_INSN, C_none, 0, I_V4FMADDSS }, + { "v4fnmaddss", TOKEN_INSN, C_none, 0, I_V4FNMADDSS }, + { "v4dpwssds", TOKEN_INSN, C_none, 0, I_V4DPWSSDS }, + { "v4dpwssd", TOKEN_INSN, C_none, 0, I_V4DPWSSD }, + { "encls", TOKEN_INSN, C_none, 0, I_ENCLS }, + { "enclu", TOKEN_INSN, C_none, 0, I_ENCLU }, + { "enclv", TOKEN_INSN, C_none, 0, I_ENCLV }, + { "hint_nop0", TOKEN_INSN, C_none, 0, I_HINT_NOP0 }, + { "hint_nop1", TOKEN_INSN, C_none, 0, I_HINT_NOP1 }, + { "hint_nop2", TOKEN_INSN, C_none, 0, I_HINT_NOP2 }, + { "hint_nop3", TOKEN_INSN, C_none, 0, I_HINT_NOP3 }, + { "hint_nop4", TOKEN_INSN, C_none, 0, I_HINT_NOP4 }, + { "hint_nop5", TOKEN_INSN, C_none, 0, I_HINT_NOP5 }, + { "hint_nop6", TOKEN_INSN, C_none, 0, I_HINT_NOP6 }, + { "hint_nop7", TOKEN_INSN, C_none, 0, I_HINT_NOP7 }, + { "hint_nop8", TOKEN_INSN, C_none, 0, I_HINT_NOP8 }, + { "hint_nop9", TOKEN_INSN, C_none, 0, I_HINT_NOP9 }, + { "hint_nop10", TOKEN_INSN, C_none, 0, I_HINT_NOP10 }, + { "hint_nop11", TOKEN_INSN, C_none, 0, I_HINT_NOP11 }, + { "hint_nop12", TOKEN_INSN, C_none, 0, I_HINT_NOP12 }, + { "hint_nop13", TOKEN_INSN, C_none, 0, I_HINT_NOP13 }, + { "hint_nop14", TOKEN_INSN, C_none, 0, I_HINT_NOP14 }, + { "hint_nop15", TOKEN_INSN, C_none, 0, I_HINT_NOP15 }, + { "hint_nop16", TOKEN_INSN, C_none, 0, I_HINT_NOP16 }, + { "hint_nop17", TOKEN_INSN, C_none, 0, I_HINT_NOP17 }, + { "hint_nop18", TOKEN_INSN, C_none, 0, I_HINT_NOP18 }, + { "hint_nop19", TOKEN_INSN, C_none, 0, I_HINT_NOP19 }, + { "hint_nop20", TOKEN_INSN, C_none, 0, I_HINT_NOP20 }, + { "hint_nop21", TOKEN_INSN, C_none, 0, I_HINT_NOP21 }, + { "hint_nop22", TOKEN_INSN, C_none, 0, I_HINT_NOP22 }, + { "hint_nop23", TOKEN_INSN, C_none, 0, I_HINT_NOP23 }, + { "hint_nop24", TOKEN_INSN, C_none, 0, I_HINT_NOP24 }, + { "hint_nop25", TOKEN_INSN, C_none, 0, I_HINT_NOP25 }, + { "hint_nop26", TOKEN_INSN, C_none, 0, I_HINT_NOP26 }, + { "hint_nop27", TOKEN_INSN, C_none, 0, I_HINT_NOP27 }, + { "hint_nop28", TOKEN_INSN, C_none, 0, I_HINT_NOP28 }, + { "hint_nop29", TOKEN_INSN, C_none, 0, I_HINT_NOP29 }, + { "hint_nop30", TOKEN_INSN, C_none, 0, I_HINT_NOP30 }, + { "hint_nop31", TOKEN_INSN, C_none, 0, I_HINT_NOP31 }, + { "hint_nop32", TOKEN_INSN, C_none, 0, I_HINT_NOP32 }, + { "hint_nop33", TOKEN_INSN, C_none, 0, I_HINT_NOP33 }, + { "hint_nop34", TOKEN_INSN, C_none, 0, I_HINT_NOP34 }, + { "hint_nop35", TOKEN_INSN, C_none, 0, I_HINT_NOP35 }, + { "hint_nop36", TOKEN_INSN, C_none, 0, I_HINT_NOP36 }, + { "hint_nop37", TOKEN_INSN, C_none, 0, I_HINT_NOP37 }, + { "hint_nop38", TOKEN_INSN, C_none, 0, I_HINT_NOP38 }, + { "hint_nop39", TOKEN_INSN, C_none, 0, I_HINT_NOP39 }, + { "hint_nop40", TOKEN_INSN, C_none, 0, I_HINT_NOP40 }, + { "hint_nop41", TOKEN_INSN, C_none, 0, I_HINT_NOP41 }, + { "hint_nop42", TOKEN_INSN, C_none, 0, I_HINT_NOP42 }, + { "hint_nop43", TOKEN_INSN, C_none, 0, I_HINT_NOP43 }, + { "hint_nop44", TOKEN_INSN, C_none, 0, I_HINT_NOP44 }, + { "hint_nop45", TOKEN_INSN, C_none, 0, I_HINT_NOP45 }, + { "hint_nop46", TOKEN_INSN, C_none, 0, I_HINT_NOP46 }, + { "hint_nop47", TOKEN_INSN, C_none, 0, I_HINT_NOP47 }, + { "hint_nop48", TOKEN_INSN, C_none, 0, I_HINT_NOP48 }, + { "hint_nop49", TOKEN_INSN, C_none, 0, I_HINT_NOP49 }, + { "hint_nop50", TOKEN_INSN, C_none, 0, I_HINT_NOP50 }, + { "hint_nop51", TOKEN_INSN, C_none, 0, I_HINT_NOP51 }, + { "hint_nop52", TOKEN_INSN, C_none, 0, I_HINT_NOP52 }, + { "hint_nop53", TOKEN_INSN, C_none, 0, I_HINT_NOP53 }, + { "hint_nop54", TOKEN_INSN, C_none, 0, I_HINT_NOP54 }, + { "hint_nop55", TOKEN_INSN, C_none, 0, I_HINT_NOP55 }, + { "hint_nop56", TOKEN_INSN, C_none, 0, I_HINT_NOP56 }, + { "hint_nop57", TOKEN_INSN, C_none, 0, I_HINT_NOP57 }, + { "hint_nop58", TOKEN_INSN, C_none, 0, I_HINT_NOP58 }, + { "hint_nop59", TOKEN_INSN, C_none, 0, I_HINT_NOP59 }, + { "hint_nop60", TOKEN_INSN, C_none, 0, I_HINT_NOP60 }, + { "hint_nop61", TOKEN_INSN, C_none, 0, I_HINT_NOP61 }, + { "hint_nop62", TOKEN_INSN, C_none, 0, I_HINT_NOP62 }, + { "hint_nop63", TOKEN_INSN, C_none, 0, I_HINT_NOP63 }, + { "al", TOKEN_REG, 0, 0, R_AL }, + { "ah", TOKEN_REG, 0, 0, R_AH }, + { "ax", TOKEN_REG, 0, 0, R_AX }, + { "eax", TOKEN_REG, 0, 0, R_EAX }, + { "rax", TOKEN_REG, 0, 0, R_RAX }, + { "bl", TOKEN_REG, 0, 0, R_BL }, + { "bh", TOKEN_REG, 0, 0, R_BH }, + { "bx", TOKEN_REG, 0, 0, R_BX }, + { "ebx", TOKEN_REG, 0, 0, R_EBX }, + { "rbx", TOKEN_REG, 0, 0, R_RBX }, + { "cl", TOKEN_REG, 0, 0, R_CL }, + { "ch", TOKEN_REG, 0, 0, R_CH }, + { "cx", TOKEN_REG, 0, 0, R_CX }, + { "ecx", TOKEN_REG, 0, 0, R_ECX }, + { "rcx", TOKEN_REG, 0, 0, R_RCX }, + { "dl", TOKEN_REG, 0, 0, R_DL }, + { "dh", TOKEN_REG, 0, 0, R_DH }, + { "dx", TOKEN_REG, 0, 0, R_DX }, + { "edx", TOKEN_REG, 0, 0, R_EDX }, + { "rdx", TOKEN_REG, 0, 0, R_RDX }, + { "spl", TOKEN_REG, 0, 0, R_SPL }, + { "sp", TOKEN_REG, 0, 0, R_SP }, + { "esp", TOKEN_REG, 0, 0, R_ESP }, + { "rsp", TOKEN_REG, 0, 0, R_RSP }, + { "bpl", TOKEN_REG, 0, 0, R_BPL }, + { "bp", TOKEN_REG, 0, 0, R_BP }, + { "ebp", TOKEN_REG, 0, 0, R_EBP }, + { "rbp", TOKEN_REG, 0, 0, R_RBP }, + { "sil", TOKEN_REG, 0, 0, R_SIL }, + { "si", TOKEN_REG, 0, 0, R_SI }, + { "esi", TOKEN_REG, 0, 0, R_ESI }, + { "rsi", TOKEN_REG, 0, 0, R_RSI }, + { "dil", TOKEN_REG, 0, 0, R_DIL }, + { "di", TOKEN_REG, 0, 0, R_DI }, + { "edi", TOKEN_REG, 0, 0, R_EDI }, + { "rdi", TOKEN_REG, 0, 0, R_RDI }, + { "r8b", TOKEN_REG, 0, 0, R_R8B }, + { "r9b", TOKEN_REG, 0, 0, R_R9B }, + { "r10b", TOKEN_REG, 0, 0, R_R10B }, + { "r11b", TOKEN_REG, 0, 0, R_R11B }, + { "r12b", TOKEN_REG, 0, 0, R_R12B }, + { "r13b", TOKEN_REG, 0, 0, R_R13B }, + { "r14b", TOKEN_REG, 0, 0, R_R14B }, + { "r15b", TOKEN_REG, 0, 0, R_R15B }, + { "r8w", TOKEN_REG, 0, 0, R_R8W }, + { "r9w", TOKEN_REG, 0, 0, R_R9W }, + { "r10w", TOKEN_REG, 0, 0, R_R10W }, + { "r11w", TOKEN_REG, 0, 0, R_R11W }, + { "r12w", TOKEN_REG, 0, 0, R_R12W }, + { "r13w", TOKEN_REG, 0, 0, R_R13W }, + { "r14w", TOKEN_REG, 0, 0, R_R14W }, + { "r15w", TOKEN_REG, 0, 0, R_R15W }, + { "r8d", TOKEN_REG, 0, 0, R_R8D }, + { "r9d", TOKEN_REG, 0, 0, R_R9D }, + { "r10d", TOKEN_REG, 0, 0, R_R10D }, + { "r11d", TOKEN_REG, 0, 0, R_R11D }, + { "r12d", TOKEN_REG, 0, 0, R_R12D }, + { "r13d", TOKEN_REG, 0, 0, R_R13D }, + { "r14d", TOKEN_REG, 0, 0, R_R14D }, + { "r15d", TOKEN_REG, 0, 0, R_R15D }, + { "r8", TOKEN_REG, 0, 0, R_R8 }, + { "r9", TOKEN_REG, 0, 0, R_R9 }, + { "r10", TOKEN_REG, 0, 0, R_R10 }, + { "r11", TOKEN_REG, 0, 0, R_R11 }, + { "r12", TOKEN_REG, 0, 0, R_R12 }, + { "r13", TOKEN_REG, 0, 0, R_R13 }, + { "r14", TOKEN_REG, 0, 0, R_R14 }, + { "r15", TOKEN_REG, 0, 0, R_R15 }, + { "es", TOKEN_REG, 0, 0, R_ES }, + { "cs", TOKEN_REG, 0, 0, R_CS }, + { "ss", TOKEN_REG, 0, 0, R_SS }, + { "ds", TOKEN_REG, 0, 0, R_DS }, + { "fs", TOKEN_REG, 0, 0, R_FS }, + { "gs", TOKEN_REG, 0, 0, R_GS }, + { "segr6", TOKEN_REG, 0, 0, R_SEGR6 }, + { "segr7", TOKEN_REG, 0, 0, R_SEGR7 }, + { "cr0", TOKEN_REG, 0, 0, R_CR0 }, + { "cr1", TOKEN_REG, 0, 0, R_CR1 }, + { "cr2", TOKEN_REG, 0, 0, R_CR2 }, + { "cr3", TOKEN_REG, 0, 0, R_CR3 }, + { "cr4", TOKEN_REG, 0, 0, R_CR4 }, + { "cr5", TOKEN_REG, 0, 0, R_CR5 }, + { "cr6", TOKEN_REG, 0, 0, R_CR6 }, + { "cr7", TOKEN_REG, 0, 0, R_CR7 }, + { "cr8", TOKEN_REG, 0, 0, R_CR8 }, + { "cr9", TOKEN_REG, 0, 0, R_CR9 }, + { "cr10", TOKEN_REG, 0, 0, R_CR10 }, + { "cr11", TOKEN_REG, 0, 0, R_CR11 }, + { "cr12", TOKEN_REG, 0, 0, R_CR12 }, + { "cr13", TOKEN_REG, 0, 0, R_CR13 }, + { "cr14", TOKEN_REG, 0, 0, R_CR14 }, + { "cr15", TOKEN_REG, 0, 0, R_CR15 }, + { "dr0", TOKEN_REG, 0, 0, R_DR0 }, + { "dr1", TOKEN_REG, 0, 0, R_DR1 }, + { "dr2", TOKEN_REG, 0, 0, R_DR2 }, + { "dr3", TOKEN_REG, 0, 0, R_DR3 }, + { "dr4", TOKEN_REG, 0, 0, R_DR4 }, + { "dr5", TOKEN_REG, 0, 0, R_DR5 }, + { "dr6", TOKEN_REG, 0, 0, R_DR6 }, + { "dr7", TOKEN_REG, 0, 0, R_DR7 }, + { "dr8", TOKEN_REG, 0, 0, R_DR8 }, + { "dr9", TOKEN_REG, 0, 0, R_DR9 }, + { "dr10", TOKEN_REG, 0, 0, R_DR10 }, + { "dr11", TOKEN_REG, 0, 0, R_DR11 }, + { "dr12", TOKEN_REG, 0, 0, R_DR12 }, + { "dr13", TOKEN_REG, 0, 0, R_DR13 }, + { "dr14", TOKEN_REG, 0, 0, R_DR14 }, + { "dr15", TOKEN_REG, 0, 0, R_DR15 }, + { "tr0", TOKEN_REG, 0, 0, R_TR0 }, + { "tr1", TOKEN_REG, 0, 0, R_TR1 }, + { "tr2", TOKEN_REG, 0, 0, R_TR2 }, + { "tr3", TOKEN_REG, 0, 0, R_TR3 }, + { "tr4", TOKEN_REG, 0, 0, R_TR4 }, + { "tr5", TOKEN_REG, 0, 0, R_TR5 }, + { "tr6", TOKEN_REG, 0, 0, R_TR6 }, + { "tr7", TOKEN_REG, 0, 0, R_TR7 }, + { "st0", TOKEN_REG, 0, 0, R_ST0 }, + { "st1", TOKEN_REG, 0, 0, R_ST1 }, + { "st2", TOKEN_REG, 0, 0, R_ST2 }, + { "st3", TOKEN_REG, 0, 0, R_ST3 }, + { "st4", TOKEN_REG, 0, 0, R_ST4 }, + { "st5", TOKEN_REG, 0, 0, R_ST5 }, + { "st6", TOKEN_REG, 0, 0, R_ST6 }, + { "st7", TOKEN_REG, 0, 0, R_ST7 }, + { "mm0", TOKEN_REG, 0, 0, R_MM0 }, + { "mm1", TOKEN_REG, 0, 0, R_MM1 }, + { "mm2", TOKEN_REG, 0, 0, R_MM2 }, + { "mm3", TOKEN_REG, 0, 0, R_MM3 }, + { "mm4", TOKEN_REG, 0, 0, R_MM4 }, + { "mm5", TOKEN_REG, 0, 0, R_MM5 }, + { "mm6", TOKEN_REG, 0, 0, R_MM6 }, + { "mm7", TOKEN_REG, 0, 0, R_MM7 }, + { "xmm0", TOKEN_REG, 0, 0, R_XMM0 }, + { "xmm1", TOKEN_REG, 0, 0, R_XMM1 }, + { "xmm2", TOKEN_REG, 0, 0, R_XMM2 }, + { "xmm3", TOKEN_REG, 0, 0, R_XMM3 }, + { "xmm4", TOKEN_REG, 0, 0, R_XMM4 }, + { "xmm5", TOKEN_REG, 0, 0, R_XMM5 }, + { "xmm6", TOKEN_REG, 0, 0, R_XMM6 }, + { "xmm7", TOKEN_REG, 0, 0, R_XMM7 }, + { "xmm8", TOKEN_REG, 0, 0, R_XMM8 }, + { "xmm9", TOKEN_REG, 0, 0, R_XMM9 }, + { "xmm10", TOKEN_REG, 0, 0, R_XMM10 }, + { "xmm11", TOKEN_REG, 0, 0, R_XMM11 }, + { "xmm12", TOKEN_REG, 0, 0, R_XMM12 }, + { "xmm13", TOKEN_REG, 0, 0, R_XMM13 }, + { "xmm14", TOKEN_REG, 0, 0, R_XMM14 }, + { "xmm15", TOKEN_REG, 0, 0, R_XMM15 }, + { "xmm16", TOKEN_REG, 0, 0, R_XMM16 }, + { "xmm17", TOKEN_REG, 0, 0, R_XMM17 }, + { "xmm18", TOKEN_REG, 0, 0, R_XMM18 }, + { "xmm19", TOKEN_REG, 0, 0, R_XMM19 }, + { "xmm20", TOKEN_REG, 0, 0, R_XMM20 }, + { "xmm21", TOKEN_REG, 0, 0, R_XMM21 }, + { "xmm22", TOKEN_REG, 0, 0, R_XMM22 }, + { "xmm23", TOKEN_REG, 0, 0, R_XMM23 }, + { "xmm24", TOKEN_REG, 0, 0, R_XMM24 }, + { "xmm25", TOKEN_REG, 0, 0, R_XMM25 }, + { "xmm26", TOKEN_REG, 0, 0, R_XMM26 }, + { "xmm27", TOKEN_REG, 0, 0, R_XMM27 }, + { "xmm28", TOKEN_REG, 0, 0, R_XMM28 }, + { "xmm29", TOKEN_REG, 0, 0, R_XMM29 }, + { "xmm30", TOKEN_REG, 0, 0, R_XMM30 }, + { "xmm31", TOKEN_REG, 0, 0, R_XMM31 }, + { "ymm0", TOKEN_REG, 0, 0, R_YMM0 }, + { "ymm1", TOKEN_REG, 0, 0, R_YMM1 }, + { "ymm2", TOKEN_REG, 0, 0, R_YMM2 }, + { "ymm3", TOKEN_REG, 0, 0, R_YMM3 }, + { "ymm4", TOKEN_REG, 0, 0, R_YMM4 }, + { "ymm5", TOKEN_REG, 0, 0, R_YMM5 }, + { "ymm6", TOKEN_REG, 0, 0, R_YMM6 }, + { "ymm7", TOKEN_REG, 0, 0, R_YMM7 }, + { "ymm8", TOKEN_REG, 0, 0, R_YMM8 }, + { "ymm9", TOKEN_REG, 0, 0, R_YMM9 }, + { "ymm10", TOKEN_REG, 0, 0, R_YMM10 }, + { "ymm11", TOKEN_REG, 0, 0, R_YMM11 }, + { "ymm12", TOKEN_REG, 0, 0, R_YMM12 }, + { "ymm13", TOKEN_REG, 0, 0, R_YMM13 }, + { "ymm14", TOKEN_REG, 0, 0, R_YMM14 }, + { "ymm15", TOKEN_REG, 0, 0, R_YMM15 }, + { "ymm16", TOKEN_REG, 0, 0, R_YMM16 }, + { "ymm17", TOKEN_REG, 0, 0, R_YMM17 }, + { "ymm18", TOKEN_REG, 0, 0, R_YMM18 }, + { "ymm19", TOKEN_REG, 0, 0, R_YMM19 }, + { "ymm20", TOKEN_REG, 0, 0, R_YMM20 }, + { "ymm21", TOKEN_REG, 0, 0, R_YMM21 }, + { "ymm22", TOKEN_REG, 0, 0, R_YMM22 }, + { "ymm23", TOKEN_REG, 0, 0, R_YMM23 }, + { "ymm24", TOKEN_REG, 0, 0, R_YMM24 }, + { "ymm25", TOKEN_REG, 0, 0, R_YMM25 }, + { "ymm26", TOKEN_REG, 0, 0, R_YMM26 }, + { "ymm27", TOKEN_REG, 0, 0, R_YMM27 }, + { "ymm28", TOKEN_REG, 0, 0, R_YMM28 }, + { "ymm29", TOKEN_REG, 0, 0, R_YMM29 }, + { "ymm30", TOKEN_REG, 0, 0, R_YMM30 }, + { "ymm31", TOKEN_REG, 0, 0, R_YMM31 }, + { "zmm0", TOKEN_REG, 0, 0, R_ZMM0 }, + { "zmm1", TOKEN_REG, 0, 0, R_ZMM1 }, + { "zmm2", TOKEN_REG, 0, 0, R_ZMM2 }, + { "zmm3", TOKEN_REG, 0, 0, R_ZMM3 }, + { "zmm4", TOKEN_REG, 0, 0, R_ZMM4 }, + { "zmm5", TOKEN_REG, 0, 0, R_ZMM5 }, + { "zmm6", TOKEN_REG, 0, 0, R_ZMM6 }, + { "zmm7", TOKEN_REG, 0, 0, R_ZMM7 }, + { "zmm8", TOKEN_REG, 0, 0, R_ZMM8 }, + { "zmm9", TOKEN_REG, 0, 0, R_ZMM9 }, + { "zmm10", TOKEN_REG, 0, 0, R_ZMM10 }, + { "zmm11", TOKEN_REG, 0, 0, R_ZMM11 }, + { "zmm12", TOKEN_REG, 0, 0, R_ZMM12 }, + { "zmm13", TOKEN_REG, 0, 0, R_ZMM13 }, + { "zmm14", TOKEN_REG, 0, 0, R_ZMM14 }, + { "zmm15", TOKEN_REG, 0, 0, R_ZMM15 }, + { "zmm16", TOKEN_REG, 0, 0, R_ZMM16 }, + { "zmm17", TOKEN_REG, 0, 0, R_ZMM17 }, + { "zmm18", TOKEN_REG, 0, 0, R_ZMM18 }, + { "zmm19", TOKEN_REG, 0, 0, R_ZMM19 }, + { "zmm20", TOKEN_REG, 0, 0, R_ZMM20 }, + { "zmm21", TOKEN_REG, 0, 0, R_ZMM21 }, + { "zmm22", TOKEN_REG, 0, 0, R_ZMM22 }, + { "zmm23", TOKEN_REG, 0, 0, R_ZMM23 }, + { "zmm24", TOKEN_REG, 0, 0, R_ZMM24 }, + { "zmm25", TOKEN_REG, 0, 0, R_ZMM25 }, + { "zmm26", TOKEN_REG, 0, 0, R_ZMM26 }, + { "zmm27", TOKEN_REG, 0, 0, R_ZMM27 }, + { "zmm28", TOKEN_REG, 0, 0, R_ZMM28 }, + { "zmm29", TOKEN_REG, 0, 0, R_ZMM29 }, + { "zmm30", TOKEN_REG, 0, 0, R_ZMM30 }, + { "zmm31", TOKEN_REG, 0, 0, R_ZMM31 }, + { "k0", TOKEN_REG, 0, 0, R_K0 }, + { "k1", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K1 }, + { "k2", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K2 }, + { "k3", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K3 }, + { "k4", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K4 }, + { "k5", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K5 }, + { "k6", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K6 }, + { "k7", TOKEN_REG, 0, TFLAG_BRC_OPT, R_K7 }, + { "bnd0", TOKEN_REG, 0, 0, R_BND0 }, + { "bnd1", TOKEN_REG, 0, 0, R_BND1 }, + { "bnd2", TOKEN_REG, 0, 0, R_BND2 }, + { "bnd3", TOKEN_REG, 0, 0, R_BND3 }, + { "a16", TOKEN_PREFIX, 0, 0, P_A16 }, + { "a32", TOKEN_PREFIX, 0, 0, P_A32 }, + { "a64", TOKEN_PREFIX, 0, 0, P_A64 }, + { "asp", TOKEN_PREFIX, 0, 0, P_ASP }, + { "lock", TOKEN_PREFIX, 0, 0, P_LOCK }, + { "o16", TOKEN_PREFIX, 0, 0, P_O16 }, + { "o32", TOKEN_PREFIX, 0, 0, P_O32 }, + { "o64", TOKEN_PREFIX, 0, 0, P_O64 }, + { "osp", TOKEN_PREFIX, 0, 0, P_OSP }, + { "rep", TOKEN_PREFIX, 0, 0, P_REP }, + { "repe", TOKEN_PREFIX, 0, 0, P_REPE }, + { "repne", TOKEN_PREFIX, 0, 0, P_REPNE }, + { "repnz", TOKEN_PREFIX, 0, 0, P_REPNZ }, + { "repz", TOKEN_PREFIX, 0, 0, P_REPZ }, + { "times", TOKEN_PREFIX, 0, 0, P_TIMES }, + { "wait", TOKEN_PREFIX, 0, 0, P_WAIT }, + { "xacquire", TOKEN_PREFIX, 0, 0, P_XACQUIRE }, + { "xrelease", TOKEN_PREFIX, 0, 0, P_XRELEASE }, + { "bnd", TOKEN_PREFIX, 0, 0, P_BND }, + { "nobnd", TOKEN_PREFIX, 0, 0, P_NOBND }, + { "abs", TOKEN_SPECIAL, 0, 0, S_ABS }, + { "byte", TOKEN_SPECIAL, 0, 0, S_BYTE }, + { "dword", TOKEN_SPECIAL, 0, 0, S_DWORD }, + { "far", TOKEN_SPECIAL, 0, 0, S_FAR }, + { "long", TOKEN_SPECIAL, 0, 0, S_LONG }, + { "near", TOKEN_SPECIAL, 0, 0, S_NEAR }, + { "nosplit", TOKEN_SPECIAL, 0, 0, S_NOSPLIT }, + { "oword", TOKEN_SPECIAL, 0, 0, S_OWORD }, + { "qword", TOKEN_SPECIAL, 0, 0, S_QWORD }, + { "rel", TOKEN_SPECIAL, 0, 0, S_REL }, + { "short", TOKEN_SPECIAL, 0, 0, S_SHORT }, + { "strict", TOKEN_SPECIAL, 0, 0, S_STRICT }, + { "to", TOKEN_SPECIAL, 0, 0, S_TO }, + { "tword", TOKEN_SPECIAL, 0, 0, S_TWORD }, + { "word", TOKEN_SPECIAL, 0, 0, S_WORD }, + { "yword", TOKEN_SPECIAL, 0, 0, S_YWORD }, + { "zword", TOKEN_SPECIAL, 0, 0, S_ZWORD }, + { "ptr", TOKEN_ID, 0, TFLAG_WARN, 0 }, + { "__infinity__", TOKEN_FLOAT, 0, 0, 0 }, + { "__nan__", TOKEN_FLOAT, 0, 0, 0 }, + { "__qnan__", TOKEN_FLOAT, 0, 0, 0 }, + { "__snan__", TOKEN_FLOAT, 0, 0, 0 }, + { "__float8__", TOKEN_FLOATIZE, 0, 0, FLOAT_8 }, + { "__float16__", TOKEN_FLOATIZE, 0, 0, FLOAT_16 }, + { "__float32__", TOKEN_FLOATIZE, 0, 0, FLOAT_32 }, + { "__float64__", TOKEN_FLOATIZE, 0, 0, FLOAT_64 }, + { "__float80m__", TOKEN_FLOATIZE, 0, 0, FLOAT_80M }, + { "__float80e__", TOKEN_FLOATIZE, 0, 0, FLOAT_80E }, + { "__float128l__", TOKEN_FLOATIZE, 0, 0, FLOAT_128L }, + { "__float128h__", TOKEN_FLOATIZE, 0, 0, FLOAT_128H }, + { "__utf16__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF16 }, + { "__utf16le__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF16LE }, + { "__utf16be__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF16BE }, + { "__utf32__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF32 }, + { "__utf32le__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF32LE }, + { "__utf32be__", TOKEN_STRFUNC, 0, 0, STRFUNC_UTF32BE }, + { "__ilog2e__", TOKEN_IFUNC, 0, 0, IFUNC_ILOG2E }, + { "__ilog2w__", TOKEN_IFUNC, 0, 0, IFUNC_ILOG2W }, + { "__ilog2f__", TOKEN_IFUNC, 0, 0, IFUNC_ILOG2F }, + { "__ilog2c__", TOKEN_IFUNC, 0, 0, IFUNC_ILOG2C }, + { "seg", TOKEN_SEG, 0, 0, 0 }, + { "wrt", TOKEN_WRT, 0, 0, 0 }, + { "1to2", TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO2 }, + { "1to4", TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO4 }, + { "1to8", TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO8 }, + { "1to16", TOKEN_DECORATOR, 0, TFLAG_BRC | TFLAG_BRDCAST , BRC_1TO16 }, + { "rn-sae", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_RN }, + { "rd-sae", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_RD }, + { "ru-sae", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_RU }, + { "rz-sae", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_RZ }, + { "sae", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_SAE }, + { "z", TOKEN_DECORATOR, 0, TFLAG_BRC, BRC_Z }, + { "evex", TOKEN_PREFIX, 0, TFLAG_BRC, P_EVEX }, + { "vex3", TOKEN_PREFIX, 0, TFLAG_BRC, P_VEX3 }, + { "vex2", TOKEN_PREFIX, 0, TFLAG_BRC, P_VEX2 }, + }; + uint32_t k1, k2; + uint64_t crc; + uint16_t ix; + const struct tokendata *data; + + tv->t_flag = 0; + crc = crc64(UINT64_C(0xace2d0e480575791), token); + k1 = (uint32_t)crc; + k2 = (uint32_t)(crc >> 32); + + ix = hash1[k1 & 0x7ff] + hash2[k2 & 0x7ff]; + if (ix >= 2283) + return tv->t_type = TOKEN_ID; + + data = &tokendata[ix]; + if (strcmp(data->string, token)) + return tv->t_type = TOKEN_ID; + + tv->t_integer = data->num; + tv->t_inttwo = data->aux; + tv->t_flag = data->tokflag; + return tv->t_type = data->tokentype; +} diff --git a/asm/tokhash.pl b/asm/tokhash.pl new file mode 100644 index 0000000..9bc2b91 --- /dev/null +++ b/asm/tokhash.pl @@ -0,0 +1,284 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2014 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. +## +## -------------------------------------------------------------------------- + +# +# Generate a perfect hash for token parsing +# +# Usage: tokenhash.pl insns.dat regs.dat tokens.dat +# + +require 'phash.ph'; + +my($output, $insns_dat, $regs_dat, $tokens_dat) = @ARGV; + +%tokens = (); +@tokendata = (); + +# +# List of condition codes +# +@conditions = ('a', 'ae', 'b', 'be', 'c', 'e', 'g', 'ge', 'l', 'le', + 'na', 'nae', 'nb', 'nbe', 'nc', 'ne', 'ng', 'nge', 'nl', + 'nle', 'no', 'np', 'ns', 'nz', 'o', 'p', 'pe', 'po', 's', 'z'); + +# +# Read insns.dat +# +open(ID, '<', $insns_dat) or die "$0: cannot open $insns_dat: $!\n"; +while (defined($line = )) { + if ($line =~ /^([A-Z0-9_]+)(|cc)\s/) { + $insn = $1.$2; + ($token = $1) =~ tr/A-Z/a-z/; + + if ($2 eq '') { + # Single instruction token + if (!defined($tokens{$token})) { + $tokens{$token} = scalar @tokendata; + push(@tokendata, "\"${token}\", TOKEN_INSN, C_none, 0, I_${insn}"); + } + } else { + # Conditional instruction + foreach $cc (@conditions) { + if (!defined($tokens{$token.$cc})) { + $tokens{$token.$cc} = scalar @tokendata; + push(@tokendata, "\"${token}${cc}\", TOKEN_INSN, C_\U$cc\E, 0, I_${insn}"); + } + } + } + } +} +close(ID); + +# +# Read regs.dat +# +open(RD, '<', $regs_dat) or die "$0: cannot open $regs_dat: $!\n"; +while (defined($line = )) { + if ($line =~ /^([a-z0-9_-]+)\s*\S+\s*\S+\s*[0-9]+\s*(\S*)/) { + $reg = $1; + $reg_flag = $2; + + 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--) { + if (defined($tokens{$reg})) { + die "Duplicate definition: $reg\n"; + } + $tokens{$reg} = scalar @tokendata; + if ($reg_flag eq '') { + push(@tokendata, "\"${reg}\", TOKEN_REG, 0, 0, R_\U${reg}\E"); + } else { + push(@tokendata, "\"${reg}\", TOKEN_REG, 0, ${reg_flag}, R_\U${reg}\E"); + } + + if (defined($reg_prefix)) { + $reg_nr++; + $reg = sprintf("%s%u%s", $reg_prefix, $reg_nr, $reg_suffix); + } else { + # Not a dashed sequence + die if ($nregs); + } + } + } +} +close(RD); + +# +# Read tokens.dat +# +open(TD, '<', $tokens_dat) or die "$0: cannot open $tokens_dat: $!\n"; +while (defined($line = )) { + if ($line =~ /^\%\s+(.*)$/) { + $pattern = $1; + } elsif ($line =~ /^([a-z0-9_-]+)/) { + $token = $1; + + if (defined($tokens{$token})) { + die "Duplicate definition: $token\n"; + } + $tokens{$token} = scalar @tokendata; + + $data = $pattern; + if ($data =~ /^(.*)\{(.*)\}(.*)$/) { + my $head = $1, $tail = $3; + my $px = $2; + + $px =~ s/\*/(.*)/g; + if ($token =~ /$px/i) { + $data = $head."\U$1".$tail; + } else { + die "$0: token $token doesn't match $px\n"; + } + } + + $data =~ s/\*/\U$token/g; + + push(@tokendata, "\"$token\", $data"); + } +} +close(TD); + +if ($output eq 'h') { + # + # tokens.h + # + + $max_len = 0; + foreach $token (keys(%tokens)) { + if (length($token) > $max_len) { + $max_len = length($token); + } + } + + print "/*\n"; + print " * This file is generated from insns.dat, regs.dat and token.dat\n"; + print " * by tokhash.pl; do not edit.\n"; + print " */\n"; + print "\n"; + + print "#ifndef NASM_TOKENS_H\n"; + print "#define NASM_TOKENS_H\n"; + print "\n"; + print "#define MAX_KEYWORD $max_len /* length of longest keyword */\n"; + print "\n"; + print "#endif /* NASM_TOKENS_H */\n"; +} elsif ($output eq 'c') { + # + # tokhash.c + # + + @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 "/*\n"; + print " * This file is generated from insns.dat, regs.dat and token.dat\n"; + print " * by tokhash.pl; do not edit.\n"; + print " */\n"; + print "\n"; + + print "#include \"compiler.h\"\n"; + print "#include \n"; + print "#include \"nasm.h\"\n"; + print "#include \"hashtbl.h\"\n"; + print "#include \"insns.h\"\n"; + print "#include \"stdscan.h\"\n"; + print "\n"; + + # These somewhat odd sizes and ordering thereof are due to the + # relative ranges of the types; this makes it fit in 16 bytes on + # 64-bit machines and 12 bytes on 32-bit machines. + print "struct tokendata {\n"; + print " const char *string;\n"; + print " int16_t tokentype;\n"; + print " int8_t aux;\n"; + print " int8_t tokflag;\n"; + print " int32_t num;\n"; + print "};\n"; + print "\n"; + + print "int nasm_token_hash(const char *token, struct tokenval *tv)\n"; + print "{\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 "#define UNUSED (65535/3)\n"; + + print " static const int16_t hash1[$n] = {\n"; + for ($i = 0; $i < $n; $i++) { + my $h = ${$g}[$i*2+0]; + print " ", defined($h) ? $h : 'UNUSED', ",\n"; + } + print " };\n"; + + print " static const int16_t hash2[$n] = {\n"; + for ($i = 0; $i < $n; $i++) { + my $h = ${$g}[$i*2+1]; + print " ", defined($h) ? $h : 'UNUSED', ",\n"; + } + print " };\n"; + + printf " static const struct tokendata tokendata[%d] = {\n", scalar(@tokendata); + foreach $d (@tokendata) { + print " { ", $d, " },\n"; + } + print " };\n"; + + print " uint32_t k1, k2;\n"; + print " uint64_t crc;\n"; + # For correct overflow behavior, "ix" should be unsigned of the same + # width as the hash arrays. + print " uint16_t ix;\n"; + print " const struct tokendata *data;\n"; + print "\n"; + printf " tv->t_flag = 0;\n"; + printf " crc = crc64(UINT64_C(0x%08x%08x), token);\n", + $$sv[0], $$sv[1]; + print " k1 = (uint32_t)crc;\n"; + print " k2 = (uint32_t)(crc >> 32);\n"; + print "\n"; + printf " ix = hash1[k1 & 0x%x] + hash2[k2 & 0x%x];\n", $n-1, $n-1; + printf " if (ix >= %d)\n", scalar(@tokendata); + print " return tv->t_type = TOKEN_ID;\n"; + print "\n"; + print " data = &tokendata[ix];\n"; + + print " if (strcmp(data->string, token))\n"; + print " return tv->t_type = TOKEN_ID;\n"; + print "\n"; + print " tv->t_integer = data->num;\n"; + print " tv->t_inttwo = data->aux;\n"; + print " tv->t_flag = data->tokflag;\n"; + print " return tv->t_type = data->tokentype;\n"; + print "}\n"; +} diff --git a/autogen.sh b/autogen.sh new file mode 100644 index 0000000..5dbcbb5 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh -xe +# +# Simple script to run the appropriate autotools from a repository. +# +autoreconf +rm -rf autom4te.cache config.log config.status +rm -f Makefile rdoff/Makefile doc/Makefile +rm -f config.h.in config.h config/config.h diff --git a/common/common.c b/common/common.c new file mode 100644 index 0000000..1323799 --- /dev/null +++ b/common/common.c @@ -0,0 +1,64 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * common.c - code common to nasm and ndisasm + */ + +#include "compiler.h" +#include "nasm.h" +#include "nasmlib.h" +#include "insns.h" + +/* + * The current bit size of the CPU + */ +int globalbits = 0; +/* + * Common list of prefix names; ideally should be auto-generated + * from tokens.dat + */ +const char *prefix_name(int token) +{ + static const char *prefix_names[] = { + "a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp", + "rep", "repe", "repne", "repnz", "repz", "times", "wait", + "xacquire", "xrelease", "bnd" + }; + unsigned int prefix = token-PREFIX_ENUM_START; + + if (prefix >= ARRAY_SIZE(prefix_names)) + return NULL; + + return prefix_names[prefix]; +} diff --git a/config/config.h.in b/config/config.h.in new file mode 100644 index 0000000..2ea06da --- /dev/null +++ b/config/config.h.in @@ -0,0 +1,540 @@ +/* config/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 to call abort() on panics (internal errors), for debugging. */ +#undef ABORT_ON_PANIC + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if compiled with the `-fdata-sections' compiler flag */ +#undef CFLAG_FDATA_SECTIONS + +/* Define to 1 if compiled with the `-ffunction-sections' compiler flag */ +#undef CFLAG_FFUNCTION_SECTIONS + +/* Define to 1 if compiled with the `-fgnu89-inline' compiler flag */ +#undef CFLAG_FGNU89_INLINE + +/* Define to 1 if compiled with the `-flto' compiler flag */ +#undef CFLAG_FLTO + +/* Define to 1 if compiled with the `-fno-common' compiler flag */ +#undef CFLAG_FNO_COMMON + +/* Define to 1 if compiled with the `-fno-omit-frame-pointer' compiler flag */ +#undef CFLAG_FNO_OMIT_FRAME_POINTER + +/* Define to 1 if compiled with the `-fsanitize=address' compiler flag */ +#undef CFLAG_FSANITIZE_ADDRESS + +/* Define to 1 if compiled with the `-fsanitize=undefined' compiler flag */ +#undef CFLAG_FSANITIZE_UNDEFINED + +/* Define to 1 if compiled with the `-fvisibility=hidden' compiler flag */ +#undef CFLAG_FVISIBILITY_HIDDEN + +/* Define to 1 if compiled with the `-fwrapv' compiler flag */ +#undef CFLAG_FWRAPV + +/* Define to 1 if compiled with the `-ggdb3' compiler flag */ +#undef CFLAG_GGDB3 + +/* Define to 1 if compiled with the `-pedantic' compiler flag */ +#undef CFLAG_PEDANTIC + +/* Define to 1 if compiled with the `-U__STRICT_ANSI__' compiler flag */ +#undef CFLAG_U_STRICT_ANSI + +/* Define to 1 if compiled with the `-W' compiler flag */ +#undef CFLAG_W + +/* Define to 1 if compiled with the `-Wall' compiler flag */ +#undef CFLAG_WALL + +/* Define to 1 if compiled with the `-Wc90-c99-compat' compiler flag */ +#undef CFLAG_WC90_C99_COMPAT + +/* Define to 1 if compiled with the `-Werror' compiler flag */ +#undef CFLAG_WERROR + +/* Define to 1 if compiled with the `-Werror=attributes' compiler flag */ +#undef CFLAG_WERROR_ATTRIBUTES + +/* Define to 1 if compiled with the `-Werror=comment' compiler flag */ +#undef CFLAG_WERROR_COMMENT + +/* Define to 1 if compiled with the `-Werror=implicit' compiler flag */ +#undef CFLAG_WERROR_IMPLICIT + +/* Define to 1 if compiled with the `-Werror=missing-braces' compiler flag */ +#undef CFLAG_WERROR_MISSING_BRACES + +/* Define to 1 if compiled with the `-Werror=missing-declarations' compiler + flag */ +#undef CFLAG_WERROR_MISSING_DECLARATIONS + +/* Define to 1 if compiled with the `-Werror=missing-prototypes' compiler flag + */ +#undef CFLAG_WERROR_MISSING_PROTOTYPES + +/* Define to 1 if compiled with the `-Werror=pointer-arith' compiler flag */ +#undef CFLAG_WERROR_POINTER_ARITH + +/* Define to 1 if compiled with the `-Werror=return-type' compiler flag */ +#undef CFLAG_WERROR_RETURN_TYPE + +/* Define to 1 if compiled with the `-Werror=strict-prototypes' compiler flag + */ +#undef CFLAG_WERROR_STRICT_PROTOTYPES + +/* Define to 1 if compiled with the `-Werror=trigraphs' compiler flag */ +#undef CFLAG_WERROR_TRIGRAPHS + +/* Define to 1 if compiled with the `-Werror=unknown-warning-option' compiler + flag */ +#undef CFLAG_WERROR_UNKNOWN_WARNING_OPTION + +/* Define to 1 if compiled with the `-Werror=vla' compiler flag */ +#undef CFLAG_WERROR_VLA + +/* Define to 1 if compiled with the `-Wlong-long' compiler flag */ +#undef CFLAG_WLONG_LONG + +/* Define to 1 if compiled with the `-Wl,--gc-sections' compiler flag */ +#undef CFLAG_WL_GC_SECTIONS + +/* Define to 1 if compiled with the `-Wpedantic-ms-format' compiler flag */ +#undef CFLAG_WPEDANTIC_MS_FORMAT + +/* Define to 1 if compiled with the `-Wstringop-truncation' compiler flag */ +#undef CFLAG_WSTRINGOP_TRUNCATION + +/* Define to 1 if you have the `access' function. */ +#undef HAVE_ACCESS + +/* Define to 1 if you have the `canonicalize_file_name' function. */ +#undef HAVE_CANONICALIZE_FILE_NAME + +/* Define to 1 if you have the `cpu_to_le16' intrinsic function. */ +#undef HAVE_CPU_TO_LE16 + +/* Define to 1 if you have the `cpu_to_le32' intrinsic function. */ +#undef HAVE_CPU_TO_LE32 + +/* Define to 1 if you have the `cpu_to_le64' intrinsic function. */ +#undef HAVE_CPU_TO_LE64 + +/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRCASECMP + +/* Define to 1 if you have the declaration of `stricmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRICMP + +/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you + don't. */ +#undef HAVE_DECL_STRLCPY + +/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNCASECMP + +/* Define to 1 if you have the declaration of `strnicmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNICMP + +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNLEN + +/* Define to 1 if you have the declaration of `strrchrnul', and to 0 if you + don't. */ +#undef HAVE_DECL_STRRCHRNUL + +/* Define to 1 if you have the declaration of `strsep', and to 0 if you don't. + */ +#undef HAVE_DECL_STRSEP + +/* Define to 1 if you have the header file. */ +#undef HAVE_ENDIAN_H + +/* Define to 1 if you have the `faccessat' function. */ +#undef HAVE_FACCESSAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fileno' function. */ +#undef HAVE_FILENO + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the `fstat' function. */ +#undef HAVE_FSTAT + +/* Define to 1 if you have the `ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* Define to 1 if your compiler supports __attribute__((alloc_size)) on + functions */ +#undef HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE + +/* Define to 1 if your compiler supports __attribute__((cold)) on functions */ +#undef HAVE_FUNC_ATTRIBUTE_COLD + +/* Define to 1 if your compiler supports __attribute__((const)) on functions + */ +#undef HAVE_FUNC_ATTRIBUTE_CONST + +/* Define to 1 if your compiler supports __attribute__((error)) on functions + */ +#undef HAVE_FUNC_ATTRIBUTE_ERROR + +/* Define to 1 if your compiler supports __attribute__((format)) on functions + */ +#undef HAVE_FUNC_ATTRIBUTE_FORMAT + +/* Define to 1 if your compiler supports __attribute__((malloc)) on functions + */ +#undef HAVE_FUNC_ATTRIBUTE_MALLOC + +/* Define to 1 if your compiler supports __attribute__((noreturn)) on + functions */ +#undef HAVE_FUNC_ATTRIBUTE_NORETURN + +/* Define to 1 if your compiler supports __attribute__((pure)) on functions */ +#undef HAVE_FUNC_ATTRIBUTE_PURE + +/* Define to 1 if your compiler supports __attribute__((returns_nonnull)) on + functions */ +#undef HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL + +/* Define to 1 if your compiler supports __attribute__((sentinel)) on + functions */ +#undef HAVE_FUNC_ATTRIBUTE_SENTINEL + +/* Define to 1 if you have the `getgid' function. */ +#undef HAVE_GETGID + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `getuid' function. */ +#undef HAVE_GETUID + +/* Define to 1 if you have the `htole16' intrinsic function. */ +#undef HAVE_HTOLE16 + +/* Define to 1 if you have the `htole32' intrinsic function. */ +#undef HAVE_HTOLE32 + +/* Define to 1 if you have the `htole64' intrinsic function. */ +#undef HAVE_HTOLE64 + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTRIN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MACHINE_ENDIAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `pathconf' function. */ +#undef HAVE_PATHCONF + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `stat' function. */ +#undef HAVE_STAT + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if your compiler supports C99 extern inline */ +#undef HAVE_STDC_INLINE + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDNORETURN_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `stricmp' function. */ +#undef HAVE_STRICMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the `strnicmp' function. */ +#undef HAVE_STRNICMP + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the `strrchrnul' function. */ +#undef HAVE_STRRCHRNUL + +/* Define to 1 if you have the `strsep' function. */ +#undef HAVE_STRSEP + +/* Define to 1 if the system has the type `struct stat'. */ +#undef HAVE_STRUCT_STAT + +/* Define to 1 if the system has the type `struct _stati64'. */ +#undef HAVE_STRUCT__STATI64 + +/* Define to 1 if you have the `sysconf' function. */ +#undef HAVE_SYSCONF + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_ENDIAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the `_access' function. */ +#undef HAVE__ACCESS + +/* Define to 1 if you have the `_BitScanReverse' intrinsic function. */ +#undef HAVE__BITSCANREVERSE + +/* Define to 1 if you have the `_BitScanReverse64' intrinsic function. */ +#undef HAVE__BITSCANREVERSE64 + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if you have the `_byteswap_uint64' intrinsic function. */ +#undef HAVE__BYTESWAP_UINT64 + +/* Define to 1 if you have the `_byteswap_ulong' intrinsic function. */ +#undef HAVE__BYTESWAP_ULONG + +/* Define to 1 if you have the `_byteswap_ushort' intrinsic function. */ +#undef HAVE__BYTESWAP_USHORT + +/* Define to 1 if you have the `_chsize' function. */ +#undef HAVE__CHSIZE + +/* Define to 1 if you have the `_chsize_s' function. */ +#undef HAVE__CHSIZE_S + +/* Define to 1 if you have the `_filelengthi64' function. */ +#undef HAVE__FILELENGTHI64 + +/* Define to 1 if you have the `_fileno' function. */ +#undef HAVE__FILENO + +/* Define to 1 if you have the `_fseeki64' function. */ +#undef HAVE__FSEEKI64 + +/* Define to 1 if you have the `_fstati64' function. */ +#undef HAVE__FSTATI64 + +/* Define to 1 if you have the `_fullpath' function. */ +#undef HAVE__FULLPATH + +/* Define to 1 if you have the `_snprintf' function. */ +#undef HAVE__SNPRINTF + +/* Define to 1 if you have the `_stati64' function. */ +#undef HAVE__STATI64 + +/* Define to 1 if you have the `_vsnprintf' function. */ +#undef HAVE__VSNPRINTF + +/* Define to 1 if you have the `__bswap_16' intrinsic function. */ +#undef HAVE___BSWAP_16 + +/* Define to 1 if you have the `__bswap_32' intrinsic function. */ +#undef HAVE___BSWAP_32 + +/* Define to 1 if you have the `__bswap_64' intrinsic function. */ +#undef HAVE___BSWAP_64 + +/* Define to 1 if you have the `__builtin_bswap16' intrinsic function. */ +#undef HAVE___BUILTIN_BSWAP16 + +/* Define to 1 if you have the `__builtin_bswap32' intrinsic function. */ +#undef HAVE___BUILTIN_BSWAP32 + +/* Define to 1 if you have the `__builtin_bswap64' intrinsic function. */ +#undef HAVE___BUILTIN_BSWAP64 + +/* Define to 1 if you have the `__builtin_clz' intrinsic function. */ +#undef HAVE___BUILTIN_CLZ + +/* Define to 1 if you have the `__builtin_clzl' intrinsic function. */ +#undef HAVE___BUILTIN_CLZL + +/* Define to 1 if you have the `__builtin_clzll' intrinsic function. */ +#undef HAVE___BUILTIN_CLZLL + +/* Define to 1 if you have the `__builtin_constant_p' intrinsic function. */ +#undef HAVE___BUILTIN_CONSTANT_P + +/* Define to 1 if you have the `__builtin_expect' intrinsic function. */ +#undef HAVE___BUILTIN_EXPECT + +/* Define to 1 if you have the `__cpu_to_le16' intrinsic function. */ +#undef HAVE___CPU_TO_LE16 + +/* Define to 1 if you have the `__cpu_to_le32' intrinsic function. */ +#undef HAVE___CPU_TO_LE32 + +/* Define to 1 if you have the `__cpu_to_le64' intrinsic function. */ +#undef HAVE___CPU_TO_LE64 + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define to 1 if your processor stores words with the least significant byte + first (like Intel and VAX, unlike Motorola and SPARC). */ +#undef WORDS_LITTLEENDIAN + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#undef restrict +/* Work around a bug in Sun C++: it does not support _Restrict or + __restrict__, even though the corresponding Sun C compiler ends up with + "#define restrict _Restrict" or "#define restrict __restrict__" in the + previous line. Perhaps some future version of Sun C++ will work with + restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +# define __restrict__ +#endif + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type wide enough to hold a + pointer, if such a type exists, and if the system does not define it. */ +#undef uintptr_t diff --git a/config/msvc.h b/config/msvc.h new file mode 100644 index 0000000..631652e --- /dev/null +++ b/config/msvc.h @@ -0,0 +1,192 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * config/msvc.h + * + * Compiler definitions for Microsoft Visual C++; + * instead of config.h.in. See config.h.in for the + * variables which can be defined here. + * + * MSDN seems to have information back to Visual Studio 2003, so aim + * for compatibility that far back. + * + * Relevant _MSC_VER values: + * 1310 - Visual Studio 2003 + * 1400 - Visual Studio 2005 + * 1500 - Visual Studio 2008 + * 1600 - Visual Studio 2010 + * 1700 - Visual Studio 2012 + * 1800 - Visual Studio 2013 + * 1900 - Visual Studio 2015 + * 1910 - Visual Studio 2017 + */ + +#ifndef NASM_CONFIG_MSVC_H +#define NASM_CONFIG_MSVC_H + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#if _MSC_VER >= 1800 +# define HAVE_INTTYPES_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_IO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the `access' function. */ +#define HAVE_ACCESS 1 +#if _MSC_VER < 1400 +# define access _access +#endif + +/* Define to 1 if you have the `fileno' function. */ +#define HAVE_FILENO 1 +#if _MSC_VER < 1400 +# define fileno _fileno +#endif + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 +#if _MSC_VER < 1900 +# define snprintf _snprinf +#endif + +/* Define to 1 if you have the `_chsize' function. */ +#define HAVE__CHSIZE 1 + +/* Define to 1 if you have the `_chsize_s' function. */ +#if _MSC_VER >= 1400 +# define HAVE__CHSIZE_S 1 +#endif + +/* Define to 1 if you have the `_filelengthi64' function. */ +#define HAVE__FILELENGTHI64 1 + +/* Define to 1 if you have the `_fseeki64' function. */ +#define HAVE__FSEEKI64 1 + +/* Define to 1 if you have the `_fullpath' function. */ +#define HAVE__FULLPATH 1 + +/* Define to 1 if the system has the type `struct _stati64'. */ +#define HAVE_STRUCT__STATI64 + +/* Define to 1 if you have the `_stati64' function. */ +#define HAVE__STATI64 1 + +/* Define to 1 if you have the `_fstati64' function. */ +#define HAVE__FSTATI64 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +#if _MSC_VER >= 1800 +# define HAVE_STDBOOL_H 1 +#endif + +/* Define to 1 if you have the `stricmp' function. */ +#define HAVE_STRICMP 1 +/* Define to 1 if you have the declaration of `stricmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRICMP 1 +#if _MSC_VER < 1400 +# define stricmp _stricmp +#endif + +/* Define to 1 if you have the `strnicmp' function. */ +#define HAVE_STRNICMP 1 +/* Define to 1 if you have the declaration of `strnicmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRNICMP 1 +#if _MSC_VER < 1400 +# define strnicmp _strnicmp +#endif + +#if _MSC_VER >= 1400 +/* Define to 1 if you have the `strnlen' function. */ +# define HAVE_STRNLEN 1 +/* Define to 1 if you have the declaration of `strnlen', and to 0 if you + don't. */ +# define HAVE_DECL_STRNLEN 1 +#endif + +/* Define to 1 if the system has the type `uintptr_t'. */ +#if _MSC_VER >= 1900 +# define HAVE_UINTPTR_T 1 +#else +/* Define to the type of an unsigned integer type wide enough to hold a + pointer, if such a type exists, and if the system does not define it. */ +# define uintptr_t size_t +#endif + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 +#if _MSC_VER < 1400 +# define vsnprint _vsnprintf +#endif + +/* Define to 1 if the system has the type `_Bool'. */ +#if _MSC_VER >= 1900 +# define HAVE__BOOL 1 +#endif + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if your processor stores words with the least significant byte + first (like Intel and VAX, unlike Motorola and SPARC). */ +#define WORDS_LITTLEENDIAN 1 + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#define inline __inline + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#define restrict __restrict + +#endif /* NASM_CONFIG_MSVC_H */ diff --git a/config/unknown.h b/config/unknown.h new file mode 100644 index 0000000..d3cbe49 --- /dev/null +++ b/config/unknown.h @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * config/unknown.h + * + * Compiler definitions for an unknown compiler. Assume the worst. + */ + +#ifndef NASM_CONFIG_UNKNOWN_H +#define NASM_CONFIG_UNKNOWN_H + +/* Assume these don't exist */ +#ifndef inline +# define inline +#endif +#ifndef restrict +# define restrict +#endif + +#endif /* NASM_CONFIG_UNKNOWN_H */ diff --git a/config/watcom.h b/config/watcom.h new file mode 100644 index 0000000..029a36f --- /dev/null +++ b/config/watcom.h @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2016 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. + * + * ----------------------------------------------------------------------- */ + +/* + * config/watcom.h + * + * Compiler definitions for OpenWatcom instead of config.h.in. + * See config.h.in for the variables which can be defined here. + * + * This was taken from openwcom.mak and needs to be actually validated. + */ + +#ifndef NASM_CONFIG_WATCOM_H +#define NASM_CONFIG_WATCOM_H + +#define HAVE_DECL_STRCASECMP 1 +#define HAVE_DECL_STRICMP 1 +#define HAVE_DECL_STRLCPY 1 +#define HAVE_DECL_STRNCASECMP 1 +#define HAVE_DECL_STRNICMP 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SNPRINTF 1 +#define HAVE_STDBOOL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRCSPN 1 +#define HAVE_STRICMP 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_STRNICMP 1 +#define HAVE_STRSPN 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_VSNPRINTF 1 +#define STDC_HEADERS 1 +#define inline __inline + +#endif /* NASM_CONFIG_WATCOM_H */ diff --git a/configure b/configure new file mode 100644 index 0000000..357b7cf --- /dev/null +++ b/configure @@ -0,0 +1,10142 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="config/config.h.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_list= +ac_subst_vars='LTLIBOBJS +LIBOBJS +CC_RANLIB +CC_AR +PDFOPT +STRIP +RANLIB +AR +XMLTO +ASCIIDOC +NROFF +LIBEXT +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +SET_MAKE +LN_S +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +ac_prefix_program +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +enable_optimization +enable_gdb +enable_panic_abort +enable_pdf_compression +enable_sections +enable_lto +enable_sanitizer +enable_werror +enable_ccache +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --disable-optimization compile without optimization (-O0) to help debugging + --enable-gdb disable optimization and compile with extra debug + information for GDB debugger + --enable-panic-abort call abort() on panic to trap in the debugger + --disable-pdf-compression + generate an uncompressed documentation PDF + --enable-sections compile with function/data section support + --enable-lto compile with gcc-style link time optimization + --enable-sanitizer compile with sanitizers enabled + --enable-werror compile with -Werror to error out on any warning + --enable-ccache compile with ccache + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +as_fn_append ac_header_list " stdlib.h" +as_fn_append ac_header_list " unistd.h" +as_fn_append ac_header_list " sys/param.h" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers config/config.h" + + +if test "x$prefix" = xNONE; then + $as_echo_n "checking for prefix by " >&6 + # Extract the first word of "nasm", so it can be a program name with args. +set dummy nasm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_prefix_program+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_prefix_program in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_prefix_program="$ac_prefix_program" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_prefix_program="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_prefix_program=$ac_cv_path_ac_prefix_program +if test -n "$ac_prefix_program"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prefix_program" >&5 +$as_echo "$ac_prefix_program" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test -n "$ac_prefix_program"; then + prefix=`$as_dirname -- "$ac_prefix_program" || +$as_expr X"$ac_prefix_program" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_prefix_program" : 'X\(//\)[^/]' \| \ + X"$ac_prefix_program" : 'X\(//\)$' \| \ + X"$ac_prefix_program" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_prefix_program" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + prefix=`$as_dirname -- "$prefix" || +$as_expr X"$prefix" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$prefix" : 'X\(//\)[^/]' \| \ + X"$prefix" : 'X\(//\)$' \| \ + X"$prefix" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$prefix" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + fi +fi + + +pa_init_cflags="$CFLAGS" + +WINELOADER=/dev/null +export WINELOADER + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + case $ac_cv_prog_cc_stdc in #( + no) : + ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 +else + ac_cv_prog_cc_stdc=no +fi + +fi + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 +$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } + if ${ac_cv_prog_cc_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +fi + + case $ac_cv_prog_cc_stdc in #( + no) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; #( + '') : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 +$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# Check whether --enable-optimization was given. +if test "${enable_optimization+set}" = set; then : + enableval=$enable_optimization; +else + enableval=yes +fi + + if test x"$enableval" = xno; then : + pa_optimize=-O0 +else + pa_optimize=-O3 +fi + + +# Check whether --enable-gdb was given. +if test "${enable_gdb+set}" = set; then : + enableval=$enable_gdb; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + pa_optimize='-O0' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -ggdb3" >&5 +$as_echo_n "checking if $CC accepts -ggdb3... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -ggdb3" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -ggdb3" + +$as_echo "#define CFLAG_GGDB3 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi + + +if test x"$pa_init_cflags" = x; then : + CFLAGS=`echo "$CFLAGS" | sed -e "s/-O2/$pa_optimize/"` +fi + +if test x"$pa_optimize" = "x-O0"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-omit-frame-pointer" >&5 +$as_echo_n "checking if $CC accepts -fno-omit-frame-pointer... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fno-omit-frame-pointer" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -fno-omit-frame-pointer" + +$as_echo "#define CFLAG_FNO_OMIT_FRAME_POINTER 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +# Check whether --enable-panic-abort was given. +if test "${enable_panic_abort+set}" = set; then : + enableval=$enable_panic_abort; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + $as_echo "#define ABORT_ON_PANIC 1" >>confdefs.h + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of library files" >&5 +$as_echo_n "checking for suffix of library files... " >&6; } +if test x"$LIBEXT" = x; then + case "$OBJEXT" in + obj ) + LIBEXT=lib + ;; + *) + LIBEXT=a + ;; + esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBEXT" >&5 +$as_echo "$LIBEXT" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 +$as_echo_n "checking for C/C++ restrict keyword... " >&6; } +if ${ac_cv_c_restrict+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_restrict=no + # The order here caters to the fact that C++ does not require restrict. + for ac_kw in __restrict __restrict__ _Restrict restrict; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +typedef int * int_ptr; + int foo (int_ptr $ac_kw ip) { + return ip[0]; + } +int +main () +{ +int s[1]; + int * $ac_kw t = s; + t[0] = 0; + return foo(t) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_restrict=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_restrict" != no && break + done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 +$as_echo "$ac_cv_c_restrict" >&6; } + + case $ac_cv_c_restrict in + restrict) ;; + no) $as_echo "#define restrict /**/" >>confdefs.h + ;; + *) cat >>confdefs.h <<_ACEOF +#define restrict $ac_cv_c_restrict +_ACEOF + ;; + esac + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + $as_echo "#define WORDS_LITTLEENDIAN 1" >>confdefs.h + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fwrapv" >&5 +$as_echo_n "checking if $CC accepts -fwrapv... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fwrapv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -fwrapv" + +$as_echo "#define CFLAG_FWRAPV 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -U__STRICT_ANSI__" >&5 +$as_echo_n "checking if $CC accepts -U__STRICT_ANSI__... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -U__STRICT_ANSI__" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -U__STRICT_ANSI__" + +$as_echo "#define CFLAG_U_STRICT_ANSI 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-common" >&5 +$as_echo_n "checking if $CC accepts -fno-common... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fno-common" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -fno-common" + +$as_echo "#define CFLAG_FNO_COMMON 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +for ac_prog in nroff +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NROFF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NROFF"; then + ac_cv_prog_NROFF="$NROFF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NROFF="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NROFF=$ac_cv_prog_NROFF +if test -n "$NROFF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NROFF" >&5 +$as_echo "$NROFF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$NROFF" && break +done +test -n "$NROFF" || NROFF="false" + +for ac_prog in asciidoc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ASCIIDOC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ASCIIDOC"; then + ac_cv_prog_ASCIIDOC="$ASCIIDOC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ASCIIDOC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ASCIIDOC=$ac_cv_prog_ASCIIDOC +if test -n "$ASCIIDOC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ASCIIDOC" >&5 +$as_echo "$ASCIIDOC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ASCIIDOC" && break +done +test -n "$ASCIIDOC" || ASCIIDOC="false" + +for ac_prog in xmlto +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_XMLTO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$XMLTO"; then + ac_cv_prog_XMLTO="$XMLTO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_XMLTO="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +XMLTO=$ac_cv_prog_XMLTO +if test -n "$XMLTO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XMLTO" >&5 +$as_echo "$XMLTO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$XMLTO" && break +done +test -n "$XMLTO" || XMLTO="false" + + +if test $ASCIIDOC = false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No asciidoc package found" >&5 +$as_echo "$as_me: WARNING: No asciidoc package found" >&2;} + +fi +if test $XMLTO = false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No xmlto package found" >&5 +$as_echo "$as_me: WARNING: No xmlto package found" >&2;} + +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in inttypes.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" +if test "x$ac_cv_header_inttypes_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_INTTYPES_H 1 +_ACEOF + +fi + +done + +for ac_header in strings.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" +if test "x$ac_cv_header_strings_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRINGS_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } + ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +for ac_header in stdnoreturn.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdnoreturn.h" "ac_cv_header_stdnoreturn_h" "$ac_includes_default" +if test "x$ac_cv_header_stdnoreturn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDNORETURN_H 1 +_ACEOF + +fi + +done + +for ac_header in io.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" +if test "x$ac_cv_header_io_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IO_H 1 +_ACEOF + +fi + +done + +for ac_header in fcntl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" +if test "x$ac_cv_header_fcntl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FCNTL_H 1 +_ACEOF + +fi + +done + +for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/mman.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mman_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_MMAN_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/types.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_types_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_TYPES_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/stat.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_stat_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_STAT_H 1 +_ACEOF + +fi + +done + + +for ac_func in strcasecmp stricmp +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in strncasecmp strnicmp +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in strsep +do : + ac_fn_c_check_func "$LINENO" "strsep" "ac_cv_func_strsep" +if test "x$ac_cv_func_strsep" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRSEP 1 +_ACEOF + +fi +done + +for ac_func in strnlen +do : + ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" +if test "x$ac_cv_func_strnlen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRNLEN 1 +_ACEOF + +fi +done + +for ac_func in strrchrnul +do : + ac_fn_c_check_func "$LINENO" "strrchrnul" "ac_cv_func_strrchrnul" +if test "x$ac_cv_func_strrchrnul" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRRCHRNUL 1 +_ACEOF + +fi +done + + +for ac_func in getuid +do : + ac_fn_c_check_func "$LINENO" "getuid" "ac_cv_func_getuid" +if test "x$ac_cv_func_getuid" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETUID 1 +_ACEOF + +fi +done + +for ac_func in getgid +do : + ac_fn_c_check_func "$LINENO" "getgid" "ac_cv_func_getgid" +if test "x$ac_cv_func_getgid" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETGID 1 +_ACEOF + +fi +done + + +for ac_func in realpath +do : + ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" +if test "x$ac_cv_func_realpath" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_REALPATH 1 +_ACEOF + +fi +done + +for ac_func in canonicalize_file_name +do : + ac_fn_c_check_func "$LINENO" "canonicalize_file_name" "ac_cv_func_canonicalize_file_name" +if test "x$ac_cv_func_canonicalize_file_name" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CANONICALIZE_FILE_NAME 1 +_ACEOF + +fi +done + +for ac_func in _fullpath +do : + ac_fn_c_check_func "$LINENO" "_fullpath" "ac_cv_func__fullpath" +if test "x$ac_cv_func__fullpath" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__FULLPATH 1 +_ACEOF + +fi +done + +for ac_func in pathconf +do : + ac_fn_c_check_func "$LINENO" "pathconf" "ac_cv_func_pathconf" +if test "x$ac_cv_func_pathconf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PATHCONF 1 +_ACEOF + +fi +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 +$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } +if ${ac_cv_sys_largefile_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=no; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGEFILE_SOURCE 1 +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=1; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_cv_sys_largefile_source=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 +$as_echo "$ac_cv_sys_largefile_source" >&6; } +case $ac_cv_sys_largefile_source in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source +_ACEOF +;; +esac +rm -rf conftest* + +# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug +# in glibc 2.1.3, but that breaks too many other things. +# If you want fseeko and ftello with glibc, upgrade to a fixed glibc. +if test $ac_cv_sys_largefile_source != unknown; then + +$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h + +fi + +for ac_func in _fseeki64 +do : + ac_fn_c_check_func "$LINENO" "_fseeki64" "ac_cv_func__fseeki64" +if test "x$ac_cv_func__fseeki64" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__FSEEKI64 1 +_ACEOF + +fi +done + +for ac_func in ftruncate _chsize _chsize_s +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in fileno _fileno +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in _filelengthi64 +do : + ac_fn_c_check_func "$LINENO" "_filelengthi64" "ac_cv_func__filelengthi64" +if test "x$ac_cv_func__filelengthi64" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__FILELENGTHI64 1 +_ACEOF + +fi +done + + + + + for ac_header in $ac_header_list +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + +for ac_func in getpagesize +do : + ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" +if test "x$ac_cv_func_getpagesize" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETPAGESIZE 1 +_ACEOF + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 +$as_echo_n "checking for working mmap... " >&6; } +if ${ac_cv_func_mmap_fixed_mapped+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_mmap_fixed_mapped=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +/* malloc might have been renamed as rpl_malloc. */ +#undef malloc + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the file system buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propagated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ + +#include +#include + +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +char *malloc (); +#endif + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +int +main () +{ + char *data, *data2, *data3; + const char *cdata2; + int i, pagesize; + int fd, fd2; + + pagesize = getpagesize (); + + /* First, make a file with some known garbage in it. */ + data = (char *) malloc (pagesize); + if (!data) + return 1; + for (i = 0; i < pagesize; ++i) + *(data + i) = rand (); + umask (0); + fd = creat ("conftest.mmap", 0600); + if (fd < 0) + return 2; + if (write (fd, data, pagesize) != pagesize) + return 3; + close (fd); + + /* Next, check that the tail of a page is zero-filled. File must have + non-zero length, otherwise we risk SIGBUS for entire page. */ + fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); + if (fd2 < 0) + return 4; + cdata2 = ""; + if (write (fd2, cdata2, 1) != 1) + return 5; + data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); + if (data2 == MAP_FAILED) + return 6; + for (i = 0; i < pagesize; ++i) + if (*(data2 + i)) + return 7; + close (fd2); + if (munmap (data2, pagesize)) + return 8; + + /* Next, try to mmap the file at a fixed address which already has + something else allocated at it. If we can, also make sure that + we see the same garbage. */ + fd = open ("conftest.mmap", O_RDWR); + if (fd < 0) + return 9; + if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + return 10; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + return 11; + + /* Finally, make sure that changes to the mapped area do not + percolate back to the file as seen by read(). (This is a bug on + some variants of i386 svr4.0.) */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = (char *) malloc (pagesize); + if (!data3) + return 12; + if (read (fd, data3, pagesize) != pagesize) + return 13; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + return 14; + close (fd); + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_mmap_fixed_mapped=yes +else + ac_cv_func_mmap_fixed_mapped=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 +$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } +if test $ac_cv_func_mmap_fixed_mapped = yes; then + +$as_echo "#define HAVE_MMAP 1" >>confdefs.h + +fi +rm -f conftest.mmap conftest.txt + +for ac_func in getpagesize +do : + ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" +if test "x$ac_cv_func_getpagesize" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETPAGESIZE 1 +_ACEOF + +fi +done + +for ac_func in sysconf +do : + ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" +if test "x$ac_cv_func_sysconf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYSCONF 1 +_ACEOF + +fi +done + + +for ac_func in access _access faccessat +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_expect" >&5 +$as_echo_n "checking for __builtin_expect... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_expect(1,1); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_EXPECT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + +for ac_header in intrin.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "intrin.h" "ac_cv_header_intrin_h" "$ac_includes_default" +if test "x$ac_cv_header_intrin_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_INTRIN_H 1 +_ACEOF + ac_includes_default="$ac_includes_default +#include " + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5 +$as_echo_n "checking for __builtin_clz... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_clz(0U); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_CLZ 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clzl" >&5 +$as_echo_n "checking for __builtin_clzl... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_clzl(0UL); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_CLZL 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clzll" >&5 +$as_echo_n "checking for __builtin_clzll... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_clzll(0ULL); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_CLZLL 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _BitScanReverse" >&5 +$as_echo_n "checking for _BitScanReverse... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)_BitScanReverse(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE__BITSCANREVERSE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _BitScanReverse64" >&5 +$as_echo_n "checking for _BitScanReverse64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)_BitScanReverse64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE__BITSCANREVERSE64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + +for ac_func in vsnprintf _vsnprintf +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in snprintf _snprintf +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in strlcpy +do : + ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRLCPY 1 +_ACEOF + +fi +done + +for ac_func in strrchrnul +do : + ac_fn_c_check_func "$LINENO" "strrchrnul" "ac_cv_func_strrchrnul" +if test "x$ac_cv_func_strrchrnul" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRRCHRNUL 1 +_ACEOF + +fi +done + + +ac_fn_c_check_type "$LINENO" "struct _stati64" "ac_cv_type_struct__stati64" "$ac_includes_default" +if test "x$ac_cv_type_struct__stati64" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT__STATI64 1 +_ACEOF + + +fi + +ac_fn_c_check_type "$LINENO" "struct stat" "ac_cv_type_struct_stat" "$ac_includes_default" +if test "x$ac_cv_type_struct_stat" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT 1 +_ACEOF + + +fi + +for ac_func in stat _stati64 +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in fstat _fstati64 +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_fn_c_check_decl "$LINENO" "strcasecmp" "ac_cv_have_decl_strcasecmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_strcasecmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRCASECMP $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "stricmp" "ac_cv_have_decl_stricmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_stricmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRICMP $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_strncasecmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRNCASECMP $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strnicmp" "ac_cv_have_decl_strnicmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_strnicmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRNICMP $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strsep" "ac_cv_have_decl_strsep" "$ac_includes_default" +if test "x$ac_cv_have_decl_strsep" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRSEP $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strlcpy" "ac_cv_have_decl_strlcpy" "$ac_includes_default" +if test "x$ac_cv_have_decl_strlcpy" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRLCPY $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default" +if test "x$ac_cv_have_decl_strnlen" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRNLEN $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "strrchrnul" "ac_cv_have_decl_strrchrnul" "$ac_includes_default" +if test "x$ac_cv_have_decl_strrchrnul" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRRCHRNUL $ac_have_decl +_ACEOF + + + + ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + +$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h + +else + for ac_type in 'unsigned int' 'unsigned long int' \ + 'unsigned long long int'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +cat >>confdefs.h <<_ACEOF +#define uintptr_t $ac_type +_ACEOF + + ac_type= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test -z "$ac_type" && break + done +fi + + + +# Check whether --enable-pdf-compression was given. +if test "${enable_pdf_compression+set}" = set; then : + enableval=$enable_pdf_compression; +else + enableval=yes +fi + + if test x"$enableval" = xno; then : + PDFOPT='-nocompress' +fi + + + +for ac_header in endian.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_endian_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ENDIAN_H 1 +_ACEOF + ac_includes_default="$ac_includes_default +#include " + +fi + +done +for ac_header in sys/endian.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/endian.h" "ac_cv_header_sys_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_endian_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_ENDIAN_H 1 +_ACEOF + ac_includes_default="$ac_includes_default +#include " + +fi + +done +for ac_header in machine/endian.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "machine/endian.h" "ac_cv_header_machine_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_machine_endian_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MACHINE_ENDIAN_H 1 +_ACEOF + ac_includes_default="$ac_includes_default +#include " + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu_to_le16" >&5 +$as_echo_n "checking for cpu_to_le16... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)cpu_to_le16(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_CPU_TO_LE16 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu_to_le32" >&5 +$as_echo_n "checking for cpu_to_le32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)cpu_to_le32(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_CPU_TO_LE32 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu_to_le64" >&5 +$as_echo_n "checking for cpu_to_le64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)cpu_to_le64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_CPU_TO_LE64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpu_to_le16" >&5 +$as_echo_n "checking for __cpu_to_le16... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__cpu_to_le16(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___CPU_TO_LE16 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpu_to_le32" >&5 +$as_echo_n "checking for __cpu_to_le32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__cpu_to_le32(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___CPU_TO_LE32 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpu_to_le64" >&5 +$as_echo_n "checking for __cpu_to_le64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__cpu_to_le64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___CPU_TO_LE64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htole16" >&5 +$as_echo_n "checking for htole16... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)htole16(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_HTOLE16 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htole32" >&5 +$as_echo_n "checking for htole32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)htole32(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_HTOLE32 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htole64" >&5 +$as_echo_n "checking for htole64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)htole64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_HTOLE64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __bswap_16" >&5 +$as_echo_n "checking for __bswap_16... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__bswap_16(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BSWAP_16 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __bswap_32" >&5 +$as_echo_n "checking for __bswap_32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__bswap_32(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BSWAP_32 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __bswap_64" >&5 +$as_echo_n "checking for __bswap_64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__bswap_64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BSWAP_64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap16" >&5 +$as_echo_n "checking for __builtin_bswap16... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_bswap16(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_BSWAP16 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5 +$as_echo_n "checking for __builtin_bswap32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_bswap32(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_BSWAP32 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap64" >&5 +$as_echo_n "checking for __builtin_bswap64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_bswap64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_BSWAP64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _byteswap_ushort" >&5 +$as_echo_n "checking for _byteswap_ushort... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)_byteswap_ushort(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE__BYTESWAP_USHORT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _byteswap_ulong" >&5 +$as_echo_n "checking for _byteswap_ulong... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)_byteswap_ulong(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE__BYTESWAP_ULONG 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _byteswap_uint64" >&5 +$as_echo_n "checking for _byteswap_uint64... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)_byteswap_uint64(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE__BYTESWAP_UINT64 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_constant_p" >&5 +$as_echo_n "checking for __builtin_constant_p... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +int main(void) { + (void)__builtin_constant_p(0); + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE___BUILTIN_CONSTANT_P 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=attributes" >&5 +$as_echo_n "checking if $CC accepts -Werror=attributes... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=attributes" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=attributes" + +$as_echo "#define CFLAG_WERROR_ATTRIBUTES 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the noreturn function attribute" >&5 +$as_echo_n "checking if $CC supports the noreturn function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((noreturn)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_NORETURN 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the returns_nonnull function attribute" >&5 +$as_echo_n "checking if $CC supports the returns_nonnull function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((returns_nonnull)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_RETURNS_NONNULL 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the malloc function attribute" >&5 +$as_echo_n "checking if $CC supports the malloc function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((malloc)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_MALLOC 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the alloc_size function attribute" >&5 +$as_echo_n "checking if $CC supports the alloc_size function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((alloc_size(1))) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the sentinel function attribute" >&5 +$as_echo_n "checking if $CC supports the sentinel function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((sentinel)) + bar(const char *, ...); +void * foo(void); +void * foo(void) +{ + return + bar("a","b",NULL); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_SENTINEL 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the format function attribute" >&5 +$as_echo_n "checking if $CC supports the format function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern int __attribute__((format(printf,1,2))) + bar(const char *, ...); +int foo(void); +int foo(void) +{ + return + bar("%d",1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_FORMAT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the const function attribute" >&5 +$as_echo_n "checking if $CC supports the const function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((const)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_CONST 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the pure function attribute" >&5 +$as_echo_n "checking if $CC supports the pure function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((pure)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_PURE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the cold function attribute" >&5 +$as_echo_n "checking if $CC supports the cold function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void * __attribute__((cold)) + bar(int); +void * foo(void); +void * foo(void) +{ + return + bar(1); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_COLD 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports the error function attribute" >&5 +$as_echo_n "checking if $CC supports the error function attribute... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +extern void __attribute__((error("message"))) barf(void); +void foo(void); +void foo(void) +{ + if (0) + barf(); +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_FUNC_ATTRIBUTE_ERROR 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +# Check whether --enable-sections was given. +if test "${enable_sections+set}" = set; then : + enableval=$enable_sections; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -ffunction-sections" >&5 +$as_echo_n "checking if $CC accepts -ffunction-sections... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -ffunction-sections" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -ffunction-sections" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -ffunction-sections" + LDFLAGS="$pa_add_cldflags__old_ldflags -ffunction-sections" + +$as_echo "#define CFLAG_FFUNCTION_SECTIONS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fdata-sections" >&5 +$as_echo_n "checking if $CC accepts -fdata-sections... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fdata-sections" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -fdata-sections" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -fdata-sections" + LDFLAGS="$pa_add_cldflags__old_ldflags -fdata-sections" + +$as_echo "#define CFLAG_FDATA_SECTIONS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wl,--gc-sections" >&5 +$as_echo_n "checking if $CC accepts -Wl,--gc-sections... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wl,--gc-sections" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--gc-sections" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -Wl,--gc-sections" + LDFLAGS="$pa_add_cldflags__old_ldflags -Wl,--gc-sections" + +$as_echo "#define CFLAG_WL_GC_SECTIONS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + + +# Check whether --enable-lto was given. +if test "${enable_lto+set}" = set; then : + enableval=$enable_lto; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -flto" >&5 +$as_echo_n "checking if $CC accepts -flto... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -flto" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -flto" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -flto" + LDFLAGS="$pa_add_cldflags__old_ldflags -flto" + +$as_echo "#define CFLAG_FLTO 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ccbase=`echo "$CC" | awk '{ print $1; }'` + for ac_prog in ${ccbase}-ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC_AR"; then + ac_cv_prog_CC_AR="$CC_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_AR=$ac_cv_prog_CC_AR +if test -n "$CC_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_AR" >&5 +$as_echo "$CC_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC_AR" && break +done +test -n "$CC_AR" || CC_AR="$ac_cv_prog_AR" + + AR="$CC_AR" + for ac_prog in ${ccbase}-ranlib +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC_RANLIB"; then + ac_cv_prog_CC_RANLIB="$CC_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC_RANLIB="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC_RANLIB=$ac_cv_prog_CC_RANLIB +if test -n "$CC_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_RANLIB" >&5 +$as_echo "$CC_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC_RANLIB" && break +done +test -n "$CC_RANLIB" || CC_RANLIB="$ac_cv_prog_RANLIB" + + RANLIB="$CC_RANLIB" +fi + + +# Check whether --enable-sanitizer was given. +if test "${enable_sanitizer+set}" = set; then : + enableval=$enable_sanitizer; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-omit-frame-pointer" >&5 +$as_echo_n "checking if $CC accepts -fno-omit-frame-pointer... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fno-omit-frame-pointer" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -fno-omit-frame-pointer" + +$as_echo "#define CFLAG_FNO_OMIT_FRAME_POINTER 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fsanitize=address" >&5 +$as_echo_n "checking if $CC accepts -fsanitize=address... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fsanitize=address" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -fsanitize=address" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -fsanitize=address" + LDFLAGS="$pa_add_cldflags__old_ldflags -fsanitize=address" + +$as_echo "#define CFLAG_FSANITIZE_ADDRESS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fsanitize=undefined" >&5 +$as_echo_n "checking if $CC accepts -fsanitize=undefined... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fsanitize=undefined" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -fsanitize=undefined" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -fsanitize=undefined" + LDFLAGS="$pa_add_cldflags__old_ldflags -fsanitize=undefined" + +$as_echo "#define CFLAG_FSANITIZE_UNDEFINED 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fvisibility=hidden" >&5 +$as_echo_n "checking if $CC accepts -fvisibility=hidden... " >&6; } + pa_add_cldflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + pa_add_cldflags__old_ldflags="$LDFLAGS" + LDFLAGS="$LDFLAGS -fvisibility=hidden" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags -fvisibility=hidden" + LDFLAGS="$pa_add_cldflags__old_ldflags -fvisibility=hidden" + +$as_echo "#define CFLAG_FVISIBILITY_HIDDEN 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cldflags__old_cflags" + LDFLAGS="$pa_add_cldflags__old_ldflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -W" >&5 +$as_echo_n "checking if $CC accepts -W... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -W" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -W" + +$as_echo "#define CFLAG_W 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wall" >&5 +$as_echo_n "checking if $CC accepts -Wall... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wall" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Wall" + +$as_echo "#define CFLAG_WALL 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -pedantic" >&5 +$as_echo_n "checking if $CC accepts -pedantic... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -pedantic" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -pedantic" + +$as_echo "#define CFLAG_PEDANTIC 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=unknown-warning-option" >&5 +$as_echo_n "checking if $CC accepts -Werror=unknown-warning-option... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=unknown-warning-option" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=unknown-warning-option" + +$as_echo "#define CFLAG_WERROR_UNKNOWN_WARNING_OPTION 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wpedantic-ms-format" >&5 +$as_echo_n "checking if $CC accepts -Wpedantic-ms-format... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wpedantic-ms-format" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Wno-pedantic-ms-format" + +$as_echo "#define CFLAG_WPEDANTIC_MS_FORMAT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wc90-c99-compat" >&5 +$as_echo_n "checking if $CC accepts -Wc90-c99-compat... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wc90-c99-compat" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Wc90-c99-compat" + +$as_echo "#define CFLAG_WC90_C99_COMPAT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wlong-long" >&5 +$as_echo_n "checking if $CC accepts -Wlong-long... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wlong-long" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Wno-long-long" + +$as_echo "#define CFLAG_WLONG_LONG 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Wstringop-truncation" >&5 +$as_echo_n "checking if $CC accepts -Wstringop-truncation... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Wstringop-truncation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Wno-stringop-truncation" + +$as_echo "#define CFLAG_WSTRINGOP_TRUNCATION 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror" >&5 +$as_echo_n "checking if $CC accepts -Werror... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror" + +$as_echo "#define CFLAG_WERROR 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=implicit" >&5 +$as_echo_n "checking if $CC accepts -Werror=implicit... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=implicit" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=implicit" + +$as_echo "#define CFLAG_WERROR_IMPLICIT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=missing-braces" >&5 +$as_echo_n "checking if $CC accepts -Werror=missing-braces... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=missing-braces" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=missing-braces" + +$as_echo "#define CFLAG_WERROR_MISSING_BRACES 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=return-type" >&5 +$as_echo_n "checking if $CC accepts -Werror=return-type... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=return-type" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=return-type" + +$as_echo "#define CFLAG_WERROR_RETURN_TYPE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=trigraphs" >&5 +$as_echo_n "checking if $CC accepts -Werror=trigraphs... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=trigraphs" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=trigraphs" + +$as_echo "#define CFLAG_WERROR_TRIGRAPHS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=pointer-arith" >&5 +$as_echo_n "checking if $CC accepts -Werror=pointer-arith... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=pointer-arith" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=pointer-arith" + +$as_echo "#define CFLAG_WERROR_POINTER_ARITH 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=strict-prototypes" >&5 +$as_echo_n "checking if $CC accepts -Werror=strict-prototypes... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=strict-prototypes" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=strict-prototypes" + +$as_echo "#define CFLAG_WERROR_STRICT_PROTOTYPES 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=missing-prototypes" >&5 +$as_echo_n "checking if $CC accepts -Werror=missing-prototypes... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=missing-prototypes" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=missing-prototypes" + +$as_echo "#define CFLAG_WERROR_MISSING_PROTOTYPES 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=missing-declarations" >&5 +$as_echo_n "checking if $CC accepts -Werror=missing-declarations... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=missing-declarations" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=missing-declarations" + +$as_echo "#define CFLAG_WERROR_MISSING_DECLARATIONS 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=comment" >&5 +$as_echo_n "checking if $CC accepts -Werror=comment... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=comment" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=comment" + +$as_echo "#define CFLAG_WERROR_COMMENT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -Werror=vla" >&5 +$as_echo_n "checking if $CC accepts -Werror=vla... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror=vla" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -Werror=vla" + +$as_echo "#define CFLAG_WERROR_VLA 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports C99 external inlines" >&5 +$as_echo_n "checking if $CC supports C99 external inlines... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default + +/* Don't mistake GNU inlines for c99 */ +#ifdef __GNUC_GNU_INLINE__ +# error "Using gnu inline standard" +#endif + +inline int foo(int x) +{ + return x+1; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_STDC_INLINE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fgnu89-inline" >&5 +$as_echo_n "checking if $CC accepts -fgnu89-inline... " >&6; } + pa_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fgnu89-inline" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +printf("Hello, World!\n"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$pa_add_cflags__old_cflags -fgnu89-inline" + +$as_echo "#define CFLAG_FGNU89_INLINE 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$pa_add_cflags__old_cflags" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# Check whether --enable-ccache was given. +if test "${enable_ccache+set}" = set; then : + enableval=$enable_ccache; +else + enableval=no +fi + + if test x"$enableval" != xno; then : + CC="ccache $CC" +fi + + +ac_config_commands="$ac_config_commands default-1" + +ac_config_files="$ac_config_files Makefile doc/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS config/config.h" ;; + "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "default-1":C) mkdir -p config nasmlib nsis output stdlib x86 asm disasm rdoff macros common ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..e707158 --- /dev/null +++ b/configure.ac @@ -0,0 +1,313 @@ +dnl Process this file with autoconf 2.69 or later to produce +dnl a configure script. +AC_PREREQ(2.69) +AC_INIT(config/config.h.in) +AC_CONFIG_HEADERS(config/config.h) + +AC_PREFIX_PROGRAM(nasm) + +dnl Save initial CFLAGS, to see if -g -O2 came from configure or not +pa_init_cflags="$CFLAGS" + +dnl This prevents us from running Wine and thinking we are not +dnl cross-compiling when in fact we are; running Wine here is at +dnl the best very slow and doesn't buy us a single thing at all. +WINELOADER=/dev/null +export WINELOADER + +dnl Checks for programs and enable necessary CC extensions +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_PROG_CC +AC_PROG_CC_STDC +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PROG_INSTALL + +dnl If the user did not specify a CFLAGS default, change default -O2 +dnl to either -O3 (normal) or -O0 (for debugging) +PA_ARG_DISABLED([optimization], + [compile without optimization (-O0) to help debugging], + [pa_optimize=-O0], [pa_optimize=-O3]) + +dnl Compile and link with dwarf debug +PA_ARG_ENABLED([gdb], + [disable optimization and compile with extra debug information for GDB debugger], + [pa_optimize='-O0' + PA_ADD_CFLAGS([-ggdb3]) + ]) + +AS_IF([test x"$pa_init_cflags" = x], + [CFLAGS=`echo "$CFLAGS" | sed -e "s/-O2/$pa_optimize/"`]) + +AS_IF([test x"$pa_optimize" = "x-O0"], + [PA_ADD_CFLAGS([-fno-omit-frame-pointer])]) + +dnl Abort on panic +PA_ARG_ENABLED([panic-abort], + [call abort() on panic to trap in the debugger], + [AC_DEFINE(ABORT_ON_PANIC)]) +AH_TEMPLATE(ABORT_ON_PANIC, +[Define to 1 to call abort() on panics (internal errors), for debugging.]) + +dnl Check for library extension +PA_LIBEXT + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_C_RESTRICT +AC_TYPE_SIZE_T +AC_C_BIGENDIAN(AC_DEFINE(WORDS_BIGENDIAN),AC_DEFINE(WORDS_LITTLEENDIAN),,) +AH_TEMPLATE(WORDS_BIGENDIAN, +[Define to 1 if your processor stores words with the most significant +byte first (like Motorola and SPARC, unlike Intel and VAX).]) +AH_TEMPLATE(WORDS_LITTLEENDIAN, +[Define to 1 if your processor stores words with the least significant +byte first (like Intel and VAX, unlike Motorola and SPARC).]) + +dnl Force gcc and gcc-compatible compilers treat signed integers +dnl as 2's complement +PA_ADD_CFLAGS([-fwrapv]) + +dnl Some environments abuse __STRICT_ANSI__ to disable some +dnl function declarations +PA_ADD_CFLAGS([-U__STRICT_ANSI__]) + +dnl Don't put things in common if we can avoid it. We don't want to +dnl assume all compilers support common, and this will help find those +dnl problems. This also works around an OSX linker problem. +PA_ADD_CFLAGS([-fno-common]) + +dnl Look for programs... +AC_CHECK_PROGS(NROFF, nroff, false) +AC_CHECK_PROGS(ASCIIDOC, asciidoc, false) +AC_CHECK_PROGS(XMLTO, xmlto, false) + +dnl Check for progs needed for manpage generation +AS_IF([test $ASCIIDOC = false], + [AC_MSG_WARN([No asciidoc package found])] +) +AS_IF([test $XMLTO = false], + [AC_MSG_WARN([No xmlto package found])] +) + +dnl Check for host compiler tools +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(inttypes.h) +AC_CHECK_HEADERS(strings.h) +AC_HEADER_STDBOOL +AC_CHECK_HEADERS(stdnoreturn.h) +AC_CHECK_HEADERS(io.h) +AC_CHECK_HEADERS(fcntl.h) +AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS(sys/mman.h) +AC_CHECK_HEADERS(sys/types.h) +AC_CHECK_HEADERS(sys/stat.h) + +dnl Checks for library functions. +AC_CHECK_FUNCS(strcasecmp stricmp) +AC_CHECK_FUNCS(strncasecmp strnicmp) +AC_CHECK_FUNCS(strsep) +AC_CHECK_FUNCS(strnlen) +AC_CHECK_FUNCS(strrchrnul) + +AC_CHECK_FUNCS(getuid) +AC_CHECK_FUNCS(getgid) + +AC_CHECK_FUNCS(realpath) +AC_CHECK_FUNCS(canonicalize_file_name) +AC_CHECK_FUNCS(_fullpath) +AC_CHECK_FUNCS(pathconf) + +AC_FUNC_FSEEKO +AC_CHECK_FUNCS([_fseeki64]) +AC_CHECK_FUNCS([ftruncate _chsize _chsize_s]) +AC_CHECK_FUNCS([fileno _fileno]) + +AC_CHECK_FUNCS(_filelengthi64) +AC_FUNC_MMAP +AC_CHECK_FUNCS(getpagesize) +AC_CHECK_FUNCS(sysconf) + +AC_CHECK_FUNCS([access _access faccessat]) + +PA_HAVE_FUNC(__builtin_expect, (1,1)) + +dnl ilog2() building blocks +PA_ADD_HEADERS(intrin.h) +PA_HAVE_FUNC(__builtin_clz, (0U)) +PA_HAVE_FUNC(__builtin_clzl, (0UL)) +PA_HAVE_FUNC(__builtin_clzll, (0ULL)) +PA_HAVE_FUNC(_BitScanReverse, (0)) +PA_HAVE_FUNC(_BitScanReverse64, (0)) + +dnl Functions for which we have replacements available in stdlib/ +AC_CHECK_FUNCS([vsnprintf _vsnprintf]) +AC_CHECK_FUNCS([snprintf _snprintf]) +AC_CHECK_FUNCS([strlcpy]) +AC_CHECK_FUNCS([strrchrnul]) + +dnl These types are POSIX-specific, and Windows does it differently... +AC_CHECK_TYPES([struct _stati64]) +AC_CHECK_TYPES([struct stat]) +AC_CHECK_FUNCS([stat _stati64]) +AC_CHECK_FUNCS([fstat _fstati64]) + +dnl Check for functions that might not be declared in the headers for +dnl various idiotic reasons (mostly because of library authors +dnl abusing the meaning of __STRICT_ANSI__) +AC_CHECK_DECLS(strcasecmp) +AC_CHECK_DECLS(stricmp) +AC_CHECK_DECLS(strncasecmp) +AC_CHECK_DECLS(strnicmp) +AC_CHECK_DECLS(strsep) +AC_CHECK_DECLS(strlcpy) +AC_CHECK_DECLS(strnlen) +AC_CHECK_DECLS(strrchrnul) + +dnl Check for missing types +AC_TYPE_UINTPTR_T + +dnl Documentation: should we generate an uncompressed PDF? It is +dnl about twice as big, but it can be externally compressed (e.g. with xz) +dnl and becomes significantly smaller than the original. +PA_ARG_DISABLED([pdf-compression], + [generate an uncompressed documentation PDF], + [PDFOPT='-nocompress']) +AC_SUBST([PDFOPT]) + +dnl +dnl Look for byte-swapping support... +dnl +PA_ADD_HEADERS(endian.h sys/endian.h machine/endian.h) +PA_HAVE_FUNC(cpu_to_le16, (0)) +PA_HAVE_FUNC(cpu_to_le32, (0)) +PA_HAVE_FUNC(cpu_to_le64, (0)) +PA_HAVE_FUNC(__cpu_to_le16, (0)) +PA_HAVE_FUNC(__cpu_to_le32, (0)) +PA_HAVE_FUNC(__cpu_to_le64, (0)) +PA_HAVE_FUNC(htole16, (0)) +PA_HAVE_FUNC(htole32, (0)) +PA_HAVE_FUNC(htole64, (0)) +PA_HAVE_FUNC(__bswap_16, (0)) +PA_HAVE_FUNC(__bswap_32, (0)) +PA_HAVE_FUNC(__bswap_64, (0)) +PA_HAVE_FUNC(__builtin_bswap16, (0)) +PA_HAVE_FUNC(__builtin_bswap32, (0)) +PA_HAVE_FUNC(__builtin_bswap64, (0)) +PA_HAVE_FUNC(_byteswap_ushort, (0)) +PA_HAVE_FUNC(_byteswap_ulong, (0)) +PA_HAVE_FUNC(_byteswap_uint64, (0)) + +dnl +dnl Check for __builtin_constant_p() +dnl +PA_HAVE_FUNC(__builtin_constant_p, (0)) + +dnl +dnl Check for supported gcc attributes; some compilers (e.g. Sun CC) +dnl support these, but don't define __GNUC__ as they don't support +dnl some other features of gcc. +dnl +PA_ADD_CFLAGS([-Werror=attributes]) +PA_FUNC_ATTRIBUTE(noreturn) +PA_FUNC_ATTRIBUTE(returns_nonnull) +PA_FUNC_ATTRIBUTE(malloc) +PA_FUNC_ATTRIBUTE(alloc_size, (1)) +PA_FUNC_ATTRIBUTE(sentinel,,, [const char *, ...], ["a","b",NULL]) +PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1]) +PA_FUNC_ATTRIBUTE(const) +PA_FUNC_ATTRIBUTE(pure) +PA_FUNC_ATTRIBUTE(cold) +PA_FUNC_ATTRIBUTE_ERROR + +dnl +dnl support function sections (if available) +dnl +PA_ARG_ENABLED([sections], + [compile with function/data section support], + [PA_ADD_CLDFLAGS([-ffunction-sections]) + PA_ADD_CLDFLAGS([-fdata-sections]) + PA_ADD_CLDFLAGS([-Wl,--gc-sections])], + []) + +dnl +dnl support LTO +dnl +PA_ARG_ENABLED([lto], + [compile with gcc-style link time optimization], + [PA_ADD_CLDFLAGS([-flto]) + dnl Note: we use _PROG rather than _TOOL since we are prepending the full + dnl CC name which ought to already contain the host triplet if needed + ccbase=`echo "$CC" | awk '{ print $1; }'` + AC_CHECK_PROGS(CC_AR, [${ccbase}-ar], [$ac_cv_prog_AR]) + AR="$CC_AR" + AC_CHECK_PROGS(CC_RANLIB, [${ccbase}-ranlib], [$ac_cv_prog_RANLIB]) + RANLIB="$CC_RANLIB"], []) + +dnl +dnl support sanitizers (if available) +dnl +PA_ARG_ENABLED([sanitizer], + [compile with sanitizers enabled], + [PA_ADD_CFLAGS([-fno-omit-frame-pointer]) + PA_ADD_CLDFLAGS([-fsanitize=address]) + PA_ADD_CLDFLAGS([-fsanitize=undefined])]) + +dnl +dnl Don't make symbols visible, there is no point and it just +dnl makes the code slower. +dnl +PA_ADD_CLDFLAGS([-fvisibility=hidden]) + +dnl If we have gcc, add appropriate code cleanliness options +PA_ADD_CFLAGS([-W]) +PA_ADD_CFLAGS([-Wall]) +PA_ADD_CFLAGS([-pedantic]) +dnl LLVM doesn't error out on invalid -W options unless this option is +dnl specified first. Enable this so this script can actually discover +dnl which -W options are possible for this compiler. +PA_ADD_CFLAGS([-Werror=unknown-warning-option]) +dnl Suppress format warning on Windows targets due to their +PA_ADD_CFLAGS([-Wpedantic-ms-format],[-Wno-pedantic-ms-format]) +PA_ADD_CFLAGS([-Wc90-c99-compat]) +PA_ADD_CFLAGS([-Wlong-long],[-Wno-long-long]) +dnl This is needed because we intentionally expect strncpy() to fill +dnl in a zero-padded (not zero-terminated) buffer in several backends +PA_ADD_CFLAGS([-Wstringop-truncation],[-Wno-stringop-truncation]) +dnl PA_ADD_CFLAGS([-Wwrite-strings]) +PA_ARG_ENABLED([werror], + [compile with -Werror to error out on any warning], + [PA_ADD_CFLAGS([-Werror])], + [PA_ADD_CFLAGS([-Werror=implicit]) + PA_ADD_CFLAGS([-Werror=missing-braces]) + PA_ADD_CFLAGS([-Werror=return-type]) + PA_ADD_CFLAGS([-Werror=trigraphs]) + PA_ADD_CFLAGS([-Werror=pointer-arith]) + PA_ADD_CFLAGS([-Werror=strict-prototypes]) + PA_ADD_CFLAGS([-Werror=missing-prototypes]) + PA_ADD_CFLAGS([-Werror=missing-declarations]) + PA_ADD_CFLAGS([-Werror=comment]) + PA_ADD_CFLAGS([-Werror=vla])] +) + +dnl +dnl On some versions of gcc, -Werror=missing-prototypes causes problems +dnl with C99-style external inlines. Test this *after* adding the -Werror +dnl options. +dnl +PA_CHECK_BAD_STDC_INLINE + +dnl +dnl support ccache +dnl +PA_ARG_ENABLED([ccache], [compile with ccache], [CC="ccache $CC"], []) + +AC_OUTPUT_COMMANDS([mkdir -p config nasmlib nsis output stdlib x86 asm disasm rdoff macros common]) +AC_OUTPUT(Makefile doc/Makefile) diff --git a/contrib/MSVC6.txt b/contrib/MSVC6.txt new file mode 100644 index 0000000..ce23756 --- /dev/null +++ b/contrib/MSVC6.txt @@ -0,0 +1,25 @@ +Compilation with Nasm on MSVC 6.0, with usage of Custom Build step. + +1) Open your project in MSVC. + +2) Add .asm at the list of source files. + +3) Click on it with the right button, further press Settings... + +4) In General tab, flags "Always use custom build step" and "Exclude file + from build" should be disabled. + +5) In "Custom Build" tab it is necessary to define "Commands" and "Outputs" + (By "Outputs" build system checks if it has reached a necessary result. + This parameter is mandatory and without it MSVC will not let you close + the window by OK button). + + The "Commands" should be set to + + nasmw.exe -fwin -o $(OUTDIR)\$(InputName).obj $(InputName).asm + + And "Outputs" to + + $(OUTDIR)\$(InputName).obj + +Have fun! diff --git a/contrib/VSrules/nasm.README b/contrib/VSrules/nasm.README new file mode 100644 index 0000000..8fbf155 --- /dev/null +++ b/contrib/VSrules/nasm.README @@ -0,0 +1,16 @@ + Visual Studio 2008 NASM integration + + +In order to use nasm seamlessly in your VS2k8, follow the steps below. + +1. First install nasm by running its installer +2. copy nasm.rules to c:\Program Files\Microsoft Visual Studio 2008\VC\VCProjectDefaults +3. Start Visual Studio 2008 +4. go to Tools->Options->VC++ Directories +5. click on Show Directories for Executables +6. add C:\Program Files\NASM to the list of paths +7. Open a solution that you want to use NASM with +8. Right click on the project name and select Custom Build Rules +9. Check the box next to the NASM line +10. Add any .asm files to the project +11. click on build to test diff --git a/contrib/VSrules/nasm.rules b/contrib/VSrules/nasm.rules new file mode 100644 index 0000000..79b4fb1 --- /dev/null +++ b/contrib/VSrules/nasm.rules @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + diff --git a/disasm/disasm.c b/disasm/disasm.c new file mode 100644 index 0000000..fd3eb42 --- /dev/null +++ b/disasm/disasm.c @@ -0,0 +1,1765 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2012 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. + * + * ----------------------------------------------------------------------- */ + +/* + * disasm.c where all the _work_ gets done in the Netwide Disassembler + */ + +#include "compiler.h" + +#include +#include +#include + +#include "nasm.h" +#include "disasm.h" +#include "sync.h" +#include "insns.h" +#include "tables.h" +#include "regdis.h" +#include "disp8.h" + +#define fetch_safe(_start, _ptr, _size, _need, _op) \ + do { \ + if (((_ptr) - (_start)) >= ((_size) - (_need))) \ + _op; \ + } while (0) + +#define fetch_or_return(_start, _ptr, _size, _need) \ + fetch_safe(_start, _ptr, _size, _need, return 0) + +/* + * Flags that go into the `segment' field of `insn' structures + * during disassembly. + */ +#define SEG_RELATIVE 1 +#define SEG_32BIT 2 +#define SEG_RMREG 4 +#define SEG_DISP8 8 +#define SEG_DISP16 16 +#define SEG_DISP32 32 +#define SEG_NODISP 64 +#define SEG_SIGNED 128 +#define SEG_64BIT 256 + +/* + * Prefix information + */ +struct prefix_info { + uint8_t osize; /* Operand size */ + uint8_t asize; /* Address size */ + uint8_t osp; /* Operand size prefix present */ + uint8_t asp; /* Address size prefix present */ + uint8_t rep; /* Rep prefix present */ + uint8_t seg; /* Segment override prefix present */ + uint8_t wait; /* WAIT "prefix" present */ + uint8_t lock; /* Lock prefix present */ + uint8_t vex[3]; /* VEX prefix present */ + uint8_t vex_c; /* VEX "class" (VEX, XOP, ...) */ + uint8_t vex_m; /* VEX.M field */ + uint8_t vex_v; + uint8_t vex_lp; /* VEX.LP fields */ + uint32_t rex; /* REX prefix present */ + uint8_t evex[3]; /* EVEX prefix present */ +}; + +#define getu8(x) (*(uint8_t *)(x)) +#if X86_MEMORY +/* Littleendian CPU which can handle unaligned references */ +#define getu16(x) (*(uint16_t *)(x)) +#define getu32(x) (*(uint32_t *)(x)) +#define getu64(x) (*(uint64_t *)(x)) +#else +static uint16_t getu16(uint8_t *data) +{ + return (uint16_t)data[0] + ((uint16_t)data[1] << 8); +} +static uint32_t getu32(uint8_t *data) +{ + return (uint32_t)getu16(data) + ((uint32_t)getu16(data+2) << 16); +} +static uint64_t getu64(uint8_t *data) +{ + return (uint64_t)getu32(data) + ((uint64_t)getu32(data+4) << 32); +} +#endif + +#define gets8(x) ((int8_t)getu8(x)) +#define gets16(x) ((int16_t)getu16(x)) +#define gets32(x) ((int32_t)getu32(x)) +#define gets64(x) ((int64_t)getu64(x)) + +/* Important: regval must already have been adjusted for rex extensions */ +static enum reg_enum whichreg(opflags_t regflags, int regval, int rex) +{ + size_t i; + + static const struct { + opflags_t flags; + enum reg_enum reg; + } specific_registers[] = { + {REG_AL, R_AL}, + {REG_AX, R_AX}, + {REG_EAX, R_EAX}, + {REG_RAX, R_RAX}, + {REG_DL, R_DL}, + {REG_DX, R_DX}, + {REG_EDX, R_EDX}, + {REG_RDX, R_RDX}, + {REG_CL, R_CL}, + {REG_CX, R_CX}, + {REG_ECX, R_ECX}, + {REG_RCX, R_RCX}, + {FPU0, R_ST0}, + {XMM0, R_XMM0}, + {YMM0, R_YMM0}, + {ZMM0, R_ZMM0}, + {REG_ES, R_ES}, + {REG_CS, R_CS}, + {REG_SS, R_SS}, + {REG_DS, R_DS}, + {REG_FS, R_FS}, + {REG_GS, R_GS}, + {OPMASK0, R_K0}, + }; + + if (!(regflags & (REGISTER|REGMEM))) + return 0; /* Registers not permissible?! */ + + regflags |= REGISTER; + + for (i = 0; i < ARRAY_SIZE(specific_registers); i++) + if (!(specific_registers[i].flags & ~regflags)) + return specific_registers[i].reg; + + /* All the entries below look up regval in an 16-entry array */ + if (regval < 0 || regval > (rex & REX_EV ? 31 : 15)) + return 0; + +#define GET_REGISTER(__array, __index) \ + ((size_t)(__index) < (size_t)ARRAY_SIZE(__array) ? __array[(__index)] : 0) + + if (!(REG8 & ~regflags)) { + if (rex & (REX_P|REX_NH)) + return GET_REGISTER(nasm_rd_reg8_rex, regval); + else + return GET_REGISTER(nasm_rd_reg8, regval); + } + if (!(REG16 & ~regflags)) + return GET_REGISTER(nasm_rd_reg16, regval); + if (!(REG32 & ~regflags)) + return GET_REGISTER(nasm_rd_reg32, regval); + if (!(REG64 & ~regflags)) + return GET_REGISTER(nasm_rd_reg64, regval); + if (!(REG_SREG & ~regflags)) + return GET_REGISTER(nasm_rd_sreg, regval & 7); /* Ignore REX */ + if (!(REG_CREG & ~regflags)) + return GET_REGISTER(nasm_rd_creg, regval); + if (!(REG_DREG & ~regflags)) + return GET_REGISTER(nasm_rd_dreg, regval); + if (!(REG_TREG & ~regflags)) { + if (regval > 7) + return 0; /* TR registers are ill-defined with rex */ + return GET_REGISTER(nasm_rd_treg, regval); + } + if (!(FPUREG & ~regflags)) + return GET_REGISTER(nasm_rd_fpureg, regval & 7); /* Ignore REX */ + if (!(MMXREG & ~regflags)) + return GET_REGISTER(nasm_rd_mmxreg, regval & 7); /* Ignore REX */ + if (!(XMMREG & ~regflags)) + return GET_REGISTER(nasm_rd_xmmreg, regval); + if (!(YMMREG & ~regflags)) + return GET_REGISTER(nasm_rd_ymmreg, regval); + if (!(ZMMREG & ~regflags)) + return GET_REGISTER(nasm_rd_zmmreg, regval); + if (!(OPMASKREG & ~regflags)) + return GET_REGISTER(nasm_rd_opmaskreg, regval); + if (!(BNDREG & ~regflags)) + return GET_REGISTER(nasm_rd_bndreg, regval); + +#undef GET_REGISTER + return 0; +} + +static uint32_t append_evex_reg_deco(char *buf, uint32_t num, + decoflags_t deco, uint8_t *evex) +{ + const char * const er_names[] = {"rn-sae", "rd-sae", "ru-sae", "rz-sae"}; + uint32_t num_chars = 0; + + if ((deco & MASK) && (evex[2] & EVEX_P2AAA)) { + enum reg_enum opmasknum = nasm_rd_opmaskreg[evex[2] & EVEX_P2AAA]; + const char * regname = nasm_reg_names[opmasknum - EXPR_REG_START]; + + num_chars += snprintf(buf + num_chars, num - num_chars, + "{%s}", regname); + + if ((deco & Z) && (evex[2] & EVEX_P2Z)) { + num_chars += snprintf(buf + num_chars, num - num_chars, + "{z}"); + } + } + + if (evex[2] & EVEX_P2B) { + if (deco & ER) { + uint8_t er_type = (evex[2] & EVEX_P2LL) >> 5; + num_chars += snprintf(buf + num_chars, num - num_chars, + ",{%s}", er_names[er_type]); + } else if (deco & SAE) { + num_chars += snprintf(buf + num_chars, num - num_chars, + ",{sae}"); + } + } + + return num_chars; +} + +static uint32_t append_evex_mem_deco(char *buf, uint32_t num, opflags_t type, + decoflags_t deco, uint8_t *evex) +{ + uint32_t num_chars = 0; + + if ((evex[2] & EVEX_P2B) && (deco & BRDCAST_MASK)) { + decoflags_t deco_brsize = deco & BRSIZE_MASK; + opflags_t template_opsize = (deco_brsize == BR_BITS32 ? BITS32 : BITS64); + uint8_t br_num = (type & SIZE_MASK) / BITS128 * + BITS64 / template_opsize * 2; + + num_chars += snprintf(buf + num_chars, num - num_chars, + "{1to%d}", br_num); + } + + if ((deco & MASK) && (evex[2] & EVEX_P2AAA)) { + enum reg_enum opmasknum = nasm_rd_opmaskreg[evex[2] & EVEX_P2AAA]; + const char * regname = nasm_reg_names[opmasknum - EXPR_REG_START]; + + num_chars += snprintf(buf + num_chars, num - num_chars, + "{%s}", regname); + + if ((deco & Z) && (evex[2] & EVEX_P2Z)) { + num_chars += snprintf(buf + num_chars, num - num_chars, + "{z}"); + } + } + + + return num_chars; +} + +/* + * Process an effective address (ModRM) specification. + */ +static uint8_t *do_ea(uint8_t *data, int modrm, int asize, + int segsize, enum ea_type type, + operand *op, insn *ins) +{ + int mod, rm, scale, index, base; + int rex; + uint8_t *evex; + uint8_t sib = 0; + bool is_evex = !!(ins->rex & REX_EV); + + mod = (modrm >> 6) & 03; + rm = modrm & 07; + + if (mod != 3 && asize != 16 && rm == 4) + sib = *data++; + + rex = ins->rex; + evex = ins->evex_p; + + if (mod == 3) { /* pure register version */ + op->basereg = rm+(rex & REX_B ? 8 : 0); + op->segment |= SEG_RMREG; + if (is_evex && segsize == 64) { + op->basereg += (evex[0] & EVEX_P0X ? 0 : 16); + } + return data; + } + + op->disp_size = 0; + op->eaflags = 0; + + if (asize == 16) { + /* + * specifies the displacement size (none, byte or + * word), and specifies the register combination. + * Exception: mod=0,rm=6 does not specify [BP] as one might + * expect, but instead specifies [disp16]. + */ + + if (type != EA_SCALAR) + return NULL; + + op->indexreg = op->basereg = -1; + op->scale = 1; /* always, in 16 bits */ + switch (rm) { + case 0: + op->basereg = R_BX; + op->indexreg = R_SI; + break; + case 1: + op->basereg = R_BX; + op->indexreg = R_DI; + break; + case 2: + op->basereg = R_BP; + op->indexreg = R_SI; + break; + case 3: + op->basereg = R_BP; + op->indexreg = R_DI; + break; + case 4: + op->basereg = R_SI; + break; + case 5: + op->basereg = R_DI; + break; + case 6: + op->basereg = R_BP; + break; + case 7: + op->basereg = R_BX; + break; + } + if (rm == 6 && mod == 0) { /* special case */ + op->basereg = -1; + if (segsize != 16) + op->disp_size = 16; + mod = 2; /* fake disp16 */ + } + switch (mod) { + case 0: + op->segment |= SEG_NODISP; + break; + case 1: + op->segment |= SEG_DISP8; + if (ins->evex_tuple != 0) { + op->offset = gets8(data) * get_disp8N(ins); + } else { + op->offset = gets8(data); + } + data++; + break; + case 2: + op->segment |= SEG_DISP16; + op->offset = *data++; + op->offset |= ((unsigned)*data++) << 8; + break; + } + return data; + } else { + /* + * Once again, specifies displacement size (this time + * none, byte or *dword*), while specifies the base + * register. Again, [EBP] is missing, replaced by a pure + * disp32 (this time that's mod=0,rm=*5*) in 32-bit mode, + * and RIP-relative addressing in 64-bit mode. + * + * However, rm=4 + * indicates not a single base register, but instead the + * presence of a SIB byte... + */ + int a64 = asize == 64; + + op->indexreg = -1; + + if (a64) + op->basereg = nasm_rd_reg64[rm | ((rex & REX_B) ? 8 : 0)]; + else + op->basereg = nasm_rd_reg32[rm | ((rex & REX_B) ? 8 : 0)]; + + if (rm == 5 && mod == 0) { + if (segsize == 64) { + op->eaflags |= EAF_REL; + op->segment |= SEG_RELATIVE; + } + + if (asize != 64) + op->disp_size = asize; + + op->basereg = -1; + mod = 2; /* fake disp32 */ + } + + + if (rm == 4) { /* process SIB */ + uint8_t vsib_hi = 0; + scale = (sib >> 6) & 03; + index = (sib >> 3) & 07; + base = sib & 07; + + op->scale = 1 << scale; + + if (segsize == 64) { + vsib_hi = (rex & REX_X ? 8 : 0) | + (evex[2] & EVEX_P2VP ? 0 : 16); + } + + if (type == EA_XMMVSIB) + op->indexreg = nasm_rd_xmmreg[index | vsib_hi]; + else if (type == EA_YMMVSIB) + op->indexreg = nasm_rd_ymmreg[index | vsib_hi]; + else if (type == EA_ZMMVSIB) + op->indexreg = nasm_rd_zmmreg[index | vsib_hi]; + else if (index == 4 && !(rex & REX_X)) + op->indexreg = -1; /* ESP/RSP cannot be an index */ + else if (a64) + op->indexreg = nasm_rd_reg64[index | ((rex & REX_X) ? 8 : 0)]; + else + op->indexreg = nasm_rd_reg32[index | ((rex & REX_X) ? 8 : 0)]; + + if (base == 5 && mod == 0) { + op->basereg = -1; + mod = 2; /* Fake disp32 */ + } else if (a64) + op->basereg = nasm_rd_reg64[base | ((rex & REX_B) ? 8 : 0)]; + else + op->basereg = nasm_rd_reg32[base | ((rex & REX_B) ? 8 : 0)]; + + if (segsize == 16) + op->disp_size = 32; + } else if (type != EA_SCALAR) { + /* Can't have VSIB without SIB */ + return NULL; + } + + switch (mod) { + case 0: + op->segment |= SEG_NODISP; + break; + case 1: + op->segment |= SEG_DISP8; + if (ins->evex_tuple != 0) { + op->offset = gets8(data) * get_disp8N(ins); + } else { + op->offset = gets8(data); + } + data++; + break; + case 2: + op->segment |= SEG_DISP32; + op->offset = gets32(data); + data += 4; + break; + } + return data; + } +} + +/* + * Determine whether the instruction template in t corresponds to the data + * stream in data. Return the number of bytes matched if so. + */ +#define case4(x) case (x): case (x)+1: case (x)+2: case (x)+3 + +static int matches(const struct itemplate *t, uint8_t *data, + const struct prefix_info *prefix, int segsize, insn *ins) +{ + uint8_t *r = (uint8_t *)(t->code); + uint8_t *origdata = data; + bool a_used = false, o_used = false; + enum prefixes drep = 0; + enum prefixes dwait = 0; + uint8_t lock = prefix->lock; + int osize = prefix->osize; + int asize = prefix->asize; + int i, c; + int op1, op2; + struct operand *opx, *opy; + uint8_t opex = 0; + bool vex_ok = false; + int regmask = (segsize == 64) ? 15 : 7; + enum ea_type eat = EA_SCALAR; + + for (i = 0; i < MAX_OPERANDS; i++) { + ins->oprs[i].segment = ins->oprs[i].disp_size = + (segsize == 64 ? SEG_64BIT : segsize == 32 ? SEG_32BIT : 0); + } + ins->condition = -1; + ins->evex_tuple = 0; + ins->rex = prefix->rex; + memset(ins->prefixes, 0, sizeof ins->prefixes); + + if (itemp_has(t, (segsize == 64 ? IF_NOLONG : IF_LONG))) + return 0; + + if (prefix->rep == 0xF2) + drep = (itemp_has(t, IF_BND) ? P_BND : P_REPNE); + else if (prefix->rep == 0xF3) + drep = P_REP; + + dwait = prefix->wait ? P_WAIT : 0; + + while ((c = *r++) != 0) { + op1 = (c & 3) + ((opex & 1) << 2); + op2 = ((c >> 3) & 3) + ((opex & 2) << 1); + opx = &ins->oprs[op1]; + opy = &ins->oprs[op2]; + opex = 0; + + switch (c) { + case 01: + case 02: + case 03: + case 04: + while (c--) + if (*r++ != *data++) + return 0; + break; + + case 05: + case 06: + case 07: + opex = c; + break; + + case4(010): + { + int t = *r++, d = *data++; + if (d < t || d > t + 7) + return 0; + else { + opx->basereg = (d-t)+ + (ins->rex & REX_B ? 8 : 0); + opx->segment |= SEG_RMREG; + } + break; + } + + case4(014): + /* this is an separate index reg position of MIB operand (ICC) */ + /* Disassembler uses NASM's split EA form only */ + break; + + case4(0274): + opx->offset = (int8_t)*data++; + opx->segment |= SEG_SIGNED; + break; + + case4(020): + opx->offset = *data++; + break; + + case4(024): + opx->offset = *data++; + break; + + case4(030): + opx->offset = getu16(data); + data += 2; + break; + + case4(034): + if (osize == 32) { + opx->offset = getu32(data); + data += 4; + } else { + opx->offset = getu16(data); + data += 2; + } + if (segsize != asize) + opx->disp_size = asize; + break; + + case4(040): + opx->offset = getu32(data); + data += 4; + break; + + case4(0254): + opx->offset = gets32(data); + data += 4; + break; + + case4(044): + switch (asize) { + case 16: + opx->offset = getu16(data); + data += 2; + if (segsize != 16) + opx->disp_size = 16; + break; + case 32: + opx->offset = getu32(data); + data += 4; + if (segsize == 16) + opx->disp_size = 32; + break; + case 64: + opx->offset = getu64(data); + opx->disp_size = 64; + data += 8; + break; + } + break; + + case4(050): + opx->offset = gets8(data++); + opx->segment |= SEG_RELATIVE; + break; + + case4(054): + opx->offset = getu64(data); + data += 8; + break; + + case4(060): + opx->offset = gets16(data); + data += 2; + opx->segment |= SEG_RELATIVE; + opx->segment &= ~SEG_32BIT; + break; + + case4(064): /* rel */ + opx->segment |= SEG_RELATIVE; + /* In long mode rel is always 32 bits, sign extended. */ + if (segsize == 64 || osize == 32) { + opx->offset = gets32(data); + data += 4; + if (segsize != 64) + opx->segment |= SEG_32BIT; + opx->type = (opx->type & ~SIZE_MASK) + | (segsize == 64 ? BITS64 : BITS32); + } else { + opx->offset = gets16(data); + data += 2; + opx->segment &= ~SEG_32BIT; + opx->type = (opx->type & ~SIZE_MASK) | BITS16; + } + break; + + case4(070): + opx->offset = gets32(data); + data += 4; + opx->segment |= SEG_32BIT | SEG_RELATIVE; + break; + + case4(0100): + case4(0110): + case4(0120): + case4(0130): + { + int modrm = *data++; + opx->segment |= SEG_RMREG; + data = do_ea(data, modrm, asize, segsize, eat, opy, ins); + if (!data) + return 0; + opx->basereg = ((modrm >> 3) & 7) + (ins->rex & REX_R ? 8 : 0); + if ((ins->rex & REX_EV) && (segsize == 64)) + opx->basereg += (ins->evex_p[0] & EVEX_P0RP ? 0 : 16); + break; + } + + case 0172: + { + uint8_t ximm = *data++; + c = *r++; + ins->oprs[c >> 3].basereg = (ximm >> 4) & regmask; + ins->oprs[c >> 3].segment |= SEG_RMREG; + ins->oprs[c & 7].offset = ximm & 15; + } + break; + + case 0173: + { + uint8_t ximm = *data++; + c = *r++; + + if ((c ^ ximm) & 15) + return 0; + + ins->oprs[c >> 4].basereg = (ximm >> 4) & regmask; + ins->oprs[c >> 4].segment |= SEG_RMREG; + } + break; + + case4(0174): + { + uint8_t ximm = *data++; + + opx->basereg = (ximm >> 4) & regmask; + opx->segment |= SEG_RMREG; + } + break; + + case4(0200): + case4(0204): + case4(0210): + case4(0214): + case4(0220): + case4(0224): + case4(0230): + case4(0234): + { + int modrm = *data++; + if (((modrm >> 3) & 07) != (c & 07)) + return 0; /* spare field doesn't match up */ + data = do_ea(data, modrm, asize, segsize, eat, opy, ins); + if (!data) + return 0; + break; + } + + case4(0240): + case 0250: + { + uint8_t evexm = *r++; + uint8_t evexwlp = *r++; + uint8_t modrm, valid_mask; + ins->evex_tuple = *r++ - 0300; + modrm = *(origdata + 1); + + ins->rex |= REX_EV; + if ((prefix->rex & (REX_EV|REX_V|REX_P)) != REX_EV) + return 0; + + if ((evexm & 0x1f) != prefix->vex_m) + return 0; + + switch (evexwlp & 060) { + case 000: + if (prefix->rex & REX_W) + return 0; + break; + case 020: + if (!(prefix->rex & REX_W)) + return 0; + ins->rex |= REX_W; + break; + case 040: /* VEX.W is a don't care */ + ins->rex &= ~REX_W; + break; + case 060: + break; + } + + /* If EVEX.b is set with reg-reg op, + * EVEX.L'L contains embedded rounding control info + */ + if ((prefix->evex[2] & EVEX_P2B) && ((modrm >> 6) == 3)) { + valid_mask = 0x3; /* prefix only */ + } else { + valid_mask = 0xf; /* vector length and prefix */ + } + if ((evexwlp ^ prefix->vex_lp) & valid_mask) + return 0; + + if (c == 0250) { + if ((prefix->vex_v != 0) || + (!(prefix->evex[2] & EVEX_P2VP) && + ((eat < EA_XMMVSIB) || (eat > EA_ZMMVSIB)))) + return 0; + } else { + opx->segment |= SEG_RMREG; + opx->basereg = ((~prefix->evex[2] & EVEX_P2VP) << (4 - 3) ) | + prefix->vex_v; + } + vex_ok = true; + memcpy(ins->evex_p, prefix->evex, 3); + break; + } + + case4(0260): + case 0270: + { + int vexm = *r++; + int vexwlp = *r++; + + ins->rex |= REX_V; + if ((prefix->rex & (REX_V|REX_P)) != REX_V) + return 0; + + if ((vexm & 0x1f) != prefix->vex_m) + return 0; + + switch (vexwlp & 060) { + case 000: + if (prefix->rex & REX_W) + return 0; + break; + case 020: + if (!(prefix->rex & REX_W)) + return 0; + ins->rex &= ~REX_W; + break; + case 040: /* VEX.W is a don't care */ + ins->rex &= ~REX_W; + break; + case 060: + break; + } + + /* The 010 bit of vexwlp is set if VEX.L is ignored */ + if ((vexwlp ^ prefix->vex_lp) & ((vexwlp & 010) ? 03 : 07)) + return 0; + + if (c == 0270) { + if (prefix->vex_v != 0) + return 0; + } else { + opx->segment |= SEG_RMREG; + opx->basereg = prefix->vex_v; + } + vex_ok = true; + break; + } + + case 0271: + if (prefix->rep == 0xF3) + drep = P_XRELEASE; + break; + + case 0272: + if (prefix->rep == 0xF2) + drep = P_XACQUIRE; + else if (prefix->rep == 0xF3) + drep = P_XRELEASE; + break; + + case 0273: + if (prefix->lock == 0xF0) { + if (prefix->rep == 0xF2) + drep = P_XACQUIRE; + else if (prefix->rep == 0xF3) + drep = P_XRELEASE; + } + break; + + case 0310: + if (asize != 16) + return 0; + else + a_used = true; + break; + + case 0311: + if (asize != 32) + return 0; + else + a_used = true; + break; + + case 0312: + if (asize != segsize) + return 0; + else + a_used = true; + break; + + case 0313: + if (asize != 64) + return 0; + else + a_used = true; + break; + + case 0314: + if (prefix->rex & REX_B) + return 0; + break; + + case 0315: + if (prefix->rex & REX_X) + return 0; + break; + + case 0316: + if (prefix->rex & REX_R) + return 0; + break; + + case 0317: + if (prefix->rex & REX_W) + return 0; + break; + + case 0320: + if (osize != 16) + return 0; + else + o_used = true; + break; + + case 0321: + if (osize != 32) + return 0; + else + o_used = true; + break; + + case 0322: + if (osize != (segsize == 16 ? 16 : 32)) + return 0; + else + o_used = true; + break; + + case 0323: + ins->rex |= REX_W; /* 64-bit only instruction */ + osize = 64; + o_used = true; + break; + + case 0324: + if (osize != 64) + return 0; + o_used = true; + break; + + case 0325: + ins->rex |= REX_NH; + break; + + case 0330: + { + int t = *r++, d = *data++; + if (d < t || d > t + 15) + return 0; + else + ins->condition = d - t; + break; + } + + case 0326: + if (prefix->rep == 0xF3) + return 0; + break; + + case 0331: + if (prefix->rep) + return 0; + break; + + case 0332: + if (prefix->rep != 0xF2) + return 0; + drep = 0; + break; + + case 0333: + if (prefix->rep != 0xF3) + return 0; + drep = 0; + break; + + case 0334: + if (lock) { + ins->rex |= REX_R; + lock = 0; + } + break; + + case 0335: + if (drep == P_REP) + drep = P_REPE; + break; + + case 0336: + case 0337: + break; + + case 0340: + return 0; + + case 0341: + if (prefix->wait != 0x9B) + return 0; + dwait = 0; + break; + + case 0360: + if (prefix->osp || prefix->rep) + return 0; + break; + + case 0361: + if (!prefix->osp || prefix->rep) + return 0; + o_used = true; + break; + + case 0364: + if (prefix->osp) + return 0; + break; + + case 0365: + if (prefix->asp) + return 0; + break; + + case 0366: + if (!prefix->osp) + return 0; + o_used = true; + break; + + case 0367: + if (!prefix->asp) + return 0; + a_used = true; + break; + + case 0370: + case 0371: + break; + + case 0374: + eat = EA_XMMVSIB; + break; + + case 0375: + eat = EA_YMMVSIB; + break; + + case 0376: + eat = EA_ZMMVSIB; + break; + + default: + return 0; /* Unknown code */ + } + } + + if (!vex_ok && (ins->rex & (REX_V | REX_EV))) + return 0; + + /* REX cannot be combined with VEX */ + if ((ins->rex & REX_V) && (prefix->rex & REX_P)) + return 0; + + /* + * Check for unused rep or a/o prefixes. + */ + for (i = 0; i < t->operands; i++) { + if (ins->oprs[i].segment != SEG_RMREG) + a_used = true; + } + + if (lock) { + if (ins->prefixes[PPS_LOCK]) + return 0; + ins->prefixes[PPS_LOCK] = P_LOCK; + } + if (drep) { + if (ins->prefixes[PPS_REP]) + return 0; + ins->prefixes[PPS_REP] = drep; + } + ins->prefixes[PPS_WAIT] = dwait; + if (!o_used) { + if (osize != ((segsize == 16) ? 16 : 32)) { + enum prefixes pfx = 0; + + switch (osize) { + case 16: + pfx = P_O16; + break; + case 32: + pfx = P_O32; + break; + case 64: + pfx = P_O64; + break; + } + + if (ins->prefixes[PPS_OSIZE]) + return 0; + ins->prefixes[PPS_OSIZE] = pfx; + } + } + if (!a_used && asize != segsize) { + if (ins->prefixes[PPS_ASIZE]) + return 0; + ins->prefixes[PPS_ASIZE] = asize == 16 ? P_A16 : P_A32; + } + + /* Fix: check for redundant REX prefixes */ + + return data - origdata; +} + +/* Condition names for disassembly, sorted by x86 code */ +static const char * const condition_name[16] = { + "o", "no", "c", "nc", "z", "nz", "na", "a", + "s", "ns", "pe", "po", "l", "nl", "ng", "g" +}; + +int32_t disasm(uint8_t *data, int32_t data_size, char *output, int outbufsize, int segsize, + int64_t offset, int autosync, iflag_t *prefer) +{ + const struct itemplate * const *p, * const *best_p; + const struct disasm_index *ix; + uint8_t *dp; + int length, best_length = 0; + char *segover; + int i, slen, colon, n; + uint8_t *origdata; + int works; + insn tmp_ins, ins; + iflag_t goodness, best; + int best_pref; + struct prefix_info prefix; + bool end_prefix; + bool is_evex; + + memset(&ins, 0, sizeof ins); + + /* + * Scan for prefixes. + */ + memset(&prefix, 0, sizeof prefix); + prefix.asize = segsize; + prefix.osize = (segsize == 64) ? 32 : segsize; + segover = NULL; + origdata = data; + + ix = itable; + + end_prefix = false; + while (!end_prefix) { + switch (*data) { + case 0xF2: + case 0xF3: + fetch_or_return(origdata, data, data_size, 1); + prefix.rep = *data++; + break; + + case 0x9B: + fetch_or_return(origdata, data, data_size, 1); + prefix.wait = *data++; + break; + + case 0xF0: + fetch_or_return(origdata, data, data_size, 1); + prefix.lock = *data++; + break; + + case 0x2E: + fetch_or_return(origdata, data, data_size, 1); + segover = "cs", prefix.seg = *data++; + break; + case 0x36: + fetch_or_return(origdata, data, data_size, 1); + segover = "ss", prefix.seg = *data++; + break; + case 0x3E: + fetch_or_return(origdata, data, data_size, 1); + segover = "ds", prefix.seg = *data++; + break; + case 0x26: + fetch_or_return(origdata, data, data_size, 1); + segover = "es", prefix.seg = *data++; + break; + case 0x64: + fetch_or_return(origdata, data, data_size, 1); + segover = "fs", prefix.seg = *data++; + break; + case 0x65: + fetch_or_return(origdata, data, data_size, 1); + segover = "gs", prefix.seg = *data++; + break; + + case 0x66: + fetch_or_return(origdata, data, data_size, 1); + prefix.osize = (segsize == 16) ? 32 : 16; + prefix.osp = *data++; + break; + case 0x67: + fetch_or_return(origdata, data, data_size, 1); + prefix.asize = (segsize == 32) ? 16 : 32; + prefix.asp = *data++; + break; + + case 0xC4: + case 0xC5: + if (segsize == 64 || (data[1] & 0xc0) == 0xc0) { + fetch_or_return(origdata, data, data_size, 2); + prefix.vex[0] = *data++; + prefix.vex[1] = *data++; + + prefix.rex = REX_V; + prefix.vex_c = RV_VEX; + + if (prefix.vex[0] == 0xc4) { + fetch_or_return(origdata, data, data_size, 1); + prefix.vex[2] = *data++; + prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */ + prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W; + prefix.vex_m = prefix.vex[1] & 0x1f; + prefix.vex_v = (~prefix.vex[2] >> 3) & 15; + prefix.vex_lp = prefix.vex[2] & 7; + } else { + prefix.rex |= (~prefix.vex[1] >> (7-2)) & REX_R; + prefix.vex_m = 1; + prefix.vex_v = (~prefix.vex[1] >> 3) & 15; + prefix.vex_lp = prefix.vex[1] & 7; + } + + ix = itable_vex[RV_VEX][prefix.vex_m][prefix.vex_lp & 3]; + } + end_prefix = true; + break; + + case 0x62: + { + if (segsize == 64 || ((data[1] & 0xc0) == 0xc0)) { + fetch_or_return(origdata, data, data_size, 4); + data++; /* 62h EVEX prefix */ + prefix.evex[0] = *data++; + prefix.evex[1] = *data++; + prefix.evex[2] = *data++; + + prefix.rex = REX_EV; + prefix.vex_c = RV_EVEX; + prefix.rex |= (~prefix.evex[0] >> 5) & 7; /* REX_RXB */ + prefix.rex |= (prefix.evex[1] >> (7-3)) & REX_W; + prefix.vex_m = prefix.evex[0] & EVEX_P0MM; + prefix.vex_v = (~prefix.evex[1] & EVEX_P1VVVV) >> 3; + prefix.vex_lp = ((prefix.evex[2] & EVEX_P2LL) >> (5-2)) | + (prefix.evex[1] & EVEX_P1PP); + + ix = itable_vex[prefix.vex_c][prefix.vex_m][prefix.vex_lp & 3]; + } + end_prefix = true; + break; + } + + case 0x8F: + if ((data[1] & 030) != 0 && + (segsize == 64 || (data[1] & 0xc0) == 0xc0)) { + fetch_or_return(origdata, data, data_size, 3); + prefix.vex[0] = *data++; + prefix.vex[1] = *data++; + prefix.vex[2] = *data++; + + prefix.rex = REX_V; + prefix.vex_c = RV_XOP; + + prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */ + prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W; + prefix.vex_m = prefix.vex[1] & 0x1f; + prefix.vex_v = (~prefix.vex[2] >> 3) & 15; + prefix.vex_lp = prefix.vex[2] & 7; + + ix = itable_vex[RV_XOP][prefix.vex_m][prefix.vex_lp & 3]; + } + end_prefix = true; + break; + + case REX_P + 0x0: + case REX_P + 0x1: + case REX_P + 0x2: + case REX_P + 0x3: + case REX_P + 0x4: + case REX_P + 0x5: + case REX_P + 0x6: + case REX_P + 0x7: + case REX_P + 0x8: + case REX_P + 0x9: + case REX_P + 0xA: + case REX_P + 0xB: + case REX_P + 0xC: + case REX_P + 0xD: + case REX_P + 0xE: + case REX_P + 0xF: + if (segsize == 64) { + fetch_or_return(origdata, data, data_size, 1); + prefix.rex = *data++; + if (prefix.rex & REX_W) + prefix.osize = 64; + } + end_prefix = true; + break; + + default: + end_prefix = true; + break; + } + } + + iflag_set_all(&best); /* Worst possible */ + best_p = NULL; + best_pref = INT_MAX; + + if (!ix) + return 0; /* No instruction table at all... */ + + dp = data; + fetch_or_return(origdata, dp, data_size, 1); + ix += *dp++; + while (ix->n == -1) { + fetch_or_return(origdata, dp, data_size, 1); + ix = (const struct disasm_index *)ix->p + *dp++; + } + + p = (const struct itemplate * const *)ix->p; + for (n = ix->n; n; n--, p++) { + if ((length = matches(*p, data, &prefix, segsize, &tmp_ins))) { + works = true; + /* + * Final check to make sure the types of r/m match up. + * XXX: Need to make sure this is actually correct. + */ + for (i = 0; i < (*p)->operands; i++) { + if ( + /* If it's a mem-only EA but we have a + register, die. */ + ((tmp_ins.oprs[i].segment & SEG_RMREG) && + is_class(MEMORY, (*p)->opd[i])) || + /* If it's a reg-only EA but we have a memory + ref, die. */ + (!(tmp_ins.oprs[i].segment & SEG_RMREG) && + !(REG_EA & ~(*p)->opd[i]) && + !((*p)->opd[i] & REG_SMASK)) || + /* Register type mismatch (eg FS vs REG_DESS): + die. */ + ((((*p)->opd[i] & (REGISTER | FPUREG)) || + (tmp_ins.oprs[i].segment & SEG_RMREG)) && + !whichreg((*p)->opd[i], + tmp_ins.oprs[i].basereg, tmp_ins.rex)) + ) { + works = false; + break; + } + } + + /* + * Note: we always prefer instructions which incorporate + * prefixes in the instructions themselves. This is to allow + * e.g. PAUSE to be preferred to REP NOP, and deal with + * MMX/SSE instructions where prefixes are used to select + * between MMX and SSE register sets or outright opcode + * selection. + */ + if (works) { + int i, nprefix; + goodness = iflag_pfmask(*p); + goodness = iflag_xor(&goodness, prefer); + nprefix = 0; + for (i = 0; i < MAXPREFIX; i++) + if (tmp_ins.prefixes[i]) + nprefix++; + if (nprefix < best_pref || + (nprefix == best_pref && + iflag_cmp(&goodness, &best) < 0)) { + /* This is the best one found so far */ + best = goodness; + best_p = p; + best_pref = nprefix; + best_length = length; + ins = tmp_ins; + } + } + } + } + + if (!best_p) + return 0; /* no instruction was matched */ + + /* Pick the best match */ + p = best_p; + length = best_length; + + slen = 0; + + /* TODO: snprintf returns the value that the string would have if + * the buffer were long enough, and not the actual length of + * the returned string, so each instance of using the return + * value of snprintf should actually be checked to assure that + * the return value is "sane." Maybe a macro wrapper could + * be used for that purpose. + */ + for (i = 0; i < MAXPREFIX; i++) { + const char *prefix = prefix_name(ins.prefixes[i]); + if (prefix) + slen += snprintf(output+slen, outbufsize-slen, "%s ", prefix); + } + + i = (*p)->opcode; + if (i >= FIRST_COND_OPCODE) + slen += snprintf(output + slen, outbufsize - slen, "%s%s", + nasm_insn_names[i], condition_name[ins.condition]); + else + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_insn_names[i]); + + colon = false; + is_evex = !!(ins.rex & REX_EV); + length += data - origdata; /* fix up for prefixes */ + for (i = 0; i < (*p)->operands; i++) { + opflags_t t = (*p)->opd[i]; + decoflags_t deco = (*p)->deco[i]; + const operand *o = &ins.oprs[i]; + int64_t offs; + + output[slen++] = (colon ? ':' : i == 0 ? ' ' : ','); + + offs = o->offset; + if (o->segment & SEG_RELATIVE) { + offs += offset + length; + /* + * sort out wraparound + */ + if (!(o->segment & (SEG_32BIT|SEG_64BIT))) + offs &= 0xffff; + else if (segsize != 64) + offs &= 0xffffffff; + + /* + * add sync marker, if autosync is on + */ + if (autosync) + add_sync(offs, 0L); + } + + if (t & COLON) + colon = true; + else + colon = false; + + if ((t & (REGISTER | FPUREG)) || + (o->segment & SEG_RMREG)) { + enum reg_enum reg; + reg = whichreg(t, o->basereg, ins.rex); + if (t & TO) + slen += snprintf(output + slen, outbufsize - slen, "to "); + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_reg_names[reg-EXPR_REG_START]); + if (t & REGSET_MASK) + slen += snprintf(output + slen, outbufsize - slen, "+%d", + (int)((t & REGSET_MASK) >> (REGSET_SHIFT-1))-1); + if (is_evex && deco) + slen += append_evex_reg_deco(output + slen, outbufsize - slen, + deco, ins.evex_p); + } else if (!(UNITY & ~t)) { + output[slen++] = '1'; + } else if (t & IMMEDIATE) { + if (t & BITS8) { + slen += + snprintf(output + slen, outbufsize - slen, "byte "); + if (o->segment & SEG_SIGNED) { + if (offs < 0) { + offs *= -1; + output[slen++] = '-'; + } else + output[slen++] = '+'; + } + } else if (t & BITS16) { + slen += + snprintf(output + slen, outbufsize - slen, "word "); + } else if (t & BITS32) { + slen += + snprintf(output + slen, outbufsize - slen, "dword "); + } else if (t & BITS64) { + slen += + snprintf(output + slen, outbufsize - slen, "qword "); + } else if (t & NEAR) { + slen += + snprintf(output + slen, outbufsize - slen, "near "); + } else if (t & SHORT) { + slen += + snprintf(output + slen, outbufsize - slen, "short "); + } + slen += + snprintf(output + slen, outbufsize - slen, "0x%"PRIx64"", + offs); + } else if (!(MEM_OFFS & ~t)) { + slen += + snprintf(output + slen, outbufsize - slen, + "[%s%s%s0x%"PRIx64"]", + (segover ? segover : ""), + (segover ? ":" : ""), + (o->disp_size == 64 ? "qword " : + o->disp_size == 32 ? "dword " : + o->disp_size == 16 ? "word " : ""), offs); + segover = NULL; + } else if (is_class(REGMEM, t)) { + int started = false; + if (t & BITS8) + slen += + snprintf(output + slen, outbufsize - slen, "byte "); + if (t & BITS16) + slen += + snprintf(output + slen, outbufsize - slen, "word "); + if (t & BITS32) + slen += + snprintf(output + slen, outbufsize - slen, "dword "); + if (t & BITS64) + slen += + snprintf(output + slen, outbufsize - slen, "qword "); + if (t & BITS80) + slen += + snprintf(output + slen, outbufsize - slen, "tword "); + if ((ins.evex_p[2] & EVEX_P2B) && (deco & BRDCAST_MASK)) { + /* when broadcasting, each element size should be used */ + if (deco & BR_BITS32) + slen += + snprintf(output + slen, outbufsize - slen, "dword "); + else if (deco & BR_BITS64) + slen += + snprintf(output + slen, outbufsize - slen, "qword "); + } else { + if (t & BITS128) + slen += + snprintf(output + slen, outbufsize - slen, "oword "); + if (t & BITS256) + slen += + snprintf(output + slen, outbufsize - slen, "yword "); + if (t & BITS512) + slen += + snprintf(output + slen, outbufsize - slen, "zword "); + } + if (t & FAR) + slen += snprintf(output + slen, outbufsize - slen, "far "); + if (t & NEAR) + slen += + snprintf(output + slen, outbufsize - slen, "near "); + output[slen++] = '['; + if (o->disp_size) + slen += snprintf(output + slen, outbufsize - slen, "%s", + (o->disp_size == 64 ? "qword " : + o->disp_size == 32 ? "dword " : + o->disp_size == 16 ? "word " : + "")); + if (o->eaflags & EAF_REL) + slen += snprintf(output + slen, outbufsize - slen, "rel "); + if (segover) { + slen += + snprintf(output + slen, outbufsize - slen, "%s:", + segover); + segover = NULL; + } + if (o->basereg != -1) { + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_reg_names[(o->basereg-EXPR_REG_START)]); + started = true; + } + if (o->indexreg != -1 && !itemp_has(*best_p, IF_MIB)) { + if (started) + output[slen++] = '+'; + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_reg_names[(o->indexreg-EXPR_REG_START)]); + if (o->scale > 1) + slen += + snprintf(output + slen, outbufsize - slen, "*%d", + o->scale); + started = true; + } + + + if (o->segment & SEG_DISP8) { + if (is_evex) { + const char *prefix; + uint32_t offset = offs; + if ((int32_t)offset < 0) { + prefix = "-"; + offset = -offset; + } else { + prefix = "+"; + } + slen += + snprintf(output + slen, outbufsize - slen, "%s0x%"PRIx32"", + prefix, offset); + } else { + const char *prefix; + uint8_t offset = offs; + if ((int8_t)offset < 0) { + prefix = "-"; + offset = -offset; + } else { + prefix = "+"; + } + slen += + snprintf(output + slen, outbufsize - slen, "%s0x%"PRIx8"", + prefix, offset); + } + } else if (o->segment & SEG_DISP16) { + const char *prefix; + uint16_t offset = offs; + if ((int16_t)offset < 0 && started) { + offset = -offset; + prefix = "-"; + } else { + prefix = started ? "+" : ""; + } + slen += + snprintf(output + slen, outbufsize - slen, + "%s0x%"PRIx16"", prefix, offset); + } else if (o->segment & SEG_DISP32) { + if (prefix.asize == 64) { + const char *prefix; + uint64_t offset = offs; + if ((int32_t)offs < 0 && started) { + offset = -offset; + prefix = "-"; + } else { + prefix = started ? "+" : ""; + } + slen += + snprintf(output + slen, outbufsize - slen, + "%s0x%"PRIx64"", prefix, offset); + } else { + const char *prefix; + uint32_t offset = offs; + if ((int32_t) offset < 0 && started) { + offset = -offset; + prefix = "-"; + } else { + prefix = started ? "+" : ""; + } + slen += + snprintf(output + slen, outbufsize - slen, + "%s0x%"PRIx32"", prefix, offset); + } + } + + if (o->indexreg != -1 && itemp_has(*best_p, IF_MIB)) { + output[slen++] = ','; + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_reg_names[(o->indexreg-EXPR_REG_START)]); + if (o->scale > 1) + slen += + snprintf(output + slen, outbufsize - slen, "*%d", + o->scale); + started = true; + } + + output[slen++] = ']'; + + if (is_evex && deco) + slen += append_evex_mem_deco(output + slen, outbufsize - slen, + t, deco, ins.evex_p); + } else { + slen += + snprintf(output + slen, outbufsize - slen, "", + i); + } + } + output[slen] = '\0'; + if (segover) { /* unused segment override */ + char *p = output; + int count = slen + 1; + while (count--) + p[count + 3] = p[count]; + strncpy(output, segover, 2); + output[2] = ' '; + } + return length; +} + +/* + * This is called when we don't have a complete instruction. If it + * is a standalone *single-byte* prefix show it as such, otherwise + * print it as a literal. + */ +int32_t eatbyte(uint8_t *data, char *output, int outbufsize, int segsize) +{ + uint8_t byte = *data; + const char *str = NULL; + + switch (byte) { + case 0xF2: + str = "repne"; + break; + case 0xF3: + str = "rep"; + break; + case 0x9B: + str = "wait"; + break; + case 0xF0: + str = "lock"; + break; + case 0x2E: + str = "cs"; + break; + case 0x36: + str = "ss"; + break; + case 0x3E: + str = "ds"; + break; + case 0x26: + str = "es"; + break; + case 0x64: + str = "fs"; + break; + case 0x65: + str = "gs"; + break; + case 0x66: + str = (segsize == 16) ? "o32" : "o16"; + break; + case 0x67: + str = (segsize == 32) ? "a16" : "a32"; + break; + case REX_P + 0x0: + case REX_P + 0x1: + case REX_P + 0x2: + case REX_P + 0x3: + case REX_P + 0x4: + case REX_P + 0x5: + case REX_P + 0x6: + case REX_P + 0x7: + case REX_P + 0x8: + case REX_P + 0x9: + case REX_P + 0xA: + case REX_P + 0xB: + case REX_P + 0xC: + case REX_P + 0xD: + case REX_P + 0xE: + case REX_P + 0xF: + if (segsize == 64) { + snprintf(output, outbufsize, "rex%s%s%s%s%s", + (byte == REX_P) ? "" : ".", + (byte & REX_W) ? "w" : "", + (byte & REX_R) ? "r" : "", + (byte & REX_X) ? "x" : "", + (byte & REX_B) ? "b" : ""); + break; + } + /* else fall through */ + default: + snprintf(output, outbufsize, "db 0x%02x", byte); + break; + } + + if (str) + snprintf(output, outbufsize, "%s", str); + + return 1; +} diff --git a/disasm/disasm.h b/disasm/disasm.h new file mode 100644 index 0000000..053474d --- /dev/null +++ b/disasm/disasm.h @@ -0,0 +1,49 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * disasm.h header file for disasm.c + */ + +#ifndef NASM_DISASM_H +#define NASM_DISASM_H + +#include "iflag.h" + +#define INSN_MAX 32 /* one instruction can't be longer than this */ + +int32_t disasm(uint8_t *data, int32_t data_size, char *output, int outbufsize, int segsize, + int64_t offset, int autosync, iflag_t *prefer); +int32_t eatbyte(uint8_t *data, char *output, int outbufsize, int segsize); + +#endif diff --git a/disasm/ndisasm.c b/disasm/ndisasm.c new file mode 100644 index 0000000..2d0cf15 --- /dev/null +++ b/disasm/ndisasm.c @@ -0,0 +1,396 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * ndisasm.c the Netwide Disassembler main module + */ + +#include "compiler.h" + +#include +#include +#include +#include +#include +#include + +#include "insns.h" +#include "nasm.h" +#include "nasmlib.h" +#include "error.h" +#include "ver.h" +#include "sync.h" +#include "disasm.h" + +#define BPL 8 /* bytes per line of hex dump */ + +static const char *help = + "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n" + " [-e bytes] [-k start,bytes] [-p vendor] file\n" + " -a or -i activates auto (intelligent) sync\n" + " -u same as -b 32\n" + " -b 16, -b 32 or -b 64 sets the processor mode\n" + " -h displays this text\n" + " -r or -v displays the version number\n" + " -e skips bytes of header\n" + " -k avoids disassembling bytes from position \n" + " -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n"; + +static void output_ins(uint64_t, uint8_t *, int, char *); +static void skip(uint32_t dist, FILE * fp); + +static void ndisasm_verror(int severity, const char *fmt, va_list va) +{ + vfprintf(stderr, fmt, va); + + if (severity & ERR_FATAL) + exit(1); +} + +int main(int argc, char **argv) +{ + char buffer[INSN_MAX * 2], *p, *ep, *q; + char outbuf[256]; + char *pname = *argv; + char *filename = NULL; + uint32_t nextsync, synclen, initskip = 0L; + int lenread; + int32_t lendis; + bool autosync = false; + int bits = 16, b; + bool eof = false; + iflag_t prefer; + bool rn_error; + int64_t offset; + FILE *fp; + + tolower_init(); + nasm_set_verror(ndisasm_verror); + iflag_clear_all(&prefer); + + offset = 0; + init_sync(); + + while (--argc) { + char *v, *vv, *p = *++argv; + if (*p == '-' && p[1]) { + p++; + while (*p) + switch (nasm_tolower(*p)) { + case 'a': /* auto or intelligent sync */ + case 'i': + autosync = true; + p++; + break; + case 'h': + fputs(help, stderr); + return 0; + case 'r': + case 'v': + fprintf(stderr, + "NDISASM version %s compiled on %s\n", + nasm_version, nasm_date); + return 0; + case 'u': /* -u for -b 32, -uu for -b 64 */ + if (bits < 64) + bits <<= 1; + p++; + break; + case 'b': /* bits */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-b' requires an argument\n", + pname); + return 1; + } + b = strtoul(v, &ep, 10); + if (*ep || !(bits == 16 || bits == 32 || bits == 64)) { + fprintf(stderr, "%s: argument to `-b' should" + " be 16, 32 or 64\n", pname); + } else { + bits = b; + } + p = ""; /* force to next argument */ + break; + case 'o': /* origin */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-o' requires an argument\n", + pname); + return 1; + } + offset = readnum(v, &rn_error); + if (rn_error) { + fprintf(stderr, + "%s: `-o' requires a numeric argument\n", + pname); + return 1; + } + p = ""; /* force to next argument */ + break; + case 's': /* sync point */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-s' requires an argument\n", + pname); + return 1; + } + add_sync(readnum(v, &rn_error), 0L); + if (rn_error) { + fprintf(stderr, + "%s: `-s' requires a numeric argument\n", + pname); + return 1; + } + p = ""; /* force to next argument */ + break; + case 'e': /* skip a header */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-e' requires an argument\n", + pname); + return 1; + } + initskip = readnum(v, &rn_error); + if (rn_error) { + fprintf(stderr, + "%s: `-e' requires a numeric argument\n", + pname); + return 1; + } + p = ""; /* force to next argument */ + break; + case 'k': /* skip a region */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-k' requires an argument\n", + pname); + return 1; + } + vv = strchr(v, ','); + if (!vv) { + fprintf(stderr, + "%s: `-k' requires two numbers separated" + " by a comma\n", pname); + return 1; + } + *vv++ = '\0'; + nextsync = readnum(v, &rn_error); + if (rn_error) { + fprintf(stderr, + "%s: `-k' requires numeric arguments\n", + pname); + return 1; + } + synclen = readnum(vv, &rn_error); + if (rn_error) { + fprintf(stderr, + "%s: `-k' requires numeric arguments\n", + pname); + return 1; + } + add_sync(nextsync, synclen); + p = ""; /* force to next argument */ + break; + case 'p': /* preferred vendor */ + v = p[1] ? p + 1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-p' requires an argument\n", + pname); + return 1; + } + if (!strcmp(v, "intel")) { + iflag_clear_all(&prefer); /* default */ + } else if (!strcmp(v, "amd")) { + iflag_clear_all(&prefer); + iflag_set(&prefer, IF_AMD); + iflag_set(&prefer, IF_3DNOW); + } else if (!strcmp(v, "cyrix")) { + iflag_clear_all(&prefer); + iflag_set(&prefer, IF_CYRIX); + iflag_set(&prefer, IF_3DNOW); + } else if (!strcmp(v, "idt") || + !strcmp(v, "centaur") || + !strcmp(v, "winchip")) { + iflag_clear_all(&prefer); + iflag_set(&prefer, IF_3DNOW); + } else { + fprintf(stderr, + "%s: unknown vendor `%s' specified with `-p'\n", + pname, v); + return 1; + } + p = ""; /* force to next argument */ + break; + default: /*bf */ + fprintf(stderr, "%s: unrecognised option `-%c'\n", + pname, *p); + return 1; + } + } else if (!filename) { + filename = p; + } else { + fprintf(stderr, "%s: more than one filename specified\n", + pname); + return 1; + } + } + + if (!filename) { + fprintf(stderr, help, pname); + return 0; + } + + if (strcmp(filename, "-")) { + fp = fopen(filename, "rb"); + if (!fp) { + fprintf(stderr, "%s: unable to open `%s': %s\n", + pname, filename, strerror(errno)); + return 1; + } + } else + fp = stdin; + + if (initskip > 0) + skip(initskip, fp); + + /* + * This main loop is really horrible, and wants rewriting with + * an axe. It'll stay the way it is for a while though, until I + * find the energy... + */ + + p = q = buffer; + nextsync = next_sync(offset, &synclen); + do { + uint32_t to_read = buffer + sizeof(buffer) - p; + if ((nextsync || synclen) && + to_read > nextsync - offset - (p - q)) + to_read = nextsync - offset - (p - q); + if (to_read) { + lenread = fread(p, 1, to_read, fp); + if (lenread == 0) + eof = true; /* help along systems with bad feof */ + } else + lenread = 0; + p += lenread; + if ((nextsync || synclen) && + (uint32_t)offset == nextsync) { + if (synclen) { + fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX32" bytes\n", + offset, synclen); + offset += synclen; + skip(synclen, fp); + } + p = q = buffer; + nextsync = next_sync(offset, &synclen); + } + while (p > q && (p - q >= INSN_MAX || lenread == 0)) { + lendis = disasm((uint8_t *)q, INSN_MAX, outbuf, sizeof(outbuf), + bits, offset, autosync, &prefer); + if (!lendis || lendis > (p - q) + || ((nextsync || synclen) && + (uint32_t)lendis > nextsync - offset)) + lendis = eatbyte((uint8_t *) q, outbuf, sizeof(outbuf), bits); + output_ins(offset, (uint8_t *) q, lendis, outbuf); + q += lendis; + offset += lendis; + } + if (q >= buffer + INSN_MAX) { + uint8_t *r = (uint8_t *) buffer, *s = (uint8_t *) q; + int count = p - q; + while (count--) + *r++ = *s++; + p -= (q - buffer); + q = buffer; + } + } while (lenread > 0 || !(eof || feof(fp))); + + if (fp != stdin) + fclose(fp); + + return 0; +} + +static void output_ins(uint64_t offset, uint8_t *data, + int datalen, char *insn) +{ + int bytes; + fprintf(stdout, "%08"PRIX64" ", offset); + + bytes = 0; + while (datalen > 0 && bytes < BPL) { + fprintf(stdout, "%02X", *data++); + bytes++; + datalen--; + } + + fprintf(stdout, "%*s%s\n", (BPL + 1 - bytes) * 2, "", insn); + + while (datalen > 0) { + fprintf(stdout, " -"); + bytes = 0; + while (datalen > 0 && bytes < BPL) { + fprintf(stdout, "%02X", *data++); + bytes++; + datalen--; + } + fprintf(stdout, "\n"); + } +} + +/* + * Skip a certain amount of data in a file, either by seeking if + * possible, or if that fails then by reading and discarding. + */ +static void skip(uint32_t dist, FILE * fp) +{ + char buffer[256]; /* should fit on most stacks :-) */ + + /* + * Got to be careful with fseek: at least one fseek I've tried + * doesn't approve of SEEK_CUR. So I'll use SEEK_SET and + * ftell... horrible but apparently necessary. + */ + if (fseek(fp, dist + ftell(fp), SEEK_SET)) { + while (dist > 0) { + uint32_t len = (dist < sizeof(buffer) ? + dist : sizeof(buffer)); + if (fread(buffer, 1, len, fp) < len) { + perror("fread"); + exit(1); + } + dist -= len; + } + } +} diff --git a/disasm/sync.c b/disasm/sync.c new file mode 100644 index 0000000..7116b22 --- /dev/null +++ b/disasm/sync.c @@ -0,0 +1,132 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * sync.c the Netwide Disassembler synchronisation processing module + */ + +#include "compiler.h" + +#include +#include +#include + +#include "nasmlib.h" +#include "sync.h" + +#define SYNC_MAX_SHIFT 31 +#define SYNC_MAX_SIZE (1U << SYNC_MAX_SHIFT) + +/* initial # of sync points (*must* be power of two)*/ +#define SYNC_INITIAL_CHUNK (1U << 12) + +/* + * This lot manages the current set of sync points by means of a + * heap (priority queue) structure. + */ + +static struct Sync { + uint64_t pos; + uint32_t length; +} *synx; + +static uint32_t max_synx, nsynx; + +static inline void swap_sync(uint32_t dst, uint32_t src) +{ + struct Sync t = synx[dst]; + synx[dst] = synx[src]; + synx[src] = t; +} + +void init_sync(void) +{ + max_synx = SYNC_INITIAL_CHUNK; + synx = nasm_malloc((max_synx + 1) * sizeof(*synx)); + nsynx = 0; +} + +void add_sync(uint64_t pos, uint32_t length) +{ + uint32_t i; + + if (nsynx >= max_synx) { + if (max_synx >= SYNC_MAX_SIZE) /* too many sync points! */ + return; + max_synx = (max_synx << 1); + synx = nasm_realloc(synx, (max_synx + 1) * sizeof(*synx)); + } + + nsynx++; + synx[nsynx].pos = pos; + synx[nsynx].length = length; + + for (i = nsynx; i > 1; i /= 2) { + if (synx[i / 2].pos > synx[i].pos) + swap_sync(i / 2, i); + } +} + +uint64_t next_sync(uint64_t position, uint32_t *length) +{ + while (nsynx > 0 && synx[1].pos + synx[1].length <= position) { + uint32_t i, j; + + swap_sync(nsynx, 1); + nsynx--; + + i = 1; + while (i * 2 <= nsynx) { + j = i * 2; + if (synx[j].pos < synx[i].pos && + (j + 1 > nsynx || synx[j + 1].pos > synx[j].pos)) { + swap_sync(j, i); + i = j; + } else if (j + 1 <= nsynx && synx[j + 1].pos < synx[i].pos) { + swap_sync(j + 1, i); + i = j + 1; + } else + break; + } + } + + if (nsynx > 0) { + if (length) + *length = synx[1].length; + return synx[1].pos; + } else { + if (length) + *length = 0L; + return 0; + } +} diff --git a/disasm/sync.h b/disasm/sync.h new file mode 100644 index 0000000..15c5afd --- /dev/null +++ b/disasm/sync.h @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------------- * + * + * 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. + * + * ----------------------------------------------------------------------- */ + +/* + * sync.h header file for sync.c + */ + +#ifndef NASM_SYNC_H +#define NASM_SYNC_H + +void init_sync(void); +void add_sync(uint64_t position, uint32_t length); +uint64_t next_sync(uint64_t position, uint32_t *length); + +#endif diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..69b8d8b --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,90 @@ +# +# UNIX Makefile for NASM documentation +# + +top_srcdir = .. +srcdir = . + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin +mandir = ${datarootdir}/man +docdir = ${datarootdir}/doc/${PACKAGE} +htmldir = ${docdir} +infodir = ${datarootdir}/info +datarootdir = ${prefix}/share + +INSTALL = /bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +PERL = perl -I$(srcdir) + +PDFOPT = + +MKDIR = mkdir +RM_F = rm -f +RM_RF = rm -rf +CP_F = cp -f +CP_UF = cp -ufv + +# Auxiliary files referenced by the HTML files +HTMLAUX = nasmdoc.css local.css nasmlogw.png + +SRCS = nasmdoc.src inslist.src changes.src version.src +OUT = html nasmdoc.txt nasmdoc.pdf + +.SUFFIXES: +.SUFFIXES: .pfa .ph + +all: $(OUT) + +inslist.src: inslist.pl ../x86/insns.dat + $(PERL) $(srcdir)/inslist.pl $(srcdir)/../x86/insns.dat + +.PHONY: html +html: $(HTMLAUX) + $(MKDIR) -p html + for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done + $(MAKE) html/nasmdoc0.html + +RDSRC = $(PERL) $(srcdir)/rdsrc.pl -I$(srcdir)/ + +html/nasmdoc0.html: $(SRCS) rdsrc.pl + $(RM_F) html/*.html + $(RDSRC) -ohtml html nasmdoc.src + +nasmdoc.dip: $(SRCS) rdsrc.pl + $(RDSRC) dip nasmdoc.src + +nasmdoc.txt: $(SRCS) rdsrc.pl + $(RDSRC) txt nasmdoc.src + +version.src: $(top_srcdir)/version.pl $(top_srcdir)/version + $(PERL) $(top_srcdir)/version.pl docsrc \ + < $(top_srcdir)/version > version.src + +nasmdoc.ps: nasmdoc.dip genps.pl afmmetrics.ph ttfmetrics.ph \ + pswidth.ph nasmlogo.eps psfonts.ph head.ps + $(PERL) $(srcdir)/genps.pl -epsdir "$(srcdir)" \ + -headps $(srcdir)/head.ps nasmdoc.dip \ + > nasmdoc.ps + +nasmdoc.pdf: nasmdoc.ps pspdf.pl + $(PERL) $(srcdir)/pspdf.pl $(PDFOPT) nasmdoc.ps nasmdoc.pdf + +clean: + -$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip + -$(RM_F) *.aux *.cp *.fn *.ky *.pg *.log *.toc *.tp *.vr + -$(RM_F) inslist.src version.src + -$(RM_F) nasmdoc*.ps + +spotless: clean + -$(RM_RF) html info + -$(RM_F) *.hlp nasmdoc.txt *.inf *.pdf *.dvi + +install: all + $(MKDIR) -p $(DESTDIR)$(htmldir) + $(INSTALL_DATA) html/* $(DESTDIR)$(htmldir) + $(MKDIR) -p $(DESTDIR)$(docdir) + $(INSTALL_DATA) nasmdoc.pdf nasmdoc.txt $(DESTDIR)$(docdir) diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..27e6fad --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,90 @@ +# +# UNIX Makefile for NASM documentation +# + +top_srcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ +docdir = @docdir@ +htmldir = @htmldir@ +infodir = @infodir@ +datarootdir = @datarootdir@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +PERL = perl -I$(srcdir) + +PDFOPT = @PDFOPT@ + +MKDIR = mkdir +RM_F = rm -f +RM_RF = rm -rf +CP_F = cp -f +CP_UF = cp -ufv + +# Auxiliary files referenced by the HTML files +HTMLAUX = nasmdoc.css local.css nasmlogw.png + +SRCS = nasmdoc.src inslist.src changes.src version.src +OUT = html nasmdoc.txt nasmdoc.pdf + +.SUFFIXES: +.SUFFIXES: .pfa .ph + +all: $(OUT) + +inslist.src: inslist.pl ../x86/insns.dat + $(PERL) $(srcdir)/inslist.pl $(srcdir)/../x86/insns.dat + +.PHONY: html +html: $(HTMLAUX) + $(MKDIR) -p html + for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done + $(MAKE) html/nasmdoc0.html + +RDSRC = $(PERL) $(srcdir)/rdsrc.pl -I$(srcdir)/ + +html/nasmdoc0.html: $(SRCS) rdsrc.pl + $(RM_F) html/*.html + $(RDSRC) -ohtml html nasmdoc.src + +nasmdoc.dip: $(SRCS) rdsrc.pl + $(RDSRC) dip nasmdoc.src + +nasmdoc.txt: $(SRCS) rdsrc.pl + $(RDSRC) txt nasmdoc.src + +version.src: $(top_srcdir)/version.pl $(top_srcdir)/version + $(PERL) $(top_srcdir)/version.pl docsrc \ + < $(top_srcdir)/version > version.src + +nasmdoc.ps: nasmdoc.dip genps.pl afmmetrics.ph ttfmetrics.ph \ + pswidth.ph nasmlogo.eps psfonts.ph head.ps + $(PERL) $(srcdir)/genps.pl -epsdir "$(srcdir)" \ + -headps $(srcdir)/head.ps nasmdoc.dip \ + > nasmdoc.ps + +nasmdoc.pdf: nasmdoc.ps pspdf.pl + $(PERL) $(srcdir)/pspdf.pl $(PDFOPT) nasmdoc.ps nasmdoc.pdf + +clean: + -$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip + -$(RM_F) *.aux *.cp *.fn *.ky *.pg *.log *.toc *.tp *.vr + -$(RM_F) inslist.src version.src + -$(RM_F) nasmdoc*.ps + +spotless: clean + -$(RM_RF) html info + -$(RM_F) *.hlp nasmdoc.txt *.inf *.pdf *.dvi + +install: all + $(MKDIR) -p $(DESTDIR)$(htmldir) + $(INSTALL_DATA) html/* $(DESTDIR)$(htmldir) + $(MKDIR) -p $(DESTDIR)$(docdir) + $(INSTALL_DATA) nasmdoc.pdf nasmdoc.txt $(DESTDIR)$(docdir) diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..6395622 --- /dev/null +++ b/doc/README @@ -0,0 +1,20 @@ +To build the entire documentation, the following tools are needed: + +1. A Perl interpreter for your platform +2. The following Perl modules available from CPAN: + Font::TTF + Sort::Versions +3. asciidoc + http://asciidoc.org/ +4. xmlto + https://fedorahosted.org/xmlto +5. One of: + Adobe Acrobat (acrodist) + Ghostscript (ps2pdf) http://download.ghostscript.com/ + pstopdf (available on some BSD-derived Unix systems) + + Of these, Ghostscript is the most tested, although Acrobat has + been claimed to generate smaller files. +6. For best results, the Adobe fonts Source Sans Pro and Source Code + Pro, available for free at: + https://github.com/adobe-fonts diff --git a/doc/afmmetrics.ph b/doc/afmmetrics.ph new file mode 100644 index 0000000..c6f6d61 --- /dev/null +++ b/doc/afmmetrics.ph @@ -0,0 +1,102 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2017 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. +## +## -------------------------------------------------------------------------- + +# +# Parse AFM metric file, returns a reference to fontdata +# +sub parse_afm_file($$) { + my($filename, $filetype) = @_; + + my $fontdata = { + widths => {}, + kern => {} + }; + + my $charmetrics = 0; + my $kerndata = 0; + my $charcode, $width, $name; + + my $fontfile = $filename.'.'.$filetype; + return undef unless ( -f $fontfile ); + + $fontdata->{file} = $fontfile; + $fontdata->{type} = $filetype; + $fontdata->{scale} = 1000; # AFM metrics always have scale 1000 + + return undef unless (open(my $fh, '<', $filename.'.afm')); + + while ( my $line = <$fh> ) { + if ( $line =~ /^\s*FontName\s+(.*)\s*$/i ) { + $fontdata->{'name'} = $1; + } elsif ( $line =~ /^\s*StartCharMetrics\b/i ) { + $charmetrics = 1; + } elsif ( $line =~ /^\s*EndCharMetrics\b/i ) { + $charmetrics = 0; + } elsif ( $line =~ /^\s*StartKernPairs\b/i ) { + $kerndata = 1; + } elsif ( $line =~ /^\s*EndKernPairs\b/i ) { + $kerndata = 0; + } elsif ( $charmetrics ) { + my @data = split(/\s*;\s*/, $line); + undef $charcode, $width, $name; + foreach my $d ( @data ) { + my @dd = split(/\s+/, $d); + if ( $dd[0] eq 'C' ) { + $charcode = $dd[1]; + } elsif ( $dd[0] eq 'WX' ) { + $width = $dd[1]; + } elsif ( $dd[0] eq 'W' ) { + $width = $dd[2]; + } elsif ( $dd[0] eq 'N' ) { + $name = $dd[1]; + } + } + if ( defined($name) && defined($width) ) { + $fontdata->{widths}{$name} = $width; + } + } elsif ( $kerndata ) { + my($kpx, $a, $b, $adj) = split(/\s+/, $line); + if ( $kpx eq 'KPX' ) { + if (!exists($fontdata->{kern}{$a})) { + $fontdata->{kern}{$a} = {}; + } + $fontdata->{kern}{$a}{$b} = $adj; + } + } + } + + return $fontdata; +} + +1; diff --git a/doc/changes.src b/doc/changes.src new file mode 100644 index 0000000..efed8a1 --- /dev/null +++ b/doc/changes.src @@ -0,0 +1,2659 @@ +\# +\# NASM revision history in nasmdoc format +\# + +\H{cl-2.xx} NASM 2 Series + +The NASM 2 series supports x86-64, and is the production version of NASM +since 2007. + +\S{cl-2.14} Version 2.14 + +\b Changed \c{-I} option semantics by adding a trailing path separator unconditionally. + +\b Fixed null dereference in corrupted invalid single line macros. + +\b Fixed division by zero which may happen if source code is malformed. + +\b Fixed out of bound access in processing of malformed segment override. + +\b Fixed out of bound access in certain \c{EQU} parsing. + +\b Fixed buffer underflow in float parsing. + +\b Added \c{SGX} (Intel Software Guard Extensions) instructions. + +\b Added \c{+n} syntax for multiple contiguous registers. + +\b Fixed \c{subsections_via_symbols} for \c{macho} object format. + +\b Added the \c{--gprefix}, \c{--gpostfix}, \c{--lprefix}, and +\c{--lpostfix} command line options, to allow command line base symbol +renaming. See \k{opt-pfix}. + +\b Allow label renaming to be specified by \c{%pragma} in addition to +from the command line. See \k{mangling}. + +\b Supported generic \c{%pragma} namespaces, \c{output} and \c{debug}. See +\k{gen-namespace}. + +\b Added the \c{--pragma} command line option to inject a \c{%pragma} +directive. See \k{opt-pragma}. + +\b Added the \c{--before} command line option to accept preprocess +statement before input. See \k{opt-before}. + +\b Added \c{AVX512} \c{VBMI2} (Additional Bit Manipulation), \c{VNNI} (Vector +Neural Network), \c{BITALG} (Bit Algorithm), and \c{GFNI} (Galois Field New +Instruction) instructions. + +\b Added the \c{STATIC} directive for local symbols that should be +renamed using global-symbol rules. See \k{static}. + +\b Allow a symbol to be defined as \c{EXTERN} and then later +overridden as \c{GLOBAL} or \c{COMMON}. Furthermore, a symbol declared +\c{EXTERN} and then defined will be treated as \c{GLOBAL}. See \k{extern}. + +\b The \c{GLOBAL} directive no longer is required to precede the +definition of the symbol. + +\b Support \c{private_extern} as \c{macho} specific extension to the +\c{GLOBAL} directive. See \k{macho-pext}. + +\b Updated \c{UD0} encoding to match with the specification + +\b Added the \c{--limit-X} command line option to set execution +limits. See \k{opt-limit}. + +\b Updated the \c{Codeview} version number to be aligned with \c{MASM}. + +\b Added the \c{--keep-all} command line option to preserve output +files. See \k{opt-keep-all}. + +\b Added the \c{--include} command line option, an alias to \c{-P} (\k{opt-p}). + +\b Added the \c{--help} command line option as an alias to \c{-h} (\k{syntax}). + +\b Added \c{-W}, \c{-D}, and \c{-Q} suffix aliases for \c{RET} + instructions so the operand sizes of these instructions can be + encoded without using \c{o16}, \c{o32} or \c{o64}. + +\S{cl-2.13.03} Version 2.13.03 + +\b Added AVX and AVX512 \c{VAES*} and \c{VPCLMULQDQ} instructions. + +\b Fixed missing dwarf record in x32 ELF output format. + +\S{cl-2.13.02} Version 2.13.02 + +\b Fix false positive in testing of numeric overflows. + +\b Fix generation of \c{PEXTRW} instruction. + +\b Fix \c{smartalign} package which could trigger an error during + optimization if the alignment code expanded too much due to + optimization of the previous code. + +\b Fix a case where negative value in \c{TIMES} directive causes + panic instead of an error. + +\b Always finalize \c{.debug_abbrev} section with a null in + \c{dwarf} output format. + +\b Support \c{debug} flag in section attributes for \c{macho} + output format. See \k{machosect}. + +\b Support up to 16 characters in section names for \c{macho} + output format. + +\b Fix missing update of global \c{BITS} setting if \c{SECTION} + directive specified a bit size using output format-specific + extensions (e.g. \c{USE32} for the \c{obj} output format.) + +\b Fix the incorrect generation of VEX-encoded instruction when static + mode decorators are specified on scalar instructions, losing the + decorators as they require EVEX encoding. + +\b Option \c{-MW} to quote dependency outputs according to Watcom + Make conventions instead of POSIX Make conventions. See \k{opt-MW}. + +\b The \c{obj} output format now contains embedded dependency file + information, unless disabled with \c{%pragma obj nodepend}. See + \k{objdepend}. + +\b Fix generation of dependency lists. + +\b Fix a number of null pointer reference and memory allocation errors. + +\b Always generate symbol-relative relocations for the \c{macho64} + output format; at least some versions of the XCode/LLVM linker fails + for section-relative relocations. + +\S{cl-2.13.01} Version 2.13.01 + +\b Fix incorrect output for some types of \c{FAR} or \c{SEG} + references in the \c{obj} output format, and possibly other 16-bit + output formats. + +\b Fix the address in the list file for an instruction containing a + \c{TIMES} directive. + +\b Fix error with \c{TIMES} used together with an instruction which + can vary in size, e.g. \c{JMP}. + +\b Fix breakage on some uses of the \c{DZ} pseudo-op. + +\S{cl-2.13} Version 2.13 + +\b Support the official forms of the \c{UD0} and \c{UD1} instructions. + +\b Allow self-segment-relative expressions in immediates and + displacements, even when combined with an external or otherwise + out-of-segment special symbol, e.g.: + +\c extern foo +\c mov eax,[foo - $ + ebx] ; Now legal + +\b Handle a 64-bit origin in NDISASM. + +\b NASM can now generate sparse output files for relevant output + formats, if the underlying operating system supports them. + +\b The \c{macho} object format now supports the \c{subsections_via_symbols} + and \c{no_dead_strip} directives, see \k{macho-ssvs}. + +\b The \c{macho} object format now supports the \c{no_dead_strip}, + \c{live_support} and \c{strip_static_syms} section flags, see + \k{machosect}. + +\b The \c{macho} object format now supports the \c{dwarf} debugging + format, as required by newer toolchains. + +\b All warnings can now be suppressed if desired; warnings not + otherwise part of any warning class are now considered its own + warning class called \c{other} (e.g. \c{-w-other}). Furthermore, + warning-as-error can now be controlled on a per warning class + basis, using the syntax \c{-w+error=}\e{warning-class} and its + equivalent for all other warning control options. See \k{opt-w} + for the command-line options and warning classes and + \k{asmdir-warning} for the \c{[WARNING]} directive. + +\b Fix a number of bugs related to AVX-512 decorators. + +\b Significant improvements to building NASM with Microsoft Visual + Studio via \c{Mkfiles/msvc.mak}. It is now possible to build the + full Windows installer binary as long as the necessary + prerequisites are installed; see \c{Mkfiles/README} + +\b To build NASM with custom modifications (table changes) or from the + git tree now requires Perl 5.8 at the very minimum, quite possibly + a higher version (Perl 5.24.1 tested.) There is no requirement to + have Perl on your system at all if all you want to do is build + unmodified NASM from source archives. + +\b Fix the \c{\{z\}} decorator on AVX-512 \c{VMOVDQ*} instructions. + +\b Add new warnings for certain dangerous constructs which never ought + to have been allowed. In particular, the \c{RESB} family of + instructions should have been taking a critical expression all + along. + +\b Fix the EVEX (AVX-512) versions of the \c{VPBROADCAST}, \c{VPEXTR}, + and \c{VPINSR} instructions. + +\b Support contracted forms of additional instructions. As a general + rule, if an instruction has a non-destructive source immediately + after a destination register that isn't used as an input, NASM + supports omitting that source register, using the destination + register as that value. This among other things makes it easier to + convert SSE code to the equivalent AVX code: + +\c addps xmm1,xmm0 ; SSE instruction +\c vaddps ymm1,ymm1,ymm0 ; AVX official long form +\c vaddps ymm1,ymm0 ; AVX contracted form + +\b Fix Codeview malformed compiler version record. + +\b Add the \c{CLWB} and \c{PCOMMIT} instructions. Note that the + \c{PCOMMIT} instruction has been deprecated and will never be + included in a shipping product; it is included for completeness + only. + +\b Add the \c{%pragma} preprocessor directive for soft-error directives. + +\b Add the \c{RDPID} instruction. + +\S{cl-2.12.02} Version 2.12.02 + +\b Fix preprocessor errors, especially \c{%error} and \c{%warning}, + inside \c{%if} statements. + +\b Fix relative relocations in 32-bit Mach-O. + +\b More Codeview debug format fixes. + +\b If the MASM \c{PTR} keyword is encountered, issue a warning. This is + much more likely to indicate a MASM-ism encountered in NASM than it + is a valid label. This warning can be suppressed with \c{-w-ptr}, + the \c{[warning]} directive (see \k{opt-w}) or by the macro + definition \c{%idefine ptr $%?} (see \k{selfref%?}). + +\b When an error or a warning comes from the expansion of a multi-line + macro, display the file and line numbers for the expanded macros. + Macros defined with \c{.nolist} do not get displayed. + +\b Add macros \c{ilog2fw()} and \c{ilog2cw()} to the \c{ifunc} macro + package. See \k{ilog2}. + + +\S{cl-2.12.01} Version 2.12.01 + +\b Portability fixes for some platforms. + +\b Fix error when not specifying a list file. + +\b Correct the handling of macro-local labels in the Codeview + debugging format. + +\b Add \c{CLZERO}, \c{MONITORX} and \c{MWAITX} instructions. + + +\S{cl-2.12} Version 2.12 + +\b Major fixes to the \c{macho} backend (\k{machofmt}); earlier versions + would produce invalid symbols and relocations on a regular basis. + +\b Support for thread-local storage in Mach-O. + +\b Support for arbitrary sections in Mach-O. + +\b Fix wrong negative size treated as a big positive value passed into + backend causing NASM to crash. + +\b Fix handling of zero-extending unsigned relocations, we have been printing + wrong message and forgot to assign segment with predefined value before + passing it into output format. + +\b Fix potential write of oversized (with size greater than allowed in + output format) relative relocations. + +\b Portability fixes for building NASM with the LLVM compiler. + +\b Add support of Codeview version 8 (\c{cv8}) debug format for + \c{win32} and \c{win64} formats in the \c{COFF} backend, + see \k{codeview}. + +\b Allow 64-bit outputs in 16/32-bit only backends. Unsigned 64-bit + relocations are zero-extended from 32-bits with a warning + (suppressible via \c{-w-zext-reloc}); signed 64-bit relocations are + an error. + +\b Line numbers in list files now correspond to the lines in the source + files, instead of simply being sequential. + +\b There is now an official 64-bit (x64 a.k.a. x86-64) build for Windows. + + +\S{cl-2.11.09} Version 2.11.09 + +\b Fix potential stack overwrite in \c{macho32} backend. + +\b Fix relocation records in \c{macho64} backend. + +\b Fix symbol lookup computation in \c{macho64} backend. + +\b Adjust \c{.symtab} and \c{.rela.text} sections alignments to 8 bytes + in \c{elf64} backed. + +\b Fix section length computation in \c{bin} backend which leaded in incorrect + relocation records. + +\S{cl-2.11.08} Version 2.11.08 + +\b Fix section length computation in \c{bin} backend which leaded in incorrect + relocation records. + +\b Add a warning for numeric preprocessor definitions passed via command + line which might have unexpected results otherwise. + +\b Add ability to specify a module name record in \c{rdoff} linker with + \c{-mn} option. + +\b Increase label length capacity up to 256 bytes in \c{rdoff} backend for + FreePascal sake, which tends to generate very long labels for procedures. + +\b Fix segmentation failure when rip addressing is used in \c{macho64} backend. + +\b Fix access on out of memory when handling strings with a single + grave. We have sixed similar problem in previous release but not + all cases were covered. + +\b Fix NULL dereference in disassembled on \c{BND} instruction. + +\S{cl-2.11.07} Version 2.11.07 + +\b Fix 256 bit \c{VMOVNTPS} instruction. + +\b Fix \c{-MD} option handling, which was rather broken in previous +release changing command line api. + +\b Fix access to unitialized space when handling strings with +a single grave. + +\b Fix nil dereference in handling memory reference parsing. + +\S{cl-2.11.06} Version 2.11.06 + +\b Update AVX512 instructions based on the Extension Reference (319433-021 Sept +2014). + +\b Fix the behavior of \c{-MF} and \c{-MD} options (Bugzilla 3392280) + +\b Updated Win32 Makefile to fix issue with build + +\S{cl-2.11.05} Version 2.11.05 + +\b Add \c{--v} as an alias for \c{-v} (see \k{opt-v}), for +command-line compatibility with Yasm. + +\b Fix a bug introduced in 2.11.03 whereby certain instructions would +contain multiple REX prefixes, and thus be corrupt. + +\S{cl-2.11.04} Version 2.11.04 + +\b Removed an invalid error checking code. Sometimes a memref only with +a displacement can also set an evex flag. For example: + +\c vmovdqu32 [0xabcd]{k1}, zmm0 + +\b Fixed a bug in disassembler that EVEX.L'L vector length was not matched +when EVEX.b was set because it was simply considered as EVEC.RC. +Separated EVEX.L'L case from EVEX.RC which is ignored in matching. + +\S{cl-2.11.03} Version 2.11.03 + +\b Fix a bug there REX prefixes were missing on instructions inside a +\c{TIMES} statement. + +\S{cl-2.11.02} Version 2.11.02 + +\b Add the \c{XSAVEC}, \c{XSAVES} and \c{XRSTORS} family instructions. + +\b Add the \c{CLFLUSHOPT} instruction. + +\S{cl-2.11.01} Version 2.11.01 + +\b Allow instructions which implicitly uses \c{XMM0} (\c{VBLENDVPD}, +\c{VBLENDVPS}, \c{PBLENDVB} and \c{SHA256RNDS2}) to be specified +without an explicit \c{xmm0} on the assembly line. In other words, +the following two lines produce the same output: + +\c vblendvpd xmm2,xmm1,xmm0 ; Last operand is fixed xmm0 +\c vblendvpd xmm2,xmm1 ; Implicit xmm0 omitted + +\b In the ELF backends, don't crash the assembler if \c{section align} +is specified without a value. + +\S{cl-2.11} Version 2.11 + +\b Add support for the Intel AVX-512 instruction set: + +\b 16 new, 512-bit SIMD registers. Total 32 \c{(ZMM0 ~ ZMM31)} + +\b 8 new opmask registers \c{(K0 ~ K7)}. One of 7 registers \c{(K1 ~ K7)} can +be used as an opmask for conditional execution. + +\b A new EVEX encoding prefix. EVEX is based on VEX and provides more +capabilities: opmasks, broadcasting, embedded rounding and compressed +displacements. + +\c - opmask +\c VDIVPD zmm0{k1}{z}, zmm1, zmm3 ; conditional vector operation +\c ; using opmask k1. +\c ; {z} is for zero-masking +\c - broadcasting +\c VDIVPS zmm4, zmm5, [rbx]{1to16} ; load single-precision float and +\c ; replicate it 16 times. 32 * 16 = 512 +\c - embedded rounding +\c VCVTSI2SD xmm6, xmm7, {rz-sae}, rax ; round toward zero. note that it +\c ; is used as if a separate operand. +\c ; it comes after the last SIMD operand + +\b Add support for \c{ZWORD} (512 bits), \c{DZ} and \c{RESZ}. + +\b Add support for the MPX and SHA instruction sets. + +\b Better handling of section redefinition. + +\b Generate manpages when running \c{'make dist'}. + +\b Handle all token chains in mmacro params range. + +\b Support split [base,index] effective address: + +\c mov eax,[eax+8,ecx*4] ; eax=base, ecx=index, 4=scale, 8=disp + +This is expected to be most useful for the MPX instructions. + +\b Support \c{BND} prefix for branch instructions (for MPX). + +\b The \c{DEFAULT} directive can now take \c{BND} and \c{NOBND} +options to indicate whether all relevant branches should be getting +\c{BND} prefixes. This is expected to be the normal for use in MPX +code. + +\b Add \c{{evex}}, \c{{vex3}} and \c{{vex2}} instruction prefixes to +have NASM encode the corresponding instruction, if possible, with an EVEX, +3-byte VEX, or 2-byte VEX prefix, respectively. + +\b Support for section names longer than 8 bytes in Win32/Win64 COFF. + +\b The \c{NOSPLIT} directive by itself no longer forces a single +register to become an index register, unless it has an explicit +multiplier. + +\c mov eax,[nosplit eax] ; eax as base register +\c mov eax,[nosplit eax*1] ; eax as index register + +\S{cl-2.10.09} Version 2.10.09 + +\b Pregenerate man pages. + +\S{cl-2.10.08} Version 2.10.08 + +\b Fix \c{VMOVNTDQA}, \c{MOVNTDQA} and \c{MOVLPD} instructions. + +\b Fix collision for \c{VGATHERQPS}, \c{VPGATHERQD} instructions. + +\b Fix \c{VPMOVSXBQ}, \c{VGATHERQPD}, \c{VSPLLW} instructions. + +\b Add a bunch of AMD TBM instructions. + +\b Fix potential stack overwrite in numbers conversion. + +\b Allow byte size in \c{PREFETCHTx} instructions. + +\b Make manual pages up to date. + +\b Make \c{F3} and \c{F2} SSE prefixes to override \c{66}. + +\b Support of AMD SVM instructions in 32 bit mode. + +\b Fix near offsets code generation for \c{JMP}, \c{CALL} instrictions +in long mode. + +\b Fix preprocessor parse regression when id is expanding to a whitespace. + +\S{cl-2.10.07} Version 2.10.07 + +\b Fix line continuation parsing being broken in previous version. + +\S{cl-2.10.06} Version 2.10.06 + +\b Always quote the dependency source names when using the automatic +dependency generation options. + +\b If no dependency target name is specified via the \c{-MT} or +\c{-MQ} options, quote the default output name. + +\b Fix assembly of shift operations in \c{CPU 8086} mode. + +\b Fix incorrect generation of explicit immediate byte for shift by 1 +under certain circumstances. + +\b Fix assembly of the \c{VPCMPGTQ} instruction. + +\b Fix RIP-relative relocations in the \c{macho64} backend. + +\S{cl-2.10.05} Version 2.10.05 + +\b Add the \c{CLAC} and \c{STAC} instructions. + +\S{cl-2.10.04} Version 2.10.04 + +\b Add back the inadvertently deleted 256-bit version of the \c{VORPD} +instruction. + +\b Correct disassembly of instructions starting with byte \c{82} hex. + +\b Fix corner cases in token pasting, for example: + +\c %define N 1e%++%+ 5 +\c dd N, 1e+5 + +\S{cl-2.10.03} Version 2.10.03 + +\b Correct the assembly of the instruction: + +\c XRELEASE MOV [absolute],AL + +\> Previous versions would incorrectly generate \c{F3 A2} for this +instruction and issue a warning; correct behavior is to emit \c{F3 88 +05}. + +\S{cl-2.10.02} Version 2.10.02 + +\b Add the \c{ifunc} macro package with integer functions, currently +only integer logarithms. See \k{pkg_ifunc}. + +\b Add the \c{RDSEED}, \c{ADCX} and \c{ADOX} instructions. + +\S{cl-2.10.01} Version 2.10.01 + +\b Add missing VPMOVMSKB instruction with reg32, ymmreg operands. + +\S{cl-2.10} Version 2.10 + +\b When optimization is enabled, \c{mov r64,imm} now optimizes to the + shortest form possible between: + +\c mov r32,imm32 ; 5 bytes +\c mov r64,imm32 ; 7 bytes +\c mov r64,imm64 ; 10 bytes + +\> To force a specific form, use the \c{STRICT} keyword, see \k{strict}. + +\b Add support for the Intel AVX2 instruction set. + +\b Add support for Bit Manipulation Instructions 1 and 2. + +\b Add support for Intel Transactional Synchronization Extensions (TSX). + +\b Add support for x32 ELF (32-bit ELF with the CPU in 64-bit mode.) + See \k{elffmt}. + +\b Add support for bigendian UTF-16 and UTF-32. See \k{unicode}. + +\S{cl-2.09.10} Version 2.09.10 + +\b Fix up NSIS script to protect uninstaller against registry keys + absence or corruption. It brings in a few additional questions + to a user during deinstallation procedure but still it is better + than unpredictable file removal. + +\S{cl-2.09.09} Version 2.09.09 + +\b Fix initialization of section attributes of \c{bin} output format. + +\b Fix \c{mach64} output format bug that crashes NASM due to NULL symbols. + + +\S{cl-2.09.08} Version 2.09.08 + +\b Fix \c{__OUTPUT_FORMAT__} assignment when output driver alias + is used. For example when \c{-f elf} is used \c{__OUTPUT_FORMAT__} + must be set to \c{elf}, if \c{-f elf32} is used \c{__OUTPUT_FORMAT__} + must be assigned accordingly, i.e. to \c{elf32}. The rule applies to + all output driver aliases. See \k{ofmtm}. + + +\S{cl-2.09.07} Version 2.09.07 + +\b Fix attempts to close same file several times + when \c{-a} option is used. + +\b Fixes for VEXTRACTF128, VMASKMOVPS encoding. + + +\S{cl-2.09.06} Version 2.09.06 + +\b Fix missed section attribute initialization in \c{bin} output target. + + +\S{cl-2.09.05} Version 2.09.05 + +\b Fix arguments encoding for VPEXTRW instruction. + +\b Remove invalid form of VPEXTRW instruction. + +\b Add \c{VLDDQU} as alias for \c{VLDQQU} to + match specification. + + +\S{cl-2.09.04} Version 2.09.04 + +\b Fix incorrect labels offset for VEX intructions. + +\b Eliminate bogus warning on implicit operand size override. + +\b \c{%if} term could not handle 64 bit numbers. + +\b The COFF backend was limiting relocations number to 16 bits even if + in real there were a way more relocations. + + +\S{cl-2.09.03} Version 2.09.03 + +\b Print \c{%macro} name inside \c{%rep} blocks on error. + +\b Fix preprocessor expansion behaviour. It happened sometime + too early and sometime simply wrong. Move behaviour back to + the origins (down to NASM 2.05.01). + +\b Fix unitialized data dereference on OMF output format. + +\b Issue warning on unterminated \c{%{} construct. + +\b Fix for documentation typo. + + +\S{cl-2.09.02} Version 2.09.02 + +\b Fix reversed tokens when \c{%deftok} produces more than one output token. + +\b Fix segmentation fault on disassembling some VEX instructions. + +\b Missing \c{%endif} did not always cause error. + +\b Fix typo in documentation. + +\b Compound context local preprocessor single line macro identifiers + were not expanded early enough and as result lead to unresolved + symbols. + + +\S{cl-2.09.01} Version 2.09.01 + +\b Fix NULL dereference on missed %deftok second parameter. + +\b Fix NULL dereference on invalid %substr parameters. + + +\S{cl-2.09} Version 2.09 + +\b Fixed assignment the magnitude of \c{%rep} counter. It is limited + to 62 bits now. + +\b Fixed NULL dereference if argument of \c{%strlen} resolves + to whitespace. For example if nonexistent macro parameter is used. + +\b \c{%ifenv}, \c{%elifenv}, \c{%ifnenv}, and \c{%elifnenv} directives + introduced. See \k{ifenv}. + +\b Fixed NULL dereference if environment variable is missed. + +\b Updates of new AVX v7 Intel instructions. + +\b \c{PUSH imm32} is now officially documented. + +\b Fix for encoding the LFS, LGS and LSS in 64-bit mode. + +\b Fixes for compatibility with OpenWatcom compiler and DOS 8.3 file + format limitation. + +\b Macros parameters range expansion introduced. See \k{mlmacrange}. + +\b Backward compatibility on expanging of local sigle macros restored. + +\b 8 bit relocations for \c{elf} and \c{bin} output formats are introduced. + +\b Short intersegment jumps are permitted now. + +\b An alignment more than 64 bytes are allowed for \c{win32}, + \c{win64} output formats. + +\b \c{SECTALIGN} directive introduced. See \k{sectalign}. + +\b \c{nojmp} option introduced in \c{smartalign} package. See + \k{pkg_smartalign}. + +\b Short aliases \c{win}, \c{elf} and \c{macho} for output formats are + introduced. Each stands for \c{win32}, \c{elf32} and \c{macho32} + accordingly. + +\b Faster handling of missing directives implemented. + +\b Various small improvements in documentation. + +\b No hang anymore if unable to open malloc.log file. + +\b The environments without vsnprintf function are able to build nasm again. + +\b AMD LWP instructions updated. + +\b Tighten EA checks. We warn a user if there overflow in EA addressing. + +\b Make \c{-Ox} the default optimization level. For the legacy + behavior, specify \c{-O0} explicitly. See \k{opt-O}. + +\b Environment variables read with \c{%!} or tested with \c{%ifenv} + can now contain non-identifier characters if surrounded by quotes. + See \k{getenv}. + +\b Add a new standard macro package \c{%use fp} for floating-point + convenience macros. See \k{pkg_fp}. + + +\S{cl-2.08.02} Version 2.08.02 + +\b Fix crash under certain circumstances when using the \c{%+} operator. + + +\S{cl-2.08.01} Version 2.08.01 + +\b Fix the \c{%use} statement, which was broken in 2.08. + + +\S{cl-2.08} Version 2.08 + +\b A number of enhancements/fixes in macros area. + +\b Support for converting strings to tokens. See \k{deftok}. + +\b Fuzzy operand size logic introduced. + +\b Fix COFF stack overrun on too long export identifiers. + +\b Fix Macho-O alignment bug. + +\b Fix crashes with -fwin32 on file with many exports. + +\b Fix stack overrun for too long [DEBUG id]. + +\b Fix incorrect sbyte usage in IMUL (hit only if optimization + flag passed). + +\b Append ending token for \c{.stabs} records in the ELF output format. + +\b New NSIS script which uses ModernUI and MultiUser approach. + +\b Visual Studio 2008 NASM integration (rules file). + +\b Warn a user if a constant is too long (and as result will be stripped). + +\b The obsoleted pre-XOP AMD SSE5 instruction set which was never actualized + was removed. + +\b Fix stack overrun on too long error file name passed from the command line. + +\b Bind symbols to the .text section by default (ie in case if SECTION + directive was omitted) in the ELF output format. + +\b Fix sync points array index wrapping. + +\b A few fixes for FMA4 and XOP instruction templates. + +\b Add AMD Lightweight Profiling (LWP) instructions. + +\b Fix the offset for \c{%arg} in 64-bit mode. + +\b An undefined local macro (\c{%$}) no longer matches a global macro + with the same name. + +\b Fix NULL dereference on too long local labels. + + +\S{cl-2.07} Version 2.07 + +\b NASM is now under the 2-clause BSD license. See \k{legal}. + +\b Fix the section type for the \c{.strtab} section in the \c{elf64} + output format. + +\b Fix the handling of \c{COMMON} directives in the \c{obj} output format. + +\b New \c{ith} and \c{srec} output formats; these are variants of the + \c{bin} output format which output Intel hex and Motorola S-records, + respectively. See \k{ithfmt} and \k{srecfmt}. + +\b \c{rdf2ihx} replaced with an enhanced \c{rdf2bin}, which can output + binary, COM, Intel hex or Motorola S-records. + +\b The Windows installer now puts the NASM directory first in the + \c{PATH} of the "NASM Shell". + +\b Revert the early expansion behavior of \c{%+} to pre-2.06 behavior: + \c{%+} is only expanded late. + +\b Yet another Mach-O alignment fix. + +\b Don't delete the list file on errors. Also, include error and + warning information in the list file. + +\b Support for 64-bit Mach-O output, see \k{machofmt}. + +\b Fix assert failure on certain operations that involve strings with + high-bit bytes. + + +\S{cl-2.06} Version 2.06 + +\b This release is dedicated to the memory of Charles A. Crayne, long + time NASM developer as well as moderator of \c{comp.lang.asm.x86} and + author of the book \e{Serious Assembler}. We miss you, Chuck. + +\b Support for indirect macro expansion (\c{%[...]}). See \k{indmacro}. + +\b \c{%pop} can now take an argument, see \k{pushpop}. + +\b The argument to \c{%use} is no longer macro-expanded. Use + \c{%[...]} if macro expansion is desired. + +\b Support for thread-local storage in ELF32 and ELF64. See \k{elftls}. + +\b Fix crash on \c{%ifmacro} without an argument. + +\b Correct the arguments to the \c{POPCNT} instruction. + +\b Fix section alignment in the Mach-O format. + +\b Update AVX support to version 5 of the Intel specification. + +\b Fix the handling of accesses to context-local macros from higher + levels in the context stack. + +\b Treat \c{WAIT} as a prefix rather than as an instruction, thereby + allowing constructs like \c{O16 FSAVE} to work correctly. + +\b Support for structures with a non-zero base offset. See \k{struc}. + +\b Correctly handle preprocessor token concatenation (see \k{concat}) + involving floating-point numbers. + +\b The \c{PINSR} series of instructions have been corrected and + rationalized. + +\b Removed AMD SSE5, replaced with the new XOP/FMA4/CVT16 (rev 3.03) + spec. + +\b The ELF backends no longer automatically generate a \c{.comment} section. + +\b Add additional "well-known" ELF sections with default attributes. See + \k{elfsect}. + + +\S{cl-2.05.01} Version 2.05.01 + +\b Fix the \c{-w}/\c{-W} option parsing, which was broken in NASM 2.05. + + +\S{cl-2.05} Version 2.05 + +\b Fix redundant REX.W prefix on \c{JMP reg64}. + +\b Make the behaviour of \c{-O0} match NASM 0.98 legacy behavior. + See \k{opt-O}. + +\b \c{-w-user} can be used to suppress the output of \c{%warning} directives. + See \k{opt-w}. + +\b Fix bug where \c{ALIGN} would issue a full alignment datum instead of + zero bytes. + +\b Fix offsets in list files. + +\b Fix \c{%include} inside multi-line macros or loops. + +\b Fix error where NASM would generate a spurious warning on valid + optimizations of immediate values. + +\b Fix arguments to a number of the \c{CVT} SSE instructions. + +\b Fix RIP-relative offsets when the instruction carries an immediate. + +\b Massive overhaul of the ELF64 backend for spec compliance. + +\b Fix the Geode \c{PFRCPV} and \c{PFRSQRTV} instruction. + +\b Fix the SSE 4.2 \c{CRC32} instruction. + + +\S{cl-2.04} Version 2.04 + +\b Sanitize macro handing in the \c{%error} directive. + +\b New \c{%warning} directive to issue user-controlled warnings. + +\b \c{%error} directives are now deferred to the final assembly phase. + +\b New \c{%fatal} directive to immediately terminate assembly. + +\b New \c{%strcat} directive to join quoted strings together. + +\b New \c{%use} macro directive to support standard macro directives. See + \k{use}. + +\b Excess default parameters to \c{%macro} now issues a warning by default. + See \k{mlmacro}. + +\b Fix \c{%ifn} and \c{%elifn}. + +\b Fix nested \c{%else} clauses. + +\b Correct the handling of nested \c{%rep}s. + +\b New \c{%unmacro} directive to undeclare a multi-line macro. + See \k{unmacro}. + +\b Builtin macro \c{__PASS__} which expands to the current assembly pass. + See \k{pass_macro}. + +\b \c{__utf16__} and \c{__utf32__} operators to generate UTF-16 and UTF-32 + strings. See \k{unicode}. + +\b Fix bug in case-insensitive matching when compiled on platforms that + don't use the \c{configure} script. Of the official release binaries, + that only affected the OS/2 binary. + +\b Support for x87 packed BCD constants. See \k{bcdconst}. + +\b Correct the \c{LTR} and \c{SLDT} instructions in 64-bit mode. + +\b Fix unnecessary REX.W prefix on indirect jumps in 64-bit mode. + +\b Add AVX versions of the AES instructions (\c{VAES}...). + +\b Fix the 256-bit FMA instructions. + +\b Add 256-bit AVX stores per the latest AVX spec. + +\b VIA XCRYPT instructions can now be written either with or without + \c{REP}, apparently different versions of the VIA spec wrote them + differently. + +\b Add missing 64-bit \c{MOVNTI} instruction. + +\b Fix the operand size of \c{VMREAD} and \c{VMWRITE}. + +\b Numerous bug fixes, especially to the AES, AVX and VTX instructions. + +\b The optimizer now always runs until it converges. It also runs even + when disabled, but doesn't optimize. This allows most forward references + to be resolved properly. + +\b \c{%push} no longer needs a context identifier; omitting the context + identifier results in an anonymous context. + + +\S{cl-2.03.01} Version 2.03.01 + +\b Fix buffer overflow in the listing module. + +\b Fix the handling of hexadecimal escape codes in `...` strings. + +\b The Postscript/PDF documentation has been reformatted. + +\b The \c{-F} option now implies \c{-g}. + + +\S{cl-2.03} Version 2.03 + +\b Add support for Intel AVX, CLMUL and FMA instructions, +including YMM registers. + +\b \c{dy}, \c{resy} and \c{yword} for 32-byte operands. + +\b Fix some SSE5 instructions. + +\b Intel \c{INVEPT}, \c{INVVPID} and \c{MOVBE} instructions. + +\b Fix checking for critical expressions when the optimizer is enabled. + +\b Support the DWARF debugging format for ELF targets. + +\b Fix optimizations of signed bytes. + +\b Fix operation on bigendian machines. + +\b Fix buffer overflow in the preprocessor. + +\b \c{SAFESEH} support for Win32, \c{IMAGEREL} for Win64 (SEH). + +\b \c{%?} and \c{%??} to refer to the name of a macro itself. In particular, +\c{%idefine keyword $%?} can be used to make a keyword "disappear". + +\b New options for dependency generation: \c{-MD}, \c{-MF}, +\c{-MP}, \c{-MT}, \c{-MQ}. + +\b New preprocessor directives \c{%pathsearch} and \c{%depend}; INCBIN +reimplemented as a macro. + +\b \c{%include} now resolves macros in a sane manner. + +\b \c{%substr} can now be used to get other than one-character substrings. + +\b New type of character/string constants, using backquotes (\c{`...`}), +which support C-style escape sequences. + +\b \c{%defstr} and \c{%idefstr} to stringize macro definitions before +creation. + +\b Fix forward references used in \c{EQU} statements. + + +\S{cl-2.02} Version 2.02 + +\b Additional fixes for MMX operands with explicit \c{qword}, as well as + (hopefully) SSE operands with \c{oword}. + +\b Fix handling of truncated strings with \c{DO}. + +\b Fix segfaults due to memory overwrites when floating-point constants + were used. + +\b Fix segfaults due to missing include files. + +\b Fix OpenWatcom Makefiles for DOS and OS/2. + +\b Add autogenerated instruction list back into the documentation. + +\b ELF: Fix segfault when generating stabs, and no symbols have been + defined. + +\b ELF: Experimental support for DWARF debugging information. + +\b New compile date and time standard macros. + +\b \c{%ifnum} now returns true for negative numbers. + +\b New \c{%iftoken} test for a single token. + +\b New \c{%ifempty} test for empty expansion. + +\b Add support for the \c{XSAVE} instruction group. + +\b Makefile for Netware/gcc. + +\b Fix issue with some warnings getting emitted way too many times. + +\b Autogenerated instruction list added to the documentation. + + +\S{cl-2.01} Version 2.01 + +\b Fix the handling of MMX registers with explicit \c{qword} tags on + memory (broken in 2.00 due to 64-bit changes.) + +\b Fix the PREFETCH instructions. + +\b Fix the documentation. + +\b Fix debugging info when using \c{-f elf} +(backwards compatibility alias for \c{-f elf32}). + +\b Man pages for rdoff tools (from the Debian project.) + +\b ELF: handle large numbers of sections. + +\b Fix corrupt output when the optimizer runs out of passes. + + +\S{cl-2.00} Version 2.00 + +\b Added c99 data-type compliance. + +\b Added general x86-64 support. + +\b Added win64 (x86-64 COFF) output format. + +\b Added \c{__BITS__} standard macro. + +\b Renamed the \c{elf} output format to \c{elf32} for clarity. + +\b Added \c{elf64} and \c{macho} (MacOS X) output formats. + +\b Added Numeric constants in \c{dq} directive. + +\b Added \c{oword}, \c{do} and \c{reso} pseudo operands. + +\b Allow underscores in numbers. + +\b Added 8-, 16- and 128-bit floating-point formats. + +\b Added binary, octal and hexadecimal floating-point. + +\b Correct the generation of floating-point constants. + +\b Added floating-point option control. + +\b Added Infinity and NaN floating point support. + +\b Added ELF Symbol Visibility support. + +\b Added setting OSABI value in ELF header directive. + +\b Added Generate Makefile Dependencies option. + +\b Added Unlimited Optimization Passes option. + +\b Added \c{%IFN} and \c{%ELIFN} support. + +\b Added Logical Negation Operator. + +\b Enhanced Stack Relative Preprocessor Directives. + +\b Enhanced ELF Debug Formats. + +\b Enhanced Send Errors to a File option. + +\b Added SSSE3, SSE4.1, SSE4.2, SSE5 support. + +\b Added a large number of additional instructions. + +\b Significant performance improvements. + +\b \c{-w+warning} and \c{-w-warning} can now be written as -Wwarning and + -Wno-warning, respectively. See \k{opt-w}. + +\b Add \c{-w+error} to treat warnings as errors. See \k{opt-w}. + +\b Add \c{-w+all} and \c{-w-all} to enable or disable all suppressible + warnings. See \k{opt-w}. + + +\H{cl-0.98.xx} NASM 0.98 Series + +The 0.98 series was the production versions of NASM from 1999 to 2007. + + +\S{cl-0.98.39} Version 0.98.39 + +\b fix buffer overflow + +\b fix outas86's \c{.bss} handling + +\b "make spotless" no longer deletes config.h.in. + +\b \c{%(el)if(n)idn} insensitivity to string quotes difference (#809300). + +\b (nasm.c)\c{__OUTPUT_FORMAT__} changed to string value instead of symbol. + +\S{cl-0.98.38} Version 0.98.38 + + +\b Add Makefile for 16-bit DOS binaries under OpenWatcom, and modify + \c{mkdep.pl} to be able to generate completely pathless dependencies, as + required by OpenWatcom wmake (it supports path searches, but not + explicit paths.) + +\b Fix the \c{STR} instruction. + +\b Fix the ELF output format, which was broken under certain + circumstances due to the addition of stabs support. + +\b Quick-fix Borland format debug-info for \c{-f obj} + +\b Fix for \c{%rep} with no arguments (#560568) + +\b Fix concatenation of preprocessor function call (#794686) + +\b Fix long label causes coredump (#677841) + +\b Use autoheader as well as autoconf to keep configure from generating + ridiculously long command lines. + +\b Make sure that all of the formats which support debugging output + actually will suppress debugging output when \c{-g} not specified. + +\S{cl-0.98.37} Version 0.98.37 + + +\b Paths given in \c{-I} switch searched for \c{incbin}-ed as + well as \c{%include}-ed files. + +\b Added stabs debugging for the ELF output format, patch from + Martin Wawro. + +\b Fix \c{output/outbin.c} to allow origin > 80000000h. + +\b Make \c{-U} switch work. + +\b Fix the use of relative offsets with explicit prefixes, e.g. +\c{a32 loop foo}. + +\b Remove \c{backslash()}. + +\b Fix the \c{SMSW} and \c{SLDT} instructions. + +\b \c{-O2} and \c{-O3} are no longer aliases for \c{-O10} and \c{-O15}. +If you mean the latter, please say so! :) + +\S{cl-0.98.36} Version 0.98.36 + + +\b Update rdoff - librarian/archiver - common rec - docs! + +\b Fix signed/unsigned problems. + +\b Fix \c{JMP FAR label} and \c{CALL FAR label}. + +\b Add new multisection support - map files - fix align bug + +\b Fix sysexit, movhps/movlps reg,reg bugs in insns.dat + +\b \c{Q} or \c{O} suffixes indicate octal + +\b Support Prescott new instructions (PNI). + +\b Cyrix \c{XSTORE} instruction. + + +\S{cl-0.98.35} Version 0.98.35 + +\b Fix build failure on 16-bit DOS (Makefile.bc3 workaround for compiler bug.) + +\b Fix dependencies and compiler warnings. + +\b Add "const" in a number of places. + +\b Add -X option to specify error reporting format (use -Xvc to + integrate with Microsoft Visual Studio.) + +\b Minor changes for code legibility. + +\b Drop use of tmpnam() in rdoff (security fix.) + + +\S{cl-0.98.34} Version 0.98.34 + +\b Correct additional address-size vs. operand-size confusions. + +\b Generate dependencies for all Makefiles automatically. + +\b Add support for unimplemented (but theoretically available) + registers such as tr0 and cr5. Segment registers 6 and 7 are called + segr6 and segr7 for the operations which they can be represented. + +\b Correct some disassembler bugs related to redundant address-size prefixes. + Some work still remains in this area. + +\b Correctly generate an error for things like "SEG eax". + +\b Add the JMPE instruction, enabled by "CPU IA64". + +\b Correct compilation on newer gcc/glibc platforms. + +\b Issue an error on things like "jmp far eax". + + +\S{cl-0.98.33} Version 0.98.33 + +\b New __NASM_PATCHLEVEL__ and __NASM_VERSION_ID__ standard macros to + round out the version-query macros. version.pl now understands + X.YYplWW or X.YY.ZZplWW as a version number, equivalent to + X.YY.ZZ.WW (or X.YY.0.WW, as appropriate). + +\b New keyword "strict" to disable the optimization of specific + operands. + +\b Fix the handing of size overrides with JMP instructions + (instructions such as "jmp dword foo".) + +\b Fix the handling of "ABSOLUTE label", where "label" points into a + relocatable segment. + +\b Fix OBJ output format with lots of externs. + +\b More documentation updates. + +\b Add -Ov option to get verbose information about optimizations. + +\b Undo a braindead change which broke \c{%elif} directives. + +\b Makefile updates. + + +\S{cl-0.98.32} Version 0.98.32 + +\b Fix NASM crashing when \c{%macro} directives were left unterminated. + +\b Lots of documentation updates. + +\b Complete rewrite of the PostScript/PDF documentation generator. + +\b The MS Visual C++ Makefile was updated and corrected. + +\b Recognize .rodata as a standard section name in ELF. + +\b Fix some obsolete Perl4-isms in Perl scripts. + +\b Fix configure.in to work with autoconf 2.5x. + +\b Fix a couple of "make cleaner" misses. + +\b Make the normal "./configure && make" work with Cygwin. + + +\S{cl-0.98.31} Version 0.98.31 + +\b Correctly build in a separate object directory again. + +\b Derive all references to the version number from the version file. + +\b New standard macros __NASM_SUBMINOR__ and __NASM_VER__ macros. + +\b Lots of Makefile updates and bug fixes. + +\b New \c{%ifmacro} directive to test for multiline macros. + +\b Documentation updates. + +\b Fixes for 16-bit OBJ format output. + +\b Changed the NASM environment variable to NASMENV. + + +\S{cl-0.98.30} Version 0.98.30 + +\b Changed doc files a lot: completely removed old READMExx and + Wishlist files, incorporating all information in CHANGES and TODO. + +\b I waited a long time to rename zoutieee.c to (original) outieee.c + +\b moved all output modules to output/ subdirectory. + +\b Added 'make strip' target to strip debug info from nasm & ndisasm. + +\b Added INSTALL file with installation instructions. + +\b Added -v option description to nasm man. + +\b Added dist makefile target to produce source distributions. + +\b 16-bit support for ELF output format (GNU extension, but useful.) + + +\S{cl-0.98.28} Version 0.98.28 + +\b Fastcooked this for Debian's Woody release: +Frank applied the INCBIN bug patch to 0.98.25alt and called +it 0.98.28 to not confuse poor little apt-get. + + +\S{cl-0.98.26} Version 0.98.26 + +\b Reorganised files even better from 0.98.25alt + + +\S{cl-0.98.25alt} Version 0.98.25alt + +\b Prettified the source tree. Moved files to more reasonable places. + +\b Added findleak.pl script to misc/ directory. + +\b Attempted to fix doc. + + +\S{cl-0.98.25} Version 0.98.25 + +\b Line continuation character \c{\\}. + +\b Docs inadvertantly reverted - "dos packaging". + + +\S{cl-0.98.24p1} Version 0.98.24p1 + +\b FIXME: Someone, document this please. + + +\S{cl-0.98.24} Version 0.98.24 + +\b Documentation - Ndisasm doc added to Nasm.doc. + + +\S{cl-0.98.23} Version 0.98.23 + +\b Attempted to remove rdoff version1 + +\b Lino Mastrodomenico's patches to preproc.c (%$$ bug?). + + +\S{cl-0.98.22} Version 0.98.22 + +\b Update rdoff2 - attempt to remove v1. + + +\S{cl-0.98.21} Version 0.98.21 + +\b Optimization fixes. + + +\S{cl-0.98.20} Version 0.98.20 + +\b Optimization fixes. + + +\S{cl-0.98.19} Version 0.98.19 + +\b H. J. Lu's patch back out. + + +\S{cl-0.98.18} Version 0.98.18 + +\b Added ".rdata" to "-f win32". + + +\S{cl-0.98.17} Version 0.98.17 + +\b H. J. Lu's "bogus elf" patch. (Red Hat problem?) + + +\S{cl-0.98.16} Version 0.98.16 + +\b Fix whitespace before "[section ..." bug. + + +\S{cl-0.98.15} Version 0.98.15 + +\b Rdoff changes (?). + +\b Fix fixes to memory leaks. + + +\S{cl-0.98.14} Version 0.98.14 + +\b Fix memory leaks. + + +\S{cl-0.98.13} Version 0.98.13 + +\b There was no 0.98.13 + + +\S{cl-0.98.12} Version 0.98.12 + +\b Update optimization (new function of "-O1") + +\b Changes to test/bintest.asm (?). + + +\S{cl-0.98.11} Version 0.98.11 + +\b Optimization changes. + +\b Ndisasm fixed. + + +\S{cl-0.98.10} Version 0.98.10 + +\b There was no 0.98.10 + + +\S{cl-0.98.09} Version 0.98.09 + +\b Add multiple sections support to "-f bin". + +\b Changed GLOBAL_TEMP_BASE in outelf.c from 6 to 15. + +\b Add "-v" as an alias to the "-r" switch. + +\b Remove "#ifdef" from Tasm compatibility options. + +\b Remove redundant size-overrides on "mov ds, ex", etc. + +\b Fixes to SSE2, other insns.dat (?). + +\b Enable uppercase "I" and "P" switches. + +\b Case insinsitive "seg" and "wrt". + +\b Update install.sh (?). + +\b Allocate tokens in blocks. + +\b Improve "invalid effective address" messages. + + +\S{cl-0.98.08} Version 0.98.08 + +\b Add "\c{%strlen}" and "\c{%substr}" macro operators + +\b Fixed broken c16.mac. + +\b Unterminated string error reported. + +\b Fixed bugs as per 0.98bf + + +\S{cl-0.98.09b with John Coffman patches released 28-Oct-2001} Version 0.98.09b with John Coffman patches released 28-Oct-2001 + +Changes from 0.98.07 release to 98.09b as of 28-Oct-2001 + +\b More closely compatible with 0.98 when -O0 is implied +or specified. Not strictly identical, since backward +branches in range of short offsets are recognized, and signed +byte values with no explicit size specification will be +assembled as a single byte. + +\b More forgiving with the PUSH instruction. 0.98 requires +a size to be specified always. 0.98.09b will imply the size +from the current BITS setting (16 or 32). + +\b Changed definition of the optimization flag: + +\c -O0 strict two-pass assembly, JMP and Jcc are +\c handled more like 0.98, except that back- +\c ward JMPs are short, if possible. +\c +\c -O1 strict two-pass assembly, but forward +\c branches are assembled with code guaranteed +\c to reach; may produce larger code than +\c -O0, but will produce successful assembly +\c more often if branch offset sizes are not +\c specified. +\c +\c -O2 multi-pass optimization, minimize branch +\c offsets; also will minimize signed immed- +\c iate bytes, overriding size specification. +\c +\c -O3 like -O2, but more passes taken, if needed + + +\S{cl-0.98.07 released 01/28/01} Version 0.98.07 released 01/28/01 + +\b Added Stepane Denis' SSE2 instructions to a *working* + version of the code - some earlier versions were based on + broken code - sorry 'bout that. version "0.98.07" + +\b Cosmetic modifications to nasm.c, nasm.h, + AUTHORS, MODIFIED + + +\S{cl-0.98.06f released 01/18/01} Version 0.98.06f released 01/18/01 + + +\b Add "metalbrain"s jecxz bug fix in insns.dat + +\b Alter nasmdoc.src to match - version "0.98.06f" + + +\S{cl-0.98.06e released 01/09/01} Version 0.98.06e released 01/09/01 + + +\b Removed the "outforms.h" file - it appears to be + someone's old backup of "outform.h". version "0.98.06e" + +\b fbk - finally added the fix for the "multiple %includes bug", + known since 7/27/99 - reported originally (?) and sent to + us by Austin Lunnen - he reports that John Fine had a fix + within the day. Here it is... + +\b Nelson Rush resigns from the group. Big thanks to Nelson for + his leadership and enthusiasm in getting these changes + incorporated into Nasm! + +\b fbk - [list +], [list -] directives - ineptly implemented, should + be re-written or removed, perhaps. + +\b Brian Raiter / fbk - "elfso bug" fix - applied to aoutb format + as well - testing might be desirable... + +\b James Seter - -postfix, -prefix command line switches. + +\b Yuri Zaporozhets - rdoff utility changes. + + +\S{cl-0.98p1} Version 0.98p1 + +\b GAS-like palign (Panos Minos) + +\b FIXME: Someone, fill this in with details + + +\S{cl-0.98bf (bug-fixed)} Version 0.98bf (bug-fixed) + +\b Fixed - elf and aoutb bug - shared libraries + - multiple "%include" bug in "-f obj" + - jcxz, jecxz bug + - unrecognized option bug in ndisasm + +\S{cl-0.98.03 with John Coffman's changes released 27-Jul-2000} Version 0.98.03 with John Coffman's changes released 27-Jul-2000 + +\b Added signed byte optimizations for the 0x81/0x83 class +of instructions: ADC, ADD, AND, CMP, OR, SBB, SUB, XOR: +when used as 'ADD reg16,imm' or 'ADD reg32,imm.' Also +optimization of signed byte form of 'PUSH imm' and 'IMUL +reg,imm'/'IMUL reg,reg,imm.' No size specification is needed. + +\b Added multi-pass JMP and Jcc offset optimization. Offsets +on forward references will preferentially use the short form, +without the need to code a specific size (short or near) for +the branch. Added instructions for 'Jcc label' to use the +form 'Jnotcc $+3/JMP label', in cases where a short offset +is out of bounds. If compiling for a 386 or higher CPU, then +the 386 form of Jcc will be used instead. + +\> This feature is controlled by a new command-line switch: "O", +(upper case letter O). "-O0" reverts the assembler to no +extra optimization passes, "-O1" allows up to 5 extra passes, +and "-O2"(default), allows up to 10 extra optimization passes. + +\b Added a new directive: 'cpu XXX', where XXX is any of: +8086, 186, 286, 386, 486, 586, pentium, 686, PPro, P2, P3 or +Katmai. All are case insensitive. All instructions will +be selected only if they apply to the selected cpu or lower. +Corrected a couple of bugs in cpu-dependence in 'insns.dat'. + +\b Added to 'standard.mac', the "use16" and "use32" forms of +the "bits 16/32" directive. This is nothing new, just conforms +to a lot of other assemblers. (minor) + +\b Changed label allocation from 320/32 (10000 labels @ 200K+) +to 32/37 (1000 labels); makes running under DOS much easier. +Since additional label space is allocated dynamically, this +should have no effect on large programs with lots of labels. +The 37 is a prime, believed to be better for hashing. (minor) + + +\S{cl-0.98.03} Version 0.98.03 + +"Integrated patchfile 0.98-0.98.01. I call this version 0.98.03 for +historical reasons: 0.98.02 was trashed." --John Coffman +, 27-Jul-2000 + +\b Kendall Bennett's SciTech MGL changes + +\b Note that you must define "TASM_COMPAT" at compile-time +to get the Tasm Ideal Mode compatibility. + +\b All changes can be compiled in and out using the TASM_COMPAT macros, +and when compiled without TASM_COMPAT defined we get the exact same +binary as the unmodified 0.98 sources. + +\b standard.mac, macros.c: Added macros to ignore TASM directives before +first include + +\b nasm.h: Added extern declaration for tasm_compatible_mode + +\b nasm.c: Added global variable tasm_compatible_mode + +\b Added command line switch for TASM compatible mode (-t) + +\b Changed version command line to reflect when compiled with TASM additions + +\b Added response file processing to allow all arguments on a single +line (response file is @resp rather than -@resp for NASM format). + +\b labels.c: Changes islocal() macro to support TASM style @@local labels. + +\b Added islocalchar() macro to support TASM style @@local labels. + +\b parser.c: Added support for TASM style memory references (ie: mov +[DWORD eax],10 rather than the NASM style mov DWORD [eax],10). + +\b preproc.c: Added new directives, \c{%arg}, \c{%local}, \c{%stacksize} to directives +table + +\b Added support for TASM style directives without a leading % symbol. + +\b Integrated a block of changes from Andrew Zabolotny : + +\b A new keyword \c{%xdefine} and its case-insensitive counterpart \c{%ixdefine}. +They work almost the same way as \c{%define} and \c{%idefine} but expand +the definition immediately, not on the invocation. Something like a cross +between \c{%define} and \c{%assign}. The "x" suffix stands for "eXpand", so +"xdefine" can be deciphered as "expand-and-define". Thus you can do +things like this: + +\c %assign ofs 0 +\c +\c %macro arg 1 +\c %xdefine %1 dword [esp+ofs] +\c %assign ofs ofs+4 +\c %endmacro + +\b Changed the place where the expansion of %$name macros are expanded. +Now they are converted into ..@ctxnum.name form when detokenizing, so +there are no quirks as before when using %$name arguments to macros, +in macros etc. For example: + +\c %macro abc 1 +\c %define %1 hello +\c %endm +\c +\c abc %$here +\c %$here + +\> Now last line will be expanded into "hello" as expected. This also allows + for lots of goodies, a good example are extended "proc" macros included + in this archive. + +\b Added a check for "cstk" in smacro_defined() before calling get_ctx() - + this allows for things like: + +\c %ifdef %$abc +\c %endif + +\> to work without warnings even in no context. + +\b Added a check for "cstk" in %if*ctx and %elif*ctx directives - + this allows to use \c{%ifctx} without excessive warnings. If there is + no active context, \c{%ifctx} goes through "false" branch. + +\b Removed "user error: " prefix with \c{%error} directive: it just clobbers the + output and has absolutely no functionality. Besides, this allows to write + macros that does not differ from built-in functions in any way. + +\b Added expansion of string that is output by \c{%error} directive. Now you + can do things like: + +\c %define hello(x) Hello, x! +\c +\c %define %$name andy +\c %error "hello(%$name)" + +\> Same happened with \c{%include} directive. + +\b Now all directives that expect an identifier will try to expand and + concatenate everything without whitespaces in between before usage. + For example, with "unfixed" nasm the commands + +\c %define %$abc hello +\c %define __%$abc goodbye +\c __%$abc + +\> would produce "incorrect" output: last line will expand to + +\c hello goodbyehello + +\> Not quite what you expected, eh? :-) The answer is that preprocessor + treats the \c{%define} construct as if it would be + +\c %define __ %$abc goodbye + +\> (note the white space between __ and %$abc). After my "fix" it + will "correctly" expand into + +\c goodbye + +\> as expected. Note that I use quotes around words "correct", "incorrect" + etc because this is rather a feature not a bug; however current behaviour + is more logical (and allows more advanced macro usage :-). + + Same change was applied to: + \c{%push},\c{%macro},\c{%imacro},\c{%define},\c{%idefine},\c{%xdefine},\c{%ixdefine}, + \c{%assign},\c{%iassign},\c{%undef} + +\b A new directive [WARNING {+|-}warning-id] have been added. It works only + if the assembly phase is enabled (i.e. it doesn't work with nasm -e). + +\b A new warning type: macro-selfref. By default this warning is disabled; + when enabled NASM warns when a macro self-references itself; for example + the following source: + +\c [WARNING macro-selfref] +\c +\c %macro push 1-* +\c %rep %0 +\c push %1 +\c %rotate 1 +\c %endrep +\c %endmacro +\c +\c push eax,ebx,ecx + +\> will produce a warning, but if we remove the first line we won't see it + anymore (which is The Right Thing To Do {tm} IMHO since C preprocessor + eats such constructs without warnings at all). + +\b Added a "error" routine to preprocessor which always will set ERR_PASS1 + bit in severity_code. This removes annoying repeated errors on first + and second passes from preprocessor. + +\b Added the %+ operator in single-line macros for concatenating two + identifiers. Usage example: + +\c %define _myfunc _otherfunc +\c %define cextern(x) _ %+ x +\c cextern (myfunc) + +\> After first expansion, third line will become "_myfunc". After this + expansion is performed again so it becomes "_otherunc". + +\b Now if preprocessor is in a non-emitting state, no warning or error + will be emitted. Example: + +\c %if 1 +\c mov eax,ebx +\c %else +\c put anything you want between these two brackets, +\c even macro-parameter references %1 or local +\c labels %$zz or macro-local labels %%zz - no +\c warning will be emitted. +\c %endif + +\b Context-local variables on expansion as a last resort are looked up + in outer contexts. For example, the following piece: + +\c %push outer +\c %define %$a [esp] +\c +\c %push inner +\c %$a +\c %pop +\c %pop + +\> will expand correctly the fourth line to [esp]; if we'll define another + %$a inside the "inner" context, it will take precedence over outer + definition. However, this modification has been applied only to + expand_smacro and not to smacro_define: as a consequence expansion + looks in outer contexts, but \c{%ifdef} won't look in outer contexts. + +\> This behaviour is needed because we don't want nested contexts to + act on already defined local macros. Example: + +\c %define %$arg1 [esp+4] +\c test eax,eax +\c if nz +\c mov eax,%$arg1 +\c endif + +\> In this example the "if" mmacro enters into the "if" context, so %$arg1 + is not valid anymore inside "if". Of course it could be worked around + by using explicitely %$$arg1 but this is ugly IMHO. + +\b Fixed memory leak in \c{%undef}. The origline wasn't freed before + exiting on success. + +\b Fixed trap in preprocessor when line expanded to empty set of tokens. + This happens, for example, in the following case: + +\c #define SOMETHING +\c SOMETHING + + +\S{cl-0.98} Version 0.98 + +All changes since NASM 0.98p3 have been produced by H. Peter Anvin . + +\b The documentation comment delimiter is \# not #. + +\b Allow EQU definitions to refer to external labels; reported by + Pedro Gimeno. + +\b Re-enable support for RDOFF v1; reported by Pedro Gimeno. + +\b Updated License file per OK from Simon and Julian. + + +\S{cl-0.98p9} Version 0.98p9 + +\b Update documentation (although the instruction set reference will + have to wait; I don't want to hold up the 0.98 release for it.) + +\b Verified that the NASM implementation of the PEXTRW and PMOVMSKB + instructions is correct. The encoding differs from what the Intel + manuals document, but the Pentium III behaviour matches NASM, not + the Intel manuals. + +\b Fix handling of implicit sizes in PSHUFW and PINSRW, reported by + Stefan Hoffmeister. + +\b Resurrect the -s option, which was removed when changing the + diagnostic output to stdout. + + +\S{cl-0.98p8} Version 0.98p8 + +\b Fix for "DB" when NASM is running on a bigendian machine. + +\b Invoke insns.pl once for each output script, making Makefile.in + legal for "make -j". + +\b Improve the Unix configure-based makefiles to make package + creation easier. + +\b Included an RPM .spec file for building RPM (RedHat Package Manager) + packages on Linux or Unix systems. + +\b Fix Makefile dependency problems. + +\b Change src/rdsrc.pl to include sectioning information in info + output; required for install-info to work. + +\b Updated the RDOFF distribution to version 2 from Jules; minor + massaging to make it compile in my environment. + +\b Split doc files that can be built by anyone with a Perl interpreter off + into a separate archive. + +\b "Dress rehearsal" release! + + +\S{cl-0.98p7} Version 0.98p7 + +\b Fixed opcodes with a third byte-sized immediate argument to not + complain if given "byte" on the immediate. + +\b Allow \c{%undef} to remove single-line macros with arguments. This + matches the behaviour of #undef in the C preprocessor. + +\b Allow -d, -u, -i and -p to be specified as -D, -U, -I and -P for + compatibility with most C compilers and preprocessors. This allows + Makefile options to be shared between cc and nasm, for example. + +\b Minor cleanups. + +\b Went through the list of Katmai instructions and hopefully fixed the + (rather few) mistakes in it. + +\b (Hopefully) fixed a number of disassembler bugs related to ambiguous + instructions (disambiguated by -p) and SSE instructions with REP. + +\b Fix for bug reported by Mark Junger: "call dword 0x12345678" should + work and may add an OSP (affected CALL, JMP, Jcc). + +\b Fix for environments when "stderr" isn't a compile-time constant. + + +\S{cl-0.98p6} Version 0.98p6 + + +\b Took officially over coordination of the 0.98 release; so drop + the p3.x notation. Skipped p4 and p5 to avoid confusion with John + Fine's J4 and J5 releases. + +\b Update the documentation; however, it still doesn't include + documentation for the various new instructions. I somehow wonder if + it makes sense to have an instruction set reference in the assembler + manual when Intel et al have PDF versions of their manuals online. + +\b Recognize "idt" or "centaur" for the -p option to ndisasm. + +\b Changed error messages back to stderr where they belong, but add an + -E option to redirect them elsewhere (the DOS shell cannot redirect + stderr.) + +\b -M option to generate Makefile dependencies (based on code from Alex + Verstak.) + +\b \c{%undef} preprocessor directive, and -u option, that undefines a + single-line macro. + +\b OS/2 Makefile (Mkfiles/Makefile.os2) for Borland under OS/2; from + Chuck Crayne. + +\b Various minor bugfixes (reported by): + - Dangling \c{%s} in preproc.c (Martin Junker) + +\b THERE ARE KNOWN BUGS IN SSE AND THE OTHER KATMAI INSTRUCTIONS. I am + on a trip and didn't bring the Katmai instruction reference, so I + can't work on them right now. + +\b Updated the License file per agreement with Simon and Jules to + include a GPL distribution clause. + + +\S{cl-0.98p3.7} Version 0.98p3.7 + +\b (Hopefully) fixed the canned Makefiles to include the outrdf2 and + zoutieee modules. + +\b Renamed changes.asm to changed.asm. + + +\S{cl-0.98p3.6} Version 0.98p3.6 + +\b Fixed a bunch of instructions that were added in 0.98p3.5 which had + memory operands, and the address-size prefix was missing from the + instruction pattern. + + +\S{cl-0.98p3.5} Version 0.98p3.5 + +\b Merged in changes from John S. Fine's 0.98-J5 release. John's based + 0.98-J5 on my 0.98p3.3 release; this merges the changes. + +\b Expanded the instructions flag field to a long so we can fit more + flags; mark SSE (KNI) and AMD or Katmai-specific instructions as + such. + +\b Fix the "PRIV" flag on a bunch of instructions, and create new + "PROT" flag for protected-mode-only instructions (orthogonal to if + the instruction is privileged!) and new "SMM" flag for SMM-only + instructions. + +\b Added AMD-only SYSCALL and SYSRET instructions. + +\b Make SSE actually work, and add new Katmai MMX instructions. + +\b Added a -p (preferred vendor) option to ndisasm so that it can + distinguish e.g. Cyrix opcodes also used in SSE. For example: + +\c ndisasm -p cyrix aliased.bin +\c 00000000 670F514310 paddsiw mm0,[ebx+0x10] +\c 00000005 670F514320 paddsiw mm0,[ebx+0x20] +\c ndisasm -p intel aliased.bin +\c 00000000 670F514310 sqrtps xmm0,[ebx+0x10] +\c 00000005 670F514320 sqrtps xmm0,[ebx+0x20] + +\b Added a bunch of Cyrix-specific instructions. + + +\S{cl-0.98p3.4} Version 0.98p3.4 + +\b Made at least an attempt to modify all the additional Makefiles (in + the Mkfiles directory). I can't test it, but this was the best I + could do. + +\b DOS DJGPP+"Opus Make" Makefile from John S. Fine. + +\b changes.asm changes from John S. Fine. + + +\S{cl-0.98p3.3} Version 0.98p3.3 + +\b Patch from Conan Brink to allow nesting of \c{%rep} directives. + +\b If we're going to allow INT01 as an alias for INT1/ICEBP (one of + Jules 0.98p3 changes), then we should allow INT03 as an alias for INT3 + as well. + +\b Updated changes.asm to include the latest changes. + +\b Tried to clean up the s that had snuck in from a DOS/Windows + environment into my Unix environment, and try to make sure than + DOS/Windows users get them back. + +\b We would silently generate broken tools if insns.dat wasn't sorted + properly. Change insns.pl so that the order doesn't matter. + +\b Fix bug in insns.pl (introduced by me) which would cause conditional + instructions to have an extra "cc" in disassembly, e.g. "jnz" + disassembled as "jccnz". + + +\S{cl-0.98p3.2} Version 0.98p3.2 + +\b Merged in John S. Fine's changes from his 0.98-J4 prerelease; see + http://www.csoft.net/cz/johnfine/ + +\b Changed previous "spotless" Makefile target (appropriate for distribution) + to "distclean", and added "cleaner" target which is same as "clean" + except deletes files generated by Perl scripts; "spotless" is union. + +\b Removed BASIC programs from distribution. Get a Perl interpreter + instead (see below.) + +\b Calling this "pre-release 3.2" rather than "p3-hpa2" because of + John's contributions. + +\b Actually link in the IEEE output format (zoutieee.c); fix a bunch of + compiler warnings in that file. Note I don't know what IEEE output + is supposed to look like, so these changes were made "blind". + + +\S{cl-0.98p3-hpa} Version 0.98p3-hpa + +\b Merged nasm098p3.zip with nasm-0.97.tar.gz to create a fully + buildable version for Unix systems (Makefile.in updates, etc.) + +\b Changed insns.pl to create the instruction tables in nasm.h and + names.c, so that a new instruction can be added by adding it *only* + to insns.dat. + +\b Added the following new instructions: SYSENTER, SYSEXIT, FXSAVE, + FXRSTOR, UD1, UD2 (the latter two are two opcodes that Intel + guarantee will never be used; one of them is documented as UD2 in + Intel documentation, the other one just as "Undefined Opcode" -- + calling it UD1 seemed to make sense.) + +\b MAX_SYMBOL was defined to be 9, but LOADALL286 and LOADALL386 are 10 + characters long. Now MAX_SYMBOL is derived from insns.dat. + +\b A note on the BASIC programs included: forget them. insns.bas is + already out of date. Get yourself a Perl interpreter for your + platform of choice at + \W{http://www.cpan.org/ports/index.html}{http://www.cpan.org/ports/index.html}. + + +\S{cl-0.98p3} Version 0.98 pre-release 3 + +\b added response file support, improved command line handling, new layout +help screen + +\b fixed limit checking bug, 'OUT byte nn, reg' bug, and a couple of rdoff +related bugs, updated Wishlist; 0.98 Prerelease 3. + + +\S{cl-0.98p2} Version 0.98 pre-release 2 + +\b fixed bug in outcoff.c to do with truncating section names longer +than 8 characters, referencing beyond end of string; 0.98 pre-release 2 + + +\S{cl-0.98p1} Version 0.98 pre-release 1 + +\b Fixed a bug whereby STRUC didn't work at all in RDF. + +\b Fixed a problem with group specification in PUBDEFs in OBJ. + +\b Improved ease of adding new output formats. Contribution due to +Fox Cutter. + +\b Fixed a bug in relocations in the `bin' format: was showing up when +a relocatable reference crossed an 8192-byte boundary in any output +section. + +\b Fixed a bug in local labels: local-label lookups were inconsistent +between passes one and two if an EQU occurred between the definition +of a global label and the subsequent use of a local label local to +that global. + +\b Fixed a seg-fault in the preprocessor (again) which happened when +you use a blank line as the first line of a multi-line macro +definition and then defined a label on the same line as a call to +that macro. + +\b Fixed a stale-pointer bug in the handling of the NASM environment +variable. Thanks to Thomas McWilliams. + +\b ELF had a hard limit on the number of sections which caused +segfaults when transgressed. Fixed. + +\b Added ability for ndisasm to read from stdin by using `-' as the +filename. + +\b ndisasm wasn't outputting the TO keyword. Fixed. + +\b Fixed error cascade on bogus expression in \c{%if} - an error in +evaluation was causing the entire \c{%if} to be discarded, thus creating +trouble later when the \c{%else} or \c{%endif} was encountered. + +\b Forward reference tracking was instruction-granular not operand- +granular, which was causing 286-specific code to be generated +needlessly on code of the form `shr word [forwardref],1'. Thanks to +Jim Hague for sending a patch. + +\b All messages now appear on stdout, as sending them to stderr serves +no useful purpose other than to make redirection difficult. + +\b Fixed the problem with EQUs pointing to an external symbol - this +now generates an error message. + +\b Allowed multiple size prefixes to an operand, of which only the first +is taken into account. + +\b Incorporated John Fine's changes, including fixes of a large number +of preprocessor bugs, some small problems in OBJ, and a reworking of +label handling to define labels before their line is assembled, rather +than after. + +\b Reformatted a lot of the source code to be more readable. Included +'coding.txt' as a guideline for how to format code for contributors. + +\b Stopped nested \c{%reps} causing a panic - they now cause a slightly more +friendly error message instead. + +\b Fixed floating point constant problems (patch by Pedro Gimeno) + +\b Fixed the return value of insn_size() not being checked for -1, indicating +an error. + +\b Incorporated 3Dnow! instructions. + +\b Fixed the 'mov eax, eax + ebx' bug. + +\b Fixed the GLOBAL EQU bug in ELF. Released developers release 3. + +\b Incorporated John Fine's command line parsing changes + +\b Incorporated David Lindauer's OMF debug support + +\b Made changes for LCC 4.0 support (\c{__NASM_CDecl__}, removed register size +specification warning when sizes agree). + + +\H{cl-0.9x} NASM 0.9 Series + +Revisions before 0.98. + + +\S{cl-0.97} Version 0.97 released December 1997 + +\b This was entirely a bug-fix release to 0.96, which seems to have got +cursed. Silly me. + +\b Fixed stupid mistake in OBJ which caused `MOV EAX,' to +fail. Caused by an error in the `MOV EAX,' support. + +\b ndisasm hung at EOF when compiled with lcc on Linux because lcc on +Linux somehow breaks feof(). ndisasm now does not rely on feof(). + +\b A heading in the documentation was missing due to a markup error in +the indexing. Fixed. + +\b Fixed failure to update all pointers on realloc() within extended- +operand code in parser.c. Was causing wrong behaviour and seg faults +on lines such as `dd 0.0,0.0,0.0,0.0,...' + +\b Fixed a subtle preprocessor bug whereby invoking one multi-line +macro on the first line of the expansion of another, when the second +had been invoked with a label defined before it, didn't expand the +inner macro. + +\b Added internal.doc back in to the distribution archives - it was +missing in 0.96 *blush* + +\b Fixed bug causing 0.96 to be unable to assemble its own test files, +specifically objtest.asm. *blush again* + +\b Fixed seg-faults and bogus error messages caused by mismatching +\c{%rep} and \c{%endrep} within multi-line macro definitions. + +\b Fixed a problem with buffer overrun in OBJ, which was causing +corruption at ends of long PUBDEF records. + +\b Separated DOS archives into main-program and documentation to reduce +download size. + + +\S{cl-0.96} Version 0.96 released November 1997 + +\b Fixed a bug whereby, if `nasm sourcefile' would cause a filename +collision warning and put output into `nasm.out', then `nasm +sourcefile -o outputfile' still gave the warning even though the +`-o' was honoured. +Fixed name pollution under Digital UNIX: one of its header files +defined R_SP, which broke the enum in nasm.h. + +\b Fixed minor instruction table problems: FUCOM and FUCOMP didn't have +two-operand forms; NDISASM didn't recognise the longer register +forms of PUSH and POP (eg FF F3 for PUSH BX); TEST mem,imm32 was +flagged as undocumented; the 32-bit forms of CMOV had 16-bit operand +size prefixes; `AAD imm' and `AAM imm' are no longer flagged as +undocumented because the Intel Architecture reference documents +them. + +\b Fixed a problem with the local-label mechanism, whereby strange +types of symbol (EQUs, auto-defined OBJ segment base symbols) +interfered with the `previous global label' value and screwed up +local labels. + +\b Fixed a bug whereby the stub preprocessor didn't communicate with +the listing file generator, so that the -a and -l options in +conjunction would produce a useless listing file. + +\b Merged `os2' object file format back into `obj', after discovering +that `obj' _also_ shouldn't have a link pass separator in a module +containing a non-trivial MODEND. Flat segments are now declared +using the FLAT attribute. `os2' is no longer a valid object format +name: use `obj'. + +\b Removed the fixed-size temporary storage in the evaluator. Very very +long expressions (like `mov ax,1+1+1+1+...' for two hundred 1s or +so) should now no longer crash NASM. + +\b Fixed a bug involving segfaults on disassembly of MMX instructions, +by changing the meaning of one of the operand-type flags in nasm.h. +This may cause other apparently unrelated MMX problems; it needs to +be tested thoroughly. + +\b Fixed some buffer overrun problems with large OBJ output files. +Thanks to DJ Delorie for the bug report and fix. + +\b Made preprocess-only mode actually listen to the \c{%line} markers as it +prints them, so that it can report errors more sanely. + +\b Re-designed the evaluator to keep more sensible track of expressions +involving forward references: can now cope with previously-nightmare +situations such as: + +\c mov ax,foo | bar +\c foo equ 1 +\c bar equ 2 + +\b Added the ALIGN and ALIGNB standard macros. + +\b Added PIC support in ELF: use of WRT to obtain the four extra +relocation types needed. + +\b Added the ability for output file formats to define their own +extensions to the GLOBAL, COMMON and EXTERN directives. + +\b Implemented common-variable alignment, and global-symbol type and +size declarations, in ELF. + +\b Implemented NEAR and FAR keywords for common variables, plus +far-common element size specification, in OBJ. + +\b Added a feature whereby EXTERNs and COMMONs in OBJ can be given a +default WRT specification (either a segment or a group). + +\b Transformed the Unix NASM archive into an auto-configuring package. + +\b Added a sanity-check for people applying SEG to things which are +already segment bases: this previously went unnoticed by the SEG +processing and caused OBJ-driver panics later. + +\b Added the ability, in OBJ format, to deal with `MOV EAX,' +type references: OBJ doesn't directly support dword-size segment +base fixups, but as long as the low two bytes of the constant term +are zero, a word-size fixup can be generated instead and it will +work. + +\b Added the ability to specify sections' alignment requirements in +Win32 object files and pure binary files. + +\b Added preprocess-time expression evaluation: the \c{%assign} (and +\c{%iassign}) directive and the bare \c{%if} (and \c{%elif}) conditional. Added +relational operators to the evaluator, for use only in \c{%if} +constructs: the standard relationals = < > <= >= <> (and C-like +synonyms == and !=) plus low-precedence logical operators &&, ^^ and +||. + +\b Added a preprocessor repeat construct: \c{%rep} / \c{%exitrep} / \c{%endrep}. + +\b Added the __FILE__ and __LINE__ standard macros. + +\b Added a sanity check for number constants being greater than +0xFFFFFFFF. The warning can be disabled. + +\b Added the %0 token whereby a variadic multi-line macro can tell how +many parameters it's been given in a specific invocation. + +\b Added \c{%rotate}, allowing multi-line macro parameters to be cycled. + +\b Added the `*' option for the maximum parameter count on multi-line +macros, allowing them to take arbitrarily many parameters. + +\b Added the ability for the user-level forms of EXTERN, GLOBAL and +COMMON to take more than one argument. + +\b Added the IMPORT and EXPORT directives in OBJ format, to deal with +Windows DLLs. + +\b Added some more preprocessor \c{%if} constructs: \c{%ifidn} / \c{%ifidni} (exact +textual identity), and \c{%ifid} / \c{%ifnum} / \c{%ifstr} (token type testing). + +\b Added the ability to distinguish SHL AX,1 (the 8086 version) from +SHL AX,BYTE 1 (the 286-and-upwards version whose constant happens to +be 1). + +\b Added NetBSD/FreeBSD/OpenBSD's variant of a.out format, complete +with PIC shared library features. + +\b Changed NASM's idiosyncratic handling of FCLEX, FDISI, FENI, FINIT, +FSAVE, FSTCW, FSTENV, and FSTSW to bring it into line with the +otherwise accepted standard. The previous behaviour, though it was a +deliberate feature, was a deliberate feature based on a +misunderstanding. Apologies for the inconvenience. + +\b Improved the flexibility of ABSOLUTE: you can now give it an +expression rather than being restricted to a constant, and it can +take relocatable arguments as well. + +\b Added the ability for a variable to be declared as EXTERN multiple +times, and the subsequent definitions are just ignored. + +\b We now allow instruction prefixes (CS, DS, LOCK, REPZ etc) to be +alone on a line (without a following instruction). + +\b Improved sanity checks on whether the arguments to EXTERN, GLOBAL +and COMMON are valid identifiers. + +\b Added misc/exebin.mac to allow direct generation of .EXE files by +hacking up an EXE header using DB and DW; also added test/binexe.asm +to demonstrate the use of this. Thanks to Yann Guidon for +contributing the EXE header code. + +\b ndisasm forgot to check whether the input file had been successfully +opened. Now it does. Doh! + +\b Added the Cyrix extensions to the MMX instruction set. + +\b Added a hinting mechanism to allow [EAX+EBX] and [EBX+EAX] to be +assembled differently. This is important since [ESI+EBP] and +[EBP+ESI] have different default base segment registers. + +\b Added support for the PharLap OMF extension for 4096-byte segment +alignment. + + +\S{cl-0.95 released July 1997} Version 0.95 released July 1997 + +\b Fixed yet another ELF bug. This one manifested if the user relied on +the default segment, and attempted to define global symbols without +first explicitly declaring the target segment. + +\b Added makefiles (for NASM and the RDF tools) to build Win32 console +apps under Symantec C++. Donated by Mark Junker. + +\b Added `macros.bas' and `insns.bas', QBasic versions of the Perl +scripts that convert `standard.mac' to `macros.c' and convert +`insns.dat' to `insnsa.c' and `insnsd.c'. Also thanks to Mark +Junker. + +\b Changed the diassembled forms of the conditional instructions so +that JB is now emitted as JC, and other similar changes. Suggested +list by Ulrich Doewich. + +\b Added `@' to the list of valid characters to begin an identifier +with. + +\b Documentary changes, notably the addition of the `Common Problems' +section in nasm.doc. + +\b Fixed a bug relating to 32-bit PC-relative fixups in OBJ. + +\b Fixed a bug in perm_copy() in labels.c which was causing exceptions +in cleanup_labels() on some systems. + +\b Positivity sanity check in TIMES argument changed from a warning to +an error following a further complaint. + +\b Changed the acceptable limits on byte and word operands to allow +things like `~10111001b' to work. + +\b Fixed a major problem in the preprocessor which caused seg-faults if +macro definitions contained blank lines or comment-only lines. + +\b Fixed inadequate error checking on the commas separating the +arguments to `db', `dw' etc. + +\b Fixed a crippling bug in the handling of macros with operand counts +defined with a `+' modifier. + +\b Fixed a bug whereby object file formats which stored the input file +name in the output file (such as OBJ and COFF) weren't doing so +correctly when the output file name was specified on the command +line. + +\b Removed [INC] and [INCLUDE] support for good, since they were +obsolete anyway. + +\b Fixed a bug in OBJ which caused all fixups to be output in 16-bit +(old-format) FIXUPP records, rather than putting the 32-bit ones in +FIXUPP32 (new-format) records. + +\b Added, tentatively, OS/2 object file support (as a minor variant on +OBJ). + +\b Updates to Fox Cutter's Borland C makefile, Makefile.bc2. + +\b Removed a spurious second fclose() on the output file. + +\b Added the `-s' command line option to redirect all messages which +would go to stderr (errors, help text) to stdout instead. + +\b Added the `-w' command line option to selectively suppress some +classes of assembly warning messages. + +\b Added the `-p' pre-include and `-d' pre-define command-line options. + +\b Added an include file search path: the `-i' command line option. + +\b Fixed a silly little preprocessor bug whereby starting a line with a +`%!' environment-variable reference caused an `unknown directive' +error. + +\b Added the long-awaited listing file support: the `-l' command line +option. + +\b Fixed a problem with OBJ format whereby, in the absence of any +explicit segment definition, non-global symbols declared in the +implicit default segment generated spurious EXTDEF records in the +output. + +\b Added the NASM environment variable. + +\b From this version forward, Win32 console-mode binaries will be +included in the DOS distribution in addition to the 16-bit binaries. +Added Makefile.vc for this purpose. + +\b Added `return 0;' to test/objlink.c to prevent compiler warnings. + +\b Added the __NASM_MAJOR__ and __NASM_MINOR__ standard defines. + +\b Added an alternative memory-reference syntax in which prefixing an +operand with `&' is equivalent to enclosing it in square brackets, +at the request of Fox Cutter. + +\b Errors in pass two now cause the program to return a non-zero error +code, which they didn't before. + +\b Fixed the single-line macro cycle detection, which didn't work at +all on macros with no parameters (caused an infinite loop). Also +changed the behaviour of single-line macro cycle detection to work +like cpp, so that macros like `extrn' as given in the documentation +can be implemented. + +\b Fixed the implementation of WRT, which was too restrictive in that +you couldn't do `mov ax,[di+abc wrt dgroup]' because (di+abc) wasn't +a relocatable reference. + + +\S{cl-0.94 released April 1997} Version 0.94 released April 1997 + + +\b Major item: added the macro processor. + +\b Added undocumented instructions SMI, IBTS, XBTS and LOADALL286. Also +reorganised CMPXCHG instruction into early-486 and Pentium forms. +Thanks to Thobias Jones for the information. + +\b Fixed two more stupid bugs in ELF, which were causing `ld' to +continue to seg-fault in a lot of non-trivial cases. + +\b Fixed a seg-fault in the label manager. + +\b Stopped FBLD and FBSTP from _requiring_ the TWORD keyword, which is +the only option for BCD loads/stores in any case. + +\b Ensured FLDCW, FSTCW and FSTSW can cope with the WORD keyword, if +anyone bothers to provide it. Previously they complained unless no +keyword at all was present. + +\b Some forms of FDIV/FDIVR and FSUB/FSUBR were still inverted: a +vestige of a bug that I thought had been fixed in 0.92. This was +fixed, hopefully for good this time... + +\b Another minor phase error (insofar as a phase error can _ever_ be +minor) fixed, this one occurring in code of the form + +\c rol ax,forward_reference +\c forward_reference equ 1 + +\b The number supplied to TIMES is now sanity-checked for positivity, +and also may be greater than 64K (which previously didn't work on +16-bit systems). + +\b Added Watcom C makefiles, and misc/pmw.bat, donated by Dominik Behr. + +\b Added the INCBIN pseudo-opcode. + +\b Due to the advent of the preprocessor, the [INCLUDE] and [INC] +directives have become obsolete. They are still supported in this +version, with a warning, but won't be in the next. + +\b Fixed a bug in OBJ format, which caused incorrect object records to +be output when absolute labels were made global. + +\b Updates to RDOFF subdirectory, and changes to outrdf.c. + + +\S{cl-0.93 released January 1997} Version 0.93 released January 1997 + +This release went out in a great hurry after semi-crippling bugs +were found in 0.92. + +\b Really \e{did} fix the stack overflows this time. *blush* + +\b Had problems with EA instruction sizes changing between passes, when +an offset contained a forward reference and so 4 bytes were +allocated for the offset in pass one; by pass two the symbol had +been defined and happened to be a small absolute value, so only 1 +byte got allocated, causing instruction size mismatch between passes +and hence incorrect address calculations. Fixed. + +\b Stupid bug in the revised ELF section generation fixed (associated +string-table section for .symtab was hard-coded as 7, even when this +didn't fit with the real section table). Was causing `ld' to +seg-fault under Linux. + +\b Included a new Borland C makefile, Makefile.bc2, donated by Fox +Cutter . + + +\S{cl-0.92 released January 1997} Version 0.92 released January 1997 + +\b The FDIVP/FDIVRP and FSUBP/FSUBRP pairs had been inverted: this was +fixed. This also affected the LCC driver. + +\b Fixed a bug regarding 32-bit effective addresses of the form +\c{[other_register+ESP]}. + +\b Documentary changes, notably documentation of the fact that Borland +Win32 compilers use `obj' rather than `win32' object format. + +\b Fixed the COMENT record in OBJ files, which was formatted +incorrectly. + +\b Fixed a bug causing segfaults in large RDF files. + +\b OBJ format now strips initial periods from segment and group +definitions, in order to avoid complications with the local label +syntax. + +\b Fixed a bug in disassembling far calls and jumps in NDISASM. + +\b Added support for user-defined sections in COFF and ELF files. + +\b Compiled the DOS binaries with a sensible amount of stack, to +prevent stack overflows on any arithmetic expression containing +parentheses. + +\b Fixed a bug in handling of files that do not terminate in a newline. + + +\S{cl-0.91 released November 1996} Version 0.91 released November 1996 + +\b Loads of bug fixes. + +\b Support for RDF added. + +\b Support for DBG debugging format added. + +\b Support for 32-bit extensions to Microsoft OBJ format added. + +\b Revised for Borland C: some variable names changed, makefile added. + +\b LCC support revised to actually work. + +\b JMP/CALL NEAR/FAR notation added. + +\b `a16', `o16', `a32' and `o32' prefixes added. + +\b Range checking on short jumps implemented. + +\b MMX instruction support added. + +\b Negative floating point constant support added. + +\b Memory handling improved to bypass 64K barrier under DOS. + +\b \c{$} prefix to force treatment of reserved words as identifiers added. + +\b Default-size mechanism for object formats added. + +\b Compile-time configurability added. + +\b \c{#}, \c{@}, \c{~} and c\{?} are now valid characters in labels. + +\b \c{-e} and \c{-k} options in NDISASM added. + + +\S{cl-0.90 released October 1996} Version 0.90 released October 1996 + +First release version. First support for object file output. Other +changes from previous version (0.3x) too numerous to document. diff --git a/doc/findfont.ph b/doc/findfont.ph new file mode 100644 index 0000000..60047b8 --- /dev/null +++ b/doc/findfont.ph @@ -0,0 +1,180 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2017 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. +## +## -------------------------------------------------------------------------- + +# +# Try our best to find a specific PostScipt font in the system. +# We need to find the font files so we can extract the metrics. +# Sadly there isn't any reasonable Perl module to do this for us, +# as far as I can tell. +# + +use strict; +use File::Spec; +use File::Find; + +require 'afmmetrics.ph'; +require 'ttfmetrics.ph'; + +my %font_info_hash = (); +my $fonts_scanned = 0; +my %prefs = { 'otf' => 1, 'ttf' => 2, 'pfa' => 3, 'pfb' => 4 }; + +sub add_file_to_font_hash($) { + my($filename) = @_; + + return unless ( -f $filename ); + return unless ( $filename =~ /^(.*)\.([[:alnum:]]+)$/ ); + + my $filestem = $1; + my $fonttype = $2; + my $fontdata; + + if ( $filename =~ /\.(otf|ttf)$/i ) { + $fontdata = parse_ttf_file($filename); + } elsif ( $filename =~ /\.(pfa|pfb)$/i ) { + if ( -f "${filestem}.afm" ) { + $fontdata = parse_afm_file($filestem, $fonttype); + } + } + + return unless (defined($fontdata)); + + my $oldinfo = $font_info_hash{$fontdata->{name}}; + + if (!defined($oldinfo) || + $prefs{$fontdata->{type}} < $prefs{$oldinfo->{type}}) { + $font_info_hash{$fontdata->{name}} = $fontdata; + } +} + +my $win32_ok = eval { + require Win32::TieRegistry; + Win32::TieRegistry->import(); + 1; +}; + +# Based on Font::TTF::Win32 by +# Martin Hosken . +# LICENSING +# +# Copyright (c) 1998-2014, SIL International (http://www.sil.org) +# +# This module is released under the terms of the Artistic License 2.0. +# For details, see the full text of the license in the file LICENSE. +sub scanfonts_win32() { + return unless ($win32_ok); + + my $Reg = $::Registry->Open('', {Access=>'KEY_READ', Delimiter=>'/'}); + my $fd; + foreach my $win ('Windows NT', 'Windows') { + $fd = $Reg->{"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/$win/CurrentVersion/Fonts"}; + last if (defined($fd)); + } + return unless (defined($fd)); + + foreach my $font (keys(%$fd)) { + my($fname, $ftype) = ($font =~ m:^/(.+?)(| \([^\(\)]+\))$:); + next unless ($ftype =~ / \((TrueType|OpenType)\)$/); + my $file = File::Spec->rel2abs($fd->{$font}, $ENV{'windir'}.'\\fonts'); + add_file_to_font_hash($file); + } +} + +sub font_search_file { + add_file_to_font_hash($_); +} + +sub findfont($) { + my($fontname) = @_; + my $win32 = eval { + require Font::TTF::Win32; + Font::TTF::Win32->import(); + 1; + }; + my($file, $psname, $fontdata); + + if (exists($font_info_hash{$fontname})) { + return $font_info_hash{$fontname}; + } + + # Are we on a system that uses fontconfig? + # NOTE: use a single string for the command here, or this + # script dies horribly on Windows, even though this isn't really + # applicable there... + if (open(my $fh, '-|', + "fc-match -f \"%{file}\\n%{postscriptname}\\n\" ". + "\" : postscriptname=$fontname\"")) { + chomp($file = <$fh>); + chomp($psname = <$fh>); + close($fh); + if ( -f $file ) { + if ($psname eq $fontname) { + add_file_to_font_hash($file); + } + if (!exists($font_info_hash{$fontname})) { + $font_info_hash{$fontname} = undef; + } + return $font_info_hash{$fontname}; + } + } + + if (exists($font_info_hash{$fontname})) { + return $font_info_hash{$fontname}; + } elsif ($fonts_scanned >= 1) { + return $font_info_hash{$fontname} = undef; + } + + scanfonts_win32(); + $fonts_scanned = 1; + + if (exists($font_info_hash{$fontname})) { + return $font_info_hash{$fontname}; + } elsif ($fonts_scanned >= 2) { + return $font_info_hash{$fontname} = undef; + } + + # Search a set of possible locations for a file, from a few different + # systems... + my @dirs = ('fonts', '/usr/share/fonts', '/usr/lib/fonts', '/Library/Fonts'); + push @dirs, $ENV{'windir'}.'\\fonts' if (defined $ENV{'windir'}); + push @dirs, $ENV{'HOME'}.'/.fonts', $ENV{'HOME'}.'/Library/Fonts' + if (defined $ENV{'HOME'}); + + find({wanted => \&font_search_file, follow=>1, no_chdir=>1}, @dirs); + $fonts_scanned = 2; + + return $font_info_hash{$fontname}; +} + +1; diff --git a/doc/genps.pl b/doc/genps.pl new file mode 100644 index 0000000..4758bb9 --- /dev/null +++ b/doc/genps.pl @@ -0,0 +1,1294 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2017 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. +## +## -------------------------------------------------------------------------- + +# +# Format the documentation as PostScript +# + +use File::Spec; + +require 'psfonts.ph'; # The fonts we want to use +require 'pswidth.ph'; # PostScript string width +require 'findfont.ph'; # Find fonts in the system + +# +# Document formatting parameters +# +%psconf = ( + pagewidth => 595, # Page width in PostScript points + pageheight => 792, # Page height in PostScript points + lmarg => 72*1.25, # Left margin in PostScript points + rmarg => 72, # Right margin in PostScript points + topmarg => 72, # Top margin in PostScript points + botmarg => 72, # Bottom margin in PostScript points + plmarg => 72*0.25, # Page number position relative to left margin + prmarg => 0, # Page number position relative to right margin + pymarg => 24, # Page number position relative to bot margin + startcopyright => 75, # How much above the bottom margin is the + # copyright notice stuff + bulladj => 12, # How much to indent a bullet/indented paragraph + tocind => 12, # TOC indentation per level + tocpnz => 24, # Width of TOC page number only zone + tocdots => 8, # Spacing between TOC dots + idxspace => 24, # Minimum space between index title and pg# + idxindent => 24, # How much to indent a subindex entry + idxgutter => 24, # Space between index columns + idxcolumns => 2, # Number of index columns + + paraskip => 6, # Space between paragraphs + chapstart => 30, # Space before a chapter heading + chapskip => 24, # Space after a chapter heading + tocskip => 6, # Space between TOC entries + ); + +%psbool = ( + colorlinks => 0, # Set links in blue rather than black + ); + +# Known paper sizes +%papersizes = ( + 'a5' => [421, 595], # ISO half paper size + 'b5' => [501, 709], # ISO small paper size + 'a4' => [595, 842], # ISO standard paper size + 'letter' => [612, 792], # US common paper size + 'pa4' => [595, 792], # Compromise ("portable a4") + 'b4' => [709,1002], # ISO intermediate paper size + 'legal' => [612,1008], # US intermediate paper size + 'a3' => [842,1190], # ISO double paper size + '11x17' => [792,1224], # US double paper size + ); + +# Canned header file +$headps = 'head.ps'; + +# Directories +$fontsdir = 'fonts'; +$epsdir = File::Spec->curdir(); + +# +# Parse the command line +# +undef $input; +while ( $arg = shift(@ARGV) ) { + if ( $arg =~ /^\-(|no\-)(.*)$/ ) { + $parm = $2; + $true = ($1 eq '') ? 1 : 0; + if ( $true && defined($papersizes{$parm}) ) { + $psconf{pagewidth} = $papersizes{$parm}->[0]; + $psconf{pageheight} = $papersizes{$parm}->[1]; + } elsif ( defined($psbool{$parm}) ) { + $psbool{$parm} = $true; + } elsif ( $true && defined($psconf{$parm}) ) { + $psconf{$parm} = shift(@ARGV); + } elsif ( $true && $parm =~ /^(title|subtitle|year|author|license)$/ ) { + $metadata{$parm} = shift(@ARGV); + } elsif ( $true && $parm eq 'fontsdir' ) { + $fontsdir = shift(@ARGV); + } elsif ( $true && $parm eq 'epsdir' ) { + $epsdir = shift(@ARGV); + } elsif ( $true && $parm eq 'headps' ) { + $headps = shift(@ARGV); + } else { + die "$0: Unknown option: $arg\n"; + } + } else { + $input = $arg; + } +} + +# Configure post-paragraph skips for each kind of paragraph +# (subject to modification above) +%skiparray = ('chap' => $psconf{chapskip}, + 'appn' => $psconf{chapstart}, + 'head' => $psconf{paraskip}, + 'subh' => $psconf{paraskip}, + 'norm' => $psconf{paraskip}, + 'bull' => $psconf{paraskip}, + 'indt' => $psconf{paraskip}, + 'bquo' => $psconf{paraskip}, + 'code' => $psconf{paraskip}, + 'toc0' => $psconf{tocskip}, + 'toc1' => $psconf{tocskip}, + 'toc2' => $psconf{tocskip} + ); + +# Read the font metrics files, and update @AllFonts +# Get the list of fonts used +%ps_all_fonts = (); +%ps_font_subst = (); +foreach my $fset ( @AllFonts ) { + foreach my $font ( @{$fset->{fonts}} ) { + my $fdata; + my @flist = @{$font->[1]}; + my $fname; + while (defined($fname = shift(@flist))) { + $fdata = findfont($fname); + last if (defined($fdata)); + } + if (!defined($fdata)) { + die "$infile: no font found of: ". + join(', ', @{$font->[1]}), "\n". + "Install one of these fonts or update psfonts.ph\n"; + } + $ps_all_fonts{$fname} = $fdata; + $font->[1] = $fdata; + } +} + +# Custom encoding vector. This is basically the same as +# ISOLatin1Encoding (a level 2 feature, so we dont want to use it), +# but with the "naked" accents at \200-\237 moved to the \000-\037 +# range (ASCII control characters), and a few extra characters thrown +# in. It is basically a modified Windows 1252 codepage, minus, for +# now, the euro sign (\200 is reserved for euro.) + +@NASMEncoding = +( + undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, + undef, undef, undef, undef, undef, undef, 'dotlessi', 'grave', + 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', + 'dieresis', undef, 'ring', 'cedilla', undef, 'hungarumlaut', + 'ogonek', 'caron', 'space', 'exclam', 'quotedbl', 'numbersign', + 'dollar', 'percent', 'ampersand', 'quoteright', 'parenleft', + 'parenright', 'asterisk', 'plus', 'comma', 'minus', 'period', + 'slash', 'zero', 'one', 'two', 'three', 'four', 'five', 'six', + 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', + 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', + 'asciicircum', 'underscore', 'quoteleft', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', + 'asciitilde', undef, undef, undef, 'quotesinglbase', 'florin', + 'quotedblbase', 'ellipsis', 'dagger', 'dbldagger', 'circumflex', + 'perthousand', 'Scaron', 'guilsinglleft', 'OE', undef, 'Zcaron', + undef, undef, 'grave', 'quotesingle', 'quotedblleft', + 'quotedblright', 'bullet', 'endash', 'emdash', 'tilde', 'trademark', + 'scaron', 'guilsignlright', 'oe', undef, 'zcaron', 'Ydieresis', + 'space', 'exclamdown', 'cent', 'sterling', 'currency', 'yen', + 'brokenbar', 'section', 'dieresis', 'copyright', 'ordfeminine', + 'guillemotleft', 'logicalnot', 'hyphen', 'registered', 'macron', + 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', 'mu', + 'paragraph', 'periodcentered', 'cedilla', 'onesuperior', + 'ordmasculine', 'guillemotright', 'onequarter', 'onehalf', + 'threequarters', 'questiondown', 'Agrave', 'Aacute', 'Acircumflex', + 'Atilde', 'Adieresis', 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', + 'Ecircumflex', 'Edieresis', 'Igrave', 'Iacute', 'Icircumflex', + 'Idieresis', 'Eth', 'Ntilde', 'Ograve', 'Oacute', 'Ocircumflex', + 'Otilde', 'Odieresis', 'multiply', 'Oslash', 'Ugrave', 'Uacute', + 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', 'germandbls', + 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', 'aring', + 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis', + 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', + 'ograve', 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', + 'oslash', 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', + 'thorn', 'ydieresis' +); + +# Name-to-byte lookup hash +%charcode = (); +for ( $i = 0 ; $i < 256 ; $i++ ) { + $charcode{$NASMEncoding[$i]} = chr($i); +} + +# +# First, format the stuff coming from the front end into +# a cleaner representation +# +if ( defined($input) ) { + open(PARAS, '<', $input) or + die "$0: cannot open $input: $!\n"; +} else { + # stdin + open(PARAS, '<-') or die "$0: $!\n"; +} +while ( defined($line = ) ) { + chomp $line; + $data = ; + chomp $data; + if ( $line =~ /^meta :(.*)$/ ) { + $metakey = $1; + $metadata{$metakey} = $data; + } elsif ( $line =~ /^indx :(.*)$/ ) { + $ixentry = $1; + push(@ixentries, $ixentry); + $ixterms{$ixentry} = [split(/\037/, $data)]; + # Look for commas. This is easier done on the string + # representation, so do it now. + if ( $data =~ /^(.*)\,\037sp\037/ ) { + $ixprefix = $1; + $ixprefix =~ s/\037n $//; # Discard possible font change at end + $ixhasprefix{$ixentry} = $ixprefix; + if ( !$ixprefixes{$ixprefix} ) { + $ixcommafirst{$ixentry}++; + } + $ixprefixes{$ixprefix}++; + } else { + # A complete term can also be used as a prefix + $ixprefixes{$data}++; + } + } else { + push(@ptypes, $line); + push(@paras, [split(/\037/, $data)]); + } +} +close(PARAS); + +# +# Convert an integer to a chosen base +# +sub int2base($$) { + my($i,$b) = @_; + my($s) = ''; + my($n) = ''; + my($z) = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + return '0' if ($i == 0); + if ( $i < 0 ) { $n = '-'; $i = -$i; } + while ( $i ) { + $s = substr($z,$i%$b,1) . $s; + $i = int($i/$b); + } + return $n.$s; +} + +# +# Convert a string to a rendering array +# +sub string2array($) +{ + my($s) = @_; + my(@a) = (); + + $s =~ s/\B\-\-\B/$charcode{'emdash'}/g; + $s =~ s/\B\-\B/ $charcode{'endash'} /g; + + while ( $s =~ /^(\s+|\S+)(.*)$/ ) { + push(@a, [0,$1]); + $s = $2; + } + + return @a; +} + +# +# Take a crossreference name and generate the PostScript name for it. +# +# This hack produces a somewhat smaller PDF... +#%ps_xref_list = (); +#$ps_xref_next = 0; +#sub ps_xref($) { +# my($s) = @_; +# my $q = $ps_xref_list{$s}; +# return $q if ( defined($ps_xref_list{$s}) ); +# $q = 'X'.int2base($ps_xref_next++, 52); +# $ps_xref_list{$s} = $q; +# return $q; +#} + +# Somewhat bigger PDF, but one which obeys # URLs +sub ps_xref($) { + return @_[0]; +} + +# +# Flow lines according to a particular font set and width +# +# A "font set" is represented as an array containing +# arrays of pairs: [, ] +# +# Each line is represented as: +# [ [type,first|last,aux,fontset,page,ypos,optional col], +# [rendering array] ] +# +# A space character may be "squeezed" by up to this much +# (as a fraction of the normal width of a space.) +# +$ps_space_squeeze = 0.00; # Min space width 100% +sub ps_flow_lines($$$@) { + my($wid, $fontset, $type, @data) = @_; + my($fonts) = $$fontset{fonts}; + my($e); + my($w) = 0; # Width of current line + my($sw) = 0; # Width of current line due to spaces + my(@l) = (); # Current line + my(@ls) = (); # Accumulated output lines + my(@xd) = (); # Metadata that goes with subsequent text + my $hasmarker = 0; # Line has -6 marker + my $pastmarker = 0; # -6 marker found + + # If there is a -6 marker anywhere in the paragraph, + # *each line* output needs to have a -6 marker + foreach $e ( @data ) { + $hasmarker = 1 if ( $$e[0] == -6 ); + } + + $w = 0; + foreach $e ( @data ) { + if ( $$e[0] < 0 ) { + # Type is metadata. Zero width. + if ( $$e[0] == -6 ) { + $pastmarker = 1; + } + if ( $$e[0] == -1 || $$e[0] == -6 ) { + # -1 (end anchor) or -6 (marker) goes with the preceeding + # text, otherwise with the subsequent text + push(@l, $e); + } else { + push(@xd, $e); + } + } else { + my $ew = ps_width($$e[1], $fontset->{fonts}->[$$e[0]][1], + \@NASMEncoding) * + ($fontset->{fonts}->[$$e[0]][0]); + my $sp = $$e[1]; + $sp =~ tr/[^ ]//d; # Delete nonspaces + my $esw = ps_width($sp, $fontset->{fonts}->[$$e[0]][1], + \@NASMEncoding) * + ($fontset->{fonts}->[$$e[0]][0]); + + if ( ($w+$ew) - $ps_space_squeeze*($sw+$esw) > $wid ) { + # Begin new line + # Search backwards for previous space chunk + my $lx = scalar(@l)-1; + my @rm = (); + while ( $lx >= 0 ) { + while ( $lx >= 0 && $l[$lx]->[0] < 0 ) { + # Skip metadata + $pastmarker = 0 if ( $l[$lx]->[0] == -6 ); + $lx--; + }; + if ( $lx >= 0 ) { + if ( $l[$lx]->[1] eq ' ' ) { + splice(@l, $lx, 1); + @rm = splice(@l, $lx); + last; # Found place to break + } else { + $lx--; + } + } + } + + # Now @l contains the stuff to remain on the old line + # If we broke the line inside a link, then split the link + # into two. + my $lkref = undef; + foreach my $lc ( @l ) { + if ( $$lc[0] == -2 || $$lc[0] == -3 || $lc[0] == -7 ) { + $lkref = $lc; + } elsif ( $$lc[0] == -1 ) { + undef $lkref; + } + } + + if ( defined($lkref) ) { + push(@l, [-1,undef]); # Terminate old reference + unshift(@rm, $lkref); # Duplicate reference on new line + } + + if ( $hasmarker ) { + if ( $pastmarker ) { + unshift(@rm,[-6,undef]); # New line starts with marker + } else { + push(@l,[-6,undef]); # Old line ends with marker + } + } + + push(@ls, [[$type,0,undef,$fontset,0,0],[@l]]); + @l = @rm; + + $w = $sw = 0; + # Compute the width of the remainder array + for my $le ( @l ) { + if ( $$le[0] >= 0 ) { + my $xew = ps_width($$le[1], + $fontset->{fonts}->[$$le[0]][1], + \@NASMEncoding) * + ($fontset->{fonts}->[$$le[0]][0]); + my $xsp = $$le[1]; + $xsp =~ tr/[^ ]//d; # Delete nonspaces + my $xsw = ps_width($xsp, + $fontset->{fonts}->[$$le[0]][1], + \@NASMEncoding) * + ($fontset->{fonts}->[$$le[0]][0]); + $w += $xew; $sw += $xsw; + } + } + } + push(@l, @xd); # Accumulated metadata + @xd = (); + if ( $$e[1] ne '' ) { + push(@l, $e); + $w += $ew; $sw += $esw; + } + } + } + push(@l,@xd); + if ( scalar(@l) ) { + push(@ls, [[$type,0,undef,$fontset,0,0],[@l]]); # Final line + } + + # Mark the first line as first and the last line as last + if ( scalar(@ls) ) { + $ls[0]->[0]->[1] |= 1; # First in para + $ls[-1]->[0]->[1] |= 2; # Last in para + } + return @ls; +} + +# +# Once we have broken things into lines, having multiple chunks +# with the same font index is no longer meaningful. Merge +# adjacent chunks to keep down the size of the whole file. +# +sub ps_merge_chunks(@) { + my(@ci) = @_; + my($c, $lc); + my(@co, $eco); + + undef $lc; + @co = (); + $eco = -1; # Index of the last entry in @co + foreach $c ( @ci ) { + if ( defined($lc) && $$c[0] == $lc && $$c[0] >= 0 ) { + $co[$eco]->[1] .= $$c[1]; + } else { + push(@co, $c); $eco++; + $lc = $$c[0]; + } + } + return @co; +} + +# +# Convert paragraphs to rendering arrays. Each +# element in the array contains (font, string), +# where font can be one of: +# -1 end link +# -2 begin crossref +# -3 begin weblink +# -4 index item anchor +# -5 crossref anchor +# -6 left/right marker (used in the index) +# -7 page link (used in the index) +# 0 normal +# 1 empatic (italic) +# 2 code (fixed spacing) +# + +sub mkparaarray($@) { + my($ptype, @chunks) = @_; + + my @para = (); + my $in_e = 0; + my $chunk; + + if ( $ptype =~ /^code/ ) { + foreach $chunk ( @chunks ) { + push(@para, [2, $chunk]); + } + } else { + foreach $chunk ( @chunks ) { + my $type = substr($chunk,0,2); + my $text = substr($chunk,2); + + if ( $type eq 'sp' ) { + push(@para, [$in_e?1:0, ' ']); + } elsif ( $type eq 'da' ) { + push(@para, [$in_e?1:0, $charcode{'endash'}]); + } elsif ( $type eq 'n ' ) { + push(@para, [0, $text]); + $in_e = 0; + } elsif ( $type =~ '^e' ) { + push(@para, [1, $text]); + $in_e = ($type eq 'es' || $type eq 'e '); + } elsif ( $type eq 'c ' ) { + push(@para, [2, $text]); + $in_e = 0; + } elsif ( $type eq 'x ' ) { + push(@para, [-2, ps_xref($text)]); + } elsif ( $type eq 'xe' ) { + push(@para, [-1, undef]); + } elsif ( $type eq 'wc' || $type eq 'w ' ) { + $text =~ /\<(.*)\>(.*)$/; + my $link = $1; $text = $2; + push(@para, [-3, $link]); + push(@para, [($type eq 'wc') ? 2:0, $text]); + push(@para, [-1, undef]); + $in_e = 0; + } elsif ( $type eq 'i ' ) { + push(@para, [-4, $text]); + } else { + die "Unexpected paragraph chunk: $chunk"; + } + } + } + return @para; +} + +$npara = scalar(@paras); +for ( $i = 0 ; $i < $npara ; $i++ ) { + $paras[$i] = [mkparaarray($ptypes[$i], @{$paras[$i]})]; +} + +# +# This converts a rendering array to a simple string +# +sub ps_arraytostr(@) { + my $s = ''; + my $c; + foreach $c ( @_ ) { + $s .= $$c[1] if ( $$c[0] >= 0 ); + } + return $s; +} + +# +# This generates a duplicate of a paragraph +# +sub ps_dup_para(@) { + my(@i) = @_; + my(@o) = (); + my($c); + + foreach $c ( @i ) { + my @cc = @{$c}; + push(@o, [@cc]); + } + return @o; +} + +# +# This generates a duplicate of a paragraph, stripping anchor +# tags (-4 and -5) +# +sub ps_dup_para_noanchor(@) { + my(@i) = @_; + my(@o) = (); + my($c); + + foreach $c ( @i ) { + my @cc = @{$c}; + push(@o, [@cc]) unless ( $cc[0] == -4 || $cc[0] == -5 ); + } + return @o; +} + +# +# Scan for header paragraphs and fix up their contents; +# also generate table of contents and PDF bookmarks. +# +@tocparas = ([[-5, 'contents'], [0,'Contents']]); +@tocptypes = ('chap'); +@bookmarks = (['title', 0, 'Title'], ['contents', 0, 'Contents']); +%bookref = (); +for ( $i = 0 ; $i < $npara ; $i++ ) { + my $xtype = $ptypes[$i]; + my $ptype = substr($xtype,0,4); + my $str; + my $book; + + if ( $ptype eq 'chap' || $ptype eq 'appn' ) { + unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) { + die "Bad para"; + } + my $secn = $1; + my $sech = $2; + my $xref = ps_xref($sech); + my $chap = ($ptype eq 'chap')?'Chapter':'Appendix'; + + $book = [$xref, 0, ps_arraytostr(@{$paras[$i]})]; + push(@bookmarks, $book); + $bookref{$secn} = $book; + + push(@tocparas, [ps_dup_para_noanchor(@{$paras[$i]})]); + push(@tocptypes, 'toc0'.' :'.$sech.':'.$chap.' '.$secn.':'); + + unshift(@{$paras[$i]}, + [-5, $xref], [0,$chap.' '.$secn.':'], [0, ' ']); + } elsif ( $ptype eq 'head' || $ptype eq 'subh' ) { + unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) { + die "Bad para"; + } + my $secn = $1; + my $sech = $2; + my $xref = ps_xref($sech); + my $pref; + $pref = $secn; $pref =~ s/\.[^\.]+$//; # Find parent node + + $book = [$xref, 0, ps_arraytostr(@{$paras[$i]})]; + push(@bookmarks, $book); + $bookref{$secn} = $book; + $bookref{$pref}->[1]--; # Adjust count for parent node + + push(@tocparas, [ps_dup_para_noanchor(@{$paras[$i]})]); + push(@tocptypes, + (($ptype eq 'subh') ? 'toc2':'toc1').' :'.$sech.':'.$secn); + + unshift(@{$paras[$i]}, [-5, $xref]); + } +} + +# +# Add TOC to beginning of paragraph list +# +unshift(@paras, @tocparas); undef @tocparas; +unshift(@ptypes, @tocptypes); undef @tocptypes; + +# +# Add copyright notice to the beginning +# +@copyright_page = +([[0, $charcode{'copyright'}], + [0, ' '], [0, $metadata{'year'}], + [0, ' '], string2array($metadata{'author'}), + [0, ' '], string2array($metadata{'copyright_tail'})], + [string2array($metadata{'license'})], + [string2array($metadata{'auxinfo'})]); + +unshift(@paras, @copyright_page); +unshift(@ptypes, ('norm') x scalar(@copyright_page)); + +$npara = scalar(@paras); + +# +# No lines generated, yet. +# +@pslines = (); + +# +# Line Auxilliary Information Types +# +$AuxStr = 1; # String +$AuxPage = 2; # Page number (from xref) +$AuxPageStr = 3; # Page number as a PostScript string +$AuxXRef = 4; # Cross reference as a name +$AuxNum = 5; # Number + +# +# Break or convert paragraphs into lines, and push them +# onto the @pslines array. +# +sub ps_break_lines($$) { + my ($paras,$ptypes) = @_; + + my $linewidth = $psconf{pagewidth}-$psconf{lmarg}-$psconf{rmarg}; + my $bullwidth = $linewidth-$psconf{bulladj}; + my $indxwidth = ($linewidth-$psconf{idxgutter})/$psconf{idxcolumns} + -$psconf{idxspace}; + + my $npara = scalar(@{$paras}); + my $i; + + for ( $i = 0 ; $i < $npara ; $i++ ) { + my $xtype = $ptypes->[$i]; + my $ptype = substr($xtype,0,4); + my @data = @{$paras->[$i]}; + my @ls = (); + if ( $ptype eq 'code' ) { + my $p; + # Code paragraph; each chunk is a line + foreach $p ( @data ) { + push(@ls, [[$ptype,0,undef,\%BodyFont,0,0],[$p]]); + } + $ls[0]->[0]->[1] |= 1; # First in para + $ls[-1]->[0]->[1] |= 2; # Last in para + } elsif ( $ptype eq 'chap' || $ptype eq 'appn' ) { + # Chapters are flowed normally, but in an unusual font + @ls = ps_flow_lines($linewidth, \%ChapFont, $ptype, @data); + } elsif ( $ptype eq 'head' || $ptype eq 'subh' ) { + unless ( $xtype =~ /^\S+ (\S+) :(.*)$/ ) { + die "Bad para"; + } + my $secn = $1; + my $sech = $2; + my $font = ($ptype eq 'head') ? \%HeadFont : \%SubhFont; + @ls = ps_flow_lines($linewidth, $font, $ptype, @data); + # We need the heading number as auxillary data + $ls[0]->[0]->[2] = [[$AuxStr,$secn]]; + } elsif ( $ptype eq 'norm' ) { + @ls = ps_flow_lines($linewidth, \%BodyFont, $ptype, @data); + } elsif ( $ptype =~ /^(bull|indt)$/ ) { + @ls = ps_flow_lines($bullwidth, \%BodyFont, $ptype, @data); + } elsif ( $ptypq eq 'bquo' ) { + @ls = ps_flow_lines($bullwidth, \%BquoFont, $ptype, @data); + } elsif ( $ptype =~ /^toc/ ) { + unless ( $xtype =~/^\S+ :([^:]*):(.*)$/ ) { + die "Bad para"; + } + my $xref = $1; + my $refname = $2.' '; + my $ntoc = substr($ptype,3,1)+0; + my $refwidth = ps_width($refname, $BodyFont{fonts}->[0][1], + \@NASMEncoding) * + ($BodyFont{fonts}->[0][0]); + + @ls = ps_flow_lines($linewidth-$ntoc*$psconf{tocind}- + $psconf{tocpnz}-$refwidth, + \%BodyFont, $ptype, @data); + + # Auxilliary data: for the first line, the cross reference symbol + # and the reference name; for all lines but the first, the + # reference width; and for the last line, the page number + # as a string. + my $nl = scalar(@ls); + $ls[0]->[0]->[2] = [[$AuxStr,$refname], [$AuxXRef,$xref]]; + for ( $j = 1 ; $j < $nl ; $j++ ) { + $ls[$j]->[0]->[2] = [[$AuxNum,$refwidth]]; + } + push(@{$ls[$nl-1]->[0]->[2]}, [$AuxPageStr,$xref]); + } elsif ( $ptype =~ /^idx/ ) { + my $lvl = substr($ptype,3,1)+0; + + @ls = ps_flow_lines($indxwidth-$lvl*$psconf{idxindent}, + \%BodyFont, $ptype, @data); + } else { + die "Unknown para type: $ptype"; + } + # Merge adjacent identical chunks + foreach $l ( @ls ) { + @{$$l[1]} = ps_merge_chunks(@{$$l[1]}); + } + push(@pslines,@ls); + } +} + +# Break the main body text into lines. +ps_break_lines(\@paras, \@ptypes); + +# +# Break lines in to pages +# + +# Where to start on page 2, the copyright page +$curpage = 2; # Start on page 2 +$curypos = $psconf{pageheight}-$psconf{topmarg}-$psconf{botmarg}- + $psconf{startcopyright}; +undef $columnstart; # Not outputting columnar text +undef $curcolumn; # Current column +$nlines = scalar(@pslines); + +# +# This formats lines inside the global @pslines array into pages, +# updating the page and y-coordinate entries. Start at the +# $startline position in @pslines and go to but not including +# $endline. The global variables $curpage, $curypos, $columnstart +# and $curcolumn are updated appropriately. +# +sub ps_break_pages($$) { + my($startline, $endline) = @_; + + # Paragraph types which should never be broken + my $nobreakregexp = "^(chap|appn|head|subh|toc.|idx.)\$"; + # Paragraph types which are heading (meaning they should not be broken + # immediately after) + my $nobreakafter = "^(chap|appn|head|subh)\$"; + # Paragraph types which should never be broken *before* + my $nobreakbefore = "^idx[1-9]\$"; + # Paragraph types which are set in columnar format + my $columnregexp = "^idx.\$"; + + my $upageheight = $psconf{pageheight}-$psconf{topmarg}-$psconf{botmarg}; + + my $i; + + for ( $i = $startline ; $i < $endline ; $i++ ) { + my $linfo = $pslines[$i]->[0]; + if ( ($$linfo[0] eq 'chap' || $$linfo[0] eq 'appn' ) + && ($$linfo[1] & 1) ) { + # First line of a new chapter heading. Start a new page. + undef $columnstart; + $curpage++ if ( $curypos > 0 || defined($columnstart) ); + # Always start on an odd page + $curpage |= 1; + $curypos = $chapstart; + } elsif ( defined($columnstart) && $$linfo[0] !~ /$columnregexp/o ) { + undef $columnstart; + $curpage++; + $curypos = 0; + } + + if ( $$linfo[0] =~ /$columnregexp/o && !defined($columnstart) ) { + $columnstart = $curypos; + $curcolumn = 0; + } + + # Adjust position by the appropriate leading + $curypos += $$linfo[3]->{leading}; + + # Record the page and y-position + $$linfo[4] = $curpage; + $$linfo[5] = $curypos; + $$linfo[6] = $curcolumn if ( defined($columnstart) ); + + if ( $curypos > $upageheight ) { + # We need to break the page before this line. + my $broken = 0; # No place found yet + while ( !$broken && $pslines[$i]->[0]->[4] == $curpage ) { + my $linfo = $pslines[$i]->[0]; + my $pinfo = $pslines[$i-1]->[0]; + + if ( $$linfo[1] == 2 ) { + # This would be an orphan, don't break. + } elsif ( $$linfo[1] & 1 ) { + # Sole line or start of paragraph. Break unless + # the previous line was part of a heading. + $broken = 1 if ( $$pinfo[0] !~ /$nobreakafter/o && + $$linfo[0] !~ /$nobreakbefore/o ); + } else { + # Middle of paragraph. Break unless we're in a + # no-break paragraph, or the previous line would + # end up being a widow. + $broken = 1 if ( $$linfo[0] !~ /$nobreakregexp/o && + $$pinfo[1] != 1 ); + } + $i--; + } + die "Nowhere to break page $curpage\n" if ( !$broken ); + # Now $i should point to line immediately before the break, i.e. + # the next paragraph should be the first on the new page + if ( defined($columnstart) && + ++$curcolumn < $psconf{idxcolumns} ) { + # We're actually breaking text into columns, not pages + $curypos = $columnstart; + } else { + undef $columnstart; + $curpage++; + $curypos = 0; + } + next; + } + + # Add end of paragraph skip + if ( $$linfo[1] & 2 ) { + $curypos += $skiparray{$$linfo[0]}; + } + } +} + +ps_break_pages(0,$nlines); # Break the main text body into pages + +# +# Find the page number of all the indices +# +%ps_xref_page = (); # Crossref anchor pages +%ps_index_pages = (); # Index item pages +$nlines = scalar(@pslines); +for ( $i = 0 ; $i < $nlines ; $i++ ) { + my $linfo = $pslines[$i]->[0]; + foreach my $c ( @{$pslines[$i]->[1]} ) { + if ( $$c[0] == -4 ) { + if ( !defined($ps_index_pages{$$c[1]}) ) { + $ps_index_pages{$$c[1]} = []; + } elsif ( $ps_index_pages{$$c[1]}->[-1] eq $$linfo[4] ) { + # Pages are emitted in order; if this is a duplicated + # entry it will be the last one + next; # Duplicate + } + push(@{$ps_index_pages{$$c[1]}}, $$linfo[4]); + } elsif ( $$c[0] == -5 ) { + $ps_xref_page{$$c[1]} = $$linfo[4]; + } + } +} + +# +# Emit index paragraphs +# +$startofindex = scalar(@pslines); +@ixparas = ([[-5,'index'],[0,'Index']]); +@ixptypes = ('chap'); + +foreach $k ( @ixentries ) { + my $n,$i; + my $ixptype = 'idx0'; + my $prefix = $ixhasprefix{$k}; + my @ixpara = mkparaarray($ixptype,@{$ixterms{$k}}); + my $commapos = undef; + + if ( defined($prefix) && $ixprefixes{$prefix} > 1 ) { + # This entry has a "hanging comma" + for ( $i = 0 ; $i < scalar(@ixpara)-1 ; $i++ ) { + if ( substr($ixpara[$i]->[1],-1,1) eq ',' && + $ixpara[$i+1]->[1] eq ' ' ) { + $commapos = $i; + last; + } + } + } + if ( defined($commapos) ) { + if ( $ixcommafirst{$k} ) { + # This is the first entry; generate the + # "hanging comma" entry + my @precomma = splice(@ixpara,0,$commapos); + if ( $ixpara[0]->[1] eq ',' ) { + shift(@ixpara); # Discard lone comma + } else { + # Discard attached comma + $ixpara[0]->[1] =~ s/\,$//; + push(@precomma,shift(@ixpara)); + } + push(@precomma, [-6,undef]); + push(@ixparas, [@precomma]); + push(@ixptypes, $ixptype); + shift(@ixpara); # Remove space + } else { + splice(@ixpara,0,$commapos+2); + } + $ixptype = 'idx1'; + } + + push(@ixpara, [-6,undef]); # Left/right marker + $i = 1; $n = scalar(@{$ps_index_pages{$k}}); + foreach $p ( @{$ps_index_pages{$k}} ) { + if ( $i++ == $n ) { + push(@ixpara,[-7,$p],[0,"$p"],[-1,undef]); + } else { + push(@ixpara,[-7,$p],[0,"$p,"],[-1,undef],[0,' ']); + } + } + + push(@ixparas, [@ixpara]); + push(@ixptypes, $ixptype); +} + +# +# Flow index paragraphs into lines +# +ps_break_lines(\@ixparas, \@ixptypes); + +# +# Format index into pages +# +$nlines = scalar(@pslines); +ps_break_pages($startofindex, $nlines); + +# +# Push index onto bookmark list +# +push(@bookmarks, ['index', 0, 'Index']); + +@all_fonts_lst = sort(keys(%ps_all_fonts)); +$all_fonts_str = join(' ', @all_fonts_lst); +@need_fonts_lst = (); +foreach my $f (@all_fonts_lst) { + push(@need_fonts_lst, $f); # unless (defined($ps_all_fonts{$f}->{file})); +} +$need_fonts_str = join(' ', @need_fonts_lst); + +# Emit the PostScript DSC header +print "%!PS-Adobe-3.0\n"; +print "%%Pages: $curpage\n"; +print "%%BoundingBox: 0 0 ", $psconf{pagewidth}, ' ', $psconf{pageheight}, "\n"; +print "%%Creator: (NASM psflow.pl)\n"; +print "%%DocumentData: Clean7Bit\n"; +print "%%DocumentFonts: $all_fonts_str\n"; +print "%%DocumentNeededFonts: $need_fonts_str\n"; +print "%%Orientation: Portrait\n"; +print "%%PageOrder: Ascend\n"; +print "%%EndComments\n"; +print "%%BeginProlog\n"; + +# Emit the configurables as PostScript tokens +foreach $c ( keys(%psconf) ) { + print "/$c ", $psconf{$c}, " def\n"; +} +foreach $c ( keys(%psbool) ) { + print "/$c ", ($psbool{$c}?'true':'false'), " def\n"; +} + +# Embed font data, if applicable +#foreach my $f (@all_fonts_lst) { +# my $fontfile = $all_ps_fonts{$f}->{file}; +# if (defined($fontfile)) { +# if (open(my $fh, '<', $fontfile)) { +# print vector <$fh>; +# close($fh); +# } +# } +#} + +# Emit custom encoding vector +$zstr = '/NASMEncoding [ '; +foreach $c ( @NASMEncoding ) { + my $z = '/'.(defined($c)?$c:'.notdef ').' '; + if ( length($zstr)+length($z) > 72 ) { + print $zstr,"\n"; + $zstr = ' '; + } + $zstr .= $z; +} +print $zstr, "] def\n"; + +# Font recoding routine +# newname fontname -- +print "/nasmenc {\n"; +print " findfont dup length dict begin\n"; +print " { 1 index /FID ne {def}{pop pop} ifelse } forall\n"; +print " /Encoding NASMEncoding def\n"; +print " currentdict\n"; +print " end\n"; +print " definefont pop\n"; +print "} def\n"; + +# Emit fontset definitions +foreach $font ( sort(keys(%ps_all_fonts)) ) { + print '/',$font,'-NASM /',$font," nasmenc\n"; +} + +foreach $fset ( @AllFonts ) { + my $i = 0; + my @zfonts = (); + foreach $font ( @{$fset->{fonts}} ) { + print '/', $fset->{name}, $i, ' ', + '/', $font->[1]->{name}, '-NASM findfont ', + $font->[0], " scalefont def\n"; + push(@zfonts, $fset->{name}.$i); + $i++; + } + print '/', $fset->{name}, ' [', join(' ',@zfonts), "] def\n"; +} + +# This is used by the bullet-paragraph PostScript methods +print "/bullet [",ps_string($charcode{'bullet'}),"] def\n"; + +# Emit the canned PostScript prologue +open(PSHEAD, '<', $headps) + or die "$0: cannot open: $headps: $!\n"; +while ( defined($line = ) ) { + print $line; +} +close(PSHEAD); +print "%%EndProlog\n"; + +# Generate a PostScript string +sub ps_string($) { + my ($s) = @_; + my ($i,$c); + my ($o) = '('; + my ($l) = length($s); + for ( $i = 0 ; $i < $l ; $i++ ) { + $c = substr($s,$i,1); + if ( ord($c) < 32 || ord($c) > 126 ) { + $o .= sprintf("\\%03o", ord($c)); + } elsif ( $c eq '(' || $c eq ')' || $c eq "\\" ) { + $o .= "\\".$c; + } else { + $o .= $c; + } + } + return $o.')'; +} + +# Generate PDF bookmarks +print "%%BeginSetup\n"; +foreach $b ( @bookmarks ) { + print '[/Title ', ps_string($b->[2]), "\n"; + print '/Count ', $b->[1], ' ' if ( $b->[1] ); + print '/Dest /',$b->[0]," /OUT pdfmark\n"; +} + +# Ask the PostScript interpreter for the proper size media +print "setpagesize\n"; +print "%%EndSetup\n"; + +# Start a PostScript page +sub ps_start_page() { + $ps_page++; + print "%%Page: $ps_page $ps_page\n"; + print "%%BeginPageSetup\n"; + print "save\n"; + print "%%EndPageSetup\n"; + print '/', $ps_page, " pa\n"; +} + +# End a PostScript page +sub ps_end_page($) { + my($pn) = @_; + if ( $pn ) { + print "($ps_page)", (($ps_page & 1) ? 'pageodd' : 'pageeven'), "\n"; + } + print "restore showpage\n"; +} + +$ps_page = 0; + +# Title page +ps_start_page(); +$title = $metadata{'title'} || ''; +$title =~ s/ \- / $charcode{'endash'} /; + +$subtitle = $metadata{'subtitle'} || ''; +$subtitle =~ s/ \- / $charcode{'endash'} /; + +# Print title +print "/ti ", ps_string($title), " def\n"; +print "/sti ", ps_string($subtitle), " def\n"; +print "lmarg pageheight 2 mul 3 div moveto\n"; +print "tfont0 setfont\n"; +print "/title linkdest ti show\n"; +print "lmarg pageheight 2 mul 3 div 10 sub moveto\n"; +print "0 setlinecap 3 setlinewidth\n"; +print "pagewidth lmarg sub rmarg sub 0 rlineto currentpoint stroke moveto\n"; +print "hfont1 setfont sti stringwidth pop neg ", + -$HeadFont{leading}, " rmoveto\n"; +print "sti show\n"; + +# Print logo, if there is one +# FIX: To be 100% correct, this should look for DocumentNeeded* +# and DocumentFonts in the header of the EPSF and add those to the +# global header. +if ( defined($metadata{epslogo}) && + open(EPS, '<', File::Spec->catfile($epsdir, $metadata{epslogo})) ) { + my @eps = (); + my ($bbllx,$bblly,$bburx,$bbury) = (undef,undef,undef,undef); + my $line; + my $scale = 1; + my $maxwidth = $psconf{pagewidth}-$psconf{lmarg}-$psconf{rmarg}; + my $maxheight = $psconf{pageheight}/3-40; + my $width, $height; + my $x, $y; + + while ( defined($line = ) ) { + last if ( $line =~ /^%%EOF/ ); + if ( !defined($bbllx) && + $line =~ /^\%\%BoundingBox\:\s*([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)\s+([0-9\.]+)/i ) { + $bbllx = $1+0; $bblly = $2+0; + $bburx = $3+0; $bbury = $4+0; + } + push(@eps,$line); + } + close(EPS); + + if ( defined($bbllx) ) { + $width = $bburx-$bbllx; + $height = $bbury-$bblly; + + if ( $width > $maxwidth ) { + $scale = $maxwidth/$width; + } + if ( $height*$scale > $maxheight ) { + $scale = $maxheight/$height; + } + + $x = ($psconf{pagewidth}-$width*$scale)/2; + $y = ($psconf{pageheight}-$height*$scale)/2; + + if ( defined($metadata{logoxadj}) ) { + $x += $metadata{logoxadj}; + } + if ( defined($metadata{logoyadj}) ) { + $y += $metadata{logoyadj}; + } + + print "BeginEPSF\n"; + print $x, ' ', $y, " translate\n"; + print $scale, " dup scale\n" unless ( $scale == 1 ); + print -$bbllx, ' ', -$bblly, " translate\n"; + print "$bbllx $bblly moveto\n"; + print "$bburx $bblly lineto\n"; + print "$bburx $bbury lineto\n"; + print "$bbllx $bbury lineto\n"; + print "$bbllx $bblly lineto clip newpath\n"; + print "%%BeginDocument: ",ps_string($metadata{epslogo}),"\n"; + print @eps; + print "%%EndDocument\n"; + print "EndEPSF\n"; + } +} +ps_end_page(0); + +# Emit the rest of the document (page 2 and on) +$curpage = 2; +ps_start_page(); +foreach $line ( @pslines ) { + my $linfo = $line->[0]; + + while ( $$linfo[4] > $curpage ) { + ps_end_page($curpage > 2); + ps_start_page(); + $curpage++; + } + + print '['; + my $curfont = 0; + foreach my $c ( @{$line->[1]} ) { + if ( $$c[0] >= 0 ) { + if ( $curfont != $$c[0] ) { + print ($curfont = $$c[0]); + } + print ps_string($$c[1]); + } elsif ( $$c[0] == -1 ) { + print '{el}'; # End link + } elsif ( $$c[0] == -2 ) { + print '{/',$$c[1],' xl}'; # xref link + } elsif ( $$c[0] == -3 ) { + print '{',ps_string($$c[1]),'wl}'; # web link + } elsif ( $$c[0] == -4 ) { + # Index anchor -- ignore + } elsif ( $$c[0] == -5 ) { + print '{/',$$c[1],' xa}'; #xref anchor + } elsif ( $$c[0] == -6 ) { + print ']['; # Start a new array + $curfont = 0; + } elsif ( $$c[0] == -7 ) { + print '{/',$$c[1],' pl}'; # page link + } else { + die "Unknown annotation"; + } + } + print ']'; + if ( defined($$linfo[2]) ) { + foreach my $x ( @{$$linfo[2]} ) { + if ( $$x[0] == $AuxStr ) { + print ps_string($$x[1]); + } elsif ( $$x[0] == $AuxPage ) { + print $ps_xref_page{$$x[1]},' '; + } elsif ( $$x[0] == $AuxPageStr ) { + print ps_string($ps_xref_page{$$x[1]}); + } elsif ( $$x[0] == $AuxXRef ) { + print '/',ps_xref($$x[1]),' '; + } elsif ( $$x[0] == $AuxNum ) { + print $$x[1],' '; + } else { + die "Unknown auxilliary data type"; + } + } + } + print ($psconf{pageheight}-$psconf{topmarg}-$$linfo[5]); + print ' ', $$linfo[6] if ( defined($$linfo[6]) ); + print ' ', $$linfo[0].$$linfo[1], "\n"; +} + +ps_end_page(1); +print "%%EOF\n"; diff --git a/doc/head.ps b/doc/head.ps new file mode 100644 index 0000000..7fbb3a9 Binary files /dev/null and b/doc/head.ps differ diff --git a/doc/inslist.pl b/doc/inslist.pl new file mode 100644 index 0000000..c7d7da4 --- /dev/null +++ b/doc/inslist.pl @@ -0,0 +1,108 @@ +#!/usr/bin/perl +## -------------------------------------------------------------------------- +## +## Copyright 1996-2017 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. +## +## -------------------------------------------------------------------------- + +# +# inslist.pl produce inslist.src +# + +print STDERR "Reading insns.dat...\n"; + +@args = (); +undef $output; +foreach $arg ( @ARGV ) { + if ( $arg =~ /^\-/ ) { + if ( $arg =~ /^\-([adins])$/ ) { + $output = $1; + } else { + die "$0: Unknown option: ${arg}\n"; + } + } else { + push (@args, $arg); + } +} + +$fname = "../insns.dat" unless $fname = $args[0]; +open (F, '<', $fname) || die "unable to open $fname"; +print STDERR "Writing inslist.src...\n"; +open S, '>', 'inslist.src'; +$line = 0; +$insns = 0; +while () { + $line++; + next if (/^\s*$/); # blank lines + if ( /^\s*;/ ) # comments + { + if ( /^\s*;\#\s*(.+)/ ) # section subheader + { + print S "\n\\S{} $1\n\n"; + } + next; + } + chomp; + unless (/^\s*(\S+)\s+(\S+)\s+(\S+|\[.*\])\s+(\S+)\s*$/) { + warn "line $line does not contain four fields\n"; + next; + } + my @entry = ($1, $2, $3, $4); + + $entry[1] =~ s/ignore//; + $entry[1] =~ s/void//; + + my @flags = split(/,/, $entry[3]); + my @nflags; + undef $isavx512; + undef @avx512fl; + for my $fl (@flags) { + next if ($fl =~ /^(ignore|SB|SM|SM2|SQ|AR2|FUTURE)$/); + + if ($fl =~ /^AVX512(.*)$/) { + $isavx512 = 1; + push(@avx512fl, $1) unless ($1 eq ''); + } else { + push(@nflags,$fl); + } + } + + if ($isavx512) { + unshift(@nflags, "AVX512".join('/', @avx512fl)); + } + + printf S "\\c %-16s %-24s %s\n",$entry[0],$entry[1], join(',', @nflags); + $insns++; +} +print S "\n"; +close S; +close F; +printf STDERR "Done: %d instructions\n", $insns; + diff --git a/doc/internal.doc b/doc/internal.doc new file mode 100644 index 0000000..88f06bc --- /dev/null +++ b/doc/internal.doc @@ -0,0 +1,290 @@ +Internals of the Netwide Assembler +================================== + +The Netwide Assembler is intended to be a modular, re-usable x86 +assembler, which can be embedded in other programs, for example as +the back end to a compiler. + +The assembler is composed of modules. The interfaces between them +look like: + + +--- preproc.c ----+ + | | + +---- parser.c ----+ + | | | + | float.c | + | | + +--- assemble.c ---+ + | | | + nasm.c ---+ insnsa.c +--- nasmlib.c + | | + +--- listing.c ----+ + | | + +---- labels.c ----+ + | | + +--- outform.c ----+ + | | + +----- *out.c -----+ + +In other words, each of `preproc.c', `parser.c', `assemble.c', +`labels.c', `listing.c', `outform.c' and each of the output format +modules `*out.c' are independent modules, which do not directly +inter-communicate except through the main program. + +The Netwide *Disassembler* is not intended to be particularly +portable or reusable or anything, however. So I won't bother +documenting it here. :-) + +nasmlib.c +--------- + +This is a library module; it contains simple library routines which +may be referenced by all other modules. Among these are a set of +wrappers around the standard `malloc' routines, which will report a +fatal error if they run out of memory, rather than returning NULL. + +preproc.c +--------- + +This contains a macro preprocessor, which takes a file name as input +and returns a sequence of preprocessed source lines. The only symbol +exported from the module is `nasmpp', which is a data structure of +type `Preproc', declared in nasm.h. This structure contains pointers +to all the functions designed to be callable from outside the +module. + +parser.c +-------- + +This contains a source-line parser. It parses `canonical' assembly +source lines, containing some combination of the `label', `opcode', +`operand' and `comment' fields: it does not process directives or +macros. It exports two functions: `parse_line' and `cleanup_insn'. + +`parse_line' is the main parser function: you pass it a source line +in ASCII text form, and it returns you an `insn' structure +containing all the details of the instruction on that line. The +parameters it requires are: + +- The location (segment, offset) where the instruction on this line + will eventually be placed. This is necessary in order to evaluate + expressions containing the Here token, `$'. + +- A function which can be called to retrieve the value of any + symbols the source line references. + +- Which pass the assembler is on: an undefined symbol only causes an + error condition on pass two. + +- The source line to be parsed. + +- A structure to fill with the results of the parse. + +- A function which can be called to report errors. + +Some instructions (DB, DW, DD for example) can require an arbitrary +amount of storage, and so some of the members of the resulting +`insn' structure will be dynamically allocated. The other function +exported by `parser.c' is `cleanup_insn', which can be called to +deallocate any dynamic storage associated with the results of a +parse. + +names.c +------- + +This doesn't count as a module - it defines a few arrays which are +shared between NASM and NDISASM, so it's a separate file which is +#included by both parser.c and disasm.c. + +float.c +------- + +This is essentially a library module: it exports one function, +`float_const', which converts an ASCII representation of a +floating-point number into an x86-compatible binary representation, +without using any built-in floating-point arithmetic (so it will run +on any platform, portably). It calls nothing, and is called only by +`parser.c'. Note that the function `float_const' must be passed an +error reporting routine. + +assemble.c +---------- + +This module contains the code generator: it translates `insn' +structures as returned from the parser module into actual generated +code which can be placed in an output file. It exports two +functions, `assemble' and `insn_size'. + +`insn_size' is designed to be called on pass one of assembly: it +takes an `insn' structure as input, and returns the amount of space +that would be taken up if the instruction described in the structure +were to be converted to real machine code. `insn_size' also requires +to be told the location (as a segment/offset pair) where the +instruction would be assembled, the mode of assembly (16/32 bit +default), and a function it can call to report errors. + +`assemble' is designed to be called on pass two: it takes all the +parameters that `insn_size' does, but has an extra parameter which +is an output driver. `assemble' actually converts the input +instruction into machine code, and outputs the machine code by means +of calling the `output' function of the driver. + +insnsa.c +-------- + +This is another library module: it exports one very big array of +instruction translations. It is generated automatically from the +insns.dat file by the insns.pl script. + +labels.c +-------- + +This module contains a label manager. It exports six functions: + +`init_labels' should be called before any other function in the +module. `cleanup_labels' may be called after all other use of the +module has finished, to deallocate storage. + +`define_label' is called to define new labels: you pass it the name +of the label to be defined, and the (segment,offset) pair giving the +value of the label. It is also passed an error-reporting function, +and an output driver structure (so that it can call the output +driver's label-definition function). `define_label' mentally +prepends the name of the most recently defined non-local label to +any label beginning with a period. + +`define_label_stub' is designed to be called in pass two, once all +the labels have already been defined: it does nothing except to +update the "most-recently-defined-non-local-label" status, so that +references to local labels in pass two will work correctly. + +`declare_as_global' is used to declare that a label should be +global. It must be called _before_ the label in question is defined. + +Finally, `lookup_label' attempts to translate a label name into a +(segment,offset) pair. It returns non-zero on success. + +The label manager module is (theoretically :) restartable: after +calling `cleanup_labels', you can call `init_labels' again, and +start a new assembly with a new set of symbols. + +listing.c +--------- + +This file contains the listing file generator. The interface to the +module is through the one symbol it exports, `nasmlist', which is a +structure containing six function pointers. The calling semantics of +these functions isn't terribly well thought out, as yet, but it +works (just about) so it's going to get left alone for now... + +outform.c +--------- + +This small module contains a set of routines to manage a list of +output formats, and select one given a keyword. It contains three +small routines: `ofmt_register' which registers an output driver as +part of the managed list, `ofmt_list' which lists the available +drivers on stdout, and `ofmt_find' which tries to find the driver +corresponding to a given name. + +The output modules +------------------ + +Each of the output modules, `outbin.o', `outelf.o' and so on, +exports only one symbol, which is an output driver data structure +containing pointers to all the functions needed to produce output +files of the appropriate type. + +The exception to this is `outcoff.o', which exports _two_ output +driver structures, since COFF and Win32 object file formats are very +similar and most of the code is shared between them. + +nasm.c +------ + +This is the main program: it calls all the functions in the above +modules, and puts them together to form a working assembler. We +hope. :-) + +Segment Mechanism +----------------- + +In NASM, the term `segment' is used to separate the different +sections/segments/groups of which an object file is composed. +Essentially, every address NASM is capable of understanding is +expressed as an offset from the beginning of some segment. + +The defining property of a segment is that if two symbols are +declared in the same segment, then the distance between them is +fixed at assembly time. Hence every externally-declared variable +must be declared in its own segment, since none of the locations of +these are known, and so no distances may be computed at assembly +time. + +The special segment value NO_SEG (-1) is used to denote an absolute +value, e.g. a constant whose value does not depend on relocation, +such as the _size_ of a data object. + +Apart from NO_SEG, segment indices all have their least significant +bit clear, if they refer to actual in-memory segments. For each +segment of this type, there is an auxiliary segment value, defined +to be the same number but with the LSB set, which denotes the +segment-base value of that segment, for object formats which support +it (Microsoft .OBJ, for example). + +Hence, if `textsym' is declared in a code segment with index 2, then +referencing `SEG textsym' would return zero offset from +segment-index 3. Or, in object formats which don't understand such +references, it would return an error instead. + +The next twist is SEG_ABS. Some symbols may be declared with a +segment value of SEG_ABS plus a 16-bit constant: this indicates that +they are far-absolute symbols, such as the BIOS keyboard buffer +under MS-DOS, which always resides at 0040h:001Eh. Far-absolutes are +handled with care in the parser, since they are supposed to evaluate +simply to their offset part within expressions, but applying SEG to +one should yield its segment part. A far-absolute should never find +its way _out_ of the parser, unless it is enclosed in a WRT clause, +in which case Microsoft 16-bit object formats will want to know +about it. + +Porting Issues +-------------- + +We have tried to write NASM in portable ANSI C: we do not assume +little-endianness or any hardware characteristics (in order that +NASM should work as a cross-assembler for x86 platforms, even when +run on other, stranger machines). + +Assumptions we _have_ made are: + +- We assume that `short' is at least 16 bits, and `long' at least + 32. This really _shouldn't_ be a problem, since Kernighan and + Ritchie tell us we are entitled to do so. + +- We rely on having more than 6 characters of significance on + externally linked symbols in the NASM sources. This may get fixed + at some point. We haven't yet come across a linker brain-dead + enough to get it wrong anyway. + +- We assume that `fopen' using the mode "wb" can be used to write + binary data files. This may be wrong on systems like VMS, with a + strange file system. Though why you'd want to run NASM on VMS is + beyond me anyway. + +That's it. Subject to those caveats, NASM should be completely +portable. If not, we _really_ want to know about it. + +Porting Non-Issues +------------------ + +The following is _not_ a portability problem, although it looks like +one. + +- When compiling with some versions of DJGPP, you may get errors + such as `warning: ANSI C forbids braced-groups within + expressions'. This isn't NASM's fault - the problem seems to be + that DJGPP's definitions of the macros include a + GNU-specific C extension. So when compiling using -ansi and + -pedantic, DJGPP complains about its own header files. It isn't a + problem anyway, since it still generates correct code. diff --git a/doc/local.css b/doc/local.css new file mode 100644 index 0000000..dfee522 --- /dev/null +++ b/doc/local.css @@ -0,0 +1 @@ +/* Add site-local nasmdoc style configuration to this file */ diff --git a/doc/nasmdoc.css b/doc/nasmdoc.css new file mode 100644 index 0000000..6ad9e91 --- /dev/null +++ b/doc/nasmdoc.css @@ -0,0 +1,150 @@ +body { + font-family: "source sans pro", "clear sans", "liberation sans", + "arial", "sans-serif"; + background: white; +} +div.title { + text-align: center; + font-weight: bold; + margin: 0.67em 0; +} +h1 { + font-size: 2em; + margin: 0; +} +span.subtitle { + font-size: 1.25em; + font-style: italic; +} +code, pre { + font-family: "source code pro", "liberation mono", "monospace"; +} +pre, blockquote { + margin-left: 4em; + margin-right: 4em; +} +code { + display: inline; + white-space: nowrap; +} +a { + text-decoration: none; +} +div.toc { + padding-left: 0; + font-size: 195%; +} +div.toc li { + list-style-type: none; + padding-left: 0; +} +div.toc ol { + padding-left: 2em; + font-size: 80%; +} +li.toc1 { + padding-top: 0.7em; +} +li.toc2 { + padding-top: 0.3em; +} +ul.index { + list-style-type: none; +} +@media not screen { + ul.navbar { + display: none; + } +} +@media print { + a { + color: inherit; + } +} +@media only screen { + div.contents { + -webkit-column-gap: 4em; + -webkit-column-rule: 1px dotted black; + -moz-column-gap: 4em; + -moz-column-rule: 1px dotted black; + column-gap: 4em; + column-rule: 1px dotted black; + } +} +@media only screen and (min-width: 90em) { + /* For a very wide screen, go to a columnar layout */ + div.contents { + -webkit-column-count: 2; + -moz-column-count: 2; + column-count: 2; + } +} +@media only screen and (min-width: 135em) { + div.contents { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + } +} +@media screen { + /* Setting an explicit margin to keep the navbar from moving */ + body { + padding: 0; + margin: 8px; + } + + /* Link styles */ + a:link { + color: #33c; + } + a:visited { + color: #338; + } + a:hover { + background: #ccc; + } + a:active { + color: #f33; + background: #ccc; + } + + /* Trick to avoid the navbar hiding the the target of an # link */ + :target { + margin-top: -10vh; + padding-top: 10vh; + background: #ffa; /* Highlight the jump target */ + background-clip: content-box; + } + + ul.navbar { + display: block; + position: sticky; + top: 8px; + width: 100%; + margin: 0; + padding: 0; + overflow: hidden; + white-space: nowrap; + list-style-type: none; + background: #336 url("nasmlogw.png") no-repeat right center; + background-size: contain; + } + + ul.navbar li { + float: left; + } + ul.navbar li.last { + border-right: none; + } + ul.navbar a { + border-right: 1px solid #bbb; + display: block; + color: white; + text-align: center; + padding: 1em 1.5em; + text-decoration: none; + } + ul.navbar a:hover { + background-color: #448; + } +} diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src new file mode 100644 index 0000000..9ebe657 --- /dev/null +++ b/doc/nasmdoc.src @@ -0,0 +1,8450 @@ +\# -------------------------------------------------------------------------- +\# +\# Copyright 1996-2018 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. +\# +\# -------------------------------------------------------------------------- +\# +\# Source code to NASM documentation +\# + +\M{category}{Programming} +\M{title}{NASM - The Netwide Assembler} +\M{year}{1996-2017} +\M{author}{The NASM Development Team} +\M{copyright_tail}{-- All Rights Reserved} +\M{license}{This document is redistributable under the license given in the file "LICENSE" distributed in the NASM archive.} +\M{summary}{This file documents NASM, the Netwide Assembler: an assembler targetting the Intel x86 series of processors, with portable source.} +\M{infoname}{NASM} +\M{infofile}{nasm} +\M{infotitle}{The Netwide Assembler for x86} +\M{epslogo}{nasmlogo.eps} +\M{logoyadj}{-72} + +\& version.src + +\IR{-D} \c{-D} option +\IR{-E} \c{-E} option +\IR{-F} \c{-F} option +\IR{-I} \c{-I} option +\IR{-M} \c{-M} option +\IR{-MD} \c{-MD} option +\IR{-MF} \c{-MF} option +\IR{-MG} \c{-MG} option +\IR{-MP} \c{-MP} option +\IR{-MQ} \c{-MQ} option +\IR{-MT} \c{-MT} option +\IR{-MW} \c{-MW} option +\IR{-O} \c{-O} option +\IR{-P} \c{-P} option +\IR{-U} \c{-U} option +\IR{-X} \c{-X} option +\IR{-a} \c{-a} option +\IR{-d} \c{-d} option +\IR{-e} \c{-e} option +\IR{-f} \c{-f} option +\IR{-g} \c{-g} option +\IR{-i} \c{-i} option +\IR{-l} \c{-l} option +\IR{-o} \c{-o} option +\IR{-p} \c{-p} option +\IR{-s} \c{-s} option +\IR{-u} \c{-u} option +\IR{-v} \c{-v} option +\IR{-W} \c{-W} option +\IR{-Werror} \c{-Werror} option +\IR{-Wno-error} \c{-Wno-error} option +\IR{-w} \c{-w} option +\IR{-y} \c{-y} option +\IR{-Z} \c{-Z} option +\IR{!=} \c{!=} operator +\IR{$, here} \c{$}, Here token +\IR{$, prefix} \c{$}, prefix +\IR{$$} \c{$$} token +\IR{%} \c{%} operator +\IR{%%} \c{%%} operator +\IR{%+1} \c{%+1} and \c{%-1} syntax +\IA{%-1}{%+1} +\IR{%0} \c{%0} parameter count +\IR{&} \c{&} operator +\IR{&&} \c{&&} operator +\IR{*} \c{*} operator +\IR{..@} \c{..@} symbol prefix +\IR{/} \c{/} operator +\IR{//} \c{//} operator +\IR{<} \c{<} operator +\IR{<<} \c{<<} operator +\IR{<=} \c{<=} operator +\IR{<>} \c{<>} operator +\IR{=} \c{=} operator +\IR{==} \c{==} operator +\IR{>} \c{>} operator +\IR{>=} \c{>=} operator +\IR{>>} \c{>>} operator +\IR{?} \c{?} MASM syntax +\IR{^} \c{^} operator +\IR{^^} \c{^^} operator +\IR{|} \c{|} operator +\IR{||} \c{||} operator +\IR{~} \c{~} operator +\IR{%$} \c{%$} and \c{%$$} prefixes +\IA{%$$}{%$} +\IR{+ opaddition} \c{+} operator, binary +\IR{+ opunary} \c{+} operator, unary +\IR{+ modifier} \c{+} modifier +\IR{- opsubtraction} \c{-} operator, binary +\IR{- opunary} \c{-} operator, unary +\IR{! opunary} \c{!} operator, unary +\IR{alignment, in bin sections} alignment, in \c{bin} sections +\IR{alignment, in elf sections} alignment, in \c{elf} sections +\IR{alignment, in win32 sections} alignment, in \c{win32} sections +\IR{alignment, of elf common variables} alignment, of \c{elf} common +variables +\IR{alignment, in obj sections} alignment, in \c{obj} sections +\IR{a.out, bsd version} \c{a.out}, BSD version +\IR{a.out, linux version} \c{a.out}, Linux version +\IR{autoconf} Autoconf +\IR{bin} bin +\IR{bitwise and} bitwise AND +\IR{bitwise or} bitwise OR +\IR{bitwise xor} bitwise XOR +\IR{block ifs} block IFs +\IR{borland pascal} Borland, Pascal +\IR{borland's win32 compilers} Borland, Win32 compilers +\IR{braces, after % sign} braces, after \c{%} sign +\IR{bsd} BSD +\IR{c calling convention} C calling convention +\IR{c symbol names} C symbol names +\IA{critical expressions}{critical expression} +\IA{command line}{command-line} +\IA{case sensitivity}{case sensitive} +\IA{case-sensitive}{case sensitive} +\IA{case-insensitive}{case sensitive} +\IA{character constants}{character constant} +\IR{codeview} CodeView debugging format +\IR{common object file format} Common Object File Format +\IR{common variables, alignment in elf} common variables, alignment +in \c{elf} +\IR{common, elf extensions to} \c{COMMON}, \c{elf} extensions to +\IR{common, obj extensions to} \c{COMMON}, \c{obj} extensions to +\IR{declaring structure} declaring structures +\IR{default-wrt mechanism} default-\c{WRT} mechanism +\IR{devpac} DevPac +\IR{djgpp} DJGPP +\IR{dll symbols, exporting} DLL symbols, exporting +\IR{dll symbols, importing} DLL symbols, importing +\IR{dos} DOS +\IR{dos archive} DOS archive +\IR{dos source archive} DOS source archive +\IA{effective address}{effective addresses} +\IA{effective-address}{effective addresses} +\IR{elf} ELF +\IR{elf, 16-bit code and} ELF, 16-bit code and +\IR{elf shared libraries} ELF, shared libraries +\IR{elf32} \c{elf32} +\IR{elf64} \c{elf64} +\IR{elfx32} \c{elfx32} +\IR{executable and linkable format} Executable and Linkable Format +\IR{extern, obj extensions to} \c{EXTERN}, \c{obj} extensions to +\IR{extern, rdf extensions to} \c{EXTERN}, \c{rdf} extensions to +\IR{floating-point, constants} floating-point, constants +\IR{floating-point, packed bcd constants} floating-point, packed BCD constants +\IR{freebsd} FreeBSD +\IR{freelink} FreeLink +\IR{functions, c calling convention} functions, C calling convention +\IR{functions, pascal calling convention} functions, Pascal calling +convention +\IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to +\IR{global, elf extensions to} \c{GLOBAL}, \c{elf} extensions to +\IR{global, rdf extensions to} \c{GLOBAL}, \c{rdf} extensions to +\IR{got} GOT +\IR{got relocations} \c{GOT} relocations +\IR{gotoff relocation} \c{GOTOFF} relocations +\IR{gotpc relocation} \c{GOTPC} relocations +\IR{intel number formats} Intel number formats +\IR{linux, elf} Linux, ELF +\IR{linux, a.out} Linux, \c{a.out} +\IR{linux, as86} Linux, \c{as86} +\IR{logical and} logical AND +\IR{logical or} logical OR +\IR{logical xor} logical XOR +\IR{mach object file format} Mach, object file format +\IA{mach-o}{macho} +\IR{mach-o} Mach-O, object file format +\IR{macho32} \c{macho32} +\IR{macho64} \c{macho64} +\IR{macos x} MacOS X +\IR{masm} MASM +\IA{memory reference}{memory references} +\IR{minix} Minix +\IA{misc directory}{misc subdirectory} +\IR{misc subdirectory} \c{misc} subdirectory +\IR{microsoft omf} Microsoft OMF +\IR{mmx registers} MMX registers +\IA{modr/m}{modr/m byte} +\IR{modr/m byte} ModR/M byte +\IR{ms-dos} MS-DOS +\IR{ms-dos device drivers} MS-DOS device drivers +\IR{multipush} \c{multipush} macro +\IR{nan} NaN +\IR{nasm version} NASM version +\IR{netbsd} NetBSD +\IR{nsis} NSIS +\IR{nullsoft scriptable installer} Nullsoft Scriptable Installer +\IR{omf} OMF +\IR{openbsd} OpenBSD +\IR{operating system} operating system +\IR{os/2} OS/2 +\IR{pascal calling convention}Pascal calling convention +\IR{passes} passes, assembly +\IR{perl} Perl +\IR{pic} PIC +\IR{pharlap} PharLap +\IR{plt} PLT +\IR{plt} \c{PLT} relocations +\IA{pre-defining macros}{pre-define} +\IA{preprocessor expressions}{preprocessor, expressions} +\IA{preprocessor loops}{preprocessor, loops} +\IA{preprocessor variables}{preprocessor, variables} +\IA{rdoff subdirectory}{rdoff} +\IR{rdoff} \c{rdoff} subdirectory +\IR{relocatable dynamic object file format} Relocatable Dynamic +Object File Format +\IR{relocations, pic-specific} relocations, PIC-specific +\IA{repeating}{repeating code} +\IR{section alignment, in elf} section alignment, in \c{elf} +\IR{section alignment, in bin} section alignment, in \c{bin} +\IR{section alignment, in obj} section alignment, in \c{obj} +\IR{section alignment, in win32} section alignment, in \c{win32} +\IR{section, elf extensions to} \c{SECTION}, \c{elf} extensions to +\IR{section, macho extensions to} \c{SECTION}, \c{macho} extensions to +\IR{section, win32 extensions to} \c{SECTION}, \c{win32} extensions to +\IR{segment alignment, in bin} segment alignment, in \c{bin} +\IR{segment alignment, in obj} segment alignment, in \c{obj} +\IR{segment, obj extensions to} \c{SEGMENT}, \c{elf} extensions to +\IR{segment names, borland pascal} segment names, Borland Pascal +\IR{shift command} \c{shift} command +\IA{sib}{sib byte} +\IR{sib byte} SIB byte +\IR{align, smart} \c{ALIGN}, smart +\IA{sectalign}{sectalign} +\IR{solaris x86} Solaris x86 +\IA{standard section names}{standardized section names} +\IR{symbols, exporting from dlls} symbols, exporting from DLLs +\IR{symbols, importing from dlls} symbols, importing from DLLs +\IR{test subdirectory} \c{test} subdirectory +\IR{tlink} \c{TLINK} +\IR{underscore, in c symbols} underscore, in C symbols +\IR{unicode} Unicode +\IR{unix} Unix +\IR{utf-8} UTF-8 +\IR{utf-16} UTF-16 +\IR{utf-32} UTF-32 +\IA{sco unix}{unix, sco} +\IR{unix, sco} Unix, SCO +\IA{unix source archive}{unix, source archive} +\IR{unix, source archive} Unix, source archive +\IA{unix system v}{unix, system v} +\IR{unix, system v} Unix, System V +\IR{unixware} UnixWare +\IR{val} VAL +\IR{version number of nasm} version number of NASM +\IR{visual c++} Visual C++ +\IR{www page} WWW page +\IR{win32} Win32 +\IR{win32} Win64 +\IR{windows} Windows +\IR{windows 95} Windows 95 +\IR{windows nt} Windows NT +\# \IC{program entry point}{entry point, program} +\# \IC{program entry point}{start point, program} +\# \IC{MS-DOS device drivers}{device drivers, MS-DOS} +\# \IC{16-bit mode, versus 32-bit mode}{32-bit mode, versus 16-bit mode} +\# \IC{c symbol names}{symbol names, in C} + + +\C{intro} Introduction + +\H{whatsnasm} What Is NASM? + +The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed +for portability and modularity. It supports a range of object file +formats, including Linux and \c{*BSD} \c{a.out}, \c{ELF}, \c{COFF}, +\c{Mach-O}, 16-bit and 32-bit \c{OBJ} (OMF) format, \c{Win32} and +\c{Win64}. It will also output plain binary files, Intel hex and +Motorola S-Record formats. Its syntax is designed to be simple and +easy to understand, similar to the syntax in the Intel Software +Developer Manual with minimal complexity. It supports all currently +known x86 architectural extensions, and has strong support for macros. + +NASM also comes with a set of utilities for handling the \c{RDOFF} +custom object-file format. + +\S{legal} \i{License} Conditions + +Please see the file \c{LICENSE}, supplied as part of any NASM +distribution archive, for the license conditions under which you may +use NASM. NASM is now under the so-called 2-clause BSD license, also +known as the simplified BSD license. + +Copyright 1996-2017 the NASM Authors - All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +\b Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +\b 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. + +\C{running} Running NASM + +\H{syntax} NASM \i{Command-Line} Syntax + +To assemble a file, you issue a command of the form + +\c nasm -f [-o ] + +For example, + +\c nasm -f elf myfile.asm + +will assemble \c{myfile.asm} into an \c{ELF} object file \c{myfile.o}. And + +\c nasm -f bin myfile.asm -o myfile.com + +will assemble \c{myfile.asm} into a raw binary file \c{myfile.com}. + +To produce a listing file, with the hex codes output from NASM +displayed on the left of the original sources, use the \c{-l} option +to give a listing file name, for example: + +\c nasm -f coff myfile.asm -l myfile.lst + +To get further usage instructions from NASM, try typing + +\c nasm -h + +\c{--help} option is also the same. + +As \c{-hf}, this will also list the available output file formats, and what they +are. + +If you use Linux but aren't sure whether your system is \c{a.out} +or \c{ELF}, type + +\c file nasm + +(in the directory in which you put the NASM binary when you +installed it). If it says something like + +\c nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1 + +then your system is \c{ELF}, and you should use the option \c{-f elf} +when you want NASM to produce Linux object files. If it says + +\c nasm: Linux/i386 demand-paged executable (QMAGIC) + +or something similar, your system is \c{a.out}, and you should use +\c{-f aout} instead (Linux \c{a.out} systems have long been obsolete, +and are rare these days.) + +Like Unix compilers and assemblers, NASM is silent unless it +goes wrong: you won't see any output at all, unless it gives error +messages. + + +\S{opt-o} The \i\c{-o} Option: Specifying the Output File Name + +NASM will normally choose the name of your output file for you; +precisely how it does this is dependent on the object file format. +For Microsoft object file formats (\c{obj}, \c{win32} and \c{win64}), +it will remove the \c{.asm} \i{extension} (or whatever extension you +like to use - NASM doesn't care) from your source file name and +substitute \c{.obj}. For Unix object file formats (\c{aout}, \c{as86}, +\c{coff}, \c{elf32}, \c{elf64}, \c{elfx32}, \c{ieee}, \c{macho32} and +\c{macho64}) it will substitute \c{.o}. For \c{dbg}, \c{rdf}, \c{ith} +and \c{srec}, it will use \c{.dbg}, \c{.rdf}, \c{.ith} and \c{.srec}, +respectively, and for the \c{bin} format it will simply remove the +extension, so that \c{myfile.asm} produces the output file \c{myfile}. + +If the output file already exists, NASM will overwrite it, unless it +has the same name as the input file, in which case it will give a +warning and use \i\c{nasm.out} as the output file name instead. + +For situations in which this behaviour is unacceptable, NASM +provides the \c{-o} command-line option, which allows you to specify +your desired output file name. You invoke \c{-o} by following it +with the name you wish for the output file, either with or without +an intervening space. For example: + +\c nasm -f bin program.asm -o program.com +\c nasm -f bin driver.asm -odriver.sys + +Note that this is a small o, and is different from a capital O , which +is used to specify the number of optimisation passes required. See \k{opt-O}. + + +\S{opt-f} The \i\c{-f} Option: Specifying the \i{Output File Format} + +If you do not supply the \c{-f} option to NASM, it will choose an +output file format for you itself. In the distribution versions of +NASM, the default is always \i\c{bin}; if you've compiled your own +copy of NASM, you can redefine \i\c{OF_DEFAULT} at compile time and +choose what you want the default to be. + +Like \c{-o}, the intervening space between \c{-f} and the output +file format is optional; so \c{-f elf} and \c{-felf} are both valid. + +A complete list of the available output file formats can be given by +issuing the command \i\c{nasm -hf}. + + +\S{opt-l} The \i\c{-l} Option: Generating a \i{Listing File} + +If you supply the \c{-l} option to NASM, followed (with the usual +optional space) by a file name, NASM will generate a +\i{source-listing file} for you, in which addresses and generated +code are listed on the left, and the actual source code, with +expansions of multi-line macros (except those which specifically +request no expansion in source listings: see \k{nolist}) on the +right. For example: + +\c nasm -f elf myfile.asm -l myfile.lst + +If a list file is selected, you may turn off listing for a +section of your source with \c{[list -]}, and turn it back on +with \c{[list +]}, (the default, obviously). There is no "user +form" (without the brackets). This can be used to list only +sections of interest, avoiding excessively long listings. + + +\S{opt-M} The \i\c{-M} Option: Generate \i{Makefile Dependencies} + +This option can be used to generate makefile dependencies on stdout. +This can be redirected to a file for further processing. For example: + +\c nasm -M myfile.asm > myfile.dep + + +\S{opt-MG} The \i\c{-MG} Option: Generate \i{Makefile Dependencies} + +This option can be used to generate makefile dependencies on stdout. +This differs from the \c{-M} option in that if a nonexisting file is +encountered, it is assumed to be a generated file and is added to the +dependency list without a prefix. + + +\S{opt-MF} The \i\c\{-MF} Option: Set Makefile Dependency File + +This option can be used with the \c{-M} or \c{-MG} options to send the +output to a file, rather than to stdout. For example: + +\c nasm -M -MF myfile.dep myfile.asm + + +\S{opt-MD} The \i\c{-MD} Option: Assemble and Generate Dependencies + +The \c{-MD} option acts as the combination of the \c{-M} and \c{-MF} +options (i.e. a filename has to be specified.) However, unlike the +\c{-M} or \c{-MG} options, \c{-MD} does \e{not} inhibit the normal +operation of the assembler. Use this to automatically generate +updated dependencies with every assembly session. For example: + +\c nasm -f elf -o myfile.o -MD myfile.dep myfile.asm + + +\S{opt-MT} The \i\c{-MT} Option: Dependency Target Name + +The \c{-MT} option can be used to override the default name of the +dependency target. This is normally the same as the output filename, +specified by the \c{-o} option. + + +\S{opt-MQ} The \i\c{-MQ} Option: Dependency Target Name (Quoted) + +The \c{-MQ} option acts as the \c{-MT} option, except it tries to +quote characters that have special meaning in Makefile syntax. This +is not foolproof, as not all characters with special meaning are +quotable in Make. The default output (if no \c{-MT} or \c{-MQ} option +is specified) is automatically quoted. + + +\S{opt-MP} The \i\c{-MP} Option: Emit phony targets + +When used with any of the dependency generation options, the \c{-MP} +option causes NASM to emit a phony target without dependencies for +each header file. This prevents Make from complaining if a header +file has been removed. + + +\S{opt-MW} The \i\c{-MW} Option: Watcom Make quoting style + +This option causes NASM to attempt to quote dependencies according to +Watcom Make conventions rather than POSIX Make conventions (also used +by most other Make variants.) This quotes \c{#} as \c{$#} rather than +\c{\\#}, uses \c{&} rather than \c{\\} for continuation lines, and +encloses filenames containing whitespace in double quotes. + + +\S{opt-F} The \i\c{-F} Option: Selecting a \i{Debug Information Format} + +This option is used to select the format of the debug information +emitted into the output file, to be used by a debugger (or \e{will} +be). Prior to version 2.03.01, the use of this switch did \e{not} enable +output of the selected debug info format. Use \c{-g}, see \k{opt-g}, +to enable output. Versions 2.03.01 and later automatically enable \c{-g} +if \c{-F} is specified. + +A complete list of the available debug file formats for an output +format can be seen by issuing the command \c{nasm -f -y}. Not +all output formats currently support debugging output. See \k{opt-y}. + +This should not be confused with the \c{-f dbg} output format option, +see \k{dbgfmt}. + + +\S{opt-g} The \i\c{-g} Option: Enabling \i{Debug Information}. + +This option can be used to generate debugging information in the specified +format. See \k{opt-F}. Using \c{-g} without \c{-F} results in emitting +debug info in the default format, if any, for the selected output format. +If no debug information is currently implemented in the selected output +format, \c{-g} is \e{silently ignored}. + + +\S{opt-X} The \i\c{-X} Option: Selecting an \i{Error Reporting Format} + +This option can be used to select an error reporting format for any +error messages that might be produced by NASM. + +Currently, two error reporting formats may be selected. They are +the \c{-Xvc} option and the \c{-Xgnu} option. The GNU format is +the default and looks like this: + +\c filename.asm:65: error: specific error message + +where \c{filename.asm} is the name of the source file in which the +error was detected, \c{65} is the source file line number on which +the error was detected, \c{error} is the severity of the error (this +could be \c{warning}), and \c{specific error message} is a more +detailed text message which should help pinpoint the exact problem. + +The other format, specified by \c{-Xvc} is the style used by Microsoft +Visual C++ and some other programs. It looks like this: + +\c filename.asm(65) : error: specific error message + +where the only difference is that the line number is in parentheses +instead of being delimited by colons. + +See also the \c{Visual C++} output format, \k{win32fmt}. + +\S{opt-Z} The \i\c{-Z} Option: Send Errors to a File + +Under \I{DOS}\c{MS-DOS} it can be difficult (though there are ways) to +redirect the standard-error output of a program to a file. Since +NASM usually produces its warning and \i{error messages} on +\i\c{stderr}, this can make it hard to capture the errors if (for +example) you want to load them into an editor. + +NASM therefore provides the \c{-Z} option, taking a filename argument +which causes errors to be sent to the specified files rather than +standard error. Therefore you can \I{redirecting errors}redirect +the errors into a file by typing + +\c nasm -Z myfile.err -f obj myfile.asm + +In earlier versions of NASM, this option was called \c{-E}, but it was +changed since \c{-E} is an option conventionally used for +preprocessing only, with disastrous results. See \k{opt-E}. + +\S{opt-s} The \i\c{-s} Option: Send Errors to \i\c{stdout} + +The \c{-s} option redirects \i{error messages} to \c{stdout} rather +than \c{stderr}, so it can be redirected under \I{DOS}\c{MS-DOS}. To +assemble the file \c{myfile.asm} and pipe its output to the \c{more} +program, you can type: + +\c nasm -s -f obj myfile.asm | more + +See also the \c{-Z} option, \k{opt-Z}. + + +\S{opt-i} The \i\c{-i}\I\c{-I} Option: Include File Search Directories + +When NASM sees the \i\c{%include} or \i\c{%pathsearch} directive in a +source file (see \k{include}, \k{pathsearch} or \k{incbin}), it will +search for the given file not only in the current directory, but also +in any directories specified on the command line by the use of the +\c{-i} option. Therefore you can include files from a \i{macro +library}, for example, by typing + +\c nasm -ic:\macrolib\ -f obj myfile.asm + +(As usual, a space between \c{-i} and the path name is allowed, and +optional). + +Prior NASM 2.14 a path provided in the option has been considered as +a verbatim copy and providing a path separator been up to a caller. +One could implicitly concatenate a search path together with a filename. +Still this was rather a trick than something useful. Now the trailing +path separator is made to always present, thus \c{-ifoo} will be +considered as the \c{-ifoo/} directory. + +If you want to define a \e{standard} \i{include search path}, +similar to \c{/usr/include} on Unix systems, you should place one or +more \c{-i} directives in the \c{NASMENV} environment variable (see +\k{nasmenv}). + +For Makefile compatibility with many C compilers, this option can also +be specified as \c{-I}. + + +\S{opt-p} The \i\c{-p}\I\c{-P} Option: \I{pre-including files}Pre-Include a File + +\I\c{%include}NASM allows you to specify files to be +\e{pre-included} into your source file, by the use of the \c{-p} +option. So running + +\c nasm myfile.asm -p myinc.inc + +is equivalent to running \c{nasm myfile.asm} and placing the +directive \c{%include "myinc.inc"} at the start of the file. + +\c{--include} option is also accepted. + +For consistency with the \c{-I}, \c{-D} and \c{-U} options, this +option can also be specified as \c{-P}. + + + +\S{opt-d} The \i\c{-d}\I\c{-D} Option: \I{pre-defining macros}Pre-Define a Macro + +\I\c{%define}Just as the \c{-p} option gives an alternative to placing +\c{%include} directives at the start of a source file, the \c{-d} +option gives an alternative to placing a \c{%define} directive. You +could code + +\c nasm myfile.asm -dFOO=100 + +as an alternative to placing the directive + +\c %define FOO 100 + +at the start of the file. You can miss off the macro value, as well: +the option \c{-dFOO} is equivalent to coding \c{%define FOO}. This +form of the directive may be useful for selecting \i{assembly-time +options} which are then tested using \c{%ifdef}, for example +\c{-dDEBUG}. + +For Makefile compatibility with many C compilers, this option can also +be specified as \c{-D}. + + +\S{opt-u} The \i\c{-u}\I\c{-U} Option: \I{Undefining macros}Undefine a Macro + +\I\c{%undef}The \c{-u} option undefines a macro that would otherwise +have been pre-defined, either automatically or by a \c{-p} or \c{-d} +option specified earlier on the command lines. + +For example, the following command line: + +\c nasm myfile.asm -dFOO=100 -uFOO + +would result in \c{FOO} \e{not} being a predefined macro in the +program. This is useful to override options specified at a different +point in a Makefile. + +For Makefile compatibility with many C compilers, this option can also +be specified as \c{-U}. + + +\S{opt-E} The \i\c{-E}\I{-e} Option: Preprocess Only + +NASM allows the \i{preprocessor} to be run on its own, up to a +point. Using the \c{-E} option (which requires no arguments) will +cause NASM to preprocess its input file, expand all the macro +references, remove all the comments and preprocessor directives, and +print the resulting file on standard output (or save it to a file, +if the \c{-o} option is also used). + +This option cannot be applied to programs which require the +preprocessor to evaluate \I{preprocessor expressions}\i{expressions} +which depend on the values of symbols: so code such as + +\c %assign tablesize ($-tablestart) + +will cause an error in \i{preprocess-only mode}. + +For compatiblity with older version of NASM, this option can also be +written \c{-e}. \c{-E} in older versions of NASM was the equivalent +of the current \c{-Z} option, \k{opt-Z}. + +\S{opt-a} The \i\c{-a} Option: Don't Preprocess At All + +If NASM is being used as the back end to a compiler, it might be +desirable to \I{suppressing preprocessing}suppress preprocessing +completely and assume the compiler has already done it, to save time +and increase compilation speeds. The \c{-a} option, requiring no +argument, instructs NASM to replace its powerful \i{preprocessor} +with a \i{stub preprocessor} which does nothing. + + +\S{opt-O} The \i\c{-O} Option: Specifying \i{Multipass Optimization} + +Using the \c{-O} option, you can tell NASM to carry out different +levels of optimization. The syntax is: + +\b \c{-O0}: No optimization. All operands take their long forms, + if a short form is not specified, except conditional jumps. + This is intended to match NASM 0.98 behavior. + +\b \c{-O1}: Minimal optimization. As above, but immediate operands + which will fit in a signed byte are optimized, + unless the long form is specified. Conditional jumps default + to the long form unless otherwise specified. + +\b \c{-Ox} (where \c{x} is the actual letter \c{x}): Multipass optimization. + Minimize branch offsets and signed immediate bytes, + overriding size specification unless the \c{strict} keyword + has been used (see \k{strict}). For compatibility with earlier + releases, the letter \c{x} may also be any number greater than + one. This number has no effect on the actual number of passes. + +The \c{-Ox} mode is recommended for most uses, and is the default +since NASM 2.09. + +Note that this is a capital \c{O}, and is different from a small \c{o}, which +is used to specify the output file name. See \k{opt-o}. + + +\S{opt-t} The \i\c{-t} Option: Enable TASM Compatibility Mode + +NASM includes a limited form of compatibility with Borland's \i\c{TASM}. +When NASM's \c{-t} option is used, the following changes are made: + +\b local labels may be prefixed with \c{@@} instead of \c{.} + +\b size override is supported within brackets. In TASM compatible mode, +a size override inside square brackets changes the size of the operand, +and not the address type of the operand as it does in NASM syntax. E.g. +\c{mov eax,[DWORD val]} is valid syntax in TASM compatibility mode. +Note that you lose the ability to override the default address type for +the instruction. + +\b unprefixed forms of some directives supported (\c{arg}, \c{elif}, +\c{else}, \c{endif}, \c{if}, \c{ifdef}, \c{ifdifi}, \c{ifndef}, +\c{include}, \c{local}) + +\S{opt-w} The \i\c{-w} and \i\c{-W} Options: Enable or Disable Assembly \i{Warnings} + +NASM can observe many conditions during the course of assembly which +are worth mentioning to the user, but not a sufficiently severe +error to justify NASM refusing to generate an output file. These +conditions are reported like errors, but come up with the word +`warning' before the message. Warnings do not prevent NASM from +generating an output file and returning a success status to the +operating system. + +Some conditions are even less severe than that: they are only +sometimes worth mentioning to the user. Therefore NASM supports the +\c{-w} command-line option, which enables or disables certain +classes of assembly warning. Such warning classes are described by a +name, for example \c{orphan-labels}; you can enable warnings of +this class by the command-line option \c{-w+orphan-labels} and +disable it by \c{-w-orphan-labels}. + +The current \i{warning classes} are: + +\b \i\c{other} specifies any warning not otherwise specified in any +class. Enabled by default. + +\b \i\c{macro-params} covers warnings about \i{multi-line macros} +being invoked with the wrong number of parameters. Enabled by default; +see \k{mlmacover} for an example of why you might want to disable it. + +\b \i\c{macro-selfref} warns if a macro references itself. Disabled by +default. + +\b \i\c{macro-defaults} warns when a macro has more default parameters +than optional parameters. Enabled by default; see \k{mlmacdef} for why +you might want to disable it. + +\b \i\c{orphan-labels} covers warnings about source lines which +contain no instruction but define a label without a trailing colon. +NASM warns about this somewhat obscure condition by default; +see \k{syntax} for more information. + +\b \i\c{number-overflow} covers warnings about numeric constants which +don't fit in 64 bits. Enabled by default. + +\b \i\c{gnu-elf-extensions} warns if 8-bit or 16-bit relocations +are used in \c{-f elf} format. The GNU extensions allow this. +Disabled by default. + +\b \i\c{float-overflow} warns about floating point overflow. +Enabled by default. + +\b \i\c{float-denorm} warns about floating point denormals. +Disabled by default. + +\b \i\c{float-underflow} warns about floating point underflow. +Disabled by default. + +\b \i\c{float-toolong} warns about too many digits in floating-point numbers. +Enabled by default. + +\b \i\c{user} controls \c{%warning} directives (see \k{pperror}). +Enabled by default. + +\b \i\c{lock} warns about \c{LOCK} prefixes on unlockable instructions. +Enabled by default. + +\b \i\c{hle} warns about invalid use of the HLE \c{XACQUIRE} or \c{XRELEASE} +prefixes. +Enabled by default. + +\b \i\c{bnd} warns about ineffective use of the \c{BND} prefix when a relaxed +form of jmp instruction becomes jmp short form. +Enabled by default. + +\b \i\c{zext-reloc} warns that a relocation has been zero-extended due +to limitations in the output format. Enabled by default. + +\b \i\c\{ptr} warns about keywords used in other assemblers that might +indicate a mistake in the source code. Currently only the MASM +\c{PTR} keyword is recognized. Enabled by default. + +\b \i\c{bad-pragma} warns about a malformed or otherwise unparsable +\c{%pragma} directive. Disabled by default. + +\b \i\c{unknown-pragma} warns about an unknown \c{%pragma} directive. +This is not yet implemented. Disabled by default. + +\b \i\c{not-my-pragma} warns about a \c{%pragma} directive which is +not applicable to this particular assembly session. This is not yet +implemented. Disabled by default. + +\b \i\c{unknown-warning} warns about a \c{-w} or \c{-W} option or a +\c{[WARNING]} directive that contains an unknown warning name or is +otherwise not possible to process. Disabled by default. + +\b \i\c{all} is an alias for \e{all} suppressible warning classes. +Thus, \c{-w+all} enables all available warnings, and \c{-w-all} +disables warnings entirely (since NASM 2.13). + +Since version 2.00, NASM has also supported the \c{gcc}-like syntax +\c{-Wwarning-class} and \c{-Wno-warning-class} instead of +\c{-w+warning-class} and \c{-w-warning-class}, respectively; both +syntaxes work identically. + +The option \c{-w+error} or \i\c{-Werror} can be used to treat warnings +as errors. This can be controlled on a per warning class basis +(\c{-w+error=}\e{warning-class} or \c{-Werror=}\e{warning-class}); +if no \e{warning-class} is specified NASM treats it as +\c{-w+error=all}; the same applies to \c{-w-error} or +\i\c{-Wno-error}, +of course. + +In addition, you can control warnings in the source code itself, using +the \i\c{[WARNING]} directive. See \k{asmdir-warning}. + + +\S{opt-v} The \i\c{-v} Option: Display \i{Version} Info + +Typing \c{NASM -v} will display the version of NASM which you are using, +and the date on which it was compiled. + +You will need the version number if you report a bug. + +For command-line compatibility with Yasm, the form \i\c{--v} is also +accepted for this option starting in NASM version 2.11.05. + +\S{opt-y} The \i\c{-y} Option: Display Available Debug Info Formats + +Typing \c{nasm -f