source: branches/1.1/ccl/compiler/X86/x86-disassemble.lisp

Last change on this file was 6996, checked in by R. Matthew Emerson, 17 years ago

Correct spelling errors.

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