NASM 0.98p3.5
authorH. Peter Anvin <hpa@zytor.com>
Tue, 30 Apr 2002 20:56:43 +0000 (20:56 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 30 Apr 2002 20:56:43 +0000 (20:56 +0000)
17 files changed:
MODIFIED
Readme
assemble.c
c16.mac
c32.mac
changes.asm
disasm.c
disasm.h
exebin.mac
insns.dat
insns.h
names.c
nasm.h
ndisasm.c
parser.c
preproc.c
rdoff/Makefile.sc

index 60a49e0..4e0ddb1 100644 (file)
--- a/MODIFIED
+++ b/MODIFIED
@@ -2,6 +2,30 @@ This is a modified version of NASM, modified and released by H. Peter
 Anvin <hpa@zytor.com>; it is not the original form released by the
 NASM authors.
 
+For release 0.98p3.5:
+
+* Merged in changes from John S. Fine's 0.98-J5 release.  John's based
+  0.98-J5 on my 0.98p3.3 release; this merges the changes.
+* Expanded the instructions flag field to a long so we can fit more
+  flags; mark SSE (KNI) and AMD or Katmai-specific instructions as
+  such.
+* Fix the "PRIV" flag on a bunch of instructions, and create new
+  "PROT" flag for protected-mode-only instructions (orthogonal to if
+  the instruction is privileged!) and new "SMM" flag for SMM-only
+  instructions.
+* Added AMD-only SYSCALL and SYSRET instructions.
+* Make SSE actually work, and add new Katmai MMX instructions.
+* Added a -p (preferred vendor) option to ndisasm so that it can
+  distinguish e.g. Cyrix opcodes also used in SSE.  For example:
+
+       ndisasm -p cyrix aliased.bin
+       00000000  670F514310        paddsiw mm0,[ebx+0x10]
+       00000005  670F514320        paddsiw mm0,[ebx+0x20]
+       ndisasm -p intel aliased.bin
+       00000000  670F514310        sqrtps xmm0,[ebx+0x10]
+       00000005  670F514320        sqrtps xmm0,[ebx+0x20]
+* Added a bunch of Cyrix-specific instructions.
+
 For release 0.98p3.4:
 
 * Made at least an attempt to modify all the additional Makefiles (in
diff --git a/Readme b/Readme
index 11fb184..6e7c56c 100644 (file)
--- a/Readme
+++ b/Readme
-This is a distribution of NASM, the Netwide Assembler. NASM is a
-prototype general-purpose x86 assembler. It will currently output
-flat-form binary files, a.out, COFF and ELF Unix object files,
-Microsoft Win32 and 16-bit DOS object files, OS/2 object files, the
-as86 object format, and a home-grown format called RDF.
+This directory contains the necessary files to port the C compiler
+``LCC'' (available by FTP from sunsite.doc.ic.ac.uk in the directory
+/computing/programming/languages/c/lcc) to compile for Linux (a.out or
+ELF) or other supported operating systems by using NASM as a back-end
+code generator.
 
-Also included is NDISASM, a prototype x86 binary-file disassembler
-which uses the same instruction table as NASM.
+This patch has been tested on lcc version 4.0.
 
-To install NASM on Linux, type `make', and then when it has finished
-copy the file `nasm' (and maybe `ndisasm') to a directory on your
-search path (maybe /usr/local/bin, or ~/bin if you don't have root
-access). You may also want to copy the man page `nasm.1' (and maybe
-`ndisasm.1') to somewhere sensible.
+To install:
 
-To install under DOS, if you don't need to rebuild from the sources,
-you can just copy nasm.exe and ndisasm.exe (16-bit DOS executables),
-or nasmw.exe and ndisasmw.exe (Win32 console applications - less
-likely to run out of memory), to somewhere on your PATH.
+- Copy `x86nasm.md' into the `src' directory of the lcc tree.
 
-To rebuild the DOS sources, various makefiles are provided:
+- Copy either `lin-elf.c' or `lin-aout.c' into the `etc' directory.
 
-- Makefile.dos, the one I build the standard 16-bit releases from,
-  designed for a hybrid system using Microsoft C and Borland Make
-  (don't ask why :-)
-- Makefile.vc, for Microsoft Visual C++ compiling to a Win32
-  command-line application. This is the one I build the standard
-  Win32 release binaries from.
+- With previous versions, you had to modify x86-nasm.md if you weren't
+  using ELF.  There is now inbuilt support within NASM in the shape
+  of the __CDECL__ macro, so this modification is no longer necessary.
 
-- Makefile.bor, for Borland C.
-- Makefile.bc2, also for Borland C, contributed by Fox Cutter.
-  Reported to work better than Makefile.bor on some systems.
+- Make the following changes to `bind.c' in the `src' directory:
 
-- Makefile.sc, for Symantec C++, compiling to a 32-bit extended DOS
-  executable.. Contributed by Mark Junker.
-- Makefile.scw, also for Symantec C++, compiling to a Win32 command-
-  line application. Also contributed by Mark Junker.
+  - Near the top of the file, add a line that reads
+       extern Interface x86nasmIR;
 
-- Makefile.wc, for Watcom C, compiling to a 32-bit extended DOS
-  executable. Contributed by Dominik Behr.
-- Makefile.wcw, also for Watcom C, compiling to a Win32 command-
-  line application. Also contributed by Dominik Behr.
+  - In the `bindings' array, add the lines
+        "x86-nasm",      &x86nasmIR,
+        "x86/nasm",      &x86nasmIR,
+    (in sensible looking places...)
 
-- Makefile.dj, for DJGPP, compiling to a 32-bit extended DOS
-  executable. Contributed by Dominik Behr.
+  A sample `bind.c' has been provided to show what the result of
+  this might look like. You might be able to get away with using it
+  directly...
 
-- Makefile.lcc, for lcc-win32, compiling to a Win32 command line
-  application. (The lcc-win32 compiler and tools are available from
-  http://www.remcomp.com/lcc-win32/)
+- Modify the lcc makefile to include rules for x86nasm.o: this will
+  have to be done in about three places. Just copy any line with
+  `x86' on it and modify it to read `x86nasm' everywhere. (Except
+  that in the list of object files that rcc is made up from, do
+  remember to ensure that every line but the last has a trailing
+  backslash...)
 
-I can't guarantee that all of those makefiles work, because I don't
-have all of those compilers. However, Makefile.dos and Makefile.vc
-work on my system, and so do Makefile.bor and Makefile.bc2.
+- You may have to modify the contents of `lin-elf.c' or `lin-aout.c'
+  to reflect the true locations of files such as crt0.o, crt1.o,
+  ld-linux.so and so forth. If you don't know where to find these,
+  compile a short C program with `gcc -v' and see what command line
+  gcc feeds to `ld'.
 
-Be careful with Borland C: there have been various conflicting
-reports about how reliable the Huge memory model is. If you try to
-compile NASM in Large model, you may get DGROUP overflows due to the
-vast quantity of data in the instruction tables. I've had reports
-from some people that Huge model doesn't work at all (and also
-reports from others that it works fine), so if you don't want to try
-moving to Huge, you could try adding the option `-dc' to the
-compiler command line instead, which causes string literals to be
-moved from DGROUP to the code segments and might make Large model
-start working. (Either solution works for me.)
+- You should now be able to build lcc, using `lin-elf.c' or
+  `lin-aout.c' as the system-dependent part of the `lcc' wrapper
+  program.
 
-Dominik Behr has also contributed the file misc/pmw.bat, which is a
-batch file to turn the output from Makefile.wc (NASM.EXE and
-NDISASM.EXE) into standalone executables incorporating Tran's
-PMODE/W DOS extender, rather than depending on an external extender
-program.
+- Symlink x86nasm.c into the `src' directory before attempting the
+  triple test, or the compile will fail.
 
-Some of the Windows makefiles produce executables called nasmw.exe
-and ndisasmw.exe, and some don't. Be prepared for either...
-
-If you're trying to unpack the DOS (.ZIP format) archive under Unix
-instead of using the .tar.gz version, you can save some time by
-doing `unzip -aL', which will convert the DOS-format text files to
-Unix and also convert all names to lower case.
-
-If you want to build a restricted version of NASM containing only
-some of the object file formats, you can achieve this by adding
-#defines to `outform.h' (see the file itself for documentation), or
-equivalently by adding compiler command line options in the
-Makefile.
-
-There is a machine description file for the `LCC' retargetable C
-compiler (version 3.6), in the directory `lcc', along with
-instructions for its use. This means that NASM can now be used as
-the code-generator back end for a useful C compiler.
-
-Michael `Wuschel' Tippach has ported his DOS extender `WDOSX' to
-enable it to work with the 32-bit binary files NASM can output: the
-original extender and his port `WDOSX/N' are available from his web
-page, http://www.geocities.com/SiliconValley/Park/4493.
-
-Matt Mastracci has written a document explaining how to write
-assembly language modules in DJGPP programs using NASM: it's on his
-web site at http://www.ucalgary.ca/~mmastrac/djgppasm.doc.
-
-The `misc' directory contains `nasm.sl', a NASM editing mode for the
-JED programmers' editor (see http://space.mit.edu/~davis/jed.html
-for details about JED). The comment at the start of the file gives
-instructions on how to install the mode. This directory also
-contains a file (`magic') containing lines to add to /etc/magic on
-Unix systems to allow the `file' command to recognise RDF files, and
-a zip file (`exasm.zip') containing the necessary files for syntax
-highlighting in the Aurora DOS editor. (The Aurora files were
-contributed by <U993847220@aol.com>; I haven't tested them as I
-don't have Aurora.)
-
-The `rdoff' directory contains sources for a linker and loader for
-the RDF object file format, to run under Linux, and also
-documentation on the internal structure of RDF files.
-
-For information about how you can distribute and use NASM, see the
-file Licence. We were tempted to put NASM under the GPL, but decided
-that in many ways it was too restrictive for developers.
-
-For information about how to use NASM, see the various forms of
-documentation in the `doc' directory: documentation is provided in
-HTML, PostScript, plain text, Texinfo, and Windows Help formats. For
-information about how to use NDISASM, see `ndisasm.doc'. For
-information about the internal structure of NASM, see
-`internal.doc'. (In particular, _please_ read `internal.doc' before
-writing any code for us...)
-
-The NASM web page is at http://www.cryogen.com/Nasm/
-
-Bug reports (and patches if you can) should be sent to
-<jules@earthcorp.com> or <anakin@pobox.com>.
+- Now it should pass the triple test, on either ELF or a.out. Voila!
index 65bcea3..ae1de20 100644 (file)
@@ -611,7 +611,7 @@ static void gencode (long segment, long offset, int bits,
            case R_SS: 
                bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
            default:
-               errfunc (ERR_PANIC, "bizarre 8086 segment register received");
+                errfunc (ERR_PANIC, "bizarre 8086 segment register received");
            }
            out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
            offset++;
@@ -622,7 +622,7 @@ static void gencode (long segment, long offset, int bits,
            case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
            case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
            default:
-               errfunc (ERR_PANIC, "bizarre 386 segment register received");
+                errfunc (ERR_PANIC, "bizarre 386 segment register received");
            }
            out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
            offset++;
@@ -928,31 +928,31 @@ static int regval (operand *o)
 {
     switch (o->basereg) {
       case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
-      case R_ST0: case R_MM0:
+      case R_ST0: case R_MM0: case R_XMM0:
        return 0;
       case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
-      case R_MM1:
+      case R_MM1: case R_XMM1:
        return 1;
       case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
-      case R_ST2: case R_MM2:
+      case R_ST2: case R_MM2:  case R_XMM2:
        return 2;
       case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
-      case R_TR3: case R_ST3: case R_MM3:
+      case R_TR3: case R_ST3: case R_MM3:  case R_XMM3:
        return 3;
       case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
-      case R_ST4: case R_MM4:
+      case R_ST4: case R_MM4:  case R_XMM4:
        return 4;
       case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
-      case R_MM5:
+      case R_MM5:  case R_XMM5:
        return 5;
       case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
-      case R_MM6:
+      case R_MM6:  case R_XMM6:
        return 6;
       case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
-      case R_MM7:
+      case R_MM7:  case R_XMM7:
        return 7;
       default:                        /* panic */
-       errfunc (ERR_PANIC, "invalid register operand given to regval()");
+        errfunc (ERR_PANIC, "invalid register operand given to regval()");
        return 0;
     }
 }
@@ -1031,10 +1031,11 @@ static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
 {
     if (!(REGISTER & ~input->type)) {  /* it's a single register */
        static int regs[] = {
-           R_MM0, R_EAX, R_AX, R_AL, R_MM1, R_ECX, R_CX, R_CL,
-           R_MM2, R_EDX, R_DX, R_DL, R_MM3, R_EBX, R_BX, R_BL,
-           R_MM4, R_ESP, R_SP, R_AH, R_MM5, R_EBP, R_BP, R_CH,
-           R_MM6, R_ESI, R_SI, R_DH, R_MM7, R_EDI, R_DI, R_BH
+         R_AL,   R_CL,   R_DL,   R_BL,   R_AH,   R_CH,   R_DH,   R_BH,
+         R_AX,   R_CX,   R_DX,   R_BX,   R_SP,   R_BP,   R_SI,   R_DI,
+         R_EAX,  R_ECX,  R_EDX,  R_EBX,  R_ESP,  R_EBP,  R_ESI,  R_EDI,
+         R_MM0,  R_MM1,  R_MM2,  R_MM3,  R_MM4,  R_MM5,  R_MM6,  R_MM7,
+         R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
        };
        int i;
 
@@ -1043,7 +1044,7 @@ static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
        if (i<elements(regs)) {
            output->sib_present = FALSE;/* no SIB necessary */
            output->bytes = 0;         /* no offset necessary either */
-           output->modrm = 0xC0 | (rfield << 3) | (i/4);
+            output->modrm = 0xC0 | (rfield << 3) | (i & 7);
        } 
        else
            return NULL;
diff --git a/c16.mac b/c16.mac
index 2853db5..50b5d5e 100644 (file)
--- a/c16.mac
+++ b/c16.mac
@@ -1,41 +1,82 @@
-; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*-\r
-\r
-%imacro proc 1                 ; begin a procedure definition\r
-%push proc\r
-         global %1\r
-%1:      push bp\r
-         mov bp,sp\r
-%ifdef FARCODE PASCAL          ; arguments may start at bp+4 or bp+6\r
-%assign %$arg 6\r
-%define %$firstarg 6\r
-%else\r
-%assign %$arg 4\r
-%define %$firstarg 4\r
-%endif\r
-%define %$procname %1\r
-%endmacro\r
-\r
-%imacro arg 0-1 2              ; used with the argument name as a label\r
-%00      equ %$arg\r
-                               ; we could possibly be adding some\r
-                               ; debug information at this point...?\r
-%assign %$arg %1+%$arg\r
-%endmacro\r
-\r
-%imacro endproc 0\r
-%ifnctx proc\r
-%error Mismatched `endproc'/`proc'\r
-%else\r
-          mov sp,bp\r
-          pop bp\r
-%ifdef PASCAL\r
-          retf %$arg - %$firstarg\r
-%elifdef FARCODE\r
-         retf\r
-%else\r
-         retn\r
-%endif\r
-__end_%$procname:              ; useful for calculating function size\r
-%pop\r
-%endif\r
-%endmacro\r
+; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*-
+
+
+
+%imacro proc 1                 ; begin a procedure definition
+
+%push proc
+
+         global %1
+
+%1:      push bp
+
+         mov bp,sp
+
+%ifdef FARCODE PASCAL          ; arguments may start at bp+4 or bp+6
+
+%assign %$arg 6
+
+%define %$firstarg 6
+
+%else
+
+%assign %$arg 4
+
+%define %$firstarg 4
+
+%endif
+
+%define %$procname %1
+
+%endmacro
+
+
+
+%imacro arg 0-1 2              ; used with the argument name as a label
+
+%00      equ %$arg
+
+                               ; we could possibly be adding some
+
+                               ; debug information at this point...?
+
+%assign %$arg %1+%$arg
+
+%endmacro
+
+
+
+%imacro endproc 0
+
+%ifnctx proc
+
+%error Mismatched `endproc'/`proc'
+
+%else
+
+          mov sp,bp
+
+          pop bp
+
+%ifdef PASCAL
+
+          retf %$arg - %$firstarg
+
+%elifdef FARCODE
+
+         retf
+
+%else
+
+         retn
+
+%endif
+
+__end_%$procname:              ; useful for calculating function size
+
+%pop
+
+%endif
+
+%endmacro
+
diff --git a/c32.mac b/c32.mac
index 6abad99..f0c116b 100644 (file)
--- a/c32.mac
+++ b/c32.mac
@@ -1,26 +1,52 @@
-; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*-\r
-\r
-%imacro proc 1                 ; begin a procedure definition\r
-%push proc\r
-          global %1\r
-%1:       push ebp\r
-          mov ebp,esp\r
-%assign %$arg 8\r
-%define %$procname %1\r
-%endmacro\r
-\r
-%imacro arg 0-1 4              ; used with the argument name as a label\r
-%00      equ %$arg\r
-%assign %$arg %1+%$arg\r
-%endmacro\r
-\r
-%imacro endproc 0\r
-%ifnctx proc\r
-%error Mismatched `endproc'/`proc'\r
-%else\r
-         leave\r
-         ret\r
-__end_%$procname:              ; useful for calculating function size\r
-%pop\r
-%endif\r
-%endmacro\r
+; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*-
+
+
+
+%imacro proc 1                 ; begin a procedure definition
+
+%push proc
+
+          global %1
+
+%1:       push ebp
+
+          mov ebp,esp
+
+%assign %$arg 8
+
+%define %$procname %1
+
+%endmacro
+
+
+
+%imacro arg 0-1 4              ; used with the argument name as a label
+
+%00      equ %$arg
+
+%assign %$arg %1+%$arg
+
+%endmacro
+
+
+
+%imacro endproc 0
+
+%ifnctx proc
+
+%error Mismatched `endproc'/`proc'
+
+%else
+
+         leave
+
+         ret
+
+__end_%$procname:              ; useful for calculating function size
+
+%pop
+
+%endif
+
+%endmacro
+
index 05b6788..2601a01 100644 (file)
@@ -98,6 +98,19 @@ forwardref:
 %endmacro
 xxx yyy
 
+;-----------------------------------------------------------------------------
+; Bug added by John in preproc.c 0.98-J4, removed by John in 0.98-J5
+;
+; Tested here to make sure it stays removed
+;
+%macro TestElse 1
+%if %1=0
+%elif %1=1
+nop
+%endif
+%endmacro
+TestElse 1
+
 %ifdef oldmsg
 ;***************************************************************
 ;
@@ -280,9 +293,20 @@ arg_example2 arg2
        ud2
        sysenter
        sysexit
+       syscall
+       sysret
        fxsave [ebx]
        fxrstor [es:ebx+esi*4+0x3000]
 
+;-----------------------------------------------------------------------------
+; Enhancement by hpa in insns.dat et al
+;
+; Actually make SSE work, and use the -p option to ndisasm to select
+; one of several aliased opcodes
+;
+       sqrtps xmm0,[ebx+10]    ; SSE opcode
+       paddsiw mm0,[ebx+10]    ; Cyrix opcode with the same byte seq.
+       
 %endif
 
 %ifdef oldcrash  ;*************************************************************
index 4764bc1..ba76097 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -53,6 +53,8 @@ static int whichreg(long regflags, int regval)
        R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7 };
     static int mmxreg[] = {
        R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7 };
+    static int xmmreg[] = {
+       R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7 };
 
     if (!(REG_AL & ~regflags))
        return R_AL;
@@ -96,6 +98,8 @@ static int whichreg(long regflags, int regval)
        return fpureg[regval];
     if (!(MMXREG & ~regflags))
        return mmxreg[regval];
+    if (!(XMMREG & ~regflags))
+       return xmmreg[regval];
     return 0;
 }
 
@@ -445,15 +449,16 @@ static int matches (unsigned char *r, unsigned char *data, int asize,
 }
 
 long disasm (unsigned char *data, char *output, int segsize, long offset,
-            int autosync
+            int autosync, unsigned long prefer)
 {
-    struct itemplate **p;
-    int length = 0;
+    struct itemplate **p, **best_p;
+    int length, best_length = 0;
     char *segover;
     int rep, lock, asize, osize, i, slen, colon;
     unsigned char *origdata;
     int works;
     insn ins;
+    unsigned long goodness, best;
 
     /*
      * Scan for prefixes.
@@ -489,45 +494,55 @@ long disasm (unsigned char *data, char *output, int segsize, long offset,
     ins.oprs[0].addr_size = ins.oprs[1].addr_size = ins.oprs[2].addr_size =
        (segsize == 16 ? 0 : SEG_32BIT);
     ins.condition = -1;
-    works = TRUE;
-    for (p = itable[*data]; *p; p++)
-       if ( (length = matches((unsigned char *)((*p)->code), data,
-                              asize, osize, segsize, &ins)) ) 
-       {
-           works = TRUE;
-           /*
-            * Final check to make sure the types of r/m match up.
-            */
-           for (i = 0; i < (*p)->operands; i++)
-               if (
-                   
-                   /* If it's a mem-only EA but we have a register, die. */
-                   ((ins.oprs[i].segment & SEG_RMREG) &&
-                    !(MEMORY & ~(*p)->opd[i])) ||
-                   
-                   /* If it's a reg-only EA but we have a memory ref, die. */
-                   (!(ins.oprs[i].segment & SEG_RMREG) &&
-                    !(REGNORM & ~(*p)->opd[i]) &&
-                    !((*p)->opd[i] & REG_SMASK)) ||
-
-                   /* Register type mismatch (eg FS vs REG_DESS): die. */
-                   ((((*p)->opd[i] & (REGISTER | FPUREG)) ||
-                     (ins.oprs[i].segment & SEG_RMREG)) &&
-                    !whichreg ((*p)->opd[i], ins.oprs[i].basereg)))
-               {
-                   works = FALSE;
-                   /*
-                    * FIXME: can we do a break here?
-                    */
-               }
-
-           if (works)
-               break;
-       }
+    best = ~0UL;               /* Worst possible */
+    best_p = NULL;
+    for (p = itable[*data]; *p; p++) {
+      if ( (length = matches((unsigned char *)((*p)->code), data,
+                            asize, osize, segsize, &ins)) ) {
+       works = TRUE;
+       /*
+        * Final check to make sure the types of r/m match up.
+        */
+       for (i = 0; i < (*p)->operands; i++) {
+         if (
+             
+             /* If it's a mem-only EA but we have a register, die. */
+             ((ins.oprs[i].segment & SEG_RMREG) &&
+              !(MEMORY & ~(*p)->opd[i])) ||
+             
+             /* If it's a reg-only EA but we have a memory ref, die. */
+             (!(ins.oprs[i].segment & SEG_RMREG) &&
+              !(REGNORM & ~(*p)->opd[i]) &&
+              !((*p)->opd[i] & REG_SMASK)) ||
+             
+             /* Register type mismatch (eg FS vs REG_DESS): die. */
+             ((((*p)->opd[i] & (REGISTER | FPUREG)) ||
+               (ins.oprs[i].segment & SEG_RMREG)) &&
+              !whichreg ((*p)->opd[i], ins.oprs[i].basereg))) {
+           works = FALSE;
+           break;
+         }
+       }  
+       
+       if (works) {
+         goodness = ((*p)->flags & IF_PFMASK) ^ prefer;
+         if ( goodness < best ) {
+           /* This is the best one found so far */
+           best = goodness;
+           best_p = p;
+           best_length = length;
+         }
+       }
+      }
+    }
 
-    if (!length || !works)
+    if (!best_p )
        return 0;                      /* no instruction was matched */
 
+    /* Pick the best match */
+    p = best_p;
+    length = best_length;
+
     slen = 0;
 
     if (rep) {
index 845fd2e..16cdbda 100644 (file)
--- a/disasm.h
+++ b/disasm.h
@@ -12,7 +12,7 @@
 #define INSN_MAX 32    /* one instruction can't be longer than this */
 
 long disasm (unsigned char *data, char *output, int segsize, long offset,
-            int autosync);
+            int autosync, unsigned long prefer);
 long eatbyte (unsigned char *data, char *output);
 
 #endif
index 022183f..89c6889 100644 (file)
-; -*- nasm -*-\r
-; NASM macro file to allow the `bin' output format to generate\r
-; simple .EXE files by constructing the EXE header by hand.\r
-; Adapted from a contribution by Yann Guidon <whygee_corp@hol.fr>\r
-\r
-%define EXE_stack_size EXE_realstacksize\r
-\r
-%macro EXE_begin 0\r
-         ORG 0E0h\r
-         section .text\r
-\r
-header_start:\r
-         db 4Dh,5Ah            ; EXE file signature\r
-         dw EXE_allocsize % 512\r
-         dw (EXE_allocsize + 511) / 512\r
-         dw 0                  ; relocation information: none\r
-         dw (header_end-header_start)/16 ; header size in paragraphs\r
-         dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem\r
-         dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem\r
-         dw -10h               ; Initial SS (before fixup)\r
-         dw EXE_endbss + EXE_realstacksize ; Initial SP (1K DPMI+1K STACK)\r
-         dw 0                  ; (no) Checksum\r
-         dw 100h               ; Initial IP - start just after the header\r
-         dw -10h               ; Initial CS (before fixup)\r
-         dw 0                  ; file offset to relocation table: none\r
-         dw 0                  ; (no overlay)\r
-         align 16,db 0\r
-header_end:\r
-\r
-EXE_startcode:\r
-         section .data\r
-EXE_startdata:\r
-         section .bss\r
-EXE_startbss:\r
-%endmacro\r
-\r
-%macro EXE_stack 1\r
-EXE_realstacksize equ %1\r
-%define EXE_stack_size EXE_bogusstacksize ; defeat EQU in EXE_end\r
-%endmacro\r
-\r
-%macro EXE_end 0\r
-         section .text\r
-EXE_endcode:\r
-         section .data\r
-EXE_enddata:\r
-         section .bss\r
-         alignb 4\r
-EXE_endbss:\r
-\r
-EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3)\r
-EXE_datasize equ EXE_enddata-EXE_startdata\r
-EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3)\r
-EXE_allocsize equ EXE_acodesize + EXE_datasize\r
-\r
-EXE_stack_size equ 0x800       ; default if nothing else was used\r
-%endmacro\r
+; -*- nasm -*-
+
+; NASM macro file to allow the `bin' output format to generate
+
+; simple .EXE files by constructing the EXE header by hand.
+
+; Adapted from a contribution by Yann Guidon <whygee_corp@hol.fr>
+
+
+
+%define EXE_stack_size EXE_realstacksize
+
+
+
+%macro EXE_begin 0
+
+         ORG 0E0h
+
+         section .text
+
+
+
+header_start:
+
+         db 4Dh,5Ah            ; EXE file signature
+
+         dw EXE_allocsize % 512
+
+         dw (EXE_allocsize + 511) / 512
+
+         dw 0                  ; relocation information: none
+
+         dw (header_end-header_start)/16 ; header size in paragraphs
+
+         dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem
+
+         dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem
+
+         dw -10h               ; Initial SS (before fixup)
+
+         dw EXE_endbss + EXE_realstacksize ; Initial SP (1K DPMI+1K STACK)
+
+         dw 0                  ; (no) Checksum
+
+         dw 100h               ; Initial IP - start just after the header
+
+         dw -10h               ; Initial CS (before fixup)
+
+         dw 0                  ; file offset to relocation table: none
+
+         dw 0                  ; (no overlay)
+
+         align 16,db 0
+
+header_end:
+
+
+
+EXE_startcode:
+
+         section .data
+
+EXE_startdata:
+
+         section .bss
+
+EXE_startbss:
+
+%endmacro
+
+
+
+%macro EXE_stack 1
+
+EXE_realstacksize equ %1
+
+%define EXE_stack_size EXE_bogusstacksize ; defeat EQU in EXE_end
+
+%endmacro
+
+
+
+%macro EXE_end 0
+
+         section .text
+
+EXE_endcode:
+
+         section .data
+
+EXE_enddata:
+
+         section .bss
+
+         alignb 4
+
+EXE_endbss:
+
+
+
+EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3)
+
+EXE_datasize equ EXE_enddata-EXE_startdata
+
+EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3)
+
+EXE_allocsize equ EXE_acodesize + EXE_datasize
+
+
+
+EXE_stack_size equ 0x800       ; default if nothing else was used
+
+%endmacro
+
index 425d0a8..deb5b11 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -85,8 +85,8 @@ AND       rm32,imm            \321\300\1\x81\204\41         386,SM
 AND       mem,imm8            \300\1\x80\204\21             8086,SM
 AND       mem,imm16           \320\300\1\x81\204\31         8086,SM
 AND       mem,imm32           \321\300\1\x81\204\41         386,SM
