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