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

Last change on this file since 10486 was 10486, checked in by gb, 11 years ago

When disassembling ia32 code, treat (movl ($ n) (% fn)) as
(recover-fn).

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