1 // $Id: arch-ia32.C,v 1.2 2002/06/07 20:17:54 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
10 #include "common/h/Types.h"
11 #include "arch-ia32.h"
13 // tables and pseudotables
15 t_ill=0, t_oneB, t_twoB, t_prefixedSSE, t_coprocEsc, t_grp, t_sse, t_grpsse, t_done=99
18 #define oneB t_done, 0
19 #define twoB t_done, 0
23 Grp1=0, Grp2, Grp3a, Grp3b, Grp4, Grp5, Grp6, Grp7, Grp8, Grp9,
24 Grp11, Grp12, Grp13, Grp14, Grp15, Grp16
29 SSE10=0, SSE11, SSE12, SSE13, SSE14, SSE15, SSE16, SSE17,
30 SSE28, SSE29, SSE2A, SSE2B, SSE2C, SSE2D, SSE2E, SSE2F,
31 SSE50, SSE51, SSE52, SSE53, SSE54, SSE55, SSE56, SSE57,
32 SSE58, SSE59, SSE5A, SSE5B, SSE5C, SSE5D, SSE5E, SSE5F,
33 SSE60, SSE61, SSE62, SSE63, SSE64, SSE65, SSE66, SSE67,
34 SSE68, SSE69, SSE6A, SSE6B, SSE6C, SSE6D, SSE6E, SSE6F,
35 SSE70, SSE74, SSE75, SSE76,
37 SSEC2, SSEC4, SSEC5, SSEC6,
38 SSED1, SSED2, SSED3, SSED4, SSED5, SSED6, SSED7,
39 SSED8, SSED9, SSEDA, SSEDB, SSEDC, SSEDD, SSEDE, SSEDF,
40 SSEE0, SSEE1, SSEE2, SSEE3, SSEE4, SSEE5, SSEE6, SSEE7,
41 SSEE8, SSEE9, SSEEA, SSEEB, SSEEC, SSEED, SSEEE, SSEEF,
42 SSEF1, SSEF2, SSEF3, SSEF4, SSEF5, SSEF6, SSEF7,
43 SSEF8, SSEF9, SSEFA, SSEFB, SSEFC, SSEFD, SSEFE
48 G12SSE010B=0, G12SSE100B, G12SSE110B,
49 G13SSE010B, G13SSE100B, G13SSE110B,
50 G14SSE010B, G14SSE011B, G14SSE110B, G14SSE111B,
53 // addressing methods (see appendix A-2)
54 enum { am_A=1, am_C, am_D, am_E, am_F, am_G, am_I, am_J, am_M, am_O,
55 am_P, am_Q, am_R, am_S, am_T, am_V, am_W, am_X, am_Y, am_reg };
57 // operand types (idem, but I invented lea for consistency; op_ didn't seem a good idea)
58 // beware that not all operand types in the tables are explained!!! Guess what they mean...
59 enum { op_a=1, op_b, op_c, op_d, op_dq, op_p, op_pd, op_pi, op_ps,
60 op_q, op_s, op_sd, op_ss, op_si, op_v, op_w, op_lea };
62 // registers [only fancy names, not used right now]
63 enum { r_AH=100, r_BH, r_CH, r_DH, r_AL, r_BL, r_CL, r_DL,
65 r_eAX, r_eBX, r_eCX, r_eDX,
66 r_EAX, r_EBX, r_ECX, r_EDX,
67 r_DS, r_ES, r_FS, r_GS, r_SS,
68 r_eSP, r_eBP, r_eSI, r_eDI,
69 r_ESP, r_EBP, r_ESI, r_EDI };
72 #define Ap { am_A, op_p }
73 #define Cd { am_C, op_d }
74 #define Dd { am_D, op_d }
75 #define Eb { am_E, op_b }
76 #define Ed { am_E, op_d }
77 #define Ep { am_E, op_p }
78 #define Ev { am_E, op_v }
79 #define Ew { am_E, op_w }
80 #define Fv { am_F, op_v }
81 #define Gb { am_G, op_b }
82 #define Gd { am_G, op_d }
83 #define Gv { am_G, op_v }
84 #define Gw { am_G, op_w }
85 #define Ib { am_I, op_b }
86 #define Iv { am_I, op_v }
87 #define Iw { am_I, op_w }
88 #define Jb { am_J, op_b }
89 #define Jv { am_J, op_v }
90 #define Ma { am_M, op_a }
91 #define Mlea { am_M, op_lea }
92 #define Mp { am_M, op_p }
93 #define Ms { am_M, op_s }
94 #define Mq { am_M, op_q }
95 #define Ob { am_O, op_b }
96 #define Ov { am_O, op_v }
97 #define Pd { am_P, op_d }
98 #define Pdq { am_P, op_dq }
99 #define Ppi { am_P, op_pi }
100 #define Pq { am_P, op_q }
101 #define Qdq { am_Q, op_dq }
102 #define Qd { am_Q, op_d }
103 #define Qpi { am_Q, op_pi }
104 #define Qq { am_Q, op_q }
105 #define Rd { am_R, op_d }
106 #define Td { am_T, op_d }
107 #define Sw { am_S, op_w }
108 #define Vdq { am_V, op_dq }
109 #define Vpd { am_V, op_pd }
110 #define Vps { am_V, op_ps }
111 #define Vq { am_V, op_q }
112 #define Vss { am_V, op_ss }
113 #define Vsd { am_V, op_sd }
114 #define Wdq { am_W, op_dq }
115 #define Wpd { am_W, op_pd }
116 #define Wps { am_W, op_ps }
117 #define Wq { am_W, op_q }
118 #define Ws { am_W, op_s }
119 #define Wsd { am_W, op_sd }
120 #define Wss { am_W, op_ss }
121 #define Xb { am_X, op_b }
122 #define Xv { am_X, op_v }
123 #define Yb { am_Y, op_b }
124 #define Yv { am_Y, op_v }
126 #define AH { am_reg, r_AH }
127 #define BH { am_reg, r_BH }
128 #define CH { am_reg, r_CH }
129 #define DH { am_reg, r_DH }
130 #define AL { am_reg, r_AL }
131 #define BL { am_reg, r_BL }
132 #define CL { am_reg, r_CL }
133 #define DL { am_reg, r_DL }
134 #define DX { am_reg, r_DX }
135 #define eAX { am_reg, r_eAX }
136 #define eBX { am_reg, r_eBX }
137 #define eCX { am_reg, r_eCX }
138 #define eDX { am_reg, r_eDX }
139 #define EAX { am_reg, r_EAX }
140 #define EBX { am_reg, r_EBX }
141 #define ECX { am_reg, r_ECX }
142 #define EDX { am_reg, r_EDX }
143 #define DS { am_reg, r_DS }
144 #define ES { am_reg, r_ES }
145 #define FS { am_reg, r_FS }
146 #define GS { am_reg, r_GS }
147 #define SS { am_reg, r_SS }
148 #define eSP { am_reg, r_eSP }
149 #define eBP { am_reg, r_eBP }
150 #define eSI { am_reg, r_eSI }
151 #define eDI { am_reg, r_eDI }
152 #define ESP { am_reg, r_ESP }
153 #define EBP { am_reg, r_EBP }
154 #define ESI { am_reg, r_ESI }
155 #define EDI { am_reg, r_EDI }
158 struct ia32_operand {
159 unsigned int admet; // addressing method
160 unsigned int optype; // operand type;
163 // An instruction table entry
165 char *name; // name of the instruction (for debbuging only)
166 unsigned int otable; // which opcode table is next; if t_done it is the current one
167 unsigned char tabidx; // at what index to look, 0 if it easy to deduce from opcode
168 bool hasModRM; // true if the instruction has a MOD/RM byte
169 ia32_operand operands[3]; // operand descriptors
170 unsigned legacyType; // legacy type of the instruction (e.g. (IS_CALL | REL_W))
174 // oneByteMap: one byte opcode map
175 static ia32_entry oneByteMap[256] = {
177 { "add", t_done, 0, true, { Eb, Gb, Zz }, 0 },
178 { "add", t_done, 0, true, { Ev, Gv, Zz }, 0 },
179 { "add", t_done, 0, true, { Gb, Eb, Zz }, 0 },
180 { "add", t_done, 0, true, { Gv, Ev, Zz }, 0 },
181 { "add", t_done, 0, false, { AL, Ib, Zz }, 0 },
182 { "add", t_done, 0, false, { eAX, Iv, Zz }, 0 },
183 { "push", t_done, 0, false, { ES, Zz, Zz }, 0 },
184 { "pop", t_done, 0, false, { ES, Zz, Zz }, 0 },
186 { "or", t_done, 0, true, { Eb, Gb, Zz }, 0 },
187 { "or", t_done, 0, true, { Ev, Gv, Zz }, 0 },
188 { "or", t_done, 0, true, { Gb, Eb, Zz }, 0 },
189 { "or", t_done, 0, true, { Gv, Ev, Zz }, 0 },
190 { "or", t_done, 0, false, { AL, Ib, Zz }, 0 },
191 { "or", t_done, 0, false, { eAX, Iv, Zz }, 0 },
192 { "push", t_done, 0, false, { ES, Zz, Zz }, 0 },
193 { 0, t_twoB, 0, false, { Zz, Zz, Zz }, 0 },
195 { "adc", t_done, 0, true, { Eb, Gb, Zz }, 0 },
196 { "adc", t_done, 0, true, { Ev, Gv, Zz }, 0 },
197 { "adc", t_done, 0, true, { Gb, Eb, Zz }, 0 },
198 { "adc", t_done, 0, true, { Gv, Ev, Zz }, 0 },
199 { "adc", t_done, 0, false, { AL, Ib, Zz }, 0 },
200 { "adc", t_done, 0, false, { eAX, Iv, Zz }, 0 },
201 { "push", t_done, 0, false, { SS, Zz, Zz }, 0 },
202 { "pop", t_done, 0, false, { SS, Zz, Zz }, 0 },
204 { "sbb", t_done, 0, true, { Eb, Gb, Zz }, 0 },
205 { "sbb", t_done, 0, true, { Ev, Gv, Zz }, 0 },
206 { "sbb", t_done, 0, true, { Gb, Eb, Zz }, 0 },
207 { "sbb", t_done, 0, true, { Gv, Ev, Zz }, 0 },
208 { "sbb", t_done, 0, false, { AL, Ib, Zz }, 0 },
209 { "sbb", t_done, 0, false, { eAX, Iv, Zz }, 0 },
210 { "push", t_done, 0, false, { DS, Zz, Zz }, 0 },
211 { "pop" , t_done, 0, false, { DS, Zz, Zz }, 0 },
213 { "and", t_done, 0, true, { Eb, Gb, Zz }, 0 },
214 { "and", t_done, 0, true, { Ev, Gv, Zz }, 0 },
215 { "and", t_done, 0, true, { Gb, Eb, Zz }, 0 },
216 { "and", t_done, 0, true, { Gv, Ev, Zz }, 0 },
217 { "and", t_done, 0, false, { AL, Ib, Zz }, 0 },
218 { "and", t_done, 0, false, { eAX, Iv, Zz }, 0 },
219 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
220 { "daa", t_done, 0, false, { Zz, Zz, Zz }, 0 },
222 { "sub", t_done, 0, true, { Eb, Gb, Zz }, 0 },
223 { "sub", t_done, 0, true, { Ev, Gv, Zz }, 0 },
224 { "sub", t_done, 0, true, { Gb, Eb, Zz }, 0 },
225 { "sub", t_done, 0, true, { Gv, Ev, Zz }, 0 },
226 { "sub", t_done, 0, false, { AL, Ib, Zz }, 0 },
227 { "sub", t_done, 0, false, { eAX, Iv, Zz }, 0 },
228 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
229 { "das" , t_done, 0, false, { Zz, Zz, Zz }, 0 },
231 { "xor", t_done, 0, true, { Eb, Gb, Zz }, 0 },
232 { "xor", t_done, 0, true, { Ev, Gv, Zz }, 0 },
233 { "xor", t_done, 0, true, { Gb, Eb, Zz }, 0 },
234 { "xor", t_done, 0, true, { Gv, Ev, Zz }, 0 },
235 { "xor", t_done, 0, false, { AL, Ib, Zz }, 0 },
236 { "xor", t_done, 0, false, { eAX, Iv, Zz }, 0 },
237 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
238 { "aaa", t_done, 0, false, { Zz, Zz, Zz }, 0 },
240 { "cmp", t_done, 0, true, { Eb, Gb, Zz }, 0 },
241 { "cmp", t_done, 0, true, { Ev, Gv, Zz }, 0 },
242 { "cmp", t_done, 0, true, { Gb, Eb, Zz }, 0 },
243 { "cmp", t_done, 0, true, { Gv, Ev, Zz }, 0 },
244 { "cmp", t_done, 0, false, { AL, Ib, Zz }, 0 },
245 { "cmp", t_done, 0, false, { eAX, Iv, Zz }, 0 },
246 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
247 { "aas", t_done, 0, false, { Zz, Zz, Zz }, 0 },
249 { "inc", t_done, 0, false, { eAX, Zz, Zz }, 0 },
250 { "inc", t_done, 0, false, { eCX, Zz, Zz }, 0 },
251 { "inc", t_done, 0, false, { eDX, Zz, Zz }, 0 },
252 { "inc", t_done, 0, false, { eBX, Zz, Zz }, 0 },
253 { "inc", t_done, 0, false, { eSP, Zz, Zz }, 0 },
254 { "inc", t_done, 0, false, { eBP, Zz, Zz }, 0 },
255 { "inc", t_done, 0, false, { eSI, Zz, Zz }, 0 },
256 { "inc", t_done, 0, false, { eDI, Zz, Zz }, 0 },
258 { "dec", t_done, 0, false, { eAX, Zz, Zz }, 0 },
259 { "dec", t_done, 0, false, { eCX, Zz, Zz }, 0 },
260 { "dec", t_done, 0, false, { eDX, Zz, Zz }, 0 },
261 { "dec", t_done, 0, false, { eBX, Zz, Zz }, 0 },
262 { "dec", t_done, 0, false, { eSP, Zz, Zz }, 0 },
263 { "dec", t_done, 0, false, { eBP, Zz, Zz }, 0 },
264 { "dec", t_done, 0, false, { eSI, Zz, Zz }, 0 },
265 { "dec", t_done, 0, false, { eDI, Zz, Zz }, 0 },
267 { "push", t_done, 0, false, { eAX, Zz, Zz }, 0 },
268 { "push", t_done, 0, false, { eCX, Zz, Zz }, 0 },
269 { "push", t_done, 0, false, { eDX, Zz, Zz }, 0 },
270 { "push", t_done, 0, false, { eBX, Zz, Zz }, 0 },
271 { "push", t_done, 0, false, { eSP, Zz, Zz }, 0 },
272 { "push", t_done, 0, false, { eBP, Zz, Zz }, 0 },
273 { "push", t_done, 0, false, { eSI, Zz, Zz }, 0 },
274 { "push", t_done, 0, false, { eDI, Zz, Zz }, 0 },
276 { "pop", t_done, 0, false, { eAX, Zz, Zz }, 0 },
277 { "pop", t_done, 0, false, { eCX, Zz, Zz }, 0 },
278 { "pop", t_done, 0, false, { eDX, Zz, Zz }, 0 },
279 { "pop", t_done, 0, false, { eBX, Zz, Zz }, 0 },
280 { "pop", t_done, 0, false, { eSP, Zz, Zz }, 0 },
281 { "pop", t_done, 0, false, { eBP, Zz, Zz }, 0 },
282 { "pop", t_done, 0, false, { eSI, Zz, Zz }, 0 },
283 { "pop", t_done, 0, false, { eDI, Zz, Zz }, 0 },
285 { "pusha(d)", t_done, 0, false, { Zz, Zz, Zz }, 0 },
286 { "popa(d)", t_done, 0, false, { Zz, Zz, Zz }, 0 },
287 { "bound", t_done, 0, true, { Gv, Ma, Zz }, 0 },
288 { "arpl", t_done, 0, true, { Ew, Gw, Zz }, 0 },
289 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
290 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_SEG_OVR
291 { 0, t_prefixedSSE, 2, false, { Zz, Zz, Zz }, 0 }, /* operand size prefix (PREFIX_OPR_SZ)*/
292 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, /* address size prefix (PREFIX_ADDR_SZ)*/
294 { "push", t_done, 0, false, { Iv, Zz, Zz }, 0 },
295 { "imul", t_done, 0, true, { Gv, Ev, Iv }, 0 },
296 { "push", t_done, 0, false, { Ib, Zz, Zz }, 0 },
297 { "imul", t_done, 0, true, { Gv, Ev, Ib }, 0 },
298 { "insb", t_done, 0, false, { Yb, DX, Zz }, 0 },
299 { "insw/d", t_done, 0, false, { Yv, DX, Zz }, 0 },
300 { "outsb", t_done, 0, false, { DX, Xb, Zz }, 0 },
301 { "outsw/d", t_done, 0, false, { DX, Xv, Zz }, 0 },
303 { "jo", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
304 { "jno", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
305 { "jb/jnaej/j", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
306 { "jnb/jae/j", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
307 { "jz", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
308 { "jnz", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
309 { "jbe", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
310 { "jnbe", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
312 { "js", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
313 { "jns", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
314 { "jp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
315 { "jnp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
316 { "jl", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
317 { "jnl", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
318 { "jle", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
319 { "jnle", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
321 { 0, t_grp, Grp1, true, { Eb, Ib, Zz }, 0 },
322 { 0, t_grp, Grp1, true, { Ev, Iv, Zz }, 0 },
323 { 0, t_grp, Grp1, true, { Eb, Ib, Zz }, 0 }, // this was Ill in the old decoder and in gdb 5.2.
324 // the book says Grp1 however;sandpile.org agrees.
325 { 0, t_grp, Grp1, true, { Ev, Ib, Zz }, 0 },
326 { "test", t_done, 0, true, { Eb, Gb, Zz }, 0 },
327 { "test", t_done, 0, true, { Ev, Gv, Zz }, 0 },
328 { "xchg", t_done, 0, true, { Eb, Gb, Zz }, 0 },
329 { "xchg", t_done, 0, true, { Ev, Gv, Zz }, 0 },
331 { "mov", t_done, 0, true, { Eb, Gb, Zz }, 0 },
332 { "mov", t_done, 0, true, { Ev, Gv, Zz }, 0 },
333 { "mov", t_done, 0, true, { Gb, Eb, Zz }, 0 },
334 { "mov", t_done, 0, true, { Gv, Ev, Zz }, 0 },
335 { "mov", t_done, 0, true, { Ew, Sw, Zz }, 0 },
336 { "lea", t_done, 0, true, { Gv, Mlea, Zz }, 0 }, // this is just M in the book
337 { "mov", t_done, 0, true, { Sw, Ew, Zz }, 0 },
338 { "pop", t_done, 0, true, { Ev, Zz, Zz }, 0 },
340 { "nop", t_done, 0, false, { Zz, Zz, Zz }, 0 },
341 { "xchg", t_done, 0, false, { eCX, Zz, Zz }, 0 },
342 { "xchg", t_done, 0, false, { eDX, Zz, Zz }, 0 },
343 { "xchg", t_done, 0, false, { eBX, Zz, Zz }, 0 },
344 { "xchg", t_done, 0, false, { eSP, Zz, Zz }, 0 },
345 { "xchg", t_done, 0, false, { eBP, Zz, Zz }, 0 },
346 { "xchg", t_done, 0, false, { eSI, Zz, Zz }, 0 },
347 { "xchg", t_done, 0, false, { eDI, Zz, Zz }, 0 },
349 { "cbw", t_done, 0, false, { Zz, Zz, Zz }, 0 },
350 { "cwd/cdq", t_done, 0, false, { Zz, Zz, Zz }, 0 },
351 { "call", t_done, 0, false, { Ap, Zz, Zz }, IS_CALL | PTR_WX },
352 { "wait", t_done, 0, false, { Zz, Zz, Zz }, 0 },
353 { "pushf", t_done, 0, false, { Fv, Zz, Zz }, 0 },
354 { "pop", t_done, 0, false, { Fv, Zz, Zz }, 0 },
355 { "sahf", t_done, 0, false, { Zz, Zz, Zz }, 0 },
356 { "lahf", t_done, 0, false, { Zz, Zz, Zz }, 0 },
358 { "mov", t_done, 0, false, { AL, Ob, Zz }, 0 },
359 { "mov", t_done, 0, false, { eAX, Ov, Zz }, 0 },
360 { "mov", t_done, 0, false, { Ob, AL, Zz }, 0 },
361 { "mov", t_done, 0, false, { Ov, eAX, Zz }, 0 },
362 { "movsb", t_done, 0, false, { Xb, Yb, Zz }, 0 },
363 { "movsw", t_done, 0, false, { Xv, Yv, Zz }, 0 },
364 { "cmpsb", t_done, 0, false, { Xb, Yb, Zz }, 0 },
365 { "cmpsw", t_done, 0, false, { Xv, Yv, Zz }, 0 },
367 { "test", t_done, 0, false, { AL, Ib, Zz }, 0 },
368 { "test", t_done, 0, false, { eAX, Iv, Zz }, 0 },
369 { "stopsb", t_done, 0, false, { Yb, AL, Zz }, 0 },
370 { "stopsw/d", t_done, 0, false, { Yv, eAX, Zz }, 0 },
371 { "lodsb", t_done, 0, false, { AL, Xb, Zz }, 0 },
372 { "lodsw", t_done, 0, false, { eAX, Xv, Zz }, 0 },
373 { "scasb", t_done, 0, false, { AL, Yb, Zz }, 0 },
374 { "scasw/d", t_done, 0, false, { eAX, Yv, Zz }, 0 },
376 { "mov", t_done, 0, false, { AL, Ib, Zz }, 0 },
377 { "mov", t_done, 0, false, { CL, Ib, Zz }, 0 },
378 { "mov", t_done, 0, false, { DL, Ib, Zz }, 0 },
379 { "mov", t_done, 0, false, { BL, Ib, Zz }, 0 },
380 { "mov", t_done, 0, false, { AH, Ib, Zz }, 0 },
381 { "mov", t_done, 0, false, { CH, Ib, Zz }, 0 },
382 { "mov", t_done, 0, false, { DH, Ib, Zz }, 0 },
383 { "mov", t_done, 0, false, { BH, Ib, Zz }, 0 },
385 { "mov", t_done, 0, false, { eAX, Iv, Zz }, 0 },
386 { "mov", t_done, 0, false, { eCX, Iv, Zz }, 0 },
387 { "mov", t_done, 0, false, { eDX, Iv, Zz }, 0 },
388 { "mov", t_done, 0, false, { eBX, Iv, Zz }, 0 },
389 { "mov", t_done, 0, false, { eSP, Iv, Zz }, 0 },
390 { "mov", t_done, 0, false, { eBP, Iv, Zz }, 0 },
391 { "mov", t_done, 0, false, { eSI, Iv, Zz }, 0 },
392 { "mov", t_done, 0, false, { eDI, Iv, Zz }, 0 },
394 { 0, t_grp, Grp2, true, { Eb, Ib, Zz }, 0 },
395 { 0, t_grp, Grp2, true, { Ev, Ib, Zz }, 0 },
396 { "ret near", t_done, 0, false, { Iw, Zz, Zz }, (IS_RET) },
397 { "ret near", t_done, 0, false, { Zz, Zz, Zz }, (IS_RET) },
398 { "les", t_done, 0, true, { Gv, Mp, Zz }, 0 },
399 { "lds", t_done, 0, true, { Gv, Mp, Zz }, 0 },
400 { 0, t_grp, Grp11, true, { Eb, Ib, Zz }, 0 },
401 { 0, t_grp, Grp11, true, { Ev, Iv, Zz }, 0 },
403 { "enter", t_done, 0, false, { Iw, Ib, Zz }, 0 },
404 { "leave", t_done, 0, false, { Zz, Zz, Zz }, 0 },
405 { "ret far", t_done, 0, false, { Iw, Zz, Zz }, (IS_RETF) },
406 { "ret far", t_done, 0, false, { Zz, Zz, Zz }, (IS_RETF) },
407 { "int 3", t_done, 0, false, { Zz, Zz, Zz }, 0 },
408 { "int", t_done, 0, false, { Ib, Zz, Zz }, 0 },
409 { "into", t_done, 0, false, { Zz, Zz, Zz }, 0 },
410 { "iret", t_done, 0, false, { Zz, Zz, Zz }, (IS_RET) },
412 { 0, t_grp, Grp2, true, { Eb, Zz, Zz }, 0 }, // const1
413 { 0, t_grp, Grp2, true, { Ev, Zz, Zz }, 0 }, // --"--
414 { 0, t_grp, Grp2, true, { Eb, CL, Zz }, 0 },
415 { 0, t_grp, Grp2, true, { Ev, CL, Zz }, 0 },
416 { "aam", t_done, 0, false, { Zz, Zz, Zz }, 0 },
417 { "aad", t_done, 0, false, { Zz, Zz, Zz }, 0 },
418 { "salc", t_done, 0, false, { Zz, Zz, Zz }, 0 }, // sandpile.org gives this as SALC; undocumeted
419 { "xlat", t_done, 0, false, { Zz, Zz, Zz }, 0 },
421 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
422 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
423 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
424 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
425 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
426 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
427 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
428 { 0, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0 },
430 { "loopn", t_done, 0, false, { Jb, Zz, Zz }, 0 },
431 { "loope", t_done, 0, false, { Jb, Zz, Zz }, 0 },
432 { "loop", t_done, 0, false, { Jb, Zz, Zz }, 0 },
433 { "jcxz/jec", t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B) },
434 { "in", t_done, 0, false, { AL, Ib, Zz }, 0 },
435 { "in", t_done, 0, false, { eAX, Ib, Zz }, 0 },
436 { "out", t_done, 0, false, { Ib, AL, Zz }, 0 },
437 { "out", t_done, 0, false, { Ib, eAX, Zz }, 0 },
439 { "call", t_done, 0, false, { Jv, Zz, Zz }, (IS_CALL | REL_X) },
440 { "jmp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JUMP | REL_X) },
441 { "jmp", t_done, 0, false, { Ap, Zz, Zz }, (IS_JUMP | PTR_WX) },
442 { "jmp", t_done, 0, false, { Jb, Zz, Zz }, (IS_JUMP | REL_B) },
443 { "in", t_done, 0, false, { AL, DX, Zz }, 0 },
444 { "in", t_done, 0, false, { eAX, DX, Zz }, 0 },
445 { "out", t_done, 0, false, { DX, AL, Zz }, 0 },
446 { "out", t_done, 0, false, { DX, eAX, Zz }, 0 },
448 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 }, // PREFIX_INSTR
449 { "int1", t_done, 0, false, { Zz, Zz, Zz }, 0 }, // INT1/ICEBP on sandpile; undocumented
450 { 0, t_prefixedSSE, 3, false, { Zz, Zz, Zz }, 0 },
451 { 0, t_prefixedSSE, 1, false, { Zz, Zz, Zz }, 0 },
452 { "hlt", t_done, 0, false, { Zz, Zz, Zz }, 0 },
453 { "cmc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
454 { 0, t_grp, Grp3a, true, { Zz, Zz, Zz }, 0 },
455 { 0, t_grp, Grp3b, true, { Zz, Zz, Zz }, 0 },
457 { "clc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
458 { "stc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
459 { "cli", t_done, 0, false, { Zz, Zz, Zz }, 0 },
460 { "sti", t_done, 0, false, { Zz, Zz, Zz }, 0 },
461 { "cld", t_done, 0, false, { Zz, Zz, Zz }, 0 },
462 { "std", t_done, 0, false, { Zz, Zz, Zz }, 0 },
463 { 0, t_grp, Grp4, true, { Zz, Zz, Zz }, 0 },
464 { 0, t_grp, Grp5, true, { Zz, Zz, Zz }, 0 }
468 // twoByteMap: two byte opcode instructions (first byte is 0x0F)
469 static ia32_entry twoByteMap[256] = {
471 { 0, t_grp, Grp6, true, { Zz, Zz, Zz }, 0 },
472 { 0, t_grp, Grp7, false, { Zz, Zz, Zz }, 0 },
473 { "lar", t_done, 0, true, { Gv, Ew, Zz }, 0 },
474 { "lsl", t_done, 0, true, { Gv, Ew, Zz }, 0 },
475 { 0, t_ill, 0, false, { Zz, Zz, Zz },0},
476 { "syscallAMD", t_done, 0, false, { Zz, Zz, Zz }, 0 },
477 { "clts", t_done, 0, false, { Zz, Zz, Zz }, 0 },
478 { "sysretAMD", t_done, 0, false, { Zz, Zz, Zz }, 0 },
480 { "invd", t_done, 0, false, { Zz, Zz, Zz }, 0 },
481 { "wbinvd", t_done, 0, false, { Zz, Zz, Zz }, 0 },
482 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
483 { "ud2", t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
484 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
485 {0, t_ill, 0,0, { Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
486 {0, t_ill, 0,0 ,{ Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
487 {0, t_ill, 0,0 ,{ Zz, Zz, Zz },0}, // FIXME: AMD 3DNOW
489 { 0, t_sse, SSE10, true, { Zz, Zz, Zz }, 0 },
490 { 0, t_sse, SSE11, true, { Zz, Zz, Zz }, 0 },
491 { 0, t_sse, SSE12, true, { Zz, Zz, Zz }, 0 },
492 { 0, t_sse, SSE13, true, { Zz, Zz, Zz }, 0 },
493 { 0, t_sse, SSE14, true, { Zz, Zz, Zz }, 0 },
494 { 0, t_sse, SSE15, true, { Zz, Zz, Zz }, 0 },
495 { 0, t_sse, SSE16, true, { Zz, Zz, Zz }, 0 },
496 { 0, t_sse, SSE17, true, { Zz, Zz, Zz }, 0 },
498 { 0, t_grp, Grp16, 0, { Zz, Zz, Zz }, 0 },
499 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
500 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
501 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
502 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
503 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
504 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
505 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
507 { "mov", t_done, 0, true, { Rd, Cd, Zz }, 0 },
508 { "mov", t_done, 0, true, { Rd, Dd, Zz }, 0 },
509 { "mov", t_done, 0, true, { Cd, Rd, Zz }, 0 },
510 { "mov", t_done, 0, true, { Dd, Rd, Zz }, 0 },
511 { "mov", t_done, 0, true, { Rd, Td, Zz }, 0 },
512 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
513 { "mov", t_done, 0, true, { Td, Rd, Zz }, 0 },
514 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
516 { 0, t_sse, SSE28, true, { Zz, Zz, Zz }, 0 },
517 { 0, t_sse, SSE29, true, { Zz, Zz, Zz }, 0 },
518 { 0, t_sse, SSE2A, true, { Zz, Zz, Zz }, 0 },
519 { 0, t_sse, SSE2B, true, { Zz, Zz, Zz }, 0 },
520 { 0, t_sse, SSE2C, true, { Zz, Zz, Zz }, 0 },
521 { 0, t_sse, SSE2D, true, { Zz, Zz, Zz }, 0 },
522 { 0, t_sse, SSE2E, true, { Zz, Zz, Zz }, 0 },
523 { 0, t_sse, SSE2F, true, { Zz, Zz, Zz }, 0 },
525 { "wrmsr", t_done, 0, false, { Zz, Zz, Zz }, 0 },
526 { "rdtsc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
527 { "rdmsr", t_done, 0, false, { Zz, Zz, Zz }, 0 },
528 { "rdpmc", t_done, 0, false, { Zz, Zz, Zz }, 0 },
529 { "sysenter", t_done, 0, false, { Zz, Zz, Zz }, 0 },
530 { "sysexit", t_done, 0, false, { Zz, Zz, Zz }, 0 },
531 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
532 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
534 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
535 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
536 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
537 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
538 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
539 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
540 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
541 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
543 { "cmovo", t_done, 0, true, { Gv, Ev, Zz }, 0 },
544 { "cmovno", t_done, 0, true, { Gv, Ev, Zz }, 0 },
545 { "cmovnae", t_done, 0, true, { Gv, Ev, Zz }, 0 },
546 { "cmovnb", t_done, 0, true, { Gv, Ev, Zz }, 0 },
547 { "cmove", t_done, 0, true, { Gv, Ev, Zz }, 0 },
548 { "cmovne", t_done, 0, true, { Gv, Ev, Zz }, 0 },
549 { "cmovbe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
550 { "cmovnbe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
552 { "cmovs", t_done, 0, true, { Gv, Ev, Zz }, 0 },
553 { "cmovns", t_done, 0, true, { Gv, Ev, Zz }, 0 },
554 { "cmovpe", t_done, 0, true, { Gv, Ev, Zz }, 0 },
555 { "cmovpo", t_done, 0, true, { Gv, Ev, Zz }, 0 },
556 { "cmovnge", t_done, 0, true, { Gv, Ev, Zz }, 0 },
557 { "cmovnl", t_done, 0, true, { Gv, Ev, Zz }, 0 },
558 { "cmovng", t_done, 0, true, { Gv, Ev, Zz }, 0 },
559 { "cmovnl", t_done, 0, true, { Gv, Ev, Zz }, 0 },
561 { 0, t_sse, SSE50, true, { Zz, Zz, Zz }, 0 },
562 { 0, t_sse, SSE51, true, { Zz, Zz, Zz }, 0 },
563 { 0, t_sse, SSE52, true, { Zz, Zz, Zz }, 0 },
564 { 0, t_sse, SSE53, true, { Zz, Zz, Zz }, 0 },
565 { 0, t_sse, SSE54, true, { Zz, Zz, Zz }, 0 },
566 { 0, t_sse, SSE55, true, { Zz, Zz, Zz }, 0 },
567 { 0, t_sse, SSE56, true, { Zz, Zz, Zz }, 0 },
568 { 0, t_sse, SSE57, true, { Zz, Zz, Zz }, 0 },
570 { 0, t_sse, SSE58, true, { Zz, Zz, Zz }, 0 },
571 { 0, t_sse, SSE59, true, { Zz, Zz, Zz }, 0 },
572 { 0, t_sse, SSE5A, true, { Zz, Zz, Zz }, 0 },
573 { 0, t_sse, SSE5B, true, { Zz, Zz, Zz }, 0 },
574 { 0, t_sse, SSE5C, true, { Zz, Zz, Zz }, 0 },
575 { 0, t_sse, SSE5D, true, { Zz, Zz, Zz }, 0 },
576 { 0, t_sse, SSE5E, true, { Zz, Zz, Zz }, 0 },
577 { 0, t_sse, SSE5F, true, { Zz, Zz, Zz }, 0 },
579 { 0, t_sse, SSE60, true, { Zz, Zz, Zz }, 0 },
580 { 0, t_sse, SSE61, true, { Zz, Zz, Zz }, 0 },
581 { 0, t_sse, SSE62, true, { Zz, Zz, Zz }, 0 },
582 { 0, t_sse, SSE63, true, { Zz, Zz, Zz }, 0 },
583 { 0, t_sse, SSE64, true, { Zz, Zz, Zz }, 0 },
584 { 0, t_sse, SSE65, true, { Zz, Zz, Zz }, 0 },
585 { 0, t_sse, SSE66, true, { Zz, Zz, Zz }, 0 },
586 { 0, t_sse, SSE67, true, { Zz, Zz, Zz }, 0 },
588 { 0, t_sse, SSE68, true, { Zz, Zz, Zz }, 0 },
589 { 0, t_sse, SSE69, true, { Zz, Zz, Zz }, 0 },
590 { 0, t_sse, SSE6A, true, { Zz, Zz, Zz }, 0 },
591 { 0, t_sse, SSE6B, true, { Zz, Zz, Zz }, 0 },
592 { 0, t_sse, SSE6C, true, { Zz, Zz, Zz }, 0 },
593 { 0, t_sse, SSE6D, true, { Zz, Zz, Zz }, 0 },
594 { 0, t_sse, SSE6E, true, { Zz, Zz, Zz }, 0 },
595 { 0, t_sse, SSE6F, true, { Zz, Zz, Zz }, 0 },
597 { 0, t_sse, SSE70, true, { Zz, Zz, Zz }, 0 },
598 { 0, t_grp, Grp12, false, { Zz, Zz, Zz }, 0 },
599 { 0, t_grp, Grp13, false, { Zz, Zz, Zz }, 0 },
600 { 0, t_grp, Grp14, false, { Zz, Zz, Zz }, 0 },
601 { 0, t_sse, SSE74, true, { Zz, Zz, Zz }, 0 },
602 { 0, t_sse, SSE75, true, { Zz, Zz, Zz }, 0 },
603 { 0, t_sse, SSE76, true, { Zz, Zz, Zz }, 0 },
604 { "emms", t_done, 0, false, { Zz, Zz, Zz }, 0 },
606 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
607 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
608 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
609 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
610 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
611 { "mmxud", t_ill, 0, 0, { Zz, Zz, Zz }, 0},
612 { 0, t_sse, SSE7E, 0, { Zz, Zz, Zz }, 0 },
613 { 0, t_sse, SSE7F, 0, { Zz, Zz, Zz }, 0 },
615 { "jo", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
616 { "jno", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
617 { "jb", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
618 { "jnb", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
619 { "jz", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
620 { "jnz", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
621 { "jbe", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
622 { "jnbe", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
624 { "js", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
625 { "jns", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
626 { "jp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
627 { "jnp", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
628 { "jl", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
629 { "jnl", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
630 { "jle", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
631 { "jnle", t_done, 0, false, { Jv, Zz, Zz }, (IS_JCC | REL_X) },
633 { "seto", t_done, 0, true, { Eb, Zz, Zz }, 0 },
634 { "setno", t_done, 0, true, { Eb, Zz, Zz }, 0 },
635 { "setb", t_done, 0, true, { Eb, Zz, Zz }, 0 },
636 { "setnb", t_done, 0, true, { Eb, Zz, Zz }, 0 },
637 { "setz", t_done, 0, true, { Eb, Zz, Zz }, 0 },
638 { "setnz", t_done, 0, true, { Eb, Zz, Zz }, 0 },
639 { "setbe", t_done, 0, true, { Eb, Zz, Zz }, 0 },
640 { "setnbe", t_done, 0, true, { Eb, Zz, Zz }, 0 },
642 { "sets", t_done, 0, true, { Eb, Zz, Zz }, 0 },
643 { "setns", t_done, 0, true, { Eb, Zz, Zz }, 0 },
644 { "setp", t_done, 0, true, { Eb, Zz, Zz }, 0 },
645 { "setnp", t_done, 0, true, { Eb, Zz, Zz }, 0 },
646 { "setl", t_done, 0, true, { Eb, Zz, Zz }, 0 },
647 { "setnl", t_done, 0, true, { Eb, Zz, Zz }, 0 },
648 { "setle", t_done, 0, true, { Eb, Zz, Zz }, 0 },
649 { "setnle", t_done, 0, true, { Eb, Zz, Zz }, 0 },
651 { "push", t_done, 0, false, { FS, Zz, Zz }, 0 },
652 { "pop", t_done, 0, false, { FS, Zz, Zz }, 0 },
653 { "cpuid", t_done, 0, false, { Zz, Zz, Zz }, 0 },
654 { "bt", t_done, 0, true, { Ev, Gv, Zz }, 0 },
655 { "shld", t_done, 0, true, { Ev, Gv, Ib }, 0 },
656 { "shld", t_done, 0, true, { Ev, Gv, CL }, 0 },
657 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0},
658 { 0, t_ill, 0, 0, { Zz, Zz, Zz }, 0},
660 { "push", t_done, 0, false, { GS, Zz, Zz }, 0 },
661 { "pop", t_done, 0, false, { GS, Zz, Zz }, 0 },
662 { "rsm", t_done, 0, false, { Zz, Zz, Zz }, 0 },
663 { "bts", t_done, 0, true, { Ev, Gv, Zz }, 0 },
664 { "shrd", t_done, 0, true, { Ev, Gv, Ib }, 0 },
665 { "shrd", t_done, 0, true, { Ev, Gv, CL }, 0 },
666 { 0, t_grp, Grp15, 0, { Zz, Zz, Zz }, 0 },
667 { "imul", t_done, 0, true, { Gv, Ev, Zz }, 0 },
669 { "cmpxch", t_done, 0, true, { Eb, Gb, Zz }, 0 },
670 { "cmpxch", t_done, 0, true, { Ev, Gv, Zz }, 0 },
671 { "lss", t_done, 0, true, { Mp, Zz, Zz }, 0 },
672 { "btr", t_done, 0, true, { Ev, Gv, Zz }, 0 },
673 { "lfs", t_done, 0, true, { Mp, Zz, Zz }, 0 },
674 { "lgs", t_done, 0, true, { Mp, Zz, Zz }, 0 },
675 { "movzx", t_done, 0, true, { Gv, Eb, Zz }, 0 },
676 { "movzx", t_done, 0, true, { Gv, Ew, Zz }, 0 },
678 {0,t_ill, 0,0,{ Zz, Zz, Zz },0},
679 { "ud2grp10", t_ill, 0, 0, { Zz, Zz, Zz }, 0 },
680 { 0, t_grp, Grp8, true, { Ev, Ib, Zz }, 0 },
681 { "btc", t_done, 0, true, { Ev, Gv, Zz }, 0 },
682 { "bsf", t_done, 0, true, { Gv, Ev, Zz }, 0 },
683 { "bsr", t_done, 0, true, { Gv, Ev, Zz }, 0 },
684 { "movsx", t_done, 0, true, { Gv, Eb, Zz }, 0 },
685 { "movsx", t_done, 0, true, { Gv, Ew, Zz }, 0 },
687 { "xadd", t_done, 0, true, { Eb, Gb, Zz }, 0 },
688 { "xadd", t_done, 0, true, { Ev, Gv, Zz }, 0 },
689 { 0, t_sse, SSEC2, true, { Zz, Zz, Zz }, 0 },
690 { "movnti" , t_done, 0, 0, { Ed, Gd, Zz }, 0 },
691 { 0, t_sse, SSEC4, true, { Zz, Zz, Zz }, 0 },
692 { 0, t_sse, SSEC5, true, { Zz, Zz, Zz }, 0 },
693 { 0, t_sse, SSEC6, true, { Zz, Zz, Zz }, 0 },
694 { 0, t_grp, Grp9, true, { Zz, Zz, Zz }, 0 },
696 { "bswap", t_done, 0, false, { EAX, Zz, Zz }, 0 },
697 { "bswap", t_done, 0, false, { ECX, Zz, Zz }, 0 },
698 { "bswap", t_done, 0, false, { EDX, Zz, Zz }, 0 },
699 { "bswap", t_done, 0, false, { EBX, Zz, Zz }, 0 },
700 { "bswap", t_done, 0, false, { ESP, Zz, Zz }, 0 },
701 { "bswap", t_done, 0, false, { EBP, Zz, Zz }, 0 },
702 { "bswap", t_done, 0, false, { ESI, Zz, Zz }, 0 },
703 { "bswap", t_done, 0, false, { EDI, Zz, Zz }, 0 },
705 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
706 { 0, t_sse, SSED1, true, { Zz, Zz, Zz }, 0 },
707 { 0, t_sse, SSED2, true, { Zz, Zz, Zz }, 0 },
708 { 0, t_sse, SSED3, true, { Zz, Zz, Zz }, 0 },
709 { 0, t_sse, SSED4, true, { Zz, Zz, Zz }, 0 },
710 { 0, t_sse, SSED5, true, { Zz, Zz, Zz }, 0 },
711 { 0, t_sse, SSED6, true, { Zz, Zz, Zz }, 0 },
712 { 0, t_sse, SSED7, true, { Zz, Zz, Zz }, 0 },
714 { 0, t_sse, SSED8, true, { Zz, Zz, Zz }, 0 },
715 { 0, t_sse, SSED9, true, { Zz, Zz, Zz }, 0 },
716 { 0, t_sse, SSEDA, true, { Zz, Zz, Zz }, 0 },
717 { 0, t_sse, SSEDB, true, { Zz, Zz, Zz }, 0 },
718 { 0, t_sse, SSEDC, true, { Zz, Zz, Zz }, 0 },
719 { 0, t_sse, SSEDD, true, { Zz, Zz, Zz }, 0 },
720 { 0, t_sse, SSEDE, true, { Zz, Zz, Zz }, 0 },
721 { 0, t_sse, SSEDF, true, { Zz, Zz, Zz }, 0 },
723 { 0, t_sse, SSEE0, true, { Zz, Zz, Zz }, 0 },
724 { 0, t_sse, SSEE1, true, { Zz, Zz, Zz }, 0 },
725 { 0, t_sse, SSEE2, true, { Zz, Zz, Zz }, 0 },
726 { 0, t_sse, SSEE3, true, { Zz, Zz, Zz }, 0 },
727 { 0, t_sse, SSEE4, true, { Zz, Zz, Zz }, 0 },
728 { 0, t_sse, SSEE5, true, { Zz, Zz, Zz }, 0 },
729 { 0, t_sse, SSEE6, true, { Zz, Zz, Zz }, 0 },
730 { 0, t_sse, SSEE7, true, { Zz, Zz, Zz }, 0 },
732 { 0, t_sse, SSEE8, true, { Zz, Zz, Zz }, 0 },
733 { 0, t_sse, SSEE9, true, { Zz, Zz, Zz }, 0 },
734 { 0, t_sse, SSEEA, true, { Zz, Zz, Zz }, 0 },
735 { 0, t_sse, SSEEB, true, { Zz, Zz, Zz }, 0 },
736 { 0, t_sse, SSEEC, true, { Zz, Zz, Zz }, 0 },
737 { 0, t_sse, SSEED, true, { Zz, Zz, Zz }, 0 },
738 { 0, t_sse, SSEEE, true, { Zz, Zz, Zz }, 0 },
739 { 0, t_sse, SSEEF, true, { Zz, Zz, Zz }, 0 },
741 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
742 { 0, t_sse, SSEF1, true, { Zz, Zz, Zz }, 0 },
743 { 0, t_sse, SSEF2, true, { Zz, Zz, Zz }, 0 },
744 { 0, t_sse, SSEF3, true, { Zz, Zz, Zz }, 0 },
745 { 0, t_sse, SSEF4, true, { Zz, Zz, Zz }, 0 },
746 { 0, t_sse, SSEF5, true, { Zz, Zz, Zz }, 0 },
747 { 0, t_sse, SSEF6, true, { Zz, Zz, Zz }, 0 },
748 { 0, t_sse, SSEF7, true, { Zz, Zz, Zz }, 0 },
750 { 0, t_sse, SSEF8, true, { Zz, Zz, Zz }, 0 },
751 { 0, t_sse, SSEF9, true, { Zz, Zz, Zz }, 0 },
752 { 0, t_sse, SSEFA, true, { Zz, Zz, Zz }, 0 },
753 { 0, t_sse, SSEFB, true, { Zz, Zz, Zz }, 0 },
754 { 0, t_sse, SSEFC, true, { Zz, Zz, Zz }, 0 },
755 { 0, t_sse, SSEFD, true, { Zz, Zz, Zz }, 0 },
756 { 0, t_sse, SSEFE, true, { Zz, Zz, Zz }, 0 },
757 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0}
760 static ia32_entry groupMap[][8] = {
761 { /* group 1 - only opcode is defined here,
762 operands are defined in the one or two byte maps below */
763 { "add", t_done, 0, true, { Zz, Zz, Zz }, 0 },
764 { "or", t_done, 0, true, { Zz, Zz, Zz }, 0 },
765 { "adc", t_done, 0, true, { Zz, Zz, Zz }, 0 },
766 { "sbb", t_done, 0, true, { Zz, Zz, Zz }, 0 },
767 { "and", t_done, 0, true, { Zz, Zz, Zz }, 0 },
768 { "sub", t_done, 0, true, { Zz, Zz, Zz }, 0 },
769 { "xor", t_done, 0, true, { Zz, Zz, Zz }, 0 },
770 { "cmp", t_done, 0, true, { Zz, Zz, Zz }, 0 }
773 { /* group 2 - only opcode is defined here,
774 operands are defined in the one or two byte maps below */
775 { "rol", t_done, 0, true, { Zz, Zz, Zz }, 0 },
776 { "ror", t_done, 0, true, { Zz, Zz, Zz }, 0 },
777 { "rcl", t_done, 0, true, { Zz, Zz, Zz }, 0 },
778 { "rcr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
779 { "shl/sal", t_done, 0, true, { Zz, Zz, Zz }, 0 },
780 { "shr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
781 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
782 { "sar", t_done, 0, true, { Zz, Zz, Zz }, 0 }
785 { /* group 3a - operands are defined here */
786 { "test", t_done, 0, true, { Eb, Ib, Zz }, 0 },
787 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
788 { "not", t_done, 0, true, { Eb, Zz, Zz }, 0 },
789 { "neg", t_done, 0, true, { Eb, Zz, Zz }, 0 },
790 { "mul", t_done, 0, true, { AL, Eb, Zz }, 0 },
791 { "imul", t_done, 0, true, { AL, Eb, Zz }, 0 },
792 { "div", t_done, 0, true, { AL, Eb, Zz }, 0 },
793 { "idiv", t_done, 0, true, { AL, Eb, Zz }, 0 }
796 { /* group 3b - operands are defined here */
797 { "test", t_done, 0, true, { Ev, Iv, Zz }, 0 },
798 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
799 { "not", t_done, 0, true, { Ev, Zz, Zz }, 0 },
800 { "neg", t_done, 0, true, { Ev, Zz, Zz }, 0 },
801 { "mul", t_done, 0, true, { eAX, Ev, Zz }, 0 },
802 { "imul", t_done, 0, true, { eAX, Ev, Zz }, 0 },
803 { "div", t_done, 0, true, { eAX, Ev, Zz }, 0 },
804 { "idiv", t_done, 0, true, { eAX, Ev, Zz }, 0 }
807 { /* group 4 - operands are defined here */
808 { "inc", t_done, 0, true, { Eb, Zz, Zz }, 0 },
809 { "dec", t_done, 0, true, { Eb, Zz, Zz }, 0 },
810 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
811 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
812 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
813 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
814 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
815 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
818 { /* group 5 - operands are defined here */
819 { "inc", t_done, 0, true, { Ev, Zz, Zz }, 0 },
820 { "dec", t_done, 0, true, { Ev, Zz, Zz }, 0 },
821 { "call", t_done, 0, true, { Ev, Zz, Zz }, (IS_CALL | INDIR) },
822 { "call", t_done, 0, true, { Ep, Zz, Zz }, (IS_CALL | INDIR) },
823 { "jmp", t_done, 0, true, { Ev, Zz, Zz }, (IS_JUMP | INDIR) },
824 { "jmp", t_done, 0, true, { Ep, Zz, Zz }, (IS_JUMP | INDIR) },
825 { "push", t_done, 0, true, { Ev, Zz, Zz }, 0 },
826 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
829 { /* group 6 - operands are defined here */
830 { "sldt", t_done, 0, true, { Ew, Zz, Zz }, 0 },
831 { "str", t_done, 0, true, { Ew, Zz, Zz }, 0 },
832 { "lldt", t_done, 0, true, { Ew, Zz, Zz }, 0 },
833 { "ltr", t_done, 0, true, { Ew, Zz, Zz }, 0 },
834 { "verr", t_done, 0, true, { Ew, Zz, Zz }, 0 },
835 { "verw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
836 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
837 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
840 { /* group 7 - operands are defined here */
841 { "sgdt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
842 { "sidt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
843 { "lgdt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
844 { "lidt", t_done, 0, true, { Ms, Zz, Zz }, 0 },
845 { "smsw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
846 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
847 { "lmsw", t_done, 0, true, { Ew, Zz, Zz }, 0 },
848 { "invlpg", t_done, 0, true, { Zz, Zz, Zz }, 0 },
851 { /* group 8 - only opcode is defined here,
852 operands are defined in the one or two byte maps below */
853 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
854 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
855 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
856 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
857 { "bt", t_done, 0, true, { Zz, Zz, Zz }, 0 },
858 { "bts", t_done, 0, true, { Zz, Zz, Zz }, 0 },
859 { "btr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
860 { "btc", t_done, 0, true, { Zz, Zz, Zz }, 0 },
863 { /* group 9 - operands are defined here */
864 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
865 { "cmpxch8b", t_done, 0, true, { Mq, Zz, Zz }, 0 },
866 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
867 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
868 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
869 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
870 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
871 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 }
874 /* group 10 is all illegal */
876 { /* group 11, opcodes defined in one byte map */
877 { "mov", t_done, 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 },
882 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
883 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
884 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
890 // Groups 12-16 are split by mod={mem,11}. Some spill over into SSE groups!
891 // Notation: G12SSE010B = group 12, SSE, reg=010; B means mod=11
892 // Use A if Intel decides to put SSE instructions for mod=mem
893 static ia32_entry groupMap2[][2][8] = {
896 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
897 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
898 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
899 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
900 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
901 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
902 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
903 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
906 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
907 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
908 { 0, t_grpsse, G12SSE010B, true, { Zz, Zz, Zz }, 0 },
909 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
910 { 0, t_grpsse, G12SSE100B, true, { Zz, Zz, Zz }, 0 },
911 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
912 { 0, t_grpsse, G12SSE110B, true, { Zz, Zz, Zz }, 0 },
913 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
918 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
919 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
920 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
921 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
922 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
923 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
924 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
925 { 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_grpsse, G13SSE010B, true, { Zz, Zz, Zz }, 0 },
931 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
932 { 0, t_grpsse, G13SSE100B, true, { Zz, Zz, Zz }, 0 },
933 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
934 { 0, t_grpsse, G13SSE110B, true, { Zz, Zz, Zz }, 0 },
935 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
940 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
941 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
942 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
943 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
944 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
945 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
946 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
947 { 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_grpsse, G14SSE010B, true, { Zz, Zz, Zz }, 0 },
953 { 0, t_grpsse, G14SSE011B, 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_grpsse, G14SSE110B, true, { Zz, Zz, Zz }, 0 },
957 { 0, t_grpsse, G14SSE111B, true, { Zz, Zz, Zz }, 0 },
962 { "fxsave", t_done, 0, true, { Zz, Zz, Zz }, 0 },
963 { "fxrstor", t_done, 0, true, { Zz, Zz, Zz }, 0 },
964 { "ldmxcsr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
965 { "stmxcsr", t_done, 0, true, { Zz, Zz, Zz }, 0 },
966 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
967 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
968 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
969 { "clflush", t_done, 0, true, { Zz, Zz, Zz }, 0 },
972 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
973 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
974 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
975 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
976 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
977 { "lfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
978 { "mfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
979 { "sfence", t_done, 0, true, { Zz, Zz, Zz }, 0 },
984 { "prefetchNTA", t_done, 0, true, { Zz, Zz, Zz }, 0 },
985 { "prefetchT0", t_done, 0, true, { Zz, Zz, Zz }, 0 },
986 { "prefetchT1", t_done, 0, true, { Zz, Zz, Zz }, 0 },
987 { "prefetchT2", t_done, 0, true, { Zz, Zz, Zz }, 0 },
988 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
989 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
990 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
991 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
994 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
995 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
996 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
997 { 0, t_ill, 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 },
1006 /* rows are not, F3, 66, F2 prefixed in this order (see book) */
1007 static ia32_entry sseMap[][4] = {
1009 { "movups", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1010 { "movss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1011 { "movupd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1012 { "movsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1015 { "movups", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1016 { "movss", t_done, 0, true, { Wss, Vss, Zz }, 0 },
1017 { "movupd", t_done, 0, true, { Wpd, Vpd, Zz }, 0 },
1018 { "movsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 }, // FIXME: bug in book?????
1021 { "movlps/movhlps", t_done, 0, true, { Wq, Vq, Zz }, 0 }, // FIXME: wierd 1st op
1022 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1023 { "movlpd", t_done, 0, true, { Vq, Ws, Zz }, 0 },
1024 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1027 { "movlps", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1028 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1029 { "movlpd", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1030 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1033 { "unpcklps", t_done, 0, true, { Vps, Wq, Zz }, 0 },
1034 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1035 { "unpcklpd", t_done, 0, true, { Vpd, Wq, Zz }, 0 },
1036 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1039 { "unpckhps", t_done, 0, true, { Vps, Wq, Zz }, 0 },
1040 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1041 { "unpckhpd", t_done, 0, true, { Vpd, Wq, Zz }, 0 },
1042 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1045 { "movhps/movlhps", t_done, 0, true, { Vq, Wq, Zz }, 0 }, // FIXME: wierd 2nd op
1046 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1047 { "movhpd", t_done, 0, true, { Vq, Wq, Zz }, 0 },
1048 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1051 { "movhps", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1052 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1053 { "movhpd", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1054 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1057 { "movaps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1058 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1059 { "movapd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1060 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1063 { "movaps", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1064 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1065 { "movapd", t_done, 0, true, { Wpd, Vpd, Zz }, 0 },
1066 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1069 { "cvtpi2ps", t_done, 0, true, { Vps, Qq, Zz }, 0 },
1070 { "cvtsi2ss", t_done, 0, true, { Vss, Ed, Zz }, 0 },
1071 { "cvtpi2pd", t_done, 0, true, { Vpd, Qdq, Zz }, 0 },
1072 { "cvtsi2sd", t_done, 0, true, { Vsd, Ed, Zz }, 0 },
1075 { "movntps", t_done, 0, true, { Wps, Vps, Zz }, 0 },
1076 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1077 { "movntps", t_done, 0, true, { Wpd, Vpd, Zz }, 0 }, // should be movntpd ???
1078 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1081 { "cvttps2pi", t_done, 0, true, { Qq, Wps, Zz }, 0 },
1082 { "cvttss2si", t_done, 0, true, { Gd, Wss, Zz }, 0 },
1083 { "cvttpd2pi", t_done, 0, true, { Qdq, Wpd, Zz }, 0 },
1084 { "cvttsd2si", t_done, 0, true, { Gd, Wsd, Zz }, 0 },
1087 { "cvtps2pi", t_done, 0, true, { Qq, Wps, Zz }, 0 },
1088 { "cvtss2si", t_done, 0, true, { Gd, Wss, Zz }, 0 },
1089 { "cvtpd2pi", t_done, 0, true, { Qdq, Wpd, Zz }, 0 },
1090 { "cvtsd2si", t_done, 0, true, { Gd, Wsd, Zz }, 0 },
1093 { "ucomiss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1094 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1095 { "ucomisd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1096 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1099 { "comiss", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1100 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1101 { "comisd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1102 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1105 { "movmskps", t_done, 0, true, { Ed, Vps, Zz }, 0 },
1106 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1107 { "movmskpd", t_done, 0, true, { Ed, Vpd, Zz }, 0 },
1108 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1111 { "sqrtps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1112 { "sqrtss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1113 { "sqrtpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1114 { "sqrtsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1117 { "rsqrtps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1118 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1119 { "rsqrtss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1120 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1123 { "rcpps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1124 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1125 { "rcpss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1126 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1129 { "andps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1130 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1131 { "andpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1132 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1135 { "andnps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1136 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1137 { "andnpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1138 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1141 { "orps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1142 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1143 { "orpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1144 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1147 { "xorps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1148 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1149 { "xorpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1150 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1153 { "addps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1154 { "addss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1155 { "addpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1156 { "addsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1159 { "mulps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1160 { "mulss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1161 { "mulpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1162 { "mulsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1165 { "cvtps2pd", t_done, 0, true, { Vpd, Wps, Zz }, 0 },
1166 { "cvtss2sd", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1167 { "cvtpd2ps", t_done, 0, true, { Vps, Wpd, Zz }, 0 }, // FIXME: book bug ???
1168 { "cvtsd2ss", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1171 { "cvtdq2ps", t_done, 0, true, { Vps, Wdq, Zz }, 0 },
1172 { "cvttps2dq", t_done, 0, true, { Vdq, Wps, Zz }, 0 }, // book has this and next swapped!!!
1173 { "cvtps2dq", t_done, 0, true, { Vdq, Wps, Zz }, 0 }, // FIXME: book bug ???
1174 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1177 { "subps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1178 { "subss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1179 { "subpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1180 { "subsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1183 { "minps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1184 { "minss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1185 { "minpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1186 { "minsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1189 { "divps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1190 { "divss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1191 { "divpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1192 { "divsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1195 { "maxps", t_done, 0, true, { Vps, Wps, Zz }, 0 },
1196 { "maxss", t_done, 0, true, { Vss, Wss, Zz }, 0 },
1197 { "maxpd", t_done, 0, true, { Vpd, Wpd, Zz }, 0 },
1198 { "maxsd", t_done, 0, true, { Vsd, Wsd, Zz }, 0 },
1201 { "punpcklbw", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1202 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1203 { "punpcklbw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1204 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1207 { "punpcklwd", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1208 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1209 { "punpcklwd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1210 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1213 { "punpcklqd", t_done, 0, true, { Pq, Qd, Zz }, 0 },
1214 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1215 { "punpcklqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1216 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1219 { "packsswb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1220 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1221 { "packsswb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1222 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1225 { "pcmpgtb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1226 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1227 { "pcmpgtb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1228 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1231 { "pcmpgtw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1232 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1233 { "pcmpgtw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1234 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1237 { "pcmpgdt", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1238 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1239 { "pcmpgdt", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1240 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1243 { "packuswb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1244 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1245 { "packuswb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1246 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1249 { "punpckhbw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1250 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1251 { "punpckhbw", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1252 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1255 { "punpckhwd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1256 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1257 { "punpckhwd", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1258 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1261 { "punpckhdq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1262 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1263 { "punpckhdq", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1264 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1267 { "packssdw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1268 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1269 { "packssdw", t_done, 0, true, { Pdq, Qdq, Zz }, 0 },
1270 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1273 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1274 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1275 { "punpcklqld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1276 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1279 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1280 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1281 { "punpckhqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1282 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1285 { "movd", t_done, 0, true, { Pd, Ed, Zz }, 0 },
1286 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1287 { "movd", t_done, 0, true, { Vdq, Ed, Zz }, 0 },
1288 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1291 { "movq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1292 { "movdqu", t_done, 0, false, { Vdq, Wdq, Zz }, 0 }, // book has this and next swapped!!!
1293 { "movdqa", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1294 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1297 { "pshufw", t_done, 0, true, { Pq, Qq, Ib }, 0 },
1298 { "pshufhw", t_done, 0, true, { Vdq, Wdq, Ib }, 0 }, // book has this and next swapped!!!
1299 { "pshufd", t_done, 0, true, { Vdq, Wdq, Ib }, 0 },
1300 { "pshuflw", t_done, 0, true, { Vdq, Wdq, Ib }, 0 },
1303 { "pcmpeqb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1304 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1305 { "pcmpeqb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1306 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1309 { "pcmpeqw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1310 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1311 { "pcmpeqw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1312 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1315 { "pcmpeqd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1316 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1317 { "pcmpeqd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1318 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1321 { "movd", t_done, 0, true, { Ed, Pd, Zz }, 0 },
1322 { "movq", t_done, 0, true, { Vq, Wq, Zz }, 0 }, // book has this and next swapped!!!
1323 { "movd", t_done, 0, true, { Ed, Vdq, Zz }, 0 },
1324 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1327 { "movq", t_done, 0, true, { Qq, Pq, Zz }, 0 },
1328 { "movdqu", t_done, 0, true, { Wdq, Vdq, Zz }, 0 }, // book has this and next swapped!!!
1329 { "movdqa", t_done, 0, true, { Wdq, Vdq, Zz }, 0 },
1330 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1333 { "cmpps", t_done, 0, true, { Vps, Wps, Ib }, 0 },
1334 { "cmpss", t_done, 0, true, { Vss, Wss, Ib }, 0 },
1335 { "cmppd", t_done, 0, true, { Vpd, Wpd, Ib }, 0 },
1336 { "cmpsd", t_done, 0, true, { Vsd, Wsd, Ib }, 0 },
1339 { "pinsrw", t_done, 0, true, { Pq, Ed, Ib }, 0 },
1340 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1341 { "pinsrw", t_done, 0, true, { Vdq, Ed, Ib }, 0 },
1342 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1345 { "pextrw", t_done, 0, true, { Gd, Pq, Ib }, 0 },
1346 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1347 { "pextrw", t_done, 0, true, { Gd, Vdq, Ib }, 0 },
1348 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1351 { "shufps", t_done, 0, true, { Vps, Wps, Ib }, 0 },
1352 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1353 { "shufpd", t_done, 0, true, { Vpd, Wpd, Ib }, 0 },
1354 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1357 { "psrlw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1358 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1359 { "psrlw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1360 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1363 { "psrld", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1364 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1365 { "psrld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1366 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1369 { "psrlq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1370 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1371 { "psrlq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1372 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1375 { "paddq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1376 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1377 { "psrlq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1378 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1381 { "pmullw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1382 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1383 { "pmullw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1384 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1387 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1388 { "movq2dq", t_done, 0, true, { Vdq, Qq, Zz }, 0 }, // lines jumbled in book
1389 { "movq", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1390 { "movdq2q", t_done, 0, true, { Pq, Wq, Zz }, 0 },
1393 { "pmovmskb", t_done, 0, true, { Gd, Pq, Zz }, 0 },
1394 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1395 { "pmovmskb", t_done, 0, true, { Gd, Vdq, Zz }, 0 },
1396 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1399 { "psubusb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1400 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1401 { "psubusb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1402 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1405 { "psubusw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1406 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1407 { "psubusw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1408 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1411 { "pminub", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1412 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1413 { "pminub", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1414 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1417 { "pand", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1418 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1419 { "pand", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1420 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1423 { "paddusb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1424 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1425 { "paddusb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1426 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1429 { "paddusw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1430 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1431 { "paddusw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1432 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1435 { "pmaxub", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1436 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1437 { "pmaxub", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1438 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1441 { "pandn", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1442 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1443 { "pandn", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1444 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1447 { "pavgb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1448 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1449 { "pavgb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1450 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1453 { "psraw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1454 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1455 { "psraw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1456 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1459 { "psrad", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1460 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1461 { "psrad", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1462 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1465 { "pavgw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1466 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1467 { "pavgw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1468 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1471 { "pmulhuw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1472 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1473 { "pmulhuw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1474 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1477 { "pmulhw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1478 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1479 { "pmulhw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1480 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1483 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1484 { "cvtdq2pd", t_done, 0, true, { Vpd, Wdq, Zz }, 0 }, // lines jumbled in book
1485 { "cvttpd2dq", t_done, 0, true, { Vdq, Wpd, Zz }, 0 },
1486 { "cvtpd2dq", t_done, 0, true, { Vdq, Wpd, Zz }, 0 },
1489 { "movntq", t_done, 0, true, { Wq, Vq, Zz }, 0 },
1490 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1491 { "movntdq", t_done, 0, true, { Wdq, Vdq, Zz }, 0 },
1492 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1495 { "psubsb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1496 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1497 { "psubsb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1498 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1501 { "psubsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1502 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1503 { "psubsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1504 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1507 { "pminsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1508 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1509 { "pminsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1510 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1513 { "por", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1514 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1515 { "por", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1516 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1519 { "paddsb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1520 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1521 { "paddsb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1522 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1525 { "paddsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1526 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1527 { "paddsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1528 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1531 { "pmaxsw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1532 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1533 { "pmaxsw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1534 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1537 { "pxor", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1538 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1539 { "pxor", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1540 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1543 { "psllw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1544 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1545 { "psllw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1546 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1549 { "pslld", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1550 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1551 { "pslld", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1552 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1555 { "psllq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1556 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1557 { "psllq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1558 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1561 { "pmuludq", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1562 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1563 { "pmuludq", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1564 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1567 { "pmaddwd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1568 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1569 { "pmaddwd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1570 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1573 { "psadbw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1574 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1575 { "psadbw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1576 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1579 { "maskmovq", t_done, 0, true, { Ppi, Qpi, Zz }, 0 },
1580 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1581 { "maskmovqu", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1582 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1585 { "psubb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1586 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1587 { "psubb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1588 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1591 { "psubw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1592 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1593 { "psubw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1594 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1597 { "psubd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1598 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1599 { "psubd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1600 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1602 { /* SSEFB */ // FIXME: Same????
1603 { "psubd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1604 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1605 { "psubd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1606 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1609 { "paddb", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1610 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1611 { "paddb", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1612 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1615 { "paddw", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1616 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1617 { "paddw", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1618 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1621 { "paddd", t_done, 0, true, { Pq, Qq, Zz }, 0 },
1622 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1623 { "paddd", t_done, 0, true, { Vdq, Wdq, Zz }, 0 },
1624 { 0, t_ill, 0, false, { Zz, Zz, Zz }, 0 },
1628 /* rows are none or 66 prefixed in this order (see book) */
1629 static ia32_entry ssegrpMap[][2] = {
1632 { "psrlw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1633 { "psrlw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1637 { "psraw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1638 { "psraw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1642 { "psllw", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1643 { "psllw", t_done, 0, true, { Pdq, Ib, Zz }, 0 }
1647 { "psrld", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1648 { "psrld", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1652 { "psrad", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1653 { "psrad", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1657 { "pslld", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1658 { "pslld", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1662 { "psrlq", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1663 { "psrlq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1667 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1668 { "psrldq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1672 { "psllq", t_done, 0, true, { Pq, Ib, Zz }, 0 },
1673 { "psllq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1677 { 0, t_ill, 0, true, { Zz, Zz, Zz }, 0 },
1678 { "pslldq", t_done, 0, true, { Wdq, Ib, Zz }, 0 }
1682 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr, const unsigned char* addr);
1685 template <unsigned int capa>
1686 ia32_instruction& ia32_decode(const unsigned char* addr, ia32_instruction& instruct)
1688 ia32_prefixes& pref = instruct.prf;
1689 unsigned int table, nxtab;
1690 unsigned int idx, sseidx = 0;
1691 ia32_entry *gotit = NULL;
1693 ia32_decode_prefixes(addr, pref);
1694 instruct.size = pref.getCount();
1695 addr += instruct.size;
1699 gotit = &oneByteMap[idx];
1700 nxtab = gotit->otable;
1704 while(nxtab != t_done) {
1709 gotit = &twoByteMap[idx];
1710 nxtab = gotit->otable;
1715 sseidx = gotit->tabidx;
1716 assert(addr[0] == 0x0F);
1718 gotit = &twoByteMap[idx];
1719 nxtab = gotit->otable;
1724 idx = gotit->tabidx;
1725 gotit = &sseMap[idx][sseidx];
1726 nxtab = gotit->otable;
1729 idx = gotit->tabidx;
1730 unsigned int reg = (addr[0] >> 3) & 7;
1737 // leave table unchanged because operands are in not defined in group map
1738 nxtab = groupMap[idx][reg].otable;
1739 assert(nxtab==t_done || nxtab==t_ill);
1742 gotit = &groupMap[idx][reg];
1743 nxtab = gotit->otable;
1746 unsigned int mod = addr[0] >> 6;
1747 gotit = &groupMap2[idx-Grp12][mod==3][reg];
1753 idx = gotit->tabidx;
1754 gotit = &ssegrpMap[idx][sseidx];
1757 instruct.legacy_type = 0;
1758 return ia32_decode_FP(pref, addr, instruct);
1760 instruct.legacy_type = ILLEGAL;
1763 assert(!"wrong table");
1767 // addr points after the opcode, and the size has been adjusted accordingly
1768 // also the SSE index is set; now 'table' points to the correct instruction map
1770 assert(gotit != NULL);
1771 instruct.legacy_type = gotit->legacyType;
1773 ia32_decode_operands(pref, *gotit, addr, instruct); // all but FP
1778 template ia32_instruction& ia32_decode<0>(const unsigned char* addr, ia32_instruction& instruct);
1780 ia32_instruction& ia32_decode_FP(const ia32_prefixes& pref, const unsigned char* addr,
1781 ia32_instruction& instruct)
1783 unsigned int nib = byteSzB; // modRM
1784 unsigned int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2); // 32-bit mode implicit
1786 if (addr[0] <= 0xBF) { // modrm
1787 nib += ia32_decode_modrm(addrSzAttr, addr);
1789 instruct.size += nib;
1794 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr, const unsigned char* addr)
1796 unsigned char modrm = addr[0];
1797 unsigned char mod = modrm >> 6;
1798 unsigned char rm = modrm & 7;
1799 //unsigned char reg = (modrm >> 3) & 7;
1801 if(addrSzAttr == 1) { // 16-bit, cannot have SIB
1804 return rm==6 ? wordSzB : 0;
1810 return 0; // register
1815 else { // 32-bit, may have SIB
1817 return 0; // only registers, no SIB
1818 bool hassib = rm == 4;
1819 unsigned int nsib = 0;
1821 unsigned char base = 0;
1829 /* this is tricky: there is a disp32 iff (1) rm == 5 or (2) rm == 4 && base == 5 */
1830 unsigned char check5 = hassib ? base : rm;
1831 return nsib + ((check5 == 5) ? dwordSzB : 0);
1834 return nsib + byteSzB;
1836 return nsib + dwordSzB;
1844 unsigned int ia32_decode_operands (const ia32_prefixes& pref, const ia32_entry& gotit,
1845 const unsigned char* addr, ia32_instruction& instruct)
1847 unsigned int nib = 0; /* # of bytes in instruction */
1848 unsigned int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2); // 32-bit mode implicit
1849 unsigned int operSzAttr = (pref.getPrefix(2) == PREFIX_SZOPER ? 1 : 2); // 32-bit mode implicit
1854 for(unsigned int i=0; i<3; ++i) {
1855 const ia32_operand& op = gotit.operands[i];
1858 case am_A: /* address = segment + offset (word or dword) */
1860 case am_O: /* operand offset */
1861 nib += wordSzB * addrSzAttr;
1863 case am_C: /* control register */
1864 case am_D: /* debug register */
1865 case am_F: /* flags register */
1866 case am_G: /* general purpose register, selecteb by reg field */
1867 case am_P: /* MMX register */
1868 case am_R: /* general purpose register, selected by mod field */
1869 case am_S: /* segment register */
1870 case am_T: /* test register */
1871 case am_V: /* XMM register */
1872 case am_reg: /* register implicitely encoded in opcode */
1874 case am_E: /* register or memory location, so decoding needed */
1875 case am_M: /* memory operand, decoding needed; size includes modRM byte */
1876 case am_Q: /* MMX register or memory location */
1877 case am_W: /* XMM register or memory location */
1878 nib += ia32_decode_modrm(addrSzAttr, addr);
1880 case am_I: /* immediate data */
1881 case am_J: /* instruction pointer offset */
1887 nib += wordSzB * operSzAttr;
1893 /* Don't forget these... */
1894 case am_X: /* memory at DS:(E)SI*/
1895 case am_Y: /* memory at ES:(E)DI*/
1904 instruct.size += nib;
1909 static const unsigned char sse_prefix[256] = {
1910 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
1911 /* 0x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1912 /* 1x */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
1913 /* 2x */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
1914 /* 3x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1915 /* 4x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1916 /* 5x */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1917 /* 6x */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1918 /* 7x */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, // Grp12-14 are SSE groups
1919 /* 8x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1920 /* 9x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1921 /* Ax */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1922 /* Bx */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1923 /* Cx */ 0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
1924 /* Dx */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1925 /* Ex */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1926 /* Fx */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1930 // FIXME: lookahead might blow up...
1931 ia32_prefixes& ia32_decode_prefixes(const unsigned char* addr, ia32_prefixes& pref)
1934 pref.prfx[0] = pref.prfx[1] = pref.prfx[2] = pref.prfx[3] = 0;
1935 bool in_prefix = true;
1941 if(addr[1]==0x0F && sse_prefix[addr[2]])
1945 pref.prfx[0] = addr[0];
1954 pref.prfx[1] = addr[0];
1957 if(addr[1]==0x0F && sse_prefix[addr[2]])
1960 pref.prfx[2] = addr[0];
1964 pref.prfx[3] = addr[0];
1972 //printf("Got %d prefixes\n", pref.count);
1976 unsigned int ia32_emulate_old_type(ia32_instruction& instruct)
1978 const ia32_prefixes& pref = instruct.prf;
1979 unsigned int& insnType = instruct.legacy_type;
1980 unsigned int operSzAttr = (pref.getPrefix(2) == PREFIX_SZOPER ? 1 : 2); // 32-bit mode implicit
1982 if (pref.getPrefix(0)) // no distinction between these
1983 insnType |= PREFIX_INST;
1984 if (pref.getPrefix(3) == PREFIX_SZADDR)
1985 insnType |= PREFIX_ADDR;
1986 if (pref.getPrefix(2) == PREFIX_SZOPER)
1987 insnType |= PREFIX_OPR;
1988 if (pref.getPrefix(1))
1989 insnType |= PREFIX_SEG; // no distinction between segments
1991 if (insnType & REL_X) {
1992 if (operSzAttr == 1)
1997 else if (insnType & PTR_WX) {
1998 if (operSzAttr == 1)