OLD | NEW |
| (Empty) |
1 #include <stdlib.h> | |
2 | |
3 #include "ia32_implicit.h" | |
4 #include "ia32_insn.h" | |
5 #include "ia32_reg.h" | |
6 #include "x86_operand_list.h" | |
7 | |
8 /* Conventions: Register operands which are aliases of another register | |
9 * operand (e.g. AX in one operand and AL in another) assume that the | |
10 * operands are different registers and that alias tracking will resolve | |
11 * data flow. This means that something like | |
12 * mov ax, al | |
13 * would have 'write only' access for AX and 'read only' access for AL, | |
14 * even though both AL and AX are read and written */ | |
15 typedef struct { | |
16 uint32_t type; | |
17 uint32_t operand; | |
18 } op_implicit_list_t; | |
19 | |
20 static op_implicit_list_t list_aaa[] = | |
21 /* 37 : AAA : rw AL */ | |
22 /* 3F : AAS : rw AL */ | |
23 {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* aaa */ | |
24 | |
25 static op_implicit_list_t list_aad[] = | |
26 /* D5 0A, D5 (ib) : AAD : rw AX */ | |
27 /* D4 0A, D4 (ib) : AAM : rw AX */ | |
28 {{ OP_R | OP_W, REG_WORD_OFFSET }, {0}}; /* aad */ | |
29 | |
30 static op_implicit_list_t list_call[] = | |
31 /* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */ | |
32 /* C2, C3, CA, CB : RET : rw ESP, rw EIP */ | |
33 {{ OP_R | OP_W, REG_EIP_INDEX }, | |
34 { OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* call, ret */ | |
35 | |
36 static op_implicit_list_t list_cbw[] = | |
37 /* 98 : CBW : r AL, rw AX */ | |
38 {{ OP_R | OP_W, REG_WORD_OFFSET }, | |
39 { OP_R, REG_BYTE_OFFSET}, {0}}; /* cbw */ | |
40 | |
41 static op_implicit_list_t list_cwde[] = | |
42 /* 98 : CWDE : r AX, rw EAX */ | |
43 {{ OP_R | OP_W, REG_DWORD_OFFSET }, | |
44 { OP_R, REG_WORD_OFFSET }, {0}}; /* cwde */ | |
45 | |
46 static op_implicit_list_t list_clts[] = | |
47 /* 0F 06 : CLTS : rw CR0 */ | |
48 {{ OP_R | OP_W, REG_CTRL_OFFSET}, {0}}; /* clts */ | |
49 | |
50 static op_implicit_list_t list_cmpxchg[] = | |
51 /* 0F B0 : CMPXCHG : rw AL */ | |
52 {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* cmpxchg */ | |
53 | |
54 static op_implicit_list_t list_cmpxchgb[] = | |
55 /* 0F B1 : CMPXCHG : rw EAX */ | |
56 {{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* cmpxchg */ | |
57 | |
58 static op_implicit_list_t list_cmpxchg8b[] = | |
59 /* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */ | |
60 {{ OP_R | OP_W, REG_DWORD_OFFSET }, | |
61 { OP_R | OP_W, REG_DWORD_OFFSET + 2 }, | |
62 { OP_R, REG_DWORD_OFFSET + 1 }, | |
63 { OP_R, REG_DWORD_OFFSET + 3 }, {0}}; /* cmpxchg8b */ | |
64 | |
65 static op_implicit_list_t list_cpuid[] = | |
66 /* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */ | |
67 {{ OP_R | OP_W, REG_DWORD_OFFSET }, | |
68 { OP_W, REG_DWORD_OFFSET + 1 }, | |
69 { OP_W, REG_DWORD_OFFSET + 2 }, | |
70 { OP_W, REG_DWORD_OFFSET + 3 }, {0}}; /* cpuid */ | |
71 | |
72 static op_implicit_list_t list_cwd[] = | |
73 /* 99 : CWD/CWQ : rw EAX, w EDX */ | |
74 {{ OP_R | OP_W, REG_DWORD_OFFSET }, | |
75 { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* cwd */ | |
76 | |
77 static op_implicit_list_t list_daa[] = | |
78 /* 27 : DAA : rw AL */ | |
79 /* 2F : DAS : rw AL */ | |
80 {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* daa */ | |
81 | |
82 static op_implicit_list_t list_idiv[] = | |
83 /* F6 : DIV, IDIV : r AX, w AL, w AH */ | |
84 /* FIXED: first op was EAX, not Aw. TODO: verify! */ | |
85 {{ OP_R, REG_WORD_OFFSET }, | |
86 { OP_W, REG_BYTE_OFFSET }, | |
87 { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* div */ | |
88 | |
89 static op_implicit_list_t list_div[] = | |
90 /* F7 : DIV, IDIV : rw EDX, rw EAX */ | |
91 {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, | |
92 { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* div */ | |
93 | |
94 static op_implicit_list_t list_enter[] = | |
95 /* C8 : ENTER : rw ESP w EBP */ | |
96 {{ OP_R | OP_W, REG_DWORD_OFFSET + 4 }, | |
97 { OP_R, REG_DWORD_OFFSET + 5 }, {0}}; /* enter */ | |
98 | |
99 static op_implicit_list_t list_f2xm1[] = | |
100 /* D9 F0 : F2XM1 : rw ST(0) */ | |
101 /* D9 E1 : FABS : rw ST(0) */ | |
102 /* D9 E0 : FCHS : rw ST(0) */ | |
103 /* D9 FF : FCOS : rw ST(0)*/ | |
104 /* D8, DA : FDIV : rw ST(0) */ | |
105 /* D8, DA : FDIVR : rw ST(0) */ | |
106 /* D9 F2 : FPTAN : rw ST(0) */ | |
107 /* D9 FC : FRNDINT : rw ST(0) */ | |
108 /* D9 FB : FSINCOS : rw ST(0) */ | |
109 /* D9 FE : FSIN : rw ST(0) */ | |
110 /* D9 FA : FSQRT : rw ST(0) */ | |
111 /* D9 F4 : FXTRACT : rw ST(0) */ | |
112 {{ OP_R | OP_W, REG_FPU_OFFSET }, {0}}; /* f2xm1 */ | |
113 | |
114 static op_implicit_list_t list_fcom[] = | |
115 /* D8, DC, DE D9 : FCOM : r ST(0) */ | |
116 /* DE, DA : FICOM : r ST(0) */ | |
117 /* DF, D8 : FIST : r ST(0) */ | |
118 /* D9 E4 : FTST : r ST(0) */ | |
119 /* D9 E5 : FXAM : r ST(0) */ | |
120 {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fcom */ | |
121 | |
122 static op_implicit_list_t list_fpatan[] = | |
123 /* D9 F3 : FPATAN : r ST(0), rw ST(1) */ | |
124 {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fpatan */ | |
125 | |
126 static op_implicit_list_t list_fprem[] = | |
127 /* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */ | |
128 /* D9 FD : FSCALE : rw ST(0), r ST(1) */ | |
129 {{ OP_R | OP_W, REG_FPU_OFFSET }, | |
130 { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fprem */ | |
131 | |
132 static op_implicit_list_t list_faddp[] = | |
133 /* DE C1 : FADDP : r ST(0), rw ST(1) */ | |
134 /* DE E9 : FSUBP : r ST(0), rw ST(1) */ | |
135 /* D9 F1 : FYL2X : r ST(0), rw ST(1) */ | |
136 /* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */ | |
137 {{ OP_R, REG_FPU_OFFSET }, | |
138 { OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0}}; /* faddp */ | |
139 | |
140 static op_implicit_list_t list_fucompp[] = | |
141 /* DA E9 : FUCOMPP : r ST(0), r ST(1) */ | |
142 {{ OP_R, REG_FPU_OFFSET }, | |
143 { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fucompp */ | |
144 | |
145 static op_implicit_list_t list_imul[] = | |
146 /* F6 : IMUL : r AL, w AX */ | |
147 /* F6 : MUL : r AL, w AX */ | |
148 {{ OP_R, REG_BYTE_OFFSET }, | |
149 { OP_W, REG_WORD_OFFSET }, {0}}; /* imul */ | |
150 | |
151 static op_implicit_list_t list_mul[] = | |
152 /* F7 : IMUL : rw EAX, w EDX */ | |
153 /* F7 : MUL : rw EAX, w EDX */ | |
154 {{ OP_R | OP_W, REG_DWORD_OFFSET }, | |
155 { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* imul */ | |
156 | |
157 static op_implicit_list_t list_lahf[] = | |
158 /* 9F : LAHF : r EFLAGS, w AH */ | |
159 {{ OP_R, REG_FLAGS_INDEX }, | |
160 { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* lahf */ | |
161 | |
162 static op_implicit_list_t list_ldmxcsr[] = | |
163 /* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */ | |
164 {{ OP_W, REG_MXCSG_INDEX }, {0}}; /* ldmxcsr */ | |
165 | |
166 static op_implicit_list_t list_leave[] = | |
167 /* C9 : LEAVE : rw ESP, w EBP */ | |
168 {{ OP_R | OP_W, REG_ESP_INDEX }, | |
169 { OP_W, REG_DWORD_OFFSET + 5 }, {0}}; /* leave */ | |
170 | |
171 static op_implicit_list_t list_lgdt[] = | |
172 /* 0F 01 : LGDT : w GDTR */ | |
173 {{ OP_W, REG_GDTR_INDEX }, {0}}; /* lgdt */ | |
174 | |
175 static op_implicit_list_t list_lidt[] = | |
176 /* 0F 01 : LIDT : w IDTR */ | |
177 {{ OP_W, REG_IDTR_INDEX }, {0}}; /* lidt */ | |
178 | |
179 static op_implicit_list_t list_lldt[] = | |
180 /* 0F 00 : LLDT : w LDTR */ | |
181 {{ OP_W, REG_LDTR_INDEX }, {0}}; /* lldt */ | |
182 | |
183 static op_implicit_list_t list_lmsw[] = | |
184 /* 0F 01 : LMSW : w CR0 */ | |
185 {{ OP_W, REG_CTRL_OFFSET }, {0}}; /* lmsw */ | |
186 | |
187 static op_implicit_list_t list_loop[] = | |
188 /* E0, E1, E2 : LOOP : rw ECX */ | |
189 {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* loop */ | |
190 | |
191 static op_implicit_list_t list_ltr[] = | |
192 /* 0F 00 : LTR : w Task Register */ | |
193 {{ OP_W, REG_TR_INDEX }, {0}}; /* ltr */ | |
194 | |
195 static op_implicit_list_t list_pop[] = | |
196 /* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */ | |
197 /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ | |
198 {{ OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* pop, push */ | |
199 | |
200 static op_implicit_list_t list_popad[] = | |
201 /* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */ | |
202 {{ OP_R | OP_W, REG_ESP_INDEX }, | |
203 { OP_W, REG_DWORD_OFFSET + 7 }, | |
204 { OP_W, REG_DWORD_OFFSET + 6 }, | |
205 { OP_W, REG_DWORD_OFFSET + 5 }, | |
206 { OP_W, REG_DWORD_OFFSET + 3 }, | |
207 { OP_W, REG_DWORD_OFFSET + 2 }, | |
208 { OP_W, REG_DWORD_OFFSET + 1 }, | |
209 { OP_W, REG_DWORD_OFFSET }, {0}}; /* popad */ | |
210 | |
211 static op_implicit_list_t list_popfd[] = | |
212 /* 9D : POPFD : rw esp, w eflags */ | |
213 {{ OP_R | OP_W, REG_ESP_INDEX }, | |
214 { OP_W, REG_FLAGS_INDEX }, {0}}; /* popfd */ | |
215 | |
216 static op_implicit_list_t list_pushad[] = | |
217 /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ | |
218 /* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */ | |
219 {{ OP_R | OP_W, REG_ESP_INDEX }, | |
220 { OP_R, REG_DWORD_OFFSET }, | |
221 { OP_R, REG_DWORD_OFFSET + 1 }, | |
222 { OP_R, REG_DWORD_OFFSET + 2 }, | |
223 { OP_R, REG_DWORD_OFFSET + 3 }, | |
224 { OP_R, REG_DWORD_OFFSET + 5 }, | |
225 { OP_R, REG_DWORD_OFFSET + 6 }, | |
226 { OP_R, REG_DWORD_OFFSET + 7 }, {0}}; /* pushad */ | |
227 | |
228 static op_implicit_list_t list_pushfd[] = | |
229 /* 9C : PUSHFD : rw esp, r eflags */ | |
230 {{ OP_R | OP_W, REG_ESP_INDEX }, | |
231 { OP_R, REG_FLAGS_INDEX }, {0}}; /* pushfd */ | |
232 | |
233 static op_implicit_list_t list_rdmsr[] = | |
234 /* 0F 32 : RDMSR : r ECX, w EDX, w EAX */ | |
235 {{ OP_R, REG_DWORD_OFFSET + 1 }, | |
236 { OP_W, REG_DWORD_OFFSET + 2 }, | |
237 { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdmsr */ | |
238 | |
239 static op_implicit_list_t list_rdpmc[] = | |
240 /* 0F 33 : RDPMC : r ECX, w EDX, w EAX */ | |
241 {{ OP_R, REG_DWORD_OFFSET + 1 }, | |
242 { OP_W, REG_DWORD_OFFSET + 2 }, | |
243 { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdpmc */ | |
244 | |
245 static op_implicit_list_t list_rdtsc[] = | |
246 /* 0F 31 : RDTSC : rw EDX, rw EAX */ | |
247 {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, | |
248 { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* rdtsc */ | |
249 | |
250 static op_implicit_list_t list_rep[] = | |
251 /* F3, F2 ... : REP : rw ECX */ | |
252 {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* rep */ | |
253 | |
254 static op_implicit_list_t list_rsm[] = | |
255 /* 0F AA : RSM : r CR4, r CR0 */ | |
256 {{ OP_R, REG_CTRL_OFFSET + 4 }, | |
257 { OP_R, REG_CTRL_OFFSET }, {0}}; /* rsm */ | |
258 | |
259 static op_implicit_list_t list_sahf[] = | |
260 /* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */ | |
261 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sahf */ | |
262 | |
263 static op_implicit_list_t list_sgdt[] = | |
264 /* 0F : SGDT : r gdtr */ | |
265 /* TODO: finish this! */ | |
266 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sgdt */ | |
267 | |
268 static op_implicit_list_t list_sidt[] = | |
269 /* 0F : SIDT : r idtr */ | |
270 /* TODO: finish this! */ | |
271 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sidt */ | |
272 | |
273 static op_implicit_list_t list_sldt[] = | |
274 /* 0F : SLDT : r ldtr */ | |
275 /* TODO: finish this! */ | |
276 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sldt */ | |
277 | |
278 static op_implicit_list_t list_smsw[] = | |
279 /* 0F : SMSW : r CR0 */ | |
280 /* TODO: finish this! */ | |
281 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* smsw */ | |
282 | |
283 static op_implicit_list_t list_stmxcsr[] = | |
284 /* 0F AE : STMXCSR : r MXCSR */ | |
285 /* TODO: finish this! */ | |
286 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* stmxcsr */ | |
287 | |
288 static op_implicit_list_t list_str[] = | |
289 /* 0F 00 : STR : r TR (task register) */ | |
290 /* TODO: finish this! */ | |
291 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* str */ | |
292 | |
293 static op_implicit_list_t list_sysenter[] = | |
294 /* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags | |
295 * r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */ | |
296 /* TODO: finish this! */ | |
297 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysenter */ | |
298 | |
299 static op_implicit_list_t list_sysexit[] = | |
300 /* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp | |
301 * r sysenter_cs_msr */ | |
302 /* TODO: finish this! */ | |
303 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysexit */ | |
304 | |
305 static op_implicit_list_t list_wrmsr[] = | |
306 /* 0F 30 : WRMST : r edx, r eax, r ecx */ | |
307 /* TODO: finish this! */ | |
308 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* wrmsr */ | |
309 | |
310 static op_implicit_list_t list_xlat[] = | |
311 /* D7 : XLAT : rw al r ebx (ptr) */ | |
312 /* TODO: finish this! */ | |
313 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* xlat */ | |
314 /* TODO: | |
315 * monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R | |
316 * mwait 0f 01 c9 eax OP_R ecx OP_R | |
317 */ | |
318 static op_implicit_list_t list_monitor[] = | |
319 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* monitor */ | |
320 static op_implicit_list_t list_mwait[] = | |
321 {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* mwait */ | |
322 | |
323 op_implicit_list_t *op_implicit_list[] = { | |
324 /* This is a list of implicit operands which are read/written by | |
325 * various x86 instructions. Note that modifications to the stack | |
326 * register are mentioned here, but that additional information on | |
327 * the effect an instruction has on the stack is contained in the | |
328 * x86_insn_t 'stack_mod' and 'stack_mod_val' fields. Use of the | |
329 * eflags register, i.e. setting, clearing, and testing flags, is | |
330 * not recorded here but rather in the flags_set and flags_tested | |
331 * fields of the x86_insn_t.*/ | |
332 NULL, | |
333 list_aaa, list_aad, list_call, list_cbw, /* 1 - 4 */ | |
334 list_cwde, list_clts, list_cmpxchg, list_cmpxchgb, /* 5 - 8 */ | |
335 list_cmpxchg8b, list_cpuid, list_cwd, list_daa, /* 9 - 12 */ | |
336 list_idiv, list_div, list_enter, list_f2xm1, /* 13 - 16 */ | |
337 list_fcom, list_fpatan, list_fprem, list_faddp, /* 17 - 20 */ | |
338 list_fucompp, list_imul, list_mul, list_lahf, /* 21 - 24 */ | |
339 list_ldmxcsr, list_leave, list_lgdt, list_lidt, /* 25 - 28 */ | |
340 list_lldt, list_lmsw, list_loop, list_ltr, /* 29 - 32 */ | |
341 list_pop, list_popad, list_popfd, list_pushad, /* 33 - 36 */ | |
342 list_pushfd, list_rdmsr, list_rdpmc, list_rdtsc, /* 37 - 40 */ | |
343 /* NOTE: 'REP' is a hack since it is a prefix: if its position | |
344 * in the table changes, then change IDX_IMPLICIT_REP in the .h */ | |
345 list_rep, list_rsm, list_sahf, list_sgdt, /* 41 - 44 */ | |
346 list_sidt, list_sldt, list_smsw, list_stmxcsr, /* 45 - 48 */ | |
347 list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */ | |
348 list_xlat, list_monitor, list_mwait, /* 53 - 55*/ | |
349 NULL /* end of list */ | |
350 }; | |
351 | |
352 #define LAST_IMPL_IDX 55 | |
353 | |
354 static void handle_impl_reg( x86_op_t *op, uint32_t val ) { | |
355 x86_reg_t *reg = &op->data.reg; | |
356 op->type = op_register; | |
357 ia32_handle_register( reg, (unsigned int) val ); | |
358 switch (reg->size) { | |
359 case 1: | |
360 op->datatype = op_byte; break; | |
361 case 2: | |
362 op->datatype = op_word; break; | |
363 case 4: | |
364 op->datatype = op_dword; break; | |
365 case 8: | |
366 op->datatype = op_qword; break; | |
367 case 10: | |
368 op->datatype = op_extreal; break; | |
369 case 16: | |
370 op->datatype = op_dqword; break; | |
371 } | |
372 return; | |
373 } | |
374 | |
375 /* 'impl_idx' is the value from the opcode table: between 1 and LAST_IMPL_IDX */ | |
376 /* returns number of operands added */ | |
377 unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx ) { | |
378 op_implicit_list_t *list; | |
379 x86_op_t *op; | |
380 unsigned int num = 0; | |
381 | |
382 if (! impl_idx || impl_idx > LAST_IMPL_IDX ) { | |
383 return 0; | |
384 } | |
385 | |
386 for ( list = op_implicit_list[impl_idx]; list->type; list++, num++ ) { | |
387 enum x86_op_access access = (enum x86_op_access) OP_PERM(list->t
ype); | |
388 enum x86_op_flags flags = (enum x86_op_flags) (OP_FLAGS(list->
type) >> 12); | |
389 | |
390 op = NULL; | |
391 /* In some cases (MUL), EAX is an implicit operand hardcoded in | |
392 * the instruction without being explicitly listed in assembly. | |
393 * For this situation, find the hardcoded operand and add the | |
394 * implied flag rather than adding a new implicit operand. */ | |
395 x86_oplist_t * existing; | |
396 if (ia32_true_register_id(list->operand) == REG_DWORD_OFFSET) { | |
397 for ( existing = insn->operands; existing; existing = ex
isting->next ) { | |
398 if (existing->op.type == op_register && | |
399 existing->op.data.reg.id == list->operand) { | |
400 op = &existing->op; | |
401 break; | |
402 } | |
403 } | |
404 } | |
405 if (!op) { | |
406 op = x86_operand_new( insn ); | |
407 /* all implicit operands are registers */ | |
408 handle_impl_reg( op, list->operand ); | |
409 /* decrement the 'explicit count' incremented by default
in | |
410 * x86_operand_new */ | |
411 insn->explicit_count = insn->explicit_count -1; | |
412 } | |
413 if (!op) { | |
414 return num; /* gah! return early */ | |
415 } | |
416 op->access |= access; | |
417 op->flags |= flags; | |
418 op->flags |= op_implied; | |
419 } | |
420 | |
421 return num; | |
422 } | |
OLD | NEW |