-ARPL      mem,reg16           \300\1\x63\101                286,PRIV,SM
-ARPL      reg16,reg16         \300\1\x63\101                286,PRIV
+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
 BOUND     reg32,mem           \321\301\1\x62\110            386
 BSF       reg16,mem           \320\301\2\x0F\xBC\110        386,SM
@@ -273,7 +273,7 @@ FDIVR     fpureg              \1\xD8\10\xF8                 8086,FPU
 FDIVR     fpu0,fpureg         \1\xD8\11\xF8                 8086,FPU
 FDIVRP    fpureg              \1\xDE\10\xF0                 8086,FPU
 FDIVRP    fpureg,fpu0         \1\xDE\10\xF0                 8086,FPU
-FEMMS     void                \2\x0F\x0E                    PENT,MMX,FPU
+FEMMS     void                \2\x0F\x0E                    PENT,3DNOW
 FENI      void                \3\x9B\xDB\xE0                8086,FPU
 FFREE     fpureg              \1\xDD\10\xC0                 8086,FPU
 FIADD     mem32               \300\1\xDA\200                8086,FPU
@@ -387,12 +387,10 @@ FXCH      void                \2\xD9\xC9                    8086,FPU
 FXCH      fpureg              \1\xD9\10\xC8                 8086,FPU
 FXCH      fpureg,fpu0         \1\xD9\10\xC8                 8086,FPU
 FXCH      fpu0,fpureg         \1\xD9\11\xC8                 8086,FPU
