Dyninst can now use am_H addressing mode
[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 using namespace std;
44 using namespace NS_x86;
45 namespace Dyninst
46 {
47     namespace InstructionAPI
48     {
49     
50         bool readsOperand(unsigned int opsema, unsigned int i)
51         {
52             switch(opsema) {
53                 case s1R2R:
54                     return (i == 0 || i == 1);
55                 case s1R:
56                 case s1RW:
57                     return i == 0;
58                 case s1W:
59                     return false;
60                 case s1W2RW:
61                 case s1W2R:   // second operand read, first operand written (e.g. mov)
62                     return i == 1;
63                 case s1RW2R:  // two operands read, first written (e.g. add)
64                 case s1RW2RW: // e.g. xchg
65                 case s1R2RW:
66                     return i == 0 || i == 1;
67                 case s1W2R3R: // e.g. imul
68                 case s1W2RW3R: // some mul
69                 case s1W2R3RW: // (stack) push & pop
70                     return i == 1 || i == 2;
71                 case s1W2W3R: // e.g. les
72                     return i == 2;
73                 case s1RW2R3R: // shld/shrd
74                 case s1RW2RW3R: // [i]div, cmpxch8b
75                 case s1R2R3R:
76                     return i == 0 || i == 1 || i == 2;
77                     break;
78                 case sNONE:
79                 default:
80                     return false;
81             }
82       
83         }
84       
85         bool writesOperand(unsigned int opsema, unsigned int i)
86         {
87             switch(opsema) {
88                 case s1R2R:
89                 case s1R:
90                     return false;
91                 case s1RW:
92                 case s1W:
93                     case s1W2R:   // second operand read, first operand written (e.g. mov)
94                         case s1RW2R:  // two operands read, first written (e.g. add)
95                             case s1W2R3R: // e.g. imul
96                                 case s1RW2R3R: // shld/shrd
97                                     return i == 0;
98                 case s1R2RW:
99                     return i == 1;
100                 case s1W2RW:
101                     case s1RW2RW: // e.g. xchg
102                         case s1W2RW3R: // some mul
103                             case s1W2W3R: // e.g. les
104                                 case s1RW2RW3R: // [i]div, cmpxch8b
105                                     return i == 0 || i == 1;
106                                     case s1W2R3RW: // (stack) push & pop
107                                         return i == 0 || i == 2;
108                 case sNONE:
109                 default:
110                     return false;
111             }
112         }
113
114
115     
116     INSTRUCTION_EXPORT InstructionDecoder_x86::InstructionDecoder_x86(Architecture a) :
117       InstructionDecoderImpl(a),
118     locs(NULL),
119     decodedInstruction(NULL),
120     sizePrefixPresent(false),
121     addrSizePrefixPresent(false)
122     {
123       if(a == Arch_x86_64) setMode(true);
124       
125     }
126     INSTRUCTION_EXPORT InstructionDecoder_x86::~InstructionDecoder_x86()
127     {
128         if(decodedInstruction) decodedInstruction->~ia32_instruction();
129         free(decodedInstruction);
130         if(locs) locs->~ia32_locations();
131         free(locs);
132
133     }
134     static const unsigned char modrm_use_sib = 4;
135     
136     INSTRUCTION_EXPORT void InstructionDecoder_x86::setMode(bool is64)
137     {
138         ia32_set_mode_64(is64);
139     }
140     
141       Expression::Ptr InstructionDecoder_x86::makeSIBExpression(const InstructionDecoder::buffer& b)
142     {
143         unsigned scale;
144         Register index;
145         Register base;
146         Result_Type registerType = ia32_is_mode_64() ? u64 : u32;
147
148         decode_SIB(locs->sib_byte, scale, index, base);
149
150         Expression::Ptr scaleAST(make_shared(singleton_object_pool<Immediate>::construct(Result(u8, dword_t(scale)))));
151         Expression::Ptr indexAST(make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(index, registerType,
152                                     locs->rex_x))));
153         Expression::Ptr baseAST;
154         if(base == 0x05)
155         {
156             switch(locs->modrm_mod)
157             {
158                 case 0x00:
159                     baseAST = decodeImmediate(op_d, b.start + locs->sib_position + 1, true);
160                     break;
161                 case 0x01: 
162                 case 0x02: 
163                     baseAST = make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(base, 
164                                                                                                registerType,
165                                                                                                locs->rex_b)));
166                     break;
167                 case 0x03:
168                 default:
169                     assert(0);
170                     break;
171             };
172         }
173         else
174         {
175             baseAST = make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(base, 
176                                                                                                registerType,
177                                                                                                locs->rex_b)));
178         }
179
180         if(index == 0x04 && (!(ia32_is_mode_64()) || !(locs->rex_x)))
181         {
182             return baseAST;
183         }
184         return makeAddExpression(baseAST, makeMultiplyExpression(indexAST, scaleAST, registerType), registerType);
185     }
186
187       Expression::Ptr InstructionDecoder_x86::makeModRMExpression(const InstructionDecoder::buffer& b,
188                                                                   unsigned int opType)
189     {
190        unsigned int regType = op_d;
191        Result_Type aw;
192        if(ia32_is_mode_64())
193        {
194            if(addrSizePrefixPresent) {
195                aw = u32;
196            } else {
197                aw = u64;
198                regType = op_q;
199            }
200        }
201        else
202        {
203            if(!addrSizePrefixPresent) {
204                aw = u32;
205            } else {
206                aw = u16;
207                regType = op_w;
208            }
209        }
210         if (opType == op_lea) {
211             // For an LEA, aw (address width) is insufficient, use makeSizeType
212             aw = makeSizeType(opType);
213         }
214         Expression::Ptr e =
215             makeRegisterExpression(makeRegisterID(locs->modrm_rm, regType, locs->rex_b));
216         switch(locs->modrm_mod)
217         {
218             case 0:
219                 if(locs->modrm_rm == modrm_use_sib) {
220                     e = makeSIBExpression(b);
221                 }
222                 if(locs->modrm_rm == 0x5 && !addrSizePrefixPresent)
223                 {
224                     assert(locs->opcode_position > -1);
225                     if(ia32_is_mode_64())
226                     {
227                         e = makeAddExpression(makeRegisterExpression(x86_64::rip),
228                                             getModRMDisplacement(b), aw);
229                     }
230                     else
231                     {
232                         e = getModRMDisplacement(b);
233                     }
234         
235                 }
236                 if(locs->modrm_rm == 0x6 && addrSizePrefixPresent)
237                 {
238                     e = getModRMDisplacement(b);
239                 }
240                 if(opType == op_lea)
241                 {
242                     return e;
243                 }
244                 return makeDereferenceExpression(e, makeSizeType(opType));
245                 assert(0);
246                 break;
247             case 1:
248             case 2:
249             {
250                 if(locs->modrm_rm == modrm_use_sib) {
251                     e = makeSIBExpression(b);
252                 }
253                 Expression::Ptr disp_e = makeAddExpression(e, getModRMDisplacement(b), aw);
254                 if(opType == op_lea)
255                 {
256                     return disp_e;
257                 }
258                 return makeDereferenceExpression(disp_e, makeSizeType(opType));
259             }
260             assert(0);
261             break;
262             case 3:
263                 return makeRegisterExpression(makeRegisterID(locs->modrm_rm, opType, locs->rex_b));
264             default:
265                 return Expression::Ptr();
266         
267         };
268         // can't get here, but make the compiler happy...
269         assert(0);
270         return Expression::Ptr();
271     }
272
273     Expression::Ptr InstructionDecoder_x86::decodeImmediate(unsigned int opType, const unsigned char* immStart, 
274                                                             bool isSigned)
275     {
276         // rex_w indicates we need to sign-extend also.
277         isSigned = isSigned || locs->rex_w;
278         
279         switch(opType)
280         {
281             case op_b:
282                 return Immediate::makeImmediate(Result(isSigned ? s8 : u8 ,*(const byte_t*)(immStart)));
283                 break;
284             case op_d:
285                 return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
286             case op_w:
287                 return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
288                 break;
289             case op_q:
290                 return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
291                 break;
292             case op_v:
293                 if (locs->rex_w || isDefault64Insn()) {
294                     return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
295                 }
296                 //if(!sizePrefixPresent)
297                 //{
298                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
299                     //}
300                     //else
301                     //{
302                     //return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
303                     //}
304                 break;
305             case op_z:
306                 // 32 bit mode & no prefix, or 16 bit mode & prefix => 32 bit
307                 // 16 bit mode, no prefix or 32 bit mode, prefix => 16 bit
308                 //if(!addrSizePrefixPresent)
309                 //{
310                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
311                     //}
312                     //else
313                     //{
314                     //return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
315                     //}
316                 break;
317             case op_p:
318                 // 32 bit mode & no prefix, or 16 bit mode & prefix => 48 bit
319                 // 16 bit mode, no prefix or 32 bit mode, prefix => 32 bit
320                 if(!sizePrefixPresent)
321                 {
322                     return Immediate::makeImmediate(Result(isSigned ? s48 : u48,*(const int64_t*)(immStart)));
323                 }
324                 else
325                 {
326                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
327                 }
328
329                 break;
330             case op_a:
331             case op_dq:
332             case op_pd:
333             case op_ps:
334             case op_s:
335             case op_si:
336             case op_lea:
337             case op_allgprs:
338             case op_512:
339             case op_c:
340                 assert(!"Can't happen: opType unexpected for valid ways to decode an immediate");
341                 return Expression::Ptr();
342             default:
343                 assert(!"Can't happen: opType out of range");
344                 return Expression::Ptr();
345         }
346     }
347     
348     Expression::Ptr InstructionDecoder_x86::getModRMDisplacement(const InstructionDecoder::buffer& b)
349     {
350         int disp_pos;
351
352         if(locs->sib_position != -1)
353         {
354             disp_pos = locs->sib_position + 1;
355         }
356         else
357         {
358             disp_pos = locs->modrm_position + 1;
359         }
360         switch(locs->modrm_mod)
361         {
362             case 1:
363                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, (*(const byte_t*)(b.start +
364                         disp_pos)))));
365                 break;
366             case 2:
367                 if(0 && sizePrefixPresent)
368                 {
369                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s16, *((const word_t*)(b.start +
370                             disp_pos)))));
371                 }
372                 else
373                 {
374                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s32, *((const dword_t*)(b.start +
375                             disp_pos)))));
376                 }
377                 break;
378             case 0:
379                 // In 16-bit mode, the word displacement is modrm r/m 6
380                 if(sizePrefixPresent && !ia32_is_mode_64())
381                 {
382                     if(locs->modrm_rm == 6)
383                     {
384                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s16,
385                                            *((const dword_t*)(b.start + disp_pos)))));
386                     }
387                     // TODO FIXME; this was decoding wrong, but I'm not sure
388                     // why...
389                     else if (locs->modrm_rm == 5) {
390                         assert(b.start + disp_pos + 4 <= b.end);
391                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s32,
392                                            *((const dword_t*)(b.start + disp_pos)))));
393                     } else {
394                         assert(b.start + disp_pos + 1 <= b.end);
395                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
396                     }
397                     break;
398                 }
399                 // ...and in 32-bit mode, the dword displacement is modrm r/m 5
400                 else
401                 {
402                     if(locs->modrm_rm == 5)
403                     {
404                         if (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                             return make_shared(singleton_object_pool<Immediate>::construct(Result()));
409                     }
410                     else
411                     {
412                         if (b.start + disp_pos + 1 <= b.end)
413                             return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
414                         else
415                             return make_shared(singleton_object_pool<Immediate>::construct(Result()));
416                     }
417                     break;
418                 }
419             default:
420                 assert(b.start + disp_pos + 1 <= b.end);
421                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
422                 break;
423         }
424     }
425
426     enum intelRegBanks
427     {
428         b_8bitNoREX = 0,
429         b_16bit,
430         b_32bit,
431         b_segment,
432         b_64bit,
433         b_xmm,
434         b_xmmhigh,
435         b_mm,
436         b_cr,
437         b_dr,
438         b_tr,
439         b_amd64ext,
440         b_8bitWithREX,
441         b_fpstack,
442         amd64_ext_8,
443         amd64_ext_16,
444         amd64_ext_32,
445     };
446     static MachRegister IntelRegTable32[][8] = {
447         {
448             x86::al, x86::cl, x86::dl, x86::bl, x86::ah, x86::ch, x86::dh, x86::bh
449         },
450         {
451             x86::ax, x86::cx, x86::dx, x86::bx, x86::sp, x86::bp, x86::si, x86::di
452         },
453         {
454             x86::eax, x86::ecx, x86::edx, x86::ebx, x86::esp, x86::ebp, x86::esi, x86::edi
455         },
456         {
457            x86::es, x86::cs, x86::ss, x86::ds, x86::fs, x86::gs, InvalidReg, InvalidReg
458         },
459         {
460             x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi
461         },
462         {
463             x86::xmm0, x86::xmm1, x86::xmm2, x86::xmm3, x86::xmm4, x86::xmm5, x86::xmm6, x86::xmm7
464         },
465         {
466             x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15
467         },
468         {
469             x86::mm0, x86::mm1, x86::mm2, x86::mm3, x86::mm4, x86::mm5, x86::mm6, x86::mm7
470         },
471         {
472             x86::cr0, x86::cr1, x86::cr2, x86::cr3, x86::cr4, x86::cr5, x86::cr6, x86::cr7
473         },
474         {
475             x86::dr0, x86::dr1, x86::dr2, x86::dr3, x86::dr4, x86::dr5, x86::dr6, x86::dr7
476         },
477         {
478             x86::tr0, x86::tr1, x86::tr2, x86::tr3, x86::tr4, x86::tr5, x86::tr6, x86::tr7
479         },
480         {
481             x86_64::r8, x86_64::r9, x86_64::r10, x86_64::r11, x86_64::r12, x86_64::r13, x86_64::r14, x86_64::r15
482         },
483         {
484             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil
485         },
486         {
487             x86::st0, x86::st1, x86::st2, x86::st3, x86::st4, x86::st5, x86::st6, x86::st7
488         }
489
490     };
491     static MachRegister IntelRegTable64[][8] = {
492         {
493             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::ah, x86_64::ch, x86_64::dh, x86_64::bh
494         },
495         {
496             x86_64::ax, x86_64::cx, x86_64::dx, x86_64::bx, x86_64::sp, x86_64::bp, x86_64::si, x86_64::di
497         },
498         {
499             x86_64::eax, x86_64::ecx, x86_64::edx, x86_64::ebx, x86_64::esp, x86_64::ebp, x86_64::esi, x86_64::edi
500         },
501         {
502             x86_64::es, x86_64::cs, x86_64::ss, x86_64::ds, x86_64::fs, x86_64::gs, InvalidReg, InvalidReg
503         },
504         {
505             x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi
506         },
507         {
508             x86_64::xmm0, x86_64::xmm1, x86_64::xmm2, x86_64::xmm3, x86_64::xmm4, x86_64::xmm5, x86_64::xmm6, x86_64::xmm7
509         },
510         {
511             x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15
512         },
513         {
514             x86_64::mm0, x86_64::mm1, x86_64::mm2, x86_64::mm3, x86_64::mm4, x86_64::mm5, x86_64::mm6, x86_64::mm7
515         },
516         {
517             x86_64::cr0, x86_64::cr1, x86_64::cr2, x86_64::cr3, x86_64::cr4, x86_64::cr5, x86_64::cr6, x86_64::cr7
518         },
519         {
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         },
522         {
523             x86_64::tr0, x86_64::tr1, x86_64::tr2, x86_64::tr3, x86_64::tr4, x86_64::tr5, x86_64::tr6, x86_64::tr7
524         },
525         {
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         },
528         {
529             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil
530         },
531         {
532             x86_64::st0, x86_64::st1, x86_64::st2, x86_64::st3, x86_64::st4, x86_64::st5, x86_64::st6, x86_64::st7
533         },
534         {
535             x86_64::r8b, x86_64::r9b, x86_64::r10b, x86_64::r11b, x86_64::r12b, x86_64::r13b, x86_64::r14b, x86_64::r15b 
536         },
537         {
538             x86_64::r8w, x86_64::r9w, x86_64::r10w, x86_64::r11w, x86_64::r12w, x86_64::r13w, x86_64::r14w, x86_64::r15w 
539         },
540         {
541             x86_64::r8d, x86_64::r9d, x86_64::r10d, x86_64::r11d, x86_64::r12d, x86_64::r13d, x86_64::r14d, x86_64::r15d 
542         },
543   {
544     x86_64::ymm0, x86_64::ymm1, x86_64::ymm2, x86_64::ymm3, x86_64::ymm4, x86_64::ymm5, x86_64::ymm6, x86_64::ymm7
545   },
546   {
547     x86_64::ymm8, x86_64::ymm9, x86_64::ymm10, x86_64::ymm11, x86_64::ymm12, x86_64::ymm13, x86_64::ymm14, x86_64::ymm15
548   }
549
550     };
551
552   /* Uses the appropriate lookup table based on the 
553      decoder architecture */
554   class IntelRegTable_access {
555     public:
556         inline MachRegister operator()(Architecture arch,
557                                        intelRegBanks bank,
558                                        int index)
559         {
560             assert(index >= 0 && index < 8);
561     
562             if(arch == Arch_x86_64)
563                 return IntelRegTable64[bank][index];
564             else if(arch == Arch_x86) 
565             {
566               if(bank > b_fpstack) return InvalidReg;
567               return IntelRegTable32[bank][index];
568             }
569             assert(0);
570             return InvalidReg;
571         }
572
573   };
574   static IntelRegTable_access IntelRegTable;
575
576       bool InstructionDecoder_x86::isDefault64Insn()
577       {
578         switch(m_Operation->getID())
579         {
580         case e_jmp:
581         case e_pop:
582         case e_push:
583         case e_call:
584           return true;
585         default:
586           return false;
587         }
588         
589       }
590       
591
592     MachRegister InstructionDecoder_x86::makeRegisterID(unsigned int intelReg, unsigned int opType,
593                                         bool isExtendedReg)
594     {
595         MachRegister retVal;
596         
597
598         if(isExtendedReg)
599         {
600             switch(opType)
601             {
602                 case op_q:  
603                     retVal = IntelRegTable(m_Arch,b_amd64ext,intelReg);
604                     break;
605                 case op_d:
606                     retVal = IntelRegTable(m_Arch,amd64_ext_32,intelReg);
607                     break;
608                 case op_w:
609                     retVal = IntelRegTable(m_Arch,amd64_ext_16,intelReg);
610                     break;
611                 case op_b:
612                     retVal = IntelRegTable(m_Arch,amd64_ext_8,intelReg);
613                     break;
614                 case op_v:
615                     if (locs->rex_w || isDefault64Insn())
616                         retVal = IntelRegTable(m_Arch, b_amd64ext, intelReg);
617                     else if (!sizePrefixPresent)
618                         retVal = IntelRegTable(m_Arch, amd64_ext_32, intelReg);
619                     //else
620                     //    retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
621                     break;      
622                 case op_p:
623                 case op_z:
624                     //              if (!sizePrefixPresent)
625                         retVal = IntelRegTable(m_Arch, amd64_ext_32, intelReg);
626                         //                  else
627                         //  retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
628                     break;
629             case op_f:
630             case op_dbl:
631                 // extended reg ignored on FP regs
632                 retVal = IntelRegTable(m_Arch, b_fpstack,intelReg);
633                 break;
634                 default:
635                     retVal = InvalidReg;
636             }
637         }
638         /* Promotion to 64-bit only applies to the operand types
639            that are varible (c,v,z). Ignoring c and z because they
640            do the right thing on 32- and 64-bit code.
641         else if(locs->rex_w)
642         {
643             // AMD64 with 64-bit operands
644             retVal = IntelRegTable[b_64bit][intelReg];
645         }
646         */
647         else
648         {
649             switch(opType)
650             {
651                 case op_v:
652                   if(locs->rex_w || isDefault64Insn())
653                         retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
654                     else
655                         retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
656                     break;
657                 case op_b:
658                     if (locs->rex_byte & 0x40) {
659                         retVal = IntelRegTable(m_Arch,b_8bitWithREX,intelReg);
660                     } else {
661                         retVal = IntelRegTable(m_Arch,b_8bitNoREX,intelReg);
662                     }
663                     break;
664                 case op_q:
665                     retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
666                     break;
667                 case op_w:
668                     retVal = IntelRegTable(m_Arch,b_16bit,intelReg);
669                     break;
670                 case op_f:
671                 case op_dbl:
672                     retVal = IntelRegTable(m_Arch,b_fpstack,intelReg);
673                     break;
674                 case op_d:
675                 case op_si:
676                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
677                     break;
678                 default:
679                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
680                     break;
681             }
682         }
683
684         if (!ia32_is_mode_64()) {
685           if ((retVal.val() & 0x00ffffff) == 0x0001000c)
686             assert(0);
687         }
688
689         return MachRegister((retVal.val() & ~retVal.getArchitecture()) | m_Arch);
690     }
691     
692     Result_Type InstructionDecoder_x86::makeSizeType(unsigned int opType)
693     {
694         switch(opType)
695         {
696             case op_b:
697             case op_c:
698                 return u8;
699             case op_d:
700             case op_ss:
701             case op_allgprs:
702             case op_si:
703                 return u32;
704             case op_w:
705             case op_a:
706                 return u16;
707             case op_q:
708             case op_sd:
709                 return u64;
710             case op_v:
711             case op_lea:
712             case op_z:
713                 if (locs->rex_w) 
714                 {
715                     return u64;
716                 }
717                 //if(ia32_is_mode_64() || !sizePrefixPresent)
718                 //{
719                     return u32;
720                     //}
721                     //else
722                     //{
723                     //return u16;
724                     //}
725                 break;
726             case op_y:
727                 if(ia32_is_mode_64())
728                         return u64;
729                 else
730                         return u32;
731                 break;
732             case op_p:
733                 // book says operand size; arch-x86 says word + word * operand size
734                 if(!ia32_is_mode_64() ^ sizePrefixPresent)
735                 {
736                     return u48;
737                 }
738                 else
739                 {
740                     return u32;
741                 }
742             case op_dq:
743             case op_qq:
744                 return u64;
745             case op_512:
746                 return m512;
747             case op_pi:
748             case op_ps:
749             case op_pd:
750                 return dbl128;
751             case op_s:
752                 return u48;
753             case op_f:
754                 return sp_float;
755             case op_dbl:
756                 return dp_float;
757             case op_14:
758                 return m14;
759             default:
760                 assert(!"Can't happen!");
761                 return u8;
762         }
763     }
764
765
766     bool InstructionDecoder_x86::decodeOneOperand(const InstructionDecoder::buffer& b,
767                                                   const ia32_operand& operand,
768                                                   int & imm_index, /* immediate operand index */
769                                                   const Instruction* insn_to_complete, 
770                                                   bool isRead, bool isWritten)
771     {
772        bool isCFT = false;
773       bool isCall = false;
774       bool isConditional = false;
775       InsnCategory cat = insn_to_complete->getCategory();
776       if(cat == c_BranchInsn || cat == c_CallInsn)
777         {
778           isCFT = true;
779           if(cat == c_CallInsn)
780             {
781               isCall = true;
782             }
783         }
784       if (cat == c_BranchInsn && insn_to_complete->getOperation().getID() != e_jmp) {
785         isConditional = true;
786       }
787
788       unsigned int optype = operand.optype;
789       int vex_vvvv = 0;
790       // int vex_l = 0;
791     if(decodedInstruction && decodedInstruction->getPrefix()->vex_prefix[0])
792     {
793       /* The vvvv bits are bits 3, 4, 5, 6 and are in 1's complement */
794       if(decodedInstruction->getPrefix()->vex_prefix[1])
795       {
796         // vex_l = decodedInstruction->getPrefix()->vex_prefix[1] & VEX3_L;
797         vex_vvvv = GETVEX_VVVV(decodedInstruction->getPrefix()->vex_prefix[1]);
798       } else {
799         // vex_l = decodedInstruction->getPrefix()->vex_prefix[0] & VEX2_L;
800         vex_vvvv = GETVEX_VVVV(decodedInstruction->getPrefix()->vex_prefix[0]);
801       }
802     }
803       if (sizePrefixPresent && 
804           ((optype == op_v) ||
805            (optype == op_z)) &&
806           (operand.admet != am_J)) {
807         optype = op_w;
808       }
809       if(optype == op_y) {
810           if(ia32_is_mode_64() && locs->rex_w)
811                   optype = op_q;
812           else
813                   optype = op_d;
814       }
815                 switch(operand.admet)
816                 {
817                     case 0:
818                     // No operand
819                     {
820 /*                        fprintf(stderr, "ERROR: Instruction with mismatched operands. Raw bytes: ");
821                         for(unsigned int i = 0; i < decodedInstruction->getSize(); i++) {
822                             fprintf(stderr, "%x ", b.start[i]);
823                         }
824                         fprintf(stderr, "\n");*/
825                         assert(!"Mismatched number of operands--check tables");
826                         return false;
827                     }
828                     case am_A:
829                     {
830                         // am_A only shows up as a far call/jump.  Position 1 should be universally safe.
831                         Expression::Ptr addr(decodeImmediate(optype, b.start + 1));
832                         insn_to_complete->addSuccessor(addr, isCall, false, false, false);
833                     }
834                     break;
835                     case am_C:
836                     {
837                         Expression::Ptr op(makeRegisterExpression(IntelRegTable(m_Arch,b_cr,locs->modrm_reg)));
838                         insn_to_complete->appendOperand(op, isRead, isWritten);
839                     }
840                     break;
841                     case am_D:
842                     {
843                         Expression::Ptr op(makeRegisterExpression(IntelRegTable(m_Arch,b_dr,locs->modrm_reg)));
844                         insn_to_complete->appendOperand(op, isRead, isWritten);
845                     }
846                     break;
847                     case am_E:
848                     // am_M is like am_E, except that mod of 0x03 should never occur (am_M specified memory,
849                     // mod of 0x03 specifies direct register access).
850                     case am_M:
851                     // am_R is the inverse of am_M; it should only have a mod of 3
852                     case am_R:
853                     // can be am_R or am_M      
854                     case am_RM: 
855                         if(isCFT)
856                         {
857                           insn_to_complete->addSuccessor(makeModRMExpression(b, optype), isCall, true, false, false);
858                         }
859                         else
860                         {
861                           insn_to_complete->appendOperand(makeModRMExpression(b, optype), isRead, isWritten);
862                         }
863                     break;
864                     case am_F:
865                     {
866                         Expression::Ptr op(makeRegisterExpression(x86::flags));
867                         insn_to_complete->appendOperand(op, isRead, isWritten);
868                     }
869                     break;
870                     case am_G:
871                     {
872                         Expression::Ptr op(makeRegisterExpression(makeRegisterID(locs->modrm_reg,
873                                 optype, locs->rex_r)));
874                         insn_to_complete->appendOperand(op, isRead, isWritten);
875                     }
876                     break;
877                     case am_H:
878                       {
879                           /* Operand comes from the VEX.vvvv bits */
880                          insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
881                               vex_vvvv <= 7 ? b_xmm : b_xmmhigh, vex_vvvv <= 7 ? vex_vvvv : vex_vvvv - 8)),
882                               isRead, isWritten);
883                       }
884                       break;
885                     case am_I:
886                         insn_to_complete->appendOperand(decodeImmediate(optype, b.start + 
887                                                                         locs->imm_position[imm_index++]), 
888                                                         isRead, isWritten);
889                         break;
890                     case am_J:
891                     {
892                         Expression::Ptr Offset(decodeImmediate(optype, 
893                                                                b.start + locs->imm_position[imm_index++], 
894                                                                true));
895                         Expression::Ptr EIP(makeRegisterExpression(MachRegister::getPC(m_Arch)));
896                         Expression::Ptr InsnSize(make_shared(singleton_object_pool<Immediate>::construct(Result(u8,
897                             decodedInstruction->getSize()))));
898                         Expression::Ptr postEIP(makeAddExpression(EIP, InsnSize, u32));
899
900                         Expression::Ptr op(makeAddExpression(Offset, postEIP, u32));
901                         insn_to_complete->addSuccessor(op, isCall, false, isConditional, false);
902                         if (isConditional) 
903                           insn_to_complete->addSuccessor(postEIP, false, false, true, true);
904                     }
905                     break;
906                     case am_O:
907                     {
908                     // Address/offset width, which is *not* what's encoded by the optype...
909                     // The deref's width is what's actually encoded here.
910                         int pseudoOpType;
911                         switch(locs->address_size)
912                         {
913                             case 1:
914                                 pseudoOpType = op_b;
915                                 break;
916                             case 2:
917                                 pseudoOpType = op_w;
918                                 break;
919                             case 4:
920                                 pseudoOpType = op_d;
921                                 break;
922                             case 0:
923                                 if(m_Arch == Arch_x86_64) {
924                                     if(!addrSizePrefixPresent)
925                                         pseudoOpType = op_q;
926                                     else
927                                         pseudoOpType = op_d;
928                                 } else {
929                                     pseudoOpType = op_v;
930                                 }
931                                 break;
932                             default:
933                                 assert(!"Bad address size, should be 0, 1, 2, or 4!");
934                                 pseudoOpType = op_b;
935                                 break;
936                         }
937
938
939                         int offset_position = locs->opcode_position;
940                         if(locs->modrm_position > offset_position && locs->modrm_operand <
941                            (int)(insn_to_complete->m_Operands.size()))
942                         {
943                             offset_position = locs->modrm_position;
944                         }
945                         if(locs->sib_position > offset_position)
946                         {
947                             offset_position = locs->sib_position;
948                         }
949                         offset_position++;
950                         insn_to_complete->appendOperand(makeDereferenceExpression(
951                                 decodeImmediate(pseudoOpType, b.start + offset_position), makeSizeType(optype)), 
952                                                         isRead, isWritten);
953                     }
954                     break;
955                     case am_P:
956                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_mm,locs->modrm_reg)),
957                                 isRead, isWritten);
958                         break;
959                     case am_Q:
960         
961                         switch(locs->modrm_mod)
962                         {
963                             // direct dereference
964                             case 0x00:
965                             case 0x01:
966                             case 0x02:
967                               insn_to_complete->appendOperand(makeModRMExpression(b, optype), isRead, isWritten);
968                                 break;
969                             case 0x03:
970                                 // use of actual register
971                                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_mm,locs->modrm_rm)),
972                                                                isRead, isWritten);
973                                 break;
974                             default:
975                                 assert(!"2-bit value modrm_mod out of range");
976                                 break;
977                         };
978                         break;
979                     case am_S:
980                     // Segment register in modrm reg field.
981                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_segment,locs->modrm_reg)),
982                                 isRead, isWritten);
983                         break;
984                     case am_T:
985                         // test register in modrm reg; should only be tr6/tr7, but we'll decode any of them
986                         // NOTE: this only appears in deprecated opcodes
987                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_tr,locs->modrm_reg)),
988                                                        isRead, isWritten);
989                         break;
990                     case am_UM:
991                         switch(locs->modrm_mod)
992                         {
993                         // direct dereference
994                         case 0x00:
995                         case 0x01:
996                         case 0x02:
997                                 insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)),
998                                                 isRead, isWritten);
999                                 break;
1000                         case 0x03:
1001                                 // use of actual register
1002                                 {
1003                                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
1004                                                         locs->rex_b ? b_xmmhigh : b_xmm, locs->modrm_rm)),
1005                                                         isRead, isWritten);
1006                                         break;
1007                                 }
1008                         default:
1009                                 assert(!"2-bit value modrm_mod out of range");
1010                                 break;
1011                         };
1012                         break;
1013                     case am_V:
1014                        
1015                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
1016                                 locs->rex_r ? b_xmmhigh : b_xmm,locs->modrm_reg)),
1017                                     isRead, isWritten);
1018                         break;
1019                     case am_W:
1020                         switch(locs->modrm_mod)
1021                         {
1022                             // direct dereference
1023                             case 0x00:
1024                             case 0x01:
1025                             case 0x02:
1026                               insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)),
1027                                                                isRead, isWritten);
1028                                 break;
1029                             case 0x03:
1030                             // use of actual register
1031                             {
1032                                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
1033                                         locs->rex_b ? b_xmmhigh : b_xmm, locs->modrm_rm)),
1034                                         isRead, isWritten);
1035                                 break;
1036                             }
1037                             default:
1038                                 assert(!"2-bit value modrm_mod out of range");
1039                                 break;
1040                         };
1041                         break;
1042                     case am_X:
1043                     {
1044                         MachRegister si_reg;
1045                         if(m_Arch == Arch_x86)
1046                         {
1047                                 if(addrSizePrefixPresent)
1048                                 {
1049                                         si_reg = x86::si;
1050                                 } else
1051                                 {
1052                                         si_reg = x86::esi;
1053                                 }
1054                         }
1055                         else
1056                         {
1057                                 if(addrSizePrefixPresent)
1058                                 {
1059                                         si_reg = x86_64::esi;
1060                                 } else
1061                                 {
1062                                         si_reg = x86_64::rsi;
1063                                 }
1064                         }
1065                         Expression::Ptr ds(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ds : x86_64::ds));
1066                         Expression::Ptr si(makeRegisterExpression(si_reg));
1067                         Expression::Ptr segmentOffset(make_shared(singleton_object_pool<Immediate>::construct(
1068                                 Result(u32, 0x10))));
1069                         Expression::Ptr ds_segment = makeMultiplyExpression(ds, segmentOffset, u32);
1070                         Expression::Ptr ds_si = makeAddExpression(ds_segment, si, u32);
1071                         insn_to_complete->appendOperand(makeDereferenceExpression(ds_si, makeSizeType(optype)),
1072                                                        isRead, isWritten);
1073                     }
1074                     break;
1075                     case am_Y:
1076                     {
1077                         MachRegister di_reg;
1078                         if(m_Arch == Arch_x86)
1079                         {
1080                                 if(addrSizePrefixPresent)
1081                                 {
1082                                         di_reg = x86::di;
1083                                 } else
1084                                 {
1085                                         di_reg = x86::edi;
1086                                 }
1087                         }
1088                         else
1089                         {
1090                                 if(addrSizePrefixPresent)
1091                                 {
1092                                         di_reg = x86_64::edi;
1093                                 } else
1094                                 {
1095                                         di_reg = x86_64::rdi;
1096                                 }
1097                         }
1098                         Expression::Ptr es(makeRegisterExpression(m_Arch == Arch_x86 ? x86::es : x86_64::es));
1099                         Expression::Ptr di(makeRegisterExpression(di_reg));
1100                         Expression::Ptr es_segment = makeMultiplyExpression(es,
1101                             make_shared(singleton_object_pool<Immediate>::construct(Result(u32, 0x10))), u32);
1102                         Expression::Ptr es_di = makeAddExpression(es_segment, di, u32);
1103                         insn_to_complete->appendOperand(makeDereferenceExpression(es_di, makeSizeType(optype)),
1104                                                        isRead, isWritten);
1105                     }
1106                     break;
1107                     case am_tworeghack:
1108                     {
1109                         if(optype == op_edxeax)
1110                         {
1111                             Expression::Ptr edx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::edx : x86_64::edx));
1112                             Expression::Ptr eax(makeRegisterExpression(m_Arch == Arch_x86 ? x86::eax : x86_64::eax));
1113                             Expression::Ptr highAddr = makeMultiplyExpression(edx,
1114                                     Immediate::makeImmediate(Result(u64, 2^32)), u64);
1115                             Expression::Ptr addr = makeAddExpression(highAddr, eax, u64);
1116                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1117                             insn_to_complete->appendOperand(op, isRead, isWritten);
1118                         }
1119                         else if (optype == op_ecxebx)
1120                         {
1121                             Expression::Ptr ecx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ecx : x86_64::ecx));
1122                             Expression::Ptr ebx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ebx : x86_64::ebx));
1123                             Expression::Ptr highAddr = makeMultiplyExpression(ecx,
1124                                     Immediate::makeImmediate(Result(u64, 2^32)), u64);
1125                             Expression::Ptr addr = makeAddExpression(highAddr, ebx, u64);
1126                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1127                             insn_to_complete->appendOperand(op, isRead, isWritten);
1128                         }
1129                     }
1130                     break;
1131                     
1132                     case am_reg:
1133                     {
1134                         MachRegister r(optype);
1135                         int size = r.size();
1136                         if((m_Arch == Arch_x86_64) && (r.regClass() == x86::GPR) && (size == 4))
1137                         {
1138                             int reg_size = isDefault64Insn() ? op_q : op_v;
1139                             if(sizePrefixPresent)
1140                             {
1141                                 reg_size = op_w;
1142                             }
1143                             // implicit regs are not extended
1144                             r = makeRegisterID((r.val() & 0xFF), reg_size, false);
1145                             entryID entryid = decodedInstruction->getEntry()->getID(locs);
1146                             if(locs->rex_b && insn_to_complete->m_Operands.empty() &&
1147                                (entryid == e_push || entryid == e_pop || entryid == e_xchg || ((*(b.start + locs->opcode_position) & 0xf0) == 0xb0)))
1148                             {
1149                                 r = MachRegister((r.val()) | x86_64::r8.val());
1150                                 assert(r.name() != "<INVALID_REG>");
1151                             }
1152                         }
1153                         else 
1154                         {
1155                             r = MachRegister((r.val() & ~r.getArchitecture()) | m_Arch);
1156                             
1157                             entryID entryid = decodedInstruction->getEntry()->getID(locs);
1158                             if(insn_to_complete->m_Operands.empty() && 
1159                                (entryid == e_push || entryid == e_pop || entryid == e_xchg || ((*(b.start + locs->opcode_position) & 0xf0) == 0xb0) ) )
1160                             {
1161                                 unsigned int opcode_byte = *(b.start+locs->opcode_position);
1162                                 unsigned int reg_id = (opcode_byte & 0x07);
1163                                 if(locs->rex_b) 
1164                                 {
1165                                     // FP stack registers are not affected by the rex_b bit in AM_REG.
1166                                     if(r.regClass() == (unsigned) x86::GPR)
1167                                     {
1168                                         int reg_op_type = op_d;
1169                                         switch(size)
1170                                         {
1171                                         case 1:
1172                                             reg_op_type = op_b;
1173                                             break;
1174                                         case 2:
1175                                             reg_op_type = op_w;
1176                                             break;
1177                                         case 8:
1178                                             reg_op_type = op_q;
1179                                             break;
1180                                         default:
1181                                             break;
1182                                         }
1183                                         r = makeRegisterID(reg_id, reg_op_type, true);
1184                                         //                                      r = MachRegister((r.val()) | x86_64::r8.val());
1185                                         assert(r.name() != "<INVALID_REG>");
1186                                     }
1187                                 }
1188                                 else if((r.size() == 1) && (locs->rex_byte & 0x40))
1189                                 {
1190                                     r = makeRegisterID(reg_id, op_b, false);
1191                                     assert(r.name() != "<INVALID_REG>");
1192                                 }
1193                             }
1194                             if(sizePrefixPresent && (r.regClass() == x86::GPR) && r.size() >= 4)
1195                             {
1196                                 r = MachRegister((r.val() & ~x86::FULL) | x86::W_REG);
1197                                 assert(r.name() != "<INVALID_REG>");
1198                             }
1199                         }
1200                         Expression::Ptr op(makeRegisterExpression(r));
1201                         insn_to_complete->appendOperand(op, isRead, isWritten);
1202                     }
1203                     break;
1204                 case am_stackH:
1205                 case am_stackP:
1206                 // handled elsewhere
1207                     break;
1208                 case am_allgprs:
1209                 {
1210                     if(m_Arch == Arch_x86)
1211                     {
1212                         insn_to_complete->appendOperand(makeRegisterExpression(x86::eax), isRead, isWritten);
1213                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ecx), isRead, isWritten);
1214                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edx), isRead, isWritten);
1215                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebx), isRead, isWritten);
1216                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esp), isRead, isWritten);
1217                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebp), isRead, isWritten);
1218                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esi), isRead, isWritten);
1219                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edi), isRead, isWritten);
1220                     }
1221                     else
1222                     {
1223                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::eax), isRead, isWritten);
1224                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ecx), isRead, isWritten);
1225                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edx), isRead, isWritten);
1226                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebx), isRead, isWritten);
1227                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esp), isRead, isWritten);
1228                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebp), isRead, isWritten);
1229                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esi), isRead, isWritten);
1230                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edi), isRead, isWritten);
1231                     }
1232                 }
1233                     break;
1234                 case am_ImplImm: {
1235                   insn_to_complete->appendOperand(Immediate::makeImmediate(Result(makeSizeType(optype), 1)), isRead, isWritten);
1236                   break;
1237                 }
1238
1239                 default:
1240                     printf("decodeOneOperand() called with unknown addressing method %d\n", operand.admet);
1241                         break;
1242                 };
1243                 return true;
1244             }
1245
1246     extern ia32_entry invalid;
1247     
1248     void InstructionDecoder_x86::doIA32Decode(InstructionDecoder::buffer& b)
1249     {
1250         if(decodedInstruction == NULL)
1251         {
1252             decodedInstruction = reinterpret_cast<ia32_instruction*>(malloc(sizeof(ia32_instruction)));
1253             assert(decodedInstruction);
1254         }
1255         if(locs == NULL)
1256         {
1257             locs = reinterpret_cast<ia32_locations*>(malloc(sizeof(ia32_locations)));
1258             assert(locs);
1259         }
1260         locs = new(locs) ia32_locations; //reinit();
1261         assert(locs->sib_position == -1);
1262         decodedInstruction = new (decodedInstruction) ia32_instruction(NULL, NULL, locs);
1263         ia32_decode(IA32_DECODE_PREFIXES, b.start, *decodedInstruction);
1264         sizePrefixPresent = (decodedInstruction->getPrefix()->getOperSzPrefix() == 0x66);
1265         if (decodedInstruction->getPrefix()->rexW()) {
1266            // as per 2.2.1.2 - rex.w overrides 66h
1267            sizePrefixPresent = false;
1268         }
1269         addrSizePrefixPresent = (decodedInstruction->getPrefix()->getAddrSzPrefix() == 0x67);
1270         static ia32_entry invalid = { e_No_Entry, 0, 0, false, { {0,0}, {0,0}, {0,0} }, 0, 0 };
1271         if(decodedInstruction->getEntry()) {
1272             // check prefix validity
1273             // lock prefix only allowed on certain insns.
1274             // TODO: refine further to check memory written operand
1275             if(decodedInstruction->getPrefix()->getPrefix(0) == PREFIX_LOCK)
1276             {
1277                 switch(decodedInstruction->getEntry()->id)
1278                 {
1279                 case e_add:
1280                 case e_adc:
1281                 case e_and:
1282                 case e_btc:
1283                 case e_btr:
1284                 case e_bts:
1285                 case e_cmpxch:
1286                 case e_cmpxch8b:
1287                 case e_dec:
1288                 case e_inc:
1289                 case e_neg:
1290                 case e_not:
1291                 case e_or:
1292                 case e_sbb:
1293                 case e_sub:
1294                 case e_xor:
1295                 case e_xadd:
1296                 case e_xchg:
1297                     break;
1298                 default:
1299                     m_Operation = make_shared(singleton_object_pool<Operation>::construct(&invalid,
1300                                     decodedInstruction->getPrefix(), locs, m_Arch));
1301                     return;
1302                 }
1303             }
1304             m_Operation = make_shared(singleton_object_pool<Operation>::construct(decodedInstruction->getEntry(),
1305                                     decodedInstruction->getPrefix(), locs, m_Arch));
1306             
1307         }
1308         else
1309         {
1310                 // Gap parsing can trigger this case; in particular, when it encounters prefixes in an invalid order.
1311                 // Notably, if a REX prefix (0x40-0x48) appears followed by another prefix (0x66, 0x67, etc)
1312                 // we'll reject the instruction as invalid and send it back with no entry.  Since this is a common
1313                 // byte sequence to see in, for example, ASCII strings, we want to simply accept this and move on, not
1314                 // yell at the user.
1315             m_Operation = make_shared(singleton_object_pool<Operation>::construct(&invalid,
1316                                     decodedInstruction->getPrefix(), locs, m_Arch));
1317         }
1318
1319     }
1320     
1321     void InstructionDecoder_x86::decodeOpcode(InstructionDecoder::buffer& b)
1322     {
1323         doIA32Decode(b);
1324         b.start += decodedInstruction->getSize();
1325     }
1326     
1327       bool InstructionDecoder_x86::decodeOperands(const Instruction* insn_to_complete)
1328     {
1329        int imm_index = 0; // handle multiple immediate operands
1330         if(!decodedInstruction) return false;
1331         unsigned int opsema = decodedInstruction->getEntry()->opsema & 0xFF;
1332         InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1333
1334         if (decodedInstruction->getEntry()->getID() == e_ret_near ||
1335             decodedInstruction->getEntry()->getID() == e_ret_far) {
1336            Expression::Ptr ret_addr = makeDereferenceExpression(makeRegisterExpression(ia32_is_mode_64() ? x86_64::rsp : x86::esp), 
1337                                                                 ia32_is_mode_64() ? u64 : u32);
1338            insn_to_complete->addSuccessor(ret_addr, false, true, false, false);
1339         }
1340
1341         for(unsigned i = 0; i < 3; i++)
1342         {
1343             if(decodedInstruction->getEntry()->operands[i].admet == 0 && 
1344                decodedInstruction->getEntry()->operands[i].optype == 0)
1345                 return true;
1346             if(!decodeOneOperand(b,
1347                                  decodedInstruction->getEntry()->operands[i], 
1348                                  imm_index, 
1349                                  insn_to_complete, 
1350                                  readsOperand(opsema, i),
1351                                  writesOperand(opsema, i)))
1352             {
1353                 return false;
1354             }
1355         }
1356     
1357         return true;
1358     }
1359
1360     
1361       INSTRUCTION_EXPORT Instruction::Ptr InstructionDecoder_x86::decode(InstructionDecoder::buffer& b)
1362     {
1363         return InstructionDecoderImpl::decode(b);
1364     }
1365     void InstructionDecoder_x86::doDelayedDecode(const Instruction* insn_to_complete)
1366     {
1367       InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1368       //insn_to_complete->m_Operands.reserve(4);
1369       doIA32Decode(b);        
1370       decodeOperands(insn_to_complete);
1371     }
1372     
1373 };
1374 };
1375