OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains3x.git] / include / opcode / i386.h
1 /* opcode/i386.h -- Intel 80386 opcode table
2    Copyright 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation.
3
4 This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
5
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.
10
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.
15
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.  */
19
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
24    we're stuck with it.
25
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 !
29
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.  */
33
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
39 #endif
40
41
42 static const template i386_optab[] = {
43
44 #define X None
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)
67 #if UNIXWARE_COMPAT
68 #define FloatDR FloatD
69 #else
70 #define FloatDR (FloatD|FloatR)
71 #endif
72
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} },
90
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} },
97 /* Intel Syntax */
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} },
100
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} },
104 /* Intel Syntax */
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} },
107
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 } },
115 /* push all */
116 {"pusha",  0,   0x60, X, wl_Suf,                { 0, 0, 0 } },
117
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 } },
124 /* pop all */
125 {"popa",   0,   0x61, X, wl_Suf,                { 0, 0, 0 } },
126
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 } },
133
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 } },
143
144 /* load effective address */
145 {"lea",    2, 0x8d,   X, wl_Suf|Modrm,          { WordMem, WordReg, 0 } },
146
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} },
153
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} },
167
168 /* arithmetic */
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} },
173
174 {"inc",    1,   0x40, X, wl_Suf|ShortForm,      { WordReg, 0, 0} },
175 {"inc",    1,   0xfe, 0, bwl_Suf|W|Modrm,       { Reg|AnyMem, 0, 0} },
176
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} },
181
182 {"dec",    1,   0x48, X, wl_Suf|ShortForm,      { WordReg, 0, 0} },
183 {"dec",    1,   0xfe, 1, bwl_Suf|W|Modrm,       { Reg|AnyMem, 0, 0} },
184
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} },
189
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} },
194
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} },
199
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} },
204
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} },
209
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} },
214
215 /* iclr with 1 operand is really xor with 2 operands. */
216 {"clr",    1,   0x30, X, bwl_Suf|W|Modrm|regKludge,     { Reg, 0, 0 } },
217
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} },
222
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} },
225
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} },
234
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} },
241 /*  att naming */
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} },
246
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
258    transformation.  */
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} },
261
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} },
266
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} },
271
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} },
276
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} },
281
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} },
286
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} },
295
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} },
299
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} },
304
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} },
308
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} },
313
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} },
317 /* Intel Syntax */
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} },
321
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} },
325 /* Intel Syntax */
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} },
330
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} },
337
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} },
369
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} },
373
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
377    prefix.  */
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} },
383
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} },
415
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} },
449
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} },
461
462 /* interrupts & op. sys insns */
463 /* See gas/config/tc-i386.c for conversion of 'int $3' into the special
464    int 3 insn. */
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} },
473
474 {"bound",  2,   0x62, X, wl_Suf|Modrm,          { WordReg, WordMem, 0} },
475
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} },
479
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} },
489
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} },
495
496 {"verr",   1, 0x0f00, 4, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
497 {"verw",   1, 0x0f00, 5, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
498
499 /* floating point instructions */
500
501 /* load */
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} },
505 /* Intel Syntax */
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) */
508 /* Intel Syntax */
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 */
514
515 /* store (no pop) */
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) */
520
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} },
525 /* Intel Syntax */
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) */
528 /* Intel Syntax */
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 */
534
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) */
538
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 */
545
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 */
553
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 */
560
561 {"ftst",   0, 0xd9e4, X, FP,                    { 0, 0, 0} },        /* test %st0 */
562 {"fxam",   0, 0xd9e5, X, FP,                    { 0, 0, 0} },        /* examine %st0 */
563
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 */
572
573 /* arithmetic */
574
575 /* add */
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 */
578 #if UNIXWARE_COMPAT
579 {"fadd",   0, 0xdec1, X, FP|Ugh,                { 0, 0, 0} },        /* alias for faddp */
580 #endif
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} },
583
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} },
588
589 /* subtract */
590 {"fsub",   2, 0xd8e0, X, FP|ShortForm|FloatDR,  { FloatReg, FloatAcc, 0} },
591 {"fsub",   1, 0xd8e0, X, FP|ShortForm,          { FloatReg, 0, 0} },
592 #if UNIXWARE_COMPAT
593 {"fsub",   0, 0xdee1, X, FP|Ugh,                { 0, 0, 0} },        /* alias for fsubp */
594 #endif
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} },
597
598 #if UNIXWARE_COMPAT
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} },
603 #else
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} },
607 #endif
608
609 /* subtract reverse */
610 {"fsubr",  2, 0xd8e8, X, FP|ShortForm|FloatDR,  { FloatReg, FloatAcc, 0} },
611 {"fsubr",  1, 0xd8e8, X, FP|ShortForm,          { FloatReg, 0, 0} },
612 #if UNIXWARE_COMPAT
613 {"fsubr",  0, 0xdee9, X, FP|Ugh,                { 0, 0, 0} },        /* alias for fsubrp */
614 #endif
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} },
617
618 #if UNIXWARE_COMPAT
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} },
623 #else
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} },
627 #endif
628
629 /* multiply */
630 {"fmul",   2, 0xd8c8, X, FP|ShortForm|FloatD,   { FloatReg, FloatAcc, 0} },
631 {"fmul",   1, 0xd8c8, X, FP|ShortForm,          { FloatReg, 0, 0} },
632 #if UNIXWARE_COMPAT
633 {"fmul",   0, 0xdec9, X, FP|Ugh,                { 0, 0, 0} },        /* alias for fmulp */
634 #endif
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} },
637
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} },
642
643 /* divide */
644 {"fdiv",   2, 0xd8f0, X, FP|ShortForm|FloatDR,  { FloatReg, FloatAcc, 0} },
645 {"fdiv",   1, 0xd8f0, X, FP|ShortForm,          { FloatReg, 0, 0} },
646 #if UNIXWARE_COMPAT
647 {"fdiv",   0, 0xdef1, X, FP|Ugh,                { 0, 0, 0} },        /* alias for fdivp */
648 #endif
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} },
651
652 #if UNIXWARE_COMPAT
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} },
657 #else
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} },
661 #endif
662
663 /* divide reverse */
664 {"fdivr",  2, 0xd8f8, X, FP|ShortForm|FloatDR,  { FloatReg, FloatAcc, 0} },
665 {"fdivr",  1, 0xd8f8, X, FP|ShortForm,          { FloatReg, 0, 0} },
666 #if UNIXWARE_COMPAT
667 {"fdivr",  0, 0xdef9, X, FP|Ugh,                { 0, 0, 0} },        /* alias for fdivrp */
668 #endif
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} },
671
672 #if UNIXWARE_COMPAT
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} },
677 #else
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} },
681 #endif
682
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} },
701
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} },
724
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} },
731
732 /*
733   opcode prefixes; we allow them as seperate insns too
734 */
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} },
767
768 /* 486 extensions */
769
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} },
776
777 /* 586 and late 486 extensions */
778 {"cpuid",   0, 0x0fa2, X, NoSuf,                { 0, 0, 0} },
779
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} },
789
790 /* Pentium Pro extensions */
791 {"rdpmc",   0, 0x0f33, X, NoSuf,                { 0, 0, 0} },
792
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. */
796
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} },
825
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} },
838
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} },
853
854 /* MMX instructions.  */
855
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 } },
913
914   
915 /* AMD 3DNow! instructions */
916 #define AMD_3DNOW_OPCODE 0x0f0f
917
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 } },
940
941 {NULL, 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
942 };
943 #undef X
944 #undef ReverseModrm
945 #undef NoSuf
946 #undef b_Suf
947 #undef w_Suf
948 #undef l_Suf
949 #undef bw_Suf
950 #undef bl_Suf
951 #undef wl_Suf
952 #undef sl_Suf
953 #undef bwl_Suf
954 #undef FP
955 #undef l_FP
956 #undef sl_FP
957
958 #define MAX_MNEM_SIZE 16        /* for parsing insn mnemonics from input */
959
960
961 /* 386 register table */
962
963 static const reg_entry i386_regtab[] = {
964   /* 8 bit regs */
965   {"al", Reg8|Acc, 0},
966   {"cl", Reg8|ShiftCount, 1},
967   {"dl", Reg8, 2},
968   {"bl", Reg8, 3},
969   {"ah", Reg8, 4},
970   {"ch", Reg8, 5},
971   {"dh", Reg8, 6},
972   {"bh", Reg8, 7},
973   /* 16 bit regs */
974   {"ax", Reg16|Acc, 0},
975   {"cx", Reg16, 1},
976   {"dx", Reg16|InOutPortReg, 2},
977   {"bx", Reg16|BaseIndex, 3},
978   {"sp", Reg16, 4},
979   {"bp", Reg16|BaseIndex, 5},
980   {"si", Reg16|BaseIndex, 6},
981   {"di", Reg16|BaseIndex, 7},
982   /* 32 bit regs */
983   {"eax", Reg32|BaseIndex|Acc, 0},
984   {"ecx", Reg32|BaseIndex, 1},
985   {"edx", Reg32|BaseIndex, 2},
986   {"ebx", Reg32|BaseIndex, 3},
987   {"esp", Reg32, 4},
988   {"ebp", Reg32|BaseIndex, 5},
989   {"esi", Reg32|BaseIndex, 6},
990   {"edi", Reg32|BaseIndex, 7},
991   /* segment registers */
992   {"es", SReg2, 0},
993   {"cs", SReg2, 1},
994   {"ss", SReg2, 2},
995   {"ds", SReg2, 3},
996   {"fs", SReg3, 4},
997   {"gs", SReg3, 5},
998   /* control registers */
999   {"cr0", Control, 0},
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 */
1008   {"db0", Debug, 0},
1009   {"db1", Debug, 1},
1010   {"db2", Debug, 2},
1011   {"db3", Debug, 3},
1012   {"db4", Debug, 4},
1013   {"db5", Debug, 5},
1014   {"db6", Debug, 6},
1015   {"db7", Debug, 7},
1016   {"dr0", Debug, 0},
1017   {"dr1", Debug, 1},
1018   {"dr2", Debug, 2},
1019   {"dr3", Debug, 3},
1020   {"dr4", Debug, 4},
1021   {"dr5", Debug, 5},
1022   {"dr6", Debug, 6},
1023   {"dr7", Debug, 7},
1024   /* test registers */
1025   {"tr0", Test, 0},
1026   {"tr1", Test, 1},
1027   {"tr2", Test, 2},
1028   {"tr3", Test, 3},
1029   {"tr4", Test, 4},
1030   {"tr5", Test, 5},
1031   {"tr6", Test, 6},
1032   {"tr7", Test, 7},
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},
1043   {"mm0", RegMMX, 0},
1044   {"mm1", RegMMX, 1},
1045   {"mm2", RegMMX, 2},
1046   {"mm3", RegMMX, 3},
1047   {"mm4", RegMMX, 4},
1048   {"mm5", RegMMX, 5},
1049   {"mm6", RegMMX, 6},
1050   {"mm7", RegMMX, 7}
1051 };
1052
1053 #define MAX_REG_NAME_SIZE 8     /* for parsing register names from input */
1054
1055 /* segment stuff */
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 };
1062
1063 /* end of opcode/i386.h */