source: trunk/ccl/compiler/X86/x86-disassemble.lisp @ 6996

Last change on this file since 6996 was 6996, checked in by rme, 14 years ago

Correct spelling errors.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 117.4 KB
Line 
1;;;-*- Mode: Lisp; Package: CCL -*-
2;;;
3;;;   Copyright (C) 2005, Clozure Associates and contributors.
4;;;   This file is part of OpenMCL.
5;;;
6;;;   OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;;   License , known as the LLGPL and distributed with OpenMCL as the
8;;;   file "LICENSE".  The LLGPL consists of a preamble and the LGPL,
9;;;   which is distributed with OpenMCL as the file "LGPL".  Where these
10;;;   conflict, the preamble takes precedence.
11;;;
12;;;   OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;;   The LLGPL is also available online at
15;;;   http://opensource.franz.com/preamble.html
16
17(in-package "CCL")
18
19(eval-when (:compile-toplevel :load-toplevel :execute)
20  (require "NXENV")
21  (require "DLL-NODE")
22  (require "X86-ASM")
23  (require "X86-LAP"))
24
25(defstruct (x86-disassembled-instruction (:include dll-node)
26                                         (:conc-name x86-di-))
27  address
28  labeled
29  prefixes                              ;explicit prefixes
30  mnemonic
31  op0
32  op1
33  op2
34  )
35
36(defstruct (x86-disassembly-state (:conc-name x86-ds-))
37  (mode-64 t)
38  (prefixes 0)
39  (used-prefixes 0)
40  (rex 0)
41  (rex-used 0)
42  (need-modrm nil)
43  (mod 0)
44  (reg 0)
45  (rm 0)
46  (blocks (make-dll-header))
47  (insn-start 0)                        ; offset of first prefix byte
48  (opcode-start 0)                      ; offset of first opcode byte
49  code-vector
50  code-pointer
51  code-limit
52  constants-vector
53  pending-labels
54  (entry-point 0)
55  current-instruction
56  (string-buffer (make-array 16 :element-type 'character
57                             :fill-pointer 0
58                             :adjustable t))
59  (symbolic-names ())
60)
61
62(defun badop (ds)
63  (setf (x86-ds-code-pointer ds) (1+ (x86-ds-opcode-start ds)))
64  ;;; Do more here.
65  )
66
67(defun x86-ds-peek-u8 (ds)
68  (aref (x86-ds-code-vector ds) (x86-ds-code-pointer ds)))
69
70(defun x86-ds-skip (ds &optional (n 1))
71  (incf (x86-ds-code-pointer ds) n))
72
73(defun x86-ds-next-u8 (ds)
74  (let* ((idx (x86-ds-code-pointer ds)))
75    (incf (x86-ds-code-pointer ds))
76    (aref (x86-ds-code-vector ds) idx)))
77
78(defun x86-ds-next-s8 (ds)
79  (let* ((u8 (x86-ds-next-u8 ds)))
80    (if (logbitp 7 u8)
81      (- u8 #x100)
82      u8)))
83
84(defun x86-ds-next-u16 (ds)
85  (let* ((low (x86-ds-next-u8 ds))
86         (high (x86-ds-next-u8 ds)))
87    (declare (type (unsigned-byte 8) low high))
88    (logior (the fixnum (ash high 8)) low)))
89
90(defun x86-ds-next-s16 (ds)
91  (let* ((low (x86-ds-next-u8 ds))
92         (high (x86-ds-next-s8 ds)))
93    (declare (type (unsigned-byte 8) low)
94             (type (signed-byte 8) high))
95    (logior (the fixnum (ash high 8)) low)))
96
97(defun x86-ds-next-u32 (ds)
98  (let* ((low (x86-ds-next-u16 ds))
99         (high (x86-ds-next-u16 ds)))
100    (declare (type (unsigned-byte 16) low high))
101    (logior (the fixnum (ash high 16)) low)))
102
103(defun x86-ds-next-s32 (ds)
104  (let* ((low (x86-ds-next-u16 ds))
105         (high (x86-ds-next-s16 ds)))
106    (declare (type (unsigned-byte 16) low)
107             (type (signed-byte 16) high))
108    (logior (the fixnum (ash high 16)) low)))
109
110(defun x86-ds-next-u64 (ds)
111  (let* ((low (x86-ds-next-u32 ds))
112         (high (x86-ds-next-u32 ds)))
113    (logior (the fixnum (ash high 32)) low)))
114
115(defun x86-ds-next-s64 (ds)
116  (let* ((low (x86-ds-next-u32 ds))
117         (high (x86-ds-next-s32 ds)))
118    (logior (the fixnum (ash high 32)) low)))
119
120(defun used-rex (ds value)
121  (if (not (zerop value))
122    (setf (x86-ds-rex-used ds)
123          (logior (x86-ds-rex-used ds)
124                  (if (logtest (x86-ds-rex ds) value)
125                    #x40
126                    0)))
127    (setf (x86-ds-rex-used ds)
128          (logior (x86-ds-rex-used ds) #x40))))
129
130(defun used-prefix (ds mask)
131  (setf (x86-ds-used-prefixes ds)
132        (logior (x86-ds-used-prefixes ds)
133                (logand (x86-ds-prefixes ds) mask))))
134
135
136
137;;; An x86-disassembly-block is -something- like a basic block in a
138;;; compiler flow graph; it ends with an unconditional jump and it's
139;;; either the entry node in that graph or it's reachable via a jump
140;;; or branch from some other reachable block.  There may, however, be
141;;; internal labels that are referenced from within the block's
142;;; instructions, from some other block, or both.  Each disassembled
143;;; instruction within a block keeps track of its address and whether
144;;; or not it's a label (a branch or jump target or a tagged return
145;;; address.)  The first instruction in each block is a label; others
146;;; (initally) aren't.  Whenever we encounter a branch or jmp
147;;; instruction (or a manipulation of a tagged return address, which
148;;; is a kind of jmp) and determine the address of the label, we add
149;;; that address to the disassembly-state's PENDING-LABELS set.  When
150;;; we're through processing the block (having encountered an
151;;; unconditional jmp), we remove a pending label from that set.  If
152;;; it's within a block that's already been processed, we ensure that
153;;; the instruction at that address is marked as a label; otherwise,
154;;; we process the new block which starts at that address.
155;;; Eventually, this'll terminate with all reachable code having been
156;;; processed.  There's embedded data and alignment padding in OpenMCL
157;;; x86 functions and this approach means that we won't try to
158;;; disassemble any of that; if the compiler generates any unreachable
159
160;;; code, we won't seen that, either.
161
162;;; There might be a large number of blocks, in which case
163;;; keeping them in a search tree might be a better idea.
164(defstruct (x86-dis-block (:include dll-node))
165  start-address
166  end-address
167  (instructions (make-dll-header))
168)
169
170;;; Insert the block before the first existing block whose
171;;; start address is greater than or equal to this block's
172;;; end address.  (Yes, they can be equal; no, there should
173;;; never be any overlap.)
174(defun insert-x86-block (block blocks)
175  (let* ((this-end (x86-dis-block-end-address block)))
176    (declare (fixnum this-end))
177    (do-dll-nodes (other blocks (append-dll-node block blocks))
178      (when (>= (the fixnum (x86-dis-block-start-address other))
179                this-end)
180        (return (insert-dll-node-before block other))))))
181
182(defun x86-dis-find-label (address blocks)
183  (declare (fixnum address))
184  (do-dll-nodes (block blocks)
185    (when (and (>= address (the fixnum (x86-dis-block-start-address block)))
186               (< address (the fixnum (x86-dis-block-end-address block))))
187      (let* ((instruction
188              (do-dll-nodes (i (x86-dis-block-instructions block))
189                (when (= (x86-di-address i) address)
190                  (return i)))))
191        (unless instruction
192          (error "Bug: no instruction at address #x~x" address))
193        (return (or (x86-di-labeled instruction)
194                    (setf (x86-di-labeled instruction) t)))))))
195
196
197;;; Flags stored in PREFIXES
198(defconstant +PREFIX-REPZ+ 1)
199(defconstant +PREFIX-REPNZ+ 2)
200(defconstant +PREFIX-LOCK+ 4)
201(defconstant +PREFIX-CS+ 8)
202(defconstant +PREFIX-SS+ #x10)
203(defconstant +PREFIX-DS+ #x20)
204(defconstant +PREFIX-ES+ #x40)
205(defconstant +PREFIX-FS+ #x80)
206(defconstant +PREFIX-GS+ #x100)
207(defconstant +PREFIX-DATA+ #x200)
208(defconstant +PREFIX-ADDR+ #x400)
209(defconstant +PREFIX-FWAIT+ #x800)
210
211
212
213                             
214(defstruct (x86-dis (:constructor %make-x86-dis))
215  mnemonic                              ; may be nil
216  flags                                 ; extra info
217  op1                                   ; function to obtain 1st operand
218  bytemode1                             ; flags associated with operand1
219  op2                                   ; function for second operand
220  bytemode2                             ; flags for operand2
221  op3                                   ; function,
222  bytemode3                             ; flags for operand3
223  )
224
225(defconstant +SUFFIX-ALWAYS+ 4)
226(defconstant +AFLAG+ 2)
227(defconstant +DFLAG+ 1)
228
229(defconstant +b-mode+ 1)                ; byte operand
230(defconstant +v-mode+ 2)                ; operand size depends on prefixes
231(defconstant +w-mode+ 3)                ; word operand
232(defconstant +d-mode+ 4)                ; double word operand
233(defconstant +q-mode+ 5)                ; quad word operand
234(defconstant +t-mode+ 6)                ; ten-byte operand
235(defconstant +x-mode+ 7)                ; 16-byte XMM operand
236(defconstant +m-mode+ 8)                ; d-mode in 32bit, q-mode in 64bit mode.
237(defconstant +cond-jump-mode+ 9)
238(defconstant +loop-jcxz-mode+ 10)
239(defconstant +dq-mode+ 11)              ; operand size depends on REX prefixes.
240(defconstant +dqw-mode+ 12)             ; registers like dq-mode, memory like w-mode.
241(defconstant +f-mode+ 13)               ; 4- or 6-byte pointer operand
242(defconstant +const-1-mode+ 14)
243
244(defconstant +es-reg+ 100)
245(defconstant +cs-reg+ 101)
246(defconstant +ss-reg+ 102)
247(defconstant +ds-reg+ 103)
248(defconstant +fs-reg+ 104)
249(defconstant +gs-reg+ 105)
250
251(defconstant +eAX-reg+ 108)
252(defconstant +eCX-reg+ 109)
253(defconstant +eDX-reg+ 110)
254(defconstant +eBX-reg+ 111)
255(defconstant +eSP-reg+ 112)
256(defconstant +eBP-reg+ 113)
257(defconstant +eSI-reg+ 114)
258(defconstant +eDI-reg+ 115)
259
260(defconstant +al-reg+ 116)
261(defconstant +cl-reg+ 117)
262(defconstant +dl-reg+ 118)
263(defconstant +bl-reg+ 119)
264(defconstant +ah-reg+ 120)
265(defconstant +ch-reg+ 121)
266(defconstant +dh-reg+ 122)
267(defconstant +bh-reg+ 123)
268
269(defconstant +ax-reg+ 124)
270(defconstant +cx-reg+ 125)
271(defconstant +dx-reg+ 126)
272(defconstant +bx-reg+ 127)
273(defconstant +sp-reg+ 128)
274(defconstant +bp-reg+ 129)
275(defconstant +si-reg+ 130)
276(defconstant +di-reg+ 131)
277
278(defconstant +rAX-reg+ 132)
279(defconstant +rCX-reg+ 133)
280(defconstant +rDX-reg+ 134)
281(defconstant +rBX-reg+ 135)
282(defconstant +rSP-reg+ 136)
283(defconstant +rBP-reg+ 137)
284(defconstant +rSI-reg+ 138)
285(defconstant +rDI-reg+ 139)
286
287(defconstant +indir-dx-reg+ 150)
288
289(defconstant +FLOATCODE+ 1)
290(defconstant +USE-GROUPS+ 2)
291(defconstant +USE-PREFIX-USER-TABLE+ 3)
292(defconstant +X86-64-SPECIAL+ 4)
293(defconstant +UUOCODE+ 5)
294
295(defconstant +REX-MODE64+ 8)
296(defconstant +REX-EXTX+ 4)
297(defconstant +REX-EXTY+ 2)
298(defconstant +REX-EXTZ+ 1)
299
300(defparameter *x86-segment-prefix-alist*
301  `((,+prefix-cs+ . "cs")
302    (,+prefix-ds+ . "ds")
303    (,+prefix-ss+ . "ss")
304    (,+prefix-es+ . "es")
305    (,+prefix-fs+ . "fs")
306    (,+prefix-gs+ . "gs")))
307
308
309(defun segment-register-from-prefixes (ds)
310  (let* ((prefixes (x86-ds-prefixes ds)))
311    (dolist (pair *x86-segment-prefix-alist*)
312      (when (logtest (car pair) prefixes)
313        (setf (x86-ds-used-prefixes ds)
314              (logior (x86-ds-used-prefixes ds)
315                      (car pair)))
316        (return (parse-x86-register-operand (cdr pair) :%))))))
317
318(defun x86-dis-make-reg-operand (r)
319  (x86::make-x86-register-operand
320   :type (logandc2 (x86::reg-entry-reg-type r)
321                   (x86::encode-operand-type :baseIndex))
322   :entry r))
323
324(defun op-st (ds bytemode sizeflag)
325  (declare (ignore ds bytemode sizeflag))
326  (parse-x86-register-operand "st" :%))
327
328(defun op-sti (ds bytemode sizeflag)
329  (declare (ignore bytemode sizeflag))
330  (x86-dis-make-reg-operand (svref x86::*x86-float-regs* (x86-ds-rm ds))))
331
332(defun op-indire (ds bytemode sizeflag)
333  (when (zerop (x86-ds-prefixes ds))
334    (setf (x86-ds-rex ds) (logior #x48 (x86-ds-rex ds))))
335  (op-e ds bytemode sizeflag))
336
337
338(defun op-e (ds bytemode sizeflag)
339  (let* ((add 0)
340         (riprel nil))
341    (used-rex ds +rex-extz+)
342    (if (logtest (x86-ds-rex ds) +rex-extz+)
343      (setq add 8))
344    (x86-ds-skip ds)                    ;skip MODRM byte
345    (cond ((eql (x86-ds-mod ds) 3)      ; EA is just a register
346           (cond ((eql bytemode +b-mode+)
347                  (used-rex ds 0)
348                  ;; This is wrong: if we don't have an REX prefix,
349                  ;; we should use the old byte register names
350                  ;; (dh, ah, ...) instead of the new ones (bpl, sil ...)
351                  ;; That'll matter if Lisp code ever needs to
352                  ;; access the #xff00 byte, but that seems unlikely
353                  (x86-dis-make-reg-operand (x86::x86-reg8 (+ (x86-ds-rm ds)
354                                                              add))))
355                 ((eql bytemode +w-mode+)
356                  (x86-dis-make-reg-operand (x86::x86-reg16 (+ (x86-ds-rm ds)
357                                                              add))))
358                 ((eql bytemode +d-mode+)
359                  (x86-dis-make-reg-operand (x86::x86-reg32 (+ (x86-ds-rm ds)
360                                                              add))))
361                 ((eql bytemode +q-mode+)
362                  (x86-dis-make-reg-operand (x86::x86-reg64 (+ (x86-ds-rm ds)
363                                                              add))))
364                 ((eql bytemode +m-mode+)
365                  (if (x86-ds-mode-64 ds)
366                    (x86-dis-make-reg-operand (x86::x86-reg64 (+ (x86-ds-rm ds)
367                                                              add)))
368                    (x86-dis-make-reg-operand (x86::x86-reg32 (+ (x86-ds-rm ds)
369                                                              add)))))
370                 ((or (eql bytemode +v-mode+)
371                      (eql bytemode +dq-mode+)
372                      (eql bytemode +dqw-mode+))
373                  (used-rex ds +rex-mode64+)
374                  (used-prefix ds +prefix-data+)
375                  (cond ((logtest (x86-ds-rex ds) +rex-mode64+)
376                         (x86-dis-make-reg-operand (x86::x86-reg64 (+ (x86-ds-rm ds)
377                                                              add))))
378                        ((or (logtest sizeflag +dflag+)
379                             (not (eql bytemode +v-mode+)))
380                         (x86-dis-make-reg-operand (x86::x86-reg32 (+ (x86-ds-rm ds)
381                                                              add))))
382                        (t
383                         (x86-dis-make-reg-operand (x86::x86-reg16 (+ (x86-ds-rm ds)
384                                                              add))))))
385                 ((eql bytemode 0) nil)
386                 (t (error "Disassembly error"))))
387          (t                            ; memory operand
388           (let* ((disp nil)
389                  (base (x86-ds-rm ds))
390                  (index nil)
391                  (scale nil)
392                  (have-base t)
393                  (have-sib nil)
394                  (memop (x86::make-x86-memory-operand)))
395             (setf (x86::x86-memory-operand-seg memop)
396                   (segment-register-from-prefixes ds))
397             (when (= base 4)
398               (setq have-sib t)
399               (let* ((sib (x86-ds-next-u8 ds)))
400                 (setq index (ldb (byte 3 3) sib))
401                 (if (or (x86-ds-mode-64 ds)
402                         (not (eql index 4)))
403                   (setq scale (ldb (byte 2 6) sib)))
404                 (setq base (ldb (byte 3 0) sib))
405                 (used-rex ds +rex-exty+)
406                 (used-rex ds +rex-extz+)
407                 (when (logtest (x86-ds-rex ds) +rex-exty+)
408                   (incf index 8))
409                 (when (logtest  (x86-ds-rex ds) +rex-extz+)
410                   (incf base 8))))
411             (case (x86-ds-mod ds)
412               (0
413                (when (= 5 (logand base 7))
414                  (setq have-base nil)
415                  (if (and (x86-ds-mode-64 ds) (not have-sib))
416                    (setq riprel t))
417                  (setq disp (x86-ds-next-s32 ds))))
418               (1
419                (setq disp (x86-ds-next-s8 ds)))
420               (2
421                (setq disp (x86-ds-next-s32 ds))))
422             (when (or (not (eql (x86-ds-mod ds) 0))
423                       (eql 5 (logand base 7)))
424               (setf (x86::x86-memory-operand-disp memop)
425                     (parse-x86-lap-expression disp))
426               (when riprel
427                 (setf (x86::x86-memory-operand-base memop)
428                       (parse-x86-register-operand "rip" :%))))
429             (when (or have-base
430                       (and have-sib
431                            (or (not (eql index 4))
432                                (not (eql scale 0)))))
433               (used-rex ds +rex-extz+)
434               (if (and (not have-sib)
435                        (logtest (x86-ds-rex ds) +rex-extz+))
436                 (incf base 8))
437               (if have-base
438                 (setf (x86::x86-memory-operand-base memop)
439                       (if (and (x86-ds-mode-64 ds)
440                                (logtest sizeflag +aflag+))
441                         (x86-dis-make-reg-operand (x86::x86-reg64 base))
442                         (x86-dis-make-reg-operand (x86::x86-reg32 base)))))
443               (when have-sib
444                 (unless (= index 4)
445                   (setf (x86::x86-memory-operand-index memop)
446                    (if (and (x86-ds-mode-64 ds)
447                             (logtest sizeflag +aflag+))
448                      (x86-dis-make-reg-operand (x86::x86-reg64 index))
449                      (x86-dis-make-reg-operand (x86::x86-reg32 index)))))
450                 (unless scale
451                   (setq scale 0))
452                 (when (or (not (eql scale 0))
453                           (not (eql index 4)))
454                   (setf (x86::x86-memory-operand-scale memop) scale))))
455             memop)))))
456
457
458(defun op-g (ds bytemode sizeflag)
459  (let* ((add 0)
460         (reg (x86-ds-reg ds)))
461    (used-rex ds +rex-extx+)
462    (if (logtest (x86-ds-rex ds) +rex-extx+)
463      (setq add 8))
464    (cond ((eql bytemode +b-mode+)
465           (used-rex ds 0)
466           ;; This is wrong: if we don't have an REX prefix,
467           ;; we should use the old byte register names
468           ;; (dh, ah, ...) instead of the new ones (bpl, sil ...)
469           ;; That'll matter if Lisp code ever needs to
470           ;; access the #xff00 byte, but that seems unlikely
471           (x86-dis-make-reg-operand (x86::x86-reg8 (+ reg add))))
472          ((eql bytemode +w-mode+)
473           (x86-dis-make-reg-operand (x86::x86-reg16 (+ reg add))))
474          ((eql bytemode +d-mode+)
475           (x86-dis-make-reg-operand (x86::x86-reg32 (+ reg add))))
476          ((eql bytemode +q-mode+)
477           (x86-dis-make-reg-operand (x86::x86-reg64 (+ reg add))))
478          ((eql bytemode +m-mode+)
479           (if (x86-ds-mode-64 ds)
480             (x86-dis-make-reg-operand (x86::x86-reg64 (+ reg add)))
481             (x86-dis-make-reg-operand (x86::x86-reg32 (+ reg add)))))
482          ((or (eql bytemode +v-mode+)
483               (eql bytemode +dq-mode+)
484               (eql bytemode +dqw-mode+))
485           (used-rex ds +rex-mode64+)
486           (used-prefix ds +prefix-data+)
487           (cond ((logtest (x86-ds-rex ds) +rex-mode64+)
488                  (x86-dis-make-reg-operand (x86::x86-reg64 (+ reg add))))
489                 ((or (logtest sizeflag +dflag+)
490                      (not (eql bytemode +v-mode+)))
491                  (x86-dis-make-reg-operand (x86::x86-reg32 (+ reg add))))
492                 (t
493                  (x86-dis-make-reg-operand (x86::x86-reg16 (+ reg add))))))
494          ((eql bytemode 0) nil)
495          (t (error "Disassembly error")))))
496
497(defun op-reg (ds code sizeflag)
498  (declare (fixnum code))
499  (let* ((add 0))
500    (used-rex ds +rex-extz+)
501    (if (logtest (x86-ds-rex ds) +rex-extz+)
502      (setq add 8))
503    (cond ((= code +indir-dx-reg+)
504           (x86::make-x86-memory-operand
505            :base (parse-x86-register-operand "dx" :%)))
506          (t
507           (let* ((r (cond ((and (>= code +ax-reg+)
508                                 (<= code +di-reg+))
509                            (x86::x86-reg16 (+ (- code +ax-reg+) add)))
510                           ((= code +es-reg+) (lookup-x86-register "es" :%))
511                           ((= code +cs-reg+) (lookup-x86-register "cs" :%))
512                           ((= code +ds-reg+) (lookup-x86-register "ds" :%))
513                           ((= code +ss-reg+) (lookup-x86-register "ss" :%))
514                           ((= code +fs-reg+) (lookup-x86-register "fs" :%))
515                           ((= code +gs-reg+) (lookup-x86-register "gs" :%))
516                           ((and (>= code +al-reg+)
517                                 (<= code +dh-reg+))
518                            ;; Again, this is wrong if there's no REX
519                            ;; prefix.
520                            (used-rex ds 0)
521                            (x86::x86-reg8 (+ add (- code +al-reg+))))
522                           ((and (>= code +rax-reg+)
523                                 (<= code +rdi-reg+)
524                                 (or (x86-ds-mode-64 ds)
525                                     (progn
526                                       (setq code (+ code (- +eax-reg+ +rax-reg+)))
527                                       nil)))
528                            (x86::x86-reg64 (+ add (- code +rax-reg+))))
529                           ((and (>= code +eax-reg+)
530                                 (<= code +edi-reg+))
531                            (used-rex ds +rex-mode64+)
532                            (used-prefix ds +prefix-data+)
533                            (if (logtest (x86-ds-rex ds) +rex-mode64+)
534                              (x86::x86-reg64 (+ add (- code +eax-reg+)))
535                              (if (logtest sizeflag +dflag+)
536                                (x86::x86-reg32 (+ add (- code +eax-reg+)))
537                                (x86::x86-reg16 (+ add (- code +eax-reg+))))))
538                           ((and (>= code +al-reg+)
539                                 (<= code +bh-reg+))
540                            (x86::x86-reg8 (+ add (- code +al-reg+))))
541                           (t (error "Disassembly error: code = ~s" code)))))
542             (x86-dis-make-reg-operand r))))))
543
544;;; Like OP-REG, but doesn't deal with extended 64-bit registers.
545(defun op-imreg (ds code sizeflag)
546  (declare (fixnum code))
547  (cond ((= code +indir-dx-reg+)
548         (x86::make-x86-memory-operand
549          :base (parse-x86-register-operand "dx" :%)))
550        (t
551         (let* ((r (cond ((and (>= code +ax-reg+)
552                               (<= code +di-reg+))
553                          (x86::x86-reg16 (- code +ax-reg+)))
554                         ((= code +es-reg+) (lookup-x86-register "es" :%))
555                         ((= code +cs-reg+) (lookup-x86-register "cs" :%))
556                         ((= code +ds-reg+) (lookup-x86-register "ds" :%))
557                         ((= code +ss-reg+) (lookup-x86-register "ss" :%))
558                         ((= code +fs-reg+) (lookup-x86-register "fs" :%))
559                         ((= code +gs-reg+) (lookup-x86-register "gs" :%))
560                         ((and (>= code +al-reg+)
561                               (<= code +dh-reg+))
562                          ;; Again, this is wrong if there's no REX
563                          ;; prefix.
564                          (used-rex ds 0)
565                          (x86::x86-reg8 (- code +al-reg+)))
566
567                         ((and (>= code +eax-reg+)
568                                 (<= code +edi-reg+))
569                          (used-rex ds +rex-mode64+)
570                          (used-prefix ds +prefix-data+)
571                          (if (logtest (x86-ds-rex ds) +rex-mode64+)
572                            (x86::x86-reg64 (- code +eax-reg+))
573                            (if (logtest sizeflag +dflag+)
574                              (x86::x86-reg32 (- code +eax-reg+))
575                              (x86::x86-reg16 (- code +eax-reg+)))))
576                         (t (error "Disassembly error")))))
577           (x86-dis-make-reg-operand r)))))
578
579;;; A (possibly unsigned) immediate.
580(defun op-i (ds bytemode sizeflag)
581  (let* ((mask -1)
582         (op (cond ((= bytemode +b-mode+)
583                    (setq mask #xff)
584                    (x86-ds-next-u8 ds))
585                   ((and (= bytemode +q-mode+)
586                         (x86-ds-mode-64 ds))
587                    (x86-ds-next-s32 ds))
588                   ((or (= bytemode +q-mode+)
589                        (= bytemode +v-mode+))
590                    (used-rex ds +rex-mode64+)
591                    (used-prefix ds +prefix-data+)
592                    (if (logtest (x86-ds-rex ds) +rex-mode64+)
593                      (x86-ds-next-s32 ds)
594                      (if (logtest sizeflag +dflag+)
595                        (progn
596                          (setq mask #xffffffff)
597                          (x86-ds-next-u32 ds))
598                        (progn
599                          (setq mask #xfffff)
600                          (x86-ds-next-u16 ds)))))
601                   ((= bytemode +w-mode+)
602                    (setq mask #xfffff)
603                    (x86-ds-next-u16 ds))
604                   ((= bytemode +const-1-mode+)
605                    nil))))
606    (when op
607      (setq op (logand op mask))
608      (x86::make-x86-immediate-operand :value (parse-x86-lap-expression op)))))
609
610(defun op-i64 (ds bytemode sizeflag)
611  (if (not (x86-ds-mode-64 ds))
612    (op-i ds bytemode sizeflag)
613    (let* ((op (cond ((= bytemode +b-mode+)
614                      (x86-ds-next-u8 ds))
615                     ((= bytemode +v-mode+)
616                      (used-rex ds +rex-mode64+)
617                      (used-prefix ds +prefix-data+)
618                      (if (logtest (x86-ds-rex ds) +rex-mode64+)
619                        (x86-ds-next-u64 ds)
620                        (if (logtest sizeflag +dflag+)
621                          (x86-ds-next-u32 ds)
622                          (x86-ds-next-u16 ds))))
623                     ((= bytemode +w-mode+)
624                      (x86-ds-next-u16 ds))
625                     (t (error "Disassembly error")))))
626      (when op
627        (x86::make-x86-immediate-operand :value (parse-x86-lap-expression op))))))
628
629(defun op-si (ds bytemode sizeflag)
630  (let* ((op
631          (cond ((= bytemode +b-mode+)
632                 (x86-ds-next-s8 ds))
633                ((= bytemode +v-mode+)
634                 (used-rex ds +rex-mode64+)
635                 (used-prefix ds +prefix-data+)
636                 (if (logtest (x86-ds-rex ds) +rex-mode64+)
637                   (x86-ds-next-s32 ds)
638                   (if (logtest sizeflag +dflag+)
639                     (x86-ds-next-s32 ds)
640                     (x86-ds-next-s16 ds))))
641                ((= bytemode +w-mode+)
642                 (x86-ds-next-s16 ds))
643                (t (error "Disassembly error")))))
644    (x86::make-x86-immediate-operand :value (parse-x86-lap-expression op))))
645
646(defun op-j (ds bytemode sizeflag)
647  (let* ((mask -1)
648         (disp (cond ((= bytemode +b-mode+)
649                      (x86-ds-next-s8 ds))
650                     ((= bytemode +v-mode+)
651                      (if (logtest sizeflag +dflag+)
652                        (x86-ds-next-s32 ds)
653                        (progn
654                          (setq mask #xffff)
655                          (x86-ds-next-u16 ds))))
656                     (t (error "Disassembly error"))))
657         (label-address (logand (+ (x86-ds-code-pointer ds) disp)
658                                mask)))
659    (push label-address (x86-ds-pending-labels ds))
660    (x86::make-x86-label-operand :label label-address)))
661
662(defun op-seg (ds x y)
663  (declare (ignore x y))
664  (x86-dis-make-reg-operand (x86::x86-segment-register (x86-ds-reg ds))))
665
666(defun op-dir (ds x sizeflag)
667  (declare (ignore x))
668  (let* ((offset (if (logtest sizeflag +dflag+)
669                   (x86-ds-next-u32 ds)
670                   (x86-ds-next-u16 ds)))
671         (seg (x86-ds-next-u16 ds)))
672    (list (x86::make-x86-immediate-operand :value (parse-x86-lap-expression seg))
673          (x86::make-x86-memory-operand :disp (parse-x86-lap-expression offset)))))
674
675(defun op-off (ds x sizeflag)
676  (declare (ignore x))
677  (x86::make-x86-memory-operand
678   :seg (segment-register-from-prefixes ds)
679   :disp (parse-x86-lap-expression (cond ((or (x86-ds-mode-64 ds)
680                                              (logtest sizeflag +aflag+))
681                                          (x86-ds-next-u32 ds))
682                                         (t (x86-ds-next-u16 ds))))))
683
684
685(defun op-off64 (ds bytemode sizeflag)
686  (if (not (x86-ds-mode-64 ds))
687    (op-off ds bytemode sizeflag)
688    (x86::make-x86-memory-operand
689     :seg (segment-register-from-prefixes ds)
690     :disp (parse-x86-lap-expression (x86-ds-next-u64 ds)))))
691       
692
693(defun %ptr-reg (ds code sizeflag)
694  (used-prefix ds +prefix-addr+)
695  (let* ((idx (- code +eax-reg+))
696         (r (if (x86-ds-mode-64 ds)
697              (if (not (logtest sizeflag +aflag+))
698                (x86::x86-reg32 idx)
699                (x86::x86-reg64 idx))
700              (if (logtest sizeflag +aflag+)
701                (x86::x86-reg32 idx)
702                (x86::x86-reg16 idx)))))
703    (x86-dis-make-reg-operand r)))
704
705(defun op-esreg (ds code sizeflag)
706  (x86::make-x86-memory-operand
707   :seg (parse-x86-register-operand "es" :%)
708   :base (%ptr-reg ds code sizeflag)))
709     
710(defun op-dsreg (ds code sizeflag)
711  (unless (logtest (x86-ds-prefixes ds)
712                   (logior +prefix-cs+
713                           +prefix-ds+
714                           +prefix-ss+
715                           +prefix-es+
716                           +prefix-fs+
717                           +prefix-gs+))
718    (setf (x86-ds-prefixes ds)
719          (logior (x86-ds-prefixes ds) +prefix-ds+)))
720  (x86::make-x86-memory-operand
721   :seg (segment-register-from-prefixes ds)
722   :base (%ptr-reg ds code sizeflag)))
723
724;;; Control-register reference.
725(defun op-c (ds x sizeflag)
726  (declare (ignore x sizeflag))
727  (let* ((add (cond ((logtest (x86-ds-rex ds) +rex-extx+)
728                     (used-rex ds +rex-extx+)
729                     8)
730                    ((and (not (x86-ds-mode-64 ds))
731                          (logtest (x86-ds-prefixes ds) +prefix-lock+))
732                     (setf (x86-ds-used-prefixes ds)
733                           (logior (x86-ds-used-prefixes ds) +prefix-lock+))
734                     8)
735                    (t 0)))
736         (regname (format nil "cr~d" (+ (x86-ds-reg ds) add))))
737    (parse-x86-register-operand regname :%)))
738 
739;;; Debug-register reference.
740(defun op-d (ds x sizeflag)
741  (declare (ignore x sizeflag))
742  (used-rex ds +rex-extx+)
743  (let* ((add (if (logtest (x86-ds-rex ds) +rex-extx+)
744                8
745                0))
746         (regname (format nil "db~d" (+ (x86-ds-reg ds) add))))
747    (parse-x86-register-operand regname :%)))
748
749;;; Test-register.  There are only 8 of them, even on x86-64.
750(defun op-t (ds x y)
751  (declare (ignore x y))
752  (parse-x86-register-operand (format nil "tr~d" (x86-ds-reg ds)) :%))
753
754(defun op-rd (ds bytemode sizeflag)
755  (if (= (x86-ds-mod ds) 3)
756    (op-e ds bytemode sizeflag)
757    (badop ds)))
758
759
760;;; A data prefix causes a reference to an xmm register instead of
761;;; the (default) case of referencing an mmx register.
762(defun op-mmx (ds x sizeflag)
763  (declare (ignore x sizeflag))
764  (let* ((prefixes (x86-ds-prefixes ds)))
765    (used-prefix ds +prefix-data+)
766    (if (logtest prefixes +prefix-data+)
767      (let* ((add (progn (used-rex ds +rex-extx+)
768                         (if (logtest (x86-ds-rex ds) +rex-extx+)
769                           8
770                           0))))
771        (x86-dis-make-reg-operand (x86::x86-xmm-register (+ (x86-ds-reg ds) add))))
772      (x86-dis-make-reg-operand (x86::x86-mmx-register (x86-ds-reg ds))))))
773
774
775(defun op-xmm (ds bytemode sizeflag)
776  (declare (ignore bytemode sizeflag))
777  (used-rex ds +rex-extx+)
778  (let* ((add (if (logtest (x86-ds-rex ds) +rex-extx+) 8 0)))
779    (x86-dis-make-reg-operand (x86::x86-xmm-register (+ (x86-ds-reg ds) add)))))
780
781(defun op-em (ds bytemode sizeflag)
782  (if (not (eql (x86-ds-mod ds) 3))
783    (op-e ds bytemode sizeflag)
784    (let* ((prefixes (x86-ds-prefixes ds)))
785      (x86-ds-skip ds)                  ; skip modrm
786      (used-prefix ds +prefix-data+)
787      (cond ((logtest prefixes +prefix-data+)
788             (used-rex ds +rex-extz+)
789             (let* ((add (if (logtest (x86-ds-rex ds) +rex-extz+)
790                           8
791                           0)))
792               (x86-dis-make-reg-operand
793                (x86::x86-xmm-register (+ (x86-ds-rm ds) add)))))
794            (t
795             (x86-dis-make-reg-operand
796              (x86::x86-mmx-register (x86-ds-rm ds))))))))
797
798(defun op-ex (ds bytemode sizeflag)
799  (if (not (eql (x86-ds-mod ds) 3))
800    (op-e ds bytemode sizeflag)
801    (let* ((add (if (logtest (x86-ds-rex ds) +rex-extz+) 8 0)))
802      (used-rex ds +rex-extz+)
803      (x86-ds-skip ds)                  ; skip modrm
804      (x86-dis-make-reg-operand (x86::x86-xmm-register (+ (x86-ds-rm ds) add))))))
805           
806(defun op-ms (ds bytemode sizeflag)
807  (if (eql (x86-ds-mod ds) 3)
808    (op-em ds bytemode sizeflag)
809    (badop ds)))
810
811(defun op-xs (ds bytemode sizeflag)
812  (if (eql (x86-ds-mod ds) 3)
813    (op-ex ds bytemode sizeflag)
814    (badop ds)))
815
816(defun op-m (ds bytemode sizeflag)
817  (if (eql (x86-ds-mod ds) 3)
818    (badop ds)
819    (op-e ds bytemode sizeflag)))
820
821(defun op-0f07 (ds bytemode sizeflag)
822  (if (or (not (eql (x86-ds-mod ds) 3))
823          (not (eql (x86-ds-rm ds) 0)))
824    (badop ds)
825    (op-e ds bytemode sizeflag)))
826
827(defun nop-fixup (ds bytemode sizeflag)
828  (declare (ignore bytemode sizeflag))
829  (if (logtest (x86-ds-prefixes ds) +prefix-repz+)
830    (break "should be PAUSE")))
831
832;;;             
833
834(defun make-x86-dis (opstring &optional
835                             op1-fun
836                             (op1-byte 0)
837                             op2-fun
838                             (op2-byte 0)
839                             op3-fun
840                             (op3-byte 0))
841  (let* ((flags nil))
842    (if (consp opstring)
843      (setq flags (cdr opstring) opstring (car opstring)))
844    (%make-x86-dis :mnemonic opstring
845                   :flags flags
846                   :op1 op1-fun
847                   :bytemode1 op1-byte
848                   :op2 op2-fun
849                   :bytemode2 op2-byte
850                   :op3 op3-fun
851                   :bytemode3 op3-byte)))
852                         
853
854;;; The root of all evil, unless the first byte of the opcode
855;;; is #xf
856(defparameter *disx86*
857  (vector
858   ;; #x00
859   (make-x86-dis "addB" 'op-e +b-mode+ 'op-g +b-mode+)
860   (make-x86-dis "addS" 'op-e +v-mode+ 'op-g +v-mode+)
861   (make-x86-dis "addB" 'op-g +b-mode+ 'op-e +b-mode+)
862   (make-x86-dis "addS" 'op-g +v-mode+ 'op-e +v-mode+)
863   (make-x86-dis "addB" 'op-imreg +al-reg+ 'op-i +b-mode+)
864   (make-x86-dis "addS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
865   (make-x86-dis '(("pushT" . "(bad)")) 'op-reg +es-reg+)
866   (make-x86-dis '(("popT" . "(bad)")) 'op-reg +es-reg+)
867   ;; #x08
868   (make-x86-dis "orB" 'op-e +b-mode+ 'op-g +b-mode+)
869   (make-x86-dis "orS" 'op-e +v-mode+ 'op-g +v-mode+)
870   (make-x86-dis "orB" 'op-g +b-mode+ 'op-e +b-mode+)
871   (make-x86-dis "orS" 'op-g +v-mode+ 'op-e +v-mode+)
872   (make-x86-dis "orB" 'op-imreg +al-reg+ 'op-i +b-mode+)
873   (make-x86-dis "orS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
874   (make-x86-dis '(("pushT" . "(bad)")) 'op-reg +cs-reg+)
875   (make-x86-dis "(bad)")               ; #x0f extended opcode escape
876   ;; #x10
877   (make-x86-dis "adcB" 'op-e +b-mode+ 'op-g +b-mode+)
878   (make-x86-dis "adcS" 'op-e +v-mode+ 'op-g +v-mode+)
879   (make-x86-dis "adcB" 'op-g +b-mode+ 'op-e +b-mode+)
880   (make-x86-dis "adcS" 'op-g +v-mode+ 'op-e +v-mode+)
881   (make-x86-dis "adcB" 'op-imreg +al-reg+ 'op-i +b-mode+)
882   (make-x86-dis "adcS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
883   (make-x86-dis '(("pushT" . "(bad)")) 'op-reg +ss-reg+)
884   (make-x86-dis '(("popT" . "(bad)")) 'op-reg +ss-reg+)
885   ;; #x18
886   (make-x86-dis "sbbB" 'op-e +b-mode+ 'op-g +b-mode+)
887   (make-x86-dis "sbbS" 'op-e +v-mode+ 'op-g +v-mode+)
888   (make-x86-dis "sbbB" 'op-g +b-mode+ 'op-e +b-mode+)
889   (make-x86-dis "sbbS" 'op-g +v-mode+ 'op-e +v-mode+)
890   (make-x86-dis "sbbB" 'op-imreg +al-reg+ 'op-i +b-mode+)
891   (make-x86-dis "sbbS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
892   (make-x86-dis '(("pushT" . "(bad)")) 'op-reg +ds-reg+)
893   (make-x86-dis '(("popT" . "(bad)")) 'op-reg +ds-reg+)
894   ;; #x20
895   (make-x86-dis "andB" 'op-e +b-mode+ 'op-g +b-mode+)
896   (make-x86-dis "andS" 'op-e +v-mode+ 'op-g +v-mode+)
897   (make-x86-dis "andB" 'op-g +b-mode+ 'op-e +b-mode+)
898   (make-x86-dis "andS" 'op-g +v-mode+ 'op-e +v-mode+)
899   (make-x86-dis "andB" 'op-imreg +al-reg+ 'op-i +b-mode+)
900   (make-x86-dis "andS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
901   (make-x86-dis "(bad)")               ; SEG ES prefix
902   (make-x86-dis '(("daa" . "(bad)")))
903   ;; #x28
904   (make-x86-dis "subB" 'op-e +b-mode+ 'op-g +b-mode+)
905   (make-x86-dis "subS" 'op-e +v-mode+ 'op-g +v-mode+)
906   (make-x86-dis "subB" 'op-g +b-mode+ 'op-e +b-mode+)
907   (make-x86-dis "subS" 'op-g +v-mode+ 'op-e +v-mode+)
908   (make-x86-dis "subB" 'op-imreg +al-reg+ 'op-i +b-mode+)
909   (make-x86-dis "subS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
910   (make-x86-dis "(bad)")               ; SEG CS prefix
911   (make-x86-dis '(("das" . "(bad)")))
912   ;; #x30
913   (make-x86-dis "xorB" 'op-e +b-mode+ 'op-g +b-mode+)
914   (make-x86-dis "xorS" 'op-e +v-mode+ 'op-g +v-mode+)
915   (make-x86-dis "xorB" 'op-g +b-mode+ 'op-e +b-mode+)
916   (make-x86-dis "xorS" 'op-g +v-mode+ 'op-e +v-mode+)
917   (make-x86-dis "xorB" 'op-imreg +al-reg+ 'op-i +b-mode+)
918   (make-x86-dis "xorS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
919   (make-x86-dis "(bad)")               ; SEG SS prefix
920   (make-x86-dis '(("aaa" . "(bad)")))
921   ;; #x38
922   (make-x86-dis "cmpB" 'op-e +b-mode+ 'op-g +b-mode+)
923   (make-x86-dis "cmpS" 'op-e +v-mode+ 'op-g +v-mode+)
924   (make-x86-dis "cmpB" 'op-g +b-mode+ 'op-e +b-mode+)
925   (make-x86-dis "cmpS" 'op-g +v-mode+ 'op-e +v-mode+)
926   (make-x86-dis "cmpB" 'op-imreg +al-reg+ 'op-i +b-mode+)
927   (make-x86-dis "cmpS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
928   (make-x86-dis "(bad)")               ; SEG DS prefix
929   (make-x86-dis '(("aas" . "(bad)")))
930   ;; #x40
931   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +eax-reg+)
932   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +ecx-reg+)
933   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +edx-reg+)
934   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +ebx-reg+)
935   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +esp-reg+)
936   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +ebp-reg+)
937   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +esi-reg+)
938   (make-x86-dis '(("incS" . "(bad)")) 'op-reg +edi-reg+)
939   ;; #x48
940   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +eax-reg+)
941   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +ecx-reg+)
942   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +edx-reg+)
943   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +ebx-reg+)
944   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +esp-reg+)
945   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +ebp-reg+)
946   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +esi-reg+)
947   (make-x86-dis '(("decS" . "(bad)")) 'op-reg +edi-reg+)
948   ;; #x50
949   (make-x86-dis "pushT" 'op-reg +rax-reg+)
950   (make-x86-dis "pushT" 'op-reg +rcx-reg+)
951   (make-x86-dis "pushT" 'op-reg +rdx-reg+)
952   (make-x86-dis "pushT" 'op-reg +rbx-reg+)
953   (make-x86-dis "pushT" 'op-reg +rsp-reg+)
954   (make-x86-dis "pushT" 'op-reg +rbp-reg+)
955   (make-x86-dis "pushT" 'op-reg +rsi-reg+)
956   (make-x86-dis "pushT" 'op-reg +rdi-reg+)
957   ;; #x58
958   (make-x86-dis "popT" 'op-reg +rax-reg+)
959   (make-x86-dis "popT" 'op-reg +rcx-reg+)
960   (make-x86-dis "popT" 'op-reg +rdx-reg+)
961   (make-x86-dis "popT" 'op-reg +rbx-reg+)
962   (make-x86-dis "popT" 'op-reg +rsp-reg+)
963   (make-x86-dis "popT" 'op-reg +rbp-reg+)
964   (make-x86-dis "popT" 'op-reg +rsi-reg+)
965   (make-x86-dis "popT" 'op-reg +rdi-reg+)
966   ;; #x60
967   (make-x86-dis '(("pushaP" . "(bad)")))
968   (make-x86-dis '(("popaP" . "(bad)")))
969   (make-x86-dis '(("boundS" . "(bad)")) 'op-g +v-mode+ 'op-e +v-mode+)
970   (make-x86-dis nil nil +x86-64-special+)
971   (make-x86-dis "(bad)")               ; seg fs
972   (make-x86-dis "(bad)")               ; seg gs
973   (make-x86-dis "(bad)")               ; op size prefix
974   (make-x86-dis "(bad)")               ; adr size prefix
975   ;; #x68
976   (make-x86-dis "pushT" 'op-i +q-mode+)
977   (make-x86-dis "imulS" 'op-g +v-mode+ 'op-e +v-mode+ 'op-i +v-mode+ )
978   (make-x86-dis "pushT" 'op-si +b-mode+)
979   (make-x86-dis "imulS" 'op-g +v-mode+ 'op-e +v-mode+ 'op-si +b-mode+ )
980   (make-x86-dis "insb" 'op-dsreg +esi-reg+ 'op-imreg +indir-dx-reg+)
981   (make-x86-dis "insR" 'op-esreg +edi-reg+ 'op-imreg +indir-dx-reg+)
982   (make-x86-dis "outsb" 'op-imreg +indir-dx-reg+ 'op-dsreg +esi-reg+)
983   (make-x86-dis "outsR" 'op-imreg +indir-dx-reg+ 'op-dsreg +esi-reg+)
984   ;; #x70
985   (make-x86-dis "joH" 'op-j +b-mode+ nil +cond-jump-mode+ )
986   (make-x86-dis "jnoH" 'op-j +b-mode+ nil +cond-jump-mode+ )
987   (make-x86-dis "jbH" 'op-j +b-mode+ nil +cond-jump-mode+ )
988   (make-x86-dis "jaeH" 'op-j +b-mode+ nil +cond-jump-mode+ )
989   (make-x86-dis "jeH" 'op-j +b-mode+ nil +cond-jump-mode+ )
990   (make-x86-dis "jneH" 'op-j +b-mode+ nil +cond-jump-mode+ )
991   (make-x86-dis "jbeH" 'op-j +b-mode+ nil +cond-jump-mode+ )
992   (make-x86-dis "jaH" 'op-j +b-mode+ nil +cond-jump-mode+ )
993   ;; #x78
994   (make-x86-dis "jsH" 'op-j +b-mode+ nil +cond-jump-mode+ )
995   (make-x86-dis "jnsH" 'op-j +b-mode+ nil +cond-jump-mode+ )
996   (make-x86-dis "jpH" 'op-j +b-mode+ nil +cond-jump-mode+ )
997   (make-x86-dis "jnpH" 'op-j +b-mode+ nil +cond-jump-mode+ )
998   (make-x86-dis "jlH" 'op-j +b-mode+ nil +cond-jump-mode+ )
999   (make-x86-dis "jgeH" 'op-j +b-mode+ nil +cond-jump-mode+ )
1000   (make-x86-dis "jleH" 'op-j +b-mode+ nil +cond-jump-mode+ )
1001   (make-x86-dis "jgH" 'op-j +b-mode+ nil +cond-jump-mode+ )
1002   ;; #x80
1003   (make-x86-dis nil nil +use-groups+ nil 0)
1004   (make-x86-dis nil nil +use-groups+ nil 1)
1005   (make-x86-dis "(bad)")
1006   (make-x86-dis nil nil +use-groups+ nil 2 )
1007   (make-x86-dis "testB" 'op-e +b-mode+ 'op-g +b-mode+)
1008   (make-x86-dis "testS" 'op-e +v-mode+ 'op-g +v-mode+)
1009   (make-x86-dis "xchgB" 'op-e +b-mode+ 'op-g +b-mode+)
1010   (make-x86-dis "xchgS" 'op-e +v-mode+ 'op-g +v-mode+)
1011   ;; #x88
1012   (make-x86-dis "movB" 'op-e +b-mode+ 'op-g +b-mode+)
1013   (make-x86-dis "movS" 'op-e +v-mode+ 'op-g +v-mode+)
1014   (make-x86-dis "movB" 'op-g +b-mode+ 'op-e +b-mode+)
1015   (make-x86-dis "movS" 'op-g +v-mode+ 'op-e +v-mode+)
1016   (make-x86-dis "movQ" 'op-e +v-mode+ 'op-seg +w-mode+)
1017   (make-x86-dis '("leaS" . :lea) 'op-g +v-mode+ 'op-m 0)
1018   (make-x86-dis "movQ" 'op-seg +w-mode+ 'op-e +v-mode+)
1019   (make-x86-dis "popU" 'op-e +v-mode+)
1020   ;; #x90
1021   (make-x86-dis "nop" 'nop-fixup 0)
1022   (make-x86-dis "xchgS" 'op-reg +ecx-reg+ 'op-imreg +eax-reg+)
1023   (make-x86-dis "xchgS" 'op-reg +edx-reg+ 'op-imreg +eax-reg+)
1024   (make-x86-dis "xchgS" 'op-reg +ebx-reg+ 'op-imreg +eax-reg+)
1025   (make-x86-dis "xchgS" 'op-reg +esp-reg+ 'op-imreg +eax-reg+)
1026   (make-x86-dis "xchgS" 'op-reg +ebp-reg+ 'op-imreg +eax-reg+)
1027   (make-x86-dis "xchgS" 'op-reg +esi-reg+ 'op-imreg +eax-reg+)
1028   (make-x86-dis "xchgS" 'op-reg +edi-reg+ 'op-imreg +eax-reg+)
1029   ;; #x98
1030   (make-x86-dis "cWtR")
1031   (make-x86-dis "cRtO")
1032   (make-x86-dis '(("JcallT" . "(bad)")) 'op-dir 0)
1033   (make-x86-dis "(bad)")               ; fwait
1034   (make-x86-dis "pushfT")
1035   (make-x86-dis "popfT")
1036   ;; "sahf" and "lahf" are unimplemented on some Intel EM64T
1037   ;; steppings, allegedly because an early AMD64 manual
1038   ;; accidentally omitted them.  It makes sense to disassemble
1039   ;; them in 64-bit mode, but it may require some thought
1040   ;; before using them in compiled code.
1041   (make-x86-dis "sahf")
1042   (make-x86-dis "lahf")
1043   ;; #xa0
1044   (make-x86-dis "movB" 'op-imreg +al-reg+ 'op-off64 +b-mode+)
1045   (make-x86-dis "movS" 'op-imreg +eax-reg+ 'op-off64 +v-mode+)
1046   (make-x86-dis "movB" 'op-off64 +b-mode+  'op-imreg +al-reg+)
1047   (make-x86-dis "movS" 'op-off64 +v-mode+ 'op-imreg +eax-reg+)
1048   (make-x86-dis "movsb" 'op-dsreg +esi-reg+ 'op-dsreg +esi-reg+)
1049   (make-x86-dis "movsR" 'op-esreg +edi-reg+ 'op-dsreg +esi-reg+)
1050   (make-x86-dis "cmpsb" 'op-dsreg +esi-reg+ 'op-dsreg +esi-reg+)
1051   (make-x86-dis "cmpsR" 'op-dsreg +esi-reg+ 'op-esreg +edi-reg+)
1052   ;; #xa8
1053   (make-x86-dis "testB" 'op-imreg +al-reg+ 'op-i +b-mode+)
1054   (make-x86-dis "testS" 'op-imreg +eax-reg+ 'op-i +v-mode+)
1055   (make-x86-dis "stosB" 'op-dsreg +esi-reg+ 'op-imreg +al-reg+)
1056   (make-x86-dis "stosS" 'op-esreg +edi-reg+ 'op-imreg +eax-reg+)
1057   (make-x86-dis "lodsB" 'op-imreg +al-reg+ 'op-dsreg +esi-reg+)
1058   (make-x86-dis "lodsS" 'op-imreg +eax-reg+ 'op-dsreg +esi-reg+)
1059   (make-x86-dis "scasB" 'op-imreg +al-reg+ 'op-dsreg +esi-reg+)
1060   (make-x86-dis "scasS" 'op-imreg +eax-reg+ 'op-esreg +edi-reg+)
1061   ;; #xb0
1062   (make-x86-dis "movB" 'op-reg +al-reg+ 'op-i +b-mode+)
1063   (make-x86-dis "movB" 'op-reg +cl-reg+ 'op-i +b-mode+)
1064   (make-x86-dis "movB" 'op-reg +dl-reg+ 'op-i +b-mode+)
1065   (make-x86-dis "movB" 'op-reg +bl-reg+ 'op-i +b-mode+)
1066   (make-x86-dis "movB" 'op-reg +ah-reg+ 'op-i +b-mode+)
1067   (make-x86-dis "movB" 'op-reg +ch-reg+ 'op-i +b-mode+)
1068   (make-x86-dis "movB" 'op-reg +dh-reg+ 'op-i +b-mode+)
1069   (make-x86-dis "movB" 'op-reg +bh-reg+ 'op-i +b-mode+)
1070   ;; #xb8
1071   (make-x86-dis "movS" 'op-reg +eax-reg+ 'op-i64 +v-mode+)
1072   (make-x86-dis "movS" 'op-reg +ecx-reg+ 'op-i64 +v-mode+)
1073   (make-x86-dis "movS" 'op-reg +edx-reg+ 'op-i64 +v-mode+)
1074   (make-x86-dis "movS" 'op-reg +ebx-reg+ 'op-i64 +v-mode+)
1075   (make-x86-dis "movS" 'op-reg +esp-reg+ 'op-i64 +v-mode+)
1076   (make-x86-dis "movS" 'op-reg +ebp-reg+ 'op-i64 +v-mode+)
1077   (make-x86-dis "movS" 'op-reg +esi-reg+ 'op-i64 +v-mode+)
1078   (make-x86-dis "movS" 'op-reg +edi-reg+ 'op-i64 +v-mode+)
1079   ;; #xc0
1080   (make-x86-dis nil nil +use-groups+ nil 3)
1081   (make-x86-dis nil nil +use-groups+ nil 4)
1082   (make-x86-dis '("retT" . :jump) 'op-i +w-mode+)
1083   (make-x86-dis '("retT" . :jump))
1084   (make-x86-dis '(("lesS" . "(bad)")) 'op-g +v-mode+ 'op-m +f-mode+)
1085   (make-x86-dis "ldsS" 'op-g +v-mode+ 'op-m +f-mode+)
1086   (make-x86-dis "movA" 'op-e +b-mode+ 'op-i +b-mode+)
1087   (make-x86-dis "movQ" 'op-e +v-mode+ 'op-i +v-mode+)
1088   ;; #xc8
1089   (make-x86-dis "enterT" 'op-i +w-mode+ 'op-i +b-mode+)
1090   (make-x86-dis "leaveT")
1091   (make-x86-dis "lretP" 'op-i +w-mode+)
1092   (make-x86-dis "lretP")
1093   (make-x86-dis "int3")
1094   (make-x86-dis nil nil +uuocode+)
1095   (make-x86-dis '(("into" . "(bad)")))
1096   (make-x86-dis "iretP")
1097   ;; #xd0
1098   (make-x86-dis nil nil +use-groups+ nil 5)
1099   (make-x86-dis nil nil +use-groups+ nil 6)
1100   (make-x86-dis nil nil +use-groups+ nil 7)
1101   (make-x86-dis nil nil +use-groups+ nil 8)
1102   (make-x86-dis '(("aam" . "(bad)")) 'op-si +b-mode+)
1103   (make-x86-dis '(("aad" . "(bad)")) 'op-si +b-mode+)
1104   (make-x86-dis "(bad)")
1105   (make-x86-dis "xlat" 'op-dsreg +ebx-reg+)
1106   ;; #xd8
1107   (make-x86-dis nil nil +floatcode+)
1108   (make-x86-dis nil nil +floatcode+)
1109   (make-x86-dis nil nil +floatcode+)
1110   (make-x86-dis nil nil +floatcode+)
1111   (make-x86-dis nil nil +floatcode+)
1112   (make-x86-dis nil nil +floatcode+)
1113   (make-x86-dis nil nil +floatcode+)
1114   (make-x86-dis nil nil +floatcode+)
1115   ;; #xe0
1116   (make-x86-dis "loopneFH" 'op-j +b-mode+ nil +loop-jcxz-mode+ )
1117   (make-x86-dis "loopeFH" 'op-j +b-mode+ nil +loop-jcxz-mode+ )
1118   (make-x86-dis "loopFH" 'op-j +b-mode+ nil +loop-jcxz-mode+ )
1119   (make-x86-dis "jEcxzH" 'op-j +b-mode+ nil +loop-jcxz-mode+ )
1120   (make-x86-dis "inB" 'op-imreg +al-reg+ 'op-i +b-mode+)
1121   (make-x86-dis "inS" 'op-imreg +eax-reg+ 'op-i +b-mode+)
1122   (make-x86-dis "outB" 'op-i +b-mode+ 'op-imreg +al-reg+)
1123   (make-x86-dis "outS" 'op-i +b-mode+ 'op-imreg +eax-reg+)
1124   ;; #xe8
1125   (make-x86-dis '("callT" . :call) 'op-j +v-mode+)
1126   (make-x86-dis '("jmpT" . :jump) 'op-j +v-mode+)
1127   (make-x86-dis '(("JjmpT" . "(bad)") . :jump) 'op-dir 0)
1128   (make-x86-dis '("jmp" . :jump)  'op-j +b-mode+)
1129   (make-x86-dis "inB" 'op-imreg +al-reg+ 'op-imreg +indir-dx-reg+)
1130   (make-x86-dis "inS" 'op-imreg +eax-reg+ 'op-imreg +indir-dx-reg+)
1131   (make-x86-dis "outB" 'op-imreg +indir-dx-reg+ 'op-imreg +al-reg+)
1132   (make-x86-dis "outS" 'op-imreg +indir-dx-reg+ 'op-imreg +eax-reg+)
1133   ;; #xf0
1134   (make-x86-dis "(bad)")               ; lock prefix
1135   (make-x86-dis "icebp")
1136   (make-x86-dis "(bad)")               ; repne
1137   (make-x86-dis "(bad)")               ; repz
1138   (make-x86-dis "hlt")
1139   (make-x86-dis "cmc")
1140   (make-x86-dis nil nil +use-groups+ nil 9)
1141   (make-x86-dis nil nil +use-groups+ nil 10)
1142   ;; #xf8
1143   (make-x86-dis "clc")
1144   (make-x86-dis "stc")
1145   (make-x86-dis "cli")
1146   (make-x86-dis "sti")
1147   (make-x86-dis "cld")
1148   (make-x86-dis "std")
1149   (make-x86-dis nil nil +use-groups+ nil 11)
1150   (make-x86-dis nil nil +use-groups+ nil 12)
1151   ))
1152
1153(defparameter *disx86-twobyte*
1154  (vector
1155   ;; #x00
1156   (make-x86-dis nil nil +use-groups+ nil 13)
1157   (make-x86-dis nil nil +use-groups+ nil 14)
1158   (make-x86-dis "larS" 'op-g +v-mode+ 'op-e +w-mode+)
1159   (make-x86-dis "lslS" 'op-g +v-mode+ 'op-e +w-mode+)
1160   (make-x86-dis "(bad)")
1161   (make-x86-dis "syscall")
1162   (make-x86-dis "clts")
1163   (make-x86-dis "sysretP")
1164   ;; #x08
1165   (make-x86-dis "invd")
1166   (make-x86-dis "wbinvd")
1167   (make-x86-dis "(bad)")
1168   (make-x86-dis "ud2a" 'op-i +b-mode+)
1169   (make-x86-dis "(bad)")
1170   (make-x86-dis nil nil +use-groups+ nil 22)
1171   (make-x86-dis "femms")
1172   (make-x86-dis "" 'op-mmx 0 'op-em +v-mode+ 'op-3dnowsuffix 0) ; See OP-3DNowSuffix.
1173   ;; #x10
1174   (make-x86-dis nil nil +use-prefix-user-table+ nil 8)
1175   (make-x86-dis nil nil +use-prefix-user-table+ nil 9)
1176   (make-x86-dis nil nil +use-prefix-user-table+ nil 30)
1177   (make-x86-dis "movlpX" 'op-ex +v-mode+ 'op-xmm 0 'SIMD-Fixup #\h)
1178   (make-x86-dis "unpcklpX" 'op-xmm 0 'op-ex +v-mode+)
1179   (make-x86-dis "unpckhpX" 'op-xmm 0 'op-ex +v-mode+)
1180   (make-x86-dis nil nil +use-prefix-user-table+ nil 31)
1181   (make-x86-dis "movhpX" 'op-ex +v-mode+ 'op-xmm 0 'SIMD-Fixup #\l)
1182   ;; #x18
1183   (make-x86-dis nil nil +use-groups+ nil 21)
1184   (make-x86-dis "(bad)")
1185   (make-x86-dis "(bad)")
1186   (make-x86-dis "(bad)")
1187   (make-x86-dis "(bad)")
1188   (make-x86-dis "(bad)")
1189   (make-x86-dis "(bad)")
1190   (make-x86-dis "(bad)")
1191   ;; #x20
1192   (make-x86-dis "movL" 'op-rd +m-mode+ 'op-c +m-mode+)
1193   (make-x86-dis "movL" 'op-rd +m-mode+ 'op-d +m-mode+)
1194   (make-x86-dis "movL" 'op-c +m-mode+ 'op-rd +m-mode+)
1195   (make-x86-dis "movL" 'op-d +m-mode+ 'op-rd +m-mode+)
1196   (make-x86-dis "movL" 'op-rd +d-mode+ 'op-t +d-mode+)
1197   (make-x86-dis "(bad)")
1198   (make-x86-dis "movL" 'op-t +d-mode+ 'op-rd +d-mode+)
1199   (make-x86-dis "(bad)")
1200   ;; #x28
1201   (make-x86-dis "movapX" 'op-xmm 0 'op-ex +v-mode+)
1202   (make-x86-dis "movapX" 'op-ex +v-mode+ 'op-xmm 0)
1203   (make-x86-dis nil nil +use-prefix-user-table+ nil 2)
1204   (make-x86-dis "movntpX" 'op-e +v-mode+ 'op-xmm 0)
1205   (make-x86-dis nil nil +use-prefix-user-table+ nil 4)
1206   (make-x86-dis nil nil +use-prefix-user-table+ nil 3)
1207   (make-x86-dis "ucomisX" 'op-xmm 0 'op-ex +v-mode+)
1208   (make-x86-dis "comisX" 'op-xmm 0 'op-ex +v-mode+)
1209   ;; #x30
1210   (make-x86-dis "wrmsr")
1211   (make-x86-dis "rdtsc")
1212   (make-x86-dis "rdmsr")
1213   (make-x86-dis "rdpmc")
1214   (make-x86-dis "sysenter")
1215   (make-x86-dis "sysexit")
1216   (make-x86-dis "(bad)")
1217   (make-x86-dis "(bad)")
1218   ;; #x38
1219   (make-x86-dis "(bad)")
1220   (make-x86-dis "(bad)")
1221   (make-x86-dis "(bad)")
1222   (make-x86-dis "(bad)")
1223   (make-x86-dis "(bad)")
1224   (make-x86-dis "(bad)")
1225   (make-x86-dis "(bad)")
1226   (make-x86-dis "(bad)")
1227   ;; #x40
1228   (make-x86-dis "cmovoS" 'op-g +v-mode+ 'op-e +v-mode+)
1229   (make-x86-dis "cmovnoS" 'op-g +v-mode+ 'op-e +v-mode+)
1230   (make-x86-dis "cmovbS" 'op-g +v-mode+ 'op-e +v-mode+)
1231   (make-x86-dis "cmovaeS" 'op-g +v-mode+ 'op-e +v-mode+)
1232   (make-x86-dis "cmoveS" 'op-g +v-mode+ 'op-e +v-mode+)
1233   (make-x86-dis "cmovneS" 'op-g +v-mode+ 'op-e +v-mode+)
1234   (make-x86-dis "cmovbeS" 'op-g +v-mode+ 'op-e +v-mode+)
1235   (make-x86-dis "cmovaS" 'op-g +v-mode+ 'op-e +v-mode+)
1236   ;; #x48
1237   (make-x86-dis "cmovsS" 'op-g +v-mode+ 'op-e +v-mode+)
1238   (make-x86-dis "cmovnsS" 'op-g +v-mode+ 'op-e +v-mode+)
1239   (make-x86-dis "cmovpS" 'op-g +v-mode+ 'op-e +v-mode+)
1240   (make-x86-dis "cmovnpS" 'op-g +v-mode+ 'op-e +v-mode+)
1241   (make-x86-dis "cmovlS" 'op-g +v-mode+ 'op-e +v-mode+)
1242   (make-x86-dis "cmovgeS" 'op-g +v-mode+ 'op-e +v-mode+)
1243   (make-x86-dis "cmovleS" 'op-g +v-mode+ 'op-e +v-mode+)
1244   (make-x86-dis "cmovgS" 'op-g +v-mode+ 'op-e +v-mode+)
1245   ;; #x50
1246   (make-x86-dis "movmskpX" 'op-g +dq-mode+ 'op-xs +v-mode+)
1247   (make-x86-dis nil nil +use-prefix-user-table+ nil 13)
1248   (make-x86-dis nil nil +use-prefix-user-table+ nil 12)
1249   (make-x86-dis nil nil +use-prefix-user-table+ nil 11)
1250   (make-x86-dis "andpX" 'op-xmm 0 'op-ex +v-mode+)
1251   (make-x86-dis "andnpX" 'op-xmm 0 'op-ex +v-mode+)
1252   (make-x86-dis "orpX" 'op-xmm 0 'op-ex +v-mode+)
1253   (make-x86-dis "xorpX" 'op-xmm 0 'op-ex +v-mode+)
1254   ;; #x58
1255   (make-x86-dis nil nil +use-prefix-user-table+ nil 0)
1256   (make-x86-dis nil nil +use-prefix-user-table+ nil 10)
1257   (make-x86-dis nil nil +use-prefix-user-table+ nil 17)
1258   (make-x86-dis nil nil +use-prefix-user-table+ nil 16)
1259   (make-x86-dis nil nil +use-prefix-user-table+ nil 14)
1260   (make-x86-dis nil nil +use-prefix-user-table+ nil 7)
1261   (make-x86-dis nil nil +use-prefix-user-table+ nil 5)
1262   (make-x86-dis nil nil +use-prefix-user-table+ nil 6)
1263   ;; #x60
1264   (make-x86-dis "punpcklbw" 'op-mmx 0 'op-em +v-mode+)
1265   (make-x86-dis "punpcklwd" 'op-mmx 0 'op-em +v-mode+)
1266   (make-x86-dis "punpckldq" 'op-mmx 0 'op-em +v-mode+)
1267   (make-x86-dis "packsswb" 'op-mmx 0 'op-em +v-mode+)
1268   (make-x86-dis "pcmpgtb" 'op-mmx 0 'op-em +v-mode+)
1269   (make-x86-dis "pcmpgtw" 'op-mmx 0 'op-em +v-mode+)
1270   (make-x86-dis "pcmpgtd" 'op-mmx 0 'op-em +v-mode+)
1271   (make-x86-dis "packuswb" 'op-mmx 0 'op-em +v-mode+)
1272   ;; #x68
1273   (make-x86-dis "punpckhbw" 'op-mmx 0 'op-em +v-mode+)
1274   (make-x86-dis "punpckhwd" 'op-mmx 0 'op-em +v-mode+)
1275   (make-x86-dis "punpckhdq" 'op-mmx 0 'op-em +v-mode+)
1276   (make-x86-dis "packssdw" 'op-mmx 0 'op-em +v-mode+)
1277   (make-x86-dis nil nil +use-prefix-user-table+ nil 26)
1278   (make-x86-dis nil nil +use-prefix-user-table+ nil 24)
1279   (make-x86-dis "movd" 'op-mmx 0 'op-e +dq-mode+)
1280   (make-x86-dis nil nil +use-prefix-user-table+ nil 19)
1281   ;; #x70
1282   (make-x86-dis nil nil +use-prefix-user-table+ nil 22)
1283   (make-x86-dis nil nil +use-groups+ nil 17)
1284   (make-x86-dis nil nil +use-groups+ nil 18)
1285   (make-x86-dis nil nil +use-groups+ nil 19)
1286   (make-x86-dis "pcmpeqb" 'op-mmx 0 'op-em +v-mode+)
1287   (make-x86-dis "pcmpeqw" 'op-mmx 0 'op-em +v-mode+)
1288   (make-x86-dis "pcmpeqd" 'op-mmx 0 'op-em +v-mode+)
1289   (make-x86-dis "emms")
1290   ;; #x78
1291   (make-x86-dis "(bad)")
1292   (make-x86-dis "(bad)")
1293   (make-x86-dis "(bad)")
1294   (make-x86-dis "(bad)")
1295   (make-x86-dis nil nil +use-prefix-user-table+ nil 28)
1296   (make-x86-dis nil nil +use-prefix-user-table+ nil 29)
1297   (make-x86-dis nil nil +use-prefix-user-table+ nil 23)
1298   (make-x86-dis nil nil +use-prefix-user-table+ nil 20)
1299   ;; #x80
1300   (make-x86-dis "joH" 'op-j +v-mode+ nil +cond-jump-mode+)
1301   (make-x86-dis "jnoH" 'op-j +v-mode+ nil +cond-jump-mode+)
1302   (make-x86-dis "jbH" 'op-j +v-mode+ nil +cond-jump-mode+)
1303   (make-x86-dis "jaeH" 'op-j +v-mode+ nil +cond-jump-mode+)
1304   (make-x86-dis "jeH" 'op-j +v-mode+ nil +cond-jump-mode+)
1305   (make-x86-dis "jneH" 'op-j +v-mode+ nil +cond-jump-mode+)
1306   (make-x86-dis "jbeH" 'op-j +v-mode+ nil +cond-jump-mode+)
1307   (make-x86-dis "jaH" 'op-j +v-mode+ nil +cond-jump-mode+)
1308   ;; #x88
1309   (make-x86-dis "jsH" 'op-j +v-mode+ nil +cond-jump-mode+)
1310   (make-x86-dis "jnsH" 'op-j +v-mode+ nil +cond-jump-mode+)
1311   (make-x86-dis "jpH" 'op-j +v-mode+ nil +cond-jump-mode+)
1312   (make-x86-dis "jnpH" 'op-j +v-mode+ nil +cond-jump-mode+)
1313   (make-x86-dis "jlH" 'op-j +v-mode+ nil +cond-jump-mode+)
1314   (make-x86-dis "jgeH" 'op-j +v-mode+ nil +cond-jump-mode+)
1315   (make-x86-dis "jleH" 'op-j +v-mode+ nil +cond-jump-mode+)
1316   (make-x86-dis "jgH" 'op-j +v-mode+ nil +cond-jump-mode+)
1317   ;; #x90
1318   (make-x86-dis "seto" 'op-e +b-mode+)
1319   (make-x86-dis "setno" 'op-e +b-mode+)
1320   (make-x86-dis "setb" 'op-e +b-mode+)
1321   (make-x86-dis "setae" 'op-e +b-mode+)
1322   (make-x86-dis "sete" 'op-e +b-mode+)
1323   (make-x86-dis "setne" 'op-e +b-mode+)
1324   (make-x86-dis "setbe" 'op-e +b-mode+)
1325   (make-x86-dis "seta" 'op-e +b-mode+)
1326   ;; #x98
1327   (make-x86-dis "sets" 'op-e +b-mode+)
1328   (make-x86-dis "setns" 'op-e +b-mode+)
1329   (make-x86-dis "setp" 'op-e +b-mode+)
1330   (make-x86-dis "setnp" 'op-e +b-mode+)
1331   (make-x86-dis "setl" 'op-e +b-mode+)
1332   (make-x86-dis "setge" 'op-e +b-mode+)
1333   (make-x86-dis "setle" 'op-e +b-mode+)
1334   (make-x86-dis "setg" 'op-e +b-mode+)
1335   ;; #xa0
1336   (make-x86-dis "pushT" 'op-reg +fs-reg+)
1337   (make-x86-dis "popT" 'op-reg +fs-reg+)
1338   (make-x86-dis "cpuid")
1339   (make-x86-dis "btS" 'op-e +v-mode+ 'op-g +v-mode+)
1340   (make-x86-dis "shldS" 'op-e +v-mode+ 'op-g +v-mode+ 'op-i +b-mode+)
1341   (make-x86-dis "shldS" 'op-e +v-mode+ 'op-g +v-mode+ 'op-imreg +cl-reg+)
1342   (make-x86-dis nil nil +use-groups+ nil 24)
1343   (make-x86-dis nil nil +use-groups+ nil 23)
1344   ;; #xa8
1345   (make-x86-dis "pushT" 'op-reg +gs-reg+)
1346   (make-x86-dis "popT" 'op-reg +gs-reg+)
1347   (make-x86-dis "rsm")
1348   (make-x86-dis "btsS" 'op-e +v-mode+ 'op-g +v-mode+)
1349   (make-x86-dis "shrdS" 'op-e +v-mode+ 'op-g +v-mode+ 'op-i +b-mode+)
1350   (make-x86-dis "shrdS" 'op-e +v-mode+ 'op-g +v-mode+ 'op-imreg +cl-reg+)
1351   (make-x86-dis nil nil +use-groups+ nil 20)
1352   (make-x86-dis "imulS" 'op-g +v-mode+ 'op-e +v-mode+)
1353   ;; #xb0
1354   (make-x86-dis "cmpxchgB" 'op-e +b-mode+ 'op-g +b-mode+)
1355   (make-x86-dis "cmpxchgS" 'op-e +v-mode+ 'op-g +v-mode+)
1356   (make-x86-dis "lssS" 'op-g +v-mode+ 'op-m +f-mode+)
1357   (make-x86-dis "btrS" 'op-e +v-mode+ 'op-g +v-mode+)
1358   (make-x86-dis "lfsS" 'op-g +v-mode+ 'op-m +f-mode+)
1359   (make-x86-dis "lgsS" 'op-g +v-mode+ 'op-m +f-mode+)
1360   (make-x86-dis "movzbR" 'op-g +v-mode+ 'op-e +b-mode+)
1361   (make-x86-dis "movzwR" 'op-g +v-mode+ 'op-e +w-mode+) ; yes there really is movzww !
1362   ;; #xb8
1363   (make-x86-dis "(bad)")
1364   (make-x86-dis "ud2b")
1365   (make-x86-dis nil nil +use-groups+ nil 15)
1366   (make-x86-dis "btcS" 'op-e +v-mode+ 'op-g +v-mode+)
1367   (make-x86-dis "bsfS" 'op-g +v-mode+ 'op-e +v-mode+)
1368   (make-x86-dis "bsrS" 'op-g +v-mode+ 'op-e +v-mode+)
1369   (make-x86-dis "movsbR" 'op-g +v-mode+ 'op-e +b-mode+)
1370   (make-x86-dis "movswR" 'op-g +v-mode+ 'op-e +w-mode+) ; yes there really is movsww !
1371   ;; #xc0
1372   (make-x86-dis "xaddB" 'op-e +b-mode+ 'op-g +b-mode+)
1373   (make-x86-dis "xaddS" 'op-e +v-mode+ 'op-g +v-mode+)
1374   (make-x86-dis nil nil +use-prefix-user-table+ nil 1)
1375   (make-x86-dis "movntiS" 'op-e +v-mode+ 'op-g +v-mode+)
1376   (make-x86-dis "pinsrw" 'op-mmx 0 'op-e +dqw-mode+ 'op-i +b-mode+)
1377   (make-x86-dis "pextrw" 'op-g +dq-mode+ 'op-ms +v-mode+ 'op-i +b-mode+)
1378   (make-x86-dis "shufpX" 'op-xmm 0 'op-ex +v-mode+ 'op-i +b-mode+)
1379   (make-x86-dis nil nil +use-groups+ nil 16)
1380   ;; #xc8
1381   (make-x86-dis "bswap" 'op-reg +eax-reg+)
1382   (make-x86-dis "bswap" 'op-reg +ecx-reg+)
1383   (make-x86-dis "bswap" 'op-reg +edx-reg+)
1384   (make-x86-dis "bswap" 'op-reg +ebx-reg+)
1385   (make-x86-dis "bswap" 'op-reg +esp-reg+)
1386   (make-x86-dis "bswap" 'op-reg +ebp-reg+)
1387   (make-x86-dis "bswap" 'op-reg +esi-reg+)
1388   (make-x86-dis "bswap" 'op-reg +edi-reg+)
1389   ;; #xd0
1390   (make-x86-dis nil nil +use-prefix-user-table+ nil 27)
1391   (make-x86-dis "psrlw" 'op-mmx 0 'op-em +v-mode+)
1392   (make-x86-dis "psrld" 'op-mmx 0 'op-em +v-mode+)
1393   (make-x86-dis "psrlq" 'op-mmx 0 'op-em +v-mode+)
1394   (make-x86-dis "paddq" 'op-mmx 0 'op-em +v-mode+)
1395   (make-x86-dis "pmullw" 'op-mmx 0 'op-em +v-mode+)
1396   (make-x86-dis nil nil +use-prefix-user-table+ nil 21)
1397   (make-x86-dis "pmovmskb" 'op-g +dq-mode+ 'op-ms +v-mode+)
1398   ;; #xd8
1399   (make-x86-dis "psubusb" 'op-mmx 0 'op-em +v-mode+)
1400   (make-x86-dis "psubusw" 'op-mmx 0 'op-em +v-mode+)
1401   (make-x86-dis "pminub" 'op-mmx 0 'op-em +v-mode+)
1402   (make-x86-dis "pand" 'op-mmx 0 'op-em +v-mode+)
1403   (make-x86-dis "paddusb" 'op-mmx 0 'op-em +v-mode+)
1404   (make-x86-dis "paddusw" 'op-mmx 0 'op-em +v-mode+)
1405   (make-x86-dis "pmaxub" 'op-mmx 0 'op-em +v-mode+)
1406   (make-x86-dis "pandn" 'op-mmx 0 'op-em +v-mode+)
1407   ;; #xe0
1408   (make-x86-dis "pavgb" 'op-mmx 0 'op-em +v-mode+)
1409   (make-x86-dis "psraw" 'op-mmx 0 'op-em +v-mode+)
1410   (make-x86-dis "psrad" 'op-mmx 0 'op-em +v-mode+)
1411   (make-x86-dis "pavgw" 'op-mmx 0 'op-em +v-mode+)
1412   (make-x86-dis "pmulhuw" 'op-mmx 0 'op-em +v-mode+)
1413   (make-x86-dis "pmulhw" 'op-mmx 0 'op-em +v-mode+)
1414   (make-x86-dis nil nil +use-prefix-user-table+ nil 15)
1415   (make-x86-dis nil nil +use-prefix-user-table+ nil 25)
1416   ;; #xe8
1417   (make-x86-dis "psubsb" 'op-mmx 0 'op-em +v-mode+)
1418   (make-x86-dis "psubsw" 'op-mmx 0 'op-em +v-mode+)
1419   (make-x86-dis "pminsw" 'op-mmx 0 'op-em +v-mode+)
1420   (make-x86-dis "por" 'op-mmx 0 'op-em +v-mode+)
1421   (make-x86-dis "paddsb" 'op-mmx 0 'op-em +v-mode+)
1422   (make-x86-dis "paddsw" 'op-mmx 0 'op-em +v-mode+)
1423   (make-x86-dis "pmaxsw" 'op-mmx 0 'op-em +v-mode+)
1424   (make-x86-dis "pxor" 'op-mmx 0 'op-em +v-mode+)
1425   ;; #xf0
1426   (make-x86-dis nil nil +use-prefix-user-table+ nil 32)
1427   (make-x86-dis "psllw" 'op-mmx 0 'op-em +v-mode+)
1428   (make-x86-dis "pslld" 'op-mmx 0 'op-em +v-mode+)
1429   (make-x86-dis "psllq" 'op-mmx 0 'op-em +v-mode+)
1430   (make-x86-dis "pmuludq" 'op-mmx 0 'op-em +v-mode+)
1431   (make-x86-dis "pmaddwd" 'op-mmx 0 'op-em +v-mode+)
1432   (make-x86-dis "psadbw" 'op-mmx 0 'op-em +v-mode+)
1433   (make-x86-dis nil nil +use-prefix-user-table+ nil 18)
1434   ;; #xf8
1435   (make-x86-dis "psubb" 'op-mmx 0 'op-em +v-mode+)
1436   (make-x86-dis "psubw" 'op-mmx 0 'op-em +v-mode+)
1437   (make-x86-dis "psubd" 'op-mmx 0 'op-em +v-mode+)
1438   (make-x86-dis "psubq" 'op-mmx 0 'op-em +v-mode+)
1439   (make-x86-dis "paddb" 'op-mmx 0 'op-em +v-mode+)
1440   (make-x86-dis "paddw" 'op-mmx 0 'op-em +v-mode+)
1441   (make-x86-dis "paddd" 'op-mmx 0 'op-em +v-mode+)
1442   (make-x86-dis "(bad)")
1443   ))
1444
1445(defparameter *onebyte-has-modrm*
1446  (make-array 256 :element-type 'bit
1447              :initial-contents '(
1448  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1449  #|       -------------------------------        |#
1450  #| 00 |# 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0  #| 00 |#
1451  #| 10 |# 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0  #| 10 |#
1452  #| 20 |# 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0  #| 20 |#
1453  #| 30 |# 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0  #| 30 |#
1454  #| 40 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 40 |#
1455  #| 50 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 50 |#
1456  #| 60 |# 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0  #| 60 |#
1457  #| 70 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 70 |#
1458  #| 80 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| 80 |#
1459  #| 90 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 90 |#
1460  #| a0 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| a0 |#
1461  #| b0 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| b0 |#
1462  #| c0 |# 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0  #| c0 |#
1463  #| d0 |# 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1  #| d0 |#
1464  #| e0 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| e0 |#
1465  #| f0 |# 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1  #| f0 |#
1466  #|       -------------------------------        |#
1467  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1468)))
1469
1470
1471(defparameter *twobyte-has-modrm*
1472  (make-array 256 :element-type 'bit
1473              :initial-contents '(
1474  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1475  #|       -------------------------------        |#
1476  #| 00 |# 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1  #| 0f |#
1477  #| 10 |# 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0  #| 1f |#
1478  #| 20 |# 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1  #| 2f |#
1479  #| 30 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 3f |#
1480  #| 40 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| 4f |#
1481  #| 50 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| 5f |#
1482  #| 60 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| 6f |#
1483  #| 70 |# 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1  #| 7f |#
1484  #| 80 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 8f |#
1485  #| 90 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| 9f |#
1486  #| a0 |# 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1  #| af |#
1487  #| b0 |# 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1  #| bf |#
1488  #| c0 |# 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0  #| cf |#
1489  #| d0 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| df |#
1490  #| e0 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  #| ef |#
1491  #| f0 |# 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0  #| ff |#
1492  #|       -------------------------------        |#
1493  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1494)))
1495
1496(defparameter *twobyte-uses-sse-prefix*
1497  (make-array 256 :element-type 'bit
1498              :initial-contents '(
1499  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1500  #|       -------------------------------        |#
1501  #| 00 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 0f |#
1502  #| 10 |# 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0  #| 1f |#
1503  #| 20 |# 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0  #| 2f |#
1504  #| 30 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 3f |#
1505  #| 40 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 4f |#
1506  #| 50 |# 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1  #| 5f |#
1507  #| 60 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1  #| 6f |#
1508  #| 70 |# 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1  #| 7f |#
1509  #| 80 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 8f |#
1510  #| 90 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 9f |#
1511  #| a0 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| af |#
1512  #| b0 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| bf |#
1513  #| c0 |# 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0  #| cf |#
1514  #| d0 |# 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0  #| df |#
1515  #| e0 |# 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0  #| ef |#
1516  #| f0 |# 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0  #| ff |#
1517  #|       -------------------------------        |#
1518  #|       0 1 2 3 4 5 6 7 8 9 a b c d e f        |#
1519)))
1520
1521
1522
1523(defparameter *grps*
1524  (vector
1525   ;; GRP1b
1526   (vector
1527    (make-x86-dis "addA" 'op-e +b-mode+ 'op-i +b-mode+)
1528    (make-x86-dis "orA" 'op-e +b-mode+ 'op-i +b-mode+)
1529    (make-x86-dis "adcA" 'op-e +b-mode+ 'op-i +b-mode+)
1530    (make-x86-dis "sbbA" 'op-e +b-mode+ 'op-i +b-mode+)
1531    (make-x86-dis "andA" 'op-e +b-mode+ 'op-i +b-mode+)
1532    (make-x86-dis "subA" 'op-e +b-mode+ 'op-i +b-mode+)
1533    (make-x86-dis "xorA" 'op-e +b-mode+ 'op-i +b-mode+)
1534    (make-x86-dis "cmpA" 'op-e +b-mode+ 'op-i +b-mode+))
1535   ;; GRP1S
1536   (vector
1537    (make-x86-dis '("addQ" . :addi32) 'op-e +v-mode+ 'op-i +v-mode+)
1538    (make-x86-dis "orQ" 'op-e +v-mode+ 'op-i +v-mode+)
1539    (make-x86-dis "adcQ" 'op-e +v-mode+ 'op-i +v-mode+)
1540    (make-x86-dis "sbbQ" 'op-e +v-mode+ 'op-i +v-mode+)
1541    (make-x86-dis "andQ" 'op-e +v-mode+ 'op-i +v-mode+)
1542    (make-x86-dis '("subQ" . :subi32) 'op-e +v-mode+ 'op-i +v-mode+)
1543    (make-x86-dis "xorQ" 'op-e +v-mode+ 'op-i +v-mode+)
1544    (make-x86-dis "cmpQ" 'op-e +v-mode+ 'op-i +v-mode+))
1545   ;; GRP1Ss
1546   (vector
1547    (make-x86-dis '("addQ" . :addi64) 'op-e +v-mode+ 'op-si +b-mode+)
1548    (make-x86-dis "orQ" 'op-e +v-mode+ 'op-si +b-mode+)
1549    (make-x86-dis "adcQ" 'op-e +v-mode+ 'op-si +b-mode+)
1550    (make-x86-dis "sbbQ" 'op-e +v-mode+ 'op-si +b-mode+)
1551    (make-x86-dis "andQ" 'op-e +v-mode+ 'op-si +b-mode+)
1552    (make-x86-dis '("subQ" . :subi64) 'op-e +v-mode+ 'op-si +b-mode+)
1553    (make-x86-dis "xorQ" 'op-e +v-mode+ 'op-si +b-mode+)
1554    (make-x86-dis "cmpQ" 'op-e +v-mode+ 'op-si +b-mode+))
1555   ;; GRP2b
1556   (vector
1557    (make-x86-dis "rolA" 'op-e +b-mode+ 'op-i +b-mode+)
1558    (make-x86-dis "rorA" 'op-e +b-mode+ 'op-i +b-mode+)
1559    (make-x86-dis "rclA" 'op-e +b-mode+ 'op-i +b-mode+)
1560    (make-x86-dis "rcrA" 'op-e +b-mode+ 'op-i +b-mode+)
1561    (make-x86-dis "shlA" 'op-e +b-mode+ 'op-i +b-mode+)
1562    (make-x86-dis "shrA" 'op-e +b-mode+ 'op-i +b-mode+)
1563    (make-x86-dis "(bad)")
1564    (make-x86-dis "sarA" 'op-e +b-mode+ 'op-i +b-mode+))
1565   ;; GRP2S
1566   (vector
1567    (make-x86-dis "rolQ" 'op-e +v-mode+ 'op-i +b-mode+)
1568    (make-x86-dis "rorQ" 'op-e +v-mode+ 'op-i +b-mode+)
1569    (make-x86-dis "rclQ" 'op-e +v-mode+ 'op-i +b-mode+)
1570    (make-x86-dis "rcrQ" 'op-e +v-mode+ 'op-i +b-mode+)
1571    (make-x86-dis "shlQ" 'op-e +v-mode+ 'op-i +b-mode+)
1572    (make-x86-dis "shrQ" 'op-e +v-mode+ 'op-i +b-mode+)
1573    (make-x86-dis "(bad)")
1574    (make-x86-dis "sarQ" 'op-e +v-mode+ 'op-i +b-mode+))
1575   ;; GRP2b-one
1576   (vector
1577    (make-x86-dis "rolA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1578    (make-x86-dis "rorA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1579    (make-x86-dis "rclA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1580    (make-x86-dis "rcrA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1581    (make-x86-dis "shlA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1582    (make-x86-dis "shrA" 'op-e +b-mode+ 'op-i +const-1-mode+)
1583    (make-x86-dis "(bad)")
1584    (make-x86-dis "sarA" 'op-e +b-mode+ 'op-i +const-1-mode+))
1585   ;; GRP2S-one
1586   (vector
1587    (make-x86-dis "rolQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1588    (make-x86-dis "rorQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1589    (make-x86-dis "rclQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1590    (make-x86-dis "rcrQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1591    (make-x86-dis "shlQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1592    (make-x86-dis "shrQ" 'op-e +v-mode+ 'op-i +const-1-mode+)
1593    (make-x86-dis "(bad)")
1594    (make-x86-dis "sarQ" 'op-e +v-mode+ 'op-i +const-1-mode+))
1595   ;; GRP2b-cl
1596   (vector
1597    (make-x86-dis "rolA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1598    (make-x86-dis "rorA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1599    (make-x86-dis "rclA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1600    (make-x86-dis "rcrA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1601    (make-x86-dis "shlA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1602    (make-x86-dis "shrA" 'op-e +b-mode+ 'op-imreg +cl-reg+)
1603    (make-x86-dis "(bad)")
1604    (make-x86-dis "sarA" 'op-e +b-mode+ 'op-imreg +cl-reg+))
1605   ;; GRP2S-cl
1606   (vector
1607    (make-x86-dis "rolQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1608    (make-x86-dis "rorQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1609    (make-x86-dis "rclQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1610    (make-x86-dis "rcrQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1611    (make-x86-dis "shlQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1612    (make-x86-dis "shrQ" 'op-e +v-mode+ 'op-imreg +cl-reg+)
1613    (make-x86-dis "(bad)")
1614    (make-x86-dis "sarQ" 'op-e +v-mode+ 'op-imreg +cl-reg+))
1615   ;; GRP3b
1616   (vector
1617    (make-x86-dis "testA" 'op-e +b-mode+ 'op-i +b-mode+)
1618    (make-x86-dis "(bad)" 'op-e +b-mode+)
1619    (make-x86-dis "notA" 'op-e +b-mode+)
1620    (make-x86-dis "negA" 'op-e +b-mode+)
1621    (make-x86-dis "mulA" 'op-e +b-mode+)            ; Don't print the implicit %al register
1622    (make-x86-dis "imulA" 'op-e +b-mode+)           ; to distinguish these opcodes from other
1623    (make-x86-dis "divA" 'op-e +b-mode+)            ; mul/imul opcodes. Do the same for div
1624    (make-x86-dis "idivA" 'op-e +b-mode+)           ; and idiv for consistency.
1625    )
1626   ;; GRP3S
1627   (vector
1628    (make-x86-dis "testQ" 'op-e +v-mode+ 'op-i +v-mode+)
1629    (make-x86-dis "(bad)")
1630    (make-x86-dis "notQ" 'op-e +v-mode+)
1631    (make-x86-dis "negQ" 'op-e +v-mode+)
1632    (make-x86-dis "mulQ" 'op-e +v-mode+)            ; Don't print the implicit register.
1633    (make-x86-dis "imulQ" 'op-e +v-mode+)
1634    (make-x86-dis "divQ" 'op-e +v-mode+)
1635    (make-x86-dis "idivQ" 'op-e +v-mode+))
1636   ;; GRP4
1637   (vector
1638    (make-x86-dis "incA" 'op-e +b-mode+)
1639    (make-x86-dis "decA" 'op-e +b-mode+)
1640    (make-x86-dis "(bad)")
1641    (make-x86-dis "(bad)")
1642    (make-x86-dis "(bad)")
1643    (make-x86-dis "(bad)")
1644    (make-x86-dis "(bad)")
1645    (make-x86-dis "(bad)"))
1646   ;; GRP5
1647   (vector
1648    (make-x86-dis "incQ" 'op-e +v-mode+)
1649    (make-x86-dis "decQ" 'op-e +v-mode+)
1650    (make-x86-dis '("callT" . :call) 'op-indire +v-mode+)
1651    (make-x86-dis '("JcallT" . :call) 'op-indire +f-mode+)
1652    (make-x86-dis '("jmpT" . :jump) 'op-indire +v-mode+)
1653    (make-x86-dis '("JjmpT" . :jump) 'op-indire +f-mode+)
1654    (make-x86-dis "pushU" 'op-e +v-mode+)
1655    (make-x86-dis "(bad)"))
1656   ;; GRP6
1657   (vector
1658    (make-x86-dis "sldtQ" 'op-e +v-mode+)
1659    (make-x86-dis "strQ" 'op-e +v-mode+)
1660    (make-x86-dis "lldt" 'op-e +w-mode+)
1661    (make-x86-dis "ltr" 'op-e +w-mode+)
1662    (make-x86-dis "verr" 'op-e +w-mode+)
1663    (make-x86-dis "verw" 'op-e +w-mode+)
1664    (make-x86-dis "(bad)")
1665    (make-x86-dis "(bad)"))
1666   ;; GRP7
1667   (vector
1668    (make-x86-dis "sgdtQ" 'op-m 0)
1669    (make-x86-dis "sidtQ" 'pni-fixup 0)
1670    (make-x86-dis '(("lgdtQ" . "lgdt")) 'op-m 0)
1671    (make-x86-dis '(("lidtQ" . "lidt")) 'op-m 0)
1672    (make-x86-dis "smswQ" 'op-e +v-mode+)
1673    (make-x86-dis "(bad)")
1674    (make-x86-dis "lmsw" 'op-e +w-mode+)
1675    (make-x86-dis "invlpg" 'INVLPG-Fixup +w-mode+))
1676   ;; GRP8
1677   (vector
1678    (make-x86-dis "(bad)")
1679    (make-x86-dis "(bad)")
1680    (make-x86-dis "(bad)")
1681    (make-x86-dis "(bad)")
1682    (make-x86-dis "btQ" 'op-e +v-mode+ 'op-i +b-mode+)
1683    (make-x86-dis "btsQ" 'op-e +v-mode+ 'op-i +b-mode+)
1684    (make-x86-dis "btrQ" 'op-e +v-mode+ 'op-i +b-mode+)
1685    (make-x86-dis "btcQ" 'op-e +v-mode+ 'op-i +b-mode+))
1686   ;; GRP9
1687   (vector
1688    (make-x86-dis "(bad)")
1689    (make-x86-dis "cmpxchg8b" 'op-e +q-mode+)
1690    (make-x86-dis "(bad)")
1691    (make-x86-dis "(bad)")
1692    (make-x86-dis "(bad)")
1693    (make-x86-dis "(bad)")
1694    (make-x86-dis "(bad)")
1695    (make-x86-dis "(bad)"))
1696   ;; GRP10
1697   (vector
1698    (make-x86-dis "(bad)")
1699    (make-x86-dis "(bad)")
1700    (make-x86-dis "psrlw" 'op-ms +v-mode+ 'op-i +b-mode+)
1701    (make-x86-dis "(bad)")
1702    (make-x86-dis "psraw" 'op-ms +v-mode+ 'op-i +b-mode+)
1703    (make-x86-dis "(bad)")
1704    (make-x86-dis "psllw" 'op-ms +v-mode+ 'op-i +b-mode+)
1705    (make-x86-dis "(bad)"))
1706   ;; GRP11
1707   (vector
1708    (make-x86-dis "(bad)")
1709    (make-x86-dis "(bad)")
1710    (make-x86-dis "psrld" 'op-ms +v-mode+ 'op-i +b-mode+)
1711    (make-x86-dis "(bad)")
1712    (make-x86-dis "psrad" 'op-ms +v-mode+ 'op-i +b-mode+)
1713    (make-x86-dis "(bad)")
1714    (make-x86-dis "pslld" 'op-ms +v-mode+ 'op-i +b-mode+)
1715    (make-x86-dis "(bad)"))
1716   ;; GRP12
1717   (vector
1718    (make-x86-dis "(bad)")
1719    (make-x86-dis "(bad)")
1720    (make-x86-dis "psrlq" 'op-ms +v-mode+ 'op-i +b-mode+)
1721    (make-x86-dis "psrldq" 'op-ms +v-mode+ 'op-i +b-mode+)
1722    (make-x86-dis "(bad)")
1723    (make-x86-dis "(bad)")
1724    (make-x86-dis "psllq" 'op-ms +v-mode+ 'op-i +b-mode+)
1725    (make-x86-dis "pslldq" 'op-ms +v-mode+ 'op-i +b-mode+))
1726   ;; GRP13
1727   (vector
1728    (make-x86-dis "fxsave" 'op-e +v-mode+)
1729    (make-x86-dis "fxrstor" 'op-e +v-mode+)
1730    (make-x86-dis "ldmxcsr" 'op-e +v-mode+)
1731    (make-x86-dis "stmxcsr" 'op-e +v-mode+)
1732    (make-x86-dis "(bad)")
1733    (make-x86-dis "lfence" 'OP-0fae 0)
1734    (make-x86-dis "mfence" 'OP-0fae 0)
1735    (make-x86-dis "clflush" 'OP-0fae 0))
1736   ;; GRP14
1737   (vector
1738    (make-x86-dis "prefetchnta" 'op-e +v-mode+)
1739    (make-x86-dis "prefetcht0" 'op-e +v-mode+)
1740    (make-x86-dis "prefetcht1" 'op-e +v-mode+)
1741    (make-x86-dis "prefetcht2" 'op-e +v-mode+)
1742    (make-x86-dis "(bad)")
1743    (make-x86-dis "(bad)")
1744    (make-x86-dis "(bad)")
1745    (make-x86-dis "(bad)"))
1746   ;; GRPAMD
1747   (vector
1748    (make-x86-dis "prefetch" 'op-e +b-mode+)
1749    (make-x86-dis "prefetchw" 'op-e +b-mode+)
1750    (make-x86-dis "(bad)")
1751    (make-x86-dis "(bad)")
1752    (make-x86-dis "(bad)")
1753    (make-x86-dis "(bad)")
1754    (make-x86-dis "(bad)")
1755    (make-x86-dis "(bad)"))
1756   ;; GRPPADLCK1
1757   (vector
1758    (make-x86-dis "xstorerng" 'op-0f07 0)
1759    (make-x86-dis "xcryptecb" 'op-0f07 0)
1760    (make-x86-dis "xcryptcbc" 'op-0f07 0)
1761    (make-x86-dis "(bad)" 'op-0f07 0)
1762    (make-x86-dis "xcryptcfb" 'op-0f07 0)
1763    (make-x86-dis "xcryptofb" 'op-0f07 0)
1764    (make-x86-dis "(bad)" 'op-0f07 0)
1765    (make-x86-dis "(bad)" 'op-0f07 0))
1766   ;; GRPPADLCK2
1767   (vector
1768    (make-x86-dis "montmul" 'op-0f07 0)
1769    (make-x86-dis "xsha1" 'op-0f07 0)
1770    (make-x86-dis "xsha256" 'op-0f07 0)
1771    (make-x86-dis "(bad)" 'op-0f07 0)
1772    (make-x86-dis "(bad)" 'op-0f07 0)
1773    (make-x86-dis "(bad)" 'op-0f07 0)
1774    (make-x86-dis "(bad)" 'op-0f07 0)
1775    (make-x86-dis "(bad)" 'op-0f07 0))))
1776
1777(defparameter *prefix-user-table*
1778  (vector
1779   ;; PREGRP0
1780   (vector
1781    (make-x86-dis "addps" 'op-xmm 0 'op-ex +v-mode+)
1782    (make-x86-dis "addss" 'op-xmm 0 'op-ex +v-mode+)
1783    (make-x86-dis "addpd" 'op-xmm 0 'op-ex +v-mode+)
1784    (make-x86-dis "addsd" 'op-xmm 0 'op-ex +v-mode+))
1785   ;; PREGRP1
1786   (vector
1787    (make-x86-dis "" 'op-xmm 0 'op-ex +v-mode+ 'op-simd-suffix 0);; See OP-SIMD-SUFFIX.
1788    (make-x86-dis "" 'op-xmm 0 'op-ex +v-mode+ 'op-simd-suffix 0)
1789    (make-x86-dis "" 'op-xmm 0 'op-ex +v-mode+ 'op-simd-suffix 0)
1790    (make-x86-dis "" 'op-xmm 0 'op-ex +v-mode+ 'op-simd-suffix 0))
1791   ;; PREGRP2
1792   (vector
1793    (make-x86-dis "cvtpi2ps" 'op-xmm 0 'op-em +v-mode+)
1794    (make-x86-dis "cvtsi2ssY" 'op-xmm 0 'op-e +v-mode+)
1795    (make-x86-dis "cvtpi2pd" 'op-xmm 0 'op-em +v-mode+)
1796    (make-x86-dis "cvtsi2sdY" 'op-xmm 0 'op-e +v-mode+))
1797   ;; PREGRP3
1798   (vector
1799    (make-x86-dis "cvtps2pi" 'op-mmx 0 'op-ex +v-mode+)
1800    (make-x86-dis "cvtss2siY" 'op-g +v-mode+ 'op-ex +v-mode+)
1801    (make-x86-dis "cvtpd2pi" 'op-mmx 0 'op-ex +v-mode+)
1802    (make-x86-dis "cvtsd2siY" 'op-g +v-mode+ 'op-ex +v-mode+))
1803   ;; PREGRP4
1804   (vector
1805    (make-x86-dis "cvttps2pi" 'op-mmx 0 'op-ex +v-mode+)
1806    (make-x86-dis "cvttss2siY" 'op-g +v-mode+ 'op-ex +v-mode+)
1807    (make-x86-dis "cvttpd2pi" 'op-mmx 0 'op-ex +v-mode+)
1808    (make-x86-dis "cvttsd2siY" 'op-g +v-mode+ 'op-ex +v-mode+))
1809   ;; PREGRP5
1810   (vector
1811    (make-x86-dis "divps" 'op-xmm 0 'op-ex +v-mode+)
1812    (make-x86-dis "divss" 'op-xmm 0 'op-ex +v-mode+)
1813    (make-x86-dis "divpd" 'op-xmm 0 'op-ex +v-mode+)
1814    (make-x86-dis "divsd" 'op-xmm 0 'op-ex +v-mode+))
1815   ;; PREGRP6
1816   (vector
1817    (make-x86-dis "maxps" 'op-xmm 0 'op-ex +v-mode+)
1818    (make-x86-dis "maxss" 'op-xmm 0 'op-ex +v-mode+)
1819    (make-x86-dis "maxpd" 'op-xmm 0 'op-ex +v-mode+)
1820    (make-x86-dis "maxsd" 'op-xmm 0 'op-ex +v-mode+))
1821   ;; PREGRP7
1822   (vector
1823    (make-x86-dis "minps" 'op-xmm 0 'op-ex +v-mode+)
1824    (make-x86-dis "minss" 'op-xmm 0 'op-ex +v-mode+)
1825    (make-x86-dis "minpd" 'op-xmm 0 'op-ex +v-mode+)
1826    (make-x86-dis "minsd" 'op-xmm 0 'op-ex +v-mode+))
1827   ;; PREGRP8
1828   (vector
1829    (make-x86-dis "movups" 'op-xmm 0 'op-ex +v-mode+)
1830    (make-x86-dis "movss" 'op-xmm 0 'op-ex +v-mode+)
1831    (make-x86-dis "movupd" 'op-xmm 0 'op-ex +v-mode+)
1832    (make-x86-dis "movsd" 'op-xmm 0 'op-ex +v-mode+))
1833   ;; PREGRP9
1834   (vector
1835    (make-x86-dis "movups" 'op-ex +v-mode+ 'op-xmm 0)
1836    (make-x86-dis "movss" 'op-ex +v-mode+ 'op-xmm 0)
1837    (make-x86-dis "movupd" 'op-ex +v-mode+ 'op-xmm 0)
1838    (make-x86-dis "movsd" 'op-ex +v-mode+ 'op-xmm 0))
1839   ;; PREGRP10
1840   (vector
1841    (make-x86-dis "mulps" 'op-xmm 0 'op-ex +v-mode+)
1842    (make-x86-dis "mulss" 'op-xmm 0 'op-ex +v-mode+)
1843    (make-x86-dis "mulpd" 'op-xmm 0 'op-ex +v-mode+)
1844    (make-x86-dis "mulsd" 'op-xmm 0 'op-ex +v-mode+))
1845   ;; PREGRP11
1846   (vector
1847    (make-x86-dis "rcpps" 'op-xmm 0 'op-ex +v-mode+)
1848    (make-x86-dis "rcpss" 'op-xmm 0 'op-ex +v-mode+)
1849    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1850    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1851   ;; PREGRP12
1852   (vector
1853    (make-x86-dis "rsqrtps" 'op-xmm 0 'op-ex +v-mode+)
1854    (make-x86-dis "rsqrtss" 'op-xmm 0 'op-ex +v-mode+)
1855    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1856    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1857   ;; PREGRP13
1858   (vector
1859    (make-x86-dis "sqrtps" 'op-xmm 0 'op-ex +v-mode+)
1860    (make-x86-dis "sqrtss" 'op-xmm 0 'op-ex +v-mode+)
1861    (make-x86-dis "sqrtpd" 'op-xmm 0 'op-ex +v-mode+)
1862    (make-x86-dis "sqrtsd" 'op-xmm 0 'op-ex +v-mode+))
1863   ;; PREGRP14
1864   (vector
1865    (make-x86-dis "subps" 'op-xmm 0 'op-ex +v-mode+)
1866    (make-x86-dis "subss" 'op-xmm 0 'op-ex +v-mode+)
1867    (make-x86-dis "subpd" 'op-xmm 0 'op-ex +v-mode+)
1868    (make-x86-dis "subsd" 'op-xmm 0 'op-ex +v-mode+))
1869   ;; PREGRP15
1870   (vector
1871    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1872    (make-x86-dis "cvtdq2pd" 'op-xmm 0 'op-ex +v-mode+)
1873    (make-x86-dis "cvttpd2dq" 'op-xmm 0 'op-ex +v-mode+)
1874    (make-x86-dis "cvtpd2dq" 'op-xmm 0 'op-ex +v-mode+))
1875   ;; PREGRP16
1876   (vector
1877    (make-x86-dis "cvtdq2ps" 'op-xmm 0 'op-ex +v-mode+)
1878    (make-x86-dis "cvttps2dq" 'op-xmm 0 'op-ex +v-mode+)
1879    (make-x86-dis "cvtps2dq" 'op-xmm 0 'op-ex +v-mode+)
1880    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1881   ;; PREGRP17
1882   (vector
1883    (make-x86-dis "cvtps2pd" 'op-xmm 0 'op-ex +v-mode+)
1884    (make-x86-dis "cvtss2sd" 'op-xmm 0 'op-ex +v-mode+)
1885    (make-x86-dis "cvtpd2ps" 'op-xmm 0 'op-ex +v-mode+)
1886    (make-x86-dis "cvtsd2ss" 'op-xmm 0 'op-ex +v-mode+))
1887   ;; PREGRP18
1888   (vector
1889    (make-x86-dis "maskmovq" 'op-mmx 0 'op-s +v-mode+)
1890    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1891    (make-x86-dis "maskmovdqu" 'op-xmm 0 'op-ex +v-mode+)
1892    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1893   ;; PREGRP19
1894   (vector
1895    (make-x86-dis "movq" 'op-mmx 0 'op-em +v-mode+)
1896    (make-x86-dis "movdqu" 'op-xmm 0 'op-ex +v-mode+)
1897    (make-x86-dis "movdqa" 'op-xmm 0 'op-ex +v-mode+)
1898    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1899   ;; PREGRP20
1900   (vector
1901    (make-x86-dis "movq" 'op-em +v-mode+ 'op-mmx 0)
1902    (make-x86-dis "movdqu" 'op-ex +v-mode+ 'op-xmm 0)
1903    (make-x86-dis "movdqa" 'op-ex +v-mode+ 'op-xmm 0)
1904    (make-x86-dis "(bad)" 'op-ex +v-mode+ 'op-xmm 0))
1905   ;; PREGRP21
1906   (vector
1907    (make-x86-dis "(bad)" 'op-ex +v-mode+ 'op-xmm 0)
1908    (make-x86-dis "movq2dq" 'op-xmm 0 'op-s +v-mode+)
1909    (make-x86-dis "movq" 'op-ex +v-mode+ 'op-xmm 0)
1910    (make-x86-dis "movdq2q" 'op-mmx 0 'op-xs +v-mode+))
1911   ;; PREGRP22
1912   (vector
1913    (make-x86-dis "pshufw" 'op-mmx 0 'op-em +v-mode+ 'op-i +b-mode+)
1914    (make-x86-dis "pshufhw" 'op-xmm 0 'op-ex +v-mode+ 'op-i +b-mode+)
1915    (make-x86-dis "pshufd" 'op-xmm 0 'op-ex +v-mode+ 'op-i +b-mode+)
1916    (make-x86-dis "pshuflw" 'op-xmm 0 'op-ex +v-mode+ 'op-i +b-mode+))
1917   ;; PREGRP23
1918   (vector
1919    (make-x86-dis "movd" 'op-e +dq-mode+ 'op-mmx 0)
1920    (make-x86-dis "movq" 'op-xmm 0 'op-ex +v-mode+)
1921    (make-x86-dis "movd" 'op-e +dq-mode+ 'op-xmm 0)
1922    (make-x86-dis "(bad)" 'op-e +d-mode+ 'op-xmm 0))
1923   ;; PREGRP24
1924   (vector
1925    (make-x86-dis "(bad)" 'op-mmx 0 'op-ex +v-mode+)
1926    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1927    (make-x86-dis "punpckhqdq" 'op-xmm 0 'op-ex +v-mode+)
1928    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1929   ;; PREGRP25
1930   (vector
1931    (make-x86-dis "movntq" 'op-em +v-mode+ 'op-mmx 0)
1932    (make-x86-dis "(bad)" 'op-em +v-mode+ 'op-xmm 0)
1933    (make-x86-dis "movntdq" 'op-em +v-mode+ 'op-xmm 0)
1934    (make-x86-dis "(bad)" 'op-em +v-mode+ 'op-xmm 0))
1935   ;; PREGRP26
1936   (vector
1937    (make-x86-dis "(bad)" 'op-mmx 0 'op-ex +v-mode+)
1938    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1939    (make-x86-dis "punpcklqdq" 'op-xmm 0 'op-ex +v-mode+)
1940    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1941   ;; PREGRP27
1942   (vector
1943    (make-x86-dis "(bad)" 'op-mmx 0 'op-ex +v-mode+)
1944    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1945    (make-x86-dis "addsubpd" 'op-xmm 0 'op-ex +v-mode+)
1946    (make-x86-dis "addsubps" 'op-xmm 0 'op-ex +v-mode+))
1947   ;; PREGRP28
1948   (vector
1949    (make-x86-dis "(bad)" 'op-mmx 0 'op-ex +v-mode+)
1950    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1951    (make-x86-dis "haddpd" 'op-xmm 0 'op-ex +v-mode+)
1952    (make-x86-dis "haddps" 'op-xmm 0 'op-ex +v-mode+))
1953   ;; PREGRP29
1954   (vector
1955    (make-x86-dis "(bad)" 'op-mmx 0 'op-ex +v-mode+)
1956    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1957    (make-x86-dis "hsubpd" 'op-xmm 0 'op-ex +v-mode+)
1958    (make-x86-dis "hsubps" 'op-xmm 0 'op-ex +v-mode+))
1959   ;; PREGRP30
1960   (vector
1961    (make-x86-dis "movlpX" 'op-xmm 0 'op-ex +v-mode+ 'SIMD-Fixup #\h);; really only 2 operands
1962    (make-x86-dis "movsldup" 'op-xmm 0 'op-ex +v-mode+)
1963    (make-x86-dis "movlpd" 'op-xmm 0 'op-ex +v-mode+)
1964    (make-x86-dis "movddup" 'op-xmm 0 'op-ex +v-mode+))
1965   ;; PREGRP31
1966   (vector
1967    (make-x86-dis "movhpX" 'op-xmm 0 'op-ex +v-mode+ 'SIMD-Fixup #\l)
1968    (make-x86-dis "movshdup" 'op-xmm 0 'op-ex +v-mode+)
1969    (make-x86-dis "movhpd" 'op-xmm 0 'op-ex +v-mode+)
1970    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+))
1971   ;; PREGRP32
1972   (vector
1973    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1974    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1975    (make-x86-dis "(bad)" 'op-xmm 0 'op-ex +v-mode+)
1976    (make-x86-dis "lddqu" 'op-xmm 0 'op-m 0))))
1977
1978(defparameter *x86-64-table*
1979    (vector
1980     (vector
1981      (make-x86-dis "arpl" 'op-e +w-mode+ 'op-g +w-mode+)
1982      (make-x86-dis "movslq" 'op-g +v-mode+ 'op-e +d-mode+))))
1983
1984
1985(defun prefix-name (ds b sizeflag)
1986  (case b
1987    (#x40 "rex")
1988    (#x41 "rexZ")
1989    (#x42 "rexY")
1990    (#x43 "rexYZ")
1991    (#x44 "rexX")
1992    (#x45 "rexXZ")
1993    (#x46 "rexYZ")
1994    (#x47 "rexXYZ")
1995    (#x48 "rex64")
1996    (#x49 "rex64Z")
1997    (#x4a "rex64Y")
1998    (#x4b "rex64YZ")
1999    (#x4c "rex64X")
2000    (#x4d "rex64XZ")
2001    (#x4e "rex64XY")
2002    (#x4f "rex64XYZ")
2003    (#xf3 "repz")
2004    (#xf2 "repnz")
2005    (#xf0 "lock")
2006    (#x2e "cs")
2007    (#x36 "ss")
2008    (#x3e "ds")
2009    (#x26 "es")
2010    (#x64 "fs")
2011    (#x65 "gs")
2012    (#x66 (if (logtest sizeflag +dflag+) "data16" "data32"))
2013    (#x67 (if (x86-ds-mode-64 ds)
2014            (if (logtest sizeflag +aflag+) "addr32" "addr64")
2015            (if (logtest sizeflag +aflag+) "addr16" "addr32")))
2016
2017    (#x9b "fwait")))
2018
2019(defun scan-prefixes (ds instruction)
2020  (setf (x86-ds-prefixes ds) 0
2021        (x86-ds-used-prefixes ds) 0
2022        (x86-ds-rex ds) 0
2023        (x86-ds-rex-used ds) 0)
2024  (let* ((newrex 0)
2025         (prefixes 0))
2026    (declare (fixnum prefixes))
2027    (do* ((b (x86-ds-peek-u8 ds)
2028             (progn (x86-ds-skip ds)
2029                    (x86-ds-peek-u8 ds))))
2030         ()
2031      (declare (type (unsigned-byte 8) b))
2032      (setq newrex 0)
2033      (cond ((and (>= b #x40)
2034                  (<= b #x4f))
2035             (if (x86-ds-mode-64 ds)
2036               (setq newrex b)
2037               (return)))
2038            ((= b #xf3)
2039             (setq prefixes (logior prefixes +prefix-repz+)))
2040            ((= b #xf2)
2041             (setq prefixes (logior prefixes +prefix-repnz+)))
2042            ((= b #xf0)
2043             (setq prefixes (logior prefixes +prefix-lock+)))
2044            ((= b #x2e)
2045             (setq prefixes (logior prefixes +prefix-cs+)))
2046            ((= b #x36)
2047             (setq prefixes (logior prefixes +prefix-ss+)))
2048            ((= b #x3e)
2049             (setq prefixes (logior prefixes +prefix-ds+)))
2050            ((= b #x26)
2051             (setq prefixes (logior prefixes +prefix-es+)))
2052            ((= b #x64)
2053             (setq prefixes (logior prefixes +prefix-fs+)))
2054            ((= b #x65)
2055             (setq prefixes (logior prefixes +prefix-gs+)))
2056            ((= b #x66)
2057             (setq prefixes (logior prefixes +prefix-data+)))
2058            ((= b #x67)
2059             (setq prefixes (logior prefixes +prefix-addr+)))
2060            ((= b #x9b)
2061             ;; FWAIT. If there are already some prefixes,
2062             ;; we've found the opcode.
2063             (if (= prefixes 0)
2064               (progn
2065                 (setq prefixes +prefix-fwait+)
2066                 (return))
2067               (setq prefixes (logior prefixes +prefix-fwait+))))
2068            (t (return)))
2069      (unless (zerop (x86-ds-rex ds))
2070        (let* ((prefix-name (prefix-name ds (x86-ds-rex ds) 0)))
2071          (when prefix-name
2072            (push prefix-name
2073                  (x86-di-prefixes instruction)))))
2074      (setf (x86-ds-rex ds) newrex))
2075    (setf (x86-ds-prefixes ds) prefixes)))
2076
2077
2078(defun x86-putop (ds template sizeflag instruction)
2079  (let* ((ok t))
2080    (when (consp template)
2081      (if (x86-ds-mode-64 ds)
2082      (setq template (cdr template))
2083      (setq template (car template))))
2084  (if (dotimes (i (length template) t)
2085          (unless (lower-case-p (schar template i))
2086            (return nil)))
2087      (setf (x86-di-mnemonic instruction) template)
2088      (let* ((string-buffer (x86-ds-string-buffer ds))
2089             (mod (x86-ds-mod ds))
2090             (rex (x86-ds-rex ds))
2091             (prefixes (x86-ds-prefixes ds))
2092             (mode64 (x86-ds-mode-64 ds)))
2093        (declare (fixnum rex prefixes))
2094        (setf (fill-pointer string-buffer) 0)
2095        (dotimes (i (length template))
2096          (let* ((c (schar template i))
2097                 (b 
2098                  (case c
2099                    (#\) (setq ok nil))
2100                    (#\A (if (or (not (eql mod 3))
2101                                 (logtest sizeflag +suffix-always+))
2102                           #\b))
2103                    (#\B (if (logtest sizeflag +suffix-always+)
2104                           #\b))
2105                    (#\C (when (or (logtest prefixes +prefix-data+)
2106                                   (logtest sizeflag +suffix-always+))
2107                           (used-prefix ds +prefix-data+)
2108                           (if (logtest sizeflag +dflag+)
2109                             #\l
2110                             #\s)))
2111                    (#\E (used-prefix ds +prefix-addr+)
2112                         (if mode64
2113                           (if (logtest sizeflag +aflag+)
2114                             #\r
2115                             #\e)
2116                           (if (logtest sizeflag +aflag+)
2117                             #\e)))
2118                    (#\F (when (or (logtest prefixes +prefix-addr+)
2119                                   (logtest sizeflag +suffix-always+))
2120                           (used-prefix ds +prefix-addr+)
2121                           (if (logtest sizeflag +aflag+)
2122                             (if mode64 #\q #\l)
2123                             (if mode64 #\l #\w))))
2124                    (#\H (let* ((ds-or-cs
2125                                 (logand prefixes
2126                                         (logior +prefix-ds+ +prefix-ds+)))
2127                                (ds-only (= ds-or-cs +prefix-ds+))
2128                                (cs-only (= ds-or-cs +prefix-cs+)))
2129                           (when (or ds-only cs-only)
2130                             (setf (x86-ds-used-prefixes ds)
2131                                   (logior (x86-ds-used-prefixes ds)
2132                                           ds-or-cs))
2133                             (if ds-only ".pt" ".pn"))))
2134                    (#\J #\l)
2135                    (#\L (if (logtest sizeflag +suffix-always+) #\l))
2136                    (#\N (if (logtest prefixes +prefix-fwait+)
2137                           (setf (x86-ds-used-prefixes ds)
2138                                 (logior (x86-ds-used-prefixes ds)
2139                                         +prefix-fwait+))
2140                           #\n))
2141                    (#\O (used-rex ds +rex-mode64+)
2142                         (if (logtest rex +rex-mode64+)
2143                           #\o
2144                           #\d))
2145                    ((#\T #\P)
2146                     (if (and (eql c #\T) mode64)
2147                       #\q
2148                       (when (or (logtest prefixes +prefix-data+)
2149                                 (logtest rex +rex-mode64+)
2150                                 (logtest sizeflag +suffix-always+))
2151                         (used-rex ds +rex-mode64+)
2152                         (if (logtest rex +rex-mode64+)
2153                           #\q
2154                           (progn
2155                             (used-prefix ds +prefix-data+)
2156                             (if (logtest sizeflag +dflag+)
2157                               #\l
2158                               #\w))))))
2159                    ((#\U #\Q)
2160                     (if (and (eql c #\U) mode64)
2161                       #\q
2162                       (progn
2163                         (used-rex ds +rex-mode64+)
2164                         (when (or (not (eql mod 3))
2165                                   (logtest sizeflag +suffix-always+))
2166                           (if (logtest rex +rex-mode64+)
2167                             #\q
2168                             (progn
2169                               (used-prefix ds +prefix-data+)
2170                               (if (logtest sizeflag +dflag+)
2171                                 #\l
2172                                 #\w)))))))
2173                    (#\R
2174                     (used-rex ds +rex-mode64+)
2175                     (if (logtest rex +rex-mode64+)
2176                       #\q
2177                       (if (logtest sizeflag +dflag+)
2178                         #\l
2179                         #\w)))
2180                    (#\S
2181                     (when (logtest sizeflag +suffix-always+)
2182                       (if (logtest rex +rex-mode64+)
2183                         #\q
2184                         (progn
2185                           (used-prefix ds +prefix-data+)
2186                           (if (logtest sizeflag +dflag+)
2187                             #\l
2188                             #\w)))))
2189                    (#\X
2190                     (used-prefix ds +prefix-data+)
2191                     (if (logtest prefixes +prefix-data+)
2192                       #\d
2193                       #\s))
2194                    (#\Y
2195                     (when (logtest rex +rex-mode64+)
2196                       (used-rex ds +rex-mode64+)
2197                       #\q))
2198                    (#\W
2199                     (used-rex ds 0)
2200                     (if (not (eql rex 0))
2201                       #\l
2202                       (progn
2203                         (used-prefix ds +prefix-data+)
2204                         (if (logtest sizeflag +dflag+)
2205                           #\w
2206                           #\b))))
2207                    (t c))))
2208            (if b
2209              (if (typep b 'character)
2210                (vector-push-extend b string-buffer)
2211                (dotimes (i (length b))
2212                  (vector-push-extend (schar b i) string-buffer))))))
2213        (setf (x86-di-mnemonic instruction) (subseq string-buffer 0))))
2214  ok))
2215
2216(defparameter *x86-dissassemble-always-print-suffix* t)
2217
2218(defun x86-dis-do-float (ds instruction floatop sizeflag)
2219  (declare (ignore floatop sizeflag))
2220  ;; Later; we want to make minimal use of the x87 fpu.
2221  (setf (x86-di-mnemonic instruction) "x87-fpu-op")
2222  (x86-ds-skip ds))
2223
2224(defun x86-dis-do-uuo (ds instruction intop)
2225  (declare (type (unsigned-byte 8) intop))
2226  (let* ((stop t))
2227    (cond ((and (>= intop #x70) (< intop #x80))
2228           (setq stop nil)
2229           (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2230             (setf (x86-di-mnemonic instruction)
2231                   "uuo-error-slot-unbound"
2232                   (x86-di-op0 instruction)
2233                   (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))                     
2234                   (x86-di-op1 instruction)
2235                   (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 4)
2236                                                                       pseudo-modrm-byte) :%))
2237                   (x86-di-op2 instruction)
2238                   (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 0)
2239                                                                       pseudo-modrm-byte) :%)))))
2240          ((< intop #x90)
2241           (setf (x86-di-mnemonic instruction) "int"
2242                 (x86-di-op0 instruction)
2243                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression intop))))
2244          ((< intop #xa0)
2245           (setf (x86-di-mnemonic instruction)
2246                 "uuo-error-unbound"
2247                 (x86-di-op0 instruction)
2248                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))))
2249          ((< intop #xb0)
2250           (setf (x86-di-mnemonic instruction)
2251                 "uuo-error-udf"
2252                 (x86-di-op0 instruction)
2253                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))))
2254         
2255          ((< intop #xc0)
2256           (setf (x86-di-mnemonic instruction)
2257                 "uuo-error-reg-not-type"
2258                 (x86-di-op0 instruction)
2259                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))
2260                 (x86-di-op1 instruction)
2261                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression (x86-ds-next-u8 ds)))))
2262          ((< intop #xc8)
2263           (if (= intop #xc3)
2264             (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2265               (setf (x86-di-mnemonic instruction)
2266                     "uuo-error-array-rank"
2267                     (x86-di-op0 instruction)
2268                     (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 4)
2269                                                                         pseudo-modrm-byte) :%))
2270                     (x86-di-op1 instruction)
2271                     (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 0)
2272                                                                         pseudo-modrm-byte) :%))))
2273                   
2274           (setf (x86-di-mnemonic instruction)
2275                 (case intop
2276                   (#xc0 "uuo-error-too-few-args")
2277                   (#xc1 "uuo-error-too-many-args")
2278                   (#xc2 "uuo-error-wrong-number-of-args")
2279                   (#xc4 (progn (setq stop nil) "uuo-gc-trap"))
2280                   (#xc5 "uuo-alloc")
2281                   (#xc6 "uuo-error-not-callable")
2282                   (#xc7 "uuo-udf-call")
2283                   (t "unknown-UUO")))))
2284          ((= intop #xc8)
2285           (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2286             (declare (type (unsigned-byte 8) pseudo-modrm-byte))
2287             (setf (x86-di-op0 instruction)
2288                 (x86-dis-make-reg-operand
2289                  (lookup-x86-register (ldb (byte 4 4) pseudo-modrm-byte) :%))
2290                 (x86-di-op1 instruction)
2291                 (x86-dis-make-reg-operand
2292                  (lookup-x86-register (ldb (byte 4 0) pseudo-modrm-byte) :%))
2293                 (x86-di-mnemonic instruction) "uuo-error-vector-bounds")))
2294          ((< intop #xd0)
2295           (cond ((= intop #xcb)
2296                  (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2297                    (setf (x86-di-mnemonic instruction)
2298                          "uuo-error-array-bounds"
2299                          (x86-di-op0 instruction)
2300                          (x86-dis-make-reg-operand
2301                           (lookup-x86-register (ldb (byte 4 4)
2302                                                     pseudo-modrm-byte) :%))
2303                          (x86-di-op1 instruction)
2304                          (x86-dis-make-reg-operand
2305                           (lookup-x86-register (ldb (byte 4 0)
2306                                                     pseudo-modrm-byte) :%)))))
2307                 ((= intop #xcc)
2308                  (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2309                    (setf (x86-di-mnemonic instruction)
2310                          "uuo-error-eep-unresolved"
2311                          (x86-di-op0 instruction)
2312                          (x86-dis-make-reg-operand
2313                           (lookup-x86-register (ldb (byte 4 4)
2314                                                     pseudo-modrm-byte) :%))
2315                          (x86-di-op1 instruction)
2316                          (x86-dis-make-reg-operand
2317                           (lookup-x86-register (ldb (byte 4 0)
2318                                                     pseudo-modrm-byte) :%)))))
2319                 (t (setf (x86-di-mnemonic instruction)
2320                          (case intop
2321                            (#xc9 "uuo-error-call-macro-or-special-operator")
2322                            (#xca (setq stop nil) "uuo-error-debug-trap")
2323                            (#xcd (setq stop nil) "uuo-error-debug-trap-with-string")
2324                            (t "unknown-UUO"))))))
2325          ((< intop #xe0)
2326           (setf (x86-di-mnemonic instruction)
2327                 "uuo-error-reg-not-tag"
2328                 (x86-di-op0 instruction)
2329                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))
2330                 (x86-di-op1 instruction)
2331                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression (x86-ds-next-u8 ds)))))
2332          ((< intop #xf0)
2333           (setf (x86-di-mnemonic instruction)
2334                 "uuo-error-reg-not-list"
2335                 (x86-di-op0 instruction)
2336                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%))))
2337          (t
2338           (setf (x86-di-mnemonic instruction)
2339                 "uuo-error-reg-not-fixnum"
2340                 (x86-di-op0 instruction)
2341                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop #xf) :%)))))
2342    stop))
2343
2344
2345
2346(defun x86-dis-analyze-operands (ds instruction flag)
2347  ;; If instruction is adding a positive displacement to the FN
2348  ;; register, note the effective address as a label reference
2349  ;; and modify the operand(s).
2350  ;; If the instruction is a MOV or PUSH whose source operand
2351  ;; is relative to the FN register, generate a constant reference.
2352  ;; If the instruction is adding a displacement to RIP, note
2353  ;; the effective address as a label reference.
2354  (let* ((op0 (x86-di-op0 instruction))
2355         (op1 (x86-di-op1 instruction))
2356         (entry-ea (x86-ds-entry-point ds)))
2357    (flet ((is-fn (thing)
2358             (if (typep thing 'x86::x86-register-operand)
2359               (let* ((entry (x86::x86-register-operand-entry thing)))
2360                 (eq entry (if (x86-ds-mode-64 ds)
2361                             (x86::x86-reg64 13)
2362                             (x86::x86-reg32 6))))))
2363           (is-rip (thing)
2364             (if (and (typep thing 'x86::x86-register-operand)
2365                      (x86-ds-mode-64 ds))
2366               (let* ((entry (x86::x86-register-operand-entry thing)))
2367                 (eq entry (svref x86::*x8664-register-entries* 102)))))
2368           (is-ra0 (thing)
2369             (if (typep thing 'x86::x86-register-operand)
2370               (let* ((entry (x86::x86-register-operand-entry thing)))
2371                 (eq entry (if (x86-ds-mode-64 ds)
2372                             (x86::x86-reg64 10)
2373                             (x86::x86-reg32 7))))))
2374           (is-disp-only (thing)
2375             (and (typep thing 'x86::x86-memory-operand)
2376                  (null (x86::x86-memory-operand-base thing))
2377                  (null (x86::x86-memory-operand-index thing))
2378                  (x86::x86-memory-operand-disp thing))))
2379      (flet ((is-fn-ea (thing)
2380               (and (typep thing 'x86::x86-memory-operand)
2381                    (is-fn (x86::x86-memory-operand-base thing))
2382                    (null (x86::x86-memory-operand-index thing))
2383                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2384                      (or (null scale) (eql 0 scale)))
2385                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2386                      (and disp (early-x86-lap-expression-value disp)))))
2387             (is-ra0-ea (thing)
2388               (and (typep thing 'x86::x86-memory-operand)
2389                    (is-ra0 (x86::x86-memory-operand-base thing))
2390                    (null (x86::x86-memory-operand-index thing))
2391                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2392                      (or (null scale) (eql 0 scale)))
2393                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2394                      (and disp (early-x86-lap-expression-value disp)))))
2395             (is-rip-ea (thing)
2396               (and (typep thing 'x86::x86-memory-operand)
2397                    (is-rip (x86::x86-memory-operand-base thing))
2398                    (null (x86::x86-memory-operand-index thing))
2399                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2400                      (or (null scale) (eql 0 scale)))
2401                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2402                      (and disp (early-x86-lap-expression-value disp))))))
2403        (case flag
2404          ;; Should also check alignment here, and check
2405         
2406          (:lea
2407           (let* ((disp ))
2408             (if (or (and (setq disp (is-fn-ea op0)) (> disp 0))
2409                       (and (setq disp (is-ra0-ea op0)) (< disp 0) (is-fn op1)))
2410               (let* ((label-ea (+ entry-ea (abs disp))))
2411                 (when (< label-ea (x86-ds-code-limit ds))
2412                   (setf (x86::x86-memory-operand-disp op0)
2413                         (parse-x86-lap-expression
2414                          (if (< disp 0)
2415                            `(- (:^ ,label-ea))
2416                            `(:^ ,label-ea))))
2417                   (push label-ea (x86-ds-pending-labels ds))))
2418               (if (and (setq disp (is-rip-ea op0)) (< disp 0) (is-fn op1))
2419                 (progn
2420                   (setf (x86::x86-memory-operand-disp op0)
2421                         (parse-x86-lap-expression `(:^ ,entry-ea)))
2422                   (push entry-ea (x86-ds-pending-labels ds)))))))
2423          ((:jump :call)
2424           (let* ((disp (is-disp-only op0)))
2425             (when disp
2426               (let* ((info (find (early-x86-lap-expression-value disp)
2427                                  x8664::*x8664-subprims*
2428                                  :key #'subprimitive-info-offset)))
2429                 (when info (setf (x86::x86-memory-operand-disp op0)
2430                                  (subprimitive-info-name info)))))))
2431
2432          )))
2433    instruction))
2434
2435(defun x86-disassemble-instruction (ds labeled)
2436  (let* ((addr (x86-ds-code-pointer ds))
2437         (sizeflag (logior +aflag+ +dflag+
2438                           (if *x86-dissassemble-always-print-suffix*
2439                             +suffix-always+
2440                             0)))
2441         (instruction (make-x86-disassembled-instruction :address addr
2442                                                         :labeled labeled))
2443         (stop nil))
2444    (setf (x86-ds-insn-start ds) addr
2445          (x86-ds-current-instruction ds) instruction)
2446    (scan-prefixes ds instruction)
2447    (setf (x86-ds-opcode-start ds) (x86-ds-code-pointer ds))
2448    (let* ((primary-opcode (x86-ds-next-u8 ds))
2449           (two-source-ops (or (= primary-opcode #x62)
2450                               (= primary-opcode #xc8)))
2451           (prefixes (x86-ds-prefixes ds))
2452           (need-modrm nil)
2453           (uses-sse-prefix nil)
2454           (uses-lock-prefix nil)
2455           (dp nil))
2456      (declare (type (unsigned-byte 8) primary-opcode)
2457               (fixnum prefixes))
2458      (if (= primary-opcode #x0f)       ;two-byte opcode
2459        (setq primary-opcode (x86-ds-next-u8 ds)
2460              dp (svref *disx86-twobyte* primary-opcode)
2461              need-modrm (eql 1 (sbit *twobyte-has-modrm* primary-opcode))
2462              uses-sse-prefix (eql 1 (sbit *twobyte-uses-sse-prefix* primary-opcode))
2463              uses-lock-prefix (= #x20 (logandc2 primary-opcode 2)))
2464        (setq dp (svref *disx86* primary-opcode)
2465              need-modrm (eql 1 (sbit *onebyte-has-modrm* primary-opcode))))
2466      (when (and (not uses-sse-prefix) 
2467                 (logtest prefixes +prefix-repz+))
2468        (push "repz" (x86-di-prefixes instruction))
2469        (setf (x86-ds-used-prefixes ds)
2470              (logior (x86-ds-used-prefixes ds) +prefix-repz+)))
2471      (when (and (not uses-sse-prefix) 
2472                 (logtest prefixes +prefix-repnz+))
2473        (push "repnz" (x86-di-prefixes instruction))
2474        (setf (x86-ds-used-prefixes ds)
2475              (logior (x86-ds-used-prefixes ds) +prefix-repnz+)))
2476      (when (and (not uses-lock-prefix)
2477                 (logtest prefixes +prefix-lock+))
2478        (push "lock" (x86-di-prefixes instruction))
2479        (setf (x86-ds-used-prefixes ds)
2480              (logior (x86-ds-used-prefixes ds) +prefix-lock+)))
2481      (when (logtest prefixes +prefix-addr+)
2482        (setq sizeflag (logxor sizeflag +aflag+))
2483        (unless (= (x86-dis-bytemode3 dp) +loop-jcxz-mode+)
2484          (if (or (x86-ds-mode-64 ds)
2485                  (logtest sizeflag +aflag+))
2486            (push "addr32" (x86-di-prefixes instruction))
2487            (push "addr16" (x86-di-prefixes instruction)))
2488          (setf (x86-ds-used-prefixes ds)
2489                (logior (x86-ds-used-prefixes ds) +prefix-addr+))))
2490      (when (and (not uses-sse-prefix)
2491                 (logtest prefixes +prefix-data+))
2492        (setq sizeflag (logxor sizeflag +dflag+))
2493        (when (and (= (x86-dis-bytemode3 dp) +cond-jump-mode+)
2494                   (= (x86-dis-bytemode1 dp) +v-mode+))
2495          (if (logtest sizeflag +dflag+)
2496            (push "data32" (x86-di-prefixes instruction))
2497            (push "data16" (x86-di-prefixes instruction)))
2498          (setf (x86-ds-used-prefixes ds)
2499                (logior (x86-ds-used-prefixes ds) +prefix-data+))))
2500      (when need-modrm
2501        (let* ((modrm-byte (x86-ds-peek-u8 ds)))
2502          (declare (type (unsigned-byte 8) modrm-byte))
2503          (setf (x86-ds-mod ds) (ldb (byte 2 6) modrm-byte)
2504                (x86-ds-reg ds) (ldb (byte 3 3) modrm-byte)
2505                (x86-ds-rm ds) (ldb (byte 3 0) modrm-byte))))
2506      (if (and (null (x86-dis-mnemonic dp))
2507               (eql (x86-dis-bytemode1 dp) +floatcode+))
2508        (x86-dis-do-float ds instruction primary-opcode sizeflag)
2509        (if (and (null (x86-dis-mnemonic dp))
2510                 (eql (x86-dis-bytemode1 dp) +uuocode+))
2511          (progn
2512            (setq stop
2513                  (x86-dis-do-uuo ds instruction (x86-ds-next-u8 ds))))
2514          (progn
2515            (when (null (x86-dis-mnemonic dp))
2516              (let* ((bytemode1 (x86-dis-bytemode1 dp)))
2517                (declare (fixnum bytemode1))
2518                (cond ((= bytemode1 +use-groups+)
2519                       (setq dp (svref (svref *grps* (x86-dis-bytemode2 dp))
2520                                       (x86-ds-reg ds))))
2521                      ((= bytemode1 +use-prefix-user-table+)
2522                       (let* ((index 0))
2523                         (used-prefix ds +prefix-repz+)
2524                         (if (logtest prefixes +prefix-repz+)
2525                           (setq index 1)
2526                           (progn
2527                             (used-prefix ds +prefix-data+)
2528                             (if (logtest prefixes +prefix-data+)
2529                               (setq index 2)
2530                               (progn
2531                                 (used-prefix ds +prefix-repnz+)
2532                                 (if (logtest prefixes +prefix-repnz+)
2533                                   (setq index 3))))))
2534                         (setq dp (svref (svref *prefix-user-table*
2535                                                (x86-dis-bytemode2 dp))
2536                                         index))))
2537                      ((= bytemode1 +x86-64-special+)
2538                       (setq dp (svref (svref *x86-64-table*
2539                                              (x86-dis-bytemode2 dp))
2540                                       (if (x86-ds-mode-64 ds) 1 0))))
2541                    (t (error "Disassembly error")))))
2542          (when (x86-putop ds (x86-dis-mnemonic dp) sizeflag instruction)
2543            (let* ((operands ())
2544                   (op1 (x86-dis-op1 dp))
2545                   (op2 (x86-dis-op2 dp))
2546                   (op3 (x86-dis-op3 dp))
2547                   (operand nil))
2548              (when op1
2549                ;(format t "~& op1 = ~s" op1)
2550                (setq operand (funcall op1 ds (x86-dis-bytemode1 dp) sizeflag))
2551                (if operand
2552                  (push operand operands)))
2553              (when op2
2554                ;(format t "~& op2 = ~s" op2)
2555                (setq operand (funcall op2 ds (x86-dis-bytemode2 dp) sizeflag))
2556                (if operand
2557                  (push operand operands)))
2558              (when op3
2559                ;(format t "~& op3 = ~s" op3)
2560                (setq operand (funcall op3 ds (x86-dis-bytemode3 dp) sizeflag))
2561                (if operand
2562                  (push operand operands)))
2563              (if two-source-ops
2564                (setf (x86-di-op1 instruction) (pop operands)
2565                      (x86-di-op0 instruction) (pop operands))
2566                (setf (x86-di-op0 instruction) (pop operands)
2567                      (x86-di-op1 instruction) (pop operands)
2568                      (x86-di-op2 instruction) (pop operands))))))))
2569      (values (x86-dis-analyze-operands ds instruction (x86-dis-flags dp))
2570              (or stop (eq (x86-dis-flags dp) :jump))))))
2571
2572(defun x86-disassemble-new-block (ds addr)
2573  (setf (x86-ds-code-pointer ds) addr)
2574  (let* ((limit (do-dll-nodes (b (x86-ds-blocks ds) (x86-ds-code-limit ds))
2575                  (when (> (x86-dis-block-start-address b) addr)
2576                    (return (x86-dis-block-start-address b)))))
2577         (block (make-x86-dis-block :start-address addr))
2578         (instructions (x86-dis-block-instructions block))
2579         (labeled (not (eql addr (x86-ds-entry-point ds)))))
2580    (loop
2581      (multiple-value-bind (instruction stop)
2582          (x86-disassemble-instruction ds labeled)
2583        (setq labeled nil)
2584        (append-dll-node instruction instructions)
2585        (if stop (return))
2586        (if (>= (x86-ds-code-pointer ds) limit)
2587          (if (= (x86-ds-code-pointer ds) limit)
2588            (return)
2589            (error "Internal disassembly error")))))
2590    (setf (x86-dis-block-end-address block) (x86-ds-code-pointer ds))
2591    (insert-x86-block block (x86-ds-blocks ds))))
2592
2593(defmethod unparse-x86-lap-expression ((exp t)
2594                                       ds)
2595  (declare (ignore ds))
2596  exp)
2597
2598(defmethod unparse-x86-lap-expression ((exp constant-x86-lap-expression)
2599                                       ds)
2600  (declare (ignore ds))
2601  (constant-x86-lap-expression-value exp))
2602
2603(defmethod unparse-x86-lap-expression ((exp label-x86-lap-expression)
2604                                       ds)
2605  (let* ((label (label-x86-lap-expression-label exp))
2606         (name (x86-lap-label-name label))
2607         (entry (x86-ds-entry-point ds)))
2608    `(":^" , (if (typep name 'fixnum)
2609            (format nil "L~d" (- name entry))
2610            name))))
2611
2612(defmethod unparse-x86-lap-expression ((exp unary-x86-lap-expression)
2613                                       ds)
2614  `(,(unary-x86-lap-expression-operator exp)
2615    ,(unparse-x86-lap-expression (unary-x86-lap-expression-operand exp) ds)))
2616
2617(defmethod unparse-x86-lap-expression ((exp binary-x86-lap-expression)
2618                                       ds)
2619  `(,(binary-x86-lap-expression-operator exp)
2620    ,(unparse-x86-lap-expression (binary-x86-lap-expression-operand0 exp) ds)
2621    ,(unparse-x86-lap-expression (binary-x86-lap-expression-operand1 exp) ds)))
2622
2623(defmethod unparse-x86-lap-expression ((exp n-ary-x86-lap-expression)
2624                                       ds)
2625  `(,(n-ary-x86-lap-expression-operator exp)
2626    ,@(mapcar #'(lambda (x)
2627                  (unparse-x86-lap-expression x ds))
2628              (n-ary-x86-lap-expression-operands exp))))
2629
2630(defmethod unparse-x86-lap-operand ((op x86::x86-register-operand)
2631                                    ds)
2632  (let* ((r (x86::x86-register-operand-entry op))
2633         (symbolic-names (x86-ds-symbolic-names ds))
2634         (reg-name (x86::reg-entry-reg-name r))
2635         (name (or (if symbolic-names
2636                     (gethash reg-name symbolic-names))
2637                     reg-name)))
2638    `(% ,name)))
2639
2640(defmethod unparse-x86-lap-operand ((op x86::x86-immediate-operand)
2641                                    ds)
2642  `($ ,(unparse-x86-lap-expression (x86::x86-immediate-operand-value op)
2643                                   ds)))
2644
2645(defmethod unparse-x86-lap-operand ((op x86::x86-label-operand)
2646                                    ds)
2647  (let* ((addr (x86::x86-label-operand-label op))
2648         (entrypoint (x86-ds-entry-point ds)))
2649    (format nil "L~d" (- addr entrypoint))))
2650
2651
2652   
2653(defmethod unparse-x86-lap-operand ((x x86::x86-memory-operand) ds)
2654  (let* ((seg (x86::x86-memory-operand-seg x))
2655         (disp (x86::x86-memory-operand-disp x)) 
2656         (base (x86::x86-memory-operand-base x))
2657         (index (x86::x86-memory-operand-index x))
2658         (scale (x86::x86-memory-operand-scale x))
2659         (val nil))
2660    (if (and base
2661             (eq (x86::x86-register-operand-entry base)
2662                 (if (x86-ds-mode-64 ds)
2663                   (x86::x86-reg64 13)
2664                   (x86::x86-reg32 6)))
2665             (null index)
2666             (or (eql scale 0) (null scale))
2667             (and (if (typep disp 'constant-x86-lap-expression)
2668                    (+ (x86-ds-entry-point ds)
2669                                  (constant-x86-lap-expression-value disp))
2670                    (unless (typep disp 'x86-lap-expression)
2671                      (setq val (if disp
2672                                  (+ (x86-ds-entry-point ds)
2673                                     disp)))))
2674                  (>= val (x86-ds-code-limit ds))))
2675      (let* ((diff (- val (x86-ds-code-limit ds)))
2676             (constant (uvref (x86-ds-constants-vector ds)
2677                              (1+ (ash diff -3)))))
2678        `(@ ',constant ,(unparse-x86-lap-operand base ds)))
2679      (collect ((subforms))
2680        (subforms '@)
2681        (if seg
2682          (subforms (unparse-x86-lap-operand seg ds)))
2683        (if disp
2684          (subforms (unparse-x86-lap-expression disp ds)))
2685        (if base
2686          (subforms (unparse-x86-lap-operand base ds)))
2687        (if index
2688          (subforms (unparse-x86-lap-operand index ds)))
2689        (if (and scale (not (eql scale 0)))
2690          (subforms (ash 1 scale)))
2691        (subforms)))))
2692   
2693(defmethod unparse-x86-lap-operand :around ((op x86::x86-operand)
2694                                            ds)
2695  (declare (ignore ds))
2696  (let* ((usual (call-next-method))
2697         (type (or (x86::x86-operand-type op) 0)))
2698    (if (logtest (x86::encode-operand-type :jumpabsolute) type)
2699      `(* ,usual)
2700      usual)))
2701
2702
2703   
2704   
2705(defun x86-print-disassembled-instruction (ds instruction seq)
2706  (let* ((addr (x86-di-address instruction))
2707         (entry (x86-ds-entry-point ds)))
2708    (when (x86-di-labeled instruction)
2709      (format t "~&L~d~&" (- addr entry))
2710      (setq seq 0))
2711    (dolist (p (x86-di-prefixes instruction))
2712      (format t "~&  (~a)~%" p))
2713    (format t "~&  (~a" (x86-di-mnemonic instruction))
2714    (let* ((op0 (x86-di-op0 instruction))
2715           (op1 (x86-di-op1 instruction))
2716           (op2 (x86-di-op2 instruction)))
2717      (when op0
2718        (format t " ~a" (unparse-x86-lap-operand op0 ds))
2719        (when op1
2720          (format t " ~a" (unparse-x86-lap-operand op1 ds))
2721          (when op2
2722            (format t " ~a" (unparse-x86-lap-operand op2 ds))))))
2723    (format t ")")
2724    (unless (zerop seq) ;(when (oddp seq)
2725      (format t "~50t;[~d]" (- addr entry)))
2726    (format t "~%")
2727    (1+ seq)))
2728
2729
2730(defun x8664-disassemble-xfunction (xfunction &key (symbolic-names
2731                                                         x8664::*x8664-symbolic-register-names*) (collect-function #'x86-print-disassembled-instruction))
2732  (check-type xfunction xfunction)
2733  (check-type (uvref xfunction 0) (simple-array (unsigned-byte 8) (*)))
2734  (let* ((ds (make-x86-disassembly-state
2735              :code-vector (uvref xfunction 0)
2736              :constants-vector xfunction
2737              :entry-point 7
2738              :code-pointer 0           ; for next-u32 below
2739              :symbolic-names symbolic-names
2740              :pending-labels (list 7)))
2741         (blocks (x86-ds-blocks ds)))
2742    (setf (x86-ds-code-limit ds)
2743          (ash (x86-ds-next-u32 ds) 3))
2744    (do* ()
2745         ((null (x86-ds-pending-labels ds)))
2746      (let* ((lab (pop (x86-ds-pending-labels ds))))
2747        (or (x86-dis-find-label lab blocks)
2748            (x86-disassemble-new-block ds lab))))
2749    (let* ((seq 0))
2750      (do-dll-nodes (block blocks)
2751        (do-dll-nodes (instruction (x86-dis-block-instructions block))
2752          (setq seq (funcall collect-function ds instruction seq)))))))
2753
2754#+x8664-target
2755(defun x8664-xdisassemble (function &optional (collect-function #'x86-print-disassembled-instruction ))
2756  (let* ((fv (%function-to-function-vector function))
2757         (function-size-in-words (uvsize fv))
2758         (code-words (%function-code-words function))
2759         (ncode-bytes (ash function-size-in-words x8664::word-shift))
2760         (code-bytes (make-array ncode-bytes
2761                                 :element-type '(unsigned-byte 8)))
2762         (numimms (- function-size-in-words code-words))
2763         (xfunction (%alloc-misc (the fixnum (1+ numimms)) target::subtag-xfunction)))
2764    (declare (fixnum code-words ncode-bytes numimms))
2765    (%copy-ivector-to-ivector fv 0 code-bytes 0 ncode-bytes)
2766    (setf (uvref xfunction 0) code-bytes)
2767    (do* ((k code-words (1+ k))
2768          (j 1 (1+ j)))
2769         ((= k function-size-in-words)
2770          (x8664-disassemble-xfunction xfunction :collect-function collect-function))
2771      (declare (fixnum j k))
2772      (setf (uvref xfunction j) (uvref fv k)))))
2773
2774(defun disassemble-list (function)
2775  (collect ((instructions))
2776    (x8664-xdisassemble
2777     function
2778     #'(lambda (ds instruction seq)
2779         (collect ((insn))
2780           (let* ((addr (x86-di-address instruction))
2781                  (entry (x86-ds-entry-point ds))
2782                  (rpc (- addr entry)))
2783             (if (x86-di-labeled instruction)
2784               (progn
2785                 (insn `(label ,rpc))
2786                 (setq seq 0))
2787               (insn rpc))
2788             (dolist (p (x86-di-prefixes instruction))
2789               (insn p))
2790             (insn (x86-di-mnemonic instruction))
2791             (let* ((op0 (x86-di-op0 instruction))
2792                    (op1 (x86-di-op1 instruction))
2793                    (op2 (x86-di-op2 instruction)))
2794               (when op0
2795                 (insn (unparse-x86-lap-operand op0 ds))
2796                 (when op1
2797                   (insn (unparse-x86-lap-operand op1 ds))
2798                   (when op2
2799                     (insn (unparse-x86-lap-operand op2 ds))  ))))
2800             (instructions (insn))
2801             (1+ seq)))))
2802    (instructions)))
2803                         
2804             
2805
2806           
2807         
2808
2809                                     
2810           
2811     
2812           
2813             
Note: See TracBrowser for help on using the repository browser.