source: branches/ia32/compiler/X86/x86-asm.lisp @ 8073

Last change on this file since 8073 was 8073, checked in by rme, 14 years ago

Let ANDL opcode take a signed or unsigned immediate; add immediate flavor
of PSLLQ instruction.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 188.4 KB
Line 
1;;;-*- Mode: Lisp; Package: (X86 :use CL) -*-
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(eval-when (:compile-toplevel :load-toplevel :execute)
18(require "X86-ARCH")
19)
20
21(in-package "X86")
22
23(defconstant +MAX-OPERANDS+ 3) ; max operands per insn
24(defconstant +MAX-IMMEDIATE-OPERANDS+ 2) ; max immediates per insn (lcall  ljmp)
25(defconstant +MAX-MEMORY-OPERANDS+ 2) ; max memory refs per insn (string ops)
26
27;;; Prefixes will be emitted in the order defined below.
28;;; WAIT-PREFIX must be the first prefix since FWAIT is really is an
29;;; instruction  and so must come before any prefixes.
30
31(defconstant +WAIT-PREFIX+ 0)
32(defconstant +LOCKREP-PREFIX+ 1)
33(defconstant +ADDR-PREFIX+ 2)
34(defconstant +DATA-PREFIX+ 3)
35(defconstant +SEG-PREFIX+ 4)
36(defconstant +REX-PREFIX+ 5) ; must come last.
37(defconstant +MAX-PREFIXES+ 6) ; max prefixes per opcode
38
39;;; we define the syntax here (modulo base index scale syntax)
40(defconstant +REGISTER-PREFIX+ #\%)
41(defconstant +IMMEDIATE-PREFIX+ #\$)
42(defconstant +ABSOLUTE-PREFIX+ #\*)
43
44(defconstant +TWO-BYTE-OPCODE-ESCAPE+ #x0f)
45(defconstant +NOP-OPCODE+ #x90)
46
47;;; register numbers
48(defconstant +EBP-REG-NUM+ 5)
49(defconstant +ESP-REG-NUM+ 4)
50
51;;; modrm-byte.regmem for twobyte escape
52(defconstant +ESCAPE-TO-TWO-BYTE-ADDRESSING+ +ESP-REG-NUM+)
53;;; index-base-byte.index for no index register addressing
54(defconstant +NO-INDEX-REGISTER+ +ESP-REG-NUM+)
55;;; index-base-byte.base for no base register addressing
56(defconstant +NO-BASE-REGISTER+ +EBP-REG-NUM+)
57(defconstant +NO-BASE-REGISTER-16+ 6)
58
59;;; these are the instruction mnemonic suffixes.
60(defconstant +WORD-MNEM-SUFFIX+ #\w)
61(defconstant +BYTE-MNEM-SUFFIX+ #\b)
62(defconstant +SHORT-MNEM-SUFFIX+ #\s)
63(defconstant +LONG-MNEM-SUFFIX+ #\l)
64(defconstant +QWORD-MNEM-SUFFIX+ #\q)
65(defconstant +LONG-DOUBLE-MNEM-SUFFIX+ #\x)
66
67;;; modrm.mode = REGMEM-FIELD-HAS-REG when a register is in there
68(defconstant +REGMEM-FIELD-HAS-REG+ #x3) ; always = #x3
69(defconstant +REGMEM-FIELD-HAS-MEM+ (lognot +REGMEM-FIELD-HAS-REG+))
70
71(eval-when (:compile-toplevel :load-toplevel :execute)
72
73;;; By default, this returns NIL if the modifier can't be encoded.
74;;; That's an error, but the caller can provide better error context.
75
76;;; first 16 bits for opcode modifier flags, rest for cpu
77;;; features.
78(defparameter *opcode-flags*
79  `((:jump . ,(ash 1 0))                ;special case for jump insns
80    (:CpuNo64 . ,(ash 1 16))            ;not supported in 64 bit mode
81    (:Cpu64 . ,(ash 1 17))              ;64 bit mode required
82    (:CpuSSE . ,(ash 1 18))             ;SSE extensions required
83    (:CpuSSE2 . ,(ash 1 19))            ;SSE2 extensions required
84    (:CpuSSE3 . ,(ash 1 20))            ;SSE3 extensions required
85))
86
87(defun %encode-opcode-flags (flags &optional errorp)
88  (flet ((encode-atomic-flag (f)
89           (if f
90             (cdr (assoc f *opcode-flags*))
91             0)))
92    (or
93     (if (atom flags)
94       (encode-atomic-flag flags)
95       (let* ((k 0))
96         (dolist (f flags k)
97           (let* ((k0 (encode-atomic-flag f)))
98             (if k0
99               (setq k (logior k0 k))
100               (return))))))
101     (if errorp (error "Unknown x86 opcode flags: ~s" flags)))))
102
103   
104
105)
106
107(defmacro encode-opcode-flags (&rest flags)
108  (%encode-opcode-flags flags t))
109
110;;; operand-types[i] bits
111;;; register
112(defconstant +operand-type-Reg8+ #x1) ; 8 bit reg
113(defconstant +operand-type-Reg16+ #x2) ; 16 bit reg
114(defconstant +operand-type-Reg32+ #x4) ; 32 bit reg
115(defconstant +operand-type-Reg64+ #x8) ; 64 bit reg
116;;; immediate
117(defconstant +operand-type-Imm8+ #x10) ; 8 bit immediate
118(defconstant +operand-type-Imm8S+ #x20) ; 8 bit immediate sign extended
119(defconstant +operand-type-Imm16+ #x40) ; 16 bit immediate
120(defconstant +operand-type-Imm32+ #x80) ; 32 bit immediate
121(defconstant +operand-type-Imm32S+ #x100) ; 32 bit immediate sign extended
122(defconstant +operand-type-Imm64+ #x200) ; 64 bit immediate
123(defconstant +operand-type-Imm1+ #x400) ; 1 bit immediate
124;;; memory
125(defconstant +operand-type-BaseIndex+ #x800)
126;;; Disp8 16 32 are used in different ways  depending on the
127;;; instruction.  For jumps  they specify the size of the PC relative
128;;; displacement  for baseindex type instructions  they specify the
129;;; size of the offset relative to the base register  and for memory
130;;; offset instructions such as `mov 1234 %al' they specify the size of
131;;; the offset relative to the segment base.
132(defconstant +operand-type-Disp8+ #x1000) ; 8 bit displacement
133(defconstant +operand-type-Disp16+ #x2000) ; 16 bit displacement
134(defconstant +operand-type-Disp32+ #x4000) ; 32 bit displacement
135(defconstant +operand-type-Disp32S+ #x8000) ; 32 bit signed displacement
136(defconstant +operand-type-Disp64+ #x10000) ; 64 bit displacement
137;;; specials
138(defconstant +operand-type-InOutPortReg+ #x20000) ; register to hold in/out port addr = dx
139(defconstant +operand-type-ShiftCount+ #x40000) ; register to hold shift cound = cl
140(defconstant +operand-type-Control+ #x80000) ; Control register
141(defconstant +operand-type-Debug+ #x100000) ; Debug register
142(defconstant +operand-type-Test+ #x200000) ; Test register
143(defconstant +operand-type-FloatReg+ #x400000) ; Float register
144(defconstant +operand-type-FloatAcc+ #x800000) ; Float stack top %st(0)
145(defconstant +operand-type-SReg2+ #x1000000) ; 2 bit segment register
146(defconstant +operand-type-SReg3+ #x2000000) ; 3 bit segment register
147(defconstant +operand-type-Acc+ #x4000000) ; Accumulator %al or %ax or %eax
148(defconstant +operand-type-JumpAbsolute+ #x8000000)
149(defconstant +operand-type-RegMMX+ #x10000000) ; MMX register
150(defconstant +operand-type-RegXMM+ #x20000000) ; XMM registers in PIII
151(defconstant +operand-type-EsSeg+ #x40000000) ; String insn operand with fixed es segment
152
153;;; InvMem is for instructions with a modrm byte that only allow a
154;;; general register encoding in the i.tm.mode and i.tm.regmem fields
155;;; eg. control reg moves.  They really ought to support a memory form
156;;; but don't  so we add an InvMem flag to the register operand to
157;;; indicate that it should be encoded in the i.tm.regmem field.
158(defconstant +operand-type-InvMem+ #x80000000)
159(defconstant +operand-type-Label+ #x100000000)
160
161;;; 4 bytes and a :reloc; otherwise just like a 32-bit immediate
162(defconstant +operand-type-Self+ #x200000000)
163
164(defconstant +operand-type-Reg+ (logior +operand-type-Reg8+ +operand-type-Reg16+ +operand-type-Reg32+ +operand-type-Reg64+)) ; gen'l register
165(defconstant +operand-type-WordReg+ (logior +operand-type-Reg16+ +operand-type-Reg32+ +operand-type-Reg64+))
166(defconstant +operand-type-ImplicitRegister+ (logior +operand-type-InOutPortReg+ +operand-type-ShiftCount+ +operand-type-Acc+ +operand-type-FloatAcc+))
167(defconstant +operand-type-Imm+ (logior +operand-type-Imm8+ +operand-type-Imm8S+ +operand-type-Imm16+ +operand-type-Imm32S+ +operand-type-Imm32+ +operand-type-Imm64+)) ; gen'l immediate
168(defconstant +operand-type-EncImm+ (logior +operand-type-Imm8+ +operand-type-Imm16+ +operand-type-Imm32+ +operand-type-Imm32S+)) ; Encodable gen'l immediate
169(defconstant +operand-type-Disp+ (logior +operand-type-Disp8+ +operand-type-Disp16+ +operand-type-Disp32+ +operand-type-Disp32S+ +operand-type-Disp64+)) ; General displacement
170(defconstant +operand-type-AnyMem+ (logior +operand-type-Disp8+ +operand-type-Disp16+ +operand-type-Disp32+ +operand-type-Disp32S+ +operand-type-BaseIndex+ +operand-type-InvMem+)) ; General memory
171;;; The following aliases are defined because the opcode table
172;;; carefully specifies the allowed memory types for each instruction.
173;;; At the moment we can only tell a memory reference size by the
174;;; instruction suffix  so there's not much point in defining Mem8
175;;; Mem16  Mem32 and Mem64 opcode modifiers - We might as well just use
176;;; the suffix directly to check memory operands.
177(defconstant +operand-type-LLongMem+ +operand-type-AnyMem+); 64 bits (or more)
178(defconstant +operand-type-LongMem+  +operand-type-AnyMem+) ; 32 bit memory ref
179(defconstant +operand-type-ShortMem+ +operand-type-AnyMem+) ; 16 bit memory ref
180(defconstant +operand-type-WordMem+ +operand-type-AnyMem+) ; 16 or 32 bit memory ref
181(defconstant +operand-type-ByteMem+ +operand-type-AnyMem+) ; 8 bit memory ref
182
183(eval-when (:compile-toplevel :load-toplevel :execute)
184
185(defparameter *x86-operand-type-names*
186  `((:Reg8 . ,+operand-type-Reg8+)
187    (:Reg16 . ,+operand-type-Reg16+)
188    (:Reg32 . ,+operand-type-Reg32+)
189    (:Reg64 . ,+operand-type-Reg64+)
190    (:Imm8 . ,+operand-type-Imm8+)
191    (:Imm8S . ,+operand-type-Imm8S+)
192    (:Imm16 . ,+operand-type-Imm16+)
193    (:Imm32 . ,+operand-type-Imm32+)
194    (:Imm32S . ,+operand-type-Imm32S+)
195    (:Imm64 . ,+operand-type-Imm64+)
196    (:Imm1 . ,+operand-type-Imm1+)
197    (:BaseIndex . ,+operand-type-BaseIndex+)
198    (:Disp8 . ,+operand-type-Disp8+)
199    (:Disp16 . ,+operand-type-Disp16+)
200    (:Disp32 . ,+operand-type-Disp32+)
201    (:Disp32S . ,+operand-type-Disp32S+)
202    (:Disp64 . ,+operand-type-Disp64+)
203    (:InOutPortReg . ,+operand-type-InOutPortReg+)
204    (:ShiftCount . ,+operand-type-ShiftCount+)
205    (:Control . ,+operand-type-Control+)
206    (:Debug . ,+operand-type-Debug+)
207    (:Test . ,+operand-type-Test+)
208    (:FloatReg . ,+operand-type-FloatReg+)
209    (:FloatAcc . ,+operand-type-FloatAcc+)
210    (:SReg2 . ,+operand-type-SReg2+)
211    (:SReg3 . ,+operand-type-SReg3+)
212    (:Acc . ,+operand-type-Acc+)
213    (:JumpAbsolute . ,+operand-type-JumpAbsolute+)
214    (:RegMMX . ,+operand-type-RegMMX+)
215    (:RegXMM . ,+operand-type-RegXMM+)
216    (:EsSeg . ,+operand-type-EsSeg+)
217    (:InvMem . ,+operand-type-InvMem+)
218    (:Reg . ,+operand-type-Reg+)
219    (:WordReg . ,+operand-type-WordReg+)
220    (:ImplicitRegister . ,+operand-type-ImplicitRegister+)
221    (:Imm . ,+operand-type-Imm+)
222    (:EncImm . ,+operand-type-EncImm+)
223    (:Disp . ,+operand-type-Disp+)
224    (:AnyMem . ,+operand-type-AnyMem+)
225    (:LLongMem . ,+operand-type-LLongMem+)
226    (:LongMem . ,+operand-type-LongMem+)
227    (:ShortMem . ,+operand-type-ShortMem+)
228    (:WordMem . ,+operand-type-WordMem+)
229    (:ByteMem . ,+operand-type-ByteMem+)
230    (:Label . ,+operand-type-Label+)
231    (:Self . ,+operand-type-Self+)
232  ))
233
234(defun %encode-operand-type (optype &optional errorp)
235  (flet ((encode-atomic-operand-type (op)
236           (if op
237             (cdr (assoc op *x86-operand-type-names* :test #'eq))
238             0)))
239    (or
240     (if (atom optype)
241       (encode-atomic-operand-type optype)
242       (let* ((k 0))
243         (dolist (op optype k)
244           (let* ((k0 (encode-atomic-operand-type op)))
245             (if k0
246               (setq k (logior k k0))
247               (return))))))
248     (if errorp (error "Unknown x86 operand type ~s" optype)))))
249)
250
251(defmacro encode-operand-type (&rest op)
252  (%encode-operand-type op t))
253
254
255
256
257
258(defconstant +RegRex+ #x1) ; Extended register.
259(defconstant +RegRex64+ #x2) ; Extended 8 bit register.
260
261(eval-when (:compile-toplevel :load-toplevel :execute)
262;;; these are for register name --> number & type hash lookup
263(defstruct reg-entry
264  reg-name
265  reg-type
266  reg-flags
267  reg-num                               ; for encoding in instruction fields
268  ordinal64                             ; canonical, ordinal register number
269  ordinal32
270)
271
272(defmethod make-load-form ((r reg-entry) &optional env)
273  (declare (ignore env))
274  (make-load-form-saving-slots r))
275
276(defstruct seg-entry
277  seg-name
278  seg-prefix
279)
280
281)
282
283
284(defstruct modrm-byte
285  regmem ; codes register or memory operand
286  reg ; codes register operand (or extended opcode)
287  mode ; how to interpret regmem & reg
288)
289
290;;; x86-64 extension prefix.
291;; typedef int rex-byte
292(defconstant +REX-OPCODE+ #x40)
293
294;;; Indicates 64 bit operand size.
295(defconstant +REX-MODE64+ 8)
296;;; High extension to reg field of modrm byte.
297(defconstant +REX-EXTX+ 4)
298;;; High extension to SIB index field.
299(defconstant +REX-EXTY+ 2)
300;;; High extension to base field of modrm or SIB  or reg field of opcode.
301(defconstant +REX-EXTZ+ 1)
302
303;;; 386 opcode byte to code indirect addressing.
304(defstruct sib-byte
305  base
306  index
307  scale
308)
309
310
311;;; x86 arch names and features
312(defstruct arch-entry
313  name  ; arch name
314  flags ; cpu feature flags
315)
316
317
318;;; The SystemV/386 SVR3.2 assembler  and probably all AT&T derived
319;;; ix86 Unix assemblers  generate floating point instructions with
320;;; reversed source and destination registers in certain cases.
321;;; Unfortunately  gcc and possibly many other programs use this
322;;; reversed syntax  so we're stuck with it.
323;;;
324;;; eg. `fsub %st(3) %st' results in st = st - st(3) as expected  but
325;;;`fsub %st %st(3)' results in st(3) = st - st(3)  rather than
326;;; the expected st(3) = st(3) - st
327;;;
328;;; This happens with all the non-commutative arithmetic floating point
329;;; operations with two register operands  where the source register is
330;;; %st  and destination register is %st(i).  See FloatDR below.
331;;;
332;;; The affected opcode map is dceX  dcfX  deeX  defX.
333
334(defconstant +MOV-AX-DISP32+ #xa0)
335(defconstant +POP-SEG-SHORT+ #x07)
336(defconstant +JUMP-PC-RELATIVE+ #xe9)
337(defconstant +INT-OPCODE+  #xcd)
338(defconstant +INT3-OPCODE+ #xcc)
339(defconstant +FWAIT-OPCODE+ #x9b)
340(defconstant +ADDR-PREFIX-OPCODE+ #x67)
341(defconstant +DATA-PREFIX-OPCODE+ #x66)
342(defconstant +LOCK-PREFIX-OPCODE+ #xf0)
343(defconstant +CS-PREFIX-OPCODE+ #x2e)
344(defconstant +DS-PREFIX-OPCODE+ #x3e)
345(defconstant +ES-PREFIX-OPCODE+ #x26)
346(defconstant +FS-PREFIX-OPCODE+ #x64)
347(defconstant +GS-PREFIX-OPCODE+ #x65)
348(defconstant +SS-PREFIX-OPCODE+ #x36)
349(defconstant +REPNE-PREFIX-OPCODE+ #xf2)
350(defconstant +REPE-PREFIX-OPCODE+  #xf3)
351
352
353(defstruct (x86-opcode-template (:constructor %make-x86-opcode-template))
354  mnemonic               ; fully qualified, includes suffix if applicable
355  flags                  ; opcode modifier and cpu type flags
356  ordinal                ; unique id
357  operand-types          ; as specific as possible
358  operand-classes        ; describe how to insert operands in base op, modrm
359  prefixes               ; list of 0 or more explicit prefixes
360  base-opcode            ; 1-3 bytes
361  rex-prefix             ; initial REX value
362  modrm-byte             ; initial modrm vale, may be nil if no modrm byte
363  )
364
365
366(eval-when (:compile-toplevel :load-toplevel :execute)
367(defun parse-x86-opcode-operand-types (types&classes)
368  (ccl::collect ((types))
369    (dolist (t&c types&classes (apply #'vector (types)))
370      (destructuring-bind (type class) t&c
371        (declare (ignore class))
372        (types (%encode-operand-type type t))))))
373
374(defparameter *x86-operand-insert-function-keywords*
375  #(:insert-nothing
376    :insert-modrm-reg
377    :insert-modrm-rm
378    :insert-memory
379    :insert-opcode-reg
380    :insert-opcode-reg4
381    :insert-cc
382    :insert-label
383    :insert-imm8-for-int
384    :insert-extra
385    :insert-imm8
386    :insert-imm8s
387    :insert-imm16
388    :insert-imm32s
389    :insert-imm32
390    :insert-imm64
391    :insert-mmx-reg
392    :insert-mmx-rm
393    :insert-xmm-reg
394    :insert-xmm-rm
395    :insert-reg4-pseudo-rm-high
396    :insert-reg4-pseudo-rm-low
397    :insert-self
398    ))
399
400(defun parse-x86-opcode-operand-classes (types&classes)
401  (ccl::collect ((classes))
402    (dolist (t&c types&classes (apply #'vector (classes)))
403      (destructuring-bind (type class) t&c
404        (declare (ignore type))
405        (classes (or (position class *x86-operand-insert-function-keywords*)
406                     (error "Unknown operand class: ~s" class)))))))
407
408(defun parse-x86-opcode-name (name&flags)
409  (string-downcase (if (atom name&flags) name&flags (car name&flags))))
410
411
412(defun parse-x86-opcode-flags (name&flags)
413  (if (atom name&flags)
414    0
415    (%encode-opcode-flags (cdr name&flags) t)))
416
417)
418
419;;; Any instruction with no operands.
420(defstruct x86-instruction
421  opcode-template
422  rex-prefix                            ; ignored in 32-bit assembly
423  base-opcode
424  modrm-byte
425  sib-byte
426  seg-prefix
427  disp
428  imm
429  extra
430  )
431
432(defun need-modrm-byte (instruction)
433  (or (x86-instruction-modrm-byte instruction)
434      (error "Bug: no modrm byte in ~s" instruction)))
435
436(defun need-rex-prefix (instruction)
437  (or (x86-instruction-rex-prefix instruction)
438      (error "Bug: no REX prefix in ~s" instruction)))
439
440
441
442
443(defconstant modrm-mod-byte (byte 2 6))
444(defconstant modrm-reg-byte (byte 3 3))
445(defconstant modrm-rm-byte (byte 3 0))
446
447(defconstant sib-scale-byte (byte 2 6))
448(defconstant sib-index-byte (byte 3 3))
449(defconstant sib-base-byte (byte 3 0))
450
451(defun mode-from-disp-size (type)
452  (cond ((logtest type (x86::encode-operand-type :disp8)) 1)
453        ((logtest type (x86::encode-operand-type :disp16 :disp32 :disp32S)) 2)
454        (t 0)))
455
456
457(defun insert-memory-operand-values (instruction
458                                     explicit-seg
459                                     disp
460                                     base
461                                     index
462                                     scale
463                                     memtype)
464  (declare (special *ds-segment-register* *ss-segment-register*)) ;fwd refs
465  (let* ((rm-byte (x86-instruction-modrm-byte instruction))
466         (sib 0)
467         (default-seg *ds-segment-register*))
468    (cond ((null base)
469           (setf (ldb modrm-mod-byte rm-byte) 0
470                 (ldb modrm-rm-byte rm-byte) +escape-to-two-byte-addressing+
471                 (ldb sib-base-byte sib) +no-base-register+
472                 memtype (encode-operand-type :disp32s))
473           (cond ((null index)
474                  ;; Just a displacement.
475                  (setf (ldb sib-index-byte sib) +no-index-register+))
476                 (t
477                  ;; No base, but index
478                  (let* ((index-reg (reg-entry-reg-num index)))
479                    (setf (ldb sib-index-byte sib) index-reg
480                          (ldb sib-scale-byte sib) (or scale 0))
481                    (when (logtest (reg-entry-reg-flags index) +RegRex+)
482                      (setf (x86-instruction-rex-prefix instruction)
483                            (logior +rex-exty+ (need-rex-prefix instruction))))))))
484          ((= (reg-entry-reg-type base) (encode-operand-type :baseIndex))
485           ;; RIP-relative.  Need a displacement if we don't already
486           ;; have one.
487           (setf (ldb modrm-rm-byte rm-byte) +no-base-register+)
488           (setq memtype
489                 (logior (encode-operand-type :disp32s)
490                         (encode-operand-type :label)
491                         (logandc2 memtype (encode-operand-type :disp)))))
492          (t
493           ;; have a real base register (not just %rip).  Maybe an
494           ;; index register, too.
495           (let* ((baseregnum (reg-entry-reg-num base)))
496             (setf (ldb modrm-rm-byte rm-byte) baseregnum)
497             (when (logtest (reg-entry-reg-flags base) +RegRex+)
498               (setf (x86-instruction-rex-prefix instruction)
499                     (logior 1 (need-rex-prefix instruction))))
500             (setf (ldb sib-base-byte sib) baseregnum)
501             (cond ((= (logand baseregnum 7) +ebp-reg-num+)
502                    (setq default-seg *ss-segment-register*)
503                    (unless disp
504                      (setf memtype (logior memtype (encode-operand-type :disp8)))))
505                   ((= baseregnum x86::+esp-reg-num+)
506                    (setq default-seg x86::*ss-segment-register*)))
507             (setf (ldb sib-scale-byte sib) (or scale 0))
508             (if (null index)
509               (setf (ldb sib-index-byte sib) +no-index-register+)
510               (progn
511                 (setf (ldb sib-index-byte sib)
512                       (reg-entry-reg-num index)
513                       (ldb modrm-rm-byte rm-byte) +escape-to-two-byte-addressing+)
514                 (when (logtest (reg-entry-reg-flags index) +RegRex+)
515                   (setf (x86-instruction-rex-prefix instruction)
516                         (logior +rex-exty+
517                                 (need-rex-prefix instruction)))))))
518               (setf (ldb modrm-mod-byte rm-byte) (mode-from-disp-size memtype))))
519    (setf (x86-instruction-modrm-byte instruction) rm-byte)
520    (when (= (ldb modrm-rm-byte rm-byte) +escape-to-two-byte-addressing+)
521      (setf (x86-instruction-sib-byte instruction) sib))
522    (when (logtest memtype (encode-operand-type :disp))
523      (unless disp (setq disp 0))
524      (setf (x86-instruction-disp instruction) disp
525            (x86-instruction-extra instruction) memtype))
526    (when (and explicit-seg
527               (not (eq explicit-seg default-seg)))
528      (setf (x86-instruction-seg-prefix instruction)
529            (seg-entry-seg-prefix explicit-seg)))))
530
531(defun insert-memory (instruction operand)
532  (insert-memory-operand-values instruction
533                                (x86-memory-operand-seg operand)
534                                (x86-memory-operand-disp operand)
535                                (x86-memory-operand-base operand)
536                                (x86-memory-operand-index operand)
537                                (x86-memory-operand-scale operand)
538                                (x86-memory-operand-type operand)))
539
540(defmacro def-x86-opcode (name&flags types-and-classes base-opcode
541                          modrm-byte rex-prefix &rest prefixes)
542  `(%make-x86-opcode-template
543    :mnemonic ,(parse-x86-opcode-name name&flags)
544    :flags ,(parse-x86-opcode-flags name&flags)
545    :operand-types ,(parse-x86-opcode-operand-types types-and-classes)
546    :operand-classes ,(parse-x86-opcode-operand-classes types-and-classes)
547    :base-opcode ,base-opcode
548    :prefixes ',prefixes
549    :rex-prefix ,rex-prefix
550    :modrm-byte ,modrm-byte))
551
552(defparameter *x86-opcode-templates*
553  (vector
554   ;; adc
555   (def-x86-opcode (adcq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
556     #x11 #o300 #x48)
557   (def-x86-opcode (adcq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
558     #x13 #o000 #x48)
559   (def-x86-opcode (adcq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
560     #x11 #x00 #x48)
561   (def-x86-opcode (adcq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
562     #x83 #o320 #x48)
563   (def-x86-opcode (adcq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
564     #x15 nil #x48)
565   (def-x86-opcode (adcq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
566     #x81 #o320 #x48)
567   (def-x86-opcode (adcq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
568     #x83 #o020 #x48)
569   (def-x86-opcode (adcq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
570     #x81 #o020 #x48)
571
572   (def-x86-opcode adcl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
573     #x11 #o300 #x00)
574   (def-x86-opcode adcl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
575     #x13 #o000 #x00)
576   (def-x86-opcode adcl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
577     #x11 #x00 #x00)
578   (def-x86-opcode adcl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
579     #x83 #o320 #x00)
580   (def-x86-opcode adcl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
581     #x15 nil nil)
582   (def-x86-opcode adcl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
583     #x81 #o320 #x00)
584   (def-x86-opcode adcl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
585     #x83 #o020 #x00)
586   (def-x86-opcode adcl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
587     #x81 #o020 #x00)
588
589   (def-x86-opcode adcw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
590     #x11 #o300 #x00 #x66)
591   (def-x86-opcode adcw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
592     #x13 #o000 #x00 #x66)
593   (def-x86-opcode adcw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
594     #x11 #x00 #x00 #x66)
595   (def-x86-opcode adcw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
596     #x83 #o320 #x00 #x66)
597   (def-x86-opcode adcw ((:imm16 :insert-imm16) (:acc :insert-nothing))
598     #x15 nil nil #x66)
599   (def-x86-opcode adcw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
600     #x81 #o320 #x00 #x66)
601   (def-x86-opcode adcw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
602     #x83 #o020 #x00 #x66)
603   (def-x86-opcode adcw ((:imm16 :insert-imm16) (:anymem :insert-memory))
604     #x81 #o020 #x00 #x66)
605
606   (def-x86-opcode adcb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
607     #x10 #o300 #x00)
608   (def-x86-opcode adcb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
609     #x12 #o000 #x00)
610   (def-x86-opcode adcb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
611     #x10 #x00 #x00)
612   (def-x86-opcode adcb ((:imm8 :insert-imm8) (:acc :insert-nothing))
613     #x14 nil nil)
614   (def-x86-opcode adcb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
615     #x80 #o320 #x00)
616   (def-x86-opcode adcb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
617     #x80 #o320 #x00)
618   (def-x86-opcode adcb ((:imm8 :insert-imm8) (:anymem :insert-memory))
619     #x80 #o020 #x00)
620
621   ;; add
622   (def-x86-opcode (addq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
623     #x01 #o300 #x48)
624   (def-x86-opcode (addq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
625     #x03 #o000 #x48)
626   (def-x86-opcode (addq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
627     #x01 #x00 #x48)
628   (def-x86-opcode (addq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
629     #x83 #o300 #x48)
630   (def-x86-opcode (addq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
631     #x05 nil #x48)
632   (def-x86-opcode (addq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
633     #x81 #o300 #x48)
634   (def-x86-opcode (addq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
635     #x83 #o000 #x48)
636   (def-x86-opcode (addq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
637     #x81 #o000 #x48)
638
639   (def-x86-opcode addl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
640     #x01 #o300 #x00)
641   (def-x86-opcode addl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
642     #x03 #o000 #x00)
643   (def-x86-opcode addl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
644     #x01 #x00 #x00)
645   (def-x86-opcode addl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
646     #x83 #o300 #x00)
647   (def-x86-opcode addl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
648     #x05 nil nil)
649   (def-x86-opcode addl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
650     #x81 #o300 #x00)
651   (def-x86-opcode addl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
652     #x83 #o000 #x00)
653   (def-x86-opcode addl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
654     #x81 #o000 #x00)
655
656   (def-x86-opcode addw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
657     #x01 #o300 #x00 #x66)
658   (def-x86-opcode addw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
659     #x03 #o000 #x00 #x66)
660   (def-x86-opcode addw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
661     #x01 #x00 #x00 #x66)
662   (def-x86-opcode addw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
663     #x83 #o300 #x00 #x66)
664   (def-x86-opcode addw ((:imm16 :insert-imm16) (:acc :insert-nothing))
665     #x05 nil nil #x66)
666   (def-x86-opcode addw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
667     #x81 #o300 #x00 #x66)
668   (def-x86-opcode addw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
669     #x83 #o000 #x00 #x66)
670   (def-x86-opcode addw ((:imm16 :insert-imm16) (:anymem :insert-memory))
671     #x81 #o000 #x00 #x66)
672
673   (def-x86-opcode addb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
674     #x00 #o300 #x00)
675   (def-x86-opcode addb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
676     #x02 #o000 #x00)
677   (def-x86-opcode addb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
678     #x00 #x00 #x00)
679   (def-x86-opcode addb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
680     #x04 nil nil)
681   (def-x86-opcode addb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
682     #x80 #o300 #x00)
683   (def-x86-opcode addb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
684     #x80 #o000 #x00)
685
686   ;; and
687   (def-x86-opcode (andq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
688     #x21 #o300 #x48)
689   (def-x86-opcode (andq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
690     #x23 #o000 #x48)
691   (def-x86-opcode (andq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
692     #x21 #x00 #x48)
693   (def-x86-opcode (andq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
694     #x83 #o340 #x48)
695   (def-x86-opcode (andq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
696     #x25 nil #x48)
697   (def-x86-opcode (andq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
698     #x81 #o340 #x48)
699   (def-x86-opcode (andq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
700     #x83 #o040 #x48)
701   (def-x86-opcode (andq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
702     #x81 #o040 #x48)
703
704   (def-x86-opcode andl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
705     #x21 #o300 #x00)
706   (def-x86-opcode andl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
707     #x23 #o000 #x00)
708   (def-x86-opcode andl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
709     #x21 #x00 #x00)
710   (def-x86-opcode andl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
711     #x83 #o340 #x00)
712   (def-x86-opcode andl (((:imm32s :imm32) :insert-imm32s) (:acc :insert-nothing))
713     #x25 nil nil)
714   (def-x86-opcode andl (((:imm32s :imm32) :insert-imm32s) (:reg32 :insert-modrm-rm))
715     #x81 #o340 #x00)
716   (def-x86-opcode andl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
717     #x83 #o040 #x00)
718   (def-x86-opcode andl (((:imm32s :imm32) :insert-imm32s) (:anymem :insert-memory))
719     #x81 #o040 #x00)
720
721   (def-x86-opcode andw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
722     #x21 #o300 #x00 #x66)
723   (def-x86-opcode andw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
724     #x23 #o000 #x00 #x66)
725   (def-x86-opcode andw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
726     #x21 #x00 #x00 #x66)
727   (def-x86-opcode andw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
728     #x83 #o340 #x00 #x66)
729   (def-x86-opcode andw ((:imm16 :insert-imm16) (:acc :insert-nothing))
730     #x25 nil nil #x66)
731   (def-x86-opcode andw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
732     #x81 #o340 #x00 #x66)
733   (def-x86-opcode andw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
734     #x83 #o040 #x00 #x66)
735   (def-x86-opcode andw ((:imm16 :insert-imm16) (:anymem :insert-memory))
736     #x81 #o040 #x00 #x66)
737
738   (def-x86-opcode andb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
739     #x20 #o300 #x00)
740   (def-x86-opcode andb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
741     #x22 #o000 #x00)
742   (def-x86-opcode andb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
743     #x20 #o000 #x00)
744   (def-x86-opcode andb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
745     #x24 nil nil)
746   (def-x86-opcode andb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
747     #x80 #o340 #x00)
748   (def-x86-opcode andb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
749     #x80 #o040 #x00)
750
751   ;; bsf
752   (def-x86-opcode (bsfq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
753     #x0fbc #o300 #x48)
754   (def-x86-opcode (bsfq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
755     #x0fbc #o000 #x48)
756
757   (def-x86-opcode bsfl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
758     #x0fbc #o300 #x00)
759   (def-x86-opcode bsfl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
760     #x0fbc #o000 #x00)
761
762   (def-x86-opcode bsfw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
763     #x0fbc #o300 #x00 #x66)
764   (def-x86-opcode bsfw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
765     #x0fbc #o000 #x00 #x66)
766
767   ;; bsr
768   (def-x86-opcode (bsrq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
769     #x0fbd #o300 #x48)
770   (def-x86-opcode (bsrq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
771     #x0fbd #o000 #x48)
772
773   (def-x86-opcode bsrl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
774     #x0fbd #o300 #x00)
775   (def-x86-opcode bsrl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
776     #x0fbd #o000 #x00)
777
778   (def-x86-opcode bsrw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
779     #x0fbd #o300 #x00 #x66)
780   (def-x86-opcode bsrw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
781     #x0fbd #o000 #x00 #x66)
782
783   ;; bswap
784   (def-x86-opcode (bswapq :cpu64) ((:reg64 :insert-opcode-reg))
785     #x0fc8 nil #x48)
786
787   (def-x86-opcode bswapl ((:reg32 :insert-opcode-reg))
788     #x0fc8 nil #x00)
789
790   ;; bt
791   (def-x86-opcode (btq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
792     #x0fba #o340 #x48)
793   (def-x86-opcode (btq :cpu64) ((:imm8 :insert-imm8) (:anymem :insert-memory))
794     #x0fba #o040 #x48)
795   (def-x86-opcode (btq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
796     #x0fa3 #o300 #x48)
797   (def-x86-opcode (btq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
798     #x0fa3 #o000 #x48)
799
800   (def-x86-opcode btl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
801     #x0fba #o340 #x00)
802   (def-x86-opcode btl ((:imm8 :insert-imm8) (:anymem :insert-memory))
803     #x0fba #o040 #x00)
804   (def-x86-opcode btl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
805     #x0fa3 #o300 #x00)
806   (def-x86-opcode btl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
807     #x0fa3 #o000 #x00)
808
809   (def-x86-opcode btw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
810     #x0fba #o340 #x00 #x66)
811   (def-x86-opcode btw ((:imm8 :insert-imm8) (:anymem :insert-memory))
812     #x0fba #o040 #x00 #x66)
813   (def-x86-opcode btw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
814     #x0fa3 #o300 #x00 #x66)
815   (def-x86-opcode btw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
816     #x0fa3 #o000 #x00 #x66)
817
818   ;; btc
819   (def-x86-opcode (btcq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
820     #x0fba #o370 #x48)
821   (def-x86-opcode (btcq :cpu64) ((:imm8 :insert-imm8) (:anymem :insert-memory))
822     #x0fba #o070 #x48)
823   (def-x86-opcode (btcq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
824     #x0fbb #o300 #x48)
825   (def-x86-opcode (btcq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
826     #x0fbb #o000 #x48)
827
828   (def-x86-opcode btcl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
829     #x0fba #o370 #x00)
830   (def-x86-opcode btcl ((:imm8 :insert-imm8) (:anymem :insert-memory))
831     #x0fba #o070 #x00)
832   (def-x86-opcode btcl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
833     #x0fbb #o300 #x00)
834   (def-x86-opcode btcl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
835     #x0fbb #o000 #x00)
836
837   (def-x86-opcode btcw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
838     #x0fba #o370 #x00 #x66)
839   (def-x86-opcode btcw ((:imm8 :insert-imm8) (:anymem :insert-memory))
840     #x0fba #o070 #x00 #x66)
841   (def-x86-opcode btcw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
842     #x0fbb #o300 #x00 #x66)
843   (def-x86-opcode btcw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
844     #x0fbb #o000 #x00 #x66)
845
846   ;; btr
847   (def-x86-opcode (btrq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
848     #x0fba #o360 #x48)
849   (def-x86-opcode (btrq :cpu64) ((:imm8 :insert-imm8) (:anymem :insert-memory))
850     #x0fba #o060 #x48)
851   (def-x86-opcode (btrq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
852     #x0fb3 #o300 #x48)
853   (def-x86-opcode (btrq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
854     #x0fb3 #o000 #x48)
855
856   (def-x86-opcode btrl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
857     #x0fba #o360 #x00)
858   (def-x86-opcode btrl ((:imm8 :insert-imm8) (:anymem :insert-memory))
859     #x0fba #o060 #x00)
860   (def-x86-opcode btrl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
861     #x0fb3 #o300 #x00)
862   (def-x86-opcode btrl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
863     #x0fb3 #o000 #x00)
864
865   (def-x86-opcode btrw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
866     #x0fba #o360  #x00 #x66)
867   (def-x86-opcode btrw ((:imm8 :insert-imm8) (:anymem :insert-memory))
868     #x0fba #o060 #x00 #x66)
869   (def-x86-opcode btrw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
870     #x0fb3 #o300 #x00 #x66)
871   (def-x86-opcode btrw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
872     #x0fb3 #o000 #x00 #x66)
873
874   ;; bts
875   (def-x86-opcode (btsq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
876     #x0fba #o350 #x48)
877   (def-x86-opcode (btsq :cpu64) ((:imm8 :insert-imm8) (:anymem :insert-memory))
878     #x0fba #o050 #x48)
879   (def-x86-opcode (btsq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
880     #x0fab #o300 #x48)
881   (def-x86-opcode (btsq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
882     #x0fab #o000 #x48)
883
884   (def-x86-opcode btsl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
885     #x0fba #o350 #x00)
886   (def-x86-opcode btsl ((:imm8 :insert-imm8) (:anymem :insert-memory))
887     #x0fba #o050 #x00)
888   (def-x86-opcode btsl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
889     #x0fab #o300 #x00)
890   (def-x86-opcode btsl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
891     #x0fab #o000 #x00)
892
893   (def-x86-opcode btsw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
894     #x0fba #o350  #x00 #x66)
895   (def-x86-opcode btsw ((:imm8 :insert-imm8) (:anymem :insert-memory))
896     #x0fba #o050 #x00 #x66)
897   (def-x86-opcode btsw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
898     #x0fab #o300 #x00 #x66)
899   (def-x86-opcode btsw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
900     #x0fab #o000 #x00 #x66)
901
902   ;; call
903   ;; Probably need to align CALL instructions within the containing function,
904   ;; so that return addresses are tagged appropriately.
905   (def-x86-opcode call ((:label :insert-label))
906     #xe8 nil nil)
907
908   (def-x86-opcode (call :cpu64) ((:reg64 :insert-modrm-rm))
909     #xff #o320 #x0)
910   (def-x86-opcode (call :cpuno64) ((:reg32 :insert-modrm-rm))
911     #xff #o320 #x0)
912
913   (def-x86-opcode call ((:anymem :insert-memory))
914     #xff #o020 #x0)
915
916   ;; cbtw
917   (def-x86-opcode cbtw ()
918     #x98 nil nil #x66)
919
920   ;; clc
921   (def-x86-opcode clc ()
922     #xf8 nil nil)
923
924   ;; cld
925   (def-x86-opcode cld ()
926     #xfc nil nil)
927
928   ;; cltd
929   (def-x86-opcode cltd ()
930     #x99 nil nil)
931
932 
933   ;; cltq
934   (def-x86-opcode (cltq :cpu64) ()
935     #x98 nil #x48)
936
937   ;; cmc
938   (def-x86-opcode cmc ()
939     #xf5 nil nil)
940
941   ;; cmovCC
942   (def-x86-opcode (cmovccq :cpu64)
943       ((:imm8 :insert-cc) (:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
944     #x0f40 #o300 #x48)
945   (def-x86-opcode (cmovccq :cpu64)
946       ((:imm8 :insert-cc) (:anymem :insert-memory) (:reg64 :insert-modrm-reg))
947     #x0f40 #o000 #x48)
948   (def-x86-opcode cmovccl
949       ((:imm8 :insert-cc) (:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
950     #x0f40 #o300 #x00)
951   (def-x86-opcode cmovccl
952       ((:imm8 :insert-cc) (:anymem :insert-memory) (:reg32 :insert-modrm-reg))
953     #x0f40 #o000 #x00)
954   (def-x86-opcode cmovccw
955       ((:imm8 :insert-cc) (:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
956     #x0f40 #o300 #x00 #x66)
957   (def-x86-opcode cmovccw
958       ((:imm8 :insert-cc) (:anymem :insert-memory) (:reg16 :insert-modrm-reg))
959     #x0f40 #o000 #x00 #x66)
960
961   (def-x86-opcode (cmovoq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
962     #x0f40 #o300 #x48)
963   (def-x86-opcode (cmovoq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
964     #x0f40 #o000 #x48)
965   (def-x86-opcode cmovol ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
966     #x0f40 #o300 #x00)
967   (def-x86-opcode cmovol ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
968     #x0f40 #o000 #x00)
969   (def-x86-opcode cmovow ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
970     #x0f40 #o300 #x00 #x66)
971   (def-x86-opcode cmovow ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
972     #x0f40 #o000 #x00 #x66)
973
974   (def-x86-opcode (cmovnoq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
975     #x0f41 #o300 #x48)
976   (def-x86-opcode (cmovnoq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
977     #x0f41 #o000 #x48)
978   (def-x86-opcode cmovnol ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
979     #x0f41 #o300 #x00)
980   (def-x86-opcode cmovnol ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
981     #x0f41 #o000 #x00)
982   (def-x86-opcode cmovnow ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
983     #x0f41 #o300 #x00 #x66)
984   (def-x86-opcode cmovnow ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
985     #x0f41 #o000 #x00 #x66)
986
987   (def-x86-opcode (cmovbq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
988     #x0f42 #o300 #x48)
989   (def-x86-opcode (cmovbq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
990     #x0f42 #o000 #x48)
991   (def-x86-opcode cmovbl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
992     #x0f42 #o300 #x00)
993   (def-x86-opcode cmovbl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
994     #x0f42 #o000 #x00)
995   (def-x86-opcode cmovbw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
996     #x0f42 #o300 #x00 #x66)
997   (def-x86-opcode cmovbw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
998     #x0f42 #o000 #x00 #x66)
999
1000   (def-x86-opcode (cmovcq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1001     #x0f42 #o300 #x48)
1002   (def-x86-opcode (cmovcq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1003     #x0f42 #o000 #x48)
1004   (def-x86-opcode cmovcl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1005     #x0f42 #o300 #x00)
1006   (def-x86-opcode cmovcl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1007     #x0f42 #o000 #x00)
1008   (def-x86-opcode cmovcw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1009     #x0f42 #o300 #x00 #x66)
1010   (def-x86-opcode cmovcw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1011     #x0f42 #o000 #x00 #x66)
1012
1013   (def-x86-opcode (cmovaeq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1014     #x0f43 #o300 #x48)
1015   (def-x86-opcode (cmovaeq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1016     #x0f43 #o000 #x48)
1017   (def-x86-opcode cmovael ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1018     #x0f43 #o300 #x00)
1019   (def-x86-opcode cmovael ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1020     #x0f43 #o000 #x00)
1021   (def-x86-opcode cmovaew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1022     #x0f43 #o300 #x00 #x66)
1023   (def-x86-opcode cmovaew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1024     #x0f43 #o000 #x00 #x66)
1025
1026   (def-x86-opcode (cmovncq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1027     #x0f43 #o300 #x48)
1028   (def-x86-opcode (cmovncq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1029     #x0f43 #o000 #x48)
1030   (def-x86-opcode cmovncl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1031     #x0f43 #o300 #x00)
1032   (def-x86-opcode cmovncl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1033     #x0f43 #o000 #x00)
1034   (def-x86-opcode cmovncw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1035     #x0f43 #o300 #x00 #x66)
1036   (def-x86-opcode cmovncw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1037     #x0f43 #o000 #x00 #x66)
1038
1039   (def-x86-opcode (cmoveq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1040     #x0f44 #o300 #x48)
1041   (def-x86-opcode (cmoveq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1042     #x0f44 #o000 #x48)
1043   (def-x86-opcode cmovel ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1044     #x0f44 #o300 #x00)
1045   (def-x86-opcode cmovel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1046     #x0f44 #o000 #x00)
1047   (def-x86-opcode cmovew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1048     #x0f44 #o300 #x00 #x66)
1049   (def-x86-opcode cmovew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1050     #x0f44 #o000 #x00 #x66)
1051
1052   (def-x86-opcode (cmovzq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1053     #x0f44 #o300 #x48)
1054   (def-x86-opcode (cmovzq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1055     #x0f44 #o000 #x48)
1056   (def-x86-opcode cmovzl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1057     #x0f44 #o300 #x00)
1058   (def-x86-opcode cmovzl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1059     #x0f44 #o000 #x00)
1060   (def-x86-opcode cmovzw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1061     #x0f44 #o300 #x00 #x66)
1062   (def-x86-opcode cmovzw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1063     #x0f44 #o000 #x00 #x66)
1064
1065   (def-x86-opcode (cmovneq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1066     #x0f45 #o300 #x48)
1067   (def-x86-opcode (cmovneq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1068     #x0f45 #o000 #x48)
1069   (def-x86-opcode cmovnel ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1070     #x0f45 #o300 #x00)
1071   (def-x86-opcode cmovnel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1072     #x0f45 #o000 #x00)
1073   (def-x86-opcode cmovnew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1074     #x0f45 #o300 #x00 #x66)
1075   (def-x86-opcode cmovnew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1076     #x0f45 #o000 #x00 #x66)
1077
1078   (def-x86-opcode (cmovnzq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1079     #x0f45 #o300 #x48)
1080   (def-x86-opcode (cmovnzq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1081     #x0f45 #o000 #x48)
1082   (def-x86-opcode cmovnzl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1083     #x0f45 #o300 #x00)
1084   (def-x86-opcode cmovnzl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1085     #x0f45 #o000 #x00)
1086   (def-x86-opcode cmovnzw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1087     #x0f45 #o300 #x00 #x66)
1088   (def-x86-opcode cmovnzw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1089     #x0f45 #o000 #x00 #x66)
1090
1091   (def-x86-opcode (cmovbeq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1092     #x0f46 #o300 #x48)
1093   (def-x86-opcode (cmovbeq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1094     #x0f46 #o000 #x48)
1095   (def-x86-opcode cmovbel ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-reg))
1096     #x0f46 #o300 #x00)
1097   (def-x86-opcode cmovbel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1098     #x0f46 #o000 #x00)
1099   (def-x86-opcode cmovbew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1100     #x0f46 #o300 #x00 #x66)
1101   (def-x86-opcode cmovbew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1102     #x0f46 #o000 #x00 #x66)
1103
1104   (def-x86-opcode (cmovaq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1105     #x0f47 #o300 #x48)
1106   (def-x86-opcode (cmovaq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1107     #x0f47 #o000 #x48)
1108   (def-x86-opcode cmoval ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1109     #x0f47 #o300 #x00)
1110   (def-x86-opcode cmoval ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1111     #x0f47 #o000 #x00)
1112   (def-x86-opcode cmovaw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1113     #x0f47 #o300 #x00 #x66)
1114   (def-x86-opcode cmovaw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1115     #x0f47 #o000 #x00 #x66)
1116
1117   (def-x86-opcode (cmovsq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1118     #x0f48 #o300 #x48)
1119   (def-x86-opcode (cmovsq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1120     #x0f48 #o000 #x48)
1121   (def-x86-opcode cmovsl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1122     #x0f48 #o300 #x00)
1123   (def-x86-opcode cmovsl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1124     #x0f48 #o000 #x00)
1125   (def-x86-opcode cmovsw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1126     #x0f48 #o300 #x00 #x66)
1127   (def-x86-opcode cmovsw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1128     #x0f48 #o000 #x00 #x66)
1129
1130   (def-x86-opcode (cmovnsq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1131     #x0f49 #o300 #x48)
1132   (def-x86-opcode (cmovnsq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1133     #x0f49 #o000 #x48)
1134   (def-x86-opcode cmovnsl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1135     #x0f49 #o300 #x00)
1136   (def-x86-opcode cmovnsl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1137     #x0f49 #o000 #x00)
1138   (def-x86-opcode cmovnsw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1139     #x0f49 #o300 #x00 #x66)
1140   (def-x86-opcode cmovnsw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1141     #x0f49 #o000 #x00 #x66)
1142
1143   (def-x86-opcode (cmovpeq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1144     #x0f4a #o300 #x48)
1145   (def-x86-opcode (cmovpeq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1146     #x0f4a #o000 #x48)
1147   (def-x86-opcode cmovpel ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1148     #x0f4a #o300 #x00)
1149   (def-x86-opcode cmovpel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1150     #x0f4a #o000 #x00)
1151   (def-x86-opcode cmovpew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1152     #x0f4a #o300 #x00 #x66)
1153   (def-x86-opcode cmovpew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1154     #x0f4a #o000 #x00 #x66)
1155
1156   (def-x86-opcode (cmovpoq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1157     #x0f4b #o300 #x48)
1158   (def-x86-opcode (cmovpoq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1159     #x0f4b #o000 #x48)
1160   (def-x86-opcode cmovpol ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1161     #x0f4b #o300 #x00)
1162   (def-x86-opcode cmovpol ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1163     #x0f4b #o000 #x00)
1164   (def-x86-opcode cmovpow ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1165     #x0f4b #o300 #x00 #x66)
1166   (def-x86-opcode cmovpow ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1167     #x0f4b #o000 #x00 #x66)
1168
1169   (def-x86-opcode (cmovlq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1170     #x0f4c #o300 #x48)
1171   (def-x86-opcode (cmovlq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1172     #x0f4c #o000 #x48)
1173   (def-x86-opcode cmovll ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1174     #x0f4c #o300 #x00)
1175   (def-x86-opcode cmovll ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1176     #x0f4c #o000 #x00)
1177   (def-x86-opcode cmovlw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1178     #x0f4c #o300 #x00 #x66)
1179   (def-x86-opcode cmovlw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1180     #x0f4c #o000 #x00 #x66)
1181
1182   (def-x86-opcode (cmovgeq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1183     #x0f4d #o300 #x48)
1184   (def-x86-opcode (cmovgeq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1185     #x0f4d #o000 #x48)
1186   (def-x86-opcode cmovgel ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1187     #x0f4d #o300 #x00)
1188   (def-x86-opcode cmovgel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1189     #x0f4d #o000 #x00)
1190   (def-x86-opcode cmovgew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1191     #x0f4d #o300 #x00 #x66)
1192   (def-x86-opcode cmovgew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1193     #x0f4d #o000 #x00 #x66)
1194
1195   (def-x86-opcode (cmovleq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1196     #x0f4e #o300 #x48)
1197   (def-x86-opcode (cmovleq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1198     #x0f4e #o000 #x48)
1199   (def-x86-opcode cmovlel ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1200     #x0f4e #o300 #x00)
1201   (def-x86-opcode cmovlel ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1202     #x0f4e #o000 #x00)
1203   (def-x86-opcode cmovlew ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1204     #x0f4e #o300 #x00 #x66)
1205   (def-x86-opcode cmovlew ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1206     #x0f4e #o000 #x00 #x66)
1207
1208   (def-x86-opcode (cmovgq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1209     #x0f4f #o300 #x48)
1210   (def-x86-opcode (cmovgq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1211     #x0f4f #o000 #x48)
1212   (def-x86-opcode cmovgl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1213     #x0f4f #o300 #x00)
1214   (def-x86-opcode cmovgl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1215     #x0f4f #o000 #x00)
1216   (def-x86-opcode cmovgw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1217     #x0f4f #o300 #x00 #x66)
1218   (def-x86-opcode cmovgw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1219     #x0f4f #o000 #x00 #x66)
1220
1221
1222   ;; cmp
1223
1224   (def-x86-opcode (cmpq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
1225     #x39 #o300 #x48)
1226   (def-x86-opcode (rcmpq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1227     #x39 #o300 #x48)
1228   (def-x86-opcode (cmpq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1229     #x3b #o000 #x48)
1230   (def-x86-opcode (rcmpq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
1231     #x3b #o000 #x48)   
1232   (def-x86-opcode (cmpq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
1233     #x39 #x00 #x48)
1234   (def-x86-opcode (rcmpq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1235     #x39 #x00 #x48)
1236   (def-x86-opcode (cmpq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
1237     #x83 #o370 #x48)
1238   (def-x86-opcode (rcmpq :cpu64) ((:reg64 :insert-modrm-rm) (:imm8s :insert-imm8s))
1239     #x83 #o370 #x48)
1240   (def-x86-opcode (cmpq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
1241     #x3d nil #x48)
1242   (def-x86-opcode (rcmpq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
1243     #x3d nil #x48)
1244   (def-x86-opcode (cmpq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
1245     #x81 #o370 #x48)
1246   (def-x86-opcode (rcmpq :cpu64) ((:reg64 :insert-modrm-rm) (:imm32s :insert-imm32s))
1247     #x81 #o370 #x48)   
1248   (def-x86-opcode (cmpq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1249     #x83 #o070 #x48)
1250   (def-x86-opcode (rcmpq :cpu64) ((:anymem :insert-memory) (:imm8s :insert-imm8s))
1251     #x83 #o070 #x48)
1252   (def-x86-opcode (cmpq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1253     #x81 #o070 #x48)
1254   (def-x86-opcode (rcmpq :cpu64) ((:anymem :insert-memory) (:imm32s :insert-imm32s))
1255     #x81 #o070 #x48)
1256
1257   (def-x86-opcode cmpl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
1258     #x39 #o300 #x00)
1259   (def-x86-opcode rcmpl ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1260     #x39 #o300 #x00)   
1261   (def-x86-opcode cmpl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1262     #x3b #o000 #x00)
1263   (def-x86-opcode rcmpl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
1264     #x3b #o000 #x00)   
1265   (def-x86-opcode cmpl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
1266     #x39 #x00 #x00)
1267   (def-x86-opcode rcmpl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1268     #x39 #x00 #x00)   
1269   (def-x86-opcode cmpl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
1270     #x83 #o370 #x00)
1271   (def-x86-opcode rcmpl ((:reg32 :insert-modrm-rm) (:imm8s :insert-imm8s))
1272     #x83 #o370 #x00)   
1273   (def-x86-opcode cmpl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
1274     #x3d nil nil)
1275   (def-x86-opcode rcmpl ((:acc :insert-nothing) (:imm32s :insert-imm32s))
1276     #x3d nil nil)   
1277   (def-x86-opcode cmpl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
1278     #x81 #o370 #x00)
1279   (def-x86-opcode rcmpl ((:reg32 :insert-modrm-rm) (:imm32s :insert-imm32s))
1280     #x81 #o370 #x00)   
1281   (def-x86-opcode cmpl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1282     #x83 #o070 #x00)
1283   (def-x86-opcode rcmpl ((:anymem :insert-memory) (:imm8s :insert-imm8s))
1284     #x83 #o070 #x00)   
1285   (def-x86-opcode cmpl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1286     #x81 #o070 #x00)
1287   (def-x86-opcode rcmpl ((:anymem :insert-memory) (:imm32s :insert-imm32s))
1288     #x81 #o070 #x00)   
1289
1290   (def-x86-opcode cmpw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1291     #x39 #o300 #x00 #x66)
1292   (def-x86-opcode rcmpw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1293     #x39 #o300 #x00 #x66)   
1294   (def-x86-opcode cmpw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1295     #x3b #o000 #x00 #x66)
1296   (def-x86-opcode rcmpw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
1297     #x3b #o000 #x00 #x66)   
1298   (def-x86-opcode cmpw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
1299     #x39 #x00 #x00 #x66)
1300   (def-x86-opcode rcmpw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1301     #x39 #x00 #x00 #x66)   
1302   (def-x86-opcode cmpw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
1303     #x83 #o370 #x00 #x66)
1304   (def-x86-opcode rcmpw ((:reg16 :insert-modrm-rm) (:imm8s :insert-imm8s))
1305     #x83 #o370 #x00 #x66)   
1306   (def-x86-opcode cmpw ((:imm16 :insert-imm16) (:acc :insert-nothing))
1307     #x3d nil nil #x66)
1308   (def-x86-opcode rcmpw ((:acc :insert-nothing) (:imm16 :insert-imm16))
1309     #x3d nil nil #x66)   
1310   (def-x86-opcode cmpw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
1311     #x81 #o370 #x00 #x66)
1312   (def-x86-opcode rcmpw ((:reg16 :insert-modrm-rm) (:imm16 :insert-imm16))
1313     #x81 #o370 #x00 #x66)   
1314   (def-x86-opcode cmpw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1315     #x83 #o070 #x00 #x66)
1316   (def-x86-opcode rcmpw ((:anymem :insert-memory) (:imm8s :insert-imm8s))
1317     #x83 #o070 #x00 #x66)   
1318   (def-x86-opcode cmpw ((:imm16 :insert-imm16) (:anymem :insert-memory))
1319     #x81 #o070 #x00 #x66)
1320   (def-x86-opcode rcmpw ((:anymem :insert-memory) (:imm16 :insert-imm16))
1321     #x81 #o070 #x00 #x66)   
1322
1323   (def-x86-opcode cmpb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
1324     #x38 #o300 #x00)
1325   (def-x86-opcode rcmpb ((:reg8 :insert-modrm-rm) (:reg8 :insert-modrm-reg))
1326     #x38 #o300 #x00)
1327   (def-x86-opcode cmpb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
1328     #x3a #o000 #x00)
1329   (def-x86-opcode rcmpb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
1330     #x3a #o000 #x00)
1331   (def-x86-opcode cmpb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
1332     #x38 #x00 #x00)
1333   (def-x86-opcode rcmpb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
1334     #x38 #x00 #x00)   
1335   (def-x86-opcode cmpb (((:imm8s :imm8) :insert-imm8s) (:acc :insert-nothing))
1336     #x3c nil nil)
1337   (def-x86-opcode rcmpb ((:acc :insert-nothing) ((:imm8s :imm8) :insert-imm8s))
1338     #x3c nil nil)
1339   (def-x86-opcode cmpb (((:imm8s :imm8) :insert-imm8s) (:reg8 :insert-modrm-rm))
1340     #x80 #o370 #x00)
1341   (def-x86-opcode rcmpb ((:reg8 :insert-modrm-rm) ((:imm8s :imm8) :insert-imm8s))
1342     #x80 #o370 #x00)
1343   (def-x86-opcode cmpb (((:imm8s :imm8) :insert-imm8s) (:anymem :insert-memory))
1344     #x80 #o070 #x00)
1345   (def-x86-opcode rcmpb ((:anymem :insert-memory) ((:imm8s :imm8) :insert-imm8s))
1346     #x80 #o070 #x00)
1347
1348   ;; cmps
1349   (def-x86-opcode (cmpsq :cpu64) ()
1350     #xa7 nil #x48)
1351
1352   (def-x86-opcode cmpsl ()
1353     #xa7 nil nil)
1354
1355   (def-x86-opcode cmpsw ()
1356     #xa7 nil nil #x66)
1357
1358   (def-x86-opcode cmpsb ()
1359     #xa6 nil nil)
1360
1361   ;; cmpxchg
1362   (def-x86-opcode (cmpxchgq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
1363     #x0fb1 #o300 #x48)
1364   (def-x86-opcode (cmpxchgq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
1365     #x0fb1 #o000 #x48)
1366
1367   (def-x86-opcode cmpxchgl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
1368     #x0fb1 #o300 #x00)
1369   (def-x86-opcode cmpxchgl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
1370     #x0fb1 #o000 #x00)
1371
1372   (def-x86-opcode cmpxchgw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1373     #x0fb1 #o300 #x00 #x66)
1374   (def-x86-opcode cmpxchgw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
1375     #x0fb1 #o000 #x00 #x66)
1376
1377   (def-x86-opcode cmpxchgb ((:reg8 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1378     #x0fb0 #o300 #x00)
1379   (def-x86-opcode cmpxchgb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
1380     #x0fb0 #o000 #x00)
1381
1382   ;; cpuid
1383   (def-x86-opcode cpuid ()
1384     #x0fa2 nil nil)
1385
1386   ;; cqto
1387   (def-x86-opcode (cqto :cpu64) ()
1388     #x99 nil #x48)
1389
1390   ;; cwtd
1391   (def-x86-opcode cwtd ()
1392     #x99 nil nil #x66)
1393
1394   ;; cwtl
1395   (def-x86-opcode cwtl ()
1396     #x98 nil nil)
1397
1398   ;; dec (not the 1-byte form).  This exists on x8664, but gas doesn't
1399   ;; know that.
1400   (def-x86-opcode (decq :cpu64) ((:reg64 :insert-modrm-rm))
1401     #xff #o310 #x48)
1402   (def-x86-opcode (decq :cpu64) ((:anymem :insert-memory))
1403     #xff #o010 #x48)
1404
1405   (def-x86-opcode (decl :cpuno64) ((:reg32 :insert-opcode-reg))
1406     #x48 nil nil)
1407   ;; This is valid in 32 bit too, but use it only on x86-64
1408   (def-x86-opcode (decl :cpu64) ((:reg32 :insert-modrm-rm))
1409     #xff #o310 #x00)
1410   (def-x86-opcode decl ((:anymem :insert-memory))
1411     #xff #o010 #x00)
1412
1413   (def-x86-opcode (decw :cpuno64) ((:reg16 :insert-opcode-reg))
1414     #x48 nil nil #x66)
1415   ;; This is valud in 32 bit too, but use it only on x86-64
1416   (def-x86-opcode (decw :cpu64) ((:reg16 :insert-modrm-rm))
1417     #xff #o310 #x00 #x66)
1418   (def-x86-opcode decw ((:anymem :insert-memory))
1419     #xff #o010 #x00 #x66)
1420
1421   (def-x86-opcode decb ((:reg8 :insert-modrm-rm))
1422     #xfe #o310 #x00)
1423   (def-x86-opcode decb ((:anymem :insert-memory))
1424     #xfe #o010 #x00)
1425
1426   ;; div
1427   (def-x86-opcode (divq :cpu64) ((:reg64 :insert-modrm-rm))
1428     #xf7 #o360 #x48)
1429   (def-x86-opcode (divq :cpu64) ((:anymem :insert-memory))
1430     #xf7 #o060 #x48)
1431
1432   (def-x86-opcode divl ((:reg32 :insert-modrm-rm))
1433     #xf7 #o360 #x00)
1434   (def-x86-opcode divl ((:anymem :insert-memory))
1435     #xf7 #o060 #x00)
1436
1437   (def-x86-opcode divw ((:reg16 :insert-modrm-rm))
1438     #xf7 #o360 #x00 #x66)
1439   (def-x86-opcode divw ((:anymem :insert-memory))
1440     #xf7 #o060 #x00 #x66)
1441
1442   (def-x86-opcode divb ((:reg8 :insert-modrm-rm))
1443     #xf6 #o360 #x00)
1444   (def-x86-opcode divl ((:anymem :insert-memory))
1445     #xf6 #o060 #x00)
1446
1447   ;; enter.
1448
1449   (def-x86-opcode enter ((:imm16 :insert-imm16) (:imm8 :insert-extra))
1450     #xc8 nil nil)
1451
1452   ;; hlt
1453   (def-x86-opcode hlt ()
1454     #xf4 nil nil)
1455
1456   ;; idiv.  Note that GAS doesn't know about newer(?) idiv forms
1457   (def-x86-opcode (idivq :cpu64) ((:reg64 :insert-modrm-rm))
1458     #xf7 #o370 #x48)
1459   (def-x86-opcode (idivq :cpu64) ((:anymem :insert-memory))
1460     #xf7 #o070 #x48)
1461
1462   (def-x86-opcode idivl ((:reg32 :insert-modrm-rm))
1463     #xf7 #o370 #x00)
1464   (def-x86-opcode idivl ((:anymem :insert-memory))
1465     #xf7 #o070 #x00)
1466
1467   (def-x86-opcode idivw ((:reg16 :insert-modrm-rm))
1468     #xf7 #o370 #x00 #x66)
1469   (def-x86-opcode idivw ((:anymem :insert-memory))
1470     #xf7 #o070 #x00 #x66)
1471
1472   (def-x86-opcode idivb ((:reg8 :insert-modrm-rm))
1473     #xf6 #o370 #x00)
1474   (def-x86-opcode idivl ((:anymem :insert-memory))
1475     #xf6 #o070 #x00)
1476
1477   ;; imul
1478   (def-x86-opcode (imulq :cpu64) ((:reg64 :insert-modrm-rm))
1479     #xf7 #o350 #x48)
1480   (def-x86-opcode (imulq :cpu64) ((:anymem :insert-memory))
1481     #xf7 #o050 #x48)
1482
1483   (def-x86-opcode (imulq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1484     #x6b #o300 #x48)
1485   (def-x86-opcode (imulq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1486     #x6b #o000 #x48)
1487   (def-x86-opcode (imulq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1488     #x69 #o300 #x48)
1489   (def-x86-opcode (imulq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1490     #x69 #o000 #x48)
1491   (def-x86-opcode (imulq :cpu64) ((:reg64 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1492     #x0faf #o300 #x48)
1493   (def-x86-opcode (imulq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1494     #x0faf #o000 #x48)   
1495
1496   
1497   (def-x86-opcode imull ((:reg32 :insert-modrm-rm))
1498     #xf7 #o350 #x00)
1499   (def-x86-opcode imull ((:anymem :insert-memory))
1500     #xf7 #o050 #x00)
1501
1502   (def-x86-opcode imull ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1503     #x6b #o300 #x00)
1504   (def-x86-opcode imull ((:imm8s :insert-imm8s) (:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1505     #x6b #o000 #x00)
1506   (def-x86-opcode imull ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1507     #x69 #o300 #x00)
1508   (def-x86-opcode imull ((:imm32s :insert-imm32s) (:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1509     #x69 #o000 #x00)
1510   (def-x86-opcode imull ((:reg32 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1511     #x0faf #o300 #x00)
1512   (def-x86-opcode imull ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1513     #x0faf #o000 #x00)   
1514   
1515   (def-x86-opcode imulw ((:reg16 :insert-modrm-rm))
1516     #xf7 #o350 #x00 #x66)
1517   (def-x86-opcode imulw ((:anymem :insert-memory))
1518     #xf7 #o050 #x00 #x66)
1519
1520   (def-x86-opcode imulw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1521     #x6b #o300 #x00 #x66)
1522   (def-x86-opcode imulw ((:imm8s :insert-imm8s) (:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1523     #x6b #o000 #x00 #x66)
1524   (def-x86-opcode imulw ((:imm32s :insert-imm32s) (:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1525     #x69 #o300 #x00 #x66)
1526   (def-x86-opcode imulw ((:imm32s :insert-imm32s) (:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1527     #x69 #o000 #x00 #x66)
1528   (def-x86-opcode imulw ((:reg16 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1529     #x0faf #o300 #x00 #x66)
1530   (def-x86-opcode imulw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1531     #x0faf #o000 #x00 #x66)   
1532
1533   (def-x86-opcode imulb ((:reg8 :insert-modrm-rm))
1534     #xf6 #o350 #x00)
1535   (def-x86-opcode imulb ((:anymem :insert-memory))
1536     #xf6 #o050 #x00)
1537
1538   ;; inc (but not the one-byte form) is available on x86-64.
1539   (def-x86-opcode (incq :cpu64) ((:reg64 :insert-modrm-rm))
1540     #xff #o300 #x48)
1541   (def-x86-opcode (incq :cpu64) ((:anymem :insert-memory))
1542     #xff #o000 #x48)
1543
1544   (def-x86-opcode (incl :cpuno64) ((:reg32 :insert-opcode-reg))
1545     #x40 nil nil)
1546   ;; This is valid in 32-bit too, but use it only on x86-64
1547   (def-x86-opcode (incl :cpu64) ((:reg32 :insert-modrm-rm))
1548     #xff #o300 #x00)
1549   (def-x86-opcode incl ((:anymem :insert-memory))
1550     #xff #o000 #x00)
1551
1552   (def-x86-opcode (incw :cpuno64) ((:reg16 :insert-opcode-reg))
1553     #x40 nil nil #x66)
1554   ;; This is valid in 32-bit too, but use it only on x86-64
1555   (def-x86-opcode (incw :cpu64) ((:reg16 :insert-modrm-rm))
1556     #xff #o300 #x00 #x66)
1557   (def-x86-opcode incw ((:anymem :insert-memory))
1558     #xff #o000 #x00 #x66)
1559
1560   (def-x86-opcode incb ((:reg8 :insert-modrm-rm))
1561     #xfe #o300 #x00)
1562   (def-x86-opcode incb ((:anymem :insert-memory))
1563     #xfe #o000 #x00)
1564
1565   ;; int.  See also UUOs.
1566   (def-x86-opcode int ((:imm8 :insert-imm8-for-int))
1567     #xcd nil nil)
1568
1569   ;; Jcc.  Generate the short form here; maybe relax later.
1570   (def-x86-opcode (jcc :jump) ((:imm8 :insert-cc) (:label :insert-label))
1571     #x70 nil nil)
1572   (def-x86-opcode (jcc.pt :jump) ((:imm8 :insert-cc) (:label :insert-label))
1573     #x70 nil nil #x3e)
1574   (def-x86-opcode (jcc.pn :jump) ((:imm8 :insert-cc) (:label :insert-label))
1575     #x70 nil nil #x2e)
1576
1577   (def-x86-opcode (jo :jump) ((:label :insert-label))
1578     #x70 nil nil)
1579   (def-x86-opcode (jo.pt :jump) ((:label :insert-label))
1580     #x70 nil nil #x3e)
1581   (def-x86-opcode (jo.pn :jump) ((:label :insert-label))
1582     #x70 nil nil #x2e)
1583   (def-x86-opcode (jno :jump) ((:label :insert-label))
1584     #x71 nil nil)
1585   (def-x86-opcode (jno.pt :jump) ((:label :insert-label))
1586     #x71 nil nil #x3e)
1587   (def-x86-opcode (jno.pn :jump) ((:label :insert-label))
1588     #x71 nil nil #x2e)
1589   (def-x86-opcode (jb :jump) ((:label :insert-label))
1590     #x72 nil nil)
1591   (def-x86-opcode (jb.pt :jump) ((:label :insert-label))
1592     #x72 nil nil #x3e)
1593   (def-x86-opcode (jb.pn :jump) ((:label :insert-label))
1594     #x72 nil nil #x2e)
1595   (def-x86-opcode (jc :jump) ((:label :insert-label))
1596     #x72 nil nil)
1597   (def-x86-opcode (jc.pt :jump) ((:label :insert-label))
1598     #x72 nil nil #x3e)
1599   (def-x86-opcode (jc.pn :jump) ((:label :insert-label))
1600     #x72 nil nil #x2e)
1601   (def-x86-opcode (jae :jump) ((:label :insert-label))
1602     #x73 nil nil)
1603   (def-x86-opcode (jae.pt :jump) ((:label :insert-label))
1604     #x73 nil nil #x3e)
1605   (def-x86-opcode (jae.pn :jump) ((:label :insert-label))
1606     #x73 nil nil #x2e)
1607   (def-x86-opcode (jnc :jump) ((:label :insert-label))
1608     #x73 nil nil)
1609   (def-x86-opcode (jnc.pt :jump) ((:label :insert-label))
1610     #x73 nil nil #x3e)
1611   (def-x86-opcode (jnc.pn :jump) ((:label :insert-label))
1612     #x73 nil nil #x2e)
1613   (def-x86-opcode (je :jump) ((:label :insert-label))
1614     #x74 nil nil)
1615   (def-x86-opcode (je.pt :jump) ((:label :insert-label))
1616     #x74 nil nil #x3e)
1617   (def-x86-opcode (je.pn :jump) ((:label :insert-label))
1618     #x74 nil nil #x2e)
1619   (def-x86-opcode (jz :jump) ((:label :insert-label))
1620     #x74 nil nil)
1621   (def-x86-opcode (jz.pt :jump) ((:label :insert-label))
1622     #x74 nil nil #x3e)
1623   (def-x86-opcode (jz.pn :jump) ((:label :insert-label))
1624     #x74 nil nil #x2e)
1625   (def-x86-opcode (jne :jump) ((:label :insert-label))
1626     #x75 nil nil)
1627   (def-x86-opcode (jne.pt :jump) ((:label :insert-label))
1628     #x75 nil nil #x3e)
1629   (def-x86-opcode (jne.pn :jump) ((:label :insert-label))
1630     #x75 nil nil #x2e)
1631   (def-x86-opcode (jnz :jump) ((:label :insert-label))
1632     #x75 nil nil)
1633   (def-x86-opcode (jnz.pt :jump) ((:label :insert-label))
1634     #x75 nil nil #x3e)
1635   (def-x86-opcode (jnz.pn :jump) ((:label :insert-label))
1636     #x75 nil nil #x2e)
1637   (def-x86-opcode (jbe :jump) ((:label :insert-label))
1638     #x76 nil nil)
1639   (def-x86-opcode (jbe.pt :jump) ((:label :insert-label))
1640     #x76 nil nil #x3e)
1641   (def-x86-opcode (jbe.pn :jump) ((:label :insert-label))
1642     #x76 nil nil #x2e)
1643   (def-x86-opcode (ja :jump) ((:label :insert-label))
1644     #x77 nil nil)
1645   (def-x86-opcode (ja.pt :jump) ((:label :insert-label))
1646     #x77 nil nil #x3e)
1647   (def-x86-opcode (ja.pn :jump) ((:label :insert-label))
1648     #x77 nil nil #x2e)
1649   (def-x86-opcode (js :jump) ((:label :insert-label))
1650     #x78 nil nil)
1651   (def-x86-opcode (js.pt :jump) ((:label :insert-label))
1652     #x78 nil nil #x3e)
1653   (def-x86-opcode (js.pn :jump) ((:label :insert-label))
1654     #x78 nil nil #x2e)
1655   (def-x86-opcode (jns :jump) ((:label :insert-label))
1656     #x79 nil nil)
1657   (def-x86-opcode (jns.pt :jump) ((:label :insert-label))
1658     #x79 nil nil #x3e)
1659   (def-x86-opcode (jns.pn :jump) ((:label :insert-label))
1660     #x79 nil nil #x2e)
1661   (def-x86-opcode (jpe :jump) ((:label :insert-label))
1662     #x7a nil nil)
1663   (def-x86-opcode (jpe.pt :jump) ((:label :insert-label))
1664     #x7a nil nil #x3e)
1665   (def-x86-opcode (jpe.pn :jump) ((:label :insert-label))
1666     #x7a nil nil #x2e)
1667   (def-x86-opcode (jpo :jump) ((:label :insert-label))
1668     #x7b nil nil)
1669   (def-x86-opcode (jpo.pt :jump) ((:label :insert-label))
1670     #x7b nil nil #x3e)
1671   (def-x86-opcode (jpo.pn :jump) ((:label :insert-label))
1672     #x7b nil nil #x2e)
1673   (def-x86-opcode (jl :jump) ((:label :insert-label))
1674     #x7c nil nil)
1675   (def-x86-opcode (jl.pt :jump) ((:label :insert-label))
1676     #x7c nil nil #x3e)
1677   (def-x86-opcode (jl.pn :jump) ((:label :insert-label))
1678     #x7c nil nil #x2e)
1679   (def-x86-opcode (jge :jump) ((:label :insert-label))
1680     #x7d nil nil)
1681   (def-x86-opcode (jge.pt :jump) ((:label :insert-label))
1682     #x7d nil nil #x3e)
1683   (def-x86-opcode (jge.pn :jump) ((:label :insert-label))
1684     #x7d nil nil #x2e)
1685   (def-x86-opcode (jle :jump) ((:label :insert-label))
1686     #x7e nil nil)
1687   (def-x86-opcode (jle.pt :jump) ((:label :insert-label))
1688     #x7e nil nil #x3e)
1689   (def-x86-opcode (jle.pn :jump) ((:label :insert-label))
1690     #x7e nil nil #x2e)
1691   (def-x86-opcode (jg :jump) ((:label :insert-label))
1692     #x7f nil nil)
1693   (def-x86-opcode (jg.pt :jump) ((:label :insert-label))
1694     #x7f nil nil #x3e)
1695   (def-x86-opcode (jg.pn :jump) ((:label :insert-label))
1696     #x7f nil nil #x2e)
1697
1698   ;; jmp .  Translating the 8-bit pc-relative version to the 32-bit
1699   ;;        pc-relative version happens during relaxation.
1700   ;; On 32-bit, I think it's possible to use 16-bit pc-relative
1701   ;; displacements---this would save a byte in instances where
1702   ;; the displacement fit in 16 bits.
1703   (def-x86-opcode (jmp :jump) ((:label :insert-label))
1704     #xeb nil nil)
1705
1706   (def-x86-opcode (jmp :cpu64) ((:reg64 :insert-modrm-rm))
1707     #xff #o340 #x0)
1708   (def-x86-opcode (jmp :cpuno64) ((:reg32 :insert-modrm-rm))
1709     #xff #o340 nil)
1710
1711   (def-x86-opcode jmp ((:anymem :insert-memory))
1712     #xff #o040 #x0)
1713
1714   ;; lea
1715   (def-x86-opcode (leaq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1716     #x8d 0 #x48)
1717
1718   (def-x86-opcode leal ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1719     #x8d 0 #x00)
1720
1721   (def-x86-opcode leaw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1722     #x8d 0 #x00 #x66)
1723
1724   ;; leave
1725   (def-x86-opcode leave ()
1726     #xc9 nil nil)
1727
1728   ;; lock
1729   (def-x86-opcode lock ()
1730     #xf0 nil nil)
1731
1732   ;; lods
1733   (def-x86-opcode lodsq ()
1734     #xac nil #x48)
1735
1736   (def-x86-opcode lodsl ()
1737     #xac nil nil)
1738
1739   ;; loop
1740   (def-x86-opcode (loopq :cpu64) ((:label :insert-label))
1741     #xe2 nil #x48)
1742
1743   (def-x86-opcode loopl ((:label :insert-label))
1744     #xe2 nil nil)
1745
1746   (def-x86-opcode (loopzq :cpu64) ((:label :insert-label))
1747     #xe1 nil #x48)
1748
1749   (def-x86-opcode loopzl ((:label :insert-label))
1750     #xe1 nil nil)
1751
1752   (def-x86-opcode (loopnzq :cpu64) ((:label :insert-label))
1753     #xe0 nil #x48)
1754
1755   (def-x86-opcode loopnzl ((:label :insert-label))
1756     #xe0 nil nil)
1757
1758   ;; mov, including the MMX/XMM variants.
1759   (def-x86-opcode movq ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
1760     #x0f6f #o300 0)
1761   (def-x86-opcode movq ((:regmmx :insert-mmx-reg) (:anymem :insert-memory))
1762     #x0f7f #o0 0)
1763   (def-x86-opcode movq ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
1764     #x0f6f #o0 0)
1765   (def-x86-opcode movq ((:regxmm :insert-xmm-reg) (:regxmm :insert-xmm-rm))
1766     #x0f7e #o300 0 #xf3)
1767   (def-x86-opcode movq ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
1768     #x0f7e #o000 0 #xf3)
1769   (def-x86-opcode movq ((:regxmm :insert-xmm-reg) (:anymem :insert-memory))
1770     #x0fd6 #o000 0 #x66)
1771
1772   (def-x86-opcode (movq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
1773     #x89 #o300 #x48)
1774   (def-x86-opcode (movq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1775     #x8b #o0 #x48)
1776   (def-x86-opcode (movq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
1777     #x89 #o0 #x48)
1778   (def-x86-opcode (movq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
1779     #xc7 #o300 #x48)
1780   (def-x86-opcode (movq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1781     #xc7 #o000 #x48)
1782   (def-x86-opcode (movq :cpu64) ((:imm64 :insert-imm64) (:reg64 :insert-opcode-reg))
1783     #xb8 nil #x48)
1784
1785   (def-x86-opcode movl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
1786     #x89 #o300 #x00)
1787   (def-x86-opcode movl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1788     #x8b #o0 #x00)
1789   (def-x86-opcode movl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
1790     #x89 #o0 #x00)
1791   (def-x86-opcode movl ((:imm32s :insert-imm32s) (:reg32 :insert-opcode-reg))
1792     #xb8 nil #x00)
1793   (def-x86-opcode movl ((:self :insert-self) (:reg32 :insert-opcode-reg))
1794     #xb8 nil #x00)
1795   (def-x86-opcode movl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1796     #xc7 #o000 #x00)
1797
1798
1799   (def-x86-opcode movw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1800     #x89 #o300 #x00 #x66)
1801   (def-x86-opcode movw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1802     #x8b #o0 #x00  #x66)
1803   (def-x86-opcode movw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
1804     #x89 #o0 #x00 #x66)
1805   (def-x86-opcode movw ((:imm16 :insert-imm16) (:reg16 :insert-opcode-reg))
1806     #xb8 nil #x00 #x66)
1807   (def-x86-opcode movw ((:imm16 :insert-imm16) (:anymem :insert-memory))
1808     #xc7 #o000 #x00 #x66)
1809
1810   (def-x86-opcode movb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
1811     #x88 #o300 0)
1812   (def-x86-opcode movb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
1813     #x8a #o0 0)
1814   (def-x86-opcode movb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
1815     #x88 #o0 0)
1816   (def-x86-opcode movb ((:imm8s :insert-imm8s) (:reg8 :insert-opcode-reg))
1817     #xb0 nil 0)
1818   (def-x86-opcode movb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1819     #xc6 #o000 0)
1820 
1821   ;; movd
1822   (def-x86-opcode (movd :cpu64) ((:reg64 :insert-modrm-rm) (:regmmx :insert-mmx-reg))
1823     #x0f6e #o300 #x48)
1824   (def-x86-opcode movd ((:reg32 :insert-modrm-rm) (:regmmx :insert-mmx-reg))
1825     #x0f6e #o300 0)
1826   (def-x86-opcode movd ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
1827     #x0f6e #o000 0)
1828   (def-x86-opcode movd ((:regmmx :insert-mmx-reg) (:reg64 :insert-modrm-rm))
1829     #x0f7e #o300 #x48)
1830   (def-x86-opcode movd ((:regmmx :insert-mmx-reg) (:reg32 :insert-modrm-rm))
1831     #x0f7e #o300 #x0)
1832   (def-x86-opcode movd ((:regmmx :insert-mmx-reg) (:anymem :insert-memory))
1833     #x0f7e #o000 #x0)
1834
1835   (def-x86-opcode (movd :cpu64) ((:reg64 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
1836     #x0f6e #o300 #x48 #x66)
1837   (def-x86-opcode movd ((:reg32 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
1838     #x0f6e #o300 0 #x66)
1839   (def-x86-opcode movd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
1840     #x0f6e #o000 0 #x66)
1841   (def-x86-opcode (movd :cpu64) ((:regxmm :insert-xmm-reg) (:reg64 :insert-modrm-rm))
1842     #x0f7e #o300 #x48 #x66)
1843   (def-x86-opcode movd ((:regxmm :insert-xmm-reg) (:reg32 :insert-modrm-rm))
1844     #x0f7e #o300 #x0 #x66)
1845   (def-x86-opcode movd ((:regxmm :insert-xmm-reg) (:anymem :insert-memory))
1846     #x0f7e #o000 #x0 #x66)
1847
1848   ;; sign-extending mov
1849   (def-x86-opcode movsbl ((:reg8 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1850     #x0fbe #o300 0)
1851   (def-x86-opcode movsbl ((:anymem :insert-memory)  (:reg32 :insert-modrm-reg))
1852     #x0fbe #o000 0)
1853   (def-x86-opcode movsbw ((:reg8 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1854     #x0fbe #o300 0 #x66)
1855   (def-x86-opcode movsbw ((:anymem :insert-memory) (:reg16 :insert-modrm-rm))
1856     #x0fbe #o300 0 #x66)
1857   (def-x86-opcode (movsbq :cpu64) ((:reg8 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1858     #x0fbe #o300 #x48)
1859   (def-x86-opcode (movsbq :cpu64) ((:anymem :insert-memory)  (:reg64 :insert-modrm-reg))
1860     #x0fbe #o000 #x48)
1861   (def-x86-opcode movswl ((:reg16 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1862     #x0fbf #o300 0)
1863   (def-x86-opcode movswl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1864     #x0fbf #o000 0)
1865   (def-x86-opcode (movswq :cpu64) ((:reg16 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1866     #x0fbf #o300 #x48)
1867   (def-x86-opcode (movswq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1868     #x0fbf #o000 #x48)
1869   (def-x86-opcode (movslq :cpu64) ((:reg32 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1870     #x63 #o300 #x48)
1871   (def-x86-opcode (movslq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1872     #x63 #o000 #x48)
1873
1874   ;; zero-extending MOVs
1875   (def-x86-opcode movzbl ((:reg8 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1876     #x0fb6 #o300 0)
1877   (def-x86-opcode movzbl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1878     #x0fb6 #o000 0)
1879   (def-x86-opcode movzbw ((:reg8 :insert-modrm-rm) (:reg16 :insert-modrm-reg))
1880     #x0fb6 #o300 0 #x66)
1881   (def-x86-opcode movzbw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1882     #x0fb6 #o300 0 #x66)
1883   (def-x86-opcode movzwl ((:reg16 :insert-modrm-rm) (:reg32 :insert-modrm-reg))
1884     #x0fb7 #o300 0)
1885   (def-x86-opcode movzwl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1886     #x0fb7 #o000 0)
1887   (def-x86-opcode (movzbq :cpu64) ((:reg8 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1888     #x0fb6 #o300 #x48)
1889   (def-x86-opcode (movzbq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1890     #x0fb6 #o000 #x48)
1891   (def-x86-opcode (movzwq :cpu64) ((:reg16 :insert-modrm-rm) (:reg64 :insert-modrm-reg))
1892     #x0fb7 #o300 #x48)
1893   (def-x86-opcode (movzwq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1894     #x0fb7 #o000 #x48)
1895
1896   ;; mul
1897   (def-x86-opcode (mulq :cpu64) ((:reg64 :insert-modrm-rm))
1898     #xf7 #o340 #x48)
1899   (def-x86-opcode (mulq :cpu64) ((:anymem :insert-memory))
1900     #xf7 #o040 #x48)
1901
1902   (def-x86-opcode mull ((:reg32 :insert-modrm-rm))
1903     #xf7 #o340 #x00)
1904   (def-x86-opcode mull ((:anymem :insert-memory))
1905     #xf7 #o040 #x00)
1906
1907   (def-x86-opcode mulw ((:reg16 :insert-modrm-rm))
1908     #xf7 #o340 #x00 #x66)
1909   (def-x86-opcode mulw ((:anymem :insert-memory))
1910     #xf7 #o040 #x00 #x66)
1911
1912   (def-x86-opcode mulb ((:reg8 :insert-modrm-rm))
1913     #xf6 #o340 #x00)
1914   (def-x86-opcode mull ((:anymem :insert-memory))
1915     #xf6 #o040 #x00)
1916
1917   ;; neg
1918   (def-x86-opcode (negq :cpu64) ((:reg64 :insert-modrm-rm))
1919     #xf7 #o330 #x48)
1920   (def-x86-opcode (negq :cpu64) ((:anymem :insert-memory))
1921     #xf7 #o030 #x48)
1922
1923   (def-x86-opcode negl ((:reg32 :insert-modrm-rm))
1924     #xf7 #o330 #x00)
1925   (def-x86-opcode negl ((:anymem :insert-memory))
1926     #xf7 #o030 #x00)
1927
1928   (def-x86-opcode negw ((:reg16 :insert-modrm-rm))
1929     #xf7 #o330 #x00 #x66)
1930   (def-x86-opcode negw ((:anymem :insert-memory))
1931     #xf7 #o030 #x00 #x66)
1932
1933   (def-x86-opcode negb ((:reg8 :insert-modrm-rm))
1934     #xf6 #o330 #x00)
1935   (def-x86-opcode negb ((:anymem :insert-memory))
1936     #xf6 #o030 #x00)
1937
1938   ;; nop
1939   (def-x86-opcode nop ()
1940     #x90 nil nil)
1941
1942   ;; not
1943   (def-x86-opcode (notq :cpu64) ((:reg64 :insert-modrm-rm))
1944     #xf7 #o320 #x48)
1945   (def-x86-opcode (notq :cpu64) ((:anymem :insert-memory))
1946     #xf7 #o020 #x48)
1947   (def-x86-opcode notl ((:reg32 :insert-modrm-rm))
1948     #xf7 #o320 #x0)
1949   (def-x86-opcode notl ((:anymem :insert-memory))
1950     #xf7 #o020 #x0)
1951   (def-x86-opcode notw ((:reg16 :insert-modrm-rm))
1952     #xf7 #o320 #x0 #x66)
1953   (def-x86-opcode notw ((:anymem :insert-memory))
1954     #xf7 #o020 #x0 #x66)
1955   (def-x86-opcode notb ((:reg8 :insert-modrm-rm))
1956     #xf6 #o320 #x0)
1957   (def-x86-opcode notb ((:anymem :insert-memory))
1958     #xf6 #o020 #x0)
1959
1960   ;; or
1961   (def-x86-opcode (orq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
1962     #x09 #o300 #x48)
1963   (def-x86-opcode (orq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
1964     #x0b #o000 #x48)
1965   (def-x86-opcode (orq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
1966     #x09 #x00 #x48)
1967   (def-x86-opcode (orq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
1968     #x83 #o310 #x48)
1969   (def-x86-opcode (orq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
1970     #x0d nil #x48)
1971   (def-x86-opcode (orq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
1972     #x81 #o310 #x48)
1973   (def-x86-opcode (orq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1974     #x83 #o010 #x48)
1975   (def-x86-opcode (orq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1976     #x81 #o010 #x48)
1977
1978   (def-x86-opcode orl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
1979     #x09 #o300 #x00)
1980   (def-x86-opcode orl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
1981     #x0b #o000 #x00)
1982   (def-x86-opcode orl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
1983     #x09 #x00 #x00)
1984   (def-x86-opcode orl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
1985     #x83 #o310 #x00)
1986   (def-x86-opcode orl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
1987     #x0d nil nil)
1988   (def-x86-opcode orl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
1989     #x81 #o310 #x00)
1990   (def-x86-opcode orl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
1991     #x83 #o010 #x00)
1992   (def-x86-opcode orl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
1993     #x81 #o010 #x00)
1994
1995   (def-x86-opcode orw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
1996     #x09 #o300 #x00 #x66)
1997   (def-x86-opcode orw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
1998     #x0b #o000 #x00 #x66)
1999   (def-x86-opcode orw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2000     #x09 #x00 #x00 #x66)
2001   (def-x86-opcode orw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
2002     #x83 #o310 #x00 #x66)
2003   (def-x86-opcode orw ((:imm16 :insert-imm16) (:acc :insert-nothing))
2004     #x0d nil nil #x66)
2005   (def-x86-opcode orw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
2006     #x81 #o310 #x00 #x66)
2007   (def-x86-opcode orw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2008     #x83 #o010 #x00 #x66)
2009   (def-x86-opcode orw ((:imm16 :insert-imm16) (:anymem :insert-memory))
2010     #x81 #o010 #x00 #x66)
2011
2012   (def-x86-opcode orb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2013     #x08 #o300 #x00)
2014   (def-x86-opcode orb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2015     #x0a #o000 #x00)
2016   (def-x86-opcode orb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2017     #x08 #x00 #x00)
2018   (def-x86-opcode orb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
2019     #x0c nil nil)
2020   (def-x86-opcode orb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2021     #x80 #o310 #x00)
2022   (def-x86-opcode orb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2023     #x80 #o310 #x00)
2024   (def-x86-opcode orb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2025     #x80 #o010 #x00)
2026
2027   ;; pop
2028   (def-x86-opcode (popq :cpu64) ((:reg64 :insert-opcode-reg))
2029     #x58 nil #x0)
2030   (def-x86-opcode (popq :cpu64) ((:anymem :insert-memory))
2031     #x8f #o000 #x0)
2032
2033   (def-x86-opcode (popl :cpuno64) ((:reg32 :insert-opcode-reg))
2034     #x58 nil nil)
2035   (def-x86-opcode (popl :cpuno64) ((:anymem :insert-memory))
2036     #x8f #o000 nil)
2037
2038   (def-x86-opcode popw ((:reg16 :insert-opcode-reg))
2039     #x58 nil #x0 #x66)
2040   (def-x86-opcode popw ((:anymem :insert-memory))
2041     #x8f #o000 #x0 #x66)
2042
2043   ;; popf
2044   (def-x86-opcode (popfq :cpu64) ()
2045     #x9d nil #x48)
2046   (def-x86-opcode popfl ()
2047     #x9d nil nil)
2048
2049   ;; push .  It's not clear how "pushw $imm16" is encoded.
2050   (def-x86-opcode (pushq :cpu64) ((:reg64 :insert-opcode-reg))
2051     #x50 nil #x0)
2052   (def-x86-opcode (pushq :cpu64) ((:anymem :insert-memory))
2053     #xff #o060 #x0)
2054   (def-x86-opcode (pushq :cpu64) ((:imm8s :insert-imm8s))
2055     #x6a nil nil)
2056   (def-x86-opcode (pushq :cpu64) ((:imm32s :insert-imm32s))
2057     #x68 nil nil)
2058
2059   (def-x86-opcode (pushl :cpuno64) ((:reg32 :insert-opcode-reg))
2060     #x50 nil nil)
2061   (def-x86-opcode (pushl :cpuno64) ((:anymem :insert-memory))
2062     #xff #o060 nil)
2063   (def-x86-opcode (pushl :cpuno64) ((:imm8s :insert-imm8s))
2064     #x6a nil nil)
2065   (def-x86-opcode (pushl :cpuno64) ((:imm32s :insert-imm32s))
2066     #x68 nil nil)
2067
2068   (def-x86-opcode pushw ((:reg16 :insert-opcode-reg))
2069     #x50 nil 0 #x66)
2070   (def-x86-opcode pushw ((:anymem :insert-memory))
2071     #xff #o060 #x0 #x66)
2072
2073   ;; pushf
2074   (def-x86-opcode (pushfq :cpu64) ()
2075     #x9c nil nil)
2076   (def-x86-opcode (pushfl :cpuno64) ()
2077     #x9c nil nil)
2078   (def-x86-opcode pushfw ()
2079     #x9c nil nil #x66)
2080
2081   ;; rcl.  Note that the :ShiftCount operand type only matches %cl.
2082   (def-x86-opcode (rclq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2083     #xd1 #o320 #x48)
2084   (def-x86-opcode (rclq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2085     #xd1 #o020 #x48)
2086   (def-x86-opcode (rclq :cpu64) ((:reg64 :insert-modrm-rm))
2087     #xd1 #o320 #x48)
2088   (def-x86-opcode (rclq :cpu64) ((:anymem :insert-memory))
2089     #xd1 #o020 #x48)
2090   (def-x86-opcode (rclq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2091     #xc1 #o320 #x48)
2092   (def-x86-opcode (rclq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2093     #xd3 #o320 #x48)
2094 
2095   (def-x86-opcode rcll ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2096     #xd1 #o320 #x0)
2097   (def-x86-opcode rcll ((:imm1 :insert-nothing) (:anymem :insert-memory))
2098     #xd1 #o020 #x0)
2099   (def-x86-opcode rcll ((:reg32 :insert-modrm-rm))
2100     #xd1 #o320 #x0)
2101   (def-x86-opcode rcll ((:anymem :insert-memory))
2102     #xd1 #o020 #x0)
2103   (def-x86-opcode rcll ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2104     #xc1 #o320 #x0)
2105   (def-x86-opcode rcll ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2106     #xd3 #o320 #x0)
2107
2108   (def-x86-opcode rclw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2109     #xd1 #o320 #x0 #x66)
2110   (def-x86-opcode rclw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2111     #xd1 #o020 #x0 #x66)
2112   (def-x86-opcode rclw ((:reg16 :insert-modrm-rm))
2113     #xd1 #o320 #x0 #x66)
2114   (def-x86-opcode rclw ((:anymem :insert-memory))
2115     #xd1 #o020 #x0 #x66)
2116   (def-x86-opcode rclw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2117     #xc1 #o320 #x0 #x66)
2118   (def-x86-opcode rclw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2119     #xd3 #o320 #x0 #x66)
2120
2121   (def-x86-opcode rclb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2122     #xd0 #o320 #x0)
2123   (def-x86-opcode rclb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2124     #xd0 #o020 #x0)
2125   (def-x86-opcode rclb ((:reg8 :insert-modrm-rm))
2126     #xd0 #o320 #x0)
2127   (def-x86-opcode rclb ((:anymem :insert-memory))
2128     #xd0 #o020 #x0)
2129   (def-x86-opcode rclb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2130     #xc0 #o320 #x0)
2131   (def-x86-opcode rclb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2132     #xd2 #o320 #x0)
2133
2134   ;; rcr
2135   (def-x86-opcode (rcrq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2136     #xd1 #o330 #x48)
2137   (def-x86-opcode (rcrq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2138     #xd1 #o030 #x48)
2139   (def-x86-opcode (rcrq :cpu64) ((:reg64 :insert-modrm-rm))
2140     #xd1 #o330 #x48)
2141   (def-x86-opcode (rcrq :cpu64) ((:anymem :insert-memory))
2142     #xd1 #o030 #x48)
2143   (def-x86-opcode (rcrq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2144     #xc1 #o330 #x48)
2145   (def-x86-opcode (rcrq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2146     #xd3 #o330 #x48)
2147 
2148   (def-x86-opcode rcrl ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2149     #xd1 #o330 #x0)
2150   (def-x86-opcode rcrl ((:imm1 :insert-nothing) (:anymem :insert-memory))
2151     #xd1 #o030 #x0)
2152   (def-x86-opcode rcrl ((:reg32 :insert-modrm-rm))
2153     #xd1 #o330 #x0)
2154   (def-x86-opcode rcrl ((:anymem :insert-memory))
2155     #xd1 #o030 #x0)
2156   (def-x86-opcode rcrl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2157     #xc1 #o330 #x0)
2158   (def-x86-opcode rcrl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2159     #xd3 #o330 #x0)
2160
2161   (def-x86-opcode rcrw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2162     #xd1 #o330 #x0 #x66)
2163   (def-x86-opcode rcrw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2164     #xd1 #o030 #x0 #x66)
2165   (def-x86-opcode rcrw ((:reg16 :insert-modrm-rm))
2166     #xd1 #o330 #x0 #x66)
2167   (def-x86-opcode rcrw ((:anymem :insert-memory))
2168     #xd1 #o030 #x0 #x66)
2169   (def-x86-opcode rcrw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2170     #xc1 #o330 #x0 #x66)
2171   (def-x86-opcode rcrw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2172     #xd3 #o330 #x0 #x66)
2173
2174   (def-x86-opcode rcrb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2175     #xd0 #o330 #x0)
2176   (def-x86-opcode rcrb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2177     #xd0 #o030 #x0)
2178   (def-x86-opcode rcrb ((:reg8 :insert-modrm-rm))
2179     #xd0 #o330 #x0)
2180   (def-x86-opcode rcrb ((:anymem :insert-memory))
2181     #xd0 #o030 #x0)
2182   (def-x86-opcode rcrb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2183     #xc0 #o330 #x0)
2184   (def-x86-opcode rcrb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2185     #xd2 #o330 #x0)
2186
2187   ;; repe, repne.  These are really prefixes, that should
2188   ;; only be used before string instructions.
2189   (def-x86-opcode repe ()
2190     #xf3 nil nil)
2191
2192   (def-x86-opcode repne ()
2193     #xf2 nil nil)
2194
2195   ;; ret
2196   (def-x86-opcode ret ()
2197     #xc3 nil nil)
2198
2199   (def-x86-opcode ret ((:imm16 :insert-imm16))
2200     #xc2 nil nil)
2201
2202   ;; rol
2203   (def-x86-opcode (rolq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2204     #xd1 #o300 #x48)
2205   (def-x86-opcode (rolq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2206     #xd1 #o000 #x48)
2207   (def-x86-opcode (rolq :cpu64) ((:reg64 :insert-modrm-rm))
2208     #xd1 #o300 #x48)
2209   (def-x86-opcode (rolq :cpu64) ((:anymem :insert-memory))
2210     #xd1 #o000 #x48)
2211   (def-x86-opcode (rolq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2212     #xc1 #o300 #x48)
2213   (def-x86-opcode (rolq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2214     #xd3 #o300 #x48)
2215 
2216   (def-x86-opcode roll ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2217     #xd1 #o300 #x0)
2218   (def-x86-opcode roll ((:imm1 :insert-nothing) (:anymem :insert-memory))
2219     #xd1 #o000 #x0)
2220   (def-x86-opcode roll ((:reg32 :insert-modrm-rm))
2221     #xd1 #o300 #x0)
2222   (def-x86-opcode roll ((:anymem :insert-memory))
2223     #xd1 #o000 #x0)
2224   (def-x86-opcode roll ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2225     #xc1 #o300 #x0)
2226   (def-x86-opcode roll ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2227     #xd3 #o300 #x0)
2228
2229   (def-x86-opcode rolw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2230     #xd1 #o300 #x0 #x66)
2231   (def-x86-opcode rolw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2232     #xd1 #o000 #x0 #x66)
2233   (def-x86-opcode rolw ((:reg16 :insert-modrm-rm))
2234     #xd1 #o300 #x0 #x66)
2235   (def-x86-opcode rolw ((:anymem :insert-memory))
2236     #xd1 #o000 #x0 #x66)
2237   (def-x86-opcode rolw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2238     #xc1 #o300 #x0 #x66)
2239   (def-x86-opcode rolw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2240     #xd3 #o300 #x0 #x66)
2241
2242   (def-x86-opcode rolb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2243     #xd0 #o300 #x0)
2244   (def-x86-opcode rolb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2245     #xd0 #o000 #x0)
2246   (def-x86-opcode rolb ((:reg8 :insert-modrm-rm))
2247     #xd0 #o300 #x0)
2248   (def-x86-opcode rolb ((:anymem :insert-memory))
2249     #xd0 #o000 #x0)
2250   (def-x86-opcode rolb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2251     #xc0 #o300 #x0)
2252   (def-x86-opcode rolb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2253     #xd2 #o300 #x0)
2254
2255   ;; ror
2256   (def-x86-opcode (rorq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2257     #xd1 #o310 #x48)
2258   (def-x86-opcode (rorq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2259     #xd1 #o010 #x48)
2260   (def-x86-opcode (rorq :cpu64) ((:reg64 :insert-modrm-rm))
2261     #xd1 #o310 #x48)
2262   (def-x86-opcode (rorq :cpu64) ((:anymem :insert-memory))
2263     #xd1 #o010 #x48)
2264   (def-x86-opcode (rorq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2265     #xc1 #o310 #x48)
2266   (def-x86-opcode (rorq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2267     #xd3 #o310 #x48)
2268 
2269   (def-x86-opcode rorl ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2270     #xd1 #o310 #x0)
2271   (def-x86-opcode rorl ((:imm1 :insert-nothing) (:anymem :insert-memory))
2272     #xd1 #o010 #x0)
2273   (def-x86-opcode rorl ((:reg32 :insert-modrm-rm))
2274     #xd1 #o310 #x0)
2275   (def-x86-opcode rorl ((:anymem :insert-memory))
2276     #xd1 #o010 #x0)
2277   (def-x86-opcode rorl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2278     #xc1 #o310 #x0)
2279   (def-x86-opcode rorl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2280     #xd3 #o310 #x0)
2281
2282   (def-x86-opcode rorw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2283     #xd1 #o310 #x0 #x66)
2284   (def-x86-opcode rorw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2285     #xd1 #o010 #x0 #x66)
2286   (def-x86-opcode rorw ((:reg16 :insert-modrm-rm))
2287     #xd1 #o310 #x0 #x66)
2288   (def-x86-opcode rorw ((:anymem :insert-memory))
2289     #xd1 #o010 #x0 #x66)
2290   (def-x86-opcode rorw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2291     #xc1 #o310 #x0 #x66)
2292   (def-x86-opcode rorw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2293     #xd3 #o310 #x0 #x66)
2294
2295   (def-x86-opcode rorb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2296     #xd0 #o310 #x0)
2297   (def-x86-opcode rorb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2298     #xd0 #o010 #x0)
2299   (def-x86-opcode rorb ((:reg8 :insert-modrm-rm))
2300     #xd0 #o310 #x0)
2301   (def-x86-opcode rorb ((:anymem :insert-memory))
2302     #xd0 #o010 #x0)
2303   (def-x86-opcode rorb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2304     #xc0 #o310 #x0)
2305   (def-x86-opcode rorb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2306     #xd2 #o310 #x0)
2307
2308   ;; sar
2309   (def-x86-opcode (sarq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2310     #xd1 #o370 #x48)
2311   (def-x86-opcode (sarq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2312     #xd1 #o070 #x48)
2313   (def-x86-opcode (sarq :cpu64) ((:reg64 :insert-modrm-rm))
2314     #xd1 #o370 #x48)
2315   (def-x86-opcode (sarq :cpu64) ((:anymem :insert-memory))
2316     #xd1 #o070 #x48)
2317   (def-x86-opcode (sarq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2318     #xc1 #o370 #x48)
2319   (def-x86-opcode (sarq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2320     #xd3 #o370 #x48)
2321 
2322   (def-x86-opcode sarl ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2323     #xd1 #o370 #x0)
2324   (def-x86-opcode sarl ((:imm1 :insert-nothing) (:anymem :insert-memory))
2325     #xd1 #o070 #x0)
2326   (def-x86-opcode sarl ((:reg32 :insert-modrm-rm))
2327     #xd1 #o370 #x0)
2328   (def-x86-opcode sarl ((:anymem :insert-memory))
2329     #xd1 #o070 #x0)
2330   (def-x86-opcode sarl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2331     #xc1 #o370 #x0)
2332   (def-x86-opcode sarl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2333     #xd3 #o370 #x0)
2334
2335   (def-x86-opcode sarw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2336     #xd1 #o370 #x0 #x66)
2337   (def-x86-opcode sarw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2338     #xd1 #o070 #x0 #x66)
2339   (def-x86-opcode sarw ((:reg16 :insert-modrm-rm))
2340     #xd1 #o370 #x0 #x66)
2341   (def-x86-opcode sarw ((:anymem :insert-memory))
2342     #xd1 #o070 #x0 #x66)
2343   (def-x86-opcode sarw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2344     #xc1 #o370 #x0 #x66)
2345   (def-x86-opcode sarw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2346     #xd3 #o370 #x0 #x66)
2347
2348   (def-x86-opcode sarb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2349     #xd0 #o370 #x0)
2350   (def-x86-opcode sarb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2351     #xd0 #o070 #x0)
2352   (def-x86-opcode sarb ((:reg8 :insert-modrm-rm))
2353     #xd0 #o370 #x0)
2354   (def-x86-opcode sarb ((:anymem :insert-memory))
2355     #xd0 #o070 #x0)
2356   (def-x86-opcode sarb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2357     #xc0 #o370 #x0)
2358   (def-x86-opcode sarb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2359     #xd2 #o370 #x0)
2360
2361   ;; sbb
2362   (def-x86-opcode (sbbq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2363     #x19 #o300 #x48)
2364   (def-x86-opcode (sbbq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
2365     #x1b #o000 #x48)
2366   (def-x86-opcode (sbbq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2367     #x19 #x00 #x48)
2368   (def-x86-opcode (sbbq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
2369     #x83 #o330 #x48)
2370   (def-x86-opcode (sbbq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2371     #x1d nil #x48)
2372   (def-x86-opcode (sbbq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
2373     #x81 #o330 #x48)
2374   (def-x86-opcode (sbbq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2375     #x83 #o030 #x48)
2376   (def-x86-opcode (sbbq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2377     #x81 #o030 #x48)
2378
2379   (def-x86-opcode sbbl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2380     #x19 #o300 #x00)
2381   (def-x86-opcode sbbl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
2382     #x1b #o000 #x00)
2383   (def-x86-opcode sbbl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2384     #x19 #x00 #x00)
2385   (def-x86-opcode sbbl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
2386     #x83 #o330 #x00)
2387   (def-x86-opcode sbbl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2388     #x1d nil nil)
2389   (def-x86-opcode sbbl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
2390     #x81 #o330 #x00)
2391   (def-x86-opcode sbbl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2392     #x83 #o030 #x00)
2393   (def-x86-opcode sbbl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2394     #x81 #o030 #x00)
2395
2396   (def-x86-opcode sbbw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2397     #x19 #o300 #x00 #x66)
2398   (def-x86-opcode sbbw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
2399     #x1b #o000 #x00 #x66)
2400   (def-x86-opcode sbbw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2401     #x19 #x00 #x00 #x66)
2402   (def-x86-opcode sbbw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
2403     #x83 #o330 #x00 #x66)
2404   (def-x86-opcode sbbw ((:imm16 :insert-imm16) (:acc :insert-nothing))
2405     #x1d nil nil #x66)
2406   (def-x86-opcode sbbw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
2407     #x81 #o330 #x00 #x66)
2408   (def-x86-opcode sbbw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2409     #x83 #o030 #x00 #x66)
2410   (def-x86-opcode sbbw ((:imm16 :insert-imm16) (:anymem :insert-memory))
2411     #x81 #o030 #x00 #x66)
2412
2413   (def-x86-opcode sbbb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2414     #x18 #o300 #x00)
2415   (def-x86-opcode sbbb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2416     #x1a #o000 #x00)
2417   (def-x86-opcode sbbb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2418     #x18 #x00 #x00)
2419   (def-x86-opcode sbbb ((:imm8 :insert-imm8) (:acc :insert-nothing))
2420     #x1c nil nil)
2421   (def-x86-opcode sbbb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2422     #x80 #o330 #x00)
2423   (def-x86-opcode sbbb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2424     #x80 #o330 #x00)
2425   (def-x86-opcode sbbb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2426     #x80 #o030 #x00)
2427
2428   ;; scas
2429   (def-x86-opcode (scasq :cpu64) ()
2430     #xaf nil #x48)
2431   (def-x86-opcode scasl ()
2432     #xaf nil nil)
2433   (def-x86-opcode scasw ()
2434     #xaf nil nil #x66)
2435   (def-x86-opcode scasb ()
2436     #xae nil nil)
2437
2438
2439   ;; setcc
2440   (def-x86-opcode setcc ((:imm8 :insert-cc) (:reg8 :insert-modrm-rm))
2441     #x0f90 #o300 0)     
2442   (def-x86-opcode seto ((:reg8 :insert-modrm-rm))
2443     #x0f90 #o300 0)
2444   (def-x86-opcode seto ((:anymem :insert-memory))
2445     #x0f90 #o000 0)
2446   (def-x86-opcode setno ((:reg8 :insert-modrm-rm))
2447     #x0f91 #o300 0)
2448   (def-x86-opcode setno ((:anymem :insert-memory))
2449     #x0f91 #o000 0)
2450   (def-x86-opcode setb ((:reg8 :insert-modrm-rm))
2451     #x0f92 #o300 0)
2452   (def-x86-opcode setb ((:anymem :insert-memory))
2453     #x0f92 #o000 0)
2454   (def-x86-opcode setc ((:reg8 :insert-modrm-rm))
2455     #x0f92 #o300 0)
2456   (def-x86-opcode setc ((:anymem :insert-memory))
2457     #x0f92 #o000 0)
2458   (def-x86-opcode setae ((:reg8 :insert-modrm-rm))
2459     #x0f93 #o300 0)
2460   (def-x86-opcode setae ((:anymem :insert-memory))
2461     #x0f93 #o000 0)
2462   (def-x86-opcode sete ((:reg8 :insert-modrm-rm))
2463     #x0f94 #o300 0)
2464   (def-x86-opcode sete ((:anymem :insert-memory))
2465     #x0f94 #o000 0)
2466   (def-x86-opcode setne ((:reg8 :insert-modrm-rm))
2467     #x0f95 #o300 0)
2468   (def-x86-opcode setne ((:anymem :insert-memory))
2469     #x0f95 #o000 0)
2470   (def-x86-opcode setbe ((:reg8 :insert-modrm-rm))
2471     #x0f96 #o300 0)
2472   (def-x86-opcode setbe ((:anymem :insert-memory))
2473     #x0f96 #o000 0)
2474   (def-x86-opcode seta ((:reg8 :insert-modrm-rm))
2475     #x0f97 #o300 0)
2476   (def-x86-opcode seta ((:anymem :insert-memory))
2477     #x0f97 #o000 0)
2478   (def-x86-opcode sets ((:reg8 :insert-modrm-rm))
2479     #x0f98 #o300 0)
2480   (def-x86-opcode sets ((:anymem :insert-memory))
2481     #x0f98 #o000 0)
2482   (def-x86-opcode setns ((:reg8 :insert-modrm-rm))
2483     #x0f99 #o300 0)
2484   (def-x86-opcode setns ((:anymem :insert-memory))
2485     #x0f99 #o000 0)
2486   (def-x86-opcode setpe ((:reg8 :insert-modrm-rm))
2487     #x0f9a #o300 0)
2488   (def-x86-opcode setpe ((:anymem :insert-memory))
2489     #x0f9a #o000 0)
2490   (def-x86-opcode setpo ((:reg8 :insert-modrm-rm))
2491     #x0f9b #o300 0)
2492   (def-x86-opcode setpo ((:anymem :insert-memory))
2493     #x0f9b #o000 0)
2494   (def-x86-opcode setl ((:reg8 :insert-modrm-rm))
2495     #x0f9c #o300 0)
2496   (def-x86-opcode setl ((:anymem :insert-memory))
2497     #x0f9c #o000 0)
2498   (def-x86-opcode setge ((:reg8 :insert-modrm-rm))
2499     #x0f9d #o300 0)
2500   (def-x86-opcode setge ((:anymem :insert-memory))
2501     #x0f9d #o000 0)
2502   (def-x86-opcode setle ((:reg8 :insert-modrm-rm))
2503     #x0f9e #o300 0)
2504   (def-x86-opcode setle ((:anymem :insert-memory))
2505     #x0f9e #o000 0)
2506   (def-x86-opcode setg ((:reg8 :insert-modrm-rm))
2507     #x0f9f #o300 0)
2508   (def-x86-opcode setg ((:anymem :insert-memory))
2509     #x0f9f #o000 0)
2510
2511   ;; shl
2512   (def-x86-opcode (shlq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2513     #xd1 #o340 #x48)
2514   (def-x86-opcode (shlq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2515     #xd1 #o040 #x48)
2516   (def-x86-opcode (shlq :cpu64) ((:reg64 :insert-modrm-rm))
2517     #xd1 #o340 #x48)
2518   (def-x86-opcode (shlq :cpu64) ((:anymem :insert-memory))
2519     #xd1 #o040 #x48)
2520   (def-x86-opcode (shlq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2521     #xc1 #o340 #x48)
2522   (def-x86-opcode (shlq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2523     #xd3 #o340 #x48)
2524 
2525   (def-x86-opcode shll ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2526     #xd1 #o340 #x0)
2527   (def-x86-opcode shll ((:imm1 :insert-nothing) (:anymem :insert-memory))
2528     #xd1 #o040 #x0)
2529   (def-x86-opcode shll ((:reg32 :insert-modrm-rm))
2530     #xd1 #o340 #x0)
2531   (def-x86-opcode shll ((:anymem :insert-memory))
2532     #xd1 #o040 #x0)
2533   (def-x86-opcode shll ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2534     #xc1 #o340 #x0)
2535   (def-x86-opcode shll ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2536     #xd3 #o340 #x0)
2537
2538   (def-x86-opcode shlw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2539     #xd1 #o340 #x0 #x66)
2540   (def-x86-opcode shlw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2541     #xd1 #o040 #x0 #x66)
2542   (def-x86-opcode shlw ((:reg16 :insert-modrm-rm))
2543     #xd1 #o340 #x0 #x66)
2544   (def-x86-opcode shlw ((:anymem :insert-memory))
2545     #xd1 #o040 #x0 #x66)
2546   (def-x86-opcode shlw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2547     #xc1 #o340 #x0 #x66)
2548   (def-x86-opcode shlw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2549     #xd3 #o340 #x0 #x66)
2550
2551   (def-x86-opcode shlb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2552     #xd0 #o340 #x0)
2553   (def-x86-opcode shlb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2554     #xd0 #o040 #x0)
2555   (def-x86-opcode shlb ((:reg8 :insert-modrm-rm))
2556     #xd0 #o340 #x0)
2557   (def-x86-opcode shlb ((:anymem :insert-memory))
2558     #xd0 #o040 #x0)
2559   (def-x86-opcode shlb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2560     #xc0 #o340 #x0)
2561   (def-x86-opcode shlb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2562     #xd2 #o340 #x0)
2563
2564   ;; shld
2565   (def-x86-opcode (shldq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2566     #x0fa4 #o300 #x48)
2567   (def-x86-opcode (shldq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2568     #x0fa4 #o000 #x48)
2569   (def-x86-opcode (shldq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2570     #x0fa5 #o300 #x48)
2571   (def-x86-opcode (shldq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2572     #x0fa5 #o000 #x48)
2573   (def-x86-opcode (shldq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2574     #x0fa5 #o300 #x48)
2575   (def-x86-opcode (shldq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2576     #x0fa5 #o000 #x48)
2577
2578   (def-x86-opcode shldl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2579     #x0fa4 #o300 #x0)
2580   (def-x86-opcode shldl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2581     #x0fa4 #o000 #x0)
2582   (def-x86-opcode shldl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2583     #x0fa5 #o300 #x0)
2584   (def-x86-opcode shldl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2585     #x0fa5 #o000 #x0)
2586   (def-x86-opcode shldl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2587     #x0fa5 #o300 #x0)
2588   (def-x86-opcode shldl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2589     #x0fa5 #o000 #x0)
2590
2591   (def-x86-opcode shldw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2592     #x0fa4 #o300 #x0 #x66)
2593   (def-x86-opcode shldw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2594     #x0fa4 #o000 #x0 #x66)
2595   (def-x86-opcode shldw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2596     #x0fa5 #o300 #x0 #x66)
2597   (def-x86-opcode shldw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2598     #x0fa5 #o000 #x0 #x66)
2599   (def-x86-opcode shldw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2600     #x0fa5 #o300 #x0 #x66)
2601   (def-x86-opcode shldw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2602     #x0fa5 #o000 #x0 #x66)
2603
2604   ;; shr
2605   (def-x86-opcode (shrq :cpu64) ((:imm1 :insert-nothing) (:reg64 :insert-modrm-rm))
2606     #xd1 #o350 #x48)
2607   (def-x86-opcode (shrq :cpu64) ((:imm1 :insert-nothing) (:anymem :insert-memory))
2608     #xd1 #o050 #x48)
2609   (def-x86-opcode (shrq :cpu64) ((:reg64 :insert-modrm-rm))
2610     #xd1 #o350 #x48)
2611   (def-x86-opcode (shrq :cpu64) ((:anymem :insert-memory))
2612     #xd1 #o050 #x48)
2613   (def-x86-opcode (shrq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-rm))
2614     #xc1 #o350 #x48)
2615   (def-x86-opcode (shrq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-rm))
2616     #xd3 #o350 #x48)
2617 
2618   (def-x86-opcode shrl ((:imm1 :insert-nothing) (:reg32 :insert-modrm-rm))
2619     #xd1 #o350 #x0)
2620   (def-x86-opcode shrl ((:imm1 :insert-nothing) (:anymem :insert-memory))
2621     #xd1 #o050 #x0)
2622   (def-x86-opcode shrl ((:reg32 :insert-modrm-rm))
2623     #xd1 #o350 #x0)
2624   (def-x86-opcode shrl ((:anymem :insert-memory))
2625     #xd1 #o050 #x0)
2626   (def-x86-opcode shrl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-rm))
2627     #xc1 #o350 #x0)
2628   (def-x86-opcode shrl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-rm))
2629     #xd3 #o350 #x0)
2630
2631   (def-x86-opcode shrw ((:imm1 :insert-nothing) (:reg16 :insert-modrm-rm))
2632     #xd1 #o350 #x0 #x66)
2633   (def-x86-opcode shrw ((:imm1 :insert-nothing) (:anymem :insert-memory))
2634     #xd1 #o050 #x0 #x66)
2635   (def-x86-opcode shrw ((:reg16 :insert-modrm-rm))
2636     #xd1 #o350 #x0 #x66)
2637   (def-x86-opcode shrw ((:anymem :insert-memory))
2638     #xd1 #o050 #x0 #x66)
2639   (def-x86-opcode shrw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-rm))
2640     #xc1 #o350 #x0 #x66)
2641   (def-x86-opcode shrw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-rm))
2642     #xd3 #o350 #x0 #x66)
2643
2644   (def-x86-opcode shrb ((:imm1 :insert-nothing) (:reg8 :insert-modrm-rm))
2645     #xd0 #o350 #x0)
2646   (def-x86-opcode shrb ((:imm1 :insert-nothing) (:anymem :insert-memory))
2647     #xd0 #o050 #x0)
2648   (def-x86-opcode shrb ((:reg8 :insert-modrm-rm))
2649     #xd0 #o350 #x0)
2650   (def-x86-opcode shrb ((:anymem :insert-memory))
2651     #xd0 #o050 #x0)
2652   (def-x86-opcode shrb ((:imm8 :insert-imm8) (:reg8 :insert-modrm-rm))
2653     #xc0 #o350 #x0)
2654   (def-x86-opcode shrb ((:shiftcount :insert-nothing) (:reg8 :insert-modrm-rm))
2655     #xd2 #o350 #x0)
2656
2657   ;; shrd
2658   (def-x86-opcode (shrdq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2659     #x0fac #o300 #x48)
2660   (def-x86-opcode (shrdq :cpu64) ((:imm8 :insert-imm8) (:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2661     #x0fac #o000 #x48)
2662   (def-x86-opcode (shrdq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2663     #x0fad #o300 #x48)
2664   (def-x86-opcode (shrdq :cpu64) ((:shiftcount :insert-nothing) (:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2665     #x0fad #o000 #x48)
2666   (def-x86-opcode (shrdq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2667     #x0fad #o300 #x48)
2668   (def-x86-opcode (shrdq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2669     #x0fad #o000 #x48)
2670
2671   (def-x86-opcode shrdl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2672     #x0fac #o300 #x0)
2673   (def-x86-opcode shrdl ((:imm8 :insert-imm8) (:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2674     #x0fac #o000 #x0)
2675   (def-x86-opcode shrdl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2676     #x0fad #o300 #x0)
2677   (def-x86-opcode shrdl ((:shiftcount :insert-nothing) (:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2678     #x0fad #o000 #x0)
2679   (def-x86-opcode shrdl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2680     #x0fad #o300 #x0)
2681   (def-x86-opcode shrdl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2682     #x0fad #o000 #x0)
2683
2684   (def-x86-opcode shrdw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2685     #x0fac #o300 #x0 #x66)
2686   (def-x86-opcode shrdw ((:imm8 :insert-imm8) (:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2687     #x0fac #o000 #x0 #x66)
2688   (def-x86-opcode shrdw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2689     #x0fad #o300 #x0 #x66)
2690   (def-x86-opcode shrdw ((:shiftcount :insert-nothing) (:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2691     #x0fad #o000 #x0 #x66)
2692   (def-x86-opcode shrdw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2693     #x0fad #o300 #x0 #x66)
2694   (def-x86-opcode shrdw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2695     #x0fad #o000 #x0 #x66)
2696
2697   ;; stc
2698   (def-x86-opcode stc ()
2699     #xf9 nil nil)
2700
2701   ;; std
2702   (def-x86-opcode std ()
2703     #xfd nil nil)
2704
2705   ;; sub
2706   (def-x86-opcode (subq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2707     #x29 #o300 #x48)
2708   (def-x86-opcode (subq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
2709     #x2b #o000 #x48)
2710   (def-x86-opcode (subq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2711     #x29 #x00 #x48)
2712   (def-x86-opcode (subq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
2713     #x83 #o350 #x48)
2714   (def-x86-opcode (subq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2715     #x2d nil #x48)
2716   (def-x86-opcode (subq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
2717     #x81 #o350 #x48)
2718   (def-x86-opcode (subq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2719     #x83 #o050 #x48)
2720   (def-x86-opcode (subq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2721     #x81 #o050 #x48)
2722
2723   (def-x86-opcode subl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2724     #x29 #o300 #x00)
2725   (def-x86-opcode subl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
2726     #x2b #o000 #x00)
2727   (def-x86-opcode subl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2728     #x29 #x00 #x00)
2729   (def-x86-opcode subl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
2730     #x83 #o350 #x00)
2731   (def-x86-opcode subl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2732     #x2d nil nil)
2733   (def-x86-opcode subl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
2734     #x81 #o350 #x00)
2735   (def-x86-opcode subl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2736     #x83 #o050 #x00)
2737   (def-x86-opcode subl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2738     #x81 #o050 #x00)
2739
2740   (def-x86-opcode subw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2741     #x29 #o300 #x00 #x66)
2742   (def-x86-opcode subw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
2743     #x2b #o000 #x00 #x66)
2744   (def-x86-opcode subw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2745     #x29 #x00 #x00 #x66)
2746   (def-x86-opcode subw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
2747     #x83 #o350 #x00 #x66)
2748   (def-x86-opcode subw ((:imm16 :insert-imm16) (:acc :insert-nothing))
2749     #x2d nil nil #x66)
2750   (def-x86-opcode subw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
2751     #x81 #o350 #x00 #x66)
2752   (def-x86-opcode subw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2753     #x83 #o050 #x00 #x66)
2754   (def-x86-opcode subw ((:imm16 :insert-imm16) (:anymem :insert-memory))
2755     #x81 #o050 #x00 #x66)
2756
2757   (def-x86-opcode subb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2758     #x28 #o300 #x00)
2759   (def-x86-opcode subb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2760     #x2a #o000 #x00)
2761   (def-x86-opcode subb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2762     #x2a #x00 #x00)
2763   (def-x86-opcode subb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
2764     #x2c nil nil)
2765   (def-x86-opcode subb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2766     #x80 #o350 #x00)
2767   (def-x86-opcode subb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2768     #x80 #o350 #x00)
2769   (def-x86-opcode subb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2770     #x80 #o050 #x00)
2771
2772   ;; syscall
2773   (def-x86-opcode (syscall :cpu64) ()
2774     #x0f0f nil nil)
2775
2776   ;; test
2777   (def-x86-opcode (testq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2778     #x85 #o300 #x48)
2779   (def-x86-opcode (testq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2780     #x85 #o000 #x48)
2781   (def-x86-opcode (testq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
2782     #x87 #o000 #x48)
2783   (def-x86-opcode (testq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2784     #xa9 nil #x48)
2785   (def-x86-opcode (testq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
2786     #xf7 #o300 #x48)
2787   (def-x86-opcode (testq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2788     #xf7 #o000 #x48)
2789
2790   (def-x86-opcode testl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2791     #x85 #o300 #x00)
2792   (def-x86-opcode testl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2793     #x85 #o000 #x00)
2794   (def-x86-opcode testl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
2795     #x87 #o000 #x00)
2796   (def-x86-opcode testl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2797     #xa9 nil #x00)
2798   (def-x86-opcode testl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
2799     #xf7 #o300 #x00)
2800   (def-x86-opcode testl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2801     #xf7 #o000 #x00)
2802
2803
2804   (def-x86-opcode testw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2805     #x85 #o300 #x00 #x66)
2806   (def-x86-opcode testw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2807     #x85 #o000 #x00 #x66)
2808   (def-x86-opcode testw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
2809     #x87 #o000 #x00 #x66)
2810   (def-x86-opcode testw ((:imm16 :insert-imm16) (:acc :insert-nothing))
2811     #xa9 nil #x00 #x66)
2812   (def-x86-opcode testw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
2813     #xf7 #o300 #x00 #x66)
2814   (def-x86-opcode testw ((:imm16 :insert-imm16) (:anymem :insert-memory))
2815     #xf7 #o000 #x00 #x66)
2816
2817
2818   (def-x86-opcode testb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2819     #x84 #o300 #x00)
2820   (def-x86-opcode testb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2821     #x84 #o000 #x00)
2822   (def-x86-opcode testb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2823     #x86 #o000 #x00)
2824   (def-x86-opcode testb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
2825     #xa8 nil #x00)
2826   (def-x86-opcode testb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2827     #xf6 #o300 #x00)
2828   (def-x86-opcode testb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2829     #xf6 #o000 #x00)
2830
2831   ;; ud2a (not to be confused with all of the other undefined/accidental
2832   ;; instructions) is "officially undefined".
2833   (def-x86-opcode ud2a ()
2834     #x0f0b nil nil)
2835
2836   (def-x86-opcode ud2b ()
2837     #x0fb9 nil nil)
2838
2839   ;; xadd
2840   (def-x86-opcode (xaddq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2841     #x0fc1 #o300 #x48)
2842   (def-x86-opcode (xaddq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2843     #x0fc1 #o000 #x48)
2844
2845   (def-x86-opcode xaddl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2846     #x0fc1 #o300 #x00)
2847   (def-x86-opcode xaddl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2848     #x0fc1 #o000 #x00)
2849
2850   (def-x86-opcode xaddw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2851     #x0fc1 #o300 #x00 #x66)
2852   (def-x86-opcode xaddw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2853     #x0fc1 #o000 #x00 #x66)
2854
2855   (def-x86-opcode xaddb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2856     #x0fc0 #o300 #x00)
2857   (def-x86-opcode xaddb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2858     #x0fc0 #o000 #x00)
2859
2860   ;; xchg
2861   ;; Allegedly, using the opcode #x9x to implement "(xchg (% eax) (% eax))"
2862   ;; doesn't zero-extend eax to rax on x86-64.  (So don't special-case
2863   ;; :acc as source or destination, and use #x86 and a modrm byte in all cases.)
2864   (def-x86-opcode (xchgq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2865     #x87 #o300 #x48)
2866   (def-x86-opcode (xchgq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2867     #x87 #o000 #x48)
2868   (def-x86-opcode (xchgq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
2869     #x89 #o000 #x48)
2870
2871   (def-x86-opcode xchgl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2872     #x87 #o300 #x00)
2873   (def-x86-opcode xchgl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2874     #x87 #o000 #x00)
2875   (def-x86-opcode xchgl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
2876     #x89 #o000 #x00)
2877
2878   (def-x86-opcode xchgw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2879     #x87 #o300 #x00 #x66)
2880   (def-x86-opcode xchgw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2881     #x87 #o000 #x00 #x66)
2882   (def-x86-opcode xchgw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
2883     #x89 #o000 #x00 #x66)
2884
2885   (def-x86-opcode xchgb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2886     #x86 #o300 #x00)
2887   (def-x86-opcode xchgb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2888     #x86 #o000 #x00)
2889   (def-x86-opcode xchgb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2890     #x88 #o000 #x00)
2891
2892   ;; xlat
2893
2894   (def-x86-opcode xlatb ()
2895     #xd7 nil nil)
2896
2897   ;; xor
2898   (def-x86-opcode (xorq :cpu64) ((:reg64 :insert-modrm-reg) (:reg64 :insert-modrm-rm))
2899     #x31 #o300 #x48)
2900   (def-x86-opcode (xorq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
2901     #x33 #o000 #x48)
2902   (def-x86-opcode (xorq :cpu64) ((:reg64 :insert-modrm-reg) (:anymem :insert-memory))
2903     #x31 #x00 #x48)
2904   (def-x86-opcode (xorq :cpu64) ((:imm8s :insert-imm8s) (:reg64 :insert-modrm-rm))
2905     #x83 #o360 #x48)
2906   (def-x86-opcode (xorq :cpu64) ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2907     #x35 nil #x48)
2908   (def-x86-opcode (xorq :cpu64) ((:imm32s :insert-imm32s) (:reg64 :insert-modrm-rm))
2909     #x81 #o360 #x48)
2910   (def-x86-opcode (xorq :cpu64) ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2911     #x83 #o060 #x48)
2912   (def-x86-opcode (xorq :cpu64) ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2913     #x81 #o060 #x48)
2914
2915   (def-x86-opcode xorl ((:reg32 :insert-modrm-reg) (:reg32 :insert-modrm-rm))
2916     #x31 #o300 #x00)
2917   (def-x86-opcode xorl ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
2918     #x33 #o000 #x00)
2919   (def-x86-opcode xorl ((:reg32 :insert-modrm-reg) (:anymem :insert-memory))
2920     #x31 #x00 #x00)
2921   (def-x86-opcode xorl ((:imm8s :insert-imm8s) (:reg32 :insert-modrm-rm))
2922     #x83 #o360 #x00)
2923   (def-x86-opcode xorl ((:imm32s :insert-imm32s) (:acc :insert-nothing))
2924     #x35 nil nil)
2925   (def-x86-opcode xorl ((:imm32s :insert-imm32s) (:reg32 :insert-modrm-rm))
2926     #x81 #o360 #x00)
2927   (def-x86-opcode xorl ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2928     #x83 #o060 #x00)
2929   (def-x86-opcode xorl ((:imm32s :insert-imm32s) (:anymem :insert-memory))
2930     #x81 #o060 #x00)
2931
2932   (def-x86-opcode xorw ((:reg16 :insert-modrm-reg) (:reg16 :insert-modrm-rm))
2933     #x31 #o300 #x00 #x66)
2934   (def-x86-opcode xorw ((:anymem :insert-memory) (:reg16 :insert-modrm-reg))
2935     #x33 #o000 #x00 #x66)
2936   (def-x86-opcode xorw ((:reg16 :insert-modrm-reg) (:anymem :insert-memory))
2937     #x31 #x00 #x00 #x66)
2938   (def-x86-opcode xorw ((:imm8s :insert-imm8s) (:reg16 :insert-modrm-rm))
2939     #x83 #o360 #x00 #x66)
2940   (def-x86-opcode xorw ((:imm16 :insert-imm16) (:acc :insert-nothing))
2941     #x35 nil nil #x66)
2942   (def-x86-opcode xorw ((:imm16 :insert-imm16) (:reg16 :insert-modrm-rm))
2943     #x81 #o360 #x00 #x66)
2944   (def-x86-opcode xorw ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2945     #x83 #o060 #x00 #x66)
2946   (def-x86-opcode xorw ((:imm16 :insert-imm16) (:anymem :insert-memory))
2947     #x81 #o060 #x00 #x66)
2948
2949   (def-x86-opcode xorb ((:reg8 :insert-modrm-reg) (:reg8 :insert-modrm-rm))
2950     #x30 #o300 #x00)
2951   (def-x86-opcode xorb ((:anymem :insert-memory) (:reg8 :insert-modrm-reg))
2952     #x32 #o000 #x00)
2953   (def-x86-opcode xorb ((:reg8 :insert-modrm-reg) (:anymem :insert-memory))
2954     #x30 #x00 #x00)
2955   (def-x86-opcode xorb ((:imm8s :insert-imm8s) (:acc :insert-nothing))
2956     #x34 nil nil)
2957   (def-x86-opcode xorb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2958     #x80 #o360 #x00)
2959   (def-x86-opcode xorb ((:imm8s :insert-imm8s) (:reg8 :insert-modrm-rm))
2960     #x80 #o360 #x00)
2961   (def-x86-opcode xorb ((:imm8s :insert-imm8s) (:anymem :insert-memory))
2962     #x80 #o060 #x00)
2963
2964   ;; fxsave
2965   (def-x86-opcode fxsaveq ((:anymem :insert-memory))
2966     #x0fae #o000 0)
2967
2968   ;; fxrstor
2969   (def-x86-opcode fxrstor ((:anymem :insert-memory))
2970     #x0fae #o010 0)
2971
2972   ;; clflush
2973   (def-x86-opcode clflush ((:anymem :insert-memory))
2974     #x0fae #o070 0)
2975
2976   ;; lfence
2977   (def-x86-opcode lfence ()
2978     #x0fae #xe8 nil)
2979
2980   ;; mfence
2981   (def-x86-opcode mfence ()
2982     #x0fae #xf0 nil)
2983   
2984   ;; pause
2985   (def-x86-opcode pause ()
2986     #xf390 nil nil)
2987
2988   ;; I don't want to have to define all mmx/sse/sse2 instructions at the
2989   ;; moment, but it wouldn't hurt to define those that the lisp is
2990   ;; likely to use.
2991
2992   ;; Useful mmx/sse2 instructions, other than movd/movq:
2993
2994   ;; emms
2995   (def-x86-opcode emms ()
2996     #x0f77 nil nil)
2997
2998   ;; addsd
2999   (def-x86-opcode addsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3000     #x0f58 #o000 #x0 #xf2)
3001   (def-x86-opcode addsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3002     #x0f58 #o300 #x0 #xf2)
3003   
3004   ;; addss
3005   (def-x86-opcode addss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3006     #x0f58 #o000 #x0 #xf3)
3007   (def-x86-opcode addss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3008     #x0f58 #o300 #x0 #xf3)
3009
3010   ;; subsd
3011   (def-x86-opcode subsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3012     #x0f5c #o000 #x0 #xf2)
3013   (def-x86-opcode subsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3014     #x0f5c #o300 #x0 #xf2)
3015
3016   ;; subss
3017   (def-x86-opcode subss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3018     #x0f5c #o000 #x0 #xf3)
3019   (def-x86-opcode subss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3020     #x0f5c #o300 #x0 #xf3)
3021
3022   ;; movapd
3023   (def-x86-opcode movapd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3024     #x0f28 #o300 #x0 #x66)
3025   (def-x86-opcode movapd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3026     #x0f28 #o000 #x0 #x66)
3027   (def-x86-opcode movapd ((:regxmm :insert-xmm-reg) (:anymem :insert-memory))
3028     #x0f29 #o000 #x0 #x66)
3029   
3030   ;; mulsd
3031   (def-x86-opcode mulsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3032     #x0f59 #o000 #x0 #xf2)
3033   (def-x86-opcode mulsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3034     #x0f59 #o300 #x0 #xf2)
3035
3036   ;; mulss
3037   (def-x86-opcode mulss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3038     #x0f59 #o000 #x0 #xf3)
3039   (def-x86-opcode mulss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3040     #x0f59 #o300 #x0 #xf3)
3041
3042   ;; divsd
3043   (def-x86-opcode divsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3044     #x0f5e #o000 #x0 #xf2)
3045   (def-x86-opcode divsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3046     #x0f5e #o300 #x0 #xf2)
3047
3048   ;; divss
3049   (def-x86-opcode divss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3050     #x0f5e #o000 #x0 #xf3)
3051   (def-x86-opcode divss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3052     #x0f5e #o300 #x0 #xf3)
3053
3054
3055   ;; sqrtsd
3056   (def-x86-opcode sqrtsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3057     #x0f51 #o000 #x0 #xf2)
3058   (def-x86-opcode sqrtsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3059     #x0f51 #o300 #x0 #xf2)
3060
3061   ;; sqrtss
3062   (def-x86-opcode sqrtss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3063     #x0f51 #o000 #x0 #xf3)
3064   (def-x86-opcode sqrtss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3065     #x0f51 #o300 #x0 #xf3)
3066   
3067   ;; comisd
3068   (def-x86-opcode comisd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3069     #x0f2f #o000 #x0 #x66)
3070   (def-x86-opcode comisd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3071     #x0f2f #o300 #x0 #x66)
3072
3073   ;; ucomisd
3074   (def-x86-opcode ucomisd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3075     #x0f2e #o000 #x0 #x66)
3076   (def-x86-opcode comisd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3077     #x0f2e #o300 #x0 u#x66)
3078
3079   
3080   ;; comiss
3081   (def-x86-opcode comiss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3082     #x0f2f #o000 #x0)
3083   (def-x86-opcode comiss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3084     #x0f2f #o300 #x0)
3085
3086   ;; ucomiss
3087   (def-x86-opcode ucomiss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3088     #x0f2e #o000 #x0)
3089   (def-x86-opcode ucomiss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3090     #x0f2e #o300 #x0)
3091
3092   ;; movsd
3093   (def-x86-opcode movsd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3094     #x0f10 #o300 #x0 #xf2)
3095   (def-x86-opcode movsd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3096     #x0f10 #o300 #x0 #xf2)
3097   (def-x86-opcode movsd ((:regxmm :insert-xmm-reg) (:anymem :insert-memory))
3098     #x0f11 #o000 #x0 #xf2)
3099
3100   
3101
3102   ;; movss
3103   (def-x86-opcode movss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3104     #x0f10 #o300 #x0 #xf3)
3105   (def-x86-opcode movss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3106     #x0f10 #o300 #x0 #xf3)
3107   (def-x86-opcode movss ((:regxmm :insert-xmm-reg) (:anymem :insert-memory))
3108     #x0f11 #o000 #x0 #xf3)
3109
3110   
3111;;; cvtsd2si.  This does rounding (as opposed to truncation).
3112   (def-x86-opcode (cvtsd2siq :cpu64) ((:regxmm :insert-xmm-rm) (:reg64 :insert-modrm-reg))
3113     #x0f2d #o300 #x48 #xf2)
3114   (def-x86-opcode (cvtsd2siq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
3115     #x0f2d #o000 #x48 #xf2)
3116   (def-x86-opcode cvtsd2sil ((:regxmm :insert-xmm-rm) (:reg32 :insert-modrm-reg))
3117     #x0f2d #o300 #x00 #xf2)
3118   (def-x86-opcode cvtsd2sil ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
3119     #x0f2d #o000 #x00 #xf2)
3120
3121;;; cvtss2si.  This does rounding (as opposed to truncation).
3122   (def-x86-opcode (cvtss2siq :cpu64) ((:regxmm :insert-xmm-rm) (:reg64 :insert-modrm-reg))
3123     #x0f2d #o300 #x48 #xf3)
3124   (def-x86-opcode (cvtss2siq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
3125     #x0f2d #o000 #x48 #xf3)
3126   (def-x86-opcode cvtss2sil ((:regxmm :insert-xmm-rm) (:reg32 :insert-modrm-reg))
3127     #x0f2d #o300 #x00 #xf3)
3128   (def-x86-opcode cvtss2sil ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
3129     #x0f2d #o000 #x00 #xf3)
3130   
3131;;; cvttsd2si.  This does truncation (as opposed to rounding).
3132   (def-x86-opcode (cvttsd2siq :cpu64) ((:regxmm :insert-xmm-rm) (:reg64 :insert-modrm-reg))
3133     #x0f2c #o300 #x48 #xf2)
3134   (def-x86-opcode (cvttsd2siq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
3135     #x0f2c #o000 #x48 #xf2)
3136   (def-x86-opcode cvttsd2sil ((:regxmm :insert-xmm-rm) (:reg32 :insert-modrm-reg))
3137     #x0f2c #o300 #x00 #xf2)
3138   (def-x86-opcode cvtsd2sil ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
3139     #x0f2c #o000 #x00 #xf2)
3140
3141;;; cvtss2si.  This does rounding (as opposed to truncation).
3142   (def-x86-opcode (cvttss2siq :cpu64) ((:regxmm :insert-xmm-rm) (:reg64 :insert-modrm-reg))
3143     #x0f2c #o300 #x48 #xf3)
3144   (def-x86-opcode (cvttss2siq :cpu64) ((:anymem :insert-memory) (:reg64 :insert-modrm-reg))
3145     #x0f2c #o000 #x48 #xf3)
3146   (def-x86-opcode cvttss2sil ((:regxmm :insert-xmm-rm) (:reg32 :insert-modrm-reg))
3147     #x0f2d #o300 #x00 #xf3)
3148   (def-x86-opcode cvttss2sil ((:anymem :insert-memory) (:reg32 :insert-modrm-reg))
3149     #x0f2c #o000 #x00 #xf3)
3150
3151   ;; cvtsi2sd
3152   (def-x86-opcode (cvtsi2sdq :cpu64) ((:reg64 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3153     #x0f2a #o300 #x48 #xf2)
3154   (def-x86-opcode (cvtsi2sdq :cpu64) ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3155     #x0f2a #o000 #x48 #xf2)
3156   (def-x86-opcode cvtsi2sdl ((:reg32 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3157     #x0f2a #o300 #x00 #xf2)
3158   (def-x86-opcode cvtsi2sdl ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3159     #x0f2a #o000 #x00 #xf2)
3160   
3161   ;; cvtsd2ss
3162   (def-x86-opcode cvtsd2ss ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3163     #x0f5a #o300 #x0 #xf2)
3164   (def-x86-opcode cvtsd2ss ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3165     #x0f5a #o000 #x0 #xf2)
3166
3167   ;; cvtsi2sd
3168   (def-x86-opcode (cvtsi2sdq :cpu64) ((:reg64 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3169     #x0f2a #o300 #x48 #xf2)
3170   (def-x86-opcode (cvtsi2sdq :cpu64) ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3171     #x0f2a #o000 #x48 #xf2)
3172   (def-x86-opcode cvtsi2sdl ((:reg32 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3173     #x0f2a #o300 #x00 #xf2)
3174   (def-x86-opcode cvtsi2sdl ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3175     #x0f2a #o000 #x00 #xf2)
3176
3177   ;; cvtsi2ss
3178   (def-x86-opcode (cvtsi2ssq :cpu64) ((:reg64 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3179     #x0f2a #o300 #x48 #xf3)
3180   (def-x86-opcode (cvtsi2ssq :cpu64) ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3181     #x0f2a #o000 #x48 #xf3)
3182   (def-x86-opcode cvtsi2ssl ((:reg32 :insert-modrm-rm) (:regxmm :insert-xmm-reg))
3183     #x0f2a #o300 #x00 #xf3)
3184   (def-x86-opcode cvtsi2ssl ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3185     #x0f2a #o000 #x00 #xf3)
3186
3187;;; cvtss2sd
3188   (def-x86-opcode cvtss2sd ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3189     #x0f5a #o300 #x0 #xf3)
3190   (def-x86-opcode cvtss2sd ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3191     #x0f5a #o000 #x0 #xf3)
3192   
3193   ;; pand
3194   (def-x86-opcode pand ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3195     #x0fdb #o300 #x0)
3196   (def-x86-opcode pand ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3197     #x0fdb #o000 #x0)
3198   (def-x86-opcode pand ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3199     #x0fef #o300 #x0 #x66)
3200   (def-x86-opcode pand ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3201     #x0fdb #o000 #x0 #x66)
3202   
3203   ;; pandn
3204   (def-x86-opcode pandn ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3205     #x0fdf #o300 #x0)
3206   (def-x86-opcode pandn ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3207     #x0fdf #o000 #x0)
3208   (def-x86-opcode pandn ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3209     #x0fdf #o300 #x0 #x66)
3210   (def-x86-opcode pandn ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3211     #x0fdf #o000 #x0 #x66)
3212
3213   ;; por
3214   (def-x86-opcode por ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3215     #x0feb #o300 #x0)
3216   (def-x86-opcode por ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3217     #x0feb #o000 #x0)
3218   (def-x86-opcode por ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3219     #x0feb #o300 #x0 #x66)
3220   (def-x86-opcode por ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3221     #x0feb #o000 #x0 #x66)
3222
3223   ;; pxor
3224   (def-x86-opcode pxor ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3225     #x0fef #o300 #x0)
3226   (def-x86-opcode pxor ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3227     #x0fef #o000 #x0)
3228   (def-x86-opcode pxor ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3229     #x0fef #o300 #x0 #x66)
3230   (def-x86-opcode pxor ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3231     #x0fef #o000 #x0 #x66)
3232
3233   ;; psllq
3234   (def-x86-opcode psllq ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3235     #x0ff3 #o300 #x0)
3236   (def-x86-opcode psllq ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3237     #x0ff3 #o000 #x0)
3238   (def-x86-opcode psllq ((:imm8 :insert-imm8) (:regmmx :insert-mmx-rm))
3239     #x0f73 #o360 #o0)
3240   (def-x86-opcode psllq ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3241     #x0ff3 #o300 #x0 #x66)
3242   (def-x86-opcode psllq ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3243     #x0ff3 #o000 #x0 #x66)
3244   (def-x86-opcode psllq ((:imm8 :insert-imm8) (:regxmm :insert-xmm-rm))
3245     #x0f73 #o360 #o0 #x66)
3246
3247   ;; psllw
3248   
3249   ;; pslld
3250
3251   ;; pslldq
3252   (def-x86-opcode pslldq ((:imm8 :insert-imm8) (:regxmm :insert-xmm-rm))
3253     #x0f73 #o370 #x0 #x66)
3254   
3255   ;; psrlq
3256   (def-x86-opcode psrlq ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3257     #x0fd3 #o300 #x0)
3258   (def-x86-opcode psrlq ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3259     #x0fd3 #o000 #x0)
3260   (def-x86-opcode psrlq ((:imm8 :insert-imm8) (:regmmx :insert-mmx-rm))
3261     #x0f73 #o320 #o0)
3262   (def-x86-opcode psrlq ((:regxmm :insert-modrm-rm) (:regxmm :insert-modrm-reg))
3263     #x0fd3 #o300 #x0 #x66)
3264   (def-x86-opcode psrlq ((:anymem :insert-memory) (:regxmm :insert-modrm-reg))
3265     #x0fd3 #o000 #x0 #x66)
3266   (def-x86-opcode psrlq ((:imm8 :insert-imm8) (:regxmm :insert-xmm-rm))
3267     #x0f73 #o320 #o0 #x66)
3268
3269   ;; psrld
3270
3271   ;; psrldq
3272   (def-x86-opcode psrldq ((:imm8 :insert-imm8) (:regxmm :insert-xmm-rm))
3273     #x0f73 #o330 #x0 #x66)
3274   
3275   ;; psrlw
3276
3277   ;; pmuludq
3278   (def-x86-opcode pmuludq ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3279     #x0ff4 #o300 #x0)
3280   (def-x86-opcode pmuludq ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3281     #x0ff4 #o000 #x0)
3282   (def-x86-opcode pmuludq ((:regxmm :insert-xmm-rm) (:regxmm :insert-xmm-reg))
3283     #x0ff4 #o300 #x0 #x66)
3284   (def-x86-opcode pmuludq ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3285     #x0ff4 #o000 #x0 #x66)
3286
3287   ;; paddq
3288   (def-x86-opcode paddq ((:regmmx :insert-mmx-rm) (:regmmx :insert-mmx-reg))
3289     #x0fd4 #o300 #x0)
3290   (def-x86-opcode paddq ((:anymem :insert-memory) (:regmmx :insert-mmx-reg))
3291     #x0fd4 #o000 #x0)
3292   (def-x86-opcode paddq ((:regxmm :insert-xmm-reg) (:regxmm :insert-xmm-reg))
3293     #x0fd4 #o300 #x0 #x66)
3294   (def-x86-opcode paddq ((:anymem :insert-memory) (:regxmm :insert-xmm-reg))
3295     #x0fd4 #o000 #x0 #x66)
3296
3297;;; End of list of useful mmx instructions
3298   (def-x86-opcode ldmxcsr ((:anymem :insert-memory))
3299     #x0fae #o020 nil)
3300
3301   (def-x86-opcode stmxcsr ((:anymem :insert-memory))
3302     #x0fae #o030 nil)
3303
3304   ;; UUOs.  Expect lots more, some of which may take pseudo-operands.
3305   (def-x86-opcode uuo-error-slot-unbound ((:reg :insert-opcode-reg4)
3306                                           (:reg :insert-reg4-pseudo-rm-high)
3307                                           (:reg :insert-reg4-pseudo-rm-low))
3308     #xcd70 0 nil)
3309
3310;;; DON'T use #xcd8x: doing so will make Mach angry and confused.
3311   
3312   (def-x86-opcode uuo-error-unbound ((:reg :insert-opcode-reg4))
3313     #xcd90 nil 0)
3314
3315   (def-x86-opcode uuo-error-udf ((:reg :insert-opcode-reg4))
3316     #xcda0 nil 0)
3317   
3318   (def-x86-opcode uuo-error-reg-not-type ((:reg :insert-opcode-reg4) (:imm8 :insert-imm8))
3319     #xcdb0 nil 0)
3320   
3321   (def-x86-opcode uuo-error-too-few-args ()
3322     #xcdc0 nil nil)
3323   (def-x86-opcode uuo-error-too-many-args ()
3324     #xcdc1 nil nil)
3325   (def-x86-opcode uuo-error-wrong-number-of-args ()
3326     #xcdc2 nil nil)
3327   (def-x86-opcode uuo-error-array-rank ((:reg :insert-reg4-pseudo-rm-high)
3328                                         (:reg :insert-reg4-pseudo-rm-low))
3329     #xcdc3 0 nil)
3330
3331   (def-x86-opcode uuo-gc-trap ()
3332     #xcdc4 nil nil)
3333   (def-x86-opcode uuo-alloc ()
3334     #xcdc5 nil nil)
3335   (def-x86-opcode uuo-error-not-callable ()
3336     #xcdc6 nil nil)
3337   (def-x86-opcode uuo-error-udf-call ()
3338     #xcdc7 nil nil)
3339
3340   (def-x86-opcode uuo-error-vector-bounds ((:reg :insert-reg4-pseudo-rm-high) (:reg :insert-reg4-pseudo-rm-low))
3341     #xcdc8 0 nil)
3342
3343   (def-x86-opcode uuo-error-call-macro-or-special-operator ()
3344     #xcdc9 nil nil)
3345
3346   (def-x86-opcode uuo-error-debug-trap ()
3347     #xcdca nil nil)
3348
3349   (def-x86-opcode uuo-error-array-bounds ((:reg :insert-reg4-pseudo-rm-high) (:reg :insert-reg4-pseudo-rm-low))
3350     #xcdcb 0 nil)
3351
3352   (def-x86-opcode uuo-error-eep-unresolved ((:reg :insert-reg4-pseudo-rm-high)
3353                                             (:reg :insert-reg4-pseudo-rm-low))
3354     #xcdcc 0 nil)
3355
3356   (def-x86-opcode uuo-error-debug-trap-with-string ()
3357     #xcdcd nil nil)
3358   
3359   (def-x86-opcode uuo-error-reg-not-tag ((:reg :insert-opcode-reg4) (:imm8 :insert-imm8))
3360     #xcdd0 nil 0)
3361   (def-x86-opcode uuo-error-reg-not-list ((:reg :insert-opcode-reg4))
3362     #xcde0 nil 0)
3363   (def-x86-opcode uuo-error-reg-not-fixnum ((:reg :insert-opcode-reg4))
3364     #xcdf0 nil 0)
3365
3366   ))
3367
3368(dotimes (i (length *x86-opcode-templates*))
3369  (setf (x86-opcode-template-ordinal (svref *x86-opcode-templates* i)) i))
3370
3371
3372(defparameter *x86-opcode-template-lists*
3373  (make-hash-table :test #'equalp))
3374
3375
3376(defun initialize-x86-opcode-templates ()
3377  (flet ((setup-templates-hash (hash templates)
3378           (clrhash hash)
3379           (do* ((i (1- (length templates)) (1- i)))
3380                ((< i 0) hash)
3381             (declare (fixnum i))
3382             (let* ((template (svref templates i))
3383                    (name (x86-opcode-template-mnemonic template)))
3384               (push template (gethash name hash))))))
3385    (setup-templates-hash *x86-opcode-template-lists* *x86-opcode-templates*)
3386    (when (fboundp 'ccl::fixup-x86-vinsn-templates)
3387      (ccl::fixup-x86-vinsn-templates
3388       (ccl::backend-p2-vinsn-templates ccl::*target-backend*)
3389       *x86-opcode-template-lists*))
3390    t))
3391
3392(defvar *x8632-registers* (make-hash-table :test #'equalp))
3393(defvar *x8664-registers* (make-hash-table :test #'equalp))
3394(defvar *x86-registers* nil)
3395
3396(defparameter *x86-operand-insert-functions*
3397  #(insert-nothing
3398    insert-modrm-reg
3399    insert-modrm-rm
3400    insert-memory
3401    insert-opcode-reg
3402    insert-opcode-reg4
3403    insert-cc
3404    insert-label
3405    insert-imm8-for-int
3406    insert-extra
3407    insert-imm8
3408    insert-imm8s
3409    insert-imm16
3410    insert-imm32s
3411    insert-imm32
3412    insert-imm64
3413    insert-mmx-reg
3414    insert-mmx-rm
3415    insert-xmm-reg
3416    insert-xmm-rm
3417    insert-reg4-pseudo-rm-high
3418    insert-reg4-pseudo-rm-low
3419    insert-self
3420))
3421
3422(initialize-x86-opcode-templates)
3423
3424;;; 386 register table.
3425
3426(eval-when (:compile-toplevel :load-toplevel :execute)
3427
3428(defconstant +REGNAM-AL+ 1) ; Entry in i386-regtab.
3429(defconstant +REGNAM-AX+ 25)
3430(defconstant +REGNAM-EAX+ 41)
3431
3432(defvar *x86-regtab*
3433  (vector
3434   ;; Make %st first as we test for it.
3435   (make-reg-entry :reg-name "st"
3436                   :reg-type (encode-operand-type :FloatReg :floatacc)
3437                   :reg-flags 0
3438                   :reg-num 0 )
3439   ;; 8 bit regs
3440   (make-reg-entry :reg-name "al"
3441                   :reg-type (encode-operand-type :Reg8 :Acc)
3442                   :reg-flags 0
3443                   :reg-num 0 )
3444   (make-reg-entry :reg-name "cl"
3445                   :reg-type (encode-operand-type :Reg8 :ShiftCount)
3446                   :reg-flags 0
3447                   :reg-num 1)
3448   (make-reg-entry :reg-name "dl"
3449                   :reg-type (encode-operand-type :Reg8)
3450                   :reg-flags 0
3451                   :reg-num 2)
3452   (make-reg-entry :reg-name "bl"
3453                   :reg-type (encode-operand-type :Reg8)
3454                   :reg-flags 0
3455                   :reg-num 3)
3456   (make-reg-entry :reg-name "ah"
3457                   :reg-type (encode-operand-type :Reg8)
3458                   :reg-flags 0
3459                   :reg-num 4)
3460   (make-reg-entry :reg-name "ch"
3461                   :reg-type (encode-operand-type :Reg8)
3462                   :reg-flags 0
3463                   :reg-num 5)
3464   (make-reg-entry :reg-name "dh"
3465                   :reg-type (encode-operand-type :Reg8)
3466                   :reg-flags 0
3467                   :reg-num 6)
3468   (make-reg-entry :reg-name "bh"
3469                   :reg-type (encode-operand-type :Reg8)
3470                   :reg-flags 0
3471                   :reg-num 7)
3472   (make-reg-entry :reg-name "axl"
3473                   :reg-type (encode-operand-type :Reg8 :Acc)
3474                   :reg-flags +RegRex64+
3475                   :reg-num 0 ) ; Must be in the "al + 8" slot.
3476   (make-reg-entry :reg-name "cxl"
3477                   :reg-type (encode-operand-type :Reg8)
3478                   :reg-flags +RegRex64+
3479                   :reg-num 1)
3480   (make-reg-entry :reg-name "dxl"
3481                   :reg-type (encode-operand-type :Reg8)
3482                   :reg-flags +RegRex64+
3483                   :reg-num 2)
3484   (make-reg-entry :reg-name "bxl"
3485                   :reg-type (encode-operand-type :Reg8)
3486                   :reg-flags +RegRex64+
3487                   :reg-num 3)
3488   (make-reg-entry :reg-name "spl"
3489                   :reg-type (encode-operand-type :Reg8)
3490                   :reg-flags +RegRex64+
3491                   :reg-num 4)
3492   (make-reg-entry :reg-name "bpl"
3493                   :reg-type (encode-operand-type :Reg8)
3494                   :reg-flags +RegRex64+
3495                   :reg-num 5)
3496   (make-reg-entry :reg-name "sil"
3497                   :reg-type (encode-operand-type :Reg8)
3498                   :reg-flags +RegRex64+
3499                   :reg-num 6)
3500   (make-reg-entry :reg-name "dil"
3501                   :reg-type (encode-operand-type :Reg8)
3502                   :reg-flags +RegRex64+
3503                   :reg-num 7)
3504   (make-reg-entry :reg-name "r8b"
3505                   :reg-type (encode-operand-type :Reg8)
3506                   :reg-flags (logior +RegRex64+ +RegRex+)
3507                   :reg-num 0 )
3508   (make-reg-entry :reg-name "r9b"
3509                   :reg-type (encode-operand-type :Reg8)
3510                   :reg-flags (logior +RegRex64+ +RegRex+)
3511                   :reg-num 1)
3512   (make-reg-entry :reg-name "r10b"
3513                   :reg-type (encode-operand-type :Reg8)
3514                   :reg-flags (logior +RegRex64+ +RegRex+)
3515                   :reg-num 2)
3516   (make-reg-entry :reg-name "r11b"
3517                   :reg-type (encode-operand-type :Reg8)
3518                   :reg-flags (logior +RegRex64+ +RegRex+)
3519                   :reg-num 3)
3520   (make-reg-entry :reg-name "r12b"
3521                   :reg-type (encode-operand-type :Reg8)
3522                   :reg-flags (logior +RegRex64+ +RegRex+)
3523                   :reg-num 4)
3524   (make-reg-entry :reg-name "r13b"
3525                   :reg-type (encode-operand-type :Reg8)
3526                   :reg-flags (logior +RegRex64+ +RegRex+)
3527                   :reg-num 5)
3528   (make-reg-entry :reg-name "r14b"
3529                   :reg-type (encode-operand-type :Reg8)
3530                   :reg-flags (logior +RegRex64+ +RegRex+)
3531                   :reg-num 6)
3532   (make-reg-entry :reg-name "r15b"
3533                   :reg-type (encode-operand-type :Reg8)
3534                   :reg-flags (logior +RegRex64+ +RegRex+)
3535                   :reg-num 7)
3536   ;; 16 bit regs
3537   (make-reg-entry :reg-name "ax"
3538                   :reg-type (encode-operand-type :Reg16 :Acc)
3539                   :reg-flags 0
3540                   :reg-num 0 )
3541   (make-reg-entry :reg-name "cx"
3542                   :reg-type (encode-operand-type :Reg16)
3543                   :reg-flags 0
3544                   :reg-num 1)
3545   (make-reg-entry :reg-name "dx"
3546                   :reg-type (encode-operand-type :Reg16 :InOutPortReg)
3547                   :reg-flags 0
3548                   :reg-num 2)
3549   (make-reg-entry :reg-name "bx"
3550                   :reg-type (encode-operand-type :Reg16 :BaseIndex)
3551                   :reg-flags 0
3552                   :reg-num 3)
3553   (make-reg-entry :reg-name "sp"
3554                   :reg-type (encode-operand-type :Reg16)
3555                   :reg-flags 0
3556                   :reg-num 4)
3557   (make-reg-entry :reg-name "bp"
3558                   :reg-type (encode-operand-type :Reg16 :BaseIndex)
3559                   :reg-flags 0
3560                   :reg-num 5)
3561   (make-reg-entry :reg-name "si"
3562                   :reg-type (encode-operand-type :Reg16 :BaseIndex)
3563                   :reg-flags 0
3564                   :reg-num 6)
3565   (make-reg-entry :reg-name "di"
3566                   :reg-type (encode-operand-type :Reg16 :BaseIndex)
3567                   :reg-flags 0
3568                   :reg-num 7)
3569   (make-reg-entry :reg-name "r8w"
3570                   :reg-type (encode-operand-type :Reg16)
3571                   :reg-flags +RegRex+
3572                   :reg-num 0 )
3573   (make-reg-entry :reg-name "r9w"
3574                   :reg-type (encode-operand-type :Reg16)
3575                   :reg-flags +RegRex+
3576                   :reg-num 1)
3577   (make-reg-entry :reg-name "r10w"
3578                   :reg-type (encode-operand-type :Reg16)
3579                   :reg-flags +RegRex+
3580                   :reg-num 2)
3581   (make-reg-entry :reg-name "r11w"
3582                   :reg-type (encode-operand-type :Reg16)
3583                   :reg-flags +RegRex+
3584                   :reg-num 3)
3585   (make-reg-entry :reg-name "r12w"
3586                   :reg-type (encode-operand-type :Reg16)
3587                   :reg-flags +RegRex+
3588                   :reg-num 4)
3589   (make-reg-entry :reg-name "r13w"
3590                   :reg-type (encode-operand-type :Reg16)
3591                   :reg-flags +RegRex+
3592                   :reg-num 5)
3593   (make-reg-entry :reg-name "r14w"
3594                   :reg-type (encode-operand-type :Reg16)
3595                   :reg-flags +RegRex+
3596                   :reg-num 6)
3597   (make-reg-entry :reg-name "r15w"
3598                   :reg-type (encode-operand-type :Reg16)
3599                   :reg-flags +RegRex+
3600                   :reg-num 7)
3601        ; 32 bit regs
3602   (make-reg-entry :reg-name "eax"
3603                   :reg-type (encode-operand-type :Reg32 :BaseIndex :Acc)
3604                   :reg-flags 0
3605                   :reg-num 0 ) ; Must be in ax + 16 slot.
3606   (make-reg-entry :reg-name "ecx"
3607                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3608                   :reg-flags 0
3609                   :reg-num 1)
3610   (make-reg-entry :reg-name "edx"
3611                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3612                   :reg-flags 0
3613                   :reg-num 2)
3614   (make-reg-entry :reg-name "ebx"
3615                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3616                   :reg-flags 0
3617                   :reg-num 3)
3618   (make-reg-entry :reg-name "esp"
3619                   :reg-type (encode-operand-type :Reg32)
3620                   :reg-flags 0
3621                   :reg-num 4)
3622   (make-reg-entry :reg-name "ebp"
3623                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3624                   :reg-flags 0
3625                   :reg-num 5)
3626   (make-reg-entry :reg-name "esi"
3627                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3628                   :reg-flags 0
3629                   :reg-num 6)
3630   (make-reg-entry :reg-name "edi"
3631                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3632                   :reg-flags 0
3633                   :reg-num 7)
3634   (make-reg-entry :reg-name "r8d"
3635                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3636                   :reg-flags +RegRex+
3637                   :reg-num 0 )
3638   (make-reg-entry :reg-name "r9d"
3639                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3640                   :reg-flags +RegRex+
3641                   :reg-num 1)
3642   (make-reg-entry :reg-name "r10d"
3643                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3644                   :reg-flags +RegRex+
3645                   :reg-num 2)
3646   (make-reg-entry :reg-name "r11d"
3647                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3648                   :reg-flags +RegRex+
3649                   :reg-num 3)
3650   (make-reg-entry :reg-name "r12d"
3651                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3652                   :reg-flags +RegRex+
3653                   :reg-num 4)
3654   (make-reg-entry :reg-name "r13d"
3655                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3656                   :reg-flags +RegRex+
3657                   :reg-num 5)
3658   (make-reg-entry :reg-name "r14d"
3659                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3660                   :reg-flags +RegRex+
3661                   :reg-num 6)
3662   (make-reg-entry :reg-name "r15d"
3663                   :reg-type (encode-operand-type :Reg32 :BaseIndex)
3664                   :reg-flags +RegRex+
3665                   :reg-num 7)
3666   (make-reg-entry :reg-name "rax"
3667                   :reg-type (encode-operand-type :Reg64 :BaseIndex :Acc)
3668                   :reg-flags 0
3669                   :reg-num 0 )
3670   (make-reg-entry :reg-name "rcx"
3671                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3672                   :reg-flags 0
3673                   :reg-num 1)
3674   (make-reg-entry :reg-name "rdx"
3675                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3676                   :reg-flags 0
3677                   :reg-num 2)
3678   (make-reg-entry :reg-name "rbx"
3679                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3680                   :reg-flags 0
3681                   :reg-num 3)
3682   (make-reg-entry :reg-name "rsp"
3683                   :reg-type (encode-operand-type :Reg64)
3684                   :reg-flags 0
3685                   :reg-num 4)
3686   (make-reg-entry :reg-name "rbp"
3687                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3688                   :reg-flags 0
3689                   :reg-num 5)
3690   (make-reg-entry :reg-name "rsi"
3691                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3692                   :reg-flags 0
3693                   :reg-num 6)
3694   (make-reg-entry :reg-name "rdi"
3695                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3696                   :reg-flags 0
3697                   :reg-num 7)
3698   (make-reg-entry :reg-name "r8"
3699                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3700                   :reg-flags +RegRex+
3701                   :reg-num 0 )
3702   (make-reg-entry :reg-name "r9"
3703                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3704                   :reg-flags +RegRex+
3705                   :reg-num 1)
3706   (make-reg-entry :reg-name "r10"
3707                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3708                   :reg-flags +RegRex+
3709                   :reg-num 2)
3710   (make-reg-entry :reg-name "r11"
3711                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3712                   :reg-flags +RegRex+
3713                   :reg-num 3)
3714   (make-reg-entry :reg-name "r12"
3715                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3716                   :reg-flags +RegRex+
3717                   :reg-num 4)
3718   (make-reg-entry :reg-name "r13"
3719                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3720                   :reg-flags +RegRex+
3721                   :reg-num 5)
3722   (make-reg-entry :reg-name "r14"
3723                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3724                   :reg-flags +RegRex+
3725                   :reg-num 6)
3726   (make-reg-entry :reg-name "r15"
3727                   :reg-type (encode-operand-type :Reg64 :BaseIndex)
3728                   :reg-flags +RegRex+
3729                   :reg-num 7)
3730        ; Segment registers.
3731   (make-reg-entry :reg-name "es"
3732                   :reg-type (encode-operand-type :SReg2)
3733                   :reg-flags 0
3734                   :reg-num 0 )
3735   (make-reg-entry :reg-name "cs"
3736                   :reg-type (encode-operand-type :SReg2)
3737                   :reg-flags 0
3738                   :reg-num 1)
3739   (make-reg-entry :reg-name "ss"
3740                   :reg-type (encode-operand-type :SReg2)
3741                   :reg-flags 0
3742                   :reg-num 2)
3743   (make-reg-entry :reg-name "ds"
3744                   :reg-type (encode-operand-type :SReg2)
3745                   :reg-flags 0
3746                   :reg-num 3)
3747   (make-reg-entry :reg-name "fs"
3748                   :reg-type (encode-operand-type :SReg3)
3749                   :reg-flags 0
3750                   :reg-num 4)
3751   (make-reg-entry :reg-name "gs"
3752                   :reg-type (encode-operand-type :SReg3)
3753                   :reg-flags 0
3754                   :reg-num 5)
3755   ;; Control registers.
3756   (make-reg-entry :reg-name "cr0"
3757                   :reg-type (encode-operand-type :Control)
3758                   :reg-flags 0
3759                   :reg-num 0 )
3760   (make-reg-entry :reg-name "cr1"
3761                   :reg-type (encode-operand-type :Control)
3762                   :reg-flags 0
3763                   :reg-num 1)
3764   (make-reg-entry :reg-name "cr2"
3765                   :reg-type (encode-operand-type :Control)
3766                   :reg-flags 0
3767                   :reg-num 2)
3768   (make-reg-entry :reg-name "cr3"
3769                   :reg-type (encode-operand-type :Control)
3770                   :reg-flags 0
3771                   :reg-num 3)
3772   (make-reg-entry :reg-name "cr4"
3773                   :reg-type (encode-operand-type :Control)
3774                   :reg-flags 0
3775                   :reg-num 4)
3776   (make-reg-entry :reg-name "cr5"
3777                   :reg-type (encode-operand-type :Control)
3778                   :reg-flags 0
3779                   :reg-num 5)
3780   (make-reg-entry :reg-name "cr6"
3781                   :reg-type (encode-operand-type :Control)
3782                   :reg-flags 0
3783                   :reg-num 6)
3784   (make-reg-entry :reg-name "cr7"
3785                   :reg-type (encode-operand-type :Control)
3786                   :reg-flags 0
3787                   :reg-num 7)
3788   (make-reg-entry :reg-name "cr8"
3789                   :reg-type (encode-operand-type :Control)
3790                   :reg-flags +RegRex+
3791                   :reg-num 0 )
3792   (make-reg-entry :reg-name "cr9"
3793                   :reg-type (encode-operand-type :Control)
3794                   :reg-flags +RegRex+
3795                   :reg-num 1)
3796   (make-reg-entry :reg-name "cr10"
3797                   :reg-type (encode-operand-type :Control)
3798                   :reg-flags +RegRex+
3799                   :reg-num 2)
3800   (make-reg-entry :reg-name "cr11"
3801                   :reg-type (encode-operand-type :Control)
3802                   :reg-flags +RegRex+
3803                   :reg-num 3)
3804   (make-reg-entry :reg-name "cr12"
3805                   :reg-type (encode-operand-type :Control)
3806                   :reg-flags +RegRex+
3807                   :reg-num 4)
3808   (make-reg-entry :reg-name "cr13"
3809                   :reg-type (encode-operand-type :Control)
3810                   :reg-flags +RegRex+
3811                   :reg-num 5)
3812   (make-reg-entry :reg-name "cr14"
3813                   :reg-type (encode-operand-type :Control)
3814                   :reg-flags +RegRex+
3815                   :reg-num 6)
3816   (make-reg-entry :reg-name "cr15"
3817                   :reg-type (encode-operand-type :Control)
3818                   :reg-flags +RegRex+
3819                   :reg-num 7)
3820   ;; Debug registers.
3821   (make-reg-entry :reg-name "db0"
3822                   :reg-type (encode-operand-type :Debug)
3823                   :reg-flags 0
3824                   :reg-num 0 )
3825   (make-reg-entry :reg-name "db1"
3826                   :reg-type (encode-operand-type :Debug)
3827                   :reg-flags 0
3828                   :reg-num 1)
3829   (make-reg-entry :reg-name "db2"
3830                   :reg-type (encode-operand-type :Debug)
3831                   :reg-flags 0
3832                   :reg-num 2)
3833   (make-reg-entry :reg-name "db3"
3834                   :reg-type (encode-operand-type :Debug)
3835                   :reg-flags 0
3836                   :reg-num 3)
3837   (make-reg-entry :reg-name "db4"
3838                   :reg-type (encode-operand-type :Debug)
3839                   :reg-flags 0
3840                   :reg-num 4)
3841   (make-reg-entry :reg-name "db5"
3842                   :reg-type (encode-operand-type :Debug)
3843                   :reg-flags 0
3844                   :reg-num 5)
3845   (make-reg-entry :reg-name "db6"
3846                   :reg-type (encode-operand-type :Debug)
3847                   :reg-flags 0
3848                   :reg-num 6)
3849   (make-reg-entry :reg-name "db7"
3850                   :reg-type (encode-operand-type :Debug)
3851                   :reg-flags 0
3852                   :reg-num 7)
3853   (make-reg-entry :reg-name "db8"
3854                   :reg-type (encode-operand-type :Debug)
3855                   :reg-flags +RegRex+
3856                   :reg-num 0 )
3857   (make-reg-entry :reg-name "db9"
3858                   :reg-type (encode-operand-type :Debug)
3859                   :reg-flags +RegRex+
3860                   :reg-num 1)
3861   (make-reg-entry :reg-name "db10"
3862                   :reg-type (encode-operand-type :Debug)
3863                   :reg-flags +RegRex+
3864                   :reg-num 2)
3865   (make-reg-entry :reg-name "db11"
3866                   :reg-type (encode-operand-type :Debug)
3867                   :reg-flags +RegRex+
3868                   :reg-num 3)
3869   (make-reg-entry :reg-name "db12"
3870                   :reg-type (encode-operand-type :Debug)
3871                   :reg-flags +RegRex+
3872                   :reg-num 4)
3873   (make-reg-entry :reg-name "db13"
3874                   :reg-type (encode-operand-type :Debug)
3875                   :reg-flags +RegRex+
3876                   :reg-num 5)
3877   (make-reg-entry :reg-name "db14"
3878                   :reg-type (encode-operand-type :Debug)
3879                   :reg-flags +RegRex+
3880                   :reg-num 6)
3881   (make-reg-entry :reg-name "db15"
3882                   :reg-type (encode-operand-type :Debug)
3883                   :reg-flags +RegRex+
3884                   :reg-num 7)
3885   (make-reg-entry :reg-name "dr0"
3886                   :reg-type (encode-operand-type :Debug)
3887                   :reg-flags 0
3888                   :reg-num 0 )
3889   (make-reg-entry :reg-name "dr1"
3890                   :reg-type (encode-operand-type :Debug)
3891                   :reg-flags 0
3892                   :reg-num 1)
3893   (make-reg-entry :reg-name "dr2"
3894                   :reg-type (encode-operand-type :Debug)
3895                   :reg-flags 0
3896                   :reg-num 2)
3897   (make-reg-entry :reg-name "dr3"
3898                   :reg-type (encode-operand-type :Debug)
3899                   :reg-flags 0
3900                   :reg-num 3)
3901   (make-reg-entry :reg-name "dr4"
3902                   :reg-type (encode-operand-type :Debug)
3903                   :reg-flags 0
3904                   :reg-num 4)
3905   (make-reg-entry :reg-name "dr5"
3906                   :reg-type (encode-operand-type :Debug)
3907                   :reg-flags 0
3908                   :reg-num 5)
3909   (make-reg-entry :reg-name "dr6"
3910                   :reg-type (encode-operand-type :Debug)
3911                   :reg-flags 0
3912                   :reg-num 6)
3913   (make-reg-entry :reg-name "dr7"
3914                   :reg-type (encode-operand-type :Debug)
3915                   :reg-flags 0
3916                   :reg-num 7)
3917   (make-reg-entry :reg-name "dr8"
3918                   :reg-type (encode-operand-type :Debug)
3919                   :reg-flags +RegRex+
3920                   :reg-num 0 )
3921   (make-reg-entry :reg-name "dr9"
3922                   :reg-type (encode-operand-type :Debug)
3923                   :reg-flags +RegRex+
3924                   :reg-num 1)
3925   (make-reg-entry :reg-name "dr10"
3926                   :reg-type (encode-operand-type :Debug)
3927                   :reg-flags +RegRex+
3928                   :reg-num 2)
3929   (make-reg-entry :reg-name "dr11"
3930                   :reg-type (encode-operand-type :Debug)
3931                   :reg-flags +RegRex+
3932                   :reg-num 3)
3933   (make-reg-entry :reg-name "dr12"
3934                   :reg-type (encode-operand-type :Debug)
3935                   :reg-flags +RegRex+
3936                   :reg-num 4)
3937   (make-reg-entry :reg-name "dr13"
3938                   :reg-type (encode-operand-type :Debug)
3939                   :reg-flags +RegRex+
3940                   :reg-num 5)
3941   (make-reg-entry :reg-name "dr14"
3942                   :reg-type (encode-operand-type :Debug)
3943                   :reg-flags +RegRex+
3944                   :reg-num 6)
3945   (make-reg-entry :reg-name "dr15"
3946                   :reg-type (encode-operand-type :Debug)
3947                   :reg-flags +RegRex+
3948                   :reg-num 7)
3949   ;; Test registers.
3950   (make-reg-entry :reg-name "tr0"
3951                   :reg-type (encode-operand-type :Test)
3952                   :reg-flags 0
3953                   :reg-num 0 )
3954   (make-reg-entry :reg-name "tr1"
3955                   :reg-type (encode-operand-type :Test)
3956                   :reg-flags 0
3957                   :reg-num 1)
3958   (make-reg-entry :reg-name "tr2"
3959                   :reg-type (encode-operand-type :Test)
3960                   :reg-flags 0
3961                   :reg-num 2)
3962   (make-reg-entry :reg-name "tr3"
3963                   :reg-type (encode-operand-type :Test)
3964                   :reg-flags 0
3965                   :reg-num 3)
3966   (make-reg-entry :reg-name "tr4"
3967                   :reg-type (encode-operand-type :Test)
3968                   :reg-flags 0
3969                   :reg-num 4)
3970   (make-reg-entry :reg-name "tr5"
3971                   :reg-type (encode-operand-type :Test)
3972                   :reg-flags 0
3973                   :reg-num 5)
3974   (make-reg-entry :reg-name "tr6"
3975                   :reg-type (encode-operand-type :Test)
3976                   :reg-flags 0
3977                   :reg-num 6)
3978   (make-reg-entry :reg-name "tr7"
3979                   :reg-type (encode-operand-type :Test)
3980                   :reg-flags 0
3981                   :reg-num 7)
3982   ;; MMX and simd registers.
3983   (make-reg-entry :reg-name "mm0"
3984                   :reg-type (encode-operand-type :RegMMX)
3985                   :reg-flags 0
3986                   :reg-num 0 )
3987   (make-reg-entry :reg-name "mm1"
3988                   :reg-type (encode-operand-type :RegMMX)
3989                   :reg-flags 0
3990                   :reg-num 1)
3991   (make-reg-entry :reg-name "mm2"
3992                   :reg-type (encode-operand-type :RegMMX)
3993                   :reg-flags 0
3994                   :reg-num 2)
3995   (make-reg-entry :reg-name "mm3"
3996                   :reg-type (encode-operand-type :RegMMX)
3997                   :reg-flags 0
3998                   :reg-num 3)
3999   (make-reg-entry :reg-name "mm4"
4000                   :reg-type (encode-operand-type :RegMMX)
4001                   :reg-flags 0
4002                   :reg-num 4)
4003   (make-reg-entry :reg-name "mm5"
4004                   :reg-type (encode-operand-type :RegMMX)
4005                   :reg-flags 0
4006                   :reg-num 5)
4007   (make-reg-entry :reg-name "mm6"
4008                   :reg-type (encode-operand-type :RegMMX)
4009                   :reg-flags 0
4010                   :reg-num 6)
4011   (make-reg-entry :reg-name "mm7"
4012                   :reg-type (encode-operand-type :RegMMX)
4013                   :reg-flags 0
4014                   :reg-num 7)
4015   (make-reg-entry :reg-name "xmm0"
4016                   :reg-type (encode-operand-type :RegXMM)
4017                   :reg-flags 0
4018                   :reg-num 0 )
4019   (make-reg-entry :reg-name "xmm1"
4020                   :reg-type (encode-operand-type :RegXMM)
4021                   :reg-flags 0
4022                   :reg-num 1)
4023   (make-reg-entry :reg-name "xmm2"
4024                   :reg-type (encode-operand-type :RegXMM)
4025                   :reg-flags 0
4026                   :reg-num 2)
4027   (make-reg-entry :reg-name "xmm3"
4028                   :reg-type (encode-operand-type :RegXMM)
4029                   :reg-flags 0
4030                   :reg-num 3)
4031   (make-reg-entry :reg-name "xmm4"
4032                   :reg-type (encode-operand-type :RegXMM)
4033                   :reg-flags 0
4034                   :reg-num 4)
4035   (make-reg-entry :reg-name "xmm5"
4036                   :reg-type (encode-operand-type :RegXMM)
4037                   :reg-flags 0
4038                   :reg-num 5)
4039   (make-reg-entry :reg-name "xmm6"
4040                   :reg-type (encode-operand-type :RegXMM)
4041                   :reg-flags 0
4042                   :reg-num 6)
4043   (make-reg-entry :reg-name "xmm7"
4044                   :reg-type (encode-operand-type :RegXMM)
4045                   :reg-flags 0
4046                   :reg-num 7)
4047   (make-reg-entry :reg-name "xmm8"
4048                   :reg-type (encode-operand-type :RegXMM)
4049                   :reg-flags +RegRex+
4050                   :reg-num 0 )
4051   (make-reg-entry :reg-name "xmm9"
4052                   :reg-type (encode-operand-type :RegXMM)
4053                   :reg-flags +RegRex+
4054                   :reg-num 1)
4055   (make-reg-entry :reg-name "xmm10"
4056                   :reg-type (encode-operand-type :RegXMM)
4057                   :reg-flags +RegRex+
4058                   :reg-num 2)
4059   (make-reg-entry :reg-name "xmm11"
4060                   :reg-type (encode-operand-type :RegXMM)
4061                   :reg-flags +RegRex+
4062                   :reg-num 3)
4063   (make-reg-entry :reg-name "xmm12"
4064                   :reg-type (encode-operand-type :RegXMM)
4065                   :reg-flags +RegRex+
4066                   :reg-num 4)
4067   (make-reg-entry :reg-name "xmm13"
4068                   :reg-type (encode-operand-type :RegXMM)
4069                   :reg-flags +RegRex+
4070                   :reg-num 5)
4071   (make-reg-entry :reg-name "xmm14"
4072                   :reg-type (encode-operand-type :RegXMM)
4073                   :reg-flags +RegRex+
4074                   :reg-num 6)
4075   (make-reg-entry :reg-name "xmm15"
4076                   :reg-type (encode-operand-type :RegXMM)
4077                   :reg-flags +RegRex+
4078                   :reg-num 7)
4079   ;; No type will make this register rejected for all purposes except
4080   ;; for addressing. This saves creating one extra type for RIP.
4081   (make-reg-entry :reg-name "rip"
4082                   :reg-type (encode-operand-type :BaseIndex)
4083                   :reg-flags 0
4084                   :reg-num 0 )
4085   ))
4086
4087(defvar *x86-float-regs*
4088  (vector
4089   (make-reg-entry :reg-name "st[0]"
4090                   :reg-type (encode-operand-type :FloatReg :FloatAcc)
4091                   :reg-flags 0
4092                   :reg-num 0)
4093   (make-reg-entry :reg-name "st[1]"
4094                   :reg-type (encode-operand-type :FloatReg)
4095                   :reg-flags 0
4096                   :reg-num 1)
4097   (make-reg-entry :reg-name "st[2]"
4098                   :reg-type (encode-operand-type :FloatReg)
4099                   :reg-flags 0
4100                   :reg-num 2)
4101   (make-reg-entry :reg-name "st[3]"
4102                   :reg-type (encode-operand-type :FloatReg)
4103                   :reg-flags 0
4104                   :reg-num 3)
4105   (make-reg-entry :reg-name "st[4]"
4106                   :reg-type (encode-operand-type :FloatReg)
4107                   :reg-flags 0
4108                   :reg-num 4)
4109   (make-reg-entry :reg-name "st[5]"
4110                   :reg-type (encode-operand-type :FloatReg)
4111                   :reg-flags 0
4112                   :reg-num 5)
4113   (make-reg-entry :reg-name "st[6]"
4114                   :reg-type (encode-operand-type :FloatReg)
4115                   :reg-flags 0
4116                   :reg-num 6)
4117   (make-reg-entry :reg-name "st[7]"
4118                   :reg-type (encode-operand-type :FloatReg)
4119                   :reg-flags 0
4120                   :reg-num 7)))
4121
4122
4123;;; Segment stuff.
4124(defvar *cs-segment-register* (make-seg-entry :seg-name "cs" :seg-prefix #x23))
4125(defvar *ds-segment-register* (make-seg-entry :seg-name "ds" :seg-prefix #x3e))
4126(defvar *ss-segment-register* (make-seg-entry :seg-name "ss" :seg-prefix #x36))
4127(defvar *es-segment-register* (make-seg-entry :seg-name "es" :seg-prefix #x26))
4128(defvar *fs-segment-register* (make-seg-entry :seg-name "fs" :seg-prefix #x64))
4129(defvar *gs-segment-register* (make-seg-entry :seg-name "gs" :seg-prefix #x65))
4130
4131(defvar *x86-seg-entries*
4132  (vector *es-segment-register*
4133          *cs-segment-register*
4134          *ss-segment-register*
4135          *ds-segment-register*
4136          *fs-segment-register*
4137          *gs-segment-register*))
4138
4139
4140
4141
4142
4143(defun init-x86-registers ()
4144  (labels ((ia32-p (entry)
4145             (not (or (logtest (reg-entry-reg-flags entry)
4146                               (logior +regrex+ +regrex64+))
4147                      (logtest (reg-entry-reg-type entry)
4148                               (encode-operand-type :reg64))
4149                      ;; As a special case, exclude RIP, whose type is
4150                      ;; *exactly* :BaseIndex
4151                      (eql (reg-entry-reg-type entry)
4152                           (encode-operand-type :BaseIndex)))))
4153           (hash-registers (vector hash 64p)
4154             (dotimes (i (length vector))
4155               (let* ((entry (svref vector i)))
4156                 (if (or 64p (ia32-p entry))
4157                   (setf (gethash (reg-entry-reg-name entry) hash) entry))))))
4158    (hash-registers *x86-regtab* *x8632-registers* nil)
4159    (hash-registers *x86-float-regs* *x8632-registers* nil)
4160    (hash-registers *x86-regtab* *x8664-registers* t)
4161    (hash-registers *x86-float-regs* *x8664-registers* t)))
4162
4163)
4164
4165(init-x86-registers)
4166
4167
4168
4169(defstruct x86-operand
4170  (type ))
4171
4172(defstruct (x86-immediate-operand (:include x86-operand))
4173  ;; The "value" of an immediate operand may be an expression (that we
4174  ;; have to do some sort of delayed evaluation on.)  It could just be
4175  ;; a lisp form (that we call EVAL on), but there might be scoping or
4176  ;; similar issues in that case.
4177  value)
4178
4179(defstruct (x86-register-operand (:include x86-operand))
4180  entry                                 ;the reg-entry
4181)
4182
4183(defstruct (x86-label-operand (:include x86-operand))
4184  label)
4185
4186
4187(defstruct (x86-memory-operand (:include x86-operand))
4188  ;; Any of these fields can be null.  Some combinations of fields -
4189  ;; like a segment register or scale factor by itself - make no
4190  ;; sense.
4191  seg                                   ; a segment register
4192  disp                                  ; a signed displacement added to base
4193  base                                  ; a GPR
4194  index                                 ; another GPR
4195  scale                                 ; scale factor, multiplied with index
4196  )
4197
4198
4199(defun insert-nothing (instruction operand)
4200  (declare (ignore instruction operand)))
4201
4202;;; Insert a 3-bit register value derived from OPERAND in INSN's modrm.reg
4203;;; field.  If the register requires REX addressing, set the REX.R bit
4204;;; in the instruction's rex-prefix.  If either the modrm or rex-prefix
4205;;; fields of the instruction are NIL, we're very confused; check for
4206;;; that explicitly until this code matures a bit.
4207
4208(defun insert-modrm-reg-entry (instruction entry)
4209  (let* ((reg-num (reg-entry-reg-num entry))
4210         (flags (reg-entry-reg-flags entry))
4211         (need-rex.r (logtest +regrex+ flags)))
4212    (setf (x86-instruction-modrm-byte instruction)
4213          (dpb reg-num (byte 3 3)
4214               (need-modrm-byte instruction)))
4215    (when need-rex.r
4216      (setf (x86-instruction-rex-prefix instruction)
4217            (logior +rex-extx+ (need-rex-prefix instruction))))
4218    (when (logtest +regrex64+ flags)
4219      (setf (x86-instruction-rex-prefix instruction)
4220            (logior #x80 (need-rex-prefix instruction))))))
4221
4222
4223
4224(defun insert-modrm-reg (instruction operand)
4225  (insert-modrm-reg-entry instruction (x86-register-operand-entry operand)))
4226
4227(defun insert-mmx-reg-entry (instruction entry)
4228  (let* ((reg-num (reg-entry-reg-num entry)))
4229    (setf (x86-instruction-modrm-byte instruction)
4230          (dpb reg-num (byte 3 3)
4231               (need-modrm-byte instruction)))))
4232
4233(defun insert-mmx-reg (instruction operand)
4234  (insert-mmx-reg-entry instruction (x86-register-operand-entry operand)))
4235
4236(defun insert-xmm-reg (instruction operand)
4237  (insert-modrm-reg instruction operand))
4238
4239(defun insert-xmm-rm (instruction operand)
4240  (insert-modrm-rm instruction operand))
4241
4242(defun insert-opcode-reg-entry (instruction entry)
4243  (let* ((reg-num (reg-entry-reg-num entry))
4244         (flags (reg-entry-reg-flags entry))
4245         (need-rex.b (logtest +regrex+ flags)))
4246    (setf (x86-instruction-base-opcode instruction)
4247          (dpb reg-num (byte 3 0)
4248               (x86-instruction-base-opcode instruction)))
4249    (when need-rex.b
4250      (setf (x86-instruction-rex-prefix instruction)
4251            (logior +rex-extz+ (need-rex-prefix instruction))))
4252    (when (logtest +regrex64+ flags)
4253      (setf (x86-instruction-rex-prefix instruction)
4254            (logior #x80 (need-rex-prefix instruction))))))
4255
4256(defun insert-opcode-reg (instruction operand)
4257  (insert-opcode-reg-entry instruction (x86-register-operand-entry operand)))
4258
4259;;; Insert a 4-bit register number in the low 4 bits of the opcode.
4260;;; (This is only used in synthetic instructions, like some UUOs.)
4261
4262(defun insert-opcode-reg4-entry (instruction entry)
4263  (let* ((reg-num (reg-entry-reg-num entry))
4264         (xreg-num (logior reg-num
4265                           (if (logtest +regrex+ (reg-entry-reg-flags entry))
4266                             #x08
4267                             #x00))))
4268    (setf (x86-instruction-base-opcode instruction)
4269          (dpb xreg-num (byte 4 0)
4270               (x86-instruction-base-opcode instruction)))))
4271
4272(defun insert-opcode-reg4 (instruction operand)
4273  (insert-opcode-reg4-entry instruction (x86-register-operand-entry operand)))
4274
4275
4276(defun insert-reg4-pseudo-rm-high-entry (instruction entry)
4277  (let* ((reg-num (reg-entry-reg-num entry))
4278         (xreg-num (logior reg-num
4279                           (if (logtest +regrex+ (reg-entry-reg-flags entry))
4280                             #x08
4281                             #x00))))
4282    (setf (x86-instruction-modrm-byte instruction)
4283          (dpb xreg-num (byte 4 4)
4284               (x86-instruction-modrm-byte instruction)))))
4285
4286(defun insert-reg4-pseudo-rm-high (instruction operand)
4287  (insert-reg4-pseudo-rm-high-entry instruction (x86-register-operand-entry operand)))
4288
4289
4290(defun insert-reg4-pseudo-rm-low-entry (instruction entry)
4291  (let* ((reg-num (reg-entry-reg-num entry))
4292         (xreg-num (logior reg-num
4293                           (if (logtest +regrex+ (reg-entry-reg-flags entry))
4294                             #x08
4295                             #x00))))
4296    (setf (x86-instruction-modrm-byte instruction)
4297          (dpb xreg-num (byte 4 0)
4298               (x86-instruction-modrm-byte instruction)))))
4299
4300(defun insert-reg4-pseudo-rm-low (instruction operand)
4301  (insert-reg4-pseudo-rm-low-entry instruction (x86-register-operand-entry operand)))
4302
4303;;; Insert a 3-bit register value derived from OPERAND in INSN's modrm.rm
4304;;; field.  If the register requires REX addressing, set the REX.B bit
4305;;; in the instruction's rex-prefix.  If either the modrm or rex-prefix
4306;;; fields of the instruction are NIL, we're very confused; check for
4307;;; that explicitly until this code matures a bit.
4308
4309(defun insert-modrm-rm-entry (instruction entry)
4310  (let* ((reg-num (reg-entry-reg-num entry))
4311         (flags (reg-entry-reg-flags entry))
4312         (need-rex.b (logtest +regrex+ flags)))
4313    (setf (x86-instruction-modrm-byte instruction)
4314          (dpb reg-num (byte 3 0) (need-modrm-byte instruction)))
4315    (when need-rex.b
4316      (setf (x86-instruction-rex-prefix instruction)
4317            (logior +rex-extz+ (need-rex-prefix instruction))))
4318    (when (logtest +regrex64+ flags)
4319      (setf (x86-instruction-rex-prefix instruction)
4320            (logior #x80 (need-rex-prefix instruction))))))
4321
4322(defun insert-modrm-rm (instruction operand)
4323  (insert-modrm-rm-entry instruction (x86-register-operand-entry operand)))
4324
4325(defun insert-mmx-rm-entry (instruction entry)
4326  (let* ((reg-num (reg-entry-reg-num entry)))
4327    (setf (x86-instruction-modrm-byte instruction)
4328          (dpb reg-num (byte 3 0) (need-modrm-byte instruction)))))
4329
4330(defun insert-mmx-rm (instruction operand)
4331  (insert-mmx-rm-entry instruction (x86-register-operand-entry operand)))
4332
4333(defun insert-imm64 (instruction operand)
4334  (setf (x86-immediate-operand-type operand)
4335        (encode-operand-type :imm64))
4336  (setf (x86-instruction-imm instruction) operand))
4337
4338(defun insert-imm32s (instruction operand)
4339  (setf (x86-immediate-operand-type operand)
4340        (encode-operand-type :imm32s))
4341  (setf (x86-instruction-imm instruction) operand))
4342
4343(defun insert-imm32 (instruction operand)
4344  (setf (x86-immediate-operand-type operand)
4345        (encode-operand-type :imm32))
4346  (setf (x86-instruction-imm instruction) operand))
4347
4348(defun insert-imm16 (instruction operand)
4349  (setf (x86-immediate-operand-type operand)
4350        (encode-operand-type :imm16))
4351  (setf (x86-instruction-imm instruction) operand))
4352
4353(defun insert-imm8 (instruction operand)
4354  (setf (x86-immediate-operand-type operand)
4355        (encode-operand-type :imm8))
4356  (setf (x86-instruction-imm instruction) operand))
4357
4358(defun insert-imm8s (instruction operand)
4359  (setf (x86-immediate-operand-type operand)
4360        (encode-operand-type :imm8s))
4361  (setf (x86-instruction-imm instruction) operand))
4362
4363(defun insert-imm8-for-int (instruction operand)
4364  (declare (ftype (function (t) t) ccl::early-x86-lap-expression-value))
4365  (let* ((expr (x86-immediate-operand-value operand))
4366         (value (ccl::early-x86-lap-expression-value expr)))