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

Last change on this file since 10202 was 10202, checked in by rme, 12 years ago

Add support for disassembling 32-bit x86 functions.

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