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
139 #define Ap OP_DIR, lptr
140 #define Av OP_DIR, v_mode
141 #define Ob OP_OFF, b_mode
142 #define Ov OP_OFF, v_mode
143 #define Xb OP_DSreg, eSI_reg
144 #define Xv OP_DSreg, eSI_reg
145 #define Yb OP_ESreg, eDI_reg
146 #define Yv OP_ESreg, eDI_reg
147 #define DSBX OP_DSreg, eBX_reg
149 #define es OP_REG, es_reg
150 #define ss OP_REG, ss_reg
151 #define cs OP_REG, cs_reg
152 #define ds OP_REG, ds_reg
153 #define fs OP_REG, fs_reg
154 #define gs OP_REG, gs_reg
157 #define EM OP_EM, v_mode
158 #define MS OP_MS, b_mode
159 #define OPSUF OP_3DNowSuffix, 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_rm
PARAMS ((int, int));
186 static void OP_ST
PARAMS ((int, int));
187 static void OP_STi
PARAMS ((int, int));
189 static void OP_ONE
PARAMS ((int, int));
191 static void OP_MMX
PARAMS ((int, int));
192 static void OP_EM
PARAMS ((int, int));
193 static void OP_MS
PARAMS ((int, int));
194 static void OP_3DNowSuffix
PARAMS ((int, int));
196 static void append_seg
PARAMS ((void));
197 static void set_op
PARAMS ((unsigned int op
));
198 static void putop
PARAMS ((char *template, int sizeflag
));
199 static void dofloat
PARAMS ((int sizeflag
));
200 static int get16
PARAMS ((void));
201 static int get32
PARAMS ((void));
202 static void ckprefix
PARAMS ((void));
203 static void ptr_reg
PARAMS ((int, int));
246 #define indir_dx_reg 150
248 #define GRP1b NULL, NULL, 0
249 #define GRP1S NULL, NULL, 1
250 #define GRP1Ss NULL, NULL, 2
251 #define GRP2b NULL, NULL, 3
252 #define GRP2S NULL, NULL, 4
253 #define GRP2b_one NULL, NULL, 5
254 #define GRP2S_one NULL, NULL, 6
255 #define GRP2b_cl NULL, NULL, 7
256 #define GRP2S_cl NULL, NULL, 8
257 #define GRP3b NULL, NULL, 9
258 #define GRP3S NULL, NULL, 10
259 #define GRP4 NULL, NULL, 11
260 #define GRP5 NULL, NULL, 12
261 #define GRP6 NULL, NULL, 13
262 #define GRP7 NULL, NULL, 14
263 #define GRP8 NULL, NULL, 15
264 #define GRP9 NULL, NULL, 16
265 #define GRP10 NULL, NULL, 17
266 #define GRP11 NULL, NULL, 18
267 #define GRP12 NULL, NULL, 19
268 #define GRP13 NULL, NULL, 20
269 #define GRP14 NULL, NULL, 21
272 #define FLOAT NULL, NULL, FLOATCODE
284 /* Upper case letters in the instruction names here are macros.
285 'A' => print 'b' if no register operands or suffix_always is true
286 'B' => print 'b' if suffix_always is true
287 'E' => print 'e' if 32-bit form of jcxz
288 'L' => print 'l' if suffix_always is true
289 'N' => print 'n' if instruction has no wait "prefix"
290 'P' => print 'w' or 'l' if instruction has an operand size prefix,
291 or suffix_always is true
292 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
293 'R' => print 'w' or 'l'
294 'S' => print 'w' or 'l' if suffix_always is true
295 'W' => print 'b' or 'w'
298 static struct dis386 dis386_att
[] = {
316 { "(bad)" }, /* 0x0f extended opcode escape */
342 { "(bad)" }, /* SEG ES prefix */
351 { "(bad)" }, /* SEG CS prefix */
360 { "(bad)" }, /* SEG SS prefix */
369 { "(bad)" }, /* SEG DS prefix */
410 { "boundS", Gv
, Ma
},
412 { "(bad)" }, /* seg fs */
413 { "(bad)" }, /* seg gs */
414 { "(bad)" }, /* op size prefix */
415 { "(bad)" }, /* adr size prefix */
417 { "pushP", Iv
}, /* 386 book wrong */
418 { "imulS", Gv
, Ev
, Iv
},
419 { "pushP", sIb
}, /* push of byte really pushes 2 or 4 bytes */
420 { "imulS", Gv
, Ev
, sIb
},
421 { "insb", Yb
, indirDX
},
422 { "insR", Yv
, indirDX
},
423 { "outsb", indirDX
, Xb
},
424 { "outsR", indirDX
, Xv
},
463 { "xchgS", eCX
, eAX
},
464 { "xchgS", eDX
, eAX
},
465 { "xchgS", eBX
, eAX
},
466 { "xchgS", eSP
, eAX
},
467 { "xchgS", eBP
, eAX
},
468 { "xchgS", eSI
, eAX
},
469 { "xchgS", eDI
, eAX
},
474 { "(bad)" }, /* fwait */
490 { "testS", eAX
, Iv
},
492 { "stosS", Yv
, eAX
},
494 { "lodsS", eAX
, Xv
},
496 { "scasS", eAX
, Yv
},
525 { "enterP", Iw
, Ib
},
565 { "inB", AL
, indirDX
},
566 { "inS", eAX
, indirDX
},
567 { "outB", indirDX
, AL
},
568 { "outS", indirDX
, eAX
},
570 { "(bad)" }, /* lock prefix */
572 { "(bad)" }, /* repne */
573 { "(bad)" }, /* repz */
589 static struct dis386 dis386_intel
[] = {
607 { "(bad)" }, /* 0x0f extended opcode escape */
633 { "(bad)" }, /* SEG ES prefix */
642 { "(bad)" }, /* SEG CS prefix */
651 { "(bad)" }, /* SEG SS prefix */
660 { "(bad)" }, /* SEG DS prefix */
701 { "boundS", Gv
, Ma
},
703 { "(bad)" }, /* seg fs */
704 { "(bad)" }, /* seg gs */
705 { "(bad)" }, /* op size prefix */
706 { "(bad)" }, /* adr size prefix */
708 { "pushP", Iv
}, /* 386 book wrong */
709 { "imulS", Gv
, Ev
, Iv
},
710 { "pushP", sIb
}, /* push of byte really pushes 2 or 4 bytes */
711 { "imulS", Gv
, Ev
, sIb
},
712 { "insb", Yb
, indirDX
},
713 { "insR", Yv
, indirDX
},
714 { "outsb", indirDX
, Xb
},
715 { "outsR", indirDX
, Xv
},
754 { "xchgS", eCX
, eAX
},
755 { "xchgS", eDX
, eAX
},
756 { "xchgS", eBX
, eAX
},
757 { "xchgS", eSP
, eAX
},
758 { "xchgS", eBP
, eAX
},
759 { "xchgS", eSI
, eAX
},
760 { "xchgS", eDI
, eAX
},
765 { "(bad)" }, /* fwait */
781 { "testS", eAX
, Iv
},
783 { "stosS", Yv
, eAX
},
785 { "lodsS", eAX
, Xv
},
787 { "scasS", eAX
, Yv
},
816 { "enterP", Iw
, Ib
},
856 { "inB", AL
, indirDX
},
857 { "inS", eAX
, indirDX
},
858 { "outB", indirDX
, AL
},
859 { "outS", indirDX
, eAX
},
861 { "(bad)" }, /* lock prefix */
863 { "(bad)" }, /* repne */
864 { "(bad)" }, /* repz */
880 static struct dis386 dis386_twobyte_att
[] = {
898 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
900 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
901 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
903 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
904 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
906 /* these are all backward in appendix A of the intel book */
916 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
917 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
919 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
920 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
922 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
923 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
925 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
926 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
928 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
929 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
931 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
932 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
934 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
935 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
937 { "punpcklbw", MX
, EM
},
938 { "punpcklwd", MX
, EM
},
939 { "punpckldq", MX
, EM
},
940 { "packsswb", MX
, EM
},
941 { "pcmpgtb", MX
, EM
},
942 { "pcmpgtw", MX
, EM
},
943 { "pcmpgtd", MX
, EM
},
944 { "packuswb", MX
, EM
},
946 { "punpckhbw", MX
, EM
},
947 { "punpckhwd", MX
, EM
},
948 { "punpckhdq", MX
, EM
},
949 { "packssdw", MX
, EM
},
950 { "(bad)" }, { "(bad)" },
958 { "pcmpeqb", MX
, EM
},
959 { "pcmpeqw", MX
, EM
},
960 { "pcmpeqd", MX
, EM
},
963 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
964 { "(bad)" }, { "(bad)" },
1008 { "shldS", Ev
, Gv
, Ib
},
1009 { "shldS", Ev
, Gv
, CL
},
1017 { "shrdS", Ev
, Gv
, Ib
},
1018 { "shrdS", Ev
, Gv
, CL
},
1020 { "imulS", Gv
, Ev
},
1022 { "cmpxchgB", Eb
, Gb
},
1023 { "cmpxchgS", Ev
, Gv
},
1024 { "lssS", Gv
, Mp
}, /* 386 lists only Mp */
1026 { "lfsS", Gv
, Mp
}, /* 386 lists only Mp */
1027 { "lgsS", Gv
, Mp
}, /* 386 lists only Mp */
1028 { "movzbR", Gv
, Eb
},
1029 { "movzwR", Gv
, Ew
}, /* yes, there really is movzww ! */
1037 { "movsbR", Gv
, Eb
},
1038 { "movswR", Gv
, Ew
}, /* yes, there really is movsww ! */
1040 { "xaddB", Eb
, Gb
},
1041 { "xaddS", Ev
, Gv
},
1049 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1059 { "psrlw", MX
, EM
},
1060 { "psrld", MX
, EM
},
1061 { "psrlq", MX
, EM
},
1063 { "pmullw", MX
, EM
},
1064 { "(bad)" }, { "(bad)" },
1066 { "psubusb", MX
, EM
},
1067 { "psubusw", MX
, EM
},
1070 { "paddusb", MX
, EM
},
1071 { "paddusw", MX
, EM
},
1073 { "pandn", MX
, EM
},
1076 { "psraw", MX
, EM
},
1077 { "psrad", MX
, EM
},
1080 { "pmulhw", MX
, EM
},
1081 { "(bad)" }, { "(bad)" },
1083 { "psubsb", MX
, EM
},
1084 { "psubsw", MX
, EM
},
1087 { "paddsb", MX
, EM
},
1088 { "paddsw", MX
, EM
},
1093 { "psllw", MX
, EM
},
1094 { "pslld", MX
, EM
},
1095 { "psllq", MX
, EM
},
1097 { "pmaddwd", MX
, EM
},
1098 { "(bad)" }, { "(bad)" },
1100 { "psubb", MX
, EM
},
1101 { "psubw", MX
, EM
},
1102 { "psubd", MX
, EM
},
1104 { "paddb", MX
, EM
},
1105 { "paddw", MX
, EM
},
1106 { "paddd", MX
, EM
},
1110 static struct dis386 dis386_twobyte_intel
[] = {
1128 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1130 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1131 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1133 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1134 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1136 /* these are all backward in appendix A of the intel book */
1146 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1147 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1149 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1150 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1152 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1153 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1155 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
1156 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
1158 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
1159 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
1161 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1162 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1164 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1165 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1167 { "punpcklbw", MX
, EM
},
1168 { "punpcklwd", MX
, EM
},
1169 { "punpckldq", MX
, EM
},
1170 { "packsswb", MX
, EM
},
1171 { "pcmpgtb", MX
, EM
},
1172 { "pcmpgtw", MX
, EM
},
1173 { "pcmpgtd", MX
, EM
},
1174 { "packuswb", MX
, EM
},
1176 { "punpckhbw", MX
, EM
},
1177 { "punpckhwd", MX
, EM
},
1178 { "punpckhdq", MX
, EM
},
1179 { "packssdw", MX
, EM
},
1180 { "(bad)" }, { "(bad)" },
1188 { "pcmpeqb", MX
, EM
},
1189 { "pcmpeqw", MX
, EM
},
1190 { "pcmpeqd", MX
, EM
},
1193 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1194 { "(bad)" }, { "(bad)" },
1238 { "shldS", Ev
, Gv
, Ib
},
1239 { "shldS", Ev
, Gv
, CL
},
1247 { "shrdS", Ev
, Gv
, Ib
},
1248 { "shrdS", Ev
, Gv
, CL
},
1250 { "imulS", Gv
, Ev
},
1252 { "cmpxchgB", Eb
, Gb
},
1253 { "cmpxchgS", Ev
, Gv
},
1254 { "lssS", Gv
, Mp
}, /* 386 lists only Mp */
1256 { "lfsS", Gv
, Mp
}, /* 386 lists only Mp */
1257 { "lgsS", Gv
, Mp
}, /* 386 lists only Mp */
1258 { "movzx", Gv
, Eb
},
1259 { "movzx", Gv
, Ew
},
1267 { "movsx", Gv
, Eb
},
1268 { "movsx", Gv
, Ew
},
1270 { "xaddB", Eb
, Gb
},
1271 { "xaddS", Ev
, Gv
},
1279 { "bswap", eAX
}, /* bswap doesn't support 16 bit regs */
1289 { "psrlw", MX
, EM
},
1290 { "psrld", MX
, EM
},
1291 { "psrlq", MX
, EM
},
1293 { "pmullw", MX
, EM
},
1294 { "(bad)" }, { "(bad)" },
1296 { "psubusb", MX
, EM
},
1297 { "psubusw", MX
, EM
},
1300 { "paddusb", MX
, EM
},
1301 { "paddusw", MX
, EM
},
1303 { "pandn", MX
, EM
},
1306 { "psraw", MX
, EM
},
1307 { "psrad", MX
, EM
},
1310 { "pmulhw", MX
, EM
},
1311 { "(bad)" }, { "(bad)" },
1313 { "psubsb", MX
, EM
},
1314 { "psubsw", MX
, EM
},
1317 { "paddsb", MX
, EM
},
1318 { "paddsw", MX
, EM
},
1323 { "psllw", MX
, EM
},
1324 { "pslld", MX
, EM
},
1325 { "psllq", MX
, EM
},
1327 { "pmaddwd", MX
, EM
},
1328 { "(bad)" }, { "(bad)" },
1330 { "psubb", MX
, EM
},
1331 { "psubw", MX
, EM
},
1332 { "psubd", MX
, EM
},
1334 { "paddb", MX
, EM
},
1335 { "paddw", MX
, EM
},
1336 { "paddd", MX
, EM
},
1340 static const unsigned char onebyte_has_modrm
[256] = {
1341 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1342 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1343 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1344 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1345 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1347 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
1348 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1349 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1350 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1351 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1352 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1353 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
1354 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1355 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1356 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
1359 static const unsigned char twobyte_has_modrm
[256] = {
1360 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1361 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1362 /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
1363 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1364 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1365 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1366 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1367 /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1368 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1369 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1370 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1371 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1372 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1373 /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
1374 /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
1375 /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
1378 static char obuf
[100];
1380 static char scratchbuf
[100];
1381 static unsigned char *start_codep
;
1382 static unsigned char *insn_codep
;
1383 static unsigned char *codep
;
1384 static disassemble_info
*the_info
;
1388 static void oappend
PARAMS ((char *s
));
1390 static char *names32
[]={
1391 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1393 static char *names16
[] = {
1394 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1396 static char *names8
[] = {
1397 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1399 static char *names_seg
[] = {
1400 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1402 static char *index16
[] = {
1403 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1406 static struct dis386 grps
[][8] = {
1431 { "addQ", Ev
, sIb
},
1433 { "adcQ", Ev
, sIb
},
1434 { "sbbQ", Ev
, sIb
},
1435 { "andQ", Ev
, sIb
},
1436 { "subQ", Ev
, sIb
},
1437 { "xorQ", Ev
, sIb
},
1508 { "testA", Eb
, Ib
},
1513 { "imulB", AL
, Eb
},
1519 { "testQ", Ev
, Iv
},
1523 { "mulS", eAX
, Ev
},
1524 { "imulS", eAX
, Ev
},
1525 { "divS", eAX
, Ev
},
1526 { "idivS", eAX
, Ev
},
1543 { "callP", indirEv
},
1544 { "callP", indirEv
},
1545 { "jmpP", indirEv
},
1546 { "ljmpP", indirEv
},
1586 { "cmpxchg8b", Ev
},
1598 { "psrlw", MS
, Ib
},
1600 { "psraw", MS
, Ib
},
1602 { "psllw", MS
, Ib
},
1609 { "psrld", MS
, Ib
},
1611 { "psrad", MS
, Ib
},
1613 { "pslld", MS
, Ib
},
1620 { "psrlq", MS
, Ib
},
1624 { "psllq", MS
, Ib
},
1641 { "prefetchw", Eb
},
1652 #define PREFIX_REPZ 1
1653 #define PREFIX_REPNZ 2
1654 #define PREFIX_LOCK 4
1656 #define PREFIX_SS 0x10
1657 #define PREFIX_DS 0x20
1658 #define PREFIX_ES 0x40
1659 #define PREFIX_FS 0x80
1660 #define PREFIX_GS 0x100
1661 #define PREFIX_DATA 0x200
1662 #define PREFIX_ADDR 0x400
1663 #define PREFIX_FWAIT 0x800
1665 static int prefixes
;
1673 FETCH_DATA (the_info
, codep
+ 1);
1677 prefixes
|= PREFIX_REPZ
;
1680 prefixes
|= PREFIX_REPNZ
;
1683 prefixes
|= PREFIX_LOCK
;
1686 prefixes
|= PREFIX_CS
;
1689 prefixes
|= PREFIX_SS
;
1692 prefixes
|= PREFIX_DS
;
1695 prefixes
|= PREFIX_ES
;
1698 prefixes
|= PREFIX_FS
;
1701 prefixes
|= PREFIX_GS
;
1704 prefixes
|= PREFIX_DATA
;
1707 prefixes
|= PREFIX_ADDR
;
1710 /* fwait is really an instruction. If there are prefixes
1711 before the fwait, they belong to the fwait, *not* to the
1712 following instruction. */
1715 prefixes
|= PREFIX_FWAIT
;
1719 prefixes
= PREFIX_FWAIT
;
1728 static char op1out
[100], op2out
[100], op3out
[100];
1729 static int op_ad
, op_index
[3];
1730 static unsigned int op_address
[3];
1731 static unsigned int start_pc
;
1735 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1736 * (see topic "Redundant prefixes" in the "Differences from 8086"
1737 * section of the "Virtual 8086 Mode" chapter.)
1738 * 'pc' should be the address of this instruction, it will
1739 * be used to print the target address if this is a relative jump or call
1740 * The function returns the length of this instruction in bytes.
1743 static int print_insn_x86
1744 PARAMS ((bfd_vma pc
, disassemble_info
*info
, int sizeflag
));
1745 static int print_insn_i386
1746 PARAMS ((bfd_vma pc
, disassemble_info
*info
));
1748 static char intel_syntax
;
1749 static char open_char
;
1750 static char close_char
;
1751 static char separator_char
;
1752 static char scale_char
;
1755 print_insn_i386_att (pc
, info
)
1757 disassemble_info
*info
;
1762 separator_char
= ',';
1765 return print_insn_i386 (pc
, info
);
1769 print_insn_i386_intel (pc
, info
)
1771 disassemble_info
*info
;
1776 separator_char
= '+';
1779 return print_insn_i386 (pc
, info
);
1783 print_insn_i386 (pc
, info
)
1785 disassemble_info
*info
;
1788 if (info
->mach
== bfd_mach_i386_i386
1789 || info
->mach
== bfd_mach_i386_i386_intel_syntax
)
1790 flags
= AFLAG
|DFLAG
;
1791 else if (info
->mach
== bfd_mach_i386_i8086
)
1795 return print_insn_x86 (pc
, info
, flags
);
1799 print_insn_x86 (pc
, info
, sizeflag
)
1801 disassemble_info
*info
;
1807 char *first
, *second
, *third
;
1809 unsigned char need_modrm
;
1811 struct dis_private priv
;
1812 bfd_byte
*inbuf
= priv
.the_buffer
;
1814 /* The output looks better if we put 5 bytes on a line, since that
1815 puts long word instructions on a single line. */
1816 info
->bytes_per_line
= 5;
1818 info
->private_data
= (PTR
) &priv
;
1819 priv
.max_fetched
= priv
.the_buffer
;
1820 priv
.insn_start
= pc
;
1821 if (setjmp (priv
.bailout
) != 0)
1830 op_index
[0] = op_index
[1] = op_index
[2] = -1;
1834 start_codep
= inbuf
;
1841 FETCH_DATA (info
, codep
+ 1);
1842 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
1846 if ((prefixes
& PREFIX_FWAIT
)
1847 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
1849 /* fwait not followed by floating point instruction. */
1850 (*info
->fprintf_func
) (info
->stream
, "fwait");
1851 /* There may be other prefixes. Skip any before the fwait. */
1852 return codep
- inbuf
;
1855 if (prefixes
& PREFIX_REPZ
)
1857 if (prefixes
& PREFIX_REPNZ
)
1859 if (prefixes
& PREFIX_LOCK
)
1862 if (prefixes
& PREFIX_DATA
)
1865 if (prefixes
& PREFIX_ADDR
)
1868 if (sizeflag
& AFLAG
)
1869 oappend ("addr32 ");
1871 oappend ("addr16 ");
1876 FETCH_DATA (info
, codep
+ 2);
1878 dp
= &dis386_twobyte_intel
[*++codep
];
1880 dp
= &dis386_twobyte_att
[*++codep
];
1881 need_modrm
= twobyte_has_modrm
[*codep
];
1886 dp
= &dis386_intel
[*codep
];
1888 dp
= &dis386_att
[*codep
];
1889 need_modrm
= onebyte_has_modrm
[*codep
];
1895 FETCH_DATA (info
, codep
+ 1);
1896 mod
= (*codep
>> 6) & 3;
1897 reg
= (*codep
>> 3) & 7;
1901 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
1907 if (dp
->name
== NULL
)
1908 dp
= &grps
[dp
->bytemode1
][reg
];
1910 putop (dp
->name
, sizeflag
);
1915 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
1920 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
1925 (*dp
->op3
)(dp
->bytemode3
, sizeflag
);
1928 obufp
= obuf
+ strlen (obuf
);
1929 for (i
= strlen (obuf
); i
< 6; i
++)
1932 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
1934 /* The enter and bound instructions are printed with operands in the same
1935 order as the intel book; everything else is printed in reverse order. */
1936 if (intel_syntax
|| two_source_ops
)
1941 op_ad
= op_index
[0];
1942 op_index
[0] = op_index
[2];
1943 op_index
[2] = op_ad
;
1954 if (op_index
[0] != -1)
1955 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
1957 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
1963 (*info
->fprintf_func
) (info
->stream
, ",");
1964 if (op_index
[1] != -1)
1965 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
1967 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
1973 (*info
->fprintf_func
) (info
->stream
, ",");
1974 if (op_index
[2] != -1)
1975 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
1977 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
1979 return codep
- inbuf
;
1982 static char *float_mem_att
[] = {
2057 static char *float_mem_intel
[] = {
2133 #define STi OP_STi, 0
2135 #define FGRPd9_2 NULL, NULL, 0
2136 #define FGRPd9_4 NULL, NULL, 1
2137 #define FGRPd9_5 NULL, NULL, 2
2138 #define FGRPd9_6 NULL, NULL, 3
2139 #define FGRPd9_7 NULL, NULL, 4
2140 #define FGRPda_5 NULL, NULL, 5
2141 #define FGRPdb_4 NULL, NULL, 6
2142 #define FGRPde_3 NULL, NULL, 7
2143 #define FGRPdf_4 NULL, NULL, 8
2145 static struct dis386 float_reg
[][8] = {
2148 { "fadd", ST
, STi
},
2149 { "fmul", ST
, STi
},
2152 { "fsub", ST
, STi
},
2153 { "fsubr", ST
, STi
},
2154 { "fdiv", ST
, STi
},
2155 { "fdivr", ST
, STi
},
2170 { "fcmovb", ST
, STi
},
2171 { "fcmove", ST
, STi
},
2172 { "fcmovbe",ST
, STi
},
2173 { "fcmovu", ST
, STi
},
2181 { "fcmovnb",ST
, STi
},
2182 { "fcmovne",ST
, STi
},
2183 { "fcmovnbe",ST
, STi
},
2184 { "fcmovnu",ST
, STi
},
2186 { "fucomi", ST
, STi
},
2187 { "fcomi", ST
, STi
},
2192 { "fadd", STi
, ST
},
2193 { "fmul", STi
, ST
},
2197 { "fsub", STi
, ST
},
2198 { "fsubr", STi
, ST
},
2199 { "fdiv", STi
, ST
},
2200 { "fdivr", STi
, ST
},
2202 { "fsubr", STi
, ST
},
2203 { "fsub", STi
, ST
},
2204 { "fdivr", STi
, ST
},
2205 { "fdiv", STi
, ST
},
2221 { "faddp", STi
, ST
},
2222 { "fmulp", STi
, ST
},
2226 { "fsubp", STi
, ST
},
2227 { "fsubrp", STi
, ST
},
2228 { "fdivp", STi
, ST
},
2229 { "fdivrp", STi
, ST
},
2231 { "fsubrp", STi
, ST
},
2232 { "fsubp", STi
, ST
},
2233 { "fdivrp", STi
, ST
},
2234 { "fdivp", STi
, ST
},
2244 { "fucomip",ST
, STi
},
2245 { "fcomip", ST
, STi
},
2251 static char *fgrps
[][8] = {
2254 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2259 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2264 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2269 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2274 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2279 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2284 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2285 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2290 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2295 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2304 unsigned char floatop
;
2306 floatop
= codep
[-1];
2311 putop (float_mem_intel
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2313 putop (float_mem_att
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
2315 if (floatop
== 0xdb)
2316 OP_E (x_mode
, sizeflag
);
2317 else if (floatop
== 0xdd)
2318 OP_E (d_mode
, sizeflag
);
2320 OP_E (v_mode
, sizeflag
);
2325 dp
= &float_reg
[floatop
- 0xd8][reg
];
2326 if (dp
->name
== NULL
)
2328 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2330 /* instruction fnstsw is only one with strange arg */
2331 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2332 strcpy (op1out
, names16
[0]);
2336 putop (dp
->name
, sizeflag
);
2340 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
2343 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
2349 OP_ST (ignore
, sizeflag
)
2358 OP_STi (ignore
, sizeflag
)
2362 sprintf (scratchbuf
, "%%st(%d)", rm
);
2363 oappend (scratchbuf
);
2367 /* capital letters in template are macros */
2369 putop (template, sizeflag
)
2375 for (p
= template; *p
; p
++)
2386 #ifdef SUFFIX_ALWAYS
2387 || (sizeflag
& SUFFIX_ALWAYS
)
2395 #ifdef SUFFIX_ALWAYS
2396 if (sizeflag
& SUFFIX_ALWAYS
)
2400 case 'E': /* For jcxz/jecxz */
2401 if (sizeflag
& AFLAG
)
2407 #ifdef SUFFIX_ALWAYS
2408 if (sizeflag
& SUFFIX_ALWAYS
)
2413 if ((prefixes
& PREFIX_FWAIT
) == 0)
2419 if ((prefixes
& PREFIX_DATA
)
2420 #ifdef SUFFIX_ALWAYS
2421 || (sizeflag
& SUFFIX_ALWAYS
)
2425 if (sizeflag
& DFLAG
)
2435 #ifdef SUFFIX_ALWAYS
2436 || (sizeflag
& SUFFIX_ALWAYS
)
2440 if (sizeflag
& DFLAG
)
2449 if (sizeflag
& DFLAG
)
2457 #ifdef SUFFIX_ALWAYS
2458 if (sizeflag
& SUFFIX_ALWAYS
)
2460 if (sizeflag
& DFLAG
)
2470 /* operand size flag for cwtl, cbtw */
2471 if (sizeflag
& DFLAG
)
2486 obufp
+= strlen (s
);
2492 if (prefixes
& PREFIX_CS
)
2494 if (prefixes
& PREFIX_DS
)
2496 if (prefixes
& PREFIX_SS
)
2498 if (prefixes
& PREFIX_ES
)
2500 if (prefixes
& PREFIX_FS
)
2502 if (prefixes
& PREFIX_GS
)
2507 OP_indirE (bytemode
, sizeflag
)
2513 OP_E (bytemode
, sizeflag
);
2517 OP_E (bytemode
, sizeflag
)
2523 /* skip mod/rm byte */
2531 oappend (names8
[rm
]);
2534 oappend (names16
[rm
]);
2537 if (sizeflag
& DFLAG
)
2538 oappend (names32
[rm
]);
2540 oappend (names16
[rm
]);
2543 oappend ("<bad dis table>");
2552 if (sizeflag
& AFLAG
) /* 32 bit address mode */
2567 FETCH_DATA (the_info
, codep
+ 1);
2568 scale
= (*codep
>> 6) & 3;
2569 index
= (*codep
>> 3) & 7;
2584 FETCH_DATA (the_info
, codep
+ 1);
2586 if ((disp
& 0x80) != 0)
2595 if (mod
!= 0 || base
== 5)
2597 sprintf (scratchbuf
, "0x%x", disp
);
2598 oappend (scratchbuf
);
2601 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
2608 oappend("BYTE PTR ");
2611 oappend("WORD PTR ");
2614 oappend("DWORD PTR ");
2617 oappend("QWORD PTR ");
2620 oappend("XWORD PTR ");
2626 *obufp
++ = open_char
;
2629 oappend (names32
[base
]);
2638 *obufp
++ = separator_char
;
2641 sprintf (scratchbuf
, "%s", names32
[index
]);
2644 sprintf (scratchbuf
, ",%s", names32
[index
]);
2645 oappend (scratchbuf
);
2649 && bytemode
!= b_mode
2650 && bytemode
!= w_mode
2651 && bytemode
!= v_mode
))
2653 *obufp
++ = scale_char
;
2655 sprintf (scratchbuf
, "%d", 1 << scale
);
2656 oappend (scratchbuf
);
2660 if (mod
!= 0 || base
== 5)
2662 /* Don't print zero displacements */
2665 sprintf (scratchbuf
, "+%d", disp
);
2666 oappend (scratchbuf
);
2670 sprintf (scratchbuf
, "%d", disp
);
2671 oappend (scratchbuf
);
2675 *obufp
++ = close_char
;
2678 else if (intel_syntax
)
2680 if (mod
!= 0 || base
== 5)
2682 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
2683 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
2687 oappend (names_seg
[3]);
2690 sprintf (scratchbuf
, "0x%x", disp
);
2691 oappend (scratchbuf
);
2696 { /* 16 bit address mode */
2703 if ((disp
& 0x8000) != 0)
2708 FETCH_DATA (the_info
, codep
+ 1);
2710 if ((disp
& 0x80) != 0)
2715 if ((disp
& 0x8000) != 0)
2721 if (mod
!= 0 || rm
== 6)
2723 sprintf (scratchbuf
, "%d", disp
);
2724 oappend (scratchbuf
);
2727 if (mod
!= 0 || rm
!= 6)
2729 *obufp
++ = open_char
;
2731 oappend (index16
[rm
]);
2732 *obufp
++ = close_char
;
2738 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2741 OP_G (bytemode
, sizeflag
)
2748 oappend (names8
[reg
]);
2751 oappend (names16
[reg
]);
2754 oappend (names32
[reg
]);
2757 if (sizeflag
& DFLAG
)
2758 oappend (names32
[reg
]);
2760 oappend (names16
[reg
]);
2763 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2773 FETCH_DATA (the_info
, codep
+ 4);
2774 x
= *codep
++ & 0xff;
2775 x
|= (*codep
++ & 0xff) << 8;
2776 x
|= (*codep
++ & 0xff) << 16;
2777 x
|= (*codep
++ & 0xff) << 24;
2786 FETCH_DATA (the_info
, codep
+ 2);
2787 x
= *codep
++ & 0xff;
2788 x
|= (*codep
++ & 0xff) << 8;
2796 op_index
[op_ad
] = op_ad
;
2797 op_address
[op_ad
] = op
;
2801 OP_REG (code
, sizeflag
)
2812 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
2813 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
2814 s
= names16
[code
- ax_reg
];
2816 case es_reg
: case ss_reg
: case cs_reg
:
2817 case ds_reg
: case fs_reg
: case gs_reg
:
2818 s
= names_seg
[code
- es_reg
];
2820 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
2821 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
2822 s
= names8
[code
- al_reg
];
2824 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
2825 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
2826 if (sizeflag
& DFLAG
)
2827 s
= names32
[code
- eAX_reg
];
2829 s
= names16
[code
- eAX_reg
];
2832 s
= INTERNAL_DISASSEMBLER_ERROR
;
2839 OP_I (bytemode
, sizeflag
)
2848 FETCH_DATA (the_info
, codep
+ 1);
2849 op
= *codep
++ & 0xff;
2852 if (sizeflag
& DFLAG
)
2861 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2866 sprintf (scratchbuf
, "0x%x", op
);
2868 sprintf (scratchbuf
, "$0x%x", op
);
2869 oappend (scratchbuf
);
2870 scratchbuf
[0] = '\0';
2874 OP_sI (bytemode
, sizeflag
)
2883 FETCH_DATA (the_info
, codep
+ 1);
2885 if ((op
& 0x80) != 0)
2889 if (sizeflag
& DFLAG
)
2894 if ((op
& 0x8000) != 0)
2900 if ((op
& 0x8000) != 0)
2904 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2908 sprintf (scratchbuf
, "%d", op
);
2910 sprintf (scratchbuf
, "$0x%x", op
);
2911 oappend (scratchbuf
);
2915 OP_J (bytemode
, sizeflag
)
2925 FETCH_DATA (the_info
, codep
+ 1);
2927 if ((disp
& 0x80) != 0)
2931 if (sizeflag
& DFLAG
)
2936 /* for some reason, a data16 prefix on a jump instruction
2937 means that the pc is masked to 16 bits after the
2938 displacement is added! */
2943 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2946 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
2948 sprintf (scratchbuf
, "0x%x", disp
);
2949 oappend (scratchbuf
);
2954 OP_SEG (dummy
, sizeflag
)
2958 static char *sreg
[] = {
2959 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2962 oappend (sreg
[reg
]);
2966 OP_DIR (size
, sizeflag
)
2975 if (sizeflag
& DFLAG
)
2985 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
2986 oappend (scratchbuf
);
2989 if (sizeflag
& DFLAG
)
2994 if ((offset
& 0x8000) != 0)
2998 offset
= start_pc
+ codep
- start_codep
+ offset
;
3000 sprintf (scratchbuf
, "0x%x", offset
);
3001 oappend (scratchbuf
);
3004 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3011 OP_OFF (ignore
, sizeflag
)
3019 if (sizeflag
& AFLAG
)
3026 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3027 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3029 oappend (names_seg
[3]);
3033 sprintf (scratchbuf
, "0x%x", off
);
3034 oappend (scratchbuf
);
3038 ptr_reg (code
, sizeflag
)
3044 if (sizeflag
& AFLAG
)
3045 s
= names32
[code
- eAX_reg
];
3047 s
= names16
[code
- eAX_reg
];
3053 OP_ESreg (code
, sizeflag
)
3058 ptr_reg (code
, sizeflag
);
3062 OP_DSreg (code
, sizeflag
)
3073 prefixes
|= PREFIX_DS
;
3075 ptr_reg (code
, sizeflag
);
3083 OP_ONE (dummy
, sizeflag
)
3094 OP_C (dummy
, sizeflag
)
3098 codep
++; /* skip mod/rm */
3099 sprintf (scratchbuf
, "%%cr%d", reg
);
3100 oappend (scratchbuf
);
3105 OP_D (dummy
, sizeflag
)
3109 codep
++; /* skip mod/rm */
3110 sprintf (scratchbuf
, "%%db%d", reg
);
3111 oappend (scratchbuf
);
3116 OP_T (dummy
, sizeflag
)
3120 codep
++; /* skip mod/rm */
3121 sprintf (scratchbuf
, "%%tr%d", reg
);
3122 oappend (scratchbuf
);
3126 OP_rm (bytemode
, sizeflag
)
3133 oappend (names32
[rm
]);
3136 oappend (names16
[rm
]);
3142 OP_MMX (ignore
, sizeflag
)
3146 sprintf (scratchbuf
, "%%mm%d", reg
);
3147 oappend (scratchbuf
);
3151 OP_EM (bytemode
, sizeflag
)
3157 OP_E (bytemode
, sizeflag
);
3162 sprintf (scratchbuf
, "%%mm%d", rm
);
3163 oappend (scratchbuf
);
3167 OP_MS (ignore
, sizeflag
)
3172 sprintf (scratchbuf
, "%%mm%d", rm
);
3173 oappend (scratchbuf
);
3176 static const char *Suffix3DNow
[] = {
3177 /* 00 */ NULL
, NULL
, NULL
, NULL
,
3178 /* 04 */ NULL
, NULL
, NULL
, NULL
,
3179 /* 08 */ NULL
, NULL
, NULL
, NULL
,
3180 /* 0C */ NULL
, "pi2fd", NULL
, NULL
,
3181 /* 10 */ NULL
, NULL
, NULL
, NULL
,
3182 /* 14 */ NULL
, NULL
, NULL
, NULL
,
3183 /* 18 */ NULL
, NULL
, NULL
, NULL
,
3184 /* 1C */ NULL
, "pf2id", NULL
, NULL
,
3185 /* 20 */ NULL
, NULL
, NULL
, NULL
,
3186 /* 24 */ NULL
, NULL
, NULL
, NULL
,
3187 /* 28 */ NULL
, NULL
, NULL
, NULL
,
3188 /* 2C */ NULL
, NULL
, NULL
, NULL
,
3189 /* 30 */ NULL
, NULL
, NULL
, NULL
,
3190 /* 34 */ NULL
, NULL
, NULL
, NULL
,
3191 /* 38 */ NULL
, NULL
, NULL
, NULL
,
3192 /* 3C */ NULL
, NULL
, NULL
, NULL
,
3193 /* 40 */ NULL
, NULL
, NULL
, NULL
,
3194 /* 44 */ NULL
, NULL
, NULL
, NULL
,
3195 /* 48 */ NULL
, NULL
, NULL
, NULL
,
3196 /* 4C */ NULL
, NULL
, NULL
, NULL
,
3197 /* 50 */ NULL
, NULL
, NULL
, NULL
,
3198 /* 54 */ NULL
, NULL
, NULL
, NULL
,
3199 /* 58 */ NULL
, NULL
, NULL
, NULL
,
3200 /* 5C */ NULL
, NULL
, NULL
, NULL
,
3201 /* 60 */ NULL
, NULL
, NULL
, NULL
,
3202 /* 64 */ NULL
, NULL
, NULL
, NULL
,
3203 /* 68 */ NULL
, NULL
, NULL
, NULL
,
3204 /* 6C */ NULL
, NULL
, NULL
, NULL
,
3205 /* 70 */ NULL
, NULL
, NULL
, NULL
,
3206 /* 74 */ NULL
, NULL
, NULL
, NULL
,
3207 /* 78 */ NULL
, NULL
, NULL
, NULL
,
3208 /* 7C */ NULL
, NULL
, NULL
, NULL
,
3209 /* 80 */ NULL
, NULL
, NULL
, NULL
,
3210 /* 84 */ NULL
, NULL
, NULL
, NULL
,
3211 /* 88 */ NULL
, NULL
, NULL
, NULL
,
3212 /* 8C */ NULL
, NULL
, NULL
, NULL
,
3213 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
3214 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
3215 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
3216 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
3217 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
3218 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
3219 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
3220 /* AC */ NULL
, NULL
, "pfacc", NULL
,
3221 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
3222 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
3223 /* B8 */ NULL
, NULL
, NULL
, NULL
,
3224 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
3225 /* C0 */ NULL
, NULL
, NULL
, NULL
,
3226 /* C4 */ NULL
, NULL
, NULL
, NULL
,
3227 /* C8 */ NULL
, NULL
, NULL
, NULL
,
3228 /* CC */ NULL
, NULL
, NULL
, NULL
,
3229 /* D0 */ NULL
, NULL
, NULL
, NULL
,
3230 /* D4 */ NULL
, NULL
, NULL
, NULL
,
3231 /* D8 */ NULL
, NULL
, NULL
, NULL
,
3232 /* DC */ NULL
, NULL
, NULL
, NULL
,
3233 /* E0 */ NULL
, NULL
, NULL
, NULL
,
3234 /* E4 */ NULL
, NULL
, NULL
, NULL
,
3235 /* E8 */ NULL
, NULL
, NULL
, NULL
,
3236 /* EC */ NULL
, NULL
, NULL
, NULL
,
3237 /* F0 */ NULL
, NULL
, NULL
, NULL
,
3238 /* F4 */ NULL
, NULL
, NULL
, NULL
,
3239 /* F8 */ NULL
, NULL
, NULL
, NULL
,
3240 /* FC */ NULL
, NULL
, NULL
, NULL
,
3244 OP_3DNowSuffix (bytemode
, sizeflag
)
3248 const char *mnemonic
;
3250 FETCH_DATA (the_info
, codep
+ 1);
3251 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3252 place where an 8-bit immediate would normally go. ie. the last
3253 byte of the instruction. */
3254 mnemonic
= Suffix3DNow
[*codep
++];
3256 strcat (obuf
, mnemonic
);
3259 /* Since a variable sized modrm/sib chunk is between the start
3260 of the opcode (0x0f0f) and the opcode suffix, we need to do
3261 all the modrm processing first, and don't know until now that
3262 we have a bad opcode. This necessitates some cleaning up. */
3265 codep
= insn_codep
+ 1;
3266 strcat (obuf
, "(bad)");