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
51 static int fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
55 /* Points to first byte not fetched. */
56 bfd_byte
*max_fetched
;
57 bfd_byte the_buffer
[MAXLEN
];
62 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
63 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
65 #define FETCH_DATA(info, addr) \
66 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
67 ? 1 : fetch_data ((info), (addr)))
70 fetch_data (info
, addr
)
71 struct disassemble_info
*info
;
75 struct dis_private
*priv
= (struct dis_private
*)info
->private_data
;
76 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
78 status
= (*info
->read_memory_func
) (start
,
80 addr
- priv
->max_fetched
,
84 (*info
->memory_error_func
) (status
, start
, info
);
85 longjmp (priv
->bailout
, 1);
88 priv
->max_fetched
= addr
;
92 #define Eb OP_E, b_mode
93 #define indirEb OP_indirE, b_mode
94 #define Gb OP_G, b_mode
95 #define Ev OP_E, v_mode
96 #define indirEv OP_indirE, v_mode
97 #define Ew OP_E, w_mode
98 #define Ma OP_E, v_mode
100 #define Mp OP_E, 0 /* ? */
101 #define Gv OP_G, v_mode
102 #define Gw OP_G, w_mode
103 #define Rw OP_rm, w_mode
104 #define Rd OP_rm, d_mode
105 #define Ib OP_I, b_mode
106 #define sIb OP_sI, b_mode /* sign extened byte */
107 #define Iv OP_I, v_mode
108 #define Iw OP_I, w_mode
109 #define Jb OP_J, b_mode
110 #define Jv OP_J, v_mode
112 #define ONE OP_ONE, 0
114 #define Cd OP_C, d_mode
115 #define Dd OP_D, d_mode
116 #define Td OP_T, d_mode
118 #define eAX OP_REG, eAX_reg
119 #define eBX OP_REG, eBX_reg
120 #define eCX OP_REG, eCX_reg
121 #define eDX OP_REG, eDX_reg
122 #define eSP OP_REG, eSP_reg
123 #define eBP OP_REG, eBP_reg
124 #define eSI OP_REG, eSI_reg
125 #define eDI OP_REG, eDI_reg
126 #define AL OP_REG, al_reg
127 #define CL OP_REG, cl_reg
128 #define DL OP_REG, dl_reg
129 #define BL OP_REG, bl_reg
130 #define AH OP_REG, ah_reg
131 #define CH OP_REG, ch_reg
132 #define DH OP_REG, dh_reg
133 #define BH OP_REG, bh_reg
134 #define AX OP_REG, ax_reg
135 #define DX OP_REG, dx_reg
136 #define indirDX OP_REG, indir_dx_reg
138 #define Sw OP_SEG, w_mode
140 #define Ob OP_OFF, b_mode
141 #define Ov OP_OFF, v_mode
142 #define Xb OP_DSreg, eSI_reg
143 #define Xv OP_DSreg, eSI_reg
144 #define Yb OP_ESreg, eDI_reg
145 #define Yv OP_ESreg, eDI_reg
146 #define DSBX OP_DSreg, eBX_reg
148 #define es OP_REG, es_reg
149 #define ss OP_REG, ss_reg
150 #define cs OP_REG, cs_reg
151 #define ds OP_REG, ds_reg
152 #define fs OP_REG, fs_reg
153 #define gs OP_REG, gs_reg
157 #define EM OP_EM, v_mode
158 #define EX OP_EX, v_mode
159 #define MS OP_MS, b_mode
161 #define OPSUF OP_3DNowSuffix, 0
162 #define OPSIMD OP_SIMD_Suffix, 0
164 /* bits in sizeflag */
165 #if 0 /* leave undefined until someone adds the extra flag to objdump */
166 #define SUFFIX_ALWAYS 4
171 typedef void (*op_rtn
) PARAMS ((int bytemode
, int sizeflag
));
173 static void OP_E
PARAMS ((int, int));
174 static void OP_G
PARAMS ((int, int));
175 static void OP_I
PARAMS ((int, int));
176 static void OP_indirE
PARAMS ((int, int));
177 static void OP_sI
PARAMS ((int, int));
178 static void OP_REG
PARAMS ((int, int));
179 static void OP_J
PARAMS ((int, int));
180 static void OP_DIR
PARAMS ((int, int));
181 static void OP_OFF
PARAMS ((int, int));
182 static void OP_ESreg
PARAMS ((int, int));
183 static void OP_DSreg
PARAMS ((int, int));
184 static void OP_SEG
PARAMS ((int, int));
185 static void OP_C
PARAMS ((int, int));
186 static void OP_D
PARAMS ((int, int));
187 static void OP_T
PARAMS ((int, int));
188 static void OP_rm
PARAMS ((int, int));
189 static void OP_ST
PARAMS ((int, int));
190 static void OP_STi
PARAMS ((int, int));
192 static void OP_ONE
PARAMS ((int, int));
194 static void OP_MMX
PARAMS ((int, int));
195 static void OP_XMM
PARAMS ((int, int));
196 static void OP_EM
PARAMS ((int, int));
197 static void OP_EX
PARAMS ((int, int));
198 static void OP_MS
PARAMS ((int, int));
199 static void OP_3DNowSuffix
PARAMS ((int, int));
200 static void OP_SIMD_Suffix
PARAMS ((int, int));
201 static void SIMD_Fixup
PARAMS ((int, int));
203 static void append_seg
PARAMS ((void));
204 static void set_op
PARAMS ((unsigned int op
));
205 static void putop
PARAMS ((char *template, int sizeflag
));
206 static void dofloat
PARAMS ((int sizeflag
));
207 static int get16
PARAMS ((void));
208 static int get32
PARAMS ((void));
209 static void ckprefix
PARAMS ((void));
210 static void ptr_reg
PARAMS ((int, int));
252 #define indir_dx_reg 150
255 #define USE_PREFIX_USER_TABLE 2
257 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
258 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
259 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
260 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
261 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
262 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
263 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
264 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
265 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
266 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
267 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
268 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
269 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
270 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
271 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
272 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
273 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
274 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
275 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
276 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
277 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
278 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
279 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
281 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
282 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
283 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
284 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
285 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
286 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
287 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
288 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
289 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
290 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
291 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
292 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
293 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
294 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
295 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
298 #define FLOAT NULL, NULL, FLOATCODE
310 /* Upper case letters in the instruction names here are macros.
311 'A' => print 'b' if no register operands or suffix_always is true
312 'B' => print 'b' if suffix_always is true
313 'E' => print 'e' if 32-bit form of jcxz
314 'L' => print 'l' if suffix_always is true
315 'N' => print 'n' if instruction has no wait "prefix"
316 'P' => print 'w' or 'l' if instruction has an operand size prefix,
317 or suffix_always is true
318 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
319 'R' => print 'w' or 'l'
320 'S' => print 'w' or 'l' if suffix_always is true
321 'W' => print 'b' or 'w'
324 static struct dis386 dis386_att
[] = {
342 { "(bad)" }, /* 0x0f extended opcode escape */
368 { "(bad)" }, /* SEG ES prefix */
377 { "(bad)" }, /* SEG CS prefix */
386 { "(bad)" }, /* SEG SS prefix */
395 { "(bad)" }, /* SEG DS prefix */
436 { "boundS", Gv
, Ma
},
438 { "(bad)" }, /* seg fs */
439 { "(bad)" }, /* seg gs */
440 { "(bad)" }, /* op size prefix */
441 { "(bad)" }, /* adr size prefix */
443 { "pushP", Iv
}, /* 386 book wrong */
444 { "imulS", Gv
, Ev
, Iv
},
445 { "pushP", sIb
}, /* push of byte really pushes 2 or 4 bytes */
446 { "imulS", Gv
, Ev
, sIb
},
447 { "insb", Yb
, indirDX
},
448 { "insR", Yv
, indirDX
},
449 { "outsb", indirDX
, Xb
},
450 { "outsR", indirDX
, Xv
},
489 { "xchgS", eCX
, eAX
},
490 { "xchgS", eDX
, eAX
},
491 { "xchgS", eBX
, eAX
},
492 { "xchgS", eSP
, eAX
},
493 { "xchgS", eBP
, eAX
},
494 { "xchgS", eSI
, eAX
},
495 { "xchgS", eDI
, eAX
},
500 { "(bad)" }, /* fwait */
516 { "testS", eAX
, Iv
},
518 { "stosS", Yv
, eAX
},
520 { "lodsS", eAX
, Xv
},
522 { "scasS", eAX
, Yv
},
551 { "enterP", Iw
, Ib
},
591 { "inB", AL
, indirDX
},
592 { "inS", eAX
, indirDX
},
593 { "outB", indirDX
, AL
},
594 { "outS", indirDX
, eAX
},
596 { "(bad)" }, /* lock prefix */
598 { "(bad)" }, /* repne */
599 { "(bad)" }, /* repz */
615 static struct dis386 dis386_intel
[] = {
633 { "(bad)" }, /* 0x0f extended opcode escape */
659 { "(bad)" }, /* SEG ES prefix */
668 { "(bad)" }, /* SEG CS prefix */
677 { "(bad)" }, /* SEG SS prefix */
686 { "(bad)" }, /* SEG DS prefix */
729 { "(bad)" }, /* seg fs */
730 { "(bad)" }, /* seg gs */
731 { "(bad)" }, /* op size prefix */
732 { "(bad)" }, /* adr size prefix */
734 { "push", Iv
}, /* 386 book wrong */
735 { "imul", Gv
, Ev
, Iv
},
736 { "push", sIb
}, /* push of byte really pushes 2 or 4 bytes */
737 { "imul", Gv
, Ev
, sIb
},
738 { "ins", Yb
, indirDX
},
739 { "ins", Yv
, indirDX
},
740 { "outs", indirDX
, Xb
},
741 { "outs", indirDX
, Xv
},
780 { "xchg", eCX
, eAX
},
781 { "xchg", eDX
, eAX
},
782 { "xchg", eBX
, eAX
},
783 { "xchg", eSP
, eAX
},
784 { "xchg", eBP
, eAX
},
785 { "xchg", eSI
, eAX
},
786 { "xchg", eDI
, eAX
},
788 { "cW" }, /* cwde and cbw */
789 { "cR" }, /* cdq and cwd */
791 { "(bad)" }, /* fwait */
882 { "in", AL
, indirDX
},
883 { "in", eAX
, indirDX
},
884 { "out", indirDX
, AL
},
885 { "out", indirDX
, eAX
},
887 { "(bad)" }, /* lock prefix */
889 { "(bad)" }, /* repne */
890 { "(bad)" }, /* repz */
906 static struct dis386 dis386_twobyte_att
[] = {
924 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
928 { "movlps", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
929 { "movlps", EX
, XM
, SIMD_Fixup
, 'h' },
930 { "unpcklps", XM
, EX
},
931 { "unpckhps", XM
, EX
},
932 { "movhps", XM
, EX
, SIMD_Fixup
, 'l' },
933 { "movhps", EX
, XM
, SIMD_Fixup
, 'l' },
936 { "(bad)" }, { "(bad)" }, { "(bad)" },
937 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
939 /* these are all backward in appendix A of the intel book */
949 { "movaps", XM
, EX
},
950 { "movaps", EX
, XM
},
952 { "movntps", Ev
, XM
},
955 { "ucomiss", XM
, EX
},
956 { "comiss", XM
, EX
},
958 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
959 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
961 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
962 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
964 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
965 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
967 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
968 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
970 { "movmskps", Gv
, EX
},
975 { "andnps", XM
, EX
},
988 { "punpcklbw", MX
, EM
},
989 { "punpcklwd", MX
, EM
},
990 { "punpckldq", MX
, EM
},
991 { "packsswb", MX
, EM
},
992 { "pcmpgtb", MX
, EM
},
993 { "pcmpgtw", MX
, EM
},
994 { "pcmpgtd", MX
, EM
},
995 { "packuswb", MX
, EM
},
997 { "punpckhbw", MX
, EM
},
998 { "punpckhwd", MX
, EM
},
999 { "punpckhdq", MX
, EM
},
1000 { "packssdw", MX
, EM
},
1001 { "(bad)" }, { "(bad)" },
1005 { "pshufw", MX
, EM
, Ib
},
1009 { "pcmpeqb", MX
, EM
},
1010 { "pcmpeqw", MX
, EM
},
1011 { "pcmpeqd", MX
, EM
},
1014 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1015 { "(bad)" }, { "(bad)" },
1059 { "shldS", Ev
, Gv
, Ib
},
1060 { "shldS", Ev
, Gv
, CL
},
1068 { "shrdS", Ev
, Gv
, Ib
},
1069 { "shrdS", Ev
, Gv
, CL
},
1071 { "imulS", Gv
, Ev
},
1073 { "cmpxchgB", Eb
, Gb
},
1074 { "cmpxchgS", Ev
, Gv
},
1075 { "lssS", Gv
, Mp
}, /* 386 lists only Mp */
1077 { "lfsS", Gv
, Mp
}, /* 386 lists only Mp */
1078 { "lgsS", Gv
, Mp
}, /* 386 lists only Mp */
1079 { "movzbR", Gv
, Eb
},
1080 { "movzwR", Gv
, Ew
}, /* yes, there really is movzww ! */
1088 { "movsbR", Gv
, Eb
},
1089 { "movswR", Gv
, Ew
}, /* yes, there really is movsww ! */
1091 { "xaddB", Eb
, Gb
},
1092 { "xaddS", Ev
, Gv
},
1095 { "pinsrw", MX
, Ev
, Ib
},
1096 { "pextrw", Ev
, MX
, Ib
},
1097 { "shufps", XM
, EX
, Ib
},
1100 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1110 { "psrlw", MX
, EM
},
1111 { "psrld", MX
, EM
},
1112 { "psrlq", MX
, EM
},
1114 { "pmullw", MX
, EM
},
1116 { "pmovmskb", Ev
, MX
},
1118 { "psubusb", MX
, EM
},
1119 { "psubusw", MX
, EM
},
1120 { "pminub", MX
, EM
},
1122 { "paddusb", MX
, EM
},
1123 { "paddusw", MX
, EM
},
1124 { "pmaxub", MX
, EM
},
1125 { "pandn", MX
, EM
},
1127 { "pavgb", MX
, EM
},
1128 { "psraw", MX
, EM
},
1129 { "psrad", MX
, EM
},
1130 { "pavgw", MX
, EM
},
1131 { "pmulhuw", MX
, EM
},
1132 { "pmulhw", MX
, EM
},
1134 { "movntq", Ev
, MX
},
1136 { "psubsb", MX
, EM
},
1137 { "psubsw", MX
, EM
},
1138 { "pminsw", MX
, EM
},
1140 { "paddsb", MX
, EM
},
1141 { "paddsw", MX
, EM
},
1142 { "pmaxsw", MX
, EM
},
1146 { "psllw", MX
, EM
},
1147 { "pslld", MX
, EM
},
1148 { "psllq", MX
, EM
},
1150 { "pmaddwd", MX
, EM
},
1151 { "psadbw", MX
, EM
},
1152 { "maskmovq", MX
, EM
},
1154 { "psubb", MX
, EM
},
1155 { "psubw", MX
, EM
},
1156 { "psubd", MX
, EM
},
1158 { "paddb", MX
, EM
},
1159 { "paddw", MX
, EM
},
1160 { "paddd", MX
, EM
},
1164 static struct dis386 dis386_twobyte_intel
[] = {
1182 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1186 { "movlps", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1187 { "movlps", EX
, XM
, SIMD_Fixup
, 'h' },
1188 { "unpcklps", XM
, EX
},
1189 { "unpckhps", XM
, EX
},
1190 { "movhps", XM
, EX
, SIMD_Fixup
, 'l' },
1191 { "movhps", EX
, XM
, SIMD_Fixup
, 'l' },
1194 { "(bad)" }, { "(bad)" }, { "(bad)" },
1195 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1197 /* these are all backward in appendix A of the intel book */
1207 { "movaps", XM
, EX
},
1208 { "movaps", EX
, XM
},
1210 { "movntps", Ev
, XM
},
1213 { "ucomiss", XM
, EX
},
1214 { "comiss", XM
, EX
},
1216 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1217 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1219 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1220 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1222 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
1223 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
1225 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
1226 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
1228 { "movmskps", Gv
, EX
},
1232 { "andps", XM
, EX
},
1233 { "andnps", XM
, EX
},
1235 { "xorps", XM
, EX
},
1246 { "punpcklbw", MX
, EM
},
1247 { "punpcklwd", MX
, EM
},
1248 { "punpckldq", MX
, EM
},
1249 { "packsswb", MX
, EM
},
1250 { "pcmpgtb", MX
, EM
},
1251 { "pcmpgtw", MX
, EM
},
1252 { "pcmpgtd", MX
, EM
},
1253 { "packuswb", MX
, EM
},
1255 { "punpckhbw", MX
, EM
},
1256 { "punpckhwd", MX
, EM
},
1257 { "punpckhdq", MX
, EM
},
1258 { "packssdw", MX
, EM
},
1259 { "(bad)" }, { "(bad)" },
1263 { "pshufw", MX
, EM
, Ib
},
1267 { "pcmpeqb", MX
, EM
},
1268 { "pcmpeqw", MX
, EM
},
1269 { "pcmpeqd", MX
, EM
},
1272 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1273 { "(bad)" }, { "(bad)" },
1317 { "shld", Ev
, Gv
, Ib
},
1318 { "shld", Ev
, Gv
, CL
},
1326 { "shrd", Ev
, Gv
, Ib
},
1327 { "shrd", Ev
, Gv
, CL
},
1331 { "cmpxchg", Eb
, Gb
},
1332 { "cmpxchg", Ev
, Gv
},
1333 { "lss", Gv
, Mp
}, /* 386 lists only Mp */
1335 { "lfs", Gv
, Mp
}, /* 386 lists only Mp */
1336 { "lgs", Gv
, Mp
}, /* 386 lists only Mp */
1337 { "movzx", Gv
, Eb
},
1338 { "movzx", Gv
, Ew
},
1346 { "movsx", Gv
, Eb
},
1347 { "movsx", Gv
, Ew
},
1353 { "pinsrw", MX
, Ev
, Ib
},
1354 { "pextrw", Ev
, MX
, Ib
},
1355 { "shufps", XM
, EX
, Ib
},
1358 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1368 { "psrlw", MX
, EM
},
1369 { "psrld", MX
, EM
},
1370 { "psrlq", MX
, EM
},
1372 { "pmullw", MX
, EM
},
1374 { "pmovmskb", Ev
, MX
},
1376 { "psubusb", MX
, EM
},
1377 { "psubusw", MX
, EM
},
1378 { "pminub", MX
, EM
},
1380 { "paddusb", MX
, EM
},
1381 { "paddusw", MX
, EM
},
1382 { "pmaxub", MX
, EM
},
1383 { "pandn", MX
, EM
},
1385 { "pavgb", MX
, EM
},
1386 { "psraw", MX
, EM
},
1387 { "psrad", MX
, EM
},
1388 { "pavgw", MX
, EM
},
1389 { "pmulhuw", MX
, EM
},
1390 { "pmulhw", MX
, EM
},
1392 { "movntq", Ev
, MX
},
1394 { "psubsb", MX
, EM
},
1395 { "psubsw", MX
, EM
},
1396 { "pminsw", MX
, EM
},
1398 { "paddsb", MX
, EM
},
1399 { "paddsw", MX
, EM
},
1400 { "pmaxsw", MX
, EM
},
1404 { "psllw", MX
, EM
},
1405 { "pslld", MX
, EM
},
1406 { "psllq", MX
, EM
},
1408 { "pmaddwd", MX
, EM
},
1409 { "psadbw", MX
, EM
},
1410 { "maskmovq", MX
, EM
},
1412 { "psubb", MX
, EM
},
1413 { "psubw", MX
, EM
},
1414 { "psubd", MX
, EM
},
1416 { "paddb", MX
, EM
},
1417 { "paddw", MX
, EM
},
1418 { "paddd", MX
, EM
},
1422 static const unsigned char onebyte_has_modrm
[256] = {
1423 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1424 /* ------------------------------- */
1425 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1426 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1427 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1428 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1429 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1430 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1431 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1432 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1433 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1434 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1435 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1436 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1437 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1438 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1439 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1440 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1441 /* ------------------------------- */
1442 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1445 static const unsigned char twobyte_has_modrm
[256] = {
1446 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1447 /* ------------------------------- */
1448 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1449 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1450 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1451 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1452 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1453 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1454 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1455 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1456 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1457 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1458 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1459 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1460 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1461 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1462 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1463 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1464 /* ------------------------------- */
1465 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1468 static const unsigned char twobyte_uses_f3_prefix
[256] = {
1469 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1470 /* ------------------------------- */
1471 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1472 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1473 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1474 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1475 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1476 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1477 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1478 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1479 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1480 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1481 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1482 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1483 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1484 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1485 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1486 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1487 /* ------------------------------- */
1488 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1491 static char obuf
[100];
1493 static char scratchbuf
[100];
1494 static unsigned char *start_codep
;
1495 static unsigned char *insn_codep
;
1496 static unsigned char *codep
;
1497 static disassemble_info
*the_info
;
1501 static void oappend
PARAMS ((char *s
));
1503 static char *names32
[]={
1504 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1506 static char *names16
[] = {
1507 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1509 static char *names8
[] = {
1510 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1512 static char *names_seg
[] = {
1513 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1515 static char *index16
[] = {
1516 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1519 static struct dis386 grps
[][8] = {
1544 { "addQ", Ev
, sIb
},
1546 { "adcQ", Ev
, sIb
},
1547 { "sbbQ", Ev
, sIb
},
1548 { "andQ", Ev
, sIb
},
1549 { "subQ", Ev
, sIb
},
1550 { "xorQ", Ev
, sIb
},
1621 { "testA", Eb
, Ib
},
1626 { "imulB", AL
, Eb
},
1632 { "testQ", Ev
, Iv
},
1636 { "mulS", eAX
, Ev
},
1637 { "imulS", eAX
, Ev
},
1638 { "divS", eAX
, Ev
},
1639 { "idivS", eAX
, Ev
},
1656 { "callP", indirEv
},
1657 { "callP", indirEv
},
1658 { "jmpP", indirEv
},
1659 { "ljmpP", indirEv
},
1699 { "cmpxchg8b", Ev
},
1711 { "psrlw", MS
, Ib
},
1713 { "psraw", MS
, Ib
},
1715 { "psllw", MS
, Ib
},
1722 { "psrld", MS
, Ib
},
1724 { "psrad", MS
, Ib
},
1726 { "pslld", MS
, Ib
},
1733 { "psrlq", MS
, Ib
},
1737 { "psllq", MS
, Ib
},
1753 { "prefetchnta", Ev
},
1754 { "prefetcht0", Ev
},
1755 { "prefetcht1", Ev
},
1756 { "prefetcht2", Ev
},
1765 { "prefetchw", Eb
},
1776 static struct dis386 prefix_user_table
[][2] = {
1779 { "addps", XM
, EX
},
1780 { "addss", XM
, EX
},
1784 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX */
1785 { "", XM
, EX
, OPSIMD
},
1789 { "cvtpi2ps", XM
, EM
},
1790 { "cvtsi2ss", XM
, Ev
},
1794 { "cvtps2pi", MX
, EX
},
1795 { "cvtss2si", Gv
, EX
},
1799 { "cvttps2pi", MX
, EX
},
1800 { "cvttss2si", Gv
, EX
},
1804 { "divps", XM
, EX
},
1805 { "divss", XM
, EX
},
1809 { "maxps", XM
, EX
},
1810 { "maxss", XM
, EX
},
1814 { "minps", XM
, EX
},
1815 { "minss", XM
, EX
},
1819 { "movups", XM
, EX
},
1820 { "movss", XM
, EX
},
1824 { "movups", EX
, XM
},
1825 { "movss", EX
, XM
},
1829 { "mulps", XM
, EX
},
1830 { "mulss", XM
, EX
},
1834 { "rcpps", XM
, EX
},
1835 { "rcpss", XM
, EX
},
1839 { "rsqrtps", XM
, EX
},
1840 { "rsqrtss", XM
, EX
},
1844 { "sqrtps", XM
, EX
},
1845 { "sqrtss", XM
, EX
},
1849 { "subps", XM
, EX
},
1850 { "subss", XM
, EX
},
1854 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1856 #define PREFIX_REPZ 1
1857 #define PREFIX_REPNZ 2
1858 #define PREFIX_LOCK 4
1860 #define PREFIX_SS 0x10
1861 #define PREFIX_DS 0x20
1862 #define PREFIX_ES 0x40
1863 #define PREFIX_FS 0x80
1864 #define PREFIX_GS 0x100
1865 #define PREFIX_DATA 0x200
1866 #define PREFIX_ADDR 0x400
1867 #define PREFIX_FWAIT 0x800
1869 static int prefixes
;
1877 FETCH_DATA (the_info
, codep
+ 1);
1881 prefixes
|= PREFIX_REPZ
;
1884 prefixes
|= PREFIX_REPNZ
;
1887 prefixes
|= PREFIX_LOCK
;
1890 prefixes
|= PREFIX_CS
;
1893 prefixes
|= PREFIX_SS
;
1896 prefixes
|= PREFIX_DS
;
1899 prefixes
|= PREFIX_ES
;
1902 prefixes
|= PREFIX_FS
;
1905 prefixes
|= PREFIX_GS
;
1908 prefixes
|= PREFIX_DATA
;
1911 prefixes
|= PREFIX_ADDR
;
1914 /* fwait is really an instruction. If there are prefixes
1915 before the fwait, they belong to the fwait, *not* to the
1916 following instruction. */
1919 prefixes
|= PREFIX_FWAIT
;
1923 prefixes
= PREFIX_FWAIT
;
1932 static char op1out
[100], op2out
[100], op3out
[100];
1933 static int op_ad
, op_index
[3];
1934 static unsigned int op_address
[3];
1935 static unsigned int start_pc
;
1939 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1940 * (see topic "Redundant prefixes" in the "Differences from 8086"
1941 * section of the "Virtual 8086 Mode" chapter.)
1942 * 'pc' should be the address of this instruction, it will
1943 * be used to print the target address if this is a relative jump or call
1944 * The function returns the length of this instruction in bytes.
1947 static int print_insn_x86
1948 PARAMS ((bfd_vma pc
, disassemble_info
*info
, int sizeflag
));
1949 static int print_insn_i386
1950 PARAMS ((bfd_vma pc
, disassemble_info
*info
));
1952 static char intel_syntax
;
1953 static char open_char
;
1954 static char close_char
;
1955 static char separator_char
;
1956 static char scale_char
;
1959 print_insn_i386_att (pc
, info
)
1961 disassemble_info
*info
;
1966 separator_char
= ',';
1969 return print_insn_i386 (pc
, info
);
1973 print_insn_i386_intel (pc
, info
)
1975 disassemble_info
*info
;
1980 separator_char
= '+';
1983 return print_insn_i386 (pc
, info
);
1987 print_insn_i386 (pc
, info
)
1989 disassemble_info
*info
;
1992 if (info
->mach
== bfd_mach_i386_i386
1993 || info
->mach
== bfd_mach_i386_i386_intel_syntax
)
1994 flags
= AFLAG
|DFLAG
;
1995 else if (info
->mach
== bfd_mach_i386_i8086
)
1999 return print_insn_x86 (pc
, info
, flags
);
2003 print_insn_x86 (pc
, info
, sizeflag
)
2005 disassemble_info
*info
;
2011 char *first
, *second
, *third
;
2013 unsigned char need_modrm
;
2014 unsigned char uses_f3_prefix
;
2016 struct dis_private priv
;
2017 bfd_byte
*inbuf
= priv
.the_buffer
;
2019 /* The output looks better if we put 6 bytes on a line, since that
2020 puts most long word instructions on a single line. */
2021 info
->bytes_per_line
= 6;
2023 info
->private_data
= (PTR
) &priv
;
2024 priv
.max_fetched
= priv
.the_buffer
;
2025 priv
.insn_start
= pc
;
2026 if (setjmp (priv
.bailout
) != 0)
2035 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2039 start_codep
= inbuf
;
2046 FETCH_DATA (info
, codep
+ 1);
2047 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2051 if ((prefixes
& PREFIX_FWAIT
)
2052 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2054 /* fwait not followed by floating point instruction. */
2055 (*info
->fprintf_func
) (info
->stream
, "fwait");
2056 /* There may be other prefixes. Skip any before the fwait. */
2057 return codep
- inbuf
;
2062 FETCH_DATA (info
, codep
+ 2);
2064 dp
= &dis386_twobyte_intel
[*++codep
];
2066 dp
= &dis386_twobyte_att
[*++codep
];
2067 need_modrm
= twobyte_has_modrm
[*codep
];
2068 uses_f3_prefix
= twobyte_uses_f3_prefix
[*codep
];
2073 dp
= &dis386_intel
[*codep
];
2075 dp
= &dis386_att
[*codep
];
2076 need_modrm
= onebyte_has_modrm
[*codep
];
2081 if (!uses_f3_prefix
&& (prefixes
& PREFIX_REPZ
))
2083 if (prefixes
& PREFIX_REPNZ
)
2085 if (prefixes
& PREFIX_LOCK
)
2088 if (prefixes
& PREFIX_DATA
)
2091 if (prefixes
& PREFIX_ADDR
)
2094 if (sizeflag
& AFLAG
)
2095 oappend ("addr32 ");
2097 oappend ("addr16 ");
2102 FETCH_DATA (info
, codep
+ 1);
2103 mod
= (*codep
>> 6) & 3;
2104 reg
= (*codep
>> 3) & 7;
2108 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2114 if (dp
->name
== NULL
)
2116 switch(dp
->bytemode2
)
2119 dp
= &grps
[dp
->bytemode1
][reg
];
2121 case USE_PREFIX_USER_TABLE
:
2122 dp
= &prefix_user_table
[dp
->bytemode1
][prefixes
& PREFIX_REPZ
? 1 : 0];
2125 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2130 putop (dp
->name
, sizeflag
);
2135 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
2140 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
2145 (*dp
->op3
)(dp
->bytemode3
, sizeflag
);
2148 obufp
= obuf
+ strlen (obuf
);
2149 for (i
= strlen (obuf
); i
< 6; i
++)
2152 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2154 /* The enter and bound instructions are printed with operands in the same
2155 order as the intel book; everything else is printed in reverse order. */
2156 if (intel_syntax
|| two_source_ops
)
2161 op_ad
= op_index
[0];
2162 op_index
[0] = op_index
[2];
2163 op_index
[2] = op_ad
;
2174 if (op_index
[0] != -1)
2175 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2177 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2183 (*info
->fprintf_func
) (info
->stream
, ",");
2184 if (op_index
[1] != -1)
2185 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2187 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2193 (*info
->fprintf_func
) (info
->stream
, ",");
2194 if (op_index
[2] != -1)
2195 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2197 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2199 return codep
- inbuf
;
2202 static char *float_mem_att
[] = {
2277 static char *float_mem_intel
[] = {
2353 #define STi OP_STi, 0
2355 #define FGRPd9_2 NULL, NULL, 0
2356 #define FGRPd9_4 NULL, NULL, 1
2357 #define FGRPd9_5 NULL, NULL, 2
2358 #define FGRPd9_6 NULL, NULL, 3
2359 #define FGRPd9_7 NULL, NULL, 4
2360 #define FGRPda_5 NULL, NULL, 5
2361 #define FGRPdb_4 NULL, NULL, 6
2362 #define FGRPde_3 NULL, NULL, 7
2363 #define FGRPdf_4 NULL, NULL, 8
2365 static struct dis386 float_reg
[][8] = {
2368 { "fadd", ST
, STi
},
2369 { "fmul", ST
, STi
},
2372 { "fsub", ST
, STi
},
2373 { "fsubr", ST
, STi
},
2374 { "fdiv", ST
, STi
},
2375 { "fdivr", ST
, STi
},
2390 { "fcmovb", ST
, STi
},
2391 { "fcmove", ST
, STi
},
2392 { "fcmovbe",ST
, STi
},
2393 { "fcmovu", ST
, STi
},
2401 { "fcmovnb",ST
, STi
},
2402 { "fcmovne",ST
, STi
},
2403 { "fcmovnbe",ST
, STi
},
2404 { "fcmovnu",ST
, STi
},
2406 { "fucomi", ST
, STi
},
2407 { "fcomi", ST
, STi
},
2412 { "fadd", STi
, ST
},
2413 { "fmul", STi
, ST
},
2417 { "fsub", STi
, ST
},
2418 { "fsubr", STi
, ST
},
2419 { "fdiv", STi
, ST
},
2420 { "fdivr", STi
, ST
},
2422 { "fsubr", STi
, ST
},
2423 { "fsub", STi
, ST
},
2424 { "fdivr", STi
, ST
},
2425 { "fdiv", STi
, ST
},
2441 { "faddp", STi
, ST
},
2442 { "fmulp", STi
, ST
},
2446 { "fsubp", STi
, ST
},
2447 { "fsubrp", STi
, ST
},
2448 { "fdivp", STi
, ST
},
2449 { "fdivrp", STi
, ST
},
2451 { "fsubrp", STi
, ST
},
2452 { "fsubp", STi
, ST
},
2453 { "fdivrp", STi
, ST
},
2454 { "fdivp", STi
, ST
},
2464 { "fucomip",ST
, STi
},
2465 { "fcomip", ST
, STi
},
2471 static char *fgrps
[][8] = {
2474 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2479 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2484 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2489 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2494 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2499 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2504 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2505 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2510 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2515 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2524 unsigned char floatop
;
2526 floatop
= codep
[-1];
2531 putop (float_mem_intel
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2533 putop (float_mem_att
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2535 if (floatop
== 0xdb)
2536 OP_E (x_mode
, sizeflag
);
2537 else if (floatop
== 0xdd)
2538 OP_E (d_mode
, sizeflag
);
2540 OP_E (v_mode
, sizeflag
);
2545 dp
= &float_reg
[floatop
- 0xd8][reg
];
2546 if (dp
->name
== NULL
)
2548 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2550 /* instruction fnstsw is only one with strange arg */
2551 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2552 strcpy (op1out
, names16
[0]);
2556 putop (dp
->name
, sizeflag
);
2560 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
2563 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
2569 OP_ST (ignore
, sizeflag
)
2578 OP_STi (ignore
, sizeflag
)
2582 sprintf (scratchbuf
, "%%st(%d)", rm
);
2583 oappend (scratchbuf
);
2587 /* capital letters in template are macros */
2589 putop (template, sizeflag
)
2595 for (p
= template; *p
; p
++)
2606 #ifdef SUFFIX_ALWAYS
2607 || (sizeflag
& SUFFIX_ALWAYS
)
2615 #ifdef SUFFIX_ALWAYS
2616 if (sizeflag
& SUFFIX_ALWAYS
)
2620 case 'E': /* For jcxz/jecxz */
2621 if (sizeflag
& AFLAG
)
2627 #ifdef SUFFIX_ALWAYS
2628 if (sizeflag
& SUFFIX_ALWAYS
)
2633 if ((prefixes
& PREFIX_FWAIT
) == 0)
2639 if ((prefixes
& PREFIX_DATA
)
2640 #ifdef SUFFIX_ALWAYS
2641 || (sizeflag
& SUFFIX_ALWAYS
)
2645 if (sizeflag
& DFLAG
)
2655 #ifdef SUFFIX_ALWAYS
2656 || (sizeflag
& SUFFIX_ALWAYS
)
2660 if (sizeflag
& DFLAG
)
2669 if (sizeflag
& DFLAG
)
2682 if (sizeflag
& DFLAG
)
2691 #ifdef SUFFIX_ALWAYS
2692 if (sizeflag
& SUFFIX_ALWAYS
)
2694 if (sizeflag
& DFLAG
)
2702 /* operand size flag for cwtl, cbtw */
2703 if (sizeflag
& DFLAG
)
2709 if (sizeflag
& DFLAG
)
2730 obufp
+= strlen (s
);
2736 if (prefixes
& PREFIX_CS
)
2738 if (prefixes
& PREFIX_DS
)
2740 if (prefixes
& PREFIX_SS
)
2742 if (prefixes
& PREFIX_ES
)
2744 if (prefixes
& PREFIX_FS
)
2746 if (prefixes
& PREFIX_GS
)
2751 OP_indirE (bytemode
, sizeflag
)
2757 OP_E (bytemode
, sizeflag
);
2761 OP_E (bytemode
, sizeflag
)
2767 /* skip mod/rm byte */
2775 oappend (names8
[rm
]);
2778 oappend (names16
[rm
]);
2781 if (sizeflag
& DFLAG
)
2782 oappend (names32
[rm
]);
2784 oappend (names16
[rm
]);
2786 case 0: /* sfence */
2789 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2798 if (sizeflag
& AFLAG
) /* 32 bit address mode */
2813 FETCH_DATA (the_info
, codep
+ 1);
2814 scale
= (*codep
>> 6) & 3;
2815 index
= (*codep
>> 3) & 7;
2830 FETCH_DATA (the_info
, codep
+ 1);
2832 if ((disp
& 0x80) != 0)
2841 if (mod
!= 0 || base
== 5)
2843 sprintf (scratchbuf
, "0x%x", disp
);
2844 oappend (scratchbuf
);
2847 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
2854 oappend("BYTE PTR ");
2857 oappend("WORD PTR ");
2860 oappend("DWORD PTR ");
2863 oappend("QWORD PTR ");
2866 oappend("XWORD PTR ");
2872 *obufp
++ = open_char
;
2875 oappend (names32
[base
]);
2884 *obufp
++ = separator_char
;
2887 sprintf (scratchbuf
, "%s", names32
[index
]);
2890 sprintf (scratchbuf
, ",%s", names32
[index
]);
2891 oappend (scratchbuf
);
2895 && bytemode
!= b_mode
2896 && bytemode
!= w_mode
2897 && bytemode
!= v_mode
))
2899 *obufp
++ = scale_char
;
2901 sprintf (scratchbuf
, "%d", 1 << scale
);
2902 oappend (scratchbuf
);
2906 if (mod
!= 0 || base
== 5)
2908 /* Don't print zero displacements */
2911 sprintf (scratchbuf
, "+%d", disp
);
2912 oappend (scratchbuf
);
2916 sprintf (scratchbuf
, "%d", disp
);
2917 oappend (scratchbuf
);
2921 *obufp
++ = close_char
;
2924 else if (intel_syntax
)
2926 if (mod
!= 0 || base
== 5)
2928 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
2929 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
2933 oappend (names_seg
[3]);
2936 sprintf (scratchbuf
, "0x%x", disp
);
2937 oappend (scratchbuf
);
2942 { /* 16 bit address mode */
2949 if ((disp
& 0x8000) != 0)
2954 FETCH_DATA (the_info
, codep
+ 1);
2956 if ((disp
& 0x80) != 0)
2961 if ((disp
& 0x8000) != 0)
2967 if (mod
!= 0 || rm
== 6)
2969 sprintf (scratchbuf
, "%d", disp
);
2970 oappend (scratchbuf
);
2973 if (mod
!= 0 || rm
!= 6)
2975 *obufp
++ = open_char
;
2977 oappend (index16
[rm
]);
2978 *obufp
++ = close_char
;
2985 OP_G (bytemode
, sizeflag
)
2992 oappend (names8
[reg
]);
2995 oappend (names16
[reg
]);
2998 oappend (names32
[reg
]);
3001 if (sizeflag
& DFLAG
)
3002 oappend (names32
[reg
]);
3004 oappend (names16
[reg
]);
3007 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3017 FETCH_DATA (the_info
, codep
+ 4);
3018 x
= *codep
++ & 0xff;
3019 x
|= (*codep
++ & 0xff) << 8;
3020 x
|= (*codep
++ & 0xff) << 16;
3021 x
|= (*codep
++ & 0xff) << 24;
3030 FETCH_DATA (the_info
, codep
+ 2);
3031 x
= *codep
++ & 0xff;
3032 x
|= (*codep
++ & 0xff) << 8;
3040 op_index
[op_ad
] = op_ad
;
3041 op_address
[op_ad
] = op
;
3045 OP_REG (code
, sizeflag
)
3056 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3057 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3058 s
= names16
[code
- ax_reg
];
3060 case es_reg
: case ss_reg
: case cs_reg
:
3061 case ds_reg
: case fs_reg
: case gs_reg
:
3062 s
= names_seg
[code
- es_reg
];
3064 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3065 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3066 s
= names8
[code
- al_reg
];
3068 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3069 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3070 if (sizeflag
& DFLAG
)
3071 s
= names32
[code
- eAX_reg
];
3073 s
= names16
[code
- eAX_reg
];
3076 s
= INTERNAL_DISASSEMBLER_ERROR
;
3083 OP_I (bytemode
, sizeflag
)
3092 FETCH_DATA (the_info
, codep
+ 1);
3093 op
= *codep
++ & 0xff;
3096 if (sizeflag
& DFLAG
)
3105 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3110 sprintf (scratchbuf
, "0x%x", op
);
3112 sprintf (scratchbuf
, "$0x%x", op
);
3113 oappend (scratchbuf
);
3114 scratchbuf
[0] = '\0';
3118 OP_sI (bytemode
, sizeflag
)
3127 FETCH_DATA (the_info
, codep
+ 1);
3129 if ((op
& 0x80) != 0)
3133 if (sizeflag
& DFLAG
)
3138 if ((op
& 0x8000) != 0)
3144 if ((op
& 0x8000) != 0)
3148 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3152 sprintf (scratchbuf
, "%d", op
);
3154 sprintf (scratchbuf
, "$0x%x", op
);
3155 oappend (scratchbuf
);
3159 OP_J (bytemode
, sizeflag
)
3169 FETCH_DATA (the_info
, codep
+ 1);
3171 if ((disp
& 0x80) != 0)
3175 if (sizeflag
& DFLAG
)
3180 /* for some reason, a data16 prefix on a jump instruction
3181 means that the pc is masked to 16 bits after the
3182 displacement is added! */
3187 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3190 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
3192 sprintf (scratchbuf
, "0x%x", disp
);
3193 oappend (scratchbuf
);
3198 OP_SEG (dummy
, sizeflag
)
3202 static char *sreg
[] = {
3203 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3206 oappend (sreg
[reg
]);
3211 OP_DIR (dummy
, sizeflag
)
3217 if (sizeflag
& DFLAG
)
3227 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
3228 oappend (scratchbuf
);
3233 OP_OFF (ignore
, sizeflag
)
3241 if (sizeflag
& AFLAG
)
3248 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3249 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3251 oappend (names_seg
[3]);
3255 sprintf (scratchbuf
, "0x%x", off
);
3256 oappend (scratchbuf
);
3260 ptr_reg (code
, sizeflag
)
3266 if (sizeflag
& AFLAG
)
3267 s
= names32
[code
- eAX_reg
];
3269 s
= names16
[code
- eAX_reg
];
3275 OP_ESreg (code
, sizeflag
)
3280 ptr_reg (code
, sizeflag
);
3284 OP_DSreg (code
, sizeflag
)
3295 prefixes
|= PREFIX_DS
;
3297 ptr_reg (code
, sizeflag
);
3305 OP_ONE (dummy
, sizeflag
)
3316 OP_C (dummy
, sizeflag
)
3320 codep
++; /* skip mod/rm */
3321 sprintf (scratchbuf
, "%%cr%d", reg
);
3322 oappend (scratchbuf
);
3327 OP_D (dummy
, sizeflag
)
3331 codep
++; /* skip mod/rm */
3332 sprintf (scratchbuf
, "%%db%d", reg
);
3333 oappend (scratchbuf
);
3338 OP_T (dummy
, sizeflag
)
3342 codep
++; /* skip mod/rm */
3343 sprintf (scratchbuf
, "%%tr%d", reg
);
3344 oappend (scratchbuf
);
3348 OP_rm (bytemode
, sizeflag
)
3355 oappend (names32
[rm
]);
3358 oappend (names16
[rm
]);
3364 OP_MMX (ignore
, sizeflag
)
3368 sprintf (scratchbuf
, "%%mm%d", reg
);
3369 oappend (scratchbuf
);
3373 OP_XMM (bytemode
, sizeflag
)
3377 sprintf (scratchbuf
, "%%xmm%d", reg
);
3378 oappend (scratchbuf
);
3382 OP_EM (bytemode
, sizeflag
)
3388 OP_E (bytemode
, sizeflag
);
3393 sprintf (scratchbuf
, "%%mm%d", rm
);
3394 oappend (scratchbuf
);
3398 OP_EX (bytemode
, sizeflag
)
3404 OP_E (bytemode
, sizeflag
);
3409 sprintf (scratchbuf
, "%%xmm%d", rm
);
3410 oappend (scratchbuf
);
3414 OP_MS (ignore
, sizeflag
)
3419 sprintf (scratchbuf
, "%%mm%d", rm
);
3420 oappend (scratchbuf
);
3423 static const char *Suffix3DNow
[] = {
3424 /* 00 */ NULL
, NULL
, NULL
, NULL
,
3425 /* 04 */ NULL
, NULL
, NULL
, NULL
,
3426 /* 08 */ NULL
, NULL
, NULL
, NULL
,
3427 /* 0C */ NULL
, "pi2fd", NULL
, NULL
,
3428 /* 10 */ NULL
, NULL
, NULL
, NULL
,
3429 /* 14 */ NULL
, NULL
, NULL
, NULL
,
3430 /* 18 */ NULL
, NULL
, NULL
, NULL
,
3431 /* 1C */ NULL
, "pf2id", NULL
, NULL
,
3432 /* 20 */ NULL
, NULL
, NULL
, NULL
,
3433 /* 24 */ NULL
, NULL
, NULL
, NULL
,
3434 /* 28 */ NULL
, NULL
, NULL
, NULL
,
3435 /* 2C */ NULL
, NULL
, NULL
, NULL
,
3436 /* 30 */ NULL
, NULL
, NULL
, NULL
,
3437 /* 34 */ NULL
, NULL
, NULL
, NULL
,
3438 /* 38 */ NULL
, NULL
, NULL
, NULL
,
3439 /* 3C */ NULL
, NULL
, NULL
, NULL
,
3440 /* 40 */ NULL
, NULL
, NULL
, NULL
,
3441 /* 44 */ NULL
, NULL
, NULL
, NULL
,
3442 /* 48 */ NULL
, NULL
, NULL
, NULL
,
3443 /* 4C */ NULL
, NULL
, NULL
, NULL
,
3444 /* 50 */ NULL
, NULL
, NULL
, NULL
,
3445 /* 54 */ NULL
, NULL
, NULL
, NULL
,
3446 /* 58 */ NULL
, NULL
, NULL
, NULL
,
3447 /* 5C */ NULL
, NULL
, NULL
, NULL
,
3448 /* 60 */ NULL
, NULL
, NULL
, NULL
,
3449 /* 64 */ NULL
, NULL
, NULL
, NULL
,
3450 /* 68 */ NULL
, NULL
, NULL
, NULL
,
3451 /* 6C */ NULL
, NULL
, NULL
, NULL
,
3452 /* 70 */ NULL
, NULL
, NULL
, NULL
,
3453 /* 74 */ NULL
, NULL
, NULL
, NULL
,
3454 /* 78 */ NULL
, NULL
, NULL
, NULL
,
3455 /* 7C */ NULL
, NULL
, NULL
, NULL
,
3456 /* 80 */ NULL
, NULL
, NULL
, NULL
,
3457 /* 84 */ NULL
, NULL
, NULL
, NULL
,
3458 /* 88 */ NULL
, NULL
, NULL
, NULL
,
3459 /* 8C */ NULL
, NULL
, NULL
, NULL
,
3460 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
3461 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
3462 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
3463 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
3464 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
3465 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
3466 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
3467 /* AC */ NULL
, NULL
, "pfacc", NULL
,
3468 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
3469 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
3470 /* B8 */ NULL
, NULL
, NULL
, NULL
,
3471 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
3472 /* C0 */ NULL
, NULL
, NULL
, NULL
,
3473 /* C4 */ NULL
, NULL
, NULL
, NULL
,
3474 /* C8 */ NULL
, NULL
, NULL
, NULL
,
3475 /* CC */ NULL
, NULL
, NULL
, NULL
,
3476 /* D0 */ NULL
, NULL
, NULL
, NULL
,
3477 /* D4 */ NULL
, NULL
, NULL
, NULL
,
3478 /* D8 */ NULL
, NULL
, NULL
, NULL
,
3479 /* DC */ NULL
, NULL
, NULL
, NULL
,
3480 /* E0 */ NULL
, NULL
, NULL
, NULL
,
3481 /* E4 */ NULL
, NULL
, NULL
, NULL
,
3482 /* E8 */ NULL
, NULL
, NULL
, NULL
,
3483 /* EC */ NULL
, NULL
, NULL
, NULL
,
3484 /* F0 */ NULL
, NULL
, NULL
, NULL
,
3485 /* F4 */ NULL
, NULL
, NULL
, NULL
,
3486 /* F8 */ NULL
, NULL
, NULL
, NULL
,
3487 /* FC */ NULL
, NULL
, NULL
, NULL
,
3491 OP_3DNowSuffix (bytemode
, sizeflag
)
3495 const char *mnemonic
;
3497 FETCH_DATA (the_info
, codep
+ 1);
3498 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3499 place where an 8-bit immediate would normally go. ie. the last
3500 byte of the instruction. */
3501 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
3503 strcat (obuf
, mnemonic
);
3506 /* Since a variable sized modrm/sib chunk is between the start
3507 of the opcode (0x0f0f) and the opcode suffix, we need to do
3508 all the modrm processing first, and don't know until now that
3509 we have a bad opcode. This necessitates some cleaning up. */
3512 codep
= insn_codep
+ 1;
3513 strcat (obuf
, "(bad)");
3518 static const char *simd_cmp_op
[] = {
3530 OP_SIMD_Suffix (bytemode
, sizeflag
)
3534 unsigned int cmp_type
;
3536 FETCH_DATA (the_info
, codep
+ 1);
3537 cmp_type
= *codep
++ & 0xff;
3540 sprintf (scratchbuf
, "cmp%s%cs",
3541 simd_cmp_op
[cmp_type
],
3542 prefixes
& PREFIX_REPZ
? 's' : 'p');
3543 strcat (obuf
, scratchbuf
);
3547 /* We have a bad extension byte. Clean up. */
3550 codep
= insn_codep
+ 1;
3551 strcat (obuf
, "(bad)");
3556 SIMD_Fixup (extrachar
, sizeflag
)
3560 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3561 forms of these instructions. */
3564 char *p
= obuf
+ strlen(obuf
);