-FXRSTOR   mem                 \300\2\x0F\xAE\202            P6,FPU
-FXSAVE    mem                 \300\2\x0F\xAE\200            P6,FPU
 FXTRACT   void                \2\xD9\xF4                    8086,FPU
 FYL2X     void                \2\xD9\xF1                    8086,FPU
 FYL2XP1   void                \2\xD9\xF9                    8086,FPU
-HLT       void                \1\xF4                        8086
+HLT       void                \1\xF4                        8086,PRIV
 IBTS      mem,reg16           \320\300\2\x0F\xA7\101        386,SW,UNDOC,ND
 IBTS      reg16,reg16         \320\300\2\x0F\xA7\101        386,UNDOC,ND
 IBTS      mem,reg32           \321\300\2\x0F\xA7\101        386,SD,UNDOC,ND
@@ -441,8 +439,8 @@ INT1      void                \1\xF1                        386
 INT03     void                \1\xCC                        8086,ND
 INT3      void                \1\xCC                        8086
 INTO      void                \1\xCE                        8086
-INVD      void                \2\x0F\x08                    486
-INVLPG    mem                 \300\2\x0F\x01\207            486
+INVD      void                \2\x0F\x08                    486,PRIV
+INVLPG    mem                 \300\2\x0F\x01\207            486,PRIV
 IRET      void                \322\1\xCF                    8086
 IRETD     void                \321\1\xCF                    386
 IRETW     void                \320\1\xCF                    8086
@@ -469,10 +467,10 @@ JMP       mem                 \322\300\1\xFF\204            8086
 JMP       mem16               \320\300\1\xFF\204            8086
 JMP       mem32               \321\300\1\xFF\204            386
 LAHF      void                \1\x9F                        8086
