source: branches/working-0710/ccl/compiler/X86/x86-disassemble.lisp @ 7582

Last change on this file since 7582 was 7582, checked in by gb, 14 years ago

Don't call BREAK when we see a NOP with a REPZ prefix.

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