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