-LAR       reg16,mem           \320\301\2\x0F\x02\110        286,PRIV,SM
-LAR       reg16,reg16         \320\301\2\x0F\x02\110        286,PRIV
-LAR       reg32,mem           \321\301\2\x0F\x02\110        286,PRIV,SM
-LAR       reg32,reg32         \321\301\2\x0F\x02\110        286,PRIV
+LAR       reg16,mem           \320\301\2\x0F\x02\110        286,PROT,SM
+LAR       reg16,reg16         \320\301\2\x0F\x02\110        286,PROT
+LAR       reg32,mem           \321\301\2\x0F\x02\110        286,PROT,SM
+LAR       reg32,reg32         \321\301\2\x0F\x02\110        286,PROT
 LDS       reg16,mem           \320\301\1\xC5\110            8086
 LDS       reg32,mem           \321\301\1\xC5\110            8086
 LEA       reg16,mem           \320\301\1\x8D\110            8086
@@ -486,9 +484,9 @@ LGDT      mem                 \300\2\x0F\x01\202            286,PRIV
 LGS       reg16,mem           \320\301\2\x0F\xB5\110        386
 LGS       reg32,mem           \321\301\2\x0F\xB5\110        386
 LIDT      mem                 \300\2\x0F\x01\203            286,PRIV
-LLDT      mem                 \300\1\x0F\17\202             286,PRIV
-LLDT      mem16               \300\1\x0F\17\202             286,PRIV
-LLDT      reg16               \300\1\x0F\17\202             286,PRIV
+LLDT      mem                 \300\1\x0F\17\202             286,PROT,PRIV
+LLDT      mem16               \300\1\x0F\17\202             286,PROT,PRIV
+LLDT      reg16               \300\1\x0F\17\202             286,PROT,PRIV
 LMSW      mem                 \300\2\x0F\x01\206            286,PRIV
 LMSW      mem16               \300\2\x0F\x01\206            286,PRIV
 LMSW      reg16               \300\2\x0F\x01\206            286,PRIV
@@ -512,15 +510,15 @@ LOOPNZ    imm,reg_ecx         \311\1\xE0\50                 386
 LOOPZ     imm                 \312\1\xE1\50                 8086
 LOOPZ     imm,reg_cx          \310\1\xE1\50                 8086
 LOOPZ     imm,reg_ecx         \311\1\xE1\50                 386
-LSL       reg16,mem           \320\301\2\x0F\x03\110        286,PRIV,SM
-LSL       reg16,reg16         \320\301\2\x0F\x03\110        286,PRIV
-LSL       reg32,mem           \321\301\2\x0F\x03\110        286,PRIV,SM
-LSL       reg32,reg32         \321\301\2\x0F\x03\110        286,PRIV
+LSL       reg16,mem           \320\301\2\x0F\x03\110        286,PROT,SM
+LSL       reg16,reg16         \320\301\2\x0F\x03\110        286,PROT
+LSL       reg32,mem           \321\301\2\x0F\x03\110        286,PROT,SM
+LSL       reg32,reg32         \321\301\2\x0F\x03\110        286,PROT
 LSS       reg16,mem           \320\301\2\x0F\xB2\110        386
 LSS       reg32,mem           \321\301\2\x0F\xB2\110        386
-LTR       mem                 \300\1\x0F\17\203             286,PRIV
-LTR       mem16               \300\1\x0F\17\203             286,PRIV
-LTR       reg16               \300\1\x0F\17\203             286,PRIV
+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
@@ -542,14 +540,14 @@ MOV       reg_eax,mem_offs    \301\321\1\xA1\35             386,SM
 MOV       mem_offs,reg_al     \300\1\xA2\34                 8086,SM
 MOV       mem_offs,reg_ax     \300\320\1\xA3\34             8086,SM
 MOV       mem_offs,reg_eax    \300\321\1\xA3\34             386,SM
-MOV       reg32,reg_cr4       \2\x0F\x20\204                PENT
-MOV       reg32,reg_creg      \2\x0F\x20\101                386
-MOV       reg32,reg_dreg      \2\x0F\x21\101                386
-MOV       reg32,reg_treg      \2\x0F\x24\101                386
-MOV       reg_cr4,reg32       \2\x0F\x22\214                PENT
-MOV       reg_creg,reg32      \2\x0F\x22\110                386
-MOV       reg_dreg,reg32      \2\x0F\x23\110                386
-MOV       reg_treg,reg32      \2\x0F\x26\110                386
+MOV       reg32,reg_cr4       \2\x0F\x20\204                PENT,PRIV
+MOV       reg32,reg_creg      \2\x0F\x20\101                386,PRIV
+MOV       reg32,reg_dreg      \2\x0F\x21\101                386,PRIV
+MOV       reg32,reg_treg      \2\x0F\x24\101                386,PRIV
+MOV       reg_cr4,reg32       \2\x0F\x22\214                PENT,PRIV
+MOV       reg_creg,reg32      \2\x0F\x22\110                386,PRIV
+MOV       reg_dreg,reg32      \2\x0F\x23\110                386,PRIV
+MOV       reg_treg,reg32      \2\x0F\x26\110                386,PRIV
 MOV       mem,reg8            \300\1\x88\101                8086,SM
 MOV       reg8,reg8           \300\1\x88\101                8086
 MOV       mem,reg16           \320\300\1\x89\101            8086,SM
@@ -660,8 +658,8 @@ PANDN     mmxreg,mem          \301\2\x0F\xDF\110            PENT,MMX,SM
 PANDN     mmxreg,mmxreg       \2\x0F\xDF\110                PENT,MMX
 PAVEB     mmxreg,mem          \301\2\x0F\x50\110            PENT,MMX,SM,CYRIX
 PAVEB     mmxreg,mmxreg       \2\x0F\x50\110                PENT,MMX,CYRIX
-PAVGUSB   mmxreg,mem          \301\2\x0F\x0F\110\01\xBF     PENT,MMX,SM,FPU
-PAVGUSB   mmxreg,mmxreg       \2\x0F\x0F\110\01\xBF         PENT,MMX,FPU
+PAVGUSB   mmxreg,mem          \301\2\x0F\x0F\110\01\xBF     PENT,3DNOW,SM
+PAVGUSB   mmxreg,mmxreg       \2\x0F\x0F\110\01\xBF         PENT,3DNOW
 PCMPEQB   mmxreg,mem          \301\2\x0F\x74\110            PENT,MMX,SM
 PCMPEQB   mmxreg,mmxreg       \2\x0F\x74\110                PENT,MMX
 PCMPEQD   mmxreg,mem          \301\2\x0F\x76\110            PENT,MMX,SM
@@ -675,40 +673,40 @@ PCMPGTD   mmxreg,mmxreg       \2\x0F\x66\110                PENT,MMX
 PCMPGTW   mmxreg,mem          \301\2\x0F\x65\110            PENT,MMX,SM
 PCMPGTW   mmxreg,mmxreg       \2\x0F\x65\110                PENT,MMX
 PDISTIB   mmxreg,mem          \301\2\x0F\x54\110            PENT,MMX,SM,CYRIX
