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 Ed OP_E, d_mode
97 #define indirEv OP_indirE, v_mode
98 #define Ew OP_E, w_mode
99 #define Ma OP_E, v_mode
100 #define M OP_E, 0 /* lea */
101 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
102 #define Gv OP_G, v_mode
103 #define Gw OP_G, w_mode
104 #define Rd OP_Rd, 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
111 #define Cd OP_C, d_mode
112 #define Dd OP_D, d_mode
113 #define Td OP_T, d_mode
115 #define eAX OP_REG, eAX_reg
116 #define eBX OP_REG, eBX_reg
117 #define eCX OP_REG, eCX_reg
118 #define eDX OP_REG, eDX_reg
119 #define eSP OP_REG, eSP_reg
120 #define eBP OP_REG, eBP_reg
121 #define eSI OP_REG, eSI_reg
122 #define eDI OP_REG, eDI_reg
123 #define AL OP_REG, al_reg
124 #define CL OP_REG, cl_reg
125 #define DL OP_REG, dl_reg
126 #define BL OP_REG, bl_reg
127 #define AH OP_REG, ah_reg
128 #define CH OP_REG, ch_reg
129 #define DH OP_REG, dh_reg
130 #define BH OP_REG, bh_reg
131 #define AX OP_REG, ax_reg
132 #define DX OP_REG, dx_reg
133 #define indirDX OP_REG, indir_dx_reg
135 #define Sw OP_SEG, w_mode
137 #define Ob OP_OFF, b_mode
138 #define Ov OP_OFF, v_mode
139 #define Xb OP_DSreg, eSI_reg
140 #define Xv OP_DSreg, eSI_reg
141 #define Yb OP_ESreg, eDI_reg
142 #define Yv OP_ESreg, eDI_reg
143 #define DSBX OP_DSreg, eBX_reg
145 #define es OP_REG, es_reg
146 #define ss OP_REG, ss_reg
147 #define cs OP_REG, cs_reg
148 #define ds OP_REG, ds_reg
149 #define fs OP_REG, fs_reg
150 #define gs OP_REG, gs_reg
154 #define EM OP_EM, v_mode
155 #define EX OP_EX, v_mode
156 #define MS OP_MS, v_mode
158 #define OPSUF OP_3DNowSuffix, 0
159 #define OPSIMD OP_SIMD_Suffix, 0
161 /* bits in sizeflag */
162 #if 0 /* leave undefined until someone adds the extra flag to objdump */
163 #define SUFFIX_ALWAYS 4
168 typedef void (*op_rtn
) PARAMS ((int bytemode
, int sizeflag
));
170 static void OP_E
PARAMS ((int, int));
171 static void OP_G
PARAMS ((int, int));
172 static void OP_I
PARAMS ((int, int));
173 static void OP_indirE
PARAMS ((int, int));
174 static void OP_sI
PARAMS ((int, int));
175 static void OP_REG
PARAMS ((int, int));
176 static void OP_J
PARAMS ((int, int));
177 static void OP_DIR
PARAMS ((int, int));
178 static void OP_OFF
PARAMS ((int, int));
179 static void OP_ESreg
PARAMS ((int, int));
180 static void OP_DSreg
PARAMS ((int, int));
181 static void OP_SEG
PARAMS ((int, int));
182 static void OP_C
PARAMS ((int, int));
183 static void OP_D
PARAMS ((int, int));
184 static void OP_T
PARAMS ((int, int));
185 static void OP_Rd
PARAMS ((int, int));
186 static void OP_ST
PARAMS ((int, int));
187 static void OP_STi
PARAMS ((int, int));
188 static void OP_MMX
PARAMS ((int, int));
189 static void OP_XMM
PARAMS ((int, int));
190 static void OP_EM
PARAMS ((int, int));
191 static void OP_EX
PARAMS ((int, int));
192 static void OP_MS
PARAMS ((int, int));
193 static void OP_3DNowSuffix
PARAMS ((int, int));
194 static void OP_SIMD_Suffix
PARAMS ((int, int));
195 static void SIMD_Fixup
PARAMS ((int, int));
197 static void append_seg
PARAMS ((void));
198 static void set_op
PARAMS ((unsigned int op
));
199 static void putop
PARAMS ((const char *template, int sizeflag
));
200 static void dofloat
PARAMS ((int sizeflag
));
201 static int get16
PARAMS ((void));
202 static int get32
PARAMS ((void));
203 static void ckprefix
PARAMS ((void));
204 static void ptr_reg
PARAMS ((int, int));
205 static void BadOp
PARAMS ((void));
247 #define indir_dx_reg 150
250 #define USE_PREFIX_USER_TABLE 2
252 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
253 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
254 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
255 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
256 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
257 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
258 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
259 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
260 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
261 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
262 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
263 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
264 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
265 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
266 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
267 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
268 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
269 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
270 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
271 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
272 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
273 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
274 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
276 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
277 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
278 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
279 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
280 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
281 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
282 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
283 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
284 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
285 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
286 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
287 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
288 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
289 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
290 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
293 #define FLOAT NULL, NULL, FLOATCODE
305 /* Upper case letters in the instruction names here are macros.
306 'A' => print 'b' if no register operands or suffix_always is true
307 'B' => print 'b' if suffix_always is true
308 'E' => print 'e' if 32-bit form of jcxz
309 'L' => print 'l' if suffix_always is true
310 'N' => print 'n' if instruction has no wait "prefix"
311 'P' => print 'w' or 'l' if instruction has an operand size prefix,
312 or suffix_always is true
313 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
314 'R' => print 'w' or 'l'
315 'S' => print 'w' or 'l' if suffix_always is true
316 'W' => print 'b' or 'w'
319 static const struct dis386 dis386_att
[] = {
337 { "(bad)" }, /* 0x0f extended opcode escape */
363 { "(bad)" }, /* SEG ES prefix */
372 { "(bad)" }, /* SEG CS prefix */
381 { "(bad)" }, /* SEG SS prefix */
390 { "(bad)" }, /* SEG DS prefix */
431 { "boundS", Gv
, Ma
},
433 { "(bad)" }, /* seg fs */
434 { "(bad)" }, /* seg gs */
435 { "(bad)" }, /* op size prefix */
436 { "(bad)" }, /* adr size prefix */
438 { "pushP", Iv
}, /* 386 book wrong */
439 { "imulS", Gv
, Ev
, Iv
},
440 { "pushP", sIb
}, /* push of byte really pushes 2 or 4 bytes */
441 { "imulS", Gv
, Ev
, sIb
},
442 { "insb", Yb
, indirDX
},
443 { "insR", Yv
, indirDX
},
444 { "outsb", indirDX
, Xb
},
445 { "outsR", indirDX
, Xv
},
484 { "xchgS", eCX
, eAX
},
485 { "xchgS", eDX
, eAX
},
486 { "xchgS", eBX
, eAX
},
487 { "xchgS", eSP
, eAX
},
488 { "xchgS", eBP
, eAX
},
489 { "xchgS", eSI
, eAX
},
490 { "xchgS", eDI
, eAX
},
495 { "(bad)" }, /* fwait */
511 { "testS", eAX
, Iv
},
513 { "stosS", Yv
, eAX
},
515 { "lodsS", eAX
, Xv
},
517 { "scasS", eAX
, Yv
},
546 { "enterP", Iw
, Ib
},
586 { "inB", AL
, indirDX
},
587 { "inS", eAX
, indirDX
},
588 { "outB", indirDX
, AL
},
589 { "outS", indirDX
, eAX
},
591 { "(bad)" }, /* lock prefix */
593 { "(bad)" }, /* repne */
594 { "(bad)" }, /* repz */
610 static const struct dis386 dis386_intel
[] = {
628 { "(bad)" }, /* 0x0f extended opcode escape */
654 { "(bad)" }, /* SEG ES prefix */
663 { "(bad)" }, /* SEG CS prefix */
672 { "(bad)" }, /* SEG SS prefix */
681 { "(bad)" }, /* SEG DS prefix */
724 { "(bad)" }, /* seg fs */
725 { "(bad)" }, /* seg gs */
726 { "(bad)" }, /* op size prefix */
727 { "(bad)" }, /* adr size prefix */
729 { "push", Iv
}, /* 386 book wrong */
730 { "imul", Gv
, Ev
, Iv
},
731 { "push", sIb
}, /* push of byte really pushes 2 or 4 bytes */
732 { "imul", Gv
, Ev
, sIb
},
733 { "ins", Yb
, indirDX
},
734 { "ins", Yv
, indirDX
},
735 { "outs", indirDX
, Xb
},
736 { "outs", indirDX
, Xv
},
775 { "xchg", eCX
, eAX
},
776 { "xchg", eDX
, eAX
},
777 { "xchg", eBX
, eAX
},
778 { "xchg", eSP
, eAX
},
779 { "xchg", eBP
, eAX
},
780 { "xchg", eSI
, eAX
},
781 { "xchg", eDI
, eAX
},
783 { "cW" }, /* cwde and cbw */
784 { "cR" }, /* cdq and cwd */
786 { "(bad)" }, /* fwait */
877 { "in", AL
, indirDX
},
878 { "in", eAX
, indirDX
},
879 { "out", indirDX
, AL
},
880 { "out", indirDX
, eAX
},
882 { "(bad)" }, /* lock prefix */
884 { "(bad)" }, /* repne */
885 { "(bad)" }, /* repz */
901 static const struct dis386 dis386_twobyte_att
[] = {
919 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
923 { "movlps", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
924 { "movlps", EX
, XM
, SIMD_Fixup
, 'h' },
925 { "unpcklps", XM
, EX
},
926 { "unpckhps", XM
, EX
},
927 { "movhps", XM
, EX
, SIMD_Fixup
, 'l' },
928 { "movhps", EX
, XM
, SIMD_Fixup
, 'l' },
931 { "(bad)" }, { "(bad)" }, { "(bad)" },
932 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
934 /* these are all backward in appendix A of the intel book */
944 { "movaps", XM
, EX
},
945 { "movaps", EX
, XM
},
947 { "movntps", Ev
, XM
},
950 { "ucomiss", XM
, EX
},
951 { "comiss", XM
, EX
},
953 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
954 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
956 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
957 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
959 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
960 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
962 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
963 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
965 { "movmskps", Gv
, EX
},
970 { "andnps", XM
, EX
},
983 { "punpcklbw", MX
, EM
},
984 { "punpcklwd", MX
, EM
},
985 { "punpckldq", MX
, EM
},
986 { "packsswb", MX
, EM
},
987 { "pcmpgtb", MX
, EM
},
988 { "pcmpgtw", MX
, EM
},
989 { "pcmpgtd", MX
, EM
},
990 { "packuswb", MX
, EM
},
992 { "punpckhbw", MX
, EM
},
993 { "punpckhwd", MX
, EM
},
994 { "punpckhdq", MX
, EM
},
995 { "packssdw", MX
, EM
},
996 { "(bad)" }, { "(bad)" },
1000 { "pshufw", MX
, EM
, Ib
},
1004 { "pcmpeqb", MX
, EM
},
1005 { "pcmpeqw", MX
, EM
},
1006 { "pcmpeqd", MX
, EM
},
1009 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1010 { "(bad)" }, { "(bad)" },
1054 { "shldS", Ev
, Gv
, Ib
},
1055 { "shldS", Ev
, Gv
, CL
},
1063 { "shrdS", Ev
, Gv
, Ib
},
1064 { "shrdS", Ev
, Gv
, CL
},
1066 { "imulS", Gv
, Ev
},
1068 { "cmpxchgB", Eb
, Gb
},
1069 { "cmpxchgS", Ev
, Gv
},
1074 { "movzbR", Gv
, Eb
},
1075 { "movzwR", Gv
, Ew
}, /* yes, there really is movzww ! */
1083 { "movsbR", Gv
, Eb
},
1084 { "movswR", Gv
, Ew
}, /* yes, there really is movsww ! */
1086 { "xaddB", Eb
, Gb
},
1087 { "xaddS", Ev
, Gv
},
1090 { "pinsrw", MX
, Ev
, Ib
},
1091 { "pextrw", Ev
, MX
, Ib
},
1092 { "shufps", XM
, EX
, Ib
},
1095 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1105 { "psrlw", MX
, EM
},
1106 { "psrld", MX
, EM
},
1107 { "psrlq", MX
, EM
},
1109 { "pmullw", MX
, EM
},
1111 { "pmovmskb", Ev
, MX
},
1113 { "psubusb", MX
, EM
},
1114 { "psubusw", MX
, EM
},
1115 { "pminub", MX
, EM
},
1117 { "paddusb", MX
, EM
},
1118 { "paddusw", MX
, EM
},
1119 { "pmaxub", MX
, EM
},
1120 { "pandn", MX
, EM
},
1122 { "pavgb", MX
, EM
},
1123 { "psraw", MX
, EM
},
1124 { "psrad", MX
, EM
},
1125 { "pavgw", MX
, EM
},
1126 { "pmulhuw", MX
, EM
},
1127 { "pmulhw", MX
, EM
},
1129 { "movntq", Ev
, MX
},
1131 { "psubsb", MX
, EM
},
1132 { "psubsw", MX
, EM
},
1133 { "pminsw", MX
, EM
},
1135 { "paddsb", MX
, EM
},
1136 { "paddsw", MX
, EM
},
1137 { "pmaxsw", MX
, EM
},
1141 { "psllw", MX
, EM
},
1142 { "pslld", MX
, EM
},
1143 { "psllq", MX
, EM
},
1145 { "pmaddwd", MX
, EM
},
1146 { "psadbw", MX
, EM
},
1147 { "maskmovq", MX
, EM
},
1149 { "psubb", MX
, EM
},
1150 { "psubw", MX
, EM
},
1151 { "psubd", MX
, EM
},
1153 { "paddb", MX
, EM
},
1154 { "paddw", MX
, EM
},
1155 { "paddd", MX
, EM
},
1159 static const struct dis386 dis386_twobyte_intel
[] = {
1177 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1181 { "movlps", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1182 { "movlps", EX
, XM
, SIMD_Fixup
, 'h' },
1183 { "unpcklps", XM
, EX
},
1184 { "unpckhps", XM
, EX
},
1185 { "movhps", XM
, EX
, SIMD_Fixup
, 'l' },
1186 { "movhps", EX
, XM
, SIMD_Fixup
, 'l' },
1189 { "(bad)" }, { "(bad)" }, { "(bad)" },
1190 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1192 /* these are all backward in appendix A of the intel book */
1202 { "movaps", XM
, EX
},
1203 { "movaps", EX
, XM
},
1205 { "movntps", Ev
, XM
},
1208 { "ucomiss", XM
, EX
},
1209 { "comiss", XM
, EX
},
1211 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1212 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1214 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1215 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1217 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
1218 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
1220 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
1221 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
1223 { "movmskps", Gv
, EX
},
1227 { "andps", XM
, EX
},
1228 { "andnps", XM
, EX
},
1230 { "xorps", XM
, EX
},
1241 { "punpcklbw", MX
, EM
},
1242 { "punpcklwd", MX
, EM
},
1243 { "punpckldq", MX
, EM
},
1244 { "packsswb", MX
, EM
},
1245 { "pcmpgtb", MX
, EM
},
1246 { "pcmpgtw", MX
, EM
},
1247 { "pcmpgtd", MX
, EM
},
1248 { "packuswb", MX
, EM
},
1250 { "punpckhbw", MX
, EM
},
1251 { "punpckhwd", MX
, EM
},
1252 { "punpckhdq", MX
, EM
},
1253 { "packssdw", MX
, EM
},
1254 { "(bad)" }, { "(bad)" },
1258 { "pshufw", MX
, EM
, Ib
},
1262 { "pcmpeqb", MX
, EM
},
1263 { "pcmpeqw", MX
, EM
},
1264 { "pcmpeqd", MX
, EM
},
1267 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1268 { "(bad)" }, { "(bad)" },
1312 { "shld", Ev
, Gv
, Ib
},
1313 { "shld", Ev
, Gv
, CL
},
1321 { "shrd", Ev
, Gv
, Ib
},
1322 { "shrd", Ev
, Gv
, CL
},
1326 { "cmpxchg", Eb
, Gb
},
1327 { "cmpxchg", Ev
, Gv
},
1332 { "movzx", Gv
, Eb
},
1333 { "movzx", Gv
, Ew
},
1341 { "movsx", Gv
, Eb
},
1342 { "movsx", Gv
, Ew
},
1348 { "pinsrw", MX
, Ev
, Ib
},
1349 { "pextrw", Ev
, MX
, Ib
},
1350 { "shufps", XM
, EX
, Ib
},
1353 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1363 { "psrlw", MX
, EM
},
1364 { "psrld", MX
, EM
},
1365 { "psrlq", MX
, EM
},
1367 { "pmullw", MX
, EM
},
1369 { "pmovmskb", Ev
, MX
},
1371 { "psubusb", MX
, EM
},
1372 { "psubusw", MX
, EM
},
1373 { "pminub", MX
, EM
},
1375 { "paddusb", MX
, EM
},
1376 { "paddusw", MX
, EM
},
1377 { "pmaxub", MX
, EM
},
1378 { "pandn", MX
, EM
},
1380 { "pavgb", MX
, EM
},
1381 { "psraw", MX
, EM
},
1382 { "psrad", MX
, EM
},
1383 { "pavgw", MX
, EM
},
1384 { "pmulhuw", MX
, EM
},
1385 { "pmulhw", MX
, EM
},
1387 { "movntq", Ev
, MX
},
1389 { "psubsb", MX
, EM
},
1390 { "psubsw", MX
, EM
},
1391 { "pminsw", MX
, EM
},
1393 { "paddsb", MX
, EM
},
1394 { "paddsw", MX
, EM
},
1395 { "pmaxsw", MX
, EM
},
1399 { "psllw", MX
, EM
},
1400 { "pslld", MX
, EM
},
1401 { "psllq", MX
, EM
},
1403 { "pmaddwd", MX
, EM
},
1404 { "psadbw", MX
, EM
},
1405 { "maskmovq", MX
, EM
},
1407 { "psubb", MX
, EM
},
1408 { "psubw", MX
, EM
},
1409 { "psubd", MX
, EM
},
1411 { "paddb", MX
, EM
},
1412 { "paddw", MX
, EM
},
1413 { "paddd", MX
, EM
},
1417 static const unsigned char onebyte_has_modrm
[256] = {
1418 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1419 /* ------------------------------- */
1420 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1421 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1422 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1423 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1424 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1425 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1426 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1427 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1428 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1429 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1430 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1431 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1432 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1433 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1434 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1435 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1436 /* ------------------------------- */
1437 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1440 static const unsigned char twobyte_has_modrm
[256] = {
1441 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1442 /* ------------------------------- */
1443 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1444 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1445 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1446 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1447 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1448 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1449 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1450 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1451 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1452 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1453 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1454 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1455 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1456 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1457 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1458 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1459 /* ------------------------------- */
1460 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1463 static const unsigned char twobyte_uses_f3_prefix
[256] = {
1464 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1465 /* ------------------------------- */
1466 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1467 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1468 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1469 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1470 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1471 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1472 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1473 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1474 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1475 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1476 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1477 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1478 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1479 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1480 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1481 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1482 /* ------------------------------- */
1483 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1486 static char obuf
[100];
1488 static char scratchbuf
[100];
1489 static unsigned char *start_codep
;
1490 static unsigned char *insn_codep
;
1491 static unsigned char *codep
;
1492 static disassemble_info
*the_info
;
1496 static void oappend
PARAMS ((const char *s
));
1498 static const char *names32
[]={
1499 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1501 static const char *names16
[] = {
1502 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1504 static const char *names8
[] = {
1505 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1507 static const char *names_seg
[] = {
1508 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1510 static const char *index16
[] = {
1511 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1514 static const struct dis386 grps
[][8] = {
1539 { "addQ", Ev
, sIb
},
1541 { "adcQ", Ev
, sIb
},
1542 { "sbbQ", Ev
, sIb
},
1543 { "andQ", Ev
, sIb
},
1544 { "subQ", Ev
, sIb
},
1545 { "xorQ", Ev
, sIb
},
1616 { "testA", Eb
, Ib
},
1621 { "imulB", AL
, Eb
},
1627 { "testQ", Ev
, Iv
},
1631 { "mulS", eAX
, Ev
},
1632 { "imulS", eAX
, Ev
},
1633 { "divS", eAX
, Ev
},
1634 { "idivS", eAX
, Ev
},
1651 { "callP", indirEv
},
1652 { "callP", indirEv
},
1653 { "jmpP", indirEv
},
1654 { "ljmpP", indirEv
},
1694 { "cmpxchg8b", Ev
},
1706 { "psrlw", MS
, Ib
},
1708 { "psraw", MS
, Ib
},
1710 { "psllw", MS
, Ib
},
1717 { "psrld", MS
, Ib
},
1719 { "psrad", MS
, Ib
},
1721 { "pslld", MS
, Ib
},
1728 { "psrlq", MS
, Ib
},
1732 { "psllq", MS
, Ib
},
1748 { "prefetchnta", Ev
},
1749 { "prefetcht0", Ev
},
1750 { "prefetcht1", Ev
},
1751 { "prefetcht2", Ev
},
1760 { "prefetchw", Eb
},
1771 static const struct dis386 prefix_user_table
[][2] = {
1774 { "addps", XM
, EX
},
1775 { "addss", XM
, EX
},
1779 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX */
1780 { "", XM
, EX
, OPSIMD
},
1784 { "cvtpi2ps", XM
, EM
},
1785 { "cvtsi2ss", XM
, Ev
},
1789 { "cvtps2pi", MX
, EX
},
1790 { "cvtss2si", Gv
, EX
},
1794 { "cvttps2pi", MX
, EX
},
1795 { "cvttss2si", Gv
, EX
},
1799 { "divps", XM
, EX
},
1800 { "divss", XM
, EX
},
1804 { "maxps", XM
, EX
},
1805 { "maxss", XM
, EX
},
1809 { "minps", XM
, EX
},
1810 { "minss", XM
, EX
},
1814 { "movups", XM
, EX
},
1815 { "movss", XM
, EX
},
1819 { "movups", EX
, XM
},
1820 { "movss", EX
, XM
},
1824 { "mulps", XM
, EX
},
1825 { "mulss", XM
, EX
},
1829 { "rcpps", XM
, EX
},
1830 { "rcpss", XM
, EX
},
1834 { "rsqrtps", XM
, EX
},
1835 { "rsqrtss", XM
, EX
},
1839 { "sqrtps", XM
, EX
},
1840 { "sqrtss", XM
, EX
},
1844 { "subps", XM
, EX
},
1845 { "subss", XM
, EX
},
1849 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1851 #define PREFIX_REPZ 1
1852 #define PREFIX_REPNZ 2
1853 #define PREFIX_LOCK 4
1855 #define PREFIX_SS 0x10
1856 #define PREFIX_DS 0x20
1857 #define PREFIX_ES 0x40
1858 #define PREFIX_FS 0x80
1859 #define PREFIX_GS 0x100
1860 #define PREFIX_DATA 0x200
1861 #define PREFIX_ADDR 0x400
1862 #define PREFIX_FWAIT 0x800
1864 static int prefixes
;
1872 FETCH_DATA (the_info
, codep
+ 1);
1876 prefixes
|= PREFIX_REPZ
;
1879 prefixes
|= PREFIX_REPNZ
;
1882 prefixes
|= PREFIX_LOCK
;
1885 prefixes
|= PREFIX_CS
;
1888 prefixes
|= PREFIX_SS
;
1891 prefixes
|= PREFIX_DS
;
1894 prefixes
|= PREFIX_ES
;
1897 prefixes
|= PREFIX_FS
;
1900 prefixes
|= PREFIX_GS
;
1903 prefixes
|= PREFIX_DATA
;
1906 prefixes
|= PREFIX_ADDR
;
1909 /* fwait is really an instruction. If there are prefixes
1910 before the fwait, they belong to the fwait, *not* to the
1911 following instruction. */
1914 prefixes
|= PREFIX_FWAIT
;
1918 prefixes
= PREFIX_FWAIT
;
1927 static char op1out
[100], op2out
[100], op3out
[100];
1928 static int op_ad
, op_index
[3];
1929 static unsigned int op_address
[3];
1930 static unsigned int start_pc
;
1934 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1935 * (see topic "Redundant prefixes" in the "Differences from 8086"
1936 * section of the "Virtual 8086 Mode" chapter.)
1937 * 'pc' should be the address of this instruction, it will
1938 * be used to print the target address if this is a relative jump or call
1939 * The function returns the length of this instruction in bytes.
1942 static int print_insn_i386
1943 PARAMS ((bfd_vma pc
, disassemble_info
*info
));
1945 static char intel_syntax
;
1946 static char open_char
;
1947 static char close_char
;
1948 static char separator_char
;
1949 static char scale_char
;
1952 print_insn_i386_att (pc
, info
)
1954 disassemble_info
*info
;
1959 separator_char
= ',';
1962 return print_insn_i386 (pc
, info
);
1966 print_insn_i386_intel (pc
, info
)
1968 disassemble_info
*info
;
1973 separator_char
= '+';
1976 return print_insn_i386 (pc
, info
);
1980 print_insn_i386 (pc
, info
)
1982 disassemble_info
*info
;
1984 const struct dis386
*dp
;
1987 char *first
, *second
, *third
;
1989 unsigned char need_modrm
;
1990 unsigned char uses_f3_prefix
;
1993 struct dis_private priv
;
1994 bfd_byte
*inbuf
= priv
.the_buffer
;
1996 if (info
->mach
== bfd_mach_i386_i386
1997 || info
->mach
== bfd_mach_i386_i386_intel_syntax
)
1998 sizeflag
= AFLAG
|DFLAG
;
1999 else if (info
->mach
== bfd_mach_i386_i8086
)
2004 /* The output looks better if we put 6 bytes on a line, since that
2005 puts most long word instructions on a single line. */
2006 info
->bytes_per_line
= 6;
2008 info
->private_data
= (PTR
) &priv
;
2009 priv
.max_fetched
= priv
.the_buffer
;
2010 priv
.insn_start
= pc
;
2011 if (setjmp (priv
.bailout
) != 0)
2020 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2024 start_codep
= inbuf
;
2031 FETCH_DATA (info
, codep
+ 1);
2032 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2036 if ((prefixes
& PREFIX_FWAIT
)
2037 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2039 /* fwait not followed by floating point instruction. */
2040 (*info
->fprintf_func
) (info
->stream
, "fwait");
2041 /* There may be other prefixes. Skip any before the fwait. */
2042 return codep
- inbuf
;
2047 FETCH_DATA (info
, codep
+ 2);
2049 dp
= &dis386_twobyte_intel
[*++codep
];
2051 dp
= &dis386_twobyte_att
[*++codep
];
2052 need_modrm
= twobyte_has_modrm
[*codep
];
2053 uses_f3_prefix
= twobyte_uses_f3_prefix
[*codep
];
2058 dp
= &dis386_intel
[*codep
];
2060 dp
= &dis386_att
[*codep
];
2061 need_modrm
= onebyte_has_modrm
[*codep
];
2066 if (!uses_f3_prefix
&& (prefixes
& PREFIX_REPZ
))
2068 if (prefixes
& PREFIX_REPNZ
)
2070 if (prefixes
& PREFIX_LOCK
)
2073 if (prefixes
& PREFIX_DATA
)
2076 if (prefixes
& PREFIX_ADDR
)
2079 if (sizeflag
& AFLAG
)
2080 oappend ("addr32 ");
2082 oappend ("addr16 ");
2087 FETCH_DATA (info
, codep
+ 1);
2088 mod
= (*codep
>> 6) & 3;
2089 reg
= (*codep
>> 3) & 7;
2093 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2099 if (dp
->name
== NULL
)
2101 switch(dp
->bytemode2
)
2104 dp
= &grps
[dp
->bytemode1
][reg
];
2106 case USE_PREFIX_USER_TABLE
:
2107 dp
= &prefix_user_table
[dp
->bytemode1
][prefixes
& PREFIX_REPZ
? 1 : 0];
2110 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2115 putop (dp
->name
, sizeflag
);
2120 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
2125 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
2130 (*dp
->op3
)(dp
->bytemode3
, sizeflag
);
2133 obufp
= obuf
+ strlen (obuf
);
2134 for (i
= strlen (obuf
); i
< 6; i
++)
2137 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2139 /* The enter and bound instructions are printed with operands in the same
2140 order as the intel book; everything else is printed in reverse order. */
2141 if (intel_syntax
|| two_source_ops
)
2146 op_ad
= op_index
[0];
2147 op_index
[0] = op_index
[2];
2148 op_index
[2] = op_ad
;
2159 if (op_index
[0] != -1)
2160 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2162 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2168 (*info
->fprintf_func
) (info
->stream
, ",");
2169 if (op_index
[1] != -1)
2170 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2172 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2178 (*info
->fprintf_func
) (info
->stream
, ",");
2179 if (op_index
[2] != -1)
2180 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2182 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2184 return codep
- inbuf
;
2187 static const char *float_mem_att
[] = {
2262 static const char *float_mem_intel
[] = {
2338 #define STi OP_STi, 0
2340 #define FGRPd9_2 NULL, NULL, 0
2341 #define FGRPd9_4 NULL, NULL, 1
2342 #define FGRPd9_5 NULL, NULL, 2
2343 #define FGRPd9_6 NULL, NULL, 3
2344 #define FGRPd9_7 NULL, NULL, 4
2345 #define FGRPda_5 NULL, NULL, 5
2346 #define FGRPdb_4 NULL, NULL, 6
2347 #define FGRPde_3 NULL, NULL, 7
2348 #define FGRPdf_4 NULL, NULL, 8
2350 static const struct dis386 float_reg
[][8] = {
2353 { "fadd", ST
, STi
},
2354 { "fmul", ST
, STi
},
2357 { "fsub", ST
, STi
},
2358 { "fsubr", ST
, STi
},
2359 { "fdiv", ST
, STi
},
2360 { "fdivr", ST
, STi
},
2375 { "fcmovb", ST
, STi
},
2376 { "fcmove", ST
, STi
},
2377 { "fcmovbe",ST
, STi
},
2378 { "fcmovu", ST
, STi
},
2386 { "fcmovnb",ST
, STi
},
2387 { "fcmovne",ST
, STi
},
2388 { "fcmovnbe",ST
, STi
},
2389 { "fcmovnu",ST
, STi
},
2391 { "fucomi", ST
, STi
},
2392 { "fcomi", ST
, STi
},
2397 { "fadd", STi
, ST
},
2398 { "fmul", STi
, ST
},
2402 { "fsub", STi
, ST
},
2403 { "fsubr", STi
, ST
},
2404 { "fdiv", STi
, ST
},
2405 { "fdivr", STi
, ST
},
2407 { "fsubr", STi
, ST
},
2408 { "fsub", STi
, ST
},
2409 { "fdivr", STi
, ST
},
2410 { "fdiv", STi
, ST
},
2426 { "faddp", STi
, ST
},
2427 { "fmulp", STi
, ST
},
2431 { "fsubp", STi
, ST
},
2432 { "fsubrp", STi
, ST
},
2433 { "fdivp", STi
, ST
},
2434 { "fdivrp", STi
, ST
},
2436 { "fsubrp", STi
, ST
},
2437 { "fsubp", STi
, ST
},
2438 { "fdivrp", STi
, ST
},
2439 { "fdivp", STi
, ST
},
2449 { "fucomip",ST
, STi
},
2450 { "fcomip", ST
, STi
},
2456 static char *fgrps
[][8] = {
2459 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2464 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2469 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2474 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2479 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2484 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2489 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2490 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2495 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2500 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2508 const struct dis386
*dp
;
2509 unsigned char floatop
;
2511 floatop
= codep
[-1];
2516 putop (float_mem_intel
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2518 putop (float_mem_att
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2520 if (floatop
== 0xdb)
2521 OP_E (x_mode
, sizeflag
);
2522 else if (floatop
== 0xdd)
2523 OP_E (d_mode
, sizeflag
);
2525 OP_E (v_mode
, sizeflag
);
2530 dp
= &float_reg
[floatop
- 0xd8][reg
];
2531 if (dp
->name
== NULL
)
2533 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2535 /* instruction fnstsw is only one with strange arg */
2536 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2537 strcpy (op1out
, names16
[0]);
2541 putop (dp
->name
, sizeflag
);
2545 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
2548 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
2554 OP_ST (ignore
, sizeflag
)
2563 OP_STi (ignore
, sizeflag
)
2567 sprintf (scratchbuf
, "%%st(%d)", rm
);
2568 oappend (scratchbuf
);
2572 /* capital letters in template are macros */
2574 putop (template, sizeflag
)
2575 const char *template;
2580 for (p
= template; *p
; p
++)
2591 #ifdef SUFFIX_ALWAYS
2592 || (sizeflag
& SUFFIX_ALWAYS
)
2600 #ifdef SUFFIX_ALWAYS
2601 if (sizeflag
& SUFFIX_ALWAYS
)
2605 case 'E': /* For jcxz/jecxz */
2606 if (sizeflag
& AFLAG
)
2612 #ifdef SUFFIX_ALWAYS
2613 if (sizeflag
& SUFFIX_ALWAYS
)
2618 if ((prefixes
& PREFIX_FWAIT
) == 0)
2624 if ((prefixes
& PREFIX_DATA
)
2625 #ifdef SUFFIX_ALWAYS
2626 || (sizeflag
& SUFFIX_ALWAYS
)
2630 if (sizeflag
& DFLAG
)
2640 #ifdef SUFFIX_ALWAYS
2641 || (sizeflag
& SUFFIX_ALWAYS
)
2645 if (sizeflag
& DFLAG
)
2654 if (sizeflag
& DFLAG
)
2667 if (sizeflag
& DFLAG
)
2676 #ifdef SUFFIX_ALWAYS
2677 if (sizeflag
& SUFFIX_ALWAYS
)
2679 if (sizeflag
& DFLAG
)
2687 /* operand size flag for cwtl, cbtw */
2688 if (sizeflag
& DFLAG
)
2694 if (sizeflag
& DFLAG
)
2715 obufp
+= strlen (s
);
2721 if (prefixes
& PREFIX_CS
)
2723 if (prefixes
& PREFIX_DS
)
2725 if (prefixes
& PREFIX_SS
)
2727 if (prefixes
& PREFIX_ES
)
2729 if (prefixes
& PREFIX_FS
)
2731 if (prefixes
& PREFIX_GS
)
2736 OP_indirE (bytemode
, sizeflag
)
2742 OP_E (bytemode
, sizeflag
);
2746 OP_E (bytemode
, sizeflag
)
2752 /* skip mod/rm byte */
2760 oappend (names8
[rm
]);
2763 oappend (names16
[rm
]);
2766 oappend (names32
[rm
]);
2769 if (sizeflag
& DFLAG
)
2770 oappend (names32
[rm
]);
2772 oappend (names16
[rm
]);
2775 if ( !(codep
[-2] == 0xAE && codep
[-1] == 0xF8 /* sfence */))
2776 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
2779 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2788 if (sizeflag
& AFLAG
) /* 32 bit address mode */
2803 FETCH_DATA (the_info
, codep
+ 1);
2804 scale
= (*codep
>> 6) & 3;
2805 index
= (*codep
>> 3) & 7;
2820 FETCH_DATA (the_info
, codep
+ 1);
2822 if ((disp
& 0x80) != 0)
2831 if (mod
!= 0 || base
== 5)
2833 sprintf (scratchbuf
, "0x%x", disp
);
2834 oappend (scratchbuf
);
2837 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
2844 oappend("BYTE PTR ");
2847 oappend("WORD PTR ");
2850 oappend("DWORD PTR ");
2853 oappend("QWORD PTR ");
2856 oappend("XWORD PTR ");
2862 *obufp
++ = open_char
;
2865 oappend (names32
[base
]);
2874 *obufp
++ = separator_char
;
2877 sprintf (scratchbuf
, "%s", names32
[index
]);
2880 sprintf (scratchbuf
, ",%s", names32
[index
]);
2881 oappend (scratchbuf
);
2885 && bytemode
!= b_mode
2886 && bytemode
!= w_mode
2887 && bytemode
!= v_mode
))
2889 *obufp
++ = scale_char
;
2891 sprintf (scratchbuf
, "%d", 1 << scale
);
2892 oappend (scratchbuf
);
2896 if (mod
!= 0 || base
== 5)
2898 /* Don't print zero displacements */
2901 sprintf (scratchbuf
, "+%d", disp
);
2902 oappend (scratchbuf
);
2906 sprintf (scratchbuf
, "%d", disp
);
2907 oappend (scratchbuf
);
2911 *obufp
++ = close_char
;
2914 else if (intel_syntax
)
2916 if (mod
!= 0 || base
== 5)
2918 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
2919 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
2923 oappend (names_seg
[3]);
2926 sprintf (scratchbuf
, "0x%x", disp
);
2927 oappend (scratchbuf
);
2932 { /* 16 bit address mode */
2939 if ((disp
& 0x8000) != 0)
2944 FETCH_DATA (the_info
, codep
+ 1);
2946 if ((disp
& 0x80) != 0)
2951 if ((disp
& 0x8000) != 0)
2957 if (mod
!= 0 || rm
== 6)
2959 sprintf (scratchbuf
, "%d", disp
);
2960 oappend (scratchbuf
);
2963 if (mod
!= 0 || rm
!= 6)
2965 *obufp
++ = open_char
;
2967 oappend (index16
[rm
]);
2968 *obufp
++ = close_char
;
2975 OP_G (bytemode
, sizeflag
)
2982 oappend (names8
[reg
]);
2985 oappend (names16
[reg
]);
2988 oappend (names32
[reg
]);
2991 if (sizeflag
& DFLAG
)
2992 oappend (names32
[reg
]);
2994 oappend (names16
[reg
]);
2997 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3007 FETCH_DATA (the_info
, codep
+ 4);
3008 x
= *codep
++ & 0xff;
3009 x
|= (*codep
++ & 0xff) << 8;
3010 x
|= (*codep
++ & 0xff) << 16;
3011 x
|= (*codep
++ & 0xff) << 24;
3020 FETCH_DATA (the_info
, codep
+ 2);
3021 x
= *codep
++ & 0xff;
3022 x
|= (*codep
++ & 0xff) << 8;
3030 op_index
[op_ad
] = op_ad
;
3031 op_address
[op_ad
] = op
;
3035 OP_REG (code
, sizeflag
)
3046 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3047 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3048 s
= names16
[code
- ax_reg
];
3050 case es_reg
: case ss_reg
: case cs_reg
:
3051 case ds_reg
: case fs_reg
: case gs_reg
:
3052 s
= names_seg
[code
- es_reg
];
3054 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3055 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3056 s
= names8
[code
- al_reg
];
3058 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3059 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3060 if (sizeflag
& DFLAG
)
3061 s
= names32
[code
- eAX_reg
];
3063 s
= names16
[code
- eAX_reg
];
3066 s
= INTERNAL_DISASSEMBLER_ERROR
;
3073 OP_I (bytemode
, sizeflag
)
3082 FETCH_DATA (the_info
, codep
+ 1);
3083 op
= *codep
++ & 0xff;
3086 if (sizeflag
& DFLAG
)
3095 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3100 sprintf (scratchbuf
, "0x%x", op
);
3102 sprintf (scratchbuf
, "$0x%x", op
);
3103 oappend (scratchbuf
);
3104 scratchbuf
[0] = '\0';
3108 OP_sI (bytemode
, sizeflag
)
3117 FETCH_DATA (the_info
, codep
+ 1);
3119 if ((op
& 0x80) != 0)
3123 if (sizeflag
& DFLAG
)
3128 if ((op
& 0x8000) != 0)
3134 if ((op
& 0x8000) != 0)
3138 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3142 sprintf (scratchbuf
, "%d", op
);
3144 sprintf (scratchbuf
, "$0x%x", op
);
3145 oappend (scratchbuf
);
3149 OP_J (bytemode
, sizeflag
)
3159 FETCH_DATA (the_info
, codep
+ 1);
3161 if ((disp
& 0x80) != 0)
3165 if (sizeflag
& DFLAG
)
3170 /* for some reason, a data16 prefix on a jump instruction
3171 means that the pc is masked to 16 bits after the
3172 displacement is added! */
3177 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3180 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
3182 sprintf (scratchbuf
, "0x%x", disp
);
3183 oappend (scratchbuf
);
3188 OP_SEG (dummy
, sizeflag
)
3192 static char *sreg
[] = {
3193 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3196 oappend (sreg
[reg
]);
3201 OP_DIR (dummy
, sizeflag
)
3207 if (sizeflag
& DFLAG
)
3217 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
3218 oappend (scratchbuf
);
3223 OP_OFF (ignore
, sizeflag
)
3231 if (sizeflag
& AFLAG
)
3238 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3239 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3241 oappend (names_seg
[3]);
3245 sprintf (scratchbuf
, "0x%x", off
);
3246 oappend (scratchbuf
);
3250 ptr_reg (code
, sizeflag
)
3256 if (sizeflag
& AFLAG
)
3257 s
= names32
[code
- eAX_reg
];
3259 s
= names16
[code
- eAX_reg
];
3265 OP_ESreg (code
, sizeflag
)
3270 ptr_reg (code
, sizeflag
);
3274 OP_DSreg (code
, sizeflag
)
3285 prefixes
|= PREFIX_DS
;
3287 ptr_reg (code
, sizeflag
);
3292 OP_C (dummy
, sizeflag
)
3296 sprintf (scratchbuf
, "%%cr%d", reg
);
3297 oappend (scratchbuf
);
3302 OP_D (dummy
, sizeflag
)
3306 sprintf (scratchbuf
, "%%db%d", reg
);
3307 oappend (scratchbuf
);
3312 OP_T (dummy
, sizeflag
)
3316 sprintf (scratchbuf
, "%%tr%d", reg
);
3317 oappend (scratchbuf
);
3321 OP_Rd (bytemode
, sizeflag
)
3326 OP_E (bytemode
, sizeflag
);
3332 OP_MMX (ignore
, sizeflag
)
3336 sprintf (scratchbuf
, "%%mm%d", reg
);
3337 oappend (scratchbuf
);
3341 OP_XMM (bytemode
, sizeflag
)
3345 sprintf (scratchbuf
, "%%xmm%d", reg
);
3346 oappend (scratchbuf
);
3350 OP_EM (bytemode
, sizeflag
)
3356 OP_E (bytemode
, sizeflag
);
3361 sprintf (scratchbuf
, "%%mm%d", rm
);
3362 oappend (scratchbuf
);
3366 OP_EX (bytemode
, sizeflag
)
3372 OP_E (bytemode
, sizeflag
);
3377 sprintf (scratchbuf
, "%%xmm%d", rm
);
3378 oappend (scratchbuf
);
3382 OP_MS (bytemode
, sizeflag
)
3387 OP_EM (bytemode
, sizeflag
);
3392 static const char *Suffix3DNow
[] = {
3393 /* 00 */ NULL
, NULL
, NULL
, NULL
,
3394 /* 04 */ NULL
, NULL
, NULL
, NULL
,
3395 /* 08 */ NULL
, NULL
, NULL
, NULL
,
3396 /* 0C */ NULL
, "pi2fd", NULL
, NULL
,
3397 /* 10 */ NULL
, NULL
, NULL
, NULL
,
3398 /* 14 */ NULL
, NULL
, NULL
, NULL
,
3399 /* 18 */ NULL
, NULL
, NULL
, NULL
,
3400 /* 1C */ NULL
, "pf2id", NULL
, NULL
,
3401 /* 20 */ NULL
, NULL
, NULL
, NULL
,
3402 /* 24 */ NULL
, NULL
, NULL
, NULL
,
3403 /* 28 */ NULL
, NULL
, NULL
, NULL
,
3404 /* 2C */ NULL
, NULL
, NULL
, NULL
,
3405 /* 30 */ NULL
, NULL
, NULL
, NULL
,
3406 /* 34 */ NULL
, NULL
, NULL
, NULL
,
3407 /* 38 */ NULL
, NULL
, NULL
, NULL
,
3408 /* 3C */ NULL
, NULL
, NULL
, NULL
,
3409 /* 40 */ NULL
, NULL
, NULL
, NULL
,
3410 /* 44 */ NULL
, NULL
, NULL
, NULL
,
3411 /* 48 */ NULL
, NULL
, NULL
, NULL
,
3412 /* 4C */ NULL
, NULL
, NULL
, NULL
,
3413 /* 50 */ NULL
, NULL
, NULL
, NULL
,
3414 /* 54 */ NULL
, NULL
, NULL
, NULL
,
3415 /* 58 */ NULL
, NULL
, NULL
, NULL
,
3416 /* 5C */ NULL
, NULL
, NULL
, NULL
,
3417 /* 60 */ NULL
, NULL
, NULL
, NULL
,
3418 /* 64 */ NULL
, NULL
, NULL
, NULL
,
3419 /* 68 */ NULL
, NULL
, NULL
, NULL
,
3420 /* 6C */ NULL
, NULL
, NULL
, NULL
,
3421 /* 70 */ NULL
, NULL
, NULL
, NULL
,
3422 /* 74 */ NULL
, NULL
, NULL
, NULL
,
3423 /* 78 */ NULL
, NULL
, NULL
, NULL
,
3424 /* 7C */ NULL
, NULL
, NULL
, NULL
,
3425 /* 80 */ NULL
, NULL
, NULL
, NULL
,
3426 /* 84 */ NULL
, NULL
, NULL
, NULL
,
3427 /* 88 */ NULL
, NULL
, NULL
, NULL
,
3428 /* 8C */ NULL
, NULL
, NULL
, NULL
,
3429 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
3430 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
3431 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
3432 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
3433 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
3434 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
3435 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
3436 /* AC */ NULL
, NULL
, "pfacc", NULL
,
3437 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
3438 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
3439 /* B8 */ NULL
, NULL
, NULL
, NULL
,
3440 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
3441 /* C0 */ NULL
, NULL
, NULL
, NULL
,
3442 /* C4 */ NULL
, NULL
, NULL
, NULL
,
3443 /* C8 */ NULL
, NULL
, NULL
, NULL
,
3444 /* CC */ NULL
, NULL
, NULL
, NULL
,
3445 /* D0 */ NULL
, NULL
, NULL
, NULL
,
3446 /* D4 */ NULL
, NULL
, NULL
, NULL
,
3447 /* D8 */ NULL
, NULL
, NULL
, NULL
,
3448 /* DC */ NULL
, NULL
, NULL
, NULL
,
3449 /* E0 */ NULL
, NULL
, NULL
, NULL
,
3450 /* E4 */ NULL
, NULL
, NULL
, NULL
,
3451 /* E8 */ NULL
, NULL
, NULL
, NULL
,
3452 /* EC */ NULL
, NULL
, NULL
, NULL
,
3453 /* F0 */ NULL
, NULL
, NULL
, NULL
,
3454 /* F4 */ NULL
, NULL
, NULL
, NULL
,
3455 /* F8 */ NULL
, NULL
, NULL
, NULL
,
3456 /* FC */ NULL
, NULL
, NULL
, NULL
,
3460 OP_3DNowSuffix (bytemode
, sizeflag
)
3464 const char *mnemonic
;
3466 FETCH_DATA (the_info
, codep
+ 1);
3467 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3468 place where an 8-bit immediate would normally go. ie. the last
3469 byte of the instruction. */
3470 obufp
= obuf
+ strlen(obuf
);
3471 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
3476 /* Since a variable sized modrm/sib chunk is between the start
3477 of the opcode (0x0f0f) and the opcode suffix, we need to do
3478 all the modrm processing first, and don't know until now that
3479 we have a bad opcode. This necessitates some cleaning up. */
3487 static const char *simd_cmp_op
[] = {
3499 OP_SIMD_Suffix (bytemode
, sizeflag
)
3503 unsigned int cmp_type
;
3505 FETCH_DATA (the_info
, codep
+ 1);
3506 obufp
= obuf
+ strlen(obuf
);
3507 cmp_type
= *codep
++ & 0xff;
3510 sprintf (scratchbuf
, "cmp%s%cs",
3511 simd_cmp_op
[cmp_type
],
3512 prefixes
& PREFIX_REPZ
? 's' : 'p');
3513 oappend (scratchbuf
);
3517 /* We have a bad extension byte. Clean up. */
3525 SIMD_Fixup (extrachar
, sizeflag
)
3529 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3530 forms of these instructions. */
3533 char *p
= obuf
+ strlen(obuf
);
3542 static void BadOp (void)
3544 codep
= insn_codep
+ 1; /* throw away prefixes and 1st. opcode byte */