|
1 |
/* This file is composed of several different files from the upstream
|
|
2 |
sourceware.org CVS. Original file boundaries marked with **** */
|
|
3 |
|
|
4 |
#include <string.h>
|
|
5 |
#include <math.h>
|
|
6 |
#include <stdio.h>
|
|
7 |
|
|
8 |
#include "dis-asm.h"
|
|
9 |
|
|
10 |
/* **** foatformat.h from sourceware.org CVS 2005-08-14. */
|
|
11 |
/* IEEE floating point support declarations, for GDB, the GNU Debugger.
|
|
12 |
Copyright 1991, 1994, 1995, 1997, 2000, 2003 Free Software Foundation, Inc.
|
|
13 |
|
|
14 |
This file is part of GDB.
|
|
15 |
|
|
16 |
This program is free software; you can redistribute it and/or modify
|
|
17 |
it under the terms of the GNU General Public License as published by
|
|
18 |
the Free Software Foundation; either version 2 of the License, or
|
|
19 |
(at your option) any later version.
|
|
20 |
|
|
21 |
This program is distributed in the hope that it will be useful,
|
|
22 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
24 |
GNU General Public License for more details.
|
|
25 |
|
|
26 |
You should have received a copy of the GNU General Public License
|
|
27 |
along with this program; if not, write to the Free Software
|
|
28 |
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
|
29 |
|
|
30 |
#if !defined (FLOATFORMAT_H)
|
|
31 |
#define FLOATFORMAT_H 1
|
|
32 |
|
|
33 |
/*#include "ansidecl.h" */
|
|
34 |
|
|
35 |
/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the
|
|
36 |
bytes are concatenated according to the byteorder flag, then each of those
|
|
37 |
fields is contiguous. We number the bits with 0 being the most significant
|
|
38 |
(i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field
|
|
39 |
contains with the *_start and *_len fields. */
|
|
40 |
|
|
41 |
/* What is the order of the bytes. */
|
|
42 |
|
|
43 |
enum floatformat_byteorders {
|
|
44 |
|
|
45 |
/* Standard little endian byte order.
|
|
46 |
EX: 1.2345678e10 => 00 00 80 c5 e0 fe 06 42 */
|
|
47 |
|
|
48 |
floatformat_little,
|
|
49 |
|
|
50 |
/* Standard big endian byte order.
|
|
51 |
EX: 1.2345678e10 => 42 06 fe e0 c5 80 00 00 */
|
|
52 |
|
|
53 |
floatformat_big,
|
|
54 |
|
|
55 |
/* Little endian byte order but big endian word order.
|
|
56 |
EX: 1.2345678e10 => e0 fe 06 42 00 00 80 c5 */
|
|
57 |
|
|
58 |
floatformat_littlebyte_bigword
|
|
59 |
|
|
60 |
};
|
|
61 |
|
|
62 |
enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no };
|
|
63 |
|
|
64 |
struct floatformat
|
|
65 |
{
|
|
66 |
enum floatformat_byteorders byteorder;
|
|
67 |
unsigned int totalsize; /* Total size of number in bits */
|
|
68 |
|
|
69 |
/* Sign bit is always one bit long. 1 means negative, 0 means positive. */
|
|
70 |
unsigned int sign_start;
|
|
71 |
|
|
72 |
unsigned int exp_start;
|
|
73 |
unsigned int exp_len;
|
|
74 |
/* Bias added to a "true" exponent to form the biased exponent. It
|
|
75 |
is intentionally signed as, otherwize, -exp_bias can turn into a
|
|
76 |
very large number (e.g., given the exp_bias of 0x3fff and a 64
|
|
77 |
bit long, the equation (long)(1 - exp_bias) evaluates to
|
|
78 |
4294950914) instead of -16382). */
|
|
79 |
int exp_bias;
|
|
80 |
/* Exponent value which indicates NaN. This is the actual value stored in
|
|
81 |
the float, not adjusted by the exp_bias. This usually consists of all
|
|
82 |
one bits. */
|
|
83 |
unsigned int exp_nan;
|
|
84 |
|
|
85 |
unsigned int man_start;
|
|
86 |
unsigned int man_len;
|
|
87 |
|
|
88 |
/* Is the integer bit explicit or implicit? */
|
|
89 |
enum floatformat_intbit intbit;
|
|
90 |
|
|
91 |
/* Internal name for debugging. */
|
|
92 |
const char *name;
|
|
93 |
|
|
94 |
/* Validator method. */
|
|
95 |
int (*is_valid) (const struct floatformat *fmt, const char *from);
|
|
96 |
};
|
|
97 |
|
|
98 |
/* floatformats for IEEE single and double, big and little endian. */
|
|
99 |
|
|
100 |
extern const struct floatformat floatformat_ieee_single_big;
|
|
101 |
extern const struct floatformat floatformat_ieee_single_little;
|
|
102 |
extern const struct floatformat floatformat_ieee_double_big;
|
|
103 |
extern const struct floatformat floatformat_ieee_double_little;
|
|
104 |
|
|
105 |
/* floatformat for ARM IEEE double, little endian bytes and big endian words */
|
|
106 |
|
|
107 |
extern const struct floatformat floatformat_ieee_double_littlebyte_bigword;
|
|
108 |
|
|
109 |
/* floatformats for various extendeds. */
|
|
110 |
|
|
111 |
extern const struct floatformat floatformat_i387_ext;
|
|
112 |
extern const struct floatformat floatformat_m68881_ext;
|
|
113 |
extern const struct floatformat floatformat_i960_ext;
|
|
114 |
extern const struct floatformat floatformat_m88110_ext;
|
|
115 |
extern const struct floatformat floatformat_m88110_harris_ext;
|
|
116 |
extern const struct floatformat floatformat_arm_ext_big;
|
|
117 |
extern const struct floatformat floatformat_arm_ext_littlebyte_bigword;
|
|
118 |
/* IA-64 Floating Point register spilt into memory. */
|
|
119 |
extern const struct floatformat floatformat_ia64_spill_big;
|
|
120 |
extern const struct floatformat floatformat_ia64_spill_little;
|
|
121 |
extern const struct floatformat floatformat_ia64_quad_big;
|
|
122 |
extern const struct floatformat floatformat_ia64_quad_little;
|
|
123 |
|
|
124 |
/* Convert from FMT to a double.
|
|
125 |
FROM is the address of the extended float.
|
|
126 |
Store the double in *TO. */
|
|
127 |
|
|
128 |
extern void
|
|
129 |
floatformat_to_double (const struct floatformat *, const char *, double *);
|
|
130 |
|
|
131 |
/* The converse: convert the double *FROM to FMT
|
|
132 |
and store where TO points. */
|
|
133 |
|
|
134 |
extern void
|
|
135 |
floatformat_from_double (const struct floatformat *, const double *, char *);
|
|
136 |
|
|
137 |
/* Return non-zero iff the data at FROM is a valid number in format FMT. */
|
|
138 |
|
|
139 |
extern int
|
|
140 |
floatformat_is_valid (const struct floatformat *fmt, const char *from);
|
|
141 |
|
|
142 |
#endif /* defined (FLOATFORMAT_H) */
|
|
143 |
/* **** End of floatformat.h */
|
|
144 |
/* **** m68k-dis.h from sourceware.org CVS 2005-08-14. */
|
|
145 |
/* Opcode table header for m680[01234]0/m6888[12]/m68851.
|
|
146 |
Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2001,
|
|
147 |
2003, 2004 Free Software Foundation, Inc.
|
|
148 |
|
|
149 |
This file is part of GDB, GAS, and the GNU binutils.
|
|
150 |
|
|
151 |
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
|
152 |
them and/or modify them under the terms of the GNU General Public
|
|
153 |
License as published by the Free Software Foundation; either version
|
|
154 |
1, or (at your option) any later version.
|
|
155 |
|
|
156 |
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
|
157 |
will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
158 |
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
|
159 |
the GNU General Public License for more details.
|
|
160 |
|
|
161 |
You should have received a copy of the GNU General Public License
|
|
162 |
along with this file; see the file COPYING. If not, write to the Free
|
|
163 |
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
|
|
164 |
02110-1301, USA. */
|
|
165 |
|
|
166 |
/* These are used as bit flags for the arch field in the m68k_opcode
|
|
167 |
structure. */
|
|
168 |
#define _m68k_undef 0
|
|
169 |
#define m68000 0x001
|
|
170 |
#define m68008 m68000 /* Synonym for -m68000. otherwise unused. */
|
|
171 |
#define m68010 0x002
|
|
172 |
#define m68020 0x004
|
|
173 |
#define m68030 0x008
|
|
174 |
#define m68ec030 m68030 /* Similar enough to -m68030 to ignore differences;
|
|
175 |
gas will deal with the few differences. */
|
|
176 |
#define m68040 0x010
|
|
177 |
/* There is no 68050. */
|
|
178 |
#define m68060 0x020
|
|
179 |
#define m68881 0x040
|
|
180 |
#define m68882 m68881 /* Synonym for -m68881. otherwise unused. */
|
|
181 |
#define m68851 0x080
|
|
182 |
#define cpu32 0x100 /* e.g., 68332 */
|
|
183 |
|
|
184 |
#define mcfmac 0x200 /* ColdFire MAC. */
|
|
185 |
#define mcfemac 0x400 /* ColdFire EMAC. */
|
|
186 |
#define cfloat 0x800 /* ColdFire FPU. */
|
|
187 |
#define mcfhwdiv 0x1000 /* ColdFire hardware divide. */
|
|
188 |
|
|
189 |
#define mcfisa_a 0x2000 /* ColdFire ISA_A. */
|
|
190 |
#define mcfisa_aa 0x4000 /* ColdFire ISA_A+. */
|
|
191 |
#define mcfisa_b 0x8000 /* ColdFire ISA_B. */
|
|
192 |
#define mcfusp 0x10000 /* ColdFire USP instructions. */
|
|
193 |
|
|
194 |
#define mcf5200 0x20000
|
|
195 |
#define mcf5206e 0x40000
|
|
196 |
#define mcf521x 0x80000
|
|
197 |
#define mcf5249 0x100000
|
|
198 |
#define mcf528x 0x200000
|
|
199 |
#define mcf5307 0x400000
|
|
200 |
#define mcf5407 0x800000
|
|
201 |
#define mcf5470 0x1000000
|
|
202 |
#define mcf5480 0x2000000
|
|
203 |
|
|
204 |
/* Handy aliases. */
|
|
205 |
#define m68040up (m68040 | m68060)
|
|
206 |
#define m68030up (m68030 | m68040up)
|
|
207 |
#define m68020up (m68020 | m68030up)
|
|
208 |
#define m68010up (m68010 | cpu32 | m68020up)
|
|
209 |
#define m68000up (m68000 | m68010up)
|
|
210 |
|
|
211 |
#define mfloat (m68881 | m68882 | m68040 | m68060)
|
|
212 |
#define mmmu (m68851 | m68030 | m68040 | m68060)
|
|
213 |
|
|
214 |
/* The structure used to hold information for an opcode. */
|
|
215 |
|
|
216 |
struct m68k_opcode
|
|
217 |
{
|
|
218 |
/* The opcode name. */
|
|
219 |
const char *name;
|
|
220 |
/* The pseudo-size of the instruction(in bytes). Used to determine
|
|
221 |
number of bytes necessary to disassemble the instruction. */
|
|
222 |
unsigned int size;
|
|
223 |
/* The opcode itself. */
|
|
224 |
unsigned long opcode;
|
|
225 |
/* The mask used by the disassembler. */
|
|
226 |
unsigned long match;
|
|
227 |
/* The arguments. */
|
|
228 |
const char *args;
|
|
229 |
/* The architectures which support this opcode. */
|
|
230 |
unsigned int arch;
|
|
231 |
};
|
|
232 |
|
|
233 |
/* The structure used to hold information for an opcode alias. */
|
|
234 |
|
|
235 |
struct m68k_opcode_alias
|
|
236 |
{
|
|
237 |
/* The alias name. */
|
|
238 |
const char *alias;
|
|
239 |
/* The instruction for which this is an alias. */
|
|
240 |
const char *primary;
|
|
241 |
};
|
|
242 |
|
|
243 |
/* We store four bytes of opcode for all opcodes because that is the
|
|
244 |
most any of them need. The actual length of an instruction is
|
|
245 |
always at least 2 bytes, and is as much longer as necessary to hold
|
|
246 |
the operands it has.
|
|
247 |
|
|
248 |
The match field is a mask saying which bits must match particular
|
|
249 |
opcode in order for an instruction to be an instance of that
|
|
250 |
opcode.
|
|
251 |
|
|
252 |
The args field is a string containing two characters for each
|
|
253 |
operand of the instruction. The first specifies the kind of
|
|
254 |
operand; the second, the place it is stored. */
|
|
255 |
|
|
256 |
/* Kinds of operands:
|
|
257 |
Characters used: AaBbCcDdEeFfGgHIiJkLlMmnOopQqRrSsTtU VvWwXxYyZz01234|*~%;@!&$?/<>#^+-
|
|
258 |
|
|
259 |
D data register only. Stored as 3 bits.
|
|
260 |
A address register only. Stored as 3 bits.
|
|
261 |
a address register indirect only. Stored as 3 bits.
|
|
262 |
R either kind of register. Stored as 4 bits.
|
|
263 |
r either kind of register indirect only. Stored as 4 bits.
|
|
264 |
At the moment, used only for cas2 instruction.
|
|
265 |
F floating point coprocessor register only. Stored as 3 bits.
|
|
266 |
O an offset (or width): immediate data 0-31 or data register.
|
|
267 |
Stored as 6 bits in special format for BF... insns.
|
|
268 |
+ autoincrement only. Stored as 3 bits (number of the address register).
|
|
269 |
- autodecrement only. Stored as 3 bits (number of the address register).
|
|
270 |
Q quick immediate data. Stored as 3 bits.
|
|
271 |
This matches an immediate operand only when value is in range 1 .. 8.
|
|
272 |
M moveq immediate data. Stored as 8 bits.
|
|
273 |
This matches an immediate operand only when value is in range -128..127
|
|
274 |
T trap vector immediate data. Stored as 4 bits.
|
|
275 |
|
|
276 |
k K-factor for fmove.p instruction. Stored as a 7-bit constant or
|
|
277 |
a three bit register offset, depending on the field type.
|
|
278 |
|
|
279 |
# immediate data. Stored in special places (b, w or l)
|
|
280 |
which say how many bits to store.
|
|
281 |
^ immediate data for floating point instructions. Special places
|
|
282 |
are offset by 2 bytes from '#'...
|
|
283 |
B pc-relative address, converted to an offset
|
|
284 |
that is treated as immediate data.
|
|
285 |
d displacement and register. Stores the register as 3 bits
|
|
286 |
and stores the displacement in the entire second word.
|
|
287 |
|
|
288 |
C the CCR. No need to store it; this is just for filtering validity.
|
|
289 |
S the SR. No need to store, just as with CCR.
|
|
290 |
U the USP. No need to store, just as with CCR.
|
|
291 |
E the MAC ACC. No need to store, just as with CCR.
|
|
292 |
e the EMAC ACC[0123].
|
|
293 |
G the MAC/EMAC MACSR. No need to store, just as with CCR.
|
|
294 |
g the EMAC ACCEXT{01,23}.
|
|
295 |
H the MASK. No need to store, just as with CCR.
|
|
296 |
i the MAC/EMAC scale factor.
|
|
297 |
|
|
298 |
I Coprocessor ID. Not printed if 1. The Coprocessor ID is always
|
|
299 |
extracted from the 'd' field of word one, which means that an extended
|
|
300 |
coprocessor opcode can be skipped using the 'i' place, if needed.
|
|
301 |
|
|
302 |
s System Control register for the floating point coprocessor.
|
|
303 |
|
|
304 |
J Misc register for movec instruction, stored in 'j' format.
|
|
305 |
Possible values:
|
|
306 |
0x000 SFC Source Function Code reg [60, 40, 30, 20, 10]
|
|
307 |
0x001 DFC Data Function Code reg [60, 40, 30, 20, 10]
|
|
308 |
0x002 CACR Cache Control Register [60, 40, 30, 20, mcf]
|
|
309 |
0x003 TC MMU Translation Control [60, 40]
|
|
310 |
0x004 ITT0 Instruction Transparent
|
|
311 |
Translation reg 0 [60, 40]
|
|
312 |
0x005 ITT1 Instruction Transparent
|
|
313 |
Translation reg 1 [60, 40]
|
|
314 |
0x006 DTT0 Data Transparent
|
|
315 |
Translation reg 0 [60, 40]
|
|
316 |
0x007 DTT1 Data Transparent
|
|
317 |
Translation reg 1 [60, 40]
|
|
318 |
0x008 BUSCR Bus Control Register [60]
|
|
319 |
0x800 USP User Stack Pointer [60, 40, 30, 20, 10]
|
|
320 |
0x801 VBR Vector Base reg [60, 40, 30, 20, 10, mcf]
|
|
321 |
0x802 CAAR Cache Address Register [ 30, 20]
|
|
322 |
0x803 MSP Master Stack Pointer [ 40, 30, 20]
|
|
323 |
0x804 ISP Interrupt Stack Pointer [ 40, 30, 20]
|
|
324 |
0x805 MMUSR MMU Status reg [ 40]
|
|
325 |
0x806 URP User Root Pointer [60, 40]
|
|
326 |
0x807 SRP Supervisor Root Pointer [60, 40]
|
|
327 |
0x808 PCR Processor Configuration reg [60]
|
|
328 |
0xC00 ROMBAR ROM Base Address Register [520X]
|
|
329 |
0xC04 RAMBAR0 RAM Base Address Register 0 [520X]
|
|
330 |
0xC05 RAMBAR1 RAM Base Address Register 0 [520X]
|
|
331 |
0xC0F MBAR0 RAM Base Address Register 0 [520X]
|
|
332 |
0xC04 FLASHBAR FLASH Base Address Register [mcf528x]
|
|
333 |
0xC05 RAMBAR Static RAM Base Address Register [mcf528x]
|
|
334 |
|
|
335 |
L Register list of the type d0-d7/a0-a7 etc.
|
|
336 |
(New! Improved! Can also hold fp0-fp7, as well!)
|
|
337 |
The assembler tries to see if the registers match the insn by
|
|
338 |
looking at where the insn wants them stored.
|
|
339 |
|
|
340 |
l Register list like L, but with all the bits reversed.
|
|
341 |
Used for going the other way. . .
|
|
342 |
|
|
343 |
c cache identifier which may be "nc" for no cache, "ic"
|
|
344 |
for instruction cache, "dc" for data cache, or "bc"
|
|
345 |
for both caches. Used in cinv and cpush. Always
|
|
346 |
stored in position "d".
|
|
347 |
|
|
348 |
u Any register, with ``upper'' or ``lower'' specification. Used
|
|
349 |
in the mac instructions with size word.
|
|
350 |
|
|
351 |
The remainder are all stored as 6 bits using an address mode and a
|
|
352 |
register number; they differ in which addressing modes they match.
|
|
353 |
|
|
354 |
* all (modes 0-6,7.0-4)
|
|
355 |
~ alterable memory (modes 2-6,7.0,7.1)
|
|
356 |
(not 0,1,7.2-4)
|
|
357 |
% alterable (modes 0-6,7.0,7.1)
|
|
358 |
(not 7.2-4)
|
|
359 |
; data (modes 0,2-6,7.0-4)
|
|
360 |
(not 1)
|
|
361 |
@ data, but not immediate (modes 0,2-6,7.0-3)
|
|
362 |
(not 1,7.4)
|
|
363 |
! control (modes 2,5,6,7.0-3)
|
|
364 |
(not 0,1,3,4,7.4)
|
|
365 |
& alterable control (modes 2,5,6,7.0,7.1)
|
|
366 |
(not 0,1,3,4,7.2-4)
|
|
367 |
$ alterable data (modes 0,2-6,7.0,7.1)
|
|
368 |
(not 1,7.2-4)
|
|
369 |
? alterable control, or data register (modes 0,2,5,6,7.0,7.1)
|
|
370 |
(not 1,3,4,7.2-4)
|
|
371 |
/ control, or data register (modes 0,2,5,6,7.0-3)
|
|
372 |
(not 1,3,4,7.4)
|
|
373 |
> *save operands (modes 2,4,5,6,7.0,7.1)
|
|
374 |
(not 0,1,3,7.2-4)
|
|
375 |
< *restore operands (modes 2,3,5,6,7.0-3)
|
|
376 |
(not 0,1,4,7.4)
|
|
377 |
|
|
378 |
coldfire move operands:
|
|
379 |
m (modes 0-4)
|
|
380 |
n (modes 5,7.2)
|
|
381 |
o (modes 6,7.0,7.1,7.3,7.4)
|
|
382 |
p (modes 0-5)
|
|
383 |
|
|
384 |
coldfire bset/bclr/btst/mulsl/mulul operands:
|
|
385 |
q (modes 0,2-5)
|
|
386 |
v (modes 0,2-5,7.0,7.1)
|
|
387 |
b (modes 0,2-5,7.2)
|
|
388 |
w (modes 2-5,7.2)
|
|
389 |
y (modes 2,5)
|
|
390 |
z (modes 2,5,7.2)
|
|
391 |
x mov3q immediate operand.
|
|
392 |
4 (modes 2,3,4,5)
|
|
393 |
*/
|
|
394 |
|
|
395 |
/* For the 68851: */
|
|
396 |
/* I didn't use much imagination in choosing the
|
|
397 |
following codes, so many of them aren't very
|
|
398 |
mnemonic. -rab
|
|
399 |
|
|
400 |
0 32 bit pmmu register
|
|
401 |
Possible values:
|
|
402 |
000 TC Translation Control Register (68030, 68851)
|
|
403 |
|
|
404 |
1 16 bit pmmu register
|
|
405 |
111 AC Access Control (68851)
|
|
406 |
|
|
407 |
2 8 bit pmmu register
|
|
408 |
100 CAL Current Access Level (68851)
|
|
409 |
101 VAL Validate Access Level (68851)
|
|
410 |
110 SCC Stack Change Control (68851)
|
|
411 |
|
|
412 |
3 68030-only pmmu registers (32 bit)
|
|
413 |
010 TT0 Transparent Translation reg 0
|
|
414 |
(aka Access Control reg 0 -- AC0 -- on 68ec030)
|
|
415 |
011 TT1 Transparent Translation reg 1
|
|
416 |
(aka Access Control reg 1 -- AC1 -- on 68ec030)
|
|
417 |
|
|
418 |
W wide pmmu registers
|
|
419 |
Possible values:
|
|
420 |
001 DRP Dma Root Pointer (68851)
|
|
421 |
010 SRP Supervisor Root Pointer (68030, 68851)
|
|
422 |
011 CRP Cpu Root Pointer (68030, 68851)
|
|
423 |
|
|
424 |
f function code register (68030, 68851)
|
|
425 |
0 SFC
|
|
426 |
1 DFC
|
|
427 |
|
|
428 |
V VAL register only (68851)
|
|
429 |
|
|
430 |
X BADx, BACx (16 bit)
|
|
431 |
100 BAD Breakpoint Acknowledge Data (68851)
|
|
432 |
101 BAC Breakpoint Acknowledge Control (68851)
|
|
433 |
|
|
434 |
Y PSR (68851) (MMUSR on 68030) (ACUSR on 68ec030)
|
|
435 |
Z PCSR (68851)
|
|
436 |
|
|
437 |
| memory (modes 2-6, 7.*)
|
|
438 |
|
|
439 |
t address test level (68030 only)
|
|
440 |
Stored as 3 bits, range 0-7.
|
|
441 |
Also used for breakpoint instruction now.
|
|
442 |
|
|
443 |
*/
|
|
444 |
|
|
445 |
/* Places to put an operand, for non-general operands:
|
|
446 |
Characters used: BbCcDdFfGgHhIijkLlMmNnostWw123456789/
|
|
447 |
|
|
448 |
s source, low bits of first word.
|
|
449 |
d dest, shifted 9 in first word
|
|
450 |
1 second word, shifted 12
|
|
451 |
2 second word, shifted 6
|
|
452 |
3 second word, shifted 0
|
|
453 |
4 third word, shifted 12
|
|
454 |
5 third word, shifted 6
|
|
455 |
6 third word, shifted 0
|
|
456 |
7 second word, shifted 7
|
|
457 |
8 second word, shifted 10
|
|
458 |
9 second word, shifted 5
|
|
459 |
D store in both place 1 and place 3; for divul and divsl.
|
|
460 |
B first word, low byte, for branch displacements
|
|
461 |
W second word (entire), for branch displacements
|
|
462 |
L second and third words (entire), for branch displacements
|
|
463 |
(also overloaded for move16)
|
|
464 |
b second word, low byte
|
|
465 |
w second word (entire) [variable word/long branch offset for dbra]
|
|
466 |
W second word (entire) (must be signed 16 bit value)
|
|
467 |
l second and third word (entire)
|
|
468 |
g variable branch offset for bra and similar instructions.
|
|
469 |
The place to store depends on the magnitude of offset.
|
|
470 |
t store in both place 7 and place 8; for floating point operations
|
|
471 |
c branch offset for cpBcc operations.
|
|
472 |
The place to store is word two if bit six of word one is zero,
|
|
473 |
and words two and three if bit six of word one is one.
|
|
474 |
i Increment by two, to skip over coprocessor extended operands. Only
|
|
475 |
works with the 'I' format.
|
|
476 |
k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number.
|
|
477 |
Also used for dynamic fmovem instruction.
|
|
478 |
C floating point coprocessor constant - 7 bits. Also used for static
|
|
479 |
K-factors...
|
|
480 |
j Movec register #, stored in 12 low bits of second word.
|
|
481 |
m For M[S]ACx; 4 bits split with MSB shifted 6 bits in first word
|
|
482 |
and remaining 3 bits of register shifted 9 bits in first word.
|
|
483 |
Indicate upper/lower in 1 bit shifted 7 bits in second word.
|
|
484 |
Use with `R' or `u' format.
|
|
485 |
n `m' withouth upper/lower indication. (For M[S]ACx; 4 bits split
|
|
486 |
with MSB shifted 6 bits in first word and remaining 3 bits of
|
|
487 |
register shifted 9 bits in first word. No upper/lower
|
|
488 |
indication is done.) Use with `R' or `u' format.
|
|
489 |
o For M[S]ACw; 4 bits shifted 12 in second word (like `1').
|
|
490 |
Indicate upper/lower in 1 bit shifted 7 bits in second word.
|
|
491 |
Use with `R' or `u' format.
|
|
492 |
M For M[S]ACw; 4 bits in low bits of first word. Indicate
|
|
493 |
upper/lower in 1 bit shifted 6 bits in second word. Use with
|
|
494 |
`R' or `u' format.
|
|
495 |
N For M[S]ACw; 4 bits in low bits of second word. Indicate
|
|
496 |
upper/lower in 1 bit shifted 6 bits in second word. Use with
|
|
497 |
`R' or `u' format.
|
|
498 |
h shift indicator (scale factor), 1 bit shifted 10 in second word
|
|
499 |
|
|
500 |
Places to put operand, for general operands:
|
|
501 |
d destination, shifted 6 bits in first word
|
|
502 |
b source, at low bit of first word, and immediate uses one byte
|
|
503 |
w source, at low bit of first word, and immediate uses two bytes
|
|
504 |
l source, at low bit of first word, and immediate uses four bytes
|
|
505 |
s source, at low bit of first word.
|
|
506 |
Used sometimes in contexts where immediate is not allowed anyway.
|
|
507 |
f single precision float, low bit of 1st word, immediate uses 4 bytes
|
|
508 |
F double precision float, low bit of 1st word, immediate uses 8 bytes
|
|
509 |
x extended precision float, low bit of 1st word, immediate uses 12 bytes
|
|
510 |
p packed float, low bit of 1st word, immediate uses 12 bytes
|
|
511 |
G EMAC accumulator, load (bit 4 2nd word, !bit8 first word)
|
|
512 |
H EMAC accumulator, non load (bit 4 2nd word, bit 8 first word)
|
|
513 |
F EMAC ACCx
|
|
514 |
f EMAC ACCy
|
|
515 |
I MAC/EMAC scale factor
|
|
516 |
/ Like 's', but set 2nd word, bit 5 if trailing_ampersand set
|
|
517 |
] first word, bit 10
|
|
518 |
*/
|
|
519 |
|
|
520 |
extern const struct m68k_opcode m68k_opcodes[];
|
|
521 |
extern const struct m68k_opcode_alias m68k_opcode_aliases[];
|
|
522 |
|
|
523 |
extern const int m68k_numopcodes, m68k_numaliases;
|
|
524 |
|
|
525 |
/* **** End of m68k-opcode.h */
|
|
526 |
/* **** m68k-dis.c from sourceware.org CVS 2005-08-14. */
|
|
527 |
/* Print Motorola 68k instructions.
|
|
528 |
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
|
529 |
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
|
530 |
Free Software Foundation, Inc.
|
|
531 |
|
|
532 |
This file is free software; you can redistribute it and/or modify
|
|
533 |
it under the terms of the GNU General Public License as published by
|
|
534 |
the Free Software Foundation; either version 2 of the License, or
|
|
535 |
(at your option) any later version.
|
|
536 |
|
|
537 |
This program is distributed in the hope that it will be useful,
|
|
538 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
539 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
540 |
GNU General Public License for more details.
|
|
541 |
|
|
542 |
You should have received a copy of the GNU General Public License
|
|
543 |
along with this program; if not, write to the Free Software
|
|
544 |
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
545 |
MA 02110-1301, USA. */
|
|
546 |
|
|
547 |
/* Local function prototypes. */
|
|
548 |
|
|
549 |
const char * const fpcr_names[] =
|
|
550 |
{
|
|
551 |
"", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
|
|
552 |
"%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
|
|
553 |
};
|
|
554 |
|
|
555 |
static char *const reg_names[] =
|
|
556 |
{
|
|
557 |
"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
|
|
558 |
"%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
|
|
559 |
"%ps", "%pc"
|
|
560 |
};
|
|
561 |
|
|
562 |
/* Name of register halves for MAC/EMAC.
|
|
563 |
Seperate from reg_names since 'spu', 'fpl' look weird. */
|
|
564 |
static char *const reg_half_names[] =
|
|
565 |
{
|
|
566 |
"%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
|
|
567 |
"%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
|
|
568 |
"%ps", "%pc"
|
|
569 |
};
|
|
570 |
|
|
571 |
/* Sign-extend an (unsigned char). */
|
|
572 |
#if __STDC__ == 1
|
|
573 |
#define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
|
|
574 |
#else
|
|
575 |
#define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
|
|
576 |
#endif
|
|
577 |
|
|
578 |
/* Get a 1 byte signed integer. */
|
|
579 |
#define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
|
|
580 |
|
|
581 |
/* Get a 2 byte signed integer. */
|
|
582 |
#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
|
|
583 |
#define NEXTWORD(p) \
|
|
584 |
(p += 2, FETCH_DATA (info, p), \
|
|
585 |
COERCE16 ((p[-2] << 8) + p[-1]))
|
|
586 |
|
|
587 |
/* Get a 4 byte signed integer. */
|
|
588 |
#define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
|
|
589 |
#define NEXTLONG(p) \
|
|
590 |
(p += 4, FETCH_DATA (info, p), \
|
|
591 |
(COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
|
|
592 |
|
|
593 |
/* Get a 4 byte unsigned integer. */
|
|
594 |
#define NEXTULONG(p) \
|
|
595 |
(p += 4, FETCH_DATA (info, p), \
|
|
596 |
(unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
|
|
597 |
|
|
598 |
/* Get a single precision float. */
|
|
599 |
#define NEXTSINGLE(val, p) \
|
|
600 |
(p += 4, FETCH_DATA (info, p), \
|
|
601 |
floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
|
|
602 |
|
|
603 |
/* Get a double precision float. */
|
|
604 |
#define NEXTDOUBLE(val, p) \
|
|
605 |
(p += 8, FETCH_DATA (info, p), \
|
|
606 |
floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
|
|
607 |
|
|
608 |
/* Get an extended precision float. */
|
|
609 |
#define NEXTEXTEND(val, p) \
|
|
610 |
(p += 12, FETCH_DATA (info, p), \
|
|
611 |
floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
|
|
612 |
|
|
613 |
/* Need a function to convert from packed to double
|
|
614 |
precision. Actually, it's easier to print a
|
|
615 |
packed number than a double anyway, so maybe
|
|
616 |
there should be a special case to handle this... */
|
|
617 |
#define NEXTPACKED(p) \
|
|
618 |
(p += 12, FETCH_DATA (info, p), 0.0)
|
|
619 |
|
|
620 |
/* Maximum length of an instruction. */
|
|
621 |
#define MAXLEN 22
|
|
622 |
|
|
623 |
#include <setjmp.h>
|
|
624 |
|
|
625 |
struct private
|
|
626 |
{
|
|
627 |
/* Points to first byte not fetched. */
|
|
628 |
bfd_byte *max_fetched;
|
|
629 |
bfd_byte the_buffer[MAXLEN];
|
|
630 |
bfd_vma insn_start;
|
|
631 |
jmp_buf bailout;
|
|
632 |
};
|
|
633 |
|
|
634 |
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
|
|
635 |
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
|
|
636 |
on error. */
|
|
637 |
#define FETCH_DATA(info, addr) \
|
|
638 |
((addr) <= ((struct private *) (info->private_data))->max_fetched \
|
|
639 |
? 1 : fetch_data ((info), (addr)))
|
|
640 |
|
|
641 |
static int
|
|
642 |
fetch_data (struct disassemble_info *info, bfd_byte *addr)
|
|
643 |
{
|
|
644 |
int status;
|
|
645 |
struct private *priv = (struct private *)info->private_data;
|
|
646 |
bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
|
|
647 |
|
|
648 |
status = (*info->read_memory_func) (start,
|
|
649 |
priv->max_fetched,
|
|
650 |
addr - priv->max_fetched,
|
|
651 |
info);
|
|
652 |
if (status != 0)
|
|
653 |
{
|
|
654 |
(*info->memory_error_func) (status, start, info);
|
|
655 |
longjmp (priv->bailout, 1);
|
|
656 |
}
|
|
657 |
else
|
|
658 |
priv->max_fetched = addr;
|
|
659 |
return 1;
|
|
660 |
}
|
|
661 |
|
|
662 |
/* This function is used to print to the bit-bucket. */
|
|
663 |
static int
|
|
664 |
dummy_printer (FILE *file ATTRIBUTE_UNUSED,
|
|
665 |
const char *format ATTRIBUTE_UNUSED,
|
|
666 |
...)
|
|
667 |
{
|
|
668 |
return 0;
|
|
669 |
}
|
|
670 |
|
|
671 |
static void
|
|
672 |
dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED,
|
|
673 |
struct disassemble_info *info ATTRIBUTE_UNUSED)
|
|
674 |
{
|
|
675 |
}
|
|
676 |
|
|
677 |
/* Fetch BITS bits from a position in the instruction specified by CODE.
|
|
678 |
CODE is a "place to put an argument", or 'x' for a destination
|
|
679 |
that is a general address (mode and register).
|
|
680 |
BUFFER contains the instruction. */
|
|
681 |
|
|
682 |
static int
|
|
683 |
fetch_arg (unsigned char *buffer,
|
|
684 |
int code,
|
|
685 |
int bits,
|
|
686 |
disassemble_info *info)
|
|
687 |
{
|
|
688 |
int val = 0;
|
|
689 |
|
|
690 |
switch (code)
|
|
691 |
{
|
|
692 |
case '/': /* MAC/EMAC mask bit. */
|
|
693 |
val = buffer[3] >> 5;
|
|
694 |
break;
|
|
695 |
|
|
696 |
case 'G': /* EMAC ACC load. */
|
|
697 |
val = ((buffer[3] >> 3) & 0x2) | ((~buffer[1] >> 7) & 0x1);
|
|
698 |
break;
|
|
699 |
|
|
700 |
case 'H': /* EMAC ACC !load. */
|
|
701 |
val = ((buffer[3] >> 3) & 0x2) | ((buffer[1] >> 7) & 0x1);
|
|
702 |
break;
|
|
703 |
|
|
704 |
case ']': /* EMAC ACCEXT bit. */
|
|
705 |
val = buffer[0] >> 2;
|
|
706 |
break;
|
|
707 |
|
|
708 |
case 'I': /* MAC/EMAC scale factor. */
|
|
709 |
val = buffer[2] >> 1;
|
|
710 |
break;
|
|
711 |
|
|
712 |
case 'F': /* EMAC ACCx. */
|
|
713 |
val = buffer[0] >> 1;
|
|
714 |
break;
|
|
715 |
|
|
716 |
case 'f':
|
|
717 |
val = buffer[1];
|
|
718 |
break;
|
|
719 |
|
|
720 |
case 's':
|
|
721 |
val = buffer[1];
|
|
722 |
break;
|
|
723 |
|
|
724 |
case 'd': /* Destination, for register or quick. */
|
|
725 |
val = (buffer[0] << 8) + buffer[1];
|
|
726 |
val >>= 9;
|
|
727 |
break;
|
|
728 |
|
|
729 |
case 'x': /* Destination, for general arg. */
|
|
730 |
val = (buffer[0] << 8) + buffer[1];
|
|
731 |
val >>= 6;
|
|
732 |
break;
|
|
733 |
|
|
734 |
case 'k':
|
|
735 |
FETCH_DATA (info, buffer + 3);
|
|
736 |
val = (buffer[3] >> 4);
|
|
737 |
break;
|
|
738 |
|
|
739 |
case 'C':
|
|
740 |
FETCH_DATA (info, buffer + 3);
|
|
741 |
val = buffer[3];
|
|
742 |
break;
|
|
743 |
|
|
744 |
case '1':
|
|
745 |
FETCH_DATA (info, buffer + 3);
|
|
746 |
val = (buffer[2] << 8) + buffer[3];
|
|
747 |
val >>= 12;
|
|
748 |
break;
|
|
749 |
|
|
750 |
case '2':
|
|
751 |
FETCH_DATA (info, buffer + 3);
|
|
752 |
val = (buffer[2] << 8) + buffer[3];
|
|
753 |
val >>= 6;
|
|
754 |
break;
|
|
755 |
|
|
756 |
case '3':
|
|
757 |
case 'j':
|
|
758 |
FETCH_DATA (info, buffer + 3);
|
|
759 |
val = (buffer[2] << 8) + buffer[3];
|
|
760 |
break;
|
|
761 |
|
|
762 |
case '4':
|
|
763 |
FETCH_DATA (info, buffer + 5);
|
|
764 |
val = (buffer[4] << 8) + buffer[5];
|
|
765 |
val >>= 12;
|
|
766 |
break;
|
|
767 |
|
|
768 |
case '5':
|
|
769 |
FETCH_DATA (info, buffer + 5);
|
|
770 |
val = (buffer[4] << 8) + buffer[5];
|
|
771 |
val >>= 6;
|
|
772 |
break;
|
|
773 |
|
|
774 |
case '6':
|
|
775 |
FETCH_DATA (info, buffer + 5);
|
|
776 |
val = (buffer[4] << 8) + buffer[5];
|
|
777 |
break;
|
|
778 |
|
|
779 |
case '7':
|
|
780 |
FETCH_DATA (info, buffer + 3);
|
|
781 |
val = (buffer[2] << 8) + buffer[3];
|
|
782 |
val >>= 7;
|
|
783 |
break;
|
|
784 |
|
|
785 |
case '8':
|
|
786 |
FETCH_DATA (info, buffer + 3);
|
|
787 |
val = (buffer[2] << 8) + buffer[3];
|
|
788 |
val >>= 10;
|
|
789 |
break;
|
|
790 |
|
|
791 |
case '9':
|
|
792 |
FETCH_DATA (info, buffer + 3);
|
|
793 |
val = (buffer[2] << 8) + buffer[3];
|
|
794 |
val >>= 5;
|
|
795 |
break;
|
|
796 |
|
|
797 |
case 'e':
|
|
798 |
val = (buffer[1] >> 6);
|
|
799 |
break;
|
|
800 |
|
|
801 |
case 'm':
|
|
802 |
val = (buffer[1] & 0x40 ? 0x8 : 0)
|
|
803 |
| ((buffer[0] >> 1) & 0x7)
|
|
804 |
| (buffer[3] & 0x80 ? 0x10 : 0);
|
|
805 |
break;
|
|
806 |
|
|
807 |
case 'n':
|
|
808 |
val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
|
|
809 |
break;
|
|
810 |
|
|
811 |
case 'o':
|
|
812 |
val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
|
|
813 |
break;
|
|
814 |
|
|
815 |
case 'M':
|
|
816 |
val = (buffer[1] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
|
|
817 |
break;
|
|
818 |
|
|
819 |
case 'N':
|
|
820 |
val = (buffer[3] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
|
|
821 |
break;
|
|
822 |
|
|
823 |
case 'h':
|
|
824 |
val = buffer[2] >> 2;
|
|
825 |
break;
|
|
826 |
|
|
827 |
default:
|
|
828 |
abort ();
|
|
829 |
}
|
|
830 |
|
|
831 |
switch (bits)
|
|
832 |
{
|
|
833 |
case 1:
|
|
834 |
return val & 1;
|
|
835 |
case 2:
|
|
836 |
return val & 3;
|
|
837 |
case 3:
|
|
838 |
return val & 7;
|
|
839 |
case 4:
|
|
840 |
return val & 017;
|
|
841 |
case 5:
|
|
842 |
return val & 037;
|
|
843 |
case 6:
|
|
844 |
return val & 077;
|
|
845 |
case 7:
|
|
846 |
return val & 0177;
|
|
847 |
case 8:
|
|
848 |
return val & 0377;
|
|
849 |
case 12:
|
|
850 |
return val & 07777;
|
|
851 |
default:
|
|
852 |
abort ();
|
|
853 |
}
|
|
854 |
}
|
|
855 |
|
|
856 |
/* Check if an EA is valid for a particular code. This is required
|
|
857 |
for the EMAC instructions since the type of source address determines
|
|
858 |
if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
|
|
859 |
is a non-load EMAC instruction and the bits mean register Ry.
|
|
860 |
A similar case exists for the movem instructions where the register
|
|
861 |
mask is interpreted differently for different EAs. */
|
|
862 |
|
|
863 |
static bfd_boolean
|
|
864 |
m68k_valid_ea (char code, int val)
|
|
865 |
{
|
|
866 |
int mode, mask;
|
|
867 |
#define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
|
|
868 |
(n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
|
|
869 |
| n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
|
|
870 |
|
|
871 |
switch (code)
|
|
872 |
{
|
|
873 |
case '*':
|
|
874 |
mask = M (1,1,1,1,1,1,1,1,1,1,1,1);
|
|
875 |
break;
|
|
876 |
case '~':
|
|
877 |
mask = M (0,0,1,1,1,1,1,1,1,0,0,0);
|
|
878 |
break;
|
|
879 |
case '%':
|
|
880 |
mask = M (1,1,1,1,1,1,1,1,1,0,0,0);
|
|
881 |
break;
|
|
882 |
case ';':
|
|
883 |
mask = M (1,0,1,1,1,1,1,1,1,1,1,1);
|
|
884 |
break;
|
|
885 |
case '@':
|
|
886 |
mask = M (1,0,1,1,1,1,1,1,1,1,1,0);
|
|
887 |
break;
|
|
888 |
case '!':
|
|
889 |
mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
|
|
890 |
break;
|
|
891 |
case '&':
|
|
892 |
mask = M (0,0,1,0,0,1,1,1,1,0,0,0);
|
|
893 |
break;
|
|
894 |
case '$':
|
|
895 |
mask = M (1,0,1,1,1,1,1,1,1,0,0,0);
|
|
896 |
break;
|
|
897 |
case '?':
|
|
898 |
mask = M (1,0,1,0,0,1,1,1,1,0,0,0);
|
|
899 |
break;
|
|
900 |
case '/':
|
|
901 |
mask = M (1,0,1,0,0,1,1,1,1,1,1,0);
|
|
902 |
break;
|
|
903 |
case '|':
|
|
904 |
mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
|
|
905 |
break;
|
|
906 |
case '>':
|
|
907 |
mask = M (0,0,1,0,1,1,1,1,1,0,0,0);
|
|
908 |
break;
|
|
909 |
case '<':
|
|
910 |
mask = M (0,0,1,1,0,1,1,1,1,1,1,0);
|
|
911 |
break;
|
|
912 |
case 'm':
|
|
913 |
mask = M (1,1,1,1,1,0,0,0,0,0,0,0);
|
|
914 |
break;
|
|
915 |
case 'n':
|
|
916 |
mask = M (0,0,0,0,0,1,0,0,0,1,0,0);
|
|
917 |
break;
|
|
918 |
case 'o':
|
|
919 |
mask = M (0,0,0,0,0,0,1,1,1,0,1,1);
|
|
920 |
break;
|
|
921 |
case 'p':
|
|
922 |
mask = M (1,1,1,1,1,1,0,0,0,0,0,0);
|
|
923 |
break;
|
|
924 |
case 'q':
|
|
925 |
mask = M (1,0,1,1,1,1,0,0,0,0,0,0);
|
|
926 |
break;
|
|
927 |
case 'v':
|
|
928 |
mask = M (1,0,1,1,1,1,0,1,1,0,0,0);
|
|
929 |
break;
|
|
930 |
case 'b':
|
|
931 |
mask = M (1,0,1,1,1,1,0,0,0,1,0,0);
|
|
932 |
break;
|
|
933 |
case 'w':
|
|
934 |
mask = M (0,0,1,1,1,1,0,0,0,1,0,0);
|
|
935 |
break;
|
|
936 |
case 'y':
|
|
937 |
mask = M (0,0,1,0,0,1,0,0,0,0,0,0);
|
|
938 |
break;
|
|
939 |
case 'z':
|
|
940 |
mask = M (0,0,1,0,0,1,0,0,0,1,0,0);
|
|
941 |
break;
|
|
942 |
case '4':
|
|
943 |
mask = M (0,0,1,1,1,1,0,0,0,0,0,0);
|
|
944 |
break;
|
|
945 |
default:
|
|
946 |
abort ();
|
|
947 |
}
|
|
948 |
#undef M
|
|
949 |
|
|
950 |
mode = (val >> 3) & 7;
|
|
951 |
if (mode == 7)
|
|
952 |
mode += val & 7;
|
|
953 |
return (mask & (1 << mode)) != 0;
|
|
954 |
}
|
|
955 |
|
|
956 |
/* Print a base register REGNO and displacement DISP, on INFO->STREAM.
|
|
957 |
REGNO = -1 for pc, -2 for none (suppressed). */
|
|
958 |
|
|
959 |
static void
|
|
960 |
print_base (int regno, bfd_vma disp, disassemble_info *info)
|
|
961 |
{
|
|
962 |
if (regno == -1)
|
|
963 |
{
|
|
964 |
(*info->fprintf_func) (info->stream, "%%pc@(");
|
|
965 |
(*info->print_address_func) (disp, info);
|
|
966 |
}
|
|
967 |
else
|
|
968 |
{
|
|
969 |
char buf[50];
|
|
970 |
|
|
971 |
if (regno == -2)
|
|
972 |
(*info->fprintf_func) (info->stream, "@(");
|
|
973 |
else if (regno == -3)
|
|
974 |
(*info->fprintf_func) (info->stream, "%%zpc@(");
|
|
975 |
else
|
|
976 |
(*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
|
|
977 |
|
|
978 |
sprintf_vma (buf, disp);
|
|
979 |
(*info->fprintf_func) (info->stream, "%s", buf);
|
|
980 |
}
|
|
981 |
}
|
|
982 |
|
|
983 |
/* Print an indexed argument. The base register is BASEREG (-1 for pc).
|
|
984 |
P points to extension word, in buffer.
|
|
985 |
ADDR is the nominal core address of that extension word. */
|
|
986 |
|
|
987 |
static unsigned char *
|
|
988 |
print_indexed (int basereg,
|
|
989 |
unsigned char *p,
|
|
990 |
bfd_vma addr,
|
|
991 |
disassemble_info *info)
|
|
992 |
{
|
|
993 |
int word;
|
|
994 |
static char *const scales[] = { "", ":2", ":4", ":8" };
|
|
995 |
bfd_vma base_disp;
|
|
996 |
bfd_vma outer_disp;
|
|
997 |
char buf[40];
|
|
998 |
char vmabuf[50];
|
|
999 |
|
|
1000 |
word = NEXTWORD (p);
|
|
1001 |
|
|
1002 |
/* Generate the text for the index register.
|
|
1003 |
Where this will be output is not yet determined. */
|
|
1004 |
sprintf (buf, "%s:%c%s",
|
|
1005 |
reg_names[(word >> 12) & 0xf],
|
|
1006 |
(word & 0x800) ? 'l' : 'w',
|
|
1007 |
scales[(word >> 9) & 3]);
|
|
1008 |
|
|
1009 |
/* Handle the 68000 style of indexing. */
|
|
1010 |
|
|
1011 |
if ((word & 0x100) == 0)
|
|
1012 |
{
|
|
1013 |
base_disp = word & 0xff;
|
|
1014 |
if ((base_disp & 0x80) != 0)
|
|
1015 |
base_disp -= 0x100;
|
|
1016 |
if (basereg == -1)
|
|
1017 |
base_disp += addr;
|
|
1018 |
print_base (basereg, base_disp, info);
|
|
1019 |
(*info->fprintf_func) (info->stream, ",%s)", buf);
|
|
1020 |
return p;
|
|
1021 |
}
|
|
1022 |
|
|
1023 |
/* Handle the generalized kind. */
|
|
1024 |
/* First, compute the displacement to add to the base register. */
|
|
1025 |
if (word & 0200)
|
|
1026 |
{
|
|
1027 |
if (basereg == -1)
|
|
1028 |
basereg = -3;
|
|
1029 |
else
|
|
1030 |
basereg = -2;
|
|
1031 |
}
|
|
1032 |
if (word & 0100)
|
|
1033 |
buf[0] = '\0';
|
|
1034 |
base_disp = 0;
|
|
1035 |
switch ((word >> 4) & 3)
|
|
1036 |
{
|
|
1037 |
case 2:
|
|
1038 |
base_disp = NEXTWORD (p);
|
|
1039 |
break;
|
|
1040 |
case 3:
|
|
1041 |
base_disp = NEXTLONG (p);
|
|
1042 |
}
|
|
1043 |
if (basereg == -1)
|
|
1044 |
base_disp += addr;
|
|
1045 |
|
|
1046 |
/* Handle single-level case (not indirect). */
|
|
1047 |
if ((word & 7) == 0)
|
|
1048 |
{
|
|
1049 |
print_base (basereg, base_disp, info);
|
|
1050 |
if (buf[0] != '\0')
|
|
1051 |
(*info->fprintf_func) (info->stream, ",%s", buf);
|
|
1052 |
(*info->fprintf_func) (info->stream, ")");
|
|
1053 |
return p;
|
|
1054 |
}
|
|
1055 |
|
|
1056 |
/* Two level. Compute displacement to add after indirection. */
|
|
1057 |
outer_disp = 0;
|
|
1058 |
switch (word & 3)
|
|
1059 |
{
|
|
1060 |
case 2:
|
|
1061 |
outer_disp = NEXTWORD (p);
|
|
1062 |
break;
|
|
1063 |
case 3:
|
|
1064 |
outer_disp = NEXTLONG (p);
|
|
1065 |
}
|
|
1066 |
|
|
1067 |
print_base (basereg, base_disp, info);
|
|
1068 |
if ((word & 4) == 0 && buf[0] != '\0')
|
|
1069 |
{
|
|
1070 |
(*info->fprintf_func) (info->stream, ",%s", buf);
|
|
1071 |
buf[0] = '\0';
|
|
1072 |
}
|
|
1073 |
sprintf_vma (vmabuf, outer_disp);
|
|
1074 |
(*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
|
|
1075 |
if (buf[0] != '\0')
|
|
1076 |
(*info->fprintf_func) (info->stream, ",%s", buf);
|
|
1077 |
(*info->fprintf_func) (info->stream, ")");
|
|
1078 |
|
|
1079 |
return p;
|
|
1080 |
}
|
|
1081 |
|
|
1082 |
/* Returns number of bytes "eaten" by the operand, or
|
|
1083 |
return -1 if an invalid operand was found, or -2 if
|
|
1084 |
an opcode tabe error was found.
|
|
1085 |
ADDR is the pc for this arg to be relative to. */
|
|
1086 |
|
|
1087 |
static int
|
|
1088 |
print_insn_arg (const char *d,
|
|
1089 |
unsigned char *buffer,
|
|
1090 |
unsigned char *p0,
|
|
1091 |
bfd_vma addr,
|
|
1092 |
disassemble_info *info)
|
|
1093 |
{
|
|
1094 |
int val = 0;
|
|
1095 |
int place = d[1];
|
|
1096 |
unsigned char *p = p0;
|
|
1097 |
int regno;
|
|
1098 |
const char *regname;
|
|
1099 |
unsigned char *p1;
|
|
1100 |
double flval;
|
|
1101 |
int flt_p;
|
|
1102 |
bfd_signed_vma disp;
|
|
1103 |
unsigned int uval;
|
|
1104 |
|
|
1105 |
switch (*d)
|
|
1106 |
{
|
|
1107 |
case 'c': /* Cache identifier. */
|
|
1108 |
{
|
|
1109 |
static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
|
|
1110 |
val = fetch_arg (buffer, place, 2, info);
|
|
1111 |
(*info->fprintf_func) (info->stream, cacheFieldName[val]);
|
|
1112 |
break;
|
|
1113 |
}
|
|
1114 |
|
|
1115 |
case 'a': /* Address register indirect only. Cf. case '+'. */
|
|
1116 |
{
|
|
1117 |
(*info->fprintf_func)
|
|
1118 |
(info->stream,
|
|
1119 |
"%s@",
|
|
1120 |
reg_names[fetch_arg (buffer, place, 3, info) + 8]);
|
|
1121 |
break;
|
|
1122 |
}
|
|
1123 |
|
|
1124 |
case '_': /* 32-bit absolute address for move16. */
|
|
1125 |
{
|
|
1126 |
uval = NEXTULONG (p);
|
|
1127 |
(*info->print_address_func) (uval, info);
|
|
1128 |
break;
|
|
1129 |
}
|
|
1130 |
|
|
1131 |
case 'C':
|
|
1132 |
(*info->fprintf_func) (info->stream, "%%ccr");
|
|
1133 |
break;
|
|
1134 |
|
|
1135 |
case 'S':
|
|
1136 |
(*info->fprintf_func) (info->stream, "%%sr");
|
|
1137 |
break;
|
|
1138 |
|
|
1139 |
case 'U':
|
|
1140 |
(*info->fprintf_func) (info->stream, "%%usp");
|
|
1141 |
break;
|
|
1142 |
|
|
1143 |
case 'E':
|
|
1144 |
(*info->fprintf_func) (info->stream, "%%acc");
|
|
1145 |
break;
|
|
1146 |
|
|
1147 |
case 'G':
|
|
1148 |
(*info->fprintf_func) (info->stream, "%%macsr");
|
|
1149 |
break;
|
|
1150 |
|
|
1151 |
case 'H':
|
|
1152 |
(*info->fprintf_func) (info->stream, "%%mask");
|
|
1153 |
break;
|
|
1154 |
|
|
1155 |
case 'J':
|
|
1156 |
{
|
|
1157 |
/* FIXME: There's a problem here, different m68k processors call the
|
|
1158 |
same address different names. This table can't get it right
|
|
1159 |
because it doesn't know which processor it's disassembling for. */
|
|
1160 |
static const struct { char *name; int value; } names[]
|
|
1161 |
= {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
|
|
1162 |
{"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
|
|
1163 |
{"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
|
|
1164 |
{"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
|
|
1165 |
{"%msp", 0x803}, {"%isp", 0x804},
|
|
1166 |
{"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these. */
|
|
1167 |
|
|
1168 |
/* Should we be calling this psr like we do in case 'Y'? */
|
|
1169 |
{"%mmusr",0x805},
|
|
1170 |
|
|
1171 |
{"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
|
|
1172 |
|
|
1173 |
val = fetch_arg (buffer, place, 12, info);
|
|
1174 |
for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
|
|
1175 |
if (names[regno].value == val)
|
|
1176 |
{
|
|
1177 |
(*info->fprintf_func) (info->stream, "%s", names[regno].name);
|
|
1178 |
break;
|
|
1179 |
}
|
|
1180 |
if (regno < 0)
|
|
1181 |
(*info->fprintf_func) (info->stream, "%d", val);
|
|
1182 |
}
|
|
1183 |
break;
|
|
1184 |
|
|
1185 |
case 'Q':
|
|
1186 |
val = fetch_arg (buffer, place, 3, info);
|
|
1187 |
/* 0 means 8, except for the bkpt instruction... */
|
|
1188 |
if (val == 0 && d[1] != 's')
|
|
1189 |
val = 8;
|
|
1190 |
(*info->fprintf_func) (info->stream, "#%d", val);
|
|
1191 |
break;
|
|
1192 |
|
|
1193 |
case 'x':
|
|
1194 |
val = fetch_arg (buffer, place, 3, info);
|
|
1195 |
/* 0 means -1. */
|
|
1196 |
if (val == 0)
|
|
1197 |
val = -1;
|
|
1198 |
(*info->fprintf_func) (info->stream, "#%d", val);
|
|
1199 |
break;
|
|
1200 |
|
|
1201 |
case 'M':
|
|
1202 |
if (place == 'h')
|
|
1203 |
{
|
|
1204 |
static char *const scalefactor_name[] = { "<<", ">>" };
|
|
1205 |
val = fetch_arg (buffer, place, 1, info);
|
|
1206 |
(*info->fprintf_func) (info->stream, scalefactor_name[val]);
|
|
1207 |
}
|
|
1208 |
else
|
|
1209 |
{
|
|
1210 |
val = fetch_arg (buffer, place, 8, info);
|
|
1211 |
if (val & 0x80)
|
|
1212 |
val = val - 0x100;
|
|
1213 |
(*info->fprintf_func) (info->stream, "#%d", val);
|
|
1214 |
}
|
|
1215 |
break;
|
|
1216 |
|
|
1217 |
case 'T':
|
|
1218 |
val = fetch_arg (buffer, place, 4, info);
|
|
1219 |
(*info->fprintf_func) (info->stream, "#%d", val);
|
|
1220 |
break;
|
|
1221 |
|
|
1222 |
case 'D':
|
|
1223 |
(*info->fprintf_func) (info->stream, "%s",
|
|
1224 |
reg_names[fetch_arg (buffer, place, 3, info)]);
|
|
1225 |
break;
|
|
1226 |
|
|
1227 |
case 'A':
|
|
1228 |
(*info->fprintf_func)
|
|
1229 |
(info->stream, "%s",
|
|
1230 |
reg_names[fetch_arg (buffer, place, 3, info) + 010]);
|
|
1231 |
break;
|
|
1232 |
|
|
1233 |
case 'R':
|
|
1234 |
(*info->fprintf_func)
|
|
1235 |
(info->stream, "%s",
|
|
1236 |
reg_names[fetch_arg (buffer, place, 4, info)]);
|
|
1237 |
break;
|
|
1238 |
|
|
1239 |
case 'r':
|
|
1240 |
regno = fetch_arg (buffer, place, 4, info);
|
|
1241 |
if (regno > 7)
|
|
1242 |
(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
|
|
1243 |
else
|
|
1244 |
(*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
|
|
1245 |
break;
|
|
1246 |
|
|
1247 |
case 'F':
|
|
1248 |
(*info->fprintf_func)
|
|
1249 |
(info->stream, "%%fp%d",
|
|
1250 |
fetch_arg (buffer, place, 3, info));
|
|
1251 |
break;
|
|
1252 |
|
|
1253 |
case 'O':
|
|
1254 |
val = fetch_arg (buffer, place, 6, info);
|
|
1255 |
if (val & 0x20)
|
|
1256 |
(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
|
|
1257 |
else
|
|
1258 |
(*info->fprintf_func) (info->stream, "%d", val);
|
|
1259 |
break;
|
|
1260 |
|
|
1261 |
case '+':
|
|
1262 |
(*info->fprintf_func)
|
|
1263 |
(info->stream, "%s@+",
|
|
1264 |
reg_names[fetch_arg (buffer, place, 3, info) + 8]);
|
|
1265 |
break;
|
|
1266 |
|
|
1267 |
case '-':
|
|
1268 |
(*info->fprintf_func)
|
|
1269 |
(info->stream, "%s@-",
|
|
1270 |
reg_names[fetch_arg (buffer, place, 3, info) + 8]);
|
|
1271 |
break;
|
|
1272 |
|
|
1273 |
case 'k':
|
|
1274 |
if (place == 'k')
|
|
1275 |
(*info->fprintf_func)
|
|
1276 |
(info->stream, "{%s}",
|
|
1277 |
reg_names[fetch_arg (buffer, place, 3, info)]);
|
|
1278 |
else if (place == 'C')
|
|
1279 |
{
|
|
1280 |
val = fetch_arg (buffer, place, 7, info);
|
|
1281 |
if (val > 63) /* This is a signed constant. */
|
|
1282 |
val -= 128;
|
|
1283 |
(*info->fprintf_func) (info->stream, "{#%d}", val);
|
|
1284 |
}
|
|
1285 |
else
|
|
1286 |
return -2;
|
|
1287 |
break;
|
|
1288 |
|
|
1289 |
case '#':
|
|
1290 |
case '^':
|
|
1291 |
p1 = buffer + (*d == '#' ? 2 : 4);
|
|
1292 |
if (place == 's')
|
|
1293 |
val = fetch_arg (buffer, place, 4, info);
|
|
1294 |
else if (place == 'C')
|
|
1295 |
val = fetch_arg (buffer, place, 7, info);
|
|
1296 |
else if (place == '8')
|
|
1297 |
val = fetch_arg (buffer, place, 3, info);
|
|
1298 |
else if (place == '3')
|
|
1299 |
val = fetch_arg (buffer, place, 8, info);
|
|
1300 |
else if (place == 'b')
|
|
1301 |
val = NEXTBYTE (p1);
|
|
1302 |
else if (place == 'w' || place == 'W')
|
|
1303 |
val = NEXTWORD (p1);
|
|
1304 |
else if (place == 'l')
|
|
1305 |
val = NEXTLONG (p1);
|
|
1306 |
else
|
|
1307 |
return -2;
|
|
1308 |
(*info->fprintf_func) (info->stream, "#%d", val);
|
|
1309 |
break;
|
|
1310 |
|
|
1311 |
case 'B':
|
|
1312 |
if (place == 'b')
|
|
1313 |
disp = NEXTBYTE (p);
|
|
1314 |
else if (place == 'B')
|
|
1315 |
disp = COERCE_SIGNED_CHAR (buffer[1]);
|
|
1316 |
else if (place == 'w' || place == 'W')
|
|
1317 |
disp = NEXTWORD (p);
|
|
1318 |
else if (place == 'l' || place == 'L' || place == 'C')
|
|
1319 |
disp = NEXTLONG (p);
|
|
1320 |
else if (place == 'g')
|
|
1321 |
{
|
|
1322 |
disp = NEXTBYTE (buffer);
|
|
1323 |
if (disp == 0)
|
|
1324 |
disp = NEXTWORD (p);
|
|
1325 |
else if (disp == -1)
|
|
1326 |
disp = NEXTLONG (p);
|
|
1327 |
}
|
|
1328 |
else if (place == 'c')
|
|
1329 |
{
|
|
1330 |
if (buffer[1] & 0x40) /* If bit six is one, long offset. */
|
|
1331 |
disp = NEXTLONG (p);
|
|
1332 |
else
|
|
1333 |
disp = NEXTWORD (p);
|
|
1334 |
}
|
|
1335 |
else
|
|
1336 |
return -2;
|
|
1337 |
|
|
1338 |
(*info->print_address_func) (addr + disp, info);
|
|
1339 |
break;
|
|
1340 |
|
|
1341 |
case 'd':
|
|
1342 |
val = NEXTWORD (p);
|
|
1343 |
(*info->fprintf_func)
|
|
1344 |
(info->stream, "%s@(%d)",
|
|
1345 |
reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
|
|
1346 |
break;
|
|
1347 |
|
|
1348 |
case 's':
|
|
1349 |
(*info->fprintf_func) (info->stream, "%s",
|
|
1350 |
fpcr_names[fetch_arg (buffer, place, 3, info)]);
|
|
1351 |
break;
|
|
1352 |
|
|
1353 |
case 'e':
|
|
1354 |
val = fetch_arg(buffer, place, 2, info);
|
|
1355 |
(*info->fprintf_func) (info->stream, "%%acc%d", val);
|
|
1356 |
break;
|
|
1357 |
|
|
1358 |
case 'g':
|
|
1359 |
val = fetch_arg(buffer, place, 1, info);
|
|
1360 |
(*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
|
|
1361 |
break;
|
|
1362 |
|
|
1363 |
case 'i':
|
|
1364 |
val = fetch_arg(buffer, place, 2, info);
|
|
1365 |
if (val == 1)
|
|
1366 |
(*info->fprintf_func) (info->stream, "<<");
|
|
1367 |
else if (val == 3)
|
|
1368 |
(*info->fprintf_func) (info->stream, ">>");
|
|
1369 |
else
|
|
1370 |
return -1;
|
|
1371 |
break;
|
|
1372 |
|
|
1373 |
case 'I':
|
|
1374 |
/* Get coprocessor ID... */
|
|
1375 |
val = fetch_arg (buffer, 'd', 3, info);
|
|
1376 |
|
|
1377 |
if (val != 1) /* Unusual coprocessor ID? */
|
|
1378 |
(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
|
|
1379 |
break;
|
|
1380 |
|
|
1381 |
case '4':
|
|
1382 |
case '*':
|
|
1383 |
case '~':
|
|
1384 |
case '%':
|
|
1385 |
case ';':
|
|
1386 |
case '@':
|
|
1387 |
case '!':
|
|
1388 |
case '$':
|
|
1389 |
case '?':
|
|
1390 |
case '/':
|