-PF2ID     mmxreg,mem          \301\2\x0F\x0F\110\01\x1D     PENT,MMX,SM,FPU
-PF2ID     mmxreg,mmxreg       \2\x0F\x0F\110\01\x1D         PENT,MMX,FPU
-PFACC     mmxreg,mem          \301\2\x0F\x0F\110\01\xAE     PENT,MMX,SM,FPU
-PFACC     mmxreg,mmxreg       \2\x0F\x0F\110\01\xAE         PENT,MMX,FPU
-PFADD     mmxreg,mem          \301\2\x0F\x0F\110\01\x9E     PENT,MMX,SM,FPU
-PFADD     mmxreg,mmxreg       \2\x0F\x0F\110\01\x9E         PENT,MMX,FPU
-PFCMPEQ   mmxreg,mem          \301\2\x0F\x0F\110\01\xB0     PENT,MMX,SM,FPU
-PFCMPEQ   mmxreg,mmxreg       \2\x0F\x0F\110\01\xB0         PENT,MMX,FPU
-PFCMPGE   mmxreg,mem          \301\2\x0F\x0F\110\01\x90     PENT,MMX,SM,FPU
-PFCMPGE   mmxreg,mmxreg       \2\x0F\x0F\110\01\x90         PENT,MMX,FPU
-PFCMPGT   mmxreg,mem          \301\2\x0F\x0F\110\01\xA0     PENT,MMX,SM,FPU
-PFCMPGT   mmxreg,mmxreg       \2\x0F\x0F\110\01\xA0         PENT,MMX,FPU
-PFMAX     mmxreg,mem          \301\2\x0F\x0F\110\01\xA4     PENT,MMX,SM,FPU
-PFMAX     mmxreg,mmxreg       \2\x0F\x0F\110\01\xA4         PENT,MMX,FPU
-PFMIN     mmxreg,mem          \301\2\x0F\x0F\110\01\x94     PENT,MMX,SM,FPU
-PFMIN     mmxreg,mmxreg       \2\x0F\x0F\110\01\x94         PENT,MMX,FPU
-PFMUL     mmxreg,mem          \301\2\x0F\x0F\110\01\xB4     PENT,MMX,SM,FPU
-PFMUL     mmxreg,mmxreg       \2\x0F\x0F\110\01\xB4         PENT,MMX,FPU
-PFRCP     mmxreg,mem          \301\2\x0F\x0F\110\01\x96     PENT,MMX,SM,FPU
-PFRCP     mmxreg,mmxreg       \2\x0F\x0F\110\01\x96         PENT,MMX,FPU
-PFRCPIT1  mmxreg,mem          \301\2\x0F\x0F\110\01\xA6     PENT,MMX,SM,FPU
-PFRCPIT1  mmxreg,mmxreg       \2\x0F\x0F\110\01\xA6         PENT,MMX,FPU
-PFRCPIT2  mmxreg,mem          \301\2\x0F\x0F\110\01\xB6     PENT,MMX,SM,FPU
-PFRCPIT2  mmxreg,mmxreg       \2\x0F\x0F\110\01\xB6         PENT,MMX,FPU
-PFRSQIT1  mmxreg,mem          \301\2\x0F\x0F\110\01\xA7     PENT,MMX,SM,FPU
-PFRSQIT1  mmxreg,mmxreg       \2\x0F\x0F\110\01\xA7         PENT,MMX,FPU
-PFRSQRT   mmxreg,mem          \301\2\x0F\x0F\110\01\x97     PENT,MMX,SM,FPU
-PFRSQRT   mmxreg,mmxreg       \2\x0F\x0F\110\01\x97         PENT,MMX,FPU
-PFSUB     mmxreg,mem          \301\2\x0F\x0F\110\01\x9A     PENT,MMX,SM,FPU
-PFSUB     mmxreg,mmxreg       \2\x0F\x0F\110\01\x9A         PENT,MMX,FPU
-PFSUBR    mmxreg,mem          \301\2\x0F\x0F\110\01\xAA     PENT,MMX,SM,FPU
-PFSUBR    mmxreg,mmxreg       \2\x0F\x0F\110\01\xAA         PENT,MMX,FPU
-PI2FD     mmxreg,mem          \301\2\x0F\x0F\110\01\x0D     PENT,MMX,SM,FPU
-PI2FD     mmxreg,mmxreg       \2\x0F\x0F\110\01\x0D         PENT,MMX,FPU
+PF2ID     mmxreg,mem          \301\2\x0F\x0F\110\01\x1D     PENT,3DNOW,SM
+PF2ID     mmxreg,mmxreg       \2\x0F\x0F\110\01\x1D         PENT,3DNOW
+PFACC     mmxreg,mem          \301\2\x0F\x0F\110\01\xAE     PENT,3DNOW,SM
+PFACC     mmxreg,mmxreg       \2\x0F\x0F\110\01\xAE         PENT,3DNOW
+PFADD     mmxreg,mem          \301\2\x0F\x0F\110\01\x9E     PENT,3DNOW,SM
+PFADD     mmxreg,mmxreg       \2\x0F\x0F\110\01\x9E         PENT,3DNOW
+PFCMPEQ   mmxreg,mem          \301\2\x0F\x0F\110\01\xB0     PENT,3DNOW,SM
+PFCMPEQ   mmxreg,mmxreg       \2\x0F\x0F\110\01\xB0         PENT,3DNOW
+PFCMPGE   mmxreg,mem          \301\2\x0F\x0F\110\01\x90     PENT,3DNOW,SM
+PFCMPGE   mmxreg,mmxreg       \2\x0F\x0F\110\01\x90         PENT,3DNOW
+PFCMPGT   mmxreg,mem          \301\2\x0F\x0F\110\01\xA0     PENT,3DNOW,SM
+PFCMPGT   mmxreg,mmxreg       \2\x0F\x0F\110\01\xA0         PENT,3DNOW
+PFMAX     mmxreg,mem          \301\2\x0F\x0F\110\01\xA4     PENT,3DNOW,SM
+PFMAX     mmxreg,mmxreg       \2\x0F\x0F\110\01\xA4         PENT,3DNOW
+PFMIN     mmxreg,mem          \301\2\x0F\x0F\110\01\x94     PENT,3DNOW,SM
+PFMIN     mmxreg,mmxreg       \2\x0F\x0F\110\01\x94         PENT,3DNOW
+PFMUL     mmxreg,mem          \301\2\x0F\x0F\110\01\xB4     PENT,3DNOW,SM
+PFMUL     mmxreg,mmxreg       \2\x0F\x0F\110\01\xB4         PENT,3DNOW
+PFRCP     mmxreg,mem          \301\2\x0F\x0F\110\01\x96     PENT,3DNOW,SM
+PFRCP     mmxreg,mmxreg       \2\x0F\x0F\110\01\x96         PENT,3DNOW
+PFRCPIT1  mmxreg,mem          \301\2\x0F\x0F\110\01\xA6     PENT,3DNOW,SM
+PFRCPIT1  mmxreg,mmxreg       \2\x0F\x0F\110\01\xA6         PENT,3DNOW
+PFRCPIT2  mmxreg,mem          \301\2\x0F\x0F\110\01\xB6     PENT,3DNOW,SM
+PFRCPIT2  mmxreg,mmxreg       \2\x0F\x0F\110\01\xB6         PENT,3DNOW
+PFRSQIT1  mmxreg,mem          \301\2\x0F\x0F\110\01\xA7     PENT,3DNOW,SM
+PFRSQIT1  mmxreg,mmxreg       \2\x0F\x0F\110\01\xA7         PENT,3DNOW
+PFRSQRT   mmxreg,mem          \301\2\x0F\x0F\110\01\x97     PENT,3DNOW,SM
+PFRSQRT   mmxreg,mmxreg       \2\x0F\x0F\110\01\x97         PENT,3DNOW
+PFSUB     mmxreg,mem          \301\2\x0F\x0F\110\01\x9A     PENT,3DNOW,SM
+PFSUB     mmxreg,mmxreg       \2\x0F\x0F\110\01\x9A         PENT,3DNOW
+PFSUBR    mmxreg,mem          \301\2\x0F\x0F\110\01\xAA     PENT,3DNOW,SM
+PFSUBR    mmxreg,mmxreg       \2\x0F\x0F\110\01\xAA         PENT,3DNOW
+PI2FD     mmxreg,mem          \301\2\x0F\x0F\110\01\x0D     PENT,3DNOW,SM
+PI2FD     mmxreg,mmxreg       \2\x0F\x0F\110\01\x0D         PENT,3DNOW
 PMACHRIW  mmxreg,mem          \301\2\x0F\x5E\110            PENT,MMX,SM,CYRIX
 PMADDWD   mmxreg,mem          \301\2\x0F\xF5\110            PENT,MMX,SM
 PMADDWD   mmxreg,mmxreg       \2\x0F\xF5\110                PENT,MMX
@@ -716,8 +714,8 @@ PMAGW     mmxreg,mem          \301\2\x0F\x52\110            PENT,MMX,SM,CYRIX
 PMAGW     mmxreg,mmxreg       \2\x0F\x52\110                PENT,MMX,CYRIX
 PMULHRIW  mmxreg,mem          \301\2\x0F\x5D\110            PENT,MMX,SM,CYRIX
 PMULHRIW  mmxreg,mmxreg       \2\x0F\x5D\110                PENT,MMX,CYRIX
-PMULHRWA  mmxreg,mem          \301\2\x0F\x0F\110\1\xB7      PENT,MMX,SM,FPU
-PMULHRWA  mmxreg,mmxreg       \2\x0F\x0F\110\1\xB7          PENT,MMX,FPU
+PMULHRWA  mmxreg,mem          \301\2\x0F\x0F\110\1\xB7      PENT,3DNOW,SM
+PMULHRWA  mmxreg,mmxreg       \2\x0F\x0F\110\1\xB7          PENT,3DNOW
 PMULHRWC  mmxreg,mem          \301\2\x0F\x59\110            PENT,MMX,SM,CYRIX
 PMULHRWC  mmxreg,mmxreg       \2\x0F\x59\110                PENT,MMX,CYRIX
 PMULHW    mmxreg,mem          \301\2\x0F\xE5\110            PENT,MMX,SM
@@ -743,8 +741,8 @@ POPFD     void                \321\1\x9D                    386
 POPFW     void                \320\1\x9D                    186
 POR       mmxreg,mem          \301\2\x0F\xEB\110            PENT,MMX,SM
 POR       mmxreg,mmxreg       \2\x0F\xEB\110                PENT,MMX
-PREFETCH  mem                 \2\x0F\x0D\200                PENT,MMX,SM,FPU
-PREFETCHW mem                 \2\x0F\x0D\201                PENT,MMX,SM,FPU
+PREFETCH  mem                 \2\x0F\x0D\200                PENT,3DNOW,SM
+PREFETCHW mem                 \2\x0F\x0D\201                PENT,3DNOW,SM
 PSLLD     mmxreg,mem          \301\2\x0F\xF2\110            PENT,MMX,SM
 PSLLD     mmxreg,mmxreg       \2\x0F\xF2\110                PENT,MMX
 PSLLD     mmxreg,imm          \2\x0F\x72\206\25             PENT,MMX
@@ -832,7 +830,8 @@ RCR       rm16,imm            \320\300\1\xC1\203\25         186,SB
 RCR       rm32,unity          \321\300\1\xD1\203            386
 RCR       rm32,reg_cl         \321\300\1\xD3\203            386
 RCR       rm32,imm            \321\300\1\xC1\203\25         386,SB
-RDMSR     void                \2\x0F\x32                    PENT
+RDSHR     void                \2\x0F\x36                    P6,CYRIX,SMM
+RDMSR     void                \2\x0F\x32                    PENT,PRIV
 RDPMC     void                \2\x0F\x33                    P6
 RDTSC     void                \2\x0F\x31                    PENT
 RESB      imm                 \340                          8086
@@ -864,7 +863,9 @@ 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
-RSM       void                \2\x0F\xAA                    PENT
+RSDC      reg_sreg,mem80      \2\x0F\x79\101               486,CYRIX,SMM
+RSLDT     mem80               \2\x0F\x7B\200               486,CYRIX,SMM
+RSM       void                \2\x0F\xAA                    PENT,SMM
 SAHF      void                \1\x9E                        8086
 SAL       rm8,unity           \300\1\xD0\204                8086,ND
 SAL       rm8,reg_cl          \300\1\xD2\204                8086,ND
@@ -911,7 +912,7 @@ SBB       mem,imm32           \321\300\1\x81\203\41         386,SM
 SCASB     void                \1\xAE                        8086
 SCASD     void                \321\1\xAF                    386
 SCASW     void                \320\1\xAF                    8086
-SGDT      mem                 \300\2\x0F\x01\200            286,PRIV
+SGDT      mem                 \300\2\x0F\x01\200            286
 SHL       rm8,unity           \300\1\xD0\204                8086
 SHL       rm8,reg_cl          \300\1\xD2\204                8086
 SHL       rm8,imm             \300\1\xC0\204\25             186,SB
@@ -946,23 +947,26 @@ SHRD      mem,reg16,reg_cl    \300\320\2\x0F\xAD\101        386,SM
 SHRD      reg16,reg16,reg_cl  \300\320\2\x0F\xAD\101        386
 SHRD      mem,reg32,reg_cl    \300\321\2\x0F\xAD\101        386,SM
 SHRD      reg32,reg32,reg_cl  \300\321\2\x0F\xAD\101        386
-SIDT      mem                 \300\2\x0F\x01\201            286,PRIV
-SLDT      mem                 \300\1\x0F\17\200             286,PRIV
-SLDT      mem16               \300\1\x0F\17\200             286,PRIV
-SLDT      reg16               \300\1\x0F\17\200             286,PRIV
+SIDT      mem                 \300\2\x0F\x01\201            286
+SLDT      mem                 \300\1\x0F\17\200             286
+SLDT      mem16               \300\1\x0F\17\200             286
+SLDT      reg16               \300\1\x0F\17\200             286
 SMI       void                \1\xF1                        386,UNDOC
-SMSW      mem                 \300\2\x0F\x01\204            286,PRIV
-SMSW      mem16               \300\2\x0F\x01\204            286,PRIV
-SMSW      reg16               \300\2\x0F\x01\204            286,PRIV
+SMINT     void                \2\x0F\x38                    P6,CYRIX
+; Older Cyrix chips had this; they had to move due to conflict with MMX
+SMINTOLD  void                \2\x0F\x7E                    486,CYRIX
+SMSW      mem                 \300\2\x0F\x01\204            286
+SMSW      mem16               \300\2\x0F\x01\204            286
+SMSW      reg16               \300\2\x0F\x01\204            286
 STC       void                \1\xF9                        8086
 STD       void                \1\xFD                        8086
 STI       void                \1\xFB                        8086
 STOSB     void                \1\xAA                        8086
 STOSD     void                \321\1\xAB                    386
 STOSW     void                \320\1\xAB                    8086
