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