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