-STR       mem                 \300\1\x0F\17\201             286,PRIV
-STR       mem16               \300\1\x0F\17\201             286,PRIV
-STR       reg16               \300\1\x0F\17\201             286,PRIV
+STR       mem                 \300\1\x0F\17\201             286,PROT
+STR       mem16               \300\1\x0F\17\201             286,PROT
+STR       reg16               \300\1\x0F\17\201             286,PROT
 SUB       mem,reg8            \300\1\x28\101                8086,SM
 SUB       reg8,reg8           \300\1\x28\101                8086
 SUB       mem,reg16           \320\300\1\x29\101            8086,SM
@@ -986,8 +990,13 @@ SUB       rm32,imm            \321\300\1\x81\205\41         386,SM
 SUB       mem,imm8            \300\1\x80\205\21             8086,SM
 SUB       mem,imm16           \320\300\1\x81\205\31         8086,SM
 SUB       mem,imm32           \321\300\1\x81\205\41         386,SM
+SVDC     mem80,reg_sreg      \2\x0F\x78\101                486,CYRIX,SMM
+SVLDT     mem80               \2\x0F\x7A\200                486,CYRIX,SMM
+SVTS      mem80               \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
 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
@@ -1020,15 +1029,16 @@ UMOV      reg16,mem           \320\301\2\x0F\x13\110        386,UNDOC,SM
 UMOV      reg16,reg16         \320\301\2\x0F\x13\110        386,UNDOC
 UMOV      reg32,mem           \321\301\2\x0F\x13\110        386,UNDOC,SM
 UMOV      reg32,reg32         \321\301\2\x0F\x13\110        386,UNDOC
-VERR      mem                 \300\1\x0F\17\204             286,PRIV
-VERR      mem16               \300\1\x0F\17\204             286,PRIV
-VERR      reg16               \300\1\x0F\17\204             286,PRIV
-VERW      mem                 \300\1\x0F\17\205             286,PRIV
-VERW      mem16               \300\1\x0F\17\205             286,PRIV
-VERW      reg16               \300\1\x0F\17\205             286,PRIV
+VERR      mem                 \300\1\x0F\17\204             286,PROT
+VERR      mem16               \300\1\x0F\17\204             286,PROT
+VERR      reg16               \300\1\x0F\17\204             286,PROT
+VERW      mem                 \300\1\x0F\17\205             286,PROT
+VERW      mem16               \300\1\x0F\17\205             286,PROT
+VERW      reg16               \300\1\x0F\17\205             286,PROT
 WAIT      void                \1\x9B                        8086
-WBINVD    void                \2\x0F\x09                    486
-WRMSR     void                \2\x0F\x30                    PENT
+WBINVD    void                \2\x0F\x09                    486,PRIV
+WRSHR     void                \2\x0F\x37                    P6,CYRIX,SMM
+WRMSR     void                \2\x0F\x30                    PENT,PRIV
 XADD      mem,reg8            \300\2\x0F\xC0\101            486,SM
 XADD      reg8,reg8           \300\2\x0F\xC0\101            486
 XADD      mem,reg16           \320\300\2\x0F\xC1\101        486,SM
@@ -1088,3 +1098,196 @@ Jcc       imm                 \330\x70\50                   8086
 Jcc       imm|short           \330\x70\50                   8086
 SETcc     mem                 \300\1\x0F\330\x90\200        386,SB
 SETcc     reg8                \300\1\x0F\330\x90\200        386
+
+; Katmai Streaming SIMD instructions (SSE -- a.k.a. KNI, XMM, MMX2)
+ADDPS           xmmreg,xmmreg           \2\x0F\x58\110                  KATMAI,SSE
+ADDPS           xmmreg,mem              \301\2\x0F\x58\110              KATMAI,SSE
+ADDSS           xmmreg,xmmreg           \3\xF3\x0F\x58\110              KATMAI,SSE
+ADDSS           xmmreg,mem              \301\3\xF3\x0F\x58\110          KATMAI,SSE
+
+MULPS           xmmreg,xmmreg           \2\x0F\x59\110                  KATMAI,SSE
+MULPS           xmmreg,mem              \301\2\x0F\x59\110              KATMAI,SSE
+MULSS           xmmreg,xmmreg           \3\xF3\x0F\x59\110              KATMAI,SSE
+MULSS           xmmreg,mem              \301\3\xF3\x0F\x59\110          KATMAI,SSE
+
+DIVPS           xmmreg,xmmreg           \2\x0F\x5E\110                  KATMAI,SSE
+DIVPS           xmmreg,mem              \301\2\x0F\x5E\110              KATMAI,SSE
+DIVSS           xmmreg,xmmreg           \3\xF3\x0F\x5E\110              KATMAI,SSE
+DIVSS           xmmreg,mem              \301\3\xF3\x0F\x5E\110          KATMAI,SSE
+
+SUBPS           xmmreg,xmmreg           \2\x0F\x5C\110                  KATMAI,SSE
+SUBPS           xmmreg,mem              \301\2\x0F\x5C\110              KATMAI,SSE
+SUBSS           xmmreg,xmmreg           \3\xF3\x0F\x5C\110              KATMAI,SSE
+SUBSS           xmmreg,mem              \301\3\xF3\x0F\x5C\110          KATMAI,SSE
+
+RCPPS           xmmreg,xmmreg           \2\x0F\x53\110                  KATMAI,SSE
+RCPPS           xmmreg,mem              \301\2\x0F\x53\110              KATMAI,SSE
+RCPSS           xmmreg,xmmreg           \3\xF3\x0F\x53\110              KATMAI,SSE
+RCPSS           xmmreg,mem              \301\3\xF3\x0F\x53\110          KATMAI,SSE
+
+RSQRTPS         xmmreg,xmmreg           \2\x0F\x52\110                  KATMAI,SSE
+RSQRTPS         xmmreg,mem              \301\2\x0F\x52\110              KATMAI,SSE
+RSQRTSS         xmmreg,xmmreg           \3\xF3\x0F\x52\110              KATMAI,SSE
+RSQRTSS         xmmreg,mem              \301\3\xF3\x0F\x52\110          KATMAI,SSE
+
+SQRTPS          xmmreg,xmmreg           \2\x0F\x51\110                  KATMAI,SSE
+SQRTPS          xmmreg,mem              \301\2\x0F\x51\110              KATMAI,SSE
+SQRTSS          xmmreg,xmmreg           \3\xF3\x0F\x51\110              KATMAI,SSE
+SQRTSS          xmmreg,mem              \301\3\xF3\x0F\x51\110          KATMAI,SSE
+
+ANDPS           xmmreg,xmmreg           \2\x0F\x54\110                  KATMAI,SSE
+ANDPS           xmmreg,mem              \301\2\x0F\x54\110              KATMAI,SSE
+ANDNPS          xmmreg,xmmreg           \2\x0F\x55\110                  KATMAI,SSE
+ANDNPS          xmmreg,mem              \301\2\x0F\x55\110              KATMAI,SSE
+ORPS            xmmreg,xmmreg           \2\x0F\x56\110                  KATMAI,SSE
+ORPS            xmmreg,mem              \301\2\x0F\x56\110              KATMAI,SSE
+XORPS           xmmreg,xmmreg           \2\x0F\x57\110                  KATMAI,SSE
+XORPS           xmmreg,mem              \301\2\x0F\x57\110              KATMAI,SSE
+
+MAXPS           xmmreg,xmmreg           \2\x0F\x5F\110                  KATMAI,SSE
+MAXPS           xmmreg,mem              \301\2\x0F\x5F\110              KATMAI,SSE
+MAXSS           xmmreg,xmmreg           \3\xF3\x0F\x5F\110              KATMAI,SSE
+MAXSS           xmmreg,mem              \301\3\xF3\x0F\x5F\110          KATMAI,SSE
+MINPS           xmmreg,xmmreg           \2\x0F\x5D\110                  KATMAI,SSE
+MINPS           xmmreg,mem              \301\2\x0F\x5D\110              KATMAI,SSE
+MINSS           xmmreg,xmmreg           \3\xF3\x0F\x5D\110              KATMAI,SSE
+MINSS           xmmreg,mem              \301\3\xF3\x0F\x5D\110          KATMAI,SSE
+
+CMPEQPS         xmmreg,xmmreg           \2\x0F\xC2\110\1\x00            KATMAI,SSE
+CMPEQPS         xmmreg,mem              \301\2\x0F\xC2\110\1\x00        KATMAI,SSE
+CMPEQSS         xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x00        KATMAI,SSE
+CMPEQSS         xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\0x00   KATMAI,SSE
+
+CMPLTPS         xmmreg,xmmreg           \2\x0F\xC2\110\1\x01            KATMAI,SSE
+CMPLTPS         xmmreg,mem              \301\2\x0F\xC2\110\1\x01        KATMAI,SSE
+CMPLTSS         xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x01        KATMAI,SSE
+CMPLTSS         xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x01    KATMAI,SSE
+
+CMPLEPS         xmmreg,xmmreg           \2\x0F\xC2\110\1\x02            KATMAI,SSE
+CMPLEPS         xmmreg,mem              \301\2\x0F\xC2\110\1\x02        KATMAI,SSE
+CMPLESS         xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x02        KATMAI,SSE
+CMPLESS         xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x02    KATMAI,SSE
+
+CMPUNORDPS      xmmreg,xmmreg           \2\x0F\xC2\110\1\x03            KATMAI,SSE
+CMPUNORDPS      xmmreg,mem              \301\2\x0F\xC2\110\1\x03        KATMAI,SSE
+CMPUNORDSS      xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x03        KATMAI,SSE
+CMPUNORDSS      xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x03    KATMAI,SSE
+
+CMPNEQPS        xmmreg,xmmreg           \2\x0F\xC2\110\1\x04            KATMAI,SSE
+CMPNEQPS        xmmreg,mem              \301\2\x0F\xC2\110\1\x04        KATMAI,SSE
+CMPNEQSS        xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x04        KATMAI,SSE
+CMPNEQSS        xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x04    KATMAI,SSE
+
+CMPNLTPS        xmmreg,xmmreg           \2\x0F\xC2\110\1\x05            KATMAI,SSE
+CMPNLTPS        xmmreg,mem              \301\2\x0F\xC2\110\1\x05        KATMAI,SSE
+CMPNLTSS        xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x05        KATMAI,SSE
+CMPNLTSS        xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x05    KATMAI,SSE
+
+CMPNLEPS        xmmreg,xmmreg           \2\x0F\xC2\110\1\x06            KATMAI,SSE
+CMPNLEPS        xmmreg,mem              \301\2\x0F\xC2\110\1\x06        KATMAI,SSE
+CMPNLESS        xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x06        KATMAI,SSE
+CMPNLESS        xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x06    KATMAI,SSE
+
+CMPORDPS        xmmreg,xmmreg           \2\x0F\xC2\110\1\x07            KATMAI,SSE
+CMPORDPS        xmmreg,mem              \301\2\x0F\xC2\110\1\x07        KATMAI,SSE
+CMPORDSS        xmmreg,xmmreg           \3\xF3\x0F\xC2\110\1\x07        KATMAI,SSE
+CMPORDSS        xmmreg,mem              \301\3\xF3\x0F\xC2\110\1\x07    KATMAI,SSE
+
+UCOMISS         xmmreg,xmmreg           \2\x0F\x2E\110                  KATMAI,SSE
+UCOMISS         xmmreg,mem              \301\2\x0F\x2E\110              KATMAI,SSE
+COMISS          xmmreg,xmmreg           \2\x0F\x2F\110                  KATMAI,SSE
+COMISS          xmmreg,mem              \301\2\x0F\x2F\110              KATMAI,SSE
+
+CVTPI2PS        xmmreg,mmxreg           \2\x0F\x2A\110                  KATMAI,SSE,MMX
+CVTPI2PS        xmmreg,mem              \301\2\x0F\x2A\110              KATMAI,SSE,MMX
+CVTPS2PI        mmxreg,xmmreg           \2\x0F\x2D\110                  KATMAI,SSE,MMX
+CVTPS2PI        mmxreg,mem              \301\2\x0F\x2D\110              KATMAI,SSE,MMX
+CVTTPS2PI       mmxreg,xmmreg           \2\x0F\x2C\110                  KATMAI,SSE,MMX
+CVTTPS2PI       mmxreg,mem              \301\2\x0F\x2C\110              KATMAI,SSE,MMX
+
+CVTSI2SS        xmmreg,reg32            \3\xF3\x0F\x2A\110              KATMAI,SSE
+CVTSI2SS        xmmreg,mem              \301\3\xF3\x0F\x2A\110          KATMAI,SSE
+CVTSS2SI        reg32,xmmreg            \3\xF3\x0F\x2D\110              KATMAI,SSE
+CVTSS2SI        reg32,mem               \301\3\xF3\x0F\x2D\110          KATMAI,SSE
+CVTTSS2SI       reg32,xmmreg            \3\xF3\x0F\x2C\110              KATMAI,SSE
+CVTTSS2SI       reg32,mem               \301\xF3\3\x0F\x2C\110          KATMAI,SSE
+
+; FXSAVE/FXRSTOR were introduced in Deschutes
+FXSAVE          mem                     \300\2\x0F\xAE\200              P6,SSE,FPU
+FXRSTOR         mem                     \300\2\x0F\xAE\201              P6,SSE,FPU
+LDMXCSR         mem                     \300\2\x0F\xAE\202              KATMAI,SSE
+STMXCSR         mem                     \300\2\x0F\xAE\203              KATMAI,SSE
+
+; These instructions aren't SSE-specific; they are generic memory operations
+; and work even if CR4.OSFXFR == 0
+SFENCE          void                    \3\x0F\xAE\xF8                  KATMAI
+
+PREFETCHNTA     mem                     \300\2\x0F\x18\200              KATMAI,SM
+PREFETCHT0      mem                     \300\2\x0F\x18\201              KATMAI,SM
+PREFETCHT1      mem                     \300\2\x0F\x18\202              KATMAI,SM
+PREFETCHT2      mem                     \300\2\x0F\x18\203              KATMAI,SM
+
+MOVAPS          xmmreg,xmmreg           \2\x0F\x28\110                  KATMAI,SSE
+MOVAPS          xmmreg,mem              \301\2\x0F\x28\110              KATMAI,SSE
+MOVAPS          xmmreg,xmmreg           \2\x0F\x29\101                  KATMAI,SSE
+MOVAPS          mem,xmmreg              \300\2\x0F\x29\101              KATMAI,SSE
+
+MOVHPS          xmmreg,xmmreg           \2\x0F\x16\110                  KATMAI,SSE
+MOVHPS          xmmreg,mem              \301\2\x0F\x16\110              KATMAI,SSE
+MOVHPS          xmmreg,xmmreg           \2\x0F\x17\101                  KATMAI,SSE
+MOVHPS          mem,xmmreg              \300\2\x0F\x17\101              KATMAI,SSE
+
+MOVLPS          xmmreg,xmmreg           \2\x0F\x12\110                  KATMAI,SSE
+MOVLPS          xmmreg,mem              \301\2\x0F\x12\110              KATMAI,SSE
+MOVLPS          xmmreg,xmmreg           \2\x0F\x13\101                  KATMAI,SSE
+MOVLPS          mem,xmmreg              \300\2\x0F\x13\101              KATMAI,SSE
+
+MOVUPS          xmmreg,xmmreg           \2\x0F\x10\110                  KATMAI,SSE
+MOVUPS          xmmreg,mem              \301\2\x0F\x10\110              KATMAI,SSE
+MOVUPS          xmmreg,xmmreg           \2\x0F\x11\101                  KATMAI,SSE
+MOVUPS          mem,xmmreg              \300\2\x0F\x11\101              KATMAI,SSE
+
+MOVSS           xmmreg,xmmreg           \3\xF3\x0F\x10\110              KATMAI,SSE
+MOVSS           xmmreg,mem              \301\3\xF3\x0F\x10\110          KATMAI,SSE
+MOVSS           xmmreg,xmmreg           \3\xF3\x0F\x11\101              KATMAI,SSE
+MOVSS           mem,xmmreg              \300\3\xF3\x0F\x11\101          KATMAI,SSE
+
+MOVMSKPS        reg32,xmmreg            \2\x0F\x50\110                  KATMAI,SSE
+
+MOVNTPS         mem,xmmreg              \2\x0F\x2B\101                  KATMAI,SSE
+
+SHUFPS          xmmreg,xmmreg,imm8      \2\x0F\xC6\110\22               KATMAI,SSE
+SHUFPS         xmmreg,mem,imm8         \301\2\x0F\xC6\110\22           KATMAI,SSE
+
+UNPCKHPS        xmmreg,xmmreg           \2\x0F\x15\110                  KATMAI,SSE
+UNPCKHPS        xmmreg,mem              \301\2\x0F\x15\110              KATMAI,SSE
+UNPCKLPS        xmmreg,xmmreg           \2\x0F\x14\110                  KATMAI,SSE
+UNPCKLPS        xmmreg,mem              \301\2\x0F\x14\110              KATMAI,SSE
+
+; New MMX instructions introduced in Katmai
+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,imm8      \2\x0F\xC5\110\22               KATMAI,MMX
+; This is documented as using a reg32, but it's really using only 16 bits -- accept either
+PINSRW          mmxreg,reg16,imm8      \2\x0F\xC4\110\22               KATMAI,MMX
+PINSRW          mmxreg,reg32,imm8      \2\x0F\xC4\110\22               KATMAI,MMX
+PINSRW          mmxreg,mem16,imm8      \301\2\x0F\xC4\110\22           KATMAI,MMX,SM
+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,imm8     \2\x0F\x70\110\22               KATMAI,MMX
+PSHUFW          mmxreg,mem,imm8                \301\2\x0F\x70\110\22           KATMAI,MMX,SM
+MASKMOVQ        mmxreg,mmxreg          \2\x0F\xF7\110                  KATMAI,MMX
diff --git a/insns.h b/insns.h
index 1b637fc..f12ea60 100644 (file)
--- a/insns.h
+++ b/insns.h
@@ -14,7 +14,7 @@ struct itemplate {
     int operands;                     /* number of operands */
     long opd[3];                      /* bit flags for operand types */
     char *code;                               /* the code it assembles to */
-    int flags;                        /* some flags */
+    unsigned long flags;              /* some flags */
 };
 
 /*
@@ -44,23 +44,30 @@ struct itemplate {
  * required to have unspecified size in the instruction too...)
  */
 
