source: trunk/source/compiler/X86/x86-asm.lisp @ 8610

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

cvttss2si: correct rest of comment

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