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

Last change on this file since 12846 was 12846, checked in by gz, 10 years ago

Make the gui inspector show function disassembly. Extend the inspector protocol to support this a little better. Fix a number of bugs in closing and method inspectors.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 125.1 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         (regmask (if (x86-ds-mode-64 ds) #xf #x7)))
2234    (cond ((and (>= intop #x70) (< intop #x80))
2235           (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2236             (setf (x86-di-mnemonic instruction)
2237                   "uuo-error-slot-unbound"
2238                   (x86-di-op0 instruction)
2239                   (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))                     
2240                   (x86-di-op1 instruction)
2241                   (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 4)
2242                                                                       pseudo-modrm-byte) :%))
2243                   (x86-di-op2 instruction)
2244                   (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 0)
2245                                                                       pseudo-modrm-byte) :%)))))
2246          ((< intop #x90)
2247           (setf (x86-di-mnemonic instruction) "int"
2248                 (x86-di-op0 instruction)
2249                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression intop))))
2250          ((< intop #xa0)
2251           (setf (x86-di-mnemonic instruction)
2252                 "uuo-error-unbound"
2253                 (x86-di-op0 instruction)
2254                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))))
2255          ((< intop #xb0)
2256           (setf (x86-di-mnemonic instruction)
2257                 "uuo-error-udf"
2258                 (x86-di-op0 instruction)
2259                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))))
2260         
2261          ((< intop #xc0)
2262           (setf (x86-di-mnemonic instruction)
2263                 "uuo-error-reg-not-type"
2264                 (x86-di-op0 instruction)
2265                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))
2266                 (x86-di-op1 instruction)
2267                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression (x86-ds-next-u8 ds)))))
2268          ((< intop #xc8)
2269           (if (= intop #xc3)
2270             (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2271               (setf (x86-di-mnemonic instruction)
2272                     "uuo-error-array-rank"
2273                     (x86-di-op0 instruction)
2274                     (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 4)
2275                                                                         pseudo-modrm-byte) :%))
2276                     (x86-di-op1 instruction)
2277                     (x86-dis-make-reg-operand (lookup-x86-register (ldb (byte 4 0)
2278                                                                         pseudo-modrm-byte) :%))))
2279                   
2280           (setf (x86-di-mnemonic instruction)
2281                 (case intop
2282                   (#xc0 "uuo-error-too-few-args")
2283                   (#xc1 "uuo-error-too-many-args")
2284                   (#xc2 "uuo-error-wrong-number-of-args")
2285                   (#xc4 (progn (setq stop nil) "uuo-gc-trap"))
2286                   (#xc5 "uuo-alloc")
2287                   (#xc6 "uuo-error-not-callable")
2288                   (#xc7 "uuo-udf-call")
2289                   (t "unknown-UUO")))))
2290          ((= intop #xc8)
2291           (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2292             (declare (type (unsigned-byte 8) pseudo-modrm-byte))
2293             (setf (x86-di-op0 instruction)
2294                 (x86-dis-make-reg-operand
2295                  (lookup-x86-register (ldb (byte 4 4) pseudo-modrm-byte) :%))
2296                 (x86-di-op1 instruction)
2297                 (x86-dis-make-reg-operand
2298                  (lookup-x86-register (ldb (byte 4 0) pseudo-modrm-byte) :%))
2299                 (x86-di-mnemonic instruction) "uuo-error-vector-bounds")))
2300          ((< intop #xd0)
2301           (cond ((= intop #xcb)
2302                  (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2303                    (setf (x86-di-mnemonic instruction)
2304                          "uuo-error-array-bounds"
2305                          (x86-di-op0 instruction)
2306                          (x86-dis-make-reg-operand
2307                           (lookup-x86-register (ldb (byte 4 4)
2308                                                     pseudo-modrm-byte) :%))
2309                          (x86-di-op1 instruction)
2310                          (x86-dis-make-reg-operand
2311                           (lookup-x86-register (ldb (byte 4 0)
2312                                                     pseudo-modrm-byte) :%)))))
2313                 ((= intop #xcc)
2314                  (let* ((pseudo-modrm-byte (x86-ds-next-u8 ds)))
2315                    (setf (x86-di-mnemonic instruction)
2316                          "uuo-error-eep-unresolved"
2317                          (x86-di-op0 instruction)
2318                          (x86-dis-make-reg-operand
2319                           (lookup-x86-register (ldb (byte 4 4)
2320                                                     pseudo-modrm-byte) :%))
2321                          (x86-di-op1 instruction)
2322                          (x86-dis-make-reg-operand
2323                           (lookup-x86-register (ldb (byte 4 0)
2324                                                     pseudo-modrm-byte) :%)))))
2325                 (t (setf (x86-di-mnemonic instruction)
2326                          (case intop
2327                            (#xc9 "uuo-error-call-macro-or-special-operator")
2328                            (#xca (setq stop nil) "uuo-error-debug-trap")
2329                            (#xcd (setq stop nil) "uuo-error-debug-trap-with-string")
2330                            (t "unknown-UUO"))))))
2331          ((< intop #xe0)
2332           (setf (x86-di-mnemonic instruction)
2333                 "uuo-error-reg-not-tag"
2334                 (x86-di-op0 instruction)
2335                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))
2336                 (x86-di-op1 instruction)
2337                 (x86::make-x86-immediate-operand :value (parse-x86-lap-expression (x86-ds-next-u8 ds)))))
2338          ((< intop #xf0)
2339           (setf (x86-di-mnemonic instruction)
2340                 "uuo-error-reg-not-list"
2341                 (x86-di-op0 instruction)
2342                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%))))
2343          (t
2344           (setf (x86-di-mnemonic instruction)
2345                 "uuo-error-reg-not-fixnum"
2346                 (x86-di-op0 instruction)
2347                 (x86-dis-make-reg-operand (lookup-x86-register (logand intop regmask) :%)))))
2348    stop))
2349
2350
2351
2352(defun x86-dis-analyze-operands (ds instruction flag)
2353  ;; If instruction is adding a positive displacement to the FN
2354  ;; register, note the effective address as a label reference
2355  ;; and modify the operand(s).
2356  ;; If the instruction is a MOV or PUSH whose source operand
2357  ;; is relative to the FN register, generate a constant reference.
2358  ;; If the instruction is adding a displacement to RIP, note
2359  ;; the effective address as a label reference.
2360  ;; On ia32, if op0 is a 32-bit immediate and op1 is (% fn),
2361  ;; treat the immediate as :self.
2362  (let* ((op0 (x86-di-op0 instruction))
2363         (op1 (x86-di-op1 instruction))
2364         (entry-ea (x86-ds-entry-point ds)))
2365    (flet ((is-fn (thing)
2366             (if (typep thing 'x86::x86-register-operand)
2367               (let* ((entry (x86::x86-register-operand-entry thing)))
2368                 (eq entry (if (x86-ds-mode-64 ds)
2369                             (x86::x86-reg64 13)
2370                             (x86::x86-reg32 x8632::fn))))))
2371           (is-rip (thing)
2372             (if (and (typep thing 'x86::x86-register-operand)
2373                      (x86-ds-mode-64 ds))
2374               (let* ((entry (x86::x86-register-operand-entry thing)))
2375                 (eq entry (svref x86::*x8664-register-entries* 102)))))
2376           (is-ra0 (thing)
2377             (if (typep thing 'x86::x86-register-operand)
2378               (let* ((entry (x86::x86-register-operand-entry thing)))
2379                 (eq entry (if (x86-ds-mode-64 ds)
2380                             (x86::x86-reg64 10)
2381                             (x86::x86-reg32 7))))))
2382           (is-disp-only (thing)
2383             (and (typep thing 'x86::x86-memory-operand)
2384                  (null (x86::x86-memory-operand-base thing))
2385                  (null (x86::x86-memory-operand-index thing))
2386                  (x86::x86-memory-operand-disp thing))))
2387      (flet ((is-fn-ea (thing)
2388               (and (typep thing 'x86::x86-memory-operand)
2389                    (is-fn (x86::x86-memory-operand-base thing))
2390                    (null (x86::x86-memory-operand-index thing))
2391                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2392                      (or (null scale) (eql 0 scale)))
2393                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2394                      (and disp (early-x86-lap-expression-value disp)))))
2395             (is-ra0-ea (thing)
2396               (and (typep thing 'x86::x86-memory-operand)
2397                    (is-ra0 (x86::x86-memory-operand-base thing))
2398                    (null (x86::x86-memory-operand-index thing))
2399                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2400                      (or (null scale) (eql 0 scale)))
2401                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2402                      (and disp (early-x86-lap-expression-value disp)))))
2403             (is-rip-ea (thing)
2404               (and (typep thing 'x86::x86-memory-operand)
2405                    (is-rip (x86::x86-memory-operand-base thing))
2406                    (null (x86::x86-memory-operand-index thing))
2407                    (let* ((scale (x86::x86-memory-operand-scale thing)))
2408                      (or (null scale) (eql 0 scale)))
2409                    (let* ((disp (x86::x86-memory-operand-disp thing)))
2410                      (and disp (early-x86-lap-expression-value disp))))))
2411        (case flag
2412          ;; Should also check alignment here, and check
2413         
2414          (:lea
2415           (let* ((disp ))
2416             (if (or (and (setq disp (is-fn-ea op0)) (> disp 0))
2417                       (and (setq disp (is-ra0-ea op0)) (< disp 0) (is-fn op1)))
2418               (let* ((label-ea (+ entry-ea (abs disp))))
2419                 (when (< label-ea (x86-ds-code-limit ds))
2420                   (setf (x86::x86-memory-operand-disp op0)
2421                         (parse-x86-lap-expression
2422                          (if (< disp 0)
2423                            `(- (:^ ,label-ea))
2424                            `(:^ ,label-ea))))
2425                   (push label-ea (x86-ds-pending-labels ds))))
2426               (if (and (setq disp (is-rip-ea op0)) (< disp 0) (is-fn op1))
2427                 (progn
2428                   (setf (x86::x86-memory-operand-disp op0)
2429                         (parse-x86-lap-expression `(:^ ,entry-ea)))
2430                   (push entry-ea (x86-ds-pending-labels ds)))))))
2431          ((:jump :call)
2432           (let* ((disp (is-disp-only op0)))
2433             (when disp
2434               (let* ((info (find (early-x86-lap-expression-value disp)
2435                                  (if (x86-ds-mode-64 ds)
2436                                    x8664::*x8664-subprims*
2437                                    x8632::*x8632-subprims*)
2438                                  :key #'subprimitive-info-offset)))
2439                 (when info (setf (x86::x86-memory-operand-disp op0)
2440                                  (subprimitive-info-name info)))))))
2441          (t
2442           (unless (x86-ds-mode-64 ds)
2443             (when (and (is-fn op1)
2444                        (typep op0 'x86::x86-immediate-operand)
2445                        ;; Not sure what else would have an
2446                        ;; immediate source and %fn as destination,
2447                        ;; but check for this.
2448                        (equal (x86-di-mnemonic instruction) "movl"))
2449               (setf (x86-di-mnemonic instruction) "recover-fn"
2450                     (x86-di-op0 instruction) nil
2451                     (x86-di-op0 instruction) nil))))
2452
2453          )))
2454    instruction))
2455
2456(defun x86-disassemble-instruction (ds labeled)
2457  (let* ((addr (x86-ds-code-pointer ds))
2458         (sizeflag (logior +aflag+ +dflag+
2459                           (if *x86-dissassemble-always-print-suffix*
2460                             +suffix-always+
2461                             0)))
2462         (instruction (make-x86-disassembled-instruction :address addr
2463                                                         :labeled labeled))
2464         (stop nil))
2465    (setf (x86-ds-insn-start ds) addr
2466          (x86-ds-current-instruction ds) instruction)
2467    (scan-prefixes ds instruction)
2468    (setf (x86-ds-opcode-start ds) (x86-ds-code-pointer ds))
2469    (let* ((primary-opcode (x86-ds-next-u8 ds))
2470           (two-source-ops (or (= primary-opcode #x62)
2471                               (= primary-opcode #xc8)))
2472           (prefixes (x86-ds-prefixes ds))
2473           (need-modrm nil)
2474           (uses-sse-prefix nil)
2475           (uses-lock-prefix nil)
2476           (dp nil))
2477      (declare (type (unsigned-byte 8) primary-opcode)
2478               (fixnum prefixes))
2479      (if (= primary-opcode #x0f)       ;two-byte opcode
2480        (setq primary-opcode (x86-ds-next-u8 ds)
2481              dp (svref *disx86-twobyte* primary-opcode)
2482              need-modrm (eql 1 (sbit *twobyte-has-modrm* primary-opcode))
2483              uses-sse-prefix (eql 1 (sbit *twobyte-uses-sse-prefix* primary-opcode))
2484              uses-lock-prefix (= #x20 (logandc2 primary-opcode 2)))
2485        (setq dp (svref *disx86* primary-opcode)
2486              need-modrm (eql 1 (sbit *onebyte-has-modrm* primary-opcode))))
2487      (when (and (not uses-sse-prefix) 
2488                 (logtest prefixes +prefix-repz+))
2489        (push "repz" (x86-di-prefixes instruction))
2490        (setf (x86-ds-used-prefixes ds)
2491              (logior (x86-ds-used-prefixes ds) +prefix-repz+)))
2492      (when (and (not uses-sse-prefix) 
2493                 (logtest prefixes +prefix-repnz+))
2494        (push "repnz" (x86-di-prefixes instruction))
2495        (setf (x86-ds-used-prefixes ds)
2496              (logior (x86-ds-used-prefixes ds) +prefix-repnz+)))
2497      (when (and (not uses-lock-prefix)
2498                 (logtest prefixes +prefix-lock+))
2499        (push "lock" (x86-di-prefixes instruction))
2500        (setf (x86-ds-used-prefixes ds)
2501              (logior (x86-ds-used-prefixes ds) +prefix-lock+)))
2502      (when (logtest prefixes +prefix-addr+)
2503        (setq sizeflag (logxor sizeflag +aflag+))
2504        (unless (= (x86-dis-bytemode3 dp) +loop-jcxz-mode+)
2505          (if (or (x86-ds-mode-64 ds)
2506                  (logtest sizeflag +aflag+))
2507            (push "addr32" (x86-di-prefixes instruction))
2508            (push "addr16" (x86-di-prefixes instruction)))
2509          (setf (x86-ds-used-prefixes ds)
2510                (logior (x86-ds-used-prefixes ds) +prefix-addr+))))
2511      (when (and (not uses-sse-prefix)
2512                 (logtest prefixes +prefix-data+))
2513        (setq sizeflag (logxor sizeflag +dflag+))
2514        (when (and (= (x86-dis-bytemode3 dp) +cond-jump-mode+)
2515                   (= (x86-dis-bytemode1 dp) +v-mode+))
2516          (if (logtest sizeflag +dflag+)
2517            (push "data32" (x86-di-prefixes instruction))
2518            (push "data16" (x86-di-prefixes instruction)))
2519          (setf (x86-ds-used-prefixes ds)
2520                (logior (x86-ds-used-prefixes ds) +prefix-data+))))
2521      (when need-modrm
2522        (let* ((modrm-byte (x86-ds-peek-u8 ds)))
2523          (declare (type (unsigned-byte 8) modrm-byte))
2524          (setf (x86-ds-mod ds) (ldb (byte 2 6) modrm-byte)
2525                (x86-ds-reg ds) (ldb (byte 3 3) modrm-byte)
2526                (x86-ds-rm ds) (ldb (byte 3 0) modrm-byte))))
2527      (if (and (null (x86-dis-mnemonic dp))
2528               (eql (x86-dis-bytemode1 dp) +floatcode+))
2529        (x86-dis-do-float ds instruction primary-opcode sizeflag)
2530        (if (and (null (x86-dis-mnemonic dp))
2531                 (eql (x86-dis-bytemode1 dp) +uuocode+))
2532          (progn
2533            (setq stop
2534                  (x86-dis-do-uuo ds instruction (x86-ds-next-u8 ds))))
2535          (progn
2536            (when (null (x86-dis-mnemonic dp))
2537              (let* ((bytemode1 (x86-dis-bytemode1 dp)))
2538                (declare (fixnum bytemode1))
2539                (cond ((= bytemode1 +use-groups+)
2540                       (setq dp (svref (svref *grps* (x86-dis-bytemode2 dp))
2541                                       (x86-ds-reg ds))))
2542                      ((= bytemode1 +use-prefix-user-table+)
2543                       (let* ((index 0))
2544                         (used-prefix ds +prefix-repz+)
2545                         (if (logtest prefixes +prefix-repz+)
2546                           (setq index 1)
2547                           (progn
2548                             (used-prefix ds +prefix-data+)
2549                             (if (logtest prefixes +prefix-data+)
2550                               (setq index 2)
2551                               (progn
2552                                 (used-prefix ds +prefix-repnz+)
2553                                 (if (logtest prefixes +prefix-repnz+)
2554                                   (setq index 3))))))
2555                         (setq dp (svref (svref *prefix-user-table*
2556                                                (x86-dis-bytemode2 dp))
2557                                         index))))
2558                      ((= bytemode1 +x86-64-special+)
2559                       (setq dp (svref (svref *x86-64-table*
2560                                              (x86-dis-bytemode2 dp))
2561                                       (if (x86-ds-mode-64 ds) 1 0))))
2562                    (t (error "Disassembly error")))))
2563          (when (x86-putop ds (x86-dis-mnemonic dp) sizeflag instruction)
2564            (let* ((operands ())
2565                   (op1 (x86-dis-op1 dp))
2566                   (op2 (x86-dis-op2 dp))
2567                   (op3 (x86-dis-op3 dp))
2568                   (operand nil))
2569              (when op1
2570                ;(format t "~& op1 = ~s" op1)
2571                (setq operand (funcall op1 ds (x86-dis-bytemode1 dp) sizeflag))
2572                (if operand
2573                  (push operand operands)))
2574              (when op2
2575                ;(format t "~& op2 = ~s" op2)
2576                (setq operand (funcall op2 ds (x86-dis-bytemode2 dp) sizeflag))
2577                (if operand
2578                  (push operand operands)))
2579              (when op3
2580                ;(format t "~& op3 = ~s" op3)
2581                (setq operand (funcall op3 ds (x86-dis-bytemode3 dp) sizeflag))
2582                (if operand
2583                  (push operand operands)))
2584              (if two-source-ops
2585                (setf (x86-di-op1 instruction) (pop operands)
2586                      (x86-di-op0 instruction) (pop operands))
2587                (setf (x86-di-op0 instruction) (pop operands)
2588                      (x86-di-op1 instruction) (pop operands)
2589                      (x86-di-op2 instruction) (pop operands))))))))
2590      (values (x86-dis-analyze-operands ds instruction (x86-dis-flags dp))
2591              (or stop (eq (x86-dis-flags dp) :jump))))))
2592
2593(defun x86-disassemble-new-block (ds addr)
2594  (setf (x86-ds-code-pointer ds) addr)
2595  (let* ((limit (do-dll-nodes (b (x86-ds-blocks ds) (x86-ds-code-limit ds))
2596                  (when (> (x86-dis-block-start-address b) addr)
2597                    (return (x86-dis-block-start-address b)))))
2598         (block (make-x86-dis-block :start-address addr))
2599         (instructions (x86-dis-block-instructions block))
2600         (labeled (not (eql addr (x86-ds-entry-point ds)))))
2601    (loop
2602      (multiple-value-bind (instruction stop)
2603          (x86-disassemble-instruction ds labeled)
2604        (setq labeled nil)
2605        (append-dll-node instruction instructions)
2606        (if stop (return))
2607        (if (>= (x86-ds-code-pointer ds) limit)
2608          (if (= (x86-ds-code-pointer ds) limit)
2609            (return)
2610            (error "Internal disassembly error")))))
2611    (setf (x86-dis-block-end-address block) (x86-ds-code-pointer ds))
2612    (insert-x86-block block (x86-ds-blocks ds))))
2613
2614(defmethod unparse-x86-lap-expression ((exp t)
2615                                       ds)
2616  (declare (ignore ds))
2617  exp)
2618
2619(defmethod unparse-x86-lap-expression ((exp constant-x86-lap-expression)
2620                                       ds)
2621  (declare (ignore ds))
2622  (constant-x86-lap-expression-value exp))
2623
2624(defmethod unparse-x86-lap-expression ((exp label-x86-lap-expression)
2625                                       ds)
2626  (let* ((label (label-x86-lap-expression-label exp))
2627         (name (x86-lap-label-name label))
2628         (entry (x86-ds-entry-point ds)))
2629    `(":^" , (if (typep name 'fixnum)
2630            (format nil "L~d" (- name entry))
2631            name))))
2632
2633(defmethod unparse-x86-lap-expression ((exp unary-x86-lap-expression)
2634                                       ds)
2635  `(,(unary-x86-lap-expression-operator exp)
2636    ,(unparse-x86-lap-expression (unary-x86-lap-expression-operand exp) ds)))
2637
2638(defmethod unparse-x86-lap-expression ((exp binary-x86-lap-expression)
2639                                       ds)
2640  `(,(binary-x86-lap-expression-operator exp)
2641    ,(unparse-x86-lap-expression (binary-x86-lap-expression-operand0 exp) ds)
2642    ,(unparse-x86-lap-expression (binary-x86-lap-expression-operand1 exp) ds)))
2643
2644(defmethod unparse-x86-lap-expression ((exp n-ary-x86-lap-expression)
2645                                       ds)
2646  `(,(n-ary-x86-lap-expression-operator exp)
2647    ,@(mapcar #'(lambda (x)
2648                  (unparse-x86-lap-expression x ds))
2649              (n-ary-x86-lap-expression-operands exp))))
2650
2651(defmethod unparse-x86-lap-operand ((op x86::x86-register-operand)
2652                                    ds)
2653  (let* ((r (x86::x86-register-operand-entry op))
2654         (symbolic-names (x86-ds-symbolic-names ds))
2655         (reg-name (x86::reg-entry-reg-name r))
2656         (name (or (if symbolic-names
2657                     (gethash reg-name symbolic-names))
2658                     reg-name)))
2659    `(% ,name)))
2660
2661(defmethod unparse-x86-lap-operand ((op x86::x86-immediate-operand)
2662                                    ds)
2663  `($ ,(unparse-x86-lap-expression (x86::x86-immediate-operand-value op)
2664                                   ds)))
2665
2666(defmethod unparse-x86-lap-operand ((op x86::x86-label-operand)
2667                                    ds)
2668  (let* ((addr (x86::x86-label-operand-label op))
2669         (entrypoint (x86-ds-entry-point ds)))
2670    (format nil "L~d" (- addr entrypoint))))
2671
2672
2673(defmethod x86-lap-operand-constant-offset (op ds)
2674  (declare (ignore op ds))
2675  nil)
2676
2677(defmethod x86-lap-operand-constant-offset ((op x86::x86-memory-operand) ds)
2678  (let* ((disp (x86::x86-memory-operand-disp op)) 
2679         (base (x86::x86-memory-operand-base op))
2680         (index (x86::x86-memory-operand-index op))
2681         (scale (x86::x86-memory-operand-scale op))
2682         (code-limit (x86-ds-code-limit ds))
2683         (val (and base
2684                   (eq (x86::x86-register-operand-entry base)
2685                       (if (x86-ds-mode-64 ds)
2686                         (x86::x86-reg64 13)
2687                         (x86::x86-reg32 x8632::fn)))
2688                   (null index)
2689                   (or (eql scale 0) (null scale))
2690                   (typecase disp
2691                     (constant-x86-lap-expression
2692                      (+ (x86-ds-entry-point ds)
2693                         (constant-x86-lap-expression-value disp)))
2694                     (integer
2695                      (+ (x86-ds-entry-point ds) disp))
2696                     (t nil)))))
2697    (when (and val (>= val code-limit))
2698      (- val code-limit))))
2699
2700(defun x86-lap-operand-constant (op ds)
2701  (let ((diff (x86-lap-operand-constant-offset op ds)))
2702    (when diff
2703      (values (uvref (x86-ds-constants-vector ds)
2704                     (1+ (ash diff (if (x86-ds-mode-64 ds)
2705                                     (- x8664::word-shift)
2706                                     (- x8632::word-shift)))))
2707              t))))
2708
2709
2710(defmethod unparse-x86-lap-operand ((x x86::x86-memory-operand) ds)
2711  (multiple-value-bind (constant foundp) (x86-lap-operand-constant x ds)
2712    (if foundp
2713      `(@ ',constant ,(unparse-x86-lap-operand (x86::x86-memory-operand-base x) ds))
2714      (let* ((seg (x86::x86-memory-operand-seg x))
2715             (disp (x86::x86-memory-operand-disp x)) 
2716             (base (x86::x86-memory-operand-base x))
2717             (index (x86::x86-memory-operand-index x))
2718             (scale (x86::x86-memory-operand-scale x)))
2719        (collect ((subforms))
2720          (subforms '@)
2721          (if seg
2722            (subforms (unparse-x86-lap-operand seg ds)))
2723          (if disp
2724            (subforms (unparse-x86-lap-expression disp ds)))
2725          (if base
2726            (subforms (unparse-x86-lap-operand base ds)))
2727          (if index
2728            (subforms (unparse-x86-lap-operand index ds)))
2729          (if (and scale (not (eql scale 0)))
2730            (subforms (ash 1 scale)))
2731          (subforms))))))
2732   
2733(defmethod unparse-x86-lap-operand :around ((op x86::x86-operand)
2734                                            ds)
2735  (declare (ignore ds))
2736  (let* ((usual (call-next-method))
2737         (type (or (x86::x86-operand-type op) 0)))
2738    (if (logtest (x86::encode-operand-type :jumpabsolute) type)
2739      `(* ,usual)
2740      usual)))
2741
2742(defun write-x86-lap-operand (stream op ds)
2743  ;; Basically, have to princ because some parts are already stringified,
2744  ;; plus don't want package prefixes on assembler syntax.  But want to
2745  ;; prin1 immediates.
2746  (let ((expr (unparse-x86-lap-operand op ds)))
2747    (format stream " ")
2748    (labels ((out (stream expr)
2749               (cond ((atom expr)
2750                      (format stream "~a" expr))
2751                     ((quoted-form-p expr)
2752                      (format stream "'~s" (cadr expr)))
2753                     (t
2754                      (loop for item in expr as pre = "(" then " "
2755                        do (format stream pre)
2756                        do (out stream item))
2757                      (format stream ")")))))
2758      (out stream expr))))
2759
2760(defvar *previous-source-note*)
2761
2762(defun x86-print-disassembled-instruction (ds instruction seq function)
2763  (let* ((addr (x86-di-address instruction))
2764         (entry (x86-ds-entry-point ds))
2765         (pc (- addr entry)))
2766    (let ((source-note (find-source-note-at-pc function pc)))
2767      (unless (eql (source-note-file-range source-note)
2768                   (source-note-file-range *previous-source-note*))
2769        (setf *previous-source-note* source-note)
2770        (let* ((source-text (source-note-text source-note))
2771               (text (if source-text
2772                       (string-sans-most-whitespace source-text 100)
2773                       "#<no source text>")))
2774          (format t "~&~%;;; ~A" text))))
2775    (when (x86-di-labeled instruction)
2776      (format t "~&L~d~%" pc)
2777      (setq seq 0))
2778    (format t "~&  [~D]~8T" pc)
2779    (dolist (p (x86-di-prefixes instruction))
2780      (format t "~&  (~a)~%" p))
2781    (format t "  (~a" (x86-di-mnemonic instruction))
2782    (let* ((op0 (x86-di-op0 instruction))
2783           (op1 (x86-di-op1 instruction))
2784           (op2 (x86-di-op2 instruction)))
2785      (when op0
2786        (write-x86-lap-operand t op0 ds)
2787        (when op1
2788        (write-x86-lap-operand t op1 ds)
2789          (when op2
2790            (write-x86-lap-operand t op2 ds)))))
2791    (format t ")")
2792    (format t "~%")
2793    (1+ seq)))
2794
2795(defun x86-print-disassembled-function-header (function xfunction)
2796  (declare (ignore xfunction))
2797  (let ((source-note (function-source-note function)))
2798    (when source-note
2799      (format t ";; Source: ~S:~D-~D"
2800              (source-note-filename source-note)
2801              (source-note-start-pos source-note)
2802              (source-note-end-pos source-note))
2803      ;; Fetch source from file if don't already have it.
2804      (ensure-source-note-text source-note))))
2805
2806(defun x86-disassemble-xfunction (function xfunction
2807                                  &key (symbolic-names #+x8664-target target::*x8664-symbolic-register-names*
2808                                                       #+x8632-target target::*x8632-symbolic-register-names*)
2809                                       (collect-function #'x86-print-disassembled-instruction)
2810                                       (header-function #'x86-print-disassembled-function-header))
2811  (check-type xfunction xfunction)
2812  (check-type (uvref xfunction 0) (simple-array (unsigned-byte 8) (*)))
2813  (let* ((entry-point  #+x8664-target 7  #+x8632-target 2)
2814         (ds (make-x86-disassembly-state
2815              :mode-64 #+x8664-target t #+x8632-target nil
2816              :code-vector (uvref xfunction 0)
2817              :constants-vector xfunction
2818              :entry-point entry-point
2819              :code-pointer 0           ; for next-u32/next-u16 below
2820              :symbolic-names symbolic-names
2821              :pending-labels (list entry-point)))
2822         (blocks (x86-ds-blocks ds)))
2823    (setf (x86-ds-code-limit ds)
2824          #+x8664-target (ash (x86-ds-next-u32 ds) 3)
2825          #+x8632-target (ash (x86-ds-next-u16 ds) 2))
2826    (do* ()
2827         ((null (x86-ds-pending-labels ds)))
2828      (let* ((lab (pop (x86-ds-pending-labels ds))))
2829        (or (x86-dis-find-label lab blocks)
2830            (x86-disassemble-new-block ds lab))))
2831    (when (and header-function
2832               blocks
2833               (let ((something-to-disassemble nil))
2834                 (do-dll-nodes (block blocks)
2835                   (do-dll-nodes (instruction (x86-dis-block-instructions block))
2836                     (setf something-to-disassemble t)))
2837                 something-to-disassemble))
2838      (funcall header-function function xfunction))
2839    (let* ((seq 0)
2840           (*previous-source-note* nil))
2841      (declare (special *previous-source-note*))
2842      (do-dll-nodes (block blocks)
2843        (do-dll-nodes (instruction (x86-dis-block-instructions block))
2844          (setq seq (funcall collect-function ds instruction seq function)))))))
2845
2846(defun x86-xdisassemble (function
2847                         &optional (collect-function #'x86-print-disassembled-instruction)
2848                                   (header-function #'x86-print-disassembled-function-header))
2849  (let* ((fv (function-to-function-vector function))
2850         (function-size-in-words (uvsize fv))
2851         (code-words (%function-code-words function))
2852         (ncode-bytes (ash function-size-in-words target::word-shift))
2853         (code-bytes (make-array ncode-bytes
2854                                 :element-type '(unsigned-byte 8)))
2855         (numimms (- function-size-in-words code-words))
2856         (xfunction (%alloc-misc (the fixnum (1+ numimms)) target::subtag-xfunction)))
2857    (declare (fixnum code-words ncode-bytes numimms))
2858    (%copy-ivector-to-ivector fv 0 code-bytes 0 ncode-bytes)
2859    (setf (uvref xfunction 0) code-bytes)
2860    (do* ((k code-words (1+ k))
2861          (j 1 (1+ j)))
2862         ((= k function-size-in-words)
2863          (x86-disassemble-xfunction function xfunction
2864                                     :collect-function collect-function
2865                                     :header-function header-function))
2866      (declare (fixnum j k))
2867      (setf (uvref xfunction j) (uvref fv k)))))
2868
2869(defun disassemble-list (function)
2870  (collect ((instructions))
2871    (x86-xdisassemble
2872     function
2873     #'(lambda (ds instruction seq function)
2874         (declare (ignore function))
2875         (collect ((insn))
2876           (let* ((addr (x86-di-address instruction))
2877                  (entry (x86-ds-entry-point ds))
2878                  (rpc (- addr entry)))
2879             (if (x86-di-labeled instruction)
2880               (progn
2881                 (insn `(label ,rpc))
2882                 (setq seq 0))
2883               (insn rpc))
2884             (dolist (p (x86-di-prefixes instruction))
2885               (insn p))
2886             (insn (x86-di-mnemonic instruction))
2887             (let* ((op0 (x86-di-op0 instruction))
2888                    (op1 (x86-di-op1 instruction))
2889                    (op2 (x86-di-op2 instruction)))
2890               (when op0
2891                 (insn (unparse-x86-lap-operand op0 ds))
2892                 (when op1
2893                   (insn (unparse-x86-lap-operand op1 ds))
2894                   (when op2
2895                     (insn (unparse-x86-lap-operand op2 ds))  ))))
2896             (instructions (insn))
2897             (1+ seq))))
2898     nil)
2899    (instructions)))
2900
2901(defun x86-disassembled-instruction-line (ds instruction function &optional string-stream)
2902  (if (null string-stream)
2903    (with-output-to-string (stream)
2904      (return-from x86-disassembled-instruction-line
2905                   (x86-disassembled-instruction-line ds instruction function stream)))
2906    (let* ((addr (x86-di-address instruction))
2907           (entry (x86-ds-entry-point ds))
2908           (pc (- addr entry))
2909           (op0 (x86-di-op0 instruction))
2910           (op1 (x86-di-op1 instruction))
2911           (op2 (x86-di-op2 instruction))
2912           (label (if (x86-di-labeled instruction) (list :label pc) pc))
2913           (instr (progn
2914                    (dolist (p (x86-di-prefixes instruction))
2915                      (format string-stream "(~a) " p))
2916                    (format string-stream "(~a" (x86-di-mnemonic instruction))
2917                    (when op0 (write-x86-lap-operand string-stream op0 ds))
2918                    (when op1 (write-x86-lap-operand string-stream op1 ds))
2919                    (when op2 (write-x86-lap-operand string-stream op2 ds))
2920                    (format string-stream ")")
2921                    (get-output-stream-string string-stream)))
2922           (comment (let ((source-note (find-source-note-at-pc function pc)))
2923                      (unless (eql (source-note-file-range source-note)
2924                                   (source-note-file-range *previous-source-note*))
2925                        (setf *previous-source-note* source-note)
2926                        (let* ((source-text (source-note-text source-note))
2927                               (text (if source-text
2928                                       (string-sans-most-whitespace source-text 100)
2929                                       "#<no source text>")))
2930                          (format string-stream ";;; ~A" text)
2931                          (get-output-stream-string string-stream)))))
2932           (imms (let ((imms nil))
2933                   (multiple-value-bind (imm foundp) (x86-lap-operand-constant op2 ds)
2934                     (when foundp (push imm imms)))
2935                   (multiple-value-bind (imm foundp) (x86-lap-operand-constant op1 ds)
2936                     (when foundp (push imm imms)))
2937                   (multiple-value-bind (imm foundp) (x86-lap-operand-constant op0 ds)
2938                     (when foundp (push imm imms)))
2939                   imms)))
2940      ;; Subtle difference between no imms and a single NIL imm, so if anybody ever
2941      ;; cares for some reason, they could distinguish the two cases.
2942      (if imms
2943        (values comment label instr (if (cdr imms) (coerce imms 'vector) (car imms)))
2944        (values comment label instr)))))
2945
2946(defun disassemble-lines (function)
2947  (let ((source-note (function-source-note function)))
2948    (when source-note
2949      ;; Fetch source from file if don't already have it.
2950      (ensure-source-note-text source-note)))
2951  (let ((lines (make-array 20 :adjustable t :fill-pointer 0)))
2952    (with-output-to-string (stream)
2953      (x86-xdisassemble
2954       function
2955       #'(lambda (ds instruction seq function)
2956           (declare (ignore seq))
2957           (multiple-value-bind (comment label instr object)
2958                                (x86-disassembled-instruction-line ds instruction function stream)
2959             (when comment
2960               (vector-push-extend comment lines))
2961             (vector-push-extend (list object label instr) lines)))
2962       nil))
2963    (coerce lines 'simple-vector)))
Note: See TracBrowser for help on using the repository browser.