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