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