source: branches/working-0711/ccl/compiler/X86/x86-disassemble.lisp @ 13146

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

readloop source text recording (r13124, r13131)

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