1 /* opcode/i386.h -- Intel 80386 opcode table
2 Copyright 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 /* The UnixWare assembler, and probably other AT&T derived ix86 Unix
21 assemblers, generate floating point instructions with reversed
22 source and destination registers in certain cases. Unfortunately,
23 gcc and possibly many other programs use this reversed syntax, so
26 eg. `fsub %st(3),%st' results in st <- st - st(3) as expected, but
27 `fsub %st,%st(3)' results in st(3) <- st - st(3), rather than
28 the expected st(3) <- st(3) - st !
30 This happens with all the non-commutative arithmetic floating point
31 operations with two register operands, where the source register is
32 %st, and destination register is %st(i). Look for FloatDR below. */
34 #ifndef UNIXWARE_COMPAT
35 /* Set non-zero for broken, compatible instructions. Set to zero for
36 non-broken opcodes at your peril. gcc generates UnixWare
37 compatible instructions. */
38 #define UNIXWARE_COMPAT 1
42 static const template i386_optab[] = {
45 #define ReverseModrm (ReverseRegRegmem|Modrm)
46 #define NoSuf (No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
47 #define b_Suf (No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
48 #define w_Suf (No_bSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
49 #define l_Suf (No_bSuf|No_wSuf|No_sSuf|No_dSuf|No_xSuf)
50 #define d_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_xSuf)
51 #define x_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_dSuf)
52 #define bw_Suf (No_lSuf|No_sSuf|No_dSuf|No_xSuf)
53 #define bl_Suf (No_wSuf|No_sSuf|No_dSuf|No_xSuf)
54 #define wl_Suf (No_bSuf|No_sSuf|No_dSuf|No_xSuf)
55 #define sl_Suf (No_bSuf|No_wSuf|No_dSuf|No_xSuf)
56 #define sld_Suf (No_bSuf|No_wSuf|No_xSuf)
57 #define sldx_Suf (No_bSuf|No_wSuf)
58 #define bwl_Suf (No_sSuf|No_dSuf|No_xSuf)
59 #define bwld_Suf (No_sSuf|No_xSuf)
60 #define FP (NoSuf|IgnoreSize)
61 #define l_FP (l_Suf|IgnoreSize)
62 #define d_FP (d_Suf|IgnoreSize)
63 #define x_FP (x_Suf|IgnoreSize)
64 #define sl_FP (sl_Suf|IgnoreSize)
65 #define sld_FP (sld_Suf|IgnoreSize)
66 #define sldx_FP (sldx_Suf|IgnoreSize)
68 #define FloatDR FloatD
70 #define FloatDR (FloatD|FloatR)
73 /* move instructions */
74 #define MOV_AX_DISP32 0xa0
75 { "mov", 2, 0xa0, X, bwl_Suf|D|W, { Disp16|Disp32, Acc, 0 } },
76 { "mov", 2, 0x88, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0 } },
77 { "mov", 2, 0xb0, X, bwl_Suf|W|ShortForm, { Imm, Reg, 0 } },
78 { "mov", 2, 0xc6, X, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0 } },
79 /* The next two instructions accept WordReg so that a segment register
80 can be copied to a 32 bit register, and vice versa, without using a
81 size prefix. When moving to a 32 bit register, the upper 16 bits
82 are set to an implementation defined value (on the Pentium Pro,
83 the implementation defined value is zero). */
84 { "mov", 2, 0x8c, X, wl_Suf|Modrm, { SReg3|SReg2, WordReg|WordMem, 0 } },
85 { "mov", 2, 0x8e, X, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg3|SReg2, 0 } },
86 /* move to/from control debug registers */
87 { "mov", 2, 0x0f20, X, l_Suf|D|Modrm|IgnoreSize, { Control, Reg32, 0} },
88 { "mov", 2, 0x0f21, X, l_Suf|D|Modrm|IgnoreSize, { Debug, Reg32, 0} },
89 { "mov", 2, 0x0f24, X, l_Suf|D|Modrm|IgnoreSize, { Test, Reg32, 0} },
91 /* move with sign extend */
92 /* "movsbl" & "movsbw" must not be unified into "movsb" to avoid
93 conflict with the "movs" string move instruction. */
94 {"movsbl", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg32, 0} },
95 {"movsbw", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg16, 0} },
96 {"movswl", 2, 0x0fbf, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} },
98 {"movsx", 2, 0x0fbf, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} },
99 {"movsx", 2, 0x0fbe, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
101 /* move with zero extend */
102 {"movzb", 2, 0x0fb6, X, wl_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
103 {"movzwl", 2, 0x0fb7, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} },
105 {"movzx", 2, 0x0fb7, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} },
106 {"movzx", 2, 0x0fb6, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
108 /* push instructions */
109 {"push", 1, 0x50, X, wl_Suf|ShortForm, { WordReg,0,0 } },
110 {"push", 1, 0xff, 6, wl_Suf|Modrm, { WordReg|WordMem, 0, 0 } },
111 {"push", 1, 0x6a, X, wl_Suf, { Imm8S, 0, 0} },
112 {"push", 1, 0x68, X, wl_Suf, { Imm16|Imm32, 0, 0} },
113 {"push", 1, 0x06, X, wl_Suf|Seg2ShortForm, { SReg2,0,0 } },
114 {"push", 1, 0x0fa0, X, wl_Suf|Seg3ShortForm, { SReg3,0,0 } },
116 {"pusha", 0, 0x60, X, wl_Suf, { 0, 0, 0 } },
118 /* pop instructions */
119 {"pop", 1, 0x58, X, wl_Suf|ShortForm, { WordReg,0,0 } },
120 {"pop", 1, 0x8f, 0, wl_Suf|Modrm, { WordReg|WordMem, 0, 0 } },
121 #define POP_SEG_SHORT 0x07
122 {"pop", 1, 0x07, X, wl_Suf|Seg2ShortForm, { SReg2,0,0 } },
123 {"pop", 1, 0x0fa1, X, wl_Suf|Seg3ShortForm, { SReg3,0,0 } },
125 {"popa", 0, 0x61, X, wl_Suf, { 0, 0, 0 } },
127 /* xchg exchange instructions
128 xchg commutes: we allow both operand orders */
129 {"xchg", 2, 0x90, X, wl_Suf|ShortForm, { WordReg, Acc, 0 } },
130 {"xchg", 2, 0x90, X, wl_Suf|ShortForm, { Acc, WordReg, 0 } },
131 {"xchg", 2, 0x86, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
132 {"xchg", 2, 0x86, X, bwl_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } },
134 /* in/out from ports */
135 {"in", 2, 0xe4, X, bwl_Suf|W, { Imm8, Acc, 0 } },
136 {"in", 2, 0xec, X, bwl_Suf|W, { InOutPortReg, Acc, 0 } },
137 {"in", 1, 0xe4, X, bwl_Suf|W, { Imm8, 0, 0 } },
138 {"in", 1, 0xec, X, bwl_Suf|W, { InOutPortReg, 0, 0 } },
139 {"out", 2, 0xe6, X, bwl_Suf|W, { Acc, Imm8, 0 } },
140 {"out", 2, 0xee, X, bwl_Suf|W, { Acc, InOutPortReg, 0 } },
141 {"out", 1, 0xe6, X, bwl_Suf|W, { Imm8, 0, 0 } },
142 {"out", 1, 0xee, X, bwl_Suf|W, { InOutPortReg, 0, 0 } },
144 /* load effective address */
145 {"lea", 2, 0x8d, X, wl_Suf|Modrm, { WordMem, WordReg, 0 } },
147 /* load segment registers from memory */
148 {"lds", 2, 0xc5, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
149 {"les", 2, 0xc4, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
150 {"lfs", 2, 0x0fb4, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
151 {"lgs", 2, 0x0fb5, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
152 {"lss", 2, 0x0fb2, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
154 /* flags register instructions */
155 {"clc", 0, 0xf8, X, NoSuf, { 0, 0, 0} },
156 {"cld", 0, 0xfc, X, NoSuf, { 0, 0, 0} },
157 {"cli", 0, 0xfa, X, NoSuf, { 0, 0, 0} },
158 {"clts", 0, 0x0f06, X, NoSuf, { 0, 0, 0} },
159 {"cmc", 0, 0xf5, X, NoSuf, { 0, 0, 0} },
160 {"lahf", 0, 0x9f, X, NoSuf, { 0, 0, 0} },
161 {"sahf", 0, 0x9e, X, NoSuf, { 0, 0, 0} },
162 {"pushf", 0, 0x9c, X, wl_Suf, { 0, 0, 0} },
163 {"popf", 0, 0x9d, X, wl_Suf, { 0, 0, 0} },
164 {"stc", 0, 0xf9, X, NoSuf, { 0, 0, 0} },
165 {"std", 0, 0xfd, X, NoSuf, { 0, 0, 0} },
166 {"sti", 0, 0xfb, X, NoSuf, { 0, 0, 0} },
169 {"add", 2, 0x00, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
170 {"add", 2, 0x83, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
171 {"add", 2, 0x04, X, bwl_Suf|W, { Imm, Acc, 0} },
172 {"add", 2, 0x80, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
174 {"inc", 1, 0x40, X, wl_Suf|ShortForm, { WordReg, 0, 0} },
175 {"inc", 1, 0xfe, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
177 {"sub", 2, 0x28, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
178 {"sub", 2, 0x83, 5, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
179 {"sub", 2, 0x2c, X, bwl_Suf|W, { Imm, Acc, 0} },
180 {"sub", 2, 0x80, 5, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
182 {"dec", 1, 0x48, X, wl_Suf|ShortForm, { WordReg, 0, 0} },
183 {"dec", 1, 0xfe, 1, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
185 {"sbb", 2, 0x18, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
186 {"sbb", 2, 0x83, 3, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
187 {"sbb", 2, 0x1c, X, bwl_Suf|W, { Imm, Acc, 0} },
188 {"sbb", 2, 0x80, 3, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
190 {"cmp", 2, 0x38, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
191 {"cmp", 2, 0x83, 7, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
192 {"cmp", 2, 0x3c, X, bwl_Suf|W, { Imm, Acc, 0} },
193 {"cmp", 2, 0x80, 7, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
195 {"test", 2, 0x84, X, bwl_Suf|W|Modrm, { Reg|AnyMem, Reg, 0} },
196 {"test", 2, 0x84, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0} },
197 {"test", 2, 0xa8, X, bwl_Suf|W, { Imm, Acc, 0} },
198 {"test", 2, 0xf6, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
200 {"and", 2, 0x20, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
201 {"and", 2, 0x83, 4, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
202 {"and", 2, 0x24, X, bwl_Suf|W, { Imm, Acc, 0} },
203 {"and", 2, 0x80, 4, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
205 {"or", 2, 0x08, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
206 {"or", 2, 0x83, 1, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
207 {"or", 2, 0x0c, X, bwl_Suf|W, { Imm, Acc, 0} },
208 {"or", 2, 0x80, 1, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
210 {"xor", 2, 0x30, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
211 {"xor", 2, 0x83, 6, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
212 {"xor", 2, 0x34, X, bwl_Suf|W, { Imm, Acc, 0} },
213 {"xor", 2, 0x80, 6, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
215 /* iclr with 1 operand is really xor with 2 operands. */
216 {"clr", 1, 0x30, X, bwl_Suf|W|Modrm|regKludge, { Reg, 0, 0 } },
218 {"adc", 2, 0x10, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
219 {"adc", 2, 0x83, 2, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
220 {"adc", 2, 0x14, X, bwl_Suf|W, { Imm, Acc, 0} },
221 {"adc", 2, 0x80, 2, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
223 {"neg", 1, 0xf6, 3, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
224 {"not", 1, 0xf6, 2, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
226 {"aaa", 0, 0x37, X, NoSuf, { 0, 0, 0} },
227 {"aas", 0, 0x3f, X, NoSuf, { 0, 0, 0} },
228 {"daa", 0, 0x27, X, NoSuf, { 0, 0, 0} },
229 {"das", 0, 0x2f, X, NoSuf, { 0, 0, 0} },
230 {"aad", 0, 0xd50a, X, NoSuf, { 0, 0, 0} },
231 {"aad", 1, 0xd5, X, NoSuf, { Imm8S, 0, 0} },
232 {"aam", 0, 0xd40a, X, NoSuf, { 0, 0, 0} },
233 {"aam", 1, 0xd4, X, NoSuf, { Imm8S, 0, 0} },
235 /* conversion insns */
236 /* conversion: intel naming */
237 {"cbw", 0, 0x98, X, NoSuf|Size16, { 0, 0, 0} },
238 {"cwde", 0, 0x98, X, NoSuf|Size32, { 0, 0, 0} },
239 {"cwd", 0, 0x99, X, NoSuf|Size16, { 0, 0, 0} },
240 {"cdq", 0, 0x99, X, NoSuf|Size32, { 0, 0, 0} },
242 {"cbtw", 0, 0x98, X, NoSuf|Size16, { 0, 0, 0} },
243 {"cwtl", 0, 0x98, X, NoSuf|Size32, { 0, 0, 0} },
244 {"cwtd", 0, 0x99, X, NoSuf|Size16, { 0, 0, 0} },
245 {"cltd", 0, 0x99, X, NoSuf|Size32, { 0, 0, 0} },
247 /* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are
248 expanding 64-bit multiplies, and *cannot* be selected to accomplish
249 'imul %ebx, %eax' (opcode 0x0faf must be used in this case)
250 These multiplies can only be selected with single operand forms. */
251 {"mul", 1, 0xf6, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
252 {"imul", 1, 0xf6, 5, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
253 {"imul", 2, 0x0faf, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
254 {"imul", 3, 0x6b, X, wl_Suf|ReverseModrm, { Imm8S, WordReg|WordMem, WordReg} },
255 {"imul", 3, 0x69, X, wl_Suf|ReverseModrm, { Imm16|Imm32, WordReg|WordMem, WordReg} },
256 /* imul with 2 operands mimics imul with 3 by putting the register in
257 both i.rm.reg & i.rm.regmem fields. regKludge enables this
259 {"imul", 2, 0x6b, X, wl_Suf|Modrm|regKludge,{ Imm8S, WordReg, 0} },
260 {"imul", 2, 0x69, X, wl_Suf|Modrm|regKludge,{ Imm16|Imm32, WordReg, 0} },
262 {"div", 1, 0xf6, 6, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
263 {"div", 2, 0xf6, 6, bwl_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} },
264 {"idiv", 1, 0xf6, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
265 {"idiv", 2, 0xf6, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} },
267 {"rol", 2, 0xd0, 0, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
268 {"rol", 2, 0xc0, 0, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
269 {"rol", 2, 0xd2, 0, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
270 {"rol", 1, 0xd0, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
272 {"ror", 2, 0xd0, 1, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
273 {"ror", 2, 0xc0, 1, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
274 {"ror", 2, 0xd2, 1, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
275 {"ror", 1, 0xd0, 1, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
277 {"rcl", 2, 0xd0, 2, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
278 {"rcl", 2, 0xc0, 2, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
279 {"rcl", 2, 0xd2, 2, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
280 {"rcl", 1, 0xd0, 2, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
282 {"rcr", 2, 0xd0, 3, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
283 {"rcr", 2, 0xc0, 3, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
284 {"rcr", 2, 0xd2, 3, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
285 {"rcr", 1, 0xd0, 3, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
287 {"sal", 2, 0xd0, 4, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
288 {"sal", 2, 0xc0, 4, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
289 {"sal", 2, 0xd2, 4, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
290 {"sal", 1, 0xd0, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
291 {"shl", 2, 0xd0, 4, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
292 {"shl", 2, 0xc0, 4, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
293 {"shl", 2, 0xd2, 4, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
294 {"shl", 1, 0xd0, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
296 {"shld", 3, 0x0fa4, X, wl_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} },
297 {"shld", 3, 0x0fa5, X, wl_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} },
298 {"shld", 2, 0x0fa5, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
300 {"shr", 2, 0xd0, 5, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
301 {"shr", 2, 0xc0, 5, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
302 {"shr", 2, 0xd2, 5, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
303 {"shr", 1, 0xd0, 5, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
305 {"shrd", 3, 0x0fac, X, wl_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} },
306 {"shrd", 3, 0x0fad, X, wl_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} },
307 {"shrd", 2, 0x0fad, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
309 {"sar", 2, 0xd0, 7, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
310 {"sar", 2, 0xc0, 7, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
311 {"sar", 2, 0xd2, 7, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
312 {"sar", 1, 0xd0, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
314 /* control transfer instructions */
315 {"call", 1, 0xe8, X, wl_Suf|JumpDword, { Disp16|Disp32, 0, 0} },
316 {"call", 1, 0xff, 2, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
318 {"call", 2, 0x9a, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
319 {"lcall", 2, 0x9a, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
320 {"lcall", 1, 0xff, 3, wl_Suf|Modrm, { WordMem, 0, 0} },
322 #define JUMP_PC_RELATIVE 0xeb
323 {"jmp", 1, 0xeb, X, NoSuf|Jump, { Disp, 0, 0} },
324 {"jmp", 1, 0xff, 4, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
326 {"jmp", 2, 0xea, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
327 {"jmp", 1, 0xff, 5, wl_Suf|Modrm, { WordMem, 0, 0} },
328 {"ljmp", 2, 0xea, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
329 {"ljmp", 1, 0xff, 5, wl_Suf|Modrm, { WordMem, 0, 0} },
331 {"ret", 0, 0xc3, X, wl_Suf, { 0, 0, 0} },
332 {"ret", 1, 0xc2, X, wl_Suf, { Imm16, 0, 0} },
333 {"lret", 0, 0xcb, X, wl_Suf, { 0, 0, 0} },
334 {"lret", 1, 0xca, X, wl_Suf, { Imm16, 0, 0} },
335 {"enter", 2, 0xc8, X, wl_Suf, { Imm16, Imm8, 0} },
336 {"leave", 0, 0xc9, X, wl_Suf, { 0, 0, 0} },
338 /* conditional jumps */
339 {"jo", 1, 0x70, X, NoSuf|Jump, { Disp, 0, 0} },
340 {"jno", 1, 0x71, X, NoSuf|Jump, { Disp, 0, 0} },
341 {"jb", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
342 {"jc", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
343 {"jnae", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
344 {"jnb", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
345 {"jnc", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
346 {"jae", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
347 {"je", 1, 0x74, X, NoSuf|Jump, { Disp, 0, 0} },
348 {"jz", 1, 0x74, X, NoSuf|Jump, { Disp, 0, 0} },
349 {"jne", 1, 0x75, X, NoSuf|Jump, { Disp, 0, 0} },
350 {"jnz", 1, 0x75, X, NoSuf|Jump, { Disp, 0, 0} },
351 {"jbe", 1, 0x76, X, NoSuf|Jump, { Disp, 0, 0} },
352 {"jna", 1, 0x76, X, NoSuf|Jump, { Disp, 0, 0} },
353 {"jnbe", 1, 0x77, X, NoSuf|Jump, { Disp, 0, 0} },
354 {"ja", 1, 0x77, X, NoSuf|Jump, { Disp, 0, 0} },
355 {"js", 1, 0x78, X, NoSuf|Jump, { Disp, 0, 0} },
356 {"jns", 1, 0x79, X, NoSuf|Jump, { Disp, 0, 0} },
357 {"jp", 1, 0x7a, X, NoSuf|Jump, { Disp, 0, 0} },
358 {"jpe", 1, 0x7a, X, NoSuf|Jump, { Disp, 0, 0} },
359 {"jnp", 1, 0x7b, X, NoSuf|Jump, { Disp, 0, 0} },
360 {"jpo", 1, 0x7b, X, NoSuf|Jump, { Disp, 0, 0} },
361 {"jl", 1, 0x7c, X, NoSuf|Jump, { Disp, 0, 0} },
362 {"jnge", 1, 0x7c, X, NoSuf|Jump, { Disp, 0, 0} },
363 {"jnl", 1, 0x7d, X, NoSuf|Jump, { Disp, 0, 0} },
364 {"jge", 1, 0x7d, X, NoSuf|Jump, { Disp, 0, 0} },
365 {"jle", 1, 0x7e, X, NoSuf|Jump, { Disp, 0, 0} },
366 {"jng", 1, 0x7e, X, NoSuf|Jump, { Disp, 0, 0} },
367 {"jnle", 1, 0x7f, X, NoSuf|Jump, { Disp, 0, 0} },
368 {"jg", 1, 0x7f, X, NoSuf|Jump, { Disp, 0, 0} },
370 /* jcxz vs. jecxz is chosen on the basis of the address size prefix. */
371 {"jcxz", 1, 0xe3, X, NoSuf|JumpByte|Size16, { Disp, 0, 0} },
372 {"jecxz", 1, 0xe3, X, NoSuf|JumpByte|Size32, { Disp, 0, 0} },
374 /* The loop instructions also use the address size prefix to select
375 %cx rather than %ecx for the loop count, so the `w' form of these
376 instructions emit an address size prefix rather than a data size
378 {"loop", 1, 0xe2, X, wl_Suf|JumpByte, { Disp, 0, 0} },
379 {"loopz", 1, 0xe1, X, wl_Suf|JumpByte, { Disp, 0, 0} },
380 {"loope", 1, 0xe1, X, wl_Suf|JumpByte, { Disp, 0, 0} },
381 {"loopnz", 1, 0xe0, X, wl_Suf|JumpByte, { Disp, 0, 0} },
382 {"loopne", 1, 0xe0, X, wl_Suf|JumpByte, { Disp, 0, 0} },
384 /* set byte on flag instructions */
385 {"seto", 1, 0x0f90, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
386 {"setno", 1, 0x0f91, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
387 {"setb", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
388 {"setc", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
389 {"setnae", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
390 {"setnb", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
391 {"setnc", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
392 {"setae", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
393 {"sete", 1, 0x0f94, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
394 {"setz", 1, 0x0f94, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
395 {"setne", 1, 0x0f95, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
396 {"setnz", 1, 0x0f95, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
397 {"setbe", 1, 0x0f96, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
398 {"setna", 1, 0x0f96, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
399 {"setnbe", 1, 0x0f97, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
400 {"seta", 1, 0x0f97, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
401 {"sets", 1, 0x0f98, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
402 {"setns", 1, 0x0f99, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
403 {"setp", 1, 0x0f9a, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
404 {"setpe", 1, 0x0f9a, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
405 {"setnp", 1, 0x0f9b, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
406 {"setpo", 1, 0x0f9b, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
407 {"setl", 1, 0x0f9c, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
408 {"setnge", 1, 0x0f9c, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
409 {"setnl", 1, 0x0f9d, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
410 {"setge", 1, 0x0f9d, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
411 {"setle", 1, 0x0f9e, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
412 {"setng", 1, 0x0f9e, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
413 {"setnle", 1, 0x0f9f, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
414 {"setg", 1, 0x0f9f, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
416 /* string manipulation */
417 {"cmps", 0, 0xa6, X, bwld_Suf|W|IsString, { 0, 0, 0} },
418 {"cmps", 2, 0xa6, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} },
419 {"scmp", 0, 0xa6, X, bwld_Suf|W|IsString, { 0, 0, 0} },
420 {"scmp", 2, 0xa6, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} },
421 {"ins", 0, 0x6c, X, bwld_Suf|W|IsString, { 0, 0, 0} },
422 {"ins", 2, 0x6c, X, bwld_Suf|W|IsString, { InOutPortReg, AnyMem|EsSeg, 0} },
423 {"outs", 0, 0x6e, X, bwld_Suf|W|IsString, { 0, 0, 0} },
424 {"outs", 2, 0x6e, X, bwld_Suf|W|IsString, { AnyMem, InOutPortReg, 0} },
425 {"lods", 0, 0xac, X, bwld_Suf|W|IsString, { 0, 0, 0} },
426 {"lods", 1, 0xac, X, bwld_Suf|W|IsString, { AnyMem, 0, 0} },
427 {"lods", 2, 0xac, X, bwld_Suf|W|IsString, { AnyMem, Acc, 0} },
428 {"slod", 0, 0xac, X, bwld_Suf|W|IsString, { 0, 0, 0} },
429 {"slod", 1, 0xac, X, bwld_Suf|W|IsString, { AnyMem, 0, 0} },
430 {"slod", 2, 0xac, X, bwld_Suf|W|IsString, { AnyMem, Acc, 0} },
431 {"movs", 0, 0xa4, X, bwld_Suf|W|IsString, { 0, 0, 0} },
432 {"movs", 2, 0xa4, X, bwld_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} },
433 {"smov", 0, 0xa4, X, bwld_Suf|W|IsString, { 0, 0, 0} },
434 {"smov", 2, 0xa4, X, bwld_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} },
435 {"scas", 0, 0xae, X, bwld_Suf|W|IsString, { 0, 0, 0} },
436 {"scas", 1, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
437 {"scas", 2, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} },
438 {"ssca", 0, 0xae, X, bwld_Suf|W|IsString, { 0, 0, 0} },
439 {"ssca", 1, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
440 {"ssca", 2, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} },
441 {"stos", 0, 0xaa, X, bwld_Suf|W|IsString, { 0, 0, 0} },
442 {"stos", 1, 0xaa, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
443 {"stos", 2, 0xaa, X, bwld_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} },
444 {"ssto", 0, 0xaa, X, bwld_Suf|W|IsString, { 0, 0, 0} },
445 {"ssto", 1, 0xaa, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
446 {"ssto", 2, 0xaa, X, bwld_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} },
447 {"xlat", 0, 0xd7, X, b_Suf|IsString, { 0, 0, 0} },
448 {"xlat", 1, 0xd7, X, b_Suf|IsString, { AnyMem, 0, 0} },
450 /* bit manipulation */
451 {"bsf", 2, 0x0fbc, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
452 {"bsr", 2, 0x0fbd, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
453 {"bt", 2, 0x0fa3, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
454 {"bt", 2, 0x0fba, 4, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
455 {"btc", 2, 0x0fbb, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
456 {"btc", 2, 0x0fba, 7, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
457 {"btr", 2, 0x0fb3, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
458 {"btr", 2, 0x0fba, 6, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
459 {"bts", 2, 0x0fab, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
460 {"bts", 2, 0x0fba, 5, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
462 /* interrupts & op. sys insns */
463 /* See gas/config/tc-i386.c for conversion of 'int $3' into the special
465 #define INT_OPCODE 0xcd
466 #define INT3_OPCODE 0xcc
467 {"int", 1, 0xcd, X, NoSuf, { Imm8, 0, 0} },
468 {"int3", 0, 0xcc, X, NoSuf, { 0, 0, 0} },
469 {"into", 0, 0xce, X, NoSuf, { 0, 0, 0} },
470 {"iret", 0, 0xcf, X, wl_Suf, { 0, 0, 0} },
471 /* i386sl, i486sl, later 486, and Pentium */
472 {"rsm", 0, 0x0faa, X, NoSuf, { 0, 0, 0} },
474 {"bound", 2, 0x62, X, wl_Suf|Modrm, { WordReg, WordMem, 0} },
476 {"hlt", 0, 0xf4, X, NoSuf, { 0, 0, 0} },
477 /* nop is actually 'xchgl %eax, %eax' */
478 {"nop", 0, 0x90, X, NoSuf, { 0, 0, 0} },
480 /* protection control */
481 {"arpl", 2, 0x63, X, NoSuf|Modrm|IgnoreSize,{ Reg16, Reg16|ShortMem, 0} },
482 {"lar", 2, 0x0f02, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
483 {"lgdt", 1, 0x0f01, 2, wl_Suf|Modrm, { WordMem, 0, 0} },
484 {"lidt", 1, 0x0f01, 3, wl_Suf|Modrm, { WordMem, 0, 0} },
485 {"lldt", 1, 0x0f00, 2, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
486 {"lmsw", 1, 0x0f01, 6, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
487 {"lsl", 2, 0x0f03, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
488 {"ltr", 1, 0x0f00, 3, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
490 {"sgdt", 1, 0x0f01, 0, wl_Suf|Modrm, { WordMem, 0, 0} },
491 {"sidt", 1, 0x0f01, 1, wl_Suf|Modrm, { WordMem, 0, 0} },
492 {"sldt", 1, 0x0f00, 0, wl_Suf|Modrm, { WordReg|WordMem, 0, 0} },
493 {"smsw", 1, 0x0f01, 4, wl_Suf|Modrm, { WordReg|WordMem, 0, 0} },
494 {"str", 1, 0x0f00, 1, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
496 {"verr", 1, 0x0f00, 4, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
497 {"verw", 1, 0x0f00, 5, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
499 /* floating point instructions */
502 {"fld", 1, 0xd9c0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
503 {"fld", 1, 0xd9, 0, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 <-- mem float/double */
504 {"fld", 1, 0xd9c0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
506 {"fld", 1, 0xdb, 5, x_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem efloat */
507 {"fild", 1, 0xdf, 0, sl_Suf|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 <-- mem word(16)/dword(32) */
509 {"fild", 1, 0xdf, 5, d_Suf|IgnoreSize|Modrm,{ LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
510 {"fildq", 1, 0xdf, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
511 {"fildll", 1, 0xdf, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
512 {"fldt", 1, 0xdb, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem efloat */
513 {"fbld", 1, 0xdf, 4, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem bcd */
516 {"fst", 1, 0xddd0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
517 {"fst", 1, 0xd9, 2, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 --> mem float/double */
518 {"fst", 1, 0xddd0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
519 {"fist", 1, 0xdf, 2, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 --> mem word(16)/dword(32) */
521 /* store (with pop) */
522 {"fstp", 1, 0xddd8, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
523 {"fstp", 1, 0xd9, 3, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 --> mem float/double */
524 {"fstp", 1, 0xddd8, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
526 {"fstp", 1, 0xdb, 7, x_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem efloat */
527 {"fistp", 1, 0xdf, 3, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 --> mem word(16)/dword(32) */
529 {"fistp", 1, 0xdf, 7, d_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
530 {"fistpq", 1, 0xdf, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
531 {"fistpll",1, 0xdf, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
532 {"fstpt", 1, 0xdb, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem efloat */
533 {"fbstp", 1, 0xdf, 6, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem bcd */
535 /* exchange %st<n> with %st0 */
536 {"fxch", 1, 0xd9c8, X, FP|ShortForm, { FloatReg, 0, 0} },
537 {"fxch", 0, 0xd9c9, X, FP, { 0, 0, 0} }, /* alias for fxch %st(1) */
539 /* comparison (without pop) */
540 {"fcom", 1, 0xd8d0, X, FP|ShortForm, { FloatReg, 0, 0} },
541 {"fcom", 0, 0xd8d1, X, FP, { 0, 0, 0} }, /* alias for fcom %st(1) */
542 {"fcom", 1, 0xd8, 2, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* compare %st0, mem float/double */
543 {"fcom", 1, 0xd8d0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
544 {"ficom", 1, 0xde, 2, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* compare %st0, mem word/dword */
546 /* comparison (with pop) */
547 {"fcomp", 1, 0xd8d8, X, FP|ShortForm, { FloatReg, 0, 0} },
548 {"fcomp", 0, 0xd8d9, X, FP, { 0, 0, 0} }, /* alias for fcomp %st(1) */
549 {"fcomp", 1, 0xd8, 3, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* compare %st0, mem float/double */
550 {"fcomp", 1, 0xd8d8, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
551 {"ficomp", 1, 0xde, 3, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* compare %st0, mem word/dword */
552 {"fcompp", 0, 0xded9, X, FP, { 0, 0, 0} }, /* compare %st0, %st1 & pop 2 */
554 /* unordered comparison (with pop) */
555 {"fucom", 1, 0xdde0, X, FP|ShortForm, { FloatReg, 0, 0} },
556 {"fucom", 0, 0xdde1, X, FP, { 0, 0, 0} }, /* alias for fucom %st(1) */
557 {"fucomp", 1, 0xdde8, X, FP|ShortForm, { FloatReg, 0, 0} },
558 {"fucomp", 0, 0xdde9, X, FP, { 0, 0, 0} }, /* alias for fucomp %st(1) */
559 {"fucompp",0, 0xdae9, X, FP, { 0, 0, 0} }, /* ucompare %st0, %st1 & pop twice */
561 {"ftst", 0, 0xd9e4, X, FP, { 0, 0, 0} }, /* test %st0 */
562 {"fxam", 0, 0xd9e5, X, FP, { 0, 0, 0} }, /* examine %st0 */
564 /* load constants into %st0 */
565 {"fld1", 0, 0xd9e8, X, FP, { 0, 0, 0} }, /* %st0 <-- 1.0 */
566 {"fldl2t", 0, 0xd9e9, X, FP, { 0, 0, 0} }, /* %st0 <-- log2(10) */
567 {"fldl2e", 0, 0xd9ea, X, FP, { 0, 0, 0} }, /* %st0 <-- log2(e) */
568 {"fldpi", 0, 0xd9eb, X, FP, { 0, 0, 0} }, /* %st0 <-- pi */
569 {"fldlg2", 0, 0xd9ec, X, FP, { 0, 0, 0} }, /* %st0 <-- log10(2) */
570 {"fldln2", 0, 0xd9ed, X, FP, { 0, 0, 0} }, /* %st0 <-- ln(2) */
571 {"fldz", 0, 0xd9ee, X, FP, { 0, 0, 0} }, /* %st0 <-- 0.0 */
576 {"fadd", 2, 0xd8c0, X, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
577 {"fadd", 1, 0xd8c0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* alias for fadd %st(i), %st */
579 {"fadd", 0, 0xdec1, X, FP|Ugh, { 0, 0, 0} }, /* alias for faddp */
581 {"fadd", 1, 0xd8, 0, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
582 {"fiadd", 1, 0xde, 0, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
584 {"faddp", 2, 0xdec0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
585 {"faddp", 1, 0xdec0, X, FP|ShortForm, { FloatReg, 0, 0} },
586 {"faddp", 0, 0xdec1, X, FP, { 0, 0, 0} }, /* alias for faddp %st, %st(1) */
587 {"faddp", 2, 0xdec0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
590 {"fsub", 2, 0xd8e0, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
591 {"fsub", 1, 0xd8e0, X, FP|ShortForm, { FloatReg, 0, 0} },
593 {"fsub", 0, 0xdee1, X, FP|Ugh, { 0, 0, 0} }, /* alias for fsubp */
595 {"fsub", 1, 0xd8, 4, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
596 {"fisub", 1, 0xde, 4, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
599 {"fsubp", 2, 0xdee0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
600 {"fsubp", 1, 0xdee0, X, FP|ShortForm, { FloatReg, 0, 0} },
601 {"fsubp", 0, 0xdee1, X, FP, { 0, 0, 0} },
602 {"fsubp", 2, 0xdee0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
604 {"fsubp", 2, 0xdee8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
605 {"fsubp", 1, 0xdee8, X, FP|ShortForm, { FloatReg, 0, 0} },
606 {"fsubp", 0, 0xdee9, X, FP, { 0, 0, 0} },
609 /* subtract reverse */
610 {"fsubr", 2, 0xd8e8, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
611 {"fsubr", 1, 0xd8e8, X, FP|ShortForm, { FloatReg, 0, 0} },
613 {"fsubr", 0, 0xdee9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fsubrp */
615 {"fsubr", 1, 0xd8, 5, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
616 {"fisubr", 1, 0xde, 5, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
619 {"fsubrp", 2, 0xdee8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
620 {"fsubrp", 1, 0xdee8, X, FP|ShortForm, { FloatReg, 0, 0} },
621 {"fsubrp", 0, 0xdee9, X, FP, { 0, 0, 0} },
622 {"fsubrp", 2, 0xdee8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
624 {"fsubrp", 2, 0xdee0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
625 {"fsubrp", 1, 0xdee0, X, FP|ShortForm, { FloatReg, 0, 0} },
626 {"fsubrp", 0, 0xdee1, X, FP, { 0, 0, 0} },
630 {"fmul", 2, 0xd8c8, X, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
631 {"fmul", 1, 0xd8c8, X, FP|ShortForm, { FloatReg, 0, 0} },
633 {"fmul", 0, 0xdec9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fmulp */
635 {"fmul", 1, 0xd8, 1, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
636 {"fimul", 1, 0xde, 1, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
638 {"fmulp", 2, 0xdec8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
639 {"fmulp", 1, 0xdec8, X, FP|ShortForm, { FloatReg, 0, 0} },
640 {"fmulp", 0, 0xdec9, X, FP, { 0, 0, 0} },
641 {"fmulp", 2, 0xdec8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
644 {"fdiv", 2, 0xd8f0, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
645 {"fdiv", 1, 0xd8f0, X, FP|ShortForm, { FloatReg, 0, 0} },
647 {"fdiv", 0, 0xdef1, X, FP|Ugh, { 0, 0, 0} }, /* alias for fdivp */
649 {"fdiv", 1, 0xd8, 6, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
650 {"fidiv", 1, 0xde, 6, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
653 {"fdivp", 2, 0xdef0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
654 {"fdivp", 1, 0xdef0, X, FP|ShortForm, { FloatReg, 0, 0} },
655 {"fdivp", 0, 0xdef1, X, FP, { 0, 0, 0} },
656 {"fdivp", 2, 0xdef0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
658 {"fdivp", 2, 0xdef8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
659 {"fdivp", 1, 0xdef8, X, FP|ShortForm, { FloatReg, 0, 0} },
660 {"fdivp", 0, 0xdef9, X, FP, { 0, 0, 0} },
664 {"fdivr", 2, 0xd8f8, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
665 {"fdivr", 1, 0xd8f8, X, FP|ShortForm, { FloatReg, 0, 0} },
667 {"fdivr", 0, 0xdef9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fdivrp */
669 {"fdivr", 1, 0xd8, 7, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
670 {"fidivr", 1, 0xde, 7, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
673 {"fdivrp", 2, 0xdef8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
674 {"fdivrp", 1, 0xdef8, X, FP|ShortForm, { FloatReg, 0, 0} },
675 {"fdivrp", 0, 0xdef9, X, FP, { 0, 0, 0} },
676 {"fdivrp", 2, 0xdef8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
678 {"fdivrp", 2, 0xdef0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
679 {"fdivrp", 1, 0xdef0, X, FP|ShortForm, { FloatReg, 0, 0} },
680 {"fdivrp", 0, 0xdef1, X, FP, { 0, 0, 0} },
683 {"f2xm1", 0, 0xd9f0, X, FP, { 0, 0, 0} },
684 {"fyl2x", 0, 0xd9f1, X, FP, { 0, 0, 0} },
685 {"fptan", 0, 0xd9f2, X, FP, { 0, 0, 0} },
686 {"fpatan", 0, 0xd9f3, X, FP, { 0, 0, 0} },
687 {"fxtract",0, 0xd9f4, X, FP, { 0, 0, 0} },
688 {"fprem1", 0, 0xd9f5, X, FP, { 0, 0, 0} },
689 {"fdecstp",0, 0xd9f6, X, FP, { 0, 0, 0} },
690 {"fincstp",0, 0xd9f7, X, FP, { 0, 0, 0} },
691 {"fprem", 0, 0xd9f8, X, FP, { 0, 0, 0} },
692 {"fyl2xp1",0, 0xd9f9, X, FP, { 0, 0, 0} },
693 {"fsqrt", 0, 0xd9fa, X, FP, { 0, 0, 0} },
694 {"fsincos",0, 0xd9fb, X, FP, { 0, 0, 0} },
695 {"frndint",0, 0xd9fc, X, FP, { 0, 0, 0} },
696 {"fscale", 0, 0xd9fd, X, FP, { 0, 0, 0} },
697 {"fsin", 0, 0xd9fe, X, FP, { 0, 0, 0} },
698 {"fcos", 0, 0xd9ff, X, FP, { 0, 0, 0} },
699 {"fchs", 0, 0xd9e0, X, FP, { 0, 0, 0} },
700 {"fabs", 0, 0xd9e1, X, FP, { 0, 0, 0} },
702 /* processor control */
703 {"fninit", 0, 0xdbe3, X, FP, { 0, 0, 0} },
704 {"finit", 0, 0xdbe3, X, FP|FWait, { 0, 0, 0} },
705 {"fldcw", 1, 0xd9, 5, FP|Modrm, { ShortMem, 0, 0} },
706 {"fnstcw", 1, 0xd9, 7, FP|Modrm, { ShortMem, 0, 0} },
707 {"fstcw", 1, 0xd9, 7, FP|FWait|Modrm, { ShortMem, 0, 0} },
708 {"fnstsw", 1, 0xdfe0, X, FP, { Acc, 0, 0} },
709 {"fnstsw", 1, 0xdd, 7, FP|Modrm, { ShortMem, 0, 0} },
710 {"fnstsw", 0, 0xdfe0, X, FP, { 0, 0, 0} },
711 {"fstsw", 1, 0xdfe0, X, FP|FWait, { Acc, 0, 0} },
712 {"fstsw", 1, 0xdd, 7, FP|FWait|Modrm, { ShortMem, 0, 0} },
713 {"fstsw", 0, 0xdfe0, X, FP|FWait, { 0, 0, 0} },
714 {"fnclex", 0, 0xdbe2, X, FP, { 0, 0, 0} },
715 {"fclex", 0, 0xdbe2, X, FP|FWait, { 0, 0, 0} },
716 /* Short forms of fldenv, fstenv use data size prefix.
717 FIXME: Are these the right suffixes? */
718 {"fnstenv",1, 0xd9, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
719 {"fstenv", 1, 0xd9, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
720 {"fldenv", 1, 0xd9, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
721 {"fnsave", 1, 0xdd, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
722 {"fsave", 1, 0xdd, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
723 {"frstor", 1, 0xdd, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
725 {"ffree", 1, 0xddc0, X, FP|ShortForm, { FloatReg, 0, 0} },
726 /* P6:free st(i), pop st */
727 {"ffreep", 1, 0xdfc0, X, FP|ShortForm, { FloatReg, 0, 0} },
728 {"fnop", 0, 0xd9d0, X, FP, { 0, 0, 0} },
729 #define FWAIT_OPCODE 0x9b
730 {"fwait", 0, 0x9b, X, FP, { 0, 0, 0} },
733 opcode prefixes; we allow them as seperate insns too
735 #define ADDR_PREFIX_OPCODE 0x67
736 {"addr16", 0, 0x67, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
737 {"addr32", 0, 0x67, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
738 {"aword", 0, 0x67, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
739 {"adword", 0, 0x67, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
740 #define DATA_PREFIX_OPCODE 0x66
741 {"data16", 0, 0x66, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
742 {"data32", 0, 0x66, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
743 {"word", 0, 0x66, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
744 {"dword", 0, 0x66, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
745 #define LOCK_PREFIX_OPCODE 0xf0
746 {"lock", 0, 0xf0, X, NoSuf|IsPrefix, { 0, 0, 0} },
747 {"wait", 0, 0x9b, X, NoSuf|IsPrefix, { 0, 0, 0} },
748 #define CS_PREFIX_OPCODE 0x2e
749 {"cs", 0, 0x2e, X, NoSuf|IsPrefix, { 0, 0, 0} },
750 #define DS_PREFIX_OPCODE 0x3e
751 {"ds", 0, 0x3e, X, NoSuf|IsPrefix, { 0, 0, 0} },
752 #define ES_PREFIX_OPCODE 0x26
753 {"es", 0, 0x26, X, NoSuf|IsPrefix, { 0, 0, 0} },
754 #define FS_PREFIX_OPCODE 0x64
755 {"fs", 0, 0x64, X, NoSuf|IsPrefix, { 0, 0, 0} },
756 #define GS_PREFIX_OPCODE 0x65
757 {"gs", 0, 0x65, X, NoSuf|IsPrefix, { 0, 0, 0} },
758 #define SS_PREFIX_OPCODE 0x36
759 {"ss", 0, 0x36, X, NoSuf|IsPrefix, { 0, 0, 0} },
760 #define REPNE_PREFIX_OPCODE 0xf2
761 #define REPE_PREFIX_OPCODE 0xf3
762 {"rep", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
763 {"repe", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
764 {"repz", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
765 {"repne", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
766 {"repnz", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
770 {"bswap", 1, 0x0fc8, X, NoSuf|ShortForm, { Reg32,0,0 } },
771 {"xadd", 2, 0x0fc0, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
772 {"cmpxchg", 2, 0x0fb0, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
773 {"invd", 0, 0x0f08, X, NoSuf, { 0, 0, 0} },
774 {"wbinvd", 0, 0x0f09, X, NoSuf, { 0, 0, 0} },
775 {"invlpg", 1, 0x0f01, 7, NoSuf|Modrm, { AnyMem, 0, 0} },
777 /* 586 and late 486 extensions */
778 {"cpuid", 0, 0x0fa2, X, NoSuf, { 0, 0, 0} },
780 /* Pentium extensions */
781 {"wrmsr", 0, 0x0f30, X, NoSuf, { 0, 0, 0} },
782 {"rdtsc", 0, 0x0f31, X, NoSuf, { 0, 0, 0} },
783 {"rdmsr", 0, 0x0f32, X, NoSuf, { 0, 0, 0} },
784 {"cmpxchg8b",1,0x0fc7, 1, NoSuf|Modrm, { LLongMem, 0, 0} },
785 {"sysenter", 0, 0x0f34, X, NoSuf, { 0, 0, 0} },
786 {"sysexit", 0, 0x0f35, X, NoSuf, { 0, 0, 0} },
787 {"fxsave", 1, 0x0fae, 0, FP|Modrm, { LLongMem, 0, 0} },
788 {"fxrstor", 1, 0x0fae, 1, FP|Modrm, { LLongMem, 0, 0} },
790 /* Pentium Pro extensions */
791 {"rdpmc", 0, 0x0f33, X, NoSuf, { 0, 0, 0} },
793 {"ud2", 0, 0x0f0b, X, NoSuf, { 0, 0, 0} }, /* official undefined instr. */
794 {"ud2a", 0, 0x0f0b, X, NoSuf, { 0, 0, 0} }, /* alias for ud2 */
795 {"ud2b", 0, 0x0fb9, X, NoSuf, { 0, 0, 0} }, /* 2nd. official undefined instr. */
797 {"cmovo", 2, 0x0f40, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
798 {"cmovno", 2, 0x0f41, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
799 {"cmovb", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
800 {"cmovc", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
801 {"cmovnae", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
802 {"cmovae", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
803 {"cmovnc", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
804 {"cmovnb", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
805 {"cmove", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
806 {"cmovz", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
807 {"cmovne", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
808 {"cmovnz", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
809 {"cmovbe", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
810 {"cmovna", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
811 {"cmova", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
812 {"cmovnbe", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
813 {"cmovs", 2, 0x0f48, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
814 {"cmovns", 2, 0x0f49, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
815 {"cmovp", 2, 0x0f4a, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
816 {"cmovnp", 2, 0x0f4b, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
817 {"cmovl", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
818 {"cmovnge", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
819 {"cmovge", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
820 {"cmovnl", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
821 {"cmovle", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
822 {"cmovng", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
823 {"cmovg", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
824 {"cmovnle", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
826 {"fcmovb", 2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
827 {"fcmovnae",2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
828 {"fcmove", 2, 0xdac8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
829 {"fcmovbe", 2, 0xdad0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
830 {"fcmovna", 2, 0xdad0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
831 {"fcmovu", 2, 0xdad8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
832 {"fcmovae", 2, 0xdbc0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
833 {"fcmovnb", 2, 0xdbc0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
834 {"fcmovne", 2, 0xdbc8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
835 {"fcmova", 2, 0xdbd0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
836 {"fcmovnbe",2, 0xdbd0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
837 {"fcmovnu", 2, 0xdbd8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
839 {"fcomi", 2, 0xdbf0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
840 {"fcomi", 0, 0xdbf1, X, NoSuf|ShortForm, { 0, 0, 0} },
841 {"fcomi", 1, 0xdbf0, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
842 {"fucomi", 2, 0xdbe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
843 {"fucomi", 0, 0xdbe9, X, NoSuf|ShortForm, { 0, 0, 0} },
844 {"fucomi", 1, 0xdbe8, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
845 {"fcomip", 2, 0xdff0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
846 {"fcompi", 2, 0xdff0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
847 {"fcompi", 0, 0xdff1, X, NoSuf|ShortForm, { 0, 0, 0} },
848 {"fcompi", 1, 0xdff0, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
849 {"fucomip", 2, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
850 {"fucompi", 2, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
851 {"fucompi", 0, 0xdfe9, X, NoSuf|ShortForm, { 0, 0, 0} },
852 {"fucompi", 1, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
854 /* MMX instructions. */
856 {"emms", 0, 0x0f77, X, NoSuf, { 0, 0, 0 } },
857 {"movd", 2, 0x0f6e, X, NoSuf|Modrm, { Reg32|LongMem, RegMMX, 0 } },
858 {"movd", 2, 0x0f7e, X, NoSuf|Modrm, { RegMMX, Reg32|LongMem, 0 } },
859 {"movq", 2, 0x0f6f, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
860 {"movq", 2, 0x0f7f, X, NoSuf|Modrm, { RegMMX, RegMMX|LongMem, 0 } },
861 {"packssdw", 2, 0x0f6b, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
862 {"packsswb", 2, 0x0f63, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
863 {"packuswb", 2, 0x0f67, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
864 {"paddb", 2, 0x0ffc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
865 {"paddw", 2, 0x0ffd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
866 {"paddd", 2, 0x0ffe, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
867 {"paddsb", 2, 0x0fec, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
868 {"paddsw", 2, 0x0fed, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
869 {"paddusb", 2, 0x0fdc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
870 {"paddusw", 2, 0x0fdd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
871 {"pand", 2, 0x0fdb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
872 {"pandn", 2, 0x0fdf, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
873 {"pcmpeqb", 2, 0x0f74, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
874 {"pcmpeqw", 2, 0x0f75, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
875 {"pcmpeqd", 2, 0x0f76, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
876 {"pcmpgtb", 2, 0x0f64, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
877 {"pcmpgtw", 2, 0x0f65, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
878 {"pcmpgtd", 2, 0x0f66, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
879 {"pmaddwd", 2, 0x0ff5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
880 {"pmulhw", 2, 0x0fe5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
881 {"pmullw", 2, 0x0fd5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
882 {"por", 2, 0x0feb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
883 {"psllw", 2, 0x0ff1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
884 {"psllw", 2, 0x0f71, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
885 {"pslld", 2, 0x0ff2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
886 {"pslld", 2, 0x0f72, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
887 {"psllq", 2, 0x0ff3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
888 {"psllq", 2, 0x0f73, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
889 {"psraw", 2, 0x0fe1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
890 {"psraw", 2, 0x0f71, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
891 {"psrad", 2, 0x0fe2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
892 {"psrad", 2, 0x0f72, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
893 {"psrlw", 2, 0x0fd1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
894 {"psrlw", 2, 0x0f71, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
895 {"psrld", 2, 0x0fd2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
896 {"psrld", 2, 0x0f72, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
897 {"psrlq", 2, 0x0fd3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
898 {"psrlq", 2, 0x0f73, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
899 {"psubb", 2, 0x0ff8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
900 {"psubw", 2, 0x0ff9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
901 {"psubd", 2, 0x0ffa, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
902 {"psubsb", 2, 0x0fe8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
903 {"psubsw", 2, 0x0fe9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
904 {"psubusb", 2, 0x0fd8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
905 {"psubusw", 2, 0x0fd9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
906 {"punpckhbw",2, 0x0f68, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
907 {"punpckhwd",2, 0x0f69, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
908 {"punpckhdq",2, 0x0f6a, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
909 {"punpcklbw",2, 0x0f60, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
910 {"punpcklwd",2, 0x0f61, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
911 {"punpckldq",2, 0x0f62, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
912 {"pxor", 2, 0x0fef, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
915 /* AMD 3DNow! instructions */
916 #define AMD_3DNOW_OPCODE 0x0f0f
918 {"prefetch", 1, 0x0f0d, 0, NoSuf|Modrm, { ByteMem, 0, 0 } },
919 {"prefetchw",1, 0x0f0d, 1, NoSuf|Modrm, { ByteMem, 0, 0 } },
920 {"femms", 0, 0x0f0e, X, NoSuf, { 0, 0, 0 } },
921 {"pavgusb", 2, 0x0f0f, 0xbf, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
922 {"pf2id", 2, 0x0f0f, 0x1d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
923 {"pfacc", 2, 0x0f0f, 0xae, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
924 {"pfadd", 2, 0x0f0f, 0x9e, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
925 {"pfcmpeq", 2, 0x0f0f, 0xb0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
926 {"pfcmpge", 2, 0x0f0f, 0x90, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
927 {"pfcmpgt", 2, 0x0f0f, 0xa0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
928 {"pfmax", 2, 0x0f0f, 0xa4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
929 {"pfmin", 2, 0x0f0f, 0x94, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
930 {"pfmul", 2, 0x0f0f, 0xb4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
931 {"pfrcp", 2, 0x0f0f, 0x96, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
932 {"pfrcpit1", 2, 0x0f0f, 0xa6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
933 {"pfrcpit2", 2, 0x0f0f, 0xb6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
934 {"pfrsqit1", 2, 0x0f0f, 0xa7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
935 {"pfrsqrt", 2, 0x0f0f, 0x97, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
936 {"pfsub", 2, 0x0f0f, 0x9a, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
937 {"pfsubr", 2, 0x0f0f, 0xaa, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
938 {"pi2fd", 2, 0x0f0f, 0x0d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
939 {"pmulhrw", 2, 0x0f0f, 0xb7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
941 {NULL, 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
958 #define MAX_MNEM_SIZE 16 /* for parsing insn mnemonics from input */
961 /* 386 register table */
963 static const reg_entry i386_regtab[] = {
966 {"cl", Reg8|ShiftCount, 1},
974 {"ax", Reg16|Acc, 0},
976 {"dx", Reg16|InOutPortReg, 2},
977 {"bx", Reg16|BaseIndex, 3},
979 {"bp", Reg16|BaseIndex, 5},
980 {"si", Reg16|BaseIndex, 6},
981 {"di", Reg16|BaseIndex, 7},
983 {"eax", Reg32|BaseIndex|Acc, 0},
984 {"ecx", Reg32|BaseIndex, 1},
985 {"edx", Reg32|BaseIndex, 2},
986 {"ebx", Reg32|BaseIndex, 3},
988 {"ebp", Reg32|BaseIndex, 5},
989 {"esi", Reg32|BaseIndex, 6},
990 {"edi", Reg32|BaseIndex, 7},
991 /* segment registers */
998 /* control registers */
1000 {"cr1", Control, 1},
1001 {"cr2", Control, 2},
1002 {"cr3", Control, 3},
1003 {"cr4", Control, 4},
1004 {"cr5", Control, 5},
1005 {"cr6", Control, 6},
1006 {"cr7", Control, 7},
1007 /* debug registers */
1024 /* test registers */
1033 /* float registers */
1034 {"st(0)", FloatReg|FloatAcc, 0},
1035 {"st", FloatReg|FloatAcc, 0},
1036 {"st(1)", FloatReg, 1},
1037 {"st(2)", FloatReg, 2},
1038 {"st(3)", FloatReg, 3},
1039 {"st(4)", FloatReg, 4},
1040 {"st(5)", FloatReg, 5},
1041 {"st(6)", FloatReg, 6},
1042 {"st(7)", FloatReg, 7},
1053 #define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */
1056 static const seg_entry cs = { "cs", 0x2e };
1057 static const seg_entry ds = { "ds", 0x3e };
1058 static const seg_entry ss = { "ss", 0x36 };
1059 static const seg_entry es = { "es", 0x26 };
1060 static const seg_entry fs = { "fs", 0x64 };
1061 static const seg_entry gs = { "gs", 0x65 };
1063 /* end of opcode/i386.h */