blob: 16e41c249b1d917ab032716e8594c868fc647eff [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/* FIXME
16 opcode name remove to save table space; enum
17 x87
18 3dnow
19 cbw naming
20*/
21
22#include <vppinfra/error.h>
23#include <vppinfra/byte_order.h>
24#include <vppinfra/asm_x86.h>
25
26#define foreach_x86_gp_register \
27 _ (AX) _ (CX) _ (DX) _ (BX) \
28 _ (SP) _ (BP) _ (SI) _ (DI)
29
30typedef enum {
31#define _(r) X86_INSN_GP_REG_##r,
32 foreach_x86_gp_register
33#undef _
34} x86_insn_gp_register_t;
35
36typedef union {
37 struct {
38 u8 rm : 3;
39 u8 reg : 3;
40 u8 mode : 2;
41 };
42 u8 byte;
43} x86_insn_modrm_byte_t;
44
45typedef union {
46 struct {
47 u8 base : 3;
48 u8 index : 3;
49 u8 log2_scale : 2;
50 };
51 u8 byte;
52} x86_insn_sib_byte_t;
53
54always_inline uword
55x86_insn_has_modrm_byte (x86_insn_t * insn)
56{
57 int i;
58 for (i = 0; i < ARRAY_LEN (insn->operands); i++)
59 switch (insn->operands[i].code)
60 {
61 case 'G': case 'E': case 'M': case 'R':
62 return 1;
63 }
64 return 0;
65}
66
67always_inline uword
68x86_insn_immediate_type (x86_insn_t * insn)
69{
70 int i;
71 for (i = 0; i < ARRAY_LEN (insn->operands); i++)
72 switch (insn->operands[i].code)
73 {
74 case 'J':
75 case 'I':
76 case 'O':
77 return insn->operands[i].type;
78 }
79 return 0;
80}
81
82/* Opcode extension in modrm byte reg field. */
83#define foreach_x86_insn_modrm_reg_group \
84 _ (1) _ (1a) _ (2) _ (3) _ (4) _ (5) _ (6) _ (7) \
85 _ (8) _ (9) _ (10) _ (11) _ (12) _ (13) _ (14) \
86 _ (15) _ (16) _ (p)
87
88#define foreach_x86_insn_sse_group \
89 _ (10) _ (28) _ (50) _ (58) _ (60) _ (68) _ (70) _ (78) \
90 _ (c0) _ (d0) _ (d8) _ (e0) _ (e8) _ (f0) _ (f8)
91
92enum {
93#define _(x) X86_INSN_MODRM_REG_GROUP_##x,
94 foreach_x86_insn_modrm_reg_group
95#undef _
96#define _(x) X86_INSN_SSE_GROUP_##x,
97 foreach_x86_insn_sse_group
98#undef _
99};
100
101enum {
102#define _(x) \
103 X86_INSN_FLAG_MODRM_REG_GROUP_##x \
104 = X86_INSN_FLAG_SET_MODRM_REG_GROUP (1 + X86_INSN_MODRM_REG_GROUP_##x),
105 foreach_x86_insn_modrm_reg_group
106#undef _
107
108#define _(x) \
109 X86_INSN_FLAG_SSE_GROUP_##x \
110 = X86_INSN_FLAG_SET_SSE_GROUP (1 + X86_INSN_SSE_GROUP_##x),
111 foreach_x86_insn_sse_group
112#undef _
113};
114
115#define foreach_x86_gp_reg \
116 _ (AX) _ (CX) _ (DX) _ (BX) \
117 _ (SP) _ (BP) _ (SI) _ (DI)
118
119#define foreach_x86_condition \
120 _ (o) _ (no) _ (b) _ (nb) \
121 _ (z) _ (nz) _ (be) _ (nbe) \
122 _ (s) _ (ns) _ (p) _ (np) \
123 _ (l) _ (nl) _ (le) _ (nle)
124
125#define _3f(x,f,o0,o1,o2) \
126{ \
127 .name = #x, \
128 .flags = (f), \
129 .operands[0] = { .data = #o0 }, \
130 .operands[1] = { .data = #o1 }, \
131 .operands[2] = { .data = #o2 }, \
132}
133
134#define _2f(x,f,o0,o1) _3f(x,f,o0,o1,__)
135#define _1f(x,f,o0) _2f(x,f,o0,__)
136#define _0f(x,f) _1f(x,f,__)
137
138#define _3(x,o0,o1,o2) _3f(x,0,o0,o1,o2)
139#define _2(x,o0,o1) _2f(x,0,o0,o1)
140#define _1(x,o0) _1f(x,0,o0)
141#define _0(x) _0f(x,0)
142
143static x86_insn_t x86_insns_one_byte[256] = {
144
145#define _(x) \
146 _2 (x, Eb, Gb), \
147 _2 (x, Ev, Gv), \
148 _2 (x, Gb, Eb), \
149 _2 (x, Gv, Ev), \
150 _2 (x, AL, Ib), \
151 _2 (x, AX, Iz)
152
153 /* 0x00 */
154 _ (add),
155 _0 (push_es),
156 _0 (pop_es),
157 _ (or),
158 _0 (push_cs),
159 _0 (escape_two_byte),
160
161 /* 0x10 */
162 _ (adc),
163 _0 (push_ss),
164 _0 (pop_ss),
165 _ (sbb),
166 _0 (push_ds),
167 _0 (pop_ds),
168
169 /* 0x20 */
170 _ (and),
171 _0 (segment_es),
172 _0 (daa),
173 _ (sub),
174 _0 (segment_cs),
175 _0 (das),
176
177 /* 0x30 */
178 _ (xor),
179 _0 (segment_ss),
180 _0 (aaa),
181 _ (cmp),
182 _0 (segment_ds),
183 _0 (aas),
184
185#undef _
186
187 /* 0x40 */
188#define _(r) _1 (inc, r),
189 foreach_x86_gp_reg
190#undef _
191#define _(r) _1 (dec, r),
192 foreach_x86_gp_reg
193#undef _
194
195 /* 0x50 */
196#define _(r) _1f (push, X86_INSN_FLAG_DEFAULT_64_BIT, r),
197 foreach_x86_gp_reg
198#undef _
199#define _(r) _1f (pop, X86_INSN_FLAG_DEFAULT_64_BIT, r),
200 foreach_x86_gp_reg
201#undef _
202
203 /* 0x60 */
204 _0 (pusha),
205 _0 (popa),
206 _2 (bound, Gv, Ma),
207 _2 (movsxd, Gv, Ed),
208 _0 (segment_fs),
209 _0 (segment_gs),
210 _0 (operand_type),
211 _0 (address_size),
212 _1f (push, X86_INSN_FLAG_DEFAULT_64_BIT, Iz),
213 _3 (imul, Gv, Ev, Iz),
214 _1f (push, X86_INSN_FLAG_DEFAULT_64_BIT, Ib),
215 _3 (imul, Gv, Ev, Ib),
216 _1 (insb, DX),
217 _1 (insw, DX),
218 _1 (outsb, DX),
219 _1 (outsw, DX),
220
221 /* 0x70 */
222#define _(x) _1 (j##x, Jb),
223 foreach_x86_condition
224#undef _
225
226 /* 0x80 */
227 _2f (modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib),
228 _2f (modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Iz),
229 _2f (modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib),
230 _2f (modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Ib),
231 _2 (test, Eb, Gb),
232 _2 (test, Ev, Gv),
233 _2 (xchg, Eb, Gb),
234 _2 (xchg, Ev, Gv),
235 _2 (mov, Eb, Gb),
236 _2 (mov, Ev, Gv),
237 _2 (mov, Gb, Eb),
238 _2 (mov, Gv, Ev),
239 _2 (mov, Ev, Sw),
240 _2 (lea, Gv, Ev),
241 _2 (mov, Sw, Ew),
242 _1f (modrm_group_1a, X86_INSN_FLAG_MODRM_REG_GROUP_1a, Ev),
243
244 /* 0x90 */
245 _0 (nop),
246 _1 (xchg, CX),
247 _1 (xchg, DX),
248 _1 (xchg, BX),
249 _1 (xchg, SP),
250 _1 (xchg, BP),
251 _1 (xchg, SI),
252 _1 (xchg, DI),
253 _0 (cbw),
254 _0 (cwd),
255 _1 (call, Ap),
256 _0 (wait),
257 _0 (pushf),
258 _0 (popf),
259 _0 (sahf),
260 _0 (lahf),
261
262 /* 0xa0 */
263 _2 (mov, AL, Ob),
264 _2 (mov, AX, Ov),
265 _2 (mov, Ob, AL),
266 _2 (mov, Ov, AX),
267 _0 (movsb),
268 _0 (movsw),
269 _0 (cmpsb),
270 _0 (cmpsw),
271 _2 (test, AL, Ib),
272 _2 (test, AX, Iz),
273 _1 (stosb, AL),
274 _1 (stosw, AX),
275 _1 (lodsb, AL),
276 _1 (lodsw, AX),
277 _1 (scasb, AL),
278 _1 (scasw, AX),
279
280 /* 0xb0 */
281 _2 (mov, AL, Ib),
282 _2 (mov, CL, Ib),
283 _2 (mov, DL, Ib),
284 _2 (mov, BL, Ib),
285 _2 (mov, AH, Ib),
286 _2 (mov, CH, Ib),
287 _2 (mov, DH, Ib),
288 _2 (mov, BH, Ib),
289#define _(r) _2 (mov, r, Iv),
290 foreach_x86_gp_reg
291#undef _
292
293 /* 0xc0 */
294 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, Ib),
295 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, Ib),
296 _1 (ret, Iw),
297 _0 (ret),
298 _2 (les, Gz, Mp),
299 _2 (lds, Gz, Mp),
300 _2f (modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Eb, Ib),
301 _2f (modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Ev, Iz),
302 _2 (enter, Iw, Ib),
303 _0 (leave),
304 _1 (ret, Iw),
305 _0 (ret),
306 _0 (int3),
307 _1 (int, Ib),
308 _0 (into),
309 _0 (iret),
310
311 /* 0xd0 */
312 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, 1b),
313 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, 1b),
314 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, CL),
315 _2f (modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, CL),
316 _0 (aam),
317 _0 (aad),
318 _0 (salc),
319 _0 (xlat),
320 /* FIXME x87 */
321 _0 (bad),
322 _0 (bad),
323 _0 (bad),
324 _0 (bad),
325 _0 (bad),
326 _0 (bad),
327 _0 (bad),
328 _0 (bad),
329
330 /* 0xe0 */
331 _1 (loopnz, Jb),
332 _1 (loopz, Jb),
333 _1 (loop, Jb),
334 _1 (jcxz, Jb),
335 _2 (in, AL, Ib),
336 _2 (in, AX, Ib),
337 _2 (out, Ib, AL),
338 _2 (out, Ib, AX),
339 _1f (call, X86_INSN_FLAG_DEFAULT_64_BIT, Jz),
340 _1f ( jmp, X86_INSN_FLAG_DEFAULT_64_BIT, Jz),
341 _1 (jmp, Ap),
342 _1 (jmp, Jb),
343 _2 (in, AL, DX),
344 _2 (in, AX, DX),
345 _2 (out, DX, AL),
346 _2 (out, DX, AX),
347
348 /* 0xf0 */
349 _0 (lock),
350 _0 (int1),
351 _0 (repne),
352 _0 (rep),
353 _0 (hlt),
354 _0 (cmc),
355 _0f (modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3),
356 _0f (modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3),
357 _0 (clc),
358 _0 (stc),
359 _0 (cli),
360 _0 (sti),
361 _0 (cld),
362 _0 (std),
363 _1f (modrm_group_4, X86_INSN_FLAG_MODRM_REG_GROUP_4, Eb),
364 _0f (modrm_group_5, X86_INSN_FLAG_MODRM_REG_GROUP_5),
365};
366
367static x86_insn_t x86_insns_two_byte[256] = {
368 /* 0x00 */
369 _0f (modrm_group_6, X86_INSN_FLAG_MODRM_REG_GROUP_6),
370 _0f (modrm_group_7, X86_INSN_FLAG_MODRM_REG_GROUP_7),
371 _2 (lar, Gv, Ew),
372 _2 (lsl, Gv, Ew),
373 _0 (bad),
374 _0 (syscall),
375 _0 (clts),
376 _0 (sysret),
377 _0 (invd),
378 _0 (wbinvd),
379 _0 (bad),
380 _0 (ud2),
381 _0 (bad),
382 _0f (modrm_group_p, X86_INSN_FLAG_MODRM_REG_GROUP_p),
383 _0 (femms),
384 _0 (escape_3dnow),
385
386 /* 0x10 */
387 _2f (movups, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex),
388 _2f (movups, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx),
389 _2f (movlps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx),
390 _2f (movlps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex),
391 _2f (unpcklps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex),
392 _2f (unpckhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex),
393 _2f (movhps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx),
394 _2f (movhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex),
395 _0f (modrm_group_16, X86_INSN_FLAG_MODRM_REG_GROUP_16),
396 _0 (nop),
397 _0 (nop),
398 _0 (nop),
399 _0 (nop),
400 _0 (nop),
401 _0 (nop),
402 _0 (nop),
403
404 /* 0x20 */
405 _2 (mov, Rv, Cv),
406 _2 (mov, Rv, Dv),
407 _2 (mov, Cv, Rv),
408 _2 (mov, Dv, Rv),
409 _0 (bad),
410 _0 (bad),
411 _0 (bad),
412 _0 (bad),
413 _2f (movaps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
414 _2f (movaps, X86_INSN_FLAG_SSE_GROUP_28, Ex, Gx),
415 _2f (cvtpi2ps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
416 _2f (movntps, X86_INSN_FLAG_SSE_GROUP_28, Mx, Gx),
417 _2f (cvttps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
418 _2f (cvtps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
419 _2f (ucomiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
420 _2f (comiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex),
421
422 /* 0x30 */
423 _0 (wrmsr),
424 _0 (rdtsc),
425 _0 (rdmsr),
426 _0 (rdpmc),
427 _0 (sysenter),
428 _0 (sysexit),
429 _0 (bad),
430 _0 (bad),
431 _0 (bad),
432 _0 (bad),
433 _0 (bad),
434 _0 (bad),
435 _0 (bad),
436 _0 (bad),
437 _0 (bad),
438 _0 (bad),
439
440 /* 0x40 */
441#define _(x) _2 (cmov##x, Gv, Ev),
442 foreach_x86_condition
443#undef _
444
445 /* 0x50 */
446 _2f (movmskps, X86_INSN_FLAG_SSE_GROUP_50, Gd, Rx),
447 _2f (sqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
448 _2f (rsqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
449 _2f (rcpps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
450 _2f (andps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
451 _2f (andnps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
452 _2f (orps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
453 _2f (xorps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex),
454 _2f (addps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
455 _2f (mulps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
456 _2f (cvtps2pd, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
457 _2f (cvtdq2ps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
458 _2f (subps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
459 _2f (minps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
460 _2f (divps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
461 _2f (maxps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex),
462
463 /* 0x60 */
464 _2f (punpcklbw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
465 _2f (punpcklwd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
466 _2f (punpckldq, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
467 _2f (packsswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
468 _2f (pcmpgtb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
469 _2f (pcmpgtw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
470 _2f (pcmpgtd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
471 _2f (packuswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em),
472 _2f (punpckhbw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
473 _2f (punpckhwd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
474 _2f (punpckhdq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
475 _2f (packssdw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
476 _0f (bad, X86_INSN_FLAG_SSE_GROUP_68),
477 _0f (bad, X86_INSN_FLAG_SSE_GROUP_68),
478 _2f (movd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
479 _2f (movq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em),
480
481 /* 0x70 */
482 _3f (pshufw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em, Ib),
483 _0f (modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12),
484 _0f (modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13),
485 _0f (modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14),
486 _2f (pcmpeqb, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em),
487 _2f (pcmpeqw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em),
488 _2f (pcmpeqd, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em),
489 _0f (emms, X86_INSN_FLAG_SSE_GROUP_70),
490 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
491 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
492 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
493 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
494 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
495 _0f (bad, X86_INSN_FLAG_SSE_GROUP_78),
496 _2f (movd, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm),
497 _2f (movq, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm),
498
499 /* 0x80 */
500#define _(x) _1 (jmp##x, Jz),
501 foreach_x86_condition
502#undef _
503
504 /* 0x90 */
505#define _(x) _1 (set##x, Eb),
506 foreach_x86_condition
507#undef _
508
509 /* 0xa0 */
510 _0 (push_fs),
511 _0 (pop_fs),
512 _0 (cpuid),
513 _2 (bt, Ev, Gv),
514 _3 (shld, Ev, Gv, Ib),
515 _3 (shld, Ev, Gv, CL),
516 _0 (bad),
517 _0 (bad),
518 _0 (push_gs),
519 _0 (pop_gs),
520 _0 (rsm),
521 _2 (bts, Ev, Gv),
522 _3 (shrd, Ev, Gv, Ib),
523 _3 (shrd, Ev, Gv, CL),
524 _0f (modrm_group_15, X86_INSN_FLAG_MODRM_REG_GROUP_15),
525 _2 (imul, Gv, Ev),
526
527 /* 0xb0 */
528 _2 (cmpxchg, Eb, Gb),
529 _2 (cmpxchg, Ev, Gv),
530 _2 (lss, Gz, Mp),
531 _2 (btr, Ev, Gv),
532 _2 (lfs, Gz, Mp),
533 _2 (lgs, Gz, Mp),
534 _2 (movzbl, Gv, Eb),
535 _2 (movzwl, Gv, Ew),
536 _0 (bad),
537 _0f (modrm_group_10, X86_INSN_FLAG_MODRM_REG_GROUP_10),
538 _2f (modrm_group_8, X86_INSN_FLAG_MODRM_REG_GROUP_8, Ev, Ib),
539 _2 (btc, Ev, Gv),
540 _2 (bsf, Gv, Ev),
541 _2 (bsr, Gv, Ev),
542 _2 (movsx, Gv, Eb),
543 _2 (movsx, Gv, Ew),
544
545 /* 0xc0 */
546 _2 (xadd, Eb, Gb),
547 _2 (xadd, Ev, Gv),
548 _3f (cmpps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib),
549 _2 (movnti, Mv, Gv),
550 _3f (pinsrw, X86_INSN_FLAG_SSE_GROUP_c0, Gm, Ew, Ib),
551 _3f (pextrw, X86_INSN_FLAG_SSE_GROUP_c0, Gd, Rm, Ib),
552 _3f (shufps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib),
553 _1f (modrm_group_9, X86_INSN_FLAG_MODRM_REG_GROUP_9, Mx),
554#define _(r) _1 (bswap, r),
555 foreach_x86_gp_reg
556#undef _
557
558 /* 0xd0 */
559 _0f (bad, X86_INSN_FLAG_SSE_GROUP_d0),
560 _2f (psrlw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em),
561 _2f (psrld, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em),
562 _2f (psrlq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em),
563 _2f (paddq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em),
564 _2f (pmullw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em),
565 _0f (bad, X86_INSN_FLAG_SSE_GROUP_d0),
566 _2f (pmovmskb, X86_INSN_FLAG_SSE_GROUP_d0, Gd, Rm),
567 _2f (psubusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
568 _2f (psubusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
569 _2f (pminub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
570 _2f (pand, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
571 _2f (paddusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
572 _2f (paddusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
573 _2f (pmaxub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
574 _2f (pandn, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em),
575
576 /* 0xe0 */
577 _2f (pavgb, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
578 _2f (psraw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
579 _2f (psrad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
580 _2f (pavgw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
581 _2f (pmulhuw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
582 _2f (pmulhw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
583 _2f (bad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em),
584 _2f (movntq, X86_INSN_FLAG_SSE_GROUP_e0, Mm, Gm),
585 _2f (psubsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
586 _2f (psubsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
587 _2f (pminsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
588 _2f (por, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
589 _2f (paddsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
590 _2f (paddsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
591 _2f (pmaxsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
592 _2f (pxor, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em),
593
594 /* 0xf0 */
595 _0f (bad, X86_INSN_FLAG_SSE_GROUP_f0),
596 _2f (psllw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
597 _2f (pslld, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
598 _2f (psllq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
599 _2f (pmuludq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
600 _2f (pmaddwd, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
601 _2f (psadbw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
602 _2f (maskmovq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em),
603 _2f (psubb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
604 _2f (psubw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
605 _2f (psubd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
606 _2f (psubq, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
607 _2f (paddb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
608 _2f (paddw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
609 _2f (paddd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em),
610 _0f (bad, X86_INSN_FLAG_SSE_GROUP_f8),
611};
612
613typedef struct {
614 x86_insn_t insns[8];
615} x86_insn_group8_t;
616
617/* Escape groups are indexed by modrm reg field. */
618static x86_insn_group8_t x86_insn_modrm_reg_groups[] = {
619 [X86_INSN_MODRM_REG_GROUP_1].insns = {
620 _0 (add), _0 ( or), _0 (adc), _0 (sbb),
621 _0 (and), _0 (sub), _0 (xor), _0 (cmp),
622 },
623
624 [X86_INSN_MODRM_REG_GROUP_1a].insns = {
625 _0f (pop, X86_INSN_FLAG_DEFAULT_64_BIT),
626 _0 (bad), _0 (bad), _0 (bad),
627 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
628 },
629
630 [X86_INSN_MODRM_REG_GROUP_2].insns = {
631 _0 (rol), _0 (ror), _0 (rcl), _0 (rcr),
632 _0 (shl), _0 (shr), _0 (sal), _0 (sar),
633 },
634
635 [X86_INSN_MODRM_REG_GROUP_3].insns = {
636 _0 (test), _0 (test), _0 (not), _0 (neg),
637 _0 (mul), _0 (imul), _0 (div), _0 (idiv),
638 },
639
640 [X86_INSN_MODRM_REG_GROUP_4].insns = {
641 _0 (inc), _0 (dec), _0 (bad), _0 (bad),
642 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
643 },
644
645 [X86_INSN_MODRM_REG_GROUP_5].insns = {
646 _1 (inc, Ev),
647 _1 (dec, Ev),
648 _1f (call, X86_INSN_FLAG_DEFAULT_64_BIT, Ev),
649 _1 (call, Mp),
650 _1f (jmp, X86_INSN_FLAG_DEFAULT_64_BIT, Ev),
651 _1 (jmp, Mp),
652 _1f (push, X86_INSN_FLAG_DEFAULT_64_BIT, Ev),
653 _0 (bad),
654 },
655
656 [X86_INSN_MODRM_REG_GROUP_6].insns = {
657 _1 (sldt, Ev),
658 _1 (str, Ev),
659 _1 (lldt, Ev),
660 _1 (ltr, Ev),
661 _1 (verr, Ev),
662 _1 (verw, Ev),
663 _0 (bad),
664 _0 (bad),
665 },
666
667 [X86_INSN_MODRM_REG_GROUP_7].insns = {
668 _1 (sgdt, Mv),
669 _1 (sidt, Mv),
670 _1 (lgdt, Mv),
671 _1 (lidt, Mv),
672 _1 (smsw, Ev),
673 _0 (bad),
674 _1 (lmsw, Ew),
675 _1 (invlpg, Mv),
676 },
677
678 [X86_INSN_MODRM_REG_GROUP_8].insns = {
679 _0 (bad),
680 _0 (bad),
681 _0 (bad),
682 _0 (bad),
683 _2 (bt, Ev, Ib),
684 _2 (bts, Ev, Ib),
685 _2 (btr, Ev, Ib),
686 _2 (btc, Ev, Ib),
687 },
688
689 [X86_INSN_MODRM_REG_GROUP_9].insns = {
690 _0 (bad),
691 _1 (cmpxchg, Mx),
692 _0 (bad),
693 _0 (bad),
694 _0 (bad),
695 _0 (bad),
696 _0 (bad),
697 _0 (bad),
698 },
699
700 [X86_INSN_MODRM_REG_GROUP_10].insns = {
701 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
702 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
703 },
704
705 [X86_INSN_MODRM_REG_GROUP_11].insns = {
706 _0 (mov), _0 (bad), _0 (bad), _0 (bad),
707 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
708 },
709
710 [X86_INSN_MODRM_REG_GROUP_12].insns = {
711 _0 (bad),
712 _0 (bad),
713 _2 (psrlw, Rm, Ib),
714 _0 (bad),
715 _2 (psraw, Rm, Ib),
716 _0 (bad),
717 _2 (psllw, Rm, Ib),
718 _0 (bad),
719 },
720
721 [X86_INSN_MODRM_REG_GROUP_13].insns = {
722 _0 (bad),
723 _0 (bad),
724 _2 (psrld, Rm, Ib),
725 _0 (bad),
726 _2 (psrad, Rm, Ib),
727 _0 (bad),
728 _2 (pslld, Rm, Ib),
729 _0 (bad),
730 },
731
732 [X86_INSN_MODRM_REG_GROUP_14].insns = {
733 _0 (bad),
734 _0 (bad),
735 _2 (psrlq, Rm, Ib),
736 _0f (bad, 0),
737 _0 (bad),
738 _0 (bad),
739 _2 (psllq, Rm, Ib),
740 _0f (bad, 0),
741 },
742
743 [X86_INSN_MODRM_REG_GROUP_15].insns = {
744 _1 (fxsave, Mv),
745 _1 (fxrstor, Mv),
746 _1 (ldmxcsr, Mv),
747 _1 (stmxcsr, Mv),
748 _0 (bad),
749 _1 (lfence, Mv),
750 _1 (mfence, Mv),
751 _1 (sfence, Mv),
752 },
753
754 [X86_INSN_MODRM_REG_GROUP_16].insns = {
755 _1 (prefetch_nta, Mv),
756 _1 (prefetch_t0, Mv),
757 _1 (prefetch_t1, Mv),
758 _1 (prefetch_t2, Mv),
759 _1 (prefetch_nop, Mv),
760 _1 (prefetch_nop, Mv),
761 _1 (prefetch_nop, Mv),
762 _1 (prefetch_nop, Mv),
763 },
764
765 [X86_INSN_MODRM_REG_GROUP_p].insns = {
766 _1 (prefetch_exclusive, Mv),
767 _1 (prefetch_modified, Mv),
768 _1 (prefetch_nop, Mv),
769 _1 (prefetch_modified, Mv),
770 _1 (prefetch_nop, Mv),
771 _1 (prefetch_nop, Mv),
772 _1 (prefetch_nop, Mv),
773 _1 (prefetch_nop, Mv),
774 },
775};
776
777static x86_insn_group8_t x86_insn_sse_groups_repz[] = {
778 [X86_INSN_SSE_GROUP_10].insns = {
779 _2 (movss, Gx, Ex),
780 _2 (movss, Ex, Gx),
781 _2 (movsldup, Gx, Ex),
782 _0 (bad),
783 _0 (bad),
784 _0 (bad),
785 _2 (movshdup, Gx, Ex),
786 _0 (bad),
787 },
788
789 [X86_INSN_SSE_GROUP_28].insns = {
790 _0 (bad),
791 _0 (bad),
792 _2 (cvtsi2ss, Gx, Ev),
793 _0 (bad),
794 _2 (cvttss2si, Gv, Ex),
795 _2 (cvtss2si, Gv, Ex),
796 _0 (bad),
797 _0 (bad),
798 },
799
800 [X86_INSN_SSE_GROUP_50].insns = {
801 _0 (bad),
802 _2 (sqrtss, Gx, Ex),
803 _2 (rsqrtps, Gx, Ex),
804 _2 (rcpss, Gx, Ex),
805 _0 (bad),
806 _0 (bad),
807 _0 (bad),
808 _0 (bad),
809 },
810
811 [X86_INSN_SSE_GROUP_58].insns = {
812 _2 (addss, Gx, Ex),
813 _2 (mulss, Gx, Ex),
814 _2 (cvtss2sd, Gx, Ex),
815 _2 (cvttps2dq, Gx, Ex),
816 _2 (subss, Gx, Ex),
817 _2 (minss, Gx, Ex),
818 _2 (divss, Gx, Ex),
819 _2 (maxss, Gx, Ex),
820 },
821
822 [X86_INSN_SSE_GROUP_60].insns = {
823 _0 (bad),
824 _0 (bad),
825 _0 (bad),
826 _0 (bad),
827 _0 (bad),
828 _0 (bad),
829 _0 (bad),
830 _0 (bad),
831 },
832
833 [X86_INSN_SSE_GROUP_68].insns = {
834 _0 (bad),
835 _0 (bad),
836 _0 (bad),
837 _0 (bad),
838 _0 (bad),
839 _0 (bad),
840 _0 (bad),
841 _2 (movdqu, Gx, Ex),
842 },
843
844 [X86_INSN_SSE_GROUP_70].insns = {
845 _3 (pshufhw, Gx, Ex, Ib),
846 _0 (bad),
847 _0 (bad),
848 _0 (bad),
849 _0 (bad),
850 _0 (bad),
851 _0 (bad),
852 _0 (bad),
853 },
854
855 [X86_INSN_SSE_GROUP_78].insns = {
856 _0 (bad),
857 _0 (bad),
858 _0 (bad),
859 _0 (bad),
860 _0 (bad),
861 _0 (bad),
862 _2 (movq, Gx, Ex),
863 _2 (movdqu, Ex, Gx),
864 },
865
866 [X86_INSN_SSE_GROUP_c0].insns = {
867 _0 (bad),
868 _0 (bad),
869 _3 (cmpss, Gx, Ex, Ib),
870 _0 (bad),
871 _0 (bad),
872 _0 (bad),
873 _0 (bad),
874 _0 (bad),
875 },
876
877 [X86_INSN_SSE_GROUP_d0].insns = {
878 _0 (bad),
879 _0 (bad),
880 _0 (bad),
881 _0 (bad),
882 _0 (bad),
883 _0 (bad),
884 _2 (movq2dq, Gx, Em),
885 _0 (bad),
886 },
887
888 [X86_INSN_SSE_GROUP_d8].insns = {
889 _0 (bad),
890 _0 (bad),
891 _0 (bad),
892 _0 (bad),
893 _0 (bad),
894 _0 (bad),
895 _0 (bad),
896 _0 (bad),
897 },
898
899 [X86_INSN_SSE_GROUP_e0].insns = {
900 _0 (bad),
901 _0 (bad),
902 _0 (bad),
903 _0 (bad),
904 _0 (bad),
905 _0 (bad),
906 _2 (cvtdq2pd, Gx, Ex),
907 _0 (bad),
908 },
909
910 [X86_INSN_SSE_GROUP_e8].insns = {
911 _0 (bad),
912 _0 (bad),
913 _0 (bad),
914 _0 (bad),
915 _0 (bad),
916 _0 (bad),
917 _0 (bad),
918 _0 (bad),
919 },
920
921 [X86_INSN_SSE_GROUP_f0].insns = {
922 _0 (bad),
923 _0 (bad),
924 _0 (bad),
925 _0 (bad),
926 _0 (bad),
927 _0 (bad),
928 _0 (bad),
929 _0 (bad),
930 },
931
932 [X86_INSN_SSE_GROUP_f8].insns = {
933 _0 (bad),
934 _0 (bad),
935 _0 (bad),
936 _0 (bad),
937 _0 (bad),
938 _0 (bad),
939 _0 (bad),
940 _0 (bad),
941 },
942};
943
944static x86_insn_group8_t x86_insn_sse_groups_operand_size[] = {
945 [X86_INSN_SSE_GROUP_10].insns = {
946 _2 (movupd, Gx, Ex),
947 _2 (movupd, Ex, Gx),
948 _2 (movlpd, Gx, Ex),
949 _2 (movlpd, Ex, Gx),
950 _2 (unpcklpd, Gx, Ex),
951 _2 (unpckhpd, Gx, Ex),
952 _2 (movhpd, Gx, Mx),
953 _2 (movhpd, Mx, Gx),
954 },
955
956 [X86_INSN_SSE_GROUP_28].insns = {
957 _2 (movapd, Gx, Ex),
958 _2 (movapd, Ex, Gx),
959 _2 (cvtpi2pd, Gx, Ex),
960 _2 (movntpd, Mx, Gx),
961 _2 (cvttpd2pi, Gx, Mx),
962 _2 (cvtpd2pi, Gx, Mx),
963 _2 (ucomisd, Gx, Ex),
964 _2 (comisd, Gx, Ex),
965 },
966
967 [X86_INSN_SSE_GROUP_50].insns = {
968 _2 (movmskpd, Gd, Rx),
969 _2 (sqrtpd, Gx, Ex),
970 _0 (bad),
971 _0 (bad),
972 _2 (andpd, Gx, Ex),
973 _2 (andnpd, Gx, Ex),
974 _2 (orpd, Gx, Ex),
975 _2 (xorpd, Gx, Ex),
976 },
977
978 [X86_INSN_SSE_GROUP_58].insns = {
979 _2 (addpd, Gx, Ex),
980 _2 (mulpd, Gx, Ex),
981 _2 (cvtpd2ps, Gx, Ex),
982 _2 (cvtps2dq, Gx, Ex),
983 _2 (subpd, Gx, Ex),
984 _2 (minpd, Gx, Ex),
985 _2 (divpd, Gx, Ex),
986 _2 (maxpd, Gx, Ex),
987 },
988
989 [X86_INSN_SSE_GROUP_60].insns = {
990 _2 (punpcklbw, Gx, Ex),
991 _2 (punpcklwd, Gx, Ex),
992 _2 (punpckldq, Gx, Ex),
993 _2 (packsswb, Gx, Ex),
994 _2 (pcmpgtb, Gx, Ex),
995 _2 (pcmpgtw, Gx, Ex),
996 _2 (pcmpgtd, Gx, Ex),
997 _2 (packuswb, Gx, Ex),
998 },
999
1000 [X86_INSN_SSE_GROUP_68].insns = {
1001 _2 (punpckhbw, Gx, Ex),
1002 _2 (punpckhwd, Gx, Ex),
1003 _2 (punpckhdq, Gx, Ex),
1004 _2 (packssdw, Gx, Ex),
1005 _2 (punpcklqdq, Gx, Ex),
1006 _2 (punpckhqdq, Gx, Ex),
1007 _2 (movd, Gx, Ev),
1008 _2 (movdqa, Gx, Ex),
1009 },
1010
1011 [X86_INSN_SSE_GROUP_70].insns = {
1012 _3 (pshufd, Gx, Ex, Ib),
1013 _0f (modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12),
1014 _0f (modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13),
1015 _0f (modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14),
1016 _2 (pcmpeqb, Gx, Ex),
1017 _2 (pcmpeqw, Gx, Ex),
1018 _2 (pcmpeqd, Gx, Ex),
1019 _0 (bad),
1020 },
1021
1022 [X86_INSN_SSE_GROUP_78].insns = {
1023 _0 (bad),
1024 _0 (bad),
1025 _0 (bad),
1026 _0 (bad),
1027 _2 (haddpd, Gx, Ex),
1028 _2 (hsubpd, Gx, Ex),
1029 _2 (movd, Ev, Gx),
1030 _2 (movdqa, Ex, Gx),
1031 },
1032
1033 [X86_INSN_SSE_GROUP_c0].insns = {
1034 _0 (bad),
1035 _0 (bad),
1036 _3 (cmppd, Gx, Ex, Ib),
1037 _0 (bad),
1038 _3 (pinsrw, Gx, Ew, Ib),
1039 _3 (pextrw, Gd, Gx, Ib),
1040 _3 (shufpd, Gx, Ex, Ib),
1041 _0 (bad),
1042 },
1043
1044 [X86_INSN_SSE_GROUP_d0].insns = {
1045 _2 (addsubpd, Gx, Ex),
1046 _2 (psrlw, Gx, Ex),
1047 _2 (psrld, Gx, Ex),
1048 _2 (psrlq, Gx, Ex),
1049 _2 (paddq, Gx, Ex),
1050 _2 (pmullw, Gx, Ex),
1051 _2 (movq, Ex, Gx),
1052 _2 (pmovmskb, Gd, Rx),
1053 },
1054
1055 [X86_INSN_SSE_GROUP_d8].insns = {
1056 _2 (psubusb, Gx, Ex),
1057 _2 (psubusw, Gx, Ex),
1058 _2 (pminub, Gx, Ex),
1059 _2 (pand, Gx, Ex),
1060 _2 (paddusb, Gx, Ex),
1061 _2 (paddusw, Gx, Ex),
1062 _2 (pmaxub, Gx, Ex),
1063 _2 (pandn, Gx, Ex),
1064 },
1065
1066 [X86_INSN_SSE_GROUP_e0].insns = {
1067 _2 (pavgb, Gx, Ex),
1068 _2 (psraw, Gx, Ex),
1069 _2 (psrad, Gx, Ex),
1070 _2 (pavgw, Gx, Ex),
1071 _2 (pmulhuw, Gx, Ex),
1072 _2 (pmulhw, Gx, Ex),
1073 _2 (cvttpd2dq, Gx, Ex),
1074 _2 (movntdq, Mx, Gx),
1075 },
1076
1077 [X86_INSN_SSE_GROUP_e8].insns = {
1078 _2 (psubsb, Gx, Ex),
1079 _2 (psubsw, Gx, Ex),
1080 _2 (pminsw, Gx, Ex),
1081 _2 (por, Gx, Ex),
1082 _2 (paddsb, Gx, Ex),
1083 _2 (paddsw, Gx, Ex),
1084 _2 (pmaxsw, Gx, Ex),
1085 _2 (pxor, Gx, Ex),
1086 },
1087
1088 [X86_INSN_SSE_GROUP_f0].insns = {
1089 _0 (bad),
1090 _2 (psllw, Gx, Ex),
1091 _2 (pslld, Gx, Ex),
1092 _2 (psllq, Gx, Ex),
1093 _2 (pmuludq, Gx, Ex),
1094 _2 (pmaddwd, Gx, Ex),
1095 _2 (psadbw, Gx, Ex),
1096 _2 (maskmovdqu, Gx, Ex),
1097 },
1098
1099 [X86_INSN_SSE_GROUP_f8].insns = {
1100 _2 (psubb, Gx, Ex),
1101 _2 (psubw, Gx, Ex),
1102 _2 (psubd, Gx, Ex),
1103 _2 (psubq, Gx, Ex),
1104 _2 (paddb, Gx, Ex),
1105 _2 (paddw, Gx, Ex),
1106 _2 (paddd, Gx, Ex),
1107 _0 (bad),
1108 },
1109};
1110
1111static x86_insn_group8_t x86_insn_sse_groups_repnz[] = {
1112 [X86_INSN_SSE_GROUP_10].insns = {
1113 _2 (movsd, Gx, Ex),
1114 _2 (movsd, Ex, Gx),
1115 _2 (movddup, Gx, Ex),
1116 _0 (bad),
1117 _0 (bad),
1118 _0 (bad),
1119 _0 (bad),
1120 _0 (bad),
1121 },
1122
1123 [X86_INSN_SSE_GROUP_28].insns = {
1124 _0 (bad),
1125 _0 (bad),
1126 _2 (cvtsi2sd, Gx, Ev),
1127 _0 (bad),
1128 _2 (cvttsd2si, Gv, Ex),
1129 _2 (cvtsd2si, Gv, Ex),
1130 _0 (bad),
1131 _0 (bad),
1132 },
1133
1134 [X86_INSN_SSE_GROUP_50].insns = {
1135 _0 (bad),
1136 _2 (sqrtsd, Gx, Ex),
1137 _0 (bad),
1138 _0 (bad),
1139 _0 (bad),
1140 _0 (bad),
1141 _0 (bad),
1142 _0 (bad),
1143 },
1144
1145 [X86_INSN_SSE_GROUP_58].insns = {
1146 _2 (addsd, Gx, Ex),
1147 _2 (mulsd, Gx, Ex),
1148 _2 (cvtsd2ss, Gx, Ex),
1149 _0 (bad),
1150 _2 (subsd, Gx, Ex),
1151 _2 (minsd, Gx, Ex),
1152 _2 (divsd, Gx, Ex),
1153 _2 (maxsd, Gx, Ex),
1154 },
1155
1156 [X86_INSN_SSE_GROUP_60].insns = {
1157 _0 (bad),
1158 _0 (bad),
1159 _0 (bad),
1160 _0 (bad),
1161 _0 (bad),
1162 _0 (bad),
1163 _0 (bad),
1164 _0 (bad),
1165 },
1166
1167 [X86_INSN_SSE_GROUP_68].insns = {
1168 _0 (bad),
1169 _0 (bad),
1170 _0 (bad),
1171 _0 (bad),
1172 _0 (bad),
1173 _0 (bad),
1174 _0 (bad),
1175 _0 (bad),
1176 },
1177
1178 [X86_INSN_SSE_GROUP_70].insns = {
1179 _3 (pshuflw, Gx, Ex, Ib),
1180 _0 (bad),
1181 _0 (bad),
1182 _0 (bad),
1183 _0 (bad),
1184 _0 (bad),
1185 _0 (bad),
1186 _0 (bad),
1187 },
1188
1189 [X86_INSN_SSE_GROUP_78].insns = {
1190 _0 (bad),
1191 _0 (bad),
1192 _0 (bad),
1193 _0 (bad),
1194 _2 (haddps, Gx, Ex),
1195 _2 (hsubps, Gx, Ex),
1196 _0 (bad),
1197 _0 (bad),
1198 },
1199
1200 [X86_INSN_SSE_GROUP_c0].insns = {
1201 _0 (bad),
1202 _0 (bad),
1203 _3 (cmpsd, Gx, Ex, Ib),
1204 _0 (bad),
1205 _0 (bad),
1206 _0 (bad),
1207 _0 (bad),
1208 _0 (bad),
1209 },
1210
1211 [X86_INSN_SSE_GROUP_d0].insns = {
1212 _2 (addsubps, Gx, Ex),
1213 _0 (bad),
1214 _0 (bad),
1215 _0 (bad),
1216 _0 (bad),
1217 _0 (bad),
1218 _2 (movdq2q, Gm, Ex),
1219 _0 (bad),
1220 },
1221
1222 [X86_INSN_SSE_GROUP_d8].insns = {
1223 _0 (bad),
1224 _0 (bad),
1225 _0 (bad),
1226 _0 (bad),
1227 _0 (bad),
1228 _0 (bad),
1229 _0 (bad),
1230 _0 (bad),
1231 },
1232
1233 [X86_INSN_SSE_GROUP_e0].insns = {
1234 _0 (bad),
1235 _0 (bad),
1236 _0 (bad),
1237 _0 (bad),
1238 _0 (bad),
1239 _0 (bad),
1240 _2 (cvtpd2dq, Gx, Ex),
1241 _0 (bad),
1242 },
1243
1244 [X86_INSN_SSE_GROUP_e8].insns = {
1245 _0 (bad),
1246 _0 (bad),
1247 _0 (bad),
1248 _0 (bad),
1249 _0 (bad),
1250 _0 (bad),
1251 _0 (bad),
1252 _0 (bad),
1253 },
1254
1255 [X86_INSN_SSE_GROUP_f0].insns = {
1256 _2 (lddqu, Gx, Mx),
1257 _0 (bad),
1258 _0 (bad),
1259 _0 (bad),
1260 _0 (bad),
1261 _0 (bad),
1262 _0 (bad),
1263 _0 (bad),
1264 },
1265
1266 [X86_INSN_SSE_GROUP_f8].insns = {
1267 _0 (bad),
1268 _0 (bad),
1269 _0 (bad),
1270 _0 (bad),
1271 _0 (bad),
1272 _0 (bad),
1273 _0 (bad),
1274 _0 (bad),
1275 },
1276};
1277
1278#undef _
1279
1280/* Parses memory displacements and immediates. */
1281static u8 * x86_insn_parse_number (u32 log2_n_bytes,
1282 u8 * code, u8 * code_end,
1283 i64 * result)
1284{
1285 i64 x = 0;
1286
1287 if (code + (1 << log2_n_bytes) > code_end)
1288 return 0;
1289
1290 switch (log2_n_bytes)
1291 {
1292 case 3:
1293 x = clib_little_to_host_unaligned_mem_u64 ((u64 *) code);
1294 break;
1295
1296 case 2:
1297 x = (i32) clib_little_to_host_unaligned_mem_u32 ((u32 *) code);
1298 break;
1299
1300 case 1:
1301 x = (i16) clib_little_to_host_unaligned_mem_u16 ((u16 *) code);
1302 break;
1303
1304 case 0:
1305 x = (i8) code[0];
1306 break;
1307
1308 default:
1309 ASSERT (0);
1310 }
1311
1312 *result = x;
1313 return code + (1 << log2_n_bytes);
1314}
1315
1316static u32
1317x86_insn_log2_immediate_bytes (x86_insn_parse_t * p, x86_insn_t * insn)
1318{
1319 u32 i = ~0;
1320 switch (x86_insn_immediate_type (insn))
1321 {
1322 case 'b': i = 0; break;
1323 case 'w': i = 1; break;
1324 case 'd': i = 2; break;
1325 case 'q': i = 3; break;
1326
1327 case 'z':
1328 i = p->log2_effective_operand_bytes;
1329 if (i > 2) i = 2;
1330 break;
1331
1332 case 'v':
1333 i = p->log2_effective_operand_bytes;
1334 break;
1335
1336 default:
1337 i = ~0;
1338 break;
1339 }
1340
1341 return i;
1342}
1343
1344static u8 *
1345x86_insn_parse_modrm_byte (x86_insn_parse_t * x,
1346 x86_insn_modrm_byte_t modrm,
1347 u32 parse_flags,
1348 u8 * code,
1349 u8 * code_end)
1350{
1351 u8 effective_address_bits;
1352
1353 if (parse_flags & X86_INSN_PARSE_64_BIT)
1354 effective_address_bits = (x->flags & X86_INSN_ADDRESS_SIZE) ? 32 : 64;
1355 else if (parse_flags & X86_INSN_PARSE_32_BIT)
1356 effective_address_bits = (x->flags & X86_INSN_ADDRESS_SIZE) ? 16 : 32;
1357 else
1358 effective_address_bits = (x->flags & X86_INSN_ADDRESS_SIZE) ? 32 : 16;
1359
1360 x->log2_effective_address_bytes = 1;
1361 x->log2_effective_address_bytes += effective_address_bits > 16;
1362 x->log2_effective_address_bytes += effective_address_bits > 32;
1363
1364 x->regs[0] |= modrm.reg;
1365 if (modrm.mode == 3)
1366 x->regs[1] |= modrm.rm;
1367 else
1368 {
1369 u32 log2_disp_bytes = ~0;
1370
1371 x->flags |= X86_INSN_IS_ADDRESS;
1372
1373 if (effective_address_bits != 16)
1374 {
1375 u8 has_sib_byte = 0;
1376
1377 switch (modrm.mode)
1378 {
1379 case 0:
1380 /* When base is bp displacement is present for mode 0. */
1381 if (modrm.rm == X86_INSN_GP_REG_BP)
1382 {
1383 log2_disp_bytes = x->log2_effective_address_bytes;
1384 break;
1385 }
1386 else if (modrm.rm == X86_INSN_GP_REG_SP
1387 && effective_address_bits != 16)
1388 {
1389 has_sib_byte = 1;
1390 break;
1391 }
1392 /* fall through */
1393 case 1:
1394 case 2:
1395 x->regs[1] |= modrm.rm;
1396 x->flags |= X86_INSN_HAS_BASE;
1397 if (modrm.mode != 0)
1398 {
1399 log2_disp_bytes = (modrm.mode == 1
1400 ? 0
1401 : x->log2_effective_address_bytes);
1402 if (log2_disp_bytes > 2)
1403 log2_disp_bytes = 2;
1404 }
1405 break;
1406 }
1407
1408 if (has_sib_byte)
1409 {
1410 x86_insn_sib_byte_t sib;
1411
1412 if (code >= code_end)
1413 return 0;
1414 sib.byte = *code++;
1415
1416 x->log2_index_scale = 1 << sib.log2_scale;
1417 x->regs[1] |= sib.base;
1418 x->flags |= X86_INSN_HAS_BASE;
1419
1420 if (sib.index != X86_INSN_GP_REG_SP)
1421 {
1422 x->regs[2] |= sib.index;
1423 x->flags |= X86_INSN_HAS_INDEX;
1424 }
1425 }
1426 }
1427 else
1428 {
1429 /* effective_address_bits == 16 */
1430 switch (modrm.mode)
1431 {
1432 case 0:
1433 if (modrm.rm == 6)
1434 {
1435 /* [disp16] */
1436 log2_disp_bytes = 1;
1437 break;
1438 }
1439 /* fall through */
1440 case 1:
1441 case 2:
1442 switch (modrm.rm)
1443 {
1444 case 0: /* [bx + si/di] */
1445 case 1:
1446 x->regs[1] = X86_INSN_GP_REG_BX;
1447 x->regs[2] = X86_INSN_GP_REG_SI + (modrm.rm & 1);
1448 x->flags |= X86_INSN_HAS_BASE | X86_INSN_HAS_INDEX;
1449 break;
1450
1451 case 2: /* [bp + si/di] */
1452 case 3:
1453 x->regs[1] = X86_INSN_GP_REG_BP;
1454 x->regs[2] = X86_INSN_GP_REG_SI + (modrm.rm & 1);
1455 x->flags |= X86_INSN_HAS_BASE | X86_INSN_HAS_INDEX;
1456 break;
1457
1458 case 4: /* [si/di] */
1459 case 5:
1460 x->regs[1] = X86_INSN_GP_REG_SI + (modrm.rm & 1);
1461 x->flags |= X86_INSN_HAS_BASE;
1462 break;
1463
1464 case 6: /* [bp + disp] */
1465 x->regs[1] = X86_INSN_GP_REG_BP;
1466 x->flags |= X86_INSN_HAS_BASE;
1467 break;
1468
1469 case 7: /* [bx + disp] */
1470 x->regs[1] = X86_INSN_GP_REG_BX;
1471 x->flags |= X86_INSN_HAS_BASE;
1472 break;
1473 }
1474
1475 if (modrm.mode != 0)
1476 log2_disp_bytes = modrm.mode == 1 ? 0 : 1;
1477 break;
1478 }
1479 }
1480
1481 if (log2_disp_bytes != ~0)
1482 {
1483 i64 disp;
1484 code = x86_insn_parse_number (log2_disp_bytes, code, code_end,
1485 &disp);
1486 if (code)
1487 x->displacement = disp;
1488 }
1489 }
1490
1491 return code;
1492}
1493
1494u8 * x86_insn_parse (x86_insn_parse_t * p, u8 * code_start)
1495{
1496 u8 i, * code, * code_end;
1497 x86_insn_t * insn, * group_insn;
1498 u8 default_operand_bits, effective_operand_bits;
1499 u32 opcode, parse_flags;
1500
1501 /* Preserve global parse flags. */
1502 parse_flags = p->flags & (X86_INSN_PARSE_32_BIT | X86_INSN_PARSE_64_BIT);
1503 memset (p, 0, sizeof (p[0]));
1504 p->flags = parse_flags;
1505
1506 /* 64 implies 32 bit parsing. */
1507 if (parse_flags & X86_INSN_PARSE_64_BIT)
1508 parse_flags |= X86_INSN_PARSE_32_BIT;
1509
1510 /* Instruction must be <= 15 bytes. */
1511 code = code_start;
1512 code_end = code + 15;
1513
1514 /* Parse legacy prefixes. */
1515 while (1)
1516 {
1517 if (code >= code_end)
1518 goto insn_too_long;
1519 i = code[0];
1520 code++;
1521 switch (i)
1522 {
1523 default: goto prefix_done;
1524
1525 /* Set flags based on prefix. */
1526#define _(x,o) case o: p->flags |= X86_INSN_##x; break;
1527 foreach_x86_legacy_prefix;
1528#undef _
1529 }
1530 }
1531 prefix_done:
1532
1533 /* REX prefix. */
1534 if ((parse_flags & X86_INSN_PARSE_64_BIT) && i >= 0x40 && i <= 0x4f)
1535 {
1536 p->regs[0] |= ((i & (1 << 2)) != 0) << 3; /* r bit */
1537 p->regs[1] |= ((i & (1 << 0)) != 0) << 3; /* b bit */
1538 p->regs[2] |= ((i & (1 << 1)) != 0) << 3; /* x bit */
1539 p->flags |= ((i & (1 << 3)) /* w bit */
1540 ? X86_INSN_OPERAND_SIZE_64 : 0);
1541 if (code >= code_end)
1542 goto insn_too_long;
1543 i = *code++;
1544 }
1545
1546 opcode = i;
1547 if (opcode == 0x0f)
1548 {
1549 /* two byte opcode. */;
1550 if (code >= code_end)
1551 goto insn_too_long;
1552 i = *code++;
1553 opcode = (opcode << 8) | i;
1554 insn = x86_insns_two_byte + i;
1555 }
1556 else
1557 {
1558 static x86_insn_t arpl = {
1559 .name = "arpl",
1560 .operands[0].data = "Ew",
1561 .operands[1].data = "Gw",
1562 };
1563
1564 if (PREDICT_FALSE (i == 0x63
1565 && ! (parse_flags & X86_INSN_PARSE_64_BIT)))
1566 insn = &arpl;
1567 else
1568 insn = x86_insns_one_byte + i;
1569 }
1570
1571 if ((i = X86_INSN_FLAG_GET_SSE_GROUP (insn->flags)) != 0)
1572 {
1573 x86_insn_group8_t * g8;
1574
1575 if (p->flags & X86_INSN_OPERAND_SIZE)
1576 g8 = x86_insn_sse_groups_operand_size;
1577 else if (p->flags & X86_INSN_REPZ)
1578 g8 = x86_insn_sse_groups_repz;
1579 else if (p->flags & X86_INSN_REPNZ)
1580 g8 = x86_insn_sse_groups_repnz;
1581 else
1582 g8 = 0;
1583
1584 /* insn flags have 1 + group so != 0 test above can work. */
1585 ASSERT ((i - 1) < ARRAY_LEN (x86_insn_sse_groups_operand_size));
1586 if (g8)
1587 insn = g8[i - 1].insns + (opcode & 7);
1588 }
1589
1590 /* Parse modrm and displacement if present. */
1591 if (x86_insn_has_modrm_byte (insn))
1592 {
1593 x86_insn_modrm_byte_t modrm;
1594
1595 if (code >= code_end)
1596 goto insn_too_long;
1597 modrm.byte = *code++;
1598
1599 /* Handle special 0x0f01 and 0x0fae encodings. */
1600 if (PREDICT_FALSE (modrm.mode == 3
1601 && (opcode == 0x0f01
1602 || opcode == 0x0fae)))
1603 {
1604 static x86_insn_t x86_insns_0f01_special[] = {
1605 _0 (swapgs), _0 (rdtscp), _0 (bad), _0 (bad),
1606 _0 (bad), _0 (bad), _0 (bad), _0 (bad),
1607 };
1608 static x86_insn_t x86_insns_0fae_special[] = {
1609 _0 (vmrun), _0 (vmmcall), _0 (vmload), _0 (vmsave),
1610 _0 (stgi), _0 (clgi), _0 (skinit), _0 (invlpga),
1611 };
1612
1613 if (opcode == 0x0f01)
1614 insn = x86_insns_0f01_special;
1615 else
1616 insn = x86_insns_0fae_special;
1617 insn += modrm.rm;
1618 opcode = (opcode << 8) | modrm.byte;
1619 }
1620 else
1621 {
1622 code = x86_insn_parse_modrm_byte (p, modrm, parse_flags,
1623 code, code_end);
1624 if (! code)
1625 goto insn_too_long;
1626 }
1627 }
1628
1629 group_insn = 0;
1630 if ((i = X86_INSN_FLAG_GET_MODRM_REG_GROUP (insn->flags)) != 0)
1631 {
1632 u32 g = i - 1;
1633 ASSERT (g < ARRAY_LEN (x86_insn_modrm_reg_groups));
1634 group_insn = x86_insn_modrm_reg_groups[g].insns + (p->regs[0] & 7);
1635 }
1636
1637 p->insn = insn[0];
1638 if (group_insn)
1639 {
1640 u32 k;
1641 p->insn.name = group_insn->name;
1642 p->insn.flags |= group_insn->flags;
1643 for (k = 0; k < ARRAY_LEN (group_insn->operands); k++)
1644 if (x86_insn_operand_is_valid (group_insn, k))
1645 p->insn.operands[k] = group_insn->operands[k];
1646 }
1647
1648 default_operand_bits
1649 = ((((parse_flags & X86_INSN_PARSE_32_BIT) != 0)
1650 ^ ((p->flags & X86_INSN_OPERAND_SIZE) != 0))
1651 ? BITS (u32) : BITS (u16));
1652
1653 if ((parse_flags & X86_INSN_PARSE_64_BIT)
1654 && (p->insn.flags & X86_INSN_FLAG_DEFAULT_64_BIT))
1655 default_operand_bits = BITS (u64);
1656
1657 effective_operand_bits = default_operand_bits;
1658 if (p->flags & X86_INSN_OPERAND_SIZE_64)
1659 effective_operand_bits = BITS (u64);
1660
1661 p->log2_effective_operand_bytes = 1;
1662 p->log2_effective_operand_bytes += effective_operand_bits > 16;
1663 p->log2_effective_operand_bytes += effective_operand_bits > 32;
1664
1665 /* Parse immediate if present. */
1666 {
1667 u32 l = x86_insn_log2_immediate_bytes (p, insn);
1668 if (l <= 3)
1669 {
1670 code = x86_insn_parse_number (l, code, code_end, &p->immediate);
1671 if (! code)
1672 goto insn_too_long;
1673 }
1674 }
1675
1676 return code;
1677
1678 insn_too_long:
1679 return 0;
1680}
1681
1682static u8 * format_x86_gp_reg_operand (u8 * s, va_list * va)
1683{
1684 u32 r = va_arg (*va, u32);
1685 u32 log2_n_bytes = va_arg (*va, u32);
1686
1687 const char names8[8] = "acdbsbsd";
1688 const char names16[8] = "xxxxppii";
1689
1690 ASSERT (r < 16);
1691
1692 /* Add % register prefix. */
1693 vec_add1 (s, '%');
1694
1695 switch (log2_n_bytes)
1696 {
1697 case 0:
1698 {
1699
1700 if (r < 8)
1701 s = format (s, "%c%c", names8[r & 3], (r >> 2) ? 'l' : 'h');
1702 else
1703 s = format (s, "r%db", r);
1704 }
1705 break;
1706
1707 case 2:
1708 case 3:
1709 s = format (s, "%c", log2_n_bytes == 2 ? 'e' : 'r');
1710 /* fall through */
1711 case 1:
1712 if (r < 8)
1713 s = format (s, "%c%c", names8[r], names16[r]);
1714 else
1715 {
1716 s = format (s, "%d", r);
1717 if (log2_n_bytes != 3)
1718 s = format (s, "%c", log2_n_bytes == 1 ? 'w' : 'd');
1719 }
1720 break;
1721
1722 default:
1723 ASSERT (0);
1724 }
1725
1726 return s;
1727}
1728
1729static u8 * format_x86_reg_operand (u8 * s, va_list * va)
1730{
1731 u32 reg = va_arg (*va, u32);
1732 u32 log2_n_bytes = va_arg (*va, u32);
1733 u32 type = va_arg (*va, u32);
1734
1735 switch (type)
1736 {
1737 default:
1738 ASSERT (0);
Dave Barachf9c231e2016-08-05 10:10:18 -04001739 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001740
1741 case 'x':
1742 ASSERT (reg < 16);
1743 return format (s, "%%xmm%d", reg);
1744
1745 case 'm':
1746 ASSERT (reg < 8);
1747 return format (s, "%%mm%d", reg);
1748
1749 /* Explicit byte/word/double-word/quad-word */
1750 case 'b': log2_n_bytes = 0; break;
1751 case 'w': log2_n_bytes = 1; break;
1752 case 'd': log2_n_bytes = 2; break;
1753 case 'q': log2_n_bytes = 3; break;
1754
1755 /* Use effective operand size. */
1756 case 'v': break;
1757
1758 /* word or double-word depending on effective operand size. */
1759 case 'z':
1760 log2_n_bytes = clib_min (log2_n_bytes, 2);
1761 break;
1762 }
1763
1764 s = format (s, "%U", format_x86_gp_reg_operand, reg, log2_n_bytes);
1765 return s;
1766}
1767
1768static u8 * format_x86_mem_operand (u8 * s, va_list * va)
1769{
1770 x86_insn_parse_t * p = va_arg (*va, x86_insn_parse_t *);
1771
1772 if (p->displacement != 0)
1773 s = format (s, "0x%x", p->displacement);
1774
1775 if (p->flags & X86_INSN_HAS_BASE)
1776 {
1777 s = format (s, "(%U",
1778 format_x86_gp_reg_operand, p->regs[1],
1779 p->log2_effective_address_bytes);
1780 if (p->flags & X86_INSN_HAS_INDEX)
1781 {
1782 s = format (s, ",%U",
1783 format_x86_gp_reg_operand, p->regs[2],
1784 p->log2_effective_address_bytes);
1785 if (p->log2_index_scale != 0)
1786 s = format (s, ",%d", 1 << p->log2_index_scale);
1787 }
1788 s = format (s, ")");
1789 }
1790
1791 /* [RIP+disp] PC relative addressing in 64 bit mode. */
1792 else if (p->flags & X86_INSN_PARSE_64_BIT)
1793 s = format (s, "(%%rip)");
1794
1795 return s;
1796}
1797
1798static u8 * format_x86_insn_operand (u8 * s, va_list * va)
1799{
1800 x86_insn_parse_t * p = va_arg (*va, x86_insn_parse_t *);
1801 x86_insn_t * insn = &p->insn;
1802 u32 o = va_arg (*va, u32);
1803 u8 c, t;
1804
1805 ASSERT (o < ARRAY_LEN (insn->operands));
1806 c = insn->operands[o].code;
1807 t = insn->operands[o].type;
1808
1809 /* Register encoded in instruction. */
1810 if (c < 8)
1811 return format (s, "%U",
1812 format_x86_gp_reg_operand, c,
1813 p->log2_effective_operand_bytes);
1814
1815 switch (c)
1816 {
1817 /* Memory or reg field from modrm byte. */
1818 case 'M':
1819 ASSERT (p->flags & X86_INSN_IS_ADDRESS);
Dave Barachf9c231e2016-08-05 10:10:18 -04001820 /* FALLTHROUGH */
Ed Warnickecb9cada2015-12-08 15:45:58 -07001821 case 'E':
1822 if (p->flags & X86_INSN_IS_ADDRESS)
1823 s = format (s, "%U", format_x86_mem_operand, p);
1824 else
1825 s = format (s, "%U",
1826 format_x86_reg_operand, p->regs[1],
1827 p->log2_effective_operand_bytes, t);
1828 break;
1829
1830 /* reg field from modrm byte. */
1831 case 'R':
1832 case 'G':
1833 s = format (s, "%U",
1834 format_x86_reg_operand, p->regs[0],
1835 p->log2_effective_operand_bytes, t);
1836 break;
1837
1838 case 'I':
1839 {
1840 u32 l = x86_insn_log2_immediate_bytes (p, insn);
Dave Barachf9c231e2016-08-05 10:10:18 -04001841 i64 mask = pow2_mask (8ULL << l);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001842 s = format (s, "$0x%Lx", p->immediate & mask);
1843 }
1844 break;
1845
1846 case 'J':
1847 if (p->immediate < 0)
1848 s = format (s, "- 0x%Lx", -p->immediate);
1849 else
1850 s = format (s, "+ 0x%Lx", p->immediate);
1851 break;
1852
1853 case 'O':
1854 s = format (s, "0x%Lx", p->immediate);
1855 break;
1856
1857 case 'A':
1858 /* AX/AL */
1859 s = format (s, "%U",
1860 format_x86_gp_reg_operand, X86_INSN_GP_REG_AX,
1861 t == 'L' ? 0 : p->log2_effective_operand_bytes);
1862 break;
1863
1864 case 'B':
1865 /* BX/BL/BP */
1866 s = format (s, "%U",
1867 format_x86_gp_reg_operand,
1868 t == 'P' ? X86_INSN_GP_REG_BP : X86_INSN_GP_REG_BX,
1869 t == 'L' ? 0 : p->log2_effective_operand_bytes);
1870 break;
1871
1872 case 'C':
1873 /* CX/CL */
1874 s = format (s, "%U",
1875 format_x86_gp_reg_operand, X86_INSN_GP_REG_CX,
1876 t == 'L' ? 0 : p->log2_effective_operand_bytes);
1877 break;
1878
1879 case 'D':
1880 /* DX/DL/DI */
1881 s = format (s, "%U",
1882 format_x86_gp_reg_operand,
1883 t == 'I' ? X86_INSN_GP_REG_DI : X86_INSN_GP_REG_DX,
1884 t == 'L' ? 0 : p->log2_effective_operand_bytes);
1885 break;
1886
1887 case 'S':
1888 /* SI/SP */
1889 s = format (s, "%U",
1890 format_x86_gp_reg_operand,
1891 t == 'I' ? X86_INSN_GP_REG_SI : X86_INSN_GP_REG_SP,
1892 p->log2_effective_operand_bytes);
1893 break;
1894
1895 case '1':
1896 s = format (s, "1");
1897 break;
1898
1899 default:
1900 ASSERT (0);
1901 }
1902
1903 return s;
1904}
1905
1906u8 * format_x86_insn_parse (u8 * s, va_list * va)
1907{
1908 x86_insn_parse_t * p = va_arg (*va, x86_insn_parse_t *);
1909 x86_insn_t * insn = &p->insn;
1910 u32 o, i, is_src_dst;
1911
1912 s = format (s, "%s", insn->name);
1913
1914 if (! x86_insn_operand_is_valid (insn, 0))
1915 goto done;
1916
1917 is_src_dst = x86_insn_operand_is_valid (insn, 1);
1918
1919 /* If instruction has immediate add suffix to opcode to
1920 indicate operand size. */
1921 if (is_src_dst)
1922 {
1923 u32 b;
1924
1925 b = x86_insn_log2_immediate_bytes (p, insn);
1926 if (b < p->log2_effective_operand_bytes
1927 && (p->flags & X86_INSN_IS_ADDRESS))
1928 s = format (s, "%c", "bwlq"[b]);
1929 }
1930
1931 for (i = 0; i < ARRAY_LEN (insn->operands); i++)
1932 {
1933 o = is_src_dst + i;
1934 if (! x86_insn_operand_is_valid (insn, o))
1935 break;
1936 s = format (s, "%s%U",
1937 i == 0 ? " " : ", ",
1938 format_x86_insn_operand, p, o);
1939 }
1940
1941 if (is_src_dst)
1942 s = format (s, ", %U",
1943 format_x86_insn_operand, p, 0);
1944
1945 done:
1946 return s;
1947}