1 // $Id: arch-ia32.C,v 1.1 2002/06/06 18:25:17 gaburici Exp $
3 // Official documentation used: - IA-32 Intel Architecture Software Developer Manual
4 // volume 2: Instruction Set Reference
5 // Unofficial documentation used: - www.sandpile.org/ia32
6 // - NASM documentation
7 // The official documentation is awfully written, and full of bugs...
9 // VG(02/06/2002): configurable IA-32 decoder
10 // The decoder is configured by the capa[bilities] template parameter.
11 // For available capabilities see arch-ia32.h
15 #include "common/h/Types.h"
16 #include "arch-ia32.h"
19 // enum ia32_decoder_states {
20 // PREFIX_STATE, OPCODE1_STATE, OPCODE2_STATE, MODRM_STATE, SIB_STATE, DISP_STATE, IMM_STATE
23 // tables and pseudotables
25 t_ill=0, t_oneB, t_twoB, t_prefixedSSE, t_coprocEsc, t_grp, t_sse, t_grpsse, t_done=99
28 #define oneB t_done, 0
29 #define twoB t_done, 0
33 Grp1=0, Grp2, Grp3a, Grp3b, Grp4, Grp5, Grp6, Grp7, Grp8, Grp9,
34 Grp11, Grp12, Grp13, Grp14, Grp15, Grp16
39 SSE10=0, SSE11, SSE12, SSE13, SSE14, SSE15, SSE16, SSE17,
40 SSE28, SSE29, SSE2A, SSE2B, SSE2C, SSE2D, SSE2E, SSE2F,
41 SSE50, SSE51, SSE52, SSE53, SSE54, SSE55, SSE56, SSE57,
42 SSE58, SSE59, SSE5A, SSE5B, SSE5C, SSE5D, SSE5E, SSE5F,
43 SSE60, SSE61, SSE62, SSE63, SSE64, SSE65, SSE66, SSE67,
44 SSE68, SSE69, SSE6A, SSE6B, SSE6C, SSE6D, SSE6E, SSE6F,
45 SSE70, SSE74, SSE75, SSE76,
47 SSEC2, SSEC4, SSEC5, SSEC6,
48 SSED1, SSED2, SSED3, SSED4, SSED5, SSED6, SSED7,
49 SSED8, SSED9, SSEDA, SSEDB, SSEDC, SSEDD, SSEDE, SSEDF,
50 SSEE0, SSEE1, SSEE2, SSEE3, SSEE4, SSEE5, SSEE6, SSEE7,
51 SSEE8, SSEE9, SSEEA, SSEEB, SSEEC, SSEED, SSEEE, SSEEF,
52 SSEF1, SSEF2, SSEF3, SSEF4, SSEF5, SSEF6, SSEF7,
53 SSEF8, SSEF9, SSEFA, SSEFB, SSEFC, SSEFD, SSEFE
58 G12SSE010B=0, G12SSE100B, G12SSE110B,
59 G13SSE010B, G13SSE100B, G13SSE110B,
60 G14SSE010B, G14SSE011B, G14SSE110B, G14SSE111B,
63 // addressing methods (see appendix A-2)
64 enum { am_A=1, am_C, am_D, am_E, am_F, am_G, am_I, am_J, am_M, am_O,
65 am_P, am_Q, am_R, am_S, am_T, am_V, am_W, am_X, am_Y, am_reg };
67 // operand types (idem, but I invented lea for consistency; op_ didn't seem a good idea)
68 // beware that not all operand types in the tables are explained!!! Guess what they mean...
69 enum { op_a=1, op_b, op_c, op_d, op_dq, op_p, op_pd, op_pi, op_ps,
70 op_q, op_s, op_sd, op_ss, op_si, op_v, op_w, op_lea };
72 // registers [only fancy names, not used]
73 enum { r_AH=100, r_BH, r_CH, r_DH, r_AL, r_BL, r_CL, r_DL,
75 r_eAX, r_eBX, r_eCX, r_eDX,
76 r_EAX, r_EBX, r_ECX, r_EDX,
77 r_DS, r_ES, r_FS, r_GS, r_SS,
78 r_eSP, r_eBP, r_eSI, r_eDI,
79 r_ESP, r_EBP, r_ESI, r_EDI };
82 #define Ap { am_A, op_p }
83 #define Cd { am_C, op_d }
84 #define Dd { am_D, op_d }
85 #define Eb { am_E, op_b }
86 #define Ed { am_E, op_d }
87 #define Ep { am_E, op_p }
88 #define Ev { am_E, op_v }
89 #define Ew { am_E, op_w }
90 #define Fv { am_F, op_v }
91 #define Gb { am_G, op_b }
92 #define Gd { am_G, op_d }
93 #define Gv { am_G, op_v }
94 #define Gw { am_G, op_w }
95 #define Ib { am_I, op_b }
96 #define Iv { am_I, op_v }
97 #define Iw { am_I, op_w }
98 #define Jb { am_J, op_b }
99 #define Jv { am_J, op_v }
100 #define Ma { am_M, op_a }
101 #define Mlea { am_M, op_lea }
102 #define Mp { am_M, op_p }
103 #define Ms { am_M, op_s }
104 #define Mq { am_M, op_q }
105 #define Ob { am_O, op_b }
106 #define Ov { am_O, op_v }
107 #define Pd { am_P, op_d }
108 #define Pdq { am_P, op_dq }
109 #define Ppi { am_P, op_pi }
110 #define Pq { am_P, op_q }
111 #define Qdq { am_Q, op_dq }
112 #define Qd { am_Q, op_d }
113 #define Qpi { am_Q, op_pi }
114 #define Qq { am_Q, op_q }
115 #define Rd { am_R, op_d }
116 #define Td { am_T, op_d }
117 #define Sw { am_S, op_w }
118 #define Vdq { am_V, op_dq }
119 #define Vpd { am_V, op_pd }
120 #define Vps { am_V, op_ps }
121 #define Vq { am_V, op_q }
122 #define Vss { am_V, op_ss }
123 #define Vsd { am_V, op_sd }
124 #define Wdq { am_W, op_dq }
125 #define Wpd { am_W, op_pd }
126 #define Wps { am_W, op_ps }
127 #define Wq { am_W, op_q }
128 #define Ws { am_W, op_s }
129 #define Wsd { am_W, op_sd }
130 #define Wss { am_W, op_ss }
131 #define Xb { am_X, op_b }
132 #define Xv { am_X, op_v }
133 #define Yb { am_Y, op_b }
134 #define Yv { am_Y, op_v }
136 #define AH { am_reg, r_AH }
137 #define BH { am_reg, r_BH }
138 #define CH { am_reg, r_CH }
139 #define DH { am_reg, r_DH }
140 #define AL { am_reg, r_AL }
141 #define BL { am_reg, r_BL }
142 #define CL { am_reg, r_CL }
143 #define DL { am_reg, r_DL }
144 #define DX { am_reg, r_DX }
145 #define eAX { am_reg, r_eAX }
146 #define eBX { am_reg, r_eBX }
147 #define eCX { am_reg, r_eCX }
148 #define eDX { am_reg, r_eDX }
149 #define EAX { am_reg, r_EAX }
150 #define EBX { am_reg, r_EBX }
151 #define ECX { am_reg, r_ECX }
152 #define EDX { am_reg, r_EDX }
153 #define DS { am_reg, r_DS }
154 #define ES { am_reg, r_ES }
155 #define FS { am_reg, r_FS }
156 #define GS { am_reg, r_GS }
157 #define SS { am_reg, r_SS }
158 #define eSP { am_reg, r_eSP }
159 #define eBP { am_reg, r_eBP }
160 #define eSI { am_reg, r_eSI }
161 #define eDI { am_reg, r_eDI }
162 #define ESP { am_reg, r_ESP }
163 #define EBP { am_reg, r_EBP }
164 #define ESI { am_reg, r_ESI }
165 #define EDI { am_reg, r_EDI }
168 struct ia32_operand {
169 unsigned int admet; // addressing method
170 unsigned int optype; // operand type;
173 // An instruction table entry
175 char *name; // name of the instruction (for debbuging only)
176 unsigned int otable; // which opcode table is next; if t_done it is the current one
177 unsigned char tabidx; // at what index to look, 0 if it easy to deduce from opcode
178 bool hasModRM; // true if the instruction has a MOD/RM byte
179 ia32_operand operands[3]; // operand descriptors
180 unsigned legacyType; // old type of the instruction (e.g. (IS_CALL | REL_W))
184 // oneByteMap: one byte opcode map
185 static ia32_entry oneByteMap[256] = {
187 { "add", t_done, 0, true, { Eb, Gb, Zz }, 0 },
188 { "add", t_done, 0, true, { Ev, Gv, Zz }, 0 },
189 { "add", t_done, 0, true, { Gb, Eb, Zz }, 0 },
190 { "add", t_done, 0, true, { Gv, Ev, Zz }, 0 },
191 { "add", t_done, 0, false, { AL, Ib, Zz }, 0 },
192 { "add", t_done, 0, false, { eAX, Iv, Zz }, 0 },
193 { "push", t_done, 0, false, { ES, Zz, Zz }, 0 },
194 { "pop", t_done, 0, false, { ES, Zz, Zz }, 0 },
196 { "or", t_done, 0, true, { Eb, Gb, Zz }, 0 },
197 { "or", t_done, 0, true, { Ev, Gv, Zz }, 0 },
198 { "or", t_done, 0, true, { Gb, Eb, Zz }, 0 },
199 { "or", t_done, 0, true, { Gv, Ev, Zz }, 0 },
200 { "or", t_done, 0, false, { AL, Ib, Zz }, 0 },
201 { "or", t_done, 0, false, { eAX, Iv, Zz }, 0 },
202 { "push", t_done, 0, false, { ES, Zz, Zz }, 0 },
203 { 0, t_twoB, 0, false, { Zz, Zz, Zz }, 0 },
205 { "adc", t_done, 0, true, { Eb, Gb, Zz }, 0 },
206 { "adc", t_done, 0, true, { Ev, Gv, Zz }, 0 },
207 { "adc", t_done, 0, true, { Gb, Eb, Zz }, 0 },
208 { "adc", t_done, 0, true, { Gv, Ev, Zz }, 0 },
209 { "adc", t_done, 0, false, { AL, Ib, Zz }, 0 },
210 { "adc", t_done, 0, false, { eAX, Iv, Zz }, 0 },
211 { "push", t_done, 0, false, { SS, Zz, Zz }, 0 },
212 { "pop", t_done, 0, false, { SS, Zz, Zz }, 0 },
214 { "sbb", t_done, 0, true, { Eb, Gb, Zz }, 0 },
215 { "sbb", t_done, 0, true, { Ev, Gv, Zz }, 0 },
216 { "sbb", t_done, 0, true, { Gb, Eb, Zz }, 0 },
217 { "sbb", t_done, 0, true, { Gv, Ev, Zz }, 0 },
218 { "sbb", t_done, 0, false, { AL, Ib, Zz }, 0 },
219 { "sbb", t_done, 0, false, { eAX, Iv, Zz }, 0 },
220 { "push", t_done, 0, false, { DS, Zz, Zz }, 0 },
221 { "pop" , t_done, 0, false, { DS, Zz, Zz }, 0 },
223 { "and", t_done, 0, true, { Eb, Gb, Zz }, 0 },
224 { "and", t_done, 0, true, { Ev, Gv, Zz }, 0 },
225 { "and", t_done, 0, true, { Gb, Eb, Zz }, 0 },
226 { "and", t_done, 0, true, { Gv, Ev, Zz }, 0 },
227 { "and", t_done, 0, false, { AL, Ib, Zz }, 0 },
228 { "and", t_done, 0, false, { eAX, Iv, Zz }, 0 },
229 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
230 { "daa", t_done, 0, false, { Zz, Zz, Zz }, 0 },
232 { "sub", t_done, 0, true, { Eb, Gb, Zz }, 0 },
233 { "sub", t_done, 0, true, { Ev, Gv, Zz }, 0 },
234 { "sub", t_done, 0, true, { Gb, Eb, Zz }, 0 },
235 { "sub", t_done, 0, true, { Gv, Ev, Zz }, 0 },
236 { "sub", t_done, 0, false, { AL, Ib, Zz }, 0 },
237 { "sub", t_done, 0, false, { eAX, Iv, Zz }, 0 },
238 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
239 { "das" , t_done, 0, false, { Zz, Zz, Zz }, 0 },
241 { "xor", t_done, 0, true, { Eb, Gb, Zz }, 0 },
242 { "xor", t_done, 0, true, { Ev, Gv, Zz }, 0 },
243 { "xor", t_done, 0, true, { Gb, Eb, Zz }, 0 },
244 { "xor", t_done, 0, true, { Gv, Ev, Zz }, 0 },
245 { "xor", t_done, 0, false, { AL, Ib, Zz }, 0 },
246 { "xor", t_done, 0, false, { eAX, Iv, Zz }, 0 },
247 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
248 { "aaa", t_done, 0, false, { Zz, Zz, Zz }, 0 },
250 { "cmp", t_done, 0, true, { Eb, Gb, Zz }, 0 },
251 { "cmp", t_done, 0, true, { Ev, Gv, Zz }, 0 },
252 { "cmp", t_done, 0, true, { Gb, Eb, Zz }, 0 },
253 { "cmp", t_done, 0, true, { Gv, Ev, Zz }, 0 },
254 { "cmp", t_done, 0, false, { AL, Ib, Zz }, 0 },
255 { "cmp", t_done, 0, false, { eAX, Iv, Zz }, 0 },
256 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
257 { "aas", t_done, 0, false, { Zz, Zz, Zz }, 0 },
259 { "inc", t_done, 0, false, { eAX, Zz, Zz }, 0 },
260 { "inc", t_done, 0, false, { eCX, Zz, Zz }, 0 },
261 { "inc", t_done, 0, false, { eDX, Zz, Zz }, 0 },
262 { "inc", t_done, 0, false, { eBX, Zz, Zz }, 0 },
263 { "inc", t_done, 0, false, { eSP, Zz, Zz }, 0 },
264 { "inc", t_done, 0, false, { eBP, Zz, Zz }, 0 },
265 { "inc", t_done, 0, false, { eSI, Zz, Zz }, 0 },
266 { "inc", t_done, 0, false, { eDI, Zz, Zz }, 0 },
268 { "dec", t_done, 0, false, { eAX, Zz, Zz }, 0 },
269 { "dec", t_done, 0, false, { eCX, Zz, Zz }, 0 },
270 { "dec", t_done, 0, false, { eDX, Zz, Zz }, 0 },
271 { "dec", t_done, 0, false, { eBX, Zz, Zz }, 0 },
272 { "dec", t_done, 0, false, { eSP, Zz, Zz }, 0 },
273 { "dec", t_done, 0, false, { eBP, Zz, Zz }, 0 },
274 { "dec", t_done, 0, false, { eSI, Zz, Zz }, 0 },
275 { "dec", t_done, 0, false, { eDI, Zz, Zz }, 0 },
277 { "push", t_done, 0, false, { eAX, Zz, Zz }, 0 },
278 { "push", t_done, 0, false, { eCX, Zz, Zz }, 0 },
279 { "push", t_done, 0, false, { eDX, Zz, Zz }, 0 },
280 { "push", t_done, 0, false, { eBX, Zz, Zz }, 0 },
281 { "push", t_done, 0, false, { eSP, Zz, Zz }, 0 },
282 { "push", t_done, 0, false, { eBP, Zz, Zz }, 0 },
283 { "push", t_done, 0, false, { eSI, Zz, Zz }, 0 },
284 { "push", t_done, 0, false, { eDI, Zz, Zz }, 0 },
286 { "pop", t_done, 0, false, { eAX, Zz, Zz }, 0 },
287 { "pop", t_done, 0, false, { eCX, Zz, Zz }, 0 },
288 { "pop", t_done, 0, false, { eDX, Zz, Zz }, 0 },
289 { "pop", t_done, 0, false, { eBX, Zz, Zz }, 0 },
290 { "pop", t_done, 0, false, { eSP, Zz, Zz }, 0 },
291 { "pop", t_done, 0, false, { eBP, Zz, Zz }, 0 },
292 { "pop", t_done, 0, false, { eSI, Zz, Zz }, 0 },
293 { "pop", t_done, 0, false, { eDI, Zz, Zz }, 0 },
295 { "pusha(d)", t_done, 0, false, { Zz, Zz, Zz }, 0 },
296 { "popa(d)", t_done, 0, false, { Zz, Zz, Zz }, 0 },
297 { "bound", t_done, 0, true, { Gv, Ma, Zz }, 0 },
298 { "arpl", t_done, 0, true, { Ew, Gw, Zz }, 0 },
299 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
300 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
301 { 0, t_prefixedSSE, 2, false, { Zz, Zz, Zz }, 0 }, /* operand size prefix (PREFIX_OPR_SZ)*/
302 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, /* address size prefix (PREFIX_ADDR_SZ)*/
304 { "push", t_done, 0, false, { Iv, Zz, Zz }, 0 },
305 { "imul", t_done, 0, true, { Gv, Ev, Iv }, 0 },
306 { "push", t_done, 0, false, { Ib, Zz, Zz }, 0 },
307 { "imul", t_done, 0, true, { Gv, Ev, Ib }, 0 },
308 { "insb", t_done, 0, false, { Yb, DX, Zz }, 0 },
309 { "insw/d", t_done, 0, false, { Yv, DX, Zz }, 0 },
310 { "outsb", t_done, 0, false, { DX, Xb, Zz }, 0 },
311 { "outsw/d", t_done, 0, false, { DX, Xv, Zz }, 0 },
313 { "jo", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
314 { "jno", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
315 { "jb/jnaej/j", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
316 { "jnb/jae/j", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
317 { "jz", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
318 { "jnz", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
319 { "jbe", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
320 { "jnbe", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
322 { "js", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
323 { "jns", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
324 { "jp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
325 { "jnp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
326 { "jl", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
327 { "jnl", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
328 { "jle", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
329 { "jnle", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
331 { 0, t_grp, Grp1, true, { Eb, Ib, Zz }, 0 },
332 { 0, t_grp, Grp1, true, { Ev, Iv, Zz }, 0 },
333 { 0, t_grp, Grp1, true, { Eb, Ib, Zz }, 0 }, // this was Ill in the old decoder and in gdb 5.2.
334 // the book says Grp1 however;sandpile.org agrees.
335 { 0, t_grp, Grp1, true, { Ev, Ib, Zz }, 0 },
336 { "test", t_done, 0, true, { Eb, Gb, Zz }, 0 },
337 { "test", t_done, 0, true, { Ev, Gv, Zz }, 0 },
338 { "xchg", t_done, 0, true, { Eb, Gb, Zz }, 0 },
339 { "xchg", t_done, 0, true, { Ev, Gv, Zz }, 0 },
341 { "mov", t_done, 0, true, { Eb, Gb, Zz }, 0 },
342 { "mov", t_done, 0, true, { Ev, Gv, Zz }, 0 },
343 { "mov", t_done, 0, true, { Gb, Eb, Zz }, 0 },
344 { "mov", t_done, 0, true, { Gv, Ev, Zz }, 0 },
345 { "mov", t_done, 0, true, { Ew, Sw, Zz }, 0 },
346 { "lea", t_done, 0, true, { Gv, Mlea, Zz }, 0 }, // this is just M in the book
347 { "mov", t_done, 0, true, { Sw, Ew, Zz }, 0 },
348 { "pop", t_done, 0, true, { Ev, Zz, Zz }, 0 },
350 { "nop", t_done, 0, false, { Zz, Zz, Zz }, 0 },
351 { "xchg", t_done, 0, false, { eCX, Zz, Zz }, 0 },
352 { "xchg", t_done, 0, false, { eDX, Zz, Zz }, 0 },
353 { "xchg", t_done, 0, false, { eBX, Zz, Zz }, 0 },
354 { "xchg", t_done, 0, false, { eSP, Zz, Zz }, 0 },
355 { "xchg", t_done, 0, false, { eBP, Zz, Zz }, 0 },
356 { "xchg", t_done, 0, false, { eSI, Zz, Zz }, 0 },
357 { "xchg", t_done, 0, false, { eDI, Zz, Zz }, 0 },
359 { "cbw", t_done, 0, false, { Zz, Zz, Zz }, 0 },
360 { "cwd/cdq", t_done, 0, false, { Zz, Zz, Zz }, 0 },
361 { "call", t_done, 0, false, { Ap, Zz, Zz }, IS_CALL | PTR_WX },
362 { "wait", t_done, 0, false, { Zz, Zz, Zz }, 0 },
363 { "pushf", t_done, 0, false, { Fv, Zz, Zz }, 0 },
364 { "pop", t_done, 0, false, { Fv, Zz, Zz }, 0 },
365 { "sahf", t_done, 0, false, { Zz, Zz, Zz }, 0 },
366 { "lahf", t_done, 0, false, { Zz, Zz, Zz }, 0 },
368 { "mov", t_done, 0, false, { AL, Ob, Zz }, 0 },
369 { "mov", t_done, 0, false, { eAX, Ov, Zz }, 0 },
370 { "mov", t_done, 0, false, { Ob, AL, Zz }, 0 },
371 { "mov", t_done, 0, false, { Ov, eAX, Zz }, 0 },
372 { "movsb", t_done, 0, false, { Xb, Yb, Zz }, 0 },
373 { "movsw", t_done, 0, false, { Xv, Yv, Zz }, 0 },
374 { "cmpsb", t_done, 0, false, { Xb, Yb, Zz }, 0 },
375 { "cmpsw", t_done, 0, false, { Xv, Yv, Zz }, 0 },
377 { "test", t_done, 0, false, { AL, Ib, Zz }, 0 },
378 { "test", t_done, 0, false, { eAX, Iv, Zz }, 0 },
379 { "stopsb", t_done, 0, false, { Yb, AL, Zz }, 0 },
380 { "stopsw/d", t_done, 0, false, { Yv, eAX, Zz }, 0 },
381 { "lodsb", t_done, 0, false, { AL, Xb, Zz }, 0 },
382 { "lodsw", t_done, 0, false, { eAX, Xv, Zz }, 0 },
383 { "scasb", t_done, 0, false, { AL, Yb, Zz }, 0 },
384 { "scasw/d", t_done, 0, false, { eAX, Yv, Zz }, 0 },
386 { "mov", t_done, 0, false, { AL, Ib, Zz }, 0 },
387 { "mov", t_done, 0, false, { CL, Ib, Zz }, 0 },
388 { "mov", t_done, 0, false, { DL, Ib, Zz }, 0 },
389 { "mov", t_done, 0, false, { BL, Ib, Zz }, 0 },
390 { "mov", t_done, 0, false, { AH, Ib, Zz }, 0 },
391 { "mov", t_done, 0, false, { CH, Ib, Zz }, 0 },
392 { "mov", t_done, 0, false, { DH, Ib, Zz }, 0 },
393 { "mov", t_done, 0, false, { BH, Ib, Zz }, 0 },
395 { "mov", t_done, 0, false, { eAX, Iv, Zz }, 0 },
396 { "mov", t_done, 0, false, { eCX, Iv, Zz }, 0 },
397 { "mov", t_done, 0, false, { eDX, Iv, Zz }, 0 },
398 { "mov", t_done, 0, false, { eBX, Iv, Zz }, 0 },
399 { "mov", t_done, 0, false, { eSP, Iv, Zz }, 0 },
400 { "mov", t_done, 0, false, { eBP, Iv, Zz }, 0 },
401 { "mov", t_done, 0, false, { eSI, Iv, Zz }, 0 },
402 { "mov", t_done, 0, false, { eDI, Iv, Zz }, 0 },
404 { 0, t_grp, Grp2, true, { Eb, Ib, Zz }, 0 },
405 { 0, t_grp, Grp2, true, { Ev, Ib, Zz }, 0 },
406 { "ret near", t_done, 0, false, { Iw, Zz, Zz }, (IS_RET) },
407 { "ret near", t_done, 0, false, { Zz, Zz, Zz }, (IS_RET) },
408 { "les", t_done, 0, true, { Gv, Mp, Zz }, 0 },
409 { "lds", t_done, 0, true, { Gv, Mp, Zz }, 0 },
410 { 0, t_grp, Grp11, true, { Eb, Ib, Zz }, 0 },
411 { 0, t_grp, Grp11, true, { Ev, Iv, Zz }, 0 },
413 { "enter", t_done, 0, false, { Iw, Ib, Zz }, 0 },
414 { "leave", t_done, 0, false, { Zz, Zz, Zz }, 0 },
415 { "ret far", t_done, 0, false, { Iw, Zz, Zz }, (IS_RETF) },
416 { "ret far", t_done, 0, false, { Zz, Zz, Zz }, (IS_RETF) },
417 { "int 3", t_done, 0, false, { Zz, Zz, Zz }, 0 },
418 { "int", t_done, 0, false, { Ib, Zz, Zz }, 0 },
419 { "into", t_done, 0, false, { Zz, Zz, Zz }, 0 },
420 { "iret", t_done, 0, false, { Zz, Zz, Zz }, (IS_RET) },
422 { 0, t_grp, Grp2, true, { Eb, Zz, Zz }, 0 }, // const1
423 { 0, t_grp, Grp2, true, { Ev, Zz, Zz }, 0 }, // --"--
424 { 0, t_grp, Grp2, true, { Eb, CL, Zz }, 0 },
425 { 0, t_grp, Grp2, true, { Ev, CL, Zz }, 0 },
426 { "aam", t_done, 0, false, { Zz, Zz, Zz }, 0 },
427 { "aad", t_done, 0, false, { Zz, Zz, Zz }, 0 },
428 { "salc", t_done, 0, false, { Zz, Zz, Zz }, 0 }, // sandpile.org gives this as SALC; undocumeted
429 { "xlat", t_done, 0, false, { Zz, Zz, Zz }, 0 },
431 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
432 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
433 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
434 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
435 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
436 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
437 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
438 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
440 { "loopn", t_done, 0, false, { Jb, Zz, Zz }, 0 },
441 { "loope", t_done, 0, false, { Jb, Zz, Zz }, 0 },
442 { "loop", t_done, 0, false, { Jb, Zz, Zz }, 0 },
443 { "jcxz/jec", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
444 { "in", t_done, 0, false, { AL, Ib, Zz }, 0 },
445 { "in", t_done, 0, false, { eAX, Ib, Zz }, 0 },
446 { "out", t_done, 0, false, { Ib, AL, Zz }, 0 },
447 { "out", t_done, 0, false, { Ib, eAX, Zz }, 0 },
449 { "call", t_done, 0, false, { Jv, Zz, Zz }, (IS_CALL | REL_X) },
450 { "jmp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JUMP | REL_X) },
451 { "jmp", t_done, 0, false, { Ap, Zz, Zz }, (IS_JUMP | PTR_WX) },
452 { "jmp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JUMP | REL_B) },
453 { "in", t_done, 0, false, { AL, DX, Zz }, 0 },
454 { "in", t_done, 0, false, { eAX, DX, Zz }, 0 },
455 { "out", t_done, 0, false, { DX, AL, Zz }, 0 },
456 { "out", t_done, 0, false, { DX, eAX, Zz }, 0 },
458 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_INSTR
459 { "int1", t_done, 0, false, { Zz, Zz, Zz }, 0 }, // INT1/ICEBP on sandpile; undocumented
460 { 0, t_prefixedSSE, 3, false, { Zz, Zz, Zz }, 0 },
461 { 0, t_prefixedSSE, 1, false, { Zz, Zz, Zz }, 0 },
462 { "hlt", t_done, 0, false, { Zz, Zz, Zz }, 0 },
463 { "cmc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
464 { 0, t_grp, Grp3a, true, { Zz, Zz, Zz }, 0 },
465 { 0, t_grp, Grp3b, true, { Zz, Zz, Zz }, 0 },
467 { "clc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
468 { "stc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
469 { "cli", t_done, 0, false, { Zz, Zz, Zz }, 0 },
470 { "sti", t_done, 0, false, { Zz, Zz, Zz }, 0 },
471 { "cld", t_done, 0, false, { Zz, Zz, Zz }, 0 },
472 { "std", t_done, 0, false, { Zz, Zz, Zz }, 0 },
473 { 0, t_grp, Grp4, true, { Zz, Zz, Zz }, 0 },
474 { 0, t_grp, Grp5, true, { Zz, Zz, Zz }, 0 }
478 // twoByteMap: two byte opcode instructions (first byte is 0x0F)
479 static ia32_entry twoByteMap[256] = {
481 { 0, t_grp, Grp6, true, { Zz, Zz, Zz }, 0 },
482 { 0, t_grp, Grp7, false, { Zz, Zz, Zz }, 0 },
483 { "lar", t_done, 0, true, { Gv, Ew, Zz }, 0 },
484 { "lsl", t_done, 0, true, { Gv, Ew, Zz }, 0 },
485 { 0, t_ill, 0, false, { Zz, Zz, Zz },0},
486 { "syscallAMD", t_done, 0, false, { Zz, Zz, Zz }, 0 },
487 { "clts", t_done, 0, false, { Zz, Zz, Zz }, 0 },
488 { "sysretAMD", t_done, 0, false, { Zz, Zz, Zz }, 0 },
490 { "invd", t_done, 0, false, { Zz, Zz, Zz }, 0 },
491 { "wbinvd", t_done, 0, false, { Zz, Zz, Zz }, 0 },
492 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
493 { "ud2", t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
494 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
495 {0, t_ill, 0,0, { Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
496 {0, t_ill, 0,0 ,{ Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
497 {0, t_ill, 0,0 ,{ Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
499 { 0, t_sse, SSE10, true, { Zz, Zz, Zz }, 0 },
500 { 0, t_sse, SSE11, true, { Zz, Zz, Zz }, 0 },
501 { 0, t_sse, SSE12, true, { Zz, Zz, Zz }, 0 },
502 { 0, t_sse, SSE13, true, { Zz, Zz, Zz }, 0 },
503 { 0, t_sse, SSE14, true, { Zz, Zz, Zz }, 0 },
504 { 0, t_sse, SSE15, true, { Zz, Zz, Zz }, 0 },
505 { 0, t_sse, SSE16, true, { Zz, Zz, Zz }, 0 },
506 { 0, t_sse, SSE17, true, { Zz, Zz, Zz }, 0 },
508 { 0, t_grp, Grp16, 0, { Zz, Zz, Zz }, 0 },
509 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
510 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
511 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
512 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
513 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
514 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
515 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
517 { "mov", t_done, 0, true, { Rd, Cd, Zz }, 0 },
518 { "mov", t_done, 0, true, { Rd, Dd, Zz }, 0 },
519 { "mov", t_done, 0, true, { Cd, Rd, Zz }, 0 },
520 { "mov", t_done, 0, true, { Dd, Rd, Zz }, 0 },
521 { "mov", t_done, 0, true, { Rd, Td, Zz }, 0 },
522 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
523 { "mov", t_done, 0, true, { Td, Rd, Zz }, 0 },
524 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
526 { 0, t_sse, SSE28, true, { Zz, Zz, Zz }, 0 },
527 { 0, t_sse, SSE29, true, { Zz, Zz, Zz }, 0 },
528 { 0, t_sse, SSE2A, true, { Zz, Zz, Zz }, 0 },
529 { 0, t_sse, SSE2B, true, { Zz, Zz, Zz }, 0 },
530 { 0, t_sse, SSE2C, true, { Zz, Zz, Zz }, 0 },
531 { 0, t_sse, SSE2D, true, { Zz, Zz, Zz }, 0 },
532 { 0, t_sse, SSE2E, true, { Zz, Zz, Zz }, 0 },
533 { 0, t_sse, SSE2F, true, { Zz, Zz, Zz }, 0 },
535 { "wrmsr", t_done, 0, false, { Zz, Zz, Zz }, 0 },
536 { "rdtsc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
537 { "rdmsr", t_done, 0, false, { Zz, Zz, Zz }, 0 },
538 { "rdpmc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
539 { "sysenter", t_done, 0, false, { Zz, Zz, Zz }, 0 },
540 { "sysexit", t_done, 0, false, { Zz, Zz, Zz }, 0 },
541 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
542 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
544 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
545 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
546 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
547 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
548 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
549 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
550 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
551 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
553 { "cmovo", t_done, 0, true, { Gv, Ev, Zz }, 0 },
554 { "cmovno", t_done, 0, true, { Gv, Ev, Zz }, 0 },
555 { "cmovnae", t_done, 0, true, { Gv, Ev, Zz }, 0 },
556 { "cmovnb", t_done, 0, true, { Gv, Ev, Zz }, 0 },
557 { "cmove", t_done, 0, true, { Gv, Ev, Zz }, 0 },
558 { "cmovne", t_done, 0, true, { Gv, Ev, Zz }, 0 },
559 { "cmovbe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
560 { "cmovnbe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
562 { "cmovs", t_done, 0, true, { Gv, Ev, Zz }, 0 },
563 { "cmovns", t_done, 0, true, { Gv, Ev, Zz }, 0 },
564 { "cmovpe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
565 { "cmovpo", t_done, 0, true, { Gv, Ev, Zz }, 0 },
566 { "cmovnge", t_done, 0, true, { Gv, Ev, Zz }, 0 },
567 { "cmovnl", t_done, 0, true, { Gv, Ev, Zz }, 0 },
568 { "cmovng", t_done, 0, true, { Gv, Ev, Zz }, 0 },
569 { "cmovnl", t_done, 0, true, { Gv, Ev, Zz }, 0 },
571 { 0, t_sse, SSE50, true, { Zz, Zz, Zz }, 0 },
572 { 0, t_sse, SSE51, true, { Zz, Zz, Zz }, 0 },
573 { 0, t_sse, SSE52, true, { Zz, Zz, Zz }, 0 },
574 { 0, t_sse, SSE53, true, { Zz, Zz, Zz }, 0 },
575 { 0, t_sse, SSE54, true, { Zz, Zz, Zz }, 0 },
576 { 0, t_sse, SSE55, true, { Zz, Zz, Zz }, 0 },
577 { 0, t_sse, SSE56, true, { Zz, Zz, Zz }, 0 },
578 { 0, t_sse, SSE57, true, { Zz, Zz, Zz }, 0 },
580 { 0, t_sse, SSE58, true, { Zz, Zz, Zz }, 0 },
581 { 0, t_sse, SSE59, true, { Zz, Zz, Zz }, 0 },
582 { 0, t_sse, SSE5A, true, { Zz, Zz, Zz }, 0 },
583 { 0, t_sse, SSE5B, true, { Zz, Zz, Zz }, 0 },
584 { 0, t_sse, SSE5C, true, { Zz, Zz, Zz }, 0 },
585 { 0, t_sse, SSE5D, true, { Zz, Zz, Zz }, 0 },
586 { 0, t_sse, SSE5E, true, { Zz, Zz, Zz }, 0 },
587 { 0, t_sse, SSE5F, true, { Zz, Zz, Zz }, 0 },
589 { 0, t_sse, SSE60, true, { Zz, Zz, Zz }, 0 },
590 { 0, t_sse, SSE61, true, { Zz, Zz, Zz }, 0 },
591 { 0, t_sse, SSE62, true, { Zz, Zz, Zz }, 0 },
592 { 0, t_sse, SSE63, true, { Zz, Zz, Zz }, 0 },
593 { 0, t_sse, SSE64, true, { Zz, Zz, Zz }, 0 },
594 { 0, t_sse, SSE65, true, { Zz, Zz, Zz }, 0 },
595 { 0, t_sse, SSE66, true, { Zz, Zz, Zz }, 0 },
596 { 0, t_sse, SSE67, true, { Zz, Zz, Zz }, 0 },
598 { 0, t_sse, SSE68, true, { Zz, Zz, Zz }, 0 },
599 { 0, t_sse, SSE69, true, { Zz, Zz, Zz }, 0 },
600 { 0, t_sse, SSE6A, true, { Zz, Zz, Zz }, 0 },
601 { 0, t_sse, SSE6B, true, { Zz, Zz, Zz }, 0 },
602 { 0, t_sse, SSE6C, true, { Zz, Zz, Zz }, 0 },
603 { 0, t_sse, SSE6D, true, { Zz, Zz, Zz }, 0 },
604 { 0, t_sse, SSE6E, true, { Zz, Zz, Zz }, 0 },
605 { 0, t_sse, SSE6F, true, { Zz, Zz, Zz }, 0 },
607 { 0, t_sse, SSE70, true, { Zz, Zz, Zz }, 0 },
608 { 0, t_grp, Grp12, false, { Zz, Zz, Zz }, 0 },
609 { 0, t_grp, Grp13, false, { Zz, Zz, Zz }, 0 },
610 { 0, t_grp, Grp14, false, { Zz, Zz, Zz }, 0 },
611 { 0, t_sse, SSE74, true, { Zz, Zz, Zz }, 0 },
612 { 0, t_sse, SSE75, true, { Zz, Zz, Zz }, 0 },
613 { 0, t_sse, SSE76, true, { Zz, Zz, Zz }, 0 },
614 { "emms", t_done, 0, false, { Zz, Zz, Zz }, 0 },
616 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
617 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
618 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
619 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
620 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
621 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
622 { 0, t_sse, SSE7E, 0, { Zz, Zz, Zz }, 0 },
623 { 0, t_sse, SSE7F, 0, { Zz, Zz, Zz }, 0 },
625 { "jo", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
626 { "jno", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
627 { "jb", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
628 { "jnb", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
629 { "jz", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
630 { "jnz", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
631 { "jbe", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
632 { "jnbe", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
634 { "js", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
635 { "jns", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
636 { "jp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
637 { "jnp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
638 { "jl", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
639 { "jnl", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
640 { "jle", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
641 { "jnle", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
643 { "seto", t_done, 0, true, { Eb, Zz, Zz }, 0 },
644 { "setno", t_done, 0, true, { Eb, Zz, Zz }, 0 },
645 { "setb", t_done, 0, true, { Eb, Zz, Zz }, 0 },
646 { "setnb", t_done, 0, true, { Eb, Zz, Zz }, 0 },
647 { "setz", t_done, 0, true, { Eb, Zz, Zz }, 0 },
648 { "setnz", t_done, 0, true, { Eb, Zz, Zz }, 0 },
649 { "setbe", t_done, 0, true, { Eb, Zz, Zz }, 0 },
650 { "setnbe", t_done, 0, true, { Eb, Zz, Zz }, 0 },
652 { "sets", t_done, 0, true, { Eb, Zz, Zz }, 0 },
653 { "setns", t_done, 0, true, { Eb, Zz, Zz }, 0 },
654 { "setp", t_done, 0, true, { Eb, Zz, Zz }, 0 },
655 { "setnp", t_done, 0, true, { Eb, Zz, Zz }, 0 },
656 { "setl", t_done, 0, true, { Eb, Zz, Zz }, 0 },
657 { "setnl", t_done, 0, true, { Eb, Zz, Zz }, 0 },
658 { "setle", t_done, 0, true, { Eb, Zz, Zz }, 0 },
659 { "setnle", t_done, 0, true, { Eb, Zz, Zz }, 0 },
661 { "push", t_done, 0, false, { FS, Zz, Zz }, 0 },
662 { "pop", t_done, 0, false, { FS, Zz, Zz }, 0 },
663 { "cpuid", t_done, 0, false, { Zz, Zz, Zz }, 0 },
664 { "bt", t_done, 0, true, { Ev, Gv, Zz }, 0 },
665 { "shld", t_done, 0, true, { Ev, Gv, Ib }, 0 },
666 { "shld", t_done, 0, true, { Ev, Gv, CL }, 0 },
667 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0},
668 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0},
670 { "push", t_done, 0, false, { GS, Zz, Zz }, 0 },
671 { "pop", t_done, 0, false, { GS, Zz, Zz }, 0 },
672 { "rsm", t_done, 0, false, { Zz, Zz, Zz }, 0 },
673 { "bts", t_done, 0, true, { Ev, Gv, Zz }, 0 },
674 { "shrd", t_done, 0, true, { Ev, Gv, Ib }, 0 },
675 { "shrd", t_done, 0, true, { Ev, Gv, CL }, 0 },
676 { 0, t_grp, Grp15, 0, { Zz, Zz, Zz }, 0 },
677 { "imul", t_done, 0, true, { Gv, Ev, Zz }, 0 },
679 { "cmpxch", t_done, 0, true, { Eb, Gb, Zz }, 0 },
680 { "cmpxch", t_done, 0, true, { Ev, Gv, Zz }, 0 },
681 { "lss", t_done, 0, true, { Mp, Zz, Zz }, 0 },
682 { "btr", t_done, 0, true, { Ev, Gv, Zz }, 0 },
683 { "lfs", t_done, 0, true, { Mp, Zz, Zz }, 0 },
684 { "lgs", t_done, 0, true, { Mp, Zz, Zz }, 0 },
685 { "movzx", t_done, 0, true, { Gv, Eb, Zz }, 0 },
686 { "movzx", t_done, 0, true, { Gv, Ew, Zz }, 0 },
688 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
689 { "ud2grp10", t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
690 { 0, t_grp, Grp8, true, { Ev, Ib, Zz }, 0 },
691 { "btc", t_done, 0, true, { Ev, Gv, Zz }, 0 },
692 { "bsf", t_done, 0, true, { Gv, Ev, Zz }, 0 },
693 { "bsr", t_done, 0, true, { Gv, Ev, Zz }, 0 },
694 { "movsx", t_done, 0, true, { Gv, Eb, Zz }, 0 },
695 { "movsx", t_done, 0, true, { Gv, Ew, Zz }, 0 },
697 { "xadd", t_done, 0, true, { Eb, Gb, Zz }, 0 },
698 { "xadd", t_done, 0, true, { Ev, Gv, Zz }, 0 },
699 { 0, t_sse, SSEC2, true, { Zz, Zz, Zz }, 0 },
700 { "movnti" , t_done, 0, 0, { Ed, Gd, Zz }, 0 },
701 { 0, t_sse, SSEC4, true, { Zz, Zz, Zz }, 0 },
702 { 0, t_sse, SSEC5, true, { Zz, Zz, Zz }, 0 },
703 { 0, t_sse, SSEC6, true, { Zz, Zz, Zz }, 0 },
704 { 0, t_grp, Grp9, true, { Zz, Zz, Zz }, 0 },
706 { "bswap", t_done, 0, false, { EAX, Zz, Zz }, 0 },
707 { "bswap", t_done, 0, false, { ECX, Zz, Zz }, 0 },
708 { "bswap", t_done, 0, false, { EDX, Zz, Zz }, 0 },
709 { "bswap", t_done, 0, false, { EBX, Zz, Zz }, 0 },
710 { "bswap", t_done, 0, false, { ESP, Zz, Zz }, 0 },
711 { "bswap", t_done, 0, false, { EBP, Zz, Zz }, 0 },
712 { "bswap", t_done, 0, false, { ESI, Zz, Zz }, 0 },
713 { "bswap", t_done, 0, false, { EDI, Zz, Zz }, 0 },
715 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
716 { 0, t_sse, SSED1, true, { Zz, Zz, Zz }, 0 },
717 { 0, t_sse, SSED2, true, { Zz, Zz, Zz }, 0 },
718 { 0, t_sse, SSED3, true, { Zz, Zz, Zz }, 0 },
719 { 0, t_sse, SSED4, true, { Zz, Zz, Zz }, 0 },
720 { 0, t_sse, SSED5, true, { Zz, Zz, Zz }, 0 },
721 { 0, t_sse, SSED6, true, { Zz, Zz, Zz }, 0 },
722 { 0, t_sse, SSED7, true, { Zz, Zz, Zz }, 0 },
724 { 0, t_sse, SSED8, true, { Zz, Zz, Zz }, 0 },
725 { 0, t_sse, SSED9, true, { Zz, Zz, Zz }, 0 },
726 { 0, t_sse, SSEDA, true, { Zz, Zz, Zz }, 0 },
727 { 0, t_sse, SSEDB, true, { Zz, Zz, Zz }, 0 },
728 { 0, t_sse, SSEDC, true, { Zz, Zz, Zz }, 0 },
729 { 0, t_sse, SSEDD, true, { Zz, Zz, Zz }, 0 },
730 { 0, t_sse, SSEDE, true, { Zz, Zz, Zz }, 0 },
731 { 0, t_sse, SSEDF, true, { Zz, Zz, Zz }, 0 },
733 { 0, t_sse, SSEE0, true, { Zz, Zz, Zz }, 0 },
734 { 0, t_sse, SSEE1, true, { Zz, Zz, Zz }, 0 },
735 { 0, t_sse, SSEE2, true, { Zz, Zz, Zz }, 0 },
736 { 0, t_sse, SSEE3, true, { Zz, Zz, Zz }, 0 },
737 { 0, t_sse, SSEE4, true, { Zz, Zz, Zz }, 0 },
738 { 0, t_sse, SSEE5, true, { Zz, Zz, Zz }, 0 },
739 { 0, t_sse, SSEE6, true, { Zz, Zz, Zz }, 0 },
740 { 0, t_sse, SSEE7, true, { Zz, Zz, Zz }, 0 },
742 { 0, t_sse, SSEE8, true, { Zz, Zz, Zz }, 0 },
743 { 0, t_sse, SSEE9, true, { Zz, Zz, Zz }, 0 },
744 { 0, t_sse, SSEEA, true, { Zz, Zz, Zz }, 0 },
745 { 0, t_sse, SSEEB, true, { Zz, Zz, Zz }, 0 },
746 { 0, t_sse, SSEEC, true, { Zz, Zz, Zz }, 0 },
747 { 0, t_sse, SSEED, true, { Zz, Zz, Zz }, 0 },
748 { 0, t_sse, SSEEE, true, { Zz, Zz, Zz }, 0 },
749 { 0, t_sse, SSEEF, true, { Zz, Zz, Zz }, 0 },
751 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
752 { 0, t_sse, SSEF1, true, { Zz, Zz, Zz }, 0 },
753 { 0, t_sse, SSEF2, true, { Zz, Zz, Zz }, 0 },
754 { 0, t_sse, SSEF3, true, { Zz, Zz, Zz }, 0 },
755 { 0, t_sse, SSEF4, true, { Zz, Zz, Zz }, 0 },
756 { 0, t_sse, SSEF5, true, { Zz, Zz, Zz }, 0 },
757 { 0, t_sse, SSEF6, true, { Zz, Zz, Zz }, 0 },
758 { 0, t_sse, SSEF7, true, { Zz, Zz, Zz }, 0 },
760 { 0, t_sse, SSEF8, true, { Zz, Zz, Zz }, 0 },
761 { 0, t_sse, SSEF9, true, { Zz, Zz, Zz }, 0 },
762 { 0, t_sse, SSEFA, true, { Zz, Zz, Zz }, 0 },
763 { 0, t_sse, SSEFB, true, { Zz, Zz, Zz }, 0 },
764 { 0, t_sse, SSEFC, true, { Zz, Zz, Zz }, 0 },
765 { 0, t_sse, SSEFD, true, { Zz, Zz, Zz }, 0 },
766 { 0, t_sse, SSEFE, true, { Zz, Zz, Zz }, 0 },
767 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0}
770 static ia32_entry groupMap[][8] = {
771 { /* group 1 - only opcode is defined here,
772 operands are defined in the one or two byte maps below */
773 { "add", t_done, 0, true, { Zz, Zz, Zz }, 0 },
774 { "or", t_done, 0, true, { Zz, Zz, Zz }, 0 },
775 { "adc", t_done, 0, true, { Zz, Zz, Zz }, 0 },
776 { "sbb", t_done, 0, true, { Zz, Zz, Zz }, 0 },
777 { "and", t_done, 0, true, { Zz, Zz, Zz }, 0 },
778 { "sub", t_done, 0, true, { Zz, Zz, Zz }, 0 },
779 { "xor", t_done, 0, true, { Zz, Zz, Zz }, 0 },
780 { "cmp", t_done, 0, true, { Zz, Zz, Zz }, 0 }
783 { /* group 2 - only opcode is defined here,
784 operands are defined in the one or two byte maps below */
785 { "rol", t_done, 0, true, { Zz, Zz, Zz }, 0 },
786 { "ror", t_done, 0, true, { Zz, Zz, Zz }, 0 },
787 { "rcl", t_done, 0, true, { Zz, Zz, Zz }, 0 },
788 { "rcr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
789 { "shl/sal", t_done, 0, true, { Zz, Zz, Zz }, 0 },
790 { "shr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
791 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
792 { "sar", t_done, 0, true, { Zz, Zz, Zz }, 0 }
795 { /* group 3a - operands are defined here */
796 { "test", t_done, 0, true, { Eb, Ib, Zz }, 0 },
797 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
798 { "not", t_done, 0, true, { Eb, Zz, Zz }, 0 },
799 { "neg", t_done, 0, true, { Eb, Zz, Zz }, 0 },
800 { "mul", t_done, 0, true, { AL, Eb, Zz }, 0 },
801 { "imul", t_done, 0, true, { AL, Eb, Zz }, 0 },
802 { "div", t_done, 0, true, { AL, Eb, Zz }, 0 },
803 { "idiv", t_done, 0, true, { AL, Eb, Zz }, 0 }
806 { /* group 3b - operands are defined here */
807 { "test", t_done, 0, true, { Ev, Iv, Zz }, 0 },
808 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
809 { "not", t_done, 0, true, { Ev, Zz, Zz }, 0 },
810 { "neg", t_done, 0, true, { Ev, Zz, Zz }, 0 },
811 { "mul", t_done, 0, true, { eAX, Ev, Zz }, 0 },
812 { "imul", t_done, 0, true, { eAX, Ev, Zz }, 0 },
813 { "div", t_done, 0, true, { eAX, Ev, Zz }, 0 },
814 { "idiv", t_done, 0, true, { eAX, Ev, Zz }, 0 }
817 { /* group 4 - operands are defined here */
818 { "inc", t_done, 0, true, { Eb, Zz, Zz }, 0 },
819 { "dec", t_done, 0, true, { Eb, Zz, Zz }, 0 },
820 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
821 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
822 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
823 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
824 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
825 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
828 { /* group 5 - operands are defined here */
829 { "inc", t_done, 0, true, { Ev, Zz, Zz }, 0 },
830 { "dec", t_done, 0, true, { Ev, Zz, Zz }, 0 },
831 { "call", t_done, 0, true, { Ev, Zz, Zz }, (IS_CALL | INDIR) },
832 { "call", t_done, 0, true, { Ep, Zz, Zz }, (IS_CALL | INDIR) },
833 { "jmp", t_done, 0, true, { Ev, Zz, Zz }, (IS_JUMP | INDIR) },
834 { "jmp", t_done, 0, true, { Ep, Zz, Zz }, (IS_JUMP | INDIR) },
835 { "push", t_done, 0, true, { Ev, Zz, Zz }, 0 },
836 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
839 { /* group 6 - operands are defined here */
840 { "sldt", t_done, 0, true, { Ew, Zz, Zz }, 0 },
841 { "str", t_done, 0, true, { Ew, Zz, Zz }, 0 },
842 { "lldt", t_done, 0, true, { Ew, Zz, Zz }, 0 },
843 { "ltr", t_done, 0, true, { Ew, Zz, Zz }, 0 },
844 { "verr", t_done, 0, true, { Ew, Zz, Zz }, 0 },
845 { "verw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
846 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
847 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
850 { /* group 7 - operands are defined here */
851 { "sgdt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
852 { "sidt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
853 { "lgdt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
854 { "lidt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
855 { "smsw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
856 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
857 { "lmsw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
858 { "invlpg", t_done, 0, true, { Zz, Zz, Zz }, 0 },
861 { /* group 8 - only opcode is defined here,
862 operands are defined in the one or two byte maps below */
863 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
864 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
865 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
866 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
867 { "bt", t_done, 0, true, { Zz, Zz, Zz }, 0 },
868 { "bts", t_done, 0, true, { Zz, Zz, Zz }, 0 },
869 { "btr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
870 { "btc", t_done, 0, true, { Zz, Zz, Zz }, 0 },
873 { /* group 9 - operands are defined here */
874 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
875 { "cmpxch8b", t_done, 0, true, { Mq, Zz, Zz }, 0 },
876 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
877 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
878 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
879 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
880 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
881 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 }
884 /* group 10 is all illegal */
886 { /* group 11, opcodes defined in one byte map */
887 { "mov", t_done, 0, true, { Zz, Zz, Zz }, 0 },
888 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
889 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
890 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
891 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
892 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
893 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
894 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
900 // Groups 12-16 are split by mod={mem,11}. Some spill over into SSE groups!
901 // Notation: G12SSE010B = group 12, SSE, reg=010; B means mod=11
902 // Use A if Intel decides to put SSE instructions for mod=mem
903 static ia32_entry groupMap2[][2][8] = {
906 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
907 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
908 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
909 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
910 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
911 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
912 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
913 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
916 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
917 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
918 { 0, t_grpsse, G12SSE010B, true, { Zz, Zz, Zz }, 0 },
919 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
920 { 0, t_grpsse, G12SSE100B, true, { Zz, Zz, Zz }, 0 },
921 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
922 { 0, t_grpsse, G12SSE110B, true, { Zz, Zz, Zz }, 0 },
923 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
928 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
929 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
930 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
931 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
932 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
933 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
934 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
935 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
938 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
939 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
940 { 0, t_grpsse, G13SSE010B, true, { Zz, Zz, Zz }, 0 },
941 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
942 { 0, t_grpsse, G13SSE100B, true, { Zz, Zz, Zz }, 0 },
943 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
944 { 0, t_grpsse, G13SSE110B, true, { Zz, Zz, Zz }, 0 },
945 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
950 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
951 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
952 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
953 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
954 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
955 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
956 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
957 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
960 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
961 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
962 { 0, t_grpsse, G14SSE010B, true, { Zz, Zz, Zz }, 0 },
963 { 0, t_grpsse, G14SSE011B, true, { Zz, Zz, Zz }, 0 },
964 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
965 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
966 { 0, t_grpsse, G14SSE110B, true, { Zz, Zz, Zz }, 0 },
967 { 0, t_grpsse, G14SSE111B, true, { Zz, Zz, Zz }, 0 },
972 { "fxsave", t_done, 0, true, { Zz, Zz, Zz }, 0 },
973 { "fxrstor", t_done, 0, true, { Zz, Zz, Zz }, 0 },
974 { "ldmxcsr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
975 { "stmxcsr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
976 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
977 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
978 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
979 { "clflush", t_done, 0, true, { Zz, Zz, Zz }, 0 },
982 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
983 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
984 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
985 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
986 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
987 { "lfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
988 { "mfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
989 { "sfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
994 { "prefetchNTA", t_done, 0, true, { Zz, Zz, Zz }, 0 },
995 { "prefetchT0", t_done, 0, true, { Zz, Zz, Zz }, 0 },
996 { "prefetchT1", t_done, 0, true, { Zz, Zz, Zz }, 0 },
997 { "prefetchT2", t_done, 0, true, { Zz, Zz, Zz }, 0 },
998 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
999 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1000 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1001 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1004 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1005 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1006 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1007 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1008 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1009 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1010 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1011 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1016 /* rows are not, F3, 66, F2 prefixed in this order (see book) */
1017 static ia32_entry sseMap[][4] = {
1019 { "movups", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1020 { "movss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1021 { "movupd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1022 { "movsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1025 { "movups", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1026 { "movss", t_done, 0, true, { Wss, Vss, Zz }, 0 },
1027 { "movupd", t_done, 0, true, { Wpd, Vpd, Zz }, 0 },
1028 { "movsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 }, // FIXME: bug in book?????
1031 { "movlps/movhlps", t_done, 0, true, { Wq, Vq, Zz }, 0 }, // FIXME: wierd 1st op
1032 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1033 { "movlpd", t_done, 0, true, { Vq, Ws, Zz }, 0 },
1034 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1037 { "movlps", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1038 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1039 { "movlpd", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1040 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1043 { "unpcklps", t_done, 0, true, { Vps, Wq, Zz }, 0 },
1044 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1045 { "unpcklpd", t_done, 0, true, { Vpd, Wq, Zz }, 0 },
1046 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1049 { "unpckhps", t_done, 0, true, { Vps, Wq, Zz }, 0 },
1050 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1051 { "unpckhpd", t_done, 0, true, { Vpd, Wq, Zz }, 0 },
1052 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1055 { "movhps/movlhps", t_done, 0, true, { Vq, Wq, Zz }, 0 }, // FIXME: wierd 2nd op
1056 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1057 { "movhpd", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1058 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1061 { "movhps", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1062 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1063 { "movhpd", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1064 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1067 { "movaps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1068 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1069 { "movapd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1070 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1073 { "movaps", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1074 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1075 { "movapd", t_done, 0, true, { Wpd, Vpd, Zz }, 0 },
1076 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1079 { "cvtpi2ps", t_done, 0, true, { Vps, Qq, Zz }, 0 },
1080 { "cvtsi2ss", t_done, 0, true, { Vss, Ed, Zz }, 0 },
1081 { "cvtpi2pd", t_done, 0, true, { Vpd, Qdq, Zz }, 0 },
1082 { "cvtsi2sd", t_done, 0, true, { Vsd, Ed, Zz }, 0 },
1085 { "movntps", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1086 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1087 { "movntps", t_done, 0, true, { Wpd, Vpd, Zz }, 0 }, // should be movntpd ???
1088 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1091 { "cvttps2pi", t_done, 0, true, { Qq, Wps, Zz }, 0 },
1092 { "cvttss2si", t_done, 0, true, { Gd, Wss, Zz }, 0 },
1093 { "cvttpd2pi", t_done, 0, true, { Qdq, Wpd, Zz }, 0 },
1094 { "cvttsd2si", t_done, 0, true, { Gd, Wsd, Zz }, 0 },
1097 { "cvtps2pi", t_done, 0, true, { Qq, Wps, Zz }, 0 },
1098 { "cvtss2si", t_done, 0, true, { Gd, Wss, Zz }, 0 },
1099 { "cvtpd2pi", t_done, 0, true, { Qdq, Wpd, Zz }, 0 },
1100 { "cvtsd2si", t_done, 0, true, { Gd, Wsd, Zz }, 0 },
1103 { "ucomiss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1104 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1105 { "ucomisd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1106 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1109 { "comiss", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1110 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1111 { "comisd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1112 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1115 { "movmskps", t_done, 0, true, { Ed, Vps, Zz }, 0 },
1116 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1117 { "movmskpd", t_done, 0, true, { Ed, Vpd, Zz }, 0 },
1118 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1121 { "sqrtps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1122 { "sqrtss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1123 { "sqrtpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1124 { "sqrtsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1127 { "rsqrtps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1128 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1129 { "rsqrtss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1130 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1133 { "rcpps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1134 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1135 { "rcpss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1136 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1139 { "andps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1140 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1141 { "andpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1142 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1145 { "andnps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1146 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1147 { "andnpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1148 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1151 { "orps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1152 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1153 { "orpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1154 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1157 { "xorps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1158 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1159 { "xorpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1160 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1163 { "addps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1164 { "addss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1165 { "addpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1166 { "addsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1169 { "mulps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1170 { "mulss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1171 { "mulpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1172 { "mulsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1175 { "cvtps2pd", t_done, 0, true, { Vpd, Wps, Zz }, 0 },
1176 { "cvtss2sd", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1177 { "cvtpd2ps", t_done, 0, true, { Vps, Wpd, Zz }, 0 }, // FIXME: book bug ???
1178 { "cvtsd2ss", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1181 { "cvtdq2ps", t_done, 0, true, { Vps, Wdq, Zz }, 0 },
1182 { "cvttps2dq", t_done, 0, true, { Vdq, Wps, Zz }, 0 }, // book has this and next swapped!!!
1183 { "cvtps2dq", t_done, 0, true, { Vdq, Wps, Zz }, 0 }, // FIXME: book bug ???
1184 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1187 { "subps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1188 { "subss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1189 { "subpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1190 { "subsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1193 { "minps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1194 { "minss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1195 { "minpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1196 { "minsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1199 { "divps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1200 { "divss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1201 { "divpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1202 { "divsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1205 { "maxps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1206 { "maxss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1207 { "maxpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1208 { "maxsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1211 { "punpcklbw", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1212 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1213 { "punpcklbw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1214 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1217 { "punpcklwd", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1218 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1219 { "punpcklwd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1220 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1223 { "punpcklqd", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1224 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1225 { "punpcklqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1226 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1229 { "packsswb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1230 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1231 { "packsswb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1232 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1235 { "pcmpgtb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1236 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1237 { "pcmpgtb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1238 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1241 { "pcmpgtw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1242 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1243 { "pcmpgtw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1244 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1247 { "pcmpgdt", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1248 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1249 { "pcmpgdt", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1250 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1253 { "packuswb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1254 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1255 { "packuswb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1256 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1259 { "punpckhbw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1260 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1261 { "punpckhbw", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1262 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1265 { "punpckhwd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1266 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1267 { "punpckhwd", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1268 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1271 { "punpckhdq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1272 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1273 { "punpckhdq", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1274 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1277 { "packssdw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1278 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1279 { "packssdw", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1280 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1283 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1284 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1285 { "punpcklqld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1286 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1289 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1290 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1291 { "punpckhqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1292 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1295 { "movd", t_done, 0, true, { Pd, Ed, Zz }, 0 },
1296 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1297 { "movd", t_done, 0, true, { Vdq, Ed, Zz }, 0 },
1298 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1301 { "movq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1302 { "movdqu", t_done, 0, false, { Vdq, Wdq, Zz }, 0 }, // book has this and next swapped!!!
1303 { "movdqa", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1304 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1307 { "pshufw", t_done, 0, true, { Pq, Qq, Ib }, 0 },
1308 { "pshufhw", t_done, 0, true, { Vdq, Wdq, Ib }, 0 }, // book has this and next swapped!!!
1309 { "pshufd", t_done, 0, true, { Vdq, Wdq, Ib }, 0 },
1310 { "pshuflw", t_done, 0, true, { Vdq, Wdq, Ib }, 0 },
1313 { "pcmpeqb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1314 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1315 { "pcmpeqb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1316 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1319 { "pcmpeqw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1320 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1321 { "pcmpeqw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1322 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1325 { "pcmpeqd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1326 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1327 { "pcmpeqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1328 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1331 { "movd", t_done, 0, true, { Ed, Pd, Zz }, 0 },
1332 { "movq", t_done, 0, true, { Vq, Wq, Zz }, 0 }, // book has this and next swapped!!!
1333 { "movd", t_done, 0, true, { Ed, Vdq, Zz }, 0 },
1334 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1337 { "movq", t_done, 0, true, { Qq, Pq, Zz }, 0 },
1338 { "movdqu", t_done, 0, true, { Wdq, Vdq, Zz }, 0 }, // book has this and next swapped!!!
1339 { "movdqa", t_done, 0, true, { Wdq, Vdq, Zz }, 0 },
1340 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1343 { "cmpps", t_done, 0, true, { Vps, Wps, Ib }, 0 },
1344 { "cmpss", t_done, 0, true, { Vss, Wss, Ib }, 0 },
1345 { "cmppd", t_done, 0, true, { Vpd, Wpd, Ib }, 0 },
1346 { "cmpsd", t_done, 0, true, { Vsd, Wsd, Ib }, 0 },
1349 { "pinsrw", t_done, 0, true, { Pq, Ed, Ib }, 0 },
1350 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1351 { "pinsrw", t_done, 0, true, { Vdq, Ed, Ib }, 0 },
1352 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1355 { "pextrw", t_done, 0, true, { Gd, Pq, Ib }, 0 },
1356 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1357 { "pextrw", t_done, 0, true, { Gd, Vdq, Ib }, 0 },
1358 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1361 { "shufps", t_done, 0, true, { Vps, Wps, Ib }, 0 },
1362 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1363 { "shufpd", t_done, 0, true, { Vpd, Wpd, Ib }, 0 },
1364 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1367 { "psrlw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1368 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1369 { "psrlw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1370 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1373 { "psrld", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1374 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1375 { "psrld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1376 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1379 { "psrlq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1380 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1381 { "psrlq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1382 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1385 { "paddq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1386 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1387 { "psrlq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1388 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1391 { "pmullw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1392 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1393 { "pmullw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1394 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1397 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1398 { "movq2dq", t_done, 0, true, { Vdq, Qq, Zz }, 0 }, // lines jumbled in book
1399 { "movq", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1400 { "movdq2q", t_done, 0, true, { Pq, Wq, Zz }, 0 },
1403 { "pmovmskb", t_done, 0, true, { Gd, Pq, Zz }, 0 },
1404 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1405 { "pmovmskb", t_done, 0, true, { Gd, Vdq, Zz }, 0 },
1406 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1409 { "psubusb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1410 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1411 { "psubusb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1412 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1415 { "psubusw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1416 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1417 { "psubusw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1418 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1421 { "pminub", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1422 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1423 { "pminub", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1424 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1427 { "pand", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1428 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1429 { "pand", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1430 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1433 { "paddusb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1434 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1435 { "paddusb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1436 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1439 { "paddusw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1440 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1441 { "paddusw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1442 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1445 { "pmaxub", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1446 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1447 { "pmaxub", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1448 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1451 { "pandn", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1452 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1453 { "pandn", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1454 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1457 { "pavgb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1458 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1459 { "pavgb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1460 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1463 { "psraw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1464 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1465 { "psraw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1466 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1469 { "psrad", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1470 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1471 { "psrad", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1472 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1475 { "pavgw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1476 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1477 { "pavgw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1478 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1481 { "pmulhuw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1482 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1483 { "pmulhuw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1484 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1487 { "pmulhw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1488 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1489 { "pmulhw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1490 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1493 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1494 { "cvtdq2pd", t_done, 0, true, { Vpd, Wdq, Zz }, 0 }, // lines jumbled in book
1495 { "cvttpd2dq", t_done, 0, true, { Vdq, Wpd, Zz }, 0 },
1496 { "cvtpd2dq", t_done, 0, true, { Vdq, Wpd, Zz }, 0 },
1499 { "movntq", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1500 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1501 { "movntdq", t_done, 0, true, { Wdq, Vdq, Zz }, 0 },
1502 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1505 { "psubsb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1506 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1507 { "psubsb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1508 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1511 { "psubsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1512 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1513 { "psubsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1514 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1517 { "pminsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1518 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1519 { "pminsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1520 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1523 { "por", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1524 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1525 { "por", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1526 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1529 { "paddsb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1530 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1531 { "paddsb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1532 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1535 { "paddsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1536 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1537 { "paddsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1538 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1541 { "pmaxsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1542 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1543 { "pmaxsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1544 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1547 { "pxor", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1548 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1549 { "pxor", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1550 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1553 { "psllw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1554 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1555 { "psllw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1556 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1559 { "pslld", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1560 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1561 { "pslld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1562 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1565 { "psllq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1566 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1567 { "psllq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1568 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1571 { "pmuludq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1572 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1573 { "pmuludq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1574 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1577 { "pmaddwd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1578 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1579 { "pmaddwd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1580 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1583 { "psadbw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1584 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1585 { "psadbw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1586 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1589 { "maskmovq", t_done, 0, true, { Ppi, Qpi, Zz }, 0 },
1590 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1591 { "maskmovqu", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1592 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1595 { "psubb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1596 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1597 { "psubb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1598 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1601 { "psubw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1602 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1603 { "psubw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1604 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1607 { "psubd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1608 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1609 { "psubd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1610 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1612 { /* SSEFB */ // FIXME: Same????
1613 { "psubd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1614 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1615 { "psubd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1616 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1619 { "paddb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1620 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1621 { "paddb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1622 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1625 { "paddw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1626 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1627 { "paddw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1628 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1631 { "paddd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1632 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1633 { "paddd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1634 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1638 /* rows are none or 66 prefixed in this order (see book) */
1639 static ia32_entry ssegrpMap[][2] = {
1642 { "psrlw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1643 { "psrlw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1647 { "psraw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1648 { "psraw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1652 { "psllw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1653 { "psllw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1657 { "psrld", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1658 { "psrld", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1662 { "psrad", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1663 { "psrad", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1667 { "pslld", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1668 { "pslld", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1672 { "psrlq", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1673 { "psrlq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1677 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1678 { "psrldq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1682 { "psllq", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1683 { "psllq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1687 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1688 { "pslldq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1692 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr, const unsigned char* addr);
1694 template <unsigned int capa>
1695 ia32_instruction& ia32_decode(const unsigned char* addr, ia32_instruction& instruct)
1697 ia32_prefixes& pref = instruct.prf;
1698 unsigned int table, nxtab;
1699 unsigned int idx, sseidx = 0;
1700 ia32_entry *gotit = NULL;
1702 // if (capa & IA32_DECODE_PREFIXES) {
1706 ia32_decode_prefixes(addr, pref);
1707 instruct.size = pref.getCount();
1708 addr += instruct.size;
1712 gotit = &oneByteMap[idx];
1713 nxtab = gotit->otable;
1717 while(nxtab != t_done) {
1722 gotit = &twoByteMap[idx];
1723 nxtab = gotit->otable;
1728 sseidx = gotit->tabidx;
1729 assert(addr[0] == 0x0F);
1731 gotit = &twoByteMap[idx];
1732 nxtab = gotit->otable;
1737 idx = gotit->tabidx;
1738 gotit = &sseMap[idx][sseidx];
1739 nxtab = gotit->otable;
1742 idx = gotit->tabidx;
1743 unsigned int reg = (addr[0] >> 3) & 7;
1750 // leave table unchanged because operands are in not defined in group map
1751 nxtab = groupMap[idx][reg].otable;
1752 assert(nxtab==t_done || nxtab==t_ill);
1755 gotit = &groupMap[idx][reg];
1756 nxtab = gotit->otable;
1759 unsigned int mod = addr[0] >> 6;
1760 gotit = &groupMap2[idx-Grp12][mod==3][reg];
1766 idx = gotit->tabidx;
1767 gotit = &ssegrpMap[idx][sseidx];
1770 instruct.legacy_type = 0;
1771 return ia32_decode_FP(pref, addr, instruct);
1773 instruct.legacy_type = ILLEGAL;
1776 assert(!"wrong table");
1780 // addr points after the opcode, and the size has been adjusted accordingly
1781 // also the SSE index is set; now 'table' points to the correct instruction map
1783 assert(gotit != NULL);
1784 instruct.legacy_type = gotit->legacyType;
1786 ia32_decode_operands(pref, *gotit, addr, instruct); // all but FP
1791 template ia32_instruction& ia32_decode<0>(const unsigned char* addr, ia32_instruction& instruct);
1793 ia32_instruction& ia32_decode_FP(const ia32_prefixes& pref, const unsigned char* addr,
1794 ia32_instruction& instruct)
1796 unsigned int nib = byteSzB; // modRM
1797 unsigned int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2); // 32-bit mode implicit
1799 if (addr[0] <= 0xBF) { // modrm
1800 nib += ia32_decode_modrm(addrSzAttr, addr);
1802 instruct.size += nib;
1808 // ia32_entry& ia32_decode_opcode()
1813 #define byteSzB 1 /* size of a byte operand */
1814 #define wordSzB 2 /* size of a word operand */
1815 #define dwordSzB 4 /* size of a dword operand */
1817 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr, const unsigned char* addr)
1819 unsigned char modrm = addr[0];
1820 unsigned char mod = modrm >> 6;
1821 unsigned char rm = modrm & 7;
1822 //unsigned char reg = (modrm >> 3) & 7;
1824 if(addrSzAttr == 1) { // 16-bit, cannot have SIB
1827 return rm==6 ? wordSzB : 0;
1838 else { // 32-bit, may have SIB
1840 return 0; // only registers, no SIB
1841 bool hassib = rm == 4;
1842 unsigned int nsib = 0;
1844 unsigned char base = 0;
1852 /* this is tricky: there is a disp32 iff (1) rm == 5 or (2) rm == 4 && base == 5 */
1853 unsigned char check5 = hassib ? base : rm;
1854 return nsib + ((check5 == 5) ? dwordSzB : 0);
1857 return nsib + byteSzB;
1859 return nsib + dwordSzB;
1867 unsigned int ia32_decode_operands (const ia32_prefixes& pref, const ia32_entry& gotit,
1868 const unsigned char* addr, ia32_instruction& instruct)
1870 unsigned int nib = 0; /* # of bytes in instruction */
1871 unsigned int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2); // 32-bit mode implicit
1872 unsigned int operSzAttr = (pref.getPrefix(2) == PREFIX_SZOPER ? 1 : 2); // 32-bit mode implicit
1877 for(unsigned int i=0; i<3; ++i) {
1878 const ia32_operand& op = gotit.operands[i];
1881 case am_A: /* address = segment + offset (word or dword) */
1883 case am_O: /* operand offset */
1884 nib += wordSzB * addrSzAttr;
1886 case am_C: /* control register */
1887 case am_D: /* debug register */
1888 case am_F: /* flags register */
1889 case am_G: /* general purpose register, selecteb by reg field */
1890 case am_R: /* general purpose register, selected by mod field */
1891 case am_S: /* segment register */
1892 case am_reg: /* register implicitely encoded in opcode */
1894 case am_E: /* register or memory location, so decoding needed */
1895 case am_M: /* memory operand, decoding needed; size includes modRM byte */
1896 nib += ia32_decode_modrm(addrSzAttr, addr);
1898 case am_I: /* immediate data */
1899 case am_J: /* instruction pointer offset */
1905 nib += wordSzB * operSzAttr;
1911 /* Don't forget these... */
1912 case am_X: /* memory at DS:(E)SI*/
1913 case am_Y: /* memory at ES:(E)DI*/
1922 instruct.size += nib;
1926 // A couple of instantiations
1928 // ia32_instruction& ia32_decode<IA32_FULL_DECODER>(const unsigned char*, ia32_instruction&);
1930 static const unsigned char sse_prefix[256] = {
1931 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1932 /* ------------------------------- */
1933 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1934 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1935 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1936 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1937 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1938 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1939 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1940 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1941 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1942 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1943 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1944 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1945 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1946 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1947 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1948 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1949 /* ------------------------------- */
1950 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1953 // FIXME: lookahead might blow up...
1954 ia32_prefixes& ia32_decode_prefixes(const unsigned char* addr, ia32_prefixes& pref)
1957 pref.prfx[0] = pref.prfx[1] = pref.prfx[2] = pref.prfx[3] = 0;
1958 bool in_prefix = true;
1964 if(addr[1]==0x0F && sse_prefix[addr[2]])
1968 pref.prfx[0] = addr[0];
1977 pref.prfx[1] = addr[0];
1980 if(addr[1]==0x0F && sse_prefix[addr[2]])
1983 pref.prfx[2] = addr[0];
1987 pref.prfx[3] = addr[0];
1995 //printf("Got %d prefixes\n", pref.count);
1999 unsigned int ia32_emulate_old_type(ia32_instruction& instruct)
2001 const ia32_prefixes& pref = instruct.prf;
2002 unsigned int& insnType = instruct.legacy_type;
2003 unsigned int operSzAttr = (pref.getPrefix(2) == PREFIX_SZOPER ? 1 : 2); // 32-bit mode implicit
2005 if (pref.getPrefix(0)) // no distinction between these
2006 insnType |= PREFIX_INST;
2007 if (pref.getPrefix(3) == PREFIX_SZADDR)
2008 insnType |= PREFIX_ADDR;
2009 if (pref.getPrefix(2) == PREFIX_SZOPER)
2010 insnType |= PREFIX_OPR;
2011 if (pref.getPrefix(1))
2012 insnType |= PREFIX_SEG; // no distinction between segments
2014 if (insnType & REL_X) {
2015 if (operSzAttr == 1)
2020 else if (insnType & PTR_WX) {
2021 if (operSzAttr == 1)