Added a variety of instructions including non-volatile memory (prefetch).
[dyninst.git] / instructionAPI / src / InstructionDecoder-x86.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #define INSIDE_INSTRUCTION_API
32
33 #include "common/src/Types.h"
34 #include "InstructionDecoder-x86.h"
35 #include "Expression.h"
36 #include "common/src/arch-x86.h"
37 #include "Register.h"
38 #include "Dereference.h"
39 #include "Immediate.h" 
40 #include "BinaryFunction.h"
41 #include "common/src/singleton_object_pool.h"
42
43 // #define VEX_DEBUG
44
45 using namespace std;
46 using namespace NS_x86;
47 namespace Dyninst
48 {
49     namespace InstructionAPI
50     {
51     
52         bool readsOperand(unsigned int opsema, unsigned int i)
53         {
54             switch(opsema) {
55                 case s1R2R:
56                     return (i == 0 || i == 1);
57                 case s1R:
58                 case s1RW:
59                     return i == 0;
60                 case s1W:
61                     return false;
62                 case s1W2RW:
63                 case s1W2R:   // second operand read, first operand written (e.g. mov)
64                     return i == 1;
65                 case s1RW2R:  // two operands read, first written (e.g. add)
66                 case s1RW2RW: // e.g. xchg
67                 case s1R2RW:
68                     return i == 0 || i == 1;
69                 case s1W2R3R: // e.g. imul
70                 case s1W2RW3R: // some mul
71                 case s1W2R3RW: // (stack) push & pop
72                     return i == 1 || i == 2;
73                 case s1W2W3R: // e.g. les
74                     return i == 2;
75                 case s1RW2R3RW:
76                 case s1RW2R3R: // shld/shrd
77                 case s1RW2RW3R: // [i]div, cmpxch8b
78                 case s1R2R3R:
79                     return i == 0 || i == 1 || i == 2;
80                 case s1W2R3R4R:
81                     return i == 1 || i == 2 || i == 3;
82                 case s1RW2R3R4R:
83                     return i == 0 || i == 1 || i == 2 || i == 3;
84                 case sNONE:
85                 default:
86                     return false;
87             }
88       
89         }
90       
91         bool writesOperand(unsigned int opsema, unsigned int i)
92         {
93             switch(opsema) {
94                 case s1R2R:
95                 case s1R:
96                     return false;
97                 case s1RW:
98                 case s1W:
99                 case s1W2R:   // second operand read, first operand written (e.g. mov)
100                 case s1RW2R:  // two operands read, first written (e.g. add)
101                 case s1W2R3R: // e.g. imul
102                 case s1RW2R3R: // shld/shrd
103                 case s1RW2R3R4R:
104                   return i == 0;
105                 case s1R2RW:
106                   return i == 1;
107                 case s1W2RW:
108                 case s1RW2RW: // e.g. xchg
109                 case s1W2RW3R: // some mul
110                 case s1W2W3R: // e.g. les
111                 case s1RW2RW3R: // [i]div, cmpxch8b
112                   return i == 0 || i == 1;
113                 case s1W2R3RW: // (stack) push & pop
114                   return i == 0 || i == 2;
115                 case s1RW2R3RW:
116                   return i == 0 || i == 2;
117                 case sNONE:
118                 default:
119                     return false;
120             }
121         }
122
123
124     __thread NS_x86::ia32_instruction* InstructionDecoder_x86::decodedInstruction = NULL;
125     __thread ia32_locations* InstructionDecoder_x86::locs = NULL;
126     __thread bool InstructionDecoder_x86::sizePrefixPresent = false;
127     __thread bool InstructionDecoder_x86::addrSizePrefixPresent = false;
128     INSTRUCTION_EXPORT InstructionDecoder_x86::InstructionDecoder_x86(Architecture a) :
129       InstructionDecoderImpl(a)
130     {
131       if(a == Arch_x86_64) setMode(true);
132       
133     }
134     INSTRUCTION_EXPORT InstructionDecoder_x86::~InstructionDecoder_x86()
135     {
136
137     }
138     static const unsigned char modrm_use_sib = 4;
139     
140     INSTRUCTION_EXPORT void InstructionDecoder_x86::setMode(bool is64)
141     {
142         ia32_set_mode_64(is64);
143     }
144     
145       Expression::Ptr InstructionDecoder_x86::makeSIBExpression(const InstructionDecoder::buffer& b)
146     {
147         unsigned scale;
148         Register index;
149         Register base;
150         Result_Type registerType = ia32_is_mode_64() ? u64 : u32;
151
152         int op_type = ia32_is_mode_64() ? op_q : op_d;
153         decode_SIB(locs->sib_byte, scale, index, base);
154
155         Expression::Ptr scaleAST(make_shared(singleton_object_pool<Immediate>::construct(Result(u8, dword_t(scale)))));
156         Expression::Ptr indexAST(make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(index, op_type,
157                                     locs->rex_x))));
158         Expression::Ptr baseAST;
159         if(base == 0x05)
160         {
161             switch(locs->modrm_mod)
162             {
163                 case 0x00:
164                     baseAST = decodeImmediate(op_d, b.start + locs->sib_position + 1, true);
165                     break;
166                 case 0x01: 
167                 case 0x02: 
168                     baseAST = make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(base, 
169                                                                                                op_type,
170                                                                                                locs->rex_b)));
171                     break;
172                 case 0x03:
173                 default:
174                     assert(0);
175                     break;
176             };
177         }
178         else
179         {
180             baseAST = make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(base, 
181                                                                                                op_type,
182                                                                                                locs->rex_b)));
183         }
184
185         if(index == 0x04 && (!(ia32_is_mode_64()) || !(locs->rex_x)))
186         {
187             return baseAST;
188         }
189         return makeAddExpression(baseAST, makeMultiplyExpression(indexAST, scaleAST, registerType), registerType);
190     }
191
192       Expression::Ptr InstructionDecoder_x86::makeModRMExpression(const InstructionDecoder::buffer& b,
193                                                                   unsigned int opType)
194     {
195        unsigned int regType = op_d;
196        Result_Type aw;
197        if(ia32_is_mode_64())
198        {
199            if(addrSizePrefixPresent) {
200                aw = u32;
201            } else {
202                aw = u64;
203                regType = op_q;
204            }
205        }
206        else
207        {
208            if(!addrSizePrefixPresent) {
209                aw = u32;
210            } else {
211                aw = u16;
212                regType = op_w;
213            }
214        }
215         if (opType == op_lea) {
216             // For an LEA, aw (address width) is insufficient, use makeSizeType
217             aw = makeSizeType(opType);
218         }
219         Expression::Ptr e =
220             makeRegisterExpression(makeRegisterID(locs->modrm_rm, regType, locs->rex_b));
221         switch(locs->modrm_mod)
222         {
223             case 0:
224                 if(locs->modrm_rm == modrm_use_sib) {
225                     e = makeSIBExpression(b);
226                 }
227                 if(locs->modrm_rm == 0x5 && !addrSizePrefixPresent)
228                 {
229                     assert(locs->opcode_position > -1);
230                     if(ia32_is_mode_64())
231                     {
232                         e = makeAddExpression(makeRegisterExpression(x86_64::rip),
233                                             getModRMDisplacement(b), aw);
234                     }
235                     else
236                     {
237                         e = getModRMDisplacement(b);
238                     }
239         
240                 }
241                 if(locs->modrm_rm == 0x6 && addrSizePrefixPresent)
242                 {
243                     e = getModRMDisplacement(b);
244                 }
245                 if(opType == op_lea)
246                 {
247                     return e;
248                 }
249                 return makeDereferenceExpression(e, makeSizeType(opType));
250                 assert(0);
251                 break;
252             case 1:
253             case 2:
254             {
255                 if(locs->modrm_rm == modrm_use_sib) {
256                     e = makeSIBExpression(b);
257                 }
258                 Expression::Ptr disp_e = makeAddExpression(e, getModRMDisplacement(b), aw);
259                 if(opType == op_lea)
260                 {
261                     return disp_e;
262                 }
263                 return makeDereferenceExpression(disp_e, makeSizeType(opType));
264             }
265             assert(0);
266             break;
267             case 3:
268                 return makeRegisterExpression(makeRegisterID(locs->modrm_rm, opType, locs->rex_b));
269             default:
270                 return Expression::Ptr();
271         
272         };
273         // can't get here, but make the compiler happy...
274         assert(0);
275         return Expression::Ptr();
276     }
277
278     Expression::Ptr InstructionDecoder_x86::decodeImmediate(unsigned int opType, const unsigned char* immStart, 
279                                                             bool isSigned)
280     {
281         // rex_w indicates we need to sign-extend also.
282         isSigned = isSigned || locs->rex_w;
283         
284         switch(opType)
285         {
286             case op_b:
287                 return Immediate::makeImmediate(Result(isSigned ? s8 : u8 ,*(const byte_t*)(immStart)));
288                 break;
289             case op_d:
290                 return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
291             case op_w:
292                 return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
293                 break;
294             case op_q:
295                 return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
296                 break;
297             case op_v:
298                 if (locs->rex_w || isDefault64Insn()) {
299                     return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
300                 }
301                 //if(!sizePrefixPresent)
302                 //{
303                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
304                     //}
305                     //else
306                     //{
307                     //return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
308                     //}
309                 break;
310             case op_z:
311                 // 32 bit mode & no prefix, or 16 bit mode & prefix => 32 bit
312                 // 16 bit mode, no prefix or 32 bit mode, prefix => 16 bit
313                 //if(!addrSizePrefixPresent)
314                 //{
315                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
316                     //}
317                     //else
318                     //{
319                     //return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
320                     //}
321                 break;
322             case op_p:
323                 // 32 bit mode & no prefix, or 16 bit mode & prefix => 48 bit
324                 // 16 bit mode, no prefix or 32 bit mode, prefix => 32 bit
325                 if(!sizePrefixPresent)
326                 {
327                     return Immediate::makeImmediate(Result(isSigned ? s48 : u48,*(const int64_t*)(immStart)));
328                 }
329                 else
330                 {
331                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
332                 }
333
334                 break;
335             case op_a:
336             case op_dq:
337             case op_pd:
338             case op_ps:
339             case op_s:
340             case op_si:
341             case op_lea:
342             case op_allgprs:
343             case op_512:
344             case op_c:
345                 assert(!"Can't happen: opType unexpected for valid ways to decode an immediate");
346                 return Expression::Ptr();
347             default:
348                 assert(!"Can't happen: opType out of range");
349                 return Expression::Ptr();
350         }
351     }
352     
353     Expression::Ptr InstructionDecoder_x86::getModRMDisplacement(const InstructionDecoder::buffer& b)
354     {
355         int disp_pos;
356
357         if(locs->sib_position != -1)
358         {
359             disp_pos = locs->sib_position + 1;
360         }
361         else
362         {
363             disp_pos = locs->modrm_position + 1;
364         }
365         switch(locs->modrm_mod)
366         {
367             case 1:
368                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, (*(const byte_t*)(b.start +
369                         disp_pos)))));
370                 break;
371             case 2:
372                 if(0 && sizePrefixPresent)
373                 {
374                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s16, *((const word_t*)(b.start +
375                             disp_pos)))));
376                 }
377                 else
378                 {
379                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s32, *((const dword_t*)(b.start +
380                             disp_pos)))));
381                 }
382                 break;
383             case 0:
384                 // In 16-bit mode, the word displacement is modrm r/m 6
385                 if(sizePrefixPresent && !ia32_is_mode_64())
386                 {
387                     if(locs->modrm_rm == 6)
388                     {
389                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s16,
390                                            *((const dword_t*)(b.start + disp_pos)))));
391                     }
392                     // TODO FIXME; this was decoding wrong, but I'm not sure
393                     // why...
394                     else if (locs->modrm_rm == 5) {
395                         assert(b.start + disp_pos + 4 <= b.end);
396                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s32,
397                                            *((const dword_t*)(b.start + disp_pos)))));
398                     } else {
399                         assert(b.start + disp_pos + 1 <= b.end);
400                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
401                     }
402                     break;
403                 }
404                 // ...and in 32-bit mode, the dword displacement is modrm r/m 5
405                 else
406                 {
407                     if(locs->modrm_rm == 5)
408                     {
409                         if (b.start + disp_pos + 4 <= b.end) 
410                             return make_shared(singleton_object_pool<Immediate>::construct(Result(s32,
411                                                *((const dword_t*)(b.start + disp_pos)))));
412                         else
413                             return make_shared(singleton_object_pool<Immediate>::construct(Result()));
414                     }
415                     else
416                     {
417                         if (b.start + disp_pos + 1 <= b.end)
418                             return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
419                         else
420                             return make_shared(singleton_object_pool<Immediate>::construct(Result()));
421                     }
422                     break;
423                 }
424             default:
425                 assert(b.start + disp_pos + 1 <= b.end);
426                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
427                 break;
428         }
429     }
430
431     enum intelRegBanks
432     {
433         b_8bitNoREX = 0,
434         b_16bit,
435         b_32bit,
436         b_segment,
437         b_64bit,
438         b_xmm_set0, /* XMM0 -> XMM 7 */
439         b_xmm_set1, /* XMM8 -> XMM 15 */
440         b_xmm_set2, /* XMM16 -> XMM 23 */
441         b_xmm_set3, /* XMM24 -> XMM 31 */
442         b_ymm_set0, /* YMM0 -> YMM 7 */
443         b_ymm_set1, /* YMM8 -> YMM 15 */
444         b_ymm_set2, /* YMM16 -> YMM 23 */
445         b_ymm_set3, /* YMM24 -> YMM 31 */
446         b_zmm_set0, /* ZMM0 -> ZMM 7 */
447         b_zmm_set1, /* ZMM8 -> ZMM 15 */
448         b_zmm_set2, /* ZMM16 -> ZMM 23 */
449         b_zmm_set3, /* ZMM24 -> ZMM 31 */
450                 b_kmask,
451         b_mm,
452         b_cr,
453         b_dr,
454         b_tr,
455         b_amd64ext,
456         b_8bitWithREX,
457         b_fpstack,
458             amd64_ext_8,
459             amd64_ext_16,
460             amd64_ext_32,
461
462         b_invalid /* should remain the final entry */
463     };
464
465     static MachRegister IntelRegTable32[][8] = {
466         { x86::al, x86::cl, x86::dl, x86::bl, x86::ah, x86::ch, x86::dh, x86::bh }, /* b_8bitNoREX */
467         { x86::ax, x86::cx, x86::dx, x86::bx, x86::sp, x86::bp, x86::si, x86::di }, /* b_16bit */
468         { x86::eax, x86::ecx, x86::edx, x86::ebx, x86::esp, x86::ebp, x86::esi, x86::edi }, /* b_32bit */
469         { x86::es, x86::cs, x86::ss, x86::ds, x86::fs, x86::gs, InvalidReg, InvalidReg }, /* b_segment */
470         { x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi }, /* b_64bit */
471         { x86::xmm0, x86::xmm1, x86::xmm2, x86::xmm3, x86::xmm4, x86::xmm5, x86::xmm6, x86::xmm7 }, /* b_xmm_set0 */
472         { x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15 }, /* b_xmm_set1 */
473         { x86_64::xmm16, x86_64::xmm17, x86_64::xmm18, x86_64::xmm19, x86_64::xmm20, x86_64::xmm21, x86_64::xmm22, x86_64::xmm23 }, /* b_xmm_set2 */
474         { x86_64::xmm24, x86_64::xmm25, x86_64::xmm26, x86_64::xmm27, x86_64::xmm28, x86_64::xmm29, x86_64::xmm30, x86_64::xmm31 }, /* b_xmm_set3 */
475         { x86_64::ymm0, x86_64::ymm1, x86_64::ymm2, x86_64::ymm3, x86_64::ymm4, x86_64::ymm5, x86_64::ymm6, x86_64::ymm7 }, /* b_ymm_set0 */
476         { x86_64::ymm8, x86_64::ymm9, x86_64::ymm10, x86_64::ymm11, x86_64::ymm12, x86_64::ymm13, x86_64::ymm14, x86_64::ymm15 }, /* b_ymm_set1 */
477         { x86_64::ymm16, x86_64::ymm17, x86_64::ymm18, x86_64::ymm19, x86_64::ymm20, x86_64::ymm21, x86_64::ymm22, x86_64::ymm23 }, /* b_ymm_set2 */
478         { x86_64::ymm24, x86_64::ymm25, x86_64::ymm26, x86_64::ymm27, x86_64::ymm28, x86_64::ymm29, x86_64::ymm30, x86_64::ymm31 }, /* b_ymm_set3 */
479         { x86_64::zmm0, x86_64::zmm1, x86_64::zmm2, x86_64::zmm3, x86_64::zmm4, x86_64::zmm5, x86_64::zmm6, x86_64::zmm7 }, /* b_zmm_set0 */
480         { x86_64::zmm8, x86_64::zmm9, x86_64::zmm10, x86_64::zmm11, x86_64::zmm12, x86_64::zmm13, x86_64::zmm14, x86_64::zmm15 }, /* b_zmm_set1 */
481         { x86_64::zmm16, x86_64::zmm17, x86_64::zmm18, x86_64::zmm19, x86_64::zmm20, x86_64::zmm21, x86_64::zmm22, x86_64::zmm23 }, /* b_zmm_set2 */
482         { x86_64::zmm24, x86_64::zmm25, x86_64::zmm26, x86_64::zmm27, x86_64::zmm28, x86_64::zmm29, x86_64::zmm30, x86_64::zmm31 }, /* b_zmm_set3 */
483                 { x86_64::k0, x86_64::k1, x86_64::k2, x86_64::k3, x86_64::k4, x86_64::k5, x86_64::k6, x86_64::k7 },
484         { x86::mm0, x86::mm1, x86::mm2, x86::mm3, x86::mm4, x86::mm5, x86::mm6, x86::mm7 },
485         { x86::cr0, x86::cr1, x86::cr2, x86::cr3, x86::cr4, x86::cr5, x86::cr6, x86::cr7 },
486         { x86::dr0, x86::dr1, x86::dr2, x86::dr3, x86::dr4, x86::dr5, x86::dr6, x86::dr7 },
487         { x86::tr0, x86::tr1, x86::tr2, x86::tr3, x86::tr4, x86::tr5, x86::tr6, x86::tr7 },
488         { x86_64::r8, x86_64::r9, x86_64::r10, x86_64::r11, x86_64::r12, x86_64::r13, x86_64::r14, x86_64::r15 },
489         { x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil },
490         { x86::st0, x86::st1, x86::st2, x86::st3, x86::st4, x86::st5, x86::st6, x86::st7 }
491     };
492
493     static MachRegister IntelRegTable64[][8] = {
494         { x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::ah, x86_64::ch, x86_64::dh, x86_64::bh },
495         { x86_64::ax, x86_64::cx, x86_64::dx, x86_64::bx, x86_64::sp, x86_64::bp, x86_64::si, x86_64::di },
496         { x86_64::eax, x86_64::ecx, x86_64::edx, x86_64::ebx, x86_64::esp, x86_64::ebp, x86_64::esi, x86_64::edi },
497         { x86_64::es, x86_64::cs, x86_64::ss, x86_64::ds, x86_64::fs, x86_64::gs, InvalidReg, InvalidReg },
498         { x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi },
499         { x86_64::xmm0, x86_64::xmm1, x86_64::xmm2, x86_64::xmm3, x86_64::xmm4, x86_64::xmm5, x86_64::xmm6, x86_64::xmm7 }, /* b_xmm_set0 */
500         { x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15 }, /* b_xmm_set1 */
501         { x86_64::xmm16, x86_64::xmm17, x86_64::xmm18, x86_64::xmm19, x86_64::xmm20, x86_64::xmm21, x86_64::xmm22, x86_64::xmm23 }, /* b_xmm_set2 */
502         { x86_64::xmm24, x86_64::xmm25, x86_64::xmm26, x86_64::xmm27, x86_64::xmm28, x86_64::xmm29, x86_64::xmm30, x86_64::xmm31 }, /* b_xmm_set3 */
503         { x86_64::ymm0, x86_64::ymm1, x86_64::ymm2, x86_64::ymm3, x86_64::ymm4, x86_64::ymm5, x86_64::ymm6, x86_64::ymm7 }, /* b_ymm_set0 */
504         { x86_64::ymm8, x86_64::ymm9, x86_64::ymm10, x86_64::ymm11, x86_64::ymm12, x86_64::ymm13, x86_64::ymm14, x86_64::ymm15 }, /* b_ymm_set1 */
505         { x86_64::ymm16, x86_64::ymm17, x86_64::ymm18, x86_64::ymm19, x86_64::ymm20, x86_64::ymm21, x86_64::ymm22, x86_64::ymm23 }, /* b_ymm_set2 */
506         { x86_64::ymm24, x86_64::ymm25, x86_64::ymm26, x86_64::ymm27, x86_64::ymm28, x86_64::ymm29, x86_64::ymm30, x86_64::ymm31 }, /* b_ymm_set3 */
507         { x86_64::zmm0, x86_64::zmm1, x86_64::zmm2, x86_64::zmm3, x86_64::zmm4, x86_64::zmm5, x86_64::zmm6, x86_64::zmm7 }, /* b_zmm_set0 */
508         { x86_64::zmm8, x86_64::zmm9, x86_64::zmm10, x86_64::zmm11, x86_64::zmm12, x86_64::zmm13, x86_64::zmm14, x86_64::zmm15 }, /* b_zmm_set1 */
509         { x86_64::zmm16, x86_64::zmm17, x86_64::zmm18, x86_64::zmm19, x86_64::zmm20, x86_64::zmm21, x86_64::zmm22, x86_64::zmm23 }, /* b_zmm_set2 */
510         { x86_64::zmm24, x86_64::zmm25, x86_64::zmm26, x86_64::zmm27, x86_64::zmm28, x86_64::zmm29, x86_64::zmm30, x86_64::zmm31 }, /* b_zmm_set3 */
511                 { x86_64::k0, x86_64::k1, x86_64::k2, x86_64::k3, x86_64::k4, x86_64::k5, x86_64::k6, x86_64::k7 },
512         { x86_64::mm0, x86_64::mm1, x86_64::mm2, x86_64::mm3, x86_64::mm4, x86_64::mm5, x86_64::mm6, x86_64::mm7 },
513         { x86_64::cr0, x86_64::cr1, x86_64::cr2, x86_64::cr3, x86_64::cr4, x86_64::cr5, x86_64::cr6, x86_64::cr7 },
514         { x86_64::dr0, x86_64::dr1, x86_64::dr2, x86_64::dr3, x86_64::dr4, x86_64::dr5, x86_64::dr6, x86_64::dr7 },
515         { x86_64::tr0, x86_64::tr1, x86_64::tr2, x86_64::tr3, x86_64::tr4, x86_64::tr5, x86_64::tr6, x86_64::tr7 },
516         { x86_64::r8, x86_64::r9, x86_64::r10, x86_64::r11, x86_64::r12, x86_64::r13, x86_64::r14, x86_64::r15 },
517         { x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil },
518         { x86_64::st0, x86_64::st1, x86_64::st2, x86_64::st3, x86_64::st4, x86_64::st5, x86_64::st6, x86_64::st7 },
519             { x86_64::r8b, x86_64::r9b, x86_64::r10b, x86_64::r11b, x86_64::r12b, x86_64::r13b, x86_64::r14b, x86_64::r15b },
520             { x86_64::r8w, x86_64::r9w, x86_64::r10w, x86_64::r11w, x86_64::r12w, x86_64::r13w, x86_64::r14w, x86_64::r15w },
521             { x86_64::r8d, x86_64::r9d, x86_64::r10d, x86_64::r11d, x86_64::r12d, x86_64::r13d, x86_64::r14d, x86_64::r15d },
522     };
523
524   /* Uses the appropriate lookup table based on the 
525      decoder architecture */
526   class IntelRegTable_access {
527     public:
528         inline MachRegister operator()(Architecture arch,
529                                        intelRegBanks bank,
530                                        int index)
531         {
532             assert(index >= 0 && index < 8);
533     
534             if(arch == Arch_x86_64)
535                 return IntelRegTable64[bank][index];
536             else if(arch == Arch_x86) 
537             {
538               if(bank > b_fpstack) return InvalidReg;
539               return IntelRegTable32[bank][index];
540             }
541             assert(0);
542             return InvalidReg;
543         }
544
545   };
546   static IntelRegTable_access IntelRegTable;
547
548       bool InstructionDecoder_x86::isDefault64Insn()
549       {
550         switch(m_Operation->getID())
551         {
552         case e_jmp:
553         case e_pop:
554         case e_push:
555         case e_call:
556           return true;
557         default:
558           return false;
559         }
560         
561       }
562       
563
564     MachRegister InstructionDecoder_x86::makeRegisterID(unsigned int intelReg, unsigned int opType,
565                                         bool isExtendedReg)
566     {
567         MachRegister retVal;
568         
569
570         if(isExtendedReg)
571         {
572             switch(opType)
573             {
574                 case op_q:  
575                     retVal = IntelRegTable(m_Arch,b_amd64ext,intelReg);
576                     break;
577                 case op_d:
578                     retVal = IntelRegTable(m_Arch,amd64_ext_32,intelReg);
579                     break;
580                 case op_w:
581                     retVal = IntelRegTable(m_Arch,amd64_ext_16,intelReg);
582                     break;
583                 case op_b:
584                     retVal = IntelRegTable(m_Arch,amd64_ext_8,intelReg);
585                     break;
586                 case op_v:
587                     if (locs->rex_w || isDefault64Insn())
588                         retVal = IntelRegTable(m_Arch, b_amd64ext, intelReg);
589                     else if (!sizePrefixPresent)
590                         retVal = IntelRegTable(m_Arch, amd64_ext_32, intelReg);
591                     //else
592                     //    retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
593                     break;      
594                 case op_p:
595                 case op_z:
596                     //              if (!sizePrefixPresent)
597                         retVal = IntelRegTable(m_Arch, amd64_ext_32, intelReg);
598                         //                  else
599                         //  retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
600                     break;
601             case op_f:
602             case op_dbl:
603                 // extended reg ignored on FP regs
604                 retVal = IntelRegTable(m_Arch, b_fpstack,intelReg);
605                 break;
606                 default:
607                     retVal = InvalidReg;
608             }
609         }
610         /* Promotion to 64-bit only applies to the operand types
611            that are varible (c,v,z). Ignoring c and z because they
612            do the right thing on 32- and 64-bit code.
613         else if(locs->rex_w)
614         {
615             // AMD64 with 64-bit operands
616             retVal = IntelRegTable[b_64bit][intelReg];
617         }
618         */
619         else
620         {
621             switch(opType)
622             {
623                 case op_v:
624                   if(locs->rex_w || isDefault64Insn())
625                         retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
626                     else
627                         retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
628                     break;
629                 case op_b:
630                     if (locs->rex_byte & 0x40) {
631                         retVal = IntelRegTable(m_Arch,b_8bitWithREX,intelReg);
632                     } else {
633                         retVal = IntelRegTable(m_Arch,b_8bitNoREX,intelReg);
634                     }
635                     break;
636                 case op_q:
637                     retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
638                     break;
639                 case op_w:
640                     retVal = IntelRegTable(m_Arch,b_16bit,intelReg);
641                     break;
642                 case op_f:
643                 case op_dbl:
644                     retVal = IntelRegTable(m_Arch,b_fpstack,intelReg);
645                     break;
646                 case op_d:
647                 case op_si:
648                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
649                     break;
650                 default:
651                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
652                     break;
653             }
654         }
655
656         if (!ia32_is_mode_64()) {
657           if ((retVal.val() & 0x00ffffff) == 0x0001000c)
658             assert(0);
659         }
660
661         return MachRegister((retVal.val() & ~retVal.getArchitecture()) | m_Arch);
662     }
663     
664     Result_Type InstructionDecoder_x86::makeSizeType(unsigned int opType)
665     {
666         switch(opType)
667         {
668             case op_b:
669             case op_c:
670                 return u8;
671             case op_d:
672             case op_ss:
673             case op_allgprs:
674             case op_si:
675                 return u32;
676             case op_w:
677             case op_a:
678                 return u16;
679             case op_q:
680             case op_sd:
681                 return u64;
682             case op_v:
683             case op_lea:
684             case op_z:
685                 if (locs->rex_w) 
686                 {
687                     return u64;
688                 }
689                 //if(ia32_is_mode_64() || !sizePrefixPresent)
690                 //{
691                     return u32;
692                     //}
693                     //else
694                     //{
695                     //return u16;
696                     //}
697                 break;
698             case op_y:
699                 if(ia32_is_mode_64())
700                         return u64;
701                 else
702                         return u32;
703                 break;
704             case op_p:
705                 // book says operand size; arch-x86 says word + word * operand size
706                 if(!ia32_is_mode_64() ^ sizePrefixPresent)
707                 {
708                     return u48;
709                 }
710                 else
711                 {
712                     return u32;
713                 }
714             case op_dq:
715             case op_qq:
716                 return u64;
717             case op_512:
718                 return m512;
719             case op_pi:
720             case op_ps:
721             case op_pd:
722                 return dbl128;
723             case op_s:
724                 return u48;
725             case op_f:
726                 return sp_float;
727             case op_dbl:
728                 return dp_float;
729             case op_14:
730                 return m14;
731             default:
732                 assert(!"Can't happen!");
733                 return u8;
734         }
735     }
736
737     enum AVX_Regtype { AVX_XMM = 0, AVX_YMM, AVX_ZMM, AVX_NONE };
738     #define AVX_TYPE_OKAY(type) ((type) >= AVX_XMM && (type) <= AVX_ZMM)
739     /** 
740      * Decode an avx register based on the type of prefix. Returns true if the
741      * given configuration is invalid and should be rejected.
742      */
743     bool decodeAVX(intelRegBanks& bank, int* bank_index, int regnum, AVX_Regtype type, ia32_prefixes& pref, unsigned int admet)
744     {
745
746         /* Check to see if this is just a normal MMX register access */
747         if(type >= AVX_NONE || type < 0)
748         {
749 #ifdef VEX_DEBUG
750             printf("VEX OPERAND:  REGNUM: %d  ", regnum);
751             printf("REG_TYPE: AVX_NONE (%d)\n", type);
752 #endif
753             /* Only registers XMM0 - XMM15 are usable */
754
755             /* The register must be valid */
756             if(regnum < 0) 
757                 return true;
758
759             if(regnum < 8)
760             {
761                 bank = b_xmm_set0;
762                 *bank_index = regnum;
763             } else if(regnum < 16)
764             {
765                 bank = b_xmm_set1;
766                 *bank_index = regnum - 8;
767             } else {
768                 /* Value is out of the valid range */
769                 return true;
770             }
771
772             /* Return success */
773             return false;
774         }
775
776         switch(admet)
777         {
778             case am_V: case am_YV: case am_XV:
779                 switch(pref.vex_type)
780                 {
781                     case VEX_TYPE_EVEX:
782                         regnum |= pref.vex_R << 4;
783                         regnum |= pref.vex_r << 3;
784                         break;
785                     default:break;
786                 }
787                 break;
788             case am_U: case am_YU: case am_XU:
789             case am_W: case am_YW: case am_XW:
790                 switch(pref.vex_type)
791                 {
792                     case VEX_TYPE_EVEX:
793                         regnum |= pref.vex_x << 4;
794                         regnum |= pref.vex_b << 3;
795                         break;
796                     default: break;
797                 }
798                 break;
799                         case am_HK: case am_VK: case am_WK:
800                                 switch(pref.vex_type)
801                                 {
802                                         case VEX_TYPE_EVEX:
803                                                 bank = b_kmask;
804                                                 *bank_index = regnum;
805                                                 if(*bank_index > 7)
806                                                         *bank_index = 7;
807                                                 else if(*bank_index < 0)
808                                                         *bank_index = 0;
809                         return false; /* Return success */
810                                         default:
811                                                 assert(!"MASKING REGISTERS NOT VALID FOR THIS PREFIX");
812                                                 break;
813                                 }
814                                 break;
815             default:  break;/** SSE instruction */
816         }
817 #ifdef VEX_DEBUG
818         printf("VEX OPERAND:  REGNUM: %d  ", regnum);
819 #endif
820
821         /* Operand is potentially XMM, YMM or ZMM */
822         int setnum = 0;
823         if(regnum < 8)
824         {
825             setnum = 0;
826             *bank_index = regnum;
827         } else if(regnum < 16)
828         {
829             setnum = 1;
830             *bank_index = regnum - 8;
831         } else if(regnum < 24)
832         {
833             setnum = 2;
834             *bank_index = regnum - 16;
835         } else if(regnum < 32){
836             setnum = 3;
837             *bank_index = regnum - 24;
838         } else {
839 #ifdef VEX_DEBUG
840             printf("AVX REGISTER NUMBER:   %d   is invalid!!\n", regnum);
841 #endif
842             return false;
843         }
844
845         switch(type)
846         {
847             case AVX_XMM:
848 #ifdef VEX_DEBUG
849                 printf("REG_TYPE: AVX_XMM (%d)\n", type);
850 #endif
851                 if(setnum == 0)
852                     bank = b_xmm_set0;
853                 else if(setnum == 1)
854                     bank = b_xmm_set1;
855                 else if(setnum == 2)
856                     bank = b_xmm_set2;
857                 else if(setnum == 3)
858                     bank = b_xmm_set3;
859                 else return true;
860                 break;
861             case AVX_YMM:
862 #ifdef VEX_DEBUG
863                 printf("REG_TYPE: AVX_YMM (%d)\n", type);
864 #endif
865                 if(setnum == 0)
866                     bank = b_ymm_set0;
867                 else if(setnum == 1)
868                     bank = b_ymm_set1;
869                 else if(setnum == 2)
870                     bank = b_ymm_set2;
871                 else if(setnum == 3)
872                     bank = b_ymm_set3;
873                 else return true;
874                 break;
875             case AVX_ZMM:
876 #ifdef VEX_DEBUG
877                 printf("REG_TYPE: AVX_ZMM (%d)\n", type);
878 #endif
879                 if(setnum == 0)
880                     bank = b_zmm_set0;
881                 else if(setnum == 1)
882                     bank = b_zmm_set1;
883                 else if(setnum == 2)
884                     bank = b_zmm_set2;
885                 else if(setnum == 3)
886                     bank = b_zmm_set3;
887                 else return true;
888                 break;
889             default:
890                 return true;
891         }
892
893         /* Return Success */
894         return false;
895     }
896
897     bool InstructionDecoder_x86::decodeOneOperand(const InstructionDecoder::buffer& b,
898                                                   const ia32_operand& operand,
899                                                   int & imm_index, /* immediate operand index */
900                                                   const Instruction* insn_to_complete, bool isRead, bool isWritten)
901     {
902         bool isCFT = false;
903         bool isCall = false;
904         bool isConditional = false;
905         InsnCategory cat = insn_to_complete->getCategory();
906
907         if(cat == c_BranchInsn || cat == c_CallInsn)
908             {
909             isCFT = true;
910             if(cat == c_CallInsn)
911             {
912                 isCall = true;
913             }
914             }
915
916         if(cat == c_BranchInsn && insn_to_complete->getOperation().getID() != e_jmp) 
917         {
918                 isConditional = true;
919         }
920
921         /* There must be a preliminary decoded instruction */
922         if(!decodedInstruction)
923             assert(!"No decoded instruction!\n");
924
925         unsigned int optype = operand.optype;
926         AVX_Regtype avx_type = AVX_NONE; /* The AVX register type (if VEX prefixed) */
927         intelRegBanks bank = b_invalid; /* Specifies an AVX bank to use for register decoding */
928         int bank_index = -1; /* Specifies a bank index for an AVX register */
929         ia32_prefixes& pref = *decodedInstruction->getPrefix();
930         int regnum; /* Used to keep track of some register positions */
931
932         if (sizePrefixPresent
933             && ((optype == op_v) || (optype == op_z))
934             && (operand.admet != am_J))
935         {
936             optype = op_w;
937         }
938
939         if(pref.vex_present)
940         {
941             /* Get the AVX type from the prefix */
942             avx_type = (AVX_Regtype)pref.vex_ll;
943         }
944
945         if (sizePrefixPresent && ((optype == op_v) 
946                 || (optype == op_z)) && (operand.admet != am_J)) 
947         {
948             optype = op_w;
949         }
950
951         if(optype == op_y) 
952         {
953             if(ia32_is_mode_64() && locs->rex_w)
954             {
955                 optype = op_q;
956             } else {
957                 optype = op_d;
958             }
959         }
960      
961         switch(operand.admet)
962         {
963                         case 0:
964                                 // No operand
965                                 {
966                                         // fprintf(stderr, "ERROR: Instruction with mismatched operands. Raw bytes: ");
967                                         // for(unsigned int i = 0; i < decodedInstruction->getSize(); i++) {
968                                         //      fprintf(stderr, "%x ", b.start[i]);
969                                         // }
970                                         // fprintf(stderr, "\n");*/
971                                         assert(!"Mismatched number of operands--check tables");
972                                         return false;
973                                 }
974                 return false;
975             case am_A:
976                 {
977                         // am_A only shows up as a far call/jump.  Position 1 should be universally safe.
978                         Expression::Ptr addr(decodeImmediate(optype, b.start + 1));
979                         insn_to_complete->addSuccessor(addr, isCall, false, false, false);
980                 }
981                         break;
982
983             case am_B:
984                 {
985                     // Selects a general purpose register from VEX.vvvv (VEX3 or EVEX)
986                     if(!pref.vex_present)
987                     {
988                         assert(!"Non VEX3 or EVEX instruction with am_B addressing mode!");
989                         return false;
990                     }
991
992                     Expression::Ptr op(makeRegisterExpression(
993                         makeRegisterID(pref.vex_vvvv_reg, optype, locs->rex_r)));
994                         insn_to_complete->appendOperand(op, isRead, isWritten);
995                 }
996                 break;
997
998             case am_C:
999                 {
1000                     Expression::Ptr op(makeRegisterExpression(
1001                             IntelRegTable(m_Arch,b_cr,locs->modrm_reg)));
1002                     insn_to_complete->appendOperand(op, isRead, isWritten);
1003                 }
1004                 break;
1005
1006             case am_D:
1007                 {
1008                     Expression::Ptr op(makeRegisterExpression(
1009                                 IntelRegTable(m_Arch,b_dr,locs->modrm_reg)));
1010                     insn_to_complete->appendOperand(op, isRead, isWritten);
1011                 }
1012                 break;
1013
1014             case am_E:
1015                 // am_M is like am_E, except that mod of 0x03 should 
1016                 // never occur (am_M specified memory,
1017                 // mod of 0x03 specifies direct register access).
1018             case am_M:
1019                 // am_R is the inverse of am_M; it should only have a mod of 3
1020             case am_R:
1021                 // can be am_R or am_M  
1022                         case am_RM:     
1023                 if(isCFT)
1024                 {
1025                     insn_to_complete->addSuccessor(
1026                             makeModRMExpression(b, optype), 
1027                             isCall, true, false, false);
1028                 } else {
1029                     insn_to_complete->appendOperand(
1030                             makeModRMExpression(b, optype), 
1031                             isRead, isWritten);
1032                 }
1033                 break;
1034
1035             case am_F:
1036                 {
1037                     Expression::Ptr op(makeRegisterExpression(x86::flags));
1038                     insn_to_complete->appendOperand(op, isRead, isWritten);
1039                 }
1040                 break;
1041
1042             case am_G:
1043                 {
1044                     Expression::Ptr op(makeRegisterExpression(
1045                             makeRegisterID(locs->modrm_reg, optype, locs->rex_r)));
1046                     insn_to_complete->appendOperand(op, isRead, isWritten);
1047                 }
1048                 break;
1049
1050             case am_H: /* Could be XMM, YMM or ZMM */
1051                 /* Make sure this register class is valid for VEX */
1052                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1053                     return false;
1054
1055                 /* Grab the correct bank and bank index for this type of register */
1056                 if(decodeAVX(bank, &bank_index, pref.vex_vvvv_reg, avx_type, pref, operand.admet))
1057                     return false;
1058
1059                 /* Append the operand */
1060                 insn_to_complete->appendOperand(makeRegisterExpression(
1061                         IntelRegTable(m_Arch, bank, bank_index)), 
1062                         isRead, isWritten);
1063                 break;
1064
1065                         case am_HK: /* Could be XMM, YMM or ZMM */
1066                 /* Make sure this register class is valid for VEX */
1067                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1068                     return false;
1069
1070                 /* Grab the correct bank and bank index for this type of register */
1071                 if(decodeAVX(bank, &bank_index, pref.vex_vvvv_reg, avx_type, pref, operand.admet))
1072                     return false;
1073
1074                 /* Append the operand */
1075                 insn_to_complete->appendOperand(makeRegisterExpression(
1076                         IntelRegTable(m_Arch, bank, bank_index)),
1077                         isRead, isWritten);
1078                 break;
1079
1080                         case am_I:
1081                 insn_to_complete->appendOperand(decodeImmediate(optype, b.start +
1082                     locs->imm_position[imm_index++]),
1083                     isRead, isWritten);
1084                 break;
1085             case am_J:
1086                 {
1087                     Expression::Ptr Offset(decodeImmediate(optype,
1088                         b.start + locs->imm_position[imm_index++],
1089                         true));
1090                     Expression::Ptr EIP(makeRegisterExpression(MachRegister::getPC(m_Arch)));
1091                     Expression::Ptr InsnSize(
1092                                                         make_shared(singleton_object_pool<Immediate>::construct(Result(u8,
1093                                                         decodedInstruction->getSize()))));
1094                     Expression::Ptr postEIP(makeAddExpression(EIP, InsnSize, u32));
1095                     Expression::Ptr op(makeAddExpression(Offset, postEIP, u32));
1096                     insn_to_complete->addSuccessor(op, isCall, false, isConditional, false);
1097                     if (isConditional)
1098                         insn_to_complete->addSuccessor(postEIP, false, false, true, true);
1099                 }
1100                 break;
1101                         case am_O:
1102                                 {
1103                                         // Address/offset width, which is *not* what's encoded by the optype...
1104                                         // The deref's width is what's actually encoded here.
1105                                         int pseudoOpType;
1106                                         switch(locs->address_size)
1107                                         {
1108                                                 case 1:
1109                                                         pseudoOpType = op_b;
1110                                                         break;
1111                                                 case 2:
1112                                                         pseudoOpType = op_w;
1113                                                         break;
1114                                                 case 4:
1115                                                         pseudoOpType = op_d;
1116                                                         break;
1117                                                 case 0:
1118                                                         if(m_Arch == Arch_x86_64) {
1119                                                                 if(!addrSizePrefixPresent)
1120                                                                         pseudoOpType = op_q;
1121                                                                 else
1122                                                                         pseudoOpType = op_d;
1123                                                                 } else {
1124                                                                         pseudoOpType = op_v;
1125                                                         }
1126                                                         break;
1127                                                 default:
1128                                                         assert(!"Bad address size, should be 0, 1, 2, or 4!");
1129                                                         pseudoOpType = op_b;
1130                                                         break;
1131                                         }
1132                 
1133                                         int offset_position = locs->opcode_position;
1134                                         if(locs->modrm_position > offset_position && locs->modrm_operand <
1135                                                 (int)(insn_to_complete->m_Operands.size()))
1136                                         {
1137                                                 offset_position = locs->modrm_position;
1138                                         }
1139                 
1140                                         if(locs->sib_position > offset_position)
1141                                         {
1142                                                 offset_position = locs->sib_position;
1143                                         }
1144                 
1145                                         offset_position++;
1146                                         insn_to_complete->appendOperand(makeDereferenceExpression(
1147                                                         decodeImmediate(pseudoOpType, b.start + offset_position), 
1148                                                         makeSizeType(optype)), isRead, isWritten);
1149                                 }
1150                                 break;
1151
1152                         case am_P:
1153                                 insn_to_complete->appendOperand(makeRegisterExpression(
1154                                         IntelRegTable(m_Arch,b_mm,locs->modrm_reg)),
1155                                         isRead, isWritten);
1156                                 break;
1157
1158                         case am_Q:
1159                                 switch(locs->modrm_mod)
1160                                 {
1161                                         // direct dereference
1162                                         case 0x00:
1163                                         case 0x01:
1164                                         case 0x02:
1165                                                 insn_to_complete->appendOperand(makeModRMExpression(b, optype), 
1166                                                                 isRead, isWritten);
1167                                                 break;
1168                                         case 0x03:
1169                                                 // use of actual register
1170                                                 insn_to_complete->appendOperand(makeRegisterExpression(
1171                                                                         IntelRegTable(m_Arch,b_mm,locs->modrm_rm)),
1172                                                                         isRead, isWritten);
1173                                                 break;
1174                                         default:
1175                                                 assert(!"2-bit value modrm_mod out of range");
1176                                                 break;
1177                                 };
1178                                 break;
1179
1180                         case am_S:
1181                                 // Segment register in modrm reg field.
1182                                 insn_to_complete->appendOperand(makeRegisterExpression(
1183                                         IntelRegTable(m_Arch,b_segment,locs->modrm_reg)),
1184                                         isRead, isWritten);
1185                                 break;
1186
1187                         case am_UM:
1188                                 switch(locs->modrm_mod)
1189                                 {
1190                                         // direct dereference
1191                                         case 0x00:
1192                                         case 0x01:
1193                                         case 0x02:
1194                                                 insn_to_complete->appendOperand(
1195                                                         makeModRMExpression(b, makeSizeType(optype)),
1196                                                         isRead, isWritten);
1197                                                 break;
1198                                         case 0x03:
1199                                                 // use of actual register (am_U)
1200                                                 {
1201                                                         /* Is this a vex prefixed instruction? */
1202                                         if(pref.vex_present)
1203                                         {
1204                                         if(!AVX_TYPE_OKAY(avx_type))
1205                                                 return false;
1206                                         }
1207                         
1208                                         /* Grab the register bank and index */
1209                                         if(decodeAVX(bank, &bank_index, locs->modrm_rm, AVX_XMM, 
1210                                                                                 pref, operand.admet))
1211                                                                 return false;
1212                         
1213                                         /* Append the operand */
1214                                         insn_to_complete->appendOperand(makeRegisterExpression(
1215                                                                         IntelRegTable(m_Arch, bank, bank_index)), 
1216                                                                         isRead, isWritten);     
1217                                                         break;
1218                                                 }
1219                                         default:
1220                                                 assert(!"2-bit value modrm_mod out of range");
1221                                                 break;
1222                                 };
1223                                 break;
1224
1225                         case am_XH: /* Must be XMM */
1226                                 /* Make sure we are using a valid VEX register class */
1227                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1228                     return false;
1229
1230                 /* Constrain register type to only the XMM banks */
1231                 avx_type = AVX_XMM;
1232
1233                 /* Grab the correct bank and bank index for this type of register */
1234                 if(decodeAVX(bank, &bank_index, pref.vex_vvvv_reg, avx_type, pref, operand.admet))
1235                     return false;
1236
1237                 insn_to_complete->appendOperand(makeRegisterExpression(
1238                         IntelRegTable(m_Arch, bank, bank_index)), 
1239                         isRead, isWritten);
1240                 break;
1241
1242             case am_YH: /* Could be XMM or YMM */
1243                 /* Make sure we are using a valid VEX register class */
1244                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1245                     return false;
1246
1247                 /* Constrain to only XMM or YMM registers */
1248                 if(avx_type != AVX_XMM && avx_type != AVX_YMM)
1249                     avx_type = AVX_YMM;
1250
1251                 /* Grab the correct bank and bank index for this type of register */
1252                 if(decodeAVX(bank, &bank_index, pref.vex_vvvv_reg, avx_type, pref, operand.admet))
1253                     return false;
1254
1255                 /* Append the operand */
1256                 insn_to_complete->appendOperand(makeRegisterExpression(
1257                         IntelRegTable(m_Arch, bank, bank_index)), 
1258                         isRead, isWritten);
1259                 break;
1260
1261             case am_U: /* Could be XMM, YMM, or ZMM (or possibly non VEX)*/
1262
1263                 /* Is this a vex prefixed instruction? */  
1264                 if(pref.vex_present)
1265                 {
1266                     if(!AVX_TYPE_OKAY(avx_type))
1267                         return false;
1268                 }
1269
1270                 /* Grab the register bank and index */
1271                 if(decodeAVX(bank, &bank_index, locs->modrm_rm, AVX_XMM, pref, operand.admet))
1272                     return false;
1273
1274                 /* Append the operand */
1275                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1276                 break;
1277             case am_XU: /* Must be XMM (must be VEX) */
1278                 /* Make sure this register class is valid */
1279                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1280                     return false;
1281   
1282                 /* Constrain register to XMM banks only */        
1283                 avx_type = AVX_XMM;
1284
1285                 /* Get the register bank and index for this register */
1286                 if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
1287                     return false;
1288
1289                 /* Append the operand */
1290                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1291                 break;
1292             case am_YU: /* Must be XMM or YMM (must be VEX) */
1293                 /* Make sure this register class is valid */
1294                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1295                     return false;
1296
1297                 /* Constrain to either XMM or YMM registers */
1298                 if(avx_type != AVX_XMM && avx_type != AVX_YMM)
1299                     avx_type = AVX_YMM;
1300
1301                 /* Get the register bank and index */
1302                 if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
1303                     return false;
1304
1305                 /* Append the operand */
1306                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1307                 break;
1308             case am_V: /* Could be XMM, YMM or ZMM (possibly non VEX)*/
1309                 /* Is this a vex prefixed instruction? */
1310                 if(pref.vex_present && !AVX_TYPE_OKAY(avx_type))
1311                     return false;
1312
1313                 /* Get the base register number */
1314                 regnum = locs->modrm_reg;
1315
1316                 /* Get the register bank and the index */
1317                 if(decodeAVX(bank, &bank_index, regnum, avx_type, pref, operand.admet))
1318                     return false;
1319
1320                 /* Append the operand */
1321                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1322                 break;
1323             case am_XV: /* Must be XMM (must be VEX) */
1324
1325                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1326                     return false;
1327
1328                 regnum = locs->modrm_reg;
1329
1330                 /* Get the register bank and the index */
1331                 if(decodeAVX(bank, &bank_index, regnum, avx_type, pref, operand.admet))
1332                     return false;
1333
1334                 /* Append the operand */
1335                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1336                 break;
1337             case am_YV: /* Must be XMM or YMM (must be VEX) */
1338                 /* Make sure this register class is valid */
1339                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1340                     return false;
1341
1342                 regnum = locs->modrm_reg;
1343
1344                 /* Constrain to either XMM or YMM registers */
1345                 if(avx_type != AVX_XMM && avx_type != AVX_YMM)
1346                     avx_type = AVX_YMM;
1347
1348                 /* Get the register bank and index */
1349                 if(decodeAVX(bank, &bank_index, regnum, avx_type, pref, operand.admet))
1350                     return false;
1351
1352                 /* Append the operand */
1353                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1354                 break;
1355                         case am_VK: /* A KMasking register defined in the reg of a Mod/RM*/
1356                 /* Is this a vex prefixed instruction? */
1357                 if(pref.vex_present && !AVX_TYPE_OKAY(avx_type))
1358                     return false;
1359
1360                 /* Get the base register number */
1361                 regnum = locs->modrm_reg;
1362
1363                 /* Get the register bank and the index */
1364                 if(decodeAVX(bank, &bank_index, regnum, avx_type, pref, operand.admet))
1365                     return false;
1366
1367                 /* Append the operand */
1368                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1369                 break;
1370             case am_W: /* Could be XMM, YMM, or ZMM (or possibly not VEX) */
1371
1372                                 if(pref.vex_present)
1373                                 {
1374                                         if(!AVX_TYPE_OKAY(avx_type))
1375                                         return false;
1376                                 }
1377                                 
1378                                 switch(locs->modrm_mod)
1379                                 {
1380                                         /* Direct dereference */
1381                                         case 0x00:
1382                                         case 0x01:
1383                                         case 0x02:
1384                                                 insn_to_complete->appendOperand(
1385                                                         makeModRMExpression(b, makeSizeType(optype)), isRead, isWritten);
1386                                                 break;
1387                                         case 0x03:
1388                                                 /* Just the register is used */
1389                                                 if(decodeAVX(bank, &bank_index, locs->modrm_rm, 
1390                                                                         avx_type, pref, operand.admet))
1391                                                         return false;
1392
1393                                                 insn_to_complete->appendOperand(
1394                                                                 makeRegisterExpression(IntelRegTable(
1395                                                                                 m_Arch, bank, bank_index)), isRead, isWritten);
1396                                                 break;
1397                                         default:
1398                                                 assert(!"2-bit value modrm_mod out of range");
1399                                                 break;
1400                                 }
1401                                 break;
1402             case am_XW: /* Must be XMM (must be VEX) */
1403
1404                 /* Make sure this vex is okay */
1405                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1406                     return false;
1407          
1408                 /* Constrain to the XMM banks */ 
1409                 avx_type = AVX_XMM;
1410
1411                 switch(locs->modrm_mod)
1412                             {
1413                     /* Direct dereference */
1414                     case 0x00:
1415                     case 0x01:
1416                     case 0x02:
1417                         insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)), isRead, isWritten);
1418                         break;
1419                     case 0x03:
1420                         /* Just the register is used */
1421                         if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
1422                             return false;
1423                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1424                         break;
1425                     default:
1426                         assert(!"2-bit value modrm_mod out of range");
1427                                 break;
1428                             }
1429                 break;
1430             case am_YW: /* Must be either YMM or XMM (must be VEX) */
1431
1432                 /* Make sure the register class is okay and we have a vex prefix */
1433                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1434                     return false;
1435
1436                 /* Constrain to either XMM or YMM registers */
1437                 if(avx_type != AVX_XMM && avx_type != AVX_YMM)
1438                     avx_type = AVX_YMM;
1439
1440                 switch(locs->modrm_mod)
1441                 {
1442                     /* Direct dereference */
1443                     case 0x00:
1444                     case 0x01:
1445                     case 0x02:
1446                         insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)), isRead, isWritten);
1447                         break;
1448                     case 0x03:
1449                         /* Just the register is used */
1450                         if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
1451                             return false;
1452
1453                         /* Append the operand */
1454                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1455                         break;
1456                             default:
1457                                 assert(!"2-bit value modrm_mod out of range");
1458                                 break;
1459                 }
1460                                 break;
1461                         case am_WK: /* Must be either YMM or XMM (must be VEX) */
1462
1463                 /* Make sure the register class is okay and we have a vex prefix */
1464                 if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
1465                     return false;
1466
1467                 /* Constrain to either XMM or YMM registers */
1468                 if(avx_type != AVX_XMM && avx_type != AVX_YMM)
1469                     avx_type = AVX_YMM;
1470
1471                 switch(locs->modrm_mod)
1472                 {
1473                     /* Direct dereference */
1474                     case 0x00:
1475                     case 0x01:
1476                     case 0x02:
1477                         insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)), isRead, isWritten);
1478                         break;
1479                     case 0x03:
1480                         /* Just the register is used */
1481                         if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
1482                             return false;
1483
1484                         /* Append the operand */
1485                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
1486                         break;
1487                             default:
1488                                 assert(!"2-bit value modrm_mod out of range");
1489                                 break;
1490                 }
1491                 break;
1492                         case am_X:
1493                                 {
1494                                         MachRegister si_reg;
1495                                         if(m_Arch == Arch_x86)
1496                                         {
1497                                                 if(addrSizePrefixPresent)
1498                                                 {
1499                                                         si_reg = x86::si;
1500                                                 } else {
1501                                                         si_reg = x86::esi;
1502                                                 }
1503                                         } else {
1504                                                 if(addrSizePrefixPresent)
1505                                                 {
1506                                                         si_reg = x86_64::esi;
1507                                                 } else {
1508                                                         si_reg = x86_64::rsi;
1509                                                 }
1510                                         }
1511                                         
1512                                         Expression::Ptr ds(makeRegisterExpression(
1513                                                                 m_Arch == Arch_x86 ? x86::ds : x86_64::ds));
1514                                         Expression::Ptr si(makeRegisterExpression(si_reg));
1515                                         Expression::Ptr segmentOffset(make_shared
1516                                                         (singleton_object_pool<Immediate>::construct(Result(u32, 0x10))));
1517                                         Expression::Ptr ds_segment = makeMultiplyExpression(
1518                                                         ds, segmentOffset, u32);
1519                                         Expression::Ptr ds_si = makeAddExpression(ds_segment, si, u32);
1520                                         insn_to_complete->appendOperand(
1521                                                         makeDereferenceExpression(ds_si, makeSizeType(optype)), 
1522                                                         isRead, isWritten);
1523                                 }
1524                                 break;
1525                         case am_Y:
1526                                 {
1527                                         MachRegister di_reg;
1528                                         if(m_Arch == Arch_x86)
1529                                         {
1530                                                 if(addrSizePrefixPresent)
1531                                                 {
1532                                                         di_reg = x86::di;
1533                                                 } else {
1534                                                         di_reg = x86::edi;
1535                                                 }
1536                                         } else {
1537                                                 if(addrSizePrefixPresent)
1538                                                 {
1539                                                         di_reg = x86_64::edi;
1540                                                 } else {
1541                                                         di_reg = x86_64::rdi;
1542                                                 }
1543                                         }
1544
1545                                         Expression::Ptr es(makeRegisterExpression(
1546                                                                 m_Arch == Arch_x86 ? x86::es : x86_64::es));
1547                                         Expression::Ptr di(makeRegisterExpression(di_reg));
1548                                         
1549                                         Immediate::Ptr imm(make_shared(
1550                                                                 singleton_object_pool<Immediate>::construct(Result(u32, 0x10))));
1551                                         Expression::Ptr es_segment(
1552                                                         makeMultiplyExpression(es,imm, u32));
1553                                         Expression::Ptr es_di(makeAddExpression(es_segment, di, u32));
1554                                         insn_to_complete->appendOperand(
1555                                                         makeDereferenceExpression(es_di, makeSizeType(optype)),
1556                                                         isRead, isWritten);
1557                                         
1558                                 }
1559                                 break;
1560                         case am_tworeghack:
1561                         if(optype == op_edxeax)
1562                         {
1563                             Expression::Ptr edx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::edx : x86_64::edx));
1564                             Expression::Ptr eax(makeRegisterExpression(m_Arch == Arch_x86 ? x86::eax : x86_64::eax));
1565                     Expression::Ptr highAddr = makeMultiplyExpression(edx, Immediate::makeImmediate(Result(u64, 2^32)), u64);
1566                             Expression::Ptr addr = makeAddExpression(highAddr, eax, u64);
1567                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1568                             insn_to_complete->appendOperand(op, isRead, isWritten);
1569                 } else if (optype == op_ecxebx)
1570                         {
1571                             Expression::Ptr ecx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ecx : x86_64::ecx));
1572                             Expression::Ptr ebx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ebx : x86_64::ebx));
1573                             Expression::Ptr highAddr = makeMultiplyExpression(ecx,
1574                                     Immediate::makeImmediate(Result(u64, 2^32)), u64);
1575                             Expression::Ptr addr = makeAddExpression(highAddr, ebx, u64);
1576                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1577                             insn_to_complete->appendOperand(op, isRead, isWritten);
1578                         }
1579                     break;
1580                     
1581                     case am_reg:
1582                     {
1583                         MachRegister r(optype);
1584                         int size = r.size();
1585                     if((m_Arch == Arch_x86_64) && (r.regClass() == (unsigned int)x86::GPR) && (size == 4))
1586                         {
1587                             int reg_size = isDefault64Insn() ? op_q : op_v;
1588                             if(sizePrefixPresent)
1589                             {
1590                                 reg_size = op_w;
1591                             }
1592                             // implicit regs are not extended
1593                             r = makeRegisterID((r.val() & 0xFF), reg_size, false);
1594                             entryID entryid = decodedInstruction->getEntry()->getID(locs);
1595                             if(locs->rex_b && insn_to_complete->m_Operands.empty() &&
1596                                (entryid == e_push || entryid == e_pop || entryid == e_xchg || ((*(b.start + locs->opcode_position) & 0xf0) == 0xb0)))
1597                             {
1598                                 r = MachRegister((r.val()) | x86_64::r8.val());
1599                                 assert(r.name() != "<INVALID_REG>");
1600                             }
1601                     } else {
1602                             r = MachRegister((r.val() & ~r.getArchitecture()) | m_Arch);
1603                             
1604                             entryID entryid = decodedInstruction->getEntry()->getID(locs);
1605                             if(insn_to_complete->m_Operands.empty() && 
1606                                (entryid == e_push || entryid == e_pop || entryid == e_xchg || ((*(b.start + locs->opcode_position) & 0xf0) == 0xb0) ) )
1607                             {
1608                                 unsigned int opcode_byte = *(b.start+locs->opcode_position);
1609                                 unsigned int reg_id = (opcode_byte & 0x07);
1610                                 if(locs->rex_b) 
1611                                 {
1612                                     // FP stack registers are not affected by the rex_b bit in AM_REG.
1613                                     if(r.regClass() == (unsigned) x86::GPR)
1614                                     {
1615                                         int reg_op_type = op_d;
1616                                         switch(size)
1617                                         {
1618                                         case 1:
1619                                             reg_op_type = op_b;
1620                                             break;
1621                                         case 2:
1622                                             reg_op_type = op_w;
1623                                             break;
1624                                         case 8:
1625                                             reg_op_type = op_q;
1626                                             break;
1627                                         default:
1628                                             break;
1629                                         }
1630
1631                                         r = makeRegisterID(reg_id, reg_op_type, true);
1632                                         assert(r.name() != "<INVALID_REG>");
1633                                     }
1634                             } else if((r.size() == 1) && (locs->rex_byte & 0x40))
1635                                 {
1636                                     r = makeRegisterID(reg_id, op_b, false);
1637                                     assert(r.name() != "<INVALID_REG>");
1638                                 }
1639                             }
1640
1641                         if(sizePrefixPresent && (r.regClass() == (unsigned int)x86::GPR) && r.size() >= 4)
1642                             {
1643                                 r = MachRegister((r.val() & ~x86::FULL) | x86::W_REG);
1644                                 assert(r.name() != "<INVALID_REG>");
1645                             }
1646                         }
1647                         Expression::Ptr op(makeRegisterExpression(r));
1648                         insn_to_complete->appendOperand(op, isRead, isWritten);
1649                     }
1650                     break;
1651                 case am_stackH:
1652                 case am_stackP:
1653                 // handled elsewhere
1654                     break;
1655                 case am_allgprs:
1656                     if(m_Arch == Arch_x86)
1657                     {
1658                         insn_to_complete->appendOperand(makeRegisterExpression(x86::eax), isRead, isWritten);
1659                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ecx), isRead, isWritten);
1660                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edx), isRead, isWritten);
1661                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebx), isRead, isWritten);
1662                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esp), isRead, isWritten);
1663                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebp), isRead, isWritten);
1664                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esi), isRead, isWritten);
1665                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edi), isRead, isWritten);
1666                 } else {
1667                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::eax), isRead, isWritten);
1668                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ecx), isRead, isWritten);
1669                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edx), isRead, isWritten);
1670                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebx), isRead, isWritten);
1671                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esp), isRead, isWritten);
1672                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebp), isRead, isWritten);
1673                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esi), isRead, isWritten);
1674                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edi), isRead, isWritten);
1675                     }
1676                     break;
1677             case am_ImplImm:
1678                   insn_to_complete->appendOperand(Immediate::makeImmediate(Result(makeSizeType(optype), 1)), isRead, isWritten);
1679                   break;
1680                 default:
1681                     printf("decodeOneOperand() called with unknown addressing method %d\n", operand.admet);
1682                     // assert(0);
1683                 return false;
1684         }
1685       
1686                 return true;
1687             }
1688
1689     extern ia32_entry invalid;
1690     void InstructionDecoder_x86::doIA32Decode(InstructionDecoder::buffer& b)
1691     {
1692         if(decodedInstruction == NULL)
1693         {
1694             decodedInstruction = reinterpret_cast<ia32_instruction*>(malloc(sizeof(ia32_instruction)));
1695             assert(decodedInstruction);
1696         }
1697         if(locs == NULL)
1698         {
1699             locs = reinterpret_cast<ia32_locations*>(malloc(sizeof(ia32_locations)));
1700             assert(locs);
1701         }
1702         locs = new(locs) ia32_locations; //reinit();
1703         assert(locs->sib_position == -1);
1704         decodedInstruction = new (decodedInstruction) ia32_instruction(NULL, NULL, locs);
1705         ia32_decode(IA32_DECODE_PREFIXES, b.start, *decodedInstruction);
1706         sizePrefixPresent = (decodedInstruction->getPrefix()->getOperSzPrefix() == 0x66);
1707         if (decodedInstruction->getPrefix()->rexW()) {
1708            // as per 2.2.1.2 - rex.w overrides 66h
1709            sizePrefixPresent = false;
1710         }
1711         addrSizePrefixPresent = (decodedInstruction->getPrefix()->getAddrSzPrefix() == 0x67);
1712         static ia32_entry invalid = { e_No_Entry, 0, 0, false, { {0,0}, {0,0}, {0,0} }, 0, 0 };
1713         if(decodedInstruction->getEntry()) {
1714             // check prefix validity
1715             // lock prefix only allowed on certain insns.
1716             // TODO: refine further to check memory written operand
1717             if(decodedInstruction->getPrefix()->getPrefix(0) == PREFIX_LOCK)
1718             {
1719                 switch(decodedInstruction->getEntry()->id)
1720                 {
1721                 case e_add:
1722                 case e_adc:
1723                 case e_and:
1724                 case e_btc:
1725                 case e_btr:
1726                 case e_bts:
1727                 case e_cmpxch:
1728                 case e_cmpxch8b:
1729                 case e_dec:
1730                 case e_inc:
1731                 case e_neg:
1732                 case e_not:
1733                 case e_or:
1734                 case e_sbb:
1735                 case e_sub:
1736                 case e_xor:
1737                 case e_xadd:
1738                 case e_xchg:
1739                     break;
1740                 default:
1741                     m_Operation =make_shared(singleton_object_pool<Operation>::construct(&invalid,
1742                                     decodedInstruction->getPrefix(), locs, m_Arch));
1743                     return;
1744                 }
1745             }
1746             m_Operation = make_shared(singleton_object_pool<Operation>::construct(decodedInstruction->getEntry(),
1747                                     decodedInstruction->getPrefix(), locs, m_Arch));
1748             
1749       } else {
1750                 // Gap parsing can trigger this case; in particular, when it encounters prefixes in an invalid order.
1751                 // Notably, if a REX prefix (0x40-0x48) appears followed by another prefix (0x66, 0x67, etc)
1752                 // we'll reject the instruction as invalid and send it back with no entry.  Since this is a common
1753                 // byte sequence to see in, for example, ASCII strings, we want to simply accept this and move on, not
1754                 // yell at the user.
1755             m_Operation = make_shared(singleton_object_pool<Operation>::construct(&invalid,
1756                                     decodedInstruction->getPrefix(), locs, m_Arch));
1757         }
1758
1759     }
1760     
1761     void InstructionDecoder_x86::decodeOpcode(InstructionDecoder::buffer& b)
1762     {
1763         doIA32Decode(b);
1764         b.start += decodedInstruction->getSize();
1765     }
1766     
1767         bool InstructionDecoder_x86::decodeOperands(const Instruction* insn_to_complete)
1768     {
1769        int imm_index = 0; // handle multiple immediate operands
1770         if(!decodedInstruction || !decodedInstruction->getEntry()) return false;
1771         unsigned int opsema = decodedInstruction->getEntry()->opsema & 0xFF;
1772         InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1773
1774         if (decodedInstruction->getEntry()->getID() == e_ret_near ||
1775             decodedInstruction->getEntry()->getID() == e_ret_far) {
1776            Expression::Ptr ret_addr = makeDereferenceExpression(makeRegisterExpression(ia32_is_mode_64() ? x86_64::rsp : x86::esp), 
1777                                                                 ia32_is_mode_64() ? u64 : u32);
1778            insn_to_complete->addSuccessor(ret_addr, false, true, false, false);
1779         }
1780
1781         for(int i = 0; i < 3; i++)
1782         {
1783             if(decodedInstruction->getEntry()->operands[i].admet == 0 && 
1784                decodedInstruction->getEntry()->operands[i].optype == 0)
1785                 return true;
1786             if(!decodeOneOperand(b,
1787                                  decodedInstruction->getEntry()->operands[i], 
1788                                  imm_index, 
1789                                  insn_to_complete, 
1790                                  readsOperand(opsema, i),
1791                                  writesOperand(opsema, i)))
1792             {
1793                 return false;
1794             }
1795         }
1796
1797         /* Does this instruction have a 4th operand? */
1798         if((decodedInstruction->getEntry()->opsema & 0xFFFF) >= s4OP)
1799         {
1800           if(!decodeOneOperand(b,
1801             {am_I, op_b}, /* This is always an IMM8 */
1802             imm_index,
1803             insn_to_complete,
1804             readsOperand(opsema, 3),
1805             writesOperand(opsema, 3)))
1806             {
1807                 return false;
1808             }
1809         }
1810     
1811         return true;
1812     }
1813
1814     
1815       INSTRUCTION_EXPORT Instruction::Ptr InstructionDecoder_x86::decode(InstructionDecoder::buffer& b)
1816     {
1817         return InstructionDecoderImpl::decode(b);
1818     }
1819     void InstructionDecoder_x86::doDelayedDecode(const Instruction* insn_to_complete)
1820     {
1821       InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1822       //insn_to_complete->m_Operands.reserve(4);
1823       doIA32Decode(b);        
1824       decodeOperands(insn_to_complete);
1825     }
1826     
1827 };
1828 };
1829