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