daily update
[deliverable/binutils-gdb.git] / opcodes / m68k-dis.c
CommitLineData
252b5132 1/* Print Motorola 68k instructions.
060d22b0 2 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
fd99574b 3 1998, 1999, 2000, 2001, 2002, 2003, 2004
252b5132
RH
4 Free Software Foundation, Inc.
5
3e602632
NC
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
252b5132 10
3e602632
NC
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
252b5132 15
3e602632
NC
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
f4321104 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132 19
0d8dfecf 20#include "sysdep.h"
252b5132
RH
21#include "dis-asm.h"
22#include "floatformat.h"
19f33eee 23#include "libiberty.h"
252b5132
RH
24#include "opintl.h"
25
26#include "opcode/m68k.h"
27
28/* Local function prototypes */
29
30static int
31fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
32
33static void
34dummy_print_address PARAMS ((bfd_vma, struct disassemble_info *));
35
36static int
37fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
38
39static void
ec22bdda 40print_base PARAMS ((int, bfd_vma, disassemble_info *));
252b5132
RH
41
42static unsigned char *
43print_indexed PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
44
45static int
46print_insn_arg PARAMS ((const char *, unsigned char *, unsigned char *,
47 bfd_vma, disassemble_info *));
48
be8c092b
NC
49static bfd_boolean m68k_valid_ea (char code, int val);
50
51const char * const fpcr_names[] =
52{
9d29e1b3
NC
53 "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
54 "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
ec22bdda 55};
252b5132 56
be8c092b
NC
57static char *const reg_names[] =
58{
9d29e1b3
NC
59 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
60 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
61 "%ps", "%pc"
ec22bdda 62};
252b5132 63
be8c092b
NC
64/* Name of register halves for MAC/EMAC.
65 Seperate from reg_names since 'spu', 'fpl' look weird. */
66static char *const reg_half_names[] =
67{
68 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
69 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
70 "%ps", "%pc"
71};
72
73/* Sign-extend an (unsigned char). */
252b5132 74#if __STDC__ == 1
ec22bdda 75#define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
252b5132 76#else
ec22bdda 77#define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
252b5132
RH
78#endif
79
80/* Get a 1 byte signed integer. */
81#define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
82
83/* Get a 2 byte signed integer. */
84#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
85#define NEXTWORD(p) \
86 (p += 2, FETCH_DATA (info, p), \
87 COERCE16 ((p[-2] << 8) + p[-1]))
88
89/* Get a 4 byte signed integer. */
90#define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
91#define NEXTLONG(p) \
92 (p += 4, FETCH_DATA (info, p), \
93 (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
94
95/* Get a 4 byte unsigned integer. */
96#define NEXTULONG(p) \
97 (p += 4, FETCH_DATA (info, p), \
98 (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
99
100/* Get a single precision float. */
101#define NEXTSINGLE(val, p) \
102 (p += 4, FETCH_DATA (info, p), \
103 floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
104
105/* Get a double precision float. */
106#define NEXTDOUBLE(val, p) \
107 (p += 8, FETCH_DATA (info, p), \
108 floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
109
110/* Get an extended precision float. */
111#define NEXTEXTEND(val, p) \
112 (p += 12, FETCH_DATA (info, p), \
113 floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
114
115/* Need a function to convert from packed to double
116 precision. Actually, it's easier to print a
117 packed number than a double anyway, so maybe
118 there should be a special case to handle this... */
119#define NEXTPACKED(p) \
120 (p += 12, FETCH_DATA (info, p), 0.0)
252b5132
RH
121\f
122/* Maximum length of an instruction. */
123#define MAXLEN 22
124
125#include <setjmp.h>
126
ec22bdda 127struct private {
252b5132
RH
128 /* Points to first byte not fetched. */
129 bfd_byte *max_fetched;
130 bfd_byte the_buffer[MAXLEN];
131 bfd_vma insn_start;
132 jmp_buf bailout;
133};
134
135/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
136 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
137 on error. */
138#define FETCH_DATA(info, addr) \
ec22bdda 139 ((addr) <= ((struct private *) (info->private_data))->max_fetched \
252b5132
RH
140 ? 1 : fetch_data ((info), (addr)))
141
142static int
143fetch_data (info, addr)
144 struct disassemble_info *info;
145 bfd_byte *addr;
146{
147 int status;
148 struct private *priv = (struct private *)info->private_data;
149 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
150
151 status = (*info->read_memory_func) (start,
152 priv->max_fetched,
153 addr - priv->max_fetched,
154 info);
155 if (status != 0)
156 {
157 (*info->memory_error_func) (status, start, info);
158 longjmp (priv->bailout, 1);
159 }
160 else
161 priv->max_fetched = addr;
162 return 1;
163}
164\f
165/* This function is used to print to the bit-bucket. */
166static int
167#ifdef __STDC__
ec22bdda
KH
168dummy_printer (FILE *file ATTRIBUTE_UNUSED,
169 const char *format ATTRIBUTE_UNUSED, ...)
252b5132 170#else
ec22bdda
KH
171dummy_printer (file)
172 FILE *file ATTRIBUTE_UNUSED;
252b5132 173#endif
ec22bdda
KH
174{
175 return 0;
176}
252b5132
RH
177
178static void
179dummy_print_address (vma, info)
821011cc
AM
180 bfd_vma vma ATTRIBUTE_UNUSED;
181 struct disassemble_info *info ATTRIBUTE_UNUSED;
252b5132
RH
182{
183}
184
be8c092b
NC
185/* Try to match the current instruction to best and if so, return the
186 number of bytes consumed from the instruction stream, else zero. */
187
188static int
189match_insn_m68k (bfd_vma memaddr, disassemble_info * info,
190 const struct m68k_opcode * best, struct private * priv)
191{
192 unsigned char *save_p;
193 unsigned char *p;
194 const char *d;
195
196 bfd_byte *buffer = priv->the_buffer;
197 fprintf_ftype save_printer = info->fprintf_func;
198 void (* save_print_address) (bfd_vma, struct disassemble_info *)
199 = info->print_address_func;
200
201 /* Point at first word of argument data,
202 and at descriptor for first argument. */
203 p = buffer + 2;
204
205 /* Figure out how long the fixed-size portion of the instruction is.
206 The only place this is stored in the opcode table is
207 in the arguments--look for arguments which specify fields in the 2nd
208 or 3rd words of the instruction. */
209 for (d = best->args; *d; d += 2)
210 {
211 /* I don't think it is necessary to be checking d[0] here;
212 I suspect all this could be moved to the case statement below. */
213 if (d[0] == '#')
214 {
215 if (d[1] == 'l' && p - buffer < 6)
216 p = buffer + 6;
217 else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8')
218 p = buffer + 4;
219 }
220
221 if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
222 p = buffer + 4;
223
224 switch (d[1])
225 {
226 case '1':
227 case '2':
228 case '3':
229 case '7':
230 case '8':
231 case '9':
232 case 'i':
233 if (p - buffer < 4)
234 p = buffer + 4;
235 break;
236 case '4':
237 case '5':
238 case '6':
239 if (p - buffer < 6)
240 p = buffer + 6;
241 break;
242 default:
243 break;
244 }
245 }
246
247 /* pflusha is an exceptions. It takes no arguments but is two words
248 long. Recognize it by looking at the lower 16 bits of the mask. */
249 if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
250 p = buffer + 4;
251
252 /* lpstop is another exception. It takes a one word argument but is
253 three words long. */
254 if (p - buffer < 6
255 && (best->match & 0xffff) == 0xffff
256 && best->args[0] == '#'
257 && best->args[1] == 'w')
258 {
259 /* Copy the one word argument into the usual location for a one
260 word argument, to simplify printing it. We can get away with
261 this because we know exactly what the second word is, and we
262 aren't going to print anything based on it. */
263 p = buffer + 6;
264 FETCH_DATA (info, p);
265 buffer[2] = buffer[4];
266 buffer[3] = buffer[5];
267 }
268
269 FETCH_DATA (info, p);
270
271 d = best->args;
272
273 save_p = p;
274 info->print_address_func = dummy_print_address;
275 info->fprintf_func = (fprintf_ftype) dummy_printer;
276
277 /* We scan the operands twice. The first time we don't print anything,
278 but look for errors. */
279 for (; *d; d += 2)
280 {
281 int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
282
283 if (eaten >= 0)
284 p += eaten;
285 else if (eaten == -1)
286 {
287 info->fprintf_func = save_printer;
288 info->print_address_func = save_print_address;
289 return 0;
290 }
291 else
292 {
293 info->fprintf_func (info->stream,
294 /* xgettext:c-format */
295 _("<internal error in opcode table: %s %s>\n"),
296 best->name, best->args);
297 info->fprintf_func = save_printer;
298 info->print_address_func = save_print_address;
299 return 2;
300 }
301 }
302
303 p = save_p;
304 info->fprintf_func = save_printer;
305 info->print_address_func = save_print_address;
306
307 d = best->args;
308
309 info->fprintf_func (info->stream, "%s", best->name);
310
311 if (*d)
312 info->fprintf_func (info->stream, " ");
313
314 while (*d)
315 {
316 p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
317 d += 2;
318
319 if (*d && *(d - 2) != 'I' && *d != 'k')
320 info->fprintf_func (info->stream, ",");
321 }
322
323 return p - buffer;
324}
325
252b5132
RH
326/* Print the m68k instruction at address MEMADDR in debugged memory,
327 on INFO->STREAM. Returns length of the instruction, in bytes. */
328
329int
330print_insn_m68k (memaddr, info)
331 bfd_vma memaddr;
332 disassemble_info *info;
333{
be8c092b
NC
334 int i;
335 const char *d;
252b5132
RH
336 unsigned int arch_mask;
337 struct private priv;
338 bfd_byte *buffer = priv.the_buffer;
252b5132
RH
339 int major_opcode;
340 static int numopcodes[16];
341 static const struct m68k_opcode **opcodes[16];
be8c092b 342 int val;
252b5132
RH
343
344 if (!opcodes[0])
345 {
be8c092b
NC
346 /* Speed up the matching by sorting the opcode
347 table on the upper four bits of the opcode. */
252b5132
RH
348 const struct m68k_opcode **opc_pointer[16];
349
350 /* First count how many opcodes are in each of the sixteen buckets. */
351 for (i = 0; i < m68k_numopcodes; i++)
352 numopcodes[(m68k_opcodes[i].opcode >> 28) & 15]++;
353
be8c092b
NC
354 /* Then create a sorted table of pointers
355 that point into the unsorted table. */
356 opc_pointer[0] = xmalloc (sizeof (struct m68k_opcode *)
357 * m68k_numopcodes);
252b5132 358 opcodes[0] = opc_pointer[0];
be8c092b 359
252b5132
RH
360 for (i = 1; i < 16; i++)
361 {
362 opc_pointer[i] = opc_pointer[i - 1] + numopcodes[i - 1];
363 opcodes[i] = opc_pointer[i];
364 }
365
366 for (i = 0; i < m68k_numopcodes; i++)
367 *opc_pointer[(m68k_opcodes[i].opcode >> 28) & 15]++ = &m68k_opcodes[i];
252b5132
RH
368 }
369
370 info->private_data = (PTR) &priv;
be8c092b
NC
371 /* Tell objdump to use two bytes per chunk
372 and six bytes per line for displaying raw data. */
252b5132
RH
373 info->bytes_per_chunk = 2;
374 info->bytes_per_line = 6;
375 info->display_endian = BFD_ENDIAN_BIG;
376 priv.max_fetched = priv.the_buffer;
377 priv.insn_start = memaddr;
be8c092b 378
252b5132
RH
379 if (setjmp (priv.bailout) != 0)
380 /* Error return. */
381 return -1;
382
383 switch (info->mach)
384 {
385 default:
386 case 0:
387 arch_mask = (unsigned int) -1;
388 break;
389 case bfd_mach_m68000:
6b6e92f4 390 arch_mask = m68000|m68881|m68851;
252b5132
RH
391 break;
392 case bfd_mach_m68008:
6b6e92f4 393 arch_mask = m68008|m68881|m68851;
252b5132
RH
394 break;
395 case bfd_mach_m68010:
6b6e92f4 396 arch_mask = m68010|m68881|m68851;
252b5132
RH
397 break;
398 case bfd_mach_m68020:
6b6e92f4 399 arch_mask = m68020|m68881|m68851;
252b5132
RH
400 break;
401 case bfd_mach_m68030:
6b6e92f4 402 arch_mask = m68030|m68881|m68851;
252b5132
RH
403 break;
404 case bfd_mach_m68040:
6b6e92f4 405 arch_mask = m68040|m68881|m68851;
252b5132
RH
406 break;
407 case bfd_mach_m68060:
6b6e92f4 408 arch_mask = m68060|m68881|m68851;
252b5132 409 break;
9d29e1b3 410 case bfd_mach_mcf5200:
6b6e92f4 411 arch_mask = mcfisa_a;
9d29e1b3 412 break;
6b6e92f4 413 case bfd_mach_mcf521x:
3e602632 414 case bfd_mach_mcf528x:
6b6e92f4 415 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_aa|mcfusp|mcfemac;
3e602632 416 break;
9d29e1b3 417 case bfd_mach_mcf5206e:
6b6e92f4
NC
418 arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
419 break;
420 case bfd_mach_mcf5249:
421 arch_mask = mcfisa_a|mcfhwdiv|mcfemac;
9d29e1b3
NC
422 break;
423 case bfd_mach_mcf5307:
6b6e92f4 424 arch_mask = mcfisa_a|mcfhwdiv|mcfmac;
9d29e1b3
NC
425 break;
426 case bfd_mach_mcf5407:
6b6e92f4 427 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac;
fd99574b 428 break;
6b6e92f4
NC
429 case bfd_mach_mcf547x:
430 case bfd_mach_mcf548x:
fd99574b 431 case bfd_mach_mcfv4e:
6b6e92f4 432 arch_mask = mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac;
9d29e1b3 433 break;
252b5132
RH
434 }
435
252b5132
RH
436 FETCH_DATA (info, buffer + 2);
437 major_opcode = (buffer[0] >> 4) & 15;
be8c092b 438
252b5132
RH
439 for (i = 0; i < numopcodes[major_opcode]; i++)
440 {
441 const struct m68k_opcode *opc = opcodes[major_opcode][i];
442 unsigned long opcode = opc->opcode;
443 unsigned long match = opc->match;
444
445 if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
446 && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
447 /* Only fetch the next two bytes if we need to. */
448 && (((0xffff & match) == 0)
449 ||
450 (FETCH_DATA (info, buffer + 4)
451 && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
452 && ((0xff & buffer[3] & match) == (0xff & opcode)))
453 )
454 && (opc->arch & arch_mask) != 0)
455 {
456 /* Don't use for printout the variants of divul and divsl
457 that have the same register number in two places.
458 The more general variants will match instead. */
459 for (d = opc->args; *d; d += 2)
460 if (d[1] == 'D')
461 break;
462
463 /* Don't use for printout the variants of most floating
464 point coprocessor instructions which use the same
be8c092b 465 register number in two places, as above. */
252b5132
RH
466 if (*d == '\0')
467 for (d = opc->args; *d; d += 2)
468 if (d[1] == 't')
469 break;
470
be8c092b
NC
471 /* Don't match fmovel with more than one register;
472 wait for fmoveml. */
252b5132
RH
473 if (*d == '\0')
474 {
475 for (d = opc->args; *d; d += 2)
476 {
477 if (d[0] == 's' && d[1] == '8')
478 {
252b5132
RH
479 val = fetch_arg (buffer, d[1], 3, info);
480 if ((val & (val - 1)) != 0)
481 break;
482 }
483 }
484 }
485
be8c092b
NC
486 if (*d == '\0')
487 if ((val = match_insn_m68k (memaddr, info, opc, & priv)))
488 return val;
252b5132 489 }
252b5132 490 }
252b5132 491
252b5132 492 /* Handle undefined instructions. */
be8c092b 493 info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]);
252b5132
RH
494 return 2;
495}
496
497/* Returns number of bytes "eaten" by the operand, or
498 return -1 if an invalid operand was found, or -2 if
be8c092b 499 an opcode tabe error was found. */
252b5132
RH
500
501static int
502print_insn_arg (d, buffer, p0, addr, info)
503 const char *d;
504 unsigned char *buffer;
505 unsigned char *p0;
be8c092b 506 bfd_vma addr; /* PC for this arg to be relative to. */
252b5132
RH
507 disassemble_info *info;
508{
be8c092b
NC
509 int val = 0;
510 int place = d[1];
511 unsigned char *p = p0;
252b5132 512 int regno;
be8c092b
NC
513 const char *regname;
514 unsigned char *p1;
252b5132
RH
515 double flval;
516 int flt_p;
517 bfd_signed_vma disp;
518 unsigned int uval;
519
520 switch (*d)
521 {
be8c092b 522 case 'c': /* Cache identifier. */
252b5132
RH
523 {
524 static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
525 val = fetch_arg (buffer, place, 2, info);
526 (*info->fprintf_func) (info->stream, cacheFieldName[val]);
527 break;
528 }
529
be8c092b 530 case 'a': /* Address register indirect only. Cf. case '+'. */
252b5132
RH
531 {
532 (*info->fprintf_func)
533 (info->stream,
534 "%s@",
ec22bdda 535 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
252b5132
RH
536 break;
537 }
538
be8c092b 539 case '_': /* 32-bit absolute address for move16. */
252b5132
RH
540 {
541 uval = NEXTULONG (p);
542 (*info->print_address_func) (uval, info);
543 break;
544 }
545
546 case 'C':
547 (*info->fprintf_func) (info->stream, "%%ccr");
548 break;
549
550 case 'S':
551 (*info->fprintf_func) (info->stream, "%%sr");
552 break;
553
554 case 'U':
555 (*info->fprintf_func) (info->stream, "%%usp");
556 break;
557
461d5ddd
ILT
558 case 'E':
559 (*info->fprintf_func) (info->stream, "%%acc");
560 break;
561
562 case 'G':
563 (*info->fprintf_func) (info->stream, "%%macsr");
564 break;
565
566 case 'H':
567 (*info->fprintf_func) (info->stream, "%%mask");
568 break;
569
252b5132
RH
570 case 'J':
571 {
3e602632
NC
572 /* FIXME: There's a problem here, different m68k processors call the
573 same address different names. This table can't get it right
574 because it doesn't know which processor it's disassembling for. */
252b5132
RH
575 static const struct { char *name; int value; } names[]
576 = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
577 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
578 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
579 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
580 {"%msp", 0x803}, {"%isp", 0x804},
3e602632 581 {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these. */
252b5132
RH
582
583 /* Should we be calling this psr like we do in case 'Y'? */
584 {"%mmusr",0x805},
585
586 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
587
588 val = fetch_arg (buffer, place, 12, info);
589 for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
590 if (names[regno].value == val)
591 {
592 (*info->fprintf_func) (info->stream, "%s", names[regno].name);
593 break;
594 }
595 if (regno < 0)
596 (*info->fprintf_func) (info->stream, "%d", val);
597 }
598 break;
599
600 case 'Q':
601 val = fetch_arg (buffer, place, 3, info);
602 /* 0 means 8, except for the bkpt instruction... */
603 if (val == 0 && d[1] != 's')
604 val = 8;
605 (*info->fprintf_func) (info->stream, "#%d", val);
606 break;
607
3e602632
NC
608 case 'x':
609 val = fetch_arg (buffer, place, 3, info);
610 /* 0 means -1. */
611 if (val == 0)
612 val = -1;
613 (*info->fprintf_func) (info->stream, "#%d", val);
614 break;
615
252b5132 616 case 'M':
461d5ddd
ILT
617 if (place == 'h')
618 {
619 static char *const scalefactor_name[] = { "<<", ">>" };
620 val = fetch_arg (buffer, place, 1, info);
621 (*info->fprintf_func) (info->stream, scalefactor_name[val]);
622 }
623 else
624 {
625 val = fetch_arg (buffer, place, 8, info);
626 if (val & 0x80)
627 val = val - 0x100;
628 (*info->fprintf_func) (info->stream, "#%d", val);
629 }
252b5132
RH
630 break;
631
632 case 'T':
633 val = fetch_arg (buffer, place, 4, info);
634 (*info->fprintf_func) (info->stream, "#%d", val);
635 break;
636
637 case 'D':
638 (*info->fprintf_func) (info->stream, "%s",
639 reg_names[fetch_arg (buffer, place, 3, info)]);
640 break;
641
642 case 'A':
643 (*info->fprintf_func)
644 (info->stream, "%s",
645 reg_names[fetch_arg (buffer, place, 3, info) + 010]);
646 break;
647
648 case 'R':
649 (*info->fprintf_func)
650 (info->stream, "%s",
651 reg_names[fetch_arg (buffer, place, 4, info)]);
652 break;
653
654 case 'r':
655 regno = fetch_arg (buffer, place, 4, info);
656 if (regno > 7)
657 (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
658 else
659 (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
660 break;
661
662 case 'F':
663 (*info->fprintf_func)
664 (info->stream, "%%fp%d",
665 fetch_arg (buffer, place, 3, info));
666 break;
667
668 case 'O':
669 val = fetch_arg (buffer, place, 6, info);
670 if (val & 0x20)
ec22bdda 671 (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
252b5132
RH
672 else
673 (*info->fprintf_func) (info->stream, "%d", val);
674 break;
675
676 case '+':
677 (*info->fprintf_func)
678 (info->stream, "%s@+",
679 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
680 break;
681
682 case '-':
683 (*info->fprintf_func)
684 (info->stream, "%s@-",
685 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
686 break;
687
688 case 'k':
689 if (place == 'k')
690 (*info->fprintf_func)
691 (info->stream, "{%s}",
692 reg_names[fetch_arg (buffer, place, 3, info)]);
693 else if (place == 'C')
694 {
695 val = fetch_arg (buffer, place, 7, info);
ec22bdda 696 if (val > 63) /* This is a signed constant. */
252b5132
RH
697 val -= 128;
698 (*info->fprintf_func) (info->stream, "{#%d}", val);
699 }
700 else
701 return -2;
702 break;
703
704 case '#':
705 case '^':
706 p1 = buffer + (*d == '#' ? 2 : 4);
707 if (place == 's')
708 val = fetch_arg (buffer, place, 4, info);
709 else if (place == 'C')
710 val = fetch_arg (buffer, place, 7, info);
711 else if (place == '8')
712 val = fetch_arg (buffer, place, 3, info);
713 else if (place == '3')
714 val = fetch_arg (buffer, place, 8, info);
715 else if (place == 'b')
716 val = NEXTBYTE (p1);
717 else if (place == 'w' || place == 'W')
718 val = NEXTWORD (p1);
719 else if (place == 'l')
720 val = NEXTLONG (p1);
721 else
722 return -2;
723 (*info->fprintf_func) (info->stream, "#%d", val);
724 break;
725
726 case 'B':
727 if (place == 'b')
728 disp = NEXTBYTE (p);
729 else if (place == 'B')
ec22bdda 730 disp = COERCE_SIGNED_CHAR (buffer[1]);
252b5132
RH
731 else if (place == 'w' || place == 'W')
732 disp = NEXTWORD (p);
733 else if (place == 'l' || place == 'L' || place == 'C')
734 disp = NEXTLONG (p);
735 else if (place == 'g')
736 {
737 disp = NEXTBYTE (buffer);
738 if (disp == 0)
739 disp = NEXTWORD (p);
740 else if (disp == -1)
741 disp = NEXTLONG (p);
742 }
743 else if (place == 'c')
744 {
745 if (buffer[1] & 0x40) /* If bit six is one, long offset */
746 disp = NEXTLONG (p);
747 else
748 disp = NEXTWORD (p);
749 }
750 else
751 return -2;
752
753 (*info->print_address_func) (addr + disp, info);
754 break;
755
756 case 'd':
757 val = NEXTWORD (p);
758 (*info->fprintf_func)
759 (info->stream, "%s@(%d)",
760 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
761 break;
762
763 case 's':
764 (*info->fprintf_func) (info->stream, "%s",
765 fpcr_names[fetch_arg (buffer, place, 3, info)]);
766 break;
767
fd99574b
NC
768 case 'e':
769 val = fetch_arg(buffer, place, 2, info);
770 (*info->fprintf_func) (info->stream, "%%acc%d", val);
771 break;
772
773 case 'g':
be8c092b 774 val = fetch_arg(buffer, place, 1, info);
fd99574b
NC
775 (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
776 break;
777
778 case 'i':
779 val = fetch_arg(buffer, place, 2, info);
780 if (val == 1)
781 (*info->fprintf_func) (info->stream, "<<");
782 else if (val == 3)
783 (*info->fprintf_func) (info->stream, ">>");
be8c092b
NC
784 else
785 return -1;
fd99574b
NC
786 break;
787
252b5132
RH
788 case 'I':
789 /* Get coprocessor ID... */
790 val = fetch_arg (buffer, 'd', 3, info);
3e602632 791
252b5132
RH
792 if (val != 1) /* Unusual coprocessor ID? */
793 (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
794 break;
795
fd99574b 796 case '4':
252b5132
RH
797 case '*':
798 case '~':
799 case '%':
800 case ';':
801 case '@':
802 case '!':
803 case '$':
804 case '?':
805 case '/':
806 case '&':
807 case '|':
808 case '<':
809 case '>':
810 case 'm':
811 case 'n':
812 case 'o':
813 case 'p':
814 case 'q':
815 case 'v':
3e602632
NC
816 case 'b':
817 case 'w':
818 case 'y':
819 case 'z':
252b5132
RH
820 if (place == 'd')
821 {
822 val = fetch_arg (buffer, 'x', 6, info);
823 val = ((val & 7) << 3) + ((val >> 3) & 7);
824 }
825 else
826 val = fetch_arg (buffer, 's', 6, info);
827
be8c092b 828 /* If the <ea> is invalid for *d, then reject this match. */
8577e690 829 if (!m68k_valid_ea (*d, val))
be8c092b
NC
830 return -1;
831
252b5132
RH
832 /* Get register number assuming address register. */
833 regno = (val & 7) + 8;
834 regname = reg_names[regno];
835 switch (val >> 3)
836 {
837 case 0:
838 (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
839 break;
840
841 case 1:
842 (*info->fprintf_func) (info->stream, "%s", regname);
843 break;
844
845 case 2:
846 (*info->fprintf_func) (info->stream, "%s@", regname);
847 break;
848
849 case 3:
850 (*info->fprintf_func) (info->stream, "%s@+", regname);
851 break;
852
853 case 4:
854 (*info->fprintf_func) (info->stream, "%s@-", regname);
855 break;
856
857 case 5:
858 val = NEXTWORD (p);
859 (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
860 break;
861
862 case 6:
863 p = print_indexed (regno, p, addr, info);
864 break;
865
866 case 7:
867 switch (val & 7)
868 {
869 case 0:
870 val = NEXTWORD (p);
871 (*info->print_address_func) (val, info);
872 break;
873
874 case 1:
875 uval = NEXTULONG (p);
876 (*info->print_address_func) (uval, info);
877 break;
878
879 case 2:
880 val = NEXTWORD (p);
881 (*info->fprintf_func) (info->stream, "%%pc@(");
882 (*info->print_address_func) (addr + val, info);
883 (*info->fprintf_func) (info->stream, ")");
884 break;
885
886 case 3:
887 p = print_indexed (-1, p, addr, info);
888 break;
889
890 case 4:
891 flt_p = 1; /* Assume it's a float... */
ec22bdda 892 switch (place)
252b5132
RH
893 {
894 case 'b':
895 val = NEXTBYTE (p);
896 flt_p = 0;
897 break;
898
899 case 'w':
900 val = NEXTWORD (p);
901 flt_p = 0;
902 break;
903
904 case 'l':
905 val = NEXTLONG (p);
906 flt_p = 0;
907 break;
908
909 case 'f':
ec22bdda 910 NEXTSINGLE (flval, p);
252b5132
RH
911 break;
912
913 case 'F':
ec22bdda 914 NEXTDOUBLE (flval, p);
252b5132
RH
915 break;
916
917 case 'x':
ec22bdda 918 NEXTEXTEND (flval, p);
252b5132
RH
919 break;
920
921 case 'p':
ec22bdda 922 flval = NEXTPACKED (p);
252b5132
RH
923 break;
924
925 default:
926 return -1;
927 }
ec22bdda 928 if (flt_p) /* Print a float? */
252b5132
RH
929 (*info->fprintf_func) (info->stream, "#%g", flval);
930 else
931 (*info->fprintf_func) (info->stream, "#%d", val);
932 break;
933
934 default:
935 return -1;
936 }
937 }
fd99574b
NC
938
939 /* If place is '/', then this is the case of the mask bit for
940 mac/emac loads. Now that the arg has been printed, grab the
941 mask bit and if set, add a '&' to the arg. */
942 if (place == '/')
943 {
944 val = fetch_arg (buffer, place, 1, info);
945 if (val)
be8c092b 946 info->fprintf_func (info->stream, "&");
fd99574b 947 }
252b5132
RH
948 break;
949
950 case 'L':
951 case 'l':
952 if (place == 'w')
953 {
954 char doneany;
955 p1 = buffer + 2;
956 val = NEXTWORD (p1);
957 /* Move the pointer ahead if this point is farther ahead
958 than the last. */
959 p = p1 > p ? p1 : p;
960 if (val == 0)
961 {
962 (*info->fprintf_func) (info->stream, "#0");
963 break;
964 }
965 if (*d == 'l')
966 {
967 register int newval = 0;
968 for (regno = 0; regno < 16; ++regno)
969 if (val & (0x8000 >> regno))
970 newval |= 1 << regno;
971 val = newval;
972 }
973 val &= 0xffff;
974 doneany = 0;
975 for (regno = 0; regno < 16; ++regno)
976 if (val & (1 << regno))
977 {
978 int first_regno;
979 if (doneany)
980 (*info->fprintf_func) (info->stream, "/");
981 doneany = 1;
982 (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
983 first_regno = regno;
984 while (val & (1 << (regno + 1)))
985 ++regno;
986 if (regno > first_regno)
987 (*info->fprintf_func) (info->stream, "-%s",
988 reg_names[regno]);
989 }
990 }
991 else if (place == '3')
992 {
993 /* `fmovem' insn. */
994 char doneany;
995 val = fetch_arg (buffer, place, 8, info);
996 if (val == 0)
997 {
998 (*info->fprintf_func) (info->stream, "#0");
999 break;
1000 }
1001 if (*d == 'l')
1002 {
1003 register int newval = 0;
1004 for (regno = 0; regno < 8; ++regno)
1005 if (val & (0x80 >> regno))
1006 newval |= 1 << regno;
1007 val = newval;
1008 }
1009 val &= 0xff;
1010 doneany = 0;
1011 for (regno = 0; regno < 8; ++regno)
1012 if (val & (1 << regno))
1013 {
1014 int first_regno;
1015 if (doneany)
1016 (*info->fprintf_func) (info->stream, "/");
1017 doneany = 1;
1018 (*info->fprintf_func) (info->stream, "%%fp%d", regno);
1019 first_regno = regno;
1020 while (val & (1 << (regno + 1)))
1021 ++regno;
1022 if (regno > first_regno)
1023 (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
1024 }
1025 }
1026 else if (place == '8')
1027 {
1028 /* fmoveml for FP status registers */
1029 (*info->fprintf_func) (info->stream, "%s",
1030 fpcr_names[fetch_arg (buffer, place, 3,
1031 info)]);
1032 }
1033 else
1034 return -2;
1035 break;
1036
1037 case 'X':
1038 place = '8';
1039 case 'Y':
1040 case 'Z':
1041 case 'W':
1042 case '0':
1043 case '1':
1044 case '2':
1045 case '3':
1046 {
1047 int val = fetch_arg (buffer, place, 5, info);
1048 char *name = 0;
1049 switch (val)
1050 {
1051 case 2: name = "%tt0"; break;
1052 case 3: name = "%tt1"; break;
1053 case 0x10: name = "%tc"; break;
1054 case 0x11: name = "%drp"; break;
1055 case 0x12: name = "%srp"; break;
1056 case 0x13: name = "%crp"; break;
1057 case 0x14: name = "%cal"; break;
1058 case 0x15: name = "%val"; break;
1059 case 0x16: name = "%scc"; break;
1060 case 0x17: name = "%ac"; break;
1061 case 0x18: name = "%psr"; break;
1062 case 0x19: name = "%pcsr"; break;
1063 case 0x1c:
1064 case 0x1d:
1065 {
1066 int break_reg = ((buffer[3] >> 2) & 7);
1067 (*info->fprintf_func)
1068 (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
1069 break_reg);
1070 }
1071 break;
1072 default:
1073 (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
1074 }
1075 if (name)
1076 (*info->fprintf_func) (info->stream, "%s", name);
1077 }
1078 break;
1079
1080 case 'f':
1081 {
1082 int fc = fetch_arg (buffer, place, 5, info);
1083 if (fc == 1)
1084 (*info->fprintf_func) (info->stream, "%%dfc");
1085 else if (fc == 0)
1086 (*info->fprintf_func) (info->stream, "%%sfc");
1087 else
1088 /* xgettext:c-format */
1089 (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
1090 }
1091 break;
1092
1093 case 'V':
1094 (*info->fprintf_func) (info->stream, "%%val");
1095 break;
1096
1097 case 't':
1098 {
1099 int level = fetch_arg (buffer, place, 3, info);
1100 (*info->fprintf_func) (info->stream, "%d", level);
1101 }
1102 break;
1103
461d5ddd
ILT
1104 case 'u':
1105 {
1106 short is_upper = 0;
1107 int reg = fetch_arg (buffer, place, 5, info);
3e602632 1108
461d5ddd
ILT
1109 if (reg & 0x10)
1110 {
1111 is_upper = 1;
1112 reg &= 0xf;
1113 }
1114 (*info->fprintf_func) (info->stream, "%s%s",
be8c092b 1115 reg_half_names[reg],
461d5ddd
ILT
1116 is_upper ? "u" : "l");
1117 }
1118 break;
3e602632 1119
252b5132
RH
1120 default:
1121 return -2;
1122 }
1123
1124 return p - p0;
1125}
1126
be8c092b
NC
1127/* Check if an EA is valid for a particular code. This is required
1128 for the EMAC instructions since the type of source address determines
1129 if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
8577e690
AS
1130 is a non-load EMAC instruction and the bits mean register Ry.
1131 A similar case exists for the movem instructions where the register
1132 mask is interpreted differently for different EAs. */
be8c092b
NC
1133
1134static bfd_boolean
1135m68k_valid_ea (char code, int val)
1136{
8577e690
AS
1137 int mode, mask;
1138#define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
1139 (n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
1140 | n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
be8c092b 1141
8577e690
AS
1142 switch (code)
1143 {
1144 case '*':
1145 mask = M (1,1,1,1,1,1,1,1,1,1,1,1);
1146 break;
1147 case '~':
1148 mask = M (0,0,1,1,1,1,1,1,1,0,0,0);
1149 break;
1150 case '%':
1151 mask = M (1,1,1,1,1,1,1,1,1,0,0,0);
1152 break;
1153 case ';':
1154 mask = M (1,0,1,1,1,1,1,1,1,1,1,1);
1155 break;
1156 case '@':
1157 mask = M (1,0,1,1,1,1,1,1,1,1,1,0);
1158 break;
1159 case '!':
1160 mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
1161 break;
1162 case '&':
1163 mask = M (0,0,1,0,0,1,1,1,1,0,0,0);
1164 break;
1165 case '$':
1166 mask = M (1,0,1,1,1,1,1,1,1,0,0,0);
1167 break;
1168 case '?':
4300ab10 1169 mask = M (1,0,1,0,0,1,1,1,1,0,0,0);
8577e690
AS
1170 break;
1171 case '/':
1172 mask = M (1,0,1,0,0,1,1,1,1,1,1,0);
1173 break;
1174 case '|':
1175 mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
1176 break;
1177 case '>':
4300ab10 1178 mask = M (0,0,1,0,1,1,1,1,1,0,0,0);
8577e690
AS
1179 break;
1180 case '<':
4300ab10 1181 mask = M (0,0,1,1,0,1,1,1,1,1,1,0);
8577e690
AS
1182 break;
1183 case 'm':
1184 mask = M (1,1,1,1,1,0,0,0,0,0,0,0);
1185 break;
1186 case 'n':
1187 mask = M (0,0,0,0,0,1,0,0,0,1,0,0);
1188 break;
1189 case 'o':
1190 mask = M (0,0,0,0,0,0,1,1,1,0,1,1);
1191 break;
1192 case 'p':
1193 mask = M (1,1,1,1,1,1,0,0,0,0,0,0);
1194 break;
1195 case 'q':
1196 mask = M (1,0,1,1,1,1,0,0,0,0,0,0);
1197 break;
1198 case 'v':
1199 mask = M (1,0,1,1,1,1,0,1,1,0,0,0);
1200 break;
1201 case 'b':
1202 mask = M (1,0,1,1,1,1,0,0,0,1,0,0);
1203 break;
1204 case 'w':
1205 mask = M (0,0,1,1,1,1,0,0,0,1,0,0);
1206 break;
1207 case 'y':
1208 mask = M (0,0,1,0,0,1,0,0,0,0,0,0);
1209 break;
1210 case 'z':
1211 mask = M (0,0,1,0,0,1,0,0,0,1,0,0);
1212 break;
1213 case '4':
1214 mask = M (0,0,1,1,1,1,0,0,0,0,0,0);
1215 break;
1216 default:
1217 abort ();
1218 }
1219#undef M
be8c092b 1220
8577e690
AS
1221 mode = (val >> 3) & 7;
1222 if (mode == 7)
1223 mode += val & 7;
1224 return (mask & (1 << mode)) != 0;
be8c092b
NC
1225}
1226
252b5132
RH
1227/* Fetch BITS bits from a position in the instruction specified by CODE.
1228 CODE is a "place to put an argument", or 'x' for a destination
1229 that is a general address (mode and register).
1230 BUFFER contains the instruction. */
1231
1232static int
1233fetch_arg (buffer, code, bits, info)
1234 unsigned char *buffer;
1235 int code;
1236 int bits;
1237 disassemble_info *info;
1238{
be8c092b
NC
1239 int val = 0;
1240
252b5132
RH
1241 switch (code)
1242 {
fd99574b
NC
1243 case '/': /* MAC/EMAC mask bit. */
1244 val = buffer[3] >> 5;
1245 break;
1246
1247 case 'G': /* EMAC ACC load. */
be8c092b 1248 val = ((buffer[3] >> 3) & 0x2) | ((~buffer[1] >> 7) & 0x1);
fd99574b
NC
1249 break;
1250
1251 case 'H': /* EMAC ACC !load. */
be8c092b 1252 val = ((buffer[3] >> 3) & 0x2) | ((buffer[1] >> 7) & 0x1);
fd99574b
NC
1253 break;
1254
1255 case ']': /* EMAC ACCEXT bit. */
1256 val = buffer[0] >> 2;
1257 break;
1258
1259 case 'I': /* MAC/EMAC scale factor. */
be8c092b 1260 val = buffer[2] >> 1;
fd99574b
NC
1261 break;
1262
1263 case 'F': /* EMAC ACCx. */
1264 val = buffer[0] >> 1;
1265 break;
1266
1267 case 'f':
be8c092b 1268 val = buffer[1];
fd99574b
NC
1269 break;
1270
252b5132
RH
1271 case 's':
1272 val = buffer[1];
1273 break;
1274
1275 case 'd': /* Destination, for register or quick. */
1276 val = (buffer[0] << 8) + buffer[1];
1277 val >>= 9;
1278 break;
1279
1280 case 'x': /* Destination, for general arg */
1281 val = (buffer[0] << 8) + buffer[1];
1282 val >>= 6;
1283 break;
1284
1285 case 'k':
1286 FETCH_DATA (info, buffer + 3);
1287 val = (buffer[3] >> 4);
1288 break;
1289
1290 case 'C':
1291 FETCH_DATA (info, buffer + 3);
1292 val = buffer[3];
1293 break;
1294
1295 case '1':
1296 FETCH_DATA (info, buffer + 3);
1297 val = (buffer[2] << 8) + buffer[3];
1298 val >>= 12;
1299 break;
1300
1301 case '2':
1302 FETCH_DATA (info, buffer + 3);
1303 val = (buffer[2] << 8) + buffer[3];
1304 val >>= 6;
1305 break;
1306
1307 case '3':
1308 case 'j':
1309 FETCH_DATA (info, buffer + 3);
1310 val = (buffer[2] << 8) + buffer[3];
1311 break;
1312
1313 case '4':
1314 FETCH_DATA (info, buffer + 5);
1315 val = (buffer[4] << 8) + buffer[5];
1316 val >>= 12;
1317 break;
1318
1319 case '5':
1320 FETCH_DATA (info, buffer + 5);
1321 val = (buffer[4] << 8) + buffer[5];
1322 val >>= 6;
1323 break;
1324
1325 case '6':
1326 FETCH_DATA (info, buffer + 5);
1327 val = (buffer[4] << 8) + buffer[5];
1328 break;
1329
1330 case '7':
1331 FETCH_DATA (info, buffer + 3);
1332 val = (buffer[2] << 8) + buffer[3];
1333 val >>= 7;
1334 break;
3e602632 1335
252b5132
RH
1336 case '8':
1337 FETCH_DATA (info, buffer + 3);
1338 val = (buffer[2] << 8) + buffer[3];
1339 val >>= 10;
1340 break;
1341
1342 case '9':
1343 FETCH_DATA (info, buffer + 3);
1344 val = (buffer[2] << 8) + buffer[3];
1345 val >>= 5;
1346 break;
1347
1348 case 'e':
1349 val = (buffer[1] >> 6);
1350 break;
1351
3e602632 1352 case 'm':
461d5ddd
ILT
1353 val = (buffer[1] & 0x40 ? 0x8 : 0)
1354 | ((buffer[0] >> 1) & 0x7)
1355 | (buffer[3] & 0x80 ? 0x10 : 0);
1356 break;
1357
3e602632 1358 case 'n':
461d5ddd
ILT
1359 val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
1360 break;
1361
1362 case 'o':
1363 val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
1364 break;
1365
1366 case 'M':
be8c092b 1367 val = (buffer[1] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
461d5ddd
ILT
1368 break;
1369
1370 case 'N':
be8c092b 1371 val = (buffer[3] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
461d5ddd
ILT
1372 break;
1373
1374 case 'h':
1375 val = buffer[2] >> 2;
1376 break;
1377
252b5132
RH
1378 default:
1379 abort ();
1380 }
1381
1382 switch (bits)
1383 {
461d5ddd
ILT
1384 case 1:
1385 return val & 1;
252b5132
RH
1386 case 2:
1387 return val & 3;
1388 case 3:
1389 return val & 7;
1390 case 4:
1391 return val & 017;
1392 case 5:
1393 return val & 037;
1394 case 6:
1395 return val & 077;
1396 case 7:
1397 return val & 0177;
1398 case 8:
1399 return val & 0377;
1400 case 12:
1401 return val & 07777;
1402 default:
1403 abort ();
1404 }
1405}
1406
1407/* Print an indexed argument. The base register is BASEREG (-1 for pc).
1408 P points to extension word, in buffer.
1409 ADDR is the nominal core address of that extension word. */
1410
1411static unsigned char *
1412print_indexed (basereg, p, addr, info)
1413 int basereg;
1414 unsigned char *p;
1415 bfd_vma addr;
1416 disassemble_info *info;
1417{
be8c092b 1418 int word;
ec22bdda 1419 static char *const scales[] = { "", ":2", ":4", ":8" };
252b5132
RH
1420 bfd_vma base_disp;
1421 bfd_vma outer_disp;
1422 char buf[40];
1423 char vmabuf[50];
1424
1425 word = NEXTWORD (p);
1426
1427 /* Generate the text for the index register.
1428 Where this will be output is not yet determined. */
1429 sprintf (buf, "%s:%c%s",
1430 reg_names[(word >> 12) & 0xf],
1431 (word & 0x800) ? 'l' : 'w',
1432 scales[(word >> 9) & 3]);
1433
1434 /* Handle the 68000 style of indexing. */
1435
1436 if ((word & 0x100) == 0)
1437 {
1438 base_disp = word & 0xff;
1439 if ((base_disp & 0x80) != 0)
1440 base_disp -= 0x100;
1441 if (basereg == -1)
1442 base_disp += addr;
1443 print_base (basereg, base_disp, info);
1444 (*info->fprintf_func) (info->stream, ",%s)", buf);
1445 return p;
1446 }
1447
1448 /* Handle the generalized kind. */
1449 /* First, compute the displacement to add to the base register. */
1450
1451 if (word & 0200)
1452 {
1453 if (basereg == -1)
1454 basereg = -3;
1455 else
1456 basereg = -2;
1457 }
1458 if (word & 0100)
1459 buf[0] = '\0';
1460 base_disp = 0;
1461 switch ((word >> 4) & 3)
1462 {
1463 case 2:
1464 base_disp = NEXTWORD (p);
1465 break;
1466 case 3:
1467 base_disp = NEXTLONG (p);
1468 }
1469 if (basereg == -1)
1470 base_disp += addr;
1471
1472 /* Handle single-level case (not indirect) */
1473
1474 if ((word & 7) == 0)
1475 {
1476 print_base (basereg, base_disp, info);
1477 if (buf[0] != '\0')
1478 (*info->fprintf_func) (info->stream, ",%s", buf);
1479 (*info->fprintf_func) (info->stream, ")");
1480 return p;
1481 }
1482
1483 /* Two level. Compute displacement to add after indirection. */
1484
1485 outer_disp = 0;
1486 switch (word & 3)
1487 {
1488 case 2:
1489 outer_disp = NEXTWORD (p);
1490 break;
1491 case 3:
1492 outer_disp = NEXTLONG (p);
1493 }
1494
1495 print_base (basereg, base_disp, info);
1496 if ((word & 4) == 0 && buf[0] != '\0')
1497 {
1498 (*info->fprintf_func) (info->stream, ",%s", buf);
1499 buf[0] = '\0';
1500 }
1501 sprintf_vma (vmabuf, outer_disp);
1502 (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
1503 if (buf[0] != '\0')
1504 (*info->fprintf_func) (info->stream, ",%s", buf);
1505 (*info->fprintf_func) (info->stream, ")");
1506
1507 return p;
1508}
1509
1510/* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1511 REGNO = -1 for pc, -2 for none (suppressed). */
1512
1513static void
1514print_base (regno, disp, info)
1515 int regno;
1516 bfd_vma disp;
1517 disassemble_info *info;
1518{
1519 if (regno == -1)
1520 {
1521 (*info->fprintf_func) (info->stream, "%%pc@(");
1522 (*info->print_address_func) (disp, info);
1523 }
1524 else
1525 {
1526 char buf[50];
1527
1528 if (regno == -2)
1529 (*info->fprintf_func) (info->stream, "@(");
1530 else if (regno == -3)
1531 (*info->fprintf_func) (info->stream, "%%zpc@(");
1532 else
1533 (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
1534
1535 sprintf_vma (buf, disp);
1536 (*info->fprintf_func) (info->stream, "%s", buf);
1537 }
1538}
This page took 0.350774 seconds and 4 git commands to generate.