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