root / i386-dis.c @ 504e56eb
History | View | Annotate | Download (44.7 kB)
1 | dc99065b | bellard | /* Print i386 instructions for GDB, the GNU debugger.
|
---|---|---|---|
2 | dc99065b | bellard | Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
|
3 | dc99065b | bellard | Free Software Foundation, Inc.
|
4 | dc99065b | bellard | |
5 | dc99065b | bellard | This file is part of GDB.
|
6 | dc99065b | bellard | |
7 | dc99065b | bellard | This program is free software; you can redistribute it and/or modify
|
8 | dc99065b | bellard | it under the terms of the GNU General Public License as published by
|
9 | dc99065b | bellard | the Free Software Foundation; either version 2 of the License, or
|
10 | dc99065b | bellard | (at your option) any later version.
|
11 | dc99065b | bellard | |
12 | dc99065b | bellard | This program is distributed in the hope that it will be useful,
|
13 | dc99065b | bellard | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | dc99065b | bellard | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 | dc99065b | bellard | GNU General Public License for more details.
|
16 | dc99065b | bellard | |
17 | dc99065b | bellard | You should have received a copy of the GNU General Public License
|
18 | dc99065b | bellard | along with this program; if not, write to the Free Software
|
19 | dc99065b | bellard | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
20 | dc99065b | bellard | |
21 | dc99065b | bellard | /*
|
22 | dc99065b | bellard | * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
|
23 | dc99065b | bellard | * July 1988
|
24 | dc99065b | bellard | * modified by John Hassey (hassey@dg-rtp.dg.com)
|
25 | dc99065b | bellard | */
|
26 | dc99065b | bellard | |
27 | dc99065b | bellard | /*
|
28 | dc99065b | bellard | * The main tables describing the instructions is essentially a copy
|
29 | dc99065b | bellard | * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
|
30 | dc99065b | bellard | * Programmers Manual. Usually, there is a capital letter, followed
|
31 | dc99065b | bellard | * by a small letter. The capital letter tell the addressing mode,
|
32 | dc99065b | bellard | * and the small letter tells about the operand size. Refer to
|
33 | dc99065b | bellard | * the Intel manual for details.
|
34 | dc99065b | bellard | */
|
35 | dc99065b | bellard | |
36 | bb0ebb1f | bellard | #include <stdlib.h> |
37 | bb0ebb1f | bellard | #include <setjmp.h> |
38 | bb0ebb1f | bellard | |
39 | dc99065b | bellard | #include "dis-asm.h" |
40 | dc99065b | bellard | |
41 | dc99065b | bellard | #define MAXLEN 20 |
42 | dc99065b | bellard | |
43 | dc99065b | bellard | static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *)); |
44 | dc99065b | bellard | |
45 | dc99065b | bellard | struct dis_private
|
46 | dc99065b | bellard | { |
47 | dc99065b | bellard | /* Points to first byte not fetched. */
|
48 | dc99065b | bellard | bfd_byte *max_fetched; |
49 | dc99065b | bellard | bfd_byte the_buffer[MAXLEN]; |
50 | dc99065b | bellard | bfd_vma insn_start; |
51 | dc99065b | bellard | jmp_buf bailout; |
52 | dc99065b | bellard | }; |
53 | dc99065b | bellard | |
54 | dc99065b | bellard | /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
|
55 | dc99065b | bellard | to ADDR (exclusive) are valid. Returns 1 for success, longjmps
|
56 | dc99065b | bellard | on error. */
|
57 | dc99065b | bellard | #define FETCH_DATA(info, addr) \
|
58 | dc99065b | bellard | ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
|
59 | dc99065b | bellard | ? 1 : fetch_data ((info), (addr)))
|
60 | dc99065b | bellard | |
61 | dc99065b | bellard | static int |
62 | dc99065b | bellard | fetch_data (info, addr) |
63 | dc99065b | bellard | struct disassemble_info *info;
|
64 | dc99065b | bellard | bfd_byte *addr; |
65 | dc99065b | bellard | { |
66 | dc99065b | bellard | int status;
|
67 | dc99065b | bellard | struct dis_private *priv = (struct dis_private *)info->private_data; |
68 | dc99065b | bellard | bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); |
69 | dc99065b | bellard | |
70 | dc99065b | bellard | status = (*info->read_memory_func) (start, |
71 | dc99065b | bellard | priv->max_fetched, |
72 | dc99065b | bellard | addr - priv->max_fetched, |
73 | dc99065b | bellard | info); |
74 | dc99065b | bellard | if (status != 0) |
75 | dc99065b | bellard | { |
76 | dc99065b | bellard | (*info->memory_error_func) (status, start, info); |
77 | dc99065b | bellard | longjmp (priv->bailout, 1);
|
78 | dc99065b | bellard | } |
79 | dc99065b | bellard | else
|
80 | dc99065b | bellard | priv->max_fetched = addr; |
81 | dc99065b | bellard | return 1; |
82 | dc99065b | bellard | } |
83 | dc99065b | bellard | |
84 | dc99065b | bellard | #define Eb OP_E, b_mode
|
85 | dc99065b | bellard | #define indirEb OP_indirE, b_mode
|
86 | dc99065b | bellard | #define Gb OP_G, b_mode
|
87 | dc99065b | bellard | #define Ev OP_E, v_mode
|
88 | dc99065b | bellard | #define indirEv OP_indirE, v_mode
|
89 | dc99065b | bellard | #define Ew OP_E, w_mode
|
90 | dc99065b | bellard | #define Ma OP_E, v_mode
|
91 | dc99065b | bellard | #define M OP_E, 0 |
92 | dc99065b | bellard | #define Mp OP_E, 0 /* ? */ |
93 | dc99065b | bellard | #define Gv OP_G, v_mode
|
94 | dc99065b | bellard | #define Gw OP_G, w_mode
|
95 | dc99065b | bellard | #define Rw OP_rm, w_mode
|
96 | dc99065b | bellard | #define Rd OP_rm, d_mode
|
97 | dc99065b | bellard | #define Ib OP_I, b_mode
|
98 | dc99065b | bellard | #define sIb OP_sI, b_mode /* sign extened byte */ |
99 | dc99065b | bellard | #define Iv OP_I, v_mode
|
100 | dc99065b | bellard | #define Iw OP_I, w_mode
|
101 | dc99065b | bellard | #define Jb OP_J, b_mode
|
102 | dc99065b | bellard | #define Jv OP_J, v_mode
|
103 | dc99065b | bellard | #if 0
|
104 | dc99065b | bellard | #define ONE OP_ONE, 0
|
105 | dc99065b | bellard | #endif
|
106 | dc99065b | bellard | #define Cd OP_C, d_mode
|
107 | dc99065b | bellard | #define Dd OP_D, d_mode
|
108 | dc99065b | bellard | #define Td OP_T, d_mode
|
109 | dc99065b | bellard | |
110 | dc99065b | bellard | #define eAX OP_REG, eAX_reg
|
111 | dc99065b | bellard | #define eBX OP_REG, eBX_reg
|
112 | dc99065b | bellard | #define eCX OP_REG, eCX_reg
|
113 | dc99065b | bellard | #define eDX OP_REG, eDX_reg
|
114 | dc99065b | bellard | #define eSP OP_REG, eSP_reg
|
115 | dc99065b | bellard | #define eBP OP_REG, eBP_reg
|
116 | dc99065b | bellard | #define eSI OP_REG, eSI_reg
|
117 | dc99065b | bellard | #define eDI OP_REG, eDI_reg
|
118 | dc99065b | bellard | #define AL OP_REG, al_reg
|
119 | dc99065b | bellard | #define CL OP_REG, cl_reg
|
120 | dc99065b | bellard | #define DL OP_REG, dl_reg
|
121 | dc99065b | bellard | #define BL OP_REG, bl_reg
|
122 | dc99065b | bellard | #define AH OP_REG, ah_reg
|
123 | dc99065b | bellard | #define CH OP_REG, ch_reg
|
124 | dc99065b | bellard | #define DH OP_REG, dh_reg
|
125 | dc99065b | bellard | #define BH OP_REG, bh_reg
|
126 | dc99065b | bellard | #define AX OP_REG, ax_reg
|
127 | dc99065b | bellard | #define DX OP_REG, dx_reg
|
128 | dc99065b | bellard | #define indirDX OP_REG, indir_dx_reg
|
129 | dc99065b | bellard | |
130 | dc99065b | bellard | #define Sw OP_SEG, w_mode
|
131 | dc99065b | bellard | #define Ap OP_DIR, lptr
|
132 | dc99065b | bellard | #define Av OP_DIR, v_mode
|
133 | dc99065b | bellard | #define Ob OP_OFF, b_mode
|
134 | dc99065b | bellard | #define Ov OP_OFF, v_mode
|
135 | dc99065b | bellard | #define Xb OP_DSSI, b_mode
|
136 | dc99065b | bellard | #define Xv OP_DSSI, v_mode
|
137 | dc99065b | bellard | #define Yb OP_ESDI, b_mode
|
138 | dc99065b | bellard | #define Yv OP_ESDI, v_mode
|
139 | dc99065b | bellard | |
140 | dc99065b | bellard | #define es OP_REG, es_reg
|
141 | dc99065b | bellard | #define ss OP_REG, ss_reg
|
142 | dc99065b | bellard | #define cs OP_REG, cs_reg
|
143 | dc99065b | bellard | #define ds OP_REG, ds_reg
|
144 | dc99065b | bellard | #define fs OP_REG, fs_reg
|
145 | dc99065b | bellard | #define gs OP_REG, gs_reg
|
146 | dc99065b | bellard | |
147 | dc99065b | bellard | #define MX OP_MMX, 0 |
148 | dc99065b | bellard | #define EM OP_EM, v_mode
|
149 | dc99065b | bellard | #define MS OP_MS, b_mode
|
150 | dc99065b | bellard | |
151 | dc99065b | bellard | typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag)); |
152 | dc99065b | bellard | |
153 | dc99065b | bellard | static int OP_E PARAMS ((int, int, int)); |
154 | dc99065b | bellard | static int OP_G PARAMS ((int, int, int)); |
155 | dc99065b | bellard | static int OP_I PARAMS ((int, int, int)); |
156 | dc99065b | bellard | static int OP_indirE PARAMS ((int, int, int)); |
157 | dc99065b | bellard | static int OP_sI PARAMS ((int, int, int)); |
158 | dc99065b | bellard | static int OP_REG PARAMS ((int, int, int)); |
159 | dc99065b | bellard | static int OP_J PARAMS ((int, int, int)); |
160 | dc99065b | bellard | static int OP_DIR PARAMS ((int, int, int)); |
161 | dc99065b | bellard | static int OP_OFF PARAMS ((int, int, int)); |
162 | dc99065b | bellard | static int OP_ESDI PARAMS ((int, int, int)); |
163 | dc99065b | bellard | static int OP_DSSI PARAMS ((int, int, int)); |
164 | dc99065b | bellard | static int OP_SEG PARAMS ((int, int, int)); |
165 | dc99065b | bellard | static int OP_C PARAMS ((int, int, int)); |
166 | dc99065b | bellard | static int OP_D PARAMS ((int, int, int)); |
167 | dc99065b | bellard | static int OP_T PARAMS ((int, int, int)); |
168 | dc99065b | bellard | static int OP_rm PARAMS ((int, int, int)); |
169 | dc99065b | bellard | static int OP_ST PARAMS ((int, int, int)); |
170 | dc99065b | bellard | static int OP_STi PARAMS ((int, int, int)); |
171 | dc99065b | bellard | #if 0
|
172 | dc99065b | bellard | static int OP_ONE PARAMS ((int, int, int));
|
173 | dc99065b | bellard | #endif
|
174 | dc99065b | bellard | static int OP_MMX PARAMS ((int, int, int)); |
175 | dc99065b | bellard | static int OP_EM PARAMS ((int, int, int)); |
176 | dc99065b | bellard | static int OP_MS PARAMS ((int, int, int)); |
177 | dc99065b | bellard | |
178 | dc99065b | bellard | static void append_prefix PARAMS ((void)); |
179 | dc99065b | bellard | static void set_op PARAMS ((int op)); |
180 | dc99065b | bellard | static void putop PARAMS ((char *template, int aflag, int dflag)); |
181 | dc99065b | bellard | static void dofloat PARAMS ((int aflag, int dflag)); |
182 | dc99065b | bellard | static int get16 PARAMS ((void)); |
183 | dc99065b | bellard | static int get32 PARAMS ((void)); |
184 | dc99065b | bellard | static void ckprefix PARAMS ((void)); |
185 | dc99065b | bellard | |
186 | dc99065b | bellard | #define b_mode 1 |
187 | dc99065b | bellard | #define v_mode 2 |
188 | dc99065b | bellard | #define w_mode 3 |
189 | dc99065b | bellard | #define d_mode 4 |
190 | dc99065b | bellard | |
191 | dc99065b | bellard | #define es_reg 100 |
192 | dc99065b | bellard | #define cs_reg 101 |
193 | dc99065b | bellard | #define ss_reg 102 |
194 | dc99065b | bellard | #define ds_reg 103 |
195 | dc99065b | bellard | #define fs_reg 104 |
196 | dc99065b | bellard | #define gs_reg 105 |
197 | dc99065b | bellard | #define eAX_reg 107 |
198 | dc99065b | bellard | #define eCX_reg 108 |
199 | dc99065b | bellard | #define eDX_reg 109 |
200 | dc99065b | bellard | #define eBX_reg 110 |
201 | dc99065b | bellard | #define eSP_reg 111 |
202 | dc99065b | bellard | #define eBP_reg 112 |
203 | dc99065b | bellard | #define eSI_reg 113 |
204 | dc99065b | bellard | #define eDI_reg 114 |
205 | dc99065b | bellard | |
206 | dc99065b | bellard | #define lptr 115 |
207 | dc99065b | bellard | |
208 | dc99065b | bellard | #define al_reg 116 |
209 | dc99065b | bellard | #define cl_reg 117 |
210 | dc99065b | bellard | #define dl_reg 118 |
211 | dc99065b | bellard | #define bl_reg 119 |
212 | dc99065b | bellard | #define ah_reg 120 |
213 | dc99065b | bellard | #define ch_reg 121 |
214 | dc99065b | bellard | #define dh_reg 122 |
215 | dc99065b | bellard | #define bh_reg 123 |
216 | dc99065b | bellard | |
217 | dc99065b | bellard | #define ax_reg 124 |
218 | dc99065b | bellard | #define cx_reg 125 |
219 | dc99065b | bellard | #define dx_reg 126 |
220 | dc99065b | bellard | #define bx_reg 127 |
221 | dc99065b | bellard | #define sp_reg 128 |
222 | dc99065b | bellard | #define bp_reg 129 |
223 | dc99065b | bellard | #define si_reg 130 |
224 | dc99065b | bellard | #define di_reg 131 |
225 | dc99065b | bellard | |
226 | dc99065b | bellard | #define indir_dx_reg 150 |
227 | dc99065b | bellard | |
228 | dc99065b | bellard | #define GRP1b NULL, NULL, 0 |
229 | dc99065b | bellard | #define GRP1S NULL, NULL, 1 |
230 | dc99065b | bellard | #define GRP1Ss NULL, NULL, 2 |
231 | dc99065b | bellard | #define GRP2b NULL, NULL, 3 |
232 | dc99065b | bellard | #define GRP2S NULL, NULL, 4 |
233 | dc99065b | bellard | #define GRP2b_one NULL, NULL, 5 |
234 | dc99065b | bellard | #define GRP2S_one NULL, NULL, 6 |
235 | dc99065b | bellard | #define GRP2b_cl NULL, NULL, 7 |
236 | dc99065b | bellard | #define GRP2S_cl NULL, NULL, 8 |
237 | dc99065b | bellard | #define GRP3b NULL, NULL, 9 |
238 | dc99065b | bellard | #define GRP3S NULL, NULL, 10 |
239 | dc99065b | bellard | #define GRP4 NULL, NULL, 11 |
240 | dc99065b | bellard | #define GRP5 NULL, NULL, 12 |
241 | dc99065b | bellard | #define GRP6 NULL, NULL, 13 |
242 | dc99065b | bellard | #define GRP7 NULL, NULL, 14 |
243 | dc99065b | bellard | #define GRP8 NULL, NULL, 15 |
244 | dc99065b | bellard | #define GRP9 NULL, NULL, 16 |
245 | dc99065b | bellard | #define GRP10 NULL, NULL, 17 |
246 | dc99065b | bellard | #define GRP11 NULL, NULL, 18 |
247 | dc99065b | bellard | #define GRP12 NULL, NULL, 19 |
248 | dc99065b | bellard | |
249 | dc99065b | bellard | #define FLOATCODE 50 |
250 | dc99065b | bellard | #define FLOAT NULL, NULL, FLOATCODE |
251 | dc99065b | bellard | |
252 | dc99065b | bellard | struct dis386 {
|
253 | dc99065b | bellard | char *name;
|
254 | dc99065b | bellard | op_rtn op1; |
255 | dc99065b | bellard | int bytemode1;
|
256 | dc99065b | bellard | op_rtn op2; |
257 | dc99065b | bellard | int bytemode2;
|
258 | dc99065b | bellard | op_rtn op3; |
259 | dc99065b | bellard | int bytemode3;
|
260 | dc99065b | bellard | }; |
261 | dc99065b | bellard | |
262 | dc99065b | bellard | static struct dis386 dis386[] = { |
263 | dc99065b | bellard | /* 00 */
|
264 | dc99065b | bellard | { "addb", Eb, Gb },
|
265 | dc99065b | bellard | { "addS", Ev, Gv },
|
266 | dc99065b | bellard | { "addb", Gb, Eb },
|
267 | dc99065b | bellard | { "addS", Gv, Ev },
|
268 | dc99065b | bellard | { "addb", AL, Ib },
|
269 | dc99065b | bellard | { "addS", eAX, Iv },
|
270 | dc99065b | bellard | { "pushS", es },
|
271 | dc99065b | bellard | { "popS", es },
|
272 | dc99065b | bellard | /* 08 */
|
273 | dc99065b | bellard | { "orb", Eb, Gb },
|
274 | dc99065b | bellard | { "orS", Ev, Gv },
|
275 | dc99065b | bellard | { "orb", Gb, Eb },
|
276 | dc99065b | bellard | { "orS", Gv, Ev },
|
277 | dc99065b | bellard | { "orb", AL, Ib },
|
278 | dc99065b | bellard | { "orS", eAX, Iv },
|
279 | dc99065b | bellard | { "pushS", cs },
|
280 | dc99065b | bellard | { "(bad)" }, /* 0x0f extended opcode escape */ |
281 | dc99065b | bellard | /* 10 */
|
282 | dc99065b | bellard | { "adcb", Eb, Gb },
|
283 | dc99065b | bellard | { "adcS", Ev, Gv },
|
284 | dc99065b | bellard | { "adcb", Gb, Eb },
|
285 | dc99065b | bellard | { "adcS", Gv, Ev },
|
286 | dc99065b | bellard | { "adcb", AL, Ib },
|
287 | dc99065b | bellard | { "adcS", eAX, Iv },
|
288 | dc99065b | bellard | { "pushS", ss },
|
289 | dc99065b | bellard | { "popS", ss },
|
290 | dc99065b | bellard | /* 18 */
|
291 | dc99065b | bellard | { "sbbb", Eb, Gb },
|
292 | dc99065b | bellard | { "sbbS", Ev, Gv },
|
293 | dc99065b | bellard | { "sbbb", Gb, Eb },
|
294 | dc99065b | bellard | { "sbbS", Gv, Ev },
|
295 | dc99065b | bellard | { "sbbb", AL, Ib },
|
296 | dc99065b | bellard | { "sbbS", eAX, Iv },
|
297 | dc99065b | bellard | { "pushS", ds },
|
298 | dc99065b | bellard | { "popS", ds },
|
299 | dc99065b | bellard | /* 20 */
|
300 | dc99065b | bellard | { "andb", Eb, Gb },
|
301 | dc99065b | bellard | { "andS", Ev, Gv },
|
302 | dc99065b | bellard | { "andb", Gb, Eb },
|
303 | dc99065b | bellard | { "andS", Gv, Ev },
|
304 | dc99065b | bellard | { "andb", AL, Ib },
|
305 | dc99065b | bellard | { "andS", eAX, Iv },
|
306 | dc99065b | bellard | { "(bad)" }, /* SEG ES prefix */ |
307 | dc99065b | bellard | { "daa" },
|
308 | dc99065b | bellard | /* 28 */
|
309 | dc99065b | bellard | { "subb", Eb, Gb },
|
310 | dc99065b | bellard | { "subS", Ev, Gv },
|
311 | dc99065b | bellard | { "subb", Gb, Eb },
|
312 | dc99065b | bellard | { "subS", Gv, Ev },
|
313 | dc99065b | bellard | { "subb", AL, Ib },
|
314 | dc99065b | bellard | { "subS", eAX, Iv },
|
315 | dc99065b | bellard | { "(bad)" }, /* SEG CS prefix */ |
316 | dc99065b | bellard | { "das" },
|
317 | dc99065b | bellard | /* 30 */
|
318 | dc99065b | bellard | { "xorb", Eb, Gb },
|
319 | dc99065b | bellard | { "xorS", Ev, Gv },
|
320 | dc99065b | bellard | { "xorb", Gb, Eb },
|
321 | dc99065b | bellard | { "xorS", Gv, Ev },
|
322 | dc99065b | bellard | { "xorb", AL, Ib },
|
323 | dc99065b | bellard | { "xorS", eAX, Iv },
|
324 | dc99065b | bellard | { "(bad)" }, /* SEG SS prefix */ |
325 | dc99065b | bellard | { "aaa" },
|
326 | dc99065b | bellard | /* 38 */
|
327 | dc99065b | bellard | { "cmpb", Eb, Gb },
|
328 | dc99065b | bellard | { "cmpS", Ev, Gv },
|
329 | dc99065b | bellard | { "cmpb", Gb, Eb },
|
330 | dc99065b | bellard | { "cmpS", Gv, Ev },
|
331 | dc99065b | bellard | { "cmpb", AL, Ib },
|
332 | dc99065b | bellard | { "cmpS", eAX, Iv },
|
333 | dc99065b | bellard | { "(bad)" }, /* SEG DS prefix */ |
334 | dc99065b | bellard | { "aas" },
|
335 | dc99065b | bellard | /* 40 */
|
336 | dc99065b | bellard | { "incS", eAX },
|
337 | dc99065b | bellard | { "incS", eCX },
|
338 | dc99065b | bellard | { "incS", eDX },
|
339 | dc99065b | bellard | { "incS", eBX },
|
340 | dc99065b | bellard | { "incS", eSP },
|
341 | dc99065b | bellard | { "incS", eBP },
|
342 | dc99065b | bellard | { "incS", eSI },
|
343 | dc99065b | bellard | { "incS", eDI },
|
344 | dc99065b | bellard | /* 48 */
|
345 | dc99065b | bellard | { "decS", eAX },
|
346 | dc99065b | bellard | { "decS", eCX },
|
347 | dc99065b | bellard | { "decS", eDX },
|
348 | dc99065b | bellard | { "decS", eBX },
|
349 | dc99065b | bellard | { "decS", eSP },
|
350 | dc99065b | bellard | { "decS", eBP },
|
351 | dc99065b | bellard | { "decS", eSI },
|
352 | dc99065b | bellard | { "decS", eDI },
|
353 | dc99065b | bellard | /* 50 */
|
354 | dc99065b | bellard | { "pushS", eAX },
|
355 | dc99065b | bellard | { "pushS", eCX },
|
356 | dc99065b | bellard | { "pushS", eDX },
|
357 | dc99065b | bellard | { "pushS", eBX },
|
358 | dc99065b | bellard | { "pushS", eSP },
|
359 | dc99065b | bellard | { "pushS", eBP },
|
360 | dc99065b | bellard | { "pushS", eSI },
|
361 | dc99065b | bellard | { "pushS", eDI },
|
362 | dc99065b | bellard | /* 58 */
|
363 | dc99065b | bellard | { "popS", eAX },
|
364 | dc99065b | bellard | { "popS", eCX },
|
365 | dc99065b | bellard | { "popS", eDX },
|
366 | dc99065b | bellard | { "popS", eBX },
|
367 | dc99065b | bellard | { "popS", eSP },
|
368 | dc99065b | bellard | { "popS", eBP },
|
369 | dc99065b | bellard | { "popS", eSI },
|
370 | dc99065b | bellard | { "popS", eDI },
|
371 | dc99065b | bellard | /* 60 */
|
372 | dc99065b | bellard | { "pusha" },
|
373 | dc99065b | bellard | { "popa" },
|
374 | dc99065b | bellard | { "boundS", Gv, Ma },
|
375 | dc99065b | bellard | { "arpl", Ew, Gw },
|
376 | dc99065b | bellard | { "(bad)" }, /* seg fs */ |
377 | dc99065b | bellard | { "(bad)" }, /* seg gs */ |
378 | dc99065b | bellard | { "(bad)" }, /* op size prefix */ |
379 | dc99065b | bellard | { "(bad)" }, /* adr size prefix */ |
380 | dc99065b | bellard | /* 68 */
|
381 | dc99065b | bellard | { "pushS", Iv }, /* 386 book wrong */ |
382 | dc99065b | bellard | { "imulS", Gv, Ev, Iv },
|
383 | dc99065b | bellard | { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */ |
384 | dc99065b | bellard | { "imulS", Gv, Ev, Ib },
|
385 | dc99065b | bellard | { "insb", Yb, indirDX },
|
386 | dc99065b | bellard | { "insS", Yv, indirDX },
|
387 | dc99065b | bellard | { "outsb", indirDX, Xb },
|
388 | dc99065b | bellard | { "outsS", indirDX, Xv },
|
389 | dc99065b | bellard | /* 70 */
|
390 | dc99065b | bellard | { "jo", Jb },
|
391 | dc99065b | bellard | { "jno", Jb },
|
392 | dc99065b | bellard | { "jb", Jb },
|
393 | dc99065b | bellard | { "jae", Jb },
|
394 | dc99065b | bellard | { "je", Jb },
|
395 | dc99065b | bellard | { "jne", Jb },
|
396 | dc99065b | bellard | { "jbe", Jb },
|
397 | dc99065b | bellard | { "ja", Jb },
|
398 | dc99065b | bellard | /* 78 */
|
399 | dc99065b | bellard | { "js", Jb },
|
400 | dc99065b | bellard | { "jns", Jb },
|
401 | dc99065b | bellard | { "jp", Jb },
|
402 | dc99065b | bellard | { "jnp", Jb },
|
403 | dc99065b | bellard | { "jl", Jb },
|
404 | dc99065b | bellard | { "jnl", Jb },
|
405 | dc99065b | bellard | { "jle", Jb },
|
406 | dc99065b | bellard | { "jg", Jb },
|
407 | dc99065b | bellard | /* 80 */
|
408 | dc99065b | bellard | { GRP1b }, |
409 | dc99065b | bellard | { GRP1S }, |
410 | dc99065b | bellard | { "(bad)" },
|
411 | dc99065b | bellard | { GRP1Ss }, |
412 | dc99065b | bellard | { "testb", Eb, Gb },
|
413 | dc99065b | bellard | { "testS", Ev, Gv },
|
414 | dc99065b | bellard | { "xchgb", Eb, Gb },
|
415 | dc99065b | bellard | { "xchgS", Ev, Gv },
|
416 | dc99065b | bellard | /* 88 */
|
417 | dc99065b | bellard | { "movb", Eb, Gb },
|
418 | dc99065b | bellard | { "movS", Ev, Gv },
|
419 | dc99065b | bellard | { "movb", Gb, Eb },
|
420 | dc99065b | bellard | { "movS", Gv, Ev },
|
421 | dc99065b | bellard | { "movS", Ev, Sw },
|
422 | dc99065b | bellard | { "leaS", Gv, M },
|
423 | dc99065b | bellard | { "movS", Sw, Ev },
|
424 | dc99065b | bellard | { "popS", Ev },
|
425 | dc99065b | bellard | /* 90 */
|
426 | dc99065b | bellard | { "nop" },
|
427 | dc99065b | bellard | { "xchgS", eCX, eAX },
|
428 | dc99065b | bellard | { "xchgS", eDX, eAX },
|
429 | dc99065b | bellard | { "xchgS", eBX, eAX },
|
430 | dc99065b | bellard | { "xchgS", eSP, eAX },
|
431 | dc99065b | bellard | { "xchgS", eBP, eAX },
|
432 | dc99065b | bellard | { "xchgS", eSI, eAX },
|
433 | dc99065b | bellard | { "xchgS", eDI, eAX },
|
434 | dc99065b | bellard | /* 98 */
|
435 | dc99065b | bellard | { "cWtS" },
|
436 | dc99065b | bellard | { "cStd" },
|
437 | dc99065b | bellard | { "lcall", Ap },
|
438 | dc99065b | bellard | { "(bad)" }, /* fwait */ |
439 | dc99065b | bellard | { "pushf" },
|
440 | dc99065b | bellard | { "popf" },
|
441 | dc99065b | bellard | { "sahf" },
|
442 | dc99065b | bellard | { "lahf" },
|
443 | dc99065b | bellard | /* a0 */
|
444 | dc99065b | bellard | { "movb", AL, Ob },
|
445 | dc99065b | bellard | { "movS", eAX, Ov },
|
446 | dc99065b | bellard | { "movb", Ob, AL },
|
447 | dc99065b | bellard | { "movS", Ov, eAX },
|
448 | dc99065b | bellard | { "movsb", Yb, Xb },
|
449 | dc99065b | bellard | { "movsS", Yv, Xv },
|
450 | dc99065b | bellard | { "cmpsb", Yb, Xb },
|
451 | dc99065b | bellard | { "cmpsS", Yv, Xv },
|
452 | dc99065b | bellard | /* a8 */
|
453 | dc99065b | bellard | { "testb", AL, Ib },
|
454 | dc99065b | bellard | { "testS", eAX, Iv },
|
455 | dc99065b | bellard | { "stosb", Yb, AL },
|
456 | dc99065b | bellard | { "stosS", Yv, eAX },
|
457 | dc99065b | bellard | { "lodsb", AL, Xb },
|
458 | dc99065b | bellard | { "lodsS", eAX, Xv },
|
459 | dc99065b | bellard | { "scasb", AL, Yb },
|
460 | dc99065b | bellard | { "scasS", eAX, Yv },
|
461 | dc99065b | bellard | /* b0 */
|
462 | dc99065b | bellard | { "movb", AL, Ib },
|
463 | dc99065b | bellard | { "movb", CL, Ib },
|
464 | dc99065b | bellard | { "movb", DL, Ib },
|
465 | dc99065b | bellard | { "movb", BL, Ib },
|
466 | dc99065b | bellard | { "movb", AH, Ib },
|
467 | dc99065b | bellard | { "movb", CH, Ib },
|
468 | dc99065b | bellard | { "movb", DH, Ib },
|
469 | dc99065b | bellard | { "movb", BH, Ib },
|
470 | dc99065b | bellard | /* b8 */
|
471 | dc99065b | bellard | { "movS", eAX, Iv },
|
472 | dc99065b | bellard | { "movS", eCX, Iv },
|
473 | dc99065b | bellard | { "movS", eDX, Iv },
|
474 | dc99065b | bellard | { "movS", eBX, Iv },
|
475 | dc99065b | bellard | { "movS", eSP, Iv },
|
476 | dc99065b | bellard | { "movS", eBP, Iv },
|
477 | dc99065b | bellard | { "movS", eSI, Iv },
|
478 | dc99065b | bellard | { "movS", eDI, Iv },
|
479 | dc99065b | bellard | /* c0 */
|
480 | dc99065b | bellard | { GRP2b }, |
481 | dc99065b | bellard | { GRP2S }, |
482 | dc99065b | bellard | { "ret", Iw },
|
483 | dc99065b | bellard | { "ret" },
|
484 | dc99065b | bellard | { "lesS", Gv, Mp },
|
485 | dc99065b | bellard | { "ldsS", Gv, Mp },
|
486 | dc99065b | bellard | { "movb", Eb, Ib },
|
487 | dc99065b | bellard | { "movS", Ev, Iv },
|
488 | dc99065b | bellard | /* c8 */
|
489 | dc99065b | bellard | { "enter", Iw, Ib },
|
490 | dc99065b | bellard | { "leave" },
|
491 | dc99065b | bellard | { "lret", Iw },
|
492 | dc99065b | bellard | { "lret" },
|
493 | dc99065b | bellard | { "int3" },
|
494 | dc99065b | bellard | { "int", Ib },
|
495 | dc99065b | bellard | { "into" },
|
496 | dc99065b | bellard | { "iret" },
|
497 | dc99065b | bellard | /* d0 */
|
498 | dc99065b | bellard | { GRP2b_one }, |
499 | dc99065b | bellard | { GRP2S_one }, |
500 | dc99065b | bellard | { GRP2b_cl }, |
501 | dc99065b | bellard | { GRP2S_cl }, |
502 | dc99065b | bellard | { "aam", Ib },
|
503 | dc99065b | bellard | { "aad", Ib },
|
504 | dc99065b | bellard | { "(bad)" },
|
505 | dc99065b | bellard | { "xlat" },
|
506 | dc99065b | bellard | /* d8 */
|
507 | dc99065b | bellard | { FLOAT }, |
508 | dc99065b | bellard | { FLOAT }, |
509 | dc99065b | bellard | { FLOAT }, |
510 | dc99065b | bellard | { FLOAT }, |
511 | dc99065b | bellard | { FLOAT }, |
512 | dc99065b | bellard | { FLOAT }, |
513 | dc99065b | bellard | { FLOAT }, |
514 | dc99065b | bellard | { FLOAT }, |
515 | dc99065b | bellard | /* e0 */
|
516 | dc99065b | bellard | { "loopne", Jb },
|
517 | dc99065b | bellard | { "loope", Jb },
|
518 | dc99065b | bellard | { "loop", Jb },
|
519 | dc99065b | bellard | { "jCcxz", Jb },
|
520 | dc99065b | bellard | { "inb", AL, Ib },
|
521 | dc99065b | bellard | { "inS", eAX, Ib },
|
522 | dc99065b | bellard | { "outb", Ib, AL },
|
523 | dc99065b | bellard | { "outS", Ib, eAX },
|
524 | dc99065b | bellard | /* e8 */
|
525 | dc99065b | bellard | { "call", Av },
|
526 | dc99065b | bellard | { "jmp", Jv },
|
527 | dc99065b | bellard | { "ljmp", Ap },
|
528 | dc99065b | bellard | { "jmp", Jb },
|
529 | dc99065b | bellard | { "inb", AL, indirDX },
|
530 | dc99065b | bellard | { "inS", eAX, indirDX },
|
531 | dc99065b | bellard | { "outb", indirDX, AL },
|
532 | dc99065b | bellard | { "outS", indirDX, eAX },
|
533 | dc99065b | bellard | /* f0 */
|
534 | dc99065b | bellard | { "(bad)" }, /* lock prefix */ |
535 | dc99065b | bellard | { "(bad)" },
|
536 | dc99065b | bellard | { "(bad)" }, /* repne */ |
537 | dc99065b | bellard | { "(bad)" }, /* repz */ |
538 | dc99065b | bellard | { "hlt" },
|
539 | dc99065b | bellard | { "cmc" },
|
540 | dc99065b | bellard | { GRP3b }, |
541 | dc99065b | bellard | { GRP3S }, |
542 | dc99065b | bellard | /* f8 */
|
543 | dc99065b | bellard | { "clc" },
|
544 | dc99065b | bellard | { "stc" },
|
545 | dc99065b | bellard | { "cli" },
|
546 | dc99065b | bellard | { "sti" },
|
547 | dc99065b | bellard | { "cld" },
|
548 | dc99065b | bellard | { "std" },
|
549 | dc99065b | bellard | { GRP4 }, |
550 | dc99065b | bellard | { GRP5 }, |
551 | dc99065b | bellard | }; |
552 | dc99065b | bellard | |
553 | dc99065b | bellard | static struct dis386 dis386_twobyte[] = { |
554 | dc99065b | bellard | /* 00 */
|
555 | dc99065b | bellard | { GRP6 }, |
556 | dc99065b | bellard | { GRP7 }, |
557 | dc99065b | bellard | { "larS", Gv, Ew },
|
558 | dc99065b | bellard | { "lslS", Gv, Ew },
|
559 | dc99065b | bellard | { "(bad)" },
|
560 | dc99065b | bellard | { "(bad)" },
|
561 | dc99065b | bellard | { "clts" },
|
562 | dc99065b | bellard | { "(bad)" },
|
563 | dc99065b | bellard | /* 08 */
|
564 | dc99065b | bellard | { "invd" },
|
565 | dc99065b | bellard | { "wbinvd" },
|
566 | dc99065b | bellard | { "(bad)" }, { "ud2a" }, |
567 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
568 | dc99065b | bellard | /* 10 */
|
569 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
570 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
571 | dc99065b | bellard | /* 18 */
|
572 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
573 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
574 | dc99065b | bellard | /* 20 */
|
575 | dc99065b | bellard | /* these are all backward in appendix A of the intel book */
|
576 | dc99065b | bellard | { "movl", Rd, Cd },
|
577 | dc99065b | bellard | { "movl", Rd, Dd },
|
578 | dc99065b | bellard | { "movl", Cd, Rd },
|
579 | dc99065b | bellard | { "movl", Dd, Rd },
|
580 | dc99065b | bellard | { "movl", Rd, Td },
|
581 | dc99065b | bellard | { "(bad)" },
|
582 | dc99065b | bellard | { "movl", Td, Rd },
|
583 | dc99065b | bellard | { "(bad)" },
|
584 | dc99065b | bellard | /* 28 */
|
585 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
586 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
587 | dc99065b | bellard | /* 30 */
|
588 | dc99065b | bellard | { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, |
589 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
590 | dc99065b | bellard | /* 38 */
|
591 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
592 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
593 | dc99065b | bellard | /* 40 */
|
594 | dc99065b | bellard | { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev }, |
595 | dc99065b | bellard | { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev }, |
596 | dc99065b | bellard | /* 48 */
|
597 | dc99065b | bellard | { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev }, |
598 | dc99065b | bellard | { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev }, |
599 | dc99065b | bellard | /* 50 */
|
600 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
601 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
602 | dc99065b | bellard | /* 58 */
|
603 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
604 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
605 | dc99065b | bellard | /* 60 */
|
606 | dc99065b | bellard | { "punpcklbw", MX, EM },
|
607 | dc99065b | bellard | { "punpcklwd", MX, EM },
|
608 | dc99065b | bellard | { "punpckldq", MX, EM },
|
609 | dc99065b | bellard | { "packsswb", MX, EM },
|
610 | dc99065b | bellard | { "pcmpgtb", MX, EM },
|
611 | dc99065b | bellard | { "pcmpgtw", MX, EM },
|
612 | dc99065b | bellard | { "pcmpgtd", MX, EM },
|
613 | dc99065b | bellard | { "packuswb", MX, EM },
|
614 | dc99065b | bellard | /* 68 */
|
615 | dc99065b | bellard | { "punpckhbw", MX, EM },
|
616 | dc99065b | bellard | { "punpckhwd", MX, EM },
|
617 | dc99065b | bellard | { "punpckhdq", MX, EM },
|
618 | dc99065b | bellard | { "packssdw", MX, EM },
|
619 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, |
620 | dc99065b | bellard | { "movd", MX, Ev },
|
621 | dc99065b | bellard | { "movq", MX, EM },
|
622 | dc99065b | bellard | /* 70 */
|
623 | dc99065b | bellard | { "(bad)" },
|
624 | dc99065b | bellard | { GRP10 }, |
625 | dc99065b | bellard | { GRP11 }, |
626 | dc99065b | bellard | { GRP12 }, |
627 | dc99065b | bellard | { "pcmpeqb", MX, EM },
|
628 | dc99065b | bellard | { "pcmpeqw", MX, EM },
|
629 | dc99065b | bellard | { "pcmpeqd", MX, EM },
|
630 | dc99065b | bellard | { "emms" },
|
631 | dc99065b | bellard | /* 78 */
|
632 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, |
633 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, |
634 | dc99065b | bellard | { "movd", Ev, MX },
|
635 | dc99065b | bellard | { "movq", EM, MX },
|
636 | dc99065b | bellard | /* 80 */
|
637 | dc99065b | bellard | { "jo", Jv },
|
638 | dc99065b | bellard | { "jno", Jv },
|
639 | dc99065b | bellard | { "jb", Jv },
|
640 | dc99065b | bellard | { "jae", Jv },
|
641 | dc99065b | bellard | { "je", Jv },
|
642 | dc99065b | bellard | { "jne", Jv },
|
643 | dc99065b | bellard | { "jbe", Jv },
|
644 | dc99065b | bellard | { "ja", Jv },
|
645 | dc99065b | bellard | /* 88 */
|
646 | dc99065b | bellard | { "js", Jv },
|
647 | dc99065b | bellard | { "jns", Jv },
|
648 | dc99065b | bellard | { "jp", Jv },
|
649 | dc99065b | bellard | { "jnp", Jv },
|
650 | dc99065b | bellard | { "jl", Jv },
|
651 | dc99065b | bellard | { "jge", Jv },
|
652 | dc99065b | bellard | { "jle", Jv },
|
653 | dc99065b | bellard | { "jg", Jv },
|
654 | dc99065b | bellard | /* 90 */
|
655 | dc99065b | bellard | { "seto", Eb },
|
656 | dc99065b | bellard | { "setno", Eb },
|
657 | dc99065b | bellard | { "setb", Eb },
|
658 | dc99065b | bellard | { "setae", Eb },
|
659 | dc99065b | bellard | { "sete", Eb },
|
660 | dc99065b | bellard | { "setne", Eb },
|
661 | dc99065b | bellard | { "setbe", Eb },
|
662 | dc99065b | bellard | { "seta", Eb },
|
663 | dc99065b | bellard | /* 98 */
|
664 | dc99065b | bellard | { "sets", Eb },
|
665 | dc99065b | bellard | { "setns", Eb },
|
666 | dc99065b | bellard | { "setp", Eb },
|
667 | dc99065b | bellard | { "setnp", Eb },
|
668 | dc99065b | bellard | { "setl", Eb },
|
669 | dc99065b | bellard | { "setge", Eb },
|
670 | dc99065b | bellard | { "setle", Eb },
|
671 | dc99065b | bellard | { "setg", Eb },
|
672 | dc99065b | bellard | /* a0 */
|
673 | dc99065b | bellard | { "pushS", fs },
|
674 | dc99065b | bellard | { "popS", fs },
|
675 | dc99065b | bellard | { "cpuid" },
|
676 | dc99065b | bellard | { "btS", Ev, Gv },
|
677 | dc99065b | bellard | { "shldS", Ev, Gv, Ib },
|
678 | dc99065b | bellard | { "shldS", Ev, Gv, CL },
|
679 | dc99065b | bellard | { "(bad)" },
|
680 | dc99065b | bellard | { "(bad)" },
|
681 | dc99065b | bellard | /* a8 */
|
682 | dc99065b | bellard | { "pushS", gs },
|
683 | dc99065b | bellard | { "popS", gs },
|
684 | dc99065b | bellard | { "rsm" },
|
685 | dc99065b | bellard | { "btsS", Ev, Gv },
|
686 | dc99065b | bellard | { "shrdS", Ev, Gv, Ib },
|
687 | dc99065b | bellard | { "shrdS", Ev, Gv, CL },
|
688 | dc99065b | bellard | { "(bad)" },
|
689 | dc99065b | bellard | { "imulS", Gv, Ev },
|
690 | dc99065b | bellard | /* b0 */
|
691 | dc99065b | bellard | { "cmpxchgb", Eb, Gb },
|
692 | dc99065b | bellard | { "cmpxchgS", Ev, Gv },
|
693 | dc99065b | bellard | { "lssS", Gv, Mp }, /* 386 lists only Mp */ |
694 | dc99065b | bellard | { "btrS", Ev, Gv },
|
695 | dc99065b | bellard | { "lfsS", Gv, Mp }, /* 386 lists only Mp */ |
696 | dc99065b | bellard | { "lgsS", Gv, Mp }, /* 386 lists only Mp */ |
697 | dc99065b | bellard | { "movzbS", Gv, Eb },
|
698 | dc99065b | bellard | { "movzwS", Gv, Ew },
|
699 | dc99065b | bellard | /* b8 */
|
700 | dc99065b | bellard | { "ud2b" },
|
701 | dc99065b | bellard | { "(bad)" },
|
702 | dc99065b | bellard | { GRP8 }, |
703 | dc99065b | bellard | { "btcS", Ev, Gv },
|
704 | dc99065b | bellard | { "bsfS", Gv, Ev },
|
705 | dc99065b | bellard | { "bsrS", Gv, Ev },
|
706 | dc99065b | bellard | { "movsbS", Gv, Eb },
|
707 | dc99065b | bellard | { "movswS", Gv, Ew },
|
708 | dc99065b | bellard | /* c0 */
|
709 | dc99065b | bellard | { "xaddb", Eb, Gb },
|
710 | dc99065b | bellard | { "xaddS", Ev, Gv },
|
711 | dc99065b | bellard | { "(bad)" },
|
712 | dc99065b | bellard | { "(bad)" },
|
713 | dc99065b | bellard | { "(bad)" },
|
714 | dc99065b | bellard | { "(bad)" },
|
715 | dc99065b | bellard | { "(bad)" },
|
716 | dc99065b | bellard | { GRP9 }, |
717 | dc99065b | bellard | /* c8 */
|
718 | dc99065b | bellard | { "bswap", eAX },
|
719 | dc99065b | bellard | { "bswap", eCX },
|
720 | dc99065b | bellard | { "bswap", eDX },
|
721 | dc99065b | bellard | { "bswap", eBX },
|
722 | dc99065b | bellard | { "bswap", eSP },
|
723 | dc99065b | bellard | { "bswap", eBP },
|
724 | dc99065b | bellard | { "bswap", eSI },
|
725 | dc99065b | bellard | { "bswap", eDI },
|
726 | dc99065b | bellard | /* d0 */
|
727 | dc99065b | bellard | { "(bad)" },
|
728 | dc99065b | bellard | { "psrlw", MX, EM },
|
729 | dc99065b | bellard | { "psrld", MX, EM },
|
730 | dc99065b | bellard | { "psrlq", MX, EM },
|
731 | dc99065b | bellard | { "(bad)" },
|
732 | dc99065b | bellard | { "pmullw", MX, EM },
|
733 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, |
734 | dc99065b | bellard | /* d8 */
|
735 | dc99065b | bellard | { "psubusb", MX, EM },
|
736 | dc99065b | bellard | { "psubusw", MX, EM },
|
737 | dc99065b | bellard | { "(bad)" },
|
738 | dc99065b | bellard | { "pand", MX, EM },
|
739 | dc99065b | bellard | { "paddusb", MX, EM },
|
740 | dc99065b | bellard | { "paddusw", MX, EM },
|
741 | dc99065b | bellard | { "(bad)" },
|
742 | dc99065b | bellard | { "pandn", MX, EM },
|
743 | dc99065b | bellard | /* e0 */
|
744 | dc99065b | bellard | { "(bad)" },
|
745 | dc99065b | bellard | { "psraw", MX, EM },
|
746 | dc99065b | bellard | { "psrad", MX, EM },
|
747 | dc99065b | bellard | { "(bad)" },
|
748 | dc99065b | bellard | { "(bad)" },
|
749 | dc99065b | bellard | { "pmulhw", MX, EM },
|
750 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, |
751 | dc99065b | bellard | /* e8 */
|
752 | dc99065b | bellard | { "psubsb", MX, EM },
|
753 | dc99065b | bellard | { "psubsw", MX, EM },
|
754 | dc99065b | bellard | { "(bad)" },
|
755 | dc99065b | bellard | { "por", MX, EM },
|
756 | dc99065b | bellard | { "paddsb", MX, EM },
|
757 | dc99065b | bellard | { "paddsw", MX, EM },
|
758 | dc99065b | bellard | { "(bad)" },
|
759 | dc99065b | bellard | { "pxor", MX, EM },
|
760 | dc99065b | bellard | /* f0 */
|
761 | dc99065b | bellard | { "(bad)" },
|
762 | dc99065b | bellard | { "psllw", MX, EM },
|
763 | dc99065b | bellard | { "pslld", MX, EM },
|
764 | dc99065b | bellard | { "psllq", MX, EM },
|
765 | dc99065b | bellard | { "(bad)" },
|
766 | dc99065b | bellard | { "pmaddwd", MX, EM },
|
767 | dc99065b | bellard | { "(bad)" }, { "(bad)" }, |
768 | dc99065b | bellard | /* f8 */
|
769 | dc99065b | bellard | { "psubb", MX, EM },
|
770 | dc99065b | bellard | { "psubw", MX, EM },
|
771 | dc99065b | bellard | { "psubd", MX, EM },
|
772 | dc99065b | bellard | { "(bad)" },
|
773 | dc99065b | bellard | { "paddb", MX, EM },
|
774 | dc99065b | bellard | { "paddw", MX, EM },
|
775 | dc99065b | bellard | { "paddd", MX, EM },
|
776 | dc99065b | bellard | { "(bad)" }
|
777 | dc99065b | bellard | }; |
778 | dc99065b | bellard | |
779 | dc99065b | bellard | static const unsigned char onebyte_has_modrm[256] = { |
780 | dc99065b | bellard | 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, |
781 | dc99065b | bellard | 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, |
782 | dc99065b | bellard | 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, |
783 | dc99065b | bellard | 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, |
784 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
785 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
786 | dc99065b | bellard | 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, |
787 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
788 | dc99065b | bellard | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
789 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
790 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
791 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
792 | dc99065b | bellard | 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, |
793 | dc99065b | bellard | 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, |
794 | dc99065b | bellard | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
795 | dc99065b | bellard | 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 |
796 | dc99065b | bellard | }; |
797 | dc99065b | bellard | |
798 | dc99065b | bellard | static const unsigned char twobyte_has_modrm[256] = { |
799 | dc99065b | bellard | /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ |
800 | dc99065b | bellard | /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */ |
801 | dc99065b | bellard | /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */ |
802 | dc99065b | bellard | /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ |
803 | dc99065b | bellard | /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ |
804 | dc99065b | bellard | /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */ |
805 | dc99065b | bellard | /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */ |
806 | dc99065b | bellard | /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */ |
807 | dc99065b | bellard | /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ |
808 | dc99065b | bellard | /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ |
809 | dc99065b | bellard | /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ |
810 | dc99065b | bellard | /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ |
811 | dc99065b | bellard | /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ |
812 | dc99065b | bellard | /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */ |
813 | dc99065b | bellard | /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */ |
814 | dc99065b | bellard | /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */ |
815 | dc99065b | bellard | }; |
816 | dc99065b | bellard | |
817 | dc99065b | bellard | static char obuf[100]; |
818 | dc99065b | bellard | static char *obufp; |
819 | dc99065b | bellard | static char scratchbuf[100]; |
820 | dc99065b | bellard | static unsigned char *start_codep; |
821 | dc99065b | bellard | static unsigned char *codep; |
822 | dc99065b | bellard | static disassemble_info *the_info;
|
823 | dc99065b | bellard | static int mod; |
824 | dc99065b | bellard | static int rm; |
825 | dc99065b | bellard | static int reg; |
826 | dc99065b | bellard | static void oappend PARAMS ((char *s)); |
827 | dc99065b | bellard | |
828 | dc99065b | bellard | static char *names32[]={ |
829 | dc99065b | bellard | "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", |
830 | dc99065b | bellard | }; |
831 | dc99065b | bellard | static char *names16[] = { |
832 | dc99065b | bellard | "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", |
833 | dc99065b | bellard | }; |
834 | dc99065b | bellard | static char *names8[] = { |
835 | dc99065b | bellard | "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", |
836 | dc99065b | bellard | }; |
837 | dc99065b | bellard | static char *names_seg[] = { |
838 | dc99065b | bellard | "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", |
839 | dc99065b | bellard | }; |
840 | dc99065b | bellard | static char *index16[] = { |
841 | dc99065b | bellard | "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx" |
842 | dc99065b | bellard | }; |
843 | dc99065b | bellard | |
844 | dc99065b | bellard | static struct dis386 grps[][8] = { |
845 | dc99065b | bellard | /* GRP1b */
|
846 | dc99065b | bellard | { |
847 | dc99065b | bellard | { "addb", Eb, Ib },
|
848 | dc99065b | bellard | { "orb", Eb, Ib },
|
849 | dc99065b | bellard | { "adcb", Eb, Ib },
|
850 | dc99065b | bellard | { "sbbb", Eb, Ib },
|
851 | dc99065b | bellard | { "andb", Eb, Ib },
|
852 | dc99065b | bellard | { "subb", Eb, Ib },
|
853 | dc99065b | bellard | { "xorb", Eb, Ib },
|
854 | dc99065b | bellard | { "cmpb", Eb, Ib }
|
855 | dc99065b | bellard | }, |
856 | dc99065b | bellard | /* GRP1S */
|
857 | dc99065b | bellard | { |
858 | dc99065b | bellard | { "addS", Ev, Iv },
|
859 | dc99065b | bellard | { "orS", Ev, Iv },
|
860 | dc99065b | bellard | { "adcS", Ev, Iv },
|
861 | dc99065b | bellard | { "sbbS", Ev, Iv },
|
862 | dc99065b | bellard | { "andS", Ev, Iv },
|
863 | dc99065b | bellard | { "subS", Ev, Iv },
|
864 | dc99065b | bellard | { "xorS", Ev, Iv },
|
865 | dc99065b | bellard | { "cmpS", Ev, Iv }
|
866 | dc99065b | bellard | }, |
867 | dc99065b | bellard | /* GRP1Ss */
|
868 | dc99065b | bellard | { |
869 | dc99065b | bellard | { "addS", Ev, sIb },
|
870 | dc99065b | bellard | { "orS", Ev, sIb },
|
871 | dc99065b | bellard | { "adcS", Ev, sIb },
|
872 | dc99065b | bellard | { "sbbS", Ev, sIb },
|
873 | dc99065b | bellard | { "andS", Ev, sIb },
|
874 | dc99065b | bellard | { "subS", Ev, sIb },
|
875 | dc99065b | bellard | { "xorS", Ev, sIb },
|
876 | dc99065b | bellard | { "cmpS", Ev, sIb }
|
877 | dc99065b | bellard | }, |
878 | dc99065b | bellard | /* GRP2b */
|
879 | dc99065b | bellard | { |
880 | dc99065b | bellard | { "rolb", Eb, Ib },
|
881 | dc99065b | bellard | { "rorb", Eb, Ib },
|
882 | dc99065b | bellard | { "rclb", Eb, Ib },
|
883 | dc99065b | bellard | { "rcrb", Eb, Ib },
|
884 | dc99065b | bellard | { "shlb", Eb, Ib },
|
885 | dc99065b | bellard | { "shrb", Eb, Ib },
|
886 | dc99065b | bellard | { "(bad)" },
|
887 | dc99065b | bellard | { "sarb", Eb, Ib },
|
888 | dc99065b | bellard | }, |
889 | dc99065b | bellard | /* GRP2S */
|
890 | dc99065b | bellard | { |
891 | dc99065b | bellard | { "rolS", Ev, Ib },
|
892 | dc99065b | bellard | { "rorS", Ev, Ib },
|
893 | dc99065b | bellard | { "rclS", Ev, Ib },
|
894 | dc99065b | bellard | { "rcrS", Ev, Ib },
|
895 | dc99065b | bellard | { "shlS", Ev, Ib },
|
896 | dc99065b | bellard | { "shrS", Ev, Ib },
|
897 | dc99065b | bellard | { "(bad)" },
|
898 | dc99065b | bellard | { "sarS", Ev, Ib },
|
899 | dc99065b | bellard | }, |
900 | dc99065b | bellard | /* GRP2b_one */
|
901 | dc99065b | bellard | { |
902 | dc99065b | bellard | { "rolb", Eb },
|
903 | dc99065b | bellard | { "rorb", Eb },
|
904 | dc99065b | bellard | { "rclb", Eb },
|
905 | dc99065b | bellard | { "rcrb", Eb },
|
906 | dc99065b | bellard | { "shlb", Eb },
|
907 | dc99065b | bellard | { "shrb", Eb },
|
908 | dc99065b | bellard | { "(bad)" },
|
909 | dc99065b | bellard | { "sarb", Eb },
|
910 | dc99065b | bellard | }, |
911 | dc99065b | bellard | /* GRP2S_one */
|
912 | dc99065b | bellard | { |
913 | dc99065b | bellard | { "rolS", Ev },
|
914 | dc99065b | bellard | { "rorS", Ev },
|
915 | dc99065b | bellard | { "rclS", Ev },
|
916 | dc99065b | bellard | { "rcrS", Ev },
|
917 | dc99065b | bellard | { "shlS", Ev },
|
918 | dc99065b | bellard | { "shrS", Ev },
|
919 | dc99065b | bellard | { "(bad)" },
|
920 | dc99065b | bellard | { "sarS", Ev },
|
921 | dc99065b | bellard | }, |
922 | dc99065b | bellard | /* GRP2b_cl */
|
923 | dc99065b | bellard | { |
924 | dc99065b | bellard | { "rolb", Eb, CL },
|
925 | dc99065b | bellard | { "rorb", Eb, CL },
|
926 | dc99065b | bellard | { "rclb", Eb, CL },
|
927 | dc99065b | bellard | { "rcrb", Eb, CL },
|
928 | dc99065b | bellard | { "shlb", Eb, CL },
|
929 | dc99065b | bellard | { "shrb", Eb, CL },
|
930 | dc99065b | bellard | { "(bad)" },
|
931 | dc99065b | bellard | { "sarb", Eb, CL },
|
932 | dc99065b | bellard | }, |
933 | dc99065b | bellard | /* GRP2S_cl */
|
934 | dc99065b | bellard | { |
935 | dc99065b | bellard | { "rolS", Ev, CL },
|
936 | dc99065b | bellard | { "rorS", Ev, CL },
|
937 | dc99065b | bellard | { "rclS", Ev, CL },
|
938 | dc99065b | bellard | { "rcrS", Ev, CL },
|
939 | dc99065b | bellard | { "shlS", Ev, CL },
|
940 | dc99065b | bellard | { "shrS", Ev, CL },
|
941 | dc99065b | bellard | { "(bad)" },
|
942 | dc99065b | bellard | { "sarS", Ev, CL }
|
943 | dc99065b | bellard | }, |
944 | dc99065b | bellard | /* GRP3b */
|
945 | dc99065b | bellard | { |
946 | dc99065b | bellard | { "testb", Eb, Ib },
|
947 | dc99065b | bellard | { "(bad)", Eb },
|
948 | dc99065b | bellard | { "notb", Eb },
|
949 | dc99065b | bellard | { "negb", Eb },
|
950 | dc99065b | bellard | { "mulb", AL, Eb },
|
951 | dc99065b | bellard | { "imulb", AL, Eb },
|
952 | dc99065b | bellard | { "divb", AL, Eb },
|
953 | dc99065b | bellard | { "idivb", AL, Eb }
|
954 | dc99065b | bellard | }, |
955 | dc99065b | bellard | /* GRP3S */
|
956 | dc99065b | bellard | { |
957 | dc99065b | bellard | { "testS", Ev, Iv },
|
958 | dc99065b | bellard | { "(bad)" },
|
959 | dc99065b | bellard | { "notS", Ev },
|
960 | dc99065b | bellard | { "negS", Ev },
|
961 | dc99065b | bellard | { "mulS", eAX, Ev },
|
962 | dc99065b | bellard | { "imulS", eAX, Ev },
|
963 | dc99065b | bellard | { "divS", eAX, Ev },
|
964 | dc99065b | bellard | { "idivS", eAX, Ev },
|
965 | dc99065b | bellard | }, |
966 | dc99065b | bellard | /* GRP4 */
|
967 | dc99065b | bellard | { |
968 | dc99065b | bellard | { "incb", Eb },
|
969 | dc99065b | bellard | { "decb", Eb },
|
970 | dc99065b | bellard | { "(bad)" },
|
971 | dc99065b | bellard | { "(bad)" },
|
972 | dc99065b | bellard | { "(bad)" },
|
973 | dc99065b | bellard | { "(bad)" },
|
974 | dc99065b | bellard | { "(bad)" },
|
975 | dc99065b | bellard | { "(bad)" },
|
976 | dc99065b | bellard | }, |
977 | dc99065b | bellard | /* GRP5 */
|
978 | dc99065b | bellard | { |
979 | dc99065b | bellard | { "incS", Ev },
|
980 | dc99065b | bellard | { "decS", Ev },
|
981 | dc99065b | bellard | { "call", indirEv },
|
982 | dc99065b | bellard | { "lcall", indirEv },
|
983 | dc99065b | bellard | { "jmp", indirEv },
|
984 | dc99065b | bellard | { "ljmp", indirEv },
|
985 | dc99065b | bellard | { "pushS", Ev },
|
986 | dc99065b | bellard | { "(bad)" },
|
987 | dc99065b | bellard | }, |
988 | dc99065b | bellard | /* GRP6 */
|
989 | dc99065b | bellard | { |
990 | dc99065b | bellard | { "sldt", Ew },
|
991 | dc99065b | bellard | { "str", Ew },
|
992 | dc99065b | bellard | { "lldt", Ew },
|
993 | dc99065b | bellard | { "ltr", Ew },
|
994 | dc99065b | bellard | { "verr", Ew },
|
995 | dc99065b | bellard | { "verw", Ew },
|
996 | dc99065b | bellard | { "(bad)" },
|
997 | dc99065b | bellard | { "(bad)" }
|
998 | dc99065b | bellard | }, |
999 | dc99065b | bellard | /* GRP7 */
|
1000 | dc99065b | bellard | { |
1001 | dc99065b | bellard | { "sgdt", Ew },
|
1002 | dc99065b | bellard | { "sidt", Ew },
|
1003 | dc99065b | bellard | { "lgdt", Ew },
|
1004 | dc99065b | bellard | { "lidt", Ew },
|
1005 | dc99065b | bellard | { "smsw", Ew },
|
1006 | dc99065b | bellard | { "(bad)" },
|
1007 | dc99065b | bellard | { "lmsw", Ew },
|
1008 | dc99065b | bellard | { "invlpg", Ew },
|
1009 | dc99065b | bellard | }, |
1010 | dc99065b | bellard | /* GRP8 */
|
1011 | dc99065b | bellard | { |
1012 | dc99065b | bellard | { "(bad)" },
|
1013 | dc99065b | bellard | { "(bad)" },
|
1014 | dc99065b | bellard | { "(bad)" },
|
1015 | dc99065b | bellard | { "(bad)" },
|
1016 | dc99065b | bellard | { "btS", Ev, Ib },
|
1017 | dc99065b | bellard | { "btsS", Ev, Ib },
|
1018 | dc99065b | bellard | { "btrS", Ev, Ib },
|
1019 | dc99065b | bellard | { "btcS", Ev, Ib },
|
1020 | dc99065b | bellard | }, |
1021 | dc99065b | bellard | /* GRP9 */
|
1022 | dc99065b | bellard | { |
1023 | dc99065b | bellard | { "(bad)" },
|
1024 | dc99065b | bellard | { "cmpxchg8b", Ev },
|
1025 | dc99065b | bellard | { "(bad)" },
|
1026 | dc99065b | bellard | { "(bad)" },
|
1027 | dc99065b | bellard | { "(bad)" },
|
1028 | dc99065b | bellard | { "(bad)" },
|
1029 | dc99065b | bellard | { "(bad)" },
|
1030 | dc99065b | bellard | { "(bad)" },
|
1031 | dc99065b | bellard | }, |
1032 | dc99065b | bellard | /* GRP10 */
|
1033 | dc99065b | bellard | { |
1034 | dc99065b | bellard | { "(bad)" },
|
1035 | dc99065b | bellard | { "(bad)" },
|
1036 | dc99065b | bellard | { "psrlw", MS, Ib },
|
1037 | dc99065b | bellard | { "(bad)" },
|
1038 | dc99065b | bellard | { "psraw", MS, Ib },
|
1039 | dc99065b | bellard | { "(bad)" },
|
1040 | dc99065b | bellard | { "psllw", MS, Ib },
|
1041 | dc99065b | bellard | { "(bad)" },
|
1042 | dc99065b | bellard | }, |
1043 | dc99065b | bellard | /* GRP11 */
|
1044 | dc99065b | bellard | { |
1045 | dc99065b | bellard | { "(bad)" },
|
1046 | dc99065b | bellard | { "(bad)" },
|
1047 | dc99065b | bellard | { "psrld", MS, Ib },
|
1048 | dc99065b | bellard | { "(bad)" },
|
1049 | dc99065b | bellard | { "psrad", MS, Ib },
|
1050 | dc99065b | bellard | { "(bad)" },
|
1051 | dc99065b | bellard | { "pslld", MS, Ib },
|
1052 | dc99065b | bellard | { "(bad)" },
|
1053 | dc99065b | bellard | }, |
1054 | dc99065b | bellard | /* GRP12 */
|
1055 | dc99065b | bellard | { |
1056 | dc99065b | bellard | { "(bad)" },
|
1057 | dc99065b | bellard | { "(bad)" },
|
1058 | dc99065b | bellard | { "psrlq", MS, Ib },
|
1059 | dc99065b | bellard | { "(bad)" },
|
1060 | dc99065b | bellard | { "(bad)" },
|
1061 | dc99065b | bellard | { "(bad)" },
|
1062 | dc99065b | bellard | { "psllq", MS, Ib },
|
1063 | dc99065b | bellard | { "(bad)" },
|
1064 | dc99065b | bellard | } |
1065 | dc99065b | bellard | }; |
1066 | dc99065b | bellard | |
1067 | dc99065b | bellard | #define PREFIX_REPZ 1 |
1068 | dc99065b | bellard | #define PREFIX_REPNZ 2 |
1069 | dc99065b | bellard | #define PREFIX_LOCK 4 |
1070 | dc99065b | bellard | #define PREFIX_CS 8 |
1071 | dc99065b | bellard | #define PREFIX_SS 0x10 |
1072 | dc99065b | bellard | #define PREFIX_DS 0x20 |
1073 | dc99065b | bellard | #define PREFIX_ES 0x40 |
1074 | dc99065b | bellard | #define PREFIX_FS 0x80 |
1075 | dc99065b | bellard | #define PREFIX_GS 0x100 |
1076 | dc99065b | bellard | #define PREFIX_DATA 0x200 |
1077 | dc99065b | bellard | #define PREFIX_ADR 0x400 |
1078 | dc99065b | bellard | #define PREFIX_FWAIT 0x800 |
1079 | dc99065b | bellard | |
1080 | dc99065b | bellard | static int prefixes; |
1081 | dc99065b | bellard | |
1082 | dc99065b | bellard | static void |
1083 | dc99065b | bellard | ckprefix () |
1084 | dc99065b | bellard | { |
1085 | dc99065b | bellard | prefixes = 0;
|
1086 | dc99065b | bellard | while (1) |
1087 | dc99065b | bellard | { |
1088 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
1089 | dc99065b | bellard | switch (*codep)
|
1090 | dc99065b | bellard | { |
1091 | dc99065b | bellard | case 0xf3: |
1092 | dc99065b | bellard | prefixes |= PREFIX_REPZ; |
1093 | dc99065b | bellard | break;
|
1094 | dc99065b | bellard | case 0xf2: |
1095 | dc99065b | bellard | prefixes |= PREFIX_REPNZ; |
1096 | dc99065b | bellard | break;
|
1097 | dc99065b | bellard | case 0xf0: |
1098 | dc99065b | bellard | prefixes |= PREFIX_LOCK; |
1099 | dc99065b | bellard | break;
|
1100 | dc99065b | bellard | case 0x2e: |
1101 | dc99065b | bellard | prefixes |= PREFIX_CS; |
1102 | dc99065b | bellard | break;
|
1103 | dc99065b | bellard | case 0x36: |
1104 | dc99065b | bellard | prefixes |= PREFIX_SS; |
1105 | dc99065b | bellard | break;
|
1106 | dc99065b | bellard | case 0x3e: |
1107 | dc99065b | bellard | prefixes |= PREFIX_DS; |
1108 | dc99065b | bellard | break;
|
1109 | dc99065b | bellard | case 0x26: |
1110 | dc99065b | bellard | prefixes |= PREFIX_ES; |
1111 | dc99065b | bellard | break;
|
1112 | dc99065b | bellard | case 0x64: |
1113 | dc99065b | bellard | prefixes |= PREFIX_FS; |
1114 | dc99065b | bellard | break;
|
1115 | dc99065b | bellard | case 0x65: |
1116 | dc99065b | bellard | prefixes |= PREFIX_GS; |
1117 | dc99065b | bellard | break;
|
1118 | dc99065b | bellard | case 0x66: |
1119 | dc99065b | bellard | prefixes |= PREFIX_DATA; |
1120 | dc99065b | bellard | break;
|
1121 | dc99065b | bellard | case 0x67: |
1122 | dc99065b | bellard | prefixes |= PREFIX_ADR; |
1123 | dc99065b | bellard | break;
|
1124 | dc99065b | bellard | case 0x9b: |
1125 | dc99065b | bellard | prefixes |= PREFIX_FWAIT; |
1126 | dc99065b | bellard | break;
|
1127 | dc99065b | bellard | default:
|
1128 | dc99065b | bellard | return;
|
1129 | dc99065b | bellard | } |
1130 | dc99065b | bellard | codep++; |
1131 | dc99065b | bellard | } |
1132 | dc99065b | bellard | } |
1133 | dc99065b | bellard | |
1134 | dc99065b | bellard | static char op1out[100], op2out[100], op3out[100]; |
1135 | dc99065b | bellard | static int op_address[3], op_ad, op_index[3]; |
1136 | dc99065b | bellard | static int start_pc; |
1137 | dc99065b | bellard | |
1138 | dc99065b | bellard | |
1139 | dc99065b | bellard | /*
|
1140 | dc99065b | bellard | * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
|
1141 | dc99065b | bellard | * (see topic "Redundant prefixes" in the "Differences from 8086"
|
1142 | dc99065b | bellard | * section of the "Virtual 8086 Mode" chapter.)
|
1143 | dc99065b | bellard | * 'pc' should be the address of this instruction, it will
|
1144 | dc99065b | bellard | * be used to print the target address if this is a relative jump or call
|
1145 | dc99065b | bellard | * The function returns the length of this instruction in bytes.
|
1146 | dc99065b | bellard | */
|
1147 | dc99065b | bellard | |
1148 | dc99065b | bellard | int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag, |
1149 | dc99065b | bellard | int dflag));
|
1150 | dc99065b | bellard | int
|
1151 | dc99065b | bellard | print_insn_i386 (pc, info) |
1152 | dc99065b | bellard | bfd_vma pc; |
1153 | dc99065b | bellard | disassemble_info *info; |
1154 | dc99065b | bellard | { |
1155 | dc99065b | bellard | if (info->mach == bfd_mach_i386_i386)
|
1156 | dc99065b | bellard | return print_insn_x86 (pc, info, 1, 1); |
1157 | dc99065b | bellard | else if (info->mach == bfd_mach_i386_i8086) |
1158 | dc99065b | bellard | return print_insn_x86 (pc, info, 0, 0); |
1159 | dc99065b | bellard | else
|
1160 | dc99065b | bellard | abort (); |
1161 | dc99065b | bellard | } |
1162 | dc99065b | bellard | |
1163 | dc99065b | bellard | int
|
1164 | dc99065b | bellard | print_insn_x86 (pc, info, aflag, dflag) |
1165 | dc99065b | bellard | bfd_vma pc; |
1166 | dc99065b | bellard | disassemble_info *info; |
1167 | dc99065b | bellard | int aflag;
|
1168 | dc99065b | bellard | int dflag;
|
1169 | dc99065b | bellard | { |
1170 | dc99065b | bellard | struct dis386 *dp;
|
1171 | dc99065b | bellard | int i;
|
1172 | dc99065b | bellard | int enter_instruction;
|
1173 | dc99065b | bellard | char *first, *second, *third;
|
1174 | dc99065b | bellard | int needcomma;
|
1175 | dc99065b | bellard | unsigned char need_modrm; |
1176 | dc99065b | bellard | |
1177 | dc99065b | bellard | struct dis_private priv;
|
1178 | dc99065b | bellard | bfd_byte *inbuf = priv.the_buffer; |
1179 | dc99065b | bellard | |
1180 | dc99065b | bellard | /* The output looks better if we put 5 bytes on a line, since that
|
1181 | dc99065b | bellard | puts long word instructions on a single line. */
|
1182 | dc99065b | bellard | info->bytes_per_line = 5;
|
1183 | dc99065b | bellard | |
1184 | dc99065b | bellard | info->private_data = (PTR) &priv; |
1185 | dc99065b | bellard | priv.max_fetched = priv.the_buffer; |
1186 | dc99065b | bellard | priv.insn_start = pc; |
1187 | dc99065b | bellard | if (setjmp (priv.bailout) != 0) |
1188 | dc99065b | bellard | /* Error return. */
|
1189 | dc99065b | bellard | return -1; |
1190 | dc99065b | bellard | |
1191 | dc99065b | bellard | obuf[0] = 0; |
1192 | dc99065b | bellard | op1out[0] = 0; |
1193 | dc99065b | bellard | op2out[0] = 0; |
1194 | dc99065b | bellard | op3out[0] = 0; |
1195 | dc99065b | bellard | |
1196 | dc99065b | bellard | op_index[0] = op_index[1] = op_index[2] = -1; |
1197 | dc99065b | bellard | |
1198 | dc99065b | bellard | the_info = info; |
1199 | dc99065b | bellard | start_pc = pc; |
1200 | dc99065b | bellard | start_codep = inbuf; |
1201 | dc99065b | bellard | codep = inbuf; |
1202 | dc99065b | bellard | |
1203 | dc99065b | bellard | ckprefix (); |
1204 | dc99065b | bellard | |
1205 | dc99065b | bellard | FETCH_DATA (info, codep + 1);
|
1206 | dc99065b | bellard | if (*codep == 0xc8) |
1207 | dc99065b | bellard | enter_instruction = 1;
|
1208 | dc99065b | bellard | else
|
1209 | dc99065b | bellard | enter_instruction = 0;
|
1210 | dc99065b | bellard | |
1211 | dc99065b | bellard | obufp = obuf; |
1212 | dc99065b | bellard | |
1213 | dc99065b | bellard | if (prefixes & PREFIX_REPZ)
|
1214 | dc99065b | bellard | oappend ("repz ");
|
1215 | dc99065b | bellard | if (prefixes & PREFIX_REPNZ)
|
1216 | dc99065b | bellard | oappend ("repnz ");
|
1217 | dc99065b | bellard | if (prefixes & PREFIX_LOCK)
|
1218 | dc99065b | bellard | oappend ("lock ");
|
1219 | dc99065b | bellard | |
1220 | dc99065b | bellard | if ((prefixes & PREFIX_FWAIT)
|
1221 | dc99065b | bellard | && ((*codep < 0xd8) || (*codep > 0xdf))) |
1222 | dc99065b | bellard | { |
1223 | dc99065b | bellard | /* fwait not followed by floating point instruction */
|
1224 | dc99065b | bellard | (*info->fprintf_func) (info->stream, "fwait");
|
1225 | dc99065b | bellard | return (1); |
1226 | dc99065b | bellard | } |
1227 | dc99065b | bellard | |
1228 | dc99065b | bellard | if (prefixes & PREFIX_DATA)
|
1229 | dc99065b | bellard | dflag ^= 1;
|
1230 | dc99065b | bellard | |
1231 | dc99065b | bellard | if (prefixes & PREFIX_ADR)
|
1232 | dc99065b | bellard | { |
1233 | dc99065b | bellard | aflag ^= 1;
|
1234 | dc99065b | bellard | if (aflag)
|
1235 | dc99065b | bellard | oappend ("addr32 ");
|
1236 | dc99065b | bellard | else
|
1237 | dc99065b | bellard | oappend ("addr16 ");
|
1238 | dc99065b | bellard | } |
1239 | dc99065b | bellard | |
1240 | dc99065b | bellard | if (*codep == 0x0f) |
1241 | dc99065b | bellard | { |
1242 | dc99065b | bellard | FETCH_DATA (info, codep + 2);
|
1243 | dc99065b | bellard | dp = &dis386_twobyte[*++codep]; |
1244 | dc99065b | bellard | need_modrm = twobyte_has_modrm[*codep]; |
1245 | dc99065b | bellard | } |
1246 | dc99065b | bellard | else
|
1247 | dc99065b | bellard | { |
1248 | dc99065b | bellard | dp = &dis386[*codep]; |
1249 | dc99065b | bellard | need_modrm = onebyte_has_modrm[*codep]; |
1250 | dc99065b | bellard | } |
1251 | dc99065b | bellard | codep++; |
1252 | dc99065b | bellard | |
1253 | dc99065b | bellard | if (need_modrm)
|
1254 | dc99065b | bellard | { |
1255 | dc99065b | bellard | FETCH_DATA (info, codep + 1);
|
1256 | dc99065b | bellard | mod = (*codep >> 6) & 3; |
1257 | dc99065b | bellard | reg = (*codep >> 3) & 7; |
1258 | dc99065b | bellard | rm = *codep & 7;
|
1259 | dc99065b | bellard | } |
1260 | dc99065b | bellard | |
1261 | dc99065b | bellard | if (dp->name == NULL && dp->bytemode1 == FLOATCODE) |
1262 | dc99065b | bellard | { |
1263 | dc99065b | bellard | dofloat (aflag, dflag); |
1264 | dc99065b | bellard | } |
1265 | dc99065b | bellard | else
|
1266 | dc99065b | bellard | { |
1267 | dc99065b | bellard | if (dp->name == NULL) |
1268 | dc99065b | bellard | dp = &grps[dp->bytemode1][reg]; |
1269 | dc99065b | bellard | |
1270 | dc99065b | bellard | putop (dp->name, aflag, dflag); |
1271 | dc99065b | bellard | |
1272 | dc99065b | bellard | obufp = op1out; |
1273 | dc99065b | bellard | op_ad = 2;
|
1274 | dc99065b | bellard | if (dp->op1)
|
1275 | dc99065b | bellard | (*dp->op1)(dp->bytemode1, aflag, dflag); |
1276 | dc99065b | bellard | |
1277 | dc99065b | bellard | obufp = op2out; |
1278 | dc99065b | bellard | op_ad = 1;
|
1279 | dc99065b | bellard | if (dp->op2)
|
1280 | dc99065b | bellard | (*dp->op2)(dp->bytemode2, aflag, dflag); |
1281 | dc99065b | bellard | |
1282 | dc99065b | bellard | obufp = op3out; |
1283 | dc99065b | bellard | op_ad = 0;
|
1284 | dc99065b | bellard | if (dp->op3)
|
1285 | dc99065b | bellard | (*dp->op3)(dp->bytemode3, aflag, dflag); |
1286 | dc99065b | bellard | } |
1287 | dc99065b | bellard | |
1288 | dc99065b | bellard | obufp = obuf + strlen (obuf); |
1289 | dc99065b | bellard | for (i = strlen (obuf); i < 6; i++) |
1290 | dc99065b | bellard | oappend (" ");
|
1291 | dc99065b | bellard | oappend (" ");
|
1292 | dc99065b | bellard | (*info->fprintf_func) (info->stream, "%s", obuf);
|
1293 | dc99065b | bellard | |
1294 | dc99065b | bellard | /* enter instruction is printed with operands in the
|
1295 | dc99065b | bellard | * same order as the intel book; everything else
|
1296 | dc99065b | bellard | * is printed in reverse order
|
1297 | dc99065b | bellard | */
|
1298 | dc99065b | bellard | if (enter_instruction)
|
1299 | dc99065b | bellard | { |
1300 | dc99065b | bellard | first = op1out; |
1301 | dc99065b | bellard | second = op2out; |
1302 | dc99065b | bellard | third = op3out; |
1303 | dc99065b | bellard | op_ad = op_index[0];
|
1304 | dc99065b | bellard | op_index[0] = op_index[2]; |
1305 | dc99065b | bellard | op_index[2] = op_ad;
|
1306 | dc99065b | bellard | } |
1307 | dc99065b | bellard | else
|
1308 | dc99065b | bellard | { |
1309 | dc99065b | bellard | first = op3out; |
1310 | dc99065b | bellard | second = op2out; |
1311 | dc99065b | bellard | third = op1out; |
1312 | dc99065b | bellard | } |
1313 | dc99065b | bellard | needcomma = 0;
|
1314 | dc99065b | bellard | if (*first)
|
1315 | dc99065b | bellard | { |
1316 | dc99065b | bellard | if (op_index[0] != -1) |
1317 | dc99065b | bellard | (*info->print_address_func) (op_address[op_index[0]], info);
|
1318 | dc99065b | bellard | else
|
1319 | dc99065b | bellard | (*info->fprintf_func) (info->stream, "%s", first);
|
1320 | dc99065b | bellard | needcomma = 1;
|
1321 | dc99065b | bellard | } |
1322 | dc99065b | bellard | if (*second)
|
1323 | dc99065b | bellard | { |
1324 | dc99065b | bellard | if (needcomma)
|
1325 | dc99065b | bellard | (*info->fprintf_func) (info->stream, ",");
|
1326 | dc99065b | bellard | if (op_index[1] != -1) |
1327 | dc99065b | bellard | (*info->print_address_func) (op_address[op_index[1]], info);
|
1328 | dc99065b | bellard | else
|
1329 | dc99065b | bellard | (*info->fprintf_func) (info->stream, "%s", second);
|
1330 | dc99065b | bellard | needcomma = 1;
|
1331 | dc99065b | bellard | } |
1332 | dc99065b | bellard | if (*third)
|
1333 | dc99065b | bellard | { |
1334 | dc99065b | bellard | if (needcomma)
|
1335 | dc99065b | bellard | (*info->fprintf_func) (info->stream, ",");
|
1336 | dc99065b | bellard | if (op_index[2] != -1) |
1337 | dc99065b | bellard | (*info->print_address_func) (op_address[op_index[2]], info);
|
1338 | dc99065b | bellard | else
|
1339 | dc99065b | bellard | (*info->fprintf_func) (info->stream, "%s", third);
|
1340 | dc99065b | bellard | } |
1341 | dc99065b | bellard | return (codep - inbuf);
|
1342 | dc99065b | bellard | } |
1343 | dc99065b | bellard | |
1344 | dc99065b | bellard | static char *float_mem[] = { |
1345 | dc99065b | bellard | /* d8 */
|
1346 | dc99065b | bellard | "fadds",
|
1347 | dc99065b | bellard | "fmuls",
|
1348 | dc99065b | bellard | "fcoms",
|
1349 | dc99065b | bellard | "fcomps",
|
1350 | dc99065b | bellard | "fsubs",
|
1351 | dc99065b | bellard | "fsubrs",
|
1352 | dc99065b | bellard | "fdivs",
|
1353 | dc99065b | bellard | "fdivrs",
|
1354 | dc99065b | bellard | /* d9 */
|
1355 | dc99065b | bellard | "flds",
|
1356 | dc99065b | bellard | "(bad)",
|
1357 | dc99065b | bellard | "fsts",
|
1358 | dc99065b | bellard | "fstps",
|
1359 | dc99065b | bellard | "fldenv",
|
1360 | dc99065b | bellard | "fldcw",
|
1361 | dc99065b | bellard | "fNstenv",
|
1362 | dc99065b | bellard | "fNstcw",
|
1363 | dc99065b | bellard | /* da */
|
1364 | dc99065b | bellard | "fiaddl",
|
1365 | dc99065b | bellard | "fimull",
|
1366 | dc99065b | bellard | "ficoml",
|
1367 | dc99065b | bellard | "ficompl",
|
1368 | dc99065b | bellard | "fisubl",
|
1369 | dc99065b | bellard | "fisubrl",
|
1370 | dc99065b | bellard | "fidivl",
|
1371 | dc99065b | bellard | "fidivrl",
|
1372 | dc99065b | bellard | /* db */
|
1373 | dc99065b | bellard | "fildl",
|
1374 | dc99065b | bellard | "(bad)",
|
1375 | dc99065b | bellard | "fistl",
|
1376 | dc99065b | bellard | "fistpl",
|
1377 | dc99065b | bellard | "(bad)",
|
1378 | dc99065b | bellard | "fldt",
|
1379 | dc99065b | bellard | "(bad)",
|
1380 | dc99065b | bellard | "fstpt",
|
1381 | dc99065b | bellard | /* dc */
|
1382 | dc99065b | bellard | "faddl",
|
1383 | dc99065b | bellard | "fmull",
|
1384 | dc99065b | bellard | "fcoml",
|
1385 | dc99065b | bellard | "fcompl",
|
1386 | dc99065b | bellard | "fsubl",
|
1387 | dc99065b | bellard | "fsubrl",
|
1388 | dc99065b | bellard | "fdivl",
|
1389 | dc99065b | bellard | "fdivrl",
|
1390 | dc99065b | bellard | /* dd */
|
1391 | dc99065b | bellard | "fldl",
|
1392 | dc99065b | bellard | "(bad)",
|
1393 | dc99065b | bellard | "fstl",
|
1394 | dc99065b | bellard | "fstpl",
|
1395 | dc99065b | bellard | "frstor",
|
1396 | dc99065b | bellard | "(bad)",
|
1397 | dc99065b | bellard | "fNsave",
|
1398 | dc99065b | bellard | "fNstsw",
|
1399 | dc99065b | bellard | /* de */
|
1400 | dc99065b | bellard | "fiadd",
|
1401 | dc99065b | bellard | "fimul",
|
1402 | dc99065b | bellard | "ficom",
|
1403 | dc99065b | bellard | "ficomp",
|
1404 | dc99065b | bellard | "fisub",
|
1405 | dc99065b | bellard | "fisubr",
|
1406 | dc99065b | bellard | "fidiv",
|
1407 | dc99065b | bellard | "fidivr",
|
1408 | dc99065b | bellard | /* df */
|
1409 | dc99065b | bellard | "fild",
|
1410 | dc99065b | bellard | "(bad)",
|
1411 | dc99065b | bellard | "fist",
|
1412 | dc99065b | bellard | "fistp",
|
1413 | dc99065b | bellard | "fbld",
|
1414 | dc99065b | bellard | "fildll",
|
1415 | dc99065b | bellard | "fbstp",
|
1416 | dc99065b | bellard | "fistpll",
|
1417 | dc99065b | bellard | }; |
1418 | dc99065b | bellard | |
1419 | dc99065b | bellard | #define ST OP_ST, 0 |
1420 | dc99065b | bellard | #define STi OP_STi, 0 |
1421 | dc99065b | bellard | |
1422 | dc99065b | bellard | #define FGRPd9_2 NULL, NULL, 0 |
1423 | dc99065b | bellard | #define FGRPd9_4 NULL, NULL, 1 |
1424 | dc99065b | bellard | #define FGRPd9_5 NULL, NULL, 2 |
1425 | dc99065b | bellard | #define FGRPd9_6 NULL, NULL, 3 |
1426 | dc99065b | bellard | #define FGRPd9_7 NULL, NULL, 4 |
1427 | dc99065b | bellard | #define FGRPda_5 NULL, NULL, 5 |
1428 | dc99065b | bellard | #define FGRPdb_4 NULL, NULL, 6 |
1429 | dc99065b | bellard | #define FGRPde_3 NULL, NULL, 7 |
1430 | dc99065b | bellard | #define FGRPdf_4 NULL, NULL, 8 |
1431 | dc99065b | bellard | |
1432 | dc99065b | bellard | static struct dis386 float_reg[][8] = { |
1433 | dc99065b | bellard | /* d8 */
|
1434 | dc99065b | bellard | { |
1435 | dc99065b | bellard | { "fadd", ST, STi },
|
1436 | dc99065b | bellard | { "fmul", ST, STi },
|
1437 | dc99065b | bellard | { "fcom", STi },
|
1438 | dc99065b | bellard | { "fcomp", STi },
|
1439 | dc99065b | bellard | { "fsub", ST, STi },
|
1440 | dc99065b | bellard | { "fsubr", ST, STi },
|
1441 | dc99065b | bellard | { "fdiv", ST, STi },
|
1442 | dc99065b | bellard | { "fdivr", ST, STi },
|
1443 | dc99065b | bellard | }, |
1444 | dc99065b | bellard | /* d9 */
|
1445 | dc99065b | bellard | { |
1446 | dc99065b | bellard | { "fld", STi },
|
1447 | dc99065b | bellard | { "fxch", STi },
|
1448 | dc99065b | bellard | { FGRPd9_2 }, |
1449 | dc99065b | bellard | { "(bad)" },
|
1450 | dc99065b | bellard | { FGRPd9_4 }, |
1451 | dc99065b | bellard | { FGRPd9_5 }, |
1452 | dc99065b | bellard | { FGRPd9_6 }, |
1453 | dc99065b | bellard | { FGRPd9_7 }, |
1454 | dc99065b | bellard | }, |
1455 | dc99065b | bellard | /* da */
|
1456 | dc99065b | bellard | { |
1457 | dc99065b | bellard | { "fcmovb", ST, STi },
|
1458 | dc99065b | bellard | { "fcmove", ST, STi },
|
1459 | dc99065b | bellard | { "fcmovbe",ST, STi },
|
1460 | dc99065b | bellard | { "fcmovu", ST, STi },
|
1461 | dc99065b | bellard | { "(bad)" },
|
1462 | dc99065b | bellard | { FGRPda_5 }, |
1463 | dc99065b | bellard | { "(bad)" },
|
1464 | dc99065b | bellard | { "(bad)" },
|
1465 | dc99065b | bellard | }, |
1466 | dc99065b | bellard | /* db */
|
1467 | dc99065b | bellard | { |
1468 | dc99065b | bellard | { "fcmovnb",ST, STi },
|
1469 | dc99065b | bellard | { "fcmovne",ST, STi },
|
1470 | dc99065b | bellard | { "fcmovnbe",ST, STi },
|
1471 | dc99065b | bellard | { "fcmovnu",ST, STi },
|
1472 | dc99065b | bellard | { FGRPdb_4 }, |
1473 | dc99065b | bellard | { "fucomi", ST, STi },
|
1474 | dc99065b | bellard | { "fcomi", ST, STi },
|
1475 | dc99065b | bellard | { "(bad)" },
|
1476 | dc99065b | bellard | }, |
1477 | dc99065b | bellard | /* dc */
|
1478 | dc99065b | bellard | { |
1479 | dc99065b | bellard | { "fadd", STi, ST },
|
1480 | dc99065b | bellard | { "fmul", STi, ST },
|
1481 | dc99065b | bellard | { "(bad)" },
|
1482 | dc99065b | bellard | { "(bad)" },
|
1483 | dc99065b | bellard | { "fsub", STi, ST },
|
1484 | dc99065b | bellard | { "fsubr", STi, ST },
|
1485 | dc99065b | bellard | { "fdiv", STi, ST },
|
1486 | dc99065b | bellard | { "fdivr", STi, ST },
|
1487 | dc99065b | bellard | }, |
1488 | dc99065b | bellard | /* dd */
|
1489 | dc99065b | bellard | { |
1490 | dc99065b | bellard | { "ffree", STi },
|
1491 | dc99065b | bellard | { "(bad)" },
|
1492 | dc99065b | bellard | { "fst", STi },
|
1493 | dc99065b | bellard | { "fstp", STi },
|
1494 | dc99065b | bellard | { "fucom", STi },
|
1495 | dc99065b | bellard | { "fucomp", STi },
|
1496 | dc99065b | bellard | { "(bad)" },
|
1497 | dc99065b | bellard | { "(bad)" },
|
1498 | dc99065b | bellard | }, |
1499 | dc99065b | bellard | /* de */
|
1500 | dc99065b | bellard | { |
1501 | dc99065b | bellard | { "faddp", STi, ST },
|
1502 | dc99065b | bellard | { "fmulp", STi, ST },
|
1503 | dc99065b | bellard | { "(bad)" },
|
1504 | dc99065b | bellard | { FGRPde_3 }, |
1505 | dc99065b | bellard | { "fsubp", STi, ST },
|
1506 | dc99065b | bellard | { "fsubrp", STi, ST },
|
1507 | dc99065b | bellard | { "fdivp", STi, ST },
|
1508 | dc99065b | bellard | { "fdivrp", STi, ST },
|
1509 | dc99065b | bellard | }, |
1510 | dc99065b | bellard | /* df */
|
1511 | dc99065b | bellard | { |
1512 | dc99065b | bellard | { "(bad)" },
|
1513 | dc99065b | bellard | { "(bad)" },
|
1514 | dc99065b | bellard | { "(bad)" },
|
1515 | dc99065b | bellard | { "(bad)" },
|
1516 | dc99065b | bellard | { FGRPdf_4 }, |
1517 | dc99065b | bellard | { "fucomip",ST, STi },
|
1518 | dc99065b | bellard | { "fcomip", ST, STi },
|
1519 | dc99065b | bellard | { "(bad)" },
|
1520 | dc99065b | bellard | }, |
1521 | dc99065b | bellard | }; |
1522 | dc99065b | bellard | |
1523 | dc99065b | bellard | |
1524 | dc99065b | bellard | static char *fgrps[][8] = { |
1525 | dc99065b | bellard | /* d9_2 0 */
|
1526 | dc99065b | bellard | { |
1527 | dc99065b | bellard | "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", |
1528 | dc99065b | bellard | }, |
1529 | dc99065b | bellard | |
1530 | dc99065b | bellard | /* d9_4 1 */
|
1531 | dc99065b | bellard | { |
1532 | dc99065b | bellard | "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", |
1533 | dc99065b | bellard | }, |
1534 | dc99065b | bellard | |
1535 | dc99065b | bellard | /* d9_5 2 */
|
1536 | dc99065b | bellard | { |
1537 | dc99065b | bellard | "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", |
1538 | dc99065b | bellard | }, |
1539 | dc99065b | bellard | |
1540 | dc99065b | bellard | /* d9_6 3 */
|
1541 | dc99065b | bellard | { |
1542 | dc99065b | bellard | "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", |
1543 | dc99065b | bellard | }, |
1544 | dc99065b | bellard | |
1545 | dc99065b | bellard | /* d9_7 4 */
|
1546 | dc99065b | bellard | { |
1547 | dc99065b | bellard | "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", |
1548 | dc99065b | bellard | }, |
1549 | dc99065b | bellard | |
1550 | dc99065b | bellard | /* da_5 5 */
|
1551 | dc99065b | bellard | { |
1552 | dc99065b | bellard | "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", |
1553 | dc99065b | bellard | }, |
1554 | dc99065b | bellard | |
1555 | dc99065b | bellard | /* db_4 6 */
|
1556 | dc99065b | bellard | { |
1557 | dc99065b | bellard | "feni(287 only)","fdisi(287 only)","fNclex","fNinit", |
1558 | dc99065b | bellard | "fNsetpm(287 only)","(bad)","(bad)","(bad)", |
1559 | dc99065b | bellard | }, |
1560 | dc99065b | bellard | |
1561 | dc99065b | bellard | /* de_3 7 */
|
1562 | dc99065b | bellard | { |
1563 | dc99065b | bellard | "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", |
1564 | dc99065b | bellard | }, |
1565 | dc99065b | bellard | |
1566 | dc99065b | bellard | /* df_4 8 */
|
1567 | dc99065b | bellard | { |
1568 | dc99065b | bellard | "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", |
1569 | dc99065b | bellard | }, |
1570 | dc99065b | bellard | }; |
1571 | dc99065b | bellard | |
1572 | dc99065b | bellard | static void |
1573 | dc99065b | bellard | dofloat (aflag, dflag) |
1574 | dc99065b | bellard | int aflag;
|
1575 | dc99065b | bellard | int dflag;
|
1576 | dc99065b | bellard | { |
1577 | dc99065b | bellard | struct dis386 *dp;
|
1578 | dc99065b | bellard | unsigned char floatop; |
1579 | dc99065b | bellard | |
1580 | dc99065b | bellard | floatop = codep[-1];
|
1581 | dc99065b | bellard | |
1582 | dc99065b | bellard | if (mod != 3) |
1583 | dc99065b | bellard | { |
1584 | dc99065b | bellard | putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag); |
1585 | dc99065b | bellard | obufp = op1out; |
1586 | dc99065b | bellard | OP_E (v_mode, aflag, dflag); |
1587 | dc99065b | bellard | return;
|
1588 | dc99065b | bellard | } |
1589 | dc99065b | bellard | codep++; |
1590 | dc99065b | bellard | |
1591 | dc99065b | bellard | dp = &float_reg[floatop - 0xd8][reg];
|
1592 | dc99065b | bellard | if (dp->name == NULL) |
1593 | dc99065b | bellard | { |
1594 | dc99065b | bellard | putop (fgrps[dp->bytemode1][rm], aflag, dflag); |
1595 | dc99065b | bellard | /* instruction fnstsw is only one with strange arg */
|
1596 | dc99065b | bellard | if (floatop == 0xdf |
1597 | dc99065b | bellard | && FETCH_DATA (the_info, codep + 1)
|
1598 | dc99065b | bellard | && *codep == 0xe0)
|
1599 | dc99065b | bellard | strcpy (op1out, "%eax");
|
1600 | dc99065b | bellard | } |
1601 | dc99065b | bellard | else
|
1602 | dc99065b | bellard | { |
1603 | dc99065b | bellard | putop (dp->name, aflag, dflag); |
1604 | dc99065b | bellard | obufp = op1out; |
1605 | dc99065b | bellard | if (dp->op1)
|
1606 | dc99065b | bellard | (*dp->op1)(dp->bytemode1, aflag, dflag); |
1607 | dc99065b | bellard | obufp = op2out; |
1608 | dc99065b | bellard | if (dp->op2)
|
1609 | dc99065b | bellard | (*dp->op2)(dp->bytemode2, aflag, dflag); |
1610 | dc99065b | bellard | } |
1611 | dc99065b | bellard | } |
1612 | dc99065b | bellard | |
1613 | dc99065b | bellard | /* ARGSUSED */
|
1614 | dc99065b | bellard | static int |
1615 | dc99065b | bellard | OP_ST (ignore, aflag, dflag) |
1616 | dc99065b | bellard | int ignore;
|
1617 | dc99065b | bellard | int aflag;
|
1618 | dc99065b | bellard | int dflag;
|
1619 | dc99065b | bellard | { |
1620 | dc99065b | bellard | oappend ("%st");
|
1621 | dc99065b | bellard | return (0); |
1622 | dc99065b | bellard | } |
1623 | dc99065b | bellard | |
1624 | dc99065b | bellard | /* ARGSUSED */
|
1625 | dc99065b | bellard | static int |
1626 | dc99065b | bellard | OP_STi (ignore, aflag, dflag) |
1627 | dc99065b | bellard | int ignore;
|
1628 | dc99065b | bellard | int aflag;
|
1629 | dc99065b | bellard | int dflag;
|
1630 | dc99065b | bellard | { |
1631 | dc99065b | bellard | sprintf (scratchbuf, "%%st(%d)", rm);
|
1632 | dc99065b | bellard | oappend (scratchbuf); |
1633 | dc99065b | bellard | return (0); |
1634 | dc99065b | bellard | } |
1635 | dc99065b | bellard | |
1636 | dc99065b | bellard | |
1637 | dc99065b | bellard | /* capital letters in template are macros */
|
1638 | dc99065b | bellard | static void |
1639 | dc99065b | bellard | putop (template, aflag, dflag) |
1640 | dc99065b | bellard | char *template;
|
1641 | dc99065b | bellard | int aflag;
|
1642 | dc99065b | bellard | int dflag;
|
1643 | dc99065b | bellard | { |
1644 | dc99065b | bellard | char *p;
|
1645 | dc99065b | bellard | |
1646 | dc99065b | bellard | for (p = template; *p; p++)
|
1647 | dc99065b | bellard | { |
1648 | dc99065b | bellard | switch (*p)
|
1649 | dc99065b | bellard | { |
1650 | dc99065b | bellard | default:
|
1651 | dc99065b | bellard | *obufp++ = *p; |
1652 | dc99065b | bellard | break;
|
1653 | dc99065b | bellard | case 'C': /* For jcxz/jecxz */ |
1654 | dc99065b | bellard | if (aflag)
|
1655 | dc99065b | bellard | *obufp++ = 'e';
|
1656 | dc99065b | bellard | break;
|
1657 | dc99065b | bellard | case 'N': |
1658 | dc99065b | bellard | if ((prefixes & PREFIX_FWAIT) == 0) |
1659 | dc99065b | bellard | *obufp++ = 'n';
|
1660 | dc99065b | bellard | break;
|
1661 | dc99065b | bellard | case 'S': |
1662 | dc99065b | bellard | /* operand size flag */
|
1663 | dc99065b | bellard | if (dflag)
|
1664 | dc99065b | bellard | *obufp++ = 'l';
|
1665 | dc99065b | bellard | else
|
1666 | dc99065b | bellard | *obufp++ = 'w';
|
1667 | dc99065b | bellard | break;
|
1668 | dc99065b | bellard | case 'W': |
1669 | dc99065b | bellard | /* operand size flag for cwtl, cbtw */
|
1670 | dc99065b | bellard | if (dflag)
|
1671 | dc99065b | bellard | *obufp++ = 'w';
|
1672 | dc99065b | bellard | else
|
1673 | dc99065b | bellard | *obufp++ = 'b';
|
1674 | dc99065b | bellard | break;
|
1675 | dc99065b | bellard | } |
1676 | dc99065b | bellard | } |
1677 | dc99065b | bellard | *obufp = 0;
|
1678 | dc99065b | bellard | } |
1679 | dc99065b | bellard | |
1680 | dc99065b | bellard | static void |
1681 | dc99065b | bellard | oappend (s) |
1682 | dc99065b | bellard | char *s;
|
1683 | dc99065b | bellard | { |
1684 | dc99065b | bellard | strcpy (obufp, s); |
1685 | dc99065b | bellard | obufp += strlen (s); |
1686 | dc99065b | bellard | *obufp = 0;
|
1687 | dc99065b | bellard | } |
1688 | dc99065b | bellard | |
1689 | dc99065b | bellard | static void |
1690 | dc99065b | bellard | append_prefix () |
1691 | dc99065b | bellard | { |
1692 | dc99065b | bellard | if (prefixes & PREFIX_CS)
|
1693 | dc99065b | bellard | oappend ("%cs:");
|
1694 | dc99065b | bellard | if (prefixes & PREFIX_DS)
|
1695 | dc99065b | bellard | oappend ("%ds:");
|
1696 | dc99065b | bellard | if (prefixes & PREFIX_SS)
|
1697 | dc99065b | bellard | oappend ("%ss:");
|
1698 | dc99065b | bellard | if (prefixes & PREFIX_ES)
|
1699 | dc99065b | bellard | oappend ("%es:");
|
1700 | dc99065b | bellard | if (prefixes & PREFIX_FS)
|
1701 | dc99065b | bellard | oappend ("%fs:");
|
1702 | dc99065b | bellard | if (prefixes & PREFIX_GS)
|
1703 | dc99065b | bellard | oappend ("%gs:");
|
1704 | dc99065b | bellard | } |
1705 | dc99065b | bellard | |
1706 | dc99065b | bellard | static int |
1707 | dc99065b | bellard | OP_indirE (bytemode, aflag, dflag) |
1708 | dc99065b | bellard | int bytemode;
|
1709 | dc99065b | bellard | int aflag;
|
1710 | dc99065b | bellard | int dflag;
|
1711 | dc99065b | bellard | { |
1712 | dc99065b | bellard | oappend ("*");
|
1713 | dc99065b | bellard | return OP_E (bytemode, aflag, dflag);
|
1714 | dc99065b | bellard | } |
1715 | dc99065b | bellard | |
1716 | dc99065b | bellard | static int |
1717 | dc99065b | bellard | OP_E (bytemode, aflag, dflag) |
1718 | dc99065b | bellard | int bytemode;
|
1719 | dc99065b | bellard | int aflag;
|
1720 | dc99065b | bellard | int dflag;
|
1721 | dc99065b | bellard | { |
1722 | dc99065b | bellard | int disp;
|
1723 | dc99065b | bellard | |
1724 | dc99065b | bellard | /* skip mod/rm byte */
|
1725 | dc99065b | bellard | codep++; |
1726 | dc99065b | bellard | |
1727 | dc99065b | bellard | if (mod == 3) |
1728 | dc99065b | bellard | { |
1729 | dc99065b | bellard | switch (bytemode)
|
1730 | dc99065b | bellard | { |
1731 | dc99065b | bellard | case b_mode:
|
1732 | dc99065b | bellard | oappend (names8[rm]); |
1733 | dc99065b | bellard | break;
|
1734 | dc99065b | bellard | case w_mode:
|
1735 | dc99065b | bellard | oappend (names16[rm]); |
1736 | dc99065b | bellard | break;
|
1737 | dc99065b | bellard | case v_mode:
|
1738 | dc99065b | bellard | if (dflag)
|
1739 | dc99065b | bellard | oappend (names32[rm]); |
1740 | dc99065b | bellard | else
|
1741 | dc99065b | bellard | oappend (names16[rm]); |
1742 | dc99065b | bellard | break;
|
1743 | dc99065b | bellard | default:
|
1744 | dc99065b | bellard | oappend ("<bad dis table>");
|
1745 | dc99065b | bellard | break;
|
1746 | dc99065b | bellard | } |
1747 | dc99065b | bellard | return 0; |
1748 | dc99065b | bellard | } |
1749 | dc99065b | bellard | |
1750 | dc99065b | bellard | disp = 0;
|
1751 | dc99065b | bellard | append_prefix (); |
1752 | dc99065b | bellard | |
1753 | dc99065b | bellard | if (aflag) /* 32 bit address mode */ |
1754 | dc99065b | bellard | { |
1755 | dc99065b | bellard | int havesib;
|
1756 | dc99065b | bellard | int havebase;
|
1757 | dc99065b | bellard | int base;
|
1758 | dc99065b | bellard | int index = 0; |
1759 | dc99065b | bellard | int scale = 0; |
1760 | dc99065b | bellard | |
1761 | dc99065b | bellard | havesib = 0;
|
1762 | dc99065b | bellard | havebase = 1;
|
1763 | dc99065b | bellard | base = rm; |
1764 | dc99065b | bellard | |
1765 | dc99065b | bellard | if (base == 4) |
1766 | dc99065b | bellard | { |
1767 | dc99065b | bellard | havesib = 1;
|
1768 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
1769 | dc99065b | bellard | scale = (*codep >> 6) & 3; |
1770 | dc99065b | bellard | index = (*codep >> 3) & 7; |
1771 | dc99065b | bellard | base = *codep & 7;
|
1772 | dc99065b | bellard | codep++; |
1773 | dc99065b | bellard | } |
1774 | dc99065b | bellard | |
1775 | dc99065b | bellard | switch (mod)
|
1776 | dc99065b | bellard | { |
1777 | dc99065b | bellard | case 0: |
1778 | dc99065b | bellard | if (base == 5) |
1779 | dc99065b | bellard | { |
1780 | dc99065b | bellard | havebase = 0;
|
1781 | dc99065b | bellard | disp = get32 (); |
1782 | dc99065b | bellard | } |
1783 | dc99065b | bellard | break;
|
1784 | dc99065b | bellard | case 1: |
1785 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
1786 | dc99065b | bellard | disp = *codep++; |
1787 | dc99065b | bellard | if ((disp & 0x80) != 0) |
1788 | dc99065b | bellard | disp -= 0x100;
|
1789 | dc99065b | bellard | break;
|
1790 | dc99065b | bellard | case 2: |
1791 | dc99065b | bellard | disp = get32 (); |
1792 | dc99065b | bellard | break;
|
1793 | dc99065b | bellard | } |
1794 | dc99065b | bellard | |
1795 | dc99065b | bellard | if (mod != 0 || base == 5) |
1796 | dc99065b | bellard | { |
1797 | dc99065b | bellard | sprintf (scratchbuf, "0x%x", disp);
|
1798 | dc99065b | bellard | oappend (scratchbuf); |
1799 | dc99065b | bellard | } |
1800 | dc99065b | bellard | |
1801 | dc99065b | bellard | if (havebase || (havesib && (index != 4 || scale != 0))) |
1802 | dc99065b | bellard | { |
1803 | dc99065b | bellard | oappend ("(");
|
1804 | dc99065b | bellard | if (havebase)
|
1805 | dc99065b | bellard | oappend (names32[base]); |
1806 | dc99065b | bellard | if (havesib)
|
1807 | dc99065b | bellard | { |
1808 | dc99065b | bellard | if (index != 4) |
1809 | dc99065b | bellard | { |
1810 | dc99065b | bellard | sprintf (scratchbuf, ",%s", names32[index]);
|
1811 | dc99065b | bellard | oappend (scratchbuf); |
1812 | dc99065b | bellard | } |
1813 | dc99065b | bellard | sprintf (scratchbuf, ",%d", 1 << scale); |
1814 | dc99065b | bellard | oappend (scratchbuf); |
1815 | dc99065b | bellard | } |
1816 | dc99065b | bellard | oappend (")");
|
1817 | dc99065b | bellard | } |
1818 | dc99065b | bellard | } |
1819 | dc99065b | bellard | else
|
1820 | dc99065b | bellard | { /* 16 bit address mode */
|
1821 | dc99065b | bellard | switch (mod)
|
1822 | dc99065b | bellard | { |
1823 | dc99065b | bellard | case 0: |
1824 | dc99065b | bellard | if (rm == 6) |
1825 | dc99065b | bellard | { |
1826 | dc99065b | bellard | disp = get16 (); |
1827 | dc99065b | bellard | if ((disp & 0x8000) != 0) |
1828 | dc99065b | bellard | disp -= 0x10000;
|
1829 | dc99065b | bellard | } |
1830 | dc99065b | bellard | break;
|
1831 | dc99065b | bellard | case 1: |
1832 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
1833 | dc99065b | bellard | disp = *codep++; |
1834 | dc99065b | bellard | if ((disp & 0x80) != 0) |
1835 | dc99065b | bellard | disp -= 0x100;
|
1836 | dc99065b | bellard | break;
|
1837 | dc99065b | bellard | case 2: |
1838 | dc99065b | bellard | disp = get16 (); |
1839 | dc99065b | bellard | if ((disp & 0x8000) != 0) |
1840 | dc99065b | bellard | disp -= 0x10000;
|
1841 | dc99065b | bellard | break;
|
1842 | dc99065b | bellard | } |
1843 | dc99065b | bellard | |
1844 | dc99065b | bellard | if (mod != 0 || rm == 6) |
1845 | dc99065b | bellard | { |
1846 | dc99065b | bellard | sprintf (scratchbuf, "0x%x", disp);
|
1847 | dc99065b | bellard | oappend (scratchbuf); |
1848 | dc99065b | bellard | } |
1849 | dc99065b | bellard | |
1850 | dc99065b | bellard | if (mod != 0 || rm != 6) |
1851 | dc99065b | bellard | { |
1852 | dc99065b | bellard | oappend ("(");
|
1853 | dc99065b | bellard | oappend (index16[rm]); |
1854 | dc99065b | bellard | oappend (")");
|
1855 | dc99065b | bellard | } |
1856 | dc99065b | bellard | } |
1857 | dc99065b | bellard | return 0; |
1858 | dc99065b | bellard | } |
1859 | dc99065b | bellard | |
1860 | dc99065b | bellard | static int |
1861 | dc99065b | bellard | OP_G (bytemode, aflag, dflag) |
1862 | dc99065b | bellard | int bytemode;
|
1863 | dc99065b | bellard | int aflag;
|
1864 | dc99065b | bellard | int dflag;
|
1865 | dc99065b | bellard | { |
1866 | dc99065b | bellard | switch (bytemode)
|
1867 | dc99065b | bellard | { |
1868 | dc99065b | bellard | case b_mode:
|
1869 | dc99065b | bellard | oappend (names8[reg]); |
1870 | dc99065b | bellard | break;
|
1871 | dc99065b | bellard | case w_mode:
|
1872 | dc99065b | bellard | oappend (names16[reg]); |
1873 | dc99065b | bellard | break;
|
1874 | dc99065b | bellard | case d_mode:
|
1875 | dc99065b | bellard | oappend (names32[reg]); |
1876 | dc99065b | bellard | break;
|
1877 | dc99065b | bellard | case v_mode:
|
1878 | dc99065b | bellard | if (dflag)
|
1879 | dc99065b | bellard | oappend (names32[reg]); |
1880 | dc99065b | bellard | else
|
1881 | dc99065b | bellard | oappend (names16[reg]); |
1882 | dc99065b | bellard | break;
|
1883 | dc99065b | bellard | default:
|
1884 | dc99065b | bellard | oappend ("<internal disassembler error>");
|
1885 | dc99065b | bellard | break;
|
1886 | dc99065b | bellard | } |
1887 | dc99065b | bellard | return (0); |
1888 | dc99065b | bellard | } |
1889 | dc99065b | bellard | |
1890 | dc99065b | bellard | static int |
1891 | dc99065b | bellard | get32 () |
1892 | dc99065b | bellard | { |
1893 | dc99065b | bellard | int x = 0; |
1894 | dc99065b | bellard | |
1895 | dc99065b | bellard | FETCH_DATA (the_info, codep + 4);
|
1896 | dc99065b | bellard | x = *codep++ & 0xff;
|
1897 | dc99065b | bellard | x |= (*codep++ & 0xff) << 8; |
1898 | dc99065b | bellard | x |= (*codep++ & 0xff) << 16; |
1899 | dc99065b | bellard | x |= (*codep++ & 0xff) << 24; |
1900 | dc99065b | bellard | return (x);
|
1901 | dc99065b | bellard | } |
1902 | dc99065b | bellard | |
1903 | dc99065b | bellard | static int |
1904 | dc99065b | bellard | get16 () |
1905 | dc99065b | bellard | { |
1906 | dc99065b | bellard | int x = 0; |
1907 | dc99065b | bellard | |
1908 | dc99065b | bellard | FETCH_DATA (the_info, codep + 2);
|
1909 | dc99065b | bellard | x = *codep++ & 0xff;
|
1910 | dc99065b | bellard | x |= (*codep++ & 0xff) << 8; |
1911 | dc99065b | bellard | return (x);
|
1912 | dc99065b | bellard | } |
1913 | dc99065b | bellard | |
1914 | dc99065b | bellard | static void |
1915 | dc99065b | bellard | set_op (op) |
1916 | dc99065b | bellard | int op;
|
1917 | dc99065b | bellard | { |
1918 | dc99065b | bellard | op_index[op_ad] = op_ad; |
1919 | dc99065b | bellard | op_address[op_ad] = op; |
1920 | dc99065b | bellard | } |
1921 | dc99065b | bellard | |
1922 | dc99065b | bellard | static int |
1923 | dc99065b | bellard | OP_REG (code, aflag, dflag) |
1924 | dc99065b | bellard | int code;
|
1925 | dc99065b | bellard | int aflag;
|
1926 | dc99065b | bellard | int dflag;
|
1927 | dc99065b | bellard | { |
1928 | dc99065b | bellard | char *s;
|
1929 | dc99065b | bellard | |
1930 | dc99065b | bellard | switch (code)
|
1931 | dc99065b | bellard | { |
1932 | dc99065b | bellard | case indir_dx_reg: s = "(%dx)"; break; |
1933 | dc99065b | bellard | case ax_reg: case cx_reg: case dx_reg: case bx_reg: |
1934 | dc99065b | bellard | case sp_reg: case bp_reg: case si_reg: case di_reg: |
1935 | dc99065b | bellard | s = names16[code - ax_reg]; |
1936 | dc99065b | bellard | break;
|
1937 | dc99065b | bellard | case es_reg: case ss_reg: case cs_reg: |
1938 | dc99065b | bellard | case ds_reg: case fs_reg: case gs_reg: |
1939 | dc99065b | bellard | s = names_seg[code - es_reg]; |
1940 | dc99065b | bellard | break;
|
1941 | dc99065b | bellard | case al_reg: case ah_reg: case cl_reg: case ch_reg: |
1942 | dc99065b | bellard | case dl_reg: case dh_reg: case bl_reg: case bh_reg: |
1943 | dc99065b | bellard | s = names8[code - al_reg]; |
1944 | dc99065b | bellard | break;
|
1945 | dc99065b | bellard | case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: |
1946 | dc99065b | bellard | case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: |
1947 | dc99065b | bellard | if (dflag)
|
1948 | dc99065b | bellard | s = names32[code - eAX_reg]; |
1949 | dc99065b | bellard | else
|
1950 | dc99065b | bellard | s = names16[code - eAX_reg]; |
1951 | dc99065b | bellard | break;
|
1952 | dc99065b | bellard | default:
|
1953 | dc99065b | bellard | s = "<internal disassembler error>";
|
1954 | dc99065b | bellard | break;
|
1955 | dc99065b | bellard | } |
1956 | dc99065b | bellard | oappend (s); |
1957 | dc99065b | bellard | return (0); |
1958 | dc99065b | bellard | } |
1959 | dc99065b | bellard | |
1960 | dc99065b | bellard | static int |
1961 | dc99065b | bellard | OP_I (bytemode, aflag, dflag) |
1962 | dc99065b | bellard | int bytemode;
|
1963 | dc99065b | bellard | int aflag;
|
1964 | dc99065b | bellard | int dflag;
|
1965 | dc99065b | bellard | { |
1966 | dc99065b | bellard | int op;
|
1967 | dc99065b | bellard | |
1968 | dc99065b | bellard | switch (bytemode)
|
1969 | dc99065b | bellard | { |
1970 | dc99065b | bellard | case b_mode:
|
1971 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
1972 | dc99065b | bellard | op = *codep++ & 0xff;
|
1973 | dc99065b | bellard | break;
|
1974 | dc99065b | bellard | case v_mode:
|
1975 | dc99065b | bellard | if (dflag)
|
1976 | dc99065b | bellard | op = get32 (); |
1977 | dc99065b | bellard | else
|
1978 | dc99065b | bellard | op = get16 (); |
1979 | dc99065b | bellard | break;
|
1980 | dc99065b | bellard | case w_mode:
|
1981 | dc99065b | bellard | op = get16 (); |
1982 | dc99065b | bellard | break;
|
1983 | dc99065b | bellard | default:
|
1984 | dc99065b | bellard | oappend ("<internal disassembler error>");
|
1985 | dc99065b | bellard | return (0); |
1986 | dc99065b | bellard | } |
1987 | dc99065b | bellard | sprintf (scratchbuf, "$0x%x", op);
|
1988 | dc99065b | bellard | oappend (scratchbuf); |
1989 | dc99065b | bellard | return (0); |
1990 | dc99065b | bellard | } |
1991 | dc99065b | bellard | |
1992 | dc99065b | bellard | static int |
1993 | dc99065b | bellard | OP_sI (bytemode, aflag, dflag) |
1994 | dc99065b | bellard | int bytemode;
|
1995 | dc99065b | bellard | int aflag;
|
1996 | dc99065b | bellard | int dflag;
|
1997 | dc99065b | bellard | { |
1998 | dc99065b | bellard | int op;
|
1999 | dc99065b | bellard | |
2000 | dc99065b | bellard | switch (bytemode)
|
2001 | dc99065b | bellard | { |
2002 | dc99065b | bellard | case b_mode:
|
2003 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
2004 | dc99065b | bellard | op = *codep++; |
2005 | dc99065b | bellard | if ((op & 0x80) != 0) |
2006 | dc99065b | bellard | op -= 0x100;
|
2007 | dc99065b | bellard | break;
|
2008 | dc99065b | bellard | case v_mode:
|
2009 | dc99065b | bellard | if (dflag)
|
2010 | dc99065b | bellard | op = get32 (); |
2011 | dc99065b | bellard | else
|
2012 | dc99065b | bellard | { |
2013 | dc99065b | bellard | op = get16(); |
2014 | dc99065b | bellard | if ((op & 0x8000) != 0) |
2015 | dc99065b | bellard | op -= 0x10000;
|
2016 | dc99065b | bellard | } |
2017 | dc99065b | bellard | break;
|
2018 | dc99065b | bellard | case w_mode:
|
2019 | dc99065b | bellard | op = get16 (); |
2020 | dc99065b | bellard | if ((op & 0x8000) != 0) |
2021 | dc99065b | bellard | op -= 0x10000;
|
2022 | dc99065b | bellard | break;
|
2023 | dc99065b | bellard | default:
|
2024 | dc99065b | bellard | oappend ("<internal disassembler error>");
|
2025 | dc99065b | bellard | return (0); |
2026 | dc99065b | bellard | } |
2027 | dc99065b | bellard | sprintf (scratchbuf, "$0x%x", op);
|
2028 | dc99065b | bellard | oappend (scratchbuf); |
2029 | dc99065b | bellard | return (0); |
2030 | dc99065b | bellard | } |
2031 | dc99065b | bellard | |
2032 | dc99065b | bellard | static int |
2033 | dc99065b | bellard | OP_J (bytemode, aflag, dflag) |
2034 | dc99065b | bellard | int bytemode;
|
2035 | dc99065b | bellard | int aflag;
|
2036 | dc99065b | bellard | int dflag;
|
2037 | dc99065b | bellard | { |
2038 | dc99065b | bellard | int disp;
|
2039 | dc99065b | bellard | int mask = -1; |
2040 | dc99065b | bellard | |
2041 | dc99065b | bellard | switch (bytemode)
|
2042 | dc99065b | bellard | { |
2043 | dc99065b | bellard | case b_mode:
|
2044 | dc99065b | bellard | FETCH_DATA (the_info, codep + 1);
|
2045 | dc99065b | bellard | disp = *codep++; |
2046 | dc99065b | bellard | if ((disp & 0x80) != 0) |
2047 | dc99065b | bellard | disp -= 0x100;
|
2048 | dc99065b | bellard | break;
|
2049 | dc99065b | bellard | case v_mode:
|
2050 | dc99065b | bellard | if (dflag)
|
2051 | dc99065b | bellard | disp = get32 (); |
2052 | dc99065b | bellard | else
|
2053 | dc99065b | bellard | { |
2054 | dc99065b | bellard | disp = get16 (); |
2055 | dc99065b | bellard | if ((disp & 0x8000) != 0) |
2056 | dc99065b | bellard | disp -= 0x10000;
|
2057 | dc99065b | bellard | /* for some reason, a data16 prefix on a jump instruction
|
2058 | dc99065b | bellard | means that the pc is masked to 16 bits after the
|
2059 | dc99065b | bellard | displacement is added! */
|
2060 | dc99065b | bellard | mask = 0xffff;
|
2061 | dc99065b | bellard | } |
2062 | dc99065b | bellard | break;
|
2063 | dc99065b | bellard | default:
|
2064 | dc99065b | bellard | oappend ("<internal disassembler error>");
|
2065 | dc99065b | bellard | return (0); |
2066 | dc99065b | bellard | } |
2067 | dc99065b | bellard | disp = (start_pc + codep - start_codep + disp) & mask; |
2068 | dc99065b | bellard | set_op (disp); |
2069 | dc99065b | bellard | sprintf (scratchbuf, "0x%x", disp);
|
2070 | dc99065b | bellard | oappend (scratchbuf); |
2071 | dc99065b | bellard | return (0); |
2072 | dc99065b | bellard | } |
2073 | dc99065b | bellard | |
2074 | dc99065b | bellard | /* ARGSUSED */
|
2075 | dc99065b | bellard | static int |
2076 | dc99065b | bellard | OP_SEG (dummy, aflag, dflag) |
2077 | dc99065b | bellard | int dummy;
|
2078 | dc99065b | bellard | int aflag;
|
2079 | dc99065b | bellard | int dflag;
|
2080 | dc99065b | bellard | { |
2081 | dc99065b | bellard | static char *sreg[] = { |
2082 | dc99065b | bellard | "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", |
2083 | dc99065b | bellard | }; |
2084 | dc99065b | bellard | |
2085 | dc99065b | bellard | oappend (sreg[reg]); |
2086 | dc99065b | bellard | return (0); |
2087 | dc99065b | bellard | } |
2088 | dc99065b | bellard | |
2089 | dc99065b | bellard | static int |
2090 | dc99065b | bellard | OP_DIR (size, aflag, dflag) |
2091 | dc99065b | bellard | int size;
|
2092 | dc99065b | bellard | int aflag;
|
2093 | dc99065b | bellard | int dflag;
|
2094 | dc99065b | bellard | { |
2095 | dc99065b | bellard | int seg, offset;
|
2096 | dc99065b | bellard | |
2097 | dc99065b | bellard | switch (size)
|
2098 | dc99065b | bellard | { |
2099 | dc99065b | bellard | case lptr:
|
2100 | dc99065b | bellard | if (aflag)
|
2101 | dc99065b | bellard | { |
2102 | dc99065b | bellard | offset = get32 (); |
2103 | dc99065b | bellard | seg = get16 (); |
2104 | dc99065b | bellard | } |
2105 | dc99065b | bellard | else
|
2106 | dc99065b | bellard | { |
2107 | dc99065b | bellard | offset = get16 (); |
2108 | dc99065b | bellard | seg = get16 (); |
2109 | dc99065b | bellard | } |
2110 | dc99065b | bellard | sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
|
2111 | dc99065b | bellard | oappend (scratchbuf); |
2112 | dc99065b | bellard | break;
|
2113 | dc99065b | bellard | case v_mode:
|
2114 | dc99065b | bellard | if (aflag)
|
2115 | dc99065b | bellard | offset = get32 (); |
2116 | dc99065b | bellard | else
|
2117 | dc99065b | bellard | { |
2118 | dc99065b | bellard | offset = get16 (); |
2119 | dc99065b | bellard | if ((offset & 0x8000) != 0) |
2120 | dc99065b | bellard | offset -= 0x10000;
|
2121 | dc99065b | bellard | } |
2122 | dc99065b | bellard | |
2123 | dc99065b | bellard | offset = start_pc + codep - start_codep + offset; |
2124 | dc99065b | bellard | set_op (offset); |
2125 | dc99065b | bellard | sprintf (scratchbuf, "0x%x", offset);
|
2126 | dc99065b | bellard | oappend (scratchbuf); |
2127 | dc99065b | bellard | break;
|
2128 | dc99065b | bellard | default:
|
2129 | dc99065b | bellard | oappend ("<internal disassembler error>");
|
2130 | dc99065b | bellard | break;
|
2131 | dc99065b | bellard | } |
2132 | dc99065b | bellard | return (0); |
2133 | dc99065b | bellard | } |
2134 | dc99065b | bellard | |
2135 | dc99065b | bellard | /* ARGSUSED */
|
2136 | dc99065b | bellard | static int |
2137 | dc99065b | bellard | OP_OFF (bytemode, aflag, dflag) |
2138 | dc99065b | bellard | int bytemode;
|
2139 | dc99065b | bellard | int aflag;
|
2140 | dc99065b | bellard | int dflag;
|
2141 | dc99065b | bellard | { |
2142 | dc99065b | bellard | int off;
|
2143 | dc99065b | bellard | |
2144 | dc99065b | bellard | append_prefix (); |
2145 | dc99065b | bellard | |
2146 | dc99065b | bellard | if (aflag)
|
2147 | dc99065b | bellard | off = get32 (); |
2148 | dc99065b | bellard | else
|
2149 | dc99065b | bellard | off = get16 (); |
2150 | dc99065b | bellard | |
2151 | dc99065b | bellard | sprintf (scratchbuf, "0x%x", off);
|
2152 | dc99065b | bellard | oappend (scratchbuf); |
2153 | dc99065b | bellard | return (0); |
2154 | dc99065b | bellard | } |
2155 | dc99065b | bellard | |
2156 | dc99065b | bellard | /* ARGSUSED */
|
2157 | dc99065b | bellard | static int |
2158 | dc99065b | bellard | OP_ESDI (dummy, aflag, dflag) |
2159 | dc99065b | bellard | int dummy;
|
2160 | dc99065b | bellard | int aflag;
|
2161 | dc99065b | bellard | int dflag;
|
2162 | dc99065b | bellard | { |
2163 | dc99065b | bellard | oappend ("%es:(");
|
2164 | dc99065b | bellard | oappend (aflag ? "%edi" : "%di"); |
2165 | dc99065b | bellard | oappend (")");
|
2166 | dc99065b | bellard | return (0); |
2167 | dc99065b | bellard | } |
2168 | dc99065b | bellard | |
2169 | dc99065b | bellard | /* ARGSUSED */
|
2170 | dc99065b | bellard | static int |
2171 | dc99065b | bellard | OP_DSSI (dummy, aflag, dflag) |
2172 | dc99065b | bellard | int dummy;
|
2173 | dc99065b | bellard | int aflag;
|
2174 | dc99065b | bellard | int dflag;
|
2175 | dc99065b | bellard | { |
2176 | dc99065b | bellard | if ((prefixes
|
2177 | dc99065b | bellard | & (PREFIX_CS |
2178 | dc99065b | bellard | | PREFIX_DS |
2179 | dc99065b | bellard | | PREFIX_SS |
2180 | dc99065b | bellard | | PREFIX_ES |
2181 | dc99065b | bellard | | PREFIX_FS |
2182 | dc99065b | bellard | | PREFIX_GS)) == 0)
|
2183 | dc99065b | bellard | prefixes |= PREFIX_DS; |
2184 | dc99065b | bellard | append_prefix (); |
2185 | dc99065b | bellard | oappend ("(");
|
2186 | dc99065b | bellard | oappend (aflag ? "%esi" : "%si"); |
2187 | dc99065b | bellard | oappend (")");
|
2188 | dc99065b | bellard | return (0); |
2189 | dc99065b | bellard | } |
2190 | dc99065b | bellard | |
2191 | dc99065b | bellard | #if 0
|
2192 | dc99065b | bellard | /* Not used. */
|
2193 | dc99065b | bellard | |
2194 | dc99065b | bellard | /* ARGSUSED */
|
2195 | dc99065b | bellard | static int
|
2196 | dc99065b | bellard | OP_ONE (dummy, aflag, dflag)
|
2197 | dc99065b | bellard | int dummy;
|
2198 | dc99065b | bellard | int aflag;
|
2199 | dc99065b | bellard | int dflag;
|
2200 | dc99065b | bellard | {
|
2201 | dc99065b | bellard | oappend ("1");
|
2202 | dc99065b | bellard | return (0);
|
2203 | dc99065b | bellard | }
|
2204 | dc99065b | bellard | |
2205 | dc99065b | bellard | #endif
|
2206 | dc99065b | bellard | |
2207 | dc99065b | bellard | /* ARGSUSED */
|
2208 | dc99065b | bellard | static int |
2209 | dc99065b | bellard | OP_C (dummy, aflag, dflag) |
2210 | dc99065b | bellard | int dummy;
|
2211 | dc99065b | bellard | int aflag;
|
2212 | dc99065b | bellard | int dflag;
|
2213 | dc99065b | bellard | { |
2214 | dc99065b | bellard | codep++; /* skip mod/rm */
|
2215 | dc99065b | bellard | sprintf (scratchbuf, "%%cr%d", reg);
|
2216 | dc99065b | bellard | oappend (scratchbuf); |
2217 | dc99065b | bellard | return (0); |
2218 | dc99065b | bellard | } |
2219 | dc99065b | bellard | |
2220 | dc99065b | bellard | /* ARGSUSED */
|
2221 | dc99065b | bellard | static int |
2222 | dc99065b | bellard | OP_D (dummy, aflag, dflag) |
2223 | dc99065b | bellard | int dummy;
|
2224 | dc99065b | bellard | int aflag;
|
2225 | dc99065b | bellard | int dflag;
|
2226 | dc99065b | bellard | { |
2227 | dc99065b | bellard | codep++; /* skip mod/rm */
|
2228 | dc99065b | bellard | sprintf (scratchbuf, "%%db%d", reg);
|
2229 | dc99065b | bellard | oappend (scratchbuf); |
2230 | dc99065b | bellard | return (0); |
2231 | dc99065b | bellard | } |
2232 | dc99065b | bellard | |
2233 | dc99065b | bellard | /* ARGSUSED */
|
2234 | dc99065b | bellard | static int |
2235 | dc99065b | bellard | OP_T (dummy, aflag, dflag) |
2236 | dc99065b | bellard | int dummy;
|
2237 | dc99065b | bellard | int aflag;
|
2238 | dc99065b | bellard | int dflag;
|
2239 | dc99065b | bellard | { |
2240 | dc99065b | bellard | codep++; /* skip mod/rm */
|
2241 | dc99065b | bellard | sprintf (scratchbuf, "%%tr%d", reg);
|
2242 | dc99065b | bellard | oappend (scratchbuf); |
2243 | dc99065b | bellard | return (0); |
2244 | dc99065b | bellard | } |
2245 | dc99065b | bellard | |
2246 | dc99065b | bellard | static int |
2247 | dc99065b | bellard | OP_rm (bytemode, aflag, dflag) |
2248 | dc99065b | bellard | int bytemode;
|
2249 | dc99065b | bellard | int aflag;
|
2250 | dc99065b | bellard | int dflag;
|
2251 | dc99065b | bellard | { |
2252 | dc99065b | bellard | switch (bytemode)
|
2253 | dc99065b | bellard | { |
2254 | dc99065b | bellard | case d_mode:
|
2255 | dc99065b | bellard | oappend (names32[rm]); |
2256 | dc99065b | bellard | break;
|
2257 | dc99065b | bellard | case w_mode:
|
2258 | dc99065b | bellard | oappend (names16[rm]); |
2259 | dc99065b | bellard | break;
|
2260 | dc99065b | bellard | } |
2261 | dc99065b | bellard | return (0); |
2262 | dc99065b | bellard | } |
2263 | dc99065b | bellard | |
2264 | dc99065b | bellard | static int |
2265 | dc99065b | bellard | OP_MMX (bytemode, aflag, dflag) |
2266 | dc99065b | bellard | int bytemode;
|
2267 | dc99065b | bellard | int aflag;
|
2268 | dc99065b | bellard | int dflag;
|
2269 | dc99065b | bellard | { |
2270 | dc99065b | bellard | sprintf (scratchbuf, "%%mm%d", reg);
|
2271 | dc99065b | bellard | oappend (scratchbuf); |
2272 | dc99065b | bellard | return 0; |
2273 | dc99065b | bellard | } |
2274 | dc99065b | bellard | |
2275 | dc99065b | bellard | static int |
2276 | dc99065b | bellard | OP_EM (bytemode, aflag, dflag) |
2277 | dc99065b | bellard | int bytemode;
|
2278 | dc99065b | bellard | int aflag;
|
2279 | dc99065b | bellard | int dflag;
|
2280 | dc99065b | bellard | { |
2281 | dc99065b | bellard | if (mod != 3) |
2282 | dc99065b | bellard | return OP_E (bytemode, aflag, dflag);
|
2283 | dc99065b | bellard | |
2284 | dc99065b | bellard | codep++; |
2285 | dc99065b | bellard | sprintf (scratchbuf, "%%mm%d", rm);
|
2286 | dc99065b | bellard | oappend (scratchbuf); |
2287 | dc99065b | bellard | return 0; |
2288 | dc99065b | bellard | } |
2289 | dc99065b | bellard | |
2290 | dc99065b | bellard | static int |
2291 | dc99065b | bellard | OP_MS (bytemode, aflag, dflag) |
2292 | dc99065b | bellard | int bytemode;
|
2293 | dc99065b | bellard | int aflag;
|
2294 | dc99065b | bellard | int dflag;
|
2295 | dc99065b | bellard | { |
2296 | dc99065b | bellard | ++codep; |
2297 | dc99065b | bellard | sprintf (scratchbuf, "%%mm%d", rm);
|
2298 | dc99065b | bellard | oappend (scratchbuf); |
2299 | dc99065b | bellard | return 0; |
2300 | dc99065b | bellard | } |