-#define IF_SM     0x0001              /* size match */
-#define IF_SM2    0x0002              /* size match first two operands */
-#define IF_SB     0x0004              /* unsized operands can't be non-byte */
-#define IF_SW     0x0008              /* unsized operands can't be non-word */
-#define IF_SD     0x0010              /* unsized operands can't be nondword */
-#define IF_8086   0x0000              /* 8086 instruction */
-#define IF_186    0x0100              /* 186+ instruction */
-#define IF_286    0x0200              /* 286+ instruction */
-#define IF_386    0x0300              /* 386+ instruction */
-#define IF_486    0x0400              /* 486+ instruction */
-#define IF_PENT   0x0500              /* Pentium instruction */
-#define IF_P6     0x0600              /* P6 instruction */
-#define IF_CYRIX  0x0800              /* Cyrix-specific instruction */
-#define IF_PMASK  0x0F00              /* the mask for processor types */
-#define IF_PRIV   0x1000              /* it's a privileged instruction */
-#define IF_UNDOC  0x2000              /* it's an undocumented instruction */
-#define IF_FPU    0x4000              /* it's an FPU instruction */
-#define IF_MMX    0x8000              /* it's an MMX instruction */
+#define IF_SM     0x00000001UL        /* size match */
+#define IF_SM2    0x00000002UL        /* size match first two operands */
+#define IF_SB     0x00000004UL        /* unsized operands can't be non-byte */
+#define IF_SW     0x00000008UL        /* unsized operands can't be non-word */
+#define IF_SD     0x00000010UL        /* unsized operands can't be nondword */
+#define IF_PRIV   0x00000100UL        /* it's a privileged instruction */
+#define IF_SMM    0x00000200UL        /* it's only valid in SMM */
+#define IF_PROT   0x00000400UL         /* it's protected mode only */
+#define IF_UNDOC  0x00001000UL        /* it's an undocumented instruction */
+#define IF_FPU    0x00002000UL        /* it's an FPU instruction */
+#define IF_MMX    0x00004000UL        /* it's an MMX instruction */
+#define IF_3DNOW  0x00008000UL        /* it's a 3DNow! instruction */
+#define IF_SSE    0x00010000UL        /* it's a SSE (KNI, MMX2) instruction */
+#define IF_PMASK  0xFF000000UL        /* the mask for processor types */
+#define IF_PFMASK 0xF001FF00UL        /* the mask for disassembly "prefer" */
+#define IF_8086   0x00000000UL        /* 8086 instruction */
+#define IF_186    0x01000000UL        /* 186+ instruction */
+#define IF_286    0x02000000UL        /* 286+ instruction */
+#define IF_386    0x03000000UL        /* 386+ instruction */
+#define IF_486    0x04000000UL        /* 486+ instruction */
+#define IF_PENT   0x05000000UL        /* Pentium instruction */
+#define IF_P6     0x06000000UL        /* P6 instruction */
+#define IF_KATMAI 0x07000000UL         /* Katmai instructions */
+#define IF_CYRIX  0x10000000UL        /* Cyrix-specific instruction */
+#define IF_AMD    0x20000000UL        /* AMD-specific instruction */
 
 #endif
