NASM 0.98.09
authorH. Peter Anvin <hpa@zytor.com>
Tue, 30 Apr 2002 21:01:08 +0000 (21:01 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 30 Apr 2002 21:01:08 +0000 (21:01 +0000)
29 files changed:
AUTHORS
Makefile.in
Mkfiles/Makefile.b32
Mkfiles/Makefile.dl [new file with mode: 0644]
assemble.c
doc/makedocs.bat [new file with mode: 0644]
doc/nasmdoc.src
insns.dat
labels.c
listing.c
macros.pl
misc/scitech.mac [new file with mode: 0644]
nasm.c
nasm.h
nasmlib.c
outaout.c
outas86.c
outbin.c
outcoff.c
outelf.c
outform.h
outobj.c
parser.c
preproc.c
rdoff/Makefile.in
rdoff/README
rdoff/ldrdf1.c [deleted file]
standard.mac
zoutieee.c

diff --git a/AUTHORS b/AUTHORS
index 2fa097d..fb10957 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,5 @@
 This is the AUTHORS file for the NASM project located at:
-http://nasm.rm-f.net/
+http://nasm.2y.net/
 
 Names should be inserted as follows:
 
index 3d31f56..52a772a 100644 (file)
@@ -15,7 +15,7 @@ bindir                = @bindir@
 mandir         = @mandir@
 
 CC             = @CC@
-CFLAGS         = @CFLAGS@ @GCCFLAGS@ -I$(srcdir) -I.
+CFLAGS         = @CFLAGS@ @GCCFLAGS@ -I$(srcdir) -I. 
 LDFLAGS                = @LDFLAGS@
 
 INSTALL                = @INSTALL@
index 2e642d0..d83e6e0 100644 (file)
@@ -7,13 +7,19 @@
 #
 # This Makefile is designed to build NASM with the latest
 # version of Borland C++Builder and has been tested with 
-# Borland C++ 5.3 (Borland C++Builder 3.0) and Borland C++ 5.4
-# (Borland C++Builder 4.0) in combination with
-# Borland MAKE versions 5.1 and 5.2
+# Borland C++ 5.5 (Borland C++Builder 5.0) in combination
+# Borland MAKE 5.2
+#
+# Additionally, the free Borland C++ Compiler 5.5 is supported;
+# see
+#
+#   http://www.borland.com/bcppbuilder/freecompiler/
 #
 # MAKEFILE is maintained by Stefan.Hoffmeister@Econos.de
 #
 
+srcdir=.
+BINDIR=e:\devel\bcb5\cbuilder5\bin
 
 # If "BINDIR=C:\...." has not been defined on the command line
 # assume that the binary files are in the same directory as the
 
 
 CC=$(BINDIR)\bcc32
-CCFLAGS=-tWC -c -O2 -A
+CCFLAGS=-q -Q -tWC -c -O2 -A -w-8057
+  # /q:    Suppress compiler identification banner
+  # /Q:    Extended compiler error information
   # /-tWC: Windows console mode application
   # /c:    Compile, do not link
   # /O2:   Optimize for speed
   # /A:    ANSI compatible code only
+  # /-w-8057: Turn off "Parameter <param> never used in function <func>" warning
 
 LINK=$(BINDIR)\ilink32
-LINKFLAGS=/V4.0 /x /c /ap /L$(BINDIR)\..\LIB     # /L -> default LIB directory
+LINKFLAGS=/V4.0 /q /x /c /ap /L$(BINDIR)\..\LIB     # /L -> default LIB directory
   # /V4.0: marked as Win95 / NT application in PE header
+  # /q:    suppress command-line banner
   # /x:    no map file
   # /c:    case sensitive link
   # /ap:   link for 32-bit console application
@@ -131,7 +141,30 @@ parser.$(OBJ): parser.c nasm.h insnsi.h nasmlib.h parser.h float.h names.c insns
 preproc.$(OBJ): preproc.c macros.c preproc.h nasm.h insnsi.h nasmlib.h
 sync.$(OBJ): sync.c sync.h
 
+# These source files are automagically generated from a single
+# instruction-table file by a Perl script. They're distributed,
+# though, so it isn't necessary to have Perl just to recompile NASM
+# from the distribution.
+
+insnsa.c: InstructionData
+insnsd.c: InstructionData
+insnsi.h: InstructionData
+insnsn.c: InstructionData
+
+InstructionData: insns.dat insns.pl
+       perl $(srcdir)/insns.pl -a $(srcdir)/insns.dat
+
+# 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.c: standard.mac macros.pl
+       perl $(srcdir)/macros.pl $(srcdir)/standard.mac
+
 clean:
-  del *.obj
-  del nasm$(SUFFIX)$(EXE)
-  del ndisasm$(SUFFIX)$(EXE)
+  @-del /S *.obj  2> NUL 1>&2
+  @-del /S *.il?  2> NUL 1>&2
+  @-del /S *.tds  2> NUL 1>&2
+  @-del /S *.~*  2> NUL 1>&2
+  @-del /S nasm$(SUFFIX)$(EXE)  2> NUL 1>&2
+  @-del /S ndisasm$(SUFFIX)$(EXE)  2> NUL 1>&2
diff --git a/Mkfiles/Makefile.dl b/Mkfiles/Makefile.dl
new file mode 100644 (file)
index 0000000..db53e57
--- /dev/null
@@ -0,0 +1,46 @@
+# Makefile for the Netwide Assembler under 16-bit DOS
+#
+# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
+# Julian Hall. All rights reserved. The software is
+# redistributable under the licence given in the file "Licence"
+# distributed in the NASM archive.
+#
+# This Makefile is designed to build NASM using David Lindauer's
+# cc386
+
+CC = cc386 /C+N
+LINK = valx -case -use32 -map
+LINKFLAGS =
+LIBRARIES =
+OBJ = obj
+
+.c.obj:
+       $(CC) $&
+       &nasm -fobj $&.ASM
+
+NDISASMOBJS = ndisasm.$(OBJ) disasm.$(OBJ) sync.$(OBJ) nasmlib.$(OBJ) \
+              insnsd.$(OBJ)
+
+NASMOBJS = nasm.$(OBJ) nasmlib.$(OBJ) eval.$(OBJ) float.$(OBJ) insnsa.$(OBJ) \
+           assemble.$(OBJ) labels.$(OBJ) parser.$(OBJ) outform.$(OBJ) \
+          outbin.$(OBJ) outaout.$(OBJ) outcoff.$(OBJ) outelf.$(OBJ) \
+          outobj.$(OBJ) outas86.$(OBJ) outrdf.$(OBJ) outrdf2.$(OBJ) outdbg.$(OBJ) \
+           preproc.$(OBJ) listing.$(OBJ) zoutieee.$(OBJ)
+
+all : nasm.exe ndisasm.exe
+
+# We have to have a horrible kludge here to get round the 128 character
+# limit, as usual...
+LINKOBJS = a*.obj e*.obj f*.obj insnsa.obj l*.obj na*.obj o*.obj p*.obj z*.obj
+nasm.exe: $(NASMOBJS)
+       $(LINK) \cc386\lib\c0dos $(LINKOBJS:.obj=),nasm,nasm,\cc386\lib\cldos
+
+ndisasm.exe: $(NDISASMOBJS)
+       $(LINK) \cc386\lib\c0dos.obj $(NDISASMOBJS:.obj=),ndisasm,ndisasm,\cc386\lib\cldos
+
+clean :
+        del *.asm
+        del *.obj
+        del *.map
+        del *.exe
+
index 98bb507..8058979 100644 (file)
@@ -546,7 +546,9 @@ static int is_sbyte (insn *ins, int op, int size)
     int ret;
     
     ret = !(ins->forw_ref && ins->oprs[op].opflags ) &&        /* dead in the water on forward reference or External */
-              ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
+          !(ins->oprs[op].type & (BITS16|BITS32)) &&    /* John Coffman's 3/24/01 patch - fbk - 10/16/01 */
+          ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG;
+
     v = ins->oprs[op].offset;
     if (size==16) v = (signed short)v;   /* sign extend if 16 bits */
     
diff --git a/doc/makedocs.bat b/doc/makedocs.bat
new file mode 100644 (file)
index 0000000..70db811
--- /dev/null
@@ -0,0 +1,254 @@
+@echo off
+if "%1"=="clean" goto makeclean
+if "%1"=="CLEAN" goto makeclean
+if "%1"=="spotless" goto spotless
+if "%1"=="SPOTLESS" goto spotless
+if "%1"=="install" goto install
+if "%1"=="INSTALL" goto install
+
+cls
+echo.
+echo.
+echo.
+echo    Usage:
+echo.
+echo        makedocs - no parameters - makes all Docs
+echo        makedocs install - installs already made docs in subdirectories
+echo        makedocs clean - removes docs from current directory
+echo        makedocs spotless - removes all - including default install dirs
+echo.
+echo.
+echo.
+echo.
+echo        Makedocs(.bat), with no parameters will create Nasm Documentation
+echo        in several formats: plain ascii text, ps, html, rtf, Windows help
+echo        format, and if you've got an "info" system installed, info format.
+echo.
+echo.
+echo                This requires Perl, and almost 4MB disk space.
+echo.
+echo.
+choice "                     Proceed with making docs? "
+if errorlevel 2 goto exit
+
+:makeall
+
+echo.
+echo.
+echo                        This takes a while. Stretch!
+echo.
+echo.
+
+perl rdsrc.pl<nasmdoc.src
+echo.
+echo.
+choice "                       Make *info* files? "
+if errorlevel 2 goto noinfo
+:makeinfo
+echo.
+echo.
+makeinfo nasmdoc.tex
+
+:noinfo
+
+:install
+
+if not exist nasmdoc.txt goto nofiles
+if not exist nasmdoc0.htm goto nofiles
+if not exist nasmdo10.htm goto nofiles
+if not exist nasmdoc.hpj goto nofiles
+if not exist nasmdoc.rtf goto nofiles
+if not exist nasmdoc.ps goto nofiles
+if not exist nasmdoc.tex goto nofiles
+goto gotfiles
+:nofiles
+echo.
+echo.
+echo.
+echo.
+echo                       Alert!      Files missing!
+echo.
+echo.
+choice "               Would you like to make them now? "
+if errorlevel 2 goto exit
+goto makeall
+
+:gotfiles
+
+:: get current path
+
+set oldprompt=%prompt%
+echo @prompt set nasdoc=$p>temp1.bat
+command /c temp1.bat>temp2.bat
+call temp2
+del temp1.bat
+del temp2.bat
+set prompt=%oldprompt%
+set oldprompt=
+
+echo.
+echo.
+echo.
+echo.
+echo        Current Directory is %nasdoc%
+echo        Nasm Documentation will be installed under this
+echo        as %nasdoc%\text\nasmdoc.txt, etc.
+echo.
+echo.
+choice "                   Change this directory? "
+if errorlevel 2 goto dirok
+
+echo.
+echo.
+echo.
+echo.
+echo      Directory *above* the directory you name (at least) should exist.
+echo      Nasm documentation will be installed *under* the directory you
+echo      name. E.G. \docs\nasm\html, etc. No trailing backslash!
+echo.
+echo.
+
+echo                Enter new name for base directory:
+set input=
+fc con nul /lb1 /n|date|find "1:">magic.bat
+echo set input=%%5>enter.bat
+call magic
+set nasdoc=%input%
+del magic.bat
+del enter.bat
+set input=
+
+echo.
+echo.
+md %nasdoc%
+echo.
+echo.
+
+choice "  Install Text docs in %nasdoc%\text ? "
+if errorlevel 2 goto notext
+md %nasdoc%\text
+copy nasmdoc.txt %nasdoc%\text
+:notext
+
+choice "  Install Html docs in %nasdoc%\html ? "
+if errorlevel 2 goto nohtml
+md %nasdoc%\html
+copy *.htm %nasdoc%\html
+:nohtml
+
+choice "  Install Info docs in %nasdoc%\info ? "
+if errorlevel 2 goto noinfodocs
+if not exist nasm.inf goto inofiles
+if not exist nasm.i9 goto inofiles
+goto gotifiles
+:inofiles
+echo.
+echo.
+echo                       Alert!      Files missing!
+echo.
+echo.
+choice "               Would you like to make them now? "
+if errorlevel 2 goto noinfodocs
+if not exist nasmdoc.tex goto makeall
+goto makeinfo
+
+:gotifiles
+
+md %nasdoc%\info
+copy nasm.i* %nasdoc%\info
+:noinfodocs
+
+choice "  Install Winhelp docs in %nasdoc%\winhelp ? "
+if errorlevel 2 goto nowinhelp
+md %nasdoc%\winhelp
+copy nasmdoc.rtf %nasdoc%\winhelp
+copy nasmdoc.hpj %nasdoc%\winhelp
+:nowinhelp
+
+choice "  Install Postscript docs in %nasdoc%\ps ? "
+if errorlevel 2 goto nops
+md %nasdoc%\ps
+copy nasmdoc.ps %nasdoc%\ps
+:nops
+goto cleanup
+
+:dirok
+
+choice "  Install Text docs in .\text ? "
+if errorlevel 2 goto notext2
+md text
+copy nasmdoc.txt text
+:notext2
+
+choice "  Install Html docs in .\html ? "
+if errorlevel 2 goto nohtml2
+md html
+copy *.htm html
+:nohtml2
+
+choice "  Install Info docs in .\info ? "
+if errorlevel 2 goto nid2
+
+if not exist nasm.inf goto inof2
+if not exist nasm.i9 goto inof2
+goto gifiles2
+:inof2
+echo.
+echo.
+echo                       Alert!      Files missing!
+echo.
+echo.
+choice "               Would you like to make them now? "
+if errorlevel 2 goto nid2
+if not exist nasmdoc.tex goto makeall
+goto makeinfo
+
+:gifiles2
+
+md info
+copy nasm.i* info
+:nid2
+
+choice "  Install Winhelp docs in .\winhelp ? "
+if errorlevel 2 goto nwhelp2
+md winhelp
+copy nasmdoc.rtf winhelp
+copy nasmdoc.hpj winhelp
+:nwhelp2
+
+choice "  Install Postscript docs in .\ps ? "
+if errorlevel 2 goto nops2
+md ps
+copy nasmdoc.ps ps
+:nops2
+
+
+:cleanup
+set nasdoc=
+
+echo.
+echo.
+echo.
+echo.
+choice "        Remove all files created, but not installed?"
+if not errorlevel 2 goto makeclean
+
+goto exit
+
+:spotless
+deltree /y text
+deltree /y html
+deltree /y info
+deltree /y winhelp
+deltree /y ps
+
+:makeclean
+del *.htm
+del *.rtf
+del *.hpj
+del *.txt
+del *.tex
+del *.ps
+del nasm.i*
+
+:exit
index c047f1f..f91861b 100644 (file)
@@ -592,6 +592,39 @@ 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-t} The \i\c{-t} option: Enable TASM Compatibility Mode
+
+NASM includes a limited form of compatibility with Borland's TASM.  
+When NASM's -t option is used, the following changes are made:
+
+\b local labels may be prefixed with \c{@@} instead of \c{.}
+
+\b TASM-style response files beginning with \c{@} may be specified on
+the command line.  This is different from the \c{-@resp} style that NASM
+natively supports.
+
+\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 \c{%arg} preprocessor directive is supported which is similar to 
+TASM's ARG directive.
+
+\b \c{%local} preprocessor directive
+
+\b \c{%stacksize} preprocessor directive
+
+\b unprefixed forms of some directives supported (arg, elif, else, 
+endif, if, ifdef, ifdifi, ifndef, include, local)
+
+\b more... 
+
+For more information on the directives, see the section on TASM 
+Compatiblity preprocessor directives in \k{tasmcompat}.
 \S{opt-w} The \i\c{-w} Option: Enable or Disable Assembly \i{Warnings}
 
 NASM can observe many conditions during the course of assembly which
@@ -2585,6 +2618,111 @@ boundary, for example, is a waste of effort. Again, NASM does not
 check that the section's alignment characteristics are sensible for
 the use of \c{ALIGN} or \c{ALIGNB}.
 
+\H{tasmcompat} \i{TASM Compatible Preprocessor Directives}
+
+The following preprocessor directives may only be used when TASM 
+compatibility is turned on using the \c{-t} command line switch 
+(This switch is described in \k{opt-t}.)
+
+\b\c{%arg}  (see \k{arg})
+
+\b\c{%stacksize}  (see \k{stacksize})
+
+\b\c{%local}  (see \k{local})
+
+\S{arg} \i\c{%arg} Directive
+
+The \c{%arg} directive is used to simplify the handling of 
+parameters passed on the stack.  Stack based parameter passing
+is used by many high level languages, including C, C++ and Pascal.  
+
+While NASM comes with macros which attempt to duplicate this 
+functionality (see \k{16cmacro}), the syntax is not particularly 
+convenient to use and is not TASM compatible.  Here is an example 
+which shows the use of \c{%arg} without any external macros:
+
+\c some_function:
+\c           %push mycontext        ; save the current context 
+\c           %stacksize large       ; tell NASM to use bp
+\c           %arg i:word, j_ptr:word
+\c           mov ax,[i]
+\c           mov bx,[j_ptr]
+\c           add ax,[bx]
+\c           ret
+\c           %pop                   ; restore original context 
+
+This is similar to the procedure defined in \k{16cmacro} and adds 
+the value in i to the value pointed to by j_ptr and returns the 
+sum in the ax register.  See \k{pushpop} for an explanation of 
+\c{push} and \c{pop} and the use of context stacks.
+
+\S{stacksize} \i\c{%stacksize} Directive
+
+The \c{%stacksize} directive is used in conjunction with the 
+\c{%arg} (see \k{arg}) and the \c{%local} (see \k{local}) directives.  
+It tells NASM the default size to use for subsequent \c{%arg} and 
+\c{%local} directives.  The \c{%stacksize} directive takes one 
+required argument which is one of \c{flat}, \c{large} or \c{small}.
+
+\c %stacksize flat
+
+This form causes NASM to use stack-based parameter addressing 
+relative to \c{ebp} and it assumes that a near form of call was used
+to get to this label (i.e. that \c{eip} is on the stack).
+
+\c %stacksize large
+
+This form uses \c{bp} to do stack-based parameter addressing and
+assumes that a far form of call was used to get to this address 
+(i.e. that \c{ip} and \c{cs} are on the stack).
+
+\c %stacksize small
+
+This form also uses \c{bp} to address stack parameters, but it is
+different from \c{large} because it also assumes that the old value
+of bp is pushed onto the stack (i.e. it expects an \c{ENTER} 
+instruction).  In other words, it expects that \c{bp}, \c{ip} and 
+\c{cs} are on the top of the stack, underneath any local space which
+may have been allocated by \c{ENTER}.  This form is probably most
+useful when used in combination with the \c{%local} directive 
+(see \k{local}).
+
+\S{local} \i\c{%local} Directive
+
+The \c{%local} directive is used to simplify the use of local
+temporary stack variables allocated in a stack frame.  Automatic
+local variables in C are an example of this kind of variable.  The
+\c{%local} directive is most useful when used with the \c{%stacksize}
+(see \k{stacksize} and is also compatible with the \c{%arg} directive 
+(see \k{arg}).  It allows simplified reference to variables on the
+stack which have been allocated typically by using the \c{ENTER} 
+instruction (see \k{insENTER} for a description of that instruction).
+An example of its use is the following:
+
+\c silly_swap:
+\c           %push mycontext        ; save the current context 
+\c           %stacksize small       ; tell NASM to use bp
+\c           %assign %$localsize 0  ; see text for explanation
+\c           %local old_ax:word, old_dx:word
+\c           enter %$localsize,0    ; see text for explanation
+\c           mov [old_ax],ax        ; swap ax & bx
+\c           mov [old_dx],dx        ; and swap dx & cx
+\c           mov ax,bx
+\c           mov dx,cx
+\c           mov bx,[old_ax]
+\c           mov cx,[old_dx]
+\c           leave                  ; restore old bp
+\c           ret                    ;
+\c           %pop                   ; restore original context 
+
+The \c{%$localsize} variable is used internally by the 
+\c{%local} directive and \e{must} be defined within the 
+current context before the \c{%local} directive may be used.
+Failure to do so will result in one expression syntax error for
+each \c{%local} variable declared.  It then may be used in 
+the construction of an appropriately sized ENTER instruction
+as shown in the example.
+
 \C{directive} \i{Assembler Directives}
 
 NASM, though it attempts to avoid the bureaucracy of assemblers like
@@ -4173,6 +4311,9 @@ directory, is a file \c{c16.mac} of macros. It defines three macros:
 used for C-style procedure definitions, and they automate a lot of
 the work involved in keeping track of the calling convention.
 
+(An alternative, TASM compatible form of \c{arg} is also now built 
+into NASM's preprocessor.  See \k{tasmcompat} for details.)
+
 An example of an assembly function using the macro set is given
 here:
 
@@ -5371,7 +5512,7 @@ The encodings for the various classes of register are:
 \b \i{Segment registers}: \c{ES} is 0, \c{CS} is 1, \c{SS} is 2, \c{DS}
 is 3, \c{FS} is 4, and \c{GS} is 5.
 
-\b \I{floating-point, registers}{Floating-point registers}: \c{ST0}
+\b \I{floating-point, registers}Floating-point registers: \c{ST0}
 is 0, \c{ST1} is 1, \c{ST2} is 2, \c{ST3} is 3, \c{ST4} is 4,
 \c{ST5} is 5, \c{ST6} is 6, and \c{ST7} is 7.
 
@@ -6296,7 +6437,7 @@ of both their operands.
 \c DIVSS xmmreg,memory           ; F3,0F,5E,/r [KATMAI,SSE] 
 \c DIVSS xmmreg,xmmreg           ; ??         [KATMAI,SSE] 
 
-c\{DIVSS}-The DIVSS instructions divide the lowest SP FP numbers 
+\c{DIVSS}-The DIVSS instructions divide the lowest SP FP numbers 
 of both operands; the upper three fields are passed through from xmm1.
 
 
@@ -6404,7 +6545,7 @@ register stack.
 \c{FCHS} negates the number in \c{ST0}: negative numbers become
 positive, and vice versa.
 
-\H{insFCLEX} \i\c{FCLEX}, \{FNCLEX}: Clear Floating-Point Exceptions
+\H{insFCLEX} \i\c{FCLEX}, \c{FNCLEX}: Clear Floating-Point Exceptions
 
 \c FCLEX                         ; 9B DB E2             [8086,FPU]
 \c FNCLEX                        ; DB E2                [8086,FPU]
@@ -7964,7 +8105,7 @@ operation on the 64-bit MMX registers.
 \c OUT DX,AX                     ; o16 EF               [8086]
 \c OUT DX,EAX                    ; o32 EF               [386]
 
-\c{IN} writes the contents of the given source register to the
+\c{OUT} writes the contents of the given source register to the
 specified I/O port. The port number may be specified as an immediate
 value if it is between 0 and 255, and otherwise must be stored in
 \c{DX}. See also \c{IN} (\k{insIN}).
index cc678c5..e167a77 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -6,7 +6,7 @@
 ; redistributable under the licence given in the file "Licence"
 ; distributed in the NASM archive.
 ;
-; Format of file: all four fields must be present on every functional
+; Format of file: All four fields must be present on every functional
 ; line. Hence `void' for no-operand instructions, and `\0' for such
 ; as EQU. If the last three fields are all `ignore', no action is
 ; taken except to register the opcode as being present.
@@ -37,14 +37,14 @@ ADC       rm16,imm8           \320\300\1\x83\202\15         8086
 ADC       rm32,imm8           \321\300\1\x83\202\15         386
 ADC       reg_al,imm          \1\x14\21                     8086,SM
 ADC       reg_ax,imm          \320\1\x15\31                 8086,SM
-ADC       reg_eax,sbyte       \321\1\x83\202\15                  386,ND
+ADC       reg_eax,sbyte       \321\1\x83\202\15             386,ND
 ADC       reg_eax,imm         \321\1\x15\41                 386,SM
 ADC       rm8,imm             \300\1\x80\202\21             8086,SM
-ADC       rm16,imm            \320\300\134\1\x81\202\131         8086,SM,ND
-ADC       rm32,imm            \321\300\144\1\x81\202\141         386,SM,ND
+ADC       rm16,imm            \320\300\134\1\x81\202\131    8086,SM,ND
+ADC       rm32,imm            \321\300\144\1\x81\202\141    386,SM,ND
 ADC       mem,imm8            \300\1\x80\202\21             8086,SM
-ADC       mem,imm16           \320\300\134\1\x81\202\131         8086,SM,ND
-ADC       mem,imm32           \321\300\144\1\x81\202\141         386,SM,ND
+ADC       mem,imm16           \320\300\134\1\x81\202\131    8086,SM,ND
+ADC       mem,imm32           \321\300\144\1\x81\202\141    386,SM,ND
 ADD       mem,reg8            \300\17\101                   8086,SM
 ADD       reg8,reg8           \300\17\101                   8086
 ADD       mem,reg16           \320\300\1\x01\101            8086,SM
@@ -61,14 +61,14 @@ ADD       rm16,imm8           \320\300\1\x83\200\15         8086
 ADD       rm32,imm8           \321\300\1\x83\200\15         386
 ADD       reg_al,imm          \1\x04\21                     8086,SM
 ADD       reg_ax,imm          \320\1\x05\31                 8086,SM
-ADD       reg_eax,sbyte       \321\1\x83\200\15                  386,ND
+ADD       reg_eax,sbyte       \321\1\x83\200\15             386,ND
 ADD       reg_eax,imm         \321\1\x05\41                 386,SM
 ADD       rm8,imm             \300\1\x80\200\21             8086,SM
-ADD       rm16,imm            \320\300\134\1\x81\200\131         8086,SM,ND
-ADD       rm32,imm            \321\300\144\1\x81\200\141         386,SM,ND
+ADD       rm16,imm            \320\300\134\1\x81\200\131    8086,SM,ND
+ADD       rm32,imm            \321\300\144\1\x81\200\141    386,SM,ND
 ADD       mem,imm8            \300\1\x80\200\21             8086,SM
-ADD       mem,imm16           \320\300\134\1\x81\200\131         8086,SM,ND
-ADD       mem,imm32           \321\300\144\1\x81\200\141         386,SM,ND
+ADD       mem,imm16           \320\300\134\1\x81\200\131    8086,SM,ND
+ADD       mem,imm32           \321\300\144\1\x81\200\141    386,SM,ND
 AND       mem,reg8            \300\1\x20\101                8086,SM
 AND       reg8,reg8           \300\1\x20\101                8086
 AND       mem,reg16           \320\300\1\x21\101            8086,SM
@@ -85,14 +85,14 @@ AND       rm16,imm8           \320\300\1\x83\204\15         8086
 AND       rm32,imm8           \321\300\1\x83\204\15         386
 AND       reg_al,imm          \1\x24\21                     8086,SM
 AND       reg_ax,imm          \320\1\x25\31                 8086,SM
-AND       reg_eax,sbyte       \321\1\x83\204\15                  386,ND
+AND       reg_eax,sbyte       \321\1\x83\204\15             386,ND
 AND       reg_eax,imm         \321\1\x25\41                 386,SM
 AND       rm8,imm             \300\1\x80\204\21             8086,SM
-AND       rm16,imm            \320\300\134\1\x81\204\131         8086,SM,ND
-AND       rm32,imm            \321\300\144\1\x81\204\141         386,SM,ND
+AND       rm16,imm            \320\300\134\1\x81\204\131    8086,SM,ND
+AND       rm32,imm            \321\300\144\1\x81\204\141    386,SM,ND
 AND       mem,imm8            \300\1\x80\204\21             8086,SM
-AND       mem,imm16           \320\300\134\1\x81\204\131         8086,SM,ND
-AND       mem,imm32           \321\300\144\1\x81\204\141         386,SM,ND
+AND       mem,imm16           \320\300\134\1\x81\204\131    8086,SM,ND
+AND       mem,imm32           \321\300\144\1\x81\204\141    386,SM,ND
 ARPL      mem,reg16           \300\1\x63\101                286,PROT,SM
 ARPL      reg16,reg16         \300\1\x63\101                286,PROT
 BOUND     reg16,mem           \320\301\1\x62\110            186
@@ -178,14 +178,14 @@ CMP       rm16,imm8           \320\300\1\x83\207\15         8086
 CMP       rm32,imm8           \321\300\1\x83\207\15         386
 CMP       reg_al,imm          \1\x3C\21                     8086,SM
 CMP       reg_ax,imm          \320\1\x3D\31                 8086,SM
-CMP       reg_eax,sbyte       \321\1\x83\207\15                  386,ND
+CMP       reg_eax,sbyte       \321\1\x83\207\15             386,ND
 CMP       reg_eax,imm         \321\1\x3D\41                 386,SM
 CMP       rm8,imm             \300\1\x80\207\21             8086,SM
-CMP       rm16,imm            \320\300\134\1\x81\207\131         8086,SM,ND
-CMP       rm32,imm            \321\300\144\1\x81\207\141         386,SM,ND
+CMP       rm16,imm            \320\300\134\1\x81\207\131    8086,SM,ND
+CMP       rm32,imm            \321\300\144\1\x81\207\141    386,SM,ND
 CMP       mem,imm8            \300\1\x80\207\21             8086,SM
-CMP       mem,imm16           \320\300\134\1\x81\207\131         8086,SM,ND
-CMP       mem,imm32           \321\300\144\1\x81\207\141         386,SM,ND
+CMP       mem,imm16           \320\300\134\1\x81\207\131    8086,SM,ND
+CMP       mem,imm32           \321\300\144\1\x81\207\141    386,SM,ND
 CMPSB     void                \332\1\xA6                    8086
 CMPSD     void                \332\321\1\xA7                386
 CMPSW     void                \332\320\1\xA7                8086
@@ -424,16 +424,16 @@ IMUL      reg32,mem           \321\301\2\x0F\xAF\110        386,SM
 IMUL      reg32,reg32         \321\2\x0F\xAF\110            386
 IMUL      reg16,mem,imm8      \320\301\1\x6B\110\16         186,SM
 IMUL      reg16,reg16,imm8    \320\301\1\x6B\110\16         186
-IMUL      reg16,mem,imm       \320\301\135\1\x69\110\132         186,SM
-IMUL      reg16,reg16,imm     \320\135\1\x69\110\132             186,SM
+IMUL      reg16,mem,imm       \320\301\135\1\x69\110\132    186,SM
+IMUL      reg16,reg16,imm     \320\135\1\x69\110\132        186,SM
 IMUL      reg32,mem,imm8      \321\301\1\x6B\110\16         386,SM
 IMUL      reg32,reg32,imm8    \321\1\x6B\110\16             386
-IMUL      reg32,mem,imm       \321\301\145\1\x69\110\142         386,SM
-IMUL      reg32,reg32,imm     \321\145\1\x69\110\142             386,SM
+IMUL      reg32,mem,imm       \321\301\145\1\x69\110\142    386,SM
+IMUL      reg32,reg32,imm     \321\145\1\x69\110\142        386,SM
 IMUL      reg16,imm8          \320\1\x6B\100\15             186
-IMUL      reg16,imm           \320\134\1\x69\100\131             186,SM
+IMUL      reg16,imm           \320\134\1\x69\100\131        186,SM
 IMUL      reg32,imm8          \321\1\x6B\100\15             386
-IMUL      reg32,imm           \321\144\1\x69\100\141             386,SM
+IMUL      reg32,imm           \321\144\1\x69\100\141        386,SM
 IN        reg_al,imm          \1\xE4\25                     8086,SB
 IN        reg_ax,imm          \320\1\xE5\25                 8086,SB
 IN        reg_eax,imm         \321\1\xE5\25                 386,SB
@@ -463,7 +463,7 @@ IRETW     void                \320\1\xCF                    8086
 JCXZ      imm                 \310\1\xE3\50                 8086
 JECXZ     imm                 \311\1\xE3\50                 386
 JMP       imm|short           \1\xEB\50                     8086
-JMP       imm                 \370\1\xEB\50                     8086,ND
+JMP       imm                 \370\1\xEB\50                 8086,ND
 JMP       imm                 \322\1\xE9\64                 8086
 JMP       imm|near            \322\1\xE9\64                 8086,ND
 JMP       imm|far             \322\1\xEA\34\37              8086,ND
@@ -542,21 +542,21 @@ LSS       reg32,mem           \321\301\2\x0F\xB2\110        386
 LTR       mem                 \300\1\x0F\17\203             286,PROT,PRIV
 LTR       mem16               \300\1\x0F\17\203             286,PROT,PRIV
 LTR       reg16               \300\1\x0F\17\203             286,PROT,PRIV
-MOV       mem,reg_cs          \320\300\1\x8C\201            8086,SM
-MOV       mem,reg_dess        \320\300\1\x8C\101            8086,SM
-MOV       mem,reg_fsgs        \320\300\1\x8C\101            386,SM
+MOV       mem,reg_cs          \300\1\x8C\201                   8086,SM
+MOV       mem,reg_dess        \300\1\x8C\101                           8086,SM
+MOV       mem,reg_fsgs        \300\1\x8C\101                           386,SM
 MOV       reg16,reg_cs        \320\300\1\x8C\201            8086
 MOV       reg16,reg_dess      \320\300\1\x8C\101            8086
 MOV       reg16,reg_fsgs      \320\300\1\x8C\101            386
-MOV       rm32,reg_cs         \321\300\1\x8C\201            8086
-MOV       rm32,reg_dess       \321\300\1\x8C\101            8086
-MOV       rm32,reg_fsgs       \321\300\1\x8C\101            386
-MOV       reg_dess,mem        \320\301\1\x8E\110            8086,SM
-MOV       reg_fsgs,mem        \320\301\1\x8E\110            386,SM
-MOV       reg_dess,reg16      \320\301\1\x8E\110            8086
-MOV       reg_fsgs,reg16      \320\301\1\x8E\110            386
-MOV       reg_dess,rm32       \321\301\1\x8E\110            8086
-MOV       reg_fsgs,rm32       \321\301\1\x8E\110            386
+MOV       reg32,reg_cs        \321\300\1\x8C\201            8086
+MOV       reg32,reg_dess      \321\300\1\x8C\101            8086
+MOV       reg32,reg_fsgs      \321\300\1\x8C\101            386
+MOV       reg_dess,mem        \301\1\x8E\110                8086,SM
+MOV       reg_fsgs,mem        \301\1\x8E\110                386,SM
+MOV       reg_dess,reg16      \301\1\x8E\110                8086
+MOV       reg_fsgs,reg16      \301\1\x8E\110                386
+MOV       reg_dess,reg32      \301\1\x8E\110                8086
+MOV       reg_fsgs,reg32      \301\1\x8E\110                386
 MOV       reg_al,mem_offs     \301\1\xA0\35                 8086,SM
 MOV       reg_ax,mem_offs     \301\320\1\xA1\35             8086,SM
 MOV       reg_eax,mem_offs    \301\321\1\xA1\35             386,SM
@@ -637,14 +637,14 @@ OR        rm16,imm8           \320\300\1\x83\201\15         8086
 OR        rm32,imm8           \321\300\1\x83\201\15         386
 OR        reg_al,imm          \1\x0C\21                     8086,SM
 OR        reg_ax,imm          \320\1\x0D\31                 8086,SM
-OR        reg_eax,sbyte       \321\1\x83\201\15                  386,ND
+OR        reg_eax,sbyte       \321\1\x83\201\15             386,ND
 OR        reg_eax,imm         \321\1\x0D\41                 386,SM
 OR        rm8,imm             \300\1\x80\201\21             8086,SM
-OR        rm16,imm            \320\300\134\1\x81\201\131         8086,SM,ND
-OR        rm32,imm            \321\300\144\1\x81\201\141         386,SM,ND
+OR        rm16,imm            \320\300\134\1\x81\201\131    8086,SM,ND
+OR        rm32,imm            \321\300\144\1\x81\201\141    386,SM,ND
 OR        mem,imm8            \300\1\x80\201\21             8086,SM
-OR        mem,imm16           \320\300\134\1\x81\201\131         8086,SM,ND
-OR        mem,imm32           \321\300\144\1\x81\201\141         386,SM,ND
+OR        mem,imm16           \320\300\134\1\x81\201\131    8086,SM,ND
+OR        mem,imm32           \321\300\144\1\x81\201\141    386,SM,ND
 OUT       imm,reg_al          \1\xE6\24                     8086,SB
 OUT       imm,reg_ax          \320\1\xE7\24                 8086,SB
 OUT       imm,reg_eax         \321\1\xE7\24                 386,SB
@@ -888,8 +888,8 @@ ROR       rm16,imm            \320\300\1\xC1\201\25         186,SB
 ROR       rm32,unity          \321\300\1\xD1\201            386
 ROR       rm32,reg_cl         \321\300\1\xD3\201            386
 ROR       rm32,imm            \321\300\1\xC1\201\25         386,SB
-RSDC      reg_sreg,mem80      \301\2\x0F\x79\110           486,CYRIX,SMM
-RSLDT     mem80               \300\2\x0F\x7B\200           486,CYRIX,SMM
+RSDC      reg_sreg,mem80      \301\2\x0F\x79\110            486,CYRIX,SMM
+RSLDT     mem80               \300\2\x0F\x7B\200            486,CYRIX,SMM
 RSM       void                \2\x0F\xAA                    PENT,SMM
 RSTS      mem80               \300\2\x0F\x7D\200            486,CYRIX,SMM
 SAHF      void                \1\x9E                        8086
@@ -928,14 +928,14 @@ SBB       rm16,imm8           \320\300\1\x83\203\15         8086
 SBB       rm32,imm8           \321\300\1\x83\203\15         8086
 SBB       reg_al,imm          \1\x1C\21                     8086,SM
 SBB       reg_ax,imm          \320\1\x1D\31                 8086,SM
-SBB       reg_eax,sbyte       \321\1\x83\203\15                  386,ND
+SBB       reg_eax,sbyte       \321\1\x83\203\15             386,ND
 SBB       reg_eax,imm         \321\1\x1D\41                 386,SM
 SBB       rm8,imm             \300\1\x80\203\21             8086,SM
-SBB       rm16,imm            \320\300\134\1\x81\203\131         8086,SM,ND
-SBB       rm32,imm            \321\300\144\1\x81\203\141         386,SM,ND
+SBB       rm16,imm            \320\300\134\1\x81\203\131    8086,SM,ND
+SBB       rm32,imm            \321\300\144\1\x81\203\141    386,SM,ND
 SBB       mem,imm8            \300\1\x80\203\21             8086,SM
-SBB       mem,imm16           \320\300\134\1\x81\203\131         8086,SM,ND
-SBB       mem,imm32           \321\300\144\1\x81\203\141         386,SM,ND
+SBB       mem,imm16           \320\300\134\1\x81\203\131    8086,SM,ND
+SBB       mem,imm32           \321\300\144\1\x81\203\141    386,SM,ND
 SCASB     void                \332\1\xAE                    8086
 SCASD     void                \332\321\1\xAF                386
 SCASW     void                \332\320\1\xAF                8086
@@ -1010,21 +1010,21 @@ SUB       rm16,imm8           \320\300\1\x83\205\15         8086
 SUB       rm32,imm8           \321\300\1\x83\205\15         386
 SUB       reg_al,imm          \1\x2C\21                     8086,SM
 SUB       reg_ax,imm          \320\1\x2D\31                 8086,SM
-SUB       reg_eax,sbyte       \321\1\x83\205\15                  386,ND
+SUB       reg_eax,sbyte       \321\1\x83\205\15             386,ND
 SUB       reg_eax,imm         \321\1\x2D\41                 386,SM
 SUB       rm8,imm             \300\1\x80\205\21             8086,SM
-SUB       rm16,imm            \320\300\134\1\x81\205\131         8086,SM,ND
-SUB       rm32,imm            \321\300\144\1\x81\205\141         386,SM,ND
+SUB       rm16,imm            \320\300\134\1\x81\205\131    8086,SM,ND
+SUB       rm32,imm            \321\300\144\1\x81\205\141    386,SM,ND
 SUB       mem,imm8            \300\1\x80\205\21             8086,SM
-SUB       mem,imm16           \320\300\134\1\x81\205\131         8086,SM,ND
-SUB       mem,imm32           \321\300\144\1\x81\205\141         386,SM,ND
-SVDC     mem80,reg_sreg      \300\2\x0F\x78\101            486,CYRIX,SMM
+SUB       mem,imm16           \320\300\134\1\x81\205\131    8086,SM,ND
+SUB       mem,imm32           \321\300\144\1\x81\205\141    386,SM,ND
+SVDC      mem80,reg_sreg      \300\2\x0F\x78\101            486,CYRIX,SMM
 SVLDT     mem80               \300\2\x0F\x7A\200            486,CYRIX,SMM
 SVTS      mem80               \300\2\x0F\x7C\200            486,CYRIX,SMM
 SYSCALL   void                \2\x0F\x05                    P6,AMD
 SYSENTER  void                \2\x0F\x34                    P6
 SYSEXIT   void                \2\x0F\x36                    P6,PRIV
-SYSRET    void               \2\x0F\x07                    P6,PRIV,AMD
+SYSRET    void                \2\x0F\x07                    P6,PRIV,AMD
 TEST      mem,reg8            \300\1\x84\101                8086,SM
 TEST      reg8,reg8           \300\1\x84\101                8086
 TEST      mem,reg16           \320\300\1\x85\101            8086,SM
@@ -1112,14 +1112,14 @@ XOR       rm16,imm8           \320\300\1\x83\206\15         8086
 XOR       rm32,imm8           \321\300\1\x83\206\15         386
 XOR       reg_al,imm          \1\x34\21                     8086,SM
 XOR       reg_ax,imm          \320\1\x35\31                 8086,SM
-XOR       reg_eax,sbyte       \321\1\x83\206\15                  386,ND
+XOR       reg_eax,sbyte       \321\1\x83\206\15             386,ND
 XOR       reg_eax,imm         \321\1\x35\41                 386,SM
 XOR       rm8,imm             \300\1\x80\206\21             8086,SM
-XOR       rm16,imm            \320\300\134\1\x81\206\131         8086,SM,ND
-XOR       rm32,imm            \321\300\144\1\x81\206\141         386,SM,ND
+XOR       rm16,imm            \320\300\134\1\x81\206\131    8086,SM,ND
+XOR       rm32,imm            \321\300\144\1\x81\206\141    386,SM,ND
 XOR       mem,imm8            \300\1\x80\206\21             8086,SM
-XOR       mem,imm16           \320\300\134\1\x81\206\131         8086,SM,ND
-XOR       mem,imm32           \321\300\144\1\x81\206\141         386,SM,ND
+XOR       mem,imm16           \320\300\134\1\x81\206\131    8086,SM,ND
+XOR       mem,imm32           \321\300\144\1\x81\206\141    386,SM,ND
 CMOVcc    reg16,mem           \320\301\1\x0F\330\x40\110    P6,SM
 CMOVcc    reg16,reg16         \320\301\1\x0F\330\x40\110    P6
 CMOVcc    reg32,mem           \321\301\1\x0F\330\x40\110    P6,SM
@@ -1128,9 +1128,9 @@ Jcc       imm|near            \322\1\x0F\330\x80\64         386
 Jcc       imm16|near          \320\1\x0F\330\x80\64         386
 Jcc       imm32|near          \321\1\x0F\330\x80\64         386
 Jcc       imm|short           \330\x70\50                   8086,ND
-Jcc       imm                 \370\330\x70\50                   8086,ND
-Jcc       imm                 \1\x0F\330\x80\64                 386,ND
-Jcc       imm                 \330\x71\373\1\xE9\64            8086,ND
+Jcc       imm                 \370\330\x70\50               8086,ND
+Jcc       imm                 \1\x0F\330\x80\64             386,ND
+Jcc       imm                 \330\x71\373\1\xE9\64         8086,ND
 Jcc       imm                 \330\x70\50                   8086
 SETcc     mem                 \300\1\x0F\330\x90\200        386,SB
 SETcc     reg8                \300\1\x0F\330\x90\200        386
@@ -1177,11 +1177,11 @@ CMPUNORDPS      xmmreg,xmmreg           \331\2\x0F\xC2\110\1\x03        KATMAI,S
 CMPUNORDSS      xmmreg,mem              \301\333\2\x0F\xC2\110\1\x03    KATMAI,SSE
 CMPUNORDSS      xmmreg,xmmreg           \333\2\x0F\xC2\110\1\x03        KATMAI,SSE
 ; CMPPS/CMPSS must come after the specific ops; that way the disassembler will find the
-; specific ops first and only disassemble illegal ones as cmpps.
-CMPPS          xmmreg,mem,imm          \301\331\2\x0F\xC2\110\22       KATMAI,SSE,SB,AR2
-CMPPS          xmmreg,xmmreg,imm       \331\2\x0F\xC2\110\22           KATMAI,SSE,SB,AR2
-CMPSS          xmmreg,mem,imm          \301\333\2\x0F\xC2\110\22       KATMAI,SSE,SB,AR2
-CMPSS          xmmreg,xmmreg,imm       \333\2\x0F\xC2\110\22           KATMAI,SSE,SB,AR2
+; specific ops first and only disassemble illegal ones as cmpps/cmpss.
+CMPPS           xmmreg,mem,imm          \301\331\2\x0F\xC2\110\26       KATMAI,SSE,SB,AR2
+CMPPS           xmmreg,xmmreg,imm       \331\2\x0F\xC2\110\26           KATMAI,SSE,SB,AR2
+CMPSS           xmmreg,mem,imm          \301\333\2\x0F\xC2\110\26       KATMAI,SSE,SB,AR2
+CMPSS           xmmreg,xmmreg,imm       \333\2\x0F\xC2\110\26           KATMAI,SSE,SB,AR2
 COMISS          xmmreg,mem              \301\2\x0F\x2F\110              KATMAI,SSE
 COMISS          xmmreg,xmmreg           \2\x0F\x2F\110                  KATMAI,SSE
 CVTPI2PS        xmmreg,mem              \301\331\2\x0F\x2A\110          KATMAI,SSE,MMX
@@ -1222,7 +1222,7 @@ MOVLPS          mem,xmmreg              \300\2\x0F\x13\101              KATMAI,S
 MOVLPS          xmmreg,xmmreg           \2\x0F\x12\101                  KATMAI,SSE,ND
 MOVHLPS         xmmreg,xmmreg           \2\x0F\x12\110                  KATMAI,SSE
 MOVMSKPS        reg32,xmmreg            \2\x0F\x50\110                  KATMAI,SSE
-MOVNTPS         mem,xmmreg              \2\x0F\x2B\101                  KATMAI,SSE
+MOVNTPS         mem,xmmreg              \300\2\x0F\x2B\101              KATMAI,SSE
 MOVSS           xmmreg,mem              \301\333\2\x0F\x10\110          KATMAI,SSE
 MOVSS           mem,xmmreg              \300\333\2\x0F\x11\101          KATMAI,SSE
 MOVSS           xmmreg,xmmreg           \333\2\x0F\x10\110              KATMAI,SSE
@@ -1245,8 +1245,8 @@ RSQRTPS         xmmreg,mem              \301\331\2\x0F\x52\110          KATMAI,S
 RSQRTPS         xmmreg,xmmreg           \331\2\x0F\x52\110              KATMAI,SSE
 RSQRTSS         xmmreg,mem              \301\333\2\x0F\x52\110          KATMAI,SSE
 RSQRTSS         xmmreg,xmmreg           \333\2\x0F\x52\110              KATMAI,SSE
-SHUFPS         xmmreg,mem,imm          \301\2\x0F\xC6\110\22           KATMAI,SSE,SB,AR2
-SHUFPS          xmmreg,xmmreg,imm       \2\x0F\xC6\110\22               KATMAI,SSE,SB,AR2
+SHUFPS          xmmreg,mem,imm          \301\2\x0F\xC6\110\26           KATMAI,SSE,SB,AR2
+SHUFPS          xmmreg,xmmreg,imm       \2\x0F\xC6\110\26               KATMAI,SSE,SB,AR2
 SQRTPS          xmmreg,mem              \301\331\2\x0F\x51\110          KATMAI,SSE
 SQRTPS          xmmreg,xmmreg           \331\2\x0F\x51\110              KATMAI,SSE
 SQRTSS          xmmreg,mem              \301\333\2\x0F\x51\110          KATMAI,SSE
@@ -1265,11 +1265,11 @@ UNPCKLPS        xmmreg,xmmreg           \2\x0F\x14\110                  KATMAI,S
 XORPS           xmmreg,mem              \301\2\x0F\x57\110              KATMAI,SSE
 XORPS           xmmreg,xmmreg           \2\x0F\x57\110                  KATMAI,SSE
 
-; Introduced in Dechutes but necessary for SSE support
+; Introduced in Deschutes but necessary for SSE support
 FXRSTOR         mem                     \300\2\x0F\xAE\201              P6,SSE,FPU
 FXSAVE          mem                     \300\2\x0F\xAE\200              P6,SSE,FPU
 
-; These instructions aren't SSE-specific; they are generic memory operations
+; These instructions are not SSE-specific; they are generic memory operations
 ; and work even if CR4.OSFXFR == 0
 PREFETCHNTA     mem                     \300\2\x0F\x18\200              KATMAI
 PREFETCHT0      mem                     \300\2\x0F\x18\201              KATMAI
@@ -1278,307 +1278,351 @@ PREFETCHT2      mem                     \300\2\x0F\x18\203              KATMAI
 SFENCE          void                    \3\x0F\xAE\xF8                  KATMAI
 
 ; New MMX instructions introduced in Katmai
-MASKMOVQ        mmxreg,mmxreg          \2\x0F\xF7\110                  KATMAI,MMX
-MOVNTQ          mem,mmxreg              \2\x0F\xE7\101                  KATMAI,MMX,SM
-PAVGB           mmxreg,mmxreg          \2\x0F\xE0\110                  KATMAI,MMX
-PAVGB           mmxreg,mem             \301\2\x0F\xE0\110              KATMAI,MMX,SM
-PAVGW           mmxreg,mmxreg          \2\x0F\xE3\110                  KATMAI,MMX
-PAVGW           mmxreg,mem             \301\2\x0F\xE3\110              KATMAI,MMX,SM
-PEXTRW          reg32,mmxreg,imm       \2\x0F\xC5\110\22               KATMAI,MMX,SB,AR2
+MASKMOVQ        mmxreg,mmxreg           \2\x0F\xF7\110                  KATMAI,MMX
+MOVNTQ          mem,mmxreg              \300\2\x0F\xE7\101              KATMAI,MMX,SM
+PAVGB           mmxreg,mmxreg           \2\x0F\xE0\110                  KATMAI,MMX
+PAVGB           mmxreg,mem              \301\2\x0F\xE0\110              KATMAI,MMX,SM
+PAVGW           mmxreg,mmxreg           \2\x0F\xE3\110                  KATMAI,MMX
+PAVGW           mmxreg,mem              \301\2\x0F\xE3\110              KATMAI,MMX,SM
+PEXTRW          reg32,mmxreg,imm        \2\x0F\xC5\110\26               KATMAI,MMX,SB,AR2
 ; PINSRW is documented as using a reg32, but it's really using only 16 bit
 ; -- accept either, but be truthful in disassembly
-PINSRW          mmxreg,reg16,imm       \2\x0F\xC4\110\22               KATMAI,MMX,SB,AR2
-PINSRW          mmxreg,reg32,imm       \2\x0F\xC4\110\22               KATMAI,MMX,SB,AR2,ND
-PINSRW         mmxreg,mem,imm          \301\2\x0F\xC4\110\22           KATMAI,MMX,SB,AR2
-PINSRW          mmxreg,mem16,imm       \301\2\x0F\xC4\110\22           KATMAI,MMX,SB,AR2,ND
-PMAXSW          mmxreg,mmxreg          \2\x0F\xEE\110                  KATMAI,MMX
-PMAXSW         mmxreg,mem              \301\2\x0F\xEE\110              KATMAI,MMX,SM
-PMAXUB          mmxreg,mmxreg          \2\x0F\xDE\110                  KATMAI,MMX
-PMAXUB         mmxreg,mem              \301\2\x0F\xDE\110              KATMAI,MMX,SM
-PMINSW          mmxreg,mmxreg          \2\x0F\xEA\110                  KATMAI,MMX
-PMINSW         mmxreg,mem              \301\2\x0F\xEA\110              KATMAI,MMX,SM
-PMINUB          mmxreg,mmxreg          \2\x0F\xDA\110                  KATMAI,MMX
-PMINUB         mmxreg,mem              \301\2\x0F\xDA\110              KATMAI,MMX,SM
-PMOVMSKB        reg32,mmxreg           \2\x0F\xD7\110                  KATMAI,MMX
-PMULHUW         mmxreg,mmxreg          \2\x0F\xE4\110                  KATMAI,MMX
-PMULHUW                mmxreg,mem              \301\2\x0F\xE4\110              KATMAI,MMX,SM
-PSADBW          mmxreg,mmxreg          \2\x0F\xF6\110                  KATMAI,MMX
-PSADBW                 mmxreg,mem              \301\2\x0F\xF6\110              KATMAI,MMX,SM
-PSHUFW          mmxreg,mmxreg,imm      \2\x0F\x70\110\22               KATMAI,MMX,SB,AR2
-PSHUFW          mmxreg,mem,imm         \301\2\x0F\x70\110\22           KATMAI,MMX,SM2,SB,AR2
+PINSRW          mmxreg,reg16,imm        \2\x0F\xC4\110\26               KATMAI,MMX,SB,AR2
+PINSRW          mmxreg,reg32,imm        \2\x0F\xC4\110\26               KATMAI,MMX,SB,AR2,ND
+PINSRW          mmxreg,mem,imm          \301\2\x0F\xC4\110\26           KATMAI,MMX,SB,AR2
+PINSRW          mmxreg,mem16,imm        \301\2\x0F\xC4\110\26           KATMAI,MMX,SB,AR2,ND
+PMAXSW          mmxreg,mmxreg           \2\x0F\xEE\110                  KATMAI,MMX
+PMAXSW          mmxreg,mem              \301\2\x0F\xEE\110              KATMAI,MMX,SM
+PMAXUB          mmxreg,mmxreg           \2\x0F\xDE\110                  KATMAI,MMX
+PMAXUB          mmxreg,mem              \301\2\x0F\xDE\110              KATMAI,MMX,SM
+PMINSW          mmxreg,mmxreg           \2\x0F\xEA\110                  KATMAI,MMX
+PMINSW          mmxreg,mem              \301\2\x0F\xEA\110              KATMAI,MMX,SM
+PMINUB          mmxreg,mmxreg           \2\x0F\xDA\110                  KATMAI,MMX
+PMINUB          mmxreg,mem              \301\2\x0F\xDA\110              KATMAI,MMX,SM
+PMOVMSKB        reg32,mmxreg            \2\x0F\xD7\110                  KATMAI,MMX
+PMULHUW         mmxreg,mmxreg           \2\x0F\xE4\110                  KATMAI,MMX
+PMULHUW         mmxreg,mem              \301\2\x0F\xE4\110              KATMAI,MMX,SM
+PSADBW          mmxreg,mmxreg           \2\x0F\xF6\110                  KATMAI,MMX
+PSADBW          mmxreg,mem              \301\2\x0F\xF6\110              KATMAI,MMX,SM
+PSHUFW          mmxreg,mmxreg,imm       \2\x0F\x70\110\22               KATMAI,MMX,SB,AR2
+PSHUFW          mmxreg,mem,imm          \301\2\x0F\x70\110\22           KATMAI,MMX,SM2,SB,AR2
 
-; The five new Athlon instructions
-PF2IW     mmxreg,mem          \301\2\x0F\x0F\110\01\x1C     PENT,3DNOW,SM
-PF2IW     mmxreg,mmxreg       \2\x0F\x0F\110\01\x1C         PENT,3DNOW
-PFNACC    mmxreg,mem          \301\2\x0F\x0F\110\01\x8A     PENT,3DNOW,SM
-PFNACC    mmxreg,mmxreg       \2\x0F\x0F\110\01\x8A         PENT,3DNOW
-PFPNACC   mmxreg,mem          \301\2\x0F\x0F\110\01\x8E     PENT,3DNOW,SM
-PFPNACC   mmxreg,mmxreg       \2\x0F\x0F\110\01\x8E         PENT,3DNOW
-PI2FW     mmxreg,mem          \301\2\x0F\x0F\110\01\x0C     PENT,3DNOW,SM
-PI2FW     mmxreg,mmxreg       \2\x0F\x0F\110\01\x0C         PENT,3DNOW
-PSWAPD    mmxreg,mem          \301\2\x0F\x0F\110\01\xBB     PENT,3DNOW,SM
-PSWAPD    mmxreg,mmxreg       \2\x0F\x0F\110\01\xBB         PENT,3DNOW
+; AMD Enhanced 3DNow! (Athlon) instructions
+PF2IW           mmxreg,mem              \301\2\x0F\x0F\110\01\x1C       PENT,3DNOW,SM
+PF2IW           mmxreg,mmxreg           \2\x0F\x0F\110\01\x1C           PENT,3DNOW
+PFNACC          mmxreg,mem              \301\2\x0F\x0F\110\01\x8A       PENT,3DNOW,SM
+PFNACC          mmxreg,mmxreg           \2\x0F\x0F\110\01\x8A           PENT,3DNOW
+PFPNACC         mmxreg,mem              \301\2\x0F\x0F\110\01\x8E       PENT,3DNOW,SM
+PFPNACC         mmxreg,mmxreg           \2\x0F\x0F\110\01\x8E           PENT,3DNOW
+PI2FW           mmxreg,mem              \301\2\x0F\x0F\110\01\x0C       PENT,3DNOW,SM
+PI2FW           mmxreg,mmxreg           \2\x0F\x0F\110\01\x0C           PENT,3DNOW
+PSWAPD          mmxreg,mem              \301\2\x0F\x0F\110\01\xBB       PENT,3DNOW,SM
+PSWAPD          mmxreg,mmxreg           \2\x0F\x0F\110\01\xBB           PENT,3DNOW
 
-; Introduced in Willamette
-; opcode       parameters                              assembly                                range
-MASKMOVDQU     xmmreg,xmmreg                   \3\x66\x0F\xF7                  WILLAMETTE      
-CLFLUSH        mem                                     \2\x0F\xAE                              WILLAMETTE
-MOVNTDQ        xmmreg,mem                              \3\x66\x0F\xEF                  WILLAMETTE
-MOVNTI         reg32,mem                               \2\x0F\xC3                              WILLAMETTE
-PAUSE          void                                    \2\xF3\x90                              WILLAMETTE
-LFENCE         void                                    \3\x0F\xAE\xF8                  WILLAMETTE
-MFENCE         void                                    \3\x0F\xAE\xF8                  WILLAMETTE
+; Willamette SSE2 Cacheability Instructions
+MASKMOVDQU      xmmreg,xmmreg           \3\x66\x0F\xF7\110              WILLAMETTE,SSE2
+; CLFLUSH needs its own feature flag implemented one day
+CLFLUSH         mem                     \300\2\x0F\xAE\207              WILLAMETTE,SSE2
+MOVNTDQ         mem,xmmreg              \300\3\x66\x0F\xE7\101          WILLAMETTE,SSE2,SM
+MOVNTI          mem,reg32               \300\2\x0F\xC3\101              WILLAMETTE,SSE2,SM
+MOVNTPD         mem,xmmreg              \300\3\x66\x0F\x2B\101          WILLAMETTE,SSE2,SM
+PAUSE           void                    \333\1\x90                      WILLAMETTE,SSE2
+LFENCE          void                    \3\x0F\xAE\xE8                  WILLAMETTE,SSE2
+MFENCE          void                    \3\x0F\xAE\xF0                  WILLAMETTE,SSE2
+
+; Willamette MMX instructions (SSE2 SIMD Integer Instructions)
+MOVD            xmmreg,reg32            \3\x66\x0F\x6E\110              WILLAMETTE,SSE2
+MOVD            reg32,xmmreg            \3\x66\x0F\x7E\101              WILLAMETTE,SSE2
+MOVD            mem,xmmreg              \300\3\x66\x0F\x7E\101          WILLAMETTE,SSE2
+MOVD            xmmreg,mem              \301\3\x66\x0F\x6E\110          WILLAMETTE,SSE2
+MOVDQA          xmmreg,xmmreg           \3\x66\x0F\x6F\110              WILLAMETTE,SSE2
+MOVDQA          mem,xmmreg              \300\3\x66\x0F\x7F\101          WILLAMETTE,SSE2,SM
+MOVDQA          xmmreg,mem              \301\3\x66\x0F\x6F\110          WILLAMETTE,SSE2,SM
+MOVDQA          xmmreg,xmmreg           \3\x66\x0F\x7F\110              WILLAMETTE,SSE2
+MOVDQU          xmmreg,xmmreg           \333\2\x0F\x6F\110              WILLAMETTE,SSE2
+MOVDQU          mem,xmmreg              \333\300\2\x0F\x7F\101          WILLAMETTE,SSE2,SM
+MOVDQU          xmmreg,mem              \301\333\2\x0F\x6F\110          WILLAMETTE,SSE2,SM
+MOVDQU          xmmreg,xmmreg           \333\2\x0F\x7F\110              WILLAMETTE,SSE2
+MOVDQ2Q         mmxreg,xmmreg           \3\xF2\x0F\xD6\110              WILLAMETTE,SSE2
+MOVQ            xmmreg,xmmreg           \333\2\x0F\x7E\110              WILLAMETTE,SSE2
+MOVQ            xmmreg,xmmreg           \3\x66\x0F\xD6\110              WILLAMETTE,SSE2
+MOVQ            mem,xmmreg              \300\3\x66\x0F\xD6\101          WILLAMETTE,SSE2
+MOVQ            xmmreg,mem              \301\333\2\x0F\x7E\110          WILLAMETTE,SSE2
+MOVQ2DQ         xmmreg,mmxreg           \333\2\x0F\xD6\110              WILLAMETTE,SSE2
+PACKSSWB        xmmreg,xmmreg           \3\x66\x0F\x63\110              WILLAMETTE,SSE2
+PACKSSWB        xmmreg,mem              \301\3\x66\x0F\x63\110          WILLAMETTE,SSE2,SM
+PACKSSDW        xmmreg,xmmreg           \3\x66\x0F\x6B\110              WILLAMETTE,SSE2
+PACKSSDW        xmmreg,mem              \301\3\x66\x0F\x6B\110          WILLAMETTE,SSE2,SM
+PACKUSWB        xmmreg,xmmreg           \3\x66\x0F\x67\110              WILLAMETTE,SSE2
+PACKUSWB        xmmreg,mem              \301\3\x66\x0F\x67\110          WILLAMETTE,SSE2,SM
+PADDB           xmmreg,xmmreg           \3\x66\x0F\xFC\110              WILLAMETTE,SSE2
+PADDB           xmmreg,mem              \301\3\x66\x0F\xFC\110          WILLAMETTE,SSE2,SM
+PADDW           xmmreg,xmmreg           \3\x66\x0F\xFD\110              WILLAMETTE,SSE2
+PADDW           xmmreg,mem              \301\3\x66\x0F\xFD\110          WILLAMETTE,SSE2,SM
+PADDD           xmmreg,xmmreg           \3\x66\x0F\xFE\110              WILLAMETTE,SSE2
+PADDD           xmmreg,mem              \301\3\x66\x0F\xFE\110          WILLAMETTE,SSE2,SM
+PADDQ           mmxreg,mmxreg           \2\x0F\xD4\110                  WILLAMETTE,SSE2
+PADDQ           mmxreg,mem              \301\2\x0F\xD4\110              WILLAMETTE,SSE2,SM
+PADDQ           xmmreg,xmmreg           \3\x66\x0F\xD4\110              WILLAMETTE,SSE2
+PADDQ           xmmreg,mem              \301\3\x66\x0F\xD4\110          WILLAMETTE,SSE2,SM
+PADDSB          xmmreg,mem              \301\3\x66\x0F\xEC\110          WILLAMETTE,SSE2,SM
+PADDSB          xmmreg,xmmreg           \3\x66\x0F\xEC\110              WILLAMETTE,SSE2
+PADDSW          xmmreg,mem              \301\3\x66\x0F\xED\110          WILLAMETTE,SSE2,SM
+PADDSW          xmmreg,xmmreg           \3\x66\x0F\xED\110              WILLAMETTE,SSE2
+PADDUSB         xmmreg,mem              \301\3\x66\x0F\xDC\110          WILLAMETTE,SSE2,SM
+PADDUSB         xmmreg,xmmreg           \3\x66\x0F\xDC\110              WILLAMETTE,SSE2
+PADDUSW         xmmreg,mem              \301\3\x66\x0F\xDD\110          WILLAMETTE,SSE2,SM
+PADDUSW         xmmreg,xmmreg           \3\x66\x0F\xDD\110              WILLAMETTE,SSE2
+PAND            xmmreg,xmmreg           \3\x66\x0F\xDB\110              WILLAMETTE,SSE2
+PAND            xmmreg,mem              \301\3\x66\x0F\xDB\110          WILLAMETTE,SSE2,SM
+PANDN           xmmreg,xmmreg           \3\x66\x0F\xDF\110              WILLAMETTE,SSE2
+PANDN           xmmreg,mem              \301\3\x66\x0F\xDF\110          WILLAMETTE,SSE2,SM
+PAVGB           xmmreg,xmmreg           \3\x66\x0F\xE0\110              WILLAMETTE,SSE2
+PAVGB           xmmreg,mem              \301\3\x66\x0F\xE0\110          WILLAMETTE,SSE2,SM
+PAVGW           xmmreg,xmmreg           \3\x66\x0F\xE3\110              WILLAMETTE,SSE2
+PAVGW           xmmreg,mem              \301\3\x66\x0F\xE3\110          WILLAMETTE,SSE2,SM
+PCMPEQB         xmmreg,xmmreg           \3\x66\x0F\x74\110              WILLAMETTE,SSE2
+PCMPEQB         xmmreg,mem              \301\3\x66\x0F\x74\110          WILLAMETTE,SSE2,SM
+PCMPEQW         xmmreg,xmmreg           \3\x66\x0F\x75\110              WILLAMETTE,SSE2
+PCMPEQW         xmmreg,mem              \301\3\x66\x0F\x75\110          WILLAMETTE,SSE2,SM
+PCMPEQD         xmmreg,xmmreg           \3\x66\x0F\x76\110              WILLAMETTE,SSE2
+PCMPEQD         xmmreg,mem              \301\3\x66\x0F\x76\110          WILLAMETTE,SSE2,SM
+PCMPGTB         xmmreg,xmmreg           \3\x66\x0F\x64\110              WILLAMETTE,SSE2
+PCMPGTB         xmmreg,mem              \301\3\x66\x0F\x64\110          WILLAMETTE,SSE2,SM
+PCMPGTW         xmmreg,xmmreg           \3\x66\x0F\x65\110              WILLAMETTE,SSE2
+PCMPGTW         xmmreg,mem              \301\3\x66\x0F\x65\110          WILLAMETTE,SSE2,SM
+PCMPGTD         xmmreg,xmmreg           \3\x66\x0F\x66\110              WILLAMETTE,SSE2
+PCMPGTD         xmmreg,mem              \301\3\x66\x0F\x66\110          WILLAMETTE,SSE2,SM
+PEXTRW          reg32,xmmreg,imm        \3\x66\x0F\xC5\110\26           WILLAMETTE,SSE2,SB,AR2
+PINSRW          xmmreg,reg16,imm        \3\x66\x0F\xC4\110\26           WILLAMETTE,SSE2,SB,AR2
+PINSRW          xmmreg,reg32,imm        \3\x66\x0F\xC4\110\26           WILLAMETTE,SSE2,SB,AR2,ND
+PINSRW          xmmreg,mem,imm          \301\3\x66\x0F\xC4\110\26       WILLAMETTE,SSE2,SB,AR2
+PINSRW          xmmreg,mem16,imm        \301\3\x66\x0F\xC4\110\26       WILLAMETTE,SSE2,SB,AR2,ND
+PMADDWD         xmmreg,mem              \301\3\x66\x0F\xF5\110          WILLAMETTE,SSE2,SM
+PMADDWD         xmmreg,xmmreg           \3\x66\x0F\xF5\110              WILLAMETTE,SSE2
+PMAXSW          xmmreg,xmmreg           \3\x66\x0F\xEE\110              WILLAMETTE,SSE2
+PMAXSW          xmmreg,mem              \301\3\x66\x0F\xEE\110          WILLAMETTE,SSE2,SM
+PMAXUB          xmmreg,xmmreg           \3\x66\x0F\xDE\110              WILLAMETTE,SSE2
+PMAXUB          xmmreg,mem              \301\3\x66\x0F\xDE\110          WILLAMETTE,SSE2,SM
+PMINSW          xmmreg,xmmreg           \3\x66\x0F\xEA\110              WILLAMETTE,SSE2
+PMINSW          xmmreg,mem              \301\3\x66\x0F\xEA\110          WILLAMETTE,SSE2,SM
+PMINUB          xmmreg,xmmreg           \3\x66\x0F\xDA\110              WILLAMETTE,SSE2
+PMINUB          xmmreg,mem              \301\3\x66\x0F\xDA\110          WILLAMETTE,SSE2,SM
+PMOVMSKB        reg32,xmmreg            \3\x66\x0F\xD7\110              WILLAMETTE,SSE2
+PMULHUW         xmmreg,xmmreg           \3\x66\x0F\xE4\110              WILLAMETTE,SSE2
+PMULHUW         xmmreg,mem              \301\3\x66\x0F\xE4\110          WILLAMETTE,SSE2,SM
+PMULHW          xmmreg,mem              \301\3\x66\x0F\xE5\110          WILLAMETTE,SSE2,SM
+PMULHW          xmmreg,xmmreg           \3\x66\x0F\xE5\110              WILLAMETTE,SSE2
+PMULLW          xmmreg,mem              \301\3\x66\x0F\xD5\110          WILLAMETTE,SSE2,SM
+PMULLW          xmmreg,xmmreg           \3\x66\x0F\xD5\110              WILLAMETTE,SSE2
+PMULUDQ         mmxreg,mmxreg           \2\x0F\xF4\110                  WILLAMETTE,SSE2
+PMULUDQ         mmxreg,mem              \301\2\x0F\xF4\110              WILLAMETTE,SSE2,SM
+PMULUDQ         xmmreg,xmmreg           \3\x66\x0F\xF4\110              WILLAMETTE,SSE2
+PMULUDQ         xmmreg,mem              \301\3\x66\x0F\xF4\110          WILLAMETTE,SSE2,SM
+POR             xmmreg,mem              \301\3\x66\x0F\xEB\110          WILLAMETTE,SSE2,SM
+POR             xmmreg,xmmreg           \3\x66\x0F\xEB\110              WILLAMETTE,SSE2
+PSADBW          xmmreg,xmmreg           \3\x66\x0F\xF6\110              WILLAMETTE,SSE2
+PSADBW          xmmreg,mem              \301\3\x66\x0F\xF6\110          WILLAMETTE,SSE2,SM
+PSHUFD          xmmreg,xmmreg,imm       \3\x66\x0F\x70\110\22           WILLAMETTE,SSE2,SB,AR2
+PSHUFD          xmmreg,mem,imm          \301\3\x66\x0F\x70\110\22       WILLAMETTE,SSE2,SM2,SB,AR2
+PSHUFHW         xmmreg,xmmreg,imm       \333\2\x0F\x70\110\22           WILLAMETTE,SSE2,SB,AR2
+PSHUFHW         xmmreg,mem,imm          \301\333\2\x0F\x70\110\22       WILLAMETTE,SSE2,SM2,SB,AR2
+PSHUFLW         xmmreg,xmmreg,imm       \3\xF2\x0F\x70\110\22           WILLAMETTE,SSE2,SB,AR2
+PSHUFLW         xmmreg,mem,imm          \301\3\xF2\x0F\x70\110\22       WILLAMETTE,SSE2,SM2,SB,AR2
+PSLLDQ          xmmreg,imm              \3\x66\x0F\x73\207\25           WILLAMETTE,SSE2,SB,AR1
+PSLLW           xmmreg,mem              \301\3\x66\x0F\xF1\110          WILLAMETTE,SSE2,SM
+PSLLW           xmmreg,xmmreg           \3\x66\x0F\xF1\110              WILLAMETTE,SSE2
+PSLLW           xmmreg,imm              \3\x66\x0F\x71\206\25           WILLAMETTE,SSE2,SB,AR1
+PSLLD           xmmreg,mem              \301\3\x66\x0F\xF2\110          WILLAMETTE,SSE2,SM
+PSLLD           xmmreg,xmmreg           \3\x66\x0F\xF2\110              WILLAMETTE,SSE2
+PSLLD           xmmreg,imm              \3\x66\x0F\x72\206\25           WILLAMETTE,SSE2,SB,AR1
+PSLLQ           xmmreg,mem              \301\3\x66\x0F\xF3\110          WILLAMETTE,SSE2,SM
+PSLLQ           xmmreg,xmmreg           \3\x66\x0F\xF3\110              WILLAMETTE,SSE2
+PSLLQ           xmmreg,imm              \3\x66\x0F\x73\206\25           WILLAMETTE,SSE2,SB,AR1
+PSRAW           xmmreg,mem              \301\3\x66\x0F\xE1\110          WILLAMETTE,SSE2,SM
+PSRAW           xmmreg,xmmreg           \3\x66\x0F\xE1\110              WILLAMETTE,SSE2
+PSRAW           xmmreg,imm              \3\x66\x0F\x71\204\25           WILLAMETTE,SSE2,SB,AR1
+PSRAD           xmmreg,mem              \301\3\x66\x0F\xE2\110          WILLAMETTE,SSE2,SM
+PSRAD           xmmreg,xmmreg           \3\x66\x0F\xE2\110              WILLAMETTE,SSE2
+PSRAD           xmmreg,imm              \3\x66\x0F\x72\204\25           WILLAMETTE,SSE2,SB,AR1
+PSRLDQ          xmmreg,imm              \3\x66\x0F\x73\203\25           WILLAMETTE,SSE2,SB,AR1
+PSRLW           xmmreg,mem              \301\3\x66\x0F\xD1\110          WILLAMETTE,SSE2,SM
+PSRLW           xmmreg,xmmreg           \3\x66\x0F\xD1\110              WILLAMETTE,SSE2
+PSRLW           xmmreg,imm              \3\x66\x0F\x71\202\25           WILLAMETTE,SSE2,SB,AR1
+PSRLD           xmmreg,mem              \301\3\x66\x0F\xD2\110          WILLAMETTE,SSE2,SM
+PSRLD           xmmreg,xmmreg           \3\x66\x0F\xD2\110              WILLAMETTE,SSE2
+PSRLD           xmmreg,imm              \3\x66\x0F\x72\202\25           WILLAMETTE,SSE2,SB,AR1
+PSRLQ           xmmreg,mem              \301\3\x66\x0F\xD3\110          WILLAMETTE,SSE2,SM
+PSRLQ           xmmreg,xmmreg           \3\x66\x0F\xD3\110              WILLAMETTE,SSE2
+PSRLQ           xmmreg,imm              \3\x66\x0F\x73\202\25           WILLAMETTE,SSE2,SB,AR1
+PSUBB           xmmreg,mem              \301\3\x66\x0F\xF8\110          WILLAMETTE,SSE2,SM
+PSUBB           xmmreg,xmmreg           \3\x66\x0F\xF8\110              WILLAMETTE,SSE2
+PSUBW           xmmreg,mem              \301\3\x66\x0F\xF9\110          WILLAMETTE,SSE2,SM
+PSUBW           xmmreg,xmmreg           \3\x66\x0F\xF9\110              WILLAMETTE,SSE2
+PSUBD           xmmreg,mem              \301\3\x66\x0F\xFA\110          WILLAMETTE,SSE2,SM
+PSUBD           xmmreg,xmmreg           \3\x66\x0F\xFA\110              WILLAMETTE,SSE2
+PSUBQ           mmxreg,mmxreg           \2\x0F\xFB\110                  WILLAMETTE,SSE2
+PSUBQ           mmxreg,mem              \301\2\x0F\xFB\110              WILLAMETTE,SSE2,SM
+PSUBQ           xmmreg,xmmreg           \3\x66\x0F\xFB\110              WILLAMETTE,SSE2
+PSUBQ           xmmreg,mem              \301\3\x66\x0F\xFB\110          WILLAMETTE,SSE2,SM
+PSUBSB          xmmreg,mem              \301\3\x66\x0F\xE8\110          WILLAMETTE,SSE2,SM
+PSUBSB          xmmreg,xmmreg           \3\x66\x0F\xE8\110              WILLAMETTE,SSE2
+PSUBSW          xmmreg,mem              \301\3\x66\x0F\xE9\110          WILLAMETTE,SSE2,SM
+PSUBSW          xmmreg,xmmreg           \3\x66\x0F\xE9\110              WILLAMETTE,SSE2
+PSUBUSB         xmmreg,mem              \301\3\x66\x0F\xD8\110          WILLAMETTE,SSE2,SM
+PSUBUSB         xmmreg,xmmreg           \3\x66\x0F\xD8\110              WILLAMETTE,SSE2
+PSUBUSW         xmmreg,mem              \301\3\x66\x0F\xD9\110          WILLAMETTE,SSE2,SM
+PSUBUSW         xmmreg,xmmreg           \3\x66\x0F\xD9\110              WILLAMETTE,SSE2
+PUNPCKHBW       xmmreg,mem              \301\3\x66\x0F\x68\110          WILLAMETTE,SSE2,SM
+PUNPCKHBW       xmmreg,xmmreg           \3\x66\x0F\x68\110              WILLAMETTE,SSE2
+PUNPCKHWD       xmmreg,mem              \301\3\x66\x0F\x69\110          WILLAMETTE,SSE2,SM
+PUNPCKHWD       xmmreg,xmmreg           \3\x66\x0F\x69\110              WILLAMETTE,SSE2
+PUNPCKHDQ       xmmreg,mem              \301\3\x66\x0F\x6A\110          WILLAMETTE,SSE2,SM
+PUNPCKHDQ       xmmreg,xmmreg           \3\x66\x0F\x6A\110              WILLAMETTE,SSE2
+PUNPCKHQDQ      xmmreg,xmmreg           \3\x66\x0F\x6D\110              WILLAMETTE,SSE2
+PUNPCKHQDQ      xmmreg,mem              \301\3\x66\x0F\x6D\110          WILLAMETTE,SSE2,SM
+PUNPCKLBW       xmmreg,mem              \301\3\x66\x0F\x60\110          WILLAMETTE,SSE2,SM
+PUNPCKLBW       xmmreg,xmmreg           \3\x66\x0F\x60\110              WILLAMETTE,SSE2
+PUNPCKLWD       xmmreg,mem              \301\3\x66\x0F\x61\110          WILLAMETTE,SSE2,SM
+PUNPCKLWD       xmmreg,xmmreg           \3\x66\x0F\x61\110              WILLAMETTE,SSE2
+PUNPCKLDQ       xmmreg,mem              \301\3\x66\x0F\x62\110          WILLAMETTE,SSE2,SM
+PUNPCKLDQ       xmmreg,xmmreg           \3\x66\x0F\x62\110              WILLAMETTE,SSE2
+PUNPCKLQDQ      xmmreg,xmmreg           \3\x66\x0F\x6C\110              WILLAMETTE,SSE2
+PUNPCKLQDQ      xmmreg,mem              \301\3\x66\x0F\x6C\110          WILLAMETTE,SSE2,SM
+PXOR            xmmreg,mem              \301\3\x66\x0F\xEF\110          WILLAMETTE,SSE2,SM
+PXOR            xmmreg,xmmreg           \3\x66\x0F\xEF\110              WILLAMETTE,SSE2
 
-; Willamette MMX instructions (SSE2)
-MOVD            xmmreg,reg32                              \3\x66\x0F\x6E                          WILLAMETTE
-MOVD            reg32,xmmreg                              \3\x66\x0F\x7E                          WILLAMETTE
-MOVD           mem,xmmreg                              \3\x66\x0F\x7E                          WILLAMETTE
-MOVD           xmmreg,mem                              \3\x66\x0F\x6E                          WILLAMETTE
-MOVDQA          xmmreg,reg32                              \3\x66\x0F\x6F                          WILLAMETTE
-MOVDQA         mem,xmmreg                              \3\x66\x0F\x7F                          WILLAMETTE
-MOVDQA         xmmreg,mem                              \3\x66\x0F\x6F                          WILLAMETTE
-MOVDQA          reg32,xmmreg                              \3\x66\x0F\x7F                          WILLAMETTE
-MOVDQU          xmmreg,reg32                              \3\xF3\x0F\x6F                          WILLAMETTE
-MOVDQU         mem,xmmreg                              \3\xF3\x0F\x7F                          WILLAMETTE
-MOVDQU         xmmreg,mem                              \3\xF3\x0F\x6F                          WILLAMETTE
-MOVDQU          reg32,xmmreg                              \3\xF3\x0F\x7F                          WILLAMETTE
-MOVQ2DQ        mmxreg,xmmreg                   \3\xF2\x0F\xD6                          WILLAMETTE
-PACKSSWB       xmmreg,xmmreg                   \3\x66\x0F\x63                          WILLAMETTE
-PACKSSWB       xmmreg,mem                              \3\x66\x0F\x63                          WILLAMETTE
-PACKSSDW       xmmreg,xmmreg                   \3\x66\x0F\x6B                          WILLAMETTE
-PACKSSDW       xmmreg,mem                              \3\x66\x0F\x6B                          WILLAMETTE
-PACKUSWB       xmmreg,xmmreg                   \3\x66\x0F\x67                          WILLAMETTE
-PACKUSWB       xmmreg,mem                              \3\x66\x0F\x67                          WILLAMETTE
-PADDQ           xmmreg,mmxreg                    \3\x66\x0F\xD4                          WILLAMETTE
-PADDQ          xmmreg,mem                              \3\x66\x0F\xD4                          WILLAMETTE
-PADDD          xmmreg,xmmreg                   \3\x66\x0F\xFE                          WILLAMETTE
-PADDD          xmmreg,mem                              \3\x66\x0F\xFE                          WILLAMETTE
-PADDSB         xmmreg,mem                              \3\x66\x0F\xEC                          WILLAMETTE
-PADDSB         xmmreg,xmmreg                   \3\x66\x0F\xEC                          WILLAMETTE
-PADDSW         xmmreg,mem                              \3\x66\x0F\xED                          WILLAMETTE
-PADDSW         xmmreg,xmmreg                   \3\x66\x0F\xED                          WILLAMETTE
-PADDUSB        xmmreg,mem                              \3\x66\x0F\xDC                          WILLAMETTE
-PADDUSB        xmmreg,xmmreg                   \3\x66\x0F\xDC                          WILLAMETTE
-PADDUSW        xmmreg,mem                              \3\x66\x0F\xDD                          WILLAMETTE
-PADDUSW        xmmreg,xmmreg                   \3\x66\x0F\xDD                          WILLAMETTE
-PAND           xmmreg,xmmreg                   \3\x66\x0F\xDB                          WILLAMETTE
-PAND           xmmreg,mem                              \3\x66\x0F\xDB                          WILLAMETTE
-PANDN          xmmreg,xmmreg                   \3\x66\x0F\xDF                          WILLAMETTE
-PANDN          xmmreg,mem                              \3\x66\x0F\xDF                          WILLAMETTE
-PAVGB          xmmreg,xmmreg                   \3\x66\x0F\xE0                          WILLAMETTE
-PAVGB          xmmreg,mem                              \3\x66\x0F\xE0                          WILLAMETTE
-PAVGW          xmmreg,xmmreg                   \3\x66\x0F\xE3                          WILLAMETTE
-PAVGW          xmmreg,mem                              \3\x66\x0F\xE3                          WILLAMETTE
-PCMPEQB        xmmreg,xmmreg                   \3\x66\x0F\x74                          WILLAMETTE
-PCMPEQB        xmmreg,mem                              \3\x66\x0F\x74                          WILLAMETTE
-PCMPEQW        xmmreg,xmmreg                   \3\x66\x0F\x75                          WILLAMETTE
-PCMPEQW        xmmreg,mem                              \3\x66\x0F\x75                          WILLAMETTE
-PCMPEQD        xmmreg,xmmreg                   \3\x66\x0F\x76                          WILLAMETTE
-PCMPEQD        xmmreg,mem                              \3\x66\x0F\x76                          WILLAMETTE
-PCMPGTB        xmmreg,xmmreg                   \3\x66\x0F\x64                          WILLAMETTE
-PCMPGTB        xmmreg,mem                              \3\x66\x0F\x64                          WILLAMETTE
-PCMPGTW        xmmreg,xmmreg                   \3\x66\x0F\x65                          WILLAMETTE
-PCMPGTW        xmmreg,mem                              \3\x66\x0F\x65                          WILLAMETTE
-PCMPGTD        xmmreg,xmmreg                   \3\x66\x0F\x66                          WILLAMETTE
-PCMPGTD        xmmreg,mem                              \3\x66\x0F\x66                          WILLAMETTE
-PEXTRW         reg32,xmmreg,imm8               \3\x66\x0F\xC5\110\22           WILLAMETTE
-PINSRW         xmmreg,reg16,imm                \3\x66\x0F\xC4\110\22           WILLAMETTE,MMX,SB,AR2
-PINSRW         xmmreg,reg32,imm                \3\x66\x0F\xC4\110\22           WILLAMETTE,MMX,SB,AR2,ND
-PINSRW         xmmreg,mem,imm                  \301\3\x66\x0F\xC4\110\22               WILLAMETTE,MMX,SB,AR2
-PINSRW         xmmreg,mem16,imm                \301\3\x66\x0F\xC4\110\22               WILLAMETTE,MMX,SB,AR2,ND
-PMAXSW         xmmreg,xmmreg                   \3\x66\x0F\xEE\110                      WILLAMETTE,MMX
-PMAXSW         xmmreg,mem                              \301\3\x66\x0F\xEE\110          WILLAMETTE,MMX,SM
-PMAXUB         xmmreg,xmmreg                   \3\x66\x0F\xDE\110                      WILLAMETTE,MMX
-PMAXUB         xmmreg,mem                              \301\3\x66\x0F\xDE\110          WILLAMETTE,MMX,SM
-PMINSW         xmmreg,xmmreg                   \3\x66\x0F\xEA\110                      WILLAMETTE,MMX
-PMINSW         xmmreg,mem                              \301\3\x66\x0F\xEA\110          WILLAMETTE,MMX,SM
-PMINUB         xmmreg,xmmreg                   \3\x66\x0F\xDA\110                      WILLAMETTE,MMX
-PMINUB         xmmreg,mem                              \301\3\x66\x0F\xDA\110          WILLAMETTE,MMX,SM
-PMOVMSKB       reg32,xmmreg                    \3\x66\x0F\xD7\110                      WILLAMETTE,MMX
-PMULHUW        xmmreg,xmmreg                   \3\x66\x0F\xE4\110                      WILLAMETTE,MMX
-PMULHUW        xmmreg,mem                              \301\3\x66\x0F\xE4\110          WILLAMETTE,MMX,SM
-PSADBW         xmmreg,xmmreg                   \3\x66\x0F\xF6\110                      WILLAMETTE,MMX
-PSADBW         xmmreg,mem                              \301\3\x66\x0F\xF6\110          WILLAMETTE,MMX,SM
-PSHUFD         xmmreg,xmmreg,imm               \3\x66\x0F\x70\110\22           WILLAMETTE,MMX,SB,AR2
-PSHUFD         xmmreg,mem,imm                  \301\3\x66\x0F\x70\110\22               WILLAMETTE,MMX,SM2,SB,AR2
-PMADDWD   xmmreg,mem                            \301\3\x66\x0F\xF5\110                 WILLAMETTE,MMX,SM
-PMADDWD   xmmreg,xmmreg                          \3\x66\x0F\xF5\110                            WILLAMETTE,MMX
-PMULLW   xmmreg,mem                      \301\3\x66\x0F\xD5\110                        WILLAMETTE,MMX,SM
-PMULLW   xmmreg,xmmreg                   \3\x66\x0F\xD5\110                            WILLAMETTE,MMX
-PMULUDQ         mmxreg,mmxreg             \2\x0F\xF4                              WILLAMETTE
-PMULUDQ         mmxreg,mem                       \2\x0F\xF4                              WILLAMETTE
-PMULUDQ        xmmreg,xmmreg           \3\x66\x0F\xF4                          WILLAMETTE
-PMULUDQ        xmmreg,mem                      \3\x66\x0F\xF4                          WILLAMETTE
-POR            xmmreg,mem                      \301\3\x66\x0F\xEB\110                    WILLAMETTE,MMX,SM
-POR            xmmreg,xmmreg           \3\x66\x0F\xEB\110                                WILLAMETTE,MMX
-PSHUFLW        xmmreg,xmmreg,imm8      \3\xF2\x0F\x70                          WILLAMETTE
-PSHUFLW        xmmreg,mem,imm8         \3\xF2\x0F\x70                          WILLAMETTE
-PSHUFHW        xmmreg,xmmreg,imm8      \3\xF3\x0F\x70                          WILLAMETTE
-PSHUFHW        xmmreg,mem,imm8         \3\xF3\x0F\x70                          WILLAMETTE
-PSLLDQ         xmmreg,imm8             \3\x66\x0F\x73                  WILLAMETTE
-PSLLD    xmmreg,mem              \301\3\x66\x0F\xF2\110                        WILLAMETTE,MMX,SM
-PSLLD    xmmreg,xmmreg           \3\x66\x0F\xF2\110                            WILLAMETTE,MMX
-PSLLD    xmmreg,imm              \3\x66\x0F\x72\206\25                         WILLAMETTE,MMX
-PSLLQ    xmmreg,mem              \301\3\x66\x0F\xF3\110                        WILLAMETTE,MMX,SM
-PSLLQ    xmmreg,xmmreg           \3\x66\x0F\xF3\110                            WILLAMETTE,MMX
-PSLLQ    xmmreg,imm              \3\x66\x0F\x73\206\25                         WILLAMETTE,MMX
-PSLLW    xmmreg,mem              \301\3\x66\x0F\xF1\110                        WILLAMETTE,MMX,SM
-PSLLW    xmmreg,xmmreg           \3\x66\x0F\xF1\110                            WILLAMETTE,MMX
-PSLLW    xmmreg,imm              \3\x66\x0F\x71\206\25                         WILLAMETTE,MMX
-PSRAD    xmmreg,mem              \301\3\x66\x0F\xE2\110                        WILLAMETTE,MMX,SM
-PSRAD    xmmreg,xmmreg           \3\x66\x0F\xE2\110                            WILLAMETTE,MMX
-PSRAD    xmmreg,imm              \3\x66\x0F\x72\204\25                         WILLAMETTE,MMX
-PSRAW    xmmreg,mem              \301\3\x66\x0F\xE1\110                        WILLAMETTE,MMX,SM
-PSRAW    xmmreg,xmmreg           \3\x66\x0F\xE1\110                            WILLAMETTE,MMX
-PSRAW    xmmreg,imm              \3\x66\x0F\x71\204\25                         WILLAMETTE,MMX
-PSRLW    xmmreg,imm              \3\x66\x0F\x73\202\25                         WILLAMETTE,MMX
-PSRLD    xmmreg,mem              \301\3\x66\x0F\xD2\110                        WILLAMETTE,MMX,SM
-PSRLD    xmmreg,xmmreg           \3\x66\x0F\xD2\110                            WILLAMETTE,MMX
-PSRLD    xmmreg,imm              \3\x66\x0F\x72\202\25                         WILLAMETTE,MMX
-PSRLQ    xmmreg,mem              \301\3\x66\x0F\xD3\110                        WILLAMETTE,MMX,SM
-PSRLQ    xmmreg,xmmreg           \3\x66\x0F\xD3\110                            WILLAMETTE,MMX
-PSRLQ    xmmreg,imm              \3\x66\x0F\x73\202\25                         WILLAMETTE,MMX
-PSRLW    xmmreg,mem              \301\3\x66\x0F\xD1\110                        WILLAMETTE,MMX,SM
-PSRLW    xmmreg,xmmreg           \3\x66\x0F\xD1\110                            WILLAMETTE,MMX
-PSRLW    xmmreg,imm              \3\x66\x0F\x71\202\25                         WILLAMETTE,MMX
-PSUBQ     mmxreg,mmxreg                   \2\x0F\xFB                                              WILLAMETTE
-PSUBQ     mmxreg,mem                     \2\x0F\xFB                                              WILLAMETTE
-PSUBQ    xmmreg,xmmreg                 \3\x66\x0F\xFB                                  WILLAMETTE
-PSUBQ     xmmreg,mem                    \3\x66\x0F\xFB                                    WILLAMETTE
-PSUBB    xmmreg,mem              \301\3\x66\x0F\xF8\110                        WILLAMETTE,MMX,SM
-PSUBB    xmmreg,xmmreg           \3\x66\x0F\xF8\110                            WILLAMETTE,MMX
-PSUBD    xmmreg,mem              \301\3\x66\x0F\xFA\110                        WILLAMETTE,MMX,SM
-PSUBD    xmmreg,xmmreg           \3\x66\x0F\xFA\110                            WILLAMETTE,MMX
-PSUBSB   xmmreg,mem              \301\3\x66\x0F\xE8\110                        WILLAMETTE,MMX,SM
-PSUBSB   xmmreg,xmmreg           \3\x66\x0F\xE8\110                            WILLAMETTE,MMX
-PSUBSW   xmmreg,mem              \301\3\x66\x0F\xE9\110                        WILLAMETTE,MMX,SM
-PSUBSW   xmmreg,xmmreg           \3\x66\x0F\xE9\110                            WILLAMETTE,MMX
-PSUBUSB           xmmreg,mem             \301\3\x66\x0F\xD8\110                        WILLAMETTE,MMX,SM
-PSUBUSB           xmmreg,xmmreg          \3\x66\x0F\xD8\110                            WILLAMETTE,MMX
-PSUBUSW           xmmreg,mem             \301\3\x66\x0F\xD9\110                        WILLAMETTE,MMX,SM
-PSUBUSW           xmmreg,xmmreg          \3\x66\x0F\xD9\110                            WILLAMETTE,MMX
-PSUBW    xmmreg,mem              \301\3\x66\x0F\xF9\110                        WILLAMETTE,MMX,SM
-PSUBW    xmmreg,xmmreg           \3\x66\x0F\xF9\110                            WILLAMETTE,MMX
-PUNPCKHBW xmmreg,mem             \301\3\x66\x0F\x68\110                        WILLAMETTE,MMX,SM
-PUNPCKHBW xmmreg,xmmreg          \3\x66\x0F\x68\110                            WILLAMETTE,MMX
-PUNPCKHDQ xmmreg,mem             \301\3\x66\x0F\x6A\110                        WILLAMETTE,MMX,SM
-PUNPCKHDQ xmmreg,xmmreg          \3\x66\x0F\x6A\110                            WILLAMETTE,MMX
-PUNPCKHWD xmmreg,mem             \301\3\x66\x0F\x69\110                        WILLAMETTE,MMX,SM
-PUNPCKHWD xmmreg,xmmreg          \3\x66\x0F\x69\110                            WILLAMETTE,MMX
-PUNPCKLBW xmmreg,mem             \301\3\x66\x0F\x60\110                        WILLAMETTE,MMX,SM
-PUNPCKLBW xmmreg,xmmreg          \3\x66\x0F\x60\110                            WILLAMETTE,MMX
-PUNPCKLDQ xmmreg,mem             \301\3\x66\x0F\x62\110                        WILLAMETTE,MMX,SM
-PUNPCKLDQ xmmreg,xmmreg          \3\x66\x0F\x62\110                            WILLAMETTE,MMX
-PUNPCKLWD xmmreg,mem             \301\3\x66\x0F\x61\110                        WILLAMETTE,MMX,SM
-PUNPCKLWD xmmreg,xmmreg          \3\x66\x0F\x61\110                            WILLAMETTE,MMX
-PUNPCKLQDQ     xmmreg,xmmreg           \3\x66\x0F\x6C\110                                              WILLAMETTE
-PUNPCKLQDQ     xmmreg,mem                      \301\3\x66\x0F\x6C\110                                          WILLAMETTE
-PUNPCKHQDQ     xmmreg,xmmreg           \3\x66\x0F\x6D\110                                              WILLAMETTE
-PUNPCKHQDQ     xmmreg,mem                      \301\3\x66\x0F\x6D\110                                          WILLAMETTE
-PXOR     xmmreg,mem              \301\3\x66\x0F\xEF\110                        WILLAMETTE,MMX,SM
-PXOR     xmmreg,xmmreg           \3\x66\x0F\xEF\110                            WILLAMETTE,MMX
 ; Willamette Streaming SIMD instructions (SSE2)
-; opcode       parameters                              assembly                                range
-ADDPD          xmmreg,xmmreg                   \3\x66\x0F\x58                  WILLAMETTE,SSE2
-ADDPD          mem,xmmreg                              \3\x66\x0F\x58                  WILLAMETTE,SSE2
-ADDSD          xmmreg,xmmreg                   \3\xF2\x0F\x58                  WILLAMETTE,SSE2
-ADDSD          mem,xmmreg                              \3\xF2\x0F\x58                  WILLAMETTE,SSE2
-ANDNPD         xmmreg,xmmreg                   \3\x66\x0F\x54                  WILLAMETTE,SSE2
-ANDNPD         mem,xmmreg                              \3\x66\x0F\x54                  WILLAMETTE,SSE2
-ANDDPD         xmmreg,xmmreg                   \3\x66\x0F\x55                  WILLAMETTE,SSE2
-ANDDPD         mem,xmmreg                              \3\x66\x0F\x55                  WILLAMETTE,SSE2
-CMPPD          xmmreg,xmmreg,imm8              \3\x66\x0F\xC2                  WILLAMETTE,SSE2
-CMPPD          mem,xmmreg,imm8                 \3\x66\x0F\xC2                  WILLAMETTE,SSE2
-CMPSD          xmmreg,xmmreg,imm8              \1\xA7                                  WILLAMETTE,SSE2
-CMPSD          mem,xmmreg,imm8                 \1\xA7                                  WILLAMETTE,SSE2
-COMISD         xmmreg,xmmreg                   \3\x66\x0F\x2F                  WILLAMETTE,SSE2
-COMISD         mem,xmmreg                              \3\x66\x0F\x2F                  WILLAMETTE,SSE2
-CVTPI2PD        mmxreg,xmmreg                    \3\x66\x0F\x2A                  WILLAMETTE,SSE2
-CVTPI2PD       mem,xmmreg                              \3\x66\x0F\x2A                  WILLAMETTE,SSE2
-CVTPD2PI        xmmreg,mmxreg                    \3\x66\x0F\x2C                  WILLAMETTE,SSE2
-CVTPD2PI        mem,mmxreg                               \3\x66\x0F\x2C                  WILLAMETTE,SSE2
-CVTSI2SD       reg32,xmmreg                    \3\xF2\x0F\x2A                  WILLAMETTE,SSE2
-CVTSI2SD       mem,xmmreg                              \3\xF2\x0F\x2A                  WILLAMETTE,SSE2
-CVTSD2SI       xmmreg,reg32                    \3\xF2\x0F\x2D                  WILLAMETTE,SSE2
-CVTSD2SI       mem,reg32                               \3\xF2\x0F\x2D                  WILLAMETTE,SSE2
-CVTPD2PS       xmmreg,xmmreg                   \2\x0F\x2A                              WILLAMETTE,SSE2
-CVTPD2PS       mem,xmmreg                              \2\x0F\x2A                              WILLAMETTE,SSE2
-CVTPS2PD       xmmreg,xmmreg                   \2\x0F\x5A                              WILLAMETTE,SSE2
-CVTPS2PD       mem,xmmreg                              \2\x0F\x5A                              WILLAMETTE,SSE2
-CVTSD2SS       xmmreg,xmmreg                   \3\xF2\x0F\x5A                  WILLAMETTE,SSE2
-CVTSD2SS       mem,xmmreg                              \3\xF2\x0F\x5A                  WILLAMETTE,SSE2
-CVTSS2SD       xmmreg,xmmreg                   \3\xF3\x0F\x5A                  WILLAMETTE,SSE2
-CVTSS2SD       mem,xmmreg                              \3\xF3\x0F\x5A                  WILLAMETTE,SSE2
-CVTPD2DQ       xmmreg,xmmreg                   \3\xF2\x0F\xE6                  WILLAMETTE,SSE2
-CVTPD2DQ       mem,xmmreg                              \3\xF2\x0F\xE6                  WILLAMETTE,SSE2
-CVTDQ2PD       xmmreg,xmmreg                   \3\xF3\x0F\xE6                  WILLAMETTE,SSE2
-CVTDQ2PD       mem,xmmreg                              \3\xF3\x0F\xE6                  WILLAMETTE,SSE2
-CVTDQ2PS       xmmreg,xmmreg                   \2\x0F\x5B                              WILLAMETTE,SSE2
-CVTDQ2PS       mem,xmmreg                              \2\x0F\x5B                              WILLAMETTE,SSE2
-CVTPS2DQ       xmmreg,xmmreg                   \3\x66\x0F\x5B                  WILLAMETTE,SSE2
-CVTPS2DQ       mem,xmmreg                              \3\x66\x0F\x5B                  WILLAMETTE,SSE2
-CVTTPD2PI       mmxreg,xmmreg                    \3\x66\x0F\x2C                  WILLAMETTE,SSE2
-CVTTPD2PI      mem,xmmreg                              \3\x66\x0F\x2C                  WILLAMETTE,SSE2
-CVTTPD2DQ       mmxreg,xmmreg                    \3\x66\x0F\xE6                  WILLAMETTE,SSE2
-CVTTPD2DQ      mem,xmmreg                              \3\x66\x0F\xE6                  WILLAMETTE,SSE2
-CVTTPS2DQ       mmxreg,xmmreg                    \3\xF3\x0F\x5B                  WILLAMETTE,SSE2
-CVTTPS2DQ      mem,xmmreg                              \3\xF3\x0F\x5B                  WILLAMETTE,SSE2
-CVTTPS2PI       mmxreg,xmmreg                    \3\x0F\x2C                              WILLAMETTE,SSE2
-CVTTPS2PI      mem,xmmreg                              \3\x0F\x2C                              WILLAMETTE,SSE2
-CVTTSD2SI       mmxreg,xmmreg                    \3\xF2\x0F\x2C                  WILLAMETTE,SSE2
-CVTTSD2SI      mem,xmmreg                              \3\xF2\x0F\x2C                  WILLAMETTE,SSE2
-CVTTSS2SI       mmxreg,xmmreg                    \3\xF3\x0F\x2C                  WILLAMETTE,SSE2
-CVTTSS2SI      mem,xmmreg                              \3\xF3\x0F\x2C                  WILLAMETTE,SSE2
-DIVPD          xmmreg,xmmreg                   \3\x66\x0F\x5E                  WILLAMETTE,SSE2
-DIVPD          mem,xmmreg                              \3\x66\x0F\x5E                  WILLAMETTE,SSE2
-DIVSD          xmmreg,xmmreg                   \3\xF2\x0F\x5E                  WILLAMETTE,SSE2
-DIVSD          mem,xmmreg                              \3\xF2\x0F\x5E                  WILLAMETTE,SSE2
-MAXPD          xmmreg,xmmreg                   \3\x66\x0F\x5F                  WILLAMETTE,SSE2
-MAXPD          mem,xmmreg                              \3\x66\x0F\x5F                  WILLAMETTE,SSE2
-MAXSD          xmmreg,xmmreg                   \3\xF2\x0F\x5F                  WILLAMETTE,SSE2
-MAXSD          mem,xmmreg                              \3\xF2\x0F\x5F                  WILLAMETTE,SSE2
-MINPD          xmmreg,xmmreg                   \3\x66\x0F\x5D                  WILLAMETTE,SSE2
-MINPD          mem,xmmreg                              \3\x66\x0F\x5D                  WILLAMETTE,SSE2
-MINSD          xmmreg,xmmreg                   \3\xF2\x0F\x5D                  WILLAMETTE,SSE2
-MINSD          mem,xmmreg                              \3\xF2\x0F\x5D                  WILLAMETTE,SSE2
-MOVAPD         xmmreg,xmmreg                   \3\x66\x0F\x28                  WILLAMETTE,SSE2
-MOVAPD         xmmreg,xmmreg                   \3\x66\x0F\x29                  WILLAMETTE,SSE2
-MOVAPD         mem,xmmreg                              \3\x66\x0F\x29                  WILLAMETTE,SSE2
-MOVAPD         xmmreg,mem                              \3\x66\x0F\x28                  WILLAMETTE,SSE2
-MOVHPD         mem,xmmreg                              \3\x66\x0F\x17                  WILLAMETTE,SSE2
-MOVHPD         xmmreg,xmmreg                   \3\x66\x0F\x16                  WILLAMETTE,SSE2
-MOVLPD         mem,xmmreg                              \3\x66\x0F\x13                  WILLAMETTE,SSE2
-MOVLPD         xmmreg,xmmreg                   \3\x66\x0F\x12                  WILLAMETTE,SSE2
-MOVMSKPD       xmmreg,reg32                    \3\x66\x0F\x50                  WILLAMETTE,SSE2
-MOVSD          xmmreg,xmmreg                   \3\xF2\x0F\x10                  WILLAMETTE,SSE2
-MOVSD          xmmreg,xmmreg                   \3\xF2\x0F\x11                  WILLAMETTE,SSE2
-MOVSD          mem,xmmreg                              \3\xF2\x0F\x11                  WILLAMETTE,SSE2
-MOVSD          xmmreg,mem                              \3\xF2\x0F\x10                  WILLAMETTE,SSE2
-MOVUPD         xmmreg,xmmreg                   \3\x66\x0F\x10                  WILLAMETTE,SSE2
-MOVUPD         xmmreg,xmmreg                   \3\x66\x0F\x11                  WILLAMETTE,SSE2
-MOVUPD         mem,xmmreg                              \3\x66\x0F\x11                  WILLAMETTE,SSE2
-MOVUPD         xmmreg,mem                              \3\x66\x0F\x10                  WILLAMETTE,SSE2
-MULPD          xmmreg,xmmreg                   \3\x66\x0F\x59                  WILLAMETTE,SSE2
-MULPD          mem,xmmreg                              \3\x66\x0F\x59                  WILLAMETTE,SSE2
-MULSD          xmmreg,xmmreg                   \3\xF2\x0F\x59                  WILLAMETTE,SSE2
-MULSD          mem,xmmreg                              \3\xF2\x0F\x59                  WILLAMETTE,SSE2
-ORPD           mem,xmmreg                              \3\x66\x0F\x56                  WILLAMETTE,SSE2
-ORPD           xmmreg,xmmreg,imm8              \3\x66\x0F\x56                  WILLAMETTE,SSE2
-SHUFPD         xmmreg,xmmreg,imm8              \3\x66\x0F\xC6                  WILLAMETTE,SSE2
-SHUFPD         mem,xmmreg                              \3\x66\x0F\xC6                  WILLAMETTE,SSE2
-SQRTPD         xmmreg,xmmreg                   \3\x66\x0F\x51                  WILLAMETTE,SSE2
-SQRTPD         mem,xmmreg                              \3\x66\x0F\x51                  WILLAMETTE,SSE2
-SQRTSD         xmmreg,xmmreg                   \3\xF2\x0F\x51                  WILLAMETTE,SSE2
-SQRTSD         mem,xmmreg                              \3\xF2\x0F\x51                  WILLAMETTE,SSE2
-SUBPD          xmmreg,xmmreg                   \3\x66\x0F\x5C                  WILLAMETTE,SSE2
-SUBPD          mem,xmmreg                              \3\x66\x0F\x5C                  WILLAMETTE,SSE2
-SUBSD          xmmreg,xmmreg                   \3\xF2\x0F\x5C                  WILLAMETTE,SSE2
-SUBSD          mem,xmmreg                              \3\xF2\x0F\x5C                  WILLAMETTE,SSE2
-UCOMISD        xmmreg,xmmreg                   \3\x66\x0F\x2E                  WILLAMETTE,SSE2
-UCOMISD        mem,xmmreg                              \3\x66\x0F\x2E                  WILLAMETTE,SSE2
-UNPCKHPD       xmmreg,xmmreg                   \3\x66\x0F\x15                  WILLAMETTE,SSE2
-UNPCKHPD       mem,xmmreg                              \3\x66\x0F\x15                  WILLAMETTE,SSE2
-UNPCKLPD       xmmreg,xmmreg                   \3\x66\x0F\x14                  WILLAMETTE,SSE2
-UNPCKLPD       mem,xmmreg                              \3\x66\x0F\x14                  WILLAMETTE,SSE2
-XORPD          xmmreg,xmmreg                   \3\x66\x0F\x57                  WILLAMETTE,SSE2
-XORPD          mem,xmmreg                              \3\x66\x0F\x57                  WILLAMETTE,SSE2
+ADDPD           xmmreg,xmmreg           \331\3\x66\x0F\x58\110          WILLAMETTE,SSE2
+ADDPD           xmmreg,mem              \301\331\3\x66\x0F\x58\110      WILLAMETTE,SSE2,SM
+ADDSD           xmmreg,xmmreg           \331\3\xF2\x0F\x58\110          WILLAMETTE,SSE2
+ADDSD           xmmreg,mem              \301\331\3\xF2\x0F\x58\110      WILLAMETTE,SSE2
+ANDNPD          xmmreg,xmmreg           \331\3\x66\x0F\x55\110          WILLAMETTE,SSE2
+ANDNPD          xmmreg,mem              \301\331\3\x66\x0F\x55\110      WILLAMETTE,SSE2,SM
+ANDPD           xmmreg,xmmreg           \331\3\x66\x0F\x54\110          WILLAMETTE,SSE2
+ANDPD           xmmreg,mem              \301\331\3\x66\x0F\x54\110      WILLAMETTE,SSE2,SM
+CMPEQPD         xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x00    WILLAMETTE,SSE2,SM
+CMPEQPD         xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x00        WILLAMETTE,SSE2
+CMPEQSD         xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x00    WILLAMETTE,SSE2
+CMPEQSD         xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x00        WILLAMETTE,SSE2
+CMPLEPD         xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x02    WILLAMETTE,SSE2,SM
+CMPLEPD         xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x02        WILLAMETTE,SSE2
+CMPLESD         xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x02    WILLAMETTE,SSE2
+CMPLESD         xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x02        WILLAMETTE,SSE2
+CMPLTPD         xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x01    WILLAMETTE,SSE2,SM
+CMPLTPD         xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x01        WILLAMETTE,SSE2
+CMPLTSD         xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x01    WILLAMETTE,SSE2
+CMPLTSD         xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x01        WILLAMETTE,SSE2
+CMPNEQPD        xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x04    WILLAMETTE,SSE2,SM
+CMPNEQPD        xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x04        WILLAMETTE,SSE2
+CMPNEQSD        xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x04    WILLAMETTE,SSE2
+CMPNEQSD        xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x04        WILLAMETTE,SSE2
+CMPNLEPD        xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x06    WILLAMETTE,SSE2,SM
+CMPNLEPD        xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x06        WILLAMETTE,SSE2
+CMPNLESD        xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x06    WILLAMETTE,SSE2
+CMPNLESD        xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x06        WILLAMETTE,SSE2
+CMPNLTPD        xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x05    WILLAMETTE,SSE2,SM
+CMPNLTPD        xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x05        WILLAMETTE,SSE2
+CMPNLTSD        xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x05    WILLAMETTE,SSE2
+CMPNLTSD        xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x05        WILLAMETTE,SSE2
+CMPORDPD        xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x07    WILLAMETTE,SSE2,SM
+CMPORDPD        xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x07        WILLAMETTE,SSE2
+CMPORDSD        xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x07    WILLAMETTE,SSE2
+CMPORDSD        xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x07        WILLAMETTE,SSE2
+CMPUNORDPD      xmmreg,mem              \301\331\3\x66\x0F\xC2\110\1\x03    WILLAMETTE,SSE2,SM
+CMPUNORDPD      xmmreg,xmmreg           \331\3\x66\x0F\xC2\110\1\x03        WILLAMETTE,SSE2
+CMPUNORDSD      xmmreg,mem              \301\331\3\xF2\x0F\xC2\110\1\x03    WILLAMETTE,SSE2
+CMPUNORDSD      xmmreg,xmmreg           \331\3\xF2\x0F\xC2\110\1\x03        WILLAMETTE,SSE2
+; CMPPD/CMPSD must come after the specific ops; that way the disassembler will find the
+; specific ops first and only disassemble illegal ones as cmppd/cmpsd.
+CMPPD           xmmreg,xmmreg,imm       \331\3\x66\x0F\xC2\110\26       WILLAMETTE,SSE2,SB,AR2
+CMPPD           xmmreg,mem,imm          \301\331\3\x66\x0F\xC2\110\26   WILLAMETTE,SSE2,SM2,SB,AR2
+CMPSD           xmmreg,xmmreg,imm       \331\3\xF2\x0F\xC2\110\26       WILLAMETTE,SSE2,SB,AR2
+CMPSD           xmmreg,mem,imm          \301\331\3\xF2\x0F\xC2\110\26   WILLAMETTE,SSE2,SB,AR2
+COMISD          xmmreg,xmmreg           \331\3\x66\x0F\x2F\110          WILLAMETTE,SSE2
+COMISD          xmmreg,mem              \301\331\3\x66\x0F\x2F\110      WILLAMETTE,SSE2
+CVTDQ2PD        xmmreg,xmmreg           \333\2\x0F\xE6\110              WILLAMETTE,SSE2
+CVTDQ2PD        xmmreg,mem              \301\333\2\x0F\xE6\110          WILLAMETTE,SSE2
+CVTDQ2PS        xmmreg,xmmreg           \2\x0F\x5B\110                  WILLAMETTE,SSE2
+CVTDQ2PS        xmmreg,mem              \301\2\x0F\x5B\110              WILLAMETTE,SSE2,SM
+CVTPD2DQ        xmmreg,xmmreg           \3\xF2\x0F\xE6\110              WILLAMETTE,SSE2
+CVTPD2DQ        xmmreg,mem              \301\3\xF2\x0F\xE6\110          WILLAMETTE,SSE2,SM
+CVTPD2PI        mmxreg,xmmreg           \3\x66\x0F\x2D\110              WILLAMETTE,SSE2
+CVTPD2PI        mmxreg,mem              \301\3\x66\x0F\x2D\110          WILLAMETTE,SSE2
+CVTPD2PS        xmmreg,xmmreg           \3\x66\x0F\x5A\110              WILLAMETTE,SSE2
+CVTPD2PS        xmmreg,mem              \301\3\x66\x0F\x5A\110          WILLAMETTE,SSE2,SM
+CVTPI2PD        xmmreg,mmxreg           \3\x66\x0F\x2A\110              WILLAMETTE,SSE2
+CVTPI2PD        xmmreg,mem              \301\3\x66\x0F\x2A\110          WILLAMETTE,SSE2
+CVTPS2DQ        xmmreg,xmmreg           \3\x66\x0F\x5B\110              WILLAMETTE,SSE2
+CVTPS2DQ        xmmreg,mem              \301\3\x66\x0F\x5B\110          WILLAMETTE,SSE2,SM
+CVTPS2PD        xmmreg,xmmreg           \2\x0F\x5A\110                  WILLAMETTE,SSE2
+CVTPS2PD        xmmreg,mem              \301\2\x0F\x5A\110              WILLAMETTE,SSE2
+CVTSD2SI        reg32,xmmreg            \3\xF2\x0F\x2D\110              WILLAMETTE,SSE2
+CVTSD2SI        reg32,mem               \301\3\xF2\x0F\x2D\110          WILLAMETTE,SSE2
+CVTSD2SS        xmmreg,xmmreg           \3\xF2\x0F\x5A\110              WILLAMETTE,SSE2
+CVTSD2SS        xmmreg,mem              \301\3\xF2\x0F\x5A\110          WILLAMETTE,SSE2
+CVTSI2SD        xmmreg,reg32            \3\xF2\x0F\x2A\110              WILLAMETTE,SSE2
+CVTSI2SD        xmmreg,mem              \301\3\xF2\x0F\x2A\110          WILLAMETTE,SSE2
+CVTSS2SD        xmmreg,xmmreg           \333\2\x0F\x5A\110              WILLAMETTE,SSE2
+CVTSS2SD        xmmreg,mem              \301\333\2\x0F\x5A\110          WILLAMETTE,SSE2
+CVTTPD2PI       mmxreg,xmmreg           \3\x66\x0F\x2C\110              WILLAMETTE,SSE2
+CVTTPD2PI       mmxreg,mem              \301\3\x66\x0F\x2C\110          WILLAMETTE,SSE2
+CVTTPD2DQ       xmmreg,xmmreg           \3\x66\x0F\xE6\110              WILLAMETTE,SSE2
+CVTTPD2DQ       xmmreg,mem              \301\3\x66\x0F\xE6\110          WILLAMETTE,SSE2,SM
+CVTTPS2DQ       xmmreg,xmmreg           \333\2\x0F\x5B\110              WILLAMETTE,SSE2
+CVTTPS2DQ       xmmreg,mem              \301\333\2\x0F\x5B\110          WILLAMETTE,SSE2,SM
+CVTTSD2SI       reg32,xmmreg            \3\xF2\x0F\x2C\110              WILLAMETTE,SSE2
+CVTTSD2SI       reg32,mem               \301\3\xF2\x0F\x2C\110          WILLAMETTE,SSE2
+DIVPD           xmmreg,xmmreg           \3\x66\x0F\x5E\110              WILLAMETTE,SSE2
+DIVPD           xmmreg,mem              \301\3\x66\x0F\x5E\110          WILLAMETTE,SSE2,SM
+DIVSD           xmmreg,xmmreg           \3\xF2\x0F\x5E\110              WILLAMETTE,SSE2
+DIVSD           xmmreg,mem              \301\3\xF2\x0F\x5E\110          WILLAMETTE,SSE2
+MAXPD           xmmreg,xmmreg           \3\x66\x0F\x5F\110              WILLAMETTE,SSE2
+MAXPD           xmmreg,mem              \301\3\x66\x0F\x5F\110          WILLAMETTE,SSE2,SM
+MAXSD           xmmreg,xmmreg           \3\xF2\x0F\x5F\110              WILLAMETTE,SSE2
+MAXSD           xmmreg,mem              \301\3\xF2\x0F\x5F\110          WILLAMETTE,SSE2
+MINPD           xmmreg,xmmreg           \3\x66\x0F\x5D\110              WILLAMETTE,SSE2
+MINPD           xmmreg,mem              \301\3\x66\x0F\x5D\110          WILLAMETTE,SSE2,SM
+MINSD           xmmreg,xmmreg           \3\xF2\x0F\x5D\110              WILLAMETTE,SSE2
+MINSD           xmmreg,mem              \301\3\xF2\x0F\x5D\110          WILLAMETTE,SSE2
+MOVAPD          xmmreg,xmmreg           \3\x66\x0F\x28\110              WILLAMETTE,SSE2
+MOVAPD          xmmreg,xmmreg           \3\x66\x0F\x29\110              WILLAMETTE,SSE2
+MOVAPD          mem,xmmreg              \300\3\x66\x0F\x29\101          WILLAMETTE,SSE2,SM
+MOVAPD          xmmreg,mem              \301\3\x66\x0F\x28\110          WILLAMETTE,SSE2,SM
+MOVHPD          mem,xmmreg              \300\3\x66\x0F\x17\101          WILLAMETTE,SSE2
+MOVHPD          xmmreg,mem              \301\3\x66\x0F\x16\110          WILLAMETTE,SSE2
+MOVLPD          mem,xmmreg              \300\3\x66\x0F\x13\101          WILLAMETTE,SSE2
+MOVLPD          xmmreg,mem              \301\3\x66\x0F\x12\110          WILLAMETTE,SSE2
+MOVMSKPD        reg32,xmmreg            \3\x66\x0F\x50\110              WILLAMETTE,SSE2
+MOVSD           xmmreg,xmmreg           \3\xF2\x0F\x10\110              WILLAMETTE,SSE2
+MOVSD           xmmreg,xmmreg           \3\xF2\x0F\x11\110              WILLAMETTE,SSE2
+MOVSD           mem,xmmreg              \300\3\xF2\x0F\x11\101          WILLAMETTE,SSE2
+MOVSD           xmmreg,mem              \301\3\xF2\x0F\x10\110          WILLAMETTE,SSE2
+MOVUPD          xmmreg,xmmreg           \3\x66\x0F\x10\110              WILLAMETTE,SSE2
+MOVUPD          xmmreg,xmmreg           \3\x66\x0F\x11\110              WILLAMETTE,SSE2
+MOVUPD          mem,xmmreg              \300\3\x66\x0F\x11\101          WILLAMETTE,SSE2,SM
+MOVUPD          xmmreg,mem              \301\3\x66\x0F\x10\110          WILLAMETTE,SSE2,SM
+MULPD           xmmreg,xmmreg           \3\x66\x0F\x59\110              WILLAMETTE,SSE2
+MULPD           xmmreg,mem              \301\3\x66\x0F\x59\110          WILLAMETTE,SSE2,SM
+MULSD           xmmreg,xmmreg           \3\xF2\x0F\x59\110              WILLAMETTE,SSE2
+MULSD           xmmreg,mem              \301\3\xF2\x0F\x59\110          WILLAMETTE,SSE2
+ORPD            xmmreg,mem              \301\3\x66\x0F\x56\110          WILLAMETTE,SSE2,SM
+ORPD            xmmreg,xmmreg           \3\x66\x0F\x56\110              WILLAMETTE,SSE2
+SHUFPD          xmmreg,xmmreg,imm       \3\x66\x0F\xC6\110\26           WILLAMETTE,SSE2,SB,AR2
+SHUFPD          xmmreg,mem,imm          \301\3\x66\x0F\xC6\110\26       WILLAMETTE,SSE2,SM,SB,AR2
+SQRTPD          xmmreg,xmmreg           \3\x66\x0F\x51\110              WILLAMETTE,SSE2
+SQRTPD          xmmreg,mem              \301\3\x66\x0F\x51\110          WILLAMETTE,SSE2,SM
+SQRTSD          xmmreg,xmmreg           \3\xF2\x0F\x51\110              WILLAMETTE,SSE2
+SQRTSD          xmmreg,mem              \301\3\xF2\x0F\x51\110          WILLAMETTE,SSE2
+SUBPD           xmmreg,xmmreg           \3\x66\x0F\x5C\110              WILLAMETTE,SSE2
+SUBPD           xmmreg,mem              \301\3\x66\x0F\x5C\110          WILLAMETTE,SSE2,SM
+SUBSD           xmmreg,xmmreg           \3\xF2\x0F\x5C\110              WILLAMETTE,SSE2
+SUBSD           xmmreg,mem              \301\3\xF2\x0F\x5C\110          WILLAMETTE,SSE2
+UCOMISD         xmmreg,xmmreg           \3\x66\x0F\x2E\110              WILLAMETTE,SSE2
+UCOMISD         xmmreg,mem              \301\3\x66\x0F\x2E\110          WILLAMETTE,SSE2
+UNPCKHPD        xmmreg,xmmreg           \3\x66\x0F\x15\110              WILLAMETTE,SSE2
+UNPCKHPD        mem,xmmreg              \300\3\x66\x0F\x15\101          WILLAMETTE,SSE2,SM
+UNPCKLPD        xmmreg,xmmreg           \3\x66\x0F\x14\110              WILLAMETTE,SSE2
+UNPCKLPD        xmmreg,mem              \301\3\x66\x0F\x14\110          WILLAMETTE,SSE2,SM
+XORPD           xmmreg,xmmreg           \3\x66\x0F\x57\110              WILLAMETTE,SSE2
+XORPD           xmmreg,mem              \301\3\x66\x0F\x57\110          WILLAMETTE,SSE2,SM
index f137847..c793904 100644 (file)
--- a/labels.c
+++ b/labels.c
@@ -20,7 +20,6 @@
  * @@, so @@local is a TASM compatible local label. Note that we only
  * check for the first @ symbol, although TASM requires both.
  */
-#ifdef TASM_COMPAT
 #define islocal(l)                                              \
        (tasm_compatible_mode ?                                 \
        (((l)[0] == '.' || (l)[0] == '@') && (l)[1] != '.') :   \
        (tasm_compatible_mode ?                                  \
        ((c) == '.' || (c) == '@') :                            \
        ((c) == '.'))
-#else
-#define islocal(l) ((l)[0] == '.' && (l)[1] != '.')
-#define islocalchar(c) ((c) == '.')
-#endif
 
 #define LABEL_BLOCK  32               /* no. of labels/block */
 #define LBLK_SIZE    (LABEL_BLOCK*sizeof(union label))
index 570e7fb..5efc6db 100644 (file)
--- a/listing.c
+++ b/listing.c
@@ -122,7 +122,7 @@ static void list_out (long offset, char *str)
 
 static void list_output (long offset, void *data, unsigned long type) 
 {
-    long typ, size;
+    unsigned long typ, size;
 
     if (!listp || suppress || user_nolist)    /* fbk - 9/2/00 */
        return;
index 0a12bb0..e1d9ed0 100644 (file)
--- a/macros.pl
+++ b/macros.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -w
 #
 # macros.pl   produce macros.c from standard.mac
 #
@@ -6,6 +6,11 @@
 # Julian Hall. All rights reserved. The software is
 # redistributable under the licence given in the file "Licence"
 # distributed in the NASM archive.
+use strict;
+
+my $fname;
+my $line = 0;
+my $index = 0;
 
 $fname = "standard.mac" unless $fname = $ARGV[0];
 open INPUT,$fname || die "unable to open $fname\n";
@@ -15,14 +20,25 @@ print OUTPUT "/* This file auto-generated from standard.mac by macros.pl" .
         " - don't edit it */\n\nstatic char *stdmac[] = {\n";
 
 while (<INPUT>) {
-  chomp;
-  # this regexp ought to match anything at all, so why bother with
-  # a sensible error message ;-)
-  die "swirly thing alert" unless /^\s*((\s*([^"';\s]+|"[^"]*"|'[^']*'))*)/;
-  $_ = $1;
-  s/\\/\\\\/g;
-  s/"/\\"/g;
-  print OUTPUT "    \"$_\",\n" if length > 0;
+       $line++;
+       chomp;
+       if (m/^\s*((\s*([^"';\s]+|"[^"]*"|'[^']*'))*)\s*(;.*)?$/) {
+               $_ = $1;
+       s/\\/\\\\/g;
+       s/"/\\"/g;
+               if (length > 0) {
+                       print OUTPUT "    \"$_\",\n";
+                       if ($index >= 0) {
+                               if (m/__NASM_MAJOR__/) {
+                                       $index = -$index;
+                               } else {
+                                       $index++;
+                               }
+                       }               
+               } 
+       } else {
+               die "$fname:$line:  error unterminated quote";
+       }
 }
-
-print OUTPUT "    NULL\n};\n"
+$index = -$index;
+print OUTPUT "    NULL\n};\n#define TASM_MACRO_COUNT $index\n"
diff --git a/misc/scitech.mac b/misc/scitech.mac
new file mode 100644 (file)
index 0000000..26f85f4
--- /dev/null
@@ -0,0 +1,1223 @@
+;****************************************************************************
+;*
+;*  ========================================================================
+;*
+;*    The contents of this file are subject to the SciTech MGL Public
+;*    License Version 1.0 (the "License"); you may not use this file
+;*    except in compliance with the License. You may obtain a copy of
+;*    the License at http://www.scitechsoft.com/mgl-license.txt
+;*
+;*    Software distributed under the License is distributed on an
+;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+;*    implied. See the License for the specific language governing
+;*    rights and limitations under the License.
+;*
+;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
+;*
+;*    The Initial Developer of the Original Code is SciTech Software, Inc.
+;*    All Rights Reserved.
+;*
+;*  ========================================================================
+;*
+;* Language:    NetWide Assembler (NASM) or Turbo Assembler (TASM)
+;* Environment: Any Intel Environment
+;*
+;* Description: Macros to provide memory model independant assembly language
+;*              module for C programming. Supports the large and flat memory
+;*                             models.
+;*
+;*             The defines that you should use when assembling modules that
+;*                             use this macro package are:
+;*
+;*                                     __LARGE__       Assemble for 16-bit large model
+;*                  __FLAT__    Assemble for 32-bit FLAT memory model
+;*                  __NOU__            No underscore for all external C labels
+;*                                     __NOU_VAR__     No underscore for global variables only
+;*
+;*                             The default settings are for 16-bit large memory model with
+;*                             leading underscores for symbol names.
+;*
+;*                             The main intent of the macro file is to enable programmers
+;*                             to write _one_ set of source that can be assembled to run
+;*                             in either 16 bit real and protected modes or 32 bit
+;*                             protected mode without the need to riddle the code with
+;*                             'if flatmodel' style conditional assembly (it is still there
+;*                             but nicely hidden by a macro layer that enhances the
+;*                             readability and understandability of the resulting code).
+;*
+;****************************************************************************
+
+; Include the appropriate version in here depending on the assembler. NASM
+; appears to always try and parse code, even if it is in a non-compiling
+; block of a ifdef expression, and hence crashes if we include the TASM
+; macro package in the same header file. Hence we split the macros up into
+; two separate header files.
+
+ifdef __NASM_MAJOR__
+
+;============================================================================
+; Macro package when compiling with NASM.
+;============================================================================
+
+; Turn off underscores for globals if disabled for all externals
+
+%ifdef __NOU__
+%define        __NOU_VAR__
+%endif
+
+; Define the __WINDOWS__ symbol if we are compiling for any Windows
+; environment
+
+%ifdef __WINDOWS16__
+%define        __WINDOWS__                     1
+%endif
+%ifdef __WINDOWS32__
+%define __WINDOWS__                    1
+%define __WINDOWS32_386__      1
+%endif
+
+; Macros for accessing 'generic' registers
+
+%ifdef __FLAT__
+%idefine _ax   eax
+%idefine _bx   ebx
+%idefine _cx   ecx
+%idefine _dx   edx
+%idefine _si   esi
+%idefine _di   edi
+%idefine _bp   ebp
+%idefine _sp   esp
+%idefine _es
+%idefine UCHAR         BYTE            ; Size of a character
+%idefine USHORT WORD           ; Size of a short
+%idefine UINT  DWORD           ; Size of an integer
+%idefine ULONG         DWORD           ; Size of a long
+%idefine BOOL  DWORD           ; Size of a boolean
+%idefine DPTR  DWORD           ; Size of a data pointer
+%idefine FDPTR         FWORD           ; Size of a far data pointer
+%idefine NDPTR         DWORD           ; Size of a near data pointer
+%idefine CPTR  DWORD           ; Size of a code pointer
+%idefine FCPTR         FWORD           ; Size of a far code pointer
+%idefine NCPTR         DWORD           ; Size of a near code pointer
+%idefine FPTR  NEAR            ; Distance for function pointers
+%idefine DUINT dd                      ; Declare a integer variable
+%idefine intsize 4
+%idefine flatmodel 1
+%else
+%idefine _ax   ax
+%idefine _bx   bx
+%idefine _cx   cx
+%idefine _dx   dx
+%idefine _si   si
+%idefine _di   di
+%idefine _bp   bp
+%idefine _sp   sp
+%idefine _es   es:
+%idefine UCHAR         BYTE            ; Size of a character
+%idefine USHORT WORD           ; Size of a short
+%idefine UINT  WORD            ; Size of an integer
+%idefine ULONG         DWORD           ; Size of a long
+%idefine BOOL  WORD            ; Size of a boolean
+%idefine DPTR  DWORD           ; Size of a data pointer
+%idefine FDPTR         DWORD           ; Size of a far data pointer
+%idefine NDPTR         WORD            ; Size of a near data pointer
+%idefine CPTR  DWORD           ; Size of a code pointer
+%idefine FCPTR         DWORD           ; Size of a far code pointer
+%idefine NCPTR         WORD            ; Size of a near code pointer
+%idefine FPTR   FAR                    ; Distance for function pointers
+%idefine DUINT dw                      ; Declare a integer variable
+%idefine intsize 2
+%endif
+%idefine invert ~
+%idefine offset
+%idefine use_nasm
+
+; Convert all jumps to near jumps, since NASM does not so this automatically
+
+%idefine jo            jo near
+%idefine jno   jno near
+%idefine jz            jz near
+%idefine jnz   jnz near
+%idefine je            je near
+%idefine jne   jne near
+%idefine jb            jb      near
+%idefine jbe   jbe     near
+%idefine ja            ja      near
+%idefine jae   jae     near
+%idefine jl            jl      near
+%idefine jle   jle     near
+%idefine jg            jg      near
+%idefine jge   jge     near
+%idefine jc            jc      near
+%idefine jnc   jnc     near
+%idefine js            js      near
+%idefine jns   jns     near
+
+%ifdef DOUBLE
+%idefine       REAL    QWORD
+%idefine       DREAL   dq
+%else
+%idefine       REAL    DWORD
+%idefine       DREAL   dd
+%endif
+
+; Boolean truth values (same as those in debug.h)
+
+%idefine False         0
+%idefine True          1
+%idefine No                    0
+%idefine Yes           1
+%idefine Yes           1
+
+; Macro to be invoked at the start of all modules to set up segments for
+; later use. Does nothing for NASM.
+
+%imacro header 1
+%endmacro
+
+; Macro to begin a data segment
+
+%imacro begdataseg 1
+%ifdef __GNUC__
+segment .data public class=DATA use32 flat
+%else
+%ifdef flatmodel
+segment _DATA public align=4 class=DATA use32 flat
+%else
+segment _DATA public align=4 class=DATA use16
+%endif
+%endif
+%endmacro
+
+; Macro to end a data segment
+
+%imacro enddataseg 1
+%endmacro
+
+; Macro to begin a code segment
+
+%imacro begcodeseg 1
+%ifdef __GNUC__
+segment .text public class=CODE use32 flat
+%else
+%ifdef flatmodel
+segment _TEXT public align=16 class=CODE use32 flat
+%else
+segment %1_TEXT public align=16 class=CODE use16
+%endif
+%endif
+%endmacro
+
+; Macro to begin a near code segment
+
+%imacro begcodeseg_near 0
+%ifdef __GNUC__
+segment .text public class=CODE use32 flat
+%else
+%ifdef flatmodel
+segment _TEXT public align=16 class=CODE use32 flat
+%else
+segment _TEXT public align=16 class=CODE use16
+%endif
+%endif
+%endmacro
+
+; Macro to end a code segment
+
+%imacro endcodeseg 1
+%endmacro
+
+; Macro to end a near code segment
+
+%imacro endcodeseg_near 0
+%endmacro
+
+; Macro for an extern C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+%imacro cextern 2
+%ifdef __NOU_VAR__
+extern %1
+%else
+extern _%1
+%define        %1 _%1
+%endif
+%endmacro
+
+%imacro cexternfunc 2
+%ifdef __NOU__
+extern %1
+%else
+extern _%1
+%define        %1 _%1
+%endif
+%endmacro
+
+; Macro for a public C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+%imacro cpublic 1
+%ifdef __NOU_VAR__
+global %1
+%1:
+%else
+global _%1
+_%1:
+%define        %1 _%1
+%endif
+%endmacro
+
+; Macro for an global C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+%imacro cglobal 1
+%ifdef __NOU_VAR__
+global %1
+%else
+global _%1
+%define        %1 _%1
+%endif
+%endmacro
+
+; Macro for an global C function symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+%imacro cglobalfunc 1
+%ifdef __NOU__
+global %1
+%else
+global _%1
+%define        %1 _%1
+%endif
+%endmacro
+
+; Macro to start a C callable function. This will be a far function for
+; 16-bit code, and a near function for 32-bit code.
+
+%imacro cprocstatic 1
+%push cproc
+%1:
+%ifdef flatmodel
+%stacksize flat
+%define ret    retn
+%else
+%stacksize large
+%define ret    retf
+%endif
+%assign %$localsize 0
+%endmacro
+
+%imacro cprocstart 1
+%push cproc
+       cglobalfunc %1
+%1:
+%ifdef flatmodel
+%stacksize flat
+%define ret    retn
+%else
+%stacksize large
+%define ret    retf
+%endif
+%assign %$localsize 0
+%endmacro
+
+; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
+; calling conventions are always _far _pascal for 16 bit DLL's, we actually
+; rename this routine with an extra underscore with 'C' calling conventions
+; and a small DLL stub will be provided by the high level code to call the
+; assembler routine.
+
+%imacro        cprocstartdll16 1
+%ifdef __WINDOWS16__
+cprocstart     _%1
+%else
+cprocstart     %1
+%endif
+%endmacro
+
+; Macro to start a C callable near function.
+
+%imacro cprocnear 1
+%push cproc
+       cglobalfunc %1
+%1:
+%define ret    retn
+%ifdef flatmodel
+%stacksize flat
+%else
+%stacksize small
+%endif
+%assign %$localsize 0
+%endmacro
+
+; Macro to start a C callable far function.
+
+%imacro cprocfar 1
+%push cproc
+       cglobalfunc %1
+%1:
+%define ret    retf
+%ifdef flatmodel
+%stacksize flat
+%else
+%stacksize large
+%endif
+%assign %$localsize 0
+%endmacro
+
+; Macro to end a C function
+
+%imacro cprocend 0
+%pop
+%endmacro
+
+; Macros for entering and exiting C callable functions. Note that we must
+; always save and restore the SI and DI registers for C functions, and for
+; 32 bit C functions we also need to save and restore EBX and clear the
+; direction flag.
+
+%imacro enter_c 0
+               push    _bp
+               mov     _bp,_sp
+%ifnidn        %$localsize,0
+               sub             _sp,%$localsize
+%endif
+%ifdef flatmodel
+               push    ebx
+%endif
+               push    _si
+               push    _di
+%endmacro
+
+%imacro leave_c 0
+               pop             _di
+               pop             _si
+%ifdef flatmodel
+               pop             ebx
+               cld
+%endif
+%ifnidn %$localsize,0
+               mov     _sp,_bp
+%endif
+               pop     _bp
+%endmacro
+
+%imacro   use_ebx 0
+%ifdef flatmodel
+               push    ebx
+%endif
+%endmacro
+
+%imacro   unuse_ebx 0
+%ifdef flatmodel
+               pop     ebx
+%endif
+%endmacro
+
+; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
+; be used in assembly routines. This evaluates to nothing in the flat memory
+; model, but is saves and restores DS in the large memory model.
+
+%imacro        use_ds 0
+%ifndef flatmodel
+               push    ds
+%endif
+%endmacro
+
+%imacro        unuse_ds 0
+%ifndef flatmodel
+               pop             ds
+%endif
+%endmacro
+
+%imacro        use_es 0
+%ifndef flatmodel
+               push    es
+%endif
+%endmacro
+
+%imacro        unuse_es 0
+%ifndef flatmodel
+               pop             es
+%endif
+%endmacro
+
+; Macros for loading the address of a data pointer into a segment and
+; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
+; memory model, or it simply loads the offset into the register in the flat
+; memory model since DS and ES always point to all addressable memory. You
+; must use the correct _REG (ie: _BX) %imacros for documentation purposes.
+
+%imacro        _lds    2
+%ifdef flatmodel
+               mov     %1,%2
+%else
+               lds             %1,%2
+%endif
+%endmacro
+
+%imacro   _les 2
+%ifdef flatmodel
+               mov     %1,%2
+%else
+               les             %1,%2
+%endif
+%endmacro
+
+; Macros for adding and subtracting a value from registers. Two value are
+; provided, one for 16 bit modes and another for 32 bit modes (the extended
+; register is used in 32 bit modes).
+
+%imacro   _add 3
+%ifdef flatmodel
+               add             e%1, %3
+%else
+               add             %1, %2
+%endif
+%endmacro
+
+%imacro        _sub    3
+%ifdef flatmodel
+               sub             e%1, %3
+%else
+               sub             %1, %2
+%endif
+%endmacro
+
+; Macro to clear the high order word for the 32 bit extended registers.
+; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
+; value, and will evaluate to nothing in 16 bit modes.
+
+%imacro        clrhi   1
+%ifdef flatmodel
+               movzx   e%1,%1
+%endif
+%endmacro
+
+%imacro        sgnhi   1
+%ifdef flatmodel
+               movsx   e%1,%1
+%endif
+%endmacro
+
+; Macro to load an extended register with an integer value in either mode
+
+%imacro        loadint 2
+%ifdef flatmodel
+               mov             e%1,%2
+%else
+               xor             e%1,e%1
+               mov     %1,%2
+%endif
+%endmacro
+
+; Macros to load and store integer values with string instructions
+
+%imacro        LODSINT 0
+%ifdef flatmodel
+               lodsd
+%else
+               lodsw
+%endif
+%endmacro
+
+%imacro        STOSINT 0
+%ifdef flatmodel
+               stosd
+%else
+               stosw
+%endif
+%endmacro
+
+; Macros to provide resb, resw, resd compatibility with NASM
+
+%imacro        dclb 1
+times %1 db 0
+%endmacro
+
+%imacro        dclw 1
+times %1 dw 0
+%endmacro
+
+%imacro        dcld 1
+times %1 dd 0
+%endmacro
+
+; macros to declare assembler function stubs for function structures
+
+%imacro        BEGIN_STUBS_DEF 2
+begdataseg  _STUBS
+%ifdef __NOU_VAR__
+extern %1
+%define        STUBS_START     %1
+%else
+extern _%1
+%define        STUBS_START     _%1
+%endif
+enddataseg  _STUBS
+begcodeseg  _STUBS
+%assign off %2
+%endmacro
+
+%imacro   DECLARE_STUB 1
+%ifdef __NOU__
+               global %1
+%1:
+%else
+               global _%1
+_%1:
+%endif
+               jmp     [DWORD STUBS_START+off]
+%assign off off+4
+%endmacro
+
+%imacro DECLARE_STDCALL 2
+%ifdef STDCALL_MANGLE
+               global _%1@%2
+_%1@%2:
+%else
+%ifdef __GNUC__
+               global _%1
+_%1:
+%else
+               global %1
+%1:
+%endif
+%endif
+               jmp     [DWORD STUBS_START+off]
+%assign off off+4
+%endmacro
+
+%imacro   END_STUBS_DEF 0
+endcodeseg  _STUBS
+%endmacro
+
+; macros to declare assembler import stubs for binary loadable drivers
+
+%imacro        BEGIN_IMPORTS_DEF       1
+BEGIN_STUBS_DEF        %1,4
+%endmacro
+
+%imacro   DECLARE_IMP  1
+DECLARE_STUB   %1
+%endmacro
+
+%imacro   END_IMPORTS_DEF 0
+END_STUBS_DEF
+%endmacro
+
+else   ; __NASM_MAJOR__
+
+;============================================================================
+; Macro package when compiling with TASM.
+;============================================================================
+
+; Turn off underscores for globals if disabled for all externals
+
+ifdef  __NOU__
+__NOU_VAR__                    = 1
+endif
+
+; Define the __WINDOWS__ symbol if we are compiling for any Windows
+; environment
+
+ifdef  __WINDOWS16__
+__WINDOWS__            = 1
+endif
+ifdef  __WINDOWS32__
+__WINDOWS__            = 1
+__WINDOWS32_386__      = 1
+endif
+ifdef  __WIN386__
+__WINDOWS__            = 1
+__WINDOWS32_386__      = 1
+endif
+ifdef  __VXD__
+__WINDOWS__            = 1
+__WINDOWS32_386__      = 1
+               MASM
+               .386
+               NO_SEGMENTS     = 1
+               include vmm.inc                 ; IGNORE DEPEND
+               include vsegment.inc    ; IGNORE DEPEND
+               IDEAL
+endif
+
+; Macros for accessing 'generic' registers
+
+ifdef   __FLAT__
+               _ax                     EQU     eax             ; EAX is used for accumulator
+               _bx                     EQU     ebx             ; EBX is used for accumulator
+               _cx             EQU ecx     ; ECX is used for looping
+               _dx                     EQU     edx             ; EDX is used for data register
+               _si                     EQU     esi             ; ESI is the source index register
+               _di                     EQU     edi             ; EDI is the destination index register
+               _bp                     EQU     ebp             ; EBP is used for base pointer register
+               _sp                     EQU     esp             ; ESP is used for stack pointer register
+               _es                     EQU                     ; ES and DS are the same in 32 bit PM
+               typedef UCHAR BYTE              ; Size of a character
+               typedef USHORT WORD             ; Size of a short
+               typedef UINT DWORD              ; Size of an integer
+               typedef ULONG DWORD             ; Size of a long
+               typedef BOOL DWORD      ; Size of a boolean
+               typedef DPTR DWORD              ; Size of a data pointer
+               typedef FDPTR FWORD             ; Size of a far data pointer
+               typedef NDPTR DWORD             ; Size of a near data pointer
+               typedef CPTR DWORD              ; Size of a code pointer
+               typedef FCPTR FWORD             ; Size of a far code pointer
+               typedef NCPTR DWORD             ; Size of a near code pointer
+               typedef DUINT DWORD             ; Declare a integer variable
+               FPTR        EQU NEAR    ; Distance for function pointers
+               intsize         =       4               ; Size of an integer
+               flatmodel       =       1               ; This is a flat memory model
+               P386                    ; Turn on 386 code generation
+               MODEL       FLAT        ; Set up for 32 bit simplified FLAT model
+else
+               _ax                     EQU     ax              ; AX is used for accumulator
+               _bx                     EQU     bx              ; BX is used for accumulator
+               _cx             EQU cx          ; CX is used for looping
+               _dx                     EQU     dx              ; DX is used for data register
+               _si                     EQU     si              ; SI is the source index register
+               _di                     EQU     di              ; DI is the destination index register
+               _bp                     EQU     bp              ; BP is used for base pointer register
+               _sp                     EQU     sp              ; SP is used for stack pointer register
+               _es                     EQU es:         ; ES is used for segment override
+               typedef UCHAR BYTE      ; Size of a character
+               typedef USHORT WORD             ; Size of a short
+               typedef UINT WORD               ; Size of an integer
+               typedef ULONG DWORD             ; Size of a long
+               typedef BOOL WORD               ; Size of a boolean
+               typedef DPTR DWORD              ; Size of a data pointer
+               typedef FDPTR DWORD             ; Size of a far data pointer
+               typedef NDPTR WORD              ; Size of a near data pointer
+               typedef CPTR DWORD              ; Size of a code pointer
+               typedef FCPTR DWORD             ; Size of a far code pointer
+               typedef NCPTR WORD              ; Size of a near code pointer
+               typedef DUINT WORD              ; Declare a integer variable
+               FPTR        EQU FAR             ; Distance for function pointers
+               intsize         =       2               ; Size of an integer
+               P386                                    ; Turn on 386 code generation
+endif
+        invert      EQU not
+
+; Provide a typedef for real floating point numbers
+
+ifdef  DOUBLE
+typedef        REAL    QWORD
+typedef        DREAL   QWORD
+else
+typedef        REAL    DWORD
+typedef        DREAL   DWORD
+endif
+
+; Macros to access the floating point stack registers to convert them
+; from NASM style to TASM style
+
+st0                    EQU             st(0)
+st1                    EQU             st(1)
+st2                    EQU             st(2)
+st3                    EQU             st(3)
+st4                    EQU             st(4)
+st5                    EQU             st(5)
+st6                    EQU             st(6)
+st7                    EQU             st(7)
+st8                    EQU             st(8)
+
+; Boolean truth values (same as those in debug.h)
+
+ifndef __VXD__
+False          =               0
+True           =               1
+No                     =               0
+Yes                    =               1
+Yes                    =               1
+endif
+
+; Macros for the _DATA data segment. This segment contains initialised data.
+
+MACRO   begdataseg name
+ifdef  __VXD__
+               MASM
+VXD_LOCKED_DATA_SEG
+               IDEAL
+else
+ifdef   flatmodel
+               DATASEG
+else
+SEGMENT _DATA DWORD PUBLIC USE16 'DATA'
+endif
+endif
+ENDM
+
+MACRO   enddataseg name
+ifdef  __VXD__
+               MASM
+VXD_LOCKED_DATA_ENDS
+               IDEAL
+else
+ifndef  flatmodel
+ENDS    _DATA
+endif
+endif
+ENDM
+
+; Macro for the main code segment.
+
+MACRO   begcodeseg name
+ifdef  __VXD__
+               MASM
+VXD_LOCKED_CODE_SEG
+               IDEAL
+else
+ifdef   flatmodel
+               CODESEG
+               ASSUME  CS:FLAT,DS:FLAT,SS:FLAT
+else
+SEGMENT &name&_TEXT PARA PUBLIC USE16 'CODE'
+               ASSUME CS:&name&_TEXT,DS:_DATA
+endif
+endif
+ENDM
+
+; Macro for a near code segment
+
+MACRO   begcodeseg_near
+ifdef   flatmodel
+               CODESEG
+               ASSUME  CS:FLAT,DS:FLAT,SS:FLAT
+else
+SEGMENT _TEXT PARA PUBLIC USE16 'CODE'
+               ASSUME CS:_TEXT,DS:_DATA
+endif
+ENDM
+
+MACRO   endcodeseg name
+ifdef  __VXD__
+               MASM
+VXD_LOCKED_CODE_ENDS
+               IDEAL
+else
+ifndef  flatmodel
+ENDS    &name&_TEXT
+endif
+endif
+ENDM
+
+MACRO   endcodeseg_near
+ifndef  flatmodel
+ENDS    _TEXT
+endif
+ENDM
+
+; Macro to be invoked at the start of all modules to set up segments for
+; later use.
+
+MACRO   header name
+begdataseg name
+enddataseg name
+ENDM
+
+; Macro for an extern C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+MACRO   cextern        name,size
+ifdef  __NOU_VAR__
+               EXTRN   name:size
+else
+               EXTRN   _&name&:size
+name   EQU             _&name&
+endif
+ENDM
+
+MACRO   cexternfunc    name,size
+ifdef  __NOU__
+               EXTRN   name:size
+else
+               EXTRN   _&name&:size
+name   EQU             _&name&
+endif
+ENDM
+
+MACRO   stdexternfunc  name,args,size
+ifdef  STDCALL_MANGLE
+               EXTRN   _&name&@&num_args&:size
+name   EQU             _&name&@&num_args
+else
+               EXTRN   name:size
+endif
+ENDM
+
+; Macro for a public C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+MACRO  cpublic name
+ifdef  __NOU_VAR__
+name:
+               PUBLIC  name
+else
+_&name&:
+               PUBLIC  _&name&
+name   EQU             _&name&
+endif
+ENDM
+
+; Macro for an global C symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+MACRO  cglobal name
+ifdef  __NOU_VAR__
+               PUBLIC  name
+else
+               PUBLIC  _&name&
+name   EQU             _&name&
+endif
+ENDM
+
+; Macro for an global C function symbol. If the C compiler requires leading
+; underscores, then the underscores are added to the symbol names, otherwise
+; they are left off. The symbol name is referenced in the assembler code
+; using the non-underscored symbol name.
+
+MACRO  cglobalfunc name
+ifdef  __NOU__
+               PUBLIC  name
+else
+               PUBLIC  _&name&
+name   EQU             _&name&
+endif
+ENDM
+
+; Macro to start a C callable function. This will be a far function for
+; 16-bit code, and a near function for 32-bit code.
+
+MACRO   cprocstatic name               ; Set up model independant private proc
+ifdef flatmodel
+PROC           name NEAR
+else
+PROC    name FAR
+endif
+LocalSize      = 0
+ENDM
+
+MACRO   cprocstart name                ; Set up model independant proc
+ifdef flatmodel
+ifdef  __NOU__
+PROC           name NEAR
+else
+PROC           _&name& NEAR
+endif
+else
+ifdef  __NOU__
+PROC    name FAR
+else
+PROC    _&name& FAR
+endif
+endif
+LocalSize      = 0
+               cglobalfunc     name
+ENDM
+
+MACRO   cprocnear name                 ; Set up near proc
+ifdef  __NOU__
+PROC    name NEAR
+else
+PROC    _&name& NEAR
+endif
+LocalSize      = 0
+               cglobalfunc     name
+ENDM
+
+MACRO   cprocfar name           ; Set up far proc
+ifdef  __NOU__
+PROC    name FAR
+else
+PROC    _&name& FAR
+endif
+LocalSize      = 0
+               cglobalfunc     name
+ENDM
+
+MACRO   cprocend                  ; End procedure macro
+ENDP
+ENDM
+
+; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
+; calling conventions are always _far _pascal for 16 bit DLL's, we actually
+; rename this routine with an extra underscore with 'C' calling conventions
+; and a small DLL stub will be provided by the high level code to call the
+; assembler routine.
+
+MACRO   cprocstartdll16 name
+ifdef  __WINDOWS16__
+cprocstart     _&name&
+else
+cprocstart     name
+endif
+ENDM
+
+; Macros for entering and exiting C callable functions. Note that we must
+; always save and restore the SI and DI registers for C functions, and for
+; 32 bit C functions we also need to save and restore EBX and clear the
+; direction flag.
+
+MACRO  save_c_regs
+ifdef  flatmodel
+               push    ebx
+endif
+               push    _si
+               push    _di
+ENDM
+
+MACRO  enter_c
+               push    _bp
+               mov     _bp,_sp
+       IFDIFI  <LocalSize>,<0>
+               sub             _sp,LocalSize
+       ENDIF
+               save_c_regs
+ENDM
+
+MACRO  restore_c_regs
+               pop             _di
+               pop             _si
+ifdef  flatmodel
+               pop             ebx
+endif
+ENDM
+
+MACRO  leave_c
+               restore_c_regs
+               cld
+       IFDIFI  <LocalSize>,<0>
+               mov     _sp,_bp
+       ENDIF
+               pop     _bp
+ENDM
+
+MACRO   use_ebx
+ifdef flatmodel
+               push    ebx
+endif
+ENDM
+
+MACRO   unuse_ebx
+ifdef flatmodel
+               pop     ebx
+endif
+ENDM
+
+; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
+; be used in assembly routines. This evaluates to nothing in the flat memory
+; model, but is saves and restores DS in the large memory model.
+
+MACRO  use_ds
+ifndef flatmodel
+               push    ds
+endif
+ENDM
+
+MACRO  unuse_ds
+ifndef flatmodel
+               pop             ds
+endif
+ENDM
+
+MACRO  use_es
+ifndef flatmodel
+               push    es
+endif
+ENDM
+
+MACRO  unuse_es
+ifndef flatmodel
+               pop             es
+endif
+ENDM
+
+; Macros for loading the address of a data pointer into a segment and
+; index register pair. The macro explicitly loads DS or ES in the 16 bit
+; memory model, or it simply loads the offset into the register in the flat
+; memory model since DS and ES always point to all addressable memory. You
+; must use the correct _REG (ie: _BX) macros for documentation purposes.
+
+MACRO  _lds    reg, addr
+ifdef flatmodel
+               mov     reg,addr
+else
+               lds             reg,addr
+endif
+ENDM
+
+MACRO   _les   reg, addr
+ifdef flatmodel
+               mov     reg,addr
+else
+               les             reg,addr
+endif
+ENDM
+
+; Macros for adding and subtracting a value from registers. Two value are
+; provided, one for 16 bit modes and another for 32 bit modes (the extended
+; register is used in 32 bit modes).
+
+MACRO   _add   reg, val16, val32
+ifdef flatmodel
+               add             e&reg&, val32
+else
+               add             reg, val16
+endif
+ENDM
+
+MACRO  _sub    reg, val16, val32
+ifdef flatmodel
+               sub             e&reg&, val32
+else
+               sub             reg, val16
+endif
+ENDM
+
+; Macro to clear the high order word for the 32 bit extended registers.
+; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
+; value, and will evaluate to nothing in 16 bit modes.
+
+MACRO  clrhi   reg
+ifdef  flatmodel
+               movzx   e&reg&,reg
+endif
+ENDM
+
+MACRO  sgnhi   reg
+ifdef  flatmodel
+               movsx   e&reg&,reg
+endif
+ENDM
+
+; Macro to load an extended register with an integer value in either mode
+
+MACRO  loadint reg,val
+ifdef flatmodel
+               mov             e&reg&,val
+else
+               xor             e&reg&,e&reg&
+               mov     reg,val
+endif
+ENDM
+
+; Macros to load and store integer values with string instructions
+
+MACRO  LODSINT
+ifdef flatmodel
+               lodsd
+else
+               lodsw
+endif
+ENDM
+
+MACRO  STOSINT
+ifdef flatmodel
+               stosd
+else
+               stosw
+endif
+ENDM
+
+; Macros to provide resb, resw, resd compatibility with NASM
+
+MACRO  dclb    count
+db     count dup (0)
+ENDM
+
+MACRO  dclw    count
+dw     count dup (0)
+ENDM
+
+MACRO  dcld    count
+dd     count dup (0)
+ENDM
+
+; Macros to provide resb, resw, resd compatibility with NASM
+
+MACRO  resb    count
+db     count dup (?)
+ENDM
+
+MACRO  resw    count
+dw     count dup (?)
+ENDM
+
+MACRO  resd    count
+dd     count dup (?)
+ENDM
+
+; Macros to declare assembler stubs for function structures
+
+MACRO  BEGIN_STUBS_DEF name, firstOffset
+begdataseg  _STUBS
+ifdef  __NOU_VAR__
+               EXTRN   name:DWORD
+STUBS_START    =   name
+else
+               EXTRN   _&name&:DWORD
+name   EQU             _&name&
+STUBS_START    =   _&name
+endif
+enddataseg  _STUBS
+begcodeseg  _STUBS
+off = firstOffset
+ENDM
+
+MACRO   DECLARE_STUB   name
+ifdef  __NOU__
+name:
+               PUBLIC  name
+else
+_&name:
+               PUBLIC  _&name
+endif
+               jmp     [DWORD STUBS_START+off]
+off = off + 4
+ENDM
+
+MACRO   DECLARE_STDCALL        name,num_args
+ifdef  STDCALL_MANGLE
+_&name&@&num_args&:
+               PUBLIC  _&name&@&num_args&
+else
+name:
+               PUBLIC  name
+endif
+               jmp     [DWORD STUBS_START+off]
+off = off + 4
+ENDM
+
+MACRO   END_STUBS_DEF
+endcodeseg  _STUBS
+ENDM
+
+MACRO  BEGIN_IMPORTS_DEF       name
+BEGIN_STUBS_DEF        name,4
+ENDM
+
+MACRO   DECLARE_IMP    name
+DECLARE_STUB   name
+ENDM
+
+MACRO   END_IMPORTS_DEF
+END_STUBS_DEF
+ENDM
+
+endif
diff --git a/nasm.c b/nasm.c
index 1123ee3..cd7f714 100644 (file)
--- a/nasm.c
+++ b/nasm.c
@@ -38,9 +38,8 @@ static void register_output_formats(void);
 static void usage(void);
 
 static int using_debug_info;
-#ifdef TASM_COMPAT
 int       tasm_compatible_mode = FALSE;
-#endif
+int pass0;
 
 static char inname[FILENAME_MAX];
 static char outname[FILENAME_MAX];
@@ -131,7 +130,7 @@ static int want_usage;
 static int terminate_after_phase;
 int user_nolist = 0;             /* fbk 9/2/00 */
 
-static void nasm_fputs(char *line, FILE *ofile) 
+static void nasm_fputs(char *line, FILE *ofile)
 {
     if (ofile) {
        fputs(line, ofile);
@@ -140,7 +139,7 @@ static void nasm_fputs(char *line, FILE *ofile)
        puts(line);
 }
 
-int main(int argc, char **argv) 
+int main(int argc, char **argv)
 {
        pass0 = 1;
     want_usage = terminate_after_phase = FALSE;
@@ -151,7 +150,7 @@ int main(int argc, char **argv)
 
     preproc = &nasmpp;
     operating_mode = op_normal;
-    
+
     error_file = stderr;
 
     seg_init();
@@ -160,7 +159,7 @@ int main(int argc, char **argv)
 
     parse_cmdline(argc, argv);
 
-    if (terminate_after_phase) 
+    if (terminate_after_phase)
     {
        if (want_usage)
            usage();
@@ -201,7 +200,7 @@ int main(int argc, char **argv)
       char *file_name = NULL;
       long  prior_linnum=0;
       int   lineinc=0;
-      
+
       if (*outname) {
        ofile = fopen(outname, "w");
        if (!ofile)
@@ -209,9 +208,9 @@ int main(int argc, char **argv)
                        "unable to open output file `%s'", outname);
       } else
        ofile = NULL;
-      
+
       location.known = FALSE;
-      
+
 /*      pass = 1; */
       preproc->reset (inname, 2, report_error, evaluate, &nasmlist);
       while ( (line = preproc->getline()) ) {
@@ -280,7 +279,7 @@ int main(int argc, char **argv)
           * so we're leaving out the one here.
           *     fclose (ofile);
           */
-         
+       
          remove(outname);
          if (listname[0])
            remove(listname);
@@ -288,10 +287,10 @@ int main(int argc, char **argv)
       }
     break;
     }
-    
+
     if (want_usage)
       usage();
-    
+
     raa_free (offsets);
     saa_free (forwrefs);
     eval_cleanup ();
@@ -354,7 +353,7 @@ static int process_arg (char *p, char *q)
     if (!p || !p[0])
        return 0;
 
-    if (p[0]=='-' && ! stopoptions) 
+    if (p[0]=='-' && ! stopoptions)
     {
        switch (p[1]) {
          case 's':
@@ -364,9 +363,11 @@ static int process_arg (char *p, char *q)
          case 'O':
          case 'f':
          case 'p':
+          case 'P':
          case 'd':
          case 'D':
          case 'i':
+          case 'I':
          case 'l':
          case 'E':
          case 'F':
@@ -425,20 +426,18 @@ static int process_arg (char *p, char *q)
            printf("usage: nasm [-@ response file] [-o outfile] [-f format] "
                   "[-l listfile]\n"
                   "            [options...] [--] filename\n"
-                  "    or nasm -r   for version info\n\n"
-#ifdef TASM_COMPAT
+                  "    or nasm -r   for version info (obsolete)\n"
+                  "    or nasm -v   for version info (preferred)\n\n"
                   "    -t          Assemble in SciTech TASM compatible mode\n"
                   "    -g          Generate debug information in selected format.\n"
-#endif
                   "    -e          preprocess only (writes output to stdout by default)\n"
                   "    -a          don't preprocess (assemble only)\n"
                   "    -M          generate Makefile dependencies on stdout\n\n"
                   "    -E<file>    redirect error messages to file\n"
                   "    -s          redirect error messages to stdout\n\n"
-                  "    -g          enable debug info\n"
                   "    -F format   select a debugging format\n\n"
                   "    -I<path>    adds a pathname to the include file path\n"
-                  "    -O<digit>   optimize branch offsets -O0 disables, -O2 default\n"
+                  "    -O<digit>   optimize branch offsets (-O0 disables, default)\n"
                   "    -P<file>    pre-includes a file\n"
                   "    -D<macro>[=<value>] pre-defines a macro\n"
                   "    -U<macro>   undefines a macro\n"
@@ -468,20 +467,16 @@ static int process_arg (char *p, char *q)
            dfmt_list(ofmt, stdout);
            exit(0);
            break;
-#ifdef TASM_COMPAT
          case 't':
            tasm_compatible_mode = TRUE;
            break;
-#endif
          case 'r':
-#ifdef TASM_COMPAT
-           printf("NASM version %s - SciTech TASM compatible additions\n", NASM_VER);
-#else
-           printf("NASM version %s\n", NASM_VER);
-#endif
+         case 'v':
+           printf("NASM version %s compiled "
 #ifdef DEBUG
-           printf("Compiled with -DDEBUG on " __DATE__ "\n");
+           "with -DDEBUG "
 #endif
+           "on " __DATE__ "\n", NASM_VER);
            exit (0);                  /* never need usage message here */
            break;
          case 'e':                    /* preprocess only */
@@ -507,7 +502,7 @@ static int process_arg (char *p, char *q)
            break;
           case 'M':
            operating_mode = op_depend;
-           break; 
+           break;
 
          case '-':
          {
@@ -575,8 +570,8 @@ static int process_arg (char *p, char *q)
                          p[1]);
            break;
        }
-    } 
-    else 
+    }
+    else
     {
        if (*inname) {
            report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
@@ -655,7 +650,6 @@ static void process_respfile (FILE *rfile)
  * argv array. Used by the environment variable and response file
  * processing.
  */
-#ifdef TASM_COMPAT
 static void process_args (char *args) {
     char *p, *q, *arg, *prevarg;
     char separator = ' ';
@@ -676,16 +670,11 @@ static void process_args (char *args) {
     if (arg)
        process_arg (arg, NULL);
 }
-#endif
 
 static void parse_cmdline(int argc, char **argv)
 {
     FILE *rfile;
     char *envreal, *envcopy=NULL, *p, *arg;
-#ifndef        TASM_COMPAT
-    char *q, *prevarg;
-    char separator = ' ';
-#endif
 
     *inname = *outname = *listname = '\0';
 
@@ -696,24 +685,7 @@ static void parse_cmdline(int argc, char **argv)
     arg = NULL;
     if (envreal) {
        envcopy = nasm_strdup(envreal);
-#ifdef TASM_COMPAT
        process_args(envcopy);
-#else
-       p = envcopy;
-       if (*p && *p != '-')
-           separator = *p++;
-       while (*p) {
-           q = p;
-           while (*p && *p != separator) p++;
-           while (*p == separator) *p++ = '\0';
-           prevarg = arg;
-           arg = q;
-           if (process_arg (prevarg, arg))
-               arg = NULL;
-       }
-       if (arg)
-           process_arg (arg, NULL);
-#endif
        nasm_free (envcopy);
     }
 
@@ -724,7 +696,6 @@ static void parse_cmdline(int argc, char **argv)
     {
        int i;
        argv++;
-#ifdef TASM_COMPAT
        if (argv[0][0] == '@') {
            /* We have a response file, so process this as a set of
             * arguments like the environment variable. This allows us
@@ -748,7 +719,6 @@ static void parse_cmdline(int argc, char **argv)
            argc--;
            argv++;
        }
-#endif
        if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
            if ((p = get_param (argv[0], argc > 1 ? argv[1] : NULL, &i))) {
                if ((rfile = fopen(p, "r"))) {
@@ -793,9 +763,9 @@ static void assemble_file (char *fname)
       pass1 = pass < pass_max ? 1 : 2;  /* seq is 1, 1, 1,..., 1, 2 */
       pass2 = pass > 1 ? 2 : 1;         /* seq is 1, 2, 2,..., 2, 2 */
   /*      pass0                            seq is 0, 0, 0,..., 1, 2 */
-      
+
       def_label = pass > 1 ? redefine_label : define_label;
-      
+
 
       sb = cmd_sb;        /* set 'bits' to command line default */
       cpu = cmd_cpu;
@@ -817,13 +787,13 @@ static void assemble_file (char *fname)
       if (pass == 1) location.known = TRUE;
       location.offset = offs = GET_CURR_OFFS;
 
-      while ( (line = preproc->getline()) ) 
+      while ( (line = preproc->getline()) )
       {
          globallineno++;
 
          /* here we parse our directives; this is not handled by the 'real'
             * parser. */
-         if ( (i = getkw (line, &value)) ) 
+         if ( (i = getkw (line, &value)) )
          {
                switch (i) {
                case 1:               /* [SEGMENT n] */
@@ -1046,7 +1016,7 @@ static void assemble_file (char *fname)
                   break;
                default:
                   if (!ofmt->directive (line+1, value, pass2))
-                     report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC, 
+                     report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC,
                               "unrecognised directive [%s]",
                               line+1);
                }
@@ -1054,7 +1024,7 @@ static void assemble_file (char *fname)
          else         /* it isn't a directive */
          {
                parse_line (pass1, line, &output_ins,
-                           report_error, evaluate, 
+                           report_error, evaluate,
                            def_label);
 
                if (!optimizing && pass == 2) {
@@ -1069,12 +1039,12 @@ static void assemble_file (char *fname)
                }
 
 
-               if (!optimizing && output_ins.forw_ref) 
+               if (!optimizing && output_ins.forw_ref)
                {
                   if (pass == 1) {
-                        for(i = 0; i < output_ins.operands; i++) 
+                        for(i = 0; i < output_ins.operands; i++)
                         {
-                           if (output_ins.oprs[i].opflags & OPFLAG_FORWARD) 
+                           if (output_ins.oprs[i].opflags & OPFLAG_FORWARD)
                            {
                                     struct forwrefinfo *fwinf =
                                        (struct forwrefinfo *)saa_wstruct(forwrefs);
@@ -1103,7 +1073,7 @@ static void assemble_file (char *fname)
                         */
 
                         if (output_ins.operands >= 2 &&
-                        (output_ins.oprs[1].opflags & OPFLAG_FORWARD)) 
+                        (output_ins.oprs[1].opflags & OPFLAG_FORWARD))
                         {
                            output_ins.oprs[1].type &= ~(ONENESS|BYTENESS);
                         }
@@ -1127,18 +1097,18 @@ static void assemble_file (char *fname)
 
                         else if (output_ins.label[0] != '.' ||
                                  output_ins.label[1] != '.' ||
-                                 output_ins.label[2] == '@') 
+                                 output_ins.label[2] == '@')
                         {
                            if (output_ins.operands == 1 &&
                                  (output_ins.oprs[0].type & IMMEDIATE) &&
-                                 output_ins.oprs[0].wrt == NO_SEG) 
+                                 output_ins.oprs[0].wrt == NO_SEG)
                            {
                               int isext = output_ins.oprs[0].opflags & OPFLAG_EXTERN;
                               def_label (output_ins.label,
                                              output_ins.oprs[0].segment,
                                              output_ins.oprs[0].offset,
                                              NULL, FALSE, isext, ofmt, report_error);
-                           } 
+                           }
                            else if (output_ins.operands == 2 &&
                                        (output_ins.oprs[0].type & IMMEDIATE) &&
                                        (output_ins.oprs[0].type & COLON) &&
@@ -1146,13 +1116,13 @@ static void assemble_file (char *fname)
                                        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) 
+                                       output_ins.oprs[1].wrt == NO_SEG)
                            {
                                  def_label (output_ins.label,
                                              output_ins.oprs[0].offset | SEG_ABS,
                                              output_ins.oprs[1].offset,
                                              NULL, FALSE, FALSE, ofmt, report_error);
-                           } 
+                           }
                            else
                                  report_error(ERR_NONFATAL, "bad syntax for EQU");
                         }
@@ -1163,7 +1133,7 @@ static void assemble_file (char *fname)
                         */
                         if (output_ins.label[0] == '.' &&
                            output_ins.label[1] == '.' &&
-                           output_ins.label[2] != '@') 
+                           output_ins.label[2] != '@')
                         {
                            if (output_ins.operands == 1 &&
                                  (output_ins.oprs[0].type & IMMEDIATE)) {
@@ -1171,19 +1141,19 @@ static void assemble_file (char *fname)
                                              output_ins.oprs[0].segment,
                                              output_ins.oprs[0].offset,
                                              NULL, FALSE, FALSE, ofmt, report_error);
-                           } 
+                           }
                            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[1].type & IMMEDIATE) &&
-                                       output_ins.oprs[1].segment == NO_SEG) 
+                                       output_ins.oprs[1].segment == NO_SEG)
                            {
                                  define_label (output_ins.label,
                                              output_ins.oprs[0].offset | SEG_ABS,
                                              output_ins.oprs[1].offset,
                                              NULL, FALSE, FALSE, ofmt, report_error);
-                           } 
+                           }
                            else
                                  report_error(ERR_NONFATAL, "bad syntax for EQU");
                         }
@@ -1196,26 +1166,26 @@ static void assemble_file (char *fname)
                                           &output_ins, report_error);
 
                         /* if (using_debug_info)  && output_ins.opcode != -1)*/
-                        if (using_debug_info);  /* fbk 12/29/00 */
+                        if (using_debug_info)  /* fbk 03/25/01 */
 
                         {
                            /* this is done here so we can do debug type info */
                            long typeinfo = TYS_ELEMENTS(output_ins.operands);
                            switch (output_ins.opcode) {
                                     case I_RESB:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;  
+                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;
                                         break;
                                     case I_RESW:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;  
+                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;
                                         break;
                                     case I_RESD:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;  
+                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;
                                         break;
                                     case I_RESQ:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;  
+                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;
                                         break;
                                     case I_REST:
-                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;  
+                                        typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;
                                         break;
                                     case I_DB:
                                         typeinfo |= TY_BYTE;
@@ -1247,7 +1217,7 @@ static void assemble_file (char *fname)
                            offs += l;
                            SET_CURR_OFFS (offs);
                         }
-                        /* 
+                        /*
                         * else l == -1 => invalid instruction, which will be
                         * flagged as an error on pass 2
                         */
@@ -1282,7 +1252,7 @@ static void assemble_file (char *fname)
         pass0++;
         if (pass0==2) pass = pass_max - 1;
       }        else if (!optimizing) pass0++;
-      
+
    } /* for (pass=1; pass<=2; pass++) */
 
    nasmlist.cleanup();
@@ -1290,11 +1260,11 @@ static void assemble_file (char *fname)
    if (optimizing && using_debug_info) /*  -On and -g switches */
       fprintf(error_file,
                 "info:: assembly required 1+%d+1 passes\n", pass_cnt-2);
-#endif    
+#endif
 } /* exit from assemble_file (...) */
 
 
-static int getkw (char *buf, char **value) 
+static int getkw (char *buf, char **value)
 {
     char *p, *q;
 
@@ -1330,7 +1300,7 @@ static int getkw (char *buf, char **value)
        while (*buf!=']') buf++;
        *buf++ = '\0';
     }
-#if 0    
+#if 0
     for (q=p; *q; q++)
        *q = tolower(*q);
 #endif 
@@ -1357,7 +1327,7 @@ static int getkw (char *buf, char **value)
     return -1;
 }
 
-static void report_error (int severity, char *fmt, ...) 
+static void report_error (int severity, char *fmt, ...)
 {
     va_list ap;
 
@@ -1397,7 +1367,7 @@ static void report_error (int severity, char *fmt, ...)
       case ERR_DEBUG:
         fputs("debug: ", error_file); break;
     }
-    
+
     va_start (ap, fmt);
     vfprintf (error_file, fmt, ap);
     fputc ('\n', error_file);
@@ -1429,12 +1399,12 @@ static void report_error (int severity, char *fmt, ...)
     }
 }
 
-static void usage(void) 
+static void usage(void)
 {
     fputs("type `nasm -h' for help\n", error_file);
 }
 
-static void register_output_formats(void) 
+static void register_output_formats(void)
 {
     ofmt = ofmt_register (report_error);
 }
@@ -1447,7 +1417,7 @@ static ListGen *no_pp_list;
 static long no_pp_lineinc;
 
 static void no_pp_reset (char *file, int pass, efunc error, evalfunc eval,
-                        ListGen *listgen) 
+                        ListGen *listgen)
 {
     src_set_fname(nasm_strdup(file));
     src_set_linnum(0);
@@ -1462,7 +1432,7 @@ static void no_pp_reset (char *file, int pass, efunc error, evalfunc eval,
     (void) eval;                      /* placate compilers */
 }
 
-static char *no_pp_getline (void) 
+static char *no_pp_getline (void)
 {
     char *buffer, *p, *q;
     int bufsize;
@@ -1521,20 +1491,20 @@ static char *no_pp_getline (void)
     return buffer;
 }
 
-static void no_pp_cleanup (void) 
+static void no_pp_cleanup (void)
 {
     fclose(no_pp_fp);
 }
 
 static unsigned long get_cpu (char *value)
 {
-    
+
     if (!strcmp(value, "8086")) return IF_8086;
     if (!strcmp(value, "186")) return IF_186;
     if (!strcmp(value, "286")) return IF_286;
     if (!strcmp(value, "386")) return IF_386;
     if (!strcmp(value, "486")) return IF_486;
-    if (!strcmp(value, "586")    || 
+    if (!strcmp(value, "586")    ||
        !nasm_stricmp(value, "pentium") )       return IF_PENT;
     if (!strcmp(value, "686")  ||
        !nasm_stricmp(value, "ppro") ||
@@ -1543,7 +1513,7 @@ static unsigned long get_cpu (char *value)
        !nasm_stricmp(value, "katmai") )        return IF_KATMAI;
 
     report_error (pass0<2 ? ERR_NONFATAL : ERR_FATAL, "unknown 'cpu' type");
-        
+
     return IF_PLEVEL;  /* the maximum level */
 }
 
@@ -1551,7 +1521,7 @@ static unsigned long get_cpu (char *value)
 static int get_bits (char *value)
 {
     int i;
-    
+
     if ((i = atoi(value)) == 16)  return i;   /* set for a 16-bit segment */
     else if (i == 32) {
        if (cpu < IF_386) {
diff --git a/nasm.h b/nasm.h
index 34ebacb..d4079dc 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -13,7 +13,7 @@
 
 #define NASM_MAJOR_VER 0
 #define NASM_MINOR_VER 98
-#define NASM_VER "0.98.08"
+#define NASM_VER "0.98.09"
 
 #ifndef NULL
 #define NULL 0
@@ -856,9 +856,7 @@ struct dfmt {
 
 #define elements(x)     ( sizeof(x) / sizeof(*(x)) )
 
-#ifdef TASM_COMPAT
 extern int tasm_compatible_mode;
-#endif
 
 /*
  * This declaration passes the "pass" number to all other modules
@@ -868,6 +866,6 @@ extern int tasm_compatible_mode;
  *       2 = pass 2
  */
 
-int pass0;     /* this is globally known */
+extern int pass0;      /* this is globally known */
 
 #endif
index 64f2b7f..f556d99 100644 (file)
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -757,9 +757,9 @@ int stdscan (void *private_data, struct tokenval *tv)
        if ((tv->t_integer=bsi(ourcopy, special_names,
                                  elements(special_names)))>=0)
            return tv->t_type = TOKEN_SPECIAL;
-       if (!strcmp(ourcopy, "seg"))
+       if (!nasm_stricmp(ourcopy, "seg"))
            return tv->t_type = TOKEN_SEG;
-       if (!strcmp(ourcopy, "wrt"))
+       if (!nasm_stricmp(ourcopy, "wrt"))
            return tv->t_type = TOKEN_WRT;
        return tv->t_type = TOKEN_ID;
     } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
index 22ac229..b8e74be 100644 (file)
--- a/outaout.c
+++ b/outaout.c
@@ -825,10 +825,10 @@ static void aout_write_relocs (struct Reloc *r)
 
 static void aout_write_syms (void) 
 {
-    int i;
+    unsigned long i;
 
     saa_rewind (syms);
-    for (i=0; i<nsyms; i++) {
+    for (i = 0; i < nsyms; i++) {
        struct Symbol *sym = saa_rstruct(syms);
        fwritelong (sym->strpos, aoutfp);
        fwritelong ((long)sym->type & ~SYM_WITH_SIZE, aoutfp);
index eb02186..8c69567 100644 (file)
--- a/outas86.c
+++ b/outas86.c
@@ -350,7 +350,7 @@ static void as86_out (long segto, void *data, unsigned long type,
 
 static void as86_write(void) 
 {
-    int i;
+    unsigned long i;
     long symlen, seglen, segsize;
 
     /*
index a3289cf..95ac5da 100644 (file)
--- a/outbin.c
+++ b/outbin.c
@@ -1,5 +1,5 @@
-/* outbin.c    output routines for the Netwide Assembler to produce
- *             flat-form binary files
+/* outbin.c output routines for the Netwide Assembler to produce
+ *    flat-form binary files
  *
  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  * Julian Hall. All rights reserved. The software is
@@ -7,6 +7,13 @@
  * distributed in the NASM archive.
  */
 
+/*
+ * version with multiple sections support
+ *
+ * sections go in order defined by their org's if present
+ * if no org present, sections go in sequence they appear.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -22,11 +29,16 @@ static FILE *fp;
 static efunc error;
 
 static struct Section {
+    struct Section *next;
     struct SAA *contents;
     long length;
-    long index;
-} textsect, datasect;
-static long bsslen, bssindex;
+    long org;                  /* assigned org */
+    long pos;                  /* file position of section ?? */
+    long pad;                  /* padding bytes to next section in file */
+    long index;                /* the NASM section id */
+    long align;                /* section alignment, cannot be absolute addr */
+    char *name;
+} *sections, **sectail;
 
 static struct Reloc {
     struct Reloc *next;
@@ -37,12 +49,10 @@ static struct Reloc {
     struct Section *target;
 } *relocs, **reloctail;
 
-static long data_align, bss_align;
-
-static long start_point;
+static long current_section;
 
 static void add_reloc (struct Section *s, long bytes, long secref,
-                      long secrel) 
+             long secrel)
 {
     struct Reloc *r;
 
@@ -56,307 +66,491 @@ static void add_reloc (struct Section *s, long bytes, long secref,
     r->target = s;
 }
 
-static void bin_init (FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval) 
+static struct Section *find_section_by_name(char *name)
+{
+   struct Section *s;
+
+   for (s = sections; s; s = s->next)
+      if (!strcmp(s->name,name))
+         break;
+
+   return s;
+}
+
+static struct Section *find_section_by_index(long index)
+{
+   struct Section *s;
+
+   for (s = sections; s; s = s->next)
+      if ( s->index == index )
+         break;
+
+   return s;
+}
+
+static struct Section *alloc_section(char *name)
+{
+   struct Section *s;
+
+   s = find_section_by_name(name);
+   if(s)
+      error(ERR_PANIC, "section %s re-defined", name);
+
+   s = nasm_malloc(sizeof(struct Section));
+   *sectail    = s;
+   sectail     = &s->next;
+   s->next     = NULL;
+
+   s->contents = saa_init(1L);
+   s->length   = 0;
+   s->pos      = 0;
+   s->org      = -1; /* default org is -1 because we want
+                      * to adjust sections one after another
+                      */
+   s->index    = seg_alloc();
+   s->align    = 4;
+   s->pad      = 0;
+   s->name     = nasm_strdup(name);
+
+   return s;
+}
+
+static void bin_init (FILE *afp, efunc errfunc, ldfunc ldef, evalfunc eval)
 {
     fp = afp;
+    error = errfunc;
 
     (void) eval;   /* Don't warn that this parameter is unused */
+    (void) ldef;            /* placate optimisers */
 
-    error = errfunc;
-    (void) ldef;                      /* placate optimisers */
-
-    start_point = 0L;                 /* default */
-    textsect.contents = saa_init(1L);
-    datasect.contents = saa_init(1L);
-    textsect.length = datasect.length = 0;
-    textsect.index = seg_alloc();
-    datasect.index = seg_alloc();
-    bsslen = 0;
-    bssindex = seg_alloc();
-    relocs = NULL;
+    current_section = -1L;
+    relocs    = NULL;
     reloctail = &relocs;
-    data_align = bss_align = 4;
+    sections  = NULL;
+    sectail   = &sections;
 }
 
-static void bin_cleanup (int debuginfo) 
+static void bin_cleanup (int debuginfo)
 {
-    struct Reloc *r;
-    long datapos, datagap, bsspos;
-
-    (void) debuginfo;
-
-    datapos = start_point + textsect.length;
-    datapos = (datapos + data_align-1) & ~(data_align-1);
-    datagap = datapos - (start_point + textsect.length);
-    bsspos = datapos + datasect.length;
-    bsspos = (bsspos + bss_align-1) & ~(bss_align-1);
-
-    saa_rewind (textsect.contents);
-    saa_rewind (datasect.contents);
-
-    for (r = relocs; r; r = r->next) 
-    {
-       unsigned char *p, *q, mydata[4];
-       long l;
-
-       saa_fread (r->target->contents, r->posn, mydata, r->bytes);
-       p = q = mydata;
-       l = *p++;
-       if (r->bytes > 1) {
-           l += ((long)*p++) << 8;
-           if (r->bytes == 4) {
-               l += ((long)*p++) << 16;
-               l += ((long)*p++) << 24;
-           }
-       }
-
-       if (r->secref == textsect.index)
-           l += start_point;
-       else if (r->secref == datasect.index)
-           l += datapos;
-       else if (r->secref == bssindex)
-           l += bsspos;
-
-       if (r->secrel == textsect.index)
-           l -= start_point;
-       else if (r->secrel == datasect.index)
-           l -= datapos;
-       else if (r->secrel == bssindex)
-           l -= bsspos;
-
-       if (r->bytes == 4)
-           WRITELONG(q, l);
-       else if (r->bytes == 2)
-           WRITESHORT(q, l);
-       else
-           *q++ = l & 0xFF;
-       saa_fwrite (r->target->contents, r->posn, mydata, r->bytes);
-    }
-    saa_fpwrite (textsect.contents, fp);
-    if (datasect.length > 0) {
-       while (datagap--)
-           fputc('\0', fp);
-       saa_fpwrite (datasect.contents, fp);
-    }
-    fclose (fp);
-    saa_free (textsect.contents);
-    saa_free (datasect.contents);
-    while (relocs) {
-       r = relocs->next;
-       nasm_free (relocs);
-       relocs = r;
-    }
+   struct Section *outsections, **outstail;
+   struct Section *s, *o, *ls, *lo;
+   struct Reloc *r;
+   long least_org;
+
+   (void) debuginfo;
+
+   /* sort sections by their orgs
+    * sections without org follow their natural order
+    * after the org'd sections
+    */
+   outsections = NULL;
+   outstail = &outsections;
+
+   while( 1 )
+   {
+      least_org = 0x7fffffff;
+
+      ls = lo = NULL;
+      for( s = sections, o = NULL; s; o = s, s = s->next )
+         if( s->org != -1 && s->org < least_org )
+         {
+            least_org = s->org;
+            ls = s;
+            lo = o;
+         }
+
+      if(ls) /* relink to outsections */
+      {
+#ifdef DEBUG
+         fprintf(stdout, "bin_cleanup: relinking section %s org %ld\n", ls->name, ls->org);
+#endif
+         /* unlink from sections */
+         if(lo)
+            lo->next = ls->next;
+         else
+            if(ls == sections)
+               sections = ls->next;
+
+         /* link in to outsections */
+         if( ls->length > 0 )
+         {
+            *outstail   = ls;
+            outstail    = &ls->next;
+            ls->next    = NULL;
+         }
+      }
+      else
+         break;
+   }
+
+   /* link outsections at start of sections */
+   *outstail = sections;
+   sections = outsections;
+
+   /* calculate sections positions */
+   for(s = sections, o = NULL; s; s = s->next)
+   {
+      if(!strcmp(s->name,".bss")) continue; /* don't count .bss yet */
+
+      if(o)
+      {
+         /* if section doesn't have its
+          * own org, align from prev section
+          */
+         if( s->org == -1 )
+            s->org = o->org + o->length;
+
+         /* check orgs */
+         if( s->org - o->org < o->length )
+            error( ERR_PANIC, "sections %s and %s overlap!", o->name, s->name );
+
+         /* align previous section */
+         o->pad = ((o->pos + o->length + o->align-1) & ~(o->align-1)) - (o->pos + o->length);
+
+         if( s->org - o->org > o->length )
+         {
+#ifdef DEBUG
+            fprintf(stdout, "forced padding: %ld\n", s->org - o->org - o->length);
+#endif
+            o->pad = s->org - o->org - o->length;
+         }
+
+         s->pos += o->pos + o->length + o->pad;
+         s->org = s->pos + sections->org;
+      }
+
+#ifdef DEBUG
+      fprintf(stdout, "bin_cleanup: section %s at %ld(%lx) org %ld(%lx) prev <pos %ld(%lx)+size %ld(%lx)+pad %ld(%lx)> size %ld(%lx) align %ld(%lx)\n",
+              s->name, s->pos, s->pos, s->org, s->org, o?o->pos:0, o?o->pos:0,
+              o?o->length:0, o?o->length:0, o?o->pad:0, o?o->pad:0, s->length, s->length,
+              s->align, s->align);
+#endif
+
+      /* prepare for relocating by the way */
+      saa_rewind( s->contents );
+
+      o = s;
+   }
+
+   /* adjust .bss */
+   s = find_section_by_name(".bss");
+   if(s)
+   {
+      s->org = o->org + o->length + o->pad;
+
+#ifdef DEBUG
+      fprintf(stdout, "bin_cleanup: section %s at %ld org %ld prev (pos %ld+size %ld+pad %ld) size %ld align %ld\n",
+              s->name, s->pos, s->org, o?o->pos:0, o?o->length:0, o?o->pad:0, s->length, s->align);
+#endif
+   }
+
+   /* apply relocations */
+   for (r = relocs; r; r = r->next)
+   {
+      unsigned char *p, *q, mydata[4];
+      long l;
+
+      saa_fread (r->target->contents, r->posn, mydata, r->bytes);
+      p = q = mydata;
+      l = *p++;
+
+      if (r->bytes > 1) {
+         l += ((long)*p++) << 8;
+         if (r->bytes == 4) {
+            l += ((long)*p++) << 16;
+            l += ((long)*p++) << 24;
+         }
+      }
+
+      s = find_section_by_index(r->secref);
+      if(s)
+         l += s->org;
+
+      s = find_section_by_index(r->secrel);
+      if(s)
+         l -= s->org;
+
+      if (r->bytes == 4)
+          WRITELONG(q, l);
+      else if (r->bytes == 2)
+          WRITESHORT(q, l);
+      else
+          *q++ = l & 0xFF;
+      saa_fwrite (r->target->contents, r->posn, mydata, r->bytes);
+   }
+
+   /* write sections to file */
+   for(s = outsections; s; s = s->next)
+   {
+      if(s->length > 0 && strcmp(s->name,".bss"))
+      {
+#ifdef DEBUG
+         fprintf(stdout, "bin_cleanup: writing section %s\n", s->name);
+#endif
+         saa_fpwrite (s->contents, fp);
+         if( s->next )
+            while( s->pad-- > 0 )
+               fputc('\0', fp);
+               /* could pad with nops, since we don't
+                * know if this is code section or not
+                */
+      }
+   }
+
+   fclose (fp);
+
+   while (relocs) {
+      r = relocs->next;
+      nasm_free (relocs);
+      relocs = r;
+   }
+
+   while (outsections) {
+      s = outsections->next;
+      saa_free  (outsections->contents);
+      nasm_free (outsections->name);
+      nasm_free (outsections);
+      outsections = s;
+   }
 }
 
 static void bin_out (long segto, void *data, unsigned long type,
-                    long segment, long wrt) 
+           long segment, long wrt)
 {
     unsigned char *p, mydata[4];
-    struct Section *s;
+    struct Section *s, *sec;
     long realbytes;
 
     if (wrt != NO_SEG) {
-       wrt = NO_SEG;                  /* continue to do _something_ */
-       error (ERR_NONFATAL, "WRT not supported by binary output format");
+   wrt = NO_SEG;            /* continue to do _something_ */
+   error (ERR_NONFATAL, "WRT not supported by binary output format");
     }
 
     /*
      * handle absolute-assembly (structure definitions)
      */
     if (segto == NO_SEG) {
-       if ((type & OUT_TYPMASK) != OUT_RESERVE)
-           error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
-                  " space");
-       return;
+   if ((type & OUT_TYPMASK) != OUT_RESERVE)
+       error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
+         " space");
+   return;
     }
 
-    if (segto == bssindex) {          /* BSS */
-       if ((type & OUT_TYPMASK) != OUT_RESERVE)
-           error(ERR_WARNING, "attempt to initialise memory in the"
-                 " BSS section: ignored");
-       s = NULL;
-    } else if (segto == textsect.index) {
-       s = &textsect;
-    } else if (segto == datasect.index) {
-       s = &datasect;
-    } else {
-       error(ERR_WARNING, "attempt to assemble code in"
-             " segment %d: defaulting to `.text'", segto);
-       s = &textsect;
+    /*
+     * Find the segment we are targetting.
+     */
+    s = find_section_by_index(segto);
+    if (!s)
+   error (ERR_PANIC, "code directed to nonexistent segment?");
+
+    if (!strcmp(s->name, ".bss")) {         /* BSS */
+   if ((type & OUT_TYPMASK) != OUT_RESERVE)
+       error(ERR_WARNING, "attempt to initialise memory in the"
+        " BSS section: ignored");
+   s = NULL;
     }
 
-    if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
-       if (segment != NO_SEG &&
-           segment != textsect.index &&
-           segment != datasect.index &&
-           segment != bssindex) {
-           if (segment % 2)
-               error(ERR_NONFATAL, "binary output format does not support"
-                     " segment base references");
-           else
-               error(ERR_NONFATAL, "binary output format does not support"
-                     " external references");
-           segment = NO_SEG;
-       }
-       if (s) {
-           if (segment != NO_SEG)
-               add_reloc (s, type & OUT_SIZMASK, segment, -1L);
-           p = mydata;
-           if ((type & OUT_SIZMASK) == 4)
-               WRITELONG (p, *(long *)data);
-           else
-               WRITESHORT (p, *(long *)data);
-           saa_wbytes (s->contents, mydata, type & OUT_SIZMASK);
-           s->length += type & OUT_SIZMASK;
-       } else
-           bsslen += type & OUT_SIZMASK;
-    } else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
-       type &= OUT_SIZMASK;
-       p = data;
-       if (s) {
-           saa_wbytes (s->contents, data, type);
-           s->length += type;
-       } else
-           bsslen += type;
-    } else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
-       if (s) {
-           error(ERR_WARNING, "uninitialised space declared in"
-                 " %s section: zeroing",
-                 (segto == textsect.index ? "code" : "data"));
-       }
-       type &= OUT_SIZMASK;
-       if (s) {
-           saa_wbytes (s->contents, NULL, type);
-           s->length += type;
-       } else
-           bsslen += type;
-    } 
-    else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
-            (type & OUT_TYPMASK) == OUT_REL4ADR) 
-    {
-       realbytes = ((type & OUT_TYPMASK) == OUT_REL4ADR ? 4 : 2);
-       if (segment != NO_SEG &&
-           segment != textsect.index &&
-           segment != datasect.index &&
-           segment != bssindex) {
-           if (segment % 2)
-               error(ERR_NONFATAL, "binary output format does not support"
-                     " segment base references");
-           else
-               error(ERR_NONFATAL, "binary output format does not support"
-                     " external references");
-           segment = NO_SEG;
-       }
-       if (s) {
-           add_reloc (s, realbytes, segment, segto);
-           p = mydata;
-           if (realbytes == 4)
-               WRITELONG (p, *(long*)data - realbytes - s->length);
-           else
-               WRITESHORT (p, *(long*)data - realbytes - s->length);
-           saa_wbytes (s->contents, mydata, realbytes);
-           s->length += realbytes;
-       } else
-           bsslen += realbytes;
-    }
+   if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
+
+      if (segment != NO_SEG && !find_section_by_index(segment)) {
+          if (segment % 2)
+         error(ERR_NONFATAL, "binary output format does not support"
+               " segment base references");
+          else
+         error(ERR_NONFATAL, "binary output format does not support"
+               " external references");
+          segment = NO_SEG;
+      }
+
+      if (s) {
+         if (segment != NO_SEG)
+            add_reloc (s, type & OUT_SIZMASK, segment, -1L);
+         p = mydata;
+         if ((type & OUT_SIZMASK) == 4)
+            WRITELONG (p, *(long *)data);
+         else
+            WRITESHORT (p, *(long *)data);
+         saa_wbytes (s->contents, mydata, type & OUT_SIZMASK);
+         s->length += type & OUT_SIZMASK;
+      } else {
+         sec = find_section_by_name(".bss");
+         if(!sec)
+            error(ERR_PANIC, ".bss section is not present");
+         sec->length += type & OUT_SIZMASK;
+      }
+
+   } else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
+      type &= OUT_SIZMASK;
+      p = data;
+      if (s) {
+          saa_wbytes (s->contents, data, type);
+          s->length += type;
+      } else {
+         sec = find_section_by_name(".bss");
+         if(!sec)
+            error(ERR_PANIC, ".bss section is not present");
+         sec->length += type;
+      }
+
+   } else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
+      if (s) {
+          error(ERR_WARNING, "uninitialised space declared in"
+           " %s section: zeroing", s->name);
+      }
+      type &= OUT_SIZMASK;
+      if (s) {
+          saa_wbytes (s->contents, NULL, type);
+          s->length += type;
+      } else {
+         sec = find_section_by_name(".bss");
+         if(!sec)
+            error(ERR_PANIC, ".bss section is not present");
+         sec->length += type;
+      }
+   }
+   else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
+        (type & OUT_TYPMASK) == OUT_REL4ADR)
+   {
+      realbytes = ((type & OUT_TYPMASK) == OUT_REL4ADR ? 4 : 2);
+
+      if (segment != NO_SEG && !find_section_by_index(segment)) {
+          if (segment % 2)
+         error(ERR_NONFATAL, "binary output format does not support"
+               " segment base references");
+          else
+         error(ERR_NONFATAL, "binary output format does not support"
+               " external references");
+          segment = NO_SEG;
+      }
+
+      if (s) {
+         add_reloc (s, realbytes, segment, segto);
+         p = mydata;
+         if (realbytes == 4)
+            WRITELONG (p, *(long*)data - realbytes - s->length);
+         else
+            WRITESHORT (p, *(long*)data - realbytes - s->length);
+         saa_wbytes (s->contents, mydata, realbytes);
+         s->length += realbytes;
+      } else {
+         sec = find_section_by_name(".bss");
+         if(!sec)
+            error(ERR_PANIC, ".bss section is not present");
+         sec->length += realbytes;
+      }
+   }
 }
 
 static void bin_deflabel (char *name, long segment, long offset,
-                         int is_global, char *special) 
+           int is_global, char *special)
 {
-
     (void) segment;   /* Don't warn that this parameter is unused */
     (void) offset;    /* Don't warn that this parameter is unused */
 
     if (special)
-       error (ERR_NONFATAL, "binary format does not support any"
-              " special symbol types");
+   error (ERR_NONFATAL, "binary format does not support any"
+          " special symbol types");
 
     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
-       error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
-       return;
+   error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
+   return;
     }
 
     if (is_global == 2) {
-       error (ERR_NONFATAL, "binary output format does not support common"
-              " variables");
+   error (ERR_NONFATAL, "binary output format does not support common"
+          " variables");
     }
 }
 
-static long bin_secname (char *name, int pass, int *bits) 
+static long bin_secname (char *name, int pass, int *bits)
 {
     int sec_index;
     long *sec_align;
     char *p;
+    struct Section *sec;
 
     (void) pass;   /* Don't warn that this parameter is unused */
 
     /*
-     * Default is 16 bits.
+     * Default is 16 bits .text segment
      */
-    if (!name)
-       *bits = 16;
-
-    if (!name)
-       return textsect.index;
-
-    p = name;
-    while (*p && !isspace(*p)) p++;
-    if (*p) *p++ = '\0';
-    if (!strcmp(name, ".text")) {
-       sec_index = textsect.index;
-       sec_align = NULL;
-    } else if (!strcmp(name, ".data")) {
-       sec_index = datasect.index;
-       sec_align = &data_align;
-    } else if (!strcmp(name, ".bss")) {
-       sec_index = bssindex;
-       sec_align = &bss_align;
-    } else
-       return NO_SEG;
+   if (!name)
+   {
+      *bits = 16;
+      sec = find_section_by_name(".text");
+      if(!sec) sec = alloc_section(".text");
+      sec->org = 0; /* default .text org */
+      current_section = sec->index;
+      return sec->index;
+   }
+
+   p = name;
+   while (*p && !isspace(*p)) p++;
+   if (*p) *p++ = '\0';
+   if (!strcmp(name, ".text")) {
+      sec = find_section_by_name(".text");
+      if(!sec) sec = alloc_section(".text");
+      sec_index = sec->index;
+      sec_align = NULL;
+   } else {
+      sec = find_section_by_name(name);
+      if(!sec) sec = alloc_section(name);
+      sec_index = sec->index;
+      sec_align = &sec->align;
+   }
 
     if (*p) {
-       if (!nasm_strnicmp(p,"align=",6)) {
-           if (sec_align == NULL)
-               error(ERR_NONFATAL, "cannot specify an alignment to"
-                     " the `.text' section");
-           else if (p[6+strspn(p+6,"0123456789")])
-               error(ERR_NONFATAL, "argument to `align' is not numeric");
-           else {
-               unsigned int align = atoi(p+6);
-               if (!align || ((align-1) & align))
-                   error(ERR_NONFATAL, "argument to `align' is not a"
-                         " power of two");
-               else
-                   *sec_align = align;
-           }
-       }
+   if (!nasm_strnicmp(p,"align=",6)) {
+       if (sec_align == NULL)
+      error(ERR_NONFATAL, "cannot specify an alignment to"
+            " the .text section");
+       else if (p[6+strspn(p+6,"0123456789")])
+      error(ERR_NONFATAL, "argument to `align' is not numeric");
+       else {
+      unsigned int align = atoi(p+6);
+      if (!align || ((align-1) & align))
+          error(ERR_NONFATAL, "argument to `align' is not a"
+           " power of two");
+      else
+          *sec_align = align;
+       }
     }
+   }
 
-    return sec_index;
+   current_section = sec->index;
+   return sec_index;
 }
 
-static long bin_segbase (long segment) 
+static long bin_segbase (long segment)
 {
     return segment;
 }
 
-static int bin_directive (char *directive, char *value, int pass) 
+static int bin_directive (char *directive, char *value, int pass)
 {
-    int rn_error;
+   struct Section *s;
+   int rn_error;
 
-    (void) pass;   /* Don't warn that this parameter is unused */
+   (void) pass;   /* Don't warn that this parameter is unused */
 
-    if (!strcmp(directive, "org")) {
-       start_point = readnum (value, &rn_error);
-       if (rn_error)
-           error (ERR_NONFATAL, "argument to ORG should be numeric");
-       return 1;
-    } else
-       return 0;
+   if (!nasm_stricmp(directive, "org")) {
+      if(current_section == -1)
+         error(ERR_PANIC, "org of cosmic space specified");
+
+      s = find_section_by_index(current_section);
+      if(!s)
+         error(ERR_PANIC, "current_section points nowhere");
+
+      s->org = readnum (value, &rn_error);
+      if (rn_error)
+          error (ERR_NONFATAL, "argument to ORG should be numeric");
+      return 1;
+   }
+
+   return 0;
 }
 
-static void bin_filename (char *inname, char *outname, efunc error) 
+static void bin_filename (char *inname, char *outname, efunc error)
 {
     standard_extension (inname, outname, "", error);
 }
@@ -375,8 +569,9 @@ static int bin_set_info(enum geninfo type, char **val)
 {
     return 0;
 }
+
 struct ofmt of_bin = {
-    "flat-form binary files (e.g. DOS .COM, .SYS)",
+    "flat-form binary files (e.g. DOS .COM, .SYS) multisection support test",
     "bin",
     NULL,
     null_debug_arr,
index f546a8e..cf2b075 100644 (file)
--- a/outcoff.c
+++ b/outcoff.c
@@ -651,10 +651,10 @@ static void coff_symbol (char *name, long strpos, long value,
     fputc (aux, coffp);
 }
 
-static void coff_write_symbols (void) 
+static void coff_write_symbols (void)
 {
     char filename[18];
-    int i;
+    unsigned long i;
 
     /*
      * The `.file' record, and the file name auxiliary record.
@@ -669,7 +669,7 @@ static void coff_write_symbols (void)
      */
     memset (filename, 0, 18);         /* useful zeroed buffer */
 
-    for (i=0; i<nsects; i++) {
+    for (i = 0; i < nsects; i++) {
        coff_symbol (sects[i]->name, 0L, 0L, i+1, 3, 1);
        fwritelong (sects[i]->len, coffp);
        fwriteshort (sects[i]->nrelocs, coffp);
@@ -685,7 +685,7 @@ static void coff_write_symbols (void)
      * The real symbols.
      */
     saa_rewind (syms);
-    for (i=0; i<nsyms; i++) {
+    for (i = 0; i < nsyms; i++) {
        struct Symbol *sym = saa_rstruct (syms);
        coff_symbol (sym->strpos == -1 ? sym->name : NULL,
                     sym->strpos, sym->value, sym->section,
index 13a93ab..38f4a56 100644 (file)
--- a/outelf.c
+++ b/outelf.c
@@ -105,7 +105,7 @@ extern struct ofmt of_elf;
 #define SYM_DATA 0x01
 #define SYM_FUNCTION 0x02
 
-#define GLOBAL_TEMP_BASE            /* bigger than any constant sym id */
+#define GLOBAL_TEMP_BASE 15           /* bigger than any constant sym id */
 
 #define SEG_ALIGN 16                  /* alignment of sections in file */
 #define SEG_ALIGN_1 (SEG_ALIGN-1)
index 564bbba..18d4768 100644 (file)
--- a/outform.h
+++ b/outform.h
 #endif
 #endif
 
-/* finally... override any format specifically specifed to be off */
+/* finally... override any format specifically specified to be off */
 #ifdef OF_NO_BIN
 #undef OF_BIN
 #endif
index 0490ba1..4d8b6c9 100644 (file)
--- a/outobj.c
+++ b/outobj.c
@@ -977,7 +977,7 @@ static void obj_write_fixup (ObjRecord *orp, int bytes,
 static void obj_out (long segto, void *data, unsigned long type,
                     long segment, long wrt) 
 {
-    long size, realtype;
+    unsigned long size, realtype;
     unsigned char *ucdata;
     long ldata;
     struct Segment *seg;
index 385c218..00dfcad 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -423,7 +423,6 @@ insn *parse_line (int pass, char *buffer, insn *result,
            bracket = (i == '[');
            i = stdscan(NULL, &tokval);
            if (i == TOKEN_SPECIAL) {  /* check for address size override */
-#ifdef TASM_COMPAT
                if (tasm_compatible_mode) {
                  switch ((int)tokval.t_integer) {
                    /* For TASM compatibility a size override inside the
@@ -458,7 +457,6 @@ insn *parse_line (int pass, char *buffer, insn *result,
                      error (ERR_NONFATAL, "invalid operand size specification");
                  }
                } else {
-#endif
                  /* Standard NASM compatible syntax */
                  switch ((int)tokval.t_integer) {
                    case S_NOSPLIT:
@@ -480,9 +478,7 @@ insn *parse_line (int pass, char *buffer, insn *result,
                      error (ERR_NONFATAL, "invalid size specification in"
                             " effective address");
                  }
-#ifdef TASM_COMPAT
                }
-#endif
                i = stdscan(NULL, &tokval);
            }
        } else {                       /* immediate operand, or register */
@@ -589,7 +585,7 @@ insn *parse_line (int pass, char *buffer, insn *result,
 
                else if (e->value != 1)          /* If both want to be index */
                {
-                   error(ERR_NONFATAL, "invalid effective address");
+                   error(ERR_NONFATAL, "beroset-p-592-invalid effective address");
                    result->opcode = -1;
                    return result;
                } 
@@ -600,7 +596,7 @@ insn *parse_line (int pass, char *buffer, insn *result,
            if (e->type != 0) {        /* is there an offset? */
                if (e->type <= EXPR_REG_END)  /* in fact, is there an error? */
                {
-                   error (ERR_NONFATAL, "invalid effective address");
+                   error (ERR_NONFATAL, "beroset-p-603-invalid effective address");
                    result->opcode = -1;
                    return result;
                } 
@@ -627,14 +623,14 @@ insn *parse_line (int pass, char *buffer, insn *result,
                         * Look for a segment base type.
                         */
                        if (e->type && e->type < EXPR_SEGBASE) {
-                           error (ERR_NONFATAL, "invalid effective address");
+                           error (ERR_NONFATAL, "beroset-p-630-invalid effective address");
                            result->opcode = -1;
                            return result;
                        }
                        while (e->type && e->value == 0)
                            e++;
                        if (e->type && e->value != 1) {
-                           error (ERR_NONFATAL, "invalid effective address");
+                           error (ERR_NONFATAL, "beroset-p-637-invalid effective address");
                            result->opcode = -1;
                            return result;
                        }
@@ -647,7 +643,7 @@ insn *parse_line (int pass, char *buffer, insn *result,
                        while (e->type && e->value == 0)
                            e++;
                        if (e->type) {
-                           error (ERR_NONFATAL, "invalid effective address");
+                           error (ERR_NONFATAL, "beroset-p-650-invalid effective address");
                            result->opcode = -1;
                            return result;
                        }
@@ -660,7 +656,7 @@ insn *parse_line (int pass, char *buffer, insn *result,
            }
 
            if (e->type != 0) {    /* there'd better be nothing left! */
-               error (ERR_NONFATAL, "invalid effective address");
+               error (ERR_NONFATAL, "beroset-p-663-invalid effective address");
                result->opcode = -1;
                return result;
            }
index 87c128f..488517b 100644 (file)
--- a/preproc.c
+++ b/preproc.c
@@ -56,7 +56,8 @@ typedef struct IncPath IncPath;
 /*
  * Store the definition of a single-line macro.
  */
-struct SMacro {
+struct SMacro
+{
     SMacro *next;
     char *name;
     int casesense;
@@ -82,32 +83,34 @@ struct SMacro {
  * When a MMacro is being expanded, `params', `iline', `nparam',
  * `paramlen', `rotate' and `unique' are local to the invocation.
  */
-struct MMacro {
+struct MMacro
+{
     MMacro *next;
     char *name;
     int casesense;
     int nparam_min, nparam_max;
-    int plus;                         /* is the last parameter greedy? */
-    int nolist;                               /* is this macro listing-inhibited? */
+    int plus;                  /* is the last parameter greedy? */
+    int nolist;                        /* is this macro listing-inhibited? */
     int in_progress;
-    Token *dlist;                     /* All defaults as one list */
-    Token **defaults;                 /* Parameter default pointers */
-    int ndefs;                        /* number of default parameters */
+    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 */
+    MMacro *rep_nest;          /* used for nesting %rep */
+    Token **params;            /* actual parameters */
+    Token *iline;              /* invocation line */
     int nparam, rotate, *paramlen;
     unsigned long unique;
-    int lineno;                                /* Current line number on expansion */
+    int lineno;                        /* Current line number on expansion */
 };
 
 /*
  * The context stack is composed of a linked list of these.
  */
-struct Context {
+struct Context
+{
     Context *next;
     SMacro *localmac;
     char *name;
@@ -133,13 +136,15 @@ struct Context {
  * mechanism as an alternative to trying to find a sensible type of
  * quote to use on the filename we were passed.
  */
-struct Token {
+struct Token
+{
     Token *next;
     char *text;
-    SMacro *mac;                      /* associated macro for TOK_SMAC_END */
+    SMacro *mac;               /* associated macro for TOK_SMAC_END */
     int type;
 };
-enum {
+enum
+{
     TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
     TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
     TOK_INTERNAL_STRING
@@ -167,7 +172,8 @@ enum {
  * others have `finishes' NULL, but `first' may still be NULL if
  * the line is blank.
  */
-struct Line {
+struct Line
+{
     Line *next;
     MMacro *finishes;
     Token *first;
@@ -177,14 +183,15 @@ struct Line {
  * To handle an arbitrary level of file inclusion, we maintain a
  * stack (ie linked list) of these things.
  */
-struct Include {
+struct Include
+{
     Include *next;
     FILE *fp;
     Cond *conds;
     Line *expansion;
     char *fname;
     int lineno, lineinc;
-    MMacro *mstk;                     /* stack of active macros/reps */
+    MMacro *mstk;              /* stack of active macros/reps */
 };
 
 /*
@@ -192,7 +199,8 @@ struct Include {
  * 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 {
+struct IncPath
+{
     IncPath *next;
     char *path;
 };
@@ -204,11 +212,13 @@ struct IncPath {
  * 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 {
+struct Cond
+{
     Cond *next;
     int state;
 };
-enum {
+enum
+{
     /*
      * These states are for use just after %if or %elif: IF_TRUE
      * means the condition has evaluated to truth so we are
@@ -247,7 +257,8 @@ static char *conditions[] = {
     "na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no",
     "np", "ns", "nz", "o", "p", "pe", "po", "s", "z"
 };
-enum {
+enum
+{
     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_S, c_Z
@@ -262,9 +273,7 @@ static int inverse_ccs[] = {
  * Directive names.
  */
 static char *directives[] = {
-#ifdef TASM_COMPAT
     "%arg",
-#endif
     "%assign", "%clear", "%define", "%elif", "%elifctx", "%elifdef",
     "%elifid", "%elifidn", "%elifidni", "%elifnctx", "%elifndef",
     "%elifnid", "%elifnidn", "%elifnidni", "%elifnnum", "%elifnstr",
@@ -274,19 +283,14 @@ static char *directives[] = {
     "%ifndef", "%ifnid", "%ifnidn", "%ifnidni", "%ifnnum",
     "%ifnstr", "%ifnum", "%ifstr", "%imacro", "%include",
     "%ixdefine", "%line",
-#ifdef TASM_COMPAT
     "%local",
-#endif
     "%macro", "%pop", "%push", "%rep", "%repl", "%rotate",
-#ifdef TASM_COMPAT
     "%stacksize",
-#endif
-       "%strlen", "%substr", "%undef", "%xdefine"
+    "%strlen", "%substr", "%undef", "%xdefine"
 };
-enum {
-#ifdef TASM_COMPAT
+enum
+{
     PP_ARG,
-#endif
     PP_ASSIGN, PP_CLEAR, PP_DEFINE, PP_ELIF, PP_ELIFCTX, PP_ELIFDEF,
     PP_ELIFID, PP_ELIFIDN, PP_ELIFIDNI, PP_ELIFNCTX, PP_ELIFNDEF,
     PP_ELIFNID, PP_ELIFNIDN, PP_ELIFNIDNI, PP_ELIFNNUM, PP_ELIFNSTR,
@@ -296,17 +300,12 @@ enum {
     PP_IFNDEF, PP_IFNID, PP_IFNIDN, PP_IFNIDNI, PP_IFNNUM,
     PP_IFNSTR, PP_IFNUM, PP_IFSTR, PP_IMACRO, PP_INCLUDE,
     PP_IXDEFINE, PP_LINE,
-#ifdef TASM_COMPAT
     PP_LOCAL,
-#endif
     PP_MACRO, PP_POP, PP_PUSH, PP_REP, PP_REPL, PP_ROTATE,
-#ifdef TASM_COMPAT
     PP_STACKSIZE,
-#endif
-       PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
+    PP_STRLEN, PP_SUBSTR, PP_UNDEF, PP_XDEFINE
 };
 
-#ifdef TASM_COMPAT
 
 /* For TASM compatibility we need to be able to recognise TASM compatible
  * conditional compilation directives. Using the NASM pre-processor does
@@ -318,7 +317,8 @@ enum {
 #       define MAX(a,b) ( ((a) > (b)) ? (a) : (b))
 #endif
 
-enum {
+enum
+{
     TM_ARG, TM_ELIF, TM_ELSE, TM_ENDIF, TM_IF, TM_IFDEF, TM_IFDIFI,
     TM_IFNDEF, TM_INCLUDE, TM_LOCAL
 };
@@ -333,18 +333,17 @@ static char *StackPointer = "ebp";
 static int ArgOffset = 8;
 static int LocalOffset = 4;
 
-#endif
 
 static Context *cstk;
 static Include *istk;
 static IncPath *ipath = NULL;
 
-static efunc __error;  /* Pointer to client-provided error reporting function */
+static efunc __error;          /* Pointer to client-provided error reporting function */
 static evalfunc evaluate;
 
 static int pass;               /* HACK: pass 0 = generate dependencies only */
 
-static unsigned long unique;          /* unique identifier numbers */
+static unsigned long unique;   /* unique identifier numbers */
 
 static Line *predef = NULL;
 
@@ -393,14 +392,22 @@ static char **extrastdmac = NULL;
 int any_extrastdmac;
 
 /*
+ * Tokens are allocated in blocks to improve speed
+ */
+#define TOKEN_BLOCKSIZE 4096
+static Token *freeTokens = NULL;
+
+/*
  * Forward declarations.
  */
-static Token *expand_mmac_params (Token *tline);
-static Token *expand_smacro (Token *tline);
-static Token *expand_id (Token *tline);
-static Context *get_ctx (char *name, int all_contexts);
-static void make_tok_num(Token *tok, long val);
-static void error (int severity, char *fmt, ...);
+static Token *expand_mmac_params(Token * tline);
+static Token *expand_smacro(Token * tline);
+static Token *expand_id(Token * tline);
+static Context *get_ctx(char *name, int all_contexts);
+static void make_tok_num(Token * tok, long val);
+static void error(int severity, char *fmt, ...);
+static Token *new_Token(Token * next, int type, char *text, int txtlen);
+static Token *delete_Token(Token * t);
 
 /*
  * Macros for safe checking of token pointers, avoid *(NULL)
@@ -410,13 +417,13 @@ static void error (int severity, char *fmt, ...);
 #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))))
 
-#ifdef TASM_COMPAT
 /* 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)
+static char *
+check_tasm_directive(char *line)
 {
     int i, j, k, m, len;
     char *p = line, *oldline, oldchar;
@@ -429,45 +436,53 @@ static char *check_tasm_directive(char *line)
     i = -1;
     j = sizeof(tasm_directives) / sizeof(*tasm_directives);
     len = 0;
-    while (!isspace(p [len]) && p [len] != 0)
+    while (!isspace(p[len]) && p[len] != 0)
        len++;
-    if (len) {
-       oldchar = p [len];
-       p [len] = 0;
-       while (j - i > 1) {
+    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) {
+           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;
+               p[len] = oldchar;
                len = strlen(p);
                oldline = line;
                line = nasm_malloc(len + 2);
-               line [0] = '%';
-               if (k == TM_IFDIFI) {
+               line[0] = '%';
+               if (k == TM_IFDIFI)
+               {
                    /* NASM does not recognise IFDIFI, so we convert it to
                     * %ifdef BOGUS. This is not used in NASM comaptible
                     * code, but does need to parse for the TASM macro
                     * package.
                     */
-                   strcpy(line + 1,"ifdef BOGUS");
-               } else {
+                   strcpy(line + 1, "ifdef BOGUS");
+               }
+               else
+               {
                    memcpy(line + 1, p, len + 1);
                }
                nasm_free(oldline);
                return line;
-           } else if (m < 0) {
+           }
+           else if (m < 0)
+           {
                j = k;
-           } else
+           }
+           else
                i = k;
        }
-       p [len] = oldchar;
+       p[len] = oldchar;
     }
     return line;
 }
-#endif
 
 /*
  * The pre-preprocessing stage... This function translates line
@@ -475,27 +490,27 @@ static char *check_tasm_directive(char *line)
  * flags') into NASM preprocessor line number indications (`%line
  * lineno file').
  */
-static char *prepreproc(char *line)
+static char *
+prepreproc(char *line)
 {
     int lineno, fnlen;
     char *fname, *oldline;
 
-    if (line[0] == '#' && line[1] == ' ') {
+    if (line[0] == '#' && line[1] == ' ')
+    {
        oldline = line;
-       fname = oldline+2;
+       fname = oldline + 2;
        lineno = atoi(fname);
        fname += strspn(fname, "0123456789 ");
        if (*fname == '"')
            fname++;
        fnlen = strcspn(fname, "\"");
-       line = nasm_malloc(20+fnlen);
+       line = nasm_malloc(20 + fnlen);
        sprintf(line, "%%line %d %.*s", lineno, fnlen, fname);
-       nasm_free (oldline);
+       nasm_free(oldline);
     }
-#ifdef TASM_COMPAT
     if (tasm_compatible_mode)
        return check_tasm_directive(line);
-#endif
     return line;
 }
 
@@ -505,7 +520,8 @@ static char *prepreproc(char *line)
  * invariant under case changes. We implement this by applying a
  * perfectly normal hash function to the uppercase of the string.
  */
-static int hash(char *s) 
+static int
+hash(char *s)
 {
     unsigned int h = 0;
     int i = 0;
@@ -518,10 +534,11 @@ static int hash(char *s)
     };
 
 
-    while (*s) {
+    while (*s)
+    {
        h += multipliers[i] * (unsigned char) (toupper(*s));
        s++;
-       if (++i >= sizeof(multipliers)/sizeof(*multipliers))
+       if (++i >= sizeof(multipliers) / sizeof(*multipliers))
            i = 0;
     }
     h %= NHASH;
@@ -531,62 +548,65 @@ static int hash(char *s)
 /*
  * Free a linked list of tokens.
  */
-static void free_tlist (Token *list) 
+static void
+free_tlist(Token * list)
 {
-    Token *t;
-    while (list) {
-       t = list;
-       list = list->next;
-       nasm_free (t->text);
-       nasm_free (t);
+    while (list)
+    {
+       list = delete_Token(list);
     }
 }
 
 /*
  * Free a linked list of lines.
  */
-static void free_llist (Line *list) 
+static void
+free_llist(Line * list)
 {
     Line *l;
-    while (list) {
+    while (list)
+    {
        l = list;
        list = list->next;
-       free_tlist (l->first);
-       nasm_free (l);
+       free_tlist(l->first);
+       nasm_free(l);
     }
 }
 
 /*
  * Free an MMacro
  */
-static void free_mmacro (MMacro *m) 
+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);
+    nasm_free(m->name);
+    free_tlist(m->dlist);
+    nasm_free(m->defaults);
+    free_llist(m->expansion);
+    nasm_free(m);
 }
 
 /*
  * Pop the context stack.
  */
-static void ctx_pop (void) 
+static void
+ctx_pop(void)
 {
     Context *c = cstk;
     SMacro *smac, *s;
 
     cstk = cstk->next;
     smac = c->localmac;
-    while (smac) {
+    while (smac)
+    {
        s = smac;
        smac = smac->next;
-       nasm_free (s->name);
-       free_tlist (s->expansion);
-       nasm_free (s);
+       nasm_free(s->name);
+       free_tlist(s->expansion);
+       nasm_free(s);
     }
-    nasm_free (c->name);
-    nasm_free (c);
+    nasm_free(c->name);
+    nasm_free(c);
 }
 
 #define BUF_DELTA 512
@@ -596,15 +616,18 @@ static void ctx_pop (void)
  * return lines from the standard macro set if this has not already
  * been done.
  */
-static char *read_line (void) 
+static char *
+read_line(void)
 {
     char *buffer, *p, *q;
     int bufsize;
 
-    if (stdmacpos) {
-       if (*stdmacpos) {
+    if (stdmacpos)
+    {
+       if (*stdmacpos)
+       {
            char *ret = nasm_strdup(*stdmacpos++);
-           if (!*stdmacpos && any_extrastdmac) 
+           if (!*stdmacpos && any_extrastdmac)
            {
                stdmacpos = extrastdmac;
                any_extrastdmac = FALSE;
@@ -616,21 +639,19 @@ static char *read_line (void)
             * most convenient way to implement the pre-include and
             * pre-define features.
             */
-           if (!*stdmacpos) 
+           if (!*stdmacpos)
            {
                Line *pd, *l;
-               Token *head, **tail, *t, *tt;
+               Token *head, **tail, *t;
 
-               for (pd = predef; pd; pd = pd->next) {
+               for (pd = predef; pd; pd = pd->next)
+               {
                    head = NULL;
                    tail = &head;
-                   for (t = pd->first; t; t = t->next) {
-                       tt = *tail = nasm_malloc(sizeof(Token));
-                       tt->next = NULL;
-                       tail = &tt->next;
-                       tt->type = t->type;
-                       tt->text = nasm_strdup(t->text);
-                       tt->mac = t->mac;   /* always NULL here, in fact */
+                   for (t = pd->first; t; t = t->next)
+                   {
+                       *tail = new_Token(NULL, t->type, t->text, 0);
+                       tail = &(*tail)->next;
                    }
                    l = nasm_malloc(sizeof(Line));
                    l->next = istk->expansion;
@@ -640,8 +661,9 @@ static char *read_line (void)
                }
            }
            return ret;
-       } 
-       else {
+       }
+       else
+       {
            stdmacpos = NULL;
        }
     }
@@ -649,24 +671,28 @@ static char *read_line (void)
     bufsize = BUF_DELTA;
     buffer = nasm_malloc(BUF_DELTA);
     p = buffer;
-    while (1) {
-       q = fgets(p, bufsize-(p-buffer), istk->fp);
+    while (1)
+    {
+       q = fgets(p, bufsize - (p - buffer), istk->fp);
        if (!q)
            break;
        p += strlen(p);
-       if (p > buffer && p[-1] == '\n') {
+       if (p > buffer && p[-1] == '\n')
+       {
            break;
        }
-       if (p-buffer > bufsize-10) {
-           long offset = p-buffer;
+       if (p - buffer > bufsize - 10)
+       {
+           long offset = p - buffer;
            bufsize += BUF_DELTA;
            buffer = nasm_realloc(buffer, bufsize);
-           p = buffer+offset;         /* prevent stale-pointer problems */
+           p = buffer + offset;        /* prevent stale-pointer problems */
        }
     }
 
-    if (!q && p == buffer) {
-       nasm_free (buffer);
+    if (!q && p == buffer)
+    {
+       nasm_free(buffer);
        return NULL;
     }
 
@@ -685,7 +711,7 @@ static char *read_line (void)
      */
     buffer[strcspn(buffer, "\032")] = '\0';
 
-    list->line (LIST_READ, buffer);
+    list->line(LIST_READ, buffer);
 
     return buffer;
 }
@@ -695,53 +721,71 @@ static char *read_line (void)
  * don't need to parse the value out of e.g. numeric tokens: we
  * simply split one string into many.
  */
-static Token *tokenise (char *line) 
+static Token *
+tokenise(char *line)
 {
     char *p = line;
     int type;
     Token *list = NULL;
     Token *t, **tail = &list;
 
-    while (*line) {
+    while (*line)
+    {
        p = line;
-       if (*p == '%' &&
-             (isdigit(p[1]) ||
-             ((p[1] == '-' || p[1] == '+') && isdigit(p[2])) ||
-             ((p[1] == '+') && (isspace (p[2]) || !p[2]))))
+       if (*p == '%')
        {
-           p++;
-           do {
-               p++;
-           } while (isdigit(*p));
-           type = TOK_PREPROC_ID;
-       }
-       else if (*p == '%' && p[1] == '{') {
-           p += 2;
-           while (*p && *p != '}') {
-               p[-1] = *p;
                p++;
-           }
-           p[-1] = '\0';
-           if (*p) p++;
-           type = TOK_PREPROC_ID;
+               if ( isdigit(*p) ||
+                       ((*p == '-' || *p == '+') && isdigit(p[1])) ||
+                       ((*p == '+') && (isspace(p[1]) || !p[1])))
+                               {
+                       do
+                       {
+                       p++;
+                       }
+                       while (isdigit(*p));
+                       type = TOK_PREPROC_ID;
+               }
+               else if (*p == '{')
+               {
+                       p++;
+                       while (*p && *p != '}')
+                       {
+                       p[-1] = *p;
+                       p++;
+                       }
+                       p[-1] = '\0';
+                       if (*p)
+                       p++;
+                       type = TOK_PREPROC_ID;
+               }
+               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 (*p == '%' && (isidchar(p[1]) ||
-                 ((p[1] == '!' || p[1] == '%' || p[1] == '$') &&
-                 isidchar(p[2]))))
+       else if (isidstart(*p) || (*p == '$' && isidstart(p[1])))
        {
-           p++;
-           do {
-               p++;
-           } while (isidchar(*p));
-           type = TOK_PREPROC_ID;
-       }
-       else if (isidstart(*p) || (*p == '$' && isidstart(p[1]))) {
            type = TOK_ID;
            p++;
            while (*p && isidchar(*p))
                p++;
        }
-       else if (*p == '\'' || *p == '"') {
+       else if (*p == '\'' || *p == '"')
+       {
            /*
             * A string token.
             */
@@ -750,14 +794,17 @@ static Token *tokenise (char *line)
            type = TOK_STRING;
            while (*p && *p != c)
                p++;
-           if (*p) { 
-                       p++; 
-               } 
-               else { 
-                       error(ERR_WARNING, "unterminated string"); 
-               }
-       } 
-       else if (isnumstart(*p)) {
+           if (*p)
+           {
+               p++;
+           }
+           else
+           {
+               error(ERR_WARNING, "unterminated string");
+           }
+       }
+       else if (isnumstart(*p))
+       {
            /*
             * A number token.
             */
@@ -765,8 +812,9 @@ static Token *tokenise (char *line)
            p++;
            while (*p && isnumchar(*p))
                p++;
-       } 
-       else if (isspace(*p)) {
+       }
+       else if (isspace(*p))
+       {
            type = TOK_WHITESPACE;
            p++;
            while (*p && isspace(*p))
@@ -776,16 +824,21 @@ static Token *tokenise (char *line)
             * pretending it's a comment; whitespace just before a
             * comment gets lumped into the comment.
             */
-           if (!*p || *p == ';') {
+           if (!*p || *p == ';')
+           {
                type = TOK_COMMENT;
-               while (*p) p++;
+               while (*p)
+                   p++;
            }
-       } 
-       else if (*p == ';') {
+       }
+       else if (*p == ';')
+       {
            type = TOK_COMMENT;
-           while (*p) p++;
-       } 
-       else {
+           while (*p)
+               p++;
+       }
+       else
+       {
            /*
             * Anything else is an operator of some kind. We check
             * for all the double-character operators (>>, <<, //,
@@ -794,30 +847,25 @@ static Token *tokenise (char *line)
             */
            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[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++;
        }
-       if (type != TOK_COMMENT) {
-           *tail = t = nasm_malloc (sizeof(Token));
+       if (type != TOK_COMMENT)
+       {
+           *tail = t = new_Token(NULL, type, line, p - line);
            tail = &t->next;
-           t->next = NULL;
-           t->type = type;
-           t->text = nasm_malloc(1+p-line);
-           strncpy(t->text, line, p-line);
-           t->text[p-line] = '\0';
        }
        line = p;
     }
@@ -825,22 +873,74 @@ static Token *tokenise (char *line)
     return list;
 }
 
+
+/*
+ *  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 mac and next elements to NULL.
+ */
+static Token *
+new_Token(Token * next, int type, char *text, int txtlen)
+{
+    Token *t;
+    int i;
+
+    if (freeTokens == NULL)
+    {
+       freeTokens = nasm_malloc(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->mac = NULL;
+    t->type = type;
+    if (type == TOK_WHITESPACE || text == NULL)
+    {
+       t->text = NULL;
+    }
+    else
+    {
+       if (txtlen == 0)
+           txtlen = strlen(text);
+       t->text = nasm_malloc(1 + txtlen);
+       strncpy(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->next : NULL;
+    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, int expand_locals)
+static char *
+detoken(Token * tlist, int expand_locals)
 {
     Token *t;
     int len;
     char *line, *p;
 
     len = 0;
-    for (t = tlist; t; t = t->next) {
-       if (t->type == TOK_PREPROC_ID && t->text[1] == '!') {
-           char *p = getenv(t->text+2);
-           nasm_free (t->text);
+    for (t = tlist; t; t = t->next)
+    {
+       if (t->type == TOK_PREPROC_ID && t->text[1] == '!')
+       {
+           char *p = getenv(t->text + 2);
+           nasm_free(t->text);
            if (p)
                t->text = nasm_strdup(p);
            else
@@ -848,29 +948,43 @@ static char *detoken (Token *tlist, int expand_locals)
        }
        /* Expand local macros here and not during preprocessing */
        if (expand_locals &&
-           t->type == TOK_PREPROC_ID && t->text &&
-           t->text[0] == '%' && t->text [1] == '$') {
-           Context *ctx = get_ctx (t->text, FALSE);
-           if (ctx) {
-               char buffer [40];
+               t->type == TOK_PREPROC_ID && t->text &&
+               t->text[0] == '%' && t->text[1] == '$')
+       {
+           Context *ctx = get_ctx(t->text, FALSE);
+           if (ctx)
+           {
+               char buffer[40];
                char *p, *q = t->text + 2;
 
-               q += strspn (q, "$");
-               sprintf (buffer, "..@%lu.", ctx->number);
-               p = nasm_malloc (strlen(buffer)+strlen(q)+1);
-               strcpy (p, buffer);
-               strcat (p, q);
-               nasm_free (t->text);
+               q += strspn(q, "$");
+               sprintf(buffer, "..@%lu.", ctx->number);
+               p = nasm_strcat(buffer, q);
+               nasm_free(t->text);
                t->text = p;
            }
        }
-       if (t->text)
+       if (t->type == TOK_WHITESPACE)
+       {
+           len++;
+       }
+       else if (t->text)
+       {
            len += strlen(t->text);
+       }
     }
-    p = line = nasm_malloc(len+1);
-    for (t = tlist; t; t = t->next) {
-       if (t->text) {
-           strcpy (p, t->text);
+    p = line = nasm_malloc(len + 1);
+    for (t = tlist; t; t = t->next)
+    {
+       if (t->type == TOK_WHITESPACE)
+       {
+           *p = ' ';
+               p++;
+               *p = '\0';
+       }
+       else if (t->text)
+       {
+           strcpy(p, t->text);
            p += strlen(p);
        }
     }
@@ -884,16 +998,19 @@ static char *detoken (Token *tlist, int expand_locals)
  * the first token in the line to be passed in as its private_data
  * field.
  */
-static int ppscan(void *private_data, struct tokenval *tokval) 
+static int
+ppscan(void *private_data, struct tokenval *tokval)
 {
     Token **tlineptr = private_data;
     Token *tline;
 
-    do {
+    do
+    {
        tline = *tlineptr;
        *tlineptr = tline ? tline->next : NULL;
-    } while (tline && (tline->type == TOK_WHITESPACE ||
-                      tline->type == TOK_COMMENT));
+    }
+    while (tline && (tline->type == TOK_WHITESPACE ||
+                   tline->type == TOK_COMMENT));
 
     if (!tline)
        return tokval->t_type = TOKEN_EOS;
@@ -903,9 +1020,11 @@ static int ppscan(void *private_data, struct tokenval *tokval)
     if (tline->text[0] == '$' && tline->text[1] == '$' && !tline->text[1])
        return tokval->t_type = TOKEN_BASE;
 
-    if (tline->type == TOK_ID) {
+    if (tline->type == TOK_ID)
+    {
        tokval->t_charptr = tline->text;
-       if (tline->text[0] == '$') {
+       if (tline->text[0] == '$')
+       {
            tokval->t_charptr++;
            return tokval->t_type = TOKEN_ID;
        }
@@ -920,7 +1039,8 @@ static int ppscan(void *private_data, struct tokenval *tokval)
        return tokval->t_type = TOKEN_ID;
     }
 
-    if (tline->type == TOK_NUMBER) {
+    if (tline->type == TOK_NUMBER)
+    {
        int rn_error;
 
        tokval->t_integer = readnum(tline->text, &rn_error);
@@ -930,7 +1050,8 @@ static int ppscan(void *private_data, struct tokenval *tokval)
        return tokval->t_type = TOKEN_NUM;
     }
 
-    if (tline->type == TOK_STRING) {
+    if (tline->type == TOK_STRING)
+    {
        int rn_warn;
        char q, *r;
        int l;
@@ -939,29 +1060,41 @@ static int ppscan(void *private_data, struct tokenval *tokval)
        q = *r++;
        l = strlen(r);
 
-       if (l == 0 || r[l-1] != q)
+       if (l == 0 || r[l - 1] != q)
            return tokval->t_type = TOKEN_ERRNUM;
-       tokval->t_integer = readstrnum(r, l-1, &rn_warn);
+       tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
        if (rn_warn)
-           error(ERR_WARNING|ERR_PASS1,
-                 "character constant too long");
+           error(ERR_WARNING | ERR_PASS1, "character constant too long");
        tokval->t_charptr = NULL;
        return tokval->t_type = TOKEN_NUM;
     }
 
-    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;
+    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;
     }
 
     /*
@@ -976,9 +1109,10 @@ static int ppscan(void *private_data, struct tokenval *tokval)
  * simple wrapper which calls either strcmp or nasm_stricmp
  * depending on the value of the `casesense' parameter.
  */
-static int mstrcmp(char *p, char *q, int casesense)
+static int
+mstrcmp(char *p, char *q, int casesense)
 {
-    return casesense ? strcmp(p,q) : nasm_stricmp(p,q);
+    return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
 }
 
 /*
@@ -991,7 +1125,8 @@ static int mstrcmp(char *p, char *q, int casesense)
  * only the context that directly results from the number of $'s
  * in variable's name.
  */
-static Context *get_ctx (char *name, int all_contexts)
+static Context *
+get_ctx(char *name, int all_contexts)
 {
     Context *ctx;
     SMacro *m;
@@ -1000,49 +1135,55 @@ static Context *get_ctx (char *name, int all_contexts)
     if (!name || name[0] != '%' || name[1] != '$')
        return NULL;
 
-    if (!cstk) {
-       error (ERR_NONFATAL, "`%s': context stack is empty", name);
+    if (!cstk)
+    {
+       error(ERR_NONFATAL, "`%s': context stack is empty", name);
        return NULL;
     }
 
-    for (i = strspn (name+2, "$"), ctx = cstk; (i > 0) && ctx; i--) {
+    for (i = strspn(name + 2, "$"), ctx = cstk; (i > 0) && ctx; i--)
+    {
        ctx = ctx->next;
        i--;
     }
-       if (!ctx) {
-           error (ERR_NONFATAL, "`%s': context stack is only"
-                  " %d level%s deep", name, i-1, (i==2 ? "" : "s"));
-           return NULL;
-       }
+    if (!ctx)
+    {
+       error(ERR_NONFATAL, "`%s': context stack is only"
+               " %d level%s deep", name, i - 1, (i == 2 ? "" : "s"));
+       return NULL;
+    }
     if (!all_contexts)
-    return ctx;
+       return ctx;
 
-    do {
+    do
+    {
        /* Search for this smacro in found context */
        m = ctx->localmac;
-       while (m) {
+       while (m)
+       {
            if (!mstrcmp(m->name, name, m->casesense))
                return ctx;
            m = m->next;
        }
        ctx = ctx->next;
-    } while (ctx);
+    }
+    while (ctx);
     return NULL;
 }
 
-#ifdef TASM_COMPAT
 /* Add a slash to the end of a path if it is missing. We use the
  * forward slash to make it compatible with Unix systems.
  */
-static void backslash(char *s)
+static void
+backslash(char *s)
 {
     int pos = strlen(s);
-    if (s[pos-1] != '\\' && s[pos-1] != '/') {
+    if (s[pos - 1] != '\\' && s[pos - 1] != '/')
+    {
        s[pos] = '/';
-       s[pos+1] = '\0';
+       s[pos + 1] = '\0';
     }
 }
-#endif
 
 /*
  * Open an include file. This routine must always return a valid
@@ -1051,38 +1192,34 @@ static void backslash(char *s)
  * the include path one by one until it finds the file or reaches
  * the end of the path.
  */
-static FILE *inc_fopen(char *file) 
+static FILE *
+inc_fopen(char *file)
 {
     FILE *fp;
     char *prefix = "", *combine;
     IncPath *ip = ipath;
     static int namelen = 0;
-#ifdef TASM_COMPAT
     int len = strlen(file);
-#endif
 
-    while (1) {
-#ifdef TASM_COMPAT
-       combine = nasm_malloc(strlen(prefix)+1+len+1);
+    while (1)
+    {
+       combine = nasm_malloc(strlen(prefix) + 1 + len + 1);
        strcpy(combine, prefix);
        if (prefix[0] != 0)
            backslash(combine);
        strcat(combine, file);
-#else
-       combine = nasm_strcat(prefix,file);
-#endif
        fp = fopen(combine, "r");
        if (pass == 0 && fp)
        {
-         namelen += strlen(combine) + 1;
-         if (namelen > 62)
-         {
-           printf(" \\\n  ");
-           namelen = 2;
-         }
-         printf(" %s", combine);
+           namelen += strlen(combine) + 1;
+           if (namelen > 62)
+           {
+               printf(" \\\n  ");
+               namelen = 2;
+           }
+           printf(" %s", combine);
        }
-       nasm_free (combine);
+       nasm_free(combine);
        if (fp)
            return fp;
        if (!ip)
@@ -1091,9 +1228,8 @@ static FILE *inc_fopen(char *file)
        ip = ip->next;
     }
 
-    error (ERR_FATAL,
-          "unable to open include file `%s'", file);
-    return NULL;                      /* never reached - placate compilers */
+    error(ERR_FATAL, "unable to open include file `%s'", file);
+    return NULL;               /* never reached - placate compilers */
 }
 
 /*
@@ -1117,26 +1253,32 @@ static FILE *inc_fopen(char *file)
  * with %$ the context will be automatically computed. If all_contexts
  * is true, macro will be searched in outer contexts as well.
  */
-static int smacro_defined (Context *ctx, char *name, int nparam, SMacro **defn,
-    int nocase)
+static int
+smacro_defined(Context * ctx, char *name, int nparam, SMacro ** defn,
+       int nocase)
 {
     SMacro *m;
 
     if (ctx)
        m = ctx->localmac;
-    else if (name[0] == '%' && name[1] == '$') {
+    else if (name[0] == '%' && name[1] == '$')
+    {
        if (cstk)
-           ctx = get_ctx (name, FALSE);
+           ctx = get_ctx(name, FALSE);
        if (!ctx)
-           return FALSE;              /* got to return _something_ */
+           return FALSE;       /* got to return _something_ */
        m = ctx->localmac;
-    } else
+    }
+    else
        m = smacros[hash(name)];
 
-    while (m) {
+    while (m)
+    {
        if (!mstrcmp(m->name, name, m->casesense && nocase) &&
-           (nparam <= 0 || m->nparam == 0 || nparam == m->nparam)) {
-           if (defn) {
+               (nparam <= 0 || m->nparam == 0 || nparam == m->nparam))
+       {
+           if (defn)
+           {
                if (nparam == m->nparam || nparam == -1)
                    *defn = m;
                else
@@ -1156,14 +1298,17 @@ static int smacro_defined (Context *ctx, char *name, int nparam, SMacro **defn,
  * 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) 
+static void
+count_mmac_params(Token * t, int *nparam, Token *** params)
 {
     int paramsize, brace;
 
     *nparam = paramsize = 0;
     *params = NULL;
-    while (t) {
-       if (*nparam >= paramsize) {
+    while (t)
+    {
+       if (*nparam >= paramsize)
+       {
            paramsize += PARAM_DELTA;
            *params = nasm_realloc(*params, sizeof(**params) * paramsize);
        }
@@ -1174,22 +1319,25 @@ static void count_mmac_params (Token *t, int *nparam, Token ***params)
        (*params)[(*nparam)++] = t;
        while (tok_isnt_(t, brace ? "}" : ","))
            t = t->next;
-       if (t) {                       /* got a comma/brace */
+       if (t)
+       {                       /* got a comma/brace */
            t = t->next;
-           if (brace) {
+           if (brace)
+           {
                /*
                 * Now we've found the closing brace, look further
                 * for the comma.
                 */
                skip_white_(t);
-               if (tok_isnt_(t, ",")) {
-                   error (ERR_NONFATAL,
-                          "braces do not enclose all of macro parameter");
+               if (tok_isnt_(t, ","))
+               {
+                   error(ERR_NONFATAL,
+                           "braces do not enclose all of macro parameter");
                    while (tok_isnt_(t, ","))
                        t = t->next;
                }
                if (t)
-                   t = t->next;               /* eat the comma */
+                   t = t->next;        /* eat the comma */
            }
        }
     }
@@ -1201,158 +1349,207 @@ static void count_mmac_params (Token *t, int *nparam, Token ***params)
  *
  * We must free the tline we get passed.
  */
-static int if_condition (Token *tline, int i) 
+static int
+if_condition(Token * tline, int i)
 {
-    int    j, casesense;
-    Token  * t, * tt, ** tptr, * origline;
+    int j, casesense;
+    Token *t, *tt, **tptr, *origline;
     struct tokenval tokval;
-    expr   * evalresult;
+    expr *evalresult;
 
     origline = tline;
 
-    switch (i) {
-      case PP_IFCTX: case PP_ELIFCTX:
-      case PP_IFNCTX: case PP_ELIFNCTX:
-       j = FALSE;                     /* have we matched yet? */
-       while (cstk && tline) {
-           skip_white_(tline);
-           if (!tline || tline->type != TOK_ID) {
-               error(ERR_NONFATAL,
-                     "`%s' expects context identifiers", directives[i]);
-               free_tlist (origline);
-               return -1;
+    switch (i)
+    {
+       case PP_IFCTX:
+       case PP_ELIFCTX:
+       case PP_IFNCTX:
+       case PP_ELIFNCTX:
+           j = FALSE;          /* have we matched yet? */
+           while (cstk && tline)
+           {
+               skip_white_(tline);
+               if (!tline || tline->type != TOK_ID)
+               {
+                   error(ERR_NONFATAL,
+                           "`%s' expects context identifiers",
+                           directives[i]);
+                   free_tlist(origline);
+                   return -1;
+               }
+               if (!nasm_stricmp(tline->text, cstk->name))
+                   j = TRUE;
+               tline = tline->next;
            }
-           if (!nasm_stricmp(tline->text, cstk->name))
-               j = TRUE;
-           tline = tline->next;
-       }
-       if (i == PP_IFNCTX || i == PP_ELIFNCTX)
-           j = !j;
-       free_tlist (origline);
-       return j;
-
-      case PP_IFDEF: case PP_ELIFDEF:
-      case PP_IFNDEF: case PP_ELIFNDEF:
-       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] != '$'))) {
+           if (i == PP_IFNCTX || i == PP_ELIFNCTX)
+               j = !j;
+           free_tlist(origline);
+           return j;
+
+       case PP_IFDEF:
+       case PP_ELIFDEF:
+       case PP_IFNDEF:
+       case PP_ELIFNDEF:
+           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] != '$')))
+               {
+                   error(ERR_NONFATAL,
+                           "`%%if%sdef' expects macro identifiers",
+                           (i == PP_ELIFNDEF ? "n" : ""));
+                   free_tlist(origline);
+                   return -1;
+               }
+               if (smacro_defined(NULL, tline->text, 0, NULL, 1))
+                   j = TRUE;
+               tline = tline->next;
+           }
+           if (i == PP_IFNDEF || i == PP_ELIFNDEF)
+               j = !j;
+           free_tlist(origline);
+           return j;
+
+       case PP_IFIDN:
+       case PP_ELIFIDN:
+       case PP_IFNIDN:
+       case PP_ELIFNIDN:
+       case PP_IFIDNI:
+       case PP_ELIFIDNI:
+       case PP_IFNIDNI:
+       case PP_ELIFNIDNI:
+           tline = expand_smacro(tline);
+           t = tt = tline;
+           while (tok_isnt_(tt, ","))
+               tt = tt->next;
+           if (!tt)
+           {
                error(ERR_NONFATAL,
-                     "`%%if%sdef' expects macro identifiers",
-                     (i==PP_ELIFNDEF ? "n" : ""));
-               free_tlist (origline);
+                       "`%s' expects two comma-separated arguments",
+                       directives[i]);
+               free_tlist(tline);
                return -1;
            }
-           if (smacro_defined (NULL, tline->text, 0, NULL, 1))
-               j = TRUE;
-               tline = tline->next;
-       }
-       if (i == PP_IFNDEF || i == PP_ELIFNDEF)
-           j = !j;
-       free_tlist (origline);
-       return j;
-
-      case PP_IFIDN: case PP_ELIFIDN: case PP_IFNIDN: case PP_ELIFNIDN:
-      case PP_IFIDNI: case PP_ELIFIDNI: case PP_IFNIDNI: case PP_ELIFNIDNI:
-       tline = expand_smacro(tline);
-       t = tt = tline;
-       while (tok_isnt_(tt, ","))
            tt = tt->next;
-       if (!tt) {
-           error(ERR_NONFATAL, "`%s' expects two comma-separated arguments",
-                 directives[i]);
-           free_tlist (tline);
-           return -1;
-       }
-       tt = tt->next;
-       casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
-                    i == PP_IFNIDN || i == PP_ELIFNIDN);
-       j = TRUE;                      /* assume equality unless proved not */
-       while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt) {
-           if (tt->type == TOK_OTHER && !strcmp(tt->text, ",")) {
-               error(ERR_NONFATAL, "`%s': more than one comma on line",
-                     directives[i]);
-               free_tlist (tline);
-               return -1;
+           casesense = (i == PP_IFIDN || i == PP_ELIFIDN ||
+                   i == PP_IFNIDN || i == PP_ELIFNIDN);
+           j = TRUE;           /* assume equality unless proved not */
+           while ((t->type != TOK_OTHER || strcmp(t->text, ",")) && tt)
+           {
+               if (tt->type == TOK_OTHER && !strcmp(tt->text, ","))
+               {
+                   error(ERR_NONFATAL, "`%s': more than one comma on line",
+                           directives[i]);
+                   free_tlist(tline);
+                   return -1;
+               }
+               if (t->type == TOK_WHITESPACE)
+               {
+                   t = t->next;
+                   continue;
+               }
+               else if (tt->type == TOK_WHITESPACE)
+               {
+                   tt = tt->next;
+                   continue;
+               }
+               else if (tt->type != t->type ||
+                       mstrcmp(tt->text, t->text, casesense))
+               {
+                   j = FALSE;  /* found mismatching tokens */
+                   break;
+               }
+               else
+               {
+                   t = t->next;
+                   tt = tt->next;
+                   continue;
+               }
            }
-           if (t->type == TOK_WHITESPACE) {
-               t = t->next;
-               continue;
-           } else if (tt->type == TOK_WHITESPACE) {
-               tt = tt->next;
-               continue;
-           } else if (tt->type != t->type ||
-                      (casesense ? strcmp(tt->text, t->text) :
-                       nasm_stricmp(tt->text, t->text))) {
-               j = FALSE;             /* found mismatching tokens */
-               break;
-           } else {
+           if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
+               j = FALSE;      /* trailing gunk on one end or other */
+           if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
+                   i == PP_IFNIDNI || i == PP_ELIFNIDNI)
+               j = !j;
+           free_tlist(tline);
+           return j;
+
+       case PP_IFID:
+       case PP_ELIFID:
+       case PP_IFNID:
+       case PP_ELIFNID:
+       case PP_IFNUM:
+       case PP_ELIFNUM:
+       case PP_IFNNUM:
+       case PP_ELIFNNUM:
+       case PP_IFSTR:
+       case PP_ELIFSTR:
+       case PP_IFNSTR:
+       case PP_ELIFNSTR:
+           tline = expand_smacro(tline);
+           t = tline;
+           while (tok_type_(t, TOK_WHITESPACE))
                t = t->next;
-               tt = tt->next;
-               continue;
+           j = FALSE;          /* placate optimiser */
+           if (t)
+               switch (i)
+               {
+                   case PP_IFID:
+                   case PP_ELIFID:
+                   case PP_IFNID:
+                   case PP_ELIFNID:
+                       j = (t->type == TOK_ID);
+                       break;
+                   case PP_IFNUM:
+                   case PP_ELIFNUM:
+                   case PP_IFNNUM:
+                   case PP_ELIFNNUM:
+                       j = (t->type == TOK_NUMBER);
+                       break;
+                   case PP_IFSTR:
+                   case PP_ELIFSTR:
+                   case PP_IFNSTR:
+                   case PP_ELIFNSTR:
+                       j = (t->type == TOK_STRING);
+                       break;
+               }
+           if (i == PP_IFNID || i == PP_ELIFNID ||
+                   i == PP_IFNNUM || i == PP_ELIFNNUM ||
+                   i == PP_IFNSTR || i == PP_ELIFNSTR)
+               j = !j;
+           free_tlist(tline);
+           return j;
+
+       case PP_IF:
+       case PP_ELIF:
+           t = tline = expand_smacro(tline);
+           tptr = &t;
+           tokval.t_type = TOKEN_INVALID;
+           evalresult = evaluate(ppscan, tptr, &tokval,
+                   NULL, pass | CRITICAL, error, NULL);
+           free_tlist(tline);
+           if (!evalresult)
+               return -1;
+           if (tokval.t_type)
+               error(ERR_WARNING,
+                       "trailing garbage after expression ignored");
+           if (!is_simple(evalresult))
+           {
+               error(ERR_NONFATAL,
+                       "non-constant value given to `%s'", directives[i]);
+               return -1;
            }
-       }
-       if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt)
-           j = FALSE;                 /* trailing gunk on one end or other */
-       if (i == PP_IFNIDN || i == PP_ELIFNIDN ||
-           i == PP_IFNIDNI || i == PP_ELIFNIDNI)
-           j = !j;
-       free_tlist (tline);
-       return j;
-
-      case PP_IFID: case PP_ELIFID: case PP_IFNID: case PP_ELIFNID:
-      case PP_IFNUM: case PP_ELIFNUM: case PP_IFNNUM: case PP_ELIFNNUM:
-      case PP_IFSTR: case PP_ELIFSTR: case PP_IFNSTR: case PP_ELIFNSTR:
-       tline = expand_smacro(tline);
-       t = tline;
-       while (tok_type_(t, TOK_WHITESPACE))
-           t = t->next;
-       j = FALSE;                     /* placate optimiser */
-       if (t) switch (i) {
-         case PP_IFID: case PP_ELIFID: case PP_IFNID: case PP_ELIFNID:
-           j = (t->type == TOK_ID);
-           break;
-         case PP_IFNUM: case PP_ELIFNUM: case PP_IFNNUM: case PP_ELIFNNUM:
-           j = (t->type == TOK_NUMBER);
-           break;
-         case PP_IFSTR: case PP_ELIFSTR: case PP_IFNSTR: case PP_ELIFNSTR:
-           j = (t->type == TOK_STRING);
-           break;
-       }
-       if (i == PP_IFNID || i == PP_ELIFNID ||
-           i == PP_IFNNUM || i == PP_ELIFNNUM ||
-           i == PP_IFNSTR || i == PP_ELIFNSTR)
-           j = !j;
-       free_tlist (tline);
-       return j;
-
-      case PP_IF: case PP_ELIF:
-       t = tline = expand_smacro(tline);
-       tptr = &t;
-       tokval.t_type = TOKEN_INVALID;
-       evalresult = evaluate (ppscan, tptr, &tokval,
-                              NULL, pass | CRITICAL, error, NULL);
-       free_tlist (tline);
-       if (!evalresult)
-           return -1;
-       if (tokval.t_type)
-           error(ERR_WARNING,
-                 "trailing garbage after expression ignored");
-       if (!is_simple(evalresult)) {
-           error(ERR_NONFATAL,
-                 "non-constant value given to `%s'", directives[i]);
-           return -1;
-       }
-       return reloc_value(evalresult) != 0;
-
-      default:
-       error(ERR_FATAL,
-             "preprocessor directive `%s' not yet implemented",
-             directives[i]);
-       free_tlist (origline);
-       return -1;                     /* yeah, right */
+           return reloc_value(evalresult) != 0;
+
+       default:
+           error(ERR_FATAL,
+                   "preprocessor directive `%s' not yet implemented",
+                   directives[i]);
+           free_tlist(origline);
+           return -1;          /* yeah, right */
     }
 }
 
@@ -1361,11 +1558,12 @@ static int if_condition (Token *tline, int i)
  * First tokenise the string, apply "expand_smacro" and then de-tokenise back.
  * The returned variable should ALWAYS be freed after usage.
  */
-void expand_macros_in_string (char **p)
+void
+expand_macros_in_string(char **p)
 {
-    Token *line = tokenise (*p);
-    line = expand_smacro (line);
-    *p = detoken (line, FALSE);
+    Token *line = tokenise(*p);
+    line = expand_smacro(line);
+    *p = detoken(line, FALSE);
 }
 
 /*
@@ -1379,12 +1577,11 @@ void expand_macros_in_string (char **p)
  * 
  * bit 0 is set if a directive was found (so the line gets freed)
  */
-static int do_directive (Token *tline) 
+static int
+do_directive(Token * tline)
 {
     int i, j, k, m, nparam, nolist;
-#ifdef TASM_COMPAT
     int offset;
-#endif
     char *p, *mname;
     Include *inc;
     Context *ctx;
@@ -1401,21 +1598,30 @@ static int do_directive (Token *tline)
 
     skip_white_(tline);
     if (!tok_type_(tline, TOK_PREPROC_ID) ||
-       (tline->text[1]=='%' || tline->text[1]=='$' || tline->text[1]=='!'))
+           (tline->text[1] == '%' || tline->text[1] == '$'
+                   || tline->text[1] == '!'))
        return 0;
 
     i = -1;
-    j = sizeof(directives)/sizeof(*directives);
-    while (j-i > 1) {
-       k = (j+i) / 2;
+    j = sizeof(directives) / sizeof(*directives);
+    while (j - i > 1)
+    {
+       k = (j + i) / 2;
        m = nasm_stricmp(tline->text, directives[k]);
        if (m == 0) {
-           i = k;
-           j = -2;
+               if (tasm_compatible_mode) {
+               i = k;
+               j = -2;
+               } else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {
+                   i = k;
+               j = -2;
+               }
            break;
-       } else if (m < 0) {
+       }
+       else if (m < 0) {
            j = k;
-       } else
+       }
+       else
            i = k;
     }
 
@@ -1426,23 +1632,22 @@ static int do_directive (Token *tline)
      * directives.
      */
     if (((istk->conds && !emitting(istk->conds->state)) ||
-        (istk->mstk && !istk->mstk->in_progress)) &&
-       i != PP_IF && i != PP_ELIF &&
-       i != PP_IFCTX && i != PP_ELIFCTX &&
-       i != PP_IFDEF && i != PP_ELIFDEF &&
-       i != PP_IFID && i != PP_ELIFID &&
-       i != PP_IFIDN && i != PP_ELIFIDN &&
-       i != PP_IFIDNI && i != PP_ELIFIDNI &&
-       i != PP_IFNCTX && i != PP_ELIFNCTX &&
-       i != PP_IFNDEF && i != PP_ELIFNDEF &&
-       i != PP_IFNID && i != PP_ELIFNID &&
-       i != PP_IFNIDN && i != PP_ELIFNIDN &&
-       i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
-       i != PP_IFNNUM && i != PP_ELIFNNUM &&
-       i != PP_IFNSTR && i != PP_ELIFNSTR &&
-       i != PP_IFNUM && i != PP_ELIFNUM &&
-       i != PP_IFSTR && i != PP_ELIFSTR &&
-       i != PP_ELSE && i != PP_ENDIF)
+                   (istk->mstk && !istk->mstk->in_progress)) &&
+           i != PP_IF && i != PP_ELIF &&
+           i != PP_IFCTX && i != PP_ELIFCTX &&
+           i != PP_IFDEF && i != PP_ELIFDEF &&
+           i != PP_IFID && i != PP_ELIFID &&
+           i != PP_IFIDN && i != PP_ELIFIDN &&
+           i != PP_IFIDNI && i != PP_ELIFIDNI &&
+           i != PP_IFNCTX && i != PP_ELIFNCTX &&
+           i != PP_IFNDEF && i != PP_ELIFNDEF &&
+           i != PP_IFNID && i != PP_ELIFNID &&
+           i != PP_IFNIDN && i != PP_ELIFNIDN &&
+           i != PP_IFNIDNI && i != PP_ELIFNIDNI &&
+           i != PP_IFNNUM && i != PP_ELIFNNUM &&
+           i != PP_IFNSTR && i != PP_ELIFNSTR &&
+           i != PP_IFNUM && i != PP_ELIFNUM &&
+           i != PP_IFSTR && i != PP_ELIFSTR && i != PP_ELSE && i != PP_ENDIF)
     {
        return 0;
     }
@@ -1455,1125 +1660,1247 @@ static int do_directive (Token *tline)
      * causes an error, so should be let through.
      */
     if (defining && i != PP_MACRO && i != PP_IMACRO &&
-       i != PP_ENDMACRO && i != PP_ENDM &&
-       (defining->name || (i != PP_ENDREP && i != PP_REP)))
+           i != PP_ENDMACRO && i != PP_ENDM &&
+           (defining->name || (i != PP_ENDREP && i != PP_REP)))
     {
        return 0;
     }
 
-    if (j != -2) {
+    if (j != -2)
+    {
        error(ERR_NONFATAL, "unknown preprocessor directive `%s'",
-             tline->text);
-       return 0;                      /* didn't get it */
+               tline->text);
+       return 0;               /* didn't get it */
     }
 
-    switch (i) {
-#ifdef TASM_COMPAT
-      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.
-        * the following form:
-        *
-        *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
-        */
-       tline = tline->next;
-       if (tline && tline->type == TOK_WHITESPACE)
-           tline = tline->next;
-       if (!tline || tline->type != TOK_ID) {
-           error (ERR_NONFATAL,"`%%stacksize' missing size parameter");
-           free_tlist (origline);
-           return 3;
-       }
-       if (nasm_stricmp(tline->text,"flat") == 0) {
-           /* All subsequent ARG directives are for a 32-bit stack */
-           StackSize = 4;
-           StackPointer = "ebp";
-           ArgOffset = 8;
-           LocalOffset = 4;
-       } 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 = 2;
-       } 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.
+    switch (i)
+    {
+       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.
+            * the following form:
+            *
+            *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD
             */
-           StackSize = 2;
-           StackPointer = "bp";
-           ArgOffset = 6;
-           LocalOffset = 2;
-       } else {
-           error (ERR_NONFATAL,"`%%stacksize' invalid size type");
-           free_tlist (origline);
-           return 3;
-       }
-       free_tlist(origline);
-       return 3;
-
-      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) {
-               error (ERR_NONFATAL,"`%%arg' missing argument parameter");
-               free_tlist (origline);
+           if (!tline || tline->type != TOK_ID)
+           {
+               error(ERR_NONFATAL, "`%%stacksize' missing size parameter");
+               free_tlist(origline);
                return 3;
            }
-           arg = tline->text;
-
-           /* Find the argument size type */
-           tline = tline->next;
-           if (!tline || tline->type != TOK_OTHER || tline->text[0] != ':') {
-               error (ERR_NONFATAL,"Syntax error processing `%%arg' directive");
-               free_tlist (origline);
-               return 3;
+           if (nasm_stricmp(tline->text, "flat") == 0)
+           {
+               /* All subsequent ARG directives are for a 32-bit stack */
+               StackSize = 4;
+               StackPointer = "ebp";
+               ArgOffset = 8;
+               LocalOffset = 4;
            }
-           tline = tline->next;
-           if (!tline || tline->type != TOK_ID) {
-               error (ERR_NONFATAL,"`%%arg' missing size type parameter");
-               free_tlist (origline);
-               return 3;
+           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 = 2;
            }
-
-           /* Allow macro expansion of type parameter */
-           tt = tokenise(tline->text);
-           tt = expand_smacro(tt);
-           if (nasm_stricmp(tt->text,"byte") == 0) {
-               size = MAX(StackSize,1);
-           } else if (nasm_stricmp(tt->text,"word") == 0) {
-               size = MAX(StackSize,2);
-           } else if (nasm_stricmp(tt->text,"dword") == 0) {
-               size = MAX(StackSize,4);
-           } else if (nasm_stricmp(tt->text,"qword") == 0) {
-               size = MAX(StackSize,8);
-           } else if (nasm_stricmp(tt->text,"tword") == 0) {
-               size = MAX(StackSize,10);
-           } else {
-               error (ERR_NONFATAL,"Invalid size type for `%%arg' missing directive");
-               free_tlist (tt);
-               free_tlist (origline);
+           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 = 2;
+           }
+           else
+           {
+               error(ERR_NONFATAL, "`%%stacksize' invalid size type");
+               free_tlist(origline);
                return 3;
            }
-           free_tlist (tt);
+           free_tlist(origline);
+           return 3;
 
-           /* Now define the macro for the argument */
-           sprintf(directive,"%%define %s (%s+%d)", arg, StackPointer, offset);
-           do_directive(tokenise(directive));
-           offset += size;
+       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;
 
-           /* Move to the next argument in the list */
-           tline = tline->next;
-           if (tline && tline->type == TOK_WHITESPACE)
+               /* Find the argument name */
                tline = tline->next;
-       } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
-       free_tlist (origline);
-       return 3;
-
-      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;
+               if (tline && tline->type == TOK_WHITESPACE)
+                   tline = tline->next;
+               if (!tline || tline->type != TOK_ID)
+               {
+                   error(ERR_NONFATAL, "`%%arg' missing argument parameter");
+                   free_tlist(origline);
+                   return 3;
+               }
+               arg = tline->text;
 
-           /* Find the argument name */
-           tline = tline->next;
-           if (tline && tline->type == TOK_WHITESPACE)
+               /* Find the argument size type */
                tline = tline->next;
-           if (!tline || tline->type != TOK_ID) {
-               error (ERR_NONFATAL,"`%%local' missing argument parameter");
-               free_tlist (origline);
-               return 3;
-           }
-           local = tline->text;
+               if (!tline || tline->type != TOK_OTHER
+                       || tline->text[0] != ':')
+               {
+                   error(ERR_NONFATAL,
+                           "Syntax error processing `%%arg' directive");
+                   free_tlist(origline);
+                   return 3;
+               }
+               tline = tline->next;
+               if (!tline || tline->type != TOK_ID)
+               {
+                   error(ERR_NONFATAL,
+                           "`%%arg' missing size type parameter");
+                   free_tlist(origline);
+                   return 3;
+               }
 
-           /* Find the argument size type */
-           tline = tline->next;
-           if (!tline || tline->type != TOK_OTHER || tline->text[0] != ':') {
-               error (ERR_NONFATAL,"Syntax error processing `%%local' directive");
-               free_tlist (origline);
-               return 3;
-           }
-           tline = tline->next;
-           if (!tline || tline->type != TOK_ID) {
-               error (ERR_NONFATAL,"`%%local' missing size type parameter");
-               free_tlist (origline);
-               return 3;
-           }
+               /* Allow macro expansion of type parameter */
+               tt = tokenise(tline->text);
+               tt = expand_smacro(tt);
+               if (nasm_stricmp(tt->text, "byte") == 0)
+               {
+                   size = MAX(StackSize, 1);
+               }
+               else if (nasm_stricmp(tt->text, "word") == 0)
+               {
+                   size = MAX(StackSize, 2);
+               }
+               else if (nasm_stricmp(tt->text, "dword") == 0)
+               {
+                   size = MAX(StackSize, 4);
+               }
+               else if (nasm_stricmp(tt->text, "qword") == 0)
+               {
+                   size = MAX(StackSize, 8);
+               }
+               else if (nasm_stricmp(tt->text, "tword") == 0)
+               {
+                   size = MAX(StackSize, 10);
+               }
+               else
+               {
+                   error(ERR_NONFATAL,
+                           "Invalid size type for `%%arg' missing directive");
+                   free_tlist(tt);
+                   free_tlist(origline);
+                   return 3;
+               }
+               free_tlist(tt);
 
-           /* Allow macro expansion of type parameter */
-           tt = tokenise(tline->text);
-           tt = expand_smacro(tt);
-           if (nasm_stricmp(tt->text,"byte") == 0) {
-               size = MAX(StackSize,1);
-           } else if (nasm_stricmp(tt->text,"word") == 0) {
-               size = MAX(StackSize,2);
-           } else if (nasm_stricmp(tt->text,"dword") == 0) {
-               size = MAX(StackSize,4);
-           } else if (nasm_stricmp(tt->text,"qword") == 0) {
-               size = MAX(StackSize,8);
-           } else if (nasm_stricmp(tt->text,"tword") == 0) {
-               size = MAX(StackSize,10);
-           } else {
-               error (ERR_NONFATAL,"Invalid size type for `%%local' missing directive");
-               free_tlist (tt);
-               free_tlist (origline);
-               return 3;
+               /* Now define the macro for the argument */
+               sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,
+                       offset);
+               do_directive(tokenise(directive));
+               offset += size;
+
+               /* Move to the next argument in the list */
+               tline = tline->next;
+               if (tline && tline->type == TOK_WHITESPACE)
+                   tline = tline->next;
            }
-           free_tlist (tt);
+           while (tline && tline->type == TOK_OTHER
+                   && tline->text[0] == ',');
+           free_tlist(origline);
+           return 3;
+
+       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)
+               {
+                   error(ERR_NONFATAL,
+                           "`%%local' missing argument parameter");
+                   free_tlist(origline);
+                   return 3;
+               }
+               local = tline->text;
+
+               /* Find the argument size type */
+               tline = tline->next;
+               if (!tline || tline->type != TOK_OTHER
+                       || tline->text[0] != ':')
+               {
+                   error(ERR_NONFATAL,
+                           "Syntax error processing `%%local' directive");
+                   free_tlist(origline);
+                   return 3;
+               }
+               tline = tline->next;
+               if (!tline || tline->type != TOK_ID)
+               {
+                   error(ERR_NONFATAL,
+                           "`%%local' missing size type parameter");
+                   free_tlist(origline);
+                   return 3;
+               }
+
+               /* Allow macro expansion of type parameter */
+               tt = tokenise(tline->text);
+               tt = expand_smacro(tt);
+               if (nasm_stricmp(tt->text, "byte") == 0)
+               {
+                   size = MAX(StackSize, 1);
+               }
+               else if (nasm_stricmp(tt->text, "word") == 0)
+               {
+                   size = MAX(StackSize, 2);
+               }
+               else if (nasm_stricmp(tt->text, "dword") == 0)
+               {
+                   size = MAX(StackSize, 4);
+               }
+               else if (nasm_stricmp(tt->text, "qword") == 0)
+               {
+                   size = MAX(StackSize, 8);
+               }
+               else if (nasm_stricmp(tt->text, "tword") == 0)
+               {
+                   size = MAX(StackSize, 10);
+               }
+               else
+               {
+                   error(ERR_NONFATAL,
+                           "Invalid size type for `%%local' missing directive");
+                   free_tlist(tt);
+                   free_tlist(origline);
+                   return 3;
+               }
+               free_tlist(tt);
 
-           /* Now define the macro for the argument */
-           sprintf(directive,"%%define %s (%s-%d)", local, StackPointer, offset);
+               /* Now define the macro for the argument */
+               sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,
+                       offset);
                do_directive(tokenise(directive));
                offset += size;
 
                /* Now define the assign to setup the enter_c macro correctly */
-               sprintf(directive,"%%assign %%$localsize %%$localsize+%d", size);
+               sprintf(directive, "%%assign %%$localsize %%$localsize+%d",
+                       size);
                do_directive(tokenise(directive));
 
-           /* Move to the next argument in the list */
-           tline = tline->next;
-           if (tline && tline->type == TOK_WHITESPACE)
+               /* Move to the next argument in the list */
                tline = tline->next;
-       } while (tline && tline->type == TOK_OTHER && tline->text[0] == ',');
-       free_tlist (origline);
-       return 3;
-#endif
-
-      case PP_CLEAR:
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%clear' ignored");
-       for (j=0; j<NHASH; j++) {
-           while (mmacros[j]) {
-               MMacro *m = mmacros[j];
-               mmacros[j] = m->next;
-               free_mmacro(m);
-           }
-           while (smacros[j]) {
-               SMacro *s = smacros[j];
-               smacros[j] = smacros[j]->next;
-               nasm_free (s->name);
-               free_tlist (s->expansion);
-               nasm_free (s);
+               if (tline && tline->type == TOK_WHITESPACE)
+                   tline = tline->next;
            }
-       }
-       free_tlist (origline);
-       return 3;
-
-      case PP_INCLUDE:
-       tline = tline->next;
-       skip_white_(tline);
-       if (!tline || (tline->type != TOK_STRING &&
-                      tline->type != TOK_INTERNAL_STRING)) 
-       {
-           error(ERR_NONFATAL, "`%%include' expects a file name");
-           free_tlist (origline);
-           return 3;                  /* but we did _something_ */
-       }
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%include' ignored");
-       if (tline->type != TOK_INTERNAL_STRING) {
-           p = tline->text+1;         /* point past the quote to the name */
-           p[strlen(p)-1] = '\0';     /* remove the trailing quote */
-       } else
-           p = tline->text;           /* internal_string is easier */
-       expand_macros_in_string (&p);
-       inc = nasm_malloc(sizeof(Include));
-       inc->next = istk;
-       inc->conds = NULL;
-       inc->fp = inc_fopen(p);
-       inc->fname = src_set_fname (p);
-       inc->lineno = src_set_linnum(0);
-       inc->lineinc = 1;
-       inc->expansion = NULL;
-       inc->mstk = NULL;
-       istk = inc;
-       list->uplevel (LIST_INCLUDE);
-       free_tlist (origline);
-       return 5;
-
-      case PP_PUSH:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tok_type_(tline, TOK_ID)) {
-           error(ERR_NONFATAL,
-                 "`%%push' expects a context identifier");
-           free_tlist (origline);
-           return 3;                  /* but we did _something_ */
-       }
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%push' ignored");
-       ctx = nasm_malloc(sizeof(Context));
-       ctx->next = cstk;
-       ctx->localmac = NULL;
-       ctx->name = nasm_strdup(tline->text);
-       ctx->number = unique++;
-       cstk = ctx;
-       free_tlist (origline);
-       break;
-
-      case PP_REPL:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tok_type_(tline, TOK_ID)) {
-           error(ERR_NONFATAL,
-                 "`%%repl' expects a context identifier");
-           free_tlist (origline);
-           return 3;                  /* but we did _something_ */
-       }
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%repl' ignored");
-       if (!cstk)
-           error(ERR_NONFATAL,
-                 "`%%repl': context stack is empty");
-       else {
-           nasm_free (cstk->name);
-           cstk->name = nasm_strdup(tline->text);
-       }
-       free_tlist (origline);
-       break;
-
-      case PP_POP:
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%pop' ignored");
-       if (!cstk)
-           error(ERR_NONFATAL,
-                 "`%%pop': context stack is already empty");
-       else
-           ctx_pop();
-       free_tlist (origline);
-       break;
-
-      case PP_ERROR:
-       tline->next = expand_smacro (tline->next);
-       tline = tline->next;
-       skip_white_(tline);
-       if (tok_type_(tline, TOK_STRING)) {
-           p = tline->text+1;         /* point past the quote to the name */
-           p[strlen(p)-1] = '\0';     /* remove the trailing quote */
-           expand_macros_in_string (&p);
-           error (ERR_NONFATAL, "%s", p);
-           nasm_free (p);
-       } else {
-           p = detoken(tline, FALSE);
-           error (ERR_WARNING, "%s", p);
-           nasm_free(p);
-       }
-       free_tlist (origline);
-       break;
-
-      case PP_IF:
-      case PP_IFCTX:
-      case PP_IFDEF:
-      case PP_IFID:
-      case PP_IFIDN:
-      case PP_IFIDNI:
-      case PP_IFNCTX:
-      case PP_IFNDEF:
-      case PP_IFNID:
-      case PP_IFNIDN:
-      case PP_IFNIDNI:
-      case PP_IFNNUM:
-      case PP_IFNSTR:
-      case PP_IFNUM:
-      case PP_IFSTR:
-       if (istk->conds && !emitting(istk->conds->state))
-           j = COND_NEVER;
-       else {
-           j = if_condition(tline->next, i);
-           tline->next = NULL;        /* it got freed */
-           free_tlist (origline);
-           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;
-       return (j == COND_IF_TRUE ? 3 : 1);
-
-      case PP_ELIF:
-      case PP_ELIFCTX:
-      case PP_ELIFDEF:
-      case PP_ELIFID:
-      case PP_ELIFIDN:
-      case PP_ELIFIDNI:
-      case PP_ELIFNCTX:
-      case PP_ELIFNDEF:
-      case PP_ELIFNID:
-      case PP_ELIFNIDN:
-      case PP_ELIFNIDNI:
-      case PP_ELIFNNUM:
-      case PP_ELIFNSTR:
-      case PP_ELIFNUM:
-      case PP_ELIFSTR:
-       if (!istk->conds)
-           error(ERR_FATAL, "`%s': no matching `%%if'",
-                 directives[i]);
-       if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
-           istk->conds->state = COND_NEVER;
-       else {
-           j = if_condition(expand_mmac_params(tline->next), i);
-           tline->next = NULL;        /* it got freed */
-           free_tlist (origline);
-           istk->conds->state = j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
-       }
-       return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
+           while (tline && tline->type == TOK_OTHER
+                   && tline->text[0] == ',');
+           free_tlist(origline);
+           return 3;
 
-      case PP_ELSE:
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%else' ignored");
-       if (!istk->conds)
-           error(ERR_FATAL,
-                 "`%%else': no matching `%%if'");
-       if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
-           istk->conds->state = COND_ELSE_FALSE;
-       else
-           istk->conds->state = COND_ELSE_TRUE;
-       free_tlist (origline);
-       return 5;
-
-      case PP_ENDIF:
-       if (tline->next)
-           error(ERR_WARNING,
-                 "trailing garbage after `%%endif' ignored");
-       if (!istk->conds)
-           error(ERR_FATAL,
-                 "`%%endif': no matching `%%if'");
-       cond = istk->conds;
-       istk->conds = cond->next;
-       nasm_free (cond);
-       free_tlist (origline);
-       return 5;
-
-      case PP_MACRO:
-      case PP_IMACRO:
-       if (defining)
-           error (ERR_FATAL,
-                  "`%%%smacro': already defining a macro",
-                  (i == PP_IMACRO ? "i" : ""));
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tok_type_(tline, TOK_ID)) {
-           error (ERR_NONFATAL,
-                  "`%%%smacro' expects a macro name",
-                  (i == PP_IMACRO ? "i" : ""));
+       case PP_CLEAR:
+           if (tline->next)
+               error(ERR_WARNING,
+                       "trailing garbage after `%%clear' ignored");
+           for (j = 0; j < NHASH; j++)
+           {
+               while (mmacros[j])
+               {
+                   MMacro *m = mmacros[j];
+                   mmacros[j] = m->next;
+                   free_mmacro(m);
+               }
+               while (smacros[j])
+               {
+                   SMacro *s = smacros[j];
+                   smacros[j] = smacros[j]->next;
+                   nasm_free(s->name);
+                   free_tlist(s->expansion);
+                   nasm_free(s);
+               }
+           }
+           free_tlist(origline);
            return 3;
-       }
-       defining = nasm_malloc(sizeof(MMacro));
-       defining->name = nasm_strdup(tline->text);
-       defining->casesense = (i == PP_MACRO);
-       defining->plus = FALSE;
-       defining->nolist = FALSE;
-       defining->in_progress = FALSE;
-       defining->rep_nest = NULL;
-       tline = expand_smacro (tline->next);
-       skip_white_(tline);
-       if (!tok_type_(tline, TOK_NUMBER)) {
-           error (ERR_NONFATAL,
-                  "`%%%smacro' expects a parameter count",
-                  (i == PP_IMACRO ? "i" : ""));
-           defining->nparam_min = defining->nparam_max = 0;
-       } else {
-           defining->nparam_min = defining->nparam_max =
-               readnum(tline->text, &j);
-           if (j)
-               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, "*"))
-               defining->nparam_max = INT_MAX;
-           else if (!tok_type_(tline, TOK_NUMBER))
-               error (ERR_NONFATAL,
-                      "`%%%smacro' expects a parameter count after `-'",
-                      (i == PP_IMACRO ? "i" : ""));
-           else {
-               defining->nparam_max = readnum(tline->text, &j);
-               if (j)
-                   error (ERR_NONFATAL,
-                          "unable to parse parameter count `%s'",
-                          tline->text);
-               if (defining->nparam_min > defining->nparam_max)
-                   error (ERR_NONFATAL,
-                          "minimum parameter count exceeds maximum");
+
+       case PP_INCLUDE:
+           tline = tline->next;
+           skip_white_(tline);
+           if (!tline || (tline->type != TOK_STRING &&
+                           tline->type != TOK_INTERNAL_STRING))
+           {
+               error(ERR_NONFATAL, "`%%include' expects a file name");
+               free_tlist(origline);
+               return 3;       /* but we did _something_ */
            }
-       }
-       if (tline && tok_is_(tline->next, "+")) {
+           if (tline->next)
+               error(ERR_WARNING,
+                       "trailing garbage after `%%include' ignored");
+           if (tline->type != TOK_INTERNAL_STRING)
+           {
+               p = tline->text + 1;    /* point past the quote to the name */
+               p[strlen(p) - 1] = '\0';        /* remove the trailing quote */
+           }
+           else
+               p = tline->text;        /* internal_string is easier */
+           expand_macros_in_string(&p);
+           inc = nasm_malloc(sizeof(Include));
+           inc->next = istk;
+           inc->conds = NULL;
+           inc->fp = inc_fopen(p);
+           inc->fname = src_set_fname(p);
+           inc->lineno = src_set_linnum(0);
+           inc->lineinc = 1;
+           inc->expansion = NULL;
+           inc->mstk = NULL;
+           istk = inc;
+           list->uplevel(LIST_INCLUDE);
+           free_tlist(origline);
+           return 5;
+
+       case PP_PUSH:
            tline = tline->next;
-           defining->plus = TRUE;
-       }
-       if (tline && tok_type_(tline->next, TOK_ID) &&
-           !nasm_stricmp(tline->next->text, ".nolist")) 
-       {
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tok_type_(tline, TOK_ID))
+           {
+               error(ERR_NONFATAL, "`%%push' expects a context identifier");
+               free_tlist(origline);
+               return 3;       /* but we did _something_ */
+           }
+           if (tline->next)
+               error(ERR_WARNING, "trailing garbage after `%%push' ignored");
+           ctx = nasm_malloc(sizeof(Context));
+           ctx->next = cstk;
+           ctx->localmac = NULL;
+           ctx->name = nasm_strdup(tline->text);
+           ctx->number = unique++;
+           cstk = ctx;
+           free_tlist(origline);
+           break;
+
+       case PP_REPL:
            tline = tline->next;
-           defining->nolist = TRUE;
-       }
-       mmac = mmacros[hash(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)) 
-           {
-               error (ERR_WARNING,
-                      "redefining multi-line macro `%s'", defining->name);
-               break;
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tok_type_(tline, TOK_ID))
+           {
+               error(ERR_NONFATAL, "`%%repl' expects a context identifier");
+               free_tlist(origline);
+               return 3;       /* but we did _something_ */
            }
-           mmac = mmac->next;
-       }
-       /*
-        * Handle default parameters.
-        */
-       if (tline && tline->next) {
-           defining->dlist = tline->next;
-           tline->next = NULL;
-           count_mmac_params (defining->dlist, &defining->ndefs,
-                              &defining->defaults);
-       } else {
-           defining->dlist = NULL;
-           defining->defaults = NULL;
-       }
-       defining->expansion = NULL;
-       free_tlist (origline);
-       return 1;
-
-      case PP_ENDM:
-      case PP_ENDMACRO:
-       if (!defining) {
-           error (ERR_NONFATAL, "`%s': not defining a macro",
-                  tline->text);
-           return 3;
-       }
-       k = hash(defining->name);
-       defining->next = mmacros[k];
-       mmacros[k] = defining;
-       defining = NULL;
-       free_tlist (origline);
-       return 5;
-
-      case PP_ROTATE:
-       if (tline->next && tline->next->type == TOK_WHITESPACE)
+           if (tline->next)
+               error(ERR_WARNING, "trailing garbage after `%%repl' ignored");
+           if (!cstk)
+               error(ERR_NONFATAL, "`%%repl': context stack is empty");
+           else
+           {
+               nasm_free(cstk->name);
+               cstk->name = nasm_strdup(tline->text);
+           }
+           free_tlist(origline);
+           break;
+
+       case PP_POP:
+           if (tline->next)
+               error(ERR_WARNING, "trailing garbage after `%%pop' ignored");
+           if (!cstk)
+               error(ERR_NONFATAL,
+                       "`%%pop': context stack is already empty");
+           else
+               ctx_pop();
+           free_tlist(origline);
+           break;
+
+       case PP_ERROR:
+           tline->next = expand_smacro(tline->next);
            tline = tline->next;
-       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, error, NULL);
-       free_tlist (tline);
-       if (!evalresult)
-           return 3;
-       if (tokval.t_type)
-           error(ERR_WARNING,
-                 "trailing garbage after expression ignored");
-       if (!is_simple(evalresult)) {
-           error(ERR_NONFATAL,
-                 "non-constant value given to `%%rotate'");
-           return 3;
-       }
-       mmac = istk->mstk;
-       while (mmac && !mmac->name)    /* avoid mistaking %reps for macros */
-           mmac = mmac->next_active;
-       if (!mmac)
-           error(ERR_NONFATAL, "`%%rotate' invoked outside a macro call");
-       mmac->rotate = mmac->rotate + reloc_value(evalresult);
-       if (mmac->rotate < 0)
-           mmac->rotate = mmac->nparam - (-mmac->rotate) % mmac->nparam;
-       mmac->rotate %= mmac->nparam;
-       return 1;
-
-      case PP_REP:
-       nolist = FALSE;
-       tline = tline->next;
-       if (tline->next && tline->next->type == TOK_WHITESPACE)
+           skip_white_(tline);
+           if (tok_type_(tline, TOK_STRING))
+           {
+               p = tline->text + 1;    /* point past the quote to the name */
+               p[strlen(p) - 1] = '\0';        /* remove the trailing quote */
+               expand_macros_in_string(&p);
+               error(ERR_NONFATAL, "%s", p);
+               nasm_free(p);
+           }
+           else
+           {
+               p = detoken(tline, FALSE);
+               error(ERR_WARNING, "%s", p);
+               nasm_free(p);
+           }
+           free_tlist(origline);
+           break;
+
+       case PP_IF:
+       case PP_IFCTX:
+       case PP_IFDEF:
+       case PP_IFID:
+       case PP_IFIDN:
+       case PP_IFIDNI:
+       case PP_IFNCTX:
+       case PP_IFNDEF:
+       case PP_IFNID:
+       case PP_IFNIDN:
+       case PP_IFNIDNI:
+       case PP_IFNNUM:
+       case PP_IFNSTR:
+       case PP_IFNUM:
+       case PP_IFSTR:
+           if (istk->conds && !emitting(istk->conds->state))
+               j = COND_NEVER;
+           else
+           {
+               j = if_condition(tline->next, i);
+               tline->next = NULL;     /* it got freed */
+               free_tlist(origline);
+               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;
+           return (j == COND_IF_TRUE ? 3 : 1);
+
+       case PP_ELIF:
+       case PP_ELIFCTX:
+       case PP_ELIFDEF:
+       case PP_ELIFID:
+       case PP_ELIFIDN:
+       case PP_ELIFIDNI:
+       case PP_ELIFNCTX:
+       case PP_ELIFNDEF:
+       case PP_ELIFNID:
+       case PP_ELIFNIDN:
+       case PP_ELIFNIDNI:
+       case PP_ELIFNNUM:
+       case PP_ELIFNSTR:
+       case PP_ELIFNUM:
+       case PP_ELIFSTR:
+           if (!istk->conds)
+               error(ERR_FATAL, "`%s': no matching `%%if'", directives[i]);
+           if (emitting(istk->conds->state)
+                   || istk->conds->state == COND_NEVER)
+               istk->conds->state = COND_NEVER;
+           else
+           {
+               j = if_condition(expand_mmac_params(tline->next), i);
+               tline->next = NULL;     /* it got freed */
+               free_tlist(origline);
+               istk->conds->state =
+                       j < 0 ? COND_NEVER : j ? COND_IF_TRUE : COND_IF_FALSE;
+           }
+           return (istk->conds->state == COND_IF_TRUE ? 5 : 1);
+
+       case PP_ELSE:
+           if (tline->next)
+               error(ERR_WARNING, "trailing garbage after `%%else' ignored");
+           if (!istk->conds)
+               error(ERR_FATAL, "`%%else': no matching `%%if'");
+           if (emitting(istk->conds->state)
+                   || istk->conds->state == COND_NEVER)
+               istk->conds->state = COND_ELSE_FALSE;
+           else
+               istk->conds->state = COND_ELSE_TRUE;
+           free_tlist(origline);
+           return 5;
+
+       case PP_ENDIF:
+           if (tline->next)
+               error(ERR_WARNING,
+                       "trailing garbage after `%%endif' ignored");
+           if (!istk->conds)
+               error(ERR_FATAL, "`%%endif': no matching `%%if'");
+           cond = istk->conds;
+           istk->conds = cond->next;
+           nasm_free(cond);
+           free_tlist(origline);
+           return 5;
+
+       case PP_MACRO:
+       case PP_IMACRO:
+           if (defining)
+               error(ERR_FATAL,
+                       "`%%%smacro': already defining a macro",
+                       (i == PP_IMACRO ? "i" : ""));
            tline = tline->next;
-       if (tline->next && tline->next->type == TOK_ID &&
-           !nasm_stricmp(tline->next->text, ".nolist")) {
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tok_type_(tline, TOK_ID))
+           {
+               error(ERR_NONFATAL,
+                       "`%%%smacro' expects a macro name",
+                       (i == PP_IMACRO ? "i" : ""));
+               return 3;
+           }
+           defining = nasm_malloc(sizeof(MMacro));
+           defining->name = nasm_strdup(tline->text);
+           defining->casesense = (i == PP_MACRO);
+           defining->plus = FALSE;
+           defining->nolist = FALSE;
+           defining->in_progress = FALSE;
+           defining->rep_nest = NULL;
+           tline = expand_smacro(tline->next);
+           skip_white_(tline);
+           if (!tok_type_(tline, TOK_NUMBER))
+           {
+               error(ERR_NONFATAL,
+                       "`%%%smacro' expects a parameter count",
+                       (i == PP_IMACRO ? "i" : ""));
+               defining->nparam_min = defining->nparam_max = 0;
+           }
+           else
+           {
+               defining->nparam_min = defining->nparam_max =
+                       readnum(tline->text, &j);
+               if (j)
+                   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, "*"))
+                   defining->nparam_max = INT_MAX;
+               else if (!tok_type_(tline, TOK_NUMBER))
+                   error(ERR_NONFATAL,
+                           "`%%%smacro' expects a parameter count after `-'",
+                           (i == PP_IMACRO ? "i" : ""));
+               else
+               {
+                   defining->nparam_max = readnum(tline->text, &j);
+                   if (j)
+                       error(ERR_NONFATAL,
+                               "unable to parse parameter count `%s'",
+                               tline->text);
+                   if (defining->nparam_min > defining->nparam_max)
+                       error(ERR_NONFATAL,
+                               "minimum parameter count exceeds maximum");
+               }
+           }
+           if (tline && tok_is_(tline->next, "+"))
+           {
+               tline = tline->next;
+               defining->plus = TRUE;
+           }
+           if (tline && tok_type_(tline->next, TOK_ID) &&
+                   !nasm_stricmp(tline->next->text, ".nolist"))
+           {
+               tline = tline->next;
+               defining->nolist = TRUE;
+           }
+           mmac = mmacros[hash(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))
+               {
+                   error(ERR_WARNING,
+                           "redefining multi-line macro `%s'",
+                           defining->name);
+                   break;
+               }
+               mmac = mmac->next;
+           }
+           /*
+            * Handle default parameters.
+            */
+           if (tline && tline->next)
+           {
+               defining->dlist = tline->next;
+               tline->next = NULL;
+               count_mmac_params(defining->dlist, &defining->ndefs,
+                       &defining->defaults);
+           }
+           else
+           {
+               defining->dlist = NULL;
+               defining->defaults = NULL;
+           }
+           defining->expansion = NULL;
+           free_tlist(origline);
+           return 1;
+
+       case PP_ENDM:
+       case PP_ENDMACRO:
+           if (!defining)
+           {
+               error(ERR_NONFATAL, "`%s': not defining a macro",
+                       tline->text);
+               return 3;
+           }
+           k = hash(defining->name);
+           defining->next = mmacros[k];
+           mmacros[k] = defining;
+           defining = NULL;
+           free_tlist(origline);
+           return 5;
+
+       case PP_ROTATE:
+           if (tline->next && tline->next->type == TOK_WHITESPACE)
+               tline = tline->next;
+           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, error, NULL);
+           free_tlist(tline);
+           if (!evalresult)
+               return 3;
+           if (tokval.t_type)
+               error(ERR_WARNING,
+                       "trailing garbage after expression ignored");
+           if (!is_simple(evalresult))
+           {
+               error(ERR_NONFATAL, "non-constant value given to `%%rotate'");
+               return 3;
+           }
+           mmac = istk->mstk;
+           while (mmac && !mmac->name) /* avoid mistaking %reps for macros */
+               mmac = mmac->next_active;
+           if (!mmac)
+               error(ERR_NONFATAL,
+                       "`%%rotate' invoked outside a macro call");
+           mmac->rotate = mmac->rotate + reloc_value(evalresult);
+           if (mmac->rotate < 0)
+               mmac->rotate = mmac->nparam - (-mmac->rotate) % mmac->nparam;
+           mmac->rotate %= mmac->nparam;
+           return 1;
+
+       case PP_REP:
+           nolist = FALSE;
            tline = tline->next;
-           nolist = TRUE;
-       }
-       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, error, NULL);
-       free_tlist (tline);
-       if (!evalresult)
-           return 3;
-       if (tokval.t_type)
-           error(ERR_WARNING,
-                 "trailing garbage after expression ignored");
-       if (!is_simple(evalresult)) {
-           error(ERR_NONFATAL,
-                 "non-constant value given to `%%rep'");
-           return 3;
-       }
-       tmp_defining = defining;
-       defining = nasm_malloc(sizeof(MMacro));
-       defining->name = NULL;         /* flags this macro as a %rep block */
-       defining->casesense = 0;
-       defining->plus = FALSE;
-       defining->nolist = nolist;
-       defining->in_progress = reloc_value(evalresult) + 1;
-       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 1;
-
-      case PP_ENDREP:
-       if (!defining || defining->name) {
-           error (ERR_NONFATAL,
-                  "`%%endrep': no matching `%%rep'");
-           return 3;
-       }
+           if (tline->next && tline->next->type == TOK_WHITESPACE)
+               tline = tline->next;
+           if (tline->next && tline->next->type == TOK_ID &&
+                   !nasm_stricmp(tline->next->text, ".nolist"))
+           {
+               tline = tline->next;
+               nolist = TRUE;
+           }
+           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, error, NULL);
+           free_tlist(tline);
+           if (!evalresult)
+               return 3;
+           if (tokval.t_type)
+               error(ERR_WARNING,
+                       "trailing garbage after expression ignored");
+           if (!is_simple(evalresult))
+           {
+               error(ERR_NONFATAL, "non-constant value given to `%%rep'");
+               return 3;
+           }
+           tmp_defining = defining;
+           defining = nasm_malloc(sizeof(MMacro));
+           defining->name = NULL;      /* flags this macro as a %rep block */
+           defining->casesense = 0;
+           defining->plus = FALSE;
+           defining->nolist = nolist;
+           defining->in_progress = reloc_value(evalresult) + 1;
+           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 1;
 
-       /*
-        * 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;
+       case PP_ENDREP:
+           if (!defining || defining->name)
+           {
+               error(ERR_NONFATAL, "`%%endrep': no matching `%%rep'");
+               return 3;
+           }
 
-       istk->mstk = defining;
+           /*
+            * 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;
 
-       list->uplevel (defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
-       tmp_defining = defining;
-       defining = defining->rep_nest;
-       free_tlist (origline);
-       return 1;
+           istk->mstk = defining;
 
-      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.
-        */
-       for (l = istk->expansion; l; l = l->next)
-           if (l->finishes && !l->finishes->name)
-               break;
+           list->uplevel(defining->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
+           tmp_defining = defining;
+           defining = defining->rep_nest;
+           free_tlist(origline);
+           return 1;
 
-       if (l)
-           l->finishes->in_progress = 0;
-       else
-           error (ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
-       free_tlist (origline);
-       return 1;
-
-      case PP_XDEFINE:
-      case PP_IXDEFINE:
-      case PP_DEFINE:
-      case PP_IDEFINE:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tline || (tline->type != TOK_ID &&
-                      (tline->type != TOK_PREPROC_ID ||
-                       tline->text[1] != '$'))) {
-           error (ERR_NONFATAL,
-                  "`%%%s%sdefine' expects a macro identifier",
-                  ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
-                  ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
-           free_tlist (origline);
-           return 3;
-       }
+       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.
+            */
+           for (l = istk->expansion; l; l = l->next)
+               if (l->finishes && !l->finishes->name)
+                   break;
 
-       ctx = get_ctx (tline->text, FALSE);
-       if (!ctx)
-           smhead = &smacros[hash(tline->text)];
-       else
+           if (l)
+               l->finishes->in_progress = 0;
+           else
+               error(ERR_NONFATAL, "`%%exitrep' not within `%%rep' block");
+           free_tlist(origline);
+           return 1;
+
+       case PP_XDEFINE:
+       case PP_IXDEFINE:
+       case PP_DEFINE:
+       case PP_IDEFINE:
+           tline = tline->next;
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tline || (tline->type != TOK_ID &&
+                           (tline->type != TOK_PREPROC_ID ||
+                                   tline->text[1] != '$')))
+           {
+               error(ERR_NONFATAL,
+                       "`%%%s%sdefine' expects a macro identifier",
+                       ((i == PP_IDEFINE || i == PP_IXDEFINE) ? "i" : ""),
+                       ((i == PP_XDEFINE || i == PP_IXDEFINE) ? "x" : ""));
+               free_tlist(origline);
+               return 3;
+           }
+
+           ctx = get_ctx(tline->text, FALSE);
+           if (!ctx)
+               smhead = &smacros[hash(tline->text)];
+           else
                smhead = &ctx->localmac;
-       mname = tline->text;
-       last = tline;
-       param_start = tline = tline->next;
-       nparam = 0;
+           mname = tline->text;
+           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);
+           /* 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.
-            */
+           if (tok_is_(tline, "("))
+           {
+               /*
+                * This macro has parameters.
+                */
 
-           tline = tline->next;
-           while (1) {
-               skip_white_(tline);
-               if (!tline) {
-                   error (ERR_NONFATAL,
-                          "parameter identifier expected");
-                   free_tlist (origline);
-                   return 3;
-               }
-               if (tline->type != TOK_ID) {
-                   error (ERR_NONFATAL,
-                          "`%s': parameter identifier expected",
-                          tline->text);
-                   free_tlist (origline);
-                   return 3;
-               }
-               tline->type = TOK_SMAC_PARAM + nparam++;
                tline = tline->next;
-               skip_white_(tline);
-               if (tok_is_(tline, ",")) {
+               while (1)
+               {
+                   skip_white_(tline);
+                   if (!tline)
+                   {
+                       error(ERR_NONFATAL, "parameter identifier expected");
+                       free_tlist(origline);
+                       return 3;
+                   }
+                   if (tline->type != TOK_ID)
+                   {
+                       error(ERR_NONFATAL,
+                               "`%s': parameter identifier expected",
+                               tline->text);
+                       free_tlist(origline);
+                       return 3;
+                   }
+                   tline->type = TOK_SMAC_PARAM + nparam++;
                    tline = tline->next;
-                   continue;
+                   skip_white_(tline);
+                   if (tok_is_(tline, ","))
+                   {
+                       tline = tline->next;
+                       continue;
+                   }
+                   if (!tok_is_(tline, ")"))
+                   {
+                       error(ERR_NONFATAL,
+                               "`)' expected to terminate macro template");
+                       free_tlist(origline);
+                       return 3;
+                   }
+                   break;
                }
-               if (!tok_is_(tline, ")")) {
-                   error (ERR_NONFATAL,
-                          "`)' expected to terminate macro template");
-                   free_tlist (origline);
+               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)
+               {
+                   for (tt = param_start; tt; tt = tt->next)
+                       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).
+            */
+           if (smacro_defined(ctx, mname, nparam, &smac, i == PP_DEFINE))
+           {
+               if (!smac)
+               {
+                   error(ERR_WARNING,
+                           "single-line macro `%s' defined both with and"
+                           " without parameters", mname);
+                   free_tlist(origline);
+                   free_tlist(macro_start);
                    return 3;
                }
-               break;
+               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);
+               }
            }
-           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) {
-               for (tt = param_start; tt; tt = tt->next)
-                   if (tt->type >= TOK_SMAC_PARAM &&
-                       !strcmp(tt->text, t->text))
-                       t->type = tt->type;
+           else
+           {
+               smac = nasm_malloc(sizeof(SMacro));
+               smac->next = *smhead;
+               *smhead = smac;
            }
-           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).
-        */
-       if (smacro_defined (ctx, mname, nparam, &smac, i == PP_DEFINE)) {
-           if (!smac) {
-               error (ERR_WARNING,
-                      "single-line macro `%s' defined both with and"
-                      " without parameters", mname);
-               free_tlist (origline);
-               free_tlist (macro_start);
+           smac->name = nasm_strdup(mname);
+           smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
+           smac->nparam = nparam;
+           smac->expansion = macro_start;
+           smac->in_progress = FALSE;
+           free_tlist(origline);
+           return 3;
+
+       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] != '$')))
+           {
+               error(ERR_NONFATAL, "`%%undef' expects a macro identifier");
+               free_tlist(origline);
                return 3;
-           } 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 {
-           smac = nasm_malloc(sizeof(SMacro));
-           smac->next = *smhead;
-           *smhead = smac;
-       }
-       smac->name = nasm_strdup(mname);
-       smac->casesense = ((i == PP_DEFINE) || (i == PP_XDEFINE));
-       smac->nparam = nparam;
-       smac->expansion = macro_start;
-       smac->in_progress = FALSE;
-       free_tlist (origline);
-       return 3;
-
-    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] != '$'))) {
-           error (ERR_NONFATAL,
-                  "`%%undef' expects a macro identifier");
-           free_tlist (origline);
-           return 3;
-       }
-       if (tline->next) {
-           error (ERR_WARNING,
-               "trailing garbage after macro name ignored");
-       }
+           if (tline->next)
+           {
+               error(ERR_WARNING,
+                       "trailing garbage after macro name ignored");
+           }
 
-       /* Find the context that symbol belongs to */
-       ctx = get_ctx (tline->text, FALSE);
-       if (!ctx)
-           smhead = &smacros[hash(tline->text)];
-       else
-           smhead = &ctx->localmac;
+           /* Find the context that symbol belongs to */
+           ctx = get_ctx(tline->text, FALSE);
+           if (!ctx)
+               smhead = &smacros[hash(tline->text)];
+           else
+               smhead = &ctx->localmac;
 
-       mname = tline->text;
-       last = tline;
-       last->next = NULL;
+           mname = tline->text;
+           last = tline;
+           last->next = NULL;
 
-       /*
-        * We now have a macro name... go hunt for it.
-        */
-       while (smacro_defined (ctx, mname, -1, &smac, 1)) {
-         /* Defined, so we need to find its predecessor and nuke it */
-         SMacro **s;
-         for ( s = smhead ; *s && *s != smac ; s = &(*s)->next );
-         if ( *s ) {
-           *s = smac->next;
-           nasm_free(smac->name);
-           free_tlist(smac->expansion);
-           nasm_free(smac);
-         }
-       }
-       free_tlist (origline);
-       return 3;
-
-      case PP_STRLEN:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tline || (tline->type != TOK_ID &&
-                      (tline->type != TOK_PREPROC_ID ||
-                       tline->text[1] != '$'))) {
-           error (ERR_NONFATAL,
-                  "`%%strlen' expects a macro identifier as first parameter");
-           free_tlist (origline);
+           /*
+            * We now have a macro name... go hunt for it.
+            */
+           while (smacro_defined(ctx, mname, -1, &smac, 1))
+           {
+               /* Defined, so we need to find its predecessor and nuke it */
+               SMacro **s;
+               for (s = smhead; *s && *s != smac; s = &(*s)->next);
+               if (*s)
+               {
+                   *s = smac->next;
+                   nasm_free(smac->name);
+                   free_tlist(smac->expansion);
+                   nasm_free(smac);
+               }
+           }
+           free_tlist(origline);
            return 3;
-       }
-        ctx = get_ctx (tline->text, FALSE);
-       if (!ctx)
-           smhead = &smacros[hash(tline->text)];
-       else
+
+       case PP_STRLEN:
+           tline = tline->next;
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tline || (tline->type != TOK_ID &&
+                           (tline->type != TOK_PREPROC_ID ||
+                                   tline->text[1] != '$')))
+           {
+               error(ERR_NONFATAL,
+                       "`%%strlen' expects a macro identifier as first parameter");
+               free_tlist(origline);
+               return 3;
+           }
+           ctx = get_ctx(tline->text, FALSE);
+           if (!ctx)
+               smhead = &smacros[hash(tline->text)];
+           else
                smhead = &ctx->localmac;
-       mname = tline->text;
-       last = tline;
-       tline = expand_smacro (tline->next);
-       last->next = NULL;
+           mname = tline->text;
+           last = tline;
+           tline = expand_smacro(tline->next);
+           last->next = NULL;
 
-       t = tline;
-       while (tok_type_(t, TOK_WHITESPACE))
+           t = tline;
+           while (tok_type_(t, TOK_WHITESPACE))
                t = t->next;
-       /* t should now point to the string */
-       if (t->type != TOK_STRING) {
+           /* t should now point to the string */
+           if (t->type != TOK_STRING)
+           {
                error(ERR_NONFATAL,
                        "`%%strlen` requires string as second parameter");
                free_tlist(tline);
                free_tlist(origline);
                return 3;
-       }
+           }
 
-       macro_start = nasm_malloc(sizeof(*macro_start));
-       macro_start->next = NULL;
-       make_tok_num(macro_start, strlen(t->text)-2);
-       macro_start->mac = NULL;
+           macro_start = nasm_malloc(sizeof(*macro_start));
+           macro_start->next = NULL;
+           make_tok_num(macro_start, strlen(t->text) - 2);
+           macro_start->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.
-        */
-       if (smacro_defined (ctx, mname, 0, &smac, i == PP_STRLEN)) {
-           if (!smac)
-               error (ERR_WARNING,
-                      "single-line macro `%s' defined both with and"
-                      " without parameters", mname);
-           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 {
-           smac = nasm_malloc(sizeof(SMacro));
-           smac->next = *smhead;
-           *smhead = smac;
-       }
-       smac->name = nasm_strdup(mname);
-       smac->casesense = (i == PP_STRLEN);
-       smac->nparam = 0;
-       smac->expansion = macro_start;
-       smac->in_progress = FALSE;
-       free_tlist (tline);
-       free_tlist (origline);
-       return 3;
-
-        case PP_SUBSTR:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tline || (tline->type != TOK_ID &&
-                      (tline->type != TOK_PREPROC_ID ||
-                       tline->text[1] != '$'))) {
-           error (ERR_NONFATAL,
-                  "`%%substr' expects a macro identifier as first parameter");
-           free_tlist (origline);
+           /*
+            * 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.
+            */
+           if (smacro_defined(ctx, mname, 0, &smac, i == PP_STRLEN))
+           {
+               if (!smac)
+                   error(ERR_WARNING,
+                           "single-line macro `%s' defined both with and"
+                           " without parameters", mname);
+               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
+           {
+               smac = nasm_malloc(sizeof(SMacro));
+               smac->next = *smhead;
+               *smhead = smac;
+           }
+           smac->name = nasm_strdup(mname);
+           smac->casesense = (i == PP_STRLEN);
+           smac->nparam = 0;
+           smac->expansion = macro_start;
+           smac->in_progress = FALSE;
+           free_tlist(tline);
+           free_tlist(origline);
            return 3;
-       }
-        ctx = get_ctx (tline->text, FALSE);
-       if (!ctx)
-           smhead = &smacros[hash(tline->text)];
-       else
+
+       case PP_SUBSTR:
+           tline = tline->next;
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tline || (tline->type != TOK_ID &&
+                           (tline->type != TOK_PREPROC_ID ||
+                                   tline->text[1] != '$')))
+           {
+               error(ERR_NONFATAL,
+                       "`%%substr' expects a macro identifier as first parameter");
+               free_tlist(origline);
+               return 3;
+           }
+           ctx = get_ctx(tline->text, FALSE);
+           if (!ctx)
+               smhead = &smacros[hash(tline->text)];
+           else
                smhead = &ctx->localmac;
-       mname = tline->text;
-       last = tline;
-       tline = expand_smacro (tline->next);
-       last->next = NULL;
+           mname = tline->text;
+           last = tline;
+           tline = expand_smacro(tline->next);
+           last->next = NULL;
 
-       t = tline->next;
-       while (tok_type_(t, TOK_WHITESPACE))
+           t = tline->next;
+           while (tok_type_(t, TOK_WHITESPACE))
                t = t->next;
-       
-       /* t should now point to the string */
-       if (t->type != TOK_STRING) {
+
+           /* t should now point to the string */
+           if (t->type != TOK_STRING)
+           {
                error(ERR_NONFATAL,
                        "`%%substr` requires string as second parameter");
                free_tlist(tline);
                free_tlist(origline);
                return 3;
-       }
+           }
 
-       tt = t->next;
-       tptr = &tt;
-       tokval.t_type = TOKEN_INVALID;
-       evalresult = evaluate (ppscan, tptr, &tokval, NULL, pass, error, NULL);
-       if (!evalresult) {
+           tt = t->next;
+           tptr = &tt;
+           tokval.t_type = TOKEN_INVALID;
+           evalresult =
+                   evaluate(ppscan, tptr, &tokval, NULL, pass, error, NULL);
+           if (!evalresult)
+           {
                free_tlist(tline);
                free_tlist(origline);
                return 3;
-       }
-       if (!is_simple(evalresult)) {
-               error(ERR_NONFATAL, 
-                       "non-constant value given to `%%substr`");
+           }
+           if (!is_simple(evalresult))
+           {
+               error(ERR_NONFATAL, "non-constant value given to `%%substr`");
                free_tlist(tline);
                free_tlist(origline);
                return 3;
-       }
-
-       macro_start = nasm_malloc(sizeof(*macro_start));
-       macro_start->next = NULL;
-       macro_start->text = nasm_strdup("'''");
-       if (evalresult->value > 0 && evalresult->value < strlen(t->text)-1) {
-               macro_start->text[1] = t->text[evalresult->value];
-       }
-       else {
-               macro_start->text[2] = '\0';
-       }
-       macro_start->type = TOK_STRING;
-       macro_start->mac = NULL;
+           }
+
+           macro_start = nasm_malloc(sizeof(*macro_start));
+           macro_start->next = NULL;
+           macro_start->text = nasm_strdup("'''");
+           if (evalresult->value > 0
+                   && evalresult->value < strlen(t->text) - 1)
+           {
+               macro_start->text[1] = t->text[evalresult->value];
+           }
+           else
+           {
+               macro_start->text[2] = '\0';
+           }
+           macro_start->type = TOK_STRING;
+           macro_start->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.
+            */
+           if (smacro_defined(ctx, mname, 0, &smac, i == PP_SUBSTR))
+           {
+               if (!smac)
+                   error(ERR_WARNING,
+                           "single-line macro `%s' defined both with and"
+                           " without parameters", mname);
+               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
+           {
+               smac = nasm_malloc(sizeof(SMacro));
+               smac->next = *smhead;
+               *smhead = smac;
+           }
+           smac->name = nasm_strdup(mname);
+           smac->casesense = (i == PP_SUBSTR);
+           smac->nparam = 0;
+           smac->expansion = macro_start;
+           smac->in_progress = FALSE;
+           free_tlist(tline);
+           free_tlist(origline);
+           return 3;
+
+
+       case PP_ASSIGN:
+       case PP_IASSIGN:
+           tline = tline->next;
+           skip_white_(tline);
+           tline = expand_id(tline);
+           if (!tline || (tline->type != TOK_ID &&
+                           (tline->type != TOK_PREPROC_ID ||
+                                   tline->text[1] != '$')))
+           {
+               error(ERR_NONFATAL,
+                       "`%%%sassign' expects a macro identifier",
+                       (i == PP_IASSIGN ? "i" : ""));
+               free_tlist(origline);
+               return 3;
+           }
+           ctx = get_ctx(tline->text, FALSE);
+           if (!ctx)
+               smhead = &smacros[hash(tline->text)];
+           else
+               smhead = &ctx->localmac;
+           mname = tline->text;
+           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, error, NULL);
+           free_tlist(tline);
+           if (!evalresult)
+           {
+               free_tlist(origline);
+               return 3;
+           }
 
-       /*
-        * 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.
-        */
-       if (smacro_defined (ctx, mname, 0, &smac, i == PP_SUBSTR)) {
-           if (!smac)
-               error (ERR_WARNING,
-                      "single-line macro `%s' defined both with and"
-                      " without parameters", mname);
-           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 {
-           smac = nasm_malloc(sizeof(SMacro));
-           smac->next = *smhead;
-           *smhead = smac;
-       }
-       smac->name = nasm_strdup(mname);
-       smac->casesense = (i == PP_SUBSTR);
-       smac->nparam = 0;
-       smac->expansion = macro_start;
-       smac->in_progress = FALSE;
-       free_tlist (tline);
-       free_tlist (origline);
-       return 3;
-
-           
-      case PP_ASSIGN:
-      case PP_IASSIGN:
-       tline = tline->next;
-       skip_white_(tline);
-       tline = expand_id (tline);
-       if (!tline || (tline->type != TOK_ID &&
-                      (tline->type != TOK_PREPROC_ID ||
-                       tline->text[1] != '$'))) {
-           error (ERR_NONFATAL,
-                  "`%%%sassign' expects a macro identifier",
-                  (i == PP_IASSIGN ? "i" : ""));
-           free_tlist (origline);
-           return 3;
-       }
-        ctx = get_ctx (tline->text, FALSE);
-       if (!ctx)
-           smhead = &smacros[hash(tline->text)];
-       else
-               smhead = &ctx->localmac;
-       mname = tline->text;
-       last = tline;
-       tline = expand_smacro (tline->next);
-       last->next = NULL;
+           if (tokval.t_type)
+               error(ERR_WARNING,
+                       "trailing garbage after expression ignored");
 
-       t = tline;
-       tptr = &t;
-       tokval.t_type = TOKEN_INVALID;
-       evalresult = evaluate (ppscan, tptr, &tokval, NULL, pass, error, NULL);
-       free_tlist (tline);
-       if (!evalresult) {
-           free_tlist (origline);
-           return 3;
-       }
+           if (!is_simple(evalresult))
+           {
+               error(ERR_NONFATAL,
+                       "non-constant value given to `%%%sassign'",
+                       (i == PP_IASSIGN ? "i" : ""));
+               free_tlist(origline);
+               return 3;
+           }
 
-       if (tokval.t_type)
-           error(ERR_WARNING,
-                 "trailing garbage after expression ignored");
+           macro_start = nasm_malloc(sizeof(*macro_start));
+           macro_start->next = NULL;
+           make_tok_num(macro_start, reloc_value(evalresult));
+           macro_start->mac = NULL;
 
-       if (!is_simple(evalresult)) {
-           error(ERR_NONFATAL,
-                 "non-constant value given to `%%%sassign'",
-                 (i == PP_IASSIGN ? "i" : ""));
-           free_tlist (origline);
+           /*
+            * 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.
+            */
+           if (smacro_defined(ctx, mname, 0, &smac, i == PP_ASSIGN))
+           {
+               if (!smac)
+                   error(ERR_WARNING,
+                           "single-line macro `%s' defined both with and"
+                           " without parameters", mname);
+               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
+           {
+               smac = nasm_malloc(sizeof(SMacro));
+               smac->next = *smhead;
+               *smhead = smac;
+           }
+           smac->name = nasm_strdup(mname);
+           smac->casesense = (i == PP_ASSIGN);
+           smac->nparam = 0;
+           smac->expansion = macro_start;
+           smac->in_progress = FALSE;
+           free_tlist(origline);
            return 3;
-       }
-
-       macro_start = nasm_malloc(sizeof(*macro_start));
-       macro_start->next = NULL;
-       make_tok_num(macro_start, reloc_value(evalresult));
-       macro_start->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.
-        */
-       if (smacro_defined (ctx, mname, 0, &smac, i == PP_ASSIGN)) {
-           if (!smac)
-               error (ERR_WARNING,
-                      "single-line macro `%s' defined both with and"
-                      " without parameters", mname);
-           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 {
-           smac = nasm_malloc(sizeof(SMacro));
-           smac->next = *smhead;
-           *smhead = smac;
-       }
-       smac->name = nasm_strdup(mname);
-       smac->casesense = (i == PP_ASSIGN);
-       smac->nparam = 0;
-       smac->expansion = macro_start;
-       smac->in_progress = FALSE;
-       free_tlist (origline);
-       return 3;
-
-      case PP_LINE:
-       /*
-        * Syntax is `%line nnn[+mmm] [filename]'
-        */
-       tline = tline->next;
-       skip_white_(tline);
-       if (!tok_type_(tline, TOK_NUMBER)) {
-           error (ERR_NONFATAL, "`%%line' expects line number");
-           free_tlist (origline);
-           return 3;
-       }
-       k = readnum(tline->text, &j);
-       m = 1;
-       tline = tline->next;
-       if (tok_is_(tline, "+")) {
+       case PP_LINE:
+           /*
+            * Syntax is `%line nnn[+mmm] [filename]'
+            */
            tline = tline->next;
-           if (!tok_type_(tline, TOK_NUMBER)) {
-               error (ERR_NONFATAL,
-                      "`%%line' expects line increment");
-               free_tlist (origline);
+           skip_white_(tline);
+           if (!tok_type_(tline, TOK_NUMBER))
+           {
+               error(ERR_NONFATAL, "`%%line' expects line number");
+               free_tlist(origline);
                return 3;
            }
-           m = readnum(tline->text, &j);
+           k = readnum(tline->text, &j);
+           m = 1;
            tline = tline->next;
-       }
-       skip_white_(tline);
-       src_set_linnum(k);
-       istk->lineinc = m;
-       if (tline) {
-           nasm_free (src_set_fname (detoken (tline, FALSE)));
-       }
-       free_tlist (origline);
-       return 5;
-
-      default:
-       error(ERR_FATAL,
-             "preprocessor directive `%s' not yet implemented",
-             directives[i]);
-       break;
+           if (tok_is_(tline, "+"))
+           {
+               tline = tline->next;
+               if (!tok_type_(tline, TOK_NUMBER))
+               {
+                   error(ERR_NONFATAL, "`%%line' expects line increment");
+                   free_tlist(origline);
+                   return 3;
+               }
+               m = readnum(tline->text, &j);
+               tline = tline->next;
+           }
+           skip_white_(tline);
+           src_set_linnum(k);
+           istk->lineinc = m;
+           if (tline)
+           {
+               nasm_free(src_set_fname(detoken(tline, FALSE)));
+           }
+           free_tlist(origline);
+           return 5;
+
+       default:
+           error(ERR_FATAL,
+                   "preprocessor directive `%s' not yet implemented",
+                   directives[i]);
+           break;
     }
     return 3;
 }
@@ -2583,7 +2910,8 @@ static int do_directive (Token *tline)
  * nothing else. Return the condition code index if so, or -1
  * otherwise.
  */
-static int find_cc (Token *t) 
+static int
+find_cc(Token * t)
 {
     Token *tt;
     int i, j, k, m;
@@ -2597,17 +2925,22 @@ static int find_cc (Token *t)
        return -1;
 
     i = -1;
-    j = sizeof(conditions)/sizeof(*conditions);
-    while (j-i > 1) {
-       k = (j+i) / 2;
+    j = sizeof(conditions) / sizeof(*conditions);
+    while (j - i > 1)
+    {
+       k = (j + i) / 2;
        m = nasm_stricmp(t->text, conditions[k]);
-       if (m == 0) {
+       if (m == 0)
+       {
            i = k;
            j = -2;
            break;
-       } else if (m < 0) {
+       }
+       else if (m < 0)
+       {
            j = k;
-       } else
+       }
+       else
            i = k;
     }
     if (j != -2)
@@ -2619,20 +2952,23 @@ static int find_cc (Token *t)
  * Expand MMacro-local things: parameter references (%0, %n, %+n,
  * %-n) and MMacro-local identifiers (%%foo).
  */
-static Token *expand_mmac_params (Token *tline) 
+static Token *
+expand_mmac_params(Token * tline)
 {
-    Token *t, *tt, *ttt, **tail, *thead;
+    Token *t, *tt, **tail, *thead;
 
     tail = &thead;
     thead = NULL;
 
-    while (tline) {
+    while (tline)
+    {
        if (tline->type == TOK_PREPROC_ID &&
-           (((tline->text[1] == '+' || tline->text[1] == '-') && tline->text [2]) ||
-            tline->text[1] == '%' ||
-            (tline->text[1] >= '0' && tline->text[1] <= '9'))) {
+               (((tline->text[1] == '+' || tline->text[1] == '-')
+                               && tline->text[2]) || tline->text[1] == '%'
+                       || (tline->text[1] >= '0' && tline->text[1] <= '9')))
+       {
            char *text = NULL;
-           int type = 0, cc;          /* type = 0 to placate optimisers */
+           int type = 0, cc;   /* type = 0 to placate optimisers */
            char tmpbuf[30];
            int n, i;
            MMacro *mac;
@@ -2641,105 +2977,126 @@ static Token *expand_mmac_params (Token *tline)
            tline = tline->next;
 
            mac = istk->mstk;
-           while (mac && !mac->name)  /* avoid mistaking %reps for macros */
+           while (mac && !mac->name)   /* avoid mistaking %reps for macros */
                mac = mac->next_active;
            if (!mac)
                error(ERR_NONFATAL, "`%s': not in a macro call", t->text);
-           else 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;
-               sprintf(tmpbuf, "%d", mac->nparam);
-               text = nasm_strdup(tmpbuf);
-               break;
-             case '%':
-               type = TOK_ID;
-               sprintf(tmpbuf, "..@%lu.", 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) {
-                   error (ERR_NONFATAL,
-                          "macro parameter %d is not a condition code",
-                          n+1);
-                   text = NULL;
-               } else {
-                   type = TOK_ID;
-                   if (inverse_ccs[cc] == -1) {
-                       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) {
-                   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++) {
-                       ttt = *tail = nasm_malloc(sizeof(Token));
-                       tail = &ttt->next;
-                       ttt->type = tt->type;
-                       ttt->text = nasm_strdup(tt->text);
-                       ttt->mac = NULL;
-                       tt = tt->next;
-                   }
+           else
+               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;
+                       sprintf(tmpbuf, "%d", mac->nparam);
+                       text = nasm_strdup(tmpbuf);
+                       break;
+                   case '%':
+                       type = TOK_ID;
+                       sprintf(tmpbuf, "..@%lu.", 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)
+                       {
+                           error(ERR_NONFATAL,
+                                   "macro parameter %d is not a condition code",
+                                   n + 1);
+                           text = NULL;
+                       }
+                       else
+                       {
+                           type = TOK_ID;
+                           if (inverse_ccs[cc] == -1)
+                           {
+                               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)
+                       {
+                           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;
                }
-               text = NULL;       /* we've done it here */
-               break;
+           if (!text)
+           {
+               delete_Token(t);
            }
-           nasm_free (t->text);
-           if (!text) {
-               nasm_free (t);
-           } else {
+           else
+           {
                *tail = t;
                tail = &t->next;
                t->type = type;
+               nasm_free(t->text);
                t->text = text;
                t->mac = NULL;
            }
            continue;
-       } else {
+       }
+       else
+       {
            t = *tail = tline;
            tline = tline->next;
            t->mac = NULL;
@@ -2748,37 +3105,35 @@ static Token *expand_mmac_params (Token *tline)
     }
     *tail = NULL;
     t = thead;
-    for (; t && (tt=t->next)!=NULL ; t = t->next)
-       switch (t->type) {
-       case TOK_WHITESPACE:
-           if (tt->type == TOK_WHITESPACE) {
-               t->next = tt->next;
-               nasm_free(tt->text);
-               nasm_free(tt); 
-           }
-           break;
-       case TOK_ID:
-           if (tt->type == TOK_ID || tt->type == TOK_NUMBER) {
-               char *tmp = nasm_strcat(t->text, tt->text);
-               nasm_free(t->text);
-               t->text = tmp;
-               t->next = tt->next;
-               nasm_free(tt->text);
-               nasm_free(tt); 
-           }
-           break;
-       case TOK_NUMBER:
-           if (tt->type == TOK_NUMBER) {
-               char *tmp = nasm_strcat(t->text, tt->text);
-               nasm_free(t->text);
-               t->text = tmp;
-               t->next = tt->next;
-               nasm_free(tt->text);
-               nasm_free(tt); 
-           }
-           break;
+    for (; t && (tt = t->next) != NULL; t = t->next)
+       switch (t->type)
+       {
+           case TOK_WHITESPACE:
+               if (tt->type == TOK_WHITESPACE)
+               {
+                   t->next = delete_Token(tt);
+               }
+               break;
+           case TOK_ID:
+               if (tt->type == TOK_ID || tt->type == TOK_NUMBER)
+               {
+                   char *tmp = nasm_strcat(t->text, tt->text);
+                   nasm_free(t->text);
+                   t->text = tmp;
+                   t->next = delete_Token(tt);
+               }
+               break;
+           case TOK_NUMBER:
+               if (tt->type == TOK_NUMBER)
+               {
+                   char *tmp = nasm_strcat(t->text, tt->text);
+                   nasm_free(t->text);
+                   t->text = tmp;
+                   t->next = delete_Token(tt);
+               }
+               break;
        }
-               
+
     return thead;
 }
 
@@ -2789,7 +3144,8 @@ static Token *expand_mmac_params (Token *tline)
  * Tokens from input to output a lot of the time, rather than
  * actually bothering to destroy and replicate.)
  */
-static Token *expand_smacro (Token *tline) 
+static Token *
+expand_smacro(Token * tline)
 {
     Token *t, *tt, *mstart, **tail, *thead;
     SMacro *head = NULL, *m;
@@ -2808,239 +3164,260 @@ static Token *expand_smacro (Token *tline)
      */
     if (org_tline)
     {
-       tline = nasm_malloc (sizeof (Token));
-       *tline = *org_tline;
+       tline =
+               new_Token(org_tline->next, org_tline->type, org_tline->text,
+               0);
+       tline->mac = org_tline->mac;
     }
 
-again:
+  again:
     tail = &thead;
     thead = NULL;
 
-    while (tline) {  /* main token loop */
-       if ((mname = tline->text)) {
+    while (tline)
+    {                          /* main token loop */
+       if ((mname = tline->text))
+       {
            /* if this token is a local macro, look in local context */
            if (tline->type == TOK_ID || tline->type == TOK_PREPROC_ID)
-               ctx = get_ctx (mname, TRUE);
-            else
+               ctx = get_ctx(mname, TRUE);
+           else
                ctx = NULL;
            if (!ctx)
                head = smacros[hash(mname)];
            else
                head = ctx->localmac;
-       /*
-        * 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.
-        */
+           /*
+            * 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.
+            */
            for (m = head; m; m = m->next)
                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 (m)
+           {
+               mstart = tline;
+               params = NULL;
+               paramsize = NULL;
+               if (m->nparam == 0)
                {
-                   if (!strcmp("__FILE__", m->name)) {
-                       long num=0;
-                       src_get(&num, &(tline->text));
-                       nasm_quote(&(tline->text));
-                       tline->type = TOK_STRING;
-                       continue;
-                   }
-                   if (!strcmp("__LINE__", m->name)) {
-                       nasm_free(tline->text);
-                       make_tok_num(tline, src_get_linnum());
+                   /*
+                    * 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))
+                       {
+                           long num = 0;
+                           src_get(&num, &(tline->text));
+                           nasm_quote(&(tline->text));
+                           tline->type = TOK_STRING;
+                           continue;
+                       }
+                       if (!strcmp("__LINE__", m->name))
+                       {
+                           nasm_free(tline->text);
+                           make_tok_num(tline, src_get_linnum());
+                           continue;
+                       }
+                       tline = delete_Token(tline);
                        continue;
                    }
-                   t = tline;
+               }
+               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;
-                   nasm_free (t->text);
-                   nasm_free (t);
-                   continue;
+                   skip_white_(tline);
+                   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;
+                       tline = tline->next;
+                       sparam = PARAM_DELTA;
+                       params = nasm_malloc(sparam * sizeof(Token *));
+                       params[0] = tline;
+                       paramsize = nasm_malloc(sparam * sizeof(int));
+                       paramsize[0] = 0;
+                       for (;; tline = tline->next)
+                       {       /* parameter loop */
+                           if (!tline)
+                           {
+                               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;
+                               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)
+                           error(ERR_WARNING | ERR_WARN_MNP,
+                                   "macro `%s' exists, "
+                                   "but not taking %d parameters",
+                                   mstart->text, nparam);
+                   }
                }
-             } 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);
-                 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;
-                     tline = tline->next;
-                     sparam = PARAM_DELTA;
-                     params = nasm_malloc (sparam*sizeof(Token *));
-                     params[0] = tline;
-                     paramsize = nasm_malloc (sparam*sizeof(int));
-                     paramsize[0] = 0;
-                     for (;;tline = tline->next) {    /* parameter loop */
-                         if (!tline) {
-                             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;
-                             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)
-                         error (ERR_WARNING|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;
+               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;
                }
-               tt = nasm_malloc(sizeof(Token));
-               tt->type = TOK_SMAC_END;
-               tt->text = NULL;
-               tt->mac = m;
-               m->in_progress = TRUE;
-               tt->next = tline;
-               tline = tt;
-               for (t = m->expansion; t; t = t->next) {
-                   if (t->type >= TOK_SMAC_PARAM) {
-                       Token *pcopy = tline, **ptail = &pcopy;
-                       Token *ttt, *pt;
-                       int i;
-                       
-                       ttt = params[t->type - TOK_SMAC_PARAM];
-                       for (i=paramsize[t->type-TOK_SMAC_PARAM]; --i>=0;) {
-                           pt = *ptail = nasm_malloc(sizeof(Token));
-                           pt->next = tline;
-                           ptail = &pt->next;
-                           pt->text = nasm_strdup(ttt->text);
-                           pt->type = ttt->type;
-                           pt->mac = NULL;
-                           ttt = ttt->next;
+               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->mac = m;
+                   m->in_progress = TRUE;
+                   tline = tt;
+                   for (t = m->expansion; t; t = t->next)
+                   {
+                       if (t->type >= TOK_SMAC_PARAM)
+                       {
+                           Token *pcopy = tline, **ptail = &pcopy;
+                           Token *ttt, *pt;
+                           int i;
+
+                           ttt = params[t->type - TOK_SMAC_PARAM];
+                           for (i = paramsize[t->type - TOK_SMAC_PARAM];
+                                   --i >= 0;)
+                           {
+                               pt = *ptail =
+                                       new_Token(tline, ttt->type, ttt->text,
+                                       0);
+                               ptail = &pt->next;
+                               ttt = ttt->next;
+                           }
+                           tline = pcopy;
+                       }
+                       else
+                       {
+                           tt = new_Token(tline, t->type, t->text, 0);
+                           tline = tt;
                        }
-                       tline = pcopy;
-                   } else {
-                       tt = nasm_malloc(sizeof(Token));
-                       tt->type = t->type;
-                       tt->text = nasm_strdup(t->text);
-                       tt->mac = NULL;
-                       tt->next = tline;
-                       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);
+                   continue;   /* main token loop */
                }
-       
-               /*
-                * Having done that, get rid of the macro call, and clean
-                * up the parameters.
-                */
-               nasm_free (params);
-               nasm_free (paramsize);
-               free_tlist (mstart);
-               continue;  /* main token loop */
-             }
            }
        }
 
-       if (tline->type == TOK_SMAC_END) {
+       if (tline->type == TOK_SMAC_END)
+       {
            tline->mac->in_progress = FALSE;
-           t = tline;
-           tline = tline->next;
-           nasm_free (t);
-       } else {
+           tline = delete_Token(tline);
+       }
+       else
+       {
            t = *tail = tline;
            tline = tline->next;
            t->mac = NULL;
@@ -3058,60 +3435,61 @@ again:
      */
     t = thead;
     rescan = 0;
-    while (t) {
+    while (t)
+    {
        while (t && t->type != TOK_ID && t->type != TOK_PREPROC_ID)
            t = t->next;
        if (!t || !t->next)
            break;
        if (t->next->type == TOK_ID ||
-           t->next->type == TOK_PREPROC_ID ||
-           t->next->type == TOK_NUMBER) {
-           Token *next = t->next->next;
-           char *p = nasm_malloc (strlen (t->text) + strlen (t->next->text) + 1);
-           strcpy (p, t->text);
-           strcat (p, t->next->text);
-                   nasm_free (t->text);
-           nasm_free (t->next->text);
-           nasm_free (t->next);
-           t->next = next;
-                   t->text = p;
+               t->next->type == TOK_PREPROC_ID ||
+               t->next->type == TOK_NUMBER)
+       {
+           char *p = nasm_strcat(t->text, t->next->text);
+           nasm_free(t->text);
+           t->next = delete_Token(t->next);
+           t->text = p;
            rescan = 1;
-       } else if (t->next->type == TOK_WHITESPACE && t->next->next &&
-                  t->next->next->type == TOK_PREPROC_ID &&
-                  strcmp (t->next->next->text, "%+") == 0) {
+       }
+       else if (t->next->type == TOK_WHITESPACE && t->next->next &&
+               t->next->next->type == TOK_PREPROC_ID &&
+               strcmp(t->next->next->text, "%+") == 0)
+       {
            /* free the next whitespace, the %+ token and next whitespace */
-            int i;
-            for (i = 1; i <= 3; i++)
-            {
-               Token *next;
+           int i;
+           for (i = 1; i <= 3; i++)
+           {
                if (!t->next || (i != 2 && t->next->type != TOK_WHITESPACE))
                    break;
-               next = t->next->next;
-               nasm_free (t->next->text);
-               nasm_free (t->next);
-               t->next = next;
-           } /* endfor */
-       } else
-         t = t->next;
-               }
+               t->next = delete_Token(t->next);
+           }                   /* endfor */
+       }
+       else
+           t = t->next;
+    }
     /* If we concatenaded something, re-scan the line for macros */
-    if (rescan) {
+    if (rescan)
+    {
        tline = thead;
        goto again;
-           }
+    }
 
     if (org_tline)
     {
-       if (thead) {
+       if (thead)
+       {
            *org_tline = *thead;
-           nasm_free (thead);
-       } else
+           /* 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 = nasm_strdup (" ");
+           memset(org_tline, 0, sizeof(*org_tline));
+           org_tline->text = NULL;
            org_tline->type = TOK_WHITESPACE;
        }
        thead = org_tline;
@@ -3139,35 +3517,36 @@ again:
  * otherwise it will be left as-is) then concatenate all successive
  * PP_IDs into one.
  */
-static Token *expand_id (Token *tline)
+static Token *
+expand_id(Token * tline)
 {
     Token *cur, *oldnext = NULL;
 
-    if (!tline ||
-       !tline->next)
+    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->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 */
+    if (cur)
+    {
+       oldnext = cur->next;    /* Detach the tail past identifier */
+       cur->next = NULL;       /* so that expand_smacro stops here */
     }
 
-    tline = expand_smacro (tline);
+    tline = expand_smacro(tline);
 
-    if (cur) {
+    if (cur)
+    {
        /* expand_smacro possibly changhed tline; re-scan for EOL */
-        cur = tline;
+       cur = tline;
        while (cur && cur->next)
            cur = cur->next;
        if (cur)
@@ -3185,7 +3564,8 @@ static Token *expand_id (Token *tline)
  * 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) 
+static MMacro *
+is_mmacro(Token * tline, Token *** params_array)
 {
     MMacro *head, *m;
     Token **params;
@@ -3209,35 +3589,40 @@ static MMacro *is_mmacro (Token *tline, Token ***params_array)
      * OK, we have a potential macro. Count and demarcate the
      * parameters.
      */
-    count_mmac_params (tline->next, &nparam, &params);
+    count_mmac_params(tline->next, &nparam, &params);
 
     /*
      * 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)) {
+    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) {
+           if (m->in_progress)
+           {
 #if 0
-               error (ERR_NONFATAL,
-                      "self-reference in multi-line macro `%s'",
-                      m->name);
+               error(ERR_NONFATAL,
+                       "self-reference in multi-line macro `%s'", m->name);
 #endif
-               nasm_free (params);
+               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) {
+           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++;
                }
@@ -3252,7 +3637,8 @@ static MMacro *is_mmacro (Token *tline, Token ***params_array)
            /*
             * Then terminate the parameter list, and leave.
             */
-           if (!params) {             /* need this special case */
+           if (!params)
+           {                   /* need this special case */
                params = nasm_malloc(sizeof(*params));
                nparam = 0;
            }
@@ -3273,10 +3659,10 @@ static MMacro *is_mmacro (Token *tline, Token ***params_array)
      * After all that, we didn't find one with the right number of
      * parameters. Issue a warning, and fail to expand the macro.
      */
-    error (ERR_WARNING|ERR_WARN_MNP,
-          "macro `%s' exists, but not taking %d parameters",
-          tline->text, nparam);
-    nasm_free (params);
+    error(ERR_WARNING | ERR_WARN_MNP,
+           "macro `%s' exists, but not taking %d parameters",
+           tline->text, nparam);
+    nasm_free(params);
     return NULL;
 }
 
@@ -3285,7 +3671,8 @@ static MMacro *is_mmacro (Token *tline, Token ***params_array)
  * 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) 
+static int
+expand_mmacro(Token * tline)
 {
     Token *startline = tline;
     Token *label = NULL;
@@ -3299,8 +3686,9 @@ static int expand_mmacro (Token *tline)
     skip_white_(t);
     if (!tok_type_(t, TOK_ID))
        return 0;
-    m = is_mmacro (t, &params);
-    if (!m) {
+    m = is_mmacro(t, &params);
+    if (!m)
+    {
        Token *last;
        /*
         * We have an id which isn't a macro call. We'll assume
@@ -3312,7 +3700,8 @@ static int expand_mmacro (Token *tline)
        t = t->next;
        if (tok_type_(t, TOK_WHITESPACE))
            last = t, t = t->next;
-       if (tok_is_(t, ":")) {
+       if (tok_is_(t, ":"))
+       {
            dont_prepend = 1;
            last = t, t = t->next;
            if (tok_type_(t, TOK_WHITESPACE))
@@ -3331,11 +3720,12 @@ static int expand_mmacro (Token *tline)
      */
     for (nparam = 0; params[nparam]; nparam++)
        ;
-    paramlen = nparam ? nasm_malloc(nparam*sizeof(*paramlen)) : NULL;
+    paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL;
 
-    for (i = 0; params[i]; i++) {
+    for (i = 0; params[i]; i++)
+    {
        int brace = FALSE;
-       int comma = (!m->plus || i < nparam-1);
+       int comma = (!m->plus || i < nparam - 1);
 
        t = params[i];
        skip_white_(t);
@@ -3343,13 +3733,14 @@ static int expand_mmacro (Token *tline)
            t = t->next, brace = TRUE, comma = FALSE;
        params[i] = t;
        paramlen[i] = 0;
-       while (t) {
+       while (t)
+       {
            if (comma && t->type == TOK_OTHER && !strcmp(t->text, ","))
-               break;                 /* ... because we have hit a comma */
+               break;          /* ... because we have hit a comma */
            if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ","))
-               break;                 /* ... or a space then a comma */
+               break;          /* ... or a space then a comma */
            if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}"))
-               break;                 /* ... or a brace */
+               break;          /* ... or a brace */
            t = t->next;
            paramlen[i]++;
        }
@@ -3386,7 +3777,8 @@ static int expand_mmacro (Token *tline)
     m->next_active = istk->mstk;
     istk->mstk = m;
 
-    for (l = m->expansion; l; l = l->next) {
+    for (l = m->expansion; l; l = l->next)
+    {
        Token **tail;
 
        ll = nasm_malloc(sizeof(Line));
@@ -3395,21 +3787,19 @@ static int expand_mmacro (Token *tline)
        istk->expansion = ll;
        tail = &ll->first;
 
-       for (t = l->first; t; t = t->next) {
+       for (t = l->first; t; t = t->next)
+       {
            Token *x = t;
-           if (t->type == TOK_PREPROC_ID && 
-               t->text[1]=='0' && t->text[2]=='0') 
+           if (t->type == TOK_PREPROC_ID &&
+                   t->text[1] == '0' && t->text[2] == '0')
            {
                dont_prepend = -1;
                x = label;
                if (!x)
                    continue;
            }
-           tt = *tail = nasm_malloc(sizeof(Token));
+           tt = *tail = new_Token(NULL, x->type, x->text, 0);
            tail = &tt->next;
-           tt->type = x->type;
-           tt->text = nasm_strdup(x->text);
-           tt->mac = NULL;
        }
        *tail = NULL;
     }
@@ -3418,28 +3808,27 @@ static int expand_mmacro (Token *tline)
      * If we had a label, push it on as the first line of
      * the macro expansion.
      */
-    if (label) {
-       if (dont_prepend<0)
+    if (label)
+    {
+       if (dont_prepend < 0)
            free_tlist(startline);
-       else {
+       else
+       {
            ll = nasm_malloc(sizeof(Line));
            ll->finishes = NULL;
            ll->next = istk->expansion;
            istk->expansion = ll;
            ll->first = startline;
-           if (!dont_prepend) {
+           if (!dont_prepend)
+           {
                while (label->next)
                    label = label->next;
-               label->next = tt = nasm_malloc(sizeof(Token));
-               tt->next = NULL;
-               tt->mac = NULL;
-               tt->type = TOK_OTHER;
-               tt->text = nasm_strdup(":");
+               label->next = tt = new_Token(NULL, TOK_OTHER, ":", 0);
            }
        }
     }
 
-    list->uplevel (m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
+    list->uplevel(m->nolist ? LIST_MACRO_NOLIST : LIST_MACRO);
 
     return 1;
 }
@@ -3450,28 +3839,30 @@ static int expand_mmacro (Token *tline)
  * won't want to see same error twice (preprocessing is done once
  * per pass) we will want to show errors only during pass one.
  */
-static void error (int severity, char *fmt, ...)
+static void
+error(int severity, char *fmt, ...)
 {
     va_list arg;
-    char buff [1024];
+    char buff[1024];
 
     /* If we're in a dead branch of IF or something like it, ignore the error */
     if (istk->conds && !emitting(istk->conds->state))
        return;
 
-    va_start (arg, fmt);
-    vsprintf (buff, fmt, arg);
-    va_end (arg);
+    va_start(arg, fmt);
+    vsprintf(buff, fmt, arg);
+    va_end(arg);
 
     if (istk->mstk && istk->mstk->name)
-       __error (severity|ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
-           istk->mstk->lineno, buff);
+       __error(severity | ERR_PASS1, "(%s:%d) %s", istk->mstk->name,
+               istk->mstk->lineno, buff);
     else
-       __error (severity|ERR_PASS1, "%s", buff);
+       __error(severity | ERR_PASS1, "%s", buff);
 }
 
-static void pp_reset (char *file, int apass, efunc errfunc, evalfunc eval,
-                     ListGen *listgen) 
+static void
+pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
+       ListGen * listgen)
 {
     int h;
 
@@ -3488,35 +3879,43 @@ static void pp_reset (char *file, int apass, efunc errfunc, evalfunc eval,
     src_set_linnum(0);
     istk->lineinc = 1;
     if (!istk->fp)
-       error (ERR_FATAL|ERR_NOFILE, "unable to open input file `%s'", file);
+       error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
     defining = NULL;
-    for (h=0; h<NHASH; h++) {
+    for (h = 0; h < NHASH; h++)
+    {
        mmacros[h] = NULL;
        smacros[h] = NULL;
     }
     unique = 0;
-    stdmacpos = stdmac;
+       if (tasm_compatible_mode) {
+           stdmacpos = stdmac;
+       } else {
+               stdmacpos = &stdmac[TASM_MACRO_COUNT];
+       }
     any_extrastdmac = (extrastdmac != NULL);
     list = listgen;
     evaluate = eval;
     pass = apass;
 }
 
-static char *pp_getline (void) 
+static char *
+pp_getline(void)
 {
     char *line;
     Token *tline;
-    int ret;
 
-    while (1) {
+    while (1)
+    {
        /*
         * Fetch a tokenised line, either from the macro-expansion
         * buffer or from the input file.
         */
        tline = NULL;
-       while (istk->expansion && istk->expansion->finishes) {
+       while (istk->expansion && istk->expansion->finishes)
+       {
            Line *l = istk->expansion;
-           if (!l->finishes->name && l->finishes->in_progress > 1) {
+           if (!l->finishes->name && l->finishes->in_progress > 1)
+           {
                Line *ll;
 
                /*
@@ -3533,7 +3932,8 @@ static char *pp_getline (void)
                 * if we did.
                 */
                l->finishes->in_progress--;
-               for (l = l->finishes->expansion; l; l = l->next) {
+               for (l = l->finishes->expansion; l; l = l->next)
+               {
                    Token *t, *tt, **tail;
 
                    ll = nasm_malloc(sizeof(Line));
@@ -3542,20 +3942,20 @@ static char *pp_getline (void)
                    ll->first = NULL;
                    tail = &ll->first;
 
-                   for (t = l->first; t; t = t->next) {
-                       if (t->text) {
-                           tt = *tail = nasm_malloc(sizeof(Token));
-                           tt->next = NULL;
+                   for (t = l->first; t; t = t->next)
+                   {
+                       if (t->text || t->type == TOK_WHITESPACE)
+                       {
+                           tt = *tail = new_Token(NULL, t->type, t->text, 0);
                            tail = &tt->next;
-                           tt->type = t->type;
-                           tt->text = nasm_strdup(t->text);
-                           tt->mac = NULL;
                        }
                    }
 
                    istk->expansion = ll;
                }
-           } else {
+           }
+           else
+           {
                /*
                 * Check whether a `%rep' was started and not ended
                 * within this macro expansion. This can happen and
@@ -3563,23 +3963,24 @@ static char *pp_getline (void)
                 * I'm too confused to work out how to recover
                 * sensibly from it.
                 */
-               if (defining) {
+               if (defining)
+               {
                    if (defining->name)
-                       error (ERR_PANIC,
-                              "defining with name in expansion");
+                       error(ERR_PANIC, "defining with name in expansion");
                    else if (istk->mstk->name)
-                       error (ERR_FATAL, "`%%rep' without `%%endrep' within"
-                              " expansion of macro `%s'", istk->mstk->name);
+                       error(ERR_FATAL, "`%%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) {
+                   if (m->name)
+                   {
                        /*
                         * This was a real macro call, not a %rep, and
                         * therefore the parameter information needs to
@@ -3589,35 +3990,38 @@ static char *pp_getline (void)
                        free_tlist(m->iline);
                        nasm_free(m->paramlen);
                        l->finishes->in_progress = FALSE;
-                   } 
+                   }
                    else
                        free_mmacro(m);
                }
                istk->expansion = l->next;
-               nasm_free (l);
-               list->downlevel (LIST_MACRO);
+               nasm_free(l);
+               list->downlevel(LIST_MACRO);
            }
        }
-       while (1) {  /* until we get a line we can use */
+       while (1)
+       {                       /* until we get a line we can use */
 
-           if (istk->expansion) {   /* from a macro expansion */
+           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);
-               list->line (LIST_MACRO, p);
+               nasm_free(l);
+               p = detoken(tline, FALSE);
+               list->line(LIST_MACRO, p);
                nasm_free(p);
                break;
            }
            line = read_line();
-           if (line) {    /* from the current input file */
+           if (line)
+           {                   /* from the current input file */
                line = prepreproc(line);
                tline = tokenise(line);
-               nasm_free (line);
+               nasm_free(line);
                break;
            }
            /*
@@ -3629,10 +4033,10 @@ static char *pp_getline (void)
                if (i->conds)
                    error(ERR_FATAL, "expected `%%endif' before end of file");
                istk = i->next;
-               list->downlevel (LIST_INCLUDE);
+               list->downlevel(LIST_INCLUDE);
                src_set_linnum(i->lineno);
-               nasm_free ( src_set_fname(i->fname) );
-               nasm_free (i);
+               nasm_free(src_set_fname(i->fname));
+               nasm_free(i);
                if (!istk)
                    return NULL;
            }
@@ -3654,10 +4058,12 @@ static char *pp_getline (void)
        /*
         * Check the line to see if it's a preprocessor directive.
         */
-       ret = do_directive(tline);
-       if (ret & 1) {
-               continue;
-       } else if (defining) {
+       if (do_directive(tline) & 1)
+       {
+           continue;
+       }
+       else if (defining)
+       {
            /*
             * We're defining a multi-line macro. We emit nothing
             * at all, and just
@@ -3669,7 +4075,9 @@ static char *pp_getline (void)
            l->finishes = FALSE;
            defining->expansion = l;
            continue;
-       } else if (istk->conds && !emitting(istk->conds->state)) {
+       }
+       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
@@ -3678,7 +4086,9 @@ static char *pp_getline (void)
             */
            free_tlist(tline);
            continue;
-       } else if (istk->mstk && !istk->mstk->in_progress) {
+       }
+       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
@@ -3689,18 +4099,22 @@ static char *pp_getline (void)
             */
            free_tlist(tline);
            continue;
-       } else {
+       }
+       else
+       {
            tline = expand_smacro(tline);
-           ret = expand_mmacro(tline);
-           if (!ret) {
+           if (!expand_mmacro(tline))
+           {
                /*
                 * De-tokenise the line again, and emit it.
                 */
                line = detoken(tline, TRUE);
-               free_tlist (tline);
+               free_tlist(tline);
                break;
-           } else {
-               continue;              /* expand_mmacro calls free_tlist */
+           }
+           else
+           {
+               continue;       /* expand_mmacro calls free_tlist */
            }
        }
     }
@@ -3708,43 +4122,50 @@ static char *pp_getline (void)
     return line;
 }
 
-static void pp_cleanup (void) 
+static void
+pp_cleanup(void)
 {
     int h;
 
-    if (defining) {
-       error (ERR_NONFATAL, "end of file while still defining macro `%s'",
-              defining->name);
-       free_mmacro (defining);
+    if (defining)
+    {
+       error(ERR_NONFATAL, "end of file while still defining macro `%s'",
+               defining->name);
+       free_mmacro(defining);
     }
     while (cstk)
        ctx_pop();
-    for (h=0; h<NHASH; h++) {
-       while (mmacros[h]) {
+    for (h = 0; h < NHASH; h++)
+    {
+       while (mmacros[h])
+       {
            MMacro *m = mmacros[h];
            mmacros[h] = mmacros[h]->next;
            free_mmacro(m);
        }
-       while (smacros[h]) {
+       while (smacros[h])
+       {
            SMacro *s = smacros[h];
            smacros[h] = smacros[h]->next;
-           nasm_free (s->name);
-           free_tlist (s->expansion);
-           nasm_free (s);
+           nasm_free(s->name);
+           free_tlist(s->expansion);
+           nasm_free(s);
        }
     }
-    while (istk) {
+    while (istk)
+    {
        Include *i = istk;
        istk = istk->next;
        fclose(i->fp);
-       nasm_free (i->fname);
-       nasm_free (i);
+       nasm_free(i->fname);
+       nasm_free(i);
     }
     while (cstk)
        ctx_pop();
 }
 
-void pp_include_path (char *path) 
+void
+pp_include_path(char *path)
 {
     IncPath *i;
 
@@ -3754,24 +4175,15 @@ void pp_include_path (char *path)
     ipath = i;
 }
 
-void pp_pre_include (char *fname) 
+void
+pp_pre_include(char *fname)
 {
     Token *inc, *space, *name;
     Line *l;
 
-    inc = nasm_malloc(sizeof(Token));
-    inc->next = space = nasm_malloc(sizeof(Token));
-    space->next = name = nasm_malloc(sizeof(Token));
-    name->next = NULL;
-
-    inc->type = TOK_PREPROC_ID;
-    inc->text = nasm_strdup("%include");
-    space->type = TOK_WHITESPACE;
-    space->text = nasm_strdup(" ");
-    name->type = TOK_INTERNAL_STRING;
-    name->text = nasm_strdup(fname);
-
-    inc->mac = space->mac = name->mac = NULL;
+    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;
@@ -3780,29 +4192,22 @@ void pp_pre_include (char *fname)
     predef = l;
 }
 
-void pp_pre_define (char *definition) 
+void
+pp_pre_define(char *definition)
 {
     Token *def, *space;
     Line *l;
     char *equals;
 
     equals = strchr(definition, '=');
-
-    def = nasm_malloc(sizeof(Token));
-    def->next = space = nasm_malloc(sizeof(Token));
+    space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
+    def = new_Token(space, TOK_PREPROC_ID, "%define", 0);
     if (equals)
        *equals = ' ';
     space->next = tokenise(definition);
     if (equals)
        *equals = '=';
 
-    def->type = TOK_PREPROC_ID;
-    def->text = nasm_strdup("%define");
-    space->type = TOK_WHITESPACE;
-    space->text = nasm_strdup(" ");
-
-    def->mac = space->mac = NULL;
-
     l = nasm_malloc(sizeof(Line));
     l->next = predef;
     l->first = def;
@@ -3810,21 +4215,14 @@ void pp_pre_define (char *definition)
     predef = l;
 }
 
-void pp_pre_undefine (char *definition) 
+void
+pp_pre_undefine(char *definition)
 {
     Token *def, *space;
     Line *l;
 
-    def = nasm_malloc(sizeof(Token));
-    def->next = space = nasm_malloc(sizeof(Token));
-    space->next = tokenise(definition);
-
-    def->type = TOK_PREPROC_ID;
-    def->text = nasm_strdup("%undef");
-    space->type = TOK_WHITESPACE;
-    space->text = nasm_strdup(" ");
-
-    def->mac = space->mac = NULL;
+    space = new_Token(NULL, TOK_WHITESPACE, NULL, 0);
+    def = new_Token(space, TOK_PREPROC_ID, "%undef", 0);
 
     l = nasm_malloc(sizeof(Line));
     l->next = predef;
@@ -3833,12 +4231,14 @@ void pp_pre_undefine (char *definition)
     predef = l;
 }
 
-void pp_extra_stdmac (char **macros) 
+void
+pp_extra_stdmac(char **macros)
 {
     extrastdmac = macros;
 }
 
-static void make_tok_num(Token *tok, long val) 
+static void
+make_tok_num(Token * tok, long val)
 {
     char numbuf[20];
     sprintf(numbuf, "%ld", val);
index 46efc0a..5ea14a0 100644 (file)
@@ -62,7 +62,9 @@ rdflib.o: rdflib.c
 segtab.o: segtab.c
 
 nasmlib.o: $(top_srcdir)/nasmlib.c
-       $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
+##     $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c
+       cd $(top_srcdir);make nasmlib.o
+       cp $(top_srcdir)/nasmlib.o $(srcdir)
 
 clean:
        rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx
index 66988d2..29f9aa0 100644 (file)
@@ -4,8 +4,16 @@ RDOFF Utils v0.3
 The files contained in this directory are the C source code of a set
 of tools (and general purpose library files) for the manipulation of
 RDOFF version 2 object files. Note that these programs (with the
-exception of 'rdfdump') will NOT work with version 1 object files. Version 1
-of RDOFF is no longer supported. You should be using v2 instead now.
+exception of 'rdfdump') will NOT work with version 1 object files. See
+the subdirectory v1 for programs that perform that task. 
+
+Note: If you do not have a v1 subdirectory, you may have unpacked the
+ZIP file without specifying the 'restore directory structure' option -
+delete these files, and run your ZIP extracter again with this option 
+turned on ('-d' for PKUNZIP).
+
+RDOFF version 1 is no longer really supported, you should be using
+v2 instead now.
 
 There is also a 'Changes' file, which documents the differences between
 RDOFF 1 and 2, and an 'rdoff2.txt' file, with complete documentation for the
diff --git a/rdoff/ldrdf1.c b/rdoff/ldrdf1.c
deleted file mode 100644 (file)
index 9e4a215..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/* ldrdf.c     RDOFF Object File linker/loader main program
- *
- * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
- * Julian Hall. All rights reserved. The software is
- * redistributable under the licence given in the file "Licence"
- * distributed in the NASM archive.
- */
-
-/* TODO: Make the system skip a module (other than the first) if none
- * of the other specified modules contain a reference to it.
- * May require the system to make an extra pass of the modules to be
- * loaded eliminating those that aren't required.
- *
- * Support all the existing documented options...
- *
- * Support libaries (.a files - requires a 'ranlib' type utility)
- *             (I think I've got this working, so I've upped the version)
- *
- * -s option to strip resolved symbols from exports. (Could make this an
- * external utility)
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "rdoff.h"
-#include "nasmlib.h"
-#include "symtab.h"
-#include "collectn.h"
-#include "rdlib.h"
-
-#define LDRDF_VERSION "0.30"
-
-/* global variables - those to set options: */
-
-int    verbose = 0;    /* reflects setting of command line switch */
-int    align = 16;
-int    errors = 0;     /* set by functions to cause halt after current
-                          stage of processing */
-
-/* the linked list of modules that must be loaded & linked */
-
-struct modulenode {
-    rdffile    f;      /* the file */
-    long       coderel;        /* module's code relocation factor */
-    long       datarel;        /* module's data relocation factor */
-    long       bssrel;         /* module's bss data reloc. factor */
-    void *     header;         /* header location, if loaded */
-    char *     name;           /* filename */
-    struct modulenode *next;
-};
-
-#define newstr(str) strcpy(malloc(strlen(str) + 1),str)
-#define newstrcat(s1,s2) strcat(strcpy(malloc(strlen(s1)+strlen(s2)+1),s1),s2)
-
-
-struct modulenode *modules = NULL,*lastmodule = NULL;
-
-/* the linked list of libraries to be searched for missing imported
-   symbols */
-
-struct librarynode * libraries = NULL, * lastlib = NULL;
-
-void *symtab;  /* The symbol table */
-
-rdf_headerbuf * newheader ;    /* New header to be written to output */
-
-/* loadmodule - find the characteristics of a module and add it to the
- *             list of those being linked together                     */
-
-void loadmodule(char *filename)
-{
-  struct modulenode *prev;
-  if (! modules) {
-    modules = malloc(sizeof(struct modulenode));
-    lastmodule = modules;
-    prev = NULL;
-  }
-  else {
-    lastmodule->next = malloc(sizeof(struct modulenode));
-    prev = lastmodule;
-    lastmodule = lastmodule->next;
-  }
-
-  if (! lastmodule) {
-    fputs("ldrdf: not enough memory\n",stderr);
-    exit(1);
-  }
-
-  if (rdfopen(&lastmodule->f,filename)) {
-    rdfperror("ldrdf",filename);
-    exit(1);
-  }
-
-  lastmodule->header = NULL;   /* header hasn't been loaded */
-  lastmodule->name = filename;
-  lastmodule->next = NULL;
-
-  if (prev) {
-    lastmodule->coderel = prev->coderel + prev->f.code_len;
-    if (lastmodule->coderel % align != 0)
-      lastmodule->coderel += align - (lastmodule->coderel % align);
-    lastmodule->datarel = prev->datarel + prev->f.data_len;
-    if (lastmodule->datarel % align != 0)
-      lastmodule->datarel += align - (lastmodule->datarel % align);
-  }
-  else {
-    lastmodule->coderel = 0;
-    lastmodule->datarel = 0;
-  }
-
-  if (verbose)
-    printf("%s code = %08lx (+%04lx), data = %08lx (+%04lx)\n",filename,
-          lastmodule->coderel,lastmodule->f.code_len,
-          lastmodule->datarel,lastmodule->f.data_len);
-
-  lastmodule->header = malloc(lastmodule->f.header_len);
-  if (!lastmodule->header) {
-      fprintf(stderr,"ldrdf: out of memory\n");
-      exit(1);
-  }
-
-  if (rdfloadseg(&lastmodule->f,RDOFF_HEADER,lastmodule->header))
-  {
-      rdfperror("ldrdf",filename);
-      exit(1);
-  }
-}
-
-/* load_library                add a library to list of libraries to search
- *                      for undefined symbols
- */
-
-void load_library(char * name)
-{
-    if (verbose)
-       printf("adding library %s to search path\n",name);
-       
-    if (! lastlib) {
-       lastlib = libraries = malloc(sizeof(struct librarynode));
-    }
-    else
-    {
-       lastlib->next = malloc(sizeof(struct librarynode));
-       lastlib = lastlib->next;
-    }
-
-    if (! lastlib) {
-       fprintf(stderr, "ldrdf: out of memory\n");
-       exit(1);
-    }
-    strcpy (lastlib->name = malloc (1+strlen(name)), name);
-    lastlib->fp = NULL;
-    lastlib->referenced = 0;
-    lastlib->next = NULL;
-}
-
-
-/* build_symbols()     step through each module's header, and locate
- *                     exported symbols, placing them in a global table
- */
-
-long bsslength;
-
-void mod_addsymbols(struct modulenode * mod)
-{
-    rdfheaderrec *r;
-    symtabEnt e;
-    long cbBss;
-
-    mod->bssrel = bsslength;
-    cbBss = 0;
-    rdfheaderrewind(&mod->f);
-    while ((r = rdfgetheaderrec(&mod->f)))
-    {
-
-       if (r->type == 5)               /* Allocate BSS */
-           cbBss += r->b.amount;
-
-       if (r->type != 3) continue;     /* ignore all but export recs */
-
-       e.segment = r->e.segment;
-       e.offset = r->e.offset + 
-           (e.segment == 0 ? mod->coderel : /* 0 -> code */
-            e.segment == 1 ? mod->datarel : /* 1 -> data */
-            mod->bssrel) ; /* 2 -> bss  */
-       
-       e.flags = 0;
-       e.name = malloc(strlen(r->e.label) + 1);
-       if (! e.name)
-       {
-           fprintf(stderr,"ldrdf: out of memory\n");
-           exit(1);
-       }
-       strcpy(e.name,r->e.label);
-       symtabInsert(symtab,&e);
-    }
-    bsslength += cbBss;
-}
-
-void build_symbols()
-{
-  struct modulenode *mod;
-
-  if (verbose) printf("building global symbol table:\n");
-  newheader = rdfnewheader();
-
-  symtab = symtabNew();
-  bsslength = 0;                 /* keep track of location of BSS symbols */
-
-  for (mod = modules; mod; mod = mod->next)
-  {
-      mod_addsymbols( mod );
-  }
-  if (verbose)
-  {
-      symtabDump(symtab,stdout);
-      printf("BSS length = %ld bytes\n\n",bsslength);
-  }
-}
-
-
-/* scan_libraries()    search through headers of modules for undefined
- *                     symbols, and scan libraries for those symbols,
- *                     adding library modules found to list of modules
- *                     to load.                                        */
-
-void scan_libraries(void)
-{
-    struct modulenode  * mod, * nm;
-    struct librarynode * lib;
-    rdfheaderrec       * r;
-    int                        found;
-    char               * tmp;
-
-    if (verbose) printf("Scanning libraries for unresolved symbols...\n");
-
-    mod = modules;
-
-    while (mod)
-    {
-       rdfheaderrewind(&mod->f);
-
-       while ((r = rdfgetheaderrec(&mod->f)))
-       {
-           if (r->type != 2) continue; /* not an import record */
-           if ( symtabFind (symtab,r->i.label) )
-               continue;               /* symbol already defined */
-           
-           /* okay, we have an undefined symbol... step through
-              the libraries now */
-           if (verbose >= 2) {
-               printf("undefined symbol '%s'...",r->i.label);
-               fflush(stdout);
-           }
-
-           lib = libraries;
-           found = 0;
-
-           tmp = newstr(r->i.label);
-           while (! found && lib)
-           {
-               /* move this to an outer loop...! */
-               nm = malloc(sizeof(struct modulenode));
-
-               if (rdl_searchlib(lib,tmp,&nm->f))
-               {       /* found a module in the library */
-
-                   /* create a modulenode for it */
-
-                   if (! nm) {
-                       fprintf(stderr,"ldrdf: out of memory\n");
-                       exit(1);
-                   }
-
-                   nm->name = newstrcat(lib->name,nm->f.name);
-                   if (verbose >= 2) printf("found in '%s'\n",nm->name);
-
-                   nm->coderel = lastmodule->coderel + lastmodule->f.code_len;
-                   if (nm->coderel % align != 0)
-                       nm->coderel += align - (nm->coderel % align);
-
-                   nm->datarel = lastmodule->datarel + lastmodule->f.data_len;
-                   if (nm->datarel % align != 0)
-                       nm->datarel += align - (nm->datarel % align);
-
-                   nm->header = malloc(nm->f.header_len);
-                   if (! nm->header)
-                   {
-                       fprintf(stderr,"ldrdf: out of memory\n");
-                       exit(1);
-                   }
-
-                   if (rdfloadseg(&nm->f,RDOFF_HEADER,nm->header))
-                   {
-                       rdfperror("ldrdf",nm->name);
-                       exit(1);
-                   }
-
-                   nm->next = NULL;
-                   found = 1;
-                   lastmodule->next = nm;
-                   lastmodule = nm;
-
-                   if (verbose)
-                       printf("%s code = %08lx (+%04lx), data = %08lx "
-                              "(+%04lx)\n",lastmodule->name,
-                              lastmodule->coderel,lastmodule->f.code_len,
-                              lastmodule->datarel,lastmodule->f.data_len);
-
-                   /* add the module's info to the symbol table */
-                   mod_addsymbols(nm);
-               }
-               else
-               {
-                   if (rdl_error) {
-                       rdl_perror("ldrdf",lib->name);
-                       exit(1);
-                   }
-                   free(nm);
-               }
-               lib = lib->next;
-           }
-           free(tmp);
-           if (!found && verbose >= 2) printf("not found\n");
-       }
-       mod = mod->next;
-    }
-}
-
-/* load_segments()     allocates memory for & loads the code & data segs
- *                     from the RDF modules
- */
-
-char *text,*data;
-long textlength,datalength;
-
-void load_segments(void)
-{
-  struct modulenode *mod;
-
-  if (!modules) {
-    fprintf(stderr,"ldrdf: nothing to do\n");
-    exit(0);
-  }
-  if (!lastmodule) {
-    fprintf(stderr,"ldrdf: panic: module list exists, but lastmodule=NULL\n");
-    exit(3);
-  }
-
-  if (verbose)
-    printf("loading modules into memory\n");
-
-  /* The following stops 16 bit DOS from crashing whilst attempting to
-     work using segments > 64K */
-  if (sizeof(int) == 2) { /* expect a 'code has no effect' warning on 32 bit
-                           platforms... */
-    if (lastmodule->coderel + lastmodule->f.code_len > 65535 ||
-       lastmodule->datarel + lastmodule->f.data_len > 65535) {
-      fprintf(stderr,"ldrdf: segment length has exceeded 64K; use a 32 bit "
-             "version.\nldrdf: code size = %05lx, data size = %05lx\n",
-             lastmodule->coderel + lastmodule->f.code_len,
-             lastmodule->datarel + lastmodule->f.data_len);
-      exit(1);
-    }
-  }
-
-  text = malloc(textlength = lastmodule->coderel + lastmodule->f.code_len);
-  data = malloc(datalength = lastmodule->datarel + lastmodule->f.data_len);
-
-  if (!text || !data) {
-    fprintf(stderr,"ldrdf: out of memory\n");
-    exit(1);
-  }
-
-  mod = modules;
-  while (mod) {                /* load the segments for each module */
-      if (verbose >= 2) printf("  loading %s\n",mod->name);
-      if (rdfloadseg(&mod->f,RDOFF_CODE,&text[mod->coderel]) ||
-         rdfloadseg(&mod->f,RDOFF_DATA,&data[mod->datarel])) {
-         rdfperror("ldrdf",mod->name);
-         exit(1);
-      }
-      rdfclose(&mod->f);       /* close file; segments remain */
-      mod = mod->next;
-  }
-}
-    
-/* link_segments()     step through relocation records in each module's
- *                     header, fixing up references.
- */
-
-void link_segments(void)
-{
-  struct modulenode    *mod;
-  Collection           imports;
-  symtabEnt            *s;
-  long                         rel,relto;
-  char                         *seg;
-  rdfheaderrec         *r;
-  int                  bRelative;
-
-  if (verbose) printf("linking segments\n");
-
-  collection_init(&imports);
-
-  for (mod = modules; mod; mod = mod->next) {
-    if (verbose >= 2) printf("* processing %s\n",mod->name);
-    rdfheaderrewind(&mod->f);
-    while((r = rdfgetheaderrec(&mod->f))) {
-       if (verbose >= 3) printf("record type: %d\n",r->type);
-       switch(r->type) {
-       case 1:         /* relocation record */
-           if (r->r.segment >= 64) {           /* Relative relocation; */
-               bRelative = 1;          /* need to find location relative */
-               r->r.segment -= 64;             /* to start of this segment */
-               relto = r->r.segment == 0 ? mod->coderel : mod->datarel;
-           }
-           else
-           {
-               bRelative = 0;          /* non-relative - need to relocate
-                                        * at load time                 */
-               relto = 0;             /* placate optimiser warnings */
-           }
-
-           /* calculate absolute offset of reference, not rel to beginning of
-              segment */
-           r->r.offset += r->r.segment == 0 ? mod->coderel : mod->datarel;
-
-           /* calculate the relocation factor to apply to the operand -
-              the base address of one of this modules segments if referred
-              segment is 0 - 2, or the address of an imported symbol
-              otherwise. */
-
-           if (r->r.refseg == 0) rel = mod->coderel;
-           else if (r->r.refseg == 1) rel = mod->datarel;
-           else if (r->r.refseg == 2) rel = mod->bssrel;
-           else {              /* cross module link - find reference */
-               s = *colln(&imports,r->r.refseg - 2);
-               if (!s) {
-                   fprintf(stderr,"ldrdf: link to undefined segment %04x in"
-                           " %s:%d\n", r->r.refseg,mod->name,r->r.segment);
-                   errors = 1;
-                   break;
-               }
-               rel = s->offset;
-         
-               r->r.refseg = s->segment;       /* change referred segment, 
-                                                  so that new header is
-                                                  correct */
-           }
-
-           if (bRelative)      /* Relative - subtract current segment start */
-               rel -= relto; 
-           else  
-           {                   /* Add new relocation header */
-               rdfaddheader(newheader,r);
-           }
-           
-           /* Work out which segment we're making changes to ... */
-           if (r->r.segment == 0) seg = text;
-           else if (r->r.segment == 1) seg = data;
-           else {
-               fprintf(stderr,"ldrdf: relocation in unknown segment %d in "
-                       "%s\n", r->r.segment,mod->name);
-               errors = 1;
-               break;
-           }
-
-           /* Add the relocation factor to the datum specified: */
-
-           if (verbose >= 3)
-               printf("  - relocating %d:%08lx by %08lx\n",r->r.segment,
-                      r->r.offset,rel);
-
-           /**** The following code is non-portable. Rewrite it... ****/
-           switch(r->r.length) {
-           case 1:
-               seg[r->r.offset] += (char) rel;
-               break;
-           case 2:
-               *(int16 *)(seg + r->r.offset) += (int16) rel;
-               break;
-           case 4:
-               *(long *)(seg + r->r.offset) += rel;
-               break;
-           }
-           break;
-
-       case 2:         /* import record */
-           s = symtabFind(symtab, r->i.label);
-           if (s == NULL) {
-               /* Need to add support for dynamic linkage */
-               fprintf(stderr,"ldrdf: undefined symbol %s in module %s\n",
-                       r->i.label,mod->name);
-               errors = 1;
-           }
-           else 
-           {
-               *colln(&imports,r->i.segment - 2) = s;
-               if (verbose >= 2)
-                   printf("imported %s as %04x\n", r->i.label, r->i.segment);
-           }
-           break;
-
-       case 3:         /* export; dump to output new version */
-           s = symtabFind(symtab, r->e.label);
-           if (! s) {
-               fprintf(stderr,"ldrdf: internal error - undefined symbol %s "
-                       "exported in header of '%s'\n",r->e.label,mod->name);
-               continue;
-           }
-           r->e.offset = s->offset;
-           rdfaddheader(newheader,r);
-           break;
-
-       case 4:         /* DLL record */
-           rdfaddheader(newheader,r);          /* copy straight to output */
-           break;
-       }
-    }
-    if (rdf_errno != 0) {
-       rdfperror("ldrdf",mod->name);
-       exit(1);
-    }
-    collection_reset(&imports);
-  }
-}
-    
-/* write_output()      write linked program out to a file */
-
-void write_output(char *filename)
-{
-    FILE               * fp;
-    rdfheaderrec       r;
-
-    if (verbose) printf("writing output to '%s'\n",filename);
-
-    fp = fopen(filename,"wb");
-    if (! fp)
-    {
-       fprintf(stderr,"ldrdf: could not open '%s' for writing\n",filename);
-       exit(1);
-    }
-  
-    
-    /* add BSS length count to header... */
-    if (bsslength)
-    {
-       r.type = 5;
-       r.b.amount = bsslength;
-       rdfaddheader(newheader,&r);
-    }
-
-    /* Write header */
-    rdfwriteheader(fp,newheader);
-    rdfdoneheader(newheader);
-    newheader = NULL;
-
-    /* Write text */
-    if (fwrite(&textlength,1,4,fp) != 4
-       || fwrite(text,1,textlength,fp) !=textlength)
-    {
-       fprintf(stderr,"ldrdf: error writing %s\n",filename);
-       exit(1);
-    }
-
-    /* Write data */
-    if (fwrite(&datalength,1,4,fp) != 4 ||
-       fwrite(data,1,datalength,fp) != datalength)
-    {
-       fprintf (stderr,"ldrdf: error writing %s\n", filename);
-       exit(1);
-    }
-    fclose(fp);
-}
-
-
-/* main program: interpret command line, and pass parameters on to
- * individual module loaders & the linker
- *
- * Command line format:
- * ldrdf [-o outfile | -x] [-r xxxx] [-v] [--] infile [infile ...]
- *
- * Default action is to output a file named 'aout.rdx'. -x specifies
- * that the linked object program should be executed, rather than
- * written to a file. -r specifies that the object program should
- * be prelocated at address 'xxxx'. This option cannot be used
- * in conjunction with -x.
- */
-
-const char *usagemsg = "usage:\n"
-" ldrdf [-o outfile | -x] [-a x] [-v] [-p x] [--] infile [infile ...]\n"
-"       [-l<libname> ...]\n\n"
-" ldrdf -h     displays this message\n"
-" ldrdf -r     displays version information\n\n"
-"   -o selects output filename (default is aout.rdx)\n"
-"   -x causes ldrdx to link & execute rather than write to file\n"
-"   -a x causes object program to be statically relocated to address 'x'\n"
-"   -v turns on verbose mode\n"
-"   -p x causes segments to be aligned (padded) to x byte boundaries\n"
-"      (default is 16 bytes)\n"
-"   -l<name> causes 'name' to be linked in as a library. Note no search is\n"
-"      performed - the entire pathname MUST be specified.\n";
-
-void usage(void)
-{
-  fputs(usagemsg,stderr);
-}
-
-int main(int argc,char **argv)
-{
-  char *ofilename = "aout.rdx";
-  long relocateaddr = -1;      /* -1 if no relocation is to occur */
-  int  execute = 0;            /* 1 to execute after linking, 0 otherwise */
-  int  procsw = 1;             /* set to 0 by '--' */
-  int  tmp;
-
-  if (argc == 1) {
-    usage();
-    exit(1);
-  }
-
-  /* process command line switches, and add modules specified to linked list
-     of modules, keeping track of total memory required to load them */
-
-  while(argv++,--argc) {
-    if (procsw && !strcmp(*argv,"-h")) {       /* Help command */
-      usage(); exit(1);
-    }
-    else if (procsw && !strcmp(*argv,"-r")) {
-      printf("ldrdf version %s (%s) (%s)\n",LDRDF_VERSION,_RDOFF_H,
-            sizeof(int) == 2 ? "16 bit" : "32 bit");
-      exit(1);
-    }
-    else if (procsw && !strcmp(*argv,"-o")) {
-      ofilename = *++argv;
-      --argc;
-      if (execute) {
-       fprintf(stderr,"ldrdf: -o and -x switches incompatible\n");
-       exit(1);
-      }
-      if (verbose > 1) printf("output filename set to '%s'\n",ofilename);
-    }
-    else if (procsw && !strcmp(*argv,"-x")) {
-      execute++;
-      if (verbose > 1) printf("will execute linked object\n");
-    }
-    else if (procsw && !strcmp(*argv,"-a")) {
-      relocateaddr = readnum(*++argv,&tmp);
-      --argc;
-      if (tmp) {
-       fprintf(stderr,"ldrdf: error in parameter to '-a' switch: '%s'\n",
-               *argv);
-       exit(1);
-      }
-      if (execute) {
-       fprintf(stderr,"ldrdf: -a and -x switches incompatible\n");
-       exit(1);
-      }
-      if (verbose) printf("will relocate to %08lx\n",relocateaddr);
-    }
-    else if (procsw && !strcmp(*argv,"-v")) {
-      verbose++;
-      if (verbose == 1) printf("verbose mode selected\n");
-    }
-    else if (procsw && !strcmp(*argv,"-p")) {
-      align = readnum(*++argv,&tmp);
-      --argc;
-      if (tmp) {
-       fprintf(stderr,"ldrdf: error in parameter to '-p' switch: '%s'\n",
-               *argv);
-       exit(1);
-      }
-      if (align != 1 && align != 2 && align != 4 && align != 8 && align != 16
-         && align != 32 && align != 256) {
-       fprintf(stderr,"ldrdf: %d is an invalid alignment factor - must be"
-               "1,2,4,8,16 or 256\n",align);
-       exit(1);
-      }
-      if (verbose > 1) printf("alignment %d selected\n",align);
-    }
-    else if (procsw && !strncmp(*argv,"-l",2)) {
-       load_library(*argv + 2);
-    }
-    else if (procsw && !strcmp(*argv,"--")) {
-      procsw = 0;
-    }
-    else {                                     /* is a filename */
-      if (verbose > 1) printf("processing module %s\n",*argv);
-      loadmodule(*argv);
-    }
-  }
-
-  /* we should be scanning for unresolved references, and removing
-     unreferenced modules from the list of modules here, so that
-     we know about the final size once libraries have been linked in */
-
-  build_symbols();     /* build a global symbol table...           */
-
-  scan_libraries();    /* check for imported symbols not in table,
-                          and ensure the relevant library modules
-                          are loaded */
-
-  load_segments();     /* having calculated size of reqd segments, load
-                          each rdoff module's segments into memory */
-
-  link_segments();     /* step through each module's header, and resolve
-                          references to the global symbol table.
-                          This also does local address fixups. */
-
-  if (errors) {
-    fprintf(stderr,"ldrdf: there were errors - aborted\n");
-    exit(errors);
-  }
-  if (execute) {
-    fprintf(stderr,"ldrdf: module execution not yet supported\n");
-    exit(1);
-  }
-  if (relocateaddr != -1) {
-    fprintf(stderr,"ldrdf: static relocation not yet supported\n");
-    exit(1);
-  }
-
-  write_output(ofilename);
-  return 0;
-}
index 58e65df..333cedd 100644 (file)
@@ -1,4 +1,15 @@
 ; Standard macro set for NASM 0.98 -*- nasm -*-
+
+; Macros to make NASM ignore some TASM directives before the first include
+; directive.
+
+    %idefine IDEAL
+    %idefine JUMPS
+    %idefine P386
+    %idefine P486
+    %idefine P586
+    %idefine END
+
 ; Note that although some user-level forms of directives are defined
 ; here, not all of them are: the user-level form of a format-specific
 ; directive should be defined in the module for that directive.
@@ -32,7 +43,7 @@
 %define %$strucname %1
 [absolute 0]
 %$strucname:                   ; allow definition of `.member' to work sanely
-%endmacro
+%endmacro 
 %imacro endstruc 0.nolist
 %{$strucname}_size:
 %pop
@@ -97,12 +108,3 @@ __SECT__
 %endmacro
 
 
-; Macros to make NASM ignore some TASM directives before the first include
-; directive.
-
-%idefine IDEAL
-%idefine JUMPS
-%idefine P386
-%idefine P486
-%idefine P586
-%idefine END
index 0bcdb5c..9784e79 100644 (file)
@@ -158,7 +158,7 @@ extern struct ofmt of_ieee;
 
 static void ieee_data_new(struct ieeeSection *);
 static void ieee_write_fixup (long, long, struct ieeeSection *,
-                               int, long, long);
+                               int, unsigned long, long);
 static void ieee_install_fixup(struct ieeeSection *, struct ieeeFixupp *);
 static long ieee_segment (char *, int, int *);
 static void ieee_write_file(int debuginfo);
@@ -369,7 +369,7 @@ static void ieee_deflabel (char *name, long segment,
  */
 static void ieee_out (long segto, void *data, unsigned long type,
                     long segment, long wrt) {
-    long size, realtype;
+    unsigned long size, realtype;
     unsigned char *ucdata;
     long ldata;
     struct ieeeSection *seg;
@@ -447,7 +447,7 @@ static void ieee_data_new(struct ieeeSection *segto) {
  * If anyone wants to optimize this is a good canditate!
  */
 static void ieee_write_fixup (long segment, long wrt, struct ieeeSection * segto,
-                               int size, long realtype, long offset) {
+                               int size, unsigned long realtype, long offset) {
     struct ieeeSection *target;
     struct ieeeFixupp s;
 
@@ -1312,7 +1312,7 @@ static void dbgls_linnum (const char *lnfname, long lineno, long segto)
     }
     ieee_write_byte(seghead, fn->index);
     ieee_write_word(seghead, lineno);
-    ieee_write_fixup (segto, NO_SEG, seghead, 4,OUT_ADDRESS,seg->currentpos);
+    ieee_write_fixup (segto, NO_SEG, seghead, 4, OUT_ADDRESS, seg->currentpos);
 
 }
 static void dbgls_deflabel (char *name, long segment,