1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include "qemu/osdep.h"
35#include "disas/bfd.h"
36#include "qemu/cutils.h"
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#ifndef SYSV386_COMPAT
77
78
79
80#define SYSV386_COMPAT 1
81#endif
82#ifndef OLDGCC_COMPAT
83
84
85
86#define OLDGCC_COMPAT SYSV386_COMPAT
87#endif
88
89#define MOV_AX_DISP32 0xa0
90#define POP_SEG_SHORT 0x07
91#define JUMP_PC_RELATIVE 0xeb
92#define INT_OPCODE 0xcd
93#define INT3_OPCODE 0xcc
94
95
96#define FWAIT_OPCODE 0x9b
97#define ADDR_PREFIX_OPCODE 0x67
98#define DATA_PREFIX_OPCODE 0x66
99#define LOCK_PREFIX_OPCODE 0xf0
100#define CS_PREFIX_OPCODE 0x2e
101#define DS_PREFIX_OPCODE 0x3e
102#define ES_PREFIX_OPCODE 0x26
103#define FS_PREFIX_OPCODE 0x64
104#define GS_PREFIX_OPCODE 0x65
105#define SS_PREFIX_OPCODE 0x36
106#define REPNE_PREFIX_OPCODE 0xf2
107#define REPE_PREFIX_OPCODE 0xf3
108
109#define TWO_BYTE_OPCODE_ESCAPE 0x0f
110#define NOP_OPCODE (char) 0x90
111
112
113#define EBP_REG_NUM 5
114#define ESP_REG_NUM 4
115
116
117#define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
118
119#define NO_INDEX_REGISTER ESP_REG_NUM
120
121#define NO_BASE_REGISTER EBP_REG_NUM
122#define NO_BASE_REGISTER_16 6
123
124
125#define REGMEM_FIELD_HAS_REG 0x3
126#define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
127
128
129#define REX_OPCODE 0x40
130
131
132#define REX_W 8
133
134#define REX_R 4
135
136#define REX_X 2
137
138#define REX_B 1
139
140
141#define MAX_OPERANDS 4
142
143
144#define MAX_IMMEDIATE_OPERANDS 2
145
146
147#define MAX_MEMORY_OPERANDS 2
148
149
150#define MAX_MNEM_SIZE 16
151
152
153#define MAX_REG_NAME_SIZE 8
154
155
156#include "qemu-common.h"
157
158static int fetch_data2(struct disassemble_info *, bfd_byte *);
159static int fetch_data(struct disassemble_info *, bfd_byte *);
160static void ckprefix (void);
161static const char *prefix_name (int, int);
162static int print_insn (bfd_vma, disassemble_info *);
163static void dofloat (int);
164static void OP_ST (int, int);
165static void OP_STi (int, int);
166static int putop (const char *, int);
167static void oappend (const char *);
168static void append_seg (void);
169static void OP_indirE (int, int);
170static void print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp);
171static void print_displacement (char *, bfd_vma);
172static void OP_E (int, int);
173static void OP_G (int, int);
174static void OP_vvvv (int, int);
175static bfd_vma get64 (void);
176static bfd_signed_vma get32 (void);
177static bfd_signed_vma get32s (void);
178static int get16 (void);
179static void set_op (bfd_vma, int);
180static void OP_REG (int, int);
181static void OP_IMREG (int, int);
182static void OP_I (int, int);
183static void OP_I64 (int, int);
184static void OP_sI (int, int);
185static void OP_J (int, int);
186static void OP_SEG (int, int);
187static void OP_DIR (int, int);
188static void OP_OFF (int, int);
189static void OP_OFF64 (int, int);
190static void ptr_reg (int, int);
191static void OP_ESreg (int, int);
192static void OP_DSreg (int, int);
193static void OP_C (int, int);
194static void OP_D (int, int);
195static void OP_T (int, int);
196static void OP_R (int, int);
197static void OP_MMX (int, int);
198static void OP_XMM (int, int);
199static void OP_EM (int, int);
200static void OP_EX (int, int);
201static void OP_EMC (int,int);
202static void OP_MXC (int,int);
203static void OP_MS (int, int);
204static void OP_XS (int, int);
205static void OP_M (int, int);
206static void OP_VMX (int, int);
207static void OP_0fae (int, int);
208static void OP_0f07 (int, int);
209static void NOP_Fixup1 (int, int);
210static void NOP_Fixup2 (int, int);
211static void OP_3DNowSuffix (int, int);
212static void OP_SIMD_Suffix (int, int);
213static void SIMD_Fixup (int, int);
214static void PNI_Fixup (int, int);
215static void SVME_Fixup (int, int);
216static void INVLPG_Fixup (int, int);
217static void BadOp (void);
218static void VMX_Fixup (int, int);
219static void REP_Fixup (int, int);
220static void CMPXCHG8B_Fixup (int, int);
221static void XMM_Fixup (int, int);
222static void CRC32_Fixup (int, int);
223
224struct dis_private {
225
226 bfd_byte *max_fetched;
227 bfd_byte the_buffer[MAX_MNEM_SIZE];
228 bfd_vma insn_start;
229 int orig_sizeflag;
230 sigjmp_buf bailout;
231};
232
233enum address_mode
234{
235 mode_16bit,
236 mode_32bit,
237 mode_64bit
238};
239
240static enum address_mode address_mode;
241
242
243static int prefixes;
244
245
246static int rex;
247
248static int rex_used;
249
250
251
252
253#define USED_REX(value) \
254 { \
255 if (value) \
256 { \
257 if ((rex & value)) \
258 rex_used |= (value) | REX_OPCODE; \
259 } \
260 else \
261 rex_used |= REX_OPCODE; \
262 }
263
264
265
266static int used_prefixes;
267
268
269static int vex_reg;
270
271
272#define PREFIX_REPZ 1
273#define PREFIX_REPNZ 2
274#define PREFIX_LOCK 4
275#define PREFIX_CS 8
276#define PREFIX_SS 0x10
277#define PREFIX_DS 0x20
278#define PREFIX_ES 0x40
279#define PREFIX_FS 0x80
280#define PREFIX_GS 0x100
281#define PREFIX_DATA 0x200
282#define PREFIX_ADDR 0x400
283#define PREFIX_FWAIT 0x800
284
285#define PREFIX_VEX_0F 0x1000
286#define PREFIX_VEX_0F38 0x2000
287#define PREFIX_VEX_0F3A 0x4000
288
289
290
291
292static int
293fetch_data2(struct disassemble_info *info, bfd_byte *addr)
294{
295 int status;
296 struct dis_private *priv = (struct dis_private *) info->private_data;
297 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
298
299 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
300 status = (*info->read_memory_func) (start,
301 priv->max_fetched,
302 addr - priv->max_fetched,
303 info);
304 else
305 status = -1;
306 if (status != 0)
307 {
308
309
310
311
312 if (priv->max_fetched == priv->the_buffer)
313 (*info->memory_error_func) (status, start, info);
314 siglongjmp(priv->bailout, 1);
315 }
316 else
317 priv->max_fetched = addr;
318 return 1;
319}
320
321static int
322fetch_data(struct disassemble_info *info, bfd_byte *addr)
323{
324 if (addr <= ((struct dis_private *) (info->private_data))->max_fetched) {
325 return 1;
326 } else {
327 return fetch_data2(info, addr);
328 }
329}
330
331
332#define XX { NULL, 0 }
333
334#define Bv { OP_vvvv, v_mode }
335#define Eb { OP_E, b_mode }
336#define Ev { OP_E, v_mode }
337#define Ed { OP_E, d_mode }
338#define Edq { OP_E, dq_mode }
339#define Edqw { OP_E, dqw_mode }
340#define Edqb { OP_E, dqb_mode }
341#define Edqd { OP_E, dqd_mode }
342#define indirEv { OP_indirE, stack_v_mode }
343#define indirEp { OP_indirE, f_mode }
344#define stackEv { OP_E, stack_v_mode }
345#define Em { OP_E, m_mode }
346#define Ew { OP_E, w_mode }
347#define M { OP_M, 0 }
348#define Ma { OP_M, v_mode }
349#define Mp { OP_M, f_mode }
350#define Mq { OP_M, q_mode }
351#define Gb { OP_G, b_mode }
352#define Gv { OP_G, v_mode }
353#define Gd { OP_G, d_mode }
354#define Gdq { OP_G, dq_mode }
355#define Gm { OP_G, m_mode }
356#define Gw { OP_G, w_mode }
357#define Rd { OP_R, d_mode }
358#define Rm { OP_R, m_mode }
359#define Ib { OP_I, b_mode }
360#define sIb { OP_sI, b_mode }
361#define Iv { OP_I, v_mode }
362#define Iq { OP_I, q_mode }
363#define Iv64 { OP_I64, v_mode }
364#define Iw { OP_I, w_mode }
365#define I1 { OP_I, const_1_mode }
366#define Jb { OP_J, b_mode }
367#define Jv { OP_J, v_mode }
368#define Cm { OP_C, m_mode }
369#define Dm { OP_D, m_mode }
370#define Td { OP_T, d_mode }
371
372#define RMeAX { OP_REG, eAX_reg }
373#define RMeBX { OP_REG, eBX_reg }
374#define RMeCX { OP_REG, eCX_reg }
375#define RMeDX { OP_REG, eDX_reg }
376#define RMeSP { OP_REG, eSP_reg }
377#define RMeBP { OP_REG, eBP_reg }
378#define RMeSI { OP_REG, eSI_reg }
379#define RMeDI { OP_REG, eDI_reg }
380#define RMrAX { OP_REG, rAX_reg }
381#define RMrBX { OP_REG, rBX_reg }
382#define RMrCX { OP_REG, rCX_reg }
383#define RMrDX { OP_REG, rDX_reg }
384#define RMrSP { OP_REG, rSP_reg }
385#define RMrBP { OP_REG, rBP_reg }
386#define RMrSI { OP_REG, rSI_reg }
387#define RMrDI { OP_REG, rDI_reg }
388#define RMAL { OP_REG, al_reg }
389#define RMAL { OP_REG, al_reg }
390#define RMCL { OP_REG, cl_reg }
391#define RMDL { OP_REG, dl_reg }
392#define RMBL { OP_REG, bl_reg }
393#define RMAH { OP_REG, ah_reg }
394#define RMCH { OP_REG, ch_reg }
395#define RMDH { OP_REG, dh_reg }
396#define RMBH { OP_REG, bh_reg }
397#define RMAX { OP_REG, ax_reg }
398#define RMDX { OP_REG, dx_reg }
399
400#define eAX { OP_IMREG, eAX_reg }
401#define eBX { OP_IMREG, eBX_reg }
402#define eCX { OP_IMREG, eCX_reg }
403#define eDX { OP_IMREG, eDX_reg }
404#define eSP { OP_IMREG, eSP_reg }
405#define eBP { OP_IMREG, eBP_reg }
406#define eSI { OP_IMREG, eSI_reg }
407#define eDI { OP_IMREG, eDI_reg }
408#define AL { OP_IMREG, al_reg }
409#define CL { OP_IMREG, cl_reg }
410#define DL { OP_IMREG, dl_reg }
411#define BL { OP_IMREG, bl_reg }
412#define AH { OP_IMREG, ah_reg }
413#define CH { OP_IMREG, ch_reg }
414#define DH { OP_IMREG, dh_reg }
415#define BH { OP_IMREG, bh_reg }
416#define AX { OP_IMREG, ax_reg }
417#define DX { OP_IMREG, dx_reg }
418#define zAX { OP_IMREG, z_mode_ax_reg }
419#define indirDX { OP_IMREG, indir_dx_reg }
420
421#define Sw { OP_SEG, w_mode }
422#define Sv { OP_SEG, v_mode }
423#define Ap { OP_DIR, 0 }
424#define Ob { OP_OFF64, b_mode }
425#define Ov { OP_OFF64, v_mode }
426#define Xb { OP_DSreg, eSI_reg }
427#define Xv { OP_DSreg, eSI_reg }
428#define Xz { OP_DSreg, eSI_reg }
429#define Yb { OP_ESreg, eDI_reg }
430#define Yv { OP_ESreg, eDI_reg }
431#define DSBX { OP_DSreg, eBX_reg }
432
433#define es { OP_REG, es_reg }
434#define ss { OP_REG, ss_reg }
435#define cs { OP_REG, cs_reg }
436#define ds { OP_REG, ds_reg }
437#define fs { OP_REG, fs_reg }
438#define gs { OP_REG, gs_reg }
439
440#define MX { OP_MMX, 0 }
441#define XM { OP_XMM, 0 }
442#define EM { OP_EM, v_mode }
443#define EMd { OP_EM, d_mode }
444#define EMq { OP_EM, q_mode }
445#define EXd { OP_EX, d_mode }
446#define EXq { OP_EX, q_mode }
447#define EXx { OP_EX, x_mode }
448#define MS { OP_MS, v_mode }
449#define XS { OP_XS, v_mode }
450#define EMC { OP_EMC, v_mode }
451#define MXC { OP_MXC, 0 }
452#define VM { OP_VMX, q_mode }
453#define OPSUF { OP_3DNowSuffix, 0 }
454#define OPSIMD { OP_SIMD_Suffix, 0 }
455#define XMM0 { XMM_Fixup, 0 }
456
457
458#define Xbr { REP_Fixup, eSI_reg }
459#define Xvr { REP_Fixup, eSI_reg }
460#define Ybr { REP_Fixup, eDI_reg }
461#define Yvr { REP_Fixup, eDI_reg }
462#define Yzr { REP_Fixup, eDI_reg }
463#define indirDXr { REP_Fixup, indir_dx_reg }
464#define ALr { REP_Fixup, al_reg }
465#define eAXr { REP_Fixup, eAX_reg }
466
467#define cond_jump_flag { NULL, cond_jump_mode }
468#define loop_jcxz_flag { NULL, loop_jcxz_mode }
469
470
471#define SUFFIX_ALWAYS 4
472#define AFLAG 2
473#define DFLAG 1
474
475#define b_mode 1
476#define v_mode 2
477#define w_mode 3
478#define d_mode 4
479#define q_mode 5
480#define t_mode 6
481#define x_mode 7
482#define m_mode 8
483#define cond_jump_mode 9
484#define loop_jcxz_mode 10
485#define dq_mode 11
486#define dqw_mode 12
487#define f_mode 13
488#define const_1_mode 14
489#define stack_v_mode 15
490#define z_mode 16
491#define o_mode 17
492#define dqb_mode 18
493#define dqd_mode 19
494
495#define es_reg 100
496#define cs_reg 101
497#define ss_reg 102
498#define ds_reg 103
499#define fs_reg 104
500#define gs_reg 105
501
502#define eAX_reg 108
503#define eCX_reg 109
504#define eDX_reg 110
505#define eBX_reg 111
506#define eSP_reg 112
507#define eBP_reg 113
508#define eSI_reg 114
509#define eDI_reg 115
510
511#define al_reg 116
512#define cl_reg 117
513#define dl_reg 118
514#define bl_reg 119
515#define ah_reg 120
516#define ch_reg 121
517#define dh_reg 122
518#define bh_reg 123
519
520#define ax_reg 124
521#define cx_reg 125
522#define dx_reg 126
523#define bx_reg 127
524#define sp_reg 128
525#define bp_reg 129
526#define si_reg 130
527#define di_reg 131
528
529#define rAX_reg 132
530#define rCX_reg 133
531#define rDX_reg 134
532#define rBX_reg 135
533#define rSP_reg 136
534#define rBP_reg 137
535#define rSI_reg 138
536#define rDI_reg 139
537
538#define z_mode_ax_reg 149
539#define indir_dx_reg 150
540
541#define FLOATCODE 1
542#define USE_GROUPS 2
543#define USE_PREFIX_USER_TABLE 3
544#define X86_64_SPECIAL 4
545#define IS_3BYTE_OPCODE 5
546
547#define FLOAT NULL, { { NULL, FLOATCODE } }
548
549#define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
550#define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
551#define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
552#define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
553#define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
554#define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
555#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
556#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
557#define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
558#define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
559#define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
560#define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
561#define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
562#define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
563#define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
564#define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
565#define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
566#define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
567#define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
568#define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
569#define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
570#define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
571#define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
572#define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
573#define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
574#define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
575#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
576#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
577
578#define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
579#define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
580#define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
581#define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
582#define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
583#define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
584#define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
585#define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
586#define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
587#define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
588#define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
589#define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
590#define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
591#define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
592#define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
593#define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
594#define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
595#define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
596#define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
597#define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
598#define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
599#define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
600#define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
601#define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
602#define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
603#define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
604#define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
605#define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
606#define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
607#define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
608#define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
609#define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
610#define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
611#define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
612#define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
613#define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
614#define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
615#define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
616#define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
617#define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } }
618#define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } }
619#define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } }
620#define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } }
621#define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } }
622#define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } }
623#define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } }
624#define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } }
625#define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } }
626#define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } }
627#define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } }
628#define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } }
629#define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } }
630#define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } }
631#define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } }
632#define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } }
633#define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } }
634#define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } }
635#define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } }
636#define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } }
637#define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } }
638#define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } }
639#define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } }
640#define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } }
641#define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } }
642#define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } }
643#define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } }
644#define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } }
645#define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } }
646#define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } }
647#define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } }
648#define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } }
649#define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } }
650#define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } }
651#define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } }
652#define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } }
653#define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } }
654#define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } }
655#define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } }
656#define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } }
657#define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } }
658#define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } }
659#define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } }
660#define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } }
661#define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } }
662#define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } }
663#define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } }
664#define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } }
665#define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } }
666#define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } }
667#define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } }
668#define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } }
669#define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } }
670#define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } }
671#define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } }
672#define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } }
673#define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } }
674#define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } }
675#define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } }
676#define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } }
677#define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } }
678#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } }
679#define PREGRP101 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 101 } }
680#define PREGRP102 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 102 } }
681#define PREGRP103 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 103 } }
682#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
683#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
684#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
685#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } }
686
687#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
688#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
689#define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
690#define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
691
692#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
693#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
694
695typedef void (*op_rtn) (int bytemode, int sizeflag);
696
697struct dis386 {
698 const char *name;
699 struct
700 {
701 op_rtn rtn;
702 int bytemode;
703 } op[MAX_OPERANDS];
704};
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747static const struct dis386 dis386[] = {
748
749 { "addB", { Eb, Gb } },
750 { "addS", { Ev, Gv } },
751 { "addB", { Gb, Eb } },
752 { "addS", { Gv, Ev } },
753 { "addB", { AL, Ib } },
754 { "addS", { eAX, Iv } },
755 { "push{T|}", { es } },
756 { "pop{T|}", { es } },
757
758 { "orB", { Eb, Gb } },
759 { "orS", { Ev, Gv } },
760 { "orB", { Gb, Eb } },
761 { "orS", { Gv, Ev } },
762 { "orB", { AL, Ib } },
763 { "orS", { eAX, Iv } },
764 { "push{T|}", { cs } },
765 { "(bad)", { XX } },
766
767 { "adcB", { Eb, Gb } },
768 { "adcS", { Ev, Gv } },
769 { "adcB", { Gb, Eb } },
770 { "adcS", { Gv, Ev } },
771 { "adcB", { AL, Ib } },
772 { "adcS", { eAX, Iv } },
773 { "push{T|}", { ss } },
774 { "pop{T|}", { ss } },
775
776 { "sbbB", { Eb, Gb } },
777 { "sbbS", { Ev, Gv } },
778 { "sbbB", { Gb, Eb } },
779 { "sbbS", { Gv, Ev } },
780 { "sbbB", { AL, Ib } },
781 { "sbbS", { eAX, Iv } },
782 { "push{T|}", { ds } },
783 { "pop{T|}", { ds } },
784
785 { "andB", { Eb, Gb } },
786 { "andS", { Ev, Gv } },
787 { "andB", { Gb, Eb } },
788 { "andS", { Gv, Ev } },
789 { "andB", { AL, Ib } },
790 { "andS", { eAX, Iv } },
791 { "(bad)", { XX } },
792 { "daa{|}", { XX } },
793
794 { "subB", { Eb, Gb } },
795 { "subS", { Ev, Gv } },
796 { "subB", { Gb, Eb } },
797 { "subS", { Gv, Ev } },
798 { "subB", { AL, Ib } },
799 { "subS", { eAX, Iv } },
800 { "(bad)", { XX } },
801 { "das{|}", { XX } },
802
803 { "xorB", { Eb, Gb } },
804 { "xorS", { Ev, Gv } },
805 { "xorB", { Gb, Eb } },
806 { "xorS", { Gv, Ev } },
807 { "xorB", { AL, Ib } },
808 { "xorS", { eAX, Iv } },
809 { "(bad)", { XX } },
810 { "aaa{|}", { XX } },
811
812 { "cmpB", { Eb, Gb } },
813 { "cmpS", { Ev, Gv } },
814 { "cmpB", { Gb, Eb } },
815 { "cmpS", { Gv, Ev } },
816 { "cmpB", { AL, Ib } },
817 { "cmpS", { eAX, Iv } },
818 { "(bad)", { XX } },
819 { "aas{|}", { XX } },
820
821 { "inc{S|}", { RMeAX } },
822 { "inc{S|}", { RMeCX } },
823 { "inc{S|}", { RMeDX } },
824 { "inc{S|}", { RMeBX } },
825 { "inc{S|}", { RMeSP } },
826 { "inc{S|}", { RMeBP } },
827 { "inc{S|}", { RMeSI } },
828 { "inc{S|}", { RMeDI } },
829
830 { "dec{S|}", { RMeAX } },
831 { "dec{S|}", { RMeCX } },
832 { "dec{S|}", { RMeDX } },
833 { "dec{S|}", { RMeBX } },
834 { "dec{S|}", { RMeSP } },
835 { "dec{S|}", { RMeBP } },
836 { "dec{S|}", { RMeSI } },
837 { "dec{S|}", { RMeDI } },
838
839 { "pushV", { RMrAX } },
840 { "pushV", { RMrCX } },
841 { "pushV", { RMrDX } },
842 { "pushV", { RMrBX } },
843 { "pushV", { RMrSP } },
844 { "pushV", { RMrBP } },
845 { "pushV", { RMrSI } },
846 { "pushV", { RMrDI } },
847
848 { "popV", { RMrAX } },
849 { "popV", { RMrCX } },
850 { "popV", { RMrDX } },
851 { "popV", { RMrBX } },
852 { "popV", { RMrSP } },
853 { "popV", { RMrBP } },
854 { "popV", { RMrSI } },
855 { "popV", { RMrDI } },
856
857 { X86_64_0 },
858 { X86_64_1 },
859 { X86_64_2 },
860 { X86_64_3 },
861 { "(bad)", { XX } },
862 { "(bad)", { XX } },
863 { "(bad)", { XX } },
864 { "(bad)", { XX } },
865
866 { "pushT", { Iq } },
867 { "imulS", { Gv, Ev, Iv } },
868 { "pushT", { sIb } },
869 { "imulS", { Gv, Ev, sIb } },
870 { "ins{b||b|}", { Ybr, indirDX } },
871 { "ins{R||G|}", { Yzr, indirDX } },
872 { "outs{b||b|}", { indirDXr, Xb } },
873 { "outs{R||G|}", { indirDXr, Xz } },
874
875 { "joH", { Jb, XX, cond_jump_flag } },
876 { "jnoH", { Jb, XX, cond_jump_flag } },
877 { "jbH", { Jb, XX, cond_jump_flag } },
878 { "jaeH", { Jb, XX, cond_jump_flag } },
879 { "jeH", { Jb, XX, cond_jump_flag } },
880 { "jneH", { Jb, XX, cond_jump_flag } },
881 { "jbeH", { Jb, XX, cond_jump_flag } },
882 { "jaH", { Jb, XX, cond_jump_flag } },
883
884 { "jsH", { Jb, XX, cond_jump_flag } },
885 { "jnsH", { Jb, XX, cond_jump_flag } },
886 { "jpH", { Jb, XX, cond_jump_flag } },
887 { "jnpH", { Jb, XX, cond_jump_flag } },
888 { "jlH", { Jb, XX, cond_jump_flag } },
889 { "jgeH", { Jb, XX, cond_jump_flag } },
890 { "jleH", { Jb, XX, cond_jump_flag } },
891 { "jgH", { Jb, XX, cond_jump_flag } },
892
893 { GRP1b },
894 { GRP1S },
895 { "(bad)", { XX } },
896 { GRP1Ss },
897 { "testB", { Eb, Gb } },
898 { "testS", { Ev, Gv } },
899 { "xchgB", { Eb, Gb } },
900 { "xchgS", { Ev, Gv } },
901
902 { "movB", { Eb, Gb } },
903 { "movS", { Ev, Gv } },
904 { "movB", { Gb, Eb } },
905 { "movS", { Gv, Ev } },
906 { "movD", { Sv, Sw } },
907 { "leaS", { Gv, M } },
908 { "movD", { Sw, Sv } },
909 { GRP1a },
910
911 { PREGRP38 },
912 { "xchgS", { RMeCX, eAX } },
913 { "xchgS", { RMeDX, eAX } },
914 { "xchgS", { RMeBX, eAX } },
915 { "xchgS", { RMeSP, eAX } },
916 { "xchgS", { RMeBP, eAX } },
917 { "xchgS", { RMeSI, eAX } },
918 { "xchgS", { RMeDI, eAX } },
919
920 { "cW{t||t|}R", { XX } },
921 { "cR{t||t|}O", { XX } },
922 { "Jcall{T|}", { Ap } },
923 { "(bad)", { XX } },
924 { "pushfT", { XX } },
925 { "popfT", { XX } },
926 { "sahf{|}", { XX } },
927 { "lahf{|}", { XX } },
928
929 { "movB", { AL, Ob } },
930 { "movS", { eAX, Ov } },
931 { "movB", { Ob, AL } },
932 { "movS", { Ov, eAX } },
933 { "movs{b||b|}", { Ybr, Xb } },
934 { "movs{R||R|}", { Yvr, Xv } },
935 { "cmps{b||b|}", { Xb, Yb } },
936 { "cmps{R||R|}", { Xv, Yv } },
937
938 { "testB", { AL, Ib } },
939 { "testS", { eAX, Iv } },
940 { "stosB", { Ybr, AL } },
941 { "stosS", { Yvr, eAX } },
942 { "lodsB", { ALr, Xb } },
943 { "lodsS", { eAXr, Xv } },
944 { "scasB", { AL, Yb } },
945 { "scasS", { eAX, Yv } },
946
947 { "movB", { RMAL, Ib } },
948 { "movB", { RMCL, Ib } },
949 { "movB", { RMDL, Ib } },
950 { "movB", { RMBL, Ib } },
951 { "movB", { RMAH, Ib } },
952 { "movB", { RMCH, Ib } },
953 { "movB", { RMDH, Ib } },
954 { "movB", { RMBH, Ib } },
955
956 { "movS", { RMeAX, Iv64 } },
957 { "movS", { RMeCX, Iv64 } },
958 { "movS", { RMeDX, Iv64 } },
959 { "movS", { RMeBX, Iv64 } },
960 { "movS", { RMeSP, Iv64 } },
961 { "movS", { RMeBP, Iv64 } },
962 { "movS", { RMeSI, Iv64 } },
963 { "movS", { RMeDI, Iv64 } },
964
965 { GRP2b },
966 { GRP2S },
967 { "retT", { Iw } },
968 { "retT", { XX } },
969 { "les{S|}", { Gv, Mp } },
970 { "ldsS", { Gv, Mp } },
971 { GRP11_C6 },
972 { GRP11_C7 },
973
974 { "enterT", { Iw, Ib } },
975 { "leaveT", { XX } },
976 { "lretP", { Iw } },
977 { "lretP", { XX } },
978 { "int3", { XX } },
979 { "int", { Ib } },
980 { "into{|}", { XX } },
981 { "iretP", { XX } },
982
983 { GRP2b_one },
984 { GRP2S_one },
985 { GRP2b_cl },
986 { GRP2S_cl },
987 { "aam{|}", { sIb } },
988 { "aad{|}", { sIb } },
989 { "(bad)", { XX } },
990 { "xlat", { DSBX } },
991
992 { FLOAT },
993 { FLOAT },
994 { FLOAT },
995 { FLOAT },
996 { FLOAT },
997 { FLOAT },
998 { FLOAT },
999 { FLOAT },
1000
1001 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
1002 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
1003 { "loopFH", { Jb, XX, loop_jcxz_flag } },
1004 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
1005 { "inB", { AL, Ib } },
1006 { "inG", { zAX, Ib } },
1007 { "outB", { Ib, AL } },
1008 { "outG", { Ib, zAX } },
1009
1010 { "callT", { Jv } },
1011 { "jmpT", { Jv } },
1012 { "Jjmp{T|}", { Ap } },
1013 { "jmp", { Jb } },
1014 { "inB", { AL, indirDX } },
1015 { "inG", { zAX, indirDX } },
1016 { "outB", { indirDX, AL } },
1017 { "outG", { indirDX, zAX } },
1018
1019 { "(bad)", { XX } },
1020 { "icebp", { XX } },
1021 { "(bad)", { XX } },
1022 { "(bad)", { XX } },
1023 { "hlt", { XX } },
1024 { "cmc", { XX } },
1025 { GRP3b },
1026 { GRP3S },
1027
1028 { "clc", { XX } },
1029 { "stc", { XX } },
1030 { "cli", { XX } },
1031 { "sti", { XX } },
1032 { "cld", { XX } },
1033 { "std", { XX } },
1034 { GRP4 },
1035 { GRP5 },
1036};
1037
1038static const struct dis386 dis386_twobyte[] = {
1039
1040 { GRP6 },
1041 { GRP7 },
1042 { "larS", { Gv, Ew } },
1043 { "lslS", { Gv, Ew } },
1044 { "(bad)", { XX } },
1045 { "syscall", { XX } },
1046 { "clts", { XX } },
1047 { "sysretP", { XX } },
1048
1049 { "invd", { XX } },
1050 { "wbinvd", { XX } },
1051 { "(bad)", { XX } },
1052 { "ud2a", { XX } },
1053 { "(bad)", { XX } },
1054 { GRPAMD },
1055 { "femms", { XX } },
1056 { "", { MX, EM, OPSUF } },
1057
1058 { PREGRP8 },
1059 { PREGRP9 },
1060 { PREGRP30 },
1061 { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } },
1062 { "unpcklpX", { XM, EXq } },
1063 { "unpckhpX", { XM, EXq } },
1064 { PREGRP31 },
1065 { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } },
1066
1067 { GRP16 },
1068 { "(bad)", { XX } },
1069 { "(bad)", { XX } },
1070 { "(bad)", { XX } },
1071 { "(bad)", { XX } },
1072 { "(bad)", { XX } },
1073 { "(bad)", { XX } },
1074 { "nopQ", { Ev } },
1075
1076 { "movZ", { Rm, Cm } },
1077 { "movZ", { Rm, Dm } },
1078 { "movZ", { Cm, Rm } },
1079 { "movZ", { Dm, Rm } },
1080 { "movL", { Rd, Td } },
1081 { "(bad)", { XX } },
1082 { "movL", { Td, Rd } },
1083 { "(bad)", { XX } },
1084
1085 { "movapX", { XM, EXx } },
1086 { "movapX", { EXx, XM } },
1087 { PREGRP2 },
1088 { PREGRP33 },
1089 { PREGRP4 },
1090 { PREGRP3 },
1091 { PREGRP93 },
1092 { PREGRP94 },
1093
1094 { "wrmsr", { XX } },
1095 { "rdtsc", { XX } },
1096 { "rdmsr", { XX } },
1097 { "rdpmc", { XX } },
1098 { "sysenter", { XX } },
1099 { "sysexit", { XX } },
1100 { "(bad)", { XX } },
1101 { "(bad)", { XX } },
1102
1103 { THREE_BYTE_0 },
1104 { "(bad)", { XX } },
1105 { THREE_BYTE_1 },
1106 { "(bad)", { XX } },
1107 { "(bad)", { XX } },
1108 { "(bad)", { XX } },
1109 { "(bad)", { XX } },
1110 { "(bad)", { XX } },
1111
1112 { "cmovo", { Gv, Ev } },
1113 { "cmovno", { Gv, Ev } },
1114 { "cmovb", { Gv, Ev } },
1115 { "cmovae", { Gv, Ev } },
1116 { "cmove", { Gv, Ev } },
1117 { "cmovne", { Gv, Ev } },
1118 { "cmovbe", { Gv, Ev } },
1119 { "cmova", { Gv, Ev } },
1120
1121 { "cmovs", { Gv, Ev } },
1122 { "cmovns", { Gv, Ev } },
1123 { "cmovp", { Gv, Ev } },
1124 { "cmovnp", { Gv, Ev } },
1125 { "cmovl", { Gv, Ev } },
1126 { "cmovge", { Gv, Ev } },
1127 { "cmovle", { Gv, Ev } },
1128 { "cmovg", { Gv, Ev } },
1129
1130 { "movmskpX", { Gdq, XS } },
1131 { PREGRP13 },
1132 { PREGRP12 },
1133 { PREGRP11 },
1134 { "andpX", { XM, EXx } },
1135 { "andnpX", { XM, EXx } },
1136 { "orpX", { XM, EXx } },
1137 { "xorpX", { XM, EXx } },
1138
1139 { PREGRP0 },
1140 { PREGRP10 },
1141 { PREGRP17 },
1142 { PREGRP16 },
1143 { PREGRP14 },
1144 { PREGRP7 },
1145 { PREGRP5 },
1146 { PREGRP6 },
1147
1148 { PREGRP95 },
1149 { PREGRP96 },
1150 { PREGRP97 },
1151 { "packsswb", { MX, EM } },
1152 { "pcmpgtb", { MX, EM } },
1153 { "pcmpgtw", { MX, EM } },
1154 { "pcmpgtd", { MX, EM } },
1155 { "packuswb", { MX, EM } },
1156
1157 { "punpckhbw", { MX, EM } },
1158 { "punpckhwd", { MX, EM } },
1159 { "punpckhdq", { MX, EM } },
1160 { "packssdw", { MX, EM } },
1161 { PREGRP26 },
1162 { PREGRP24 },
1163 { "movd", { MX, Edq } },
1164 { PREGRP19 },
1165
1166 { PREGRP22 },
1167 { GRP12 },
1168 { GRP13 },
1169 { GRP14 },
1170 { "pcmpeqb", { MX, EM } },
1171 { "pcmpeqw", { MX, EM } },
1172 { "pcmpeqd", { MX, EM } },
1173 { "emms", { XX } },
1174
1175 { PREGRP34 },
1176 { PREGRP35 },
1177 { "(bad)", { XX } },
1178 { "(bad)", { XX } },
1179 { PREGRP28 },
1180 { PREGRP29 },
1181 { PREGRP23 },
1182 { PREGRP20 },
1183
1184 { "joH", { Jv, XX, cond_jump_flag } },
1185 { "jnoH", { Jv, XX, cond_jump_flag } },
1186 { "jbH", { Jv, XX, cond_jump_flag } },
1187 { "jaeH", { Jv, XX, cond_jump_flag } },
1188 { "jeH", { Jv, XX, cond_jump_flag } },
1189 { "jneH", { Jv, XX, cond_jump_flag } },
1190 { "jbeH", { Jv, XX, cond_jump_flag } },
1191 { "jaH", { Jv, XX, cond_jump_flag } },
1192
1193 { "jsH", { Jv, XX, cond_jump_flag } },
1194 { "jnsH", { Jv, XX, cond_jump_flag } },
1195 { "jpH", { Jv, XX, cond_jump_flag } },
1196 { "jnpH", { Jv, XX, cond_jump_flag } },
1197 { "jlH", { Jv, XX, cond_jump_flag } },
1198 { "jgeH", { Jv, XX, cond_jump_flag } },
1199 { "jleH", { Jv, XX, cond_jump_flag } },
1200 { "jgH", { Jv, XX, cond_jump_flag } },
1201
1202 { "seto", { Eb } },
1203 { "setno", { Eb } },
1204 { "setb", { Eb } },
1205 { "setae", { Eb } },
1206 { "sete", { Eb } },
1207 { "setne", { Eb } },
1208 { "setbe", { Eb } },
1209 { "seta", { Eb } },
1210
1211 { "sets", { Eb } },
1212 { "setns", { Eb } },
1213 { "setp", { Eb } },
1214 { "setnp", { Eb } },
1215 { "setl", { Eb } },
1216 { "setge", { Eb } },
1217 { "setle", { Eb } },
1218 { "setg", { Eb } },
1219
1220 { "pushT", { fs } },
1221 { "popT", { fs } },
1222 { "cpuid", { XX } },
1223 { "btS", { Ev, Gv } },
1224 { "shldS", { Ev, Gv, Ib } },
1225 { "shldS", { Ev, Gv, CL } },
1226 { GRPPADLCK2 },
1227 { GRPPADLCK1 },
1228
1229 { "pushT", { gs } },
1230 { "popT", { gs } },
1231 { "rsm", { XX } },
1232 { "btsS", { Ev, Gv } },
1233 { "shrdS", { Ev, Gv, Ib } },
1234 { "shrdS", { Ev, Gv, CL } },
1235 { GRP15 },
1236 { "imulS", { Gv, Ev } },
1237
1238 { "cmpxchgB", { Eb, Gb } },
1239 { "cmpxchgS", { Ev, Gv } },
1240 { "lssS", { Gv, Mp } },
1241 { "btrS", { Ev, Gv } },
1242 { "lfsS", { Gv, Mp } },
1243 { "lgsS", { Gv, Mp } },
1244 { "movz{bR|x|bR|x}", { Gv, Eb } },
1245 { "movz{wR|x|wR|x}", { Gv, Ew } },
1246
1247 { PREGRP37 },
1248 { "ud2b", { XX } },
1249 { GRP8 },
1250 { "btcS", { Ev, Gv } },
1251 { PREGRP107 },
1252 { PREGRP36 },
1253 { "movs{bR|x|bR|x}", { Gv, Eb } },
1254 { "movs{wR|x|wR|x}", { Gv, Ew } },
1255
1256 { "xaddB", { Eb, Gb } },
1257 { "xaddS", { Ev, Gv } },
1258 { PREGRP1 },
1259 { "movntiS", { Ev, Gv } },
1260 { "pinsrw", { MX, Edqw, Ib } },
1261 { "pextrw", { Gdq, MS, Ib } },
1262 { "shufpX", { XM, EXx, Ib } },
1263 { GRP9 },
1264
1265 { "bswap", { RMeAX } },
1266 { "bswap", { RMeCX } },
1267 { "bswap", { RMeDX } },
1268 { "bswap", { RMeBX } },
1269 { "bswap", { RMeSP } },
1270 { "bswap", { RMeBP } },
1271 { "bswap", { RMeSI } },
1272 { "bswap", { RMeDI } },
1273
1274 { PREGRP27 },
1275 { "psrlw", { MX, EM } },
1276 { "psrld", { MX, EM } },
1277 { "psrlq", { MX, EM } },
1278 { "paddq", { MX, EM } },
1279 { "pmullw", { MX, EM } },
1280 { PREGRP21 },
1281 { "pmovmskb", { Gdq, MS } },
1282
1283 { "psubusb", { MX, EM } },
1284 { "psubusw", { MX, EM } },
1285 { "pminub", { MX, EM } },
1286 { "pand", { MX, EM } },
1287 { "paddusb", { MX, EM } },
1288 { "paddusw", { MX, EM } },
1289 { "pmaxub", { MX, EM } },
1290 { "pandn", { MX, EM } },
1291
1292 { "pavgb", { MX, EM } },
1293 { "psraw", { MX, EM } },
1294 { "psrad", { MX, EM } },
1295 { "pavgw", { MX, EM } },
1296 { "pmulhuw", { MX, EM } },
1297 { "pmulhw", { MX, EM } },
1298 { PREGRP15 },
1299 { PREGRP25 },
1300
1301 { "psubsb", { MX, EM } },
1302 { "psubsw", { MX, EM } },
1303 { "pminsw", { MX, EM } },
1304 { "por", { MX, EM } },
1305 { "paddsb", { MX, EM } },
1306 { "paddsw", { MX, EM } },
1307 { "pmaxsw", { MX, EM } },
1308 { "pxor", { MX, EM } },
1309
1310 { PREGRP32 },
1311 { "psllw", { MX, EM } },
1312 { "pslld", { MX, EM } },
1313 { "psllq", { MX, EM } },
1314 { "pmuludq", { MX, EM } },
1315 { "pmaddwd", { MX, EM } },
1316 { "psadbw", { MX, EM } },
1317 { PREGRP18 },
1318
1319 { "psubb", { MX, EM } },
1320 { "psubw", { MX, EM } },
1321 { "psubd", { MX, EM } },
1322 { "psubq", { MX, EM } },
1323 { "paddb", { MX, EM } },
1324 { "paddw", { MX, EM } },
1325 { "paddd", { MX, EM } },
1326 { "(bad)", { XX } },
1327};
1328
1329static const unsigned char onebyte_has_modrm[256] = {
1330
1331
1332 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1333 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1334 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1335 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1336 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1337 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1338 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
1339 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1340 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1341 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1342 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1343 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1344 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
1345 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1347 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
1348
1349
1350};
1351
1352static const unsigned char twobyte_has_modrm[256] = {
1353
1354
1355 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1,
1356 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,
1357 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,
1358 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,
1359 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1360 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1361 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1362 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1,
1363 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1364 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1365 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
1366 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,
1367 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
1368 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1369 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1370 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
1371
1372
1373};
1374
1375static const unsigned char twobyte_uses_DATA_prefix[256] = {
1376
1377
1378 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1379 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,
1380 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
1381 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,
1382 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1383 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1384 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,
1385 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,
1386 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1387 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1388 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1389 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1390 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
1391 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1392 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1393 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0
1394
1395
1396};
1397
1398static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1399
1400
1401 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1402 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
1403 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
1404 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1405 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1406 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1,
1407 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1408 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,
1409 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1410 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1411 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1412 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1413 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
1414 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1415 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1416 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1417
1418
1419};
1420
1421static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1422
1423
1424 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1425 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,
1426 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,
1427 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1428 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1429 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1430 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1431 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
1432 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1433 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1434 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1435 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,
1436 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
1437 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1438 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1439 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1440
1441
1442};
1443
1444
1445static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1446
1447
1448 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
1449 1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,0,
1450 1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0,
1451 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
1452 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1453 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1454 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1455 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1456 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1457 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1458 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1459 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1460 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1461 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
1462 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1463 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
1464
1465
1466};
1467
1468
1469static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1470
1471
1472 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1473 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1474 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1475 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1476 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1477 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1478 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1479 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1480 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1481 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1482 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1483 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1484 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1485 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1486 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1487 1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
1488
1489
1490};
1491
1492
1493static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1494
1495
1496 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1497 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1498 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1499 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1500 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1501 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1502 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1503 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1504 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1505 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1506 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1507 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1508 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1509 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1510 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1511 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
1512
1513
1514};
1515
1516
1517static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1518
1519
1520 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
1521 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
1522 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
1523 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1524 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
1525 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1526 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
1527 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1528 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1529 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1530 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1531 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1532 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1533 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1534 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1535 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1536
1537
1538};
1539
1540
1541static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1542
1543
1544 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1545 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1546 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1547 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1548 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1549 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1550 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1551 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1552 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1553 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1554 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1555 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1556 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1557 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1558 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1559 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1560
1561
1562};
1563
1564
1565static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1566
1567
1568 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1569 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1570 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1571 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1572 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1573 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1574 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1575 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1576 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1577 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1578 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1579 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1580 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1581 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1582 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1583 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1584
1585
1586};
1587
1588static char obuf[100];
1589static char *obufp;
1590static char scratchbuf[100];
1591static unsigned char *start_codep;
1592static unsigned char *insn_codep;
1593static unsigned char *codep;
1594static disassemble_info *the_info;
1595static struct
1596 {
1597 int mod;
1598 int reg;
1599 int rm;
1600 }
1601modrm;
1602static unsigned char need_modrm;
1603
1604
1605
1606
1607#define MODRM_CHECK if (!need_modrm) abort ()
1608
1609static const char * const *names64;
1610static const char * const *names32;
1611static const char * const *names16;
1612static const char * const *names8;
1613static const char * const *names8rex;
1614static const char * const *names_seg;
1615static const char * const *index16;
1616
1617static const char * const intel_names64[] = {
1618 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1619 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1620};
1621static const char * const intel_names32[] = {
1622 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1623 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1624};
1625static const char * const intel_names16[] = {
1626 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1627 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1628};
1629static const char * const intel_names8[] = {
1630 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1631};
1632static const char * const intel_names8rex[] = {
1633 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1634 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1635};
1636static const char * const intel_names_seg[] = {
1637 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1638};
1639static const char * const intel_index16[] = {
1640 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1641};
1642
1643static const char * const att_names64[] = {
1644 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1645 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1646};
1647static const char * const att_names32[] = {
1648 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1649 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1650};
1651static const char * const att_names16[] = {
1652 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1653 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1654};
1655static const char * const att_names8[] = {
1656 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1657};
1658static const char * const att_names8rex[] = {
1659 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1660 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1661};
1662static const char * const att_names_seg[] = {
1663 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1664};
1665static const char * const att_index16[] = {
1666 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1667};
1668
1669static const struct dis386 grps[][8] = {
1670
1671 {
1672 { "popU", { stackEv } },
1673 { "(bad)", { XX } },
1674 { "(bad)", { XX } },
1675 { "(bad)", { XX } },
1676 { "(bad)", { XX } },
1677 { "(bad)", { XX } },
1678 { "(bad)", { XX } },
1679 { "(bad)", { XX } },
1680 },
1681
1682 {
1683 { "addA", { Eb, Ib } },
1684 { "orA", { Eb, Ib } },
1685 { "adcA", { Eb, Ib } },
1686 { "sbbA", { Eb, Ib } },
1687 { "andA", { Eb, Ib } },
1688 { "subA", { Eb, Ib } },
1689 { "xorA", { Eb, Ib } },
1690 { "cmpA", { Eb, Ib } },
1691 },
1692
1693 {
1694 { "addQ", { Ev, Iv } },
1695 { "orQ", { Ev, Iv } },
1696 { "adcQ", { Ev, Iv } },
1697 { "sbbQ", { Ev, Iv } },
1698 { "andQ", { Ev, Iv } },
1699 { "subQ", { Ev, Iv } },
1700 { "xorQ", { Ev, Iv } },
1701 { "cmpQ", { Ev, Iv } },
1702 },
1703
1704 {
1705 { "addQ", { Ev, sIb } },
1706 { "orQ", { Ev, sIb } },
1707 { "adcQ", { Ev, sIb } },
1708 { "sbbQ", { Ev, sIb } },
1709 { "andQ", { Ev, sIb } },
1710 { "subQ", { Ev, sIb } },
1711 { "xorQ", { Ev, sIb } },
1712 { "cmpQ", { Ev, sIb } },
1713 },
1714
1715 {
1716 { "rolA", { Eb, Ib } },
1717 { "rorA", { Eb, Ib } },
1718 { "rclA", { Eb, Ib } },
1719 { "rcrA", { Eb, Ib } },
1720 { "shlA", { Eb, Ib } },
1721 { "shrA", { Eb, Ib } },
1722 { "(bad)", { XX } },
1723 { "sarA", { Eb, Ib } },
1724 },
1725
1726 {
1727 { "rolQ", { Ev, Ib } },
1728 { "rorQ", { Ev, Ib } },
1729 { "rclQ", { Ev, Ib } },
1730 { "rcrQ", { Ev, Ib } },
1731 { "shlQ", { Ev, Ib } },
1732 { "shrQ", { Ev, Ib } },
1733 { "(bad)", { XX } },
1734 { "sarQ", { Ev, Ib } },
1735 },
1736
1737 {
1738 { "rolA", { Eb, I1 } },
1739 { "rorA", { Eb, I1 } },
1740 { "rclA", { Eb, I1 } },
1741 { "rcrA", { Eb, I1 } },
1742 { "shlA", { Eb, I1 } },
1743 { "shrA", { Eb, I1 } },
1744 { "(bad)", { XX } },
1745 { "sarA", { Eb, I1 } },
1746 },
1747
1748 {
1749 { "rolQ", { Ev, I1 } },
1750 { "rorQ", { Ev, I1 } },
1751 { "rclQ", { Ev, I1 } },
1752 { "rcrQ", { Ev, I1 } },
1753 { "shlQ", { Ev, I1 } },
1754 { "shrQ", { Ev, I1 } },
1755 { "(bad)", { XX } },
1756 { "sarQ", { Ev, I1 } },
1757 },
1758
1759 {
1760 { "rolA", { Eb, CL } },
1761 { "rorA", { Eb, CL } },
1762 { "rclA", { Eb, CL } },
1763 { "rcrA", { Eb, CL } },
1764 { "shlA", { Eb, CL } },
1765 { "shrA", { Eb, CL } },
1766 { "(bad)", { XX } },
1767 { "sarA", { Eb, CL } },
1768 },
1769
1770 {
1771 { "rolQ", { Ev, CL } },
1772 { "rorQ", { Ev, CL } },
1773 { "rclQ", { Ev, CL } },
1774 { "rcrQ", { Ev, CL } },
1775 { "shlQ", { Ev, CL } },
1776 { "shrQ", { Ev, CL } },
1777 { "(bad)", { XX } },
1778 { "sarQ", { Ev, CL } },
1779 },
1780
1781 {
1782 { "testA", { Eb, Ib } },
1783 { "(bad)", { Eb } },
1784 { "notA", { Eb } },
1785 { "negA", { Eb } },
1786 { "mulA", { Eb } },
1787 { "imulA", { Eb } },
1788 { "divA", { Eb } },
1789 { "idivA", { Eb } },
1790 },
1791
1792 {
1793 { "testQ", { Ev, Iv } },
1794 { "(bad)", { XX } },
1795 { "notQ", { Ev } },
1796 { "negQ", { Ev } },
1797 { "mulQ", { Ev } },
1798 { "imulQ", { Ev } },
1799 { "divQ", { Ev } },
1800 { "idivQ", { Ev } },
1801 },
1802
1803 {
1804 { "incA", { Eb } },
1805 { "decA", { Eb } },
1806 { "(bad)", { XX } },
1807 { "(bad)", { XX } },
1808 { "(bad)", { XX } },
1809 { "(bad)", { XX } },
1810 { "(bad)", { XX } },
1811 { "(bad)", { XX } },
1812 },
1813
1814 {
1815 { "incQ", { Ev } },
1816 { "decQ", { Ev } },
1817 { "callT", { indirEv } },
1818 { "JcallT", { indirEp } },
1819 { "jmpT", { indirEv } },
1820 { "JjmpT", { indirEp } },
1821 { "pushU", { stackEv } },
1822 { "(bad)", { XX } },
1823 },
1824
1825 {
1826 { "sldtD", { Sv } },
1827 { "strD", { Sv } },
1828 { "lldt", { Ew } },
1829 { "ltr", { Ew } },
1830 { "verr", { Ew } },
1831 { "verw", { Ew } },
1832 { "(bad)", { XX } },
1833 { "(bad)", { XX } },
1834 },
1835
1836 {
1837 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1838 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1839 { "lgdt{Q|Q||}", { M } },
1840 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1841 { "smswD", { Sv } },
1842 { "(bad)", { XX } },
1843 { "lmsw", { Ew } },
1844 { "invlpg", { { INVLPG_Fixup, w_mode } } },
1845 },
1846
1847 {
1848 { "(bad)", { XX } },
1849 { "(bad)", { XX } },
1850 { "(bad)", { XX } },
1851 { "(bad)", { XX } },
1852 { "btQ", { Ev, Ib } },
1853 { "btsQ", { Ev, Ib } },
1854 { "btrQ", { Ev, Ib } },
1855 { "btcQ", { Ev, Ib } },
1856 },
1857
1858 {
1859 { "(bad)", { XX } },
1860 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1861 { "(bad)", { XX } },
1862 { "(bad)", { XX } },
1863 { "(bad)", { XX } },
1864 { "(bad)", { XX } },
1865 { "", { VM } },
1866 { "vmptrst", { Mq } },
1867 },
1868
1869 {
1870 { "movA", { Eb, Ib } },
1871 { "(bad)", { XX } },
1872 { "(bad)", { XX } },
1873 { "(bad)", { XX } },
1874 { "(bad)", { XX } },
1875 { "(bad)", { XX } },
1876 { "(bad)", { XX } },
1877 { "(bad)", { XX } },
1878 },
1879
1880 {
1881 { "movQ", { Ev, Iv } },
1882 { "(bad)", { XX } },
1883 { "(bad)", { XX } },
1884 { "(bad)", { XX } },
1885 { "(bad)", { XX } },
1886 { "(bad)", { XX } },
1887 { "(bad)", { XX } },
1888 { "(bad)", { XX } },
1889 },
1890
1891 {
1892 { "(bad)", { XX } },
1893 { "(bad)", { XX } },
1894 { "psrlw", { MS, Ib } },
1895 { "(bad)", { XX } },
1896 { "psraw", { MS, Ib } },
1897 { "(bad)", { XX } },
1898 { "psllw", { MS, Ib } },
1899 { "(bad)", { XX } },
1900 },
1901
1902 {
1903 { "(bad)", { XX } },
1904 { "(bad)", { XX } },
1905 { "psrld", { MS, Ib } },
1906 { "(bad)", { XX } },
1907 { "psrad", { MS, Ib } },
1908 { "(bad)", { XX } },
1909 { "pslld", { MS, Ib } },
1910 { "(bad)", { XX } },
1911 },
1912
1913 {
1914 { "(bad)", { XX } },
1915 { "(bad)", { XX } },
1916 { "psrlq", { MS, Ib } },
1917 { "psrldq", { MS, Ib } },
1918 { "(bad)", { XX } },
1919 { "(bad)", { XX } },
1920 { "psllq", { MS, Ib } },
1921 { "pslldq", { MS, Ib } },
1922 },
1923
1924 {
1925 { "fxsave", { Ev } },
1926 { "fxrstor", { Ev } },
1927 { "ldmxcsr", { Ev } },
1928 { "stmxcsr", { Ev } },
1929 { "(bad)", { XX } },
1930 { "lfence", { { OP_0fae, 0 } } },
1931 { "mfence", { { OP_0fae, 0 } } },
1932 { "clflush", { { OP_0fae, 0 } } },
1933 },
1934
1935 {
1936 { "prefetchnta", { Ev } },
1937 { "prefetcht0", { Ev } },
1938 { "prefetcht1", { Ev } },
1939 { "prefetcht2", { Ev } },
1940 { "(bad)", { XX } },
1941 { "(bad)", { XX } },
1942 { "(bad)", { XX } },
1943 { "(bad)", { XX } },
1944 },
1945
1946 {
1947 { "prefetch", { Eb } },
1948 { "prefetchw", { Eb } },
1949 { "(bad)", { XX } },
1950 { "(bad)", { XX } },
1951 { "(bad)", { XX } },
1952 { "(bad)", { XX } },
1953 { "(bad)", { XX } },
1954 { "(bad)", { XX } },
1955 },
1956
1957 {
1958 { "xstore-rng", { { OP_0f07, 0 } } },
1959 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1960 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1961 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1962 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1963 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1964 { "(bad)", { { OP_0f07, 0 } } },
1965 { "(bad)", { { OP_0f07, 0 } } },
1966 },
1967
1968 {
1969 { "montmul", { { OP_0f07, 0 } } },
1970 { "xsha1", { { OP_0f07, 0 } } },
1971 { "xsha256", { { OP_0f07, 0 } } },
1972 { "(bad)", { { OP_0f07, 0 } } },
1973 { "(bad)", { { OP_0f07, 0 } } },
1974 { "(bad)", { { OP_0f07, 0 } } },
1975 { "(bad)", { { OP_0f07, 0 } } },
1976 { "(bad)", { { OP_0f07, 0 } } },
1977 }
1978};
1979
1980static const struct dis386 prefix_user_table[][4] = {
1981
1982 {
1983 { "addps", { XM, EXx } },
1984 { "addss", { XM, EXd } },
1985 { "addpd", { XM, EXx } },
1986 { "addsd", { XM, EXq } },
1987 },
1988
1989 {
1990 { "", { XM, EXx, OPSIMD } },
1991 { "", { XM, EXx, OPSIMD } },
1992 { "", { XM, EXx, OPSIMD } },
1993 { "", { XM, EXx, OPSIMD } },
1994 },
1995
1996 {
1997 { "cvtpi2ps", { XM, EMC } },
1998 { "cvtsi2ssY", { XM, Ev } },
1999 { "cvtpi2pd", { XM, EMC } },
2000 { "cvtsi2sdY", { XM, Ev } },
2001 },
2002
2003 {
2004 { "cvtps2pi", { MXC, EXx } },
2005 { "cvtss2siY", { Gv, EXx } },
2006 { "cvtpd2pi", { MXC, EXx } },
2007 { "cvtsd2siY", { Gv, EXx } },
2008 },
2009
2010 {
2011 { "cvttps2pi", { MXC, EXx } },
2012 { "cvttss2siY", { Gv, EXx } },
2013 { "cvttpd2pi", { MXC, EXx } },
2014 { "cvttsd2siY", { Gv, EXx } },
2015 },
2016
2017 {
2018 { "divps", { XM, EXx } },
2019 { "divss", { XM, EXx } },
2020 { "divpd", { XM, EXx } },
2021 { "divsd", { XM, EXx } },
2022 },
2023
2024 {
2025 { "maxps", { XM, EXx } },
2026 { "maxss", { XM, EXx } },
2027 { "maxpd", { XM, EXx } },
2028 { "maxsd", { XM, EXx } },
2029 },
2030
2031 {
2032 { "minps", { XM, EXx } },
2033 { "minss", { XM, EXx } },
2034 { "minpd", { XM, EXx } },
2035 { "minsd", { XM, EXx } },
2036 },
2037
2038 {
2039 { "movups", { XM, EXx } },
2040 { "movss", { XM, EXx } },
2041 { "movupd", { XM, EXx } },
2042 { "movsd", { XM, EXx } },
2043 },
2044
2045 {
2046 { "movups", { EXx, XM } },
2047 { "movss", { EXx, XM } },
2048 { "movupd", { EXx, XM } },
2049 { "movsd", { EXx, XM } },
2050 },
2051
2052 {
2053 { "mulps", { XM, EXx } },
2054 { "mulss", { XM, EXx } },
2055 { "mulpd", { XM, EXx } },
2056 { "mulsd", { XM, EXx } },
2057 },
2058
2059 {
2060 { "rcpps", { XM, EXx } },
2061 { "rcpss", { XM, EXx } },
2062 { "(bad)", { XM, EXx } },
2063 { "(bad)", { XM, EXx } },
2064 },
2065
2066 {
2067 { "rsqrtps",{ XM, EXx } },
2068 { "rsqrtss",{ XM, EXx } },
2069 { "(bad)", { XM, EXx } },
2070 { "(bad)", { XM, EXx } },
2071 },
2072
2073 {
2074 { "sqrtps", { XM, EXx } },
2075 { "sqrtss", { XM, EXx } },
2076 { "sqrtpd", { XM, EXx } },
2077 { "sqrtsd", { XM, EXx } },
2078 },
2079
2080 {
2081 { "subps", { XM, EXx } },
2082 { "subss", { XM, EXx } },
2083 { "subpd", { XM, EXx } },
2084 { "subsd", { XM, EXx } },
2085 },
2086
2087 {
2088 { "(bad)", { XM, EXx } },
2089 { "cvtdq2pd", { XM, EXq } },
2090 { "cvttpd2dq", { XM, EXx } },
2091 { "cvtpd2dq", { XM, EXx } },
2092 },
2093
2094 {
2095 { "cvtdq2ps", { XM, EXx } },
2096 { "cvttps2dq", { XM, EXx } },
2097 { "cvtps2dq", { XM, EXx } },
2098 { "(bad)", { XM, EXx } },
2099 },
2100
2101 {
2102 { "cvtps2pd", { XM, EXq } },
2103 { "cvtss2sd", { XM, EXx } },
2104 { "cvtpd2ps", { XM, EXx } },
2105 { "cvtsd2ss", { XM, EXx } },
2106 },
2107
2108 {
2109 { "maskmovq", { MX, MS } },
2110 { "(bad)", { XM, EXx } },
2111 { "maskmovdqu", { XM, XS } },
2112 { "(bad)", { XM, EXx } },
2113 },
2114
2115 {
2116 { "movq", { MX, EM } },
2117 { "movdqu", { XM, EXx } },
2118 { "movdqa", { XM, EXx } },
2119 { "(bad)", { XM, EXx } },
2120 },
2121
2122 {
2123 { "movq", { EM, MX } },
2124 { "movdqu", { EXx, XM } },
2125 { "movdqa", { EXx, XM } },
2126 { "(bad)", { EXx, XM } },
2127 },
2128
2129 {
2130 { "(bad)", { EXx, XM } },
2131 { "movq2dq",{ XM, MS } },
2132 { "movq", { EXx, XM } },
2133 { "movdq2q",{ MX, XS } },
2134 },
2135
2136 {
2137 { "pshufw", { MX, EM, Ib } },
2138 { "pshufhw",{ XM, EXx, Ib } },
2139 { "pshufd", { XM, EXx, Ib } },
2140 { "pshuflw",{ XM, EXx, Ib } },
2141 },
2142
2143 {
2144 { "movd", { Edq, MX } },
2145 { "movq", { XM, EXx } },
2146 { "movd", { Edq, XM } },
2147 { "(bad)", { Ed, XM } },
2148 },
2149
2150 {
2151 { "(bad)", { MX, EXx } },
2152 { "(bad)", { XM, EXx } },
2153 { "punpckhqdq", { XM, EXx } },
2154 { "(bad)", { XM, EXx } },
2155 },
2156
2157 {
2158 { "movntq", { EM, MX } },
2159 { "(bad)", { EM, XM } },
2160 { "movntdq",{ EM, XM } },
2161 { "(bad)", { EM, XM } },
2162 },
2163
2164 {
2165 { "(bad)", { MX, EXx } },
2166 { "(bad)", { XM, EXx } },
2167 { "punpcklqdq", { XM, EXx } },
2168 { "(bad)", { XM, EXx } },
2169 },
2170
2171 {
2172 { "(bad)", { MX, EXx } },
2173 { "(bad)", { XM, EXx } },
2174 { "addsubpd", { XM, EXx } },
2175 { "addsubps", { XM, EXx } },
2176 },
2177
2178 {
2179 { "(bad)", { MX, EXx } },
2180 { "(bad)", { XM, EXx } },
2181 { "haddpd", { XM, EXx } },
2182 { "haddps", { XM, EXx } },
2183 },
2184
2185 {
2186 { "(bad)", { MX, EXx } },
2187 { "(bad)", { XM, EXx } },
2188 { "hsubpd", { XM, EXx } },
2189 { "hsubps", { XM, EXx } },
2190 },
2191
2192 {
2193 { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } },
2194 { "movsldup", { XM, EXx } },
2195 { "movlpd", { XM, EXq } },
2196 { "movddup", { XM, EXq } },
2197 },
2198
2199 {
2200 { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } },
2201 { "movshdup", { XM, EXx } },
2202 { "movhpd", { XM, EXq } },
2203 { "(bad)", { XM, EXq } },
2204 },
2205
2206 {
2207 { "(bad)", { XM, EXx } },
2208 { "(bad)", { XM, EXx } },
2209 { "(bad)", { XM, EXx } },
2210 { "lddqu", { XM, M } },
2211 },
2212
2213 {
2214 {"movntps", { Ev, XM } },
2215 {"movntss", { Ev, XM } },
2216 {"movntpd", { Ev, XM } },
2217 {"movntsd", { Ev, XM } },
2218 },
2219
2220
2221 {
2222 {"vmread", { Em, Gm } },
2223 {"(bad)", { XX } },
2224 {"extrq", { XS, Ib, Ib } },
2225 {"insertq", { XM, XS, Ib, Ib } },
2226 },
2227
2228
2229 {
2230 {"vmwrite", { Gm, Em } },
2231 {"(bad)", { XX } },
2232 {"extrq", { XM, XS } },
2233 {"insertq", { XM, XS } },
2234 },
2235
2236
2237 {
2238 { "bsrS", { Gv, Ev } },
2239 { "lzcntS", { Gv, Ev } },
2240 { "bsrS", { Gv, Ev } },
2241 { "(bad)", { XX } },
2242 },
2243
2244
2245 {
2246 { "(bad)", { XX } },
2247 { "popcntS", { Gv, Ev } },
2248 { "(bad)", { XX } },
2249 { "(bad)", { XX } },
2250 },
2251
2252
2253 {
2254 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2255 { "pause", { XX } },
2256 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2257 { "(bad)", { XX } },
2258 },
2259
2260
2261 {
2262 { "(bad)", { XX } },
2263 { "(bad)", { XX } },
2264 { "pblendvb", {XM, EXx, XMM0 } },
2265 { "(bad)", { XX } },
2266 },
2267
2268
2269 {
2270 { "(bad)", { XX } },
2271 { "(bad)", { XX } },
2272 { "blendvps", {XM, EXx, XMM0 } },
2273 { "(bad)", { XX } },
2274 },
2275
2276
2277 {
2278 { "(bad)", { XX } },
2279 { "(bad)", { XX } },
2280 { "blendvpd", { XM, EXx, XMM0 } },
2281 { "(bad)", { XX } },
2282 },
2283
2284
2285 {
2286 { "(bad)", { XX } },
2287 { "(bad)", { XX } },
2288 { "ptest", { XM, EXx } },
2289 { "(bad)", { XX } },
2290 },
2291
2292
2293 {
2294 { "(bad)", { XX } },
2295 { "(bad)", { XX } },
2296 { "pmovsxbw", { XM, EXx } },
2297 { "(bad)", { XX } },
2298 },
2299
2300
2301 {
2302 { "(bad)", { XX } },
2303 { "(bad)", { XX } },
2304 { "pmovsxbd", { XM, EXx } },
2305 { "(bad)", { XX } },
2306 },
2307
2308
2309 {
2310 { "(bad)", { XX } },
2311 { "(bad)", { XX } },
2312 { "pmovsxbq", { XM, EXx } },
2313 { "(bad)", { XX } },
2314 },
2315
2316
2317 {
2318 { "(bad)", { XX } },
2319 { "(bad)", { XX } },
2320 { "pmovsxwd", { XM, EXx } },
2321 { "(bad)", { XX } },
2322 },
2323
2324
2325 {
2326 { "(bad)", { XX } },
2327 { "(bad)", { XX } },
2328 { "pmovsxwq", { XM, EXx } },
2329 { "(bad)", { XX } },
2330 },
2331
2332
2333 {
2334 { "(bad)", { XX } },
2335 { "(bad)", { XX } },
2336 { "pmovsxdq", { XM, EXx } },
2337 { "(bad)", { XX } },
2338 },
2339
2340
2341 {
2342 { "(bad)", { XX } },
2343 { "(bad)", { XX } },
2344 { "pmuldq", { XM, EXx } },
2345 { "(bad)", { XX } },
2346 },
2347
2348
2349 {
2350 { "(bad)", { XX } },
2351 { "(bad)", { XX } },
2352 { "pcmpeqq", { XM, EXx } },
2353 { "(bad)", { XX } },
2354 },
2355
2356
2357 {
2358 { "(bad)", { XX } },
2359 { "(bad)", { XX } },
2360 { "movntdqa", { XM, EM } },
2361 { "(bad)", { XX } },
2362 },
2363
2364
2365 {
2366 { "(bad)", { XX } },
2367 { "(bad)", { XX } },
2368 { "packusdw", { XM, EXx } },
2369 { "(bad)", { XX } },
2370 },
2371
2372
2373 {
2374 { "(bad)", { XX } },
2375 { "(bad)", { XX } },
2376 { "pmovzxbw", { XM, EXx } },
2377 { "(bad)", { XX } },
2378 },
2379
2380
2381 {
2382 { "(bad)", { XX } },
2383 { "(bad)", { XX } },
2384 { "pmovzxbd", { XM, EXx } },
2385 { "(bad)", { XX } },
2386 },
2387
2388
2389 {
2390 { "(bad)", { XX } },
2391 { "(bad)", { XX } },
2392 { "pmovzxbq", { XM, EXx } },
2393 { "(bad)", { XX } },
2394 },
2395
2396
2397 {
2398 { "(bad)", { XX } },
2399 { "(bad)", { XX } },
2400 { "pmovzxwd", { XM, EXx } },
2401 { "(bad)", { XX } },
2402 },
2403
2404
2405 {
2406 { "(bad)", { XX } },
2407 { "(bad)", { XX } },
2408 { "pmovzxwq", { XM, EXx } },
2409 { "(bad)", { XX } },
2410 },
2411
2412
2413 {
2414 { "(bad)", { XX } },
2415 { "(bad)", { XX } },
2416 { "pmovzxdq", { XM, EXx } },
2417 { "(bad)", { XX } },
2418 },
2419
2420
2421 {
2422 { "(bad)", { XX } },
2423 { "(bad)", { XX } },
2424 { "pminsb", { XM, EXx } },
2425 { "(bad)", { XX } },
2426 },
2427
2428
2429 {
2430 { "(bad)", { XX } },
2431 { "(bad)", { XX } },
2432 { "pminsd", { XM, EXx } },
2433 { "(bad)", { XX } },
2434 },
2435
2436
2437 {
2438 { "(bad)", { XX } },
2439 { "(bad)", { XX } },
2440 { "pminuw", { XM, EXx } },
2441 { "(bad)", { XX } },
2442 },
2443
2444
2445 {
2446 { "(bad)", { XX } },
2447 { "(bad)", { XX } },
2448 { "pminud", { XM, EXx } },
2449 { "(bad)", { XX } },
2450 },
2451
2452
2453 {
2454 { "(bad)", { XX } },
2455 { "(bad)", { XX } },
2456 { "pmaxsb", { XM, EXx } },
2457 { "(bad)", { XX } },
2458 },
2459
2460
2461 {
2462 { "(bad)", { XX } },
2463 { "(bad)", { XX } },
2464 { "pmaxsd", { XM, EXx } },
2465 { "(bad)", { XX } },
2466 },
2467
2468
2469 {
2470 { "(bad)", { XX } },
2471 { "(bad)", { XX } },
2472 { "pmaxuw", { XM, EXx } },
2473 { "(bad)", { XX } },
2474 },
2475
2476
2477 {
2478 { "(bad)", { XX } },
2479 { "(bad)", { XX } },
2480 { "pmaxud", { XM, EXx } },
2481 { "(bad)", { XX } },
2482 },
2483
2484
2485 {
2486 { "(bad)", { XX } },
2487 { "(bad)", { XX } },
2488 { "pmulld", { XM, EXx } },
2489 { "(bad)", { XX } },
2490 },
2491
2492
2493 {
2494 { "(bad)", { XX } },
2495 { "(bad)", { XX } },
2496 { "phminposuw", { XM, EXx } },
2497 { "(bad)", { XX } },
2498 },
2499
2500
2501 {
2502 { "(bad)", { XX } },
2503 { "(bad)", { XX } },
2504 { "roundps", { XM, EXx, Ib } },
2505 { "(bad)", { XX } },
2506 },
2507
2508
2509 {
2510 { "(bad)", { XX } },
2511 { "(bad)", { XX } },
2512 { "roundpd", { XM, EXx, Ib } },
2513 { "(bad)", { XX } },
2514 },
2515
2516
2517 {
2518 { "(bad)", { XX } },
2519 { "(bad)", { XX } },
2520 { "roundss", { XM, EXx, Ib } },
2521 { "(bad)", { XX } },
2522 },
2523
2524
2525 {
2526 { "(bad)", { XX } },
2527 { "(bad)", { XX } },
2528 { "roundsd", { XM, EXx, Ib } },
2529 { "(bad)", { XX } },
2530 },
2531
2532
2533 {
2534 { "(bad)", { XX } },
2535 { "(bad)", { XX } },
2536 { "blendps", { XM, EXx, Ib } },
2537 { "(bad)", { XX } },
2538 },
2539
2540
2541 {
2542 { "(bad)", { XX } },
2543 { "(bad)", { XX } },
2544 { "blendpd", { XM, EXx, Ib } },
2545 { "(bad)", { XX } },
2546 },
2547
2548
2549 {
2550 { "(bad)", { XX } },
2551 { "(bad)", { XX } },
2552 { "pblendw", { XM, EXx, Ib } },
2553 { "(bad)", { XX } },
2554 },
2555
2556
2557 {
2558 { "(bad)", { XX } },
2559 { "(bad)", { XX } },
2560 { "pextrb", { Edqb, XM, Ib } },
2561 { "(bad)", { XX } },
2562 },
2563
2564
2565 {
2566 { "(bad)", { XX } },
2567 { "(bad)", { XX } },
2568 { "pextrw", { Edqw, XM, Ib } },
2569 { "(bad)", { XX } },
2570 },
2571
2572
2573 {
2574 { "(bad)", { XX } },
2575 { "(bad)", { XX } },
2576 { "pextrK", { Edq, XM, Ib } },
2577 { "(bad)", { XX } },
2578 },
2579
2580
2581 {
2582 { "(bad)", { XX } },
2583 { "(bad)", { XX } },
2584 { "extractps", { Edqd, XM, Ib } },
2585 { "(bad)", { XX } },
2586 },
2587
2588
2589 {
2590 { "(bad)", { XX } },
2591 { "(bad)", { XX } },
2592 { "pinsrb", { XM, Edqb, Ib } },
2593 { "(bad)", { XX } },
2594 },
2595
2596
2597 {
2598 { "(bad)", { XX } },
2599 { "(bad)", { XX } },
2600 { "insertps", { XM, EXx, Ib } },
2601 { "(bad)", { XX } },
2602 },
2603
2604
2605 {
2606 { "(bad)", { XX } },
2607 { "(bad)", { XX } },
2608 { "pinsrK", { XM, Edq, Ib } },
2609 { "(bad)", { XX } },
2610 },
2611
2612
2613 {
2614 { "(bad)", { XX } },
2615 { "(bad)", { XX } },
2616 { "dpps", { XM, EXx, Ib } },
2617 { "(bad)", { XX } },
2618 },
2619
2620
2621 {
2622 { "(bad)", { XX } },
2623 { "(bad)", { XX } },
2624 { "dppd", { XM, EXx, Ib } },
2625 { "(bad)", { XX } },
2626 },
2627
2628
2629 {
2630 { "(bad)", { XX } },
2631 { "(bad)", { XX } },
2632 { "mpsadbw", { XM, EXx, Ib } },
2633 { "(bad)", { XX } },
2634 },
2635
2636
2637 {
2638 { "(bad)", { XX } },
2639 { "(bad)", { XX } },
2640 { "pcmpgtq", { XM, EXx } },
2641 { "(bad)", { XX } },
2642 },
2643
2644
2645 {
2646 { "movbe", { Gv, Ev } },
2647 { "(bad)", { XX } },
2648 { "movbe", { Gv, Ev } },
2649 { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },
2650 },
2651
2652
2653 {
2654 { "movbe", { Ev, Gv } },
2655 { "(bad)", { XX } },
2656 { "movbe", { Ev, Gv } },
2657 { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },
2658 },
2659
2660
2661 {
2662 { "(bad)", { XX } },
2663 { "(bad)", { XX } },
2664 { "pcmpestrm", { XM, EXx, Ib } },
2665 { "(bad)", { XX } },
2666 },
2667
2668
2669 {
2670 { "(bad)", { XX } },
2671 { "(bad)", { XX } },
2672 { "pcmpestri", { XM, EXx, Ib } },
2673 { "(bad)", { XX } },
2674 },
2675
2676
2677 {
2678 { "(bad)", { XX } },
2679 { "(bad)", { XX } },
2680 { "pcmpistrm", { XM, EXx, Ib } },
2681 { "(bad)", { XX } },
2682 },
2683
2684
2685 {
2686 { "(bad)", { XX } },
2687 { "(bad)", { XX } },
2688 { "pcmpistri", { XM, EXx, Ib } },
2689 { "(bad)", { XX } },
2690 },
2691
2692
2693 {
2694 { "ucomiss",{ XM, EXd } },
2695 { "(bad)", { XX } },
2696 { "ucomisd",{ XM, EXq } },
2697 { "(bad)", { XX } },
2698 },
2699
2700
2701 {
2702 { "comiss", { XM, EXd } },
2703 { "(bad)", { XX } },
2704 { "comisd", { XM, EXq } },
2705 { "(bad)", { XX } },
2706 },
2707
2708
2709 {
2710 { "punpcklbw",{ MX, EMd } },
2711 { "(bad)", { XX } },
2712 { "punpcklbw",{ MX, EMq } },
2713 { "(bad)", { XX } },
2714 },
2715
2716
2717 {
2718 { "punpcklwd",{ MX, EMd } },
2719 { "(bad)", { XX } },
2720 { "punpcklwd",{ MX, EMq } },
2721 { "(bad)", { XX } },
2722 },
2723
2724
2725 {
2726 { "punpckldq",{ MX, EMd } },
2727 { "(bad)", { XX } },
2728 { "punpckldq",{ MX, EMq } },
2729 { "(bad)", { XX } },
2730 },
2731
2732
2733 {
2734 { "(bad)", { XX } },
2735 { "(bad)", { XX } },
2736 { "pclmulqdq", { XM, EXx, Ib } },
2737 { "(bad)", { XX } },
2738 },
2739
2740
2741 {
2742 { "(bad)", { XX } },
2743 { "(bad)", { XX } },
2744 { "aesimc", { XM, EXx } },
2745 { "(bad)", { XX } },
2746 },
2747
2748
2749 {
2750 { "(bad)", { XX } },
2751 { "(bad)", { XX } },
2752 { "aesenc", { XM, EXx } },
2753 { "(bad)", { XX } },
2754 },
2755
2756
2757 {
2758 { "(bad)", { XX } },
2759 { "(bad)", { XX } },
2760 { "aesenclast", { XM, EXx } },
2761 { "(bad)", { XX } },
2762 },
2763
2764
2765 {
2766 { "(bad)", { XX } },
2767 { "(bad)", { XX } },
2768 { "aesdec", { XM, EXx } },
2769 { "(bad)", { XX } },
2770 },
2771
2772
2773 {
2774 { "(bad)", { XX } },
2775 { "(bad)", { XX } },
2776 { "aesdeclast", { XM, EXx } },
2777 { "(bad)", { XX } },
2778 },
2779
2780
2781 {
2782 { "(bad)", { XX } },
2783 { "(bad)", { XX } },
2784 { "aeskeygenassist", { XM, EXx, Ib } },
2785 { "(bad)", { XX } },
2786 },
2787
2788
2789 {
2790 { "andnS", { Gv, Bv, Ev } },
2791 { "(bad)", { XX } },
2792 { "(bad)", { XX } },
2793 { "(bad)", { XX } },
2794 },
2795
2796
2797 {
2798 { "bextrS", { Gv, Ev, Bv } },
2799 { "sarxS", { Gv, Ev, Bv } },
2800 { "shlxS", { Gv, Ev, Bv } },
2801 { "shrxS", { Gv, Ev, Bv } },
2802 },
2803
2804
2805 {
2806 { "bsfS", { Gv, Ev } },
2807 { "tzcntS", { Gv, Ev } },
2808 { "bsfS", { Gv, Ev } },
2809 { "(bad)", { XX } },
2810 },
2811};
2812
2813static const struct dis386 x86_64_table[][2] = {
2814 {
2815 { "pusha{P|}", { XX } },
2816 { "(bad)", { XX } },
2817 },
2818 {
2819 { "popa{P|}", { XX } },
2820 { "(bad)", { XX } },
2821 },
2822 {
2823 { "bound{S|}", { Gv, Ma } },
2824 { "(bad)", { XX } },
2825 },
2826 {
2827 { "arpl", { Ew, Gw } },
2828 { "movs{||lq|xd}", { Gv, Ed } },
2829 },
2830};
2831
2832static const struct dis386 three_byte_table[][256] = {
2833
2834 {
2835
2836 { "pshufb", { MX, EM } },
2837 { "phaddw", { MX, EM } },
2838 { "phaddd", { MX, EM } },
2839 { "phaddsw", { MX, EM } },
2840 { "pmaddubsw", { MX, EM } },
2841 { "phsubw", { MX, EM } },
2842 { "phsubd", { MX, EM } },
2843 { "phsubsw", { MX, EM } },
2844
2845 { "psignb", { MX, EM } },
2846 { "psignw", { MX, EM } },
2847 { "psignd", { MX, EM } },
2848 { "pmulhrsw", { MX, EM } },
2849 { "(bad)", { XX } },
2850 { "(bad)", { XX } },
2851 { "(bad)", { XX } },
2852 { "(bad)", { XX } },
2853
2854 { PREGRP39 },
2855 { "(bad)", { XX } },
2856 { "(bad)", { XX } },
2857 { "(bad)", { XX } },
2858 { PREGRP40 },
2859 { PREGRP41 },
2860 { "(bad)", { XX } },
2861 { PREGRP42 },
2862
2863 { "(bad)", { XX } },
2864 { "(bad)", { XX } },
2865 { "(bad)", { XX } },
2866 { "(bad)", { XX } },
2867 { "pabsb", { MX, EM } },
2868 { "pabsw", { MX, EM } },
2869 { "pabsd", { MX, EM } },
2870 { "(bad)", { XX } },
2871
2872 { PREGRP43 },
2873 { PREGRP44 },
2874 { PREGRP45 },
2875 { PREGRP46 },
2876 { PREGRP47 },
2877 { PREGRP48 },
2878 { "(bad)", { XX } },
2879 { "(bad)", { XX } },
2880
2881 { PREGRP49 },
2882 { PREGRP50 },
2883 { PREGRP51 },
2884 { PREGRP52 },
2885 { "(bad)", { XX } },
2886 { "(bad)", { XX } },
2887 { "(bad)", { XX } },
2888 { "(bad)", { XX } },
2889
2890 { PREGRP53 },
2891 { PREGRP54 },
2892 { PREGRP55 },
2893 { PREGRP56 },
2894 { PREGRP57 },
2895 { PREGRP58 },
2896 { "(bad)", { XX } },
2897 { PREGRP86 },
2898
2899 { PREGRP59 },
2900 { PREGRP60 },
2901 { PREGRP61 },
2902 { PREGRP62 },
2903 { PREGRP63 },
2904 { PREGRP64 },
2905 { PREGRP65 },
2906 { PREGRP66 },
2907
2908 { PREGRP67 },
2909 { PREGRP68 },
2910 { "(bad)", { XX } },
2911 { "(bad)", { XX } },
2912 { "(bad)", { XX } },
2913 { "(bad)", { XX } },
2914 { "(bad)", { XX } },
2915 { "(bad)", { XX } },
2916
2917 { "(bad)", { XX } },
2918 { "(bad)", { XX } },
2919 { "(bad)", { XX } },
2920 { "(bad)", { XX } },
2921 { "(bad)", { XX } },
2922 { "(bad)", { XX } },
2923 { "(bad)", { XX } },
2924 { "(bad)", { XX } },
2925
2926 { "(bad)", { XX } },
2927 { "(bad)", { XX } },
2928 { "(bad)", { XX } },
2929 { "(bad)", { XX } },
2930 { "(bad)", { XX } },
2931 { "(bad)", { XX } },
2932 { "(bad)", { XX } },
2933 { "(bad)", { XX } },
2934
2935 { "(bad)", { XX } },
2936 { "(bad)", { XX } },
2937 { "(bad)", { XX } },
2938 { "(bad)", { XX } },
2939 { "(bad)", { XX } },
2940 { "(bad)", { XX } },
2941 { "(bad)", { XX } },
2942 { "(bad)", { XX } },
2943
2944 { "(bad)", { XX } },
2945 { "(bad)", { XX } },
2946 { "(bad)", { XX } },
2947 { "(bad)", { XX } },
2948 { "(bad)", { XX } },
2949 { "(bad)", { XX } },
2950 { "(bad)", { XX } },
2951 { "(bad)", { XX } },
2952
2953 { "(bad)", { XX } },
2954 { "(bad)", { XX } },
2955 { "(bad)", { XX } },
2956 { "(bad)", { XX } },
2957 { "(bad)", { XX } },
2958 { "(bad)", { XX } },
2959 { "(bad)", { XX } },
2960 { "(bad)", { XX } },
2961
2962 { "(bad)", { XX } },
2963 { "(bad)", { XX } },
2964 { "(bad)", { XX } },
2965 { "(bad)", { XX } },
2966 { "(bad)", { XX } },
2967 { "(bad)", { XX } },
2968 { "(bad)", { XX } },
2969 { "(bad)", { XX } },
2970
2971 { "(bad)", { XX } },
2972 { "(bad)", { XX } },
2973 { "(bad)", { XX } },
2974 { "(bad)", { XX } },
2975 { "(bad)", { XX } },
2976 { "(bad)", { XX } },
2977 { "(bad)", { XX } },
2978 { "(bad)", { XX } },
2979
2980 { "(bad)", { XX } },
2981 { "(bad)", { XX } },
2982 { "(bad)", { XX } },
2983 { "(bad)", { XX } },
2984 { "(bad)", { XX } },
2985 { "(bad)", { XX } },
2986 { "(bad)", { XX } },
2987 { "(bad)", { XX } },
2988
2989 { "(bad)", { XX } },
2990 { "(bad)", { XX } },
2991 { "(bad)", { XX } },
2992 { "(bad)", { XX } },
2993 { "(bad)", { XX } },
2994 { "(bad)", { XX } },
2995 { "(bad)", { XX } },
2996 { "(bad)", { XX } },
2997
2998 { "(bad)", { XX } },
2999 { "(bad)", { XX } },
3000 { "(bad)", { XX } },
3001 { "(bad)", { XX } },
3002 { "(bad)", { XX } },
3003 { "(bad)", { XX } },
3004 { "(bad)", { XX } },
3005 { "(bad)", { XX } },
3006
3007 { "(bad)", { XX } },
3008 { "(bad)", { XX } },
3009 { "(bad)", { XX } },
3010 { "(bad)", { XX } },
3011 { "(bad)", { XX } },
3012 { "(bad)", { XX } },
3013 { "(bad)", { XX } },
3014 { "(bad)", { XX } },
3015
3016 { "(bad)", { XX } },
3017 { "(bad)", { XX } },
3018 { "(bad)", { XX } },
3019 { "(bad)", { XX } },
3020 { "(bad)", { XX } },
3021 { "(bad)", { XX } },
3022 { "(bad)", { XX } },
3023 { "(bad)", { XX } },
3024
3025 { "(bad)", { XX } },
3026 { "(bad)", { XX } },
3027 { "(bad)", { XX } },
3028 { "(bad)", { XX } },
3029 { "(bad)", { XX } },
3030 { "(bad)", { XX } },
3031 { "(bad)", { XX } },
3032 { "(bad)", { XX } },
3033
3034 { "(bad)", { XX } },
3035 { "(bad)", { XX } },
3036 { "(bad)", { XX } },
3037 { "(bad)", { XX } },
3038 { "(bad)", { XX } },
3039 { "(bad)", { XX } },
3040 { "(bad)", { XX } },
3041 { "(bad)", { XX } },
3042
3043 { "(bad)", { XX } },
3044 { "(bad)", { XX } },
3045 { "(bad)", { XX } },
3046 { "(bad)", { XX } },
3047 { "(bad)", { XX } },
3048 { "(bad)", { XX } },
3049 { "(bad)", { XX } },
3050 { "(bad)", { XX } },
3051
3052 { "(bad)", { XX } },
3053 { "(bad)", { XX } },
3054 { "(bad)", { XX } },
3055 { "(bad)", { XX } },
3056 { "(bad)", { XX } },
3057 { "(bad)", { XX } },
3058 { "(bad)", { XX } },
3059 { "(bad)", { XX } },
3060
3061 { "(bad)", { XX } },
3062 { "(bad)", { XX } },
3063 { "(bad)", { XX } },
3064 { "(bad)", { XX } },
3065 { "(bad)", { XX } },
3066 { "(bad)", { XX } },
3067 { "(bad)", { XX } },
3068 { "(bad)", { XX } },
3069
3070 { "(bad)", { XX } },
3071 { "(bad)", { XX } },
3072 { "(bad)", { XX } },
3073 { "(bad)", { XX } },
3074 { "(bad)", { XX } },
3075 { "(bad)", { XX } },
3076 { "(bad)", { XX } },
3077 { "(bad)", { XX } },
3078
3079 { "(bad)", { XX } },
3080 { "(bad)", { XX } },
3081 { "(bad)", { XX } },
3082 { PREGRP99 },
3083 { PREGRP100 },
3084 { PREGRP101 },
3085 { PREGRP102 },
3086 { PREGRP103 },
3087
3088 { "(bad)", { XX } },
3089 { "(bad)", { XX } },
3090 { "(bad)", { XX } },
3091 { "(bad)", { XX } },
3092 { "(bad)", { XX } },
3093 { "(bad)", { XX } },
3094 { "(bad)", { XX } },
3095 { "(bad)", { XX } },
3096
3097 { "(bad)", { XX } },
3098 { "(bad)", { XX } },
3099 { "(bad)", { XX } },
3100 { "(bad)", { XX } },
3101 { "(bad)", { XX } },
3102 { "(bad)", { XX } },
3103 { "(bad)", { XX } },
3104 { "(bad)", { XX } },
3105
3106 { PREGRP87 },
3107 { PREGRP88 },
3108 { PREGRP105 },
3109 { "(bad)", { XX } },
3110 { "(bad)", { XX } },
3111 { "(bad)", { XX } },
3112 { "(bad)", { XX } },
3113 { PREGRP106 },
3114
3115 { "(bad)", { XX } },
3116 { "(bad)", { XX } },
3117 { "(bad)", { XX } },
3118 { "(bad)", { XX } },
3119 { "(bad)", { XX } },
3120 { "(bad)", { XX } },
3121 { "(bad)", { XX } },
3122 { "(bad)", { XX } },
3123 },
3124
3125 {
3126
3127 { "(bad)", { XX } },
3128 { "(bad)", { XX } },
3129 { "(bad)", { XX } },
3130 { "(bad)", { XX } },
3131 { "(bad)", { XX } },
3132 { "(bad)", { XX } },
3133 { "(bad)", { XX } },
3134 { "(bad)", { XX } },
3135
3136 { PREGRP69 },
3137 { PREGRP70 },
3138 { PREGRP71 },
3139 { PREGRP72 },
3140 { PREGRP73 },
3141 { PREGRP74 },
3142 { PREGRP75 },
3143 { "palignr", { MX, EM, Ib } },
3144
3145 { "(bad)", { XX } },
3146 { "(bad)", { XX } },
3147 { "(bad)", { XX } },
3148 { "(bad)", { XX } },
3149 { PREGRP76 },
3150 { PREGRP77 },
3151 { PREGRP78 },
3152 { PREGRP79 },
3153
3154 { "(bad)", { XX } },
3155 { "(bad)", { XX } },
3156 { "(bad)", { XX } },
3157 { "(bad)", { XX } },
3158 { "(bad)", { XX } },
3159 { "(bad)", { XX } },
3160 { "(bad)", { XX } },
3161 { "(bad)", { XX } },
3162
3163 { PREGRP80 },
3164 { PREGRP81 },
3165 { PREGRP82 },
3166 { "(bad)", { XX } },
3167 { "(bad)", { XX } },
3168 { "(bad)", { XX } },
3169 { "(bad)", { XX } },
3170 { "(bad)", { XX } },
3171
3172 { "(bad)", { XX } },
3173 { "(bad)", { XX } },
3174 { "(bad)", { XX } },
3175 { "(bad)", { XX } },
3176 { "(bad)", { XX } },
3177 { "(bad)", { XX } },
3178 { "(bad)", { XX } },
3179 { "(bad)", { XX } },
3180
3181 { "(bad)", { XX } },
3182 { "(bad)", { XX } },
3183 { "(bad)", { XX } },
3184 { "(bad)", { XX } },
3185 { "(bad)", { XX } },
3186 { "(bad)", { XX } },
3187 { "(bad)", { XX } },
3188 { "(bad)", { XX } },
3189
3190 { "(bad)", { XX } },
3191 { "(bad)", { XX } },
3192 { "(bad)", { XX } },
3193 { "(bad)", { XX } },
3194 { "(bad)", { XX } },
3195 { "(bad)", { XX } },
3196 { "(bad)", { XX } },
3197 { "(bad)", { XX } },
3198
3199 { PREGRP83 },
3200 { PREGRP84 },
3201 { PREGRP85 },
3202 { "(bad)", { XX } },
3203 { PREGRP98 },
3204 { "(bad)", { XX } },
3205 { "(bad)", { XX } },
3206 { "(bad)", { XX } },
3207
3208 { "(bad)", { XX } },
3209 { "(bad)", { XX } },
3210 { "(bad)", { XX } },
3211 { "(bad)", { XX } },
3212 { "(bad)", { XX } },
3213 { "(bad)", { XX } },
3214 { "(bad)", { XX } },
3215 { "(bad)", { XX } },
3216
3217 { "(bad)", { XX } },
3218 { "(bad)", { XX } },
3219 { "(bad)", { XX } },
3220 { "(bad)", { XX } },
3221 { "(bad)", { XX } },
3222 { "(bad)", { XX } },
3223 { "(bad)", { XX } },
3224 { "(bad)", { XX } },
3225
3226 { "(bad)", { XX } },
3227 { "(bad)", { XX } },
3228 { "(bad)", { XX } },
3229 { "(bad)", { XX } },
3230 { "(bad)", { XX } },
3231 { "(bad)", { XX } },
3232 { "(bad)", { XX } },
3233 { "(bad)", { XX } },
3234
3235 { PREGRP89 },
3236 { PREGRP90 },
3237 { PREGRP91 },
3238 { PREGRP92 },
3239 { "(bad)", { XX } },
3240 { "(bad)", { XX } },
3241 { "(bad)", { XX } },
3242 { "(bad)", { XX } },
3243
3244 { "(bad)", { XX } },
3245 { "(bad)", { XX } },
3246 { "(bad)", { XX } },
3247 { "(bad)", { XX } },
3248 { "(bad)", { XX } },
3249 { "(bad)", { XX } },
3250 { "(bad)", { XX } },
3251 { "(bad)", { XX } },
3252
3253 { "(bad)", { XX } },
3254 { "(bad)", { XX } },
3255 { "(bad)", { XX } },
3256 { "(bad)", { XX } },
3257 { "(bad)", { XX } },
3258 { "(bad)", { XX } },
3259 { "(bad)", { XX } },
3260 { "(bad)", { XX } },
3261
3262 { "(bad)", { XX } },
3263 { "(bad)", { XX } },
3264 { "(bad)", { XX } },
3265 { "(bad)", { XX } },
3266 { "(bad)", { XX } },
3267 { "(bad)", { XX } },
3268 { "(bad)", { XX } },
3269 { "(bad)", { XX } },
3270
3271 { "(bad)", { XX } },
3272 { "(bad)", { XX } },
3273 { "(bad)", { XX } },
3274 { "(bad)", { XX } },
3275 { "(bad)", { XX } },
3276 { "(bad)", { XX } },
3277 { "(bad)", { XX } },
3278 { "(bad)", { XX } },
3279
3280 { "(bad)", { XX } },
3281 { "(bad)", { XX } },
3282 { "(bad)", { XX } },
3283 { "(bad)", { XX } },
3284 { "(bad)", { XX } },
3285 { "(bad)", { XX } },
3286 { "(bad)", { XX } },
3287 { "(bad)", { XX } },
3288
3289 { "(bad)", { XX } },
3290 { "(bad)", { XX } },
3291 { "(bad)", { XX } },
3292 { "(bad)", { XX } },
3293 { "(bad)", { XX } },
3294 { "(bad)", { XX } },
3295 { "(bad)", { XX } },
3296 { "(bad)", { XX } },
3297
3298 { "(bad)", { XX } },
3299 { "(bad)", { XX } },
3300 { "(bad)", { XX } },
3301 { "(bad)", { XX } },
3302 { "(bad)", { XX } },
3303 { "(bad)", { XX } },
3304 { "(bad)", { XX } },
3305 { "(bad)", { XX } },
3306
3307 { "(bad)", { XX } },
3308 { "(bad)", { XX } },
3309 { "(bad)", { XX } },
3310 { "(bad)", { XX } },
3311 { "(bad)", { XX } },
3312 { "(bad)", { XX } },
3313 { "(bad)", { XX } },
3314 { "(bad)", { XX } },
3315
3316 { "(bad)", { XX } },
3317 { "(bad)", { XX } },
3318 { "(bad)", { XX } },
3319 { "(bad)", { XX } },
3320 { "(bad)", { XX } },
3321 { "(bad)", { XX } },
3322 { "(bad)", { XX } },
3323 { "(bad)", { XX } },
3324
3325 { "(bad)", { XX } },
3326 { "(bad)", { XX } },
3327 { "(bad)", { XX } },
3328 { "(bad)", { XX } },
3329 { "(bad)", { XX } },
3330 { "(bad)", { XX } },
3331 { "(bad)", { XX } },
3332 { "(bad)", { XX } },
3333
3334 { "(bad)", { XX } },
3335 { "(bad)", { XX } },
3336 { "(bad)", { XX } },
3337 { "(bad)", { XX } },
3338 { "(bad)", { XX } },
3339 { "(bad)", { XX } },
3340 { "(bad)", { XX } },
3341 { "(bad)", { XX } },
3342
3343 { "(bad)", { XX } },
3344 { "(bad)", { XX } },
3345 { "(bad)", { XX } },
3346 { "(bad)", { XX } },
3347 { "(bad)", { XX } },
3348 { "(bad)", { XX } },
3349 { "(bad)", { XX } },
3350 { "(bad)", { XX } },
3351
3352 { "(bad)", { XX } },
3353 { "(bad)", { XX } },
3354 { "(bad)", { XX } },
3355 { "(bad)", { XX } },
3356 { "(bad)", { XX } },
3357 { "(bad)", { XX } },
3358 { "(bad)", { XX } },
3359 { "(bad)", { XX } },
3360
3361 { "(bad)", { XX } },
3362 { "(bad)", { XX } },
3363 { "(bad)", { XX } },
3364 { "(bad)", { XX } },
3365 { "(bad)", { XX } },
3366 { "(bad)", { XX } },
3367 { "(bad)", { XX } },
3368 { "(bad)", { XX } },
3369
3370 { "(bad)", { XX } },
3371 { "(bad)", { XX } },
3372 { "(bad)", { XX } },
3373 { "(bad)", { XX } },
3374 { "(bad)", { XX } },
3375 { "(bad)", { XX } },
3376 { "(bad)", { XX } },
3377 { PREGRP104 },
3378
3379 { "(bad)", { XX } },
3380 { "(bad)", { XX } },
3381 { "(bad)", { XX } },
3382 { "(bad)", { XX } },
3383 { "(bad)", { XX } },
3384 { "(bad)", { XX } },
3385 { "(bad)", { XX } },
3386 { "(bad)", { XX } },
3387
3388 { "(bad)", { XX } },
3389 { "(bad)", { XX } },
3390 { "(bad)", { XX } },
3391 { "(bad)", { XX } },
3392 { "(bad)", { XX } },
3393 { "(bad)", { XX } },
3394 { "(bad)", { XX } },
3395 { "(bad)", { XX } },
3396
3397 { "(bad)", { XX } },
3398 { "(bad)", { XX } },
3399 { "(bad)", { XX } },
3400 { "(bad)", { XX } },
3401 { "(bad)", { XX } },
3402 { "(bad)", { XX } },
3403 { "(bad)", { XX } },
3404 { "(bad)", { XX } },
3405
3406 { "(bad)", { XX } },
3407 { "(bad)", { XX } },
3408 { "(bad)", { XX } },
3409 { "(bad)", { XX } },
3410 { "(bad)", { XX } },
3411 { "(bad)", { XX } },
3412 { "(bad)", { XX } },
3413 { "(bad)", { XX } },
3414 }
3415};
3416
3417#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
3418
3419static void
3420ckprefix (void)
3421{
3422 int newrex;
3423 rex = 0;
3424 prefixes = 0;
3425 used_prefixes = 0;
3426 rex_used = 0;
3427 while (1)
3428 {
3429 fetch_data(the_info, codep + 1);
3430 newrex = 0;
3431 switch (*codep)
3432 {
3433
3434 case 0x40:
3435 case 0x41:
3436 case 0x42:
3437 case 0x43:
3438 case 0x44:
3439 case 0x45:
3440 case 0x46:
3441 case 0x47:
3442 case 0x48:
3443 case 0x49:
3444 case 0x4a:
3445 case 0x4b:
3446 case 0x4c:
3447 case 0x4d:
3448 case 0x4e:
3449 case 0x4f:
3450 if (address_mode == mode_64bit)
3451 newrex = *codep;
3452 else
3453 return;
3454 break;
3455 case 0xf3:
3456 prefixes |= PREFIX_REPZ;
3457 break;
3458 case 0xf2:
3459 prefixes |= PREFIX_REPNZ;
3460 break;
3461 case 0xf0:
3462 prefixes |= PREFIX_LOCK;
3463 break;
3464 case 0x2e:
3465 prefixes |= PREFIX_CS;
3466 break;
3467 case 0x36:
3468 prefixes |= PREFIX_SS;
3469 break;
3470 case 0x3e:
3471 prefixes |= PREFIX_DS;
3472 break;
3473 case 0x26:
3474 prefixes |= PREFIX_ES;
3475 break;
3476 case 0x64:
3477 prefixes |= PREFIX_FS;
3478 break;
3479 case 0x65:
3480 prefixes |= PREFIX_GS;
3481 break;
3482 case 0x66:
3483 prefixes |= PREFIX_DATA;
3484 break;
3485 case 0x67:
3486 prefixes |= PREFIX_ADDR;
3487 break;
3488 case FWAIT_OPCODE:
3489
3490
3491
3492 if (prefixes || rex)
3493 {
3494 prefixes |= PREFIX_FWAIT;
3495 codep++;
3496 return;
3497 }
3498 prefixes = PREFIX_FWAIT;
3499 break;
3500 default:
3501 return;
3502 }
3503
3504 if (rex)
3505 {
3506 rex_used = rex;
3507 return;
3508 }
3509 rex = newrex;
3510 codep++;
3511 }
3512}
3513
3514static void
3515ckvexprefix (void)
3516{
3517 int op, vex2, vex3, newrex = 0, newpfx = prefixes;
3518
3519 if (address_mode == mode_16bit) {
3520 return;
3521 }
3522
3523 fetch_data(the_info, codep + 1);
3524 op = *codep;
3525
3526 if (op != 0xc4 && op != 0xc5) {
3527 return;
3528 }
3529
3530 fetch_data(the_info, codep + 2);
3531 vex2 = codep[1];
3532
3533 if (address_mode == mode_32bit && (vex2 & 0xc0) != 0xc0) {
3534 return;
3535 }
3536
3537 if (op == 0xc4) {
3538
3539 fetch_data(the_info, codep + 3);
3540 vex3 = codep[2];
3541
3542 newrex |= (vex2 & 0x80 ? 0 : REX_R);
3543 newrex |= (vex2 & 0x40 ? 0 : REX_X);
3544 newrex |= (vex2 & 0x20 ? 0 : REX_B);
3545 newrex |= (vex3 & 0x80 ? REX_W : 0);
3546 switch (vex2 & 0x1f) {
3547 case 1:
3548 newpfx |= PREFIX_VEX_0F;
3549 break;
3550 case 2:
3551 newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F38;
3552 break;
3553 case 3:
3554 newpfx |= PREFIX_VEX_0F | PREFIX_VEX_0F3A;
3555 break;
3556 }
3557 vex2 = vex3;
3558 codep += 3;
3559 } else {
3560
3561 newrex |= (vex2 & 0x80 ? 0 : REX_R);
3562 codep += 2;
3563 }
3564
3565 vex_reg = (~vex2 >> 3) & 15;
3566 switch (vex2 & 3) {
3567 case 1:
3568 newpfx |= PREFIX_DATA;
3569 break;
3570 case 2:
3571 newpfx |= PREFIX_REPZ;
3572 break;
3573 case 3:
3574 newpfx |= PREFIX_REPNZ;
3575 break;
3576 }
3577
3578 rex = newrex;
3579 prefixes = newpfx;
3580}
3581
3582
3583
3584
3585static const char *
3586prefix_name (int pref, int sizeflag)
3587{
3588 static const char * const rexes [16] =
3589 {
3590 "rex",
3591 "rex.B",
3592 "rex.X",
3593 "rex.XB",
3594 "rex.R",
3595 "rex.RB",
3596 "rex.RX",
3597 "rex.RXB",
3598 "rex.W",
3599 "rex.WB",
3600 "rex.WX",
3601 "rex.WXB",
3602 "rex.WR",
3603 "rex.WRB",
3604 "rex.WRX",
3605 "rex.WRXB",
3606 };
3607
3608 switch (pref)
3609 {
3610
3611 case 0x40:
3612 case 0x41:
3613 case 0x42:
3614 case 0x43:
3615 case 0x44:
3616 case 0x45:
3617 case 0x46:
3618 case 0x47:
3619 case 0x48:
3620 case 0x49:
3621 case 0x4a:
3622 case 0x4b:
3623 case 0x4c:
3624 case 0x4d:
3625 case 0x4e:
3626 case 0x4f:
3627 return rexes [pref - 0x40];
3628 case 0xf3:
3629 return "repz";
3630 case 0xf2:
3631 return "repnz";
3632 case 0xf0:
3633 return "lock";
3634 case 0x2e:
3635 return "cs";
3636 case 0x36:
3637 return "ss";
3638 case 0x3e:
3639 return "ds";
3640 case 0x26:
3641 return "es";
3642 case 0x64:
3643 return "fs";
3644 case 0x65:
3645 return "gs";
3646 case 0x66:
3647 return (sizeflag & DFLAG) ? "data16" : "data32";
3648 case 0x67:
3649 if (address_mode == mode_64bit)
3650 return (sizeflag & AFLAG) ? "addr32" : "addr64";
3651 else
3652 return (sizeflag & AFLAG) ? "addr16" : "addr32";
3653 case FWAIT_OPCODE:
3654 return "fwait";
3655 default:
3656 return NULL;
3657 }
3658}
3659
3660static char op_out[MAX_OPERANDS][100];
3661static int op_ad, op_index[MAX_OPERANDS];
3662static int two_source_ops;
3663static bfd_vma op_address[MAX_OPERANDS];
3664static bfd_vma op_riprel[MAX_OPERANDS];
3665static bfd_vma start_pc;
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676static char intel_syntax;
3677static char open_char;
3678static char close_char;
3679static char separator_char;
3680static char scale_char;
3681
3682int
3683print_insn_i386 (bfd_vma pc, disassemble_info *info)
3684{
3685 intel_syntax = -1;
3686
3687 return print_insn (pc, info);
3688}
3689
3690static int
3691print_insn (bfd_vma pc, disassemble_info *info)
3692{
3693 const struct dis386 *dp;
3694 int i;
3695 char *op_txt[MAX_OPERANDS];
3696 int needcomma;
3697 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
3698 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
3699 int sizeflag;
3700 const char *p;
3701 struct dis_private priv;
3702 unsigned char op;
3703 unsigned char threebyte;
3704
3705 if (info->mach == bfd_mach_x86_64_intel_syntax
3706 || info->mach == bfd_mach_x86_64)
3707 address_mode = mode_64bit;
3708 else
3709 address_mode = mode_32bit;
3710
3711 if (intel_syntax == (char) -1)
3712 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
3713 || info->mach == bfd_mach_x86_64_intel_syntax);
3714
3715 if (info->mach == bfd_mach_i386_i386
3716 || info->mach == bfd_mach_x86_64
3717 || info->mach == bfd_mach_i386_i386_intel_syntax
3718 || info->mach == bfd_mach_x86_64_intel_syntax)
3719 priv.orig_sizeflag = AFLAG | DFLAG;
3720 else if (info->mach == bfd_mach_i386_i8086)
3721 priv.orig_sizeflag = 0;
3722 else
3723 abort ();
3724
3725 for (p = info->disassembler_options; p != NULL; )
3726 {
3727 if (strncmp (p, "x86-64", 6) == 0)
3728 {
3729 address_mode = mode_64bit;
3730 priv.orig_sizeflag = AFLAG | DFLAG;
3731 }
3732 else if (strncmp (p, "i386", 4) == 0)
3733 {
3734 address_mode = mode_32bit;
3735 priv.orig_sizeflag = AFLAG | DFLAG;
3736 }
3737 else if (strncmp (p, "i8086", 5) == 0)
3738 {
3739 address_mode = mode_16bit;
3740 priv.orig_sizeflag = 0;
3741 }
3742 else if (strncmp (p, "intel", 5) == 0)
3743 {
3744 intel_syntax = 1;
3745 }
3746 else if (strncmp (p, "att", 3) == 0)
3747 {
3748 intel_syntax = 0;
3749 }
3750 else if (strncmp (p, "addr", 4) == 0)
3751 {
3752 if (address_mode == mode_64bit)
3753 {
3754 if (p[4] == '3' && p[5] == '2')
3755 priv.orig_sizeflag &= ~AFLAG;
3756 else if (p[4] == '6' && p[5] == '4')
3757 priv.orig_sizeflag |= AFLAG;
3758 }
3759 else
3760 {
3761 if (p[4] == '1' && p[5] == '6')
3762 priv.orig_sizeflag &= ~AFLAG;
3763 else if (p[4] == '3' && p[5] == '2')
3764 priv.orig_sizeflag |= AFLAG;
3765 }
3766 }
3767 else if (strncmp (p, "data", 4) == 0)
3768 {
3769 if (p[4] == '1' && p[5] == '6')
3770 priv.orig_sizeflag &= ~DFLAG;
3771 else if (p[4] == '3' && p[5] == '2')
3772 priv.orig_sizeflag |= DFLAG;
3773 }
3774 else if (strncmp (p, "suffix", 6) == 0)
3775 priv.orig_sizeflag |= SUFFIX_ALWAYS;
3776
3777 p = strchr (p, ',');
3778 if (p != NULL)
3779 p++;
3780 }
3781
3782 if (intel_syntax)
3783 {
3784 names64 = intel_names64;
3785 names32 = intel_names32;
3786 names16 = intel_names16;
3787 names8 = intel_names8;
3788 names8rex = intel_names8rex;
3789 names_seg = intel_names_seg;
3790 index16 = intel_index16;
3791 open_char = '[';
3792 close_char = ']';
3793 separator_char = '+';
3794 scale_char = '*';
3795 }
3796 else
3797 {
3798 names64 = att_names64;
3799 names32 = att_names32;
3800 names16 = att_names16;
3801 names8 = att_names8;
3802 names8rex = att_names8rex;
3803 names_seg = att_names_seg;
3804 index16 = att_index16;
3805 open_char = '(';
3806 close_char = ')';
3807 separator_char = ',';
3808 scale_char = ',';
3809 }
3810
3811
3812
3813 info->bytes_per_line = 7;
3814
3815 info->private_data = &priv;
3816 priv.max_fetched = priv.the_buffer;
3817 priv.insn_start = pc;
3818
3819 obuf[0] = 0;
3820 for (i = 0; i < MAX_OPERANDS; ++i)
3821 {
3822 op_out[i][0] = 0;
3823 op_index[i] = -1;
3824 }
3825
3826 the_info = info;
3827 start_pc = pc;
3828 start_codep = priv.the_buffer;
3829 codep = priv.the_buffer;
3830
3831 if (sigsetjmp(priv.bailout, 0) != 0)
3832 {
3833 const char *name;
3834
3835
3836
3837
3838 if (codep > priv.the_buffer)
3839 {
3840 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3841 if (name != NULL)
3842 (*info->fprintf_func) (info->stream, "%s", name);
3843 else
3844 {
3845
3846 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3847 (unsigned int) priv.the_buffer[0]);
3848 }
3849
3850 return 1;
3851 }
3852
3853 return -1;
3854 }
3855
3856 obufp = obuf;
3857 ckprefix ();
3858 ckvexprefix ();
3859
3860 insn_codep = codep;
3861 sizeflag = priv.orig_sizeflag;
3862
3863 fetch_data(info, codep + 1);
3864 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3865
3866 if (((prefixes & PREFIX_FWAIT)
3867 && ((*codep < 0xd8) || (*codep > 0xdf)))
3868 || (rex && rex_used))
3869 {
3870 const char *name;
3871
3872
3873
3874 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3875 if (name == NULL)
3876 name = INTERNAL_DISASSEMBLER_ERROR;
3877 (*info->fprintf_func) (info->stream, "%s", name);
3878 return 1;
3879 }
3880
3881 op = 0;
3882 if (prefixes & PREFIX_VEX_0F)
3883 {
3884 used_prefixes |= PREFIX_VEX_0F | PREFIX_VEX_0F38 | PREFIX_VEX_0F3A;
3885 if (prefixes & PREFIX_VEX_0F38)
3886 threebyte = 0x38;
3887 else if (prefixes & PREFIX_VEX_0F3A)
3888 threebyte = 0x3a;
3889 else
3890 threebyte = *codep++;
3891 goto vex_opcode;
3892 }
3893 if (*codep == 0x0f)
3894 {
3895 fetch_data(info, codep + 2);
3896 threebyte = codep[1];
3897 codep += 2;
3898 vex_opcode:
3899 dp = &dis386_twobyte[threebyte];
3900 need_modrm = twobyte_has_modrm[threebyte];
3901 uses_DATA_prefix = twobyte_uses_DATA_prefix[threebyte];
3902 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[threebyte];
3903 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[threebyte];
3904 uses_LOCK_prefix = (threebyte & ~0x02) == 0x20;
3905 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3906 {
3907 fetch_data(info, codep + 2);
3908 op = *codep++;
3909 switch (threebyte)
3910 {
3911 case 0x38:
3912 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3913 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3914 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3915 break;
3916 case 0x3a:
3917 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3918 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3919 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3920 break;
3921 default:
3922 break;
3923 }
3924 }
3925 }
3926 else
3927 {
3928 dp = &dis386[*codep];
3929 need_modrm = onebyte_has_modrm[*codep];
3930 uses_DATA_prefix = 0;
3931 uses_REPNZ_prefix = 0;
3932
3933 uses_REPZ_prefix = *codep == 0x90;
3934 uses_LOCK_prefix = 0;
3935 codep++;
3936 }
3937
3938 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3939 {
3940 oappend ("repz ");
3941 used_prefixes |= PREFIX_REPZ;
3942 }
3943 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3944 {
3945 oappend ("repnz ");
3946 used_prefixes |= PREFIX_REPNZ;
3947 }
3948
3949 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3950 {
3951 oappend ("lock ");
3952 used_prefixes |= PREFIX_LOCK;
3953 }
3954
3955 if (prefixes & PREFIX_ADDR)
3956 {
3957 sizeflag ^= AFLAG;
3958 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
3959 {
3960 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3961 oappend ("addr32 ");
3962 else
3963 oappend ("addr16 ");
3964 used_prefixes |= PREFIX_ADDR;
3965 }
3966 }
3967
3968 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3969 {
3970 sizeflag ^= DFLAG;
3971 if (dp->op[2].bytemode == cond_jump_mode
3972 && dp->op[0].bytemode == v_mode
3973 && !intel_syntax)
3974 {
3975 if (sizeflag & DFLAG)
3976 oappend ("data32 ");
3977 else
3978 oappend ("data16 ");
3979 used_prefixes |= PREFIX_DATA;
3980 }
3981 }
3982
3983 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3984 {
3985 dp = &three_byte_table[dp->op[1].bytemode][op];
3986 modrm.mod = (*codep >> 6) & 3;
3987 modrm.reg = (*codep >> 3) & 7;
3988 modrm.rm = *codep & 7;
3989 }
3990 else if (need_modrm)
3991 {
3992 fetch_data(info, codep + 1);
3993 modrm.mod = (*codep >> 6) & 3;
3994 modrm.reg = (*codep >> 3) & 7;
3995 modrm.rm = *codep & 7;
3996 }
3997
3998 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
3999 {
4000 dofloat (sizeflag);
4001 }
4002 else
4003 {
4004 int index;
4005 if (dp->name == NULL)
4006 {
4007 switch (dp->op[0].bytemode)
4008 {
4009 case USE_GROUPS:
4010 dp = &grps[dp->op[1].bytemode][modrm.reg];
4011 break;
4012
4013 case USE_PREFIX_USER_TABLE:
4014 index = 0;
4015 used_prefixes |= (prefixes & PREFIX_REPZ);
4016 if (prefixes & PREFIX_REPZ)
4017 index = 1;
4018 else
4019 {
4020
4021
4022 used_prefixes |= (prefixes & PREFIX_REPNZ);
4023 if (prefixes & PREFIX_REPNZ)
4024 index = 3;
4025 else
4026 {
4027 used_prefixes |= (prefixes & PREFIX_DATA);
4028 if (prefixes & PREFIX_DATA)
4029 index = 2;
4030 }
4031 }
4032 dp = &prefix_user_table[dp->op[1].bytemode][index];
4033 break;
4034
4035 case X86_64_SPECIAL:
4036 index = address_mode == mode_64bit ? 1 : 0;
4037 dp = &x86_64_table[dp->op[1].bytemode][index];
4038 break;
4039
4040 default:
4041 oappend (INTERNAL_DISASSEMBLER_ERROR);
4042 break;
4043 }
4044 }
4045
4046 if (dp->name != NULL && putop (dp->name, sizeflag) == 0)
4047 {
4048 for (i = 0; i < MAX_OPERANDS; ++i)
4049 {
4050 obufp = op_out[i];
4051 op_ad = MAX_OPERANDS - 1 - i;
4052 if (dp->op[i].rtn)
4053 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
4054 }
4055 }
4056 }
4057
4058
4059
4060
4061
4062 if ((prefixes & ~used_prefixes) != 0)
4063 {
4064 const char *name;
4065
4066 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
4067 if (name == NULL)
4068 name = INTERNAL_DISASSEMBLER_ERROR;
4069 (*info->fprintf_func) (info->stream, "%s", name);
4070 return 1;
4071 }
4072 if (rex & ~rex_used)
4073 {
4074 const char *name;
4075 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
4076 if (name == NULL)
4077 name = INTERNAL_DISASSEMBLER_ERROR;
4078 (*info->fprintf_func) (info->stream, "%s ", name);
4079 }
4080
4081 obufp = obuf + strlen (obuf);
4082 for (i = strlen (obuf); i < 6; i++)
4083 oappend (" ");
4084 oappend (" ");
4085 (*info->fprintf_func) (info->stream, "%s", obuf);
4086
4087
4088
4089 if (intel_syntax || two_source_ops)
4090 {
4091 bfd_vma riprel;
4092
4093 for (i = 0; i < MAX_OPERANDS; ++i)
4094 op_txt[i] = op_out[i];
4095
4096 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
4097 {
4098 op_ad = op_index[i];
4099 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
4100 op_index[MAX_OPERANDS - 1 - i] = op_ad;
4101 riprel = op_riprel[i];
4102 op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
4103 op_riprel[MAX_OPERANDS - 1 - i] = riprel;
4104 }
4105 }
4106 else
4107 {
4108 for (i = 0; i < MAX_OPERANDS; ++i)
4109 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
4110 }
4111
4112 needcomma = 0;
4113 for (i = 0; i < MAX_OPERANDS; ++i)
4114 if (*op_txt[i])
4115 {
4116 if (needcomma)
4117 (*info->fprintf_func) (info->stream, ",");
4118 if (op_index[i] != -1 && !op_riprel[i])
4119 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
4120 else
4121 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
4122 needcomma = 1;
4123 }
4124
4125 for (i = 0; i < MAX_OPERANDS; i++)
4126 if (op_index[i] != -1 && op_riprel[i])
4127 {
4128 (*info->fprintf_func) (info->stream, " # ");
4129 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
4130 + op_address[op_index[i]]), info);
4131 break;
4132 }
4133 return codep - priv.the_buffer;
4134}
4135
4136static const char *float_mem[] = {
4137
4138 "fadd{s||s|}",
4139 "fmul{s||s|}",
4140 "fcom{s||s|}",
4141 "fcomp{s||s|}",
4142 "fsub{s||s|}",
4143 "fsubr{s||s|}",
4144 "fdiv{s||s|}",
4145 "fdivr{s||s|}",
4146
4147 "fld{s||s|}",
4148 "(bad)",
4149 "fst{s||s|}",
4150 "fstp{s||s|}",
4151 "fldenvIC",
4152 "fldcw",
4153 "fNstenvIC",
4154 "fNstcw",
4155
4156 "fiadd{l||l|}",
4157 "fimul{l||l|}",
4158 "ficom{l||l|}",
4159 "ficomp{l||l|}",
4160 "fisub{l||l|}",
4161 "fisubr{l||l|}",
4162 "fidiv{l||l|}",
4163 "fidivr{l||l|}",
4164
4165 "fild{l||l|}",
4166 "fisttp{l||l|}",
4167 "fist{l||l|}",
4168 "fistp{l||l|}",
4169 "(bad)",
4170 "fld{t||t|}",
4171 "(bad)",
4172 "fstp{t||t|}",
4173
4174 "fadd{l||l|}",
4175 "fmul{l||l|}",
4176 "fcom{l||l|}",
4177 "fcomp{l||l|}",
4178 "fsub{l||l|}",
4179 "fsubr{l||l|}",
4180 "fdiv{l||l|}",
4181 "fdivr{l||l|}",
4182
4183 "fld{l||l|}",
4184 "fisttp{ll||ll|}",
4185 "fst{l||l|}",
4186 "fstp{l||l|}",
4187 "frstorIC",
4188 "(bad)",
4189 "fNsaveIC",
4190 "fNstsw",
4191
4192 "fiadd",
4193 "fimul",
4194 "ficom",
4195 "ficomp",
4196 "fisub",
4197 "fisubr",
4198 "fidiv",
4199 "fidivr",
4200
4201 "fild",
4202 "fisttp",
4203 "fist",
4204 "fistp",
4205 "fbld",
4206 "fild{ll||ll|}",
4207 "fbstp",
4208 "fistp{ll||ll|}",
4209};
4210
4211static const unsigned char float_mem_mode[] = {
4212
4213 d_mode,
4214 d_mode,
4215 d_mode,
4216 d_mode,
4217 d_mode,
4218 d_mode,
4219 d_mode,
4220 d_mode,
4221
4222 d_mode,
4223 0,
4224 d_mode,
4225 d_mode,
4226 0,
4227 w_mode,
4228 0,
4229 w_mode,
4230
4231 d_mode,
4232 d_mode,
4233 d_mode,
4234 d_mode,
4235 d_mode,
4236 d_mode,
4237 d_mode,
4238 d_mode,
4239
4240 d_mode,
4241 d_mode,
4242 d_mode,
4243 d_mode,
4244 0,
4245 t_mode,
4246 0,
4247 t_mode,
4248
4249 q_mode,
4250 q_mode,
4251 q_mode,
4252 q_mode,
4253 q_mode,
4254 q_mode,
4255 q_mode,
4256 q_mode,
4257
4258 q_mode,
4259 q_mode,
4260 q_mode,
4261 q_mode,
4262 0,
4263 0,
4264 0,
4265 w_mode,
4266
4267 w_mode,
4268 w_mode,
4269 w_mode,
4270 w_mode,
4271 w_mode,
4272 w_mode,
4273 w_mode,
4274 w_mode,
4275
4276 w_mode,
4277 w_mode,
4278 w_mode,
4279 w_mode,
4280 t_mode,
4281 q_mode,
4282 t_mode,
4283 q_mode
4284};
4285
4286#define ST { OP_ST, 0 }
4287#define STi { OP_STi, 0 }
4288
4289#define FGRPd9_2 NULL, { { NULL, 0 } }
4290#define FGRPd9_4 NULL, { { NULL, 1 } }
4291#define FGRPd9_5 NULL, { { NULL, 2 } }
4292#define FGRPd9_6 NULL, { { NULL, 3 } }
4293#define FGRPd9_7 NULL, { { NULL, 4 } }
4294#define FGRPda_5 NULL, { { NULL, 5 } }
4295#define FGRPdb_4 NULL, { { NULL, 6 } }
4296#define FGRPde_3 NULL, { { NULL, 7 } }
4297#define FGRPdf_4 NULL, { { NULL, 8 } }
4298
4299static const struct dis386 float_reg[][8] = {
4300
4301 {
4302 { "fadd", { ST, STi } },
4303 { "fmul", { ST, STi } },
4304 { "fcom", { STi } },
4305 { "fcomp", { STi } },
4306 { "fsub", { ST, STi } },
4307 { "fsubr", { ST, STi } },
4308 { "fdiv", { ST, STi } },
4309 { "fdivr", { ST, STi } },
4310 },
4311
4312 {
4313 { "fld", { STi } },
4314 { "fxch", { STi } },
4315 { FGRPd9_2 },
4316 { "(bad)", { XX } },
4317 { FGRPd9_4 },
4318 { FGRPd9_5 },
4319 { FGRPd9_6 },
4320 { FGRPd9_7 },
4321 },
4322
4323 {
4324 { "fcmovb", { ST, STi } },
4325 { "fcmove", { ST, STi } },
4326 { "fcmovbe",{ ST, STi } },
4327 { "fcmovu", { ST, STi } },
4328 { "(bad)", { XX } },
4329 { FGRPda_5 },
4330 { "(bad)", { XX } },
4331 { "(bad)", { XX } },
4332 },
4333
4334 {
4335 { "fcmovnb",{ ST, STi } },
4336 { "fcmovne",{ ST, STi } },
4337 { "fcmovnbe",{ ST, STi } },
4338 { "fcmovnu",{ ST, STi } },
4339 { FGRPdb_4 },
4340 { "fucomi", { ST, STi } },
4341 { "fcomi", { ST, STi } },
4342 { "(bad)", { XX } },
4343 },
4344
4345 {
4346 { "fadd", { STi, ST } },
4347 { "fmul", { STi, ST } },
4348 { "(bad)", { XX } },
4349 { "(bad)", { XX } },
4350#if SYSV386_COMPAT
4351 { "fsub", { STi, ST } },
4352 { "fsubr", { STi, ST } },
4353 { "fdiv", { STi, ST } },
4354 { "fdivr", { STi, ST } },
4355#else
4356 { "fsubr", { STi, ST } },
4357 { "fsub", { STi, ST } },
4358 { "fdivr", { STi, ST } },
4359 { "fdiv", { STi, ST } },
4360#endif
4361 },
4362
4363 {
4364 { "ffree", { STi } },
4365 { "(bad)", { XX } },
4366 { "fst", { STi } },
4367 { "fstp", { STi } },
4368 { "fucom", { STi } },
4369 { "fucomp", { STi } },
4370 { "(bad)", { XX } },
4371 { "(bad)", { XX } },
4372 },
4373
4374 {
4375 { "faddp", { STi, ST } },
4376 { "fmulp", { STi, ST } },
4377 { "(bad)", { XX } },
4378 { FGRPde_3 },
4379#if SYSV386_COMPAT
4380 { "fsubp", { STi, ST } },
4381 { "fsubrp", { STi, ST } },
4382 { "fdivp", { STi, ST } },
4383 { "fdivrp", { STi, ST } },
4384#else
4385 { "fsubrp", { STi, ST } },
4386 { "fsubp", { STi, ST } },
4387 { "fdivrp", { STi, ST } },
4388 { "fdivp", { STi, ST } },
4389#endif
4390 },
4391
4392 {
4393 { "ffreep", { STi } },
4394 { "(bad)", { XX } },
4395 { "(bad)", { XX } },
4396 { "(bad)", { XX } },
4397 { FGRPdf_4 },
4398 { "fucomip", { ST, STi } },
4399 { "fcomip", { ST, STi } },
4400 { "(bad)", { XX } },
4401 },
4402};
4403
4404static const char *fgrps[][8] = {
4405
4406 {
4407 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4408 },
4409
4410
4411 {
4412 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
4413 },
4414
4415
4416 {
4417 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
4418 },
4419
4420
4421 {
4422 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
4423 },
4424
4425
4426 {
4427 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
4428 },
4429
4430
4431 {
4432 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4433 },
4434
4435
4436 {
4437 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
4438 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
4439 },
4440
4441
4442 {
4443 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4444 },
4445
4446
4447 {
4448 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
4449 },
4450};
4451
4452static void
4453dofloat (int sizeflag)
4454{
4455 const struct dis386 *dp;
4456 unsigned char floatop;
4457
4458 floatop = codep[-1];
4459
4460 if (modrm.mod != 3)
4461 {
4462 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
4463
4464 putop (float_mem[fp_indx], sizeflag);
4465 obufp = op_out[0];
4466 op_ad = 2;
4467 OP_E (float_mem_mode[fp_indx], sizeflag);
4468 return;
4469 }
4470
4471 MODRM_CHECK;
4472 codep++;
4473
4474 dp = &float_reg[floatop - 0xd8][modrm.reg];
4475 if (dp->name == NULL)
4476 {
4477 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
4478
4479
4480 if (floatop == 0xdf && codep[-1] == 0xe0)
4481 pstrcpy (op_out[0], sizeof(op_out[0]), names16[0]);
4482 }
4483 else
4484 {
4485 putop (dp->name, sizeflag);
4486
4487 obufp = op_out[0];
4488 op_ad = 2;
4489 if (dp->op[0].rtn)
4490 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
4491
4492 obufp = op_out[1];
4493 op_ad = 1;
4494 if (dp->op[1].rtn)
4495 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
4496 }
4497}
4498
4499static void
4500OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4501{
4502 oappend ("%st" + intel_syntax);
4503}
4504
4505static void
4506OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4507{
4508 snprintf (scratchbuf, sizeof(scratchbuf), "%%st(%d)", modrm.rm);
4509 oappend (scratchbuf + intel_syntax);
4510}
4511
4512
4513static int
4514putop (const char *template, int sizeflag)
4515{
4516 const char *p;
4517 int alt = 0;
4518
4519 for (p = template; *p; p++)
4520 {
4521 switch (*p)
4522 {
4523 default:
4524 *obufp++ = *p;
4525 break;
4526 case '{':
4527 alt = 0;
4528 if (intel_syntax)
4529 alt += 1;
4530 if (address_mode == mode_64bit)
4531 alt += 2;
4532 while (alt != 0)
4533 {
4534 while (*++p != '|')
4535 {
4536 if (*p == '}')
4537 {
4538
4539 pstrcpy (obuf, sizeof(obuf), "(bad)");
4540 obufp = obuf + 5;
4541 return 1;
4542 }
4543 else if (*p == '\0')
4544 abort ();
4545 }
4546 alt--;
4547 }
4548
4549 case 'I':
4550 alt = 1;
4551 continue;
4552 case '|':
4553 while (*++p != '}')
4554 {
4555 if (*p == '\0')
4556 abort ();
4557 }
4558 break;
4559 case '}':
4560 break;
4561 case 'A':
4562 if (intel_syntax)
4563 break;
4564 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4565 *obufp++ = 'b';
4566 break;
4567 case 'B':
4568 if (intel_syntax)
4569 break;
4570 if (sizeflag & SUFFIX_ALWAYS)
4571 *obufp++ = 'b';
4572 break;
4573 case 'C':
4574 if (intel_syntax && !alt)
4575 break;
4576 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
4577 {
4578 if (sizeflag & DFLAG)
4579 *obufp++ = intel_syntax ? 'd' : 'l';
4580 else
4581 *obufp++ = intel_syntax ? 'w' : 's';
4582 used_prefixes |= (prefixes & PREFIX_DATA);
4583 }
4584 break;
4585 case 'D':
4586 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
4587 break;
4588 USED_REX (REX_W);
4589 if (modrm.mod == 3)
4590 {
4591 if (rex & REX_W)
4592 *obufp++ = 'q';
4593 else if (sizeflag & DFLAG)
4594 *obufp++ = intel_syntax ? 'd' : 'l';
4595 else
4596 *obufp++ = 'w';
4597 used_prefixes |= (prefixes & PREFIX_DATA);
4598 }
4599 else
4600 *obufp++ = 'w';
4601 break;
4602 case 'E':
4603 if (address_mode == mode_64bit)
4604 {
4605 if (sizeflag & AFLAG)
4606 *obufp++ = 'r';
4607 else
4608 *obufp++ = 'e';
4609 }
4610 else
4611 if (sizeflag & AFLAG)
4612 *obufp++ = 'e';
4613 used_prefixes |= (prefixes & PREFIX_ADDR);
4614 break;
4615 case 'F':
4616 if (intel_syntax)
4617 break;
4618 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
4619 {
4620 if (sizeflag & AFLAG)
4621 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
4622 else
4623 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
4624 used_prefixes |= (prefixes & PREFIX_ADDR);
4625 }
4626 break;
4627 case 'G':
4628 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
4629 break;
4630 if ((rex & REX_W) || (sizeflag & DFLAG))
4631 *obufp++ = 'l';
4632 else
4633 *obufp++ = 'w';
4634 if (!(rex & REX_W))
4635 used_prefixes |= (prefixes & PREFIX_DATA);
4636 break;
4637 case 'H':
4638 if (intel_syntax)
4639 break;
4640 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
4641 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
4642 {
4643 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
4644 *obufp++ = ',';
4645 *obufp++ = 'p';
4646 if (prefixes & PREFIX_DS)
4647 *obufp++ = 't';
4648 else
4649 *obufp++ = 'n';
4650 }
4651 break;
4652 case 'J':
4653 if (intel_syntax)
4654 break;
4655 *obufp++ = 'l';
4656 break;
4657 case 'K':
4658 USED_REX (REX_W);
4659 if (rex & REX_W)
4660 *obufp++ = 'q';
4661 else
4662 *obufp++ = 'd';
4663 break;
4664 case 'Z':
4665 if (intel_syntax)
4666 break;
4667 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
4668 {
4669 *obufp++ = 'q';
4670 break;
4671 }
4672
4673 case 'L':
4674 if (intel_syntax)
4675 break;
4676 if (sizeflag & SUFFIX_ALWAYS)
4677 *obufp++ = 'l';
4678 break;
4679 case 'N':
4680 if ((prefixes & PREFIX_FWAIT) == 0)
4681 *obufp++ = 'n';
4682 else
4683 used_prefixes |= PREFIX_FWAIT;
4684 break;
4685 case 'O':
4686 USED_REX (REX_W);
4687 if (rex & REX_W)
4688 *obufp++ = 'o';
4689 else if (intel_syntax && (sizeflag & DFLAG))
4690 *obufp++ = 'q';
4691 else
4692 *obufp++ = 'd';
4693 if (!(rex & REX_W))
4694 used_prefixes |= (prefixes & PREFIX_DATA);
4695 break;
4696 case 'T':
4697 if (intel_syntax)
4698 break;
4699 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4700 {
4701 *obufp++ = 'q';
4702 break;
4703 }
4704
4705 case 'P':
4706 if (intel_syntax)
4707 break;
4708 if ((prefixes & PREFIX_DATA)
4709 || (rex & REX_W)
4710 || (sizeflag & SUFFIX_ALWAYS))
4711 {
4712 USED_REX (REX_W);
4713 if (rex & REX_W)
4714 *obufp++ = 'q';
4715 else
4716 {
4717 if (sizeflag & DFLAG)
4718 *obufp++ = 'l';
4719 else
4720 *obufp++ = 'w';
4721 }
4722 used_prefixes |= (prefixes & PREFIX_DATA);
4723 }
4724 break;
4725 case 'U':
4726 if (intel_syntax)
4727 break;
4728 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4729 {
4730 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4731 *obufp++ = 'q';
4732 break;
4733 }
4734
4735 case 'Q':
4736 if (intel_syntax && !alt)
4737 break;
4738 USED_REX (REX_W);
4739 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
4740 {
4741 if (rex & REX_W)
4742 *obufp++ = 'q';
4743 else
4744 {
4745 if (sizeflag & DFLAG)
4746 *obufp++ = intel_syntax ? 'd' : 'l';
4747 else
4748 *obufp++ = 'w';
4749 }
4750 used_prefixes |= (prefixes & PREFIX_DATA);
4751 }
4752 break;
4753 case 'R':
4754 USED_REX (REX_W);
4755 if (rex & REX_W)
4756 *obufp++ = 'q';
4757 else if (sizeflag & DFLAG)
4758 {
4759 if (intel_syntax)
4760 *obufp++ = 'd';
4761 else
4762 *obufp++ = 'l';
4763 }
4764 else
4765 *obufp++ = 'w';
4766 if (intel_syntax && !p[1]
4767 && ((rex & REX_W) || (sizeflag & DFLAG)))
4768 *obufp++ = 'e';
4769 if (!(rex & REX_W))
4770 used_prefixes |= (prefixes & PREFIX_DATA);
4771 break;
4772 case 'V':
4773 if (intel_syntax)
4774 break;
4775 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4776 {
4777 if (sizeflag & SUFFIX_ALWAYS)
4778 *obufp++ = 'q';
4779 break;
4780 }
4781
4782 case 'S':
4783 if (intel_syntax)
4784 break;
4785 if (sizeflag & SUFFIX_ALWAYS)
4786 {
4787 if (rex & REX_W)
4788 *obufp++ = 'q';
4789 else
4790 {
4791 if (sizeflag & DFLAG)
4792 *obufp++ = 'l';
4793 else
4794 *obufp++ = 'w';
4795 used_prefixes |= (prefixes & PREFIX_DATA);
4796 }
4797 }
4798 break;
4799 case 'X':
4800 if (prefixes & PREFIX_DATA)
4801 *obufp++ = 'd';
4802 else
4803 *obufp++ = 's';
4804 used_prefixes |= (prefixes & PREFIX_DATA);
4805 break;
4806 case 'Y':
4807 if (intel_syntax)
4808 break;
4809 if (rex & REX_W)
4810 {
4811 USED_REX (REX_W);
4812 *obufp++ = 'q';
4813 }
4814 break;
4815
4816 case 'W':
4817
4818 USED_REX (REX_W);
4819 if (rex & REX_W)
4820 {
4821 if (intel_syntax)
4822 *obufp++ = 'd';
4823 else
4824 *obufp++ = 'l';
4825 }
4826 else if (sizeflag & DFLAG)
4827 *obufp++ = 'w';
4828 else
4829 *obufp++ = 'b';
4830 if (!(rex & REX_W))
4831 used_prefixes |= (prefixes & PREFIX_DATA);
4832 break;
4833 }
4834 alt = 0;
4835 }
4836 *obufp = 0;
4837 return 0;
4838}
4839
4840static void
4841oappend (const char *s)
4842{
4843 strcpy (obufp, s);
4844 obufp += strlen (s);
4845}
4846
4847static void
4848append_seg (void)
4849{
4850 if (prefixes & PREFIX_CS)
4851 {
4852 used_prefixes |= PREFIX_CS;
4853 oappend ("%cs:" + intel_syntax);
4854 }
4855 if (prefixes & PREFIX_DS)
4856 {
4857 used_prefixes |= PREFIX_DS;
4858 oappend ("%ds:" + intel_syntax);
4859 }
4860 if (prefixes & PREFIX_SS)
4861 {
4862 used_prefixes |= PREFIX_SS;
4863 oappend ("%ss:" + intel_syntax);
4864 }
4865 if (prefixes & PREFIX_ES)
4866 {
4867 used_prefixes |= PREFIX_ES;
4868 oappend ("%es:" + intel_syntax);
4869 }
4870 if (prefixes & PREFIX_FS)
4871 {
4872 used_prefixes |= PREFIX_FS;
4873 oappend ("%fs:" + intel_syntax);
4874 }
4875 if (prefixes & PREFIX_GS)
4876 {
4877 used_prefixes |= PREFIX_GS;
4878 oappend ("%gs:" + intel_syntax);
4879 }
4880}
4881
4882static void
4883OP_indirE (int bytemode, int sizeflag)
4884{
4885 if (!intel_syntax)
4886 oappend ("*");
4887 OP_E (bytemode, sizeflag);
4888}
4889
4890static void
4891print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp)
4892{
4893 if (address_mode == mode_64bit)
4894 {
4895 if (hex)
4896 {
4897 char tmp[30];
4898 int i;
4899 buf[0] = '0';
4900 buf[1] = 'x';
4901 snprintf_vma (tmp, sizeof(tmp), disp);
4902 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++) {
4903 }
4904 pstrcpy (buf + 2, bufsize - 2, tmp + i);
4905 }
4906 else
4907 {
4908 bfd_signed_vma v = disp;
4909 char tmp[30];
4910 int i;
4911 if (v < 0)
4912 {
4913 *(buf++) = '-';
4914 v = -disp;
4915
4916 if (v < 0)
4917 {
4918 pstrcpy (buf, bufsize, "9223372036854775808");
4919 return;
4920 }
4921 }
4922 if (!v)
4923 {
4924 pstrcpy (buf, bufsize, "0");
4925 return;
4926 }
4927
4928 i = 0;
4929 tmp[29] = 0;
4930 while (v)
4931 {
4932 tmp[28 - i] = (v % 10) + '0';
4933 v /= 10;
4934 i++;
4935 }
4936 pstrcpy (buf, bufsize, tmp + 29 - i);
4937 }
4938 }
4939 else
4940 {
4941 if (hex)
4942 snprintf (buf, bufsize, "0x%x", (unsigned int) disp);
4943 else
4944 snprintf (buf, bufsize, "%d", (int) disp);
4945 }
4946}
4947
4948
4949
4950static void
4951print_displacement (char *buf, bfd_vma disp)
4952{
4953 bfd_signed_vma val = disp;
4954 char tmp[30];
4955 int i, j = 0;
4956
4957 if (val < 0)
4958 {
4959 buf[j++] = '-';
4960 val = -disp;
4961
4962
4963 if (val < 0)
4964 {
4965 switch (address_mode)
4966 {
4967 case mode_64bit:
4968 strcpy (buf + j, "0x8000000000000000");
4969 break;
4970 case mode_32bit:
4971 strcpy (buf + j, "0x80000000");
4972 break;
4973 case mode_16bit:
4974 strcpy (buf + j, "0x8000");
4975 break;
4976 }
4977 return;
4978 }
4979 }
4980
4981 buf[j++] = '0';
4982 buf[j++] = 'x';
4983
4984 snprintf_vma (tmp, sizeof(tmp), val);
4985 for (i = 0; tmp[i] == '0'; i++)
4986 continue;
4987 if (tmp[i] == '\0')
4988 i--;
4989 strcpy (buf + j, tmp + i);
4990}
4991
4992static void
4993intel_operand_size (int bytemode, int sizeflag)
4994{
4995 switch (bytemode)
4996 {
4997 case b_mode:
4998 case dqb_mode:
4999 oappend ("BYTE PTR ");
5000 break;
5001 case w_mode:
5002 case dqw_mode:
5003 oappend ("WORD PTR ");
5004 break;
5005 case stack_v_mode:
5006 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5007 {
5008 oappend ("QWORD PTR ");
5009 used_prefixes |= (prefixes & PREFIX_DATA);
5010 break;
5011 }
5012
5013 case v_mode:
5014 case dq_mode:
5015 USED_REX (REX_W);
5016 if (rex & REX_W)
5017 oappend ("QWORD PTR ");
5018 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
5019 oappend ("DWORD PTR ");
5020 else
5021 oappend ("WORD PTR ");
5022 used_prefixes |= (prefixes & PREFIX_DATA);
5023 break;
5024 case z_mode:
5025 if ((rex & REX_W) || (sizeflag & DFLAG))
5026 *obufp++ = 'D';
5027 oappend ("WORD PTR ");
5028 if (!(rex & REX_W))
5029 used_prefixes |= (prefixes & PREFIX_DATA);
5030 break;
5031 case d_mode:
5032 case dqd_mode:
5033 oappend ("DWORD PTR ");
5034 break;
5035 case q_mode:
5036 oappend ("QWORD PTR ");
5037 break;
5038 case m_mode:
5039 if (address_mode == mode_64bit)
5040 oappend ("QWORD PTR ");
5041 else
5042 oappend ("DWORD PTR ");
5043 break;
5044 case f_mode:
5045 if (sizeflag & DFLAG)
5046 oappend ("FWORD PTR ");
5047 else
5048 oappend ("DWORD PTR ");
5049 used_prefixes |= (prefixes & PREFIX_DATA);
5050 break;
5051 case t_mode:
5052 oappend ("TBYTE PTR ");
5053 break;
5054 case x_mode:
5055 oappend ("XMMWORD PTR ");
5056 break;
5057 case o_mode:
5058 oappend ("OWORD PTR ");
5059 break;
5060 default:
5061 break;
5062 }
5063}
5064
5065static void
5066OP_E (int bytemode, int sizeflag)
5067{
5068 bfd_vma disp;
5069 int add = 0;
5070 int riprel = 0;
5071 USED_REX (REX_B);
5072 if (rex & REX_B)
5073 add += 8;
5074
5075
5076 MODRM_CHECK;
5077 codep++;
5078
5079 if (modrm.mod == 3)
5080 {
5081 switch (bytemode)
5082 {
5083 case b_mode:
5084 USED_REX (0);
5085 if (rex)
5086 oappend (names8rex[modrm.rm + add]);
5087 else
5088 oappend (names8[modrm.rm + add]);
5089 break;
5090 case w_mode:
5091 oappend (names16[modrm.rm + add]);
5092 break;
5093 case d_mode:
5094 oappend (names32[modrm.rm + add]);
5095 break;
5096 case q_mode:
5097 oappend (names64[modrm.rm + add]);
5098 break;
5099 case m_mode:
5100 if (address_mode == mode_64bit)
5101 oappend (names64[modrm.rm + add]);
5102 else
5103 oappend (names32[modrm.rm + add]);
5104 break;
5105 case stack_v_mode:
5106 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5107 {
5108 oappend (names64[modrm.rm + add]);
5109 used_prefixes |= (prefixes & PREFIX_DATA);
5110 break;
5111 }
5112 bytemode = v_mode;
5113
5114 case v_mode:
5115 case dq_mode:
5116 case dqb_mode:
5117 case dqd_mode:
5118 case dqw_mode:
5119 USED_REX (REX_W);
5120 if (rex & REX_W)
5121 oappend (names64[modrm.rm + add]);
5122 else if ((sizeflag & DFLAG) || bytemode != v_mode)
5123 oappend (names32[modrm.rm + add]);
5124 else
5125 oappend (names16[modrm.rm + add]);
5126 used_prefixes |= (prefixes & PREFIX_DATA);
5127 break;
5128 case 0:
5129 break;
5130 default:
5131 oappend (INTERNAL_DISASSEMBLER_ERROR);
5132 break;
5133 }
5134 return;
5135 }
5136
5137 disp = 0;
5138 if (intel_syntax)
5139 intel_operand_size (bytemode, sizeflag);
5140 append_seg ();
5141
5142 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5143 {
5144
5145 int havedisp;
5146 int havesib;
5147 int havebase;
5148 int base;
5149 int index = 0;
5150 int scale = 0;
5151
5152 havesib = 0;
5153 havebase = 1;
5154 base = modrm.rm;
5155
5156 if (base == 4)
5157 {
5158 havesib = 1;
5159 fetch_data(the_info, codep + 1);
5160 index = (*codep >> 3) & 7;
5161 if (address_mode == mode_64bit || index != 0x4)
5162
5163 scale = (*codep >> 6) & 3;
5164 base = *codep & 7;
5165 USED_REX (REX_X);
5166 if (rex & REX_X)
5167 index += 8;
5168 codep++;
5169 }
5170 base += add;
5171
5172 switch (modrm.mod)
5173 {
5174 case 0:
5175 if ((base & 7) == 5)
5176 {
5177 havebase = 0;
5178 if (address_mode == mode_64bit && !havesib)
5179 riprel = 1;
5180 disp = get32s ();
5181 }
5182 break;
5183 case 1:
5184 fetch_data (the_info, codep + 1);
5185 disp = *codep++;
5186 if ((disp & 0x80) != 0)
5187 disp -= 0x100;
5188 break;
5189 case 2:
5190 disp = get32s ();
5191 break;
5192 }
5193
5194 havedisp = havebase || (havesib && (index != 4 || scale != 0));
5195
5196 if (!intel_syntax)
5197 if (modrm.mod != 0 || (base & 7) == 5)
5198 {
5199 if (havedisp || riprel)
5200 print_displacement (scratchbuf, disp);
5201 else
5202 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5203 oappend (scratchbuf);
5204 if (riprel)
5205 {
5206 set_op (disp, 1);
5207 oappend ("(%rip)");
5208 }
5209 }
5210
5211 if (havedisp || (intel_syntax && riprel))
5212 {
5213 *obufp++ = open_char;
5214 if (intel_syntax && riprel)
5215 {
5216 set_op (disp, 1);
5217 oappend ("rip");
5218 }
5219 *obufp = '\0';
5220 if (havebase)
5221 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5222 ? names64[base] : names32[base]);
5223 if (havesib)
5224 {
5225 if (index != 4)
5226 {
5227 if (!intel_syntax || havebase)
5228 {
5229 *obufp++ = separator_char;
5230 *obufp = '\0';
5231 }
5232 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
5233 ? names64[index] : names32[index]);
5234 }
5235 if (scale != 0 || (!intel_syntax && index != 4))
5236 {
5237 *obufp++ = scale_char;
5238 *obufp = '\0';
5239 snprintf (scratchbuf, sizeof(scratchbuf), "%d", 1 << scale);
5240 oappend (scratchbuf);
5241 }
5242 }
5243 if (intel_syntax
5244 && (disp || modrm.mod != 0 || (base & 7) == 5))
5245 {
5246 if ((bfd_signed_vma) disp >= 0)
5247 {
5248 *obufp++ = '+';
5249 *obufp = '\0';
5250 }
5251 else if (modrm.mod != 1)
5252 {
5253 *obufp++ = '-';
5254 *obufp = '\0';
5255 disp = - (bfd_signed_vma) disp;
5256 }
5257
5258 print_displacement (scratchbuf, disp);
5259 oappend (scratchbuf);
5260 }
5261
5262 *obufp++ = close_char;
5263 *obufp = '\0';
5264 }
5265 else if (intel_syntax)
5266 {
5267 if (modrm.mod != 0 || (base & 7) == 5)
5268 {
5269 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5270 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5271 ;
5272 else
5273 {
5274 oappend (names_seg[ds_reg - es_reg]);
5275 oappend (":");
5276 }
5277 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5278 oappend (scratchbuf);
5279 }
5280 }
5281 }
5282 else
5283 {
5284 switch (modrm.mod)
5285 {
5286 case 0:
5287 if (modrm.rm == 6)
5288 {
5289 disp = get16 ();
5290 if ((disp & 0x8000) != 0)
5291 disp -= 0x10000;
5292 }
5293 break;
5294 case 1:
5295 fetch_data(the_info, codep + 1);
5296 disp = *codep++;
5297 if ((disp & 0x80) != 0)
5298 disp -= 0x100;
5299 break;
5300 case 2:
5301 disp = get16 ();
5302 if ((disp & 0x8000) != 0)
5303 disp -= 0x10000;
5304 break;
5305 }
5306
5307 if (!intel_syntax)
5308 if (modrm.mod != 0 || modrm.rm == 6)
5309 {
5310 print_displacement (scratchbuf, disp);
5311 oappend (scratchbuf);
5312 }
5313
5314 if (modrm.mod != 0 || modrm.rm != 6)
5315 {
5316 *obufp++ = open_char;
5317 *obufp = '\0';
5318 oappend (index16[modrm.rm]);
5319 if (intel_syntax
5320 && (disp || modrm.mod != 0 || modrm.rm == 6))
5321 {
5322 if ((bfd_signed_vma) disp >= 0)
5323 {
5324 *obufp++ = '+';
5325 *obufp = '\0';
5326 }
5327 else if (modrm.mod != 1)
5328 {
5329 *obufp++ = '-';
5330 *obufp = '\0';
5331 disp = - (bfd_signed_vma) disp;
5332 }
5333
5334 print_displacement (scratchbuf, disp);
5335 oappend (scratchbuf);
5336 }
5337
5338 *obufp++ = close_char;
5339 *obufp = '\0';
5340 }
5341 else if (intel_syntax)
5342 {
5343 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5344 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
5345 ;
5346 else
5347 {
5348 oappend (names_seg[ds_reg - es_reg]);
5349 oappend (":");
5350 }
5351 print_operand_value (scratchbuf, sizeof(scratchbuf), 1,
5352 disp & 0xffff);
5353 oappend (scratchbuf);
5354 }
5355 }
5356}
5357
5358static void
5359OP_G (int bytemode, int sizeflag)
5360{
5361 int add = 0;
5362 USED_REX (REX_R);
5363 if (rex & REX_R)
5364 add += 8;
5365 switch (bytemode)
5366 {
5367 case b_mode:
5368 USED_REX (0);
5369 if (rex)
5370 oappend (names8rex[modrm.reg + add]);
5371 else
5372 oappend (names8[modrm.reg + add]);
5373 break;
5374 case w_mode:
5375 oappend (names16[modrm.reg + add]);
5376 break;
5377 case d_mode:
5378 oappend (names32[modrm.reg + add]);
5379 break;
5380 case q_mode:
5381 oappend (names64[modrm.reg + add]);
5382 break;
5383 case v_mode:
5384 case dq_mode:
5385 case dqb_mode:
5386 case dqd_mode:
5387 case dqw_mode:
5388 USED_REX (REX_W);
5389 if (rex & REX_W)
5390 oappend (names64[modrm.reg + add]);
5391 else if ((sizeflag & DFLAG) || bytemode != v_mode)
5392 oappend (names32[modrm.reg + add]);
5393 else
5394 oappend (names16[modrm.reg + add]);
5395 used_prefixes |= (prefixes & PREFIX_DATA);
5396 break;
5397 case m_mode:
5398 if (address_mode == mode_64bit)
5399 oappend (names64[modrm.reg + add]);
5400 else
5401 oappend (names32[modrm.reg + add]);
5402 break;
5403 default:
5404 oappend (INTERNAL_DISASSEMBLER_ERROR);
5405 break;
5406 }
5407}
5408
5409static void
5410OP_vvvv (int bytemode, int sizeflags)
5411{
5412 USED_REX (REX_W);
5413 if (rex & REX_W) {
5414 oappend(names64[vex_reg]);
5415 } else {
5416 oappend(names32[vex_reg]);
5417 }
5418}
5419
5420static bfd_vma
5421get64 (void)
5422{
5423 bfd_vma x;
5424#ifdef BFD64
5425 unsigned int a;
5426 unsigned int b;
5427
5428 fetch_data(the_info, codep + 8);
5429 a = *codep++ & 0xff;
5430 a |= (*codep++ & 0xff) << 8;
5431 a |= (*codep++ & 0xff) << 16;
5432 a |= (*codep++ & 0xff) << 24;
5433 b = *codep++ & 0xff;
5434 b |= (*codep++ & 0xff) << 8;
5435 b |= (*codep++ & 0xff) << 16;
5436 b |= (*codep++ & 0xff) << 24;
5437 x = a + ((bfd_vma) b << 32);
5438#else
5439 abort ();
5440 x = 0;
5441#endif
5442 return x;
5443}
5444
5445static bfd_signed_vma
5446get32 (void)
5447{
5448 bfd_signed_vma x = 0;
5449
5450 fetch_data(the_info, codep + 4);
5451 x = *codep++ & (bfd_signed_vma) 0xff;
5452 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5453 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5454 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5455 return x;
5456}
5457
5458static bfd_signed_vma
5459get32s (void)
5460{
5461 bfd_signed_vma x = 0;
5462
5463 fetch_data(the_info, codep + 4);
5464 x = *codep++ & (bfd_signed_vma) 0xff;
5465 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
5466 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
5467 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
5468
5469 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
5470
5471 return x;
5472}
5473
5474static int
5475get16 (void)
5476{
5477 int x = 0;
5478
5479 fetch_data(the_info, codep + 2);
5480 x = *codep++ & 0xff;
5481 x |= (*codep++ & 0xff) << 8;
5482 return x;
5483}
5484
5485static void
5486set_op (bfd_vma op, int riprel)
5487{
5488 op_index[op_ad] = op_ad;
5489 if (address_mode == mode_64bit)
5490 {
5491 op_address[op_ad] = op;
5492 op_riprel[op_ad] = riprel;
5493 }
5494 else
5495 {
5496
5497 op_address[op_ad] = op & 0xffffffff;
5498 op_riprel[op_ad] = riprel & 0xffffffff;
5499 }
5500}
5501
5502static void
5503OP_REG (int code, int sizeflag)
5504{
5505 const char *s;
5506 int add = 0;
5507 USED_REX (REX_B);
5508 if (rex & REX_B)
5509 add = 8;
5510
5511 switch (code)
5512 {
5513 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5514 case sp_reg: case bp_reg: case si_reg: case di_reg:
5515 s = names16[code - ax_reg + add];
5516 break;
5517 case es_reg: case ss_reg: case cs_reg:
5518 case ds_reg: case fs_reg: case gs_reg:
5519 s = names_seg[code - es_reg + add];
5520 break;
5521 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5522 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5523 USED_REX (0);
5524 if (rex)
5525 s = names8rex[code - al_reg + add];
5526 else
5527 s = names8[code - al_reg];
5528 break;
5529 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
5530 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
5531 if (address_mode == mode_64bit && (sizeflag & DFLAG))
5532 {
5533 s = names64[code - rAX_reg + add];
5534 break;
5535 }
5536 code += eAX_reg - rAX_reg;
5537
5538 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5539 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5540 USED_REX (REX_W);
5541 if (rex & REX_W)
5542 s = names64[code - eAX_reg + add];
5543 else if (sizeflag & DFLAG)
5544 s = names32[code - eAX_reg + add];
5545 else
5546 s = names16[code - eAX_reg + add];
5547 used_prefixes |= (prefixes & PREFIX_DATA);
5548 break;
5549 default:
5550 s = INTERNAL_DISASSEMBLER_ERROR;
5551 break;
5552 }
5553 oappend (s);
5554}
5555
5556static void
5557OP_IMREG (int code, int sizeflag)
5558{
5559 const char *s;
5560
5561 switch (code)
5562 {
5563 case indir_dx_reg:
5564 if (intel_syntax)
5565 s = "dx";
5566 else
5567 s = "(%dx)";
5568 break;
5569 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
5570 case sp_reg: case bp_reg: case si_reg: case di_reg:
5571 s = names16[code - ax_reg];
5572 break;
5573 case es_reg: case ss_reg: case cs_reg:
5574 case ds_reg: case fs_reg: case gs_reg:
5575 s = names_seg[code - es_reg];
5576 break;
5577 case al_reg: case ah_reg: case cl_reg: case ch_reg:
5578 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
5579 USED_REX (0);
5580 if (rex)
5581 s = names8rex[code - al_reg];
5582 else
5583 s = names8[code - al_reg];
5584 break;
5585 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
5586 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
5587 USED_REX (REX_W);
5588 if (rex & REX_W)
5589 s = names64[code - eAX_reg];
5590 else if (sizeflag & DFLAG)
5591 s = names32[code - eAX_reg];
5592 else
5593 s = names16[code - eAX_reg];
5594 used_prefixes |= (prefixes & PREFIX_DATA);
5595 break;
5596 case z_mode_ax_reg:
5597 if ((rex & REX_W) || (sizeflag & DFLAG))
5598 s = *names32;
5599 else
5600 s = *names16;
5601 if (!(rex & REX_W))
5602 used_prefixes |= (prefixes & PREFIX_DATA);
5603 break;
5604 default:
5605 s = INTERNAL_DISASSEMBLER_ERROR;
5606 break;
5607 }
5608 oappend (s);
5609}
5610
5611static void
5612OP_I (int bytemode, int sizeflag)
5613{
5614 bfd_signed_vma op;
5615 bfd_signed_vma mask = -1;
5616
5617 switch (bytemode)
5618 {
5619 case b_mode:
5620 fetch_data(the_info, codep + 1);
5621 op = *codep++;
5622 mask = 0xff;
5623 break;
5624 case q_mode:
5625 if (address_mode == mode_64bit)
5626 {
5627 op = get32s ();
5628 break;
5629 }
5630
5631 case v_mode:
5632 USED_REX (REX_W);
5633 if (rex & REX_W)
5634 op = get32s ();
5635 else if (sizeflag & DFLAG)
5636 {
5637 op = get32 ();
5638 mask = 0xffffffff;
5639 }
5640 else
5641 {
5642 op = get16 ();
5643 mask = 0xfffff;
5644 }
5645 used_prefixes |= (prefixes & PREFIX_DATA);
5646 break;
5647 case w_mode:
5648 mask = 0xfffff;
5649 op = get16 ();
5650 break;
5651 case const_1_mode:
5652 if (intel_syntax)
5653 oappend ("1");
5654 return;
5655 default:
5656 oappend (INTERNAL_DISASSEMBLER_ERROR);
5657 return;
5658 }
5659
5660 op &= mask;
5661 scratchbuf[0] = '$';
5662 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5663 oappend (scratchbuf + intel_syntax);
5664 scratchbuf[0] = '\0';
5665}
5666
5667static void
5668OP_I64 (int bytemode, int sizeflag)
5669{
5670 bfd_signed_vma op;
5671 bfd_signed_vma mask = -1;
5672
5673 if (address_mode != mode_64bit)
5674 {
5675 OP_I (bytemode, sizeflag);
5676 return;
5677 }
5678
5679 switch (bytemode)
5680 {
5681 case b_mode:
5682 fetch_data(the_info, codep + 1);
5683 op = *codep++;
5684 mask = 0xff;
5685 break;
5686 case v_mode:
5687 USED_REX (REX_W);
5688 if (rex & REX_W)
5689 op = get64 ();
5690 else if (sizeflag & DFLAG)
5691 {
5692 op = get32 ();
5693 mask = 0xffffffff;
5694 }
5695 else
5696 {
5697 op = get16 ();
5698 mask = 0xfffff;
5699 }
5700 used_prefixes |= (prefixes & PREFIX_DATA);
5701 break;
5702 case w_mode:
5703 mask = 0xfffff;
5704 op = get16 ();
5705 break;
5706 default:
5707 oappend (INTERNAL_DISASSEMBLER_ERROR);
5708 return;
5709 }
5710
5711 op &= mask;
5712 scratchbuf[0] = '$';
5713 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5714 oappend (scratchbuf + intel_syntax);
5715 scratchbuf[0] = '\0';
5716}
5717
5718static void
5719OP_sI (int bytemode, int sizeflag)
5720{
5721 bfd_signed_vma op;
5722
5723 switch (bytemode)
5724 {
5725 case b_mode:
5726 fetch_data(the_info, codep + 1);
5727 op = *codep++;
5728 if ((op & 0x80) != 0)
5729 op -= 0x100;
5730 break;
5731 case v_mode:
5732 USED_REX (REX_W);
5733 if (rex & REX_W)
5734 op = get32s ();
5735 else if (sizeflag & DFLAG)
5736 {
5737 op = get32s ();
5738 }
5739 else
5740 {
5741 op = get16 ();
5742 if ((op & 0x8000) != 0)
5743 op -= 0x10000;
5744 }
5745 used_prefixes |= (prefixes & PREFIX_DATA);
5746 break;
5747 case w_mode:
5748 op = get16 ();
5749 if ((op & 0x8000) != 0)
5750 op -= 0x10000;
5751 break;
5752 default:
5753 oappend (INTERNAL_DISASSEMBLER_ERROR);
5754 return;
5755 }
5756
5757 scratchbuf[0] = '$';
5758 print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
5759 oappend (scratchbuf + intel_syntax);
5760}
5761
5762static void
5763OP_J (int bytemode, int sizeflag)
5764{
5765 bfd_vma disp;
5766 bfd_vma mask = -1;
5767 bfd_vma segment = 0;
5768
5769 switch (bytemode)
5770 {
5771 case b_mode:
5772 fetch_data(the_info, codep + 1);
5773 disp = *codep++;
5774 if ((disp & 0x80) != 0)
5775 disp -= 0x100;
5776 break;
5777 case v_mode:
5778 if ((sizeflag & DFLAG) || (rex & REX_W))
5779 disp = get32s ();
5780 else
5781 {
5782 disp = get16 ();
5783 if ((disp & 0x8000) != 0)
5784 disp -= 0x10000;
5785
5786
5787
5788
5789 mask = 0xffff;
5790 if ((prefixes & PREFIX_DATA) == 0)
5791 segment = ((start_pc + codep - start_codep)
5792 & ~((bfd_vma) 0xffff));
5793 }
5794 used_prefixes |= (prefixes & PREFIX_DATA);
5795 break;
5796 default:
5797 oappend (INTERNAL_DISASSEMBLER_ERROR);
5798 return;
5799 }
5800 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
5801 set_op (disp, 0);
5802 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
5803 oappend (scratchbuf);
5804}
5805
5806static void
5807OP_SEG (int bytemode, int sizeflag)
5808{
5809 if (bytemode == w_mode)
5810 oappend (names_seg[modrm.reg]);
5811 else
5812 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
5813}
5814
5815static void
5816OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
5817{
5818 int seg, offset;
5819
5820 if (sizeflag & DFLAG)
5821 {
5822 offset = get32 ();
5823 seg = get16 ();
5824 }
5825 else
5826 {
5827 offset = get16 ();
5828 seg = get16 ();
5829 }
5830 used_prefixes |= (prefixes & PREFIX_DATA);
5831 if (intel_syntax)
5832 snprintf (scratchbuf, sizeof(scratchbuf), "0x%x:0x%x", seg, offset);
5833 else
5834 snprintf (scratchbuf, sizeof(scratchbuf), "$0x%x,$0x%x", seg, offset);
5835 oappend (scratchbuf);
5836}
5837
5838static void
5839OP_OFF (int bytemode, int sizeflag)
5840{
5841 bfd_vma off;
5842
5843 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5844 intel_operand_size (bytemode, sizeflag);
5845 append_seg ();
5846
5847 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
5848 off = get32 ();
5849 else
5850 off = get16 ();
5851
5852 if (intel_syntax)
5853 {
5854 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5855 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5856 {
5857 oappend (names_seg[ds_reg - es_reg]);
5858 oappend (":");
5859 }
5860 }
5861 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
5862 oappend (scratchbuf);
5863}
5864
5865static void
5866OP_OFF64 (int bytemode, int sizeflag)
5867{
5868 bfd_vma off;
5869
5870 if (address_mode != mode_64bit
5871 || (prefixes & PREFIX_ADDR))
5872 {
5873 OP_OFF (bytemode, sizeflag);
5874 return;
5875 }
5876
5877 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5878 intel_operand_size (bytemode, sizeflag);
5879 append_seg ();
5880
5881 off = get64 ();
5882
5883 if (intel_syntax)
5884 {
5885 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
5886 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
5887 {
5888 oappend (names_seg[ds_reg - es_reg]);
5889 oappend (":");
5890 }
5891 }
5892 print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
5893 oappend (scratchbuf);
5894}
5895
5896static void
5897ptr_reg (int code, int sizeflag)
5898{
5899 const char *s;
5900
5901 *obufp++ = open_char;
5902 used_prefixes |= (prefixes & PREFIX_ADDR);
5903 if (address_mode == mode_64bit)
5904 {
5905 if (!(sizeflag & AFLAG))
5906 s = names32[code - eAX_reg];
5907 else
5908 s = names64[code - eAX_reg];
5909 }
5910 else if (sizeflag & AFLAG)
5911 s = names32[code - eAX_reg];
5912 else
5913 s = names16[code - eAX_reg];
5914 oappend (s);
5915 *obufp++ = close_char;
5916 *obufp = 0;
5917}
5918
5919static void
5920OP_ESreg (int code, int sizeflag)
5921{
5922 if (intel_syntax)
5923 {
5924 switch (codep[-1])
5925 {
5926 case 0x6d:
5927 intel_operand_size (z_mode, sizeflag);
5928 break;
5929 case 0xa5:
5930 case 0xa7:
5931 case 0xab:
5932 case 0xaf:
5933 intel_operand_size (v_mode, sizeflag);
5934 break;
5935 default:
5936 intel_operand_size (b_mode, sizeflag);
5937 }
5938 }
5939 oappend ("%es:" + intel_syntax);
5940 ptr_reg (code, sizeflag);
5941}
5942
5943static void
5944OP_DSreg (int code, int sizeflag)
5945{
5946 if (intel_syntax)
5947 {
5948 switch (codep[-1])
5949 {
5950 case 0x6f:
5951 intel_operand_size (z_mode, sizeflag);
5952 break;
5953 case 0xa5:
5954 case 0xa7:
5955 case 0xad:
5956 intel_operand_size (v_mode, sizeflag);
5957 break;
5958 default:
5959 intel_operand_size (b_mode, sizeflag);
5960 }
5961 }
5962 if ((prefixes
5963 & (PREFIX_CS
5964 | PREFIX_DS
5965 | PREFIX_SS
5966 | PREFIX_ES
5967 | PREFIX_FS
5968 | PREFIX_GS)) == 0)
5969 prefixes |= PREFIX_DS;
5970 append_seg ();
5971 ptr_reg (code, sizeflag);
5972}
5973
5974static void
5975OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5976{
5977 int add = 0;
5978 if (rex & REX_R)
5979 {
5980 USED_REX (REX_R);
5981 add = 8;
5982 }
5983 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5984 {
5985 used_prefixes |= PREFIX_LOCK;
5986 add = 8;
5987 }
5988 snprintf (scratchbuf, sizeof(scratchbuf), "%%cr%d", modrm.reg + add);
5989 oappend (scratchbuf + intel_syntax);
5990}
5991
5992static void
5993OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5994{
5995 int add = 0;
5996 USED_REX (REX_R);
5997 if (rex & REX_R)
5998 add = 8;
5999 if (intel_syntax)
6000 snprintf (scratchbuf, sizeof(scratchbuf), "db%d", modrm.reg + add);
6001 else
6002 snprintf (scratchbuf, sizeof(scratchbuf), "%%db%d", modrm.reg + add);
6003 oappend (scratchbuf);
6004}
6005
6006static void
6007OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6008{
6009 snprintf (scratchbuf, sizeof(scratchbuf), "%%tr%d", modrm.reg);
6010 oappend (scratchbuf + intel_syntax);
6011}
6012
6013static void
6014OP_R (int bytemode, int sizeflag)
6015{
6016 if (modrm.mod == 3)
6017 OP_E (bytemode, sizeflag);
6018 else
6019 BadOp ();
6020}
6021
6022static void
6023OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6024{
6025 used_prefixes |= (prefixes & PREFIX_DATA);
6026 if (prefixes & PREFIX_DATA)
6027 {
6028 int add = 0;
6029 USED_REX (REX_R);
6030 if (rex & REX_R)
6031 add = 8;
6032 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
6033 }
6034 else
6035 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
6036 oappend (scratchbuf + intel_syntax);
6037}
6038
6039static void
6040OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6041{
6042 int add = 0;
6043 USED_REX (REX_R);
6044 if (rex & REX_R)
6045 add = 8;
6046 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.reg + add);
6047 oappend (scratchbuf + intel_syntax);
6048}
6049
6050static void
6051OP_EM (int bytemode, int sizeflag)
6052{
6053 if (modrm.mod != 3)
6054 {
6055 if (intel_syntax && bytemode == v_mode)
6056 {
6057 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
6058 used_prefixes |= (prefixes & PREFIX_DATA);
6059 }
6060 OP_E (bytemode, sizeflag);
6061 return;
6062 }
6063
6064
6065 MODRM_CHECK;
6066 codep++;
6067 used_prefixes |= (prefixes & PREFIX_DATA);
6068 if (prefixes & PREFIX_DATA)
6069 {
6070 int add = 0;
6071
6072 USED_REX (REX_B);
6073 if (rex & REX_B)
6074 add = 8;
6075 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
6076 }
6077 else
6078 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
6079 oappend (scratchbuf + intel_syntax);
6080}
6081
6082
6083
6084
6085
6086
6087static void
6088OP_EMC (int bytemode, int sizeflag)
6089{
6090 if (modrm.mod != 3)
6091 {
6092 if (intel_syntax && bytemode == v_mode)
6093 {
6094 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
6095 used_prefixes |= (prefixes & PREFIX_DATA);
6096 }
6097 OP_E (bytemode, sizeflag);
6098 return;
6099 }
6100
6101
6102 MODRM_CHECK;
6103 codep++;
6104 used_prefixes |= (prefixes & PREFIX_DATA);
6105 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.rm);
6106 oappend (scratchbuf + intel_syntax);
6107}
6108
6109static void
6110OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6111{
6112 used_prefixes |= (prefixes & PREFIX_DATA);
6113 snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", modrm.reg);
6114 oappend (scratchbuf + intel_syntax);
6115}
6116
6117static void
6118OP_EX (int bytemode, int sizeflag)
6119{
6120 int add = 0;
6121 if (modrm.mod != 3)
6122 {
6123 OP_E (bytemode, sizeflag);
6124 return;
6125 }
6126 USED_REX (REX_B);
6127 if (rex & REX_B)
6128 add = 8;
6129
6130
6131 MODRM_CHECK;
6132 codep++;
6133 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", modrm.rm + add);
6134 oappend (scratchbuf + intel_syntax);
6135}
6136
6137static void
6138OP_MS (int bytemode, int sizeflag)
6139{
6140 if (modrm.mod == 3)
6141 OP_EM (bytemode, sizeflag);
6142 else
6143 BadOp ();
6144}
6145
6146static void
6147OP_XS (int bytemode, int sizeflag)
6148{
6149 if (modrm.mod == 3)
6150 OP_EX (bytemode, sizeflag);
6151 else
6152 BadOp ();
6153}
6154
6155static void
6156OP_M (int bytemode, int sizeflag)
6157{
6158 if (modrm.mod == 3)
6159
6160 BadOp ();
6161 else
6162 OP_E (bytemode, sizeflag);
6163}
6164
6165static void
6166OP_0f07 (int bytemode, int sizeflag)
6167{
6168 if (modrm.mod != 3 || modrm.rm != 0)
6169 BadOp ();
6170 else
6171 OP_E (bytemode, sizeflag);
6172}
6173
6174static void
6175OP_0fae (int bytemode, int sizeflag)
6176{
6177 if (modrm.mod == 3)
6178 {
6179 if (modrm.reg == 7)
6180 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
6181
6182 if (modrm.reg < 5 || modrm.rm != 0)
6183 {
6184 BadOp ();
6185 return;
6186 }
6187 }
6188 else if (modrm.reg != 7)
6189 {
6190 BadOp ();
6191 return;
6192 }
6193
6194 OP_E (bytemode, sizeflag);
6195}
6196
6197
6198
6199
6200static void
6201NOP_Fixup1 (int bytemode, int sizeflag)
6202{
6203 if ((prefixes & PREFIX_DATA) != 0
6204 || (rex != 0
6205 && rex != 0x48
6206 && address_mode == mode_64bit))
6207 OP_REG (bytemode, sizeflag);
6208 else
6209 strcpy (obuf, "nop");
6210}
6211
6212static void
6213NOP_Fixup2 (int bytemode, int sizeflag)
6214{
6215 if ((prefixes & PREFIX_DATA) != 0
6216 || (rex != 0
6217 && rex != 0x48
6218 && address_mode == mode_64bit))
6219 OP_IMREG (bytemode, sizeflag);
6220}
6221
6222static const char *Suffix3DNow[] = {
6223 NULL, NULL, NULL, NULL,
6224 NULL, NULL, NULL, NULL,
6225 NULL, NULL, NULL, NULL,
6226 "pi2fw", "pi2fd", NULL, NULL,
6227 NULL, NULL, NULL, NULL,
6228 NULL, NULL, NULL, NULL,
6229 NULL, NULL, NULL, NULL,
6230 "pf2iw", "pf2id", NULL, NULL,
6231 NULL, NULL, NULL, NULL,
6232 NULL, NULL, NULL, NULL,
6233 NULL, NULL, NULL, NULL,
6234 NULL, NULL, NULL, NULL,
6235 NULL, NULL, NULL, NULL,
6236 NULL, NULL, NULL, NULL,
6237 NULL, NULL, NULL, NULL,
6238 NULL, NULL, NULL, NULL,
6239 NULL, NULL, NULL, NULL,
6240 NULL, NULL, NULL, NULL,
6241 NULL, NULL, NULL, NULL,
6242 NULL, NULL, NULL, NULL,
6243 NULL, NULL, NULL, NULL,
6244 NULL, NULL, NULL, NULL,
6245 NULL, NULL, NULL, NULL,
6246 NULL, NULL, NULL, NULL,
6247 NULL, NULL, NULL, NULL,
6248 NULL, NULL, NULL, NULL,
6249 NULL, NULL, NULL, NULL,
6250 NULL, NULL, NULL, NULL,
6251 NULL, NULL, NULL, NULL,
6252 NULL, NULL, NULL, NULL,
6253 NULL, NULL, NULL, NULL,
6254 NULL, NULL, NULL, NULL,
6255 NULL, NULL, NULL, NULL,
6256 NULL, NULL, NULL, NULL,
6257 NULL, NULL, "pfnacc", NULL,
6258 NULL, NULL, "pfpnacc", NULL,
6259 "pfcmpge", NULL, NULL, NULL,
6260 "pfmin", NULL, "pfrcp", "pfrsqrt",
6261 NULL, NULL, "pfsub", NULL,
6262 NULL, NULL, "pfadd", NULL,
6263 "pfcmpgt", NULL, NULL, NULL,
6264 "pfmax", NULL, "pfrcpit1", "pfrsqit1",
6265 NULL, NULL, "pfsubr", NULL,
6266 NULL, NULL, "pfacc", NULL,
6267 "pfcmpeq", NULL, NULL, NULL,
6268 "pfmul", NULL, "pfrcpit2", "pmulhrw",
6269 NULL, NULL, NULL, "pswapd",
6270 NULL, NULL, NULL, "pavgusb",
6271 NULL, NULL, NULL, NULL,
6272 NULL, NULL, NULL, NULL,
6273 NULL, NULL, NULL, NULL,
6274 NULL, NULL, NULL, NULL,
6275 NULL, NULL, NULL, NULL,
6276 NULL, NULL, NULL, NULL,
6277 NULL, NULL, NULL, NULL,
6278 NULL, NULL, NULL, NULL,
6279 NULL, NULL, NULL, NULL,
6280 NULL, NULL, NULL, NULL,
6281 NULL, NULL, NULL, NULL,
6282 NULL, NULL, NULL, NULL,
6283 NULL, NULL, NULL, NULL,
6284 NULL, NULL, NULL, NULL,
6285 NULL, NULL, NULL, NULL,
6286 NULL, NULL, NULL, NULL,
6287};
6288
6289static void
6290OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6291{
6292 const char *mnemonic;
6293
6294 fetch_data(the_info, codep + 1);
6295
6296
6297
6298 obufp = obuf + strlen (obuf);
6299 mnemonic = Suffix3DNow[*codep++ & 0xff];
6300 if (mnemonic)
6301 oappend (mnemonic);
6302 else
6303 {
6304
6305
6306
6307
6308 op_out[0][0] = '\0';
6309 op_out[1][0] = '\0';
6310 BadOp ();
6311 }
6312}
6313
6314static const char *simd_cmp_op[] = {
6315 "eq",
6316 "lt",
6317 "le",
6318 "unord",
6319 "neq",
6320 "nlt",
6321 "nle",
6322 "ord"
6323};
6324
6325static void
6326OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
6327{
6328 unsigned int cmp_type;
6329
6330 fetch_data(the_info, codep + 1);
6331 obufp = obuf + strlen (obuf);
6332 cmp_type = *codep++ & 0xff;
6333 if (cmp_type < 8)
6334 {
6335 char suffix1 = 'p', suffix2 = 's';
6336 used_prefixes |= (prefixes & PREFIX_REPZ);
6337 if (prefixes & PREFIX_REPZ)
6338 suffix1 = 's';
6339 else
6340 {
6341 used_prefixes |= (prefixes & PREFIX_DATA);
6342 if (prefixes & PREFIX_DATA)
6343 suffix2 = 'd';
6344 else
6345 {
6346 used_prefixes |= (prefixes & PREFIX_REPNZ);
6347 if (prefixes & PREFIX_REPNZ)
6348 suffix1 = 's', suffix2 = 'd';
6349 }
6350 }
6351 snprintf (scratchbuf, sizeof(scratchbuf), "cmp%s%c%c",
6352 simd_cmp_op[cmp_type], suffix1, suffix2);
6353 used_prefixes |= (prefixes & PREFIX_REPZ);
6354 oappend (scratchbuf);
6355 }
6356 else
6357 {
6358
6359 op_out[0][0] = '\0';
6360 op_out[1][0] = '\0';
6361 BadOp ();
6362 }
6363}
6364
6365static void
6366SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
6367{
6368
6369
6370 if (modrm.mod == 3)
6371 {
6372 char *p = obuf + strlen (obuf);
6373 *(p + 1) = '\0';
6374 *p = *(p - 1);
6375 *(p - 1) = *(p - 2);
6376 *(p - 2) = *(p - 3);
6377 *(p - 3) = extrachar;
6378 }
6379}
6380
6381static void
6382PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6383{
6384 if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
6385 {
6386
6387 size_t olen = strlen (obuf);
6388 char *p = obuf + olen - 4;
6389 const char * const *names = (address_mode == mode_64bit
6390 ? names64 : names32);
6391
6392
6393 if (*p == 'i')
6394 --p;
6395
6396
6397 if (!intel_syntax
6398 && (prefixes & PREFIX_ADDR)
6399 && olen >= (4 + 7)
6400 && *(p - 1) == ' '
6401 && strncmp (p - 7, "addr", 4) == 0
6402 && (strncmp (p - 3, "16", 2) == 0
6403 || strncmp (p - 3, "32", 2) == 0))
6404 p -= 7;
6405
6406 if (modrm.rm)
6407 {
6408
6409 strcpy (p, "mwait");
6410 if (!intel_syntax)
6411 strcpy (op_out[0], names[0]);
6412 }
6413 else
6414 {
6415
6416 strcpy (p, "monitor");
6417 if (!intel_syntax)
6418 {
6419 const char * const *op1_names;
6420 if (!(prefixes & PREFIX_ADDR))
6421 op1_names = (address_mode == mode_16bit
6422 ? names16 : names);
6423 else
6424 {
6425 op1_names = (address_mode != mode_32bit
6426 ? names32 : names16);
6427 used_prefixes |= PREFIX_ADDR;
6428 }
6429 strcpy (op_out[0], op1_names[0]);
6430 strcpy (op_out[2], names[2]);
6431 }
6432 }
6433 if (!intel_syntax)
6434 {
6435 strcpy (op_out[1], names[1]);
6436 two_source_ops = 1;
6437 }
6438
6439 codep++;
6440 }
6441 else
6442 OP_M (0, sizeflag);
6443}
6444
6445static void
6446SVME_Fixup (int bytemode, int sizeflag)
6447{
6448 const char *alt;
6449 char *p;
6450
6451 switch (*codep)
6452 {
6453 case 0xd8:
6454 alt = "vmrun";
6455 break;
6456 case 0xd9:
6457 alt = "vmmcall";
6458 break;
6459 case 0xda:
6460 alt = "vmload";
6461 break;
6462 case 0xdb:
6463 alt = "vmsave";
6464 break;
6465 case 0xdc:
6466 alt = "stgi";
6467 break;
6468 case 0xdd:
6469 alt = "clgi";
6470 break;
6471 case 0xde:
6472 alt = "skinit";
6473 break;
6474 case 0xdf:
6475 alt = "invlpga";
6476 break;
6477 default:
6478 OP_M (bytemode, sizeflag);
6479 return;
6480 }
6481
6482 p = obuf + strlen (obuf) - 4;
6483
6484 if (*p == 'i')
6485 --p;
6486 strcpy (p, alt);
6487 if (!(prefixes & PREFIX_ADDR))
6488 {
6489 ++codep;
6490 return;
6491 }
6492 used_prefixes |= PREFIX_ADDR;
6493 switch (*codep++)
6494 {
6495 case 0xdf:
6496 strcpy (op_out[1], names32[1]);
6497 two_source_ops = 1;
6498
6499 case 0xd8:
6500 case 0xda:
6501 case 0xdb:
6502 *obufp++ = open_char;
6503 if (address_mode == mode_64bit || (sizeflag & AFLAG))
6504 alt = names32[0];
6505 else
6506 alt = names16[0];
6507 strcpy (obufp, alt);
6508 obufp += strlen (alt);
6509 *obufp++ = close_char;
6510 *obufp = '\0';
6511 break;
6512 }
6513}
6514
6515static void
6516INVLPG_Fixup (int bytemode, int sizeflag)
6517{
6518 const char *alt;
6519
6520 switch (*codep)
6521 {
6522 case 0xf8:
6523 alt = "swapgs";
6524 break;
6525 case 0xf9:
6526 alt = "rdtscp";
6527 break;
6528 default:
6529 OP_M (bytemode, sizeflag);
6530 return;
6531 }
6532
6533 strcpy (obuf + strlen (obuf) - 6, alt);
6534 codep++;
6535}
6536
6537static void
6538BadOp (void)
6539{
6540
6541 codep = insn_codep + 1;
6542 oappend ("(bad)");
6543}
6544
6545static void
6546VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
6547{
6548 if (modrm.mod == 3
6549 && modrm.reg == 0
6550 && modrm.rm >=1
6551 && modrm.rm <= 4)
6552 {
6553
6554 char *p = obuf + strlen (obuf) - 4;
6555
6556
6557 if (*p == 'g')
6558 --p;
6559
6560 switch (modrm.rm)
6561 {
6562 case 1:
6563 strcpy (p, "vmcall");
6564 break;
6565 case 2:
6566 strcpy (p, "vmlaunch");
6567 break;
6568 case 3:
6569 strcpy (p, "vmresume");
6570 break;
6571 case 4:
6572 strcpy (p, "vmxoff");
6573 break;
6574 }
6575
6576 codep++;
6577 }
6578 else
6579 OP_E (0, sizeflag);
6580}
6581
6582static void
6583OP_VMX (int bytemode, int sizeflag)
6584{
6585 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
6586 if (prefixes & PREFIX_DATA)
6587 strcpy (obuf, "vmclear");
6588 else if (prefixes & PREFIX_REPZ)
6589 strcpy (obuf, "vmxon");
6590 else
6591 strcpy (obuf, "vmptrld");
6592 OP_E (bytemode, sizeflag);
6593}
6594
6595static void
6596REP_Fixup (int bytemode, int sizeflag)
6597{
6598
6599
6600 size_t ilen = 0;
6601
6602 if (prefixes & PREFIX_REPZ)
6603 switch (*insn_codep)
6604 {
6605 case 0x6e:
6606 case 0x6f:
6607 case 0xa4:
6608 case 0xa5:
6609 if (!intel_syntax)
6610 ilen = 5;
6611 else
6612 ilen = 4;
6613 break;
6614 case 0xaa:
6615 case 0xab:
6616 case 0xac:
6617 case 0xad:
6618 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
6619 ilen = 5;
6620 else
6621 ilen = 4;
6622 break;
6623 case 0x6c:
6624 case 0x6d:
6625 if (!intel_syntax)
6626 ilen = 4;
6627 else
6628 ilen = 3;
6629 break;
6630 default:
6631 abort ();
6632 break;
6633 }
6634
6635 if (ilen != 0)
6636 {
6637 size_t olen;
6638 char *p;
6639
6640 olen = strlen (obuf);
6641 p = obuf + olen - ilen - 1 - 4;
6642
6643 if ((prefixes & PREFIX_ADDR))
6644 p -= 1 + 6;
6645
6646 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
6647 }
6648
6649 switch (bytemode)
6650 {
6651 case al_reg:
6652 case eAX_reg:
6653 case indir_dx_reg:
6654 OP_IMREG (bytemode, sizeflag);
6655 break;
6656 case eDI_reg:
6657 OP_ESreg (bytemode, sizeflag);
6658 break;
6659 case eSI_reg:
6660 OP_DSreg (bytemode, sizeflag);
6661 break;
6662 default:
6663 abort ();
6664 break;
6665 }
6666}
6667
6668static void
6669CMPXCHG8B_Fixup (int bytemode, int sizeflag)
6670{
6671 USED_REX (REX_W);
6672 if (rex & REX_W)
6673 {
6674
6675 char *p = obuf + strlen (obuf) - 2;
6676 strcpy (p, "16b");
6677 bytemode = o_mode;
6678 }
6679 OP_M (bytemode, sizeflag);
6680}
6681
6682static void
6683XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED)
6684{
6685 snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", reg);
6686 oappend (scratchbuf + intel_syntax);
6687}
6688
6689static void
6690CRC32_Fixup (int bytemode, int sizeflag)
6691{
6692
6693 char *p = obuf + strlen (obuf);
6694
6695 switch (bytemode)
6696 {
6697 case b_mode:
6698 if (intel_syntax)
6699 break;
6700
6701 *p++ = 'b';
6702 break;
6703 case v_mode:
6704 if (intel_syntax)
6705 break;
6706
6707 USED_REX (REX_W);
6708 if (rex & REX_W)
6709 *p++ = 'q';
6710 else if (sizeflag & DFLAG)
6711 *p++ = 'l';
6712 else
6713 *p++ = 'w';
6714 used_prefixes |= (prefixes & PREFIX_DATA);
6715 break;
6716 default:
6717 oappend (INTERNAL_DISASSEMBLER_ERROR);
6718 break;
6719 }
6720 *p = '\0';
6721
6722 if (modrm.mod == 3)
6723 {
6724 int add;
6725
6726
6727 MODRM_CHECK;
6728 codep++;
6729
6730 USED_REX (REX_B);
6731 add = (rex & REX_B) ? 8 : 0;
6732 if (bytemode == b_mode)
6733 {
6734 USED_REX (0);
6735 if (rex)
6736 oappend (names8rex[modrm.rm + add]);
6737 else
6738 oappend (names8[modrm.rm + add]);
6739 }
6740 else
6741 {
6742 USED_REX (REX_W);
6743 if (rex & REX_W)
6744 oappend (names64[modrm.rm + add]);
6745 else if ((prefixes & PREFIX_DATA))
6746 oappend (names16[modrm.rm + add]);
6747 else
6748 oappend (names32[modrm.rm + add]);
6749 }
6750 }
6751 else
6752 OP_E (bytemode, sizeflag);
6753}
6754