/src/capstonev5/arch/X86/X86Disassembler.c
Line  | Count  | Source  | 
1  |  | //===-- X86Disassembler.cpp - Disassembler for x86 and x86_64 -------------===//  | 
2  |  | //  | 
3  |  | //                     The LLVM Compiler Infrastructure  | 
4  |  | //  | 
5  |  | // This file is distributed under the University of Illinois Open Source  | 
6  |  | // License. See LICENSE.TXT for details.  | 
7  |  | //  | 
8  |  | //===----------------------------------------------------------------------===//  | 
9  |  | //  | 
10  |  | // This file is part of the X86 Disassembler.  | 
11  |  | // It contains code to translate the data produced by the decoder into  | 
12  |  | //  MCInsts.  | 
13  |  | //  | 
14  |  | // The X86 disassembler is a table-driven disassembler for the 16-, 32-, and  | 
15  |  | // 64-bit X86 instruction sets.  The main decode sequence for an assembly  | 
16  |  | // instruction in this disassembler is:  | 
17  |  | //  | 
18  |  | // 1. Read the prefix bytes and determine the attributes of the instruction.  | 
19  |  | //    These attributes, recorded in enum attributeBits  | 
20  |  | //    (X86DisassemblerDecoderCommon.h), form a bitmask.  The table CONTEXTS_SYM  | 
21  |  | //    provides a mapping from bitmasks to contexts, which are represented by  | 
22  |  | //    enum InstructionContext (ibid.).  | 
23  |  | //  | 
24  |  | // 2. Read the opcode, and determine what kind of opcode it is.  The  | 
25  |  | //    disassembler distinguishes four kinds of opcodes, which are enumerated in  | 
26  |  | //    OpcodeType (X86DisassemblerDecoderCommon.h): one-byte (0xnn), two-byte  | 
27  |  | //    (0x0f 0xnn), three-byte-38 (0x0f 0x38 0xnn), or three-byte-3a  | 
28  |  | //    (0x0f 0x3a 0xnn).  Mandatory prefixes are treated as part of the context.  | 
29  |  | //  | 
30  |  | // 3. Depending on the opcode type, look in one of four ClassDecision structures  | 
31  |  | //    (X86DisassemblerDecoderCommon.h).  Use the opcode class to determine which  | 
32  |  | //    OpcodeDecision (ibid.) to look the opcode in.  Look up the opcode, to get  | 
33  |  | //    a ModRMDecision (ibid.).  | 
34  |  | //  | 
35  |  | // 4. Some instructions, such as escape opcodes or extended opcodes, or even  | 
36  |  | //    instructions that have ModRM*Reg / ModRM*Mem forms in LLVM, need the  | 
37  |  | //    ModR/M byte to complete decode.  The ModRMDecision's type is an entry from  | 
38  |  | //    ModRMDecisionType (X86DisassemblerDecoderCommon.h) that indicates if the  | 
39  |  | //    ModR/M byte is required and how to interpret it.  | 
40  |  | //  | 
41  |  | // 5. After resolving the ModRMDecision, the disassembler has a unique ID  | 
42  |  | //    of type InstrUID (X86DisassemblerDecoderCommon.h).  Looking this ID up in  | 
43  |  | //    INSTRUCTIONS_SYM yields the name of the instruction and the encodings and  | 
44  |  | //    meanings of its operands.  | 
45  |  | //  | 
46  |  | // 6. For each operand, its encoding is an entry from OperandEncoding  | 
47  |  | //    (X86DisassemblerDecoderCommon.h) and its type is an entry from  | 
48  |  | //    OperandType (ibid.).  The encoding indicates how to read it from the  | 
49  |  | //    instruction; the type indicates how to interpret the value once it has  | 
50  |  | //    been read.  For example, a register operand could be stored in the R/M  | 
51  |  | //    field of the ModR/M byte, the REG field of the ModR/M byte, or added to  | 
52  |  | //    the main opcode.  This is orthogonal from its meaning (an GPR or an XMM  | 
53  |  | //    register, for instance).  Given this information, the operands can be  | 
54  |  | //    extracted and interpreted.  | 
55  |  | //  | 
56  |  | // 7. As the last step, the disassembler translates the instruction information  | 
57  |  | //    and operands into a format understandable by the client - in this case, an  | 
58  |  | //    MCInst for use by the MC infrastructure.  | 
59  |  | //  | 
60  |  | // The disassembler is broken broadly into two parts: the table emitter that  | 
61  |  | // emits the instruction decode tables discussed above during compilation, and  | 
62  |  | // the disassembler itself.  The table emitter is documented in more detail in  | 
63  |  | // utils/TableGen/X86DisassemblerEmitter.h.  | 
64  |  | //  | 
65  |  | // X86Disassembler.cpp contains the code responsible for step 7, and for  | 
66  |  | //   invoking the decoder to execute steps 1-6.  | 
67  |  | // X86DisassemblerDecoderCommon.h contains the definitions needed by both the  | 
68  |  | //   table emitter and the disassembler.  | 
69  |  | // X86DisassemblerDecoder.h contains the public interface of the decoder,  | 
70  |  | //   factored out into C for possible use by other projects.  | 
71  |  | // X86DisassemblerDecoder.c contains the source code of the decoder, which is  | 
72  |  | //   responsible for steps 1-6.  | 
73  |  | //  | 
74  |  | //===----------------------------------------------------------------------===//  | 
75  |  |  | 
76  |  | /* Capstone Disassembly Engine */  | 
77  |  | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */  | 
78  |  |  | 
79  |  | #ifdef CAPSTONE_HAS_X86  | 
80  |  |  | 
81  |  | #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)  | 
82  |  | #pragma warning(disable:4996)     // disable MSVC's warning on strncpy()  | 
83  |  | #pragma warning(disable:28719)    // disable MSVC's warning on strncpy()  | 
84  |  | #endif  | 
85  |  |  | 
86  |  | #include <capstone/platform.h>  | 
87  |  |  | 
88  |  | #if defined(CAPSTONE_HAS_OSXKERNEL)  | 
89  |  | #include <Availability.h>  | 
90  |  | #endif  | 
91  |  |  | 
92  |  | #include <string.h>  | 
93  |  |  | 
94  |  | #include "../../cs_priv.h"  | 
95  |  |  | 
96  |  | #include "X86BaseInfo.h"  | 
97  |  | #include "X86Disassembler.h"  | 
98  |  | #include "X86DisassemblerDecoderCommon.h"  | 
99  |  | #include "X86DisassemblerDecoder.h"  | 
100  |  | #include "../../MCInst.h"  | 
101  |  | #include "../../utils.h"  | 
102  |  | #include "X86Mapping.h"  | 
103  |  |  | 
104  |  | #define GET_REGINFO_ENUM  | 
105  |  | #define GET_REGINFO_MC_DESC  | 
106  |  | #include "X86GenRegisterInfo.inc"  | 
107  |  |  | 
108  |  | #define GET_INSTRINFO_ENUM  | 
109  |  | #ifdef CAPSTONE_X86_REDUCE  | 
110  |  | #include "X86GenInstrInfo_reduce.inc"  | 
111  |  | #else  | 
112  |  | #include "X86GenInstrInfo.inc"  | 
113  |  | #endif  | 
114  |  |  | 
115  |  | // Fill-ins to make the compiler happy.  These constants are never actually  | 
116  |  | //   assigned; they are just filler to make an automatically-generated switch  | 
117  |  | //   statement work.  | 
118  |  | enum { | 
119  |  |   X86_BX_SI = 500,  | 
120  |  |   X86_BX_DI = 501,  | 
121  |  |   X86_BP_SI = 502,  | 
122  |  |   X86_BP_DI = 503,  | 
123  |  |   X86_sib   = 504,  | 
124  |  |   X86_sib64 = 505  | 
125  |  | };  | 
126  |  |  | 
127  |  | //  | 
128  |  | // Private code that translates from struct InternalInstructions to MCInsts.  | 
129  |  | //  | 
130  |  |  | 
131  |  | /// translateRegister - Translates an internal register to the appropriate LLVM  | 
132  |  | ///   register, and appends it as an operand to an MCInst.  | 
133  |  | ///  | 
134  |  | /// @param mcInst     - The MCInst to append to.  | 
135  |  | /// @param reg        - The Reg to append.  | 
136  |  | static void translateRegister(MCInst *mcInst, Reg reg)  | 
137  | 431k  | { | 
138  | 96.2M  | #define ENTRY(x) X86_##x,  | 
139  | 431k  |   static const uint16_t llvmRegnums[] = { | 
140  | 431k  |     ALL_REGS  | 
141  | 431k  |     0  | 
142  | 431k  |   };  | 
143  | 431k  | #undef ENTRY  | 
144  |  |  | 
145  | 431k  |   uint16_t llvmRegnum = llvmRegnums[reg];  | 
146  | 431k  |   MCOperand_CreateReg0(mcInst, llvmRegnum);  | 
147  | 431k  | }  | 
148  |  |  | 
149  |  | static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { | 
150  |  |   0,        // SEG_OVERRIDE_NONE  | 
151  |  |   X86_CS,  | 
152  |  |   X86_SS,  | 
153  |  |   X86_DS,  | 
154  |  |   X86_ES,  | 
155  |  |   X86_FS,  | 
156  |  |   X86_GS  | 
157  |  | };  | 
158  |  |  | 
159  |  | /// translateSrcIndex   - Appends a source index operand to an MCInst.  | 
160  |  | ///  | 
161  |  | /// @param mcInst       - The MCInst to append to.  | 
162  |  | /// @param insn         - The internal instruction.  | 
163  |  | static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)  | 
164  | 23.7k  | { | 
165  | 23.7k  |   unsigned baseRegNo;  | 
166  |  |  | 
167  | 23.7k  |   if (insn->mode == MODE_64BIT)  | 
168  | 9.58k  |     baseRegNo = insn->hasAdSize ? X86_ESI : X86_RSI;  | 
169  | 14.1k  |   else if (insn->mode == MODE_32BIT)  | 
170  | 6.60k  |     baseRegNo = insn->hasAdSize ? X86_SI : X86_ESI;  | 
171  | 7.52k  |   else { | 
172  |  |     // assert(insn->mode == MODE_16BIT);  | 
173  | 7.52k  |     baseRegNo = insn->hasAdSize ? X86_ESI : X86_SI;  | 
174  | 7.52k  |   }  | 
175  |  |  | 
176  | 23.7k  |   MCOperand_CreateReg0(mcInst, baseRegNo);  | 
177  |  |  | 
178  | 23.7k  |   MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);  | 
179  |  |  | 
180  | 23.7k  |   return false;  | 
181  | 23.7k  | }  | 
182  |  |  | 
183  |  | /// translateDstIndex   - Appends a destination index operand to an MCInst.  | 
184  |  | ///  | 
185  |  | /// @param mcInst       - The MCInst to append to.  | 
186  |  | /// @param insn         - The internal instruction.  | 
187  |  | static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)  | 
188  | 31.5k  | { | 
189  | 31.5k  |   unsigned baseRegNo;  | 
190  |  |  | 
191  | 31.5k  |   if (insn->mode == MODE_64BIT)  | 
192  | 14.8k  |     baseRegNo = insn->hasAdSize ? X86_EDI : X86_RDI;  | 
193  | 16.6k  |   else if (insn->mode == MODE_32BIT)  | 
194  | 7.25k  |     baseRegNo = insn->hasAdSize ? X86_DI : X86_EDI;  | 
195  | 9.38k  |   else { | 
196  |  |     // assert(insn->mode == MODE_16BIT);  | 
197  | 9.38k  |     baseRegNo = insn->hasAdSize ? X86_EDI : X86_DI;  | 
198  | 9.38k  |   }  | 
199  |  |  | 
200  | 31.5k  |   MCOperand_CreateReg0(mcInst, baseRegNo);  | 
201  |  |  | 
202  | 31.5k  |   return false;  | 
203  | 31.5k  | }  | 
204  |  |  | 
205  |  | /// translateImmediate  - Appends an immediate operand to an MCInst.  | 
206  |  | ///  | 
207  |  | /// @param mcInst       - The MCInst to append to.  | 
208  |  | /// @param immediate    - The immediate value to append.  | 
209  |  | /// @param operand      - The operand, as stored in the descriptor table.  | 
210  |  | /// @param insn         - The internal instruction.  | 
211  |  | static void translateImmediate(MCInst *mcInst, uint64_t immediate,  | 
212  |  |     const OperandSpecifier *operand, InternalInstruction *insn)  | 
213  | 167k  | { | 
214  | 167k  |   OperandType type;  | 
215  |  |  | 
216  | 167k  |   type = (OperandType)operand->type;  | 
217  | 167k  |   if (type == TYPE_REL) { | 
218  |  |     //isBranch = true;  | 
219  |  |     //pcrel = insn->startLocation + insn->immediateOffset + insn->immediateSize;  | 
220  | 33.4k  |     switch (operand->encoding) { | 
221  | 0  |       default:  | 
222  | 0  |         break;  | 
223  | 1.58k  |       case ENCODING_Iv:  | 
224  | 1.58k  |         switch (insn->displacementSize) { | 
225  | 0  |           default:  | 
226  | 0  |             break;  | 
227  | 0  |           case 1:  | 
228  | 0  |             if(immediate & 0x80)  | 
229  | 0  |               immediate |= ~(0xffull);  | 
230  | 0  |             break;  | 
231  | 574  |           case 2:  | 
232  | 574  |             if(immediate & 0x8000)  | 
233  | 303  |               immediate |= ~(0xffffull);  | 
234  | 574  |             break;  | 
235  | 1.01k  |           case 4:  | 
236  | 1.01k  |             if(immediate & 0x80000000)  | 
237  | 360  |               immediate |= ~(0xffffffffull);  | 
238  | 1.01k  |             break;  | 
239  | 0  |           case 8:  | 
240  | 0  |             break;  | 
241  | 1.58k  |         }  | 
242  | 1.58k  |         break;  | 
243  | 30.0k  |       case ENCODING_IB:  | 
244  | 30.0k  |         if (immediate & 0x80)  | 
245  | 9.62k  |           immediate |= ~(0xffull);  | 
246  | 30.0k  |         break;  | 
247  | 927  |       case ENCODING_IW:  | 
248  | 927  |         if (immediate & 0x8000)  | 
249  | 659  |           immediate |= ~(0xffffull);  | 
250  | 927  |         break;  | 
251  | 897  |       case ENCODING_ID:  | 
252  | 897  |         if (immediate & 0x80000000)  | 
253  | 453  |           immediate |= ~(0xffffffffull);  | 
254  | 897  |         break;  | 
255  | 33.4k  |     }  | 
256  | 33.4k  |   } // By default sign-extend all X86 immediates based on their encoding.  | 
257  | 133k  |   else if (type == TYPE_IMM) { | 
258  | 64.9k  |     switch (operand->encoding) { | 
259  | 18.6k  |       default:  | 
260  | 18.6k  |         break;  | 
261  | 37.0k  |       case ENCODING_IB:  | 
262  | 37.0k  |         if(immediate & 0x80)  | 
263  | 12.3k  |           immediate |= ~(0xffull);  | 
264  | 37.0k  |         break;  | 
265  | 6.79k  |       case ENCODING_IW:  | 
266  | 6.79k  |         if(immediate & 0x8000)  | 
267  | 3.69k  |           immediate |= ~(0xffffull);  | 
268  | 6.79k  |         break;  | 
269  | 2.05k  |       case ENCODING_ID:  | 
270  | 2.05k  |         if(immediate & 0x80000000)  | 
271  | 1.04k  |           immediate |= ~(0xffffffffull);  | 
272  | 2.05k  |         break;  | 
273  | 486  |       case ENCODING_IO:  | 
274  | 486  |         break;  | 
275  | 64.9k  |     }  | 
276  | 68.8k  |   } else if (type == TYPE_IMM3) { | 
277  | 10.0k  | #ifndef CAPSTONE_X86_REDUCE  | 
278  |  |     // Check for immediates that printSSECC can't handle.  | 
279  | 10.0k  |     if (immediate >= 8) { | 
280  | 6.53k  |       unsigned NewOpc = 0;  | 
281  |  |  | 
282  | 6.53k  |       switch (MCInst_getOpcode(mcInst)) { | 
283  | 0  |         default: break; // never reach  | 
284  | 225  |         case X86_CMPPDrmi:  NewOpc = X86_CMPPDrmi_alt;  break;  | 
285  | 210  |         case X86_CMPPDrri:  NewOpc = X86_CMPPDrri_alt;  break;  | 
286  | 657  |         case X86_CMPPSrmi:  NewOpc = X86_CMPPSrmi_alt;  break;  | 
287  | 420  |         case X86_CMPPSrri:  NewOpc = X86_CMPPSrri_alt;  break;  | 
288  | 515  |         case X86_CMPSDrm:   NewOpc = X86_CMPSDrm_alt;   break;  | 
289  | 233  |         case X86_CMPSDrr:   NewOpc = X86_CMPSDrr_alt;   break;  | 
290  | 564  |         case X86_CMPSSrm:   NewOpc = X86_CMPSSrm_alt;   break;  | 
291  | 249  |         case X86_CMPSSrr:   NewOpc = X86_CMPSSrr_alt;   break;  | 
292  | 549  |         case X86_VPCOMBri:  NewOpc = X86_VPCOMBri_alt;  break;  | 
293  | 107  |         case X86_VPCOMBmi:  NewOpc = X86_VPCOMBmi_alt;  break;  | 
294  | 320  |         case X86_VPCOMWri:  NewOpc = X86_VPCOMWri_alt;  break;  | 
295  | 74  |         case X86_VPCOMWmi:  NewOpc = X86_VPCOMWmi_alt;  break;  | 
296  | 209  |         case X86_VPCOMDri:  NewOpc = X86_VPCOMDri_alt;  break;  | 
297  | 212  |         case X86_VPCOMDmi:  NewOpc = X86_VPCOMDmi_alt;  break;  | 
298  | 217  |         case X86_VPCOMQri:  NewOpc = X86_VPCOMQri_alt;  break;  | 
299  | 201  |         case X86_VPCOMQmi:  NewOpc = X86_VPCOMQmi_alt;  break;  | 
300  | 71  |         case X86_VPCOMUBri: NewOpc = X86_VPCOMUBri_alt; break;  | 
301  | 251  |         case X86_VPCOMUBmi: NewOpc = X86_VPCOMUBmi_alt; break;  | 
302  | 379  |         case X86_VPCOMUWri: NewOpc = X86_VPCOMUWri_alt; break;  | 
303  | 75  |         case X86_VPCOMUWmi: NewOpc = X86_VPCOMUWmi_alt; break;  | 
304  | 212  |         case X86_VPCOMUDri: NewOpc = X86_VPCOMUDri_alt; break;  | 
305  | 200  |         case X86_VPCOMUDmi: NewOpc = X86_VPCOMUDmi_alt; break;  | 
306  | 292  |         case X86_VPCOMUQri: NewOpc = X86_VPCOMUQri_alt; break;  | 
307  | 92  |         case X86_VPCOMUQmi: NewOpc = X86_VPCOMUQmi_alt; break;  | 
308  | 6.53k  |       }  | 
309  |  |  | 
310  |  |       // Switch opcode to the one that doesn't get special printing.  | 
311  | 6.53k  |       if (NewOpc != 0) { | 
312  | 6.53k  |         MCInst_setOpcode(mcInst, NewOpc);  | 
313  | 6.53k  |       }  | 
314  | 6.53k  |     }  | 
315  | 10.0k  | #endif  | 
316  | 58.7k  |   } else if (type == TYPE_IMM5) { | 
317  | 15.5k  | #ifndef CAPSTONE_X86_REDUCE  | 
318  |  |     // Check for immediates that printAVXCC can't handle.  | 
319  | 15.5k  |     if (immediate >= 32) { | 
320  | 13.0k  |       unsigned NewOpc = 0;  | 
321  |  |  | 
322  | 13.0k  |       switch (MCInst_getOpcode(mcInst)) { | 
323  | 3.75k  |         default: break; // unexpected opcode  | 
324  | 3.75k  |         case X86_VCMPPDrmi:   NewOpc = X86_VCMPPDrmi_alt;   break;  | 
325  | 220  |         case X86_VCMPPDrri:   NewOpc = X86_VCMPPDrri_alt;   break;  | 
326  | 571  |         case X86_VCMPPSrmi:   NewOpc = X86_VCMPPSrmi_alt;   break;  | 
327  | 259  |         case X86_VCMPPSrri:   NewOpc = X86_VCMPPSrri_alt;   break;  | 
328  | 267  |         case X86_VCMPSDrm:    NewOpc = X86_VCMPSDrm_alt;    break;  | 
329  | 343  |         case X86_VCMPSDrr:    NewOpc = X86_VCMPSDrr_alt;    break;  | 
330  | 429  |         case X86_VCMPSSrm:    NewOpc = X86_VCMPSSrm_alt;    break;  | 
331  | 666  |         case X86_VCMPSSrr:    NewOpc = X86_VCMPSSrr_alt;    break;  | 
332  | 296  |         case X86_VCMPPDYrmi:  NewOpc = X86_VCMPPDYrmi_alt;  break;  | 
333  | 346  |         case X86_VCMPPDYrri:  NewOpc = X86_VCMPPDYrri_alt;  break;  | 
334  | 88  |         case X86_VCMPPSYrmi:  NewOpc = X86_VCMPPSYrmi_alt;  break;  | 
335  | 409  |         case X86_VCMPPSYrri:  NewOpc = X86_VCMPPSYrri_alt;  break;  | 
336  | 306  |         case X86_VCMPPDZrmi:  NewOpc = X86_VCMPPDZrmi_alt;  break;  | 
337  | 828  |         case X86_VCMPPDZrri:  NewOpc = X86_VCMPPDZrri_alt;  break;  | 
338  | 226  |         case X86_VCMPPDZrrib: NewOpc = X86_VCMPPDZrrib_alt; break;  | 
339  | 203  |         case X86_VCMPPSZrmi:  NewOpc = X86_VCMPPSZrmi_alt;  break;  | 
340  | 219  |         case X86_VCMPPSZrri:  NewOpc = X86_VCMPPSZrri_alt;  break;  | 
341  | 242  |         case X86_VCMPPSZrrib: NewOpc = X86_VCMPPSZrrib_alt; break;  | 
342  | 195  |         case X86_VCMPPDZ128rmi:  NewOpc = X86_VCMPPDZ128rmi_alt;  break;  | 
343  | 196  |         case X86_VCMPPDZ128rri:  NewOpc = X86_VCMPPDZ128rri_alt;  break;  | 
344  | 204  |         case X86_VCMPPSZ128rmi:  NewOpc = X86_VCMPPSZ128rmi_alt;  break;  | 
345  | 200  |         case X86_VCMPPSZ128rri:  NewOpc = X86_VCMPPSZ128rri_alt;  break;  | 
346  | 196  |         case X86_VCMPPDZ256rmi:  NewOpc = X86_VCMPPDZ256rmi_alt;  break;  | 
347  | 118  |         case X86_VCMPPDZ256rri:  NewOpc = X86_VCMPPDZ256rri_alt;  break;  | 
348  | 229  |         case X86_VCMPPSZ256rmi:  NewOpc = X86_VCMPPSZ256rmi_alt;  break;  | 
349  | 391  |         case X86_VCMPPSZ256rri:  NewOpc = X86_VCMPPSZ256rri_alt;  break;  | 
350  | 215  |         case X86_VCMPSDZrm_Int:  NewOpc = X86_VCMPSDZrmi_alt;  break;  | 
351  | 197  |         case X86_VCMPSDZrr_Int:  NewOpc = X86_VCMPSDZrri_alt;  break;  | 
352  | 234  |         case X86_VCMPSDZrrb_Int: NewOpc = X86_VCMPSDZrrb_alt;  break;  | 
353  | 198  |         case X86_VCMPSSZrm_Int:  NewOpc = X86_VCMPSSZrmi_alt;  break;  | 
354  | 201  |         case X86_VCMPSSZrr_Int:  NewOpc = X86_VCMPSSZrri_alt;  break;  | 
355  | 384  |         case X86_VCMPSSZrrb_Int: NewOpc = X86_VCMPSSZrrb_alt;  break;  | 
356  | 13.0k  |       }  | 
357  |  |  | 
358  |  |       // Switch opcode to the one that doesn't get special printing.  | 
359  | 13.0k  |       if (NewOpc != 0) { | 
360  | 9.27k  |         MCInst_setOpcode(mcInst, NewOpc);  | 
361  | 9.27k  |       }  | 
362  | 13.0k  |     }  | 
363  | 15.5k  | #endif  | 
364  | 43.1k  |   } else if (type == TYPE_AVX512ICC) { | 
365  | 13.2k  | #ifndef CAPSTONE_X86_REDUCE  | 
366  | 13.2k  |     if (immediate >= 8 || ((immediate & 0x3) == 3)) { | 
367  | 9.53k  |       unsigned NewOpc = 0;  | 
368  | 9.53k  |       switch (MCInst_getOpcode(mcInst)) { | 
369  | 0  |         default: // llvm_unreachable("unexpected opcode"); | 
370  | 194  |         case X86_VPCMPBZ128rmi:    NewOpc = X86_VPCMPBZ128rmi_alt;    break;  | 
371  | 33  |         case X86_VPCMPBZ128rmik:   NewOpc = X86_VPCMPBZ128rmik_alt;   break;  | 
372  | 39  |         case X86_VPCMPBZ128rri:    NewOpc = X86_VPCMPBZ128rri_alt;    break;  | 
373  | 111  |         case X86_VPCMPBZ128rrik:   NewOpc = X86_VPCMPBZ128rrik_alt;   break;  | 
374  | 11  |         case X86_VPCMPBZ256rmi:    NewOpc = X86_VPCMPBZ256rmi_alt;    break;  | 
375  | 24  |         case X86_VPCMPBZ256rmik:   NewOpc = X86_VPCMPBZ256rmik_alt;   break;  | 
376  | 6  |         case X86_VPCMPBZ256rri:    NewOpc = X86_VPCMPBZ256rri_alt;    break;  | 
377  | 7  |         case X86_VPCMPBZ256rrik:   NewOpc = X86_VPCMPBZ256rrik_alt;   break;  | 
378  | 356  |         case X86_VPCMPBZrmi:       NewOpc = X86_VPCMPBZrmi_alt;       break;  | 
379  | 57  |         case X86_VPCMPBZrmik:      NewOpc = X86_VPCMPBZrmik_alt;      break;  | 
380  | 56  |         case X86_VPCMPBZrri:       NewOpc = X86_VPCMPBZrri_alt;       break;  | 
381  | 131  |         case X86_VPCMPBZrrik:      NewOpc = X86_VPCMPBZrrik_alt;      break;  | 
382  | 2  |         case X86_VPCMPDZ128rmi:    NewOpc = X86_VPCMPDZ128rmi_alt;    break;  | 
383  | 28  |         case X86_VPCMPDZ128rmib:   NewOpc = X86_VPCMPDZ128rmib_alt;   break;  | 
384  | 46  |         case X86_VPCMPDZ128rmibk:  NewOpc = X86_VPCMPDZ128rmibk_alt;  break;  | 
385  | 23  |         case X86_VPCMPDZ128rmik:   NewOpc = X86_VPCMPDZ128rmik_alt;   break;  | 
386  | 5  |         case X86_VPCMPDZ128rri:    NewOpc = X86_VPCMPDZ128rri_alt;    break;  | 
387  | 140  |         case X86_VPCMPDZ128rrik:   NewOpc = X86_VPCMPDZ128rrik_alt;   break;  | 
388  | 32  |         case X86_VPCMPDZ256rmi:    NewOpc = X86_VPCMPDZ256rmi_alt;    break;  | 
389  | 41  |         case X86_VPCMPDZ256rmib:   NewOpc = X86_VPCMPDZ256rmib_alt;   break;  | 
390  | 25  |         case X86_VPCMPDZ256rmibk:  NewOpc = X86_VPCMPDZ256rmibk_alt;  break;  | 
391  | 37  |         case X86_VPCMPDZ256rmik:   NewOpc = X86_VPCMPDZ256rmik_alt;   break;  | 
392  | 32  |         case X86_VPCMPDZ256rri:    NewOpc = X86_VPCMPDZ256rri_alt;    break;  | 
393  | 119  |         case X86_VPCMPDZ256rrik:   NewOpc = X86_VPCMPDZ256rrik_alt;   break;  | 
394  | 28  |         case X86_VPCMPDZrmi:       NewOpc = X86_VPCMPDZrmi_alt;       break;  | 
395  | 148  |         case X86_VPCMPDZrmib:      NewOpc = X86_VPCMPDZrmib_alt;      break;  | 
396  | 151  |         case X86_VPCMPDZrmibk:     NewOpc = X86_VPCMPDZrmibk_alt;     break;  | 
397  | 39  |         case X86_VPCMPDZrmik:      NewOpc = X86_VPCMPDZrmik_alt;      break;  | 
398  | 167  |         case X86_VPCMPDZrri:       NewOpc = X86_VPCMPDZrri_alt;       break;  | 
399  | 157  |         case X86_VPCMPDZrrik:      NewOpc = X86_VPCMPDZrrik_alt;      break;  | 
400  | 13  |         case X86_VPCMPQZ128rmi:    NewOpc = X86_VPCMPQZ128rmi_alt;    break;  | 
401  | 276  |         case X86_VPCMPQZ128rmib:   NewOpc = X86_VPCMPQZ128rmib_alt;   break;  | 
402  | 25  |         case X86_VPCMPQZ128rmibk:  NewOpc = X86_VPCMPQZ128rmibk_alt;  break;  | 
403  | 55  |         case X86_VPCMPQZ128rmik:   NewOpc = X86_VPCMPQZ128rmik_alt;   break;  | 
404  | 24  |         case X86_VPCMPQZ128rri:    NewOpc = X86_VPCMPQZ128rri_alt;    break;  | 
405  | 96  |         case X86_VPCMPQZ128rrik:   NewOpc = X86_VPCMPQZ128rrik_alt;   break;  | 
406  | 98  |         case X86_VPCMPQZ256rmi:    NewOpc = X86_VPCMPQZ256rmi_alt;    break;  | 
407  | 10  |         case X86_VPCMPQZ256rmib:   NewOpc = X86_VPCMPQZ256rmib_alt;   break;  | 
408  | 66  |         case X86_VPCMPQZ256rmibk:  NewOpc = X86_VPCMPQZ256rmibk_alt;  break;  | 
409  | 77  |         case X86_VPCMPQZ256rmik:   NewOpc = X86_VPCMPQZ256rmik_alt;   break;  | 
410  | 197  |         case X86_VPCMPQZ256rri:    NewOpc = X86_VPCMPQZ256rri_alt;    break;  | 
411  | 57  |         case X86_VPCMPQZ256rrik:   NewOpc = X86_VPCMPQZ256rrik_alt;   break;  | 
412  | 53  |         case X86_VPCMPQZrmi:       NewOpc = X86_VPCMPQZrmi_alt;       break;  | 
413  | 64  |         case X86_VPCMPQZrmib:      NewOpc = X86_VPCMPQZrmib_alt;      break;  | 
414  | 40  |         case X86_VPCMPQZrmibk:     NewOpc = X86_VPCMPQZrmibk_alt;     break;  | 
415  | 167  |         case X86_VPCMPQZrmik:      NewOpc = X86_VPCMPQZrmik_alt;      break;  | 
416  | 207  |         case X86_VPCMPQZrri:       NewOpc = X86_VPCMPQZrri_alt;       break;  | 
417  | 24  |         case X86_VPCMPQZrrik:      NewOpc = X86_VPCMPQZrrik_alt;      break;  | 
418  | 2  |         case X86_VPCMPUBZ128rmi:   NewOpc = X86_VPCMPUBZ128rmi_alt;   break;  | 
419  | 56  |         case X86_VPCMPUBZ128rmik:  NewOpc = X86_VPCMPUBZ128rmik_alt;  break;  | 
420  | 14  |         case X86_VPCMPUBZ128rri:   NewOpc = X86_VPCMPUBZ128rri_alt;   break;  | 
421  | 47  |         case X86_VPCMPUBZ128rrik:  NewOpc = X86_VPCMPUBZ128rrik_alt;  break;  | 
422  | 18  |         case X86_VPCMPUBZ256rmi:   NewOpc = X86_VPCMPUBZ256rmi_alt;   break;  | 
423  | 21  |         case X86_VPCMPUBZ256rmik:  NewOpc = X86_VPCMPUBZ256rmik_alt;  break;  | 
424  | 71  |         case X86_VPCMPUBZ256rri:   NewOpc = X86_VPCMPUBZ256rri_alt;   break;  | 
425  | 3  |         case X86_VPCMPUBZ256rrik:  NewOpc = X86_VPCMPUBZ256rrik_alt;  break;  | 
426  | 26  |         case X86_VPCMPUBZrmi:      NewOpc = X86_VPCMPUBZrmi_alt;      break;  | 
427  | 235  |         case X86_VPCMPUBZrmik:     NewOpc = X86_VPCMPUBZrmik_alt;     break;  | 
428  | 176  |         case X86_VPCMPUBZrri:      NewOpc = X86_VPCMPUBZrri_alt;      break;  | 
429  | 36  |         case X86_VPCMPUBZrrik:     NewOpc = X86_VPCMPUBZrrik_alt;     break;  | 
430  | 2  |         case X86_VPCMPUDZ128rmi:   NewOpc = X86_VPCMPUDZ128rmi_alt;   break;  | 
431  | 126  |         case X86_VPCMPUDZ128rmib:  NewOpc = X86_VPCMPUDZ128rmib_alt;  break;  | 
432  | 44  |         case X86_VPCMPUDZ128rmibk: NewOpc = X86_VPCMPUDZ128rmibk_alt; break;  | 
433  | 6  |         case X86_VPCMPUDZ128rmik:  NewOpc = X86_VPCMPUDZ128rmik_alt;  break;  | 
434  | 53  |         case X86_VPCMPUDZ128rri:   NewOpc = X86_VPCMPUDZ128rri_alt;   break;  | 
435  | 40  |         case X86_VPCMPUDZ128rrik:  NewOpc = X86_VPCMPUDZ128rrik_alt;  break;  | 
436  | 31  |         case X86_VPCMPUDZ256rmi:   NewOpc = X86_VPCMPUDZ256rmi_alt;   break;  | 
437  | 155  |         case X86_VPCMPUDZ256rmib:  NewOpc = X86_VPCMPUDZ256rmib_alt;  break;  | 
438  | 15  |         case X86_VPCMPUDZ256rmibk: NewOpc = X86_VPCMPUDZ256rmibk_alt; break;  | 
439  | 159  |         case X86_VPCMPUDZ256rmik:  NewOpc = X86_VPCMPUDZ256rmik_alt;  break;  | 
440  | 178  |         case X86_VPCMPUDZ256rri:   NewOpc = X86_VPCMPUDZ256rri_alt;   break;  | 
441  | 15  |         case X86_VPCMPUDZ256rrik:  NewOpc = X86_VPCMPUDZ256rrik_alt;  break;  | 
442  | 124  |         case X86_VPCMPUDZrmi:      NewOpc = X86_VPCMPUDZrmi_alt;      break;  | 
443  | 66  |         case X86_VPCMPUDZrmib:     NewOpc = X86_VPCMPUDZrmib_alt;     break;  | 
444  | 223  |         case X86_VPCMPUDZrmibk:    NewOpc = X86_VPCMPUDZrmibk_alt;    break;  | 
445  | 39  |         case X86_VPCMPUDZrmik:     NewOpc = X86_VPCMPUDZrmik_alt;     break;  | 
446  | 159  |         case X86_VPCMPUDZrri:      NewOpc = X86_VPCMPUDZrri_alt;      break;  | 
447  | 26  |         case X86_VPCMPUDZrrik:     NewOpc = X86_VPCMPUDZrrik_alt;     break;  | 
448  | 169  |         case X86_VPCMPUQZ128rmi:   NewOpc = X86_VPCMPUQZ128rmi_alt;   break;  | 
449  | 80  |         case X86_VPCMPUQZ128rmib:  NewOpc = X86_VPCMPUQZ128rmib_alt;  break;  | 
450  | 315  |         case X86_VPCMPUQZ128rmibk: NewOpc = X86_VPCMPUQZ128rmibk_alt; break;  | 
451  | 28  |         case X86_VPCMPUQZ128rmik:  NewOpc = X86_VPCMPUQZ128rmik_alt;  break;  | 
452  | 49  |         case X86_VPCMPUQZ128rri:   NewOpc = X86_VPCMPUQZ128rri_alt;   break;  | 
453  | 56  |         case X86_VPCMPUQZ128rrik:  NewOpc = X86_VPCMPUQZ128rrik_alt;  break;  | 
454  | 7  |         case X86_VPCMPUQZ256rmi:   NewOpc = X86_VPCMPUQZ256rmi_alt;   break;  | 
455  | 70  |         case X86_VPCMPUQZ256rmib:  NewOpc = X86_VPCMPUQZ256rmib_alt;  break;  | 
456  | 164  |         case X86_VPCMPUQZ256rmibk: NewOpc = X86_VPCMPUQZ256rmibk_alt; break;  | 
457  | 180  |         case X86_VPCMPUQZ256rmik:  NewOpc = X86_VPCMPUQZ256rmik_alt;  break;  | 
458  | 148  |         case X86_VPCMPUQZ256rri:   NewOpc = X86_VPCMPUQZ256rri_alt;   break;  | 
459  | 64  |         case X86_VPCMPUQZ256rrik:  NewOpc = X86_VPCMPUQZ256rrik_alt;  break;  | 
460  | 47  |         case X86_VPCMPUQZrmi:      NewOpc = X86_VPCMPUQZrmi_alt;      break;  | 
461  | 67  |         case X86_VPCMPUQZrmib:     NewOpc = X86_VPCMPUQZrmib_alt;     break;  | 
462  | 78  |         case X86_VPCMPUQZrmibk:    NewOpc = X86_VPCMPUQZrmibk_alt;    break;  | 
463  | 105  |         case X86_VPCMPUQZrmik:     NewOpc = X86_VPCMPUQZrmik_alt;     break;  | 
464  | 177  |         case X86_VPCMPUQZrri:      NewOpc = X86_VPCMPUQZrri_alt;      break;  | 
465  | 126  |         case X86_VPCMPUQZrrik:     NewOpc = X86_VPCMPUQZrrik_alt;     break;  | 
466  | 16  |         case X86_VPCMPUWZ128rmi:   NewOpc = X86_VPCMPUWZ128rmi_alt;   break;  | 
467  | 145  |         case X86_VPCMPUWZ128rmik:  NewOpc = X86_VPCMPUWZ128rmik_alt;  break;  | 
468  | 62  |         case X86_VPCMPUWZ128rri:   NewOpc = X86_VPCMPUWZ128rri_alt;   break;  | 
469  | 279  |         case X86_VPCMPUWZ128rrik:  NewOpc = X86_VPCMPUWZ128rrik_alt;  break;  | 
470  | 62  |         case X86_VPCMPUWZ256rmi:   NewOpc = X86_VPCMPUWZ256rmi_alt;   break;  | 
471  | 32  |         case X86_VPCMPUWZ256rmik:  NewOpc = X86_VPCMPUWZ256rmik_alt;  break;  | 
472  | 36  |         case X86_VPCMPUWZ256rri:   NewOpc = X86_VPCMPUWZ256rri_alt;   break;  | 
473  | 43  |         case X86_VPCMPUWZ256rrik:  NewOpc = X86_VPCMPUWZ256rrik_alt;  break;  | 
474  | 36  |         case X86_VPCMPUWZrmi:      NewOpc = X86_VPCMPUWZrmi_alt;      break;  | 
475  | 3  |         case X86_VPCMPUWZrmik:     NewOpc = X86_VPCMPUWZrmik_alt;     break;  | 
476  | 123  |         case X86_VPCMPUWZrri:      NewOpc = X86_VPCMPUWZrri_alt;      break;  | 
477  | 60  |         case X86_VPCMPUWZrrik:     NewOpc = X86_VPCMPUWZrrik_alt;     break;  | 
478  | 31  |         case X86_VPCMPWZ128rmi:    NewOpc = X86_VPCMPWZ128rmi_alt;    break;  | 
479  | 69  |         case X86_VPCMPWZ128rmik:   NewOpc = X86_VPCMPWZ128rmik_alt;   break;  | 
480  | 36  |         case X86_VPCMPWZ128rri:    NewOpc = X86_VPCMPWZ128rri_alt;    break;  | 
481  | 33  |         case X86_VPCMPWZ128rrik:   NewOpc = X86_VPCMPWZ128rrik_alt;   break;  | 
482  | 20  |         case X86_VPCMPWZ256rmi:    NewOpc = X86_VPCMPWZ256rmi_alt;    break;  | 
483  | 43  |         case X86_VPCMPWZ256rmik:   NewOpc = X86_VPCMPWZ256rmik_alt;   break;  | 
484  | 182  |         case X86_VPCMPWZ256rri:    NewOpc = X86_VPCMPWZ256rri_alt;    break;  | 
485  | 71  |         case X86_VPCMPWZ256rrik:   NewOpc = X86_VPCMPWZ256rrik_alt;   break;  | 
486  | 65  |         case X86_VPCMPWZrmi:       NewOpc = X86_VPCMPWZrmi_alt;       break;  | 
487  | 138  |         case X86_VPCMPWZrmik:      NewOpc = X86_VPCMPWZrmik_alt;      break;  | 
488  | 54  |         case X86_VPCMPWZrri:       NewOpc = X86_VPCMPWZrri_alt;       break;  | 
489  | 4  |         case X86_VPCMPWZrrik:      NewOpc = X86_VPCMPWZrrik_alt;      break;  | 
490  | 9.53k  |       }  | 
491  |  |  | 
492  |  |       // Switch opcode to the one that doesn't get special printing.  | 
493  | 9.53k  |       if (NewOpc != 0) { | 
494  | 9.53k  |         MCInst_setOpcode(mcInst, NewOpc);  | 
495  | 9.53k  |       }  | 
496  | 9.53k  |     }  | 
497  | 13.2k  | #endif  | 
498  | 13.2k  |   }  | 
499  |  |  | 
500  | 167k  |   switch (type) { | 
501  | 600  |     case TYPE_XMM:  | 
502  | 600  |       MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4));  | 
503  | 600  |       return;  | 
504  | 954  |     case TYPE_YMM:  | 
505  | 954  |       MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4));  | 
506  | 954  |       return;  | 
507  | 0  |     case TYPE_ZMM:  | 
508  | 0  |       MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4));  | 
509  | 0  |       return;  | 
510  | 165k  |     default:  | 
511  |  |       // operand is 64 bits wide.  Do nothing.  | 
512  | 165k  |       break;  | 
513  | 167k  |   }  | 
514  |  |  | 
515  | 165k  |   MCOperand_CreateImm0(mcInst, immediate);  | 
516  |  |  | 
517  | 165k  |   if (type == TYPE_MOFFS) { | 
518  | 6.12k  |     MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);  | 
519  | 6.12k  |   }  | 
520  | 165k  | }  | 
521  |  |  | 
522  |  | /// translateRMRegister - Translates a register stored in the R/M field of the  | 
523  |  | ///   ModR/M byte to its LLVM equivalent and appends it to an MCInst.  | 
524  |  | /// @param mcInst       - The MCInst to append to.  | 
525  |  | /// @param insn         - The internal instruction to extract the R/M field  | 
526  |  | ///                       from.  | 
527  |  | /// @return             - 0 on success; -1 otherwise  | 
528  |  | static bool translateRMRegister(MCInst *mcInst, InternalInstruction *insn)  | 
529  | 119k  | { | 
530  | 119k  |   if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) { | 
531  |  |     //debug("A R/M register operand may not have a SIB byte"); | 
532  | 0  |     return true;  | 
533  | 0  |   }  | 
534  |  |  | 
535  | 119k  |   switch (insn->eaBase) { | 
536  | 0  |     case EA_BASE_NONE:  | 
537  |  |       //debug("EA_BASE_NONE for ModR/M base"); | 
538  | 0  |       return true;  | 
539  | 0  | #define ENTRY(x) case EA_BASE_##x:  | 
540  | 0  |       ALL_EA_BASES  | 
541  | 0  | #undef ENTRY  | 
542  |  |         //debug("A R/M register operand may not have a base; " | 
543  |  |         //      "the operand must be a register.");  | 
544  | 0  |         return true;  | 
545  | 0  | #define ENTRY(x)                                                      \  | 
546  | 119k  |     case EA_REG_##x:                                                    \  | 
547  | 119k  |       MCOperand_CreateReg0(mcInst, X86_##x); break;  | 
548  | 0  |       ALL_REGS  | 
549  | 0  | #undef ENTRY  | 
550  | 0  |     default:  | 
551  |  |         //debug("Unexpected EA base register"); | 
552  | 0  |         return true;  | 
553  | 119k  |   }  | 
554  |  |  | 
555  | 119k  |   return false;  | 
556  | 119k  | }  | 
557  |  |  | 
558  |  | /// translateRMMemory - Translates a memory operand stored in the Mod and R/M  | 
559  |  | ///   fields of an internal instruction (and possibly its SIB byte) to a memory  | 
560  |  | ///   operand in LLVM's format, and appends it to an MCInst.  | 
561  |  | ///  | 
562  |  | /// @param mcInst       - The MCInst to append to.  | 
563  |  | /// @param insn         - The instruction to extract Mod, R/M, and SIB fields  | 
564  |  | ///                       from.  | 
565  |  | /// @return             - 0 on success; nonzero otherwise  | 
566  |  | static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)  | 
567  | 241k  | { | 
568  |  |   // Addresses in an MCInst are represented as five operands:  | 
569  |  |   //   1. basereg       (register)  The R/M base, or (if there is a SIB) the  | 
570  |  |   //                                SIB base  | 
571  |  |   //   2. scaleamount   (immediate) 1, or (if there is a SIB) the specified  | 
572  |  |   //                                scale amount  | 
573  |  |   //   3. indexreg      (register)  x86_registerNONE, or (if there is a SIB)  | 
574  |  |   //                                the index (which is multiplied by the  | 
575  |  |   //                                scale amount)  | 
576  |  |   //   4. displacement  (immediate) 0, or the displacement if there is one  | 
577  |  |   //   5. segmentreg    (register)  x86_registerNONE for now, but could be set  | 
578  |  |   //                                if we have segment overrides  | 
579  | 241k  |   int scaleAmount, indexReg;  | 
580  |  |  | 
581  | 241k  |   if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) { | 
582  | 17.6k  |     if (insn->sibBase != SIB_BASE_NONE) { | 
583  | 16.5k  |       switch (insn->sibBase) { | 
584  | 0  | #define ENTRY(x)                                          \  | 
585  | 16.5k  |         case SIB_BASE_##x:                                  \  | 
586  | 16.5k  |         MCOperand_CreateReg0(mcInst, X86_##x); break;  | 
587  | 0  |         ALL_SIB_BASES  | 
588  | 0  | #undef ENTRY  | 
589  | 0  |         default:  | 
590  |  |           //debug("Unexpected sibBase"); | 
591  | 0  |           return true;  | 
592  | 16.5k  |       }  | 
593  | 16.5k  |     } else { | 
594  | 1.06k  |       MCOperand_CreateReg0(mcInst, 0);  | 
595  | 1.06k  |     }  | 
596  |  |  | 
597  | 17.6k  |     if (insn->sibIndex != SIB_INDEX_NONE) { | 
598  | 14.7k  |       switch (insn->sibIndex) { | 
599  | 0  |         default:  | 
600  |  |           //debug("Unexpected sibIndex"); | 
601  | 0  |           return true;  | 
602  | 0  | #define ENTRY(x)                                          \  | 
603  | 14.7k  |         case SIB_INDEX_##x:                                 \  | 
604  | 14.7k  |           indexReg = X86_##x; break;  | 
605  | 0  |           EA_BASES_32BIT  | 
606  | 52  |             EA_BASES_64BIT  | 
607  | 179  |             REGS_XMM  | 
608  | 46  |             REGS_YMM  | 
609  | 14.7k  |             REGS_ZMM  | 
610  | 14.7k  | #undef ENTRY  | 
611  | 14.7k  |       }  | 
612  | 14.7k  |     } else { | 
613  |  |       // Use EIZ/RIZ for a few ambiguous cases where the SIB byte is present,  | 
614  |  |       // but no index is used and modrm alone should have been enough.  | 
615  |  |       // -No base register in 32-bit mode. In 64-bit mode this is used to  | 
616  |  |       //  avoid rip-relative addressing.  | 
617  |  |       // -Any base register used other than ESP/RSP/R12D/R12. Using these as a  | 
618  |  |       //  base always requires a SIB byte.  | 
619  |  |       // -A scale other than 1 is used.  | 
620  | 2.90k  |       if (insn->sibScale != 1 ||  | 
621  | 1.95k  |           (insn->sibBase == SIB_BASE_NONE && insn->mode != MODE_64BIT) ||  | 
622  | 1.75k  |           (insn->sibBase != SIB_BASE_NONE &&  | 
623  | 1.56k  |            insn->sibBase != SIB_BASE_ESP && insn->sibBase != SIB_BASE_RSP &&  | 
624  | 1.62k  |            insn->sibBase != SIB_BASE_R12D && insn->sibBase != SIB_BASE_R12)) { | 
625  | 1.62k  |         indexReg = insn->addressSize == 4? X86_EIZ : X86_RIZ;  | 
626  | 1.62k  |       } else  | 
627  | 1.28k  |         indexReg = 0;  | 
628  | 2.90k  |     }  | 
629  |  |  | 
630  | 17.6k  |     scaleAmount = insn->sibScale;  | 
631  | 224k  |   } else { | 
632  | 224k  |     switch (insn->eaBase) { | 
633  | 5.33k  |       case EA_BASE_NONE:  | 
634  | 5.33k  |         if (insn->eaDisplacement == EA_DISP_NONE) { | 
635  |  |           //debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base"); | 
636  | 0  |           return true;  | 
637  | 0  |         }  | 
638  | 5.33k  |         if (insn->mode == MODE_64BIT) { | 
639  | 1.06k  |           if (insn->prefix3 == 0x67)  // address-size prefix overrides RIP relative addressing  | 
640  | 203  |             MCOperand_CreateReg0(mcInst, X86_EIP);  | 
641  | 858  |           else  | 
642  |  |             // Section 2.2.1.6  | 
643  | 858  |             MCOperand_CreateReg0(mcInst, insn->addressSize == 4 ? X86_EIP : X86_RIP);  | 
644  | 4.27k  |         } else { | 
645  | 4.27k  |           MCOperand_CreateReg0(mcInst, 0);  | 
646  | 4.27k  |         }  | 
647  |  |  | 
648  | 5.33k  |         indexReg = 0;  | 
649  | 5.33k  |         break;  | 
650  | 23.7k  |       case EA_BASE_BX_SI:  | 
651  | 23.7k  |         MCOperand_CreateReg0(mcInst, X86_BX);  | 
652  | 23.7k  |         indexReg = X86_SI;  | 
653  | 23.7k  |         break;  | 
654  | 11.0k  |       case EA_BASE_BX_DI:  | 
655  | 11.0k  |         MCOperand_CreateReg0(mcInst, X86_BX);  | 
656  | 11.0k  |         indexReg = X86_DI;  | 
657  | 11.0k  |         break;  | 
658  | 8.97k  |       case EA_BASE_BP_SI:  | 
659  | 8.97k  |         MCOperand_CreateReg0(mcInst, X86_BP);  | 
660  | 8.97k  |         indexReg = X86_SI;  | 
661  | 8.97k  |         break;  | 
662  | 7.90k  |       case EA_BASE_BP_DI:  | 
663  | 7.90k  |         MCOperand_CreateReg0(mcInst, X86_BP);  | 
664  | 7.90k  |         indexReg = X86_DI;  | 
665  | 7.90k  |         break;  | 
666  | 167k  |       default:  | 
667  | 167k  |         indexReg = 0;  | 
668  | 167k  |         switch (insn->eaBase) { | 
669  | 0  |           default:  | 
670  |  |             //debug("Unexpected eaBase"); | 
671  | 0  |             return true;  | 
672  |  |             // Here, we will use the fill-ins defined above.  However,  | 
673  |  |             //   BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and  | 
674  |  |             //   sib and sib64 were handled in the top-level if, so they're only  | 
675  |  |             //   placeholders to keep the compiler happy.  | 
676  | 0  | #define ENTRY(x)                                        \  | 
677  | 167k  |           case EA_BASE_##x:                                 \  | 
678  | 167k  |               MCOperand_CreateReg0(mcInst, X86_##x); break;  | 
679  | 0  |             ALL_EA_BASES  | 
680  | 0  | #undef ENTRY  | 
681  | 6.58k  | #define ENTRY(x) case EA_REG_##x:  | 
682  | 2.19k  |               ALL_REGS  | 
683  | 0  | #undef ENTRY  | 
684  |  |               //debug("A R/M memory operand may not be a register; " | 
685  |  |               //      "the base field must be a base.");  | 
686  | 0  |               return true;  | 
687  | 167k  |         }  | 
688  | 224k  |     }  | 
689  |  |  | 
690  | 224k  |     scaleAmount = 1;  | 
691  | 224k  |   }  | 
692  |  |  | 
693  | 241k  |   MCOperand_CreateImm0(mcInst, scaleAmount);  | 
694  | 241k  |   MCOperand_CreateReg0(mcInst, indexReg);  | 
695  | 241k  |   MCOperand_CreateImm0(mcInst, insn->displacement);  | 
696  |  |  | 
697  | 241k  |   MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);  | 
698  |  |  | 
699  | 241k  |   return false;  | 
700  | 241k  | }  | 
701  |  |  | 
702  |  | /// translateRM - Translates an operand stored in the R/M (and possibly SIB)  | 
703  |  | ///   byte of an instruction to LLVM form, and appends it to an MCInst.  | 
704  |  | ///  | 
705  |  | /// @param mcInst       - The MCInst to append to.  | 
706  |  | /// @param operand      - The operand, as stored in the descriptor table.  | 
707  |  | /// @param insn         - The instruction to extract Mod, R/M, and SIB fields  | 
708  |  | ///                       from.  | 
709  |  | /// @return             - 0 on success; nonzero otherwise  | 
710  |  | static bool translateRM(MCInst *mcInst, const OperandSpecifier *operand,  | 
711  |  |     InternalInstruction *insn)  | 
712  | 360k  | { | 
713  | 360k  |   switch (operand->type) { | 
714  | 0  |     default:  | 
715  |  |       //debug("Unexpected type for a R/M operand"); | 
716  | 0  |       return true;  | 
717  | 33.7k  |     case TYPE_R8:  | 
718  | 34.2k  |     case TYPE_R16:  | 
719  | 35.5k  |     case TYPE_R32:  | 
720  | 42.6k  |     case TYPE_R64:  | 
721  | 77.7k  |     case TYPE_Rv:  | 
722  | 80.9k  |     case TYPE_MM64:  | 
723  | 97.9k  |     case TYPE_XMM:  | 
724  | 106k  |     case TYPE_YMM:  | 
725  | 116k  |     case TYPE_ZMM:  | 
726  | 118k  |     case TYPE_VK:  | 
727  | 118k  |     case TYPE_DEBUGREG:  | 
728  | 118k  |     case TYPE_CONTROLREG:  | 
729  | 119k  |     case TYPE_BNDR:  | 
730  | 119k  |       return translateRMRegister(mcInst, insn);  | 
731  | 235k  |     case TYPE_M:  | 
732  | 237k  |     case TYPE_MVSIBX:  | 
733  | 239k  |     case TYPE_MVSIBY:  | 
734  | 241k  |     case TYPE_MVSIBZ:  | 
735  | 241k  |       return translateRMMemory(mcInst, insn);  | 
736  | 360k  |   }  | 
737  | 360k  | }  | 
738  |  |  | 
739  |  | /// translateFPRegister - Translates a stack position on the FPU stack to its  | 
740  |  | ///   LLVM form, and appends it to an MCInst.  | 
741  |  | ///  | 
742  |  | /// @param mcInst       - The MCInst to append to.  | 
743  |  | /// @param stackPos     - The stack position to translate.  | 
744  |  | static void translateFPRegister(MCInst *mcInst, uint8_t stackPos)  | 
745  | 2.42k  | { | 
746  | 2.42k  |   MCOperand_CreateReg0(mcInst, X86_ST0 + stackPos);  | 
747  | 2.42k  | }  | 
748  |  |  | 
749  |  | /// translateMaskRegister - Translates a 3-bit mask register number to  | 
750  |  | ///   LLVM form, and appends it to an MCInst.  | 
751  |  | ///  | 
752  |  | /// @param mcInst       - The MCInst to append to.  | 
753  |  | /// @param maskRegNum   - Number of mask register from 0 to 7.  | 
754  |  | /// @return             - false on success; true otherwise.  | 
755  |  | static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)  | 
756  | 41.6k  | { | 
757  | 41.6k  |   if (maskRegNum >= 8) { | 
758  |  |     // debug("Invalid mask register number"); | 
759  | 0  |     return true;  | 
760  | 0  |   }  | 
761  |  |  | 
762  | 41.6k  |   MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);  | 
763  |  |  | 
764  | 41.6k  |   return false;  | 
765  | 41.6k  | }  | 
766  |  |  | 
767  |  | /// translateOperand - Translates an operand stored in an internal instruction  | 
768  |  | ///   to LLVM's format and appends it to an MCInst.  | 
769  |  | ///  | 
770  |  | /// @param mcInst       - The MCInst to append to.  | 
771  |  | /// @param operand      - The operand, as stored in the descriptor table.  | 
772  |  | /// @param insn         - The internal instruction.  | 
773  |  | /// @return             - false on success; true otherwise.  | 
774  |  | static bool translateOperand(MCInst *mcInst, const OperandSpecifier *operand, InternalInstruction *insn)  | 
775  | 1.18M  | { | 
776  | 1.18M  |   switch (operand->encoding) { | 
777  | 306k  |     case ENCODING_REG:  | 
778  | 306k  |       translateRegister(mcInst, insn->reg);  | 
779  | 306k  |       return false;  | 
780  | 41.6k  |     case ENCODING_WRITEMASK:  | 
781  | 41.6k  |       return translateMaskRegister(mcInst, insn->writemask);  | 
782  | 2.26M  |     CASE_ENCODING_RM:  | 
783  | 2.26M  |     CASE_ENCODING_VSIB:  | 
784  | 360k  |       return translateRM(mcInst, operand, insn);  | 
785  | 129k  |     case ENCODING_IB:  | 
786  | 137k  |     case ENCODING_IW:  | 
787  | 140k  |     case ENCODING_ID:  | 
788  | 140k  |     case ENCODING_IO:  | 
789  | 161k  |     case ENCODING_Iv:  | 
790  | 167k  |     case ENCODING_Ia:  | 
791  | 167k  |       translateImmediate(mcInst, insn->immediates[insn->numImmediatesTranslated++], operand, insn);  | 
792  | 167k  |       return false;  | 
793  | 2.86k  |     case ENCODING_IRC:  | 
794  | 2.86k  |       MCOperand_CreateImm0(mcInst, insn->RC);  | 
795  | 2.86k  |       return false;  | 
796  | 23.7k  |     case ENCODING_SI:  | 
797  | 23.7k  |       return translateSrcIndex(mcInst, insn);  | 
798  | 31.5k  |     case ENCODING_DI:  | 
799  | 31.5k  |       return translateDstIndex(mcInst, insn);  | 
800  | 4.55k  |     case ENCODING_RB:  | 
801  | 4.55k  |     case ENCODING_RW:  | 
802  | 4.55k  |     case ENCODING_RD:  | 
803  | 14.9k  |     case ENCODING_RO:  | 
804  | 66.1k  |     case ENCODING_Rv:  | 
805  | 66.1k  |       translateRegister(mcInst, insn->opcodeRegister);  | 
806  | 66.1k  |       return false;  | 
807  | 2.42k  |     case ENCODING_FP:  | 
808  | 2.42k  |       translateFPRegister(mcInst, insn->modRM & 7);  | 
809  | 2.42k  |       return false;  | 
810  | 58.7k  |     case ENCODING_VVVV:  | 
811  | 58.7k  |       translateRegister(mcInst, insn->vvvv);  | 
812  | 58.7k  |       return false;  | 
813  | 125k  |     case ENCODING_DUP:  | 
814  | 125k  |       return translateOperand(mcInst, &insn->operands[operand->type - TYPE_DUP0], insn);  | 
815  | 0  |     default:  | 
816  |  |       //debug("Unhandled operand encoding during translation"); | 
817  | 0  |       return true;  | 
818  | 1.18M  |   }  | 
819  | 1.18M  | }  | 
820  |  |  | 
821  |  | static bool translateInstruction(MCInst *mcInst, InternalInstruction *insn)  | 
822  | 552k  | { | 
823  | 552k  |   int index;  | 
824  |  |  | 
825  | 552k  |   if (!insn->spec) { | 
826  |  |     //debug("Instruction has no specification"); | 
827  | 0  |     return true;  | 
828  | 0  |   }  | 
829  |  |  | 
830  | 552k  |   MCInst_clear(mcInst);  | 
831  | 552k  |   MCInst_setOpcode(mcInst, insn->instructionID);  | 
832  |  |  | 
833  |  |   // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3  | 
834  |  |   // prefix bytes should be disassembled as xrelease and xacquire then set the  | 
835  |  |   // opcode to those instead of the rep and repne opcodes.  | 
836  | 552k  | #ifndef CAPSTONE_X86_REDUCE  | 
837  | 552k  |   if (insn->xAcquireRelease) { | 
838  | 3.94k  |     if (MCInst_getOpcode(mcInst) == X86_REP_PREFIX)  | 
839  | 0  |       MCInst_setOpcode(mcInst, X86_XRELEASE_PREFIX);  | 
840  | 3.94k  |     else if (MCInst_getOpcode(mcInst) == X86_REPNE_PREFIX)  | 
841  | 0  |       MCInst_setOpcode(mcInst, X86_XACQUIRE_PREFIX);  | 
842  | 3.94k  |   }  | 
843  | 552k  | #endif  | 
844  |  |  | 
845  | 552k  |   insn->numImmediatesTranslated = 0;  | 
846  |  |  | 
847  | 3.86M  |   for (index = 0; index < X86_MAX_OPERANDS; ++index) { | 
848  | 3.31M  |     if (insn->operands[index].encoding != ENCODING_NONE) { | 
849  | 1.06M  |       if (translateOperand(mcInst, &insn->operands[index], insn)) { | 
850  | 0  |         return true;  | 
851  | 0  |       }  | 
852  | 1.06M  |     }  | 
853  | 3.31M  |   }  | 
854  |  |  | 
855  | 552k  |   return false;  | 
856  | 552k  | }  | 
857  |  |  | 
858  |  | static int reader(const struct reader_info *info, uint8_t *byte, uint64_t address)  | 
859  | 2.80M  | { | 
860  | 2.80M  |   if (address - info->offset >= info->size)  | 
861  |  |     // out of buffer range  | 
862  | 3.38k  |     return -1;  | 
863  |  |  | 
864  | 2.79M  |   *byte = info->code[address - info->offset];  | 
865  |  |  | 
866  | 2.79M  |   return 0;  | 
867  | 2.80M  | }  | 
868  |  |  | 
869  |  | // copy x86 detail information from internal structure to public structure  | 
870  |  | static void update_pub_insn(cs_insn *pub, InternalInstruction *inter)  | 
871  | 552k  | { | 
872  | 552k  |   if (inter->vectorExtensionType != 0) { | 
873  | 79.0k  |     memcpy(pub->detail->x86.opcode, inter->vectorExtensionPrefix, sizeof(pub->detail->x86.opcode));  | 
874  | 473k  |   } else { | 
875  | 473k  |     if (inter->twoByteEscape) { | 
876  | 38.4k  |       if (inter->threeByteEscape) { | 
877  | 0  |         pub->detail->x86.opcode[0] = inter->twoByteEscape;  | 
878  | 0  |         pub->detail->x86.opcode[1] = inter->threeByteEscape;  | 
879  | 0  |         pub->detail->x86.opcode[2] = inter->opcode;  | 
880  | 38.4k  |       } else { | 
881  | 38.4k  |         pub->detail->x86.opcode[0] = inter->twoByteEscape;  | 
882  | 38.4k  |         pub->detail->x86.opcode[1] = inter->opcode;  | 
883  | 38.4k  |       }  | 
884  | 435k  |     } else { | 
885  | 435k  |         pub->detail->x86.opcode[0] = inter->opcode;  | 
886  | 435k  |     }  | 
887  | 473k  |   }  | 
888  |  |  | 
889  | 552k  |   pub->detail->x86.rex = inter->rexPrefix;  | 
890  |  |  | 
891  | 552k  |   pub->detail->x86.addr_size = inter->addressSize;  | 
892  |  |  | 
893  | 552k  |   pub->detail->x86.modrm = inter->orgModRM;  | 
894  | 552k  |   pub->detail->x86.encoding.modrm_offset = inter->modRMOffset;  | 
895  |  |  | 
896  | 552k  |   pub->detail->x86.sib = inter->sib;  | 
897  | 552k  |   pub->detail->x86.sib_index = x86_map_sib_index(inter->sibIndex);  | 
898  | 552k  |   pub->detail->x86.sib_scale = inter->sibScale;  | 
899  | 552k  |   pub->detail->x86.sib_base = x86_map_sib_base(inter->sibBase);  | 
900  |  |  | 
901  | 552k  |   pub->detail->x86.disp = inter->displacement;  | 
902  | 552k  |   if (inter->consumedDisplacement) { | 
903  | 81.1k  |     pub->detail->x86.encoding.disp_offset = inter->displacementOffset;  | 
904  | 81.1k  |     pub->detail->x86.encoding.disp_size = inter->displacementSize;  | 
905  | 81.1k  |   }  | 
906  |  |  | 
907  | 552k  |   pub->detail->x86.encoding.imm_offset = inter->immediateOffset;  | 
908  | 552k  |   if (pub->detail->x86.encoding.imm_size == 0 && inter->immediateOffset != 0)  | 
909  | 156k  |     pub->detail->x86.encoding.imm_size = inter->immediateSize;  | 
910  | 552k  | }  | 
911  |  |  | 
912  |  | void X86_init(MCRegisterInfo *MRI)  | 
913  | 11.4k  | { | 
914  |  |   // InitMCRegisterInfo(), X86GenRegisterInfo.inc  | 
915  |  |   // RI->InitMCRegisterInfo(X86RegDesc, 277,  | 
916  |  |   //                        RA, PC,  | 
917  |  |   //                        X86MCRegisterClasses, 86,  | 
918  |  |   //                        X86RegUnitRoots, 162, X86RegDiffLists, X86LaneMaskLists, X86RegStrings,  | 
919  |  |   //                        X86RegClassStrings,  | 
920  |  |   //                        X86SubRegIdxLists, 9,  | 
921  |  |   //                        X86SubRegIdxRanges, X86RegEncodingTable);  | 
922  |  |   /*  | 
923  |  |      InitMCRegisterInfo(X86RegDesc, 234,  | 
924  |  |      RA, PC,  | 
925  |  |      X86MCRegisterClasses, 79,  | 
926  |  |      X86RegUnitRoots, 119, X86RegDiffLists, X86RegStrings,  | 
927  |  |      X86SubRegIdxLists, 7,  | 
928  |  |      X86SubRegIdxRanges, X86RegEncodingTable);  | 
929  |  |   */  | 
930  |  |  | 
931  | 11.4k  |   MCRegisterInfo_InitMCRegisterInfo(MRI, X86RegDesc, 277,  | 
932  | 11.4k  |       0, 0,  | 
933  | 11.4k  |       X86MCRegisterClasses, 86,  | 
934  | 11.4k  |       0, 0, X86RegDiffLists, 0,  | 
935  | 11.4k  |       X86SubRegIdxLists, 9,  | 
936  | 11.4k  |       0);  | 
937  | 11.4k  | }  | 
938  |  |  | 
939  |  | // Public interface for the disassembler  | 
940  |  | bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,  | 
941  |  |     MCInst *instr, uint16_t *size, uint64_t address, void *_info)  | 
942  | 556k  | { | 
943  | 556k  |   cs_struct *handle = (cs_struct *)(uintptr_t)ud;  | 
944  | 556k  |   InternalInstruction insn = { 0 }; | 
945  | 556k  |   struct reader_info info;  | 
946  | 556k  |   int ret;  | 
947  | 556k  |   bool result;  | 
948  |  |  | 
949  | 556k  |   info.code = code;  | 
950  | 556k  |   info.size = code_len;  | 
951  | 556k  |   info.offset = address;  | 
952  |  |  | 
953  | 556k  |   if (instr->flat_insn->detail) { | 
954  |  |     // instr->flat_insn->detail initialization: 3 alternatives  | 
955  |  |  | 
956  |  |     // 1. The whole structure, this is how it's done in other arch disassemblers  | 
957  |  |     // Probably overkill since cs_detail is huge because of the 36 operands of ARM  | 
958  |  |       | 
959  |  |     //memset(instr->flat_insn->detail, 0, sizeof(cs_detail));  | 
960  |  |  | 
961  |  |     // 2. Only the part relevant to x86  | 
962  | 556k  |     memset(instr->flat_insn->detail, 0, offsetof(cs_detail, x86) + sizeof(cs_x86));  | 
963  |  |  | 
964  |  |     // 3. The relevant part except for x86.operands  | 
965  |  |     // sizeof(cs_x86) is 0x1c0, sizeof(x86.operands) is 0x180  | 
966  |  |     // marginally faster, should be okay since x86.op_count is set to 0  | 
967  |  |  | 
968  |  |     //memset(instr->flat_insn->detail, 0, offsetof(cs_detail, x86)+offsetof(cs_x86, operands));  | 
969  | 556k  |   }  | 
970  |  |  | 
971  | 556k  |   if (handle->mode & CS_MODE_16)  | 
972  | 174k  |     ret = decodeInstruction(&insn,  | 
973  | 174k  |         reader, &info,  | 
974  | 174k  |         address,  | 
975  | 174k  |         MODE_16BIT);  | 
976  | 382k  |   else if (handle->mode & CS_MODE_32)  | 
977  | 173k  |     ret = decodeInstruction(&insn,  | 
978  | 173k  |         reader, &info,  | 
979  | 173k  |         address,  | 
980  | 173k  |         MODE_32BIT);  | 
981  | 209k  |   else  | 
982  | 209k  |     ret = decodeInstruction(&insn,  | 
983  | 209k  |         reader, &info,  | 
984  | 209k  |         address,  | 
985  | 209k  |         MODE_64BIT);  | 
986  |  |  | 
987  | 556k  |   if (ret) { | 
988  |  |     // *size = (uint16_t)(insn.readerCursor - address);  | 
989  | 4.19k  |     return false;  | 
990  | 552k  |   } else { | 
991  | 552k  |     *size = (uint16_t)insn.length;  | 
992  |  |  | 
993  | 552k  |     result = (!translateInstruction(instr, &insn)) ?  true : false;  | 
994  | 552k  |     if (result) { | 
995  | 552k  |       unsigned Flags = X86_IP_NO_PREFIX;  | 
996  | 552k  |       instr->imm_size = insn.immSize;  | 
997  |  |  | 
998  |  |       // copy all prefixes  | 
999  | 552k  |       instr->x86_prefix[0] = insn.prefix0;  | 
1000  | 552k  |       instr->x86_prefix[1] = insn.prefix1;  | 
1001  | 552k  |       instr->x86_prefix[2] = insn.prefix2;  | 
1002  | 552k  |       instr->x86_prefix[3] = insn.prefix3;  | 
1003  | 552k  |       instr->xAcquireRelease = insn.xAcquireRelease;  | 
1004  |  |  | 
1005  | 552k  |       if (handle->detail) { | 
1006  | 552k  |         update_pub_insn(instr->flat_insn, &insn);  | 
1007  | 552k  |       }  | 
1008  |  |  | 
1009  | 552k  |       if (insn.hasAdSize)  | 
1010  | 6.53k  |         Flags |= X86_IP_HAS_AD_SIZE;  | 
1011  |  |  | 
1012  | 552k  |       if (!insn.mandatoryPrefix) { | 
1013  | 541k  |         if (insn.hasOpSize)  | 
1014  | 16.9k  |           Flags |= X86_IP_HAS_OP_SIZE;  | 
1015  |  |  | 
1016  | 541k  |         if (insn.repeatPrefix == 0xf2)  | 
1017  | 19.5k  |           Flags |= X86_IP_HAS_REPEAT_NE;  | 
1018  | 521k  |         else if (insn.repeatPrefix == 0xf3 &&  | 
1019  |  |             // It should not be 'pause' f3 90  | 
1020  | 15.5k  |             insn.opcode != 0x90)  | 
1021  | 15.2k  |           Flags |= X86_IP_HAS_REPEAT;  | 
1022  | 541k  |         if (insn.hasLockPrefix)  | 
1023  | 34.5k  |           Flags |= X86_IP_HAS_LOCK;  | 
1024  | 541k  |       }  | 
1025  |  |  | 
1026  | 552k  |       instr->flags = Flags;  | 
1027  | 552k  |     }  | 
1028  |  |  | 
1029  | 552k  |     return result;  | 
1030  | 552k  |   }  | 
1031  | 556k  | }  | 
1032  |  |  | 
1033  |  | #endif  |