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