diff --git a/names.c b/names.c
index 1a462ec..e220ebf 100644 (file)
--- a/names.c
+++ b/names.c
@@ -14,7 +14,8 @@ static char *reg_names[] = {         /* register names, as strings */
     "ebx", "ecx", "edi", "edx", "es", "esi", "esp", "fs", "gs",
     "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "si",
     "sp", "ss", "st0", "st1", "st2", "st3", "st4", "st5", "st6",
-    "st7", "tr3", "tr4", "tr5", "tr6", "tr7"
+    "st7", "tr3", "tr4", "tr5", "tr6", "tr7",
+    "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
 };
 
 static char *conditions[] = {         /* condition code names */
diff --git a/nasm.h b/nasm.h
index 4076284..73a3fd9 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 pre-release 3.4"
+#define NASM_VER "0.98 pre-release 3.5"
 
 #ifndef NULL
 #define NULL 0
@@ -380,6 +380,7 @@ enum {
 #define REG16     0x00201002L
 #define REG32     0x00201004L
 #define MMXREG    0x00201008L         /* MMX registers */
+#define XMMREG    0x00201010L          /* XMM Katmai reg */
 #define FPUREG    0x01000000L         /* floating point stack registers */
 #define FPU0      0x01000800L         /* FPU stack register zero */
 
@@ -423,7 +424,8 @@ enum {                                     /* register names */
     R_EBP, R_EBX, R_ECX, R_EDI, R_EDX, R_ES, R_ESI, R_ESP, R_FS,
     R_GS, R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
     R_SI, R_SP, R_SS, R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5,
-    R_ST6, R_ST7, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7, REG_ENUM_LIMIT
+    R_ST6, R_ST7, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7,
+    R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, REG_ENUM_LIMIT
 };
 
 /* Instruction names automatically generated from insns.dat */
index a07a278..99e943a 100644 (file)
--- a/ndisasm.c
+++ b/ndisasm.c
@@ -12,6 +12,7 @@
 #include <ctype.h>
 #include <errno.h>
 
+#include "insns.h"
 #include "nasm.h"
 #include "nasmlib.h"
 #include "sync.h"
 
 static const char *help =
 "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n"
-"               [-e bytes] [-k start,bytes] file\n"
+"               [-e bytes] [-k start,bytes] [-p vendor] file\n"
 "   -a or -i activates auto (intelligent) sync\n"
 "   -u sets USE32 (32-bit mode)\n"
 "   -b 16 or -b 32 sets number of bits too\n"
 "   -h displays this text\n"
 "   -r displays the version number\n"
 "   -e skips <bytes> bytes of header\n"
-"   -k avoids disassembling <bytes> bytes from position <start>\n";
+"   -k avoids disassembling <bytes> bytes from position <start>\n"
+"   -p selects the preferred vendor instruction set (intel, amd, cyrix)\n";
 
 static void output_ins (unsigned long, unsigned char *, int, char *);
 static void skip (unsigned long dist, FILE *fp);
@@ -44,6 +46,7 @@ int main(int argc, char **argv)
     int autosync = FALSE;
     int bits = 16;
     int eof = FALSE;
+    unsigned long prefer = 0;
     int rn_error;
     long offset;
     FILE *fp;
@@ -157,6 +160,24 @@ int main(int argc, char **argv)
                add_sync (nextsync, synclen);
                p = "";                /* force to next argument */
                break;
+           case 'p':                  /* preferred vendor */
+               v = p[1] ? p+1 : --argc ? *++argv : NULL;
+               if (!v) {
+                   fprintf(stderr, "%s: `-p' requires an argument\n", pname);
+                   return 1;
+               }
+               if ( !strcmp(v, "intel") ) {
+                 prefer = 0;   /* Default */
+               } else if ( !strcmp(v, "amd") ) {
+                 prefer = IF_AMD|IF_3DNOW;
+               } else if ( !strcmp(v, "cyrix") ) {
+                 prefer = IF_CYRIX|IF_3DNOW;
+               } else {
+                 fprintf(stderr, "%s: unknown vendor `%s' specified with `-p'\n", pname, v);
+                 return 1;
+               }
+               p = "";                /* force to next argument */
+               break;
            }
        } else if (!filename) {
            filename = p;
@@ -213,7 +234,7 @@ int main(int argc, char **argv)
            nextsync = next_sync (offset, &synclen);
        }
        while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
-           lendis = disasm (q, outbuf, bits, offset, autosync);
+           lendis = disasm (q, outbuf, bits, offset, autosync, prefer);
            if (!lendis || lendis > (p - q) ||
                lendis > nextsync-offset)
                lendis = eatbyte (q, outbuf);
index 704e2eb..1a9c9e4 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -28,7 +28,8 @@ static long reg_flags[] = {          /* sizes and special flags */
     MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG,
     REG16, REG16, REG_DESS, FPU0, FPUREG, FPUREG, FPUREG, FPUREG,
     FPUREG, FPUREG, FPUREG, REG_TREG, REG_TREG, REG_TREG, REG_TREG,
-    REG_TREG
+    REG_TREG,
+    XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG
 };
 
 enum {                                /* special tokens */
index e16432a..4460907 100644 (file)
--- a/preproc.c
+++ b/preproc.c
@@ -8,10 +8,30 @@
  * initial version 18/iii/97 by Simon Tatham
  */
 
-#define br0 '{'
-#define br1 "{"
-#define br2 '}'
-#define br3 "}"
+/* Typical flow of text through preproc
+ *
+ * pp_getline gets tokenised lines, either
+ *
+ *   from a macro expansion
+ *
+ * or
+ *   {
+ *   read_line  gets raw text from stdmacpos, or predef, or current input file
+ *   tokenise   converts to tokens
+ *   }
+ *
+ * expand_mmac_params is used to expand %1 etc., unless a macro is being
+ * defined or a false conditional is being processed
+ * (%0, %1, %+1, %-1, %%foo
+ *
+ * do_directive checks for directives
+ *
+ * expand_smacro is used to expand single line macros
+ *
+ * expand_mmacro is used to expand multi-line macros
+ *
+ * detoken is used to convert the line back to text
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -323,8 +343,9 @@ int any_extrastdmac;
 /*
  * Forward declarations.
  */
+static Token *expand_mmac_params (Token *tline);
 static Token *expand_smacro (Token *tline);
-static void make_tok_num(Token *tok, long val);
+static void   make_tok_num(Token *tok, long val);
 
 /*
  * Macros for safe checking of token pointers, avoid *(NULL)
@@ -1413,7 +1434,7 @@ static int do_directive (Token *tline)
        if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER)
            istk->conds->state = COND_NEVER;
        else {
-           j = if_condition(tline->next, i);
+           j = if_condition(expand_mmac_params(tline->next), i);
            tline->next = NULL;        /* it got freed */
            free_tlist (origline);
            if (j < 0)
@@ -2279,7 +2300,7 @@ static Token *expand_smacro (Token *tline)
                                  white = 0;
                                  continue; /* parameter loop */
                              }
-                             if (ch == br0 && 
+                             if (ch == '{' && 
                                  (brackets>0 || (brackets==0 &&
                                                  !paramsize[nparam])))
                              {
@@ -2289,7 +2310,7 @@ static Token *expand_smacro (Token *tline)
                                      continue; /* parameter loop */
                                  }
                              }
-                             if (ch == br2 && brackets>0)
+                             if (ch == '}' && brackets>0)
                                  if (--brackets == 0) {
                                      brackets = -1;
                                      continue; /* parameter loop */
@@ -2966,7 +2987,6 @@ void pp_include_path (char *path)
     i = nasm_malloc(sizeof(IncPath));
     i->path = nasm_strdup(path);
     i->next = ipath;
-
     ipath = i;
 }
 
index f88e603..816cc98 100644 (file)
 # Makefile for RDOFF object file utils; part of the Netwide Assembler
+
 #
+
 # 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 for use under Unix (probably fairly
+
 # portably).
 
+
+
 CC = sc
+
 CCFLAGS = -I..\ -c -a1 -mn -Nc -w2 -w7 -o+time -5
+
 LINK = link
+
 LINKFLAGS = /noi /exet:NT /su:console
 
+
+
 OBJ=obj
+
 EXE=.exe
 
+
+
 NASMLIB = ..\nasmlib.$(OBJ)
+
 NASMLIB_H = ..\nasmlib.h
+
 LDRDFLIBS = rdoff.$(OBJ) $(NASMLIB) symtab.$(OBJ) collectn.$(OBJ) rdlib.$(OBJ)
+
 RDXLIBS = rdoff.$(OBJ) rdfload.$(OBJ) symtab.$(OBJ) collectn.$(OBJ)
 
+
+
 .c.$(OBJ):
+
        $(CC) $(CCFLAGS) $*.c
 
+
+
 all : rdfdump$(EXE) ldrdf$(EXE) rdx$(EXE) rdflib$(EXE) rdf2bin$(EXE) rdf2com$(EXE)
 
+
+
 rdfdump$(EXE)   : rdfdump.$(OBJ)
+
         $(LINK) $(LINKFLAGS) rdfdump.$(OBJ), rdfdump$(EXE);
+
 ldrdf$(EXE)     : ldrdf.$(OBJ) $(LDRDFLIBS)
+
         $(LINK) $(LINKFLAGS) ldrdf.$(OBJ) $(LDRDFLIBS), ldrdf$(EXE);
+
 rdx$(EXE)       : rdx.$(OBJ) $(RDXLIBS)
+
         $(LINK) $(LINKFLAGS) rdx.$(OBJ) $(RDXLIBS), rdx$(EXE);
+
 rdflib$(EXE)    : rdflib.$(OBJ)
+
         $(LINK) $(LINKFLAGS) rdflib.$(OBJ), rdflib$(EXE);
+
 rdf2bin$(EXE)   : rdf2bin.$(OBJ) $(RDXLIBS) $(NASMLIB)
+
         $(LINK) $(LINKFLAGS) rdf2bin.$(OBJ) $(RDXLIBS) $(NASMLIB), rdf2bin$(EXE);
+
 rdf2com$(EXE)   : rdf2bin$(EXE)
+
         copy rdf2bin$(EXE) rdf2com$(EXE)
 
+
+
 rdf2bin.$(OBJ)  : rdf2bin.c
+
 rdfdump.$(OBJ)  : rdfdump.c
+
 rdoff.$(OBJ)    : rdoff.c rdoff.h
+
 ldrdf.$(OBJ)    : ldrdf.c rdoff.h $(NASMLIB_H) symtab.h collectn.h rdlib.h
+
 symtab.$(OBJ)   : symtab.c symtab.h
+
 collectn.$(OBJ) : collectn.c collectn.h
+
 rdx.$(OBJ)      : rdx.c rdoff.h rdfload.h symtab.h
+
 rdfload.$(OBJ)  : rdfload.c rdfload.h rdoff.h collectn.h symtab.h
+
 rdlib.$(OBJ)    : rdlib.c rdlib.h
+
 rdflib.$(OBJ)   : rdflib.c
 
+
+
 clean :
+
         del *.$(OBJ) rdfdump$(EXE) ldrdf$(EXE) rdx$(EXE) rdflib$(EXE) rdf2bin$(EXE)
+
+
+
+
+