Compilation fixes for gcc 3.1, MSVC 6.0 & 7.0
[dyninst.git] / dyninstAPI / src / arch-x86.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: arch-x86.C,v 1.17 2002/06/17 17:04:04 gaburici Exp $
43 // x86 instruction decoder
44
45 #include <assert.h>
46 #include <stdio.h>
47 #include "common/h/Types.h"
48 #include "arch-x86.h"
49 #include "arch-ia32.h"
50
51 // opcode descriptors (from the Pentium manual)
52 enum {
53   Grp1=0, Grp2, Grp3a, Grp3b, Grp4, Grp5, Grp6, Grp7, Grp8, Grp9, 
54   oneB, twoB, coprocEsc,
55   PREFIX_SEG_OVR, PREFIX_OPR_SZ, PREFIX_ADDR_SZ, PREFIX_INSTR,
56   Ill
57 };
58
59 // operand descriptor (from the Pentium manual)
60 enum {
61   noOperand = 0,
62   const1,
63   CS, DS, ES, FS, GS, SS,
64   AL, AH, BL, BH, CL, CH, DL, DH,
65   AX, BX, CX, DX, SI, DI, BP, SP,
66   eAX, eBX, eCX, eDX, eSI, eDI, eBP, eSP,
67   rEAX, rEBX, rECX, rEDX, rESI, rEDI, rEBP, rESP,
68
69   Ap,
70   Cd,
71   Dd,
72   Eb, Ep, Ev, Ew,
73   Fv,
74   Gb, Gv, Gw,
75   Ib, Iv, Iw,
76   Jb, Jv,
77   M, Ma, Mp, Mq, Ms,
78   Ob, Ov,
79   Rd,
80   Sw, 
81   Xb, Xv,
82   Yb, Yv
83 };
84
85 // an entry of the opcode tables map
86 struct x86_insn {
87   char *name;              // name of the instruction (for debbuging only)
88   unsigned escape_code;    // which opcode tables to look at (eg. oneB, twoB, etc)
89   bool hasModRM;           // true if the instruction has a MOD/RM byte
90   unsigned operands[3];    // operand descriptos
91   unsigned insnType;       // the type of the instruction (e.g. (IS_CALL | REL_W))
92 };
93
94
95 /* groupMap: opcodes determined by bits 5,4,3 of the MOD/RM byte.
96    For some instructions in this table, the operands are defined in the
97    one or two byte opcode map, for others the operands are defined here.
98    Get operands from one or two byte map: Grp1, Grp2, Grp8
99    Get operands from ModRM map: Grp3a, Grp3b, Grp4, Grp5, Grp6, Grp7, Grp 9
100
101 */
102 static x86_insn groupMap[10][8] = {
103  { /* group 1 - only opcode is defined here,
104       operands are defined in the one or two byte maps below */
105   { "add", 0, true, { 0, 0, 0 }, 0 },
106   { "or", 0, true, { 0, 0, 0 }, 0 },
107   { "adc", 0, true, { 0, 0, 0 }, 0 },
108   { "sbb", 0, true, { 0, 0, 0 }, 0 },
109   { "and", 0, true, { 0, 0, 0 }, 0 },
110   { "sub", 0, true, { 0, 0, 0 }, 0 },
111   { "xor", 0, true, { 0, 0, 0 }, 0 },
112   { "cmp", 0, true, { 0, 0, 0 }, 0 }
113  },
114
115  {  /* group 2 - only opcode is defined here, 
116        operands are defined in the one or two byte maps below */
117   { "rol", 0, true, { 0, 0, 0 }, 0 },
118   { "ror", 0, true, { 0, 0, 0 }, 0 },
119   { "rcl", 0, true, { 0, 0, 0 }, 0 },
120   { "rcr", 0, true, { 0, 0, 0 }, 0 },
121   { "shl sal", 0, true, { 0, 0, 0 }, 0 },
122   { "shr", 0, true, { 0, 0, 0 }, 0 },
123   { 0, Ill, 0, { 0, 0, 0 }, 0 },
124   { "sar", 0, true, { 0, 0, 0 }, 0 }
125  },
126
127  { /* group 3a - operands are defined here */
128   { "test", 0, true, { Eb, Ib, 0 }, 0 },
129   { 0, Ill, 0, { 0, 0, 0 }, 0 },
130   { "not", 0, true, { Eb, 0, 0 }, 0 },
131   { "neg", 0, true, { Eb, 0, 0 }, 0 },
132   { "mul", 0, true, { AL, Eb, 0 }, 0 },
133   { "imul", 0, true, { AL, Eb, 0 }, 0 },
134   { "div", 0, true, { AL, Eb, 0 }, 0 },
135   { "idiv", 0, true, { AL, Eb, 0 }, 0 }
136  },
137
138  { /* group 3b - operands are defined here */
139   { "test", 0, true, { Ev, Iv, 0 }, 0 },
140   { 0, Ill, 0, { 0, 0, 0 }, 0 },
141   { "not", 0, true, { Ev, 0, 0 }, 0 },
142   { "neg", 0, true, { Ev, 0, 0 }, 0 },
143   { "mul", 0, true, { eAX, Ev, 0 }, 0 },
144   { "imul", 0, true, { eAX, Ev, 0 }, 0 },
145   { "div", 0, true, { eAX, Ev, 0 }, 0 },
146   { "idiv", 0, true, { eAX, Ev, 0 }, 0 }
147  },
148
149  { /* group 4 - operands are defined here */
150   { "inc", 0, true, { Eb, 0, 0 }, 0 },
151   { "dec", 0, true, { Eb, 0, 0 }, 0 },
152   { 0, Ill, 0, { 0, 0, 0 }, 0 },
153   { 0, Ill, 0, { 0, 0, 0 }, 0 },
154   { 0, Ill, 0, { 0, 0, 0 }, 0 },
155   { 0, Ill, 0, { 0, 0, 0 }, 0 },
156   { 0, Ill, 0, { 0, 0, 0 }, 0 },
157   { 0, Ill, 0, { 0, 0, 0 }, 0 },
158  },
159
160  { /* group 5 - operands are defined here */
161   { "inc", 0, true, { Ev, 0, 0 }, 0 },
162   { "dec", 0, true, { Ev, 0, 0 }, 0 },
163   { "call", 0, true, { Ev, 0, 0 }, (IS_CALL | INDIR) },
164   { "call", 0, true, { Ep, 0, 0 }, (IS_CALL | INDIR) },
165   { "jmp", 0, true, { Ev, 0, 0 } , (IS_JUMP | INDIR) },
166   { "jmp", 0, true, { Ep, 0, 0 }, (IS_JUMP | INDIR) },
167   { "push", 0, true, { Ev, 0, 0, }, 0 },
168   { 0, Ill, 0, { 0, 0, 0 }, 0 },
169  },
170
171  { /* group 6 - operands are defined here */
172   { "sldt", 0, true, { Ew, 0, 0 }, 0 },
173   { "str", 0, true, { Ew, 0, 0 }, 0 },
174   { "lldt", 0, true, { Ew, 0, 0 }, 0 },
175   { "ltr", 0, true, { Ew, 0, 0 }, 0 },
176   { "verr", 0, true, { Ew, 0, 0 }, 0 },
177   { "verw", 0, true, { Ew, 0, 0 }, 0 },
178   { 0, Ill, 0, { 0, 0, 0 }, 0 },
179   { 0, Ill, 0, { 0, 0, 0 }, 0 },
180  },
181
182  { /* group 7 - operands are defined here */
183   { "sgdt", 0, true, { Ms, 0, 0 }, 0 },
184   { "sidt", 0, true, { Ms, 0, 0 }, 0 },
185   { "lgdt", 0, true, { Ms, 0, 0 }, 0 },
186   { "lidt", 0, true, { Ms, 0, 0 }, 0 },
187   { "smsw", 0, true, { Ew, 0, 0 }, 0 },
188   { 0, Ill, 0, { 0, 0, 0 }, 0 },
189   { "lmsw", 0, true, { Ew, 0, 0 }, 0 },
190   { "invlpg", 0, true, { 0, 0, 0 }, 0 },
191  },
192
193  { /* group 8 - only opcode is defined here, 
194      operands are defined in the one or two byte maps below */
195   { 0, Ill, 0, { 0, 0, 0 }, 0 },
196   { 0, Ill, 0, { 0, 0, 0 }, 0 },
197   { 0, Ill, 0, { 0, 0, 0 }, 0 },
198   { 0, Ill, 0, { 0, 0, 0 }, 0 },
199   { "bt", 0, true, { 0, 0, 0 }, 0 },
200   { "bts", 0, true, { 0, 0, 0 }, 0 },
201   { "btr", 0, true, { 0, 0, 0 }, 0 },
202   { "btc", 0, true, { 0, 0, 0 }, 0 },
203  },
204
205  { /* group 9 - operands are defined here */
206   { 0, Ill, 0, { 0, 0, 0 }, 0 },
207   { "cmpxch8b", 0, true, { Mq, 0, 0 }, 0 },
208   { 0, Ill, 0, { 0, 0, 0 }, 0 },
209   { 0, Ill, 0, { 0, 0, 0 }, 0 },
210   { 0, Ill, 0, { 0, 0, 0 }, 0 },
211   { 0, Ill, 0, { 0, 0, 0 }, 0 },
212   { 0, Ill, 0, { 0, 0, 0 }, 0 },
213   { 0, Ill, 0, { 0, 0, 0 }, 0 }
214  },
215 };
216
217 // twoByteMap: two byte opcode instructions (first byte is 0x0F)
218 static x86_insn twoByteMap[256] = {
219   /* 00 */
220   { 0, Grp6, true, { 0, 0, 0 }, 0 }, 
221   { 0, 0, false, { 0, 0, 0 }, 0 },
222   { "lar", twoB, true, { Gv, Ew, 0 }, 0  },
223   { "lsl", twoB, true, { Gv, Ew, 0 }, 0  },
224   {0,Ill,0,{0,0,0},0},
225   {0,Ill,0,{0,0,0},0},
226   { "clts", twoB, false, { 0, 0, 0 }, 0 },
227   {0,Ill,0,{0,0,0},0},
228   /* 08 */
229   { "invd", twoB, false, { 0, 0, 0 }, 0 },
230   { "wbinvd", twoB, false, { 0, 0, 0 }, 0 },
231   {0,Ill,0,{0,0,0},0},
232   {0,Ill,0,{0,0,0},0},
233   {0,Ill,0,{0,0,0},0},
234   {0,Ill,0,{0,0,0},0},
235   {0,Ill,0,{0,0,0},0},
236   {0,Ill,0,{0,0,0},0},
237   /* 10 */
238   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
239   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
240   /* 18 */
241   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
242   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
243   /* 20 */
244   { "mov", twoB, true, { Rd, Cd, 0 }, 0 },
245   { "mov", twoB, true, { Rd, Dd, 0 }, 0 },
246   { "mov", twoB, true, { Cd, Rd, 0 }, 0 },
247   { "mov", twoB, true, { Dd, Rd, 0 }, 0 },
248   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
249   /* 28 */
250   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
251   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
252   /* 30 */
253   { "wrmsr", twoB, false, { 0, 0, 0 }, 0 },
254   { "rdtsc", twoB, false, { 0, 0, 0 }, 0 },
255   { "rdmsr", twoB, false, { 0, 0, 0 }, 0 },
256   {0,Ill,0,{0,0,0},0},
257   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
258   /* 38 */
259   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
260   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
261   /* 40 */
262   { "cmovo", twoB, true, { Gv, Ev, 0 }, 0 },
263   { "cmovno", twoB, true, { Gv, Ev, 0 }, 0 },
264   { "cmovnae", twoB, true, { Gv, Ev, 0 }, 0 },
265   { "cmovnb", twoB, true, { Gv, Ev, 0 }, 0 },
266   { "cmove", twoB, true, { Gv, Ev, 0 }, 0 },
267   { "cmovne", twoB, true, { Gv, Ev, 0 }, 0 },
268   { "cmovbe", twoB, true, { Gv, Ev, 0 }, 0 },
269   { "cmovnbe", twoB, true, { Gv, Ev, 0 }, 0 },
270   /* 48 */
271   { "cmovs", twoB, true, { Gv, Ev, 0 }, 0 },
272   { "cmovns", twoB, true, { Gv, Ev, 0 }, 0 },
273   { "cmovpe", twoB, true, { Gv, Ev, 0 }, 0 },
274   { "cmovpo", twoB, true, { Gv, Ev, 0 }, 0 },
275   { "cmovnge", twoB, true, { Gv, Ev, 0 }, 0 },
276   { "cmovnl", twoB, true, { Gv, Ev, 0 }, 0 },
277   { "cmovng", twoB, true, { Gv, Ev, 0 }, 0 },
278   { "cmovnl", twoB, true, { Gv, Ev, 0 }, 0 },
279   /* 50 */
280   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
281   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
282   /* 58 */
283   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
284   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
285   /* 60 */
286   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
287   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
288   /* 68 */
289   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
290   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
291   /* 70 */
292   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
293   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
294   /* 78 */
295   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
296   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
297   /* 80 */
298   { "jo", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
299   { "jno", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
300   { "jb", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
301   { "jnb", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
302   { "jz", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
303   { "jnz", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
304   { "jbe", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
305   { "jnbe", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
306   /* 88 */
307   { "js", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
308   { "jns", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
309   { "jp", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
310   { "jnp", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
311   { "jl", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
312   { "jnl", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
313   { "jle", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
314   { "jnle", twoB, false, { Jv, 0, 0 }, (IS_JCC | REL_X) },
315   /* 90 */
316   { "seto", twoB, true, { Eb, 0, 0 }, 0 },
317   { "setno", twoB, true, { Eb, 0, 0 }, 0 },
318   { "setb", twoB, true, { Eb, 0, 0 }, 0 },
319   { "setnb", twoB, true, { Eb, 0, 0 }, 0 },
320   { "setz", twoB, true, { Eb, 0, 0 }, 0 },
321   { "setnz", twoB, true, { Eb, 0, 0 }, 0 },
322   { "setbe", twoB, true, { Eb, 0, 0 }, 0 },
323   { "setnbe", twoB, true, { Eb, 0, 0 }, 0 },
324   /* 98 */
325   { "sets", twoB, true, { Eb, 0, 0 }, 0 },
326   { "setns", twoB, true, { Eb, 0, 0 }, 0 },
327   { "setp", twoB, true, { Eb, 0, 0 }, 0 },
328   { "setnp", twoB, true, { Eb, 0, 0 }, 0 },
329   { "setl", twoB, true, { Eb, 0, 0 }, 0 },
330   { "setnl", twoB, true, { Eb, 0, 0 }, 0 },
331   { "setle", twoB, true, { Eb, 0, 0 }, 0 },
332   { "setnle", twoB, true, { Eb, 0, 0 }, 0 },
333   /* A0 */
334   { "push", twoB, false, { FS, 0, 0 }, 0 },
335   { "pop", twoB, false, { FS, 0, 0 }, 0 },
336   { "cpuid", twoB, false, { 0, 0, 0 }, 0 },
337   { "bt", twoB, true, { Ev, Gv, 0 }, 0 },
338   { "shld", twoB, true, { Ev, Gv, Ib }, 0 },
339   { "shld", twoB, true, { Ev, Gv, CL }, 0 },
340   {0,Ill,0,{0,0,0},0}, 
341   {0,Ill,0,{0,0,0},0},
342   /* A8 */
343   { "push", twoB, false, { GS, 0, 0 }, 0 },
344   { "pop", twoB, false, { GS, 0, 0 }, 0 },
345   { "rsm", twoB, false, { 0, 0, 0 }, 0 },
346   { "bts", twoB, true, { Ev, Gv, 0 }, 0 },
347   { "shrd", twoB, true, { Ev, Gv, Ib }, 0 },
348   { "shrd", twoB, true, { Ev, Gv, CL }, 0 },
349   {0,Ill,0,{0,0,0},0}, 
350   { "imul", twoB, true, { Gv, Ev, 0 }, 0 },
351   /* B0 */
352   { "cmpxch", twoB, true, { Eb, Gb, 0 }, 0 },
353   { "cmpxch", twoB, true, { Ev, Gv, 0 }, 0 },
354   { "lss", twoB, true, { Mp, 0, 0 }, 0 },
355   { "btr", twoB, true, { Ev, Gv, 0 }, 0 },
356   { "lfs", twoB, true, { Mp, 0, 0 }, 0 },
357   { "lgs", twoB, true, { Mp, 0, 0 }, 0 },
358   { "movzx", twoB, true, { Gv, Eb, 0 }, 0 },
359   { "movzx", twoB, true, { Gv, Ew, 0 }, 0 },
360   /* B8 */
361   {0,Ill,0,{0,0,0},0},
362   {0,Ill,0,{0,0,0},0},
363   { 0, Grp8, true, { Ev, Ib, 0 }, 0 },
364   { "btc", twoB, true, { Ev, Gv, 0 }, 0 },
365   { "bsf", twoB, true, { Gv, Ev, 0 }, 0 },
366   { "bsr", twoB, true, { Gv, Ev, 0 }, 0 },
367   { "movsx", twoB, true, { Gv, Eb, 0 }, 0 },
368   { "movsx", twoB, true, { Gv, Ew, 0 }, 0 },
369   /* C0 */
370   { "xadd", twoB, true, { Eb, Gb, 0 }, 0 },
371   { "xadd", twoB, true, { Ev, Gv, 0 }, 0 },
372   {0,Ill,0,{0,0,0},0},
373   {0,Ill,0,{0,0,0},0},
374   {0,Ill,0,{0,0,0},0},
375   {0,Ill,0,{0,0,0},0},
376   {0,Ill,0,{0,0,0},0},
377   { 0, Grp9, true, { 0, 0, 0 }, 0 },
378   /* C8 */
379   { "bswap", twoB, false, { rEAX, 0, 0 }, 0 }, 
380   { "bswap", twoB, false, { rECX, 0, 0 }, 0 }, 
381   { "bswap", twoB, false, { rEDX, 0, 0 }, 0 }, 
382   { "bswap", twoB, false, { rEBX, 0, 0 }, 0 }, 
383   { "bswap", twoB, false, { rESP, 0, 0 }, 0 },
384   { "bswap", twoB, false, { rEBP, 0, 0 }, 0 }, 
385   { "bswap", twoB, false, { rESI, 0, 0 }, 0 }, 
386   { "bswap", twoB, false, { rEDI, 0, 0 }, 0 }, 
387   /* D0 */
388   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
389   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
390   /* D8 */
391   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
392   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
393   /* E0 */
394   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
395   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
396   /* E8 */
397   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
398   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
399   /* F0 */
400   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
401   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
402   /* F8 */
403   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
404   {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0}, {0,Ill,0,{0,0,0},0},
405 };
406
407
408 // oneByteMap: one byte opcode map
409 static x86_insn oneByteMap[256] = {
410   /* 00 */
411   { "add", oneB, true, { Eb, Gb, 0 }, 0 },
412   { "add", oneB, true, { Ev, Gv, 0 }, 0 },
413   { "add", oneB, true, { Gb, Eb, 0 }, 0 },
414   { "add", oneB, true, { Gv, Ev, 0 }, 0 },
415   { "add", oneB, false, { AL, Ib, 0 }, 0 },
416   { "add", oneB, false, { eAX, Iv, 0 }, 0 },
417   { "push", oneB, false, { ES, 0, 0 }, 0 },
418   { "pop", oneB, false, { ES, 0, 0 }, 0 },
419   /* 08 */
420   { "or", oneB, true, { Eb, Gb, 0 }, 0 },
421   { "or", oneB, true, { Ev, Gv, 0 }, 0 },
422   { "or", oneB, true, { Gb, Eb, 0 }, 0 },
423   { "or", oneB, true, { Gv, Ev, 0 }, 0 },
424   { "or", oneB, false, { AL, Ib, 0 }, 0 },
425   { "or", oneB, false, { eAX, Iv, 0 }, 0 },
426   { "push", oneB, false, { ES, 0, 0 }, 0 },
427   { 0 , twoB, false, { 0, 0, 0 }, 0 },
428   /* 10 */
429   { "adc", oneB, true, { Eb, Gb, 0 }, 0 },
430   { "adc", oneB, true, { Ev, Gv, 0 }, 0 },
431   { "adc", oneB, true, { Gb, Eb, 0 }, 0 },
432   { "adc", oneB, true, { Gv, Ev, 0 }, 0 },
433   { "adc", oneB, false, { AL, Ib, 0 }, 0 },
434   { "adc", oneB, false, { eAX, Iv, 0 }, 0 },
435   { "push", oneB, false, { SS, 0, 0 }, 0 },
436   { "pop", oneB, false, { SS, 0, 0 }, 0 },
437   /* 18 */
438   { "sbb", oneB, true, { Eb, Gb, 0 }, 0 },
439   { "sbb", oneB, true, { Ev, Gv, 0 }, 0 },
440   { "sbb", oneB, true, { Gb, Eb, 0 }, 0 },
441   { "sbb", oneB, true, { Gv, Ev, 0 }, 0 },
442   { "sbb", oneB, false, { AL, Ib, 0 }, 0 },
443   { "sbb", oneB, false, { eAX, Iv, 0 }, 0 },
444   { "push", oneB, false, { DS, 0, 0 }, 0 },
445   { "pop" , oneB, false, { DS, 0, 0 }, 0 },
446   /* 20 */
447   { "and", oneB, true, { Eb, Gb, 0 }, 0 },
448   { "and", oneB, true, { Ev, Gv, 0 }, 0 },
449   { "and", oneB, true, { Gb, Eb, 0 }, 0 },
450   { "and", oneB, true, { Gv, Ev, 0 }, 0 },
451   { "and", oneB, false, { AL, Ib, 0 }, 0 },
452   { "and", oneB, false, { eAX, Iv, 0 }, 0 },
453   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
454   { "daa", oneB, false, { 0, 0, 0 }, 0 },
455   /* 28 */
456   { "sub", oneB, true, { Eb, Gb, 0 }, 0 },
457   { "sub", oneB, true, { Ev, Gv, 0 }, 0 },
458   { "sub", oneB, true, { Gb, Eb, 0 }, 0 },
459   { "sub", oneB, true, { Gv, Ev, 0 }, 0 },
460   { "sub", oneB, false, { AL, Ib, 0 }, 0 },
461   { "sub", oneB, false, { eAX, Iv, 0 }, 0 },
462   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
463   { "das" , oneB, false, { 0, 0, 0 }, 0 },
464   /* 30 */
465   { "xor", oneB, true, { Eb, Gb, 0 }, 0 },
466   { "xor", oneB, true, { Ev, Gv, 0 }, 0 },
467   { "xor", oneB, true, { Gb, Eb, 0 }, 0 },
468   { "xor", oneB, true, { Gv, Ev, 0 }, 0 },
469   { "xor", oneB, false, { AL, Ib, 0 }, 0 },
470   { "xor", oneB, false, { eAX, Iv, 0 }, 0 },
471   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
472   { "aaa", oneB, false, { 0, 0, 0 }, 0 },
473   /* 38 */
474   { "cmp", oneB, true, { Eb, Gb, 0 }, 0 },
475   { "cmp", oneB, true, { Ev, Gv, 0 }, 0 },
476   { "cmp", oneB, true, { Gb, Eb, 0 }, 0 },
477   { "cmp", oneB, true, { Gv, Ev, 0 }, 0 },
478   { "cmp", oneB, false, { AL, Ib, 0 }, 0 },
479   { "cmp", oneB, false, { eAX, Iv, 0 }, 0 },
480   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
481   { "aas" , oneB, false, { 0, 0, 0 }, 0 },
482   /* 40 */
483   { "inc", oneB, false, { eAX, 0, 0 }, 0 }, 
484   { "inc", oneB, false, { eCX, 0, 0 }, 0 },
485   { "inc", oneB, false, { eDX, 0, 0 }, 0 },
486   { "inc", oneB, false, { eBX, 0, 0 }, 0 },
487   { "inc", oneB, false, { eSP, 0, 0 }, 0 },
488   { "inc", oneB, false, { eBP, 0, 0 }, 0 },
489   { "inc", oneB, false, { eSI, 0, 0 }, 0 },
490   { "inc", oneB, false, { eDI, 0, 0 }, 0 },
491   /* 48 */
492   { "dec", oneB, false, { eAX, 0, 0 }, 0 }, 
493   { "dec", oneB, false, { eCX, 0, 0 }, 0 },
494   { "dec", oneB, false, { eDX, 0, 0 }, 0 },
495   { "dec", oneB, false, { eBX, 0, 0 }, 0 },
496   { "dec", oneB, false, { eSP, 0, 0 }, 0 },
497   { "dec", oneB, false, { eBP, 0, 0 }, 0 },
498   { "dec", oneB, false, { eSI, 0, 0 }, 0 },
499   { "dec", oneB, false, { eDI, 0, 0 }, 0 },
500   /* 50 */
501   { "push", oneB, false, { eAX, 0, 0 }, 0 }, 
502   { "push", oneB, false, { eCX, 0, 0 }, 0 },
503   { "push", oneB, false, { eDX, 0, 0 }, 0 },
504   { "push", oneB, false, { eBX, 0, 0 }, 0 },
505   { "push", oneB, false, { eSP, 0, 0 }, 0 },
506   { "push", oneB, false, { eBP, 0, 0 }, 0 },
507   { "push", oneB, false, { eSI, 0, 0 }, 0 },
508   { "push", oneB, false, { eDI, 0, 0 }, 0 },
509   /* 58 */
510   { "pop", oneB, false, { eAX, 0, 0 }, 0 }, 
511   { "pop", oneB, false, { eCX, 0, 0 }, 0 },
512   { "pop", oneB, false, { eDX, 0, 0 }, 0 },
513   { "pop", oneB, false, { eBX, 0, 0 }, 0 },
514   { "pop", oneB, false, { eSP, 0, 0 }, 0 },
515   { "pop", oneB, false, { eBP, 0, 0 }, 0 },
516   { "pop", oneB, false, { eSI, 0, 0 }, 0 },
517   { "pop", oneB, false, { eDI, 0, 0 }, 0 },
518   /* 60 */
519   { "pusha(d)", oneB, false, { 0, 0, 0 }, 0 }, 
520   { "popa(d)", oneB, false, { 0, 0, 0 }, 0 },
521   { "bound", oneB, true, { Gv, Ma, 0 }, 0 },
522   { "arpl", oneB, true, { Ew, Gw, 0 }, 0 },
523   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
524   { 0, PREFIX_SEG_OVR, false, { 0, 0, 0 }, 0 },
525   { 0, PREFIX_OPR_SZ, false, { 0, 0, 0 }, 0 }, /* operand size prefix */
526   { 0, PREFIX_ADDR_SZ, false, { 0, 0, 0 }, 0 }, /* address size prefix */
527   /* 68 */
528   { "push", oneB, false, { Iv, 0, 0 }, 0 },
529   { "imul", oneB, true, { Gv, Ev, Iv }, 0 },
530   { "push", oneB, false, { Ib, 0, 0 }, 0 },
531   { "imul", oneB, true, { Gv, Ev, Ib }, 0 },
532   { "insb", oneB, false, { Yb, DX, 0 }, 0 },
533   { "insw/d", oneB, false, { Yv, DX, 0 }, 0 },
534   { "outsb", oneB, false, { DX, Xb, 0 }, 0 },
535   { "outsw/d", oneB, false, { DX, Xv, 0 }, 0 },
536   /* 70 */
537   { "jo", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
538   { "jno", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
539   { "jb/jnaej/j", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
540   { "jnb/jae/j", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
541   { "jz", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
542   { "jnz", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
543   { "jbe", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
544   { "jnbe", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
545   /* 78 */
546   { "js", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
547   { "jns", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
548   { "jp", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
549   { "jnp", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
550   { "jl", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
551   { "jnl", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
552   { "jle", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
553   { "jnle", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
554   /* 80 */
555   { 0, Grp1, true, { Eb, Ib, 0 }, 0 },
556   { 0, Grp1, true, { Ev, Iv, 0 }, 0 },
557   { 0, Ill, 0, { 0, 0, 0 }, 0 },
558   { 0, Grp1, true, { Ev, Ib, 0 }, 0 },
559   { "test", oneB, true, { Eb, Gb, 0 }, 0 },
560   { "test", oneB, true, { Ev, Gv, 0 }, 0 },
561   { "xchg", oneB, true, { Eb, Gb, 0 }, 0 },
562   { "xchg", oneB, true, { Ev, Gv, 0 }, 0 },
563   /* 88 */
564   { "mov", oneB, true, { Eb, Gb, 0 }, 0 },
565   { "mov", oneB, true, { Ev, Gv, 0 }, 0 },
566   { "mov", oneB, true, { Gb, Eb, 0 }, 0 },
567   { "mov", oneB, true, { Gv, Ev, 0 }, 0 },
568   { "mov", oneB, true, { Ew, Sw, 0 }, 0 },
569   { "lea", oneB, true, { Gv, M, 0 }, 0 },
570   { "mov", oneB, true, { Sw, Ew, 0 }, 0 },
571   { "pop", oneB, true, { Ev, 0, 0, }, 0 },
572   /* 90 */
573   { "nop", oneB, false, { 0, 0, 0 }, 0 },
574   { "xchg", oneB, false, { eCX, 0, 0 }, 0 },
575   { "xchg", oneB, false, { eDX, 0, 0 }, 0 },
576   { "xchg", oneB, false, { eBX, 0, 0 }, 0 },
577   { "xchg", oneB, false, { eSP, 0, 0 }, 0 },
578   { "xchg", oneB, false, { eBP, 0, 0 }, 0 },
579   { "xchg", oneB, false, { eSI, 0, 0 }, 0 },
580   { "xchg", oneB, false, { eDI, 0, 0 }, 0 },
581   /* 98 */
582   { "cbw", oneB, false, { 0, 0, 0 }, 0 },
583   { "cwd/cdq", oneB, false, { 0, 0, 0 }, 0 },
584   { "call", oneB, false, { Ap, 0, 0}, IS_CALL | PTR_WX },
585   { "wait", oneB, false, { 0, 0, 0 }, 0 },
586   { "pushf", oneB, false, { Fv, 0, 0 }, 0 },
587   { "pop", oneB, false, { Fv, 0, 0 }, 0 },
588   { "sahf", oneB, false, { 0, 0, 0 }, 0 },
589   { "lahf", oneB, false, { 0, 0, 0 }, 0 },
590   /* A0 */
591   { "mov", oneB, false, { AL, Ob, 0 }, 0 },
592   { "mov", oneB, false, { eAX, Ov, 0 }, 0 },
593   { "mov", oneB, false, { Ob, AL, 0 }, 0 },
594   { "mov", oneB, false, { Ov, eAX, 0 }, 0 },
595   { "movsb", oneB, false, { Xb, Yb, 0 }, 0 },
596   { "movsw", oneB, false, { Xv, Yv, 0 }, 0 },
597   { "cmpsb", oneB, false, { Xb, Yb, 0 }, 0 },
598   { "cmpsw", oneB, false, { Xv, Yv, 0 }, 0 },
599   /* A8 */
600   { "test", oneB, false, { AL, Ib, 0 }, 0 },
601   { "test", oneB, false, { eAX, Iv, 0 }, 0 },
602   { "stopsb", oneB, false, { Yb, AL, 0 }, 0 },
603   { "stopsw/d", oneB, false, { Yv, eAX, 0 }, 0 },
604   { "lodsb", oneB, false, { AL, Xb, 0 }, 0 },
605   { "lodsw", oneB, false, { eAX, Xv, 0 }, 0 },
606   { "scasb", oneB, false, { AL, Yb, 0 }, 0 },
607   { "scasw/d", oneB, false, { eAX, Yv, 0 }, 0 },
608   /* B0 */
609   { "mov", oneB, false, { AL, Ib, 0 }, 0 },
610   { "mov", oneB, false, { CL, Ib, 0 }, 0 },
611   { "mov", oneB, false, { DL, Ib, 0 }, 0 },
612   { "mov", oneB, false, { BL, Ib, 0 }, 0 },
613   { "mov", oneB, false, { AH, Ib, 0 }, 0 },
614   { "mov", oneB, false, { CH, Ib, 0 }, 0 },
615   { "mov", oneB, false, { DH, Ib, 0 }, 0 },
616   { "mov", oneB, false, { BH, Ib, 0 }, 0 },
617   /* B8 */
618   { "mov", oneB, false, { eAX, Iv, 0 }, 0 },
619   { "mov", oneB, false, { eCX, Iv, 0 }, 0 },
620   { "mov", oneB, false, { eDX, Iv, 0 }, 0 },
621   { "mov", oneB, false, { eBX, Iv, 0 }, 0 },
622   { "mov", oneB, false, { eSP, Iv, 0 }, 0 },
623   { "mov", oneB, false, { eBP, Iv, 0 }, 0 },
624   { "mov", oneB, false, { eSI, Iv, 0 }, 0 },
625   { "mov", oneB, false, { eDI, Iv, 0 }, 0 },
626   /* C0 */
627   { 0, Grp2, true, { Eb, Ib, 0 }, 0 },
628   { 0, Grp2, true, { Ev, Ib, 0 }, 0 },
629   { "ret near", oneB, false, { Iw, 0, 0 }, (IS_RET) },
630   { "ret near", oneB, false, { 0, 0, 0 }, (IS_RET) },
631   { "les", oneB, true, { Gv, Mp, 0 }, 0 },
632   { "lds", oneB, true, { Gv, Mp, 0 }, 0 },
633   { "mov", oneB, true, { Eb, Ib, 0 }, 0 },
634   { "mov", oneB, true, { Ev, Iv, 0 }, 0 },
635   /* C8 */
636   { "enter", oneB, false, { Iw, Ib, 0 }, 0 },
637   { "leave", oneB, false, { 0, 0, 0 }, 0 },
638   { "ret far", oneB, false, { Iw, 0, 0 }, (IS_RETF) },
639   { "ret far", oneB, false, { 0, 0, 0 }, (IS_RETF) },
640   { "int 3", oneB, false, { 0, 0, 0 }, 0 },
641   { "int", oneB, false, { Ib, 0, 0 }, 0 },
642   { "into", oneB, false, { 0, 0, 0 }, 0 },
643   { "iret", oneB, false, { 0, 0, 0 }, (IS_RET) },
644   /* D0 */
645   { 0, Grp2, true, { Eb, const1, 0 }, 0 },
646   { 0, Grp2, true, { Ev, const1, 0 }, 0 },
647   { 0, Grp2, true, { Eb, CL, 0 }, 0 },
648   { 0, Grp2, true, { Ev, CL, 0 }, 0 },
649   { "aam", oneB, false, { 0, 0, 0 }, 0 },
650   { "aad", oneB, false, { 0, 0, 0 }, 0 },
651   { 0, Ill, 0, { 0, 0, 0 }, 0 },
652   { "xlat", oneB, false, { 0, 0, 0 }, 0 },
653   /* D8 */
654   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
655   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
656   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
657   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
658   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
659   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
660   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
661   { 0, coprocEsc, true, { 0, 0, 0 }, 0 },
662   /* E0 */
663   { "loopn", oneB, false, { Jb, 0, 0 }, 0 },
664   { "loope", oneB, false, { Jb, 0, 0 }, 0 },
665   { "loop", oneB, false, { Jb, 0, 0 }, 0 },
666   { "jcxz/jec", oneB, false, { Jb, 0, 0 }, (IS_JCC | REL_B) },
667   { "in", oneB, false, { AL, Ib, 0 }, 0 },
668   { "in", oneB, false, { eAX, Ib, 0 }, 0 },
669   { "out", oneB, false, { Ib, AL, 0 }, 0 },
670   { "out", oneB, false, { Ib, eAX, 0 }, 0 },
671   /* E8 */
672   { "call", oneB, false, { Jv, 0, 0 }, (IS_CALL | REL_X) },
673   { "jmp", oneB, false, { Jv, 0, 0 }, (IS_JUMP | REL_X) },
674   { "jmp", oneB, false, { Ap, 0, 0 }, (IS_JUMP | PTR_WX) },
675   { "jmp", oneB, false, { Jb, 0, 0 }, (IS_JUMP | REL_B) },
676   { "in", oneB, false, { AL, DX, 0 }, 0 },
677   { "in", oneB, false, { eAX, DX, 0 }, 0 },
678   { "out", oneB, false, { DX, AL, 0 }, 0 },
679   { "out", oneB, false, { DX, eAX, 0 }, 0 },
680   /* F0 */
681   { 0, PREFIX_INSTR, false, { 0, 0, 0 }, 0 },
682   { 0, 0, false, { 0, 0, 0 }, 0 },
683   { 0, PREFIX_INSTR, false, { 0, 0, 0 }, 0 },
684   { 0, PREFIX_INSTR, false, { 0, 0, 0 }, 0 },
685   { "hlt", oneB, false, { 0, 0, 0 }, 0 },
686   { "cmc", oneB, false, { 0, 0, 0 }, 0 },
687   { 0, Grp3a, true, { Eb, 0, 0 }, 0 },
688   { 0, Grp3b, true, { Ev, 0, 0 }, 0 },
689   /* F8 */
690   { "clc", oneB, false, { 0, 0, 0 }, 0 },
691   { "stc", oneB, false, { 0, 0, 0 }, 0 },
692   { "cli", oneB, false, { 0, 0, 0 }, 0 },
693   { "sti", oneB, false, { 0, 0, 0 }, 0 },
694   { "cld", oneB, false, { 0, 0, 0 }, 0 },
695   { "std", oneB, false, { 0, 0, 0 }, 0 },
696   { 0, Grp4, true, { 0, 0, 0 }, 0 },
697   { 0, Grp5, true, { 0, 0, 0 }, 0 }
698 };
699
700
701 /* decodes an operand especified in the ModRM byte. Return the size in bytes of the
702    operand field, not counting the ModRM byte.
703 */
704 static unsigned doModRMOperand(const unsigned addrSzAttr, // the address size attr.
705                                const unsigned Mod,        // mod field
706                                const unsigned RM,         // RM field
707                                const unsigned SIB)        // SIB byte
708 {
709   if (addrSzAttr == 1) { // 16-bit addressing - use table 25-2 in the Pentium manual
710     if ((Mod == 0 && RM == 6) || (Mod == 2)) {
711       return wordSzB;
712     }
713     else if (Mod == 1) {
714       return byteSzB;
715     }
716     else {
717       return 0;
718     }
719   }
720   else { // 32-bit addressing -  use table 25-3 in the Pentium manual
721     if ((Mod == 0 && RM == 5) || (Mod == 2)) {
722       return dwordSzB;
723     }
724     else if (Mod == 1) {
725       return byteSzB;
726     }
727     else {
728       // check SIB: there is a 32 bit displacement if Mod = 0 and 
729       // the base field of SIB is 5
730       if (Mod == 0 && RM == 4 && ((SIB & 0x7) == 5))
731         return dwordSzB;
732       else 
733         return 0;
734     }
735   }
736   // not reached
737   assert(0);
738 }
739
740 /*
741    decodes an operand of an instruction.
742    Return the size in bytes of the operand fields. If the operand is encoded in the
743    opcode or in the ModR/M byte, the size returned is zero.
744 */
745 static unsigned doOperand(const unsigned operandType,   // type descriptor of operand
746                           const unsigned operandSzAttr, // operand sz. attribute
747                           const unsigned addrSzAttr,    // address sz. attribute
748                           const unsigned Mod,           // MOD field
749                           const unsigned RM,            // RM field
750                           const unsigned SIB)           // SIB byte
751 {
752   switch (operandType) {
753   case Ap:
754     /* direct address of operand encoded in instruction as a segment number (word)
755        and an offset (word or dword)
756      */
757     return (wordSzB + (addrSzAttr * wordSzB));
758     break;
759
760   case Cd:
761   case Dd:
762     // ModRM byte selects operand
763     return 0;
764     break;
765   
766   case Eb:
767   case Ep:
768   case Ev:
769   case Ew:
770     /* the operand is either a register or a memory operand.
771        The operand size doesn't matter here as the instruction does not have the
772        operand itself, but only its address.
773        Only the address size is used here.
774     */
775     return doModRMOperand(addrSzAttr, Mod, RM, SIB);
776     break;
777
778   case Fv:
779     // operand is flag register
780     return 0;
781     break;
782
783   case Gb:
784   case Gv:
785   case Gw:
786     // operand encoded in modR/M byte
787     return 0;
788     break;
789
790   case Ib: /* immediate byte */
791     return byteSzB;
792     break;
793   case Iv: /* immediate word or dword */
794     return (wordSzB * operandSzAttr);
795     break;
796   case Iw: /* immediate word */
797     return wordSzB;
798     break;
799
800   case Jb: /* byte relative offset in instruction */
801     return byteSzB;
802     break;
803   case Jv: /* word or dword relative offset in instruction */
804     return (wordSzB * operandSzAttr);
805     break;
806
807   case M:
808   case Ma:
809   case Mp:
810   case Mq:
811   case Ms:
812     /* Like E but the operand can be only a memory operand.
813        The operand size doesn't matter here as the instruction does not have the
814        operand itself, but only its address.
815        Only the address size is used here.
816     */
817     return doModRMOperand(addrSzAttr, Mod, RM, SIB);
818     break;
819
820   case Ob:
821   case Ov: 
822     /* offset of operand encoded as word or dword */
823     return (wordSzB * addrSzAttr);
824     break;
825
826   case Rd:
827     return 0;
828     break;
829
830   case Sw:
831     // operand defined in reg field of ModR/M byte
832     return 0;
833     break;
834
835   case Xb:
836   case Xv:
837     return 0;
838     break;
839
840   case Yb:
841   case Yv:
842     return 0;
843     break;
844
845   case const1:
846     return 0;
847     break;
848
849   default:
850     if (operandType >= CS && operandType <= rESP)
851       return 0;
852   }
853   // should not be reached
854   assert(0);
855   return 0;
856 }
857
858 /* decodes the operands, return the total size in bytes of the operands */
859 static unsigned doOperands(unsigned operands[3],
860                     const unsigned operandSzAttr, const unsigned addrSzAttr,
861                     const unsigned Mod, const unsigned RM, const unsigned SIB)
862 {
863   unsigned size = 0;
864   if (operands[0]) {
865     size += doOperand(operands[0], operandSzAttr, addrSzAttr, Mod, RM, SIB);
866   }
867   if (operands[1]) {
868     size += doOperand(operands[1], operandSzAttr, addrSzAttr, Mod, RM, SIB);
869   }
870   if (operands[2]) {
871     size += doOperand(operands[2], operandSzAttr, addrSzAttr, Mod, RM, SIB);
872   }
873   return size;
874 }
875
876
877 unsigned get_instruction2(const unsigned char* addr, unsigned &insnType)
878 {
879   bool instrPrefix = false;
880   bool addrSzPrefix = false;
881   bool oprSzPrefix = false;
882   bool segOvrPrefix = false;
883
884   unsigned operandSzAttr = 2;
885   unsigned addrSzAttr = 2;
886
887   const unsigned char *nextb = addr;
888   x86_insn *desc;
889   x86_insn *descAux;
890   unsigned code;
891   unsigned ModRMbyte = 0;
892   unsigned Mod=0;
893   unsigned Reg=0;
894   unsigned RM=0;
895   unsigned SIB=0;
896   bool hasSIB;
897
898   insnType = 0;
899
900   // check prefixes
901   do {
902     desc = &oneByteMap[*nextb++];
903     code = desc->escape_code;
904     if (code == PREFIX_INSTR)
905       instrPrefix = true;
906     else if (code == PREFIX_ADDR_SZ)
907       addrSzPrefix = true;
908     else if (code == PREFIX_OPR_SZ)
909       oprSzPrefix = true;
910     else if (code == PREFIX_SEG_OVR)
911       segOvrPrefix = true;
912     else
913       // no more prefixes
914       break;
915   } while (true);
916
917   if (oprSzPrefix)
918     operandSzAttr = 1;
919   if (addrSzPrefix)
920     addrSzAttr = 1;
921
922   /* if it is a two byte opcode instruction, fetch the next opcode byte 
923      and decode using twoByteMap */
924   if (code == twoB) {
925     desc = &twoByteMap[*nextb++];
926     code = desc->escape_code;
927   }
928
929   // check if the instruction has Mod/RM and SIB bytes
930   if (desc->hasModRM) {
931     ModRMbyte = *nextb++;
932     Mod = ModRMbyte >> 6;
933     RM = ModRMbyte & 0x07;
934     Reg = (ModRMbyte >> 3) & 0x07;
935     hasSIB = (Mod != 3) && (RM == 4);
936     if (hasSIB) {
937       SIB = *nextb++;
938     }
939   }  
940
941   /* now decode the instruction */
942   switch (code) {
943   case oneB:
944   case twoB:
945     insnType = desc->insnType;
946     if (insnType & REL_X) {
947       // set the correct size for the operand
948       if (operandSzAttr == 1)
949         insnType |= REL_W;
950       else
951         insnType |= REL_D;
952     }
953     //assert(desc->name);
954     //printf("%s ", desc->name);
955     nextb += doOperands(desc->operands, operandSzAttr, addrSzAttr, Mod, RM, SIB);
956     break;
957
958   case Grp1:
959   case Grp2:
960   case Grp8:
961     // operands defined in oneByteMap
962     insnType = desc->insnType;
963     descAux = &groupMap[code][Reg];
964     //assert(descAux->name);
965     //printf("%s ", descAux->name);
966     nextb += doOperands(desc->operands, operandSzAttr, addrSzAttr, Mod, RM, SIB);
967     break;
968
969   case Grp3a:
970   case Grp3b:
971   case Grp4:
972   case Grp5:
973   case Grp6:
974   case Grp7:
975   case Grp9:
976     // operands defined in groupMap
977     descAux = &groupMap[code][Reg];
978     insnType = descAux->insnType;
979     //assert(descAux->name);
980     //printf("%s ", descAux->name);
981     nextb += doOperands(descAux->operands, operandSzAttr, addrSzAttr, Mod, RM, SIB);
982     break;
983
984   case coprocEsc:
985     insnType = 0;
986     //fprintf(stderr,"FP instruction %x\n", nextb);
987     if (ModRMbyte <= 0xBF) {
988       nextb += doModRMOperand(addrSzAttr, Mod, RM, SIB);
989     }
990     break;
991     
992   case Ill:
993     insnType = ILLEGAL;
994     break;
995
996   default:
997     // should not be reached
998     assert(0);
999     break;
1000   }
1001
1002   // set the correct size for the operand in insnType
1003   if (insnType & REL_X) {
1004     if (operandSzAttr == 1)
1005       insnType |= REL_W;
1006     else
1007       insnType |= REL_D;
1008   }
1009   else if (insnType & PTR_WX) {
1010     if (operandSzAttr == 1)
1011       insnType |= PTR_WW;
1012     else
1013       insnType |= PTR_WD;
1014   }
1015
1016   // set the prefix flags in insnType
1017   if (instrPrefix)
1018     insnType |= PREFIX_INST;
1019   if (addrSzPrefix)
1020     insnType |= PREFIX_ADDR;
1021   if (oprSzPrefix)
1022     insnType |= PREFIX_OPR;
1023   if (segOvrPrefix)
1024     insnType |= PREFIX_SEG;
1025
1026   return (nextb - addr);
1027 }
1028
1029 /* decode instruction at address addr, return size of instruction */
1030 unsigned get_instruction(const unsigned char* addr, unsigned &insnType)
1031 {
1032   int r1;
1033   unsigned insnType1;
1034
1035   ia32_instruction i;
1036 #if defined(i386_unknown_nt4_0) && _MSC_VER < 1300
1037   ia32_decode(0, addr, i);
1038 #else
1039   ia32_decode<0>(addr, i);
1040 #endif
1041   r1 = i.getSize();
1042   insnType1 = ia32_emulate_old_type(i);
1043
1044 #ifdef DEBUG_CMPDEC
1045   int r2;
1046   unsigned insnType2;
1047
1048   r2 = get_instruction2(addr, insnType2);
1049   if(r1 != r2) {
1050     fprintf(stderr, "[L] %d!=%d @ %p:", r1, r2, addr);
1051     for(int i=0; i<10; ++i)
1052       fprintf(stderr, " %x", addr[i]);
1053     fprintf(stderr, "\n");
1054   }
1055   if(insnType1 != insnType2) {
1056     fprintf(stderr, "[T] %x!=%x @ %p:", insnType1, insnType2, addr);
1057     for(int i=0; i<10; ++i)
1058       fprintf(stderr, " %x", addr[i]);
1059     fprintf(stderr, "\n");
1060   }
1061 #endif
1062
1063   insnType = insnType1;
1064   return r1;
1065 }
1066
1067
1068 /* CODE ADDED FOR FUNCTION RELOCATION */
1069
1070 /*************************************************************************/
1071 /*************************************************************************/
1072
1073 // find the target of a jump or call
1074
1075 Address get_target(const unsigned char *instr, unsigned type, unsigned size,
1076                                                               Address addr) {
1077   int disp = displacement(instr, type);
1078   return (Address)(addr + size + disp);
1079 }
1080
1081
1082 // get the displacement of a jump or call
1083
1084 int displacement(const unsigned char *instr, unsigned type) {
1085
1086   int disp = 0;
1087
1088   if (type & IS_JUMP) {
1089     if (type & REL_B) {
1090       disp = *(const char *)(instr+1);
1091     } else if (type & REL_W) {
1092       disp = *(const short *)(instr+2); // skip prefix and opcode
1093     } else if (type & REL_D) {
1094       disp = *(const int *)(instr+1);
1095     }
1096   } else if (type & IS_JCC) {
1097     if (type & REL_B) {
1098       disp = *(const char *)(instr+1);
1099     } else if (type & REL_W) {
1100       disp = *(const short *)(instr+3); // skip prefix and two byte opcode
1101     } else if (type & REL_D) {
1102       disp = *(const int *)(instr+2);   // skip two byte opcode
1103     }
1104   } else if (type & IS_CALL) {
1105     if (type & REL_W) {
1106       disp = *(const short *)(instr+2); // skip prefix and opcode
1107     } else if (type & REL_D) {
1108       disp = *(const int *)(instr+1);
1109     }
1110   }
1111   
1112   return disp;
1113 }
1114
1115
1116 // get the displacement of a relative jump or call
1117
1118 int get_disp(instruction *insn) {
1119   return displacement(insn->ptr(), insn->type());
1120 }
1121
1122
1123 // if setDisp is true set the target of a relative jump or call insn
1124 // otherwise, return the number of bytes needed to expand the present 
1125 // instruction so that its target is in the range of its displacement. 
1126 // In cases where we have a short near jump out of the function, we always 
1127 // want to expand it to a 4 byte jump
1128
1129 int set_disp(bool setDisp, instruction *insn, int newOffset, bool outOfFunc) {
1130
1131   unsigned char *instr = (const_cast<unsigned char *> (insn->ptr()));
1132   unsigned type = insn->type();
1133
1134   if (!((type & IS_JUMP) || (type & IS_JCC) || (type & IS_CALL))) return 0; 
1135   
1136   if (type & IS_CALL) {
1137     if (type & REL_W) {
1138       if (outOfFunc) {
1139         return 2;  // go from 3 to 5 bytes;
1140       } else { 
1141           if (setDisp) {
1142             instr++;
1143             *((short *) instr) = (short) newOffset;
1144           }
1145           else return 0;
1146       }
1147     } else { 
1148         if (type & REL_D) {
1149           if (setDisp) {
1150             instr++;
1151             *((int *) instr) = (int) newOffset;
1152           }
1153           else return 0;
1154         }
1155     }
1156     return 0;
1157   }
1158  
1159   // assert((type & IS_JUMP) || (type & IS_JCC));
1160
1161   if (type & REL_B) {
1162     if (*instr == JCXZ) {
1163       if (newOffset > 127 || newOffset < -128 || outOfFunc) {
1164         return 7;  // go from 2 to 9 bytes
1165       } else {
1166           if (setDisp) { 
1167             instr++;
1168             *((char *) instr) = (char) newOffset;
1169           }
1170           else return 0;
1171       }
1172     } else {
1173         if (type & IS_JCC) {
1174           if (newOffset > 127 || newOffset < -128 || outOfFunc) {
1175             return 4;  // go from 2 to 6 bytes
1176           } else {
1177               if (setDisp) {
1178                 instr++; 
1179                 *((char *) instr) = (char) newOffset;
1180               }
1181               else return 0;
1182           }
1183         } else {
1184             if (type & IS_JUMP) {
1185               if (newOffset > 127 || newOffset < -128 || outOfFunc) {
1186                 return 3;  // go from 2 to 5 bytes
1187               } else {
1188                   if (setDisp) {
1189                     instr++;
1190                     *((char *) instr) = (char) newOffset;
1191                   }
1192                   else return 0;
1193               }
1194             }
1195         } 
1196     }   
1197   } else {
1198       if (type & REL_W) {
1199         if (newOffset > 32767 || newOffset < -32768 || outOfFunc) {
1200           return 1;  // drop the PREFIX_OPR, add 2 bytes for disp
1201         } else {
1202             if (setDisp) {
1203               if (type & PREFIX_OPR)
1204                 instr++;
1205               if (type & PREFIX_SEG)
1206                 instr++;
1207               instr++; 
1208               *((short *) instr) = (short) newOffset;
1209             } else return 0;
1210         }
1211       } else {
1212           if (setDisp) {
1213             if (type & REL_D) {
1214               if (type & PREFIX_SEG)
1215                 instr++;
1216               if (*instr == 0x0F)
1217                 instr++;
1218               instr++; 
1219               *((int *) instr) = (int) newOffset;
1220             } 
1221           } else return 0;               
1222       }
1223   }
1224   return 0;
1225 }
1226
1227 int addressOfMachineInsn(instruction *insn) {
1228   return (int)insn->ptr();
1229 }
1230
1231 int sizeOfMachineInsn(instruction *insn) {
1232   return insn->size();
1233 }
1234
1235 /*********************************************************************/
1236 /*********************************************************************/
1237
1238
1239
1240 //This function decodes the addressing modes used for call instructions
1241 //For documentation on these mode, and how to decode them, see tables
1242 //2-2 and 2-3 from the intel software developers manual.
1243 int get_instruction_operand(const unsigned char *ptr, Register& base_reg,
1244                             Register& index_reg, int& displacement, 
1245                             unsigned& scale, unsigned &Mod){
1246   x86_insn *desc;
1247   unsigned code;
1248   unsigned ModRMbyte;
1249   unsigned RM=0;
1250   unsigned REG;
1251   unsigned SIBbyte = 0;
1252   bool hasSIB;
1253   //Initialize default values to an appropriately devilish number 
1254   base_reg = 666;
1255   index_reg = 666;
1256   displacement = 0;
1257   scale = 0;
1258   Mod = 0;
1259
1260   do {
1261     desc = &oneByteMap[*ptr++];
1262     code = desc->escape_code;
1263     if (code == PREFIX_INSTR 
1264         || code == PREFIX_ADDR_SZ
1265         || code == PREFIX_OPR_SZ
1266         || code == PREFIX_SEG_OVR){
1267       
1268       //We do not have support for handling the prefixes of x86 instructions
1269       return -1;
1270     }
1271     else
1272       // no more prefixes
1273       break;
1274   } while (true);
1275   
1276   if (code != Grp5) {
1277     //We should never get here, there should never be a non group5
1278     //indirect call instruction
1279     return -1;
1280   }
1281   
1282   //If the instruction has a mod/rm byte
1283   if (desc->hasModRM) {
1284     ModRMbyte = *ptr++;
1285     Mod = ModRMbyte >> 6;
1286     RM = ModRMbyte & 0x07;
1287     REG = (ModRMbyte >> 3) & 0x07;
1288     hasSIB = (Mod != 3) && (RM == 4);
1289     if (hasSIB) {
1290       SIBbyte = *ptr++;
1291     }
1292
1293     if(REG == 2){
1294       if (Mod == 3){ //Standard call where address is in register
1295         base_reg = (Register) RM;
1296         return REGISTER_DIRECT;
1297       }
1298       else if (Mod == 2){
1299         displacement = *( ( const unsigned int * ) ptr );
1300         ptr+= wordSzB;
1301         if(hasSIB){
1302           decode_SIB(SIBbyte, scale, index_reg, base_reg);
1303           return SIB;
1304         }       
1305         else {
1306           base_reg = (Register) RM;
1307           return REGISTER_INDIRECT_DISPLACED; 
1308         }
1309       }
1310       else if(Mod == 1){//call with 8-bit signed displacement
1311         displacement = *( const char * )ptr;
1312         ptr+= byteSzB;
1313         if(hasSIB){
1314           decode_SIB(SIBbyte, scale, index_reg, base_reg);
1315           return SIB;
1316         }
1317         else {
1318           base_reg = (Register) RM;
1319           return REGISTER_INDIRECT_DISPLACED; 
1320         }
1321       }
1322       else if(Mod == 0){
1323         if(hasSIB){
1324           decode_SIB(SIBbyte, scale, index_reg, base_reg);
1325           if(base_reg == 5){
1326             displacement = *( ( const unsigned int * )ptr );
1327             ptr+= wordSzB;
1328           }
1329           else 
1330             displacement = 0;
1331           return SIB;
1332         }
1333         else if(RM == 5){ //The disp32 field from Table 2-2 of IA guide
1334           displacement = *( ( const unsigned int * ) ptr );
1335           ptr+= wordSzB;
1336           return DISPLACED;
1337         }
1338         else {
1339           base_reg = (Register) RM;
1340           return REGISTER_INDIRECT;
1341         }
1342       }
1343     }
1344     else if(REG==3){ 
1345       //The call instruction is a far call, for which there
1346       //is no monitoring code
1347       return -1;
1348     }
1349     else assert(0);
1350   }
1351   
1352
1353   return -1;
1354 }  
1355
1356 //Determine appropriate scale, index, and base given SIB byte.
1357 void decode_SIB(unsigned sib, unsigned& scale, Register& index_reg, Register& base_reg){
1358   scale = sib >> 6;
1359   
1360   //scale = 2^scale
1361   if(scale == 0)
1362     scale = 1;
1363   else if(scale == 1)
1364     scale = 2;
1365   else if(scale == 2)
1366     scale = 4;
1367   else if(scale == 3)
1368     scale = 8;
1369
1370   index_reg = (sib >> 3) & 0x07;
1371   base_reg = sib & 0x07;
1372 }
1373
1374 const unsigned char*
1375 skip_headers(const unsigned char* addr, bool& isWordAddr,bool& isWordOp)
1376 {
1377   isWordAddr = false;
1378   isWordOp = false;
1379
1380   ia32_prefixes prefs;
1381
1382   ia32_decode_prefixes(addr, prefs);
1383   if(prefs.getPrefix(2) == PREFIX_SZOPER)
1384     isWordOp = true;
1385   if(prefs.getPrefix(3) == PREFIX_SZADDR)
1386     isWordAddr = true;
1387   return addr+prefs.getCount();
1388 }
1389
1390 bool insn_hasSIB(unsigned ModRMbyte,unsigned& Mod,unsigned& Reg,unsigned& RM){
1391     Mod = (ModRMbyte >> 6) & 0x03;
1392     Reg = (ModRMbyte >> 3) & 0x07;
1393     RM = ModRMbyte & 0x07;
1394     return ((Mod != 3) && ((RM == 4) || (RM == 5)));
1395 }