* Bugfix: InstrucIter no longer used for int_function iteration.
[dyninst.git] / dyninstAPI / src / arch-x86.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: arch-x86.C,v 1.75 2007/12/11 20:22:06 bill Exp $
43
44 // Official documentation used:    - IA-32 Intel Architecture Software Developer Manual (2001 ed.)
45 //                                 - AMD x86-64 Architecture Programmer's Manual (rev 3.00, 1/2002)
46 // Unofficial documentation used:  - www.sandpile.org/ia32
47 //                                 - NASM documentation
48
49 // Note: Unless specified "book" refers to Intel's manual
50
51 #include <assert.h>
52 #include <stdio.h>
53 #include "boost/assign/list_of.hpp"
54 #include "boost/assign/std/vector.hpp"
55 #include "boost/assign/std/set.hpp"
56 #include <map>
57 #include <string>
58 #include "common/h/Types.h"
59 #include "arch.h"
60 #include "util.h"
61 #include "debug.h"
62 #include "InstrucIter.h"
63 #include "dyninstAPI/src/emit-x86.h"
64 #include "process.h"
65 #include "inst-x86.h"
66
67 using namespace std;
68 using namespace boost::assign;
69
70
71 // groups
72 enum {
73   Grp1a=0, Grp1b, Grp1c, Grp1d, Grp2, Grp3a, Grp3b, Grp4, Grp5, Grp6, Grp7,
74   Grp8, Grp9, Grp11, Grp12, Grp13, Grp14, Grp15, Grp16, GrpAMD
75 };
76
77 // SSE
78 enum {
79   SSE10=0, SSE11, SSE12, SSE13, SSE14, SSE15, SSE16, SSE17,
80   SSE28, SSE29, SSE2A, SSE2B, SSE2C, SSE2D, SSE2E, SSE2F,
81   SSE50, SSE51, SSE52, SSE53, SSE54, SSE55, SSE56, SSE57,
82   SSE58, SSE59, SSE5A, SSE5B, SSE5C, SSE5D, SSE5E, SSE5F,
83   SSE60, SSE61, SSE62, SSE63, SSE64, SSE65, SSE66, SSE67,
84   SSE68, SSE69, SSE6A, SSE6B, SSE6C, SSE6D, SSE6E, SSE6F,
85   SSE70, SSE74, SSE75, SSE76,
86   SSE7E, SSE7F,
87   SSEC2, SSEC4, SSEC5, SSEC6,
88   SSED1, SSED2, SSED3, SSED4, SSED5, SSED6, SSED7,
89   SSED8, SSED9, SSEDA, SSEDB, SSEDC, SSEDD, SSEDE, SSEDF,
90   SSEE0, SSEE1, SSEE2, SSEE3, SSEE4, SSEE5, SSEE6, SSEE7,
91   SSEE8, SSEE9, SSEEA, SSEEB, SSEEC, SSEED, SSEEE, SSEEF,
92   SSEF1, SSEF2, SSEF3, SSEF4, SSEF5, SSEF6, SSEF7,
93   SSEF8, SSEF9, SSEFA, SSEFB, SSEFC, SSEFD, SSEFE
94 };
95
96
97 // SSE groups
98 enum {
99   G12SSE010B=0, G12SSE100B, G12SSE110B,
100   G13SSE010B, G13SSE100B, G13SSE110B,
101   G14SSE010B, G14SSE011B, G14SSE110B, G14SSE111B,
102 };
103
104
105 #define Zz   { 0, 0 }
106 #define Ap   { am_A, op_p }
107 #define Cd   { am_C, op_d }
108 #define Dd   { am_D, op_d }
109 #define Eb   { am_E, op_b }
110 #define Ed   { am_E, op_d }
111 #define Ep   { am_E, op_p }
112 #define Ev   { am_E, op_v }
113 #define Ew   { am_E, op_w }
114 #define Fv   { am_F, op_v }
115 #define Gb   { am_G, op_b }
116 #define Gd   { am_G, op_d }
117 #define Gv   { am_G, op_v }
118 #define Gw   { am_G, op_w }
119 #define Ib   { am_I, op_b }
120 #define Iv   { am_I, op_v }
121 #define Iw   { am_I, op_w }
122 #define Iz   { am_I, op_z }
123 #define Jb   { am_J, op_b }
124 #define Jv   { am_J, op_v }
125 #define Jz   { am_J, op_z }
126 #define Ma   { am_M, op_a }
127 #define Mb   { am_M, op_b }
128 #define Mlea { am_M, op_lea }
129 #define Mp   { am_M, op_p }
130 #define Ms   { am_M, op_s }
131 #define Md   { am_M, op_d }
132 #define Mq   { am_M, op_q }
133 #define M512 { am_M, op_512 }
134 #define Ob   { am_O, op_b }
135 #define Ov   { am_O, op_v }
136 #define Pd   { am_P, op_d }
137 #define Pdq  { am_P, op_dq }
138 #define Ppi  { am_P, op_pi }
139 #define Pq   { am_P, op_q }
140 #define Qdq  { am_Q, op_dq }
141 #define Qd   { am_Q, op_d }
142 #define Qpi  { am_Q, op_pi }
143 #define Qq   { am_Q, op_q }
144 #define Rd   { am_R, op_d }
145 #define Td   { am_T, op_d }
146 #define Sw   { am_S, op_w }
147 #define Vdq  { am_V, op_dq }
148 #define Vpd  { am_V, op_pd }
149 #define Vps  { am_V, op_ps }
150 #define Vq   { am_V, op_q }
151 #define Vss  { am_V, op_ss }
152 #define Vsd  { am_V, op_sd }
153 #define Wdq  { am_W, op_dq }
154 #define Wpd  { am_W, op_pd }
155 #define Wps  { am_W, op_ps }
156 #define Wq   { am_W, op_q }
157 #define Ws   { am_W, op_s }
158 #define Wsd  { am_W, op_sd }
159 #define Wss  { am_W, op_ss }
160 #define Xb   { am_X, op_b }
161 #define Xv   { am_X, op_v }
162 #define Yb   { am_Y, op_b }
163 #define Yv   { am_Y, op_v }
164 #define STHb { am_stackH, op_b }
165 #define STPb { am_stackP, op_b }
166 #define STHv { am_stackH, op_v }
167 #define STPv { am_stackP, op_v }
168 #define STHw { am_stackH, op_w }
169 #define STPw { am_stackP, op_w }
170 #define STHd { am_stackH, op_d }
171 #define STPd { am_stackP, op_d }
172 #define STHa { am_stackH, op_allgprs }
173 #define STPa { am_stackP, op_allgprs }
174
175 #define STKb { am_stack, op_b }
176 #define STKv { am_stack, op_v }
177 #define STKw { am_stack, op_w }
178 #define STKd { am_stack, op_d }
179 #define STKa { am_stack, op_allgprs }
180
181
182 #define GPRS { am_allgprs, op_allgprs }
183
184 #define AH  { am_reg, r_AH }
185 #define AX  { am_reg, r_AX }
186 #define BH  { am_reg, r_BH }
187 #define CH  { am_reg, r_CH }
188 #define DH  { am_reg, r_DH }
189 #define AL  { am_reg, r_AL }
190 #define BL  { am_reg, r_BL }
191 #define CL  { am_reg, r_CL }
192 #define CS  { am_reg, r_CS }
193 #define DL  { am_reg, r_DL }
194 #define DX  { am_reg, r_DX }
195 #define eAX { am_reg, r_eAX }
196 #define eBX { am_reg, r_eBX }
197 #define eCX { am_reg, r_eCX }
198 #define eDX { am_reg, r_eDX }
199 #define EAX { am_reg, r_EAX }
200 #define EBX { am_reg, r_EBX }
201 #define ECX { am_reg, r_ECX }
202 #define EDX { am_reg, r_EDX }
203 #define DS  { am_reg, r_DS }
204 #define ES  { am_reg, r_ES }
205 #define FS  { am_reg, r_FS }
206 #define GS  { am_reg, r_GS }
207 #define SS  { am_reg, r_SS }
208 #define eSP { am_reg, r_eSP }
209 #define eBP { am_reg, r_eBP }
210 #define eSI { am_reg, r_eSI }
211 #define eDI { am_reg, r_eDI }
212 #define ESP { am_reg, r_ESP }
213 #define EBP { am_reg, r_EBP }
214 #define ESI { am_reg, r_ESI }
215 #define EDI { am_reg, r_EDI }
216 #define ECXEBX { am_reg, r_ECXEBX }
217 #define EDXEAX { am_reg, r_EDXEAX }
218
219
220 #define FPOS 16
221
222 enum {
223   fNT=1,   // non-temporal
224   fPREFETCHNT,
225   fPREFETCHT0,
226   fPREFETCHT1,
227   fPREFETCHT2,
228   fPREFETCHAMDE,
229   fPREFETCHAMDW,
230   fCALL,
231   fNEARRET,
232   fFARRET,
233   fIRET,
234   fENTER,
235   fLEAVE,
236   fXLAT,
237   fIO,
238   fSEGDESC,
239   fCOND,
240   fCMPXCH,
241   fCMPXCH8,
242   fINDIRCALL,
243   fINDIRJUMP,
244   fFXSAVE,
245   fFXRSTOR,
246   fCLFLUSH,
247   fREP,   // only rep prefix allowed: ins, movs, outs, lods, stos
248   fSCAS,
249   fCMPS
250 };
251
252 map<entryID, string> entryNames = map_list_of
253   (e_aaa, "aaa")
254   (e_aad, "aad")
255   (e_aam, "aam")
256   (e_aas, "aas")
257   (e_adc, "adc")
258   (e_add, "add")
259   (e_addpd, "addpd")
260   (e_addps, "addps")
261   (e_addsd, "addsd")
262   (e_addss, "addss")
263   (e_and, "and")
264   (e_andnpd, "andnpd")
265   (e_andnps, "andnps")
266   (e_andpd, "andpd")
267   (e_andps, "andps")
268   (e_arpl, "arpl")
269   (e_bound, "bound")
270   (e_bsf, "bsf")
271   (e_bsr, "bsr")
272   (e_bswap, "bswap")
273   (e_bt, "bt")
274   (e_btc, "btc")
275   (e_btr, "btr")
276   (e_bts, "bts")
277   (e_call, "call")
278   (e_cbw_cwde, "cbw/cwde")
279   (e_clc, "clc")
280   (e_cld, "cld")
281   (e_clflush, "clflush")
282   (e_cli, "cli")
283   (e_clts, "clts")
284   (e_cmc, "cmc")
285   (e_cmovbe, "cmovbe")
286   (e_cmove, "cmove")
287   (e_cmovnae, "cmovnae")
288   (e_cmovnb, "cmovnb")
289   (e_cmovnbe, "cmovnbe")
290   (e_cmovne, "cmovne")
291   (e_cmovng, "cmovng")
292   (e_cmovnge, "cmovnge")
293   (e_cmovnl, "cmovnl")
294   (e_cmovno, "cmovno")
295   (e_cmovns, "cmovns")
296   (e_cmovo, "cmovo")
297   (e_cmovpe, "cmovpe")
298   (e_cmovpo, "cmovpo")
299   (e_cmovs, "cmovs")
300   (e_cmp, "cmp")
301   (e_cmppd, "cmppd")
302   (e_cmpps, "cmpps")
303   (e_cmpsb, "cmpsb")
304   (e_cmpsd, "cmpsd")
305   (e_cmpss, "cmpss")
306   (e_cmpsw, "cmpsw")
307   (e_cmpxch, "cmpxch")
308   (e_cmpxch8b, "cmpxch8b")
309   (e_comisd, "comisd")
310   (e_comiss, "comiss")
311   (e_cpuid, "cpuid")
312   (e_cvtdq2pd, "cvtdq2pd")
313   (e_cvtdq2ps, "cvtdq2ps")
314   (e_cvtpd2dq, "cvtpd2dq")
315   (e_cvtpd2pi, "cvtpd2pi")
316   (e_cvtpd2ps, "cvtpd2ps")
317   (e_cvtpi2pd, "cvtpi2pd")
318   (e_cvtpi2ps, "cvtpi2ps")
319   (e_cvtps2dq, "cvtps2dq")
320   (e_cvtps2pd, "cvtps2pd")
321   (e_cvtps2pi, "cvtps2pi")
322   (e_cvtsd2si, "cvtsd2si")
323   (e_cvtsd2ss, "cvtsd2ss")
324   (e_cvtsi2sd, "cvtsi2sd")
325   (e_cvtsi2ss, "cvtsi2ss")
326   (e_cvtss2sd, "cvtss2sd")
327   (e_cvtss2si, "cvtss2si")
328   (e_cvttpd2dq, "cvttpd2dq")
329   (e_cvttpd2pi, "cvttpd2pi")
330   (e_cvttps2dq, "cvttps2dq")
331   (e_cvttps2pi, "cvttps2pi")
332   (e_cvttsd2si, "cvttsd2si")
333   (e_cvttss2si, "cvttss2si")
334   (e_cwd_cdq, "cwd/cdq")
335   (e_daa, "daa")
336   (e_das, "das")
337   (e_dec, "dec")
338   (e_div, "div")
339   (e_divpd, "divpd")
340   (e_divps, "divps")
341   (e_divsd, "divsd")
342   (e_divss, "divss")
343   (e_emms, "emms")
344   (e_enter, "enter")
345   (e_femms, "femms")
346   (e_fxrstor, "fxrstor")
347   (e_fxsave, "fxsave")
348   (e_hlt, "hlt")
349   (e_idiv, "idiv")
350   (e_imul, "imul")
351   (e_in, "in")
352   (e_inc, "inc")
353   (e_insb, "insb")
354   (e_insw_d, "insw/d")
355   (e_int, "int")
356   (e_int3, "int 3")
357   (e_int1, "int1")
358   (e_into, "into")
359   (e_invd, "invd")
360   (e_invlpg, "invlpg")
361   (e_iret, "iret")
362   (e_jb, "jb")
363   (e_jb_jnaej_j, "jb/jnaej/j")
364   (e_jbe, "jbe")
365   (e_jcxz_jec, "jcxz/jec")
366   (e_jl, "jl")
367   (e_jle, "jle")
368   (e_jmp, "jmp")
369   (e_jnb, "jnb")
370   (e_jnb_jae_j, "jnb/jae/j")
371   (e_jnbe, "jnbe")
372   (e_jnl, "jnl")
373   (e_jnle, "jnle")
374   (e_jno, "jno")
375   (e_jnp, "jnp")
376   (e_jns, "jns")
377   (e_jnz, "jnz")
378   (e_jo, "jo")
379   (e_jp, "jp")
380   (e_js, "js")
381   (e_jz, "jz")
382   (e_lahf, "lahf")
383   (e_lar, "lar")
384   (e_ldmxcsr, "ldmxcsr")
385   (e_lds, "lds")
386   (e_lea, "lea")
387   (e_leave, "leave")
388   (e_les, "les")
389   (e_lfence, "lfence")
390   (e_lfs, "lfs")
391   (e_lgdt, "lgdt")
392   (e_lgs, "lgs")
393   (e_lidt, "lidt")
394   (e_lldt, "lldt")
395   (e_lmsw, "lmsw")
396   (e_lodsb, "lodsb")
397   (e_lodsw, "lodsw")
398   (e_loop, "loop")
399   (e_loope, "loope")
400   (e_loopn, "loopn")
401   (e_lsl, "lsl")
402   (e_lss, "lss")
403   (e_ltr, "ltr")
404   (e_maskmovdqu, "maskmovdqu")
405   (e_maskmovq, "maskmovq")
406   (e_maxpd, "maxpd")
407   (e_maxps, "maxps")
408   (e_maxsd, "maxsd")
409   (e_maxss, "maxss")
410   (e_mfence, "mfence")
411   (e_minpd, "minpd")
412   (e_minps, "minps")
413   (e_minsd, "minsd")
414   (e_minss, "minss")
415   (e_mmxud, "mmxud")
416   (e_mov, "mov")
417   (e_movapd, "movapd")
418   (e_movaps, "movaps")
419   (e_movd, "movd")
420   (e_movdq2q, "movdq2q")
421   (e_movdqa, "movdqa")
422   (e_movdqu, "movdqu")
423   (e_movhpd, "movhpd")
424   (e_movhps, "movhps")
425   (e_movhps_movlhps, "movhps/movlhps")
426   (e_movlpd, "movlpd")
427   (e_movlps, "movlps")
428   (e_movlps_movhlps, "movlps/movhlps")
429   (e_movmskpd, "movmskpd")
430   (e_movmskps, "movmskps")
431   (e_movntdq, "movntdq")
432   (e_movnti, "movnti")
433   (e_movntpd, "movntpd")
434   (e_movntps, "movntps")
435   (e_movntq, "movntq")
436   (e_movq, "movq")
437   (e_movq2dq, "movq2dq")
438   (e_movsb, "movsb")
439   (e_movsd, "movsd")
440   (e_movss, "movss")
441   (e_movsw_d, "movsw/d")
442   (e_movsx, "movsx")
443   (e_movupd, "movupd")
444   (e_movups, "movups")
445   (e_movzx, "movzx")
446   (e_mul, "mul")
447   (e_mulpd, "mulpd")
448   (e_mulps, "mulps")
449   (e_mulsd, "mulsd")
450   (e_mulss, "mulss")
451   (e_neg, "neg")
452   (e_nop, "nop")
453   (e_not, "not")
454   (e_or, "or")
455   (e_orpd, "orpd")
456   (e_orps, "orps")
457   (e_out, "out")
458   (e_outsb, "outsb")
459   (e_outsw_d, "outsw/d")
460   (e_packssdw, "packssdw")
461   (e_packsswb, "packsswb")
462   (e_packuswb, "packuswb")
463   (e_paddb, "paddb")
464   (e_paddd, "paddd")
465   (e_paddq, "paddq")
466   (e_paddsb, "paddsb")
467   (e_paddsw, "paddsw")
468   (e_paddusb, "paddusb")
469   (e_paddusw, "paddusw")
470   (e_paddw, "paddw")
471   (e_pand, "pand")
472   (e_pandn, "pandn")
473   (e_pavgb, "pavgb")
474   (e_pavgw, "pavgw")
475   (e_pcmpeqb, "pcmpeqb")
476   (e_pcmpeqd, "pcmpeqd")
477   (e_pcmpeqw, "pcmpeqw")
478   (e_pcmpgdt, "pcmpgdt")
479   (e_pcmpgtb, "pcmpgtb")
480   (e_pcmpgtw, "pcmpgtw")
481   (e_pextrw, "pextrw")
482   (e_pinsrw, "pinsrw")
483   (e_pmaddwd, "pmaddwd")
484   (e_pmaxsw, "pmaxsw")
485   (e_pmaxub, "pmaxub")
486   (e_pminsw, "pminsw")
487   (e_pminub, "pminub")
488   (e_pmovmskb, "pmovmskb")
489   (e_pmulhuw, "pmulhuw")
490   (e_pmulhw, "pmulhw")
491   (e_pmullw, "pmullw")
492   (e_pmuludq, "pmuludq")
493   (e_pop, "pop")
494   (e_popa_d, "popa(d)")
495   (e_popf_d, "popf(d)")
496   (e_por, "por")
497   (e_prefetch, "prefetch")
498   (e_prefetchNTA, "prefetchNTA")
499   (e_prefetchT0, "prefetchT0")
500   (e_prefetchT1, "prefetchT1")
501   (e_prefetchT2, "prefetchT2")
502   (e_prefetch_w, "prefetch(w)")
503   (e_prefetchw, "prefetchw")
504   (e_psadbw, "psadbw")
505   (e_pshufd, "pshufd")
506   (e_pshufhw, "pshufhw")
507   (e_pshuflw, "pshuflw")
508   (e_pshufw, "pshufw")
509   (e_pslld, "pslld")
510   (e_pslldq, "pslldq")
511   (e_psllq, "psllq")
512   (e_psllw, "psllw")
513   (e_psrad, "psrad")
514   (e_psraw, "psraw")
515   (e_psrld, "psrld")
516   (e_psrldq, "psrldq")
517   (e_psrlq, "psrlq")
518   (e_psrlw, "psrlw")
519   (e_psubb, "psubb")
520   (e_psubd, "psubd")
521   (e_psubsb, "psubsb")
522   (e_psubsw, "psubsw")
523   (e_psubusb, "psubusb")
524   (e_psubusw, "psubusw")
525   (e_psubw, "psubw")
526   (e_punpckhbw, "punpckhbw")
527   (e_punpckhdq, "punpckhdq")
528   (e_punpckhqd, "punpckhqd")
529   (e_punpckhwd, "punpckhwd")
530   (e_punpcklbw, "punpcklbw")
531   (e_punpcklqd, "punpcklqd")
532   (e_punpcklqld, "punpcklqld")
533   (e_punpcklwd, "punpcklwd")
534   (e_push, "push")
535   (e_pusha_d, "pusha(d)")
536   (e_pushf_d, "pushf(d)")
537   (e_pxor, "pxor")
538   (e_rcl, "rcl")
539   (e_rcpps, "rcpps")
540   (e_rcpss, "rcpss")
541   (e_rcr, "rcr")
542   (e_rdmsr, "rdmsr")
543   (e_rdpmc, "rdpmc")
544   (e_rdtsc, "rdtsc")
545   (e_ret_far, "ret far")
546   (e_ret_near, "ret near")
547   (e_rol, "rol")
548   (e_ror, "ror")
549   (e_rsm, "rsm")
550   (e_rsqrtps, "rsqrtps")
551   (e_rsqrtss, "rsqrtss")
552   (e_sahf, "sahf")
553   (e_salc, "salc")
554   (e_sar, "sar")
555   (e_sbb, "sbb")
556   (e_scasb, "scasb")
557   (e_scasw_d, "scasw/d")
558   (e_setb, "setb")
559   (e_setbe, "setbe")
560   (e_setl, "setl")
561   (e_setle, "setle")
562   (e_setnb, "setnb")
563   (e_setnbe, "setnbe")
564   (e_setnl, "setnl")
565   (e_setnle, "setnle")
566   (e_setno, "setno")
567   (e_setnp, "setnp")
568   (e_setns, "setns")
569   (e_setnz, "setnz")
570   (e_seto, "seto")
571   (e_setp, "setp")
572   (e_sets, "sets")
573   (e_setz, "setz")
574   (e_sfence, "sfence")
575   (e_sgdt, "sgdt")
576   (e_shl_sal, "shl/sal")
577   (e_shld, "shld")
578   (e_shr, "shr")
579   (e_shrd, "shrd")
580   (e_shufpd, "shufpd")
581   (e_shufps, "shufps")
582   (e_sidt, "sidt")
583   (e_sldt, "sldt")
584   (e_smsw, "smsw")
585   (e_sqrtpd, "sqrtpd")
586   (e_sqrtps, "sqrtps")
587   (e_sqrtsd, "sqrtsd")
588   (e_sqrtss, "sqrtss")
589   (e_stc, "stc")
590   (e_std, "std")
591   (e_sti, "sti")
592   (e_stmxcsr, "stmxcsr")
593   (e_stosb, "stosb")
594   (e_stosw_d, "stosw/d")
595   (e_str, "str")
596   (e_sub, "sub")
597   (e_subpd, "subpd")
598   (e_subps, "subps")
599   (e_subsd, "subsd")
600   (e_subss, "subss")
601   (e_syscall, "syscall")
602   (e_sysenter, "sysenter")
603   (e_sysexit, "sysexit")
604   (e_sysret, "sysret")
605   (e_test, "test")
606   (e_ucomisd, "ucomisd")
607   (e_ucomiss, "ucomiss")
608   (e_ud2, "ud2")
609   (e_ud2grp10, "ud2grp10")
610   (e_unpckhpd, "unpckhpd")
611   (e_unpckhps, "unpckhps")
612   (e_unpcklpd, "unpcklpd")
613   (e_unpcklps, "unpcklps")
614   (e_verr, "verr")
615   (e_verw, "verw")
616   (e_wait, "wait")
617   (e_wbinvd, "wbinvd")
618   (e_wrmsr, "wrmsr")
619   (e_xadd, "xadd")
620   (e_xchg, "xchg")
621   (e_xlat, "xlat")
622   (e_xor, "xor")
623   (e_xorpd, "xorpd")
624   (e_xorps, "xorps")
625 ;
626
627
628 const char* ia32_entry::name()
629 {
630   map<entryID, string>::const_iterator found = entryNames.find(id);
631   if(found != entryNames.end())
632   {
633     return found->second.c_str();
634   }
635   return NULL;
636 }
637
638 const map<entryID, flagInfo>& ia32_instruction::getFlagTable()
639 {
640   static map<entryID, flagInfo> flagTable;
641   if(flagTable.empty()) 
642   {
643     ia32_instruction::initFlagTable(flagTable);
644   }
645   return flagTable;
646 }
647
648 const vector<RegisterID> standardFlags = list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF)(r_CF);
649
650   
651 void ia32_instruction::initFlagTable(map<entryID, flagInfo>& flagTable)
652 {
653   flagTable[e_aaa] = flagInfo(list_of(r_AF), standardFlags);
654   flagTable[e_aad] = flagInfo(vector<RegisterID>(), standardFlags);
655   flagTable[e_aam] = flagInfo(vector<RegisterID>(), standardFlags);
656   flagTable[e_aas] = flagInfo(list_of(r_AF), standardFlags);
657   flagTable[e_adc] = flagInfo(list_of(r_CF), standardFlags);
658   flagTable[e_add] = flagInfo(vector<RegisterID>(), standardFlags);
659   flagTable[e_and] = flagInfo(vector<RegisterID>(), standardFlags);
660   flagTable[e_arpl] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
661   flagTable[e_bsf] = flagInfo(vector<RegisterID>(), standardFlags);
662   flagTable[e_bt] = flagInfo(vector<RegisterID>(), standardFlags);
663   flagTable[e_bts] = flagInfo(vector<RegisterID>(), standardFlags);
664   flagTable[e_btr] = flagInfo(vector<RegisterID>(), standardFlags);
665   flagTable[e_btc] = flagInfo(vector<RegisterID>(), standardFlags);
666   flagTable[e_clc] = flagInfo(vector<RegisterID>(), list_of(r_CF));
667   flagTable[e_cld] = flagInfo(vector<RegisterID>(), list_of(r_DF));
668   flagTable[e_cli] = flagInfo(vector<RegisterID>(), list_of(r_IF));
669   flagTable[e_cmc] = flagInfo(vector<RegisterID>(), list_of(r_CF));
670   flagTable[e_cmovbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
671   flagTable[e_cmove] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
672   flagTable[e_cmovnae] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
673   flagTable[e_cmovnb] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
674   flagTable[e_cmovnbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
675   flagTable[e_cmovne] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
676   flagTable[e_cmovng] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
677   flagTable[e_cmovnge] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
678   flagTable[e_cmovnl] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
679   flagTable[e_cmovno] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
680   flagTable[e_cmovns] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
681   flagTable[e_cmovo] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
682   flagTable[e_cmovpe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
683   flagTable[e_cmovpo] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
684   flagTable[e_cmovs] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
685   flagTable[e_cmp] = flagInfo(vector<RegisterID>(), standardFlags);
686   flagTable[e_cmpsb] = flagInfo(vector<RegisterID>(), standardFlags);
687   flagTable[e_cmpsd] = flagInfo(vector<RegisterID>(), standardFlags);
688   flagTable[e_cmpss] = flagInfo(vector<RegisterID>(), standardFlags);
689   flagTable[e_cmpsw] = flagInfo(vector<RegisterID>(), standardFlags);
690   flagTable[e_cmpxch] = flagInfo(vector<RegisterID>(), standardFlags);
691   flagTable[e_cmpxch8b] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
692   flagTable[e_comisd] = flagInfo(vector<RegisterID>(), standardFlags);
693   flagTable[e_comiss] = flagInfo(vector<RegisterID>(), standardFlags);
694   flagTable[e_daa] = flagInfo(list_of(r_AF)(r_CF), standardFlags);
695   flagTable[e_das] = flagInfo(list_of(r_AF)(r_CF), standardFlags);
696   flagTable[e_dec] = flagInfo(vector<RegisterID>(), list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF));
697   flagTable[e_div] = flagInfo(list_of(r_AF)(r_CF), standardFlags);
698   // TODO: FCMOVcc (not in our entry table) (reads zf/pf/cf)
699   // TODO: FCOMI/FCOMIP/FUCOMI/FUCOMIP (writes/zf/pf/cf)
700   flagTable[e_idiv] = flagInfo(vector<RegisterID>(), standardFlags);
701   flagTable[e_imul] = flagInfo(vector<RegisterID>(), standardFlags);
702   flagTable[e_inc] = flagInfo(vector<RegisterID>(), list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF));
703   flagTable[e_insb] = flagInfo(list_of(r_DF), vector<RegisterID>());
704   flagTable[e_insw_d] = flagInfo(list_of(r_DF), vector<RegisterID>());
705   flagTable[e_int] = flagInfo(vector<RegisterID>(), list_of(r_TF)(r_NT));
706   flagTable[e_int3] = flagInfo(vector<RegisterID>(), list_of(r_TF)(r_NT));
707   flagTable[e_into] = flagInfo(list_of(r_OF), list_of(r_TF)(r_NT));
708   flagTable[e_ucomisd] = flagInfo(vector<RegisterID>(), standardFlags);
709   flagTable[e_ucomiss] = flagInfo(vector<RegisterID>(), standardFlags);
710   flagTable[e_iret] = flagInfo(list_of(r_NT), list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF)(r_CF)(r_TF)(r_IF)(r_DF));
711   flagTable[e_jb] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
712   flagTable[e_jb_jnaej_j] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
713   flagTable[e_jbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
714   flagTable[e_jcxz_jec] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
715   flagTable[e_jl] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
716   flagTable[e_jle] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
717   flagTable[e_jnb] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
718   flagTable[e_jnb_jae_j] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
719   flagTable[e_jnbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
720   flagTable[e_jnl] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
721   flagTable[e_jnle] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
722   flagTable[e_jno] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
723   flagTable[e_jnp] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
724   flagTable[e_jns] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
725   flagTable[e_jnz] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
726   flagTable[e_jo] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
727   flagTable[e_jp] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
728   flagTable[e_js] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
729   flagTable[e_jz] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
730   flagTable[e_lar] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
731   flagTable[e_loop] = flagInfo(list_of(r_DF), vector<RegisterID>());
732   flagTable[e_loope] = flagInfo(list_of(r_ZF), vector<RegisterID>());
733   flagTable[e_loopn] = flagInfo(list_of(r_ZF), vector<RegisterID>());
734   flagTable[e_lsl] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
735   // I'd expect that mov control/debug/test gets handled when we do operand analysis
736   // If it doesn't, fix later
737   flagTable[e_mul] = flagInfo(vector<RegisterID>(), standardFlags);
738   flagTable[e_neg] = flagInfo(vector<RegisterID>(), standardFlags);
739   flagTable[e_or] = flagInfo(vector<RegisterID>(), standardFlags);
740   flagTable[e_outsb] = flagInfo(list_of(r_DF), vector<RegisterID>());
741   flagTable[e_outsw_d] = flagInfo(list_of(r_DF), vector<RegisterID>());
742   flagTable[e_popf_d] = flagInfo(vector<RegisterID>(), list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF)(r_CF)(r_TF)(r_IF)(r_DF)(r_NT));
743   flagTable[e_rcl] = flagInfo(list_of(r_CF), list_of(r_OF)(r_CF));
744   flagTable[e_rcr] = flagInfo(list_of(r_CF), list_of(r_OF)(r_CF));
745   flagTable[e_rol] = flagInfo(list_of(r_CF), list_of(r_OF)(r_CF));
746   flagTable[e_ror] = flagInfo(list_of(r_CF), list_of(r_OF)(r_CF));
747   flagTable[e_rsm] = flagInfo(vector<RegisterID>(), list_of(r_OF)(r_SF)(r_ZF)(r_AF)(r_PF)(r_CF)(r_TF)(r_IF)(r_DF)(r_NT)(r_RF));
748   flagTable[e_sahf] = flagInfo(list_of(r_SF)(r_ZF)(r_AF)(r_PF)(r_CF), vector<RegisterID>());
749   flagTable[e_sar] = flagInfo(vector<RegisterID>(), standardFlags);
750   flagTable[e_shr] = flagInfo(vector<RegisterID>(), standardFlags);
751   flagTable[e_setb] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
752   flagTable[e_setbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
753   flagTable[e_setl] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
754   flagTable[e_setle] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
755   flagTable[e_setnb] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
756   flagTable[e_setnbe] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
757   flagTable[e_setnl] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
758   flagTable[e_setnle] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
759   flagTable[e_setno] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
760   flagTable[e_setnp] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
761   flagTable[e_setns] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
762   flagTable[e_setnz] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
763   flagTable[e_seto] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
764   flagTable[e_setp] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
765   flagTable[e_sets] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
766   flagTable[e_setz] = flagInfo(list_of(r_OF)(r_SF)(r_ZF)(r_PF)(r_CF), vector<RegisterID>());
767   flagTable[e_shld] = flagInfo(vector<RegisterID>(), standardFlags);
768   flagTable[e_shrd] = flagInfo(vector<RegisterID>(), standardFlags);
769   flagTable[e_shl_sal] = flagInfo(vector<RegisterID>(), standardFlags);
770   flagTable[e_stc] = flagInfo(vector<RegisterID>(), list_of(r_CF));
771   flagTable[e_std] = flagInfo(vector<RegisterID>(), list_of(r_DF));
772   flagTable[e_sti] = flagInfo(vector<RegisterID>(), list_of(r_IF));
773   flagTable[e_stosb] = flagInfo(list_of(r_DF), vector<RegisterID>());
774   flagTable[e_stosw_d] = flagInfo(list_of(r_DF), vector<RegisterID>());
775   flagTable[e_sub] = flagInfo(vector<RegisterID>(), standardFlags);
776   flagTable[e_verr] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
777   flagTable[e_verw] = flagInfo(vector<RegisterID>(), list_of(r_ZF));
778   flagTable[e_xadd] = flagInfo(vector<RegisterID>(), standardFlags);
779   flagTable[e_xor] = flagInfo(vector<RegisterID>(), standardFlags);
780 }
781
782 bool ia32_entry::flagsUsed(std::set<RegisterID>& flagsRead, std::set<RegisterID>& flagsWritten)
783 {
784   map<entryID, flagInfo>::const_iterator found = ia32_instruction::getFlagTable().find(id);
785   if(found == ia32_instruction::getFlagTable().end())
786   {
787     return false;
788   }
789   // No entries for something that touches no flags, so always return true if we had an entry
790   const flagInfo& foundInfo(found->second);
791
792   copy(foundInfo.readFlags.begin(), foundInfo.readFlags.end(), inserter(flagsRead, flagsRead.begin()));
793   copy(foundInfo.writtenFlags.begin(), foundInfo.writtenFlags.end(), inserter(flagsWritten,flagsWritten.begin()));
794   return true;
795 }
796
797
798
799 // Modded table entry for push/pop, daa, das, aaa, aas, insb/w/d, outsb/w/d, xchg, cbw
800 // les, lds, aam, aad, loop(z/nz), cmpxch, lss, mul, imul, div, idiv, cmpxch8, [ld/st]mxcsr
801 // clflush, prefetch*
802
803
804 // oneByteMap: one byte opcode map
805 static ia32_entry oneByteMap[256] = {
806   /* 00 */
807   { e_add,  t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
808   { e_add,  t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
809   { e_add,  t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
810   { e_add,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
811   { e_add,  t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
812   { e_add,  t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
813   { e_push, t_done, 0, false, { STHw, ES, eSP }, 0, s1W2R3RW },
814   { e_pop,  t_done, 0, false, { ES, STPw, eSP }, 0, s1W2R3RW },
815   /* 08 */
816   { e_or,   t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
817   { e_or,   t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
818   { e_or,   t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
819   { e_or,   t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
820   { e_or,   t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
821   { e_or,   t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
822   { e_push, t_done, 0, false, { STHw, CS, eSP }, 0, s1W2R3RW },
823   { e_No_Entry,      t_twoB, 0, false, { Zz, Zz, Zz }, 0, 0 },
824   /* 10 */
825   { e_adc,  t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
826   { e_adc,  t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
827   { e_adc,  t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
828   { e_adc,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
829   { e_adc,  t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
830   { e_adc,  t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
831   { e_push, t_done, 0, false, { STHw, SS, eSP }, 0, s1W2R3RW },
832   { e_pop,  t_done, 0, false, { SS, STPw, eSP }, 0, s1W2R3RW },
833   /* 18 */
834   { e_sbb,  t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
835   { e_sbb,  t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
836   { e_sbb,  t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
837   { e_sbb,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
838   { e_sbb,  t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
839   { e_sbb,  t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
840   { e_push, t_done, 0, false, { STHw, DS, eSP }, 0, s1W2R3RW },
841   { e_pop , t_done, 0, false, { DS, STPw, eSP }, 0, s1W2R3RW },
842   /* 20 */
843   { e_and, t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
844   { e_and, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
845   { e_and, t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
846   { e_and, t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
847   { e_and, t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
848   { e_and, t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
849   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
850   { e_daa, t_done, 0, false, { AL, Zz, Zz }, 0, s1RW },
851   /* 28 */
852   { e_sub, t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
853   { e_sub, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
854   { e_sub, t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
855   { e_sub, t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
856   { e_sub, t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
857   { e_sub, t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
858   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
859   { e_das , t_done, 0, false, { AL, Zz, Zz }, 0, s1RW },
860   /* 30 */
861   { e_xor, t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2R },
862   { e_xor, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
863   { e_xor, t_done, 0, true, { Gb, Eb, Zz }, 0, s1RW2R },
864   { e_xor, t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
865   { e_xor, t_done, 0, false, { AL, Ib, Zz }, 0, s1RW2R },
866   { e_xor, t_done, 0, false, { eAX, Iz, Zz }, 0, s1RW2R },
867   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
868   { e_aaa, t_done, 0, false, { AX, Zz, Zz }, 0, s1RW2R },
869   /* 38 */
870   { e_cmp, t_done, 0, true, { Eb, Gb, Zz }, 0, s1R2R },
871   { e_cmp, t_done, 0, true, { Ev, Gv, Zz }, 0, s1R2R },
872   { e_cmp, t_done, 0, true, { Gb, Eb, Zz }, 0, s1R2R },
873   { e_cmp, t_done, 0, true, { Gv, Ev, Zz }, 0, s1R2R },
874   { e_cmp, t_done, 0, false, { AL, Ib, Zz }, 0, s1R2R },
875   { e_cmp, t_done, 0, false, { eAX, Iz, Zz }, 0, s1R2R },
876   { e_No_Entry,     t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
877   { e_aas, t_done, 0, false, { AX, Zz, Zz }, 0, s1RW },
878   /* 40 */
879   { e_inc, t_done, 0, false, { eAX, Zz, Zz }, 0, s1RW },
880   { e_inc, t_done, 0, false, { eCX, Zz, Zz }, 0, s1RW },
881   { e_inc, t_done, 0, false, { eDX, Zz, Zz }, 0, s1RW },
882   { e_inc, t_done, 0, false, { eBX, Zz, Zz }, 0, s1RW },
883   { e_inc, t_done, 0, false, { eSP, Zz, Zz }, 0, s1RW },
884   { e_inc, t_done, 0, false, { eBP, Zz, Zz }, 0, s1RW },
885   { e_inc, t_done, 0, false, { eSI, Zz, Zz }, 0, s1RW },
886   { e_inc, t_done, 0, false, { eDI, Zz, Zz }, 0, s1RW },
887   /* 48 */
888   { e_dec, t_done, 0, false, { eAX, Zz, Zz }, 0, s1RW },
889   { e_dec, t_done, 0, false, { eCX, Zz, Zz }, 0, s1RW },
890   { e_dec, t_done, 0, false, { eDX, Zz, Zz }, 0, s1RW },
891   { e_dec, t_done, 0, false, { eBX, Zz, Zz }, 0, s1RW },
892   { e_dec, t_done, 0, false, { eSP, Zz, Zz }, 0, s1RW },
893   { e_dec, t_done, 0, false, { eBP, Zz, Zz }, 0, s1RW },
894   { e_dec, t_done, 0, false, { eSI, Zz, Zz }, 0, s1RW },
895   { e_dec, t_done, 0, false, { eDI, Zz, Zz }, 0, s1RW },
896   /* 50 */
897   { e_push, t_done, 0, false, { STHv, eAX, eSP }, 0, s1W2R3RW },
898   { e_push, t_done, 0, false, { STHv, eCX, eSP }, 0, s1W2R3RW },
899   { e_push, t_done, 0, false, { STHv, eDX, eSP }, 0, s1W2R3RW },
900   { e_push, t_done, 0, false, { STHv, eBX, eSP }, 0, s1W2R3RW },
901   { e_push, t_done, 0, false, { STHv, eSP, eSP }, 0, s1W2R3RW },
902   { e_push, t_done, 0, false, { STHv, eBP, eSP }, 0, s1W2R3RW },
903   { e_push, t_done, 0, false, { STHv, eSI, eSP }, 0, s1W2R3RW },
904   { e_push, t_done, 0, false, { STHv, eDI, eSP }, 0, s1W2R3RW },
905   /* 58 */
906   { e_pop, t_done, 0, false, { eAX, STPv, eSP }, 0, s1W2R3RW },
907   { e_pop, t_done, 0, false, { eCX, STPv, eSP }, 0, s1W2R3RW },
908   { e_pop, t_done, 0, false, { eDX, STPv, eSP }, 0, s1W2R3RW },
909   { e_pop, t_done, 0, false, { eBX, STPv, eSP }, 0, s1W2R3RW },
910   { e_pop, t_done, 0, false, { eSP, STPv, eSP }, 0, s1W2R3RW },
911   { e_pop, t_done, 0, false, { eBP, STPv, eSP }, 0, s1W2R3RW },
912   { e_pop, t_done, 0, false, { eSI, STPv, eSP }, 0, s1W2R3RW },
913   { e_pop, t_done, 0, false, { eDI, STPv, eSP }, 0, s1W2R3RW },
914   /* 60 */
915   { e_pusha_d, t_done, 0, false, { STHa, GPRS, eSP }, 0, s1W2R3RW },
916   { e_popa_d,  t_done, 0, false, { GPRS, STPa, eSP }, 0, s1W2R3RW },
917   { e_bound,    t_done, 0, true, { Gv, Ma, Zz }, 0, s1R2R },
918   { e_arpl,     t_done, 0, true, { Ew, Gw, Zz }, 0, s1R2R },
919   { e_No_Entry,          t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
920   { e_No_Entry,          t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
921   { e_No_Entry,   t_prefixedSSE, 2, false, { Zz, Zz, Zz }, 0, 0 }, /* operand size prefix (PREFIX_OPR_SZ)*/
922   { e_No_Entry,          t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 }, /* address size prefix (PREFIX_ADDR_SZ)*/
923   /* 68 */
924   { e_push,    t_done, 0, false, { STHv, Iz, eSP }, 0, s1W2R3RW },
925   { e_imul,    t_done, 0, true, { Gv, Ev, Iz }, 0, s1W2R3R },
926   { e_push,    t_done, 0, false, { STHb, Ib, eSP }, 0, s1W2R3RW },
927   { e_imul,    t_done, 0, true, { Gv, Ev, Ib }, 0, s1W2R3R },
928   { e_insb,    t_done, 0, false, { Yb, DX, Zz }, 0, s1W2R | (fREP << FPOS) }, // (e)SI/DI changed
929   { e_insw_d,  t_done, 0, false, { Yv, DX, Zz }, 0, s1W2R | (fREP << FPOS) },
930   { e_outsb,   t_done, 0, false, { DX, Xb, Zz }, 0, s1W2R | (fREP << FPOS) },
931   { e_outsw_d, t_done, 0, false, { DX, Xv, Zz }, 0, s1W2R | (fREP << FPOS) },
932   /* 70 */
933   { e_jo,         t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
934   { e_jno,        t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
935   { e_jb_jnaej_j, t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
936   { e_jnb_jae_j,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
937   { e_jz,         t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
938   { e_jnz,        t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
939   { e_jbe,        t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
940   { e_jnbe,       t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
941   /* 78 */
942   { e_js,   t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
943   { e_jns,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
944   { e_jp,   t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
945   { e_jnp,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
946   { e_jl,   t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
947   { e_jnl,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
948   { e_jle,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
949   { e_jnle, t_done, 0, false, { Jb, Zz, Zz }, (IS_JCC | REL_B), s1R },
950   /* 80 */
951   { e_No_Entry, t_grp, Grp1a, true, { Zz, Zz, Zz }, 0, 0 },
952   { e_No_Entry, t_grp, Grp1b, true, { Zz, Zz, Zz }, 0, 0 },
953   { e_No_Entry, t_grp, Grp1c, true, { Zz, Zz, Zz }, 0, 0 }, // book says Grp1 however;sandpile.org agrees.
954   { e_No_Entry, t_grp, Grp1d, true, { Zz, Zz, Zz }, 0, 0 },
955   { e_test, t_done, 0, true, { Eb, Gb, Zz }, 0, s1R2R },
956   { e_test, t_done, 0, true, { Ev, Gv, Zz }, 0, s1R2R },
957   { e_xchg, t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2RW },
958   { e_xchg, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2RW },
959   /* 88 */
960   { e_mov, t_done, 0, true, { Eb, Gb, Zz }, 0, s1W2R },
961   { e_mov, t_done, 0, true, { Ev, Gv, Zz }, 0, s1W2R },
962   { e_mov, t_done, 0, true, { Gb, Eb, Zz }, 0, s1W2R },
963   { e_mov, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R },
964   { e_mov, t_done, 0, true, { Ew, Sw, Zz }, 0, s1W2R },
965   { e_lea, t_done, 0, true, { Gv, Mlea, Zz }, 0, s1W2R }, // this is just M in the book
966                                                         // AFAICT the 2nd operand is not accessed
967   { e_mov, t_done, 0, true, { Sw, Ew, Zz }, 0, s1W2R },
968   { e_pop, t_done, 0, true, { Ev, STPv, eSP }, 0, s1W2R3RW },
969   /* 90 */
970   { e_nop,  t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // actually xchg eax,eax
971   { e_xchg, t_done, 0, false, { eCX, eAX, Zz }, 0, s1RW2RW },
972   { e_xchg, t_done, 0, false, { eDX, eAX, Zz }, 0, s1RW2RW },
973   { e_xchg, t_done, 0, false, { eBX, eAX, Zz }, 0, s1RW2RW },
974   { e_xchg, t_done, 0, false, { eSP, eAX, Zz }, 0, s1RW2RW },
975   { e_xchg, t_done, 0, false, { eBP, eAX, Zz }, 0, s1RW2RW },
976   { e_xchg, t_done, 0, false, { eSI, eAX, Zz }, 0, s1RW2RW },
977   { e_xchg, t_done, 0, false, { eDI, eAX, Zz }, 0, s1RW2RW },
978   /* 98 */
979   { e_cbw_cwde, t_done, 0, false, { eAX, Zz, Zz }, 0, s1RW },
980   { e_cwd_cdq,  t_done, 0, false, { eDX, eAX, Zz }, 0, s1W2R },
981   { e_call,     t_done, 0, false, { Ap, Zz, Zz }, IS_CALL | PTR_WX, s1R },
982   { e_wait,     t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
983   { e_pushf_d, t_done, 0, false, { STHv, Fv, eSP }, 0, s1W2R3RW },
984   { e_popf_d,  t_done, 0, false, { Fv, STPv, eSP }, 0, s1W2R3RW },
985   { e_sahf,     t_done, 0, false, { Zz, Zz, Zz }, 0, 0 }, // FIXME Intel
986   { e_lahf,     t_done, 0, false, { Zz, Zz, Zz }, 0, 0 }, // FIXME Intel
987   /* A0 */
988   { e_mov,   t_done, 0, false, { AL, Ob, Zz },  0, s1W2R },
989   { e_mov,   t_done, 0, false, { eAX, Ov, Zz }, 0, s1W2R },
990   { e_mov,   t_done, 0, false, { Ob, AL, Zz },  0, s1W2R },
991   { e_mov,   t_done, 0, false, { Ov, eAX, Zz }, 0, s1W2R },
992   // XXX: Xv is source, Yv is destination for movs, so they're swapped!
993   { e_movsb, t_done, 0, false, { Yb, Xb, Zz },  0, s1W2R | (fREP << FPOS) }, // (e)SI/DI changed
994   { e_movsw_d, t_done, 0, false, { Yv, Xv, Zz }, 0, s1W2R | (fREP << FPOS) },
995   { e_cmpsb, t_done, 0, false, { Xb, Yb, Zz },  0, s1R2R | (fCMPS << FPOS) },
996   { e_cmpsw, t_done, 0, false, { Xv, Yv, Zz },  0, s1R2R | (fCMPS << FPOS) },
997   /* A8 */
998   { e_test,     t_done, 0, false, { AL, Ib, Zz },  0, s1R2R },
999   { e_test,     t_done, 0, false, { eAX, Iz, Zz }, 0, s1R2R },
1000   { e_stosb,    t_done, 0, false, { Yb, AL, Zz },  0, s1W2R | (fREP << FPOS) },
1001   { e_stosw_d,  t_done, 0, false, { Yv, eAX, Zz }, 0, s1W2R | (fREP << FPOS) },
1002   { e_lodsb,    t_done, 0, false, { AL, Xb, Zz },  0, s1W2R | (fREP << FPOS) },
1003   { e_lodsw,    t_done, 0, false, { eAX, Xv, Zz }, 0, s1W2R | (fREP << FPOS) },
1004   { e_scasb,    t_done, 0, false, { AL, Yb, Zz },  0, s1R2R | (fSCAS << FPOS) },
1005   { e_scasw_d,  t_done, 0, false, { eAX, Yv, Zz }, 0, s1R2R | (fSCAS << FPOS) },
1006   /* B0 */
1007   { e_mov, t_done, 0, false, { AL, Ib, Zz }, 0, s1W2R },
1008   { e_mov, t_done, 0, false, { CL, Ib, Zz }, 0, s1W2R },
1009   { e_mov, t_done, 0, false, { DL, Ib, Zz }, 0, s1W2R },
1010   { e_mov, t_done, 0, false, { BL, Ib, Zz }, 0, s1W2R },
1011   { e_mov, t_done, 0, false, { AH, Ib, Zz }, 0, s1W2R },
1012   { e_mov, t_done, 0, false, { CH, Ib, Zz }, 0, s1W2R },
1013   { e_mov, t_done, 0, false, { DH, Ib, Zz }, 0, s1W2R },
1014   { e_mov, t_done, 0, false, { BH, Ib, Zz }, 0, s1W2R },
1015   /* B8 */
1016   { e_mov, t_done, 0, false, { eAX, Iv, Zz }, 0, s1W2R },
1017   { e_mov, t_done, 0, false, { eCX, Iv, Zz }, 0, s1W2R },
1018   { e_mov, t_done, 0, false, { eDX, Iv, Zz }, 0, s1W2R },
1019   { e_mov, t_done, 0, false, { eBX, Iv, Zz }, 0, s1W2R },
1020   { e_mov, t_done, 0, false, { eSP, Iv, Zz }, 0, s1W2R },
1021   { e_mov, t_done, 0, false, { eBP, Iv, Zz }, 0, s1W2R },
1022   { e_mov, t_done, 0, false, { eSI, Iv, Zz }, 0, s1W2R },
1023   { e_mov, t_done, 0, false, { eDI, Iv, Zz }, 0, s1W2R },
1024   /* C0 */
1025   { e_No_Entry, t_grp, Grp2, true, { Eb, Ib, Zz }, 0, s1RW2R },
1026   { e_No_Entry, t_grp, Grp2, true, { Ev, Ib, Zz }, 0, s1RW2R },
1027   { e_ret_near, t_done, 0, false, { Iw, Zz, Zz }, (IS_RET | IS_RETC), s1R | (fNEARRET << FPOS) },
1028   { e_ret_near, t_done, 0, false, { Zz, Zz, Zz }, (IS_RET), fNEARRET << FPOS },
1029   { e_les,      t_done, 0, true, { ES, Gv, Mp }, 0, s1W2W3R },
1030   { e_lds,      t_done, 0, true, { DS, Gv, Mp }, 0, s1W2W3R },
1031   { e_No_Entry, t_grp, Grp11, true, { Eb, Ib, Zz }, 0, s1W2R },
1032   { e_No_Entry, t_grp, Grp11, true, { Ev, Iz, Zz }, 0, s1W2R },
1033   /* C8 */
1034   { e_enter,   t_done, 0, false, { Iw, Ib, Zz }, 0, fENTER << FPOS },
1035   { e_leave,   t_done, 0, false, { Zz, Zz, Zz }, 0, fLEAVE << FPOS },
1036   { e_ret_far, t_done, 0, false, { Iw, Zz, Zz }, (IS_RETF | IS_RETC), fFARRET << FPOS },
1037   { e_ret_far, t_done, 0, false, { Zz, Zz, Zz }, (IS_RETF), fFARRET << FPOS },
1038   { e_int3,   t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1039   { e_int,     t_done, 0, false, { Ib, Zz, Zz }, 0, sNONE },
1040   { e_into,    t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1041   { e_iret,    t_done, 0, false, { Zz, Zz, Zz }, (IS_RET), fIRET << FPOS},
1042   /* D0 */
1043   { e_No_Entry, t_grp, Grp2, true, { Eb, Zz, Zz }, 0, s1RW }, // const1
1044   { e_No_Entry, t_grp, Grp2, true, { Ev, Zz, Zz }, 0, s1RW }, // --"--
1045   { e_No_Entry, t_grp, Grp2, true, { Eb, CL, Zz }, 0, s1RW2R },
1046   { e_No_Entry, t_grp, Grp2, true, { Ev, CL, Zz }, 0, s1RW2R },
1047   { e_aam,  t_done, 0, false, { AX, Ib, Zz }, 0, s1RW2R },
1048   { e_aad,  t_done, 0, false, { AX, Ib, Zz }, 0, s1RW2R },
1049   { e_salc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // undocumeted
1050   { e_xlat, t_done, 0, false, { Zz, Zz, Zz }, 0, fXLAT << FPOS }, // scream
1051   /* D8 */
1052   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1053   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1054   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1055   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1056   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1057   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1058   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1059   { e_No_Entry, t_coprocEsc, 0, true, { Zz, Zz, Zz }, 0, 0 },
1060   /* E0 */
1061   { e_loopn,    t_done, 0, false, { Jb, eCX, Zz }, 0, s1R2R }, // aren't these conditional jumps?
1062   { e_loope,    t_done, 0, false, { Jb, eCX, Zz }, 0, s1R2R },
1063   { e_loop,     t_done, 0, false, { Jb, eCX, Zz }, 0, s1R2R },
1064   { e_jcxz_jec, t_done, 0, false, { Jb, eCX, Zz }, (IS_JCC | REL_B), s1R2R },
1065   { e_in,       t_done, 0, false, { AL, Ib, Zz }, 0, s1W2R | fIO << FPOS },
1066   { e_in,       t_done, 0, false, { eAX, Ib, Zz }, 0, s1W2R | fIO << FPOS },
1067   { e_out,      t_done, 0, false, { Ib, AL, Zz }, 0, s1W2R | fIO << FPOS },
1068   { e_out,      t_done, 0, false, { Ib, eAX, Zz }, 0, s1W2R | fIO << FPOS },
1069   /* E8 */
1070   { e_call, t_done, 0, false, { Jz, Zz, Zz }, (IS_CALL | REL_X), fCALL << FPOS },
1071   { e_jmp,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JUMP | REL_X), s1R },
1072   { e_jmp,  t_done, 0, false, { Ap, Zz, Zz }, (IS_JUMP | PTR_WX), s1R },
1073   { e_jmp,  t_done, 0, false, { Jb, Zz, Zz }, (IS_JUMP | REL_B), s1R },
1074   { e_in,   t_done, 0, false, { AL, DX, Zz }, 0, s1W2R | (fIO << FPOS) },
1075   { e_in,   t_done, 0, false, { eAX, DX, Zz }, 0, s1W2R | (fIO << FPOS) },
1076   { e_out,  t_done, 0, false, { DX, AL, Zz }, 0, s1W2R | (fIO << FPOS) },
1077   { e_out,  t_done, 0, false, { DX, eAX, Zz }, 0, s1W2R | (fIO << FPOS) },
1078   /* F0 */
1079   { e_No_Entry,      t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_INSTR
1080   { e_int1, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // undocumented
1081   { e_No_Entry, t_prefixedSSE, 3, false, { Zz, Zz, Zz }, 0, 0 },
1082   { e_No_Entry, t_prefixedSSE, 1, false, { Zz, Zz, Zz }, 0, 0 },
1083   { e_hlt,  t_done, 0, false, { Zz, Zz, Zz }, PRVLGD, sNONE },
1084   { e_cmc,  t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1085   { e_No_Entry, t_grp, Grp3a, true, { Zz, Zz, Zz }, 0, sNONE },
1086   { e_No_Entry, t_grp, Grp3b, true, { Zz, Zz, Zz }, 0, sNONE },
1087   /* F8 */
1088   { e_clc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1089   { e_stc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1090   { e_cli, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1091   { e_sti, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1092   { e_cld, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1093   { e_std, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1094   { e_No_Entry, t_grp, Grp4, true, { Zz, Zz, Zz }, 0, sNONE },
1095   { e_No_Entry, t_grp, Grp5, true, { Zz, Zz, Zz }, 0, sNONE }
1096 };
1097
1098
1099 // twoByteMap: two byte opcode instructions (first byte is 0x0F)
1100 static ia32_entry twoByteMap[256] = {
1101   /* 00 */
1102   // Syscall/sysret are somewhat hacked
1103   // Syscall on amd64 will also read CS/SS for where to call in 32-bit mode
1104   { e_No_Entry, t_grp, Grp6, true, { Zz, Zz, Zz }, 0, 0 },
1105   { e_No_Entry, t_grp, Grp7, false, { Zz, Zz, Zz }, 0, 0 },
1106   { e_lar,        t_done, 0, true, { Gv, Ew, Zz }, 0, s1W2R | (fSEGDESC << FPOS) },
1107   { e_lsl,        t_done, 0, true, { Gv, Ew, Zz }, 0, s1W2R | (fSEGDESC << FPOS) },
1108   { e_No_Entry,            t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 },
1109   { e_syscall,    t_done, 0, false, { eCX, Zz, Zz }, 0, s1W }, // AMD: writes return address to eCX; for liveness, treat as hammering all
1110   { e_clts,       t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1111   { e_sysret,     t_done, 0, false, { eCX, Zz, Zz }, 0, s1R }, // AMD; reads return address from eCX; unlikely to occur in Dyninst use cases but we'll be paranoid
1112   /* 08 */
1113   { e_invd,   t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // only in priviledge 0, so ignored
1114   { e_wbinvd, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // idem
1115   { e_No_Entry,        t_ill,  0, false, { Zz, Zz, Zz }, 0, 0 },
1116   { e_ud2,    t_ill,  0, 0, { Zz, Zz, Zz }, 0, 0 },
1117   { e_No_Entry,        t_ill,  0, 0, { Zz, Zz, Zz }, 0, 0 },
1118   { e_prefetch_w, t_grp, GrpAMD, true, { Zz, Zz, Zz }, 0, 0 },    // AMD prefetch group
1119   { e_femms,       t_done,  0, false, { Zz, Zz, Zz }, 0, sNONE },  // AMD specific
1120   // semantic is bogus for the 1st operand - but correct for the 2nd,
1121   // which is the only one that can be a memory operand :)
1122   // fixing the 1st operand requires an extra table for the 3dnow instructions...
1123   { e_No_Entry,             t_3dnow, 0, true,  { Pq, Qq, Zz }, 0, s1RW2R }, // AMD 3DNow! suffixes
1124   /* 10 */
1125   { e_No_Entry, t_sse, SSE10, true, { Zz, Zz, Zz }, 0, 0 },
1126   { e_No_Entry, t_sse, SSE11, true, { Zz, Zz, Zz }, 0, 0 },
1127   { e_No_Entry, t_sse, SSE12, true, { Zz, Zz, Zz }, 0, 0 },
1128   { e_No_Entry, t_sse, SSE13, true, { Zz, Zz, Zz }, 0, 0 },
1129   { e_No_Entry, t_sse, SSE14, true, { Zz, Zz, Zz }, 0, 0 },
1130   { e_No_Entry, t_sse, SSE15, true, { Zz, Zz, Zz }, 0, 0 },
1131   { e_No_Entry, t_sse, SSE16, true, { Zz, Zz, Zz }, 0, 0 },
1132   { e_No_Entry, t_sse, SSE17, true, { Zz, Zz, Zz }, 0, 0 },
1133   /* 18 */
1134   { e_No_Entry, t_grp, Grp16, 0, { Zz, Zz, Zz }, 0, 0 },
1135   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1136   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1137   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1138   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1139   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1140   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1141   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1142   /* 20 */
1143   { e_mov, t_done, 0, true, { Rd, Cd, Zz }, 0, s1W2R },
1144   { e_mov, t_done, 0, true, { Rd, Dd, Zz }, 0, s1W2R },
1145   { e_mov, t_done, 0, true, { Cd, Rd, Zz }, 0, s1W2R },
1146   { e_mov, t_done, 0, true, { Dd, Rd, Zz }, 0, s1W2R },
1147   { e_mov, t_done, 0, true, { Rd, Td, Zz }, 0, s1W2R },
1148   { e_No_Entry,     t_ill,  0, 0, { Zz, Zz, Zz }, 0, 0 },
1149   { e_mov, t_done, 0, true, { Td, Rd, Zz }, 0, s1W2R },
1150   { e_No_Entry,     t_ill,  0, 0, { Zz, Zz, Zz }, 0, 0 },
1151   /* 28 */
1152   { e_No_Entry, t_sse, SSE28, true, { Zz, Zz, Zz }, 0, 0 },
1153   { e_No_Entry, t_sse, SSE29, true, { Zz, Zz, Zz }, 0, 0 },
1154   { e_No_Entry, t_sse, SSE2A, true, { Zz, Zz, Zz }, 0, 0 },
1155   { e_No_Entry, t_sse, SSE2B, true, { Zz, Zz, Zz }, 0, 0 },
1156   { e_No_Entry, t_sse, SSE2C, true, { Zz, Zz, Zz }, 0, 0 },
1157   { e_No_Entry, t_sse, SSE2D, true, { Zz, Zz, Zz }, 0, 0 },
1158   { e_No_Entry, t_sse, SSE2E, true, { Zz, Zz, Zz }, 0, 0 },
1159   { e_No_Entry, t_sse, SSE2F, true, { Zz, Zz, Zz }, 0, 0 },
1160   /* 30 */
1161   { e_wrmsr, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1162   { e_rdtsc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE},
1163   { e_rdmsr, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1164   { e_rdpmc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1165   { e_sysenter, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // XXX: fixme for kernel work
1166   { e_sysexit,  t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // XXX: fixme for kernel work
1167   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 }, 
1168   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1169   /* 38 */
1170   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1171   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1172   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1173   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1174   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1175   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1176   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1177   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0 ,0 },
1178   /* 40 */
1179   { e_cmovo,   t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1180   { e_cmovno,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1181   { e_cmovnae, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1182   { e_cmovnb,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1183   { e_cmove,   t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1184   { e_cmovne,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1185   { e_cmovbe,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1186   { e_cmovnbe, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1187   /* 48 */
1188   { e_cmovs,   t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1189   { e_cmovns,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1190   { e_cmovpe,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1191   { e_cmovpo,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1192   { e_cmovnge, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1193   { e_cmovnl,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1194   { e_cmovng,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1195   { e_cmovnl,  t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R | (fCOND << FPOS) },
1196   /* 50 */
1197   { e_No_Entry, t_sse, SSE50, true, { Zz, Zz, Zz }, 0, 0 },
1198   { e_No_Entry, t_sse, SSE51, true, { Zz, Zz, Zz }, 0, 0 },
1199   { e_No_Entry, t_sse, SSE52, true, { Zz, Zz, Zz }, 0, 0 },
1200   { e_No_Entry, t_sse, SSE53, true, { Zz, Zz, Zz }, 0, 0 },
1201   { e_No_Entry, t_sse, SSE54, true, { Zz, Zz, Zz }, 0, 0 },
1202   { e_No_Entry, t_sse, SSE55, true, { Zz, Zz, Zz }, 0, 0 },
1203   { e_No_Entry, t_sse, SSE56, true, { Zz, Zz, Zz }, 0, 0 },
1204   { e_No_Entry, t_sse, SSE57, true, { Zz, Zz, Zz }, 0, 0 },
1205   /* 58 */
1206   { e_No_Entry, t_sse, SSE58, true, { Zz, Zz, Zz }, 0, 0 },
1207   { e_No_Entry, t_sse, SSE59, true, { Zz, Zz, Zz }, 0, 0 },
1208   { e_No_Entry, t_sse, SSE5A, true, { Zz, Zz, Zz }, 0, 0 },
1209   { e_No_Entry, t_sse, SSE5B, true, { Zz, Zz, Zz }, 0, 0 },
1210   { e_No_Entry, t_sse, SSE5C, true, { Zz, Zz, Zz }, 0, 0 },
1211   { e_No_Entry, t_sse, SSE5D, true, { Zz, Zz, Zz }, 0, 0 },
1212   { e_No_Entry, t_sse, SSE5E, true, { Zz, Zz, Zz }, 0, 0 },
1213   { e_No_Entry, t_sse, SSE5F, true, { Zz, Zz, Zz }, 0, 0 },
1214   /* 60 */
1215   { e_No_Entry, t_sse, SSE60, true, { Zz, Zz, Zz }, 0, 0 },
1216   { e_No_Entry, t_sse, SSE61, true, { Zz, Zz, Zz }, 0, 0 },
1217   { e_No_Entry, t_sse, SSE62, true, { Zz, Zz, Zz }, 0, 0 },
1218   { e_No_Entry, t_sse, SSE63, true, { Zz, Zz, Zz }, 0, 0 },
1219   { e_No_Entry, t_sse, SSE64, true, { Zz, Zz, Zz }, 0, 0 },
1220   { e_No_Entry, t_sse, SSE65, true, { Zz, Zz, Zz }, 0, 0 },
1221   { e_No_Entry, t_sse, SSE66, true, { Zz, Zz, Zz }, 0, 0 },
1222   { e_No_Entry, t_sse, SSE67, true, { Zz, Zz, Zz }, 0, 0 },
1223   /* 68 */
1224   { e_No_Entry, t_sse, SSE68, true, { Zz, Zz, Zz }, 0, 0 },
1225   { e_No_Entry, t_sse, SSE69, true, { Zz, Zz, Zz }, 0, 0 },
1226   { e_No_Entry, t_sse, SSE6A, true, { Zz, Zz, Zz }, 0, 0 },
1227   { e_No_Entry, t_sse, SSE6B, true, { Zz, Zz, Zz }, 0, 0 },
1228   { e_No_Entry, t_sse, SSE6C, true, { Zz, Zz, Zz }, 0, 0 },
1229   { e_No_Entry, t_sse, SSE6D, true, { Zz, Zz, Zz }, 0, 0 },
1230   { e_No_Entry, t_sse, SSE6E, true, { Zz, Zz, Zz }, 0, 0 },
1231   { e_No_Entry, t_sse, SSE6F, true, { Zz, Zz, Zz }, 0, 0 },
1232   /* 70 */
1233   { e_No_Entry, t_sse, SSE70, true, { Zz, Zz, Zz }, 0, 0 },
1234   { e_No_Entry, t_grp, Grp12, false, { Zz, Zz, Zz }, 0, 0 },
1235   { e_No_Entry, t_grp, Grp13, false, { Zz, Zz, Zz }, 0, 0 },
1236   { e_No_Entry, t_grp, Grp14, false, { Zz, Zz, Zz }, 0, 0 },
1237   { e_No_Entry, t_sse, SSE74, true, { Zz, Zz, Zz }, 0, 0 },
1238   { e_No_Entry, t_sse, SSE75, true, { Zz, Zz, Zz }, 0, 0 },
1239   { e_No_Entry, t_sse, SSE76, true, { Zz, Zz, Zz }, 0, 0 },
1240   { e_emms, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1241   /* 78 */
1242   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1243   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1244   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1245   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1246   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1247   { e_mmxud, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1248   { e_No_Entry, t_sse, SSE7E, 0, { Zz, Zz, Zz }, 0, 0 },
1249   { e_No_Entry, t_sse, SSE7F, 0, { Zz, Zz, Zz }, 0, 0 },
1250   /* 80 */
1251   { e_jo,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1252   { e_jno,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1253   { e_jb,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1254   { e_jnb,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1255   { e_jz,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1256   { e_jnz,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1257   { e_jbe,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1258   { e_jnbe, t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1259   /* 88 */
1260   { e_js,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1261   { e_jns,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1262   { e_jp,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1263   { e_jnp,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1264   { e_jl,   t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1265   { e_jnl,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1266   { e_jle,  t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1267   { e_jnle, t_done, 0, false, { Jz, Zz, Zz }, (IS_JCC | REL_X), s1R | (fCOND << FPOS) },
1268   /* 90 */
1269   { e_seto,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1270   { e_setno,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1271   { e_setb,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1272   { e_setnb,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1273   { e_setz,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1274   { e_setnz,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1275   { e_setbe,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1276   { e_setnbe, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1277   /* 98 */
1278   { e_sets,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1279   { e_setns,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1280   { e_setp,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1281   { e_setnp,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1282   { e_setl,   t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1283   { e_setnl,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1284   { e_setle,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1285   { e_setnle, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
1286   /* A0 */
1287   { e_push,   t_done, 0, false, { STHw, FS, eSP }, 0, s1W2R3RW },
1288   { e_pop,    t_done, 0, false, { FS, STPw, eSP }, 0, s1W2R3RW },
1289   { e_cpuid,  t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1290   { e_bt,     t_done, 0, true, { Ev, Gv, Zz }, 0, s1R2R },
1291   { e_shld,   t_done, 0, true, { Ev, Gv, Ib }, 0, s1RW2R3R },
1292   { e_shld,   t_done, 0, true, { Ev, Gv, CL }, 0, s1RW2R3R },
1293   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 }, 
1294   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1295   /* A8 */
1296   { e_push, t_done, 0, false, { STHw, GS, eSP }, 0, s1W2R3RW },
1297   { e_pop,  t_done, 0, false, { GS, STPw, eSP }, 0, s1W2R3RW },
1298   { e_rsm,  t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
1299   { e_bts,  t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
1300   { e_shrd, t_done, 0, true, { Ev, Gv, Ib }, 0, s1RW2R3R },
1301   { e_shrd, t_done, 0, true, { Ev, Gv, CL }, 0, s1RW2R3R },
1302   { e_No_Entry, t_grp, Grp15, 0, { Zz, Zz, Zz }, 0, 0 }, 
1303   { e_imul, t_done, 0, true, { Gv, Ev, Zz }, 0, s1RW2R },
1304   /* B0 */
1305   // Assuming this is used with LOCK prefix, the destination gets a write anyway
1306   // This is not the case without lock prefix, but I ignore that case
1307   // Also, given that the 3rd operand is a register I ignore that it may be written
1308   { e_cmpxch, t_done, 0, true, { Eb, Gb, AL }, 0, s1RW2R3R | (fCMPXCH << FPOS) },
1309   { e_cmpxch, t_done, 0, true, { Ev, Gv, eAX }, 0, s1RW2R3R | (fCMPXCH << FPOS) },
1310   { e_lss, t_done, 0, true, { SS, Gv, Mp }, 0, s1W2W3R },
1311   { e_btr, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
1312   { e_lfs, t_done, 0, true, { FS, Gv, Mp }, 0, s1W2W3R },
1313   { e_lgs, t_done, 0, true, { GS, Gv, Mp }, 0, s1W2W3R },
1314   { e_movzx, t_done, 0, true, { Gv, Eb, Zz }, 0, s1W2R },
1315   { e_movzx, t_done, 0, true, { Gv, Ew, Zz }, 0, s1W2R },
1316   /* B8 */
1317   { e_No_Entry, t_ill, 0, 0, { Zz, Zz, Zz }, 0, 0 },
1318   { e_ud2grp10, t_ill, 0, 0, { Zz, Zz, Zz }, 0, sNONE },
1319   { e_No_Entry, t_grp, Grp8, true, { Zz, Zz, Zz }, 0, 0 },
1320   { e_btc, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2R },
1321   { e_bsf, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R },
1322   { e_bsr, t_done, 0, true, { Gv, Ev, Zz }, 0, s1W2R },
1323   { e_movsx, t_done, 0, true, { Gv, Eb, Zz }, 0, s1W2R },
1324   { e_movsx, t_done, 0, true, { Gv, Ew, Zz }, 0, s1W2R },
1325   /* C0 */
1326   { e_xadd, t_done, 0, true, { Eb, Gb, Zz }, 0, s1RW2RW },
1327   { e_xadd, t_done, 0, true, { Ev, Gv, Zz }, 0, s1RW2RW },
1328   { e_No_Entry, t_sse, SSEC2, true, { Zz, Zz, Zz }, 0, 0 },
1329   { e_movnti , t_done, 0, 0, { Ev, Gv, Zz }, 0, s1W2R | (fNT << FPOS) },
1330   { e_No_Entry, t_sse, SSEC4, true, { Zz, Zz, Zz }, 0, 0 },
1331   { e_No_Entry, t_sse, SSEC5, true, { Zz, Zz, Zz }, 0, 0 },
1332   { e_No_Entry, t_sse, SSEC6, true, { Zz, Zz, Zz }, 0, 0 },
1333   { e_No_Entry, t_grp, Grp9,  true, { Zz, Zz, Zz }, 0, 0 },
1334   /* C8 */
1335   { e_bswap, t_done, 0, false, { EAX, Zz, Zz }, 0, s1RW }, 
1336   { e_bswap, t_done, 0, false, { ECX, Zz, Zz }, 0, s1RW },
1337   { e_bswap, t_done, 0, false, { EDX, Zz, Zz }, 0, s1RW }, 
1338   { e_bswap, t_done, 0, false, { EBX, Zz, Zz }, 0, s1RW }, 
1339   { e_bswap, t_done, 0, false, { ESP, Zz, Zz }, 0, s1RW },
1340   { e_bswap, t_done, 0, false, { EBP, Zz, Zz }, 0, s1RW }, 
1341   { e_bswap, t_done, 0, false, { ESI, Zz, Zz }, 0, s1RW }, 
1342   { e_bswap, t_done, 0, false, { EDI, Zz, Zz }, 0, s1RW }, 
1343   /* D0 */
1344   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1345   { e_No_Entry, t_sse, SSED1, true, { Zz, Zz, Zz }, 0, 0 },
1346   { e_No_Entry, t_sse, SSED2, true, { Zz, Zz, Zz }, 0, 0 },
1347   { e_No_Entry, t_sse, SSED3, true, { Zz, Zz, Zz }, 0, 0 },
1348   { e_No_Entry, t_sse, SSED4, true, { Zz, Zz, Zz }, 0, 0 },
1349   { e_No_Entry, t_sse, SSED5, true, { Zz, Zz, Zz }, 0, 0 },
1350   { e_No_Entry, t_sse, SSED6, true, { Zz, Zz, Zz }, 0, 0 },
1351   { e_No_Entry, t_sse, SSED7, true, { Zz, Zz, Zz }, 0, 0 },
1352   /* D8 */
1353   { e_No_Entry, t_sse, SSED8, true, { Zz, Zz, Zz }, 0, 0 },
1354   { e_No_Entry, t_sse, SSED9, true, { Zz, Zz, Zz }, 0, 0 },
1355   { e_No_Entry, t_sse, SSEDA, true, { Zz, Zz, Zz }, 0, 0 },
1356   { e_No_Entry, t_sse, SSEDB, true, { Zz, Zz, Zz }, 0, 0 },
1357   { e_No_Entry, t_sse, SSEDC, true, { Zz, Zz, Zz }, 0, 0 },
1358   { e_No_Entry, t_sse, SSEDD, true, { Zz, Zz, Zz }, 0, 0 },
1359   { e_No_Entry, t_sse, SSEDE, true, { Zz, Zz, Zz }, 0, 0 },
1360   { e_No_Entry, t_sse, SSEDF, true, { Zz, Zz, Zz }, 0, 0 },
1361   /* E0 */
1362   { e_No_Entry, t_sse, SSEE0, true, { Zz, Zz, Zz }, 0, 0 },
1363   { e_No_Entry, t_sse, SSEE1, true, { Zz, Zz, Zz }, 0, 0 },
1364   { e_No_Entry, t_sse, SSEE2, true, { Zz, Zz, Zz }, 0, 0 },
1365   { e_No_Entry, t_sse, SSEE3, true, { Zz, Zz, Zz }, 0, 0 },
1366   { e_No_Entry, t_sse, SSEE4, true, { Zz, Zz, Zz }, 0, 0 },
1367   { e_No_Entry, t_sse, SSEE5, true, { Zz, Zz, Zz }, 0, 0 },
1368   { e_No_Entry, t_sse, SSEE6, true, { Zz, Zz, Zz }, 0, 0 },
1369   { e_No_Entry, t_sse, SSEE7, true, { Zz, Zz, Zz }, 0, 0 },
1370   /* E8 */
1371   { e_No_Entry, t_sse, SSEE8, true, { Zz, Zz, Zz }, 0, 0 },
1372   { e_No_Entry, t_sse, SSEE9, true, { Zz, Zz, Zz }, 0, 0 },
1373   { e_No_Entry, t_sse, SSEEA, true, { Zz, Zz, Zz }, 0, 0 },
1374   { e_No_Entry, t_sse, SSEEB, true, { Zz, Zz, Zz }, 0, 0 },
1375   { e_No_Entry, t_sse, SSEEC, true, { Zz, Zz, Zz }, 0, 0 },
1376   { e_No_Entry, t_sse, SSEED, true, { Zz, Zz, Zz }, 0, 0 },
1377   { e_No_Entry, t_sse, SSEEE, true, { Zz, Zz, Zz }, 0, 0 },
1378   { e_No_Entry, t_sse, SSEEF, true, { Zz, Zz, Zz }, 0, 0 },
1379   /* F0 */
1380   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1381   { e_No_Entry, t_sse, SSEF1, true, { Zz, Zz, Zz }, 0, 0 },
1382   { e_No_Entry, t_sse, SSEF2, true, { Zz, Zz, Zz }, 0, 0 },
1383   { e_No_Entry, t_sse, SSEF3, true, { Zz, Zz, Zz }, 0, 0 },
1384   { e_No_Entry, t_sse, SSEF4, true, { Zz, Zz, Zz }, 0, 0 },
1385   { e_No_Entry, t_sse, SSEF5, true, { Zz, Zz, Zz }, 0, 0 },
1386   { e_No_Entry, t_sse, SSEF6, true, { Zz, Zz, Zz }, 0, 0 },
1387   { e_No_Entry, t_sse, SSEF7, true, { Zz, Zz, Zz }, 0, 0 },
1388   /* F8 */
1389   { e_No_Entry, t_sse, SSEF8, true, { Zz, Zz, Zz }, 0, 0 },
1390   { e_No_Entry, t_sse, SSEF9, true, { Zz, Zz, Zz }, 0, 0 },
1391   { e_No_Entry, t_sse, SSEFA, true, { Zz, Zz, Zz }, 0, 0 },
1392   { e_No_Entry, t_sse, SSEFB, true, { Zz, Zz, Zz }, 0, 0 },
1393   { e_No_Entry, t_sse, SSEFC, true, { Zz, Zz, Zz }, 0, 0 },
1394   { e_No_Entry, t_sse, SSEFD, true, { Zz, Zz, Zz }, 0, 0 },
1395   { e_No_Entry, t_sse, SSEFE, true, { Zz, Zz, Zz }, 0, 0 },
1396   { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
1397 };
1398
1399 static ia32_entry groupMap[][8] = {
1400   { /* group 1a */
1401     { e_add, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1402     { e_or,  t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1403     { e_adc, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1404     { e_sbb, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1405     { e_and, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1406     { e_sub, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1407     { e_xor, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1408     { e_cmp, t_done, 0, true, { Eb, Ib, Zz }, 0, s1R2R },
1409   },
1410   { /* group 1b */
1411     { e_add, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1412     { e_or,  t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1413     { e_adc, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1414     { e_sbb, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1415     { e_and, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1416     { e_sub, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1417     { e_xor, t_done, 0, true, { Ev, Iz, Zz }, 0, s1RW2R },
1418     { e_cmp, t_done, 0, true, { Ev, Iz, Zz }, 0, s1R2R },
1419   },
1420   { /* group 1c */
1421     { e_add, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1422     { e_or,  t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1423     { e_adc, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1424     { e_sbb, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1425     { e_and, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1426     { e_sub, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1427     { e_xor, t_done, 0, true, { Eb, Ib, Zz }, 0, s1RW2R },
1428     { e_cmp, t_done, 0, true, { Eb, Ib, Zz }, 0, s1R2R },
1429   },
1430   { /* group 1d */
1431     { e_add, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1432     { e_or,  t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1433     { e_adc, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1434     { e_sbb, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1435     { e_and, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1436     { e_sub, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1437     { e_xor, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1438     { e_cmp, t_done, 0, true, { Ev, Ib, Zz }, 0, s1R2R },
1439   },
1440
1441
1442  {  /* group 2 - only opcode is defined here, 
1443        operands are defined in the one or two byte maps above */
1444   { e_rol, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1445   { e_ror, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1446   { e_rcl, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1447   { e_rcr, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1448   { e_shl_sal, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1449   { e_shr, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 },
1450   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1451   { e_sar, t_done, 0, true, { Zz, Zz, Zz }, 0, 0 }
1452  },
1453
1454  { /* group 3a - operands are defined here */
1455   { e_test, t_done, 0, true, { Eb, Ib, Zz }, 0, s1R2R },
1456   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1457   { e_not,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1RW },
1458   { e_neg,  t_done, 0, true, { Eb, Zz, Zz }, 0, s1RW },
1459   { e_mul,  t_done, 0, true, { AX, AL, Eb }, 0, s1W2RW3R },
1460   { e_imul, t_done, 0, true, { AX, AL, Eb }, 0, s1W2R3R },
1461   { e_div,  t_done, 0, true, { AX, AL, Eb }, 0, s1RW2R3R },
1462   { e_idiv, t_done, 0, true, { AX, AL, Eb }, 0, s1W2R3R }
1463  },
1464
1465  { /* group 3b - operands are defined here */
1466   { e_test, t_done, 0, true, { Ev, Iz, Zz }, 0, s1R2R },
1467   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1468   { e_not,  t_done, 0, true, { Ev, Zz, Zz }, 0, s1RW },
1469   { e_neg,  t_done, 0, true, { Ev, Zz, Zz }, 0, s1RW },
1470   { e_mul,  t_done, 0, true, { eDX, eAX, Ev }, 0, s1W2RW3R },
1471   { e_imul, t_done, 0, true, { eDX, eAX, Ev }, 0, s1W2RW3R },
1472   { e_div,  t_done, 0, true, { eDX, eAX, Ev }, 0, s1RW2RW3R },
1473   { e_idiv, t_done, 0, true, { eDX, eAX, Ev }, 0, s1RW2RW3R }
1474  },
1475
1476  { /* group 4 - operands are defined here */
1477   { e_inc, t_done, 0, true, { Eb, Zz, Zz }, 0, s1RW },
1478   { e_dec, t_done, 0, true, { Eb, Zz, Zz }, 0, s1RW },
1479   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1480   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1481   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1482   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1483   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1484   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1485  },
1486
1487  { /* group 5 - operands are defined here */
1488   { e_inc,  t_done, 0, true, { Ev, Zz, Zz }, 0, s1RW },
1489   { e_dec,  t_done, 0, true, { Ev, Zz, Zz }, 0, s1RW },
1490   { e_call, t_done, 0, true, { Ev, Zz, Zz }, (IS_CALL | INDIR), s1R | (fINDIRCALL << FPOS) },
1491   { e_call, t_done, 0, true, { Ep, Zz, Zz }, (IS_CALL | INDIR), s1R | (fINDIRCALL << FPOS) },
1492   { e_jmp,  t_done, 0, true, { Ev, Zz, Zz }, (IS_JUMP | INDIR), s1R | (fINDIRJUMP << FPOS) },
1493   { e_jmp,  t_done, 0, true, { Ep, Zz, Zz }, (IS_JUMP | INDIR), s1R | (fINDIRJUMP << FPOS) },
1494   { e_push, t_done, 0, true, { Ev, Zz, Zz }, 0, 0 },
1495   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1496  },
1497
1498  { /* group 6 - operands are defined here */
1499    // these need to be fixed for kernel mode accesses
1500   { e_sldt, t_done, 0, true, { Ew, Zz, Zz }, 0, s1W },
1501   { e_str,  t_done, 0, true, { Ew, Zz, Zz }, 0, s1W },
1502   { e_lldt, t_done, 0, true, { Ew, Zz, Zz }, 0, s1R },
1503   { e_ltr,  t_done, 0, true, { Ew, Zz, Zz }, 0, s1R },
1504   { e_verr, t_done, 0, true, { Ew, Zz, Zz }, 0, s1R },
1505   { e_verw, t_done, 0, true, { Ew, Zz, Zz }, 0, s1R },
1506   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1507   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1508  },
1509
1510  { /* group 7 - operands are defined here */
1511    // idem
1512   { e_sgdt, t_done, 0, true, { Ms, Zz, Zz }, 0, s1W },
1513   { e_sidt, t_done, 0, true, { Ms, Zz, Zz }, 0, s1W },
1514   { e_lgdt, t_done, 0, true, { Ms, Zz, Zz }, 0, s1R },
1515   { e_lidt, t_done, 0, true, { Ms, Zz, Zz }, 0, s1R },
1516   { e_smsw, t_done, 0, true, { Ew, Zz, Zz }, 0, s1W },
1517   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1518   { e_lmsw, t_done, 0, true, { Ew, Zz, Zz }, 0, s1R },
1519   { e_invlpg, t_done, 0, true, { Zz, Zz, Zz }, 0, sNONE }, // 64-bit: swapgs also uses this encoding (w/ mod=11)
1520  },
1521
1522  { /* group 8 - only opcode is defined here, 
1523      operands are defined in the one or two byte maps below */
1524   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1525   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1526   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1527   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1528   { e_bt,  t_done, 0, true, { Ev, Ib, Zz }, 0, s1R2R },
1529   { e_bts, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1530   { e_btr, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1531   { e_btc, t_done, 0, true, { Ev, Ib, Zz }, 0, s1RW2R },
1532  },
1533
1534  { /* group 9 - operands are defined here */
1535   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1536   // see comments for cmpxch
1537   { e_cmpxch8b, t_done, 0, true, { EDXEAX, Mq, ECXEBX }, 0, s1RW2RW3R | (fCMPXCH8 << FPOS) },
1538   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1539   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1540   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1541   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1542   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1543   { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }
1544  },
1545
1546  /* group 10 is all illegal */
1547
1548  { /* group 11, opcodes defined in one byte map */
1549    { e_mov, t_done, 0, true, { Zz, Zz, Zz }, 0, sNONE },
1550    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1551    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1552    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1553    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1554    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1555    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1556    { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1557  }
1558
1559 };
1560
1561
1562 // Groups 12-16 are split by mod={mem,11}. Some spill over into SSE groups!
1563 // Notation: G12SSE010B = group 12, SSE, reg=010; B means mod=11
1564 // Use A if Intel decides to put SSE instructions for mod=mem
1565 static ia32_entry groupMap2[][2][8] = {
1566   { /* group 12 */
1567     {
1568       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1569       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1570       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1571       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1572       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1573       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1574       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1575       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1576     },
1577     {
1578       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1579       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1580       { e_No_Entry, t_grpsse, G12SSE010B, true, { Zz, Zz, Zz }, 0, 0 },
1581       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1582       { e_No_Entry, t_grpsse, G12SSE100B, true, { Zz, Zz, Zz }, 0, 0 },
1583       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1584       { e_No_Entry, t_grpsse, G12SSE110B, true, { Zz, Zz, Zz }, 0, 0 },
1585       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1586     }
1587   },
1588   { /* group 13 */
1589     {
1590       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1591       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1592       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1593       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1594       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1595       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1596       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1597       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1598     },
1599     {
1600       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1601       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1602       { e_No_Entry, t_grpsse, G13SSE010B, true, { Zz, Zz, Zz }, 0, 0 },
1603       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1604       { e_No_Entry, t_grpsse, G13SSE100B, true, { Zz, Zz, Zz }, 0, 0 },
1605       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1606       { e_No_Entry, t_grpsse, G13SSE110B, true, { Zz, Zz, Zz }, 0, 0 },
1607       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1608     }
1609   },
1610   { /* group 14 */
1611     {
1612       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1613       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1614       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1615       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1616       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1617       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1618       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1619       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1620     },
1621     {
1622       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1623       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1624       { e_No_Entry, t_grpsse, G14SSE010B, true, { Zz, Zz, Zz }, 0, 0 },
1625       { e_No_Entry, t_grpsse, G14SSE011B, true, { Zz, Zz, Zz }, 0, 0 },
1626       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1627       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1628       { e_No_Entry, t_grpsse, G14SSE110B, true, { Zz, Zz, Zz }, 0, 0 },
1629       { e_No_Entry, t_grpsse, G14SSE111B, true, { Zz, Zz, Zz }, 0, 0 },
1630     }
1631   },
1632   { /* group 15 */
1633     {
1634       { e_fxsave,  t_done, 0, true, { M512, Zz, Zz }, 0, s1W | (fFXSAVE << FPOS) },
1635       { e_fxrstor, t_done, 0, true, { M512, Zz, Zz }, 0, s1R | (fFXRSTOR << FPOS) },
1636       { e_ldmxcsr, t_done, 0, true, { Md, Zz, Zz }, 0, s1R },
1637       { e_stmxcsr, t_done, 0, true, { Md, Zz, Zz }, 0, s1W },
1638       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1639       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1640       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1641       { e_clflush, t_done, 0, true, { Mb, Zz, Zz }, 0, s1W | (fCLFLUSH << FPOS) },
1642     },
1643     {
1644       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1645       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1646       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1647       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1648       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1649       { e_lfence, t_done, 0, true, { Zz, Zz, Zz }, 0, sNONE },
1650       { e_mfence, t_done, 0, true, { Zz, Zz, Zz }, 0, sNONE },
1651       { e_sfence, t_done, 0, true, { Zz, Zz, Zz }, 0, sNONE },
1652     }
1653   },
1654   { /* group 16 */
1655     {
1656       { e_prefetchNTA, t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHNT << FPOS) },
1657       { e_prefetchT0,  t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHT0 << FPOS) },
1658       { e_prefetchT1,  t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHT1 << FPOS) },
1659       { e_prefetchT2,  t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHT1 << FPOS) },
1660       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1661       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1662       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1663       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1664     },
1665     {
1666       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1667       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1668       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1669       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1670       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1671       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1672       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1673       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1674     }
1675   },
1676   { /* AMD prefetch group */
1677     {
1678       { e_prefetch,   t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHAMDE << FPOS) },
1679       { e_prefetchw,  t_done, 0, true, { Mb, Zz, Zz }, 0, s1R | (fPREFETCHAMDW << FPOS) },
1680       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1681       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1682       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1683       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1684       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1685       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 }, // this is reserved, not illegal, ugh...
1686     },
1687     {
1688       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1689       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1690       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1691       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1692       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1693       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1694       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1695       { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
1696     }
1697   }
1698 };
1699
1700 /* rows are not, F3, 66, F2 prefixed in this order (see book) */
1701 static ia32_entry sseMap[][4] = {
1702   { /* SSE10 */
1703     { e_movups, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
1704     { e_movss,  t_done, 0, true, { Vss, Wss, Zz }, 0, s1W2R },
1705     { e_movupd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1W2R },
1706     { e_movsd,  t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1W2R },
1707   },
1708   { /* SSE11 */
1709     { e_movups, t_done, 0, true, { Wps, Vps, Zz }, 0, s1W2R },
1710     { e_movss,  t_done, 0, true, { Wss, Vss, Zz }, 0, s1W2R },
1711     { e_movupd, t_done, 0, true, { Wpd, Vpd, Zz }, 0, s1W2R },
1712     { e_movsd,  t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1W2R }, // FIXME: bug in book?????
1713   },
1714   { /* SSE12 */
1715     { e_movlps_movhlps, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R }, // FIXME: wierd 1st op
1716     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1717     { e_movlpd, t_done, 0, true, { Vq, Ws, Zz }, 0, s1W2R },
1718     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1719   },
1720   { /* SSE13 */
1721     { e_movlps, t_done, 0, true, { Vq, Wq, Zz }, 0, s1W2R },
1722     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1723     { e_movlpd, t_done, 0, true, { Vq, Wq, Zz }, 0, s1W2R },
1724     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1725   },
1726   { /* SSE14 */
1727     { e_unpcklps, t_done, 0, true, { Vps, Wq, Zz }, 0, s1RW2R },
1728     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1729     { e_unpcklpd, t_done, 0, true, { Vpd, Wq, Zz }, 0, s1RW2R },
1730     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1731   },
1732   { /* SSE15 */
1733     { e_unpckhps, t_done, 0, true, { Vps, Wq, Zz }, 0, s1RW2R },
1734     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1735     { e_unpckhpd, t_done, 0, true, { Vpd, Wq, Zz }, 0, s1RW2R },
1736     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1737   },
1738   { /* SSE16 */
1739     { e_movhps_movlhps, t_done, 0, true, { Vq, Wq, Zz }, 0, s1W2R }, // FIXME: wierd 2nd op
1740     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1741     { e_movhpd, t_done, 0, true, { Vq, Wq, Zz }, 0, s1W2R },
1742     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1743   },
1744   { /* SSE17 */
1745     { e_movhps, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R },
1746     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1747     { e_movhpd, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R },
1748     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1749   },
1750   { /* SSE28 */
1751     { e_movaps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
1752     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1753     { e_movapd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1W2R },
1754     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1755   },
1756   { /* SSE29 */
1757     { e_movaps, t_done, 0, true, { Wps, Vps, Zz }, 0, s1W2R },
1758     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1759     { e_movapd, t_done, 0, true, { Wpd, Vpd, Zz }, 0, s1W2R },
1760     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1761   },
1762   { /* SSE2A */
1763     { e_cvtpi2ps, t_done, 0, true, { Vps, Qq, Zz }, 0, s1W2R },
1764     { e_cvtsi2ss, t_done, 0, true, { Vss, Ev, Zz }, 0, s1W2R },
1765     { e_cvtpi2pd, t_done, 0, true, { Vpd, Qdq, Zz }, 0, s1W2R },
1766     { e_cvtsi2sd, t_done, 0, true, { Vsd, Ev, Zz }, 0, s1W2R },
1767   },
1768   { /* SSE2B */
1769     { e_movntps, t_done, 0, true, { Wps, Vps, Zz }, 0, s1W2R | (fNT << FPOS) },
1770     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1771     { e_movntpd, t_done, 0, true, { Wpd, Vpd, Zz }, 0, s1W2R | (fNT << FPOS) }, // bug in book
1772     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1773   },
1774   { /* SSE2C */
1775     { e_cvttps2pi, t_done, 0, true, { Qq, Wps, Zz }, 0, s1W2R },
1776     { e_cvttss2si, t_done, 0, true, { Gv, Wss, Zz }, 0, s1W2R },
1777     { e_cvttpd2pi, t_done, 0, true, { Qdq, Wpd, Zz }, 0, s1W2R },
1778     { e_cvttsd2si, t_done, 0, true, { Gv, Wsd, Zz }, 0, s1W2R },
1779   },
1780   { /* SSE2D */
1781     { e_cvtps2pi, t_done, 0, true, { Qq, Wps, Zz }, 0, s1W2R },
1782     { e_cvtss2si, t_done, 0, true, { Gv, Wss, Zz }, 0, s1W2R },
1783     { e_cvtpd2pi, t_done, 0, true, { Qdq, Wpd, Zz }, 0, s1W2R },
1784     { e_cvtsd2si, t_done, 0, true, { Gv, Wsd, Zz }, 0, s1W2R },
1785   },
1786   { /* SSE2E */
1787     { e_ucomiss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1R2R },
1788     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1789     { e_ucomisd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1R2R },
1790     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1791   },
1792   { /* SSE2F */
1793     { e_comiss, t_done, 0, true, { Vps, Wps, Zz }, 0, s1R2R },
1794     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1795     { e_comisd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1R2R },
1796     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1797   },
1798   { /* SSE50 */
1799     { e_movmskps, t_done, 0, true, { Ed, Vps, Zz }, 0, s1W2R },
1800     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1801     { e_movmskpd, t_done, 0, true, { Ed, Vpd, Zz }, 0, s1W2R },
1802     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1803   },
1804   { /* SSE51 */
1805     { e_sqrtps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
1806     { e_sqrtss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1W2R },
1807     { e_sqrtpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1W2R },
1808     { e_sqrtsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1W2R },
1809   },
1810   { /* SSE52 */
1811     { e_rsqrtps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
1812     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1813     { e_rsqrtss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1W2R },
1814     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1815   },
1816   { /* SSE53 */
1817     { e_rcpps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
1818     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1819     { e_rcpss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1W2R },
1820     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1821   },
1822   { /* SSE54 */
1823     { e_andps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1824     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1825     { e_andpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1826     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1827   },
1828   { /* SSE55 */
1829     { e_andnps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1830     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1831     { e_andnpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1832     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1833   },
1834   { /* SSE56 */
1835     { e_orps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1836     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1837     { e_orpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1838     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1839   },
1840   { /* SSE57 */
1841     { e_xorps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1842     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1843     { e_xorpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1844     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1845   },
1846   { /* SSE58 */
1847     { e_addps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1848     { e_addss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1849     { e_addpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1850     { e_addsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1851   },
1852   { /* SSE59 */
1853     { e_mulps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1854     { e_mulss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1855     { e_mulpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1856     { e_mulsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1857   },
1858   { /* SSE5A */
1859     { e_cvtps2pd, t_done, 0, true, { Vpd, Wps, Zz }, 0, s1W2R },
1860     { e_cvtss2sd, t_done, 0, true, { Vss, Wss, Zz }, 0, s1W2R },
1861     { e_cvtpd2ps, t_done, 0, true, { Vps, Wpd, Zz }, 0, s1W2R }, // FIXME: book bug ???
1862     { e_cvtsd2ss, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1W2R },
1863   },
1864   { /* SSE5B */
1865     { e_cvtdq2ps, t_done, 0, true, { Vps, Wdq, Zz }, 0, s1W2R },
1866     { e_cvttps2dq, t_done, 0, true, { Vdq, Wps, Zz }, 0, s1W2R }, // book has this/next swapped!!! 
1867     { e_cvtps2dq, t_done, 0, true, { Vdq, Wps, Zz }, 0, s1W2R },  // FIXME: book bug ???
1868     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1869   },
1870   { /* SSE5C */
1871     { e_subps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1872     { e_subss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1873     { e_subpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1874     { e_subsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1875   },
1876   { /* SSE5D */
1877     { e_minps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1878     { e_minss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1879     { e_minpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1880     { e_minsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1881   },
1882   { /* SSE5E */
1883     { e_divps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1884     { e_divss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1885     { e_divpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1886     { e_divsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1887   },
1888   { /* SSE5F */
1889     { e_maxps, t_done, 0, true, { Vps, Wps, Zz }, 0, s1RW2R },
1890     { e_maxss, t_done, 0, true, { Vss, Wss, Zz }, 0, s1RW2R },
1891     { e_maxpd, t_done, 0, true, { Vpd, Wpd, Zz }, 0, s1RW2R },
1892     { e_maxsd, t_done, 0, true, { Vsd, Wsd, Zz }, 0, s1RW2R },
1893   },
1894   { /* SSE60 */
1895     { e_punpcklbw, t_done, 0, true, { Pq, Qd, Zz }, 0, s1RW2R },
1896     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1897     { e_punpcklbw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1898     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1899   },
1900   { /* SSE61 */
1901     { e_punpcklwd, t_done, 0, true, { Pq, Qd, Zz }, 0, s1RW2R },
1902     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1903     { e_punpcklwd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1904     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1905   },
1906   { /* SSE62 */
1907     { e_punpcklqd, t_done, 0, true, { Pq, Qd, Zz }, 0, s1RW2R },
1908     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1909     { e_punpcklqd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1910     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1911   },
1912   { /* SSE63 */
1913     { e_packsswb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1914     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1915     { e_packsswb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1916     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1917   },
1918   { /* SSE64 */
1919     { e_pcmpgtb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
1920     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1921     { e_pcmpgtb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
1922     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1923   },
1924   { /* SSE65 */
1925     { e_pcmpgtw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
1926     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1927     { e_pcmpgtw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
1928     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1929   },
1930   { /* SSE66 */
1931     { e_pcmpgdt, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
1932     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1933     { e_pcmpgdt, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
1934     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1935   },
1936   { /* SSE67 */
1937     { e_packuswb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1938     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1939     { e_packuswb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1940     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1941   },
1942   { /* SSE68 */
1943     { e_punpckhbw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1944     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1945     { e_punpckhbw, t_done, 0, true, { Pdq, Qdq, Zz }, 0, s1RW2R },
1946     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1947   },
1948   { /* SSE69 */
1949     { e_punpckhwd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1950     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1951     { e_punpckhwd, t_done, 0, true, { Pdq, Qdq, Zz }, 0, s1RW2R },
1952     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1953   },
1954   { /* SSE6A */
1955     { e_punpckhdq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1956     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1957     { e_punpckhdq, t_done, 0, true, { Pdq, Qdq, Zz }, 0, s1RW2R },
1958     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1959   },
1960   { /* SSE6B */
1961     { e_packssdw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
1962     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1963     { e_packssdw, t_done, 0, true, { Pdq, Qdq, Zz }, 0, s1RW2R },
1964     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1965   },
1966   { /* SSE6C */
1967     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1968     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1969     { e_punpcklqld, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1970     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1971   },
1972   { /* SSE6D */
1973     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1974     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1975     { e_punpckhqd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
1976     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1977   },
1978   { /* SSE6E */
1979     { e_movd, t_done, 0, true, { Pd, Ev, Zz }, 0, s1W2R },
1980     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1981     { e_movd, t_done, 0, true, { Vdq, Ev, Zz }, 0, s1W2R },
1982     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1983   },
1984   { /* SSE6F */
1985     { e_movq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1W2R },
1986     { e_movdqu, t_done, 0, false, { Vdq, Wdq, Zz }, 0, s1W2R }, // book has this/next swapped!!!
1987     { e_movdqa, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1W2R },
1988     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1989   },
1990   { /* SSE70 */
1991     { e_pshufw, t_done, 0, true, { Pq, Qq, Ib }, 0, s1W2R3R },
1992     { e_pshufhw, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1W2R3R }, // book has this/next swapped!!!
1993     { e_pshufd, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1W2R3R },
1994     { e_pshuflw, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1W2R3R },
1995   },
1996   { /* SSE74 */
1997     { e_pcmpeqb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
1998     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
1999     { e_pcmpeqb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
2000     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2001   },
2002   { /* SSE75 */
2003     { e_pcmpeqw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
2004     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2005     { e_pcmpeqw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
2006     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2007   },
2008   { /* SSE76 */
2009     { e_pcmpeqd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1R2R },
2010     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2011     { e_pcmpeqd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1R2R },
2012     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2013   },
2014   { /* SSE7E */
2015     { e_movd, t_done, 0, true, { Ev, Pd, Zz }, 0, s1W2R },
2016     { e_movq, t_done, 0, true, { Vq, Wq, Zz }, 0, s1W2R }, // book has this and next swapped!!!
2017     { e_movd, t_done, 0, true, { Ev, Vdq, Zz }, 0, s1W2R },
2018     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2019   },
2020   { /* SSE7F */
2021     { e_movq, t_done, 0, true, { Qq, Pq, Zz }, 0, s1W2R },
2022     { e_movdqu, t_done, 0, true, { Wdq, Vdq, Zz }, 0, s1W2R }, // book has this and next swapped!!!
2023     { e_movdqa, t_done, 0, true, { Wdq, Vdq, Zz }, 0, s1W2R },
2024     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2025   },
2026   { /* SSEC2 */
2027     { e_cmpps, t_done, 0, true, { Vps, Wps, Ib }, 0, s1RW2R3R }, // comparison writes to dest!
2028     { e_cmpss, t_done, 0, true, { Vss, Wss, Ib }, 0, s1RW2R3R },
2029     { e_cmppd, t_done, 0, true, { Vpd, Wpd, Ib }, 0, s1RW2R3R },
2030     { e_cmpsd, t_done, 0, true, { Vsd, Wsd, Ib }, 0, s1RW2R3R },
2031   },
2032   { /* SSEC4 */
2033     { e_pinsrw, t_done, 0, true, { Pq, Ed, Ib }, 0, s1RW2R3R },
2034     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2035     { e_pinsrw, t_done, 0, true, { Vdq, Ed, Ib }, 0, s1RW2R3R },
2036     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2037   },
2038   { /* SSEC5 */
2039     { e_pextrw, t_done, 0, true, { Gd, Pq, Ib }, 0, s1W2R3R },
2040     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2041     { e_pextrw, t_done, 0, true, { Gd, Vdq, Ib }, 0, s1W2R3R },
2042     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2043   },
2044   { /* SSEC6 */
2045     { e_shufps, t_done, 0, true, { Vps, Wps, Ib }, 0, s1RW2R3R },
2046     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2047     { e_shufpd, t_done, 0, true, { Vpd, Wpd, Ib }, 0, s1RW2R3R },
2048     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2049   },
2050   { /* SSED1 */
2051     { e_psrlw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2052     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2053     { e_psrlw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2054     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2055   },
2056   { /* SSED2 */
2057     { e_psrld, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2058     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2059     { e_psrld, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2060     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2061   },
2062   { /* SSED3 */
2063     { e_psrlq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2064     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2065     { e_psrlq, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2066     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2067   },
2068   { /* SSED4 */
2069     { e_paddq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2070     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2071     { e_paddq, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2072     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2073   },
2074   { /* SSED5 */
2075     { e_pmullw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2076     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2077     { e_pmullw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2078     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2079   },
2080   { /* SSED6 */
2081     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2082     { e_movq2dq, t_done, 0, true, { Vdq, Qq, Zz }, 0, s1W2R }, // lines jumbled in book
2083     { e_movq, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R },
2084     { e_movdq2q, t_done, 0, true, { Pq, Wq, Zz }, 0, s1W2R },
2085   },
2086   { /* SSED7 */
2087     { e_pmovmskb, t_done, 0, true, { Gd, Pq, Zz }, 0, s1W2R },
2088     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2089     { e_pmovmskb, t_done, 0, true, { Gd, Vdq, Zz }, 0, s1W2R },
2090     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2091   },
2092   { /* SSED8 */
2093     { e_psubusb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2094     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2095     { e_psubusb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2096     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2097   },
2098   { /* SSED9 */
2099     { e_psubusw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2100     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2101     { e_psubusw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2102     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2103   },
2104   { /* SSEDA */
2105     { e_pminub, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2106     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2107     { e_pminub, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2108     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2109   },
2110   { /* SSEDB */
2111     { e_pand, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2112     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2113     { e_pand, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2114     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2115   },
2116   { /* SSEDC */
2117     { e_paddusb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2118     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2119     { e_paddusb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2120     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2121   },
2122   { /* SSEDD */
2123     { e_paddusw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2124     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2125     { e_paddusw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2126     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2127   },
2128   { /* SSEDE */
2129     { e_pmaxub, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2130     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2131     { e_pmaxub, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2132     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2133   },
2134   { /* SSEDF */
2135     { e_pandn, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2136     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2137     { e_pandn, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2138     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2139   },
2140   { /* SSEE0 */
2141     { e_pavgb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2142     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2143     { e_pavgb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2144     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2145   },
2146   { /* SSEE1 */
2147     { e_psraw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2148     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2149     { e_psraw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2150     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2151   },
2152   { /* SSEE2 */
2153     { e_psrad, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2154     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2155     { e_psrad, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2156     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2157   },
2158   { /* SSEE3 */
2159     { e_pavgw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2160     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2161     { e_pavgw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2162     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2163   },
2164   { /* SSEE4 */
2165     { e_pmulhuw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2166     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2167     { e_pmulhuw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2168     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2169   },
2170   { /* SSEE5 */
2171     { e_pmulhw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2172     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2173     { e_pmulhw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2174     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2175   },
2176   { /* SSEE6 */
2177     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2178     { e_cvtdq2pd, t_done, 0, true, { Vpd, Wdq, Zz }, 0, s1W2R }, // lines jumbled in book
2179     { e_cvttpd2dq, t_done, 0, true, { Vdq, Wpd, Zz }, 0, s1W2R },
2180     { e_cvtpd2dq, t_done, 0, true, { Vdq, Wpd, Zz }, 0, s1W2R },
2181   },
2182   { /* SSEE7 */
2183     { e_movntq, t_done, 0, true, { Wq, Vq, Zz }, 0, s1W2R | (fNT << FPOS) },
2184     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2185     { e_movntdq, t_done, 0, true, { Wdq, Vdq, Zz }, 0, s1W2R | (fNT << FPOS) },
2186     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2187   },
2188   { /* SSEE8 */
2189     { e_psubsb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2190     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2191     { e_psubsb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2192     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2193   },
2194   { /* SSEE9 */
2195     { e_psubsw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2196     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2197     { e_psubsw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2198     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2199   },
2200   { /* SSEEA */
2201     { e_pminsw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2202     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2203     { e_pminsw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2204     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2205   },
2206   { /* SSEEB */
2207     { e_por, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2208     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2209     { e_por, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2210     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2211   },
2212   { /* SSEEC */
2213     { e_paddsb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2214     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2215     { e_paddsb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2216     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2217   },
2218   { /* SSEED */
2219     { e_paddsw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2220     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2221     { e_paddsw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2222     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2223   },
2224   { /* SSEEE */
2225     { e_pmaxsw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2226     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2227     { e_pmaxsw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2228     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2229   },
2230   { /* SSEEF */
2231     { e_pxor, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2232     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2233     { e_pxor, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2234     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2235   },
2236   { /* SSEF1 */
2237     { e_psllw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2238     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2239     { e_psllw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2240     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2241   },
2242   { /* SSEF2 */
2243     { e_pslld, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2244     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2245     { e_pslld, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2246     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2247   },
2248   { /* SSEF3 */
2249     { e_psllq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2250     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2251     { e_psllq, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2252     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2253   },
2254   { /* SSEF4 */
2255     { e_pmuludq, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2256     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2257     { e_pmuludq, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2258     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2259   },
2260   { /* SSEF5 */
2261     { e_pmaddwd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2262     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2263     { e_pmaddwd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2264     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2265   },
2266   { /* SSEF6 */
2267     { e_psadbw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2268     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2269     { e_psadbw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2270     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2271   },
2272   { /* SSEF7 */
2273     { e_maskmovq, t_done, 0, true, { Ppi, Qpi, Zz }, 0, s1W2R | (fNT << FPOS) },
2274     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2275     { e_maskmovdqu, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1W2R | (fNT << FPOS) }, // bug in book
2276     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2277   },
2278   { /* SSEF8 */
2279     { e_psubb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2280     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2281     { e_psubb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2282     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2283   },
2284   { /* SSEF9 */
2285     { e_psubw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2286     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2287     { e_psubw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2288     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2289   },
2290   { /* SSEFA */
2291     { e_psubd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2292     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2293     { e_psubd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2294     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2295   },
2296   { /* SSEFB */ // FIXME: Same????
2297     { e_psubd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2298     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2299     { e_psubd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2300     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2301   },
2302   { /* SSEFC */
2303     { e_paddb, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2304     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2305     { e_paddb, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2306     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2307   },
2308   { /* SSEFD */
2309     { e_paddw, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2310     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2311     { e_paddw, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2312     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2313   },
2314   { /* SSEFE */
2315     { e_paddd, t_done, 0, true, { Pq, Qq, Zz }, 0, s1RW2R },
2316     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2317     { e_paddd, t_done, 0, true, { Vdq, Wdq, Zz }, 0, s1RW2R },
2318     { e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
2319   }
2320 };
2321
2322 /* rows are none or 66 prefixed in this order (see book) */
2323 static ia32_entry ssegrpMap[][2] = {
2324   /* G12SSE010B */
2325   {
2326     { e_psrlw, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2327     { e_psrlw, t_done, 0, true, { Pdq, Ib, Zz }, 0, s1RW2R }
2328   },
2329   /* G12SSE100B */
2330   {
2331     { e_psraw, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2332     { e_psraw, t_done, 0, true, { Pdq, Ib, Zz }, 0, s1RW2R }
2333   },
2334   /* G12SSE110B */
2335   {
2336     { e_psllw, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2337     { e_psllw, t_done, 0, true, { Pdq, Ib, Zz }, 0, s1RW2R }
2338   },
2339   /* G13SSE010B */
2340   {
2341     { e_psrld, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2342     { e_psrld, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2343   },
2344   /* G13SSE100B */
2345   {
2346     { e_psrad, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2347     { e_psrad, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2348   },
2349   /* G13SSE110B */
2350   {
2351     { e_pslld, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2352     { e_pslld, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2353   },
2354   /* G14SSE010B */
2355   {
2356     { e_psrlq, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2357     { e_psrlq, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2358   },
2359   /* G14SSE011B */
2360   {
2361     { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
2362     { e_psrldq, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2363   },
2364   /* G14SSE110B */
2365   {
2366     { e_psllq, t_done, 0, true, { Pq, Ib, Zz }, 0, s1RW2R },
2367     { e_psllq, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2368   },
2369   /* G14SSE111B */
2370   {
2371     { e_No_Entry, t_ill, 0, true, { Zz, Zz, Zz }, 0, 0 },
2372     { e_pslldq, t_done, 0, true, { Wdq, Ib, Zz }, 0, s1RW2R }
2373   }
2374 };
2375
2376 static bool mode_64 = false;
2377
2378 void ia32_set_mode_64(bool mode) {
2379   mode_64 = mode;
2380 }
2381
2382 bool ia32_is_mode_64() {
2383   return mode_64;
2384 }
2385
2386 ia32_entry movsxd = { e_movsxd, t_done, 0, true, { Gv, Ed, Zz }, 0, s1W2R };
2387
2388 static void ia32_translate_for_64(ia32_entry** gotit_ptr)
2389 {
2390     if (*gotit_ptr == &oneByteMap[0x63]) // APRL redefined to MOVSXD
2391         *gotit_ptr = &movsxd;
2392 }
2393
2394 /* full decoding version: supports memory access information */
2395 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr,
2396                                       const unsigned char* addr,
2397                                       ia32_memacc* macadr,
2398                                       const ia32_prefixes* pref,
2399                                       ia32_locations *pos);
2400
2401 /* shortcut version: just decodes instruction size info */
2402 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr,
2403                                       const unsigned char* addr)
2404 {
2405     return ia32_decode_modrm(addrSzAttr, addr, NULL, NULL, NULL);
2406 }
2407
2408 void ia32_memacc::print()
2409 {
2410     fprintf(stderr, "base: %d, index: %d, scale:%d, disp: %ld (%lx), size: %d, addr_size: %d\n",
2411             regs[0], regs[1], scale, imm, imm, size, addr_size);
2412 }
2413
2414
2415 ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32_instruction& instruct)
2416 {
2417   ia32_prefixes& pref = instruct.prf;
2418   unsigned int table, nxtab;
2419   unsigned int idx, sseidx = 0;
2420   ia32_entry *gotit = NULL;
2421   int condbits = 0;
2422
2423   if(capa & IA32_DECODE_MEMACCESS)
2424     assert(instruct.mac != NULL);
2425
2426   if (!ia32_decode_prefixes(addr, pref, instruct.loc)) {
2427     instruct.size = 1;
2428     instruct.legacy_type = ILLEGAL;
2429     return instruct;
2430   }
2431
2432   if (instruct.loc) instruct.loc->num_prefixes = pref.getCount();
2433   instruct.size = pref.getCount();
2434   addr += instruct.size;
2435
2436   table = t_oneB;
2437   idx = addr[0];
2438   gotit = &oneByteMap[idx];
2439   nxtab = gotit->otable;
2440   instruct.size += 1;
2441   addr += 1;
2442
2443   if(capa & IA32_DECODE_CONDITION) {
2444     assert(instruct.cond != NULL);
2445     condbits = idx & 0x0F;
2446   }
2447
2448   while(nxtab != t_done) {
2449     table = nxtab;
2450     switch(table) {
2451     case t_twoB:
2452       idx = addr[0];
2453       gotit = &twoByteMap[idx];
2454       nxtab = gotit->otable;
2455       instruct.size += 1;
2456       addr += 1;
2457       if(capa & IA32_DECODE_CONDITION)
2458         condbits = idx & 0x0F;
2459       break;
2460     case t_prefixedSSE:
2461       sseidx = gotit->tabidx;
2462       assert(addr[0] == 0x0F);
2463       idx = addr[1];
2464       gotit = &twoByteMap[idx];
2465       nxtab = gotit->otable;
2466       instruct.size += 2;
2467       addr += 2;
2468       break;
2469     case t_sse:
2470       idx = gotit->tabidx;
2471       gotit = &sseMap[idx][sseidx];
2472       nxtab = gotit->otable;
2473       break;
2474     case t_grp: {
2475       idx = gotit->tabidx;
2476       unsigned int reg  = (addr[0] >> 3) & 7;
2477       if(idx < Grp12)
2478         switch(idx) {
2479         case Grp2:
2480         case Grp11:
2481           // leave table unchanged because operands are in not defined in group map
2482           nxtab = groupMap[idx][reg].otable;
2483           assert(nxtab==t_done || nxtab==t_ill);
2484           break;
2485         default:
2486           gotit = &groupMap[idx][reg];
2487           nxtab = gotit->otable;
2488         }
2489       else {
2490         unsigned int mod = addr[0] >> 6;
2491         gotit = &groupMap2[idx-Grp12][mod==3][reg];
2492         nxtab = gotit->otable;
2493       }
2494       break;
2495     }
2496     case t_grpsse:
2497       sseidx >>= 1;
2498       idx = gotit->tabidx;
2499       gotit = &ssegrpMap[idx][sseidx];
2500       nxtab = gotit->otable;
2501       break;
2502     case t_coprocEsc:
2503       instruct.legacy_type = 0;
2504           if(capa & IA32_DECODE_CONDITION) {
2505         ; // FIXME: translation to tttn & set it
2506           }
2507       instruct = ia32_decode_FP(idx, pref, addr, instruct, gotit, instruct.mac);
2508       return instruct;
2509     case t_3dnow:
2510       // 3D now opcodes are given as suffix: ModRM [SIB] [displacement] opcode
2511       // Right now we don't care what the actual opcode is, so there's no table
2512       instruct.size += 1;
2513       nxtab = t_done;
2514       break;
2515     case t_ill:
2516       instruct.legacy_type = ILLEGAL;
2517       return instruct;
2518     default:
2519       assert(!"wrong table");
2520     }
2521   }
2522
2523   assert(gotit != NULL);
2524   instruct.legacy_type = gotit->legacyType;
2525
2526   // addr points after the opcode, and the size has been adjusted accordingly
2527   if (instruct.loc) instruct.loc->opcode_size = instruct.size - pref.getCount();
2528   if (instruct.loc) instruct.loc->opcode_position = pref.getCount();
2529
2530   // make adjustments for instruction redefined in 64-bit mode
2531   if (mode_64)
2532     ia32_translate_for_64(&gotit);
2533
2534   ia32_decode_operands(pref, *gotit, addr, instruct, instruct.mac); // all but FP
2535
2536   if(capa & IA32_DECODE_MEMACCESS) {
2537     int sema = gotit->opsema & ((1<<FPOS)-1);
2538     int hack = gotit->opsema >> FPOS;
2539     switch(sema) {
2540     case sNONE:
2541       break;
2542     case s1R:
2543       switch(hack) {
2544       case fPREFETCHNT:
2545         instruct.mac[0].prefetch = true;
2546         instruct.mac[0].prefetchlvl = 0;
2547         break;
2548       case fPREFETCHT0:
2549         instruct.mac[0].prefetch = true;
2550         instruct.mac[0].prefetchlvl = 1;
2551         break;
2552       case fPREFETCHT1:
2553         instruct.mac[0].prefetch = true;
2554         instruct.mac[0].prefetchlvl = 2;
2555         break;
2556       case fPREFETCHT2:
2557         instruct.mac[0].prefetch = true;
2558         instruct.mac[0].prefetchlvl = 3;
2559         break;
2560       case fPREFETCHAMDE:
2561         instruct.mac[0].prefetch = true;
2562         instruct.mac[0].prefetchstt = 0;
2563         break;
2564       case fPREFETCHAMDW:
2565         instruct.mac[0].prefetch = true;
2566         instruct.mac[0].prefetchstt = 1;
2567         break;
2568       default:
2569         instruct.mac[0].read = true;
2570       }
2571       break;
2572     case s1W:
2573       instruct.mac[0].write = true;
2574       break;
2575     case s1RW:
2576       instruct.mac[0].read = true;
2577       instruct.mac[0].write = true;
2578       instruct.mac[0].nt = hack == fNT;
2579       break;
2580     case s1R2R:
2581       instruct.mac[0].read = true;
2582       instruct.mac[1].read = true;
2583       break;
2584     case s1W2R:
2585       instruct.mac[0].write = true;
2586       instruct.mac[0].nt = hack == fNT; // all NTs are s1W2R
2587       instruct.mac[1].read = true;
2588       break;
2589     case s1RW2R:
2590       instruct.mac[0].read = true;
2591       instruct.mac[0].write = true;
2592       instruct.mac[1].read = true;
2593       break;
2594     case s1RW2RW:
2595       instruct.mac[0].read = true;
2596       instruct.mac[0].write = true;
2597       instruct.mac[1].read = true;
2598       instruct.mac[1].write = true;
2599       break;
2600     case s1W2R3R:
2601       instruct.mac[0].write = true;
2602       instruct.mac[1].read = true;
2603       instruct.mac[2].read = true;
2604       break;
2605     case s1W2W3R:
2606       instruct.mac[0].write = true;
2607       instruct.mac[1].write = true;
2608       instruct.mac[2].read = true;
2609       break;
2610     case s1W2RW3R:
2611       instruct.mac[0].write = true;
2612       instruct.mac[1].read = true;
2613       instruct.mac[1].write = true;
2614       instruct.mac[2].read = true;
2615       break;
2616     case s1W2R3RW:
2617       instruct.mac[0].write = true;
2618       instruct.mac[1].read = true;
2619       instruct.mac[2].read = true;
2620       instruct.mac[2].write = true;
2621       break;
2622     case s1RW2R3R:
2623       instruct.mac[0].read = true;
2624       instruct.mac[0].write = true;
2625       instruct.mac[1].read = true;
2626       instruct.mac[2].read = true;
2627       break;
2628     case s1RW2RW3R:
2629       instruct.mac[0].write = true;
2630       instruct.mac[0].read = true;
2631       instruct.mac[1].read = true;
2632       instruct.mac[1].write = true;
2633       instruct.mac[2].read = true;
2634       break;
2635     }
2636
2637     switch(pref.getPrefix(0)) {
2638     case PREFIX_REPNZ:
2639       switch(hack) {
2640       case fSCAS:
2641         instruct.mac[1].sizehack = shREPNESCAS;
2642         break;
2643       case fCMPS:
2644         instruct.mac[0].sizehack = shREPNECMPS;
2645         instruct.mac[1].sizehack = shREPNECMPS;
2646         break;
2647       default:
2648         bperr( "IA32 DECODER: unexpected repnz prefix ignored...\n");
2649       }
2650       break;
2651     case PREFIX_REP:
2652       switch(hack) {
2653       case fSCAS:
2654         instruct.mac[1].sizehack = shREPESCAS;
2655         break;
2656       case fCMPS:
2657         instruct.mac[0].sizehack = shREPECMPS;
2658         instruct.mac[1].sizehack = shREPECMPS;
2659         break;
2660       case fREP:
2661         instruct.mac[0].sizehack = shREP;
2662         instruct.mac[1].sizehack = shREP;
2663         break;
2664       default:
2665         bperr( "IA32 DECODER: unexpected rep prefix ignored...\n");
2666       }
2667       break;
2668     case 0:
2669     case PREFIX_LOCK:
2670       break;
2671     default:
2672       bperr( "IA32 WARNING: unknown type 0 prefix!\n");
2673       break;
2674     }
2675
2676 #if 0
2677     // debug output for memory access decoding
2678     for (int i = 0; i < 3; i++) {
2679         if (instruct.mac[i].is) {
2680             fprintf(stderr, "%d)", i);
2681             if (instruct.mac[i].read)
2682                 fprintf(stderr, " read");
2683             if (instruct.mac[i].write)
2684                 fprintf(stderr, " write");
2685             if (instruct.mac[i].nt)
2686                 fprintf(stderr, " nt");
2687             if (instruct.mac[i].sizehack)
2688                 fprintf(stderr, " sizehack");
2689             fprintf(stderr, "\n");
2690             instruct.mac[i].print();
2691         }
2692     }
2693 #endif
2694
2695   }
2696
2697
2698   if(capa & IA32_DECODE_CONDITION) {
2699     int hack = gotit->opsema >> FPOS;
2700     if(hack == fCOND)
2701       instruct.cond->set(condbits);
2702   }
2703
2704   instruct.entry = gotit;
2705   return instruct;
2706 }
2707
2708 ia32_instruction& ia32_decode_FP(unsigned int opcode, const ia32_prefixes& pref,
2709                                  const unsigned char* addr, ia32_instruction& instruct,
2710                                  ia32_entry * entry, ia32_memacc *mac)
2711 {
2712   unsigned int nib = byteSzB; // modRM
2713   unsigned int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2); // 32-bit mode implicit
2714   unsigned int operSzAttr = (pref.getPrefix(2) == PREFIX_SZOPER ? 1 : 2); // 32-bit mode implicit
2715
2716   if (addr[0] <= 0xBF) { // modrm
2717     if (instruct.loc) {
2718        instruct.loc->modrm_position = instruct.loc->opcode_position +
2719           instruct.loc->opcode_size;
2720        instruct.loc->modrm_operand = 0;
2721     }
2722     nib += ia32_decode_modrm(addrSzAttr, addr, mac, &pref, instruct.loc);
2723     // also need to check for AMD64 rip-relative data addressing
2724     // occurs when mod == 0 and r/m == 101
2725     if (mode_64)
2726        if ((addr[0] & 0xc7) == 0x05)
2727           instruct.rip_relative_data = true;
2728     // operand size has to be determined from opcode
2729     if(mac)
2730       {
2731         switch(opcode) {
2732         case 0xD8: // all single real
2733           mac->size = 4;
2734           mac->read = true;
2735           break;
2736         case 0xD9: {
2737           unsigned char modrm = addr[0];
2738           unsigned char reg = (modrm >> 3) & 7;
2739           switch(reg) {
2740           case 0:
2741             mac->size = 4;
2742             mac->read = true;
2743             break;
2744           case 2:
2745           case 3:
2746             mac->size = 4;
2747             mac->write = true;
2748             break;
2749           case 1:
2750             instruct.legacy_type = ILLEGAL;
2751             break;
2752           case 4:
2753             mac->size = 14 * operSzAttr;
2754             mac->read = true;
2755             break;
2756           case 5:
2757             mac->read = true;
2758             mac->size = 2;
2759             break;
2760           case 6:
2761             mac->size = 14 * operSzAttr;
2762             mac->write = true;
2763             break;
2764           case 7:
2765             mac->write = true;
2766             mac->size = 2;
2767             break;
2768           }
2769           break; }
2770         case 0xDA:  // all double real
2771           mac->size = 8;
2772           mac->read = true;
2773           break;
2774         case 0xDB: {
2775           unsigned char modrm = addr[0];
2776           unsigned char reg = (modrm >> 3) & 7;
2777           switch(reg) {
2778           case 0:
2779             mac->size = dwordSzB;
2780             mac->read = true;
2781             break;
2782           case 2:
2783           case 3:
2784             mac->size = dwordSzB;
2785             mac->write = true;
2786             break;
2787           case 1:
2788           case 4:
2789           case 6:
2790             instruct.legacy_type = ILLEGAL;
2791             break;
2792           case 5:
2793             mac->size = 10; // extended real
2794             mac->read = true;
2795             break;
2796           case 7:
2797             mac->size = 10; // extended real
2798             mac->write = true;
2799             break;
2800           }
2801           break; }
2802         case 0xDC:   // all double real
2803           mac->size = 8;
2804           mac->read = true;
2805           break;
2806         case 0xDD: {
2807           unsigned char modrm = addr[0];
2808           unsigned char reg = (modrm >> 3) & 7;
2809           switch(reg) {
2810           case 0:
2811             mac->size = 8;
2812             mac->read = true;
2813             break;
2814           case 2:
2815           case 3:
2816             mac->size = 8;
2817             mac->write = true;
2818             break;
2819           case 1:
2820           case 5:
2821             instruct.legacy_type = ILLEGAL;
2822             break;
2823           case 4:
2824             mac->size = operSzAttr == 2 ? 108 : 98;
2825             mac->read = true;
2826             break;
2827           case 6:
2828             mac->size = operSzAttr == 2 ? 108 : 98;
2829             mac->write = true;
2830             break;
2831           case 7:
2832             mac->size = 2;
2833             mac->write = true;
2834             break;    
2835           }
2836           break; }
2837         case 0xDE: // all word integer
2838           mac->size = wordSzB;
2839           mac->write = true;
2840           break;
2841         case 0xDF: {
2842           unsigned char modrm = addr[0];
2843           unsigned char reg = (modrm >> 3) & 7;
2844           switch(reg) {
2845           case 0:
2846             mac->size = wordSzB;
2847             mac->read = true;
2848             break;
2849           case 2:
2850           case 3:
2851             mac->size = wordSzB;
2852             mac->write = true;
2853             break;
2854           case 1:
2855             instruct.legacy_type = ILLEGAL;
2856             break;
2857           case 4:
2858             mac->size = 10;
2859             mac->read = true;
2860             break;
2861           case 5:
2862             mac->size = 8;
2863             mac->read = true;
2864             break;
2865           case 6:
2866             mac->size = 10;
2867             mac->write = true;
2868             break;
2869           case 7:
2870             mac->size = 8;
2871             mac->write = true;
2872             break;
2873           }
2874           break; }
2875         } // switch(opcode) 
2876       } // if mac
2877   } // if modrm
2878   
2879   instruct.size += nib;
2880   instruct.entry = entry;
2881   
2882   return instruct;
2883 }
2884
2885 #define MODRM_MOD(x) ((x) >> 6)
2886 #define MODRM_RM(x) ((x) & 7)
2887 #define MODRM_REG(x) (((x) & (7 << 3)) >> 3)
2888 #define MODRM_SET_MOD(x, y) ((x) |= ((y) << 6))
2889 #define MODRM_SET_RM(x, y) ((x) |= (y))
2890 #define MODRM_SET_REG(x, y) ((x) |= ((y) << 3))
2891
2892 static unsigned int ia32_decode_modrm(const unsigned int addrSzAttr,
2893                                       const unsigned char* addr,
2894                                       ia32_memacc* macadr,
2895                                       const ia32_prefixes* pref,
2896                                       ia32_locations *loc)
2897 {
2898  
2899   unsigned char modrm = addr[0];
2900   unsigned char mod = MODRM_MOD(modrm);
2901   unsigned char rm  = MODRM_RM(modrm);
2902   unsigned char reg = MODRM_REG(modrm);
2903   if (loc) {
2904      loc->modrm_byte = modrm;
2905      loc->modrm_mod = mod;
2906      loc->modrm_rm = rm;
2907      loc->modrm_reg = reg;
2908      loc->address_size = addrSzAttr;
2909   }
2910   ++addr;
2911
2912   if(addrSzAttr == 1) { // 16-bit, cannot have SIB
2913     //bperr( "16bit addr!\n");
2914     switch(mod) {
2915     case 0:
2916       //bperr( "16bit addr - case 0, rm = %d!\n", rm);
2917       if(macadr)
2918         switch (rm) {
2919         case 0: // [BX+SI]
2920           macadr->set16(mBX, mSI, 0);
2921           break;
2922         case 1:
2923           macadr->set16(mBX, mDI, 0);
2924           break;
2925         case 2:
2926           macadr->set16(mBP, mSI, 0);
2927           break;
2928         case 3:
2929           macadr->set16(mBP, mDI, 0);
2930           break;
2931         case 4:
2932           macadr->set16(mSI, -1, 0);
2933           break;
2934         case 5:
2935           macadr->set16(mDI, -1, 0);
2936           break;
2937         case 6: { 
2938            // disp16
2939            const short int *pdisp16 = (const short int*)addr;
2940            //bperr( "16bit addr - case6!\n");
2941            macadr->set16(-1, -1, *pdisp16);
2942            if (loc) { 
2943               loc->disp_position = loc->modrm_position + 1;
2944               loc->disp_size = 2;
2945            }
2946            break; 
2947         }
2948         case 7:
2949           macadr->set16(mBX, -1, 0);
2950           break;
2951         }
2952       return rm==6 ? wordSzB : 0;
2953     case 1:
2954       //bperr( "16bit addr - case1!\n");
2955       if(macadr) {
2956         const char *pdisp8 = (const char*)addr;
2957         if (loc) { 
2958            loc->disp_position = loc->modrm_position + 1;
2959            loc->disp_size = 1;
2960         }
2961         switch (rm) {
2962         case 0: 
2963           macadr->set16(mBX, mSI, *pdisp8);
2964           break;
2965         case 1:
2966           macadr->set16(mBX, mDI, *pdisp8);
2967           break;
2968         case 2:
2969           macadr->set16(mBP, mSI, *pdisp8);
2970           break;
2971         case 3:
2972           macadr->set16(mBP, mDI, *pdisp8);
2973           break;
2974         case 4:
2975           macadr->set16(mSI, -1, *pdisp8);
2976           break;
2977         case 5:
2978           macadr->set16(mDI, -1, *pdisp8);
2979           break;
2980         case 6:
2981           macadr->set16(mBP, -1, *pdisp8);
2982           break;
2983         case 7:
2984           macadr->set16(mBX, -1, *pdisp8);
2985           break;
2986         }
2987       }
2988       return byteSzB;
2989     case 2:
2990       //bperr( "16bit addr - case2!\n");
2991       if(macadr) {
2992         const short int *pdisp16 = (const short int*)addr;
2993         if (loc) { 
2994            loc->disp_position = loc->modrm_position + 1;
2995            loc->disp_size = 2;
2996         }
2997         switch (rm) {
2998         case 0: 
2999           macadr->set16(mBX, mSI, *pdisp16);
3000           break;
3001         case 1:
3002           macadr->set16(mBX, mDI, *pdisp16);
3003           break;
3004         case 2:
3005           macadr->set16(mBP, mSI, *pdisp16);
3006           break;
3007         case 3:
3008           macadr->set16(mBP, mDI, *pdisp16);
3009           break;
3010         case 4:
3011           macadr->set16(mSI, -1, *pdisp16);
3012           break;
3013         case 5:
3014           macadr->set16(mDI, -1, *pdisp16);
3015           break;
3016         case 6:
3017           macadr->set16(mBP, -1, *pdisp16);
3018           break;
3019         case 7:
3020           macadr->set16(mBX, -1, *pdisp16);
3021           break;
3022         }
3023       }
3024
3025       return wordSzB;
3026     case 3:
3027       return 0; // register
3028     default:
3029       assert(0);
3030     }
3031   }
3032   else { // 32-bit or 64-bit, may have SIB
3033     if(mod == 3)
3034       return 0; // only registers, no SIB
3035     bool hassib = rm == 4;
3036     unsigned int nsib = 0;
3037     unsigned char sib;
3038     int base = 0, scale = -1, index = -1;  // prevent g++ from whining.
3039     if(hassib) {
3040       nsib = byteSzB;
3041       sib = addr[0];
3042       if (loc) { 
3043          loc->sib_position = loc->modrm_position + 1;
3044          loc->sib_byte = sib;
3045       }
3046       ++addr;
3047       base = sib & 7;
3048       if(macadr) {
3049         scale = sib >> 6;
3050         index = (sib >> 3) & 7;
3051
3052         // stack pointer can't be used as an index - supports base-only addressing w/ SIB
3053         if(index == 4 && !pref->rexX())
3054           index = -1;
3055       }
3056     }
3057     switch(mod) {
3058     case 0: {
3059       /* this is tricky: there is a disp32 iff (1) rm == 5  or  (2) hassib && base == 5 */
3060       unsigned char check5 = hassib ? base : rm;
3061       if(macadr)
3062         switch (rm) {
3063         case 0:
3064           macadr->set(apply_rex_bit(mEAX, pref->rexB()), 0, addrSzAttr);
3065           break;
3066         case 1:
3067           macadr->set(apply_rex_bit(mECX, pref->rexB()), 0, addrSzAttr);
3068           break;
3069         case 2:
3070           macadr->set(apply_rex_bit(mEDX, pref->rexB()), 0, addrSzAttr);
3071           break;
3072         case 3:
3073           macadr->set(apply_rex_bit(mEBX, pref->rexB()), 0, addrSzAttr);
3074           break;
3075         case 4: // SIB
3076           if(base == 5) 
3077           { 
3078              // disp32[index<<scale]
3079              const int *pdisp32 = (const int*)addr;
3080              if (loc) { 
3081                 loc->disp_position = loc->sib_position + 1;
3082                 loc->disp_size = 4;
3083              }
3084              macadr->set_sib(-1, scale, apply_rex_bit(index, pref->rexX()), 
3085                              *pdisp32, addrSzAttr);
3086           }
3087           else
3088             macadr->set_sib(apply_rex_bit(base, pref->rexB()), scale, 
3089                             apply_rex_bit(index, pref->rexX()),
3090                             0, addrSzAttr);
3091           break;
3092         case 5: { 
3093            // disp32 (or [RIP + disp32] for 64-bit mode)
3094            if (loc) { 
3095               loc->disp_position = loc->modrm_position + 1;
3096               loc->disp_size = 4;
3097            }
3098            const int *pdisp32 = (const int*)addr;
3099            if (mode_64)
3100               macadr->set(mRIP, *pdisp32, addrSzAttr);
3101            else
3102               macadr->set(-1, *pdisp32, addrSzAttr);
3103            break; 
3104         }
3105         case 6:
3106            macadr->set(apply_rex_bit(mESI, pref->rexB()), 0, addrSzAttr);
3107            break;
3108         case 7:
3109            macadr->set(apply_rex_bit(mEDI, pref->rexB()), 0, addrSzAttr);
3110            break;
3111       }
3112       return nsib + ((check5 == 5) ? dwordSzB : 0);
3113     }
3114     case 1:
3115       if(macadr) {
3116         const char *pdisp8 = (const char*)addr;
3117         switch (rm) {
3118         case 0:
3119           macadr->set(apply_rex_bit(mEAX, pref->rexB()), *pdisp8, addrSzAttr);
3120           break;
3121         case 1:
3122           macadr->set(apply_rex_bit(mECX, pref->rexB()), *pdisp8, addrSzAttr);
3123           break;
3124         case 2:
3125           macadr->set(apply_rex_bit(mEDX, pref->rexB()), *pdisp8, addrSzAttr);
3126           break;
3127         case 3:
3128           macadr->set(apply_rex_bit(mEBX, pref->rexB()), *pdisp8, addrSzAttr);
3129           break;
3130         case 4:
3131           // disp8[EBP + index<<scale] happens naturally here when base=5
3132            if (loc) { 
3133               loc->disp_position = loc->sib_position + 1;
3134               loc->disp_size = 1;
3135            }           
3136           macadr->set_sib(apply_rex_bit(base, pref->rexB()), scale, apply_rex_bit(index, pref->rexX()),
3137                           *pdisp8, addrSzAttr);
3138           break;
3139         case 5:
3140           macadr->set(apply_rex_bit(mEBP, pref->rexB()), *pdisp8, addrSzAttr);
3141           break;
3142         case 6:
3143           macadr->set(apply_rex_bit(mESI, pref->rexB()), *pdisp8, addrSzAttr);
3144           break;
3145         case 7:
3146           macadr->set(apply_rex_bit(mEDI, pref->rexB()), *pdisp8, addrSzAttr);
3147           break;
3148         }
3149       }
3150       return nsib + byteSzB;
3151     case 2:
3152       if(macadr) {
3153         const int *pdisp32 = (const int*)addr;
3154         switch (rm) {
3155         case 0:
3156           macadr->set(apply_rex_bit(mEAX, pref->rexB()), *pdisp32, addrSzAttr);
3157           break;
3158         case 1:
3159           macadr->set(apply_rex_bit(mECX, pref->rexB()), *pdisp32, addrSzAttr);
3160           break;
3161         case 2:
3162           macadr->set(apply_rex_bit(mEDX, pref->rexB()), *pdisp32, addrSzAttr);
3163           break;
3164         case 3:
3165           macadr->set(apply_rex_bit(mEBX, pref->rexB()), *pdisp32, addrSzAttr);
3166           break;
3167         case 4:
3168           // disp32[EBP + index<<scale] happens naturally here when base=5
3169            if (loc) { 
3170               loc->disp_position = loc->sib_position + 1;
3171               loc->disp_size = 4;
3172            }
3173           macadr->set_sib(apply_rex_bit(base, pref->rexB()), scale, apply_rex_bit(index, pref->rexX()),
3174                           *pdisp32, addrSzAttr);
3175           break;
3176         case 5:
3177           macadr->set(apply_rex_bit(mEBP, pref->rexB()), *pdisp32, addrSzAttr);
3178           break;
3179         case 6:
3180           macadr->set(apply_rex_bit(mESI, pref->rexB()), *pdisp32, addrSzAttr);
3181           break;
3182         case 7:
3183           macadr->set(apply_rex_bit(mEDI, pref->rexB()), *pdisp32, addrSzAttr);
3184           break;
3185         }
3186       }
3187       return nsib + dwordSzB;
3188     default:
3189       assert(0);
3190     }
3191   }
3192   return 0; // MS compiler from VS 6.0 wants this
3193 }
3194
3195
3196 static inline int type2size(unsigned int optype, unsigned int operSzAttr)
3197 {
3198   switch(optype) {
3199   case op_a:
3200     return 2 * wordSzB * operSzAttr;
3201   case op_b:
3202     return byteSzB;
3203   case op_c:
3204     assert(!"Where is this used, Intel?");
3205     return byteSzB * operSzAttr;
3206   case op_d:
3207     return dwordSzB;
3208   case op_dq:
3209     return dqwordSzB;
3210   case op_p:
3211     return wordSzB + wordSzB * operSzAttr; // XXX book says operand size...
3212   case op_pd:  // Intel "forgot" to define this in book, but uses it
3213     return dqwordSzB;
3214   case op_pi:
3215     return qwordSzB;
3216   case op_ps:
3217     return dqwordSzB;
3218   case op_q:
3219     return qwordSzB;
3220   case op_s:
3221     return 6;
3222   case op_sd:  // another Intel amnesia case
3223     return qwordSzB;
3224   case op_ss:
3225     return dwordSzB;
3226   case op_si:
3227     assert(!"Where is this used, Intel?");
3228     return dwordSzB;
3229   case op_v:
3230     return wordSzB * operSzAttr;
3231   case op_w:
3232     return wordSzB;
3233   case op_z:
3234       return operSzAttr == 1 ? wordSzB : dwordSzB;
3235   case op_lea:
3236     //    assert(!"Should not be evaluated");
3237     // We might be called, if we don't know this is an lea ahead of time
3238     // It's okay to return 0 here, because we really don't load/store
3239     return 0;
3240   case op_allgprs:
3241     return 8 * wordSzB * operSzAttr;
3242   case op_512:
3243     return 512;
3244   default:
3245     assert(!"No such type");
3246     return -1;
3247   }
3248 }
3249
3250
3251 int getOperSz(const ia32_prefixes &pref) 
3252 {
3253    if (pref.rexW()) return 4;
3254    else if (pref.getPrefix(2) == PREFIX_SZOPER) return 1;
3255    else return 2;
3256 }
3257
3258 unsigned int ia32_decode_operands (const ia32_prefixes& pref, 
3259                                    const ia32_entry& gotit, 
3260                                    const unsigned char* addr, 
3261                                    ia32_instruction& instruct,
3262                                    ia32_memacc *mac)
3263 {
3264   ia32_locations *loc = instruct.loc;
3265   unsigned int nib = 0 /* # of bytes in instruction */;
3266
3267   int addrSzAttr = (pref.getPrefix(3) == PREFIX_SZADDR ? 1 : 2);
3268
3269   if (mode_64)
3270     addrSzAttr *= 2;
3271
3272   int operSzAttr = getOperSz(pref);
3273
3274   if(gotit.hasModRM)
3275     nib += byteSzB;
3276
3277   for(unsigned int i=0; i<3; ++i) {
3278     const ia32_operand& op = gotit.operands[i];
3279     if(op.admet) {
3280       // At most two operands can be memory, the third is register or immediate
3281       //assert(i<2 || op.admet == am_reg || op.admet == am_I);
3282       switch(op.admet) {
3283       case am_A: /* address = segment + offset (word or dword or qword) */
3284         nib += wordSzB;
3285         if(mac)
3286           bperr( "x86: segment selector ignored [am_A].\n");
3287       case am_O: /* operand offset */
3288         nib += wordSzB * addrSzAttr;
3289         if(mac) {
3290           int offset;
3291           switch(addrSzAttr) {
3292           case 1: // 16-bit offset
3293               offset = *((const short int*)addr);
3294               break;
3295           case 2: // 32-bit offset
3296               offset = *((const int*)addr);
3297               break;
3298           case 4: // 64-bit
3299               offset = *((const long*)addr);
3300               break;
3301           default:
3302               assert(0);
3303               break;
3304           }
3305           mac[i].set(-1, offset, addrSzAttr);
3306           mac[i].size = type2size(op.optype, operSzAttr);
3307         }
3308         break;
3309       case am_C:   /* control register */
3310       case am_D:   /* debug register */
3311       case am_F:   /* flags register */
3312       case am_G:   /* general purpose register, selecteb by reg field */
3313       case am_P:   /* MMX register */
3314       case am_R:   /* general purpose register, selected by r/m field */
3315       case am_S:   /* segment register */
3316       case am_T:   /* test register */
3317       case am_V:   /* XMM register */
3318       case am_reg: /* register implicitely encoded in opcode */
3319       case am_allgprs:
3320         break;
3321       case am_E: /* register or memory location, so decoding needed */
3322       case am_M: /* memory operand, decoding needed; size includes modRM byte */
3323       case am_Q: /* MMX register or memory location */
3324       case am_W: /* XMM register or memory location */
3325          if (loc) {
3326             loc->modrm_position = loc->opcode_size + loc->opcode_position;
3327             loc->modrm_operand = i;
3328          }
3329          if(mac) {
3330             nib += ia32_decode_modrm(addrSzAttr, addr, &mac[i], &pref, loc);
3331             mac[i].size = type2size(op.optype, operSzAttr);
3332             if (loc) loc->address_size = mac[i].size;
3333          }
3334          else
3335             nib += ia32_decode_modrm(addrSzAttr, addr);
3336          
3337          // also need to check for AMD64 rip-relative data addressing
3338          // occurs when mod == 0 and r/m == 101
3339          if (mode_64)
3340             if ((addr[0] & 0xc7) == 0x05)
3341                instruct.rip_relative_data = true;
3342          
3343          break;
3344       case am_I: /* immediate data */
3345       case am_J: { /* instruction pointer offset */
3346          int imm_size = type2size(op.optype, operSzAttr);
3347          if (loc) {
3348             loc->imm_position = nib + loc->opcode_position + loc->opcode_size;
3349             loc->imm_size = imm_size;
3350          }
3351          nib += imm_size;
3352          break;
3353       }
3354       /* TODO: rep prefixes, deal with them here? */
3355       case am_X: /* memory at DS:(E)SI*/
3356         if(mac)
3357           mac[i].setXY(mESI, type2size(op.optype, operSzAttr), addrSzAttr);
3358         break;
3359       case am_Y: /* memory at ES:(E)DI*/
3360         if(mac)
3361           mac[i].setXY(mEDI, type2size(op.optype, operSzAttr), addrSzAttr);
3362         break;
3363       case am_stackH: /* stack push */
3364         if(mac) {
3365           // assuming 32-bit (64-bit for AMD64) stack segment
3366           // AMD64: push defaults to 64-bit operand size
3367           if (mode_64 && operSzAttr == 2)
3368               operSzAttr = 4;
3369           mac[i].set(mESP, -2 * operSzAttr, addrSzAttr);
3370           mac[i].size = type2size(op.optype, operSzAttr);
3371         }
3372         break;
3373       case am_stackP: /* stack pop */
3374         if(mac) {
3375           // assuming 32-bit (64-bit for AMD64) stack segment
3376           // AMD64: pop defaults to 64-bit operand size
3377           if (mode_64 && operSzAttr == 2)
3378               operSzAttr = 4;
3379           mac[i].set(mESP, 0, addrSzAttr);
3380           mac[i].size = type2size(op.optype, operSzAttr);
3381         }
3382         break;
3383       default:
3384         assert(0);
3385       }
3386     }
3387     else
3388       break;
3389   }
3390   instruct.size += nib;
3391   return nib;
3392 }
3393
3394
3395 static const unsigned char sse_prefix[256] = {
3396   /*       0 1 2 3 4 5 6 7 8 9 A B C D E F  */
3397   /* 0x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3398   /* 1x */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
3399   /* 2x */ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
3400   /* 3x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3401   /* 4x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3402   /* 5x */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
3403   /* 6x */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
3404   /* 7x */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, // Grp12-14 are SSE groups
3405   /* 8x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3406   /* 9x */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3407   /* Ax */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3408   /* Bx */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3409   /* Cx */ 0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
3410   /* Dx */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
3411   /* Ex */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
3412   /* Fx */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
3413 };
3414
3415
3416 // FIXME: lookahead might blow up...
3417 bool ia32_decode_prefixes(const unsigned char* addr, ia32_prefixes& pref,
3418                           ia32_locations *loc)
3419 {
3420   pref.count = 0;
3421   pref.prfx[0] = pref.prfx[1] = pref.prfx[2] = pref.prfx[3] = pref.prfx[4] = 0;
3422   pref.opcode_prefix = 0;
3423   bool in_prefix = true;
3424
3425   while(in_prefix) {
3426     switch(addr[0]) {
3427     case PREFIX_REPNZ:
3428     case PREFIX_REP:
3429        if(addr[1]==0x0F && sse_prefix[addr[2]]) {
3430           pref.opcode_prefix = addr[0];
3431           break;
3432        }
3433     case PREFIX_LOCK:
3434        ++pref.count;
3435        pref.prfx[0] = addr[0];
3436        break;
3437     case PREFIX_SEGCS:
3438     case PREFIX_SEGSS:
3439     case PREFIX_SEGDS:
3440     case PREFIX_SEGES:
3441     case PREFIX_SEGFS:
3442     case PREFIX_SEGGS:
3443        ++pref.count;
3444        pref.prfx[1] = addr[0];
3445        break;
3446     case PREFIX_SZOPER:
3447        if(addr[1]==0x0F && sse_prefix[addr[2]]) {
3448           pref.opcode_prefix = addr[0];
3449           break;
3450        }
3451        ++pref.count;
3452        pref.prfx[2] = addr[0];
3453        break;
3454     case PREFIX_SZADDR:
3455        ++pref.count;
3456        pref.prfx[3] = addr[0];