FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
asm_x86.c
Go to the documentation of this file.
1 /*
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 
30 typedef enum {
31 #define _(r) X86_INSN_GP_REG_##r,
33 #undef _
35 
36 typedef union {
37  struct {
38  u8 rm : 3;
39  u8 reg : 3;
40  u8 mode : 2;
41  };
44 
45 typedef union {
46  struct {
47  u8 base : 3;
48  u8 index : 3;
50  };
53 
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 
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 
92 enum {
93 #define _(x) X86_INSN_MODRM_REG_GROUP_##x,
95 #undef _
96 #define _(x) X86_INSN_SSE_GROUP_##x,
98 #undef _
99 };
100 
101 enum {
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),
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),
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 
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),
190 #undef _
191 #define _(r) _1 (dec, r),
193 #undef _
194 
195  /* 0x50 */
196 #define _(r) _1f (push, X86_INSN_FLAG_DEFAULT_64_BIT, r),
198 #undef _
199 #define _(r) _1f (pop, X86_INSN_FLAG_DEFAULT_64_BIT, r),
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),
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),
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 
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),
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),
502 #undef _
503 
504  /* 0x90 */
505 #define _(x) _1 (set##x, Eb),
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),
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 
613 typedef struct {
614  x86_insn_t insns[8];
616 
617 /* Escape groups are indexed by modrm reg field. */
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 
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 
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 
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. */
1281 static 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 
1316 static u32
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':
1329  if (i > 2) i = 2;
1330  break;
1331 
1332  case 'v':
1334  break;
1335 
1336  default:
1337  i = ~0;
1338  break;
1339  }
1340 
1341  return i;
1342 }
1343 
1344 static u8 *
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 
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
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 
1494 u8 * 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  clib_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;
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)
1577  else if (p->flags & X86_INSN_REPZ)
1579  else if (p->flags & X86_INSN_REPNZ)
1581  else
1582  g8 = 0;
1583 
1584  /* insn flags have 1 + group so != 0 test above can work. */
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;
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)
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 
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 
1682 static 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 
1729 static 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);
1739  break;
1740 
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 
1768 static 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",
1780  if (p->flags & X86_INSN_HAS_INDEX)
1781  {
1782  s = format (s, ",%U",
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 
1798 static 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",
1814 
1815  switch (c)
1816  {
1817  /* Memory or reg field from modrm byte. */
1818  case 'M':
1819  ASSERT (p->flags & X86_INSN_IS_ADDRESS);
1820  /* FALLTHROUGH */
1821  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",
1828  break;
1829 
1830  /* reg field from modrm byte. */
1831  case 'R':
1832  case 'G':
1833  s = format (s, "%U",
1836  break;
1837 
1838  case 'I':
1839  {
1840  u32 l = x86_insn_log2_immediate_bytes (p, insn);
1841  i64 mask = pow2_mask (8ULL << l);
1842  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",
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",
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",
1891  t == 'I' ? X86_INSN_GP_REG_SI : X86_INSN_GP_REG_SP,
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 
1906 u8 * 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 }
x86_insn_parse_t::insn
x86_insn_t insn
Definition: asm_x86.h:111
foreach_x86_insn_modrm_reg_group
#define foreach_x86_insn_modrm_reg_group
Definition: asm_x86.c:83
x86_insn_parse_t::log2_effective_address_bytes
u8 log2_effective_address_bytes
Definition: asm_x86.h:102
foreach_x86_insn_sse_group
#define foreach_x86_insn_sse_group
Definition: asm_x86.c:88
X86_INSN_FLAG_GET_SSE_GROUP
#define X86_INSN_FLAG_GET_SSE_GROUP(f)
Definition: asm_x86.h:41
format_x86_reg_operand
static u8 * format_x86_reg_operand(u8 *s, va_list *va)
Definition: asm_x86.c:1729
x86_insn_parse_t::flags
u32 flags
Definition: asm_x86.h:107
asm_x86.h
pow2_mask
static uword pow2_mask(uword x)
Definition: clib.h:252
x86_insn_sib_byte_t::base
u8 base
Definition: asm_x86.c:47
x86_insn_log2_immediate_bytes
static u32 x86_insn_log2_immediate_bytes(x86_insn_parse_t *p, x86_insn_t *insn)
Definition: asm_x86.c:1317
format_x86_insn_parse
u8 * format_x86_insn_parse(u8 *s, va_list *va)
Definition: asm_x86.c:1906
x86_insn_has_modrm_byte
static uword x86_insn_has_modrm_byte(x86_insn_t *insn)
Definition: asm_x86.c:55
x86_insn_modrm_byte_t::byte
u8 byte
Definition: asm_x86.c:42
u16
unsigned short u16
Definition: types.h:57
x86_insn_group8_t
Definition: asm_x86.c:613
x86_insn_modrm_byte_t::mode
u8 mode
Definition: asm_x86.c:40
byte_order.h
x86_insn_operand_is_valid
static uword x86_insn_operand_is_valid(x86_insn_t *i, uword o)
Definition: asm_x86.h:47
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
i64
signed long i64
Definition: types.h:78
i32
signed int i32
Definition: types.h:77
x86_insn_immediate_type
static uword x86_insn_immediate_type(x86_insn_t *insn)
Definition: asm_x86.c:68
x86_insn_sib_byte_t
Definition: asm_x86.c:45
x86_insn_parse_t::log2_effective_operand_bytes
u8 log2_effective_operand_bytes
Definition: asm_x86.h:101
x86_insn_sib_byte_t::byte
u8 byte
Definition: asm_x86.c:51
i16
signed short i16
Definition: types.h:46
x86_insn_parse_t::immediate
i64 immediate
Definition: asm_x86.h:109
error.h
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
BITS
#define BITS(x)
Definition: clib.h:69
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
uword
u64 uword
Definition: types.h:112
x86_insn_modrm_byte_t::reg
u8 reg
Definition: asm_x86.c:39
x86_insn_operand_t::type
u8 type
Definition: asm_x86.h:25
foreach_x86_condition
#define foreach_x86_condition
Definition: asm_x86.c:119
x86_insn_parse
u8 * x86_insn_parse(x86_insn_parse_t *p, u8 *code_start)
Definition: asm_x86.c:1494
x86_insn_group8_t::insns
x86_insn_t insns[8]
Definition: asm_x86.c:614
mask
vl_api_pnat_mask_t mask
Definition: pnat.api:45
format_x86_gp_reg_operand
static u8 * format_x86_gp_reg_operand(u8 *s, va_list *va)
Definition: asm_x86.c:1682
clib_min
#define clib_min(x, y)
Definition: clib.h:342
X86_INSN_FLAG_GET_MODRM_REG_GROUP
#define X86_INSN_FLAG_GET_MODRM_REG_GROUP(f)
Definition: asm_x86.h:43
format_x86_mem_operand
static u8 * format_x86_mem_operand(u8 *s, va_list *va)
Definition: asm_x86.c:1768
x86_insn_sse_groups_repnz
static x86_insn_group8_t x86_insn_sse_groups_repnz[]
Definition: asm_x86.c:1111
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
foreach_x86_gp_reg
#define foreach_x86_gp_reg
Definition: asm_x86.c:115
u64
unsigned long u64
Definition: types.h:89
i8
signed char i8
Definition: types.h:45
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
x86_insn_t::name
char * name
Definition: asm_x86.h:33
foreach_x86_legacy_prefix
@ foreach_x86_legacy_prefix
Definition: asm_x86.h:80
u32
unsigned int u32
Definition: types.h:88
format_x86_insn_operand
static u8 * format_x86_insn_operand(u8 *s, va_list *va)
Definition: asm_x86.c:1798
x86_insn_parse_t::regs
u8 regs[3]
Definition: asm_x86.h:97
x86_insn_operand_t::code
u8 code
Definition: asm_x86.h:24
x86_insn_parse_t::log2_index_scale
u8 log2_index_scale
Definition: asm_x86.h:100
x86_insn_parse_t
Definition: asm_x86.h:91
x86_insn_sse_groups_repz
static x86_insn_group8_t x86_insn_sse_groups_repz[]
Definition: asm_x86.c:777
x86_insn_t::flags
u16 flags
Definition: asm_x86.h:38
x86_insn_parse_t::displacement
i32 displacement
Definition: asm_x86.h:104
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
X86_INSN_FLAG_DEFAULT_64_BIT
#define X86_INSN_FLAG_DEFAULT_64_BIT
Definition: asm_x86.h:39
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
x86_insn_t
Definition: asm_x86.h:30
i
int i
Definition: flowhash_template.h:376
x86_insn_gp_register_t
x86_insn_gp_register_t
Definition: asm_x86.c:30
x86_insn_parse_number
static u8 * x86_insn_parse_number(u32 log2_n_bytes, u8 *code, u8 *code_end, i64 *result)
Definition: asm_x86.c:1281
x86_insn_sib_byte_t::index
u8 index
Definition: asm_x86.c:48
x86_insn_modrm_byte_t
Definition: asm_x86.c:36
x86_insn_sib_byte_t::log2_scale
u8 log2_scale
Definition: asm_x86.c:49
x86_insn_modrm_reg_groups
static x86_insn_group8_t x86_insn_modrm_reg_groups[]
Definition: asm_x86.c:618
x86_insns_two_byte
static x86_insn_t x86_insns_two_byte[256]
Definition: asm_x86.c:367
x86_insn_t::operands
x86_insn_operand_t operands[3]
Definition: asm_x86.h:36
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
foreach_x86_gp_register
#define foreach_x86_gp_register
Definition: asm_x86.c:26
x86_insns_one_byte
static x86_insn_t x86_insns_one_byte[256]
Definition: asm_x86.c:143
x86_insn_modrm_byte_t::rm
u8 rm
Definition: asm_x86.c:38
x86_insn_parse_modrm_byte
static u8 * x86_insn_parse_modrm_byte(x86_insn_parse_t *x, x86_insn_modrm_byte_t modrm, u32 parse_flags, u8 *code, u8 *code_end)
Definition: asm_x86.c:1345
x86_insn_sse_groups_operand_size
static x86_insn_group8_t x86_insn_sse_groups_operand_size[]
Definition: asm_x86.c:944