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