1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 * modified by John Hassey (hassey@dg-rtp.dg.com)
28 * The main tables describing the instructions is essentially a copy
29 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 * Programmers Manual. Usually, there is a capital letter, followed
31 * by a small letter. The capital letter tell the addressing mode,
32 * and the small letter tells about the operand size. Refer to
33 * the Intel manual for details.
44 #ifndef UNIXWARE_COMPAT
45 /* Set non-zero for broken, compatible instructions. Set to zero for
46 non-broken opcodes. */
47 #define UNIXWARE_COMPAT 1
50 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
54 /* Points to first byte not fetched. */
55 bfd_byte *max_fetched;
56 bfd_byte the_buffer[MAXLEN];
61 /* The opcode for the fwait instruction, which we treat as a prefix
63 #define FWAIT_OPCODE (0x9b)
65 /* Flags for the prefixes for the current instruction. See below. */
68 /* Flags stored in PREFIXES. */
70 #define PREFIX_REPNZ 2
73 #define PREFIX_SS 0x10
74 #define PREFIX_DS 0x20
75 #define PREFIX_ES 0x40
76 #define PREFIX_FS 0x80
77 #define PREFIX_GS 0x100
78 #define PREFIX_DATA 0x200
79 #define PREFIX_ADDR 0x400
80 #define PREFIX_FWAIT 0x800
82 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
83 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
85 #define FETCH_DATA(info, addr) \
86 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
87 ? 1 : fetch_data ((info), (addr)))
90 fetch_data (info, addr)
91 struct disassemble_info *info;
95 struct dis_private *priv = (struct dis_private *)info->private_data;
96 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
98 status = (*info->read_memory_func) (start,
100 addr - priv->max_fetched,
104 /* If we have found an fwait prefix and an fwait opcode, then
105 print_insn_i386 will arrange to print an instruction after we
106 longjmp, and we don't want to print an error message here.
107 This hack is required because we treat fwait as a prefix, but
108 since fwait is really an instruction we want to print a
109 standalone fwait correctly. */
110 if ((prefixes & PREFIX_FWAIT) == 0
111 || memchr (priv->the_buffer, FWAIT_OPCODE,
112 priv->max_fetched - priv->the_buffer) == NULL)
113 (*info->memory_error_func) (status, start, info);
114 longjmp (priv->bailout, 1);
117 priv->max_fetched = addr;
121 #define Eb OP_E, b_mode
122 #define indirEb OP_indirE, b_mode
123 #define Gb OP_G, b_mode
124 #define Ev OP_E, v_mode
125 #define Ed OP_E, d_mode
126 #define indirEv OP_indirE, v_mode
127 #define Ew OP_E, w_mode
128 #define Ma OP_E, v_mode
129 #define M OP_E, 0 /* lea */
130 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
131 #define Gv OP_G, v_mode
132 #define Gw OP_G, w_mode
133 #define Rd OP_Rd, d_mode
134 #define Ib OP_I, b_mode
135 #define sIb OP_sI, b_mode /* sign extened byte */
136 #define Iv OP_I, v_mode
137 #define Iw OP_I, w_mode
138 #define Jb OP_J, b_mode
139 #define Jv OP_J, v_mode
140 #define Cd OP_C, d_mode
141 #define Dd OP_D, d_mode
142 #define Td OP_T, d_mode
144 #define eAX OP_REG, eAX_reg
145 #define eBX OP_REG, eBX_reg
146 #define eCX OP_REG, eCX_reg
147 #define eDX OP_REG, eDX_reg
148 #define eSP OP_REG, eSP_reg
149 #define eBP OP_REG, eBP_reg
150 #define eSI OP_REG, eSI_reg
151 #define eDI OP_REG, eDI_reg
152 #define AL OP_REG, al_reg
153 #define CL OP_REG, cl_reg
154 #define DL OP_REG, dl_reg
155 #define BL OP_REG, bl_reg
156 #define AH OP_REG, ah_reg
157 #define CH OP_REG, ch_reg
158 #define DH OP_REG, dh_reg
159 #define BH OP_REG, bh_reg
160 #define AX OP_REG, ax_reg
161 #define DX OP_REG, dx_reg
162 #define indirDX OP_REG, indir_dx_reg
164 #define Sw OP_SEG, w_mode
166 #define Ob OP_OFF, b_mode
167 #define Ov OP_OFF, v_mode
168 #define Xb OP_DSreg, eSI_reg
169 #define Xv OP_DSreg, eSI_reg
170 #define Yb OP_ESreg, eDI_reg
171 #define Yv OP_ESreg, eDI_reg
172 #define DSBX OP_DSreg, eBX_reg
174 #define es OP_REG, es_reg
175 #define ss OP_REG, ss_reg
176 #define cs OP_REG, cs_reg
177 #define ds OP_REG, ds_reg
178 #define fs OP_REG, fs_reg
179 #define gs OP_REG, gs_reg
183 #define EM OP_EM, v_mode
184 #define EX OP_EX, v_mode
185 #define MS OP_MS, v_mode
187 #define OPSUF OP_3DNowSuffix, 0
188 #define OPSIMD OP_SIMD_Suffix, 0
190 /* bits in sizeflag */
191 #if 0 /* leave undefined until someone adds the extra flag to objdump */
192 #define SUFFIX_ALWAYS 4
197 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
199 static void OP_E PARAMS ((int, int));
200 static void OP_G PARAMS ((int, int));
201 static void OP_I PARAMS ((int, int));
202 static void OP_indirE PARAMS ((int, int));
203 static void OP_sI PARAMS ((int, int));
204 static void OP_REG PARAMS ((int, int));
205 static void OP_J PARAMS ((int, int));
206 static void OP_DIR PARAMS ((int, int));
207 static void OP_OFF PARAMS ((int, int));
208 static void OP_ESreg PARAMS ((int, int));
209 static void OP_DSreg PARAMS ((int, int));
210 static void OP_SEG PARAMS ((int, int));
211 static void OP_C PARAMS ((int, int));
212 static void OP_D PARAMS ((int, int));
213 static void OP_T PARAMS ((int, int));
214 static void OP_Rd PARAMS ((int, int));
215 static void OP_ST PARAMS ((int, int));
216 static void OP_STi PARAMS ((int, int));
217 static void OP_MMX PARAMS ((int, int));
218 static void OP_XMM PARAMS ((int, int));
219 static void OP_EM PARAMS ((int, int));
220 static void OP_EX PARAMS ((int, int));
221 static void OP_MS PARAMS ((int, int));
222 static void OP_3DNowSuffix PARAMS ((int, int));
223 static void OP_SIMD_Suffix PARAMS ((int, int));
224 static void SIMD_Fixup PARAMS ((int, int));
226 static void append_seg PARAMS ((void));
227 static void set_op PARAMS ((unsigned int op));
228 static void putop PARAMS ((const char *template, int sizeflag));
229 static void dofloat PARAMS ((int sizeflag));
230 static int get16 PARAMS ((void));
231 static int get32 PARAMS ((void));
232 static void ckprefix PARAMS ((void));
233 static void ptr_reg PARAMS ((int, int));
234 static void BadOp PARAMS ((void));
276 #define indir_dx_reg 150
279 #define USE_PREFIX_USER_TABLE 2
281 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
282 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
283 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
284 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
285 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
286 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
287 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
288 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
289 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
290 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
291 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
292 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
293 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
294 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
295 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
296 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
297 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
298 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
299 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
300 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
301 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
302 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
303 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
305 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
306 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
307 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
308 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
309 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
310 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
311 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
312 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
313 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
314 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
315 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
316 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
317 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
318 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
319 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
322 #define FLOAT NULL, NULL, FLOATCODE
334 /* Upper case letters in the instruction names here are macros.
335 'A' => print 'b' if no register operands or suffix_always is true
336 'B' => print 'b' if suffix_always is true
337 'E' => print 'e' if 32-bit form of jcxz
338 'L' => print 'l' if suffix_always is true
339 'N' => print 'n' if instruction has no wait "prefix"
340 'P' => print 'w' or 'l' if instruction has an operand size prefix,
341 or suffix_always is true
342 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
343 'R' => print 'w' or 'l'
344 'S' => print 'w' or 'l' if suffix_always is true
345 'W' => print 'b' or 'w'
348 static const struct dis386 dis386_att[] = {
366 { "(bad)" }, /* 0x0f extended opcode escape */
392 { "(bad)" }, /* SEG ES prefix */
401 { "(bad)" }, /* SEG CS prefix */
410 { "(bad)" }, /* SEG SS prefix */
419 { "(bad)" }, /* SEG DS prefix */
460 { "boundS", Gv, Ma },
462 { "(bad)" }, /* seg fs */
463 { "(bad)" }, /* seg gs */
464 { "(bad)" }, /* op size prefix */
465 { "(bad)" }, /* adr size prefix */
467 { "pushP", Iv }, /* 386 book wrong */
468 { "imulS", Gv, Ev, Iv },
469 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
470 { "imulS", Gv, Ev, sIb },
471 { "insb", Yb, indirDX },
472 { "insR", Yv, indirDX },
473 { "outsb", indirDX, Xb },
474 { "outsR", indirDX, Xv },
513 { "xchgS", eCX, eAX },
514 { "xchgS", eDX, eAX },
515 { "xchgS", eBX, eAX },
516 { "xchgS", eSP, eAX },
517 { "xchgS", eBP, eAX },
518 { "xchgS", eSI, eAX },
519 { "xchgS", eDI, eAX },
524 { "(bad)" }, /* fwait */
540 { "testS", eAX, Iv },
542 { "stosS", Yv, eAX },
544 { "lodsS", eAX, Xv },
546 { "scasS", eAX, Yv },
575 { "enterP", Iw, Ib },
615 { "inB", AL, indirDX },
616 { "inS", eAX, indirDX },
617 { "outB", indirDX, AL },
618 { "outS", indirDX, eAX },
620 { "(bad)" }, /* lock prefix */
622 { "(bad)" }, /* repne */
623 { "(bad)" }, /* repz */
639 static const struct dis386 dis386_intel[] = {
657 { "(bad)" }, /* 0x0f extended opcode escape */
683 { "(bad)" }, /* SEG ES prefix */
692 { "(bad)" }, /* SEG CS prefix */
701 { "(bad)" }, /* SEG SS prefix */
710 { "(bad)" }, /* SEG DS prefix */
753 { "(bad)" }, /* seg fs */
754 { "(bad)" }, /* seg gs */
755 { "(bad)" }, /* op size prefix */
756 { "(bad)" }, /* adr size prefix */
758 { "push", Iv }, /* 386 book wrong */
759 { "imul", Gv, Ev, Iv },
760 { "push", sIb }, /* push of byte really pushes 2 or 4 bytes */
761 { "imul", Gv, Ev, sIb },
762 { "ins", Yb, indirDX },
763 { "ins", Yv, indirDX },
764 { "outs", indirDX, Xb },
765 { "outs", indirDX, Xv },
804 { "xchg", eCX, eAX },
805 { "xchg", eDX, eAX },
806 { "xchg", eBX, eAX },
807 { "xchg", eSP, eAX },
808 { "xchg", eBP, eAX },
809 { "xchg", eSI, eAX },
810 { "xchg", eDI, eAX },
812 { "cW" }, /* cwde and cbw */
813 { "cR" }, /* cdq and cwd */
815 { "(bad)" }, /* fwait */
906 { "in", AL, indirDX },
907 { "in", eAX, indirDX },
908 { "out", indirDX, AL },
909 { "out", indirDX, eAX },
911 { "(bad)" }, /* lock prefix */
913 { "(bad)" }, /* repne */
914 { "(bad)" }, /* repz */
930 static const struct dis386 dis386_twobyte_att[] = {
948 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
952 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
953 { "movlps", EX, XM, SIMD_Fixup, 'h' },
954 { "unpcklps", XM, EX },
955 { "unpckhps", XM, EX },
956 { "movhps", XM, EX, SIMD_Fixup, 'l' },
957 { "movhps", EX, XM, SIMD_Fixup, 'l' },
960 { "(bad)" }, { "(bad)" }, { "(bad)" },
961 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
963 /* these are all backward in appendix A of the intel book */
973 { "movaps", XM, EX },
974 { "movaps", EX, XM },
976 { "movntps", Ev, XM },
979 { "ucomiss", XM, EX },
980 { "comiss", XM, EX },
982 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
983 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
985 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
986 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
988 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
989 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
991 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
992 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
994 { "movmskps", Gv, EX },
999 { "andnps", XM, EX },
1001 { "xorps", XM, EX },
1012 { "punpcklbw", MX, EM },
1013 { "punpcklwd", MX, EM },
1014 { "punpckldq", MX, EM },
1015 { "packsswb", MX, EM },
1016 { "pcmpgtb", MX, EM },
1017 { "pcmpgtw", MX, EM },
1018 { "pcmpgtd", MX, EM },
1019 { "packuswb", MX, EM },
1021 { "punpckhbw", MX, EM },
1022 { "punpckhwd", MX, EM },
1023 { "punpckhdq", MX, EM },
1024 { "packssdw", MX, EM },
1025 { "(bad)" }, { "(bad)" },
1029 { "pshufw", MX, EM, Ib },
1033 { "pcmpeqb", MX, EM },
1034 { "pcmpeqw", MX, EM },
1035 { "pcmpeqd", MX, EM },
1038 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1039 { "(bad)" }, { "(bad)" },
1083 { "shldS", Ev, Gv, Ib },
1084 { "shldS", Ev, Gv, CL },
1092 { "shrdS", Ev, Gv, Ib },
1093 { "shrdS", Ev, Gv, CL },
1095 { "imulS", Gv, Ev },
1097 { "cmpxchgB", Eb, Gb },
1098 { "cmpxchgS", Ev, Gv },
1103 { "movzbR", Gv, Eb },
1104 { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
1112 { "movsbR", Gv, Eb },
1113 { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
1115 { "xaddB", Eb, Gb },
1116 { "xaddS", Ev, Gv },
1119 { "pinsrw", MX, Ev, Ib },
1120 { "pextrw", Ev, MX, Ib },
1121 { "shufps", XM, EX, Ib },
1124 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1134 { "psrlw", MX, EM },
1135 { "psrld", MX, EM },
1136 { "psrlq", MX, EM },
1138 { "pmullw", MX, EM },
1140 { "pmovmskb", Ev, MX },
1142 { "psubusb", MX, EM },
1143 { "psubusw", MX, EM },
1144 { "pminub", MX, EM },
1146 { "paddusb", MX, EM },
1147 { "paddusw", MX, EM },
1148 { "pmaxub", MX, EM },
1149 { "pandn", MX, EM },
1151 { "pavgb", MX, EM },
1152 { "psraw", MX, EM },
1153 { "psrad", MX, EM },
1154 { "pavgw", MX, EM },
1155 { "pmulhuw", MX, EM },
1156 { "pmulhw", MX, EM },
1158 { "movntq", Ev, MX },
1160 { "psubsb", MX, EM },
1161 { "psubsw", MX, EM },
1162 { "pminsw", MX, EM },
1164 { "paddsb", MX, EM },
1165 { "paddsw", MX, EM },
1166 { "pmaxsw", MX, EM },
1170 { "psllw", MX, EM },
1171 { "pslld", MX, EM },
1172 { "psllq", MX, EM },
1174 { "pmaddwd", MX, EM },
1175 { "psadbw", MX, EM },
1176 { "maskmovq", MX, EM },
1178 { "psubb", MX, EM },
1179 { "psubw", MX, EM },
1180 { "psubd", MX, EM },
1182 { "paddb", MX, EM },
1183 { "paddw", MX, EM },
1184 { "paddd", MX, EM },
1188 static const struct dis386 dis386_twobyte_intel[] = {
1206 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1210 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1211 { "movlps", EX, XM, SIMD_Fixup, 'h' },
1212 { "unpcklps", XM, EX },
1213 { "unpckhps", XM, EX },
1214 { "movhps", XM, EX, SIMD_Fixup, 'l' },
1215 { "movhps", EX, XM, SIMD_Fixup, 'l' },
1218 { "(bad)" }, { "(bad)" }, { "(bad)" },
1219 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1221 /* these are all backward in appendix A of the intel book */
1231 { "movaps", XM, EX },
1232 { "movaps", EX, XM },
1234 { "movntps", Ev, XM },
1237 { "ucomiss", XM, EX },
1238 { "comiss", XM, EX },
1240 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1241 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1243 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1244 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1246 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
1247 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
1249 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
1250 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
1252 { "movmskps", Gv, EX },
1256 { "andps", XM, EX },
1257 { "andnps", XM, EX },
1259 { "xorps", XM, EX },
1270 { "punpcklbw", MX, EM },
1271 { "punpcklwd", MX, EM },
1272 { "punpckldq", MX, EM },
1273 { "packsswb", MX, EM },
1274 { "pcmpgtb", MX, EM },
1275 { "pcmpgtw", MX, EM },
1276 { "pcmpgtd", MX, EM },
1277 { "packuswb", MX, EM },
1279 { "punpckhbw", MX, EM },
1280 { "punpckhwd", MX, EM },
1281 { "punpckhdq", MX, EM },
1282 { "packssdw", MX, EM },
1283 { "(bad)" }, { "(bad)" },
1287 { "pshufw", MX, EM, Ib },
1291 { "pcmpeqb", MX, EM },
1292 { "pcmpeqw", MX, EM },
1293 { "pcmpeqd", MX, EM },
1296 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1297 { "(bad)" }, { "(bad)" },
1341 { "shld", Ev, Gv, Ib },
1342 { "shld", Ev, Gv, CL },
1350 { "shrd", Ev, Gv, Ib },
1351 { "shrd", Ev, Gv, CL },
1355 { "cmpxchg", Eb, Gb },
1356 { "cmpxchg", Ev, Gv },
1361 { "movzx", Gv, Eb },
1362 { "movzx", Gv, Ew },
1370 { "movsx", Gv, Eb },
1371 { "movsx", Gv, Ew },
1377 { "pinsrw", MX, Ev, Ib },
1378 { "pextrw", Ev, MX, Ib },
1379 { "shufps", XM, EX, Ib },
1382 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1392 { "psrlw", MX, EM },
1393 { "psrld", MX, EM },
1394 { "psrlq", MX, EM },
1396 { "pmullw", MX, EM },
1398 { "pmovmskb", Ev, MX },
1400 { "psubusb", MX, EM },
1401 { "psubusw", MX, EM },
1402 { "pminub", MX, EM },
1404 { "paddusb", MX, EM },
1405 { "paddusw", MX, EM },
1406 { "pmaxub", MX, EM },
1407 { "pandn", MX, EM },
1409 { "pavgb", MX, EM },
1410 { "psraw", MX, EM },
1411 { "psrad", MX, EM },
1412 { "pavgw", MX, EM },
1413 { "pmulhuw", MX, EM },
1414 { "pmulhw", MX, EM },
1416 { "movntq", Ev, MX },
1418 { "psubsb", MX, EM },
1419 { "psubsw", MX, EM },
1420 { "pminsw", MX, EM },
1422 { "paddsb", MX, EM },
1423 { "paddsw", MX, EM },
1424 { "pmaxsw", MX, EM },
1428 { "psllw", MX, EM },
1429 { "pslld", MX, EM },
1430 { "psllq", MX, EM },
1432 { "pmaddwd", MX, EM },
1433 { "psadbw", MX, EM },
1434 { "maskmovq", MX, EM },
1436 { "psubb", MX, EM },
1437 { "psubw", MX, EM },
1438 { "psubd", MX, EM },
1440 { "paddb", MX, EM },
1441 { "paddw", MX, EM },
1442 { "paddd", MX, EM },
1446 static const unsigned char onebyte_has_modrm[256] = {
1447 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1448 /* ------------------------------- */
1449 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1450 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1451 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1452 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1453 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1454 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1455 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1456 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1457 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1458 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1459 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1460 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1461 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1462 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1463 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1464 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1465 /* ------------------------------- */
1466 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1469 static const unsigned char twobyte_has_modrm[256] = {
1470 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1471 /* ------------------------------- */
1472 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1473 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1474 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1475 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1476 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1477 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1478 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1479 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1480 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1481 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1482 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1483 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1484 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1485 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1486 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1487 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1488 /* ------------------------------- */
1489 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1492 static const unsigned char twobyte_uses_f3_prefix[256] = {
1493 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1494 /* ------------------------------- */
1495 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1496 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1497 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1498 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1499 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1500 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1501 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1502 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1503 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1504 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1505 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1506 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1507 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1508 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1509 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1510 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1511 /* ------------------------------- */
1512 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1515 static char obuf[100];
1517 static char scratchbuf[100];
1518 static unsigned char *start_codep;
1519 static unsigned char *insn_codep;
1520 static unsigned char *codep;
1521 static disassemble_info *the_info;
1525 static void oappend PARAMS ((const char *s));
1527 static const char *names32[]={
1528 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1530 static const char *names16[] = {
1531 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1533 static const char *names8[] = {
1534 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1536 static const char *names_seg[] = {
1537 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1539 static const char *index16[] = {
1540 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1543 static const struct dis386 grps[][8] = {
1568 { "addQ", Ev, sIb },
1570 { "adcQ", Ev, sIb },
1571 { "sbbQ", Ev, sIb },
1572 { "andQ", Ev, sIb },
1573 { "subQ", Ev, sIb },
1574 { "xorQ", Ev, sIb },
1645 { "testA", Eb, Ib },
1650 { "imulB", AL, Eb },
1656 { "testQ", Ev, Iv },
1660 { "mulS", eAX, Ev },
1661 { "imulS", eAX, Ev },
1662 { "divS", eAX, Ev },
1663 { "idivS", eAX, Ev },
1680 { "callP", indirEv },
1681 { "callP", indirEv },
1682 { "jmpP", indirEv },
1683 { "ljmpP", indirEv },
1723 { "cmpxchg8b", Ev },
1735 { "psrlw", MS, Ib },
1737 { "psraw", MS, Ib },
1739 { "psllw", MS, Ib },
1746 { "psrld", MS, Ib },
1748 { "psrad", MS, Ib },
1750 { "pslld", MS, Ib },
1757 { "psrlq", MS, Ib },
1761 { "psllq", MS, Ib },
1777 { "prefetchnta", Ev },
1778 { "prefetcht0", Ev },
1779 { "prefetcht1", Ev },
1780 { "prefetcht2", Ev },
1789 { "prefetchw", Eb },
1800 static const struct dis386 prefix_user_table[][2] = {
1803 { "addps", XM, EX },
1804 { "addss", XM, EX },
1808 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
1809 { "", XM, EX, OPSIMD },
1813 { "cvtpi2ps", XM, EM },
1814 { "cvtsi2ss", XM, Ev },
1818 { "cvtps2pi", MX, EX },
1819 { "cvtss2si", Gv, EX },
1823 { "cvttps2pi", MX, EX },
1824 { "cvttss2si", Gv, EX },
1828 { "divps", XM, EX },
1829 { "divss", XM, EX },
1833 { "maxps", XM, EX },
1834 { "maxss", XM, EX },
1838 { "minps", XM, EX },
1839 { "minss", XM, EX },
1843 { "movups", XM, EX },
1844 { "movss", XM, EX },
1848 { "movups", EX, XM },
1849 { "movss", EX, XM },
1853 { "mulps", XM, EX },
1854 { "mulss", XM, EX },
1858 { "rcpps", XM, EX },
1859 { "rcpss", XM, EX },
1863 { "rsqrtps", XM, EX },
1864 { "rsqrtss", XM, EX },
1868 { "sqrtps", XM, EX },
1869 { "sqrtss", XM, EX },
1873 { "subps", XM, EX },
1874 { "subss", XM, EX },
1878 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1886 FETCH_DATA (the_info, codep + 1);
1890 prefixes |= PREFIX_REPZ;
1893 prefixes |= PREFIX_REPNZ;
1896 prefixes |= PREFIX_LOCK;
1899 prefixes |= PREFIX_CS;
1902 prefixes |= PREFIX_SS;
1905 prefixes |= PREFIX_DS;
1908 prefixes |= PREFIX_ES;
1911 prefixes |= PREFIX_FS;
1914 prefixes |= PREFIX_GS;
1917 prefixes |= PREFIX_DATA;
1920 prefixes |= PREFIX_ADDR;
1923 /* fwait is really an instruction. If there are prefixes
1924 before the fwait, they belong to the fwait, *not* to the
1925 following instruction. */
1928 prefixes |= PREFIX_FWAIT;
1932 prefixes = PREFIX_FWAIT;
1941 static char op1out[100], op2out[100], op3out[100];
1942 static int op_ad, op_index[3];
1943 static unsigned int op_address[3];
1944 static unsigned int start_pc;
1948 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1949 * (see topic "Redundant prefixes" in the "Differences from 8086"
1950 * section of the "Virtual 8086 Mode" chapter.)
1951 * 'pc' should be the address of this instruction, it will
1952 * be used to print the target address if this is a relative jump or call
1953 * The function returns the length of this instruction in bytes.
1956 static int print_insn_i386
1957 PARAMS ((bfd_vma pc, disassemble_info *info));
1959 static char intel_syntax;
1960 static char open_char;
1961 static char close_char;
1962 static char separator_char;
1963 static char scale_char;
1966 print_insn_i386_att (pc, info)
1968 disassemble_info *info;
1973 separator_char = ',';
1976 return print_insn_i386 (pc, info);
1980 print_insn_i386_intel (pc, info)
1982 disassemble_info *info;
1987 separator_char = '+';
1990 return print_insn_i386 (pc, info);
1994 print_insn_i386 (pc, info)
1996 disassemble_info *info;
1998 const struct dis386 *dp;
2001 char *first, *second, *third;
2003 unsigned char need_modrm;
2004 unsigned char uses_f3_prefix;
2007 struct dis_private priv;
2008 bfd_byte *inbuf = priv.the_buffer;
2010 if (info->mach == bfd_mach_i386_i386
2011 || info->mach == bfd_mach_i386_i386_intel_syntax)
2012 sizeflag = AFLAG|DFLAG;
2013 else if (info->mach == bfd_mach_i386_i8086)
2018 /* The output looks better if we put 6 bytes on a line, since that
2019 puts most long word instructions on a single line. */
2020 info->bytes_per_line = 6;
2022 info->private_data = (PTR) &priv;
2023 priv.max_fetched = priv.the_buffer;
2024 priv.insn_start = pc;
2031 op_index[0] = op_index[1] = op_index[2] = -1;
2035 start_codep = inbuf;
2038 if (setjmp (priv.bailout) != 0)
2040 /* Getting here means we tried for data but didn't get it. That
2041 means we have an incomplete instruction of some sort.
2042 However, we need to check at least one case here: fwait is a
2043 complete instruction, although we treat it as a prefix. */
2044 if (prefixes & PREFIX_FWAIT)
2048 p = memchr (inbuf, FWAIT_OPCODE, codep - inbuf);
2051 (*info->fprintf_func) (info->stream, "fwait");
2052 return (p + 1) - inbuf;
2058 /* This will at least let objdump print the bytes followed
2059 by the error message generated by fetch_data. */
2060 return codep - inbuf;
2070 FETCH_DATA (info, codep + 1);
2071 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2075 if ((prefixes & PREFIX_FWAIT)
2076 && ((*codep < 0xd8) || (*codep > 0xdf)))
2078 /* fwait not followed by floating point instruction. */
2079 (*info->fprintf_func) (info->stream, "fwait");
2080 /* There may be other prefixes. Skip any before the fwait. */
2081 return codep - inbuf;
2086 FETCH_DATA (info, codep + 2);
2088 dp = &dis386_twobyte_intel[*++codep];
2090 dp = &dis386_twobyte_att[*++codep];
2091 need_modrm = twobyte_has_modrm[*codep];
2092 uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
2097 dp = &dis386_intel[*codep];
2099 dp = &dis386_att[*codep];
2100 need_modrm = onebyte_has_modrm[*codep];
2105 if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
2107 if (prefixes & PREFIX_REPNZ)
2109 if (prefixes & PREFIX_LOCK)
2112 if (prefixes & PREFIX_DATA)
2115 if (prefixes & PREFIX_ADDR)
2118 if (sizeflag & AFLAG)
2119 oappend ("addr32 ");
2121 oappend ("addr16 ");
2126 FETCH_DATA (info, codep + 1);
2127 mod = (*codep >> 6) & 3;
2128 reg = (*codep >> 3) & 7;
2132 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2138 if (dp->name == NULL)
2140 switch(dp->bytemode2)
2143 dp = &grps[dp->bytemode1][reg];
2145 case USE_PREFIX_USER_TABLE:
2146 dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
2149 oappend (INTERNAL_DISASSEMBLER_ERROR);
2154 putop (dp->name, sizeflag);
2159 (*dp->op1)(dp->bytemode1, sizeflag);
2164 (*dp->op2)(dp->bytemode2, sizeflag);
2169 (*dp->op3)(dp->bytemode3, sizeflag);
2172 obufp = obuf + strlen (obuf);
2173 for (i = strlen (obuf); i < 6; i++)
2176 (*info->fprintf_func) (info->stream, "%s", obuf);
2178 /* The enter and bound instructions are printed with operands in the same
2179 order as the intel book; everything else is printed in reverse order. */
2180 if (intel_syntax || two_source_ops)
2185 op_ad = op_index[0];
2186 op_index[0] = op_index[2];
2187 op_index[2] = op_ad;
2198 if (op_index[0] != -1)
2199 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2201 (*info->fprintf_func) (info->stream, "%s", first);
2207 (*info->fprintf_func) (info->stream, ",");
2208 if (op_index[1] != -1)
2209 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2211 (*info->fprintf_func) (info->stream, "%s", second);
2217 (*info->fprintf_func) (info->stream, ",");
2218 if (op_index[2] != -1)
2219 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2221 (*info->fprintf_func) (info->stream, "%s", third);
2223 return codep - inbuf;
2226 static const char *float_mem_att[] = {
2301 static const char *float_mem_intel[] = {
2377 #define STi OP_STi, 0
2379 #define FGRPd9_2 NULL, NULL, 0
2380 #define FGRPd9_4 NULL, NULL, 1
2381 #define FGRPd9_5 NULL, NULL, 2
2382 #define FGRPd9_6 NULL, NULL, 3
2383 #define FGRPd9_7 NULL, NULL, 4
2384 #define FGRPda_5 NULL, NULL, 5
2385 #define FGRPdb_4 NULL, NULL, 6
2386 #define FGRPde_3 NULL, NULL, 7
2387 #define FGRPdf_4 NULL, NULL, 8
2389 static const struct dis386 float_reg[][8] = {
2392 { "fadd", ST, STi },
2393 { "fmul", ST, STi },
2396 { "fsub", ST, STi },
2397 { "fsubr", ST, STi },
2398 { "fdiv", ST, STi },
2399 { "fdivr", ST, STi },
2414 { "fcmovb", ST, STi },
2415 { "fcmove", ST, STi },
2416 { "fcmovbe",ST, STi },
2417 { "fcmovu", ST, STi },
2425 { "fcmovnb",ST, STi },
2426 { "fcmovne",ST, STi },
2427 { "fcmovnbe",ST, STi },
2428 { "fcmovnu",ST, STi },
2430 { "fucomi", ST, STi },
2431 { "fcomi", ST, STi },
2436 { "fadd", STi, ST },
2437 { "fmul", STi, ST },
2441 { "fsub", STi, ST },
2442 { "fsubr", STi, ST },
2443 { "fdiv", STi, ST },
2444 { "fdivr", STi, ST },
2446 { "fsubr", STi, ST },
2447 { "fsub", STi, ST },
2448 { "fdivr", STi, ST },
2449 { "fdiv", STi, ST },
2465 { "faddp", STi, ST },
2466 { "fmulp", STi, ST },
2470 { "fsubp", STi, ST },
2471 { "fsubrp", STi, ST },
2472 { "fdivp", STi, ST },
2473 { "fdivrp", STi, ST },
2475 { "fsubrp", STi, ST },
2476 { "fsubp", STi, ST },
2477 { "fdivrp", STi, ST },
2478 { "fdivp", STi, ST },
2488 { "fucomip",ST, STi },
2489 { "fcomip", ST, STi },
2495 static char *fgrps[][8] = {
2498 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2503 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2508 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2513 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2518 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2523 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2528 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2529 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2534 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2539 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2547 const struct dis386 *dp;
2548 unsigned char floatop;
2550 floatop = codep[-1];
2555 putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2557 putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2559 if (floatop == 0xdb)
2560 OP_E (x_mode, sizeflag);
2561 else if (floatop == 0xdd)
2562 OP_E (d_mode, sizeflag);
2564 OP_E (v_mode, sizeflag);
2569 dp = &float_reg[floatop - 0xd8][reg];
2570 if (dp->name == NULL)
2572 putop (fgrps[dp->bytemode1][rm], sizeflag);
2574 /* instruction fnstsw is only one with strange arg */
2575 if (floatop == 0xdf && codep[-1] == 0xe0)
2576 strcpy (op1out, names16[0]);
2580 putop (dp->name, sizeflag);
2584 (*dp->op1)(dp->bytemode1, sizeflag);
2587 (*dp->op2)(dp->bytemode2, sizeflag);
2593 OP_ST (ignore, sizeflag)
2602 OP_STi (ignore, sizeflag)
2606 sprintf (scratchbuf, "%%st(%d)", rm);
2607 oappend (scratchbuf);
2611 /* capital letters in template are macros */
2613 putop (template, sizeflag)
2614 const char *template;
2619 for (p = template; *p; p++)
2630 #ifdef SUFFIX_ALWAYS
2631 || (sizeflag & SUFFIX_ALWAYS)
2639 #ifdef SUFFIX_ALWAYS
2640 if (sizeflag & SUFFIX_ALWAYS)
2644 case 'E': /* For jcxz/jecxz */
2645 if (sizeflag & AFLAG)
2651 #ifdef SUFFIX_ALWAYS
2652 if (sizeflag & SUFFIX_ALWAYS)
2657 if ((prefixes & PREFIX_FWAIT) == 0)
2663 if ((prefixes & PREFIX_DATA)
2664 #ifdef SUFFIX_ALWAYS
2665 || (sizeflag & SUFFIX_ALWAYS)
2669 if (sizeflag & DFLAG)
2679 #ifdef SUFFIX_ALWAYS
2680 || (sizeflag & SUFFIX_ALWAYS)
2684 if (sizeflag & DFLAG)
2693 if (sizeflag & DFLAG)
2706 if (sizeflag & DFLAG)
2715 #ifdef SUFFIX_ALWAYS
2716 if (sizeflag & SUFFIX_ALWAYS)
2718 if (sizeflag & DFLAG)
2726 /* operand size flag for cwtl, cbtw */
2727 if (sizeflag & DFLAG)
2733 if (sizeflag & DFLAG)
2754 obufp += strlen (s);
2760 if (prefixes & PREFIX_CS)
2762 if (prefixes & PREFIX_DS)
2764 if (prefixes & PREFIX_SS)
2766 if (prefixes & PREFIX_ES)
2768 if (prefixes & PREFIX_FS)
2770 if (prefixes & PREFIX_GS)
2775 OP_indirE (bytemode, sizeflag)
2781 OP_E (bytemode, sizeflag);
2785 OP_E (bytemode, sizeflag)
2791 /* skip mod/rm byte */
2799 oappend (names8[rm]);
2802 oappend (names16[rm]);
2805 oappend (names32[rm]);
2808 if (sizeflag & DFLAG)
2809 oappend (names32[rm]);
2811 oappend (names16[rm]);
2814 if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */))
2815 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
2818 oappend (INTERNAL_DISASSEMBLER_ERROR);
2827 if (sizeflag & AFLAG) /* 32 bit address mode */
2842 FETCH_DATA (the_info, codep + 1);
2843 scale = (*codep >> 6) & 3;
2844 index = (*codep >> 3) & 7;
2859 FETCH_DATA (the_info, codep + 1);
2861 if ((disp & 0x80) != 0)
2870 if (mod != 0 || base == 5)
2872 sprintf (scratchbuf, "0x%x", disp);
2873 oappend (scratchbuf);
2876 if (havebase || (havesib && (index != 4 || scale != 0)))
2883 oappend("BYTE PTR ");
2886 oappend("WORD PTR ");
2889 oappend("DWORD PTR ");
2892 oappend("QWORD PTR ");
2895 oappend("XWORD PTR ");
2901 *obufp++ = open_char;
2904 oappend (names32[base]);
2913 *obufp++ = separator_char;
2916 sprintf (scratchbuf, "%s", names32[index]);
2919 sprintf (scratchbuf, ",%s", names32[index]);
2920 oappend (scratchbuf);
2924 && bytemode != b_mode
2925 && bytemode != w_mode
2926 && bytemode != v_mode))
2928 *obufp++ = scale_char;
2930 sprintf (scratchbuf, "%d", 1 << scale);
2931 oappend (scratchbuf);
2935 if (mod != 0 || base == 5)
2937 /* Don't print zero displacements */
2940 sprintf (scratchbuf, "+%d", disp);
2941 oappend (scratchbuf);
2945 sprintf (scratchbuf, "%d", disp);
2946 oappend (scratchbuf);
2950 *obufp++ = close_char;
2953 else if (intel_syntax)
2955 if (mod != 0 || base == 5)
2957 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
2958 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
2962 oappend (names_seg[3]);
2965 sprintf (scratchbuf, "0x%x", disp);
2966 oappend (scratchbuf);
2971 { /* 16 bit address mode */
2978 if ((disp & 0x8000) != 0)
2983 FETCH_DATA (the_info, codep + 1);
2985 if ((disp & 0x80) != 0)
2990 if ((disp & 0x8000) != 0)
2996 if (mod != 0 || rm == 6)
2998 sprintf (scratchbuf, "%d", disp);
2999 oappend (scratchbuf);
3002 if (mod != 0 || rm != 6)
3004 *obufp++ = open_char;
3006 oappend (index16[rm]);
3007 *obufp++ = close_char;
3014 OP_G (bytemode, sizeflag)
3021 oappend (names8[reg]);
3024 oappend (names16[reg]);
3027 oappend (names32[reg]);
3030 if (sizeflag & DFLAG)
3031 oappend (names32[reg]);
3033 oappend (names16[reg]);
3036 oappend (INTERNAL_DISASSEMBLER_ERROR);
3046 FETCH_DATA (the_info, codep + 4);
3047 x = *codep++ & 0xff;
3048 x |= (*codep++ & 0xff) << 8;
3049 x |= (*codep++ & 0xff) << 16;
3050 x |= (*codep++ & 0xff) << 24;
3059 FETCH_DATA (the_info, codep + 2);
3060 x = *codep++ & 0xff;
3061 x |= (*codep++ & 0xff) << 8;
3069 op_index[op_ad] = op_ad;
3070 op_address[op_ad] = op;
3074 OP_REG (code, sizeflag)
3085 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3086 case sp_reg: case bp_reg: case si_reg: case di_reg:
3087 s = names16[code - ax_reg];
3089 case es_reg: case ss_reg: case cs_reg:
3090 case ds_reg: case fs_reg: case gs_reg:
3091 s = names_seg[code - es_reg];
3093 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3094 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3095 s = names8[code - al_reg];
3097 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3098 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3099 if (sizeflag & DFLAG)
3100 s = names32[code - eAX_reg];
3102 s = names16[code - eAX_reg];
3105 s = INTERNAL_DISASSEMBLER_ERROR;
3112 OP_I (bytemode, sizeflag)
3121 FETCH_DATA (the_info, codep + 1);
3122 op = *codep++ & 0xff;
3125 if (sizeflag & DFLAG)
3134 oappend (INTERNAL_DISASSEMBLER_ERROR);
3139 sprintf (scratchbuf, "0x%x", op);
3141 sprintf (scratchbuf, "$0x%x", op);
3142 oappend (scratchbuf);
3143 scratchbuf[0] = '\0';
3147 OP_sI (bytemode, sizeflag)
3156 FETCH_DATA (the_info, codep + 1);
3158 if ((op & 0x80) != 0)
3162 if (sizeflag & DFLAG)
3167 if ((op & 0x8000) != 0)
3173 if ((op & 0x8000) != 0)
3177 oappend (INTERNAL_DISASSEMBLER_ERROR);
3181 sprintf (scratchbuf, "%d", op);
3183 sprintf (scratchbuf, "$0x%x", op);
3184 oappend (scratchbuf);
3188 OP_J (bytemode, sizeflag)
3198 FETCH_DATA (the_info, codep + 1);
3200 if ((disp & 0x80) != 0)
3204 if (sizeflag & DFLAG)
3209 /* for some reason, a data16 prefix on a jump instruction
3210 means that the pc is masked to 16 bits after the
3211 displacement is added! */
3216 oappend (INTERNAL_DISASSEMBLER_ERROR);
3219 disp = (start_pc + codep - start_codep + disp) & mask;
3221 sprintf (scratchbuf, "0x%x", disp);
3222 oappend (scratchbuf);
3227 OP_SEG (dummy, sizeflag)
3231 static char *sreg[] = {
3232 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3235 oappend (sreg[reg]);
3240 OP_DIR (dummy, sizeflag)
3246 if (sizeflag & DFLAG)
3256 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3257 oappend (scratchbuf);
3262 OP_OFF (ignore, sizeflag)
3270 if (sizeflag & AFLAG)
3277 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3278 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3280 oappend (names_seg[3]);
3284 sprintf (scratchbuf, "0x%x", off);
3285 oappend (scratchbuf);
3289 ptr_reg (code, sizeflag)
3295 if (sizeflag & AFLAG)
3296 s = names32[code - eAX_reg];
3298 s = names16[code - eAX_reg];
3304 OP_ESreg (code, sizeflag)
3309 ptr_reg (code, sizeflag);
3313 OP_DSreg (code, sizeflag)
3324 prefixes |= PREFIX_DS;
3326 ptr_reg (code, sizeflag);
3331 OP_C (dummy, sizeflag)
3335 sprintf (scratchbuf, "%%cr%d", reg);
3336 oappend (scratchbuf);
3341 OP_D (dummy, sizeflag)
3345 sprintf (scratchbuf, "%%db%d", reg);
3346 oappend (scratchbuf);
3351 OP_T (dummy, sizeflag)
3355 sprintf (scratchbuf, "%%tr%d", reg);
3356 oappend (scratchbuf);
3360 OP_Rd (bytemode, sizeflag)
3365 OP_E (bytemode, sizeflag);
3371 OP_MMX (ignore, sizeflag)
3375 sprintf (scratchbuf, "%%mm%d", reg);
3376 oappend (scratchbuf);
3380 OP_XMM (bytemode, sizeflag)
3384 sprintf (scratchbuf, "%%xmm%d", reg);
3385 oappend (scratchbuf);
3389 OP_EM (bytemode, sizeflag)
3395 OP_E (bytemode, sizeflag);
3400 sprintf (scratchbuf, "%%mm%d", rm);
3401 oappend (scratchbuf);
3405 OP_EX (bytemode, sizeflag)
3411 OP_E (bytemode, sizeflag);
3416 sprintf (scratchbuf, "%%xmm%d", rm);
3417 oappend (scratchbuf);
3421 OP_MS (bytemode, sizeflag)
3426 OP_EM (bytemode, sizeflag);
3431 static const char *Suffix3DNow[] = {
3432 /* 00 */ NULL, NULL, NULL, NULL,
3433 /* 04 */ NULL, NULL, NULL, NULL,
3434 /* 08 */ NULL, NULL, NULL, NULL,
3435 /* 0C */ NULL, "pi2fd", NULL, NULL,
3436 /* 10 */ NULL, NULL, NULL, NULL,
3437 /* 14 */ NULL, NULL, NULL, NULL,
3438 /* 18 */ NULL, NULL, NULL, NULL,
3439 /* 1C */ NULL, "pf2id", NULL, NULL,
3440 /* 20 */ NULL, NULL, NULL, NULL,
3441 /* 24 */ NULL, NULL, NULL, NULL,
3442 /* 28 */ NULL, NULL, NULL, NULL,
3443 /* 2C */ NULL, NULL, NULL, NULL,
3444 /* 30 */ NULL, NULL, NULL, NULL,
3445 /* 34 */ NULL, NULL, NULL, NULL,
3446 /* 38 */ NULL, NULL, NULL, NULL,
3447 /* 3C */ NULL, NULL, NULL, NULL,
3448 /* 40 */ NULL, NULL, NULL, NULL,
3449 /* 44 */ NULL, NULL, NULL, NULL,
3450 /* 48 */ NULL, NULL, NULL, NULL,
3451 /* 4C */ NULL, NULL, NULL, NULL,
3452 /* 50 */ NULL, NULL, NULL, NULL,
3453 /* 54 */ NULL, NULL, NULL, NULL,
3454 /* 58 */ NULL, NULL, NULL, NULL,
3455 /* 5C */ NULL, NULL, NULL, NULL,
3456 /* 60 */ NULL, NULL, NULL, NULL,
3457 /* 64 */ NULL, NULL, NULL, NULL,
3458 /* 68 */ NULL, NULL, NULL, NULL,
3459 /* 6C */ NULL, NULL, NULL, NULL,
3460 /* 70 */ NULL, NULL, NULL, NULL,
3461 /* 74 */ NULL, NULL, NULL, NULL,
3462 /* 78 */ NULL, NULL, NULL, NULL,
3463 /* 7C */ NULL, NULL, NULL, NULL,
3464 /* 80 */ NULL, NULL, NULL, NULL,
3465 /* 84 */ NULL, NULL, NULL, NULL,
3466 /* 88 */ NULL, NULL, NULL, NULL,
3467 /* 8C */ NULL, NULL, NULL, NULL,
3468 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3469 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3470 /* 98 */ NULL, NULL, "pfsub", NULL,
3471 /* 9C */ NULL, NULL, "pfadd", NULL,
3472 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3473 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3474 /* A8 */ NULL, NULL, "pfsubr", NULL,
3475 /* AC */ NULL, NULL, "pfacc", NULL,
3476 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3477 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3478 /* B8 */ NULL, NULL, NULL, NULL,
3479 /* BC */ NULL, NULL, NULL, "pavgusb",
3480 /* C0 */ NULL, NULL, NULL, NULL,
3481 /* C4 */ NULL, NULL, NULL, NULL,
3482 /* C8 */ NULL, NULL, NULL, NULL,
3483 /* CC */ NULL, NULL, NULL, NULL,
3484 /* D0 */ NULL, NULL, NULL, NULL,
3485 /* D4 */ NULL, NULL, NULL, NULL,
3486 /* D8 */ NULL, NULL, NULL, NULL,
3487 /* DC */ NULL, NULL, NULL, NULL,
3488 /* E0 */ NULL, NULL, NULL, NULL,
3489 /* E4 */ NULL, NULL, NULL, NULL,
3490 /* E8 */ NULL, NULL, NULL, NULL,
3491 /* EC */ NULL, NULL, NULL, NULL,
3492 /* F0 */ NULL, NULL, NULL, NULL,
3493 /* F4 */ NULL, NULL, NULL, NULL,
3494 /* F8 */ NULL, NULL, NULL, NULL,
3495 /* FC */ NULL, NULL, NULL, NULL,
3499 OP_3DNowSuffix (bytemode, sizeflag)
3503 const char *mnemonic;
3505 FETCH_DATA (the_info, codep + 1);
3506 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3507 place where an 8-bit immediate would normally go. ie. the last
3508 byte of the instruction. */
3509 obufp = obuf + strlen(obuf);
3510 mnemonic = Suffix3DNow[*codep++ & 0xff];
3515 /* Since a variable sized modrm/sib chunk is between the start
3516 of the opcode (0x0f0f) and the opcode suffix, we need to do
3517 all the modrm processing first, and don't know until now that
3518 we have a bad opcode. This necessitates some cleaning up. */
3526 static const char *simd_cmp_op [] = {
3538 OP_SIMD_Suffix (bytemode, sizeflag)
3542 unsigned int cmp_type;
3544 FETCH_DATA (the_info, codep + 1);
3545 obufp = obuf + strlen(obuf);
3546 cmp_type = *codep++ & 0xff;
3549 sprintf (scratchbuf, "cmp%s%cs",
3550 simd_cmp_op[cmp_type],
3551 prefixes & PREFIX_REPZ ? 's' : 'p');
3552 oappend (scratchbuf);
3556 /* We have a bad extension byte. Clean up. */
3564 SIMD_Fixup (extrachar, sizeflag)
3568 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3569 forms of these instructions. */
3572 char *p = obuf + strlen(obuf);
3581 static void BadOp (void)
3583 codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */